xref: /titanic_53/usr/src/cmd/ipf/tools/ipfcomp.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * Copyright (C) 1993-2001 by Darren Reed.
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * See the IPFILTER.LICENCE file for details on licencing.
5*7c478bd9Sstevel@tonic-gate  */
6*7c478bd9Sstevel@tonic-gate #if !defined(lint)
7*7c478bd9Sstevel@tonic-gate static const char sccsid[] = "@(#)ip_fil.c	2.41 6/5/96 (C) 1993-2000 Darren Reed";
8*7c478bd9Sstevel@tonic-gate static const char rcsid[] = "@(#)$Id: ipfcomp.c,v 1.19 2003/04/09 19:04:33 darrenr Exp $";
9*7c478bd9Sstevel@tonic-gate #endif
10*7c478bd9Sstevel@tonic-gate 
11*7c478bd9Sstevel@tonic-gate #include "ipf.h"
12*7c478bd9Sstevel@tonic-gate 
13*7c478bd9Sstevel@tonic-gate 
14*7c478bd9Sstevel@tonic-gate typedef struct {
15*7c478bd9Sstevel@tonic-gate 	int c;
16*7c478bd9Sstevel@tonic-gate 	int e;
17*7c478bd9Sstevel@tonic-gate 	int n;
18*7c478bd9Sstevel@tonic-gate 	int p;
19*7c478bd9Sstevel@tonic-gate 	int s;
20*7c478bd9Sstevel@tonic-gate } mc_t;
21*7c478bd9Sstevel@tonic-gate 
22*7c478bd9Sstevel@tonic-gate 
23*7c478bd9Sstevel@tonic-gate static char *portcmp[] = { "*", "==", "!=", "<", ">", "<=", ">=", "**", "***" };
24*7c478bd9Sstevel@tonic-gate static int count = 0;
25*7c478bd9Sstevel@tonic-gate 
26*7c478bd9Sstevel@tonic-gate int intcmp __P((const void *, const void *));
27*7c478bd9Sstevel@tonic-gate static void indent __P((FILE *, int));
28*7c478bd9Sstevel@tonic-gate static void printeq __P((FILE *, char *, int, int, int));
29*7c478bd9Sstevel@tonic-gate static void printipeq __P((FILE *, char *, int, int, int));
30*7c478bd9Sstevel@tonic-gate static void addrule __P((FILE *, frentry_t *));
31*7c478bd9Sstevel@tonic-gate static void printhooks __P((FILE *, int, int, frgroup_t *));
32*7c478bd9Sstevel@tonic-gate static void emitheader __P((frgroup_t *, u_int, u_int));
33*7c478bd9Sstevel@tonic-gate static void emitGroup __P((int, int, void *, frentry_t *, char *,
34*7c478bd9Sstevel@tonic-gate 			   u_int, u_int));
35*7c478bd9Sstevel@tonic-gate static void emittail __P((void));
36*7c478bd9Sstevel@tonic-gate static void printCgroup __P((int, frentry_t *, mc_t *, char *));
37*7c478bd9Sstevel@tonic-gate 
38*7c478bd9Sstevel@tonic-gate #define	FRC_IFN	0
39*7c478bd9Sstevel@tonic-gate #define	FRC_V	1
40*7c478bd9Sstevel@tonic-gate #define	FRC_P	2
41*7c478bd9Sstevel@tonic-gate #define	FRC_FL	3
42*7c478bd9Sstevel@tonic-gate #define	FRC_TOS	4
43*7c478bd9Sstevel@tonic-gate #define	FRC_TTL	5
44*7c478bd9Sstevel@tonic-gate #define	FRC_SRC	6
45*7c478bd9Sstevel@tonic-gate #define	FRC_DST	7
46*7c478bd9Sstevel@tonic-gate #define	FRC_TCP	8
47*7c478bd9Sstevel@tonic-gate #define	FRC_SP	9
48*7c478bd9Sstevel@tonic-gate #define	FRC_DP	10
49*7c478bd9Sstevel@tonic-gate #define	FRC_OPT	11
50*7c478bd9Sstevel@tonic-gate #define	FRC_SEC	12
51*7c478bd9Sstevel@tonic-gate #define	FRC_ATH	13
52*7c478bd9Sstevel@tonic-gate #define	FRC_ICT	14
53*7c478bd9Sstevel@tonic-gate #define	FRC_ICC	15
54*7c478bd9Sstevel@tonic-gate #define	FRC_MAX	16
55*7c478bd9Sstevel@tonic-gate 
56*7c478bd9Sstevel@tonic-gate 
57*7c478bd9Sstevel@tonic-gate static	FILE	*cfile = NULL;
58*7c478bd9Sstevel@tonic-gate 
59*7c478bd9Sstevel@tonic-gate /*
60*7c478bd9Sstevel@tonic-gate  * This is called once per filter rule being loaded to emit data structures
61*7c478bd9Sstevel@tonic-gate  * required.
62*7c478bd9Sstevel@tonic-gate  */
63*7c478bd9Sstevel@tonic-gate void printc(fr)
64*7c478bd9Sstevel@tonic-gate frentry_t *fr;
65*7c478bd9Sstevel@tonic-gate {
66*7c478bd9Sstevel@tonic-gate 	fripf_t *ipf;
67*7c478bd9Sstevel@tonic-gate 	u_long *ulp;
68*7c478bd9Sstevel@tonic-gate 	char *and;
69*7c478bd9Sstevel@tonic-gate 	FILE *fp;
70*7c478bd9Sstevel@tonic-gate 	int i;
71*7c478bd9Sstevel@tonic-gate 
72*7c478bd9Sstevel@tonic-gate 	if (fr->fr_v != 4)
73*7c478bd9Sstevel@tonic-gate 		return;
74*7c478bd9Sstevel@tonic-gate 	if ((fr->fr_type != FR_T_IPF) && (fr->fr_type != FR_T_NONE))
75*7c478bd9Sstevel@tonic-gate 		return;
76*7c478bd9Sstevel@tonic-gate 	if ((fr->fr_type == FR_T_IPF) &&
77*7c478bd9Sstevel@tonic-gate 	    ((fr->fr_datype != FRI_NORMAL) || (fr->fr_satype != FRI_NORMAL)))
78*7c478bd9Sstevel@tonic-gate 		return;
79*7c478bd9Sstevel@tonic-gate 	ipf = fr->fr_ipf;
80*7c478bd9Sstevel@tonic-gate 
81*7c478bd9Sstevel@tonic-gate 	if (cfile == NULL)
82*7c478bd9Sstevel@tonic-gate 		cfile = fopen("ip_rules.c", "w");
83*7c478bd9Sstevel@tonic-gate 	if (cfile == NULL)
84*7c478bd9Sstevel@tonic-gate 		return;
85*7c478bd9Sstevel@tonic-gate 	fp = cfile;
86*7c478bd9Sstevel@tonic-gate 	if (count == 0) {
87*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "/*\n");
88*7c478bd9Sstevel@tonic-gate  		fprintf(fp, "* Copyright (C) 1993-2000 by Darren Reed.\n");
89*7c478bd9Sstevel@tonic-gate  		fprintf(fp, "*\n");
90*7c478bd9Sstevel@tonic-gate  		fprintf(fp, "* Redistribution and use in source and binary forms are permitted\n");
91*7c478bd9Sstevel@tonic-gate  		fprintf(fp, "* provided that this notice is preserved and due credit is given\n");
92*7c478bd9Sstevel@tonic-gate  		fprintf(fp, "* to the original author and the contributors.\n");
93*7c478bd9Sstevel@tonic-gate  		fprintf(fp, "*/\n\n");
94*7c478bd9Sstevel@tonic-gate 
95*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "#include <sys/types.h>\n");
96*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "#include <sys/time.h>\n");
97*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "#include <sys/socket.h>\n");
98*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "#include <sys/systm.h>\n");
99*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "#include <sys/errno.h>\n");
100*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "#include <sys/param.h>\n");
101*7c478bd9Sstevel@tonic-gate 		fprintf(fp,
102*7c478bd9Sstevel@tonic-gate "#if !defined(__SVR4) && !defined(__svr4__) && !defined(__hpux)\n");
103*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "# include <sys/mbuf.h>\n");
104*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "#endif\n");
105*7c478bd9Sstevel@tonic-gate 		fprintf(fp,
106*7c478bd9Sstevel@tonic-gate "#if defined(__FreeBSD__) && (__FreeBSD_version > 220000)\n");
107*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "# include <sys/sockio.h>\n");
108*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "#else\n");
109*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "# include <sys/ioctl.h>\n");
110*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "#endif /* FreeBSD */\n");
111*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "#include <net/if.h>\n");
112*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "#include <netinet/in.h>\n");
113*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "#include <netinet/in_systm.h>\n");
114*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "#include <netinet/ip.h>\n");
115*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "#include <netinet/tcp.h>\n");
116*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "#include \"ip_compat.h\"\n");
117*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "#include \"ip_fil.h\"\n\n");
118*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "#include \"ip_rules.h\"\n\n");
119*7c478bd9Sstevel@tonic-gate 	}
120*7c478bd9Sstevel@tonic-gate 
121*7c478bd9Sstevel@tonic-gate 	addrule(fp, fr);
122*7c478bd9Sstevel@tonic-gate 	fr->fr_type |= FR_T_BUILTIN;
123*7c478bd9Sstevel@tonic-gate 	and = "";
124*7c478bd9Sstevel@tonic-gate 	fr->fr_ref = 1;
125*7c478bd9Sstevel@tonic-gate 	i = sizeof(*fr);
126*7c478bd9Sstevel@tonic-gate 	if (i & -(1 - sizeof(*ulp)))
127*7c478bd9Sstevel@tonic-gate 		i += sizeof(u_long);
128*7c478bd9Sstevel@tonic-gate 	for (i /= sizeof(u_long), ulp = (u_long *)fr; i > 0; i--) {
129*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "%s%#lx", and, *ulp++);
130*7c478bd9Sstevel@tonic-gate 		and = ", ";
131*7c478bd9Sstevel@tonic-gate 	}
132*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "\n};\n");
133*7c478bd9Sstevel@tonic-gate 	fr->fr_type &= ~FR_T_BUILTIN;
134*7c478bd9Sstevel@tonic-gate 
135*7c478bd9Sstevel@tonic-gate 	count++;
136*7c478bd9Sstevel@tonic-gate 
137*7c478bd9Sstevel@tonic-gate 	fflush(fp);
138*7c478bd9Sstevel@tonic-gate }
139*7c478bd9Sstevel@tonic-gate 
140*7c478bd9Sstevel@tonic-gate 
141*7c478bd9Sstevel@tonic-gate static frgroup_t *groups = NULL;
142*7c478bd9Sstevel@tonic-gate 
143*7c478bd9Sstevel@tonic-gate 
144*7c478bd9Sstevel@tonic-gate static void addrule(fp, fr)
145*7c478bd9Sstevel@tonic-gate FILE *fp;
146*7c478bd9Sstevel@tonic-gate frentry_t *fr;
147*7c478bd9Sstevel@tonic-gate {
148*7c478bd9Sstevel@tonic-gate 	frentry_t *f, **fpp;
149*7c478bd9Sstevel@tonic-gate 	frgroup_t *g;
150*7c478bd9Sstevel@tonic-gate 	u_long *ulp;
151*7c478bd9Sstevel@tonic-gate 	char *and;
152*7c478bd9Sstevel@tonic-gate 	int i;
153*7c478bd9Sstevel@tonic-gate 
154*7c478bd9Sstevel@tonic-gate 	f = (frentry_t *)malloc(sizeof(*f));
155*7c478bd9Sstevel@tonic-gate 	bcopy((char *)fr, (char *)f, sizeof(*fr));
156*7c478bd9Sstevel@tonic-gate 	if (fr->fr_ipf) {
157*7c478bd9Sstevel@tonic-gate 		f->fr_ipf = (fripf_t *)malloc(sizeof(*f->fr_ipf));
158*7c478bd9Sstevel@tonic-gate 		bcopy((char *)fr->fr_ipf, (char *)f->fr_ipf,
159*7c478bd9Sstevel@tonic-gate 		      sizeof(*fr->fr_ipf));
160*7c478bd9Sstevel@tonic-gate 	}
161*7c478bd9Sstevel@tonic-gate 
162*7c478bd9Sstevel@tonic-gate 	f->fr_next = NULL;
163*7c478bd9Sstevel@tonic-gate 	for (g = groups; g != NULL; g = g->fg_next)
164*7c478bd9Sstevel@tonic-gate 		if ((strncmp(g->fg_name, f->fr_group, FR_GROUPLEN) == 0) &&
165*7c478bd9Sstevel@tonic-gate 		    (g->fg_flags == (f->fr_flags & FR_INOUT)))
166*7c478bd9Sstevel@tonic-gate 			break;
167*7c478bd9Sstevel@tonic-gate 
168*7c478bd9Sstevel@tonic-gate 	if (g == NULL) {
169*7c478bd9Sstevel@tonic-gate 		g = (frgroup_t *)calloc(1, sizeof(*g));
170*7c478bd9Sstevel@tonic-gate 		g->fg_next = groups;
171*7c478bd9Sstevel@tonic-gate 		groups = g;
172*7c478bd9Sstevel@tonic-gate 		g->fg_head = f;
173*7c478bd9Sstevel@tonic-gate 		bcopy(f->fr_group, g->fg_name, FR_GROUPLEN);
174*7c478bd9Sstevel@tonic-gate 		g->fg_ref = 0;
175*7c478bd9Sstevel@tonic-gate 		g->fg_flags = f->fr_flags & FR_INOUT;
176*7c478bd9Sstevel@tonic-gate 	}
177*7c478bd9Sstevel@tonic-gate 
178*7c478bd9Sstevel@tonic-gate 	for (fpp = &g->fg_start; *fpp != NULL; )
179*7c478bd9Sstevel@tonic-gate 		fpp = &((*fpp)->fr_next);
180*7c478bd9Sstevel@tonic-gate 	*fpp = f;
181*7c478bd9Sstevel@tonic-gate 
182*7c478bd9Sstevel@tonic-gate 	if (fr->fr_dsize > 0) {
183*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "\
184*7c478bd9Sstevel@tonic-gate static u_long ipf%s_rule_data_%s_%u[] = {\n",
185*7c478bd9Sstevel@tonic-gate 			f->fr_flags & FR_INQUE ? "in" : "out",
186*7c478bd9Sstevel@tonic-gate 			g->fg_name, g->fg_ref);
187*7c478bd9Sstevel@tonic-gate 		and = "";
188*7c478bd9Sstevel@tonic-gate 		i = fr->fr_dsize;
189*7c478bd9Sstevel@tonic-gate 		ulp = fr->fr_data;
190*7c478bd9Sstevel@tonic-gate 		for (i /= sizeof(u_long); i > 0; i--) {
191*7c478bd9Sstevel@tonic-gate 			fprintf(fp, "%s%#lx", and, *ulp++);
192*7c478bd9Sstevel@tonic-gate 			and = ", ";
193*7c478bd9Sstevel@tonic-gate 		}
194*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "\n};\n");
195*7c478bd9Sstevel@tonic-gate 	}
196*7c478bd9Sstevel@tonic-gate 
197*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "\nstatic u_long %s_rule_%s_%d[] = {\n",
198*7c478bd9Sstevel@tonic-gate 		f->fr_flags & FR_INQUE ? "in" : "out", g->fg_name, g->fg_ref);
199*7c478bd9Sstevel@tonic-gate 
200*7c478bd9Sstevel@tonic-gate 	g->fg_ref++;
201*7c478bd9Sstevel@tonic-gate 
202*7c478bd9Sstevel@tonic-gate 	if (f->fr_grhead != 0) {
203*7c478bd9Sstevel@tonic-gate 		for (g = groups; g != NULL; g = g->fg_next)
204*7c478bd9Sstevel@tonic-gate 			if ((strncmp(g->fg_name, f->fr_grhead,
205*7c478bd9Sstevel@tonic-gate 				     FR_GROUPLEN) == 0) &&
206*7c478bd9Sstevel@tonic-gate 			    g->fg_flags == (f->fr_flags & FR_INOUT))
207*7c478bd9Sstevel@tonic-gate 				break;
208*7c478bd9Sstevel@tonic-gate 		if (g == NULL) {
209*7c478bd9Sstevel@tonic-gate 			g = (frgroup_t *)calloc(1, sizeof(*g));
210*7c478bd9Sstevel@tonic-gate 			g->fg_next = groups;
211*7c478bd9Sstevel@tonic-gate 			groups = g;
212*7c478bd9Sstevel@tonic-gate 			g->fg_head = f;
213*7c478bd9Sstevel@tonic-gate 			bcopy(f->fr_grhead, g->fg_name, FR_GROUPLEN);
214*7c478bd9Sstevel@tonic-gate 			g->fg_ref = 0;
215*7c478bd9Sstevel@tonic-gate 			g->fg_flags = f->fr_flags & FR_INOUT;
216*7c478bd9Sstevel@tonic-gate 		}
217*7c478bd9Sstevel@tonic-gate 	}
218*7c478bd9Sstevel@tonic-gate }
219*7c478bd9Sstevel@tonic-gate 
220*7c478bd9Sstevel@tonic-gate 
221*7c478bd9Sstevel@tonic-gate int intcmp(c1, c2)
222*7c478bd9Sstevel@tonic-gate const void *c1, *c2;
223*7c478bd9Sstevel@tonic-gate {
224*7c478bd9Sstevel@tonic-gate 	const mc_t *i1 = (const mc_t *)c1, *i2 = (const mc_t *)c2;
225*7c478bd9Sstevel@tonic-gate 
226*7c478bd9Sstevel@tonic-gate 	if (i1->n == i2->n) {
227*7c478bd9Sstevel@tonic-gate 		return i1->c - i2->c;
228*7c478bd9Sstevel@tonic-gate 	}
229*7c478bd9Sstevel@tonic-gate 	return i2->n - i1->n;
230*7c478bd9Sstevel@tonic-gate }
231*7c478bd9Sstevel@tonic-gate 
232*7c478bd9Sstevel@tonic-gate 
233*7c478bd9Sstevel@tonic-gate static void indent(fp, in)
234*7c478bd9Sstevel@tonic-gate FILE *fp;
235*7c478bd9Sstevel@tonic-gate int in;
236*7c478bd9Sstevel@tonic-gate {
237*7c478bd9Sstevel@tonic-gate 	for (; in; in--)
238*7c478bd9Sstevel@tonic-gate 		fputc('\t', fp);
239*7c478bd9Sstevel@tonic-gate }
240*7c478bd9Sstevel@tonic-gate 
241*7c478bd9Sstevel@tonic-gate static void printeq(fp, var, m, max, v)
242*7c478bd9Sstevel@tonic-gate FILE *fp;
243*7c478bd9Sstevel@tonic-gate char *var;
244*7c478bd9Sstevel@tonic-gate int m, max, v;
245*7c478bd9Sstevel@tonic-gate {
246*7c478bd9Sstevel@tonic-gate 	if (m == max)
247*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "%s == %#x) {\n", var, v);
248*7c478bd9Sstevel@tonic-gate 	else
249*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "(%s & %#x) == %#x) {\n", var, m, v);
250*7c478bd9Sstevel@tonic-gate }
251*7c478bd9Sstevel@tonic-gate 
252*7c478bd9Sstevel@tonic-gate /*
253*7c478bd9Sstevel@tonic-gate  * Parameters: var - IP# being compared
254*7c478bd9Sstevel@tonic-gate  *             fl - 0 for positive match, 1 for negative match
255*7c478bd9Sstevel@tonic-gate  *             m - netmask
256*7c478bd9Sstevel@tonic-gate  *             v - required address
257*7c478bd9Sstevel@tonic-gate  */
258*7c478bd9Sstevel@tonic-gate static void printipeq(fp, var, fl, m, v)
259*7c478bd9Sstevel@tonic-gate FILE *fp;
260*7c478bd9Sstevel@tonic-gate char *var;
261*7c478bd9Sstevel@tonic-gate int fl, m, v;
262*7c478bd9Sstevel@tonic-gate {
263*7c478bd9Sstevel@tonic-gate 	if (m == 0xffffffff)
264*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "%s ", var);
265*7c478bd9Sstevel@tonic-gate 	else
266*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "(%s & %#x) ", var, m);
267*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "%c", fl ? '!' : '=');
268*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "= %#x) {\n", v);
269*7c478bd9Sstevel@tonic-gate }
270*7c478bd9Sstevel@tonic-gate 
271*7c478bd9Sstevel@tonic-gate 
272*7c478bd9Sstevel@tonic-gate void emit(num, dir, v, fr)
273*7c478bd9Sstevel@tonic-gate int num, dir;
274*7c478bd9Sstevel@tonic-gate void *v;
275*7c478bd9Sstevel@tonic-gate frentry_t *fr;
276*7c478bd9Sstevel@tonic-gate {
277*7c478bd9Sstevel@tonic-gate 	u_int incnt, outcnt;
278*7c478bd9Sstevel@tonic-gate 	frgroup_t *g;
279*7c478bd9Sstevel@tonic-gate 	frentry_t *f;
280*7c478bd9Sstevel@tonic-gate 
281*7c478bd9Sstevel@tonic-gate 	for (g = groups; g != NULL; g = g->fg_next) {
282*7c478bd9Sstevel@tonic-gate 		if (dir == 0 || dir == -1) {
283*7c478bd9Sstevel@tonic-gate 			if ((g->fg_flags & FR_INQUE) == 0)
284*7c478bd9Sstevel@tonic-gate 				continue;
285*7c478bd9Sstevel@tonic-gate 			for (incnt = 0, f = g->fg_start; f != NULL;
286*7c478bd9Sstevel@tonic-gate 			     f = f->fr_next)
287*7c478bd9Sstevel@tonic-gate 				incnt++;
288*7c478bd9Sstevel@tonic-gate 			emitGroup(num, dir, v, fr, g->fg_name, incnt, 0);
289*7c478bd9Sstevel@tonic-gate 		}
290*7c478bd9Sstevel@tonic-gate 		if (dir == 1 || dir == -1) {
291*7c478bd9Sstevel@tonic-gate 			if ((g->fg_flags & FR_OUTQUE) == 0)
292*7c478bd9Sstevel@tonic-gate 				continue;
293*7c478bd9Sstevel@tonic-gate 			for (outcnt = 0, f = g->fg_start; f != NULL;
294*7c478bd9Sstevel@tonic-gate 			     f = f->fr_next)
295*7c478bd9Sstevel@tonic-gate 				outcnt++;
296*7c478bd9Sstevel@tonic-gate 			emitGroup(num, dir, v, fr, g->fg_name, 0, outcnt);
297*7c478bd9Sstevel@tonic-gate 		}
298*7c478bd9Sstevel@tonic-gate 	}
299*7c478bd9Sstevel@tonic-gate 
300*7c478bd9Sstevel@tonic-gate 	if (num == -1 && dir == -1) {
301*7c478bd9Sstevel@tonic-gate 		for (g = groups; g != NULL; g = g->fg_next) {
302*7c478bd9Sstevel@tonic-gate 			if ((g->fg_flags & FR_INQUE) != 0) {
303*7c478bd9Sstevel@tonic-gate 				for (incnt = 0, f = g->fg_start; f != NULL;
304*7c478bd9Sstevel@tonic-gate 				     f = f->fr_next)
305*7c478bd9Sstevel@tonic-gate 					incnt++;
306*7c478bd9Sstevel@tonic-gate 				if (incnt > 0)
307*7c478bd9Sstevel@tonic-gate 					emitheader(g, incnt, 0);
308*7c478bd9Sstevel@tonic-gate 			}
309*7c478bd9Sstevel@tonic-gate 			if ((g->fg_flags & FR_OUTQUE) != 0) {
310*7c478bd9Sstevel@tonic-gate 				for (outcnt = 0, f = g->fg_start; f != NULL;
311*7c478bd9Sstevel@tonic-gate 				     f = f->fr_next)
312*7c478bd9Sstevel@tonic-gate 					outcnt++;
313*7c478bd9Sstevel@tonic-gate 				if (outcnt > 0)
314*7c478bd9Sstevel@tonic-gate 					emitheader(g, 0, outcnt);
315*7c478bd9Sstevel@tonic-gate 			}
316*7c478bd9Sstevel@tonic-gate 		}
317*7c478bd9Sstevel@tonic-gate 		emittail();
318*7c478bd9Sstevel@tonic-gate 	}
319*7c478bd9Sstevel@tonic-gate }
320*7c478bd9Sstevel@tonic-gate 
321*7c478bd9Sstevel@tonic-gate 
322*7c478bd9Sstevel@tonic-gate static void emitheader(grp, incount, outcount)
323*7c478bd9Sstevel@tonic-gate frgroup_t *grp;
324*7c478bd9Sstevel@tonic-gate u_int incount, outcount;
325*7c478bd9Sstevel@tonic-gate {
326*7c478bd9Sstevel@tonic-gate 	static FILE *fph = NULL;
327*7c478bd9Sstevel@tonic-gate 	frgroup_t *g;
328*7c478bd9Sstevel@tonic-gate 
329*7c478bd9Sstevel@tonic-gate 	if (fph == NULL) {
330*7c478bd9Sstevel@tonic-gate 		fph = fopen("ip_rules.h", "w");
331*7c478bd9Sstevel@tonic-gate 		if (fph == NULL)
332*7c478bd9Sstevel@tonic-gate 			return;
333*7c478bd9Sstevel@tonic-gate 
334*7c478bd9Sstevel@tonic-gate 		fprintf(fph, "extern int ipfrule_add __P((void));\n");
335*7c478bd9Sstevel@tonic-gate 		fprintf(fph, "extern int ipfrule_remove __P((void));\n");
336*7c478bd9Sstevel@tonic-gate 	}
337*7c478bd9Sstevel@tonic-gate 
338*7c478bd9Sstevel@tonic-gate 	printhooks(cfile, incount, outcount, grp);
339*7c478bd9Sstevel@tonic-gate 
340*7c478bd9Sstevel@tonic-gate 	if (incount) {
341*7c478bd9Sstevel@tonic-gate 		fprintf(fph, "\n\
342*7c478bd9Sstevel@tonic-gate extern frentry_t *ipfrule_match_in_%s __P((fr_info_t *, u_32_t *));\n\
343*7c478bd9Sstevel@tonic-gate extern frentry_t *ipf_rules_in_%s[%d];\n",
344*7c478bd9Sstevel@tonic-gate 			grp->fg_name, grp->fg_name, incount);
345*7c478bd9Sstevel@tonic-gate 
346*7c478bd9Sstevel@tonic-gate 		for (g = groups; g != grp; g = g->fg_next)
347*7c478bd9Sstevel@tonic-gate 			if ((strncmp(g->fg_name, grp->fg_name,
348*7c478bd9Sstevel@tonic-gate 				     FR_GROUPLEN) == 0) &&
349*7c478bd9Sstevel@tonic-gate 			    g->fg_flags == grp->fg_flags)
350*7c478bd9Sstevel@tonic-gate 				break;
351*7c478bd9Sstevel@tonic-gate 		if (g == grp) {
352*7c478bd9Sstevel@tonic-gate 			fprintf(fph, "\n\
353*7c478bd9Sstevel@tonic-gate extern int ipfrule_add_in_%s __P((void));\n\
354*7c478bd9Sstevel@tonic-gate extern int ipfrule_remove_in_%s __P((void));\n", grp->fg_name, grp->fg_name);
355*7c478bd9Sstevel@tonic-gate 		}
356*7c478bd9Sstevel@tonic-gate 	}
357*7c478bd9Sstevel@tonic-gate 	if (outcount) {
358*7c478bd9Sstevel@tonic-gate 		fprintf(fph, "\n\
359*7c478bd9Sstevel@tonic-gate extern frentry_t *ipfrule_match_out_%s __P((fr_info_t *, u_32_t *));\n\
360*7c478bd9Sstevel@tonic-gate extern frentry_t *ipf_rules_out_%s[%d];\n",
361*7c478bd9Sstevel@tonic-gate 			grp->fg_name, grp->fg_name, outcount);
362*7c478bd9Sstevel@tonic-gate 
363*7c478bd9Sstevel@tonic-gate 		for (g = groups; g != g; g = g->fg_next)
364*7c478bd9Sstevel@tonic-gate 			if ((strncmp(g->fg_name, grp->fg_name,
365*7c478bd9Sstevel@tonic-gate 				     FR_GROUPLEN) == 0) &&
366*7c478bd9Sstevel@tonic-gate 			    g->fg_flags == grp->fg_flags)
367*7c478bd9Sstevel@tonic-gate 				break;
368*7c478bd9Sstevel@tonic-gate 		if (g == grp) {
369*7c478bd9Sstevel@tonic-gate 			fprintf(fph, "\n\
370*7c478bd9Sstevel@tonic-gate extern int ipfrule_add_out_%s __P((void));\n\
371*7c478bd9Sstevel@tonic-gate extern int ipfrule_remove_out_%s __P((void));\n",
372*7c478bd9Sstevel@tonic-gate 				grp->fg_name, grp->fg_name);
373*7c478bd9Sstevel@tonic-gate 		}
374*7c478bd9Sstevel@tonic-gate 	}
375*7c478bd9Sstevel@tonic-gate }
376*7c478bd9Sstevel@tonic-gate 
377*7c478bd9Sstevel@tonic-gate static void emittail()
378*7c478bd9Sstevel@tonic-gate {
379*7c478bd9Sstevel@tonic-gate 	frgroup_t *g;
380*7c478bd9Sstevel@tonic-gate 
381*7c478bd9Sstevel@tonic-gate 	fprintf(cfile, "\n\
382*7c478bd9Sstevel@tonic-gate int ipfrule_add()\n\
383*7c478bd9Sstevel@tonic-gate {\n\
384*7c478bd9Sstevel@tonic-gate 	int err;\n\
385*7c478bd9Sstevel@tonic-gate \n");
386*7c478bd9Sstevel@tonic-gate 	for (g = groups; g != NULL; g = g->fg_next)
387*7c478bd9Sstevel@tonic-gate 		fprintf(cfile, "\
388*7c478bd9Sstevel@tonic-gate 	err = ipfrule_add_%s_%s();\n\
389*7c478bd9Sstevel@tonic-gate 	if (err != 0)\n\
390*7c478bd9Sstevel@tonic-gate 		return err;\n",
391*7c478bd9Sstevel@tonic-gate 			(g->fg_flags & FR_INQUE) ? "in" : "out", g->fg_name);
392*7c478bd9Sstevel@tonic-gate 	fprintf(cfile, "\
393*7c478bd9Sstevel@tonic-gate 	return 0;\n");
394*7c478bd9Sstevel@tonic-gate 	fprintf(cfile, "}\n\
395*7c478bd9Sstevel@tonic-gate \n");
396*7c478bd9Sstevel@tonic-gate 
397*7c478bd9Sstevel@tonic-gate 	fprintf(cfile, "\n\
398*7c478bd9Sstevel@tonic-gate int ipfrule_remove()\n\
399*7c478bd9Sstevel@tonic-gate {\n\
400*7c478bd9Sstevel@tonic-gate 	int err;\n\
401*7c478bd9Sstevel@tonic-gate \n");
402*7c478bd9Sstevel@tonic-gate 	for (g = groups; g != NULL; g = g->fg_next)
403*7c478bd9Sstevel@tonic-gate 		fprintf(cfile, "\
404*7c478bd9Sstevel@tonic-gate 	err = ipfrule_remove_%s_%s();\n\
405*7c478bd9Sstevel@tonic-gate 	if (err != 0)\n\
406*7c478bd9Sstevel@tonic-gate 		return err;\n",
407*7c478bd9Sstevel@tonic-gate 			(g->fg_flags & FR_INQUE) ? "in" : "out", g->fg_name);
408*7c478bd9Sstevel@tonic-gate 	fprintf(cfile, "\
409*7c478bd9Sstevel@tonic-gate 	return 0;\n");
410*7c478bd9Sstevel@tonic-gate 	fprintf(cfile, "}\n");
411*7c478bd9Sstevel@tonic-gate }
412*7c478bd9Sstevel@tonic-gate 
413*7c478bd9Sstevel@tonic-gate 
414*7c478bd9Sstevel@tonic-gate static void emitGroup(num, dir, v, fr, group, incount, outcount)
415*7c478bd9Sstevel@tonic-gate int num, dir;
416*7c478bd9Sstevel@tonic-gate void *v;
417*7c478bd9Sstevel@tonic-gate frentry_t *fr;
418*7c478bd9Sstevel@tonic-gate char *group;
419*7c478bd9Sstevel@tonic-gate u_int incount, outcount;
420*7c478bd9Sstevel@tonic-gate {
421*7c478bd9Sstevel@tonic-gate 	static FILE *fp = NULL;
422*7c478bd9Sstevel@tonic-gate 	static int header[2] = { 0, 0 };
423*7c478bd9Sstevel@tonic-gate 	static char egroup[FR_GROUPLEN] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
424*7c478bd9Sstevel@tonic-gate 	static int openfunc = 0;
425*7c478bd9Sstevel@tonic-gate 	static mc_t *n = NULL;
426*7c478bd9Sstevel@tonic-gate 	static int sin = 0;
427*7c478bd9Sstevel@tonic-gate 	frentry_t *f;
428*7c478bd9Sstevel@tonic-gate 	frgroup_t *g;
429*7c478bd9Sstevel@tonic-gate 	fripf_t *ipf;
430*7c478bd9Sstevel@tonic-gate 	int i, in, j;
431*7c478bd9Sstevel@tonic-gate 	mc_t *m = v;
432*7c478bd9Sstevel@tonic-gate 
433*7c478bd9Sstevel@tonic-gate 	if (fp == NULL)
434*7c478bd9Sstevel@tonic-gate 		fp = cfile;
435*7c478bd9Sstevel@tonic-gate 	if (fp == NULL)
436*7c478bd9Sstevel@tonic-gate 		return;
437*7c478bd9Sstevel@tonic-gate 	if (strncmp(egroup, group, FR_GROUPLEN)) {
438*7c478bd9Sstevel@tonic-gate 		for (sin--; sin > 0; sin--) {
439*7c478bd9Sstevel@tonic-gate 			indent(fp, sin);
440*7c478bd9Sstevel@tonic-gate 			fprintf(fp, "}\n");
441*7c478bd9Sstevel@tonic-gate 		}
442*7c478bd9Sstevel@tonic-gate 		if (openfunc == 1) {
443*7c478bd9Sstevel@tonic-gate 			fprintf(fp, "\treturn fr;\n}\n");
444*7c478bd9Sstevel@tonic-gate 			openfunc = 0;
445*7c478bd9Sstevel@tonic-gate 			if (n != NULL) {
446*7c478bd9Sstevel@tonic-gate 				free(n);
447*7c478bd9Sstevel@tonic-gate 				n = NULL;
448*7c478bd9Sstevel@tonic-gate 			}
449*7c478bd9Sstevel@tonic-gate 		}
450*7c478bd9Sstevel@tonic-gate 		sin = 0;
451*7c478bd9Sstevel@tonic-gate 		header[0] = 0;
452*7c478bd9Sstevel@tonic-gate 		header[1] = 0;
453*7c478bd9Sstevel@tonic-gate 		strncpy(egroup, group, FR_GROUPLEN);
454*7c478bd9Sstevel@tonic-gate 	} else if (openfunc == 1 && num < 0) {
455*7c478bd9Sstevel@tonic-gate 		if (n != NULL) {
456*7c478bd9Sstevel@tonic-gate 			free(n);
457*7c478bd9Sstevel@tonic-gate 			n = NULL;
458*7c478bd9Sstevel@tonic-gate 		}
459*7c478bd9Sstevel@tonic-gate 		for (sin--; sin > 0; sin--) {
460*7c478bd9Sstevel@tonic-gate 			indent(fp, sin);
461*7c478bd9Sstevel@tonic-gate 			fprintf(fp, "}\n");
462*7c478bd9Sstevel@tonic-gate 		}
463*7c478bd9Sstevel@tonic-gate 		if (openfunc == 1) {
464*7c478bd9Sstevel@tonic-gate 			fprintf(fp, "\treturn fr;\n}\n");
465*7c478bd9Sstevel@tonic-gate 			openfunc = 0;
466*7c478bd9Sstevel@tonic-gate 		}
467*7c478bd9Sstevel@tonic-gate 	}
468*7c478bd9Sstevel@tonic-gate 
469*7c478bd9Sstevel@tonic-gate 	if (dir == -1)
470*7c478bd9Sstevel@tonic-gate 		return;
471*7c478bd9Sstevel@tonic-gate 
472*7c478bd9Sstevel@tonic-gate 	for (g = groups; g != NULL; g = g->fg_next) {
473*7c478bd9Sstevel@tonic-gate 		if (dir == 0 && (g->fg_flags & FR_INQUE) == 0)
474*7c478bd9Sstevel@tonic-gate 			continue;
475*7c478bd9Sstevel@tonic-gate 		else if (dir == 1 && (g->fg_flags & FR_OUTQUE) == 0)
476*7c478bd9Sstevel@tonic-gate 			continue;
477*7c478bd9Sstevel@tonic-gate 		if (strncmp(g->fg_name, group, FR_GROUPLEN) != 0)
478*7c478bd9Sstevel@tonic-gate 			continue;
479*7c478bd9Sstevel@tonic-gate 		break;
480*7c478bd9Sstevel@tonic-gate 	}
481*7c478bd9Sstevel@tonic-gate 
482*7c478bd9Sstevel@tonic-gate 	/*
483*7c478bd9Sstevel@tonic-gate 	 * Output the array of pointers to rules for this group.
484*7c478bd9Sstevel@tonic-gate 	 */
485*7c478bd9Sstevel@tonic-gate 	if (num == -2 && dir == 0 && header[0] == 0 && incount != 0) {
486*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "\nfrentry_t *ipf_rules_in_%s[%d] = {",
487*7c478bd9Sstevel@tonic-gate 			group, incount);
488*7c478bd9Sstevel@tonic-gate 		for (f = g->fg_start, i = 0; f != NULL; f = f->fr_next) {
489*7c478bd9Sstevel@tonic-gate 			if ((f->fr_flags & FR_INQUE) == 0)
490*7c478bd9Sstevel@tonic-gate 				continue;
491*7c478bd9Sstevel@tonic-gate 			if ((i & 1) == 0) {
492*7c478bd9Sstevel@tonic-gate 				fprintf(fp, "\n\t");
493*7c478bd9Sstevel@tonic-gate 			}
494*7c478bd9Sstevel@tonic-gate 			fprintf(fp,
495*7c478bd9Sstevel@tonic-gate 				"(frentry_t *)&in_rule_%s_%d",
496*7c478bd9Sstevel@tonic-gate 				f->fr_group, i);
497*7c478bd9Sstevel@tonic-gate 			if (i + 1 < incount)
498*7c478bd9Sstevel@tonic-gate 				fprintf(fp, ", ");
499*7c478bd9Sstevel@tonic-gate 			i++;
500*7c478bd9Sstevel@tonic-gate 		}
501*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "\n};\n");
502*7c478bd9Sstevel@tonic-gate 	}
503*7c478bd9Sstevel@tonic-gate 
504*7c478bd9Sstevel@tonic-gate 	if (num == -2 && dir == 1 && header[1] == 0 && outcount != 0) {
505*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "\nfrentry_t *ipf_rules_out_%s[%d] = {",
506*7c478bd9Sstevel@tonic-gate 			group, outcount);
507*7c478bd9Sstevel@tonic-gate 		for (f = g->fg_start, i = 0; f != NULL; f = f->fr_next) {
508*7c478bd9Sstevel@tonic-gate 			if ((f->fr_flags & FR_OUTQUE) == 0)
509*7c478bd9Sstevel@tonic-gate 				continue;
510*7c478bd9Sstevel@tonic-gate 			if ((i & 1) == 0) {
511*7c478bd9Sstevel@tonic-gate 				fprintf(fp, "\n\t");
512*7c478bd9Sstevel@tonic-gate 			}
513*7c478bd9Sstevel@tonic-gate 			fprintf(fp,
514*7c478bd9Sstevel@tonic-gate 				"(frentry_t *)&out_rule_%s_%d",
515*7c478bd9Sstevel@tonic-gate 				f->fr_group, i);
516*7c478bd9Sstevel@tonic-gate 			if (i + 1 < outcount)
517*7c478bd9Sstevel@tonic-gate 				fprintf(fp, ", ");
518*7c478bd9Sstevel@tonic-gate 			i++;
519*7c478bd9Sstevel@tonic-gate 		}
520*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "\n};\n");
521*7c478bd9Sstevel@tonic-gate 		fp = NULL;
522*7c478bd9Sstevel@tonic-gate 	}
523*7c478bd9Sstevel@tonic-gate 
524*7c478bd9Sstevel@tonic-gate 	if (num < 0)
525*7c478bd9Sstevel@tonic-gate 		return;
526*7c478bd9Sstevel@tonic-gate 
527*7c478bd9Sstevel@tonic-gate 	in = 0;
528*7c478bd9Sstevel@tonic-gate 	ipf = fr->fr_ipf;
529*7c478bd9Sstevel@tonic-gate 
530*7c478bd9Sstevel@tonic-gate 	/*
531*7c478bd9Sstevel@tonic-gate 	 * If the function header has not been printed then print it now.
532*7c478bd9Sstevel@tonic-gate 	 */
533*7c478bd9Sstevel@tonic-gate 	if (header[dir] == 0) {
534*7c478bd9Sstevel@tonic-gate 		int pdst = 0, psrc = 0;
535*7c478bd9Sstevel@tonic-gate 
536*7c478bd9Sstevel@tonic-gate 		openfunc = 1;
537*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "\nfrentry_t *ipfrule_match_%s_%s(fin, passp)\n",
538*7c478bd9Sstevel@tonic-gate 			(dir == 0) ? "in" : "out", group);
539*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "fr_info_t *fin;\n");
540*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "u_32_t *passp;\n");
541*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "{\n");
542*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "\tfrentry_t *fr = NULL;\n");
543*7c478bd9Sstevel@tonic-gate 
544*7c478bd9Sstevel@tonic-gate 		/*
545*7c478bd9Sstevel@tonic-gate 		 * Print out any variables that need to be declared.
546*7c478bd9Sstevel@tonic-gate 		 */
547*7c478bd9Sstevel@tonic-gate 		for (f = g->fg_start, i = 0; f != NULL; f = f->fr_next) {
548*7c478bd9Sstevel@tonic-gate 			if (incount + outcount > m[FRC_SRC].e + 1)
549*7c478bd9Sstevel@tonic-gate 				psrc = 1;
550*7c478bd9Sstevel@tonic-gate 			if (incount + outcount > m[FRC_DST].e + 1)
551*7c478bd9Sstevel@tonic-gate 				pdst = 1;
552*7c478bd9Sstevel@tonic-gate 		}
553*7c478bd9Sstevel@tonic-gate 		if (psrc == 1)
554*7c478bd9Sstevel@tonic-gate 			fprintf(fp, "\tu_32_t src = ntohl(%s);\n",
555*7c478bd9Sstevel@tonic-gate 				"fin->fin_fi.fi_saddr");
556*7c478bd9Sstevel@tonic-gate 		if (pdst == 1)
557*7c478bd9Sstevel@tonic-gate 			fprintf(fp, "\tu_32_t dst = ntohl(%s);\n",
558*7c478bd9Sstevel@tonic-gate 				"fin->fin_fi.fi_daddr");
559*7c478bd9Sstevel@tonic-gate 	}
560*7c478bd9Sstevel@tonic-gate 
561*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < FRC_MAX; i++) {
562*7c478bd9Sstevel@tonic-gate 		switch(m[i].c)
563*7c478bd9Sstevel@tonic-gate 		{
564*7c478bd9Sstevel@tonic-gate 		case FRC_IFN :
565*7c478bd9Sstevel@tonic-gate 			if (*fr->fr_ifname)
566*7c478bd9Sstevel@tonic-gate 				m[i].s = 1;
567*7c478bd9Sstevel@tonic-gate 			break;
568*7c478bd9Sstevel@tonic-gate 		case FRC_V :
569*7c478bd9Sstevel@tonic-gate 			if (ipf != NULL && ipf->fri_mip.fi_v != 0)
570*7c478bd9Sstevel@tonic-gate 				m[i].s = 1;
571*7c478bd9Sstevel@tonic-gate 			break;
572*7c478bd9Sstevel@tonic-gate 		case FRC_FL :
573*7c478bd9Sstevel@tonic-gate 			if (ipf != NULL && ipf->fri_mip.fi_flx != 0)
574*7c478bd9Sstevel@tonic-gate 				m[i].s = 1;
575*7c478bd9Sstevel@tonic-gate 			break;
576*7c478bd9Sstevel@tonic-gate 		case FRC_P :
577*7c478bd9Sstevel@tonic-gate 			if (ipf != NULL && ipf->fri_mip.fi_p != 0)
578*7c478bd9Sstevel@tonic-gate 				m[i].s = 1;
579*7c478bd9Sstevel@tonic-gate 			break;
580*7c478bd9Sstevel@tonic-gate 		case FRC_TTL :
581*7c478bd9Sstevel@tonic-gate 			if (ipf != NULL && ipf->fri_mip.fi_ttl != 0)
582*7c478bd9Sstevel@tonic-gate 				m[i].s = 1;
583*7c478bd9Sstevel@tonic-gate 			break;
584*7c478bd9Sstevel@tonic-gate 		case FRC_TOS :
585*7c478bd9Sstevel@tonic-gate 			if (ipf != NULL && ipf->fri_mip.fi_tos != 0)
586*7c478bd9Sstevel@tonic-gate 				m[i].s = 1;
587*7c478bd9Sstevel@tonic-gate 			break;
588*7c478bd9Sstevel@tonic-gate 		case FRC_TCP :
589*7c478bd9Sstevel@tonic-gate 			if (ipf == NULL)
590*7c478bd9Sstevel@tonic-gate 				break;
591*7c478bd9Sstevel@tonic-gate 			if ((ipf->fri_ip.fi_p == IPPROTO_TCP) &&
592*7c478bd9Sstevel@tonic-gate 			    fr->fr_tcpfm != 0)
593*7c478bd9Sstevel@tonic-gate 				m[i].s = 1;
594*7c478bd9Sstevel@tonic-gate 			break;
595*7c478bd9Sstevel@tonic-gate 		case FRC_SP :
596*7c478bd9Sstevel@tonic-gate 			if (ipf == NULL)
597*7c478bd9Sstevel@tonic-gate 				break;
598*7c478bd9Sstevel@tonic-gate 			if (fr->fr_scmp == FR_INRANGE)
599*7c478bd9Sstevel@tonic-gate 				m[i].s = 1;
600*7c478bd9Sstevel@tonic-gate 			else if (fr->fr_scmp == FR_OUTRANGE)
601*7c478bd9Sstevel@tonic-gate 				m[i].s = 1;
602*7c478bd9Sstevel@tonic-gate 			else if (fr->fr_scmp != 0)
603*7c478bd9Sstevel@tonic-gate 				m[i].s = 1;
604*7c478bd9Sstevel@tonic-gate 			break;
605*7c478bd9Sstevel@tonic-gate 		case FRC_DP :
606*7c478bd9Sstevel@tonic-gate 			if (ipf == NULL)
607*7c478bd9Sstevel@tonic-gate 				break;
608*7c478bd9Sstevel@tonic-gate 			if (fr->fr_dcmp == FR_INRANGE)
609*7c478bd9Sstevel@tonic-gate 				m[i].s = 1;
610*7c478bd9Sstevel@tonic-gate 			else if (fr->fr_dcmp == FR_OUTRANGE)
611*7c478bd9Sstevel@tonic-gate 				m[i].s = 1;
612*7c478bd9Sstevel@tonic-gate 			else if (fr->fr_dcmp != 0)
613*7c478bd9Sstevel@tonic-gate 				m[i].s = 1;
614*7c478bd9Sstevel@tonic-gate 			break;
615*7c478bd9Sstevel@tonic-gate 		case FRC_SRC :
616*7c478bd9Sstevel@tonic-gate 			if (ipf == NULL)
617*7c478bd9Sstevel@tonic-gate 				break;
618*7c478bd9Sstevel@tonic-gate 			if (fr->fr_satype == FRI_LOOKUP) {
619*7c478bd9Sstevel@tonic-gate 				;
620*7c478bd9Sstevel@tonic-gate 			} else if ((fr->fr_smask != 0) ||
621*7c478bd9Sstevel@tonic-gate 				   (fr->fr_flags & FR_NOTSRCIP) != 0)
622*7c478bd9Sstevel@tonic-gate 				m[i].s = 1;
623*7c478bd9Sstevel@tonic-gate 			break;
624*7c478bd9Sstevel@tonic-gate 		case FRC_DST :
625*7c478bd9Sstevel@tonic-gate 			if (ipf == NULL)
626*7c478bd9Sstevel@tonic-gate 				break;
627*7c478bd9Sstevel@tonic-gate 			if (fr->fr_datype == FRI_LOOKUP) {
628*7c478bd9Sstevel@tonic-gate 				;
629*7c478bd9Sstevel@tonic-gate 			} else if ((fr->fr_dmask != 0) ||
630*7c478bd9Sstevel@tonic-gate 				   (fr->fr_flags & FR_NOTDSTIP) != 0)
631*7c478bd9Sstevel@tonic-gate 				m[i].s = 1;
632*7c478bd9Sstevel@tonic-gate 			break;
633*7c478bd9Sstevel@tonic-gate 		case FRC_OPT :
634*7c478bd9Sstevel@tonic-gate 			if (ipf == NULL)
635*7c478bd9Sstevel@tonic-gate 				break;
636*7c478bd9Sstevel@tonic-gate 			if (fr->fr_optmask != 0)
637*7c478bd9Sstevel@tonic-gate 				m[i].s = 1;
638*7c478bd9Sstevel@tonic-gate 			break;
639*7c478bd9Sstevel@tonic-gate 		case FRC_SEC :
640*7c478bd9Sstevel@tonic-gate 			if (ipf == NULL)
641*7c478bd9Sstevel@tonic-gate 				break;
642*7c478bd9Sstevel@tonic-gate 			if (fr->fr_secmask != 0)
643*7c478bd9Sstevel@tonic-gate 				m[i].s = 1;
644*7c478bd9Sstevel@tonic-gate 			break;
645*7c478bd9Sstevel@tonic-gate 		case FRC_ATH :
646*7c478bd9Sstevel@tonic-gate 			if (ipf == NULL)
647*7c478bd9Sstevel@tonic-gate 				break;
648*7c478bd9Sstevel@tonic-gate 			if (fr->fr_authmask != 0)
649*7c478bd9Sstevel@tonic-gate 				m[i].s = 1;
650*7c478bd9Sstevel@tonic-gate 			break;
651*7c478bd9Sstevel@tonic-gate 		case FRC_ICT :
652*7c478bd9Sstevel@tonic-gate 			if (ipf == NULL)
653*7c478bd9Sstevel@tonic-gate 				break;
654*7c478bd9Sstevel@tonic-gate 			if ((fr->fr_icmpm & 0xff00) != 0)
655*7c478bd9Sstevel@tonic-gate 				m[i].s = 1;
656*7c478bd9Sstevel@tonic-gate 			break;
657*7c478bd9Sstevel@tonic-gate 		case FRC_ICC :
658*7c478bd9Sstevel@tonic-gate 			if (ipf == NULL)
659*7c478bd9Sstevel@tonic-gate 				break;
660*7c478bd9Sstevel@tonic-gate 			if ((fr->fr_icmpm & 0xff) != 0)
661*7c478bd9Sstevel@tonic-gate 				m[i].s = 1;
662*7c478bd9Sstevel@tonic-gate 			break;
663*7c478bd9Sstevel@tonic-gate 		}
664*7c478bd9Sstevel@tonic-gate 	}
665*7c478bd9Sstevel@tonic-gate 
666*7c478bd9Sstevel@tonic-gate 	if (!header[dir]) {
667*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "\n");
668*7c478bd9Sstevel@tonic-gate 		header[dir] = 1;
669*7c478bd9Sstevel@tonic-gate 		sin = 0;
670*7c478bd9Sstevel@tonic-gate 	}
671*7c478bd9Sstevel@tonic-gate 
672*7c478bd9Sstevel@tonic-gate 	qsort(m, FRC_MAX, sizeof(mc_t), intcmp);
673*7c478bd9Sstevel@tonic-gate 
674*7c478bd9Sstevel@tonic-gate 	if (n) {
675*7c478bd9Sstevel@tonic-gate 		/*
676*7c478bd9Sstevel@tonic-gate 		 * Calculate the indentation interval upto the last common
677*7c478bd9Sstevel@tonic-gate 		 * common comparison being made.
678*7c478bd9Sstevel@tonic-gate 		 */
679*7c478bd9Sstevel@tonic-gate 		for (i = 0, in = 1; i < FRC_MAX; i++) {
680*7c478bd9Sstevel@tonic-gate 			if (n[i].c != m[i].c)
681*7c478bd9Sstevel@tonic-gate 				break;
682*7c478bd9Sstevel@tonic-gate 			if (n[i].s != m[i].s)
683*7c478bd9Sstevel@tonic-gate 				break;
684*7c478bd9Sstevel@tonic-gate 			if (n[i].s) {
685*7c478bd9Sstevel@tonic-gate 				if (n[i].n && (n[i].n > n[i].e)) {
686*7c478bd9Sstevel@tonic-gate 					m[i].p++;
687*7c478bd9Sstevel@tonic-gate 					in += m[i].p;
688*7c478bd9Sstevel@tonic-gate 					break;
689*7c478bd9Sstevel@tonic-gate 				}
690*7c478bd9Sstevel@tonic-gate 				if (n[i].e > 0) {
691*7c478bd9Sstevel@tonic-gate 					in++;
692*7c478bd9Sstevel@tonic-gate 				} else
693*7c478bd9Sstevel@tonic-gate 					break;
694*7c478bd9Sstevel@tonic-gate 			}
695*7c478bd9Sstevel@tonic-gate 		}
696*7c478bd9Sstevel@tonic-gate 		if (sin != in) {
697*7c478bd9Sstevel@tonic-gate 			for (j = sin - 1; j >= in; j--) {
698*7c478bd9Sstevel@tonic-gate 				indent(fp, j);
699*7c478bd9Sstevel@tonic-gate 				fprintf(fp, "}\n");
700*7c478bd9Sstevel@tonic-gate 			}
701*7c478bd9Sstevel@tonic-gate 		}
702*7c478bd9Sstevel@tonic-gate 	} else {
703*7c478bd9Sstevel@tonic-gate 		in = 1;
704*7c478bd9Sstevel@tonic-gate 		i = 0;
705*7c478bd9Sstevel@tonic-gate 	}
706*7c478bd9Sstevel@tonic-gate 
707*7c478bd9Sstevel@tonic-gate 	/*
708*7c478bd9Sstevel@tonic-gate 	 * print out C code that implements a filter rule.
709*7c478bd9Sstevel@tonic-gate 	 */
710*7c478bd9Sstevel@tonic-gate 	for (; i < FRC_MAX; i++) {
711*7c478bd9Sstevel@tonic-gate 		switch(m[i].c)
712*7c478bd9Sstevel@tonic-gate 		{
713*7c478bd9Sstevel@tonic-gate 		case FRC_IFN :
714*7c478bd9Sstevel@tonic-gate 			if (m[i].s) {
715*7c478bd9Sstevel@tonic-gate 				indent(fp, in);
716*7c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (fin->fin_ifp == ");
717*7c478bd9Sstevel@tonic-gate 				fprintf(fp, "ipf_rules_%s_%s[%d]->fr_ifa) {\n",
718*7c478bd9Sstevel@tonic-gate 					dir ? "out" : "in", group, num);
719*7c478bd9Sstevel@tonic-gate 				in++;
720*7c478bd9Sstevel@tonic-gate 			}
721*7c478bd9Sstevel@tonic-gate 			break;
722*7c478bd9Sstevel@tonic-gate 		case FRC_V :
723*7c478bd9Sstevel@tonic-gate 			if (m[i].s) {
724*7c478bd9Sstevel@tonic-gate 				indent(fp, in);
725*7c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (fin->fin_v == %d) {\n",
726*7c478bd9Sstevel@tonic-gate 					ipf->fri_ip.fi_v);
727*7c478bd9Sstevel@tonic-gate 				in++;
728*7c478bd9Sstevel@tonic-gate 			}
729*7c478bd9Sstevel@tonic-gate 			break;
730*7c478bd9Sstevel@tonic-gate 		case FRC_FL :
731*7c478bd9Sstevel@tonic-gate 			if (m[i].s) {
732*7c478bd9Sstevel@tonic-gate 				indent(fp, in);
733*7c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (");
734*7c478bd9Sstevel@tonic-gate 				printeq(fp, "fin->fin_flx",
735*7c478bd9Sstevel@tonic-gate 				        ipf->fri_mip.fi_flx, 0xf,
736*7c478bd9Sstevel@tonic-gate 					ipf->fri_ip.fi_flx);
737*7c478bd9Sstevel@tonic-gate 				in++;
738*7c478bd9Sstevel@tonic-gate 			}
739*7c478bd9Sstevel@tonic-gate 			break;
740*7c478bd9Sstevel@tonic-gate 		case FRC_P :
741*7c478bd9Sstevel@tonic-gate 			if (m[i].s) {
742*7c478bd9Sstevel@tonic-gate 				indent(fp, in);
743*7c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (fin->fin_p == %d) {\n",
744*7c478bd9Sstevel@tonic-gate 					ipf->fri_ip.fi_p);
745*7c478bd9Sstevel@tonic-gate 				in++;
746*7c478bd9Sstevel@tonic-gate 			}
747*7c478bd9Sstevel@tonic-gate 			break;
748*7c478bd9Sstevel@tonic-gate 		case FRC_TTL :
749*7c478bd9Sstevel@tonic-gate 			if (m[i].s) {
750*7c478bd9Sstevel@tonic-gate 				indent(fp, in);
751*7c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (");
752*7c478bd9Sstevel@tonic-gate 				printeq(fp, "fin->fin_ttl",
753*7c478bd9Sstevel@tonic-gate 					ipf->fri_mip.fi_ttl, 0xff,
754*7c478bd9Sstevel@tonic-gate 					ipf->fri_ip.fi_ttl);
755*7c478bd9Sstevel@tonic-gate 				in++;
756*7c478bd9Sstevel@tonic-gate 			}
757*7c478bd9Sstevel@tonic-gate 			break;
758*7c478bd9Sstevel@tonic-gate 		case FRC_TOS :
759*7c478bd9Sstevel@tonic-gate 			if (m[i].s) {
760*7c478bd9Sstevel@tonic-gate 				indent(fp, in);
761*7c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (fin->fin_tos");
762*7c478bd9Sstevel@tonic-gate 				printeq(fp, "fin->fin_tos",
763*7c478bd9Sstevel@tonic-gate 					ipf->fri_mip.fi_tos, 0xff,
764*7c478bd9Sstevel@tonic-gate 					ipf->fri_ip.fi_tos);
765*7c478bd9Sstevel@tonic-gate 				in++;
766*7c478bd9Sstevel@tonic-gate 			}
767*7c478bd9Sstevel@tonic-gate 			break;
768*7c478bd9Sstevel@tonic-gate 		case FRC_TCP :
769*7c478bd9Sstevel@tonic-gate 			if (m[i].s) {
770*7c478bd9Sstevel@tonic-gate 				indent(fp, in);
771*7c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (");
772*7c478bd9Sstevel@tonic-gate 				printeq(fp, "fin->fin_tcpf", fr->fr_tcpfm,
773*7c478bd9Sstevel@tonic-gate 					0xff, fr->fr_tcpf);
774*7c478bd9Sstevel@tonic-gate 				in++;
775*7c478bd9Sstevel@tonic-gate 			}
776*7c478bd9Sstevel@tonic-gate 			break;
777*7c478bd9Sstevel@tonic-gate 		case FRC_SP :
778*7c478bd9Sstevel@tonic-gate 			if (!m[i].s)
779*7c478bd9Sstevel@tonic-gate 				break;
780*7c478bd9Sstevel@tonic-gate 			if (fr->fr_scmp == FR_INRANGE) {
781*7c478bd9Sstevel@tonic-gate 				indent(fp, in);
782*7c478bd9Sstevel@tonic-gate 				fprintf(fp, "if ((fin->fin_data[0] > %d) && ",
783*7c478bd9Sstevel@tonic-gate 					fr->fr_sport);
784*7c478bd9Sstevel@tonic-gate 				fprintf(fp, "(fin->fin_data[0] < %d)",
785*7c478bd9Sstevel@tonic-gate 					fr->fr_stop);
786*7c478bd9Sstevel@tonic-gate 				fprintf(fp, ") {\n");
787*7c478bd9Sstevel@tonic-gate 				in++;
788*7c478bd9Sstevel@tonic-gate 			} else if (fr->fr_scmp == FR_OUTRANGE) {
789*7c478bd9Sstevel@tonic-gate 				indent(fp, in);
790*7c478bd9Sstevel@tonic-gate 				fprintf(fp, "if ((fin->fin_data[0] < %d) || ",
791*7c478bd9Sstevel@tonic-gate 					fr->fr_sport);
792*7c478bd9Sstevel@tonic-gate 				fprintf(fp, "(fin->fin_data[0] > %d)",
793*7c478bd9Sstevel@tonic-gate 					fr->fr_stop);
794*7c478bd9Sstevel@tonic-gate 				fprintf(fp, ") {\n");
795*7c478bd9Sstevel@tonic-gate 				in++;
796*7c478bd9Sstevel@tonic-gate 			} else if (fr->fr_scmp) {
797*7c478bd9Sstevel@tonic-gate 				indent(fp, in);
798*7c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (fin->fin_data[0] %s %d)",
799*7c478bd9Sstevel@tonic-gate 					portcmp[fr->fr_scmp], fr->fr_sport);
800*7c478bd9Sstevel@tonic-gate 				fprintf(fp, " {\n");
801*7c478bd9Sstevel@tonic-gate 				in++;
802*7c478bd9Sstevel@tonic-gate 			}
803*7c478bd9Sstevel@tonic-gate 			break;
804*7c478bd9Sstevel@tonic-gate 		case FRC_DP :
805*7c478bd9Sstevel@tonic-gate 			if (!m[i].s)
806*7c478bd9Sstevel@tonic-gate 				break;
807*7c478bd9Sstevel@tonic-gate 			if (fr->fr_dcmp == FR_INRANGE) {
808*7c478bd9Sstevel@tonic-gate 				indent(fp, in);
809*7c478bd9Sstevel@tonic-gate 				fprintf(fp, "if ((fin->fin_data[1] > %d) && ",
810*7c478bd9Sstevel@tonic-gate 					fr->fr_dport);
811*7c478bd9Sstevel@tonic-gate 				fprintf(fp, "(fin->fin_data[1] < %d)",
812*7c478bd9Sstevel@tonic-gate 					fr->fr_dtop);
813*7c478bd9Sstevel@tonic-gate 				fprintf(fp, ") {\n");
814*7c478bd9Sstevel@tonic-gate 				in++;
815*7c478bd9Sstevel@tonic-gate 			} else if (fr->fr_dcmp == FR_OUTRANGE) {
816*7c478bd9Sstevel@tonic-gate 				indent(fp, in);
817*7c478bd9Sstevel@tonic-gate 				fprintf(fp, "if ((fin->fin_data[1] < %d) || ",
818*7c478bd9Sstevel@tonic-gate 					fr->fr_dport);
819*7c478bd9Sstevel@tonic-gate 				fprintf(fp, "(fin->fin_data[1] > %d)",
820*7c478bd9Sstevel@tonic-gate 					fr->fr_dtop);
821*7c478bd9Sstevel@tonic-gate 				fprintf(fp, ") {\n");
822*7c478bd9Sstevel@tonic-gate 				in++;
823*7c478bd9Sstevel@tonic-gate 			} else if (fr->fr_dcmp) {
824*7c478bd9Sstevel@tonic-gate 				indent(fp, in);
825*7c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (fin->fin_data[1] %s %d)",
826*7c478bd9Sstevel@tonic-gate 					portcmp[fr->fr_dcmp], fr->fr_dport);
827*7c478bd9Sstevel@tonic-gate 				fprintf(fp, " {\n");
828*7c478bd9Sstevel@tonic-gate 				in++;
829*7c478bd9Sstevel@tonic-gate 			}
830*7c478bd9Sstevel@tonic-gate 			break;
831*7c478bd9Sstevel@tonic-gate 		case FRC_SRC :
832*7c478bd9Sstevel@tonic-gate 			if (!m[i].s)
833*7c478bd9Sstevel@tonic-gate 				break;
834*7c478bd9Sstevel@tonic-gate 			if (fr->fr_satype == FRI_LOOKUP) {
835*7c478bd9Sstevel@tonic-gate 				;
836*7c478bd9Sstevel@tonic-gate 			} else if ((fr->fr_smask != 0) ||
837*7c478bd9Sstevel@tonic-gate 				   (fr->fr_flags & FR_NOTSRCIP) != 0) {
838*7c478bd9Sstevel@tonic-gate 				indent(fp, in);
839*7c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (");
840*7c478bd9Sstevel@tonic-gate 				printipeq(fp, "src",
841*7c478bd9Sstevel@tonic-gate 					  fr->fr_flags & FR_NOTSRCIP,
842*7c478bd9Sstevel@tonic-gate 					  fr->fr_smask, fr->fr_saddr);
843*7c478bd9Sstevel@tonic-gate 				in++;
844*7c478bd9Sstevel@tonic-gate 			}
845*7c478bd9Sstevel@tonic-gate 			break;
846*7c478bd9Sstevel@tonic-gate 		case FRC_DST :
847*7c478bd9Sstevel@tonic-gate 			if (!m[i].s)
848*7c478bd9Sstevel@tonic-gate 				break;
849*7c478bd9Sstevel@tonic-gate 			if (fr->fr_datype == FRI_LOOKUP) {
850*7c478bd9Sstevel@tonic-gate 				;
851*7c478bd9Sstevel@tonic-gate 			} else if ((fr->fr_dmask != 0) ||
852*7c478bd9Sstevel@tonic-gate 				   (fr->fr_flags & FR_NOTDSTIP) != 0) {
853*7c478bd9Sstevel@tonic-gate 				indent(fp, in);
854*7c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (");
855*7c478bd9Sstevel@tonic-gate 				printipeq(fp, "dst",
856*7c478bd9Sstevel@tonic-gate 					  fr->fr_flags & FR_NOTDSTIP,
857*7c478bd9Sstevel@tonic-gate 					  fr->fr_dmask, fr->fr_daddr);
858*7c478bd9Sstevel@tonic-gate 				in++;
859*7c478bd9Sstevel@tonic-gate 			}
860*7c478bd9Sstevel@tonic-gate 			break;
861*7c478bd9Sstevel@tonic-gate 		case FRC_OPT :
862*7c478bd9Sstevel@tonic-gate 			if (m[i].s) {
863*7c478bd9Sstevel@tonic-gate 				indent(fp, in);
864*7c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (");
865*7c478bd9Sstevel@tonic-gate 				printeq(fp, "fin->fin_fi.fi_optmsk",
866*7c478bd9Sstevel@tonic-gate 					fr->fr_optmask, 0xffffffff,
867*7c478bd9Sstevel@tonic-gate 				        fr->fr_optbits);
868*7c478bd9Sstevel@tonic-gate 				in++;
869*7c478bd9Sstevel@tonic-gate 			}
870*7c478bd9Sstevel@tonic-gate 			break;
871*7c478bd9Sstevel@tonic-gate 		case FRC_SEC :
872*7c478bd9Sstevel@tonic-gate 			if (m[i].s) {
873*7c478bd9Sstevel@tonic-gate 				indent(fp, in);
874*7c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (");
875*7c478bd9Sstevel@tonic-gate 				printeq(fp, "fin->fin_fi.fi_secmsk",
876*7c478bd9Sstevel@tonic-gate 					fr->fr_secmask, 0xffff,
877*7c478bd9Sstevel@tonic-gate 					fr->fr_secbits);
878*7c478bd9Sstevel@tonic-gate 				in++;
879*7c478bd9Sstevel@tonic-gate 			}
880*7c478bd9Sstevel@tonic-gate 			break;
881*7c478bd9Sstevel@tonic-gate 		case FRC_ATH :
882*7c478bd9Sstevel@tonic-gate 			if (m[i].s) {
883*7c478bd9Sstevel@tonic-gate 				indent(fp, in);
884*7c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (");
885*7c478bd9Sstevel@tonic-gate 				printeq(fp, "fin->fin_fi.fi_authmsk",
886*7c478bd9Sstevel@tonic-gate 					fr->fr_authmask, 0xffff,
887*7c478bd9Sstevel@tonic-gate 					fr->fr_authbits);
888*7c478bd9Sstevel@tonic-gate 				in++;
889*7c478bd9Sstevel@tonic-gate 			}
890*7c478bd9Sstevel@tonic-gate 			break;
891*7c478bd9Sstevel@tonic-gate 		case FRC_ICT :
892*7c478bd9Sstevel@tonic-gate 			if (m[i].s) {
893*7c478bd9Sstevel@tonic-gate 				indent(fp, in);
894*7c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (");
895*7c478bd9Sstevel@tonic-gate 				printeq(fp, "fin->fin_data[0]",
896*7c478bd9Sstevel@tonic-gate 					fr->fr_icmpm & 0xff00, 0xffff,
897*7c478bd9Sstevel@tonic-gate 					fr->fr_icmp & 0xff00);
898*7c478bd9Sstevel@tonic-gate 				in++;
899*7c478bd9Sstevel@tonic-gate 			}
900*7c478bd9Sstevel@tonic-gate 			break;
901*7c478bd9Sstevel@tonic-gate 		case FRC_ICC :
902*7c478bd9Sstevel@tonic-gate 			if (m[i].s) {
903*7c478bd9Sstevel@tonic-gate 				indent(fp, in);
904*7c478bd9Sstevel@tonic-gate 				fprintf(fp, "if (");
905*7c478bd9Sstevel@tonic-gate 				printeq(fp, "fin->fin_data[0]",
906*7c478bd9Sstevel@tonic-gate 					fr->fr_icmpm & 0xff, 0xffff,
907*7c478bd9Sstevel@tonic-gate 					fr->fr_icmp & 0xff);
908*7c478bd9Sstevel@tonic-gate 				in++;
909*7c478bd9Sstevel@tonic-gate 			}
910*7c478bd9Sstevel@tonic-gate 			break;
911*7c478bd9Sstevel@tonic-gate 		}
912*7c478bd9Sstevel@tonic-gate 
913*7c478bd9Sstevel@tonic-gate 	}
914*7c478bd9Sstevel@tonic-gate 
915*7c478bd9Sstevel@tonic-gate 	indent(fp, in);
916*7c478bd9Sstevel@tonic-gate 	if (fr->fr_flags & FR_QUICK) {
917*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "return (frentry_t *)&%s_rule_%s_%d;\n",
918*7c478bd9Sstevel@tonic-gate 			fr->fr_flags & FR_INQUE ? "in" : "out",
919*7c478bd9Sstevel@tonic-gate 			fr->fr_group, num);
920*7c478bd9Sstevel@tonic-gate 	} else {
921*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "fr = (frentry_t *)&%s_rule_%s_%d;\n",
922*7c478bd9Sstevel@tonic-gate 			fr->fr_flags & FR_INQUE ? "in" : "out",
923*7c478bd9Sstevel@tonic-gate 			fr->fr_group, num);
924*7c478bd9Sstevel@tonic-gate 	}
925*7c478bd9Sstevel@tonic-gate 	if (n == NULL)
926*7c478bd9Sstevel@tonic-gate 		n = (mc_t *)malloc(sizeof(*n) * FRC_MAX);
927*7c478bd9Sstevel@tonic-gate 	bcopy((char *)m, (char *)n, sizeof(*n) * FRC_MAX);
928*7c478bd9Sstevel@tonic-gate 	sin = in;
929*7c478bd9Sstevel@tonic-gate }
930*7c478bd9Sstevel@tonic-gate 
931*7c478bd9Sstevel@tonic-gate 
932*7c478bd9Sstevel@tonic-gate void printC(dir)
933*7c478bd9Sstevel@tonic-gate int dir;
934*7c478bd9Sstevel@tonic-gate {
935*7c478bd9Sstevel@tonic-gate 	static mc_t *m = NULL;
936*7c478bd9Sstevel@tonic-gate 	frgroup_t *g;
937*7c478bd9Sstevel@tonic-gate 
938*7c478bd9Sstevel@tonic-gate 	if (m == NULL)
939*7c478bd9Sstevel@tonic-gate 		m = (mc_t *)calloc(1, sizeof(*m) * FRC_MAX);
940*7c478bd9Sstevel@tonic-gate 
941*7c478bd9Sstevel@tonic-gate 	for (g = groups; g != NULL; g = g->fg_next) {
942*7c478bd9Sstevel@tonic-gate 		if ((dir == 0) && ((g->fg_flags & FR_INQUE) != 0))
943*7c478bd9Sstevel@tonic-gate 			printCgroup(dir, g->fg_start, m, g->fg_name);
944*7c478bd9Sstevel@tonic-gate 		if ((dir == 1) && ((g->fg_flags & FR_OUTQUE) != 0))
945*7c478bd9Sstevel@tonic-gate 			printCgroup(dir, g->fg_start, m, g->fg_name);
946*7c478bd9Sstevel@tonic-gate 	}
947*7c478bd9Sstevel@tonic-gate 
948*7c478bd9Sstevel@tonic-gate 	emit(-1, dir, m, NULL);
949*7c478bd9Sstevel@tonic-gate }
950*7c478bd9Sstevel@tonic-gate 
951*7c478bd9Sstevel@tonic-gate 
952*7c478bd9Sstevel@tonic-gate /*
953*7c478bd9Sstevel@tonic-gate  * Now print out code to implement all of the rules.
954*7c478bd9Sstevel@tonic-gate  */
955*7c478bd9Sstevel@tonic-gate static void printCgroup(dir, top, m, group)
956*7c478bd9Sstevel@tonic-gate int dir;
957*7c478bd9Sstevel@tonic-gate frentry_t *top;
958*7c478bd9Sstevel@tonic-gate mc_t *m;
959*7c478bd9Sstevel@tonic-gate char *group;
960*7c478bd9Sstevel@tonic-gate {
961*7c478bd9Sstevel@tonic-gate 	frentry_t *fr, *fr1;
962*7c478bd9Sstevel@tonic-gate 	int i, n, rn;
963*7c478bd9Sstevel@tonic-gate 	u_int count;
964*7c478bd9Sstevel@tonic-gate 
965*7c478bd9Sstevel@tonic-gate 	for (count = 0, fr1 = top; fr1 != NULL; fr1 = fr1->fr_next) {
966*7c478bd9Sstevel@tonic-gate 		if ((dir == 0) && ((fr1->fr_flags & FR_INQUE) != 0))
967*7c478bd9Sstevel@tonic-gate 			count++;
968*7c478bd9Sstevel@tonic-gate 		else if ((dir == 1) && ((fr1->fr_flags & FR_OUTQUE) != 0))
969*7c478bd9Sstevel@tonic-gate 			count++;
970*7c478bd9Sstevel@tonic-gate 	}
971*7c478bd9Sstevel@tonic-gate 
972*7c478bd9Sstevel@tonic-gate 	if (dir == 0)
973*7c478bd9Sstevel@tonic-gate 		emitGroup(-2, dir, m, fr1, group, count, 0);
974*7c478bd9Sstevel@tonic-gate 	else if (dir == 1)
975*7c478bd9Sstevel@tonic-gate 		emitGroup(-2, dir, m, fr1, group, 0, count);
976*7c478bd9Sstevel@tonic-gate 
977*7c478bd9Sstevel@tonic-gate 	/*
978*7c478bd9Sstevel@tonic-gate 	 * Before printing each rule, check to see how many of its fields are
979*7c478bd9Sstevel@tonic-gate 	 * matched by subsequent rules.
980*7c478bd9Sstevel@tonic-gate 	 */
981*7c478bd9Sstevel@tonic-gate 	for (fr1 = top, rn = 0; fr1 != NULL; fr1 = fr1->fr_next, rn++) {
982*7c478bd9Sstevel@tonic-gate 		if (!dir && !(fr1->fr_flags & FR_INQUE))
983*7c478bd9Sstevel@tonic-gate 			continue;
984*7c478bd9Sstevel@tonic-gate 		if (dir && !(fr1->fr_flags & FR_OUTQUE))
985*7c478bd9Sstevel@tonic-gate 			continue;
986*7c478bd9Sstevel@tonic-gate 		n = 0xfffffff;
987*7c478bd9Sstevel@tonic-gate 
988*7c478bd9Sstevel@tonic-gate 		for (i = 0; i < FRC_MAX; i++)
989*7c478bd9Sstevel@tonic-gate 			m[i].e = 0;
990*7c478bd9Sstevel@tonic-gate 		qsort(m, FRC_MAX, sizeof(mc_t), intcmp);
991*7c478bd9Sstevel@tonic-gate 
992*7c478bd9Sstevel@tonic-gate 		for (i = 0; i < FRC_MAX; i++) {
993*7c478bd9Sstevel@tonic-gate 			m[i].c = i;
994*7c478bd9Sstevel@tonic-gate 			m[i].e = 0;
995*7c478bd9Sstevel@tonic-gate 			m[i].n = 0;
996*7c478bd9Sstevel@tonic-gate 			m[i].s = 0;
997*7c478bd9Sstevel@tonic-gate 		}
998*7c478bd9Sstevel@tonic-gate 
999*7c478bd9Sstevel@tonic-gate 		for (fr = fr1->fr_next; fr; fr = fr->fr_next) {
1000*7c478bd9Sstevel@tonic-gate 			if (!dir && !(fr->fr_flags & FR_INQUE))
1001*7c478bd9Sstevel@tonic-gate 				continue;
1002*7c478bd9Sstevel@tonic-gate 			if (dir && !(fr->fr_flags & FR_OUTQUE))
1003*7c478bd9Sstevel@tonic-gate 				continue;
1004*7c478bd9Sstevel@tonic-gate 
1005*7c478bd9Sstevel@tonic-gate 			if ((n & 0x0001) &&
1006*7c478bd9Sstevel@tonic-gate 			    !strcmp(fr1->fr_ifname, fr->fr_ifname)) {
1007*7c478bd9Sstevel@tonic-gate 				m[FRC_IFN].e++;
1008*7c478bd9Sstevel@tonic-gate 				m[FRC_IFN].n++;
1009*7c478bd9Sstevel@tonic-gate 			} else
1010*7c478bd9Sstevel@tonic-gate 				n &= ~0x0001;
1011*7c478bd9Sstevel@tonic-gate 
1012*7c478bd9Sstevel@tonic-gate 			if ((n & 0x0002) && (fr1->fr_v == fr->fr_v)) {
1013*7c478bd9Sstevel@tonic-gate 				m[FRC_V].e++;
1014*7c478bd9Sstevel@tonic-gate 				m[FRC_V].n++;
1015*7c478bd9Sstevel@tonic-gate 			} else
1016*7c478bd9Sstevel@tonic-gate 				n &= ~0x0002;
1017*7c478bd9Sstevel@tonic-gate 
1018*7c478bd9Sstevel@tonic-gate 			if ((n & 0x0004) &&
1019*7c478bd9Sstevel@tonic-gate 			    (fr->fr_type == fr1->fr_type) &&
1020*7c478bd9Sstevel@tonic-gate 			    (fr->fr_type == FR_T_IPF) &&
1021*7c478bd9Sstevel@tonic-gate 			    (fr1->fr_mip.fi_flx == fr->fr_mip.fi_flx) &&
1022*7c478bd9Sstevel@tonic-gate 			    (fr1->fr_ip.fi_flx == fr->fr_ip.fi_flx)) {
1023*7c478bd9Sstevel@tonic-gate 				m[FRC_FL].e++;
1024*7c478bd9Sstevel@tonic-gate 				m[FRC_FL].n++;
1025*7c478bd9Sstevel@tonic-gate 			} else
1026*7c478bd9Sstevel@tonic-gate 				n &= ~0x0004;
1027*7c478bd9Sstevel@tonic-gate 
1028*7c478bd9Sstevel@tonic-gate 			if ((n & 0x0008) &&
1029*7c478bd9Sstevel@tonic-gate 			    (fr->fr_type == fr1->fr_type) &&
1030*7c478bd9Sstevel@tonic-gate 			    (fr->fr_type == FR_T_IPF) &&
1031*7c478bd9Sstevel@tonic-gate 			    (fr1->fr_proto == fr->fr_proto)) {
1032*7c478bd9Sstevel@tonic-gate 				m[FRC_P].e++;
1033*7c478bd9Sstevel@tonic-gate 				m[FRC_P].n++;
1034*7c478bd9Sstevel@tonic-gate 			} else
1035*7c478bd9Sstevel@tonic-gate 				n &= ~0x0008;
1036*7c478bd9Sstevel@tonic-gate 
1037*7c478bd9Sstevel@tonic-gate 			if ((n & 0x0010) &&
1038*7c478bd9Sstevel@tonic-gate 			    (fr->fr_type == fr1->fr_type) &&
1039*7c478bd9Sstevel@tonic-gate 			    (fr->fr_type == FR_T_IPF) &&
1040*7c478bd9Sstevel@tonic-gate 			    (fr1->fr_ttl == fr->fr_ttl)) {
1041*7c478bd9Sstevel@tonic-gate 				m[FRC_TTL].e++;
1042*7c478bd9Sstevel@tonic-gate 				m[FRC_TTL].n++;
1043*7c478bd9Sstevel@tonic-gate 			} else
1044*7c478bd9Sstevel@tonic-gate 				n &= ~0x0010;
1045*7c478bd9Sstevel@tonic-gate 
1046*7c478bd9Sstevel@tonic-gate 			if ((n & 0x0020) &&
1047*7c478bd9Sstevel@tonic-gate 			    (fr->fr_type == fr1->fr_type) &&
1048*7c478bd9Sstevel@tonic-gate 			    (fr->fr_type == FR_T_IPF) &&
1049*7c478bd9Sstevel@tonic-gate 			    (fr1->fr_tos == fr->fr_tos)) {
1050*7c478bd9Sstevel@tonic-gate 				m[FRC_TOS].e++;
1051*7c478bd9Sstevel@tonic-gate 				m[FRC_TOS].n++;
1052*7c478bd9Sstevel@tonic-gate 			} else
1053*7c478bd9Sstevel@tonic-gate 				n &= ~0x0020;
1054*7c478bd9Sstevel@tonic-gate 
1055*7c478bd9Sstevel@tonic-gate 			if ((n & 0x0040) &&
1056*7c478bd9Sstevel@tonic-gate 			    (fr->fr_type == fr1->fr_type) &&
1057*7c478bd9Sstevel@tonic-gate 			    (fr->fr_type == FR_T_IPF) &&
1058*7c478bd9Sstevel@tonic-gate 			    ((fr1->fr_tcpfm == fr->fr_tcpfm) &&
1059*7c478bd9Sstevel@tonic-gate 			    (fr1->fr_tcpf == fr->fr_tcpf))) {
1060*7c478bd9Sstevel@tonic-gate 				m[FRC_TCP].e++;
1061*7c478bd9Sstevel@tonic-gate 				m[FRC_TCP].n++;
1062*7c478bd9Sstevel@tonic-gate 			} else
1063*7c478bd9Sstevel@tonic-gate 				n &= ~0x0040;
1064*7c478bd9Sstevel@tonic-gate 
1065*7c478bd9Sstevel@tonic-gate 			if ((n & 0x0080) &&
1066*7c478bd9Sstevel@tonic-gate 			    (fr->fr_type == fr1->fr_type) &&
1067*7c478bd9Sstevel@tonic-gate 			    (fr->fr_type == FR_T_IPF) &&
1068*7c478bd9Sstevel@tonic-gate 			    ((fr1->fr_scmp == fr->fr_scmp) &&
1069*7c478bd9Sstevel@tonic-gate 			     (fr1->fr_stop == fr->fr_stop) &&
1070*7c478bd9Sstevel@tonic-gate 			     (fr1->fr_sport == fr->fr_sport))) {
1071*7c478bd9Sstevel@tonic-gate 				m[FRC_SP].e++;
1072*7c478bd9Sstevel@tonic-gate 				m[FRC_SP].n++;
1073*7c478bd9Sstevel@tonic-gate 			} else
1074*7c478bd9Sstevel@tonic-gate 				n &= ~0x0080;
1075*7c478bd9Sstevel@tonic-gate 
1076*7c478bd9Sstevel@tonic-gate 			if ((n & 0x0100) &&
1077*7c478bd9Sstevel@tonic-gate 			    (fr->fr_type == fr1->fr_type) &&
1078*7c478bd9Sstevel@tonic-gate 			    (fr->fr_type == FR_T_IPF) &&
1079*7c478bd9Sstevel@tonic-gate 			    ((fr1->fr_dcmp == fr->fr_dcmp) &&
1080*7c478bd9Sstevel@tonic-gate 			     (fr1->fr_dtop == fr->fr_dtop) &&
1081*7c478bd9Sstevel@tonic-gate 			     (fr1->fr_dport == fr->fr_dport))) {
1082*7c478bd9Sstevel@tonic-gate 				m[FRC_DP].e++;
1083*7c478bd9Sstevel@tonic-gate 				m[FRC_DP].n++;
1084*7c478bd9Sstevel@tonic-gate 			} else
1085*7c478bd9Sstevel@tonic-gate 				n &= ~0x0100;
1086*7c478bd9Sstevel@tonic-gate 
1087*7c478bd9Sstevel@tonic-gate 			if ((n & 0x0200) &&
1088*7c478bd9Sstevel@tonic-gate 			    (fr->fr_type == fr1->fr_type) &&
1089*7c478bd9Sstevel@tonic-gate 			    (fr->fr_type == FR_T_IPF) &&
1090*7c478bd9Sstevel@tonic-gate 			    ((fr1->fr_satype == FRI_LOOKUP) &&
1091*7c478bd9Sstevel@tonic-gate 			    (fr->fr_satype == FRI_LOOKUP) &&
1092*7c478bd9Sstevel@tonic-gate 			    (fr1->fr_srcnum == fr->fr_srcnum))) {
1093*7c478bd9Sstevel@tonic-gate 				m[FRC_SRC].e++;
1094*7c478bd9Sstevel@tonic-gate 				m[FRC_SRC].n++;
1095*7c478bd9Sstevel@tonic-gate 			} else if ((n & 0x0200) &&
1096*7c478bd9Sstevel@tonic-gate 				   (fr->fr_type == fr1->fr_type) &&
1097*7c478bd9Sstevel@tonic-gate 				   (fr->fr_type == FR_T_IPF) &&
1098*7c478bd9Sstevel@tonic-gate 				   (((fr1->fr_flags & FR_NOTSRCIP) ==
1099*7c478bd9Sstevel@tonic-gate 				    (fr->fr_flags & FR_NOTSRCIP)))) {
1100*7c478bd9Sstevel@tonic-gate 					if ((fr1->fr_smask == fr->fr_smask) &&
1101*7c478bd9Sstevel@tonic-gate 					    (fr1->fr_saddr == fr->fr_saddr))
1102*7c478bd9Sstevel@tonic-gate 						m[FRC_SRC].e++;
1103*7c478bd9Sstevel@tonic-gate 					else
1104*7c478bd9Sstevel@tonic-gate 						n &= ~0x0200;
1105*7c478bd9Sstevel@tonic-gate 					if (fr1->fr_smask &&
1106*7c478bd9Sstevel@tonic-gate 					    (fr1->fr_saddr & fr1->fr_smask) ==
1107*7c478bd9Sstevel@tonic-gate 					    (fr->fr_saddr & fr1->fr_smask)) {
1108*7c478bd9Sstevel@tonic-gate 						m[FRC_SRC].n++;
1109*7c478bd9Sstevel@tonic-gate 						n |= 0x0200;
1110*7c478bd9Sstevel@tonic-gate 					}
1111*7c478bd9Sstevel@tonic-gate 			} else {
1112*7c478bd9Sstevel@tonic-gate 				n &= ~0x0200;
1113*7c478bd9Sstevel@tonic-gate 			}
1114*7c478bd9Sstevel@tonic-gate 
1115*7c478bd9Sstevel@tonic-gate 			if ((n & 0x0400) &&
1116*7c478bd9Sstevel@tonic-gate 			    (fr->fr_type == fr1->fr_type) &&
1117*7c478bd9Sstevel@tonic-gate 			    (fr->fr_type == FR_T_IPF) &&
1118*7c478bd9Sstevel@tonic-gate 			    ((fr1->fr_datype == FRI_LOOKUP) &&
1119*7c478bd9Sstevel@tonic-gate 			    (fr->fr_datype == FRI_LOOKUP) &&
1120*7c478bd9Sstevel@tonic-gate 			    (fr1->fr_dstnum == fr->fr_dstnum))) {
1121*7c478bd9Sstevel@tonic-gate 				m[FRC_DST].e++;
1122*7c478bd9Sstevel@tonic-gate 				m[FRC_DST].n++;
1123*7c478bd9Sstevel@tonic-gate 			} else if ((n & 0x0400) &&
1124*7c478bd9Sstevel@tonic-gate 				   (fr->fr_type == fr1->fr_type) &&
1125*7c478bd9Sstevel@tonic-gate 				   (fr->fr_type == FR_T_IPF) &&
1126*7c478bd9Sstevel@tonic-gate 				   (((fr1->fr_flags & FR_NOTDSTIP) ==
1127*7c478bd9Sstevel@tonic-gate 				    (fr->fr_flags & FR_NOTDSTIP)))) {
1128*7c478bd9Sstevel@tonic-gate 					if ((fr1->fr_dmask == fr->fr_dmask) &&
1129*7c478bd9Sstevel@tonic-gate 					    (fr1->fr_daddr == fr->fr_daddr))
1130*7c478bd9Sstevel@tonic-gate 						m[FRC_DST].e++;
1131*7c478bd9Sstevel@tonic-gate 					else
1132*7c478bd9Sstevel@tonic-gate 						n &= ~0x0400;
1133*7c478bd9Sstevel@tonic-gate 					if (fr1->fr_dmask &&
1134*7c478bd9Sstevel@tonic-gate 					    (fr1->fr_daddr & fr1->fr_dmask) ==
1135*7c478bd9Sstevel@tonic-gate 					    (fr->fr_daddr & fr1->fr_dmask)) {
1136*7c478bd9Sstevel@tonic-gate 						m[FRC_DST].n++;
1137*7c478bd9Sstevel@tonic-gate 						n |= 0x0400;
1138*7c478bd9Sstevel@tonic-gate 					}
1139*7c478bd9Sstevel@tonic-gate 			} else {
1140*7c478bd9Sstevel@tonic-gate 				n &= ~0x0400;
1141*7c478bd9Sstevel@tonic-gate 			}
1142*7c478bd9Sstevel@tonic-gate 
1143*7c478bd9Sstevel@tonic-gate 			if ((n & 0x0800) &&
1144*7c478bd9Sstevel@tonic-gate 			    (fr->fr_type == fr1->fr_type) &&
1145*7c478bd9Sstevel@tonic-gate 			    (fr->fr_type == FR_T_IPF) &&
1146*7c478bd9Sstevel@tonic-gate 			    (fr1->fr_optmask == fr->fr_optmask) &&
1147*7c478bd9Sstevel@tonic-gate 			    (fr1->fr_optbits == fr->fr_optbits)) {
1148*7c478bd9Sstevel@tonic-gate 				m[FRC_OPT].e++;
1149*7c478bd9Sstevel@tonic-gate 				m[FRC_OPT].n++;
1150*7c478bd9Sstevel@tonic-gate 			} else
1151*7c478bd9Sstevel@tonic-gate 				n &= ~0x0800;
1152*7c478bd9Sstevel@tonic-gate 
1153*7c478bd9Sstevel@tonic-gate 			if ((n & 0x1000) &&
1154*7c478bd9Sstevel@tonic-gate 			    (fr->fr_type == fr1->fr_type) &&
1155*7c478bd9Sstevel@tonic-gate 			    (fr->fr_type == FR_T_IPF) &&
1156*7c478bd9Sstevel@tonic-gate 			    (fr1->fr_secmask == fr->fr_secmask) &&
1157*7c478bd9Sstevel@tonic-gate 			    (fr1->fr_secbits == fr->fr_secbits)) {
1158*7c478bd9Sstevel@tonic-gate 				m[FRC_SEC].e++;
1159*7c478bd9Sstevel@tonic-gate 				m[FRC_SEC].n++;
1160*7c478bd9Sstevel@tonic-gate 			} else
1161*7c478bd9Sstevel@tonic-gate 				n &= ~0x1000;
1162*7c478bd9Sstevel@tonic-gate 
1163*7c478bd9Sstevel@tonic-gate 			if ((n & 0x10000) &&
1164*7c478bd9Sstevel@tonic-gate 			    (fr->fr_type == fr1->fr_type) &&
1165*7c478bd9Sstevel@tonic-gate 			    (fr->fr_type == FR_T_IPF) &&
1166*7c478bd9Sstevel@tonic-gate 			    (fr1->fr_authmask == fr->fr_authmask) &&
1167*7c478bd9Sstevel@tonic-gate 			    (fr1->fr_authbits == fr->fr_authbits)) {
1168*7c478bd9Sstevel@tonic-gate 				m[FRC_ATH].e++;
1169*7c478bd9Sstevel@tonic-gate 				m[FRC_ATH].n++;
1170*7c478bd9Sstevel@tonic-gate 			} else
1171*7c478bd9Sstevel@tonic-gate 				n &= ~0x10000;
1172*7c478bd9Sstevel@tonic-gate 
1173*7c478bd9Sstevel@tonic-gate 			if ((n & 0x20000) &&
1174*7c478bd9Sstevel@tonic-gate 			    (fr->fr_type == fr1->fr_type) &&
1175*7c478bd9Sstevel@tonic-gate 			    (fr->fr_type == FR_T_IPF) &&
1176*7c478bd9Sstevel@tonic-gate 			    ((fr1->fr_icmpm & 0xff00) ==
1177*7c478bd9Sstevel@tonic-gate 			     (fr->fr_icmpm & 0xff00)) &&
1178*7c478bd9Sstevel@tonic-gate 			    ((fr1->fr_icmp & 0xff00) ==
1179*7c478bd9Sstevel@tonic-gate 			     (fr->fr_icmp & 0xff00))) {
1180*7c478bd9Sstevel@tonic-gate 				m[FRC_ICT].e++;
1181*7c478bd9Sstevel@tonic-gate 				m[FRC_ICT].n++;
1182*7c478bd9Sstevel@tonic-gate 			} else
1183*7c478bd9Sstevel@tonic-gate 				n &= ~0x20000;
1184*7c478bd9Sstevel@tonic-gate 
1185*7c478bd9Sstevel@tonic-gate 			if ((n & 0x40000) &&
1186*7c478bd9Sstevel@tonic-gate 			    (fr->fr_type == fr1->fr_type) &&
1187*7c478bd9Sstevel@tonic-gate 			    (fr->fr_type == FR_T_IPF) &&
1188*7c478bd9Sstevel@tonic-gate 			    ((fr1->fr_icmpm & 0xff) == (fr->fr_icmpm & 0xff)) &&
1189*7c478bd9Sstevel@tonic-gate 			    ((fr1->fr_icmp & 0xff) == (fr->fr_icmp & 0xff))) {
1190*7c478bd9Sstevel@tonic-gate 				m[FRC_ICC].e++;
1191*7c478bd9Sstevel@tonic-gate 				m[FRC_ICC].n++;
1192*7c478bd9Sstevel@tonic-gate 			} else
1193*7c478bd9Sstevel@tonic-gate 				n &= ~0x40000;
1194*7c478bd9Sstevel@tonic-gate 		}
1195*7c478bd9Sstevel@tonic-gate 		/*msort(m);*/
1196*7c478bd9Sstevel@tonic-gate 
1197*7c478bd9Sstevel@tonic-gate 		if (dir == 0)
1198*7c478bd9Sstevel@tonic-gate 			emitGroup(rn, dir, m, fr1, group, count, 0);
1199*7c478bd9Sstevel@tonic-gate 		else if (dir == 1)
1200*7c478bd9Sstevel@tonic-gate 			emitGroup(rn, dir, m, fr1, group, 0, count);
1201*7c478bd9Sstevel@tonic-gate 	}
1202*7c478bd9Sstevel@tonic-gate }
1203*7c478bd9Sstevel@tonic-gate 
1204*7c478bd9Sstevel@tonic-gate static void printhooks(fp, in, out, grp)
1205*7c478bd9Sstevel@tonic-gate FILE *fp;
1206*7c478bd9Sstevel@tonic-gate int in;
1207*7c478bd9Sstevel@tonic-gate int out;
1208*7c478bd9Sstevel@tonic-gate frgroup_t *grp;
1209*7c478bd9Sstevel@tonic-gate {
1210*7c478bd9Sstevel@tonic-gate 	frentry_t *fr;
1211*7c478bd9Sstevel@tonic-gate 	char *group;
1212*7c478bd9Sstevel@tonic-gate 	int dogrp, i;
1213*7c478bd9Sstevel@tonic-gate 	char *instr;
1214*7c478bd9Sstevel@tonic-gate 
1215*7c478bd9Sstevel@tonic-gate 	group = grp->fg_name;
1216*7c478bd9Sstevel@tonic-gate 	dogrp = 0;
1217*7c478bd9Sstevel@tonic-gate 
1218*7c478bd9Sstevel@tonic-gate 	if (in && out) {
1219*7c478bd9Sstevel@tonic-gate 		fprintf(stderr,
1220*7c478bd9Sstevel@tonic-gate 			"printhooks called with both in and out set\n");
1221*7c478bd9Sstevel@tonic-gate 		exit(1);
1222*7c478bd9Sstevel@tonic-gate 	}
1223*7c478bd9Sstevel@tonic-gate 
1224*7c478bd9Sstevel@tonic-gate 	if (in) {
1225*7c478bd9Sstevel@tonic-gate 		instr = "in";
1226*7c478bd9Sstevel@tonic-gate 	} else if (out) {
1227*7c478bd9Sstevel@tonic-gate 		instr = "out";
1228*7c478bd9Sstevel@tonic-gate 	} else {
1229*7c478bd9Sstevel@tonic-gate 		instr = "???";
1230*7c478bd9Sstevel@tonic-gate 	}
1231*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "static frentry_t ipfrule_%s_%s;\n", instr, group);
1232*7c478bd9Sstevel@tonic-gate 
1233*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "\
1234*7c478bd9Sstevel@tonic-gate \n\
1235*7c478bd9Sstevel@tonic-gate int ipfrule_add_%s_%s()\n", instr, group);
1236*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "\
1237*7c478bd9Sstevel@tonic-gate {\n\
1238*7c478bd9Sstevel@tonic-gate 	int i, j, err = 0, max;\n\
1239*7c478bd9Sstevel@tonic-gate 	frentry_t *fp;\n");
1240*7c478bd9Sstevel@tonic-gate 
1241*7c478bd9Sstevel@tonic-gate 	if (dogrp)
1242*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "\
1243*7c478bd9Sstevel@tonic-gate 	frgroup_t *fg;\n");
1244*7c478bd9Sstevel@tonic-gate 
1245*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "\n");
1246*7c478bd9Sstevel@tonic-gate 
1247*7c478bd9Sstevel@tonic-gate 	for (i = 0, fr = grp->fg_start; fr != NULL; i++, fr = fr->fr_next)
1248*7c478bd9Sstevel@tonic-gate 		if (fr->fr_dsize > 0) {
1249*7c478bd9Sstevel@tonic-gate 			fprintf(fp, "\
1250*7c478bd9Sstevel@tonic-gate 	ipf_rules_%s_%s[%d]->fr_data = &ipf%s_rule_data_%s_%u;\n",
1251*7c478bd9Sstevel@tonic-gate 				instr, grp->fg_name, i,
1252*7c478bd9Sstevel@tonic-gate 				instr, grp->fg_name, i);
1253*7c478bd9Sstevel@tonic-gate 		}
1254*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "\
1255*7c478bd9Sstevel@tonic-gate 	max = sizeof(ipf_rules_%s_%s)/sizeof(frentry_t *);\n\
1256*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < max; i++) {\n\
1257*7c478bd9Sstevel@tonic-gate 		fp = ipf_rules_%s_%s[i];\n\
1258*7c478bd9Sstevel@tonic-gate 		fp->fr_next = NULL;\n", instr, group, instr, group);
1259*7c478bd9Sstevel@tonic-gate 
1260*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "\
1261*7c478bd9Sstevel@tonic-gate 		for (j = i + 1; j < max; j++)\n\
1262*7c478bd9Sstevel@tonic-gate 			if (strncmp(fp->fr_group,\n\
1263*7c478bd9Sstevel@tonic-gate 				    ipf_rules_%s_%s[j]->fr_group,\n\
1264*7c478bd9Sstevel@tonic-gate 				    FR_GROUPLEN) == 0) {\n\
1265*7c478bd9Sstevel@tonic-gate 				fp->fr_next = ipf_rules_%s_%s[j];\n\
1266*7c478bd9Sstevel@tonic-gate 				break;\n\
1267*7c478bd9Sstevel@tonic-gate 			}\n", instr, group, instr, group);
1268*7c478bd9Sstevel@tonic-gate 	if (dogrp)
1269*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "\
1270*7c478bd9Sstevel@tonic-gate \n\
1271*7c478bd9Sstevel@tonic-gate 		if (fp->fr_grhead != 0) {\n\
1272*7c478bd9Sstevel@tonic-gate 			fg = fr_addgroup(fp->fr_grhead, fp, FR_INQUE,\n\
1273*7c478bd9Sstevel@tonic-gate 					 IPL_LOGIPF, 0);\n\
1274*7c478bd9Sstevel@tonic-gate 			if (fg != NULL)\n\
1275*7c478bd9Sstevel@tonic-gate 				fp->fr_grp = &fg->fg_start;\n\
1276*7c478bd9Sstevel@tonic-gate 		}\n");
1277*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "\
1278*7c478bd9Sstevel@tonic-gate 	}\n\
1279*7c478bd9Sstevel@tonic-gate \n\
1280*7c478bd9Sstevel@tonic-gate 	fp = &ipfrule_%s_%s;\n", instr, group);
1281*7c478bd9Sstevel@tonic-gate 		fprintf(fp, "\
1282*7c478bd9Sstevel@tonic-gate 	bzero((char *)fp, sizeof(*fp));\n\
1283*7c478bd9Sstevel@tonic-gate 	fp->fr_type = FR_T_CALLFUNC|FR_T_BUILTIN;\n\
1284*7c478bd9Sstevel@tonic-gate 	fp->fr_flags = FR_%sQUE|FR_NOMATCH;\n\
1285*7c478bd9Sstevel@tonic-gate 	fp->fr_data = (void *)ipf_rules_%s_%s[0];\n",
1286*7c478bd9Sstevel@tonic-gate 		(in != 0) ? "IN" : "OUT", instr, group);
1287*7c478bd9Sstevel@tonic-gate 
1288*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "\
1289*7c478bd9Sstevel@tonic-gate 	fp->fr_v = 4;\n\
1290*7c478bd9Sstevel@tonic-gate 	fp->fr_func = (ipfunc_t)ipfrule_match_%s_%s;\n\
1291*7c478bd9Sstevel@tonic-gate 	err = frrequest(IPL_LOGIPF, SIOCADDFR, (caddr_t)fp, fr_active, 0);\n",
1292*7c478bd9Sstevel@tonic-gate 			instr, group);
1293*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "\treturn err;\n}\n");
1294*7c478bd9Sstevel@tonic-gate 
1295*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "\n\n\
1296*7c478bd9Sstevel@tonic-gate int ipfrule_remove_%s_%s()\n", instr, group);
1297*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "\
1298*7c478bd9Sstevel@tonic-gate {\n\
1299*7c478bd9Sstevel@tonic-gate 	int err = 0, i;\n\
1300*7c478bd9Sstevel@tonic-gate 	frentry_t *fp;\n\
1301*7c478bd9Sstevel@tonic-gate \n\
1302*7c478bd9Sstevel@tonic-gate 	/*\n\
1303*7c478bd9Sstevel@tonic-gate 	 * Try to remove the %sbound rule.\n", instr);
1304*7c478bd9Sstevel@tonic-gate 
1305*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "\
1306*7c478bd9Sstevel@tonic-gate 	 */\n\
1307*7c478bd9Sstevel@tonic-gate 	if (ipfrule_%s_%s.fr_ref > 0) {\n", instr, group);
1308*7c478bd9Sstevel@tonic-gate 
1309*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "\
1310*7c478bd9Sstevel@tonic-gate 		err = EBUSY;\n\
1311*7c478bd9Sstevel@tonic-gate 	} else {\n");
1312*7c478bd9Sstevel@tonic-gate 
1313*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "\
1314*7c478bd9Sstevel@tonic-gate 		i = sizeof(ipf_rules_%s_%s)/sizeof(frentry_t *) - 1;\n\
1315*7c478bd9Sstevel@tonic-gate 		for (; i >= 0; i--) {\n\
1316*7c478bd9Sstevel@tonic-gate 			fp = ipf_rules_%s_%s[i];\n\
1317*7c478bd9Sstevel@tonic-gate 			if (fp->fr_ref > 1) {\n\
1318*7c478bd9Sstevel@tonic-gate 				err = EBUSY;\n\
1319*7c478bd9Sstevel@tonic-gate 				break;\n\
1320*7c478bd9Sstevel@tonic-gate 			}\n\
1321*7c478bd9Sstevel@tonic-gate 		}\n\
1322*7c478bd9Sstevel@tonic-gate 	}\n\
1323*7c478bd9Sstevel@tonic-gate 	if (err == 0)\n\
1324*7c478bd9Sstevel@tonic-gate 		err = frrequest(IPL_LOGIPF, SIOCDELFR,\n\
1325*7c478bd9Sstevel@tonic-gate 				(caddr_t)&ipfrule_%s_%s, fr_active, 0);\n",
1326*7c478bd9Sstevel@tonic-gate 		instr, group, instr, group, instr, group);
1327*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "\
1328*7c478bd9Sstevel@tonic-gate 	if (err)\n\
1329*7c478bd9Sstevel@tonic-gate 		return err;\n\
1330*7c478bd9Sstevel@tonic-gate \n\n");
1331*7c478bd9Sstevel@tonic-gate 
1332*7c478bd9Sstevel@tonic-gate 	fprintf(fp, "\treturn err;\n}\n");
1333*7c478bd9Sstevel@tonic-gate }
1334