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