mirror of https://github.com/ipxe/ipxe.git
[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>pull/34/head
parent
095c007aa3
commit
bb1abb2b21
|
@ -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' ) {
|
||||
|
|
|
@ -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 ) {
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue