diff options
author | cinap_lenrek <cinap_lenrek@gmx.de> | 2013-04-02 03:48:10 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@gmx.de> | 2013-04-02 03:48:10 +0200 |
commit | d645d4d81bed04bba1530d1dabb921279e3c4c34 (patch) | |
tree | 822e79056a16253b30e091117192a2b4d42ea4fd /sys/src/ape/lib/bsd | |
parent | 4c2d520eeffe4c69f93f7195658f6e4877bb2ccf (diff) |
ape: inet_pton() parse dotted address to IPv4 mapped addresses for AF_INET6
Diffstat (limited to 'sys/src/ape/lib/bsd')
-rw-r--r-- | sys/src/ape/lib/bsd/inet_pton.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/sys/src/ape/lib/bsd/inet_pton.c b/sys/src/ape/lib/bsd/inet_pton.c index 0e10ab5cf..7a0b9c83b 100644 --- a/sys/src/ape/lib/bsd/inet_pton.c +++ b/sys/src/ape/lib/bsd/inet_pton.c @@ -31,7 +31,7 @@ delimchar(int c) int inet_pton(int af, char *src, void *dst) { - int i, elipsis = 0; + int i, v4 = 1, elipsis = 0; unsigned char *to; unsigned long x; char *p, *op; @@ -52,12 +52,23 @@ inet_pton(int af, char *src, void *dst) op = p; x = strtoul(p, &p, 16); + if(*p == '.' || (*p == 0 && i == 0)){ /* ends with v4? */ + struct in_addr in; + + if(i > 16-4 || inet_aton(op, &in) == 0) + return 0; /* parse error */ + + memmove(to+i, (unsigned char*)&in.s_addr, 4); + i += 4; + break; + } if(x != (unsigned short)x || *p != ':' && !delimchar(*p)) return 0; /* parse error */ to[i] = x>>8; to[i+1] = x; if(*p == ':'){ + v4 = 0; if(*++p == ':'){ /* :: is elided zero short(s) */ if (elipsis) return 0; /* second :: */ @@ -73,5 +84,7 @@ inet_pton(int af, char *src, void *dst) memmove(&to[elipsis+16-i], &to[elipsis], i-elipsis); memset(&to[elipsis], 0, 16-i); } + if(v4) + to[10] = to[11] = 0xff; return 1; } |