问题背景
来自于群友的一个关于 IP 数据报分片的软考问题,主要如下,答案是 B 和 A。
假设一个IP数据报总长度为4000B,要经过一段MTU为1500B的链路,该IP数据报必须经过分片才能通过该链路。该原始IP数据报需被分成( )个片,若IP首部没有可选字段,则最后一个片首部中Ofiset字段为( )。
(1) A.2 B.3 C.4 D.5
(2) A.370 B.740 C.1480 D.2960
主要是第 2 个答案,以前研究 IPv4 Fragment Offset 的时候,自己也都是以实际数据帧长度像是 2960 字节理解,但仔细翻了下 RFC 文档发现并不是这样,研究了下还发现了一个 Wireshark 的问题,简单记录下。
问题分析
测试方式
简单在 Windows 主机上 ping 大包,ICMP 数据字段为 3992 字节,加上 ICMP 首部 8 字节,总长度为 4000 字节,同时进行了 Wireshark 抓包。
$ ping -l 3992 www.baidu.com
正在 Ping www.a.shifen.com [180.101.49.11] 具有 3992 字节的数据:
请求超时。
请求超时。
请求超时。
请求超时。
180.101.49.11 的 Ping 统计信息:
数据包: 已发送 = 4,已接收 = 0,丢失 = 4 (100% 丢失),
此处可忽略 ICMP 数据包分片带来的不通现象,为安全策略管控导致。
基础分析
数据帧1 和 数据帧 2
14 字节 ( Ethernet II 首部长度 ) + 20 字节 ( IPv4 首部长度 ) + 1480 字节(Data 长度) = 1514 字节
数据帧3
14 字节 ( Ethernet II 首部长度 ) + 20 字节 ( IPv4 首部长度 ) + 1040 字节(Data 长度) = 1074 字节
ICMP 1480+1480+1040 = 4000 字节 ,也就是分成了 3 片,数据帧 1 off = 0,数据帧 2 off = 1480,数据帧 3 off = 2960 。
理论上这样分析下来貌似没什么问题,包括数据帧 3 所显示的 2 进制 0 1011 1001 0000
确实就是十进制 2960
,16 进制应该是 0b 90
,但是 wireshark 显示却是 01 72
,哪一处出了问题???
查询了 RFC 791
,引用如下:
Fragment Offset: 13 bits
This field indicates where in the datagram this fragment belongs.The fragment offset is measured in units of 8 octets (64 bits). The first fragment has offset zero.
fragment offset 的单位是 8 字节,8 字节的由来?
首先又要从 IPv4 首部 Total Length 说起。因为 Total length 长度是 16 bit,能表示的最大值就是 2 的 16 次方,以 1 字节为单位,意味着 IPv4 数据包最大长度可能是 65536 字节,而 fragment offset 设计只有 13 bit,能表示的最大值也就是 2 的 13 次方,只能表示出 8192 ,所以定义了以 8 字节为单位,这样分片偏移量最大就能表示出 65536 字节。
所以数据帧 3 正确显示的 2 进制应该是 0 0001 0111 0010
, 十进制值应该是 370
,16 进制就是 01 72
,所以目前的 Wireshark 版本(Version 3.6.3) 在此处二进制的值显示会有些问题,有歧义~
…0 1011 1001 0000 = Fragment Offset: 2960 x
…0 0001 0111 0010 = Fragment Offset: 370 √
这个逻辑不知道 Wireshark 是如何定义的,把原始数据包的二进制直接给左移了3位,所以这个值算出来的十进制直接就是 2960, 就是为了在分组细节中显示真实偏移长度嘛???
进一步分析
为了验证这个问题,同样的数据包在科来中显示如下,数据帧 3 的二进制就是 0 0001 0111 0010
,后面会显示提示 2960 偏移字节,完全正确~
然后又翻查了 Wireshark 版本注释,并做了老版本的验证,发现在 Version 3.0.5 之前就都是 370 ,而到了 Version 3.0.6 开始之后就都变成了 2960 。。。。
Wireshark 3.0.6 Release Notes
https://www.wireshark.org/docs/relnotes/wireshark-3.0.6.html
Updated Protocol Support
AgentX, BT L2CAP, ERSPAN, GRE, IPv4, IS-IS, NAS 5GS, OpcUa, SNMP, and SRT
可能就在 IPv4 这一笔带过了。。。
总结
🤣 软考好难,要是我真碰到肯定就挂了,嗨,基础知识不牢靠。。
感谢阅读,更多技术文章可关注个人公众号:Echo Reply ,谢谢。