IP协议详解 - IPv4头部结构

特点

IP协议是TCP/IP协议族的power,它为上层协议提供无状态无连接不可靠的服务。


无状态(stateless)是指IP通信的双方不同步传输数据的状态信息,因此所有IP数据报的发送、传输和接受都是相互独立、没有上下文关系。这种服务最大的缺点无法处理乱序和重复的IP数据报。

虽然IP数据报头部提供了一个标识字段用以标识一个唯一的IP数据报,但它是用来处理IP分片和重组的,而不是用来指示接受顺序的。

无状态服务的优点也很明显:简单、高效。无须为保持通信的状态而分配一些内核资源,也无需每次传输数据时都携带状态信息。


无连接(connectionless)是指IP通信双方都不长久地维持对方的任何信息。因此,上层协议每次发送数据时,都要明确指定对端的IP地址。


不可靠是指IP协议不能保证IP数据报时候能准确地到达接收端,它只是承诺尽最大努力(try best to do it)。发送错误时,只会通知上层协议,而不会试图重传。因此使用IP服务的上层协议需要自己实现数据确认、超时重传等机制以达到可靠传输的目的。


IPv4头部结构


4位版本号(version)指定IP协议的版本。对IPv4来说,其值是4。

4位头部长度(header length)标识该IP头部有多少个32bit字(4字节)。因为4位最大能表示15,所以IP头部最长是60字节。

8位服务类型(Type Of Service, TOS)包括一个3位的优先权字段(现在已经被忽略),4位TOS字段和1位保留字段(必须置0)。4位TOS字段分别表示:最小延时,最大吞吐量,最高可靠性和最小费用。只有一个能置1。应用程序应该根据实际需要来设置它。比如有像ssh和telnet这样的登录程序需要的是最小延时服务,而像ftp这样的服务则是需要最大吞吐量。

16位总长度(total length)是指整个IP数据报的长度,以字节为单位,因此IP数据报的最大长度是65535(2^16-1)字节。但由于MTU的限制,长度超过MTU的数据报都将被分片传输。所以实际传输的IP数据报的长度远远没有达到最大值。


接下来的3个字段则描述了如何实现分片。

16位标识(identification)唯一的标识主机发送的每一个数据报。其初始值有系统随机生成;每发送一个数据报,其值就加1。该值在数据报分片时被复制到每个分片中,因此同一个数据报的所有分片都具有相同的标识符。

3位字段的第一位保留。第二位(Don't Fragment, DF)表示“禁止分片”。如果设置了这个位,IP模块将不对数据报进行分片。在这种情况下,如果IP数据报长度超过MTU,则IP模块将丢弃数据报并返回一个ICMP差错报文。第三位(More Fragment,MF)表示“更多分片”。除了数据报的最后一个分片外,其他分片都要把它置1。

13位分片偏移(fragmentation offset)是分片相对原始IP数据报开始处(仅指数据部分)的偏移。实际的偏移值是该值左移3位(乘8)得到的。由于这个原因,处理最后一个IP分片外,每个IP分片的数据部分的长度必须是8的整数倍(这样才能保证后面的IP分片拥有一个合适的偏移值)。


8位生存时间(Time To Live, TTL)是数据报到达目的地之前允许经过的路由器跳数。发送端设置该值,常见的值为64。IP数据报没经过一个路由器,这个值就减1。当该值为0时,路由器将丢弃这个数据报,并向源端发送一个ICMP差错报文。TTL值可以用来防止数据报陷入路由循环。

8位协议(protocol)用来区分上层协议。file:///etc/protocols定义了所有上层协议对应的protocol字段的数值:

16位头部校验和(header checksum)由发送端设置,接收端对其使用CRC算法以校验IP数据报头部在传输过程中是否损坏。


32位的源端IP地址和目的端地址用来标识数据报的发送端和接收端。一般情况下,无论中间经过多少个路由,这两个地址在整个数据报的传读过程中保持不变。


IPv4最后一个选项字段(option)是可变长的可选信息。因为IP头部最长60个字节,所以这个部分最多40个字节。可用的IP选项包括:

  • 路由记录(record route),用来告知数据报途经的所有路由器都将自己的IP地址填入IP头部的选项部分,这样偶们就可以跟踪数据报的传递路径。
  • 时间戳(timestamp)告诉每个路由器都将数据报被转发的时间(或时间与IP地址对)填入IP头部的选项部分,这样就可以测量途径路由之间数据报传输的时间。
  • 松散源路由选择(loose source routing),制定一个路由器IP地址列表,数据报发送过程中必须经过其中所有的路由器。
  • 严格源路由选择(strict source routing),数据报只能经过被指定的路由器。

更多信息可以参考RFC1393。

使用tcpdump观察IPv4头部结构


sudo tcpdump -ntx -i lo 抓取本地回路上的数据包

此时观察tcpdump输出的第一个数据包:

IP 127.0.0.1.37136 > 127.0.0.1.23: Flags [S], seq 2679128991, win 65495, options [mss 65495,sackOK,TS val 2670277567 ecr 0,nop,wscale 7], length 0

0x0000: 4510 003c 0d5e 4000 4006 2f4c 7f00 0001

0x0010: 7f00 0001 9110 0017 9fb0 439f 0000 0000

0x0020: a002 ffd7 fe30 0000 0204 ffd7 0402 080a

0x0030: 9f29 33bf 0000 0000 0103 0307

该数据包描述的是一个IP数据报。这次我们开启了-x,使之输出数据包的二进制码。此包中一共包含60个字节,其中前20字节是IP头部,后40字节是TCP头部,不包括应用程序数据(length 0)。


原文链接:,转发请注明来源!
「IP协议详解 - IPv4头部结构」评论列表

发表评论