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