1 /* 2 * Checksum routine for Internet Protocol family headers (C Version) 3 * 4 * Licensed under GPLv2, see file LICENSE in this source tree. 5 */ 6 7 #include "libbb.h" 8 inet_cksum(const void * ptr,int nleft)9uint16_t FAST_FUNC inet_cksum(const void *ptr, int nleft) 10 { 11 const uint16_t *addr = ptr; 12 13 /* 14 * Our algorithm is simple, using a 32 bit accumulator, 15 * we add sequential 16 bit words to it, and at the end, fold 16 * back all the carry bits from the top 16 bits into the lower 17 * 16 bits. 18 */ 19 unsigned sum = 0; 20 while (nleft > 1) { 21 sum += *addr++; 22 nleft -= 2; 23 } 24 25 /* Mop up an odd byte, if necessary */ 26 if (nleft == 1) { 27 if (BB_LITTLE_ENDIAN) 28 sum += *(uint8_t*)addr; 29 else 30 sum += *(uint8_t*)addr << 8; 31 } 32 33 /* Add back carry outs from top 16 bits to low 16 bits */ 34 sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ 35 sum += (sum >> 16); /* add carry */ 36 37 return (uint16_t)~sum; 38 } 39