tether.c - plan9port - [fork] Plan 9 from user space
HTML git clone git://src.adamsgaard.dk/plan9port
DIR Log
DIR Files
DIR Refs
DIR README
DIR LICENSE
---
tether.c (2024B)
---
1 #include <u.h>
2 #include <libc.h>
3 #include <ip.h>
4 #include "dat.h"
5 #include "protos.h"
6
7 typedef struct Hdr Hdr;
8 struct Hdr {
9 uchar d[6];
10 uchar s[6];
11 uchar type[2];
12 char data[1500];
13 };
14 #define ETHERMINTU 60 /* minimum transmit size */
15 #define ETHERMAXTU 1514 /* maximum transmit size */
16 #define ETHERHDRSIZE 14 /* size of an ethernet header */
17
18 static Mux p_mux[] =
19 {
20 {"ip", 0x0800, } ,
21 {"arp", 0x0806, } ,
22 {"rarp", 0x0806, } ,
23 {"ip6", 0x86dd, } ,
24 {"pppoe_disc", 0x8863, },
25 {"pppoe_sess", 0x8864, },
26 {"eapol", 0x888e, },
27 {0}
28 };
29
30 enum
31 {
32 Os, /* source */
33 Od, /* destination */
34 Oa, /* source or destination */
35 Ot, /* type */
36 };
37
38 static Field p_fields[] =
39 {
40 {"s", Fether, Os, "source address", } ,
41 {"d", Fether, Od, "destination address", } ,
42 {"a", Fether, Oa, "source|destination address" } ,
43 {"sd", Fether, Oa, "source|destination address" } ,
44 {"t", Fnum, Ot, "type" } ,
45 {0}
46 };
47
48 static void
49 p_compile(Filter *f)
50 {
51 Mux *m;
52
53 if(f->op == '='){
54 compile_cmp(ether.name, f, p_fields);
55 return;
56 }
57 for(m = p_mux; m->name != nil; m++)
58 if(strcmp(f->s, m->name) == 0){
59 f->pr = m->pr;
60 f->ulv = m->val;
61 f->subop = Ot;
62 return;
63 }
64 sysfatal("unknown ethernet field or protocol: %s", f->s);
65 }
66
67 static int
68 p_filter(Filter *f, Msg *m)
69 {
70 Hdr *h;
71
72 if(m->pe - m->ps < ETHERHDRSIZE)
73 return 0;
74
75 h = (Hdr*)m->ps;
76 m->ps += ETHERHDRSIZE;
77
78 switch(f->subop){
79 case Os:
80 return !memcmp(h->s, f->a, 6);
81 case Od:
82 return !memcmp(h->d, f->a, 6);
83 case Oa:
84 return memcmp(h->s, f->a, 6) == 0 || memcmp(h->d, f->a, 6) == 0;
85 case Ot:
86 return NetS(h->type) == f->ulv;
87 }
88 return 0;
89 }
90
91 static int
92 p_seprint(Msg *m)
93 {
94 Hdr *h;
95 uint t;
96 int len;
97
98 len = m->pe - m->ps;
99 if(len < ETHERHDRSIZE)
100 return -1;
101
102 h = (Hdr*)m->ps;
103 m->ps += ETHERHDRSIZE;
104
105 t = NetS(h->type);
106 demux(p_mux, t, t, m, &dump);
107
108 m->p = seprint(m->p, m->e, "s=%E d=%E pr=%4.4ux ln=%d", h->s, h->d,
109 t, len);
110 return 0;
111 }
112
113 Proto ether =
114 {
115 "ether",
116 p_compile,
117 p_filter,
118 p_seprint,
119 p_mux,
120 "%#.4lux",
121 p_fields,
122 defaultframer
123 };