/*
 * This file is part of the UCB release of Plan 9. It is subject to the license
 * terms in the LICENSE file found in the top-level directory of this
 * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
 * part of the UCB release of Plan 9, including this file, may be copied,
 * modified, propagated, or distributed except according to the terms contained
 * in the LICENSE file.
 */
#include <stdlib.h>

#include <iplib/iplib.h>
#include <parlib/parlib.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>

static int isascii(int c)
{
	return ((c >= 0) && (c <= 128));
}
static int isalnum(int c)
{
	return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
	        (c >= '0' && c <= '9'));
}
static int isdigit(int c)
{
	return ((c >= '0' && c <= '9'));
}
static int isxdigit(int c)
{
	return ((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') ||
	        (c >= '0' && c <= '9'));
}

char *v4parseip(uint8_t *to, char *from)
{
	int i;
	char *p;

	p = from;
	for (i = 0; i < 4 && *p; i++) {
		to[i] = strtoul(p, &p, 0);
		if (*p == '.')
			p++;
	}
	switch (CLASS(to)) {
	case 0: /* class A - 1 uchar net */
	case 1:
		if (i == 3) {
			to[3] = to[2];
			to[2] = to[1];
			to[1] = 0;
		} else if (i == 2) {
			to[3] = to[1];
			to[1] = 0;
		}
		break;
	case 2: /* class B - 2 uchar net */
		if (i == 3) {
			to[3] = to[2];
			to[2] = 0;
		}
		break;
	}
	return p;
}

static int ipcharok(int c)
{
	return c == '.' || c == ':' || isascii(c) && isxdigit(c);
}

static int delimchar(int c)
{
	if (c == '\0')
		return 1;
	if (c == '.' || c == ':' || isascii(c) && isalnum(c))
		return 0;
	return 1;
}

/*
 * `from' may contain an address followed by other characters,
 * at least in /boot, so we permit whitespace (and more) after the address.
 * we do ensure that "delete" cannot be parsed as "de::".
 *
 * some callers don't check the return value for errors, so
 * set `to' to something distinctive in the case of a parse error.
 */
int64_t parseip(uint8_t *to, char *from)
{
	int i, elipsis = 0, v4 = 1;
	uint32_t x;
	char *p, *op;

	memset(to, 0, IPaddrlen);
	p = from;
	for (i = 0; i < IPaddrlen && ipcharok(*p); i += 2) {
		op = p;
		x = strtoul(p, &p, 16);
		if (*p == '.' || (*p == 0 && i == 0)) { /* ends with v4? */
			p = v4parseip(to + i, op);
			i += 4;
			break;
		}
		/* v6: at most 4 hex digits, followed by colon or delim */
		if (x != (uint16_t)x || *p != ':' && !delimchar(*p)) {
			memset(to, 0, IPaddrlen);
			return -1; /* parse error */
		}
		to[i] = x >> 8;
		to[i + 1] = x;
		if (*p == ':') {
			v4 = 0;
			if (*++p == ':') { /* :: is elided zero short(s) */
				if (elipsis) {
					memset(to, 0, IPaddrlen);
					return -1; /* second :: */
				}
				elipsis = i + 2;
				p++;
			}
		} else if (p == op) /* strtoul made no progress? */
			break;
	}
	if (p == from || !delimchar(*p)) {
		memset(to, 0, IPaddrlen);
		return -1; /* parse error */
	}
	if (i < IPaddrlen) {
		memmove(&to[elipsis + IPaddrlen - i], &to[elipsis],
			i - elipsis);
		memset(&to[elipsis], 0, IPaddrlen - i);
	}
	if (v4) {
		to[10] = to[11] = 0xff;
		return nhgetl(to + IPv4off);
	} else
		return 6;
}

/*
 *  hack to allow ip v4 masks to be entered in the old
 *  style
 */
int64_t parseipmask(uint8_t *to, char *from)
{
	int i, w;
	int64_t x;
	uint8_t *p;

	if (*from == '/') {
		/* as a number of prefix bits */
		i = atoi(from + 1);
		if (i < 0)
			i = 0;
		if (i > 128)
			i = 128;
		w = i;
		memset(to, 0, IPaddrlen);
		for (p = to; i >= 8; i -= 8)
			*p++ = 0xff;
		if (i > 0)
			*p = ~((1 << (8 - i)) - 1);
		x = nhgetl(to + IPv4off);
		/*
		 * identify as ipv6 if the mask is inexpressible as a v4 mask
		 * (because it has too few mask bits).  Arguably, we could
		 * always return 6 here.
		 */
		if (w < 8 * (IPaddrlen - IPv4addrlen))
			return 6;
	} else {
		/* as a straight v4 bit mask */
		x = parseip(to, from);
		if (x != -1)
			x = (uint32_t)nhgetl(to + IPv4off);
		if (memcmp(to, v4prefix, IPv4off) == 0)
			memset(to, 0xff, IPv4off);
	}
	return x;
}

/*
 *  parse a v4 ip address/mask in cidr format
 */
char *v4parsecidr(uint8_t *addr, uint8_t *mask, char *from)
{
	int i;
	char *p;
	uint8_t *a;

	p = v4parseip(addr, from);

	if (*p == '/') {
		/* as a number of prefix bits */
		i = strtoul(p + 1, &p, 0);
		/* We might have been passed a v6 mask - the signal for that
		 * will be having more than 32 bits. */
		if (i >= 32)
			i -= 128 - 32;
		memset(mask, 0, IPv4addrlen);
		for (a = mask; i >= 8; i -= 8)
			*a++ = 0xff;
		if (i > 0)
			*a = ~((1 << (8 - i)) - 1);
	} else
		memcpy(mask, defmask(addr), IPv4addrlen);
	return p;
}
