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