1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 * Copyright 2012 Milan Jurik. All rights reserved. 25 */ 26 27 #include <stdio.h> 28 #include <stdlib.h> 29 #include <ctype.h> 30 #include <string.h> 31 #include <fcntl.h> 32 #include <string.h> 33 #include <sys/types.h> 34 #include <sys/time.h> 35 #include <stddef.h> 36 #include <unistd.h> 37 #include <stropts.h> 38 #include <sys/socket.h> 39 #include <sys/sockio.h> 40 #include <sys/vlan.h> 41 #include <net/if.h> 42 #include <netinet/in.h> 43 #include <netinet/ip.h> 44 #include <inet/ip6.h> 45 #include <inet/ip.h> 46 #include <netinet/if_ether.h> 47 #include <netinet/tcp.h> 48 #include <netinet/udp.h> 49 #include <netdb.h> 50 #include <arpa/inet.h> 51 #include <rpc/rpc.h> 52 #include <rpc/rpcent.h> 53 #include <sys/dlpi.h> 54 55 #include <snoop.h> 56 #include "snoop_vlan.h" 57 58 #define IPV4_ONLY 0 59 #define IPV6_ONLY 1 60 #define IPV4_AND_IPV6 2 61 62 /* 63 * The following constants represent the offsets in bytes from the beginning 64 * of the IP(v6) header of the source and destination IP(v6) addresses. 65 * These are useful when generating filter code. 66 */ 67 #define IPV4_SRCADDR_OFFSET 12 68 #define IPV4_DSTADDR_OFFSET 16 69 #define IPV6_SRCADDR_OFFSET 8 70 #define IPV6_DSTADDR_OFFSET 24 71 #define IP_VERS(p) (((*(uchar_t *)p) & 0xf0) >> 4) 72 #define MASKED_IPV4_VERS 0x40 73 #define MASKED_IPV6_VERS 0x60 74 #define IP_HDR_LEN(p) (((*(uchar_t *)p) & 0xf) * 4) 75 #define TCP_HDR_LEN(p) ((((*((uchar_t *)p+12)) >> 4) & 0xf) * 4) 76 77 /* 78 * Coding the constant below is tacky, but the compiler won't let us 79 * be more clever. E.g., &((struct ip *)0)->ip_xxx 80 */ 81 #define IP_PROTO_OF(p) (((uchar_t *)p)[9]) 82 83 /* 84 * AppleTalk uses 802.2 Ethernet encapsulation with LLC/SNAP headers, 85 * for 8 octets of overhead, and the common AppleTalk DDP Ethernet 86 * header is another 4 octets. 87 * 88 * The following constants represents the offsets in bytes from the beginning 89 * of the Ethernet payload to various parts of the DDP header. 90 */ 91 92 #define AT_DST_NET_OFFSET 12 93 #define AT_SRC_NET_OFFSET 14 94 #define AT_DST_NODE_OFFSET 16 95 #define AT_SRC_NODE_OFFSET 17 96 97 /* 98 * Offset for the source and destination zoneid in the ipnet header. 99 */ 100 #define IPNET_SRCZONE_OFFSET 16 101 #define IPNET_DSTZONE_OFFSET 20 102 103 int eaddr; /* need ethernet addr */ 104 105 int opstack; /* operand stack depth */ 106 107 /* 108 * These are the operators of the user-level filter. 109 * STOP ends execution of the filter expression and 110 * returns the truth value at the top of the stack. 111 * OP_LOAD_OCTET, OP_LOAD_SHORT and OP_LOAD_LONG pop 112 * an offset value from the stack and load a value of 113 * an appropriate size from the packet (octet, short or 114 * long). The offset is computed from a base value that 115 * may be set via the OP_OFFSET operators. 116 * OP_EQ, OP_NE, OP_GT, OP_GE, OP_LT, OP_LE pop two values 117 * from the stack and return the result of their comparison. 118 * OP_AND, OP_OR, OP_XOR pop two values from the stack and 119 * do perform a bitwise operation on them - returning a result 120 * to the stack. OP_NOT inverts the bits of the value on the 121 * stack. 122 * OP_BRFL and OP_BRTR branch to an offset in the code array 123 * depending on the value at the top of the stack: true (not 0) 124 * or false (0). 125 * OP_ADD, OP_SUB, OP_MUL, OP_DIV and OP_REM pop two values 126 * from the stack and perform arithmetic. 127 * The OP_OFFSET operators change the base from which the 128 * OP_LOAD operators compute their offsets. 129 * OP_OFFSET_ZERO sets the offset to zero - beginning of packet. 130 * OP_OFFSET_LINK sets the base to the first octet after 131 * the link (DLC) header. OP_OFFSET_IP, OP_OFFSET_TCP, 132 * and OP_OFFSET_UDP do the same for those headers - they 133 * set the offset base to the *end* of the header - not the 134 * beginning. The OP_OFFSET_RPC operator is a bit unusual. 135 * It points the base at the cached RPC header. For the 136 * purposes of selection, RPC reply headers look like call 137 * headers except for the direction value. 138 * OP_OFFSET_ETHERTYPE sets base according to the following 139 * algorithm: 140 * if the packet is not VLAN tagged, then set base to 141 * the ethertype field in the ethernet header 142 * else set base to the ethertype field of the VLAN header 143 * OP_OFFSET_POP restores the offset base to the value prior 144 * to the most recent OP_OFFSET call. 145 */ 146 enum optype { 147 OP_STOP = 0, 148 OP_LOAD_OCTET, 149 OP_LOAD_SHORT, 150 OP_LOAD_LONG, 151 OP_LOAD_CONST, 152 OP_LOAD_LENGTH, 153 OP_EQ, 154 OP_NE, 155 OP_GT, 156 OP_GE, 157 OP_LT, 158 OP_LE, 159 OP_AND, 160 OP_OR, 161 OP_XOR, 162 OP_NOT, 163 OP_BRFL, 164 OP_BRTR, 165 OP_ADD, 166 OP_SUB, 167 OP_MUL, 168 OP_DIV, 169 OP_REM, 170 OP_OFFSET_POP, 171 OP_OFFSET_ZERO, 172 OP_OFFSET_LINK, 173 OP_OFFSET_IP, 174 OP_OFFSET_TCP, 175 OP_OFFSET_UDP, 176 OP_OFFSET_RPC, 177 OP_OFFSET_SLP, 178 OP_OFFSET_ETHERTYPE, 179 OP_LAST 180 }; 181 182 static char *opnames[] = { 183 "STOP", 184 "LOAD_OCTET", 185 "LOAD_SHORT", 186 "LOAD_LONG", 187 "LOAD_CONST", 188 "LOAD_LENGTH", 189 "EQ", 190 "NE", 191 "GT", 192 "GE", 193 "LT", 194 "LE", 195 "AND", 196 "OR", 197 "XOR", 198 "NOT", 199 "BRFL", 200 "BRTR", 201 "ADD", 202 "SUB", 203 "MUL", 204 "DIV", 205 "REM", 206 "OFFSET_POP", 207 "OFFSET_ZERO", 208 "OFFSET_ETHER", 209 "OFFSET_IP", 210 "OFFSET_TCP", 211 "OFFSET_UDP", 212 "OFFSET_RPC", 213 "OP_OFFSET_SLP", 214 "OFFSET_ETHERTYPE", 215 "" 216 }; 217 218 #define MAXOPS 1024 219 #define MAXSS 64 220 static uint_t oplist[MAXOPS]; /* array of operators */ 221 static uint_t *curr_op; /* last op generated */ 222 223 extern int valid_slp(uchar_t *, int); /* decides if a SLP msg is valid */ 224 extern struct hostent *lgetipnodebyname(const char *, int, int, int *); 225 226 static void alternation(); 227 static uint_t chain(); 228 static void codeprint(); 229 static void emitop(); 230 static void emitval(); 231 static void expression(); 232 static struct xid_entry *find_rpc(); 233 static void optimize(); 234 static void ethertype_match(); 235 236 /* 237 * Get a ushort from a possibly unaligned character buffer. 238 * 239 * INPUTS: buffer - where the data is. Must be at least 240 * sizeof(uint16_t) bytes long. 241 * OUPUTS: An unsigned short that contains the data at buffer. 242 * No calls to ntohs or htons are done on the data. 243 */ 244 static uint16_t 245 get_u16(uchar_t *buffer) 246 { 247 uint8_t *bufraw = buffer; 248 249 /* 250 * ntohs is used only as a cheap way to flip the bits 251 * around on a little endian platform. The value will 252 * still be in host order or network order, depending on 253 * the order it was in when it was passed in. 254 */ 255 return (ntohs(bufraw[0] << 8 | bufraw[1])); 256 } 257 258 /* 259 * Returns the ULP for an IPv4 or IPv6 packet 260 * Assumes that the packet has already been checked to verify 261 * that it's either IPv4 or IPv6 262 * 263 * XXX Will need to be updated for AH and ESP 264 * XXX when IPsec is supported for v6. 265 */ 266 static uchar_t 267 ip_proto_of(uchar_t *ip) 268 { 269 uchar_t nxt; 270 boolean_t not_done = B_TRUE; 271 uchar_t *ptr = ip; 272 273 switch (IP_VERS(ip)) { 274 case IPV4_VERSION: 275 return (IP_PROTO_OF(ip)); 276 case IPV6_VERSION: 277 278 nxt = ip[6]; 279 ptr += 40; /* size of ip6 header */ 280 do { 281 switch (nxt) { 282 /* 283 * XXX Add IPsec headers here when supported for v6 284 * XXX (the AH will have a different size...) 285 */ 286 case IPPROTO_HOPOPTS: 287 case IPPROTO_ROUTING: 288 case IPPROTO_FRAGMENT: 289 case IPPROTO_DSTOPTS: 290 ptr += (8 * (ptr[1] + 1)); 291 nxt = *ptr; 292 break; 293 294 default: 295 not_done = B_FALSE; 296 break; 297 } 298 } while (not_done); 299 return (nxt); 300 default: 301 break; /* shouldn't get here... */ 302 } 303 return (0); 304 } 305 306 /* 307 * Returns the total IP header length. 308 * For v4, this includes any options present. 309 * For v6, this is the length of the IPv6 header plus 310 * any extension headers present. 311 * 312 * XXX Will need to be updated for AH and ESP 313 * XXX when IPsec is supported for v6. 314 */ 315 static int 316 ip_hdr_len(uchar_t *ip) 317 { 318 uchar_t nxt; 319 int hdr_len; 320 boolean_t not_done = B_TRUE; 321 int len = 40; /* IPv6 header size */ 322 uchar_t *ptr = ip; 323 324 switch (IP_VERS(ip)) { 325 case IPV4_VERSION: 326 return (IP_HDR_LEN(ip)); 327 case IPV6_VERSION: 328 nxt = ip[6]; 329 ptr += len; 330 do { 331 switch (nxt) { 332 /* 333 * XXX Add IPsec headers here when supported for v6 334 * XXX (the AH will have a different size...) 335 */ 336 case IPPROTO_HOPOPTS: 337 case IPPROTO_ROUTING: 338 case IPPROTO_FRAGMENT: 339 case IPPROTO_DSTOPTS: 340 hdr_len = (8 * (ptr[1] + 1)); 341 len += hdr_len; 342 ptr += hdr_len; 343 nxt = *ptr; 344 break; 345 346 default: 347 not_done = B_FALSE; 348 break; 349 } 350 } while (not_done); 351 return (len); 352 default: 353 break; 354 } 355 return (0); /* not IP */ 356 } 357 358 static void 359 codeprint() 360 { 361 uint_t *op; 362 363 printf("User filter:\n"); 364 365 for (op = oplist; *op; op++) { 366 if (*op <= OP_LAST) 367 printf("\t%2d: %s\n", op - oplist, opnames[*op]); 368 else 369 printf("\t%2d: (%d)\n", op - oplist, *op); 370 371 switch (*op) { 372 case OP_LOAD_CONST: 373 case OP_BRTR: 374 case OP_BRFL: 375 op++; 376 if ((int)*op < 0) 377 printf("\t%2d: 0x%08x (%d)\n", 378 op - oplist, *op, *op); 379 else 380 printf("\t%2d: %d (0x%08x)\n", 381 op - oplist, *op, *op); 382 } 383 } 384 printf("\t%2d: STOP\n", op - oplist); 385 printf("\n"); 386 } 387 388 389 /* 390 * Take a pass through the generated code and optimize 391 * branches. A branch true (BRTR) that has another BRTR 392 * at its destination can use the address of the destination 393 * BRTR. A BRTR that points to a BRFL (branch false) should 394 * point to the address following the BRFL. 395 * A similar optimization applies to BRFL operators. 396 */ 397 static void 398 optimize(uint_t *oplistp) 399 { 400 uint_t *op; 401 402 for (op = oplistp; *op; op++) { 403 switch (*op) { 404 case OP_LOAD_CONST: 405 op++; 406 break; 407 case OP_BRTR: 408 op++; 409 optimize(&oplist[*op]); 410 if (oplist[*op] == OP_BRFL) 411 *op += 2; 412 else if (oplist[*op] == OP_BRTR) 413 *op = oplist[*op + 1]; 414 break; 415 case OP_BRFL: 416 op++; 417 optimize(&oplist[*op]); 418 if (oplist[*op] == OP_BRTR) 419 *op += 2; 420 else if (oplist[*op] == OP_BRFL) 421 *op = oplist[*op + 1]; 422 break; 423 } 424 } 425 } 426 427 /* 428 * RPC packets are tough to filter. 429 * While the call packet has all the interesting 430 * info: program number, version, procedure etc, 431 * the reply packet has none of this information. 432 * If we want to do useful filtering based on this 433 * information then we have to stash the information 434 * from the call packet, and use the XID in the reply 435 * to find the stashed info. The stashed info is 436 * kept in a circular lifo, assuming that a call packet 437 * will be followed quickly by its reply. 438 */ 439 440 struct xid_entry { 441 unsigned x_xid; /* The XID (32 bits) */ 442 unsigned x_dir; /* CALL or REPLY */ 443 unsigned x_rpcvers; /* Protocol version (2) */ 444 unsigned x_prog; /* RPC program number */ 445 unsigned x_vers; /* RPC version number */ 446 unsigned x_proc; /* RPC procedure number */ 447 }; 448 static struct xid_entry xe_table[XID_CACHE_SIZE]; 449 static struct xid_entry *xe_first = &xe_table[0]; 450 static struct xid_entry *xe = &xe_table[0]; 451 static struct xid_entry *xe_last = &xe_table[XID_CACHE_SIZE - 1]; 452 453 static struct xid_entry * 454 find_rpc(struct rpc_msg *rpc) 455 { 456 struct xid_entry *x; 457 458 for (x = xe; x >= xe_first; x--) 459 if (x->x_xid == rpc->rm_xid) 460 return (x); 461 for (x = xe_last; x > xe; x--) 462 if (x->x_xid == rpc->rm_xid) 463 return (x); 464 return (NULL); 465 } 466 467 static void 468 stash_rpc(struct rpc_msg *rpc) 469 { 470 struct xid_entry *x; 471 472 if (find_rpc(rpc)) 473 return; 474 475 x = xe++; 476 if (xe > xe_last) 477 xe = xe_first; 478 x->x_xid = rpc->rm_xid; 479 x->x_dir = htonl(REPLY); 480 x->x_prog = rpc->rm_call.cb_prog; 481 x->x_vers = rpc->rm_call.cb_vers; 482 x->x_proc = rpc->rm_call.cb_proc; 483 } 484 485 /* 486 * SLP can multicast requests, and recieve unicast replies in which 487 * neither the source nor destination port is identifiable as a SLP 488 * port. Hence, we need to do as RPC does, and keep track of packets we 489 * are interested in. For SLP, however, we use ports, not XIDs, and 490 * a smaller cache size is more efficient since every incoming packet 491 * needs to be checked. 492 */ 493 494 #define SLP_CACHE_SIZE 64 495 static uint_t slp_table[SLP_CACHE_SIZE]; 496 static int slp_index = 0; 497 498 /* 499 * Returns the index of dport in the table if found, otherwise -1. 500 */ 501 static int 502 find_slp(uint_t dport) { 503 int i; 504 505 if (!dport) 506 return (0); 507 508 for (i = slp_index; i >= 0; i--) 509 if (slp_table[i] == dport) { 510 return (i); 511 } 512 for (i = SLP_CACHE_SIZE - 1; i > slp_index; i--) 513 if (slp_table[i] == dport) { 514 return (i); 515 } 516 return (-1); 517 } 518 519 static void stash_slp(uint_t sport) { 520 if (slp_table[slp_index - 1] == sport) 521 /* avoid redundancy due to multicast retransmissions */ 522 return; 523 524 slp_table[slp_index++] = sport; 525 if (slp_index == SLP_CACHE_SIZE) 526 slp_index = 0; 527 } 528 529 /* 530 * This routine takes a packet and returns true or false 531 * according to whether the filter expression selects it 532 * or not. 533 * We assume here that offsets for short and long values 534 * are even - we may die with an alignment error if the 535 * CPU doesn't support odd addresses. Note that long 536 * values are loaded as two shorts so that 32 bit word 537 * alignment isn't important. 538 * 539 * IPv6 is a bit stickier to handle than IPv4... 540 */ 541 542 int 543 want_packet(uchar_t *pkt, int len, int origlen) 544 { 545 uint_t stack[MAXSS]; /* operand stack */ 546 uint_t *op; /* current operator */ 547 uint_t *sp; /* top of operand stack */ 548 uchar_t *base; /* base for offsets into packet */ 549 uchar_t *ip; /* addr of IP header, unaligned */ 550 uchar_t *tcp; /* addr of TCP header, unaligned */ 551 uchar_t *udp; /* addr of UDP header, unaligned */ 552 struct rpc_msg rpcmsg; /* addr of RPC header */ 553 struct rpc_msg *rpc; 554 int newrpc = 0; 555 uchar_t *slphdr; /* beginning of SLP header */ 556 uint_t slp_sport, slp_dport; 557 int off, header_size; 558 uchar_t *offstack[MAXSS]; /* offset stack */ 559 uchar_t **offp; /* current offset */ 560 uchar_t *opkt = NULL; 561 uint_t olen; 562 563 sp = stack; 564 *sp = 1; 565 base = pkt; 566 offp = offstack; 567 568 header_size = (*interface->header_len)((char *)pkt, len); 569 570 for (op = oplist; *op; op++) { 571 switch ((enum optype) *op) { 572 case OP_LOAD_OCTET: 573 if ((base + *sp) > (pkt + len)) 574 return (0); /* packet too short */ 575 576 *sp = *((uchar_t *)(base + *sp)); 577 break; 578 case OP_LOAD_SHORT: 579 off = *sp; 580 581 if ((base + off + sizeof (uint16_t) - 1) > (pkt + len)) 582 return (0); /* packet too short */ 583 584 *sp = ntohs(get_u16((uchar_t *)(base + off))); 585 break; 586 case OP_LOAD_LONG: 587 off = *sp; 588 589 if ((base + off + sizeof (uint32_t) - 1) > (pkt + len)) 590 return (0); /* packet too short */ 591 592 /* 593 * Handle 3 possible alignments 594 */ 595 switch ((((unsigned)base) + off) % sizeof (uint_t)) { 596 case 0: 597 *sp = *(uint_t *)(base + off); 598 break; 599 600 case 2: 601 *((ushort_t *)(sp)) = 602 *((ushort_t *)(base + off)); 603 *(((ushort_t *)sp) + 1) = 604 *((ushort_t *)(base + off) + 1); 605 break; 606 607 case 1: 608 case 3: 609 *((uchar_t *)(sp)) = 610 *((uchar_t *)(base + off)); 611 *(((uchar_t *)sp) + 1) = 612 *((uchar_t *)(base + off) + 1); 613 *(((uchar_t *)sp) + 2) = 614 *((uchar_t *)(base + off) + 2); 615 *(((uchar_t *)sp) + 3) = 616 *((uchar_t *)(base + off) + 3); 617 break; 618 } 619 *sp = ntohl(*sp); 620 break; 621 case OP_LOAD_CONST: 622 if (sp >= &stack[MAXSS]) 623 return (0); 624 *(++sp) = *(++op); 625 break; 626 case OP_LOAD_LENGTH: 627 if (sp >= &stack[MAXSS]) 628 return (0); 629 *(++sp) = origlen; 630 break; 631 case OP_EQ: 632 if (sp < &stack[1]) 633 return (0); 634 sp--; 635 *sp = *sp == *(sp + 1); 636 break; 637 case OP_NE: 638 if (sp < &stack[1]) 639 return (0); 640 sp--; 641 *sp = *sp != *(sp + 1); 642 break; 643 case OP_GT: 644 if (sp < &stack[1]) 645 return (0); 646 sp--; 647 *sp = *sp > *(sp + 1); 648 break; 649 case OP_GE: 650 if (sp < &stack[1]) 651 return (0); 652 sp--; 653 *sp = *sp >= *(sp + 1); 654 break; 655 case OP_LT: 656 if (sp < &stack[1]) 657 return (0); 658 sp--; 659 *sp = *sp < *(sp + 1); 660 break; 661 case OP_LE: 662 if (sp < &stack[1]) 663 return (0); 664 sp--; 665 *sp = *sp <= *(sp + 1); 666 break; 667 case OP_AND: 668 if (sp < &stack[1]) 669 return (0); 670 sp--; 671 *sp &= *(sp + 1); 672 break; 673 case OP_OR: 674 if (sp < &stack[1]) 675 return (0); 676 sp--; 677 *sp |= *(sp + 1); 678 break; 679 case OP_XOR: 680 if (sp < &stack[1]) 681 return (0); 682 sp--; 683 *sp ^= *(sp + 1); 684 break; 685 case OP_NOT: 686 *sp = !*sp; 687 break; 688 case OP_BRFL: 689 op++; 690 if (!*sp) 691 op = &oplist[*op] - 1; 692 break; 693 case OP_BRTR: 694 op++; 695 if (*sp) 696 op = &oplist[*op] - 1; 697 break; 698 case OP_ADD: 699 if (sp < &stack[1]) 700 return (0); 701 sp--; 702 *sp += *(sp + 1); 703 break; 704 case OP_SUB: 705 if (sp < &stack[1]) 706 return (0); 707 sp--; 708 *sp -= *(sp + 1); 709 break; 710 case OP_MUL: 711 if (sp < &stack[1]) 712 return (0); 713 sp--; 714 *sp *= *(sp + 1); 715 break; 716 case OP_DIV: 717 if (sp < &stack[1]) 718 return (0); 719 sp--; 720 *sp /= *(sp + 1); 721 break; 722 case OP_REM: 723 if (sp < &stack[1]) 724 return (0); 725 sp--; 726 *sp %= *(sp + 1); 727 break; 728 case OP_OFFSET_POP: 729 if (offp < &offstack[0]) 730 return (0); 731 base = *offp--; 732 if (opkt != NULL) { 733 pkt = opkt; 734 len = olen; 735 opkt = NULL; 736 } 737 break; 738 case OP_OFFSET_ZERO: 739 if (offp >= &offstack[MAXSS]) 740 return (0); 741 *++offp = base; 742 base = pkt; 743 break; 744 case OP_OFFSET_LINK: 745 if (offp >= &offstack[MAXSS]) 746 return (0); 747 *++offp = base; 748 base = pkt + header_size; 749 /* 750 * If the offset exceeds the packet length, 751 * we should not be interested in this packet... 752 * Just return 0. 753 */ 754 if (base > pkt + len) { 755 return (0); 756 } 757 break; 758 case OP_OFFSET_IP: 759 if (offp >= &offstack[MAXSS]) 760 return (0); 761 *++offp = base; 762 ip = pkt + header_size; 763 base = ip + ip_hdr_len(ip); 764 if (base == ip) { 765 return (0); /* not IP */ 766 } 767 if (base > pkt + len) { 768 return (0); /* bad pkt */ 769 } 770 break; 771 case OP_OFFSET_TCP: 772 if (offp >= &offstack[MAXSS]) 773 return (0); 774 *++offp = base; 775 ip = pkt + header_size; 776 tcp = ip + ip_hdr_len(ip); 777 if (tcp == ip) { 778 return (0); /* not IP */ 779 } 780 base = tcp + TCP_HDR_LEN(tcp); 781 if (base > pkt + len) { 782 return (0); 783 } 784 break; 785 case OP_OFFSET_UDP: 786 if (offp >= &offstack[MAXSS]) 787 return (0); 788 *++offp = base; 789 ip = pkt + header_size; 790 udp = ip + ip_hdr_len(ip); 791 if (udp == ip) { 792 return (0); /* not IP */ 793 } 794 base = udp + sizeof (struct udphdr); 795 if (base > pkt + len) { 796 return (0); 797 } 798 break; 799 case OP_OFFSET_RPC: 800 if (offp >= &offstack[MAXSS]) 801 return (0); 802 *++offp = base; 803 ip = pkt + header_size; 804 rpc = NULL; 805 806 if (IP_VERS(ip) != IPV4_VERSION && 807 IP_VERS(ip) != IPV6_VERSION) { 808 if (sp >= &stack[MAXSS]) 809 return (0); 810 *(++sp) = 0; 811 break; 812 } 813 814 switch (ip_proto_of(ip)) { 815 case IPPROTO_UDP: 816 udp = ip + ip_hdr_len(ip); 817 rpc = (struct rpc_msg *)(udp + 818 sizeof (struct udphdr)); 819 break; 820 case IPPROTO_TCP: 821 tcp = ip + ip_hdr_len(ip); 822 /* 823 * Need to skip an extra 4 for the xdr_rec 824 * field. 825 */ 826 rpc = (struct rpc_msg *)(tcp + 827 TCP_HDR_LEN(tcp) + 4); 828 break; 829 } 830 /* 831 * We need to have at least 24 bytes of a RPC 832 * packet to look at to determine the validity 833 * of it. 834 */ 835 if (rpc == NULL || (uchar_t *)rpc + 24 > pkt + len) { 836 if (sp >= &stack[MAXSS]) 837 return (0); 838 *(++sp) = 0; 839 break; 840 } 841 /* align */ 842 (void) memcpy(&rpcmsg, rpc, 24); 843 if (!valid_rpc((char *)&rpcmsg, 24)) { 844 if (sp >= &stack[MAXSS]) 845 return (0); 846 *(++sp) = 0; 847 break; 848 } 849 if (ntohl(rpcmsg.rm_direction) == CALL) { 850 base = (uchar_t *)rpc; 851 newrpc = 1; 852 if (sp >= &stack[MAXSS]) 853 return (0); 854 *(++sp) = 1; 855 } else { 856 opkt = pkt; 857 olen = len; 858 859 pkt = base = (uchar_t *)find_rpc(&rpcmsg); 860 len = sizeof (struct xid_entry); 861 if (sp >= &stack[MAXSS]) 862 return (0); 863 *(++sp) = base != NULL; 864 } 865 break; 866 case OP_OFFSET_SLP: 867 slphdr = NULL; 868 ip = pkt + header_size; 869 870 if (IP_VERS(ip) != IPV4_VERSION && 871 IP_VERS(ip) != IPV6_VERSION) { 872 if (sp >= &stack[MAXSS]) 873 return (0); 874 *(++sp) = 0; 875 break; 876 } 877 878 switch (ip_proto_of(ip)) { 879 struct udphdr udp_h; 880 struct tcphdr tcp_h; 881 case IPPROTO_UDP: 882 udp = ip + ip_hdr_len(ip); 883 /* align */ 884 memcpy(&udp_h, udp, sizeof (udp_h)); 885 slp_sport = ntohs(udp_h.uh_sport); 886 slp_dport = ntohs(udp_h.uh_dport); 887 slphdr = udp + sizeof (struct udphdr); 888 break; 889 case IPPROTO_TCP: 890 tcp = ip + ip_hdr_len(ip); 891 /* align */ 892 memcpy(&tcp_h, tcp, sizeof (tcp_h)); 893 slp_sport = ntohs(tcp_h.th_sport); 894 slp_dport = ntohs(tcp_h.th_dport); 895 slphdr = tcp + TCP_HDR_LEN(tcp); 896 break; 897 } 898 if (slphdr == NULL || slphdr > pkt + len) { 899 if (sp >= &stack[MAXSS]) 900 return (0); 901 *(++sp) = 0; 902 break; 903 } 904 if (slp_sport == 427 || slp_dport == 427) { 905 if (sp >= &stack[MAXSS]) 906 return (0); 907 *(++sp) = 1; 908 if (slp_sport != 427 && slp_dport == 427) 909 stash_slp(slp_sport); 910 break; 911 } else if (find_slp(slp_dport) != -1) { 912 if (valid_slp(slphdr, len)) { 913 if (sp >= &stack[MAXSS]) 914 return (0); 915 *(++sp) = 1; 916 break; 917 } 918 /* else fallthrough to reject */ 919 } 920 if (sp >= &stack[MAXSS]) 921 return (0); 922 *(++sp) = 0; 923 break; 924 case OP_OFFSET_ETHERTYPE: 925 /* 926 * Set base to the location of the ethertype as 927 * appropriate for this link type. Note that it's 928 * not called "ethertype" for every link type, but 929 * we need to call it something. 930 */ 931 if (offp >= &offstack[MAXSS]) 932 return (0); 933 *++offp = base; 934 base = pkt + interface->network_type_offset; 935 936 /* 937 * Below, we adjust the offset for unusual 938 * link-layer headers that may have the protocol 939 * type in a variable location beyond what was set 940 * above. 941 */ 942 switch (interface->mac_type) { 943 case DL_ETHER: 944 case DL_CSMACD: 945 /* 946 * If this is a VLAN-tagged packet, we need 947 * to point to the ethertype field in the 948 * VLAN header. Move past the ethertype 949 * field in the ethernet header. 950 */ 951 if (ntohs(get_u16(base)) == ETHERTYPE_VLAN) 952 base += (ENCAP_ETHERTYPE_OFF); 953 break; 954 } 955 if (base > pkt + len) { 956 /* Went too far, drop the packet */ 957 return (0); 958 } 959 break; 960 } 961 } 962 963 if (*sp && newrpc) 964 stash_rpc(&rpcmsg); 965 966 return (*sp); 967 } 968 969 static void 970 load_const(uint_t constval) 971 { 972 emitop(OP_LOAD_CONST); 973 emitval(constval); 974 } 975 976 static void 977 load_value(int offset, int len) 978 { 979 if (offset >= 0) 980 load_const(offset); 981 982 switch (len) { 983 case 1: 984 emitop(OP_LOAD_OCTET); 985 break; 986 case 2: 987 emitop(OP_LOAD_SHORT); 988 break; 989 case 4: 990 emitop(OP_LOAD_LONG); 991 break; 992 } 993 } 994 995 /* 996 * Emit code to compare a field in 997 * the packet against a constant value. 998 */ 999 static void 1000 compare_value(uint_t offset, uint_t len, uint_t val) 1001 { 1002 load_const(val); 1003 load_value(offset, len); 1004 emitop(OP_EQ); 1005 } 1006 1007 static void 1008 compare_addr_v4(uint_t offset, uint_t len, uint_t val) 1009 { 1010 load_const(ntohl(val)); 1011 load_value(offset, len); 1012 emitop(OP_EQ); 1013 } 1014 1015 static void 1016 compare_addr_v6(uint_t offset, uint_t len, struct in6_addr val) 1017 { 1018 int i; 1019 uint32_t value; 1020 1021 for (i = 0; i < len; i += 4) { 1022 value = ntohl(*(uint32_t *)&val.s6_addr[i]); 1023 load_const(value); 1024 load_value(offset + i, 4); 1025 emitop(OP_EQ); 1026 if (i != 0) 1027 emitop(OP_AND); 1028 } 1029 } 1030 1031 /* 1032 * Same as above except do the comparison 1033 * after and'ing a mask value. Useful 1034 * for comparing IP network numbers 1035 */ 1036 static void 1037 compare_value_mask(uint_t offset, uint_t len, uint_t val, int mask) 1038 { 1039 load_value(offset, len); 1040 load_const(mask); 1041 emitop(OP_AND); 1042 load_const(val); 1043 emitop(OP_EQ); 1044 } 1045 1046 /* 1047 * Compare two zoneid's. The arg val passed in is stored in network 1048 * byte order. 1049 */ 1050 static void 1051 compare_value_zone(uint_t offset, uint32_t val) 1052 { 1053 load_const(ntohl(val)); 1054 load_value(offset, 4); 1055 emitop(OP_EQ); 1056 } 1057 1058 /* Emit an operator into the code array */ 1059 static void 1060 emitop(enum optype opcode) 1061 { 1062 if (curr_op >= &oplist[MAXOPS]) 1063 pr_err("expression too long"); 1064 *curr_op++ = opcode; 1065 } 1066 1067 /* 1068 * Remove n operators recently emitted into 1069 * the code array. Used by alternation(). 1070 */ 1071 static void 1072 unemit(int numops) 1073 { 1074 curr_op -= numops; 1075 } 1076 1077 1078 /* 1079 * Same as emitop except that we're emitting 1080 * a value that's not an operator. 1081 */ 1082 static void 1083 emitval(uint_t val) 1084 { 1085 if (curr_op >= &oplist[MAXOPS]) 1086 pr_err("expression too long"); 1087 *curr_op++ = val; 1088 } 1089 1090 /* 1091 * Used to chain forward branches together 1092 * for later resolution by resolve_chain(). 1093 */ 1094 static uint_t 1095 chain(int p) 1096 { 1097 uint_t pos = curr_op - oplist; 1098 1099 emitval(p); 1100 return (pos); 1101 } 1102 1103 /* 1104 * Proceed backward through the code array 1105 * following a chain of forward references. 1106 * At each reference install the destination 1107 * branch offset. 1108 */ 1109 static void 1110 resolve_chain(uint_t p) 1111 { 1112 uint_t n; 1113 uint_t pos = curr_op - oplist; 1114 1115 while (p) { 1116 n = oplist[p]; 1117 oplist[p] = pos; 1118 p = n; 1119 } 1120 } 1121 1122 #define EQ(val) (strcmp(token, val) == 0) 1123 1124 char *tkp, *sav_tkp; 1125 char *token; 1126 enum { EOL, ALPHA, NUMBER, FIELD, ADDR_IP, ADDR_ETHER, SPECIAL, 1127 ADDR_IP6, ADDR_AT } tokentype; 1128 uint_t tokenval; 1129 1130 /* 1131 * This is the scanner. Each call returns the next 1132 * token in the filter expression. A token is either: 1133 * EOL: The end of the line - no more tokens. 1134 * ALPHA: A name that begins with a letter and contains 1135 * letters or digits, hyphens or underscores. 1136 * NUMBER: A number. The value can be represented as 1137 * a decimal value (1234) or an octal value 1138 * that begins with zero (066) or a hex value 1139 * that begins with 0x or 0X (0xff). 1140 * FIELD: A name followed by a left square bracket. 1141 * ADDR_IP: An IP address. Any sequence of digits 1142 * separated by dots e.g. 109.104.40.13 1143 * ADDR_ETHER: An ethernet address. Any sequence of hex 1144 * digits separated by colons e.g. 8:0:20:0:76:39 1145 * SPECIAL: A special character e.g. ">" or "(". The scanner 1146 * correctly handles digraphs - two special characters 1147 * that constitute a single token e.g. "==" or ">=". 1148 * ADDR_IP6: An IPv6 address. 1149 * 1150 * ADDR_AT: An AppleTalk Phase II address. A sequence of two numbers 1151 * separated by a dot. 1152 * 1153 * The current token is maintained in "token" and and its 1154 * type in "tokentype". If tokentype is NUMBER then the 1155 * value is held in "tokenval". 1156 */ 1157 1158 static const char *namechars = 1159 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-."; 1160 static const char *numchars = "0123456789abcdefABCDEFXx:."; 1161 1162 void 1163 next() 1164 { 1165 static int savechar; 1166 char *p; 1167 int size, size1; 1168 int base, colons, dots, alphas, double_colon; 1169 1170 colons = 0; 1171 double_colon = 0; 1172 1173 if (*tkp == '\0') { 1174 token = tkp; 1175 *tkp = savechar; 1176 } 1177 1178 sav_tkp = tkp; 1179 1180 while (isspace(*tkp)) tkp++; 1181 token = tkp; 1182 if (*token == '\0') { 1183 tokentype = EOL; 1184 return; 1185 } 1186 1187 /* A token containing ':' cannot be ALPHA type */ 1188 tkp = token + strspn(token, numchars); 1189 for (p = token; p < tkp; p++) { 1190 if (*p == ':') { 1191 colons++; 1192 if (*(p+1) == ':') 1193 double_colon++; 1194 } 1195 } 1196 1197 tkp = token; 1198 if (isalpha(*tkp) && !colons) { 1199 tokentype = ALPHA; 1200 tkp += strspn(tkp, namechars); 1201 if (*tkp == '[') { 1202 tokentype = FIELD; 1203 *tkp++ = '\0'; 1204 } 1205 } else 1206 1207 /* 1208 * RFC1123 states that host names may now start with digits. Need 1209 * to change parser to account for this. Also, need to distinguish 1210 * between 1.2.3.4 and 1.2.3.a where the first case is an IP address 1211 * and the second is a domain name. 333aaa needs to be distinguished 1212 * from 0x333aaa. The first is a host name and the second is a number. 1213 * 1214 * The (colons > 1) conditional differentiates between ethernet 1215 * and IPv6 addresses, and an expression of the form base[expr:size], 1216 * which can only contain one ':' character. 1217 */ 1218 if (isdigit(*tkp) || colons > 1) { 1219 tkp = token + strspn(token, numchars); 1220 dots = alphas = 0; 1221 for (p = token; p < tkp; p++) { 1222 if (*p == '.') 1223 dots++; 1224 else if (isalpha(*p)) 1225 alphas = 1; 1226 } 1227 if (colons > 1) { 1228 if (colons == 5 && double_colon == 0) { 1229 tokentype = ADDR_ETHER; 1230 } else { 1231 tokentype = ADDR_IP6; 1232 } 1233 } else if (dots) { 1234 size = tkp - token; 1235 size1 = strspn(token, "0123456789."); 1236 if (dots == 1 && size == size1) { 1237 tokentype = ADDR_AT; 1238 } else 1239 if (dots != 3 || size != size1) { 1240 tokentype = ALPHA; 1241 if (*tkp != '\0' && !isspace(*tkp)) { 1242 tkp += strspn(tkp, namechars); 1243 if (*tkp == '[') { 1244 tokentype = FIELD; 1245 *tkp++ = '\0'; 1246 } 1247 } 1248 } else 1249 tokentype = ADDR_IP; 1250 } else if (token + strspn(token, namechars) <= tkp) { 1251 /* 1252 * With the above check, if there are more 1253 * characters after the last digit, assume 1254 * that it is not a number. 1255 */ 1256 tokentype = NUMBER; 1257 p = tkp; 1258 tkp = token; 1259 base = 10; 1260 if (*tkp == '0') { 1261 base = 8; 1262 tkp++; 1263 if (*tkp == 'x' || *tkp == 'X') 1264 base = 16; 1265 } 1266 if ((base == 10 || base == 8) && alphas) { 1267 tokentype = ALPHA; 1268 tkp = p; 1269 } else if (base == 16) { 1270 size = 2 + strspn(token+2, 1271 "0123456789abcdefABCDEF"); 1272 size1 = p - token; 1273 if (size != size1) { 1274 tokentype = ALPHA; 1275 tkp = p; 1276 } else 1277 /* 1278 * handles the case of 0x so an error message 1279 * is not printed. Treats 0x as 0. 1280 */ 1281 if (size == 2) { 1282 tokenval = 0; 1283 tkp = token +2; 1284 } else { 1285 tokenval = strtoul(token, &tkp, base); 1286 } 1287 } else { 1288 tokenval = strtoul(token, &tkp, base); 1289 } 1290 } else { 1291 tokentype = ALPHA; 1292 tkp += strspn(tkp, namechars); 1293 if (*tkp == '[') { 1294 tokentype = FIELD; 1295 *tkp++ = '\0'; 1296 } 1297 } 1298 } else { 1299 tokentype = SPECIAL; 1300 tkp++; 1301 if ((*token == '=' && *tkp == '=') || 1302 (*token == '>' && *tkp == '=') || 1303 (*token == '<' && *tkp == '=') || 1304 (*token == '!' && *tkp == '=')) 1305 tkp++; 1306 } 1307 1308 savechar = *tkp; 1309 *tkp = '\0'; 1310 } 1311 1312 typedef struct match_type { 1313 char *m_name; 1314 int m_offset; 1315 int m_size; 1316 int m_value; 1317 int m_depend; 1318 enum optype m_optype; 1319 } match_type_t; 1320 1321 static match_type_t ether_match_types[] = { 1322 /* 1323 * Table initialized assuming Ethernet data link headers. 1324 * m_offset is an offset beyond the offset op, which is why 1325 * the offset is zero for when snoop needs to check an ethertype. 1326 */ 1327 "ip", 0, 2, ETHERTYPE_IP, -1, OP_OFFSET_ETHERTYPE, 1328 "ip6", 0, 2, ETHERTYPE_IPV6, -1, OP_OFFSET_ETHERTYPE, 1329 "arp", 0, 2, ETHERTYPE_ARP, -1, OP_OFFSET_ETHERTYPE, 1330 "rarp", 0, 2, ETHERTYPE_REVARP, -1, OP_OFFSET_ETHERTYPE, 1331 "pppoed", 0, 2, ETHERTYPE_PPPOED, -1, OP_OFFSET_ETHERTYPE, 1332 "pppoes", 0, 2, ETHERTYPE_PPPOES, -1, OP_OFFSET_ETHERTYPE, 1333 "tcp", 9, 1, IPPROTO_TCP, 0, OP_OFFSET_LINK, 1334 "tcp", 6, 1, IPPROTO_TCP, 1, OP_OFFSET_LINK, 1335 "udp", 9, 1, IPPROTO_UDP, 0, OP_OFFSET_LINK, 1336 "udp", 6, 1, IPPROTO_UDP, 1, OP_OFFSET_LINK, 1337 "icmp", 9, 1, IPPROTO_ICMP, 0, OP_OFFSET_LINK, 1338 "icmp6", 6, 1, IPPROTO_ICMPV6, 1, OP_OFFSET_LINK, 1339 "ospf", 9, 1, IPPROTO_OSPF, 0, OP_OFFSET_LINK, 1340 "ospf", 6, 1, IPPROTO_OSPF, 1, OP_OFFSET_LINK, 1341 "ip-in-ip", 9, 1, IPPROTO_ENCAP, 0, OP_OFFSET_LINK, 1342 "esp", 9, 1, IPPROTO_ESP, 0, OP_OFFSET_LINK, 1343 "esp", 6, 1, IPPROTO_ESP, 1, OP_OFFSET_LINK, 1344 "ah", 9, 1, IPPROTO_AH, 0, OP_OFFSET_LINK, 1345 "ah", 6, 1, IPPROTO_AH, 1, OP_OFFSET_LINK, 1346 "sctp", 9, 1, IPPROTO_SCTP, 0, OP_OFFSET_LINK, 1347 "sctp", 6, 1, IPPROTO_SCTP, 1, OP_OFFSET_LINK, 1348 0, 0, 0, 0, 0, 0 1349 }; 1350 1351 static match_type_t ipnet_match_types[] = { 1352 /* 1353 * Table initialized assuming Ethernet data link headers. 1354 * m_offset is an offset beyond the offset op, which is why 1355 * the offset is zero for when snoop needs to check an ethertype. 1356 */ 1357 "ip", 0, 1, IPV4_VERSION, -1, OP_OFFSET_ETHERTYPE, 1358 "ip6", 0, 1, IPV6_VERSION, -1, OP_OFFSET_ETHERTYPE, 1359 "tcp", 9, 1, IPPROTO_TCP, 0, OP_OFFSET_LINK, 1360 "tcp", 6, 1, IPPROTO_TCP, 1, OP_OFFSET_LINK, 1361 "udp", 9, 1, IPPROTO_UDP, 0, OP_OFFSET_LINK, 1362 "udp", 6, 1, IPPROTO_UDP, 1, OP_OFFSET_LINK, 1363 "icmp", 9, 1, IPPROTO_ICMP, 0, OP_OFFSET_LINK, 1364 "icmp6", 6, 1, IPPROTO_ICMPV6, 1, OP_OFFSET_LINK, 1365 "ospf", 9, 1, IPPROTO_OSPF, 0, OP_OFFSET_LINK, 1366 "ospf", 6, 1, IPPROTO_OSPF, 1, OP_OFFSET_LINK, 1367 "ip-in-ip", 9, 1, IPPROTO_ENCAP, 0, OP_OFFSET_LINK, 1368 "esp", 9, 1, IPPROTO_ESP, 0, OP_OFFSET_LINK, 1369 "esp", 6, 1, IPPROTO_ESP, 1, OP_OFFSET_LINK, 1370 "ah", 9, 1, IPPROTO_AH, 0, OP_OFFSET_LINK, 1371 "ah", 6, 1, IPPROTO_AH, 1, OP_OFFSET_LINK, 1372 "sctp", 9, 1, IPPROTO_SCTP, 0, OP_OFFSET_LINK, 1373 "sctp", 6, 1, IPPROTO_SCTP, 1, OP_OFFSET_LINK, 1374 0, 0, 0, 0, 0, 0 1375 }; 1376 1377 static match_type_t iptun_match_types[] = { 1378 "ip", 0, 1, IPPROTO_ENCAP, -1, OP_OFFSET_ETHERTYPE, 1379 "ip6", 0, 1, IPPROTO_IPV6, -1, OP_OFFSET_ETHERTYPE, 1380 "tcp", 9, 1, IPPROTO_TCP, 0, OP_OFFSET_LINK, 1381 "tcp", 6, 1, IPPROTO_TCP, 1, OP_OFFSET_LINK, 1382 "udp", 9, 1, IPPROTO_UDP, 0, OP_OFFSET_LINK, 1383 "udp", 6, 1, IPPROTO_UDP, 1, OP_OFFSET_LINK, 1384 "icmp", 9, 1, IPPROTO_ICMP, 0, OP_OFFSET_LINK, 1385 "icmp6", 6, 1, IPPROTO_ICMPV6, 1, OP_OFFSET_LINK, 1386 "ospf", 9, 1, IPPROTO_OSPF, 0, OP_OFFSET_LINK, 1387 "ospf", 6, 1, IPPROTO_OSPF, 1, OP_OFFSET_LINK, 1388 "ip-in-ip", 9, 1, IPPROTO_ENCAP, 0, OP_OFFSET_LINK, 1389 "esp", 9, 1, IPPROTO_ESP, 0, OP_OFFSET_LINK, 1390 "esp", 6, 1, IPPROTO_ESP, 1, OP_OFFSET_LINK, 1391 "ah", 9, 1, IPPROTO_AH, 0, OP_OFFSET_LINK, 1392 "ah", 6, 1, IPPROTO_AH, 1, OP_OFFSET_LINK, 1393 "sctp", 9, 1, IPPROTO_SCTP, 0, OP_OFFSET_LINK, 1394 "sctp", 6, 1, IPPROTO_SCTP, 1, OP_OFFSET_LINK, 1395 0, 0, 0, 0, 0, 0 1396 }; 1397 1398 static void 1399 generate_check(match_type_t match_types[], int index, int type) 1400 { 1401 match_type_t *mtp = &match_types[index]; 1402 /* 1403 * Note: this code assumes the above dependencies are 1404 * not cyclic. This *should* always be true. 1405 */ 1406 if (mtp->m_depend != -1) 1407 generate_check(match_types, mtp->m_depend, type); 1408 1409 emitop(mtp->m_optype); 1410 load_value(mtp->m_offset, mtp->m_size); 1411 load_const(mtp->m_value); 1412 emitop(OP_OFFSET_POP); 1413 1414 emitop(OP_EQ); 1415 1416 if (mtp->m_depend != -1) 1417 emitop(OP_AND); 1418 } 1419 1420 /* 1421 * Generate code based on the keyword argument. 1422 * This word is looked up in the match_types table 1423 * and checks a field within the packet for a given 1424 * value e.g. ether or ip type field. The match 1425 * can also have a dependency on another entry e.g. 1426 * "tcp" requires that the packet also be "ip". 1427 */ 1428 static int 1429 comparison(char *s) 1430 { 1431 unsigned int i, n_checks = 0; 1432 match_type_t *match_types; 1433 1434 switch (interface->mac_type) { 1435 case DL_ETHER: 1436 match_types = ether_match_types; 1437 break; 1438 case DL_IPNET: 1439 match_types = ipnet_match_types; 1440 break; 1441 case DL_IPV4: 1442 case DL_IPV6: 1443 case DL_6TO4: 1444 match_types = iptun_match_types; 1445 break; 1446 default: 1447 return (0); 1448 } 1449 1450 for (i = 0; match_types[i].m_name != NULL; i++) { 1451 if (strcmp(s, match_types[i].m_name) != 0) 1452 continue; 1453 1454 n_checks++; 1455 generate_check(match_types, i, interface->mac_type); 1456 if (n_checks > 1) 1457 emitop(OP_OR); 1458 } 1459 1460 return (n_checks > 0); 1461 } 1462 1463 enum direction { ANY, TO, FROM }; 1464 enum direction dir; 1465 1466 /* 1467 * Generate code to match an IP address. The address 1468 * may be supplied either as a hostname or in dotted format. 1469 * For source packets both the IP source address and ARP 1470 * src are checked. 1471 * Note: we don't check packet type here - whether IP or ARP. 1472 * It's possible that we'll do an improper match. 1473 */ 1474 static void 1475 ipaddr_match(enum direction which, char *hostname, int inet_type) 1476 { 1477 bool_t found_host; 1478 int m = 0, n = 0; 1479 uint_t *addr4ptr; 1480 uint_t addr4; 1481 struct in6_addr *addr6ptr; 1482 int h_addr_index; 1483 struct hostent *hp = NULL; 1484 int error_num = 0; 1485 boolean_t freehp = B_FALSE; 1486 boolean_t first = B_TRUE; 1487 1488 /* 1489 * The addr4offset and addr6offset variables simplify the code which 1490 * generates the address comparison filter. With these two variables, 1491 * duplicate code need not exist for the TO and FROM case. 1492 * A value of -1 describes the ANY case (TO and FROM). 1493 */ 1494 int addr4offset; 1495 int addr6offset; 1496 1497 found_host = 0; 1498 1499 if (tokentype == ADDR_IP) { 1500 hp = lgetipnodebyname(hostname, AF_INET, 0, &error_num); 1501 if (hp == NULL) { 1502 hp = getipnodebyname(hostname, AF_INET, 0, &error_num); 1503 freehp = 1; 1504 } 1505 if (hp == NULL) { 1506 if (error_num == TRY_AGAIN) { 1507 pr_err("couldn't resolve %s (try again later)", 1508 hostname); 1509 } else { 1510 pr_err("couldn't resolve %s", hostname); 1511 } 1512 } 1513 inet_type = IPV4_ONLY; 1514 } else if (tokentype == ADDR_IP6) { 1515 hp = lgetipnodebyname(hostname, AF_INET6, 0, &error_num); 1516 if (hp == NULL) { 1517 hp = getipnodebyname(hostname, AF_INET6, 0, &error_num); 1518 freehp = 1; 1519 } 1520 if (hp == NULL) { 1521 if (error_num == TRY_AGAIN) { 1522 pr_err("couldn't resolve %s (try again later)", 1523 hostname); 1524 } else { 1525 pr_err("couldn't resolve %s", hostname); 1526 } 1527 } 1528 inet_type = IPV6_ONLY; 1529 } else { 1530 /* Some hostname i.e. tokentype is ALPHA */ 1531 switch (inet_type) { 1532 case IPV4_ONLY: 1533 /* Only IPv4 address is needed */ 1534 hp = lgetipnodebyname(hostname, AF_INET, 0, &error_num); 1535 if (hp == NULL) { 1536 hp = getipnodebyname(hostname, AF_INET, 0, 1537 &error_num); 1538 freehp = 1; 1539 } 1540 if (hp != NULL) { 1541 found_host = 1; 1542 } 1543 break; 1544 case IPV6_ONLY: 1545 /* Only IPv6 address is needed */ 1546 hp = lgetipnodebyname(hostname, AF_INET6, 0, 1547 &error_num); 1548 if (hp == NULL) { 1549 hp = getipnodebyname(hostname, AF_INET6, 0, 1550 &error_num); 1551 freehp = 1; 1552 } 1553 if (hp != NULL) { 1554 found_host = 1; 1555 } 1556 break; 1557 case IPV4_AND_IPV6: 1558 /* Both IPv4 and IPv6 are needed */ 1559 hp = lgetipnodebyname(hostname, AF_INET6, 1560 AI_ALL | AI_V4MAPPED, &error_num); 1561 if (hp == NULL) { 1562 hp = getipnodebyname(hostname, AF_INET6, 1563 AI_ALL | AI_V4MAPPED, &error_num); 1564 freehp = 1; 1565 } 1566 if (hp != NULL) { 1567 found_host = 1; 1568 } 1569 break; 1570 default: 1571 found_host = 0; 1572 } 1573 1574 if (!found_host) { 1575 if (error_num == TRY_AGAIN) { 1576 pr_err("could not resolve %s (try again later)", 1577 hostname); 1578 } else { 1579 pr_err("could not resolve %s", hostname); 1580 } 1581 } 1582 } 1583 1584 if (hp == NULL) 1585 return; 1586 1587 switch (which) { 1588 case TO: 1589 addr4offset = IPV4_DSTADDR_OFFSET; 1590 addr6offset = IPV6_DSTADDR_OFFSET; 1591 break; 1592 case FROM: 1593 addr4offset = IPV4_SRCADDR_OFFSET; 1594 addr6offset = IPV6_SRCADDR_OFFSET; 1595 break; 1596 case ANY: 1597 addr4offset = -1; 1598 addr6offset = -1; 1599 break; 1600 } 1601 1602 /* 1603 * The code below generates the filter. 1604 */ 1605 if (hp->h_addrtype == AF_INET) { 1606 ethertype_match(interface->network_type_ip); 1607 emitop(OP_BRFL); 1608 n = chain(n); 1609 emitop(OP_OFFSET_LINK); 1610 h_addr_index = 0; 1611 addr4ptr = (uint_t *)hp->h_addr_list[h_addr_index]; 1612 while (addr4ptr != NULL) { 1613 if (addr4offset == -1) { 1614 compare_addr_v4(IPV4_SRCADDR_OFFSET, 4, 1615 *addr4ptr); 1616 emitop(OP_BRTR); 1617 m = chain(m); 1618 compare_addr_v4(IPV4_DSTADDR_OFFSET, 4, 1619 *addr4ptr); 1620 } else { 1621 compare_addr_v4(addr4offset, 4, *addr4ptr); 1622 } 1623 addr4ptr = (uint_t *)hp->h_addr_list[++h_addr_index]; 1624 if (addr4ptr != NULL) { 1625 emitop(OP_BRTR); 1626 m = chain(m); 1627 } 1628 } 1629 if (m != 0) { 1630 resolve_chain(m); 1631 } 1632 emitop(OP_OFFSET_POP); 1633 resolve_chain(n); 1634 } else { 1635 /* first pass: IPv4 addresses */ 1636 h_addr_index = 0; 1637 addr6ptr = (struct in6_addr *)hp->h_addr_list[h_addr_index]; 1638 first = B_TRUE; 1639 while (addr6ptr != NULL) { 1640 if (IN6_IS_ADDR_V4MAPPED(addr6ptr)) { 1641 if (first) { 1642 ethertype_match( 1643 interface->network_type_ip); 1644 emitop(OP_BRFL); 1645 n = chain(n); 1646 emitop(OP_OFFSET_LINK); 1647 first = B_FALSE; 1648 } else { 1649 emitop(OP_BRTR); 1650 m = chain(m); 1651 } 1652 IN6_V4MAPPED_TO_INADDR(addr6ptr, 1653 (struct in_addr *)&addr4); 1654 if (addr4offset == -1) { 1655 compare_addr_v4(IPV4_SRCADDR_OFFSET, 4, 1656 addr4); 1657 emitop(OP_BRTR); 1658 m = chain(m); 1659 compare_addr_v4(IPV4_DSTADDR_OFFSET, 4, 1660 addr4); 1661 } else { 1662 compare_addr_v4(addr4offset, 4, addr4); 1663 } 1664 } 1665 addr6ptr = (struct in6_addr *) 1666 hp->h_addr_list[++h_addr_index]; 1667 } 1668 /* second pass: IPv6 addresses */ 1669 h_addr_index = 0; 1670 addr6ptr = (struct in6_addr *)hp->h_addr_list[h_addr_index]; 1671 first = B_TRUE; 1672 while (addr6ptr != NULL) { 1673 if (!IN6_IS_ADDR_V4MAPPED(addr6ptr)) { 1674 if (first) { 1675 /* 1676 * bypass check for IPv6 addresses 1677 * when we have an IPv4 packet 1678 */ 1679 if (n != 0) { 1680 emitop(OP_BRTR); 1681 m = chain(m); 1682 emitop(OP_BRFL); 1683 m = chain(m); 1684 resolve_chain(n); 1685 n = 0; 1686 } 1687 ethertype_match( 1688 interface->network_type_ipv6); 1689 emitop(OP_BRFL); 1690 n = chain(n); 1691 emitop(OP_OFFSET_LINK); 1692 first = B_FALSE; 1693 } else { 1694 emitop(OP_BRTR); 1695 m = chain(m); 1696 } 1697 if (addr6offset == -1) { 1698 compare_addr_v6(IPV6_SRCADDR_OFFSET, 1699 16, *addr6ptr); 1700 emitop(OP_BRTR); 1701 m = chain(m); 1702 compare_addr_v6(IPV6_DSTADDR_OFFSET, 1703 16, *addr6ptr); 1704 } else { 1705 compare_addr_v6(addr6offset, 16, 1706 *addr6ptr); 1707 } 1708 } 1709 addr6ptr = (struct in6_addr *) 1710 hp->h_addr_list[++h_addr_index]; 1711 } 1712 if (m != 0) { 1713 resolve_chain(m); 1714 } 1715 emitop(OP_OFFSET_POP); 1716 resolve_chain(n); 1717 } 1718 1719 /* only free struct hostent returned by getipnodebyname() */ 1720 if (freehp) { 1721 freehostent(hp); 1722 } 1723 } 1724 1725 /* 1726 * Match on zoneid. The arg zone passed in is in network byte order. 1727 */ 1728 static void 1729 zone_match(enum direction which, uint32_t zone) 1730 { 1731 1732 switch (which) { 1733 case TO: 1734 compare_value_zone(IPNET_DSTZONE_OFFSET, zone); 1735 break; 1736 case FROM: 1737 compare_value_zone(IPNET_SRCZONE_OFFSET, zone); 1738 break; 1739 case ANY: 1740 compare_value_zone(IPNET_SRCZONE_OFFSET, zone); 1741 compare_value_zone(IPNET_DSTZONE_OFFSET, zone); 1742 emitop(OP_OR); 1743 } 1744 } 1745 1746 /* 1747 * Generate code to match an AppleTalk address. The address 1748 * must be given as two numbers with a dot between 1749 * 1750 */ 1751 static void 1752 ataddr_match(enum direction which, char *hostname) 1753 { 1754 uint_t net; 1755 uint_t node; 1756 uint_t m, n; 1757 1758 sscanf(hostname, "%u.%u", &net, &node); 1759 1760 emitop(OP_OFFSET_LINK); 1761 switch (which) { 1762 case TO: 1763 compare_value(AT_DST_NET_OFFSET, 2, net); 1764 emitop(OP_BRFL); 1765 m = chain(0); 1766 compare_value(AT_DST_NODE_OFFSET, 1, node); 1767 resolve_chain(m); 1768 break; 1769 case FROM: 1770 compare_value(AT_SRC_NET_OFFSET, 2, net); 1771 emitop(OP_BRFL); 1772 m = chain(0); 1773 compare_value(AT_SRC_NODE_OFFSET, 1, node); 1774 resolve_chain(m); 1775 break; 1776 case ANY: 1777 compare_value(AT_DST_NET_OFFSET, 2, net); 1778 emitop(OP_BRFL); 1779 m = chain(0); 1780 compare_value(AT_DST_NODE_OFFSET, 1, node); 1781 resolve_chain(m); 1782 emitop(OP_BRTR); 1783 n = chain(0); 1784 compare_value(AT_SRC_NET_OFFSET, 2, net); 1785 emitop(OP_BRFL); 1786 m = chain(0); 1787 compare_value(AT_SRC_NODE_OFFSET, 1, node); 1788 resolve_chain(m); 1789 resolve_chain(n); 1790 break; 1791 } 1792 emitop(OP_OFFSET_POP); 1793 } 1794 1795 /* 1796 * Compare ethernet addresses. The address may 1797 * be provided either as a hostname or as a 1798 * 6 octet colon-separated address. 1799 */ 1800 static void 1801 etheraddr_match(enum direction which, char *hostname) 1802 { 1803 uint_t addr; 1804 ushort_t *addrp; 1805 int to_offset, from_offset; 1806 struct ether_addr e, *ep = NULL; 1807 int m; 1808 1809 /* 1810 * First, check the interface type for whether src/dest address 1811 * is determinable; if not, retreat early. 1812 */ 1813 switch (interface->mac_type) { 1814 case DL_ETHER: 1815 from_offset = ETHERADDRL; 1816 to_offset = 0; 1817 break; 1818 1819 case DL_IB: 1820 /* 1821 * If an ethernet address is attempted to be used 1822 * on an IPoIB interface, flag error. Link address 1823 * based filtering is unsupported on IPoIB, so there 1824 * is no ipibaddr_match() or parsing support for IPoIB 1825 * 20 byte link addresses. 1826 */ 1827 pr_err("filter option unsupported on media"); 1828 break; 1829 1830 case DL_FDDI: 1831 from_offset = 7; 1832 to_offset = 1; 1833 break; 1834 1835 default: 1836 /* 1837 * Where do we find "ether" address for FDDI & TR? 1838 * XXX can improve? ~sparker 1839 */ 1840 load_const(1); 1841 return; 1842 } 1843 1844 if (isxdigit(*hostname)) 1845 ep = ether_aton(hostname); 1846 if (ep == NULL) { 1847 if (ether_hostton(hostname, &e)) 1848 if (!arp_for_ether(hostname, &e)) 1849 pr_err("cannot obtain ether addr for %s", 1850 hostname); 1851 ep = &e; 1852 } 1853 memcpy(&addr, (ushort_t *)ep, 4); 1854 addrp = (ushort_t *)ep + 2; 1855 1856 emitop(OP_OFFSET_ZERO); 1857 switch (which) { 1858 case TO: 1859 compare_value(to_offset, 4, ntohl(addr)); 1860 emitop(OP_BRFL); 1861 m = chain(0); 1862 compare_value(to_offset + 4, 2, ntohs(*addrp)); 1863 resolve_chain(m); 1864 break; 1865 case FROM: 1866 compare_value(from_offset, 4, ntohl(addr)); 1867 emitop(OP_BRFL); 1868 m = chain(0); 1869 compare_value(from_offset + 4, 2, ntohs(*addrp)); 1870 resolve_chain(m); 1871 break; 1872 case ANY: 1873 compare_value(to_offset, 4, ntohl(addr)); 1874 compare_value(to_offset + 4, 2, ntohs(*addrp)); 1875 emitop(OP_AND); 1876 emitop(OP_BRTR); 1877 m = chain(0); 1878 1879 compare_value(from_offset, 4, ntohl(addr)); 1880 compare_value(from_offset + 4, 2, ntohs(*addrp)); 1881 emitop(OP_AND); 1882 resolve_chain(m); 1883 break; 1884 } 1885 emitop(OP_OFFSET_POP); 1886 } 1887 1888 static void 1889 ethertype_match(int val) 1890 { 1891 int ether_offset = interface->network_type_offset; 1892 1893 /* 1894 * If the user is interested in ethertype VLAN, 1895 * then we need to set the offset to the beginning of the packet. 1896 * But if the user is interested in another ethertype, 1897 * such as IPv4, then we need to take into consideration 1898 * the fact that the packet might be VLAN tagged. 1899 */ 1900 if (interface->mac_type == DL_ETHER || 1901 interface->mac_type == DL_CSMACD) { 1902 if (val != ETHERTYPE_VLAN) { 1903 /* 1904 * OP_OFFSET_ETHERTYPE puts us at the ethertype 1905 * field whether or not there is a VLAN tag, 1906 * so ether_offset goes to zero if we get here. 1907 */ 1908 emitop(OP_OFFSET_ETHERTYPE); 1909 ether_offset = 0; 1910 } else { 1911 emitop(OP_OFFSET_ZERO); 1912 } 1913 } 1914 compare_value(ether_offset, interface->network_type_len, val); 1915 if (interface->mac_type == DL_ETHER || 1916 interface->mac_type == DL_CSMACD) { 1917 emitop(OP_OFFSET_POP); 1918 } 1919 } 1920 1921 /* 1922 * Match a network address. The host part 1923 * is masked out. The network address may 1924 * be supplied either as a netname or in 1925 * IP dotted format. The mask to be used 1926 * for the comparison is assumed from the 1927 * address format (see comment below). 1928 */ 1929 static void 1930 netaddr_match(enum direction which, char *netname) 1931 { 1932 uint_t addr; 1933 uint_t mask = 0xff000000; 1934 uint_t m; 1935 struct netent *np; 1936 1937 if (isdigit(*netname)) { 1938 addr = inet_network(netname); 1939 } else { 1940 np = getnetbyname(netname); 1941 if (np == NULL) 1942 pr_err("net %s not known", netname); 1943 addr = np->n_net; 1944 } 1945 1946 /* 1947 * Left justify the address and figure 1948 * out a mask based on the supplied address. 1949 * Set the mask according to the number of zero 1950 * low-order bytes. 1951 * Note: this works only for whole octet masks. 1952 */ 1953 if (addr) { 1954 while ((addr & ~mask) != 0) { 1955 mask |= (mask >> 8); 1956 } 1957 } 1958 1959 emitop(OP_OFFSET_LINK); 1960 switch (which) { 1961 case TO: 1962 compare_value_mask(16, 4, addr, mask); 1963 break; 1964 case FROM: 1965 compare_value_mask(12, 4, addr, mask); 1966 break; 1967 case ANY: 1968 compare_value_mask(12, 4, addr, mask); 1969 emitop(OP_BRTR); 1970 m = chain(0); 1971 compare_value_mask(16, 4, addr, mask); 1972 resolve_chain(m); 1973 break; 1974 } 1975 emitop(OP_OFFSET_POP); 1976 } 1977 1978 /* 1979 * Match either a UDP or TCP port number. 1980 * The port number may be provided either as 1981 * port name as listed in /etc/services ("nntp") or as 1982 * the port number itself (2049). 1983 */ 1984 static void 1985 port_match(enum direction which, char *portname) 1986 { 1987 struct servent *sp; 1988 uint_t m, port; 1989 1990 if (isdigit(*portname)) { 1991 port = atoi(portname); 1992 } else { 1993 sp = getservbyname(portname, NULL); 1994 if (sp == NULL) 1995 pr_err("invalid port number or name: %s", portname); 1996 port = ntohs(sp->s_port); 1997 } 1998 1999 emitop(OP_OFFSET_IP); 2000 2001 switch (which) { 2002 case TO: 2003 compare_value(2, 2, port); 2004 break; 2005 case FROM: 2006 compare_value(0, 2, port); 2007 break; 2008 case ANY: 2009 compare_value(2, 2, port); 2010 emitop(OP_BRTR); 2011 m = chain(0); 2012 compare_value(0, 2, port); 2013 resolve_chain(m); 2014 break; 2015 } 2016 emitop(OP_OFFSET_POP); 2017 } 2018 2019 /* 2020 * Generate code to match packets with a specific 2021 * RPC program number. If the progname is a name 2022 * it is converted to a number via /etc/rpc. 2023 * The program version and/or procedure may be provided 2024 * as extra qualifiers. 2025 */ 2026 static void 2027 rpc_match_prog(enum direction which, char *progname, int vers, int proc) 2028 { 2029 struct rpcent *rpc; 2030 uint_t prog; 2031 uint_t m, n; 2032 2033 if (isdigit(*progname)) { 2034 prog = atoi(progname); 2035 } else { 2036 rpc = (struct rpcent *)getrpcbyname(progname); 2037 if (rpc == NULL) 2038 pr_err("invalid program name: %s", progname); 2039 prog = rpc->r_number; 2040 } 2041 2042 emitop(OP_OFFSET_RPC); 2043 emitop(OP_BRFL); 2044 n = chain(0); 2045 2046 compare_value(12, 4, prog); 2047 emitop(OP_BRFL); 2048 m = chain(0); 2049 if (vers >= 0) { 2050 compare_value(16, 4, vers); 2051 emitop(OP_BRFL); 2052 m = chain(m); 2053 } 2054 if (proc >= 0) { 2055 compare_value(20, 4, proc); 2056 emitop(OP_BRFL); 2057 m = chain(m); 2058 } 2059 2060 switch (which) { 2061 case TO: 2062 compare_value(4, 4, CALL); 2063 emitop(OP_BRFL); 2064 m = chain(m); 2065 break; 2066 case FROM: 2067 compare_value(4, 4, REPLY); 2068 emitop(OP_BRFL); 2069 m = chain(m); 2070 break; 2071 } 2072 resolve_chain(m); 2073 resolve_chain(n); 2074 emitop(OP_OFFSET_POP); 2075 } 2076 2077 /* 2078 * Generate code to parse a field specification 2079 * and load the value of the field from the packet 2080 * onto the operand stack. 2081 * The field offset may be specified relative to the 2082 * beginning of the ether header, IP header, UDP header, 2083 * or TCP header. An optional size specification may 2084 * be provided following a colon. If no size is given 2085 * one byte is assumed e.g. 2086 * 2087 * ether[0] The first byte of the ether header 2088 * ip[2:2] The second 16 bit field of the IP header 2089 */ 2090 static void 2091 load_field() 2092 { 2093 int size = 1; 2094 int s; 2095 2096 2097 if (EQ("ether")) 2098 emitop(OP_OFFSET_ZERO); 2099 else if (EQ("ip") || EQ("ip6") || EQ("pppoed") || EQ("pppoes")) 2100 emitop(OP_OFFSET_LINK); 2101 else if (EQ("udp") || EQ("tcp") || EQ("icmp") || EQ("ip-in-ip") || 2102 EQ("ah") || EQ("esp")) 2103 emitop(OP_OFFSET_IP); 2104 else 2105 pr_err("invalid field type"); 2106 next(); 2107 s = opstack; 2108 expression(); 2109 if (opstack != s + 1) 2110 pr_err("invalid field offset"); 2111 opstack--; 2112 if (*token == ':') { 2113 next(); 2114 if (tokentype != NUMBER) 2115 pr_err("field size expected"); 2116 size = tokenval; 2117 if (size != 1 && size != 2 && size != 4) 2118 pr_err("field size invalid"); 2119 next(); 2120 } 2121 if (*token != ']') 2122 pr_err("right bracket expected"); 2123 2124 load_value(-1, size); 2125 emitop(OP_OFFSET_POP); 2126 } 2127 2128 /* 2129 * Check that the operand stack 2130 * contains n arguments 2131 */ 2132 static void 2133 checkstack(int numargs) 2134 { 2135 if (opstack != numargs) 2136 pr_err("invalid expression at \"%s\".", token); 2137 } 2138 2139 static void 2140 primary() 2141 { 2142 int m, m2, s; 2143 2144 for (;;) { 2145 if (tokentype == FIELD) { 2146 load_field(); 2147 opstack++; 2148 next(); 2149 break; 2150 } 2151 2152 if (comparison(token)) { 2153 opstack++; 2154 next(); 2155 break; 2156 } 2157 2158 if (EQ("not") || EQ("!")) { 2159 next(); 2160 s = opstack; 2161 primary(); 2162 checkstack(s + 1); 2163 emitop(OP_NOT); 2164 break; 2165 } 2166 2167 if (EQ("(")) { 2168 next(); 2169 s = opstack; 2170 expression(); 2171 checkstack(s + 1); 2172 if (!EQ(")")) 2173 pr_err("right paren expected"); 2174 next(); 2175 } 2176 2177 if (EQ("to") || EQ("dst")) { 2178 dir = TO; 2179 next(); 2180 continue; 2181 } 2182 2183 if (EQ("from") || EQ("src")) { 2184 dir = FROM; 2185 next(); 2186 continue; 2187 } 2188 2189 if (EQ("ether")) { 2190 eaddr = 1; 2191 next(); 2192 continue; 2193 } 2194 2195 if (EQ("proto")) { 2196 next(); 2197 if (tokentype != NUMBER) 2198 pr_err("IP proto type expected"); 2199 emitop(OP_OFFSET_LINK); 2200 compare_value(IPV4_TYPE_HEADER_OFFSET, 1, tokenval); 2201 emitop(OP_OFFSET_POP); 2202 opstack++; 2203 next(); 2204 continue; 2205 } 2206 2207 if (EQ("broadcast")) { 2208 /* 2209 * Be tricky: FDDI ether dst address begins at 2210 * byte one. Since the address is really six 2211 * bytes long, this works for FDDI & ethernet. 2212 * XXX - Token ring? 2213 */ 2214 emitop(OP_OFFSET_ZERO); 2215 if (interface->mac_type == DL_IB) 2216 pr_err("filter option unsupported on media"); 2217 compare_value(1, 4, 0xffffffff); 2218 emitop(OP_OFFSET_POP); 2219 opstack++; 2220 next(); 2221 break; 2222 } 2223 2224 if (EQ("multicast")) { 2225 /* XXX Token ring? */ 2226 emitop(OP_OFFSET_ZERO); 2227 if (interface->mac_type == DL_FDDI) { 2228 compare_value_mask(1, 1, 0x01, 0x01); 2229 } else if (interface->mac_type == DL_IB) { 2230 pr_err("filter option unsupported on media"); 2231 } else { 2232 compare_value_mask(0, 1, 0x01, 0x01); 2233 } 2234 emitop(OP_OFFSET_POP); 2235 opstack++; 2236 next(); 2237 break; 2238 } 2239 2240 if (EQ("decnet")) { 2241 /* XXX Token ring? */ 2242 if (interface->mac_type == DL_FDDI) { 2243 load_value(19, 2); /* ether type */ 2244 load_const(0x6000); 2245 emitop(OP_GE); 2246 emitop(OP_BRFL); 2247 m = chain(0); 2248 load_value(19, 2); /* ether type */ 2249 load_const(0x6009); 2250 emitop(OP_LE); 2251 resolve_chain(m); 2252 } else { 2253 emitop(OP_OFFSET_ETHERTYPE); 2254 load_value(0, 2); /* ether type */ 2255 load_const(0x6000); 2256 emitop(OP_GE); 2257 emitop(OP_BRFL); 2258 m = chain(0); 2259 load_value(0, 2); /* ether type */ 2260 load_const(0x6009); 2261 emitop(OP_LE); 2262 resolve_chain(m); 2263 emitop(OP_OFFSET_POP); 2264 } 2265 opstack++; 2266 next(); 2267 break; 2268 } 2269 2270 if (EQ("vlan-id")) { 2271 next(); 2272 if (tokentype != NUMBER) 2273 pr_err("vlan id expected"); 2274 emitop(OP_OFFSET_ZERO); 2275 ethertype_match(ETHERTYPE_VLAN); 2276 emitop(OP_BRFL); 2277 m = chain(0); 2278 compare_value_mask(VLAN_ID_OFFSET, 2, tokenval, 2279 VLAN_ID_MASK); 2280 resolve_chain(m); 2281 emitop(OP_OFFSET_POP); 2282 opstack++; 2283 next(); 2284 break; 2285 } 2286 2287 if (EQ("apple")) { 2288 /* 2289 * Appletalk also appears in 802.2 2290 * packets, so check for the ethertypes 2291 * at offset 12 and 20 in the MAC header. 2292 */ 2293 ethertype_match(ETHERTYPE_AT); 2294 emitop(OP_BRTR); 2295 m = chain(0); 2296 ethertype_match(ETHERTYPE_AARP); 2297 emitop(OP_BRTR); 2298 m = chain(m); 2299 compare_value(20, 2, ETHERTYPE_AT); /* 802.2 */ 2300 emitop(OP_BRTR); 2301 m = chain(m); 2302 compare_value(20, 2, ETHERTYPE_AARP); /* 802.2 */ 2303 resolve_chain(m); 2304 opstack++; 2305 next(); 2306 break; 2307 } 2308 2309 if (EQ("vlan")) { 2310 ethertype_match(ETHERTYPE_VLAN); 2311 compare_value_mask(VLAN_ID_OFFSET, 2, 0, VLAN_ID_MASK); 2312 emitop(OP_NOT); 2313 emitop(OP_AND); 2314 opstack++; 2315 next(); 2316 break; 2317 } 2318 2319 if (EQ("bootp") || EQ("dhcp")) { 2320 ethertype_match(interface->network_type_ip); 2321 emitop(OP_BRFL); 2322 m = chain(0); 2323 emitop(OP_OFFSET_LINK); 2324 compare_value(9, 1, IPPROTO_UDP); 2325 emitop(OP_OFFSET_POP); 2326 emitop(OP_BRFL); 2327 m = chain(m); 2328 emitop(OP_OFFSET_IP); 2329 compare_value(0, 4, 2330 (IPPORT_BOOTPS << 16) | IPPORT_BOOTPC); 2331 emitop(OP_BRTR); 2332 m2 = chain(0); 2333 compare_value(0, 4, 2334 (IPPORT_BOOTPC << 16) | IPPORT_BOOTPS); 2335 resolve_chain(m2); 2336 emitop(OP_OFFSET_POP); 2337 resolve_chain(m); 2338 opstack++; 2339 dir = ANY; 2340 next(); 2341 break; 2342 } 2343 2344 if (EQ("dhcp6")) { 2345 ethertype_match(interface->network_type_ipv6); 2346 emitop(OP_BRFL); 2347 m = chain(0); 2348 emitop(OP_OFFSET_LINK); 2349 compare_value(6, 1, IPPROTO_UDP); 2350 emitop(OP_OFFSET_POP); 2351 emitop(OP_BRFL); 2352 m = chain(m); 2353 emitop(OP_OFFSET_IP); 2354 compare_value(2, 2, IPPORT_DHCPV6S); 2355 emitop(OP_BRTR); 2356 m2 = chain(0); 2357 compare_value(2, 2, IPPORT_DHCPV6C); 2358 resolve_chain(m2); 2359 emitop(OP_OFFSET_POP); 2360 resolve_chain(m); 2361 opstack++; 2362 dir = ANY; 2363 next(); 2364 break; 2365 } 2366 2367 if (EQ("ethertype")) { 2368 next(); 2369 if (tokentype != NUMBER) 2370 pr_err("ether type expected"); 2371 ethertype_match(tokenval); 2372 opstack++; 2373 next(); 2374 break; 2375 } 2376 2377 if (EQ("pppoe")) { 2378 ethertype_match(ETHERTYPE_PPPOED); 2379 ethertype_match(ETHERTYPE_PPPOES); 2380 emitop(OP_OR); 2381 opstack++; 2382 next(); 2383 break; 2384 } 2385 2386 if (EQ("inet")) { 2387 next(); 2388 if (EQ("host")) 2389 next(); 2390 if (tokentype != ALPHA && tokentype != ADDR_IP) 2391 pr_err("host/IPv4 addr expected after inet"); 2392 ipaddr_match(dir, token, IPV4_ONLY); 2393 opstack++; 2394 next(); 2395 break; 2396 } 2397 2398 if (EQ("inet6")) { 2399 next(); 2400 if (EQ("host")) 2401 next(); 2402 if (tokentype != ALPHA && tokentype != ADDR_IP6) 2403 pr_err("host/IPv6 addr expected after inet6"); 2404 ipaddr_match(dir, token, IPV6_ONLY); 2405 opstack++; 2406 next(); 2407 break; 2408 } 2409 2410 if (EQ("length")) { 2411 emitop(OP_LOAD_LENGTH); 2412 opstack++; 2413 next(); 2414 break; 2415 } 2416 2417 if (EQ("less")) { 2418 next(); 2419 if (tokentype != NUMBER) 2420 pr_err("packet length expected"); 2421 emitop(OP_LOAD_LENGTH); 2422 load_const(tokenval); 2423 emitop(OP_LT); 2424 opstack++; 2425 next(); 2426 break; 2427 } 2428 2429 if (EQ("greater")) { 2430 next(); 2431 if (tokentype != NUMBER) 2432 pr_err("packet length expected"); 2433 emitop(OP_LOAD_LENGTH); 2434 load_const(tokenval); 2435 emitop(OP_GT); 2436 opstack++; 2437 next(); 2438 break; 2439 } 2440 2441 if (EQ("nofrag")) { 2442 emitop(OP_OFFSET_LINK); 2443 compare_value_mask(6, 2, 0, 0x1fff); 2444 emitop(OP_OFFSET_POP); 2445 emitop(OP_BRFL); 2446 m = chain(0); 2447 ethertype_match(interface->network_type_ip); 2448 resolve_chain(m); 2449 opstack++; 2450 next(); 2451 break; 2452 } 2453 2454 if (EQ("net") || EQ("dstnet") || EQ("srcnet")) { 2455 if (EQ("dstnet")) 2456 dir = TO; 2457 else if (EQ("srcnet")) 2458 dir = FROM; 2459 next(); 2460 netaddr_match(dir, token); 2461 dir = ANY; 2462 opstack++; 2463 next(); 2464 break; 2465 } 2466 2467 if (EQ("port") || EQ("srcport") || EQ("dstport")) { 2468 if (EQ("dstport")) 2469 dir = TO; 2470 else if (EQ("srcport")) 2471 dir = FROM; 2472 next(); 2473 port_match(dir, token); 2474 dir = ANY; 2475 opstack++; 2476 next(); 2477 break; 2478 } 2479 2480 if (EQ("rpc")) { 2481 uint_t vers, proc; 2482 char savetoken[32]; 2483 2484 vers = proc = -1; 2485 next(); 2486 (void) strlcpy(savetoken, token, sizeof (savetoken)); 2487 next(); 2488 if (*token == ',') { 2489 next(); 2490 if (tokentype != NUMBER) 2491 pr_err("version number expected"); 2492 vers = tokenval; 2493 next(); 2494 } 2495 if (*token == ',') { 2496 next(); 2497 if (tokentype != NUMBER) 2498 pr_err("proc number expected"); 2499 proc = tokenval; 2500 next(); 2501 } 2502 rpc_match_prog(dir, savetoken, vers, proc); 2503 dir = ANY; 2504 opstack++; 2505 break; 2506 } 2507 2508 if (EQ("slp")) { 2509 /* filter out TCP handshakes */ 2510 emitop(OP_OFFSET_LINK); 2511 compare_value(9, 1, IPPROTO_TCP); 2512 emitop(OP_LOAD_CONST); 2513 emitval(52); 2514 emitop(OP_LOAD_CONST); 2515 emitval(2); 2516 emitop(OP_LOAD_SHORT); 2517 emitop(OP_GE); 2518 emitop(OP_AND); /* proto == TCP && len < 52 */ 2519 emitop(OP_NOT); 2520 emitop(OP_BRFL); /* pkt too short to be a SLP call */ 2521 m = chain(0); 2522 2523 emitop(OP_OFFSET_POP); 2524 emitop(OP_OFFSET_SLP); 2525 resolve_chain(m); 2526 opstack++; 2527 next(); 2528 break; 2529 } 2530 2531 if (EQ("ldap")) { 2532 dir = ANY; 2533 port_match(dir, "ldap"); 2534 opstack++; 2535 next(); 2536 break; 2537 } 2538 2539 if (EQ("and") || EQ("or")) { 2540 break; 2541 } 2542 2543 if (EQ("zone")) { 2544 next(); 2545 if (tokentype != NUMBER) 2546 pr_err("zoneid expected"); 2547 zone_match(dir, BE_32((uint32_t)(tokenval))); 2548 opstack++; 2549 next(); 2550 break; 2551 } 2552 2553 if (EQ("gateway")) { 2554 next(); 2555 if (eaddr || tokentype != ALPHA) 2556 pr_err("hostname required: %s", token); 2557 etheraddr_match(dir, token); 2558 dir = ANY; 2559 emitop(OP_BRFL); 2560 m = chain(0); 2561 ipaddr_match(dir, token, IPV4_AND_IPV6); 2562 emitop(OP_NOT); 2563 resolve_chain(m); 2564 opstack++; 2565 next(); 2566 } 2567 2568 if (EQ("host") || EQ("between") || 2569 tokentype == ALPHA || /* assume its a hostname */ 2570 tokentype == ADDR_IP || 2571 tokentype == ADDR_IP6 || 2572 tokentype == ADDR_AT || 2573 tokentype == ADDR_ETHER) { 2574 if (EQ("host") || EQ("between")) 2575 next(); 2576 if (eaddr || tokentype == ADDR_ETHER) { 2577 etheraddr_match(dir, token); 2578 } else if (tokentype == ALPHA) { 2579 ipaddr_match(dir, token, IPV4_AND_IPV6); 2580 } else if (tokentype == ADDR_AT) { 2581 ataddr_match(dir, token); 2582 } else if (tokentype == ADDR_IP) { 2583 ipaddr_match(dir, token, IPV4_ONLY); 2584 } else { 2585 ipaddr_match(dir, token, IPV6_ONLY); 2586 } 2587 dir = ANY; 2588 eaddr = 0; 2589 opstack++; 2590 next(); 2591 break; 2592 } 2593 2594 if (tokentype == NUMBER) { 2595 load_const(tokenval); 2596 opstack++; 2597 next(); 2598 break; 2599 } 2600 2601 break; /* unknown token */ 2602 } 2603 } 2604 2605 struct optable { 2606 char *op_tok; 2607 enum optype op_type; 2608 }; 2609 2610 static struct optable 2611 mulops[] = { 2612 "*", OP_MUL, 2613 "/", OP_DIV, 2614 "%", OP_REM, 2615 "&", OP_AND, 2616 "", OP_STOP, 2617 }; 2618 2619 static struct optable 2620 addops[] = { 2621 "+", OP_ADD, 2622 "-", OP_SUB, 2623 "|", OP_OR, 2624 "^", OP_XOR, 2625 "", OP_STOP, 2626 }; 2627 2628 static struct optable 2629 compareops[] = { 2630 "==", OP_EQ, 2631 "=", OP_EQ, 2632 "!=", OP_NE, 2633 ">", OP_GT, 2634 ">=", OP_GE, 2635 "<", OP_LT, 2636 "<=", OP_LE, 2637 "", OP_STOP, 2638 }; 2639 2640 /* 2641 * Using the table, find the operator 2642 * that corresponds to the token. 2643 * Return 0 if not found. 2644 */ 2645 static int 2646 find_op(char *tok, struct optable *table) 2647 { 2648 struct optable *op; 2649 2650 for (op = table; *op->op_tok; op++) { 2651 if (strcmp(tok, op->op_tok) == 0) 2652 return (op->op_type); 2653 } 2654 2655 return (0); 2656 } 2657 2658 static void 2659 expr_mul() 2660 { 2661 int op; 2662 int s = opstack; 2663 2664 primary(); 2665 while (op = find_op(token, mulops)) { 2666 next(); 2667 primary(); 2668 checkstack(s + 2); 2669 emitop(op); 2670 opstack--; 2671 } 2672 } 2673 2674 static void 2675 expr_add() 2676 { 2677 int op, s = opstack; 2678 2679 expr_mul(); 2680 while (op = find_op(token, addops)) { 2681 next(); 2682 expr_mul(); 2683 checkstack(s + 2); 2684 emitop(op); 2685 opstack--; 2686 } 2687 } 2688 2689 static void 2690 expr_compare() 2691 { 2692 int op, s = opstack; 2693 2694 expr_add(); 2695 while (op = find_op(token, compareops)) { 2696 next(); 2697 expr_add(); 2698 checkstack(s + 2); 2699 emitop(op); 2700 opstack--; 2701 } 2702 } 2703 2704 /* 2705 * Alternation ("and") is difficult because 2706 * an implied "and" is acknowledge between 2707 * two adjacent primaries. Just keep calling 2708 * the lower-level expression routine until 2709 * no value is added to the opstack. 2710 */ 2711 static void 2712 alternation() 2713 { 2714 int m = 0; 2715 int s = opstack; 2716 2717 expr_compare(); 2718 checkstack(s + 1); 2719 for (;;) { 2720 if (EQ("and")) 2721 next(); 2722 emitop(OP_BRFL); 2723 m = chain(m); 2724 expr_compare(); 2725 if (opstack != s + 2) 2726 break; 2727 opstack--; 2728 } 2729 unemit(2); 2730 resolve_chain(m); 2731 } 2732 2733 static void 2734 expression() 2735 { 2736 int m = 0; 2737 int s = opstack; 2738 2739 alternation(); 2740 while (EQ("or") || EQ(",")) { 2741 emitop(OP_BRTR); 2742 m = chain(m); 2743 next(); 2744 alternation(); 2745 checkstack(s + 2); 2746 opstack--; 2747 } 2748 resolve_chain(m); 2749 } 2750 2751 /* 2752 * Take n args from the argv list 2753 * and concatenate them into a single string. 2754 */ 2755 char * 2756 concat_args(char **argv, int argc) 2757 { 2758 int i, len; 2759 char *str, *p; 2760 2761 /* First add the lengths of all the strings */ 2762 len = 0; 2763 for (i = 0; i < argc; i++) 2764 len += strlen(argv[i]) + 1; 2765 2766 /* allocate the big string */ 2767 str = (char *)malloc(len); 2768 if (str == NULL) 2769 pr_err("no mem"); 2770 2771 p = str; 2772 2773 /* 2774 * Concat the strings into the big 2775 * string using a space as separator 2776 */ 2777 for (i = 0; i < argc; i++) { 2778 strcpy(p, argv[i]); 2779 p += strlen(p); 2780 *p++ = ' '; 2781 } 2782 *--p = '\0'; 2783 2784 return (str); 2785 } 2786 2787 /* 2788 * Take the expression in the string "expr" 2789 * and compile it into the code array. 2790 * Print the generated code if the print 2791 * arg is set. 2792 */ 2793 void 2794 compile(char *expr, int print) 2795 { 2796 expr = strdup(expr); 2797 if (expr == NULL) 2798 pr_err("no mem"); 2799 curr_op = oplist; 2800 tkp = expr; 2801 dir = ANY; 2802 2803 next(); 2804 if (tokentype != EOL) 2805 expression(); 2806 emitop(OP_STOP); 2807 if (tokentype != EOL) 2808 pr_err("invalid expression"); 2809 optimize(oplist); 2810 if (print) 2811 codeprint(); 2812 } 2813 2814 /* 2815 * Lookup hostname in the arp cache. 2816 */ 2817 boolean_t 2818 arp_for_ether(char *hostname, struct ether_addr *ep) 2819 { 2820 struct arpreq ar; 2821 struct hostent *hp; 2822 struct sockaddr_in *sin; 2823 int error_num; 2824 int s; 2825 2826 memset(&ar, 0, sizeof (ar)); 2827 sin = (struct sockaddr_in *)&ar.arp_pa; 2828 sin->sin_family = AF_INET; 2829 hp = getipnodebyname(hostname, AF_INET, 0, &error_num); 2830 if (hp == NULL) { 2831 return (B_FALSE); 2832 } 2833 memcpy(&sin->sin_addr, hp->h_addr, sizeof (sin->sin_addr)); 2834 s = socket(AF_INET, SOCK_DGRAM, 0); 2835 if (s < 0) { 2836 return (B_FALSE); 2837 } 2838 if (ioctl(s, SIOCGARP, &ar) < 0) { 2839 close(s); 2840 return (B_FALSE); 2841 } 2842 close(s); 2843 memcpy(ep->ether_addr_octet, ar.arp_ha.sa_data, sizeof (*ep)); 2844 return (B_TRUE); 2845 } 2846