[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[leafnode-list] [PATCH] IPv6 question



The attached patch should fix the issue, but I cannot reproduce the
original problem (not using CentOS 7, but Ubuntu 14.04) - I can't seem
to get IPv4-mapped IPv6 addresses here through inetd nor xinetd 2.3.15
built from source.

>From 650fe949dff11c380a30a64582043b286a1a004a Mon Sep 17 00:00:00 2001
From: Matthias Andree <matthias.andree@xxxxxx>
Date: Mon, 24 Aug 2015 23:48:28 +0200
Subject: [PATCH] Fix for IPv4-mapped IPv6 addresses (::ffff:10.9.8.7).

---
 NEWS             |  2 ++
 checkpeerlocal.c | 28 +++++++++++++++++++++++++---
 2 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/NEWS b/NEWS
index 0bf17da..fcbfce6 100644
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,8 @@
 - The roff manual page sources now render proper hyphens (-), minus characters
   (\-) and en-dashes (\[en]) depending on their context. This is so that
   copying-and-pasting from the manual page works properly.
+- The code that checks if the peer is local now properly deals with IPv4
+  mapped IPv6 addresses.
 
 ==============================================================================
 * 1.11.10, 2013-06-11
diff --git a/checkpeerlocal.c b/checkpeerlocal.c
index 4417e24..36ec69a 100644
--- a/checkpeerlocal.c
+++ b/checkpeerlocal.c
@@ -159,6 +159,17 @@ static void pat(const struct sockaddr *addr)
 }
 #endif
 
+/** extract IPv4 address from IPv6-mapped IPv4 address (::ffff:10.9.8.7)
+ */
+#if HAVE_IPV6
+static void extract_v6mappedv4(const struct sockaddr_in6 *i6, struct sockaddr_in *out)
+{
+    out->sin_family = AF_INET;
+    out->sin_port = i6->sin6_port;
+    memcpy(&out->sin_addr, &(i6->sin6_addr.s6_addr[12]), 4);
+}
+#endif
+
 /**
  * check whether the peer of the socket is local to any of our network
  * interfaces, \return
@@ -196,6 +207,15 @@ int checkpeerlocal(int sock)
     }
 #endif
 
+    if (IN6_IS_ADDR_V4MAPPED(&addr.sin6.sin6_addr)) {
+	    /* map to IPv4 */
+	    struct sockaddr_in si;
+	    D((printf("IPv4 mapped IPv6 address: ")));
+	    extract_v6mappedv4(&addr.sin6, &si);
+	    memcpy(&addr.sin, &si, sizeof(struct sockaddr_in));
+	    D(pat(&addr.sa));
+    }
+
     if (getifaddrs(&ifap) != 0) {
 	D(printf("getifaddrs failed: %s\n", strerror(errno)));
 	return -1;
@@ -280,6 +300,10 @@ int checkpeerlocal(int sock)
 	    return -1;
     }
 
+#ifdef TEST_LOCAL
+    memcpy(&addr, &tstaddr, sizeof(addr));
+#endif
+
     type = addr.ss.ss_family;
     D(printf("address type of peer socket: %d\n", type));
 
@@ -315,9 +339,7 @@ int checkpeerlocal(int sock)
 	    /* map to IPv4 */
 	    struct sockaddr_in si;
 	    D((printf("IPv4 mapped IPv6 address\n")));
-	    si.sin_family = AF_INET;
-	    si.sin_port = i6->sin6_port;
-	    memcpy(&si.sin_addr, &(i6->sin6_addr.s6_addr[12]), 4);
+	    extract_v6mappedv4(i6, &si);
 	    memcpy(&addr.sin, &si, sizeof(struct sockaddr_in));
 	} else {
 	    return 0;
-- 
1.9.1

-- 
_______________________________________________
leafnode-list mailing list
leafnode-list@xxxxxxxxxxxxxxxxxxxxxxxxxxx
https://www.dt.e-technik.tu-dortmund.de/mailman/listinfo/leafnode-list
http://leafnode.sourceforge.net/