Linux 内核网络协议栈 -sk_buff结构体

sk_buff结构体是linux网络代码中最重要的数据结构,是整个网络传输载体。所以sk_buff结构体里面有很多关于其他功能的成员字段,比如:防火墙,子路由系统,多播等。这些字段并不是一定有的,只有在满足特点条件才有的。

 sk_buff结构体是双链表结构,sk_buff结构体关联多个其他结构体:

第一是数据区:由sk_buff中head和end指向的数据块,用来存储sk_buff结构的数据也即是存储数据包的内容和各层协议头。

第二是分片结构:用来表示IP分片的一个结构体,实则上是和sk_buff结构的数据区相连的,即是end指针的下一个字节开始就是分片结构。也正是此原因,所以分片结构和sk_buff数据区内存分配及销毁时都是一起的。

第三是分片结构指向的数据区,即是IP分片内容。


数据包在各层间传输时,data指针的变化:sk_buff在各层间传输时,只改变指针和添加协议头,不拷贝也不删除协议头。

 假设从收包开始:

       (1)开始进入第二层时,这时data指针指向帧头。mac = data,然后操作mac指针已经数据包。当二层操作完后把包往三层传送时,会调用一个函数(具体什么函数后面会详细讲)让data指针指向三层的IP头;

       (2)当包进入第三层时,这时data指针已经指向了IP头,让nh = data,然后操作nh指针已经数据包,当三层操作完后把包往四层传送时,同样调用一个函数把data指向四层的TCP头;同理,四层也是一样处理的,只移动指针,不删除协议头。发包时就相反了,只是变成了为每一层添加协议头了。下面是书上的图,供参考。

 

 sk_buff_head结构体和sk_buff结构体关系:

 

sk_buff结构体数据区:

  sk_buff结构体只是网络数据包中的一些配置,真正包含传输内容和传输协议的都是在sk_buff结构体中几个指针所指向的数据区中。这里先简称数据区,数据区的大小是:(skb->end  - skb->head);对于每个数据包来说这个大小都是固定的,而且在传输过程中skb->end和skb->head所指向的地址都是不变的。这块数据区是用来存放应用层发下来的数据和各层的协议信息。但在计算数据长度或者操作协议信息时,一般都要和实际的数据存放指针为准。实际数据指针为data和tail,data指向实际数据开始的地方,tail指向实际数据结束的地方。
        下面来看下sk_buff结构体中的指针和数据区关系:

 (1)sk_buff结构数据区刚被申请好,此时head指针、data指针、tail指针都是指向同一个地方。记住前面讲过的:head指针和end指针指向的位置一直都不变,而对于数据的变化和协议信息的添加都是通过data指针和tail指针的改变来表现的。
        (2)开始准备存储应用层下发过来的数据,通过调用函数skb_reserve()来使data指针和tail指针同时向下移动,空出一部分空间来为后期添加协议信息。
        (3)开始存储数据了,通过调用函数skb_put()来使tail指针向下移动空出空间来添加数据,此时skb->data和skb->tail之间存放的都是数据信息,无协议信息。
        (4)这时就开始调用函数skb_push()来使data指针向上移动,空出空间来添加各层协议信息。直到最后到达二层,添加完帧头然后就开始发包了。

 

另外一篇文章介绍sk_buff结构体讲解的特别详细

https://blog.csdn.net/shanshanpt/article/details/21024465#commentBox

 

IP数据包协议的讲解:

https://blog.csdn.net/tanforever/article/details/79353047

https://blog.csdn.net/u011240016/article/details/52799673

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值