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