《TCP/IP详解 卷2:实现》 —1.9.3 添加IP和UDP首部
1.9.3 添加IP和UDP首部
在插口层将目标插口地址结构复制到mbuf中,并把数据复制到mbuf链中后,与此插口描述符(一个UDP描述符)对应的协议层被调用。明确地说,UDP输出例程被调用,指向mbuf的指针被作为一个参数传递。这个例程要在这150字节数据的前面添加一个IP首部和一个UDP首部,然后将这些mbuf传递给IP输出例程。
在图1-7中的mbuf链表中添加这些数据的方法是分配另外一个mbuf,把它放在链首,并将分组首部从带有100字节数据的mbuf复制到这个mbuf。在图1-8中显示了这三个mbuf。
图1-8 在图1-7中的mbuf链表中添加另一个带有IP和UDP首部的mbuf
IP首部和UDP首部被放置在新mbuf的最后,这个新mbuf就成了整个链表的首部。如果需要,它允许任何其他低层协议(例如接口层)在IP首部前添加自己的首部,而不需要再复制IP和UDP首部。在第一个mbuf中的m_data指针指向这两个首部的起始位置,m_len的值是28。在分组首部和IP首部之间有72字节的未用空间留给以后的首部,它们可通过适当地修改m_data指针和m_len添加在IP首部的前面。稍后我们会看见以太网首部就是用这种方法建立的。
注意,分组首部已从带有100字节数据的mbuf中移到新mbuf中去了。分组首部必须放在mbuf链表的第一个mbuf中。在移动分组首部的同时,在第一个mbuf设置M_PKTHDR标志并且在第二个mbuf中清除此标志。在第二个mbuf中分组首部占用的空间现在未用。最后,在此分组首部中的长度成员由于增加了28 字节而变成了178。
然后UDP输出例程填写UDP首部和IP首部中它们所能填写的部分。例如,IP首部中的目标地址可以被设置,但IP检验和要留给IP输出例程来计算和存放。
UDP检验和计算后存储在UDP首部中。注意,这要求遍历存储在mbuf链表中的所有150字节的数据。这样,内核要对这150字节的用户数据做两次遍历:一次是把用户缓存中的数据复制到内核中的mbuf中,一次是计算UDP检验和。对整个数据的额外遍历会降低协议的性能,在后续章节中我们会介绍另一种可选的实现技术,它可以避免不必要的遍历。
接着,UDP输出例程调用IP输出例程,并把此mbuf链表的指针传递给IP输出例程。
- 点赞
- 收藏
- 关注作者
评论(0)