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