/* 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 <kmalloc.h>
#include <string.h>
#include <stdio.h>
#include <syscall.h>
#include <error.h>
#include <net/ip.h>

struct ICMPpkt {
	uint8_t type;
	uint8_t code;
	uint8_t cksum[2];
	uint8_t icmpid[2];
	uint8_t seq[2];
};

/* plan 9 uses anon struct members.
 * We have been naming the struct
 * members and just using the extra level of deref
 * e.g. i->x becomes i->i6->x.
 */
struct IPICMP {
/*
	Ip6hdr;
	ICMPpkt;
*/
	uint8_t vcf[4];		// version:4, traffic class:8, flow label:20
	uint8_t ploadlen[2];	// payload length: packet length - 40
	uint8_t proto;		// next header type
	uint8_t ttl;		// hop limit
	uint8_t src[IPaddrlen];
	uint8_t dst[IPaddrlen];
	uint8_t type;
	uint8_t code;
	uint8_t cksum[2];
	uint8_t icmpid[2];
	uint8_t seq[2];

};

struct NdiscC {
	//IPICMP;
	uint8_t vcf[4];		// version:4, traffic class:8, flow label:20
	uint8_t ploadlen[2];	// payload length: packet length - 40
	uint8_t proto;		// next header type
	uint8_t ttl;		// hop limit
	uint8_t src[IPaddrlen];
	uint8_t dst[IPaddrlen];
	uint8_t type;
	uint8_t code;
	uint8_t cksum[2];
	uint8_t icmpid[2];
	uint8_t seq[2];

	uint8_t target[IPaddrlen];
};

struct Ndpkt {
	//NdiscC;
	uint8_t vcf[4];		// version:4, traffic class:8, flow label:20
	uint8_t ploadlen[2];	// payload length: packet length - 40
	uint8_t proto;		// next header type
	uint8_t ttl;		// hop limit
	uint8_t src[IPaddrlen];
	uint8_t dst[IPaddrlen];
	uint8_t type;
	uint8_t code;
	uint8_t cksum[2];
	uint8_t icmpid[2];
	uint8_t seq[2];

	uint8_t target[IPaddrlen];

	uint8_t otype;
	uint8_t olen;		// length in units of 8 octets(incl type, code),
	// 1 for IEEE 802 addresses
	uint8_t lnaddr[6];	// link-layer address
};

enum {
	// ICMPv6 types
	EchoReply = 0,
	UnreachableV6 = 1,
	PacketTooBigV6 = 2,
	TimeExceedV6 = 3,
	SrcQuench = 4,
	ParamProblemV6 = 4,
	Redirect = 5,
	EchoRequest = 8,
	TimeExceed = 11,
	InParmProblem = 12,
	Timestamp = 13,
	TimestampReply = 14,
	InfoRequest = 15,
	InfoReply = 16,
	AddrMaskRequest = 17,
	AddrMaskReply = 18,
	EchoRequestV6 = 128,
	EchoReplyV6 = 129,
	RouterSolicit = 133,
	RouterAdvert = 134,
	NbrSolicit = 135,
	NbrAdvert = 136,
	RedirectV6 = 137,

	Maxtype6 = 137,
};

char *icmpnames6[Maxtype6 + 1] = {
	[EchoReply] "EchoReply",
	[UnreachableV6] "UnreachableV6",
	[PacketTooBigV6] "PacketTooBigV6",
	[TimeExceedV6] "TimeExceedV6",
	[SrcQuench] "SrcQuench",
	[Redirect] "Redirect",
	[EchoRequest] "EchoRequest",
	[TimeExceed] "TimeExceed",
	[InParmProblem] "InParmProblem",
	[Timestamp] "Timestamp",
	[TimestampReply] "TimestampReply",
	[InfoRequest] "InfoRequest",
	[InfoReply] "InfoReply",
	[AddrMaskRequest] "AddrMaskRequest",
	[AddrMaskReply] "AddrMaskReply",
	[EchoRequestV6] "EchoRequestV6",
	[EchoReplyV6] "EchoReplyV6",
	[RouterSolicit] "RouterSolicit",
	[RouterAdvert] "RouterAdvert",
	[NbrSolicit] "NbrSolicit",
	[NbrAdvert] "NbrAdvert",
	[RedirectV6] "RedirectV6",
};

