xref: /onnv-gate/usr/src/lib/libast/common/string/strtoip6.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 #else
278462SApril.Chin@Sun.COM #include <stdint.h>
288462SApril.Chin@Sun.COM #endif
298462SApril.Chin@Sun.COM 
308462SApril.Chin@Sun.COM #include <ctype.h>
318462SApril.Chin@Sun.COM #include <ip6.h>
328462SApril.Chin@Sun.COM 
338462SApril.Chin@Sun.COM /*
348462SApril.Chin@Sun.COM  * convert string to ipv6 network byte order ip address
358462SApril.Chin@Sun.COM  * with optional prefix bits
368462SApril.Chin@Sun.COM  * pointer to first unused char placed in *e, even on error
378462SApril.Chin@Sun.COM  * return 0:ok <0:error
388462SApril.Chin@Sun.COM  */
398462SApril.Chin@Sun.COM 
408462SApril.Chin@Sun.COM #define COL		16
418462SApril.Chin@Sun.COM #define DOT		17
428462SApril.Chin@Sun.COM #define END		18
438462SApril.Chin@Sun.COM #define PFX		19
448462SApril.Chin@Sun.COM 
458462SApril.Chin@Sun.COM int
strtoip6(register const char * s,char ** e,unsigned char * addr,unsigned char * bits)468462SApril.Chin@Sun.COM strtoip6(register const char* s, char** e, unsigned char* addr, unsigned char* bits)
478462SApril.Chin@Sun.COM {
488462SApril.Chin@Sun.COM 	register unsigned char*	b = addr;
498462SApril.Chin@Sun.COM 	register unsigned char*	x = b + IP6ADDR;
508462SApril.Chin@Sun.COM 	register unsigned char*	z;
518462SApril.Chin@Sun.COM 	register int		c;
528462SApril.Chin@Sun.COM 	register uint32_t	a;
538462SApril.Chin@Sun.COM 
548462SApril.Chin@Sun.COM 	static unsigned char	lex[256];
558462SApril.Chin@Sun.COM 
568462SApril.Chin@Sun.COM 	if (!lex[0])
578462SApril.Chin@Sun.COM 	{
588462SApril.Chin@Sun.COM 		for (c = 0; c < sizeof(lex); ++c)
598462SApril.Chin@Sun.COM 			lex[c] = END;
608462SApril.Chin@Sun.COM 		lex['0'] = 0;
618462SApril.Chin@Sun.COM 		lex['1'] = 1;
628462SApril.Chin@Sun.COM 		lex['2'] = 2;
638462SApril.Chin@Sun.COM 		lex['3'] = 3;
648462SApril.Chin@Sun.COM 		lex['4'] = 4;
658462SApril.Chin@Sun.COM 		lex['5'] = 5;
668462SApril.Chin@Sun.COM 		lex['6'] = 6;
678462SApril.Chin@Sun.COM 		lex['7'] = 7;
688462SApril.Chin@Sun.COM 		lex['8'] = 8;
698462SApril.Chin@Sun.COM 		lex['9'] = 9;
708462SApril.Chin@Sun.COM 		lex['A'] = lex['a'] = 10;
718462SApril.Chin@Sun.COM 		lex['B'] = lex['b'] = 11;
728462SApril.Chin@Sun.COM 		lex['C'] = lex['c'] = 12;
738462SApril.Chin@Sun.COM 		lex['D'] = lex['d'] = 13;
748462SApril.Chin@Sun.COM 		lex['E'] = lex['e'] = 14;
758462SApril.Chin@Sun.COM 		lex['F'] = lex['f'] = 15;
768462SApril.Chin@Sun.COM 		lex[':'] = COL;
778462SApril.Chin@Sun.COM 		lex['.'] = DOT;
788462SApril.Chin@Sun.COM 		lex['/'] = PFX;
798462SApril.Chin@Sun.COM 	}
808462SApril.Chin@Sun.COM 	while (isspace(*s))
818462SApril.Chin@Sun.COM 		s++;
828462SApril.Chin@Sun.COM 	z = 0;
838462SApril.Chin@Sun.COM 	a = 0;
848462SApril.Chin@Sun.COM 	if (*s)
858462SApril.Chin@Sun.COM 		for (;;)
868462SApril.Chin@Sun.COM 		{
878462SApril.Chin@Sun.COM 			switch (c = lex[*((unsigned char*)s++)])
888462SApril.Chin@Sun.COM 			{
898462SApril.Chin@Sun.COM 			case END:
908462SApril.Chin@Sun.COM 			case PFX:
918462SApril.Chin@Sun.COM 				if ((x - b) < 2)
928462SApril.Chin@Sun.COM 					break;
938462SApril.Chin@Sun.COM 				*b++ = a>>8;
948462SApril.Chin@Sun.COM 				*b++ = a;
958462SApril.Chin@Sun.COM 				break;
968462SApril.Chin@Sun.COM 			case COL:
978462SApril.Chin@Sun.COM 				if ((x - b) < 2)
988462SApril.Chin@Sun.COM 					break;
998462SApril.Chin@Sun.COM 				*b++ = a>>8;
1008462SApril.Chin@Sun.COM 				*b++ = a;
1018462SApril.Chin@Sun.COM 				a = 0;
1028462SApril.Chin@Sun.COM 				if (*s == ':')
1038462SApril.Chin@Sun.COM 				{
1048462SApril.Chin@Sun.COM 					if (z)
1058462SApril.Chin@Sun.COM 					{
1068462SApril.Chin@Sun.COM 						s--;
1078462SApril.Chin@Sun.COM 						break;
1088462SApril.Chin@Sun.COM 					}
1098462SApril.Chin@Sun.COM 					z = b;
1108462SApril.Chin@Sun.COM 					if ((c = lex[*((unsigned char*)++s)]) >= 16)
1118462SApril.Chin@Sun.COM 					{
1128462SApril.Chin@Sun.COM 						s++;
1138462SApril.Chin@Sun.COM 						break;
1148462SApril.Chin@Sun.COM 					}
1158462SApril.Chin@Sun.COM 				}
1168462SApril.Chin@Sun.COM 				continue;
1178462SApril.Chin@Sun.COM 			case DOT:
1188462SApril.Chin@Sun.COM 				if (b >= x)
1198462SApril.Chin@Sun.COM 				{
1208462SApril.Chin@Sun.COM 					s--;
1218462SApril.Chin@Sun.COM 					break;
1228462SApril.Chin@Sun.COM 				}
1238462SApril.Chin@Sun.COM 				*b++ = ((a >> 8) & 0xf) * 100 + ((a >> 4) & 0xf) * 10 + (a & 0xf);
1248462SApril.Chin@Sun.COM 				a = 0;
1258462SApril.Chin@Sun.COM 				for (;;)
1268462SApril.Chin@Sun.COM 				{
1278462SApril.Chin@Sun.COM 					switch (c = lex[*((unsigned char*)s++)])
1288462SApril.Chin@Sun.COM 					{
1298462SApril.Chin@Sun.COM 					case COL:
1308462SApril.Chin@Sun.COM 					case END:
1318462SApril.Chin@Sun.COM 					case PFX:
1328462SApril.Chin@Sun.COM 						if (b < x)
1338462SApril.Chin@Sun.COM 							*b++ = a;
1348462SApril.Chin@Sun.COM 						a = 0;
1358462SApril.Chin@Sun.COM 						break;
1368462SApril.Chin@Sun.COM 					case DOT:
1378462SApril.Chin@Sun.COM 						if (b >= x)
1388462SApril.Chin@Sun.COM 							break;
1398462SApril.Chin@Sun.COM 						*b++ = a;
1408462SApril.Chin@Sun.COM 						a = 0;
1418462SApril.Chin@Sun.COM 						continue;
1428462SApril.Chin@Sun.COM 					default:
1438462SApril.Chin@Sun.COM 						a = (a * 10) + c;
1448462SApril.Chin@Sun.COM 						continue;
1458462SApril.Chin@Sun.COM 					}
1468462SApril.Chin@Sun.COM 					break;
1478462SApril.Chin@Sun.COM 				}
1488462SApril.Chin@Sun.COM 				if (c == COL)
1498462SApril.Chin@Sun.COM 				{
1508462SApril.Chin@Sun.COM 					if (*s == ':')
1518462SApril.Chin@Sun.COM 					{
1528462SApril.Chin@Sun.COM 						if (z)
1538462SApril.Chin@Sun.COM 						{
1548462SApril.Chin@Sun.COM 							s--;
1558462SApril.Chin@Sun.COM 							break;
1568462SApril.Chin@Sun.COM 						}
1578462SApril.Chin@Sun.COM 						z = b;
1588462SApril.Chin@Sun.COM 						if ((c = lex[*((unsigned char*)++s)]) >= 16)
1598462SApril.Chin@Sun.COM 						{
1608462SApril.Chin@Sun.COM 							s++;
1618462SApril.Chin@Sun.COM 							break;
1628462SApril.Chin@Sun.COM 						}
1638462SApril.Chin@Sun.COM 					}
1648462SApril.Chin@Sun.COM 					if ((b - addr) == 6 && addr[0] == 0x20 && addr[1] == 0x02)
1658462SApril.Chin@Sun.COM 						continue;
1668462SApril.Chin@Sun.COM 				}
1678462SApril.Chin@Sun.COM 				break;
1688462SApril.Chin@Sun.COM 			default:
1698462SApril.Chin@Sun.COM 				a = (a << 4) | c;
1708462SApril.Chin@Sun.COM 				continue;
1718462SApril.Chin@Sun.COM 			}
1728462SApril.Chin@Sun.COM 			break;
1738462SApril.Chin@Sun.COM 		}
1748462SApril.Chin@Sun.COM 	if (b == addr)
1758462SApril.Chin@Sun.COM 		c = END + 1;
1768462SApril.Chin@Sun.COM 	else
1778462SApril.Chin@Sun.COM 	{
1788462SApril.Chin@Sun.COM 		if (z)
1798462SApril.Chin@Sun.COM 		{
1808462SApril.Chin@Sun.COM 			while (b > z)
1818462SApril.Chin@Sun.COM 				*--x = *--b;
1828462SApril.Chin@Sun.COM 			while (x > z)
1838462SApril.Chin@Sun.COM 				*--x = 0;
1848462SApril.Chin@Sun.COM 		}
1858462SApril.Chin@Sun.COM 		else
1868462SApril.Chin@Sun.COM 			while (b < x)
1878462SApril.Chin@Sun.COM 				*b++ = 0;
1888462SApril.Chin@Sun.COM 		if (bits)
1898462SApril.Chin@Sun.COM 		{
1908462SApril.Chin@Sun.COM 			a = 0;
1918462SApril.Chin@Sun.COM 			if (c == PFX)
1928462SApril.Chin@Sun.COM 				while ((c = lex[*((unsigned char*)s++)]) < 10)
1938462SApril.Chin@Sun.COM 					a = a * 10 + c;
1948462SApril.Chin@Sun.COM 			*bits = a;
1958462SApril.Chin@Sun.COM 		}
1968462SApril.Chin@Sun.COM 	}
1978462SApril.Chin@Sun.COM 	if (e)
1988462SApril.Chin@Sun.COM 		*e = (char*)(s - 1);
1998462SApril.Chin@Sun.COM 	return c == END ? 0 : -1;
2008462SApril.Chin@Sun.COM }
201