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