7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/***********************************************************************
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1985-2010 AT&T Intellectual Property *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* and is licensed under the *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* A copy of the License is available at *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* http://www.opensource.org/licenses/cpl1.0.txt *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* Information and Software Systems Research *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* AT&T Research *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* Florham Park NJ *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* Glenn Fowler <gsf@research.att.com> *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* David Korn <dgk@research.att.com> *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* Phong Vo <kpv@research.att.com> *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin***********************************************************************/
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#pragma prototyped
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if _PACKAGE_ast
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#include <ast.h>
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#include <stdint.h>
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#include <ctype.h>
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#include <ip6.h>
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/*
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * convert string to ipv6 network byte order ip address
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * with optional prefix bits
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * pointer to first unused char placed in *e, even on error
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * return 0:ok <0:error
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define COL 16
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define DOT 17
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define END 18
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define PFX 19
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinint
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstrtoip6(register const char* s, char** e, unsigned char* addr, unsigned char* bits)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register unsigned char* b = addr;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register unsigned char* x = b + IP6ADDR;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register unsigned char* z;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register int c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register uint32_t a;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin static unsigned char lex[256];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (!lex[0])
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for (c = 0; c < sizeof(lex); ++c)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lex[c] = END;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lex['0'] = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lex['1'] = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lex['2'] = 2;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lex['3'] = 3;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lex['4'] = 4;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lex['5'] = 5;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lex['6'] = 6;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lex['7'] = 7;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lex['8'] = 8;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lex['9'] = 9;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lex['A'] = lex['a'] = 10;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lex['B'] = lex['b'] = 11;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lex['C'] = lex['c'] = 12;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lex['D'] = lex['d'] = 13;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lex['E'] = lex['e'] = 14;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lex['F'] = lex['f'] = 15;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lex[':'] = COL;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lex['.'] = DOT;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lex['/'] = PFX;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while (isspace(*s))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin s++;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin z = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin a = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (*s)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for (;;)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin switch (c = lex[*((unsigned char*)s++)])
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case END:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case PFX:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if ((x - b) < 2)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *b++ = a>>8;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *b++ = a;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case COL:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if ((x - b) < 2)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *b++ = a>>8;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *b++ = a;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin a = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (*s == ':')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (z)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin s--;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin z = b;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if ((c = lex[*((unsigned char*)++s)]) >= 16)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin s++;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin continue;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case DOT:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (b >= x)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin s--;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *b++ = ((a >> 8) & 0xf) * 100 + ((a >> 4) & 0xf) * 10 + (a & 0xf);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin a = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for (;;)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin switch (c = lex[*((unsigned char*)s++)])
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case COL:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case END:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case PFX:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (b < x)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *b++ = a;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin a = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case DOT:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (b >= x)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *b++ = a;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin a = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin continue;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin default:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin a = (a * 10) + c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin continue;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (c == COL)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (*s == ':')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (z)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin s--;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin z = b;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if ((c = lex[*((unsigned char*)++s)]) >= 16)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin s++;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if ((b - addr) == 6 && addr[0] == 0x20 && addr[1] == 0x02)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin continue;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin default:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin a = (a << 4) | c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin continue;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (b == addr)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = END + 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (z)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while (b > z)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *--x = *--b;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while (x > z)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *--x = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while (b < x)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *b++ = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (bits)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin a = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (c == PFX)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while ((c = lex[*((unsigned char*)s++)]) < 10)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin a = a * 10 + c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *bits = a;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (e)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *e = (char*)(s - 1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return c == END ? 0 : -1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}