/*********************************************************************** * * * This software is part of the ast package * * Copyright (c) 1985-2010 AT&T Intellectual Property * * and is licensed under the * * Common Public License, Version 1.0 * * by AT&T Intellectual Property * * * * A copy of the License is available at * * http://www.opensource.org/licenses/cpl1.0.txt * * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * * * * Information and Software Systems Research * * AT&T Research * * Florham Park NJ * * * * Glenn Fowler * * David Korn * * Phong Vo * * * ***********************************************************************/ #pragma prototyped #if _PACKAGE_ast #include #endif #include #if !_PACKAGE_ast /* * return a pointer to n bytes from a circular re-use buffer */ static char* fmtbuf(int n) { char* b; static char buf[1024]; static char* p = buf; if ((&buf[sizeof(buf)] - p) < n) p = buf; b = p; p += n; return b; } #endif /* * copy p to s, then convert 0<=n<=999 to text * next char in s returned * caller ensures that s can take strlen(p)+3 bytes */ static char* dec(char* s, char* p, int n) { while (*s = *p++) s++; if (n >= 100) *s++ = '0' + ((n / 100) % 10); if (n >= 10) *s++ = '0' + ((n / 10) % 10); *s++ = '0' + (n % 10); return s; } /* * return pointer to normalized ipv6 address addr * with optional prefix bits if 0 < bits <= 128 * return value in short-term circular buffer */ char* fmtip6(unsigned char* addr, int bits) { register unsigned char* a = addr; register int n = IP6ADDR; register int i; register int z; register int k; register int m; unsigned char r[IP6ADDR]; char* b; char* s; static const char dig[] = "0123456789ABCDEF"; s = b = fmtbuf(44); r[m = z = 0] = 0; if (a[0] == 0x20 && a[1] == 0x02 && (a[2] || a[3] || a[4] || a[5])) { z = 6; s = dec(s, "2002:", a[2]); s = dec(s, ".", a[3]); s = dec(s, ".", a[4]); s = dec(s, ".", a[5]); } for (i = z; i < n; i += 2) { for (k = i; i < n - 1 && !a[i] && !a[i + 1]; i += 2); if ((r[k] = i - k) > r[m] || r[k] == r[m] && i >= (n - 1)) m = k; } if (!m) switch (r[m]) { case 0: m = -1; break; case 14: if (!a[14] && a[15] <= 15) break; /*FALLTHROUGH*/ case 12: s = dec(s, "::", a[12]); s = dec(s, ".", a[13]); s = dec(s, ".", a[14]); s = dec(s, ".", a[15]); n = 0; break; case 10: if (a[10] == 0xFF && a[11] == 0xFF) { s = dec(s, "::FFFF:", a[12]); s = dec(s, ".", a[13]); s = dec(s, ".", a[14]); s = dec(s, ".", a[15]); n = 0; } break; } for (i = z; i < n; i++) { if (i == m) { *s++ = ':'; *s++ = ':'; if ((i += r[m]) >= n) { z = 1; break; } z = 0; } else if (i && !(i & 1)) { if (z) z = 0; else *s++ = '0'; *s++ = ':'; } if ((k = (a[i] >> 4) & 0xf) || z) { z = 1; *s++ = dig[k]; } if ((k = a[i] & 0xf) || z) { z = 1; *s++ = dig[k]; } } if (!z && *(s - 1) == ':') *s++ = '0'; if (bits > 0 && bits <= 128) s = dec(s, "/", bits); *s = 0; return b; }