xref: /plan9-contrib/sys/src/9/pc/ethersink.c (revision 1ff86ac2119b78ae0a5e2334633ca21c83e546e4)
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