12.4.4套接字缓冲区提供的函数

 

1.操纵sk_buff链表的函数

   sk_buff链表是一个双向链表,它包括一个链表头而且每一个缓冲区都有一个prevnext指针,指向链表中前一个和后一个缓冲区结点。

 

struct sk_buff *skb_dequeue(struct skb_buff_head *list)

这个函数作用是把第一个缓冲区从链表中移走。返回取出的sk_buff,如果队列为空,就返回空指针。添加缓冲区用到 skb_queue_head skb_queue_tail两个例程。

int skb_peek(struct sk_buff_head *list)

返回指向缓冲区链表第一个节点的指针。

int skb_queue_empty(struct sk_buff_head *list)

如果链表为空,返回  true

void skb_queue_head(struct sk_buff *skb)

这个函数在链表头部添加一个缓冲区。

void skb_queue_head_init(struct sk_buff_head *list)

初始化 sk_buff_head结构 。该函数必须在所有的链表操作之前调用,而且它不能被重复执行。

__u32 skb_queue_len(struct sk_buff_head *list)

返回队列中排队的缓冲区的数目。

void skb_queue_tail(struct sk_buff *skb)

这个函数在链表的尾部添加一个缓冲区,这是在缓冲区操作函数中最常用的一个函数。

void skb_unlink(struct sk_buff *skb)

这个函数从链表中移去一个缓冲区。它只是将缓冲区从链表中移去,但并不释放它。

 

许多更复杂的协议,如TCP协议,当它接收到数据时,需要保持链表中数据帧的顺序或对数据帧进行重新排序。有两个函数完成这些工作:

 void skb_append(struct sk_buff *entry, struct sk_buff *new_entry)

 void skb_insert(struct sk_buff *entry, struct sk_buff *new_entry)

它们可以使用户把一个缓冲区放在链表中任何一个位置。

 

2.创建或取消一个缓冲区结构的函数

    这些操作用到内存处理方法,它们的正确使用对管理内存非常重要。sk_buff结构的数量和它们占用内存大小会对机器产生很大的影响,因为网络缓冲区的内存组合是最主要一种的系统内存组合。

struct sk_buff *alloc_skb(int size, int priority)

创建一个新的sk_buff 结构并将它初始化。

void kfree_skb(struct sk_buff *skb, int rw)

释放一个skb_buff

struct sk_buff *skb_clone(struct sk_buff *old, int priority)

复制一个sk_buff,但不复制数据部分。

struct sk_buff *skb_copy(struct sk_buff *skb)

完全复制一个sk_buff

 

3.对 sk_buff 结构数据区进行操作的操作。

    这些函数用到了套接字结构体中两个域:缓冲区长度(skb->len) 和缓冲区中数据包的实际起始地址 (skb->data)。这些两个域对用户来说是可见的,而且它们具有只读属性。

unsigned char *skb_headroom(struct sk_buff *skb)

返回sk_buff结构头部空闲空间的字节数大小

unsigned char *skb_pull(struct sk_buff *skb, int len)

该函数将 data 指针向数据区的末尾移动,减少了len 字段的长度。该函数可用于从接收到的数据头上移去数据或协议头。

unsigned char *skb_push(struct sk_buff *skb, int len)

该函数将 data 指针向数据区的前端移动,增加 了len 字段的长度。在发送数据的过程中,利用该函数可在数据的前端添加数据或协议头。

unsigned char *skb_put(struct sk_buff *skb, int len)

该函数将 tail  指针向数据区的末尾移动,增加了 len 字段的长度。在发送数据的过程中,利用该函数可在数据的末端添加数据或协议尾。

unsigned char *skb_reserve(struct sk_buff *skb, int len)

该函数在缓冲区头部创建一块额外的空间,这块空间在 skb_push  添加数据时使用。因为套接字建立时并没有为 skb_push 预留空间。它也可以用于在缓冲区的头部增加一块空白区域,从而调整缓冲区的大小,使缓冲区的长度统一。这个函数只对一个空的缓冲区才能使用。

unsigned char *skb_tailroom(struct sk_buff *skb)

返回sk_buff尾部空闲空间的字节数大小

unsigned char *skb_trim(struct sk_buff *skb, int len)

该函数和 put 函数的功能相反,它将 tail  指针向数据区的前端移动,减小了 len 字段的长度。该函数可用于从接收到的数据尾上移去数据或协议尾。如果缓冲区的长度比“ len”还长,那么它就通过移去缓冲区尾部若干字节,把缓冲区的大小缩减到“ len”长度。