/* 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 <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>
#include <net/ip.h>

typedef struct Etherhdr Etherhdr;
struct Etherhdr {
	uint8_t d[6];
	uint8_t s[6];
	uint8_t t[2];
};

static uint8_t ipbroadcast[IPaddrlen] = {
	0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff,
};

static uint8_t etherbroadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };

static void etherread4(void *a);
static void etherread6(void *a);
static void etherbind(struct Ipifc *ifc, int argc, char **argv);
static void etherunbind(struct Ipifc *ifc);
static void etherbwrite(struct Ipifc *ifc, struct block *bp, int version,
			uint8_t *ip);
static void etheraddmulti(struct Ipifc *ifc, uint8_t * a, uint8_t * ia);
static void etherremmulti(struct Ipifc *ifc, uint8_t * a, uint8_t * ia);
static struct block *multicastarp(struct Fs *f, struct arpent *a,
				  struct medium *m, uint8_t *mac);
static void sendarp(struct Ipifc *ifc, struct arpent *a);
static void sendgarp(struct Ipifc *ifc, uint8_t * unused_uint8_p_t);
static int multicastea(uint8_t * ea, uint8_t * ip);
static void recvarpproc(void *);
static void resolveaddr6(struct Ipifc *ifc, struct arpent *a);
static void etherpref2addr(uint8_t * pref, uint8_t * ea);

struct medium ethermedium = {
	.name = "ether",
	.hsize = 14,
	.mintu = 60,
	.maxtu = 1514,
	.maclen = 6,
	.bind = etherbind,
	.unbind = etherunbind,
	.bwrite = etherbwrite,
	.addmulti = etheraddmulti,
	.remmulti = etherremmulti,
	.ares = arpenter,
	.areg = sendgarp,
	.pref2addr = etherpref2addr,
};

struct medium trexmedium = {
	.name = "trex",
	.hsize = 14,
	.mintu = 60,
	.maxtu = 1514,
	.maclen = 6,
	.bind = etherbind,
	.unbind = etherunbind,
	.bwrite = etherbwrite,
	.addmulti = etheraddmulti,
	.remmulti = etherremmulti,
	.ares = arpenter,
	.areg = sendgarp,
	.pref2addr = etherpref2addr,
};

typedef struct Etherrock Etherrock;
struct Etherrock {
	struct Fs *f;			/* file system we belong to */
	struct proc *arpp;		/* arp process */
	struct proc *read4p;		/* reading process (v4) */
	struct proc *read6p;		/* reading process (v6) */
	struct chan *mchan4;		/* Data channel for v4 */
	struct chan *achan;		/* Arp channel */
	struct chan *cchan4;		/* Control channel for v4 */
	struct chan *mchan6;		/* Data channel for v6 */
	struct chan *cchan6;		/* Control channel for v6 */
};

/*
 *  ethernet arp request
 */
enum {
	ETARP = 0x0806,
	ETIP4 = 0x0800,
	ETIP6 = 0x86DD,
	ARPREQUEST = 1,
	ARPREPLY = 2,
};

typedef struct Etherarp Etherarp;
struct Etherarp {
	uint8_t d[6];
	uint8_t s[6];
	uint8_t type[2];
	uint8_t hrd[2];
	uint8_t pro[2];
	uint8_t hln;
	uint8_t pln;
	uint8_t op[2];
	uint8_t sha[6];
	uint8_t spa[4];
	uint8_t tha[6];
	uint8_t tpa[4];
};

static char *nbmsg = "nonblocking";

static unsigned int parsefeat(char *ptr)
{
	unsigned int feat = 0;

	if (strstr(ptr, "ipck"))
		feat |= NETF_IPCK;
	if (strstr(ptr, "udpck"))
		feat |= NETF_UDPCK;
	if (strstr(ptr, "tcpck"))
		feat |= NETF_TCPCK;
	if (strstr(ptr, "padmin"))
		feat |= NETF_PADMIN;
	if (strstr(ptr, "sg"))
		feat |= NETF_SG;
	if (strstr(ptr, "tso"))
		feat |= NETF_TSO;
	if (strstr(ptr, "lro"))
		feat |= NETF_LRO;
	if (strstr(ptr, "rxcsum"))
		feat |= NETF_RXCSUM;
	return feat;
}

/*
 *  called to bind an IP ifc to an ethernet device
 *  called with ifc wlock'd
 */
