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