diff --git a/include/utils.h b/include/utils.h index d3895d56..6f072f62 100644 --- a/include/utils.h +++ b/include/utils.h @@ -54,7 +54,40 @@ typedef struct __u32 data[64]; } inet_prefix; -#define PREFIXLEN_SPECIFIED 1 +enum { + PREFIXLEN_SPECIFIED = (1 << 0), + ADDRTYPE_INET = (1 << 1), + ADDRTYPE_UNSPEC = (1 << 2), + ADDRTYPE_MULTI = (1 << 3), + + ADDRTYPE_INET_UNSPEC = ADDRTYPE_INET | ADDRTYPE_UNSPEC, + ADDRTYPE_INET_MULTI = ADDRTYPE_INET | ADDRTYPE_MULTI +}; + +static inline bool is_addrtype_inet(const inet_prefix *p) +{ + return p->flags & ADDRTYPE_INET; +} + +static inline bool is_addrtype_inet_unspec(const inet_prefix *p) +{ + return (p->flags & ADDRTYPE_INET_UNSPEC) == ADDRTYPE_INET_UNSPEC; +} + +static inline bool is_addrtype_inet_multi(const inet_prefix *p) +{ + return (p->flags & ADDRTYPE_INET_MULTI) == ADDRTYPE_INET_MULTI; +} + +static inline bool is_addrtype_inet_not_unspec(const inet_prefix *p) +{ + return (p->flags & ADDRTYPE_INET_UNSPEC) == ADDRTYPE_INET; +} + +static inline bool is_addrtype_inet_not_multi(const inet_prefix *p) +{ + return (p->flags & ADDRTYPE_INET_MULTI) == ADDRTYPE_INET; +} #define DN_MAXADDL 20 #ifndef AF_DECnet diff --git a/lib/utils.c b/lib/utils.c index 48c4bcb0..e66c1ff7 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -534,7 +534,7 @@ int get_addr64(__u64 *ap, const char *cp) return 1; } -int get_addr_1(inet_prefix *addr, const char *name, int family) +static int __get_addr_1(inet_prefix *addr, const char *name, int family) { memset(addr, 0, sizeof(*addr)); @@ -619,6 +619,36 @@ int get_addr_1(inet_prefix *addr, const char *name, int family) return 0; } +int get_addr_1(inet_prefix *addr, const char *name, int family) +{ + int ret; + + ret = __get_addr_1(addr, name, family); + if (ret) + return ret; + + switch (addr->family) { + case AF_INET: + if (!addr->data[0]) + addr->flags |= ADDRTYPE_INET_UNSPEC; + else if (IN_MULTICAST(ntohl(addr->data[0]))) + addr->flags |= ADDRTYPE_INET_MULTI; + else + addr->flags |= ADDRTYPE_INET; + break; + case AF_INET6: + if (IN6_IS_ADDR_UNSPECIFIED(addr->data)) + addr->flags |= ADDRTYPE_INET_UNSPEC; + else if (IN6_IS_ADDR_MULTICAST(addr->data)) + addr->flags |= ADDRTYPE_INET_MULTI; + else + addr->flags |= ADDRTYPE_INET; + break; + } + + return 0; +} + int af_bit_len(int af) { switch (af) {