enum {
	InMsgs6,
	InErrors6,
	OutMsgs6,
	CsumErrs6,
	LenErrs6,
	HlenErrs6,
	HoplimErrs6,
	IcmpCodeErrs6,
	TargetErrs6,
	OptlenErrs6,
	AddrmxpErrs6,
	RouterAddrErrs6,

	Nstats6,
};

static char *statnames6[Nstats6] = {
	[InMsgs6] "InMsgs",
	[InErrors6] "InErrors",
	[OutMsgs6] "OutMsgs",
	[CsumErrs6] "CsumErrs",
	[LenErrs6] "LenErrs",
	[HlenErrs6] "HlenErrs",
	[HoplimErrs6] "HoplimErrs",
	[IcmpCodeErrs6] "IcmpCodeErrs",
	[TargetErrs6] "TargetErrs",
	[OptlenErrs6] "OptlenErrs",
	[AddrmxpErrs6] "AddrmxpErrs",
	[RouterAddrErrs6] "RouterAddrErrs",
};

typedef struct Icmppriv6 {
	uint32_t stats[Nstats6];

	/* message counts */
	uint32_t in[Maxtype6 + 1];
	uint32_t out[Maxtype6 + 1];
} Icmppriv6;

typedef struct Icmpcb6 {
	uint8_t headers;
} Icmpcb6;

static char *unreachcode[] = {
	[icmp6_no_route] "no route to destination",
	[icmp6_ad_prohib] "comm with destination administratively prohibited",
	[icmp6_unassigned] "icmp unreachable: unassigned error code (2)",
	[icmp6_adr_unreach] "address unreachable",
	[icmp6_port_unreach] "port unreachable",
	[icmp6_unkn_code] "icmp unreachable: unknown code",
};

enum {
	ICMP_USEAD6 = 40,
};

enum {
	Oflag = 1 << 5,
	Sflag = 1 << 6,
	Rflag = 1 << 7,
};

enum {
	slladd = 1,
	tlladd = 2,
	prfinfo = 3,
	redhdr = 4,
	mtuopt = 5,
};

static void icmpkick6(void *x, struct block *bp);

static void icmpcreate6(struct conv *c)
{
	c->rq = qopen(64 * 1024, Qmsg, 0, c);
	c->wq = qbypass(icmpkick6, c);
}

static void set_cksum(struct block *bp)
{
	struct IPICMP *p = (struct IPICMP *)(bp->rp);

	hnputl(p->vcf, 0);	// borrow IP header as pseudoheader
	hnputs(p->ploadlen, blocklen(bp) - IPV6HDR_LEN);
	p->proto = 0;
	p->ttl = ICMPv6;	// ttl gets set later
	hnputs(p->cksum, 0);
	hnputs(p->cksum, ptclcsum(bp, 0, blocklen(bp)));
	p->proto = ICMPv6;
}

static struct block *newIPICMP(int packetlen)
{
	struct block *nbp;

	nbp = block_alloc(packetlen, MEM_WAIT);
	nbp->wp += packetlen;
	memset(nbp->rp, 0, packetlen);
	return nbp;
}

void icmpadvise6(struct Proto *icmp, struct block *bp, char *msg)
{
	struct conv **c, *s;
	struct IPICMP *p;
	uint16_t recid;

	p = (struct IPICMP *)bp->rp;
	recid = nhgets(p->icmpid);

	for (c = icmp->conv; *c; c++) {
		s = *c;
		if (s->lport == recid)
			if (ipcmp(s->raddr, p->dst) == 0) {
				qhangup(s->rq, msg);
				qhangup(s->wq, msg);
				break;
			}
	}
	freeblist(bp);
}

