我想问一下我根据ICMPv6协议计算16位校验和的解决方案是否正确。我试着跟随Wikipedia,但主要有两件事我不确定。在
首先是the packet length
是什么意思-它是没有校验和的整个ICMPv6包的数据包长度,还是只有有效负载?它和IPv6一样是八位字节吗?这个ICMPv6回显请求的长度是多少?在
6000 # beginning of IPv6 packet
0000 0000 3a00 FE80 0000 0000 0000 0202
B3FF FE1E 8329 FE80 0000 0000 0000 0202
B3FF FE1E 8330
8000 xxxx # this is beginning of the ICMP packet - type and checksum
a088 0000 0001 # from here including this line I compute the length
0203 0405 0607 0809 0a0b 0c0d 0e0f 1011
1213 1415 1617 1819 1a1b 1c1d 1e1f 2021
2223 2425 2627 2829 2a2b 2c2d 2e2f 3031
3233
这是否意味着上面的长度是56个八位字节,正如我在下面的代码中所述?在
我很难理解这一点(同样来自wiki)。在
Following this pseudo header, the checksum is continued with the ICMPv6 message in which the checksum is initially set to zero. The checksum computation is performed according to Internet protocol standards using 16-bit ones' complement summation, followed by complementing the checksum itself and inserting it into the checksum field
这是否意味着我也应该将校验和字段上带有0000的整个ICMPv6帧添加到校验和中?在
我试图用Python编写一个简单的程序:
^{pr2}$对于以下ICMPv6 ping请求(具有IPv6标头):
d392 30fb 0001 d393 30fb 0001 86dd 6000
0000 0000 3a00 FE80 0000 0000 0000 0202
B3FF FE1E 8329 FE80 0000 0000 0000 0202
B3FF FE1E 8330 8000 xxxx a088 0000 0001
0203 0405 0607 0809 0a0b 0c0d 0e0f 1011
1213 1415 1617 1819 1a1b 1c1d 1e1f 2021
2223 2425 2627 2829 2a2b 2c2d 2e2f 3031
3233
它可以输出:
27741 37794
0xe672 # correct?
0b1111111111111111
所以我应该把xxxx
替换为e672
。对吗?当我试图用wireshark计算这个值时,我得到了不同的答案。在
我会用一个例子来回答你的问题。在
让我们从Wireshark wiki获取this sample capture,这样我们就有了相同的包,在Wireshark中打开它,让我们获取第一个ICMPv6包(第3帧)。在
请注意,对于这个包,至少有一点很重要:IPv6层的有效负载长度为32(0x20)。在
注意:要在Wireshark上将数据包提取为字符串,请选择数据包和所需的层(例如Ipv6),然后:
right click
>;copy
>;bytes
>;hex stream
构建伪标题
要计算校验和,首先要根据RFC 2460 section 8.1构建伪头。在
校验和是在伪报头和ICMPv6数据包上计算的。在
我们需要构建伪标题:
源IP和目标IP来自IPv6层。在
下一个标题字段固定为58:
上层包长度:
在我们的例子中,上层(ICMPv6)不携带长度字段,所以在这种情况下,我们必须使用IPv6层的有效负载长度字段,对于这个数据包,这个字段是32(0x20)。在
让我们尝试一些代码:
代码应该这样调用:
^{pr2}$构建ICMPV6数据包
正如rfc 4443 section 2.3中提到的,在任何计算之前,校验和字段必须设置为0。在
在本例中,我使用ICMPv6中的
type
和code
字段作为一个16位的单值。校验和字段被删除,数据包的剩余部分被简单地称为“remainment”:正在为校验和计算构建数据包的ICMPv6部分:
名称如下:
计算校验和
根据RFC 1701计算校验和。Python中的主要困难是将和包装成16位的数量。在
calc_checksum()
函数的输入是伪报头和数据包的ICMPv6部分的连接(校验和设置为0):Python示例:
代码示例
代码很难看,但返回了正确的校验和。在我们的示例中,此代码返回
0x68db
,根据wireshark的说法,这是正确的。在相关问题 更多 >
编程相关推荐