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