static void icmpkick6(void *x, struct block *bp)
{
	struct conv *c = x;
	struct IPICMP *p;
	uint8_t laddr[IPaddrlen], raddr[IPaddrlen];
	Icmppriv6 *ipriv = c->p->priv;
	Icmpcb6 *icb = (struct Icmpcb6 *)c->ptcl;

	if (bp == NULL)
		return;

	if (icb->headers == 6) {
		/* get user specified addresses */
		bp = pullupblock(bp, ICMP_USEAD6);
		if (bp == NULL)
			return;
		bp->rp += 8;
		ipmove(laddr, bp->rp);
		bp->rp += IPaddrlen;
		ipmove(raddr, bp->rp);
		bp->rp += IPaddrlen;
		bp = padblock(bp, sizeof(struct ip6hdr));

		if (blocklen(bp) < sizeof(struct IPICMP)) {
			freeblist(bp);
			return;
		}
		p = (struct IPICMP *)(bp->rp);

		ipmove(p->dst, raddr);
		ipmove(p->src, laddr);

	} else {
		if (blocklen(bp) < sizeof(struct IPICMP)) {
			freeblist(bp);
			return;
		}
		p = (struct IPICMP *)(bp->rp);

		ipmove(p->dst, c->raddr);
		ipmove(p->src, c->laddr);
		hnputs(p->icmpid, c->lport);
	}

	set_cksum(bp);
	p->vcf[0] = 0x06 << 4;
	if (p->type <= Maxtype6)
		ipriv->out[p->type]++;
	ipoput6(c->p->f, bp, 0, c->ttl, c->tos, NULL);
}

static void icmpctl6(struct conv *c, char **argv, int argc)
{
	Icmpcb6 *icb = (Icmpcb6*)c->ptcl;

	if ((argc == 1) && strcmp(argv[0], "headers") == 0)
		icb->headers = 6;
	else
		error(EINVAL, "unknown command to icmpctl6");
}

static void goticmpkt6(struct Proto *icmp, struct block *bp, int muxkey)
{
	struct conv **c, *s;
	struct IPICMP *p = (struct IPICMP *)bp->rp;
	uint16_t recid;
	uint8_t *addr;

	if (muxkey == 0) {
		recid = nhgets(p->icmpid);
		addr = p->src;
	} else {
		recid = muxkey;
		addr = p->dst;
	}

	for (c = icmp->conv; *c; c++) {
		s = *c;
		if (s->lport == recid && ipcmp(s->raddr, addr) == 0) {
			bp = concatblock(bp);
			if (bp != NULL)
				qpass(s->rq, bp);
			return;
		}
	}

	freeblist(bp);
}

static struct block *mkechoreply6(struct block *bp)
{
	struct IPICMP *p = (struct IPICMP *)(bp->rp);
	uint8_t addr[IPaddrlen];

	ipmove(addr, p->src);
	ipmove(p->src, p->dst);
	ipmove(p->dst, addr);
	p->type = EchoReplyV6;
	set_cksum(bp);
	return bp;
}

/*
 * sends out an ICMPv6 neighbor solicitation
 * 	suni == SRC_UNSPEC or SRC_UNI,
 *	tuni == TARG_MULTI => multicast for address resolution,
 * 	and tuni == TARG_UNI => neighbor reachability.
 */

void icmpns(struct Fs *f, uint8_t *src, int suni, uint8_t *targ, int tuni,
	    uint8_t *mac)
{
	struct block *nbp;
	struct Ndpkt *np;
	struct Proto *icmp = f->t2p[ICMPv6];
	struct Icmppriv6 *ipriv = icmp->priv;

	nbp = newIPICMP(sizeof(struct Ndpkt));
	np = (struct Ndpkt *)nbp->rp;

	if (suni == SRC_UNSPEC)
		memmove(np->src, v6Unspecified, IPaddrlen);
	else
		memmove(np->src, src, IPaddrlen);

	if (tuni == TARG_UNI)
		memmove(np->dst, targ, IPaddrlen);
	else
		ipv62smcast(np->dst, targ);

	np->type = NbrSolicit;
	np->code = 0;
	memmove(np->target, targ, IPaddrlen);
	if (suni != SRC_UNSPEC) {
		np->otype = SRC_LLADDRESS;
		np->olen = 1;	/* 1+1+6 = 8 = 1 8-octet */
		memmove(np->lnaddr, mac, sizeof(np->lnaddr));
	} else {
		int r = sizeof(struct Ndpkt) - sizeof(struct NdiscC);
		nbp->wp -= r;
	}

	set_cksum(nbp);
	np = (struct Ndpkt *)nbp->rp;
	np->ttl = HOP_LIMIT;
	np->vcf[0] = 0x06 << 4;
	ipriv->out[NbrSolicit]++;
	netlog(f, Logicmp, "sending neighbor solicitation %I\n", targ);
	ipoput6(f, nbp, 0, MAXTTL, DFLTTOS, NULL);
}

/*
 * sends out an ICMPv6 neighbor advertisement. pktflags == RSO flags.
 */
