// INFERNO
#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>

#define DPRINT if(0)print

enum {
	Maxmedia = 32,
	Nself = Maxmedia * 5,
	NHASH = (1 << 6),
	NCACHE = 256,
	QMAX = 64 * 1024 - 1,
};

struct medium *media[Maxmedia] = {
	0
};

/*
 *  cache of local addresses (addresses we answer to)
 */
struct Ipself {
	uint8_t a[IPaddrlen];
	struct Ipself *hnext;		/* next address in the hash table */
	struct Iplink *link;		/* binding twixt Ipself and Ipifc */
	uint32_t expire;
	uint8_t type;				/* type of address */
	int ref;
	struct Ipself *next;		/* free list */
};

struct Ipselftab {
	qlock_t qlock;
	int inited;
	int acceptall;				/* true if an interface has the null address */
	struct Ipself *hash[NHASH];	/* hash chains */
};

/*
 *  Multicast addresses are chained onto a Chan so that
 *  we can remove them when the Chan is closed.
 */
typedef struct Ipmcast Ipmcast;
struct Ipmcast {
	Ipmcast *next;
	uint8_t ma[IPaddrlen];		/* multicast address */
	uint8_t ia[IPaddrlen];		/* interface address */
};

/* quick hash for ip addresses */
#define hashipa(a) ( ( ((a)[IPaddrlen-2]<<8) | (a)[IPaddrlen-1] )%NHASH )

static char tifc[] = "ifc ";

static void addselfcache(struct Fs *f, struct Ipifc *ifc, struct Iplifc *lifc,
						 uint8_t * a, int type);
static void remselfcache(struct Fs *f,
						 struct Ipifc *ifc, struct Iplifc *lifc, uint8_t * a);
static char *ipifcjoinmulti(struct Ipifc *ifc, char **argv, int argc);
static char *ipifcleavemulti(struct Ipifc *ifc, char **argv, int argc);
static void ipifcregisterproxy(struct Fs *, struct Ipifc *,
							   uint8_t * unused_uint8_p_t);
static char *ipifcremlifc(struct Ipifc *, struct Iplifc *);

/*
 *  link in a new medium
 */
void addipmedium(struct medium *med)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(media) - 1; i++)
		if (media[i] == NULL) {
			media[i] = med;
			break;
		}
}

/*
 *  find the medium with this name
 */
struct medium *ipfindmedium(char *name)
{
	struct medium **mp;

	for (mp = media; *mp != NULL; mp++)
		if (strcmp((*mp)->name, name) == 0)
			break;
	return *mp;
}

/*
 *  attach a device (or pkt driver) to the interface.
 *  called with c locked
 */
static char *ipifcbind(struct conv *c, char **argv, int argc)
{
	ERRSTACK(1);
	struct Ipifc *ifc;
	struct medium *m;

	if (argc < 2)
		return Ebadarg;

	ifc = (struct Ipifc *)c->ptcl;

	/* bind the device to the interface */
	m = ipfindmedium(argv[1]);
	if (m == NULL)
		return "unknown interface type";

	wlock(&ifc->rwlock);
	if (ifc->m != NULL) {
		wunlock(&ifc->rwlock);
		return "interface already bound";
	}
	if (waserror()) {
		wunlock(&ifc->rwlock);
		nexterror();
	}

	/* do medium specific binding */
	(*m->bind) (ifc, argc, argv);

	/* set the bound device name */
	if (argc > 2)
		strncpy(ifc->dev, argv[2], sizeof(ifc->dev));
	else
		snprintf(ifc->dev, sizeof ifc->dev, "%s%d", m->name, c->x);
	ifc->dev[sizeof(ifc->dev) - 1] = 0;

	/* set up parameters */
	ifc->m = m;
	ifc->mintu = ifc->m->mintu;
	ifc->maxtu = ifc->m->maxtu;
	if (ifc->m->unbindonclose == 0)
		ifc->conv->inuse++;
	ifc->rp.mflag = 0;	// default not managed
	ifc->rp.oflag = 0;
	ifc->rp.maxraint = 600000;	// millisecs
	ifc->rp.minraint = 200000;
	ifc->rp.linkmtu = 0;	// no mtu sent
	ifc->rp.reachtime = 0;
	ifc->rp.rxmitra = 0;
	ifc->rp.ttl = MAXTTL;
	ifc->rp.routerlt = 3 * (ifc->rp.maxraint);

	/* any ancillary structures (like routes) no longer pertain */
	ifc->ifcid++;

	/* reopen all the queues closed by a previous unbind */
	qreopen(c->rq);
	qreopen(c->eq);
	qreopen(c->sq);

	wunlock(&ifc->rwlock);
	poperror();

	return NULL;
}

/*
 *  detach a device from an interface, close the interface
 *  called with ifc->conv closed
 */
static char *ipifcunbind(struct Ipifc *ifc)
{
	ERRSTACK(1);
	char *err;

	if (waserror()) {
		wunlock(&ifc->rwlock);
		nexterror();
	}
	wlock(&ifc->rwlock);

	/* dissociate routes */
	if (ifc->m != NULL && ifc->m->unbindonclose == 0)
		ifc->conv->inuse--;
	ifc->ifcid++;

	/* disassociate device */
	if (ifc->m != NULL && ifc->m->unbind)
		(*ifc->m->unbind) (ifc);
	memset(ifc->dev, 0, sizeof(ifc->dev));
	ifc->arg = NULL;
	ifc->reassemble = 0;

	/* close queues to stop queuing of packets */
	qclose(ifc->conv->rq);
	qclose(ifc->conv->wq);
	qclose(ifc->conv->sq);

	/* disassociate logical interfaces */
	while (ifc->lifc) {
		err = ipifcremlifc(ifc, ifc->lifc);
		if (err)
			error(err);
	}

	ifc->m = NULL;
	wunlock(&ifc->rwlock);
	poperror();
	return NULL;
}

char sfixedformat[] =
	"device %s maxtu %d sendra %d recvra %d mflag %d oflag %d maxraint %d minraint %d linkmtu %d reachtime %d rxmitra %d ttl %d routerlt %d pktin %lu pktout %lu errin %lu errout %lu\n";

char slineformat[] = "	%-40I %-10M %-40I %-12lu %-12lu\n";

