我想问一下根据ICMPv6协议计算16位校验和的方案是否正确。我试图按照Wikipedia,但我不确定主要是关于两件事情。计算ICMPv6头的16位校验和
首先是什么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个八位字节,因为我在下面的代码中声明?
然后我有问题了解这一点(再次从维基)。
在此伪报头之后,校验和将继续,其中校验和初始设置为零的ICMPv6消息为 。该 校验和计算是根据互联网协议 标准使用16位的补求和,然后 补充校验本身和它插入校验 场
这是否意味着我要补充的整体执行ICMPv6帧与校验和字段上的0000是否也是校验和?
我试图在Python编写一个简单的程序进行这个:
# START OF Pseudo header
# we are doing 16 bit checksum hence quadruplets
## source IP
sip = ['FE80', '0000', '0000', '0000', '0202', 'B3FF', 'FE1E', '8329']
## destination IP
dip = ['FE80', '0000', '0000', '0000', '0202', 'B3FF', 'FE1E', '8330']
## next header - 32 bits, permanently set to (58)_dec ~ (88)_hex
nh = ['0000', '0088']
## packet length -> see my question above: (56)_dec ~ (38)_hex
lng = ['0038']
png = "8000 0000 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".split(" ")
# END OF PSEUDO HEADER
tot = sip + dip + lng + nh + png # from what the sum is going to be counted
stot = sum([int(x, 16) for x in tot]) % 65535 # we are in 16 bits world
rstot = 65535 - stot # wrap around
res = hex(rstot) # convert to hex
print(stot, rstot)
print(res)
check = bin(rstot + stot)
print(check) # all ones
即以下的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
所以我应该用e672
替换xxxx
。这是对的吗?当我尝试用wireshark计算这个时,我得到了一个不同的答案。
夫妇的注意事项:你的回答包的校验和一个32位的字段(“> I”),但它应该是一个16位字段([来源](https://开头的连接。 wikipedia.org/wiki/Internet_Control_Message_Protocol_version_6#Packet_format))导致长度为34个字节的ICMP数据包,而不是您用于校验和计算的32个数据包。它似乎也假定ICMP数据包的类型是135/NDP,但OP特别提到了128/Echo Request。如果我错了,请纠正我,我正在尝试将您的解决方案用于我自己的基于python的ping程序。 – ocket8888