xref: /onnv-gate/usr/src/lib/libast/common/string/fmtip6.c (revision 12068:08a39a083754)
18462SApril.Chin@Sun.COM /***********************************************************************
28462SApril.Chin@Sun.COM *                                                                      *
38462SApril.Chin@Sun.COM *               This software is part of the ast package               *
4*12068SRoger.Faulkner@Oracle.COM *          Copyright (c) 1985-2010 AT&T Intellectual Property          *
58462SApril.Chin@Sun.COM *                      and is licensed under the                       *
68462SApril.Chin@Sun.COM *                  Common Public License, Version 1.0                  *
78462SApril.Chin@Sun.COM *                    by AT&T Intellectual Property                     *
88462SApril.Chin@Sun.COM *                                                                      *
98462SApril.Chin@Sun.COM *                A copy of the License is available at                 *
108462SApril.Chin@Sun.COM *            http://www.opensource.org/licenses/cpl1.0.txt             *
118462SApril.Chin@Sun.COM *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
128462SApril.Chin@Sun.COM *                                                                      *
138462SApril.Chin@Sun.COM *              Information and Software Systems Research               *
148462SApril.Chin@Sun.COM *                            AT&T Research                             *
158462SApril.Chin@Sun.COM *                           Florham Park NJ                            *
168462SApril.Chin@Sun.COM *                                                                      *
178462SApril.Chin@Sun.COM *                 Glenn Fowler <gsf@research.att.com>                  *
188462SApril.Chin@Sun.COM *                  David Korn <dgk@research.att.com>                   *
198462SApril.Chin@Sun.COM *                   Phong Vo <kpv@research.att.com>                    *
208462SApril.Chin@Sun.COM *                                                                      *
218462SApril.Chin@Sun.COM ***********************************************************************/
228462SApril.Chin@Sun.COM #pragma prototyped
238462SApril.Chin@Sun.COM 
248462SApril.Chin@Sun.COM #if _PACKAGE_ast
258462SApril.Chin@Sun.COM #include <ast.h>
268462SApril.Chin@Sun.COM #endif
278462SApril.Chin@Sun.COM 
288462SApril.Chin@Sun.COM #include <ip6.h>
298462SApril.Chin@Sun.COM 
308462SApril.Chin@Sun.COM #if !_PACKAGE_ast
318462SApril.Chin@Sun.COM 
328462SApril.Chin@Sun.COM /*
338462SApril.Chin@Sun.COM  * return a pointer to n bytes from a circular re-use buffer
348462SApril.Chin@Sun.COM  */
358462SApril.Chin@Sun.COM 
368462SApril.Chin@Sun.COM static char*
fmtbuf(int n)378462SApril.Chin@Sun.COM fmtbuf(int n)
388462SApril.Chin@Sun.COM {
398462SApril.Chin@Sun.COM 	char*		b;
408462SApril.Chin@Sun.COM 
418462SApril.Chin@Sun.COM 	static char	buf[1024];
428462SApril.Chin@Sun.COM 	static char*	p = buf;
438462SApril.Chin@Sun.COM 
448462SApril.Chin@Sun.COM 	if ((&buf[sizeof(buf)] - p) < n)
458462SApril.Chin@Sun.COM 		p = buf;
468462SApril.Chin@Sun.COM 	b = p;
478462SApril.Chin@Sun.COM 	p += n;
488462SApril.Chin@Sun.COM 	return b;
498462SApril.Chin@Sun.COM }
508462SApril.Chin@Sun.COM 
518462SApril.Chin@Sun.COM #endif
528462SApril.Chin@Sun.COM 
538462SApril.Chin@Sun.COM /*
548462SApril.Chin@Sun.COM  * copy p to s, then convert 0<=n<=999 to text
558462SApril.Chin@Sun.COM  * next char in s returned
568462SApril.Chin@Sun.COM  * caller ensures that s can take strlen(p)+3 bytes
578462SApril.Chin@Sun.COM  */
588462SApril.Chin@Sun.COM 
598462SApril.Chin@Sun.COM static char*
dec(char * s,char * p,int n)608462SApril.Chin@Sun.COM dec(char* s, char* p, int n)
618462SApril.Chin@Sun.COM {
628462SApril.Chin@Sun.COM 	while (*s = *p++)
638462SApril.Chin@Sun.COM 		s++;
648462SApril.Chin@Sun.COM 	if (n >= 100)
658462SApril.Chin@Sun.COM 		*s++ = '0' + ((n / 100) % 10);
668462SApril.Chin@Sun.COM 	if (n >= 10)
678462SApril.Chin@Sun.COM 		*s++ = '0' + ((n / 10) % 10);
688462SApril.Chin@Sun.COM 	*s++ = '0' + (n % 10);
698462SApril.Chin@Sun.COM 	return s;
708462SApril.Chin@Sun.COM }
718462SApril.Chin@Sun.COM 
728462SApril.Chin@Sun.COM /*
738462SApril.Chin@Sun.COM  * return pointer to normalized ipv6 address addr
748462SApril.Chin@Sun.COM  * with optional prefix bits if 0 < bits <= 128
758462SApril.Chin@Sun.COM  * return value in short-term circular buffer
768462SApril.Chin@Sun.COM  */
778462SApril.Chin@Sun.COM 
788462SApril.Chin@Sun.COM char*
fmtip6(unsigned char * addr,int bits)798462SApril.Chin@Sun.COM fmtip6(unsigned char* addr, int bits)
808462SApril.Chin@Sun.COM {
818462SApril.Chin@Sun.COM 	register unsigned char*	a = addr;
828462SApril.Chin@Sun.COM 	register int		n = IP6ADDR;
838462SApril.Chin@Sun.COM 	register int		i;
848462SApril.Chin@Sun.COM 	register int		z;
858462SApril.Chin@Sun.COM 	register int		k;
868462SApril.Chin@Sun.COM 	register int		m;
878462SApril.Chin@Sun.COM 	unsigned char		r[IP6ADDR];
888462SApril.Chin@Sun.COM 	char*			b;
898462SApril.Chin@Sun.COM 	char*			s;
908462SApril.Chin@Sun.COM 
918462SApril.Chin@Sun.COM 	static const char	dig[] = "0123456789ABCDEF";
928462SApril.Chin@Sun.COM 
938462SApril.Chin@Sun.COM 	s = b = fmtbuf(44);
948462SApril.Chin@Sun.COM 	r[m = z = 0] = 0;
958462SApril.Chin@Sun.COM 	if (a[0] == 0x20 && a[1] == 0x02 && (a[2] || a[3] || a[4] || a[5]))
968462SApril.Chin@Sun.COM 	{
978462SApril.Chin@Sun.COM 		z = 6;
988462SApril.Chin@Sun.COM 		s = dec(s, "2002:", a[2]);
998462SApril.Chin@Sun.COM 		s = dec(s, ".", a[3]);
1008462SApril.Chin@Sun.COM 		s = dec(s, ".", a[4]);
1018462SApril.Chin@Sun.COM 		s = dec(s, ".", a[5]);
1028462SApril.Chin@Sun.COM 	}
1038462SApril.Chin@Sun.COM 	for (i = z; i < n; i += 2)
1048462SApril.Chin@Sun.COM 	{
1058462SApril.Chin@Sun.COM 		for (k = i; i < n - 1 && !a[i] && !a[i + 1]; i += 2);
1068462SApril.Chin@Sun.COM 		if ((r[k] = i - k) > r[m] || r[k] == r[m] && i >= (n - 1))
1078462SApril.Chin@Sun.COM 			m = k;
1088462SApril.Chin@Sun.COM 	}
1098462SApril.Chin@Sun.COM 	if (!m)
1108462SApril.Chin@Sun.COM 		switch (r[m])
1118462SApril.Chin@Sun.COM 		{
1128462SApril.Chin@Sun.COM 		case 0:
1138462SApril.Chin@Sun.COM 			m = -1;
1148462SApril.Chin@Sun.COM 			break;
1158462SApril.Chin@Sun.COM 		case 14:
1168462SApril.Chin@Sun.COM 			if (!a[14] && a[15] <= 15)
1178462SApril.Chin@Sun.COM 				break;
1188462SApril.Chin@Sun.COM 			/*FALLTHROUGH*/
1198462SApril.Chin@Sun.COM 		case 12:
1208462SApril.Chin@Sun.COM 			s = dec(s, "::", a[12]);
1218462SApril.Chin@Sun.COM 			s = dec(s, ".", a[13]);
1228462SApril.Chin@Sun.COM 			s = dec(s, ".", a[14]);
1238462SApril.Chin@Sun.COM 			s = dec(s, ".", a[15]);
1248462SApril.Chin@Sun.COM 			n = 0;
1258462SApril.Chin@Sun.COM 			break;
1268462SApril.Chin@Sun.COM 		case 10:
1278462SApril.Chin@Sun.COM 			if (a[10] == 0xFF && a[11] == 0xFF)
1288462SApril.Chin@Sun.COM 			{
1298462SApril.Chin@Sun.COM 				s = dec(s, "::FFFF:", a[12]);
1308462SApril.Chin@Sun.COM 				s = dec(s, ".", a[13]);
1318462SApril.Chin@Sun.COM 				s = dec(s, ".", a[14]);
1328462SApril.Chin@Sun.COM 				s = dec(s, ".", a[15]);
1338462SApril.Chin@Sun.COM 				n = 0;
1348462SApril.Chin@Sun.COM 			}
1358462SApril.Chin@Sun.COM 			break;
1368462SApril.Chin@Sun.COM 		}
1378462SApril.Chin@Sun.COM 	for (i = z; i < n; i++)
1388462SApril.Chin@Sun.COM 	{
1398462SApril.Chin@Sun.COM 		if (i == m)
1408462SApril.Chin@Sun.COM 		{
1418462SApril.Chin@Sun.COM 			*s++ = ':';
1428462SApril.Chin@Sun.COM 			*s++ = ':';
1438462SApril.Chin@Sun.COM 			if ((i += r[m]) >= n)
14410898Sroland.mainz@nrubsig.org 			{
14510898Sroland.mainz@nrubsig.org 				z = 1;
1468462SApril.Chin@Sun.COM 				break;
14710898Sroland.mainz@nrubsig.org 			}
1488462SApril.Chin@Sun.COM 			z = 0;
1498462SApril.Chin@Sun.COM 		}
1508462SApril.Chin@Sun.COM 		else if (i && !(i & 1))
1518462SApril.Chin@Sun.COM 		{
1528462SApril.Chin@Sun.COM 			if (z)
1538462SApril.Chin@Sun.COM 				z = 0;
1548462SApril.Chin@Sun.COM 			else
1558462SApril.Chin@Sun.COM 				*s++ = '0';
1568462SApril.Chin@Sun.COM 			*s++ = ':';
1578462SApril.Chin@Sun.COM 		}
1588462SApril.Chin@Sun.COM 		if ((k = (a[i] >> 4) & 0xf) || z)
1598462SApril.Chin@Sun.COM 		{
1608462SApril.Chin@Sun.COM 			z = 1;
1618462SApril.Chin@Sun.COM 			*s++ = dig[k];
1628462SApril.Chin@Sun.COM 		}
1638462SApril.Chin@Sun.COM 		if ((k = a[i] & 0xf) || z)
1648462SApril.Chin@Sun.COM 		{
1658462SApril.Chin@Sun.COM 			z = 1;
1668462SApril.Chin@Sun.COM 			*s++ = dig[k];
1678462SApril.Chin@Sun.COM 		}
1688462SApril.Chin@Sun.COM 	}
16910898Sroland.mainz@nrubsig.org 	if (!z && *(s - 1) == ':')
17010898Sroland.mainz@nrubsig.org 		*s++ = '0';
1718462SApril.Chin@Sun.COM 	if (bits > 0 && bits <= 128)
1728462SApril.Chin@Sun.COM 		s = dec(s, "/", bits);
1738462SApril.Chin@Sun.COM 	*s = 0;
1748462SApril.Chin@Sun.COM 	return b;
1758462SApril.Chin@Sun.COM }
176