/* Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
 * Portions Copyright © 1997-1999 Vita Nuova Limited
 * Portions Copyright © 2000-2007 Vita Nuova Holdings Limited
 *                                (www.vitanuova.com)
 * Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
 *
 * Modified for the Akaros operating system:
 * Copyright (c) 2013-2014 The Regents of the University of California
 * Copyright (c) 2013-2015 Google Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE. */

#include <vfs.h>
#include <kfs.h>
#include <slab.h>
#include <kmalloc.h>
#include <kref.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <error.h>
#include <cpio.h>
#include <pmap.h>
#include <smp.h>
#include <net/ip.h>
#include <endian.h>

/*
 *  well known IP addresses
 */
uint8_t IPv4_loopback[IPaddrlen] = {
	0, 0, 0, 0,
	0, 0, 0, 0,
	0, 0, 0xff, 0xff,
	0x7f, 0x00, 0x00, 0x01
};

uint8_t IPv4_zeroes[IPaddrlen] = {
	0, 0, 0, 0,
	0, 0, 0, 0,
	0, 0, 0xff, 0xff,
	0x00, 0x00, 0x00, 0x00
};

uint8_t IPv4bcast[IPaddrlen] = {
	0, 0, 0, 0,
	0, 0, 0, 0,
	0, 0, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff
};

uint8_t IPv4allsys[IPaddrlen] = {
	0, 0, 0, 0,
	0, 0, 0, 0,
	0, 0, 0xff, 0xff,
	0xe0, 0, 0, 0x01
};

uint8_t IPv4allrouter[IPaddrlen] = {
	0, 0, 0, 0,
	0, 0, 0, 0,
	0, 0, 0xff, 0xff,
	0xe0, 0, 0, 0x02
};

uint8_t IPallbits[IPaddrlen] = {
	0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff
};

uint8_t IPnoaddr[IPaddrlen];

/*
 *  prefix of all v4 addresses
 */
uint8_t v4prefix[IPaddrlen] = {
	0, 0, 0, 0,
	0, 0, 0, 0,
	0, 0, 0xff, 0xff,
	0, 0, 0, 0
};

char *v6hdrtypes[Maxhdrtype] = {
	[HBH] "HopbyHop",
	[ICMP] "ICMP",
	[IGMP] "IGMP",
	[GGP] "GGP",
	[IPINIP] "IP",
	[ST] "ST",
	[TCP] "TCP",
	[UDP] "UDP",
	[ISO_TP4] "ISO_TP4",
	[RH] "Routinghdr",
	[FH] "Fraghdr",
	[IDRP] "IDRP",
	[RSVP] "RSVP",
	[AH] "Authhdr",
	[ESP] "ESP",
	[ICMPv6] "ICMPv6",
	[NNH] "Nonexthdr",
	[ISO_IP] "ISO_IP",
	[IGRP] "IGRP",
	[OSPF] "OSPF",
};

/*
 *  well known IPv6 addresses
 */
uint8_t v6Unspecified[IPaddrlen] = {
	0, 0, 0, 0,
	0, 0, 0, 0,
	0, 0, 0, 0,
	0, 0, 0, 0
};

uint8_t v6loopback[IPaddrlen] = {
	0, 0, 0, 0,
	0, 0, 0, 0,
	0, 0, 0, 0,
	0, 0, 0, 0x01
};

uint8_t v6linklocal[IPaddrlen] = {
	0xfe, 0x80, 0, 0,
	0, 0, 0, 0,
	0, 0, 0, 0,
	0, 0, 0, 0
};

uint8_t v6linklocalmask[IPaddrlen] = {
	0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff,
	0, 0, 0, 0,
	0, 0, 0, 0
};

int v6llpreflen = 8;			// link-local prefix length
uint8_t v6sitelocal[IPaddrlen] = {
	0xfe, 0xc0, 0, 0,
	0, 0, 0, 0,
	0, 0, 0, 0,
	0, 0, 0, 0
};

uint8_t v6sitelocalmask[IPaddrlen] = {
	0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff,
	0, 0, 0, 0,
	0, 0, 0, 0
};

int v6slpreflen = 6;			// site-local prefix length
uint8_t v6glunicast[IPaddrlen] = {
	0x08, 0, 0, 0,
	0, 0, 0, 0,
	0, 0, 0, 0,
	0, 0, 0, 0
};

uint8_t v6multicast[IPaddrlen] = {
	0xff, 0, 0, 0,
	0, 0, 0, 0,
	0, 0, 0, 0,
	0, 0, 0, 0
};

uint8_t v6multicastmask[IPaddrlen] = {
	0xff, 0, 0, 0,
	0, 0, 0, 0,
	0, 0, 0, 0,
	0, 0, 0, 0
};

