From 2e6459c7f6141c30efb75fdeba93902ac55f83f0 Mon Sep 17 00:00:00 2001 From: Matthew Iselin Date: Thu, 26 May 2011 21:27:14 +1000 Subject: [PATCH] [ipv6] Implement inet6_aton, numeric IPv6 address resolution Signed-off-by: Matthew Iselin Signed-off-by: Marty Connor --- 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 7167482f..02fe3123 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 99254359..abf53535 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 ) ); } -- 2.11.4.GIT