sk_buff 函数操作(一)

来源:互联网 发布:windows命令行 编辑:程序博客网 时间:2024/05/18 01:23

1: Alloc 分配完 之后的结构 仅仅是分配了线束数据区域,但是现在还没有数据



2:skb_reserve函数

 static inline void skb_reserve(struct sk_buff *skb, int len){         skb->data += len;         skb->tail += len; }

这个函数很重要,是为“协议头”预留空间!而且是尽最大的空间预留,因为很多头都会有可选项,那么我们不知道可选项是多大,所以只能是按照最大的分配,那么也说明了一点,预留的空间headroom也就是不一定都能使用完的!可能还有剩余的,由上面的图也可以看出来!这也是为什么需要这么多指针的问题!那么这个函数直接导致head指针和tail、data指针分离


注意headroom就是用来存储各个协议头的足够大的空间,tailroom就可以认为是存储其他线性数据的空间。( 这里不要曲解协议头不是线性数据,其实协议头也是!!!所以当增加头的时候,data指针向上移动,当增加其他数据的时候,tail指针向下移动 )。现在data和tail指向一起,那么还是说明数据没有!!!

 skb_put函数 ----> 用于操作线性数据区域(tailroom区域)的用户数据

static inline unsigned char *skb_put(struct sk_buff *skb, unsigned int len){         unsigned char *tmp = skb->tail;         SKB_LINEAR_ASSERT(skb);                   skb->tail += len;                 // 移动指针         skb->len  += len;                 // 数据空间增大len         if (unlikely(skb->tail>skb->end)) // 如果tail指针超过end指针了,那么处理错误~                 skb_over_panic(skb, len, current_text_addr());         return tmp;}

这函数其实就是从tailroom预留空间,相当于是移动tail指针,这样如果从上图(图六)开始看,也就是tail开始向下移动,和data分离了。。。一般来说,这样做都是为了用户数据再次处理,或者说为TCP/IP的负载预留空间!


skb_push函数:----------> 用于操作headroom区域的协议头

static inline unsigned char *skb_push(struct sk_buff *skb, unsigned int len){         skb->data -= len;      // 向上移动指针         skb->len  += len;      // 数据长度增加         if (unlikely(skb->data<skb->head))  // data指针超过head那么就是处理错误~                 skb_under_panic(skb, len, current_text_addr());         return skb->data;
}

和skb_put对应,上面试操作用户数据的,这里是操作协议头的!其实就是data指针向上移动而已~注意len增大了哦~前面说了协议头也是属于数据!


skb_pull函数:-----------> 其实这个函数才是与skb_push函数对应的函数!因为这是去头函数,而skb_push是增头函数!所以这个函数一般用在解包的时候!

static inline unsigned char *skb_pull(struct sk_buff *skb, unsigned int len){         return unlikely(len > skb->len) ? NULL : __skb_pull(skb, len);}  static inline unsigned char *__pskb_pull(struct sk_buff *skb, unsigned int len){         if (len > skb_headlen(skb) &&             !__pskb_pull_tail(skb, len-skb_headlen(skb)))                 return NULL;         skb->len -= len;                              // 长度减小         return skb->data += len;                      // 移动指针}

其实就是data指针向下移动,当前一个协议头被去掉,headroom剩余的空间增大了!看下图:


虚线是data之前的指针位置,现在移动到下面实线!!需注意:len的长度减小,减小的大小是剥去的头的大小!!

1:从应用层用户数据开始,直到物理层发送出去

      > 初始化的什么就不多说了,和前面的差不多,现在也加入用户数据已经在了,如图七所示一样!那么到了TCP层,需要增加

         TCP层的头:


   需要注意的是这里是传输层,那么传输层的结构u中的th代表的是tcp的头,那么tcp指向tcp头OK!同时注意 len长度+=l1 哦~~~

        > 再看到了IP层:如图11



到链路层了:








0 0