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 #else
277c2fbfb3SApril Chin #include <stdint.h>
287c2fbfb3SApril Chin #endif
297c2fbfb3SApril Chin 
307c2fbfb3SApril Chin #include <ctype.h>
317c2fbfb3SApril Chin #include <ip6.h>
327c2fbfb3SApril Chin 
337c2fbfb3SApril Chin /*
347c2fbfb3SApril Chin  * convert string to ipv6 network byte order ip address
357c2fbfb3SApril Chin  * with optional prefix bits
367c2fbfb3SApril Chin  * pointer to first unused char placed in *e, even on error
377c2fbfb3SApril Chin  * return 0:ok <0:error
387c2fbfb3SApril Chin  */
397c2fbfb3SApril Chin 
407c2fbfb3SApril Chin #define COL		16
417c2fbfb3SApril Chin #define DOT		17
427c2fbfb3SApril Chin #define END		18
437c2fbfb3SApril Chin #define PFX		19
447c2fbfb3SApril Chin 
457c2fbfb3SApril Chin int
strtoip6(register const char * s,char ** e,unsigned char * addr,unsigned char * bits)467c2fbfb3SApril Chin strtoip6(register const char* s, char** e, unsigned char* addr, unsigned char* bits)
477c2fbfb3SApril Chin {
487c2fbfb3SApril Chin 	register unsigned char*	b = addr;
497c2fbfb3SApril Chin 	register unsigned char*	x = b + IP6ADDR;
507c2fbfb3SApril Chin 	register unsigned char*	z;
517c2fbfb3SApril Chin 	register int		c;
527c2fbfb3SApril Chin 	register uint32_t	a;
537c2fbfb3SApril Chin 
547c2fbfb3SApril Chin 	static unsigned char	lex[256];
557c2fbfb3SApril Chin 
567c2fbfb3SApril Chin 	if (!lex[0])
577c2fbfb3SApril Chin 	{
587c2fbfb3SApril Chin 		for (c = 0; c < sizeof(lex); ++c)
597c2fbfb3SApril Chin 			lex[c] = END;
607c2fbfb3SApril Chin 		lex['0'] = 0;
617c2fbfb3SApril Chin 		lex['1'] = 1;
627c2fbfb3SApril Chin 		lex['2'] = 2;
637c2fbfb3SApril Chin 		lex['3'] = 3;
647c2fbfb3SApril Chin 		lex['4'] = 4;
657c2fbfb3SApril Chin 		lex['5'] = 5;
667c2fbfb3SApril Chin 		lex['6'] = 6;
677c2fbfb3SApril Chin 		lex['7'] = 7;
687c2fbfb3SApril Chin 		lex['8'] = 8;
697c2fbfb3SApril Chin 		lex['9'] = 9;
707c2fbfb3SApril Chin 		lex['A'] = lex['a'] = 10;
717c2fbfb3SApril Chin 		lex['B'] = lex['b'] = 11;
727c2fbfb3SApril Chin 		lex['C'] = lex['c'] = 12;
737c2fbfb3SApril Chin 		lex['D'] = lex['d'] = 13;
747c2fbfb3SApril Chin 		lex['E'] = lex['e'] = 14;
757c2fbfb3SApril Chin 		lex['F'] = lex['f'] = 15;
767c2fbfb3SApril Chin 		lex[':'] = COL;
777c2fbfb3SApril Chin 		lex['.'] = DOT;
787c2fbfb3SApril Chin 		lex['/'] = PFX;
797c2fbfb3SApril Chin 	}
807c2fbfb3SApril Chin 	while (isspace(*s))
817c2fbfb3SApril Chin 		s++;
827c2fbfb3SApril Chin 	z = 0;
837c2fbfb3SApril Chin 	a = 0;
847c2fbfb3SApril Chin 	if (*s)
857c2fbfb3SApril Chin 		for (;;)
867c2fbfb3SApril Chin 		{
877c2fbfb3SApril Chin 			switch (c = lex[*((unsigned char*)s++)])
887c2fbfb3SApril Chin 			{
897c2fbfb3SApril Chin 			case END:
907c2fbfb3SApril Chin 			case PFX:
917c2fbfb3SApril Chin 				if ((x - b) < 2)
927c2fbfb3SApril Chin 					break;
937c2fbfb3SApril Chin 				*b++ = a>>8;
947c2fbfb3SApril Chin 				*b++ = a;
957c2fbfb3SApril Chin 				break;
967c2fbfb3SApril Chin 			case COL:
977c2fbfb3SApril Chin 				if ((x - b) < 2)
987c2fbfb3SApril Chin 					break;
997c2fbfb3SApril Chin 				*b++ = a>>8;
1007c2fbfb3SApril Chin 				*b++ = a;
1017c2fbfb3SApril Chin 				a = 0;
1027c2fbfb3SApril Chin 				if (*s == ':')
1037c2fbfb3SApril Chin 				{
1047c2fbfb3SApril Chin 					if (z)
1057c2fbfb3SApril Chin 					{
1067c2fbfb3SApril Chin 						s--;
1077c2fbfb3SApril Chin 						break;
1087c2fbfb3SApril Chin 					}
1097c2fbfb3SApril Chin 					z = b;
1107c2fbfb3SApril Chin 					if ((c = lex[*((unsigned char*)++s)]) >= 16)
1117c2fbfb3SApril Chin 					{
1127c2fbfb3SApril Chin 						s++;
1137c2fbfb3SApril Chin 						break;
1147c2fbfb3SApril Chin 					}
1157c2fbfb3SApril Chin 				}
1167c2fbfb3SApril Chin 				continue;
1177c2fbfb3SApril Chin 			case DOT:
1187c2fbfb3SApril Chin 				if (b >= x)
1197c2fbfb3SApril Chin 				{
1207c2fbfb3SApril Chin 					s--;
1217c2fbfb3SApril Chin 					break;
1227c2fbfb3SApril Chin 				}
1237c2fbfb3SApril Chin 				*b++ = ((a >> 8) & 0xf) * 100 + ((a >> 4) & 0xf) * 10 + (a & 0xf);
1247c2fbfb3SApril Chin 				a = 0;
1257c2fbfb3SApril Chin 				for (;;)
1267c2fbfb3SApril Chin 				{
1277c2fbfb3SApril Chin 					switch (c = lex[*((unsigned char*)s++)])
1287c2fbfb3SApril Chin 					{
1297c2fbfb3SApril Chin 					case COL:
1307c2fbfb3SApril Chin 					case END:
1317c2fbfb3SApril Chin 					case PFX:
1327c2fbfb3SApril Chin 						if (b < x)
1337c2fbfb3SApril Chin 							*b++ = a;
1347c2fbfb3SApril Chin 						a = 0;
1357c2fbfb3SApril Chin 						break;
1367c2fbfb3SApril Chin 					case DOT:
1377c2fbfb3SApril Chin 						if (b >= x)
1387c2fbfb3SApril Chin 							break;
1397c2fbfb3SApril Chin 						*b++ = a;
1407c2fbfb3SApril Chin 						a = 0;
1417c2fbfb3SApril Chin 						continue;
1427c2fbfb3SApril Chin 					default:
1437c2fbfb3SApril Chin 						a = (a * 10) + c;
1447c2fbfb3SApril Chin 						continue;
1457c2fbfb3SApril Chin 					}
1467c2fbfb3SApril Chin 					break;
1477c2fbfb3SApril Chin 				}
1487c2fbfb3SApril Chin 				if (c == COL)
1497c2fbfb3SApril Chin 				{
1507c2fbfb3SApril Chin 					if (*s == ':')
1517c2fbfb3SApril Chin 					{
1527c2fbfb3SApril Chin 						if (z)
1537c2fbfb3SApril Chin 						{
1547c2fbfb3SApril Chin 							s--;
1557c2fbfb3SApril Chin 							break;
1567c2fbfb3SApril Chin 						}
1577c2fbfb3SApril Chin 						z = b;
1587c2fbfb3SApril Chin 						if ((c = lex[*((unsigned char*)++s)]) >= 16)
1597c2fbfb3SApril Chin 						{
1607c2fbfb3SApril Chin 							s++;
1617c2fbfb3SApril Chin 							break;
1627c2fbfb3SApril Chin 						}
1637c2fbfb3SApril Chin 					}
1647c2fbfb3SApril Chin 					if ((b - addr) == 6 && addr[0] == 0x20 && addr[1] == 0x02)
1657c2fbfb3SApril Chin 						continue;
1667c2fbfb3SApril Chin 				}
1677c2fbfb3SApril Chin 				break;
1687c2fbfb3SApril Chin 			default:
1697c2fbfb3SApril Chin 				a = (a << 4) | c;
1707c2fbfb3SApril Chin 				continue;
1717c2fbfb3SApril Chin 			}
1727c2fbfb3SApril Chin 			break;
1737c2fbfb3SApril Chin 		}
1747c2fbfb3SApril Chin 	if (b == addr)
1757c2fbfb3SApril Chin 		c = END + 1;
1767c2fbfb3SApril Chin 	else
1777c2fbfb3SApril Chin 	{
1787c2fbfb3SApril Chin 		if (z)
1797c2fbfb3SApril Chin 		{
1807c2fbfb3SApril Chin 			while (b > z)
1817c2fbfb3SApril Chin 				*--x = *--b;
1827c2fbfb3SApril Chin 			while (x > z)
1837c2fbfb3SApril Chin 				*--x = 0;
1847c2fbfb3SApril Chin 		}
1857c2fbfb3SApril Chin 		else
1867c2fbfb3SApril Chin 			while (b < x)
1877c2fbfb3SApril Chin 				*b++ = 0;
1887c2fbfb3SApril Chin 		if (bits)
1897c2fbfb3SApril Chin 		{
1907c2fbfb3SApril Chin 			if (c == PFX)
191*b30d1939SAndy Fiddaman 			{
192*b30d1939SAndy Fiddaman 				a = 0;
1937c2fbfb3SApril Chin 				while ((c = lex[*((unsigned char*)s++)]) < 10)
1947c2fbfb3SApril Chin 					a = a * 10 + c;
195*b30d1939SAndy Fiddaman 			}
196*b30d1939SAndy Fiddaman 			else
197*b30d1939SAndy Fiddaman 				a = 0xff;
1987c2fbfb3SApril Chin 			*bits = a;
1997c2fbfb3SApril Chin 		}
2007c2fbfb3SApril Chin 	}
2017c2fbfb3SApril Chin 	if (e)
2027c2fbfb3SApril Chin 		*e = (char*)(s - 1);
2037c2fbfb3SApril Chin 	return c == END ? 0 : -1;
2047c2fbfb3SApril Chin }
205