/* 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 <ip.h>

static int netown(struct netfile *, char *unused_char_p_t, int);
static int openfile(struct ether *, int);
static char *matchtoken(char *unused_char_p_t, char *);
static char *netmulti(struct ether *, struct netfile *,
					  uint8_t * unused_uint8_p_t, int);
static int parseaddr(uint8_t * unused_uint8_p_t, char *unused_char_p_t, int);

/*
 *  set up a new network interface
 */
void netifinit(struct ether *nif, char *name, int nfile, uint32_t limit)
{
	qlock_init(&nif->qlock);
	strlcpy(nif->name, name, KNAMELEN);
	nif->nfile = nfile;
	nif->f = kzmalloc(nfile * sizeof(struct netfile *), 0);
	if (nif->f)
		memset(nif->f, 0, nfile * sizeof(struct netfile *));
	else
		nif->nfile = 0;
	nif->limit = limit;
}

/*
 *  generate a 3 level directory
 */
static int
netifgen(struct chan *c, char *unused_char_p_t, struct dirtab *vp,
		 int unused_int, int i, struct dir *dp)
{
	struct qid q;
	struct ether *nif = (struct ether *)vp;
	struct netfile *f;
	int perm;
	char *o;

	q.type = QTFILE;
	q.vers = 0;

	/* top level directory contains the name of the network */
	if (c->qid.path == 0) {
		switch (i) {
			case DEVDOTDOT:
				q.path = 0;
				q.type = QTDIR;
				devdir(c, q, ".", 0, eve, 0555, dp);
				break;
			case 0:
				q.path = N2ndqid;
				q.type = QTDIR;
				strlcpy(get_cur_genbuf(), nif->name, GENBUF_SZ);
				devdir(c, q, get_cur_genbuf(), 0, eve, 0555, dp);
				break;
			default:
				return -1;
		}
		return 1;
	}

	/* second level contains clone plus all the conversations.
	 *
	 * This ancient comment is from plan9.  Inferno and nxm both had issues
	 * here.  You couldn't ls /net/ether0/ when it didn't have any convs.  There
	 * were also issues with nxm where you couldn't stat ether0/x/stats
	 * properly.
	 *
	 * The issue is that if we handle things like Nstatqid, then we will never
	 * pass it down to the third level. And since we just set the path ==
	 * Nstatqid, we won't have the NETID muxed in. If someone isn't trying to
	 * generate a chan, but instead is looking it up (devwalk generates, devstat
	 * already has the chan), then they are also looking for a devdir with path
	 * containing ID << 5. So if you stat ether0/1/ifstats, devstat is looking
	 * for path 41, but we return path 9 (41 = 32 + 9). (these numbers are
	 * before we tracked NETID + 1).
	 *
	 * We (akaros and plan9) had a big if here, that would catch things that do
	 * not exist in the subdirs of a netif. Things like clone make sense here.
	 * I guess addr too, though that seems to be added since the original
	 * comment. You can see what the 3rd level was expecting to parse by looking
	 * farther down in the code.
	 *
	 * The root of the problem was that the old code couldn't tell the
	 * difference between no netid and netid 0. Now, we determine if we're at
	 * the second level by the lack of a netid, instead of trying to enumerate
	 * the qid types that the second level could have. The latter approach
	 * allowed for something like ether0/1/stats, but we couldn't actually
	 * devstat ether0/stats directly. It's worth noting that there is no
	 * difference to the content of ether0/stats and ether0/x/stats (when you
	 * read), but they have different chan qids.
	 *
	 * Here's the old if block:
	 t = NETTYPE(c->qid.path);
	 if (t == N2ndqid || t == Ncloneqid || t == Naddrqid) {
	 */
	if (NETID(c->qid.path) == -1) {
		switch (i) {
			case DEVDOTDOT:
				q.type = QTDIR;
				q.path = 0;
				devdir(c, q, ".", 0, eve, DMDIR | 0555, dp);
				break;
			case 0:
				q.path = Ncloneqid;
				devdir(c, q, "clone", 0, eve, 0666, dp);
				break;
			case 1:
				q.path = Naddrqid;
				devdir(c, q, "addr", 0, eve, 0666, dp);
				break;
			case 2:
				q.path = Nstatqid;
				devdir(c, q, "stats", 0, eve, 0444, dp);
				break;
			case 3:
				q.path = Nifstatqid;
				devdir(c, q, "ifstats", 0, eve, 0444, dp);
				break;
			default:
				i -= 4;
				if (i >= nif->nfile)
					return -1;
				if (nif->f[i] == 0)
					return 0;
				q.type = QTDIR;
				q.path = NETQID(i, N3rdqid);
				snprintf(get_cur_genbuf(), GENBUF_SZ, "%d", i);
				devdir(c, q, get_cur_genbuf(), 0, eve, DMDIR | 0555, dp);
				break;
		}
		return 1;
	}

	/* third level */
	f = nif->f[NETID(c->qid.path)];
	if (f == 0)
		return 0;
	if (*f->owner) {
		o = f->owner;
		perm = f->mode;
	} else {
		o = eve;
		perm = 0666;
	}
	switch (i) {
		case DEVDOTDOT:
			q.type = QTDIR;
			q.path = N2ndqid;
			strlcpy(get_cur_genbuf(), nif->name, GENBUF_SZ);
			devdir(c, q, get_cur_genbuf(), 0, eve, DMDIR | 0555, dp);
			break;
		case 0:
			q.path = NETQID(NETID(c->qid.path), Ndataqid);
			devdir(c, q, "data", 0, o, perm, dp);
			break;
		case 1:
			q.path = NETQID(NETID(c->qid.path), Nctlqid);
			devdir(c, q, "ctl", 0, o, perm, dp);
			break;
		case 2:
			q.path = NETQID(NETID(c->qid.path), Nstatqid);
			devdir(c, q, "stats", 0, eve, 0444, dp);
			break;
		case 3:
			q.path = NETQID(NETID(c->qid.path), Ntypeqid);
			devdir(c, q, "type", 0, eve, 0444, dp);
			break;
		case 4:
			q.path = NETQID(NETID(c->qid.path), Nifstatqid);
			devdir(c, q, "ifstats", 0, eve, 0444, dp);
			break;
		default:
			return -1;
	}
	return 1;
}

