You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -4,7 +4,7 @@ Enjoy! All credits go to https://github.com/roman10.
This is a follow up of the previous post, how to calculate IP/TCP/UDP checksum part 1 — theory.
#IP Header Checksum Calculation Implementation
#IP Header Checksum Calculation Implementation
To calculate the IP checksum, one can use the code below,
```c
@@ -38,7 +38,7 @@ The method compute_ip_checksum initialize the checksum field of IP header to zer
Note that the data structure iphdr and tcphdr and udphdr are Linux data structures representing IP header, TCP header and UDP header respectively. You may want to Google for more information in order to understand the code.
#TCP Header Checksum Calculation Implementation
#TCP Header Checksum Calculation Implementation
To calculate the TCP checksum, you can use the code below,
The method sums the pseudo TCP header first, then the IP payload, which is the TCP segment. It also pads the last byte if there’re odd number of bytes. For detailed description of the algorithm, please refer to comments in the code and part 1.
#UDP Header Checksum Calculation Implementation
#UDP Header Checksum Calculation Implementation
To calculate the UDP checksum, one can follow the code below,
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Compute checksum for count bytes starting at addr, using one's complement of one's complement sum*/
static unsigned short compute_checksum(unsigned short *addr, unsigned int count) {
register unsigned long sum = 0;
while (count > 1) {
sum += * addr++;
count -= 2;
}
//if any bytes left, pad the bytes and add
if(count > 0) {
sum += ((*addr)&htons(0xFF00));
}
//Fold sum to 16 bits: add carrier to result
while (sum>>16) {
sum = (sum & 0xffff) + (sum >> 16);
}
//one's complement
sum = ~sum;
return ((unsigned short)sum);
}
```
The method compute_ip_checksum initialize the checksum field of IP header to zeros. Then calls a method compute_checksum. The mothod compute_checksum accepts the computation data and computation length as two input parameters. It sum up all 16-bit words, if there’s odd number of bytes, it adds a padding byte. After summing up all words, it folds the sum to 16 bits by adding the carrier to the results. At last, it takes the one’s complement of sum and cast it to 16-bit unsigned short type. You can refer to part 1 for more detailed description of the algorithm.
Note that the data structure iphdr and tcphdr and udphdr are Linux data structures representing IP header, TCP header and UDP header respectively. You may want to Google for more information in order to understand the code.
#TCP Header Checksum Calculation Implementation
To calculate the TCP checksum, you can use the code below,
```c
/* set tcp checksum: given IP header and tcp segment */
void compute_tcp_checksum(struct iphdr *pIph, unsigned short *ipPayload) {
register unsigned long sum = 0;
unsigned short tcpLen = ntohs(pIph->tot_len) - (pIph->ihl<<2);
//Fold 32-bit sum to 16 bits: add carrier to result
while (sum>>16) {
sum = (sum & 0xffff) + (sum >> 16);
}
sum = ~sum;
//set computation result
tcphdrp->check = (unsigned short)sum;
}
```
The method sums the pseudo TCP header first, then the IP payload, which is the TCP segment. It also pads the last byte if there’re odd number of bytes. For detailed description of the algorithm, please refer to comments in the code and part 1.
#UDP Header Checksum Calculation Implementation
To calculate the UDP checksum, one can follow the code below,
```c
/* set tcp checksum: given IP header and UDP datagram */
voidcompute_udp_checksum(struct iphdr *pIph, unsigned short *ipPayload) {
The code is similar to TCP checksum computation. Except that when the checksum is compted as all 0s, we set them to 1s. As 0x0000 is already reserved for indicating that the checksum is not computed. Also please refer to part 1 for detailed description of the algorithm.