当前位置:  开发笔记 > 编程语言 > 正文

在python中计算IP校验和

如何解决《在python中计算IP校验和》经验,为你挑选了2个好方法。

我需要计算IP数据包的校验和,如http://www.faqs.org/rfcs/rfc1071.html中所述.

我已经有以下代码:

#!/usr/bin/python
import struct

data = "45 00 00 47 73 88 40 00 40 06 a2 c4 83 9f 0e 85 83 9f 0e a1"

# a test for the checksum calculation

def _checksum(data):
    #calculate the header sum
    ip_header_sum = sum(struct.unpack_from("6H", data))
    #add the carry
    ip_header_sum = (ip_header_sum & 0xFFFF) + (ip_header_sum >> 16 & 0xFFFF)
    #invert the sum, python does not support inversion (~a is -a + 1) so we have to do
    #little trick: ~a is the same as 0xFFFF & ~a
    ip_header_sum = ~ip_header_sum & 0xFFFF

    return ip_header_sum #should return 0 if correct

data = data.split()
data = map(lambda x: int(x,16), data)
data = struct.pack("%dB" % len(data), *data)

print " ".join(map(lambda x: "0x%02x" % ord(x), data))
print "Checksum: 0x%04x" % _checksum(data)

它适用于我使用wireshark捕获的包,它应具有正确的校验和,因此应评估为0

不幸的是结果是0x6524.有趣的是,对于每个正确的数据包,结果总是为0x6524 ...

谁发现错误?

编辑使错误更清晰 *第二次编辑*



1> 小智..:

您可以直接使用校验和udp计算python中的解决方案,这会导致预期的校验和值为零.

import struct

data = "45 00 00 47 73 88 40 00 40 06 a2 c4 83 9f 0e 85 83 9f 0e a1"

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

data = data.split()
data = map(lambda x: int(x,16), data)
data = struct.pack("%dB" % len(data), *data)

print ' '.join('%02X' % ord(x) for x in data)
print "Checksum: 0x%04x" % checksum(data)

结果:

45 00 00 47 73 88 40 00 40 06 A2 C4 83 9F 0E 85 83 9F 0E A1
Checksum: 0x0000



2> nickm..:

你这里有两个问题.

首先,您的调用struct.unpack_from仅从缓冲区中解压缩4个16位值(即8个字节).如果你想解开整个头,你需要做这样的事情struct.unpack_from("!nH"),在这里n是要解开短裤的数量.您可以生成相应的格式字符串struct.unpack_from("!%dH"%(len(data)/2), data),假设data除了IP标头之外什么都不包含.

其次,一旦你这样做,你会发现校验和现在可以达到0.这是已经设置了校验和的数据包的正确结果,就像这个一样.(您突出显示了上面数据包中的字节A2C4字节.)要从头开始计算数据包的正确校验和,您需要将校验和字节设置为0.(请参阅RFC1071中步骤2的开头:"要生成校验和,校验和字段本身被清除".)


*你突出显示上面数据包中的ac和c4字节* - 我不认为Simon故意突出显示示例数据包的任何字节,StackOverflow引擎确实如此,认为它是一些代码
推荐阅读
Life一切安好
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有