我正在尝试在 C#中计算ICMPv6数据包的校验和。我按照here发布的建议,但似乎仍然存在细微差别。
这就是我计算校验和的方法:
//Note: Initial checksum in payload is set to 0x00, 0x00
//Add ip source bytes (16 bytes)
checksum += Utilities.BitConverterToUInt16(IpV6SourceBytes, 0);
checksum += Utilities.BitConverterToUInt16(IpV6SourceBytes, 2);
checksum += Utilities.BitConverterToUInt16(IpV6SourceBytes, 4);
checksum += Utilities.BitConverterToUInt16(IpV6SourceBytes, 6);
checksum += Utilities.BitConverterToUInt16(IpV6SourceBytes, 8);
checksum += Utilities.BitConverterToUInt16(IpV6SourceBytes, 10);
checksum += Utilities.BitConverterToUInt16(IpV6SourceBytes, 12);
checksum += Utilities.BitConverterToUInt16(IpV6SourceBytes, 14);
//Add ip destination bytes (16 bytes)
checksum += Utilities.BitConverterToUInt16(IpV6DestinationBytes, 0);
checksum += Utilities.BitConverterToUInt16(IpV6DestinationBytes, 2);
checksum += Utilities.BitConverterToUInt16(IpV6DestinationBytes, 4);
checksum += Utilities.BitConverterToUInt16(IpV6DestinationBytes, 6);
checksum += Utilities.BitConverterToUInt16(IpV6DestinationBytes, 8);
checksum += Utilities.BitConverterToUInt16(IpV6DestinationBytes, 10);
checksum += Utilities.BitConverterToUInt16(IpV6DestinationBytes, 12);
checksum += Utilities.BitConverterToUInt16(IpV6DestinationBytes, 14);
//Add length (2 bytes) - tested, value is correct (32 for {0x00, 0x20})
checksum += Utilities.BitConverterToUInt16(ip6.PayloadLength, 0);
//Add next-header (1 byte) - tested, value is correct (58)
checksum += (byte)ip6.NextProtocol;
//Add ICMPv6 message
for (int i = 0; i < buffer.Length; i +=2) {
checksum += Utilities.BitConverterToUInt16(buffer, i);
}
checksum += (ushort)(checksum >> 16);
checksum = (ushort)~checksum;
Console.WriteLine(checksum);
Checksum = BitConverter.GetBytes((UInt16)checksum).Reverse().ToArray();
Utilities.BitConverterToUint16 方法:
public static ushort BitConverterToUInt16(byte[] value, int startIndex) {
return BitConverter.ToUInt16(value.Reverse().ToArray(),
value.Length - sizeof(UInt16) - startIndex);
}
Wireshark的意见: 校验和:0x4201 [不正确,应为0x4209]
我错过了什么?
编辑:注意: Utilities.BitConverterToUInt16检索接下来的2个字节(16位)。我引用的帖子使用4个字节(32位)作为有效载荷长度,即使该字段长度为2个字节。我不知道为什么另一篇文章使用了4个字节,这就是为什么我很困惑。
Edit2:好的,我几乎到处搜索,无法识别问题。
这让我很生气。如果有人能指出我正确的方向,我会非常感激。我绝对不知道为什么校验和错了。再次感谢。
编辑3:不确定这是否有用但似乎校验和总是小8(即使我更改了IPv6标头中的所有值,例如IP地址)。