void icmpna(struct Fs *f, uint8_t * src, uint8_t * dst, uint8_t * targ,
            uint8_t * mac, uint8_t flags)
{
	struct block *nbp;
	struct Ndpkt *np;
	struct Proto *icmp = f->t2p[ICMPv6];
	Icmppriv6 *ipriv = icmp->priv;

	nbp = newIPICMP(sizeof(struct Ndpkt));
	np = (struct Ndpkt *)nbp->rp;

	memmove(np->src, src, IPaddrlen);
	memmove(np->dst, dst, IPaddrlen);

	np->type = NbrAdvert;
	np->code = 0;
	np->icmpid[0] = flags;
	memmove(np->target, targ, IPaddrlen);

	np->otype = TARGET_LLADDRESS;
	np->olen = 1;
	memmove(np->lnaddr, mac, sizeof(np->lnaddr));

	set_cksum(nbp);
	np = (struct Ndpkt *)nbp->rp;
	np->ttl = HOP_LIMIT;
	np->vcf[0] = 0x06 << 4;
	ipriv->out[NbrAdvert]++;
	netlog(f, Logicmp, "sending neighbor advertisement %I\n", src);
	ipoput6(f, nbp, 0, MAXTTL, DFLTTOS, NULL);
}

void icmphostunr(struct Fs *f, struct Ipifc *ifc,
                 struct block *bp, int code, int free)
{
	struct block *nbp;
	struct IPICMP *np;
	struct ip6hdr *p;
	int osz = BLEN(bp);
	int sz = MIN(sizeof(struct IPICMP) + osz, v6MINTU);
	struct Proto *icmp = f->t2p[ICMPv6];
	Icmppriv6 *ipriv = icmp->priv;

	p = (struct ip6hdr *)bp->rp;

	if (isv6mcast(p->src))
		goto freebl;

	nbp = newIPICMP(sz);
	np = (struct IPICMP *)nbp->rp;

	rlock(&ifc->rwlock);
	if (ipv6anylocal(ifc, np->src)) {
		netlog(f, Logicmp, "send icmphostunr -> s%I d%I\n",
		       p->src, p->dst);
	} else {
		netlog(f, Logicmp, "icmphostunr fail -> s%I d%I\n",
		       p->src, p->dst);
		runlock(&ifc->rwlock);
		freeblist(nbp);
		goto freebl;
	}

	memmove(np->dst, p->src, IPaddrlen);
	np->type = UnreachableV6;
	np->code = code;
	memmove(nbp->rp + sizeof(struct IPICMP), bp->rp,
			sz - sizeof(struct IPICMP));
	set_cksum(nbp);
	np->ttl = HOP_LIMIT;
	np->vcf[0] = 0x06 << 4;
	ipriv->out[UnreachableV6]++;

	if (free)
		ipiput6(f, ifc, nbp);
	else
		ipoput6(f, nbp, 0, MAXTTL, DFLTTOS, NULL);
	runlock(&ifc->rwlock);
freebl:
	if (free)
		freeblist(bp);
}

void icmpttlexceeded6(struct Fs *f, struct Ipifc *ifc, struct block *bp)
{
	struct block *nbp;
	struct IPICMP *np;
	struct ip6hdr *p;
	int osz = BLEN(bp);
	int sz = MIN(sizeof(struct IPICMP) + osz, v6MINTU);
	struct Proto *icmp = f->t2p[ICMPv6];
	Icmppriv6 *ipriv = icmp->priv;

	p = (struct ip6hdr *)bp->rp;

	if (isv6mcast(p->src))
		return;

	nbp = newIPICMP(sz);
	np = (struct IPICMP *)nbp->rp;

	if (ipv6anylocal(ifc, np->src)) {
		netlog(f, Logicmp, "send icmpttlexceeded6 -> s%I d%I\n",
		       p->src, p->dst);
	} else {
		netlog(f, Logicmp, "icmpttlexceeded6 fail -> s%I d%I\n",
		       p->src, p->dst);
		return;
	}

	memmove(np->dst, p->src, IPaddrlen);
	np->type = TimeExceedV6;
	np->code = 0;
	memmove(nbp->rp + sizeof(struct IPICMP), bp->rp,
	        sz - sizeof(struct IPICMP));
	set_cksum(nbp);
	np->ttl = HOP_LIMIT;
	np->vcf[0] = 0x06 << 4;
	ipriv->out[TimeExceedV6]++;
	ipoput6(f, nbp, 0, MAXTTL, DFLTTOS, NULL);
}

