1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1985-2008 AT&T Intellectual Property * 5 * and is licensed under the * 6 * Common Public License, Version 1.0 * 7 * by AT&T Intellectual Property * 8 * * 9 * A copy of the License is available at * 10 * http://www.opensource.org/licenses/cpl1.0.txt * 11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 12 * * 13 * Information and Software Systems Research * 14 * AT&T Research * 15 * Florham Park NJ * 16 * * 17 * Glenn Fowler <gsf@research.att.com> * 18 * David Korn <dgk@research.att.com> * 19 * Phong Vo <kpv@research.att.com> * 20 * * 21 ***********************************************************************/ 22 #pragma prototyped 23 24 #if _PACKAGE_ast 25 #include <ast.h> 26 #endif 27 28 #include <ip6.h> 29 30 #if !_PACKAGE_ast 31 32 /* 33 * return a pointer to n bytes from a circular re-use buffer 34 */ 35 36 static char* 37 fmtbuf(int n) 38 { 39 char* b; 40 41 static char buf[1024]; 42 static char* p = buf; 43 44 if ((&buf[sizeof(buf)] - p) < n) 45 p = buf; 46 b = p; 47 p += n; 48 return b; 49 } 50 51 #endif 52 53 /* 54 * copy p to s, then convert 0<=n<=999 to text 55 * next char in s returned 56 * caller ensures that s can take strlen(p)+3 bytes 57 */ 58 59 static char* 60 dec(char* s, char* p, int n) 61 { 62 while (*s = *p++) 63 s++; 64 if (n >= 100) 65 *s++ = '0' + ((n / 100) % 10); 66 if (n >= 10) 67 *s++ = '0' + ((n / 10) % 10); 68 *s++ = '0' + (n % 10); 69 return s; 70 } 71 72 /* 73 * return pointer to normalized ipv6 address addr 74 * with optional prefix bits if 0 < bits <= 128 75 * return value in short-term circular buffer 76 */ 77 78 char* 79 fmtip6(unsigned char* addr, int bits) 80 { 81 register unsigned char* a = addr; 82 register int n = IP6ADDR; 83 register int i; 84 register int z; 85 register int k; 86 register int m; 87 unsigned char r[IP6ADDR]; 88 char* b; 89 char* s; 90 91 static const char dig[] = "0123456789ABCDEF"; 92 93 s = b = fmtbuf(44); 94 r[m = z = 0] = 0; 95 if (a[0] == 0x20 && a[1] == 0x02 && (a[2] || a[3] || a[4] || a[5])) 96 { 97 z = 6; 98 s = dec(s, "2002:", a[2]); 99 s = dec(s, ".", a[3]); 100 s = dec(s, ".", a[4]); 101 s = dec(s, ".", a[5]); 102 } 103 for (i = z; i < n; i += 2) 104 { 105 for (k = i; i < n - 1 && !a[i] && !a[i + 1]; i += 2); 106 if ((r[k] = i - k) > r[m] || r[k] == r[m] && i >= (n - 1)) 107 m = k; 108 } 109 if (!m) 110 switch (r[m]) 111 { 112 case 0: 113 m = -1; 114 break; 115 case 14: 116 if (!a[14] && a[15] <= 15) 117 break; 118 /*FALLTHROUGH*/ 119 case 12: 120 s = dec(s, "::", a[12]); 121 s = dec(s, ".", a[13]); 122 s = dec(s, ".", a[14]); 123 s = dec(s, ".", a[15]); 124 n = 0; 125 break; 126 case 10: 127 if (a[10] == 0xFF && a[11] == 0xFF) 128 { 129 s = dec(s, "::FFFF:", a[12]); 130 s = dec(s, ".", a[13]); 131 s = dec(s, ".", a[14]); 132 s = dec(s, ".", a[15]); 133 n = 0; 134 } 135 break; 136 } 137 for (i = z; i < n; i++) 138 { 139 if (i == m) 140 { 141 *s++ = ':'; 142 *s++ = ':'; 143 if ((i += r[m]) >= n) 144 break; 145 z = 0; 146 } 147 else if (i && !(i & 1)) 148 { 149 if (z) 150 z = 0; 151 else 152 *s++ = '0'; 153 *s++ = ':'; 154 } 155 if ((k = (a[i] >> 4) & 0xf) || z) 156 { 157 z = 1; 158 *s++ = dig[k]; 159 } 160 if ((k = a[i] & 0xf) || z) 161 { 162 z = 1; 163 *s++ = dig[k]; 164 } 165 } 166 if (bits > 0 && bits <= 128) 167 s = dec(s, "/", bits); 168 *s = 0; 169 return b; 170 } 171