Search code examples
tcpchecksum

Checking tcp checksum


I have the following packet (in hexadecimal):

45 00 00 2C
14 3C 40 00
80 06 63 39
C0 A8 01 02
C0 A8 01 04
11 EF 00 7C
4F BF BB FE
18 DF 7A 77
50 18 00 40
02 41 00 00
78 70 00 01

In which I have identified the IP header:

45 00 00 2C
14 3C 40 00
80 06 63 39
C0 A8 01 02
C0 A8 01 04

the TCP header:

11 EF 00 7C
4F BF BB FE
18 DF 7A 77
50 18 00 40
02 41 00 00

And the data

78 70 00 01

I'm trying to verify the checksum. For this, I sum up all the fields in the TCP header except the checksum field, which gives me 201D6

Then I sum up the data bytes, which adds to 7871

Then I add the computed TCP length (which is 24) the protocol, and the IP source and destination addresses; total: 18380

Adding the three last marked quantities its 3FDC7 And suming the most valued digit with the rest of the number is FDCA which turns into 0235 when computing its one complement. Nevertheless that is different from the checksum from the original packet.

Where did I mess up things?


Solution

  • There is two error in the computation:

    The first one is a simple one, you sum up 24 for the TCP length, but the length has to be in hexadecimal, so it's 0x0018.

    The second one is more tricky, the RFC 793 says:

    The checksum field is the 16 bit one's complement of the one's complement sum of all 16 bit words in the header and text.

    So it's not just a simple sum of a 16 bit words but a one's complement sum, this forum answer explains how it works:

    1. Add the 16-bit values up. Each time a carry-out (17th bit) is produced, swing that bit around and add it back into the LSb (one's digit). This is somewhat erroneously referred to as "one's complement addition."

    2. Once all the values are added in this manner, invert all the bits in the result. A binary value that has all the bits of another binary value inverted is called its "one's complement," or simply its "complement."

    Doing this you will find:

    • 0x01D8 for the TCP header without the checksum

    • 0x7871 for the data

    • 0x8375 for the pseudo-header

      • 0x0018 for the TCP length

      • 0xC0A0102 for the IP src

      • C0A80104 for the IP dst

      • 0x0006 for the protocol

    The 16 bit one's complement sum and the complement of all this gives 0x0241 which is the right result.