1 | #include <sys/socket.h>
|
---|
2 | #include <arpa/inet.h>
|
---|
3 | #include <errno.h>
|
---|
4 | #include <stdio.h>
|
---|
5 | #include <string.h>
|
---|
6 |
|
---|
7 | const char *inet_ntop(int af, const void *restrict a0, char *restrict s, socklen_t l)
|
---|
8 | {
|
---|
9 | const unsigned char *a = a0;
|
---|
10 | int i, j, max, best;
|
---|
11 | char buf[100];
|
---|
12 |
|
---|
13 | switch (af) {
|
---|
14 | case AF_INET:
|
---|
15 | if (snprintf(s, l, "%d.%d.%d.%d", a[0],a[1],a[2],a[3]) < l)
|
---|
16 | return s;
|
---|
17 | break;
|
---|
18 | case AF_INET6:
|
---|
19 | if (memcmp(a, "\0\0\0\0\0\0\0\0\0\0\377\377", 12))
|
---|
20 | snprintf(buf, sizeof buf,
|
---|
21 | "%x:%x:%x:%x:%x:%x:%x:%x",
|
---|
22 | 256*a[0]+a[1],256*a[2]+a[3],
|
---|
23 | 256*a[4]+a[5],256*a[6]+a[7],
|
---|
24 | 256*a[8]+a[9],256*a[10]+a[11],
|
---|
25 | 256*a[12]+a[13],256*a[14]+a[15]);
|
---|
26 | else
|
---|
27 | snprintf(buf, sizeof buf,
|
---|
28 | "%x:%x:%x:%x:%x:%x:%d.%d.%d.%d",
|
---|
29 | 256*a[0]+a[1],256*a[2]+a[3],
|
---|
30 | 256*a[4]+a[5],256*a[6]+a[7],
|
---|
31 | 256*a[8]+a[9],256*a[10]+a[11],
|
---|
32 | a[12],a[13],a[14],a[15]);
|
---|
33 | /* Replace longest /(^0|:)[:0]{2,}/ with "::" */
|
---|
34 | for (i=best=0, max=2; buf[i]; i++) {
|
---|
35 | if (i && buf[i] != ':') continue;
|
---|
36 | j = strspn(buf+i, ":0");
|
---|
37 | if (j>max) best=i, max=j;
|
---|
38 | }
|
---|
39 | if (max>2) {
|
---|
40 | buf[best] = buf[best+1] = ':';
|
---|
41 | memmove(buf+best+2, buf+best+max, i-best-max+1);
|
---|
42 | }
|
---|
43 | if (strlen(buf) < l) {
|
---|
44 | strcpy(s, buf);
|
---|
45 | return s;
|
---|
46 | }
|
---|
47 | break;
|
---|
48 | default:
|
---|
49 | errno = EAFNOSUPPORT;
|
---|
50 | return 0;
|
---|
51 | }
|
---|
52 | errno = ENOSPC;
|
---|
53 | return 0;
|
---|
54 | }
|
---|