]> The Tcpdump Group git mirrors - libpcap/blob - gencode.c
Eliminate duplicated word in comment.
[libpcap] / gencode.c
1 /*#define CHASE_CHAIN*/
2 /*
3 * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998
4 * The Regents of the University of California. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that: (1) source code distributions
8 * retain the above copyright notice and this paragraph in its entirety, (2)
9 * distributions including binary code include the above copyright notice and
10 * this paragraph in its entirety in the documentation or other materials
11 * provided with the distribution, and (3) all advertising materials mentioning
12 * features or use of this software display the following acknowledgement:
13 * ``This product includes software developed by the University of California,
14 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
15 * the University nor the names of its contributors may be used to endorse
16 * or promote products derived from this software without specific prior
17 * written permission.
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
19 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21 */
22 #ifndef lint
23 static const char rcsid[] =
24 "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.101 2000-01-29 21:01:27 fenner Exp $ (LBL)";
25 #endif
26
27 #include <sys/types.h>
28 #include <sys/socket.h>
29 #include <sys/time.h>
30 #ifdef __NetBSD__
31 #include <sys/param.h>
32 #endif
33
34 #if __STDC__
35 struct mbuf;
36 struct rtentry;
37 #endif
38
39 #include <net/if.h>
40
41 #include <netinet/in.h>
42 #include <netinet/if_ether.h>
43
44 #include <stdlib.h>
45 #include <memory.h>
46 #include <setjmp.h>
47 #if __STDC__
48 #include <stdarg.h>
49 #else
50 #include <varargs.h>
51 #endif
52
53 #include "pcap-int.h"
54
55 #include "ethertype.h"
56 #include "gencode.h"
57 #include "ppp.h"
58 #include <pcap-namedb.h>
59 #ifdef INET6
60 #include <netdb.h>
61 #include <sys/socket.h>
62 #endif /*INET6*/
63
64 #include "gnuc.h"
65 #ifdef HAVE_OS_PROTO_H
66 #include "os-proto.h"
67 #endif
68
69 #define JMP(c) ((c)|BPF_JMP|BPF_K)
70
71 /* Locals */
72 static jmp_buf top_ctx;
73 static pcap_t *bpf_pcap;
74
75 /* XXX */
76 #ifdef PCAP_FDDIPAD
77 int pcap_fddipad = PCAP_FDDIPAD;
78 #else
79 int pcap_fddipad;
80 #endif
81
82 /* VARARGS */
83 __dead void
84 #if __STDC__
85 bpf_error(const char *fmt, ...)
86 #else
87 bpf_error(fmt, va_alist)
88 const char *fmt;
89 va_dcl
90 #endif
91 {
92 va_list ap;
93
94 #if __STDC__
95 va_start(ap, fmt);
96 #else
97 va_start(ap);
98 #endif
99 if (bpf_pcap != NULL)
100 (void)vsprintf(pcap_geterr(bpf_pcap), fmt, ap);
101 va_end(ap);
102 longjmp(top_ctx, 1);
103 /* NOTREACHED */
104 }
105
106 static void init_linktype(int);
107
108 static int alloc_reg(void);
109 static void free_reg(int);
110
111 static struct block *root;
112
113 /*
114 * We divy out chunks of memory rather than call malloc each time so
115 * we don't have to worry about leaking memory. It's probably
116 * not a big deal if all this memory was wasted but it this ever
117 * goes into a library that would probably not be a good idea.
118 */
119 #define NCHUNKS 16
120 #define CHUNK0SIZE 1024
121 struct chunk {
122 u_int n_left;
123 void *m;
124 };
125
126 static struct chunk chunks[NCHUNKS];
127 static int cur_chunk;
128
129 static void *newchunk(u_int);
130 static void freechunks(void);
131 static inline struct block *new_block(int);
132 static inline struct slist *new_stmt(int);
133 static struct block *gen_retblk(int);
134 static inline void syntax(void);
135
136 static void backpatch(struct block *, struct block *);
137 static void merge(struct block *, struct block *);
138 static struct block *gen_cmp(u_int, u_int, bpf_int32);
139 static struct block *gen_mcmp(u_int, u_int, bpf_int32, bpf_u_int32);
140 static struct block *gen_bcmp(u_int, u_int, const u_char *);
141 static struct block *gen_uncond(int);
142 static inline struct block *gen_true(void);
143 static inline struct block *gen_false(void);
144 static struct block *gen_linktype(int);
145 static struct block *gen_hostop(bpf_u_int32, bpf_u_int32, int, int, u_int, u_int);
146 #ifdef INET6
147 static struct block *gen_hostop6(struct in6_addr *, struct in6_addr *, int, int, u_int, u_int);
148 #endif
149 static struct block *gen_ehostop(const u_char *, int);
150 static struct block *gen_fhostop(const u_char *, int);
151 static struct block *gen_dnhostop(bpf_u_int32, int, u_int);
152 static struct block *gen_host(bpf_u_int32, bpf_u_int32, int, int);
153 #ifdef INET6
154 static struct block *gen_host6(struct in6_addr *, struct in6_addr *, int, int);
155 #endif
156 static struct block *gen_gateway(const u_char *, bpf_u_int32 **, int, int);
157 static struct block *gen_ipfrag(void);
158 static struct block *gen_portatom(int, bpf_int32);
159 #ifdef INET6
160 static struct block *gen_portatom6(int, bpf_int32);
161 #endif
162 struct block *gen_portop(int, int, int);
163 static struct block *gen_port(int, int, int);
164 #ifdef INET6
165 struct block *gen_portop6(int, int, int);
166 static struct block *gen_port6(int, int, int);
167 #endif
168 static int lookup_proto(const char *, int);
169 static struct block *gen_proto(int, int, int);
170 static struct slist *xfer_to_x(struct arth *);
171 static struct slist *xfer_to_a(struct arth *);
172 static struct block *gen_len(int, int);
173
174 static void *
175 newchunk(n)
176 u_int n;
177 {
178 struct chunk *cp;
179 int k, size;
180
181 #ifndef __NetBSD__
182 /* XXX Round up to nearest long. */
183 n = (n + sizeof(long) - 1) & ~(sizeof(long) - 1);
184 #else
185 /* XXX Round up to structure boundary. */
186 n = ALIGN(n);
187 #endif
188
189 cp = &chunks[cur_chunk];
190 if (n > cp->n_left) {
191 ++cp, k = ++cur_chunk;
192 if (k >= NCHUNKS)
193 bpf_error("out of memory");
194 size = CHUNK0SIZE << k;
195 cp->m = (void *)malloc(size);
196 memset((char *)cp->m, 0, size);
197 cp->n_left = size;
198 if (n > size)
199 bpf_error("out of memory");
200 }
201 cp->n_left -= n;
202 return (void *)((char *)cp->m + cp->n_left);
203 }
204
205 static void
206 freechunks()
207 {
208 int i;
209
210 cur_chunk = 0;
211 for (i = 0; i < NCHUNKS; ++i)
212 if (chunks[i].m != NULL) {
213 free(chunks[i].m);
214 chunks[i].m = NULL;
215 }
216 }
217
218 /*
219 * A strdup whose allocations are freed after code generation is over.
220 */
221 char *
222 sdup(s)
223 register const char *s;
224 {
225 int n = strlen(s) + 1;
226 char *cp = newchunk(n);
227
228 strcpy(cp, s);
229 return (cp);
230 }
231
232 static inline struct block *
233 new_block(code)
234 int code;
235 {
236 struct block *p;
237
238 p = (struct block *)newchunk(sizeof(*p));
239 p->s.code = code;
240 p->head = p;
241
242 return p;
243 }
244
245 static inline struct slist *
246 new_stmt(code)
247 int code;
248 {
249 struct slist *p;
250
251 p = (struct slist *)newchunk(sizeof(*p));
252 p->s.code = code;
253
254 return p;
255 }
256
257 static struct block *
258 gen_retblk(v)
259 int v;
260 {
261 struct block *b = new_block(BPF_RET|BPF_K);
262
263 b->s.k = v;
264 return b;
265 }
266
267 static inline void
268 syntax()
269 {
270 bpf_error("syntax error in filter expression");
271 }
272
273 static bpf_u_int32 netmask;
274 static int snaplen;
275 int no_optimize;
276
277 int
278 pcap_compile(pcap_t *p, struct bpf_program *program,
279 char *buf, int optimize, bpf_u_int32 mask)
280 {
281 extern int n_errors;
282 int len;
283
284 no_optimize = 0;
285 n_errors = 0;
286 root = NULL;
287 bpf_pcap = p;
288 if (setjmp(top_ctx)) {
289 freechunks();
290 return (-1);
291 }
292
293 netmask = mask;
294 snaplen = pcap_snapshot(p);
295
296 lex_init(buf ? buf : "");
297 init_linktype(pcap_datalink(p));
298 (void)pcap_parse();
299
300 if (n_errors)
301 syntax();
302
303 if (root == NULL)
304 root = gen_retblk(snaplen);
305
306 if (optimize && !no_optimize) {
307 bpf_optimize(&root);
308 if (root == NULL ||
309 (root->s.code == (BPF_RET|BPF_K) && root->s.k == 0))
310 bpf_error("expression rejects all packets");
311 }
312 program->bf_insns = icode_to_fcode(root, &len);
313 program->bf_len = len;
314
315 freechunks();
316 return (0);
317 }
318
319 /*
320 * entry point for using the compiler with no pcap open
321 * pass in all the stuff that is needed explicitly instead.
322 */
323 int
324 pcap_compile_nopcap(int snaplen_arg, int linktype_arg,
325 struct bpf_program *program,
326 char *buf, int optimize, bpf_u_int32 mask)
327 {
328 extern int n_errors;
329 int len;
330
331 n_errors = 0;
332 root = NULL;
333 bpf_pcap = NULL;
334 if (setjmp(top_ctx)) {
335 freechunks();
336 return (-1);
337 }
338
339 netmask = mask;
340
341 /* XXX needed? I don't grok the use of globals here. */
342 snaplen = snaplen_arg;
343
344 lex_init(buf ? buf : "");
345 init_linktype(linktype_arg);
346 (void)pcap_parse();
347
348 if (n_errors)
349 syntax();
350
351 if (root == NULL)
352 root = gen_retblk(snaplen_arg);
353
354 if (optimize) {
355 bpf_optimize(&root);
356 if (root == NULL ||
357 (root->s.code == (BPF_RET|BPF_K) && root->s.k == 0))
358 bpf_error("expression rejects all packets");
359 }
360 program->bf_insns = icode_to_fcode(root, &len);
361 program->bf_len = len;
362
363 freechunks();
364 return (0);
365 }
366
367 /*
368 * Backpatch the blocks in 'list' to 'target'. The 'sense' field indicates
369 * which of the jt and jf fields has been resolved and which is a pointer
370 * back to another unresolved block (or nil). At least one of the fields
371 * in each block is already resolved.
372 */
373 static void
374 backpatch(list, target)
375 struct block *list, *target;
376 {
377 struct block *next;
378
379 while (list) {
380 if (!list->sense) {
381 next = JT(list);
382 JT(list) = target;
383 } else {
384 next = JF(list);
385 JF(list) = target;
386 }
387 list = next;
388 }
389 }
390
391 /*
392 * Merge the lists in b0 and b1, using the 'sense' field to indicate
393 * which of jt and jf is the link.
394 */
395 static void
396 merge(b0, b1)
397 struct block *b0, *b1;
398 {
399 register struct block **p = &b0;
400
401 /* Find end of list. */
402 while (*p)
403 p = !((*p)->sense) ? &JT(*p) : &JF(*p);
404
405 /* Concatenate the lists. */
406 *p = b1;
407 }
408
409 void
410 finish_parse(p)
411 struct block *p;
412 {
413 backpatch(p, gen_retblk(snaplen));
414 p->sense = !p->sense;
415 backpatch(p, gen_retblk(0));
416 root = p->head;
417 }
418
419 void
420 gen_and(b0, b1)
421 struct block *b0, *b1;
422 {
423 backpatch(b0, b1->head);
424 b0->sense = !b0->sense;
425 b1->sense = !b1->sense;
426 merge(b1, b0);
427 b1->sense = !b1->sense;
428 b1->head = b0->head;
429 }
430
431 void
432 gen_or(b0, b1)
433 struct block *b0, *b1;
434 {
435 b0->sense = !b0->sense;
436 backpatch(b0, b1->head);
437 b0->sense = !b0->sense;
438 merge(b1, b0);
439 b1->head = b0->head;
440 }
441
442 void
443 gen_not(b)
444 struct block *b;
445 {
446 b->sense = !b->sense;
447 }
448
449 static struct block *
450 gen_cmp(offset, size, v)
451 u_int offset, size;
452 bpf_int32 v;
453 {
454 struct slist *s;
455 struct block *b;
456
457 s = new_stmt(BPF_LD|BPF_ABS|size);
458 s->s.k = offset;
459
460 b = new_block(JMP(BPF_JEQ));
461 b->stmts = s;
462 b->s.k = v;
463
464 return b;
465 }
466
467 static struct block *
468 gen_mcmp(offset, size, v, mask)
469 u_int offset, size;
470 bpf_int32 v;
471 bpf_u_int32 mask;
472 {
473 struct block *b = gen_cmp(offset, size, v);
474 struct slist *s;
475
476 if (mask != 0xffffffff) {
477 s = new_stmt(BPF_ALU|BPF_AND|BPF_K);
478 s->s.k = mask;
479 b->stmts->next = s;
480 }
481 return b;
482 }
483
484 static struct block *
485 gen_bcmp(offset, size, v)
486 register u_int offset, size;
487 register const u_char *v;
488 {
489 register struct block *b, *tmp;
490
491 b = NULL;
492 while (size >= 4) {
493 register const u_char *p = &v[size - 4];
494 bpf_int32 w = ((bpf_int32)p[0] << 24) |
495 ((bpf_int32)p[1] << 16) | ((bpf_int32)p[2] << 8) | p[3];
496
497 tmp = gen_cmp(offset + size - 4, BPF_W, w);
498 if (b != NULL)
499 gen_and(b, tmp);
500 b = tmp;
501 size -= 4;
502 }
503 while (size >= 2) {
504 register const u_char *p = &v[size - 2];
505 bpf_int32 w = ((bpf_int32)p[0] << 8) | p[1];
506
507 tmp = gen_cmp(offset + size - 2, BPF_H, w);
508 if (b != NULL)
509 gen_and(b, tmp);
510 b = tmp;
511 size -= 2;
512 }
513 if (size > 0) {
514 tmp = gen_cmp(offset, BPF_B, (bpf_int32)v[0]);
515 if (b != NULL)
516 gen_and(b, tmp);
517 b = tmp;
518 }
519 return b;
520 }
521
522 /*
523 * Various code constructs need to know the layout of the data link
524 * layer. These variables give the necessary offsets. off_linktype
525 * is set to -1 for no encapsulation, in which case, IP is assumed.
526 */
527 static u_int off_linktype;
528 static u_int off_nl;
529 static int linktype;
530
531 static void
532 init_linktype(type)
533 int type;
534 {
535 linktype = type;
536
537 switch (type) {
538
539 case DLT_EN10MB:
540 off_linktype = 12;
541 off_nl = 14;
542 return;
543
544 case DLT_SLIP:
545 /*
546 * SLIP doesn't have a link level type. The 16 byte
547 * header is hacked into our SLIP driver.
548 */
549 off_linktype = -1;
550 off_nl = 16;
551 return;
552
553 case DLT_SLIP_BSDOS:
554 /* XXX this may be the same as the DLT_PPP_BSDOS case */
555 off_linktype = -1;
556 /* XXX end */
557 off_nl = 24;
558 return;
559
560 case DLT_NULL:
561 off_linktype = 0;
562 off_nl = 4;
563 return;
564
565 case DLT_PPP:
566 case DLT_CHDLC:
567 off_linktype = 2;
568 off_nl = 4;
569 return;
570
571 case DLT_PPP_BSDOS:
572 off_linktype = 5;
573 off_nl = 24;
574 return;
575
576 case DLT_FDDI:
577 /*
578 * FDDI doesn't really have a link-level type field.
579 * We assume that SSAP = SNAP is being used and pick
580 * out the encapsulated Ethernet type.
581 */
582 off_linktype = 19;
583 #ifdef PCAP_FDDIPAD
584 off_linktype += pcap_fddipad;
585 #endif
586 off_nl = 21;
587 #ifdef PCAP_FDDIPAD
588 off_nl += pcap_fddipad;
589 #endif
590 return;
591
592 case DLT_IEEE802:
593 off_linktype = 20;
594 off_nl = 22;
595 return;
596
597 case DLT_ATM_RFC1483:
598 /*
599 * assume routed, non-ISO PDUs
600 * (i.e., LLC = 0xAA-AA-03, OUT = 0x00-00-00)
601 */
602 off_linktype = 6;
603 off_nl = 8;
604 return;
605
606 case DLT_RAW:
607 off_linktype = -1;
608 off_nl = 0;
609 return;
610 }
611 bpf_error("unknown data link type 0x%x", linktype);
612 /* NOTREACHED */
613 }
614
615 static struct block *
616 gen_uncond(rsense)
617 int rsense;
618 {
619 struct block *b;
620 struct slist *s;
621
622 s = new_stmt(BPF_LD|BPF_IMM);
623 s->s.k = !rsense;
624 b = new_block(JMP(BPF_JEQ));
625 b->stmts = s;
626
627 return b;
628 }
629
630 static inline struct block *
631 gen_true()
632 {
633 return gen_uncond(1);
634 }
635
636 static inline struct block *
637 gen_false()
638 {
639 return gen_uncond(0);
640 }
641
642 static struct block *
643 gen_linktype(proto)
644 register int proto;
645 {
646 struct block *b0, *b1;
647
648 /* If we're not using encapsulation and checking for IP, we're done */
649 if (off_linktype == -1 && proto == ETHERTYPE_IP)
650 return gen_true();
651
652 switch (linktype) {
653
654 case DLT_SLIP:
655 return gen_false();
656
657 case DLT_PPP:
658 if (proto == ETHERTYPE_IP)
659 proto = PPP_IP; /* XXX was 0x21 */
660 #ifdef INET6
661 else if (proto == ETHERTYPE_IPV6)
662 proto = PPP_IPV6;
663 #endif
664 break;
665
666 case DLT_PPP_BSDOS:
667 switch (proto) {
668
669 case ETHERTYPE_IP:
670 b0 = gen_cmp(off_linktype, BPF_H, PPP_IP);
671 b1 = gen_cmp(off_linktype, BPF_H, PPP_VJC);
672 gen_or(b0, b1);
673 b0 = gen_cmp(off_linktype, BPF_H, PPP_VJNC);
674 gen_or(b1, b0);
675 return b0;
676
677 #ifdef INET6
678 case ETHERTYPE_IPV6:
679 proto = PPP_IPV6;
680 /* more to go? */
681 break;
682 #endif
683
684 case ETHERTYPE_DN:
685 proto = PPP_DECNET;
686 break;
687
688 case ETHERTYPE_ATALK:
689 proto = PPP_APPLE;
690 break;
691
692 case ETHERTYPE_NS:
693 proto = PPP_NS;
694 break;
695 }
696 break;
697
698 case DLT_NULL:
699 /* XXX */
700 if (proto == ETHERTYPE_IP)
701 return (gen_cmp(0, BPF_W, (bpf_int32)htonl(AF_INET)));
702 #ifdef INET6
703 else if (proto == ETHERTYPE_IPV6)
704 return (gen_cmp(0, BPF_W, (bpf_int32)htonl(AF_INET6)));
705 #endif
706 else
707 return gen_false();
708 }
709 return gen_cmp(off_linktype, BPF_H, (bpf_int32)proto);
710 }
711
712 static struct block *
713 gen_hostop(addr, mask, dir, proto, src_off, dst_off)
714 bpf_u_int32 addr;
715 bpf_u_int32 mask;
716 int dir, proto;
717 u_int src_off, dst_off;
718 {
719 struct block *b0, *b1;
720 u_int offset;
721
722 switch (dir) {
723
724 case Q_SRC:
725 offset = src_off;
726 break;
727
728 case Q_DST:
729 offset = dst_off;
730 break;
731
732 case Q_AND:
733 b0 = gen_hostop(addr, mask, Q_SRC, proto, src_off, dst_off);
734 b1 = gen_hostop(addr, mask, Q_DST, proto, src_off, dst_off);
735 gen_and(b0, b1);
736 return b1;
737
738 case Q_OR:
739 case Q_DEFAULT:
740 b0 = gen_hostop(addr, mask, Q_SRC, proto, src_off, dst_off);
741 b1 = gen_hostop(addr, mask, Q_DST, proto, src_off, dst_off);
742 gen_or(b0, b1);
743 return b1;
744
745 default:
746 abort();
747 }
748 b0 = gen_linktype(proto);
749 b1 = gen_mcmp(offset, BPF_W, (bpf_int32)addr, mask);
750 gen_and(b0, b1);
751 return b1;
752 }
753
754 #ifdef INET6
755 static struct block *
756 gen_hostop6(addr, mask, dir, proto, src_off, dst_off)
757 struct in6_addr *addr;
758 struct in6_addr *mask;
759 int dir, proto;
760 u_int src_off, dst_off;
761 {
762 struct block *b0, *b1;
763 u_int offset;
764 u_int32_t *a, *m;
765
766 switch (dir) {
767
768 case Q_SRC:
769 offset = src_off;
770 break;
771
772 case Q_DST:
773 offset = dst_off;
774 break;
775
776 case Q_AND:
777 b0 = gen_hostop6(addr, mask, Q_SRC, proto, src_off, dst_off);
778 b1 = gen_hostop6(addr, mask, Q_DST, proto, src_off, dst_off);
779 gen_and(b0, b1);
780 return b1;
781
782 case Q_OR:
783 case Q_DEFAULT:
784 b0 = gen_hostop6(addr, mask, Q_SRC, proto, src_off, dst_off);
785 b1 = gen_hostop6(addr, mask, Q_DST, proto, src_off, dst_off);
786 gen_or(b0, b1);
787 return b1;
788
789 default:
790 abort();
791 }
792 /* this order is important */
793 a = (u_int32_t *)addr;
794 m = (u_int32_t *)mask;
795 b1 = gen_mcmp(offset + 12, BPF_W, ntohl(a[3]), ntohl(m[3]));
796 b0 = gen_mcmp(offset + 8, BPF_W, ntohl(a[2]), ntohl(m[2]));
797 gen_and(b0, b1);
798 b0 = gen_mcmp(offset + 4, BPF_W, ntohl(a[1]), ntohl(m[1]));
799 gen_and(b0, b1);
800 b0 = gen_mcmp(offset + 0, BPF_W, ntohl(a[0]), ntohl(m[0]));
801 gen_and(b0, b1);
802 b0 = gen_linktype(proto);
803 gen_and(b0, b1);
804 return b1;
805 }
806 #endif /*INET6*/
807
808 static struct block *
809 gen_ehostop(eaddr, dir)
810 register const u_char *eaddr;
811 register int dir;
812 {
813 register struct block *b0, *b1;
814
815 switch (dir) {
816 case Q_SRC:
817 return gen_bcmp(6, 6, eaddr);
818
819 case Q_DST:
820 return gen_bcmp(0, 6, eaddr);
821
822 case Q_AND:
823 b0 = gen_ehostop(eaddr, Q_SRC);
824 b1 = gen_ehostop(eaddr, Q_DST);
825 gen_and(b0, b1);
826 return b1;
827
828 case Q_DEFAULT:
829 case Q_OR:
830 b0 = gen_ehostop(eaddr, Q_SRC);
831 b1 = gen_ehostop(eaddr, Q_DST);
832 gen_or(b0, b1);
833 return b1;
834 }
835 abort();
836 /* NOTREACHED */
837 }
838
839 /*
840 * Like gen_ehostop, but for DLT_FDDI
841 */
842 static struct block *
843 gen_fhostop(eaddr, dir)
844 register const u_char *eaddr;
845 register int dir;
846 {
847 struct block *b0, *b1;
848
849 switch (dir) {
850 case Q_SRC:
851 #ifdef PCAP_FDDIPAD
852 return gen_bcmp(6 + 1 + pcap_fddipad, 6, eaddr);
853 #else
854 return gen_bcmp(6 + 1, 6, eaddr);
855 #endif
856
857 case Q_DST:
858 #ifdef PCAP_FDDIPAD
859 return gen_bcmp(0 + 1 + pcap_fddipad, 6, eaddr);
860 #else
861 return gen_bcmp(0 + 1, 6, eaddr);
862 #endif
863
864 case Q_AND:
865 b0 = gen_fhostop(eaddr, Q_SRC);
866 b1 = gen_fhostop(eaddr, Q_DST);
867 gen_and(b0, b1);
868 return b1;
869
870 case Q_DEFAULT:
871 case Q_OR:
872 b0 = gen_fhostop(eaddr, Q_SRC);
873 b1 = gen_fhostop(eaddr, Q_DST);
874 gen_or(b0, b1);
875 return b1;
876 }
877 abort();
878 /* NOTREACHED */
879 }
880
881 /*
882 * This is quite tricky because there may be pad bytes in front of the
883 * DECNET header, and then there are two possible data packet formats that
884 * carry both src and dst addresses, plus 5 packet types in a format that
885 * carries only the src node, plus 2 types that use a different format and
886 * also carry just the src node.
887 *
888 * Yuck.
889 *
890 * Instead of doing those all right, we just look for data packets with
891 * 0 or 1 bytes of padding. If you want to look at other packets, that
892 * will require a lot more hacking.
893 *
894 * To add support for filtering on DECNET "areas" (network numbers)
895 * one would want to add a "mask" argument to this routine. That would
896 * make the filter even more inefficient, although one could be clever
897 * and not generate masking instructions if the mask is 0xFFFF.
898 */
899 static struct block *
900 gen_dnhostop(addr, dir, base_off)
901 bpf_u_int32 addr;
902 int dir;
903 u_int base_off;
904 {
905 struct block *b0, *b1, *b2, *tmp;
906 u_int offset_lh; /* offset if long header is received */
907 u_int offset_sh; /* offset if short header is received */
908
909 switch (dir) {
910
911 case Q_DST:
912 offset_sh = 1; /* follows flags */
913 offset_lh = 7; /* flgs,darea,dsubarea,HIORD */
914 break;
915
916 case Q_SRC:
917 offset_sh = 3; /* follows flags, dstnode */
918 offset_lh = 15; /* flgs,darea,dsubarea,did,sarea,ssub,HIORD */
919 break;
920
921 case Q_AND:
922 /* Inefficient because we do our Calvinball dance twice */
923 b0 = gen_dnhostop(addr, Q_SRC, base_off);
924 b1 = gen_dnhostop(addr, Q_DST, base_off);
925 gen_and(b0, b1);
926 return b1;
927
928 case Q_OR:
929 case Q_DEFAULT:
930 /* Inefficient because we do our Calvinball dance twice */
931 b0 = gen_dnhostop(addr, Q_SRC, base_off);
932 b1 = gen_dnhostop(addr, Q_DST, base_off);
933 gen_or(b0, b1);
934 return b1;
935
936 default:
937 abort();
938 }
939 b0 = gen_linktype(ETHERTYPE_DN);
940 /* Check for pad = 1, long header case */
941 tmp = gen_mcmp(base_off + 2, BPF_H,
942 (bpf_int32)ntohs(0x0681), (bpf_int32)ntohs(0x07FF));
943 b1 = gen_cmp(base_off + 2 + 1 + offset_lh,
944 BPF_H, (bpf_int32)ntohs(addr));
945 gen_and(tmp, b1);
946 /* Check for pad = 0, long header case */
947 tmp = gen_mcmp(base_off + 2, BPF_B, (bpf_int32)0x06, (bpf_int32)0x7);
948 b2 = gen_cmp(base_off + 2 + offset_lh, BPF_H, (bpf_int32)ntohs(addr));
949 gen_and(tmp, b2);
950 gen_or(b2, b1);
951 /* Check for pad = 1, short header case */
952 tmp = gen_mcmp(base_off + 2, BPF_H,
953 (bpf_int32)ntohs(0x0281), (bpf_int32)ntohs(0x07FF));
954 b2 = gen_cmp(base_off + 2 + 1 + offset_sh,
955 BPF_H, (bpf_int32)ntohs(addr));
956 gen_and(tmp, b2);
957 gen_or(b2, b1);
958 /* Check for pad = 0, short header case */
959 tmp = gen_mcmp(base_off + 2, BPF_B, (bpf_int32)0x02, (bpf_int32)0x7);
960 b2 = gen_cmp(base_off + 2 + offset_sh, BPF_H, (bpf_int32)ntohs(addr));
961 gen_and(tmp, b2);
962 gen_or(b2, b1);
963
964 /* Combine with test for linktype */
965 gen_and(b0, b1);
966 return b1;
967 }
968
969 static struct block *
970 gen_host(addr, mask, proto, dir)
971 bpf_u_int32 addr;
972 bpf_u_int32 mask;
973 int proto;
974 int dir;
975 {
976 struct block *b0, *b1;
977
978 switch (proto) {
979
980 case Q_DEFAULT:
981 b0 = gen_host(addr, mask, Q_IP, dir);
982 b1 = gen_host(addr, mask, Q_ARP, dir);
983 gen_or(b0, b1);
984 b0 = gen_host(addr, mask, Q_RARP, dir);
985 gen_or(b1, b0);
986 return b0;
987
988 case Q_IP:
989 return gen_hostop(addr, mask, dir, ETHERTYPE_IP,
990 off_nl + 12, off_nl + 16);
991
992 case Q_RARP:
993 return gen_hostop(addr, mask, dir, ETHERTYPE_REVARP,
994 off_nl + 14, off_nl + 24);
995
996 case Q_ARP:
997 return gen_hostop(addr, mask, dir, ETHERTYPE_ARP,
998 off_nl + 14, off_nl + 24);
999
1000 case Q_TCP:
1001 bpf_error("'tcp' modifier applied to host");
1002
1003 case Q_UDP:
1004 bpf_error("'udp' modifier applied to host");
1005
1006 case Q_ICMP:
1007 bpf_error("'icmp' modifier applied to host");
1008
1009 case Q_IGMP:
1010 bpf_error("'igmp' modifier applied to host");
1011
1012 case Q_IGRP:
1013 bpf_error("'igrp' modifier applied to host");
1014
1015 case Q_PIM:
1016 bpf_error("'pim' modifier applied to host");
1017
1018 case Q_ATALK:
1019 bpf_error("ATALK host filtering not implemented");
1020
1021 case Q_DECNET:
1022 return gen_dnhostop(addr, dir, off_nl);
1023
1024 case Q_SCA:
1025 bpf_error("SCA host filtering not implemented");
1026
1027 case Q_LAT:
1028 bpf_error("LAT host filtering not implemented");
1029
1030 case Q_MOPDL:
1031 bpf_error("MOPDL host filtering not implemented");
1032
1033 case Q_MOPRC:
1034 bpf_error("MOPRC host filtering not implemented");
1035
1036 #ifdef INET6
1037 case Q_IPV6:
1038 bpf_error("'ip6' modifier applied to ip host");
1039
1040 case Q_ICMPV6:
1041 bpf_error("'icmp6' modifier applied to host");
1042 #endif /* INET6 */
1043
1044 case Q_AH:
1045 bpf_error("'ah' modifier applied to host");
1046
1047 case Q_ESP:
1048 bpf_error("'esp' modifier applied to host");
1049
1050 default:
1051 abort();
1052 }
1053 /* NOTREACHED */
1054 }
1055
1056 #ifdef INET6
1057 static struct block *
1058 gen_host6(addr, mask, proto, dir)
1059 struct in6_addr *addr;
1060 struct in6_addr *mask;
1061 int proto;
1062 int dir;
1063 {
1064 struct block *b0, *b1;
1065
1066 switch (proto) {
1067
1068 case Q_DEFAULT:
1069 return gen_host6(addr, mask, Q_IPV6, dir);
1070
1071 case Q_IP:
1072 bpf_error("'ip' modifier applied to ip6 host");
1073
1074 case Q_RARP:
1075 bpf_error("'rarp' modifier applied to ip6 host");
1076
1077 case Q_ARP:
1078 bpf_error("'arp' modifier applied to ip6 host");
1079
1080 case Q_TCP:
1081 bpf_error("'tcp' modifier applied to host");
1082
1083 case Q_UDP:
1084 bpf_error("'udp' modifier applied to host");
1085
1086 case Q_ICMP:
1087 bpf_error("'icmp' modifier applied to host");
1088
1089 case Q_IGMP:
1090 bpf_error("'igmp' modifier applied to host");
1091
1092 case Q_IGRP:
1093 bpf_error("'igrp' modifier applied to host");
1094
1095 case Q_PIM:
1096 bpf_error("'pim' modifier applied to host");
1097
1098 case Q_ATALK:
1099 bpf_error("ATALK host filtering not implemented");
1100
1101 case Q_DECNET:
1102 bpf_error("'decnet' modifier applied to ip6 host");
1103
1104 case Q_SCA:
1105 bpf_error("SCA host filtering not implemented");
1106
1107 case Q_LAT:
1108 bpf_error("LAT host filtering not implemented");
1109
1110 case Q_MOPDL:
1111 bpf_error("MOPDL host filtering not implemented");
1112
1113 case Q_MOPRC:
1114 bpf_error("MOPRC host filtering not implemented");
1115
1116 case Q_IPV6:
1117 return gen_hostop6(addr, mask, dir, ETHERTYPE_IPV6,
1118 off_nl + 8, off_nl + 24);
1119
1120 case Q_ICMPV6:
1121 bpf_error("'icmp6' modifier applied to host");
1122
1123 case Q_AH:
1124 bpf_error("'ah' modifier applied to host");
1125
1126 case Q_ESP:
1127 bpf_error("'esp' modifier applied to host");
1128
1129 default:
1130 abort();
1131 }
1132 /* NOTREACHED */
1133 }
1134 #endif /*INET6*/
1135
1136 static struct block *
1137 gen_gateway(eaddr, alist, proto, dir)
1138 const u_char *eaddr;
1139 bpf_u_int32 **alist;
1140 int proto;
1141 int dir;
1142 {
1143 struct block *b0, *b1, *tmp;
1144
1145 if (dir != 0)
1146 bpf_error("direction applied to 'gateway'");
1147
1148 switch (proto) {
1149 case Q_DEFAULT:
1150 case Q_IP:
1151 case Q_ARP:
1152 case Q_RARP:
1153 if (linktype == DLT_EN10MB)
1154 b0 = gen_ehostop(eaddr, Q_OR);
1155 else if (linktype == DLT_FDDI)
1156 b0 = gen_fhostop(eaddr, Q_OR);
1157 else
1158 bpf_error(
1159 "'gateway' supported only on ethernet or FDDI");
1160
1161 b1 = gen_host(**alist++, 0xffffffff, proto, Q_OR);
1162 while (*alist) {
1163 tmp = gen_host(**alist++, 0xffffffff, proto, Q_OR);
1164 gen_or(b1, tmp);
1165 b1 = tmp;
1166 }
1167 gen_not(b1);
1168 gen_and(b0, b1);
1169 return b1;
1170 }
1171 bpf_error("illegal modifier of 'gateway'");
1172 /* NOTREACHED */
1173 }
1174
1175 struct block *
1176 gen_proto_abbrev(proto)
1177 int proto;
1178 {
1179 struct block *b0, *b1;
1180
1181 switch (proto) {
1182
1183 case Q_TCP:
1184 b1 = gen_proto(IPPROTO_TCP, Q_IP, Q_DEFAULT);
1185 #ifdef INET6
1186 b0 = gen_proto(IPPROTO_TCP, Q_IPV6, Q_DEFAULT);
1187 gen_or(b0, b1);
1188 #endif
1189 break;
1190
1191 case Q_UDP:
1192 b1 = gen_proto(IPPROTO_UDP, Q_IP, Q_DEFAULT);
1193 #ifdef INET6
1194 b0 = gen_proto(IPPROTO_UDP, Q_IPV6, Q_DEFAULT);
1195 gen_or(b0, b1);
1196 #endif
1197 break;
1198
1199 case Q_ICMP:
1200 b1 = gen_proto(IPPROTO_ICMP, Q_IP, Q_DEFAULT);
1201 break;
1202
1203 case Q_IGMP:
1204 b1 = gen_proto(2, Q_IP, Q_DEFAULT);
1205 break;
1206
1207 #ifndef IPPROTO_IGRP
1208 #define IPPROTO_IGRP 9
1209 #endif
1210 case Q_IGRP:
1211 b1 = gen_proto(IPPROTO_IGRP, Q_IP, Q_DEFAULT);
1212 gen_and(b0, b1);
1213 break;
1214
1215 #ifndef IPPROTO_PIM
1216 #define IPPROTO_PIM 103
1217 #endif
1218
1219 case Q_PIM:
1220 b1 = gen_proto(IPPROTO_PIM, Q_IP, Q_DEFAULT);
1221 #ifdef INET6
1222 b0 = gen_proto(IPPROTO_PIM, Q_IPV6, Q_DEFAULT);
1223 gen_or(b0, b1);
1224 #endif
1225 break;
1226
1227 case Q_IP:
1228 b1 = gen_linktype(ETHERTYPE_IP);
1229 break;
1230
1231 case Q_ARP:
1232 b1 = gen_linktype(ETHERTYPE_ARP);
1233 break;
1234
1235 case Q_RARP:
1236 b1 = gen_linktype(ETHERTYPE_REVARP);
1237 break;
1238
1239 case Q_LINK:
1240 bpf_error("link layer applied in wrong context");
1241
1242 case Q_ATALK:
1243 b1 = gen_linktype(ETHERTYPE_ATALK);
1244 break;
1245
1246 case Q_DECNET:
1247 b1 = gen_linktype(ETHERTYPE_DN);
1248 break;
1249
1250 case Q_SCA:
1251 b1 = gen_linktype(ETHERTYPE_SCA);
1252 break;
1253
1254 case Q_LAT:
1255 b1 = gen_linktype(ETHERTYPE_LAT);
1256 break;
1257
1258 case Q_MOPDL:
1259 b1 = gen_linktype(ETHERTYPE_MOPDL);
1260 break;
1261
1262 case Q_MOPRC:
1263 b1 = gen_linktype(ETHERTYPE_MOPRC);
1264 break;
1265
1266 #ifdef INET6
1267 case Q_IPV6:
1268 b1 = gen_linktype(ETHERTYPE_IPV6);
1269 break;
1270
1271 #ifndef IPPROTO_ICMPV6
1272 #define IPPROTO_ICMPV6 58
1273 #endif
1274 case Q_ICMPV6:
1275 b1 = gen_proto(IPPROTO_ICMPV6, Q_IPV6, Q_DEFAULT);
1276 break;
1277 #endif /* INET6 */
1278
1279 #ifndef IPPROTO_AH
1280 #define IPPROTO_AH 51
1281 #endif
1282 case Q_AH:
1283 b1 = gen_proto(IPPROTO_AH, Q_IP, Q_DEFAULT);
1284 #ifdef INET6
1285 b0 = gen_proto(IPPROTO_AH, Q_IPV6, Q_DEFAULT);
1286 gen_or(b0, b1);
1287 #endif
1288 break;
1289
1290 #ifndef IPPROTO_ESP
1291 #define IPPROTO_ESP 50
1292 #endif
1293 case Q_ESP:
1294 b1 = gen_proto(IPPROTO_ESP, Q_IP, Q_DEFAULT);
1295 #ifdef INET6
1296 b0 = gen_proto(IPPROTO_ESP, Q_IPV6, Q_DEFAULT);
1297 gen_or(b0, b1);
1298 #endif
1299 break;
1300
1301 default:
1302 abort();
1303 }
1304 return b1;
1305 }
1306
1307 static struct block *
1308 gen_ipfrag()
1309 {
1310 struct slist *s;
1311 struct block *b;
1312
1313 /* not ip frag */
1314 s = new_stmt(BPF_LD|BPF_H|BPF_ABS);
1315 s->s.k = off_nl + 6;
1316 b = new_block(JMP(BPF_JSET));
1317 b->s.k = 0x1fff;
1318 b->stmts = s;
1319 gen_not(b);
1320
1321 return b;
1322 }
1323
1324 static struct block *
1325 gen_portatom(off, v)
1326 int off;
1327 bpf_int32 v;
1328 {
1329 struct slist *s;
1330 struct block *b;
1331
1332 s = new_stmt(BPF_LDX|BPF_MSH|BPF_B);
1333 s->s.k = off_nl;
1334
1335 s->next = new_stmt(BPF_LD|BPF_IND|BPF_H);
1336 s->next->s.k = off_nl + off;
1337
1338 b = new_block(JMP(BPF_JEQ));
1339 b->stmts = s;
1340 b->s.k = v;
1341
1342 return b;
1343 }
1344
1345 #ifdef INET6
1346 static struct block *
1347 gen_portatom6(off, v)
1348 int off;
1349 bpf_int32 v;
1350 {
1351 return gen_cmp(off_nl + 40 + off, BPF_H, v);
1352 }
1353 #endif/*INET6*/
1354
1355 struct block *
1356 gen_portop(port, proto, dir)
1357 int port, proto, dir;
1358 {
1359 struct block *b0, *b1, *tmp;
1360
1361 /* ip proto 'proto' */
1362 tmp = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)proto);
1363 b0 = gen_ipfrag();
1364 gen_and(tmp, b0);
1365
1366 switch (dir) {
1367 case Q_SRC:
1368 b1 = gen_portatom(0, (bpf_int32)port);
1369 break;
1370
1371 case Q_DST:
1372 b1 = gen_portatom(2, (bpf_int32)port);
1373 break;
1374
1375 case Q_OR:
1376 case Q_DEFAULT:
1377 tmp = gen_portatom(0, (bpf_int32)port);
1378 b1 = gen_portatom(2, (bpf_int32)port);
1379 gen_or(tmp, b1);
1380 break;
1381
1382 case Q_AND:
1383 tmp = gen_portatom(0, (bpf_int32)port);
1384 b1 = gen_portatom(2, (bpf_int32)port);
1385 gen_and(tmp, b1);
1386 break;
1387
1388 default:
1389 abort();
1390 }
1391 gen_and(b0, b1);
1392
1393 return b1;
1394 }
1395
1396 static struct block *
1397 gen_port(port, ip_proto, dir)
1398 int port;
1399 int ip_proto;
1400 int dir;
1401 {
1402 struct block *b0, *b1, *tmp;
1403
1404 /* ether proto ip */
1405 b0 = gen_linktype(ETHERTYPE_IP);
1406
1407 switch (ip_proto) {
1408 case IPPROTO_UDP:
1409 case IPPROTO_TCP:
1410 b1 = gen_portop(port, ip_proto, dir);
1411 break;
1412
1413 case PROTO_UNDEF:
1414 tmp = gen_portop(port, IPPROTO_TCP, dir);
1415 b1 = gen_portop(port, IPPROTO_UDP, dir);
1416 gen_or(tmp, b1);
1417 break;
1418
1419 default:
1420 abort();
1421 }
1422 gen_and(b0, b1);
1423 return b1;
1424 }
1425
1426 #ifdef INET6
1427 struct block *
1428 gen_portop6(port, proto, dir)
1429 int port, proto, dir;
1430 {
1431 struct block *b0, *b1, *tmp;
1432
1433 /* ip proto 'proto' */
1434 b0 = gen_cmp(off_nl + 6, BPF_B, (bpf_int32)proto);
1435
1436 switch (dir) {
1437 case Q_SRC:
1438 b1 = gen_portatom6(0, (bpf_int32)port);
1439 break;
1440
1441 case Q_DST:
1442 b1 = gen_portatom6(2, (bpf_int32)port);
1443 break;
1444
1445 case Q_OR:
1446 case Q_DEFAULT:
1447 tmp = gen_portatom6(0, (bpf_int32)port);
1448 b1 = gen_portatom6(2, (bpf_int32)port);
1449 gen_or(tmp, b1);
1450 break;
1451
1452 case Q_AND:
1453 tmp = gen_portatom6(0, (bpf_int32)port);
1454 b1 = gen_portatom6(2, (bpf_int32)port);
1455 gen_and(tmp, b1);
1456 break;
1457
1458 default:
1459 abort();
1460 }
1461 gen_and(b0, b1);
1462
1463 return b1;
1464 }
1465
1466 static struct block *
1467 gen_port6(port, ip_proto, dir)
1468 int port;
1469 int ip_proto;
1470 int dir;
1471 {
1472 struct block *b0, *b1, *tmp;
1473
1474 /* ether proto ip */
1475 b0 = gen_linktype(ETHERTYPE_IPV6);
1476
1477 switch (ip_proto) {
1478 case IPPROTO_UDP:
1479 case IPPROTO_TCP:
1480 b1 = gen_portop6(port, ip_proto, dir);
1481 break;
1482
1483 case PROTO_UNDEF:
1484 tmp = gen_portop6(port, IPPROTO_TCP, dir);
1485 b1 = gen_portop6(port, IPPROTO_UDP, dir);
1486 gen_or(tmp, b1);
1487 break;
1488
1489 default:
1490 abort();
1491 }
1492 gen_and(b0, b1);
1493 return b1;
1494 }
1495 #endif /* INET6 */
1496
1497 static int
1498 lookup_proto(name, proto)
1499 register const char *name;
1500 register int proto;
1501 {
1502 register int v;
1503
1504 switch (proto) {
1505
1506 case Q_DEFAULT:
1507 case Q_IP:
1508 v = pcap_nametoproto(name);
1509 if (v == PROTO_UNDEF)
1510 bpf_error("unknown ip proto '%s'", name);
1511 break;
1512
1513 case Q_LINK:
1514 /* XXX should look up h/w protocol type based on linktype */
1515 v = pcap_nametoeproto(name);
1516 if (v == PROTO_UNDEF)
1517 bpf_error("unknown ether proto '%s'", name);
1518 break;
1519
1520 default:
1521 v = PROTO_UNDEF;
1522 break;
1523 }
1524 return v;
1525 }
1526
1527 struct stmt *
1528 gen_joinsp(s, n)
1529 struct stmt **s;
1530 int n;
1531 {
1532 }
1533
1534 struct block *
1535 gen_protochain(v, proto, dir)
1536 int v;
1537 int proto;
1538 int dir;
1539 {
1540 #ifdef NO_PROTOCHAIN
1541 return gen_proto(v, proto, dir);
1542 #else
1543 struct block *b0, *b;
1544 struct slist *s[100], *sp;
1545 int fix2, fix3, fix4, fix5;
1546 int ahcheck, again, end;
1547 int i, max;
1548 int reg1 = alloc_reg();
1549 int reg2 = alloc_reg();
1550
1551 memset(s, 0, sizeof(s));
1552 fix2 = fix3 = fix4 = fix5 = 0;
1553
1554 switch (proto) {
1555 case Q_IP:
1556 case Q_IPV6:
1557 break;
1558 case Q_DEFAULT:
1559 b0 = gen_protochain(v, Q_IP, dir);
1560 b = gen_protochain(v, Q_IPV6, dir);
1561 gen_or(b0, b);
1562 return b;
1563 default:
1564 bpf_error("bad protocol applied for 'protochain'");
1565 /*NOTREACHED*/
1566 }
1567
1568 no_optimize = 1; /*this code is not compatible with optimzer yet */
1569
1570 /*
1571 * s[0] is a dummy entry to protect other BPF insn from damaged
1572 * by s[fix] = foo with uninitialized variable "fix". It is somewhat
1573 * hard to find interdependency made by jump table fixup.
1574 */
1575 i = 0;
1576 s[i] = new_stmt(0); /*dummy*/
1577 i++;
1578
1579 switch (proto) {
1580 case Q_IP:
1581 b0 = gen_linktype(ETHERTYPE_IP);
1582
1583 /* A = ip->ip_p */
1584 s[i] = new_stmt(BPF_LD|BPF_ABS|BPF_B);
1585 s[i]->s.k = off_nl + 9;
1586 i++;
1587 /* X = ip->ip_hl << 2 */
1588 s[i] = new_stmt(BPF_LDX|BPF_MSH|BPF_B);
1589 s[i]->s.k = off_nl;
1590 i++;
1591 break;
1592 #ifdef INET6
1593 case Q_IPV6:
1594 b0 = gen_linktype(ETHERTYPE_IPV6);
1595
1596 /* A = ip6->ip_nxt */
1597 s[i] = new_stmt(BPF_LD|BPF_ABS|BPF_B);
1598 s[i]->s.k = off_nl + 6;
1599 i++;
1600 /* X = sizeof(struct ip6_hdr) */
1601 s[i] = new_stmt(BPF_LDX|BPF_IMM);
1602 s[i]->s.k = 40;
1603 i++;
1604 break;
1605 #endif
1606 default:
1607 bpf_error("unsupported proto to gen_protochain");
1608 /*NOTREACHED*/
1609 }
1610
1611 /* again: if (A == v) goto end; else fall through; */
1612 again = i;
1613 s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K);
1614 s[i]->s.k = v;
1615 s[i]->s.jt = NULL; /*later*/
1616 s[i]->s.jf = NULL; /*update in next stmt*/
1617 fix5 = i;
1618 i++;
1619
1620 #ifndef IPPROTO_NONE
1621 #define IPPROTO_NONE 59
1622 #endif
1623 /* if (A == IPPROTO_NONE) goto end */
1624 s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K);
1625 s[i]->s.jt = NULL; /*later*/
1626 s[i]->s.jf = NULL; /*update in next stmt*/
1627 s[i]->s.k = IPPROTO_NONE;
1628 s[fix5]->s.jf = s[i];
1629 fix2 = i;
1630 i++;
1631
1632 #ifdef INET6
1633 if (proto == Q_IPV6) {
1634 int v6start, v6end, v6advance, j;
1635
1636 v6start = i;
1637 /* if (A == IPPROTO_HOPOPTS) goto v6advance */
1638 s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K);
1639 s[i]->s.jt = NULL; /*later*/
1640 s[i]->s.jf = NULL; /*update in next stmt*/
1641 s[i]->s.k = IPPROTO_HOPOPTS;
1642 s[fix2]->s.jf = s[i];
1643 i++;
1644 /* if (A == IPPROTO_DSTOPTS) goto v6advance */
1645 s[i - 1]->s.jf = s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K);
1646 s[i]->s.jt = NULL; /*later*/
1647 s[i]->s.jf = NULL; /*update in next stmt*/
1648 s[i]->s.k = IPPROTO_DSTOPTS;
1649 i++;
1650 /* if (A == IPPROTO_ROUTING) goto v6advance */
1651 s[i - 1]->s.jf = s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K);
1652 s[i]->s.jt = NULL; /*later*/
1653 s[i]->s.jf = NULL; /*update in next stmt*/
1654 s[i]->s.k = IPPROTO_ROUTING;
1655 i++;
1656 /* if (A == IPPROTO_FRAGMENT) goto v6advance; else goto ahcheck; */
1657 s[i - 1]->s.jf = s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K);
1658 s[i]->s.jt = NULL; /*later*/
1659 s[i]->s.jf = NULL; /*later*/
1660 s[i]->s.k = IPPROTO_FRAGMENT;
1661 fix3 = i;
1662 v6end = i;
1663 i++;
1664
1665 /* v6advance: */
1666 v6advance = i;
1667
1668 /*
1669 * in short,
1670 * A = P[X + 1];
1671 * X = X + (P[X] + 1) * 8;
1672 */
1673 /* A = X */
1674 s[i] = new_stmt(BPF_MISC|BPF_TXA);
1675 i++;
1676 /* MEM[reg1] = A */
1677 s[i] = new_stmt(BPF_ST);
1678 s[i]->s.k = reg1;
1679 i++;
1680 /* A += 1 */
1681 s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
1682 s[i]->s.k = 1;
1683 i++;
1684 /* X = A */
1685 s[i] = new_stmt(BPF_MISC|BPF_TAX);
1686 i++;
1687 /* A = P[X + packet head]; */
1688 s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B);
1689 s[i]->s.k = off_nl;
1690 i++;
1691 /* MEM[reg2] = A */
1692 s[i] = new_stmt(BPF_ST);
1693 s[i]->s.k = reg2;
1694 i++;
1695 /* X = MEM[reg1] */
1696 s[i] = new_stmt(BPF_LDX|BPF_MEM);
1697 s[i]->s.k = reg1;
1698 i++;
1699 /* A = P[X + packet head] */
1700 s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B);
1701 s[i]->s.k = off_nl;
1702 i++;
1703 /* A += 1 */
1704 s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
1705 s[i]->s.k = 1;
1706 i++;
1707 /* A *= 8 */
1708 s[i] = new_stmt(BPF_ALU|BPF_MUL|BPF_K);
1709 s[i]->s.k = 8;
1710 i++;
1711 /* X = A; */
1712 s[i] = new_stmt(BPF_MISC|BPF_TAX);
1713 i++;
1714 /* A = MEM[reg2] */
1715 s[i] = new_stmt(BPF_LD|BPF_MEM);
1716 s[i]->s.k = reg2;
1717 i++;
1718
1719 /* goto again; (must use BPF_JA for backward jump) */
1720 s[i] = new_stmt(BPF_JMP|BPF_JA);
1721 s[i]->s.k = again - i - 1;
1722 s[i - 1]->s.jf = s[i];
1723 i++;
1724
1725 /* fixup */
1726 for (j = v6start; j <= v6end; j++)
1727 s[j]->s.jt = s[v6advance];
1728 } else
1729 #endif
1730 {
1731 /* nop */
1732 s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
1733 s[i]->s.k = 0;
1734 s[fix2]->s.jf = s[i];
1735 i++;
1736 }
1737
1738 /* ahcheck: */
1739 ahcheck = i;
1740 /* if (A == IPPROTO_AH) then fall through; else goto end; */
1741 s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K);
1742 s[i]->s.jt = NULL; /*later*/
1743 s[i]->s.jf = NULL; /*later*/
1744 s[i]->s.k = IPPROTO_AH;
1745 if (fix3)
1746 s[fix3]->s.jf = s[ahcheck];
1747 fix4 = i;
1748 i++;
1749
1750 /*
1751 * in short,
1752 * A = P[X + 1];
1753 * X = X + (P[X] + 2) * 4;
1754 */
1755 /* A = X */
1756 s[i - 1]->s.jt = s[i] = new_stmt(BPF_MISC|BPF_TXA);
1757 i++;
1758 /* MEM[reg1] = A */
1759 s[i] = new_stmt(BPF_ST);
1760 s[i]->s.k = reg1;
1761 i++;
1762 /* A += 1 */
1763 s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
1764 s[i]->s.k = 1;
1765 i++;
1766 /* X = A */
1767 s[i] = new_stmt(BPF_MISC|BPF_TAX);
1768 i++;
1769 /* A = P[X + packet head]; */
1770 s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B);
1771 s[i]->s.k = off_nl;
1772 i++;
1773 /* MEM[reg2] = A */
1774 s[i] = new_stmt(BPF_ST);
1775 s[i]->s.k = reg2;
1776 i++;
1777 /* X = MEM[reg1] */
1778 s[i] = new_stmt(BPF_LDX|BPF_MEM);
1779 s[i]->s.k = reg1;
1780 i++;
1781 /* A = P[X + packet head] */
1782 s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B);
1783 s[i]->s.k = off_nl;
1784 i++;
1785 /* A += 2 */
1786 s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
1787 s[i]->s.k = 2;
1788 i++;
1789 /* A *= 4 */
1790 s[i] = new_stmt(BPF_ALU|BPF_MUL|BPF_K);
1791 s[i]->s.k = 4;
1792 i++;
1793 /* X = A; */
1794 s[i] = new_stmt(BPF_MISC|BPF_TAX);
1795 i++;
1796 /* A = MEM[reg2] */
1797 s[i] = new_stmt(BPF_LD|BPF_MEM);
1798 s[i]->s.k = reg2;
1799 i++;
1800
1801 /* goto again; (must use BPF_JA for backward jump) */
1802 s[i] = new_stmt(BPF_JMP|BPF_JA);
1803 s[i]->s.k = again - i - 1;
1804 i++;
1805
1806 /* end: nop */
1807 end = i;
1808 s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
1809 s[i]->s.k = 0;
1810 s[fix2]->s.jt = s[end];
1811 s[fix4]->s.jf = s[end];
1812 s[fix5]->s.jt = s[end];
1813 i++;
1814
1815 /*
1816 * make slist chain
1817 */
1818 max = i;
1819 for (i = 0; i < max - 1; i++)
1820 s[i]->next = s[i + 1];
1821 s[max - 1]->next = NULL;
1822
1823 /*
1824 * emit final check
1825 */
1826 b = new_block(JMP(BPF_JEQ));
1827 b->stmts = s[1]; /*remember, s[0] is dummy*/
1828 b->s.k = v;
1829
1830 free_reg(reg1);
1831 free_reg(reg2);
1832
1833 gen_and(b0, b);
1834 return b;
1835 #endif
1836 }
1837
1838 static struct block *
1839 gen_proto(v, proto, dir)
1840 int v;
1841 int proto;
1842 int dir;
1843 {
1844 struct block *b0, *b1;
1845
1846 if (dir != Q_DEFAULT)
1847 bpf_error("direction applied to 'proto'");
1848
1849 switch (proto) {
1850 case Q_DEFAULT:
1851 #ifdef INET6
1852 b0 = gen_proto(v, Q_IP, dir);
1853 b1 = gen_proto(v, Q_IPV6, dir);
1854 gen_or(b0, b1);
1855 return b1;
1856 #else
1857 /*FALLTHROUGH*/
1858 #endif
1859 case Q_IP:
1860 b0 = gen_linktype(ETHERTYPE_IP);
1861 #ifndef CHASE_CHAIN
1862 b1 = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)v);
1863 #else
1864 b1 = gen_protochain(v, Q_IP);
1865 #endif
1866 gen_and(b0, b1);
1867 return b1;
1868
1869 case Q_ARP:
1870 bpf_error("arp does not encapsulate another protocol");
1871 /* NOTREACHED */
1872
1873 case Q_RARP:
1874 bpf_error("rarp does not encapsulate another protocol");
1875 /* NOTREACHED */
1876
1877 case Q_ATALK:
1878 bpf_error("atalk encapsulation is not specifiable");
1879 /* NOTREACHED */
1880
1881 case Q_DECNET:
1882 bpf_error("decnet encapsulation is not specifiable");
1883 /* NOTREACHED */
1884
1885 case Q_SCA:
1886 bpf_error("sca does not encapsulate another protocol");
1887 /* NOTREACHED */
1888
1889 case Q_LAT:
1890 bpf_error("lat does not encapsulate another protocol");
1891 /* NOTREACHED */
1892
1893 case Q_MOPRC:
1894 bpf_error("moprc does not encapsulate another protocol");
1895 /* NOTREACHED */
1896
1897 case Q_MOPDL:
1898 bpf_error("mopdl does not encapsulate another protocol");
1899 /* NOTREACHED */
1900
1901 case Q_LINK:
1902 return gen_linktype(v);
1903
1904 case Q_UDP:
1905 bpf_error("'udp proto' is bogus");
1906 /* NOTREACHED */
1907
1908 case Q_TCP:
1909 bpf_error("'tcp proto' is bogus");
1910 /* NOTREACHED */
1911
1912 case Q_ICMP:
1913 bpf_error("'icmp proto' is bogus");
1914 /* NOTREACHED */
1915
1916 case Q_IGMP:
1917 bpf_error("'igmp proto' is bogus");
1918 /* NOTREACHED */
1919
1920 case Q_IGRP:
1921 bpf_error("'igrp proto' is bogus");
1922 /* NOTREACHED */
1923
1924 case Q_PIM:
1925 bpf_error("'pim proto' is bogus");
1926 /* NOTREACHED */
1927
1928 #ifdef INET6
1929 case Q_IPV6:
1930 b0 = gen_linktype(ETHERTYPE_IPV6);
1931 #ifndef CHASE_CHAIN
1932 b1 = gen_cmp(off_nl + 6, BPF_B, (bpf_int32)v);
1933 #else
1934 b1 = gen_protochain(v, Q_IPV6);
1935 #endif
1936 gen_and(b0, b1);
1937 return b1;
1938
1939 case Q_ICMPV6:
1940 bpf_error("'icmp6 proto' is bogus");
1941 #endif /* INET6 */
1942
1943 case Q_AH:
1944 bpf_error("'ah proto' is bogus");
1945
1946 case Q_ESP:
1947 bpf_error("'ah proto' is bogus");
1948
1949 default:
1950 abort();
1951 /* NOTREACHED */
1952 }
1953 /* NOTREACHED */
1954 }
1955
1956 struct block *
1957 gen_scode(name, q)
1958 register const char *name;
1959 struct qual q;
1960 {
1961 int proto = q.proto;
1962 int dir = q.dir;
1963 int tproto;
1964 u_char *eaddr;
1965 bpf_u_int32 mask, addr, **alist;
1966 #ifdef INET6
1967 int tproto6;
1968 struct sockaddr_in *sin;
1969 struct sockaddr_in6 *sin6;
1970 struct addrinfo *res, *res0;
1971 struct in6_addr mask128;
1972 #endif /*INET6*/
1973 struct block *b, *tmp;
1974 int port, real_proto;
1975
1976 switch (q.addr) {
1977
1978 case Q_NET:
1979 addr = pcap_nametonetaddr(name);
1980 if (addr == 0)
1981 bpf_error("unknown network '%s'", name);
1982 /* Left justify network addr and calculate its network mask */
1983 mask = 0xffffffff;
1984 while (addr && (addr & 0xff000000) == 0) {
1985 addr <<= 8;
1986 mask <<= 8;
1987 }
1988 return gen_host(addr, mask, proto, dir);
1989
1990 case Q_DEFAULT:
1991 case Q_HOST:
1992 if (proto == Q_LINK) {
1993 switch (linktype) {
1994
1995 case DLT_EN10MB:
1996 eaddr = pcap_ether_hostton(name);
1997 if (eaddr == NULL)
1998 bpf_error(
1999 "unknown ether host '%s'", name);
2000 return gen_ehostop(eaddr, dir);
2001
2002 case DLT_FDDI:
2003 eaddr = pcap_ether_hostton(name);
2004 if (eaddr == NULL)
2005 bpf_error(
2006 "unknown FDDI host '%s'", name);
2007 return gen_fhostop(eaddr, dir);
2008
2009 default:
2010 bpf_error(
2011 "only ethernet/FDDI supports link-level host name");
2012 break;
2013 }
2014 } else if (proto == Q_DECNET) {
2015 unsigned short dn_addr = __pcap_nametodnaddr(name);
2016 /*
2017 * I don't think DECNET hosts can be multihomed, so
2018 * there is no need to build up a list of addresses
2019 */
2020 return (gen_host(dn_addr, 0, proto, dir));
2021 } else {
2022 #ifndef INET6
2023 alist = pcap_nametoaddr(name);
2024 if (alist == NULL || *alist == NULL)
2025 bpf_error("unknown host '%s'", name);
2026 tproto = proto;
2027 if (off_linktype == -1 && tproto == Q_DEFAULT)
2028 tproto = Q_IP;
2029 b = gen_host(**alist++, 0xffffffff, tproto, dir);
2030 while (*alist) {
2031 tmp = gen_host(**alist++, 0xffffffff,
2032 tproto, dir);
2033 gen_or(b, tmp);
2034 b = tmp;
2035 }
2036 return b;
2037 #else
2038 memset(&mask128, 0xff, sizeof(mask128));
2039 res0 = res = pcap_nametoaddr(name);
2040 if (res == NULL)
2041 bpf_error("unknown host '%s'", name);
2042 b = tmp = NULL;
2043 tproto = tproto6 = proto;
2044 if (off_linktype == -1 && tproto == Q_DEFAULT) {
2045 tproto = Q_IP;
2046 tproto6 = Q_IPV6;
2047 }
2048 while (res) {
2049 switch (res->ai_family) {
2050 case AF_INET:
2051 sin = (struct sockaddr_in *)
2052 res->ai_addr;
2053 tmp = gen_host(ntohl(sin->sin_addr.s_addr),
2054 0xffffffff, tproto, dir);
2055 break;
2056 case AF_INET6:
2057 sin6 = (struct sockaddr_in6 *)
2058 res->ai_addr;
2059 tmp = gen_host6(&sin6->sin6_addr,
2060 &mask128, tproto6, dir);
2061 break;
2062 }
2063 if (b)
2064 gen_or(b, tmp);
2065 b = tmp;
2066
2067 res = res->ai_next;
2068 }
2069 freeaddrinfo(res0);
2070 return b;
2071 #endif /*INET6*/
2072 }
2073
2074 case Q_PORT:
2075 if (proto != Q_DEFAULT && proto != Q_UDP && proto != Q_TCP)
2076 bpf_error("illegal qualifier of 'port'");
2077 if (pcap_nametoport(name, &port, &real_proto) == 0)
2078 bpf_error("unknown port '%s'", name);
2079 if (proto == Q_UDP) {
2080 if (real_proto == IPPROTO_TCP)
2081 bpf_error("port '%s' is tcp", name);
2082 else
2083 /* override PROTO_UNDEF */
2084 real_proto = IPPROTO_UDP;
2085 }
2086 if (proto == Q_TCP) {
2087 if (real_proto == IPPROTO_UDP)
2088 bpf_error("port '%s' is udp", name);
2089 else
2090 /* override PROTO_UNDEF */
2091 real_proto = IPPROTO_TCP;
2092 }
2093 #ifndef INET6
2094 return gen_port(port, real_proto, dir);
2095 #else
2096 {
2097 struct block *b;
2098 b = gen_port(port, real_proto, dir);
2099 gen_or(gen_port6(port, real_proto, dir), b);
2100 return b;
2101 }
2102 #endif /* INET6 */
2103
2104 case Q_GATEWAY:
2105 #ifndef INET6
2106 eaddr = pcap_ether_hostton(name);
2107 if (eaddr == NULL)
2108 bpf_error("unknown ether host: %s", name);
2109
2110 alist = pcap_nametoaddr(name);
2111 if (alist == NULL || *alist == NULL)
2112 bpf_error("unknown host '%s'", name);
2113 return gen_gateway(eaddr, alist, proto, dir);
2114 #else
2115 bpf_error("'gateway' not supported in this configuration");
2116 #endif /*INET6*/
2117
2118 case Q_PROTO:
2119 real_proto = lookup_proto(name, proto);
2120 if (real_proto >= 0)
2121 return gen_proto(real_proto, proto, dir);
2122 else
2123 bpf_error("unknown protocol: %s", name);
2124
2125 case Q_PROTOCHAIN:
2126 real_proto = lookup_proto(name, proto);
2127 if (real_proto >= 0)
2128 return gen_protochain(real_proto, proto, dir);
2129 else
2130 bpf_error("unknown protocol: %s", name);
2131
2132
2133 case Q_UNDEF:
2134 syntax();
2135 /* NOTREACHED */
2136 }
2137 abort();
2138 /* NOTREACHED */
2139 }
2140
2141 struct block *
2142 gen_mcode(s1, s2, masklen, q)
2143 register const char *s1, *s2;
2144 register int masklen;
2145 struct qual q;
2146 {
2147 register int nlen, mlen;
2148 bpf_u_int32 n, m;
2149
2150 nlen = __pcap_atoin(s1, &n);
2151 /* Promote short ipaddr */
2152 n <<= 32 - nlen;
2153
2154 if (s2 != NULL) {
2155 mlen = __pcap_atoin(s2, &m);
2156 /* Promote short ipaddr */
2157 m <<= 32 - mlen;
2158 if ((n & ~m) != 0)
2159 bpf_error("non-network bits set in \"%s mask %s\"",
2160 s1, s2);
2161 } else {
2162 /* Convert mask len to mask */
2163 if (masklen > 32)
2164 bpf_error("mask length must be <= 32");
2165 m = 0xffffffff << (32 - masklen);
2166 if ((n & ~m) != 0)
2167 bpf_error("non-network bits set in \"%s/%d\"",
2168 s1, masklen);
2169 }
2170
2171 switch (q.addr) {
2172
2173 case Q_NET:
2174 return gen_host(n, m, q.proto, q.dir);
2175
2176 default:
2177 bpf_error("Mask syntax for networks only");
2178 /* NOTREACHED */
2179 }
2180 }
2181
2182 struct block *
2183 gen_ncode(s, v, q)
2184 register const char *s;
2185 bpf_u_int32 v;
2186 struct qual q;
2187 {
2188 bpf_u_int32 mask;
2189 int proto = q.proto;
2190 int dir = q.dir;
2191 register int vlen;
2192
2193 if (s == NULL)
2194 vlen = 32;
2195 else if (q.proto == Q_DECNET)
2196 vlen = __pcap_atodn(s, &v);
2197 else
2198 vlen = __pcap_atoin(s, &v);
2199
2200 switch (q.addr) {
2201
2202 case Q_DEFAULT:
2203 case Q_HOST:
2204 case Q_NET:
2205 if (proto == Q_DECNET)
2206 return gen_host(v, 0, proto, dir);
2207 else if (proto == Q_LINK) {
2208 bpf_error("illegal link layer address");
2209 } else {
2210 mask = 0xffffffff;
2211 if (s == NULL && q.addr == Q_NET) {
2212 /* Promote short net number */
2213 while (v && (v & 0xff000000) == 0) {
2214 v <<= 8;
2215 mask <<= 8;
2216 }
2217 } else {
2218 /* Promote short ipaddr */
2219 v <<= 32 - vlen;
2220 mask <<= 32 - vlen;
2221 }
2222 return gen_host(v, mask, proto, dir);
2223 }
2224
2225 case Q_PORT:
2226 if (proto == Q_UDP)
2227 proto = IPPROTO_UDP;
2228 else if (proto == Q_TCP)
2229 proto = IPPROTO_TCP;
2230 else if (proto == Q_DEFAULT)
2231 proto = PROTO_UNDEF;
2232 else
2233 bpf_error("illegal qualifier of 'port'");
2234
2235 #ifndef INET6
2236 return gen_port((int)v, proto, dir);
2237 #else
2238 {
2239 struct block *b;
2240 b = gen_port((int)v, proto, dir);
2241 gen_or(gen_port6((int)v, proto, dir), b);
2242 return b;
2243 }
2244 #endif /* INET6 */
2245
2246 case Q_GATEWAY:
2247 bpf_error("'gateway' requires a name");
2248 /* NOTREACHED */
2249
2250 case Q_PROTO:
2251 return gen_proto((int)v, proto, dir);
2252
2253 case Q_PROTOCHAIN:
2254 return gen_protochain((int)v, proto, dir);
2255
2256 case Q_UNDEF:
2257 syntax();
2258 /* NOTREACHED */
2259
2260 default:
2261 abort();
2262 /* NOTREACHED */
2263 }
2264 /* NOTREACHED */
2265 }
2266
2267 #ifdef INET6
2268 struct block *
2269 gen_mcode6(s1, s2, masklen, q)
2270 register const char *s1, *s2;
2271 register int masklen;
2272 struct qual q;
2273 {
2274 struct addrinfo *res;
2275 struct in6_addr *addr;
2276 struct in6_addr mask;
2277 struct block *b;
2278 u_int32_t *a, *m;
2279
2280 if (s2)
2281 bpf_error("no mask %s supported", s2);
2282
2283 res = pcap_nametoaddr(s1);
2284 if (!res)
2285 bpf_error("invalid ip6 address %s", s1);
2286 if (res->ai_next)
2287 bpf_error("%s resolved to multiple address", s1);
2288 addr = &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr;
2289
2290 if (sizeof(mask) * 8 < masklen)
2291 bpf_error("mask length must be <= %u", (unsigned int)(sizeof(mask) * 8));
2292 memset(&mask, 0xff, masklen / 8);
2293 if (masklen % 8) {
2294 mask.s6_addr[masklen / 8] =
2295 (0xff << (8 - masklen % 8)) & 0xff;
2296 }
2297
2298 a = (u_int32_t *)addr;
2299 m = (u_int32_t *)&mask;
2300 if ((a[0] & ~m[0]) || (a[1] & ~m[1])
2301 || (a[2] & ~m[2]) || (a[3] & ~m[3])) {
2302 bpf_error("non-network bits set in \"%s/%d\"", s1, masklen);
2303 }
2304
2305 switch (q.addr) {
2306
2307 case Q_DEFAULT:
2308 case Q_HOST:
2309 if (masklen != 128)
2310 bpf_error("Mask syntax for networks only");
2311 /* FALLTHROUGH */
2312
2313 case Q_NET:
2314 b = gen_host6(addr, &mask, q.proto, q.dir);
2315 freeaddrinfo(res);
2316 return b;
2317
2318 default:
2319 bpf_error("invalid qualifier against IPv6 address");
2320 /* NOTREACHED */
2321 }
2322 }
2323 #endif /*INET6*/
2324
2325 struct block *
2326 gen_ecode(eaddr, q)
2327 register const u_char *eaddr;
2328 struct qual q;
2329 {
2330 if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) && q.proto == Q_LINK) {
2331 if (linktype == DLT_EN10MB)
2332 return gen_ehostop(eaddr, (int)q.dir);
2333 if (linktype == DLT_FDDI)
2334 return gen_fhostop(eaddr, (int)q.dir);
2335 }
2336 bpf_error("ethernet address used in non-ether expression");
2337 /* NOTREACHED */
2338 }
2339
2340 void
2341 sappend(s0, s1)
2342 struct slist *s0, *s1;
2343 {
2344 /*
2345 * This is definitely not the best way to do this, but the
2346 * lists will rarely get long.
2347 */
2348 while (s0->next)
2349 s0 = s0->next;
2350 s0->next = s1;
2351 }
2352
2353 static struct slist *
2354 xfer_to_x(a)
2355 struct arth *a;
2356 {
2357 struct slist *s;
2358
2359 s = new_stmt(BPF_LDX|BPF_MEM);
2360 s->s.k = a->regno;
2361 return s;
2362 }
2363
2364 static struct slist *
2365 xfer_to_a(a)
2366 struct arth *a;
2367 {
2368 struct slist *s;
2369
2370 s = new_stmt(BPF_LD|BPF_MEM);
2371 s->s.k = a->regno;
2372 return s;
2373 }
2374
2375 struct arth *
2376 gen_load(proto, index, size)
2377 int proto;
2378 struct arth *index;
2379 int size;
2380 {
2381 struct slist *s, *tmp;
2382 struct block *b;
2383 int regno = alloc_reg();
2384
2385 free_reg(index->regno);
2386 switch (size) {
2387
2388 default:
2389 bpf_error("data size must be 1, 2, or 4");
2390
2391 case 1:
2392 size = BPF_B;
2393 break;
2394
2395 case 2:
2396 size = BPF_H;
2397 break;
2398
2399 case 4:
2400 size = BPF_W;
2401 break;
2402 }
2403 switch (proto) {
2404 default:
2405 bpf_error("unsupported index operation");
2406
2407 case Q_LINK:
2408 s = xfer_to_x(index);
2409 tmp = new_stmt(BPF_LD|BPF_IND|size);
2410 sappend(s, tmp);
2411 sappend(index->s, s);
2412 break;
2413
2414 case Q_IP:
2415 case Q_ARP:
2416 case Q_RARP:
2417 case Q_ATALK:
2418 case Q_DECNET:
2419 case Q_SCA:
2420 case Q_LAT:
2421 case Q_MOPRC:
2422 case Q_MOPDL:
2423 #ifdef INET6
2424 case Q_IPV6:
2425 #endif
2426 /* XXX Note that we assume a fixed link header here. */
2427 s = xfer_to_x(index);
2428 tmp = new_stmt(BPF_LD|BPF_IND|size);
2429 tmp->s.k = off_nl;
2430 sappend(s, tmp);
2431 sappend(index->s, s);
2432
2433 b = gen_proto_abbrev(proto);
2434 if (index->b)
2435 gen_and(index->b, b);
2436 index->b = b;
2437 break;
2438
2439 case Q_TCP:
2440 case Q_UDP:
2441 case Q_ICMP:
2442 case Q_IGMP:
2443 case Q_IGRP:
2444 case Q_PIM:
2445 s = new_stmt(BPF_LDX|BPF_MSH|BPF_B);
2446 s->s.k = off_nl;
2447 sappend(s, xfer_to_a(index));
2448 sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X));
2449 sappend(s, new_stmt(BPF_MISC|BPF_TAX));
2450 sappend(s, tmp = new_stmt(BPF_LD|BPF_IND|size));
2451 tmp->s.k = off_nl;
2452 sappend(index->s, s);
2453
2454 gen_and(gen_proto_abbrev(proto), b = gen_ipfrag());
2455 if (index->b)
2456 gen_and(index->b, b);
2457 #ifdef INET6
2458 gen_and(gen_proto_abbrev(Q_IP), b);
2459 #endif
2460 index->b = b;
2461 break;
2462 #ifdef INET6
2463 case Q_ICMPV6:
2464 bpf_error("IPv6 upper-layer protocol is not supported by proto[x]");
2465 /*NOTREACHED*/
2466 #endif
2467 }
2468 index->regno = regno;
2469 s = new_stmt(BPF_ST);
2470 s->s.k = regno;
2471 sappend(index->s, s);
2472
2473 return index;
2474 }
2475
2476 struct block *
2477 gen_relation(code, a0, a1, reversed)
2478 int code;
2479 struct arth *a0, *a1;
2480 int reversed;
2481 {
2482 struct slist *s0, *s1, *s2;
2483 struct block *b, *tmp;
2484
2485 s0 = xfer_to_x(a1);
2486 s1 = xfer_to_a(a0);
2487 s2 = new_stmt(BPF_ALU|BPF_SUB|BPF_X);
2488 b = new_block(JMP(code));
2489 if (code == BPF_JGT || code == BPF_JGE) {
2490 reversed = !reversed;
2491 b->s.k = 0x80000000;
2492 }
2493 if (reversed)
2494 gen_not(b);
2495
2496 sappend(s1, s2);
2497 sappend(s0, s1);
2498 sappend(a1->s, s0);
2499 sappend(a0->s, a1->s);
2500
2501 b->stmts = a0->s;
2502
2503 free_reg(a0->regno);
2504 free_reg(a1->regno);
2505
2506 /* 'and' together protocol checks */
2507 if (a0->b) {
2508 if (a1->b) {
2509 gen_and(a0->b, tmp = a1->b);
2510 }
2511 else
2512 tmp = a0->b;
2513 } else
2514 tmp = a1->b;
2515
2516 if (tmp)
2517 gen_and(tmp, b);
2518
2519 return b;
2520 }
2521
2522 struct arth *
2523 gen_loadlen()
2524 {
2525 int regno = alloc_reg();
2526 struct arth *a = (struct arth *)newchunk(sizeof(*a));
2527 struct slist *s;
2528
2529 s = new_stmt(BPF_LD|BPF_LEN);
2530 s->next = new_stmt(BPF_ST);
2531 s->next->s.k = regno;
2532 a->s = s;
2533 a->regno = regno;
2534
2535 return a;
2536 }
2537
2538 struct arth *
2539 gen_loadi(val)
2540 int val;
2541 {
2542 struct arth *a;
2543 struct slist *s;
2544 int reg;
2545
2546 a = (struct arth *)newchunk(sizeof(*a));
2547
2548 reg = alloc_reg();
2549
2550 s = new_stmt(BPF_LD|BPF_IMM);
2551 s->s.k = val;
2552 s->next = new_stmt(BPF_ST);
2553 s->next->s.k = reg;
2554 a->s = s;
2555 a->regno = reg;
2556
2557 return a;
2558 }
2559
2560 struct arth *
2561 gen_neg(a)
2562 struct arth *a;
2563 {
2564 struct slist *s;
2565
2566 s = xfer_to_a(a);
2567 sappend(a->s, s);
2568 s = new_stmt(BPF_ALU|BPF_NEG);
2569 s->s.k = 0;
2570 sappend(a->s, s);
2571 s = new_stmt(BPF_ST);
2572 s->s.k = a->regno;
2573 sappend(a->s, s);
2574
2575 return a;
2576 }
2577
2578 struct arth *
2579 gen_arth(code, a0, a1)
2580 int code;
2581 struct arth *a0, *a1;
2582 {
2583 struct slist *s0, *s1, *s2;
2584
2585 s0 = xfer_to_x(a1);
2586 s1 = xfer_to_a(a0);
2587 s2 = new_stmt(BPF_ALU|BPF_X|code);
2588
2589 sappend(s1, s2);
2590 sappend(s0, s1);
2591 sappend(a1->s, s0);
2592 sappend(a0->s, a1->s);
2593
2594 free_reg(a1->regno);
2595
2596 s0 = new_stmt(BPF_ST);
2597 a0->regno = s0->s.k = alloc_reg();
2598 sappend(a0->s, s0);
2599
2600 return a0;
2601 }
2602
2603 /*
2604 * Here we handle simple allocation of the scratch registers.
2605 * If too many registers are alloc'd, the allocator punts.
2606 */
2607 static int regused[BPF_MEMWORDS];
2608 static int curreg;
2609
2610 /*
2611 * Return the next free register.
2612 */
2613 static int
2614 alloc_reg()
2615 {
2616 int n = BPF_MEMWORDS;
2617
2618 while (--n >= 0) {
2619 if (regused[curreg])
2620 curreg = (curreg + 1) % BPF_MEMWORDS;
2621 else {
2622 regused[curreg] = 1;
2623 return curreg;
2624 }
2625 }
2626 bpf_error("too many registers needed to evaluate expression");
2627 /* NOTREACHED */
2628 }
2629
2630 /*
2631 * Return a register to the table so it can
2632 * be used later.
2633 */
2634 static void
2635 free_reg(n)
2636 int n;
2637 {
2638 regused[n] = 0;
2639 }
2640
2641 static struct block *
2642 gen_len(jmp, n)
2643 int jmp, n;
2644 {
2645 struct slist *s;
2646 struct block *b;
2647
2648 s = new_stmt(BPF_LD|BPF_LEN);
2649 b = new_block(JMP(jmp));
2650 b->stmts = s;
2651 b->s.k = n;
2652
2653 return b;
2654 }
2655
2656 struct block *
2657 gen_greater(n)
2658 int n;
2659 {
2660 return gen_len(BPF_JGE, n);
2661 }
2662
2663 struct block *
2664 gen_less(n)
2665 int n;
2666 {
2667 struct block *b;
2668
2669 b = gen_len(BPF_JGT, n);
2670 gen_not(b);
2671
2672 return b;
2673 }
2674
2675 struct block *
2676 gen_byteop(op, idx, val)
2677 int op, idx, val;
2678 {
2679 struct block *b;
2680 struct slist *s;
2681
2682 switch (op) {
2683 default:
2684 abort();
2685
2686 case '=':
2687 return gen_cmp((u_int)idx, BPF_B, (bpf_int32)val);
2688
2689 case '<':
2690 b = gen_cmp((u_int)idx, BPF_B, (bpf_int32)val);
2691 b->s.code = JMP(BPF_JGE);
2692 gen_not(b);
2693 return b;
2694
2695 case '>':
2696 b = gen_cmp((u_int)idx, BPF_B, (bpf_int32)val);
2697 b->s.code = JMP(BPF_JGT);
2698 return b;
2699
2700 case '|':
2701 s = new_stmt(BPF_ALU|BPF_OR|BPF_K);
2702 break;
2703
2704 case '&':
2705 s = new_stmt(BPF_ALU|BPF_AND|BPF_K);
2706 break;
2707 }
2708 s->s.k = val;
2709 b = new_block(JMP(BPF_JEQ));
2710 b->stmts = s;
2711 gen_not(b);
2712
2713 return b;
2714 }
2715
2716 struct block *
2717 gen_broadcast(proto)
2718 int proto;
2719 {
2720 bpf_u_int32 hostmask;
2721 struct block *b0, *b1, *b2;
2722 static u_char ebroadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
2723
2724 switch (proto) {
2725
2726 case Q_DEFAULT:
2727 case Q_LINK:
2728 if (linktype == DLT_EN10MB)
2729 return gen_ehostop(ebroadcast, Q_DST);
2730 if (linktype == DLT_FDDI)
2731 return gen_fhostop(ebroadcast, Q_DST);
2732 bpf_error("not a broadcast link");
2733 break;
2734
2735 case Q_IP:
2736 b0 = gen_linktype(ETHERTYPE_IP);
2737 hostmask = ~netmask;
2738 b1 = gen_mcmp(off_nl + 16, BPF_W, (bpf_int32)0, hostmask);
2739 b2 = gen_mcmp(off_nl + 16, BPF_W,
2740 (bpf_int32)(~0 & hostmask), hostmask);
2741 gen_or(b1, b2);
2742 gen_and(b0, b2);
2743 return b2;
2744 }
2745 bpf_error("only ether/ip broadcast filters supported");
2746 }
2747
2748 struct block *
2749 gen_multicast(proto)
2750 int proto;
2751 {
2752 register struct block *b0, *b1;
2753 register struct slist *s;
2754
2755 switch (proto) {
2756
2757 case Q_DEFAULT:
2758 case Q_LINK:
2759 if (linktype == DLT_EN10MB) {
2760 /* ether[0] & 1 != 0 */
2761 s = new_stmt(BPF_LD|BPF_B|BPF_ABS);
2762 s->s.k = 0;
2763 b0 = new_block(JMP(BPF_JSET));
2764 b0->s.k = 1;
2765 b0->stmts = s;
2766 return b0;
2767 }
2768
2769 if (linktype == DLT_FDDI) {
2770 /* XXX TEST THIS: MIGHT NOT PORT PROPERLY XXX */
2771 /* fddi[1] & 1 != 0 */
2772 s = new_stmt(BPF_LD|BPF_B|BPF_ABS);
2773 s->s.k = 1;
2774 b0 = new_block(JMP(BPF_JSET));
2775 b0->s.k = 1;
2776 b0->stmts = s;
2777 return b0;
2778 }
2779 /* Link not known to support multicasts */
2780 break;
2781
2782 case Q_IP:
2783 b0 = gen_linktype(ETHERTYPE_IP);
2784 b1 = gen_cmp(off_nl + 16, BPF_B, (bpf_int32)224);
2785 b1->s.code = JMP(BPF_JGE);
2786 gen_and(b0, b1);
2787 return b1;
2788
2789 #ifdef INET6
2790 case Q_IPV6:
2791 b0 = gen_linktype(ETHERTYPE_IPV6);
2792 b1 = gen_cmp(off_nl + 24, BPF_B, (bpf_int32)255);
2793 gen_and(b0, b1);
2794 return b1;
2795 #endif /* INET6 */
2796 }
2797 bpf_error("only IP multicast filters supported on ethernet/FDDI");
2798 }
2799
2800 /*
2801 * generate command for inbound/outbound. It's here so we can
2802 * make it link-type specific. 'dir' = 0 implies "inbound",
2803 * = 1 implies "outbound".
2804 */
2805 struct block *
2806 gen_inbound(dir)
2807 int dir;
2808 {
2809 register struct block *b0;
2810
2811 b0 = gen_relation(BPF_JEQ,
2812 gen_load(Q_LINK, gen_loadi(0), 1),
2813 gen_loadi(0),
2814 dir);
2815 return (b0);
2816 }