《TCP/IP详解卷2:实现》笔记--IP的分片和重装

IP首部内有三个字段实现分片和重装:标识字段(ip_id)、标志字段(ip_off的3个高位比特)和偏移字段(ip_off的13个低位

比特)。标志字段由3个1bit标志组成。比特0是保留的必须为0,;比特1是“不分片”(DF)标志;比特2是“更多分片”(MF)标志。

Net/3中,标志和偏移字段结合起来,由ip_off访问,如下图所示:

ip_off的其他13bit指出在原始数据报内分片的位置,以8字节为单位计算。因此,除最后一个分片外,其他的分片都希望是一个

8字节倍数的数据,从而使后面的分片从8字节边界开始。下图显示了在原始数据报内的字节偏移关系,以及在分片的IP首部内

分片的偏移。

除最后一个分片外,设置了其余分片的MF比特。

ip_id唯一地标识某个特定数据报的分片。源系统用相同的源地址(ip_src)、目的地址(ip_dst)和协议(ip_p)值,作为

数据报在互联网上生命期的值,把每个数据报的ip_id设置成一个唯一的值。

1.分片

在ip_output函数(IP:网际协议章节)中,如果分组正好适合选定出接口的MTU,就在一个链路级帧中发送它。否则,必须对

分组分片,并在多个帧中将其发送,分组可以是一个完整的数据报或者它自己也是前边系统创建的分片。分片的代码主要

分三部分:

1.确定分片大小

如果DF被设置,则ip_output丢弃该分组,并返回,如果该数据报是在本地生成的,则运输层协议把该错误传回该进程,如果

分组是被转发的,则生成ICMP目的不可达差错报文。

Net/3没有实现“路径MTU发现”算法。

每个新的分片中包含:一个IP首部,某些原始分组中的选项以及最多len长度的数据。其中len的计算是用接口的MTU减去分组

首部的长度后,去掉低位的3比特后成为8字节倍数。

2.构造分片表

从第二个分片开始构造分片表,在表生成后,原来的分组被转换成第一个分片(减少一次mbuf的生成),对于每一个分片,

ip_output函数采取以下动作:

分配一个新的分组缓存

从原来的分组中把IP首部和IP选项复制到新的分组,并不是所有的选项都会被复制,如果IPOPT_COPIED指示copied比特被

置位,则会把选项复制到芯片中。

设置MF比特和偏移字段(ip_off)

为分片设置长度

从原始分组中把数据复制到该分组中

调整新创建的分片的mbuf分组首部,使其具有正确的全长,把新分片的接口指针清零,把ip_off转换成网络字节序,计算新

分片的检验和。将该分片通过mbuf的m_nextpkt与前面的分片链接起来。

3.构造第一个分片并发送分片

将末尾多余的数据截断后,原来的分组就被转换成第一个分片,同时设置MF比特、把ip_len和ip_off转换成网络字节序,计算

新的检验和。在这个分片中,保留所有的IP选项。在目的地址重装时,只保留数据报的第一个分片的IP选项。某些选项,如

源路由选项,必须被复制到每个分片中,即使在重装时都被丢弃了。

最后将每个分片进行发送。在发送期间遇到所有错误都会使后面的分片被丢弃。

2.重装

ipintr重装分片,并把数据报整个地交给运输层处理。ipintr需要尝试把分片重装成一个完整的数据报。

Net/3在一个全局双向链表ipq上记录不完整的数据报。可以在链表的任何地方插入和删除,并不限制一定要在末尾。ipintr

函数对表进行线性搜索,为当前分片找到合适的数据报。记住分片是由4元组{ip_id、ip_src、ip_des和ip_p}唯一标识的。ipq

的每个入口是一个分片表,如果ipintr赵大牌一个匹配,则fp指向匹配的表。ipq的数据结构如下:

许多工作是由ip_reass做的。如果ip_reass通过把当前分片与以前收到的分片组合在一起,能重装成一个完整的数据报,它就返回

指向该重装好的数据报的指针。如果没有重装好,则ip_reass保存该分片,ipintr去处理下一个分片。

如果重装处理产生一个完整的数据包,ipintr就把这个完整的数据报上传给合适的运输层。

3.ip_reass函数

ipintr把一个要处理的分片和一个指针传给ip_reass,其中指针指向的是ipq中匹配的重装首部。ip_reass可能重装成功并返回

一个完整的数据报,可能把该分片链接到数据报的重装链表上,等待其他分片到达后重装。每个重装链表的表头是一个ipq结构。

用来标识一个数据报分片的四个段,ip_id、ip_src、ip_dst和ip_p,被保存在每个重装链表表头的ipq结构中。Net/3用next和prev

