]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add fr_sockaddr_cmp()
authorAlan T. DeKok <aland@freeradius.org>
Tue, 6 May 2025 14:23:56 +0000 (10:23 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Tue, 6 May 2025 16:09:53 +0000 (12:09 -0400)
src/lib/util/inet.c
src/lib/util/inet.h

index 3c5b3e95dd0885d012d052a2613793be16abd100..a8df9fef9a17072ebf6c5a0d941f0e525db91ebe 100644 (file)
@@ -29,6 +29,7 @@
 #include <stdlib.h>
 #include <ifaddrs.h>
 #include <net/if_arp.h>
+#include <sys/un.h>
 
 /*
  *     Linux
@@ -1653,3 +1654,48 @@ int fr_interface_to_ethernet(char const *interface, fr_ethernet_t *ethernet)
        freeifaddrs(list);
        return ret;
 }
+
+
+int8_t fr_sockaddr_cmp(struct sockaddr_storage const *a, struct sockaddr_storage const *b)
+{
+       int8_t ret;
+
+       ret = CMP(a->ss_family, b->ss_family);
+       if (ret != 0) return 0;
+
+       switch (a->ss_family) {
+       case AF_INET:
+               ret = CMP(((struct sockaddr_in const *)a)->sin_port, ((struct sockaddr_in const *)b)->sin_port);
+               if (ret != 0) return ret;
+
+               ret = memcmp(&((struct sockaddr_in const *)a)->sin_addr,
+                            &((struct sockaddr_in const *)b)->sin_addr,
+                            sizeof(((struct sockaddr_in const *)a)->sin_addr));
+               return CMP(ret, 0);
+
+       case AF_INET6:
+               ret = CMP(((struct sockaddr_in6 const *)a)->sin6_port, ((struct sockaddr_in6 const *)b)->sin6_port);
+               if (ret != 0) return ret;
+
+               /*
+                *      @todo - flow info?
+                */
+
+               ret = CMP(((struct sockaddr_in6 const *)a)->sin6_scope_id, ((struct sockaddr_in6 const *)b)->sin6_scope_id);
+               if (ret != 0) return ret;
+
+               ret = memcmp(&((struct sockaddr_in6 const *)a)->sin6_addr,
+                            &((struct sockaddr_in6 const *)b)->sin6_addr,
+                            sizeof(((struct sockaddr_in6 const *)a)->sin6_addr));
+               return CMP(ret, 0);
+
+       case AF_LOCAL:
+               ret = strcmp(((struct sockaddr_un const *)a)->sun_path,
+                            ((struct sockaddr_un const *)b)->sun_path);
+               return CMP(ret, 0);
+
+       default:
+               fr_assert(0);
+               return 0;
+       }
+}
index 01d922415ad0b7d42f9cc1999bf95cc5e16c6056..ebe7cf7321f8331e1e754bd97382ae5777693214 100644 (file)
@@ -149,11 +149,14 @@ void      fr_ipaddr_get_scope_id(fr_ipaddr_t *ipaddr);
 int    fr_interface_to_ipaddr(char const *interface, fr_ipaddr_t *ipaddr, int af, bool link_local);
 
 int    fr_interface_to_ethernet(char const *interface, fr_ethernet_t *ethernet);
+
 /*
  *     Comparison
  */
 int8_t fr_ipaddr_cmp(fr_ipaddr_t const *a, fr_ipaddr_t const *b);
 
+int8_t fr_sockaddr_cmp(struct sockaddr_storage const *a, struct sockaddr_storage const *b);
+
 /*
  *     Sockaddr conversion functions
  */