/* 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->len); //the source ip sum += (pIph->saddr >> 16) & 0xFFFF; sum += (pIph->saddr) & 0xFFFF; //the dest ip sum += (pIph->daddr >> 16) & 0xFFFF; sum += (pIph->daddr) & 0xFFFF; //protocol and reserved: 17 sum += htons(IPPROTO_UDP); //the length sum += udphdrp->len; //add the IP payload //printf("add ip payload\n"); //initialize checksum to 0 udphdrp->check = 0; while (udpLen > 1) { sum += * ipPayload++; udpLen -= 2; } //if any bytes left, pad the bytes and add if (udpLen > 0) { //printf("+++++++++++++++padding: %d\n", udpLen); sum += ((*ipPayload)&htons(0xFF00)); } while (sum >> 16) sum = (sum & 0xffff) + (sum >> 16); sum = ~sum; //set computation result udphdrp->check = ((unsigned short)sum == 0x0000) ? 0xFFFF : (unsigned short)sum; }