Libinfo-173.tar.gz
[apple/libinfo.git] / gen.subproj / inet_ntop.c
1
2 #include <sys/types.h>
3 #include <netinet/in.h>
4 #include <arpa/inet.h>
5 #include <stdio.h>
6 #include <stdint.h>
7 #include <string.h>
8 #include <sys/socket.h>
9
10 void __res_close()
11 {
12 }
13
14 #define MAX_V6_ADDR_LEN 64
15
16 static const char *hexchars = "0123456789abcdef";
17
18 const char *
19 inet_ntop6(const struct in6_addr *addr, char *dst, size_t size)
20 {
21 char hexa[8][5], tmp[MAX_V6_ADDR_LEN];
22 int zr[8];
23 size_t len;
24 int32_t i, j, k, skip;
25 uint8_t x8, hx8;
26 uint16_t x16;
27 struct in_addr a4;
28
29 if (addr == NULL) return NULL;
30
31 memset(tmp, 0, MAX_V6_ADDR_LEN);
32
33 /* check for mapped or compat addresses */
34 i = IN6_IS_ADDR_V4MAPPED(addr);
35 j = IN6_IS_ADDR_V4COMPAT(addr);
36 if ((i != 0) || (j != 0))
37 {
38 a4.s_addr = addr->__u6_addr.__u6_addr32[3];
39 sprintf(tmp, "::%s%s", (i != 0) ? "ffff:" : "", inet_ntoa(a4));
40 len = strlen(tmp) + 1;
41 if (len > size) return NULL;
42 memcpy(dst, tmp, len);
43 return dst;
44 }
45
46 k = 0;
47 for (i = 0; i < 16; i += 2)
48 {
49 j = 0;
50 skip = 1;
51
52 memset(hexa[k], 0, 5);
53
54 x8 = addr->__u6_addr.__u6_addr8[i];
55
56 hx8 = x8 >> 4;
57 if (hx8 != 0)
58 {
59 skip = 0;
60 hexa[k][j++] = hexchars[hx8];
61 }
62
63 hx8 = x8 & 0x0f;
64 if ((skip == 0) || ((skip == 1) && (hx8 != 0)))
65 {
66 skip = 0;
67 hexa[k][j++] = hexchars[hx8];
68 }
69
70 x8 = addr->__u6_addr.__u6_addr8[i + 1];
71
72 hx8 = x8 >> 4;
73 if ((skip == 0) || ((skip == 1) && (hx8 != 0)))
74 {
75 hexa[k][j++] = hexchars[hx8];
76 }
77
78 hx8 = x8 & 0x0f;
79 hexa[k][j++] = hexchars[hx8];
80
81 k++;
82 }
83
84 /* find runs of zeros for :: convention */
85 j = 0;
86 for (i = 7; i >= 0; i--)
87 {
88 zr[i] = j;
89 x16 = addr->__u6_addr.__u6_addr16[i];
90 if (x16 == 0) j++;
91 else j = 0;
92 zr[i] = j;
93 }
94
95 /* find longest run of zeros */
96 k = -1;
97 j = 0;
98 for(i = 0; i < 8; i++)
99 {
100 if (zr[i] > j)
101 {
102 k = i;
103 j = zr[i];
104 }
105 }
106
107 for(i = 0; i < 8; i++)
108 {
109 if (i != k) zr[i] = 0;
110 }
111
112 len = 0;
113 for (i = 0; i < 8; i++)
114 {
115 if (zr[i] != 0)
116 {
117 /* check for leading zero */
118 if (i == 0) tmp[len++] = ':';
119 tmp[len++] = ':';
120 i += (zr[i] - 1);
121 continue;
122 }
123 for (j = 0; hexa[i][j] != '\0'; j++) tmp[len++] = hexa[i][j];
124 if (i != 7) tmp[len++] = ':';
125 }
126
127 /* trailing NULL */
128 len++;
129
130 if (len > size) return NULL;
131 memcpy(dst, tmp, len);
132 return dst;
133 }
134
135 const char *
136 inet_ntop4(const struct in_addr *addr, char *buf, size_t len)
137 {
138 const u_int8_t *ap = (u_int8_t *)&addr->s_addr;
139 int i;
140 char *bp=buf;
141
142 for (i = 0; i < 4; i++, ap++)
143 {
144 if (bp >= buf + len - 1)
145 {
146 buf[len-1] = 0;
147 return buf;
148 }
149
150 sprintf(bp, "%d", *ap);
151 bp += strlen(bp);
152 if (i != 3) *bp++='.';
153 }
154
155 *bp = 0;
156 return buf;
157 }
158
159 const char *
160 inet_ntop(int af, const void *addr, char *buf, size_t len)
161 {
162 if(af==AF_INET6)
163 return inet_ntop6(addr, buf, len);
164 if(af==AF_INET)
165 return inet_ntop4(addr, buf, len);
166 return NULL;
167 }