static int ipifcstate(struct conv *c, char *state, int n)
{
	struct Ipifc *ifc;
	struct Iplifc *lifc;
	int m;

	ifc = (struct Ipifc *)c->ptcl;

	m = snprintf(state, n, sfixedformat,
				 ifc->dev, ifc->maxtu, ifc->sendra6, ifc->recvra6,
				 ifc->rp.mflag, ifc->rp.oflag, ifc->rp.maxraint,
				 ifc->rp.minraint, ifc->rp.linkmtu, ifc->rp.reachtime,
				 ifc->rp.rxmitra, ifc->rp.ttl, ifc->rp.routerlt,
				 ifc->in, ifc->out, ifc->inerr, ifc->outerr);

	rlock(&ifc->rwlock);
	for (lifc = ifc->lifc; lifc && n > m; lifc = lifc->next)
		m += snprintf(state + m, n - m, slineformat,
					  lifc->local, lifc->mask, lifc->remote,
					  lifc->validlt, lifc->preflt);
	if (ifc->lifc == NULL)
		m += snprintf(state + m, n - m, "\n");
	runlock(&ifc->rwlock);
	return m;
}

static int ipifclocal(struct conv *c, char *state, int n)
{
	struct Ipifc *ifc;
	struct Iplifc *lifc;
	struct Iplink *link;
	int m;

	ifc = (struct Ipifc *)c->ptcl;

	m = 0;

	rlock(&ifc->rwlock);
	for (lifc = ifc->lifc; lifc; lifc = lifc->next) {
		m += snprintf(state + m, n - m, "%-40.40I ->", lifc->local);
		for (link = lifc->link; link; link = link->lifclink)
			m += snprintf(state + m, n - m, " %-40.40I", link->self->a);
		m += snprintf(state + m, n - m, "\n");
	}
	runlock(&ifc->rwlock);
	return m;
}

static int ipifcinuse(struct conv *c)
{
	struct Ipifc *ifc;

	ifc = (struct Ipifc *)c->ptcl;
	return ifc->m != NULL;
}

/*
 *  called when a process writes to an interface's 'data'
 */
static void ipifckick(void *x)
{
	ERRSTACK(1);
	struct conv *c = x;
	struct block *bp;
	struct Ipifc *ifc;

	bp = qget(c->wq);
	if (bp == NULL)
		return;

	ifc = (struct Ipifc *)c->ptcl;
	if (!canrlock(&ifc->rwlock)) {
		freeb(bp);
		return;
	}
	if (waserror()) {
		runlock(&ifc->rwlock);
		nexterror();
	}
	if (ifc->m == NULL || ifc->m->pktin == NULL)
		freeb(bp);
	else
		(*ifc->m->pktin) (c->p->f, ifc, bp);
	runlock(&ifc->rwlock);
	poperror();
}

/*
 *  called when a new ipifc structure is created
 */
static void ipifccreate(struct conv *c)
{
	struct Ipifc *ifc;

	c->rq = qopen(QMAX, 0, 0, 0);
	c->sq = qopen(2 * QMAX, 0, 0, 0);
	c->wq = qopen(QMAX, Qkick, ipifckick, c);
	ifc = (struct Ipifc *)c->ptcl;
	ifc->conv = c;
	ifc->unbinding = 0;
	ifc->m = NULL;
	ifc->reassemble = 0;
}

/*
 *  called after last close of ipifc data or ctl
 *  called with c locked, we must unlock
 */
static void ipifcclose(struct conv *c)
{
	struct Ipifc *ifc;
	struct medium *m;

	ifc = (struct Ipifc *)c->ptcl;
	m = ifc->m;
	if (m != NULL && m->unbindonclose)
		ipifcunbind(ifc);
}

/*
 *  change an interface's mtu
 */
char *ipifcsetmtu(struct Ipifc *ifc, char **argv, int argc)
{
	int mtu;

	if (argc < 2)
		return Ebadarg;
	if (ifc->m == NULL)
		return Ebadarg;
	mtu = strtoul(argv[1], 0, 0);
	if (mtu < ifc->m->mintu || mtu > ifc->m->maxtu)
		return Ebadarg;
	ifc->maxtu = mtu;
	return NULL;
}

/*
 *  add an address to an interface.
 */
char *ipifcadd(struct Ipifc *ifc, char **argv, int argc, int tentative,
			   struct Iplifc *lifcp)
{
	uint8_t ip[IPaddrlen], mask[IPaddrlen], rem[IPaddrlen];
	uint8_t bcast[IPaddrlen], net[IPaddrlen];
	struct Iplifc *lifc, **l;
	int i, type, mtu;
	struct Fs *f;
	int sendnbrdisc = 0;

	if (ifc->m == NULL)
		return "ipifc not yet bound to device";

	f = ifc->conv->p->f;

	type = Rifc;
	memset(ip, 0, IPaddrlen);
	memset(mask, 0, IPaddrlen);
	memset(rem, 0, IPaddrlen);
	switch (argc) {
		case 6:
			if (strcmp(argv[5], "proxy") == 0)
				type |= Rproxy;
			/* fall through */
		case 5:
			mtu = strtoul(argv[4], 0, 0);
			if (mtu >= ifc->m->mintu && mtu <= ifc->m->maxtu)
				ifc->maxtu = mtu;
			/* fall through */
		case 4:
			parseip(ip, argv[1]);
			parseipmask(mask, argv[2]);
			parseip(rem, argv[3]);
			maskip(rem, mask, net);
			break;
		case 3:
			parseip(ip, argv[1]);
			parseipmask(mask, argv[2]);
			maskip(ip, mask, rem);
			maskip(rem, mask, net);
			break;
		case 2:
			parseip(ip, argv[1]);
			memmove(mask, defmask(ip), IPaddrlen);
			maskip(ip, mask, rem);
			maskip(rem, mask, net);
			break;
		default:
			return Ebadarg;
			break;
	}
	if (isv4(ip))
		tentative = 0;
	wlock(&ifc->rwlock);

	/* ignore if this is already a local address for this ifc */
	for (lifc = ifc->lifc; lifc; lifc = lifc->next) {
		if (ipcmp(lifc->local, ip) == 0) {
			if (lifc->tentative != tentative)
				lifc->tentative = tentative;
			if (lifcp != NULL) {
				lifc->onlink = lifcp->onlink;
				lifc->autoflag = lifcp->autoflag;
				lifc->validlt = lifcp->validlt;
				lifc->preflt = lifcp->preflt;
				lifc->origint = lifcp->origint;
			}
			goto out;
		}
	}

