diff --git a/src/nm-core-utils.c b/src/nm-core-utils.c index d39991bd27..ca880de50b 100644 --- a/src/nm-core-utils.c +++ b/src/nm-core-utils.c @@ -316,28 +316,28 @@ nm_utils_ip6_address_clear_host_address (struct in6_addr *dst, const struct in6_ return dst; } -gboolean -nm_utils_ip6_address_same_prefix (const struct in6_addr *addr_a, const struct in6_addr *addr_b, guint8 plen) +int +nm_utils_ip6_address_same_prefix_cmp (const struct in6_addr *addr_a, const struct in6_addr *addr_b, guint8 plen) { int nbytes; - guint8 t, m; + guint8 va, vb, m; if (plen >= 128) - return memcmp (addr_a, addr_b, sizeof (struct in6_addr)) == 0; + NM_CMP_DIRECT_MEMCMP (addr_a, addr_b, sizeof (struct in6_addr)); + else { + nbytes = plen / 8; + if (nbytes) + NM_CMP_DIRECT_MEMCMP (addr_a, addr_b, nbytes); - nbytes = plen / 8; - if (nbytes) { - if (memcmp (addr_a, addr_b, nbytes) != 0) - return FALSE; + plen = plen % 8; + if (plen != 0) { + m = ~((1 << (8 - plen)) - 1); + va = ((((const guint8 *) addr_a))[nbytes]) & m; + vb = ((((const guint8 *) addr_b))[nbytes]) & m; + NM_CMP_DIRECT (va, vb); + } } - - plen = plen % 8; - if (plen == 0) - return TRUE; - - m = ~((1 << (8 - plen)) - 1); - t = ((((const guint8 *) addr_a))[nbytes]) ^ ((((const guint8 *) addr_b))[nbytes]); - return (t & m) == 0; + return 0; } /*****************************************************************************/ diff --git a/src/nm-core-utils.h b/src/nm-core-utils.h index 20df8d7e96..99d9e9c486 100644 --- a/src/nm-core-utils.h +++ b/src/nm-core-utils.h @@ -122,7 +122,26 @@ gboolean nm_ethernet_address_is_valid (gconstpointer addr, gssize len); gconstpointer nm_utils_ipx_address_clear_host_address (int family, gpointer dst, gconstpointer src, guint8 plen); in_addr_t nm_utils_ip4_address_clear_host_address (in_addr_t addr, guint8 plen); const struct in6_addr *nm_utils_ip6_address_clear_host_address (struct in6_addr *dst, const struct in6_addr *src, guint8 plen); -gboolean nm_utils_ip6_address_same_prefix (const struct in6_addr *addr_a, const struct in6_addr *addr_b, guint8 plen); +int nm_utils_ip6_address_same_prefix_cmp (const struct in6_addr *addr_a, const struct in6_addr *addr_b, guint8 plen); + +static inline gboolean +nm_utils_ip6_address_same_prefix (const struct in6_addr *addr_a, const struct in6_addr *addr_b, guint8 plen) +{ + return nm_utils_ip6_address_same_prefix_cmp (addr_a, addr_b, plen) == 0; +} + +#define NM_CMP_DIRECT_IN6ADDR_SAME_PREFIX(a, b, plen) \ + NM_CMP_RETURN (nm_utils_ip6_address_same_prefix_cmp ((a), (b), (plen))) + +#define NM_CMP_DIRECT_IN4ADDR_SAME_PREFIX(a, b, plen) \ + G_STMT_START { \ + const guint8 _plen = (plen); \ + const in_addr_t _aa = (a); \ + const in_addr_t _ab = (b); \ + \ + NM_CMP_DIRECT (htonl (nm_utils_ip4_address_clear_host_address (_aa, _plen)), \ + htonl (nm_utils_ip4_address_clear_host_address (_ab, _plen))); \ + } G_STMT_END double nm_utils_exp10 (gint16 e);