构造数据报链表,用ipq_next和ipq_prev构造分片的链表。

到达分组的IP首部被放到重装链表之前,首先被转换成一个ipasfrag结构。

ip_reass在一个由ipf_next和ip_prev连接起来的双向循环链表上,收集某个数据报的分片。下图显示了分片首部链表ipq和

分片ipasgrag之间的关系。

上图没有显示重装结构的所有复杂性。重装完全依靠把指针指向底层mbuf上的三个不同的结构。下图显示了mbuf、ipq结构、

ipasfrag结构和ip结构之间的关系。

图中含有大量的信息:

1.所有结构都放在一个mbuf的数据区内。

2.ipq链表由next和prev连接起来的ipq结构组成。每个ipq结构保存了唯一标识一个IP数据报的四个字段。

3.当作为分片链表的头访问时,每个ipq结构被看成是一个ipasfrag结构。这些分片由ipf_next和ipf_prev链接起来,分别

覆盖了ipq结构的ipq_next和ipq_prev成员。

4.每个ipasfrag结构都覆盖了到达分片的ip结构,与分片一起到达的数据在缓存中跟在该结构之后。

下图从逻辑的观点说明重装结构,该图显示了三个数据报的重装,以及ipq链表和ipasfrag结构之间的关系,阴影部分为缺少

的分片。

下面分几个部分说明重装

1.创建重装表

如果没有符合条件的ipq,则用新的数据报的第一个分片创建一个重装表。它分配一个mbuf来存放新表的头(一个ipq结构),

并把该结构插入到重装表的链表中。

2.重装超时

在Net/3中,使用生命期字段ipq_ttl来管理重超时,重装超过的初始值设置为60,每次内容调用ip_slowtimo时,ipq_ttl就减去1,

而内核每500ms调用ip_slowtimo一次。如果系统在接受到数据报的任一分片30秒后,还没有组装好一个完整的IP数据报,那么

系统就丢弃该IP重装链表。

3.数据报标识符

在目的主机上,分片包含的字节范围可能会互相覆盖,发生这种情况的原因是,当一个运输层协议重传某个数据报时,采用

与原来数据报不同的路由,而且分片的模式也可能不同,这就导致在目的主机上的项目覆盖。传输协议必须强制IP使用原来

ID字段,确保目的主机识别该数据报是重传的。

Net/3并不为运输层协议提供机制保证在重传的数据报中重用IP ID字段。在准备新数据时,ip_output通过增加全局整数ip_id

来赋一个新值。尽管如此,Net/3系统也能让运输层用相同ID字段重传IP数据报的系统上接收重叠分片。

下图说明分片可能会以不同的方式与已经到达的分片重叠。分片是按照它们到达目的主机的顺序编号的,重装的分片在图底部

显示,分片的阴影部分是被丢弃的多余字节。

4.重建数据报首部

ip_reass把ip指向链表的第一个分片,将ipasfrag结构恢复成ip结构。并将整个分组从重装链表中移走,丢弃表头的ipq结构,

调整缓存中的m_len和m_data,将前面被隐藏起来的第一个分片的首部和选项包含进来。

5.计算分组长度

计算缓存链中数据的字节数,并把值保存在m_pkthdr.len中。

《TCP/IP详解卷2:实现》笔记--IP的分片和重装,布布扣,bubuko.com

时间: 2024-10-11 22:32:30

《TCP/IP详解卷2:实现》笔记--IP的分片和重装的相关文章

《TCP/IP 详解 卷一》读书笔记-----IP静态 路由

1.主机中的路由表只能被守护进程routing daemon或者“redirect”类型的ICMP报文所更新. 2.在根据路由表进行路由选择时,判断的优先级从高到低依次为1)表中存在与目的IP完全匹配的表项2)表中存在与目的地址的网络地址匹配的表项3)表中存在default,即默认路由表项.经历上述三个步骤仍未匹配成功的,则丢弃该数据报. 3.netstat指令用于查看主机的路由表,如下图所示: 其中Gateway的“0.0.0.0”表示目的主机与当前主机在同一网段中,可直接到达,无需网关进行转

《TCP/IP详解卷1:协议》第14章 DNS:域名系统---读书笔记

<TCP/IP详解卷1:协议>第14章 DNS:域名系统---读书笔记 1.引言 5.指针查询 DNS中一直难于理解的部分就是指针查询方式,即给定一个IP地址,返回与该地址对应的域名. 当一个组织加入Internet,并获得DNS域名空间的授权,如noao.edu,则它们也获得了对应IP地址的in-addr.arpa域名空间的授权.在noao.edu这个例子中,它的网络号是140.252的B类网络.在DNS树中结点in-addr.arpa的下一级必须是该IP地址的第一字节(例中为140),再下