	/* add the address to the list of logical ifc's for this ifc */
	lifc = kzmalloc(sizeof(struct Iplifc), 0);
	ipmove(lifc->local, ip);
	ipmove(lifc->mask, mask);
	ipmove(lifc->remote, rem);
	ipmove(lifc->net, net);
	lifc->tentative = tentative;
	if (lifcp != NULL) {
		lifc->onlink = lifcp->onlink;
		lifc->autoflag = lifcp->autoflag;
		lifc->validlt = lifcp->validlt;
		lifc->preflt = lifcp->preflt;
		lifc->origint = lifcp->origint;
	} else {	// default values
		lifc->onlink = 1;
		lifc->autoflag = 1;
		lifc->validlt = UINT64_MAX;
		lifc->preflt = UINT64_MAX;
		lifc->origint = NOW / 10 ^ 3;
	}
	lifc->next = NULL;

	for (l = &ifc->lifc; *l; l = &(*l)->next) ;
	*l = lifc;

	/* check for point-to-point interface */
	if (ipcmp(ip, v6loopback))	/* skip v6 loopback, it's a special address */
		if (ipcmp(mask, IPallbits) == 0)
			type |= Rptpt;

	/* add local routes */
	if (isv4(ip))
		v4addroute(f, tifc, rem + IPv4off, mask + IPv4off, rem + IPv4off, type);
	else
		v6addroute(f, tifc, rem, mask, rem, type);

	addselfcache(f, ifc, lifc, ip, Runi);

	if ((type & (Rproxy | Rptpt)) == (Rproxy | Rptpt)) {
		ipifcregisterproxy(f, ifc, rem);
		goto out;
	}

	if (isv4(ip) || ipcmp(ip, IPnoaddr) == 0) {
		/* add subnet directed broadcast address to the self cache */
		for (i = 0; i < IPaddrlen; i++)
			bcast[i] = (ip[i] & mask[i]) | ~mask[i];
		addselfcache(f, ifc, lifc, bcast, Rbcast);

		/* add subnet directed network address to the self cache */
		for (i = 0; i < IPaddrlen; i++)
			bcast[i] = (ip[i] & mask[i]) & mask[i];
		addselfcache(f, ifc, lifc, bcast, Rbcast);

		/* add network directed broadcast address to the self cache */
		memmove(mask, defmask(ip), IPaddrlen);
		for (i = 0; i < IPaddrlen; i++)
			bcast[i] = (ip[i] & mask[i]) | ~mask[i];
		addselfcache(f, ifc, lifc, bcast, Rbcast);

		/* add network directed network address to the self cache */
		memmove(mask, defmask(ip), IPaddrlen);
		for (i = 0; i < IPaddrlen; i++)
			bcast[i] = (ip[i] & mask[i]) & mask[i];
		addselfcache(f, ifc, lifc, bcast, Rbcast);

		addselfcache(f, ifc, lifc, IPv4bcast, Rbcast);
	} else {
		if (ipcmp(ip, v6loopback) == 0) {
			/* add node-local mcast address */
			addselfcache(f, ifc, lifc, v6allnodesN, Rmulti);

			/* add route for all node multicast */
			v6addroute(f, tifc, v6allnodesN, v6allnodesNmask, v6allnodesN,
					   Rmulti);
		}

		/* add all nodes multicast address */
		addselfcache(f, ifc, lifc, v6allnodesL, Rmulti);

		/* add route for all nodes multicast */
		v6addroute(f, tifc, v6allnodesL, v6allnodesLmask, v6allnodesL, Rmulti);

		/* add solicited-node multicast address */
		ipv62smcast(bcast, ip);
		addselfcache(f, ifc, lifc, bcast, Rmulti);

		sendnbrdisc = 1;
	}

	/* register the address on this network for address resolution */
	if (isv4(ip) && ifc->m->areg != NULL)
		(*ifc->m->areg) (ifc, ip);

out:
	wunlock(&ifc->rwlock);
	if (tentative && sendnbrdisc)
		icmpns(f, 0, SRC_UNSPEC, ip, TARG_MULTI, ifc->mac);
	return NULL;
}

/*
 *  remove a logical interface from an ifc
 *  always called with ifc wlock'd
 */
static char *ipifcremlifc(struct Ipifc *ifc, struct Iplifc *lifc)
{
	struct Iplifc **l;
	struct Fs *f;

	f = ifc->conv->p->f;

	/*
	 *  find address on this interface and remove from chain.
	 *  for pt to pt we actually specify the remote address as the
	 *  addresss to remove.
	 */
	for (l = &ifc->lifc; *l != NULL && *l != lifc; l = &(*l)->next) ;
	if (*l == NULL)
		return "address not on this interface";
	*l = lifc->next;

	/* disassociate any addresses */
	while (lifc->link)
		remselfcache(f, ifc, lifc, lifc->link->self->a);

	/* remove the route for this logical interface */
	if (isv4(lifc->local))
		v4delroute(f, lifc->remote + IPv4off, lifc->mask + IPv4off, 1);
	else {
		v6delroute(f, lifc->remote, lifc->mask, 1);
		if (ipcmp(lifc->local, v6loopback) == 0)
			/* remove route for all node multicast */
			v6delroute(f, v6allnodesN, v6allnodesNmask, 1);
		else if (memcmp(lifc->local, v6linklocal, v6llpreflen) == 0)
			/* remove route for all link multicast */
			v6delroute(f, v6allnodesL, v6allnodesLmask, 1);
	}

	kfree(lifc);
	return NULL;

}

/*
 *  remove an address from an interface.
 *  called with c locked
 */
char *ipifcrem(struct Ipifc *ifc, char **argv, int argc)
{
	uint8_t ip[IPaddrlen];
	uint8_t mask[IPaddrlen];
	uint8_t rem[IPaddrlen];
	struct Iplifc *lifc;
	char *rv;

	if (argc < 3)
		return Ebadarg;

	parseip(ip, argv[1]);
	parseipmask(mask, argv[2]);
	if (argc < 4)
		maskip(ip, mask, rem);
	else
		parseip(rem, argv[3]);

	wlock(&ifc->rwlock);

	/*
	 *  find address on this interface and remove from chain.
	 *  for pt to pt we actually specify the remote address as the
	 *  addresss to remove.
	 */
	for (lifc = ifc->lifc; lifc != NULL; lifc = lifc->next) {
		if (memcmp(ip, lifc->local, IPaddrlen) == 0
			&& memcmp(mask, lifc->mask, IPaddrlen) == 0
			&& memcmp(rem, lifc->remote, IPaddrlen) == 0)
			break;
	}

	rv = ipifcremlifc(ifc, lifc);
	wunlock(&ifc->rwlock);
	return rv;
}

