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