当前位置: 首页 > news >正文

TCPIP详解 卷1协议 八 ICMPv4和ICMPv6 Internet控制报文协议

8.1——ICMPv4和ICMPv6 Internet控制报文协议

IP 协议本身并没有为终端系统提供直接的方法来发现那些发往目的地址失败的IP数据包。此外,IP 没有提供直接的方式来获取诊断信息(例如,哪些路由器在沿途中被使用了或使用一种方法来估计往返时间)。为了解决这些不足之处,将一个特殊的Internet控制报文协议(Internet Control Message Protocol,ICMP)[RFC0792] [RFC4443]与IP结合使用,以便提供与IP 协议层配置和 IP 数据包处置相关的诊断和控制信息。ICMP 通常被认为是 IP 层的一部分,它需要在所有IP 实现中存在。它使用IP 协议进行传输。因此,确切地说,它既不是一个网络层协议,也不是一个传输层协议,而是位于两者之间。

ICMP 负责传递可能需要注意的差错和控制报文。ICMP 报文通常是由 IP 层本身、上层的传输协议(例如TCP或者 UDP),甚至某些情况下是用户应用触发执行的。请注意,ICMP并不为IP 网络提供可靠性。相反,它表明了某些类别的故障和配置信息。最常见的丢包(路由器缓冲区溢出)并不会触发任何的 ICMP 信息。由其他协议如 TCP 来处理这种情况。

[RFC0792]包含ICMPv4官方基本规范,[RFC1122]和[RFC1812]对其进行了细化和澄清。[RFC4443]包含了ICMPv6的基本规范。[RFC4884]提供了一种方法来为某些ICMP 报文添加扩展对象。这项功能主要用于保存多协议标签交换(Multiprotocol Label Switching,MPLS)信息,以及显示在转发一个特定的数据报时使用到的接口和下一跳路由器。[RFC5508]给出了在通过NAT时ICMP的标准行为特征。在 IPv6 中,ICMPv6 不仅用于一些简单的错误报告和信令,它也用于邻居发现(Neighbor Discovery,ND),与 IPv4 中的 ARP起着同样的作用。它还包括用于配置主机和管理组播地址的路由器发现(Router Discovery)功能。最后,它也被用来帮助管理移动IPv6中的切换。

8.1.1 在IPv4和IPv6中的封装

ICMP报文是在IP数据报内被封装传输的

  • IPv4:协议(Protocol)字段值为1表示该报文携带了ICMPv4。ICMPv4头部包含了涵盖整个ICMP 数据段的校验和。

    image-20250506202723827

  • IPv6:ICMPv6报文可能开始于0个或者多个扩展头部之后。位于ICMPv6头部之前的最后一个扩展头部包含了一个值为58 下一个头部(Next Header)字段。ICMPv6头部包含了涵盖整个ICMP 数据段的校验和。这个校验和也涵盖了IPv6 头部中的源(Source)和目的IPv6 地址(Destination IPv6 Address)字段、长度(Length)字段和下一个头部(Next Header)字段。

    image-20250506202759204

ICMP 报文可能会像其他 IP数据报那样被分片,但是并不常见。

下图为ICMPv4和ICMPv6报文的格式,开头的 4 个字节在所有的报文中都是一样的,但是其余部分在不同的报文中不同。所有的 ICMP 报文都以 8 位的类型(Type)和代码(Code)字段开始,其后的 16 位校验和
(Checksum)字段涵盖了整个报文。ICMPv4 和ICMPv6 中的类型和代码字段值是不同的。

image-20250506203038738

在ICMPv4中,为类型字段保留了42个不同的值[ICMPTYPES],用于确定特定的报文。但是,大概只有 8 个是经常使用的。许多类型的 ICMP 报文也使用不同的代码字段值进一步指定报文的含义。校验和字段覆盖整个ICMPv4报文;在ICMPv6中,它将涵盖一个来自IPv6头部的伪头部(pseudo-header)。用于计算校验和的算法和用于计算IP头校验和的算法相同。请注意,这是一个端到端(end-to-end)的校验和例子。该校验和从发送方的ICMP报文被一路携带到最终的接收方。相比之下,IPv4头校验和在路由器的每一跳中都会改变。如果一个ICMP 实现收到一个校验和错误的ICMP 报文,该报文将被丢弃;没有 ICMP 报文可以表示收到的 ICMP 报文中的校验和是错误的。IP 层不能对数据报的有效载荷部分进行保护。如果ICMP不包括校验和,ICMP报文的内容就可能不正确,进而导致错误的系统行为。

8.2——ICMP报文

  • 差错报文:有关 IP 数据报传递的 ICMP 报文
  • 查询或信息类报文:以及信息采集和配置的ICMP报文

8.2.1 ICMPv4 报文

常见的ICMPv4 报文类型

  • 差错报文:
    • 目的不可达(类型 3)
    • 重定向(类型5)
    • 超时(类型11)
    • 参数问题(类型12)
  • 信息类报文:
    • 回显请求(类型8)
    • 回显应答(类型0)
    • 路由器通告(类型 9 )。路由器通告和路由器请求统一被称为路由器发现。
    • 路由器请求(类型10)。路由器通告和路由器请求统一被称为路由器发现。

image-20250506204442592

对于常用的报文(表 8-1 中类型号旁标有星号的),将使用表 8-2 所示的代码号。

image-20250506204823309

image-20250506205053176

8.2.2 ICMPv6 报文

表8-3给出了为ICMPv6定义的报文类型。注意ICMPv6负责的不仅是差错和信息类报文,也负责大量IPv6路由器和主机的配置。

image-20250506205541012

image-20250506205605961

在ICMPv6中,与ICMPv4一样,报文也被分组为信息类的和差错类的。然而,所有ICMPv6的差错报文的类型(Type)字段的高位比特为0。因此,ICMPv6类型从0到127的都是差错报文,类型从128到255的都是信息类报文。许多信息类报文都是请求/应答对。

将 ICMPv6 的标准报文和比较常见的 ICMPv4 报文进行比较,我们可以得到结论:设计ICMPv6时的一些努力是为了从原始的规范中去除未使用的报文,同时保留有用的报文。遵循这个方法,ICMPv6也使用代码(Code)字段,主要是为了完善某些差错报文的含义。在表8-4中,我们列出了这些标准的ICMPv6报文类型(即目的不可达、超时、参数问题),除0之外还定义了许多代码值。

image-20250506205914838

除了定义 ICMPv6 基本功能的类型和代码字段外,还支持了大量的标准选项,其中一些是必需的。这将ICMPv6与ICMPv4 中区别开来(ICMPv4 没有选项)。当前,标准的ICMPv6 选项只为ICMPv6 ND报文(类型为135 和 136)定义使用,使用了[RFC4861]中讨论的选项格式(Option Format)字段。

8.2.3 处理 ICMP报文

在ICMP中,对传入报文的处理随着系统的不同而不同。一般说来,传入的信息类请求将被操作系统自动处理,而差错类报文传递给用户进程或传输层协议,如TCP。进程可以选择对它们采取行动或忽略它们。这个一般规则的例外情况包括重定向报文和目的不可达——需要分片报文。前者将导致主机路由表中的自动更新,而后者用于路径MTU发现(PMTUD)机制,这一般是由传输层协议来实现的,如TCP。在ICMPv6中对报文的处理在一定程度上将更为严格。处理传入的ICMPv6报文时将应用以下规则:

  1. 未知的ICMPv6差错报文必须传递给上层产生差错报文的进程(如果可能的话)。
  2. 未知的ICMPv6信息类报文被丢弃。
  3. ICMPv6 差错报文将会尽可能多地包含导致差错的原始(“违规”)IPv6报文,当然最终的差错报文大小不能超过最小的 IPv6 MTU(1280 字节)。
  4. 在处理ICMPv6 差错报文时,需要提取原始(original)或者“违规”数据包(包含在ICMPv6差错报文体中)中的上层协议类型,用于选择适当的上层进程。如果这是不可能的,在任何 IPv6 层处理完后将丢弃差错报文。
  5. 存在处理差错的特殊规则
  6. IPv6节点必须限制它发送ICMPv6差错报文的速率。如令牌桶方法。

8.3——ICMP差错报文

ICMP 差错报文和信息类报文之间的区别非常重要,因为在生成 ICMPv4差错报文和ICMPv6差错报文时做了某些限制,但这不适用于查询。限制生成ICMP差错报文的原因是限制生成所谓的广播风暴,在这种情况下生成少数的报文就会造成不想要的流量喷流(例如,无限地为响应差错报文而生成差错报文)。这些规则可以概括如下:

以下情况下不会响应产生ICMPv4差错报文:

  • ICMPv4 差错报文(但是,响应ICMPv4查询报文可能会产生ICMPv4 差错报文)
  • 头部损坏的数据报(例如,校验和错误),
  • 目的地址是IPv4广播地址或IPv4组播地址(以前称为D类地址)的数据报。
  • 作为链路层广播的数据报。
  • 不是第一个分片的其他分片。
  • 源地址不是单个主机的数据报。这就是说,源地址不能为零地址、环回地址、广播地址或组播地址。

ICMPv6也类似。在下面各种情况不会响应产生 ICMPv6 差错报文:

  • ICMPv6 差错报文。
  • ICMPv6 重定向报文。
  • 目的地址是 IPv6 组播地址的数据包,以下情况除外:数据包太大(PTB)的报文;参数问题报文(代码 2)。
  • 作为链路层组播(以及前面提到的例外情况)的数据包。
  • 作为链路层广播(以及前面提到的例外情况)的数据包。
  • 源地址不是唯一识别的单个节点的数据包。这意味着,源地址不能是未指定的地址、IPv6 组播地址,或者任意为发送者所知的选播地址。

除了控制产生ICMP报文条件的规则,还有限制从单一发送者发出的ICMP总体流量水平的规则。在[RFC4443],一种推荐的限制ICMP报文速率的方法是使用令牌桶(token bucket)。

