add UNLEASHED_OBJ to unleashed.mk
[unleashed/tickless.git] / usr / src / lib / libast / common / string / fmtip6.c
blob5b1133a12d355eb177ab8901dddcd2d4f4f927bb
1 /***********************************************************************
2 * *
3 * This software is part of the ast package *
4 * Copyright (c) 1985-2010 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
24 #if _PACKAGE_ast
25 #include <ast.h>
26 #endif
28 #include <ip6.h>
30 #if !_PACKAGE_ast
33 * return a pointer to n bytes from a circular re-use buffer
36 static char*
37 fmtbuf(int n)
39 char* b;
41 static char buf[1024];
42 static char* p = buf;
44 if ((&buf[sizeof(buf)] - p) < n)
45 p = buf;
46 b = p;
47 p += n;
48 return b;
51 #endif
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
59 static char*
60 dec(char* s, char* p, int n)
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;
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
78 char*
79 fmtip6(unsigned char* addr, int bits)
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;
91 static const char dig[] = "0123456789ABCDEF";
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]))
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]);
103 for (i = z; i < n; i += 2)
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;
109 if (!m)
110 switch (r[m])
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)
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;
135 break;
137 for (i = z; i < n; i++)
139 if (i == m)
141 *s++ = ':';
142 *s++ = ':';
143 if ((i += r[m]) >= n)
145 z = 1;
146 break;
148 z = 0;
150 else if (i && !(i & 1))
152 if (z)
153 z = 0;
154 else
155 *s++ = '0';
156 *s++ = ':';
158 if ((k = (a[i] >> 4) & 0xf) || z)
160 z = 1;
161 *s++ = dig[k];
163 if ((k = a[i] & 0xf) || z)
165 z = 1;
166 *s++ = dig[k];
169 if (!z && *(s - 1) == ':')
170 *s++ = '0';
171 if (bits > 0 && bits <= 128)
172 s = dec(s, "/", bits);
173 *s = 0;
174 return b;