From: Alan T. DeKok Date: Sun, 10 May 2020 15:57:47 +0000 (-0400) Subject: add fr_ip6_pesudo_header_checksum() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8e0afda8fa066e463eaebf5f4d55b9e527dcb579;p=thirdparty%2Ffreeradius-server.git add fr_ip6_pesudo_header_checksum() --- diff --git a/src/lib/util/net.c b/src/lib/util/net.c index e7082ea1c3b..a1ad92effb5 100644 --- a/src/lib/util/net.c +++ b/src/lib/util/net.c @@ -162,3 +162,23 @@ uint16_t fr_ip_header_checksum(uint8_t const *data, uint8_t ihl) sum += (sum >> 16); return ((uint16_t) ~sum); } + +uint16_t fr_ip6_pesudo_header_checksum(struct in6_addr *src, struct in6_addr *dst, uint16_t ip_len, uint8_t ip_next) +{ + uint64_t sum = 0; + ip_pseudo_header6_t ip6; + uint16_t const *p = (uint16_t const *) &ip6; + int8_t nwords = sizeof(ip6) >> 1; /* number of 16-bit words */ + + memcpy(&ip6.ip_src, src, sizeof(ip6.ip_src)); + memcpy(&ip6.ip_dst, dst, sizeof(ip6.ip_dst)); + ip6.ip_len = ip_len; + ip6.ip_next = ip_next; + + for (sum = 0; nwords > 0; nwords--) { + sum += *p++; + } + sum = (sum >> 16) + (sum & 0xffff); + sum += (sum >> 16); + return ((uint16_t) ~sum); +} diff --git a/src/lib/util/net.h b/src/lib/util/net.h index cccd4ff37db..deca823f28d 100644 --- a/src/lib/util/net.h +++ b/src/lib/util/net.h @@ -125,6 +125,12 @@ typedef struct CC_HINT(__packed__) { struct in6_addr ip_src, ip_dst; //!< Src and Dst address } ip_header6_t; +typedef struct CC_HINT(__packed__) { + struct in6_addr ip_src, ip_dst; //!< Src and Dst address + uint32_t ip_len; //!< length + uint32_t ip_next; //!< upper 24 bits must be zero +} ip_pseudo_header6_t; + /* * UDP protocol header. * Per RFC 768, September, 1981. @@ -147,6 +153,7 @@ uint16_t fr_udp_checksum(uint8_t const *data, uint16_t len, uint16_t checksum, struct in_addr const src_addr, struct in_addr const dst_addr); int fr_udp_header_check(uint8_t const *data, uint16_t remaining, ip_header_t const *ip); uint16_t fr_ip_header_checksum(uint8_t const *data, uint8_t ihl); +uint16_t fr_ip6_pesudo_header_checksum(struct in6_addr *src, struct in6_addr *dst, uint16_t ip_len, uint8_t ip_next); /** Write out an unsigned 16bit integer in wire format (big endian) *