1*8462SApril.Chin@Sun.COM /***********************************************************************
2*8462SApril.Chin@Sun.COM *                                                                      *
3*8462SApril.Chin@Sun.COM *               This software is part of the ast package               *
4*8462SApril.Chin@Sun.COM *          Copyright (c) 1985-2008 AT&T Intellectual Property          *
5*8462SApril.Chin@Sun.COM *                      and is licensed under the                       *
6*8462SApril.Chin@Sun.COM *                  Common Public License, Version 1.0                  *
7*8462SApril.Chin@Sun.COM *                    by AT&T Intellectual Property                     *
8*8462SApril.Chin@Sun.COM *                                                                      *
9*8462SApril.Chin@Sun.COM *                A copy of the License is available at                 *
10*8462SApril.Chin@Sun.COM *            http://www.opensource.org/licenses/cpl1.0.txt             *
11*8462SApril.Chin@Sun.COM *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
12*8462SApril.Chin@Sun.COM *                                                                      *
13*8462SApril.Chin@Sun.COM *              Information and Software Systems Research               *
14*8462SApril.Chin@Sun.COM *                            AT&T Research                             *
15*8462SApril.Chin@Sun.COM *                           Florham Park NJ                            *
16*8462SApril.Chin@Sun.COM *                                                                      *
17*8462SApril.Chin@Sun.COM *                 Glenn Fowler <gsf@research.att.com>                  *
18*8462SApril.Chin@Sun.COM *                  David Korn <dgk@research.att.com>                   *
19*8462SApril.Chin@Sun.COM *                   Phong Vo <kpv@research.att.com>                    *
20*8462SApril.Chin@Sun.COM *                                                                      *
21*8462SApril.Chin@Sun.COM ***********************************************************************/
22*8462SApril.Chin@Sun.COM #pragma prototyped
23*8462SApril.Chin@Sun.COM 
24*8462SApril.Chin@Sun.COM #if _PACKAGE_ast
25*8462SApril.Chin@Sun.COM #include <ast.h>
26*8462SApril.Chin@Sun.COM #else
27*8462SApril.Chin@Sun.COM #include <stdint.h>
28*8462SApril.Chin@Sun.COM #endif
29*8462SApril.Chin@Sun.COM 
30*8462SApril.Chin@Sun.COM #include <ctype.h>
31*8462SApril.Chin@Sun.COM #include <ip6.h>
32*8462SApril.Chin@Sun.COM 
33*8462SApril.Chin@Sun.COM /*
34*8462SApril.Chin@Sun.COM  * convert string to ipv6 network byte order ip address
35*8462SApril.Chin@Sun.COM  * with optional prefix bits
36*8462SApril.Chin@Sun.COM  * pointer to first unused char placed in *e, even on error
37*8462SApril.Chin@Sun.COM  * return 0:ok <0:error
38*8462SApril.Chin@Sun.COM  */
39*8462SApril.Chin@Sun.COM 
40*8462SApril.Chin@Sun.COM #define COL		16
41*8462SApril.Chin@Sun.COM #define DOT		17
42*8462SApril.Chin@Sun.COM #define END		18
43*8462SApril.Chin@Sun.COM #define PFX		19
44*8462SApril.Chin@Sun.COM 
45*8462SApril.Chin@Sun.COM int
46*8462SApril.Chin@Sun.COM strtoip6(register const char* s, char** e, unsigned char* addr, unsigned char* bits)
47*8462SApril.Chin@Sun.COM {
48*8462SApril.Chin@Sun.COM 	register unsigned char*	b = addr;
49*8462SApril.Chin@Sun.COM 	register unsigned char*	x = b + IP6ADDR;
50*8462SApril.Chin@Sun.COM 	register unsigned char*	z;
51*8462SApril.Chin@Sun.COM 	register int		c;
52*8462SApril.Chin@Sun.COM 	register uint32_t	a;
53*8462SApril.Chin@Sun.COM 
54*8462SApril.Chin@Sun.COM 	static unsigned char	lex[256];
55*8462SApril.Chin@Sun.COM 
56*8462SApril.Chin@Sun.COM 	if (!lex[0])
57*8462SApril.Chin@Sun.COM 	{
58*8462SApril.Chin@Sun.COM 		for (c = 0; c < sizeof(lex); ++c)
59*8462SApril.Chin@Sun.COM 			lex[c] = END;
60*8462SApril.Chin@Sun.COM 		lex['0'] = 0;
61*8462SApril.Chin@Sun.COM 		lex['1'] = 1;
62*8462SApril.Chin@Sun.COM 		lex['2'] = 2;
63*8462SApril.Chin@Sun.COM 		lex['3'] = 3;
64*8462SApril.Chin@Sun.COM 		lex['4'] = 4;
65*8462SApril.Chin@Sun.COM 		lex['5'] = 5;
66*8462SApril.Chin@Sun.COM 		lex['6'] = 6;
67*8462SApril.Chin@Sun.COM 		lex['7'] = 7;
68*8462SApril.Chin@Sun.COM 		lex['8'] = 8;
69*8462SApril.Chin@Sun.COM 		lex['9'] = 9;
70*8462SApril.Chin@Sun.COM 		lex['A'] = lex['a'] = 10;
71*8462SApril.Chin@Sun.COM 		lex['B'] = lex['b'] = 11;
72*8462SApril.Chin@Sun.COM 		lex['C'] = lex['c'] = 12;
73*8462SApril.Chin@Sun.COM 		lex['D'] = lex['d'] = 13;
74*8462SApril.Chin@Sun.COM 		lex['E'] = lex['e'] = 14;
75*8462SApril.Chin@Sun.COM 		lex['F'] = lex['f'] = 15;
76*8462SApril.Chin@Sun.COM 		lex[':'] = COL;
77*8462SApril.Chin@Sun.COM 		lex['.'] = DOT;
78*8462SApril.Chin@Sun.COM 		lex['/'] = PFX;
79*8462SApril.Chin@Sun.COM 	}
80*8462SApril.Chin@Sun.COM 	while (isspace(*s))
81*8462SApril.Chin@Sun.COM 		s++;
82*8462SApril.Chin@Sun.COM 	z = 0;
83*8462SApril.Chin@Sun.COM 	a = 0;
84*8462SApril.Chin@Sun.COM 	if (*s)
85*8462SApril.Chin@Sun.COM 		for (;;)
86*8462SApril.Chin@Sun.COM 		{
87*8462SApril.Chin@Sun.COM 			switch (c = lex[*((unsigned char*)s++)])
88*8462SApril.Chin@Sun.COM 			{
89*8462SApril.Chin@Sun.COM 			case END:
90*8462SApril.Chin@Sun.COM 			case PFX:
91*8462SApril.Chin@Sun.COM 				if ((x - b) < 2)
92*8462SApril.Chin@Sun.COM 					break;
93*8462SApril.Chin@Sun.COM 				*b++ = a>>8;
94*8462SApril.Chin@Sun.COM 				*b++ = a;
95*8462SApril.Chin@Sun.COM 				break;
96*8462SApril.Chin@Sun.COM 			case COL:
97*8462SApril.Chin@Sun.COM 				if ((x - b) < 2)
98*8462SApril.Chin@Sun.COM 					break;
99*8462SApril.Chin@Sun.COM 				*b++ = a>>8;
100*8462SApril.Chin@Sun.COM 				*b++ = a;
101*8462SApril.Chin@Sun.COM 				a = 0;
102*8462SApril.Chin@Sun.COM 				if (*s == ':')
103*8462SApril.Chin@Sun.COM 				{
104*8462SApril.Chin@Sun.COM 					if (z)
105*8462SApril.Chin@Sun.COM 					{
106*8462SApril.Chin@Sun.COM 						s--;
107*8462SApril.Chin@Sun.COM 						break;
108*8462SApril.Chin@Sun.COM 					}
109*8462SApril.Chin@Sun.COM 					z = b;
110*8462SApril.Chin@Sun.COM 					if ((c = lex[*((unsigned char*)++s)]) >= 16)
111*8462SApril.Chin@Sun.COM 					{
112*8462SApril.Chin@Sun.COM 						s++;
113*8462SApril.Chin@Sun.COM 						break;
114*8462SApril.Chin@Sun.COM 					}
115*8462SApril.Chin@Sun.COM 				}
116*8462SApril.Chin@Sun.COM 				continue;
117*8462SApril.Chin@Sun.COM 			case DOT:
118*8462SApril.Chin@Sun.COM 				if (b >= x)
119*8462SApril.Chin@Sun.COM 				{
120*8462SApril.Chin@Sun.COM 					s--;
121*8462SApril.Chin@Sun.COM 					break;
122*8462SApril.Chin@Sun.COM 				}
123*8462SApril.Chin@Sun.COM 				*b++ = ((a >> 8) & 0xf) * 100 + ((a >> 4) & 0xf) * 10 + (a & 0xf);
124*8462SApril.Chin@Sun.COM 				a = 0;
125*8462SApril.Chin@Sun.COM 				for (;;)
126*8462SApril.Chin@Sun.COM 				{
127*8462SApril.Chin@Sun.COM 					switch (c = lex[*((unsigned char*)s++)])
128*8462SApril.Chin@Sun.COM 					{
129*8462SApril.Chin@Sun.COM 					case COL:
130*8462SApril.Chin@Sun.COM 					case END:
131*8462SApril.Chin@Sun.COM 					case PFX:
132*8462SApril.Chin@Sun.COM 						if (b < x)
133*8462SApril.Chin@Sun.COM 							*b++ = a;
134*8462SApril.Chin@Sun.COM 						a = 0;
135*8462SApril.Chin@Sun.COM 						break;
136*8462SApril.Chin@Sun.COM 					case DOT:
137*8462SApril.Chin@Sun.COM 						if (b >= x)
138*8462SApril.Chin@Sun.COM 							break;
139*8462SApril.Chin@Sun.COM 						*b++ = a;
140*8462SApril.Chin@Sun.COM 						a = 0;
141*8462SApril.Chin@Sun.COM 						continue;
142*8462SApril.Chin@Sun.COM 					default:
143*8462SApril.Chin@Sun.COM 						a = (a * 10) + c;
144*8462SApril.Chin@Sun.COM 						continue;
145*8462SApril.Chin@Sun.COM 					}
146*8462SApril.Chin@Sun.COM 					break;
147*8462SApril.Chin@Sun.COM 				}
148*8462SApril.Chin@Sun.COM 				if (c == COL)
149*8462SApril.Chin@Sun.COM 				{
150*8462SApril.Chin@Sun.COM 					if (*s == ':')
151*8462SApril.Chin@Sun.COM 					{
152*8462SApril.Chin@Sun.COM 						if (z)
153*8462SApril.Chin@Sun.COM 						{
154*8462SApril.Chin@Sun.COM 							s--;
155*8462SApril.Chin@Sun.COM 							break;
156*8462SApril.Chin@Sun.COM 						}
157*8462SApril.Chin@Sun.COM 						z = b;
158*8462SApril.Chin@Sun.COM 						if ((c = lex[*((unsigned char*)++s)]) >= 16)
159*8462SApril.Chin@Sun.COM 						{
160*8462SApril.Chin@Sun.COM 							s++;
161*8462SApril.Chin@Sun.COM 							break;
162*8462SApril.Chin@Sun.COM 						}
163*8462SApril.Chin@Sun.COM 					}
164*8462SApril.Chin@Sun.COM 					if ((b - addr) == 6 && addr[0] == 0x20 && addr[1] == 0x02)
165*8462SApril.Chin@Sun.COM 						continue;
166*8462SApril.Chin@Sun.COM 				}
167*8462SApril.Chin@Sun.COM 				break;
168*8462SApril.Chin@Sun.COM 			default:
169*8462SApril.Chin@Sun.COM 				a = (a << 4) | c;
170*8462SApril.Chin@Sun.COM 				continue;
171*8462SApril.Chin@Sun.COM 			}
172*8462SApril.Chin@Sun.COM 			break;
173*8462SApril.Chin@Sun.COM 		}
174*8462SApril.Chin@Sun.COM 	if (b == addr)
175*8462SApril.Chin@Sun.COM 		c = END + 1;
176*8462SApril.Chin@Sun.COM 	else
177*8462SApril.Chin@Sun.COM 	{
178*8462SApril.Chin@Sun.COM 		if (z)
179*8462SApril.Chin@Sun.COM 		{
180*8462SApril.Chin@Sun.COM 			while (b > z)
181*8462SApril.Chin@Sun.COM 				*--x = *--b;
182*8462SApril.Chin@Sun.COM 			while (x > z)
183*8462SApril.Chin@Sun.COM 				*--x = 0;
184*8462SApril.Chin@Sun.COM 		}
185*8462SApril.Chin@Sun.COM 		else
186*8462SApril.Chin@Sun.COM 			while (b < x)
187*8462SApril.Chin@Sun.COM 				*b++ = 0;
188*8462SApril.Chin@Sun.COM 		if (bits)
189*8462SApril.Chin@Sun.COM 		{
190*8462SApril.Chin@Sun.COM 			a = 0;
191*8462SApril.Chin@Sun.COM 			if (c == PFX)
192*8462SApril.Chin@Sun.COM 				while ((c = lex[*((unsigned char*)s++)]) < 10)
193*8462SApril.Chin@Sun.COM 					a = a * 10 + c;
194*8462SApril.Chin@Sun.COM 			*bits = a;
195*8462SApril.Chin@Sun.COM 		}
196*8462SApril.Chin@Sun.COM 	}
197*8462SApril.Chin@Sun.COM 	if (e)
198*8462SApril.Chin@Sun.COM 		*e = (char*)(s - 1);
199*8462SApril.Chin@Sun.COM 	return c == END ? 0 : -1;
200*8462SApril.Chin@Sun.COM }
201