int v6mcpreflen = 1;			// multicast prefix length
uint8_t v6allnodesN[IPaddrlen] = {
	0xff, 0x01, 0, 0,
	0, 0, 0, 0,
	0, 0, 0, 0,
	0, 0, 0, 0x01
};

uint8_t v6allnodesNmask[IPaddrlen] = {
	0xff, 0xff, 0, 0,
	0, 0, 0, 0,
	0, 0, 0, 0,
	0, 0, 0, 0
};

int v6aNpreflen = 2;			// all nodes (N) prefix
uint8_t v6allnodesL[IPaddrlen] = {
	0xff, 0x02, 0, 0,
	0, 0, 0, 0,
	0, 0, 0, 0,
	0, 0, 0, 0x01
};

uint8_t v6allnodesLmask[IPaddrlen] = {
	0xff, 0xff, 0, 0,
	0, 0, 0, 0,
	0, 0, 0, 0,
	0, 0, 0, 0
};

int v6aLpreflen = 2;			// all nodes (L) prefix
uint8_t v6allroutersN[IPaddrlen] = {
	0xff, 0x01, 0, 0,
	0, 0, 0, 0,
	0, 0, 0, 0,
	0, 0, 0, 0x02
};

uint8_t v6allroutersL[IPaddrlen] = {
	0xff, 0x02, 0, 0,
	0, 0, 0, 0,
	0, 0, 0, 0,
	0, 0, 0, 0x02
};

uint8_t v6allroutersS[IPaddrlen] = {
	0xff, 0x05, 0, 0,
	0, 0, 0, 0,
	0, 0, 0, 0,
	0, 0, 0, 0x02
};

uint8_t v6solicitednode[IPaddrlen] = {
	0xff, 0x02, 0, 0,
	0, 0, 0, 0,
	0, 0, 0, 0x01,
	0xff, 0, 0, 0
};

uint8_t v6solicitednodemask[IPaddrlen] = {
	0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff,
	0xff, 0x0, 0x0, 0x0
};

int v6snpreflen = 13;

uint16_t ptclcsum_one(struct block *bp, int offset, int len)
{
	uint8_t *addr;
	uint32_t losum, hisum;
	uint16_t csum;
	int odd, blocklen, x, i, boff;
	struct extra_bdata *ebd;

	hisum = 0;
	losum = 0;
	odd = 0;

	if (offset < BHLEN(bp)) {
		x = MIN(len, BHLEN(bp) - offset);
		odd = (odd + x) & 1;
		addr = bp->rp + offset;
		losum = ptclbsum(addr, x);
		len -= x;
		offset = 0;
	} else {
		offset -= BHLEN(bp);
	}
	for (int i = 0; (i < bp->nr_extra_bufs) && len; i++) {
		ebd = &bp->extra_data[i];
		boff = MIN(offset, ebd->len);
		if (offset) {
			offset -= boff;
			if (offset)
				continue;
		}
		x = MIN(len, ebd->len - boff);
		addr = (void *)(ebd->base + ebd->off);
		if (odd)
			hisum += ptclbsum(addr, x);
		else
			losum += ptclbsum(addr, x);
		odd = (odd + x) & 1;
		len -= x;
	}
	losum += hisum >> 8;
	losum += (hisum & 0xff) << 8;
	while ((csum = losum >> 16) != 0)
		losum = csum + (losum & 0xffff);

	return losum & 0xffff;
}

uint16_t ptclcsum(struct block *bp, int offset, int len)
{
	uint8_t *addr;
	uint32_t losum, hisum;
	uint16_t csum;
	int odd, blocklen, x;

	/* Correct to front of data area */
	while (bp != NULL && offset && offset >= BLEN(bp)) {
		offset -= BLEN(bp);
		bp = bp->next;
	}
	if (bp == NULL)
		return 0;

	addr = bp->rp + offset;
	blocklen = BLEN(bp) - offset;

	if (bp->next == NULL && bp->extra_len == 0) {
		if (blocklen < len)
			len = blocklen;
		return ~ptclbsum(addr, len) & 0xffff;
	}

	losum = 0;
	hisum = 0;

	odd = 0;
	while (len) {
		x = MIN(blocklen, len);
		csum = ptclcsum_one(bp, offset, x);
		if (odd)
			hisum += csum;
		else
			losum += csum;
		odd = (odd + x) & 1;
		len -= x;

		bp = bp->next;
		if (bp == NULL)
			break;
		blocklen = BLEN(bp);
		offset = 0;
	}

	losum += hisum >> 8;
	losum += (hisum & 0xff) << 8;
	while ((csum = losum >> 16) != 0)
		losum = csum + (losum & 0xffff);

	return ~losum & 0xffff;
}

enum {
	Isprefix = 16,
};