/*
 * distribute routes to active interfaces like the
 * TRIP linecards
 */
void
ipifcaddroute(struct Fs *f, int vers, uint8_t * addr, uint8_t * mask,
			  uint8_t * gate, int type)
{
	struct medium *m;
	struct conv **cp, **e;
	struct Ipifc *ifc;

	e = &f->ipifc->conv[f->ipifc->nc];
	for (cp = f->ipifc->conv; cp < e; cp++) {
		if (*cp != NULL) {
			ifc = (struct Ipifc *)(*cp)->ptcl;
			m = ifc->m;
			if (m == NULL)
				continue;
			if (m->addroute != NULL)
				m->addroute(ifc, vers, addr, mask, gate, type);
		}
	}
}

void ipifcremroute(struct Fs *f, int vers, uint8_t * addr, uint8_t * mask)
{
	struct medium *m;
	struct conv **cp, **e;
	struct Ipifc *ifc;

	e = &f->ipifc->conv[f->ipifc->nc];
	for (cp = f->ipifc->conv; cp < e; cp++) {
		if (*cp != NULL) {
			ifc = (struct Ipifc *)(*cp)->ptcl;
			m = ifc->m;
			if (m == NULL)
				continue;
			if (m->remroute != NULL)
				m->remroute(ifc, vers, addr, mask);
		}
	}
}

/*
 *  associate an address with the interface.  This wipes out any previous
 *  addresses.  This is a macro that means, remove all the old interfaces
 *  and add a new one.
 */
static char *ipifcconnect(struct conv *c, char **argv, int argc)
{
	ERRSTACK(1);
	char *err;
	struct Ipifc *ifc;

	ifc = (struct Ipifc *)c->ptcl;

	if (ifc->m == NULL)
		return "ipifc not yet bound to device";

	if (waserror()) {
		wunlock(&ifc->rwlock);
		nexterror();
	}
	wlock(&ifc->rwlock);
	while (ifc->lifc) {
		err = ipifcremlifc(ifc, ifc->lifc);
		if (err)
			error(err);
	}
	wunlock(&ifc->rwlock);
	poperror();

	err = ipifcadd(ifc, argv, argc, 0, NULL);
	if (err)
		return err;

	Fsconnected(c, NULL);

	return NULL;
}

char *ipifcsetpar6(struct Ipifc *ifc, char **argv, int argc)
{
	int i, argsleft, vmax = ifc->rp.maxraint, vmin = ifc->rp.minraint;

	argsleft = argc - 1;
	i = 1;

	if (argsleft % 2 != 0)
		return Ebadarg;

	while (argsleft > 1) {
		if (strcmp(argv[i], "recvra") == 0)
			ifc->recvra6 = (atoi(argv[i + 1]) != 0);
		else if (strcmp(argv[i], "sendra") == 0)
			ifc->sendra6 = (atoi(argv[i + 1]) != 0);
		else if (strcmp(argv[i], "mflag") == 0)
			ifc->rp.mflag = (atoi(argv[i + 1]) != 0);
		else if (strcmp(argv[i], "oflag") == 0)
			ifc->rp.oflag = (atoi(argv[i + 1]) != 0);
		else if (strcmp(argv[i], "maxraint") == 0)
			ifc->rp.maxraint = atoi(argv[i + 1]);
		else if (strcmp(argv[i], "minraint") == 0)
			ifc->rp.minraint = atoi(argv[i + 1]);
		else if (strcmp(argv[i], "linkmtu") == 0)
			ifc->rp.linkmtu = atoi(argv[i + 1]);
		else if (strcmp(argv[i], "reachtime") == 0)
			ifc->rp.reachtime = atoi(argv[i + 1]);
		else if (strcmp(argv[i], "rxmitra") == 0)
			ifc->rp.rxmitra = atoi(argv[i + 1]);
		else if (strcmp(argv[i], "ttl") == 0)
			ifc->rp.ttl = atoi(argv[i + 1]);
		else if (strcmp(argv[i], "routerlt") == 0)
			ifc->rp.routerlt = atoi(argv[i + 1]);
		else
			return Ebadarg;

		argsleft -= 2;
		i += 2;
	}

	// consistency check
	if (ifc->rp.maxraint < ifc->rp.minraint) {
		ifc->rp.maxraint = vmax;
		ifc->rp.minraint = vmin;
		return Ebadarg;
	}

	return NULL;
}

char *ipifcsendra6(struct Ipifc *ifc, char **argv, int argc)
{
	int i;

	i = 0;
	if (argc > 1)
		i = atoi(argv[1]);
	ifc->sendra6 = (i != 0);
	return NULL;
}

char *ipifcrecvra6(struct Ipifc *ifc, char **argv, int argc)
{
	int i;

	i = 0;
	if (argc > 1)
		i = atoi(argv[1]);
	ifc->recvra6 = (i != 0);
	return NULL;
}

/*
 *  non-standard control messages.
 *  called with c locked.
 */
