含IPv6扩展头时ICMPv6校验和计算错误问题咨询
ICMPv6校验和含扩展头时错误的问题分析与修复
问题核心出在伪头部的Payload Length字段取值错误,以及你未正确定位ICMPv6报文的实际长度:
- 当IPv6不含扩展头时,IPv6基本头部的“载荷长度”恰好等于ICMPv6报文的长度,所以你的计算能得到正确结果;但当存在扩展头时,IPv6基本头部的“载荷长度”是所有扩展头 + ICMPv6报文的总长度,你直接用这个值填充伪头部的Payload Length,导致校验和计算的输入数据长度错误。
- ICMPv6校验和要求伪头部中的Payload Length必须是ICMPv6报文自身的长度(即Type、Code、校验和占位字段、载荷的总字节数),而非包含扩展头的总载荷长度。
具体修复步骤
- 遍历IPv6扩展头链,定位ICMPv6报文起始位置:
- 从IPv6基本头部的Next Header字段开始,依次解析每个扩展头:每个扩展头的第一个字节是Next Header(指向后续头部类型),第二个字节是扩展头长度(单位为8字节,不包含自身第一个8字节块)。
- 直到找到Next Header值为
0x3a(ICMPv6协议号)的扩展头,该扩展头之后的部分就是ICMPv6报文。
- 计算ICMPv6报文的实际长度:
- 用IPv6基本头部的载荷长度,减去所有扩展头的总长度,得到ICMPv6报文的长度;或者直接从ICMPv6起始位置到报文末尾计算字节数。
- 修正伪头部的Payload Length字段:
- 将计算得到的ICMPv6长度(
std::uint16_t类型)填充到std::uint32_t的低16位,高16位补0,再转换为网络字节序(大端序)后放入伪头部。
- 将计算得到的ICMPv6长度(
- 确保校验和计算前ICMPv6的校验和字段置0:
- 计算校验和时,必须先将ICMPv6报文中的校验和字段设为0,再将伪头部与ICMPv6报文拼接后计算校验和,最后将结果填入校验和字段。
内容的提问来源于stack exchange,提问作者Xigma
相关产品推荐
相关产品推荐

