From bb1abb2b213adceb606ff458e3786c8c2ea4dc8a Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Thu, 19 Feb 2015 14:02:07 +0000 Subject: [ipv4] Rewrite inet_aton() 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 --- src/core/misc.c | 23 ----------------------- src/net/ipv4.c | 42 +++++++++++++++++++++++++++++++++++++----- src/tests/ipv4_test.c | 2 ++ 3 files changed, 39 insertions(+), 28 deletions(-) diff --git a/src/core/misc.c b/src/core/misc.c index eaceddfe..84cfcd80 100644 --- a/src/core/misc.c +++ b/src/core/misc.c @@ -10,29 +10,6 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include -/************************************************************************** -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' ) { diff --git a/src/net/ipv4.c b/src/net/ipv4.c index f2337130..4dae20d1 100644 --- a/src/net/ipv4.c +++ b/src/net/ipv4.c @@ -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 ) { diff --git a/src/tests/ipv4_test.c b/src/tests/ipv4_test.c index ba18f845..a72dcc51 100644 --- a/src/tests/ipv4_test.c +++ b/src/tests/ipv4_test.c @@ -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 */ -- cgit v1.2.3-55-g7522