struct walkqid *netifwalk(struct ether *nif, struct chan *c, struct chan *nc,
						  char **name, int nname)
{
	return devwalk(c, nc, name, nname, (struct dirtab *)nif, 0, netifgen);
}

struct chan *netifopen(struct ether *nif, struct chan *c, int omode)
{
	int id;
	struct netfile *f;

	id = 0;
	if (c->qid.type & QTDIR) {
		if (omode & O_WRITE)
			error(EPERM, ERROR_FIXME);
	} else {
		switch (NETTYPE(c->qid.path)) {
			case Ndataqid:
			case Nctlqid:
				id = NETID(c->qid.path);
				openfile(nif, id);
				break;
			case Ncloneqid:
				id = openfile(nif, -1);
				c->qid.path = NETQID(id, Nctlqid);
				break;
			default:
				if (omode & O_WRITE)
					error(EINVAL, ERROR_FIXME);
		}
		switch (NETTYPE(c->qid.path)) {
			case Ndataqid:
			case Nctlqid:
				f = nif->f[id];
				if (netown(f, current->user, omode & 7) < 0)
					error(EPERM, ERROR_FIXME);
				break;
		}
	}
	c->mode = openmode(omode);
	c->flag |= COPEN;
	c->offset = 0;
	c->iounit = qiomaxatomic;
	return c;
}

