Internet Checksum
You are given an in_cksum()
function. This checks the IP and TCP headers and makes sure the data transmitted safely (ie: the payload is validates, or just the header in IP's case).
The field is a uint16_t
. The sender filled this field and sent it to the destination. The receiver has to recreate this checksum and verify it with the checksum
field in the header.
IP Checksum
To do this, we have the following function:
/**
* @ip_header_length: Header length is in the ip_header struct you decode. 99% of the time it's 20, but you need to get this programmatically.
* Make sure this is 4 * the value actually in the header since this expects a number of words (not bytes).
* @ip_header: The pointer to where the ip_header info starts.
*/
int in_chksum(void* ip_header, ip_header_length);
You'll call this and store it somewhere, and check if it's 0 or not. If it's 0 then it's no error, and otherwise it is. Make sure you use 4 times the gotten length because we need to give it a number of words.
TCP Checksum
It works the same way in that you don't modify the checksum
field. However, you need to make a new buffer, move the header information into there, and do a few other things. It namely checks:
- The TCP header
- The TCP Payload
Overall just the TCP segment (see TCP, IP (and UDP) Protocol Suite for more info). It also checks the pseudo-header. It contains: - IP header info (not the whole header, just part of it)
- It does this since it doesn't trust IP.
- Contains:
- Source IP address
- Destination IP address
byte = 0
- Protocol = 6 (from IP header)
- 2-bytes of TCP segment length
In the new buffer you put:
- The pseudo-header from above
- TCP segment (with the TCP header)
Then you'll run the in_cksum
using this buffer's pointer, and you need to calculate the length (again, you need to pass in the length in words, so multiply by 4 here).
This guide also talks a lot about it.