Browse Source

[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>
tags/v1.20.1
Michael Brown 9 years ago
parent
commit
bb1abb2b21
3 changed files with 39 additions and 28 deletions
  1. 0
    23
      src/core/misc.c
  2. 37
    5
      src/net/ipv4.c
  3. 2
    0
      src/tests/ipv4_test.c

+ 0
- 23
src/core/misc.c View File

@@ -10,29 +10,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
10 10
 #include <ipxe/in.h>
11 11
 #include <ipxe/timer.h>
12 12
 
13
-/**************************************************************************
14
-INET_ATON - Convert an ascii x.x.x.x to binary form
15
-**************************************************************************/
16
-int inet_aton ( const char *cp, struct in_addr *inp ) {
17
-	const char *p = cp;
18
-	const char *digits_start;
19
-	unsigned long ip = 0;
20
-	unsigned long val;
21
-	int j;
22
-	for(j = 0; j <= 3; j++) {
23
-		digits_start = p;
24
-		val = strtoul(p, ( char ** ) &p, 10);
25
-		if ((p == digits_start) || (val > 255)) return 0;
26
-		if ( ( j < 3 ) && ( *(p++) != '.' ) ) return 0;
27
-		ip = (ip << 8) | val;
28
-	}
29
-	if ( *p == '\0' ) {
30
-		inp->s_addr = htonl(ip);
31
-		return 1;
32
-	}
33
-	return 0;
34
-}
35
-
36 13
 unsigned int strtoul_charval ( unsigned int charval ) {
37 14
 
38 15
 	if ( charval >= 'a' ) {

+ 37
- 5
src/net/ipv4.c View File

@@ -588,11 +588,43 @@ static int ipv4_arp_check ( struct net_device *netdev, const void *net_addr ) {
588 588
 	return -ENOENT;
589 589
 }
590 590
 
591
+/**
592
+ * Parse IPv4 address
593
+ *
594
+ * @v string		IPv4 address string
595
+ * @ret in		IPv4 address to fill in
596
+ * @ret ok		IPv4 address is valid
597
+ *
598
+ * Note that this function returns nonzero iff the address is valid,
599
+ * to match the standard BSD API function of the same name.  Unlike
600
+ * most other iPXE functions, a zero therefore indicates failure.
601
+ */
602
+int inet_aton ( const char *string, struct in_addr *in ) {
603
+	const char *separator = "...";
604
+	uint8_t *byte = ( ( uint8_t * ) in );
605
+	char *endp;
606
+	unsigned long value;
607
+
608
+	while ( 1 ) {
609
+		value = strtoul ( string, &endp, 0 );
610
+		if ( string == endp )
611
+			return 0;
612
+		if ( value > 0xff )
613
+			return 0;
614
+		*(byte++) = value;
615
+		if ( *endp != *separator )
616
+			return 0;
617
+		if ( ! *(separator++) )
618
+			return 1;
619
+		string = ( endp + 1 );
620
+	}
621
+}
622
+
591 623
 /**
592 624
  * Convert IPv4 address to dotted-quad notation
593 625
  *
594
- * @v in	IP address
595
- * @ret string	IP address in dotted-quad notation
626
+ * @v in		IPv4 address
627
+ * @ret string		IPv4 address in dotted-quad notation
596 628
  */
597 629
 char * inet_ntoa ( struct in_addr in ) {
598 630
 	static char buf[16]; /* "xxx.xxx.xxx.xxx" */
@@ -603,10 +635,10 @@ char * inet_ntoa ( struct in_addr in ) {
603 635
 }
604 636
 
605 637
 /**
606
- * Transcribe IP address
638
+ * Transcribe IPv4 address
607 639
  *
608
- * @v net_addr	IP address
609
- * @ret string	IP address in dotted-quad notation
640
+ * @v net_addr		IPv4 address
641
+ * @ret string		IPv4 address in dotted-quad notation
610 642
  *
611 643
  */
612 644
 static const char * ipv4_ntoa ( const void *net_addr ) {

+ 2
- 0
src/tests/ipv4_test.c View File

@@ -138,6 +138,8 @@ static void ipv4_test_exec ( void ) {
138 138
 	inet_aton_fail_ok ( "256.0.0.1" ); /* Byte out of range */
139 139
 	inet_aton_fail_ok ( "212.13.204.60.1" ); /* Too long */
140 140
 	inet_aton_fail_ok ( "127.0.0" ); /* Too short */
141
+	inet_aton_fail_ok ( "1.2.3.a" ); /* Invalid characters */
142
+	inet_aton_fail_ok ( "127.0..1" ); /* Missing bytes */
141 143
 }
142 144
 
143 145
 /** IPv4 self-test */

Loading…
Cancel
Save