跳到主要内容

2. ICMPv6 (ICMP for IPv6)

IPv6 节点使用 ICMPv6 报告处理数据包时遇到的错误, 并执行其他互联网层功能, 例如诊断 (ICMPv6 "ping"). ICMPv6 是 IPv6 的组成部分, 每个 IPv6 节点都必须完整实现基础协议 (即本规范要求的所有消息和行为).

2.1. 消息通用格式 (Message General Format)

每个 ICMPv6 消息前面都有一个 IPv6 头部以及零个或多个 IPv6 扩展头部. ICMPv6 头部由紧邻其前的头部中 Next Header 值 58 标识. (这不同于用于标识 IPv4 ICMP 的值.)

ICMPv6 消息具有以下通用格式:

    0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Code | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ Message Body +
| |

Type 字段指示消息类型. 其值决定剩余数据的格式.

Code 字段取决于消息类型. 它用于建立更细一级的消息粒度.

Checksum 字段用于检测 ICMPv6 消息以及 IPv6 头部部分内容中的数据损坏.

ICMPv6 消息分为两类: 错误消息和信息消息. 错误消息通过其消息 Type 字段值最高有效位为零来标识. 因此, 错误消息的消息类型范围是 0 到 127; 信息消息的消息类型范围是 128 到 255.

本文档定义以下 ICMPv6 消息的消息格式:

ICMPv6 错误消息:

  • 1 - 目标不可达 (Destination Unreachable, 见第 3.1 节)
  • 2 - 数据包过大 (Packet Too Big, 见第 3.2 节)
  • 3 - 时间超限 (Time Exceeded, 见第 3.3 节)
  • 4 - 参数问题 (Parameter Problem, 见第 3.4 节)
  • 100 - 私有实验
  • 101 - 私有实验
  • 127 - 保留用于扩展 ICMPv6 错误消息

ICMPv6 信息消息:

  • 128 - 回显请求 (Echo Request, 见第 4.1 节)
  • 129 - 回显应答 (Echo Reply, 见第 4.2 节)
  • 200 - 私有实验
  • 201 - 私有实验
  • 255 - 保留用于扩展 ICMPv6 信息消息

类型值 100, 101, 200 和 201 保留用于私有实验. 它们不打算用于通用用途. 预期多个并发实验会使用相同的类型值. 任何大规模和/或不受控的使用都应按第 6 节定义的方式取得真实分配.

类型值 127 和 255 保留用于未来在类型值范围短缺时进行扩展. 具体细节留待未来工作. 一种不会给当前实现造成问题的可能方式是: 如果类型等于 127 或 255, 则使用 Code 字段进行新的分配. 现有实现会按第 2.4 节 (b) 的规定忽略这些新分配. 使用这些扩展类型值的新消息可以在消息体中为其 code 值分配字段.

第 3 节和第 4 节描述 ICMPv6 错误消息类型 1 到 4 以及信息消息类型 128 和 129 的消息格式.

至少包含触发数据包的起始部分, 其目的是允许导致 ICMPv6 错误消息的数据包的发送者识别发送该数据包的上层协议和进程.

2.2. 消息源地址确定 (Message Source Address Determination)

发起 ICMPv6 消息的节点必须在计算校验和之前确定 IPv6 头部中的源 IPv6 地址和目标 IPv6 地址. 如果节点拥有多个单播地址, 它必须按如下方式选择消息的源地址:

(a) 如果该消息是对发送到该节点某个单播地址的消息的响应, 应答的源地址必须是同一地址.

(b) 如果该消息是对发送到任何其他地址的消息的响应, 例如 - 组播组地址, - 该节点实现的任播地址, 或 - 不属于该节点的单播地址

则 ICMPv6 数据包的源地址必须是属于该节点的单播地址. 该地址应按节点为其发起的任何其他数据包选择源地址时使用的规则来选择, 给定条件是该数据包的目标地址. 不过, 如果另一种选择方式会产生一个从 ICMPv6 数据包目标可达且信息量更大的地址, 也可以采用该方式.

2.3. 消息校验和计算 (Message Checksum Calculation)

