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