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