static char *ipifcctl(struct conv *c, char **argv, int argc)
{
	struct Ipifc *ifc;
	int i;

	ifc = (struct Ipifc *)c->ptcl;
	if (strcmp(argv[0], "add") == 0)
		return ipifcadd(ifc, argv, argc, 0, NULL);
	else if (strcmp(argv[0], "bootp") == 0)
		return bootp(ifc);
	else if (strcmp(argv[0], "try") == 0)
		return ipifcadd(ifc, argv, argc, 1, NULL);
	else if (strcmp(argv[0], "remove") == 0)
		return ipifcrem(ifc, argv, argc);
	else if (strcmp(argv[0], "unbind") == 0)
		return ipifcunbind(ifc);
	else if (strcmp(argv[0], "joinmulti") == 0)
		return ipifcjoinmulti(ifc, argv, argc);
	else if (strcmp(argv[0], "leavemulti") == 0)
		return ipifcleavemulti(ifc, argv, argc);
	else if (strcmp(argv[0], "mtu") == 0)
		return ipifcsetmtu(ifc, argv, argc);
	else if (strcmp(argv[0], "reassemble") == 0) {
		ifc->reassemble = 1;
		return NULL;
	} else if (strcmp(argv[0], "iprouting") == 0) {
		i = 1;
		if (argc > 1)
			i = atoi(argv[1]);
		iprouting(c->p->f, i);
		return NULL;
	} else if (strcmp(argv[0], "addpref6") == 0)
		return ipifcaddpref6(ifc, argv, argc);
	else if (strcmp(argv[0], "setpar6") == 0)
		return ipifcsetpar6(ifc, argv, argc);
	else if (strcmp(argv[0], "sendra6") == 0)
		return ipifcsendra6(ifc, argv, argc);
	else if (strcmp(argv[0], "recvra6") == 0)
		return ipifcrecvra6(ifc, argv, argc);
	return "unsupported ctl";
}

int ipifcstats(struct Proto *ipifc, char *buf, int len)
{
	return ipstats(ipifc->f, buf, len);
}

void ipifcinit(struct Fs *f)
{
	struct Proto *ipifc;

	ipifc = kzmalloc(sizeof(struct Proto), 0);
	ipifc->name = "ipifc";
	ipifc->connect = ipifcconnect;
	ipifc->announce = NULL;
	ipifc->bind = ipifcbind;
	ipifc->state = ipifcstate;
	ipifc->create = ipifccreate;
	ipifc->close = ipifcclose;
	ipifc->rcv = NULL;
	ipifc->ctl = ipifcctl;
	ipifc->advise = NULL;
	ipifc->stats = ipifcstats;
	ipifc->inuse = ipifcinuse;
	ipifc->local = ipifclocal;
	ipifc->ipproto = -1;
	ipifc->nc = Maxmedia;
	ipifc->ptclsize = sizeof(struct Ipifc);

	f->ipifc = ipifc;	/* hack for ipifcremroute, findipifc, ... */
	f->self = kzmalloc(sizeof(struct Ipselftab), 0);	/* hack for ipforme */
	qlock_init(&f->self->qlock);

	Fsproto(f, ipifc);
}

/*
 *  add to self routing cache
 *	called with c locked
 */
static void
addselfcache(struct Fs *f, struct Ipifc *ifc,
			 struct Iplifc *lifc, uint8_t * a, int type)
{
	struct Ipself *p;
	struct Iplink *lp;
	int h;

	qlock(&f->self->qlock);

	/* see if the address already exists */
	h = hashipa(a);
	for (p = f->self->hash[h]; p; p = p->next)
		if (memcmp(a, p->a, IPaddrlen) == 0)
			break;

	/* allocate a local address and add to hash chain */
	if (p == NULL) {
		p = kzmalloc(sizeof(*p), 0);
		ipmove(p->a, a);
		p->type = type;
		p->next = f->self->hash[h];
		f->self->hash[h] = p;

		/* if the null address, accept all packets */
		if (ipcmp(a, v4prefix) == 0 || ipcmp(a, IPnoaddr) == 0)
			f->self->acceptall = 1;
	}

	/* look for a link for this lifc */
	for (lp = p->link; lp; lp = lp->selflink)
		if (lp->lifc == lifc)
			break;

	/* allocate a lifc-to-local link and link to both */
	if (lp == NULL) {
		lp = kzmalloc(sizeof(*lp), 0);
		kref_init(&lp->ref, fake_release, 1);
		lp->lifc = lifc;
		lp->self = p;
		lp->selflink = p->link;
		p->link = lp;
		lp->lifclink = lifc->link;
		lifc->link = lp;

		/* add to routing table */
		if (isv4(a))
			v4addroute(f, tifc, a + IPv4off, IPallbits + IPv4off, a + IPv4off,
					   type);
		else
			v6addroute(f, tifc, a, IPallbits, a, type);

		if ((type & Rmulti) && ifc->m->addmulti != NULL)
			(*ifc->m->addmulti) (ifc, a, lifc->local);
	} else {
		kref_get(&lp->ref, 1);
	}

	qunlock(&f->self->qlock);
}

/*
 *  These structures are unlinked from their chains while
 *  other threads may be using them.  To avoid excessive locking,
 *  just put them aside for a while before freeing them.
 *	called with f->self locked
 */
static struct Iplink *freeiplink;
static struct Ipself *freeipself;

static void iplinkfree(struct Iplink *p)
{
	struct Iplink **l, *np;
	uint64_t now = NOW;

	l = &freeiplink;
	for (np = *l; np; np = *l) {
		if (np->expire > now) {
			*l = np->next;
			kfree(np);
			continue;
		}
		l = &np->next;
	}
	p->expire = now + 5000;	/* give other threads 5 secs to get out */
	p->next = NULL;
	*l = p;
}

static void ipselffree(struct Ipself *p)
{
	struct Ipself **l, *np;
	uint64_t now = NOW;

	l = &freeipself;
	for (np = *l; np; np = *l) {
		if (np->expire > now) {
			*l = np->next;
			kfree(np);
			continue;
		}
		l = &np->next;
	}
	p->expire = now + 5000;	/* give other threads 5 secs to get out */
	p->next = NULL;
	*l = p;
}

/*
 *  Decrement reference for this address on this link.
 *  Unlink from selftab if this is the last ref.
 *	called with c locked
 */
