mbuf的种类:
mbuf,全称为"memory buffer",主要用于保存进程和网络接口间互相传递的用户数据,也用于保存源与目标地址,插口选项等。
mbuf 依据m_flags中填写的不同标志M_PKTHDR和M_EXT而不同。mbuf主要有四种:
1):m_flags 为 0 ,mbuf只包含数据。mbuf中有108字节的数据空间,指针m_data指向108字节缓存的某一位置。
2):m_flags 为 M_PKTHDR,这表示一个分组首部,描述一个分组数据的第一个mbuf。
3):这种mbuf不包含分组首部(没有设置K_PKTHDR),但包含超过208字节的数据,这时用到了一个外部缓存cluster(需要设置M_EXT)
4):最后一个包含一个分组首部,包含超过208字节的数据
这四种mbuf的区别如下图所示:
mbuf的结构:
/* mbuf的头部信息 */
struct m_hdr {
struct mbuf *mh_next; /* 指向链中下一个mbuf的指针 */
struct mbuf *mh_nextpkt; /* 指向下一个链的指针 */
int mh_len; /* mbuf中数据的长度(不包括头部) */
char *mh_data; /* 指向数据区的指针 */
short mh_type; /* mbuf的数据类型,如MT_DATA*/
short mh_flags; /* mbuf标识,具体定义见下 */
};
/* mbuf标识*/
#define M_EXT 0x0001 /* has associated external storage */
#define M_PKTHDR 0x0002 /* start of record */
#define M_EOR 0x0004 /* end of record */
struct pkthdr {
int len; /* 整个mbuf链表包含数据的总长度,在链表的第一个mbuf中维护一个带有总长度的分组首部的原因是,当需要总长度时可以避免查看所有mbuf中的mh_len来求和*/
struct ifnet *rcvif; /* 指向接收分组的接收接口结构的指针*/
};
struct m_ext{
caddr_t ext_buf; // start of buffer
void (*ext_free)(); //free routine if not the usual
u_int ext_size;
};
struct mbuf {
struct m_hdr m_hdr;
union {
struct {
struct pkthdr MH_pkthdr; /* M_PKTHDR set */
union {
struct m_ext MH_ext; /* M_EXT set */
char MH_databuf[MHLEN];
} MH_dat;
} MH;
char M_databuf[MLEN]; /* !M_PKTHDR, !M_EXT */
} M_dat;
};
关于m_flags 的取值,前面我们已经议论了M_EXT 和M_PKTHDR.这里m_flags 的取值有五种