void icmppkttoobig6(struct Fs *f, struct Ipifc *ifc, struct block *bp)
{
	struct block *nbp;
	struct IPICMP *np;
	struct ip6hdr *p;
	int osz = BLEN(bp);
	int sz = MIN(sizeof(struct IPICMP) + osz, v6MINTU);
	struct Proto *icmp = f->t2p[ICMPv6];
	Icmppriv6 *ipriv = icmp->priv;

	p = (struct ip6hdr *)bp->rp;

	if (isv6mcast(p->src))
		return;

	nbp = newIPICMP(sz);
	np = (struct IPICMP *)nbp->rp;

	if (!ipv6anylocal(ifc, np->src)) {
		netlog(f, Logicmp, "icmppkttoobig6 fail -> s%I d%I\n",
		       p->src, p->dst);
		return;
	}
	netlog(f, Logicmp, "send icmppkttoobig6 -> s%I d%I\n",
	       p->src, p->dst);

	memmove(np->dst, p->src, IPaddrlen);
	np->type = PacketTooBigV6;
	np->code = 0;
	hnputl(np->icmpid, ifc->maxtu - ifc->m->hsize);
	memmove(nbp->rp + sizeof(struct IPICMP), bp->rp,
			sz - sizeof(struct IPICMP));
	set_cksum(nbp);
	np->ttl = HOP_LIMIT;
	np->vcf[0] = 0x06 << 4;
	ipriv->out[PacketTooBigV6]++;
	ipoput6(f, nbp, 0, MAXTTL, DFLTTOS, NULL);
}

/*
 * RFC 2461, pages 39-40, pages 57-58.
 */
static int valid(struct Proto *icmp, struct Ipifc *ifc,
                 struct block *bp, Icmppriv6 * ipriv)
{
	int sz, osz, unsp, n, ttl, iplen;
	int pktsz = BLEN(bp);
	uint8_t *packet = bp->rp;
	struct IPICMP *p = (struct IPICMP *)packet;
	struct Ndpkt *np;

	n = blocklen(bp);
	if (n < sizeof(struct IPICMP)) {
		ipriv->stats[HlenErrs6]++;
		netlog(icmp->f, Logicmp, "icmp hlen %d\n", n);
		goto err;
	}

	iplen = nhgets(p->ploadlen);
	if (iplen > n - IPV6HDR_LEN || (iplen % 1)) {
		ipriv->stats[LenErrs6]++;
		netlog(icmp->f, Logicmp, "icmp length %d\n", iplen);
		goto err;
	}
	// Rather than construct explicit pseudoheader, overwrite IPv6 header
	if (p->proto != ICMPv6) {
		// This code assumes no extension headers!!!
		netlog(icmp->f, Logicmp, "icmp error: extension header\n");
		goto err;
	}
	memset(packet, 0, 4);
	ttl = p->ttl;
	p->ttl = p->proto;
	p->proto = 0;
	if (ptclcsum(bp, 0, iplen + IPV6HDR_LEN)) {
		ipriv->stats[CsumErrs6]++;
		netlog(icmp->f, Logicmp, "icmp checksum error\n");
		goto err;
	}
	p->proto = p->ttl;
	p->ttl = ttl;

