summaryrefslogtreecommitdiff
path: root/sys/src/ape/lib/bsd
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@gmx.de>2013-04-02 03:48:10 +0200
committercinap_lenrek <cinap_lenrek@gmx.de>2013-04-02 03:48:10 +0200
commitd645d4d81bed04bba1530d1dabb921279e3c4c34 (patch)
tree822e79056a16253b30e091117192a2b4d42ea4fd /sys/src/ape/lib/bsd
parent4c2d520eeffe4c69f93f7195658f6e4877bb2ccf (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.c15
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;
}