Bug Summary

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

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 -fhalf-no-semantic-interposition -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 -D PIC -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;
Value stored to 'fix2' is never read
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}