	/* additional tests for some pkt types */
	if ((p->type == NbrSolicit) ||
		(p->type == NbrAdvert) ||
		(p->type == RouterAdvert) ||
		(p->type == RouterSolicit) || (p->type == RedirectV6)) {

		if (p->ttl != HOP_LIMIT) {
			ipriv->stats[HoplimErrs6]++;
			goto err;
		}
		if (p->code != 0) {
			ipriv->stats[IcmpCodeErrs6]++;
			goto err;
		}

		switch (p->type) {
		case NbrSolicit:
		case NbrAdvert:
			np = (struct Ndpkt *)p;
			if (isv6mcast(np->target)) {
				ipriv->stats[TargetErrs6]++;
				goto err;
			}
			if (optexsts(np) && (np->olen == 0)) {
				ipriv->stats[OptlenErrs6]++;
				goto err;
			}

			if (p->type == NbrSolicit) {
				if (ipcmp(np->src, v6Unspecified) == 0) {
					if (!issmcast(np->dst) || optexsts(np))
					{
						ipriv->stats[AddrmxpErrs6]++;
						goto err;
					}
				}
			}

			if (p->type == NbrAdvert) {
				if ((isv6mcast(np->dst)) &&
				    (nhgets(np->icmpid) & Sflag)) {
					ipriv->stats[AddrmxpErrs6]++;
					goto err;
				}
			}
			break;

		case RouterAdvert:
			if (pktsz - sizeof(struct ip6hdr) < 16) {
				ipriv->stats[HlenErrs6]++;
				goto err;
			}
			if (!islinklocal(p->src)) {
				ipriv->stats[RouterAddrErrs6]++;
				goto err;
			}
			sz = sizeof(struct IPICMP) + 8;
			while ((sz + 1) < pktsz) {
				osz = *(packet + sz + 1);
				if (osz <= 0) {
					ipriv->stats[OptlenErrs6]++;
					goto err;
				}
				sz += 8 * osz;
			}
			break;

		case RouterSolicit:
			if (pktsz - sizeof(struct ip6hdr) < 8) {
				ipriv->stats[HlenErrs6]++;
				goto err;
			}
			unsp = (ipcmp(p->src, v6Unspecified) == 0);
			sz = sizeof(struct IPICMP) + 8;
			while ((sz + 1) < pktsz) {
				osz = *(packet + sz + 1);
				if ((osz <= 0) ||
				    (unsp && (*(packet + sz) == slladd))) {
					ipriv->stats[OptlenErrs6]++;
					goto err;
				}
				sz += 8 * osz;
			}
			break;

		case RedirectV6:
			//to be filled in
			break;

		default:
			goto err;
		}
	}

	return 1;

err:
	ipriv->stats[InErrors6]++;
	return 0;
}

static int targettype(struct Fs *f, struct Ipifc *ifc, uint8_t * target)
{
	struct Iplifc *lifc;
	int t;

	rlock(&ifc->rwlock);
	if (ipproxyifc(f, ifc, target)) {
		runlock(&ifc->rwlock);
		return t_uniproxy;
	}

	for (lifc = ifc->lifc; lifc; lifc = lifc->next) {
		if (ipcmp(lifc->local, target) == 0) {
			t = (lifc->tentative) ? t_unitent : t_unirany;
			runlock(&ifc->rwlock);
			return t;
		}
	}

	runlock(&ifc->rwlock);
	return 0;
}