static void etherbind(struct Ipifc *ifc, int argc, char **argv)
{
	ERRSTACK(1);
	struct chan *mchan4, *cchan4, *achan, *mchan6, *cchan6;
	char *addr, *dir, *buf;
	int fd, cfd, n;
	char *ptr;
	Etherrock *er;

	if (argc < 2)
		error(EINVAL, ERROR_FIXME);

	addr = kmalloc(Maxpath, MEM_WAIT);	//char addr[2*KNAMELEN];
	dir = kmalloc(Maxpath, MEM_WAIT);	//char addr[2*KNAMELEN];
	mchan4 = cchan4 = achan = mchan6 = cchan6 = NULL;
	buf = NULL;
	if (waserror()) {
		if (mchan4 != NULL)
			cclose(mchan4);
		if (cchan4 != NULL)
			cclose(cchan4);
		if (achan != NULL)
			cclose(achan);
		if (mchan6 != NULL)
			cclose(mchan6);
		if (cchan6 != NULL)
			cclose(cchan6);
		if (buf != NULL)
			kfree(buf);
		kfree(addr);
		kfree(dir);
		nexterror();
	}

	/*
	 *  open ip converstation
	 *
	 *  the dial will fail if the type is already open on
	 *  this device.
	 */
	snprintf(addr, Maxpath, "%s!0x800", argv[2]);
	fd = kdial(addr, NULL, dir, &cfd);
	if (fd < 0)
		error(EFAIL, "dial 0x800 failed: %s", get_cur_errbuf());
	mchan4 = commonfdtochan(fd, O_RDWR, 0, 1);
	cchan4 = commonfdtochan(cfd, O_RDWR, 0, 1);
	sysclose(fd);
	sysclose(cfd);

	/*
	 *  make it non-blocking
	 */
	devtab[cchan4->type].write(cchan4, nbmsg, strlen(nbmsg), 0);

	/*
	 *  get mac address and speed
	 */
	snprintf(addr, Maxpath, "%s/stats", dir);
	fd = sysopen(addr, O_READ);
	if (fd < 0)
		error(EFAIL, "can't open ether stats: %s", get_cur_errbuf());

	buf = kzmalloc(512, 0);
	n = sysread(fd, buf, 511);
	sysclose(fd);
	if (n <= 0)
		error(EIO, ERROR_FIXME);
	buf[n] = 0;

	ptr = strstr(buf, "addr: ");
	if (!ptr)
		error(EIO, ERROR_FIXME);
	ptr += 6;
	parsemac(ifc->mac, ptr, 6);

	ptr = strstr(buf, "feat: ");
	if (ptr) {
		ptr += 6;
		ifc->feat = parsefeat(ptr);
	} else {
		ifc->feat = 0;
	}
	/*
	 *  open arp conversation
	 */
	snprintf(addr, Maxpath, "%s!0x806", argv[2]);
	fd = kdial(addr, NULL, NULL, NULL);
	if (fd < 0)
		error(EFAIL, "dial 0x806 failed: %s", get_cur_errbuf());
	achan = commonfdtochan(fd, O_RDWR, 0, 1);
	sysclose(fd);

	/*
	 *  open ip conversation
	 *
	 *  the dial will fail if the type is already open on
	 *  this device.
	 */
	snprintf(addr, Maxpath, "%s!0x86DD", argv[2]);
	fd = kdial(addr, NULL, dir, &cfd);
	if (fd < 0)
		error(EFAIL, "dial 0x86DD failed: %s", get_cur_errbuf());
	mchan6 = commonfdtochan(fd, O_RDWR, 0, 1);
	cchan6 = commonfdtochan(cfd, O_RDWR, 0, 1);
	sysclose(fd);
	sysclose(cfd);

	/*
	 *  make it non-blocking
	 */
	devtab[cchan6->type].write(cchan6, nbmsg, strlen(nbmsg), 0);

	er = kzmalloc(sizeof(*er), 0);
	er->mchan4 = mchan4;
	er->cchan4 = cchan4;
	er->achan = achan;
	er->mchan6 = mchan6;
	er->cchan6 = cchan6;
	er->f = ifc->conv->p->f;
	ifc->arg = er;

	kfree(buf);
	kfree(addr);
	kfree(dir);
	poperror();

	ktask("etherread4", etherread4, ifc);
	ktask("recvarpproc", recvarpproc, ifc);
	ktask("etherread6", etherread6, ifc);
}

/*
 *  called with ifc wlock'd
 */
