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