当发送一个ICMP 差错报文,它包含了一个完整的源自“违规”或者“原始”数据报的 IP 头部副本(即生成导致错误的数据报的IP头部,包括任何IP选项),再加上原始数据报的IP 有效载荷区中的任何其他数据,同时要确保生成的 IP/ICMP 的数据报的大小不会超过一个特定的值。对于 IPv4,这个值是 576 字节,对于 IPv6 就是 IPv6 的最小 MTU,至少是 1280 字节。包含原始 IP 数据报的有效载荷使接收的ICMP 模块能够根据 IP 头部中的协议(Protocol)或者下一个头部(Next Header)字段将该报文和特定的协议(例如,TCP或者UDP)及应用进程相关联(包含在IP数据报有效载荷区中前8个字节所包含的TCP或者UDP 头部中的 TCP 或者 UDP 端口号)。

8.3.1 扩展的ICMP和多部报文

[RFC4884]通过在ICMP报文的尾部追加扩展数据结构(extension data structure)的方法来指定一个扩展的方法。扩展结构包括一个扩展头部和可能包含可变数量数据的扩展对象,如下图所示。

image-20250506214055105

ICMPv4头部的第6个字节和ICMPv6头部的第5个字节被改为用于表示长度(Length)字段(这些字节此前已预留0 值)。在ICMPv4中,它表示以 32位字为单位的违规数据报的大小。在ICMPv6中,它是以 64 位为单位的。为了使 32 位和 64 位对齐,这些数据报中有一部分将分别用零来填充。扩展的 ICMPv4 和 ICMPv6 报文,包括一个 32 位的扩展头部和零个或多个相关联的对象。每个对象包含一个固定大小的头和一个可变长度的数据区。为了兼容性,ICMP主要有效载荷区至少有 128 个字节。

扩展结构可用于 ICMPv4 目的不可达、超时、参数问题报文,以及ICMPv6 目的不可达和超时报文。

8.3.2 目的不可达(ICMPv4类型3,ICMPv6类型1)和数据包太大(ICMPv6类型 2)

现在我们更为详细地查看一种比较常见的 ICMP 报文类型,即目的不可达。这种类型的报文用来表示数据报无法送达目的地,可能是因为传输过程中出了问题或接收者缺乏兴趣接收它。虽然ICMPv4 为此报文定义了 16个不同的代码,但其中只有 4 个是最常用的。这包括主机不可达(代码 1)、端口不可达(代码 3)、需要分片/指定不用分片(代码 4)、管理禁止通信(代码 13)。在 ICMPv6 中,目的不可达报文类型值是 1,并有 7 个不同的代码值。与 IPv4 相比,ICMPv6 中需要分片报文已经被一个完全不同的类型取代(类型 2),但是其用法和对应的 ICMP 目的不可达非常相似。在ICMPv6中,这就是所谓的数据包太大(PTB)报文。从这里开始,我们将使用简单的 ICMPv6 PTB 术语来表示ICMPv4(类型3,代码4)报文或者ICMPv6(类型2,代码0)报文。

为 ICMPv4 和 ICMPv6 指定的目的不可达报文格式如下图所示。目的不可达报文,对ICMPv4而言其类型字段为3,对ICMPv6而言其类型字段为1。代码字段表示了不可达的特定项目或者原因。

image-20250506215428505

8.3.2.1 ICMPv4主机不可达(代码1)和ICMPv6地址不可达(代码3)

这种形式的目的不可达报文是由路由器或者主机产生的,出现在当它被要求使用直接交付方法发送一个IP数据报到一个主机,但由于某些原因无法到达目的地时。例如当最后一跳路由器试图发送一个ARP请求到已经不在或者关闭的主机时,这种情况就可能会出现。对于ICMPv6,它使用一个有点不同的机制来检测无响应的主机,这个报文可能是因为 ND 过程失败而产生的。

8.3.2.2 ICMPv6目的无路由(代码0)

此报文对ICMPv4中的主机不可达报文进行了细分,将直接交付失败导致的和没有路由导致的区分开来。此报文出现在当到达的数据报不必采用直接交付的方式来转发,但却没有路由条目来指定下一跳该用哪个路由器时的情况下。正如我们已经看到的,如果IP路由器想要成功转发的话,它们必须为收到的任何数据包的目的地址包含一个有效的下一跳转发项。

8.3.2.3 ICMPv4管理禁止通信(代码3)和ICMPv6目的管理禁止通信(代码1)

在ICMPv4和ICMPv6中,这些目的不可达报文能够表明一个管理禁令正阻止到目的地的成功通信。这通常是由一个防火墙故意丢弃流量导致的,而这些流量未能遵守由路由器发送的 ICMP 差错报文所强加的部分操作策略。在许多情况下,不会广而告之存在一个特殊的丢弃流量的策略,所以一般可以禁止生成这些报文,要么默默丢弃传入的数据包,要么产生一些其他的 ICMP 差错报文来代替。

8.3.2.4 ICMPv4端口不可达(代码3)和ICMPv6端口不可达(代码4)

当传人的数据报的目的应用程序还没准备好接收它时,就会生成一个端口不可达报文。这种情况最常出现在和 UDP 一起使用,当一个报文被发往的端口号并未被任何服务器进程使用时。如果UDP接收到一个数据报且对应的目的端口号并未被任何进程使用,UDP便会回应一个ICMP端口不可达报文。

8.3.2.5 ICMPv4 PTB(代码 4)

如果一个IPv4 路由器收到一个打算转发的数据报,如果数据报大于选定的传出网络接口的 MTU,则数据报需要分片。如果到达的数据报在IP头部中设置了不分片位字段,那么它会被丢弃而不是转发,此时将产生ICMPv4目的不可达(PTB)报文。由于发送此报文的路由器知道下一跳的MTU,为此能够将MTU值包含在它生成的差错报文中。

此报文本来是用于诊断网络的,但已被用于路径MTU 发现。当与一个特定主机通信时,如果想要避免对数据包进行分片,PMTUD 被用来确定合适的包大小。它通常与TCP 一起使用。

8.3.2.6 ICMPv6 PTB(类型2,代码0)

在ICMPv6中,一个特殊的报文和类型代码组合可用于表示一个数据包对于下一跳的MTU而言实在太大(见下图)。

image-20250506222932549

这个报文不是一个目的不可达报文。回想一下,在IPv6中只有数据报的发送者才能执行数据包分片,且总是采用 MTU 发现机制。因此,这个报文主要是被 IPv6 的 PMTUD 机制使用,但是偶尔也用在当一个到达的数据包对下一跳来说太大了导致不能传输的情况。因为路由在PMTUD操作及数据包被投入网络之后可能会改变,因此到达路由器的数据包大于传出的MTU的情况总是有可能发生的。与现代ICMPv4实现中的目的不可达代码4(PTB)报文一样,基于产生ICMP报文的路由器的出口链路的 MTU来确定的数据包MTU 大小被包含在指示(indication)中。

8.3.2.7 ICMPv6 超出源地址范围(代码 2)

IPv6 使用不同范围的地址。因此,有可能会构建一个不同范围的源和目的地址的数据包。此外,在相同范围内其目的地址有可能是无法到达的。例如,使用本地链路范围的源地址的数据包,其目的地址可能是一个需要遍历多跳路由的全局范围的地址。由于源地址的范围不足,数据包将被通过的路由器丢弃,同时生成一个这种形式的ICMPv6差错报文以表示这个问题。

8.3.2.8 ICMPv6源地址失败进/出策略(代码5)

代码5是代码1更为细化的版本,使用在当一个特定的入口或出口过滤政策是导致数据报无法成功投递的原因时。这可能会使用在:例如,当一个主机试图采用一个意想不到的网络前缀的源IPv6地址来发送流量时[RFC3704]。

8.3.2.9 ICMPv6拒绝路由到目的地(代码6)

一个拒绝(reject)或封阻路由(blocking route)是一个特殊的路由或转发条目,指示匹配的数据包应该被丢弃,并生成一个ICMPv6目的不可达拒绝路由报文。(一个类似的称为黑洞路由(blackhole route)的条目也能够丢弃匹配的数据包,但是并不会生成目的不可达报文。)这些路由可能会安装在路由器的转发表中,以防止数据包被发送到不希望的目的地中。不希望的目的地可能包括火星(martian)路由(公共互联网上并未使用的前缀)
和虚假(bogons)路由(尚未分配的有效前缀)。

8.3.3 重定向(ICMPv4类型5,ICMPv6类型 137)

假如一个路由器收到一个来自主机的数据报,并确定自身并不是主机将数据报投递到目的地的对应下一跳,则该路由器发送一个重定向报文到主机并将该报文发送到正确的路由器(或者主机)。也就是说,如果它能够确定给定的数据报存在一个比自己更好的下一跳路由,它就向主机发送重定向报文使其更新转发表,这样以后目的地一样的流量就会被定向到新的节点中。这项功能通过向IP转发功能指示向哪里发送数据包提供了一种路由协议的原始形式。

ICMP 重定向报文包含了主机针对 ICMP 差错报文中指定的目的地址应该采用的下一跳路由器(或者目的主机,如果采用直接交付的方式可达的话)的 IP 地址。之前的重定向功能支持区别重定向到一台主机和重定向到一个网络(network),但是自从无类地址被采用之后(CIDR),网络重定向形式便消失了。这样,当一个主机接收到一个主机重定向,它只针对单个 IP 目的地址是有效的。一个总是选择错误路由器的主机能够通过为每个访问的本地子网之外的目的地址设置一个转发表条目来结束这种情况,其中每个条目是通过接收它配置的默认路由器的重定向报文来添加的。ICMPv4 的重定向报文格式如下图所示。

image-20250506224935397

ICMPv4 重定向报文在其有效负载部分中包含了数据报下一跳正确路由器的IPv4 地址。一个主机通过检查到来的重定向报文的源 IPv4 地址来验证它是否来自当前正使用的默认路由器。

在ICMPv6中,重定向报文(类型137)包含目标地址和目的地址(参见下图),它是和ND过程一起被定义的。目标地址(Target Address)字段包含用于下一跳的正确节点的本地链路IPv6地址。目的地址(Destination Address)是数据报中触发这个重定向的目的IPv6地址。当目的地址和接收到重定向报文的主机是在同一个链路上时,目标地址和目的地址字段是一样的。这种方法能够告诉一台主机另一台主机是在同一个链路上的,即使它
们使用的地址前缀不同。

image-20250506225552957

