From: Yu Watanabe Date: Mon, 24 Jul 2023 17:36:25 +0000 (+0900) Subject: in-addr-util: introduce in_addr_prefix_covers_full() and friends X-Git-Tag: v255-rc1~900^2~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=45e76094abd69f7ed36408282777a636bfd26598;p=thirdparty%2Fsystemd.git in-addr-util: introduce in_addr_prefix_covers_full() and friends --- diff --git a/src/basic/in-addr-util.c b/src/basic/in-addr-util.c index 30d90cce0d7..ee4ea67ac63 100644 --- a/src/basic/in-addr-util.c +++ b/src/basic/in-addr-util.c @@ -727,10 +727,11 @@ int in_addr_mask(int family, union in_addr_union *addr, unsigned char prefixlen) } } -int in4_addr_prefix_covers( +int in4_addr_prefix_covers_full( const struct in_addr *prefix, unsigned char prefixlen, - const struct in_addr *address) { + const struct in_addr *address, + unsigned char address_prefixlen) { struct in_addr masked_prefix, masked_address; int r; @@ -738,6 +739,9 @@ int in4_addr_prefix_covers( assert(prefix); assert(address); + if (prefixlen > address_prefixlen) + return false; + masked_prefix = *prefix; r = in4_addr_mask(&masked_prefix, prefixlen); if (r < 0) @@ -751,10 +755,11 @@ int in4_addr_prefix_covers( return in4_addr_equal(&masked_prefix, &masked_address); } -int in6_addr_prefix_covers( +int in6_addr_prefix_covers_full( const struct in6_addr *prefix, unsigned char prefixlen, - const struct in6_addr *address) { + const struct in6_addr *address, + unsigned char address_prefixlen) { struct in6_addr masked_prefix, masked_address; int r; @@ -762,6 +767,9 @@ int in6_addr_prefix_covers( assert(prefix); assert(address); + if (prefixlen > address_prefixlen) + return false; + masked_prefix = *prefix; r = in6_addr_mask(&masked_prefix, prefixlen); if (r < 0) @@ -775,20 +783,21 @@ int in6_addr_prefix_covers( return in6_addr_equal(&masked_prefix, &masked_address); } -int in_addr_prefix_covers( +int in_addr_prefix_covers_full( int family, const union in_addr_union *prefix, unsigned char prefixlen, - const union in_addr_union *address) { + const union in_addr_union *address, + unsigned char address_prefixlen) { assert(prefix); assert(address); switch (family) { case AF_INET: - return in4_addr_prefix_covers(&prefix->in, prefixlen, &address->in); + return in4_addr_prefix_covers_full(&prefix->in, prefixlen, &address->in, address_prefixlen); case AF_INET6: - return in6_addr_prefix_covers(&prefix->in6, prefixlen, &address->in6); + return in6_addr_prefix_covers_full(&prefix->in6, prefixlen, &address->in6, address_prefixlen); default: return -EAFNOSUPPORT; } diff --git a/src/basic/in-addr-util.h b/src/basic/in-addr-util.h index 200b9eb69df..95e73162b13 100644 --- a/src/basic/in-addr-util.h +++ b/src/basic/in-addr-util.h @@ -144,9 +144,18 @@ int in4_addr_default_subnet_mask(const struct in_addr *addr, struct in_addr *mas int in4_addr_mask(struct in_addr *addr, unsigned char prefixlen); int in6_addr_mask(struct in6_addr *addr, unsigned char prefixlen); int in_addr_mask(int family, union in_addr_union *addr, unsigned char prefixlen); -int in4_addr_prefix_covers(const struct in_addr *prefix, unsigned char prefixlen, const struct in_addr *address); -int in6_addr_prefix_covers(const struct in6_addr *prefix, unsigned char prefixlen, const struct in6_addr *address); -int in_addr_prefix_covers(int family, const union in_addr_union *prefix, unsigned char prefixlen, const union in_addr_union *address); +int in4_addr_prefix_covers_full(const struct in_addr *prefix, unsigned char prefixlen, const struct in_addr *address, unsigned char address_prefixlen); +int in6_addr_prefix_covers_full(const struct in6_addr *prefix, unsigned char prefixlen, const struct in6_addr *address, unsigned char address_prefixlen); +int in_addr_prefix_covers_full(int family, const union in_addr_union *prefix, unsigned char prefixlen, const union in_addr_union *address, unsigned char address_prefixlen); +static inline int in4_addr_prefix_covers(const struct in_addr *prefix, unsigned char prefixlen, const struct in_addr *address) { + return in4_addr_prefix_covers_full(prefix, prefixlen, address, 32); +} +static inline int in6_addr_prefix_covers(const struct in6_addr *prefix, unsigned char prefixlen, const struct in6_addr *address) { + return in6_addr_prefix_covers_full(prefix, prefixlen, address, 128); +} +static inline int in_addr_prefix_covers(int family, const union in_addr_union *prefix, unsigned char prefixlen, const union in_addr_union *address) { + return in_addr_prefix_covers_full(family, prefix, prefixlen, address, family == AF_INET ? 32 : family == AF_INET6 ? 128 : 0); +} int in_addr_parse_prefixlen(int family, const char *p, unsigned char *ret); int in_addr_prefix_from_string(const char *p, int family, union in_addr_union *ret_prefix, unsigned char *ret_prefixlen);