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