0

I packed a struct using this line

# type(8) code(8) checksum(16) process id(16) sequence(16)
packet = struct.pack("bbHHh", ICMP_ECHO_REQUEST, 0, packet_checksum, pid, sequence)

And now im using a checksum calculation function which unpacks the packet in a way that the 16 bits of where the checksum should be (packet_checksum) is removed. But i don't know how it does that, and what does the sum function actually do? add up the different elements?:

n = len(pkt)
two_bytes = struct.unpack("%sH" % (n/2), pkt)
chksum = sum(two_bytes)

the code works well i'm just wondering how it works.

J. Daniel
  • 373
  • 3
  • 18
  • Have you read the [relevant](https://docs.python.org/3/library/struct.html?module-struct#struct.unpack) [documentation](https://docs.python.org/3/library/functions.html?sum#sum) ? – PM 2Ring Sep 03 '15 at 12:01
  • I'm puzzled at the use of `n = len(pkt); ..."%sH" % (n/2)` because, well, H is 2 bytes, so the length in bytes is taken, then divided by 2, then multiplied by the length of H, which is 2 again... `n = (n/2) * 2` So this part seems pointless. – zxq9 Sep 03 '15 at 12:24

1 Answers1

0

You seem to be trying to create an ICMP packet and to then calculate the checksum for it. For this you should carry out your initial pack with 0 for the checksum rather than trying to remove it. You could then extract each WORD as follows:

for x in xrange(0, len(packet), 2):
    print struct.unpack("H", packet[x:x+2])[0]

This assumes your packet is an even number of bytes, so if the length is odd, you could possibly temporarily append an extra 0 for the calculation.

Note, the ICMP checksum is not a simple case of adding these together, it requires a one-compliment sum. See the following answer for further information.

Community
  • 1
  • 1
Martin Evans
  • 45,791
  • 17
  • 81
  • 97