inet_cksum.c 867 B

123456789101112131415161718192021222324252627282930313233343536
  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. #include "libbb.h"
  7. uint16_t FAST_FUNC inet_cksum(uint16_t *addr, int nleft)
  8. {
  9. /*
  10. * Our algorithm is simple, using a 32 bit accumulator,
  11. * we add sequential 16 bit words to it, and at the end, fold
  12. * back all the carry bits from the top 16 bits into the lower
  13. * 16 bits.
  14. */
  15. unsigned sum = 0;
  16. while (nleft > 1) {
  17. sum += *addr++;
  18. nleft -= 2;
  19. }
  20. /* Mop up an odd byte, if necessary */
  21. if (nleft == 1) {
  22. if (BB_LITTLE_ENDIAN)
  23. sum += *(uint8_t*)addr;
  24. else
  25. sum += *(uint8_t*)addr << 8;
  26. }
  27. /* Add back carry outs from top 16 bits to low 16 bits */
  28. sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
  29. sum += (sum >> 16); /* add carry */
  30. return (uint16_t)~sum;
  31. }