[gPXE-devel] [PATCH 04/31] [ipv6] implemented inet6_aton and set up NUMERIC resolv to handle IPv6 addresses.

matthew at theiselins.net matthew at theiselins.net
Fri Jul 8 10:28:13 EDT 2011


From: Matthew Iselin <matthew at theiselins.net>

Signed-off-by: Matthew Iselin <matthew at theiselins.net>
---
 src/core/resolv.c |   10 ++++++++--
 src/net/ipv6.c    |   44 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/src/core/resolv.c b/src/core/resolv.c
index 7167482..02fe312 100644
--- a/src/core/resolv.c
+++ b/src/core/resolv.c
@@ -116,6 +116,7 @@ static int numeric_resolv ( struct resolv_interface *resolv,
 			    const char *name, struct sockaddr *sa ) {
 	struct numeric_resolv *numeric;
 	struct sockaddr_in *sin;
+	struct sockaddr_in6 *sin6;
 
 	/* Allocate and initialise structure */
 	numeric = zalloc ( sizeof ( *numeric ) );
@@ -132,8 +133,13 @@ static int numeric_resolv ( struct resolv_interface *resolv,
 	/* Attempt to resolve name */
 	sin = ( ( struct sockaddr_in * ) &numeric->sa );
 	sin->sin_family = AF_INET;
-	if ( inet_aton ( name, &sin->sin_addr ) == 0 )
-		numeric->rc = -EINVAL;
+	if ( inet_aton ( name, &sin->sin_addr ) == 0 ) {
+		sin6 = ( ( struct sockaddr_in6 * ) &numeric->sa );
+		sin6->sin_family = AF_INET6;
+		if ( inet6_aton ( name, &sin6->sin6_addr ) == 0 ) {
+			numeric->rc = -EINVAL;
+		}
+	}
 
 	/* Attach to parent interface, mortalise self, and return */
 	resolv_plug_plug ( &numeric->resolv, resolv );
diff --git a/src/net/ipv6.c b/src/net/ipv6.c
index 9925435..abf5353 100644
--- a/src/net/ipv6.c
+++ b/src/net/ipv6.c
@@ -431,6 +431,50 @@ char * inet6_ntoa ( struct in6_addr in6 ) {
 	return buf;
 }
 
+/**
+ * Convert a string to an IPv6 address.
+ *
+ * @v in6   String to convert to an address.
+ */
+int inet6_aton ( const char *cp, struct in6_addr *inp ) {
+	char convbuf[40];
+	char *tmp = convbuf, *next = convbuf;
+	size_t i = 0;
+	
+	strcpy ( convbuf, cp );
+	
+	DBG ( "ipv6 converting %s to an in6_addr\n", cp );
+	
+	/* Handle the first part of the address (or all of it if no zero-compression. */
+	while ( ( next = strchr ( next, ':' ) ) ) {
+		/* Cater for zero-compression. */
+		if ( *tmp == ':' )
+			break;
+		
+		/* Convert to integer. */
+		inp->s6_addr16[i++] = htons( strtoul ( tmp, 0, 16 ) );
+		
+		*next++ = 0;
+		tmp = next;
+	}
+	
+	/* Handle zero-compression now (go backwards). */
+	i = 7;
+	if ( *tmp == ':' ) {
+		next = strrchr ( next, ':' );
+		do
+		{
+			tmp = next + 1;
+			*next-- = 0;
+		
+			/* Convert to integer. */
+			inp->s6_addr16[i--] = htons( strtoul ( tmp, 0, 16 ) );
+		} while ( ( next = strrchr ( next, ':' ) ) );
+	}
+	
+	return 1;
+}
+
 static const char * ipv6_ntoa ( const void *net_addr ) {
 	return inet6_ntoa ( * ( ( struct in6_addr * ) net_addr ) );
 }
-- 
1.7.2.5



More information about the gPXE-devel mailing list