19a747e4fSDavid du Colombier /*
29a747e4fSDavid du Colombier * An ethernet /dev/null.
39a747e4fSDavid du Colombier * Useful as a bridging target with ethernet-based VPN.
49a747e4fSDavid du Colombier */
59a747e4fSDavid du Colombier #include "u.h"
69a747e4fSDavid du Colombier #include "../port/lib.h"
79a747e4fSDavid du Colombier #include "mem.h"
89a747e4fSDavid du Colombier #include "dat.h"
99a747e4fSDavid du Colombier #include "fns.h"
109a747e4fSDavid du Colombier #include "io.h"
119a747e4fSDavid du Colombier #include "../port/error.h"
129a747e4fSDavid du Colombier #include "../port/netif.h"
139a747e4fSDavid du Colombier #include "etherif.h"
149a747e4fSDavid du Colombier
15*1ff86ac2SDavid du Colombier enum{
16*1ff86ac2SDavid du Colombier CMea = 0,
17*1ff86ac2SDavid du Colombier CMmtu
18*1ff86ac2SDavid du Colombier };
19*1ff86ac2SDavid du Colombier
20*1ff86ac2SDavid du Colombier static Cmdtab sinkcmds[] = {
21*1ff86ac2SDavid du Colombier {CMea, "ea", 2},
22*1ff86ac2SDavid du Colombier {CMmtu, "mtu", 2},
23*1ff86ac2SDavid du Colombier };
24*1ff86ac2SDavid du Colombier
259a747e4fSDavid du Colombier static long
ctl(Ether * ether,void * buf,long n)269a747e4fSDavid du Colombier ctl(Ether *ether, void *buf, long n)
279a747e4fSDavid du Colombier {
289a747e4fSDavid du Colombier uchar ea[Eaddrlen];
299a747e4fSDavid du Colombier Cmdbuf *cb;
30*1ff86ac2SDavid du Colombier Cmdtab *ct;
31*1ff86ac2SDavid du Colombier long mtu;
329a747e4fSDavid du Colombier
339a747e4fSDavid du Colombier cb = parsecmd(buf, n);
34*1ff86ac2SDavid du Colombier if(waserror()){
359a747e4fSDavid du Colombier free(cb);
36*1ff86ac2SDavid du Colombier nexterror();
37*1ff86ac2SDavid du Colombier }
38*1ff86ac2SDavid du Colombier ct = lookupcmd(cb, sinkcmds, nelem(sinkcmds));
39*1ff86ac2SDavid du Colombier switch(ct->index){
40*1ff86ac2SDavid du Colombier case CMea:
41*1ff86ac2SDavid du Colombier if(parseether(ea, cb->f[1]) < 0)
42*1ff86ac2SDavid du Colombier cmderror(cb, "invalid ea");
439a747e4fSDavid du Colombier memmove(ether->ea, ea, Eaddrlen);
449a747e4fSDavid du Colombier memmove(ether->addr, ether->ea, Eaddrlen);
45*1ff86ac2SDavid du Colombier break;
46*1ff86ac2SDavid du Colombier case CMmtu:
47*1ff86ac2SDavid du Colombier mtu = strtol(cb->f[1], nil, 0);
48*1ff86ac2SDavid du Colombier if(mtu < ETHERMINTU || mtu > 9000)
49*1ff86ac2SDavid du Colombier cmderror(cb, "invalid mtu");
50*1ff86ac2SDavid du Colombier ether->maxmtu = mtu;
51*1ff86ac2SDavid du Colombier ether->mtu = mtu;
52*1ff86ac2SDavid du Colombier break;
539a747e4fSDavid du Colombier }
54*1ff86ac2SDavid du Colombier poperror();
559a747e4fSDavid du Colombier free(cb);
56*1ff86ac2SDavid du Colombier return n;
579a747e4fSDavid du Colombier }
589a747e4fSDavid du Colombier
599a747e4fSDavid du Colombier static void
nop(Ether *)609a747e4fSDavid du Colombier nop(Ether*)
619a747e4fSDavid du Colombier {
629a747e4fSDavid du Colombier }
639a747e4fSDavid du Colombier
64*1ff86ac2SDavid du Colombier static void
discard(Ether * ether)65*1ff86ac2SDavid du Colombier discard(Ether* ether)
66*1ff86ac2SDavid du Colombier {
67*1ff86ac2SDavid du Colombier qflush(ether->oq);
68*1ff86ac2SDavid du Colombier }
69*1ff86ac2SDavid du Colombier
709a747e4fSDavid du Colombier static int
reset(Ether * ether)719a747e4fSDavid du Colombier reset(Ether* ether)
729a747e4fSDavid du Colombier {
739a747e4fSDavid du Colombier if(ether->type==nil)
749a747e4fSDavid du Colombier return -1;
759a747e4fSDavid du Colombier ether->mbps = 1000;
769a747e4fSDavid du Colombier ether->attach = nop;
77*1ff86ac2SDavid du Colombier ether->transmit = discard;
78fb7f0c93SDavid du Colombier ether->irq = -1;
799a747e4fSDavid du Colombier ether->interrupt = nil;
809a747e4fSDavid du Colombier ether->ifstat = nil;
819a747e4fSDavid du Colombier ether->ctl = ctl;
829a747e4fSDavid du Colombier ether->promiscuous = nil;
839a747e4fSDavid du Colombier ether->multicast = nil;
849a747e4fSDavid du Colombier ether->arg = ether;
859a747e4fSDavid du Colombier return 0;
869a747e4fSDavid du Colombier }
879a747e4fSDavid du Colombier
889a747e4fSDavid du Colombier void
ethersinklink(void)899a747e4fSDavid du Colombier ethersinklink(void)
909a747e4fSDavid du Colombier {
919a747e4fSDavid du Colombier addethercard("sink", reset);
929a747e4fSDavid du Colombier }
93