aboutgitcodebugslistschat
path: root/inany.h
diff options
context:
space:
mode:
Diffstat (limited to 'inany.h')
-rw-r--r--inany.h125
1 files changed, 110 insertions, 15 deletions
diff --git a/inany.h b/inany.h
index 407690e..7ca5cbd 100644
--- a/inany.h
+++ b/inany.h
@@ -43,6 +43,17 @@ extern const union inany_addr inany_any4;
#define in4addr_loopback (inany_loopback4.v4mapped.a4)
#define in4addr_any (inany_any4.v4mapped.a4)
+#define INANY_INIT4(a4init) { \
+ .v4mapped = { \
+ .zero = { 0 }, \
+ .one = { 0xff, 0xff }, \
+ .a4 = a4init, \
+ }, \
+ }
+
+#define inany_from_v4(a4) \
+ ((union inany_addr)INANY_INIT4((a4)))
+
/** union sockaddr_inany - Either a sockaddr_in or a sockaddr_in6
* @sa_family: Address family, AF_INET or AF_INET6
* @sa: Plain struct sockaddr (useful to avoid casts)
@@ -79,6 +90,54 @@ static inline bool inany_equals(const union inany_addr *a,
return IN6_ARE_ADDR_EQUAL(&a->a6, &b->a6);
}
+/** inany_equals4 - Compare an IPv[46] address to an IPv4 address
+ * @a: IPv[46] addresses
+ * @b: IPv4 address
+ *
+ * Return: true if @a and @b are the same address
+ */
+static inline bool inany_equals4(const union inany_addr *a,
+ const struct in_addr *b)
+{
+ const struct in_addr *a4 = inany_v4(a);
+
+ return a4 && IN4_ARE_ADDR_EQUAL(a4, b);
+}
+
+/** inany_equals6 - Compare an IPv[46] address to an IPv6 address
+ * @a: IPv[46] addresses
+ * @b: IPv6 address
+ *
+ * Return: true if @a and @b are the same address
+ */
+static inline bool inany_equals6(const union inany_addr *a,
+ const struct in6_addr *b)
+{
+ return IN6_ARE_ADDR_EQUAL(&a->a6, b);
+}
+
+/** inany_is_loopback4() - Check if address is IPv4 loopback
+ * @a: IPv[46] address
+ *
+ * Return: true if @a is in 127.0.0.1/8
+ */
+static inline bool inany_is_loopback4(const union inany_addr *a)
+{
+ const struct in_addr *v4 = inany_v4(a);
+
+ return v4 && IN4_IS_ADDR_LOOPBACK(v4);
+}
+
+/** inany_is_loopback6() - Check if address is IPv6 loopback
+ * @a: IPv[46] address
+ *
+ * Return: true if @a is in ::1
+ */
+static inline bool inany_is_loopback6(const union inany_addr *a)
+{
+ return IN6_IS_ADDR_LOOPBACK(&a->a6);
+}
+
/** inany_is_loopback() - Check if address is loopback
* @a: IPv[46] address
*
@@ -86,9 +145,29 @@ static inline bool inany_equals(const union inany_addr *a,
*/
static inline bool inany_is_loopback(const union inany_addr *a)
{
+ return inany_is_loopback4(a) || inany_is_loopback6(a);
+}
+
+/** inany_is_unspecified4() - Check if address is unspecified IPv4
+ * @a: IPv[46] address
+ *
+ * Return: true if @a is 0.0.0.0
+ */
+static inline bool inany_is_unspecified4(const union inany_addr *a)
+{
const struct in_addr *v4 = inany_v4(a);
- return IN6_IS_ADDR_LOOPBACK(&a->a6) || (v4 && IN4_IS_ADDR_LOOPBACK(v4));
+ return v4 && IN4_IS_ADDR_UNSPECIFIED(v4);
+}
+
+/** inany_is_unspecified6() - Check if address is unspecified IPv6
+ * @a: IPv[46] address
+ *
+ * Return: true if @a is ::
+ */
+static inline bool inany_is_unspecified6(const union inany_addr *a)
+{
+ return IN6_IS_ADDR_UNSPECIFIED(&a->a6);
}
/** inany_is_unspecified() - Check if address is unspecified
@@ -98,10 +177,19 @@ static inline bool inany_is_loopback(const union inany_addr *a)
*/
static inline bool inany_is_unspecified(const union inany_addr *a)
{
- const struct in_addr *v4 = inany_v4(a);
+ return inany_is_unspecified4(a) || inany_is_unspecified6(a);
+}
- return IN6_IS_ADDR_UNSPECIFIED(&a->a6) ||
- (v4 && IN4_IS_ADDR_UNSPECIFIED(v4));
+/* FIXME: consider handling of IPv4 link-local addresses */
+
+/** inany_is_linklocal6() - Check if address is link-local IPv6
+ * @a: IPv[46] address
+ *
+ * Return: true if @a is in fe80::/10 (IPv6 link local unicast)
+ */
+static inline bool inany_is_linklocal6(const union inany_addr *a)
+{
+ return IN6_IS_ADDR_LINKLOCAL(&a->a6);
}
/** inany_is_multicast() - Check if address is multicast or broadcast
@@ -123,7 +211,6 @@ static inline bool inany_is_multicast(const union inany_addr *a)
*
* Return: true if @a is specified and a unicast address
*/
-/* cppcheck-suppress unusedFunction */
static inline bool inany_is_unicast(const union inany_addr *a)
{
return !inany_is_unspecified(a) && !inany_is_multicast(a);
@@ -150,23 +237,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
@@ -183,5 +277,6 @@ static inline void inany_siphash_feed(struct siphash_state *state,
#define INANY_ADDRSTRLEN MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN)
const char *inany_ntop(const union inany_addr *src, char *dst, socklen_t size);
+int inany_pton(const char *src, union inany_addr *dst);
#endif /* INANY_H */