]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
fix various bugs in inet.c
authorAlan T. DeKok <aland@freeradius.org>
Sat, 14 Feb 2026 03:14:45 +0000 (22:14 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Sat, 14 Feb 2026 03:28:55 +0000 (22:28 -0500)
src/lib/util/inet.c

index a66a2982bfafe2f5045d7fc7242b6808699d5860..dea8fbabf7733b282fceb6f67b9abdddd9645b80 100644 (file)
@@ -96,9 +96,10 @@ int fr_ipaddr_is_multicast(fr_ipaddr_t const *ipaddr)
 {
        if (ipaddr->af == AF_INET) {
                /*
-                *      224.0.0.0 (3758096384) - 239.255.255.255 (4026531839)
+                *      224.0.0.0 - 239.255.255.255.
                 */
-               if ((ipaddr->addr.v4.s_addr >= 3758096384) && (ipaddr->addr.v4.s_addr <= 4026531839)) return 1;
+               if ((ipaddr->addr.v4.s_addr >= htonl((uint32_t) 0xe0000000)) &&
+                   (ipaddr->addr.v4.s_addr < htonl((uint32_t) 0xf0000000))) return 1;
 #ifdef HAVE_STRUCT_SOCKADDR_IN6
        } else if (ipaddr->af == AF_INET6) {
                /* Unconst for emscripten/musl */
@@ -238,8 +239,8 @@ void fr_ipaddr_mask(fr_ipaddr_t *addr, uint8_t prefix)
  * This function returns only one IP address, of the specified address family,
  * or the first address (of whatever family), if AF_UNSPEC is used.
  *
- * If fallback is specified and af is AF_INET, but not AF_INET records were
- * found and a record for AF_INET6 exists that record will be returned.
+ * If fallback is specified and af is AF_INET, but no AF_INET records were
+ * found and a record for AF_INET6 exists, then the IPv6 record will be returned.
  *
  * If fallback is specified and af is AF_INET6, and a record with AF_INET4 exists
  * that record will be returned inserted.
@@ -285,7 +286,7 @@ int fr_inet_hton(fr_ipaddr_t *out, int af, char const *hostname, bool fallback)
                        return -1;
                }
                out->af = af;
-               out->prefix = 32;
+               out->prefix = (af == AF_INET) ? 32 : 128;
                out->scope_id = 0;
 
                return 0;
@@ -693,7 +694,7 @@ int fr_inet_pton6(fr_ipaddr_t *out, char const *value, ssize_t inlen, bool resol
                if (!p || !*p) return 0;
 
                /*
-                *      Parse scope.
+                *      Parse scope ID.
                 */
                prefix = strtoul(p, &eptr, 10);
                if (prefix > UINT32_MAX) {
@@ -706,6 +707,8 @@ int fr_inet_pton6(fr_ipaddr_t *out, char const *value, ssize_t inlen, bool resol
                        return -1;
                }
 
+               out->scope_id = prefix;
+
                return 0;
        }
 
@@ -1449,7 +1452,7 @@ int fr_ipaddr_from_sockaddr(fr_ipaddr_t *ipaddr, uint16_t *port,
 
                if (salen < sizeof(s4)) {
                        fr_strerror_const("IPv4 address is too small");
-                       return 0;
+                       return -1;
                }
 
                memcpy(&s4, sa, sizeof(s4));
@@ -1465,7 +1468,7 @@ int fr_ipaddr_from_sockaddr(fr_ipaddr_t *ipaddr, uint16_t *port,
 
                if (salen < sizeof(s6)) {
                        fr_strerror_const("IPv6 address is too small");
-                       return 0;
+                       return -1;
                }
 
                memcpy(&s6, sa, sizeof(s6));
@@ -1661,7 +1664,7 @@ int8_t fr_sockaddr_cmp(struct sockaddr_storage const *a, struct sockaddr_storage
        int ret;
 
        ret = CMP(a->ss_family, b->ss_family);
-       if (ret != 0) return 0;
+       if (ret != 0) return ret;
 
        switch (a->ss_family) {
        case AF_INET: