Bug Summary

File:src/lib/libpcap/gencode.c
Warning:line 1871, column 2
Value stored to 'fix2' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

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