diff options
Diffstat (limited to 'inany.h')
| -rw-r--r-- | inany.h | 83 |
1 files changed, 59 insertions, 24 deletions
@@ -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 */ |
