[ipv6] Implement inet6_aton, numeric IPv6 address resolution
[gpxe.git] / src / net / ipv6.c
index 5ce4e1a..abf5353 100644 (file)
@@ -49,7 +49,7 @@ static LIST_HEAD ( miniroutes );
  * Add IPv6 minirouting table entry
  *
  * @v netdev           Network device
- * @v prefix           Destination prefix
+ * @v prefix           Destination prefix (in bits)
  * @v address          Address of the interface
  * @v gateway          Gateway address (or ::0 for no gateway)
  * @ret miniroute      Routing table entry, or NULL
@@ -60,7 +60,7 @@ add_ipv6_miniroute ( struct net_device *netdev, struct in6_addr prefix,
                     struct in6_addr gateway ) {
        struct ipv6_miniroute *miniroute;
        
-       DBG("ipv6 add: %s/%d ", inet6_ntoa(address), prefix_len * 8);
+       DBG("ipv6 add: %s/%d ", inet6_ntoa(address), prefix_len);
        DBG("gw %s\n", inet6_ntoa(gateway));
 
        miniroute = malloc ( sizeof ( *miniroute ) );
@@ -91,7 +91,7 @@ add_ipv6_miniroute ( struct net_device *netdev, struct in6_addr prefix,
 static void del_ipv6_miniroute ( struct ipv6_miniroute *miniroute ) {
        
        DBG("ipv6 del: %s/%d\n", inet6_ntoa(miniroute->address),
-                                miniroute->prefix_len * 8);
+                                miniroute->prefix_len);
        
        netdev_put ( miniroute->netdev );
        list_del ( &miniroute->list );
@@ -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 ) );
 }