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

校验和udp计算python

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

我想计算我想发送的UDP报头数据包的校验和:

packetosend = """60 00 00 00 00 24 3a 40 20 02 c0 a8 01 50 00 01 00 00 
00 00 00 00 09 38 20 02 c0 a8 01 50 00 01 00 00 00 00 00 00 09 6f"""

所以我需要加入这个utf-16(不是问题)并计算这个特定数据包的校验和.我怎样才能做到这一点?

谢谢!

编辑:是的它是ICMPv6数据包的IPv6标头,无论如何我想知道的是公式,以及它是如何工作的.

我将给出一个ICMP ping echo(v4)数据包的另一个例子:

packet = """
08 00 d1 15 76 0c 00 07 bf d3 55 4a ad b5 03 00   // "d1 15" is the packet checksum 
08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17
18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27
28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37"""

谢谢.



1> Jason Orendo..:

这对我来说看起来不像UDP包.它看起来像ICMPv6数据包的IPv6标头,但缺少数据包的实际有效负载.

IPv6标头不包含校验和.

对于ICMP,校验和是"从Type字段开始的ICMP消息的一个补码和的16位补码." 一个补码算法涉及进位的特殊处理.

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

为了计算正确的校验和,当然你必须从右边开始msg,这意味着首先至少将校验和字段清零,并且可能还需要添加"虚拟标题",具体取决于您使用的协议.



2> pfa..:

在Scapy中有一个可靠的校验和函数可以正确处理字节序问题(http://www.secdev.org/projects/scapy,GPLv2)。

在Python 2.7中,scapy的utils.py:

if struct.pack("H",1) == "\x00\x01": # big endian
    def checksum(pkt):
        if len(pkt) % 2 == 1:
            pkt += "\0"
        s = sum(array.array("H", pkt))
        s = (s >> 16) + (s & 0xffff)
        s += s >> 16
        s = ~s
        return s & 0xffff
else:
    def checksum(pkt):
        if len(pkt) % 2 == 1:
            pkt += "\0"
        s = sum(array.array("H", pkt))
        s = (s >> 16) + (s & 0xffff)
        s += s >> 16
        s = ~s
        return (((s>>8)&0xff)|s<<8) & 0xffff

这对于使用IP头校验和的任何协议(IP,TCP,UDP,ICMP)都是正确的。但是,UDP还具有特殊情况,即应将计算为0x0000的校验和作为0xffff传输。上面的函数不能解决这个问题,因此对于UDP,您将不得不处理这种特殊情况。

推荐阅读
依然-狠幸福
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有