mbuf的主要用途是保存在进程和网络接口间互相传递的用户数据。但mbuf也用于保存其他各种数据:源与目标地址、插口选项等等。
下面将要经常会的遇到的四种不同类型的mbuf,它们依据在成员mh_flags中填写的不同标志M_PKTHDR和M_EXT而不同。
1) 第一类mbuf的mh_flags等于0,mbuf只包含数据,在mbuf中有108字节的数据空间,指针mh_data指向这108字节缓存中的某个位置。
2) 第二类mbuf的mh_flags值是M_PKTHDR,它指示这是一个分组首部,描述一个分组数据的第一个mbuf。数据仍然保存在这个mbuf中,但是由于分组首部占用了8字节,只有100字节的数据可存储在这个mbuf中。
3) 当分组数据超过208字节的数据时,如果采用前面提到的1/2类mbuf,需要3个或更多的mbuf,这时我们就要使用一种称之为簇的mbuf,就是我们下面讲到的mbuf。第3类m b u f不包含分组首部(没有设置M_PKTHDR),但包含超过208字节的数据,这时用到一个叫“簇”的外部缓存(设置M_EXT)。在此mbuf中仍然为分组首部结构分配了空间,但没有用。在这个mbuf中,指针mh_data指向这个簇中的某个位置。
4) 第四类mbuf包含一个分组首部,包含超过208字节的数据,同时设置了标志M_PKTHDR和M_EXT。
4种类型的mbuf结构如下图所示,下面代码中的定义简化了对结构成员变量的访问,是经常使用的一种编程手段,图中都是使用重定义后的名称。
#define m_next m_hdr.mh_next
#define m_len m_hdr.mh_len
#define m_data m_hdr.mh_data
#define m_type m_hdr.mh_type
#define m_flags m_hdr.mh_flags
#define m_nextpkt m_hdr.mh_nextpkt
#define m_act m_nextpkt
#define m_pkthdr M_dat.MH.MH_pkthdr
#define m_ext M_dat.MH.MH_dat.MH_ext
#define m_pktdat M_dat.MH.MH_dat.MH_databuf
#define m_dat M_dat.M_databuf
#define m_len m_hdr.mh_len
#define m_data m_hdr.mh_data
#define m_type m_hdr.mh_type
#define m_flags m_hdr.mh_flags
#define m_nextpkt m_hdr.mh_nextpkt
#define m_act m_nextpkt
#define m_pkthdr M_dat.MH.MH_pkthdr
#define m_ext M_dat.MH.MH_dat.MH_ext
#define m_pktdat M_dat.MH.MH_dat.MH_databuf
#define m_dat M_dat.M_databuf