Friday, September 21, 2007

C# TCP Checksum

Recently I have been developing some code that needed to calculate the checksum for a TCP packet before transmission.

The TCP checksum is the 16 bit one's complement of the one's complement sum of all 16 bit words in the TCP header and text. A 96 bit pseudo header is also taken into account when calculating the checksum. This pseudo header is constructed from the IP src address, dst address, protocol and TCP header length. For the purposes of calculating the checksum, the checksum word in the TCP buffer is set to 0's.

There seems to be very little information in regarding this floating about, and certainly no C# examples; so here is the working code, should you need it:

// Calculates the TCP checksum using the IP Header and TCP Header.
// Ensure the TCPHeader contains an even number of bytes before passing to this method.
// If an odd number, pad with a 0 byte just for checksumming purposes.
static ushort GetTCPChecksum(byte[] IPHeader, byte[] TCPHeader)
{
uint sum = 0;
// TCP Header
for (int x = 0; x < TCPHeader.Length; x += 2)
{
sum += ntoh(BitConverter.ToUInt16(TCPHeader, x));
}
// Pseudo header - Source Address
sum += ntoh(BitConverter.ToUInt16(IPHeader, 12));
sum += ntoh(BitConverter.ToUInt16(IPHeader, 14));
// Pseudo header - Dest Address
sum += ntoh(BitConverter.ToUInt16(IPHeader, 16));
sum += ntoh(BitConverter.ToUInt16(IPHeader, 18));
// Pseudo header - Protocol
sum += ntoh(BitConverter.ToUInt16(new byte[] { 0, IPHeader[9] }, 0));
// Pseudo header - TCP Header length
sum += (UInt16)TCPHeader.Length;
// 16 bit 1's compliment
while ((sum >> 16) != 0) { sum = ((sum & 0xFFFF) + (sum >> 16)); }
sum = ~sum;
return (ushort)ntoh((UInt16)sum);
}

private static ushort ntoh(UInt16 In)
{
int x = IPAddress.NetworkToHostOrder(In);
return (ushort) (x >> 16);
}

3 comments:

Anonymous said...
This comment has been removed by a blog administrator.
Anonymous said...
This comment has been removed by a blog administrator.
Malweth said...

Thank you! I'm working on a class project that uses SharpPcap and need some way to make the checksums.

I'll let you know how it goes.