aboutgitcodebugslistschat
path: root/inany.h
diff options
context:
space:
mode:
Diffstat (limited to 'inany.h')
-rw-r--r--inany.h67
1 files changed, 57 insertions, 10 deletions
diff --git a/inany.h b/inany.h
index d2893ce..9891ed6 100644
--- a/inany.h
+++ b/inany.h
@@ -9,6 +9,12 @@
#ifndef INANY_H
#define INANY_H
+#include <assert.h>
+#include <string.h>
+
+#include "ip.h"
+#include "siphash.h"
+
struct siphash_state;
/** union inany_addr - Represents either an IPv4 or IPv6 address
@@ -67,6 +73,23 @@ union sockaddr_inany {
struct sockaddr_in6 sa6;
};
+/** socklen_inany() - Get relevant address length for sockaddr_inany address
+ * @sa: sockaddr_inany socket address
+ *
+ * Return: socket address length for bind() or connect(), from IP family in @sa
+ */
+static inline socklen_t socklen_inany(const union sockaddr_inany *sa)
+{
+ switch (sa->sa_family) {
+ case AF_INET:
+ return sizeof(sa->sa4);
+ case AF_INET6:
+ return sizeof(sa->sa6);
+ default:
+ ASSERT(0);
+ }
+}
+
/** inany_v4 - Extract IPv4 address, if present, from IPv[46] address
* @addr: IPv4 or IPv6 address
*
@@ -79,6 +102,19 @@ static inline struct in_addr *inany_v4(const union inany_addr *addr)
return (struct in_addr *)&addr->v4mapped.a4;
}
+/** inany_default_prefix_len() - Get default prefix length for address
+ * @addr: IPv4 or iPv6 address
+ *
+ * Return: Class-based prefix length for IPv4 (in IPv6 format: 104-128),
+ * or 64 for IPv6
+ */
+static inline int inany_default_prefix_len(const union inany_addr *addr)
+{
+ const struct in_addr *v4 = inany_v4(addr);
+
+ return v4 ? ip4_class_prefix_len(v4) + 96 : 64;
+}
+
/** inany_equals - Compare two IPv[46] addresses
* @a, @b: IPv[46] addresses
*
@@ -237,23 +273,30 @@ static inline void inany_from_af(union inany_addr *aa,
}
/** inany_from_sockaddr - Extract IPv[46] address and port number from sockaddr
- * @aa: Pointer to store IPv[46] address
+ * @dst: Pointer to store IPv[46] address (output)
* @port: Pointer to store port number, host order
- * @addr: AF_INET or AF_INET6 socket address
+ * @addr: Socket address
+ *
+ * Return: 0 on success, -1 on error (bad address family)
*/
-static inline void inany_from_sockaddr(union inany_addr *aa, in_port_t *port,
- const union sockaddr_inany *sa)
+static inline int inany_from_sockaddr(union inany_addr *dst, in_port_t *port,
+ const void *addr)
{
+ const union sockaddr_inany *sa = (const union sockaddr_inany *)addr;
+
if (sa->sa_family == AF_INET6) {
- inany_from_af(aa, AF_INET6, &sa->sa6.sin6_addr);
+ inany_from_af(dst, AF_INET6, &sa->sa6.sin6_addr);
*port = ntohs(sa->sa6.sin6_port);
- } else if (sa->sa_family == AF_INET) {
- inany_from_af(aa, AF_INET, &sa->sa4.sin_addr);
+ return 0;
+ }
+
+ if (sa->sa_family == AF_INET) {
+ inany_from_af(dst, AF_INET, &sa->sa4.sin_addr);
*port = ntohs(sa->sa4.sin_port);
- } else {
- /* Not valid to call with other address families */
- ASSERT(0);
+ return 0;
}
+
+ return -1;
}
/** inany_siphash_feed- Fold IPv[46] address into an in-progress siphash
@@ -269,6 +312,10 @@ static inline void inany_siphash_feed(struct siphash_state *state,
#define INANY_ADDRSTRLEN MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN)
+bool inany_matches(const union inany_addr *a, const union inany_addr *b);
const char *inany_ntop(const union inany_addr *src, char *dst, socklen_t size);
+int inany_pton(const char *src, union inany_addr *dst);
+int inany_prefix_pton(const char *src, union inany_addr *dst,
+ uint8_t *prefix_len);
#endif /* INANY_H */