xref: /titanic_52/usr/src/cmd/ipf/lib/common/printfr.c (revision d6c23f6fbecbcca8ddd2b74c6e10f37095f9fd46)
17c478bd9Sstevel@tonic-gate /*
2*d6c23f6fSyx160601  * Copyright (C) 2000-2005 by Darren Reed.
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * See the IPFILTER.LICENCE file for details on licencing.
57c478bd9Sstevel@tonic-gate  *
6ab25eeb5Syz155240  * $Id: printfr.c,v 1.43.2.12 2005/06/12 07:18:42 darrenr Exp $
77c478bd9Sstevel@tonic-gate  *
81b47e080Sdr146992  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
97c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
107c478bd9Sstevel@tonic-gate  */
117c478bd9Sstevel@tonic-gate 
127c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
137c478bd9Sstevel@tonic-gate 
147c478bd9Sstevel@tonic-gate #include "ipf.h"
157c478bd9Sstevel@tonic-gate 
167c478bd9Sstevel@tonic-gate /*
177c478bd9Sstevel@tonic-gate  * print the filter structure in a useful way
187c478bd9Sstevel@tonic-gate  */
197c478bd9Sstevel@tonic-gate void	printfr(fp, iocfunc)
207c478bd9Sstevel@tonic-gate struct	frentry	*fp;
217c478bd9Sstevel@tonic-gate ioctlfunc_t	iocfunc;
227c478bd9Sstevel@tonic-gate {
237c478bd9Sstevel@tonic-gate 	struct protoent	*p;
247c478bd9Sstevel@tonic-gate 	u_short	sec[2];
257c478bd9Sstevel@tonic-gate 	u_32_t type;
267c478bd9Sstevel@tonic-gate 	u_char *t;
277c478bd9Sstevel@tonic-gate 	char *s;
287c478bd9Sstevel@tonic-gate 	int pr;
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate 	pr = -2;
317c478bd9Sstevel@tonic-gate 	type = fp->fr_type & ~FR_T_BUILTIN;
327c478bd9Sstevel@tonic-gate 
337c478bd9Sstevel@tonic-gate 	if ((fp->fr_type & FR_T_BUILTIN) != 0)
347c478bd9Sstevel@tonic-gate 		printf("# Builtin: ");
357c478bd9Sstevel@tonic-gate 
36ab25eeb5Syz155240 	if (fp->fr_collect != 0)
37ab25eeb5Syz155240 		printf("%u ", fp->fr_collect);
38ab25eeb5Syz155240 
397c478bd9Sstevel@tonic-gate 	if (fp->fr_type == FR_T_CALLFUNC) {
407c478bd9Sstevel@tonic-gate 		;
417c478bd9Sstevel@tonic-gate 	} else if (fp->fr_func != NULL) {
427c478bd9Sstevel@tonic-gate 		printf("call");
437c478bd9Sstevel@tonic-gate 		if ((fp->fr_flags & FR_CALLNOW) != 0)
447c478bd9Sstevel@tonic-gate 			printf(" now");
457c478bd9Sstevel@tonic-gate 		s = kvatoname(fp->fr_func, iocfunc);
467c478bd9Sstevel@tonic-gate 		printf(" %s/%u", s ? s : "?", fp->fr_arg);
477c478bd9Sstevel@tonic-gate 	} else if (FR_ISPASS(fp->fr_flags))
487c478bd9Sstevel@tonic-gate 		printf("pass");
497c478bd9Sstevel@tonic-gate 	else if (FR_ISBLOCK(fp->fr_flags)) {
507c478bd9Sstevel@tonic-gate 		printf("block");
517c478bd9Sstevel@tonic-gate 		if (fp->fr_flags & FR_RETICMP) {
527c478bd9Sstevel@tonic-gate 			if ((fp->fr_flags & FR_RETMASK) == FR_FAKEICMP)
537c478bd9Sstevel@tonic-gate 				printf(" return-icmp-as-dest");
547c478bd9Sstevel@tonic-gate 			else if ((fp->fr_flags & FR_RETMASK) == FR_RETICMP)
557c478bd9Sstevel@tonic-gate 				printf(" return-icmp");
567c478bd9Sstevel@tonic-gate 			if (fp->fr_icode) {
577c478bd9Sstevel@tonic-gate 				if (fp->fr_icode <= MAX_ICMPCODE)
587c478bd9Sstevel@tonic-gate 					printf("(%s)",
597c478bd9Sstevel@tonic-gate 						icmpcodes[(int)fp->fr_icode]);
607c478bd9Sstevel@tonic-gate 				else
617c478bd9Sstevel@tonic-gate 					printf("(%d)", fp->fr_icode);
627c478bd9Sstevel@tonic-gate 			}
637c478bd9Sstevel@tonic-gate 		} else if ((fp->fr_flags & FR_RETMASK) == FR_RETRST)
647c478bd9Sstevel@tonic-gate 			printf(" return-rst");
657c478bd9Sstevel@tonic-gate 	} else if ((fp->fr_flags & FR_LOGMASK) == FR_LOG) {
667c478bd9Sstevel@tonic-gate 		printlog(fp);
677c478bd9Sstevel@tonic-gate 	} else if (FR_ISACCOUNT(fp->fr_flags))
687c478bd9Sstevel@tonic-gate 		printf("count");
697c478bd9Sstevel@tonic-gate 	else if (FR_ISAUTH(fp->fr_flags))
707c478bd9Sstevel@tonic-gate 		printf("auth");
717c478bd9Sstevel@tonic-gate 	else if (FR_ISPREAUTH(fp->fr_flags))
727c478bd9Sstevel@tonic-gate 		printf("preauth");
737c478bd9Sstevel@tonic-gate 	else if (FR_ISNOMATCH(fp->fr_flags))
747c478bd9Sstevel@tonic-gate 		printf("nomatch");
757c478bd9Sstevel@tonic-gate 	else if (FR_ISSKIP(fp->fr_flags))
767c478bd9Sstevel@tonic-gate 		printf("skip %u", fp->fr_arg);
777c478bd9Sstevel@tonic-gate 	else {
787c478bd9Sstevel@tonic-gate 		printf("%x", fp->fr_flags);
797c478bd9Sstevel@tonic-gate 	}
807c478bd9Sstevel@tonic-gate 
817c478bd9Sstevel@tonic-gate 	if (fp->fr_flags & FR_OUTQUE)
827c478bd9Sstevel@tonic-gate 		printf(" out ");
837c478bd9Sstevel@tonic-gate 	else
847c478bd9Sstevel@tonic-gate 		printf(" in ");
857c478bd9Sstevel@tonic-gate 
867c478bd9Sstevel@tonic-gate 	if (((fp->fr_flags & FR_LOGB) == FR_LOGB) ||
877c478bd9Sstevel@tonic-gate 	    ((fp->fr_flags & FR_LOGP) == FR_LOGP)) {
887c478bd9Sstevel@tonic-gate 		printlog(fp);
897c478bd9Sstevel@tonic-gate 		putchar(' ');
907c478bd9Sstevel@tonic-gate 	}
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate 	if (fp->fr_flags & FR_QUICK)
937c478bd9Sstevel@tonic-gate 		printf("quick ");
947c478bd9Sstevel@tonic-gate 
957c478bd9Sstevel@tonic-gate 	if (*fp->fr_ifname) {
967c478bd9Sstevel@tonic-gate 		printifname("on ", fp->fr_ifname, fp->fr_ifa);
977c478bd9Sstevel@tonic-gate 		if (*fp->fr_ifnames[1] && strcmp(fp->fr_ifnames[1], "*"))
987c478bd9Sstevel@tonic-gate 			printifname(",", fp->fr_ifnames[1], fp->fr_ifas[1]);
997c478bd9Sstevel@tonic-gate 		putchar(' ');
100ab25eeb5Syz155240 	}
1017c478bd9Sstevel@tonic-gate 
102ab25eeb5Syz155240 	if (*fp->fr_dif.fd_ifname || (fp->fr_flags & FR_DUP))
1037c478bd9Sstevel@tonic-gate 		print_toif("dup-to", &fp->fr_dif);
1047c478bd9Sstevel@tonic-gate 	if (*fp->fr_tif.fd_ifname)
1057c478bd9Sstevel@tonic-gate 		print_toif("to", &fp->fr_tif);
106ab25eeb5Syz155240 	if (*fp->fr_rif.fd_ifname)
107ab25eeb5Syz155240 		print_toif("reply-to", &fp->fr_rif);
1087c478bd9Sstevel@tonic-gate 	if (fp->fr_flags & FR_FASTROUTE)
1097c478bd9Sstevel@tonic-gate 		printf("fastroute ");
1107c478bd9Sstevel@tonic-gate 
1117c478bd9Sstevel@tonic-gate 	if ((*fp->fr_ifnames[2] && strcmp(fp->fr_ifnames[2], "*")) ||
1127c478bd9Sstevel@tonic-gate 	    (*fp->fr_ifnames[3] && strcmp(fp->fr_ifnames[3], "*"))) {
1137c478bd9Sstevel@tonic-gate 		if (fp->fr_flags & FR_OUTQUE)
1147c478bd9Sstevel@tonic-gate 			printf("in-via ");
1157c478bd9Sstevel@tonic-gate 		else
1167c478bd9Sstevel@tonic-gate 			printf("out-via ");
1177c478bd9Sstevel@tonic-gate 
1187c478bd9Sstevel@tonic-gate 		if (*fp->fr_ifnames[2]) {
1197c478bd9Sstevel@tonic-gate 			printifname("", fp->fr_ifnames[2],
1207c478bd9Sstevel@tonic-gate 				    fp->fr_ifas[2]);
1217c478bd9Sstevel@tonic-gate 			putchar(' ');
1227c478bd9Sstevel@tonic-gate 
1237c478bd9Sstevel@tonic-gate 			if (*fp->fr_ifnames[3]) {
1247c478bd9Sstevel@tonic-gate 				printifname(",", fp->fr_ifnames[3],
1257c478bd9Sstevel@tonic-gate 					    fp->fr_ifas[3]);
1267c478bd9Sstevel@tonic-gate 			}
1277c478bd9Sstevel@tonic-gate 		}
1287c478bd9Sstevel@tonic-gate 	}
1297c478bd9Sstevel@tonic-gate 
1307c478bd9Sstevel@tonic-gate 	if (type == FR_T_IPF) {
1317c478bd9Sstevel@tonic-gate 		if (fp->fr_mip.fi_tos)
1327c478bd9Sstevel@tonic-gate 			printf("tos %#x ", fp->fr_tos);
1337c478bd9Sstevel@tonic-gate 		if (fp->fr_mip.fi_ttl)
1347c478bd9Sstevel@tonic-gate 			printf("ttl %d ", fp->fr_ttl);
1357c478bd9Sstevel@tonic-gate 		if (fp->fr_flx & FI_TCPUDP) {
1367c478bd9Sstevel@tonic-gate 			printf("proto tcp/udp ");
1377c478bd9Sstevel@tonic-gate 			pr = -1;
1387c478bd9Sstevel@tonic-gate 		} else if (fp->fr_mip.fi_p) {
1397c478bd9Sstevel@tonic-gate 			pr = fp->fr_ip.fi_p;
140ab25eeb5Syz155240 			p = getprotobynumber(pr);
141ab25eeb5Syz155240 			printf("proto ");
142ab25eeb5Syz155240 			printproto(p, pr, NULL);
143ab25eeb5Syz155240 			putchar(' ');
1447c478bd9Sstevel@tonic-gate 		}
1457c478bd9Sstevel@tonic-gate 	}
1467c478bd9Sstevel@tonic-gate 
1477c478bd9Sstevel@tonic-gate 	if (type == FR_T_NONE) {
1487c478bd9Sstevel@tonic-gate 		printf("all");
1497c478bd9Sstevel@tonic-gate 	} else if (type == FR_T_IPF) {
1507c478bd9Sstevel@tonic-gate 		printf("from %s", fp->fr_flags & FR_NOTSRCIP ? "!" : "");
151ab25eeb5Syz155240 		printaddr(fp->fr_v, fp->fr_satype, fp->fr_ifname,
152ab25eeb5Syz155240 			  &fp->fr_src.s_addr, &fp->fr_smsk.s_addr);
1537c478bd9Sstevel@tonic-gate 		if (fp->fr_scmp)
1547c478bd9Sstevel@tonic-gate 			printportcmp(pr, &fp->fr_tuc.ftu_src);
1557c478bd9Sstevel@tonic-gate 
1567c478bd9Sstevel@tonic-gate 		printf(" to %s", fp->fr_flags & FR_NOTDSTIP ? "!" : "");
157ab25eeb5Syz155240 		printaddr(fp->fr_v, fp->fr_datype, fp->fr_ifname,
158ab25eeb5Syz155240 			  &fp->fr_dst.s_addr, &fp->fr_dmsk.s_addr);
1597c478bd9Sstevel@tonic-gate 		if (fp->fr_dcmp)
1607c478bd9Sstevel@tonic-gate 			printportcmp(pr, &fp->fr_tuc.ftu_dst);
1617c478bd9Sstevel@tonic-gate 
1627663b816Sml37995 		if ((fp->fr_proto == IPPROTO_ICMP
1637663b816Sml37995 #ifdef	USE_INET6
1647663b816Sml37995 		    || fp->fr_proto == IPPROTO_ICMPV6
1657663b816Sml37995 #endif
1667663b816Sml37995 		    ) && fp->fr_icmpm) {
1677c478bd9Sstevel@tonic-gate 			int	type = fp->fr_icmp, code;
1687c478bd9Sstevel@tonic-gate 
1697c478bd9Sstevel@tonic-gate 			type = ntohs(fp->fr_icmp);
1707c478bd9Sstevel@tonic-gate 			code = type & 0xff;
1717c478bd9Sstevel@tonic-gate 			type /= 256;
1727c478bd9Sstevel@tonic-gate 			if (type < (sizeof(icmptypes) / sizeof(char *) - 1) &&
1737663b816Sml37995 			    icmptypes[type] && fp->fr_proto == IPPROTO_ICMP)
1747c478bd9Sstevel@tonic-gate 				printf(" icmp-type %s", icmptypes[type]);
1757c478bd9Sstevel@tonic-gate 			else
1767c478bd9Sstevel@tonic-gate 				printf(" icmp-type %d", type);
1777c478bd9Sstevel@tonic-gate 			if (ntohs(fp->fr_icmpm) & 0xff)
1787c478bd9Sstevel@tonic-gate 				printf(" code %d", code);
1797c478bd9Sstevel@tonic-gate 		}
1807c478bd9Sstevel@tonic-gate 		if ((fp->fr_proto == IPPROTO_TCP) &&
1817c478bd9Sstevel@tonic-gate 		    (fp->fr_tcpf || fp->fr_tcpfm)) {
1827c478bd9Sstevel@tonic-gate 			printf(" flags ");
1837c478bd9Sstevel@tonic-gate 			if (fp->fr_tcpf & ~TCPF_ALL)
1847c478bd9Sstevel@tonic-gate 				printf("0x%x", fp->fr_tcpf);
1857c478bd9Sstevel@tonic-gate 			else
1867c478bd9Sstevel@tonic-gate 				for (s = flagset, t = flags; *s; s++, t++)
1877c478bd9Sstevel@tonic-gate 					if (fp->fr_tcpf & *t)
1887c478bd9Sstevel@tonic-gate 						(void)putchar(*s);
1897c478bd9Sstevel@tonic-gate 			if (fp->fr_tcpfm) {
1907c478bd9Sstevel@tonic-gate 				(void)putchar('/');
1917c478bd9Sstevel@tonic-gate 				if (fp->fr_tcpfm & ~TCPF_ALL)
1927c478bd9Sstevel@tonic-gate 					printf("0x%x", fp->fr_tcpfm);
1937c478bd9Sstevel@tonic-gate 				else
1947c478bd9Sstevel@tonic-gate 					for (s = flagset, t = flags; *s;
1957c478bd9Sstevel@tonic-gate 					     s++, t++)
1967c478bd9Sstevel@tonic-gate 						if (fp->fr_tcpfm & *t)
1977c478bd9Sstevel@tonic-gate 							(void)putchar(*s);
1987c478bd9Sstevel@tonic-gate 			}
1997c478bd9Sstevel@tonic-gate 		}
2007c478bd9Sstevel@tonic-gate 	} else if (type == FR_T_BPFOPC) {
201ab25eeb5Syz155240 		fakebpf_t *fb;
2027c478bd9Sstevel@tonic-gate 		int i;
2037c478bd9Sstevel@tonic-gate 
204ab25eeb5Syz155240 		printf("bpf-v%d { \"", fp->fr_v);
205ab25eeb5Syz155240 		i = fp->fr_dsize / sizeof(*fb);
2067c478bd9Sstevel@tonic-gate 
207ab25eeb5Syz155240 		for (fb = fp->fr_data, s = ""; i; i--, fb++, s = " ")
208ab25eeb5Syz155240 			printf("%s%#x %#x %#x %#x", s, fb->fb_c, fb->fb_t,
209ab25eeb5Syz155240 			       fb->fb_f, fb->fb_k);
2107c478bd9Sstevel@tonic-gate 
211ab25eeb5Syz155240 		printf("\" }");
2127c478bd9Sstevel@tonic-gate 	} else if (type == FR_T_COMPIPF) {
2137c478bd9Sstevel@tonic-gate 		;
2147c478bd9Sstevel@tonic-gate 	} else if (type == FR_T_CALLFUNC) {
2157c478bd9Sstevel@tonic-gate 		printf("call function at %p", fp->fr_data);
2167c478bd9Sstevel@tonic-gate 	} else {
2177c478bd9Sstevel@tonic-gate 		printf("[unknown filter type %#x]", fp->fr_type);
2187c478bd9Sstevel@tonic-gate 	}
2197c478bd9Sstevel@tonic-gate 
220ab25eeb5Syz155240 	if ((type == FR_T_IPF) &&
221ab25eeb5Syz155240 	    ((fp->fr_flx & FI_WITH) || (fp->fr_mflx & FI_WITH) ||
222ab25eeb5Syz155240 	     fp->fr_optbits || fp->fr_optmask ||
223ab25eeb5Syz155240 	     fp->fr_secbits || fp->fr_secmask)) {
224ab25eeb5Syz155240 		char *comma = " ";
225ab25eeb5Syz155240 
226ab25eeb5Syz155240 		printf(" with");
227ab25eeb5Syz155240 		if (fp->fr_optbits || fp->fr_optmask ||
228ab25eeb5Syz155240 		    fp->fr_secbits || fp->fr_secmask) {
229ab25eeb5Syz155240 			sec[0] = fp->fr_secmask;
230ab25eeb5Syz155240 			sec[1] = fp->fr_secbits;
231ab25eeb5Syz155240 			if (fp->fr_v == 4)
232ab25eeb5Syz155240 				optprint(sec, fp->fr_optmask, fp->fr_optbits);
233ab25eeb5Syz155240 #ifdef	USE_INET6
234ab25eeb5Syz155240 			else
235ab25eeb5Syz155240 				optprintv6(sec, fp->fr_optmask,
236ab25eeb5Syz155240 					   fp->fr_optbits);
237ab25eeb5Syz155240 #endif
238ab25eeb5Syz155240 		} else if (fp->fr_mflx & FI_OPTIONS) {
239ab25eeb5Syz155240 			fputs(comma, stdout);
240ab25eeb5Syz155240 			if (!(fp->fr_flx & FI_OPTIONS))
241ab25eeb5Syz155240 				printf("not ");
242ab25eeb5Syz155240 			printf("ipopts");
243ab25eeb5Syz155240 			comma = ",";
244ab25eeb5Syz155240 		}
245ab25eeb5Syz155240 		if (fp->fr_mflx & FI_SHORT) {
246ab25eeb5Syz155240 			fputs(comma, stdout);
247ab25eeb5Syz155240 			if (!(fp->fr_flx & FI_SHORT))
248ab25eeb5Syz155240 				printf("not ");
249ab25eeb5Syz155240 			printf("short");
250ab25eeb5Syz155240 			comma = ",";
251ab25eeb5Syz155240 		}
252ab25eeb5Syz155240 		if (fp->fr_mflx & FI_FRAG) {
253ab25eeb5Syz155240 			fputs(comma, stdout);
254ab25eeb5Syz155240 			if (!(fp->fr_flx & FI_FRAG))
255ab25eeb5Syz155240 				printf("not ");
256ab25eeb5Syz155240 			printf("frag");
257ab25eeb5Syz155240 			comma = ",";
258ab25eeb5Syz155240 		}
259ab25eeb5Syz155240 		if (fp->fr_mflx & FI_FRAGBODY) {
260ab25eeb5Syz155240 			fputs(comma, stdout);
261ab25eeb5Syz155240 			if (!(fp->fr_flx & FI_FRAGBODY))
262ab25eeb5Syz155240 				printf("not ");
263ab25eeb5Syz155240 			printf("frag-body");
264ab25eeb5Syz155240 			comma = ",";
265ab25eeb5Syz155240 		}
266ab25eeb5Syz155240 		if (fp->fr_mflx & FI_NATED) {
267ab25eeb5Syz155240 			fputs(comma, stdout);
268ab25eeb5Syz155240 			if (!(fp->fr_flx & FI_NATED))
269ab25eeb5Syz155240 				printf("not ");
270ab25eeb5Syz155240 			printf("nat");
271ab25eeb5Syz155240 			comma = ",";
272ab25eeb5Syz155240 		}
273ab25eeb5Syz155240 		if (fp->fr_mflx & FI_LOWTTL) {
274ab25eeb5Syz155240 			fputs(comma, stdout);
275ab25eeb5Syz155240 			if (!(fp->fr_flx & FI_LOWTTL))
276ab25eeb5Syz155240 				printf("not ");
277ab25eeb5Syz155240 			printf("lowttl");
278ab25eeb5Syz155240 			comma = ",";
279ab25eeb5Syz155240 		}
280ab25eeb5Syz155240 		if (fp->fr_mflx & FI_BAD) {
281ab25eeb5Syz155240 			fputs(comma, stdout);
282ab25eeb5Syz155240 			if (!(fp->fr_flx & FI_BAD))
283ab25eeb5Syz155240 				printf("not ");
284ab25eeb5Syz155240 			printf("bad");
285ab25eeb5Syz155240 			comma = ",";
286ab25eeb5Syz155240 		}
287ab25eeb5Syz155240 		if (fp->fr_mflx & FI_BADSRC) {
288ab25eeb5Syz155240 			fputs(comma, stdout);
289ab25eeb5Syz155240 			if (!(fp->fr_flx & FI_BADSRC))
290ab25eeb5Syz155240 				printf("not ");
291ab25eeb5Syz155240 			printf("bad-src");
292ab25eeb5Syz155240 			comma = ",";
293ab25eeb5Syz155240 		}
294ab25eeb5Syz155240 		if (fp->fr_mflx & FI_BADNAT) {
295ab25eeb5Syz155240 			fputs(comma, stdout);
296ab25eeb5Syz155240 			if (!(fp->fr_flx & FI_BADNAT))
297ab25eeb5Syz155240 				printf("not ");
298ab25eeb5Syz155240 			printf("bad-nat");
299ab25eeb5Syz155240 			comma = ",";
300ab25eeb5Syz155240 		}
301ab25eeb5Syz155240 		if (fp->fr_mflx & FI_OOW) {
302ab25eeb5Syz155240 			fputs(comma, stdout);
303ab25eeb5Syz155240 			if (!(fp->fr_flx & FI_OOW))
304ab25eeb5Syz155240 				printf("not ");
305ab25eeb5Syz155240 			printf("oow");
306ab25eeb5Syz155240 		}
307ab25eeb5Syz155240 		if (fp->fr_mflx & FI_MULTICAST) {
308ab25eeb5Syz155240 			fputs(comma, stdout);
309ab25eeb5Syz155240 			if (!(fp->fr_flx & FI_MULTICAST))
310ab25eeb5Syz155240 				printf("not ");
3111b47e080Sdr146992 			printf("mcast");
312ab25eeb5Syz155240 			comma = ",";
313ab25eeb5Syz155240 		}
314ab25eeb5Syz155240 		if (fp->fr_mflx & FI_BROADCAST) {
315ab25eeb5Syz155240 			fputs(comma, stdout);
316ab25eeb5Syz155240 			if (!(fp->fr_flx & FI_BROADCAST))
317ab25eeb5Syz155240 				printf("not ");
318ab25eeb5Syz155240 			printf("bcast");
319ab25eeb5Syz155240 			comma = ",";
320ab25eeb5Syz155240 		}
321ab25eeb5Syz155240 		if (fp->fr_mflx & FI_MBCAST) {
322ab25eeb5Syz155240 			fputs(comma, stdout);
323ab25eeb5Syz155240 			if (!(fp->fr_flx & FI_MBCAST))
324ab25eeb5Syz155240 				printf("not ");
325ab25eeb5Syz155240 			printf("mbcast");
326ab25eeb5Syz155240 			comma = ",";
327ab25eeb5Syz155240 		}
328ab25eeb5Syz155240 		if (fp->fr_mflx & FI_STATE) {
329ab25eeb5Syz155240 			fputs(comma, stdout);
330ab25eeb5Syz155240 			if (!(fp->fr_flx & FI_STATE))
331ab25eeb5Syz155240 				printf("not ");
332ab25eeb5Syz155240 			printf("state");
333ab25eeb5Syz155240 			comma = ",";
334ab25eeb5Syz155240 		}
335ab25eeb5Syz155240 	}
336ab25eeb5Syz155240 
3377c478bd9Sstevel@tonic-gate 	if (fp->fr_flags & FR_KEEPSTATE) {
3387c478bd9Sstevel@tonic-gate 		printf(" keep state");
339ab25eeb5Syz155240 		if ((fp->fr_flags & (FR_STSTRICT|FR_NEWISN|FR_NOICMPERR|FR_STATESYNC)) ||
3407c478bd9Sstevel@tonic-gate 		    (fp->fr_statemax != 0) || (fp->fr_age[0] != 0)) {
341ab25eeb5Syz155240 			char *comma = "";
3427c478bd9Sstevel@tonic-gate 			printf(" (");
343ab25eeb5Syz155240 			if (fp->fr_statemax != 0) {
3447c478bd9Sstevel@tonic-gate 				printf("limit %u", fp->fr_statemax);
345ab25eeb5Syz155240 				comma = ",";
346ab25eeb5Syz155240 			}
347ab25eeb5Syz155240 			if (fp->fr_flags & FR_STSTRICT) {
348ab25eeb5Syz155240 				printf("%sstrict", comma);
349ab25eeb5Syz155240 				comma = ",";
350ab25eeb5Syz155240 			}
351ab25eeb5Syz155240 			if (fp->fr_flags & FR_NEWISN) {
352ab25eeb5Syz155240 				printf("%snewisn", comma);
353ab25eeb5Syz155240 				comma = ",";
354ab25eeb5Syz155240 			}
355ab25eeb5Syz155240 			if (fp->fr_flags & FR_NOICMPERR) {
356ab25eeb5Syz155240 				printf("%sno-icmp-err", comma);
357ab25eeb5Syz155240 				comma = ",";
358ab25eeb5Syz155240 			}
359ab25eeb5Syz155240 			if (fp->fr_flags & FR_STATESYNC) {
360ab25eeb5Syz155240 				printf("%ssync", comma);
361ab25eeb5Syz155240 				comma = ",";
362ab25eeb5Syz155240 			}
3637c478bd9Sstevel@tonic-gate 			if (fp->fr_age[0] || fp->fr_age[1])
364ab25eeb5Syz155240 				printf("%sage %d/%d", comma, fp->fr_age[0],
3657c478bd9Sstevel@tonic-gate 				       fp->fr_age[1]);
3667c478bd9Sstevel@tonic-gate 			printf(")");
3677c478bd9Sstevel@tonic-gate 		}
3687c478bd9Sstevel@tonic-gate 	}
3697c478bd9Sstevel@tonic-gate 	if (fp->fr_flags & FR_KEEPFRAG) {
3707c478bd9Sstevel@tonic-gate 		printf(" keep frags");
3717c478bd9Sstevel@tonic-gate 		if (fp->fr_flags & (FR_FRSTRICT)) {
3727c478bd9Sstevel@tonic-gate 			printf(" (");
3737c478bd9Sstevel@tonic-gate 			if (fp->fr_flags & FR_FRSTRICT)
3747c478bd9Sstevel@tonic-gate 				printf(" strict");
3757c478bd9Sstevel@tonic-gate 			printf(" )");
3767c478bd9Sstevel@tonic-gate 
3777c478bd9Sstevel@tonic-gate 		}
3787c478bd9Sstevel@tonic-gate 	}
3797c478bd9Sstevel@tonic-gate 	if (fp->fr_isc != (struct ipscan *)-1) {
3807c478bd9Sstevel@tonic-gate 		if (fp->fr_isctag[0])
3817c478bd9Sstevel@tonic-gate 			printf(" scan %s", fp->fr_isctag);
3827c478bd9Sstevel@tonic-gate 		else
3837c478bd9Sstevel@tonic-gate 			printf(" scan *");
3847c478bd9Sstevel@tonic-gate 	}
3857c478bd9Sstevel@tonic-gate 	if (*fp->fr_grhead != '\0')
3867c478bd9Sstevel@tonic-gate 		printf(" head %s", fp->fr_grhead);
3877c478bd9Sstevel@tonic-gate 	if (*fp->fr_group != '\0')
3887c478bd9Sstevel@tonic-gate 		printf(" group %s", fp->fr_group);
389ab25eeb5Syz155240 	if (fp->fr_logtag != FR_NOLOGTAG || *fp->fr_nattag.ipt_tag) {
390ab25eeb5Syz155240 		char *s = "";
391ab25eeb5Syz155240 
392ab25eeb5Syz155240 		printf(" set-tag(");
393ab25eeb5Syz155240 		if (fp->fr_logtag != FR_NOLOGTAG) {
394ab25eeb5Syz155240 			printf("log=%u", fp->fr_logtag);
395ab25eeb5Syz155240 			s = ", ";
396ab25eeb5Syz155240 		}
397ab25eeb5Syz155240 		if (*fp->fr_nattag.ipt_tag) {
398ab25eeb5Syz155240 			printf("%snat=%-.*s", s, IPFTAG_LEN,
399ab25eeb5Syz155240 				fp->fr_nattag.ipt_tag);
400ab25eeb5Syz155240 		}
401ab25eeb5Syz155240 		printf(")");
402ab25eeb5Syz155240 	}
4037c478bd9Sstevel@tonic-gate 	if (fp->fr_pps)
4047c478bd9Sstevel@tonic-gate 		printf(" pps %d", fp->fr_pps);
4057c478bd9Sstevel@tonic-gate 	(void)putchar('\n');
4067c478bd9Sstevel@tonic-gate }
407