diff options
author | Guillaume Cottenceau <gc@mandriva.com> | 2001-05-14 13:47:49 +0000 |
---|---|---|
committer | Guillaume Cottenceau <gc@mandriva.com> | 2001-05-14 13:47:49 +0000 |
commit | f15aa3a552022743398a652165d76bf912c715e5 (patch) | |
tree | b58f8b4c47fc571fbb498d83a4bd4fca226ac6c4 /mdk-stage1/dietlibc/libcruft/inet_pton.c | |
parent | 189b01c358a1181ddc951adba97a0258d5fc2cf1 (diff) | |
download | drakx-f15aa3a552022743398a652165d76bf912c715e5.tar drakx-f15aa3a552022743398a652165d76bf912c715e5.tar.gz drakx-f15aa3a552022743398a652165d76bf912c715e5.tar.bz2 drakx-f15aa3a552022743398a652165d76bf912c715e5.tar.xz drakx-f15aa3a552022743398a652165d76bf912c715e5.zip |
Initial revision
Diffstat (limited to 'mdk-stage1/dietlibc/libcruft/inet_pton.c')
-rw-r--r-- | mdk-stage1/dietlibc/libcruft/inet_pton.c | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/mdk-stage1/dietlibc/libcruft/inet_pton.c b/mdk-stage1/dietlibc/libcruft/inet_pton.c new file mode 100644 index 000000000..d5c17509c --- /dev/null +++ b/mdk-stage1/dietlibc/libcruft/inet_pton.c @@ -0,0 +1,97 @@ +#include <stdlib.h> +#include <arpa/inet.h> +#include <errno.h> + +static unsigned int scan_ip6(const char *s,char ip[16]) +{ + unsigned int i; + unsigned int len=0; + unsigned long u; + + char suffix[16]; + int prefixlen=0; + int suffixlen=0; + + for (i=0; i<16; i++) ip[i]=0; + + for (;;) { + if (*s == ':') { + len++; + if (s[1] == ':') { /* Found "::", skip to part 2 */ + s+=2; + len++; + break; + } + s++; + } + { + char *tmp; + u=strtol(s,&tmp,16); + i=tmp-s; + } + + if (!i) return 0; + if (prefixlen==12 && s[i]=='.') { + /* the last 4 bytes may be written as IPv4 address */ + if (inet_aton(s,(struct in_addr*)(ip+12))) + return i+len; + else + return 0; + } + ip[prefixlen++] = (u >> 8); + ip[prefixlen++] = (u & 255); + s += i; len += i; + if (prefixlen==16) + return len; + } + +/* part 2, after "::" */ + for (;;) { + if (*s == ':') { + if (suffixlen==0) + break; + s++; + len++; + } else if (suffixlen!=0) + break; + { + char *tmp; + u=strtol(s,&tmp,16); + i=tmp-s; + } + if (!i) { + len--; + break; + } + if (suffixlen+prefixlen<=12 && s[i]=='.') { + if (inet_aton(s,(struct in_addr*)(suffix+suffixlen))) { + suffixlen+=4; + len+=strlen(s); + break; + } else + prefixlen=12-suffixlen; /* make end-of-loop test true */ + } + suffix[suffixlen++] = (u >> 8); + suffix[suffixlen++] = (u & 255); + s += i; len += i; + if (prefixlen+suffixlen==16) + break; + } + for (i=0; i<suffixlen; i++) + ip[16-suffixlen+i] = suffix[i]; + return len; +} + +int inet_pton(int AF, const char *CP, void *BUF) { + if (AF==AF_INET) { + if (!inet_aton(CP,(struct in_addr*)BUF)) + return 0; + } else if (AF==AF_INET6) { + if (CP[scan_ip6(CP,BUF)]) + return 0; + } else { + errno=EAFNOSUPPORT; + return -1; + } + return 1; +} |