2009-11-20 150 views
4

我想計算出我想要發送一個UDP報頭數據包的校驗: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回波(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

當你看着'hashlib'的文檔時,你看到了什麼? – 2009-11-20 11:11:08

回答

8

這看起來不像一個UDP數據包給我。它看起來像ICMPv6數據包的IPv6標頭,但數據包的實際有效負載丟失。

IPv6報頭do not contain a checksum

對於ICMP,校驗和是「以類型字段開始的ICMP消息的補碼總和的16位補碼」。 One's complement arithmetic涉及進位的特殊處理。

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,這意味着至少第一歸零校驗和字段,並且還可能需要加入「虛擬頭」,取決於協議你正在使用。

+1

我想知道如何將函數校驗和中的w線改爲這個 w =(ord(msg [i])<< 8)+(ord(msg [i + 1])) – 2012-10-01 11:34:55

+0

@Jason,輸入什麼類型是您的函數校驗和所必需的? – 2014-04-03 16:44:16

+0

請注意,該校驗和函數假定輸入「msg」參數的長度爲偶數。奇數長度輸入發生異常。這種慣用的解決方案是在校驗和計算過程中使用填充字節,而不是作爲數據包的一部分進行傳輸。 (例如,在校驗和函數中,檢查msg是否是奇數長度,如果是,則將msg重新分配給:msg + =「\ x00」。) – pfa 2014-08-24 15:56:02

4

有一個穩固的校驗和功能,可以正確處理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你必須處理這個特殊情況。