unsigned short /* this function generates header checksums */
csum (unsigned short *buf, int nwords)
{
unsigned long sum;
for (sum = 0; nwords > 0; nwords--) // add words(16bits) together
{
sum += *buf++;
}
sum = (sum >> 16) + (sum & 0xffff); //add carry over
sum += (sum >> 16); 开发者_JS百科 //MY question: what exactly does this step do??? add possible left-over
//byte? But hasn't it already been added in the loop (if
//any)?
return ((unsigned short) ~sum);
}
- I assume nwords in the number of 16bits word, not 8bits byte (if there are odd byte, nword is rounded to next large), is it correct? Say ip_hdr has 27 bytes totally, then nword will be 14 instead of 13, right?
- The line sum = (sum >> 16) + (sum & 0xffff) is to add carry over to make 16bit complement
- sum += (sum >> 16); What's the purpose of this step? Add left-over byte? But left-over byte has already been added in the loop?
Thanks!
You're correct. Step 3 condenses sum, a 32-bit long, into a 16-bit unsigned short, which is the length of the checksum. This is for performance purposes, allowing one to calculate the checksum without tracking overflow until the end. It does this both in step 2 and step 3 because it may have overflowed from step 2. Then it returns just the inverted lower 16 bits of sum.
This is a bit clearer: http://www.sysnet.ucsd.edu/~cfleizac/iptcphdr.html
精彩评论