与ICMPv6中的其他ND报文一样,这个报文能够包含选项。这些选项类型包括了目标链路层地址选项和重定向头部选项。当重定向报文在一个非广播多路访问(non-broadcast multiple access,NBMA)网络使用时,必须包含目标链路层地址选项,这是因为在这种情况下接收重定向报文的主机没有其他更为有效的方法来确定新的下一跳的链路层地址。重定向头部选项包含了导致产生重定向报文的 IPv6 数据包中的一部分。

8.3.4 ICMP 超时(ICMPv4 类型 11,ICMPv6 类型 3)

每个 IPv4 数据报在头部中都有一个生存周期(Time-to-Live,TTL)字段,而每个 IPv6数据报在其头部中都有一个跳数限制(Hop Limit)字段。按照最初的设想,8位TTL字段保存了一个数据报被强制丢弃之前允许活跃在网络中的秒数(如果存在转发环路,这将是一件好事)。因为另外一个规则表明,任何一个路由器对TTL字段至少减1,考虑到数据报的实际转发时间远小于1 秒这个事实,在实际中 TTL字段被用于限定一个IPv4数据报在被路由器丢弃之前所允许的跳数限制。这种用法最终在 IPv6 中被正式采用。当由于TTL或跳数限制字段值太小(即到达值0或1,且必须转发)致使路由器丢弃报文时,会产生ICMP超时(代码0)报文。此报文对于保证traceroute工具的正常运作是很重要的(在Windows 上称为 tracert)。下图给出了 ICMPv4 和 ICMPv6 的格式。

image-20250506230006016

另一个不常见的该报文的变体出现在当一个分片的 IP 数据报只有部分到达目的地时(即在一段时间后并不是所有的分片都到达了)。在这种情况下,一个ICMP超时报文(代码1)的变体被用于告知发送者它的整个数据报被丢弃了。

8.3.5 参数问题(ICMPv4类型 12,ICMPv6类型 4)

当一个主机或者路由器接收到一个IP数据报,其IP头部存在不可修复的问题时便会产生一个ICMP 参数问题报文。当一个数据报不能够被处理,且没有其他的 ICMP 报文来描述这个问题时,这个报文充当了一个“包罗万象”的错误状态指示器。在ICMPv4 和ICMPv6中,当头部中某个字段超过可接受范围导致了一个错误时,一个特殊的ICMP差错报文指针(Pointer)字段指示了错误字段相对于出错 IP头部的偏移值。以ICMPv4 为例,指针字段值为1表示一个错误的 IPv4 DS字段或者ECN字段(这些字段以前称为IPv4服务类型或者 ToS 字节,但已经被重新定义和命名过了)。ICMPv4的参数问题报文格式如下图所示。

代码0是ICMP参数问题报文最为常见的变体,可用于IPv4头部中出现的任何问题,尽管当头部或者数据报的总长度字段出现问题时可能会产生代码为2的报文。代码 1 以前被用于指示数据包中缺少例如安全标志之类的选项,但目前已经不用了。代码2是最近才定义的代码,指示存在一个损坏了的IHL 或者总长度字段值。

image-20250506231057857

这个差错报文的ICMPv6版本如下图所示。在ICMPv6中,相对于ICMPv4版本,差错的对待方式在某种程度上已经被重新定义为三种情况:

  • 存在错误的头部字段(代码 0)
  • 存在无法识别的下一个头部(Next Header)类型(代码1)
  • 存在无法识别的IPv6选项(代码2)

与ICMPv4中对应的差错报文一样,ICMPv6 参数问题中的指针字段给出了相对于问题 IPv6头部的字节偏移。例如,指针字段值为40指示第一个IPv6的扩展头部中存在问题。

image-20250506231237536

当IPv6头部中的某个字段包含了一个非法的值时,会导致错误头部(代码0)差错发生。如果 IPv6 下一个头部(头部链)字段包含了一个 IPv6 实现并不支持的头部类型值的话,会导致代码为 1 的差错发生。最终,当收到一个无法识别的 IPv6头部选项时,会导致代码为2的差错发生。

8.4——ICMP 查询/信息类报文

尽管ICMP定义了一定数量的查询报文,例如地址掩码请求/应答(类型17/18)、时间戳请求/应答(类型13/14),信息请求/应答(类型15/16),但是这些功能已经被其他特殊目的的协议替代(包括DHCP),唯一保存下来的广泛使用的ICMP查询/信息类报文是回显请求/应答报文,通常称为ping,以及路由器发现报文。虽然路由器发现机制在IPv4中并未广泛使用,但是与之类似的功能(邻居发现中的一部升)在1Pv6中却是基本的。此外,ICMPv6已经被扩展用于支持移动IPv6和具备组播能力的路由器发现。

8.4.1 回显请求/应答(ping)(ICMPv4类型0/8,ICMPv6类型129/128)

ICMP的回显请求报文大小几乎是任意的(受限于最终封装的IP数据报的大小)。收到ICMP回显请求报文后,ICMP 的实现要求将任何接收到的数据返回给发送者,即使涉及多个IP 分片。ICMP的回显请求/应答报文格式如下图所示。

image-20250508200252840

ICMPv4 和ICMPv6回显请求和回显应答报文格式。请求中的任何可选数据都必须包含在应答中。NAT 使用其中的标识符字段来匹配请求和应答。

与其他ICMP查询/信息类报文一样,服务器必须在回复中包含标识符(Identifier)和序列号(Sequence Number)字段。

这些报文是通过一个ping程序发送的,该程序通常被用于确定 Internet 上的一台主机是否可达。如果你一度能够"ping"到一台主机,那么几乎确定能够通过其他的方法(远程登录,其他服务等)访问到它。然而,当和防火墙一起使用时,这就不能完全确定了。

在 ping 的实现中将 ICMP报文的标识符字段设置为某个数,发送主机能够利用它来分离返回的应答。在基于UNIX的系统中,例如,发送进程的进程ID通常被放置在标识符字段。如果有多个ping在同一台主机同时运行的话,这样将允许ping应用程序识别返回的应答,因为ICMP协议不像传输层协议那样有端口号。当涉及防火墙行为时,这个字段通常被称为查询标识符(Query Identifier)字段。

当一个新的ping实例运行时,序列号字段从0开始,并且每发送一个回显请求报文便增加1。ping打印出每个返回的数据包的序列号,方便用户查看数据包是否丢失、重排或者重复了。回忆一下,IP(因此ICMP也是)是一个尽力(best-effort)数据报传递服务,所以三者中的任何一种情况都有可能发生。但是,ICMP 拥有 IP 没有提供的数据校验和。

ping 程序也在传出的回显请求中的可选数据区域中包含了一份本地时间拷贝。这个时间和数据区域中剩余的内容均包含在返回的回显应答报文中。当应答收到时,ping程序注意到了当前时间,用它减去应答中的时间,便得到了一个到达被 ping 的主机的 RTT 估计值。由于只用到了原始发送者的当前时间,因此这个特征不会涉及发送者和接收者之间的时钟同步。工具traceroute中RTT的测量也采用了类似的方法。

先前版本的 ping 程序每秒发送一个回显请求报文,并打印出每个返回的应答。但是,新的实现增加了输出格式和行为的变化。在Windows中,默认是发送4个回显请求,每秒一个,输出一些统计信息,然后退出。-t选项允许Windows 中的 ping 程序不断地发送回显请求直到被用户停止为止。在Linux中,其行为就按传统那样——默认是不停运行直到被用户中断为止。

注意这个过程(向 IPv4 的广播地址发送回显请求)能用于快速广播本主机系统的 ARP表。这些系统响应回显请求报文,构建一个目的是请求发送者的回显应答报文。当响应的目标系统位于同一个子网内时,将会触发 ARP请求查找请求发送者的链路层地址。这么做,ARP 将会在每个响应者和请求发送者之间交换。这也导致回显请求报文的发送者学习所有响应者的链路层地址。向发送到广播地址的请求回复 ICMP 应答报文是可选的。默认情况下,Linux系统会响应,而 Windows XP系统则不会。

8.4.2 路由器发现:路由器请求和通告(ICMPv4 类型 9,10)

我们看到了 DHCP 是如何被一个主机用于获取 IP 地址和学习到附近存在的路由器的。另外一种学习路由器的方式是路由器发现(Router Discovery,RD)。尽管可以指定为IPv4和IPv6主机配置,但是由于DHCP的普及,它在IPv4中并没有被广泛使用。但是,目前它被指定与移动IP一起使用。这个IPv6版本构成了IPv6 SLAAC功能的一部分,在逻辑上是IPv6 ND的一部分。

IPv4的路由器发现是通过采用一对ICMPv4信息类报文实现的[RFC1256]:路由器请求(RS,类型10)和路由器通告(RA,类型9)。通告由路由器通过两种方法发送。

  • 首先,它们定期对本地网络(使用TTL=1)的所有主机组播地址(224.0.0.1)进行组播,并提供给有需要的主机,它们通常使用RS报文进行请求。
  • 使用组播将RS报文发送到所有路由器组播地址上(224.0.0.2)。

路由器发现的主要目的是让一台主机学习到它所在的本地子网中的所有路由器,因此它能够从中选择一台作为默认路由。它也被用于发现那些愿意充当移动IP代理的路由器。下图给出了 ICMPv4 RA报文格式,其中包含了一个IPv4 地址列表可用做主机的默认路由器。

image-20250508203003435

ICMPv4 路由器通告报文包含了一个IPv4 地址列表可用作下一跳的默认路由。优先水平允许网络操作人员为这个列表安排不同的优先级(越高优先级越大)。移动IPv4[RFC5944]通过扩展增强了RA报文,目的是为了通告MIPv4移动代理以及被通告的路由器地址的前缀长度。

  • 地址数:给出了报文中路由地址块的个数。每个块包含了一个 IPv4 地址及相应的优先水平。
  • 地址条目大小:给出了每个块的 32 位字数。
  • 生命周期:给出了地址列表被认为是有效的秒数。
  • 优先水平:优先水平是一个32位的有符号二进制补码整数,其值越大代表优先级越高。默认的优先水平是 0,特殊值 0x80000000 表示这个地址不应该用作有效的默认路由。

