Monday, August 3, 2015

Calculating the TCP Checksum, with a taste of scapy + Wireshark

In this post we will calculate the TCP checksum. To calculate the TCP checksum we first must understand that in addition to its own header, TCP checksum uses a pseudo header. This pseudo header consists of the original source IP, destination IP, reserved (identified as 0000 0000), protocol (x06) and the length from the TCP header.

TCP pseudo header: reprinted with permission from

TCP Header: reprinted with permission from

Considering the above, let us craft a TCP Packet in scapy. We have the following
Source IP =
Destination =
TCP source port = 20
TCP destination port = 10
Data (2 bytes) = “Hi”

Let’s see what the receiving host got from a wireshark perspective

Note from the above image wireshark has already computed the TCP checksum for us. Now let’s try to see if we can get the same value as wireshark.

So from the information we have, we can go ahead and build out pseudo header. Also when adding, these values needs to be added 16 bits or 2 bytes at a time.

That’s it our TCP Checksum is 0XC5C1 which matches what wireshark provided us above.
Hope this helps someone who wanted to know how to calculate the TCP Checksum


  1. Very nice! However there seems to be a typo there....
    If "Padding/Length" is "0/10", the HEX value cannot be 0x0016.
    I tried checksum calculation with 0x0016 and it gave 0xC5C1 as result.
    Therefore "Padding/Length" should be "22", which is the right value (20 bytes TCP header + 2 bytes data).

    1. Amirm,
      You are spot on! Thanks for catching this. This was a typo on my part. If you notice, I have the correct binary values for "Padding/Length" as in "0000 0000 0001 0110". This value is indeed decimal "22" and Hex "0x0016", which represents the TCP header of 20 bytes and the data "HI" which is 2 bytes for the total of 22.

      For the next reader of this post, I'm unable to change the value above as this is an image. However, the decimal for "Padding/Length" should be "0/22" and not "0/10" as I have it above.

      Once again, thanks Amirm, for catching this.

      More importantly, thanks for reading!