在过去的几天里,我对ICMP协议充满热情,我找到了一个计算校验和的python函数:
def carry_around_add(a, b):
c = a + b
return (c & 0xffff) + (c >> 16)
def checksum(msg):
s = 0
for i in range(0, len(msg), 2):
w = ord(msg[i]) + (ord(msg[i+1]) << 8)
s = carry_around_add(s, w)
return ~s & 0xffff
print checksum("abcdefghijklmnopqrst")
在这张wireshark捕获图片中:
校验和为“0xcfcb
”但我的测试中的函数返回“55 245
- &gt; 0xd7cd
”。为什么?
非常感谢=)
答案 0 :(得分:3)
您的wireshark转储显示ICMP校验和,但是(wikipedia):
第三个和第四个字节是整个ICMP消息的校验和。
...
校验和 - 错误检查数据,根据ICMP标头和数据计算,值0替换为该字段。使用Internet Checksum,在RFC 1071中指定。
您在测试中对校验和例程的输入仅是ASCII有效负载部分。您必须提供整个ICMP输入。
例如:
def carry_around_add(a, b):
c = a + b
return (c & 0xffff) + (c >> 16)
def checksum(msg):
s = 0
for i in range(0, len(msg), 2):
w = ord(msg[i]) + (ord(msg[i+1]) << 8)
s = carry_around_add(s, w)
return ~s & 0xffff
payload_body = "abcdefghijklmnopqrst"
chk = checksum(payload_body)
print chk, '{:x}'.format(chk), '(host byte order)'
msg_type = '\x08' # ICMP Echo Request
msg_code = '\x00' # must be zero
msg_checksum_padding = '\x00\x00' # "...with value 0 substituted for this field..."
rest_header = '\x00\x01\x00\x01' # from pcap
entire_message = msg_type + msg_code + msg_checksum_padding + rest_header + payload_body
entire_chk = checksum(entire_message)
print entire_chk, '{:x}'.format(entire_chk), '(host byte order)'
当我在我的(小端)机器上运行时,我得到:
$ ./icmp_checksum_test.py
52695 cdd7 (host byte order)
52175 cbcf (host byte order)