RA 报文也被移动IP中的节点用于定位一个移动(即本地和/或外地)代理。上图描述了一个路由器通告报文,其中包含了一个移动代理通告扩展。这个扩展遵循传统的 RA 信息并包含一个值为 16 的类型(Type)字段,以及一个给出了扩展区域(不包括类型和长度字段)内字节个数的长度(Length)字段。它的值等于(6+4K),假设包含了K个地址。序列号字段给出了自从初始化之后代理产生的这种扩展的个数。注册字段给出了发送代理愿意接受MIPv4注册的最大秒数(0xFFFF的表示无穷大)。存在具有以下含义的标志(Flag)位字段:

  • R(为 MIP 服务所需的注册)
  • B(代理太忙无法接受新注册)
  • H(代理愿意充当本地代理)
  • F(代理愿意充当外地代理)
  • M(支持最小封装格式[RFC2004])
  • G(代理支持封装数据报的 GRE 隧道)
  • r(保留零)
  • T(支持反向隧道[RFC3024])
  • U(支持 UDP 的隧道[RFC3519])
  • X(支持撤销注册[RFC3543])
  • I(外地代理支持区域注册[RFC4857])

除了移动代理通告扩展,还有一个扩展已经被设计用于帮助移动节点。前缀长度扩展可能位于移动代理通告扩展之后,表示在基本路由器通告中每个对应的路由器地址的前缀长度。其格式如下图所示。

image-20250508204548655

上图中,长度字段被设置为等于 N,即来源于基本 RA 报文中的地址数字段。每个8位的前缀长度字段给出了在本地子网中使用的路由器地址字段对应的位数。这个扩展能被移动节点用来确定它是否已经从一个网络移动到另一个了。采用[RFC5944]中的算法 2,一个移动节点也能缓存一个特定链路上可用的前缀集合。如果网络前缀集合已经改变,就能检测到是移动了。

8.4.3 本地代理地址发现请求/应答(ICMPv6类型144/145)

[RFC6275]定义了4种支持MIPv6的ICMPv6报文。其中2个ICMPv6报文用于动态本地代理地址发现,另外 2 个用于重新编号和移动配置。当一个MIPv6节点访问一个新的网络时,它使用本地代理地址发现请求报文动态地发现一个本地代理(参见下图)。

image-20250508205128424

为了本地前缀,报文被发送到MIPv6 本地代理的任播地址。IPv6 的源地址通常是移动节点从当前正在访问的网络上获取的地址。愿意为给定节点及它的本地前缀充当本地代理的节点会发送一个本地代理地址发现应答报文(参见下图)。

image-20250508205438533

直接提供给移动节点单播地址的本地代理地址,极有可能是个移交地址。这些报文用于处理当一个移动节点在网络中转换但其 HA 已经变化了的情况。在重新建立一个合适的 HA之后,移动节点可能会初始化 MIPv6 绑定更新。

8.4.4 移动前缀请求/通告(ICMPv6类型146/147)

移动前缀请求报文(参见下图)是当一个节点的本地地址就要变为无效时,用于从一个 HA 处请求一个路由前缀更新。移动节点包含一个本地地址选项(IPv6 目的地址选项),并使用 IPsec 保护请求。

image-20250508205856747

请求报文在标识符字段中包含了一个随机值,用来匹配请求与应答。它和路由器请求报文类似,但是发送给一个移动节点的HA,而不是本地子网。在这个报文的通告形式中(参见下图),封装的IPv6 数据报必须包含一个类型为 2 的路由头部。标识符字段的值和请求报文中的标识符值一样。M(Manged Address,托管地址)字段表示主机应该使用有状态的地址配置,并避免自动配置。O(Other,其他)字段表示一个有状态的配置方法提供的是信息而不是地址。通告中包含了 1 个或者多个前缀信息选项。

image-20250508210039478

移动前缀通告报文是设计用来通知一个移动中的节点其本地前缀已经改变了。这个报文通常是使用IPsec保护的,主要是为了帮助移动节点免受假冒前缀通告的欺骗。前缀信息选项使用了[RFC4861]描述的格式,包含了移动节点应该用来配置其本地地址的前缀。

8.4.5 移动IPv6 快速切换报文(ICMPv6类型 154)

MIPv6 的一个变体为 MIPv6 定义了快速切换[RFC5568](称为 FMIPv6)。当一个移动节点从一个网络的接入点(AP)移动到另一个时,它指定的方法可以改善 IP 层的切换延迟。这是通过在切换发生之前预测路由器和地址信息来完成的。这个协议涉及对所谓的代理路由器的发现,它的行为类似于普通路由器,但是移动节点在切换到一个新的网络时需要用到。有对应的 ICMPv6 代理路由器请求和通告报文(分别称为 RtSolPr和 PrRtAdv)。基本的 RtSolPr 和 PrRtAdv 格式如下图所示。

image-20250508210626935

一个移动节点可能有关于它将来使用的 AP 的地址或者标识符的信息(例如,通过“扫描”802.11网络),RtSolPr报文使用代码0和子类型2,同时必须包含至少一个选项,即新接入点链路层地址选项。这是用于指出移动节点请求的信息是关于哪个AP的。RtSolPr报文可能也包含一个链路层地址选项来识别源,如果知道的话。这些选项使用了IPv6 ND选项格式。

8.4.6 组播侦听查询/报告/完成(ICMPv6类型130/131/132)

组播侦听发现(MLD)[RFC2710] [RFC3590]为采用 IPv6 的链路提供了组播地址管理。它和 IPv4 采用的 IGMP协议类似,此处我们描述组成MLD(版本 1)报文的格式,包括组播侦听查询、报告和完成报文。基本格式如下图所示。这些报文被发送时其 IPv6 跳数限制(Hop Limit)字段值为 1,并带有路由器告警逐跳 IPv6 选项。

MLD的主要目的是让组播路由器了解与它们相连的每个链路上的主机使用的组播地址。MLDv2(版本 2 组播侦听发现)扩展了此功能,允许主机指定它们希望(或不希望)接收流量的特定主机。组播路由器发送两种形式的 MLD 查询报文:一般的查询和特定于组播地址的查询。一般来说,路由器发送查询报文,主机采用报告响应,或者是响应查询,或者是在一台主机的组播地址成员发生变化时主动提供。

image-20250508211048282

最大响应时间(Maximum Response Time)字段只有在查询时是非零的,它是响应查询主机发送报告可能推迟的最大毫秒数。由于组播路由器只需要知道,至少有一台主机对发往特定组播地址的流量感兴趣(因为链路层组播支持允许路由器不必为每个目的复制报文),节点可以随机故意地拖延它们的报告,甚至完全抑制它们(如果发现另一个邻居已经做出了响应)。这一字段提供这种延迟时长的一个上限。对于一般的查询和路由器在报告中感兴趣的地址,组播地址(Multicast Address)字段为0,对于MLD报告报文(类型131)和MLD完成报文(类型132),它分别包含和报告相关的地址或不再感兴趣的地址。

8.4.7 版本2组播侦听发现(ICMPv6类型143)

[RFC3810]定义了在[RFC2710]中描述的MLD功能扩展。特别是,它定义了一个组播侦听的方式来指定只监听一个特定集合的发送者(或者,排除一个特定的集合)。因此,它对支持源特定组播(SSM)非常有用。它基本上是对与IPv4一起使用的IGMPv3协议在IPv6下使用的一个转换,它使用ICMPv6 来管理多数组播地址。

MLDv2 扩展了MLD查询报文,增加了与特定来源相关的其他信息(见下图)。报文中开始的24个字节和MLD格式是一样的。

image-20250508212112862

  • 最大响应代码:指定发送MLD响应报文之前允许的最大时间。这个字段的值是特殊的,因此其解释与 MLDv1 也略有不同:如果它小于 32768,则与MLDv1 中一样,最大的响应延迟就设置为该值(以毫秒为单位)。如果该值等于或大于32769,字段使用下图所示的格式编码一个浮点数。

    image-20250508212245786

    在这种情况下,最大响应时间设置为等于((mant | 0x1000)<<(exp + 3))毫秒。采用这个看似复杂的编码策略的原因是为了让大、小响应延迟值都能编码在这个字段中,并保留一些与MLDv1的兼容性。特别是,它可以仔细调整离开延迟,并影响报告的突发性。

  • S字段:一般查询中组播地址字段设置为0。对于一个特定组播地址查询或特定的组播地址和源查询,它被设置为查询的组播地址。S字段指示是否应抑制路由器端处理。设置时,它表示任何接收的组播路由器,当监听到一个查询时它必须抑制正常的计时器更新计算。这并不表示,如果路由器本身就是一个组播监听者的话,查询器选举或正常的“主机端”处理应该被抑制。

  • QRV字段:如果设置了QRV(查询器鲁棒性变量)字段,它将包含一个不超过 7的值。如果发送者的内部QRV 值超过7,那么这个字段应设为0。鲁棒性变量能够根据一个子网上的丢包率来微调 MLD 的更新率。QQIC(Querier’s Query Interval Code,查询器查询间隔代码)字段编码查询时间间隔,如下图所示。

    image-20250508212735225

    查询时间间隔以秒为单位,它从 QQIC 字段按如下方式计算得到:如果QQIC<128,那么QQI=QQIC;否则,QQI=((mant | 0x10) << (exp+3))。

  • 源个数(N):表示查询中源地址个数。对于一般的查询或者特定的组播地址查询,此字段为0。对于特定的组播地址和源查询报文,它不为0。

  • 组播地址记录:MLDv2 报告中使用的组播地址记录(参见下两个图)包含对 IPv6 节点源地址过滤器所做的修改。

    image-20250508213253044

    记录类型主要可以分为三类:

    • 当前状态记录:包括 MODE_IS_INCLUDE(IS_IN)和MODE_IS_EXCLUDE(IS-EX)类型,指明的地址过滤模式对于指定的源而言(其中必须至少存在一个)分别是“包括”或“排除”。
    • 过滤模式变化记录:CHANGE_TO_INCLUDE
      (TO-IN)或CHANGE_TO_EXCLUDE(TO_EX)和当前状态记录是类似的,但当有变化或者不需要包含一个非空的源列表时将被发送。
    • 源列表改变记录:当过滤器的状态(包含/排除)不变而只有源列表被改变时,ALLOW_NEW_SOURCES(ALLOW)和BLOCK_OLD SOURCES(BLOCK)将被使用。

    为了简化了 MLDv2[RFC5790]的操作,对 MLDv2(和IGMPv3)做了修改,即删除了 EXCLUDE 模式。这种“轻量级”的方法,称为 LW-MLDv2(和LW-IGMPv3),使用先前定义的相同报文格式,但删除了很少使用的要求组播路由器保存附加状态的 EXCLUDE 指令。

    image-20250508213802253

