diff options
-rw-r--r-- | usr/klibc/inet/inet_aton.c | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/usr/klibc/inet/inet_aton.c b/usr/klibc/inet/inet_aton.c index beceeea36a733..954e5d8d90be6 100644 --- a/usr/klibc/inet/inet_aton.c +++ b/usr/klibc/inet/inet_aton.c @@ -3,20 +3,38 @@ */ #include <arpa/inet.h> +#include <ctype.h> #include <stdio.h> int inet_aton(const char *str, struct in_addr *addr) { + int i = 0, digits = 0, val = 0; union { uint8_t b[4]; uint32_t l; } a; + char ch; - if (sscanf(str, "%hhu.%hhu.%hhu.%hhu", - &a.b[0], &a.b[1], &a.b[2], &a.b[3]) == 4) { - addr->s_addr = a.l; /* Always in network byte order */ - return 1; - } else { - return 0; + for (;;) { + ch = *str++; + if (ch == (i == 3 ? 0 : '.')) { + if (digits == 0) + return 0; + a.b[i] = val; + if (++i == 4) + break; + digits = 0; + val = 0; + } else if (isdigit((unsigned char)ch)) { + digits++; + val = val * 10 + (ch - '0'); + if (val > 0xff) + return 0; + } else { + return 0; + } } + + addr->s_addr = a.l; + return 1; } |