long
netifread(struct ether *nif, struct chan *c, void *a, long n,
	  uint32_t offset)
{
	int i, j;
	struct netfile *f;
	char *p;

	if (c->qid.type & QTDIR)
		return devdirread(c, a, n, (struct dirtab *)nif, 0, netifgen);

	switch (NETTYPE(c->qid.path)) {
		case Ndataqid:
			f = nif->f[NETID(c->qid.path)];
			return qread(f->in, a, n);
		case Nctlqid:
			return readnum(offset, a, n, NETID(c->qid.path), NUMSIZE);
		case Nstatqid:
			p = kzmalloc(READSTR, 0);
			if (p == NULL)
				return 0;
			j = snprintf(p, READSTR, "in: %d\n", nif->inpackets);
			j += snprintf(p + j, READSTR - j, "link: %d\n", nif->link);
			j += snprintf(p + j, READSTR - j, "out: %d\n", nif->outpackets);
			j += snprintf(p + j, READSTR - j, "crc errs: %d\n", nif->crcs);
			j += snprintf(p + j, READSTR - j, "overflows: %d\n",
						  nif->overflows);
			j += snprintf(p + j, READSTR - j, "soft overflows: %d\n",
						  nif->soverflows);
			j += snprintf(p + j, READSTR - j, "framing errs: %d\n",
						  nif->frames);
			j += snprintf(p + j, READSTR - j, "buffer errs: %d\n", nif->buffs);
			j += snprintf(p + j, READSTR - j, "output errs: %d\n", nif->oerrs);
			j += snprintf(p + j, READSTR - j, "prom: %d\n", nif->prom);
			j += snprintf(p + j, READSTR - j, "mbps: %d\n", nif->mbps);
			j += snprintf(p + j, READSTR - j, "addr: ");
			for (i = 0; i < nif->alen; i++)
				j += snprintf(p + j, READSTR - j, "%02.2x", nif->addr[i]);
			j += snprintf(p + j, READSTR - j, "\n");
			j += snprintf(p + j, READSTR - j, "feat: ");
			if (nif->feat & NETF_IPCK)
				j += snprintf(p + j, READSTR - j, "ipck ");
			if (nif->feat & NETF_UDPCK)
				j += snprintf(p + j, READSTR - j, "udpck ");
			if (nif->feat & NETF_TCPCK)
				j += snprintf(p + j, READSTR - j, "tcpck ");
			if (nif->feat & NETF_PADMIN)
				j += snprintf(p + j, READSTR - j, "padmin ");
			if (nif->feat & NETF_SG)
				j += snprintf(p + j, READSTR - j, "sg ");
			if (nif->feat & NETF_TSO)
				j += snprintf(p + j, READSTR - j, "tso ");
			if (nif->feat & NETF_LRO)
				j += snprintf(p + j, READSTR - j, "lro ");
			snprintf(p + j, READSTR - j, "\n");
			n = readstr(offset, a, n, p);
			kfree(p);
			return n;
		case Naddrqid:
			p = kzmalloc(READSTR, 0);
			if (p == NULL)
				return 0;
			j = 0;
			for (i = 0; i < nif->alen; i++)
				j += snprintf(p + j, READSTR - j, "%02.2x", nif->addr[i]);
			n = readstr(offset, a, n, p);
			kfree(p);
			return n;
		case Ntypeqid:
			f = nif->f[NETID(c->qid.path)];
			return readnum(offset, a, n, f->type, NUMSIZE);
		case Nifstatqid:
			return 0;
	}
	error(EINVAL, ERROR_FIXME);
	return -1;	/* not reached */
}

struct block *netifbread(struct ether *nif, struct chan *c, long n,
						 uint32_t offset)
{
	if ((c->qid.type & QTDIR) || NETTYPE(c->qid.path) != Ndataqid)
		return devbread(c, n, offset);

	return qbread(nif->f[NETID(c->qid.path)]->in, n);
}

/*
 *  make sure this type isn't already in use on this device
 */
