GUA
2000::/3
全球单播。IANA 当前分配块是 2000::/3(即最高 3 bit 为 001)。教学文档里的 2001:db8::/32 专供举例,路由表里不该出现。
全书对 NDP、SLAAC、ICMPv6 几乎只点到名字。这一页把地址、40 字节首部、邻居发现五种报文、地址配置决策和排障命令按抓包能对上的粒度写完。
IPv6 地址 128 bit,写成 8 组 4 位十六进制。每组可省前导零;连续的全零组只能用一次 :: 压缩。没有广播,广播的活交给组播。
2000::/3
全球单播。IANA 当前分配块是 2000::/3(即最高 3 bit 为 001)。教学文档里的 2001:db8::/32 专供举例,路由表里不该出现。
fc00::/7
唯一本地(RFC 4193)。本地自行分配时 L 位置 1,实际用 fd00::/8 再加 40 bit 随机 Global ID。fc00::/8(L=0)留给尚未启用的中心分配。
fe80::/10
链路本地。前缀 10 bit 1111111010 + 54 bit 全 0 + 64 bit 接口标识,所以线上几乎总是 fe80::/64。每个接口必须有一个。路由器不得把 LLA 源或目的转发到别的链路。
::/128 · ::1/128
:: 是未指定地址,表示“还没有地址”(DAD 的 NS 源地址)。::1 是环回。二者不可对调,也不可配到物理接口上。
LLA 的规范前缀是 FE80::/10,但格式图把接下来 54 bit 钉死为 0。写地址时用 fe80::IID;写前缀长度时教学和实现都按 /64。看到 fec0::/10 是已废弃的站点本地(RFC 3879),新实现按全球单播对待。
fe80::1%en0链路本地和有限范围组播在节点上可能对应多条链路。RFC 4007 规定文本形式 <address>%<zone_id>。zone id 只在本机有意义:macOS / BSD 常用接口名(en0),Linux 用接口名或 ifindex(eth0 / 2)。% 后面那截不上线,抓包里看不到。
同一条链路在两台机器上的 zone id 不必相同。A 机的 %en0 和 B 机的 %eth0 可以指同一条线。把 %en0 抄进配置文件、DNS 或对端命令,是错的。
ff00::/8 | 8 | 4 | 4 | 112 bits |
+--------+----+----+---------------------------------------------+
|11111111|flgs|scop| group ID |
+--------+----+----+---------------------------------------------+
flgs = |0|R|P|T| (RFC 4291 §2.7)
最高 8 bit 全 1。接着 4 bit 标志(T=0 是 IANA 永久组,T=1 是临时组;P / R 见 RFC 3306 / 3956),再 4 bit 范围(scop):
| scop | 范围 | 常见地址 |
|---|---|---|
| 1 | 接口本地 | ff01::1 本接口所有节点 |
| 2 | 链路本地 | ff02::1 全节点 · ff02::2 全路由器 |
| 5 | 站点本地 | ff05::2 站点内全路由器 |
| e | 全球 | 跨站点组播 |
以太网把 IPv6 组播映成 33:33:xx:xx:xx:xx(RFC 2464):取 IPv6 组播地址的最后 32 bit 接到 33:33 后面。交换机按这个 MAC 做组播转发,不是广播。
NDP 不用以太网广播做地址解析。每个单播 / 任播地址对应一个 solicited-node 组播:取该地址的低 24 bit,接到前缀 FF02:0:0:0:0:1:FF00::/104 上(RFC 4291 §2.7.1)。
单播 2001:0db8:0000:0000:021a:2bff:fe3c:4d5e 低 24 bit .............................. 3c:4d5e SNMA ff02:0000:0000:0000:0000:0001:ff3c:4d5e 压缩 ff02::1:ff3c:4d5e 以太网 33:33:ff:3c:4d:5e
同一链路上 IID 后 24 bit 相同的地址会撞到同一个组,但这比“全节点组播”安静两个数量级。节点必须为自己配置过的每个单播 / 任播加入对应 SNMA。
Modified EUI-64(RFC 4291 附录 A)曾是 SLAAC 生成接口标识的默认算法。从 48 bit MAC 做:中间插入 ff:fe,再翻转第一字节的 U/L 位(universal/local,书面形式第一字节从左数第 7 bit,也就是该字节值异或 0x02)。
MAC 00:1a:2b:3c:4d:5e 插入 ff:fe 00:1a:2b:ff:fe:3c:4d:5e 翻转 U/L 02:1a:2b:ff:fe:3c:4d:5e IID 021a:2bff:fe3c:4d5e LLA fe80::21a:2bff:fe3c:4d5e
RFC 8064 起,SLAAC 不应再用 EUI-64 当默认 IID:MAC 会泄漏进全球地址,跨前缀也能追踪同一台机器。现代栈两套并行:
稳定地址用 RFC 7217 语义不透明 IID(同一前缀、同一台机器上稳定,换前缀就变)。临时地址用 RFC 8981(取代 RFC 4941):每个启用了 A 位的前缀再生成随机 IID,定期轮换,外出连接优先用它当源地址。
Wireshark 里看到 ff:fe 夹在 IID 中间,才是旧式 EUI-64;macOS / iOS / Android / 现代 Windows 的全球地址通常没有这段。
33:33:ff:xx:xx:xx,不是广播 ff:ff:ff:ff:ff:ff。fe80::1%en0 没有意义。固定 40 字节。没有 IHL、没有首部校验和、没有分片字段。可选项全部挪到扩展头链,由 Next Header 串起来。
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version| Traffic Class | Flow Label |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Payload Length | Next Header | Hop Limit |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ Source Address +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ Destination Address +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
RFC 8200 §3 · 40 octets
抓包第一字节高半字节是 6。看到 4 就不是这份首部。
差分服务 + ECN,对应 IPv4 的 ToS / DSCP 字节。RFC 8200 把它交给 RFC 2474 / 3168 解释。
源端给“同一流”打的标签。中间节点可用来做等价路径上的粘滞转发。IPv4 没有对等物。
固定 40 字节首部之后的八位组数,含全部扩展头。这是和 IPv4 Total Length(含首部)最容易考反的一点。值为 0 时可能是 jumbogram(Hop-by-Hop 选项,少见)。
紧随其后的头类型,取值与 IPv4 Protocol 同一张 IANA 表:6 TCP、17 UDP、58 ICMPv6,或某个扩展头。
每转发一次减 1;收到已是 0 或减到 0 则丢弃。目的节点收到 Hop Limit = 0 的包应照常处理,不丢。NDP 要求发送时填 255,接收时也必须是 255。
各占 16 字节,合计 32 字节,所以固定首部是 8 + 32 = 40。存在 Routing 头时,目的地址字段沿途会被改写成下一个中间点。
| IPv4(RFC 791) | IPv6(RFC 8200) | 为什么 |
|---|---|---|
| IHL 4 bit | 没有(定长 40 B) | 选项不再挤在基本首部里 |
| Total Length(含首部) | Payload Length(不含 40 B) | 首部长度已知,只报后面有多长 |
| Identification / Flags / Frag Off | 基本首部里没有 | 分片只允许源端做,走 Fragment 扩展头 |
| Header Checksum 16 bit | 没有 | 见下 |
| Protocol | Next Header | 同一张号表,但可以指向扩展头 |
| TTL | Hop Limit | 名字改成名副其实的跳数;算法相同 |
| Options + Padding | 扩展头链 | 仅显式配置的节点才沿途处理 Hop-by-Hop;未配置不影响转发 |
| — | Flow Label 20 bit | 新增 |
RFC 8200 开篇把“丢掉若干 IPv4 字段”写成降低每包转发成本。校验和是其中最贵的一个:IPv4 每跳改 TTL 都必须重算 16 bit 一补码。IPv6 认定两层已经够用——链路层 FCS(以太网 CRC-32)覆盖整帧;TCP / UDP / ICMPv6 的校验和带伪首部,覆盖源、目的、长度和真正的上层 Next Header。中间节点递减 Hop Limit 时不再碰校验和。
连带后果:IPv6 上 UDP 校验和原则上必须算(不能再像 IPv4 那样填 0 关掉);ICMPv6 校验和始终含伪首部,Next Header 取值 58(RFC 4443 §2.3)。
可选的网络层信息放在基本首部和上层头之间,用 Next Header 逐个串。RFC 8200 §4.1 推荐顺序:
IPv6 header Hop-by-Hop Options Next Header = 0 唯一允许沿途处理;须紧跟基本首部 Destination Options 60 给 Routing 头里的中间目的 Routing 43 Fragment 44 仅源端插入 Authentication (AH) 51 Encapsulating Security (ESP) 50 Destination Options 60 只给最终目的 Upper-Layer 6 / 17 / 58 / … No Next Header 59 后面没有上层头
除 Destination Options 最多两次外,每种扩展头建议至多一次。Hop-by-Hop 是唯一允许沿途处理的扩展头,且必须紧跟 IPv6 基本首部(RFC 8200 §4 / §4.3)。RFC 8200 已改为:只有显式配置处理的节点才查看它;未配置的节点跳过该头、正常转发,存在 HbH 不构成丢包理由(RFC 9673 §5.1)。节点必须能接受乱序和重复的扩展头(Hop-by-Hop 除外),但源端应按上面的顺序发。
中间路由器不得把 IPv6 包切开。包大于出接口 MTU 时,路由器丢弃并回 ICMPv6 Packet Too Big(Type 2)。源端若仍要发送超过路径 MTU 的包,自己插 Fragment 头(Next Header 44),在目的地重组。RFC 8200 §5 劝阻这种用法:能适配到路径 MTU(下限 1280)就不要源端分片。
ip.checksum、ip.flags、ip.frag_offset、ip.hdr_len。ipv6.plen 对的是 Payload Length,把它跟整帧长度相加时应再加 40,不要当 IPv4 的 Total Length 用。ipv6.nxt 是第一个 Next Header;真正的上层协议看链尾,或用 tcp / udp / icmpv6。Neighbor Discovery 取代 IPv4 的 ARP、ICMP 路由器发现和 Redirect。五种报文全是 ICMPv6,Code 一律 0,IPv6 Hop Limit 发送填 255、接收也必须是 255——跨 hop 改过 Hop Limit 的伪造包直接丢。
| 报文 | Type | 典型目的 | 干什么 |
|---|---|---|---|
| Router Solicitation | 133 | ff02::2 | 主机催路由器立刻发 RA |
| Router Advertisement | 134 | ff02::1 或单播 | 前缀、MTU、M/O、默认路由器 |
| Neighbor Solicitation | 135 | SNMA 或单播 | 解析 / DAD / NUD |
| Neighbor Advertisement | 136 | 单播或 ff02::1 | 回答 NS,或主动更新缓存 |
| Redirect | 137 | 被重定向主机 | 更好的下一跳 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Code | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options ...
RFC 4861 §4.1
源地址:本接口已有的单播,或还没有地址时用 ::。目的:通常 ff02::2(全路由器)。选项:源链路层地址(Source LLA,Type 1);源是 :: 时不得带这个选项。
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Code | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Cur Hop Limit |M|O| Reserved | Router Lifetime |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Reachable Time |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Retrans Timer |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options ...
RFC 4861 §4.2
源地址必须是发送接口的链路本地。目的:对端 RS 的源,或 ff02::1。固定头里和考试最相关的三位:
SLAAC 真正看的 A 位不在这 16 字节固定头,而在选项 Prefix Information(Type 3):
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type=3 | Length=4 | Prefix Length |L|A|P| Reserved1|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Valid Lifetime |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Preferred Lifetime |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Reserved2 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Prefix (128 bit) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
RFC 4861 §4.6.2 · RFC 9762 P · 32 octets
L:此前缀可用于判断“在链上”。A:此前缀可用于无状态自动配置(RFC 4862)。RFC 9762 在原 Reserved1 里定义了 P 位(DHCPv6-PD Preferred;实际位序为 L|A|R|P|Reserved——R 是 RFC 6275 移动 IPv6 使用,本图略去)。Valid / Preferred Lifetime 各 32 bit 秒;全 1(0xffffffff)表示无穷。Preferred 不得超过 Valid。路由器不应通告链路本地前缀,主机应忽略这样的选项。
常见其它选项:Source LLA(Type 1)、MTU(Type 5)、RDNSS(RFC 8106,Type 25)。
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Code | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Target Address (128 bit) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options ...
RFC 4861 §4.3
Target Address 是“我想解析 / 探测 / 验重的那个单播或任播”,不能是组播。三种用法目的地址不同:
| 用途 | 源 | 目的 | Source LLA |
|---|---|---|---|
| 地址解析 | 本机单播 | 目标的 SNMA | 应当带 |
| NUD | 本机单播 | 邻居单播 | 可选 |
| DAD | :: | 试探地址的 SNMA | 不得带 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Code | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|R|S|O| Reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Target Address (128 bit) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options ...
RFC 4861 §4.4
ff02::1,因此 S=0。若 NS 的源是 ::(对方在做 DAD),NA 不能单播回去,目的改成 ff02::1。选项 Target LLA(Type 2)给出自己的 MAC。
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Code | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Target Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Destination Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options ...
RFC 4861 §4.5
源必须是发送接口 LLA。目的是触发重定向的那台主机。Target 是更好的下一跳;若目的就在链上,Target 等于 Destination,主机以后直接把该目的当邻居。选项常带 Target LLA 和 Redirected Header(Type 4,截一段原包)。
| IPv4 ARP(RFC 826) | IPv6 NDP(RFC 4861) |
|---|---|
独立以太类型 0x0806,不走 IP | 走 IPv6 + ICMPv6(NH=58),类型 135 / 136 |
| Request 以太网广播 | NS 发到目标的 solicited-node 组播 |
| Reply 通常单播 | NA 单播(S=1);DAD 冲突则 NA 到 ff02::1 |
| Who-has TPA? Tell SPA | Target Address + 源 IPv6 + Source LLA 选项 |
| Sender HA 在 ARP 固定头 | MAC 在 ICMPv6 选项里,不在固定头 |
| Gratuitous ARP | 非请求 NA(S=0;O 依用途 / 规范可 0 或 1)。经典通告目的 ff02::1;RFC 9131 GNA 对 preferred address SHOULD O=0、目的 SHOULD ff02::2 |
| ARP cache | Neighbor Cache(INCOMPLETE / REACHABLE / STALE / DELAY / PROBE) |
| 无路由器发现 | 另有 RS / RA;默认路由来自 RA 的 Router Lifetime |
| 无 DAD | DAD 复用 NS / NA,源地址为 :: |
RFC 4862 §5.4:任何单播地址——手工、SLAAC、DHCPv6——赋给接口之前都必须做重复地址检测,除非管理员关了该接口的 DAD。anycast 地址 MUST NOT 做 DAD(任播本就不唯一)。过程:
先加入该地址的 solicited-node 组,才能听到别人的冲突声明。
源 ::,目的为试探地址的 SNMA,Target = 试探地址,不带 Source LLA。默认 DupAddrDetectTransmits = 1,间隔为 RA / 协议常量里的 RetransTimer(缺省 1000 ms)。
收到针对同一 Target 的 NA,或收到另一台机器发来、Target 相同的 NS:冲突——须排除本机组播回环(自己发出的 DAD NS 再收进来不算,RFC 4862 §5.4.3)。失败处置(§5.4.5):仅当重复的是 link-local、且 IID 源自本应唯一的硬件地址时,才停用该接口的 IPv6;其它情况放弃这个地址再试即可。
超时未闻冲突,地址离开 Tentative,变为 Preferred(或按寿命进入 Deprecated)。
Optimistic DAD(RFC 4429)允许在探测未完成时用该地址做外出连接,本页按 4862 基线讲。
主机 A(fe80::a,MAC 02:00:00:00:00:0a)解析主机 B 的 2001:db8::b。B 的 SNMA 是 ff02::1:ff00:b。
ff:ff:ff:ff:ff:ff。解析走 33:33:ff:…,RA / 经典非请求 NA 走全节点组播 MAC 33:33:00:00:00:01;RFC 9131 GNA 目的 SHOULD 是全路由器 ff02::2(MAC 33:33:00:00:00:02)。O 位依用途 / 规范,不必恒为 1。主机先有链路本地,再听 RA。RA 的 M/O 是信息可用性指示,典型主机策略据此决定要不要找 DHCPv6,但不是强制开关——RFC 8415 §18 允许本地策略独立发起。每个前缀选项上的 A 位决定要不要用 SLAAC 拼地址。三套旋钮是正交的,不是“开了 DHCP 就没有 SLAAC”。
fe80::/64 + 本接口 IID。IID 如今多半是 RFC 7217,不再是 EUI-64。
通过后,接口才有可用的链路本地,才能把 LLA 当源去发 RS。
不必串行死等:4862 允许 LLA 的 DAD 和等 RA 并行。路由器对 RS 可以随机延迟至多 0.5 秒(MAX_RA_DELAY_TIME,RFC 4861 §6.2.6),避免一齐应答。
A=1 且前缀长度 + IID 长度 = 128(通常是 /64 + 64)才形成全球 / ULA 地址,再对该地址做 DAD。A=0 只可能更新“在链上”信息(还要看 L),不拼地址。
RA 源 LLA 在 Router Lifetime ≠ 0 时成为默认路由器。Hop Limit、Reachable Time、Retrans Timer、MTU 选项按 4861 §6.3.4 更新。
见下表。M/O 是可用性指示,不是强制开关(RFC 8415 §18 允许本地策略独立发起)。DNS 也可以只靠 RA 里的 RDNSS(RFC 8106),不必为此开 DHCPv6。
Preferred Lifetime 到期 → Deprecated:已有连接可继续用,新连接不应再选它当源。Valid Lifetime 到期 → Invalid:从接口上拿掉。Valid 全 1 表示无穷。这是站点重编号的挂钩。
| M | O | A | 主机行为 |
|---|---|---|---|
| 0 | 0 | 1 | 典型:纯 SLAAC。DNS 若需要,看 RA 的 RDNSS,不发起 DHCPv6。 |
| 0 | 1 | 1 | 典型:SLAAC 配地址;无状态 DHCPv6(Information-Request)拿 DNS 等。 |
| 0 | 1 | 0 | 该 PIO 不做 SLAAC;可用无状态 DHCPv6 取其他信息(DNS 等)。 |
| 1 | × | 0 | 典型:有状态 DHCPv6 配地址(IA_NA 等)。O 可忽略。 |
| 1 | × | 1 | 典型:SLAAC 和有状态 DHCPv6 都可以配地址,两套可同时在接口上。 |
| 0 | 0 | 0 | 不自动配全球地址;只剩 LLA(再加手工)。本地策略仍可发起 DHCPv6。 |
M:addresses are available via DHCPv6。O:other configuration information is available via DHCPv6。If the M flag is set, the O flag is redundant and can be ignored。If neither M nor O flags are set, this indicates that no information is available via DHCPv6。
这是可用性指示,不是强制开关。RFC 8415 §18 允许主机按本地策略独立发起 DHCPv6,不必等 M/O。A 位按每个前缀独立。一条 RA 可以同时带 2001:db8:1::/64 A=1 和 2001:db8:2::/64 A=0。
DHCPv6 现行文本是 RFC 8415(吸收了 3315)。UDP:客户端 546,服务器 / 中继 547。链路上的服务器组播 ff02::1:2。
IPv4 的“DHCP 失败就 APIPA(169.254/16)”在 v6 不成立:LLA 是每个接口的必选项,不是兜底失败态。
dhcp 标记的地址:M=1 且 A=1,不是配置错误。ICMPv6 的 Next Header 是 58,不是 IPv4 的 Protocol 1。它是 IPv6 的一部分:每个节点必须实现 RFC 4443 的基线。NDP、MLD 都挂在这张类型表上,但定义在别的 RFC。
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Code | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Message Body |
RFC 4443 §2.1
Type 最高位为 0(0–127)是差错,为 1(128–255)是信息。校验和覆盖整条 ICMPv6 消息外加 IPv6 伪首部,伪首部里的 Next Header 固定写 58(RFC 4443 §2.3)。这是相对 ICMPv4 的明确变化。
| Type | 名字 | 关键 Code / 字段 |
|---|---|---|
| 1 | Destination Unreachable | 0 无路由 · 1 管理禁止 · 2 超出源地址范围 · 3 地址不可达 · 4 端口不可达 · 5 出入策略 · 6 拒绝路由 |
| 2 | Packet Too Big | Code 必须 0;紧接着 32 bit 下一跳出接口 MTU |
| 3 | Time Exceeded | 0 Hop Limit 在转发中耗尽 · 1 分片重组超时 |
| 4 | Parameter Problem | 0 首部字段错 · 1 无法识别的 Next Header · 2 无法识别的 IPv6 选项;指针指出出错八位组 |
| 128 / 129 | Echo Request / Reply | Identifier + Sequence,ping6 |
| 130–132 / 143 | MLD / MLDv2 | IPv6 侧的 IGMP 对等物 |
| 133–137 | NDP | 见上一节 |
RFC 8200 §5:每条链路 MTU 至少 1280;不能一次塞下 1280 的链路必须在 IPv6 之下自己做分片重组。中间路由器不得在 IPv6 层切开数据报。于是:
把 ICMPv6 一刀切掉,IPv6 会在“大于 1280 的路径”上静默失败:TCP 看起来能握手(小包),传输大段时卡住。至少放行 Type 2,以及 NDP 133–137、Echo 128/129。这是 IPv6 排障里最常见的自伤。
icmp 只会命中 IPv4。今天的默认答案是双栈。隧道(6to4、Teredo)大多已淘汰。IPv6-only 接入网靠 NAT64/DNS64;应用层靠 Happy Eyeballs 避免“AAAA 能解析、路径却是死的”。
同一接口同时有 IPv4 和 IPv6。DNS 既回 A 也回 AAAA。选哪套地址由 Happy Eyeballs 和目的地址选择(RFC 6724)决定,不是“有 AAAA 就只走 v6”。
给只有 IPv6 的主机访问只有 IPv4 的服务器(DNS64 见 RFC 6147,NAT64 见 RFC 6146):
递归解析器替客户端查 A。若没有 AAAA,就把 IPv4 地址嵌入一个 IPv6 前缀,合成 AAAA。熟知前缀是 RFC 6052 的 64:ff9b::/96:64:ff9b::c000:201 表示 192.0.2.1。
目的落在 NAT64 前缀上,路由把包送到 NAT64。
RFC 6146 是有状态的:IPv6 首部 ↔ IPv4 首部,传输层端口按需改写。回来的 v4 包再译回 v6。
NAT64 翻译的是协议,不是“把内网 v6 藏到一个公网 v6 后面”。IPv6 侧通常仍是全球地址。纯 IPv6 目的(真正的 AAAA)不经过 NAT64。移动网常见的 464XLAT(RFC 6877)是在主机上再加一层 CLAT,给那些写死 IPv4 字面量的应用用。
偏好 IPv6,但不为它空等。
“v6 优先”不是“AAAA 解析失败才试 A”,更不是“SYN 发给 v6 之后空等三次超时”。抓包里常见:一条 AAAA、一条 A,两条 SYN 前后相差约 250 ms,先回来的那条留下。
64:ff9b::/96 通常表示地址合成,须结合 DNS 应答确认(是 DNS64 填的 AAAA,还是应用自己拼的);确认后再把它当 NAT64 路径,而不是原生双栈。2002::/16)和 Teredo(2001:0::/32)今天应视为遗物,新部署不要再开。先看本机地址和默认路由,再看邻居缓存,最后抓 NDP / PTB。IPv6 坏了却“能 ping 通网关 LLA”,多半是 RA 没来或 ICMPv6 被滤。
| 目的 | macOS / BSD | Linux |
|---|---|---|
| 地址与标志 | ifconfig en0ifconfig -a inet6 | ip -6 addr |
| ping | ping6 2001:db8::1ping6 fe80::1%en0 | ping -6 2001:db8::1部分发行版保留兼容命令 ping6 |
| 邻居缓存 | ndp -an | ip -6 neigh |
| 默认路由器 / 前缀 | ndp -r · ndp -p | 看 ip -6 route 与 RA 守护进程日志 |
| 路由表 | netstat -rnf inet6route -n get -inet6 default | ip -6 routeip -6 route show default |
| 组播组成员 | netstat -g | ip -6 maddr |
| traceroute | traceroute6 | traceroute -6 / tracepath -6 / tracepath6 |
| 主动要 RA | (内核自动发 RS) | rdisc6 eth0(ndisc6 包) |
| 状态 | 含义 |
|---|---|
| INCOMPLETE | 已发 NS,还没等到 NA(解析中) |
| REACHABLE | 近期得到正向确认(S=1 的 NA 或上层提示) |
| STALE | Reachable Time 到期,下次发包前先用缓存,再进入 DELAY |
| DELAY | 等上层确认;超时则 PROBE |
| PROBE | 单播 NS 做 NUD |
Linux 的 FAILED 是实现层对“解析失败”的汇总,规范五态里没有这个词。长时间 INCOMPLETE / FAILED 盯网关:RA 里的路由器 LLA 和你 ping 的不是同一个,或二层隔离了组播。
| 过滤器 | 命中 |
|---|---|
ipv6 | 所有 IPv6 |
icmpv6 | Next Header 58 |
icmpv6.type==133 … 137 | RS / RA / NS / NA / Redirect |
icmpv6.type==128 || icmpv6.type==129 | ping6 |
icmpv6.type==2 | Packet Too Big |
icmpv6.type==3 | Time Exceeded |
dhcpv6 | UDP 546/547 |
ipv6.dst==ff02::1:ff00:0/104 | solicited-node |
eth.type==0x86dd | 以太网 IPv6 |
ip6[40] 假定 ICMPv6 紧跟 40 字节基本首部。中间插入 Hop-by-Hop 等扩展头时,这个写法会偏掉。Wireshark 显示过滤器没有这个问题,优先用 icmpv6.type。
ipv6.plen。fe80::/64 用。指定具体地址必须带 zone id(%en0);zone id 不上线。ff02::1:ff00:0/104。不是低 32 bit。以太网目的是 33:33:ff:xx:xx:xx,不是广播。ff02::1,S 位为 0。fec0::/10 站点本地已废弃。:: 是未指定,::1 是环回。