diff options
Diffstat (limited to 'lib/ipaddr.h')
| -rw-r--r-- | lib/ipaddr.h | 64 |
1 files changed, 55 insertions, 9 deletions
diff --git a/lib/ipaddr.h b/lib/ipaddr.h index cd7f79a04e..730c7ce130 100644 --- a/lib/ipaddr.h +++ b/lib/ipaddr.h @@ -25,6 +25,8 @@ #include <zebra.h> +#include "lib/log.h" + #ifdef __cplusplus extern "C" { #endif @@ -33,9 +35,9 @@ extern "C" { * Generic IP address - union of IPv4 and IPv6 address. */ enum ipaddr_type_t { - IPADDR_NONE = 0, - IPADDR_V4 = 1, /* IPv4 */ - IPADDR_V6 = 2, /* IPv6 */ + IPADDR_NONE = AF_UNSPEC, + IPADDR_V4 = AF_INET, + IPADDR_V6 = AF_INET6, }; struct ipaddr { @@ -59,6 +61,18 @@ struct ipaddr { #define IPADDRSZ(p) \ (IS_IPADDR_V4((p)) ? sizeof(struct in_addr) : sizeof(struct in6_addr)) +static inline int ipaddr_family(const struct ipaddr *ip) +{ + switch (ip->ipa_type) { + case IPADDR_V4: + return AF_INET; + case IPADDR_V6: + return AF_INET6; + default: + return AF_UNSPEC; + } +} + static inline int str2ipaddr(const char *str, struct ipaddr *ip) { int ret; @@ -84,15 +98,18 @@ static inline int str2ipaddr(const char *str, struct ipaddr *ip) static inline char *ipaddr2str(const struct ipaddr *ip, char *buf, int size) { buf[0] = '\0'; - if (ip) { - if (IS_IPADDR_V4(ip)) - inet_ntop(AF_INET, &ip->ip.addr, buf, size); - else if (IS_IPADDR_V6(ip)) - inet_ntop(AF_INET6, &ip->ip.addr, buf, size); - } + if (ip) + inet_ntop(ip->ipa_type, &ip->ip.addr, buf, size); return buf; } +#define IS_MAPPED_IPV6(A) \ + ((A)->s6_addr32[0] == 0x00000000 \ + ? ((A)->s6_addr32[1] == 0x00000000 \ + ? (ntohl((A)->s6_addr32[2]) == 0xFFFF ? 1 : 0) \ + : 0) \ + : 0) + /* * Convert IPv4 address to IPv4-mapped IPv6 address which is of the * form ::FFFF:<IPv4 address> (RFC 4291). This IPv6 address can then @@ -128,6 +145,35 @@ static inline bool ipaddr_isset(struct ipaddr *ip) return (0 != memcmp(&a, ip, sizeof(struct ipaddr))); } +/* + * generic ordering comparison between IP addresses + */ +static inline int ipaddr_cmp(const struct ipaddr *a, const struct ipaddr *b) +{ + uint32_t va, vb; + va = a->ipa_type; + vb = b->ipa_type; + if (va != vb) + return (va < vb) ? -1 : 1; + switch (a->ipa_type) { + case IPADDR_V4: + va = ntohl(a->ipaddr_v4.s_addr); + vb = ntohl(b->ipaddr_v4.s_addr); + if (va != vb) + return (va < vb) ? -1 : 1; + return 0; + case IPADDR_V6: + return memcmp((void *)&a->ipaddr_v6, (void *)&b->ipaddr_v6, + sizeof(a->ipaddr_v6)); + default: + return 0; + } +} + +#ifdef _FRR_ATTRIBUTE_PRINTFRR +#pragma FRR printfrr_ext "%pIA" (struct ipaddr *) +#endif + #ifdef __cplusplus } #endif |