static int typeinuse(struct ether *nif, int type)
{
	struct netfile *f, **fp, **efp;

	if (type <= 0)
		return 0;

	efp = &nif->f[nif->nfile];
	for (fp = nif->f; fp < efp; fp++) {
		f = *fp;
		if (f == 0)
			continue;
		if (f->type == type)
			return 1;
	}
	return 0;
}

/*
 *  the devxxx.c that calls us handles writing data, it knows best
 */
long netifwrite(struct ether *nif, struct chan *c, void *a, long n)
{
	ERRSTACK(1);
	struct netfile *f;
	int type;
	char *p, buf[64];
	uint8_t binaddr[Nmaxaddr];

	if (NETTYPE(c->qid.path) != Nctlqid)
		error(EPERM, ERROR_FIXME);

	if (n >= sizeof(buf))
		n = sizeof(buf) - 1;
	memmove(buf, a, n);
	buf[n] = 0;

	qlock(&nif->qlock);
	if (waserror()) {
		qunlock(&nif->qlock);
		nexterror();
	}

	f = nif->f[NETID(c->qid.path)];
	if ((p = matchtoken(buf, "connect")) != 0) {
		type = strtol(p, 0, 0);	/* allows any base, though usually hex */
		if (typeinuse(nif, type))
			error(EBUSY, ERROR_FIXME);
		f->type = type;
		if (f->type < 0)
			nif->all++;
	} else if (matchtoken(buf, "promiscuous")) {
		if (f->prom == 0) {
			if (nif->prom == 0 && nif->promiscuous != NULL)
				nif->promiscuous(nif->arg, 1);
			f->prom = 1;
			nif->prom++;
		}
	} else if ((p = matchtoken(buf, "scanbs")) != 0) {
		/* scan for base stations */
		if (f->scan == 0) {
			type = strtol(p, 0, 0);	/* allows any base, though usually hex */
			if (type < 5)
				type = 5;
			if (nif->scanbs != NULL)
				nif->scanbs(nif->arg, type);
			f->scan = type;
			nif->scan++;
		}
	} else if (matchtoken(buf, "bridge")) {
		f->bridge = 1;
	} else if (matchtoken(buf, "headersonly")) {
		f->headersonly = 1;
	} else if ((p = matchtoken(buf, "addmulti")) != 0) {
		if (parseaddr(binaddr, p, nif->alen) < 0)
			error(EFAIL, "bad address");
		p = netmulti(nif, f, binaddr, 1);
		if (p)
			error(EFAIL, p);
	} else if ((p = matchtoken(buf, "remmulti")) != 0) {
		if (parseaddr(binaddr, p, nif->alen) < 0)
			error(EFAIL, "bad address");
		p = netmulti(nif, f, binaddr, 0);
		if (p)
			error(EFAIL, p);
	} else if (matchtoken(buf, "oneblock")) {
		/* Qmsg + Qcoal = one block at a time. */
		q_toggle_qmsg(f->in, TRUE);
		q_toggle_qcoalesce(f->in, TRUE);
	} else
		n = -1;
	qunlock(&nif->qlock);
	poperror();
	return n;
}

int netifwstat(struct ether *nif, struct chan *c, uint8_t * db, int n)
{
	struct dir *dir;
	struct netfile *f;
	int m;

	f = nif->f[NETID(c->qid.path)];
	if (f == 0)
		error(ENOENT, ERROR_FIXME);

	if (netown(f, current->user, O_WRITE) < 0)
		error(EPERM, ERROR_FIXME);

	dir = kzmalloc(sizeof(struct dir) + n, 0);
	m = convM2D(db, n, &dir[0], (char *)&dir[1]);
	if (m == 0) {
		kfree(dir);
		error(ENODATA, ERROR_FIXME);
	}
	if (!emptystr(dir[0].uid))
		strlcpy(f->owner, dir[0].uid, KNAMELEN);
	if (dir[0].mode != ~0UL)
		f->mode = dir[0].mode;
	kfree(dir);
	return m;
}

