chiark / gitweb /
ipv6: Support printing, comparing, etc. IPv6 addresses
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 29 Jun 2014 22:10:31 +0000 (23:10 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 5 Oct 2014 20:27:29 +0000 (21:27 +0100)
If we support IPv6, convert addresses with adns_addr2text.  Otherwise
stick with inet_ntoa.

With these changes, there is nothing remaining that will actually
crash secnet if it is passed an IPv6 address.  However, it is not yet
possible to mention IPv6 addresses in the configuration, and the udp
transport needs dual stack support.

Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
secnet.h
util.c

index 3fba00f406862d14abe59e97e54dad5cdfe12b58..628a7555f3e38213eb44efe883fe1250dd8dbf7f 100644 (file)
--- a/secnet.h
+++ b/secnet.h
@@ -33,6 +33,9 @@ typedef _Bool bool_t;
 union iaddr {
     struct sockaddr sa;
     struct sockaddr_in sin;
 union iaddr {
     struct sockaddr sa;
     struct sockaddr_in sin;
+#ifdef CONFIG_IPV6
+    struct sockaddr_in6 sin6;
+#endif
 };
 
 #define ASSERT(x) do { if (!(x)) { fatal("assertion failed line %d file " \
 };
 
 #define ASSERT(x) do { if (!(x)) { fatal("assertion failed line %d file " \
diff --git a/util.c b/util.c
index 5658aa3ca62c0efe9dce7b048bb08dade1e5906d..426fc69c1a9e922931c52c23d88377dbcf743f1d 100644 (file)
--- a/util.c
+++ b/util.c
@@ -36,6 +36,7 @@
 #include <limits.h>
 #include <assert.h>
 #include <sys/wait.h>
 #include <limits.h>
 #include <assert.h>
 #include <sys/wait.h>
+#include <adns.h>
 #include "util.h"
 #include "unaligned.h"
 #include "magic.h"
 #include "util.h"
 #include "unaligned.h"
 #include "magic.h"
@@ -482,17 +483,47 @@ extern void slilog_part(struct log_if *lf, int priority, const char *message, ..
 
 const char *iaddr_to_string(const union iaddr *ia)
 {
 
 const char *iaddr_to_string(const union iaddr *ia)
 {
-    static char bufs[IADDR_NBUFS][100];
     static int b;
 
     b++;
     b &= IADDR_NBUFS-1;
 
     static int b;
 
     b++;
     b &= IADDR_NBUFS-1;
 
+#ifndef CONFIG_IPV6
+
+    static char bufs[IADDR_NBUFS][100];
+
     assert(ia->sa.sa_family == AF_INET);
 
     snprintf(bufs[b], sizeof(bufs[b]), "[%s]:%d",
             inet_ntoa(ia->sin.sin_addr),
             ntohs(ia->sin.sin_port));
     assert(ia->sa.sa_family == AF_INET);
 
     snprintf(bufs[b], sizeof(bufs[b]), "[%s]:%d",
             inet_ntoa(ia->sin.sin_addr),
             ntohs(ia->sin.sin_port));
+
+#else /* CONFIG_IPV6 => we have adns_addr2text */
+
+    static char bufs[IADDR_NBUFS][1+ADNS_ADDR2TEXT_BUFLEN+20];
+
+    int port;
+
+    char *addrbuf = bufs[b];
+    *addrbuf++ = '[';
+    int addrbuflen = ADNS_ADDR2TEXT_BUFLEN;
+
+    int r = adns_addr2text(&ia->sa, 0, addrbuf, &addrbuflen, &port);
+    if (r) {
+       const char fmt[]= "scoped IPv6 addr, error: %.*s";
+       sprintf(addrbuf, fmt,
+               ADNS_ADDR2TEXT_BUFLEN - sizeof(fmt) /* underestimate */,
+               strerror(r));
+    }
+
+    char *portbuf = addrbuf;
+    int addrl = strlen(addrbuf);
+    portbuf += addrl;
+
+    snprintf(portbuf, sizeof(bufs[b])-addrl, "]:%d", port);
+
+#endif /* CONFIG_IPV6 */
+
     return bufs[b];
 }
 
     return bufs[b];
 }
 
@@ -504,6 +535,13 @@ bool_t iaddr_equal(const union iaddr *ia, const union iaddr *ib)
     case AF_INET:
        return ia->sin.sin_addr.s_addr == ib->sin.sin_addr.s_addr
            && ia->sin.sin_port        == ib->sin.sin_port;
     case AF_INET:
        return ia->sin.sin_addr.s_addr == ib->sin.sin_addr.s_addr
            && ia->sin.sin_port        == ib->sin.sin_port;
+#ifdef CONFIG_IPV6
+    case AF_INET6:
+       return !memcmp(&ia->sin6.sin6_addr, &ib->sin6.sin6_addr, 16)
+           && ia->sin6.sin6_scope_id  == ib->sin6.sin6_scope_id
+           && ia->sin6.sin6_port      == ib->sin6.sin6_port
+           /* we ignore the flowinfo field */;
+#endif /* CONFIG_IPV6 */
     default:
        abort();
     }
     default:
        abort();
     }
@@ -513,6 +551,9 @@ int iaddr_socklen(const union iaddr *ia)
 {
     switch (ia->sa.sa_family) {
     case AF_INET:  return sizeof(ia->sin);
 {
     switch (ia->sa.sa_family) {
     case AF_INET:  return sizeof(ia->sin);
+#ifdef CONFIG_IPV6
+    case AF_INET6: return sizeof(ia->sin6);
+#endif /* CONFIG_IPV6 */
     default:       abort();
     }
 }
     default:       abort();
     }
 }