static void
remselfcache(struct Fs *f, struct Ipifc *ifc, struct Iplifc *lifc, uint8_t * a)
{
	struct Ipself *p, **l;
	struct Iplink *link, **l_self, **l_lifc;

	qlock(&f->self->qlock);

	/* find the unique selftab entry */
	l = &f->self->hash[hashipa(a)];
	for (p = *l; p; p = *l) {
		if (ipcmp(p->a, a) == 0)
			break;
		l = &p->next;
	}

	if (p == NULL)
		goto out;

	/*
	 *  walk down links from an ifc looking for one
	 *  that matches the selftab entry
	 */
	l_lifc = &lifc->link;
	for (link = *l_lifc; link; link = *l_lifc) {
		if (link->self == p)
			break;
		l_lifc = &link->lifclink;
	}

	if (link == NULL)
		goto out;

	/*
	 *  walk down the links from the selftab looking for
	 *  the one we just found
	 */
	l_self = &p->link;
	for (link = *l_self; link; link = *l_self) {
		if (link == *(l_lifc))
			break;
		l_self = &link->selflink;
	}

	if (link == NULL)
		panic("remselfcache");

	if (kref_refcnt(&link->ref) > 1)
		goto out;

	if ((p->type & Rmulti) && ifc->m->remmulti != NULL)
		(*ifc->m->remmulti) (ifc, a, lifc->local);

	/* ref == 0, remove from both chains and free the link */
	*l_lifc = link->lifclink;
	*l_self = link->selflink;
	iplinkfree(link);

	if (p->link != NULL)
		goto out;

	/* remove from routing table */
	if (isv4(a))
		v4delroute(f, a + IPv4off, IPallbits + IPv4off, 1);
	else
		v6delroute(f, a, IPallbits, 1);

	/* no more links, remove from hash and free */
	*l = p->next;
	ipselffree(p);

	/* if IPnoaddr, forget */
	if (ipcmp(a, v4prefix) == 0 || ipcmp(a, IPnoaddr) == 0)
		f->self->acceptall = 0;

out:
	qunlock(&f->self->qlock);
}

static char *stformat = "%-44.44I %2.2d %4.4s\n";
enum {
	Nstformat = 41,
};

long ipselftabread(struct Fs *f, char *cp, uint32_t offset, int n)
{
	int i, m, nifc, off;
	struct Ipself *p;
	struct Iplink *link;
	char state[8];

	m = 0;
	off = offset;
	qlock(&f->self->qlock);
	for (i = 0; i < NHASH && m < n; i++) {
		for (p = f->self->hash[i]; p != NULL && m < n; p = p->next) {
			nifc = 0;
			for (link = p->link; link; link = link->selflink)
				nifc++;
			routetype(p->type, state);
			m += snprintf(cp + m, n - m, stformat, p->a, nifc, state);
			if (off > 0) {
				off -= m;
				m = 0;
			}
		}
	}
	qunlock(&f->self->qlock);
	return m;
}

int iptentative(struct Fs *f, uint8_t * addr)
{
	struct Ipself *p;

	p = f->self->hash[hashipa(addr)];
	for (; p; p = p->next) {
		if (ipcmp(addr, p->a) == 0) {
			return p->link->lifc->tentative;
		}
	}
	return 0;
}

/*
 *  returns
 *	0		- no match
 *	Runi
 *	Rbcast
 *	Rmcast
 */
int ipforme(struct Fs *f, uint8_t * addr)
{
	struct Ipself *p;

	p = f->self->hash[hashipa(addr)];
	for (; p; p = p->next) {
		if (ipcmp(addr, p->a) == 0)
			return p->type;
	}

	/* hack to say accept anything */
	if (f->self->acceptall)
		return Runi;

	return 0;
}

/*
 *  find the ifc on same net as the remote system.  If none,
 *  return NULL.
 */
struct Ipifc *findipifc(struct Fs *f, uint8_t * remote, int type)
{
	struct Ipifc *ifc, *x;
	struct Iplifc *lifc;
	struct conv **cp, **e;
	uint8_t gnet[IPaddrlen];
	uint8_t xmask[IPaddrlen];

	x = NULL;
	memset(xmask, 0, IPaddrlen);

	/* find most specific match */
	e = &f->ipifc->conv[f->ipifc->nc];
	for (cp = f->ipifc->conv; cp < e; cp++) {
		if (*cp == 0)
			continue;

		ifc = (struct Ipifc *)(*cp)->ptcl;

		for (lifc = ifc->lifc; lifc; lifc = lifc->next) {
			maskip(remote, lifc->mask, gnet);
			if (ipcmp(gnet, lifc->net) == 0) {
				if (x == NULL || ipcmp(lifc->mask, xmask) > 0) {
					x = ifc;
					ipmove(xmask, lifc->mask);
				}
			}
		}
	}
	if (x != NULL)
		return x;

	/* for now for broadcast and multicast, just use first interface */
	if (type & (Rbcast | Rmulti)) {
		for (cp = f->ipifc->conv; cp < e; cp++) {
			if (*cp == 0)
				continue;
			ifc = (struct Ipifc *)(*cp)->ptcl;
			if (ifc->lifc != NULL)
				return ifc;
		}
	}

	return NULL;
}

enum {
	unknownv6,
	multicastv6,
	unspecifiedv6,
	linklocalv6,
	sitelocalv6,
	globalv6,
};

int v6addrtype(uint8_t * addr)
{
	if (isv6global(addr))
		return globalv6;
	if (islinklocal(addr))
		return linklocalv6;
	if (isv6mcast(addr))
		return multicastv6;
	if (issitelocal(addr))
		return sitelocalv6;
	return unknownv6;
}

#define v6addrcurr(lifc) (( (lifc)->origint + (lifc)->preflt >= (NOW/10^3) ) || ( (lifc)->preflt == UINT64_MAX ))

static void findprimaryipv6(struct Fs *f, uint8_t * local)
{
	struct conv **cp, **e;
	struct Ipifc *ifc;
	struct Iplifc *lifc;
	int atype, atypel;

	ipmove(local, v6Unspecified);
	atype = unspecifiedv6;

	/* find "best" (global > sitelocal > link local > unspecified)
	 * local address; address must be current */

	e = &f->ipifc->conv[f->ipifc->nc];
	for (cp = f->ipifc->conv; cp < e; cp++) {
		if (*cp == 0)
			continue;
		ifc = (struct Ipifc *)(*cp)->ptcl;
		for (lifc = ifc->lifc; lifc; lifc = lifc->next) {
			atypel = v6addrtype(lifc->local);
			if (atypel > atype)
				if (v6addrcurr(lifc)) {
					ipmove(local, lifc->local);
					atype = atypel;
					if (atype == globalv6)
						return;
				}
		}
	}
}

/*
 *  returns first ip address configured
 */
static void findprimaryipv4(struct Fs *f, uint8_t * local)
{
	struct conv **cp, **e;
	struct Ipifc *ifc;
	struct Iplifc *lifc;

	/* find first ifc local address */
	e = &f->ipifc->conv[f->ipifc->nc];
	for (cp = f->ipifc->conv; cp < e; cp++) {
		if (*cp == 0)
			continue;
		ifc = (struct Ipifc *)(*cp)->ptcl;
		if ((lifc = ifc->lifc) != NULL) {
			ipmove(local, lifc->local);
			return;
		}
	}
}