《TCP/IP详解卷1:协议》第17、18章 TCP:传输控制协议(2)-读书笔记

章节回顾: <TCP/IP详解卷1:协议>第1章 概述-读书笔记 <TCP/IP详解卷1:协议>第2章 链路层-读书笔记 <TCP/IP详解卷1:协议>第3章 IP:网际协议(1)-读书笔记 <TCP/IP详解卷1:协议>第3章 IP:网际协议(2)-读书笔记 <TCP/IP详解卷1:协议>第4章 ARP:地址解析协议-读书笔记 <TCP/IP详解卷1:协议>第5章 RARP:逆地址解析协议-读书笔记 <TCP/IP详解卷1:协

《TCP/IP详解卷1:协议》第5章 RARP:逆地址解析协议-读书笔记

章节回顾: <TCP/IP详解卷1:协议>第1章 概述-读书笔记 <TCP/IP详解卷1:协议>第2章 链路层-读书笔记 <TCP/IP详解卷1:协议>第3章 IP:网际协议(1)-读书笔记 <TCP/IP详解卷1:协议>第3章 IP:网际协议(2)-读书笔记 <TCP/IP详解卷1:协议>第4章 ARP:地址解析协议-读书笔记 <TCP/IP详解卷1:协议>第5章 RARP:逆地址解析协议-读书笔记 1.引言 具有本地磁盘的系统引导

《TCP/IP详解卷1:协议》第3章 IP:网际协议(1)-读书笔记

章节回顾: <TCP/IP详解卷1:协议>第1章 概述-读书笔记 <TCP/IP详解卷1:协议>第2章 链路层-读书笔记 1.引言 IP是TCP/IP协议族中最核心的协议.所有的TCP.UDP.ICMP及IGMP数据都以IP数据报格式传输.IP提供不可靠.无连接的数据报传送服务. (1)不可靠 它不能保证IP数据报能成功地到达目的地.IP仅提供最好的传输服务.如果发生某种错误,如某个路由器暂时用完了缓冲区,IP有一个简单的错误处理算法:丢弃该数据报,然后发送ICMP消息报给信源端.

《TCP/IP详解卷2:实现》笔记--域和协议

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">Net/3组把协议关联到一个域,并且用一个协议族常量来标识每个域.Net/3还通过所有的编址方法将协议分组.在一个域中</span> 的每个协议使用同类地址,并且每种地址只被一个域使用.作为结果,一个域能通过它的协议族或地址族常量唯一标识. 下图是是我们讨论的协议和常量. 1

《TCP/IP详解卷2:实现》笔记--IP编址

1.接口和地址 在本文中讨论的所有接口和地址结构的一个例子配置如下图所示: 上图中显示了我们三个接口例子:以太网接口,SLIP接口和环回接口.它们都有一个链路层地址作为地址列表中的第一个结点. 显示的以太网接口有两个IP地址,SLIP接口有一个IP地址,并且环回接口有一个IP地址和一个OSI地址. 所有的IP地址都被链接到in_ifaddr列表中,并且所有链路层地址能从ifnet_addrs数组访问. 后面的部分讨论上图的数据结构以及用来查看和修改这些结构的IP专用ioctl命令. 2.sock

《TCP/IP详解卷2:实现》笔记--接口层

提示:该实验所在的平台是在RedHat 6下 该实验成功的前提有三个: (1):windows能ping通linux系统 (2):关闭linux的防火墙 :执行指令 /etc/init.d/iptables  stop (3):让SeLinux关闭  :执行指令:  setenforce permissive 补充: SELinux(Security-Enhanced Linux) 是美国国家安全局(NSA)对于强制访问控制的实现,是 Linux历史上最杰出的新安全子系统.SELinux 是一个

《TCP/IP详解卷1:协议》第17、18章 TCP:传输控制协议(1)-读书笔记

章节回顾: <TCP/IP详解卷1:协议>第1章 概述-读书笔记 <TCP/IP详解卷1:协议>第2章 链路层-读书笔记 <TCP/IP详解卷1:协议>第3章 IP:网际协议(1)-读书笔记 <TCP/IP详解卷1:协议>第3章 IP:网际协议(2)-读书笔记 <TCP/IP详解卷1:协议>第4章 ARP:地址解析协议-读书笔记 <TCP/IP详解卷1:协议>第5章 RARP:逆地址解析协议-读书笔记 <TCP/IP详解卷1:协