/* 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);
}
