《TCP/IP详解 卷2:实现》 —2.6 m_devget和m_pullup函数

举报
华章计算机 发表于 2019/11/20 16:32:38 2019/11/20
【摘要】 本节书摘来自华章计算机《TCP/IP详解 卷2:实现》一书中第2章,第2.6.1节,作者是[美]加里R.赖特(Gary R.Wright),W. 理查德史蒂文斯(W.Richard Stevens),陆雪莹 蒋慧 等译 谢希仁 校。

2.6   m_devget和m_pullup函数

我们在讨论IP、ICMP、IGMP、UDP和TCP的代码时会遇到函数m_pullup。它用来保证指定数目的字节(相应协议首部的大小)在链表的第一个mbuf中紧挨着存放,即这些指定数目的字节被复制到一个新的mbuf并紧接着存放。为了理解m_pullup的用法,必须查看它的实现及相关的函数m_devget和宏mtod与dtom。在分析这些问题的同时我们还可以再次领会Net/3中mbuf的用法。

2.6.1   m_devget函数

当接收到一个以太网帧时,设备驱动程序调用函数m_devget来创建一个mbuf链表,并把设备中的帧复制到这个链表中。根据所接收的帧的长度(不包括以太网首部),可能导致4种不同的mbuf链表。图2-14所示的是前两种。

image.png

图2-14   m_devget创建的前两种类型的mbuf

1) 图2-14左边的mbuf用于数据的长度在0~84字节之间的情况。在这个图中,我们假定有52字节的数据:一个20字节的IP首部和一个32字节的TCP首部(标准的20字节的TCP首部加上12字节的TCP选项),但不包括TCP数据。既然m_devget返回的mbuf数据从IP首部开始,m_len的实际最小值是28:20字节的IP首部,8字节的UDP首部和一个0长度的UDP数据报。

m_devget在这个mbuf的开始保留了16字节未用。虽然14字节的以太网首部不存放在这里,但还是分配了一个14字节的用于输出的以太网首部,这是同一个mbuf,用于输出。我们会遇到函数icmp_reflect和tcp_respond,它们通过把接收到的mbuf作为输出mbuf来产生一个应答。在这两种情况中,接收的数据报应该少于84字节,因此很容易在前面保留16字节的空间,这样在建立输出数据报时可以节省时间。分配16字节而不是14字节是为了在mbuf中用长字对准方式存储IP首部。

2) 如果数据在85~100字节之间,就仍然存放在一个分组首部mbuf中,但在开始没有16字节的空间。数据存储在数组m_pktdat的开始,并且任何未用的空间放在这个数组的后面。例如在图2-14右边的mbuf显示的就是这个例子,假设有85字节数据。

3) 图2-15所示的是m_devget创建的第3种mbuf。当数据在101~207字节之间时,要求有两个mbuf。前100字节存放在第一个mbuf中(有分组首部的mbuf),而剩下的存放在第二个mbuf中。在此例中,我们显示的是一个104字节的数据报。在第一个mbuf的开始没有保留16字节的空间。

image.png

图2-15   m_devget创建的第3种mbuf

4) 图2-16所示的是m_devget创建的第4种mbuf。如果数据超过或等于208 字节(MINCLBYTES),要用一个或多个簇。图中的例子假设了一个1500字节的以太网帧。如果使用1024字节的簇,本例子需要两个mbuf,每个mbuf都有标志M_EXT,以及指向一个簇的指针。


【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。