8.4.8 组播路由器发现(IGMP类型48/49/50,ICMPv6类型 151/152/153)

[RFC4286]描述组播路由器发现(MRD),该方法定义的特殊报文可以和ICMPv6和IGMP一起使用,用来发现能够转发组播数据包和它们的一些配置参数的路由器。最初的想法主要是和"IGMP/MLD侦听”一起使用。IGMP/MLD侦听是一种机制,主机和路由器(例如,第2层交换机)以外的系统也可以了解网络层组播路由器和感兴趣主机的位置。MRD报文发送时总是将IPv4的TTL或IPv6的跳数限制字段设为1,并设有路由器警告选项,可能是如下类型之一:通告(151),请求(152),或终止(153)。在配置的时间间隔定期地发送通告,表明路由器愿意转发组播流量。终止报文表明要终止这种意愿。请求报文可用于请求路由器发送通告报文。通告报文格式如下图所示。

image-20250508214103208

通告报文从路由器的 IP 地址(IPv6 链路本地地址)发送到所有侦听者的 IP 地址:
224.0.0.106(IPv4)和链路本地组播地址ff02::6a(IPv6)。接收者能够了解路由器的通告间隔和 MLD 参数(QQI 和 QRV)。请注意,QQI 值是查询的间隔(以秒计),不是之前在 MLDv2 查询中描述的 QQIC(编码版本的 QQI 值)。

请求和终止报文格式几乎相同(见下图),只有类型字段的值有所不同。

image-20250508214225632

上图显示请求和终止报文的格式几乎是相同的。请求报文请求一个组播路由器发送一个通告报文。这样的报文被发送到所有路由器地址224.0.0.2(IPv4)和本地链路组播地址ff02::2(IPv6)。终止报文被发送到所有的侦听者IP地址,表示发送路由器不再愿意转发组播流量了。

8.5——IPv6 中的邻居发现

IPv6中的邻居发现协议(有时简称为NDP或者ND)[RFC4861]将路由器发现和由ARP提供的带有地址映射功能的ICMPv4重定向机制结合在一起。它也被指定用于支持移动IPv6。与 ARP 和 IPv4 普遍使用广播地址(除了路由器发现)不同,ICMPv6广泛使用组播地址,在网络层和链路层中都使用。

ND 被设计允许在同一个链路或者网段的节点(路由器和主机)找到彼此,确定它们之间是否有双向连通性,确定一个邻居是否变得不合作或者不可用。它也支持无状态的地址自动配置。所有的ND功能都是由网络层或者之上的ICMPv6提供的,致使它最大限度地独立于底层所采用的链路层技术。但是,ND并不倾向于采用链路层组播功能,也正是这个原因在非广播和非组播链路层(称为非广播多路访问或者NBMA链路)上的操作可能会有一些差别。
ND中两个主要部分是:邻居请求/通告(NS/NA),在网络和链路层地址之间提供类似于ARP的映射功能;还有路由器请求和通告(RS/RA),提供的功能包括路由器发现、移动IP 代理发现、重定向,以及对一些自动配置的支持。ND 的一个安全变体SEND[RFC3971]通过引入额外的 ND 选项增加了认证和特殊形式的寻址。

ND 报文就是ICMPv6报文,只是发送时 IPv6的跳数限制字段值被设置为255。接收者通过验证进来的ND报文有这个值,以防止被非本链路上的发送者尝试发送假冒本地ICMPv6 报文(这样的报文到达时其值会小于255)欺骗。ND 报文可以携带丰富的选项。

8.5.1 ICMPv6路由器请求和通告(ICMPv6类型133,134)

路由器通告(RA)报文表明附近路由器的存在及其功能。它们定期被路由器发送,或者是响应一个路由器请求(RS)报文。RS报文(参见下图)用于请求链路上的路由器发送RA报文。RS报文被发送到所有路由器组播地址ff02::2。如果报文的发送者使用IPv6地址,而不是未指定的地址(在自动配置过程中使用),则应该包括一个源链路层地址选项。对于这样的报文,这是唯一有效的选项。

image-20250509132921347

路由器通告(RA)报文(参见下图)是由路由器发送到所有节点的组播地址(FF02::1)的,或者是发送到请求主机的单播地址——如果该通告是为了响应一个请求。RA报文通知本地主机和其他路由器关于本地链路的有关配置细节。

image-20250509133108329

  • 当前跳数限制:指定主机发送IPv6数据报的默认跳数限制。值为0表示发送路由器并不关心。

  • 下一个字节包含了位字段数,正如在[RFC5175]总结和扩展的那样。

    • M(托管):表明本地 IPv6地址分配是由有状态的配置来处理的,主机应避免使用无状态的自动配置。

    • O(其他):表示其他有状态的信息(即 IPv6 地址以外的)使用一个有状态的配置机制。

    • H(本地代理):表示发送路由器愿意充当一个移动IPv6节点的本地代理。

    • Pref(优先级):给出了将报文发送者作为一个默认路由器来使用的优先级层次:

      • 01:高;
      • 00:中(默认);
      • 11,低;
      • 10,保留(未使用)。

      当和实验性质的 ND 代理工具[RFC4389]配合使用时,将使用 P(代理)标志。它为 IPv6 提供了一个类似代理 ARP 的功能。

  • 路由器生命周期:表示发送路由器可以作为默认下一跳的时间,以秒计。如果它被设置为0,发送路由器不应该用作默认路由器。此字段只适用于使用发送路由器作为默认路由器,它不会影响同一个报文中的其他选项。

  • 可达时间:给出一个节点到达另一个节点所需的毫秒数,假设已经发生了双向通信。这被邻居不可达检测机制使用。

  • 重传计时器:规定主机延迟发送连续ND报文的时间,以毫秒为单位。

  • 选项:此报文通常包含源链路层选项(如果适用的话),如果链路中使用了可变长度的 MTU则应包含MTU选项。该路由器还应该包括前缀信息选项,表示本地链路上使用了哪些IPv6前缀。

8.5.2 ICMPv6邻居请求和通告(ICMPv6类型 135,136)

ICMPv6中的邻居请求(NS)报文(参见下图),有效地取代了IPv4中的ARP请求报文。其主要目的是将IPv6地址转换为链路层地址。但是,它也被用于检测附近的节点是否可达,它们是否可以双向到达(即节点间是否可以互相通信)。当用于确定地址映射时,它被发送到目标地址字段中包含的IPv6地址所对应的请求节点的组播地址
(前缀 f02:: 1:f/104,并结合请求 IPv6 地址中的低 24位)。当这个报文被用来确定到邻居的连接性时,它被发送到该邻居的IPv6单播地址,而不是请求节点的地址。

image-20250509134536626

NS报文包含发送者想设法学习的链路层地址对应的IPv6地址。该报文可能包含源链路层地址选项。当请求是被发送到一个组播地址时,该选项必须包含在使用链路层寻址的网络中,对于单播请求而言,该选项应该被包含。如果报文的发送者使用未指定的地址作为源地址(例如,在重复地址检测期间),则不应该包括该选项。

ICMPv6 邻居通告(NA)报文(参见下图)和 IPv4 中的 ARP 响应报文的目的一样,还能够有助于邻居不可达检测。它要么作为NS报文的响应被发送,要么当一个节点的IPv6地址变化时被异步发送。它要么被发送到请求节点的单播地址,要么当请求节点使用未指定的地址作为源地址时,它被发送到所有节点的组播地址。

image-20250509134809018

  • R(路由器):表示该报文的发送者是一个路由器。这可能会改变,例如当一台路由器不再是路由器,而成为一台主机时。
  • S(请求):表示该报文是在响应先前收到的请求。这个字段用来验证已经取得的邻居之间的双向连通性。
  • O(覆盖):表示在报文中的信息应覆盖报文发送者之前缓存的任何信息。它不应该在请求通告、任播地址或请求代理通告中设置,而应该在其他通告(请求或主动)中设置。
  • 目标地址:对于请求通告,目标地址字段就是正在被查找的IPv6地址。对于主动通告,它是已经改变的链路层地址对应的IPv6地址。当通告是通过一个组播地址被请求时,此报文必须包含支持链路层寻址的网络的目标链路层地址。

8.5.3 ICMPv6反向邻居发现请求/通告(ICMPv6 类型 141/142)

IPv6中的反向邻居发现(Inverse Neighbor Discovery,IND)功能起源于需要在帧中继网络中确定给定的链路层地址对应的 IPv6 地址。它类似于反向的 ARP 协议,主要用于支持IPv4 网络中的无盘计算机。其主要功能是确定一个已知的链路层地址对应的网络层地址。下图显示了 IND 请求和通告报文的基本格式。

IND 请求报文被发送到IPv6 层的所有节点的组播地址,但是却封装在一个单播链路层地址(正在被查找的那个)中。它必须同时包含源链路层地址选项和目的链路层地址选项。它可能也包含一个源/目标地址列表选项和/或一个 MTU 选项。

image-20250509135432494

8.5.4 邻居不可达检测

ND的一个重要特征是检测在同一个链路上的两个系统什么时候丢失了或者变得非对称了(即在两个方向上均不可用)。这是通过邻居不可达检测(Neighbor Unreachability Detection,NUD)算法完成的。它被用于管理每个节点上的邻居缓存(neighbor cache)。邻居缓存和ARP缓存类似,它是一个(概念上)数据结构,用于保存IPv6到链路层地址的映射信息(这些信息在执行到链路邻居的IPv6数据报直接交付时需要),以及针对映射状态的信息。下图显示了它如何在邻居缓存中维护条目。

image-20250509135702528

邻居不可达检测帮助维护由多个邻居条目组成的邻居缓存。在任何时间,每个条目是5种状态中的一种。对连接可达性的确认是通过接收邻居通告报文或者其他更高层的协议信息来完成的。主动证据包括主动的邻居和路由器通告报文

