1 /*
2 * An ethernet /dev/null.
3 * Useful as a bridging target with ethernet-based VPN.
4 */
5 #include "u.h"
6 #include "../port/lib.h"
7 #include "mem.h"
8 #include "dat.h"
9 #include "fns.h"
10 #include "io.h"
11 #include "../port/error.h"
12 #include "../port/netif.h"
13 #include "etherif.h"
14
15 enum{
16 CMea = 0,
17 CMmtu
18 };
19
20 static Cmdtab sinkcmds[] = {
21 {CMea, "ea", 2},
22 {CMmtu, "mtu", 2},
23 };
24
25 static long
ctl(Ether * ether,void * buf,long n)26 ctl(Ether *ether, void *buf, long n)
27 {
28 uchar ea[Eaddrlen];
29 Cmdbuf *cb;
30 Cmdtab *ct;
31 long mtu;
32
33 cb = parsecmd(buf, n);
34 if(waserror()){
35 free(cb);
36 nexterror();
37 }
38 ct = lookupcmd(cb, sinkcmds, nelem(sinkcmds));
39 switch(ct->index){
40 case CMea:
41 if(parseether(ea, cb->f[1]) < 0)
42 cmderror(cb, "invalid ea");
43 memmove(ether->ea, ea, Eaddrlen);
44 memmove(ether->addr, ether->ea, Eaddrlen);
45 break;
46 case CMmtu:
47 mtu = strtol(cb->f[1], nil, 0);
48 if(mtu < ETHERMINTU || mtu > 9000)
49 cmderror(cb, "invalid mtu");
50 ether->maxmtu = mtu;
51 ether->mtu = mtu;
52 break;
53 }
54 poperror();
55 free(cb);
56 return n;
57 }
58
59 static void
nop(Ether *)60 nop(Ether*)
61 {
62 }
63
64 static void
discard(Ether * ether)65 discard(Ether* ether)
66 {
67 qflush(ether->oq);
68 }
69
70 static int
reset(Ether * ether)71 reset(Ether* ether)
72 {
73 if(ether->type==nil)
74 return -1;
75 ether->mbps = 1000;
76 ether->attach = nop;
77 ether->transmit = discard;
78 ether->irq = -1;
79 ether->interrupt = nil;
80 ether->ifstat = nil;
81 ether->ctl = ctl;
82 ether->promiscuous = nil;
83 ether->multicast = nil;
84 ether->arg = ether;
85 return 0;
86 }
87
88 void
ethersinklink(void)89 ethersinklink(void)
90 {
91 addethercard("sink", reset);
92 }
93