static uint8_t prefixvals[256] = {
	[0x00] 0 | Isprefix,
	[0x80] 1 | Isprefix,
	[0xC0] 2 | Isprefix,
	[0xE0] 3 | Isprefix,
	[0xF0] 4 | Isprefix,
	[0xF8] 5 | Isprefix,
	[0xFC] 6 | Isprefix,
	[0xFE] 7 | Isprefix,
	[0xFF] 8 | Isprefix,
};

#define CLASS(p) ((*( uint8_t *)(p))>>6)

extern 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 uint8_t 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 uint8_t net */
			if (i == 3) {
				to[3] = to[2];
				to[2] = 0;
			}
			break;
	}
	return p;
}

int isv4(uint8_t * ip)
{
	unsigned short *ips = (unsigned short *)ip;
	return 0xffff == ips[5];
}

/*
 *  the following routines are unrolled with no memset's to speed
 *  up the usual case.  They assume IP addresses are naturally aligned.
 */
void v4tov6(uint8_t * v6, uint8_t * v4)
{
	uint32_t *v6p = (uint32_t *)v6;
	uint32_t *v4p = (uint32_t *)v4;

	v6p[0] = 0;
	v6p[1] = 0;
	v6p[2] = (unsigned int)PP_NTOHL(0xffff);
	v6p[3] = v4p[0];
}

int v6tov4(uint8_t * v4, uint8_t * v6)
{

	uint32_t *v6p = (uint32_t *)v6;
	uint32_t *v4p = (uint32_t *)v4;

	if (v6p[0] == 0 && v6p[1] == 0 &&
	    v6p[2] == (unsigned int)PP_NTOHL(0xffff)) {
		v4p[0] = v6p[3];
		return 0;
	} else {
		v4p[0] = 0;
		return -1;
	}
}

uint32_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 < 16 && *p; i += 2) {
		op = p;
		x = strtoul(p, &p, 16);
		if (*p == '.' || (*p == 0 && i == 0)) {
			p = v4parseip(to + i, op);
			i += 4;
			break;
		} else {
			to[i] = x >> 8;
			to[i + 1] = x;
		}
		if (*p == ':') {
			v4 = 0;
			if (*++p == ':') {
				elipsis = i + 2;
				p++;
			}
		}
	}
	if (i < 16) {
		memmove(&to[elipsis + 16 - i], &to[elipsis], i - elipsis);
		memset(&to[elipsis], 0, 16 - i);
	}
	if (v4) {
		to[10] = to[11] = 0xff;
		return nhgetl(to + 12);
	} else
		return 6;
}

/*
 *  hack to allow ip v4 masks to be entered in the old
 *  style
 */
uint32_t parseipmask(uint8_t * to, char *from)
{
	uint32_t x;
	int i;
	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;
		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);
	} else {
		/* as a straight bit mask */
		x = parseip(to, from);
		if (memcmp(to, v4prefix, IPv4off) == 0)
			memset(to, 0xff, IPv4off);
	}
	return x;
}

void maskip(uint8_t * from, uint8_t * mask, uint8_t * to)
{
	int i;

	for (i = 0; i < IPaddrlen; i++)
		to[i] = from[i] & mask[i];
}

uint8_t classmask[4][16] = {
	{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	 0xff, 0x00, 0x00, 0x00}
	,
	{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	 0xff, 0x00, 0x00, 0x00}
	,
	{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	 0xff, 0xff, 0x00, 0x00}
	,

	{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	 0xff, 0xff, 0xff, 0x00}
	,
};

uint8_t *defmask(uint8_t * ip)
{
	if (isv4(ip))
		return classmask[ip[IPv4off] >> 6];
	else {
		if (ipcmp(ip, v6loopback) == 0)
			return IPallbits;
		else if (memcmp(ip, v6linklocal, v6llpreflen) == 0)
			return v6linklocalmask;
		else if (memcmp(ip, v6sitelocal, v6slpreflen) == 0)
			return v6sitelocalmask;
		else if (memcmp(ip, v6solicitednode, v6snpreflen) == 0)
			return v6solicitednodemask;
		else if (memcmp(ip, v6multicast, v6mcpreflen) == 0)
			return v6multicastmask;
		return IPallbits;
	}
}

void ipv62smcast(uint8_t * smcast, uint8_t * a)
{
	assert(IPaddrlen == 16);
	memmove(smcast, v6solicitednode, IPaddrlen);
	smcast[13] = a[13];
	smcast[14] = a[14];
	smcast[15] = a[15];
}

/*
 *  parse a hex mac address
 */
int parsemac(uint8_t * to, char *from, int len)
{
	char nip[4];
	char *p;
	int i;

	p = from;
	memset(to, 0, len);
	for (i = 0; i < len; i++) {
		if (p[0] == '\0' || p[1] == '\0')
			break;

		nip[0] = p[0];
		nip[1] = p[1];
		nip[2] = '\0';
		p += 2;

		to[i] = strtoul(nip, 0, 16);
		if (*p == ':')
			p++;
	}
	return i;
}