int netifstat(struct ether *nif, struct chan *c, uint8_t * db, int n)
{
	return devstat(c, db, n, (struct dirtab *)nif, 0, netifgen);
}

void netifclose(struct ether *nif, struct chan *c)
{
	struct netfile *f;
	int t;
	struct netaddr *ap;

	if ((c->flag & COPEN) == 0)
		return;

	t = NETTYPE(c->qid.path);
	if (t != Ndataqid && t != Nctlqid)
		return;

	f = nif->f[NETID(c->qid.path)];
	qlock(&f->qlock);
	if (--(f->inuse) == 0) {
		if (f->prom) {
			qlock(&nif->qlock);
			if (--(nif->prom) == 0 && nif->promiscuous != NULL)
				nif->promiscuous(nif->arg, 0);
			qunlock(&nif->qlock);
			f->prom = 0;
		}
		if (f->scan) {
			qlock(&nif->qlock);
			if (--(nif->scan) == 0 && nif->scanbs != NULL)
				nif->scanbs(nif->arg, 0);
			qunlock(&nif->qlock);
			f->prom = 0;
			f->scan = 0;
		}
		if (f->nmaddr) {
			qlock(&nif->qlock);
			t = 0;
			for (ap = nif->maddr; ap; ap = ap->next) {
				if (f->maddr[t / 8] & (1 << (t % 8)))
					netmulti(nif, f, ap->addr, 0);
			}
			qunlock(&nif->qlock);
			f->nmaddr = 0;
		}
		if (f->type < 0) {
			qlock(&nif->qlock);
			--(nif->all);
			qunlock(&nif->qlock);
		}
		f->owner[0] = 0;
		f->type = 0;
		f->bridge = 0;
		f->headersonly = 0;
		qclose(f->in);
	}
	qunlock(&f->qlock);
}

spinlock_t netlock = SPINLOCK_INITIALIZER;

static int netown(struct netfile *p, char *o, int omode)
{
	static int access[] = { 0400, 0200, 0600, 0100 };
	int mode;
	int t;

	spin_lock(&netlock);
	if (*p->owner) {
		if (strncmp(o, p->owner, KNAMELEN) == 0)	/* User */
			mode = p->mode;
		else if (strncmp(o, eve, KNAMELEN) == 0)	/* Bootes is group */
			mode = p->mode << 3;
		else
			mode = p->mode << 6;	/* Other */

		t = access[omode & 3];
		if ((t & mode) == t) {
			spin_unlock(&netlock);
			return 0;
		} else {
			spin_unlock(&netlock);
			return -1;
		}
	}
	strlcpy(p->owner, o, KNAMELEN);
	p->mode = 0660;
	spin_unlock(&netlock);
	return 0;
}

/*
 *  Increment the reference count of a network device.
 *  If id < 0, return an unused ether device.
 */
static int openfile(struct ether *nif, int id)
{
	ERRSTACK(1);
	struct netfile *f, **fp, **efp;

	if (id >= 0) {
		f = nif->f[id];
		if (f == 0)
			error(ENODEV, ERROR_FIXME);
		qlock(&f->qlock);
		qreopen(f->in);
		f->inuse++;
		qunlock(&f->qlock);
		return id;
	}

	qlock(&nif->qlock);
	if (waserror()) {
		qunlock(&nif->qlock);
		nexterror();
	}
	efp = &nif->f[nif->nfile];
	for (fp = nif->f; fp < efp; fp++) {
		f = *fp;
		if (f == 0) {
			f = kzmalloc(sizeof(struct netfile), 0);
			if (f == 0)
				exhausted("memory");
			/* since we lock before netifinit (if we ever call that...) */
			qlock_init(&f->qlock);
			f->in = qopen(nif->limit, Qmsg, 0, 0);
			if (f->in == NULL) {
				kfree(f);
				exhausted("memory");
			}
			*fp = f;
			qlock(&f->qlock);
		} else {
			qlock(&f->qlock);
			if (f->inuse) {
				qunlock(&f->qlock);
				continue;
			}
		}
		f->inuse = 1;
		qreopen(f->in);
		netown(f, current->user, 0);
		qunlock(&f->qlock);
		qunlock(&nif->qlock);
		poperror();
		return fp - nif->f;
	}
	error(ENODEV, ERROR_FIXME);
	return -1;	/* not reached */
}

