From: Alan T. DeKok Date: Tue, 6 May 2025 14:23:56 +0000 (-0400) Subject: add fr_sockaddr_cmp() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7626a881ca51f8ed04aba9c7dcc1e95beeb8953d;p=thirdparty%2Ffreeradius-server.git add fr_sockaddr_cmp() --- diff --git a/src/lib/util/inet.c b/src/lib/util/inet.c index 3c5b3e95dd0..a8df9fef9a1 100644 --- a/src/lib/util/inet.c +++ b/src/lib/util/inet.c @@ -29,6 +29,7 @@ #include #include #include +#include /* * 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; + } +} diff --git a/src/lib/util/inet.h b/src/lib/util/inet.h index 01d922415ad..ebe7cf7321f 100644 --- a/src/lib/util/inet.h +++ b/src/lib/util/inet.h @@ -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 */