取消
显示结果 
搜索替代 
您的意思是: 
cancel
4888
查看次数
18
有帮助
4
评论
goldyear20201
Spotlight
Spotlight
本帖最后由 goldyear 于 2017-8-29 17:48 编辑
【原创】先说结论:

测试IP分片重组时,具体字段的设置方式如下(通过抓包可以观察)
1) first-fragment: MF=1,fragment offset=0,DF=0 or 1
2) non-first-fragment: MF=1,fragment offset!=0,DF=0 or 1
3) non-fragment: MF=0(即Last fragment),fragment offset=0,DF=0 or 1
4) non-or-first-fragment: 同上1)+3)
5) small-fragment:any fragment offset=1,2,3 MF/DF任意
6) any-fragment: any fragment offset!=0 MF/DF任意

7) 判断数据包没有被分割,在Flags标记中,More fragments被置为0(也就是Last Fragments),所以说明后面分段了
8) First fragment, Offset=0,Non-First fragment,Offset!=0

-----------------------------
以上是IP分片重组概念和测试设置方式
具体原理如下:

链路层具有最大传输单元MTU这个特性,它限制了数据帧的最大长度,不同的网络类型都有一个上限值。以太网的MTU是1500,可以用 netstat -i 命令查看这个值。如果IP层有数据包要传,而且数据包的长度超过了MTU,那么IP层就要对数据包进行分片(fragmentation)操作,使每一片的长度都小于或等于MTU。我们假设要传输一个UDP数据包,以太网的MTU为1500字节,一般IP首部为20字节,UDP首部为8字节,数据的净荷(payload)部分预留是1500-20-8=1472字节。如果数据部分大于1472字节,就会出现分片现象。
当提交给数据链路层进行传送时,一个IP分片或一个很小的无需分片的IP数据报称为分组。数据链路层在分组前面加上它自己的首部,并发送得到的帧。

IP首部(5-8字节)包含了分片和重组所需的信息:


IdentificationRDFMFFragment Offset


<-----16------><---3------><-------13------->

Identification:发送端发送的IP数据包标识字段都是一个唯一值,该值在分片时被复制到每个片中。
R:保留未用。
DF:Don't Fragment,“不分片”位,如果将这一比特置1 ,IP层将不对数据报进行分片。
MF:More Fragment,“更多的片”,除了最后一片外,其他每个组成数据报的片都要把该比特置1。
Fragment Offset:该片偏移原始数据包开始处的位置。偏移的字节数是该值乘以8。

两个Flags和Fragment Offset结合使用,进行分片时,DF比特设置为0,表示可以进行分片(如果为1,表示不分片),这时如果 MF的值为1,则表示当前IP报文是一个IP包的其中一段分片,并且不是最后一个分片(如果MF=0,即Last Fragments,为非分片或者最后一个分片),这时结合Fragment Offset域继续判断;如果MF为1而 Fragment Offset = 0,表示该IP报文为第一个分片,而且后续有分片;如果MF为1而Fragment Offset不是0,表示该IP报文为中间的一个分片;如果MF为0而Fragment Offset不是0,表示该报文是最后一个分片。如果MF为0而Fragment Offset是0,表示该报文为non-fragment。
另外,当数据报被分片后,每个片的总长度值要改为该片的长度值。


举例说明IP分片重组的过程
1)
假设分片前报文IHL=5, Total Length = 800, MF = 0, Fragment Offset = 0, MTU为512;
则分片报文1的IHL1 = 5, Total Length1 = 508, MF = 1, Fragment Offset1 = 0;
分片报文2的IHL2 = 5, Total Length2 = 312, MF = 0, Fragment Offset2 = 61。
(IHL-Internet Header Length 报头长度,位于IP报文的第二个字段,4bit,表示IP报文头部按32位字长(32位,4字节)计数的长度,也即报文头的长度等于IHL的值乘以4。
由于IPv4的头部为变长,所以需要用该字段来标示IP报文头的长度,也等同于数据字段的偏移量。最小为5,即5×32 = 160位 = 20字节。最大为15,表示15×32 bits = 480位 = 60字节。)
其中Total Length1 + Total Length2 = 508+312 = 820,比 Total Length多出的20字节为新增的IP头,并且由于偏移量的单位为8Byte,所以非尾片的净荷长度都是8Byte的整数倍,MTU为512Byte,去除IP头IHL*4 = 5*4 = 20Byte后得到512-20 = 492Byte, 492Byte不是8Byte的整数倍,就取488Byte,加上IP头得到488+20 = 508Byte。由于报文1的净荷为488Byte,所以报文2的Fragment Offset就是 488/8 = 61, Total Length2 为总净荷长度(Total Length -IHL*4 = 800-20 = 780Byte)减去报文1的净荷长度488Byte加上报文2的IP头20Byte得到780-488+20 = 312Byte。

2)
同样可假设重组前报文1的IHL = 5, Total Length1 = 1012 , MF = 1, Fragment Offset1 = 0;
报文2的IHL = 5, Total Length2 = 312, MF = 0, Fragment Offset2 = 124。
则重组后的报文IHL = 5, Total Length = 1304, MF = 0, Fragment Offset = 0。
其中报文1的净荷长度为Total Length1 – IHL1*4 = 1012-20 = 992Byte, Fragment Offset1 = O, MF = 1,表示报文1有后续报文并且报文1的后续报文偏移量应该是0*8 + 992 = 992Byte,而报文2的 Fragment Offset2 = 124,则偏移量为124 * 8 = 992Byte,所以报文1和报文2是相连的,并且MF = 0 表示报文2为最后一个分片,此时就得到了原来的报文重组完成,重组后的报文 MF = 0, Fragment Offset = 0,Total Length 为报文1的净荷长度(992Byte)加上报文2的净荷长度(Total Length2 –IHL*4 = 312 - 20 = 292Byte)加上IP报文头20Byte为992 + 292 + 20 = 1304Byte。

评论
sxsure001
Spotlight
Spotlight
感谢分享,,,,赞lollol
gcq
Level 1
Level 1
这个很好,一般工程师对这个都比较模糊吧。
goldyear20201
Spotlight
Spotlight
一般做DPI或者研发测试,可能会用到
cxpxm119114
Level 1
Level 1
谢谢分享!即使不做研发,但可澄清很多概念:)
入门指南

使用上面的搜索栏输入关键字、短语或问题,搜索问题的答案。

我们希望您在这里的旅程尽可能顺利,因此这里有一些链接可以帮助您快速熟悉思科社区:









快捷链接