- 论坛徽章:
- 0
|
在LINUX的实现中,同一个网络报文的数据在内存中是连续存放的,每个
网络报文都有一个控制结构,叫做sk_buff。
sk_buff是一个控制结构,通过它,才可以访问网络报文里的各种数
据。所以在分配网络报文存储空间时,同时也分配它的控制结构sk_buff。在这
个控制结构里,有指向网络报文的指针,也有描述网络报文的变量。下面是
sk_buff的定义,依次注释如下:
struct sk_buff {
struct sk_buff * next;
struct sk_buff * prev;
struct sk_buff_head * list;
以上三个变量将sk_buff链接到一个双向循环链表中,链表的结构会在后面讲
到。
struct sock *sk;
此报文所属的sock结构,此值在本机发出的报文中有效,从网络设备收到的报
文此值为空。
struct timeval stamp; //此报文收到时的时间
struct device *dev; //收到此报文的网络设备
union
{
struct tcphdr *th;
struct udphdr *uh;
struct icmphdr *icmph;
struct igmphdr *igmph;
struct iphdr *ipiph;
struct spxhdr *spxh;
unsigned char *raw;
} h;
union
{
struct iphdr *iph;
struct ipv6hdr *ipv6h;
struct arphdr *arph;
struct ipxhdr *ipxh;
unsigned char *raw;
} nh;
union
{
struct ethhdr *ethernet;
unsigned char *raw;
} mac;
以上三个union结构依次是传输层,网络层,链路层的头部结构指针。这些指
针在网络报文进入这一层时被赋值,其中raw是一个无结构的字符指针,用于
扩展的协议。
struct dst_entry *dst; //此报文的路由,路由确定后赋此值
char cb[48]; //用于在协议栈之间传递参数,参数内容的涵义由
使用它的函数确定。
unsigned int len;
此报文的长度,这是指网络报文在不同协议层中的长度,包括头部和数据。在
协议栈的不同层,这个长度是不同的。
unsigned char is_clone,
cloned,
以上两个变量描述此控制结构是否是clone的控制结构。一个网络报文可以对
应多个控制结构,其中只有一个是原始的结构,其他的都是clone出来的。由
于可能存在多个控制结构,所以在释放网络报文时要确定它所有的控制结构都
已被释放。
pkt_type,
网络报文的类型,常见的有PACKET_HOST,代表发给本机的报文;还有
PACKET_OUTGOING,代表本机发出的报文。
unsigned short protocol; //链路层协议
unsigned int truesize; //此报文存储区的长度,这个长度是16字节
对齐的,一般要比报文的长度大。
unsigned char *head;
unsigned char *data;
unsigned char *tail;
unsigned char *end;
以上四个变量指向此报文存储区,具体的涵义后面会解释。
__u32 fwmark; //防火墙在报文中做的标记
};
网络报文的存储空间是在网络设备收到网络报文或者应用程序发送数据时分配
的,分配的空间以16字节对齐。分配成功之后,将网络报文填充到这个存储空
间中去。填充时先在存储空间的头部预留了一定数量的空隙,然后将网络报文
放到剩余的空间中去。但是网络报文不一定填满整个存储空间,有可能在存储
空间的后部还有一定数量的空隙,所以sk_buff里面的head指针指向存储空间
的起始地址,end指针指向存储空间的结束地址,data指针指向网络报文的起始
地址,tail指针指向网络报文的结束地址。网络报文在存储空间里的存放的顺序
依次是:链路层的头部,网络层的头部,传输层的头部,传输层的数据。在协议栈的不同层,sk_buff的指针data指向这一层的网络报文的头部。同时,在sk_buff里,也有相关的数据结构来表示不同层头部信息。
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/109217/showart_2136357.html |
|