diff options
author | Thomas Haller <thaller@redhat.com> | 2022-04-22 16:26:58 (GMT) |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2022-04-22 17:04:19 (GMT) |
commit | 40683cc496b2aaae0b2ca53329b092a9a77fc82b (patch) | |
tree | 73a46d123f6de51914c82fd98d1c29ba86de9e0e | |
parent | 6615dc0d38856855d37d34dadf70cfa610bd20f2 (diff) | |
download | libnl-40683cc496b2aaae0b2ca53329b092a9a77fc82b.zip libnl-40683cc496b2aaae0b2ca53329b092a9a77fc82b.tar.gz libnl-40683cc496b2aaae0b2ca53329b092a9a77fc82b.tar.bz2 |
netlink/private: add internal helper utils
inet_ntop() is documented to fail, so we have various places
with pointless (and wrong) error checking. Well, it can fail
if we pass an unexpected address family (which we must not and
assert against that), or if we pass an invalid string buffer (which we
must not, and cannot meaningfully assert for that). So it can only fail
in case of a bug and there is no need for error checking.
Yes, libc could theoretically fail, but if it fails on such a function that
requires no memory allocation, then it really needs to be fixed.
-rw-r--r-- | include/netlink-private/utils.h | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/include/netlink-private/utils.h b/include/netlink-private/utils.h index 8fb12af..dca05b9 100644 --- a/include/netlink-private/utils.h +++ b/include/netlink-private/utils.h @@ -12,6 +12,8 @@ #include <errno.h> #include <string.h> #include <stdbool.h> +#include <netinet/in.h> +#include <arpa/inet.h> #if __BYTE_ORDER == __BIG_ENDIAN #define ntohll(x) (x) @@ -84,6 +86,40 @@ /*****************************************************************************/ +#define _nl_assert_addr_family_or_unspec(addr_family) \ + do { \ + typeof(addr_family) _addr_family = (addr_family); \ + \ + _nl_assert(_addr_family == AF_UNSPEC || \ + _addr_family == AF_INET || \ + _addr_family == AF_INET6); \ + } while (0) + +#define _nl_assert_addr_family(addr_family) \ + do { \ + typeof(addr_family) _addr_family = (addr_family); \ + \ + _nl_assert(_addr_family == AF_INET || \ + _addr_family == AF_INET6); \ + } while (0) + +/*****************************************************************************/ + +#define _NL_SWAP(pa, pb) \ + do { \ + typeof(*(pa)) *_pa = (pa); \ + typeof(*(pb)) *_pb = (pb); \ + typeof(*_pa) _tmp; \ + \ + _nl_assert(_pa); \ + _nl_assert(_pb); \ + _tmp = *_pa; \ + *_pa = *_pb; \ + *_pb = _tmp; \ + } while (0) + +/*****************************************************************************/ + #define _NL_N_ELEMENTS(arr) (sizeof(arr) / sizeof((arr)[0])) /*****************************************************************************/ @@ -300,4 +336,41 @@ _nl_memdup(const void *ptr, size_t len) #define _nl_memdup_ptr(ptr) ((__typeof__(ptr)) _nl_memdup((ptr), sizeof(*(ptr)))) +/*****************************************************************************/ + +typedef union { + in_addr_t addr4; + struct in_addr a4; + struct in6_addr a6; +} _NLIPAddr; + +static inline char *_nl_inet_ntop(int addr_family, const void *addr, + char buf[static INET_ADDRSTRLEN]) +{ + char *r; + + _nl_assert_addr_family(addr_family); + _nl_assert(addr); + + /* inet_ntop() is documented to fail, but if we pass a known address family + * and a suitably large buffer, it cannot. Assert for that. */ + + r = (char *)inet_ntop(addr_family, addr, buf, + (addr_family == AF_INET) ? INET_ADDRSTRLEN : + INET6_ADDRSTRLEN); + _nl_assert(r == buf); + _nl_assert(strlen(r) < ((addr_family == AF_INET) ? INET_ADDRSTRLEN : + INET6_ADDRSTRLEN)); + + return r; +} + +static inline char *_nl_inet_ntop_dup(int addr_family, const void *addr) +{ + return (char *)_nl_inet_ntop(addr_family, addr, + malloc((addr_family == AF_INET) ? + INET_ADDRSTRLEN : + INET6_ADDRSTRLEN)); +} + #endif |