17c2fbfb3SApril Chin /*********************************************************************** 27c2fbfb3SApril Chin * * 37c2fbfb3SApril Chin * This software is part of the ast package * 4*3e14f97fSRoger A. Faulkner * Copyright (c) 1985-2010 AT&T Intellectual Property * 57c2fbfb3SApril Chin * and is licensed under the * 67c2fbfb3SApril Chin * Common Public License, Version 1.0 * 77c2fbfb3SApril Chin * by AT&T Intellectual Property * 87c2fbfb3SApril Chin * * 97c2fbfb3SApril Chin * A copy of the License is available at * 107c2fbfb3SApril Chin * http://www.opensource.org/licenses/cpl1.0.txt * 117c2fbfb3SApril Chin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 127c2fbfb3SApril Chin * * 137c2fbfb3SApril Chin * Information and Software Systems Research * 147c2fbfb3SApril Chin * AT&T Research * 157c2fbfb3SApril Chin * Florham Park NJ * 167c2fbfb3SApril Chin * * 177c2fbfb3SApril Chin * Glenn Fowler <gsf@research.att.com> * 187c2fbfb3SApril Chin * David Korn <dgk@research.att.com> * 197c2fbfb3SApril Chin * Phong Vo <kpv@research.att.com> * 207c2fbfb3SApril Chin * * 217c2fbfb3SApril Chin ***********************************************************************/ 227c2fbfb3SApril Chin #pragma prototyped 237c2fbfb3SApril Chin 247c2fbfb3SApril Chin #if _PACKAGE_ast 257c2fbfb3SApril Chin #include <ast.h> 267c2fbfb3SApril Chin #else 277c2fbfb3SApril Chin #include <stdint.h> 287c2fbfb3SApril Chin #endif 297c2fbfb3SApril Chin 307c2fbfb3SApril Chin #include <ctype.h> 317c2fbfb3SApril Chin #include <ip6.h> 327c2fbfb3SApril Chin 337c2fbfb3SApril Chin /* 347c2fbfb3SApril Chin * convert string to ipv6 network byte order ip address 357c2fbfb3SApril Chin * with optional prefix bits 367c2fbfb3SApril Chin * pointer to first unused char placed in *e, even on error 377c2fbfb3SApril Chin * return 0:ok <0:error 387c2fbfb3SApril Chin */ 397c2fbfb3SApril Chin 407c2fbfb3SApril Chin #define COL 16 417c2fbfb3SApril Chin #define DOT 17 427c2fbfb3SApril Chin #define END 18 437c2fbfb3SApril Chin #define PFX 19 447c2fbfb3SApril Chin 457c2fbfb3SApril Chin int strtoip6(register const char * s,char ** e,unsigned char * addr,unsigned char * bits)467c2fbfb3SApril Chinstrtoip6(register const char* s, char** e, unsigned char* addr, unsigned char* bits) 477c2fbfb3SApril Chin { 487c2fbfb3SApril Chin register unsigned char* b = addr; 497c2fbfb3SApril Chin register unsigned char* x = b + IP6ADDR; 507c2fbfb3SApril Chin register unsigned char* z; 517c2fbfb3SApril Chin register int c; 527c2fbfb3SApril Chin register uint32_t a; 537c2fbfb3SApril Chin 547c2fbfb3SApril Chin static unsigned char lex[256]; 557c2fbfb3SApril Chin 567c2fbfb3SApril Chin if (!lex[0]) 577c2fbfb3SApril Chin { 587c2fbfb3SApril Chin for (c = 0; c < sizeof(lex); ++c) 597c2fbfb3SApril Chin lex[c] = END; 607c2fbfb3SApril Chin lex['0'] = 0; 617c2fbfb3SApril Chin lex['1'] = 1; 627c2fbfb3SApril Chin lex['2'] = 2; 637c2fbfb3SApril Chin lex['3'] = 3; 647c2fbfb3SApril Chin lex['4'] = 4; 657c2fbfb3SApril Chin lex['5'] = 5; 667c2fbfb3SApril Chin lex['6'] = 6; 677c2fbfb3SApril Chin lex['7'] = 7; 687c2fbfb3SApril Chin lex['8'] = 8; 697c2fbfb3SApril Chin lex['9'] = 9; 707c2fbfb3SApril Chin lex['A'] = lex['a'] = 10; 717c2fbfb3SApril Chin lex['B'] = lex['b'] = 11; 727c2fbfb3SApril Chin lex['C'] = lex['c'] = 12; 737c2fbfb3SApril Chin lex['D'] = lex['d'] = 13; 747c2fbfb3SApril Chin lex['E'] = lex['e'] = 14; 757c2fbfb3SApril Chin lex['F'] = lex['f'] = 15; 767c2fbfb3SApril Chin lex[':'] = COL; 777c2fbfb3SApril Chin lex['.'] = DOT; 787c2fbfb3SApril Chin lex['/'] = PFX; 797c2fbfb3SApril Chin } 807c2fbfb3SApril Chin while (isspace(*s)) 817c2fbfb3SApril Chin s++; 827c2fbfb3SApril Chin z = 0; 837c2fbfb3SApril Chin a = 0; 847c2fbfb3SApril Chin if (*s) 857c2fbfb3SApril Chin for (;;) 867c2fbfb3SApril Chin { 877c2fbfb3SApril Chin switch (c = lex[*((unsigned char*)s++)]) 887c2fbfb3SApril Chin { 897c2fbfb3SApril Chin case END: 907c2fbfb3SApril Chin case PFX: 917c2fbfb3SApril Chin if ((x - b) < 2) 927c2fbfb3SApril Chin break; 937c2fbfb3SApril Chin *b++ = a>>8; 947c2fbfb3SApril Chin *b++ = a; 957c2fbfb3SApril Chin break; 967c2fbfb3SApril Chin case COL: 977c2fbfb3SApril Chin if ((x - b) < 2) 987c2fbfb3SApril Chin break; 997c2fbfb3SApril Chin *b++ = a>>8; 1007c2fbfb3SApril Chin *b++ = a; 1017c2fbfb3SApril Chin a = 0; 1027c2fbfb3SApril Chin if (*s == ':') 1037c2fbfb3SApril Chin { 1047c2fbfb3SApril Chin if (z) 1057c2fbfb3SApril Chin { 1067c2fbfb3SApril Chin s--; 1077c2fbfb3SApril Chin break; 1087c2fbfb3SApril Chin } 1097c2fbfb3SApril Chin z = b; 1107c2fbfb3SApril Chin if ((c = lex[*((unsigned char*)++s)]) >= 16) 1117c2fbfb3SApril Chin { 1127c2fbfb3SApril Chin s++; 1137c2fbfb3SApril Chin break; 1147c2fbfb3SApril Chin } 1157c2fbfb3SApril Chin } 1167c2fbfb3SApril Chin continue; 1177c2fbfb3SApril Chin case DOT: 1187c2fbfb3SApril Chin if (b >= x) 1197c2fbfb3SApril Chin { 1207c2fbfb3SApril Chin s--; 1217c2fbfb3SApril Chin break; 1227c2fbfb3SApril Chin } 1237c2fbfb3SApril Chin *b++ = ((a >> 8) & 0xf) * 100 + ((a >> 4) & 0xf) * 10 + (a & 0xf); 1247c2fbfb3SApril Chin a = 0; 1257c2fbfb3SApril Chin for (;;) 1267c2fbfb3SApril Chin { 1277c2fbfb3SApril Chin switch (c = lex[*((unsigned char*)s++)]) 1287c2fbfb3SApril Chin { 1297c2fbfb3SApril Chin case COL: 1307c2fbfb3SApril Chin case END: 1317c2fbfb3SApril Chin case PFX: 1327c2fbfb3SApril Chin if (b < x) 1337c2fbfb3SApril Chin *b++ = a; 1347c2fbfb3SApril Chin a = 0; 1357c2fbfb3SApril Chin break; 1367c2fbfb3SApril Chin case DOT: 1377c2fbfb3SApril Chin if (b >= x) 1387c2fbfb3SApril Chin break; 1397c2fbfb3SApril Chin *b++ = a; 1407c2fbfb3SApril Chin a = 0; 1417c2fbfb3SApril Chin continue; 1427c2fbfb3SApril Chin default: 1437c2fbfb3SApril Chin a = (a * 10) + c; 1447c2fbfb3SApril Chin continue; 1457c2fbfb3SApril Chin } 1467c2fbfb3SApril Chin break; 1477c2fbfb3SApril Chin } 1487c2fbfb3SApril Chin if (c == COL) 1497c2fbfb3SApril Chin { 1507c2fbfb3SApril Chin if (*s == ':') 1517c2fbfb3SApril Chin { 1527c2fbfb3SApril Chin if (z) 1537c2fbfb3SApril Chin { 1547c2fbfb3SApril Chin s--; 1557c2fbfb3SApril Chin break; 1567c2fbfb3SApril Chin } 1577c2fbfb3SApril Chin z = b; 1587c2fbfb3SApril Chin if ((c = lex[*((unsigned char*)++s)]) >= 16) 1597c2fbfb3SApril Chin { 1607c2fbfb3SApril Chin s++; 1617c2fbfb3SApril Chin break; 1627c2fbfb3SApril Chin } 1637c2fbfb3SApril Chin } 1647c2fbfb3SApril Chin if ((b - addr) == 6 && addr[0] == 0x20 && addr[1] == 0x02) 1657c2fbfb3SApril Chin continue; 1667c2fbfb3SApril Chin } 1677c2fbfb3SApril Chin break; 1687c2fbfb3SApril Chin default: 1697c2fbfb3SApril Chin a = (a << 4) | c; 1707c2fbfb3SApril Chin continue; 1717c2fbfb3SApril Chin } 1727c2fbfb3SApril Chin break; 1737c2fbfb3SApril Chin } 1747c2fbfb3SApril Chin if (b == addr) 1757c2fbfb3SApril Chin c = END + 1; 1767c2fbfb3SApril Chin else 1777c2fbfb3SApril Chin { 1787c2fbfb3SApril Chin if (z) 1797c2fbfb3SApril Chin { 1807c2fbfb3SApril Chin while (b > z) 1817c2fbfb3SApril Chin *--x = *--b; 1827c2fbfb3SApril Chin while (x > z) 1837c2fbfb3SApril Chin *--x = 0; 1847c2fbfb3SApril Chin } 1857c2fbfb3SApril Chin else 1867c2fbfb3SApril Chin while (b < x) 1877c2fbfb3SApril Chin *b++ = 0; 1887c2fbfb3SApril Chin if (bits) 1897c2fbfb3SApril Chin { 1907c2fbfb3SApril Chin a = 0; 1917c2fbfb3SApril Chin if (c == PFX) 1927c2fbfb3SApril Chin while ((c = lex[*((unsigned char*)s++)]) < 10) 1937c2fbfb3SApril Chin a = a * 10 + c; 1947c2fbfb3SApril Chin *bits = a; 1957c2fbfb3SApril Chin } 1967c2fbfb3SApril Chin } 1977c2fbfb3SApril Chin if (e) 1987c2fbfb3SApril Chin *e = (char*)(s - 1); 1997c2fbfb3SApril Chin return c == END ? 0 : -1; 2007c2fbfb3SApril Chin } 201