/*
 *  hashing tcp, udp, ... connections
 *  gcc weirdness: it gave a bogus result until ron split the %= out.
 */
uint32_t iphash(uint8_t * sa, uint16_t sp, uint8_t * da, uint16_t dp)
{
	uint32_t ret;
	ret = (sa[IPaddrlen - 1] << 24) ^ (sp << 16) ^ (da[IPaddrlen - 1] << 8)
		^ dp;
	ret %= Nhash;
	return ret;
}

void iphtadd(struct Ipht *ht, struct conv *c)
{
	uint32_t hv;
	struct Iphash *h;

	hv = iphash(c->raddr, c->rport, c->laddr, c->lport);
	h = kzmalloc(sizeof(*h), 0);
	if (ipcmp(c->raddr, IPnoaddr) != 0)
		h->match = IPmatchexact;
	else {
		if (ipcmp(c->laddr, IPnoaddr) != 0) {
			if (c->lport == 0)
				h->match = IPmatchaddr;
			else
				h->match = IPmatchpa;
		} else {
			if (c->lport == 0)
				h->match = IPmatchany;
			else
				h->match = IPmatchport;
		}
	}
	h->c = c;

	spin_lock(&ht->lock);
	h->next = ht->tab[hv];
	ht->tab[hv] = h;
	spin_unlock(&ht->lock);
}

void iphtrem(struct Ipht *ht, struct conv *c)
{
	uint32_t hv;
	struct Iphash **l, *h;

	hv = iphash(c->raddr, c->rport, c->laddr, c->lport);
	spin_lock(&ht->lock);
	for (l = &ht->tab[hv]; (*l) != NULL; l = &(*l)->next)
		if ((*l)->c == c) {
			h = *l;
			(*l) = h->next;
			kfree(h);
			break;
		}
	spin_unlock(&ht->lock);
}

/* look for a matching conversation with the following precedence
 *	connected && raddr,rport,laddr,lport
 *	announced && laddr,lport
 *	announced && *,lport
 *	announced && laddr,*
 *	announced && *,*
 */
struct conv *iphtlook(struct Ipht *ht, uint8_t * sa, uint16_t sp, uint8_t * da,
					  uint16_t dp)
{
	uint32_t hv;
	struct Iphash *h;
	struct conv *c;

	/* exact 4 pair match (connection) */
	hv = iphash(sa, sp, da, dp);
	spin_lock(&ht->lock);
	for (h = ht->tab[hv]; h != NULL; h = h->next) {
		if (h->match != IPmatchexact)
			continue;
		c = h->c;
		if (sp == c->rport && dp == c->lport
			&& ipcmp(sa, c->raddr) == 0 && ipcmp(da, c->laddr) == 0) {
			spin_unlock(&ht->lock);
			return c;
		}
	}

	/* match local address and port */
	hv = iphash(IPnoaddr, 0, da, dp);
	for (h = ht->tab[hv]; h != NULL; h = h->next) {
		if (h->match != IPmatchpa)
			continue;
		c = h->c;
		if (dp == c->lport && ipcmp(da, c->laddr) == 0) {
			spin_unlock(&ht->lock);
			return c;
		}
	}

	/* match just port */
	hv = iphash(IPnoaddr, 0, IPnoaddr, dp);
	for (h = ht->tab[hv]; h != NULL; h = h->next) {
		if (h->match != IPmatchport)
			continue;
		c = h->c;
		if (dp == c->lport) {
			spin_unlock(&ht->lock);
			return c;
		}
	}

	/* match local address */
	hv = iphash(IPnoaddr, 0, da, 0);
	for (h = ht->tab[hv]; h != NULL; h = h->next) {
		if (h->match != IPmatchaddr)
			continue;
		c = h->c;
		if (ipcmp(da, c->laddr) == 0) {
			spin_unlock(&ht->lock);
			return c;
		}
	}

	/* look for something that matches anything */
	hv = iphash(IPnoaddr, 0, IPnoaddr, 0);
	for (h = ht->tab[hv]; h != NULL; h = h->next) {
		if (h->match != IPmatchany)
			continue;
		c = h->c;
		spin_unlock(&ht->lock);
		return c;
	}
	spin_unlock(&ht->lock);
	return NULL;
}

void dump_ipht(struct Ipht *ht)
{
	struct Iphash *h;
	struct conv *c;

	spin_lock(&ht->lock);
	for (int i = 0; i < Nipht; i++) {
		for (h = ht->tab[i]; h != NULL; h = h->next) {
			c = h->c;
			printk("Conv proto %s, idx %d: local %I:%d, remote %I:%d\n",
			       c->p->name, c->x, c->laddr, c->lport, c->raddr, c->rport);
		}
	}
	spin_unlock(&ht->lock);
}
