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