sk_buff是一个控制结构,通过它,才可以访问网络报文里的各种数
据。所以在分配网络报文存储空间时,同时也分配它的控制结构sk_buff。在这
个控制结构里,有指向网络报文的指针,也有描述网络报文的变量。下面是
sk_buff的定义,依次注释如下:
注 意“......以上三个union结构依次是传输层,网络层,链路层的头部结构指针。这些指针在网络报文进入这一层时被赋值.....”,也就是说这些 指针只是在不同的时刻(不同的协议层面上)来描述相同的数据(当然在每一个层肯定要进行头信息的添加或者其他操作)。我理解作者此处的意思是:不能因为此 结构体重定义了某个指针,这个指针在协议栈中的引用一定就是一个有效值(有意义的)值,指针指向单元的内容首先取决于特定数据包所采用的协议,还有就是数 据包是否已经经过了对应的协议层被修改成为有效值。
这是网络数据包与描述它的sk_buff结构体的对应关系:
据。所以在分配网络报文存储空间时,同时也分配它的控制结构sk_buff。在这
个控制结构里,有指向网络报文的指针,也有描述网络报文的变量。下面是
sk_buff的定义,依次注释如下:
CODE:
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; //防火墙在报文中做的标记
}
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; //防火墙在报文中做的标记
}
注 意“......以上三个union结构依次是传输层,网络层,链路层的头部结构指针。这些指针在网络报文进入这一层时被赋值.....”,也就是说这些 指针只是在不同的时刻(不同的协议层面上)来描述相同的数据(当然在每一个层肯定要进行头信息的添加或者其他操作)。我理解作者此处的意思是:不能因为此 结构体重定义了某个指针,这个指针在协议栈中的引用一定就是一个有效值(有意义的)值,指针指向单元的内容首先取决于特定数据包所采用的协议,还有就是数 据包是否已经经过了对应的协议层被修改成为有效值。
这是网络数据包与描述它的sk_buff结构体的对应关系:
![](https://i-blog.csdnimg.cn/blog_migrate/bb5e61c71e24d00ea6e9d00a9c487a6a.png)