]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[ipv4] Rewrite inet_aton()
authorMichael Brown <mcb30@ipxe.org>
Thu, 19 Feb 2015 14:02:07 +0000 (14:02 +0000)
committerMichael Brown <mcb30@ipxe.org>
Thu, 19 Feb 2015 14:02:07 +0000 (14:02 +0000)
The implementation of inet_aton() has an unknown provenance.  Rewrite
this code to avoid potential licensing uncertainty.

Also move the code from core/misc.c to its logical home in net/ipv4.c,
and add a few extra test cases.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/core/misc.c
src/net/ipv4.c
src/tests/ipv4_test.c

index eaceddfea5fec02cd678cd5b5b261416ded192fb..84cfcd803362e71a2efd6d8342aa56582b953f7d 100644 (file)
@@ -10,29 +10,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #include <ipxe/in.h>
 #include <ipxe/timer.h>
 
-/**************************************************************************
-INET_ATON - Convert an ascii x.x.x.x to binary form
-**************************************************************************/
-int inet_aton ( const char *cp, struct in_addr *inp ) {
-       const char *p = cp;
-       const char *digits_start;
-       unsigned long ip = 0;
-       unsigned long val;
-       int j;
-       for(j = 0; j <= 3; j++) {
-               digits_start = p;
-               val = strtoul(p, ( char ** ) &p, 10);
-               if ((p == digits_start) || (val > 255)) return 0;
-               if ( ( j < 3 ) && ( *(p++) != '.' ) ) return 0;
-               ip = (ip << 8) | val;
-       }
-       if ( *p == '\0' ) {
-               inp->s_addr = htonl(ip);
-               return 1;
-       }
-       return 0;
-}
-
 unsigned int strtoul_charval ( unsigned int charval ) {
 
        if ( charval >= 'a' ) {
index f2337130589e8a02221bd04965a26ef43968d81d..4dae20d10557d68aa7eaf90ff90a2daf80d8243e 100644 (file)
@@ -588,11 +588,43 @@ static int ipv4_arp_check ( struct net_device *netdev, const void *net_addr ) {
        return -ENOENT;
 }
 
+/**
+ * Parse IPv4 address
+ *
+ * @v string           IPv4 address string
+ * @ret in             IPv4 address to fill in
+ * @ret ok             IPv4 address is valid
+ *
+ * Note that this function returns nonzero iff the address is valid,
+ * to match the standard BSD API function of the same name.  Unlike
+ * most other iPXE functions, a zero therefore indicates failure.
+ */
+int inet_aton ( const char *string, struct in_addr *in ) {
+       const char *separator = "...";
+       uint8_t *byte = ( ( uint8_t * ) in );
+       char *endp;
+       unsigned long value;
+
+       while ( 1 ) {
+               value = strtoul ( string, &endp, 0 );
+               if ( string == endp )
+                       return 0;
+               if ( value > 0xff )
+                       return 0;
+               *(byte++) = value;
+               if ( *endp != *separator )
+                       return 0;
+               if ( ! *(separator++) )
+                       return 1;
+               string = ( endp + 1 );
+       }
+}
+
 /**
  * Convert IPv4 address to dotted-quad notation
  *
- * @v in       IP address
- * @ret string IP address in dotted-quad notation
+ * @v in               IPv4 address
+ * @ret string         IPv4 address in dotted-quad notation
  */
 char * inet_ntoa ( struct in_addr in ) {
        static char buf[16]; /* "xxx.xxx.xxx.xxx" */
@@ -603,10 +635,10 @@ char * inet_ntoa ( struct in_addr in ) {
 }
 
 /**
- * Transcribe IP address
+ * Transcribe IPv4 address
  *
- * @v net_addr IP address
- * @ret string IP address in dotted-quad notation
+ * @v net_addr         IPv4 address
+ * @ret string         IPv4 address in dotted-quad notation
  *
  */
 static const char * ipv4_ntoa ( const void *net_addr ) {
index ba18f8450ceca0d5e5a6edfab58e7644c4094656..a72dcc51ad1957c1a650adabc1c78e88106e44ee 100644 (file)
@@ -138,6 +138,8 @@ static void ipv4_test_exec ( void ) {
        inet_aton_fail_ok ( "256.0.0.1" ); /* Byte out of range */
        inet_aton_fail_ok ( "212.13.204.60.1" ); /* Too long */
        inet_aton_fail_ok ( "127.0.0" ); /* Too short */
+       inet_aton_fail_ok ( "1.2.3.a" ); /* Invalid characters */
+       inet_aton_fail_ok ( "127.0..1" ); /* Missing bytes */
 }
 
 /** IPv4 self-test */