static void etherunbind(struct Ipifc *ifc)
{
	Etherrock *er = ifc->arg;
	printk("[kernel] etherunbind not supported yet!\n");

	// we'll need to tell the ktasks to exit, maybe via flags and a wakeup
#if 0
	if (er->read4p)
		postnote(er->read4p, 1, "unbind", 0);
	if (er->read6p)
		postnote(er->read6p, 1, "unbind", 0);
	if (er->arpp)
		postnote(er->arpp, 1, "unbind", 0);
#endif

	/* wait for readers to die */
	while (er->arpp != 0 || er->read4p != 0 || er->read6p != 0)
		cpu_relax();
	kthread_usleep(300 * 1000);

	if (er->mchan4 != NULL)
		cclose(er->mchan4);
	if (er->achan != NULL)
		cclose(er->achan);
	if (er->cchan4 != NULL)
		cclose(er->cchan4);
	if (er->mchan6 != NULL)
		cclose(er->mchan6);
	if (er->cchan6 != NULL)
		cclose(er->cchan6);

	kfree(er);
}

/*
 * copy ethernet address
 */
static inline void etherfilladdr(uint16_t *pkt, uint16_t *dst, uint16_t *src)
{
	*pkt++ = *dst++;
	*pkt++ = *dst++;
	*pkt++ = *dst++;
	*pkt++ = *src++;
	*pkt++ = *src++;
	*pkt = *src;
}

/*
 *  called by ipoput with a single block to write with ifc rlock'd
 */
static void etherbwrite(struct Ipifc *ifc, struct block *bp, int version,
			uint8_t *ip)
{
	Etherhdr *eh;
	struct arpent *a;
	uint8_t mac[6];
	Etherrock *er = ifc->arg;

	ipifc_trace_block(ifc, bp);
	/* get mac address of destination.
	 *
	 * Locking is tricky here.  If we get arpent 'a' back, the f->arp is
	 * qlocked.  if multicastarp returns bp, then it unlocked it for us.  if
	 * not, sendarp or resolveaddr6 unlocked it for us.  yikes. */
	a = arpget(er->f->arp, bp, version, ifc, ip, mac);
	if (a) {
		/* check for broadcast or multicast.  if it is either, this
		 * sorts that out and returns the bp for the first packet on the
		 * arp's hold list.*/
		bp = multicastarp(er->f, a, ifc->m, mac);
		if (bp == NULL) {
			switch (version) {
				case V4:
					sendarp(ifc, a);
					break;
				case V6:
					resolveaddr6(ifc, a);
					break;
				default:
					panic("etherbwrite: version %d",
					      version);
			}
			return;
		}
	}

	/* make it a single block with space for the ether header */
	bp = padblock(bp, ifc->m->hsize);
	if (bp->next)
		bp = concatblock(bp);
	eh = (Etherhdr *) bp->rp;

	/* copy in mac addresses and ether type */
	etherfilladdr((uint16_t *)bp->rp, (uint16_t *)mac,
		      (uint16_t *)ifc->mac);

	switch (version) {
	case V4:
		eh->t[0] = 0x08;
		eh->t[1] = 0x00;
		devtab[er->mchan4->type].bwrite(er->mchan4, bp, 0);
		break;
	case V6:
		eh->t[0] = 0x86;
		eh->t[1] = 0xDD;
		devtab[er->mchan6->type].bwrite(er->mchan6, bp, 0);
		break;
	default:
		panic("etherbwrite2: version %d", version);
	}
	ifc->out++;
}

/*
 *  process to read from the ethernet
 */
static void etherread4(void *a)
{
	ERRSTACK(2);
	struct Ipifc *ifc;
	struct block *bp;
	Etherrock *er;

	ifc = a;
	er = ifc->arg;
	er->read4p = current;	/* hide identity under a rock for unbind */
	if (waserror()) {
		er->read4p = 0;
		poperror();
		warn("etherread4 returns, probably unexpectedly\n");
		return;
	}
	for (;;) {
		bp = devtab[er->mchan4->type].bread(er->mchan4, 128 * 1024, 0);
		if (!canrlock(&ifc->rwlock)) {
			freeb(bp);
			continue;
		}
		if (waserror()) {
			runlock(&ifc->rwlock);
			nexterror();
		}
		ifc->in++;
		bp->rp += ifc->m->hsize;
		if (ifc->lifc == NULL) {
			freeb(bp);
		} else {
			ipifc_trace_block(ifc, bp);
			ipiput4(er->f, ifc, bp);
		}
		runlock(&ifc->rwlock);
		poperror();
	}
	poperror();
}

