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, 1, IPV4_VERSION, -1, OP_OFFSET_ETHERTYPE, 1363 "ip6", 0, 1, IPV6_VERSION, -1, OP_OFFSET_ETHERTYPE, 1364 "tcp", 9, 1, IPPROTO_TCP, 0, OP_OFFSET_LINK, 1365 "tcp", 6, 1, IPPROTO_TCP, 1, OP_OFFSET_LINK, 1366 "udp", 9, 1, IPPROTO_UDP, 0, OP_OFFSET_LINK, 1367 "udp", 6, 1, IPPROTO_UDP, 1, OP_OFFSET_LINK, 1368 "icmp", 9, 1, IPPROTO_ICMP, 0, OP_OFFSET_LINK, 1369 "icmp6", 6, 1, IPPROTO_ICMPV6, 1, OP_OFFSET_LINK, 1370 "ospf", 9, 1, IPPROTO_OSPF, 0, OP_OFFSET_LINK, 1371 "ospf", 6, 1, IPPROTO_OSPF, 1, OP_OFFSET_LINK, 1372 "ip-in-ip", 9, 1, IPPROTO_ENCAP, 0, OP_OFFSET_LINK, 1373 "esp", 9, 1, IPPROTO_ESP, 0, OP_OFFSET_LINK, 1374 "esp", 6, 1, IPPROTO_ESP, 1, OP_OFFSET_LINK, 1375 "ah", 9, 1, IPPROTO_AH, 0, OP_OFFSET_LINK, 1376 "ah", 6, 1, IPPROTO_AH, 1, OP_OFFSET_LINK, 1377 "sctp", 9, 1, IPPROTO_SCTP, 0, OP_OFFSET_LINK, 1378 "sctp", 6, 1, IPPROTO_SCTP, 1, OP_OFFSET_LINK, 1379 0, 0, 0, 0, 0, 0 1380 }; 1381 1382 static void 1383 generate_check(match_type_t match_types[], int index, int type) 1384 { 1385 match_type_t *mtp = &match_types[index]; 1386 /* 1387 * Note: this code assumes the above dependencies are 1388 * not cyclic. This *should* always be true. 1389 */ 1390 if (mtp->m_depend != -1) 1391 generate_check(match_types, mtp->m_depend, type); 1392 1393 emitop(mtp->m_optype); 1394 load_value(mtp->m_offset, mtp->m_size); 1395 load_const(mtp->m_value); 1396 emitop(OP_OFFSET_POP); 1397 1398 emitop(OP_EQ); 1399 1400 if (mtp->m_depend != -1) 1401 emitop(OP_AND); 1402 } 1403 1404 /* 1405 * Generate code based on the keyword argument. 1406 * This word is looked up in the match_types table 1407 * and checks a field within the packet for a given 1408 * value e.g. ether or ip type field. The match 1409 * can also have a dependency on another entry e.g. 1410 * "tcp" requires that the packet also be "ip". 1411 */ 1412 static int 1413 comparison(char *s) 1414 { 1415 unsigned int i, n_checks = 0; 1416 match_type_t *match_types; 1417 1418 switch (interface->mac_type) { 1419 case DL_ETHER: 1420 match_types = ether_match_types; 1421 break; 1422 case DL_IPNET: 1423 match_types = ipnet_match_types; 1424 break; 1425 default: 1426 return (0); 1427 } 1428 1429 for (i = 0; match_types[i].m_name != NULL; i++) { 1430 if (strcmp(s, match_types[i].m_name) != 0) 1431 continue; 1432 1433 n_checks++; 1434 generate_check(match_types, i, interface->mac_type); 1435 if (n_checks > 1) 1436 emitop(OP_OR); 1437 } 1438 1439 return (n_checks > 0); 1440 } 1441 1442 enum direction { ANY, TO, FROM }; 1443 enum direction dir; 1444 1445 /* 1446 * Generate code to match an IP address. The address 1447 * may be supplied either as a hostname or in dotted format. 1448 * For source packets both the IP source address and ARP 1449 * src are checked. 1450 * Note: we don't check packet type here - whether IP or ARP. 1451 * It's possible that we'll do an improper match. 1452 */ 1453 static void 1454 ipaddr_match(enum direction which, char *hostname, int inet_type) 1455 { 1456 bool_t found_host; 1457 int m = 0, n = 0; 1458 uint_t *addr4ptr; 1459 uint_t addr4; 1460 struct in6_addr *addr6ptr; 1461 int h_addr_index; 1462 struct hostent *hp = NULL; 1463 int error_num = 0; 1464 boolean_t freehp = B_FALSE; 1465 boolean_t first = B_TRUE; 1466 1467 /* 1468 * The addr4offset and addr6offset variables simplify the code which 1469 * generates the address comparison filter. With these two variables, 1470 * duplicate code need not exist for the TO and FROM case. 1471 * A value of -1 describes the ANY case (TO and FROM). 1472 */ 1473 int addr4offset; 1474 int addr6offset; 1475 1476 found_host = 0; 1477 1478 if (tokentype == ADDR_IP) { 1479 hp = lgetipnodebyname(hostname, AF_INET, 0, &error_num); 1480 if (hp == NULL) { 1481 hp = getipnodebyname(hostname, AF_INET, 0, &error_num); 1482 freehp = 1; 1483 } 1484 if (hp == NULL) { 1485 if (error_num == TRY_AGAIN) { 1486 pr_err("couldn't resolve %s (try again later)", 1487 hostname); 1488 } else { 1489 pr_err("couldn't resolve %s", hostname); 1490 } 1491 } 1492 inet_type = IPV4_ONLY; 1493 } else if (tokentype == ADDR_IP6) { 1494 hp = lgetipnodebyname(hostname, AF_INET6, 0, &error_num); 1495 if (hp == NULL) { 1496 hp = getipnodebyname(hostname, AF_INET6, 0, &error_num); 1497 freehp = 1; 1498 } 1499 if (hp == NULL) { 1500 if (error_num == TRY_AGAIN) { 1501 pr_err("couldn't resolve %s (try again later)", 1502 hostname); 1503 } else { 1504 pr_err("couldn't resolve %s", hostname); 1505 } 1506 } 1507 inet_type = IPV6_ONLY; 1508 } else { 1509 /* Some hostname i.e. tokentype is ALPHA */ 1510 switch (inet_type) { 1511 case IPV4_ONLY: 1512 /* Only IPv4 address is needed */ 1513 hp = lgetipnodebyname(hostname, AF_INET, 0, &error_num); 1514 if (hp == NULL) { 1515 hp = getipnodebyname(hostname, AF_INET, 0, 1516 &error_num); 1517 freehp = 1; 1518 } 1519 if (hp != NULL) { 1520 found_host = 1; 1521 } 1522 break; 1523 case IPV6_ONLY: 1524 /* Only IPv6 address is needed */ 1525 hp = lgetipnodebyname(hostname, AF_INET6, 0, 1526 &error_num); 1527 if (hp == NULL) { 1528 hp = getipnodebyname(hostname, AF_INET6, 0, 1529 &error_num); 1530 freehp = 1; 1531 } 1532 if (hp != NULL) { 1533 found_host = 1; 1534 } 1535 break; 1536 case IPV4_AND_IPV6: 1537 /* Both IPv4 and IPv6 are needed */ 1538 hp = lgetipnodebyname(hostname, AF_INET6, 1539 AI_ALL | AI_V4MAPPED, &error_num); 1540 if (hp == NULL) { 1541 hp = getipnodebyname(hostname, AF_INET6, 1542 AI_ALL | AI_V4MAPPED, &error_num); 1543 freehp = 1; 1544 } 1545 if (hp != NULL) { 1546 found_host = 1; 1547 } 1548 break; 1549 default: 1550 found_host = 0; 1551 } 1552 1553 if (!found_host) { 1554 if (error_num == TRY_AGAIN) { 1555 pr_err("could not resolve %s (try again later)", 1556 hostname); 1557 } else { 1558 pr_err("could not resolve %s", hostname); 1559 } 1560 } 1561 } 1562 1563 switch (which) { 1564 case TO: 1565 addr4offset = IPV4_DSTADDR_OFFSET; 1566 addr6offset = IPV6_DSTADDR_OFFSET; 1567 break; 1568 case FROM: 1569 addr4offset = IPV4_SRCADDR_OFFSET; 1570 addr6offset = IPV6_SRCADDR_OFFSET; 1571 break; 1572 case ANY: 1573 addr4offset = -1; 1574 addr6offset = -1; 1575 break; 1576 } 1577 1578 /* 1579 * The code below generates the filter. 1580 */ 1581 if (hp != NULL && hp->h_addrtype == AF_INET) { 1582 ethertype_match(interface->network_type_ip); 1583 emitop(OP_BRFL); 1584 n = chain(n); 1585 emitop(OP_OFFSET_LINK); 1586 h_addr_index = 0; 1587 addr4ptr = (uint_t *)hp->h_addr_list[h_addr_index]; 1588 while (addr4ptr != NULL) { 1589 if (addr4offset == -1) { 1590 compare_addr_v4(IPV4_SRCADDR_OFFSET, 4, 1591 *addr4ptr); 1592 emitop(OP_BRTR); 1593 m = chain(m); 1594 compare_addr_v4(IPV4_DSTADDR_OFFSET, 4, 1595 *addr4ptr); 1596 } else { 1597 compare_addr_v4(addr4offset, 4, *addr4ptr); 1598 } 1599 addr4ptr = (uint_t *)hp->h_addr_list[++h_addr_index]; 1600 if (addr4ptr != NULL) { 1601 emitop(OP_BRTR); 1602 m = chain(m); 1603 } 1604 } 1605 if (m != 0) { 1606 resolve_chain(m); 1607 } 1608 emitop(OP_OFFSET_POP); 1609 resolve_chain(n); 1610 } else { 1611 /* first pass: IPv4 addresses */ 1612 h_addr_index = 0; 1613 addr6ptr = (struct in6_addr *)hp->h_addr_list[h_addr_index]; 1614 first = B_TRUE; 1615 while (addr6ptr != NULL) { 1616 if (IN6_IS_ADDR_V4MAPPED(addr6ptr)) { 1617 if (first) { 1618 ethertype_match( 1619 interface->network_type_ip); 1620 emitop(OP_BRFL); 1621 n = chain(n); 1622 emitop(OP_OFFSET_LINK); 1623 first = B_FALSE; 1624 } else { 1625 emitop(OP_BRTR); 1626 m = chain(m); 1627 } 1628 IN6_V4MAPPED_TO_INADDR(addr6ptr, 1629 (struct in_addr *)&addr4); 1630 if (addr4offset == -1) { 1631 compare_addr_v4(IPV4_SRCADDR_OFFSET, 4, 1632 addr4); 1633 emitop(OP_BRTR); 1634 m = chain(m); 1635 compare_addr_v4(IPV4_DSTADDR_OFFSET, 4, 1636 addr4); 1637 } else { 1638 compare_addr_v4(addr4offset, 4, addr4); 1639 } 1640 } 1641 addr6ptr = (struct in6_addr *) 1642 hp->h_addr_list[++h_addr_index]; 1643 } 1644 /* second pass: IPv6 addresses */ 1645 h_addr_index = 0; 1646 addr6ptr = (struct in6_addr *)hp->h_addr_list[h_addr_index]; 1647 first = B_TRUE; 1648 while (addr6ptr != NULL) { 1649 if (!IN6_IS_ADDR_V4MAPPED(addr6ptr)) { 1650 if (first) { 1651 /* 1652 * bypass check for IPv6 addresses 1653 * when we have an IPv4 packet 1654 */ 1655 if (n != 0) { 1656 emitop(OP_BRTR); 1657 m = chain(m); 1658 emitop(OP_BRFL); 1659 m = chain(m); 1660 resolve_chain(n); 1661 n = 0; 1662 } 1663 ethertype_match( 1664 interface->network_type_ipv6); 1665 emitop(OP_BRFL); 1666 n = chain(n); 1667 emitop(OP_OFFSET_LINK); 1668 first = B_FALSE; 1669 } else { 1670 emitop(OP_BRTR); 1671 m = chain(m); 1672 } 1673 if (addr6offset == -1) { 1674 compare_addr_v6(IPV6_SRCADDR_OFFSET, 1675 16, *addr6ptr); 1676 emitop(OP_BRTR); 1677 m = chain(m); 1678 compare_addr_v6(IPV6_DSTADDR_OFFSET, 1679 16, *addr6ptr); 1680 } else { 1681 compare_addr_v6(addr6offset, 16, 1682 *addr6ptr); 1683 } 1684 } 1685 addr6ptr = (struct in6_addr *) 1686 hp->h_addr_list[++h_addr_index]; 1687 } 1688 if (m != 0) { 1689 resolve_chain(m); 1690 } 1691 emitop(OP_OFFSET_POP); 1692 resolve_chain(n); 1693 } 1694 1695 /* only free struct hostent returned by getipnodebyname() */ 1696 if (freehp) { 1697 freehostent(hp); 1698 } 1699 } 1700 1701 /* 1702 * Match on zoneid. The arg zone passed in is in network byte order. 1703 */ 1704 static void 1705 zone_match(enum direction which, uint64_t zone) 1706 { 1707 1708 switch (which) { 1709 case TO: 1710 compare_value_zone(IPNET_DSTZONE_OFFSET, zone); 1711 break; 1712 case FROM: 1713 compare_value_zone(IPNET_SRCZONE_OFFSET, zone); 1714 break; 1715 case ANY: 1716 compare_value_zone(IPNET_SRCZONE_OFFSET, zone); 1717 compare_value_zone(IPNET_DSTZONE_OFFSET, zone); 1718 emitop(OP_OR); 1719 } 1720 } 1721 1722 /* 1723 * Generate code to match an AppleTalk address. The address 1724 * must be given as two numbers with a dot between 1725 * 1726 */ 1727 static void 1728 ataddr_match(enum direction which, char *hostname) 1729 { 1730 uint_t net; 1731 uint_t node; 1732 uint_t m, n; 1733 1734 sscanf(hostname, "%u.%u", &net, &node); 1735 1736 emitop(OP_OFFSET_LINK); 1737 switch (which) { 1738 case TO: 1739 compare_value(AT_DST_NET_OFFSET, 2, net); 1740 emitop(OP_BRFL); 1741 m = chain(0); 1742 compare_value(AT_DST_NODE_OFFSET, 1, node); 1743 resolve_chain(m); 1744 break; 1745 case FROM: 1746 compare_value(AT_SRC_NET_OFFSET, 2, net); 1747 emitop(OP_BRFL); 1748 m = chain(0); 1749 compare_value(AT_SRC_NODE_OFFSET, 1, node); 1750 resolve_chain(m); 1751 break; 1752 case ANY: 1753 compare_value(AT_DST_NET_OFFSET, 2, net); 1754 emitop(OP_BRFL); 1755 m = chain(0); 1756 compare_value(AT_DST_NODE_OFFSET, 1, node); 1757 resolve_chain(m); 1758 emitop(OP_BRTR); 1759 n = chain(0); 1760 compare_value(AT_SRC_NET_OFFSET, 2, net); 1761 emitop(OP_BRFL); 1762 m = chain(0); 1763 compare_value(AT_SRC_NODE_OFFSET, 1, node); 1764 resolve_chain(m); 1765 resolve_chain(n); 1766 break; 1767 } 1768 emitop(OP_OFFSET_POP); 1769 } 1770 1771 /* 1772 * Compare ethernet addresses. The address may 1773 * be provided either as a hostname or as a 1774 * 6 octet colon-separated address. 1775 */ 1776 static void 1777 etheraddr_match(enum direction which, char *hostname) 1778 { 1779 uint_t addr; 1780 ushort_t *addrp; 1781 int to_offset, from_offset; 1782 struct ether_addr e, *ep = NULL; 1783 int m; 1784 1785 /* 1786 * First, check the interface type for whether src/dest address 1787 * is determinable; if not, retreat early. 1788 */ 1789 switch (interface->mac_type) { 1790 case DL_ETHER: 1791 from_offset = ETHERADDRL; 1792 to_offset = 0; 1793 break; 1794 1795 case DL_IB: 1796 /* 1797 * If an ethernet address is attempted to be used 1798 * on an IPoIB interface, flag error. Link address 1799 * based filtering is unsupported on IPoIB, so there 1800 * is no ipibaddr_match() or parsing support for IPoIB 1801 * 20 byte link addresses. 1802 */ 1803 pr_err("filter option unsupported on media"); 1804 break; 1805 1806 case DL_FDDI: 1807 from_offset = 7; 1808 to_offset = 1; 1809 break; 1810 1811 default: 1812 /* 1813 * Where do we find "ether" address for FDDI & TR? 1814 * XXX can improve? ~sparker 1815 */ 1816 load_const(1); 1817 return; 1818 } 1819 1820 if (isxdigit(*hostname)) 1821 ep = ether_aton(hostname); 1822 if (ep == NULL) { 1823 if (ether_hostton(hostname, &e)) 1824 if (!arp_for_ether(hostname, &e)) 1825 pr_err("cannot obtain ether addr for %s", 1826 hostname); 1827 ep = &e; 1828 } 1829 memcpy(&addr, (ushort_t *)ep, 4); 1830 addrp = (ushort_t *)ep + 2; 1831 1832 emitop(OP_OFFSET_ZERO); 1833 switch (which) { 1834 case TO: 1835 compare_value(to_offset, 4, ntohl(addr)); 1836 emitop(OP_BRFL); 1837 m = chain(0); 1838 compare_value(to_offset + 4, 2, ntohs(*addrp)); 1839 resolve_chain(m); 1840 break; 1841 case FROM: 1842 compare_value(from_offset, 4, ntohl(addr)); 1843 emitop(OP_BRFL); 1844 m = chain(0); 1845 compare_value(from_offset + 4, 2, ntohs(*addrp)); 1846 resolve_chain(m); 1847 break; 1848 case ANY: 1849 compare_value(to_offset, 4, ntohl(addr)); 1850 compare_value(to_offset + 4, 2, ntohs(*addrp)); 1851 emitop(OP_AND); 1852 emitop(OP_BRTR); 1853 m = chain(0); 1854 1855 compare_value(from_offset, 4, ntohl(addr)); 1856 compare_value(from_offset + 4, 2, ntohs(*addrp)); 1857 emitop(OP_AND); 1858 resolve_chain(m); 1859 break; 1860 } 1861 emitop(OP_OFFSET_POP); 1862 } 1863 1864 static void 1865 ethertype_match(int val) 1866 { 1867 int ether_offset = interface->network_type_offset; 1868 1869 /* 1870 * If the user is interested in ethertype VLAN, 1871 * then we need to set the offset to the beginning of the packet. 1872 * But if the user is interested in another ethertype, 1873 * such as IPv4, then we need to take into consideration 1874 * the fact that the packet might be VLAN tagged. 1875 */ 1876 if (interface->mac_type == DL_ETHER || 1877 interface->mac_type == DL_CSMACD) { 1878 if (val != ETHERTYPE_VLAN) { 1879 /* 1880 * OP_OFFSET_ETHERTYPE puts us at the ethertype 1881 * field whether or not there is a VLAN tag, 1882 * so ether_offset goes to zero if we get here. 1883 */ 1884 emitop(OP_OFFSET_ETHERTYPE); 1885 ether_offset = 0; 1886 } else { 1887 emitop(OP_OFFSET_ZERO); 1888 } 1889 } 1890 compare_value(ether_offset, interface->network_type_len, val); 1891 if (interface->mac_type == DL_ETHER || 1892 interface->mac_type == DL_CSMACD) { 1893 emitop(OP_OFFSET_POP); 1894 } 1895 } 1896 1897 static void 1898 ipnettype_match(int val) 1899 { 1900 int ipnet_offset = interface->network_type_offset; 1901 1902 emitop(OP_OFFSET_ETHERTYPE); 1903 compare_value(ipnet_offset, 2, val); 1904 } 1905 1906 /* 1907 * Match a network address. The host part 1908 * is masked out. The network address may 1909 * be supplied either as a netname or in 1910 * IP dotted format. The mask to be used 1911 * for the comparison is assumed from the 1912 * address format (see comment below). 1913 */ 1914 static void 1915 netaddr_match(enum direction which, char *netname) 1916 { 1917 uint_t addr; 1918 uint_t mask = 0xff000000; 1919 uint_t m; 1920 struct netent *np; 1921 1922 if (isdigit(*netname)) { 1923 addr = inet_network(netname); 1924 } else { 1925 np = getnetbyname(netname); 1926 if (np == NULL) 1927 pr_err("net %s not known", netname); 1928 addr = np->n_net; 1929 } 1930 1931 /* 1932 * Left justify the address and figure 1933 * out a mask based on the supplied address. 1934 * Set the mask according to the number of zero 1935 * low-order bytes. 1936 * Note: this works only for whole octet masks. 1937 */ 1938 if (addr) { 1939 while ((addr & ~mask) != 0) { 1940 mask |= (mask >> 8); 1941 } 1942 } 1943 1944 emitop(OP_OFFSET_LINK); 1945 switch (which) { 1946 case TO: 1947 compare_value_mask(16, 4, addr, mask); 1948 break; 1949 case FROM: 1950 compare_value_mask(12, 4, addr, mask); 1951 break; 1952 case ANY: 1953 compare_value_mask(12, 4, addr, mask); 1954 emitop(OP_BRTR); 1955 m = chain(0); 1956 compare_value_mask(16, 4, addr, mask); 1957 resolve_chain(m); 1958 break; 1959 } 1960 emitop(OP_OFFSET_POP); 1961 } 1962 1963 /* 1964 * Match either a UDP or TCP port number. 1965 * The port number may be provided either as 1966 * port name as listed in /etc/services ("nntp") or as 1967 * the port number itself (2049). 1968 */ 1969 static void 1970 port_match(enum direction which, char *portname) 1971 { 1972 struct servent *sp; 1973 uint_t m, port; 1974 1975 if (isdigit(*portname)) { 1976 port = atoi(portname); 1977 } else { 1978 sp = getservbyname(portname, NULL); 1979 if (sp == NULL) 1980 pr_err("invalid port number or name: %s", portname); 1981 port = ntohs(sp->s_port); 1982 } 1983 1984 emitop(OP_OFFSET_IP); 1985 1986 switch (which) { 1987 case TO: 1988 compare_value(2, 2, port); 1989 break; 1990 case FROM: 1991 compare_value(0, 2, port); 1992 break; 1993 case ANY: 1994 compare_value(2, 2, port); 1995 emitop(OP_BRTR); 1996 m = chain(0); 1997 compare_value(0, 2, port); 1998 resolve_chain(m); 1999 break; 2000 } 2001 emitop(OP_OFFSET_POP); 2002 } 2003 2004 /* 2005 * Generate code to match packets with a specific 2006 * RPC program number. If the progname is a name 2007 * it is converted to a number via /etc/rpc. 2008 * The program version and/or procedure may be provided 2009 * as extra qualifiers. 2010 */ 2011 static void 2012 rpc_match_prog(enum direction which, char *progname, int vers, int proc) 2013 { 2014 struct rpcent *rpc; 2015 uint_t prog; 2016 uint_t m, n; 2017 2018 if (isdigit(*progname)) { 2019 prog = atoi(progname); 2020 } else { 2021 rpc = (struct rpcent *)getrpcbyname(progname); 2022 if (rpc == NULL) 2023 pr_err("invalid program name: %s", progname); 2024 prog = rpc->r_number; 2025 } 2026 2027 emitop(OP_OFFSET_RPC); 2028 emitop(OP_BRFL); 2029 n = chain(0); 2030 2031 compare_value(12, 4, prog); 2032 emitop(OP_BRFL); 2033 m = chain(0); 2034 if (vers >= 0) { 2035 compare_value(16, 4, vers); 2036 emitop(OP_BRFL); 2037 m = chain(m); 2038 } 2039 if (proc >= 0) { 2040 compare_value(20, 4, proc); 2041 emitop(OP_BRFL); 2042 m = chain(m); 2043 } 2044 2045 switch (which) { 2046 case TO: 2047 compare_value(4, 4, CALL); 2048 emitop(OP_BRFL); 2049 m = chain(m); 2050 break; 2051 case FROM: 2052 compare_value(4, 4, REPLY); 2053 emitop(OP_BRFL); 2054 m = chain(m); 2055 break; 2056 } 2057 resolve_chain(m); 2058 resolve_chain(n); 2059 emitop(OP_OFFSET_POP); 2060 } 2061 2062 /* 2063 * Generate code to parse a field specification 2064 * and load the value of the field from the packet 2065 * onto the operand stack. 2066 * The field offset may be specified relative to the 2067 * beginning of the ether header, IP header, UDP header, 2068 * or TCP header. An optional size specification may 2069 * be provided following a colon. If no size is given 2070 * one byte is assumed e.g. 2071 * 2072 * ether[0] The first byte of the ether header 2073 * ip[2:2] The second 16 bit field of the IP header 2074 */ 2075 static void 2076 load_field() 2077 { 2078 int size = 1; 2079 int s; 2080 2081 2082 if (EQ("ether")) 2083 emitop(OP_OFFSET_ZERO); 2084 else if (EQ("ip") || EQ("ip6") || EQ("pppoed") || EQ("pppoes")) 2085 emitop(OP_OFFSET_LINK); 2086 else if (EQ("udp") || EQ("tcp") || EQ("icmp") || EQ("ip-in-ip") || 2087 EQ("ah") || EQ("esp")) 2088 emitop(OP_OFFSET_IP); 2089 else 2090 pr_err("invalid field type"); 2091 next(); 2092 s = opstack; 2093 expression(); 2094 if (opstack != s + 1) 2095 pr_err("invalid field offset"); 2096 opstack--; 2097 if (*token == ':') { 2098 next(); 2099 if (tokentype != NUMBER) 2100 pr_err("field size expected"); 2101 size = tokenval; 2102 if (size != 1 && size != 2 && size != 4) 2103 pr_err("field size invalid"); 2104 next(); 2105 } 2106 if (*token != ']') 2107 pr_err("right bracket expected"); 2108 2109 load_value(-1, size); 2110 emitop(OP_OFFSET_POP); 2111 } 2112 2113 /* 2114 * Check that the operand stack 2115 * contains n arguments 2116 */ 2117 static void 2118 checkstack(int numargs) 2119 { 2120 if (opstack != numargs) 2121 pr_err("invalid expression at \"%s\".", token); 2122 } 2123 2124 static void 2125 primary() 2126 { 2127 int m, m2, s; 2128 2129 for (;;) { 2130 if (tokentype == FIELD) { 2131 load_field(); 2132 opstack++; 2133 next(); 2134 break; 2135 } 2136 2137 if (comparison(token)) { 2138 opstack++; 2139 next(); 2140 break; 2141 } 2142 2143 if (EQ("not") || EQ("!")) { 2144 next(); 2145 s = opstack; 2146 primary(); 2147 checkstack(s + 1); 2148 emitop(OP_NOT); 2149 break; 2150 } 2151 2152 if (EQ("(")) { 2153 next(); 2154 s = opstack; 2155 expression(); 2156 checkstack(s + 1); 2157 if (!EQ(")")) 2158 pr_err("right paren expected"); 2159 next(); 2160 } 2161 2162 if (EQ("to") || EQ("dst")) { 2163 dir = TO; 2164 next(); 2165 continue; 2166 } 2167 2168 if (EQ("from") || EQ("src")) { 2169 dir = FROM; 2170 next(); 2171 continue; 2172 } 2173 2174 if (EQ("ether")) { 2175 eaddr = 1; 2176 next(); 2177 continue; 2178 } 2179 2180 if (EQ("proto")) { 2181 next(); 2182 if (tokentype != NUMBER) 2183 pr_err("IP proto type expected"); 2184 emitop(OP_OFFSET_LINK); 2185 compare_value(IPV4_TYPE_HEADER_OFFSET, 1, tokenval); 2186 emitop(OP_OFFSET_POP); 2187 opstack++; 2188 next(); 2189 continue; 2190 } 2191 2192 if (EQ("broadcast")) { 2193 /* 2194 * Be tricky: FDDI ether dst address begins at 2195 * byte one. Since the address is really six 2196 * bytes long, this works for FDDI & ethernet. 2197 * XXX - Token ring? 2198 */ 2199 emitop(OP_OFFSET_ZERO); 2200 if (interface->mac_type == DL_IB) 2201 pr_err("filter option unsupported on media"); 2202 compare_value(1, 4, 0xffffffff); 2203 emitop(OP_OFFSET_POP); 2204 opstack++; 2205 next(); 2206 break; 2207 } 2208 2209 if (EQ("multicast")) { 2210 /* XXX Token ring? */ 2211 emitop(OP_OFFSET_ZERO); 2212 if (interface->mac_type == DL_FDDI) { 2213 compare_value_mask(1, 1, 0x01, 0x01); 2214 } else if (interface->mac_type == DL_IB) { 2215 pr_err("filter option unsupported on media"); 2216 } else { 2217 compare_value_mask(0, 1, 0x01, 0x01); 2218 } 2219 emitop(OP_OFFSET_POP); 2220 opstack++; 2221 next(); 2222 break; 2223 } 2224 2225 if (EQ("decnet")) { 2226 /* XXX Token ring? */ 2227 if (interface->mac_type == DL_FDDI) { 2228 load_value(19, 2); /* ether type */ 2229 load_const(0x6000); 2230 emitop(OP_GE); 2231 emitop(OP_BRFL); 2232 m = chain(0); 2233 load_value(19, 2); /* ether type */ 2234 load_const(0x6009); 2235 emitop(OP_LE); 2236 resolve_chain(m); 2237 } else { 2238 emitop(OP_OFFSET_ETHERTYPE); 2239 load_value(0, 2); /* ether type */ 2240 load_const(0x6000); 2241 emitop(OP_GE); 2242 emitop(OP_BRFL); 2243 m = chain(0); 2244 load_value(0, 2); /* ether type */ 2245 load_const(0x6009); 2246 emitop(OP_LE); 2247 resolve_chain(m); 2248 emitop(OP_OFFSET_POP); 2249 } 2250 opstack++; 2251 next(); 2252 break; 2253 } 2254 2255 if (EQ("vlan-id")) { 2256 next(); 2257 if (tokentype != NUMBER) 2258 pr_err("vlan id expected"); 2259 emitop(OP_OFFSET_ZERO); 2260 ethertype_match(ETHERTYPE_VLAN); 2261 emitop(OP_BRFL); 2262 m = chain(0); 2263 compare_value_mask(VLAN_ID_OFFSET, 2, tokenval, 2264 VLAN_ID_MASK); 2265 resolve_chain(m); 2266 emitop(OP_OFFSET_POP); 2267 opstack++; 2268 next(); 2269 break; 2270 } 2271 2272 if (EQ("apple")) { 2273 /* 2274 * Appletalk also appears in 802.2 2275 * packets, so check for the ethertypes 2276 * at offset 12 and 20 in the MAC header. 2277 */ 2278 ethertype_match(ETHERTYPE_AT); 2279 emitop(OP_BRTR); 2280 m = chain(0); 2281 ethertype_match(ETHERTYPE_AARP); 2282 emitop(OP_BRTR); 2283 m = chain(m); 2284 compare_value(20, 2, ETHERTYPE_AT); /* 802.2 */ 2285 emitop(OP_BRTR); 2286 m = chain(m); 2287 compare_value(20, 2, ETHERTYPE_AARP); /* 802.2 */ 2288 resolve_chain(m); 2289 opstack++; 2290 next(); 2291 break; 2292 } 2293 2294 if (EQ("vlan")) { 2295 ethertype_match(ETHERTYPE_VLAN); 2296 compare_value_mask(VLAN_ID_OFFSET, 2, 0, VLAN_ID_MASK); 2297 emitop(OP_NOT); 2298 emitop(OP_AND); 2299 opstack++; 2300 next(); 2301 break; 2302 } 2303 2304 if (EQ("bootp") || EQ("dhcp")) { 2305 ethertype_match(interface->network_type_ip); 2306 emitop(OP_BRFL); 2307 m = chain(0); 2308 emitop(OP_OFFSET_LINK); 2309 compare_value(9, 1, IPPROTO_UDP); 2310 emitop(OP_OFFSET_POP); 2311 emitop(OP_BRFL); 2312 m = chain(m); 2313 emitop(OP_OFFSET_IP); 2314 compare_value(0, 4, 2315 (IPPORT_BOOTPS << 16) | IPPORT_BOOTPC); 2316 emitop(OP_BRTR); 2317 m2 = chain(0); 2318 compare_value(0, 4, 2319 (IPPORT_BOOTPC << 16) | IPPORT_BOOTPS); 2320 resolve_chain(m2); 2321 emitop(OP_OFFSET_POP); 2322 resolve_chain(m); 2323 opstack++; 2324 dir = ANY; 2325 next(); 2326 break; 2327 } 2328 2329 if (EQ("dhcp6")) { 2330 ethertype_match(interface->network_type_ipv6); 2331 emitop(OP_BRFL); 2332 m = chain(0); 2333 emitop(OP_OFFSET_LINK); 2334 compare_value(6, 1, IPPROTO_UDP); 2335 emitop(OP_OFFSET_POP); 2336 emitop(OP_BRFL); 2337 m = chain(m); 2338 emitop(OP_OFFSET_IP); 2339 compare_value(2, 2, IPPORT_DHCPV6S); 2340 emitop(OP_BRTR); 2341 m2 = chain(0); 2342 compare_value(2, 2, IPPORT_DHCPV6C); 2343 resolve_chain(m2); 2344 emitop(OP_OFFSET_POP); 2345 resolve_chain(m); 2346 opstack++; 2347 dir = ANY; 2348 next(); 2349 break; 2350 } 2351 2352 if (EQ("ethertype")) { 2353 next(); 2354 if (tokentype != NUMBER) 2355 pr_err("ether type expected"); 2356 ethertype_match(tokenval); 2357 opstack++; 2358 next(); 2359 break; 2360 } 2361 2362 if (EQ("pppoe")) { 2363 ethertype_match(ETHERTYPE_PPPOED); 2364 ethertype_match(ETHERTYPE_PPPOES); 2365 emitop(OP_OR); 2366 opstack++; 2367 next(); 2368 break; 2369 } 2370 2371 if (EQ("inet")) { 2372 next(); 2373 if (EQ("host")) 2374 next(); 2375 if (tokentype != ALPHA && tokentype != ADDR_IP) 2376 pr_err("host/IPv4 addr expected after inet"); 2377 ipaddr_match(dir, token, IPV4_ONLY); 2378 opstack++; 2379 next(); 2380 break; 2381 } 2382 2383 if (EQ("inet6")) { 2384 next(); 2385 if (EQ("host")) 2386 next(); 2387 if (tokentype != ALPHA && tokentype != ADDR_IP6) 2388 pr_err("host/IPv6 addr expected after inet6"); 2389 ipaddr_match(dir, token, IPV6_ONLY); 2390 opstack++; 2391 next(); 2392 break; 2393 } 2394 2395 if (EQ("length")) { 2396 emitop(OP_LOAD_LENGTH); 2397 opstack++; 2398 next(); 2399 break; 2400 } 2401 2402 if (EQ("less")) { 2403 next(); 2404 if (tokentype != NUMBER) 2405 pr_err("packet length expected"); 2406 emitop(OP_LOAD_LENGTH); 2407 load_const(tokenval); 2408 emitop(OP_LT); 2409 opstack++; 2410 next(); 2411 break; 2412 } 2413 2414 if (EQ("greater")) { 2415 next(); 2416 if (tokentype != NUMBER) 2417 pr_err("packet length expected"); 2418 emitop(OP_LOAD_LENGTH); 2419 load_const(tokenval); 2420 emitop(OP_GT); 2421 opstack++; 2422 next(); 2423 break; 2424 } 2425 2426 if (EQ("nofrag")) { 2427 emitop(OP_OFFSET_LINK); 2428 compare_value_mask(6, 2, 0, 0x1fff); 2429 emitop(OP_OFFSET_POP); 2430 emitop(OP_BRFL); 2431 m = chain(0); 2432 ethertype_match(interface->network_type_ip); 2433 resolve_chain(m); 2434 opstack++; 2435 next(); 2436 break; 2437 } 2438 2439 if (EQ("net") || EQ("dstnet") || EQ("srcnet")) { 2440 if (EQ("dstnet")) 2441 dir = TO; 2442 else if (EQ("srcnet")) 2443 dir = FROM; 2444 next(); 2445 netaddr_match(dir, token); 2446 dir = ANY; 2447 opstack++; 2448 next(); 2449 break; 2450 } 2451 2452 if (EQ("port") || EQ("srcport") || EQ("dstport")) { 2453 if (EQ("dstport")) 2454 dir = TO; 2455 else if (EQ("srcport")) 2456 dir = FROM; 2457 next(); 2458 port_match(dir, token); 2459 dir = ANY; 2460 opstack++; 2461 next(); 2462 break; 2463 } 2464 2465 if (EQ("rpc")) { 2466 uint_t vers, proc; 2467 char savetoken[32]; 2468 2469 vers = proc = -1; 2470 next(); 2471 (void) strlcpy(savetoken, token, sizeof (savetoken)); 2472 next(); 2473 if (*token == ',') { 2474 next(); 2475 if (tokentype != NUMBER) 2476 pr_err("version number expected"); 2477 vers = tokenval; 2478 next(); 2479 } 2480 if (*token == ',') { 2481 next(); 2482 if (tokentype != NUMBER) 2483 pr_err("proc number expected"); 2484 proc = tokenval; 2485 next(); 2486 } 2487 rpc_match_prog(dir, savetoken, vers, proc); 2488 dir = ANY; 2489 opstack++; 2490 break; 2491 } 2492 2493 if (EQ("slp")) { 2494 /* filter out TCP handshakes */ 2495 emitop(OP_OFFSET_LINK); 2496 compare_value(9, 1, IPPROTO_TCP); 2497 emitop(OP_LOAD_CONST); 2498 emitval(52); 2499 emitop(OP_LOAD_CONST); 2500 emitval(2); 2501 emitop(OP_LOAD_SHORT); 2502 emitop(OP_GE); 2503 emitop(OP_AND); /* proto == TCP && len < 52 */ 2504 emitop(OP_NOT); 2505 emitop(OP_BRFL); /* pkt too short to be a SLP call */ 2506 m = chain(0); 2507 2508 emitop(OP_OFFSET_POP); 2509 emitop(OP_OFFSET_SLP); 2510 resolve_chain(m); 2511 opstack++; 2512 next(); 2513 break; 2514 } 2515 2516 if (EQ("ldap")) { 2517 dir = ANY; 2518 port_match(dir, "ldap"); 2519 opstack++; 2520 next(); 2521 break; 2522 } 2523 2524 if (EQ("and") || EQ("or")) { 2525 break; 2526 } 2527 2528 if (EQ("zone")) { 2529 next(); 2530 if (tokentype != NUMBER) 2531 pr_err("zoneid expected"); 2532 zone_match(dir, BE_64((uint64_t)(tokenval))); 2533 opstack++; 2534 next(); 2535 break; 2536 } 2537 2538 if (EQ("gateway")) { 2539 next(); 2540 if (eaddr || tokentype != ALPHA) 2541 pr_err("hostname required: %s", token); 2542 etheraddr_match(dir, token); 2543 dir = ANY; 2544 emitop(OP_BRFL); 2545 m = chain(0); 2546 ipaddr_match(dir, token, IPV4_AND_IPV6); 2547 emitop(OP_NOT); 2548 resolve_chain(m); 2549 opstack++; 2550 next(); 2551 } 2552 2553 if (EQ("host") || EQ("between") || 2554 tokentype == ALPHA || /* assume its a hostname */ 2555 tokentype == ADDR_IP || 2556 tokentype == ADDR_IP6 || 2557 tokentype == ADDR_AT || 2558 tokentype == ADDR_ETHER) { 2559 if (EQ("host") || EQ("between")) 2560 next(); 2561 if (eaddr || tokentype == ADDR_ETHER) { 2562 etheraddr_match(dir, token); 2563 } else if (tokentype == ALPHA) { 2564 ipaddr_match(dir, token, IPV4_AND_IPV6); 2565 } else if (tokentype == ADDR_AT) { 2566 ataddr_match(dir, token); 2567 } else if (tokentype == ADDR_IP) { 2568 ipaddr_match(dir, token, IPV4_ONLY); 2569 } else { 2570 ipaddr_match(dir, token, IPV6_ONLY); 2571 } 2572 dir = ANY; 2573 eaddr = 0; 2574 opstack++; 2575 next(); 2576 break; 2577 } 2578 2579 if (tokentype == NUMBER) { 2580 load_const(tokenval); 2581 opstack++; 2582 next(); 2583 break; 2584 } 2585 2586 break; /* unknown token */ 2587 } 2588 } 2589 2590 struct optable { 2591 char *op_tok; 2592 enum optype op_type; 2593 }; 2594 2595 static struct optable 2596 mulops[] = { 2597 "*", OP_MUL, 2598 "/", OP_DIV, 2599 "%", OP_REM, 2600 "&", OP_AND, 2601 "", OP_STOP, 2602 }; 2603 2604 static struct optable 2605 addops[] = { 2606 "+", OP_ADD, 2607 "-", OP_SUB, 2608 "|", OP_OR, 2609 "^", OP_XOR, 2610 "", OP_STOP, 2611 }; 2612 2613 static struct optable 2614 compareops[] = { 2615 "==", OP_EQ, 2616 "=", OP_EQ, 2617 "!=", OP_NE, 2618 ">", OP_GT, 2619 ">=", OP_GE, 2620 "<", OP_LT, 2621 "<=", OP_LE, 2622 "", OP_STOP, 2623 }; 2624 2625 /* 2626 * Using the table, find the operator 2627 * that corresponds to the token. 2628 * Return 0 if not found. 2629 */ 2630 static int 2631 find_op(char *tok, struct optable *table) 2632 { 2633 struct optable *op; 2634 2635 for (op = table; *op->op_tok; op++) { 2636 if (strcmp(tok, op->op_tok) == 0) 2637 return (op->op_type); 2638 } 2639 2640 return (0); 2641 } 2642 2643 static void 2644 expr_mul() 2645 { 2646 int op; 2647 int s = opstack; 2648 2649 primary(); 2650 while (op = find_op(token, mulops)) { 2651 next(); 2652 primary(); 2653 checkstack(s + 2); 2654 emitop(op); 2655 opstack--; 2656 } 2657 } 2658 2659 static void 2660 expr_add() 2661 { 2662 int op, s = opstack; 2663 2664 expr_mul(); 2665 while (op = find_op(token, addops)) { 2666 next(); 2667 expr_mul(); 2668 checkstack(s + 2); 2669 emitop(op); 2670 opstack--; 2671 } 2672 } 2673 2674 static void 2675 expr_compare() 2676 { 2677 int op, s = opstack; 2678 2679 expr_add(); 2680 while (op = find_op(token, compareops)) { 2681 next(); 2682 expr_add(); 2683 checkstack(s + 2); 2684 emitop(op); 2685 opstack--; 2686 } 2687 } 2688 2689 /* 2690 * Alternation ("and") is difficult because 2691 * an implied "and" is acknowledge between 2692 * two adjacent primaries. Just keep calling 2693 * the lower-level expression routine until 2694 * no value is added to the opstack. 2695 */ 2696 static void 2697 alternation() 2698 { 2699 int m = 0; 2700 int s = opstack; 2701 2702 expr_compare(); 2703 checkstack(s + 1); 2704 for (;;) { 2705 if (EQ("and")) 2706 next(); 2707 emitop(OP_BRFL); 2708 m = chain(m); 2709 expr_compare(); 2710 if (opstack != s + 2) 2711 break; 2712 opstack--; 2713 } 2714 unemit(2); 2715 resolve_chain(m); 2716 } 2717 2718 static void 2719 expression() 2720 { 2721 int m = 0; 2722 int s = opstack; 2723 2724 alternation(); 2725 while (EQ("or") || EQ(",")) { 2726 emitop(OP_BRTR); 2727 m = chain(m); 2728 next(); 2729 alternation(); 2730 checkstack(s + 2); 2731 opstack--; 2732 } 2733 resolve_chain(m); 2734 } 2735 2736 /* 2737 * Take n args from the argv list 2738 * and concatenate them into a single string. 2739 */ 2740 char * 2741 concat_args(char **argv, int argc) 2742 { 2743 int i, len; 2744 char *str, *p; 2745 2746 /* First add the lengths of all the strings */ 2747 len = 0; 2748 for (i = 0; i < argc; i++) 2749 len += strlen(argv[i]) + 1; 2750 2751 /* allocate the big string */ 2752 str = (char *)malloc(len); 2753 if (str == NULL) 2754 pr_err("no mem"); 2755 2756 p = str; 2757 2758 /* 2759 * Concat the strings into the big 2760 * string using a space as separator 2761 */ 2762 for (i = 0; i < argc; i++) { 2763 strcpy(p, argv[i]); 2764 p += strlen(p); 2765 *p++ = ' '; 2766 } 2767 *--p = '\0'; 2768 2769 return (str); 2770 } 2771 2772 /* 2773 * Take the expression in the string "expr" 2774 * and compile it into the code array. 2775 * Print the generated code if the print 2776 * arg is set. 2777 */ 2778 void 2779 compile(char *expr, int print) 2780 { 2781 expr = strdup(expr); 2782 if (expr == NULL) 2783 pr_err("no mem"); 2784 curr_op = oplist; 2785 tkp = expr; 2786 dir = ANY; 2787 2788 next(); 2789 if (tokentype != EOL) 2790 expression(); 2791 emitop(OP_STOP); 2792 if (tokentype != EOL) 2793 pr_err("invalid expression"); 2794 optimize(oplist); 2795 if (print) 2796 codeprint(); 2797 } 2798 2799 /* 2800 * Lookup hostname in the arp cache. 2801 */ 2802 boolean_t 2803 arp_for_ether(char *hostname, struct ether_addr *ep) 2804 { 2805 struct arpreq ar; 2806 struct hostent *hp; 2807 struct sockaddr_in *sin; 2808 int error_num; 2809 int s; 2810 2811 memset(&ar, 0, sizeof (ar)); 2812 sin = (struct sockaddr_in *)&ar.arp_pa; 2813 sin->sin_family = AF_INET; 2814 hp = getipnodebyname(hostname, AF_INET, 0, &error_num); 2815 if (hp == NULL) { 2816 return (B_FALSE); 2817 } 2818 memcpy(&sin->sin_addr, hp->h_addr, sizeof (sin->sin_addr)); 2819 s = socket(AF_INET, SOCK_DGRAM, 0); 2820 if (s < 0) { 2821 return (B_FALSE); 2822 } 2823 if (ioctl(s, SIOCGARP, &ar) < 0) { 2824 close(s); 2825 return (B_FALSE); 2826 } 2827 close(s); 2828 memcpy(ep->ether_addr_octet, ar.arp_ha.sa_data, sizeof (*ep)); 2829 return (B_TRUE); 2830 } 2831