This source file includes following definitions.
- rpl_inet_ntop
- inet_ntop
- inet_ntop4
- inet_ntop6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 #include <config.h>
36
37
38 #include <arpa/inet.h>
39
40
41
42 #ifndef IF_LINT
43 # if defined GCC_LINT || defined lint
44 # define IF_LINT(Code) Code
45 # else
46 # define IF_LINT(Code)
47 # endif
48 #endif
49
50 #if HAVE_DECL_INET_NTOP
51
52 # undef inet_ntop
53
54 const char *
55 rpl_inet_ntop (int af, const void *restrict src,
56 char *restrict dst, socklen_t cnt)
57 {
58 return inet_ntop (af, src, dst, cnt);
59 }
60
61 #else
62
63 # include <stdio.h>
64 # include <string.h>
65 # include <errno.h>
66
67 # define NS_IN6ADDRSZ 16
68 # define NS_INT16SZ 2
69
70
71
72
73
74 typedef int verify_int_size[4 <= sizeof (int) ? 1 : -1];
75
76 static const char *inet_ntop4 (const unsigned char *src, char *dst, socklen_t size);
77 # if HAVE_IPV6
78 static const char *inet_ntop6 (const unsigned char *src, char *dst, socklen_t size);
79 # endif
80
81
82
83
84
85
86
87
88
89
90 const char *
91 inet_ntop (int af, const void *restrict src,
92 char *restrict dst, socklen_t cnt)
93 {
94 switch (af)
95 {
96 # if HAVE_IPV4
97 case AF_INET:
98 return (inet_ntop4 (src, dst, cnt));
99 # endif
100
101 # if HAVE_IPV6
102 case AF_INET6:
103 return (inet_ntop6 (src, dst, cnt));
104 # endif
105
106 default:
107 errno = EAFNOSUPPORT;
108 return (NULL);
109 }
110
111 }
112
113
114
115
116
117
118
119
120
121
122
123
124 static const char *
125 inet_ntop4 (const unsigned char *src, char *dst, socklen_t size)
126 {
127 char tmp[sizeof "255.255.255.255"];
128 int len;
129
130 len = sprintf (tmp, "%u.%u.%u.%u", src[0], src[1], src[2], src[3]);
131 if (len < 0)
132 return NULL;
133
134 if (len > size)
135 {
136 errno = ENOSPC;
137 return NULL;
138 }
139
140 return strcpy (dst, tmp);
141 }
142
143 # if HAVE_IPV6
144
145
146
147
148
149
150
151 static const char *
152 inet_ntop6 (const unsigned char *src, char *dst, socklen_t size)
153 {
154
155
156
157
158
159
160
161 char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
162 struct
163 {
164 int base, len;
165 } best, cur;
166 unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ];
167 int i;
168
169
170
171
172
173
174 memset (words, '\0', sizeof words);
175 for (i = 0; i < NS_IN6ADDRSZ; i += 2)
176 words[i / 2] = (src[i] << 8) | src[i + 1];
177 best.base = -1;
178 cur.base = -1;
179 IF_LINT(best.len = 0);
180 IF_LINT(cur.len = 0);
181 for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++)
182 {
183 if (words[i] == 0)
184 {
185 if (cur.base == -1)
186 cur.base = i, cur.len = 1;
187 else
188 cur.len++;
189 }
190 else
191 {
192 if (cur.base != -1)
193 {
194 if (best.base == -1 || cur.len > best.len)
195 best = cur;
196 cur.base = -1;
197 }
198 }
199 }
200 if (cur.base != -1)
201 {
202 if (best.base == -1 || cur.len > best.len)
203 best = cur;
204 }
205 if (best.base != -1 && best.len < 2)
206 best.base = -1;
207
208
209
210
211 tp = tmp;
212 for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++)
213 {
214
215 if (best.base != -1 && i >= best.base && i < (best.base + best.len))
216 {
217 if (i == best.base)
218 *tp++ = ':';
219 continue;
220 }
221
222 if (i != 0)
223 *tp++ = ':';
224
225 if (i == 6 && best.base == 0 &&
226 (best.len == 6 || (best.len == 5 && words[5] == 0xffff)))
227 {
228 if (!inet_ntop4 (src + 12, tp, sizeof tmp - (tp - tmp)))
229 return (NULL);
230 tp += strlen (tp);
231 break;
232 }
233 {
234 int len = sprintf (tp, "%x", words[i]);
235 if (len < 0)
236 return NULL;
237 tp += len;
238 }
239 }
240
241 if (best.base != -1 && (best.base + best.len) ==
242 (NS_IN6ADDRSZ / NS_INT16SZ))
243 *tp++ = ':';
244 *tp++ = '\0';
245
246
247
248
249 if ((socklen_t) (tp - tmp) > size)
250 {
251 errno = ENOSPC;
252 return NULL;
253 }
254
255 return strcpy (dst, tmp);
256 }
257
258 # endif
259
260 #endif