用户反馈说对最近捕获到的数据包内容感到困惑,其中的两个以太网数据包,看起来像是 TCP/IP 有效负载的两个分片,因为它有以太网标识 IPv4 (0x0800),IP ID 显示相同的值,并且源/目的 IP 地址和端口也一致。
但是这两个数据包的 IPv4 首部却没有 IP 分片的几个标识:
如果按用户所反馈的数据包现象来说,确实是一个比较奇怪的案例,但是网络协议分析讲究眼见为实,毕竟谁也不是猜测的专家。
数据包跟踪文件基本信息如下:
λ capinfos "IP_Id 4958 Frag_Offset ZERO.pcapng"
File name: IP_Id 4958 Frag_Offset ZERO.pcapng
File type: Wireshark/... - pcapng
File encapsulation: Ethernet
File timestamp precision: microseconds (6)
Packet size limit: file hdr: (not set)
Number of packets: 6
File size: 2940 bytes
Data size: 2492 bytes
Capture duration: 0.098405 seconds
First packet time: 2017-07-28 02:03:15.503250
Last packet time: 2017-07-28 02:03:15.601655
Data byte rate: 25 kBps
Data bit rate: 202 kbps
Average packet size: 415.33 bytes
Average packet rate: 60 packets/s
SHA256: 08bb3b445b865e80b7b02000a002d387f3e23eaa746e8bfec3e2020d10af9a31
RIPEMD160: f3f7570c672bb7bfabcbfe006c3fc2b119237bfb
SHA1: 1ffc38d630487447cb203ac593da3f8e36835177
Strict time order: True
Capture oper-sys: 64-bit Windows 10, build 15063
Capture application: Dumpcap (Wireshark) 2.2.6 (v2.2.6-0-g32dac6a)
Number of interfaces in file: 1
Interface #0 info:
Name = \Device\NPF_{04A953BC-ADF6-4F27-9F29-205A684C378D}
Encapsulation = Ethernet (1 - ether)
Capture length = 262144
Time precision = microseconds (6)
Time ticks per second = 1000000
Time resolution = 0x06
Operating system = 64-bit Windows 10, build 15063
Number of stat entries = 0
Number of packets = 6
数据包数量仅为 6 个,抓包客户端系统为 Win10 ,Wireshark 直接抓取。整个数据包内容也并无任何告警信息,一切正常。
基于上述数据包内容,包括 Wireshark 的判断分析,实际上是没有任何问题的,但如用户反馈,疑似有 IP 分片存在,判断的理由是存在相同的 IP ID 。
展开 IP ID 信息,确实如用户所述,No.2 和 No.4 数据包存在同样的 IP ID 值 0x135e 。
首先什么是 IP ID ? 实际上指的是 IPv4 Identification,详情可见 RFC 791
:
Identification: 16 bits
An identifying value assigned by the sender to aid in assembling the fragments of a datagram.
如 RFC 791
说明,IP ID 是一个由发送端所分配的一种标识值,用于协助组装数据报分片。同样在 RFC 6864 Updated Specification of the IPv4 ID Field
也一样定义了相关概念:
In IPv4, the Identification (ID) field is a 16-bit value that is unique for every datagram for a given source address, destination address, and protocol, such that it does not repeat within the maximum datagram lifetime (MDL) [RFC791] [RFC1122]. As currently specified, all datagrams between a source and destination of a given protocol must have unique IPv4 ID values over a period of this MDL, which is typically interpreted as two minutes and is related to the recommended reassembly timeout [RFC1122]. This uniqueness is currently specified as for all datagrams, regardless of fragmentation settings.
在 IPv4 中 ID 对于给定的源地址、目的地址和协议,它是唯一的,在最大数据报生命周期内不会重复。一般来说,发送端常见的是一个递增显示的值,举例如下。当然在给定源地址、目的地址和协议的情况下,同时间传输的不同 Stream ,IP ID 值会共享使用,所以有时在同一条流中上下数据包的IP ID 值会有所间隔,并不是连续的。
再说到 IP 分片,因为分片和重组的需要,需唯一标识 ID,这样同一个数据报因为分片的要求,最终会产生有着同样 IP ID 的多个数据报。下例以一个 Ping 大包 5600 字节为例,由于 MTU 1500 的缘故,分成 4 个数据报,不论是 icmp request 或是 icmp reply 。
综上所述,用户是在基于 IP ID 重复的一个条件下,判断是有分片的情况,但是却又不存在分片应该存在的字段,像是 Don’t fragment 、More fragments 等等,所以产生了疑问。
但实际上除了 IP 分片场景使得 IP ID 重复以外,在有些特殊场景也是会存在重复情况的:
用户的这个数据包跟踪文件也很好的说明了这个问题,No.1、No.2 和 No.4 实际上是三个连续的 TCP 分段,从 TCP Seq Num 很清楚说明了这个问题,并不是真正的 IP 分片,也自然没有分片字段的存在。而基于 RFC 对 IP ID 的使用定义,它的重复性并不会造成传输问题,也因此 Wireshark 在此判断是没有任何异常的。
因此对于用户的这个问题,我个人的判断是协议栈层面出错,分配出了重复的 IP ID 值,因为对运行环境的未知,问题有可能是在发送端,也有可能是中间设备。
抓牢基础知识点,结合各类场景,合理还原数据包一个真相。
https://osqa-ask.wireshark.org/questions/63427/fragment-offset-is-zero-0-but-same-senderrecipient-ipaddrportipid/
https://www.rfc-editor.org/rfc/rfc791.txt
https://www.rfc-editor.org/rfc/rfc6864.txt