sk_buff结构

来源:互联网 发布:置乱算法 arnold c语言 编辑:程序博客网 时间:2024/05/17 04:00

文章出处:http://book.51cto.com/art/200912/168620.htm

                    http://www.newsmth.net/pc/pccon.php?id=1363&nid=296040&pid=0&tag=0&tid=7570

    内核层和用户层在网络方面的差别很大,在内核的网络层中sk_buff结构占有重要的地位,几乎所有的处理均与此结构有关系。网络协议栈是一个层次架构的软件结构,层与层之间通过预定的接口传递报文。网络报文中包含了在协议各层使用到的各种信息。由于网络报文之间的大小不是固定的,因此采用合适的数据结构来存储这些网络报文就显得非常重要。

1. 结构sk_buff的原型

    在linux的2.6版本的内核中,采用结构sk_buff来存储这些数据。在这个结构中,既有指向网络报文的指针,同时也有描述网络报文的变量。sk_buff数据结构的代码如下所示。

struct sk_buff   {  struct sk_buff         *next;  struct sk_buff         *prev;  struct sock           *sk;  ktime_t                 tstamp;  struct net_device       *dev;  union   {  struct  dst_entry    *dst;  struct  rtable       *rtable;  };  struct  sec_path      *sp;  char                 cb[48];  unsigned int          len,  data_len;  __u16               mac_len,  hdr_len;  union   {  __wsum           csum;  struct  {  __u16            csum_start;  __u16            csum_offset;  };  };  __u32                   priority;  __u8                     local_df:1,                   cloned:1,  ip_summed:2,  nohdr:1,  nfctinfo:3;  __u8                    pkt_type:3,  fclone:2,  ipvs_property:1,  peeked:1,  nf_trace:1;  __be16                  protocol;  void                    (*destructor)(struct sk_buff *skb);  struct nf_conntrack     *nfct;  struct sk_buff          *nfct_reasm;  struct nf_bridge_info   *nf_bridge;  int                     iif;  __u16                   queue_mapping;  __u16                   tc_index;  __u16                   tc_verd;  __u8                    ndisc_nodetype:2;  dma_cookie_t            dma_cookie;  __u32                   secmark;  __u32                   mark;  sk_buff_data_t          transport_header;  sk_buff_data_t          network_header;  sk_buff_data_t          mac_header;  sk_buff_data_t          tail;  sk_buff_data_t          end;  unsigned char           *head,                          *data;  unsigned int            truesize;  atomic_t                users;  }; 

    sk_buff主要成员的含义如下:

    next: sk_buff链表中的下一个缓冲区。

    prev: sk_buff链表中的前一个缓冲区。以上两个变量将sk_buff链接到一个双向链表中。

    sk: 本网络报文所属的sock结构,此值仅在本机发出的报文中有效,从网络收到的报文此值为空。

    tstamp: 报文收到的时间戳。

    dev: 收到此报文的网络设备。

    transport_header: 传输层头部。

    network_header: 网络层头部。

    mac_header: 链路层头部。

    cb: 用于控制缓冲区。每个层都可以使用此指针,将私有的数据放置于此。

    len: 有效数据长度。

    data_len: 数据长度。

    mac_len: 链路层头部长度,对于以太网,指mac地址所用的长度,为6.

    hdr_len: skb的可写头部长度。

    csum: 校验和(包含开始和偏移)。

    csum_start: 当开始计算校验和时从skb->head的偏移。

    csum_offset: 从csum_start开始的偏移。

    local_df: 允许本地分片。

    pkt_type: 包的类别。

    priority: 包队列的优先级。

    truesize: 报文缓冲区的大小。

    head: 报文缓冲区的头。

    data: 数据的头指针。

    tail: 数据的尾指针。

    end: 报文缓冲区的尾部。

    2. sk_buff的含义

下图是sk_buff的框图,其中tail、end、head和data是对网络报文部分的描述。

图的左边表示sk_buff结构,右侧标识网络包的存储区。可以看到,sk_buff中有四个指针指向存储区。其中head一定指向存储区的开头,end一定指向存储区的结尾。 data指向实际内容的开头,tail指向实际内容的结尾。这样做有两个原因,一时在分配空间的时候我们尚不知道具体需要多大的空间,只能按照最大可能空间来分配;二是为了满足字节对齐的需要。

