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