/*
 * Internet Control Message Protocol for IPv6
 */
#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>

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

	Nstats6,
};

enum {
	ICMP_USEAD6 = 40,
};

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

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,
};

/* on-the-wire packet formats */
typedef struct IPICMP IPICMP;
typedef struct Ndpkt Ndpkt;
typedef struct NdiscC NdiscC;

/* we do this to avoid possible struct padding  */
#define ICMPHDR \
	IPV6HDR; \
	uint8_t	type; \
	uint8_t	code; \
	uint8_t	cksum[2]; \
	uint8_t	icmpid[2]; \
	uint8_t	seq[2]

struct IPICMP {
	ICMPHDR;
	uint8_t payload[];
};

#define IPICMPSZ offsetof(IPICMP, payload[0])

struct NdiscC {
	ICMPHDR;
	uint8_t target[IPaddrlen];
	uint8_t payload[];
};

#define NDISCSZ offsetof(NdiscC, payload[0])

struct Ndpkt {
	ICMPHDR;
	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 */
	uint8_t payload[];
};

#define NDPKTSZ offsetof(Ndpkt, payload[0])

typedef struct Icmppriv6 {
	uint32_t stats[Nstats6];

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

typedef struct Icmpcb6 {
	qlock_t qlock;
	uint8_t headers;
} Icmpcb6;

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",
};

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",
};

static char *unreachcode[] = {
	[Icmp6_no_route] "no route to destination",
	[Icmp6_ad_prohib] "comm with destination administratively prohibited",
	[Icmp6_out_src_scope] "beyond scope of source address",
	[Icmp6_adr_unreach] "address unreachable",
	[Icmp6_port_unreach] "port unreachable",
	[Icmp6_gress_src_fail] "source address failed ingress/egress policy",
	[Icmp6_rej_route] "reject route to destination",
	[Icmp6_unknown] "icmp unreachable: unknown code",
};

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)
{
	IPICMP *p = (IPICMP *) (bp->rp);

	hnputl(p->vcf, 0);	/* borrow IP header as pseudoheader */
	hnputs(p->ploadlen, blocklen(bp) - IP6HDR);
	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 = allocb(packetlen);
	nbp->wp += packetlen;
	memset(nbp->rp, 0, packetlen);
	return nbp;
}

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

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

	for (c = icmp->conv; *c; c++) {
		s = *c;
		if (s->lport == recid && 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)
{
	uint8_t laddr[IPaddrlen], raddr[IPaddrlen];
	struct conv *c = x;
	IPICMP *p;
	Icmppriv6 *ipriv = c->p->priv;
	Icmpcb6 *icb = (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, IP6HDR);
	}

	if (blocklen(bp) < IPICMPSZ) {
		freeblist(bp);
		return;
	}
	p = (IPICMP *) (bp->rp);
	if (icb->headers == 6) {
		ipmove(p->dst, raddr);
		ipmove(p->src, laddr);
	} else {
		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);
}