/*
 *  process to read from the ethernet, IPv6
 */
static void etherread6(void *a)
{
	ERRSTACK(2);
	struct Ipifc *ifc;
	struct block *bp;
	Etherrock *er;

	ifc = a;
	er = ifc->arg;
	er->read6p = current;	/* hide identity under a rock for unbind */
	if (waserror()) {
		er->read6p = 0;
		warn("etherread6 returns, probably unexpectedly\n");
		poperror();
		return;
	}
	for (;;) {
		bp = devtab[er->mchan6->type].bread(er->mchan6, ifc->maxtu, 0);
		if (!canrlock(&ifc->rwlock)) {
			freeb(bp);
			continue;
		}
		if (waserror()) {
			runlock(&ifc->rwlock);
			nexterror();
		}
		ifc->in++;
		bp->rp += ifc->m->hsize;
		if (ifc->lifc == NULL) {
			freeb(bp);
		} else {
			ipifc_trace_block(ifc, bp);
			ipiput6(er->f, ifc, bp);
		}
		runlock(&ifc->rwlock);
		poperror();
	}
	poperror();
}

static void etheraddmulti(struct Ipifc *ifc, uint8_t * a, uint8_t * unused)
{
	uint8_t mac[6];
	char buf[64];
	Etherrock *er = ifc->arg;
	int version;

	version = multicastea(mac, a);
	snprintf(buf, sizeof(buf), "addmulti %E", mac);
	switch (version) {
	case V4:
		devtab[er->cchan4->type].write(er->cchan4, buf, strlen(buf), 0);
		break;
	case V6:
		devtab[er->cchan6->type].write(er->cchan6, buf, strlen(buf), 0);
		break;
	default:
		panic("etheraddmulti: version %d", version);
	}
}

static void etherremmulti(struct Ipifc *ifc, uint8_t * a, uint8_t * unused)
{
	uint8_t mac[6];
	char buf[64];
	Etherrock *er = ifc->arg;
	int version;

	version = multicastea(mac, a);
	snprintf(buf, sizeof(buf), "remmulti %E", mac);
	switch (version) {
	case V4:
		devtab[er->cchan4->type].write(er->cchan4, buf, strlen(buf), 0);
		break;
	case V6:
		devtab[er->cchan6->type].write(er->cchan6, buf, strlen(buf), 0);
		break;
	default:
		panic("etherremmulti: version %d", version);
	}
}

/*
 *  send an ethernet arp
 *  (only v4, v6 uses the neighbor discovery, rfc1970)
 *
 * May drop packets on stale arps. */
static void sendarp(struct Ipifc *ifc, struct arpent *a)
{
	int n;
	struct block *bp;
	Etherarp *e;
	Etherrock *er = ifc->arg;

	/* don't do anything if it's been less than a second since the last.
	 * ctime is set to 0 for the first time through.  we hold the f->arp
	 * qlock, so there shouldn't be a problem with another arp request for
	 * this same arpent coming down til we update ctime again. */
	if (NOW - a->ctime < 1000) {
		arprelease(er->f->arp, a);
		return;
	}

	/* remove all but the last message.  brho: this might be unnecessary.
	 * we'll eventually send them.  but they should be quite stale at this
	 * point. */
	while ((bp = a->hold) != NULL) {
		if (bp == a->last)
			break;
		a->hold = bp->list;
		freeblist(bp);
	}

	/* update last sent time */
	a->ctime = NOW;
	arprelease(er->f->arp, a);

	n = sizeof(Etherarp);
	if (n < a->type->mintu)
		n = a->type->mintu;
	bp = block_alloc(n, MEM_WAIT);
	memset(bp->rp, 0, n);
	e = (Etherarp *) bp->rp;
	memmove(e->tpa, a->ip + IPv4off, sizeof(e->tpa));
	ipv4local(ifc, e->spa);
	memmove(e->sha, ifc->mac, sizeof(e->sha));
	memset(e->d, 0xff, sizeof(e->d));	/* ethernet broadcast */
	memmove(e->s, ifc->mac, sizeof(e->s));

	hnputs(e->type, ETARP);
	hnputs(e->hrd, 1);
	hnputs(e->pro, ETIP4);
	e->hln = sizeof(e->sha);
	e->pln = sizeof(e->spa);
	hnputs(e->op, ARPREQUEST);
	bp->wp += n;

	n = devtab[er->achan->type].bwrite(er->achan, bp, 0);
	if (n < 0)
		printd("arp: send: %r\n");
}

