mywiki:linux:ip_checksum_apis
Differences
This shows you the differences between two versions of the page.
| Next revision | Previous revision | ||
| mywiki:linux:ip_checksum_apis [2015/05/08 09:32] – created super | mywiki:linux:ip_checksum_apis [2019/09/15 18:55] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 34: | Line 34: | ||
| } | } | ||
| </ | </ | ||
| + | |||
| + | |||
| + | ====== UDP Checksum calculation ====== | ||
| + | <file c udp_checksum.c> | ||
| + | /* set tcp checksum: given IP header and its IP payload, ie, UDP header and its payload */ | ||
| + | void compute_udp_checksum(struct iphdr *pIph, unsigned short *ipPayload) | ||
| + | { | ||
| + | register unsigned long sum = 0; | ||
| + | struct udphdr *udphdrp = (struct udphdr *)(ipPayload); | ||
| + | unsigned short udpLen = htons(udphdrp-> | ||
| + | //the source ip | ||
| + | sum += (pIph-> | ||
| + | sum += (pIph-> | ||
| + | //the dest ip | ||
| + | sum += (pIph-> | ||
| + | sum += (pIph-> | ||
| + | //protocol and reserved: 17 | ||
| + | sum += htons(IPPROTO_UDP); | ||
| + | //the length | ||
| + | sum += udphdrp-> | ||
| + | //add the IP payload | ||
| + | // | ||
| + | // | ||
| + | udphdrp-> | ||
| + | |||
| + | while (udpLen > 1) { | ||
| + | sum += * ipPayload++; | ||
| + | udpLen -= 2; | ||
| + | } | ||
| + | |||
| + | //if any bytes left, pad the bytes and add | ||
| + | if (udpLen > 0) { | ||
| + | // | ||
| + | sum += ((*ipPayload)& | ||
| + | } | ||
| + | |||
| + | while (sum >> 16) | ||
| + | sum = (sum & 0xffff) + (sum >> 16); | ||
| + | |||
| + | sum = ~sum; | ||
| + | //set computation result | ||
| + | udphdrp-> | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ====== TCP Checksum calculation ====== | ||
| + | <file c tcp_checksum.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-> | ||
| + | struct tcphdr *tcphdrp = (struct tcphdr *)(ipPayload); | ||
| + | //add the pseudo header | ||
| + | //the source ip | ||
| + | sum += (pIph-> | ||
| + | sum += (pIph-> | ||
| + | //the dest ip | ||
| + | sum += (pIph-> | ||
| + | sum += (pIph-> | ||
| + | //protocol and reserved: 6 | ||
| + | sum += htons(IPPROTO_TCP); | ||
| + | //the length | ||
| + | sum += htons(tcpLen); | ||
| + | //add the IP payload | ||
| + | // | ||
| + | tcphdrp-> | ||
| + | |||
| + | while (tcpLen > 1) { | ||
| + | sum += * ipPayload++; | ||
| + | tcpLen -= 2; | ||
| + | } | ||
| + | |||
| + | //if any bytes left, pad the bytes and add | ||
| + | if (tcpLen > 0) { | ||
| + | sum += ((*ipPayload)& | ||
| + | } | ||
| + | |||
| + | //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-> | ||
| + | } | ||
| + | </ | ||
| + | |||
mywiki/linux/ip_checksum_apis.1431048758.txt.gz · Last modified: (external edit)
