Blame


1 87a52e04 2005-12-26 devnull #include <u.h>
2 87a52e04 2005-12-26 devnull #include <libc.h>
3 87a52e04 2005-12-26 devnull #include <ip.h>
4 87a52e04 2005-12-26 devnull #include <bio.h>
5 87a52e04 2005-12-26 devnull #include <fcall.h>
6 87a52e04 2005-12-26 devnull #include <libsec.h>
7 87a52e04 2005-12-26 devnull #include "dat.h"
8 87a52e04 2005-12-26 devnull #include "protos.h"
9 87a52e04 2005-12-26 devnull #include "y.tab.h"
10 87a52e04 2005-12-26 devnull
11 87a52e04 2005-12-26 devnull int Cflag;
12 87a52e04 2005-12-26 devnull int pflag;
13 87a52e04 2005-12-26 devnull int Nflag;
14 87a52e04 2005-12-26 devnull int sflag;
15 87a52e04 2005-12-26 devnull int tiflag;
16 87a52e04 2005-12-26 devnull int toflag;
17 87a52e04 2005-12-26 devnull
18 87a52e04 2005-12-26 devnull char *prom = "promiscuous";
19 87a52e04 2005-12-26 devnull
20 87a52e04 2005-12-26 devnull enum
21 87a52e04 2005-12-26 devnull {
22 87a52e04 2005-12-26 devnull Pktlen= 64*1024,
23 cbeb0b26 2006-04-01 devnull Blen= 16*1024
24 87a52e04 2005-12-26 devnull };
25 87a52e04 2005-12-26 devnull
26 87a52e04 2005-12-26 devnull Filter *filter;
27 87a52e04 2005-12-26 devnull Proto *root;
28 87a52e04 2005-12-26 devnull Biobuf out;
29 87a52e04 2005-12-26 devnull vlong starttime, pkttime;
30 87a52e04 2005-12-26 devnull int pcap;
31 87a52e04 2005-12-26 devnull
32 87a52e04 2005-12-26 devnull int filterpkt(Filter *f, uchar *ps, uchar *pe, Proto *pr, int);
33 87a52e04 2005-12-26 devnull void printpkt(char *p, char *e, uchar *ps, uchar *pe);
34 87a52e04 2005-12-26 devnull void mkprotograph(void);
35 87a52e04 2005-12-26 devnull Proto* findproto(char *name);
36 87a52e04 2005-12-26 devnull Filter* compile(Filter *f);
37 87a52e04 2005-12-26 devnull void printfilter(Filter *f, char *tag);
38 a38a1836 2006-02-14 devnull void printhelp(char*);
39 87a52e04 2005-12-26 devnull void tracepkt(uchar*, int);
40 87a52e04 2005-12-26 devnull void pcaphdr(void);
41 87a52e04 2005-12-26 devnull
42 87a52e04 2005-12-26 devnull void
43 a38a1836 2006-02-14 devnull printusage(void)
44 a38a1836 2006-02-14 devnull {
45 a38a1836 2006-02-14 devnull fprint(2, "usage: %s [-CDdpst] [-N n] [-f filter] [-h first-header] path\n", argv0);
46 a38a1836 2006-02-14 devnull fprint(2, " for protocol help: %s -? [proto]\n", argv0);
47 a38a1836 2006-02-14 devnull }
48 a38a1836 2006-02-14 devnull
49 a38a1836 2006-02-14 devnull void
50 87a52e04 2005-12-26 devnull usage(void)
51 87a52e04 2005-12-26 devnull {
52 a38a1836 2006-02-14 devnull printusage();
53 87a52e04 2005-12-26 devnull exits("usage");
54 87a52e04 2005-12-26 devnull }
55 87a52e04 2005-12-26 devnull
56 87a52e04 2005-12-26 devnull void
57 87a52e04 2005-12-26 devnull main(int argc, char **argv)
58 87a52e04 2005-12-26 devnull {
59 87a52e04 2005-12-26 devnull uchar *pkt;
60 87a52e04 2005-12-26 devnull char *buf, *file, *p, *e;
61 87a52e04 2005-12-26 devnull int fd;
62 87a52e04 2005-12-26 devnull int n;
63 87a52e04 2005-12-26 devnull
64 87a52e04 2005-12-26 devnull Binit(&out, 1, OWRITE);
65 87a52e04 2005-12-26 devnull
66 87a52e04 2005-12-26 devnull fmtinstall('E', eipfmt);
67 87a52e04 2005-12-26 devnull fmtinstall('V', eipfmt);
68 87a52e04 2005-12-26 devnull fmtinstall('I', eipfmt);
69 87a52e04 2005-12-26 devnull fmtinstall('H', encodefmt);
70 87a52e04 2005-12-26 devnull fmtinstall('F', fcallfmt);
71 87a52e04 2005-12-26 devnull
72 87a52e04 2005-12-26 devnull pkt = malloc(Pktlen+16);
73 87a52e04 2005-12-26 devnull pkt += 16;
74 87a52e04 2005-12-26 devnull buf = malloc(Blen);
75 87a52e04 2005-12-26 devnull e = buf+Blen-1;
76 87a52e04 2005-12-26 devnull
77 87a52e04 2005-12-26 devnull pflag = 1;
78 87a52e04 2005-12-26 devnull Nflag = 32;
79 87a52e04 2005-12-26 devnull sflag = 0;
80 87a52e04 2005-12-26 devnull
81 87a52e04 2005-12-26 devnull mkprotograph();
82 87a52e04 2005-12-26 devnull
83 87a52e04 2005-12-26 devnull ARGBEGIN{
84 a38a1836 2006-02-14 devnull default:
85 a38a1836 2006-02-14 devnull usage();
86 87a52e04 2005-12-26 devnull case '?':
87 a38a1836 2006-02-14 devnull printusage();
88 a38a1836 2006-02-14 devnull printhelp(ARGF());
89 87a52e04 2005-12-26 devnull exits(0);
90 87a52e04 2005-12-26 devnull break;
91 87a52e04 2005-12-26 devnull case 'N':
92 a38a1836 2006-02-14 devnull p = EARGF(usage());
93 87a52e04 2005-12-26 devnull Nflag = atoi(p);
94 87a52e04 2005-12-26 devnull break;
95 87a52e04 2005-12-26 devnull case 'f':
96 a38a1836 2006-02-14 devnull p = EARGF(usage());
97 87a52e04 2005-12-26 devnull yyinit(p);
98 87a52e04 2005-12-26 devnull yyparse();
99 87a52e04 2005-12-26 devnull break;
100 87a52e04 2005-12-26 devnull case 's':
101 87a52e04 2005-12-26 devnull sflag = 1;
102 87a52e04 2005-12-26 devnull break;
103 87a52e04 2005-12-26 devnull case 'h':
104 a38a1836 2006-02-14 devnull p = EARGF(usage());
105 87a52e04 2005-12-26 devnull root = findproto(p);
106 87a52e04 2005-12-26 devnull if(root == nil)
107 87a52e04 2005-12-26 devnull sysfatal("unknown protocol: %s", p);
108 87a52e04 2005-12-26 devnull break;
109 87a52e04 2005-12-26 devnull case 'd':
110 87a52e04 2005-12-26 devnull toflag = 1;
111 87a52e04 2005-12-26 devnull break;
112 87a52e04 2005-12-26 devnull case 'D':
113 87a52e04 2005-12-26 devnull toflag = 1;
114 87a52e04 2005-12-26 devnull pcap = 1;
115 87a52e04 2005-12-26 devnull break;
116 87a52e04 2005-12-26 devnull case 't':
117 87a52e04 2005-12-26 devnull tiflag = 1;
118 87a52e04 2005-12-26 devnull break;
119 87a52e04 2005-12-26 devnull case 'C':
120 87a52e04 2005-12-26 devnull Cflag = 1;
121 87a52e04 2005-12-26 devnull break;
122 87a52e04 2005-12-26 devnull case 'p':
123 87a52e04 2005-12-26 devnull pflag = 0;
124 87a52e04 2005-12-26 devnull break;
125 87a52e04 2005-12-26 devnull }ARGEND;
126 87a52e04 2005-12-26 devnull
127 87a52e04 2005-12-26 devnull if(pcap)
128 87a52e04 2005-12-26 devnull pcaphdr();
129 87a52e04 2005-12-26 devnull
130 a38a1836 2006-02-14 devnull if(argc > 1)
131 a38a1836 2006-02-14 devnull usage();
132 a38a1836 2006-02-14 devnull
133 87a52e04 2005-12-26 devnull if(argc == 0)
134 87a52e04 2005-12-26 devnull file = nil;
135 87a52e04 2005-12-26 devnull else
136 87a52e04 2005-12-26 devnull file = argv[0];
137 87a52e04 2005-12-26 devnull
138 87a52e04 2005-12-26 devnull if(tiflag){
139 a38a1836 2006-02-14 devnull if(file == nil)
140 a38a1836 2006-02-14 devnull sysfatal("must specify file with -t");
141 87a52e04 2005-12-26 devnull fd = open(file, OREAD);
142 87a52e04 2005-12-26 devnull if(fd < 0)
143 87a52e04 2005-12-26 devnull sysfatal("opening %s: %r", file);
144 87a52e04 2005-12-26 devnull }else{
145 87a52e04 2005-12-26 devnull fd = opendevice(file, pflag);
146 87a52e04 2005-12-26 devnull if(fd < 0)
147 a38a1836 2006-02-14 devnull sysfatal("opening device %s: %r", file);
148 87a52e04 2005-12-26 devnull }
149 87a52e04 2005-12-26 devnull if(root == nil)
150 87a52e04 2005-12-26 devnull root = &ether;
151 a38a1836 2006-02-14 devnull
152 87a52e04 2005-12-26 devnull filter = compile(filter);
153 87a52e04 2005-12-26 devnull
154 87a52e04 2005-12-26 devnull if(tiflag){
155 87a52e04 2005-12-26 devnull /* read a trace file */
156 87a52e04 2005-12-26 devnull for(;;){
157 87a52e04 2005-12-26 devnull n = read(fd, pkt, 10);
158 87a52e04 2005-12-26 devnull if(n != 10)
159 87a52e04 2005-12-26 devnull break;
160 87a52e04 2005-12-26 devnull pkttime = NetL(pkt+2);
161 87a52e04 2005-12-26 devnull pkttime = (pkttime<<32) | NetL(pkt+6);
162 87a52e04 2005-12-26 devnull if(starttime == 0LL)
163 87a52e04 2005-12-26 devnull starttime = pkttime;
164 87a52e04 2005-12-26 devnull n = NetS(pkt);
165 87a52e04 2005-12-26 devnull if(readn(fd, pkt, n) != n)
166 87a52e04 2005-12-26 devnull break;
167 87a52e04 2005-12-26 devnull if(filterpkt(filter, pkt, pkt+n, root, 1))
168 87a52e04 2005-12-26 devnull if(toflag)
169 87a52e04 2005-12-26 devnull tracepkt(pkt, n);
170 87a52e04 2005-12-26 devnull else
171 87a52e04 2005-12-26 devnull printpkt(buf, e, pkt, pkt+n);
172 87a52e04 2005-12-26 devnull }
173 87a52e04 2005-12-26 devnull } else {
174 87a52e04 2005-12-26 devnull /* read a real time stream */
175 87a52e04 2005-12-26 devnull starttime = nsec();
176 87a52e04 2005-12-26 devnull for(;;){
177 87a52e04 2005-12-26 devnull n = root->framer(fd, pkt, Pktlen);
178 87a52e04 2005-12-26 devnull if(n <= 0)
179 87a52e04 2005-12-26 devnull break;
180 87a52e04 2005-12-26 devnull pkttime = nsec();
181 87a52e04 2005-12-26 devnull if(filterpkt(filter, pkt, pkt+n, root, 1))
182 87a52e04 2005-12-26 devnull if(toflag)
183 87a52e04 2005-12-26 devnull tracepkt(pkt, n);
184 87a52e04 2005-12-26 devnull else
185 87a52e04 2005-12-26 devnull printpkt(buf, e, pkt, pkt+n);
186 87a52e04 2005-12-26 devnull }
187 87a52e04 2005-12-26 devnull }
188 87a52e04 2005-12-26 devnull }
189 87a52e04 2005-12-26 devnull
190 87a52e04 2005-12-26 devnull /* create a new filter node */
191 87a52e04 2005-12-26 devnull Filter*
192 87a52e04 2005-12-26 devnull newfilter(void)
193 87a52e04 2005-12-26 devnull {
194 87a52e04 2005-12-26 devnull Filter *f;
195 87a52e04 2005-12-26 devnull
196 87a52e04 2005-12-26 devnull f = mallocz(sizeof(*f), 1);
197 87a52e04 2005-12-26 devnull if(f == nil)
198 87a52e04 2005-12-26 devnull sysfatal("newfilter: %r");
199 87a52e04 2005-12-26 devnull return f;
200 87a52e04 2005-12-26 devnull }
201 87a52e04 2005-12-26 devnull
202 87a52e04 2005-12-26 devnull /*
203 87a52e04 2005-12-26 devnull * apply filter to packet
204 87a52e04 2005-12-26 devnull */
205 87a52e04 2005-12-26 devnull int
206 87a52e04 2005-12-26 devnull _filterpkt(Filter *f, Msg *m)
207 87a52e04 2005-12-26 devnull {
208 87a52e04 2005-12-26 devnull Msg ma;
209 87a52e04 2005-12-26 devnull
210 87a52e04 2005-12-26 devnull if(f == nil)
211 87a52e04 2005-12-26 devnull return 1;
212 87a52e04 2005-12-26 devnull
213 87a52e04 2005-12-26 devnull switch(f->op){
214 87a52e04 2005-12-26 devnull case '!':
215 87a52e04 2005-12-26 devnull return !_filterpkt(f->l, m);
216 87a52e04 2005-12-26 devnull case LAND:
217 87a52e04 2005-12-26 devnull ma = *m;
218 87a52e04 2005-12-26 devnull return _filterpkt(f->l, &ma) && _filterpkt(f->r, m);
219 87a52e04 2005-12-26 devnull case LOR:
220 87a52e04 2005-12-26 devnull ma = *m;
221 87a52e04 2005-12-26 devnull return _filterpkt(f->l, &ma) || _filterpkt(f->r, m);
222 87a52e04 2005-12-26 devnull case WORD:
223 87a52e04 2005-12-26 devnull if(m->needroot){
224 87a52e04 2005-12-26 devnull if(m->pr != f->pr)
225 87a52e04 2005-12-26 devnull return 0;
226 87a52e04 2005-12-26 devnull m->needroot = 0;
227 87a52e04 2005-12-26 devnull }else{
228 a38a1836 2006-02-14 devnull if(m->pr && (m->pr->filter==nil || !(m->pr->filter)(f, m)))
229 87a52e04 2005-12-26 devnull return 0;
230 87a52e04 2005-12-26 devnull }
231 87a52e04 2005-12-26 devnull if(f->l == nil)
232 87a52e04 2005-12-26 devnull return 1;
233 87a52e04 2005-12-26 devnull m->pr = f->pr;
234 87a52e04 2005-12-26 devnull return _filterpkt(f->l, m);
235 87a52e04 2005-12-26 devnull }
236 87a52e04 2005-12-26 devnull sysfatal("internal error: filterpkt op: %d", f->op);
237 87a52e04 2005-12-26 devnull return 0;
238 87a52e04 2005-12-26 devnull }
239 87a52e04 2005-12-26 devnull int
240 87a52e04 2005-12-26 devnull filterpkt(Filter *f, uchar *ps, uchar *pe, Proto *pr, int needroot)
241 87a52e04 2005-12-26 devnull {
242 87a52e04 2005-12-26 devnull Msg m;
243 87a52e04 2005-12-26 devnull
244 87a52e04 2005-12-26 devnull if(f == nil)
245 87a52e04 2005-12-26 devnull return 1;
246 87a52e04 2005-12-26 devnull
247 87a52e04 2005-12-26 devnull m.needroot = needroot;
248 87a52e04 2005-12-26 devnull m.ps = ps;
249 87a52e04 2005-12-26 devnull m.pe = pe;
250 87a52e04 2005-12-26 devnull m.pr = pr;
251 87a52e04 2005-12-26 devnull return _filterpkt(f, &m);
252 87a52e04 2005-12-26 devnull }
253 87a52e04 2005-12-26 devnull
254 87a52e04 2005-12-26 devnull /*
255 87a52e04 2005-12-26 devnull * from the Unix world
256 87a52e04 2005-12-26 devnull */
257 87a52e04 2005-12-26 devnull #define PCAP_VERSION_MAJOR 2
258 87a52e04 2005-12-26 devnull #define PCAP_VERSION_MINOR 4
259 87a52e04 2005-12-26 devnull #define TCPDUMP_MAGIC 0xa1b2c3d4
260 87a52e04 2005-12-26 devnull
261 87a52e04 2005-12-26 devnull struct pcap_file_header {
262 87a52e04 2005-12-26 devnull ulong magic;
263 87a52e04 2005-12-26 devnull ushort version_major;
264 87a52e04 2005-12-26 devnull ushort version_minor;
265 87a52e04 2005-12-26 devnull long thiszone; /* gmt to local correction */
266 87a52e04 2005-12-26 devnull ulong sigfigs; /* accuracy of timestamps */
267 87a52e04 2005-12-26 devnull ulong snaplen; /* max length saved portion of each pkt */
268 87a52e04 2005-12-26 devnull ulong linktype; /* data link type (DLT_*) */
269 87a52e04 2005-12-26 devnull };
270 87a52e04 2005-12-26 devnull
271 87a52e04 2005-12-26 devnull struct pcap_pkthdr {
272 87a52e04 2005-12-26 devnull uvlong ts; /* time stamp */
273 87a52e04 2005-12-26 devnull ulong caplen; /* length of portion present */
274 87a52e04 2005-12-26 devnull ulong len; /* length this packet (off wire) */
275 87a52e04 2005-12-26 devnull };
276 87a52e04 2005-12-26 devnull
277 87a52e04 2005-12-26 devnull /*
278 87a52e04 2005-12-26 devnull * pcap trace header
279 87a52e04 2005-12-26 devnull */
280 87a52e04 2005-12-26 devnull void
281 87a52e04 2005-12-26 devnull pcaphdr(void)
282 87a52e04 2005-12-26 devnull {
283 87a52e04 2005-12-26 devnull struct pcap_file_header hdr;
284 87a52e04 2005-12-26 devnull
285 87a52e04 2005-12-26 devnull hdr.magic = TCPDUMP_MAGIC;
286 87a52e04 2005-12-26 devnull hdr.version_major = PCAP_VERSION_MAJOR;
287 87a52e04 2005-12-26 devnull hdr.version_minor = PCAP_VERSION_MINOR;
288 87a52e04 2005-12-26 devnull
289 87a52e04 2005-12-26 devnull hdr.thiszone = 0;
290 87a52e04 2005-12-26 devnull hdr.snaplen = 1500;
291 87a52e04 2005-12-26 devnull hdr.sigfigs = 0;
292 87a52e04 2005-12-26 devnull hdr.linktype = 1;
293 87a52e04 2005-12-26 devnull
294 87a52e04 2005-12-26 devnull write(1, &hdr, sizeof(hdr));
295 87a52e04 2005-12-26 devnull }
296 87a52e04 2005-12-26 devnull
297 87a52e04 2005-12-26 devnull /*
298 87a52e04 2005-12-26 devnull * write out a packet trace
299 87a52e04 2005-12-26 devnull */
300 87a52e04 2005-12-26 devnull void
301 87a52e04 2005-12-26 devnull tracepkt(uchar *ps, int len)
302 87a52e04 2005-12-26 devnull {
303 87a52e04 2005-12-26 devnull struct pcap_pkthdr *goo;
304 87a52e04 2005-12-26 devnull
305 87a52e04 2005-12-26 devnull if(pcap){
306 87a52e04 2005-12-26 devnull goo = (struct pcap_pkthdr*)(ps-16);
307 87a52e04 2005-12-26 devnull goo->ts = pkttime;
308 87a52e04 2005-12-26 devnull goo->caplen = len;
309 87a52e04 2005-12-26 devnull goo->len = len;
310 87a52e04 2005-12-26 devnull write(1, goo, len+16);
311 87a52e04 2005-12-26 devnull } else {
312 87a52e04 2005-12-26 devnull hnputs(ps-10, len);
313 87a52e04 2005-12-26 devnull hnputl(ps-8, pkttime>>32);
314 87a52e04 2005-12-26 devnull hnputl(ps-4, pkttime);
315 87a52e04 2005-12-26 devnull write(1, ps-10, len+10);
316 87a52e04 2005-12-26 devnull }
317 87a52e04 2005-12-26 devnull }
318 87a52e04 2005-12-26 devnull
319 87a52e04 2005-12-26 devnull /*
320 87a52e04 2005-12-26 devnull * format and print a packet
321 87a52e04 2005-12-26 devnull */
322 87a52e04 2005-12-26 devnull void
323 87a52e04 2005-12-26 devnull printpkt(char *p, char *e, uchar *ps, uchar *pe)
324 87a52e04 2005-12-26 devnull {
325 87a52e04 2005-12-26 devnull Msg m;
326 a38a1836 2006-02-14 devnull ulong dt;
327 a38a1836 2006-02-14 devnull
328 a38a1836 2006-02-14 devnull dt = (pkttime-starttime)/1000000LL;
329 a38a1836 2006-02-14 devnull m.p = seprint(p, e, "%6.6uld ms ", dt);
330 87a52e04 2005-12-26 devnull m.ps = ps;
331 87a52e04 2005-12-26 devnull m.pe = pe;
332 87a52e04 2005-12-26 devnull m.e = e;
333 87a52e04 2005-12-26 devnull m.pr = root;
334 87a52e04 2005-12-26 devnull while(m.p < m.e){
335 87a52e04 2005-12-26 devnull if(!sflag)
336 87a52e04 2005-12-26 devnull m.p = seprint(m.p, m.e, "\n\t");
337 87a52e04 2005-12-26 devnull m.p = seprint(m.p, m.e, "%s(", m.pr->name);
338 87a52e04 2005-12-26 devnull if((*m.pr->seprint)(&m) < 0){
339 87a52e04 2005-12-26 devnull m.p = seprint(m.p, m.e, "TOO SHORT");
340 87a52e04 2005-12-26 devnull m.ps = m.pe;
341 87a52e04 2005-12-26 devnull }
342 87a52e04 2005-12-26 devnull m.p = seprint(m.p, m.e, ")");
343 87a52e04 2005-12-26 devnull if(m.pr == nil || m.ps >= m.pe)
344 87a52e04 2005-12-26 devnull break;
345 87a52e04 2005-12-26 devnull }
346 87a52e04 2005-12-26 devnull *m.p++ = '\n';
347 87a52e04 2005-12-26 devnull
348 87a52e04 2005-12-26 devnull if(write(1, p, m.p - p) < 0)
349 87a52e04 2005-12-26 devnull sysfatal("stdout: %r");
350 87a52e04 2005-12-26 devnull }
351 87a52e04 2005-12-26 devnull
352 87a52e04 2005-12-26 devnull Proto **xprotos;
353 87a52e04 2005-12-26 devnull int nprotos;
354 87a52e04 2005-12-26 devnull
355 87a52e04 2005-12-26 devnull /* look up a protocol by its name */
356 87a52e04 2005-12-26 devnull Proto*
357 87a52e04 2005-12-26 devnull findproto(char *name)
358 87a52e04 2005-12-26 devnull {
359 87a52e04 2005-12-26 devnull int i;
360 87a52e04 2005-12-26 devnull
361 87a52e04 2005-12-26 devnull for(i = 0; i < nprotos; i++)
362 87a52e04 2005-12-26 devnull if(strcmp(xprotos[i]->name, name) == 0)
363 87a52e04 2005-12-26 devnull return xprotos[i];
364 87a52e04 2005-12-26 devnull return nil;
365 87a52e04 2005-12-26 devnull }
366 87a52e04 2005-12-26 devnull
367 87a52e04 2005-12-26 devnull /*
368 87a52e04 2005-12-26 devnull * add an undefined protocol to protos[]
369 87a52e04 2005-12-26 devnull */
370 87a52e04 2005-12-26 devnull Proto*
371 87a52e04 2005-12-26 devnull addproto(char *name)
372 87a52e04 2005-12-26 devnull {
373 87a52e04 2005-12-26 devnull Proto *pr;
374 87a52e04 2005-12-26 devnull
375 87a52e04 2005-12-26 devnull xprotos = realloc(xprotos, (nprotos+1)*sizeof(Proto*));
376 87a52e04 2005-12-26 devnull pr = malloc(sizeof *pr);
377 87a52e04 2005-12-26 devnull *pr = dump;
378 87a52e04 2005-12-26 devnull pr->name = name;
379 87a52e04 2005-12-26 devnull xprotos[nprotos++] = pr;
380 87a52e04 2005-12-26 devnull return pr;
381 87a52e04 2005-12-26 devnull }
382 87a52e04 2005-12-26 devnull
383 87a52e04 2005-12-26 devnull /*
384 87a52e04 2005-12-26 devnull * build a graph of protocols, this could easily be circular. This
385 87a52e04 2005-12-26 devnull * links together all the multiplexing in the protocol modules.
386 87a52e04 2005-12-26 devnull */
387 87a52e04 2005-12-26 devnull void
388 87a52e04 2005-12-26 devnull mkprotograph(void)
389 87a52e04 2005-12-26 devnull {
390 87a52e04 2005-12-26 devnull Proto **l;
391 87a52e04 2005-12-26 devnull Proto *pr;
392 87a52e04 2005-12-26 devnull Mux *m;
393 87a52e04 2005-12-26 devnull
394 87a52e04 2005-12-26 devnull /* copy protos into a reallocable area */
395 87a52e04 2005-12-26 devnull for(nprotos = 0; protos[nprotos] != nil; nprotos++)
396 87a52e04 2005-12-26 devnull ;
397 87a52e04 2005-12-26 devnull xprotos = malloc(nprotos*sizeof(Proto*));
398 87a52e04 2005-12-26 devnull memmove(xprotos, protos, nprotos*sizeof(Proto*));
399 87a52e04 2005-12-26 devnull
400 87a52e04 2005-12-26 devnull for(l = protos; *l != nil; l++){
401 87a52e04 2005-12-26 devnull pr = *l;
402 87a52e04 2005-12-26 devnull for(m = pr->mux; m != nil && m->name != nil; m++){
403 87a52e04 2005-12-26 devnull m->pr = findproto(m->name);
404 87a52e04 2005-12-26 devnull if(m->pr == nil)
405 87a52e04 2005-12-26 devnull m->pr = addproto(m->name);
406 87a52e04 2005-12-26 devnull }
407 87a52e04 2005-12-26 devnull }
408 87a52e04 2005-12-26 devnull }
409 87a52e04 2005-12-26 devnull
410 87a52e04 2005-12-26 devnull /*
411 87a52e04 2005-12-26 devnull * add in a protocol node
412 87a52e04 2005-12-26 devnull */
413 87a52e04 2005-12-26 devnull static Filter*
414 87a52e04 2005-12-26 devnull addnode(Filter *f, Proto *pr)
415 87a52e04 2005-12-26 devnull {
416 87a52e04 2005-12-26 devnull Filter *nf;
417 87a52e04 2005-12-26 devnull nf = newfilter();
418 87a52e04 2005-12-26 devnull nf->pr = pr;
419 87a52e04 2005-12-26 devnull nf->s = pr->name;
420 87a52e04 2005-12-26 devnull nf->l = f;
421 87a52e04 2005-12-26 devnull nf->op = WORD;
422 87a52e04 2005-12-26 devnull return nf;
423 87a52e04 2005-12-26 devnull }
424 87a52e04 2005-12-26 devnull
425 87a52e04 2005-12-26 devnull /*
426 87a52e04 2005-12-26 devnull * recurse through the protocol graph adding missing nodes
427 87a52e04 2005-12-26 devnull * to the filter if we reach the filter's protocol
428 87a52e04 2005-12-26 devnull */
429 87a52e04 2005-12-26 devnull static Filter*
430 87a52e04 2005-12-26 devnull _fillin(Filter *f, Proto *last, int depth)
431 87a52e04 2005-12-26 devnull {
432 87a52e04 2005-12-26 devnull Mux *m;
433 87a52e04 2005-12-26 devnull Filter *nf;
434 87a52e04 2005-12-26 devnull
435 87a52e04 2005-12-26 devnull if(depth-- <= 0)
436 87a52e04 2005-12-26 devnull return nil;
437 87a52e04 2005-12-26 devnull
438 87a52e04 2005-12-26 devnull for(m = last->mux; m != nil && m->name != nil; m++){
439 87a52e04 2005-12-26 devnull if(m->pr == nil)
440 87a52e04 2005-12-26 devnull continue;
441 87a52e04 2005-12-26 devnull if(f->pr == m->pr)
442 87a52e04 2005-12-26 devnull return f;
443 87a52e04 2005-12-26 devnull nf = _fillin(f, m->pr, depth);
444 87a52e04 2005-12-26 devnull if(nf != nil)
445 87a52e04 2005-12-26 devnull return addnode(nf, m->pr);
446 87a52e04 2005-12-26 devnull }
447 87a52e04 2005-12-26 devnull return nil;
448 87a52e04 2005-12-26 devnull }
449 87a52e04 2005-12-26 devnull
450 87a52e04 2005-12-26 devnull static Filter*
451 87a52e04 2005-12-26 devnull fillin(Filter *f, Proto *last)
452 87a52e04 2005-12-26 devnull {
453 87a52e04 2005-12-26 devnull int i;
454 87a52e04 2005-12-26 devnull Filter *nf;
455 87a52e04 2005-12-26 devnull
456 87a52e04 2005-12-26 devnull /* hack to make sure top level node is the root */
457 87a52e04 2005-12-26 devnull if(last == nil){
458 87a52e04 2005-12-26 devnull if(f->pr == root)
459 87a52e04 2005-12-26 devnull return f;
460 87a52e04 2005-12-26 devnull f = fillin(f, root);
461 87a52e04 2005-12-26 devnull if(f == nil)
462 87a52e04 2005-12-26 devnull return nil;
463 87a52e04 2005-12-26 devnull return addnode(f, root);
464 87a52e04 2005-12-26 devnull }
465 87a52e04 2005-12-26 devnull
466 87a52e04 2005-12-26 devnull /* breadth first search though the protocol graph */
467 87a52e04 2005-12-26 devnull nf = f;
468 87a52e04 2005-12-26 devnull for(i = 1; i < 20; i++){
469 87a52e04 2005-12-26 devnull nf = _fillin(f, last, i);
470 87a52e04 2005-12-26 devnull if(nf != nil)
471 87a52e04 2005-12-26 devnull break;
472 87a52e04 2005-12-26 devnull }
473 87a52e04 2005-12-26 devnull return nf;
474 87a52e04 2005-12-26 devnull }
475 87a52e04 2005-12-26 devnull
476 87a52e04 2005-12-26 devnull /*
477 87a52e04 2005-12-26 devnull * massage tree so that all paths from the root to a leaf
478 87a52e04 2005-12-26 devnull * contain a filter node for each header.
479 87a52e04 2005-12-26 devnull *
480 87a52e04 2005-12-26 devnull * also, set f->pr where possible
481 87a52e04 2005-12-26 devnull */
482 87a52e04 2005-12-26 devnull Filter*
483 87a52e04 2005-12-26 devnull complete(Filter *f, Proto *last)
484 87a52e04 2005-12-26 devnull {
485 87a52e04 2005-12-26 devnull Proto *pr;
486 87a52e04 2005-12-26 devnull
487 87a52e04 2005-12-26 devnull if(f == nil)
488 87a52e04 2005-12-26 devnull return f;
489 87a52e04 2005-12-26 devnull
490 87a52e04 2005-12-26 devnull /* do a depth first traversal of the filter tree */
491 87a52e04 2005-12-26 devnull switch(f->op){
492 87a52e04 2005-12-26 devnull case '!':
493 87a52e04 2005-12-26 devnull f->l = complete(f->l, last);
494 87a52e04 2005-12-26 devnull break;
495 87a52e04 2005-12-26 devnull case LAND:
496 87a52e04 2005-12-26 devnull case LOR:
497 87a52e04 2005-12-26 devnull f->l = complete(f->l, last);
498 87a52e04 2005-12-26 devnull f->r = complete(f->r, last);
499 87a52e04 2005-12-26 devnull break;
500 87a52e04 2005-12-26 devnull case '=':
501 87a52e04 2005-12-26 devnull break;
502 87a52e04 2005-12-26 devnull case WORD:
503 87a52e04 2005-12-26 devnull pr = findproto(f->s);
504 87a52e04 2005-12-26 devnull f->pr = pr;
505 87a52e04 2005-12-26 devnull if(pr == nil){
506 87a52e04 2005-12-26 devnull if(f->l != nil){
507 87a52e04 2005-12-26 devnull fprint(2, "%s unknown proto, ignoring params\n",
508 87a52e04 2005-12-26 devnull f->s);
509 87a52e04 2005-12-26 devnull f->l = nil;
510 87a52e04 2005-12-26 devnull }
511 87a52e04 2005-12-26 devnull } else {
512 87a52e04 2005-12-26 devnull f->l = complete(f->l, pr);
513 87a52e04 2005-12-26 devnull f = fillin(f, last);
514 87a52e04 2005-12-26 devnull if(f == nil)
515 87a52e04 2005-12-26 devnull sysfatal("internal error: can't get to %s", pr->name);
516 87a52e04 2005-12-26 devnull }
517 87a52e04 2005-12-26 devnull break;
518 87a52e04 2005-12-26 devnull }
519 87a52e04 2005-12-26 devnull return f;
520 87a52e04 2005-12-26 devnull }
521 87a52e04 2005-12-26 devnull
522 87a52e04 2005-12-26 devnull /*
523 87a52e04 2005-12-26 devnull * merge common nodes under | and & moving the merged node
524 87a52e04 2005-12-26 devnull * above the | or &.
525 87a52e04 2005-12-26 devnull *
526 87a52e04 2005-12-26 devnull * do some constant foldong, e.g. `true & x' becomes x and
527 87a52e04 2005-12-26 devnull * 'true | x' becomes true.
528 87a52e04 2005-12-26 devnull */
529 87a52e04 2005-12-26 devnull static int changed;
530 87a52e04 2005-12-26 devnull
531 87a52e04 2005-12-26 devnull static Filter*
532 87a52e04 2005-12-26 devnull _optimize(Filter *f)
533 87a52e04 2005-12-26 devnull {
534 87a52e04 2005-12-26 devnull Filter *l;
535 87a52e04 2005-12-26 devnull
536 87a52e04 2005-12-26 devnull if(f == nil)
537 87a52e04 2005-12-26 devnull return f;
538 87a52e04 2005-12-26 devnull
539 87a52e04 2005-12-26 devnull switch(f->op){
540 87a52e04 2005-12-26 devnull case '!':
541 87a52e04 2005-12-26 devnull /* is child also a not */
542 87a52e04 2005-12-26 devnull if(f->l->op == '!'){
543 87a52e04 2005-12-26 devnull changed = 1;
544 87a52e04 2005-12-26 devnull return f->l->l;
545 87a52e04 2005-12-26 devnull }
546 87a52e04 2005-12-26 devnull break;
547 87a52e04 2005-12-26 devnull case LOR:
548 87a52e04 2005-12-26 devnull /* are two children the same protocol? */
549 87a52e04 2005-12-26 devnull if(f->l->op != f->r->op || f->r->op != WORD
550 87a52e04 2005-12-26 devnull || f->l->pr != f->r->pr || f->l->pr == nil)
551 87a52e04 2005-12-26 devnull break; /* no optimization */
552 87a52e04 2005-12-26 devnull
553 87a52e04 2005-12-26 devnull changed = 1;
554 87a52e04 2005-12-26 devnull
555 87a52e04 2005-12-26 devnull /* constant folding */
556 87a52e04 2005-12-26 devnull /* if either child is childless, just return that */
557 87a52e04 2005-12-26 devnull if(f->l->l == nil)
558 87a52e04 2005-12-26 devnull return f->l;
559 87a52e04 2005-12-26 devnull else if(f->r->l == nil)
560 87a52e04 2005-12-26 devnull return f->r;
561 87a52e04 2005-12-26 devnull
562 87a52e04 2005-12-26 devnull /* move the common node up, thow away one node */
563 87a52e04 2005-12-26 devnull l = f->l;
564 87a52e04 2005-12-26 devnull f->l = l->l;
565 87a52e04 2005-12-26 devnull f->r = f->r->l;
566 87a52e04 2005-12-26 devnull l->l = f;
567 87a52e04 2005-12-26 devnull return l;
568 87a52e04 2005-12-26 devnull case LAND:
569 87a52e04 2005-12-26 devnull /* are two children the same protocol? */
570 87a52e04 2005-12-26 devnull if(f->l->op != f->r->op || f->r->op != WORD
571 87a52e04 2005-12-26 devnull || f->l->pr != f->r->pr || f->l->pr == nil)
572 87a52e04 2005-12-26 devnull break; /* no optimization */
573 87a52e04 2005-12-26 devnull
574 87a52e04 2005-12-26 devnull changed = 1;
575 87a52e04 2005-12-26 devnull
576 87a52e04 2005-12-26 devnull /* constant folding */
577 87a52e04 2005-12-26 devnull /* if either child is childless, ignore it */
578 87a52e04 2005-12-26 devnull if(f->l->l == nil)
579 87a52e04 2005-12-26 devnull return f->r;
580 87a52e04 2005-12-26 devnull else if(f->r->l == nil)
581 87a52e04 2005-12-26 devnull return f->l;
582 87a52e04 2005-12-26 devnull
583 87a52e04 2005-12-26 devnull /* move the common node up, thow away one node */
584 87a52e04 2005-12-26 devnull l = f->l;
585 87a52e04 2005-12-26 devnull f->l = _optimize(l->l);
586 87a52e04 2005-12-26 devnull f->r = _optimize(f->r->l);
587 87a52e04 2005-12-26 devnull l->l = f;
588 87a52e04 2005-12-26 devnull return l;
589 87a52e04 2005-12-26 devnull }
590 87a52e04 2005-12-26 devnull f->l = _optimize(f->l);
591 87a52e04 2005-12-26 devnull f->r = _optimize(f->r);
592 87a52e04 2005-12-26 devnull return f;
593 87a52e04 2005-12-26 devnull }
594 87a52e04 2005-12-26 devnull
595 87a52e04 2005-12-26 devnull Filter*
596 87a52e04 2005-12-26 devnull optimize(Filter *f)
597 87a52e04 2005-12-26 devnull {
598 87a52e04 2005-12-26 devnull do{
599 87a52e04 2005-12-26 devnull changed = 0;
600 87a52e04 2005-12-26 devnull f = _optimize(f);
601 87a52e04 2005-12-26 devnull }while(changed);
602 87a52e04 2005-12-26 devnull
603 87a52e04 2005-12-26 devnull return f;
604 87a52e04 2005-12-26 devnull }
605 87a52e04 2005-12-26 devnull
606 87a52e04 2005-12-26 devnull /*
607 87a52e04 2005-12-26 devnull * find any top level nodes that aren't the root
608 87a52e04 2005-12-26 devnull */
609 87a52e04 2005-12-26 devnull int
610 87a52e04 2005-12-26 devnull findbogus(Filter *f)
611 87a52e04 2005-12-26 devnull {
612 87a52e04 2005-12-26 devnull int rv;
613 87a52e04 2005-12-26 devnull
614 87a52e04 2005-12-26 devnull if(f->op != WORD){
615 87a52e04 2005-12-26 devnull rv = findbogus(f->l);
616 87a52e04 2005-12-26 devnull if(f->r)
617 87a52e04 2005-12-26 devnull rv |= findbogus(f->r);
618 87a52e04 2005-12-26 devnull return rv;
619 87a52e04 2005-12-26 devnull } else if(f->pr != root){
620 87a52e04 2005-12-26 devnull fprint(2, "bad top-level protocol: %s\n", f->s);
621 87a52e04 2005-12-26 devnull return 1;
622 87a52e04 2005-12-26 devnull }
623 87a52e04 2005-12-26 devnull return 0;
624 87a52e04 2005-12-26 devnull }
625 87a52e04 2005-12-26 devnull
626 87a52e04 2005-12-26 devnull /*
627 87a52e04 2005-12-26 devnull * compile the filter
628 87a52e04 2005-12-26 devnull */
629 87a52e04 2005-12-26 devnull static void
630 87a52e04 2005-12-26 devnull _compile(Filter *f, Proto *last)
631 87a52e04 2005-12-26 devnull {
632 87a52e04 2005-12-26 devnull if(f == nil)
633 87a52e04 2005-12-26 devnull return;
634 87a52e04 2005-12-26 devnull
635 87a52e04 2005-12-26 devnull switch(f->op){
636 87a52e04 2005-12-26 devnull case '!':
637 87a52e04 2005-12-26 devnull _compile(f->l, last);
638 87a52e04 2005-12-26 devnull break;
639 87a52e04 2005-12-26 devnull case LOR:
640 87a52e04 2005-12-26 devnull case LAND:
641 87a52e04 2005-12-26 devnull _compile(f->l, last);
642 87a52e04 2005-12-26 devnull _compile(f->r, last);
643 87a52e04 2005-12-26 devnull break;
644 87a52e04 2005-12-26 devnull case WORD:
645 a38a1836 2006-02-14 devnull if(last != nil){
646 a38a1836 2006-02-14 devnull if(last->compile == nil)
647 a38a1836 2006-02-14 devnull sysfatal("unknown %s subprotocol: %s", f->pr->name, f->s);
648 87a52e04 2005-12-26 devnull (*last->compile)(f);
649 a38a1836 2006-02-14 devnull }
650 87a52e04 2005-12-26 devnull if(f->l)
651 87a52e04 2005-12-26 devnull _compile(f->l, f->pr);
652 87a52e04 2005-12-26 devnull break;
653 87a52e04 2005-12-26 devnull case '=':
654 87a52e04 2005-12-26 devnull if(last == nil)
655 87a52e04 2005-12-26 devnull sysfatal("internal error: compilewalk: badly formed tree");
656 a38a1836 2006-02-14 devnull
657 a38a1836 2006-02-14 devnull if(last->compile == nil)
658 a38a1836 2006-02-14 devnull sysfatal("unknown %s field: %s", f->pr->name, f->s);
659 87a52e04 2005-12-26 devnull (*last->compile)(f);
660 87a52e04 2005-12-26 devnull break;
661 87a52e04 2005-12-26 devnull default:
662 87a52e04 2005-12-26 devnull sysfatal("internal error: compilewalk op: %d", f->op);
663 87a52e04 2005-12-26 devnull }
664 87a52e04 2005-12-26 devnull }
665 87a52e04 2005-12-26 devnull
666 87a52e04 2005-12-26 devnull Filter*
667 87a52e04 2005-12-26 devnull compile(Filter *f)
668 87a52e04 2005-12-26 devnull {
669 87a52e04 2005-12-26 devnull if(f == nil)
670 87a52e04 2005-12-26 devnull return f;
671 87a52e04 2005-12-26 devnull
672 87a52e04 2005-12-26 devnull /* fill in the missing header filters */
673 87a52e04 2005-12-26 devnull f = complete(f, nil);
674 87a52e04 2005-12-26 devnull
675 87a52e04 2005-12-26 devnull /* constant folding */
676 87a52e04 2005-12-26 devnull f = optimize(f);
677 87a52e04 2005-12-26 devnull if(!toflag)
678 87a52e04 2005-12-26 devnull printfilter(f, "after optimize");
679 87a52e04 2005-12-26 devnull
680 87a52e04 2005-12-26 devnull /* protocol specific compilations */
681 87a52e04 2005-12-26 devnull _compile(f, nil);
682 87a52e04 2005-12-26 devnull
683 87a52e04 2005-12-26 devnull /* at this point, the root had better be the root proto */
684 87a52e04 2005-12-26 devnull if(findbogus(f)){
685 87a52e04 2005-12-26 devnull fprint(2, "bogus filter\n");
686 87a52e04 2005-12-26 devnull exits("bad filter");
687 87a52e04 2005-12-26 devnull }
688 87a52e04 2005-12-26 devnull
689 87a52e04 2005-12-26 devnull return f;
690 87a52e04 2005-12-26 devnull }
691 87a52e04 2005-12-26 devnull
692 87a52e04 2005-12-26 devnull /*
693 87a52e04 2005-12-26 devnull * parse a byte array
694 87a52e04 2005-12-26 devnull */
695 87a52e04 2005-12-26 devnull int
696 87a52e04 2005-12-26 devnull parseba(uchar *to, char *from)
697 87a52e04 2005-12-26 devnull {
698 87a52e04 2005-12-26 devnull char nip[4];
699 87a52e04 2005-12-26 devnull char *p;
700 87a52e04 2005-12-26 devnull int i;
701 87a52e04 2005-12-26 devnull
702 87a52e04 2005-12-26 devnull p = from;
703 87a52e04 2005-12-26 devnull for(i = 0; i < 16; i++){
704 87a52e04 2005-12-26 devnull if(*p == 0)
705 87a52e04 2005-12-26 devnull return -1;
706 87a52e04 2005-12-26 devnull nip[0] = *p++;
707 87a52e04 2005-12-26 devnull if(*p == 0)
708 87a52e04 2005-12-26 devnull return -1;
709 87a52e04 2005-12-26 devnull nip[1] = *p++;
710 87a52e04 2005-12-26 devnull nip[2] = 0;
711 87a52e04 2005-12-26 devnull to[i] = strtoul(nip, 0, 16);
712 87a52e04 2005-12-26 devnull }
713 87a52e04 2005-12-26 devnull return i;
714 87a52e04 2005-12-26 devnull }
715 87a52e04 2005-12-26 devnull
716 87a52e04 2005-12-26 devnull /*
717 87a52e04 2005-12-26 devnull * compile WORD = WORD, becomes a single node with a subop
718 87a52e04 2005-12-26 devnull */
719 87a52e04 2005-12-26 devnull void
720 87a52e04 2005-12-26 devnull compile_cmp(char *proto, Filter *f, Field *fld)
721 87a52e04 2005-12-26 devnull {
722 87a52e04 2005-12-26 devnull uchar x[IPaddrlen];
723 87a52e04 2005-12-26 devnull
724 87a52e04 2005-12-26 devnull if(f->op != '=')
725 87a52e04 2005-12-26 devnull sysfatal("internal error: compile_cmp %s: not a cmp", proto);
726 87a52e04 2005-12-26 devnull
727 87a52e04 2005-12-26 devnull for(; fld->name != nil; fld++){
728 87a52e04 2005-12-26 devnull if(strcmp(f->l->s, fld->name) == 0){
729 87a52e04 2005-12-26 devnull f->op = WORD;
730 87a52e04 2005-12-26 devnull f->subop = fld->subop;
731 87a52e04 2005-12-26 devnull switch(fld->ftype){
732 87a52e04 2005-12-26 devnull case Fnum:
733 87a52e04 2005-12-26 devnull f->ulv = atoi(f->r->s);
734 87a52e04 2005-12-26 devnull break;
735 87a52e04 2005-12-26 devnull case Fether:
736 87a52e04 2005-12-26 devnull parseether(f->a, f->r->s);
737 87a52e04 2005-12-26 devnull break;
738 87a52e04 2005-12-26 devnull case Fv4ip:
739 87a52e04 2005-12-26 devnull f->ulv = parseip(x, f->r->s);
740 87a52e04 2005-12-26 devnull break;
741 87a52e04 2005-12-26 devnull case Fv6ip:
742 87a52e04 2005-12-26 devnull parseip(f->a, f->r->s);
743 87a52e04 2005-12-26 devnull break;
744 87a52e04 2005-12-26 devnull case Fba:
745 87a52e04 2005-12-26 devnull parseba(f->a, f->r->s);
746 87a52e04 2005-12-26 devnull break;
747 87a52e04 2005-12-26 devnull default:
748 87a52e04 2005-12-26 devnull sysfatal("internal error: compile_cmp %s: %d",
749 87a52e04 2005-12-26 devnull proto, fld->ftype);
750 87a52e04 2005-12-26 devnull }
751 87a52e04 2005-12-26 devnull f->l = f->r = nil;
752 87a52e04 2005-12-26 devnull return;
753 87a52e04 2005-12-26 devnull }
754 87a52e04 2005-12-26 devnull }
755 87a52e04 2005-12-26 devnull sysfatal("unknown %s field in: %s = %s", proto, f->l->s, f->r->s);
756 87a52e04 2005-12-26 devnull }
757 87a52e04 2005-12-26 devnull
758 87a52e04 2005-12-26 devnull void
759 87a52e04 2005-12-26 devnull _pf(Filter *f)
760 87a52e04 2005-12-26 devnull {
761 87a52e04 2005-12-26 devnull char *s;
762 87a52e04 2005-12-26 devnull
763 87a52e04 2005-12-26 devnull if(f == nil)
764 87a52e04 2005-12-26 devnull return;
765 87a52e04 2005-12-26 devnull
766 87a52e04 2005-12-26 devnull s = nil;
767 87a52e04 2005-12-26 devnull switch(f->op){
768 87a52e04 2005-12-26 devnull case '!':
769 87a52e04 2005-12-26 devnull fprint(2, "!");
770 87a52e04 2005-12-26 devnull _pf(f->l);
771 87a52e04 2005-12-26 devnull break;
772 87a52e04 2005-12-26 devnull case WORD:
773 87a52e04 2005-12-26 devnull fprint(2, "%s", f->s);
774 87a52e04 2005-12-26 devnull if(f->l != nil){
775 a38a1836 2006-02-14 devnull fprint(2, "(");
776 87a52e04 2005-12-26 devnull _pf(f->l);
777 a38a1836 2006-02-14 devnull fprint(2, ")");
778 87a52e04 2005-12-26 devnull }
779 87a52e04 2005-12-26 devnull break;
780 87a52e04 2005-12-26 devnull case LAND:
781 87a52e04 2005-12-26 devnull s = "&&";
782 87a52e04 2005-12-26 devnull goto print;
783 87a52e04 2005-12-26 devnull case LOR:
784 87a52e04 2005-12-26 devnull s = "||";
785 87a52e04 2005-12-26 devnull goto print;
786 87a52e04 2005-12-26 devnull case '=':
787 87a52e04 2005-12-26 devnull print:
788 87a52e04 2005-12-26 devnull _pf(f->l);
789 87a52e04 2005-12-26 devnull if(s)
790 87a52e04 2005-12-26 devnull fprint(2, " %s ", s);
791 87a52e04 2005-12-26 devnull else
792 87a52e04 2005-12-26 devnull fprint(2, " %c ", f->op);
793 87a52e04 2005-12-26 devnull _pf(f->r);
794 87a52e04 2005-12-26 devnull break;
795 87a52e04 2005-12-26 devnull default:
796 87a52e04 2005-12-26 devnull fprint(2, "???");
797 87a52e04 2005-12-26 devnull break;
798 87a52e04 2005-12-26 devnull }
799 87a52e04 2005-12-26 devnull }
800 87a52e04 2005-12-26 devnull
801 87a52e04 2005-12-26 devnull void
802 87a52e04 2005-12-26 devnull printfilter(Filter *f, char *tag)
803 87a52e04 2005-12-26 devnull {
804 87a52e04 2005-12-26 devnull fprint(2, "%s: ", tag);
805 87a52e04 2005-12-26 devnull _pf(f);
806 87a52e04 2005-12-26 devnull fprint(2, "\n");
807 87a52e04 2005-12-26 devnull }
808 87a52e04 2005-12-26 devnull
809 87a52e04 2005-12-26 devnull void
810 a38a1836 2006-02-14 devnull cat(void)
811 87a52e04 2005-12-26 devnull {
812 a38a1836 2006-02-14 devnull char buf[1024];
813 a38a1836 2006-02-14 devnull int n;
814 a38a1836 2006-02-14 devnull
815 a38a1836 2006-02-14 devnull while((n = read(0, buf, sizeof buf)) > 0)
816 a38a1836 2006-02-14 devnull write(1, buf, n);
817 a38a1836 2006-02-14 devnull }
818 a38a1836 2006-02-14 devnull
819 a38a1836 2006-02-14 devnull static int fd1 = -1;
820 a38a1836 2006-02-14 devnull void
821 a38a1836 2006-02-14 devnull startmc(void)
822 a38a1836 2006-02-14 devnull {
823 a38a1836 2006-02-14 devnull int p[2];
824 a38a1836 2006-02-14 devnull
825 a38a1836 2006-02-14 devnull if(fd1 == -1)
826 a38a1836 2006-02-14 devnull fd1 = dup(1, -1);
827 a38a1836 2006-02-14 devnull
828 a38a1836 2006-02-14 devnull if(pipe(p) < 0)
829 a38a1836 2006-02-14 devnull return;
830 a38a1836 2006-02-14 devnull switch(fork()){
831 a38a1836 2006-02-14 devnull case -1:
832 a38a1836 2006-02-14 devnull return;
833 a38a1836 2006-02-14 devnull default:
834 a38a1836 2006-02-14 devnull close(p[0]);
835 a38a1836 2006-02-14 devnull dup(p[1], 1);
836 a38a1836 2006-02-14 devnull if(p[1] != 1)
837 a38a1836 2006-02-14 devnull close(p[1]);
838 a38a1836 2006-02-14 devnull return;
839 a38a1836 2006-02-14 devnull case 0:
840 a38a1836 2006-02-14 devnull close(p[1]);
841 a38a1836 2006-02-14 devnull dup(p[0], 0);
842 a38a1836 2006-02-14 devnull if(p[0] != 0)
843 a38a1836 2006-02-14 devnull close(p[0]);
844 a38a1836 2006-02-14 devnull execl("/bin/mc", "mc", nil);
845 a38a1836 2006-02-14 devnull cat();
846 a38a1836 2006-02-14 devnull _exits(0);
847 a38a1836 2006-02-14 devnull }
848 a38a1836 2006-02-14 devnull }
849 a38a1836 2006-02-14 devnull
850 a38a1836 2006-02-14 devnull void
851 a38a1836 2006-02-14 devnull stopmc(void)
852 a38a1836 2006-02-14 devnull {
853 a38a1836 2006-02-14 devnull close(1);
854 a38a1836 2006-02-14 devnull dup(fd1, 1);
855 a38a1836 2006-02-14 devnull waitpid();
856 a38a1836 2006-02-14 devnull }
857 a38a1836 2006-02-14 devnull
858 a38a1836 2006-02-14 devnull void
859 a38a1836 2006-02-14 devnull printhelp(char *name)
860 a38a1836 2006-02-14 devnull {
861 a38a1836 2006-02-14 devnull int len;
862 87a52e04 2005-12-26 devnull Proto *pr, **l;
863 87a52e04 2005-12-26 devnull Mux *m;
864 87a52e04 2005-12-26 devnull Field *f;
865 a38a1836 2006-02-14 devnull char fmt[40];
866 a38a1836 2006-02-14 devnull
867 a38a1836 2006-02-14 devnull if(name == nil){
868 a38a1836 2006-02-14 devnull print("protocols:\n");
869 a38a1836 2006-02-14 devnull startmc();
870 a38a1836 2006-02-14 devnull for(l=protos; (pr=*l) != nil; l++)
871 a38a1836 2006-02-14 devnull print(" %s\n", pr->name);
872 a38a1836 2006-02-14 devnull stopmc();
873 a38a1836 2006-02-14 devnull return;
874 87a52e04 2005-12-26 devnull }
875 a38a1836 2006-02-14 devnull
876 a38a1836 2006-02-14 devnull pr = findproto(name);
877 a38a1836 2006-02-14 devnull if(pr == nil){
878 a38a1836 2006-02-14 devnull print("unknown protocol %s\n", name);
879 a38a1836 2006-02-14 devnull return;
880 a38a1836 2006-02-14 devnull }
881 a38a1836 2006-02-14 devnull
882 a38a1836 2006-02-14 devnull if(pr->field){
883 a38a1836 2006-02-14 devnull print("%s's filter attributes:\n", pr->name);
884 a38a1836 2006-02-14 devnull len = 0;
885 a38a1836 2006-02-14 devnull for(f=pr->field; f->name; f++)
886 a38a1836 2006-02-14 devnull if(len < strlen(f->name))
887 a38a1836 2006-02-14 devnull len = strlen(f->name);
888 a38a1836 2006-02-14 devnull startmc();
889 a38a1836 2006-02-14 devnull for(f=pr->field; f->name; f++)
890 a38a1836 2006-02-14 devnull print(" %-*s - %s\n", len, f->name, f->help);
891 a38a1836 2006-02-14 devnull stopmc();
892 a38a1836 2006-02-14 devnull }
893 a38a1836 2006-02-14 devnull if(pr->mux){
894 a38a1836 2006-02-14 devnull print("%s's subprotos:\n", pr->name);
895 a38a1836 2006-02-14 devnull startmc();
896 a38a1836 2006-02-14 devnull snprint(fmt, sizeof fmt, " %s %%s\n", pr->valfmt);
897 a38a1836 2006-02-14 devnull for(m=pr->mux; m->name != nil; m++)
898 a38a1836 2006-02-14 devnull print(fmt, m->val, m->name);
899 a38a1836 2006-02-14 devnull stopmc();
900 a38a1836 2006-02-14 devnull }
901 87a52e04 2005-12-26 devnull }
902 87a52e04 2005-12-26 devnull
903 87a52e04 2005-12-26 devnull /*
904 87a52e04 2005-12-26 devnull * demultiplex to next prototol header
905 87a52e04 2005-12-26 devnull */
906 87a52e04 2005-12-26 devnull void
907 87a52e04 2005-12-26 devnull demux(Mux *mx, ulong val1, ulong val2, Msg *m, Proto *def)
908 87a52e04 2005-12-26 devnull {
909 87a52e04 2005-12-26 devnull m->pr = def;
910 87a52e04 2005-12-26 devnull for(mx = mx; mx->name != nil; mx++){
911 87a52e04 2005-12-26 devnull if(val1 == mx->val || val2 == mx->val){
912 87a52e04 2005-12-26 devnull m->pr = mx->pr;
913 87a52e04 2005-12-26 devnull break;
914 87a52e04 2005-12-26 devnull }
915 87a52e04 2005-12-26 devnull }
916 87a52e04 2005-12-26 devnull }
917 87a52e04 2005-12-26 devnull
918 87a52e04 2005-12-26 devnull /*
919 87a52e04 2005-12-26 devnull * default framer just assumes the input packet is
920 87a52e04 2005-12-26 devnull * a single read
921 87a52e04 2005-12-26 devnull */
922 87a52e04 2005-12-26 devnull int
923 87a52e04 2005-12-26 devnull defaultframer(int fd, uchar *pkt, int pktlen)
924 87a52e04 2005-12-26 devnull {
925 87a52e04 2005-12-26 devnull return read(fd, pkt, pktlen);
926 87a52e04 2005-12-26 devnull }