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