17c2fbfb3SApril Chin /***********************************************************************
27c2fbfb3SApril Chin *                                                                      *
37c2fbfb3SApril Chin *               This software is part of the ast package               *
4*b30d1939SAndy Fiddaman *          Copyright (c) 1985-2011 AT&T Intellectual Property          *
57c2fbfb3SApril Chin *                      and is licensed under the                       *
6*b30d1939SAndy Fiddaman *                 Eclipse Public License, Version 1.0                  *
77c2fbfb3SApril Chin *                    by AT&T Intellectual Property                     *
87c2fbfb3SApril Chin *                                                                      *
97c2fbfb3SApril Chin *                A copy of the License is available at                 *
10*b30d1939SAndy Fiddaman *          http://www.eclipse.org/org/documents/epl-v10.html           *
11*b30d1939SAndy Fiddaman *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
127c2fbfb3SApril Chin *                                                                      *
137c2fbfb3SApril Chin *              Information and Software Systems Research               *
147c2fbfb3SApril Chin *                            AT&T Research                             *
157c2fbfb3SApril Chin *                           Florham Park NJ                            *
167c2fbfb3SApril Chin *                                                                      *
177c2fbfb3SApril Chin *                 Glenn Fowler <gsf@research.att.com>                  *
187c2fbfb3SApril Chin *                  David Korn <dgk@research.att.com>                   *
197c2fbfb3SApril Chin *                   Phong Vo <kpv@research.att.com>                    *
207c2fbfb3SApril Chin *                                                                      *
217c2fbfb3SApril Chin ***********************************************************************/
227c2fbfb3SApril Chin #pragma prototyped
237c2fbfb3SApril Chin 
247c2fbfb3SApril Chin #if _PACKAGE_ast
257c2fbfb3SApril Chin #include <ast.h>
267c2fbfb3SApril Chin #endif
277c2fbfb3SApril Chin 
287c2fbfb3SApril Chin #include <ip6.h>
297c2fbfb3SApril Chin 
307c2fbfb3SApril Chin #if !_PACKAGE_ast
317c2fbfb3SApril Chin 
327c2fbfb3SApril Chin /*
337c2fbfb3SApril Chin  * return a pointer to n bytes from a circular re-use buffer
347c2fbfb3SApril Chin  */
357c2fbfb3SApril Chin 
367c2fbfb3SApril Chin static char*
fmtbuf(int n)377c2fbfb3SApril Chin fmtbuf(int n)
387c2fbfb3SApril Chin {
397c2fbfb3SApril Chin 	char*		b;
407c2fbfb3SApril Chin 
417c2fbfb3SApril Chin 	static char	buf[1024];
427c2fbfb3SApril Chin 	static char*	p = buf;
437c2fbfb3SApril Chin 
447c2fbfb3SApril Chin 	if ((&buf[sizeof(buf)] - p) < n)
457c2fbfb3SApril Chin 		p = buf;
467c2fbfb3SApril Chin 	b = p;
477c2fbfb3SApril Chin 	p += n;
487c2fbfb3SApril Chin 	return b;
497c2fbfb3SApril Chin }
507c2fbfb3SApril Chin 
517c2fbfb3SApril Chin #endif
527c2fbfb3SApril Chin 
537c2fbfb3SApril Chin /*
547c2fbfb3SApril Chin  * copy p to s, then convert 0<=n<=999 to text
557c2fbfb3SApril Chin  * next char in s returned
567c2fbfb3SApril Chin  * caller ensures that s can take strlen(p)+3 bytes
577c2fbfb3SApril Chin  */
587c2fbfb3SApril Chin 
597c2fbfb3SApril Chin static char*
dec(char * s,char * p,int n)607c2fbfb3SApril Chin dec(char* s, char* p, int n)
617c2fbfb3SApril Chin {
627c2fbfb3SApril Chin 	while (*s = *p++)
637c2fbfb3SApril Chin 		s++;
647c2fbfb3SApril Chin 	if (n >= 100)
657c2fbfb3SApril Chin 		*s++ = '0' + ((n / 100) % 10);
667c2fbfb3SApril Chin 	if (n >= 10)
677c2fbfb3SApril Chin 		*s++ = '0' + ((n / 10) % 10);
687c2fbfb3SApril Chin 	*s++ = '0' + (n % 10);
697c2fbfb3SApril Chin 	return s;
707c2fbfb3SApril Chin }
717c2fbfb3SApril Chin 
727c2fbfb3SApril Chin /*
737c2fbfb3SApril Chin  * return pointer to normalized ipv6 address addr
74*b30d1939SAndy Fiddaman  * with optional prefix bits if 0 <= bits <= 128
757c2fbfb3SApril Chin  * return value in short-term circular buffer
767c2fbfb3SApril Chin  */
777c2fbfb3SApril Chin 
787c2fbfb3SApril Chin char*
fmtip6(const unsigned char * addr,int bits)79*b30d1939SAndy Fiddaman fmtip6(const unsigned char* addr, int bits)
807c2fbfb3SApril Chin {
81*b30d1939SAndy Fiddaman 	register const unsigned char*	a = addr;
82*b30d1939SAndy Fiddaman 	register int			n = IP6ADDR;
83*b30d1939SAndy Fiddaman 	register int			i;
84*b30d1939SAndy Fiddaman 	register int			z;
85*b30d1939SAndy Fiddaman 	register int			k;
86*b30d1939SAndy Fiddaman 	register int			m;
87*b30d1939SAndy Fiddaman 	unsigned char			r[IP6ADDR];
88*b30d1939SAndy Fiddaman 	char*				b;
89*b30d1939SAndy Fiddaman 	char*				s;
907c2fbfb3SApril Chin 
917c2fbfb3SApril Chin 	static const char	dig[] = "0123456789ABCDEF";
927c2fbfb3SApril Chin 
937c2fbfb3SApril Chin 	s = b = fmtbuf(44);
947c2fbfb3SApril Chin 	r[m = z = 0] = 0;
957c2fbfb3SApril Chin 	if (a[0] == 0x20 && a[1] == 0x02 && (a[2] || a[3] || a[4] || a[5]))
967c2fbfb3SApril Chin 	{
977c2fbfb3SApril Chin 		z = 6;
987c2fbfb3SApril Chin 		s = dec(s, "2002:", a[2]);
997c2fbfb3SApril Chin 		s = dec(s, ".", a[3]);
1007c2fbfb3SApril Chin 		s = dec(s, ".", a[4]);
1017c2fbfb3SApril Chin 		s = dec(s, ".", a[5]);
1027c2fbfb3SApril Chin 	}
1037c2fbfb3SApril Chin 	for (i = z; i < n; i += 2)
1047c2fbfb3SApril Chin 	{
1057c2fbfb3SApril Chin 		for (k = i; i < n - 1 && !a[i] && !a[i + 1]; i += 2);
1067c2fbfb3SApril Chin 		if ((r[k] = i - k) > r[m] || r[k] == r[m] && i >= (n - 1))
1077c2fbfb3SApril Chin 			m = k;
1087c2fbfb3SApril Chin 	}
1097c2fbfb3SApril Chin 	if (!m)
1107c2fbfb3SApril Chin 		switch (r[m])
1117c2fbfb3SApril Chin 		{
1127c2fbfb3SApril Chin 		case 0:
1137c2fbfb3SApril Chin 			m = -1;
1147c2fbfb3SApril Chin 			break;
1157c2fbfb3SApril Chin 		case 14:
1167c2fbfb3SApril Chin 			if (!a[14] && a[15] <= 15)
1177c2fbfb3SApril Chin 				break;
1187c2fbfb3SApril Chin 			/*FALLTHROUGH*/
1197c2fbfb3SApril Chin 		case 12:
1207c2fbfb3SApril Chin 			s = dec(s, "::", a[12]);
1217c2fbfb3SApril Chin 			s = dec(s, ".", a[13]);
1227c2fbfb3SApril Chin 			s = dec(s, ".", a[14]);
1237c2fbfb3SApril Chin 			s = dec(s, ".", a[15]);
1247c2fbfb3SApril Chin 			n = 0;
1257c2fbfb3SApril Chin 			break;
1267c2fbfb3SApril Chin 		case 10:
1277c2fbfb3SApril Chin 			if (a[10] == 0xFF && a[11] == 0xFF)
1287c2fbfb3SApril Chin 			{
1297c2fbfb3SApril Chin 				s = dec(s, "::FFFF:", a[12]);
1307c2fbfb3SApril Chin 				s = dec(s, ".", a[13]);
1317c2fbfb3SApril Chin 				s = dec(s, ".", a[14]);
1327c2fbfb3SApril Chin 				s = dec(s, ".", a[15]);
1337c2fbfb3SApril Chin 				n = 0;
1347c2fbfb3SApril Chin 			}
1357c2fbfb3SApril Chin 			break;
1367c2fbfb3SApril Chin 		}
1377c2fbfb3SApril Chin 	for (i = z; i < n; i++)
1387c2fbfb3SApril Chin 	{
1397c2fbfb3SApril Chin 		if (i == m)
1407c2fbfb3SApril Chin 		{
1417c2fbfb3SApril Chin 			*s++ = ':';
1427c2fbfb3SApril Chin 			*s++ = ':';
1437c2fbfb3SApril Chin 			if ((i += r[m]) >= n)
14434f9b3eeSRoland Mainz 			{
14534f9b3eeSRoland Mainz 				z = 1;
1467c2fbfb3SApril Chin 				break;
14734f9b3eeSRoland Mainz 			}
1487c2fbfb3SApril Chin 			z = 0;
1497c2fbfb3SApril Chin 		}
1507c2fbfb3SApril Chin 		else if (i && !(i & 1))
1517c2fbfb3SApril Chin 		{
1527c2fbfb3SApril Chin 			if (z)
1537c2fbfb3SApril Chin 				z = 0;
1547c2fbfb3SApril Chin 			else
1557c2fbfb3SApril Chin 				*s++ = '0';
1567c2fbfb3SApril Chin 			*s++ = ':';
1577c2fbfb3SApril Chin 		}
1587c2fbfb3SApril Chin 		if ((k = (a[i] >> 4) & 0xf) || z)
1597c2fbfb3SApril Chin 		{
1607c2fbfb3SApril Chin 			z = 1;
1617c2fbfb3SApril Chin 			*s++ = dig[k];
1627c2fbfb3SApril Chin 		}
1637c2fbfb3SApril Chin 		if ((k = a[i] & 0xf) || z)
1647c2fbfb3SApril Chin 		{
1657c2fbfb3SApril Chin 			z = 1;
1667c2fbfb3SApril Chin 			*s++ = dig[k];
1677c2fbfb3SApril Chin 		}
1687c2fbfb3SApril Chin 	}
16934f9b3eeSRoland Mainz 	if (!z && *(s - 1) == ':')
17034f9b3eeSRoland Mainz 		*s++ = '0';
171*b30d1939SAndy Fiddaman 	if (bits >= 0 && bits <= 128)
1727c2fbfb3SApril Chin 		s = dec(s, "/", bits);
1737c2fbfb3SApril Chin 	*s = 0;
1747c2fbfb3SApril Chin 	return b;
1757c2fbfb3SApril Chin }
176