1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1985-2008 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 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 45 int 46 strtoip6(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 a = 0; 191 if (c == PFX) 192 while ((c = lex[*((unsigned char*)s++)]) < 10) 193 a = a * 10 + c; 194 *bits = a; 195 } 196 } 197 if (e) 198 *e = (char*)(s - 1); 199 return c == END ? 0 : -1; 200 } 201