]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add fr_ip6_pesudo_header_checksum()
authorAlan T. DeKok <aland@freeradius.org>
Sun, 10 May 2020 15:57:47 +0000 (11:57 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Sun, 10 May 2020 15:57:47 +0000 (11:57 -0400)
src/lib/util/net.c
src/lib/util/net.h

index e7082ea1c3b0c7103a708226d567846accb644a4..a1ad92effb5878f3f40dc1733e08de965cc8ca77 100644 (file)
@@ -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);
+}
index cccd4ff37dbb6b34fbd4800624ee3fe2a7f23ad6..deca823f28d9d76441b6832b0d4dfbcf05ffecce 100644 (file)
@@ -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)
  *