/*
 * This file is part of the UCB release of Plan 9. It is subject to the license
 * terms in the LICENSE file found in the top-level directory of this
 * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
 * part of the UCB release of Plan 9, including this file, may be copied,
 * modified, propagated, or distributed except according to the terms contained
 * in the LICENSE file.
 */

//
// ipconfig for IPv6
//	RS means Router Solicitation
//	RA means Router Advertisement
//

#include <parlib/alarm.h>
#include <iplib/iplib.h>
#include <parlib/common.h>
#include <parlib/parlib.h>
#include <parlib/uthread.h>

#include <ctype.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <stdarg.h>

#include "icmp.h"
#include "ipconfig.h"

#define RALOG "v6routeradv"

#define NetS(x) (((uint8_t *)x)[0] << 8 | ((uint8_t *)x)[1])
#define NetL(x) \
	(((uint8_t *)x)[0] << 24 | ((uint8_t *)x)[1] << 16 | \
	 ((uint8_t *)x)[2] << 8 | ((uint8_t *)x)[3])

enum {
	ICMP6LEN = 4,
};

// ICMP v4 & v6 header
struct icmphdr {
	uint8_t type;
	uint8_t code;
	uint8_t cksum[2];    // Checksum
	uint8_t data[];
};

char *icmpmsg6[Maxtype6 + 1] = {
        [EchoReply] "EchoReply",
        [UnreachableV6] "UnreachableV6",
        [PacketTooBigV6] "PacketTooBigV6",
        [TimeExceedV6] "TimeExceedV6",
        [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 *icmp6opts[] = {
        [0] "unknown option",
        [V6nd_srclladdr] "srcll_addr",
        [V6nd_targlladdr] "targll_addr",
        [V6nd_pfxinfo] "prefix",
        [V6nd_redirhdr] "redirect",
        [V6nd_mtu] "mtu",
        [V6nd_home] "home",
        [V6nd_srcaddrs] "src_addrs",
        [V6nd_ip] "ip",
        [V6nd_rdns] "rdns",
        [V6nd_9fs] "9fs",
        [V6nd_9auth] "9auth",
};

uint8_t v6allroutersL[IPaddrlen] = {
    0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x02
};

uint8_t v6allnodesL[IPaddrlen] = {
    0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01
};

uint8_t v6Unspecified[IPaddrlen] = {
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};

uint8_t v6loopback[IPaddrlen] = {
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
};

uint8_t v6glunicast[IPaddrlen] = {
    0x08, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};

uint8_t v6linklocal[IPaddrlen] = {
    0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};

uint8_t v6solpfx[IPaddrlen] = {
    0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
    // last 3 bytes filled with low-order bytes of addr being solicited
    0xff, 0, 0, 0,
};

uint8_t v6defmask[IPaddrlen] = {
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0
};

enum {
	Vadd,
	Vremove,
	Vunbind,
	Vaddpref6,
	Vra6,
};

static void ralog(char *fmt, ...)
{
	char msg[512];
	va_list arg;

	va_start(arg, fmt);
	vsnprintf(msg, sizeof(msg), fmt, arg);
	va_end(arg);
	fprintf(stderr, RALOG ": %s\n", msg);
}

void ea2lla(uint8_t *lla, uint8_t *ea)
{
	assert(IPaddrlen == 16);
	memset(lla, 0, IPaddrlen);
	lla[0] = 0xFE;
	lla[1] = 0x80;
	lla[8] = ea[0] | 0x2;
	lla[9] = ea[1];
	lla[10] = ea[2];
	lla[11] = 0xFF;
	lla[12] = 0xFE;
	lla[13] = ea[3];
	lla[14] = ea[4];
	lla[15] = ea[5];
}

void ipv62smcast(uint8_t *smcast, uint8_t *a)
{
	assert(IPaddrlen == 16);
	memset(smcast, 0, IPaddrlen);
	smcast[0] = 0xFF;
	smcast[1] = 0x02;
	smcast[11] = 0x1;
	smcast[12] = 0xFF;
	smcast[13] = a[13];
	smcast[14] = a[14];
	smcast[15] = a[15];
}

void v6paraminit(struct conf *cf)
{
	cf->sendra = cf->recvra = 0;
	cf->mflag = 0;
	cf->oflag = 0;
	cf->maxraint = Maxv6initraintvl;
	cf->minraint = Maxv6initraintvl / 4;
	cf->linkmtu = 1500;
	cf->reachtime = V6reachabletime;
	cf->rxmitra = V6retranstimer;
	cf->ttl = MAXTTL;

	cf->routerlt = 0;

	cf->prefixlen = 64;
	cf->onlink = 0;
	cf->autoflag = 0;
	cf->validlt = cf->preflt = ~0L;
}

static char *optname(unsigned opt)
{
	static char buf[32];

	if (opt >= COUNT_OF(icmp6opts) || icmp6opts[opt] == NULL) {
		snprintf(buf, sizeof(buf), "unknown option %d", opt);
		return buf;
	}

	return icmp6opts[opt];
}

size_t opt_sprint(uint8_t *ps, uint8_t *pe, char *buf, size_t size)
{
	int otype, osz, pktsz;
	uint8_t *a;
	size_t n;

	a = ps;
	n = 0;
	for (pktsz = pe - ps; pktsz > 0; pktsz -= osz) {
		otype = a[0];
		osz = a[1] * 8;

		switch (otype) {
		default:
			n += snprintf(buf + n, size - n, " option=%s ",
				      optname(otype));
		case V6nd_srclladdr:
		case V6nd_targlladdr:
			if (pktsz < osz || osz != 8) {
				n += snprintf(buf + n, size - n,
				              " option=%s bad size=%d",
				              optname(otype), osz);
				return n;
			}
			n += snprintf(buf + n, size - n, " option=%s maddr=%E",
			              optname(otype), a + 2);
			break;
		case V6nd_pfxinfo:
			if (pktsz < osz || osz != 32) {
				n += snprintf(buf + n, size - n,
				              " option=%s: bad size=%d",
				              optname(otype), osz);
				return n;
			}
			n += snprintf(buf, size - n,
			              " option=%s pref=%R preflen=%3.3d lflag=%1.1d aflag=%1.1d unused1=%1.1d validlt=%ud preflt=%ud unused2=%1.1d",
			              optname(otype),
			              a + 16,
			              (int)(*(a + 2)),
			              (*(a + 3) & (1 << 7)) != 0,
			              (*(a + 3) & (1 << 6)) != 0,
			              (*(a + 3) & 63) != 0,
			              NetL(a + 4),
			              NetL(a + 8),
			              NetL(a + 12) != 0);
			break;
		}
		a += osz;
	}

	return n;
}

static void pkt2str(uint8_t *ps, uint8_t *pe, char *buf, size_t size)
{
	int pktlen;
	char *tn;
	uint8_t *a;
	struct icmphdr *h;
	size_t n;

	h = (struct icmphdr *)ps;
	a = ps + 4;

	pktlen = pe - ps;
	if (pktlen < ICMP6LEN) {
		snprintf(buf, size, "short pkt");
		return;
	}

	tn = icmpmsg6[h->type];
	if (tn == NULL)
		n = snprintf(buf, size, "t=%ud c=%d ck=%4.4ux",
		             h->type, h->code, (uint16_t)NetS(h->cksum));
	else
		n = snprintf(buf, size, "t=%s c=%d ck=%4.4ux",
		             tn, h->code, (uint16_t)NetS(h->cksum));

	switch (h->type) {
	case RouterSolicit:
		ps += 8;
		n += snprintf(buf + n, size - n, " unused=%1.1d ",
			      NetL(a) != 0);
		opt_sprint(ps, pe, buf + n, size - n);
		break;
	case RouterAdvert:
		ps += 16;
		n += snprintf(buf + n, size - n,
		              " hoplim=%3.3d mflag=%1.1d oflag=%1.1d unused=%1.1d routerlt=%d reachtime=%d rxmtimer=%d",
		              a[0],
		              (*(a + 1) & (1 << 7)) != 0,
		              (*(a + 1) & (1 << 6)) != 0,
		              (*(a + 1) & 63) != 0,
		              NetS(a + 2),
		              NetL(a + 4),
		              NetL(a + 8));
		opt_sprint(ps, pe, buf + n, size - n);
		break;
	default:
		snprintf(buf + n, size - n, " unexpected icmp6 pkt type");
		break;
	}
}

int dialicmp(uint8_t *dst, int dport, int *ctlfd)
{
	int fd, cfd, n, m;
	char cmsg[100], name[128], connind[40];
	char hdrs[] = "headers";

	snprintf(name, sizeof(name), "%s/icmpv6/clone", conf.mpoint);
	cfd = open(name, O_RDWR);
	if (cfd < 0) {
		fprintf(stderr, "dialicmp: can't open %s: %r", name);
		evexit(-1);
	}

	n = snprintf(cmsg, sizeof(cmsg), "connect %R!%d!r %d", dst, dport,
		     dport);
	m = write(cfd, cmsg, n);
	if (m < n) {
		fprintf(stderr, "dialicmp: can't write %s to %s: %r", cmsg,
			name);
		evexit(-1);
	}

	lseek(cfd, 0, 0);
	n = read(cfd, connind, sizeof(connind));
	if (n < 0)
		connind[0] = 0;
	else if (n < sizeof(connind))
		connind[n] = 0;
	else
		connind[sizeof(connind) - 1] = 0;

	snprintf(name, sizeof(name), "%s/icmpv6/%s/data", conf.mpoint, connind);
	fd = open(name, O_RDWR);
	if (fd < 0) {
		fprintf(stderr, "dialicmp: can't open %s: %r", name);
		evexit(-1);
	}

	n = sizeof(hdrs) - 1;
	if (write(cfd, hdrs, n) < n) {
		fprintf(stderr, "dialicmp: can't write `%s' to %s: %r", hdrs,
			name);
		evexit(-1);
	}
	*ctlfd = cfd;
	return fd;
}

// Add an IPv6 address to an interface.
int ip6cfg(int autoconf)
{
	int dupfound = 0, n;
	char *p, *s;
	char buf[256], line[1024];
	uint8_t ethaddr[6];
	FILE *bp;

	if (autoconf) {
		// create link-local addr
		if (myetheraddr(ethaddr, conf.dev) < 0) {
			fprintf(stderr, "myetheraddr w/ %s failed: %r",
				conf.dev);
			evexit(-1);
		}
		ea2lla(conf.laddr, ethaddr);
	}

	if (dupl_disc)
		n = snprintf(buf, sizeof(buf), "try");
	else
		n = snprintf(buf, sizeof(buf), "add");

	n += snprintf(buf + n, sizeof(buf) - n, " %R", conf.laddr);
	if (!validip(conf.mask))
		ipmove(conf.mask, v6defmask);
	n += snprintf(buf + n, sizeof(buf) - n, " %M", conf.mask);
	if (validip(conf.raddr)) {
		n += snprintf(buf + n, sizeof(buf) - n, " %R", conf.raddr);
		if (conf.mtu != 0)
			n += snprintf(buf + n, sizeof(buf) - n, " %d",
				      conf.mtu);
	}

	if (write(conf.cfd, buf, n) < 0) {
		warning("write(%s): %r", buf);
		return -1;
	}

	if (!dupl_disc)
		return 0;

	usleep(3000 * 1000);

	/* read arp table, look for addr duplication */
	snprintf(buf, sizeof(buf), "%s/arp", conf.mpoint);
	bp = fopen(buf, "r");
	if (bp == NULL) {
		warning("couldn't open %s: %r", buf);
		return -1;
	}

	snprintf(buf, sizeof(buf), "%R", conf.laddr);
	for (p = buf; *p != '\0'; p++)
		if (isascii(*p) && isalpha(*p) && isupper(*p))
			*p = tolower(*p);
	while ((s = fgets(line, sizeof(line), bp)) != NULL) {
		s[strlen(line) - 1] = 0;
		for (p = buf; *p != '\0'; p++)
			if (isascii(*p) && isalpha(*p) && isupper(*p))
				*p = tolower(*p);
		if (strstr(s, buf) != 0) {
			warning("found dup entry in arp cache");
			dupfound = 1;
			break;
		}
	}
	fclose(bp);

	if (dupfound)
		doremove();
	else {
		n = snprintf(buf, sizeof(buf), "add %R %M", conf.laddr,
			     conf.mask);
		if (validip(conf.raddr)) {
			n += snprintf(buf + n, sizeof(buf) - n, " %R",
				      conf.raddr);
			if (conf.mtu != 0)
				n += snprintf(buf + n, sizeof(buf) - n, " %d",
					      conf.mtu);
		}
		write(conf.cfd, buf, n);
	}
	return 0;
}

static int recvra6on(char *net, int conn)
{
	struct ipifc *ifc;

	ifc = readipifc(net, NULL, conn);
	if (ifc == NULL)
		return 0;
	else if (ifc->sendra6 > 0)
		return IsRouter;
	else if (ifc->recvra6 > 0)
		return IsHostRecv;
	else
		return IsHostNoRecv;
}

/* send icmpv6 router solicitation to multicast address for all routers */
static void sendrs(int fd)
{
	struct routersol *rs;
	uint8_t buff[sizeof(*rs)];

	memset(buff, 0, sizeof(buff));
	rs = (struct routersol *)buff;
	memmove(rs->dst, v6allroutersL, IPaddrlen);
	memmove(rs->src, v6Unspecified, IPaddrlen);
	rs->type = ICMP6_RS;

	if (write(fd, rs, sizeof(buff)) < sizeof(buff))
		ralog("sendrs: write failed, pkt size %d", sizeof(buff));
	else
		ralog("sendrs: sent solicitation to %R from %R on %s", rs->dst,
		      rs->src, conf.dev);
}

/*
 * a router receiving a router adv from another
 * router calls this; it is basically supposed to
 * log the information in the ra and raise a flag
 * if any parameter value is different from its configured values.
 *
 * doing nothing for now since I don't know where to log this yet.
 */
static void recvrarouter(uint8_t buf[], int pktlen)
{
	ralog("i am a router and got a router advert");
}

// host receiving a router advertisement calls this
static void ewrite(int fd, char *str)
{
	int n;

	n = strlen(str);
	if (write(fd, str, n) != n)
		ralog("write(%s) failed: %r", str);
}

static void issuebasera6(struct conf *cf)
{
	char cfg[256];

	snprintf(cfg, sizeof(cfg),
	         "ra6 mflag %d oflag %d reachtime %d rxmitra %d ttl %d routerlt %d",
	         cf->mflag, cf->oflag, cf->reachtime, cf->rxmitra,
	         cf->ttl, cf->routerlt);
	ewrite(cf->cfd, cfg);
}

static void issuerara6(struct conf *cf)
{
	char cfg[256];

	snprintf(cfg, sizeof(cfg),
	         "ra6 sendra %d recvra %d maxraint %d minraint %d linkmtu %d",
		 cf->sendra, cf->recvra, cf->maxraint, cf->minraint,
		 cf->linkmtu);
	ewrite(cf->cfd, cfg);
}

static void
issueadd6(struct conf *cf)
{
	char cfg[256];

	snprintf(cfg, sizeof(cfg),
	         "add6 %R %d %d %d %lud %lud", cf->v6pref, cf->prefixlen,
	         cf->onlink, cf->autoflag, cf->validlt, cf->preflt);
	ewrite(cf->cfd, cfg);
}

static void
recvrahost(uint8_t buf[], int pktlen)
{
	int arpfd, m, n;
	char abuf[100], *msg;
	uint8_t optype;
	struct lladdropt *llao;
	struct mtuopt *mtuo;
	struct prefixopt *prfo;
	struct routeradv *ra;
	static int first = 1;

	ra = (struct routeradv *)buf;
	//	memmove(conf.v6gaddr, ra->src, IPaddrlen);
	conf.ttl = ra->cttl;
	conf.mflag = (MFMASK & ra->mor);
	conf.oflag = (OCMASK & ra->mor);
	conf.routerlt = nhgets(ra->routerlt);
	conf.reachtime = nhgetl(ra->rchbltime);
	conf.rxmitra = nhgetl(ra->rxmtimer);

	//	issueadd6(&conf);		/* for conf.v6gaddr? */
	msg = "ra6 recvra 1";
	if (write(conf.cfd, msg, strlen(msg)) < 0)
		ralog("write(ra6 recvra 1) failed: %r");
	issuebasera6(&conf);

	m = sizeof(*ra);
	while (pktlen - m > 0) {
		optype = buf[m];
		switch (optype) {
		case V6nd_srclladdr:
			llao = (struct lladdropt *)&buf[m];
			m += 8 * buf[m + 1];
			if (llao->len != 1) {
				ralog(
				    "recvrahost: illegal len (%d) for source link layer address option",
				    llao->len);
				return;
			}
			if (!ISIPV6LINKLOCAL(ra->src)) {
				ralog("recvrahost: non-link-local src addr for router adv %R",
				      ra->src);
				return;
			}

			snprintf(abuf, sizeof(abuf), "%s/arp", conf.mpoint);
			arpfd = open(abuf, O_WRONLY);
			if (arpfd < 0) {
				ralog("recvrahost: couldn't open %s to write: %r",
				      abuf);
				return;
			}

			n = snprintf(abuf, sizeof(abuf), "add ether %R %E",
				     ra->src, llao->lladdr);
			if (write(arpfd, abuf, n) < n)
				ralog("recvrahost: couldn't write to %s/arp",
				      conf.mpoint); close(arpfd);
			break;
		case V6nd_targlladdr:
		case V6nd_redirhdr:
			m += 8 * buf[m + 1];
			ralog("ignoring unexpected option type `%s' in Routeradv",
			      optname(optype));
			break;
		case V6nd_mtu:
			mtuo = (struct mtuopt *)&buf[m];
			m += 8 * mtuo->len;
			conf.linkmtu = nhgetl(mtuo->mtu);
			break;
		case V6nd_pfxinfo:
			prfo = (struct prefixopt *)&buf[m];
			m += 8 * prfo->len;
			if (prfo->len != 4) {
				ralog("illegal len (%d) for prefix option",
				      prfo->len);
				return;
			}
			memmove(conf.v6pref, prfo->pref, IPaddrlen);
			conf.prefixlen = prfo->plen;
			conf.onlink = ((prfo->lar & OLMASK) != 0);
			conf.autoflag = ((prfo->lar & AFMASK) != 0);
			conf.validlt = nhgetl(prfo->validlt);
			conf.preflt = nhgetl(prfo->preflt);
			issueadd6(&conf);
			if (first) {
				first = 0;
				ralog("got initial RA from %R on %s; pfx %R",
				      ra->src, conf.dev, prfo->pref);
			}
			break;
		default:
			if (debug)
				ralog("ignoring optype %d in Routeradv from %R",
				      optype, ra->src);
		/* fall through */
		case V6nd_srcaddrs:
			/* netsbd sends this, so quietly ignore it for now */
			m += 8 * buf[m + 1];
			break;
		}
	}
}

/*
 * daemon to receive router advertisements from routers
 */
static void *recvra6thr(void *unused_arg);

void recvra6(void)
{
	pthread_t tid;

	pthread_create(&tid, NULL, recvra6thr, NULL);
}

static void *recvra6thr(void *unused_arg)
{
	int fd, cfd, n, sendrscnt, sleepfor;
	uint8_t buf[4096];

	(void)unused_arg;

	/* TODO: why not v6allroutersL? */
	fd = dialicmp(v6allnodesL, ICMP6_RA, &cfd);
	if (fd < 0) {
		fprintf(stderr, "can't open icmp_ra connection: %r");
		evexit(-1);
	}

	sendrscnt = Maxv6rss;

	ralog("recvra6 on %s", conf.dev);
	sleepfor = jitter();
	for (;;) {
		//
		// We only get 3 (Maxv6rss) tries, so make sure we
		// wait long enough to be certain that at least one RA
		// will be transmitted.
		//
		struct alarm_waiter waiter;

		init_awaiter(&waiter, alarm_abort_sysc);
		waiter.data = current_uthread;
		set_awaiter_rel(&waiter, 1000 * MAX(sleepfor, 7000));
		set_alarm(&waiter);
		n = read(fd, buf, sizeof(buf));
		unset_alarm(&waiter);

		if (n <= 0) {
			if (sendrscnt > 0) {
				sendrscnt--;
				if (recvra6on(conf.mpoint, myifc) == IsHostRecv)
					sendrs(fd);
				sleepfor = V6rsintvl + (lrand48() % 100);
			}
			if (sendrscnt == 0) {
				sendrscnt--;
				sleepfor = 0;
				ralog("recvra6: no router advs after %d sols on %s",
				      Maxv6rss, conf.dev);
			}
			continue;
		}

		sleepfor = 0;
		sendrscnt = -1; /* got at least initial ra; no whining */
		switch (recvra6on(conf.mpoint, myifc)) {
		case IsRouter:
			recvrarouter(buf, n);
			break;
		case IsHostRecv:
			recvrahost(buf, n);
			break;
		case IsHostNoRecv:
			ralog("recvra6: recvra off, quitting on %s", conf.dev);
			close(fd);
			evexit(0);
		default:
			ralog("recvra6: unable to read router status on %s",
			      conf.dev);
			break;
		}
	}

	return NULL;
}

/*
 * return -1 -- error, reading/writing some file,
 *         0 -- no arp table updates
 *         1 -- successful arp table update
 */
int recvrs(uint8_t *buf, int pktlen, uint8_t *sol)
{
	int n, optsz, arpfd;
	char abuf[256];
	struct routersol *rs;
	struct lladdropt *llao;

	rs = (struct routersol *)buf;
	n = sizeof(*rs);
	optsz = pktlen - n;
	pkt2str(buf, buf + pktlen, abuf, sizeof(abuf));

	if (optsz != sizeof(*llao))
		return 0;
	if (buf[n] != V6nd_srclladdr || 8 * buf[n + 1] != sizeof(*llao)) {
		ralog("rs opt err %s", abuf);
		return -1;
	}

	ralog("rs recv %s", abuf);

	if (memcmp(rs->src, v6Unspecified, IPaddrlen) == 0)
		return 0;

	snprintf(abuf, sizeof(abuf), "%s/arp", conf.mpoint);
	arpfd = open(abuf, O_WRONLY);
	if (arpfd < 0) {
		ralog("recvrs: can't open %s/arp to write: %r", conf.mpoint);
		return -1;
	}

	llao = (struct lladdropt *)&buf[n];
	n = snprintf(abuf, sizeof(abuf), "add ether %R %E", rs->src,
		     llao->lladdr);
	if (write(arpfd, abuf, n) < n) {
		ralog("recvrs: can't write to %s/arp: %r", conf.mpoint);
		close(arpfd);
		return -1;
	}

	memmove(sol, rs->src, IPaddrlen);
	close(arpfd);
	return 1;
}

void sendra(int fd, uint8_t *dst, int rlt)
{
	int pktsz, preflen;
	char abuf[1024], tmp[64];
	uint8_t buf[1024], macaddr[6], src[IPaddrlen];
	struct ipifc *ifc = NULL;
	struct iplifc *lifc, *nlifc;
	struct lladdropt *llao;
	struct prefixopt *prfo;
	struct routeradv *ra;

	memset(buf, 0, sizeof(buf));
	ra = (struct routeradv *)buf;

	myetheraddr(macaddr, conf.dev);
	ea2lla(src, macaddr);
	memmove(ra->src, src, IPaddrlen);
	memmove(ra->dst, dst, IPaddrlen);
	ra->type = ICMP6_RA;
	ra->cttl = conf.ttl;

	if (conf.mflag > 0)
		ra->mor |= MFMASK;
	if (conf.oflag > 0)
		ra->mor |= OCMASK;
	if (rlt > 0)
		hnputs(ra->routerlt, conf.routerlt);
	else
		hnputs(ra->routerlt, 0);
	hnputl(ra->rchbltime, conf.reachtime);
	hnputl(ra->rxmtimer, conf.rxmitra);

	pktsz = sizeof(*ra);

	/* include all global unicast prefixes on interface in prefix options */
	ifc = readipifc(conf.mpoint, ifc, myifc);
	for (lifc = (ifc ? ifc->lifc : NULL); lifc; lifc = nlifc) {
		nlifc = lifc->next;
		prfo = (struct prefixopt *)(buf + pktsz);
		/* global unicast address? */
		if (!ISIPV6LINKLOCAL(lifc->ip) && !ISIPV6MCAST(lifc->ip) &&
		    memcmp(lifc->ip, IPnoaddr, IPaddrlen) != 0 &&
		    memcmp(lifc->ip, v6loopback, IPaddrlen) != 0 &&
		    !isv4(lifc->ip)) {
			memmove(prfo->pref, lifc->net, IPaddrlen);

			/* hack to find prefix length */
			snprintf(tmp, sizeof(tmp), "%M", lifc->mask);
			preflen = atoi(&tmp[1]);
			prfo->plen = preflen & 0xff;
			if (prfo->plen == 0)
				continue;

			prfo->type = V6nd_pfxinfo;
			prfo->len = 4;
			prfo->lar = AFMASK;
			hnputl(prfo->validlt, lifc->validlt);
			hnputl(prfo->preflt, lifc->preflt);
			pktsz += sizeof(*prfo);
		}
	}
	/*
	 * include link layer address (mac address for now) in
	 * link layer address option
	 */
	llao = (struct lladdropt *)(buf + pktsz);
	llao->type = V6nd_srclladdr;
	llao->len = 1;
	memmove(llao->lladdr, macaddr, sizeof(macaddr));
	pktsz += sizeof(*llao);
	pkt2str(buf + 40, buf + pktsz, abuf, sizeof(abuf));
	if (write(fd, buf, pktsz) < pktsz)
		ralog("sendra fail %s: %r", abuf);
	else if (debug)
		ralog("sendra succ %s", abuf);
}

/*
 * daemon to send router advertisements to hosts
 */
static void *sendra6thr(void *unused_arg);

void sendra6(void)
{
	pthread_t tid;

	pthread_create(&tid, NULL, sendra6thr, NULL);
}

void *sendra6thr(void *unused_arg)
{
	int fd, cfd, n, dstknown = 0, sendracnt, sleepfor, nquitmsgs;
	long lastra, now;
	uint8_t buf[4096], dst[IPaddrlen];
	struct ipifc *ifc = NULL;

	(void)unused_arg;

	fd = dialicmp(v6allnodesL, ICMP6_RS, &cfd);
	if (fd < 0) {
		fprintf(stderr, "can't open icmp_rs connection: %r");
		evexit(-1);
	}

	sendracnt = Maxv6initras;
	nquitmsgs = Maxv6finalras;

	ralog("sendra6 on %s", conf.dev);
	sleepfor = jitter();
	for (;;) {
		struct alarm_waiter waiter;

		init_awaiter(&waiter, alarm_abort_sysc);
		set_awaiter_rel(&waiter, 1000 * MAX(sleepfor, 0));
		lastra = time(0);
		set_alarm(&waiter);
		n = read(fd, buf, sizeof(buf));
		unset_alarm(&waiter);

		ifc = readipifc(conf.mpoint, ifc, myifc);
		if (ifc == NULL) {
			ralog("sendra6: can't read router params on %s",
			      conf.mpoint);
			continue;
		}

		if (ifc->sendra6 <= 0) {
			if (nquitmsgs > 0) {
				sendra(fd, v6allnodesL, 0);
				nquitmsgs--;
				sleepfor = Minv6interradelay + jitter();
				continue;
			} else {
				ralog("sendra6: sendra off, quitting on %s",
				      conf.dev);
				evexit(0);
			}
		}

		nquitmsgs = Maxv6finalras;

		if (n <= 0) { /* no RS */
			if (sendracnt > 0)
				sendracnt--;
		} else { /* respond to RS */
			dstknown = recvrs(buf, n, dst);
			now = time(0);

			if (now - lastra < Minv6interradelay) {
				/* too close, skip */
				sleepfor = lastra + Minv6interradelay + jitter()
					   - now;
				continue;
			}
			usleep(jitter() * 1000);
		}
		sleepfor = randint(ifc->rp.minraint, ifc->rp.maxraint);
		if (dstknown > 0)
			sendra(fd, dst, 1);
		else
			sendra(fd, v6allnodesL, 1);
	}

	return NULL;
}

void startra6(void)
{
	static const char routeon[] = "iprouting 1";

	if (conf.recvra > 0)
		recvra6();

	if (conf.sendra > 0) {
		if (write(conf.cfd, routeon, sizeof(routeon) - 1) < 0) {
			warning("write (iprouting 1) failed: %r");
			return;
		}
		sendra6();
		if (conf.recvra <= 0)
			recvra6();
	}
}

void doipv6(int what)
{
	nip = nipifcs(conf.mpoint);
	if (!noconfig) {
		lookforip(conf.mpoint);
		controldevice();
		binddevice();
	}

	switch (what) {
	default:
		fprintf(stderr, "unknown IPv6 verb\n");
		evexit(-1);
	case Vaddpref6:
		issueadd6(&conf);
		break;
	case Vra6:
		issuebasera6(&conf);
		issuerara6(&conf);
		startra6();
		break;
	}
}
