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