From 5de36cf449053fb25a40a18141f0a18bf5b52444 Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Fri, 1 Jul 2016 18:24:00 +0200 Subject: [PATCH] Add inet_pton(3). --- libc/Makefile | 2 +- libc/arpa/inet/inet_pton.c | 87 +++++++++++++++++++++++++++++++++----- 2 files changed, 77 insertions(+), 12 deletions(-) diff --git a/libc/Makefile b/libc/Makefile index 2176bae7..04f8f34f 100644 --- a/libc/Makefile +++ b/libc/Makefile @@ -17,6 +17,7 @@ ASFLAGS= FREEOBJS=\ arpa/inet/inet_ntop.o \ +arpa/inet/inet_pton.o \ assert/__assert.o \ c++/c++.o \ c++/op-new.o \ @@ -317,7 +318,6 @@ wctype/wctype.o \ HOSTEDOBJS=\ arpa/inet/inet_addr.o \ arpa/inet/inet_ntoa.o \ -arpa/inet/inet_pton.o \ blf/blowfish.o \ $(CPUDIR)/fork.o \ $(CPUDIR)/setjmp.o \ diff --git a/libc/arpa/inet/inet_pton.c b/libc/arpa/inet/inet_pton.c index 9daa0aa6..1751af0f 100644 --- a/libc/arpa/inet/inet_pton.c +++ b/libc/arpa/inet/inet_pton.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 Jonas 'Sortie' Termansen. + * Copyright (c) 2016 Jonas 'Sortie' Termansen. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,21 +14,86 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * arpa/inet/inet_pton.c - * Internet address manipulation routines. + * Convert string to network address. */ #include -#include -#include -#include -#include +#include +#include +#include +#include int inet_pton(int af, const char* restrict src, void* restrict dst) { - (void) af; - (void) src; - (void) dst; - fprintf(stderr, "%s is not implemented yet, aborting.\n", __func__); - abort(); + if ( af == AF_INET ) + { + unsigned char ip[4]; + size_t index = 0; + for ( int i = 0; i < 4; i++ ) + { + if ( i && src[index++] != '.' ) + return 0; + if ( src[index] < '0' || '9' < src[index] ) + return 0; + int num = src[index++] - '0'; + if ( num ) + { + if ( '0' <= src[index] && src[index] <= '9' ) + { + num = 10 * num + src[index++] - '0'; + if ( '0' <= src[index] && src[index] <= '9' ) + { + num = 10 * num + src[index++] - '0'; + if ( 256 <= num ) + return 0; + } + } + } + ip[i] = num; + } + if ( src[index] ) + return 0; + memcpy(dst, ip, sizeof(ip)); + return 1; + } + else if ( af == AF_INET6 ) + { + unsigned char ip[16]; + size_t index = 0; + // TODO: Support for :: syntax. + // TODO: Support for x:x:x:x:x:x:d.d.d.d syntax. + for ( int i = 0; i < 8; i++ ) + { + if ( i && src[index++] != ':' ) + return 0; + int num = 0; + for ( int j = 0; j < 4; j++ ) + { + int dgt; + if ( '0' <= src[index] && src[index] <= '9' ) + dgt = src[index] - '0'; + else if ( 'a' <= src[index] && src[index] <= 'f' ) + dgt = src[index] - 'a' + 10; + else if ( 'A' <= src[index] && src[index] <= 'F' ) + dgt = src[index] - 'A' + 10; + else + { + if ( j == 0 ) + return 0; + break; + } + num = num << 4 | dgt; + index++; + } + ip[2 * i + 0] = num >> 8 & 0xFF; + ip[2 * i + 1] = num >> 0 & 0xFF; + } + if ( src[index] ) + return 0; + memcpy(dst, ip, sizeof(ip)); + return 1; + } + else + return errno = EAFNOSUPPORT, -1; }