import less(1)
[unleashed/tickless.git] / usr / src / lib / libast / common / string / strtoip6.c
blobf4cf8dfbcec16a6ad0e4faa8b27d8e80901b8940
1 /***********************************************************************
2 * *
3 * This software is part of the ast package *
4 * Copyright (c) 1985-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
8 * *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
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
24 #if _PACKAGE_ast
25 #include <ast.h>
26 #else
27 #include <stdint.h>
28 #endif
30 #include <ctype.h>
31 #include <ip6.h>
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
40 #define COL 16
41 #define DOT 17
42 #define END 18
43 #define PFX 19
45 int
46 strtoip6(register const char* s, char** e, unsigned char* addr, unsigned char* bits)
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;
54 static unsigned char lex[256];
56 if (!lex[0])
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;
80 while (isspace(*s))
81 s++;
82 z = 0;
83 a = 0;
84 if (*s)
85 for (;;)
87 switch (c = lex[*((unsigned char*)s++)])
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 == ':')
104 if (z)
106 s--;
107 break;
109 z = b;
110 if ((c = lex[*((unsigned char*)++s)]) >= 16)
112 s++;
113 break;
116 continue;
117 case DOT:
118 if (b >= x)
120 s--;
121 break;
123 *b++ = ((a >> 8) & 0xf) * 100 + ((a >> 4) & 0xf) * 10 + (a & 0xf);
124 a = 0;
125 for (;;)
127 switch (c = lex[*((unsigned char*)s++)])
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;
146 break;
148 if (c == COL)
150 if (*s == ':')
152 if (z)
154 s--;
155 break;
157 z = b;
158 if ((c = lex[*((unsigned char*)++s)]) >= 16)
160 s++;
161 break;
164 if ((b - addr) == 6 && addr[0] == 0x20 && addr[1] == 0x02)
165 continue;
167 break;
168 default:
169 a = (a << 4) | c;
170 continue;
172 break;
174 if (b == addr)
175 c = END + 1;
176 else
178 if (z)
180 while (b > z)
181 *--x = *--b;
182 while (x > z)
183 *--x = 0;
185 else
186 while (b < x)
187 *b++ = 0;
188 if (bits)
190 a = 0;
191 if (c == PFX)
192 while ((c = lex[*((unsigned char*)s++)]) < 10)
193 a = a * 10 + c;
194 *bits = a;
197 if (e)
198 *e = (char*)(s - 1);
199 return c == END ? 0 : -1;