aboutgitcodebugslistschat
path: root/inany.h
diff options
context:
space:
mode:
Diffstat (limited to 'inany.h')
-rw-r--r--inany.h83
1 files changed, 59 insertions, 24 deletions
diff --git a/inany.h b/inany.h
index d2893ce..d0befb1 100644
--- a/inany.h
+++ b/inany.h
@@ -9,16 +9,22 @@
#ifndef INANY_H
#define INANY_H
-struct siphash_state;
+#include <assert.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <string.h>
+
+#include "common.h"
+#include "ip.h"
/** union inany_addr - Represents either an IPv4 or IPv6 address
* @a6: Address as an IPv6 address, may be IPv4-mapped
* @v4mapped.zero: All zero-bits for an IPv4 address
* @v4mapped.one: All one-bits for an IPv4 address
* @v4mapped.a4: If @a6 is an IPv4 mapped address, the IPv4 address
- * @u64: As an array of u64s (solely for hashing)
+ * @u32: As an array of u32s (solely for hashing)
*
- * @v4mapped and @u64 shouldn't be accessed except via helpers.
+ * @v4mapped and @u32 shouldn't be accessed except via helpers.
*/
union inany_addr {
struct in6_addr a6;
@@ -53,6 +59,8 @@ extern const union inany_addr inany_any4;
#define inany_from_v4(a4) \
((union inany_addr)INANY_INIT4((a4)))
+#define inany_from_v6(a6_) \
+ ((union inany_addr){.a6 = (a6_)})
/** union sockaddr_inany - Either a sockaddr_in or a sockaddr_in6
* @sa_family: Address family, AF_INET or AF_INET6
@@ -67,6 +75,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 +104,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
*
@@ -232,43 +270,40 @@ static inline void inany_from_af(union inany_addr *aa,
aa->v4mapped.a4 = *((struct in_addr *)addr);
} else {
/* Not valid to call with other address families */
- ASSERT(0);
+ assert(0);
}
}
/** 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;
}
-}
-/** inany_siphash_feed- Fold IPv[46] address into an in-progress siphash
- * @state: siphash state
- * @aa: inany to hash
- */
-static inline void inany_siphash_feed(struct siphash_state *state,
- const union inany_addr *aa)
-{
- siphash_feed(state, (uint64_t)aa->u32[0] << 32 | aa->u32[1]);
- siphash_feed(state, (uint64_t)aa->u32[2] << 32 | aa->u32[3]);
+ return -1;
}
#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);
#endif /* INANY_H */