ping中用到的校验和算法

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);
}
posted @ 2012-01-05 15:23  lxgeek  阅读(634)  评论(0编辑  收藏  举报