/*
 *  look for a token starting a string,
 *  return a pointer to first non-space char after it
 */
static char *matchtoken(char *p, char *token)
{
	int n;

	n = strlen(token);
	if (strncmp(p, token, n))
		return 0;
	p += n;
	if (*p == 0)
		return p;
	if (*p != ' ' && *p != '\t' && *p != '\n')
		return 0;
	while (*p == ' ' || *p == '\t' || *p == '\n')
		p++;
	return p;
}

static uint32_t hash(uint8_t * a, int len)
{
	uint32_t sum = 0;

	while (len-- > 0)
		sum = (sum << 1) + *a++;
	return sum % Nmhash;
}

int activemulti(struct ether *nif, uint8_t * addr, int alen)
{
	struct netaddr *hp;

	for (hp = nif->mhash[hash(addr, alen)]; hp; hp = hp->hnext)
		if (memcmp(addr, hp->addr, alen) == 0) {
			if (hp->ref)
				return 1;
			else
				break;
		}
	return 0;
}

static int parseaddr(uint8_t * to, char *from, int alen)
{
	char nip[4];
	char *p;
	int i;

	p = from;
	for (i = 0; i < alen; i++) {
		if (*p == 0)
			return -1;
		nip[0] = *p++;
		if (*p == 0)
			return -1;
		nip[1] = *p++;
		nip[2] = 0;
		to[i] = strtoul(nip, 0, 16);
		if (*p == ':')
			p++;
	}
	return 0;
}

/*
 *  keep track of multicast addresses
 */
static char *netmulti(struct ether *nif, struct netfile *f, uint8_t * addr,
					  int add)
{
	struct netaddr **l, *ap;
	int i;
	uint32_t h;

	if (nif->multicast == NULL)
		return "interface does not support multicast";

	l = &nif->maddr;
	i = 0;
	for (ap = *l; ap; ap = *l) {
		if (memcmp(addr, ap->addr, nif->alen) == 0)
			break;
		i++;
		l = &ap->next;
	}

	if (add) {
		if (ap == 0) {
			/* TODO: AFAIK, this never gets freed.  if we fix that, we can use a
			 * kref too (instead of int ap->ref). */
			*l = ap = kzmalloc(sizeof(*ap), 0);
			memmove(ap->addr, addr, nif->alen);
			ap->next = 0;
			ap->ref = 1;
			h = hash(addr, nif->alen);
			ap->hnext = nif->mhash[h];
			nif->mhash[h] = ap;
		} else {
			ap->ref++;
		}
		if (ap->ref == 1) {
			nif->nmaddr++;
			nif->multicast(nif->arg, addr, 1);
		}
		if (i < 8 * sizeof(f->maddr)) {
			if ((f->maddr[i / 8] & (1 << (i % 8))) == 0)
				f->nmaddr++;
			f->maddr[i / 8] |= 1 << (i % 8);
		}
	} else {
		if (ap == 0 || ap->ref == 0)
			return 0;
		ap->ref--;
		if (ap->ref == 0) {
			nif->nmaddr--;
			nif->multicast(nif->arg, addr, 0);
		}
		if (i < 8 * sizeof(f->maddr)) {
			if ((f->maddr[i / 8] & (1 << (i % 8))) != 0)
				f->nmaddr--;
			f->maddr[i / 8] &= ~(1 << (i % 8));
		}
	}
	return 0;
}
