IP包头(Packet Header)的格式

  • 版本(Version)——标识了数据包的IP版本号。这个4位字段的值设置为二进制的0100表示IP版本4(IPv4),设置为0110表示IP版本6(IPv6)。本章主要涉及的是IPv4,在第2章中主要讲述IPv6。在表11中列出了所有已分配的现行版本号及相关RFC。除4和6(早期提出的简单Internet协议——即SIP协议,也使用版本号6)之外,其他的所有版本号仅作为“历史产物”而存在,感兴趣的读者可以阅读相关的RFC。

  • 报头长度(header length)——字段长度为4位,正如字段名所示,它表示32位字长的IP报头长度。设计报头长度字段是因为数据包的可选项字段(在本节后面部分将会讨论)的大小会发生变化。IP报头最小长度为20个八位组,最大可以扩展到60个八位组——通过这个字段也可以描述32位字的最大长度。

  • 服务类型(Type of Service,ToS)——字段长度为8位,它用来指定特殊的数据包处理方式。服务类型字段实际上被划分为两个子字段:优先权和ToS。优先权用来设置数据包的优先级,这就像邮寄包裹一样,可以是平信、隔日送到或两日内送到。ToS允许按照吞吐量、时延、可靠性和费用方式选择传输服务。虽然ToS字段通常不用(所有位均被设置为 0),但是在开放式最短路径优先(OSPF)协议的早期规范中还是称为ToS路由选择的。优先权位偶尔在服务质量(QoS)应用中使用。图13的a部分简要地说明了8个ToS位,更详细的信息可以参见RFC1340和RFC1349。

在最近几年,ToS字段已经作为区分服务(Diffserv)架构的一部分被重新定义了。区分服务架构为IP数据包所创建的处理比通过相对严格的ToS定义所允许的处理灵活得多。在DiffServ下,我们能够在一台路由器上定义服务分类,将数据包归类到这些分类中去。路由器可以根据它们的分类使用不同的优先级对数据包进行排序和转发。每一个排序和转发的处理称为一个Per-Hop Behavior(PHB)。虽然DiffServ定义了这个架构或体系,但这个机制本身称为区分服务类别或简单地称为服务类别(CoS)。
图13中的(b)部分显示了ToS字段是如何重新定义的,开始的6个位现在构成了区分代码点(DiffServCodePoint,DSCP)。利用这6个位,我们可以使用任意数值或根据在区分服务体系结构中预先定义的服务类别,最多可以定义64个不同的服务类别,并可整理到PHB中。请注意,在IP报头中的这个字段保留了8位;区分服务体系结构重新定义了路由器对这个字段中数值的解释。
• 显式拥塞通知(Explicit Congestion Notification,ECN)——在图1-3中的显式拥塞通知是某些路由器用来支持显式拥塞通知的,当它支持该特性时,这些位可以用于拥塞信号(ECN=11)。
• 总长度(Total Length)——数据包总长度字段的长度为16位,以八位组为单位计,其中包括IP报头。接收者用IP数据包总长度减去IP报头长度,就可以确定数据包数据有效载荷的大小。16位长的二进制数用十进制表示最大可以为65535,所以IP数据包的最大长度是65535。
• 标识符(Identifier)——字段长度为16位,通常与标记字段和分段偏移字段一起用于数据包的分段。如果数据包原始长度超过数据包所要经过的数据链路的最大传输单元(MTU),那么必须将数据包分段为更小的数据包。
例如,一个大小为5000字节的数据包在穿过网络时,如果遇到一条MTU为1500字节的数据链路,即数据帧最多容纳大小为1500字节的数据包。路由器需要在数据成帧之前将数据包分段成多个数据包,其中每个数据包长度不得超过1500字节;然后路由器在每片数据包的标识字段上打上相同的标记,以便接收设备可以识别出属于一个数据包的分段。

• 标记字段(Flag)——长度为3位,其中第1位没有使用。第2位是不分段(DF)位。当DF位被设置为1时,表示路由器不能对数据包进行分段处理。如果数据包由于不能被分段而未能被转发,那么路由器将丢弃该数据包并向源点发送错误消息。这一功能可以在网络上用于测试MTU值。可以使用Ping工具可以对DF位进行设置测试。

