summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2022-04-22 16:26:58 (GMT)
committerThomas Haller <thaller@redhat.com>2022-04-22 17:04:19 (GMT)
commit40683cc496b2aaae0b2ca53329b092a9a77fc82b (patch)
tree73a46d123f6de51914c82fd98d1c29ba86de9e0e
parent6615dc0d38856855d37d34dadf70cfa610bd20f2 (diff)
downloadlibnl-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.h73
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