xref: /illumos-gate/usr/src/cmd/ipf/tools/ipfcomp.c (revision 34ef97d0)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * Copyright (C) 1993-2001 by Darren Reed.
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * See the IPFILTER.LICENCE file for details on licencing.
5*34ef97d0Sjojemann  *
6*34ef97d0Sjojemann  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
7*34ef97d0Sjojemann  * Use is subject to license terms.
87c478bd9Sstevel@tonic-gate  */
9*34ef97d0Sjojemann 
10*34ef97d0Sjojemann #pragma ident	"%Z%%M%	%I%	%E% SMI"
11*34ef97d0Sjojemann 
127c478bd9Sstevel@tonic-gate #if !defined(lint)
137c478bd9Sstevel@tonic-gate static const char sccsid[] = "@(#)ip_fil.c	2.41 6/5/96 (C) 1993-2000 Darren Reed";
14ab25eeb5Syz static const char rcsid[] = "@(#)$Id: ipfcomp.c,v 1.24.2.2 2004/04/28 10:34:44 darrenr Exp $";
157c478bd9Sstevel@tonic-gate #endif
167c478bd9Sstevel@tonic-gate 
177c478bd9Sstevel@tonic-gate #include "ipf.h"
187c478bd9Sstevel@tonic-gate 
197c478bd9Sstevel@tonic-gate 
207c478bd9Sstevel@tonic-gate typedef struct {
217c478bd9Sstevel@tonic-gate 	int c;
227c478bd9Sstevel@tonic-gate 	int e;
237c478bd9Sstevel@tonic-gate 	int n;
247c478bd9Sstevel@tonic-gate 	int p;
257c478bd9Sstevel@tonic-gate 	int s;
267c478bd9Sstevel@tonic-gate } mc_t;
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate static char *portcmp[] = { "*", "==", "!=", "<", ">", "<=", ">=", "**", "***" };
307c478bd9Sstevel@tonic-gate static int count = 0;
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate int intcmp __P((const void *, const void *));
337c478bd9Sstevel@tonic-gate static void indent __P((FILE *, int));
347c478bd9Sstevel@tonic-gate static void printeq __P((FILE *, char *, int, int, int));
357c478bd9Sstevel@tonic-gate static void printipeq __P((FILE *, char *, int, int, int));
367c478bd9Sstevel@tonic-gate static void addrule __P((FILE *, frentry_t *));
377c478bd9Sstevel@tonic-gate static void printhooks __P((FILE *, int, int, frgroup_t *));
387c478bd9Sstevel@tonic-gate static void emitheader __P((frgroup_t *, u_int, u_int));
397c478bd9Sstevel@tonic-gate static void emitGroup __P((int, int, void *, frentry_t *, char *,
407c478bd9Sstevel@tonic-gate 			   u_int, u_int));
417c478bd9Sstevel@tonic-gate static void emittail __P((void));
427c478bd9Sstevel@tonic-gate static void printCgroup __P((int, frentry_t *, mc_t *, char *));
437c478bd9Sstevel@tonic-gate 
447c478bd9Sstevel@tonic-gate #define	FRC_IFN	0
457c478bd9Sstevel@tonic-gate #define	FRC_V	1
467c478bd9Sstevel@tonic-gate #define	FRC_P	2
477c478bd9Sstevel@tonic-gate #define	FRC_FL	3
487c478bd9Sstevel@tonic-gate #define	FRC_TOS	4
497c478bd9Sstevel@tonic-gate #define	FRC_TTL	5
507c478bd9Sstevel@tonic-gate #define	FRC_SRC	6
517c478bd9Sstevel@tonic-gate #define	FRC_DST	7
527c478bd9Sstevel@tonic-gate #define	FRC_TCP	8
537c478bd9Sstevel@tonic-gate #define	FRC_SP	9
547c478bd9Sstevel@tonic-gate #define	FRC_DP	10
557c478bd9Sstevel@tonic-gate #define	FRC_OPT	11
567c478bd9Sstevel@tonic-gate #define	FRC_SEC	12
577c478bd9Sstevel@tonic-gate #define	FRC_ATH	13
587c478bd9Sstevel@tonic-gate #define	FRC_ICT	14
597c478bd9Sstevel@tonic-gate #define	FRC_ICC	15
607c478bd9Sstevel@tonic-gate #define	FRC_MAX	16
617c478bd9Sstevel@tonic-gate 
627c478bd9Sstevel@tonic-gate 
637c478bd9Sstevel@tonic-gate static	FILE	*cfile = NULL;
647c478bd9Sstevel@tonic-gate 
657c478bd9Sstevel@tonic-gate /*
667c478bd9Sstevel@tonic-gate  * This is called once per filter rule being loaded to emit data structures
677c478bd9Sstevel@tonic-gate  * required.
687c478bd9Sstevel@tonic-gate  */
697c478bd9Sstevel@tonic-gate void printc(fr)
707c478bd9Sstevel@tonic-gate frentry_t *fr;
717c478bd9Sstevel@tonic-gate {
727c478bd9Sstevel@tonic-gate 	fripf_t *ipf;
737c478bd9Sstevel@tonic-gate 	u_long *ulp;
747c478bd9Sstevel@tonic-gate 	char *and;
757c478bd9Sstevel@tonic-gate 	FILE *fp;
767c478bd9Sstevel@tonic-gate 	int i;
777c478bd9Sstevel@tonic-gate 
787c478bd9Sstevel@tonic-gate 	if (fr->fr_v != 4)
797c478bd9Sstevel@tonic-gate 		return;
807c478bd9Sstevel@tonic-gate 	if ((fr->fr_type != FR_T_IPF) && (fr->fr_type != FR_T_NONE))
817c478bd9Sstevel@tonic-gate 		return;
827c478bd9Sstevel@tonic-gate 	if ((fr->fr_type == FR_T_IPF) &&
837c478bd9Sstevel@tonic-gate 	    ((fr->fr_datype != FRI_NORMAL) || (fr->fr_satype != FRI_NORMAL)))
847c478bd9Sstevel@tonic-gate 		return;
857c478bd9Sstevel@tonic-gate 	ipf = fr->fr_ipf;
867c478bd9Sstevel@tonic-gate 
877c478bd9Sstevel@tonic-gate 	if (cfile == NULL)
887c478bd9Sstevel@tonic-gate 		cfile = fopen("ip_rules.c", "w");
897c478bd9Sstevel@tonic-gate 	if (cfile == NULL)
907c478bd9Sstevel@tonic-gate 		return;
917c478bd9Sstevel@tonic-gate 	fp = cfile;
927c478bd9Sstevel@tonic-gate 	if (count == 0) {
937c478bd9Sstevel@tonic-gate 		fprintf(fp, "/*\n");
947c478bd9Sstevel@tonic-gate  		fprintf(fp, "* Copyright (C) 1993-2000 by Darren Reed.\n");
957c478bd9Sstevel@tonic-gate  		fprintf(fp, "*\n");
967c478bd9Sstevel@tonic-gate  		fprintf(fp, "* Redistribution and use in source and binary forms are permitted\n");
977c478bd9Sstevel@tonic-gate  		fprintf(fp, "* provided that this notice is preserved and due credit is given\n");
987c478bd9Sstevel@tonic-gate  		fprintf(fp, "* to the original author and the contributors.\n");
997c478bd9Sstevel@tonic-gate  		fprintf(fp, "*/\n\n");
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate 		fprintf(fp, "#include <sys/types.h>\n");
1027c478bd9Sstevel@tonic-gate 		fprintf(fp, "#include <sys/time.h>\n");
1037c478bd9Sstevel@tonic-gate 		fprintf(fp, "#include <sys/socket.h>\n");
104ab25eeb5Syz 		fprintf(fp, "#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__sgi)\n");
105ab25eeb5Syz 		fprintf(fp, "# include <sys/systm.h>\n");
106ab25eeb5Syz 		fprintf(fp, "#endif\n");
1077c478bd9Sstevel@tonic-gate 		fprintf(fp, "#include <sys/errno.h>\n");
1087c478bd9Sstevel@tonic-gate 		fprintf(fp, "#include <sys/param.h>\n");
1097c478bd9Sstevel@tonic-gate 		fprintf(fp,
1107c478bd9Sstevel@tonic-gate "#if !defined(__SVR4) && !defined(__svr4__) && !defined(__hpux)\n");
1117c478bd9Sstevel@tonic-gate 		fprintf(fp, "# include <sys/mbuf.h>\n");
1127c478bd9Sstevel@tonic-gate 		fprintf(fp, "#endif\n");
1137c478bd9Sstevel@tonic-gate 		fprintf(fp,
1147c478bd9Sstevel@tonic-gate "#if defined(__FreeBSD__) && (__FreeBSD_version > 220000)\n");
1157c478bd9Sstevel@tonic-gate 		fprintf(fp, "# include <sys/sockio.h>\n");
1167c478bd9Sstevel@tonic-gate 		fprintf(fp, "#else\n");
1177c478bd9Sstevel@tonic-gate 		fprintf(fp, "# include <sys/ioctl.h>\n");
1187c478bd9Sstevel@tonic-gate 		fprintf(fp, "#endif /* FreeBSD */\n");
1197c478bd9Sstevel@tonic-gate 		fprintf(fp, "#include <net/if.h>\n");
1207c478bd9Sstevel@tonic-gate 		fprintf(fp, "#include <netinet/in.h>\n");
1217c478bd9Sstevel@tonic-gate 		fprintf(fp, "#include <netinet/in_systm.h>\n");
1227c478bd9Sstevel@tonic-gate 		fprintf(fp, "#include <netinet/ip.h>\n");
1237c478bd9Sstevel@tonic-gate 		fprintf(fp, "#include <netinet/tcp.h>\n");
124ab25eeb5Syz 		fprintf(fp, "#include \"netinet/ip_compat.h\"\n");
125ab25eeb5Syz 		fprintf(fp, "#include \"netinet/ip_fil.h\"\n\n");
126ab25eeb5Syz 		fprintf(fp, "#include \"netinet/ip_rules.h\"\n\n");
127ab25eeb5Syz 		fprintf(fp, "#ifndef _KERNEL\n");
128ab25eeb5Syz 		fprintf(fp, "# include <string.h>\n");
129ab25eeb5Syz 		fprintf(fp, "#endif /* _KERNEL */\n");
130ab25eeb5Syz 		fprintf(fp, "\n");
131ab25eeb5Syz 		fprintf(fp, "#ifdef IPFILTER_COMPILED\n");
1327c478bd9Sstevel@tonic-gate 	}
1337c478bd9Sstevel@tonic-gate 
1347c478bd9Sstevel@tonic-gate 	addrule(fp, fr);
1357c478bd9Sstevel@tonic-gate 	fr->fr_type |= FR_T_BUILTIN;
1367c478bd9Sstevel@tonic-gate 	and = "";
1377c478bd9Sstevel@tonic-gate 	fr->fr_ref = 1;
1387c478bd9Sstevel@tonic-gate 	i = sizeof(*fr);
1397c478bd9Sstevel@tonic-gate 	if (i & -(1 - sizeof(*ulp)))
1407c478bd9Sstevel@tonic-gate 		i += sizeof(u_long);
1417c478bd9Sstevel@tonic-gate 	for (i /= sizeof(u_long), ulp = (u_long *)fr; i > 0; i--) {
1427c478bd9Sstevel@tonic-gate 		fprintf(fp, "%s%#lx", and, *ulp++);
1437c478bd9Sstevel@tonic-gate 		and = ", ";
1447c478bd9Sstevel@tonic-gate 	}
1457c478bd9Sstevel@tonic-gate 	fprintf(fp, "\n};\n");
1467c478bd9Sstevel@tonic-gate 	fr->fr_type &= ~FR_T_BUILTIN;
1477c478bd9Sstevel@tonic-gate 
1487c478bd9Sstevel@tonic-gate 	count++;
1497c478bd9Sstevel@tonic-gate 
1507c478bd9Sstevel@tonic-gate 	fflush(fp);
1517c478bd9Sstevel@tonic-gate }
1527c478bd9Sstevel@tonic-gate 
1537c478bd9Sstevel@tonic-gate 
1547c478bd9Sstevel@tonic-gate static frgroup_t *groups = NULL;
1557c478bd9Sstevel@tonic-gate 
1567c478bd9Sstevel@tonic-gate 
1577c478bd9Sstevel@tonic-gate static void addrule(fp, fr)
1587c478bd9Sstevel@tonic-gate FILE *fp;
1597c478bd9Sstevel@tonic-gate frentry_t *fr;
1607c478bd9Sstevel@tonic-gate {
1617c478bd9Sstevel@tonic-gate 	frentry_t *f, **fpp;
1627c478bd9Sstevel@tonic-gate 	frgroup_t *g;
1637c478bd9Sstevel@tonic-gate 	u_long *ulp;
1647c478bd9Sstevel@tonic-gate 	char *and;
1657c478bd9Sstevel@tonic-gate 	int i;
1667c478bd9Sstevel@tonic-gate 
1677c478bd9Sstevel@tonic-gate 	f = (frentry_t *)malloc(sizeof(*f));
168*34ef97d0Sjojemann 	if (f == NULL) {
169*34ef97d0Sjojemann 		fprintf(stderr, "out of memory\n");
170*34ef97d0Sjojemann 		exit(1);
171*34ef97d0Sjojemann 	}
1727c478bd9Sstevel@tonic-gate 	bcopy((char *)fr, (char *)f, sizeof(*fr));
1737c478bd9Sstevel@tonic-gate 	if (fr->fr_ipf) {
1747c478bd9Sstevel@tonic-gate 		f->fr_ipf = (fripf_t *)malloc(sizeof(*f->fr_ipf));
175*34ef97d0Sjojemann 		if (f->fr_ipf == NULL) {
176*34ef97d0Sjojemann 			fprintf(stderr, "out of memory\n");
177*34ef97d0Sjojemann 			exit(1);
178*34ef97d0Sjojemann 		}
1797c478bd9Sstevel@tonic-gate 		bcopy((char *)fr->fr_ipf, (char *)f->fr_ipf,
1807c478bd9Sstevel@tonic-gate 		      sizeof(*fr->fr_ipf));
1817c478bd9Sstevel@tonic-gate 	}
1827c478bd9Sstevel@tonic-gate 
1837c478bd9Sstevel@tonic-gate 	f->fr_next = NULL;
1847c478bd9Sstevel@tonic-gate 	for (g = groups; g != NULL; g = g->fg_next)
1857c478bd9Sstevel@tonic-gate 		if ((strncmp(g->fg_name, f->fr_group, FR_GROUPLEN) == 0) &&
1867c478bd9Sstevel@tonic-gate 		    (g->fg_flags == (f->fr_flags & FR_INOUT)))
1877c478bd9Sstevel@tonic-gate 			break;
1887c478bd9Sstevel@tonic-gate 
1897c478bd9Sstevel@tonic-gate 	if (g == NULL) {
1907c478bd9Sstevel@tonic-gate 		g = (frgroup_t *)calloc(1, sizeof(*g));
191*34ef97d0Sjojemann 		if (g == NULL) {
192*34ef97d0Sjojemann 			fprintf(stderr, "out of memory\n");
193*34ef97d0Sjojemann 			exit(1);
194*34ef97d0Sjojemann 		}
1957c478bd9Sstevel@tonic-gate 		g->fg_next = groups;
1967c478bd9Sstevel@tonic-gate 		groups = g;
1977c478bd9Sstevel@tonic-gate 		g->fg_head = f;
1987c478bd9Sstevel@tonic-gate 		bcopy(f->fr_group, g->fg_name, FR_GROUPLEN);
1997c478bd9Sstevel@tonic-gate 		g->fg_ref = 0;
2007c478bd9Sstevel@tonic-gate 		g->fg_flags = f->fr_flags & FR_INOUT;
2017c478bd9Sstevel@tonic-gate 	}
2027c478bd9Sstevel@tonic-gate 
2037c478bd9Sstevel@tonic-gate 	for (fpp = &g->fg_start; *fpp != NULL; )
2047c478bd9Sstevel@tonic-gate 		fpp = &((*fpp)->fr_next);
2057c478bd9Sstevel@tonic-gate 	*fpp = f;
2067c478bd9Sstevel@tonic-gate 
2077c478bd9Sstevel@tonic-gate 	if (fr->fr_dsize > 0) {
2087c478bd9Sstevel@tonic-gate 		fprintf(fp, "\
2097c478bd9Sstevel@tonic-gate static u_long ipf%s_rule_data_%s_%u[] = {\n",
2107c478bd9Sstevel@tonic-gate 			f->fr_flags & FR_INQUE ? "in" : "out",
2117c478bd9Sstevel@tonic-gate 			g->fg_name, g->fg_ref);
2127c478bd9Sstevel@tonic-gate 		and = "";
2137c478bd9Sstevel@tonic-gate 		i = fr->fr_dsize;
2147c478bd9Sstevel@tonic-gate 		ulp = fr->fr_data;
2157c478bd9Sstevel@tonic-gate 		for (i /= sizeof(u_long); i > 0; i--) {
2167c478bd9Sstevel@tonic-gate 			fprintf(fp, "%s%#lx", and, *ulp++);
2177c478bd9Sstevel@tonic-gate 			and = ", ";
2187c478bd9Sstevel@tonic-gate 		}
2197c478bd9Sstevel@tonic-gate 		fprintf(fp, "\n};\n");
2207c478bd9Sstevel@tonic-gate 	}
2217c478bd9Sstevel@tonic-gate 
2227c478bd9Sstevel@tonic-gate 	fprintf(fp, "\nstatic u_long %s_rule_%s_%d[] = {\n",
2237c478bd9Sstevel@tonic-gate 		f->fr_flags & FR_INQUE ? "in" : "out", g->fg_name, g->fg_ref);
2247c478bd9Sstevel@tonic-gate 
2257c478bd9Sstevel@tonic-gate 	g->fg_ref++;
2267c478bd9Sstevel@tonic-gate 
2277c478bd9Sstevel@tonic-gate 	if (f->fr_grhead != 0) {
2287c478bd9Sstevel@tonic-gate 		for (g = groups; g != NULL; g = g->fg_next)
2297c478bd9Sstevel@tonic-gate 			if ((strncmp(g->fg_name, f->fr_grhead,
2307c478bd9Sstevel@tonic-gate 				     FR_GROUPLEN) == 0) &&
2317c478bd9Sstevel@tonic-gate 			    g->fg_flags == (f->fr_flags & FR_INOUT))
2327c478bd9Sstevel@tonic-gate 				break;
2337c478bd9Sstevel@tonic-gate 		if (g == NULL) {
2347c478bd9Sstevel@tonic-gate 			g = (frgroup_t *)calloc(1, sizeof(*g));
235*34ef97d0Sjojemann 			if (g == NULL) {
236*34ef97d0Sjojemann 				fprintf(stderr, "out of memory\n");
237*34ef97d0Sjojemann 				exit(1);
238*34ef97d0Sjojemann 			}
2397c478bd9Sstevel@tonic-gate 			g->fg_next = groups;
2407c478bd9Sstevel@tonic-gate 			groups = g;
2417c478bd9Sstevel@tonic-gate 			g->fg_head = f;
2427c478bd9Sstevel@tonic-gate 			bcopy(f->fr_grhead, g->fg_name, FR_GROUPLEN);
2437c478bd9Sstevel@tonic-gate 			g->fg_ref = 0;
2447c478bd9Sstevel@tonic-gate 			g->fg_flags = f->fr_flags & FR_INOUT;
2457c478bd9Sstevel@tonic-gate 		}
2467c478bd9Sstevel@tonic-gate 	}
2477c478bd9Sstevel@tonic-gate }
2487c478bd9Sstevel@tonic-gate 
2497c478bd9Sstevel@tonic-gate 
2507c478bd9Sstevel@tonic-gate int intcmp(c1, c2)
2517c478bd9Sstevel@tonic-gate const void *c1, *c2;
2527c478bd9Sstevel@tonic-gate {
2537c478bd9Sstevel@tonic-gate 	const mc_t *i1 = (const mc_t *)c1, *i2 = (const mc_t *)c2;
2547c478bd9Sstevel@tonic-gate 
2557c478bd9Sstevel@tonic-gate 	if (i1->n == i2->n) {
2567c478bd9Sstevel@tonic-gate 		return i1->c - i2->c;
2577c478bd9Sstevel@tonic-gate 	}
2587c478bd9Sstevel@tonic-gate 	return i2->n - i1->n;
2597c478bd9Sstevel@tonic-gate }
2607c478bd9Sstevel@tonic-gate 
2617c478bd9Sstevel@tonic-gate 
2627c478bd9Sstevel@tonic-gate static void indent(fp, in)
2637c478bd9Sstevel@tonic-gate FILE *fp;
2647c478bd9Sstevel@tonic-gate int in;
2657c478bd9Sstevel@tonic-gate {
2667c478bd9Sstevel@tonic-gate 	for (; in; in--)
2677c478bd9Sstevel@tonic-gate 		fputc('\t', fp);
2687c478bd9Sstevel@tonic-gate }
2697c478bd9Sstevel@tonic-gate 
2707c478bd9Sstevel@tonic-gate static void printeq(fp, var, m, max, v)
2717c478bd9Sstevel@tonic-gate FILE *fp;
2727c478bd9Sstevel@tonic-gate char *var;
2737c478bd9Sstevel@tonic-gate int m, max, v;
2747c478bd9Sstevel@tonic-gate {
2757c478bd9Sstevel@tonic-gate 	if (m == max)
2767c478bd9Sstevel@tonic-gate 		fprintf(fp, "%s == %#x) {\n", var, v);
2777c478bd9Sstevel@tonic-gate 	else
2787c478bd9Sstevel@tonic-gate 		fprintf(fp, "(%s & %#x) == %#x) {\n", var, m, v);
2797c478bd9Sstevel@tonic-gate }
2807c478bd9Sstevel@tonic-gate 
2817c478bd9Sstevel@tonic-gate /*
2827c478bd9Sstevel@tonic-gate  * Parameters: var - IP# being compared
2837c478bd9Sstevel@tonic-gate  *             fl - 0 for positive match, 1 for negative match
2847c478bd9Sstevel@tonic-gate  *             m - netmask
2857c478bd9Sstevel@tonic-gate  *             v - required address
2867c478bd9Sstevel@tonic-gate  */
2877c478bd9Sstevel@tonic-gate static void printipeq(fp, var, fl, m, v)
2887c478bd9Sstevel@tonic-gate FILE *fp;
2897c478bd9Sstevel@tonic-gate char *var;
2907c478bd9Sstevel@tonic-gate int fl, m, v;
2917c478bd9Sstevel@tonic-gate {
2927c478bd9Sstevel@tonic-gate 	if (m == 0xffffffff)
2937c478bd9Sstevel@tonic-gate 		fprintf(fp, "%s ", var);
2947c478bd9Sstevel@tonic-gate 	else
2957c478bd9Sstevel@tonic-gate 		fprintf(fp, "(%s & %#x) ", var, m);
2967c478bd9Sstevel@tonic-gate 	fprintf(fp, "%c", fl ? '!' : '=');
2977c478bd9Sstevel@tonic-gate 	fprintf(fp, "= %#x) {\n", v);
2987c478bd9Sstevel@tonic-gate }
2997c478bd9Sstevel@tonic-gate 
3007c478bd9Sstevel@tonic-gate 
3017c478bd9Sstevel@tonic-gate void emit(num, dir, v, fr)
3027c478bd9Sstevel@tonic-gate int num, dir;
3037c478bd9Sstevel@tonic-gate void *v;
3047c478bd9Sstevel@tonic-gate frentry_t *fr;
3057c478bd9Sstevel@tonic-gate {
3067c478bd9Sstevel@tonic-gate 	u_int incnt, outcnt;
3077c478bd9Sstevel@tonic-gate 	frgroup_t *g;
3087c478bd9Sstevel@tonic-gate 	frentry_t *f;
3097c478bd9Sstevel@tonic-gate 
3107c478bd9Sstevel@tonic-gate 	for (g = groups; g != NULL; g = g->fg_next) {
3117c478bd9Sstevel@tonic-gate 		if (dir == 0 || dir == -1) {
3127c478bd9Sstevel@tonic-gate 			if ((g->fg_flags & FR_INQUE) == 0)
3137c478bd9Sstevel@tonic-gate 				continue;
3147c478bd9Sstevel@tonic-gate 			for (incnt = 0, f = g->fg_start; f != NULL;
3157c478bd9Sstevel@tonic-gate 			     f = f->fr_next)
3167c478bd9Sstevel@tonic-gate 				incnt++;
3177c478bd9Sstevel@tonic-gate 			emitGroup(num, dir, v, fr, g->fg_name, incnt, 0);
3187c478bd9Sstevel@tonic-gate 		}
3197c478bd9Sstevel@tonic-gate 		if (dir == 1 || dir == -1) {
3207c478bd9Sstevel@tonic-gate 			if ((g->fg_flags & FR_OUTQUE) == 0)
3217c478bd9Sstevel@tonic-gate 				continue;
3227c478bd9Sstevel@tonic-gate 			for (outcnt = 0, f = g->fg_start; f != NULL;
3237c478bd9Sstevel@tonic-gate 			     f = f->fr_next)
3247c478bd9Sstevel@tonic-gate 				outcnt++;
3257c478bd9Sstevel@tonic-gate 			emitGroup(num, dir, v, fr, g->fg_name, 0, outcnt);
3267c478bd9Sstevel@tonic-gate 		}
3277c478bd9Sstevel@tonic-gate 	}
3287c478bd9Sstevel@tonic-gate 
3297c478bd9Sstevel@tonic-gate 	if (num == -1 && dir == -1) {
3307c478bd9Sstevel@tonic-gate 		for (g = groups; g != NULL; g = g->fg_next) {
3317c478bd9Sstevel@tonic-gate 			if ((g->fg_flags & FR_INQUE) != 0) {
3327c478bd9Sstevel@tonic-gate 				for (incnt = 0, f = g->fg_start; f != NULL;
3337c478bd9Sstevel@tonic-gate 				     f = f->fr_next)
3347c478bd9Sstevel@tonic-gate 					incnt++;
3357c478bd9Sstevel@tonic-gate 				if (incnt > 0)
3367c478bd9Sstevel@tonic-gate 					emitheader(g, incnt, 0);
3377c478bd9Sstevel@tonic-gate 			}
3387c478bd9Sstevel@tonic-gate 			if ((g->fg_flags & FR_OUTQUE) != 0) {
3397c478bd9Sstevel@tonic-gate 				for (outcnt = 0, f = g->fg_start; f != NULL;
3407c478bd9Sstevel@tonic-gate 				     f = f->fr_next)
3417c478bd9Sstevel@tonic-gate 					outcnt++;
3427c478bd9Sstevel@tonic-gate 				if (outcnt > 0)
3437c478bd9Sstevel@tonic-gate 					emitheader(g, 0, outcnt);
3447c478bd9Sstevel@tonic-gate 			}
3457c478bd9Sstevel@tonic-gate 		}
3467c478bd9Sstevel@tonic-gate 		emittail();
347ab25eeb5Syz 		fprintf(cfile, "#endif /* IPFILTER_COMPILED */\n");
3487c478bd9Sstevel@tonic-gate 	}
349ab25eeb5Syz 
3507c478bd9Sstevel@tonic-gate }
3517c478bd9Sstevel@tonic-gate 
3527c478bd9Sstevel@tonic-gate 
3537c478bd9Sstevel@tonic-gate static void emitheader(grp, incount, outcount)
3547c478bd9Sstevel@tonic-gate frgroup_t *grp;
3557c478bd9Sstevel@tonic-gate u_int incount, outcount;
3567c478bd9Sstevel@tonic-gate {
3577c478bd9Sstevel@tonic-gate 	static FILE *fph = NULL;
3587c478bd9Sstevel@tonic-gate 	frgroup_t *g;
3597c478bd9Sstevel@tonic-gate 
3607c478bd9Sstevel@tonic-gate 	if (fph == NULL) {
3617c478bd9Sstevel@tonic-gate 		fph = fopen("ip_rules.h", "w");
3627c478bd9Sstevel@tonic-gate 		if (fph == NULL)
3637c478bd9Sstevel@tonic-gate 			return;
3647c478bd9Sstevel@tonic-gate 
3657c478bd9Sstevel@tonic-gate 		fprintf(fph, "extern int ipfrule_add __P((void));\n");
3667c478bd9Sstevel@tonic-gate 		fprintf(fph, "extern int ipfrule_remove __P((void));\n");
3677c478bd9Sstevel@tonic-gate 	}
3687c478bd9Sstevel@tonic-gate 
3697c478bd9Sstevel@tonic-gate 	printhooks(cfile, incount, outcount, grp);
3707c478bd9Sstevel@tonic-gate 
3717c478bd9Sstevel@tonic-gate 	if (incount) {
3727c478bd9Sstevel@tonic-gate 		fprintf(fph, "\n\
3737c478bd9Sstevel@tonic-gate extern frentry_t *ipfrule_match_in_%s __P((fr_info_t *, u_32_t *));\n\
3747c478bd9Sstevel@tonic-gate extern frentry_t *ipf_rules_in_%s[%d];\n",
3757c478bd9Sstevel@tonic-gate 			grp->fg_name, grp->fg_name, incount);
3767c478bd9Sstevel@tonic-gate 
3777c478bd9Sstevel@tonic-gate 		for (g = groups; g != grp; g = g->fg_next)
3787c478bd9Sstevel@tonic-gate 			if ((strncmp(g->fg_name, grp->fg_name,
3797c478bd9Sstevel@tonic-gate 				     FR_GROUPLEN) == 0) &&
3807c478bd9Sstevel@tonic-gate 			    g->fg_flags == grp->fg_flags)
3817c478bd9Sstevel@tonic-gate 				break;
3827c478bd9Sstevel@tonic-gate 		if (g == grp) {
3837c478bd9Sstevel@tonic-gate 			fprintf(fph, "\n\
3847c478bd9Sstevel@tonic-gate extern int ipfrule_add_in_%s __P((void));\n\
3857c478bd9Sstevel@tonic-gate extern int ipfrule_remove_in_%s __P((void));\n", grp->fg_name, grp->fg_name);
3867c478bd9Sstevel@tonic-gate 		}
3877c478bd9Sstevel@tonic-gate 	}
3887c478bd9Sstevel@tonic-gate 	if (outcount) {
3897c478bd9Sstevel@tonic-gate 		fprintf(fph, "\n\
3907c478bd9Sstevel@tonic-gate extern frentry_t *ipfrule_match_out_%s __P((fr_info_t *, u_32_t *));\n\
3917c478bd9Sstevel@tonic-gate extern frentry_t *ipf_rules_out_%s[%d];\n",
3927c478bd9Sstevel@tonic-gate 			grp->fg_name, grp->fg_name, outcount);
3937c478bd9Sstevel@tonic-gate 
3947c478bd9Sstevel@tonic-gate 		for (g = groups; g != g; g = g->fg_next)
3957c478bd9Sstevel@tonic-gate 			if ((strncmp(g->fg_name, grp->fg_name,
3967c478bd9Sstevel@tonic-gate 				     FR_GROUPLEN) == 0) &&
3977c478bd9Sstevel@tonic-gate 			    g->fg_flags == grp->fg_flags)
3987c478bd9Sstevel@tonic-gate 				break;
3997c478bd9Sstevel@tonic-gate 		if (g == grp) {
4007c478bd9Sstevel@tonic-gate 			fprintf(fph, "\n\
4017c478bd9Sstevel@tonic-gate extern int ipfrule_add_out_%s __P((void));\n\
4027c478bd9Sstevel@tonic-gate extern int ipfrule_remove_out_%s __P((void));\n",
4037c478bd9Sstevel@tonic-gate 				grp->fg_name, grp->fg_name);
4047c478bd9Sstevel@tonic-gate 		}
4057c478bd9Sstevel@tonic-gate 	}
4067c478bd9Sstevel@tonic-gate }
4077c478bd9Sstevel@tonic-gate 
4087c478bd9Sstevel@tonic-gate static void emittail()
4097c478bd9Sstevel@tonic-gate {
4107c478bd9Sstevel@tonic-gate 	frgroup_t *g;
4117c478bd9Sstevel@tonic-gate 
4127c478bd9Sstevel@tonic-gate 	fprintf(cfile, "\n\
4137c478bd9Sstevel@tonic-gate int ipfrule_add()\n\
4147c478bd9Sstevel@tonic-gate {\n\
4157c478bd9Sstevel@tonic-gate 	int err;\n\
4167c478bd9Sstevel@tonic-gate \n");
4177c478bd9Sstevel@tonic-gate 	for (g = groups; g != NULL; g = g->fg_next)
4187c478bd9Sstevel@tonic-gate 		fprintf(cfile, "\
4197c478bd9Sstevel@tonic-gate 	err = ipfrule_add_%s_%s();\n\
4207c478bd9Sstevel@tonic-gate 	if (err != 0)\n\
4217c478bd9Sstevel@tonic-gate 		return err;\n",
4227c478bd9Sstevel@tonic-gate 			(g->fg_flags & FR_INQUE) ? "in" : "out", g->fg_name);
4237c478bd9Sstevel@tonic-gate 	fprintf(cfile, "\
4247c478bd9Sstevel@tonic-gate 	return 0;\n");
4257c478bd9Sstevel@tonic-gate 	fprintf(cfile, "}\n\
4267c478bd9Sstevel@tonic-gate \n");
4277c478bd9Sstevel@tonic-gate 
4287c478bd9Sstevel@tonic-gate 	fprintf(cfile, "\n\
4297c478bd9Sstevel@tonic-gate int ipfrule_remove()\n\
4307c478bd9Sstevel@tonic-gate {\n\
4317c478bd9Sstevel@tonic-gate 	int err;\n\
4327c478bd9Sstevel@tonic-gate \n");
4337c478bd9Sstevel@tonic-gate 	for (g = groups; g != NULL; g = g->fg_next)
4347c478bd9Sstevel@tonic-gate 		fprintf(cfile, "\
4357c478bd9Sstevel@tonic-gate 	err = ipfrule_remove_%s_%s();\n\
4367c478bd9Sstevel@tonic-gate 	if (err != 0)\n\
4377c478bd9Sstevel@tonic-gate 		return err;\n",
4387c478bd9Sstevel@tonic-gate 			(g->fg_flags & FR_INQUE) ? "in" : "out", g->fg_name);
4397c478bd9Sstevel@tonic-gate 	fprintf(cfile, "\
4407c478bd9Sstevel@tonic-gate 	return 0;\n");
4417c478bd9Sstevel@tonic-gate 	fprintf(cfile, "}\n");
4427c478bd9Sstevel@tonic-gate }
4437c478bd9Sstevel@tonic-gate 
4447c478bd9Sstevel@tonic-gate 
4457c478bd9Sstevel@tonic-gate static void emitGroup(num, dir, v, fr, group, incount, outcount)
4467c478bd9Sstevel@tonic-gate int num, dir;
4477c478bd9Sstevel@tonic-gate void *v;
4487c478bd9Sstevel@tonic-gate frentry_t *fr;
4497c478bd9Sstevel@tonic-gate char *group;
4507c478bd9Sstevel@tonic-gate u_int incount, outcount;
4517c478bd9Sstevel@tonic-gate {
4527c478bd9Sstevel@tonic-gate 	static FILE *fp = NULL;
4537c478bd9Sstevel@tonic-gate 	static int header[2] = { 0, 0 };
4547c478bd9Sstevel@tonic-gate 	static char egroup[FR_GROUPLEN] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
4557c478bd9Sstevel@tonic-gate 	static int openfunc = 0;
4567c478bd9Sstevel@tonic-gate 	static mc_t *n = NULL;
4577c478bd9Sstevel@tonic-gate 	static int sin = 0;
4587c478bd9Sstevel@tonic-gate 	frentry_t *f;
4597c478bd9Sstevel@tonic-gate 	frgroup_t *g;
4607c478bd9Sstevel@tonic-gate 	fripf_t *ipf;
4617c478bd9Sstevel@tonic-gate 	int i, in, j;
4627c478bd9Sstevel@tonic-gate 	mc_t *m = v;
4637c478bd9Sstevel@tonic-gate 
4647c478bd9Sstevel@tonic-gate 	if (fp == NULL)
4657c478bd9Sstevel@tonic-gate 		fp = cfile;
4667c478bd9Sstevel@tonic-gate 	if (fp == NULL)
4677c478bd9Sstevel@tonic-gate 		return;
4687c478bd9Sstevel@tonic-gate 	if (strncmp(egroup, group, FR_GROUPLEN)) {
4697c478bd9Sstevel@tonic-gate 		for (sin--; sin > 0; sin--) {
4707c478bd9Sstevel@tonic-gate 			indent(fp, sin);
4717c478bd9Sstevel@tonic-gate 			fprintf(fp, "}\n");
4727c478bd9Sstevel@tonic-gate 		}
4737c478bd9Sstevel@tonic-gate 		if (openfunc == 1) {
4747c478bd9Sstevel@tonic-gate 			fprintf(fp, "\treturn fr;\n}\n");
4757c478bd9Sstevel@tonic-gate 			openfunc = 0;
4767c478bd9Sstevel@tonic-gate 			if (n != NULL) {
4777c478bd9Sstevel@tonic-gate 				free(n);
4787c478bd9Sstevel@tonic-gate 				n = NULL;
4797c478bd9Sstevel@tonic-gate 			}
4807c478bd9Sstevel@tonic-gate 		}
4817c478bd9Sstevel@tonic-gate 		sin = 0;
4827c478bd9Sstevel@tonic-gate 		header[0] = 0;
4837c478bd9Sstevel@tonic-gate 		header[1] = 0;
4847c478bd9Sstevel@tonic-gate 		strncpy(egroup, group, FR_GROUPLEN);
4857c478bd9Sstevel@tonic-gate 	} else if (openfunc == 1 && num < 0) {
4867c478bd9Sstevel@tonic-gate 		if (n != NULL) {
4877c478bd9Sstevel@tonic-gate 			free(n);
4887c478bd9Sstevel@tonic-gate 			n = NULL;
4897c478bd9Sstevel@tonic-gate 		}
4907c478bd9Sstevel@tonic-gate 		for (sin--; sin > 0; sin--) {
4917c478bd9Sstevel@tonic-gate 			indent(fp, sin);
4927c478bd9Sstevel@tonic-gate 			fprintf(fp, "}\n");
4937c478bd9Sstevel@tonic-gate 		}
4947c478bd9Sstevel@tonic-gate 		if (openfunc == 1) {
4957c478bd9Sstevel@tonic-gate 			fprintf(fp, "\treturn fr;\n}\n");
4967c478bd9Sstevel@tonic-gate 			openfunc = 0;
4977c478bd9Sstevel@tonic-gate 		}
4987c478bd9Sstevel@tonic-gate 	}
4997c478bd9Sstevel@tonic-gate 
5007c478bd9Sstevel@tonic-gate 	if (dir == -1)
5017c478bd9Sstevel@tonic-gate 		return;
5027c478bd9Sstevel@tonic-gate 
5037c478bd9Sstevel@tonic-gate 	for (g = groups; g != NULL; g = g->fg_next) {
5047c478bd9Sstevel@tonic-gate 		if (dir == 0 && (g->fg_flags & FR_INQUE) == 0)
5057c478bd9Sstevel@tonic-gate 			continue;
5067c478bd9Sstevel@tonic-gate 		else if (dir == 1 && (g->fg_flags & FR_OUTQUE) == 0)
5077c478bd9Sstevel@tonic-gate 			continue;
5087c478bd9Sstevel@tonic-gate 		if (strncmp(g->fg_name, group, FR_GROUPLEN) != 0)
5097c478bd9Sstevel@tonic-gate 			continue;
5107c478bd9Sstevel@tonic-gate 		break;
5117c478bd9Sstevel@tonic-gate 	}
5127c478bd9Sstevel@tonic-gate 
5137c478bd9Sstevel@tonic-gate 	/*
5147c478bd9Sstevel@tonic-gate 	 * Output the array of pointers to rules for this group.
5157c478bd9Sstevel@tonic-gate 	 */
5167c478bd9Sstevel@tonic-gate 	if (num == -2 && dir == 0 && header[0] == 0 && incount != 0) {
5177c478bd9Sstevel@tonic-gate 		fprintf(fp, "\nfrentry_t *ipf_rules_in_%s[%d] = {",
5187c478bd9Sstevel@tonic-gate 			group, incount);
5197c478bd9Sstevel@tonic-gate 		for (f = g->fg_start, i = 0; f != NULL; f = f->fr_next) {
5207c478bd9Sstevel@tonic-gate 			if ((f->fr_flags & FR_INQUE) == 0)
5217c478bd9Sstevel@tonic-gate 				continue;
5227c478bd9Sstevel@tonic-gate 			if ((i & 1) == 0) {
5237c478bd9Sstevel@tonic-gate 				fprintf(fp, "\n\t");
5247c478bd9Sstevel@tonic-gate 			}
5257c478bd9Sstevel@tonic-gate 			fprintf(fp,
5267c478bd9Sstevel@tonic-gate 				"(frentry_t *)&in_rule_%s_%d",
5277c478bd9Sstevel@tonic-gate 				f->fr_group, i);
5287c478bd9Sstevel@tonic-gate 			if (i + 1 < incount)
5297c478bd9Sstevel@tonic-gate 				fprintf(fp, ", ");
5307c478bd9Sstevel@tonic-gate 			i++;
5317c478bd9Sstevel@tonic-gate 		}
5327c478bd9Sstevel@tonic-gate 		fprintf(fp, "\n};\n");
5337c478bd9Sstevel@tonic-gate 	}
5347c478bd9Sstevel@tonic-gate 
5357c478bd9Sstevel@tonic-gate 	if (num == -2 && dir == 1 && header[1] == 0 && outcount != 0) {
5367c478bd9Sstevel@tonic-gate 		fprintf(fp, "\nfrentry_t *ipf_rules_out_%s[%d] = {",
5377c478bd9Sstevel@tonic-gate 			group, outcount);
5387c478bd9Sstevel@tonic-gate 		for (f = g->fg_start, i = 0; f != NULL; f = f->fr_next) {
5397c478bd9Sstevel@tonic-gate 			if ((f->fr_flags & FR_OUTQUE) == 0)
5407c478bd9Sstevel@tonic-gate 				continue;
5417c478bd9Sstevel@tonic-gate 			if ((i & 1) == 0) {
5427c478bd9Sstevel@tonic-gate 				fprintf(fp, "\n\t");
5437c478bd9Sstevel@tonic-gate 			}
5447c478bd9Sstevel@tonic-gate 			fprintf(fp,
5457c478bd9Sstevel@tonic-gate 				"(frentry_t *)&out_rule_%s_%d",
5467c478bd9Sstevel@tonic-gate 				f->fr_group, i);
5477c478bd9Sstevel@tonic-gate 			if (i + 1 < outcount)
5487c478bd9Sstevel@tonic-gate 				fprintf(fp, ", ");
5497c478bd9Sstevel@tonic-gate 			i++;
5507c478bd9Sstevel@tonic-gate 		}
5517c478bd9Sstevel@tonic-gate 		fprintf(fp, "\n};\n");
5527c478bd9Sstevel@tonic-gate 		fp = NULL;
5537c478bd9Sstevel@tonic-gate 	}
5547c478bd9Sstevel@tonic-gate 
5557c478bd9Sstevel@tonic-gate 	if (num < 0)
5567c478bd9Sstevel@tonic-gate 		return;
5577c478bd9Sstevel@tonic-gate 
5587c478bd9Sstevel@tonic-gate 	in = 0;
5597c478bd9Sstevel@tonic-gate 	ipf = fr->fr_ipf;
5607c478bd9Sstevel@tonic-gate 
5617c478bd9Sstevel@tonic-gate 	/*
5627c478bd9Sstevel@tonic-gate 	 * If the function header has not been printed then print it now.
5637c478bd9Sstevel@tonic-gate 	 */
5647c478bd9Sstevel@tonic-gate 	if (header[dir] == 0) {
5657c478bd9Sstevel@tonic-gate 		int pdst = 0, psrc = 0;
5667c478bd9Sstevel@tonic-gate 
5677c478bd9Sstevel@tonic-gate 		openfunc = 1;
5687c478bd9Sstevel@tonic-gate 		fprintf(fp, "\nfrentry_t *ipfrule_match_%s_%s(fin, passp)\n",
5697c478bd9Sstevel@tonic-gate 			(dir == 0) ? "in" : "out", group);
5707c478bd9Sstevel@tonic-gate 		fprintf(fp, "fr_info_t *fin;\n");
5717c478bd9Sstevel@tonic-gate 		fprintf(fp, "u_32_t *passp;\n");
5727c478bd9Sstevel@tonic-gate 		fprintf(fp, "{\n");
5737c478bd9Sstevel@tonic-gate 		fprintf(fp, "\tfrentry_t *fr = NULL;\n");
5747c478bd9Sstevel@tonic-gate 
5757c478bd9Sstevel@tonic-gate 		/*
5767c478bd9Sstevel@tonic-gate 		 * Print out any variables that need to be declared.
5777c478bd9Sstevel@tonic-gate 		 */
5787c478bd9Sstevel@tonic-gate 		for (f = g->fg_start, i = 0; f != NULL; f = f->fr_next) {
5797c478bd9Sstevel@tonic-gate 			if (incount + outcount > m[FRC_SRC].e + 1)
5807c478bd9Sstevel@tonic-gate 				psrc = 1;
5817c478bd9Sstevel@tonic-gate 			if (incount + outcount > m[FRC_DST].e + 1)
5827c478bd9Sstevel@tonic-gate 				pdst = 1;
5837c478bd9Sstevel@tonic-gate 		}
5847c478bd9Sstevel@tonic-gate 		if (psrc == 1)
5857c478bd9Sstevel@tonic-gate 			fprintf(fp, "\tu_32_t src = ntohl(%s);\n",
5867c478bd9Sstevel@tonic-gate 				"fin->fin_fi.fi_saddr");
5877c478bd9Sstevel@tonic-gate 		if (pdst == 1)
5887c478bd9Sstevel@tonic-gate 			fprintf(fp, "\tu_32_t dst = ntohl(%s);\n",
5897c478bd9Sstevel@tonic-gate 				"fin->fin_fi.fi_daddr");
5907c478bd9Sstevel@tonic-gate 	}
5917c478bd9Sstevel@tonic-gate 
5927c478bd9Sstevel@tonic-gate 	for (i = 0; i < FRC_MAX; i++) {
5937c478bd9Sstevel@tonic-gate 		switch(m[i].c)
5947c478bd9Sstevel@tonic-gate 		{
5957c478bd9Sstevel@tonic-gate 		case FRC_IFN :
5967c478bd9Sstevel@tonic-gate 			if (*fr->fr_ifname)
5977c478bd9Sstevel@tonic-gate 				m[i].s = 1;
5987c478bd9Sstevel@tonic-gate 			break;
5997c478bd9Sstevel@tonic-gate 		case FRC_V :
6007c478bd9Sstevel@tonic-gate 			if (ipf != NULL && ipf->fri_mip.fi_v != 0)
6017c478bd9Sstevel@tonic-gate 				m[i].s = 1;
6027c478bd9Sstevel@tonic-gate 			break;
6037c478bd9Sstevel@tonic-gate 		case FRC_FL :
6047c478bd9Sstevel@tonic-gate 			if (ipf != NULL && ipf->fri_mip.fi_flx != 0)
6057c478bd9Sstevel@tonic-gate 				m[i].s = 1;
6067c478bd9Sstevel@tonic-gate 			break;
6077c478bd9Sstevel@tonic-gate 		case FRC_P :
6087c478bd9Sstevel@tonic-gate 			if (ipf != NULL && ipf->fri_mip.fi_p != 0)
6097c478bd9Sstevel@tonic-gate 				m[i].s = 1;
6107c478bd9Sstevel@tonic-gate 			break;
6117c478bd9Sstevel@tonic-gate 		case FRC_TTL :
6127c478bd9Sstevel@tonic-gate 			if (ipf != NULL && ipf->fri_mip.fi_ttl != 0)
6137c478bd9Sstevel@tonic-gate 				m[i].s = 1;
6147c478bd9Sstevel@tonic-gate 			break;
6157c478bd9Sstevel@tonic-gate 		case FRC_TOS :
6167c478bd9Sstevel@tonic-gate 			if (ipf != NULL && ipf->fri_mip.fi_tos != 0)
6177c478bd9Sstevel@tonic-gate 				m[i].s = 1;
6187c478bd9Sstevel@tonic-gate 			break;
6197c478bd9Sstevel@tonic-gate 		case FRC_TCP :
6207c478bd9Sstevel@tonic-gate 			if (ipf == NULL)
6217c478bd9Sstevel@tonic-gate 				break;
6227c478bd9Sstevel@tonic-gate 			if ((ipf->fri_ip.fi_p == IPPROTO_TCP) &&
6237c478bd9Sstevel@tonic-gate 			    fr->fr_tcpfm != 0)
6247c478bd9Sstevel@tonic-gate 				m[i].s = 1;
6257c478bd9Sstevel@tonic-gate 			break;
6267c478bd9Sstevel@tonic-gate 		case FRC_SP :
6277c478bd9Sstevel@tonic-gate 			if (ipf == NULL)
6287c478bd9Sstevel@tonic-gate 				break;
6297c478bd9Sstevel@tonic-gate 			if (fr->fr_scmp == FR_INRANGE)
6307c478bd9Sstevel@tonic-gate 				m[i].s = 1;
6317c478bd9Sstevel@tonic-gate 			else if (fr->fr_scmp == FR_OUTRANGE)
6327c478bd9Sstevel@tonic-gate 				m[i].s = 1;
6337c478bd9Sstevel@tonic-gate 			else if (fr->fr_scmp != 0)
6347c478bd9Sstevel@tonic-gate 				m[i].s = 1;
6357c478bd9Sstevel@tonic-gate 			break;
6367c478bd9Sstevel@tonic-gate 		case FRC_DP :
6377c478bd9Sstevel@tonic-gate 			if (ipf == NULL)
6387c478bd9Sstevel@tonic-gate 				break;
6397c478bd9Sstevel@tonic-gate 			if (fr->fr_dcmp == FR_INRANGE)
6407c478bd9Sstevel@tonic-gate 				m[i].s = 1;
6417c478bd9Sstevel@tonic-gate 			else if (fr->fr_dcmp == FR_OUTRANGE)
6427c478bd9Sstevel@tonic-gate 				m[i].s = 1;
6437c478bd9Sstevel@tonic-gate 			else if (fr->fr_dcmp != 0)
6447c478bd9Sstevel@tonic-gate 				m[i].s = 1;
6457c478bd9Sstevel@tonic-gate 			break;
6467c478bd9Sstevel@tonic-gate 		case FRC_SRC :
6477c478bd9Sstevel@tonic-gate 			if (ipf == NULL)
6487c478bd9Sstevel@tonic-gate 				break;
6497c478bd9Sstevel@tonic-gate 			if (fr->fr_satype == FRI_LOOKUP) {
6507c478bd9Sstevel@tonic-gate 				;
6517c478bd9Sstevel@tonic-gate 			} else if ((fr->fr_smask != 0) ||
6527c478bd9Sstevel@tonic-gate 				   (fr->fr_flags & FR_NOTSRCIP) != 0)
6537c478bd9Sstevel@tonic-gate 				m[i].s = 1;
6547c478bd9Sstevel@tonic-gate 			break;
6557c478bd9Sstevel@tonic-gate 		case FRC_DST :
6567c478bd9Sstevel@tonic-gate 			if (ipf == NULL)
6577c478bd9Sstevel@tonic-gate 				break;
6587c478bd9Sstevel@tonic-gate 			if (fr->fr_datype == FRI_LOOKUP) {
6597c478bd9Sstevel@tonic-gate 				;
6607c478bd9Sstevel@tonic-gate 			} else if ((fr->fr_dmask != 0) ||
6617c478bd9Sstevel@tonic-gate 				   (fr->fr_flags & FR_NOTDSTIP) != 0)
6627c478bd9Sstevel@tonic-gate 				m[i].s = 1;
6637c478bd9Sstevel@tonic-gate 			break;
6647c478bd9Sstevel@tonic-gate 		case FRC_OPT :
6657c478bd9Sstevel@tonic-gate 			if (ipf == NULL)
6667c478bd9Sstevel@tonic-gate 				break;
6677c478bd9Sstevel@tonic-gate 			if (fr->fr_optmask != 0)
6687c478bd9Sstevel@tonic-gate 				m[i].s = 1;
6697c478bd9Sstevel@tonic-gate 			break;
6707c478bd9Sstevel@tonic-gate 		case FRC_SEC :
6717c478bd9Sstevel@tonic-gate 			if (ipf == NULL)
6727c478bd9Sstevel@tonic-gate 				break;
6737c478bd9Sstevel@tonic-gate 			if (fr->fr_secmask != 0)
6747c478bd9Sstevel@tonic-gate 				m[i].s = 1;
6757c478bd9Sstevel@tonic-gate 			break;
6767c478bd9Sstevel@tonic-gate 		case FRC_ATH :
6777c478bd9Sstevel@tonic-gate 			if (ipf == NULL)
6787c478bd9Sstevel@tonic-gate 				break;
6797c478bd9Sstevel@tonic-gate 			if (fr->fr_authmask != 0)
6807c478bd9Sstevel@tonic-gate 				m[i].s = 1;
6817c478bd9Sstevel@tonic-gate 			break;
6827c478bd9Sstevel@tonic-gate 		case FRC_ICT :
6837c478bd9Sstevel@tonic-gate 			if (ipf == NULL)
6847c478bd9Sstevel@tonic-gate 				break;
6857c478bd9Sstevel@tonic-gate 			if ((fr->fr_icmpm & 0xff00) != 0)
6867c478bd9Sstevel@tonic-gate 				m[i].s = 1;
6877c478bd9Sstevel@tonic-gate 			break;
6887c478bd9Sstevel@tonic-gate 		case FRC_ICC :
6897c478bd9Sstevel@tonic-gate 			if (ipf == NULL)
6907c478bd9Sstevel@tonic-gate 				break;
6917c478bd9Sstevel@tonic-gate 			if ((fr->fr_icmpm & 0xff) != 0)
6927c478bd9Sstevel@tonic-gate 				m[i].s = 1;
6937c478bd9Sstevel@tonic-gate 			break;
6947c478bd9Sstevel@tonic-gate 		}
6957c478bd9Sstevel@tonic-gate 	}
6967c478bd9Sstevel@tonic-gate 
6977c478bd9Sstevel@tonic-gate 	if (!header[dir]) {
6987c478bd9Sstevel@tonic-gate 		fprintf(fp, "\n");
6997c478bd9Sstevel@tonic-gate 		header[dir] = 1;
7007c478bd9Sstevel@tonic-gate 		sin = 0;
7017c478bd9Sstevel@tonic-gate 	}
7027c478bd9Sstevel@tonic-gate 
7037c478bd9Sstevel@tonic-gate 	qsort(m, FRC_MAX, sizeof(mc_t), intcmp);
7047c478bd9Sstevel@tonic-gate 
7057c478bd9Sstevel@tonic-gate 	if (n) {
7067c478bd9Sstevel@tonic-gate 		/*
7077c478bd9Sstevel@tonic-gate 		 * Calculate the indentation interval upto the last common
7087c478bd9Sstevel@tonic-gate 		 * common comparison being made.
7097c478bd9Sstevel@tonic-gate 		 */
7107c478bd9Sstevel@tonic-gate 		for (i = 0, in = 1; i < FRC_MAX; i++) {
7117c478bd9Sstevel@tonic-gate 			if (n[i].c != m[i].c)
7127c478bd9Sstevel@tonic-gate 				break;
7137c478bd9Sstevel@tonic-gate 			if (n[i].s != m[i].s)
7147c478bd9Sstevel@tonic-gate 				break;
7157c478bd9Sstevel@tonic-gate 			if (n[i].s) {
7167c478bd9Sstevel@tonic-gate 				if (n[i].n && (n[i].n > n[i].e)) {
7177c478bd9Sstevel@tonic-gate 					m[i].p++;
7187c478bd9Sstevel@tonic-gate 					in += m[i].p;
7197c478bd9Sstevel@tonic-gate 					break;
7207c478bd9Sstevel@tonic-gate 				}
7217c478bd9Sstevel@tonic-gate 				if (n[i].e > 0) {
7227c478bd9Sstevel@tonic-gate 					in++;
7237c478bd9Sstevel@tonic-gate 				} else
7247c478bd9Sstevel@tonic-gate 					break;
7257c478bd9Sstevel@tonic-gate 			}
7267c478bd9Sstevel@tonic-gate 		}
7277c478bd9Sstevel@tonic-gate 		if (sin != in) {
7287c478bd9Sstevel@tonic-gate 			for (j = sin - 1; j >= in; j--) {
7297c478bd9Sstevel@tonic-gate 				indent(fp, j);
7307c478bd9Sstevel@tonic-gate 				fprintf(fp, "}\n");
7317c478bd9Sstevel@tonic-gate 			}
7327c478bd9Sstevel@tonic-gate 		}
7337c478bd9Sstevel@tonic-gate 	} else {
7347c478bd9Sstevel@tonic-gate 		in = 1;
7357c478bd9Sstevel@tonic-gate 		i = 0;
7367c478bd9Sstevel@tonic-gate 	}
7377c478bd9Sstevel@tonic-gate 
7387c478bd9Sstevel@tonic-gate 	/*
7397c478bd9Sstevel@tonic-gate 	 * print out C code that implements a filter rule.
740ab25eeb5Syz 	 */
7417c478bd9Sstevel@tonic-gate 	for (; i < FRC_MAX; i++) {
7427c478bd9Sstevel@tonic-gate 		switch(m[i].c)
7437c478bd9Sstevel@tonic-gate 		{
7447c478bd9Sstevel@tonic-gate 		case FRC_IFN :
7457c478bd9Sstevel@tonic-gate 			if (m[i].s) {
7467c478bd9Sstevel@tonic-gate 				indent(fp, in);
7477c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (fin->fin_ifp == ");
7487c478bd9Sstevel@tonic-gate 				fprintf(fp, "ipf_rules_%s_%s[%d]->fr_ifa) {\n",
7497c478bd9Sstevel@tonic-gate 					dir ? "out" : "in", group, num);
7507c478bd9Sstevel@tonic-gate 				in++;
7517c478bd9Sstevel@tonic-gate 			}
7527c478bd9Sstevel@tonic-gate 			break;
7537c478bd9Sstevel@tonic-gate 		case FRC_V :
7547c478bd9Sstevel@tonic-gate 			if (m[i].s) {
7557c478bd9Sstevel@tonic-gate 				indent(fp, in);
7567c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (fin->fin_v == %d) {\n",
7577c478bd9Sstevel@tonic-gate 					ipf->fri_ip.fi_v);
7587c478bd9Sstevel@tonic-gate 				in++;
7597c478bd9Sstevel@tonic-gate 			}
7607c478bd9Sstevel@tonic-gate 			break;
7617c478bd9Sstevel@tonic-gate 		case FRC_FL :
7627c478bd9Sstevel@tonic-gate 			if (m[i].s) {
7637c478bd9Sstevel@tonic-gate 				indent(fp, in);
7647c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (");
7657c478bd9Sstevel@tonic-gate 				printeq(fp, "fin->fin_flx",
7667c478bd9Sstevel@tonic-gate 				        ipf->fri_mip.fi_flx, 0xf,
7677c478bd9Sstevel@tonic-gate 					ipf->fri_ip.fi_flx);
7687c478bd9Sstevel@tonic-gate 				in++;
7697c478bd9Sstevel@tonic-gate 			}
7707c478bd9Sstevel@tonic-gate 			break;
7717c478bd9Sstevel@tonic-gate 		case FRC_P :
7727c478bd9Sstevel@tonic-gate 			if (m[i].s) {
7737c478bd9Sstevel@tonic-gate 				indent(fp, in);
7747c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (fin->fin_p == %d) {\n",
7757c478bd9Sstevel@tonic-gate 					ipf->fri_ip.fi_p);
7767c478bd9Sstevel@tonic-gate 				in++;
7777c478bd9Sstevel@tonic-gate 			}
7787c478bd9Sstevel@tonic-gate 			break;
7797c478bd9Sstevel@tonic-gate 		case FRC_TTL :
7807c478bd9Sstevel@tonic-gate 			if (m[i].s) {
7817c478bd9Sstevel@tonic-gate 				indent(fp, in);
7827c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (");
7837c478bd9Sstevel@tonic-gate 				printeq(fp, "fin->fin_ttl",
7847c478bd9Sstevel@tonic-gate 					ipf->fri_mip.fi_ttl, 0xff,
7857c478bd9Sstevel@tonic-gate 					ipf->fri_ip.fi_ttl);
7867c478bd9Sstevel@tonic-gate 				in++;
7877c478bd9Sstevel@tonic-gate 			}
7887c478bd9Sstevel@tonic-gate 			break;
7897c478bd9Sstevel@tonic-gate 		case FRC_TOS :
7907c478bd9Sstevel@tonic-gate 			if (m[i].s) {
7917c478bd9Sstevel@tonic-gate 				indent(fp, in);
7927c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (fin->fin_tos");
7937c478bd9Sstevel@tonic-gate 				printeq(fp, "fin->fin_tos",
7947c478bd9Sstevel@tonic-gate 					ipf->fri_mip.fi_tos, 0xff,
7957c478bd9Sstevel@tonic-gate 					ipf->fri_ip.fi_tos);
7967c478bd9Sstevel@tonic-gate 				in++;
7977c478bd9Sstevel@tonic-gate 			}
7987c478bd9Sstevel@tonic-gate 			break;
7997c478bd9Sstevel@tonic-gate 		case FRC_TCP :
8007c478bd9Sstevel@tonic-gate 			if (m[i].s) {
8017c478bd9Sstevel@tonic-gate 				indent(fp, in);
8027c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (");
8037c478bd9Sstevel@tonic-gate 				printeq(fp, "fin->fin_tcpf", fr->fr_tcpfm,
8047c478bd9Sstevel@tonic-gate 					0xff, fr->fr_tcpf);
8057c478bd9Sstevel@tonic-gate 				in++;
8067c478bd9Sstevel@tonic-gate 			}
8077c478bd9Sstevel@tonic-gate 			break;
8087c478bd9Sstevel@tonic-gate 		case FRC_SP :
8097c478bd9Sstevel@tonic-gate 			if (!m[i].s)
8107c478bd9Sstevel@tonic-gate 				break;
8117c478bd9Sstevel@tonic-gate 			if (fr->fr_scmp == FR_INRANGE) {
8127c478bd9Sstevel@tonic-gate 				indent(fp, in);
8137c478bd9Sstevel@tonic-gate 				fprintf(fp, "if ((fin->fin_data[0] > %d) && ",
8147c478bd9Sstevel@tonic-gate 					fr->fr_sport);
8157c478bd9Sstevel@tonic-gate 				fprintf(fp, "(fin->fin_data[0] < %d)",
8167c478bd9Sstevel@tonic-gate 					fr->fr_stop);
8177c478bd9Sstevel@tonic-gate 				fprintf(fp, ") {\n");
8187c478bd9Sstevel@tonic-gate 				in++;
8197c478bd9Sstevel@tonic-gate 			} else if (fr->fr_scmp == FR_OUTRANGE) {
8207c478bd9Sstevel@tonic-gate 				indent(fp, in);
8217c478bd9Sstevel@tonic-gate 				fprintf(fp, "if ((fin->fin_data[0] < %d) || ",
8227c478bd9Sstevel@tonic-gate 					fr->fr_sport);
8237c478bd9Sstevel@tonic-gate 				fprintf(fp, "(fin->fin_data[0] > %d)",
8247c478bd9Sstevel@tonic-gate 					fr->fr_stop);
8257c478bd9Sstevel@tonic-gate 				fprintf(fp, ") {\n");
8267c478bd9Sstevel@tonic-gate 				in++;
8277c478bd9Sstevel@tonic-gate 			} else if (fr->fr_scmp) {
8287c478bd9Sstevel@tonic-gate 				indent(fp, in);
8297c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (fin->fin_data[0] %s %d)",
8307c478bd9Sstevel@tonic-gate 					portcmp[fr->fr_scmp], fr->fr_sport);
8317c478bd9Sstevel@tonic-gate 				fprintf(fp, " {\n");
8327c478bd9Sstevel@tonic-gate 				in++;
8337c478bd9Sstevel@tonic-gate 			}
8347c478bd9Sstevel@tonic-gate 			break;
8357c478bd9Sstevel@tonic-gate 		case FRC_DP :
8367c478bd9Sstevel@tonic-gate 			if (!m[i].s)
8377c478bd9Sstevel@tonic-gate 				break;
8387c478bd9Sstevel@tonic-gate 			if (fr->fr_dcmp == FR_INRANGE) {
8397c478bd9Sstevel@tonic-gate 				indent(fp, in);
8407c478bd9Sstevel@tonic-gate 				fprintf(fp, "if ((fin->fin_data[1] > %d) && ",
8417c478bd9Sstevel@tonic-gate 					fr->fr_dport);
8427c478bd9Sstevel@tonic-gate 				fprintf(fp, "(fin->fin_data[1] < %d)",
8437c478bd9Sstevel@tonic-gate 					fr->fr_dtop);
8447c478bd9Sstevel@tonic-gate 				fprintf(fp, ") {\n");
8457c478bd9Sstevel@tonic-gate 				in++;
8467c478bd9Sstevel@tonic-gate 			} else if (fr->fr_dcmp == FR_OUTRANGE) {
8477c478bd9Sstevel@tonic-gate 				indent(fp, in);
8487c478bd9Sstevel@tonic-gate 				fprintf(fp, "if ((fin->fin_data[1] < %d) || ",
8497c478bd9Sstevel@tonic-gate 					fr->fr_dport);
8507c478bd9Sstevel@tonic-gate 				fprintf(fp, "(fin->fin_data[1] > %d)",
8517c478bd9Sstevel@tonic-gate 					fr->fr_dtop);
8527c478bd9Sstevel@tonic-gate 				fprintf(fp, ") {\n");
8537c478bd9Sstevel@tonic-gate 				in++;
8547c478bd9Sstevel@tonic-gate 			} else if (fr->fr_dcmp) {
8557c478bd9Sstevel@tonic-gate 				indent(fp, in);
8567c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (fin->fin_data[1] %s %d)",
8577c478bd9Sstevel@tonic-gate 					portcmp[fr->fr_dcmp], fr->fr_dport);
8587c478bd9Sstevel@tonic-gate 				fprintf(fp, " {\n");
8597c478bd9Sstevel@tonic-gate 				in++;
8607c478bd9Sstevel@tonic-gate 			}
8617c478bd9Sstevel@tonic-gate 			break;
8627c478bd9Sstevel@tonic-gate 		case FRC_SRC :
8637c478bd9Sstevel@tonic-gate 			if (!m[i].s)
8647c478bd9Sstevel@tonic-gate 				break;
8657c478bd9Sstevel@tonic-gate 			if (fr->fr_satype == FRI_LOOKUP) {
8667c478bd9Sstevel@tonic-gate 				;
8677c478bd9Sstevel@tonic-gate 			} else if ((fr->fr_smask != 0) ||
8687c478bd9Sstevel@tonic-gate 				   (fr->fr_flags & FR_NOTSRCIP) != 0) {
8697c478bd9Sstevel@tonic-gate 				indent(fp, in);
8707c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (");
8717c478bd9Sstevel@tonic-gate 				printipeq(fp, "src",
8727c478bd9Sstevel@tonic-gate 					  fr->fr_flags & FR_NOTSRCIP,
8737c478bd9Sstevel@tonic-gate 					  fr->fr_smask, fr->fr_saddr);
8747c478bd9Sstevel@tonic-gate 				in++;
8757c478bd9Sstevel@tonic-gate 			}
8767c478bd9Sstevel@tonic-gate 			break;
8777c478bd9Sstevel@tonic-gate 		case FRC_DST :
8787c478bd9Sstevel@tonic-gate 			if (!m[i].s)
8797c478bd9Sstevel@tonic-gate 				break;
8807c478bd9Sstevel@tonic-gate 			if (fr->fr_datype == FRI_LOOKUP) {
8817c478bd9Sstevel@tonic-gate 				;
8827c478bd9Sstevel@tonic-gate 			} else if ((fr->fr_dmask != 0) ||
8837c478bd9Sstevel@tonic-gate 				   (fr->fr_flags & FR_NOTDSTIP) != 0) {
8847c478bd9Sstevel@tonic-gate 				indent(fp, in);
8857c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (");
8867c478bd9Sstevel@tonic-gate 				printipeq(fp, "dst",
8877c478bd9Sstevel@tonic-gate 					  fr->fr_flags & FR_NOTDSTIP,
8887c478bd9Sstevel@tonic-gate 					  fr->fr_dmask, fr->fr_daddr);
8897c478bd9Sstevel@tonic-gate 				in++;
8907c478bd9Sstevel@tonic-gate 			}
8917c478bd9Sstevel@tonic-gate 			break;
8927c478bd9Sstevel@tonic-gate 		case FRC_OPT :
8937c478bd9Sstevel@tonic-gate 			if (m[i].s) {
8947c478bd9Sstevel@tonic-gate 				indent(fp, in);
8957c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (");
8967c478bd9Sstevel@tonic-gate 				printeq(fp, "fin->fin_fi.fi_optmsk",
8977c478bd9Sstevel@tonic-gate 					fr->fr_optmask, 0xffffffff,
8987c478bd9Sstevel@tonic-gate 				        fr->fr_optbits);
8997c478bd9Sstevel@tonic-gate 				in++;
9007c478bd9Sstevel@tonic-gate 			}
9017c478bd9Sstevel@tonic-gate 			break;
9027c478bd9Sstevel@tonic-gate 		case FRC_SEC :
9037c478bd9Sstevel@tonic-gate 			if (m[i].s) {
9047c478bd9Sstevel@tonic-gate 				indent(fp, in);
9057c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (");
9067c478bd9Sstevel@tonic-gate 				printeq(fp, "fin->fin_fi.fi_secmsk",
9077c478bd9Sstevel@tonic-gate 					fr->fr_secmask, 0xffff,
9087c478bd9Sstevel@tonic-gate 					fr->fr_secbits);
9097c478bd9Sstevel@tonic-gate 				in++;
9107c478bd9Sstevel@tonic-gate 			}
9117c478bd9Sstevel@tonic-gate 			break;
9127c478bd9Sstevel@tonic-gate 		case FRC_ATH :
9137c478bd9Sstevel@tonic-gate 			if (m[i].s) {
9147c478bd9Sstevel@tonic-gate 				indent(fp, in);
9157c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (");
9167c478bd9Sstevel@tonic-gate 				printeq(fp, "fin->fin_fi.fi_authmsk",
9177c478bd9Sstevel@tonic-gate 					fr->fr_authmask, 0xffff,
9187c478bd9Sstevel@tonic-gate 					fr->fr_authbits);
9197c478bd9Sstevel@tonic-gate 				in++;
9207c478bd9Sstevel@tonic-gate 			}
9217c478bd9Sstevel@tonic-gate 			break;
9227c478bd9Sstevel@tonic-gate 		case FRC_ICT :
9237c478bd9Sstevel@tonic-gate 			if (m[i].s) {
9247c478bd9Sstevel@tonic-gate 				indent(fp, in);
9257c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (");
9267c478bd9Sstevel@tonic-gate 				printeq(fp, "fin->fin_data[0]",
9277c478bd9Sstevel@tonic-gate 					fr->fr_icmpm & 0xff00, 0xffff,
9287c478bd9Sstevel@tonic-gate 					fr->fr_icmp & 0xff00);
9297c478bd9Sstevel@tonic-gate 				in++;
9307c478bd9Sstevel@tonic-gate 			}
9317c478bd9Sstevel@tonic-gate 			break;
9327c478bd9Sstevel@tonic-gate 		case FRC_ICC :
9337c478bd9Sstevel@tonic-gate 			if (m[i].s) {
9347c478bd9Sstevel@tonic-gate 				indent(fp, in);
9357c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (");
9367c478bd9Sstevel@tonic-gate 				printeq(fp, "fin->fin_data[0]",
9377c478bd9Sstevel@tonic-gate 					fr->fr_icmpm & 0xff, 0xffff,
9387c478bd9Sstevel@tonic-gate 					fr->fr_icmp & 0xff);
9397c478bd9Sstevel@tonic-gate 				in++;
9407c478bd9Sstevel@tonic-gate 			}
9417c478bd9Sstevel@tonic-gate 			break;
9427c478bd9Sstevel@tonic-gate 		}
9437c478bd9Sstevel@tonic-gate 
9447c478bd9Sstevel@tonic-gate 	}
9457c478bd9Sstevel@tonic-gate 
9467c478bd9Sstevel@tonic-gate 	indent(fp, in);
9477c478bd9Sstevel@tonic-gate 	if (fr->fr_flags & FR_QUICK) {
9487c478bd9Sstevel@tonic-gate 		fprintf(fp, "return (frentry_t *)&%s_rule_%s_%d;\n",
9497c478bd9Sstevel@tonic-gate 			fr->fr_flags & FR_INQUE ? "in" : "out",
9507c478bd9Sstevel@tonic-gate 			fr->fr_group, num);
9517c478bd9Sstevel@tonic-gate 	} else {
9527c478bd9Sstevel@tonic-gate 		fprintf(fp, "fr = (frentry_t *)&%s_rule_%s_%d;\n",
9537c478bd9Sstevel@tonic-gate 			fr->fr_flags & FR_INQUE ? "in" : "out",
9547c478bd9Sstevel@tonic-gate 			fr->fr_group, num);
9557c478bd9Sstevel@tonic-gate 	}
956*34ef97d0Sjojemann 	if (n == NULL) {
9577c478bd9Sstevel@tonic-gate 		n = (mc_t *)malloc(sizeof(*n) * FRC_MAX);
958*34ef97d0Sjojemann 		if (n == NULL) {
959*34ef97d0Sjojemann 			fprintf(stderr, "out of memory\n");
960*34ef97d0Sjojemann 			exit(1);
961*34ef97d0Sjojemann 		}
962*34ef97d0Sjojemann 	}
9637c478bd9Sstevel@tonic-gate 	bcopy((char *)m, (char *)n, sizeof(*n) * FRC_MAX);
9647c478bd9Sstevel@tonic-gate 	sin = in;
9657c478bd9Sstevel@tonic-gate }
9667c478bd9Sstevel@tonic-gate 
9677c478bd9Sstevel@tonic-gate 
9687c478bd9Sstevel@tonic-gate void printC(dir)
9697c478bd9Sstevel@tonic-gate int dir;
9707c478bd9Sstevel@tonic-gate {
9717c478bd9Sstevel@tonic-gate 	static mc_t *m = NULL;
9727c478bd9Sstevel@tonic-gate 	frgroup_t *g;
9737c478bd9Sstevel@tonic-gate 
974*34ef97d0Sjojemann 	if (m == NULL) {
9757c478bd9Sstevel@tonic-gate 		m = (mc_t *)calloc(1, sizeof(*m) * FRC_MAX);
976*34ef97d0Sjojemann 		if (m == NULL) {
977*34ef97d0Sjojemann 			fprintf(stderr, "out of memory\n");
978*34ef97d0Sjojemann 			exit(1);
979*34ef97d0Sjojemann 		}
980*34ef97d0Sjojemann 	}
9817c478bd9Sstevel@tonic-gate 
9827c478bd9Sstevel@tonic-gate 	for (g = groups; g != NULL; g = g->fg_next) {
9837c478bd9Sstevel@tonic-gate 		if ((dir == 0) && ((g->fg_flags & FR_INQUE) != 0))
9847c478bd9Sstevel@tonic-gate 			printCgroup(dir, g->fg_start, m, g->fg_name);
9857c478bd9Sstevel@tonic-gate 		if ((dir == 1) && ((g->fg_flags & FR_OUTQUE) != 0))
9867c478bd9Sstevel@tonic-gate 			printCgroup(dir, g->fg_start, m, g->fg_name);
9877c478bd9Sstevel@tonic-gate 	}
9887c478bd9Sstevel@tonic-gate 
9897c478bd9Sstevel@tonic-gate 	emit(-1, dir, m, NULL);
9907c478bd9Sstevel@tonic-gate }
9917c478bd9Sstevel@tonic-gate 
9927c478bd9Sstevel@tonic-gate 
9937c478bd9Sstevel@tonic-gate /*
9947c478bd9Sstevel@tonic-gate  * Now print out code to implement all of the rules.
9957c478bd9Sstevel@tonic-gate  */
9967c478bd9Sstevel@tonic-gate static void printCgroup(dir, top, m, group)
9977c478bd9Sstevel@tonic-gate int dir;
9987c478bd9Sstevel@tonic-gate frentry_t *top;
9997c478bd9Sstevel@tonic-gate mc_t *m;
10007c478bd9Sstevel@tonic-gate char *group;
10017c478bd9Sstevel@tonic-gate {
10027c478bd9Sstevel@tonic-gate 	frentry_t *fr, *fr1;
10037c478bd9Sstevel@tonic-gate 	int i, n, rn;
10047c478bd9Sstevel@tonic-gate 	u_int count;
10057c478bd9Sstevel@tonic-gate 
10067c478bd9Sstevel@tonic-gate 	for (count = 0, fr1 = top; fr1 != NULL; fr1 = fr1->fr_next) {
10077c478bd9Sstevel@tonic-gate 		if ((dir == 0) && ((fr1->fr_flags & FR_INQUE) != 0))
10087c478bd9Sstevel@tonic-gate 			count++;
10097c478bd9Sstevel@tonic-gate 		else if ((dir == 1) && ((fr1->fr_flags & FR_OUTQUE) != 0))
10107c478bd9Sstevel@tonic-gate 			count++;
10117c478bd9Sstevel@tonic-gate 	}
10127c478bd9Sstevel@tonic-gate 
10137c478bd9Sstevel@tonic-gate 	if (dir == 0)
10147c478bd9Sstevel@tonic-gate 		emitGroup(-2, dir, m, fr1, group, count, 0);
10157c478bd9Sstevel@tonic-gate 	else if (dir == 1)
10167c478bd9Sstevel@tonic-gate 		emitGroup(-2, dir, m, fr1, group, 0, count);
10177c478bd9Sstevel@tonic-gate 
10187c478bd9Sstevel@tonic-gate 	/*
10197c478bd9Sstevel@tonic-gate 	 * Before printing each rule, check to see how many of its fields are
10207c478bd9Sstevel@tonic-gate 	 * matched by subsequent rules.
10217c478bd9Sstevel@tonic-gate 	 */
10227c478bd9Sstevel@tonic-gate 	for (fr1 = top, rn = 0; fr1 != NULL; fr1 = fr1->fr_next, rn++) {
10237c478bd9Sstevel@tonic-gate 		if (!dir && !(fr1->fr_flags & FR_INQUE))
10247c478bd9Sstevel@tonic-gate 			continue;
10257c478bd9Sstevel@tonic-gate 		if (dir && !(fr1->fr_flags & FR_OUTQUE))
10267c478bd9Sstevel@tonic-gate 			continue;
10277c478bd9Sstevel@tonic-gate 		n = 0xfffffff;
10287c478bd9Sstevel@tonic-gate 
10297c478bd9Sstevel@tonic-gate 		for (i = 0; i < FRC_MAX; i++)
10307c478bd9Sstevel@tonic-gate 			m[i].e = 0;
10317c478bd9Sstevel@tonic-gate 		qsort(m, FRC_MAX, sizeof(mc_t), intcmp);
10327c478bd9Sstevel@tonic-gate 
10337c478bd9Sstevel@tonic-gate 		for (i = 0; i < FRC_MAX; i++) {
10347c478bd9Sstevel@tonic-gate 			m[i].c = i;
10357c478bd9Sstevel@tonic-gate 			m[i].e = 0;
10367c478bd9Sstevel@tonic-gate 			m[i].n = 0;
10377c478bd9Sstevel@tonic-gate 			m[i].s = 0;
10387c478bd9Sstevel@tonic-gate 		}
10397c478bd9Sstevel@tonic-gate 
10407c478bd9Sstevel@tonic-gate 		for (fr = fr1->fr_next; fr; fr = fr->fr_next) {
10417c478bd9Sstevel@tonic-gate 			if (!dir && !(fr->fr_flags & FR_INQUE))
10427c478bd9Sstevel@tonic-gate 				continue;
10437c478bd9Sstevel@tonic-gate 			if (dir && !(fr->fr_flags & FR_OUTQUE))
10447c478bd9Sstevel@tonic-gate 				continue;
10457c478bd9Sstevel@tonic-gate 
10467c478bd9Sstevel@tonic-gate 			if ((n & 0x0001) &&
10477c478bd9Sstevel@tonic-gate 			    !strcmp(fr1->fr_ifname, fr->fr_ifname)) {
10487c478bd9Sstevel@tonic-gate 				m[FRC_IFN].e++;
10497c478bd9Sstevel@tonic-gate 				m[FRC_IFN].n++;
10507c478bd9Sstevel@tonic-gate 			} else
10517c478bd9Sstevel@tonic-gate 				n &= ~0x0001;
10527c478bd9Sstevel@tonic-gate 
10537c478bd9Sstevel@tonic-gate 			if ((n & 0x0002) && (fr1->fr_v == fr->fr_v)) {
10547c478bd9Sstevel@tonic-gate 				m[FRC_V].e++;
10557c478bd9Sstevel@tonic-gate 				m[FRC_V].n++;
10567c478bd9Sstevel@tonic-gate 			} else
10577c478bd9Sstevel@tonic-gate 				n &= ~0x0002;
10587c478bd9Sstevel@tonic-gate 
10597c478bd9Sstevel@tonic-gate 			if ((n & 0x0004) &&
10607c478bd9Sstevel@tonic-gate 			    (fr->fr_type == fr1->fr_type) &&
10617c478bd9Sstevel@tonic-gate 			    (fr->fr_type == FR_T_IPF) &&
10627c478bd9Sstevel@tonic-gate 			    (fr1->fr_mip.fi_flx == fr->fr_mip.fi_flx) &&
10637c478bd9Sstevel@tonic-gate 			    (fr1->fr_ip.fi_flx == fr->fr_ip.fi_flx)) {
10647c478bd9Sstevel@tonic-gate 				m[FRC_FL].e++;
10657c478bd9Sstevel@tonic-gate 				m[FRC_FL].n++;
10667c478bd9Sstevel@tonic-gate 			} else
10677c478bd9Sstevel@tonic-gate 				n &= ~0x0004;
10687c478bd9Sstevel@tonic-gate 
10697c478bd9Sstevel@tonic-gate 			if ((n & 0x0008) &&
10707c478bd9Sstevel@tonic-gate 			    (fr->fr_type == fr1->fr_type) &&
10717c478bd9Sstevel@tonic-gate 			    (fr->fr_type == FR_T_IPF) &&
10727c478bd9Sstevel@tonic-gate 			    (fr1->fr_proto == fr->fr_proto)) {
10737c478bd9Sstevel@tonic-gate 				m[FRC_P].e++;
10747c478bd9Sstevel@tonic-gate 				m[FRC_P].n++;
10757c478bd9Sstevel@tonic-gate 			} else
10767c478bd9Sstevel@tonic-gate 				n &= ~0x0008;
10777c478bd9Sstevel@tonic-gate 
10787c478bd9Sstevel@tonic-gate 			if ((n & 0x0010) &&
10797c478bd9Sstevel@tonic-gate 			    (fr->fr_type == fr1->fr_type) &&
10807c478bd9Sstevel@tonic-gate 			    (fr->fr_type == FR_T_IPF) &&
10817c478bd9Sstevel@tonic-gate 			    (fr1->fr_ttl == fr->fr_ttl)) {
10827c478bd9Sstevel@tonic-gate 				m[FRC_TTL].e++;
10837c478bd9Sstevel@tonic-gate 				m[FRC_TTL].n++;
10847c478bd9Sstevel@tonic-gate 			} else
10857c478bd9Sstevel@tonic-gate 				n &= ~0x0010;
10867c478bd9Sstevel@tonic-gate 
10877c478bd9Sstevel@tonic-gate 			if ((n & 0x0020) &&
10887c478bd9Sstevel@tonic-gate 			    (fr->fr_type == fr1->fr_type) &&
10897c478bd9Sstevel@tonic-gate 			    (fr->fr_type == FR_T_IPF) &&
10907c478bd9Sstevel@tonic-gate 			    (fr1->fr_tos == fr->fr_tos)) {
10917c478bd9Sstevel@tonic-gate 				m[FRC_TOS].e++;
10927c478bd9Sstevel@tonic-gate 				m[FRC_TOS].n++;
10937c478bd9Sstevel@tonic-gate 			} else
10947c478bd9Sstevel@tonic-gate 				n &= ~0x0020;
10957c478bd9Sstevel@tonic-gate 
10967c478bd9Sstevel@tonic-gate 			if ((n & 0x0040) &&
10977c478bd9Sstevel@tonic-gate 			    (fr->fr_type == fr1->fr_type) &&
10987c478bd9Sstevel@tonic-gate 			    (fr->fr_type == FR_T_IPF) &&
10997c478bd9Sstevel@tonic-gate 			    ((fr1->fr_tcpfm == fr->fr_tcpfm) &&
11007c478bd9Sstevel@tonic-gate 			    (fr1->fr_tcpf == fr->fr_tcpf))) {
11017c478bd9Sstevel@tonic-gate 				m[FRC_TCP].e++;
11027c478bd9Sstevel@tonic-gate 				m[FRC_TCP].n++;
11037c478bd9Sstevel@tonic-gate 			} else
11047c478bd9Sstevel@tonic-gate 				n &= ~0x0040;
11057c478bd9Sstevel@tonic-gate 
11067c478bd9Sstevel@tonic-gate 			if ((n & 0x0080) &&
11077c478bd9Sstevel@tonic-gate 			    (fr->fr_type == fr1->fr_type) &&
11087c478bd9Sstevel@tonic-gate 			    (fr->fr_type == FR_T_IPF) &&
11097c478bd9Sstevel@tonic-gate 			    ((fr1->fr_scmp == fr->fr_scmp) &&
11107c478bd9Sstevel@tonic-gate 			     (fr1->fr_stop == fr->fr_stop) &&
11117c478bd9Sstevel@tonic-gate 			     (fr1->fr_sport == fr->fr_sport))) {
11127c478bd9Sstevel@tonic-gate 				m[FRC_SP].e++;
11137c478bd9Sstevel@tonic-gate 				m[FRC_SP].n++;
11147c478bd9Sstevel@tonic-gate 			} else
11157c478bd9Sstevel@tonic-gate 				n &= ~0x0080;
11167c478bd9Sstevel@tonic-gate 
11177c478bd9Sstevel@tonic-gate 			if ((n & 0x0100) &&
11187c478bd9Sstevel@tonic-gate 			    (fr->fr_type == fr1->fr_type) &&
11197c478bd9Sstevel@tonic-gate 			    (fr->fr_type == FR_T_IPF) &&
11207c478bd9Sstevel@tonic-gate 			    ((fr1->fr_dcmp == fr->fr_dcmp) &&
11217c478bd9Sstevel@tonic-gate 			     (fr1->fr_dtop == fr->fr_dtop) &&
11227c478bd9Sstevel@tonic-gate 			     (fr1->fr_dport == fr->fr_dport))) {
11237c478bd9Sstevel@tonic-gate 				m[FRC_DP].e++;
11247c478bd9Sstevel@tonic-gate 				m[FRC_DP].n++;
11257c478bd9Sstevel@tonic-gate 			} else
11267c478bd9Sstevel@tonic-gate 				n &= ~0x0100;
11277c478bd9Sstevel@tonic-gate 
11287c478bd9Sstevel@tonic-gate 			if ((n & 0x0200) &&
11297c478bd9Sstevel@tonic-gate 			    (fr->fr_type == fr1->fr_type) &&
11307c478bd9Sstevel@tonic-gate 			    (fr->fr_type == FR_T_IPF) &&
11317c478bd9Sstevel@tonic-gate 			    ((fr1->fr_satype == FRI_LOOKUP) &&
11327c478bd9Sstevel@tonic-gate 			    (fr->fr_satype == FRI_LOOKUP) &&
11337c478bd9Sstevel@tonic-gate 			    (fr1->fr_srcnum == fr->fr_srcnum))) {
11347c478bd9Sstevel@tonic-gate 				m[FRC_SRC].e++;
11357c478bd9Sstevel@tonic-gate 				m[FRC_SRC].n++;
11367c478bd9Sstevel@tonic-gate 			} else if ((n & 0x0200) &&
11377c478bd9Sstevel@tonic-gate 				   (fr->fr_type == fr1->fr_type) &&
11387c478bd9Sstevel@tonic-gate 				   (fr->fr_type == FR_T_IPF) &&
11397c478bd9Sstevel@tonic-gate 				   (((fr1->fr_flags & FR_NOTSRCIP) ==
11407c478bd9Sstevel@tonic-gate 				    (fr->fr_flags & FR_NOTSRCIP)))) {
11417c478bd9Sstevel@tonic-gate 					if ((fr1->fr_smask == fr->fr_smask) &&
11427c478bd9Sstevel@tonic-gate 					    (fr1->fr_saddr == fr->fr_saddr))
11437c478bd9Sstevel@tonic-gate 						m[FRC_SRC].e++;
11447c478bd9Sstevel@tonic-gate 					else
11457c478bd9Sstevel@tonic-gate 						n &= ~0x0200;
11467c478bd9Sstevel@tonic-gate 					if (fr1->fr_smask &&
11477c478bd9Sstevel@tonic-gate 					    (fr1->fr_saddr & fr1->fr_smask) ==
11487c478bd9Sstevel@tonic-gate 					    (fr->fr_saddr & fr1->fr_smask)) {
11497c478bd9Sstevel@tonic-gate 						m[FRC_SRC].n++;
11507c478bd9Sstevel@tonic-gate 						n |= 0x0200;
11517c478bd9Sstevel@tonic-gate 					}
11527c478bd9Sstevel@tonic-gate 			} else {
11537c478bd9Sstevel@tonic-gate 				n &= ~0x0200;
11547c478bd9Sstevel@tonic-gate 			}
11557c478bd9Sstevel@tonic-gate 
11567c478bd9Sstevel@tonic-gate 			if ((n & 0x0400) &&
11577c478bd9Sstevel@tonic-gate 			    (fr->fr_type == fr1->fr_type) &&
11587c478bd9Sstevel@tonic-gate 			    (fr->fr_type == FR_T_IPF) &&
11597c478bd9Sstevel@tonic-gate 			    ((fr1->fr_datype == FRI_LOOKUP) &&
11607c478bd9Sstevel@tonic-gate 			    (fr->fr_datype == FRI_LOOKUP) &&
11617c478bd9Sstevel@tonic-gate 			    (fr1->fr_dstnum == fr->fr_dstnum))) {
11627c478bd9Sstevel@tonic-gate 				m[FRC_DST].e++;
11637c478bd9Sstevel@tonic-gate 				m[FRC_DST].n++;
11647c478bd9Sstevel@tonic-gate 			} else if ((n & 0x0400) &&
11657c478bd9Sstevel@tonic-gate 				   (fr->fr_type == fr1->fr_type) &&
11667c478bd9Sstevel@tonic-gate 				   (fr->fr_type == FR_T_IPF) &&
11677c478bd9Sstevel@tonic-gate 				   (((fr1->fr_flags & FR_NOTDSTIP) ==
11687c478bd9Sstevel@tonic-gate 				    (fr->fr_flags & FR_NOTDSTIP)))) {
11697c478bd9Sstevel@tonic-gate 					if ((fr1->fr_dmask == fr->fr_dmask) &&
11707c478bd9Sstevel@tonic-gate 					    (fr1->fr_daddr == fr->fr_daddr))
11717c478bd9Sstevel@tonic-gate 						m[FRC_DST].e++;
11727c478bd9Sstevel@tonic-gate 					else
11737c478bd9Sstevel@tonic-gate 						n &= ~0x0400;
11747c478bd9Sstevel@tonic-gate 					if (fr1->fr_dmask &&
11757c478bd9Sstevel@tonic-gate 					    (fr1->fr_daddr & fr1->fr_dmask) ==
11767c478bd9Sstevel@tonic-gate 					    (fr->fr_daddr & fr1->fr_dmask)) {
11777c478bd9Sstevel@tonic-gate 						m[FRC_DST].n++;
11787c478bd9Sstevel@tonic-gate 						n |= 0x0400;
11797c478bd9Sstevel@tonic-gate 					}
11807c478bd9Sstevel@tonic-gate 			} else {
11817c478bd9Sstevel@tonic-gate 				n &= ~0x0400;
11827c478bd9Sstevel@tonic-gate 			}
11837c478bd9Sstevel@tonic-gate 
11847c478bd9Sstevel@tonic-gate 			if ((n & 0x0800) &&
11857c478bd9Sstevel@tonic-gate 			    (fr->fr_type == fr1->fr_type) &&
11867c478bd9Sstevel@tonic-gate 			    (fr->fr_type == FR_T_IPF) &&
11877c478bd9Sstevel@tonic-gate 			    (fr1->fr_optmask == fr->fr_optmask) &&
11887c478bd9Sstevel@tonic-gate 			    (fr1->fr_optbits == fr->fr_optbits)) {
11897c478bd9Sstevel@tonic-gate 				m[FRC_OPT].e++;
11907c478bd9Sstevel@tonic-gate 				m[FRC_OPT].n++;
11917c478bd9Sstevel@tonic-gate 			} else
11927c478bd9Sstevel@tonic-gate 				n &= ~0x0800;
11937c478bd9Sstevel@tonic-gate 
11947c478bd9Sstevel@tonic-gate 			if ((n & 0x1000) &&
11957c478bd9Sstevel@tonic-gate 			    (fr->fr_type == fr1->fr_type) &&
11967c478bd9Sstevel@tonic-gate 			    (fr->fr_type == FR_T_IPF) &&
11977c478bd9Sstevel@tonic-gate 			    (fr1->fr_secmask == fr->fr_secmask) &&
11987c478bd9Sstevel@tonic-gate 			    (fr1->fr_secbits == fr->fr_secbits)) {
11997c478bd9Sstevel@tonic-gate 				m[FRC_SEC].e++;
12007c478bd9Sstevel@tonic-gate 				m[FRC_SEC].n++;
12017c478bd9Sstevel@tonic-gate 			} else
12027c478bd9Sstevel@tonic-gate 				n &= ~0x1000;
12037c478bd9Sstevel@tonic-gate 
12047c478bd9Sstevel@tonic-gate 			if ((n & 0x10000) &&
12057c478bd9Sstevel@tonic-gate 			    (fr->fr_type == fr1->fr_type) &&
12067c478bd9Sstevel@tonic-gate 			    (fr->fr_type == FR_T_IPF) &&
12077c478bd9Sstevel@tonic-gate 			    (fr1->fr_authmask == fr->fr_authmask) &&
12087c478bd9Sstevel@tonic-gate 			    (fr1->fr_authbits == fr->fr_authbits)) {
12097c478bd9Sstevel@tonic-gate 				m[FRC_ATH].e++;
12107c478bd9Sstevel@tonic-gate 				m[FRC_ATH].n++;
12117c478bd9Sstevel@tonic-gate 			} else
12127c478bd9Sstevel@tonic-gate 				n &= ~0x10000;
12137c478bd9Sstevel@tonic-gate 
12147c478bd9Sstevel@tonic-gate 			if ((n & 0x20000) &&
12157c478bd9Sstevel@tonic-gate 			    (fr->fr_type == fr1->fr_type) &&
12167c478bd9Sstevel@tonic-gate 			    (fr->fr_type == FR_T_IPF) &&
12177c478bd9Sstevel@tonic-gate 			    ((fr1->fr_icmpm & 0xff00) ==
12187c478bd9Sstevel@tonic-gate 			     (fr->fr_icmpm & 0xff00)) &&
12197c478bd9Sstevel@tonic-gate 			    ((fr1->fr_icmp & 0xff00) ==
12207c478bd9Sstevel@tonic-gate 			     (fr->fr_icmp & 0xff00))) {
12217c478bd9Sstevel@tonic-gate 				m[FRC_ICT].e++;
12227c478bd9Sstevel@tonic-gate 				m[FRC_ICT].n++;
12237c478bd9Sstevel@tonic-gate 			} else
12247c478bd9Sstevel@tonic-gate 				n &= ~0x20000;
12257c478bd9Sstevel@tonic-gate 
12267c478bd9Sstevel@tonic-gate 			if ((n & 0x40000) &&
12277c478bd9Sstevel@tonic-gate 			    (fr->fr_type == fr1->fr_type) &&
12287c478bd9Sstevel@tonic-gate 			    (fr->fr_type == FR_T_IPF) &&
12297c478bd9Sstevel@tonic-gate 			    ((fr1->fr_icmpm & 0xff) == (fr->fr_icmpm & 0xff)) &&
12307c478bd9Sstevel@tonic-gate 			    ((fr1->fr_icmp & 0xff) == (fr->fr_icmp & 0xff))) {
12317c478bd9Sstevel@tonic-gate 				m[FRC_ICC].e++;
12327c478bd9Sstevel@tonic-gate 				m[FRC_ICC].n++;
12337c478bd9Sstevel@tonic-gate 			} else
12347c478bd9Sstevel@tonic-gate 				n &= ~0x40000;
12357c478bd9Sstevel@tonic-gate 		}
12367c478bd9Sstevel@tonic-gate 		/*msort(m);*/
12377c478bd9Sstevel@tonic-gate 
12387c478bd9Sstevel@tonic-gate 		if (dir == 0)
12397c478bd9Sstevel@tonic-gate 			emitGroup(rn, dir, m, fr1, group, count, 0);
12407c478bd9Sstevel@tonic-gate 		else if (dir == 1)
12417c478bd9Sstevel@tonic-gate 			emitGroup(rn, dir, m, fr1, group, 0, count);
12427c478bd9Sstevel@tonic-gate 	}
12437c478bd9Sstevel@tonic-gate }
12447c478bd9Sstevel@tonic-gate 
12457c478bd9Sstevel@tonic-gate static void printhooks(fp, in, out, grp)
12467c478bd9Sstevel@tonic-gate FILE *fp;
12477c478bd9Sstevel@tonic-gate int in;
12487c478bd9Sstevel@tonic-gate int out;
12497c478bd9Sstevel@tonic-gate frgroup_t *grp;
12507c478bd9Sstevel@tonic-gate {
12517c478bd9Sstevel@tonic-gate 	frentry_t *fr;
12527c478bd9Sstevel@tonic-gate 	char *group;
12537c478bd9Sstevel@tonic-gate 	int dogrp, i;
12547c478bd9Sstevel@tonic-gate 	char *instr;
12557c478bd9Sstevel@tonic-gate 
12567c478bd9Sstevel@tonic-gate 	group = grp->fg_name;
12577c478bd9Sstevel@tonic-gate 	dogrp = 0;
12587c478bd9Sstevel@tonic-gate 
12597c478bd9Sstevel@tonic-gate 	if (in && out) {
12607c478bd9Sstevel@tonic-gate 		fprintf(stderr,
12617c478bd9Sstevel@tonic-gate 			"printhooks called with both in and out set\n");
12627c478bd9Sstevel@tonic-gate 		exit(1);
12637c478bd9Sstevel@tonic-gate 	}
12647c478bd9Sstevel@tonic-gate 
12657c478bd9Sstevel@tonic-gate 	if (in) {
12667c478bd9Sstevel@tonic-gate 		instr = "in";
12677c478bd9Sstevel@tonic-gate 	} else if (out) {
12687c478bd9Sstevel@tonic-gate 		instr = "out";
12697c478bd9Sstevel@tonic-gate 	} else {
12707c478bd9Sstevel@tonic-gate 		instr = "???";
12717c478bd9Sstevel@tonic-gate 	}
12727c478bd9Sstevel@tonic-gate 	fprintf(fp, "static frentry_t ipfrule_%s_%s;\n", instr, group);
12737c478bd9Sstevel@tonic-gate 
12747c478bd9Sstevel@tonic-gate 	fprintf(fp, "\
12757c478bd9Sstevel@tonic-gate \n\
12767c478bd9Sstevel@tonic-gate int ipfrule_add_%s_%s()\n", instr, group);
12777c478bd9Sstevel@tonic-gate 	fprintf(fp, "\
12787c478bd9Sstevel@tonic-gate {\n\
12797c478bd9Sstevel@tonic-gate 	int i, j, err = 0, max;\n\
12807c478bd9Sstevel@tonic-gate 	frentry_t *fp;\n");
12817c478bd9Sstevel@tonic-gate 
12827c478bd9Sstevel@tonic-gate 	if (dogrp)
12837c478bd9Sstevel@tonic-gate 		fprintf(fp, "\
12847c478bd9Sstevel@tonic-gate 	frgroup_t *fg;\n");
12857c478bd9Sstevel@tonic-gate 
12867c478bd9Sstevel@tonic-gate 	fprintf(fp, "\n");
12877c478bd9Sstevel@tonic-gate 
12887c478bd9Sstevel@tonic-gate 	for (i = 0, fr = grp->fg_start; fr != NULL; i++, fr = fr->fr_next)
12897c478bd9Sstevel@tonic-gate 		if (fr->fr_dsize > 0) {
12907c478bd9Sstevel@tonic-gate 			fprintf(fp, "\
12917c478bd9Sstevel@tonic-gate 	ipf_rules_%s_%s[%d]->fr_data = &ipf%s_rule_data_%s_%u;\n",
12927c478bd9Sstevel@tonic-gate 				instr, grp->fg_name, i,
12937c478bd9Sstevel@tonic-gate 				instr, grp->fg_name, i);
12947c478bd9Sstevel@tonic-gate 		}
12957c478bd9Sstevel@tonic-gate 	fprintf(fp, "\
12967c478bd9Sstevel@tonic-gate 	max = sizeof(ipf_rules_%s_%s)/sizeof(frentry_t *);\n\
12977c478bd9Sstevel@tonic-gate 	for (i = 0; i < max; i++) {\n\
12987c478bd9Sstevel@tonic-gate 		fp = ipf_rules_%s_%s[i];\n\
12997c478bd9Sstevel@tonic-gate 		fp->fr_next = NULL;\n", instr, group, instr, group);
13007c478bd9Sstevel@tonic-gate 
13017c478bd9Sstevel@tonic-gate 	fprintf(fp, "\
13027c478bd9Sstevel@tonic-gate 		for (j = i + 1; j < max; j++)\n\
13037c478bd9Sstevel@tonic-gate 			if (strncmp(fp->fr_group,\n\
13047c478bd9Sstevel@tonic-gate 				    ipf_rules_%s_%s[j]->fr_group,\n\
13057c478bd9Sstevel@tonic-gate 				    FR_GROUPLEN) == 0) {\n\
13067c478bd9Sstevel@tonic-gate 				fp->fr_next = ipf_rules_%s_%s[j];\n\
13077c478bd9Sstevel@tonic-gate 				break;\n\
13087c478bd9Sstevel@tonic-gate 			}\n", instr, group, instr, group);
13097c478bd9Sstevel@tonic-gate 	if (dogrp)
13107c478bd9Sstevel@tonic-gate 		fprintf(fp, "\
13117c478bd9Sstevel@tonic-gate \n\
13127c478bd9Sstevel@tonic-gate 		if (fp->fr_grhead != 0) {\n\
13137c478bd9Sstevel@tonic-gate 			fg = fr_addgroup(fp->fr_grhead, fp, FR_INQUE,\n\
13147c478bd9Sstevel@tonic-gate 					 IPL_LOGIPF, 0);\n\
13157c478bd9Sstevel@tonic-gate 			if (fg != NULL)\n\
13167c478bd9Sstevel@tonic-gate 				fp->fr_grp = &fg->fg_start;\n\
13177c478bd9Sstevel@tonic-gate 		}\n");
13187c478bd9Sstevel@tonic-gate 	fprintf(fp, "\
13197c478bd9Sstevel@tonic-gate 	}\n\
13207c478bd9Sstevel@tonic-gate \n\
13217c478bd9Sstevel@tonic-gate 	fp = &ipfrule_%s_%s;\n", instr, group);
13227c478bd9Sstevel@tonic-gate 		fprintf(fp, "\
13237c478bd9Sstevel@tonic-gate 	bzero((char *)fp, sizeof(*fp));\n\
13247c478bd9Sstevel@tonic-gate 	fp->fr_type = FR_T_CALLFUNC|FR_T_BUILTIN;\n\
13257c478bd9Sstevel@tonic-gate 	fp->fr_flags = FR_%sQUE|FR_NOMATCH;\n\
13267c478bd9Sstevel@tonic-gate 	fp->fr_data = (void *)ipf_rules_%s_%s[0];\n",
13277c478bd9Sstevel@tonic-gate 		(in != 0) ? "IN" : "OUT", instr, group);
1328ab25eeb5Syz 	fprintf(fp, "\
1329ab25eeb5Syz 	fp->fr_dsize = sizeof(ipf_rules_%s_%s[0]);\n",
1330ab25eeb5Syz 		instr, group);
13317c478bd9Sstevel@tonic-gate 
13327c478bd9Sstevel@tonic-gate 	fprintf(fp, "\
13337c478bd9Sstevel@tonic-gate 	fp->fr_v = 4;\n\
13347c478bd9Sstevel@tonic-gate 	fp->fr_func = (ipfunc_t)ipfrule_match_%s_%s;\n\
13357c478bd9Sstevel@tonic-gate 	err = frrequest(IPL_LOGIPF, SIOCADDFR, (caddr_t)fp, fr_active, 0);\n",
13367c478bd9Sstevel@tonic-gate 			instr, group);
13377c478bd9Sstevel@tonic-gate 	fprintf(fp, "\treturn err;\n}\n");
13387c478bd9Sstevel@tonic-gate 
13397c478bd9Sstevel@tonic-gate 	fprintf(fp, "\n\n\
13407c478bd9Sstevel@tonic-gate int ipfrule_remove_%s_%s()\n", instr, group);
13417c478bd9Sstevel@tonic-gate 	fprintf(fp, "\
13427c478bd9Sstevel@tonic-gate {\n\
13437c478bd9Sstevel@tonic-gate 	int err = 0, i;\n\
13447c478bd9Sstevel@tonic-gate 	frentry_t *fp;\n\
13457c478bd9Sstevel@tonic-gate \n\
13467c478bd9Sstevel@tonic-gate 	/*\n\
13477c478bd9Sstevel@tonic-gate 	 * Try to remove the %sbound rule.\n", instr);
13487c478bd9Sstevel@tonic-gate 
13497c478bd9Sstevel@tonic-gate 	fprintf(fp, "\
13507c478bd9Sstevel@tonic-gate 	 */\n\
13517c478bd9Sstevel@tonic-gate 	if (ipfrule_%s_%s.fr_ref > 0) {\n", instr, group);
13527c478bd9Sstevel@tonic-gate 
13537c478bd9Sstevel@tonic-gate 	fprintf(fp, "\
13547c478bd9Sstevel@tonic-gate 		err = EBUSY;\n\
13557c478bd9Sstevel@tonic-gate 	} else {\n");
13567c478bd9Sstevel@tonic-gate 
13577c478bd9Sstevel@tonic-gate 	fprintf(fp, "\
13587c478bd9Sstevel@tonic-gate 		i = sizeof(ipf_rules_%s_%s)/sizeof(frentry_t *) - 1;\n\
13597c478bd9Sstevel@tonic-gate 		for (; i >= 0; i--) {\n\
13607c478bd9Sstevel@tonic-gate 			fp = ipf_rules_%s_%s[i];\n\
13617c478bd9Sstevel@tonic-gate 			if (fp->fr_ref > 1) {\n\
13627c478bd9Sstevel@tonic-gate 				err = EBUSY;\n\
13637c478bd9Sstevel@tonic-gate 				break;\n\
13647c478bd9Sstevel@tonic-gate 			}\n\
13657c478bd9Sstevel@tonic-gate 		}\n\
13667c478bd9Sstevel@tonic-gate 	}\n\
13677c478bd9Sstevel@tonic-gate 	if (err == 0)\n\
13687c478bd9Sstevel@tonic-gate 		err = frrequest(IPL_LOGIPF, SIOCDELFR,\n\
13697c478bd9Sstevel@tonic-gate 				(caddr_t)&ipfrule_%s_%s, fr_active, 0);\n",
13707c478bd9Sstevel@tonic-gate 		instr, group, instr, group, instr, group);
13717c478bd9Sstevel@tonic-gate 	fprintf(fp, "\
13727c478bd9Sstevel@tonic-gate 	if (err)\n\
13737c478bd9Sstevel@tonic-gate 		return err;\n\
13747c478bd9Sstevel@tonic-gate \n\n");
13757c478bd9Sstevel@tonic-gate 
13767c478bd9Sstevel@tonic-gate 	fprintf(fp, "\treturn err;\n}\n");
13777c478bd9Sstevel@tonic-gate }
1378