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 2006 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 <net/if.h>
41 #include <netinet/in_systm.h>
42 #include <netinet/in.h>
43 #include <netinet/ip.h>
44 #include <netinet/ip6.h>
45 #include <inet/ip6.h>
46 #include <inet/ip.h>
47 #include <netinet/if_ether.h>
48 #include <netinet/tcp.h>
49 #include <netinet/udp.h>
50 #include <netdb.h>
51 #include <arpa/inet.h>
52 #include <rpc/rpc.h>
53 #include <rpc/rpcent.h>
54 
55 #include <sys/dlpi.h>
56 #include <snoop.h>
57 
58 #define	IPV4_ONLY	0
59 #define	IPV6_ONLY	1
60 #define	IPV4_AND_IPV6	2
61 
62 /*
63  * The following constants represent the offsets in bytes from the beginning
64  * of the IP(v6) header of the source and destination IP(v6) addresses.
65  * These are useful when generating filter code.
66  */
67 #define	IPV4_SRCADDR_OFFSET	12
68 #define	IPV4_DSTADDR_OFFSET	16
69 #define	IPV6_SRCADDR_OFFSET	8
70 #define	IPV6_DSTADDR_OFFSET	24
71 #define	IP_VERS(p)	(((*(uchar_t *)p) & 0xf0) >> 4)
72 #define	MASKED_IPV4_VERS	0x40
73 #define	MASKED_IPV6_VERS	0x60
74 #define	IP_HDR_LEN(p)	(((*(uchar_t *)p) & 0xf) * 4)
75 #define	TCP_HDR_LEN(p)	((((*((uchar_t *)p+12)) >> 4) & 0xf) * 4)
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_POP restores the offset base to the value prior
132  * to the most recent OP_OFFSET call.
133  */
134 enum optype {
135 	OP_STOP = 0,
136 	OP_LOAD_OCTET,
137 	OP_LOAD_SHORT,
138 	OP_LOAD_LONG,
139 	OP_LOAD_CONST,
140 	OP_LOAD_LENGTH,
141 	OP_EQ,
142 	OP_NE,
143 	OP_GT,
144 	OP_GE,
145 	OP_LT,
146 	OP_LE,
147 	OP_AND,
148 	OP_OR,
149 	OP_XOR,
150 	OP_NOT,
151 	OP_BRFL,
152 	OP_BRTR,
153 	OP_ADD,
154 	OP_SUB,
155 	OP_MUL,
156 	OP_DIV,
157 	OP_REM,
158 	OP_OFFSET_POP,
159 	OP_OFFSET_ZERO,
160 	OP_OFFSET_LINK,
161 	OP_OFFSET_IP,
162 	OP_OFFSET_TCP,
163 	OP_OFFSET_UDP,
164 	OP_OFFSET_RPC,
165 	OP_OFFSET_SLP,
166 	OP_LAST
167 };
168 
169 static char *opnames[] = {
170 	"STOP",
171 	"LOAD_OCTET",
172 	"LOAD_SHORT",
173 	"LOAD_LONG",
174 	"LOAD_CONST",
175 	"LOAD_LENGTH",
176 	"EQ",
177 	"NE",
178 	"GT",
179 	"GE",
180 	"LT",
181 	"LE",
182 	"AND",
183 	"OR",
184 	"XOR",
185 	"NOT",
186 	"BRFL",
187 	"BRTR",
188 	"ADD",
189 	"SUB",
190 	"MUL",
191 	"DIV",
192 	"REM",
193 	"OFFSET_POP",
194 	"OFFSET_ZERO",
195 	"OFFSET_ETHER",
196 	"OFFSET_IP",
197 	"OFFSET_TCP",
198 	"OFFSET_UDP",
199 	"OFFSET_RPC",
200 	"OP_OFFSET_SLP",
201 	""
202 };
203 
204 #define	MAXOPS 1024
205 #define	MAXSS	64
206 static uint_t oplist[MAXOPS];	/* array of operators */
207 static uint_t *curr_op;		/* last op generated */
208 
209 extern int valid_slp(uchar_t *, int);	/* decides if a SLP msg is valid */
210 extern struct hostent *lgetipnodebyname(const char *, int, int, int *);
211 
212 static void alternation();
213 static uint_t chain();
214 static void codeprint();
215 static void emitop();
216 static void emitval();
217 static void expression();
218 static struct xid_entry *find_rpc();
219 static void optimize();
220 static void ethertype_match();
221 
222 
223 /*
224  * Returns the ULP for an IPv4 or IPv6 packet
225  * Assumes that the packet has already been checked to verify
226  * that it's either IPv4 or IPv6
227  *
228  * XXX Will need to be updated for AH and ESP
229  * XXX when IPsec is supported for v6.
230  */
231 static uchar_t
232 ip_proto_of(uchar_t *ip)
233 {
234 	uchar_t		nxt;
235 	boolean_t	not_done = B_TRUE;
236 	uchar_t		*ptr = ip;
237 
238 	switch (IP_VERS(ip)) {
239 	case IPV4_VERSION:
240 		return (IP_PROTO_OF(ip));
241 	case IPV6_VERSION:
242 
243 		nxt = ip[6];
244 		ptr += 40;		/* size of ip6 header */
245 		do {
246 			switch (nxt) {
247 			/*
248 			 * XXX Add IPsec headers here when supported for v6
249 			 * XXX (the AH will have a different size...)
250 			 */
251 			case IPPROTO_HOPOPTS:
252 			case IPPROTO_ROUTING:
253 			case IPPROTO_FRAGMENT:
254 			case IPPROTO_DSTOPTS:
255 				ptr += (8 * (ptr[1] + 1));
256 				nxt = *ptr;
257 				break;
258 
259 			default:
260 				not_done = B_FALSE;
261 				break;
262 			}
263 		} while (not_done);
264 		return (nxt);
265 	default:
266 		break;			/* shouldn't get here... */
267 	}
268 	return (0);
269 }
270 
271 /*
272  * Returns the total IP header length.
273  * For v4, this includes any options present.
274  * For v6, this is the length of the IPv6 header plus
275  * any extension headers present.
276  *
277  * XXX Will need to be updated for AH and ESP
278  * XXX when IPsec is supported for v6.
279  */
280 static int
281 ip_hdr_len(uchar_t *ip)
282 {
283 	uchar_t		nxt;
284 	int		hdr_len;
285 	boolean_t	not_done = B_TRUE;
286 	int		len = 40;	/* IPv6 header size */
287 	uchar_t		*ptr = ip;
288 
289 	switch (IP_VERS(ip)) {
290 	case IPV4_VERSION:
291 		return (IP_HDR_LEN(ip));
292 	case IPV6_VERSION:
293 		nxt = ip[6];
294 		ptr += len;
295 		do {
296 			switch (nxt) {
297 			/*
298 			 * XXX Add IPsec headers here when supported for v6
299 			 * XXX (the AH will have a different size...)
300 			 */
301 			case IPPROTO_HOPOPTS:
302 			case IPPROTO_ROUTING:
303 			case IPPROTO_FRAGMENT:
304 			case IPPROTO_DSTOPTS:
305 				hdr_len = (8 * (ptr[1] + 1));
306 				len += hdr_len;
307 				ptr += hdr_len;
308 				nxt = *ptr;
309 				break;
310 
311 			default:
312 				not_done = B_FALSE;
313 				break;
314 			}
315 		} while (not_done);
316 		return (len);
317 	default:
318 		break;
319 	}
320 	return (0);			/* not IP */
321 }
322 
323 static void
324 codeprint()
325 {
326 	uint_t *op;
327 
328 	printf("User filter:\n");
329 
330 	for (op = oplist; *op; op++) {
331 		if (*op <= OP_LAST)
332 			printf("\t%2d: %s\n", op - oplist, opnames[*op]);
333 		else
334 			printf("\t%2d: (%d)\n", op - oplist, *op);
335 
336 		switch (*op) {
337 		case OP_LOAD_CONST:
338 		case OP_BRTR:
339 		case OP_BRFL:
340 			op++;
341 			if ((int)*op < 0)
342 				printf("\t%2d:   0x%08x (%d)\n",
343 					op - oplist, *op, *op);
344 			else
345 				printf("\t%2d:   %d (0x%08x)\n",
346 					op - oplist, *op, *op);
347 		}
348 	}
349 	printf("\t%2d: STOP\n", op - oplist);
350 	printf("\n");
351 }
352 
353 
354 /*
355  * Take a pass through the generated code and optimize
356  * branches.  A branch true (BRTR) that has another BRTR
357  * at its destination can use the address of the destination
358  * BRTR.  A BRTR that points to a BRFL (branch false) should
359  * point to the address following the BRFL.
360  * A similar optimization applies to BRFL operators.
361  */
362 static void
363 optimize(uint_t *oplistp)
364 {
365 	uint_t *op;
366 
367 	for (op = oplistp; *op; op++) {
368 		switch (*op) {
369 		case OP_LOAD_CONST:
370 			op++;
371 			break;
372 		case OP_BRTR:
373 			op++;
374 			optimize(&oplist[*op]);
375 			if (oplist[*op] == OP_BRFL)
376 				*op += 2;
377 			else if (oplist[*op] == OP_BRTR)
378 				*op = oplist[*op + 1];
379 			break;
380 		case OP_BRFL:
381 			op++;
382 			optimize(&oplist[*op]);
383 			if (oplist[*op] == OP_BRTR)
384 				*op += 2;
385 			else if (oplist[*op] == OP_BRFL)
386 				*op = oplist[*op + 1];
387 			break;
388 		}
389 	}
390 }
391 
392 /*
393  * RPC packets are tough to filter.
394  * While the call packet has all the interesting
395  * info: program number, version, procedure etc,
396  * the reply packet has none of this information.
397  * If we want to do useful filtering based on this
398  * information then we have to stash the information
399  * from the call packet, and use the XID in the reply
400  * to find the stashed info.  The stashed info is
401  * kept in a circular lifo, assuming that a call packet
402  * will be followed quickly by its reply.
403  */
404 
405 struct xid_entry {
406 	unsigned	x_xid;		/* The XID (32 bits) */
407 	unsigned	x_dir;		/* CALL or REPLY */
408 	unsigned	x_rpcvers;	/* Protocol version (2) */
409 	unsigned	x_prog;		/* RPC program number */
410 	unsigned	x_vers;		/* RPC version number */
411 	unsigned	x_proc;		/* RPC procedure number */
412 };
413 static struct xid_entry	xe_table[XID_CACHE_SIZE];
414 static struct xid_entry	*xe_first = &xe_table[0];
415 static struct xid_entry	*xe	  = &xe_table[0];
416 static struct xid_entry	*xe_last  = &xe_table[XID_CACHE_SIZE - 1];
417 
418 static struct xid_entry *
419 find_rpc(struct rpc_msg *rpc)
420 {
421 	struct xid_entry *x;
422 
423 	for (x = xe; x >= xe_first; x--)
424 		if (x->x_xid == rpc->rm_xid)
425 			return (x);
426 	for (x = xe_last; x > xe; x--)
427 		if (x->x_xid == rpc->rm_xid)
428 			return (x);
429 	return (NULL);
430 }
431 
432 static void
433 stash_rpc(struct rpc_msg *rpc)
434 {
435 	struct xid_entry *x;
436 
437 	if (find_rpc(rpc))
438 		return;
439 
440 	x = xe++;
441 	if (xe > xe_last)
442 		xe = xe_first;
443 	x->x_xid  = rpc->rm_xid;
444 	x->x_dir  = htonl(REPLY);
445 	x->x_prog = rpc->rm_call.cb_prog;
446 	x->x_vers = rpc->rm_call.cb_vers;
447 	x->x_proc = rpc->rm_call.cb_proc;
448 }
449 
450 /*
451  * SLP can multicast requests, and recieve unicast replies in which
452  * neither the source nor destination port is identifiable as a SLP
453  * port. Hence, we need to do as RPC does, and keep track of packets we
454  * are interested in. For SLP, however, we use ports, not XIDs, and
455  * a smaller cache size is more efficient since every incoming packet
456  * needs to be checked.
457  */
458 
459 #define	SLP_CACHE_SIZE 64
460 static uint_t slp_table[SLP_CACHE_SIZE];
461 static int slp_index	= 0;
462 
463 /*
464  * Returns the index of dport in the table if found, otherwise -1.
465  */
466 static int
467 find_slp(uint_t dport) {
468     int i;
469 
470     if (!dport)
471 	return (0);
472 
473     for (i = slp_index; i >= 0; i--)
474 	if (slp_table[i] == dport) {
475 	    return (i);
476 	}
477     for (i = SLP_CACHE_SIZE - 1; i > slp_index; i--)
478 	if (slp_table[i] == dport) {
479 	    return (i);
480 	}
481     return (-1);
482 }
483 
484 static void stash_slp(uint_t sport) {
485     if (slp_table[slp_index - 1] == sport)
486 	/* avoid redundancy due to multicast retransmissions */
487 	return;
488 
489     slp_table[slp_index++] = sport;
490     if (slp_index == SLP_CACHE_SIZE)
491 	slp_index = 0;
492 }
493 
494 /*
495  * This routine takes a packet and returns true or false
496  * according to whether the filter expression selects it
497  * or not.
498  * We assume here that offsets for short and long values
499  * are even - we may die with an alignment error if the
500  * CPU doesn't support odd addresses.  Note that long
501  * values are loaded as two shorts so that 32 bit word
502  * alignment isn't important.
503  *
504  * IPv6 is a bit stickier to handle than IPv4...
505  */
506 
507 int
508 want_packet(uchar_t *pkt, int len, int origlen)
509 {
510 	uint_t stack[MAXSS];	/* operand stack */
511 	uint_t *op;		/* current operator */
512 	uint_t *sp;		/* top of operand stack */
513 	uchar_t *base;		/* base for offsets into packet */
514 	uchar_t *ip;		/* addr of IP header, unaligned */
515 	uchar_t *tcp;		/* addr of TCP header, unaligned */
516 	uchar_t *udp;		/* addr of UDP header, unaligned */
517 	struct rpc_msg rpcmsg;	/* addr of RPC header */
518 	struct rpc_msg *rpc;
519 	int newrpc = 0;
520 	uchar_t *slphdr;		/* beginning of SLP header */
521 	uint_t slp_sport, slp_dport;
522 	int off, header_size;
523 	uchar_t *offstack[MAXSS];	/* offset stack */
524 	uchar_t **offp;		/* current offset */
525 	uchar_t *opkt = NULL;
526 	uint_t olen;
527 
528 	sp = stack;
529 	*sp = 1;
530 	base = pkt;
531 	offp = offstack;
532 
533 	header_size = (*interface->header_len)((char *)pkt);
534 
535 	for (op = oplist; *op; op++) {
536 		switch ((enum optype) *op) {
537 		case OP_LOAD_OCTET:
538 			if ((base + *sp) > (pkt + len))
539 				return (0); /* packet too short */
540 
541 			*sp = *((uchar_t *)(base + *sp));
542 			break;
543 		case OP_LOAD_SHORT:
544 			off = *sp;
545 
546 			if ((base + off + sizeof (uint16_t) - 1) > (pkt + len))
547 				return (0); /* packet too short */
548 
549 			/*
550 			 * Handle 2 possible alignments
551 			 */
552 			switch ((((unsigned)base)+off) % sizeof (ushort_t)) {
553 			case 0:
554 				*sp = ntohs(*((ushort_t *)(base + *sp)));
555 				break;
556 			case 1:
557 				*((uchar_t *)(sp)) =
558 					*((uchar_t *)(base + off));
559 				*(((uchar_t *)sp) + 1) =
560 					*((uchar_t *)(base + off) + 1);
561 				*sp = ntohs(*(ushort_t *)sp);
562 				break;
563 			}
564 			break;
565 		case OP_LOAD_LONG:
566 			off = *sp;
567 
568 			if ((base + off + sizeof (uint32_t) - 1) > (pkt + len))
569 				return (0); /* packet too short */
570 
571 			/*
572 			 * Handle 3 possible alignments
573 			 */
574 			switch ((((unsigned)base) + off) % sizeof (uint_t)) {
575 			case 0:
576 				*sp = *(uint_t *)(base + off);
577 				break;
578 
579 			case 2:
580 				*((ushort_t *)(sp)) =
581 					*((ushort_t *)(base + off));
582 				*(((ushort_t *)sp) + 1) =
583 					*((ushort_t *)(base + off) + 1);
584 				break;
585 
586 			case 1:
587 			case 3:
588 				*((uchar_t *)(sp)) =
589 					*((uchar_t *)(base + off));
590 				*(((uchar_t *)sp) + 1) =
591 					*((uchar_t *)(base + off) + 1);
592 				*(((uchar_t *)sp) + 2) =
593 					*((uchar_t *)(base + off) + 2);
594 				*(((uchar_t *)sp) + 3) =
595 					*((uchar_t *)(base + off) + 3);
596 				break;
597 			}
598 			*sp = ntohl(*sp);
599 			break;
600 		case OP_LOAD_CONST:
601 			if (sp >= &stack[MAXSS])
602 				return (0);
603 			*(++sp) = *(++op);
604 			break;
605 		case OP_LOAD_LENGTH:
606 			if (sp >= &stack[MAXSS])
607 				return (0);
608 			*(++sp) = origlen;
609 			break;
610 		case OP_EQ:
611 			if (sp < &stack[1])
612 				return (0);
613 			sp--;
614 			*sp = *sp == *(sp + 1);
615 			break;
616 		case OP_NE:
617 			if (sp < &stack[1])
618 				return (0);
619 			sp--;
620 			*sp = *sp != *(sp + 1);
621 			break;
622 		case OP_GT:
623 			if (sp < &stack[1])
624 				return (0);
625 			sp--;
626 			*sp = *sp > *(sp + 1);
627 			break;
628 		case OP_GE:
629 			if (sp < &stack[1])
630 				return (0);
631 			sp--;
632 			*sp = *sp >= *(sp + 1);
633 			break;
634 		case OP_LT:
635 			if (sp < &stack[1])
636 				return (0);
637 			sp--;
638 			*sp = *sp < *(sp + 1);
639 			break;
640 		case OP_LE:
641 			if (sp < &stack[1])
642 				return (0);
643 			sp--;
644 			*sp = *sp <= *(sp + 1);
645 			break;
646 		case OP_AND:
647 			if (sp < &stack[1])
648 				return (0);
649 			sp--;
650 			*sp &= *(sp + 1);
651 			break;
652 		case OP_OR:
653 			if (sp < &stack[1])
654 				return (0);
655 			sp--;
656 			*sp |= *(sp + 1);
657 			break;
658 		case OP_XOR:
659 			if (sp < &stack[1])
660 				return (0);
661 			sp--;
662 			*sp ^= *(sp + 1);
663 			break;
664 		case OP_NOT:
665 			*sp = !*sp;
666 			break;
667 		case OP_BRFL:
668 			op++;
669 			if (!*sp)
670 				op = &oplist[*op] - 1;
671 			break;
672 		case OP_BRTR:
673 			op++;
674 			if (*sp)
675 				op = &oplist[*op] - 1;
676 			break;
677 		case OP_ADD:
678 			if (sp < &stack[1])
679 				return (0);
680 			sp--;
681 			*sp += *(sp + 1);
682 			break;
683 		case OP_SUB:
684 			if (sp < &stack[1])
685 				return (0);
686 			sp--;
687 			*sp -= *(sp + 1);
688 			break;
689 		case OP_MUL:
690 			if (sp < &stack[1])
691 				return (0);
692 			sp--;
693 			*sp *= *(sp + 1);
694 			break;
695 		case OP_DIV:
696 			if (sp < &stack[1])
697 				return (0);
698 			sp--;
699 			*sp /= *(sp + 1);
700 			break;
701 		case OP_REM:
702 			if (sp < &stack[1])
703 				return (0);
704 			sp--;
705 			*sp %= *(sp + 1);
706 			break;
707 		case OP_OFFSET_POP:
708 			if (offp < &offstack[0])
709 				return (0);
710 			base = *offp--;
711 			if (opkt != NULL) {
712 				pkt = opkt;
713 				len = olen;
714 				opkt = NULL;
715 			}
716 			break;
717 		case OP_OFFSET_ZERO:
718 			if (offp >= &offstack[MAXSS])
719 				return (0);
720 			*++offp = base;
721 			base = pkt;
722 			break;
723 		case OP_OFFSET_LINK:
724 			if (offp >= &offstack[MAXSS])
725 				return (0);
726 			*++offp = base;
727 			base = pkt + header_size;
728 			/*
729 			 * If the offset exceeds the packet length,
730 			 * we should not be interested in this packet...
731 			 * Just return 0.
732 			 */
733 			if (base > pkt + len) {
734 				return (0);
735 			}
736 			break;
737 		case OP_OFFSET_IP:
738 			if (offp >= &offstack[MAXSS])
739 				return (0);
740 			*++offp = base;
741 			ip = pkt + header_size;
742 			base = ip + ip_hdr_len(ip);
743 			if (base == ip) {
744 				return (0);			/* not IP */
745 			}
746 			if (base > pkt + len) {
747 				return (0);			/* bad pkt */
748 			}
749 			break;
750 		case OP_OFFSET_TCP:
751 			if (offp >= &offstack[MAXSS])
752 				return (0);
753 			*++offp = base;
754 			ip = pkt + header_size;
755 			tcp = ip + ip_hdr_len(ip);
756 			if (tcp == ip) {
757 				return (0);			    /* not IP */
758 			}
759 			base = tcp + TCP_HDR_LEN(tcp);
760 			if (base > pkt + len) {
761 				return (0);
762 			}
763 			break;
764 		case OP_OFFSET_UDP:
765 			if (offp >= &offstack[MAXSS])
766 				return (0);
767 			*++offp = base;
768 			ip = pkt + header_size;
769 			udp = ip + ip_hdr_len(ip);
770 			if (udp == ip) {
771 				return (0);			    /* not IP */
772 			}
773 			base = udp + sizeof (struct udphdr);
774 			if (base > pkt + len) {
775 				return (0);
776 			}
777 			break;
778 		case OP_OFFSET_RPC:
779 			if (offp >= &offstack[MAXSS])
780 				return (0);
781 			*++offp = base;
782 			ip = pkt + header_size;
783 			rpc = NULL;
784 
785 			if (IP_VERS(ip) != IPV4_VERSION &&
786 			    IP_VERS(ip) != IPV6_VERSION) {
787 				if (sp >= &stack[MAXSS])
788 					return (0);
789 				*(++sp) = 0;
790 				break;
791 			}
792 
793 			switch (ip_proto_of(ip)) {
794 			case IPPROTO_UDP:
795 				udp = ip + ip_hdr_len(ip);
796 				rpc = (struct rpc_msg *)(udp +
797 				    sizeof (struct udphdr));
798 				break;
799 			case IPPROTO_TCP:
800 				tcp = ip + ip_hdr_len(ip);
801 				/*
802 				 * Need to skip an extra 4 for the xdr_rec
803 				 * field.
804 				 */
805 				rpc = (struct rpc_msg *)(tcp +
806 				    TCP_HDR_LEN(tcp) + 4);
807 				break;
808 			}
809 			/*
810 			 * We need to have at least 24 bytes of a RPC
811 			 * packet to look at to determine the validity
812 			 * of it.
813 			 */
814 			if (rpc == NULL || (uchar_t *)rpc + 24 > pkt + len) {
815 				if (sp >= &stack[MAXSS])
816 					return (0);
817 				*(++sp) = 0;
818 				break;
819 			}
820 			/* align */
821 			(void) memcpy(&rpcmsg, rpc, 24);
822 			if (!valid_rpc(&rpcmsg, 24)) {
823 				if (sp >= &stack[MAXSS])
824 					return (0);
825 				*(++sp) = 0;
826 				break;
827 			}
828 			if (ntohl(rpcmsg.rm_direction) == CALL) {
829 				base = (uchar_t *)rpc;
830 				newrpc = 1;
831 				if (sp >= &stack[MAXSS])
832 					return (0);
833 				*(++sp) = 1;
834 			} else {
835 				opkt = pkt;
836 				olen = len;
837 
838 				pkt = base = (uchar_t *)find_rpc(&rpcmsg);
839 				len = sizeof (struct xid_entry);
840 				if (sp >= &stack[MAXSS])
841 					return (0);
842 				*(++sp) = base != NULL;
843 			}
844 			break;
845 		case OP_OFFSET_SLP:
846 			slphdr = NULL;
847 			ip = pkt + header_size;
848 
849 			if (IP_VERS(ip) != IPV4_VERSION &&
850 			    IP_VERS(ip) != IPV6_VERSION) {
851 				if (sp >= &stack[MAXSS])
852 					return (0);
853 				*(++sp) = 0;
854 				break;
855 			}
856 
857 			switch (ip_proto_of(ip)) {
858 				struct udphdr udp_h;
859 				struct tcphdr tcp_h;
860 			case IPPROTO_UDP:
861 				udp = ip + ip_hdr_len(ip);
862 				/* align */
863 				memcpy(&udp_h, udp, sizeof (udp_h));
864 				slp_sport = ntohs(udp_h.uh_sport);
865 				slp_dport = ntohs(udp_h.uh_dport);
866 				slphdr = udp + sizeof (struct udphdr);
867 				break;
868 			case IPPROTO_TCP:
869 				tcp = ip + ip_hdr_len(ip);
870 				/* align */
871 				memcpy(&tcp_h, tcp, sizeof (tcp_h));
872 				slp_sport = ntohs(tcp_h.th_sport);
873 				slp_dport = ntohs(tcp_h.th_dport);
874 				slphdr = tcp + TCP_HDR_LEN(tcp);
875 				break;
876 			}
877 			if (slphdr == NULL || slphdr > pkt + len) {
878 				if (sp >= &stack[MAXSS])
879 					return (0);
880 				*(++sp) = 0;
881 				break;
882 			}
883 			if (slp_sport == 427 || slp_dport == 427) {
884 				if (sp >= &stack[MAXSS])
885 					return (0);
886 				*(++sp) = 1;
887 				if (slp_sport != 427 && slp_dport == 427)
888 					stash_slp(slp_sport);
889 				break;
890 			} else if (find_slp(slp_dport) != -1) {
891 				if (valid_slp(slphdr, len)) {
892 					if (sp >= &stack[MAXSS])
893 						return (0);
894 					*(++sp) = 1;
895 					break;
896 				}
897 				/* else fallthrough to reject */
898 			}
899 			if (sp >= &stack[MAXSS])
900 				return (0);
901 			*(++sp) = 0;
902 			break;
903 		}
904 	}
905 
906 	if (*sp && newrpc)
907 		stash_rpc(&rpcmsg);
908 
909 	return (*sp);
910 }
911 
912 static void
913 load_const(uint_t constval)
914 {
915 	emitop(OP_LOAD_CONST);
916 	emitval(constval);
917 }
918 
919 static void
920 load_value(int offset, int len)
921 {
922 	if (offset >= 0)
923 		load_const(offset);
924 
925 	switch (len) {
926 		case 1:
927 			emitop(OP_LOAD_OCTET);
928 			break;
929 		case 2:
930 			emitop(OP_LOAD_SHORT);
931 			break;
932 		case 4:
933 			emitop(OP_LOAD_LONG);
934 			break;
935 	}
936 }
937 
938 /*
939  * Emit code to compare a field in
940  * the packet against a constant value.
941  */
942 static void
943 compare_value(uint_t offset, uint_t len, uint_t val)
944 {
945 	load_const(val);
946 	load_value(offset, len);
947 	emitop(OP_EQ);
948 }
949 
950 static void
951 compare_addr_v4(uint_t offset, uint_t len, uint_t val)
952 {
953 	load_const(ntohl(val));
954 	load_value(offset, len);
955 	emitop(OP_EQ);
956 }
957 
958 static void
959 compare_addr_v6(uint_t offset, uint_t len, struct in6_addr val)
960 {
961 	int i;
962 	uint32_t value;
963 
964 	for (i = 0; i < len; i += 4) {
965 		value = ntohl(*(uint32_t *)&val.s6_addr[i]);
966 		load_const(value);
967 		load_value(offset + i, 4);
968 		emitop(OP_EQ);
969 		if (i != 0)
970 			emitop(OP_AND);
971 	}
972 }
973 
974 /*
975  * Same as above except do the comparison
976  * after and'ing a mask value.  Useful
977  * for comparing IP network numbers
978  */
979 static void
980 compare_value_mask(uint_t offset, uint_t len, uint_t val, int mask)
981 {
982 	load_value(offset, len);
983 	load_const(mask);
984 	emitop(OP_AND);
985 	load_const(val);
986 	emitop(OP_EQ);
987 }
988 
989 /* Emit an operator into the code array */
990 static void
991 emitop(enum optype opcode)
992 {
993 	if (curr_op >= &oplist[MAXOPS])
994 		pr_err("expression too long");
995 	*curr_op++ = opcode;
996 }
997 
998 /*
999  * Remove n operators recently emitted into
1000  * the code array.  Used by alternation().
1001  */
1002 static void
1003 unemit(int numops)
1004 {
1005 	curr_op -= numops;
1006 }
1007 
1008 
1009 /*
1010  * Same as emitop except that we're emitting
1011  * a value that's not an operator.
1012  */
1013 static void
1014 emitval(uint_t val)
1015 {
1016 	if (curr_op >= &oplist[MAXOPS])
1017 		pr_err("expression too long");
1018 	*curr_op++ = val;
1019 }
1020 
1021 /*
1022  * Used to chain forward branches together
1023  * for later resolution by resolve_chain().
1024  */
1025 static uint_t
1026 chain(int p)
1027 {
1028 	uint_t pos = curr_op - oplist;
1029 
1030 	emitval(p);
1031 	return (pos);
1032 }
1033 
1034 /*
1035  * Proceed backward through the code array
1036  * following a chain of forward references.
1037  * At each reference install the destination
1038  * branch offset.
1039  */
1040 static void
1041 resolve_chain(uint_t p)
1042 {
1043 	uint_t n;
1044 	uint_t pos = curr_op - oplist;
1045 
1046 	while (p) {
1047 		n = oplist[p];
1048 		oplist[p] = pos;
1049 		p = n;
1050 	}
1051 }
1052 
1053 #define	EQ(val) (strcmp(token, val) == 0)
1054 
1055 char *tkp, *sav_tkp;
1056 char *token;
1057 enum { EOL, ALPHA, NUMBER, FIELD, ADDR_IP, ADDR_ETHER, SPECIAL,
1058 	ADDR_IP6, ADDR_AT } tokentype;
1059 uint_t tokenval;
1060 
1061 /*
1062  * This is the scanner.  Each call returns the next
1063  * token in the filter expression.  A token is either:
1064  * EOL:		The end of the line - no more tokens.
1065  * ALPHA:	A name that begins with a letter and contains
1066  *		letters or digits, hyphens or underscores.
1067  * NUMBER:	A number.  The value can be represented as
1068  * 		a decimal value (1234) or an octal value
1069  *		that begins with zero (066) or a hex value
1070  *		that begins with 0x or 0X (0xff).
1071  * FIELD:	A name followed by a left square bracket.
1072  * ADDR_IP:	An IP address.  Any sequence of digits
1073  *		separated by dots e.g. 109.104.40.13
1074  * ADDR_ETHER:	An ethernet address.  Any sequence of hex
1075  *		digits separated by colons e.g. 8:0:20:0:76:39
1076  * SPECIAL:	A special character e.g. ">" or "(".  The scanner
1077  *		correctly handles digraphs - two special characters
1078  *		that constitute a single token e.g. "==" or ">=".
1079  * ADDR_IP6:    An IPv6 address.
1080  *
1081  * ADDR_AT:	An AppleTalk Phase II address. A sequence of two numbers
1082  *		separated by a dot.
1083  *
1084  * The current token is maintained in "token" and and its
1085  * type in "tokentype".  If tokentype is NUMBER then the
1086  * value is held in "tokenval".
1087  */
1088 
1089 static const char *namechars =
1090 	"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-.";
1091 static const char *numchars = "0123456789abcdefABCDEFXx:.";
1092 
1093 void
1094 next()
1095 {
1096 	static int savechar;
1097 	char *p;
1098 	int size, size1;
1099 	int base, colons, dots, alphas, double_colon;
1100 
1101 	colons = 0;
1102 	double_colon = 0;
1103 
1104 	if (*tkp == '\0') {
1105 		token = tkp;
1106 		*tkp = savechar;
1107 	}
1108 
1109 	sav_tkp = tkp;
1110 
1111 	while (isspace(*tkp)) tkp++;
1112 	token = tkp;
1113 	if (*token == '\0') {
1114 		tokentype = EOL;
1115 		return;
1116 	}
1117 
1118 	/* A token containing ':' cannot be ALPHA type */
1119 	tkp = token + strspn(token, numchars);
1120 	for (p = token; p < tkp; p++) {
1121 		if (*p == ':') {
1122 			colons++;
1123 			if (*(p+1) == ':')
1124 				double_colon++;
1125 		}
1126 	}
1127 
1128 	tkp = token;
1129 	if (isalpha(*tkp) && !colons) {
1130 		tokentype = ALPHA;
1131 		tkp += strspn(tkp, namechars);
1132 		if (*tkp == '[') {
1133 			tokentype = FIELD;
1134 			*tkp++ = '\0';
1135 		}
1136 	} else
1137 
1138 	/*
1139 	 * RFC1123 states that host names may now start with digits. Need
1140 	 * to change parser to account for this. Also, need to distinguish
1141 	 * between 1.2.3.4 and 1.2.3.a where the first case is an IP address
1142 	 * and the second is a domain name. 333aaa needs to be distinguished
1143 	 * from 0x333aaa. The first is a host name and the second is a number.
1144 	 *
1145 	 * The (colons > 1) conditional differentiates between ethernet
1146 	 * and IPv6 addresses, and an expression of the form base[expr:size],
1147 	 * which can only contain one ':' character.
1148 	 */
1149 	if (isdigit(*tkp) || colons > 1) {
1150 		tkp = token + strspn(token, numchars);
1151 		dots = alphas = 0;
1152 		for (p = token; p < tkp; p++) {
1153 			if (*p == '.')
1154 				dots++;
1155 			else if (isalpha(*p))
1156 				alphas = 1;
1157 		}
1158 		if (colons > 1) {
1159 			if (colons == 5 && double_colon == 0) {
1160 				tokentype = ADDR_ETHER;
1161 			} else {
1162 				tokentype = ADDR_IP6;
1163 			}
1164 		} else if (dots) {
1165 			size = tkp - token;
1166 			size1 = strspn(token, "0123456789.");
1167 			if (dots == 1 && size == size1) {
1168 				tokentype = ADDR_AT;
1169 			} else
1170 				if (dots != 3 || size != size1) {
1171 					tokentype = ALPHA;
1172 					if (*tkp != '\0' && !isspace(*tkp)) {
1173 						tkp += strspn(tkp, namechars);
1174 						if (*tkp == '[') {
1175 							tokentype = FIELD;
1176 							*tkp++ = '\0';
1177 						}
1178 					}
1179 				} else
1180 					tokentype = ADDR_IP;
1181 		} else if (token + strspn(token, namechars) <= tkp) {
1182 			/*
1183 			 * With the above check, if there are more
1184 			 * characters after the last digit, assume
1185 			 * that it is not a number.
1186 			 */
1187 			tokentype = NUMBER;
1188 			p = tkp;
1189 			tkp = token;
1190 			base = 10;
1191 			if (*tkp == '0') {
1192 				base = 8;
1193 				tkp++;
1194 				if (*tkp == 'x' || *tkp == 'X')
1195 					base = 16;
1196 			}
1197 			if ((base == 10 || base == 8) && alphas) {
1198 				tokentype = ALPHA;
1199 				tkp = p;
1200 			} else if (base == 16) {
1201 				size = 2 + strspn(token+2,
1202 					"0123456789abcdefABCDEF");
1203 				size1 = p - token;
1204 				if (size != size1) {
1205 					tokentype = ALPHA;
1206 					tkp = p;
1207 				} else
1208 				/*
1209 				 * handles the case of 0x so an error message
1210 				 * is not printed. Treats 0x as 0.
1211 				 */
1212 				if (size == 2) {
1213 					tokenval = 0;
1214 					tkp = token +2;
1215 				} else {
1216 					tokenval = strtoul(token, &tkp, base);
1217 				}
1218 			} else {
1219 				tokenval = strtoul(token, &tkp, base);
1220 			}
1221 		} else {
1222 			tokentype = ALPHA;
1223 			tkp += strspn(tkp, namechars);
1224 			if (*tkp == '[') {
1225 				tokentype = FIELD;
1226 				*tkp++ = '\0';
1227 			}
1228 		}
1229 	} else {
1230 		tokentype = SPECIAL;
1231 		tkp++;
1232 		if ((*token == '=' && *tkp == '=') ||
1233 		    (*token == '>' && *tkp == '=') ||
1234 		    (*token == '<' && *tkp == '=') ||
1235 		    (*token == '!' && *tkp == '='))
1236 				tkp++;
1237 	}
1238 
1239 	savechar = *tkp;
1240 	*tkp = '\0';
1241 }
1242 
1243 static struct match_type {
1244 	char		*m_name;
1245 	int		m_offset;
1246 	int		m_size;
1247 	int		m_value;
1248 	int		m_depend;
1249 	enum optype	m_optype;
1250 } match_types[] = {
1251 	/*
1252 	 * Table initialized assuming Ethernet data link headers.
1253 	 */
1254 	"ip",		12, 2, ETHERTYPE_IP,	-1,	OP_OFFSET_ZERO,
1255 	"ip6",		12, 2, ETHERTYPE_IPV6,	-1,	OP_OFFSET_ZERO,
1256 	"arp",		12, 2, ETHERTYPE_ARP,	-1,	OP_OFFSET_ZERO,
1257 	"rarp",		12, 2, ETHERTYPE_REVARP, -1,	OP_OFFSET_ZERO,
1258 	"pppoed",	12, 2, ETHERTYPE_PPPOED, -1,	OP_OFFSET_ZERO,
1259 	"pppoes",	12, 2, ETHERTYPE_PPPOES, -1,	OP_OFFSET_ZERO,
1260 	"tcp",		9, 1, IPPROTO_TCP,	0,	OP_OFFSET_LINK,
1261 	"tcp",		6, 1, IPPROTO_TCP,	1,	OP_OFFSET_LINK,
1262 	"udp",		9, 1, IPPROTO_UDP,	0,	OP_OFFSET_LINK,
1263 	"udp",		6, 1, IPPROTO_UDP,	1,	OP_OFFSET_LINK,
1264 	"icmp",		9, 1, IPPROTO_ICMP,	0,	OP_OFFSET_LINK,
1265 	"icmp6",	6, 1, IPPROTO_ICMPV6,	1,	OP_OFFSET_LINK,
1266 	"ospf",		9, 1, IPPROTO_OSPF,	0,	OP_OFFSET_LINK,
1267 	"ospf",		6, 1, IPPROTO_OSPF,	1,	OP_OFFSET_LINK,
1268 	"ip-in-ip",	9, 1, IPPROTO_ENCAP,	0,	OP_OFFSET_LINK,
1269 	"esp",		9, 1, IPPROTO_ESP,	0,	OP_OFFSET_LINK,
1270 	"esp",		6, 1, IPPROTO_ESP,	1,	OP_OFFSET_LINK,
1271 	"ah",		9, 1, IPPROTO_AH,	0,	OP_OFFSET_LINK,
1272 	"ah",		6, 1, IPPROTO_AH,	1,	OP_OFFSET_LINK,
1273 	"sctp",		9, 1, IPPROTO_SCTP,	0,	OP_OFFSET_LINK,
1274 	"sctp",		6, 1, IPPROTO_SCTP,	1,	OP_OFFSET_LINK,
1275 	0,		0, 0, 0,		0,	0
1276 };
1277 
1278 static void
1279 generate_check(struct match_type *mtp)
1280 {
1281 	int	offset;
1282 
1283 	/*
1284 	 * Note: this code assumes the above dependencies are
1285 	 * not cyclic.  This *should* always be true.
1286 	 */
1287 	if (mtp->m_depend != -1)
1288 		generate_check(&match_types[mtp->m_depend]);
1289 
1290 	offset = mtp->m_offset;
1291 	if (mtp->m_optype == OP_OFFSET_ZERO) {
1292 
1293 		/*
1294 		 * The table is filled with ethernet offsets.  Here we
1295 		 * fudge the value based on what know about the
1296 		 * interface.  It is okay to do this because we are
1297 		 * checking what we believe to be an IP/ARP/RARP
1298 		 * packet, and we know those are carried in LLC-SNAP
1299 		 * headers on FDDI.  We assume that it's unlikely
1300 		 * another kind of packet, with a shorter FDDI header
1301 		 * will happen to match the filter.
1302 		 *
1303 		 *		Ether	FDDI	IPoIB
1304 		 *  edst addr	0	1	none
1305 		 *  esrc addr	6	7	none
1306 		 *  ethertype	12	19	0
1307 		 *
1308 		 * XXX token ring?
1309 		 */
1310 		if (interface->mac_type == DL_FDDI) {
1311 			if (offset < 12)
1312 				offset++;
1313 			else if (offset == 12)
1314 				offset = 19;
1315 		} else if (interface->mac_type == DL_IB) {
1316 			offset = 0;
1317 		}
1318 	}
1319 
1320 	if (mtp->m_optype != OP_OFFSET_ZERO) {
1321 		emitop(mtp->m_optype);
1322 		load_value(offset, mtp->m_size);
1323 		load_const(mtp->m_value);
1324 		emitop(OP_OFFSET_POP);
1325 	} else {
1326 		load_value(offset, mtp->m_size);
1327 		load_const(mtp->m_value);
1328 	}
1329 
1330 	emitop(OP_EQ);
1331 
1332 	if (mtp->m_depend != -1)
1333 		emitop(OP_AND);
1334 }
1335 
1336 /*
1337  * Generate code based on the keyword argument.
1338  * This word is looked up in the match_types table
1339  * and checks a field within the packet for a given
1340  * value e.g. ether or ip type field.  The match
1341  * can also have a dependency on another entry e.g.
1342  * "tcp" requires that the packet also be "ip".
1343  */
1344 static int
1345 comparison(char *s)
1346 {
1347 	unsigned int	i, n_checks = 0;
1348 
1349 	for (i = 0; match_types[i].m_name != NULL; i++) {
1350 
1351 		if (strcmp(s, match_types[i].m_name) != 0)
1352 			continue;
1353 
1354 		n_checks++;
1355 		generate_check(&match_types[i]);
1356 		if (n_checks > 1)
1357 			emitop(OP_OR);
1358 	}
1359 
1360 	return (n_checks > 0);
1361 }
1362 
1363 enum direction { ANY, TO, FROM };
1364 enum direction dir;
1365 
1366 /*
1367  * Generate code to match an IP address.  The address
1368  * may be supplied either as a hostname or in dotted format.
1369  * For source packets both the IP source address and ARP
1370  * src are checked.
1371  * Note: we don't check packet type here - whether IP or ARP.
1372  * It's possible that we'll do an improper match.
1373  */
1374 static void
1375 ipaddr_match(enum direction which, char *hostname, int inet_type)
1376 {
1377 	bool_t found_host;
1378 	int m = 0, n = 0;
1379 	uint_t *addr4ptr;
1380 	uint_t addr4;
1381 	struct in6_addr *addr6ptr;
1382 	int h_addr_index;
1383 	struct hostent *hp = NULL;
1384 	int error_num = 0;
1385 	boolean_t freehp = B_FALSE;
1386 	boolean_t first = B_TRUE;
1387 
1388 	/*
1389 	 * The addr4offset and addr6offset variables simplify the code which
1390 	 * generates the address comparison filter.  With these two variables,
1391 	 * duplicate code need not exist for the TO and FROM case.
1392 	 * A value of -1 describes the ANY case (TO and FROM).
1393 	 */
1394 	int addr4offset;
1395 	int addr6offset;
1396 
1397 	found_host = 0;
1398 
1399 	if (tokentype == ADDR_IP) {
1400 		hp = lgetipnodebyname(hostname, AF_INET,
1401 					0, &error_num);
1402 		if (hp == NULL) {
1403 			hp = getipnodebyname(hostname, AF_INET,
1404 							0, &error_num);
1405 			freehp = 1;
1406 		}
1407 		if (hp == NULL) {
1408 			if (error_num == TRY_AGAIN) {
1409 				pr_err("couldn't resolve %s (try again later)",
1410 				    hostname);
1411 			} else {
1412 				pr_err("couldn't resolve %s", hostname);
1413 			}
1414 		}
1415 		inet_type = IPV4_ONLY;
1416 	} else if (tokentype == ADDR_IP6) {
1417 		hp = lgetipnodebyname(hostname, AF_INET6,
1418 					0, &error_num);
1419 		if (hp == NULL) {
1420 			hp = getipnodebyname(hostname, AF_INET6,
1421 							0, &error_num);
1422 			freehp = 1;
1423 		}
1424 		if (hp == NULL) {
1425 			if (error_num == TRY_AGAIN) {
1426 				pr_err("couldn't resolve %s (try again later)",
1427 				    hostname);
1428 			} else {
1429 				pr_err("couldn't resolve %s", hostname);
1430 			}
1431 		}
1432 		inet_type = IPV6_ONLY;
1433 	} else {
1434 		/* Some hostname i.e. tokentype is ALPHA */
1435 		switch (inet_type) {
1436 		case IPV4_ONLY:
1437 			/* Only IPv4 address is needed */
1438 			hp = lgetipnodebyname(hostname, AF_INET,
1439 						0, &error_num);
1440 			if (hp == NULL) {
1441 				hp = getipnodebyname(hostname, AF_INET,
1442 								0, &error_num);
1443 				freehp = 1;
1444 			}
1445 			if (hp != NULL) {
1446 				found_host = 1;
1447 			}
1448 			break;
1449 		case IPV6_ONLY:
1450 			/* Only IPv6 address is needed */
1451 			hp = lgetipnodebyname(hostname, AF_INET6,
1452 						0, &error_num);
1453 			if (hp == NULL) {
1454 				hp = getipnodebyname(hostname, AF_INET6,
1455 								0, &error_num);
1456 				freehp = 1;
1457 			}
1458 			if (hp != NULL) {
1459 				found_host = 1;
1460 			}
1461 			break;
1462 		case IPV4_AND_IPV6:
1463 			/* Both IPv4 and IPv6 are needed */
1464 			hp = lgetipnodebyname(hostname, AF_INET6,
1465 					AI_ALL | AI_V4MAPPED, &error_num);
1466 			if (hp == NULL) {
1467 				hp = getipnodebyname(hostname, AF_INET6,
1468 					AI_ALL | AI_V4MAPPED, &error_num);
1469 				freehp = 1;
1470 			}
1471 			if (hp != NULL) {
1472 				found_host = 1;
1473 			}
1474 			break;
1475 		default:
1476 			found_host = 0;
1477 		}
1478 
1479 		if (!found_host) {
1480 			if (error_num == TRY_AGAIN) {
1481 				pr_err("could not resolve %s (try again later)",
1482 				    hostname);
1483 			} else {
1484 				pr_err("could not resolve %s", hostname);
1485 			}
1486 		}
1487 	}
1488 
1489 	switch (which) {
1490 	case TO:
1491 		addr4offset = IPV4_DSTADDR_OFFSET;
1492 		addr6offset = IPV6_DSTADDR_OFFSET;
1493 		break;
1494 	case FROM:
1495 		addr4offset = IPV4_SRCADDR_OFFSET;
1496 		addr6offset = IPV6_SRCADDR_OFFSET;
1497 		break;
1498 	case ANY:
1499 		addr4offset = -1;
1500 		addr6offset = -1;
1501 		break;
1502 	}
1503 
1504 	/*
1505 	 * The code below generates the filter.
1506 	 */
1507 	if (hp != NULL && hp->h_addrtype == AF_INET) {
1508 		ethertype_match(ETHERTYPE_IP);
1509 		emitop(OP_BRFL);
1510 		n = chain(n);
1511 		emitop(OP_OFFSET_LINK);
1512 		h_addr_index = 0;
1513 		addr4ptr = (uint_t *)hp->h_addr_list[h_addr_index];
1514 		while (addr4ptr != NULL) {
1515 			if (addr4offset == -1) {
1516 				compare_addr_v4(IPV4_SRCADDR_OFFSET, 4,
1517 				    *addr4ptr);
1518 				emitop(OP_BRTR);
1519 				m = chain(m);
1520 				compare_addr_v4(IPV4_DSTADDR_OFFSET, 4,
1521 				    *addr4ptr);
1522 			} else {
1523 				compare_addr_v4(addr4offset, 4, *addr4ptr);
1524 			}
1525 			addr4ptr = (uint_t *)hp->h_addr_list[++h_addr_index];
1526 			if (addr4ptr != NULL) {
1527 				emitop(OP_BRTR);
1528 				m = chain(m);
1529 			}
1530 		}
1531 		if (m != 0) {
1532 			resolve_chain(m);
1533 		}
1534 		emitop(OP_OFFSET_POP);
1535 		resolve_chain(n);
1536 	} else {
1537 		/* first pass: IPv4 addresses */
1538 		h_addr_index = 0;
1539 		addr6ptr = (struct in6_addr *)hp->h_addr_list[h_addr_index];
1540 		first = B_TRUE;
1541 		while (addr6ptr != NULL) {
1542 			if (IN6_IS_ADDR_V4MAPPED(addr6ptr)) {
1543 				if (first) {
1544 					ethertype_match(ETHERTYPE_IP);
1545 					emitop(OP_BRFL);
1546 					n = chain(n);
1547 					emitop(OP_OFFSET_LINK);
1548 					first = B_FALSE;
1549 				} else {
1550 					emitop(OP_BRTR);
1551 					m = chain(m);
1552 				}
1553 				IN6_V4MAPPED_TO_INADDR(addr6ptr,
1554 				    (struct in_addr *)&addr4);
1555 				if (addr4offset == -1) {
1556 					compare_addr_v4(IPV4_SRCADDR_OFFSET, 4,
1557 					    addr4);
1558 					emitop(OP_BRTR);
1559 					m = chain(m);
1560 					compare_addr_v4(IPV4_DSTADDR_OFFSET, 4,
1561 					    addr4);
1562 				} else {
1563 					compare_addr_v4(addr4offset, 4, addr4);
1564 				}
1565 			}
1566 			addr6ptr = (struct in6_addr *)
1567 			    hp->h_addr_list[++h_addr_index];
1568 		}
1569 		/* second pass: IPv6 addresses */
1570 		h_addr_index = 0;
1571 		addr6ptr = (struct in6_addr *)hp->h_addr_list[h_addr_index];
1572 		first = B_TRUE;
1573 		while (addr6ptr != NULL) {
1574 			if (!IN6_IS_ADDR_V4MAPPED(addr6ptr)) {
1575 				if (first) {
1576 					/*
1577 					 * bypass check for IPv6 addresses
1578 					 * when we have an IPv4 packet
1579 					 */
1580 					if (n != 0) {
1581 						emitop(OP_BRTR);
1582 						m = chain(m);
1583 						emitop(OP_BRFL);
1584 						m = chain(m);
1585 						resolve_chain(n);
1586 						n = 0;
1587 					}
1588 					ethertype_match(ETHERTYPE_IPV6);
1589 					emitop(OP_BRFL);
1590 					n = chain(n);
1591 					emitop(OP_OFFSET_LINK);
1592 					first = B_FALSE;
1593 				} else {
1594 					emitop(OP_BRTR);
1595 					m = chain(m);
1596 				}
1597 				if (addr6offset == -1) {
1598 					compare_addr_v6(IPV6_SRCADDR_OFFSET,
1599 					    16, *addr6ptr);
1600 					emitop(OP_BRTR);
1601 					m = chain(m);
1602 					compare_addr_v6(IPV6_DSTADDR_OFFSET,
1603 					    16, *addr6ptr);
1604 				} else {
1605 					compare_addr_v6(addr6offset, 16,
1606 					    *addr6ptr);
1607 				}
1608 			}
1609 			addr6ptr = (struct in6_addr *)
1610 			    hp->h_addr_list[++h_addr_index];
1611 		}
1612 		if (m != 0) {
1613 			resolve_chain(m);
1614 		}
1615 		emitop(OP_OFFSET_POP);
1616 		resolve_chain(n);
1617 	}
1618 
1619 	/* only free struct hostent returned by getipnodebyname() */
1620 	if (freehp) {
1621 		freehostent(hp);
1622 	}
1623 }
1624 
1625 /*
1626  * Generate code to match an AppleTalk address.  The address
1627  * must be given as two numbers with a dot between
1628  *
1629  */
1630 static void
1631 ataddr_match(enum direction which, char *hostname)
1632 {
1633 	uint_t net;
1634 	uint_t node;
1635 	uint_t m, n;
1636 
1637 	sscanf(hostname, "%u.%u", &net, &node);
1638 
1639 	emitop(OP_OFFSET_LINK);
1640 	switch (which) {
1641 	case TO:
1642 		compare_value(AT_DST_NET_OFFSET, 2, net);
1643 		emitop(OP_BRFL);
1644 		m = chain(0);
1645 		compare_value(AT_DST_NODE_OFFSET, 1, node);
1646 		resolve_chain(m);
1647 		break;
1648 	case FROM:
1649 		compare_value(AT_SRC_NET_OFFSET, 2, net);
1650 		emitop(OP_BRFL);
1651 		m = chain(0);
1652 		compare_value(AT_SRC_NODE_OFFSET, 1, node);
1653 		resolve_chain(m);
1654 		break;
1655 	case ANY:
1656 		compare_value(AT_DST_NET_OFFSET, 2, net);
1657 		emitop(OP_BRFL);
1658 		m = chain(0);
1659 		compare_value(AT_DST_NODE_OFFSET, 1, node);
1660 		resolve_chain(m);
1661 		emitop(OP_BRTR);
1662 		n = chain(0);
1663 		compare_value(AT_SRC_NET_OFFSET, 2, net);
1664 		emitop(OP_BRFL);
1665 		m = chain(0);
1666 		compare_value(AT_SRC_NODE_OFFSET, 1, node);
1667 		resolve_chain(m);
1668 		resolve_chain(n);
1669 		break;
1670 	}
1671 	emitop(OP_OFFSET_POP);
1672 }
1673 
1674 /*
1675  * Compare ethernet addresses. The address may
1676  * be provided either as a hostname or as a
1677  * 6 octet colon-separated address.
1678  */
1679 static void
1680 etheraddr_match(enum direction which, char *hostname)
1681 {
1682 	uint_t addr;
1683 	ushort_t *addrp;
1684 	int to_offset, from_offset;
1685 	struct ether_addr e, *ep = NULL;
1686 	int m;
1687 
1688 	/*
1689 	 * First, check the interface type for whether src/dest address
1690 	 * is determinable; if not, retreat early.
1691 	 */
1692 	switch (interface->mac_type) {
1693 	case DL_ETHER:
1694 		from_offset = ETHERADDRL;
1695 		to_offset = 0;
1696 		break;
1697 
1698 	case DL_IB:
1699 		/*
1700 		 * If an ethernet address is attempted to be used
1701 		 * on an IPoIB interface, flag error. Link address
1702 		 * based filtering is unsupported on IPoIB, so there
1703 		 * is no ipibaddr_match() or parsing support for IPoIB
1704 		 * 20 byte link addresses.
1705 		 */
1706 		pr_err("filter option unsupported on media");
1707 		break;
1708 
1709 	case DL_FDDI:
1710 		from_offset = 7;
1711 		to_offset = 1;
1712 		break;
1713 
1714 	default:
1715 		/*
1716 		 * Where do we find "ether" address for FDDI & TR?
1717 		 * XXX can improve?  ~sparker
1718 		 */
1719 		load_const(1);
1720 		return;
1721 	}
1722 
1723 	if (isxdigit(*hostname))
1724 		ep = ether_aton(hostname);
1725 	if (ep == NULL) {
1726 		if (ether_hostton(hostname, &e))
1727 			if (!arp_for_ether(hostname, &e))
1728 				pr_err("cannot obtain ether addr for %s",
1729 					hostname);
1730 		ep = &e;
1731 	}
1732 	memcpy(&addr, (ushort_t *)ep, 4);
1733 	addrp = (ushort_t *)ep + 2;
1734 
1735 	switch (which) {
1736 	case TO:
1737 		compare_value(to_offset, 4, ntohl(addr));
1738 		emitop(OP_BRFL);
1739 		m = chain(0);
1740 		compare_value(to_offset + 4, 2, ntohs(*addrp));
1741 		resolve_chain(m);
1742 		break;
1743 	case FROM:
1744 		compare_value(from_offset, 4, ntohl(addr));
1745 		emitop(OP_BRFL);
1746 		m = chain(0);
1747 		compare_value(from_offset + 4, 2, ntohs(*addrp));
1748 		resolve_chain(m);
1749 		break;
1750 	case ANY:
1751 		compare_value(to_offset, 4, ntohl(addr));
1752 		compare_value(to_offset + 4, 2, ntohs(*addrp));
1753 		emitop(OP_AND);
1754 		emitop(OP_BRTR);
1755 		m = chain(0);
1756 
1757 		compare_value(from_offset, 4, ntohl(addr));
1758 		compare_value(from_offset + 4, 2, ntohs(*addrp));
1759 		emitop(OP_AND);
1760 		resolve_chain(m);
1761 		break;
1762 	}
1763 }
1764 
1765 static void
1766 ethertype_match(int val)
1767 {
1768 	int	m;
1769 	int	ether_offset;
1770 
1771 	switch (interface->mac_type) {
1772 	case DL_ETHER:
1773 		ether_offset = 12;
1774 		break;
1775 
1776 	case DL_IB:
1777 		ether_offset = 0;
1778 		break;
1779 
1780 	case DL_FDDI:
1781 		/* XXX Okay to assume LLC SNAP? */
1782 		ether_offset = 19;
1783 		break;
1784 
1785 	default:
1786 		load_const(1);	/* Assume a match */
1787 		return;
1788 	}
1789 	compare_value(ether_offset, 2, val); /* XXX.sparker */
1790 }
1791 
1792 /*
1793  * Match a network address.  The host part
1794  * is masked out.  The network address may
1795  * be supplied either as a netname or in
1796  * IP dotted format.  The mask to be used
1797  * for the comparison is assumed from the
1798  * address format (see comment below).
1799  */
1800 static void
1801 netaddr_match(enum direction which, char *netname)
1802 {
1803 	uint_t addr;
1804 	uint_t mask = 0xff000000;
1805 	uint_t m;
1806 	struct netent *np;
1807 
1808 	if (isdigit(*netname)) {
1809 		addr = inet_network(netname);
1810 	} else {
1811 		np = getnetbyname(netname);
1812 		if (np == NULL)
1813 			pr_err("net %s not known", netname);
1814 		addr = np->n_net;
1815 	}
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