views:

390

answers:

1

Hi,

I'd like to calculate the checksum of an udp header packet I want to send :

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"""

so i need to join this utf-16 (not a problem) and calculate the checksum of this specific packet. How can i do that ?

Thanks !

EDIT: Yes it's an IPv6 header for an ICMPv6 packet, anyways what i would like to know is the formula, and how it works.

I'll give another example with an icmp ping echo (v4) packet:

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"""

Thanks.

A: 

This doesn't look like a UDP packet to me. It looks like an IPv6 header for an ICMPv6 packet, but the actual payload of the packet is missing.

IPv6 headers do not contain a checksum.

For ICMP, the checksum is "the 16-bit one's complement of the one's complement sum of the ICMP message starting with the Type field." One's complement arithmetic involves special treatment of the carry bit.

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

In order to calculate the right checksum, of course you have to start with the right msg, which means at least zeroing out the checksum field first and may also require adding "virtual headers", depending on the protocols you're using.

Jason Orendorff