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?
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:
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."
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.