in_cksum.c 776 B

123456789101112131415161718192021222324252627282930313233
  1. #include "unp.h"
  2. uint16_t
  3. in_cksum(uint16_t *addr, int len)
  4. {
  5. int nleft = len;
  6. uint32_t sum = 0;
  7. uint16_t *w = addr;
  8. uint16_t answer = 0;
  9. /*
  10. * Our algorithm is simple, using a 32 bit accumulator (sum), we add
  11. * sequential 16 bit words to it, and at the end, fold back all the
  12. * carry bits from the top 16 bits into the lower 16 bits.
  13. */
  14. while (nleft > 1) {
  15. sum += *w++;
  16. nleft -= 2;
  17. }
  18. /* 4mop up an odd byte, if necessary */
  19. if (nleft == 1) {
  20. *(unsigned char *)(&answer) = *(unsigned char *)w ;
  21. sum += answer;
  22. }
  23. /* 4add back carry outs from top 16 bits to low 16 bits */
  24. sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
  25. sum += (sum >> 16); /* add carry */
  26. answer = ~sum; /* truncate to 16 bits */
  27. return(answer);
  28. }