1 /* $OpenBSD: gencode.c,v 1.28 2007/01/02 18:35:17 reyk Exp $ */
2
3 /*
4 * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that: (1) source code distributions
9 * retain the above copyright notice and this paragraph in its entirety, (2)
10 * distributions including binary code include the above copyright notice and
11 * this paragraph in its entirety in the documentation or other materials
12 * provided with the distribution, and (3) all advertising materials mentioning
13 * features or use of this software display the following acknowledgement:
14 * ``This product includes software developed by the University of California,
15 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
16 * the University nor the names of its contributors may be used to endorse
17 * or promote products derived from this software without specific prior
18 * written permission.
19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
20 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22 */
23
24 #include <sys/types.h>
25 #include <sys/socket.h>
26 #include <sys/time.h>
27
28 struct mbuf;
29 struct rtentry;
30
31 #include <net/if.h>
32
33 #include <netinet/in.h>
34 #include <netinet/if_ether.h>
35
36 #include <net/if_pflog.h>
37 #include <net/pfvar.h>
38
39 #include <net80211/ieee80211.h>
40 #include <net80211/ieee80211_radiotap.h>
41
42 #include <stdlib.h>
43 #include <stddef.h>
44 #include <memory.h>
45 #include <setjmp.h>
46 #include <stdarg.h>
47
48 #include "pcap-int.h"
49
50 #include "ethertype.h"
51 #include "llc.h"
52 #include "gencode.h"
53 #include "ppp.h"
54 #include <pcap-namedb.h>
55 #ifdef INET6
56 #include <netdb.h>
57 #include <sys/socket.h>
58 #endif /*INET6*/
59
60 #ifdef HAVE_OS_PROTO_H
61 #include "os-proto.h"
62 #endif
63
64 __RCSID("$MirOS: src/lib/libpcap/gencode.c,v 1.4 2007/03/09 13:05:08 tg Exp $");
65
66 #define JMP(c) ((c)|BPF_JMP|BPF_K)
67
68 /* Locals */
69 static jmp_buf top_ctx;
70 static pcap_t *bpf_pcap;
71
72 /* XXX */
73 #ifdef PCAP_FDDIPAD
74 int pcap_fddipad = PCAP_FDDIPAD;
75 #else
76 int pcap_fddipad;
77 #endif
78
79 /* VARARGS */
80 __dead void
bpf_error(const char * fmt,...)81 bpf_error(const char *fmt, ...)
82 {
83 va_list ap;
84
85 va_start(ap, fmt);
86 if (bpf_pcap != NULL)
87 (void)vsnprintf(pcap_geterr(bpf_pcap), PCAP_ERRBUF_SIZE,
88 fmt, ap);
89 va_end(ap);
90 longjmp(top_ctx, 1);
91 /* NOTREACHED */
92 }
93
94 static void init_linktype(int);
95
96 static int alloc_reg(void);
97 static void free_reg(int);
98
99 static struct block *root;
100
101 /*
102 * We divy out chunks of memory rather than call malloc each time so
103 * we don't have to worry about leaking memory. It's probably
104 * not a big deal if all this memory was wasted but it this ever
105 * goes into a library that would probably not be a good idea.
106 */
107 #define NCHUNKS 16
108 #define CHUNK0SIZE 1024
109 struct chunk {
110 u_int n_left;
111 void *m;
112 };
113
114 static struct chunk chunks[NCHUNKS];
115 static int cur_chunk;
116
117 static void *newchunk(u_int);
118 static void freechunks(void);
119 static __inline struct block *new_block(int);
120 static __inline struct slist *new_stmt(int);
121 static struct block *gen_retblk(int);
122 static __inline void syntax(void);
123
124 static void backpatch(struct block *, struct block *);
125 static void merge(struct block *, struct block *);
126 static struct block *gen_cmp(u_int, u_int, bpf_int32);
127 static struct block *gen_cmp_gt(u_int, u_int, bpf_int32);
128 static struct block *gen_mcmp(u_int, u_int, bpf_int32, bpf_u_int32);
129 static struct block *gen_bcmp(u_int, u_int, const u_char *);
130 static struct block *gen_uncond(int);
131 static __inline struct block *gen_true(void);
132 static __inline struct block *gen_false(void);
133 static struct block *gen_linktype(int);
134 static struct block *gen_hostop(bpf_u_int32, bpf_u_int32, int, int, u_int, u_int);
135 #ifdef INET6
136 static struct block *gen_hostop6(struct in6_addr *, struct in6_addr *, int, int, u_int, u_int);
137 #endif
138 static struct block *gen_ehostop(const u_char *, int);
139 static struct block *gen_fhostop(const u_char *, int);
140 static struct block *gen_dnhostop(bpf_u_int32, int, u_int);
141 static struct block *gen_p80211_hostop(const u_char *, int);
142 static struct block *gen_p80211_addr(int, u_int, const u_char *);
143 static struct block *gen_host(bpf_u_int32, bpf_u_int32, int, int);
144 #ifdef INET6
145 static struct block *gen_host6(struct in6_addr *, struct in6_addr *, int, int);
146 #endif
147 #ifndef INET6
148 static struct block *gen_gateway(const u_char *, bpf_u_int32 **, int, int);
149 #endif
150 static struct block *gen_ipfrag(void);
151 static struct block *gen_portatom(int, bpf_int32);
152 #ifdef INET6
153 static struct block *gen_portatom6(int, bpf_int32);
154 #endif
155 struct block *gen_portop(int, int, int);
156 static struct block *gen_port(int, int, int);
157 #ifdef INET6
158 struct block *gen_portop6(int, int, int);
159 static struct block *gen_port6(int, int, int);
160 #endif
161 static int lookup_proto(const char *, int);
162 static struct block *gen_protochain(int, int, int);
163 static struct block *gen_proto(int, int, int);
164 static struct slist *xfer_to_x(struct arth *);
165 static struct slist *xfer_to_a(struct arth *);
166 static struct block *gen_len(int, int);
167
168 static void *
newchunk(n)169 newchunk(n)
170 u_int n;
171 {
172 struct chunk *cp;
173 int k, size;
174
175 /* XXX Round to structure boundary. */
176 n = ALIGN(n);
177
178 cp = &chunks[cur_chunk];
179 if (n > cp->n_left) {
180 ++cp, k = ++cur_chunk;
181 if (k >= NCHUNKS)
182 bpf_error("out of memory");
183 size = CHUNK0SIZE << k;
184 cp->m = (void *)malloc(size);
185 if (cp->m == NULL)
186 bpf_error("out of memory");
187
188 memset((char *)cp->m, 0, size);
189 cp->n_left = size;
190 if (n > size)
191 bpf_error("out of memory");
192 }
193 cp->n_left -= n;
194 return (void *)((char *)cp->m + cp->n_left);
195 }
196
197 static void
freechunks()198 freechunks()
199 {
200 int i;
201
202 cur_chunk = 0;
203 for (i = 0; i < NCHUNKS; ++i)
204 if (chunks[i].m != NULL) {
205 free(chunks[i].m);
206 chunks[i].m = NULL;
207 }
208 }
209
210 /*
211 * A strdup whose allocations are freed after code generation is over.
212 */
213 char *
sdup(s)214 sdup(s)
215 register const char *s;
216 {
217 int n = strlen(s) + 1;
218 char *cp = newchunk(n);
219
220 strlcpy(cp, s, n);
221 return (cp);
222 }
223
224 static __inline struct block *
new_block(code)225 new_block(code)
226 int code;
227 {
228 struct block *p;
229
230 p = (struct block *)newchunk(sizeof(*p));
231 p->s.code = code;
232 p->head = p;
233
234 return p;
235 }
236
237 static __inline struct slist *
new_stmt(code)238 new_stmt(code)
239 int code;
240 {
241 struct slist *p;
242
243 p = (struct slist *)newchunk(sizeof(*p));
244 p->s.code = code;
245
246 return p;
247 }
248
249 static struct block *
gen_retblk(v)250 gen_retblk(v)
251 int v;
252 {
253 struct block *b = new_block(BPF_RET|BPF_K);
254
255 b->s.k = v;
256 return b;
257 }
258
259 static __inline void
syntax()260 syntax()
261 {
262 bpf_error("syntax error in filter expression");
263 }
264
265 static bpf_u_int32 netmask;
266 static int snaplen;
267 int no_optimize;
268
269 int
pcap_compile(pcap_t * p,struct bpf_program * program,char * buf,int optimize,bpf_u_int32 mask)270 pcap_compile(pcap_t *p, struct bpf_program *program,
271 char *buf, int optimize, bpf_u_int32 mask)
272 {
273 extern int n_errors;
274 int len;
275
276 no_optimize = 0;
277 n_errors = 0;
278 root = NULL;
279 bpf_pcap = p;
280 if (setjmp(top_ctx)) {
281 freechunks();
282 return (-1);
283 }
284
285 netmask = mask;
286 snaplen = pcap_snapshot(p);
287
288 lex_init(buf ? buf : "");
289 init_linktype(pcap_datalink(p));
290 (void)pcap_parse();
291
292 if (n_errors)
293 syntax();
294
295 if (root == NULL)
296 root = gen_retblk(snaplen);
297
298 if (optimize && !no_optimize) {
299 bpf_optimize(&root);
300 if (root == NULL ||
301 (root->s.code == (BPF_RET|BPF_K) && root->s.k == 0))
302 bpf_error("expression rejects all packets");
303 }
304 program->bf_insns = icode_to_fcode(root, &len);
305 program->bf_len = len;
306
307 freechunks();
308 return (0);
309 }
310
311 /*
312 * entry point for using the compiler with no pcap open
313 * pass in all the stuff that is needed explicitly instead.
314 */
315 int
pcap_compile_nopcap(int snaplen_arg,int linktype_arg,struct bpf_program * program,char * buf,int optimize,bpf_u_int32 mask)316 pcap_compile_nopcap(int snaplen_arg, int linktype_arg,
317 struct bpf_program *program,
318 char *buf, int optimize, bpf_u_int32 mask)
319 {
320 extern int n_errors;
321 int len;
322
323 n_errors = 0;
324 root = NULL;
325 bpf_pcap = NULL;
326 if (setjmp(top_ctx)) {
327 freechunks();
328 return (-1);
329 }
330
331 netmask = mask;
332
333 /* XXX needed? I don't grok the use of globals here. */
334 snaplen = snaplen_arg;
335
336 lex_init(buf ? buf : "");
337 init_linktype(linktype_arg);
338 (void)pcap_parse();
339
340 if (n_errors)
341 syntax();
342
343 if (root == NULL)
344 root = gen_retblk(snaplen_arg);
345
346 if (optimize) {
347 bpf_optimize(&root);
348 if (root == NULL ||
349 (root->s.code == (BPF_RET|BPF_K) && root->s.k == 0))
350 bpf_error("expression rejects all packets");
351 }
352 program->bf_insns = icode_to_fcode(root, &len);
353 program->bf_len = len;
354
355 freechunks();
356 return (0);
357 }
358
359 /*
360 * Clean up a "struct bpf_program" by freeing all the memory allocated
361 * in it.
362 */
363 void
pcap_freecode(struct bpf_program * program)364 pcap_freecode(struct bpf_program *program)
365 {
366 program->bf_len = 0;
367 if (program->bf_insns != NULL) {
368 free((char *)program->bf_insns);
369 program->bf_insns = NULL;
370 }
371 }
372
373 /*
374 * Backpatch the blocks in 'list' to 'target'. The 'sense' field indicates
375 * which of the jt and jf fields has been resolved and which is a pointer
376 * back to another unresolved block (or nil). At least one of the fields
377 * in each block is already resolved.
378 */
379 static void
backpatch(list,target)380 backpatch(list, target)
381 struct block *list, *target;
382 {
383 struct block *next;
384
385 while (list) {
386 if (!list->sense) {
387 next = JT(list);
388 JT(list) = target;
389 } else {
390 next = JF(list);
391 JF(list) = target;
392 }
393 list = next;
394 }
395 }
396
397 /*
398 * Merge the lists in b0 and b1, using the 'sense' field to indicate
399 * which of jt and jf is the link.
400 */
401 static void
merge(b0,b1)402 merge(b0, b1)
403 struct block *b0, *b1;
404 {
405 register struct block **p = &b0;
406
407 /* Find end of list. */
408 while (*p)
409 p = !((*p)->sense) ? &JT(*p) : &JF(*p);
410
411 /* Concatenate the lists. */
412 *p = b1;
413 }
414
415 void
finish_parse(p)416 finish_parse(p)
417 struct block *p;
418 {
419 backpatch(p, gen_retblk(snaplen));
420 p->sense = !p->sense;
421 backpatch(p, gen_retblk(0));
422 root = p->head;
423 }
424
425 void
gen_and(b0,b1)426 gen_and(b0, b1)
427 struct block *b0, *b1;
428 {
429 backpatch(b0, b1->head);
430 b0->sense = !b0->sense;
431 b1->sense = !b1->sense;
432 merge(b1, b0);
433 b1->sense = !b1->sense;
434 b1->head = b0->head;
435 }
436
437 void
gen_or(b0,b1)438 gen_or(b0, b1)
439 struct block *b0, *b1;
440 {
441 b0->sense = !b0->sense;
442 backpatch(b0, b1->head);
443 b0->sense = !b0->sense;
444 merge(b1, b0);
445 b1->head = b0->head;
446 }
447
448 void
gen_not(b)449 gen_not(b)
450 struct block *b;
451 {
452 b->sense = !b->sense;
453 }
454
455 static struct block *
gen_cmp(offset,size,v)456 gen_cmp(offset, size, v)
457 u_int offset, size;
458 bpf_int32 v;
459 {
460 struct slist *s;
461 struct block *b;
462
463 s = new_stmt(BPF_LD|BPF_ABS|size);
464 s->s.k = offset;
465
466 b = new_block(JMP(BPF_JEQ));
467 b->stmts = s;
468 b->s.k = v;
469
470 return b;
471 }
472
473 static struct block *
gen_cmp_gt(offset,size,v)474 gen_cmp_gt(offset, size, v)
475 u_int offset, size;
476 bpf_int32 v;
477 {
478 struct slist *s;
479 struct block *b;
480
481 s = new_stmt(BPF_LD|BPF_ABS|size);
482 s->s.k = offset;
483
484 b = new_block(JMP(BPF_JGT));
485 b->stmts = s;
486 b->s.k = v;
487
488 return b;
489 }
490
491 static struct block *
gen_mcmp(offset,size,v,mask)492 gen_mcmp(offset, size, v, mask)
493 u_int offset, size;
494 bpf_int32 v;
495 bpf_u_int32 mask;
496 {
497 struct block *b = gen_cmp(offset, size, v);
498 struct slist *s;
499
500 if (mask != 0xffffffff) {
501 s = new_stmt(BPF_ALU|BPF_AND|BPF_K);
502 s->s.k = mask;
503 b->stmts->next = s;
504 }
505 return b;
506 }
507
508 static struct block *
gen_bcmp(offset,size,v)509 gen_bcmp(offset, size, v)
510 register u_int offset, size;
511 register const u_char *v;
512 {
513 register struct block *b, *tmp;
514
515 b = NULL;
516 while (size >= 4) {
517 register const u_char *p = &v[size - 4];
518 bpf_int32 w = ((bpf_int32)p[0] << 24) |
519 ((bpf_int32)p[1] << 16) | ((bpf_int32)p[2] << 8) | p[3];
520
521 tmp = gen_cmp(offset + size - 4, BPF_W, w);
522 if (b != NULL)
523 gen_and(b, tmp);
524 b = tmp;
525 size -= 4;
526 }
527 while (size >= 2) {
528 register const u_char *p = &v[size - 2];
529 bpf_int32 w = ((bpf_int32)p[0] << 8) | p[1];
530
531 tmp = gen_cmp(offset + size - 2, BPF_H, w);
532 if (b != NULL)
533 gen_and(b, tmp);
534 b = tmp;
535 size -= 2;
536 }
537 if (size > 0) {
538 tmp = gen_cmp(offset, BPF_B, (bpf_int32)v[0]);
539 if (b != NULL)
540 gen_and(b, tmp);
541 b = tmp;
542 }
543 return b;
544 }
545
546 /*
547 * Various code constructs need to know the layout of the data link
548 * layer. These variables give the necessary offsets. off_linktype
549 * is set to -1 for no encapsulation, in which case, IP is assumed.
550 */
551 static u_int off_linktype;
552 static u_int off_nl;
553 static int linktype;
554
555 static void
init_linktype(type)556 init_linktype(type)
557 int type;
558 {
559 linktype = type;
560
561 switch (type) {
562
563 case DLT_EN10MB:
564 off_linktype = 12;
565 off_nl = 14;
566 return;
567
568 case DLT_SLIP:
569 /*
570 * SLIP doesn't have a link level type. The 16 byte
571 * header is hacked into our SLIP driver.
572 */
573 off_linktype = -1;
574 off_nl = 16;
575 return;
576
577 case DLT_SLIP_BSDOS:
578 /* XXX this may be the same as the DLT_PPP_BSDOS case */
579 off_linktype = -1;
580 /* XXX end */
581 off_nl = 24;
582 return;
583
584 case DLT_NULL:
585 off_linktype = 0;
586 off_nl = 4;
587 return;
588
589 case DLT_PPP:
590 off_linktype = 2;
591 off_nl = 4;
592 return;
593
594 case DLT_PPP_ETHER:
595 /*
596 * This does not include the Ethernet header, and
597 * only covers session state.
598 */
599 off_linktype = 6;
600 off_nl = 8;
601 return;
602
603 case DLT_PPP_BSDOS:
604 off_linktype = 5;
605 off_nl = 24;
606 return;
607
608 case DLT_FDDI:
609 /*
610 * FDDI doesn't really have a link-level type field.
611 * We assume that SSAP = SNAP is being used and pick
612 * out the encapsulated Ethernet type.
613 */
614 off_linktype = 19;
615 #ifdef PCAP_FDDIPAD
616 off_linktype += pcap_fddipad;
617 #endif
618 off_nl = 21;
619 #ifdef PCAP_FDDIPAD
620 off_nl += pcap_fddipad;
621 #endif
622 return;
623
624 case DLT_IEEE802:
625 off_linktype = 20;
626 off_nl = 22;
627 return;
628
629 case DLT_IEEE802_11:
630 off_linktype = 30; /* XXX variable */
631 off_nl = 32;
632 return;
633
634 case DLT_IEEE802_11_RADIO: /* XXX variable */
635 off_linktype = 30 + IEEE80211_RADIOTAP_HDRLEN;
636 off_nl = 32 + IEEE80211_RADIOTAP_HDRLEN;
637 return;
638
639 case DLT_ATM_RFC1483:
640 /*
641 * assume routed, non-ISO PDUs
642 * (i.e., LLC = 0xAA-AA-03, OUT = 0x00-00-00)
643 */
644 off_linktype = 6;
645 off_nl = 8;
646 return;
647
648 case DLT_LOOP:
649 off_linktype = -1;
650 off_nl = 4;
651 return;
652
653 case DLT_ENC:
654 off_linktype = -1;
655 off_nl = 12;
656 return;
657
658 case DLT_OLD_PFLOG:
659 off_linktype = 0;
660 off_nl = 28;
661 return;
662
663 case DLT_PFLOG:
664 off_linktype = 0;
665 /* XXX read from header? */
666 off_nl = PFLOG_HDRLEN;
667 return;
668
669 case DLT_PFSYNC:
670 off_linktype = -1;
671 off_nl = 4;
672 return;
673
674 case DLT_RAW:
675 off_linktype = -1;
676 off_nl = 0;
677 return;
678 }
679 bpf_error("unknown data link type 0x%x", linktype);
680 /* NOTREACHED */
681 }
682
683 static struct block *
gen_uncond(rsense)684 gen_uncond(rsense)
685 int rsense;
686 {
687 struct block *b;
688 struct slist *s;
689
690 s = new_stmt(BPF_LD|BPF_IMM);
691 s->s.k = !rsense;
692 b = new_block(JMP(BPF_JEQ));
693 b->stmts = s;
694
695 return b;
696 }
697
698 static __inline struct block *
gen_true()699 gen_true()
700 {
701 return gen_uncond(1);
702 }
703
704 static __inline struct block *
gen_false()705 gen_false()
706 {
707 return gen_uncond(0);
708 }
709
710 static struct block *
gen_linktype(proto)711 gen_linktype(proto)
712 register int proto;
713 {
714 struct block *b0, *b1;
715
716 /* If we're not using encapsulation and checking for IP, we're done */
717 if (off_linktype == -1 && proto == ETHERTYPE_IP)
718 return gen_true();
719 #ifdef INET6
720 /* this isn't the right thing to do, but sometimes necessary */
721 if (off_linktype == -1 && proto == ETHERTYPE_IPV6)
722 return gen_true();
723 #endif
724
725 switch (linktype) {
726
727 case DLT_EN10MB:
728 if (proto <= ETHERMTU) {
729 /* This is an LLC SAP value */
730 b0 = gen_cmp_gt(off_linktype, BPF_H, ETHERMTU);
731 gen_not(b0);
732 b1 = gen_cmp(off_linktype + 2, BPF_B, (bpf_int32)proto);
733 gen_and(b0, b1);
734 return b1;
735 } else {
736 /* This is an Ethernet type */
737 return gen_cmp(off_linktype, BPF_H, (bpf_int32)proto);
738 }
739 break;
740
741 case DLT_SLIP:
742 return gen_false();
743
744 case DLT_PPP:
745 case DLT_PPP_ETHER:
746 if (proto == ETHERTYPE_IP)
747 proto = PPP_IP; /* XXX was 0x21 */
748 #ifdef INET6
749 else if (proto == ETHERTYPE_IPV6)
750 proto = PPP_IPV6;
751 #endif
752 break;
753
754 case DLT_PPP_BSDOS:
755 switch (proto) {
756
757 case ETHERTYPE_IP:
758 b0 = gen_cmp(off_linktype, BPF_H, PPP_IP);
759 b1 = gen_cmp(off_linktype, BPF_H, PPP_VJC);
760 gen_or(b0, b1);
761 b0 = gen_cmp(off_linktype, BPF_H, PPP_VJNC);
762 gen_or(b1, b0);
763 return b0;
764
765 #ifdef INET6
766 case ETHERTYPE_IPV6:
767 proto = PPP_IPV6;
768 /* more to go? */
769 break;
770 #endif /* INET6 */
771
772 case ETHERTYPE_DN:
773 proto = PPP_DECNET;
774 break;
775
776 case ETHERTYPE_ATALK:
777 proto = PPP_APPLE;
778 break;
779
780 case ETHERTYPE_NS:
781 proto = PPP_NS;
782 break;
783 }
784 break;
785
786 case DLT_LOOP:
787 case DLT_ENC:
788 case DLT_NULL:
789 /* XXX */
790 if (proto == ETHERTYPE_IP)
791 return (gen_cmp(0, BPF_W, (bpf_int32)htonl(AF_INET)));
792 #ifdef INET6
793 else if (proto == ETHERTYPE_IPV6)
794 return (gen_cmp(0, BPF_W, (bpf_int32)htonl(AF_INET6)));
795 #endif /* INET6 */
796 else
797 return gen_false();
798 break;
799 case DLT_OLD_PFLOG:
800 if (proto == ETHERTYPE_IP)
801 return (gen_cmp(0, BPF_W, (bpf_int32)AF_INET));
802 #ifdef INET6
803 else if (proto == ETHERTYPE_IPV6)
804 return (gen_cmp(0, BPF_W, (bpf_int32)AF_INET6));
805 #endif /* INET6 */
806 else
807 return gen_false();
808 break;
809
810 case DLT_PFLOG:
811 if (proto == ETHERTYPE_IP)
812 return (gen_cmp(offsetof(struct pfloghdr, af), BPF_B,
813 (bpf_int32)AF_INET));
814 #ifdef INET6
815 else if (proto == ETHERTYPE_IPV6)
816 return (gen_cmp(offsetof(struct pfloghdr, af), BPF_B,
817 (bpf_int32)AF_INET6));
818 #endif /* INET6 */
819 else
820 return gen_false();
821 break;
822
823 }
824 return gen_cmp(off_linktype, BPF_H, (bpf_int32)proto);
825 }
826
827 static struct block *
gen_hostop(addr,mask,dir,proto,src_off,dst_off)828 gen_hostop(addr, mask, dir, proto, src_off, dst_off)
829 bpf_u_int32 addr;
830 bpf_u_int32 mask;
831 int dir, proto;
832 u_int src_off, dst_off;
833 {
834 struct block *b0, *b1;
835 u_int offset;
836
837 switch (dir) {
838
839 case Q_SRC:
840 offset = src_off;
841 break;
842
843 case Q_DST:
844 offset = dst_off;
845 break;
846
847 case Q_AND:
848 b0 = gen_hostop(addr, mask, Q_SRC, proto, src_off, dst_off);
849 b1 = gen_hostop(addr, mask, Q_DST, proto, src_off, dst_off);
850 gen_and(b0, b1);
851 return b1;
852
853 case Q_OR:
854 case Q_DEFAULT:
855 b0 = gen_hostop(addr, mask, Q_SRC, proto, src_off, dst_off);
856 b1 = gen_hostop(addr, mask, Q_DST, proto, src_off, dst_off);
857 gen_or(b0, b1);
858 return b1;
859
860 default:
861 bpf_error("direction not supported on linktype 0x%x",
862 linktype);
863 }
864 b0 = gen_linktype(proto);
865 b1 = gen_mcmp(offset, BPF_W, (bpf_int32)addr, mask);
866 gen_and(b0, b1);
867 return b1;
868 }
869
870 #ifdef INET6
871 static struct block *
gen_hostop6(addr,mask,dir,proto,src_off,dst_off)872 gen_hostop6(addr, mask, dir, proto, src_off, dst_off)
873 struct in6_addr *addr;
874 struct in6_addr *mask;
875 int dir, proto;
876 u_int src_off, dst_off;
877 {
878 struct block *b0, *b1;
879 u_int offset;
880 u_int32_t *a, *m;
881
882 switch (dir) {
883
884 case Q_SRC:
885 offset = src_off;
886 break;
887
888 case Q_DST:
889 offset = dst_off;
890 break;
891
892 case Q_AND:
893 b0 = gen_hostop6(addr, mask, Q_SRC, proto, src_off, dst_off);
894 b1 = gen_hostop6(addr, mask, Q_DST, proto, src_off, dst_off);
895 gen_and(b0, b1);
896 return b1;
897
898 case Q_OR:
899 case Q_DEFAULT:
900 b0 = gen_hostop6(addr, mask, Q_SRC, proto, src_off, dst_off);
901 b1 = gen_hostop6(addr, mask, Q_DST, proto, src_off, dst_off);
902 gen_or(b0, b1);
903 return b1;
904
905 default:
906 bpf_error("direction not supported on linktype 0x%x",
907 linktype);
908 }
909 /* this order is important */
910 a = (u_int32_t *)addr;
911 m = (u_int32_t *)mask;
912 b1 = gen_mcmp(offset + 12, BPF_W, ntohl(a[3]), ntohl(m[3]));
913 b0 = gen_mcmp(offset + 8, BPF_W, ntohl(a[2]), ntohl(m[2]));
914 gen_and(b0, b1);
915 b0 = gen_mcmp(offset + 4, BPF_W, ntohl(a[1]), ntohl(m[1]));
916 gen_and(b0, b1);
917 b0 = gen_mcmp(offset + 0, BPF_W, ntohl(a[0]), ntohl(m[0]));
918 gen_and(b0, b1);
919 b0 = gen_linktype(proto);
920 gen_and(b0, b1);
921 return b1;
922 }
923 #endif /*INET6*/
924
925 static struct block *
gen_ehostop(eaddr,dir)926 gen_ehostop(eaddr, dir)
927 register const u_char *eaddr;
928 register int dir;
929 {
930 struct block *b0, *b1;
931
932 switch (dir) {
933 case Q_SRC:
934 return gen_bcmp(6, 6, eaddr);
935
936 case Q_DST:
937 return gen_bcmp(0, 6, eaddr);
938
939 case Q_AND:
940 b0 = gen_ehostop(eaddr, Q_SRC);
941 b1 = gen_ehostop(eaddr, Q_DST);
942 gen_and(b0, b1);
943 return b1;
944
945 case Q_DEFAULT:
946 case Q_OR:
947 b0 = gen_ehostop(eaddr, Q_SRC);
948 b1 = gen_ehostop(eaddr, Q_DST);
949 gen_or(b0, b1);
950 return b1;
951 default:
952 bpf_error("direction not supported on linktype 0x%x",
953 linktype);
954 }
955 /* NOTREACHED */
956 }
957
958 /*
959 * Like gen_ehostop, but for DLT_FDDI
960 */
961 static struct block *
gen_fhostop(eaddr,dir)962 gen_fhostop(eaddr, dir)
963 register const u_char *eaddr;
964 register int dir;
965 {
966 struct block *b0, *b1;
967
968 switch (dir) {
969 case Q_SRC:
970 #ifdef PCAP_FDDIPAD
971 return gen_bcmp(6 + 1 + pcap_fddipad, 6, eaddr);
972 #else
973 return gen_bcmp(6 + 1, 6, eaddr);
974 #endif
975
976 case Q_DST:
977 #ifdef PCAP_FDDIPAD
978 return gen_bcmp(0 + 1 + pcap_fddipad, 6, eaddr);
979 #else
980 return gen_bcmp(0 + 1, 6, eaddr);
981 #endif
982
983 case Q_AND:
984 b0 = gen_fhostop(eaddr, Q_SRC);
985 b1 = gen_fhostop(eaddr, Q_DST);
986 gen_and(b0, b1);
987 return b1;
988
989 case Q_DEFAULT:
990 case Q_OR:
991 b0 = gen_fhostop(eaddr, Q_SRC);
992 b1 = gen_fhostop(eaddr, Q_DST);
993 gen_or(b0, b1);
994 return b1;
995 default:
996 bpf_error("direction not supported on linktype 0x%x",
997 linktype);
998 }
999 /* NOTREACHED */
1000 }
1001
1002 /*
1003 * This is quite tricky because there may be pad bytes in front of the
1004 * DECNET header, and then there are two possible data packet formats that
1005 * carry both src and dst addresses, plus 5 packet types in a format that
1006 * carries only the src node, plus 2 types that use a different format and
1007 * also carry just the src node.
1008 *
1009 * Yuck.
1010 *
1011 * Instead of doing those all right, we just look for data packets with
1012 * 0 or 1 bytes of padding. If you want to look at other packets, that
1013 * will require a lot more hacking.
1014 *
1015 * To add support for filtering on DECNET "areas" (network numbers)
1016 * one would want to add a "mask" argument to this routine. That would
1017 * make the filter even more inefficient, although one could be clever
1018 * and not generate masking instructions if the mask is 0xFFFF.
1019 */
1020 static struct block *
gen_dnhostop(addr,dir,base_off)1021 gen_dnhostop(addr, dir, base_off)
1022 bpf_u_int32 addr;
1023 int dir;
1024 u_int base_off;
1025 {
1026 struct block *b0, *b1, *b2, *tmp;
1027 u_int offset_lh; /* offset if long header is received */
1028 u_int offset_sh; /* offset if short header is received */
1029
1030 switch (dir) {
1031
1032 case Q_DST:
1033 offset_sh = 1; /* follows flags */
1034 offset_lh = 7; /* flgs,darea,dsubarea,HIORD */
1035 break;
1036
1037 case Q_SRC:
1038 offset_sh = 3; /* follows flags, dstnode */
1039 offset_lh = 15; /* flgs,darea,dsubarea,did,sarea,ssub,HIORD */
1040 break;
1041
1042 case Q_AND:
1043 /* Inefficient because we do our Calvinball dance twice */
1044 b0 = gen_dnhostop(addr, Q_SRC, base_off);
1045 b1 = gen_dnhostop(addr, Q_DST, base_off);
1046 gen_and(b0, b1);
1047 return b1;
1048
1049 case Q_OR:
1050 case Q_DEFAULT:
1051 /* Inefficient because we do our Calvinball dance twice */
1052 b0 = gen_dnhostop(addr, Q_SRC, base_off);
1053 b1 = gen_dnhostop(addr, Q_DST, base_off);
1054 gen_or(b0, b1);
1055 return b1;
1056
1057 default:
1058 bpf_error("direction not supported on linktype 0x%x",
1059 linktype);
1060 }
1061 b0 = gen_linktype(ETHERTYPE_DN);
1062 /* Check for pad = 1, long header case */
1063 tmp = gen_mcmp(base_off + 2, BPF_H,
1064 (bpf_int32)ntohs(0x0681), (bpf_int32)ntohs(0x07FF));
1065 b1 = gen_cmp(base_off + 2 + 1 + offset_lh,
1066 BPF_H, (bpf_int32)ntohs(addr));
1067 gen_and(tmp, b1);
1068 /* Check for pad = 0, long header case */
1069 tmp = gen_mcmp(base_off + 2, BPF_B, (bpf_int32)0x06, (bpf_int32)0x7);
1070 b2 = gen_cmp(base_off + 2 + offset_lh, BPF_H, (bpf_int32)ntohs(addr));
1071 gen_and(tmp, b2);
1072 gen_or(b2, b1);
1073 /* Check for pad = 1, short header case */
1074 tmp = gen_mcmp(base_off + 2, BPF_H,
1075 (bpf_int32)ntohs(0x0281), (bpf_int32)ntohs(0x07FF));
1076 b2 = gen_cmp(base_off + 2 + 1 + offset_sh,
1077 BPF_H, (bpf_int32)ntohs(addr));
1078 gen_and(tmp, b2);
1079 gen_or(b2, b1);
1080 /* Check for pad = 0, short header case */
1081 tmp = gen_mcmp(base_off + 2, BPF_B, (bpf_int32)0x02, (bpf_int32)0x7);
1082 b2 = gen_cmp(base_off + 2 + offset_sh, BPF_H, (bpf_int32)ntohs(addr));
1083 gen_and(tmp, b2);
1084 gen_or(b2, b1);
1085
1086 /* Combine with test for linktype */
1087 gen_and(b0, b1);
1088 return b1;
1089 }
1090
1091 static struct block *
gen_host(addr,mask,proto,dir)1092 gen_host(addr, mask, proto, dir)
1093 bpf_u_int32 addr;
1094 bpf_u_int32 mask;
1095 int proto;
1096 int dir;
1097 {
1098 struct block *b0, *b1;
1099
1100 switch (proto) {
1101
1102 case Q_DEFAULT:
1103 b0 = gen_host(addr, mask, Q_IP, dir);
1104 b1 = gen_host(addr, mask, Q_ARP, dir);
1105 gen_or(b0, b1);
1106 b0 = gen_host(addr, mask, Q_RARP, dir);
1107 gen_or(b1, b0);
1108 return b0;
1109
1110 case Q_IP:
1111 return gen_hostop(addr, mask, dir, ETHERTYPE_IP,
1112 off_nl + 12, off_nl + 16);
1113
1114 case Q_RARP:
1115 return gen_hostop(addr, mask, dir, ETHERTYPE_REVARP,
1116 off_nl + 14, off_nl + 24);
1117
1118 case Q_ARP:
1119 return gen_hostop(addr, mask, dir, ETHERTYPE_ARP,
1120 off_nl + 14, off_nl + 24);
1121
1122 case Q_TCP:
1123 bpf_error("'tcp' modifier applied to host");
1124
1125 case Q_UDP:
1126 bpf_error("'udp' modifier applied to host");
1127
1128 case Q_ICMP:
1129 bpf_error("'icmp' modifier applied to host");
1130
1131 case Q_IGMP:
1132 bpf_error("'igmp' modifier applied to host");
1133
1134 case Q_IGRP:
1135 bpf_error("'igrp' modifier applied to host");
1136
1137 case Q_PIM:
1138 bpf_error("'pim' modifier applied to host");
1139
1140 case Q_STP:
1141 bpf_error("'stp' modifier applied to host");
1142
1143 case Q_ATALK:
1144 bpf_error("ATALK host filtering not implemented");
1145
1146 case Q_DECNET:
1147 return gen_dnhostop(addr, dir, off_nl);
1148
1149 case Q_SCA:
1150 bpf_error("SCA host filtering not implemented");
1151
1152 case Q_LAT:
1153 bpf_error("LAT host filtering not implemented");
1154
1155 case Q_MOPDL:
1156 bpf_error("MOPDL host filtering not implemented");
1157
1158 case Q_MOPRC:
1159 bpf_error("MOPRC host filtering not implemented");
1160
1161 #ifdef INET6
1162 case Q_IPV6:
1163 bpf_error("'ip6' modifier applied to ip host");
1164
1165 case Q_ICMPV6:
1166 bpf_error("'icmp6' modifier applied to host");
1167 #endif /* INET6 */
1168
1169 case Q_AH:
1170 bpf_error("'ah' modifier applied to host");
1171
1172 case Q_ESP:
1173 bpf_error("'esp' modifier applied to host");
1174
1175 default:
1176 bpf_error("direction not supported on linktype 0x%x",
1177 linktype);
1178 }
1179 /* NOTREACHED */
1180 }
1181
1182 #ifdef INET6
1183 static struct block *
gen_host6(addr,mask,proto,dir)1184 gen_host6(addr, mask, proto, dir)
1185 struct in6_addr *addr;
1186 struct in6_addr *mask;
1187 int proto;
1188 int dir;
1189 {
1190 switch (proto) {
1191
1192 case Q_DEFAULT:
1193 return gen_host6(addr, mask, Q_IPV6, dir);
1194
1195 case Q_IP:
1196 bpf_error("'ip' modifier applied to ip6 host");
1197
1198 case Q_RARP:
1199 bpf_error("'rarp' modifier applied to ip6 host");
1200
1201 case Q_ARP:
1202 bpf_error("'arp' modifier applied to ip6 host");
1203
1204 case Q_TCP:
1205 bpf_error("'tcp' modifier applied to host");
1206
1207 case Q_UDP:
1208 bpf_error("'udp' modifier applied to host");
1209
1210 case Q_ICMP:
1211 bpf_error("'icmp' modifier applied to host");
1212
1213 case Q_IGMP:
1214 bpf_error("'igmp' modifier applied to host");
1215
1216 case Q_IGRP:
1217 bpf_error("'igrp' modifier applied to host");
1218
1219 case Q_PIM:
1220 bpf_error("'pim' modifier applied to host");
1221
1222 case Q_STP:
1223 bpf_error("'stp' modifier applied to host");
1224
1225 case Q_ATALK:
1226 bpf_error("ATALK host filtering not implemented");
1227
1228 case Q_DECNET:
1229 bpf_error("'decnet' modifier applied to ip6 host");
1230
1231 case Q_SCA:
1232 bpf_error("SCA host filtering not implemented");
1233
1234 case Q_LAT:
1235 bpf_error("LAT host filtering not implemented");
1236
1237 case Q_MOPDL:
1238 bpf_error("MOPDL host filtering not implemented");
1239
1240 case Q_MOPRC:
1241 bpf_error("MOPRC host filtering not implemented");
1242
1243 case Q_IPV6:
1244 return gen_hostop6(addr, mask, dir, ETHERTYPE_IPV6,
1245 off_nl + 8, off_nl + 24);
1246
1247 case Q_ICMPV6:
1248 bpf_error("'icmp6' modifier applied to host");
1249
1250 case Q_AH:
1251 bpf_error("'ah' modifier applied to host");
1252
1253 case Q_ESP:
1254 bpf_error("'esp' modifier applied to host");
1255
1256 default:
1257 abort();
1258 }
1259 /* NOTREACHED */
1260 }
1261 #endif /*INET6*/
1262
1263 #ifndef INET6
1264 static struct block *
gen_gateway(eaddr,alist,proto,dir)1265 gen_gateway(eaddr, alist, proto, dir)
1266 const u_char *eaddr;
1267 bpf_u_int32 **alist;
1268 int proto;
1269 int dir;
1270 {
1271 struct block *b0, *b1, *tmp;
1272
1273 if (dir != 0)
1274 bpf_error("direction applied to 'gateway'");
1275
1276 switch (proto) {
1277 case Q_DEFAULT:
1278 case Q_IP:
1279 case Q_ARP:
1280 case Q_RARP:
1281 if (linktype == DLT_EN10MB)
1282 b0 = gen_ehostop(eaddr, Q_OR);
1283 else if (linktype == DLT_FDDI)
1284 b0 = gen_fhostop(eaddr, Q_OR);
1285 else
1286 bpf_error(
1287 "'gateway' supported only on ethernet or FDDI");
1288
1289 b1 = gen_host(**alist++, 0xffffffff, proto, Q_OR);
1290 while (*alist) {
1291 tmp = gen_host(**alist++, 0xffffffff, proto, Q_OR);
1292 gen_or(b1, tmp);
1293 b1 = tmp;
1294 }
1295 gen_not(b1);
1296 gen_and(b0, b1);
1297 return b1;
1298 }
1299 bpf_error("illegal modifier of 'gateway'");
1300 /* NOTREACHED */
1301 }
1302 #endif /*INET6*/
1303
1304 struct block *
gen_proto_abbrev(proto)1305 gen_proto_abbrev(proto)
1306 int proto;
1307 {
1308 struct block *b0 = NULL, *b1;
1309
1310 switch (proto) {
1311
1312 case Q_TCP:
1313 b1 = gen_proto(IPPROTO_TCP, Q_IP, Q_DEFAULT);
1314 #ifdef INET6
1315 b0 = gen_proto(IPPROTO_TCP, Q_IPV6, Q_DEFAULT);
1316 gen_or(b0, b1);
1317 #endif
1318 break;
1319
1320 case Q_UDP:
1321 b1 = gen_proto(IPPROTO_UDP, Q_IP, Q_DEFAULT);
1322 #ifdef INET6
1323 b0 = gen_proto(IPPROTO_UDP, Q_IPV6, Q_DEFAULT);
1324 gen_or(b0, b1);
1325 #endif
1326 break;
1327
1328 case Q_ICMP:
1329 b1 = gen_proto(IPPROTO_ICMP, Q_IP, Q_DEFAULT);
1330 break;
1331
1332 #ifndef IPPROTO_IGMP
1333 #define IPPROTO_IGMP 2
1334 #endif
1335
1336 case Q_IGMP:
1337 b1 = gen_proto(IPPROTO_IGMP, Q_IP, Q_DEFAULT);
1338 break;
1339
1340 #ifndef IPPROTO_IGRP
1341 #define IPPROTO_IGRP 9
1342 #endif
1343 case Q_IGRP:
1344 b1 = gen_proto(IPPROTO_IGRP, Q_IP, Q_DEFAULT);
1345 break;
1346
1347 #ifndef IPPROTO_PIM
1348 #define IPPROTO_PIM 103
1349 #endif
1350
1351 case Q_PIM:
1352 b1 = gen_proto(IPPROTO_PIM, Q_IP, Q_DEFAULT);
1353 #ifdef INET6
1354 b0 = gen_proto(IPPROTO_PIM, Q_IPV6, Q_DEFAULT);
1355 gen_or(b0, b1);
1356 #endif
1357 break;
1358
1359 case Q_IP:
1360 b1 = gen_linktype(ETHERTYPE_IP);
1361 break;
1362
1363 case Q_ARP:
1364 b1 = gen_linktype(ETHERTYPE_ARP);
1365 break;
1366
1367 case Q_RARP:
1368 b1 = gen_linktype(ETHERTYPE_REVARP);
1369 break;
1370
1371 case Q_LINK:
1372 bpf_error("link layer applied in wrong context");
1373
1374 case Q_ATALK:
1375 b1 = gen_linktype(ETHERTYPE_ATALK);
1376 break;
1377
1378 case Q_DECNET:
1379 b1 = gen_linktype(ETHERTYPE_DN);
1380 break;
1381
1382 case Q_SCA:
1383 b1 = gen_linktype(ETHERTYPE_SCA);
1384 break;
1385
1386 case Q_LAT:
1387 b1 = gen_linktype(ETHERTYPE_LAT);
1388 break;
1389
1390 case Q_MOPDL:
1391 b1 = gen_linktype(ETHERTYPE_MOPDL);
1392 break;
1393
1394 case Q_MOPRC:
1395 b1 = gen_linktype(ETHERTYPE_MOPRC);
1396 break;
1397
1398 case Q_STP:
1399 b1 = gen_linktype(LLCSAP_8021D);
1400 break;
1401
1402 #ifdef INET6
1403 case Q_IPV6:
1404 b1 = gen_linktype(ETHERTYPE_IPV6);
1405 break;
1406
1407 #ifndef IPPROTO_ICMPV6
1408 #define IPPROTO_ICMPV6 58
1409 #endif
1410 case Q_ICMPV6:
1411 b1 = gen_proto(IPPROTO_ICMPV6, Q_IPV6, Q_DEFAULT);
1412 break;
1413 #endif /* INET6 */
1414
1415 #ifndef IPPROTO_AH
1416 #define IPPROTO_AH 51
1417 #endif
1418 case Q_AH:
1419 b1 = gen_proto(IPPROTO_AH, Q_IP, Q_DEFAULT);
1420 #ifdef INET6
1421 b0 = gen_proto(IPPROTO_AH, Q_IPV6, Q_DEFAULT);
1422 gen_or(b0, b1);
1423 #endif
1424 break;
1425
1426 #ifndef IPPROTO_ESP
1427 #define IPPROTO_ESP 50
1428 #endif
1429 case Q_ESP:
1430 b1 = gen_proto(IPPROTO_ESP, Q_IP, Q_DEFAULT);
1431 #ifdef INET6
1432 b0 = gen_proto(IPPROTO_ESP, Q_IPV6, Q_DEFAULT);
1433 gen_or(b0, b1);
1434 #endif
1435 break;
1436
1437 default:
1438 abort();
1439 }
1440 return b1;
1441 }
1442
1443 static struct block *
gen_ipfrag()1444 gen_ipfrag()
1445 {
1446 struct slist *s;
1447 struct block *b;
1448
1449 /* not ip frag */
1450 s = new_stmt(BPF_LD|BPF_H|BPF_ABS);
1451 s->s.k = off_nl + 6;
1452 b = new_block(JMP(BPF_JSET));
1453 b->s.k = 0x1fff;
1454 b->stmts = s;
1455 gen_not(b);
1456
1457 return b;
1458 }
1459
1460 static struct block *
gen_portatom(off,v)1461 gen_portatom(off, v)
1462 int off;
1463 bpf_int32 v;
1464 {
1465 struct slist *s;
1466 struct block *b;
1467
1468 s = new_stmt(BPF_LDX|BPF_MSH|BPF_B);
1469 s->s.k = off_nl;
1470
1471 s->next = new_stmt(BPF_LD|BPF_IND|BPF_H);
1472 s->next->s.k = off_nl + off;
1473
1474 b = new_block(JMP(BPF_JEQ));
1475 b->stmts = s;
1476 b->s.k = v;
1477
1478 return b;
1479 }
1480
1481 #ifdef INET6
1482 static struct block *
gen_portatom6(off,v)1483 gen_portatom6(off, v)
1484 int off;
1485 bpf_int32 v;
1486 {
1487 return gen_cmp(off_nl + 40 + off, BPF_H, v);
1488 }
1489 #endif/*INET6*/
1490
1491 struct block *
gen_portop(port,proto,dir)1492 gen_portop(port, proto, dir)
1493 int port, proto, dir;
1494 {
1495 struct block *b0, *b1, *tmp;
1496
1497 /* ip proto 'proto' */
1498 tmp = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)proto);
1499 b0 = gen_ipfrag();
1500 gen_and(tmp, b0);
1501
1502 switch (dir) {
1503 case Q_SRC:
1504 b1 = gen_portatom(0, (bpf_int32)port);
1505 break;
1506
1507 case Q_DST:
1508 b1 = gen_portatom(2, (bpf_int32)port);
1509 break;
1510
1511 case Q_OR:
1512 case Q_DEFAULT:
1513 tmp = gen_portatom(0, (bpf_int32)port);
1514 b1 = gen_portatom(2, (bpf_int32)port);
1515 gen_or(tmp, b1);
1516 break;
1517
1518 case Q_AND:
1519 tmp = gen_portatom(0, (bpf_int32)port);
1520 b1 = gen_portatom(2, (bpf_int32)port);
1521 gen_and(tmp, b1);
1522 break;
1523
1524 default:
1525 abort();
1526 }
1527 gen_and(b0, b1);
1528
1529 return b1;
1530 }
1531
1532 static struct block *
gen_port(port,ip_proto,dir)1533 gen_port(port, ip_proto, dir)
1534 int port;
1535 int ip_proto;
1536 int dir;
1537 {
1538 struct block *b0, *b1, *tmp;
1539
1540 /* ether proto ip */
1541 b0 = gen_linktype(ETHERTYPE_IP);
1542
1543 switch (ip_proto) {
1544 case IPPROTO_UDP:
1545 case IPPROTO_TCP:
1546 b1 = gen_portop(port, ip_proto, dir);
1547 break;
1548
1549 case PROTO_UNDEF:
1550 tmp = gen_portop(port, IPPROTO_TCP, dir);
1551 b1 = gen_portop(port, IPPROTO_UDP, dir);
1552 gen_or(tmp, b1);
1553 break;
1554
1555 default:
1556 abort();
1557 }
1558 gen_and(b0, b1);
1559 return b1;
1560 }
1561
1562 #ifdef INET6
1563 struct block *
gen_portop6(port,proto,dir)1564 gen_portop6(port, proto, dir)
1565 int port, proto, dir;
1566 {
1567 struct block *b0, *b1, *tmp;
1568
1569 /* ip proto 'proto' */
1570 b0 = gen_cmp(off_nl + 6, BPF_B, (bpf_int32)proto);
1571
1572 switch (dir) {
1573 case Q_SRC:
1574 b1 = gen_portatom6(0, (bpf_int32)port);
1575 break;
1576
1577 case Q_DST:
1578 b1 = gen_portatom6(2, (bpf_int32)port);
1579 break;
1580
1581 case Q_OR:
1582 case Q_DEFAULT:
1583 tmp = gen_portatom6(0, (bpf_int32)port);
1584 b1 = gen_portatom6(2, (bpf_int32)port);
1585 gen_or(tmp, b1);
1586 break;
1587
1588 case Q_AND:
1589 tmp = gen_portatom6(0, (bpf_int32)port);
1590 b1 = gen_portatom6(2, (bpf_int32)port);
1591 gen_and(tmp, b1);
1592 break;
1593
1594 default:
1595 abort();
1596 }
1597 gen_and(b0, b1);
1598
1599 return b1;
1600 }
1601
1602 static struct block *
gen_port6(port,ip_proto,dir)1603 gen_port6(port, ip_proto, dir)
1604 int port;
1605 int ip_proto;
1606 int dir;
1607 {
1608 struct block *b0, *b1, *tmp;
1609
1610 /* ether proto ip */
1611 b0 = gen_linktype(ETHERTYPE_IPV6);
1612
1613 switch (ip_proto) {
1614 case IPPROTO_UDP:
1615 case IPPROTO_TCP:
1616 b1 = gen_portop6(port, ip_proto, dir);
1617 break;
1618
1619 case PROTO_UNDEF:
1620 tmp = gen_portop6(port, IPPROTO_TCP, dir);
1621 b1 = gen_portop6(port, IPPROTO_UDP, dir);
1622 gen_or(tmp, b1);
1623 break;
1624
1625 default:
1626 abort();
1627 }
1628 gen_and(b0, b1);
1629 return b1;
1630 }
1631 #endif /* INET6 */
1632
1633 static int
lookup_proto(name,proto)1634 lookup_proto(name, proto)
1635 register const char *name;
1636 register int proto;
1637 {
1638 register int v;
1639
1640 switch (proto) {
1641
1642 case Q_DEFAULT:
1643 case Q_IP:
1644 v = pcap_nametoproto(name);
1645 if (v == PROTO_UNDEF)
1646 bpf_error("unknown ip proto '%s'", name);
1647 break;
1648
1649 case Q_LINK:
1650 /* XXX should look up h/w protocol type based on linktype */
1651 v = pcap_nametoeproto(name);
1652 if (v == PROTO_UNDEF) {
1653 v = pcap_nametollc(name);
1654 if (v == PROTO_UNDEF)
1655 bpf_error("unknown ether proto '%s'", name);
1656 }
1657 break;
1658
1659 default:
1660 v = PROTO_UNDEF;
1661 break;
1662 }
1663 return v;
1664 }
1665
1666 static struct block *
gen_protochain(v,proto,dir)1667 gen_protochain(v, proto, dir)
1668 int v;
1669 int proto;
1670 int dir;
1671 {
1672 struct block *b0, *b;
1673 struct slist *s[100];
1674 int fix2, fix3, fix4, fix5;
1675 int ahcheck, again, end;
1676 int i, max;
1677 int reg1 = alloc_reg();
1678 int reg2 = alloc_reg();
1679
1680 memset(s, 0, sizeof(s));
1681 fix2 = fix3 = fix4 = fix5 = 0;
1682
1683 switch (proto) {
1684 case Q_IP:
1685 case Q_IPV6:
1686 break;
1687 case Q_DEFAULT:
1688 b0 = gen_protochain(v, Q_IP, dir);
1689 b = gen_protochain(v, Q_IPV6, dir);
1690 gen_or(b0, b);
1691 return b;
1692 default:
1693 bpf_error("bad protocol applied for 'protochain'");
1694 /*NOTREACHED*/
1695 }
1696
1697 no_optimize = 1; /*this code is not compatible with optimzer yet */
1698
1699 /*
1700 * s[0] is a dummy entry to protect other BPF insn from damaged
1701 * by s[fix] = foo with uninitialized variable "fix". It is somewhat
1702 * hard to find interdependency made by jump table fixup.
1703 */
1704 i = 0;
1705 s[i] = new_stmt(0); /*dummy*/
1706 i++;
1707
1708 switch (proto) {
1709 case Q_IP:
1710 b0 = gen_linktype(ETHERTYPE_IP);
1711
1712 /* A = ip->ip_p */
1713 s[i] = new_stmt(BPF_LD|BPF_ABS|BPF_B);
1714 s[i]->s.k = off_nl + 9;
1715 i++;
1716 /* X = ip->ip_hl << 2 */
1717 s[i] = new_stmt(BPF_LDX|BPF_MSH|BPF_B);
1718 s[i]->s.k = off_nl;
1719 i++;
1720 break;
1721 case Q_IPV6:
1722 b0 = gen_linktype(ETHERTYPE_IPV6);
1723
1724 /* A = ip6->ip_nxt */
1725 s[i] = new_stmt(BPF_LD|BPF_ABS|BPF_B);
1726 s[i]->s.k = off_nl + 6;
1727 i++;
1728 /* X = sizeof(struct ip6_hdr) */
1729 s[i] = new_stmt(BPF_LDX|BPF_IMM);
1730 s[i]->s.k = 40;
1731 i++;
1732 break;
1733 default:
1734 bpf_error("unsupported proto to gen_protochain");
1735 /*NOTREACHED*/
1736 }
1737
1738 /* again: if (A == v) goto end; else fall through; */
1739 again = i;
1740 s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K);
1741 s[i]->s.k = v;
1742 s[i]->s.jt = NULL; /*later*/
1743 s[i]->s.jf = NULL; /*update in next stmt*/
1744 fix5 = i;
1745 i++;
1746
1747 /* if (A == IPPROTO_NONE) goto end */
1748 s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K);
1749 s[i]->s.jt = NULL; /*later*/
1750 s[i]->s.jf = NULL; /*update in next stmt*/
1751 s[i]->s.k = IPPROTO_NONE;
1752 s[fix5]->s.jf = s[i];
1753 fix2 = i;
1754 i++;
1755
1756 if (proto == Q_IPV6) {
1757 int v6start, v6end, v6advance, j;
1758
1759 v6start = i;
1760 /* if (A == IPPROTO_HOPOPTS) goto v6advance */
1761 s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K);
1762 s[i]->s.jt = NULL; /*later*/
1763 s[i]->s.jf = NULL; /*update in next stmt*/
1764 s[i]->s.k = IPPROTO_HOPOPTS;
1765 s[fix2]->s.jf = s[i];
1766 i++;
1767 /* if (A == IPPROTO_DSTOPTS) goto v6advance */
1768 s[i - 1]->s.jf = s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K);
1769 s[i]->s.jt = NULL; /*later*/
1770 s[i]->s.jf = NULL; /*update in next stmt*/
1771 s[i]->s.k = IPPROTO_DSTOPTS;
1772 i++;
1773 /* if (A == IPPROTO_ROUTING) goto v6advance */
1774 s[i - 1]->s.jf = s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K);
1775 s[i]->s.jt = NULL; /*later*/
1776 s[i]->s.jf = NULL; /*update in next stmt*/
1777 s[i]->s.k = IPPROTO_ROUTING;
1778 i++;
1779 /* if (A == IPPROTO_FRAGMENT) goto v6advance; else goto ahcheck; */
1780 s[i - 1]->s.jf = s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K);
1781 s[i]->s.jt = NULL; /*later*/
1782 s[i]->s.jf = NULL; /*later*/
1783 s[i]->s.k = IPPROTO_FRAGMENT;
1784 fix3 = i;
1785 v6end = i;
1786 i++;
1787
1788 /* v6advance: */
1789 v6advance = i;
1790
1791 /*
1792 * in short,
1793 * A = P[X + 1];
1794 * X = X + (P[X] + 1) * 8;
1795 */
1796 /* A = X */
1797 s[i] = new_stmt(BPF_MISC|BPF_TXA);
1798 i++;
1799 /* MEM[reg1] = A */
1800 s[i] = new_stmt(BPF_ST);
1801 s[i]->s.k = reg1;
1802 i++;
1803 /* A += 1 */
1804 s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
1805 s[i]->s.k = 1;
1806 i++;
1807 /* X = A */
1808 s[i] = new_stmt(BPF_MISC|BPF_TAX);
1809 i++;
1810 /* A = P[X + packet head]; */
1811 s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B);
1812 s[i]->s.k = off_nl;
1813 i++;
1814 /* MEM[reg2] = A */
1815 s[i] = new_stmt(BPF_ST);
1816 s[i]->s.k = reg2;
1817 i++;
1818 /* X = MEM[reg1] */
1819 s[i] = new_stmt(BPF_LDX|BPF_MEM);
1820 s[i]->s.k = reg1;
1821 i++;
1822 /* A = P[X + packet head] */
1823 s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B);
1824 s[i]->s.k = off_nl;
1825 i++;
1826 /* A += 1 */
1827 s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
1828 s[i]->s.k = 1;
1829 i++;
1830 /* A *= 8 */
1831 s[i] = new_stmt(BPF_ALU|BPF_MUL|BPF_K);
1832 s[i]->s.k = 8;
1833 i++;
1834 /* X = A; */
1835 s[i] = new_stmt(BPF_MISC|BPF_TAX);
1836 i++;
1837 /* A = MEM[reg2] */
1838 s[i] = new_stmt(BPF_LD|BPF_MEM);
1839 s[i]->s.k = reg2;
1840 i++;
1841
1842 /* goto again; (must use BPF_JA for backward jump) */
1843 s[i] = new_stmt(BPF_JMP|BPF_JA);
1844 s[i]->s.k = again - i - 1;
1845 s[i - 1]->s.jf = s[i];
1846 i++;
1847
1848 /* fixup */
1849 for (j = v6start; j <= v6end; j++)
1850 s[j]->s.jt = s[v6advance];
1851 } else {
1852 /* nop */
1853 s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
1854 s[i]->s.k = 0;
1855 s[fix2]->s.jf = s[i];
1856 i++;
1857 }
1858
1859 /* ahcheck: */
1860 ahcheck = i;
1861 /* if (A == IPPROTO_AH) then fall through; else goto end; */
1862 s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K);
1863 s[i]->s.jt = NULL; /*later*/
1864 s[i]->s.jf = NULL; /*later*/
1865 s[i]->s.k = IPPROTO_AH;
1866 if (fix3)
1867 s[fix3]->s.jf = s[ahcheck];
1868 fix4 = i;
1869 i++;
1870
1871 /*
1872 * in short,
1873 * A = P[X + 1];
1874 * X = X + (P[X] + 2) * 4;
1875 */
1876 /* A = X */
1877 s[i - 1]->s.jt = s[i] = new_stmt(BPF_MISC|BPF_TXA);
1878 i++;
1879 /* MEM[reg1] = A */
1880 s[i] = new_stmt(BPF_ST);
1881 s[i]->s.k = reg1;
1882 i++;
1883 /* A += 1 */
1884 s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
1885 s[i]->s.k = 1;
1886 i++;
1887 /* X = A */
1888 s[i] = new_stmt(BPF_MISC|BPF_TAX);
1889 i++;
1890 /* A = P[X + packet head]; */
1891 s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B);
1892 s[i]->s.k = off_nl;
1893 i++;
1894 /* MEM[reg2] = A */
1895 s[i] = new_stmt(BPF_ST);
1896 s[i]->s.k = reg2;
1897 i++;
1898 /* X = MEM[reg1] */
1899 s[i] = new_stmt(BPF_LDX|BPF_MEM);
1900 s[i]->s.k = reg1;
1901 i++;
1902 /* A = P[X + packet head] */
1903 s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B);
1904 s[i]->s.k = off_nl;
1905 i++;
1906 /* A += 2 */
1907 s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
1908 s[i]->s.k = 2;
1909 i++;
1910 /* A *= 4 */
1911 s[i] = new_stmt(BPF_ALU|BPF_MUL|BPF_K);
1912 s[i]->s.k = 4;
1913 i++;
1914 /* X = A; */
1915 s[i] = new_stmt(BPF_MISC|BPF_TAX);
1916 i++;
1917 /* A = MEM[reg2] */
1918 s[i] = new_stmt(BPF_LD|BPF_MEM);
1919 s[i]->s.k = reg2;
1920 i++;
1921
1922 /* goto again; (must use BPF_JA for backward jump) */
1923 s[i] = new_stmt(BPF_JMP|BPF_JA);
1924 s[i]->s.k = again - i - 1;
1925 i++;
1926
1927 /* end: nop */
1928 end = i;
1929 s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
1930 s[i]->s.k = 0;
1931 s[fix2]->s.jt = s[end];
1932 s[fix4]->s.jf = s[end];
1933 s[fix5]->s.jt = s[end];
1934 i++;
1935
1936 /*
1937 * make slist chain
1938 */
1939 max = i;
1940 for (i = 0; i < max - 1; i++)
1941 s[i]->next = s[i + 1];
1942 s[max - 1]->next = NULL;
1943
1944 /*
1945 * emit final check
1946 */
1947 b = new_block(JMP(BPF_JEQ));
1948 b->stmts = s[1]; /*remember, s[0] is dummy*/
1949 b->s.k = v;
1950
1951 free_reg(reg1);
1952 free_reg(reg2);
1953
1954 gen_and(b0, b);
1955 return b;
1956 }
1957
1958 static struct block *
gen_proto(v,proto,dir)1959 gen_proto(v, proto, dir)
1960 int v;
1961 int proto;
1962 int dir;
1963 {
1964 struct block *b0, *b1;
1965
1966 if (dir != Q_DEFAULT)
1967 bpf_error("direction applied to 'proto'");
1968
1969 switch (proto) {
1970 case Q_DEFAULT:
1971 #ifdef INET6
1972 b0 = gen_proto(v, Q_IP, dir);
1973 b1 = gen_proto(v, Q_IPV6, dir);
1974 gen_or(b0, b1);
1975 return b1;
1976 #else
1977 /*FALLTHROUGH*/
1978 #endif
1979 case Q_IP:
1980 b0 = gen_linktype(ETHERTYPE_IP);
1981 #ifndef CHASE_CHAIN
1982 b1 = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)v);
1983 #else
1984 b1 = gen_protochain(v, Q_IP);
1985 #endif
1986 gen_and(b0, b1);
1987 return b1;
1988
1989 case Q_ARP:
1990 bpf_error("arp does not encapsulate another protocol");
1991 /* NOTREACHED */
1992
1993 case Q_RARP:
1994 bpf_error("rarp does not encapsulate another protocol");
1995 /* NOTREACHED */
1996
1997 case Q_ATALK:
1998 bpf_error("atalk encapsulation is not specifiable");
1999 /* NOTREACHED */
2000
2001 case Q_DECNET:
2002 bpf_error("decnet encapsulation is not specifiable");
2003 /* NOTREACHED */
2004
2005 case Q_SCA:
2006 bpf_error("sca does not encapsulate another protocol");
2007 /* NOTREACHED */
2008
2009 case Q_LAT:
2010 bpf_error("lat does not encapsulate another protocol");
2011 /* NOTREACHED */
2012
2013 case Q_MOPRC:
2014 bpf_error("moprc does not encapsulate another protocol");
2015 /* NOTREACHED */
2016
2017 case Q_MOPDL:
2018 bpf_error("mopdl does not encapsulate another protocol");
2019 /* NOTREACHED */
2020
2021 case Q_LINK:
2022 return gen_linktype(v);
2023
2024 case Q_UDP:
2025 bpf_error("'udp proto' is bogus");
2026 /* NOTREACHED */
2027
2028 case Q_TCP:
2029 bpf_error("'tcp proto' is bogus");
2030 /* NOTREACHED */
2031
2032 case Q_ICMP:
2033 bpf_error("'icmp proto' is bogus");
2034 /* NOTREACHED */
2035
2036 case Q_IGMP:
2037 bpf_error("'igmp proto' is bogus");
2038 /* NOTREACHED */
2039
2040 case Q_IGRP:
2041 bpf_error("'igrp proto' is bogus");
2042 /* NOTREACHED */
2043
2044 case Q_PIM:
2045 bpf_error("'pim proto' is bogus");
2046 /* NOTREACHED */
2047
2048 case Q_STP:
2049 bpf_error("'stp proto' is bogus");
2050 /* NOTREACHED */
2051
2052 #ifdef INET6
2053 case Q_IPV6:
2054 b0 = gen_linktype(ETHERTYPE_IPV6);
2055 #ifndef CHASE_CHAIN
2056 b1 = gen_cmp(off_nl + 6, BPF_B, (bpf_int32)v);
2057 #else
2058 b1 = gen_protochain(v, Q_IPV6);
2059 #endif
2060 gen_and(b0, b1);
2061 return b1;
2062
2063 case Q_ICMPV6:
2064 bpf_error("'icmp6 proto' is bogus");
2065 #endif /* INET6 */
2066
2067 case Q_AH:
2068 bpf_error("'ah proto' is bogus");
2069
2070 case Q_ESP:
2071 bpf_error("'ah proto' is bogus");
2072
2073 default:
2074 abort();
2075 /* NOTREACHED */
2076 }
2077 /* NOTREACHED */
2078 }
2079
2080 struct block *
gen_scode(name,q)2081 gen_scode(name, q)
2082 register const char *name;
2083 struct qual q;
2084 {
2085 int proto = q.proto;
2086 int dir = q.dir;
2087 int tproto;
2088 u_char *eaddr;
2089 bpf_u_int32 mask, addr;
2090 #ifndef INET6
2091 bpf_u_int32 **alist;
2092 #else
2093 int tproto6;
2094 struct sockaddr_in *sin;
2095 struct sockaddr_in6 *sin6;
2096 struct addrinfo *res, *res0;
2097 struct in6_addr mask128;
2098 #endif /*INET6*/
2099 struct block *b, *tmp;
2100 int port, real_proto;
2101
2102 switch (q.addr) {
2103
2104 case Q_NET:
2105 addr = pcap_nametonetaddr(name);
2106 if (addr == 0)
2107 bpf_error("unknown network '%s'", name);
2108 /* Left justify network addr and calculate its network mask */
2109 mask = 0xffffffff;
2110 while (addr && (addr & 0xff000000) == 0) {
2111 addr <<= 8;
2112 mask <<= 8;
2113 }
2114 return gen_host(addr, mask, proto, dir);
2115
2116 case Q_DEFAULT:
2117 case Q_HOST:
2118 if (proto == Q_LINK) {
2119 switch (linktype) {
2120
2121 case DLT_EN10MB:
2122 eaddr = pcap_ether_hostton(name);
2123 if (eaddr == NULL)
2124 bpf_error(
2125 "unknown ether host '%s'", name);
2126 return gen_ehostop(eaddr, dir);
2127
2128 case DLT_FDDI:
2129 eaddr = pcap_ether_hostton(name);
2130 if (eaddr == NULL)
2131 bpf_error(
2132 "unknown FDDI host '%s'", name);
2133 return gen_fhostop(eaddr, dir);
2134
2135 case DLT_IEEE802_11:
2136 case DLT_IEEE802_11_RADIO:
2137 eaddr = pcap_ether_hostton(name);
2138 if (eaddr == NULL)
2139 bpf_error(
2140 "unknown 802.11 host '%s'", name);
2141
2142 return gen_p80211_hostop(eaddr, dir);
2143
2144 default:
2145 bpf_error(
2146 "only ethernet/FDDI supports link-level host name");
2147 break;
2148 }
2149 } else if (proto == Q_DECNET) {
2150 unsigned short dn_addr = __pcap_nametodnaddr(name);
2151 /*
2152 * I don't think DECNET hosts can be multihomed, so
2153 * there is no need to build up a list of addresses
2154 */
2155 return (gen_host(dn_addr, 0, proto, dir));
2156 } else {
2157 #ifndef INET6
2158 alist = pcap_nametoaddr(name);
2159 if (alist == NULL || *alist == NULL)
2160 bpf_error("unknown host '%s'", name);
2161 tproto = proto;
2162 if (off_linktype == -1 && tproto == Q_DEFAULT)
2163 tproto = Q_IP;
2164 b = gen_host(**alist++, 0xffffffff, tproto, dir);
2165 while (*alist) {
2166 tmp = gen_host(**alist++, 0xffffffff,
2167 tproto, dir);
2168 gen_or(b, tmp);
2169 b = tmp;
2170 }
2171 return b;
2172 #else
2173 memset(&mask128, 0xff, sizeof(mask128));
2174 res0 = res = pcap_nametoaddrinfo(name);
2175 if (res == NULL)
2176 bpf_error("unknown host '%s'", name);
2177 b = tmp = NULL;
2178 tproto = tproto6 = proto;
2179 if (off_linktype == -1 && tproto == Q_DEFAULT) {
2180 tproto = Q_IP;
2181 tproto6 = Q_IPV6;
2182 }
2183 for (res = res0; res; res = res->ai_next) {
2184 switch (res->ai_family) {
2185 case AF_INET:
2186 if (tproto == Q_IPV6)
2187 continue;
2188
2189 sin = (struct sockaddr_in *)
2190 res->ai_addr;
2191 tmp = gen_host(ntohl(sin->sin_addr.s_addr),
2192 0xffffffff, tproto, dir);
2193 break;
2194 case AF_INET6:
2195 if (tproto6 == Q_IP)
2196 continue;
2197
2198 sin6 = (struct sockaddr_in6 *)
2199 res->ai_addr;
2200 tmp = gen_host6(&sin6->sin6_addr,
2201 &mask128, tproto6, dir);
2202 break;
2203 }
2204 if (b)
2205 gen_or(b, tmp);
2206 b = tmp;
2207 }
2208 freeaddrinfo(res0);
2209 if (b == NULL) {
2210 bpf_error("unknown host '%s'%s", name,
2211 (proto == Q_DEFAULT)
2212 ? ""
2213 : " for specified address family");
2214 }
2215 return b;
2216 #endif /*INET6*/
2217 }
2218
2219 case Q_PORT:
2220 if (proto != Q_DEFAULT && proto != Q_UDP && proto != Q_TCP)
2221 bpf_error("illegal qualifier of 'port'");
2222 if (pcap_nametoport(name, &port, &real_proto) == 0)
2223 bpf_error("unknown port '%s'", name);
2224 if (proto == Q_UDP) {
2225 if (real_proto == IPPROTO_TCP)
2226 bpf_error("port '%s' is tcp", name);
2227 else
2228 /* override PROTO_UNDEF */
2229 real_proto = IPPROTO_UDP;
2230 }
2231 if (proto == Q_TCP) {
2232 if (real_proto == IPPROTO_UDP)
2233 bpf_error("port '%s' is udp", name);
2234 else
2235 /* override PROTO_UNDEF */
2236 real_proto = IPPROTO_TCP;
2237 }
2238 #ifndef INET6
2239 return gen_port(port, real_proto, dir);
2240 #else
2241 {
2242 struct block *b;
2243 b = gen_port(port, real_proto, dir);
2244 gen_or(gen_port6(port, real_proto, dir), b);
2245 return b;
2246 }
2247 #endif /* INET6 */
2248
2249 case Q_GATEWAY:
2250 #ifndef INET6
2251 eaddr = pcap_ether_hostton(name);
2252 if (eaddr == NULL)
2253 bpf_error("unknown ether host: %s", name);
2254
2255 alist = pcap_nametoaddr(name);
2256 if (alist == NULL || *alist == NULL)
2257 bpf_error("unknown host '%s'", name);
2258 return gen_gateway(eaddr, alist, proto, dir);
2259 #else
2260 bpf_error("'gateway' not supported in this configuration");
2261 #endif /*INET6*/
2262
2263 case Q_PROTO:
2264 real_proto = lookup_proto(name, proto);
2265 if (real_proto >= 0)
2266 return gen_proto(real_proto, proto, dir);
2267 else
2268 bpf_error("unknown protocol: %s", name);
2269
2270 case Q_PROTOCHAIN:
2271 real_proto = lookup_proto(name, proto);
2272 if (real_proto >= 0)
2273 return gen_protochain(real_proto, proto, dir);
2274 else
2275 bpf_error("unknown protocol: %s", name);
2276
2277
2278 case Q_UNDEF:
2279 syntax();
2280 /* NOTREACHED */
2281 }
2282 abort();
2283 /* NOTREACHED */
2284 }
2285
2286 struct block *
gen_mcode(s1,s2,masklen,q)2287 gen_mcode(s1, s2, masklen, q)
2288 register const char *s1, *s2;
2289 register int masklen;
2290 struct qual q;
2291 {
2292 register int nlen, mlen;
2293 bpf_u_int32 n, m;
2294
2295 nlen = __pcap_atoin(s1, &n);
2296 /* Promote short ipaddr */
2297 n <<= 32 - nlen;
2298
2299 if (s2 != NULL) {
2300 mlen = __pcap_atoin(s2, &m);
2301 /* Promote short ipaddr */
2302 m <<= 32 - mlen;
2303 if ((n & ~m) != 0)
2304 bpf_error("non-network bits set in \"%s mask %s\"",
2305 s1, s2);
2306 } else {
2307 /* Convert mask len to mask */
2308 if (masklen > 32)
2309 bpf_error("mask length must be <= 32");
2310 m = 0xffffffff << (32 - masklen);
2311 if ((n & ~m) != 0)
2312 bpf_error("non-network bits set in \"%s/%d\"",
2313 s1, masklen);
2314 }
2315
2316 switch (q.addr) {
2317
2318 case Q_NET:
2319 return gen_host(n, m, q.proto, q.dir);
2320
2321 default:
2322 bpf_error("Mask syntax for networks only");
2323 /* NOTREACHED */
2324 }
2325 }
2326
2327 struct block *
gen_ncode(s,v,q)2328 gen_ncode(s, v, q)
2329 register const char *s;
2330 bpf_u_int32 v;
2331 struct qual q;
2332 {
2333 bpf_u_int32 mask;
2334 int proto = q.proto;
2335 int dir = q.dir;
2336 register int vlen;
2337
2338 if (s == NULL)
2339 vlen = 32;
2340 else if (q.proto == Q_DECNET)
2341 vlen = __pcap_atodn(s, &v);
2342 else
2343 vlen = __pcap_atoin(s, &v);
2344
2345 switch (q.addr) {
2346
2347 case Q_DEFAULT:
2348 case Q_HOST:
2349 case Q_NET:
2350 if (proto == Q_DECNET)
2351 return gen_host(v, 0, proto, dir);
2352 else if (proto == Q_LINK) {
2353 bpf_error("illegal link layer address");
2354 } else {
2355 mask = 0xffffffff;
2356 if (s == NULL && q.addr == Q_NET) {
2357 /* Promote short net number */
2358 while (v && (v & 0xff000000) == 0) {
2359 v <<= 8;
2360 mask <<= 8;
2361 }
2362 } else {
2363 /* Promote short ipaddr */
2364 v <<= 32 - vlen;
2365 mask <<= 32 - vlen;
2366 }
2367 return gen_host(v, mask, proto, dir);
2368 }
2369
2370 case Q_PORT:
2371 if (proto == Q_UDP)
2372 proto = IPPROTO_UDP;
2373 else if (proto == Q_TCP)
2374 proto = IPPROTO_TCP;
2375 else if (proto == Q_DEFAULT)
2376 proto = PROTO_UNDEF;
2377 else
2378 bpf_error("illegal qualifier of 'port'");
2379
2380 #ifndef INET6
2381 return gen_port((int)v, proto, dir);
2382 #else
2383 {
2384 struct block *b;
2385 b = gen_port((int)v, proto, dir);
2386 gen_or(gen_port6((int)v, proto, dir), b);
2387 return b;
2388 }
2389 #endif /* INET6 */
2390
2391 case Q_GATEWAY:
2392 bpf_error("'gateway' requires a name");
2393 /* NOTREACHED */
2394
2395 case Q_PROTO:
2396 return gen_proto((int)v, proto, dir);
2397
2398 case Q_PROTOCHAIN:
2399 return gen_protochain((int)v, proto, dir);
2400
2401 case Q_UNDEF:
2402 syntax();
2403 /* NOTREACHED */
2404
2405 default:
2406 abort();
2407 /* NOTREACHED */
2408 }
2409 /* NOTREACHED */
2410 }
2411
2412 #ifdef INET6
2413 struct block *
gen_mcode6(s1,s2,masklen,q)2414 gen_mcode6(s1, s2, masklen, q)
2415 register const char *s1, *s2;
2416 register int masklen;
2417 struct qual q;
2418 {
2419 struct addrinfo *res;
2420 struct in6_addr *addr;
2421 struct in6_addr mask;
2422 struct block *b;
2423 u_int32_t *a, *m;
2424
2425 if (s2)
2426 bpf_error("no mask %s supported", s2);
2427
2428 res = pcap_nametoaddrinfo(s1);
2429 if (!res)
2430 bpf_error("invalid ip6 address %s", s1);
2431 if (res->ai_next)
2432 bpf_error("%s resolved to multiple address", s1);
2433 addr = &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr;
2434
2435 if (sizeof(mask) * 8 < masklen)
2436 bpf_error("mask length must be <= %u", (unsigned int)(sizeof(mask) * 8));
2437 memset(&mask, 0xff, masklen / 8);
2438 if (masklen % 8) {
2439 mask.s6_addr[masklen / 8] =
2440 (0xff << (8 - masklen % 8)) & 0xff;
2441 }
2442
2443 a = (u_int32_t *)addr;
2444 m = (u_int32_t *)&mask;
2445 if ((a[0] & ~m[0]) || (a[1] & ~m[1])
2446 || (a[2] & ~m[2]) || (a[3] & ~m[3])) {
2447 bpf_error("non-network bits set in \"%s/%d\"", s1, masklen);
2448 }
2449
2450 switch (q.addr) {
2451
2452 case Q_DEFAULT:
2453 case Q_HOST:
2454 if (masklen != 128)
2455 bpf_error("Mask syntax for networks only");
2456 /* FALLTHROUGH */
2457
2458 case Q_NET:
2459 b = gen_host6(addr, &mask, q.proto, q.dir);
2460 freeaddrinfo(res);
2461 return b;
2462
2463 default:
2464 bpf_error("invalid qualifier against IPv6 address");
2465 /* NOTREACHED */
2466 }
2467 }
2468 #endif /*INET6*/
2469
2470 struct block *
gen_ecode(eaddr,q)2471 gen_ecode(eaddr, q)
2472 register const u_char *eaddr;
2473 struct qual q;
2474 {
2475 if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) && q.proto == Q_LINK) {
2476 if (linktype == DLT_EN10MB)
2477 return gen_ehostop(eaddr, (int)q.dir);
2478 if (linktype == DLT_FDDI)
2479 return gen_fhostop(eaddr, (int)q.dir);
2480 if (linktype == DLT_IEEE802_11 ||
2481 linktype == DLT_IEEE802_11_RADIO)
2482 return gen_p80211_hostop(eaddr, (int)q.dir);
2483 }
2484 bpf_error("ethernet address used in non-ether expression");
2485 /* NOTREACHED */
2486 }
2487
2488 void
sappend(s0,s1)2489 sappend(s0, s1)
2490 struct slist *s0, *s1;
2491 {
2492 /*
2493 * This is definitely not the best way to do this, but the
2494 * lists will rarely get long.
2495 */
2496 while (s0->next)
2497 s0 = s0->next;
2498 s0->next = s1;
2499 }
2500
2501 static struct slist *
xfer_to_x(a)2502 xfer_to_x(a)
2503 struct arth *a;
2504 {
2505 struct slist *s;
2506
2507 s = new_stmt(BPF_LDX|BPF_MEM);
2508 s->s.k = a->regno;
2509 return s;
2510 }
2511
2512 static struct slist *
xfer_to_a(a)2513 xfer_to_a(a)
2514 struct arth *a;
2515 {
2516 struct slist *s;
2517
2518 s = new_stmt(BPF_LD|BPF_MEM);
2519 s->s.k = a->regno;
2520 return s;
2521 }
2522
2523 struct arth *
gen_load(proto,index,size)2524 gen_load(proto, index, size)
2525 int proto;
2526 struct arth *index;
2527 int size;
2528 {
2529 struct slist *s, *tmp;
2530 struct block *b;
2531 int regno = alloc_reg();
2532
2533 free_reg(index->regno);
2534 switch (size) {
2535
2536 default:
2537 bpf_error("data size must be 1, 2, or 4");
2538
2539 case 1:
2540 size = BPF_B;
2541 break;
2542
2543 case 2:
2544 size = BPF_H;
2545 break;
2546
2547 case 4:
2548 size = BPF_W;
2549 break;
2550 }
2551 switch (proto) {
2552 default:
2553 bpf_error("unsupported index operation");
2554
2555 case Q_LINK:
2556 s = xfer_to_x(index);
2557 tmp = new_stmt(BPF_LD|BPF_IND|size);
2558 sappend(s, tmp);
2559 sappend(index->s, s);
2560 break;
2561
2562 case Q_IP:
2563 case Q_ARP:
2564 case Q_RARP:
2565 case Q_ATALK:
2566 case Q_DECNET:
2567 case Q_SCA:
2568 case Q_LAT:
2569 case Q_MOPRC:
2570 case Q_MOPDL:
2571 #ifdef INET6
2572 case Q_IPV6:
2573 #endif
2574 /* XXX Note that we assume a fixed link header here. */
2575 s = xfer_to_x(index);
2576 tmp = new_stmt(BPF_LD|BPF_IND|size);
2577 tmp->s.k = off_nl;
2578 sappend(s, tmp);
2579 sappend(index->s, s);
2580
2581 b = gen_proto_abbrev(proto);
2582 if (index->b)
2583 gen_and(index->b, b);
2584 index->b = b;
2585 break;
2586
2587 case Q_TCP:
2588 case Q_UDP:
2589 case Q_ICMP:
2590 case Q_IGMP:
2591 case Q_IGRP:
2592 case Q_PIM:
2593 s = new_stmt(BPF_LDX|BPF_MSH|BPF_B);
2594 s->s.k = off_nl;
2595 sappend(s, xfer_to_a(index));
2596 sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X));
2597 sappend(s, new_stmt(BPF_MISC|BPF_TAX));
2598 sappend(s, tmp = new_stmt(BPF_LD|BPF_IND|size));
2599 tmp->s.k = off_nl;
2600 sappend(index->s, s);
2601
2602 gen_and(gen_proto_abbrev(proto), b = gen_ipfrag());
2603 if (index->b)
2604 gen_and(index->b, b);
2605 #ifdef INET6
2606 gen_and(gen_proto_abbrev(Q_IP), b);
2607 #endif
2608 index->b = b;
2609 break;
2610 #ifdef INET6
2611 case Q_ICMPV6:
2612 bpf_error("IPv6 upper-layer protocol is not supported by proto[x]");
2613 /*NOTREACHED*/
2614 #endif
2615 }
2616 index->regno = regno;
2617 s = new_stmt(BPF_ST);
2618 s->s.k = regno;
2619 sappend(index->s, s);
2620
2621 return index;
2622 }
2623
2624 struct block *
gen_relation(code,a0,a1,reversed)2625 gen_relation(code, a0, a1, reversed)
2626 int code;
2627 struct arth *a0, *a1;
2628 int reversed;
2629 {
2630 struct slist *s0, *s1, *s2;
2631 struct block *b, *tmp;
2632
2633 s0 = xfer_to_x(a1);
2634 s1 = xfer_to_a(a0);
2635 s2 = new_stmt(BPF_ALU|BPF_SUB|BPF_X);
2636 b = new_block(JMP(code));
2637 if (code == BPF_JGT || code == BPF_JGE) {
2638 reversed = !reversed;
2639 b->s.k = 0x80000000;
2640 }
2641 if (reversed)
2642 gen_not(b);
2643
2644 sappend(s1, s2);
2645 sappend(s0, s1);
2646 sappend(a1->s, s0);
2647 sappend(a0->s, a1->s);
2648
2649 b->stmts = a0->s;
2650
2651 free_reg(a0->regno);
2652 free_reg(a1->regno);
2653
2654 /* 'and' together protocol checks */
2655 if (a0->b) {
2656 if (a1->b) {
2657 gen_and(a0->b, tmp = a1->b);
2658 }
2659 else
2660 tmp = a0->b;
2661 } else
2662 tmp = a1->b;
2663
2664 if (tmp)
2665 gen_and(tmp, b);
2666
2667 return b;
2668 }
2669
2670 struct arth *
gen_loadlen()2671 gen_loadlen()
2672 {
2673 int regno = alloc_reg();
2674 struct arth *a = (struct arth *)newchunk(sizeof(*a));
2675 struct slist *s;
2676
2677 s = new_stmt(BPF_LD|BPF_LEN);
2678 s->next = new_stmt(BPF_ST);
2679 s->next->s.k = regno;
2680 a->s = s;
2681 a->regno = regno;
2682
2683 return a;
2684 }
2685
2686 struct arth *
gen_loadi(val)2687 gen_loadi(val)
2688 int val;
2689 {
2690 struct arth *a;
2691 struct slist *s;
2692 int reg;
2693
2694 a = (struct arth *)newchunk(sizeof(*a));
2695
2696 reg = alloc_reg();
2697
2698 s = new_stmt(BPF_LD|BPF_IMM);
2699 s->s.k = val;
2700 s->next = new_stmt(BPF_ST);
2701 s->next->s.k = reg;
2702 a->s = s;
2703 a->regno = reg;
2704
2705 return a;
2706 }
2707
2708 struct arth *
gen_neg(a)2709 gen_neg(a)
2710 struct arth *a;
2711 {
2712 struct slist *s;
2713
2714 s = xfer_to_a(a);
2715 sappend(a->s, s);
2716 s = new_stmt(BPF_ALU|BPF_NEG);
2717 s->s.k = 0;
2718 sappend(a->s, s);
2719 s = new_stmt(BPF_ST);
2720 s->s.k = a->regno;
2721 sappend(a->s, s);
2722
2723 return a;
2724 }
2725
2726 struct arth *
gen_arth(code,a0,a1)2727 gen_arth(code, a0, a1)
2728 int code;
2729 struct arth *a0, *a1;
2730 {
2731 struct slist *s0, *s1, *s2;
2732
2733 s0 = xfer_to_x(a1);
2734 s1 = xfer_to_a(a0);
2735 s2 = new_stmt(BPF_ALU|BPF_X|code);
2736
2737 sappend(s1, s2);
2738 sappend(s0, s1);
2739 sappend(a1->s, s0);
2740 sappend(a0->s, a1->s);
2741
2742 free_reg(a1->regno);
2743
2744 s0 = new_stmt(BPF_ST);
2745 a0->regno = s0->s.k = alloc_reg();
2746 sappend(a0->s, s0);
2747
2748 return a0;
2749 }
2750
2751 /*
2752 * Here we handle simple allocation of the scratch registers.
2753 * If too many registers are alloc'd, the allocator punts.
2754 */
2755 static int regused[BPF_MEMWORDS];
2756 static int curreg;
2757
2758 /*
2759 * Return the next free register.
2760 */
2761 static int
alloc_reg()2762 alloc_reg()
2763 {
2764 int n = BPF_MEMWORDS;
2765
2766 while (--n >= 0) {
2767 if (regused[curreg])
2768 curreg = (curreg + 1) % BPF_MEMWORDS;
2769 else {
2770 regused[curreg] = 1;
2771 return curreg;
2772 }
2773 }
2774 bpf_error("too many registers needed to evaluate expression");
2775 /* NOTREACHED */
2776 }
2777
2778 /*
2779 * Return a register to the table so it can
2780 * be used later.
2781 */
2782 static void
free_reg(n)2783 free_reg(n)
2784 int n;
2785 {
2786 regused[n] = 0;
2787 }
2788
2789 static struct block *
gen_len(jmp,n)2790 gen_len(jmp, n)
2791 int jmp, n;
2792 {
2793 struct slist *s;
2794 struct block *b;
2795
2796 s = new_stmt(BPF_LD|BPF_LEN);
2797 b = new_block(JMP(jmp));
2798 b->stmts = s;
2799 b->s.k = n;
2800
2801 return b;
2802 }
2803
2804 struct block *
gen_greater(n)2805 gen_greater(n)
2806 int n;
2807 {
2808 return gen_len(BPF_JGE, n);
2809 }
2810
2811 struct block *
gen_less(n)2812 gen_less(n)
2813 int n;
2814 {
2815 struct block *b;
2816
2817 b = gen_len(BPF_JGT, n);
2818 gen_not(b);
2819
2820 return b;
2821 }
2822
2823 struct block *
gen_byteop(op,idx,val)2824 gen_byteop(op, idx, val)
2825 int op, idx, val;
2826 {
2827 struct block *b;
2828 struct slist *s;
2829
2830 switch (op) {
2831 default:
2832 abort();
2833
2834 case '=':
2835 return gen_cmp((u_int)idx, BPF_B, (bpf_int32)val);
2836
2837 case '<':
2838 b = gen_cmp((u_int)idx, BPF_B, (bpf_int32)val);
2839 b->s.code = JMP(BPF_JGE);
2840 gen_not(b);
2841 return b;
2842
2843 case '>':
2844 b = gen_cmp((u_int)idx, BPF_B, (bpf_int32)val);
2845 b->s.code = JMP(BPF_JGT);
2846 return b;
2847
2848 case '|':
2849 s = new_stmt(BPF_ALU|BPF_OR|BPF_K);
2850 break;
2851
2852 case '&':
2853 s = new_stmt(BPF_ALU|BPF_AND|BPF_K);
2854 break;
2855 }
2856 s->s.k = val;
2857 b = new_block(JMP(BPF_JEQ));
2858 b->stmts = s;
2859 gen_not(b);
2860
2861 return b;
2862 }
2863
2864 struct block *
gen_broadcast(proto)2865 gen_broadcast(proto)
2866 int proto;
2867 {
2868 bpf_u_int32 hostmask;
2869 struct block *b0, *b1, *b2;
2870 static u_char ebroadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
2871
2872 switch (proto) {
2873
2874 case Q_DEFAULT:
2875 case Q_LINK:
2876 if (linktype == DLT_EN10MB)
2877 return gen_ehostop(ebroadcast, Q_DST);
2878 if (linktype == DLT_FDDI)
2879 return gen_fhostop(ebroadcast, Q_DST);
2880 if (linktype == DLT_IEEE802_11 ||
2881 linktype == DLT_IEEE802_11_RADIO)
2882 return gen_p80211_hostop(ebroadcast, Q_DST);
2883 bpf_error("not a broadcast link");
2884 break;
2885
2886 case Q_IP:
2887 b0 = gen_linktype(ETHERTYPE_IP);
2888 hostmask = ~netmask;
2889 b1 = gen_mcmp(off_nl + 16, BPF_W, (bpf_int32)0, hostmask);
2890 b2 = gen_mcmp(off_nl + 16, BPF_W,
2891 (bpf_int32)(~0 & hostmask), hostmask);
2892 gen_or(b1, b2);
2893 gen_and(b0, b2);
2894 return b2;
2895 }
2896 bpf_error("only ether/ip broadcast filters supported");
2897 }
2898
2899 struct block *
gen_multicast(proto)2900 gen_multicast(proto)
2901 int proto;
2902 {
2903 register struct block *b0, *b1;
2904 register struct slist *s;
2905
2906 switch (proto) {
2907
2908 case Q_DEFAULT:
2909 case Q_LINK:
2910 if (linktype == DLT_EN10MB) {
2911 /* ether[0] & 1 != 0 */
2912 s = new_stmt(BPF_LD|BPF_B|BPF_ABS);
2913 s->s.k = 0;
2914 b0 = new_block(JMP(BPF_JSET));
2915 b0->s.k = 1;
2916 b0->stmts = s;
2917 return b0;
2918 }
2919
2920 if (linktype == DLT_FDDI) {
2921 /* XXX TEST THIS: MIGHT NOT PORT PROPERLY XXX */
2922 /* fddi[1] & 1 != 0 */
2923 s = new_stmt(BPF_LD|BPF_B|BPF_ABS);
2924 s->s.k = 1;
2925 b0 = new_block(JMP(BPF_JSET));
2926 b0->s.k = 1;
2927 b0->stmts = s;
2928 return b0;
2929 }
2930 /* Link not known to support multicasts */
2931 break;
2932
2933 case Q_IP:
2934 b0 = gen_linktype(ETHERTYPE_IP);
2935 b1 = gen_cmp(off_nl + 16, BPF_B, (bpf_int32)224);
2936 b1->s.code = JMP(BPF_JGE);
2937 gen_and(b0, b1);
2938 return b1;
2939
2940 #ifdef INET6
2941 case Q_IPV6:
2942 b0 = gen_linktype(ETHERTYPE_IPV6);
2943 b1 = gen_cmp(off_nl + 24, BPF_B, (bpf_int32)255);
2944 gen_and(b0, b1);
2945 return b1;
2946 #endif /* INET6 */
2947 }
2948 bpf_error("only IP multicast filters supported on ethernet/FDDI");
2949 }
2950
2951 /*
2952 * generate command for inbound/outbound. It's here so we can
2953 * make it link-type specific. 'dir' = 0 implies "inbound",
2954 * = 1 implies "outbound".
2955 */
2956 struct block *
gen_inbound(dir)2957 gen_inbound(dir)
2958 int dir;
2959 {
2960 register struct block *b0;
2961
2962 /*
2963 * Only SLIP and old-style PPP data link types support
2964 * inbound/outbound qualifiers.
2965 */
2966 switch (linktype) {
2967 case DLT_SLIP:
2968 case DLT_PPP:
2969 b0 = gen_relation(BPF_JEQ,
2970 gen_load(Q_LINK, gen_loadi(0), 1),
2971 gen_loadi(0),
2972 dir);
2973 break;
2974
2975 case DLT_PFLOG:
2976 b0 = gen_cmp(offsetof(struct pfloghdr, dir), BPF_B,
2977 (bpf_int32)((dir == 0) ? PF_IN : PF_OUT));
2978 break;
2979
2980 case DLT_OLD_PFLOG:
2981 b0 = gen_cmp(offsetof(struct old_pfloghdr, dir), BPF_H,
2982 (bpf_int32)((dir == 0) ? PF_IN : PF_OUT));
2983 break;
2984
2985 default:
2986 bpf_error("inbound/outbound not supported on linktype 0x%x",
2987 linktype);
2988 /* NOTREACHED */
2989 }
2990
2991 return (b0);
2992 }
2993
2994
2995 /* PF firewall log matched interface */
2996 struct block *
gen_pf_ifname(char * ifname)2997 gen_pf_ifname(char *ifname)
2998 {
2999 struct block *b0;
3000 u_int len, off;
3001
3002 if (linktype == DLT_PFLOG) {
3003 len = sizeof(((struct pfloghdr *)0)->ifname);
3004 off = offsetof(struct pfloghdr, ifname);
3005 } else if (linktype == DLT_OLD_PFLOG) {
3006 len = sizeof(((struct old_pfloghdr *)0)->ifname);
3007 off = offsetof(struct old_pfloghdr, ifname);
3008 } else {
3009 bpf_error("ifname not supported on linktype 0x%x", linktype);
3010 /* NOTREACHED */
3011 }
3012 if (strlen(ifname) >= len) {
3013 bpf_error("ifname interface names can only be %d characters",
3014 len - 1);
3015 /* NOTREACHED */
3016 }
3017 b0 = gen_bcmp(off, strlen(ifname), ifname);
3018 return (b0);
3019 }
3020
3021
3022 /* PF firewall log ruleset name */
3023 struct block *
gen_pf_ruleset(char * ruleset)3024 gen_pf_ruleset(char *ruleset)
3025 {
3026 struct block *b0;
3027
3028 if (linktype != DLT_PFLOG) {
3029 bpf_error("ruleset not supported on linktype 0x%x", linktype);
3030 /* NOTREACHED */
3031 }
3032 if (strlen(ruleset) >= sizeof(((struct pfloghdr *)0)->ruleset)) {
3033 bpf_error("ruleset names can only be %zu characters",
3034 sizeof(((struct pfloghdr *)0)->ruleset) - 1);
3035 /* NOTREACHED */
3036 }
3037 b0 = gen_bcmp(offsetof(struct pfloghdr, ruleset),
3038 strlen(ruleset), ruleset);
3039 return (b0);
3040 }
3041
3042
3043 /* PF firewall log rule number */
3044 struct block *
gen_pf_rnr(int rnr)3045 gen_pf_rnr(int rnr)
3046 {
3047 struct block *b0;
3048
3049 if (linktype == DLT_PFLOG) {
3050 b0 = gen_cmp(offsetof(struct pfloghdr, rulenr), BPF_W,
3051 (bpf_int32)rnr);
3052 } else if (linktype == DLT_OLD_PFLOG) {
3053 b0 = gen_cmp(offsetof(struct old_pfloghdr, rnr), BPF_H,
3054 (bpf_int32)rnr);
3055 } else {
3056 bpf_error("rnr not supported on linktype 0x%x", linktype);
3057 /* NOTREACHED */
3058 }
3059
3060 return (b0);
3061 }
3062
3063
3064 /* PF firewall log sub-rule number */
3065 struct block *
gen_pf_srnr(int srnr)3066 gen_pf_srnr(int srnr)
3067 {
3068 struct block *b0;
3069
3070 if (linktype != DLT_PFLOG) {
3071 bpf_error("srnr not supported on linktype 0x%x", linktype);
3072 /* NOTREACHED */
3073 }
3074
3075 b0 = gen_cmp(offsetof(struct pfloghdr, subrulenr), BPF_W,
3076 (bpf_int32)srnr);
3077 return (b0);
3078 }
3079
3080 /* PF firewall log reason code */
3081 struct block *
gen_pf_reason(int reason)3082 gen_pf_reason(int reason)
3083 {
3084 struct block *b0;
3085
3086 if (linktype == DLT_PFLOG) {
3087 b0 = gen_cmp(offsetof(struct pfloghdr, reason), BPF_B,
3088 (bpf_int32)reason);
3089 } else if (linktype == DLT_OLD_PFLOG) {
3090 b0 = gen_cmp(offsetof(struct old_pfloghdr, reason), BPF_H,
3091 (bpf_int32)reason);
3092 } else {
3093 bpf_error("reason not supported on linktype 0x%x", linktype);
3094 /* NOTREACHED */
3095 }
3096
3097 return (b0);
3098 }
3099
3100 /* PF firewall log action */
3101 struct block *
gen_pf_action(int action)3102 gen_pf_action(int action)
3103 {
3104 struct block *b0;
3105
3106 if (linktype == DLT_PFLOG) {
3107 b0 = gen_cmp(offsetof(struct pfloghdr, action), BPF_B,
3108 (bpf_int32)action);
3109 } else if (linktype == DLT_OLD_PFLOG) {
3110 b0 = gen_cmp(offsetof(struct old_pfloghdr, action), BPF_H,
3111 (bpf_int32)action);
3112 } else {
3113 bpf_error("action not supported on linktype 0x%x", linktype);
3114 /* NOTREACHED */
3115 }
3116
3117 return (b0);
3118 }
3119
3120 /* IEEE 802.11 wireless header */
3121 struct block *
gen_p80211_type(int type,int mask)3122 gen_p80211_type(int type, int mask)
3123 {
3124 struct block *b0;
3125 u_int offset;
3126
3127 if (!(linktype == DLT_IEEE802_11 ||
3128 linktype == DLT_IEEE802_11_RADIO)) {
3129 bpf_error("type not supported on linktype 0x%x",
3130 linktype);
3131 /* NOTREACHED */
3132 }
3133 offset = (u_int)offsetof(struct ieee80211_frame, i_fc[0]);
3134 if (linktype == DLT_IEEE802_11_RADIO)
3135 offset += IEEE80211_RADIOTAP_HDRLEN;
3136
3137 b0 = gen_mcmp(offset, BPF_B, (bpf_int32)type, (bpf_u_int32)mask);
3138
3139 return (b0);
3140 }
3141
3142 struct block *
gen_p80211_fcdir(int fcdir)3143 gen_p80211_fcdir(int fcdir)
3144 {
3145 struct block *b0;
3146 u_int offset;
3147
3148 if (!(linktype == DLT_IEEE802_11 ||
3149 linktype == DLT_IEEE802_11_RADIO)) {
3150 bpf_error("frame direction not supported on linktype 0x%x",
3151 linktype);
3152 /* NOTREACHED */
3153 }
3154 offset = (u_int)offsetof(struct ieee80211_frame, i_fc[1]);
3155 if (linktype == DLT_IEEE802_11_RADIO)
3156 offset += IEEE80211_RADIOTAP_HDRLEN;
3157
3158 b0 = gen_mcmp(offset, BPF_B, (bpf_int32)fcdir,
3159 (bpf_u_int32)IEEE80211_FC1_DIR_MASK);
3160
3161 return (b0);
3162 }
3163
3164 static struct block *
gen_p80211_hostop(const u_char * lladdr,int dir)3165 gen_p80211_hostop(const u_char *lladdr, int dir)
3166 {
3167 struct block *b0, *b1, *b2, *b3, *b4;
3168 u_int offset = 0;
3169
3170 if (linktype == DLT_IEEE802_11_RADIO)
3171 offset = IEEE80211_RADIOTAP_HDRLEN;
3172
3173 switch (dir) {
3174 case Q_SRC:
3175 b0 = gen_p80211_addr(IEEE80211_FC1_DIR_NODS, offset +
3176 (u_int)offsetof(struct ieee80211_frame, i_addr2),
3177 lladdr);
3178 b1 = gen_p80211_addr(IEEE80211_FC1_DIR_TODS, offset +
3179 (u_int)offsetof(struct ieee80211_frame, i_addr2),
3180 lladdr);
3181 b2 = gen_p80211_addr(IEEE80211_FC1_DIR_FROMDS, offset +
3182 (u_int)offsetof(struct ieee80211_frame, i_addr3),
3183 lladdr);
3184 b3 = gen_p80211_addr(IEEE80211_FC1_DIR_DSTODS, offset +
3185 (u_int)offsetof(struct ieee80211_frame_addr4, i_addr4),
3186 lladdr);
3187 b4 = gen_p80211_addr(IEEE80211_FC1_DIR_DSTODS, offset +
3188 (u_int)offsetof(struct ieee80211_frame_addr4, i_addr2),
3189 lladdr);
3190
3191 gen_or(b0, b1);
3192 gen_or(b1, b2);
3193 gen_or(b2, b3);
3194 gen_or(b3, b4);
3195 return (b4);
3196
3197 case Q_DST:
3198 b0 = gen_p80211_addr(IEEE80211_FC1_DIR_NODS, offset +
3199 (u_int)offsetof(struct ieee80211_frame, i_addr1),
3200 lladdr);
3201 b1 = gen_p80211_addr(IEEE80211_FC1_DIR_TODS, offset +
3202 (u_int)offsetof(struct ieee80211_frame, i_addr3),
3203 lladdr);
3204 b2 = gen_p80211_addr(IEEE80211_FC1_DIR_FROMDS, offset +
3205 (u_int)offsetof(struct ieee80211_frame, i_addr1),
3206 lladdr);
3207 b3 = gen_p80211_addr(IEEE80211_FC1_DIR_DSTODS, offset +
3208 (u_int)offsetof(struct ieee80211_frame_addr4, i_addr3),
3209 lladdr);
3210 b4 = gen_p80211_addr(IEEE80211_FC1_DIR_DSTODS, offset +
3211 (u_int)offsetof(struct ieee80211_frame_addr4, i_addr1),
3212 lladdr);
3213
3214 gen_or(b0, b1);
3215 gen_or(b1, b2);
3216 gen_or(b2, b3);
3217 gen_or(b3, b4);
3218 return (b4);
3219
3220 case Q_ADDR1:
3221 return (gen_bcmp(offset +
3222 (u_int)offsetof(struct ieee80211_frame,
3223 i_addr1), IEEE80211_ADDR_LEN, lladdr));
3224
3225 case Q_ADDR2:
3226 return (gen_bcmp(offset +
3227 (u_int)offsetof(struct ieee80211_frame,
3228 i_addr2), IEEE80211_ADDR_LEN, lladdr));
3229
3230 case Q_ADDR3:
3231 return (gen_bcmp(offset +
3232 (u_int)offsetof(struct ieee80211_frame,
3233 i_addr3), IEEE80211_ADDR_LEN, lladdr));
3234
3235 case Q_ADDR4:
3236 return (gen_p80211_addr(IEEE80211_FC1_DIR_DSTODS, offset +
3237 (u_int)offsetof(struct ieee80211_frame_addr4, i_addr4),
3238 lladdr));
3239
3240 case Q_AND:
3241 b0 = gen_p80211_hostop(lladdr, Q_SRC);
3242 b1 = gen_p80211_hostop(lladdr, Q_DST);
3243 gen_and(b0, b1);
3244 return (b1);
3245
3246 case Q_DEFAULT:
3247 case Q_OR:
3248 b0 = gen_p80211_hostop(lladdr, Q_ADDR1);
3249 b1 = gen_p80211_hostop(lladdr, Q_ADDR2);
3250 b2 = gen_p80211_hostop(lladdr, Q_ADDR3);
3251 b3 = gen_p80211_hostop(lladdr, Q_ADDR4);
3252 gen_or(b0, b1);
3253 gen_or(b1, b2);
3254 gen_or(b2, b3);
3255 return (b3);
3256
3257 default:
3258 bpf_error("direction not supported on linktype 0x%x",
3259 linktype);
3260 }
3261 /* NOTREACHED */
3262 }
3263
3264 static struct block *
gen_p80211_addr(int fcdir,u_int offset,const u_char * lladdr)3265 gen_p80211_addr(int fcdir, u_int offset, const u_char *lladdr)
3266 {
3267 struct block *b0, *b1;
3268
3269 b0 = gen_mcmp(offset, BPF_B, (bpf_int32)fcdir, IEEE80211_FC1_DIR_MASK);
3270 b1 = gen_bcmp(offset, IEEE80211_ADDR_LEN, lladdr);
3271 gen_and(b0, b1);
3272
3273 return (b1);
3274 }
3275