Bug Summary

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