Logo Search packages:      
Sourcecode: netdiag version File versions

csum.c

/*
 * $Id: csum.c,v 1.1 1997/08/12 16:37:50 begemot Exp begemot $
 * $Log: csum.c,v $
 * Revision 1.1  1997/08/12 16:37:50  begemot
 * Initial revision
 *
 * Revision 1.3  1995/02/26  19:21:02  begemot
 * Nothing important
 *
 * Revision 1.2  1995/02/26  18:59:25  begemot
 * Added RCS Id & Log entries into the all source files.
 *
 */

/*
 * in_cksum --
 *      Checksum routine for Internet Protocol family headers (C Version)
 */

/* in_cksum is from ping.c from netkit-base 0.10 by David A. Holland
 * Replaces non-portable code from the linux kernel asm headers
 * -- 1999-10-22 Robert Woodcock
 * also tweaked a bit for correctness -- 1999-10-24 David Huggins-Daines
 */

int in_cksum (unsigned char *addr, int len)
{
      int nleft = len;
      unsigned short *w = (unsigned short *) addr;
      int sum = 0;
      unsigned short answer = 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) {
            *(unsigned char *)(&answer) = *(unsigned char *)w ;
            sum += answer;
      }
      
      /* 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 */
      answer = ~sum;                          /* truncate to 16 bits */
      return(answer);
}
       
           

Generated by  Doxygen 1.6.0   Back to index