179{
180 /*
181 * Note that int32_t and int16_t need only be "at least" large enough to
182 * contain a value of the specified size. On some systems, like Crays,
183 * there is no such thing as an integer variable with 16 bits. Keep this
184 * in mind if you think this function should have been coded to use
185 * pointer overlays. All the world's not a VAX.
186 */
187 char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255/128"];
188 char *tp;
189 struct
190 {
191 int base,
196
197 if ((bits < -1) || (bits > 128))
198 {
199 errno = EINVAL;
200 return (NULL);
201 }
202
203 /*
204 * Preprocess: Copy the input (bytewise) array into a wordwise array. Find
205 * the longest run of 0x00's in src[] for :: shorthanding.
206 */
207 memset(words, '0円', sizeof words);
209 words[
i / 2] |= (src[
i] << ((1 - (
i % 2)) << 3));
210 best.base = -1;
212 best.len = 0;
215 {
217 {
220 else
222 }
223 else
224 {
226 {
227 if (best.base == -1 ||
cur.len > best.len)
230 }
231 }
232 }
234 {
235 if (best.base == -1 ||
cur.len > best.len)
237 }
238 if (best.base != -1 && best.len < 2)
239 best.base = -1;
240
241 /*
242 * Format the result.
243 */
244 tp = tmp;
246 {
247 /* Are we inside the best run of 0x00's? */
248 if (best.base != -1 &&
i >= best.base &&
249 i < (best.base + best.len))
250 {
252 *tp++ = ':';
253 continue;
254 }
255 /* Are we following an initial run of 0x00s or any real hex? */
257 *tp++ = ':';
258 /* Is this address an encapsulated IPv4? */
259 if (
i == 6 && best.base == 0 && (best.len == 6 ||
260 (best.len == 7 && words[7] != 0x0001) ||
261 (best.len == 5 && words[5] == 0xffff)))
262 {
263 int n;
264
265 n =
decoct(src + 12, 4, tp,
sizeof tmp - (tp - tmp));
266 if (n == 0)
267 {
269 return (NULL);
270 }
271 tp += strlen(tp);
272 break;
273 }
274 tp +=
SPRINTF((tp,
"%x", words[
i]));
275 }
276
277 /* Was it a trailing run of 0x00's? */
278 if (best.base != -1 && (best.base + best.len) ==
280 *tp++ = ':';
281 *tp = '0円';
282
283 if (bits != -1 && bits != 128)
284 tp +=
SPRINTF((tp,
"/%u", bits));
285
286 /*
287 * Check for overflow, copy, and we're done.
288 */
289 if ((size_t) (tp - tmp) > size)
290 {
292 return (NULL);
293 }
294 strcpy(dst, tmp);
295 return (dst);
296}
static int decoct(const u_char *src, int bytes, char *dst, size_t size)