图中data部分的内容包括网络包的所有内容。对于输入包而言,其每向下传输一层,都会添加一层头,所以sk_buff的data指针也会不断减小。

对于输入包而言,存储区的内容是不变的。但我们在分析包时,在每层都会剥除该层的头。为了保留我们剥除的结果,结构中会有三个指针分别指向以太、网络和传输三层的协议头。这三个指针依次分别是union{...}mac, union{...}nh和union{...}h。三个成员都是联合,其中的内容是该层可能的协议类型的指针。

还有一组成员标识存储区中的数据的长度。len表示存储区的数据长度和分片长度之和。data_len标识分片长度。mac_len表示mac头的长度。truesize表示存储区总长度(即end-head)和sk_buff本身长度之和。


下面的内容是关于如何维护存储区。

alloc_skb和dev_alloc_skb用来分配sk_buff和存储区,kfree_skb和dev_kree_skb则释放sk_buff和其对应的存储区。刚初始化完的存储区,head,data,tail都指向存储区的开头,end指向结尾。下面这些函数是修改data和tail指针的指向。

skb_reserve是在存储区的开头保留一段空间。其有两个作用,对于接收到的报文而言,可以保持字节对齐;对于发送的报文而言,可以保留空间用于存放各层的协议头。毕竟我们在高层协议就会分配该存储区,所以需要预留下层协议头的空间。该函数的作用会导致data和tail两个指针都下移,在head和它们之间留出空间。

skb_put则是将tail下移,即增加了真正空间的长度。

skb_push是将data下移,也增加了真正空间的长度。

skb_pull将data下移,减少了真正空间的长度。


    网络报文存储空间实在应用层发送网络数据,或者网络设备收到网络数据时动态分配的,分配成功之后,将接收或者发送的网络数据填充到这个存储空间中去。将网络数据填充到存储空间时,在存储空间的头部预留了一定数量的空隙,然后从此偏移量开始将网络报文复制到存储空间中

    结构sk_buff以sk_buff_head构成一个环状的链,如下图所示,next变量指向下一个sk_buff结构,prev变量指向前一个sk_buff结构,内核程序通过访问其中的各个单元来遍历整个协议栈中的网络数据。




	
				
		
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 指甲上有荧光剂怎么办 小孩吃了荧光剂怎么办 毛巾上有荧光剂怎么办 用过劣质面膜后怎么办 液体硅胶奶嘴煮完有味怎么办 后跟贴粘在鞋上怎么办 优化营商环境公安怎么办 提升营商环境公安怎么办 准予迁入证明过期了怎么办 粉底液容易脱妆怎么办 家人进了火疗传销怎么办 自发热护膝洗了怎么办 用气垫bb卡粉怎么办 贴药膏后皮肤过敏红肿怎么办 贴完膏药皮肤痒怎么办 猕猴桃吃的嘴疼怎么办 摩拜单车怎么办月卡 出国忘了带护照怎么办 雅漾喷雾失压了怎么办 洗衣服时衣服粘上卫生纸怎么办 一晚上卫生巾都是满的怎么办 宝宝头上痱子痒怎么办 短裤里的宽松紧带拧了怎么办 肉色内衣被染黑色了怎么办 安全裤总往上缩怎么办 夏天穿裙子膝盖怕凉怎么办 夏天穿裙子膝盖冷怎么办 天凉嗓子痒咳嗽怎么办 棉服里面跑毛怎么办 棉衣里面的棉一块一块的怎么办 穿姨妈巾悟出痱子怎么办 穿裙子上衣太长了怎么办 微信封号了零钱怎么办 快递加盟商欠我工资怎么办 加盟费交了以后怎么办 加盟总部违约加盟商该怎么办 自行车锁钥匙丢了怎么办 假体隆胸肿胀痛怎么办 恶露60天不干净怎么办 剖腹产俩月恶露不干净怎么办 剖腹产恶露一个多月还没干净怎么办