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 2007 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, m2, 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")) { 2098 next(); 2099 if (tokentype != NUMBER) 2100 pr_err("IP proto type expected"); 2101 emitop(OP_OFFSET_LINK); 2102 compare_value(IPV4_TYPE_HEADER_OFFSET, 1, tokenval); 2103 emitop(OP_OFFSET_POP); 2104 opstack++; 2105 next(); 2106 continue; 2107 } 2108 2109 if (EQ("broadcast")) { 2110 /* 2111 * Be tricky: FDDI ether dst address begins at 2112 * byte one. Since the address is really six 2113 * bytes long, this works for FDDI & ethernet. 2114 * XXX - Token ring? 2115 */ 2116 emitop(OP_OFFSET_ZERO); 2117 if (interface->mac_type == DL_IB) 2118 pr_err("filter option unsupported on media"); 2119 compare_value(1, 4, 0xffffffff); 2120 emitop(OP_OFFSET_POP); 2121 opstack++; 2122 next(); 2123 break; 2124 } 2125 2126 if (EQ("multicast")) { 2127 /* XXX Token ring? */ 2128 emitop(OP_OFFSET_ZERO); 2129 if (interface->mac_type == DL_FDDI) { 2130 compare_value_mask(1, 1, 0x01, 0x01); 2131 } else if (interface->mac_type == DL_IB) { 2132 pr_err("filter option unsupported on media"); 2133 } else { 2134 compare_value_mask(0, 1, 0x01, 0x01); 2135 } 2136 emitop(OP_OFFSET_POP); 2137 opstack++; 2138 next(); 2139 break; 2140 } 2141 2142 if (EQ("decnet")) { 2143 /* XXX Token ring? */ 2144 if (interface->mac_type == DL_FDDI) { 2145 load_value(19, 2); /* ether type */ 2146 load_const(0x6000); 2147 emitop(OP_GE); 2148 emitop(OP_BRFL); 2149 m = chain(0); 2150 load_value(19, 2); /* ether type */ 2151 load_const(0x6009); 2152 emitop(OP_LE); 2153 resolve_chain(m); 2154 } else { 2155 emitop(OP_OFFSET_ETHERTYPE); 2156 load_value(0, 2); /* ether type */ 2157 load_const(0x6000); 2158 emitop(OP_GE); 2159 emitop(OP_BRFL); 2160 m = chain(0); 2161 load_value(0, 2); /* ether type */ 2162 load_const(0x6009); 2163 emitop(OP_LE); 2164 resolve_chain(m); 2165 emitop(OP_OFFSET_POP); 2166 } 2167 opstack++; 2168 next(); 2169 break; 2170 } 2171 2172 if (EQ("vlan-id")) { 2173 next(); 2174 if (tokentype != NUMBER) 2175 pr_err("vlan id expected"); 2176 emitop(OP_OFFSET_ZERO); 2177 ethertype_match(ETHERTYPE_VLAN); 2178 emitop(OP_BRFL); 2179 m = chain(0); 2180 compare_value_mask(VLAN_ID_OFFSET, 2, tokenval, 2181 VLAN_ID_MASK); 2182 resolve_chain(m); 2183 emitop(OP_OFFSET_POP); 2184 opstack++; 2185 next(); 2186 break; 2187 } 2188 2189 if (EQ("apple")) { 2190 /* 2191 * Appletalk also appears in 802.2 2192 * packets, so check for the ethertypes 2193 * at offset 12 and 20 in the MAC header. 2194 */ 2195 ethertype_match(ETHERTYPE_AT); 2196 emitop(OP_BRTR); 2197 m = chain(0); 2198 ethertype_match(ETHERTYPE_AARP); 2199 emitop(OP_BRTR); 2200 m = chain(m); 2201 compare_value(20, 2, ETHERTYPE_AT); /* 802.2 */ 2202 emitop(OP_BRTR); 2203 m = chain(m); 2204 compare_value(20, 2, ETHERTYPE_AARP); /* 802.2 */ 2205 resolve_chain(m); 2206 opstack++; 2207 next(); 2208 break; 2209 } 2210 2211 if (EQ("vlan")) { 2212 ethertype_match(ETHERTYPE_VLAN); 2213 compare_value_mask(VLAN_ID_OFFSET, 2, 0, VLAN_ID_MASK); 2214 emitop(OP_NOT); 2215 emitop(OP_AND); 2216 opstack++; 2217 next(); 2218 break; 2219 } 2220 2221 if (EQ("bootp") || EQ("dhcp")) { 2222 ethertype_match(ETHERTYPE_IP); 2223 emitop(OP_BRFL); 2224 m = chain(0); 2225 emitop(OP_OFFSET_LINK); 2226 compare_value(9, 1, IPPROTO_UDP); 2227 emitop(OP_OFFSET_POP); 2228 emitop(OP_BRFL); 2229 m = chain(m); 2230 emitop(OP_OFFSET_IP); 2231 compare_value(0, 4, 2232 (IPPORT_BOOTPS << 16) | IPPORT_BOOTPC); 2233 emitop(OP_BRTR); 2234 m2 = chain(0); 2235 compare_value(0, 4, 2236 (IPPORT_BOOTPC << 16) | IPPORT_BOOTPS); 2237 resolve_chain(m2); 2238 emitop(OP_OFFSET_POP); 2239 resolve_chain(m); 2240 opstack++; 2241 dir = ANY; 2242 next(); 2243 break; 2244 } 2245 2246 if (EQ("dhcp6")) { 2247 ethertype_match(ETHERTYPE_IPV6); 2248 emitop(OP_BRFL); 2249 m = chain(0); 2250 emitop(OP_OFFSET_LINK); 2251 compare_value(6, 1, IPPROTO_UDP); 2252 emitop(OP_OFFSET_POP); 2253 emitop(OP_BRFL); 2254 m = chain(m); 2255 emitop(OP_OFFSET_IP); 2256 compare_value(2, 2, IPPORT_DHCPV6S); 2257 emitop(OP_BRTR); 2258 m2 = chain(0); 2259 compare_value(2, 2, IPPORT_DHCPV6C); 2260 resolve_chain(m2); 2261 emitop(OP_OFFSET_POP); 2262 resolve_chain(m); 2263 opstack++; 2264 dir = ANY; 2265 next(); 2266 break; 2267 } 2268 2269 if (EQ("ethertype")) { 2270 next(); 2271 if (tokentype != NUMBER) 2272 pr_err("ether type expected"); 2273 ethertype_match(tokenval); 2274 opstack++; 2275 next(); 2276 break; 2277 } 2278 2279 if (EQ("pppoe")) { 2280 ethertype_match(ETHERTYPE_PPPOED); 2281 ethertype_match(ETHERTYPE_PPPOES); 2282 emitop(OP_OR); 2283 opstack++; 2284 next(); 2285 break; 2286 } 2287 2288 if (EQ("inet")) { 2289 next(); 2290 if (EQ("host")) 2291 next(); 2292 if (tokentype != ALPHA && tokentype != ADDR_IP) 2293 pr_err("host/IPv4 addr expected after inet"); 2294 ipaddr_match(dir, token, IPV4_ONLY); 2295 opstack++; 2296 next(); 2297 break; 2298 } 2299 2300 if (EQ("inet6")) { 2301 next(); 2302 if (EQ("host")) 2303 next(); 2304 if (tokentype != ALPHA && tokentype != ADDR_IP6) 2305 pr_err("host/IPv6 addr expected after inet6"); 2306 ipaddr_match(dir, token, IPV6_ONLY); 2307 opstack++; 2308 next(); 2309 break; 2310 } 2311 2312 if (EQ("length")) { 2313 emitop(OP_LOAD_LENGTH); 2314 opstack++; 2315 next(); 2316 break; 2317 } 2318 2319 if (EQ("less")) { 2320 next(); 2321 if (tokentype != NUMBER) 2322 pr_err("packet length expected"); 2323 emitop(OP_LOAD_LENGTH); 2324 load_const(tokenval); 2325 emitop(OP_LT); 2326 opstack++; 2327 next(); 2328 break; 2329 } 2330 2331 if (EQ("greater")) { 2332 next(); 2333 if (tokentype != NUMBER) 2334 pr_err("packet length expected"); 2335 emitop(OP_LOAD_LENGTH); 2336 load_const(tokenval); 2337 emitop(OP_GT); 2338 opstack++; 2339 next(); 2340 break; 2341 } 2342 2343 if (EQ("nofrag")) { 2344 emitop(OP_OFFSET_LINK); 2345 compare_value_mask(6, 2, 0, 0x1fff); 2346 emitop(OP_OFFSET_POP); 2347 emitop(OP_BRFL); 2348 m = chain(0); 2349 ethertype_match(ETHERTYPE_IP); 2350 resolve_chain(m); 2351 opstack++; 2352 next(); 2353 break; 2354 } 2355 2356 if (EQ("net") || EQ("dstnet") || EQ("srcnet")) { 2357 if (EQ("dstnet")) 2358 dir = TO; 2359 else if (EQ("srcnet")) 2360 dir = FROM; 2361 next(); 2362 netaddr_match(dir, token); 2363 dir = ANY; 2364 opstack++; 2365 next(); 2366 break; 2367 } 2368 2369 if (EQ("port") || EQ("srcport") || EQ("dstport")) { 2370 if (EQ("dstport")) 2371 dir = TO; 2372 else if (EQ("srcport")) 2373 dir = FROM; 2374 next(); 2375 port_match(dir, token); 2376 dir = ANY; 2377 opstack++; 2378 next(); 2379 break; 2380 } 2381 2382 if (EQ("rpc")) { 2383 uint_t vers, proc; 2384 char savetoken[32]; 2385 2386 vers = proc = -1; 2387 next(); 2388 (void) strlcpy(savetoken, token, sizeof (savetoken)); 2389 next(); 2390 if (*token == ',') { 2391 next(); 2392 if (tokentype != NUMBER) 2393 pr_err("version number expected"); 2394 vers = tokenval; 2395 next(); 2396 } 2397 if (*token == ',') { 2398 next(); 2399 if (tokentype != NUMBER) 2400 pr_err("proc number expected"); 2401 proc = tokenval; 2402 next(); 2403 } 2404 rpc_match_prog(dir, savetoken, vers, proc); 2405 dir = ANY; 2406 opstack++; 2407 break; 2408 } 2409 2410 if (EQ("slp")) { 2411 /* filter out TCP handshakes */ 2412 emitop(OP_OFFSET_LINK); 2413 compare_value(9, 1, IPPROTO_TCP); 2414 emitop(OP_LOAD_CONST); 2415 emitval(52); 2416 emitop(OP_LOAD_CONST); 2417 emitval(2); 2418 emitop(OP_LOAD_SHORT); 2419 emitop(OP_GE); 2420 emitop(OP_AND); /* proto == TCP && len < 52 */ 2421 emitop(OP_NOT); 2422 emitop(OP_BRFL); /* pkt too short to be a SLP call */ 2423 m = chain(0); 2424 2425 emitop(OP_OFFSET_POP); 2426 emitop(OP_OFFSET_SLP); 2427 resolve_chain(m); 2428 opstack++; 2429 next(); 2430 break; 2431 } 2432 2433 if (EQ("ldap")) { 2434 dir = ANY; 2435 port_match(dir, "ldap"); 2436 opstack++; 2437 next(); 2438 break; 2439 } 2440 2441 if (EQ("and") || EQ("or")) { 2442 break; 2443 } 2444 2445 if (EQ("gateway")) { 2446 next(); 2447 if (eaddr || tokentype != ALPHA) 2448 pr_err("hostname required: %s", token); 2449 etheraddr_match(dir, token); 2450 dir = ANY; 2451 emitop(OP_BRFL); 2452 m = chain(0); 2453 ipaddr_match(dir, token, IPV4_AND_IPV6); 2454 emitop(OP_NOT); 2455 resolve_chain(m); 2456 opstack++; 2457 next(); 2458 } 2459 2460 if (EQ("host") || EQ("between") || 2461 tokentype == ALPHA || /* assume its a hostname */ 2462 tokentype == ADDR_IP || 2463 tokentype == ADDR_IP6 || 2464 tokentype == ADDR_AT || 2465 tokentype == ADDR_ETHER) { 2466 if (EQ("host") || EQ("between")) 2467 next(); 2468 if (eaddr || tokentype == ADDR_ETHER) { 2469 etheraddr_match(dir, token); 2470 } else if (tokentype == ALPHA) { 2471 ipaddr_match(dir, token, IPV4_AND_IPV6); 2472 } else if (tokentype == ADDR_AT) { 2473 ataddr_match(dir, token); 2474 } else if (tokentype == ADDR_IP) { 2475 ipaddr_match(dir, token, IPV4_ONLY); 2476 } else { 2477 ipaddr_match(dir, token, IPV6_ONLY); 2478 } 2479 dir = ANY; 2480 eaddr = 0; 2481 opstack++; 2482 next(); 2483 break; 2484 } 2485 2486 if (tokentype == NUMBER) { 2487 load_const(tokenval); 2488 opstack++; 2489 next(); 2490 break; 2491 } 2492 2493 break; /* unknown token */ 2494 } 2495 } 2496 2497 struct optable { 2498 char *op_tok; 2499 enum optype op_type; 2500 }; 2501 2502 static struct optable 2503 mulops[] = { 2504 "*", OP_MUL, 2505 "/", OP_DIV, 2506 "%", OP_REM, 2507 "&", OP_AND, 2508 "", OP_STOP, 2509 }; 2510 2511 static struct optable 2512 addops[] = { 2513 "+", OP_ADD, 2514 "-", OP_SUB, 2515 "|", OP_OR, 2516 "^", OP_XOR, 2517 "", OP_STOP, 2518 }; 2519 2520 static struct optable 2521 compareops[] = { 2522 "==", OP_EQ, 2523 "=", OP_EQ, 2524 "!=", OP_NE, 2525 ">", OP_GT, 2526 ">=", OP_GE, 2527 "<", OP_LT, 2528 "<=", OP_LE, 2529 "", OP_STOP, 2530 }; 2531 2532 /* 2533 * Using the table, find the operator 2534 * that corresponds to the token. 2535 * Return 0 if not found. 2536 */ 2537 static int 2538 find_op(char *tok, struct optable *table) 2539 { 2540 struct optable *op; 2541 2542 for (op = table; *op->op_tok; op++) { 2543 if (strcmp(tok, op->op_tok) == 0) 2544 return (op->op_type); 2545 } 2546 2547 return (0); 2548 } 2549 2550 static void 2551 expr_mul() 2552 { 2553 int op; 2554 int s = opstack; 2555 2556 primary(); 2557 while (op = find_op(token, mulops)) { 2558 next(); 2559 primary(); 2560 checkstack(s + 2); 2561 emitop(op); 2562 opstack--; 2563 } 2564 } 2565 2566 static void 2567 expr_add() 2568 { 2569 int op, s = opstack; 2570 2571 expr_mul(); 2572 while (op = find_op(token, addops)) { 2573 next(); 2574 expr_mul(); 2575 checkstack(s + 2); 2576 emitop(op); 2577 opstack--; 2578 } 2579 } 2580 2581 static void 2582 expr_compare() 2583 { 2584 int op, s = opstack; 2585 2586 expr_add(); 2587 while (op = find_op(token, compareops)) { 2588 next(); 2589 expr_add(); 2590 checkstack(s + 2); 2591 emitop(op); 2592 opstack--; 2593 } 2594 } 2595 2596 /* 2597 * Alternation ("and") is difficult because 2598 * an implied "and" is acknowledge between 2599 * two adjacent primaries. Just keep calling 2600 * the lower-level expression routine until 2601 * no value is added to the opstack. 2602 */ 2603 static void 2604 alternation() 2605 { 2606 int m = 0; 2607 int s = opstack; 2608 2609 expr_compare(); 2610 checkstack(s + 1); 2611 for (;;) { 2612 if (EQ("and")) 2613 next(); 2614 emitop(OP_BRFL); 2615 m = chain(m); 2616 expr_compare(); 2617 if (opstack != s + 2) 2618 break; 2619 opstack--; 2620 } 2621 unemit(2); 2622 resolve_chain(m); 2623 } 2624 2625 static void 2626 expression() 2627 { 2628 int m = 0; 2629 int s = opstack; 2630 2631 alternation(); 2632 while (EQ("or") || EQ(",")) { 2633 emitop(OP_BRTR); 2634 m = chain(m); 2635 next(); 2636 alternation(); 2637 checkstack(s + 2); 2638 opstack--; 2639 } 2640 resolve_chain(m); 2641 } 2642 2643 /* 2644 * Take n args from the argv list 2645 * and concatenate them into a single string. 2646 */ 2647 char * 2648 concat_args(char **argv, int argc) 2649 { 2650 int i, len; 2651 char *str, *p; 2652 2653 /* First add the lengths of all the strings */ 2654 len = 0; 2655 for (i = 0; i < argc; i++) 2656 len += strlen(argv[i]) + 1; 2657 2658 /* allocate the big string */ 2659 str = (char *)malloc(len); 2660 if (str == NULL) 2661 pr_err("no mem"); 2662 2663 p = str; 2664 2665 /* 2666 * Concat the strings into the big 2667 * string using a space as separator 2668 */ 2669 for (i = 0; i < argc; i++) { 2670 strcpy(p, argv[i]); 2671 p += strlen(p); 2672 *p++ = ' '; 2673 } 2674 *--p = '\0'; 2675 2676 return (str); 2677 } 2678 2679 /* 2680 * Take the expression in the string "expr" 2681 * and compile it into the code array. 2682 * Print the generated code if the print 2683 * arg is set. 2684 */ 2685 void 2686 compile(char *expr, int print) 2687 { 2688 expr = strdup(expr); 2689 if (expr == NULL) 2690 pr_err("no mem"); 2691 curr_op = oplist; 2692 tkp = expr; 2693 dir = ANY; 2694 2695 next(); 2696 if (tokentype != EOL) 2697 expression(); 2698 emitop(OP_STOP); 2699 if (tokentype != EOL) 2700 pr_err("invalid expression"); 2701 optimize(oplist); 2702 if (print) 2703 codeprint(); 2704 } 2705 2706 /* 2707 * Lookup hostname in the arp cache. 2708 */ 2709 boolean_t 2710 arp_for_ether(char *hostname, struct ether_addr *ep) 2711 { 2712 struct arpreq ar; 2713 struct hostent *hp; 2714 struct sockaddr_in *sin; 2715 int error_num; 2716 int s; 2717 2718 memset(&ar, 0, sizeof (ar)); 2719 sin = (struct sockaddr_in *)&ar.arp_pa; 2720 sin->sin_family = AF_INET; 2721 hp = getipnodebyname(hostname, AF_INET, 0, &error_num); 2722 if (hp == NULL) { 2723 return (B_FALSE); 2724 } 2725 memcpy(&sin->sin_addr, hp->h_addr, sizeof (sin->sin_addr)); 2726 s = socket(AF_INET, SOCK_DGRAM, 0); 2727 if (s < 0) { 2728 return (B_FALSE); 2729 } 2730 if (ioctl(s, SIOCGARP, &ar) < 0) { 2731 close(s); 2732 return (B_FALSE); 2733 } 2734 close(s); 2735 memcpy(ep->ether_addr_octet, ar.arp_ha.sa_data, sizeof (*ep)); 2736 return (B_TRUE); 2737 } 2738