Index: in_cksum.c =================================================================== RCS file: /cvs/src/usr.sbin/tcpdump/in_cksum.c,v retrieving revision 1.1 diff -u -p -r1.1 in_cksum.c --- in_cksum.c 20 Jun 2014 04:01:42 -0000 1.1 +++ in_cksum.c 6 Jul 2018 04:31:15 -0000 @@ -86,3 +86,40 @@ in_cksum_shouldbe(u_int16_t sum, u_int16 shouldbe = (shouldbe & 0xFFFF) + (shouldbe >> 16); return shouldbe; } + +uint32_t +in_cksum_add(const void *buf, size_t len, uint32_t sum) +{ + const uint16_t *words = buf; + + while (len > 1) { + sum += *words++; + len -= sizeof(*words); + } + + if (len == 1) { + uint8_t byte = *(const uint8_t *)words; + sum += htons(byte << 8); + } + + return (sum); +} + +uint16_t +in_cksum_fini(uint32_t sum) +{ + sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ + sum += (sum >> 16); /* add carry */ + + return (~sum); +} + +/* + * compute an IP header checksum. + * don't modifiy the packet. + */ +uint16_t +in_cksum(const void *addr, size_t len, uint32_t sum) +{ + return (in_cksum_fini(in_cksum_add(addr, len, sum))); +} Index: interface.h =================================================================== RCS file: /cvs/src/usr.sbin/tcpdump/interface.h,v retrieving revision 1.72 diff -u -p -r1.72 interface.h --- interface.h 10 Feb 2018 10:00:32 -0000 1.72 +++ interface.h 6 Jul 2018 04:31:15 -0000 @@ -295,5 +295,7 @@ extern void ospf6_print(const u_char *, extern void dhcp6_print(const u_char *, u_int, u_short, u_short); #endif /*INET6*/ -extern u_short in_cksum(const u_short *addr, int len, int csum); +extern uint32_t in_cksum_add(const void *, size_t, uint32_t); +extern uint16_t in_cksum_fini(uint32_t); +extern uint16_t in_cksum(const void *, size_t, uint32_t); extern u_int16_t in_cksum_shouldbe(u_int16_t, u_int16_t); Index: print-ip.c =================================================================== RCS file: /cvs/src/usr.sbin/tcpdump/print-ip.c,v retrieving revision 1.49 diff -u -p -r1.49 print-ip.c --- print-ip.c 10 Feb 2018 10:00:32 -0000 1.49 +++ print-ip.c 6 Jul 2018 04:31:15 -0000 @@ -312,40 +312,6 @@ trunc: } /* - * compute an IP header checksum. - * don't modifiy the packet. - */ -u_short -in_cksum(const u_short *addr, int len, int csum) -{ - int nleft = len; - const u_short *w = addr; - u_short answer; - int sum = csum; - - /* - * 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; - } - if (nleft == 1) - sum += htons(*(u_char *)w<<8); - - /* - * 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); -} - -/* * print an IP datagram. */ void