mbuf的主要用途是保存子进程和网络接口间互相传递的用户数据。但mbuf也用于保存其它各种数据:源于目的地址、插口
选项等等。
以下介绍我们要遇到的四种类型的mbuf,它们根据在成员m_flag中填写的不同标志M_PKTHDR和M_EXT而不同。
1.假设m_flags等于0,mbuf仅仅包括数据,在mbuf中有108字节的数据空间(m_dat数组)。指针m_data指向这108字节缓
存中的某个位置。我们所看到的的m_data指向缓存的起始,但它能指向缓存中的任何位置。成员m_len指示了从m_data開始的
数据字节数。
2.第二类mbuf的m_flags值是M_PKHTR,它指示这是一个分组首部,描写叙述一个分组数据的第一个mbuf。数据仍然保存在这个
mbuf中,可是因为分组首部占用了8字节,仅仅有100字节的数据可存储在这个mbuf中(在m_pktdat数组中)。
成员m_pkthdr.len的值是这个分组的mbuf链表中全部数据的总长度:即全部通过m_next指针链接的mbuf的m_len值的和,输出
分组没有使用成员m_pkthdr.rcvif,但对于接收的分组,它包括一个指向接口ifnet结构的指针。
3.下一种mbuf不包括分组首部(没有设置K_PKTHDR),但包括超过208字节的数据,这是用到一个叫簇的外部缓存
(设置M_EXT)。在此mbuf中仍然为分组首部结构分配了空间,但没实用。Net/3分配一个大小为1024或2048字节的簇,而不是
使用多个mbuf来保存数据。这个mbuf中,指针m_data指向这个簇中的某个位置。
4.最后一类mbuf包括一个分组首部,并包括超过208字节的数据,同一时候设置了标识M_PKTHDR和M_EXT。
有几点须要说明:
1.mbuf结构的大小总是128个字节,这意味着上图mbuf在m_ext后面的未用空间为88字节。
2.既然有些协议(如UDP)同意零长记录,当然就能够有m_len为0的数据缓存。
3.在每一个mbuf中的成员m_data指向对应缓存的開始。这个指正能指向对应缓存的任何位置,不一定是起始。
4.带有簇的mbuf总是包括缓存的起始地址(m_ext.ext_buf)和它的大小(m_ext.ext_size)。成员m_data和m_ext.ext_buf值
是不同的,除非m_data也指向缓存的第一个字节。结构m_ext的第三个成员ext_free,Net/3当前未使用。
5.指针m_next把mbuf链接在一起,把一个分组形成一条mbuf链表。
6.指针m_nextpkt把多个多个分组链接成一个mbuf链表队列。在队列中的每一个分组能够使一个单独的mbuf,也能够是一个
mbuf链表。每一个分组的第一个mbuf包括一个分组首部,假设多个mbuf定义一个分组,仅仅有第一个mbuf的成员m_nextpkt被
使用,其它的都是空指针。
下图所看到的是一个队列中两个分组的样例。
mbuf的定义例如以下:
有非常多操作mbuf的函数,比方我们要发送一个分组,则须要创建新的mbuf,并将分组数据拷贝到mbuf中,使用完分组后,须要
释放掉mbuf。
宏函数例如以下:
普通函数例如以下: