Blob


1 /*
2 * SNAP.
3 */
5 #include <u.h>
6 #include <libc.h>
7 #include <ip.h>
8 #include "dat.h"
9 #include "protos.h"
11 enum
12 {
13 Oorg,
14 Oet,
16 OuiEther = 0,
17 OuiCisco = 0xc,
18 OuiCisco90 = 0xf8,
19 OuiRfc2684 = 0x80c2,
20 OuiAppletalk = 0x80007,
21 };
23 static Mux p_mux[] =
24 {
25 {"ip", 0x0800, } ,
26 {"arp", 0x0806, } ,
27 {"rarp", 0x0806, } ,
28 {"ip6", 0x86dd, } ,
29 {"pppoe_disc", 0x8863, },
30 {"pppoe_sess", 0x8864, },
31 {"eapol", 0x888e, },
32 { 0 }
33 };
35 typedef struct Hdr Hdr;
36 struct Hdr
37 {
38 uchar org[3];
39 uchar et[2];
40 };
42 static Field p_fields[] =
43 {
44 { "org", Fnum, Oorg, "org" },
45 { "et", Fnum, Oet, "et" },
46 { 0 }
47 };
49 static void
50 p_compile(Filter *f)
51 {
52 Mux *m;
54 if(f->op == '='){
55 compile_cmp(snap.name, f, p_fields);
56 return;
57 }
58 for(m = p_mux; m->name != nil; m++){
59 if(strcmp(f->s, m->name) == 0){
60 f->pr = m->pr;
61 f->ulv = m->val;
62 f->subop = Oet;
63 return;
64 }
65 }
66 sysfatal("unknown snap field or protocol: %s", f->s);
67 }
69 static int
70 p_filter(Filter *f, Msg *m)
71 {
72 Hdr *h;
74 if(m->pe - m->ps < sizeof(Hdr))
75 return 0;
76 h = (Hdr*)m->ps;
77 m->ps += 5;
78 switch(f->subop){
79 case Oorg:
80 return f->ulv == Net3(h->org);
81 case Oet:
82 return f->ulv == NetS(h->et);
83 }
84 return 0;
85 }
87 static int
88 p_seprint(Msg *m)
89 {
90 Hdr *h;
92 if(m->pe - m->ps < sizeof(Hdr))
93 return 0;
94 h = (Hdr*)m->ps;
95 m->ps += 5;
96 demux(p_mux, NetS(h->et), NetS(h->et), m, &dump);
98 m->p = seprint(m->p, m->e, "org=%06x et=%04x", Net3(h->org), NetS(h->et));
99 return 0;
102 Proto snap =
104 "snap",
105 p_compile,
106 p_filter,
107 p_seprint,
108 p_mux,
109 nil,
110 nil,
111 defaultframer
112 };