xref: /illumos-gate/usr/src/cmd/ipf/tools/ipfcomp.c (revision d7c57852)
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.
8*d7c57852SGary Mills  * Copyright 2017 Gary Mills
97c478bd9Sstevel@tonic-gate  */
1034ef97d0Sjojemann 
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  */
printc(fr)637c478bd9Sstevel@tonic-gate void printc(fr)
647c478bd9Sstevel@tonic-gate frentry_t *fr;
657c478bd9Sstevel@tonic-gate {
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 
797c478bd9Sstevel@tonic-gate 	if (cfile == NULL)
807c478bd9Sstevel@tonic-gate 		cfile = fopen("ip_rules.c", "w");
817c478bd9Sstevel@tonic-gate 	if (cfile == NULL)
827c478bd9Sstevel@tonic-gate 		return;
837c478bd9Sstevel@tonic-gate 	fp = cfile;
847c478bd9Sstevel@tonic-gate 	if (count == 0) {
857c478bd9Sstevel@tonic-gate 		fprintf(fp, "/*\n");
867c478bd9Sstevel@tonic-gate  		fprintf(fp, "* Copyright (C) 1993-2000 by Darren Reed.\n");
877c478bd9Sstevel@tonic-gate  		fprintf(fp, "*\n");
887c478bd9Sstevel@tonic-gate  		fprintf(fp, "* Redistribution and use in source and binary forms are permitted\n");
897c478bd9Sstevel@tonic-gate  		fprintf(fp, "* provided that this notice is preserved and due credit is given\n");
907c478bd9Sstevel@tonic-gate  		fprintf(fp, "* to the original author and the contributors.\n");
917c478bd9Sstevel@tonic-gate  		fprintf(fp, "*/\n\n");
927c478bd9Sstevel@tonic-gate 
937c478bd9Sstevel@tonic-gate 		fprintf(fp, "#include <sys/types.h>\n");
947c478bd9Sstevel@tonic-gate 		fprintf(fp, "#include <sys/time.h>\n");
957c478bd9Sstevel@tonic-gate 		fprintf(fp, "#include <sys/socket.h>\n");
96ab25eeb5Syz 		fprintf(fp, "#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__sgi)\n");
97ab25eeb5Syz 		fprintf(fp, "# include <sys/systm.h>\n");
98ab25eeb5Syz 		fprintf(fp, "#endif\n");
997c478bd9Sstevel@tonic-gate 		fprintf(fp, "#include <sys/errno.h>\n");
1007c478bd9Sstevel@tonic-gate 		fprintf(fp, "#include <sys/param.h>\n");
1017c478bd9Sstevel@tonic-gate 		fprintf(fp,
1027c478bd9Sstevel@tonic-gate "#if !defined(__SVR4) && !defined(__svr4__) && !defined(__hpux)\n");
1037c478bd9Sstevel@tonic-gate 		fprintf(fp, "# include <sys/mbuf.h>\n");
1047c478bd9Sstevel@tonic-gate 		fprintf(fp, "#endif\n");
1057c478bd9Sstevel@tonic-gate 		fprintf(fp,
1067c478bd9Sstevel@tonic-gate "#if defined(__FreeBSD__) && (__FreeBSD_version > 220000)\n");
1077c478bd9Sstevel@tonic-gate 		fprintf(fp, "# include <sys/sockio.h>\n");
1087c478bd9Sstevel@tonic-gate 		fprintf(fp, "#else\n");
1097c478bd9Sstevel@tonic-gate 		fprintf(fp, "# include <sys/ioctl.h>\n");
1107c478bd9Sstevel@tonic-gate 		fprintf(fp, "#endif /* FreeBSD */\n");
1117c478bd9Sstevel@tonic-gate 		fprintf(fp, "#include <net/if.h>\n");
1127c478bd9Sstevel@tonic-gate 		fprintf(fp, "#include <netinet/in.h>\n");
1137c478bd9Sstevel@tonic-gate 		fprintf(fp, "#include <netinet/in_systm.h>\n");
1147c478bd9Sstevel@tonic-gate 		fprintf(fp, "#include <netinet/ip.h>\n");
1157c478bd9Sstevel@tonic-gate 		fprintf(fp, "#include <netinet/tcp.h>\n");
116ab25eeb5Syz 		fprintf(fp, "#include \"netinet/ip_compat.h\"\n");
117ab25eeb5Syz 		fprintf(fp, "#include \"netinet/ip_fil.h\"\n\n");
118ab25eeb5Syz 		fprintf(fp, "#include \"netinet/ip_rules.h\"\n\n");
119ab25eeb5Syz 		fprintf(fp, "#ifndef _KERNEL\n");
120ab25eeb5Syz 		fprintf(fp, "# include <string.h>\n");
121ab25eeb5Syz 		fprintf(fp, "#endif /* _KERNEL */\n");
122ab25eeb5Syz 		fprintf(fp, "\n");
123ab25eeb5Syz 		fprintf(fp, "#ifdef IPFILTER_COMPILED\n");
1247c478bd9Sstevel@tonic-gate 	}
1257c478bd9Sstevel@tonic-gate 
1267c478bd9Sstevel@tonic-gate 	addrule(fp, fr);
1277c478bd9Sstevel@tonic-gate 	fr->fr_type |= FR_T_BUILTIN;
1287c478bd9Sstevel@tonic-gate 	and = "";
1297c478bd9Sstevel@tonic-gate 	fr->fr_ref = 1;
1307c478bd9Sstevel@tonic-gate 	i = sizeof(*fr);
1317c478bd9Sstevel@tonic-gate 	if (i & -(1 - sizeof(*ulp)))
1327c478bd9Sstevel@tonic-gate 		i += sizeof(u_long);
1337c478bd9Sstevel@tonic-gate 	for (i /= sizeof(u_long), ulp = (u_long *)fr; i > 0; i--) {
1347c478bd9Sstevel@tonic-gate 		fprintf(fp, "%s%#lx", and, *ulp++);
1357c478bd9Sstevel@tonic-gate 		and = ", ";
1367c478bd9Sstevel@tonic-gate 	}
1377c478bd9Sstevel@tonic-gate 	fprintf(fp, "\n};\n");
1387c478bd9Sstevel@tonic-gate 	fr->fr_type &= ~FR_T_BUILTIN;
1397c478bd9Sstevel@tonic-gate 
1407c478bd9Sstevel@tonic-gate 	count++;
1417c478bd9Sstevel@tonic-gate 
1427c478bd9Sstevel@tonic-gate 	fflush(fp);
1437c478bd9Sstevel@tonic-gate }
1447c478bd9Sstevel@tonic-gate 
1457c478bd9Sstevel@tonic-gate 
1467c478bd9Sstevel@tonic-gate static frgroup_t *groups = NULL;
1477c478bd9Sstevel@tonic-gate 
1487c478bd9Sstevel@tonic-gate 
addrule(fp,fr)1497c478bd9Sstevel@tonic-gate static void addrule(fp, fr)
1507c478bd9Sstevel@tonic-gate FILE *fp;
1517c478bd9Sstevel@tonic-gate frentry_t *fr;
1527c478bd9Sstevel@tonic-gate {
1537c478bd9Sstevel@tonic-gate 	frentry_t *f, **fpp;
1547c478bd9Sstevel@tonic-gate 	frgroup_t *g;
1557c478bd9Sstevel@tonic-gate 	u_long *ulp;
1567c478bd9Sstevel@tonic-gate 	char *and;
1577c478bd9Sstevel@tonic-gate 	int i;
1587c478bd9Sstevel@tonic-gate 
1597c478bd9Sstevel@tonic-gate 	f = (frentry_t *)malloc(sizeof(*f));
16034ef97d0Sjojemann 	if (f == NULL) {
16134ef97d0Sjojemann 		fprintf(stderr, "out of memory\n");
16234ef97d0Sjojemann 		exit(1);
16334ef97d0Sjojemann 	}
1647c478bd9Sstevel@tonic-gate 	bcopy((char *)fr, (char *)f, sizeof(*fr));
1657c478bd9Sstevel@tonic-gate 	if (fr->fr_ipf) {
1667c478bd9Sstevel@tonic-gate 		f->fr_ipf = (fripf_t *)malloc(sizeof(*f->fr_ipf));
16734ef97d0Sjojemann 		if (f->fr_ipf == NULL) {
16834ef97d0Sjojemann 			fprintf(stderr, "out of memory\n");
16934ef97d0Sjojemann 			exit(1);
17034ef97d0Sjojemann 		}
1717c478bd9Sstevel@tonic-gate 		bcopy((char *)fr->fr_ipf, (char *)f->fr_ipf,
1727c478bd9Sstevel@tonic-gate 		      sizeof(*fr->fr_ipf));
1737c478bd9Sstevel@tonic-gate 	}
1747c478bd9Sstevel@tonic-gate 
1757c478bd9Sstevel@tonic-gate 	f->fr_next = NULL;
1767c478bd9Sstevel@tonic-gate 	for (g = groups; g != NULL; g = g->fg_next)
1777c478bd9Sstevel@tonic-gate 		if ((strncmp(g->fg_name, f->fr_group, FR_GROUPLEN) == 0) &&
1787c478bd9Sstevel@tonic-gate 		    (g->fg_flags == (f->fr_flags & FR_INOUT)))
1797c478bd9Sstevel@tonic-gate 			break;
1807c478bd9Sstevel@tonic-gate 
1817c478bd9Sstevel@tonic-gate 	if (g == NULL) {
1827c478bd9Sstevel@tonic-gate 		g = (frgroup_t *)calloc(1, sizeof(*g));
18334ef97d0Sjojemann 		if (g == NULL) {
18434ef97d0Sjojemann 			fprintf(stderr, "out of memory\n");
18534ef97d0Sjojemann 			exit(1);
18634ef97d0Sjojemann 		}
1877c478bd9Sstevel@tonic-gate 		g->fg_next = groups;
1887c478bd9Sstevel@tonic-gate 		groups = g;
1897c478bd9Sstevel@tonic-gate 		g->fg_head = f;
1907c478bd9Sstevel@tonic-gate 		bcopy(f->fr_group, g->fg_name, FR_GROUPLEN);
1917c478bd9Sstevel@tonic-gate 		g->fg_ref = 0;
1927c478bd9Sstevel@tonic-gate 		g->fg_flags = f->fr_flags & FR_INOUT;
1937c478bd9Sstevel@tonic-gate 	}
1947c478bd9Sstevel@tonic-gate 
1957c478bd9Sstevel@tonic-gate 	for (fpp = &g->fg_start; *fpp != NULL; )
1967c478bd9Sstevel@tonic-gate 		fpp = &((*fpp)->fr_next);
1977c478bd9Sstevel@tonic-gate 	*fpp = f;
1987c478bd9Sstevel@tonic-gate 
1997c478bd9Sstevel@tonic-gate 	if (fr->fr_dsize > 0) {
2007c478bd9Sstevel@tonic-gate 		fprintf(fp, "\
2017c478bd9Sstevel@tonic-gate static u_long ipf%s_rule_data_%s_%u[] = {\n",
2027c478bd9Sstevel@tonic-gate 			f->fr_flags & FR_INQUE ? "in" : "out",
2037c478bd9Sstevel@tonic-gate 			g->fg_name, g->fg_ref);
2047c478bd9Sstevel@tonic-gate 		and = "";
2057c478bd9Sstevel@tonic-gate 		i = fr->fr_dsize;
2067c478bd9Sstevel@tonic-gate 		ulp = fr->fr_data;
2077c478bd9Sstevel@tonic-gate 		for (i /= sizeof(u_long); i > 0; i--) {
2087c478bd9Sstevel@tonic-gate 			fprintf(fp, "%s%#lx", and, *ulp++);
2097c478bd9Sstevel@tonic-gate 			and = ", ";
2107c478bd9Sstevel@tonic-gate 		}
2117c478bd9Sstevel@tonic-gate 		fprintf(fp, "\n};\n");
2127c478bd9Sstevel@tonic-gate 	}
2137c478bd9Sstevel@tonic-gate 
2147c478bd9Sstevel@tonic-gate 	fprintf(fp, "\nstatic u_long %s_rule_%s_%d[] = {\n",
2157c478bd9Sstevel@tonic-gate 		f->fr_flags & FR_INQUE ? "in" : "out", g->fg_name, g->fg_ref);
2167c478bd9Sstevel@tonic-gate 
2177c478bd9Sstevel@tonic-gate 	g->fg_ref++;
2187c478bd9Sstevel@tonic-gate 
2197c478bd9Sstevel@tonic-gate 	if (f->fr_grhead != 0) {
2207c478bd9Sstevel@tonic-gate 		for (g = groups; g != NULL; g = g->fg_next)
2217c478bd9Sstevel@tonic-gate 			if ((strncmp(g->fg_name, f->fr_grhead,
2227c478bd9Sstevel@tonic-gate 				     FR_GROUPLEN) == 0) &&
2237c478bd9Sstevel@tonic-gate 			    g->fg_flags == (f->fr_flags & FR_INOUT))
2247c478bd9Sstevel@tonic-gate 				break;
2257c478bd9Sstevel@tonic-gate 		if (g == NULL) {
2267c478bd9Sstevel@tonic-gate 			g = (frgroup_t *)calloc(1, sizeof(*g));
22734ef97d0Sjojemann 			if (g == NULL) {
22834ef97d0Sjojemann 				fprintf(stderr, "out of memory\n");
22934ef97d0Sjojemann 				exit(1);
23034ef97d0Sjojemann 			}
2317c478bd9Sstevel@tonic-gate 			g->fg_next = groups;
2327c478bd9Sstevel@tonic-gate 			groups = g;
2337c478bd9Sstevel@tonic-gate 			g->fg_head = f;
2347c478bd9Sstevel@tonic-gate 			bcopy(f->fr_grhead, g->fg_name, FR_GROUPLEN);
2357c478bd9Sstevel@tonic-gate 			g->fg_ref = 0;
2367c478bd9Sstevel@tonic-gate 			g->fg_flags = f->fr_flags & FR_INOUT;
2377c478bd9Sstevel@tonic-gate 		}
2387c478bd9Sstevel@tonic-gate 	}
2397c478bd9Sstevel@tonic-gate }
2407c478bd9Sstevel@tonic-gate 
2417c478bd9Sstevel@tonic-gate 
intcmp(c1,c2)2427c478bd9Sstevel@tonic-gate int intcmp(c1, c2)
2437c478bd9Sstevel@tonic-gate const void *c1, *c2;
2447c478bd9Sstevel@tonic-gate {
2457c478bd9Sstevel@tonic-gate 	const mc_t *i1 = (const mc_t *)c1, *i2 = (const mc_t *)c2;
2467c478bd9Sstevel@tonic-gate 
2477c478bd9Sstevel@tonic-gate 	if (i1->n == i2->n) {
2487c478bd9Sstevel@tonic-gate 		return i1->c - i2->c;
2497c478bd9Sstevel@tonic-gate 	}
2507c478bd9Sstevel@tonic-gate 	return i2->n - i1->n;
2517c478bd9Sstevel@tonic-gate }
2527c478bd9Sstevel@tonic-gate 
2537c478bd9Sstevel@tonic-gate 
indent(fp,in)2547c478bd9Sstevel@tonic-gate static void indent(fp, in)
2557c478bd9Sstevel@tonic-gate FILE *fp;
2567c478bd9Sstevel@tonic-gate int in;
2577c478bd9Sstevel@tonic-gate {
2587c478bd9Sstevel@tonic-gate 	for (; in; in--)
2597c478bd9Sstevel@tonic-gate 		fputc('\t', fp);
2607c478bd9Sstevel@tonic-gate }
2617c478bd9Sstevel@tonic-gate 
printeq(fp,var,m,max,v)2627c478bd9Sstevel@tonic-gate static void printeq(fp, var, m, max, v)
2637c478bd9Sstevel@tonic-gate FILE *fp;
2647c478bd9Sstevel@tonic-gate char *var;
2657c478bd9Sstevel@tonic-gate int m, max, v;
2667c478bd9Sstevel@tonic-gate {
2677c478bd9Sstevel@tonic-gate 	if (m == max)
2687c478bd9Sstevel@tonic-gate 		fprintf(fp, "%s == %#x) {\n", var, v);
2697c478bd9Sstevel@tonic-gate 	else
2707c478bd9Sstevel@tonic-gate 		fprintf(fp, "(%s & %#x) == %#x) {\n", var, m, v);
2717c478bd9Sstevel@tonic-gate }
2727c478bd9Sstevel@tonic-gate 
2737c478bd9Sstevel@tonic-gate /*
2747c478bd9Sstevel@tonic-gate  * Parameters: var - IP# being compared
2757c478bd9Sstevel@tonic-gate  *             fl - 0 for positive match, 1 for negative match
2767c478bd9Sstevel@tonic-gate  *             m - netmask
2777c478bd9Sstevel@tonic-gate  *             v - required address
2787c478bd9Sstevel@tonic-gate  */
printipeq(fp,var,fl,m,v)2797c478bd9Sstevel@tonic-gate static void printipeq(fp, var, fl, m, v)
2807c478bd9Sstevel@tonic-gate FILE *fp;
2817c478bd9Sstevel@tonic-gate char *var;
2827c478bd9Sstevel@tonic-gate int fl, m, v;
2837c478bd9Sstevel@tonic-gate {
2847c478bd9Sstevel@tonic-gate 	if (m == 0xffffffff)
2857c478bd9Sstevel@tonic-gate 		fprintf(fp, "%s ", var);
2867c478bd9Sstevel@tonic-gate 	else
2877c478bd9Sstevel@tonic-gate 		fprintf(fp, "(%s & %#x) ", var, m);
2887c478bd9Sstevel@tonic-gate 	fprintf(fp, "%c", fl ? '!' : '=');
2897c478bd9Sstevel@tonic-gate 	fprintf(fp, "= %#x) {\n", v);
2907c478bd9Sstevel@tonic-gate }
2917c478bd9Sstevel@tonic-gate 
2927c478bd9Sstevel@tonic-gate 
emit(num,dir,v,fr)2937c478bd9Sstevel@tonic-gate void emit(num, dir, v, fr)
2947c478bd9Sstevel@tonic-gate int num, dir;
2957c478bd9Sstevel@tonic-gate void *v;
2967c478bd9Sstevel@tonic-gate frentry_t *fr;
2977c478bd9Sstevel@tonic-gate {
2987c478bd9Sstevel@tonic-gate 	u_int incnt, outcnt;
2997c478bd9Sstevel@tonic-gate 	frgroup_t *g;
3007c478bd9Sstevel@tonic-gate 	frentry_t *f;
3017c478bd9Sstevel@tonic-gate 
3027c478bd9Sstevel@tonic-gate 	for (g = groups; g != NULL; g = g->fg_next) {
3037c478bd9Sstevel@tonic-gate 		if (dir == 0 || dir == -1) {
3047c478bd9Sstevel@tonic-gate 			if ((g->fg_flags & FR_INQUE) == 0)
3057c478bd9Sstevel@tonic-gate 				continue;
3067c478bd9Sstevel@tonic-gate 			for (incnt = 0, f = g->fg_start; f != NULL;
3077c478bd9Sstevel@tonic-gate 			     f = f->fr_next)
3087c478bd9Sstevel@tonic-gate 				incnt++;
3097c478bd9Sstevel@tonic-gate 			emitGroup(num, dir, v, fr, g->fg_name, incnt, 0);
3107c478bd9Sstevel@tonic-gate 		}
3117c478bd9Sstevel@tonic-gate 		if (dir == 1 || dir == -1) {
3127c478bd9Sstevel@tonic-gate 			if ((g->fg_flags & FR_OUTQUE) == 0)
3137c478bd9Sstevel@tonic-gate 				continue;
3147c478bd9Sstevel@tonic-gate 			for (outcnt = 0, f = g->fg_start; f != NULL;
3157c478bd9Sstevel@tonic-gate 			     f = f->fr_next)
3167c478bd9Sstevel@tonic-gate 				outcnt++;
3177c478bd9Sstevel@tonic-gate 			emitGroup(num, dir, v, fr, g->fg_name, 0, outcnt);
3187c478bd9Sstevel@tonic-gate 		}
3197c478bd9Sstevel@tonic-gate 	}
3207c478bd9Sstevel@tonic-gate 
3217c478bd9Sstevel@tonic-gate 	if (num == -1 && dir == -1) {
3227c478bd9Sstevel@tonic-gate 		for (g = groups; g != NULL; g = g->fg_next) {
3237c478bd9Sstevel@tonic-gate 			if ((g->fg_flags & FR_INQUE) != 0) {
3247c478bd9Sstevel@tonic-gate 				for (incnt = 0, f = g->fg_start; f != NULL;
3257c478bd9Sstevel@tonic-gate 				     f = f->fr_next)
3267c478bd9Sstevel@tonic-gate 					incnt++;
3277c478bd9Sstevel@tonic-gate 				if (incnt > 0)
3287c478bd9Sstevel@tonic-gate 					emitheader(g, incnt, 0);
3297c478bd9Sstevel@tonic-gate 			}
3307c478bd9Sstevel@tonic-gate 			if ((g->fg_flags & FR_OUTQUE) != 0) {
3317c478bd9Sstevel@tonic-gate 				for (outcnt = 0, f = g->fg_start; f != NULL;
3327c478bd9Sstevel@tonic-gate 				     f = f->fr_next)
3337c478bd9Sstevel@tonic-gate 					outcnt++;
3347c478bd9Sstevel@tonic-gate 				if (outcnt > 0)
3357c478bd9Sstevel@tonic-gate 					emitheader(g, 0, outcnt);
3367c478bd9Sstevel@tonic-gate 			}
3377c478bd9Sstevel@tonic-gate 		}
3387c478bd9Sstevel@tonic-gate 		emittail();
339ab25eeb5Syz 		fprintf(cfile, "#endif /* IPFILTER_COMPILED */\n");
3407c478bd9Sstevel@tonic-gate 	}
341ab25eeb5Syz 
3427c478bd9Sstevel@tonic-gate }
3437c478bd9Sstevel@tonic-gate 
3447c478bd9Sstevel@tonic-gate 
emitheader(grp,incount,outcount)3457c478bd9Sstevel@tonic-gate static void emitheader(grp, incount, outcount)
3467c478bd9Sstevel@tonic-gate frgroup_t *grp;
3477c478bd9Sstevel@tonic-gate u_int incount, outcount;
3487c478bd9Sstevel@tonic-gate {
3497c478bd9Sstevel@tonic-gate 	static FILE *fph = NULL;
3507c478bd9Sstevel@tonic-gate 	frgroup_t *g;
3517c478bd9Sstevel@tonic-gate 
3527c478bd9Sstevel@tonic-gate 	if (fph == NULL) {
3537c478bd9Sstevel@tonic-gate 		fph = fopen("ip_rules.h", "w");
3547c478bd9Sstevel@tonic-gate 		if (fph == NULL)
3557c478bd9Sstevel@tonic-gate 			return;
3567c478bd9Sstevel@tonic-gate 
3577c478bd9Sstevel@tonic-gate 		fprintf(fph, "extern int ipfrule_add __P((void));\n");
3587c478bd9Sstevel@tonic-gate 		fprintf(fph, "extern int ipfrule_remove __P((void));\n");
3597c478bd9Sstevel@tonic-gate 	}
3607c478bd9Sstevel@tonic-gate 
3617c478bd9Sstevel@tonic-gate 	printhooks(cfile, incount, outcount, grp);
3627c478bd9Sstevel@tonic-gate 
3637c478bd9Sstevel@tonic-gate 	if (incount) {
3647c478bd9Sstevel@tonic-gate 		fprintf(fph, "\n\
3657c478bd9Sstevel@tonic-gate extern frentry_t *ipfrule_match_in_%s __P((fr_info_t *, u_32_t *));\n\
3667c478bd9Sstevel@tonic-gate extern frentry_t *ipf_rules_in_%s[%d];\n",
3677c478bd9Sstevel@tonic-gate 			grp->fg_name, grp->fg_name, incount);
3687c478bd9Sstevel@tonic-gate 
3697c478bd9Sstevel@tonic-gate 		for (g = groups; g != grp; g = g->fg_next)
3707c478bd9Sstevel@tonic-gate 			if ((strncmp(g->fg_name, grp->fg_name,
3717c478bd9Sstevel@tonic-gate 				     FR_GROUPLEN) == 0) &&
3727c478bd9Sstevel@tonic-gate 			    g->fg_flags == grp->fg_flags)
3737c478bd9Sstevel@tonic-gate 				break;
3747c478bd9Sstevel@tonic-gate 		if (g == grp) {
3757c478bd9Sstevel@tonic-gate 			fprintf(fph, "\n\
3767c478bd9Sstevel@tonic-gate extern int ipfrule_add_in_%s __P((void));\n\
3777c478bd9Sstevel@tonic-gate extern int ipfrule_remove_in_%s __P((void));\n", grp->fg_name, grp->fg_name);
3787c478bd9Sstevel@tonic-gate 		}
3797c478bd9Sstevel@tonic-gate 	}
3807c478bd9Sstevel@tonic-gate 	if (outcount) {
3817c478bd9Sstevel@tonic-gate 		fprintf(fph, "\n\
3827c478bd9Sstevel@tonic-gate extern frentry_t *ipfrule_match_out_%s __P((fr_info_t *, u_32_t *));\n\
3837c478bd9Sstevel@tonic-gate extern frentry_t *ipf_rules_out_%s[%d];\n",
3847c478bd9Sstevel@tonic-gate 			grp->fg_name, grp->fg_name, outcount);
3857c478bd9Sstevel@tonic-gate 
386d5767f31SToomas Soome 		for (g = groups; g != grp; g = g->fg_next)
3877c478bd9Sstevel@tonic-gate 			if ((strncmp(g->fg_name, grp->fg_name,
3887c478bd9Sstevel@tonic-gate 				     FR_GROUPLEN) == 0) &&
3897c478bd9Sstevel@tonic-gate 			    g->fg_flags == grp->fg_flags)
3907c478bd9Sstevel@tonic-gate 				break;
3917c478bd9Sstevel@tonic-gate 		if (g == grp) {
3927c478bd9Sstevel@tonic-gate 			fprintf(fph, "\n\
3937c478bd9Sstevel@tonic-gate extern int ipfrule_add_out_%s __P((void));\n\
3947c478bd9Sstevel@tonic-gate extern int ipfrule_remove_out_%s __P((void));\n",
3957c478bd9Sstevel@tonic-gate 				grp->fg_name, grp->fg_name);
3967c478bd9Sstevel@tonic-gate 		}
3977c478bd9Sstevel@tonic-gate 	}
3987c478bd9Sstevel@tonic-gate }
3997c478bd9Sstevel@tonic-gate 
emittail()4007c478bd9Sstevel@tonic-gate static void emittail()
4017c478bd9Sstevel@tonic-gate {
4027c478bd9Sstevel@tonic-gate 	frgroup_t *g;
4037c478bd9Sstevel@tonic-gate 
4047c478bd9Sstevel@tonic-gate 	fprintf(cfile, "\n\
4057c478bd9Sstevel@tonic-gate int ipfrule_add()\n\
4067c478bd9Sstevel@tonic-gate {\n\
4077c478bd9Sstevel@tonic-gate 	int err;\n\
4087c478bd9Sstevel@tonic-gate \n");
4097c478bd9Sstevel@tonic-gate 	for (g = groups; g != NULL; g = g->fg_next)
4107c478bd9Sstevel@tonic-gate 		fprintf(cfile, "\
4117c478bd9Sstevel@tonic-gate 	err = ipfrule_add_%s_%s();\n\
4127c478bd9Sstevel@tonic-gate 	if (err != 0)\n\
4137c478bd9Sstevel@tonic-gate 		return err;\n",
4147c478bd9Sstevel@tonic-gate 			(g->fg_flags & FR_INQUE) ? "in" : "out", g->fg_name);
4157c478bd9Sstevel@tonic-gate 	fprintf(cfile, "\
4167c478bd9Sstevel@tonic-gate 	return 0;\n");
4177c478bd9Sstevel@tonic-gate 	fprintf(cfile, "}\n\
4187c478bd9Sstevel@tonic-gate \n");
4197c478bd9Sstevel@tonic-gate 
4207c478bd9Sstevel@tonic-gate 	fprintf(cfile, "\n\
4217c478bd9Sstevel@tonic-gate int ipfrule_remove()\n\
4227c478bd9Sstevel@tonic-gate {\n\
4237c478bd9Sstevel@tonic-gate 	int err;\n\
4247c478bd9Sstevel@tonic-gate \n");
4257c478bd9Sstevel@tonic-gate 	for (g = groups; g != NULL; g = g->fg_next)
4267c478bd9Sstevel@tonic-gate 		fprintf(cfile, "\
4277c478bd9Sstevel@tonic-gate 	err = ipfrule_remove_%s_%s();\n\
4287c478bd9Sstevel@tonic-gate 	if (err != 0)\n\
4297c478bd9Sstevel@tonic-gate 		return err;\n",
4307c478bd9Sstevel@tonic-gate 			(g->fg_flags & FR_INQUE) ? "in" : "out", g->fg_name);
4317c478bd9Sstevel@tonic-gate 	fprintf(cfile, "\
4327c478bd9Sstevel@tonic-gate 	return 0;\n");
4337c478bd9Sstevel@tonic-gate 	fprintf(cfile, "}\n");
4347c478bd9Sstevel@tonic-gate }
4357c478bd9Sstevel@tonic-gate 
4367c478bd9Sstevel@tonic-gate 
emitGroup(num,dir,v,fr,group,incount,outcount)4377c478bd9Sstevel@tonic-gate static void emitGroup(num, dir, v, fr, group, incount, outcount)
4387c478bd9Sstevel@tonic-gate int num, dir;
4397c478bd9Sstevel@tonic-gate void *v;
4407c478bd9Sstevel@tonic-gate frentry_t *fr;
4417c478bd9Sstevel@tonic-gate char *group;
4427c478bd9Sstevel@tonic-gate u_int incount, outcount;
4437c478bd9Sstevel@tonic-gate {
4447c478bd9Sstevel@tonic-gate 	static FILE *fp = NULL;
4457c478bd9Sstevel@tonic-gate 	static int header[2] = { 0, 0 };
4467c478bd9Sstevel@tonic-gate 	static char egroup[FR_GROUPLEN] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
4477c478bd9Sstevel@tonic-gate 	static int openfunc = 0;
4487c478bd9Sstevel@tonic-gate 	static mc_t *n = NULL;
4497c478bd9Sstevel@tonic-gate 	static int sin = 0;
4507c478bd9Sstevel@tonic-gate 	frentry_t *f;
4517c478bd9Sstevel@tonic-gate 	frgroup_t *g;
4527c478bd9Sstevel@tonic-gate 	fripf_t *ipf;
4537c478bd9Sstevel@tonic-gate 	int i, in, j;
4547c478bd9Sstevel@tonic-gate 	mc_t *m = v;
4557c478bd9Sstevel@tonic-gate 
4567c478bd9Sstevel@tonic-gate 	if (fp == NULL)
4577c478bd9Sstevel@tonic-gate 		fp = cfile;
4587c478bd9Sstevel@tonic-gate 	if (fp == NULL)
4597c478bd9Sstevel@tonic-gate 		return;
4607c478bd9Sstevel@tonic-gate 	if (strncmp(egroup, group, FR_GROUPLEN)) {
4617c478bd9Sstevel@tonic-gate 		for (sin--; sin > 0; sin--) {
4627c478bd9Sstevel@tonic-gate 			indent(fp, sin);
4637c478bd9Sstevel@tonic-gate 			fprintf(fp, "}\n");
4647c478bd9Sstevel@tonic-gate 		}
4657c478bd9Sstevel@tonic-gate 		if (openfunc == 1) {
4667c478bd9Sstevel@tonic-gate 			fprintf(fp, "\treturn fr;\n}\n");
4677c478bd9Sstevel@tonic-gate 			openfunc = 0;
4687c478bd9Sstevel@tonic-gate 			if (n != NULL) {
4697c478bd9Sstevel@tonic-gate 				free(n);
4707c478bd9Sstevel@tonic-gate 				n = NULL;
4717c478bd9Sstevel@tonic-gate 			}
4727c478bd9Sstevel@tonic-gate 		}
4737c478bd9Sstevel@tonic-gate 		sin = 0;
4747c478bd9Sstevel@tonic-gate 		header[0] = 0;
4757c478bd9Sstevel@tonic-gate 		header[1] = 0;
4767c478bd9Sstevel@tonic-gate 		strncpy(egroup, group, FR_GROUPLEN);
4777c478bd9Sstevel@tonic-gate 	} else if (openfunc == 1 && num < 0) {
4787c478bd9Sstevel@tonic-gate 		if (n != NULL) {
4797c478bd9Sstevel@tonic-gate 			free(n);
4807c478bd9Sstevel@tonic-gate 			n = NULL;
4817c478bd9Sstevel@tonic-gate 		}
4827c478bd9Sstevel@tonic-gate 		for (sin--; sin > 0; sin--) {
4837c478bd9Sstevel@tonic-gate 			indent(fp, sin);
4847c478bd9Sstevel@tonic-gate 			fprintf(fp, "}\n");
4857c478bd9Sstevel@tonic-gate 		}
4867c478bd9Sstevel@tonic-gate 		if (openfunc == 1) {
4877c478bd9Sstevel@tonic-gate 			fprintf(fp, "\treturn fr;\n}\n");
4887c478bd9Sstevel@tonic-gate 			openfunc = 0;
4897c478bd9Sstevel@tonic-gate 		}
4907c478bd9Sstevel@tonic-gate 	}
4917c478bd9Sstevel@tonic-gate 
4927c478bd9Sstevel@tonic-gate 	if (dir == -1)
4937c478bd9Sstevel@tonic-gate 		return;
4947c478bd9Sstevel@tonic-gate 
4957c478bd9Sstevel@tonic-gate 	for (g = groups; g != NULL; g = g->fg_next) {
4967c478bd9Sstevel@tonic-gate 		if (dir == 0 && (g->fg_flags & FR_INQUE) == 0)
4977c478bd9Sstevel@tonic-gate 			continue;
4987c478bd9Sstevel@tonic-gate 		else if (dir == 1 && (g->fg_flags & FR_OUTQUE) == 0)
4997c478bd9Sstevel@tonic-gate 			continue;
5007c478bd9Sstevel@tonic-gate 		if (strncmp(g->fg_name, group, FR_GROUPLEN) != 0)
5017c478bd9Sstevel@tonic-gate 			continue;
5027c478bd9Sstevel@tonic-gate 		break;
5037c478bd9Sstevel@tonic-gate 	}
5047c478bd9Sstevel@tonic-gate 
5057c478bd9Sstevel@tonic-gate 	/*
5067c478bd9Sstevel@tonic-gate 	 * Output the array of pointers to rules for this group.
5077c478bd9Sstevel@tonic-gate 	 */
5087c478bd9Sstevel@tonic-gate 	if (num == -2 && dir == 0 && header[0] == 0 && incount != 0) {
5097c478bd9Sstevel@tonic-gate 		fprintf(fp, "\nfrentry_t *ipf_rules_in_%s[%d] = {",
5107c478bd9Sstevel@tonic-gate 			group, incount);
5117c478bd9Sstevel@tonic-gate 		for (f = g->fg_start, i = 0; f != NULL; f = f->fr_next) {
5127c478bd9Sstevel@tonic-gate 			if ((f->fr_flags & FR_INQUE) == 0)
5137c478bd9Sstevel@tonic-gate 				continue;
5147c478bd9Sstevel@tonic-gate 			if ((i & 1) == 0) {
5157c478bd9Sstevel@tonic-gate 				fprintf(fp, "\n\t");
5167c478bd9Sstevel@tonic-gate 			}
5177c478bd9Sstevel@tonic-gate 			fprintf(fp,
5187c478bd9Sstevel@tonic-gate 				"(frentry_t *)&in_rule_%s_%d",
5197c478bd9Sstevel@tonic-gate 				f->fr_group, i);
5207c478bd9Sstevel@tonic-gate 			if (i + 1 < incount)
5217c478bd9Sstevel@tonic-gate 				fprintf(fp, ", ");
5227c478bd9Sstevel@tonic-gate 			i++;
5237c478bd9Sstevel@tonic-gate 		}
5247c478bd9Sstevel@tonic-gate 		fprintf(fp, "\n};\n");
5257c478bd9Sstevel@tonic-gate 	}
5267c478bd9Sstevel@tonic-gate 
5277c478bd9Sstevel@tonic-gate 	if (num == -2 && dir == 1 && header[1] == 0 && outcount != 0) {
5287c478bd9Sstevel@tonic-gate 		fprintf(fp, "\nfrentry_t *ipf_rules_out_%s[%d] = {",
5297c478bd9Sstevel@tonic-gate 			group, outcount);
5307c478bd9Sstevel@tonic-gate 		for (f = g->fg_start, i = 0; f != NULL; f = f->fr_next) {
5317c478bd9Sstevel@tonic-gate 			if ((f->fr_flags & FR_OUTQUE) == 0)
5327c478bd9Sstevel@tonic-gate 				continue;
5337c478bd9Sstevel@tonic-gate 			if ((i & 1) == 0) {
5347c478bd9Sstevel@tonic-gate 				fprintf(fp, "\n\t");
5357c478bd9Sstevel@tonic-gate 			}
5367c478bd9Sstevel@tonic-gate 			fprintf(fp,
5377c478bd9Sstevel@tonic-gate 				"(frentry_t *)&out_rule_%s_%d",
5387c478bd9Sstevel@tonic-gate 				f->fr_group, i);
5397c478bd9Sstevel@tonic-gate 			if (i + 1 < outcount)
5407c478bd9Sstevel@tonic-gate 				fprintf(fp, ", ");
5417c478bd9Sstevel@tonic-gate 			i++;
5427c478bd9Sstevel@tonic-gate 		}
5437c478bd9Sstevel@tonic-gate 		fprintf(fp, "\n};\n");
5447c478bd9Sstevel@tonic-gate 		fp = NULL;
5457c478bd9Sstevel@tonic-gate 	}
5467c478bd9Sstevel@tonic-gate 
5477c478bd9Sstevel@tonic-gate 	if (num < 0)
5487c478bd9Sstevel@tonic-gate 		return;
5497c478bd9Sstevel@tonic-gate 
5507c478bd9Sstevel@tonic-gate 	in = 0;
5517c478bd9Sstevel@tonic-gate 	ipf = fr->fr_ipf;
5527c478bd9Sstevel@tonic-gate 
5537c478bd9Sstevel@tonic-gate 	/*
5547c478bd9Sstevel@tonic-gate 	 * If the function header has not been printed then print it now.
5557c478bd9Sstevel@tonic-gate 	 */
5567c478bd9Sstevel@tonic-gate 	if (header[dir] == 0) {
5577c478bd9Sstevel@tonic-gate 		int pdst = 0, psrc = 0;
5587c478bd9Sstevel@tonic-gate 
5597c478bd9Sstevel@tonic-gate 		openfunc = 1;
5607c478bd9Sstevel@tonic-gate 		fprintf(fp, "\nfrentry_t *ipfrule_match_%s_%s(fin, passp)\n",
5617c478bd9Sstevel@tonic-gate 			(dir == 0) ? "in" : "out", group);
5627c478bd9Sstevel@tonic-gate 		fprintf(fp, "fr_info_t *fin;\n");
5637c478bd9Sstevel@tonic-gate 		fprintf(fp, "u_32_t *passp;\n");
5647c478bd9Sstevel@tonic-gate 		fprintf(fp, "{\n");
5657c478bd9Sstevel@tonic-gate 		fprintf(fp, "\tfrentry_t *fr = NULL;\n");
5667c478bd9Sstevel@tonic-gate 
5677c478bd9Sstevel@tonic-gate 		/*
5687c478bd9Sstevel@tonic-gate 		 * Print out any variables that need to be declared.
5697c478bd9Sstevel@tonic-gate 		 */
5707c478bd9Sstevel@tonic-gate 		for (f = g->fg_start, i = 0; f != NULL; f = f->fr_next) {
5717c478bd9Sstevel@tonic-gate 			if (incount + outcount > m[FRC_SRC].e + 1)
5727c478bd9Sstevel@tonic-gate 				psrc = 1;
5737c478bd9Sstevel@tonic-gate 			if (incount + outcount > m[FRC_DST].e + 1)
5747c478bd9Sstevel@tonic-gate 				pdst = 1;
5757c478bd9Sstevel@tonic-gate 		}
5767c478bd9Sstevel@tonic-gate 		if (psrc == 1)
5777c478bd9Sstevel@tonic-gate 			fprintf(fp, "\tu_32_t src = ntohl(%s);\n",
5787c478bd9Sstevel@tonic-gate 				"fin->fin_fi.fi_saddr");
5797c478bd9Sstevel@tonic-gate 		if (pdst == 1)
5807c478bd9Sstevel@tonic-gate 			fprintf(fp, "\tu_32_t dst = ntohl(%s);\n",
5817c478bd9Sstevel@tonic-gate 				"fin->fin_fi.fi_daddr");
5827c478bd9Sstevel@tonic-gate 	}
5837c478bd9Sstevel@tonic-gate 
5847c478bd9Sstevel@tonic-gate 	for (i = 0; i < FRC_MAX; i++) {
5857c478bd9Sstevel@tonic-gate 		switch(m[i].c)
5867c478bd9Sstevel@tonic-gate 		{
5877c478bd9Sstevel@tonic-gate 		case FRC_IFN :
5887c478bd9Sstevel@tonic-gate 			if (*fr->fr_ifname)
5897c478bd9Sstevel@tonic-gate 				m[i].s = 1;
5907c478bd9Sstevel@tonic-gate 			break;
5917c478bd9Sstevel@tonic-gate 		case FRC_V :
5927c478bd9Sstevel@tonic-gate 			if (ipf != NULL && ipf->fri_mip.fi_v != 0)
5937c478bd9Sstevel@tonic-gate 				m[i].s = 1;
5947c478bd9Sstevel@tonic-gate 			break;
5957c478bd9Sstevel@tonic-gate 		case FRC_FL :
5967c478bd9Sstevel@tonic-gate 			if (ipf != NULL && ipf->fri_mip.fi_flx != 0)
5977c478bd9Sstevel@tonic-gate 				m[i].s = 1;
5987c478bd9Sstevel@tonic-gate 			break;
5997c478bd9Sstevel@tonic-gate 		case FRC_P :
6007c478bd9Sstevel@tonic-gate 			if (ipf != NULL && ipf->fri_mip.fi_p != 0)
6017c478bd9Sstevel@tonic-gate 				m[i].s = 1;
6027c478bd9Sstevel@tonic-gate 			break;
6037c478bd9Sstevel@tonic-gate 		case FRC_TTL :
6047c478bd9Sstevel@tonic-gate 			if (ipf != NULL && ipf->fri_mip.fi_ttl != 0)
6057c478bd9Sstevel@tonic-gate 				m[i].s = 1;
6067c478bd9Sstevel@tonic-gate 			break;
6077c478bd9Sstevel@tonic-gate 		case FRC_TOS :
6087c478bd9Sstevel@tonic-gate 			if (ipf != NULL && ipf->fri_mip.fi_tos != 0)
6097c478bd9Sstevel@tonic-gate 				m[i].s = 1;
6107c478bd9Sstevel@tonic-gate 			break;
6117c478bd9Sstevel@tonic-gate 		case FRC_TCP :
6127c478bd9Sstevel@tonic-gate 			if (ipf == NULL)
6137c478bd9Sstevel@tonic-gate 				break;
6147c478bd9Sstevel@tonic-gate 			if ((ipf->fri_ip.fi_p == IPPROTO_TCP) &&
6157c478bd9Sstevel@tonic-gate 			    fr->fr_tcpfm != 0)
6167c478bd9Sstevel@tonic-gate 				m[i].s = 1;
6177c478bd9Sstevel@tonic-gate 			break;
6187c478bd9Sstevel@tonic-gate 		case FRC_SP :
6197c478bd9Sstevel@tonic-gate 			if (ipf == NULL)
6207c478bd9Sstevel@tonic-gate 				break;
6217c478bd9Sstevel@tonic-gate 			if (fr->fr_scmp == FR_INRANGE)
6227c478bd9Sstevel@tonic-gate 				m[i].s = 1;
6237c478bd9Sstevel@tonic-gate 			else if (fr->fr_scmp == FR_OUTRANGE)
6247c478bd9Sstevel@tonic-gate 				m[i].s = 1;
6257c478bd9Sstevel@tonic-gate 			else if (fr->fr_scmp != 0)
6267c478bd9Sstevel@tonic-gate 				m[i].s = 1;
6277c478bd9Sstevel@tonic-gate 			break;
6287c478bd9Sstevel@tonic-gate 		case FRC_DP :
6297c478bd9Sstevel@tonic-gate 			if (ipf == NULL)
6307c478bd9Sstevel@tonic-gate 				break;
6317c478bd9Sstevel@tonic-gate 			if (fr->fr_dcmp == FR_INRANGE)
6327c478bd9Sstevel@tonic-gate 				m[i].s = 1;
6337c478bd9Sstevel@tonic-gate 			else if (fr->fr_dcmp == FR_OUTRANGE)
6347c478bd9Sstevel@tonic-gate 				m[i].s = 1;
6357c478bd9Sstevel@tonic-gate 			else if (fr->fr_dcmp != 0)
6367c478bd9Sstevel@tonic-gate 				m[i].s = 1;
6377c478bd9Sstevel@tonic-gate 			break;
6387c478bd9Sstevel@tonic-gate 		case FRC_SRC :
6397c478bd9Sstevel@tonic-gate 			if (ipf == NULL)
6407c478bd9Sstevel@tonic-gate 				break;
6417c478bd9Sstevel@tonic-gate 			if (fr->fr_satype == FRI_LOOKUP) {
6427c478bd9Sstevel@tonic-gate 				;
6437c478bd9Sstevel@tonic-gate 			} else if ((fr->fr_smask != 0) ||
6447c478bd9Sstevel@tonic-gate 				   (fr->fr_flags & FR_NOTSRCIP) != 0)
6457c478bd9Sstevel@tonic-gate 				m[i].s = 1;
6467c478bd9Sstevel@tonic-gate 			break;
6477c478bd9Sstevel@tonic-gate 		case FRC_DST :
6487c478bd9Sstevel@tonic-gate 			if (ipf == NULL)
6497c478bd9Sstevel@tonic-gate 				break;
6507c478bd9Sstevel@tonic-gate 			if (fr->fr_datype == FRI_LOOKUP) {
6517c478bd9Sstevel@tonic-gate 				;
6527c478bd9Sstevel@tonic-gate 			} else if ((fr->fr_dmask != 0) ||
6537c478bd9Sstevel@tonic-gate 				   (fr->fr_flags & FR_NOTDSTIP) != 0)
6547c478bd9Sstevel@tonic-gate 				m[i].s = 1;
6557c478bd9Sstevel@tonic-gate 			break;
6567c478bd9Sstevel@tonic-gate 		case FRC_OPT :
6577c478bd9Sstevel@tonic-gate 			if (ipf == NULL)
6587c478bd9Sstevel@tonic-gate 				break;
6597c478bd9Sstevel@tonic-gate 			if (fr->fr_optmask != 0)
6607c478bd9Sstevel@tonic-gate 				m[i].s = 1;
6617c478bd9Sstevel@tonic-gate 			break;
6627c478bd9Sstevel@tonic-gate 		case FRC_SEC :
6637c478bd9Sstevel@tonic-gate 			if (ipf == NULL)
6647c478bd9Sstevel@tonic-gate 				break;
6657c478bd9Sstevel@tonic-gate 			if (fr->fr_secmask != 0)
6667c478bd9Sstevel@tonic-gate 				m[i].s = 1;
6677c478bd9Sstevel@tonic-gate 			break;
6687c478bd9Sstevel@tonic-gate 		case FRC_ATH :
6697c478bd9Sstevel@tonic-gate 			if (ipf == NULL)
6707c478bd9Sstevel@tonic-gate 				break;
6717c478bd9Sstevel@tonic-gate 			if (fr->fr_authmask != 0)
6727c478bd9Sstevel@tonic-gate 				m[i].s = 1;
6737c478bd9Sstevel@tonic-gate 			break;
6747c478bd9Sstevel@tonic-gate 		case FRC_ICT :
6757c478bd9Sstevel@tonic-gate 			if (ipf == NULL)
6767c478bd9Sstevel@tonic-gate 				break;
6777c478bd9Sstevel@tonic-gate 			if ((fr->fr_icmpm & 0xff00) != 0)
6787c478bd9Sstevel@tonic-gate 				m[i].s = 1;
6797c478bd9Sstevel@tonic-gate 			break;
6807c478bd9Sstevel@tonic-gate 		case FRC_ICC :
6817c478bd9Sstevel@tonic-gate 			if (ipf == NULL)
6827c478bd9Sstevel@tonic-gate 				break;
6837c478bd9Sstevel@tonic-gate 			if ((fr->fr_icmpm & 0xff) != 0)
6847c478bd9Sstevel@tonic-gate 				m[i].s = 1;
6857c478bd9Sstevel@tonic-gate 			break;
6867c478bd9Sstevel@tonic-gate 		}
6877c478bd9Sstevel@tonic-gate 	}
6887c478bd9Sstevel@tonic-gate 
6897c478bd9Sstevel@tonic-gate 	if (!header[dir]) {
6907c478bd9Sstevel@tonic-gate 		fprintf(fp, "\n");
6917c478bd9Sstevel@tonic-gate 		header[dir] = 1;
6927c478bd9Sstevel@tonic-gate 		sin = 0;
6937c478bd9Sstevel@tonic-gate 	}
6947c478bd9Sstevel@tonic-gate 
6957c478bd9Sstevel@tonic-gate 	qsort(m, FRC_MAX, sizeof(mc_t), intcmp);
6967c478bd9Sstevel@tonic-gate 
6977c478bd9Sstevel@tonic-gate 	if (n) {
6987c478bd9Sstevel@tonic-gate 		/*
6997c478bd9Sstevel@tonic-gate 		 * Calculate the indentation interval upto the last common
7007c478bd9Sstevel@tonic-gate 		 * common comparison being made.
7017c478bd9Sstevel@tonic-gate 		 */
7027c478bd9Sstevel@tonic-gate 		for (i = 0, in = 1; i < FRC_MAX; i++) {
7037c478bd9Sstevel@tonic-gate 			if (n[i].c != m[i].c)
7047c478bd9Sstevel@tonic-gate 				break;
7057c478bd9Sstevel@tonic-gate 			if (n[i].s != m[i].s)
7067c478bd9Sstevel@tonic-gate 				break;
7077c478bd9Sstevel@tonic-gate 			if (n[i].s) {
7087c478bd9Sstevel@tonic-gate 				if (n[i].n && (n[i].n > n[i].e)) {
7097c478bd9Sstevel@tonic-gate 					m[i].p++;
7107c478bd9Sstevel@tonic-gate 					in += m[i].p;
7117c478bd9Sstevel@tonic-gate 					break;
7127c478bd9Sstevel@tonic-gate 				}
7137c478bd9Sstevel@tonic-gate 				if (n[i].e > 0) {
7147c478bd9Sstevel@tonic-gate 					in++;
7157c478bd9Sstevel@tonic-gate 				} else
7167c478bd9Sstevel@tonic-gate 					break;
7177c478bd9Sstevel@tonic-gate 			}
7187c478bd9Sstevel@tonic-gate 		}
7197c478bd9Sstevel@tonic-gate 		if (sin != in) {
7207c478bd9Sstevel@tonic-gate 			for (j = sin - 1; j >= in; j--) {
7217c478bd9Sstevel@tonic-gate 				indent(fp, j);
7227c478bd9Sstevel@tonic-gate 				fprintf(fp, "}\n");
7237c478bd9Sstevel@tonic-gate 			}
7247c478bd9Sstevel@tonic-gate 		}
7257c478bd9Sstevel@tonic-gate 	} else {
7267c478bd9Sstevel@tonic-gate 		in = 1;
7277c478bd9Sstevel@tonic-gate 		i = 0;
7287c478bd9Sstevel@tonic-gate 	}
7297c478bd9Sstevel@tonic-gate 
7307c478bd9Sstevel@tonic-gate 	/*
7317c478bd9Sstevel@tonic-gate 	 * print out C code that implements a filter rule.
732ab25eeb5Syz 	 */
7337c478bd9Sstevel@tonic-gate 	for (; i < FRC_MAX; i++) {
7347c478bd9Sstevel@tonic-gate 		switch(m[i].c)
7357c478bd9Sstevel@tonic-gate 		{
7367c478bd9Sstevel@tonic-gate 		case FRC_IFN :
7377c478bd9Sstevel@tonic-gate 			if (m[i].s) {
7387c478bd9Sstevel@tonic-gate 				indent(fp, in);
7397c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (fin->fin_ifp == ");
7407c478bd9Sstevel@tonic-gate 				fprintf(fp, "ipf_rules_%s_%s[%d]->fr_ifa) {\n",
7417c478bd9Sstevel@tonic-gate 					dir ? "out" : "in", group, num);
7427c478bd9Sstevel@tonic-gate 				in++;
7437c478bd9Sstevel@tonic-gate 			}
7447c478bd9Sstevel@tonic-gate 			break;
7457c478bd9Sstevel@tonic-gate 		case FRC_V :
7467c478bd9Sstevel@tonic-gate 			if (m[i].s) {
7477c478bd9Sstevel@tonic-gate 				indent(fp, in);
7487c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (fin->fin_v == %d) {\n",
7497c478bd9Sstevel@tonic-gate 					ipf->fri_ip.fi_v);
7507c478bd9Sstevel@tonic-gate 				in++;
7517c478bd9Sstevel@tonic-gate 			}
7527c478bd9Sstevel@tonic-gate 			break;
7537c478bd9Sstevel@tonic-gate 		case FRC_FL :
7547c478bd9Sstevel@tonic-gate 			if (m[i].s) {
7557c478bd9Sstevel@tonic-gate 				indent(fp, in);
7567c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (");
7577c478bd9Sstevel@tonic-gate 				printeq(fp, "fin->fin_flx",
7587c478bd9Sstevel@tonic-gate 				        ipf->fri_mip.fi_flx, 0xf,
7597c478bd9Sstevel@tonic-gate 					ipf->fri_ip.fi_flx);
7607c478bd9Sstevel@tonic-gate 				in++;
7617c478bd9Sstevel@tonic-gate 			}
7627c478bd9Sstevel@tonic-gate 			break;
7637c478bd9Sstevel@tonic-gate 		case FRC_P :
7647c478bd9Sstevel@tonic-gate 			if (m[i].s) {
7657c478bd9Sstevel@tonic-gate 				indent(fp, in);
7667c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (fin->fin_p == %d) {\n",
7677c478bd9Sstevel@tonic-gate 					ipf->fri_ip.fi_p);
7687c478bd9Sstevel@tonic-gate 				in++;
7697c478bd9Sstevel@tonic-gate 			}
7707c478bd9Sstevel@tonic-gate 			break;
7717c478bd9Sstevel@tonic-gate 		case FRC_TTL :
7727c478bd9Sstevel@tonic-gate 			if (m[i].s) {
7737c478bd9Sstevel@tonic-gate 				indent(fp, in);
7747c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (");
7757c478bd9Sstevel@tonic-gate 				printeq(fp, "fin->fin_ttl",
7767c478bd9Sstevel@tonic-gate 					ipf->fri_mip.fi_ttl, 0xff,
7777c478bd9Sstevel@tonic-gate 					ipf->fri_ip.fi_ttl);
7787c478bd9Sstevel@tonic-gate 				in++;
7797c478bd9Sstevel@tonic-gate 			}
7807c478bd9Sstevel@tonic-gate 			break;
7817c478bd9Sstevel@tonic-gate 		case FRC_TOS :
7827c478bd9Sstevel@tonic-gate 			if (m[i].s) {
7837c478bd9Sstevel@tonic-gate 				indent(fp, in);
7847c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (fin->fin_tos");
7857c478bd9Sstevel@tonic-gate 				printeq(fp, "fin->fin_tos",
7867c478bd9Sstevel@tonic-gate 					ipf->fri_mip.fi_tos, 0xff,
7877c478bd9Sstevel@tonic-gate 					ipf->fri_ip.fi_tos);
7887c478bd9Sstevel@tonic-gate 				in++;
7897c478bd9Sstevel@tonic-gate 			}
7907c478bd9Sstevel@tonic-gate 			break;
7917c478bd9Sstevel@tonic-gate 		case FRC_TCP :
7927c478bd9Sstevel@tonic-gate 			if (m[i].s) {
7937c478bd9Sstevel@tonic-gate 				indent(fp, in);
7947c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (");
7957c478bd9Sstevel@tonic-gate 				printeq(fp, "fin->fin_tcpf", fr->fr_tcpfm,
7967c478bd9Sstevel@tonic-gate 					0xff, fr->fr_tcpf);
7977c478bd9Sstevel@tonic-gate 				in++;
7987c478bd9Sstevel@tonic-gate 			}
7997c478bd9Sstevel@tonic-gate 			break;
8007c478bd9Sstevel@tonic-gate 		case FRC_SP :
8017c478bd9Sstevel@tonic-gate 			if (!m[i].s)
8027c478bd9Sstevel@tonic-gate 				break;
8037c478bd9Sstevel@tonic-gate 			if (fr->fr_scmp == FR_INRANGE) {
8047c478bd9Sstevel@tonic-gate 				indent(fp, in);
8057c478bd9Sstevel@tonic-gate 				fprintf(fp, "if ((fin->fin_data[0] > %d) && ",
8067c478bd9Sstevel@tonic-gate 					fr->fr_sport);
8077c478bd9Sstevel@tonic-gate 				fprintf(fp, "(fin->fin_data[0] < %d)",
8087c478bd9Sstevel@tonic-gate 					fr->fr_stop);
8097c478bd9Sstevel@tonic-gate 				fprintf(fp, ") {\n");
8107c478bd9Sstevel@tonic-gate 				in++;
8117c478bd9Sstevel@tonic-gate 			} else if (fr->fr_scmp == FR_OUTRANGE) {
8127c478bd9Sstevel@tonic-gate 				indent(fp, in);
8137c478bd9Sstevel@tonic-gate 				fprintf(fp, "if ((fin->fin_data[0] < %d) || ",
8147c478bd9Sstevel@tonic-gate 					fr->fr_sport);
8157c478bd9Sstevel@tonic-gate 				fprintf(fp, "(fin->fin_data[0] > %d)",
8167c478bd9Sstevel@tonic-gate 					fr->fr_stop);
8177c478bd9Sstevel@tonic-gate 				fprintf(fp, ") {\n");
8187c478bd9Sstevel@tonic-gate 				in++;
8197c478bd9Sstevel@tonic-gate 			} else if (fr->fr_scmp) {
8207c478bd9Sstevel@tonic-gate 				indent(fp, in);
8217c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (fin->fin_data[0] %s %d)",
8227c478bd9Sstevel@tonic-gate 					portcmp[fr->fr_scmp], fr->fr_sport);
8237c478bd9Sstevel@tonic-gate 				fprintf(fp, " {\n");
8247c478bd9Sstevel@tonic-gate 				in++;
8257c478bd9Sstevel@tonic-gate 			}
8267c478bd9Sstevel@tonic-gate 			break;
8277c478bd9Sstevel@tonic-gate 		case FRC_DP :
8287c478bd9Sstevel@tonic-gate 			if (!m[i].s)
8297c478bd9Sstevel@tonic-gate 				break;
8307c478bd9Sstevel@tonic-gate 			if (fr->fr_dcmp == FR_INRANGE) {
8317c478bd9Sstevel@tonic-gate 				indent(fp, in);
8327c478bd9Sstevel@tonic-gate 				fprintf(fp, "if ((fin->fin_data[1] > %d) && ",
8337c478bd9Sstevel@tonic-gate 					fr->fr_dport);
8347c478bd9Sstevel@tonic-gate 				fprintf(fp, "(fin->fin_data[1] < %d)",
8357c478bd9Sstevel@tonic-gate 					fr->fr_dtop);
8367c478bd9Sstevel@tonic-gate 				fprintf(fp, ") {\n");
8377c478bd9Sstevel@tonic-gate 				in++;
8387c478bd9Sstevel@tonic-gate 			} else if (fr->fr_dcmp == FR_OUTRANGE) {
8397c478bd9Sstevel@tonic-gate 				indent(fp, in);
8407c478bd9Sstevel@tonic-gate 				fprintf(fp, "if ((fin->fin_data[1] < %d) || ",
8417c478bd9Sstevel@tonic-gate 					fr->fr_dport);
8427c478bd9Sstevel@tonic-gate 				fprintf(fp, "(fin->fin_data[1] > %d)",
8437c478bd9Sstevel@tonic-gate 					fr->fr_dtop);
8447c478bd9Sstevel@tonic-gate 				fprintf(fp, ") {\n");
8457c478bd9Sstevel@tonic-gate 				in++;
8467c478bd9Sstevel@tonic-gate 			} else if (fr->fr_dcmp) {
8477c478bd9Sstevel@tonic-gate 				indent(fp, in);
8487c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (fin->fin_data[1] %s %d)",
8497c478bd9Sstevel@tonic-gate 					portcmp[fr->fr_dcmp], fr->fr_dport);
8507c478bd9Sstevel@tonic-gate 				fprintf(fp, " {\n");
8517c478bd9Sstevel@tonic-gate 				in++;
8527c478bd9Sstevel@tonic-gate 			}
8537c478bd9Sstevel@tonic-gate 			break;
8547c478bd9Sstevel@tonic-gate 		case FRC_SRC :
8557c478bd9Sstevel@tonic-gate 			if (!m[i].s)
8567c478bd9Sstevel@tonic-gate 				break;
8577c478bd9Sstevel@tonic-gate 			if (fr->fr_satype == FRI_LOOKUP) {
8587c478bd9Sstevel@tonic-gate 				;
8597c478bd9Sstevel@tonic-gate 			} else if ((fr->fr_smask != 0) ||
8607c478bd9Sstevel@tonic-gate 				   (fr->fr_flags & FR_NOTSRCIP) != 0) {
8617c478bd9Sstevel@tonic-gate 				indent(fp, in);
8627c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (");
8637c478bd9Sstevel@tonic-gate 				printipeq(fp, "src",
8647c478bd9Sstevel@tonic-gate 					  fr->fr_flags & FR_NOTSRCIP,
8657c478bd9Sstevel@tonic-gate 					  fr->fr_smask, fr->fr_saddr);
8667c478bd9Sstevel@tonic-gate 				in++;
8677c478bd9Sstevel@tonic-gate 			}
8687c478bd9Sstevel@tonic-gate 			break;
8697c478bd9Sstevel@tonic-gate 		case FRC_DST :
8707c478bd9Sstevel@tonic-gate 			if (!m[i].s)
8717c478bd9Sstevel@tonic-gate 				break;
8727c478bd9Sstevel@tonic-gate 			if (fr->fr_datype == FRI_LOOKUP) {
8737c478bd9Sstevel@tonic-gate 				;
8747c478bd9Sstevel@tonic-gate 			} else if ((fr->fr_dmask != 0) ||
8757c478bd9Sstevel@tonic-gate 				   (fr->fr_flags & FR_NOTDSTIP) != 0) {
8767c478bd9Sstevel@tonic-gate 				indent(fp, in);
8777c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (");
8787c478bd9Sstevel@tonic-gate 				printipeq(fp, "dst",
8797c478bd9Sstevel@tonic-gate 					  fr->fr_flags & FR_NOTDSTIP,
8807c478bd9Sstevel@tonic-gate 					  fr->fr_dmask, fr->fr_daddr);
8817c478bd9Sstevel@tonic-gate 				in++;
8827c478bd9Sstevel@tonic-gate 			}
8837c478bd9Sstevel@tonic-gate 			break;
8847c478bd9Sstevel@tonic-gate 		case FRC_OPT :
8857c478bd9Sstevel@tonic-gate 			if (m[i].s) {
8867c478bd9Sstevel@tonic-gate 				indent(fp, in);
8877c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (");
8887c478bd9Sstevel@tonic-gate 				printeq(fp, "fin->fin_fi.fi_optmsk",
8897c478bd9Sstevel@tonic-gate 					fr->fr_optmask, 0xffffffff,
8907c478bd9Sstevel@tonic-gate 				        fr->fr_optbits);
8917c478bd9Sstevel@tonic-gate 				in++;
8927c478bd9Sstevel@tonic-gate 			}
8937c478bd9Sstevel@tonic-gate 			break;
8947c478bd9Sstevel@tonic-gate 		case FRC_SEC :
8957c478bd9Sstevel@tonic-gate 			if (m[i].s) {
8967c478bd9Sstevel@tonic-gate 				indent(fp, in);
8977c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (");
8987c478bd9Sstevel@tonic-gate 				printeq(fp, "fin->fin_fi.fi_secmsk",
8997c478bd9Sstevel@tonic-gate 					fr->fr_secmask, 0xffff,
9007c478bd9Sstevel@tonic-gate 					fr->fr_secbits);
9017c478bd9Sstevel@tonic-gate 				in++;
9027c478bd9Sstevel@tonic-gate 			}
9037c478bd9Sstevel@tonic-gate 			break;
9047c478bd9Sstevel@tonic-gate 		case FRC_ATH :
9057c478bd9Sstevel@tonic-gate 			if (m[i].s) {
9067c478bd9Sstevel@tonic-gate 				indent(fp, in);
9077c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (");
9087c478bd9Sstevel@tonic-gate 				printeq(fp, "fin->fin_fi.fi_authmsk",
9097c478bd9Sstevel@tonic-gate 					fr->fr_authmask, 0xffff,
9107c478bd9Sstevel@tonic-gate 					fr->fr_authbits);
9117c478bd9Sstevel@tonic-gate 				in++;
9127c478bd9Sstevel@tonic-gate 			}
9137c478bd9Sstevel@tonic-gate 			break;
9147c478bd9Sstevel@tonic-gate 		case FRC_ICT :
9157c478bd9Sstevel@tonic-gate 			if (m[i].s) {
9167c478bd9Sstevel@tonic-gate 				indent(fp, in);
9177c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (");
9187c478bd9Sstevel@tonic-gate 				printeq(fp, "fin->fin_data[0]",
9197c478bd9Sstevel@tonic-gate 					fr->fr_icmpm & 0xff00, 0xffff,
9207c478bd9Sstevel@tonic-gate 					fr->fr_icmp & 0xff00);
9217c478bd9Sstevel@tonic-gate 				in++;
9227c478bd9Sstevel@tonic-gate 			}
9237c478bd9Sstevel@tonic-gate 			break;
9247c478bd9Sstevel@tonic-gate 		case FRC_ICC :
9257c478bd9Sstevel@tonic-gate 			if (m[i].s) {
9267c478bd9Sstevel@tonic-gate 				indent(fp, in);
9277c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (");
9287c478bd9Sstevel@tonic-gate 				printeq(fp, "fin->fin_data[0]",
9297c478bd9Sstevel@tonic-gate 					fr->fr_icmpm & 0xff, 0xffff,
9307c478bd9Sstevel@tonic-gate 					fr->fr_icmp & 0xff);
9317c478bd9Sstevel@tonic-gate 				in++;
9327c478bd9Sstevel@tonic-gate 			}
9337c478bd9Sstevel@tonic-gate 			break;
9347c478bd9Sstevel@tonic-gate 		}
9357c478bd9Sstevel@tonic-gate 
9367c478bd9Sstevel@tonic-gate 	}
9377c478bd9Sstevel@tonic-gate 
9387c478bd9Sstevel@tonic-gate 	indent(fp, in);
9397c478bd9Sstevel@tonic-gate 	if (fr->fr_flags & FR_QUICK) {
9407c478bd9Sstevel@tonic-gate 		fprintf(fp, "return (frentry_t *)&%s_rule_%s_%d;\n",
9417c478bd9Sstevel@tonic-gate 			fr->fr_flags & FR_INQUE ? "in" : "out",
9427c478bd9Sstevel@tonic-gate 			fr->fr_group, num);
9437c478bd9Sstevel@tonic-gate 	} else {
9447c478bd9Sstevel@tonic-gate 		fprintf(fp, "fr = (frentry_t *)&%s_rule_%s_%d;\n",
9457c478bd9Sstevel@tonic-gate 			fr->fr_flags & FR_INQUE ? "in" : "out",
9467c478bd9Sstevel@tonic-gate 			fr->fr_group, num);
9477c478bd9Sstevel@tonic-gate 	}
94834ef97d0Sjojemann 	if (n == NULL) {
9497c478bd9Sstevel@tonic-gate 		n = (mc_t *)malloc(sizeof(*n) * FRC_MAX);
95034ef97d0Sjojemann 		if (n == NULL) {
95134ef97d0Sjojemann 			fprintf(stderr, "out of memory\n");
95234ef97d0Sjojemann 			exit(1);
95334ef97d0Sjojemann 		}
95434ef97d0Sjojemann 	}
9557c478bd9Sstevel@tonic-gate 	bcopy((char *)m, (char *)n, sizeof(*n) * FRC_MAX);
9567c478bd9Sstevel@tonic-gate 	sin = in;
9577c478bd9Sstevel@tonic-gate }
9587c478bd9Sstevel@tonic-gate 
9597c478bd9Sstevel@tonic-gate 
printC(dir)9607c478bd9Sstevel@tonic-gate void printC(dir)
9617c478bd9Sstevel@tonic-gate int dir;
9627c478bd9Sstevel@tonic-gate {
9637c478bd9Sstevel@tonic-gate 	static mc_t *m = NULL;
9647c478bd9Sstevel@tonic-gate 	frgroup_t *g;
9657c478bd9Sstevel@tonic-gate 
96634ef97d0Sjojemann 	if (m == NULL) {
9677c478bd9Sstevel@tonic-gate 		m = (mc_t *)calloc(1, sizeof(*m) * FRC_MAX);
96834ef97d0Sjojemann 		if (m == NULL) {
96934ef97d0Sjojemann 			fprintf(stderr, "out of memory\n");
97034ef97d0Sjojemann 			exit(1);
97134ef97d0Sjojemann 		}
97234ef97d0Sjojemann 	}
9737c478bd9Sstevel@tonic-gate 
9747c478bd9Sstevel@tonic-gate 	for (g = groups; g != NULL; g = g->fg_next) {
9757c478bd9Sstevel@tonic-gate 		if ((dir == 0) && ((g->fg_flags