wireshark简易抓包分析

测试ping时会发现一个现象:
在指定ping包长度后,实际发出的包总长=指定ping包长度+28

为什么ping -s指定大小n后,发出的包长为n+28呢?

先在不涉及分片的简单情况下抓包分析。
通过下方ping指令指定包长20Byte后,终端输出的结果显示实际发出去的包长却是48Byte(小于MTU 1500,此时ping包不会被分片)。

test@test-FTF:~$ ping 172.30.200.180 -s 20
PING 172.30.200.180 (172.30.200.180) 20(48) bytes of data.
28 bytes from 172.30.200.180: icmp_seq=1 ttl=63 time=0.253 ms
^C
--- 172.30.200.180 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1016ms
rtt min/avg/max/mdev = 0.153/0.203/0.253/0.050 ms

先看下ip协议定义的包头:

wireshark 分析包 wiresharkping包分析_网络

固定ip头为20Byte(除去可选字段的可变部分),片偏移值的单位为8字节(此值为n,代表着此包数据部分偏移量是8n Byte),整个ip头的长度按照4字节对齐。

icmp协议定义的头部如下,前4Byte固定头部,一般认为icmp request、reply等常见的报文类型头部8Byte(有4Byte的可变部分记录序列号+标识符):

wireshark 分析包 wiresharkping包分析_网络协议_02


下图为实际wireshark抓包,可以看到ping包的offset偏移量是0(因为有且只有一个包),ip包总长=48Byte。这里会发现,当指定ping包20Byte时,icmp包的data部分只有12Byte,与实际发出的48Byte相差了36Byte

wireshark 分析包 wiresharkping包分析_wireshark 分析包_03


其中20Byte很好理解是IP协议头,另外8Byte为ICMP头,但是多剩下的8Byte是哪里的呢?

查看wireshark显示的十六进制ICMP报文内容,一共28Byte:

0020         08 00 6e ff 12 89 00 0a 47 ae 2a 63 00 00   ....n.....G.*c..
0030   00 00 d4 37 0e 00 00 00 00 00 10 11 12 13         ...7..........

其中“47 ae 2a 63 00 00 00 00 ”是icmp时间戳,占了8Byte,正好是前面找不到原因的8Byte大小。所以多出来的36Byte=icmp协议头固定前8Byte+icmp时间戳8Byte+ip协议头20Byte。

由此知,icmp 报文格式还有一部分可选字段是记录时间戳,request和reply类型都会使用此字段:

wireshark 分析包 wiresharkping包分析_网络协议_04


这就是为什么指定了ping包长为20后,实际抓到的icmp报文长却是28(icmp data长12)、ip包长48

当通过ping -s len指定发出长度为len的ping包时,程序默认将固定的8Byte ICMP头部长度涵盖了进去,意味着icmp报文的数据段长度将设为(len-8)。但实际发出的icmp包可能使用了头部的可选数据段记录时间戳,导致实际发送时icmp包长增加了8Byte,总的ip包长增加了28Byte。

icmp大包是如何被分片的呢?

上面是未被分片的抓包,下面观察下被分片的icmp包的ip头部offset变化。
下方指令指定5000包长后,实际发出是5028Byte。28Byte的增量同理。

test@test-FTF:~$ ping 172.30.200.180 -s 5000
PING 172.30.200.180 (172.30.200.180) 5000(5028) bytes of data.
5008 bytes from 172.30.200.180: icmp_seq=1 ttl=63 time=21.9 ms
^C
--- 172.30.200.180 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 21.860/24.090/26.321/2.230 ms

当指定ping包长为5000时,每个发出的icmp报文的数据部分长度为5000-8=4992Byte,ICMP报文总长度为4992+8+8=5008Byte=5028-20。

对于ip层来说,待传输的ip层数据为5008Byte ICMP报文,ip层将对这5008Byte的数据进行分片,确保每个分片包加上ip头部后的包总长不超过1500,即会把ip层数据分为5008=1480*3+568这四部分,需要分成4个分片包发出。

一个ping包发出,wireshark会抓到四个fragmented ip 包,如下图:

wireshark 分析包 wiresharkping包分析_网络_05

2-5号是4个分片包。注意:第一列2-5这个序号不代表ip报文id,而是表明这个软件抓到的第几个包的序号。reassembled in #5代表着这些分片内容将在5号包内重组后显示。

  • 第一个分片包:ip头部header length这里二进制值为0101,转换成十进制为5,因为这个项值的单位是4Byte,这里代表的是ip头部长度为20Byte。ip包的数据部分长度1500-20=1480Byte
  • wireshark 分析包 wiresharkping包分析_数据_06

  • 第二个分片包:flags值为20b9=0010 0000 1011 1001,flags部分的最高位0是保留位,从左数第二高位0是DF位(DF位置1代表不分片),第三高位1是MF位(MF置1代表着more fragments后面还有分片包),后13位代表片偏移,片偏移为0 0000 1011 1001(185),此值单位是8Byte,所以表示的是185*8=1480 Byte的偏移量。对于第一个分片包的icmp数据来说,第一个包只存放了1480Byte的ICMP内容,故第二个分片包的片偏移为1480。
  • wireshark 分析包 wiresharkping包分析_网络协议_07

  • 第三个分片,flags值为2172=0010 0001 0111 0010,片偏移为0001 0111 0010(370),偏移量为3708=2960Byte。对于第一个分片包的icmp数据来说,前两个包存放了14802=2960Byte的ICMP内容,故第三个分片包的片偏移为2960。
  • wireshark 分析包 wiresharkping包分析_网络协议_08

  • 第四个分片,flags值为022b=0000 0010 0010 1011,片偏移为0 0010 0010 1011(555),偏移量为5558=4440Byte。对于第一个分片包的icmp数据来说,前三个包存放了14803=4440Byte的ICMP内容,故第四个分片包的片偏移为4440。最后一个分片的icmp数据长度为588-20=568Byte。注意,最后一个分片包的MF未置上,说明当前包就是最后一个分片了。
  • wireshark 分析包 wiresharkping包分析_wireshark_09

  • 在最后一个分片包内,wireshark会自动将前面收到的所有IP分片重组后显示在此包的ip数据部分,对比可发现前面三个分片ip头之后就只有ip data区,而最后一个分片ip头后是一个完整的icmp报文(16Byte头+4992Byte数据)。