tllc.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
---
tllc.c (2491B)
---
1 /*
2 * LLC. Only enough to dispatch to SNAP and IP.
3 */
4
5 #include <u.h>
6 #include <libc.h>
7 #include <ip.h>
8 #include "dat.h"
9 #include "protos.h"
10
11 enum
12 {
13 UFmt = 3,
14 Gsap = 1,
15 IG = 1,
16 SFmt = 1,
17 UPoll = 0x10,
18 IsPoll = 0x100,
19 XidFi = 0x81,
20
21 SapNull = 0,
22 SapGlobal = 0xff,
23 Sap8021BI = 0x02,
24 Sap8021BG = 0x03,
25 SapSNA = 0x04,
26 SapIP = 0x06,
27 SapProwayNM = 0x0e,
28 Sap8021D = 0x42,
29 SapRS511 = 0x4e,
30 SapISO8208 = 0x7e,
31 SapProway = 0x8e,
32 SapSnap = 0xaa,
33 SapIpx = 0xe0,
34 SapNetbeui = 0xf0,
35 SapIsons = 0xfe,
36 };
37
38 static Mux p_mux[] =
39 {
40 // Linux gives llc -> snap not llc -> ip.
41 // If we don't tell snoopy about llc -> ip, then the default patterns
42 // like snoopy -h radiotap -f dns work better.
43 // { "ip", SapIP },
44 { "snap", SapSnap },
45 { 0 }
46 };
47
48 typedef struct Hdr Hdr;
49 struct Hdr
50 {
51 uchar dsap;
52 uchar ssap;
53 uchar dsapf;
54 uchar ssapf;
55 ushort ctl;
56 uchar isu;
57 int hdrlen;
58 };
59
60 static int
61 unpackhdr(uchar *p, uchar *ep, Hdr *h)
62 {
63 if(p+3 > ep)
64 return -1;
65 h->dsapf = p[0];
66 h->dsap = h->dsapf & ~IG;
67 h->ssapf = p[1];
68 h->ssap = h->ssapf & ~Gsap;
69 h->ctl = p[2];
70 h->hdrlen = 3;
71 if((h->ctl&UFmt) == UFmt)
72 h->isu = 1;
73 else{
74 if(p+4 > ep)
75 return -1;
76 h->hdrlen = 4;
77 h->ctl = LittleS(p+2);
78 }
79 return 0;
80 }
81
82 enum
83 {
84 Ossap,
85 Odsap,
86 Ot,
87 };
88
89 static Field p_fields[] =
90 {
91 { "ssap", Fnum, Ossap, "ssap" },
92 { "dsap", Fnum, Odsap, "dsap" },
93 { 0 }
94 };
95
96 static void
97 p_compile(Filter *f)
98 {
99 Mux *m;
100
101 if(f->op == '='){
102 compile_cmp(llc.name, f, p_fields);
103 return;
104 }
105 for(m = p_mux; m->name != nil; m++){
106 if(strcmp(f->s, m->name) == 0){
107 f->pr = m->pr;
108 f->ulv = m->val;
109 f->subop = Ot;
110 return;
111 }
112 }
113 sysfatal("unknown llc field or protocol: %s", f->s);
114 }
115
116 static int
117 p_filter(Filter *f, Msg *m)
118 {
119 Hdr h;
120
121 memset(&h, 0, sizeof h);
122 if(unpackhdr(m->ps, m->pe, &h) < 0)
123 return 0;
124 m->ps += h.hdrlen;
125
126 switch(f->subop){
127 case Ossap:
128 return f->ulv == h.ssap;
129 case Odsap:
130 return f->ulv == h.dsap;
131 case Ot:
132 return f->ulv == h.ssap && f->ulv == h.dsap;
133 }
134 return 0;
135 }
136
137 static int
138 p_seprint(Msg *m)
139 {
140 Hdr h;
141
142 memset(&h, 0, sizeof h);
143 if(unpackhdr(m->ps, m->pe, &h) < 0)
144 return -1;
145
146 m->pr = &dump;
147 m->p = seprint(m->p, m->e, "ssap=%02x dsap=%02x ctl=%04x", h.ssap, h.dsap, h.ctl);
148 m->ps += h.hdrlen;
149 m->pr = &dump;
150 if(h.ssap == h.dsap){
151 switch(h.ssap){
152 case SapIP:
153 m->pr = &ip;
154 break;
155 case SapSnap:
156 m->pr = &snap;
157 break;
158 }
159 }
160 return 0;
161 }
162
163 Proto llc =
164 {
165 "llc",
166 p_compile,
167 p_filter,
168 p_seprint,
169 p_mux,
170 nil,
171 nil,
172 defaultframer
173 };