TCP/IP之七:IP结构与IP分片

时间:2022-12-31 08:39:49

IP协议是TCP/IP的核心协议之一,正因为它的重要性,整个协议栈才叫做TCP/IP协议栈。它工作在网络层,起着重要的承上启下的作用。它的主要工作是完成IP分组的路由,并在必要时进行IP分片。

IP分组头部格式如下:

TCP/IP之七:IP结构与IP分片

(1)Version:版本号,说明是IPV4还是IPV6等等;

IHL即internet header length, IP分组头部长度,占4bit,以4字节为单位,因为这个字段只占4bit,最大值为15,导致IP首部最长只能为15*4(即60)字节;

Type of Service:服务类型,比如最少延迟之类;

Total Length:总长度字段,之所以需要总长度,是因为数据链路层有可能会往帧尾填充字节;

Identification:标识,用于分片的时候确定哪些分组原本属于同一个ip数据包,属于同一个数据包的分组具有相同的标识;

Flags:标志字段,包含3位,一位说明是否允许IP分片,一位说明是否后面还有分片,一位保留以后使用;

Fragment Offset:偏移量,IP分片后该分组在原数据包中的偏移量;

Time to Live:该分组可以经过的路由器数;

Protocol:协议类型,供上层协议复用之用;

Header Checksum:首部检验和;

Source Address:源IP地址;

Destination Address:目的IP地址;

Options:选项字段;

Padding:填充。 
(2)IP首部的固定字段有20个字节,选项和填充字段最大可以有40字节,总的最长可以为60字节。 
(3)IP首部的总长度字段为16bit,最大值可以为65535,所以如果光从IP层来看,IP分组的总长度可以有65535字节,但是实际上由于网络接口层的MTU的限制,导致IP分组不可能有这么大,当IP分组的大小长于网络接口层的MTU时需要进行IP分片,将IP数据包分成多个分组独立地在网络上传输。然而,IP层的65535的长度限制对传输层来讲几乎可以说是没有限制的。 
(4)Options字段,可以记录路由、时间戳等。


接下来来讲讲IP分片的相关话题。

我们可以通过命令netstat  -i 来查看自己所在网络的MTU。以下是我在主机上运行netstat -i的输出。可以看到eth0的MTU是1500字节,而本地环回接口的MTU是16436。

   1: Iface   MTU     Met   RX-OK RX-ERR RX-DRP RX-OVR    TX-OK TX-ERR TX-DRP TX-OVR Flg
   2: eth0    1500    0     2032  0      0      0         1428  0      0      0      BMRU
   3: lo      16436   0     8     0      0      0         8     0      0      0      LRU

但是这只是本主机所在局域网的MTU,当一个IP数据包企图跨网络进行传输时,情况要稍微复杂些,因为不同的网络可以有不同的MTU,IP数据包在传输过程中,只要有必要就会进行分片,这就是说,分片之后的IP数据包有可能再进行分片。一个IP包传输过程中所经过网络的最小MTU成为路径MTU。

路径MTU发现机制:通过发送设置了不允许分片的IP包,包大小逐渐增大,直到收到返回的不可达ICMP差错为止。

注意:IP在分片的过程中,如果不是最后一个分组,出去IP首部的数据域部分必须是8字节的整数倍。

在我的主机上的ping程序默认是设置了IP不允许分片的,当我ping 10.0.2.2 –c 1 –s 1472 时,tcpdump输出如下:

   1: 00:03:56.955624 IP spring > 10.0.2.2: ICMP echo request, id 1880, seq 1, length 1480
   2: 00:03:56.955901 IP 10.0.2.2 > spring: ICMP echo reply, id 1880, seq 1, length 1480

这是很正常的,并没有发生什么异常,这是因为总长度刚好等于1500,但是如果ping 10.0.2.2 –c 1 –s 1473 则结果如下:

   1: PING 10.0.2.2 (10.0.2.2) 1473(1501) bytes of data.
   2:  
   3: --- 10.0.2.2 ping statistics ---
   4: 1 packets transmitted, 0 received, 100% packet loss, time 0ms

对应的tcpdump监测结果如下

   1: 00:04:27.026043 IP spring > 10.0.2.2: ICMP echo request, id 1881, seq 1, length 1480
   2: 00:04:27.026078 IP spring > 10.0.2.2: icmp
   3: 00:04:27.026485 IP 10.0.2.2 > spring: icmp

2、3行的输出什么意思,是什么原因造成的,往知情者告知,不胜感激。