IPv4 报文格式

今天上课讲到这,感觉老师讲的挺好的,一些设计原理也讲的比较细致,特此记录一下。

首先 IPv4 整体报文格式如下(图来自 https://wenku.baidu.com/view/78c7a218590216fc700abb68a98271fe910eaf38.html):
IPv4 报文格式_第1张图片
因为书上网上讲 IPv4 的很多了,这里主要讲一些它们可能没提到或者我感兴趣的部分,所以看之前最好已经对这部分有一定了解。不想看全文的话,可以拖到最底下,那里是我写本文的主要目的。

文章目录

    • 版本号
    • 报头长度
    • 总长度
    • 标识字段
    • 标志字段
    • 分片偏移
    • IP 选项

版本号

IPv4 这部分填 4,IPv6 填 6

报头长度

报头长度字段占 4 位。其中每位的单位是 4 字节1。报头包括任选项。由于它是一个 4 位字段,因此报头最长为 60 字节。

对于一般数据报(没有任何 IP 选项),该字段的值为 5,即报头长度为 20 字节。

报头长度的计算公式为:报头长度 = 基本长度(20 字节)+ IP 选项长度

总长度

总长度字段是指整个 IP 数据报的长度,以字节为单位,占 16 比特。

由于该字段的长度为 16 比特,所以 IP 数据报的最大长度可达到 65536 字节。但是由于底层传输时对每次传送报文的长度有限制,当 IP 数据报的长度超过这个限制的时候2,传送这个数据报就得分片传送。例如,通常较为典型的用于以太网的该字段最大长度为 1500 字节。其中每片的区分靠 标识、标志和偏移量3 这三项来区分。当数据报分片的时候,总长度字段的值也应该变化成此片的长度,而不是 IP 数据报的总长度。

尽管 IP 支持传输一个长达 65536 字节的数据报,但是大多数的数据链路层都会对它进行分片处理;而且主机也要求不能接收超过 576 字节的数据报。由于 TCP 把用户数据报划分为若干段,因此一般来说这一点不会影响 TCP 的使用。另外大量使用 UDP 的应用(RIP、TFTP、BOOTP、DNS、SNMP 等等),它们都限制用户数据报长度为 512 字节,小于 576 字节,因此 IP 的这种限制也不会影响 UDP 的使用。

总长度的计算公式为:总长度 = 报头长度 + 数据长度

标识字段

标识字段相当于每个 IP 数据报的 ID,用于唯一的标识主机发送的每一个数据报。当一个数据报由于太长而被分片的时候,每片的标识都是一样的,这样目的主机可以知道这些分片的数据报是一个整体。

通常每发送一个报文,其值自动加一,当达到最大值时,重新从 0 开始编号。

标志字段

标志字段有三位,第一个字段没有使用。剩下两个字段如下:
IPv4 报文格式_第2张图片

DF 位被置 1 表示不要分片,它命令路由器不要将数据报分片,因为目的端不能重组分片。

分片偏移

分片偏移说明该分片在当前数据报的位置。分片偏移以 8 字节为单位4,这样偏移量 1 对应字节号 8,偏移量 2 对应字节号 16,依此类推。

例:假设网络的 MTU(最大传输单位)为 1400 字节。因此路由器将把到达的一个 4000 字节分为 3 片:

  • 第一段有 1400 字节数据,分片偏移为 0
  • 第二段有 1400 字节数据,分片偏移为 175
  • 第三段有 1200 字节数据,分片偏移为 350

IP 选项

IP 选项这个字段是数据报中一个可变长度的可选信息,最大为 40 字节。当前这些选项定义如下:

  1. 安全和处理限制(用于军事领域,详见 RFC1108)
  2. 记录路径(让每个路由器都记下该数据报的 IP 地址)
  3. 时间戳(让每个路由器都记下该数据报的 IP 地址和时间)
  4. 宽松的源站选路(为数据报指定一系列必须经过的 IP 地址)
  5. 严格的源站选路(为数据报指定一系列必须经过的 IP 地址,但是要求只能经过指定的这些地址,不能经过其他地址)

这些选项很少使用,并非所有的轴距和路由器都支持这些选项。

选项字段都是以 32 位,即 4 字节作为界限,在必要的时候插入值为 0 的填充字节,这样就能保证 IP 报头始终是 32 位的整数倍(这是报头长度字段要求的,因为报头长度字段每位代表 4 字节,即 32 位)


  1. 如果我们以 1 字节为单位的话,4 位报头长度可以表示 0-15 字节长度的报头。但是我们最小的数据报长度为 20 字节,以 1 字节为单位表示不了。经过一些衡量就设计为以 4 字节为单位,这样就可以表示 0 * 4 - 15 * 4 即 0-60 字节长度的报头。 ↩︎

  2. 对于这个限制我们可以使用 ping -f -l 字节数 目的IP 来复现,其中 -f 指定不要分片,-l 指定发送报文的长度,我们可以指定一个 2000 字节之类的。这样的话,会提示一个错误 需要拆分数据包但是设置 DF 。这就表明每个数据报其实有个长度限制。 ↩︎

  3. 同属于一个数据报的分片它们标识字段相同,目的主机就可以通过此字段将数据报分类。而每个分片的偏移量不同,目的主机就可以按此字节排序,来还原数据报。最后通过标志字段得到最后一片,从而完整的恢复数据报。 ↩︎

  4. 因为如果以 1 字节为单位,共 13 位最多只能表示处于当前数据报 2 13 2^{13} 213 字节处的分片。而我们知道一个数据报长度是用 16 位表示的,即最大 2 16 2^{16} 216 字节。想要用 2 13 2^{13} 213 字节表示完全 2 16 2^{16} 216 字节,我们就得构造一个 2 3 2^3 23 字节的映射,即分片偏移的每个字节代表总长度的 8 个字节。也正是因为这个原因,我们在划分分片大小的时候最好都划分成 8 的倍数。 ↩︎

你可能感兴趣的:(#,计算机网络)