char *icmpctl6(struct conv *c, char **argv, int argc)
{
	Icmpcb6 *icb;

	icb = (Icmpcb6 *) c->ptcl;
	if (argc == 1 && strcmp(argv[0], "headers") == 0) {
		icb->headers = 6;
		return NULL;
	}
	return "unknown control request:icmp6";
}

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

	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 ipifc *ifc)
{
	uint8_t addr[IPaddrlen];
	IPICMP *p = (IPICMP *) (bp->rp);

	ipmove(addr, p->src);
	if (!isv6mcast(p->dst))
		ipmove(p->src, p->dst);
	else if (!ipv6anylocal(ifc, p->src))
		return NULL;
	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.
 */
extern void
icmpns(struct fs *f, uint8_t * src, int suni, uint8_t * targ, int tuni,
	   uint8_t * mac)
{
	struct block *nbp;
	Ndpkt *np;
	struct proto *icmp = f->t2p[ICMPv6];
	Icmppriv6 *ipriv = icmp->priv;

	nbp = newIPICMP(NDPKTSZ);
	np = (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_LLADDR;
		np->olen = 1;	/* 1+1+6 = 8 = 1 8-octet */
		memmove(np->lnaddr, mac, sizeof(np->lnaddr));
	} else
		nbp->wp -= NDPKTSZ - NDISCSZ;

	set_cksum(nbp);
	np = (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.
 */
extern void
icmpna(struct fs *f, uint8_t * src, uint8_t * dst, uint8_t * targ,
	   uint8_t * mac, uint8_t flags)
{
	struct block *nbp;
	Ndpkt *np;
	struct proto *icmp = f->t2p[ICMPv6];
	Icmppriv6 *ipriv = icmp->priv;

	nbp = newIPICMP(NDPKTSZ);
	np = (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_LLADDR;
	np->olen = 1;
	memmove(np->lnaddr, mac, sizeof(np->lnaddr));

	set_cksum(nbp);
	np = (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);
}

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

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

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

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

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

	memmove(np->dst, p->src, IPaddrlen);
	np->type = UnreachableV6;
	np->code = code;
	memmove(nbp->rp + IPICMPSZ, bp->rp, sz - IPICMPSZ);
	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);
		return;
	}

clean:
	runlock(&ifc->rwlock);
	freeblist(bp);
}

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

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

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

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

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

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

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

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

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

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

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

	memmove(np->dst, p->src, IPaddrlen);
	np->type = PacketTooBigV6;
	np->code = 0;
	hnputl(np->icmpid, ifc->maxtu - ifc->medium->hsize);
	memmove(nbp->rp + IPICMPSZ, bp->rp, sz - IPICMPSZ);
	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;
	IPICMP *p = (IPICMP *) packet;
	Ndpkt *np;

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

	iplen = nhgets(p->ploadlen);
	if (iplen > n - IP6HDR) {
		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 + IP6HDR)) {
		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 = (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 && 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 - IP6HDR < 16) {
					ipriv->stats[HlenErrs6]++;
					goto err;
				}
				if (!islinklocal(p->src)) {
					ipriv->stats[RouterAddrErrs6]++;
					goto err;
				}
				sz = IPICMPSZ + 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 - IP6HDR < 8) {
					ipriv->stats[HlenErrs6]++;
					goto err;
				}
				unsp = (ipcmp(p->src, v6Unspecified) == 0);
				sz = IPICMPSZ + 8;
				while (sz + 1 < pktsz) {
					osz = packet[sz + 1];
					if (osz <= 0 || (unsp && packet[sz] == SRC_LLADDR)) {
						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 Tuniproxy;
	}

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

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

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

	if (!valid(icmp, ipifc, bp, ipriv) || p->type > Maxtype6)
		goto raise;

	ipriv->in[p->type]++;

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

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

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

			bp->rp -= IPICMPSZ;
			goticmpkt6(icmp, bp, 0);
			break;

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

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

			goticmpkt6(icmp, bp, 0);
			break;

		case RouterAdvert:
		case RouterSolicit:
			/* using lsrc as a temp, munge hdr for goticmp6 */
			if (0) {
				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 = (Ndpkt *) p;
			pktflags = 0;
			switch (targettype(icmp->f, ipifc, np->target)) {
				case Tunirany:
					pktflags |= Oflag;
					/* fall through */

				case Tuniproxy:
					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 Tunitent:
					/* 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 = (Ndpkt *) p;

			/*
			 * if the target address matches one of the local interface
			 * addresses and the local interface address has tentative bit
			 * set, insert into ARP table. this is so the duplicate 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: %lu\n", statnames6[i], priv->stats[i]);
	for (i = 0; i <= Maxtype6; i++)
		if (icmpnames6[i])
			p = seprintf(p, e, "%s: %lu %lu\n", icmpnames6[i],
						 priv->in[i], priv->out[i]);
/*		else
			p = seprintf(p, e, "%d: %lu %lu\n", i, priv->in[i],
				priv->out[i]);
 */
	return p - buf;
}

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

void icmp6newconv(struct proto *icmp6, struct conv *conv)
{
	/* Fsprotoclone alloc'd our priv struct and attached it to conv already.
	 * Now we need to init it */
	struct Icmpcb6 *icb = (struct Icmpcb6*)conv->ptcl;
	qlock_init(&icb->qlock);
}

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->newconv = icmp6newconv;
	icmp6->ipproto = ICMPv6;
	icmp6->nc = 16;
	icmp6->ptclsize = sizeof(Icmpcb6);

	Fsproto(fs, icmp6);
}
