in_cksum(addr, len) u_short *addr; int len; { register int nleft = len; register u_short *w = addr; register u_short answer; register int sum = 0; /* * Our algorithm is simple, using a 32 bit accumulator (sum), * we add sequential 16 bit words to it, and at the end, fold * back all the carry bits from the top 16 bits into the lower * 16 bits. */ while( nleft > 1 ) { sum += *w++; nleft -= 2; } /* mop up an odd byte, if necessary */ if( nleft == 1 ) { u_short u = 0; *(u_char *)(&u) = *(u_char *)w ; sum += u; } /* * add back carry outs from top 16 bits to low 16 bits */ sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ (将高位的数值加到低位)
sum += (sum >> 16); /* add carry */ (如果超过16位的最大的情况也加起来)
answer = ~sum; /* truncate to 16 bits */ (取反)
return (answer); }