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