/*
 *  find the local address 'closest' to the remote system, copy it to
 *  local and return the ifc for that address
 */
void findlocalip(struct Fs *f, uint8_t * local, uint8_t * remote)
{
	struct Ipifc *ifc;
	struct Iplifc *lifc;
	struct route *r;
	uint8_t gate[IPaddrlen];
	uint8_t gnet[IPaddrlen];
	int version;
	int atype = unspecifiedv6, atypel = unknownv6;

	qlock(&f->ipifc->qlock);
	r = v6lookup(f, remote, NULL);
	version = isv4(remote) ? V4 : V6;

	if (r != NULL) {
		ifc = r->rt.ifc;
		if (r->rt.type & Rv4)
			v4tov6(gate, r->v4.gate);
		else {
			ipmove(gate, r->v6.gate);
			ipmove(local, v6Unspecified);
		}

		/* find ifc address closest to the gateway to use */
		switch (version) {
			case V4:
				for (lifc = ifc->lifc; lifc; lifc = lifc->next) {
					maskip(gate, lifc->mask, gnet);
					if (ipcmp(gnet, lifc->net) == 0) {
						ipmove(local, lifc->local);
						goto out;
					}
				}
				break;
			case V6:
				for (lifc = ifc->lifc; lifc; lifc = lifc->next) {
					atypel = v6addrtype(lifc->local);
					maskip(gate, lifc->mask, gnet);
					if (ipcmp(gnet, lifc->net) == 0)
						if (atypel > atype)
							if (v6addrcurr(lifc)) {
								ipmove(local, lifc->local);
								atype = atypel;
								if (atype == globalv6)
									break;
							}
				}
				if (atype > unspecifiedv6)
					goto out;
				break;
			default:
				panic("findlocalip: version %d", version);
		}
	}

	switch (version) {
		case V4:
			findprimaryipv4(f, local);
			break;
		case V6:
			findprimaryipv6(f, local);
			break;
		default:
			panic("findlocalip2: version %d", version);
	}

out:
	qunlock(&f->ipifc->qlock);
}

/*
 *  return first v4 address associated with an interface
 */
int ipv4local(struct Ipifc *ifc, uint8_t * addr)
{
	struct Iplifc *lifc;

	for (lifc = ifc->lifc; lifc; lifc = lifc->next) {
		if (isv4(lifc->local)) {
			memmove(addr, lifc->local + IPv4off, IPv4addrlen);
			return 1;
		}
	}
	return 0;
}

/*
 *  return first v6 address associated with an interface
 */
int ipv6local(struct Ipifc *ifc, uint8_t * addr)
{
	struct Iplifc *lifc;

	for (lifc = ifc->lifc; lifc; lifc = lifc->next) {
		if (!isv4(lifc->local) && !(lifc->tentative)) {
			ipmove(addr, lifc->local);
			return 1;
		}
	}
	return 0;
}

int ipv6anylocal(struct Ipifc *ifc, uint8_t * addr)
{
	struct Iplifc *lifc;

	for (lifc = ifc->lifc; lifc; lifc = lifc->next) {
		if (!isv4(lifc->local)) {
			ipmove(addr, lifc->local);
			return SRC_UNI;
		}
	}
	return SRC_UNSPEC;
}

/*
 *  see if this address is bound to the interface
 */
struct Iplifc *iplocalonifc(struct Ipifc *ifc, uint8_t * ip)
{
	struct Iplifc *lifc;

	for (lifc = ifc->lifc; lifc; lifc = lifc->next)
		if (ipcmp(ip, lifc->local) == 0)
			return lifc;
	return NULL;
}

/*
 *  See if we're proxying for this address on this interface
 */
int ipproxyifc(struct Fs *f, struct Ipifc *ifc, uint8_t * ip)
{
	struct route *r;
	uint8_t net[IPaddrlen];
	struct Iplifc *lifc;

	/* see if this is a direct connected pt to pt address */
	r = v6lookup(f, ip, NULL);
	if (r == NULL)
		return 0;
	if ((r->rt.type & (Rifc | Rproxy)) != (Rifc | Rproxy))
		return 0;

	/* see if this is on the right interface */
	for (lifc = ifc->lifc; lifc; lifc = lifc->next) {
		maskip(ip, lifc->mask, net);
		if (ipcmp(net, lifc->remote) == 0)
			return 1;
	}

	return 0;
}

/*
 *  return multicast version if any
 */
int ipismulticast(uint8_t * ip)
{
	if (isv4(ip)) {
		if (ip[IPv4off] >= 0xe0 && ip[IPv4off] < 0xf0)
			return V4;
	} else {
		if (ip[0] == 0xff)
			return V6;
	}
	return 0;
}

int ipisbm(uint8_t * ip)
{
	if (isv4(ip)) {
		if (ip[IPv4off] >= 0xe0 && ip[IPv4off] < 0xf0)
			return V4;
		if (ipcmp(ip, IPv4bcast) == 0)
			return V4;
	} else {
		if (ip[0] == 0xff)
			return V6;
	}
	return 0;
}

/*
 *  add a multicast address to an interface, called with c locked
 */
void ipifcaddmulti(struct conv *c, uint8_t * ma, uint8_t * ia)
{
	ERRSTACK(1);
	struct Ipifc *ifc;
	struct Iplifc *lifc;
	struct conv **p;
	struct Ipmulti *multi, **l;
	struct Fs *f;

	f = c->p->f;

	for (l = &c->multi; *l; l = &(*l)->next)
		if (ipcmp(ma, (*l)->ma) == 0)
			if (ipcmp(ia, (*l)->ia) == 0)
				return;	/* it's already there */

	multi = *l = kzmalloc(sizeof(*multi), 0);
	ipmove(multi->ma, ma);
	ipmove(multi->ia, ia);
	multi->next = NULL;

	for (p = f->ipifc->conv; *p; p++) {
		if ((*p)->inuse == 0)
			continue;
		ifc = (struct Ipifc *)(*p)->ptcl;
		if (waserror()) {
			wunlock(&ifc->rwlock);
			nexterror();
		}
		wlock(&ifc->rwlock);
		for (lifc = ifc->lifc; lifc; lifc = lifc->next)
			if (ipcmp(ia, lifc->local) == 0)
				addselfcache(f, ifc, lifc, ma, Rmulti);
		wunlock(&ifc->rwlock);
		poperror();
	}
}

