summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brown2015-02-19 15:02:07 +0100
committerMichael Brown2015-02-19 15:02:07 +0100
commitbb1abb2b213adceb606ff458e3786c8c2ea4dc8a (patch)
tree95b4a41c9a1374798662f4a61e193de1a1836753
parent[legal] Add missing copyright header to net/ipv4.c (diff)
downloadipxe-bb1abb2b213adceb606ff458e3786c8c2ea4dc8a.tar.gz
ipxe-bb1abb2b213adceb606ff458e3786c8c2ea4dc8a.tar.xz
ipxe-bb1abb2b213adceb606ff458e3786c8c2ea4dc8a.zip
[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 <mcb30@ipxe.org>
-rw-r--r--src/core/misc.c23
-rw-r--r--src/net/ipv4.c42
-rw-r--r--src/tests/ipv4_test.c2
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 <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' ) {
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
@@ -589,10 +589,42 @@ static int ipv4_arp_check ( struct net_device *netdev, const void *net_addr ) {
}
/**
+ * 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 */