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 8
100 #define	IPNET_DSTZONE_OFFSET 16
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, 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 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 	0,		0,  0, 0,		0,	0
1401 };
1402 
1403 static void
1404 generate_check(match_type_t match_types[], int index, int type)
1405 {
1406 	match_type_t *mtp = &match_types[index];
1407 	/*
1408 	 * Note: this code assumes the above dependencies are
1409 	 * not cyclic.  This *should* always be true.
1410 	 */
1411 	if (mtp->m_depend != -1)
1412 		generate_check(match_types, mtp->m_depend, type);
1413 
1414 	emitop(mtp->m_optype);
1415 	load_value(mtp->m_offset, mtp->m_size);
1416 	load_const(mtp->m_value);
1417 	emitop(OP_OFFSET_POP);
1418 
1419 	emitop(OP_EQ);
1420 
1421 	if (mtp->m_depend != -1)
1422 		emitop(OP_AND);
1423 }
1424 
1425 /*
1426  * Generate code based on the keyword argument.
1427  * This word is looked up in the match_types table
1428  * and checks a field within the packet for a given
1429  * value e.g. ether or ip type field.  The match
1430  * can also have a dependency on another entry e.g.
1431  * "tcp" requires that the packet also be "ip".
1432  */
1433 static int
1434 comparison(char *s)
1435 {
1436 	unsigned int	i, n_checks = 0;
1437 	match_type_t	*match_types;
1438 
1439 	switch (interface->mac_type) {
1440 	case DL_ETHER:
1441 		match_types = ether_match_types;
1442 		break;
1443 	case DL_IPNET:
1444 		match_types = ipnet_match_types;
1445 		break;
1446 	case DL_IPV4:
1447 	case DL_IPV6:
1448 	case DL_6TO4:
1449 		match_types = iptun_match_types;
1450 		break;
1451 	default:
1452 		return (0);
1453 	}
1454 
1455 	for (i = 0; match_types[i].m_name != NULL; i++) {
1456 		if (strcmp(s, match_types[i].m_name) != 0)
1457 			continue;
1458 
1459 		n_checks++;
1460 		generate_check(match_types, i, interface->mac_type);
1461 		if (n_checks > 1)
1462 			emitop(OP_OR);
1463 	}
1464 
1465 	return (n_checks > 0);
1466 }
1467 
1468 enum direction { ANY, TO, FROM };
1469 enum direction dir;
1470 
1471 /*
1472  * Generate code to match an IP address.  The address
1473  * may be supplied either as a hostname or in dotted format.
1474  * For source packets both the IP source address and ARP
1475  * src are checked.
1476  * Note: we don't check packet type here - whether IP or ARP.
1477  * It's possible that we'll do an improper match.
1478  */
1479 static void
1480 ipaddr_match(enum direction which, char *hostname, int inet_type)
1481 {
1482 	bool_t found_host;
1483 	int m = 0, n = 0;
1484 	uint_t *addr4ptr;
1485 	uint_t addr4;
1486 	struct in6_addr *addr6ptr;
1487 	int h_addr_index;
1488 	struct hostent *hp = NULL;
1489 	int error_num = 0;
1490 	boolean_t freehp = B_FALSE;
1491 	boolean_t first = B_TRUE;
1492 
1493 	/*
1494 	 * The addr4offset and addr6offset variables simplify the code which
1495 	 * generates the address comparison filter.  With these two variables,
1496 	 * duplicate code need not exist for the TO and FROM case.
1497 	 * A value of -1 describes the ANY case (TO and FROM).
1498 	 */
1499 	int addr4offset;
1500 	int addr6offset;
1501 
1502 	found_host = 0;
1503 
1504 	if (tokentype == ADDR_IP) {
1505 		hp = lgetipnodebyname(hostname, AF_INET, 0, &error_num);
1506 		if (hp == NULL) {
1507 			hp = getipnodebyname(hostname, AF_INET, 0, &error_num);
1508 			freehp = 1;
1509 		}
1510 		if (hp == NULL) {
1511 			if (error_num == TRY_AGAIN) {
1512 				pr_err("couldn't resolve %s (try again later)",
1513 				    hostname);
1514 			} else {
1515 				pr_err("couldn't resolve %s", hostname);
1516 			}
1517 		}
1518 		inet_type = IPV4_ONLY;
1519 	} else if (tokentype == ADDR_IP6) {
1520 		hp = lgetipnodebyname(hostname, AF_INET6, 0, &error_num);
1521 		if (hp == NULL) {
1522 			hp = getipnodebyname(hostname, AF_INET6, 0, &error_num);
1523 			freehp = 1;
1524 		}
1525 		if (hp == NULL) {
1526 			if (error_num == TRY_AGAIN) {
1527 				pr_err("couldn't resolve %s (try again later)",
1528 				    hostname);
1529 			} else {
1530 				pr_err("couldn't resolve %s", hostname);
1531 			}
1532 		}
1533 		inet_type = IPV6_ONLY;
1534 	} else {
1535 		/* Some hostname i.e. tokentype is ALPHA */
1536 		switch (inet_type) {
1537 		case IPV4_ONLY:
1538 			/* Only IPv4 address is needed */
1539 			hp = lgetipnodebyname(hostname, AF_INET, 0, &error_num);
1540 			if (hp == NULL) {
1541 				hp = getipnodebyname(hostname, AF_INET,	0,
1542 				    &error_num);
1543 				freehp = 1;
1544 			}
1545 			if (hp != NULL) {
1546 				found_host = 1;
1547 			}
1548 			break;
1549 		case IPV6_ONLY:
1550 			/* Only IPv6 address is needed */
1551 			hp = lgetipnodebyname(hostname, AF_INET6, 0,
1552 			    &error_num);
1553 			if (hp == NULL) {
1554 				hp = getipnodebyname(hostname, AF_INET6, 0,
1555 				    &error_num);
1556 				freehp = 1;
1557 			}
1558 			if (hp != NULL) {
1559 				found_host = 1;
1560 			}
1561 			break;
1562 		case IPV4_AND_IPV6:
1563 			/* Both IPv4 and IPv6 are needed */
1564 			hp = lgetipnodebyname(hostname, AF_INET6,
1565 			    AI_ALL | AI_V4MAPPED, &error_num);
1566 			if (hp == NULL) {
1567 				hp = getipnodebyname(hostname, AF_INET6,
1568 				    AI_ALL | AI_V4MAPPED, &error_num);
1569 				freehp = 1;
1570 			}
1571 			if (hp != NULL) {
1572 				found_host = 1;
1573 			}
1574 			break;
1575 		default:
1576 			found_host = 0;
1577 		}
1578 
1579 		if (!found_host) {
1580 			if (error_num == TRY_AGAIN) {
1581 				pr_err("could not resolve %s (try again later)",
1582 				    hostname);
1583 			} else {
1584 				pr_err("could not resolve %s", hostname);
1585 			}
1586 		}
1587 	}
1588 
1589 	switch (which) {
1590 	case TO:
1591 		addr4offset = IPV4_DSTADDR_OFFSET;
1592 		addr6offset = IPV6_DSTADDR_OFFSET;
1593 		break;
1594 	case FROM:
1595 		addr4offset = IPV4_SRCADDR_OFFSET;
1596 		addr6offset = IPV6_SRCADDR_OFFSET;
1597 		break;
1598 	case ANY:
1599 		addr4offset = -1;
1600 		addr6offset = -1;
1601 		break;
1602 	}
1603 
1604 	/*
1605 	 * The code below generates the filter.
1606 	 */
1607 	if (hp != NULL && hp->h_addrtype == AF_INET) {
1608 		ethertype_match(interface->network_type_ip);
1609 		emitop(OP_BRFL);
1610 		n = chain(n);
1611 		emitop(OP_OFFSET_LINK);
1612 		h_addr_index = 0;
1613 		addr4ptr = (uint_t *)hp->h_addr_list[h_addr_index];
1614 		while (addr4ptr != NULL) {
1615 			if (addr4offset == -1) {
1616 				compare_addr_v4(IPV4_SRCADDR_OFFSET, 4,
1617 				    *addr4ptr);
1618 				emitop(OP_BRTR);
1619 				m = chain(m);
1620 				compare_addr_v4(IPV4_DSTADDR_OFFSET, 4,
1621 				    *addr4ptr);
1622 			} else {
1623 				compare_addr_v4(addr4offset, 4, *addr4ptr);
1624 			}
1625 			addr4ptr = (uint_t *)hp->h_addr_list[++h_addr_index];
1626 			if (addr4ptr != NULL) {
1627 				emitop(OP_BRTR);
1628 				m = chain(m);
1629 			}
1630 		}
1631 		if (m != 0) {
1632 			resolve_chain(m);
1633 		}
1634 		emitop(OP_OFFSET_POP);
1635 		resolve_chain(n);
1636 	} else {
1637 		/* first pass: IPv4 addresses */
1638 		h_addr_index = 0;
1639 		addr6ptr = (struct in6_addr *)hp->h_addr_list[h_addr_index];
1640 		first = B_TRUE;
1641 		while (addr6ptr != NULL) {
1642 			if (IN6_IS_ADDR_V4MAPPED(addr6ptr)) {
1643 				if (first) {
1644 					ethertype_match(
1645 					    interface->network_type_ip);
1646 					emitop(OP_BRFL);
1647 					n = chain(n);
1648 					emitop(OP_OFFSET_LINK);
1649 					first = B_FALSE;
1650 				} else {
1651 					emitop(OP_BRTR);
1652 					m = chain(m);
1653 				}
1654 				IN6_V4MAPPED_TO_INADDR(addr6ptr,
1655 				    (struct in_addr *)&addr4);
1656 				if (addr4offset == -1) {
1657 					compare_addr_v4(IPV4_SRCADDR_OFFSET, 4,
1658 					    addr4);
1659 					emitop(OP_BRTR);
1660 					m = chain(m);
1661 					compare_addr_v4(IPV4_DSTADDR_OFFSET, 4,
1662 					    addr4);
1663 				} else {
1664 					compare_addr_v4(addr4offset, 4, addr4);
1665 				}
1666 			}
1667 			addr6ptr = (struct in6_addr *)
1668 			    hp->h_addr_list[++h_addr_index];
1669 		}
1670 		/* second pass: IPv6 addresses */
1671 		h_addr_index = 0;
1672 		addr6ptr = (struct in6_addr *)hp->h_addr_list[h_addr_index];
1673 		first = B_TRUE;
1674 		while (addr6ptr != NULL) {
1675 			if (!IN6_IS_ADDR_V4MAPPED(addr6ptr)) {
1676 				if (first) {
1677 					/*
1678 					 * bypass check for IPv6 addresses
1679 					 * when we have an IPv4 packet
1680 					 */
1681 					if (n != 0) {
1682 						emitop(OP_BRTR);
1683 						m = chain(m);
1684 						emitop(OP_BRFL);
1685 						m = chain(m);
1686 						resolve_chain(n);
1687 						n = 0;
1688 					}
1689 					ethertype_match(
1690 					    interface->network_type_ipv6);
1691 					emitop(OP_BRFL);
1692 					n = chain(n);
1693 					emitop(OP_OFFSET_LINK);
1694 					first = B_FALSE;
1695 				} else {
1696 					emitop(OP_BRTR);
1697 					m = chain(m);
1698 				}
1699 				if (addr6offset == -1) {
1700 					compare_addr_v6(IPV6_SRCADDR_OFFSET,
1701 					    16, *addr6ptr);
1702 					emitop(OP_BRTR);
1703 					m = chain(m);
1704 					compare_addr_v6(IPV6_DSTADDR_OFFSET,
1705 					    16, *addr6ptr);
1706 				} else {
1707 					compare_addr_v6(addr6offset, 16,
1708 					    *addr6ptr);
1709 				}
1710 			}
1711 			addr6ptr = (struct in6_addr *)
1712 			    hp->h_addr_list[++h_addr_index];
1713 		}
1714 		if (m != 0) {
1715 			resolve_chain(m);
1716 		}
1717 		emitop(OP_OFFSET_POP);
1718 		resolve_chain(n);
1719 	}
1720 
1721 	/* only free struct hostent returned by getipnodebyname() */
1722 	if (freehp) {
1723 		freehostent(hp);
1724 	}
1725 }
1726 
1727 /*
1728  * Match on zoneid. The arg zone passed in is in network byte order.
1729  */
1730 static void
1731 zone_match(enum direction which, uint64_t zone)
1732 {
1733 
1734 	switch (which) {
1735 	case TO:
1736 		compare_value_zone(IPNET_DSTZONE_OFFSET, zone);
1737 		break;
1738 	case FROM:
1739 		compare_value_zone(IPNET_SRCZONE_OFFSET, zone);
1740 		break;
1741 	case ANY:
1742 		compare_value_zone(IPNET_SRCZONE_OFFSET, zone);
1743 		compare_value_zone(IPNET_DSTZONE_OFFSET, zone);
1744 		emitop(OP_OR);
1745 	}
1746 }
1747 
1748 /*
1749  * Generate code to match an AppleTalk address.  The address
1750  * must be given as two numbers with a dot between
1751  *
1752  */
1753 static void
1754 ataddr_match(enum direction which, char *hostname)
1755 {
1756 	uint_t net;
1757 	uint_t node;
1758 	uint_t m, n;
1759 
1760 	sscanf(hostname, "%u.%u", &net, &node);
1761 
1762 	emitop(OP_OFFSET_LINK);
1763 	switch (which) {
1764 	case TO:
1765 		compare_value(AT_DST_NET_OFFSET, 2, net);
1766 		emitop(OP_BRFL);
1767 		m = chain(0);
1768 		compare_value(AT_DST_NODE_OFFSET, 1, node);
1769 		resolve_chain(m);
1770 		break;
1771 	case FROM:
1772 		compare_value(AT_SRC_NET_OFFSET, 2, net);
1773 		emitop(OP_BRFL);
1774 		m = chain(0);
1775 		compare_value(AT_SRC_NODE_OFFSET, 1, node);
1776 		resolve_chain(m);
1777 		break;
1778 	case ANY:
1779 		compare_value(AT_DST_NET_OFFSET, 2, net);
1780 		emitop(OP_BRFL);
1781 		m = chain(0);
1782 		compare_value(AT_DST_NODE_OFFSET, 1, node);
1783 		resolve_chain(m);
1784 		emitop(OP_BRTR);
1785 		n = chain(0);
1786 		compare_value(AT_SRC_NET_OFFSET, 2, net);
1787 		emitop(OP_BRFL);
1788 		m = chain(0);
1789 		compare_value(AT_SRC_NODE_OFFSET, 1, node);
1790 		resolve_chain(m);
1791 		resolve_chain(n);
1792 		break;
1793 	}
1794 	emitop(OP_OFFSET_POP);
1795 }
1796 
1797 /*
1798  * Compare ethernet addresses. The address may
1799  * be provided either as a hostname or as a
1800  * 6 octet colon-separated address.
1801  */
1802 static void
1803 etheraddr_match(enum direction which, char *hostname)
1804 {
1805 	uint_t addr;
1806 	ushort_t *addrp;
1807 	int to_offset, from_offset;
1808 	struct ether_addr e, *ep = NULL;
1809 	int m;
1810 
1811 	/*
1812 	 * First, check the interface type for whether src/dest address
1813 	 * is determinable; if not, retreat early.
1814 	 */
1815 	switch (interface->mac_type) {
1816 	case DL_ETHER:
1817 		from_offset = ETHERADDRL;
1818 		to_offset = 0;
1819 		break;
1820 
1821 	case DL_IB:
1822 		/*
1823 		 * If an ethernet address is attempted to be used
1824 		 * on an IPoIB interface, flag error. Link address
1825 		 * based filtering is unsupported on IPoIB, so there
1826 		 * is no ipibaddr_match() or parsing support for IPoIB
1827 		 * 20 byte link addresses.
1828 		 */
1829 		pr_err("filter option unsupported on media");
1830 		break;
1831 
1832 	case DL_FDDI:
1833 		from_offset = 7;
1834 		to_offset = 1;
1835 		break;
1836 
1837 	default:
1838 		/*
1839 		 * Where do we find "ether" address for FDDI & TR?
1840 		 * XXX can improve?  ~sparker
1841 		 */
1842 		load_const(1);
1843 		return;
1844 	}
1845 
1846 	if (isxdigit(*hostname))
1847 		ep = ether_aton(hostname);
1848 	if (ep == NULL) {
1849 		if (ether_hostton(hostname, &e))
1850 			if (!arp_for_ether(hostname, &e))
1851 				pr_err("cannot obtain ether addr for %s",
1852 				    hostname);
1853 		ep = &e;
1854 	}
1855 	memcpy(&addr, (ushort_t *)ep, 4);
1856 	addrp = (ushort_t *)ep + 2;
1857 
1858 	emitop(OP_OFFSET_ZERO);
1859 	switch (which) {
1860 	case TO:
1861 		compare_value(to_offset, 4, ntohl(addr));
1862 		emitop(OP_BRFL);
1863 		m = chain(0);
1864 		compare_value(to_offset + 4, 2, ntohs(*addrp));
1865 		resolve_chain(m);
1866 		break;
1867 	case FROM:
1868 		compare_value(from_offset, 4, ntohl(addr));
1869 		emitop(OP_BRFL);
1870 		m = chain(0);
1871 		compare_value(from_offset + 4, 2, ntohs(*addrp));
1872 		resolve_chain(m);
1873 		break;
1874 	case ANY:
1875 		compare_value(to_offset, 4, ntohl(addr));
1876 		compare_value(to_offset + 4, 2, ntohs(*addrp));
1877 		emitop(OP_AND);
1878 		emitop(OP_BRTR);
1879 		m = chain(0);
1880 
1881 		compare_value(from_offset, 4, ntohl(addr));
1882 		compare_value(from_offset + 4, 2, ntohs(*addrp));
1883 		emitop(OP_AND);
1884 		resolve_chain(m);
1885 		break;
1886 	}
1887 	emitop(OP_OFFSET_POP);
1888 }
1889 
1890 static void
1891 ethertype_match(int val)
1892 {
1893 	int ether_offset = interface->network_type_offset;
1894 
1895 	/*
1896 	 * If the user is interested in ethertype VLAN,
1897 	 * then we need to set the offset to the beginning of the packet.
1898 	 * But if the user is interested in another ethertype,
1899 	 * such as IPv4, then we need to take into consideration
1900 	 * the fact that the packet might be VLAN tagged.
1901 	 */
1902 	if (interface->mac_type == DL_ETHER ||
1903 	    interface->mac_type == DL_CSMACD) {
1904 		if (val != ETHERTYPE_VLAN) {
1905 			/*
1906 			 * OP_OFFSET_ETHERTYPE puts us at the ethertype
1907 			 * field whether or not there is a VLAN tag,
1908 			 * so ether_offset goes to zero if we get here.
1909 			 */
1910 			emitop(OP_OFFSET_ETHERTYPE);
1911 			ether_offset = 0;
1912 		} else {
1913 			emitop(OP_OFFSET_ZERO);
1914 		}
1915 	}
1916 	compare_value(ether_offset, interface->network_type_len, val);
1917 	if (interface->mac_type == DL_ETHER ||
1918 	    interface->mac_type == DL_CSMACD) {
1919 		emitop(OP_OFFSET_POP);
1920 	}
1921 }
1922 
1923 /*
1924  * Match a network address.  The host part
1925  * is masked out.  The network address may
1926  * be supplied either as a netname or in
1927  * IP dotted format.  The mask to be used
1928  * for the comparison is assumed from the
1929  * address format (see comment below).
1930  */
1931 static void
1932 netaddr_match(enum direction which, char *netname)
1933 {
1934 	uint_t addr;
1935 	uint_t mask = 0xff000000;
1936 	uint_t m;
1937 	struct netent *np;
1938 
1939 	if (isdigit(*netname)) {
1940 		addr = inet_network(netname);
1941 	} else {
1942 		np = getnetbyname(netname);
1943 		if (np == NULL)
1944 			pr_err("net %s not known", netname);
1945 		addr = np->n_net;
1946 	}
1947 
1948 	/*
1949 	 * Left justify the address and figure
1950 	 * out a mask based on the supplied address.
1951 	 * Set the mask according to the number of zero
1952 	 * low-order bytes.
1953 	 * Note: this works only for whole octet masks.
1954 	 */
1955 	if (addr) {
1956 		while ((addr & ~mask) != 0) {
1957 			mask |= (mask >> 8);
1958 		}
1959 	}
1960 
1961 	emitop(OP_OFFSET_LINK);
1962 	switch (which) {
1963 	case TO:
1964 		compare_value_mask(16, 4, addr, mask);
1965 		break;
1966 	case FROM:
1967 		compare_value_mask(12, 4, addr, mask);
1968 		break;
1969 	case ANY:
1970 		compare_value_mask(12, 4, addr, mask);
1971 		emitop(OP_BRTR);
1972 		m = chain(0);
1973 		compare_value_mask(16, 4, addr, mask);
1974 		resolve_chain(m);
1975 		break;
1976 	}
1977 	emitop(OP_OFFSET_POP);
1978 }
1979 
1980 /*
1981  * Match either a UDP or TCP port number.
1982  * The port number may be provided either as
1983  * port name as listed in /etc/services ("nntp") or as
1984  * the port number itself (2049).
1985  */
1986 static void
1987 port_match(enum direction which, char *portname)
1988 {
1989 	struct servent *sp;
1990 	uint_t m, port;
1991 
1992 	if (isdigit(*portname)) {
1993 		port = atoi(portname);
1994 	} else {
1995 		sp = getservbyname(portname, NULL);
1996 		if (sp == NULL)
1997 			pr_err("invalid port number or name: %s", portname);
1998 		port = ntohs(sp->s_port);
1999 	}
2000 
2001 	emitop(OP_OFFSET_IP);
2002 
2003 	switch (which) {
2004 	case TO:
2005 		compare_value(2, 2, port);
2006 		break;
2007 	case FROM:
2008 		compare_value(0, 2, port);
2009 		break;
2010 	case ANY:
2011 		compare_value(2, 2, port);
2012 		emitop(OP_BRTR);
2013 		m = chain(0);
2014 		compare_value(0, 2, port);
2015 		resolve_chain(m);
2016 		break;
2017 	}
2018 	emitop(OP_OFFSET_POP);
2019 }
2020 
2021 /*
2022  * Generate code to match packets with a specific
2023  * RPC program number.  If the progname is a name
2024  * it is converted to a number via /etc/rpc.
2025  * The program version and/or procedure may be provided
2026  * as extra qualifiers.
2027  */
2028 static void
2029 rpc_match_prog(enum direction which, char *progname, int vers, int proc)
2030 {
2031 	struct rpcent *rpc;
2032 	uint_t prog;
2033 	uint_t m, n;
2034 
2035 	if (isdigit(*progname)) {
2036 		prog = atoi(progname);
2037 	} else {
2038 		rpc = (struct rpcent *)getrpcbyname(progname);
2039 		if (rpc == NULL)
2040 			pr_err("invalid program name: %s", progname);
2041 		prog = rpc->r_number;
2042 	}
2043 
2044 	emitop(OP_OFFSET_RPC);
2045 	emitop(OP_BRFL);
2046 	n = chain(0);
2047 
2048 	compare_value(12, 4, prog);
2049 	emitop(OP_BRFL);
2050 	m = chain(0);
2051 	if (vers >= 0) {
2052 		compare_value(16, 4, vers);
2053 		emitop(OP_BRFL);
2054 		m = chain(m);
2055 	}
2056 	if (proc >= 0) {
2057 		compare_value(20, 4, proc);
2058 		emitop(OP_BRFL);
2059 		m = chain(m);
2060 	}
2061 
2062 	switch (which) {
2063 	case TO:
2064 		compare_value(4, 4, CALL);
2065 		emitop(OP_BRFL);
2066 		m = chain(m);
2067 		break;
2068 	case FROM:
2069 		compare_value(4, 4, REPLY);
2070 		emitop(OP_BRFL);
2071 		m = chain(m);
2072 		break;
2073 	}
2074 	resolve_chain(m);
2075 	resolve_chain(n);
2076 	emitop(OP_OFFSET_POP);
2077 }
2078 
2079 /*
2080  * Generate code to parse a field specification
2081  * and load the value of the field from the packet
2082  * onto the operand stack.
2083  * The field offset may be specified relative to the
2084  * beginning of the ether header, IP header, UDP header,
2085  * or TCP header.  An optional size specification may
2086  * be provided following a colon.  If no size is given
2087  * one byte is assumed e.g.
2088  *
2089  *	ether[0]	The first byte of the ether header
2090  *	ip[2:2]		The second 16 bit field of the IP header
2091  */
2092 static void
2093 load_field()
2094 {
2095 	int size = 1;
2096 	int s;
2097 
2098 
2099 	if (EQ("ether"))
2100 		emitop(OP_OFFSET_ZERO);
2101 	else if (EQ("ip") || EQ("ip6") || EQ("pppoed") || EQ("pppoes"))
2102 		emitop(OP_OFFSET_LINK);
2103 	else if (EQ("udp") || EQ("tcp") || EQ("icmp") || EQ("ip-in-ip") ||
2104 	    EQ("ah") || EQ("esp"))
2105 		emitop(OP_OFFSET_IP);
2106 	else
2107 		pr_err("invalid field type");
2108 	next();
2109 	s = opstack;
2110 	expression();
2111 	if (opstack != s + 1)
2112 		pr_err("invalid field offset");
2113 	opstack--;
2114 	if (*token == ':') {
2115 		next();
2116 		if (tokentype != NUMBER)
2117 			pr_err("field size expected");
2118 		size = tokenval;
2119 		if (size != 1 && size != 2 && size != 4)
2120 			pr_err("field size invalid");
2121 		next();
2122 	}
2123 	if (*token != ']')
2124 		pr_err("right bracket expected");
2125 
2126 	load_value(-1, size);
2127 	emitop(OP_OFFSET_POP);
2128 }
2129 
2130 /*
2131  * Check that the operand stack
2132  * contains n arguments
2133  */
2134 static void
2135 checkstack(int numargs)
2136 {
2137 	if (opstack != numargs)
2138 		pr_err("invalid expression at \"%s\".", token);
2139 }
2140 
2141 static void
2142 primary()
2143 {
2144 	int m, m2, s;
2145 
2146 	for (;;) {
2147 		if (tokentype == FIELD) {
2148 			load_field();
2149 			opstack++;
2150 			next();
2151 			break;
2152 		}
2153 
2154 		if (comparison(token)) {
2155 			opstack++;
2156 			next();
2157 			break;
2158 		}
2159 
2160 		if (EQ("not") || EQ("!")) {
2161 			next();
2162 			s = opstack;
2163 			primary();
2164 			checkstack(s + 1);
2165 			emitop(OP_NOT);
2166 			break;
2167 		}
2168 
2169 		if (EQ("(")) {
2170 			next();
2171 			s = opstack;
2172 			expression();
2173 			checkstack(s + 1);
2174 			if (!EQ(")"))
2175 				pr_err("right paren expected");
2176 			next();
2177 		}
2178 
2179 		if (EQ("to") || EQ("dst")) {
2180 			dir = TO;
2181 			next();
2182 			continue;
2183 		}
2184 
2185 		if (EQ("from") || EQ("src")) {
2186 			dir = FROM;
2187 			next();
2188 			continue;
2189 		}
2190 
2191 		if (EQ("ether")) {
2192 			eaddr = 1;
2193 			next();
2194 			continue;
2195 		}
2196 
2197 		if (EQ("proto")) {
2198 			next();
2199 			if (tokentype != NUMBER)
2200 				pr_err("IP proto type expected");
2201 			emitop(OP_OFFSET_LINK);
2202 			compare_value(IPV4_TYPE_HEADER_OFFSET, 1, tokenval);
2203 			emitop(OP_OFFSET_POP);
2204 			opstack++;
2205 			next();
2206 			continue;
2207 		}
2208 
2209 		if (EQ("broadcast")) {
2210 			/*
2211 			 * Be tricky: FDDI ether dst address begins at
2212 			 * byte one.  Since the address is really six
2213 			 * bytes long, this works for FDDI & ethernet.
2214 			 * XXX - Token ring?
2215 			 */
2216 			emitop(OP_OFFSET_ZERO);
2217 			if (interface->mac_type == DL_IB)
2218 				pr_err("filter option unsupported on media");
2219 			compare_value(1, 4, 0xffffffff);
2220 			emitop(OP_OFFSET_POP);
2221 			opstack++;
2222 			next();
2223 			break;
2224 		}
2225 
2226 		if (EQ("multicast")) {
2227 			/* XXX Token ring? */
2228 			emitop(OP_OFFSET_ZERO);
2229 			if (interface->mac_type == DL_FDDI) {
2230 				compare_value_mask(1, 1, 0x01, 0x01);
2231 			} else if (interface->mac_type == DL_IB) {
2232 				pr_err("filter option unsupported on media");
2233 			} else {
2234 				compare_value_mask(0, 1, 0x01, 0x01);
2235 			}
2236 			emitop(OP_OFFSET_POP);
2237 			opstack++;
2238 			next();
2239 			break;
2240 		}
2241 
2242 		if (EQ("decnet")) {
2243 			/* XXX Token ring? */
2244 			if (interface->mac_type == DL_FDDI) {
2245 				load_value(19, 2);	/* ether type */
2246 				load_const(0x6000);
2247 				emitop(OP_GE);
2248 				emitop(OP_BRFL);
2249 				m = chain(0);
2250 				load_value(19, 2);	/* ether type */
2251 				load_const(0x6009);
2252 				emitop(OP_LE);
2253 				resolve_chain(m);
2254 			} else {
2255 				emitop(OP_OFFSET_ETHERTYPE);
2256 				load_value(0, 2);	/* ether type */
2257 				load_const(0x6000);
2258 				emitop(OP_GE);
2259 				emitop(OP_BRFL);
2260 				m = chain(0);
2261 				load_value(0, 2);	/* ether type */
2262 				load_const(0x6009);
2263 				emitop(OP_LE);
2264 				resolve_chain(m);
2265 				emitop(OP_OFFSET_POP);
2266 			}
2267 			opstack++;
2268 			next();
2269 			break;
2270 		}
2271 
2272 		if (EQ("vlan-id")) {
2273 			next();
2274 			if (tokentype != NUMBER)
2275 				pr_err("vlan id expected");
2276 			emitop(OP_OFFSET_ZERO);
2277 			ethertype_match(ETHERTYPE_VLAN);
2278 			emitop(OP_BRFL);
2279 			m = chain(0);
2280 			compare_value_mask(VLAN_ID_OFFSET, 2, tokenval,
2281 			    VLAN_ID_MASK);
2282 			resolve_chain(m);
2283 			emitop(OP_OFFSET_POP);
2284 			opstack++;
2285 			next();
2286 			break;
2287 		}
2288 
2289 		if (EQ("apple")) {
2290 			/*
2291 			 * Appletalk also appears in 802.2
2292 			 * packets, so check for the ethertypes
2293 			 * at offset 12 and 20 in the MAC header.
2294 			 */
2295 			ethertype_match(ETHERTYPE_AT);
2296 			emitop(OP_BRTR);
2297 			m = chain(0);
2298 			ethertype_match(ETHERTYPE_AARP);
2299 			emitop(OP_BRTR);
2300 			m = chain(m);
2301 			compare_value(20, 2, ETHERTYPE_AT); /* 802.2 */
2302 			emitop(OP_BRTR);
2303 			m = chain(m);
2304 			compare_value(20, 2, ETHERTYPE_AARP); /* 802.2 */
2305 			resolve_chain(m);
2306 			opstack++;
2307 			next();
2308 			break;
2309 		}
2310 
2311 		if (EQ("vlan")) {
2312 			ethertype_match(ETHERTYPE_VLAN);
2313 			compare_value_mask(VLAN_ID_OFFSET, 2, 0, VLAN_ID_MASK);
2314 			emitop(OP_NOT);
2315 			emitop(OP_AND);
2316 			opstack++;
2317 			next();
2318 			break;
2319 		}
2320 
2321 		if (EQ("bootp") || EQ("dhcp")) {
2322 			ethertype_match(interface->network_type_ip);
2323 			emitop(OP_BRFL);
2324 			m = chain(0);
2325 			emitop(OP_OFFSET_LINK);
2326 			compare_value(9, 1, IPPROTO_UDP);
2327 			emitop(OP_OFFSET_POP);
2328 			emitop(OP_BRFL);
2329 			m = chain(m);
2330 			emitop(OP_OFFSET_IP);
2331 			compare_value(0, 4,
2332 			    (IPPORT_BOOTPS << 16) | IPPORT_BOOTPC);
2333 			emitop(OP_BRTR);
2334 			m2 = chain(0);
2335 			compare_value(0, 4,
2336 			    (IPPORT_BOOTPC << 16) | IPPORT_BOOTPS);
2337 			resolve_chain(m2);
2338 			emitop(OP_OFFSET_POP);
2339 			resolve_chain(m);
2340 			opstack++;
2341 			dir = ANY;
2342 			next();
2343 			break;
2344 		}
2345 
2346 		if (EQ("dhcp6")) {
2347 			ethertype_match(interface->network_type_ipv6);
2348 			emitop(OP_BRFL);
2349 			m = chain(0);
2350 			emitop(OP_OFFSET_LINK);
2351 			compare_value(6, 1, IPPROTO_UDP);
2352 			emitop(OP_OFFSET_POP);
2353 			emitop(OP_BRFL);
2354 			m = chain(m);
2355 			emitop(OP_OFFSET_IP);
2356 			compare_value(2, 2, IPPORT_DHCPV6S);
2357 			emitop(OP_BRTR);
2358 			m2 = chain(0);
2359 			compare_value(2, 2, IPPORT_DHCPV6C);
2360 			resolve_chain(m2);
2361 			emitop(OP_OFFSET_POP);
2362 			resolve_chain(m);
2363 			opstack++;
2364 			dir = ANY;
2365 			next();
2366 			break;
2367 		}
2368 
2369 		if (EQ("ethertype")) {
2370 			next();
2371 			if (tokentype != NUMBER)
2372 				pr_err("ether type expected");
2373 			ethertype_match(tokenval);
2374 			opstack++;
2375 			next();
2376 			break;
2377 		}
2378 
2379 		if (EQ("pppoe")) {
2380 			ethertype_match(ETHERTYPE_PPPOED);
2381 			ethertype_match(ETHERTYPE_PPPOES);
2382 			emitop(OP_OR);
2383 			opstack++;
2384 			next();
2385 			break;
2386 		}
2387 
2388 		if (EQ("inet")) {
2389 			next();
2390 			if (EQ("host"))
2391 				next();
2392 			if (tokentype != ALPHA && tokentype != ADDR_IP)
2393 				pr_err("host/IPv4 addr expected after inet");
2394 			ipaddr_match(dir, token, IPV4_ONLY);
2395 			opstack++;
2396 			next();
2397 			break;
2398 		}
2399 
2400 		if (EQ("inet6")) {
2401 			next();
2402 			if (EQ("host"))
2403 				next();
2404 			if (tokentype != ALPHA && tokentype != ADDR_IP6)
2405 				pr_err("host/IPv6 addr expected after inet6");
2406 			ipaddr_match(dir, token, IPV6_ONLY);
2407 			opstack++;
2408 			next();
2409 			break;
2410 		}
2411 
2412 		if (EQ("length")) {
2413 			emitop(OP_LOAD_LENGTH);
2414 			opstack++;
2415 			next();
2416 			break;
2417 		}
2418 
2419 		if (EQ("less")) {
2420 			next();
2421 			if (tokentype != NUMBER)
2422 				pr_err("packet length expected");
2423 			emitop(OP_LOAD_LENGTH);
2424 			load_const(tokenval);
2425 			emitop(OP_LT);
2426 			opstack++;
2427 			next();
2428 			break;
2429 		}
2430 
2431 		if (EQ("greater")) {
2432 			next();
2433 			if (tokentype != NUMBER)
2434 				pr_err("packet length expected");
2435 			emitop(OP_LOAD_LENGTH);
2436 			load_const(tokenval);
2437 			emitop(OP_GT);
2438 			opstack++;
2439 			next();
2440 			break;
2441 		}
2442 
2443 		if (EQ("nofrag")) {
2444 			emitop(OP_OFFSET_LINK);
2445 			compare_value_mask(6, 2, 0, 0x1fff);
2446 			emitop(OP_OFFSET_POP);
2447 			emitop(OP_BRFL);
2448 			m = chain(0);
2449 			ethertype_match(interface->network_type_ip);
2450 			resolve_chain(m);
2451 			opstack++;
2452 			next();
2453 			break;
2454 		}
2455 
2456 		if (EQ("net") || EQ("dstnet") || EQ("srcnet")) {
2457 			if (EQ("dstnet"))
2458 				dir = TO;
2459 			else if (EQ("srcnet"))
2460 				dir = FROM;
2461 			next();
2462 			netaddr_match(dir, token);
2463 			dir = ANY;
2464 			opstack++;
2465 			next();
2466 			break;
2467 		}
2468 
2469 		if (EQ("port") || EQ("srcport") || EQ("dstport")) {
2470 			if (EQ("dstport"))
2471 				dir = TO;
2472 			else if (EQ("srcport"))
2473 				dir = FROM;
2474 			next();
2475 			port_match(dir, token);
2476 			dir = ANY;
2477 			opstack++;
2478 			next();
2479 			break;
2480 		}
2481 
2482 		if (EQ("rpc")) {
2483 			uint_t vers, proc;
2484 			char savetoken[32];
2485 
2486 			vers = proc = -1;
2487 			next();
2488 			(void) strlcpy(savetoken, token, sizeof (savetoken));
2489 			next();
2490 			if (*token == ',') {
2491 				next();
2492 				if (tokentype != NUMBER)
2493 					pr_err("version number expected");
2494 				vers = tokenval;
2495 				next();
2496 			}
2497 			if (*token == ',') {
2498 				next();
2499 				if (tokentype != NUMBER)
2500 					pr_err("proc number expected");
2501 				proc = tokenval;
2502 				next();
2503 			}
2504 			rpc_match_prog(dir, savetoken, vers, proc);
2505 			dir = ANY;
2506 			opstack++;
2507 			break;
2508 		}
2509 
2510 		if (EQ("slp")) {
2511 			/* filter out TCP handshakes */
2512 			emitop(OP_OFFSET_LINK);
2513 			compare_value(9, 1, IPPROTO_TCP);
2514 			emitop(OP_LOAD_CONST);
2515 			emitval(52);
2516 			emitop(OP_LOAD_CONST);
2517 			emitval(2);
2518 			emitop(OP_LOAD_SHORT);
2519 			emitop(OP_GE);
2520 			emitop(OP_AND);	/* proto == TCP && len < 52 */
2521 			emitop(OP_NOT);
2522 			emitop(OP_BRFL); /* pkt too short to be a SLP call */
2523 			m = chain(0);
2524 
2525 			emitop(OP_OFFSET_POP);
2526 			emitop(OP_OFFSET_SLP);
2527 			resolve_chain(m);
2528 			opstack++;
2529 			next();
2530 			break;
2531 		}
2532 
2533 		if (EQ("ldap")) {
2534 			dir = ANY;
2535 			port_match(dir, "ldap");
2536 			opstack++;
2537 			next();
2538 			break;
2539 		}
2540 
2541 		if (EQ("and") || EQ("or")) {
2542 			break;
2543 		}
2544 
2545 		if (EQ("zone")) {
2546 			next();
2547 			if (tokentype != NUMBER)
2548 				pr_err("zoneid expected");
2549 			zone_match(dir, BE_64((uint64_t)(tokenval)));
2550 			opstack++;
2551 			next();
2552 			break;
2553 		}
2554 
2555 		if (EQ("gateway")) {
2556 			next();
2557 			if (eaddr || tokentype != ALPHA)
2558 				pr_err("hostname required: %s", token);
2559 			etheraddr_match(dir, token);
2560 			dir = ANY;
2561 			emitop(OP_BRFL);
2562 			m = chain(0);
2563 			ipaddr_match(dir, token, IPV4_AND_IPV6);
2564 			emitop(OP_NOT);
2565 			resolve_chain(m);
2566 			opstack++;
2567 			next();
2568 		}
2569 
2570 		if (EQ("host") || EQ("between") ||
2571 		    tokentype == ALPHA ||	/* assume its a hostname */
2572 		    tokentype == ADDR_IP ||
2573 		    tokentype == ADDR_IP6 ||
2574 		    tokentype == ADDR_AT ||
2575 		    tokentype == ADDR_ETHER) {
2576 			if (EQ("host") || EQ("between"))
2577 				next();
2578 			if (eaddr || tokentype == ADDR_ETHER) {
2579 				etheraddr_match(dir, token);
2580 			} else if (tokentype == ALPHA) {
2581 				ipaddr_match(dir, token, IPV4_AND_IPV6);
2582 			} else if (tokentype == ADDR_AT) {
2583 				ataddr_match(dir, token);
2584 			} else if (tokentype == ADDR_IP) {
2585 				ipaddr_match(dir, token, IPV4_ONLY);
2586 			} else {
2587 				ipaddr_match(dir, token, IPV6_ONLY);
2588 			}
2589 			dir = ANY;
2590 			eaddr = 0;
2591 			opstack++;
2592 			next();
2593 			break;
2594 		}
2595 
2596 		if (tokentype == NUMBER) {
2597 			load_const(tokenval);
2598 			opstack++;
2599 			next();
2600 			break;
2601 		}
2602 
2603 		break;	/* unknown token */
2604 	}
2605 }
2606 
2607 struct optable {
2608 	char *op_tok;
2609 	enum optype op_type;
2610 };
2611 
2612 static struct optable
2613 mulops[] = {
2614 	"*",	OP_MUL,
2615 	"/",	OP_DIV,
2616 	"%",	OP_REM,
2617 	"&",	OP_AND,
2618 	"",	OP_STOP,
2619 };
2620 
2621 static struct optable
2622 addops[] = {
2623 	"+",	OP_ADD,
2624 	"-",	OP_SUB,
2625 	"|",	OP_OR,
2626 	"^",	OP_XOR,
2627 	"",	OP_STOP,
2628 };
2629 
2630 static struct optable
2631 compareops[] = {
2632 	"==",	OP_EQ,
2633 	"=",	OP_EQ,
2634 	"!=",	OP_NE,
2635 	">",	OP_GT,
2636 	">=",	OP_GE,
2637 	"<",	OP_LT,
2638 	"<=",	OP_LE,
2639 	"",	OP_STOP,
2640 };
2641 
2642 /*
2643  * Using the table, find the operator
2644  * that corresponds to the token.
2645  * Return 0 if not found.
2646  */
2647 static int
2648 find_op(char *tok, struct optable *table)
2649 {
2650 	struct optable *op;
2651 
2652 	for (op = table; *op->op_tok; op++) {
2653 		if (strcmp(tok, op->op_tok) == 0)
2654 			return (op->op_type);
2655 	}
2656 
2657 	return (0);
2658 }
2659 
2660 static void
2661 expr_mul()
2662 {
2663 	int op;
2664 	int s = opstack;
2665 
2666 	primary();
2667 	while (op = find_op(token, mulops)) {
2668 		next();
2669 		primary();
2670 		checkstack(s + 2);
2671 		emitop(op);
2672 		opstack--;
2673 	}
2674 }
2675 
2676 static void
2677 expr_add()
2678 {
2679 	int op, s = opstack;
2680 
2681 	expr_mul();
2682 	while (op = find_op(token, addops)) {
2683 		next();
2684 		expr_mul();
2685 		checkstack(s + 2);
2686 		emitop(op);
2687 		opstack--;
2688 	}
2689 }
2690 
2691 static void
2692 expr_compare()
2693 {
2694 	int op, s = opstack;
2695 
2696 	expr_add();
2697 	while (op = find_op(token, compareops)) {
2698 		next();
2699 		expr_add();
2700 		checkstack(s + 2);
2701 		emitop(op);
2702 		opstack--;
2703 	}
2704 }
2705 
2706 /*
2707  * Alternation ("and") is difficult because
2708  * an implied "and" is acknowledge between
2709  * two adjacent primaries.  Just keep calling
2710  * the lower-level expression routine until
2711  * no value is added to the opstack.
2712  */
2713 static void
2714 alternation()
2715 {
2716 	int m = 0;
2717 	int s = opstack;
2718 
2719 	expr_compare();
2720 	checkstack(s + 1);
2721 	for (;;) {
2722 		if (EQ("and"))
2723 			next();
2724 		emitop(OP_BRFL);
2725 		m = chain(m);
2726 		expr_compare();
2727 		if (opstack != s + 2)
2728 			break;
2729 		opstack--;
2730 	}
2731 	unemit(2);
2732 	resolve_chain(m);
2733 }
2734 
2735 static void
2736 expression()
2737 {
2738 	int m = 0;
2739 	int s = opstack;
2740 
2741 	alternation();
2742 	while (EQ("or") || EQ(",")) {
2743 		emitop(OP_BRTR);
2744 		m = chain(m);
2745 		next();
2746 		alternation();
2747 		checkstack(s + 2);
2748 		opstack--;
2749 	}
2750 	resolve_chain(m);
2751 }
2752 
2753 /*
2754  * Take n args from the argv list
2755  * and concatenate them into a single string.
2756  */
2757 char *
2758 concat_args(char **argv, int argc)
2759 {
2760 	int i, len;
2761 	char *str, *p;
2762 
2763 	/* First add the lengths of all the strings */
2764 	len = 0;
2765 	for (i = 0; i < argc; i++)
2766 		len += strlen(argv[i]) + 1;
2767 
2768 	/* allocate the big string */
2769 	str = (char *)malloc(len);
2770 	if (str == NULL)
2771 		pr_err("no mem");
2772 
2773 	p = str;
2774 
2775 	/*
2776 	 * Concat the strings into the big
2777 	 * string using a space as separator
2778 	 */
2779 	for (i = 0; i < argc; i++) {
2780 		strcpy(p, argv[i]);
2781 		p += strlen(p);
2782 		*p++ = ' ';
2783 	}
2784 	*--p = '\0';
2785 
2786 	return (str);
2787 }
2788 
2789 /*
2790  * Take the expression in the string "expr"
2791  * and compile it into the code array.
2792  * Print the generated code if the print
2793  * arg is set.
2794  */
2795 void
2796 compile(char *expr, int print)
2797 {
2798 	expr = strdup(expr);
2799 	if (expr == NULL)
2800 		pr_err("no mem");
2801 	curr_op = oplist;
2802 	tkp = expr;
2803 	dir = ANY;
2804 
2805 	next();
2806 	if (tokentype != EOL)
2807 		expression();
2808 	emitop(OP_STOP);
2809 	if (tokentype != EOL)
2810 		pr_err("invalid expression");
2811 	optimize(oplist);
2812 	if (print)
2813 		codeprint();
2814 }
2815 
2816 /*
2817  * Lookup hostname in the arp cache.
2818  */
2819 boolean_t
2820 arp_for_ether(char *hostname, struct ether_addr *ep)
2821 {
2822 	struct arpreq ar;
2823 	struct hostent *hp;
2824 	struct sockaddr_in *sin;
2825 	int error_num;
2826 	int s;
2827 
2828 	memset(&ar, 0, sizeof (ar));
2829 	sin = (struct sockaddr_in *)&ar.arp_pa;
2830 	sin->sin_family = AF_INET;
2831 	hp = getipnodebyname(hostname, AF_INET, 0, &error_num);
2832 	if (hp == NULL) {
2833 		return (B_FALSE);
2834 	}
2835 	memcpy(&sin->sin_addr, hp->h_addr, sizeof (sin->sin_addr));
2836 	s = socket(AF_INET, SOCK_DGRAM, 0);
2837 	if (s < 0) {
2838 		return (B_FALSE);
2839 	}
2840 	if (ioctl(s, SIOCGARP, &ar) < 0) {
2841 		close(s);
2842 		return (B_FALSE);
2843 	}
2844 	close(s);
2845 	memcpy(ep->ether_addr_octet, ar.arp_ha.sa_data, sizeof (*ep));
2846 	return (B_TRUE);
2847 }
2848