/*
 *  remove a multicast address from an interface, called with c locked
 */
void ipifcremmulti(struct conv *c, uint8_t * ma, uint8_t * ia)
{
	ERRSTACK(1);
	struct Ipmulti *multi, **l;
	struct Iplifc *lifc;
	struct conv **p;
	struct Ipifc *ifc;
	struct Fs *f;

	f = c->p->f;

	for (l = &c->multi; *l; l = &(*l)->next)
		if (ipcmp(ma, (*l)->ma) == 0)
			if (ipcmp(ia, (*l)->ia) == 0)
				break;

	multi = *l;
	if (multi == NULL)
		return;	/* we don't have it open */

	*l = multi->next;

	for (p = f->ipifc->conv; *p; p++) {
		if ((*p)->inuse == 0)
			continue;

		ifc = (struct Ipifc *)(*p)->ptcl;
		if (waserror()) {
			wunlock(&ifc->rwlock);
			nexterror();
		}
		wlock(&ifc->rwlock);
		for (lifc = ifc->lifc; lifc; lifc = lifc->next)
			if (ipcmp(ia, lifc->local) == 0)
				remselfcache(f, ifc, lifc, ma);
		wunlock(&ifc->rwlock);
		poperror();
	}

	kfree(multi);
}

/*
 *  make lifc's join and leave multicast groups
 */
static char *ipifcjoinmulti(struct Ipifc *ifc, char **argv, int argc)
{
	return NULL;
}

static char *ipifcleavemulti(struct Ipifc *ifc, char **argv, int argc)
{
	return NULL;
}

static void ipifcregisterproxy(struct Fs *f, struct Ipifc *ifc, uint8_t * ip)
{
	struct conv **cp, **e;
	struct Ipifc *nifc;
	struct Iplifc *lifc;
	struct medium *m;
	uint8_t net[IPaddrlen];

	/* register the address on any network that will proxy for us */
	e = &f->ipifc->conv[f->ipifc->nc];

	if (!isv4(ip)) {	// V6
		for (cp = f->ipifc->conv; cp < e; cp++) {
			if (*cp == NULL)
				continue;
			nifc = (struct Ipifc *)(*cp)->ptcl;
			if (nifc == ifc)
				continue;

			rlock(&nifc->rwlock);
			m = nifc->m;
			if (m == NULL || m->addmulti == NULL) {
				runlock(&nifc->rwlock);
				continue;
			}
			for (lifc = nifc->lifc; lifc; lifc = lifc->next) {
				maskip(ip, lifc->mask, net);
				if (ipcmp(net, lifc->remote) == 0) {	/* add solicited-node multicast address */
					ipv62smcast(net, ip);
					addselfcache(f, nifc, lifc, net, Rmulti);
					arpenter(f, V6, ip, nifc->mac, 6, 0);
					//(*m->addmulti)(nifc, net, ip);
					break;
				}
			}
			runlock(&nifc->rwlock);
		}
		return;
	} else {	// V4
		for (cp = f->ipifc->conv; cp < e; cp++) {
			if (*cp == NULL)
				continue;
			nifc = (struct Ipifc *)(*cp)->ptcl;
			if (nifc == ifc)
				continue;

			rlock(&nifc->rwlock);
			m = nifc->m;
			if (m == NULL || m->areg == NULL) {
				runlock(&nifc->rwlock);
				continue;
			}
			for (lifc = nifc->lifc; lifc; lifc = lifc->next) {
				maskip(ip, lifc->mask, net);
				if (ipcmp(net, lifc->remote) == 0) {
					(*m->areg) (nifc, ip);
					break;
				}
			}
			runlock(&nifc->rwlock);
		}
	}
}

// added for new v6 mesg types
static void adddefroute6(struct Fs *f, uint8_t * gate, int force)
{
	struct route *r;

	r = v6lookup(f, v6Unspecified, NULL);
	if (r != NULL)
		if (!(force) && (strcmp(r->rt.tag, "ra") != 0))	// route entries generated
			return;	// by all other means take
	// precedence over router annc

	v6delroute(f, v6Unspecified, v6Unspecified, 1);
	v6addroute(f, "ra", v6Unspecified, v6Unspecified, gate, 0);
}

enum {
	Ngates = 3,
};

char *ipifcaddpref6(struct Ipifc *ifc, char **argv, int argc)
{
	uint8_t onlink = 1;
	uint8_t autoflag = 1;
	uint64_t validlt = UINT64_MAX;
	uint64_t preflt = UINT64_MAX;
	uint64_t origint = NOW / 10 ^ 3;
	uint8_t prefix[IPaddrlen];
	int plen = 64;
	struct Iplifc *lifc;
	char addr[40], preflen[6];
	char *params[3];

	switch (argc) {
		case 7:
			preflt = atoi(argv[6]);
			/* fall through */
		case 6:
			validlt = atoi(argv[5]);
			/* fall through */
		case 5:
			autoflag = atoi(argv[4]);
			/* fall through */
		case 4:
			onlink = atoi(argv[3]);
			/* fall through */
		case 3:
			plen = atoi(argv[2]);
		case 2:
			break;
		default:
			return Ebadarg;
	}

	if ((parseip(prefix, argv[1]) != 6) ||
		(validlt < preflt) || (plen < 0) || (plen > 64) || (islinklocal(prefix))
		)
		return Ebadarg;

	lifc = kzmalloc(sizeof(struct Iplifc), 0);
	lifc->onlink = (onlink != 0);
	lifc->autoflag = (autoflag != 0);
	lifc->validlt = validlt;
	lifc->preflt = preflt;
	lifc->origint = origint;

	if (ifc->m->pref2addr != NULL)
		ifc->m->pref2addr(prefix, ifc->mac);
	else
		return Ebadarg;

	snprintf(addr, sizeof(addr), "%I", prefix);
	snprintf(preflen, sizeof(preflen), "/%d", plen);
	params[0] = "add";
	params[1] = addr;
	params[2] = preflen;

	return ipifcadd(ifc, params, 3, 0, lifc);
}
