1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| unsigned short inet_checksum(unsigned short *pkt, int n)
{
register long sum;
unsigned short oddbyte;
register unsigned short answer;
/*
* 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.
*/
sum = 0;
while (n>1)
{
sum += *pkt++;
n -= 2;
}
/* mop up an odd byte, if necessary */
if (n == 1)
{
oddbyte = 0; /* make sure top half is zero */
*((unsigned char *)&oddbyte) = *(unsigned char *)pkt;/* one byte only */
sum+=oddbyte;
}
/*
* Add back carry outs from top 16 bits to low 16 bits.
*/
sum=(sum>>16)+(sum & 0xffff); /* add high-16 to low-16 */
sum+=(sum >> 16); /* add carry */
answer = (unsigned short)~sum; /* ones-complement, then truncate to 16 bits */
return answer;
} |