每个映射可能是如下5个状态中的一种:INCOMPLETE,REACHABLE,STALE,DELAY,PROBE。上图所示的转换图显示的初始状态是 INCOMPLETE 或 STALE。当一个 IPv6 节点有一个单播数据报需要发送到目的地时,它会检查其目标缓存,看一看对应于目的地的条目是否存在。如果存在且目的地是在链路上的,再查看邻居缓存,确定邻居状态是否是 REACHABLE。如果是,使用直接交付方式发送数据报。如果没有邻居缓存条目,但目标似乎是在链路上,NUD 会进入 INCOMPLETE 状态,并发送一个 NS 报文。成功收到一个请求 NA报文便可以确定该节点是可达的,条目进入 REACHABLE 状态。STALE状态对应于目前还未确认的无效条目。当一个条目之前是REACHABLE 状态但已有一段时间没有更新,或者收到主动报文时(例如,一个节点改变其地址并发送主动NA报文),它就进入这个状态。这些情况表明,有可能是可达的,但仍需要一个有效的NA来确认。

其他状态 DELAY 和 PROBE 是临时状态。DELAY被用于当一个数据包已经被发送了,但ND目前尚无证据表明可能是可达的情况。该状态给上层协议一个机会来提供更多的证据。如果在DELAY_FIRST_PROBE_TIME秒(常数)后仍然没有接收到证据,状态将会改变到PROBE。在PROBE状态,ND会定期发送NS报文(每RetransTimer毫秒,常数默认值RETRANS_TIMER等于1000)。如果在发送MAX_UNICAST_SOLICIT(预设为3)个NS 报文后还未收到任何证据,就应该删除该条目。

8.5.5 安全邻居发现

SEND(安全邻居发现)[RFC3971]是一组特殊的增强功能,旨在为 ND 报文提供额外的安全性。这是为了帮助抵制各种欺骗攻击,其中一台主机或路由器可能会伪装成另一个。特别是在响应NS报文时,它防止节点伪装成其他节点。SEND不使用IPsec,它有自身的特殊机制。这种机制也可用于确保安全的FMIPv6切换[RFC5269]。

SEND在一套假设的框架中操作。首先,每个具备SEND的路由器有一个证书或密码认证,它可以用来证明一台主机的身份。接下来,每个主机还配备了一个信任锚——配置信息可以用来验证证书的有效性。最后,每个节点在配置它将使用的IPv6地址时,将会生成一个公钥/私钥对。

8.5.5.1 密码生成地址

也许 SEND 最有趣的特征是使用完全不同类型的称为密码生成的地址(Cryptographically Generated Address,CGA)[RFC3972] [RFC4581] [RFC4982]的IPv6地址。这种类型的地址是基于节点的公钥信息,从而将地址和节点证书关联起来。因此,拥有相应的私钥的节点或地址的所有者能够证明它是一个特定CGA 的授权用户。CGA也编码与它们相关联的子网前缀,因此它们不能被轻易地从一个子网转移到另一个子网。这种做法与通常分配地址的方法完全不同。

将一个64 位的子网前缀和一个特殊构造的接口标识符相“或”,便生成了一个IPv6 CGA,CGA接口标识符是通过一个称为Hash1的安全散列函数计算出来的,它的输入是节点的公钥和一个特殊的 CGA 参数数据结构。这些参数也被用来作为另一个安全散列函数Hash2 的输入,它提供了散列扩展技术,能有效地扩展散列函数的输出位数,进而提高其安全性(即生成一个不同的输入但却有相同散列值的强度)。CGA 技术允许自动生成地址所有者的公钥,所以这种方法可以在没有公钥基础设施或其他可信任的第三方下工作。

CGA 参数数据结构如下图所示。伪随机序列(Modifier)字段初始化一个随机值,碰撞计数(Collision Count)字段初始化为0。这个结构包括一个扩展字段可供未来使用[RFC4581]。

image-20250509141023072

一个称为Sec的3位无符号参数将影响该方法对数学破解的抵御力,以及计算中的计算复杂性(在Sec值中它们是指数的),IANA为Sec值维护一个注册表[SI]。配合 Sec 值,Hash1 和 Hash2 函数在相同的 CGA参数块进行操作。该地址所有者首先为伪随机序列字段选择一个随机值,将子网前缀字段看作 0,再计算 Hash2 的值。结果需要有(16 * Sec)个初始0位,所以修改输入将伪随机序列字段递增1,并重新计算Hash2 直到条件满足为止。这种计算的时间复杂度为 O(2 ^16 * Sec),并随着 Sec 的增加代价会更高。但是,只有当最初创建地址时,这种计算才是必需的。

一旦找到适当伪随机序列字段,便用59位的Hash1 值形成接口标识符的低 59位。前3位构成 3位Sec值,6-7(左起)位包含两个0位(对应于u和g地址)。如果该地址被发现存在冲突,递增碰撞计数字段,并重新计算Hash1。碰撞计数值的增长是不允许超过2的。由于地址冲突在开始时是不常见的,当多个这样的冲突出现时应考虑是否配置错误或遭到了攻击。一旦所有必要的计算完成了,通过连接子网前缀,Sec值以及Hash1值便能形成CGA。需要注意的是,如果子网前缀改变了,只需要重新计算Hash1,因为伪随机序列字段值仍然保持不变。

到目前为止我们已经看到 CGA 是如何产生的,但还不知道如何用于安全中。注意任何人都可以生成一个CGA,只要有子网前缀、Sec值和自己的(或别人的)公钥。为了确保CGA格式完好,并使用了适当的子网前缀,它必须经过验证,这一过程称为CGA验证。一个验证需要CGA和CGA参数的知识。验证过程需要确保满足如下条件:碰撞计数不大于2,CGA子网前缀和CGA参数中的前缀匹配,从CGA参数计算出的Hash1需要和CGA的接口标识符部分匹配(其中开始的3位、第6位和第7位“不需要关心”),通过值为0的子网前缀和碰撞计数字段以及CGA参数计算出来的Hash2值应该有(16 * Sec)个初始的0位。如果这些检查都是成功的,就是一个对应于子网前缀的合法 CGA。这个计算最多涉及两个散列函数,这是远远比地址生成过程简单的。

验证CGA正在被其授权地址所有者使用,这称为签名验证,所有者形成了一个类型报文,并附上一个 CGA 签名,该签名是使用 CGA 中的公钥及其对应的私钥的知识计算出来的。通过将一个特殊的 128位类型标签和报文结合起来,验证将形成一个数据块。使用一个 RSA 签名,并结合公钥(从 CGA参数提取)、数据块和签名作为参数来验证 CGA 的所有权。一般来说,只有在 CGA 验证和签名验证过程都顺利完成时,CGA及其用户才被认为是合法的。

使用ICMPv6报文和6个在[RFC3971]中定义的选项来处理CGA和验证。RFC还定义了2个IANA托管的注册表,用来保存信任锚选项中的名称类型(Name Type)字段和证书选项中的证书类型(Cert Type)字段。[RFC3972]定义了 CGA 报文类型注册表,采用在[RFC3971]中定义的 128 位值(其他值是在 SEND 之外定义使用的)0x086FCA5E10B200C99C8CE00164277C08。Sec 的注册值在[RFC4982]中定义,但目前只提供值 0、1、2,分别对应于在 Hash2 函数中使用的 SHA-1 安全散列函数使用的 0、16 或 32 个初始 0 位。在[RFC4581]中定义的扩展格式支持 TLV 编码,可用于未来标准的扩展,但到目前为止只定义了一个[RFC5535]。

8.5.5.2 证书路径请求/通告(ICMPv6类型148/149)

SEND 定义了请求和通告报文用来帮助主机确定构成一个证书路径的证书。这被主机用来验证路由器通告的真实性。下图显示了请求报文。

image-20250509142255270

  • 标识符:用来匹配请求和通告
  • 组件:提供了一个索引以表示请求者感兴趣的证书路径中的点。如果需要整个路径中的证书,这个值被设置为全1(值65535)。
  • 选项:这个报文可能包含一个信任锚选项

下图显示的证书路径通告报文提供了在一个多组件通告中表示一个组件(证书)的方法。这些报文为了响应一个请求而发送,或由具备SEND功能的路由器定期发送。当为了响应请求而发送报文时,目的IPv6地址是接收者的被请求节点组播地址。

image-20250509142559432

  • 标识符:填写在相应的请求报文中收到的值。针对发送到所有节点组播地址的主动通告报文,该值被设置为 0。
  • 所有组件:表示在整个证书路径中的组件总数,包括信任锚。需要注意的是推荐用一个单独的通告报文来避免分片,那么这样的报文只包含一个单一的组件。
  • 组件:给出了在证书路径中相关证书的索引(提供一个附加的证书选项)。在一个N个组件的证书路径中发送通告的推荐顺序是(N-1,N-2,…,0)。组件 N 不必被发送,因为它已经在信任锚中。

8.5.6 ICMPv6邻居发现选项

正如 IPv6 家族中的许多协议,它定义了一套标准协议头部,还包含了一个或多个选项。
ND(邻居发现)报文可能包含零个或多个选项,一些选项可以出现多次。但是,对于某些报文而言,有些选项是必需的。下图给出了ND 选项的通用格式。

image-20250509153112120

所有的ND选项以8位类型和8位长度字段开始,支持长度可变的选项,最大到255字节。选项被填充以形成8 字节边界,长度字段给出了选项的总长度,以8字节为单位。类型和长度字段包含在长度字段的值中,最小值为1。下表给出的列表包含了在2011年年中定义的25个标准选项(加上实验值)。正式列表可以在[ICMP6TYPES]中找到。

image-20250509153221868

image-20250509153239631

8.5.6.1 源/目标链路层地址选项(类型1,2)

每当在一个支持链路层选址的网络中使用时,源链路层地址选项(类型 1,参见下图)就应该被包含在 ICMPv6 RS 报文、NS 报文和RA 报文中。它指定了一个和报文相关的链路层地址。对于含有多个地址的节点可能包含上述的多个选项。

当响应一个组播请求时,采用类似格式的目标链路层地址选项必须包含在NA报文中。这个选项通常包含在重定向报文中(之前讨论的),但当在一个NBMA网络上操作时则必须被包含在这样的报文中。

image-20250509153431635

8.5.6.2 前缀信息选项(类型 3)

在RA报文和移动前缀通告报文中提供的前缀信息选项(PIO)表示链路上节点的IPv6地址前缀和(在某些情况下)完整的 IPv6 地址(参见下图)。

image-20250509153839855

