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