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
到链路层了: