diff options
Diffstat (limited to 'lib/src/util/ip_address.c')
-rw-r--r-- | lib/src/util/ip_address.c | 284 |
1 files changed, 155 insertions, 129 deletions
diff --git a/lib/src/util/ip_address.c b/lib/src/util/ip_address.c index 49916547d..412baddcf 100644 --- a/lib/src/util/ip_address.c +++ b/lib/src/util/ip_address.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -20,44 +20,51 @@ #include <hicn/util/ip_address.h> #include <hicn/util/log.h> +#include <hicn/util/sstrncpy.h> #if __BYTE_ORDER == __LITTLE_ENDIAN #ifdef __ANDROID__ -#define SWAP(x) bswap_32(x) +#define SWAP(x) bswap_32 (x) #else -#define SWAP(x) __bswap_constant_32(x) +#define SWAP(x) __bswap_constant_32 (x) #endif #else #define SWAP(x) x #endif - /* No htonl() with const */ const ip_address_t IPV4_LOOPBACK = { - .v4.as_inaddr.s_addr = SWAP(INADDR_LOOPBACK), + .v4.as_inaddr.s_addr = SWAP (INADDR_LOOPBACK), }; -const ip_address_t IPV6_LOOPBACK ={ - .v6.as_in6addr = IN6ADDR_LOOPBACK_INIT, +const ip_address_t IPV6_LOOPBACK = { + .v6.as_in6addr = IN6ADDR_LOOPBACK_INIT, }; -const ip_address_t IPV4_ANY = { - .v4.as_inaddr.s_addr = INADDR_ANY, +const ip_address_t IPV4_ANY = { + .v4.as_inaddr.s_addr = INADDR_ANY, }; const ip_address_t IPV6_ANY = { - .v6.as_in6addr = IN6ADDR_ANY_INIT, + .v6.as_in6addr = IN6ADDR_ANY_INIT, }; -const ip_address_t IP_ADDRESS_EMPTY = { - .v6.as_u64 = { 0 }, +const ip4_address_t IP4_ADDRESS_EMPTY = { + .as_u32 = 0, +}; + +const ip6_address_t IP6_ADDRESS_EMPTY = { + .as_u64 = { 0, 0 }, }; +const ip_address_t IP_ADDRESS_EMPTY = { + .v6.as_u64 = { 0, 0 }, +}; /* IP address */ int -ip_address_get_family (const char * ip_address) +ip_address_get_family (const char *ip_address) { struct addrinfo hint, *res = NULL; int rc; @@ -81,24 +88,26 @@ int ip_address_len (int family) { return (family == AF_INET6) ? IPV6_ADDR_LEN : - (family == AF_INET) ? IPV4_ADDR_LEN : 0; + (family == AF_INET) ? IPV4_ADDR_LEN : + 0; } int -ip_address_ntop (const ip_address_t * ip_address, char *dst, const size_t len, - int family) +ip_address_ntop (const ip_address_t *ip_address, char *dst, const size_t len, + int family) { - const char * s; - switch(family) { + const char *s; + switch (family) + { case AF_INET: - s = inet_ntop (AF_INET, ip_address->v4.buffer, dst, (socklen_t)len); + s = inet_ntop (AF_INET, ip_address->v4.buffer, dst, (socklen_t) len); break; case AF_INET6: - s = inet_ntop (AF_INET6, ip_address->v6.buffer, dst, (socklen_t)len); + s = inet_ntop (AF_INET6, ip_address->v6.buffer, dst, (socklen_t) len); break; default: return -1; - } + } return (s ? 1 : -1); } @@ -106,14 +115,15 @@ ip_address_ntop (const ip_address_t * ip_address, char *dst, const size_t len, * Parse ip addresses in presentation format */ int -ip_address_pton (const char *ip_address_str, ip_address_t * ip_address) +ip_address_pton (const char *ip_address_str, ip_address_t *ip_address) { int pton_fd; int family; family = ip_address_get_family (ip_address_str); - switch (family) { + switch (family) + { case AF_INET: ip_address->pad[0] = 0; ip_address->pad[1] = 0; @@ -136,32 +146,34 @@ ip_address_pton (const char *ip_address_str, ip_address_t * ip_address) } int -ip_address_snprintf(char * s, size_t size, const ip_address_t * ip_address, int family) +ip_address_snprintf (char *s, size_t size, const ip_address_t *ip_address, + int family) { - const char * rc; - switch(family) { - case AF_INET: - if (size < INET_ADDRSTRLEN) - return -1; - rc = inet_ntop (AF_INET, ip_address->v4.buffer, s, INET_ADDRSTRLEN); - break; - case AF_INET6: - if (size < INET6_ADDRSTRLEN) - return -1; - rc = inet_ntop (AF_INET6, ip_address->v6.buffer, s, INET6_ADDRSTRLEN); - break; - default: - return -1; + const char *rc; + switch (family) + { + case AF_INET: + if (size < INET_ADDRSTRLEN) + return -1; + rc = inet_ntop (AF_INET, ip_address->v4.buffer, s, INET_ADDRSTRLEN); + break; + case AF_INET6: + if (size < INET6_ADDRSTRLEN) + return -1; + rc = inet_ntop (AF_INET6, ip_address->v6.buffer, s, INET6_ADDRSTRLEN); + break; + default: + return -1; } - if (!rc) - return -1; - return (int)strlen(s); + if (!rc) + return -1; + return (int) strnlen_s (s, MAXSZ_IP_ADDRESS); } int -ip_address_to_sockaddr(const ip_address_t * ip_address, - struct sockaddr *sa, int family) +ip_address_to_sockaddr (const ip_address_t *ip_address, struct sockaddr *sa, + int family) { struct sockaddr_in6 *tmp6 = (struct sockaddr_in6 *) sa; struct sockaddr_in *tmp4 = (struct sockaddr_in *) sa; @@ -187,33 +199,30 @@ ip_address_to_sockaddr(const ip_address_t * ip_address, } int -ip_address_cmp(const ip_address_t * ip1, const ip_address_t * ip2, int family) +ip_address_cmp (const ip_address_t *ip1, const ip_address_t *ip2, int family) { - switch(family) { - case AF_INET: - return memcmp(&ip1->v4, &ip2->v4, sizeof(ip1->v4)); - break; - case AF_INET6: - return memcmp(&ip1->v6, &ip2->v6, sizeof(ip1->v6)); - break; - default: - return memcmp(ip1, ip2, sizeof(ip_address_t)); + switch (family) + { + case AF_INET: + return memcmp (ip1->v4.buffer, ip2->v4.buffer, sizeof (ip1->v4)); + case AF_INET6: + default: + return memcmp (ip1->v6.buffer, ip2->v6.buffer, sizeof (ip1->v6)); } } int -ip_address_empty(const ip_address_t * ip) +ip_address_empty (const ip_address_t *ip) { - return (memcmp(ip, &IP_ADDRESS_EMPTY, sizeof(IP_ADDRESS_EMPTY)) == 0); + return (memcmp (ip->v6.buffer, &IP_ADDRESS_EMPTY.v6.buffer, + sizeof (IP_ADDRESS_EMPTY)) == 0); } - - /* Prefix */ /* Parse IP Prefixes in presentation format (in bits, separated by a slash) */ int -ip_prefix_pton (const char *ip_address_str, ip_prefix_t * ip_prefix) +ip_prefix_pton (const char *ip_address_str, ip_prefix_t *ip_prefix) { int pton_fd; char *p; @@ -221,29 +230,32 @@ ip_prefix_pton (const char *ip_address_str, ip_prefix_t * ip_prefix) char *addr = strdup (ip_address_str); p = strchr (addr, '/'); - if (!p) { - ip_prefix->len = ~0; // until we get the ip address family - } else { - ip_prefix->len = (u8)strtoul (p + 1, &eptr, 10); - *p = 0; - } + if (!p) + { + ip_prefix->len = ~0; // until we get the ip address family + } + else + { + ip_prefix->len = (u8) strtoul (p + 1, &eptr, 10); + *p = 0; + } ip_prefix->family = ip_address_get_family (addr); switch (ip_prefix->family) { case AF_INET6: - if (ip_prefix->len == (u8)~0) - ip_prefix->len = IPV6_ADDR_LEN_BITS; + if (ip_prefix->len == (u8) ~0) + ip_prefix->len = IPV6_ADDR_LEN_BITS; if (ip_prefix->len > IPV6_ADDR_LEN_BITS) - goto ERR; + goto ERR; pton_fd = inet_pton (AF_INET6, addr, &ip_prefix->address.v6.buffer); break; case AF_INET: - if (ip_prefix->len == (u8)~0) - ip_prefix->len = IPV4_ADDR_LEN_BITS; + if (ip_prefix->len == (u8) ~0) + ip_prefix->len = IPV4_ADDR_LEN_BITS; if (ip_prefix->len > IPV4_ADDR_LEN_BITS) - goto ERR; + goto ERR; pton_fd = inet_pton (AF_INET, addr, &ip_prefix->address.v4.buffer); break; default: @@ -253,9 +265,9 @@ ip_prefix_pton (const char *ip_address_str, ip_prefix_t * ip_prefix) // 0 = not in presentation format // < 0 = other error (use perror) if (pton_fd <= 0) - goto ERR; + goto ERR; - free(addr); + free (addr); return 1; ERR: free (addr); @@ -263,129 +275,143 @@ ERR: } int -ip_prefix_ntop_short(const ip_prefix_t * ip_prefix, char *dst, size_t size) +ip_prefix_ntop_short (const ip_prefix_t *ip_prefix, char *dst, size_t size) { char ip_s[MAXSZ_IP_ADDRESS]; - const char * s; - switch(ip_prefix->family) { + const char *s; + switch (ip_prefix->family) + { case AF_INET: - s = inet_ntop (AF_INET, ip_prefix->address.v4.buffer, ip_s, MAXSZ_IP_ADDRESS); + s = inet_ntop (AF_INET, ip_prefix->address.v4.buffer, ip_s, + MAXSZ_IP_ADDRESS); break; case AF_INET6: - s = inet_ntop (AF_INET6, ip_prefix->address.v6.buffer, ip_s, MAXSZ_IP_ADDRESS); + s = inet_ntop (AF_INET6, ip_prefix->address.v6.buffer, ip_s, + MAXSZ_IP_ADDRESS); break; default: return -1; - } + } if (!s) - return -1; - int rc = snprintf(dst, size, "%s", ip_s); + return -1; + int rc = snprintf (dst, size, "%s", ip_s); if (rc >= size) - return (int)size; + return (int) size; return rc; } int -ip_prefix_ntop(const ip_prefix_t * ip_prefix, char *dst, size_t size) +ip_prefix_ntop (const ip_prefix_t *ip_prefix, char *dst, size_t size) { char ip_s[MAXSZ_IP_ADDRESS]; - const char * s; - switch(ip_prefix->family) { + const char *s; + switch (ip_prefix->family) + { case AF_INET: - s = inet_ntop (AF_INET, ip_prefix->address.v4.buffer, ip_s, MAXSZ_IP_ADDRESS); + s = inet_ntop (AF_INET, ip_prefix->address.v4.buffer, ip_s, + MAXSZ_IP_ADDRESS); break; case AF_INET6: - s = inet_ntop (AF_INET6, ip_prefix->address.v6.buffer, ip_s, MAXSZ_IP_ADDRESS); + s = inet_ntop (AF_INET6, ip_prefix->address.v6.buffer, ip_s, + MAXSZ_IP_ADDRESS); break; default: return -1; - } + } if (!s) - return -1; - int rc = snprintf(dst, size, "%s/%d", ip_s, ip_prefix->len); + return -1; + int rc = snprintf (dst, size, "%s/%d", ip_s, ip_prefix->len); if (rc >= size) - return (int)size; + return (int) size; return rc; } int -ip_prefix_len (const ip_prefix_t * prefix) +ip_prefix_snprintf (char *s, size_t size, const ip_prefix_t *prefix) +{ + return ip_prefix_ntop (prefix, s, size); +} + +int +ip_prefix_len (const ip_prefix_t *prefix) { - return prefix->len; // ip_address_len(&prefix->address, prefix->family); + return prefix->len; // ip_address_len(&prefix->address, prefix->family); } const u8 * -ip_address_get_buffer(const ip_address_t * ip_address, int family) +ip_address_get_buffer (const ip_address_t *ip_address, int family) { - switch(family) { + switch (family) + { case AF_INET: return ip_address->v4.buffer; case AF_INET6: return ip_address->v6.buffer; default: return NULL; - } + } } bool -ip_prefix_empty (const ip_prefix_t * prefix) +ip_prefix_empty (const ip_prefix_t *prefix) { return prefix->len == 0; } int -ip_prefix_to_sockaddr(const ip_prefix_t * prefix, - struct sockaddr *sa) +ip_prefix_to_sockaddr (const ip_prefix_t *prefix, struct sockaddr *sa) { - // XXX assert len == ip_address_len - return ip_address_to_sockaddr(&prefix->address, sa, prefix->family); + // XXX assert len == ip_address_len + return ip_address_to_sockaddr (&prefix->address, sa, prefix->family); } int -ip_prefix_cmp(const ip_prefix_t * prefix1, const ip_prefix_t * prefix2) +ip_prefix_cmp (const ip_prefix_t *prefix1, const ip_prefix_t *prefix2) { - if (prefix1->family < prefix2->family) - return -1; - else if (prefix1->family > prefix2->family) - return 1; + if (prefix1->family < prefix2->family) + return -1; + else if (prefix1->family > prefix2->family) + return 1; - if (prefix1->len < prefix2->len) - return -1; - else if (prefix1->len > prefix2->len) - return 1; + if (prefix1->len < prefix2->len) + return -1; + else if (prefix1->len > prefix2->len) + return 1; - return ip_address_cmp(&prefix1->address, &prefix2->address, prefix1->family); + return ip_address_cmp (&prefix1->address, &prefix2->address, + prefix1->family); } /* URL */ #define MAXSZ_PROTO_ 8 /* inetX:// */ -#define MAXSZ_PROTO MAXSZ_PROTO_ + NULLTERM +#define MAXSZ_PROTO MAXSZ_PROTO_ + NULLTERM #define MAXSZ_URL4_ MAXSZ_PROTO_ + MAXSZ_IP4_ADDRESS_ + MAXSZ_PORT_ #define MAXSZ_URL6_ MAXSZ_PROTO_ + MAXSZ_IP6_ADDRESS_ + MAXSZ_PORT_ -#define MAXSZ_URL_ MAXSZ_URL6_ -#define MAXSZ_URL4 MAXSZ_URL4_ + NULLTERM -#define MAXSZ_URL6 MAXSZ_URL6_ + NULLTERM -#define MAXSZ_URL MAXSZ_URL_ + NULLTERM +#define MAXSZ_URL_ MAXSZ_URL6_ +#define MAXSZ_URL4 MAXSZ_URL4_ + NULLTERM +#define MAXSZ_URL6 MAXSZ_URL6_ + NULLTERM +#define MAXSZ_URL MAXSZ_URL_ + NULLTERM int -url_snprintf(char * s, size_t size, int family, - const ip_address_t * ip_address, u16 port) +url_snprintf (char *s, size_t size, int family, const ip_address_t *ip_address, + u16 port) { - char ip_address_s[MAXSZ_IP_ADDRESS]; - int rc; + char ip_address_s[MAXSZ_IP_ADDRESS]; + int rc; - /* Other address are currently not supported */ - if (!IS_VALID_FAMILY(family)) - return -1; + /* Other address are currently not supported */ + if (!IS_VALID_FAMILY (family)) + return -1; - rc = ip_address_snprintf(ip_address_s, MAXSZ_IP_ADDRESS, ip_address, family); - if (rc >= MAXSZ_IP_ADDRESS) - WARN("[url_snprintf] Unexpected ip_address truncation"); - if (rc < 0) - return rc; + rc = + ip_address_snprintf (ip_address_s, MAXSZ_IP_ADDRESS, ip_address, family); + if (rc >= MAXSZ_IP_ADDRESS) + WARN ("[url_snprintf] Unexpected ip_address truncation"); + if (rc < 0) + return rc; - return snprintf(s, size, "inet%c://%s:%d", (family == AF_INET) ? '4' : '6', - ip_address_s, port); + return snprintf (s, size, "inet%c://%s:%d", (family == AF_INET) ? '4' : '6', + ip_address_s, port); } |