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