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