在多个前缀或者地址被报告的情况下,在单个报文中可能包含多个该选项的拷贝。路由器应该包含它使用的每个前缀的PIO。将R位字段设置为1表示前缀字段包含发送路由器的整个全局IPv6地址,而不只是将前缀中的剩余位设置为0或者是它的本地链路地址(在所包含的IPv6数据报的源IP地址字段中),这对移动IPv6本地代理发现将非常有用,发送路由器通告的本地代理必须包含这个选项,其中至少为一个前缀设置R位字段。

  • 前缀长度:给出在配置中被视为有效的前缀字段中的位数(多达128位)。
  • L位:是“在链路上”的标志,并表示所提供的前缀是能用于在链路上判定的。如果没有设置,它对在链路上判定的使用没有做任何声明。
  • A位:是“自主自动配置”标志,并表示所提供的前缀可用于自动配置。
  • 有效生命周期:前缀能被用于在链路上判定的秒数,值 0xFFFFFFFF 表示无穷大
  • 首选生命周期:前缀能被用于在自动地址配置的秒数,值 0xFFFFFFFF 表示无穷大

在IPv6中,“在链路上”的节点对应于那些能够使用直接交付到达的节点。在 IPv4 中,节点被认为是在链路上的,如果它们有一个共同的前缀,由它们自己的IPv4地址和分配的子网掩码组合确定。虽然使用IPv6就可以实现这样的安排,但并不是必需的,未经确认“在链路上”状态不能被假设。相反,L位字段表示对一台主机或路由器而言哪些前缀或单个主机列表是在链路上的[RFC5942]。其他机制也可以达到这个目的(例如,DHCPv6,手工配置,或ICMPv6重定向报文)。一个节点通常被认为是不在链路上的,除非有确认信息表明它是在链路上的。

8.5.6.3 重定向头部选项(类型4)

重定向头部选项被用于包含一份导致生成重定向报文的原始(“违规”)IPv6数据报。下图给出了选项格式。任何其他类型的报文将忽略该选项。

image-20250509154646609

8.5.6.4 MTU 选项(类型 5)

MTU选项仅在RA报文中提供,在其他地方被忽略(参见下图)。它提供了主机使用的 MTU,假设能够支持一个可配置的 MTU。

image-20250509160055140

MTU 选项非常重要,例如在桥接两个或者多个拥有多个不同 MTU 的异构链路层技术时。没有这个选项(假设桥接并没有产生 ICMPv6 PTB 报文),在桥接链路层网络中主机可能无法可靠地和其他主机通信。注意这个报文保留了 32 个比特位来存储 MTU,支持非常大的MTU。

8.5.6.5 通告间隔选项(类型 7)

这个选项可能被包含在 RA 报文中,在其他地方被忽略。它指定了主动组播路由器通告间的最大时间间隔(参见下图)。

image-20250509160240583

通告间隔选项给出定期路由器通告报文间的时间。通告间隔字段定义了此报文到达网络上的发送者所发送的RA报文传输间的最大毫秒数(主动组播路由器通告之间间隔的毫秒数)。路由器发送的通告可能比选项指定的通告多,但是并不频繁。移动IPv6节点在其运动检测算法中使用此选项[RFC6275]。

8.5.6.6 本地代理信息选项(类型8)

这个选项包含在愿意充当移动 IPv6 本地代理[RFC6275](即那些在RA 报文中设置 H位字段的)的路由器发出的 RA 报文中,在其他的地方被忽略。如果 H 位字段没有被设置的话,是不允许包含该选项的。在使用了请求 RA 报文进而多个不同的报文携带了多个地址且设置了 R 位字段的情况下,它们中的每个都必须包含该选项,且包含相同的值。下图给出了本地代理信息选项格式。

image-20250509160538313

  • 本地代理优先级:是一个16位无符号整数,用于帮助移动节点预定通过“本地代理地址发现应答”报文提供给它的地址。值越大表示使用发送路由器作为一个本地代理的优先级程度越大。如果这个选项没有被包括在 H 位字段(本地代理)已经被设置的路由器通告报文中,起始路由器的优先级值被认为是 0(最低的优先级)。
  • 本地代理生命周期:是16位无符号整数,指定该报文的发送者应考虑作为本地代理的秒数。此字段的默认值等于所包含的RA报文生命周期字段。这一字段的最大值(65 535)对应18.2小时,最小值是1(0表示不允许),如果本地代理生命周期和本地代理优先级字段仅包含默认值,那就不允许在RA 报文中包含整个选项。

8.5.6.7 源和目标地址列表选项(类型9,10)

这些选项可能被包含在IND 报文中[RFC3122]。下图给出了格式。

image-20250509161033282

源地址列表选项(类型9)包含了一个由源链路层地址选项指定的IPv6地址列表。目标地址列表选项(类型10)包含了由目的链路层地址选项指定的IPv6地址列表。在选项中包含的地址个数等于(Length-1)/2,其中长度(Length)字段值包含了选项的大小,以 8 字节为单位。

8.5.6.8 CGA选项(类型 11)

CGA 选项被用来和 SEND 一起携带 CGA 参数,这些参数是检验器执行 CGA 验证和签名验证所必需的。下图给出了它的格式。

image-20250509161240985

CGA 参数部分由下图描述的相同字段组成。更多的细节请参见[RFC3971]。

image-20250509161406726

8.5.6.9 RSA签名选项(类型12)

RSA签名选项被用来和SEND一起携带校验器能够使用的RSA签名,将它和CGA参数一起确定发送系统是否拥有与 CGA公钥相关的私钥。下图给出了它的格式。

image-20250509161622221

  • 密钥散列:包含构建签名所使用的公钥经 SHA-1 散列后其结果的高 128位。
  • 数字签名:包含一个基于下面这些值的标准化签名:SEND的CGA报文类型标签,源IP 和目的 IP 地址,ICMPv6头部的开始 32 位字(类型、代码和校验和字段),ND 协议的报文头和选项(不包括 RSA 签名选项)。

8.5.6.10 时间戳选项(类型 13)

时间戳选项给出了发送系统知晓的当天的当前时间。这有助于避免遭到潜在的针对SEND的重放攻击。下图给出了它的格式。

image-20250509161924007

时间戳字段记录了自1970年1月1日00:00 UTC以来的秒数。其格式是定点的,高阶的48位编码了完整的秒数,剩下的位数表示小数秒(1/64K)的值。

8.5.6.11 随机数选项(类型 14)

随机数选项保存了一个最近生成的随机数。这有助于防范潜在的针对 SEND 的重放攻击。下图给出了它的格式。

image-20250509162053277

随机数选项值是由发送者选择的一个随机数。数值的长度至少为6个字节。

8.5.6.12 信任锚选项(类型 15)

信任锚选项包含了一个证书路径的名称(根)。它与SEND一起被主机用来验证 RA 报文的真实性。下图给出了它的格式。

image-20250509162219247

名称类型(Name Type)字段表示所使用的名称类型。当前已经定义了两个值:1,DERX.502 名称;2,全限定域名称(FQDN)。可能会包含多个信任锚。名称字段采用名称类型字段定义的格式给出了信任锚的名称。信任锚是报文发送者愿意接受的信任链的信任根。

8.5.6.13 证书选项(类型 16)

证书选项保存了和 SEND一起使用的单独证书,用以提供证书路径。下图给出了它的格式。

image-20250509162714281

证书类型字段表示所使用的证书的类型。目前,只定义了一个值:1,X.509v3 证书。

8.5.6.14 IP 地址/前缀选项(类型17)

IP地址/前缀选项是和FMIPv6报文一起使用的(ICMPv6类型154)。下图给出了它的格式。

image-20250509162922012

  • 选项代码:表示哪种类型的地址被编码了:1,旧的移交地址;2,新的移交地址;3,新访问路由器的(NAR的)IPv6地址;4,NAR 的前缀(在PrRtAdv 中)。
  • 前缀长度:给出了IPv6地址字段中有效前导位个数。
  • IPv6地址字段:编码了由选项代码字段认定的IPv6地址。

8.5.6.15 链路层地址选项(类型19)

链路层地址(LLA)选项是和 FMIPv6 报文(ICMPv6 类型 154)[RFC5568]一起使用的。下图给出了它的格式。

image-20250509163207010

  • 选项代码字段值表示相关的链路层地址字段值是如何解释的:

    • 0,通配符,即附近所有的AP都要求解析
    • 1,新AP的地址
    • 2,移动节点的地址
    • 3,新访问路由器的地址
    • 4,RtSolPr/PrRtAdv报文的源地址
    • 5,地址是当前路由器的
    • 6,对应到这个地址的AP没有可用的前缀信息
    • 7,编址的AP没有可用的快速切换
  • 链路层地址字段包含由选项代码字段指定的地址。

8.5.6.16 邻居通告确认选项(类型20)

该选项是和 FMIPv6 报文(ICMPv6 类型 154)[RFC5568]一起使用的。下图给出了它的格式。

image-20250509163524386

  • 选项代码:值是 0
  • 状态:表示对主动邻居报文的处置。定义了如下值:
    • 1,新移交地址(NCoA)是无效的(执行地址配置)
    • 2,NCoA是无效的(采用IP地址选项中提供的NCoA)
    • 3,NCoA是无效的(使用NAR的地址来代替NCoA)
    • 4,之前提供的移交地址(PCoA)(没有发送绑定更新)
    • 128,无法识别的链路层地址。

8.5.6.17 路由信息选项(类型24)

该选项与 RA 报文一起使用,表示通过一个特定路由器能够到达哪些不在链路上的前缀[RFC4191]。下图给出了它的格式。

image-20250509163957892

  • 前缀长度:给出了前缀字段中的有效先导位的个数。
  • 前缀:表示和包含的前缀相关联的路由器相对于其他路由器的优先级。如果这个字段包含值2,选项必须被忽略。
  • 路由生命周期:给出了前缀被认为有效的秒数。所有位都是 1 的值表示无穷大。
  • 前缀(可变长度):给出了被描述的 IPv6 前缀。

8.5.6.18 递归 DNS 服务器选项(类型 25)

[RFC6160]中定义的递归DNS服务器(RDNSS)选项和RA报文一起使用,能够通过提供一个或者多个DNS服务器的地址来增强无状态配置。一个 RA报文中可能包含多个RDNSS选项。下图给出了它的格式。

image-20250509164519778