static void icmpiput6(struct Proto *icmp, struct Ipifc *ipifc, struct block *bp)
{
	uint8_t *packet = bp->rp;
	struct IPICMP *p = (struct IPICMP *)packet;
	Icmppriv6 *ipriv = icmp->priv;
	struct block *r;
	struct Proto *pr;
	char *msg, m2[128];
	struct Ndpkt *np;
	uint8_t pktflags;
	uint8_t lsrc[IPaddrlen];
	int refresh = 1;
	struct Iplifc *lifc;

	if (!valid(icmp, ipifc, bp, ipriv))
		goto raise;

	if (p->type <= Maxtype6)
		ipriv->in[p->type]++;
	else
		goto raise;

	switch (p->type) {
	case EchoRequestV6:
		r = mkechoreply6(bp);
		ipriv->out[EchoReply]++;
		ipoput6(icmp->f, r, 0, MAXTTL, DFLTTOS, NULL);
		break;

	case UnreachableV6:
		if (p->code > 4)
			msg = unreachcode[icmp6_unkn_code];
		else
			msg = unreachcode[p->code];

		bp->rp += sizeof(struct IPICMP);
		if (blocklen(bp) < 8) {
			ipriv->stats[LenErrs6]++;
			goto raise;
		}
		p = (struct IPICMP *)bp->rp;
		pr = Fsrcvpcolx(icmp->f, p->proto);
		if (pr != NULL && pr->advise != NULL) {
			(*pr->advise) (pr, bp, msg);
			return;
		}

		bp->rp -= sizeof(struct IPICMP);
		goticmpkt6(icmp, bp, 0);
		break;

	case TimeExceedV6:
		if (p->code == 0) {
			snprintf(m2, sizeof(m2), "ttl exceeded at %I", p->src);

			bp->rp += sizeof(struct IPICMP);
			if (blocklen(bp) < 8) {
				ipriv->stats[LenErrs6]++;
				goto raise;
			}
			p = (struct IPICMP *)bp->rp;
			pr = Fsrcvpcolx(icmp->f, p->proto);
			if (pr != NULL && pr->advise != NULL) {
				(*pr->advise) (pr, bp, m2);
				return;
			}
			bp->rp -= sizeof(struct IPICMP);
		}

		goticmpkt6(icmp, bp, 0);
		break;

	case RouterAdvert:
	case RouterSolicit:
		/* using lsrc as a temp, munge hdr for goticmp6
		   memmove(lsrc, p->src, IPaddrlen);
		   memmove(p->src, p->dst, IPaddrlen);
		   memmove(p->dst, lsrc, IPaddrlen); */

		goticmpkt6(icmp, bp, p->type);
		break;

	case NbrSolicit:
		np = (struct Ndpkt *)p;
		pktflags = 0;
		switch (targettype(icmp->f, ipifc, np->target)) {
			case t_unirany:
				pktflags |= Oflag;
				/* fall through */

			case t_uniproxy:
				if (ipcmp(np->src, v6Unspecified) != 0) {
					arpenter(icmp->f, V6, np->src,
						 np->lnaddr, 8 * np->olen - 2,
						 0);
					pktflags |= Sflag;
				}
				if (ipv6local(ipifc, lsrc)) {
					icmpna(icmp->f, lsrc,
					       (ipcmp(np->src, v6Unspecified)
						== 0) ? v6allnodesL : np->src,
					       np->target, ipifc->mac,
					       pktflags);
				} else
					freeblist(bp);
				break;

			case t_unitent:
				/* not clear what needs to be done. send up an
				 * icmp mesg saying don't use this address? */

			default:
				freeblist(bp);
		}

		break;

	case NbrAdvert:
		np = (struct Ndpkt *)p;

		/* if the target address matches one of the local interface
		 * address and the local interface address has tentative bit
		 * set, then insert into ARP table. this is so the duplication
		 * address detection part of ipconfig can discover duplication
		 * through the arp table
		 */
		lifc = iplocalonifc(ipifc, np->target);
		if (lifc && lifc->tentative)
			refresh = 0;
		arpenter(icmp->f, V6, np->target, np->lnaddr, 8 * np->olen - 2,
				 refresh);
		freeblist(bp);
		break;

	case PacketTooBigV6:

	default:
		goticmpkt6(icmp, bp, 0);
		break;
	}
	return;

raise:
	freeblist(bp);

}

int icmpstats6(struct Proto *icmp6, char *buf, int len)
{
	Icmppriv6 *priv;
	char *p, *e;
	int i;

	priv = icmp6->priv;
	p = buf;
	e = p + len;
	for (i = 0; i < Nstats6; i++)
		p = seprintf(p, e, "%s: %u\n", statnames6[i], priv->stats[i]);
	for (i = 0; i <= Maxtype6; i++) {
		if (icmpnames6[i])
			p = seprintf(p, e, "%s: %u %u\n", icmpnames6[i],
				     priv->in[i], priv->out[i]);
		else
			p = seprintf(p, e, "%d: %u %u\n", i, priv->in[i],
				     priv->out[i]);
	}
	return p - buf;
}

// need to import from icmp.c
extern int icmpstate(struct conv *c, char *state, int n);
extern void icmpannounce(struct conv *c, char **argv, int argc);
extern void icmpconnect(struct conv *c, char **argv, int argc);
extern void icmpclose(struct conv *c);

void icmp6init(struct Fs *fs)
{
	struct Proto *icmp6 = kzmalloc(sizeof(struct Proto), 0);

	icmp6->priv = kzmalloc(sizeof(Icmppriv6), 0);
	icmp6->name = "icmpv6";
	icmp6->connect = icmpconnect;
	icmp6->announce = icmpannounce;
	icmp6->state = icmpstate;
	icmp6->create = icmpcreate6;
	icmp6->close = icmpclose;
	icmp6->rcv = icmpiput6;
	icmp6->stats = icmpstats6;
	icmp6->ctl = icmpctl6;
	icmp6->advise = icmpadvise6;
	icmp6->gc = NULL;
	icmp6->ipproto = ICMPv6;
	icmp6->nc = 16;
	icmp6->ptclsize = sizeof(Icmpcb6);

	Fsproto(fs, icmp6);
}