• 分段偏移(Fragment Offset)——字段长度为13位,以8个八位组为单位,用于指明分段起始点相对于报头起始点的偏移量。由于分段到达时可能错序,所以分段偏移字段可以使接收者按照正确的顺序重组数据包。请注意,如果一个分段在传输中丢失,那么必须在网络中同一点对整个数据包重新分段并重新发送。因此,容易发生故障的数据链路会造成时延不成比例。另外,如果由于网络拥塞而造成分段丢失,那么重传整组分段会进一步加重网络拥塞。

• 生存时间(Time To Live,TTL)——字段长度为8位,在最初创建数据包时TTL即被设置为某个特定值。当数据包逐个沿路由器被传输时,每台路由器都会降低TTL的数值。当TTL值减为0时,路由器将会丢弃该数据包并向源点发送错误信息。这种方法可以防止数据包在网络上无休止地被传输。按照最初构想,TTL值以s(秒)为单位。如果数据包在路由器上被延迟的时间超过1s,路由器将会相应地调整TTL值。然而,这种方法实施起来十分困难,从来没有被广泛地支持。现代的路由器不管实际时延是多少,统统将TTL值减1,所以TTL实际上是表示跳数。
虽然TTL常见的值为15和32,但是建议的缺省值是64。像IOS软件中的trace命令这样的一些追踪工具使用的是TTL字段。如果路由器被告知需要追踪到达主机地址为10.11.12.13的路径,路由器将发送3个数据包,其中TTL值被设置为1;第1台路由器将会把TTL值减少到0,而且在丢弃数据包的同时向源点发送错误信息。源点路由器通过阅读错误信息从而得知发送错误信息的路由器即为路径上的第1台路由器。再一次被路由器发送的3个数据包的TTL值被设置为2。第1台路由器将TTL值减1,第2台路由器将TTL值再减1后为0,此时源点路由器将会接收到第2台路由器发送来的错误信息。第3次发送的数据包TTL值被设置为3,依此类推,直到目的地被发现。最终,沿着网络路径所有的路由器都会被标识出来。

• 协议(Protocol)——字段长度为8位,它给出了主机到主机层或传输层协议的“地址”或协议号,协议字段指定了数据包中信息的类型。当前已分配了100多个不同的协议号,表1-2给出了其中一些较常用的协议号。

在这里插入图片描述

• 报头校验和(Header Checksum)——是针对IP报头的纠错字段。校验和不计算被封装的数据,UDP、TCP和ICMP都有各自的校验和。报头校验和字段包含一个16位二进制补码和,这是由数据包发送者计算得到的。接收者将连同原始校验和重新进行16位二进制补码和计算。如果数据包传输中没有发生错误,那么结果应该16位全部为1。回忆前面所述内容,由于每台路由器都会降低数据包的TTL值,所以每台路由器都必须重新计算校验和。RFC1141讨论了一些简化计算的策略。

• 源地址和目的地址(Source and Destination Address)——字段长度为32位,分别表示发送者数据包源点和目的地的IP地址。IP地址的格式将会在1.3节中讨论。

• 可选项(Options)——是一个长度可变的字段,并像其名字所表示的,它是可选的。可选项被添加在包头中,包括源点产生的信息和其他路由器加入的信息;可选项字段主要用于测试。
常用的可选项如下:
松散源路由选择(Loose Source Routing)——它给出了一连串路由器接口的IP地址序列。数据包必须沿着IP地址序列传送,但是允许在相继的两个地址之间跳过多台路由器。
严格源路由选择(Strict Source Routing)——它也给出了一系列路由器接口的IP地址序列。不同于松散源路由选择,数据包必要严格按照路由转发。如果下一跳不再列表中,那么将会发生错误。
记录路由(Record Route)——当数据包离开时为每台路由器提供空间记录数据包的出站接口地址,以便保存数据包经过的所有路由器的记录。记录路由选项提供了类似于路由追踪的功能,但是不同点在于这里记录了双向路径上的出站接口信息。
时间戳(Timestamp)——除了每台路由器还会记录一个时间戳之外,时间戳选项十分类似于记录路由选项,这样数据包不仅可以知道自己到过哪里,而且还可以记录到达的时间。
还可以在Option 字段内使用Linux 内核模块 TOA,tcp option address ,用来传递记录源ip地址,多用在网关转发时(LB等SDN网关上);

• 填充(Padding)——该字段通过在可选项字段后面添加0来补足32位,这样保证报头长度是32位的倍数。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