生命周期(Lifetime)字段给出了列表中的DNS服务器被认为是有效的时间长度,以秒计。所有位都是 1 的值表示无穷大的生命周期。假如需要不同的生命周期,在同一个RA 报文中可能包含多个不同的RDNSS选项。

8.5.6.19 路由器通告扩展标志选项(类型26)

这个选项扩展了 RA 报文中使用的标志字段。它有时也称为扩展标志选项(Expanded Flags Option,EFO)。下图给出了它的格式。

image-20250509164708963

长度(Length)字段目前被定义为1,直到后续的位被分配为止。

8.5.6.20 切换密钥请求选项(类型27)

切换密钥请求选项和FMIPv6报文一起使用,它使用SEND保护信令信息的安全[RFC5269],下图给出了它的格式。

image-20250509164909473

  • 填充长度:给出了在选项尾部用 0 填充的字节个数(包含在长度字段之内)。
  • 算法类型(Algorithm Type,AT):表示用于计算认证者的算法(参见[RFC5568])。
  • 切换密钥加密公钥:使用和CGA选项相同的格式加密了 FMIPv6 CGA 公钥。
  • 填充:包含了值为 0 的字节以保证选项的长度是 8字节的倍数。

8.5.6.21 切换密钥应答选项(类型28)

该选项和FMIPv6报文一起使用,它使用SEND保护信令信息的安全[RFC5269]。下图给出了它的格式。

image-20250509165212275

  • 填充长度:给出了在选项尾部用 0 填充的字节个数(包含在长度字段之内)。
  • 算法类型(Algorithm Type,AT):表示用于计算认证者的算法(参见[RFC5568])。
  • 密钥生命周期:给出了切换密钥有效的秒数(默认是HK-LIFETIME或者43 200s)。
  • 加密的切换密钥:保存了一个对称密钥。是经过移动节点的切换密钥加密过的。加密格式是 RSAES-PKCS1-v1_5[RFC3447]。
  • 填充:包含了值为 0 的字节以保证选项的长度是 8 字节的倍数。

8.5.6.22 DNS搜索列表选项(类型31)

DNS 搜索列表(DNSSL)选项[RFC6106]用来表示一个域名扩展列表被添加到一台主机可能发起的 DNS 查询中。搜索列表是 DNS 配置信息中的一部分,当它初始化时可能提供给主机。下图给出了 DNSSL 选项的格式。

image-20250509170942993

生命周期字段表示从报文被发送的时间开始,域名搜索列表被认为是有效的时长。域名搜索列表包含一个域名扩展的列表(未压缩的),作为从部分字符串构建的FQDN的默认形式。

8.6——ICMPv4和ICMPv6转换

[RFC6145]描述了从ICMPv4转换到ICMPv6的方法,以及相反方向的转换方法。当转换ICMP时,IP和ICMP头部都要被转换。除此之外,包含了一个内部违规数据包头部及数据的ICMP差错报文,也会转换内部(违规)数据报的头部。除了映射适当的类型和代码号之外,还有需要额外考虑的分片、MTU大小以及校验和计算。回忆一下,ICMPv6 使用一个伪头部校验和来涵盖网络层信息,而ICMPv4 校验和只是在 ICMPv4 信息之上计算的。

8.6.1 从ICMPv4 转换 ICMPv6

当转换ICMPv4 信息报文到ICMPv6时,只有回显请求和回显应答报文被转换了。为了执行这个转换,类型值(8 和 0)分别被转换到值 128 和 129。在转换之后,计算并应用ICMPv6 的伪头部校验和。当转换ICMPv4 差错报文时,只有下面的差错报文被转换了:目的不可达(类型3),超时(类型11),参数问题(类型12)。

下表给出了用来执行转换的类型和代码值。没有给出的类型和代码是不会被转换的,到达的已经被转换的数据包将会被丢弃。

image-20250509171653459

正如上表给出的,对于由指针字段给出出现问题的字节偏移值的参数问题报文,用一个额外的映射来形成适当的 IPv6 指针字段值。下表给出了这个映射。

image-20250509172752608

除了要执行头部转换之外,携带在ICMPv4差错报文中的违规数据报也要根据IPv4/IPv6 转换规则来转换。注意这意味着如果内部转换没有执行的话,最终得到的ICMPv6数据报和它应有的大小会有很大不同。更新基本IPv6头部中的总长度(Total Length)字段以便反映这种影响。注意只能支持一层这种内部转换。如果发现了一个或者多个附加的内部头义部,正在被转换的数据包将被丢弃。通常,除ICMP报文之外的数据包如果转换失败将会生成一个ICMPv4 目的不可达——通信管理上禁止(代码13)报文,并将其发送到该失败数据包的发送者那里。

注意,与其他被转换到IPv6的IPv4流量一样,DF位字段没有设置的到达的数据包会导致一个或者多个包含分片头部的IPv6数据包,且生成的分片不会超过IPv6的最小MTU。这主要是为了处理IPv4的路由器允许分片IPv4流量而IPv6路由器却不允许的问题。ICMPv4 PTB报文可能需要转换到ICMPv6 PTB报文,其MTU值小于IPv6的最小链路MTU 1280字节。一个操作正确的IPv6协议栈会处理所有这样的报文,然后发送装备有分片头部的后续数据报到相同目的地。

8.6.2 从ICMPv6转换到ICMPv4

在ICMPv6信息类报文中,回显请求(类型128)和回显应答(类型129)报文被分别转换到ICMPv4回显请求(类型8)和回显应答(类型0)。更新校验和以体现类型值变化和缺少伪头部计算。其他信息类报文将被丢弃。下表给出了差错报文是如何被转换的,给出了进(ICMPv6)和出(ICMPv4)类型和代码值。

image-20250509174750992

image-20250509174831400

再一次,与参数问题报文一起使用的指针字段需要特殊处理。下表提供了从ICMPv6到ICMPv4这种情况的映射。

image-20250509175127217

注意ICMPv4校验和没有使用伪头部,因此当执行一个头部转换,假如执行的是一个非校验和中立地址转换,那么必须更新产生的校验和。此外,内部的IPv6报文可能包含非IPv4可转换地址,导致需要进行状态转换。

果发现了一个或者多个附加的内部头义部,正在被转换的数据包将被丢弃。通常,除ICMP报文之外的数据包如果转换失败将会生成一个ICMPv4 目的不可达——通信管理上禁止(代码13)报文,并将其发送到该失败数据包的发送者那里。

注意,与其他被转换到IPv6的IPv4流量一样,DF位字段没有设置的到达的数据包会导致一个或者多个包含分片头部的IPv6数据包,且生成的分片不会超过IPv6的最小MTU。这主要是为了处理IPv4的路由器允许分片IPv4流量而IPv6路由器却不允许的问题。ICMPv4 PTB报文可能需要转换到ICMPv6 PTB报文,其MTU值小于IPv6的最小链路MTU 1280字节。一个操作正确的IPv6协议栈会处理所有这样的报文,然后发送装备有分片头部的后续数据报到相同目的地。

8.6.2 从ICMPv6转换到ICMPv4

在ICMPv6信息类报文中,回显请求(类型128)和回显应答(类型129)报文被分别转换到ICMPv4回显请求(类型8)和回显应答(类型0)。更新校验和以体现类型值变化和缺少伪头部计算。其他信息类报文将被丢弃。下表给出了差错报文是如何被转换的,给出了进(ICMPv6)和出(ICMPv4)类型和代码值。

[外链图片转存中…(img-gfw8wvGl-1747056150327)]

[外链图片转存中…(img-N8UoZBF8-1747056150328)]

再一次,与参数问题报文一起使用的指针字段需要特殊处理。下表提供了从ICMPv6到ICMPv4这种情况的映射。

[外链图片转存中…(img-HPC7weKh-1747056150328)]

注意ICMPv4校验和没有使用伪头部,因此当执行一个头部转换,假如执行的是一个非校验和中立地址转换,那么必须更新产生的校验和。此外,内部的IPv6报文可能包含非IPv4可转换地址,导致需要进行状态转换。

当处理数据包大小差异时,回忆一下在IPv6数据报中没有不分片指示(“不分片”总是隐含为真),路由器不能执行分片操作。结果,将会丢弃到达转换器中的那些并不适合到达下一跳IPv4接口MTU的IPv6数据包,然后发送一个适当的ICMPv6 PTB报文返回违规数据报的IPv6源。

相关文章:

  • 深入掌握CSS定位:构建精密布局的核心技术
  • 第二章、物理层
  • 开发环境(Development Environment)
  • 【SSM-Mybatis(一)】java持久层框架-Mybatis!本文涵盖介绍Mybatis和基本使用,分析Mybatis核心配置文件
  • 豆瓣电影Top250数据工程实践:从爬虫到智能存储的技术演进(含完整代码)
  • 【Ansible】之inventory主机清单
  • 麒麟 v10 cgroup v1 切换 cgroup v2
  • 上海海关特展:二维码讲解“外来入侵物种”的危害!
  • 小智AI客户端使用测试(Python)
  • 让 - 艾里克・德布尔与斯普林格出版公司:科技变革下的出版业探索
  • 韩国直邮新纪元:Coupang多语言支持覆盖38国市场
  • 服务网格的“解剖学” - 控制平面与数据平面
  • VIC-2D 7.0 为平面样件机械试验提供全视野位移及应变数据软件
  • 1.3 极限
  • 生成对抗网络(GAN)深度解析:理论、技术与应用全景
  • 通用RAG:通过路由模块对多源异构知识库检索生成问答思路
  • 我用Deepseek + 亮数据爬虫神器 1小时做出輿情分析器
  • 【Java学习笔记】多态数组
  • HLS图像处理:从算法到硬件的创新加速之旅
  • 【类拷贝文件的运用】
  • 27岁杨阳拟任苏木镇党委副职,系2020年内蒙古自治区选调生
  • 1至4月我国汽车产销量首次双超千万辆
  • 泽连斯基:乌克兰已做好与俄罗斯举行会谈的准备
  • 默茨首访聚焦欧洲,欲推欧洲防务自主
  • 宣布停火后,印控克什米尔地区再次传出爆炸声
  • 铁肩担道义,历史鉴未来——中共中央政治局委员、外交部长王毅谈习近平主席对俄罗斯进行国事访问并出席纪念苏联伟大卫国战争胜利80周年庆典