[352] | 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 | }
|
---|