校验和是整个 ICMPv6 消息的一补和的一补的 16 位值, 计算从 ICMPv6 消息 Type 字段开始, 并在其前加上由 IPv6 头部字段组成的"伪头部", 如 [IPv6, Section 8.1] 所规定. 伪头部中使用的 Next Header 值为 58. (在 ICMPv6 校验和中包含伪头部是相对于 IPv4 的一项变化; 该变化的理由见 [IPv6].)

计算校验和时, 首先将 Checksum 字段置为零.

2.4. 消息处理规则 (Message Processing Rules)

实现处理 ICMPv6 消息时必须遵守以下规则 (来自 [RFC-1122]):

(a) 如果在目标处收到未知类型的 ICMPv6 错误消息, 则在能够识别的情况下, 必须将其传递给发起导致该错误的数据包的上层进程 (见第 2.4 节 (d)).

(b) 如果收到未知类型的 ICMPv6 信息消息, 必须静默丢弃.

(c) 每个 ICMPv6 错误消息 (type < 128) 必须包含尽可能多的 IPv6 出错 (触发) 数据包 (即导致该错误的数据包), 但不得使错误消息数据包超过 IPv6 最小 MTU [IPv6].

(d) 当要求互联网层协议将 ICMPv6 错误消息传递给上层进程时, 会从原始数据包 (包含在 ICMPv6 错误消息体中) 提取上层协议类型, 并用它选择适当的上层进程来处理该错误.

如果无法从 ICMPv6 消息中取回上层协议类型, 则在完成任何 IPv6 层处理后静默丢弃该 ICMPv6 消息. 一个示例是某个 ICMPv6 消息带有异常大量的扩展头部, 由于原始数据包为满足 IPv6 最小 MTU [IPv6] 限制而被截断, 导致不包含上层协议类型. 另一个示例是某个 ICMPv6 消息带有 ESP 扩展头部, 由于原始数据包被截断或缺少解密该数据包所需的状态, 无法解密原始数据包.

(e) 收到以下内容时, 禁止因此发起 ICMPv6 错误消息:

(e.1) ICMPv6 错误消息.

(e.2) ICMPv6 重定向消息 [IPv6-DISC].

(e.3) 目标为 IPv6 组播地址的数据包. (该规则有两个例外: (1) Packet Too Big 消息 (第 3.2 节), 用于让路径 MTU 发现能够适用于 IPv6 组播; (2) Parameter Problem 消息, Code 2 (第 3.4 节), 用于报告无法识别的 IPv6 选项 (见 [IPv6] 第 4.2 节), 且该选项的 Option Type 最高两位设置为 10).

(e.4) 以链路层组播形式发送的数据包 (e.3 的例外也适用于这种情况).

(e.5) 以链路层广播形式发送的数据包 (e.3 的例外也适用于这种情况).

(e.6) 源地址不能唯一标识单个节点的数据包, 例如 IPv6 未指定地址, IPv6 组播地址, 或 ICMP 消息发起者已知为 IPv6 任播地址的地址.

(f) 最后, 为了限制发起 ICMPv6 错误消息带来的带宽和转发成本, IPv6 节点必须限制其发起 ICMPv6 错误消息的速率. 当某个源发送错误数据包流而未理会由此产生的 ICMPv6 错误消息时, 可能出现这种情况.

对转发的 ICMP 消息进行速率限制超出本规范范围.

推荐的速率限制功能实现方法是令牌桶, 将平均传输速率限制为 N, 其中 N 可以是 packets/second, 也可以是所连接链路带宽的某个分数, 同时允许以突发方式传输最多 B 个错误消息, 只要长期平均值不被超过.

不能应对突发流量 (例如 traceroute) 的速率限制机制不推荐使用; 例如, 一个简单的基于定时器的实现, 每 T 毫秒允许一个错误消息 (即使 T 取较小值), 并不合理.

速率限制参数应当可配置. 对于令牌桶实现, 最佳默认值取决于预期部署位置 (例如高端路由器与嵌入式主机). 例如, 在小型/中型设备中, 可能的默认值可以是 B=10, N=10/s.

注意: 上述 (e) 和 (f) 中的限制优先于本文档其他任何关于发起 ICMP 错误消息的要求.

以下各节描述上述 ICMPv6 消息的消息格式.