static void resolveaddr6(struct Ipifc *ifc, struct arpent *a)
{
	int sflag;
	struct block *bp;
	Etherrock *er = ifc->arg;
	uint8_t ipsrc[IPaddrlen];

	/* don't do anything if it's been less than a second since the last */
	if (NOW - a->ctime < ReTransTimer) {
		arprelease(er->f->arp, a);
		return;
	}

	/* remove all but the last message */
	while ((bp = a->hold) != NULL) {
		if (bp == a->last)
			break;
		a->hold = bp->list;
		freeblist(bp);
	}

	/* try to keep it around for a second more */
	a->ctime = NOW;
	a->rtime = NOW + ReTransTimer;
	if (a->rxtsrem <= 0) {
		arprelease(er->f->arp, a);
		return;
	}

	a->rxtsrem--;
	arprelease(er->f->arp, a);

	if ((sflag = ipv6anylocal(ifc, ipsrc)))
		icmpns(er->f, ipsrc, sflag, a->ip, TARG_MULTI, ifc->mac);
}

/*
 *  send a gratuitous arp to refresh arp caches
 */
static void sendgarp(struct Ipifc *ifc, uint8_t * ip)
{
	int n;
	struct block *bp;
	Etherarp *e;
	Etherrock *er = ifc->arg;

	/* don't arp for our initial non address */
	if (ipcmp(ip, IPnoaddr) == 0)
		return;

	n = sizeof(Etherarp);
	if (n < ifc->m->mintu)
		n = ifc->m->mintu;
	bp = block_alloc(n, MEM_WAIT);
	memset(bp->rp, 0, n);
	e = (Etherarp *) bp->rp;
	memmove(e->tpa, ip + IPv4off, sizeof(e->tpa));
	memmove(e->spa, ip + IPv4off, sizeof(e->spa));
	memmove(e->sha, ifc->mac, sizeof(e->sha));
	memset(e->d, 0xff, sizeof(e->d));	/* ethernet broadcast */
	memmove(e->s, ifc->mac, sizeof(e->s));

	hnputs(e->type, ETARP);
	hnputs(e->hrd, 1);
	hnputs(e->pro, ETIP4);
	e->hln = sizeof(e->sha);
	e->pln = sizeof(e->spa);
	hnputs(e->op, ARPREQUEST);
	bp->wp += n;

	n = devtab[er->achan->type].bwrite(er->achan, bp, 0);
	if (n < 0)
		printd("garp: send: %r\n");
}

