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