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