static void recvarp(struct Ipifc *ifc)
{
	int n;
	struct block *ebp, *rbp;
	Etherarp *e, *r;
	uint8_t ip[IPaddrlen];
	static uint8_t eprinted[4];
	Etherrock *er = ifc->arg;

	ebp = devtab[er->achan->type].bread(er->achan, ifc->maxtu, 0);
	if (ebp == NULL) {
		printd("arp: rcv: %r\n");
		return;
	}

	e = (Etherarp *) ebp->rp;
	switch (nhgets(e->op)) {
	default:
		break;

	case ARPREPLY:
		/* check for machine using my ip address */
		v4tov6(ip, e->spa);
		if (iplocalonifc(ifc, ip) || ipproxyifc(er->f, ifc, ip)) {
			if (memcmp(e->sha, ifc->mac, sizeof(e->sha)) != 0) {
				printd("arprep: 0x%E/0x%E also has ip addr %V\n",
					   e->s, e->sha, e->spa);
				break;
			}
		}

		/* make sure we're not entering broadcast addresses */
		if (ipcmp(ip, ipbroadcast) == 0 ||
		    !memcmp(e->sha, etherbroadcast, sizeof(e->sha))) {
			printd("arprep: 0x%E/0x%E cannot register broadcast address %I\n",
			       e->s, e->sha, e->spa);
			break;
		}

		arpenter(er->f, V4, e->spa, e->sha, sizeof(e->sha), 0);
		break;

	case ARPREQUEST:
		/* don't answer arps till we know who we are */
		if (ifc->lifc == 0)
			break;

		/* check for machine using my ip or ether address */
		v4tov6(ip, e->spa);
		if (iplocalonifc(ifc, ip) || ipproxyifc(er->f, ifc, ip)) {
			if (memcmp(e->sha, ifc->mac, sizeof(e->sha)) != 0) {
				if (memcmp(eprinted, e->spa, sizeof(e->spa))) {
					/* print only once */
					printd("arpreq: 0x%E also has ip addr %V\n",
					       e->sha, e->spa);
					memmove(eprinted, e->spa,
						sizeof(e->spa));
				}
			}
		} else {
			if (memcmp(e->sha, ifc->mac, sizeof(e->sha)) == 0) {
				printd("arpreq: %V also has ether addr %E\n",
				       e->spa, e->sha);
				break;
			}
		}

		/* refresh what we know about sender */
		arpenter(er->f, V4, e->spa, e->sha, sizeof(e->sha), 1);

		/* answer only requests for our address or systems we're
		 * proxying for */
		v4tov6(ip, e->tpa);
		if (!iplocalonifc(ifc, ip))
			if (!ipproxyifc(er->f, ifc, ip))
				break;

		n = sizeof(Etherarp);
		if (n < ifc->mintu)
			n = ifc->mintu;
		rbp = block_alloc(n, MEM_WAIT);
		r = (Etherarp *) rbp->rp;
		memset(r, 0, sizeof(Etherarp));
		hnputs(r->type, ETARP);
		hnputs(r->hrd, 1);
		hnputs(r->pro, ETIP4);
		r->hln = sizeof(r->sha);
		r->pln = sizeof(r->spa);
		hnputs(r->op, ARPREPLY);
		memmove(r->tha, e->sha, sizeof(r->tha));
		memmove(r->tpa, e->spa, sizeof(r->tpa));
		memmove(r->sha, ifc->mac, sizeof(r->sha));
		memmove(r->spa, e->tpa, sizeof(r->spa));
		memmove(r->d, e->sha, sizeof(r->d));
		memmove(r->s, ifc->mac, sizeof(r->s));
		rbp->wp += n;

		n = devtab[er->achan->type].bwrite(er->achan, rbp, 0);
		if (n < 0)
			printd("arp: write: %r\n");
	}
	freeb(ebp);
}

static void recvarpproc(void *v)
{
	ERRSTACK(1);
	struct Ipifc *ifc = v;
	Etherrock *er = ifc->arg;

	er->arpp = current;
	if (waserror()) {
		er->arpp = 0;
		warn("recvarpproc returns, probably unexpectedly\n");
		poperror();
		return;
	}
	for (;;)
		recvarp(ifc);
	poperror();
}

static int multicastea(uint8_t * ea, uint8_t * ip)
{
	int x;

	switch (x = ipismulticast(ip)) {
	case V4:
		ea[0] = 0x01;
		ea[1] = 0x00;
		ea[2] = 0x5e;
		ea[3] = ip[13] & 0x7f;
		ea[4] = ip[14];
		ea[5] = ip[15];
		break;
	case V6:
		ea[0] = 0x33;
		ea[1] = 0x33;
		ea[2] = ip[12];
		ea[3] = ip[13];
		ea[4] = ip[14];
		ea[5] = ip[15];
		break;
	}
	return x;
}

/*
 *  fill in an arp entry for broadcast or multicast
 *  addresses.  Return the first queued packet for the
 *  IP address.
 */
static struct block *multicastarp(struct Fs *f, struct arpent *a,
				  struct medium *medium, uint8_t *mac)
{
	/* is it broadcast? */
	switch (ipforme(f, a->ip)) {
	case Runi:
		return NULL;
	case Rbcast:
		memset(mac, 0xff, 6);
		return arpresolve(f->arp, a, medium, mac);
	default:
		break;
	}

	/* if multicast, fill in mac */
	switch (multicastea(mac, a->ip)) {
	case V4:
	case V6:
		return arpresolve(f->arp, a, medium, mac);
	}

	/* let arp take care of it */
	return NULL;
}

static void __init ethermediumlink(void)
{
	addipmedium(&ethermedium);
	addipmedium(&trexmedium);
}
init_func_4(ethermediumlink);

static void etherpref2addr(uint8_t * pref, uint8_t * ea)
{
	pref[8] = ea[0] | 0x2;
	pref[9] = ea[1];
	pref[10] = ea[2];
	pref[11] = 0xFF;
	pref[12] = 0xFE;
	pref[13] = ea[3];
	pref[14] = ea[4];
	pref[15] = ea[5];
}
