Bug Summary

File:src/lib/libpcap/gencode.c
Warning:line 1871, column 16
Although the value stored to 'fix4' is used in the enclosing expression, the value is never actually read from 'fix4'

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;
Although the value stored to 'fix4' is used in the enclosing expression, the value is never actually read from 'fix4'
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}