xref: /onnv-gate/usr/src/cmd/ipf/lib/common/printfr.c (revision 492:0e64191f8bd0)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * Copyright (C) 1993-2001 by Darren Reed.
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * See the IPFILTER.LICENCE file for details on licencing.
50Sstevel@tonic-gate  *
60Sstevel@tonic-gate  * $Id: printfr.c,v 1.37 2003/06/03 16:01:12 darrenr Exp $
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
90Sstevel@tonic-gate  * Use is subject to license terms.
100Sstevel@tonic-gate  */
110Sstevel@tonic-gate 
120Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
130Sstevel@tonic-gate 
140Sstevel@tonic-gate #include "ipf.h"
150Sstevel@tonic-gate 
160Sstevel@tonic-gate 
170Sstevel@tonic-gate void printlookup(addr, mask)
180Sstevel@tonic-gate i6addr_t *addr, *mask;
190Sstevel@tonic-gate {
200Sstevel@tonic-gate 	switch (addr->iplookuptype)
210Sstevel@tonic-gate 	{
220Sstevel@tonic-gate 	case IPLT_POOL :
230Sstevel@tonic-gate 		printf("pool/");
240Sstevel@tonic-gate 		break;
250Sstevel@tonic-gate 	case IPLT_HASH :
260Sstevel@tonic-gate 		printf("hash/");
270Sstevel@tonic-gate 		break;
280Sstevel@tonic-gate 	default :
290Sstevel@tonic-gate 		printf("lookup(%x)=", addr->iplookuptype);
300Sstevel@tonic-gate 		break;
310Sstevel@tonic-gate 	}
320Sstevel@tonic-gate 
330Sstevel@tonic-gate 	printf("%u", addr->iplookupnum);
340Sstevel@tonic-gate 	if (opts & OPT_UNDEF) {
350Sstevel@tonic-gate 		if (mask->iplookupptr == NULL) {
360Sstevel@tonic-gate 			printf("(!)");
370Sstevel@tonic-gate 		}
380Sstevel@tonic-gate 	}
390Sstevel@tonic-gate }
400Sstevel@tonic-gate 
410Sstevel@tonic-gate 
420Sstevel@tonic-gate /*
430Sstevel@tonic-gate  * print the filter structure in a useful way
440Sstevel@tonic-gate  */
450Sstevel@tonic-gate void	printfr(fp, iocfunc)
460Sstevel@tonic-gate struct	frentry	*fp;
470Sstevel@tonic-gate ioctlfunc_t	iocfunc;
480Sstevel@tonic-gate {
490Sstevel@tonic-gate 	struct protoent	*p;
500Sstevel@tonic-gate 	u_short	sec[2];
510Sstevel@tonic-gate 	u_32_t type;
520Sstevel@tonic-gate 	u_char *t;
530Sstevel@tonic-gate 	char *s;
540Sstevel@tonic-gate 	int pr;
550Sstevel@tonic-gate 
560Sstevel@tonic-gate 	pr = -2;
570Sstevel@tonic-gate 	type = fp->fr_type & ~FR_T_BUILTIN;
580Sstevel@tonic-gate 
590Sstevel@tonic-gate 	if ((fp->fr_type & FR_T_BUILTIN) != 0)
600Sstevel@tonic-gate 		printf("# Builtin: ");
610Sstevel@tonic-gate 
620Sstevel@tonic-gate 	if (fp->fr_type == FR_T_CALLFUNC) {
630Sstevel@tonic-gate 		;
640Sstevel@tonic-gate 	} else if (fp->fr_func != NULL) {
650Sstevel@tonic-gate 		printf("call");
660Sstevel@tonic-gate 		if ((fp->fr_flags & FR_CALLNOW) != 0)
670Sstevel@tonic-gate 			printf(" now");
680Sstevel@tonic-gate 		s = kvatoname(fp->fr_func, iocfunc);
690Sstevel@tonic-gate 		printf(" %s/%u", s ? s : "?", fp->fr_arg);
700Sstevel@tonic-gate 	} else if (FR_ISPASS(fp->fr_flags))
710Sstevel@tonic-gate 		printf("pass");
720Sstevel@tonic-gate 	else if (FR_ISBLOCK(fp->fr_flags)) {
730Sstevel@tonic-gate 		printf("block");
740Sstevel@tonic-gate 		if (fp->fr_flags & FR_RETICMP) {
750Sstevel@tonic-gate 			if ((fp->fr_flags & FR_RETMASK) == FR_FAKEICMP)
760Sstevel@tonic-gate 				printf(" return-icmp-as-dest");
770Sstevel@tonic-gate 			else if ((fp->fr_flags & FR_RETMASK) == FR_RETICMP)
780Sstevel@tonic-gate 				printf(" return-icmp");
790Sstevel@tonic-gate 			if (fp->fr_icode) {
800Sstevel@tonic-gate 				if (fp->fr_icode <= MAX_ICMPCODE)
810Sstevel@tonic-gate 					printf("(%s)",
820Sstevel@tonic-gate 						icmpcodes[(int)fp->fr_icode]);
830Sstevel@tonic-gate 				else
840Sstevel@tonic-gate 					printf("(%d)", fp->fr_icode);
850Sstevel@tonic-gate 			}
860Sstevel@tonic-gate 		} else if ((fp->fr_flags & FR_RETMASK) == FR_RETRST)
870Sstevel@tonic-gate 			printf(" return-rst");
880Sstevel@tonic-gate 	} else if ((fp->fr_flags & FR_LOGMASK) == FR_LOG) {
890Sstevel@tonic-gate 		printlog(fp);
900Sstevel@tonic-gate 	} else if (FR_ISACCOUNT(fp->fr_flags))
910Sstevel@tonic-gate 		printf("count");
920Sstevel@tonic-gate 	else if (FR_ISAUTH(fp->fr_flags))
930Sstevel@tonic-gate 		printf("auth");
940Sstevel@tonic-gate 	else if (FR_ISPREAUTH(fp->fr_flags))
950Sstevel@tonic-gate 		printf("preauth");
960Sstevel@tonic-gate 	else if (FR_ISNOMATCH(fp->fr_flags))
970Sstevel@tonic-gate 		printf("nomatch");
980Sstevel@tonic-gate 	else if (FR_ISSKIP(fp->fr_flags))
990Sstevel@tonic-gate 		printf("skip %u", fp->fr_arg);
1000Sstevel@tonic-gate 	else {
1010Sstevel@tonic-gate 		printf("%x", fp->fr_flags);
1020Sstevel@tonic-gate 	}
1030Sstevel@tonic-gate 
1040Sstevel@tonic-gate 	if (fp->fr_flags & FR_OUTQUE)
1050Sstevel@tonic-gate 		printf(" out ");
1060Sstevel@tonic-gate 	else
1070Sstevel@tonic-gate 		printf(" in ");
1080Sstevel@tonic-gate 
1090Sstevel@tonic-gate 	if (((fp->fr_flags & FR_LOGB) == FR_LOGB) ||
1100Sstevel@tonic-gate 	    ((fp->fr_flags & FR_LOGP) == FR_LOGP)) {
1110Sstevel@tonic-gate 		printlog(fp);
1120Sstevel@tonic-gate 		putchar(' ');
1130Sstevel@tonic-gate 	}
1140Sstevel@tonic-gate 
1150Sstevel@tonic-gate 	if (fp->fr_flags & FR_QUICK)
1160Sstevel@tonic-gate 		printf("quick ");
1170Sstevel@tonic-gate 
1180Sstevel@tonic-gate 	if (*fp->fr_ifname) {
1190Sstevel@tonic-gate 		printifname("on ", fp->fr_ifname, fp->fr_ifa);
1200Sstevel@tonic-gate 		if (*fp->fr_ifnames[1] && strcmp(fp->fr_ifnames[1], "*"))
1210Sstevel@tonic-gate 			printifname(",", fp->fr_ifnames[1], fp->fr_ifas[1]);
1220Sstevel@tonic-gate 		putchar(' ');
1230Sstevel@tonic-gate 
1240Sstevel@tonic-gate 		if (*fp->fr_dif.fd_ifname)
1250Sstevel@tonic-gate 			print_toif("dup-to", &fp->fr_dif);
1260Sstevel@tonic-gate 		if (*fp->fr_tif.fd_ifname)
1270Sstevel@tonic-gate 			print_toif("to", &fp->fr_tif);
1280Sstevel@tonic-gate 		if (fp->fr_flags & FR_FASTROUTE)
1290Sstevel@tonic-gate 			printf("fastroute ");
1300Sstevel@tonic-gate 
1310Sstevel@tonic-gate 		if ((*fp->fr_ifnames[2] && strcmp(fp->fr_ifnames[2], "*")) ||
1320Sstevel@tonic-gate 		    (*fp->fr_ifnames[3] && strcmp(fp->fr_ifnames[3], "*"))) {
1330Sstevel@tonic-gate 			if (fp->fr_flags & FR_OUTQUE)
1340Sstevel@tonic-gate 				printf("in-via ");
1350Sstevel@tonic-gate 			else
1360Sstevel@tonic-gate 				printf("out-via ");
1370Sstevel@tonic-gate 
1380Sstevel@tonic-gate 			if (*fp->fr_ifnames[2]) {
1390Sstevel@tonic-gate 				printifname("", fp->fr_ifnames[2],
1400Sstevel@tonic-gate 					    fp->fr_ifas[2]);
1410Sstevel@tonic-gate 				putchar(' ');
1420Sstevel@tonic-gate 
1430Sstevel@tonic-gate 				if (*fp->fr_ifnames[3]) {
1440Sstevel@tonic-gate 					printifname(",", fp->fr_ifnames[3],
1450Sstevel@tonic-gate 						    fp->fr_ifas[3]);
1460Sstevel@tonic-gate 				}
1470Sstevel@tonic-gate 			}
1480Sstevel@tonic-gate 		}
1490Sstevel@tonic-gate 	}
1500Sstevel@tonic-gate 
1510Sstevel@tonic-gate 	if (type == FR_T_IPF) {
1520Sstevel@tonic-gate 		if (fp->fr_mip.fi_tos)
1530Sstevel@tonic-gate 			printf("tos %#x ", fp->fr_tos);
1540Sstevel@tonic-gate 		if (fp->fr_mip.fi_ttl)
1550Sstevel@tonic-gate 			printf("ttl %d ", fp->fr_ttl);
1560Sstevel@tonic-gate 		if (fp->fr_flx & FI_TCPUDP) {
1570Sstevel@tonic-gate 			printf("proto tcp/udp ");
1580Sstevel@tonic-gate 			pr = -1;
1590Sstevel@tonic-gate 		} else if (fp->fr_mip.fi_p) {
1600Sstevel@tonic-gate 			pr = fp->fr_ip.fi_p;
1610Sstevel@tonic-gate 			if ((p = getprotobynumber(fp->fr_proto)))
1620Sstevel@tonic-gate 				printf("proto %s ", p->p_name);
1630Sstevel@tonic-gate 			else
1640Sstevel@tonic-gate 				printf("proto %d ", fp->fr_proto);
1650Sstevel@tonic-gate 		}
1660Sstevel@tonic-gate 	}
1670Sstevel@tonic-gate 
1680Sstevel@tonic-gate 	if (type == FR_T_NONE) {
1690Sstevel@tonic-gate 		printf("all");
1700Sstevel@tonic-gate 	} else if (type == FR_T_IPF) {
1710Sstevel@tonic-gate 		printf("from %s", fp->fr_flags & FR_NOTSRCIP ? "!" : "");
1720Sstevel@tonic-gate 		if (fp->fr_satype != FRI_NORMAL) {
1730Sstevel@tonic-gate 			printf("%s", fp->fr_ifname);
1740Sstevel@tonic-gate 			if (fp->fr_satype == FRI_BROADCAST)
1750Sstevel@tonic-gate 				printf("/bcast");
1760Sstevel@tonic-gate 			else if (fp->fr_satype == FRI_NETWORK)
1770Sstevel@tonic-gate 				printf("/net");
1780Sstevel@tonic-gate 			else if (fp->fr_satype == FRI_NETMASKED)
1790Sstevel@tonic-gate 				printf("/netmasked");
1800Sstevel@tonic-gate 			else if (fp->fr_satype == FRI_PEERADDR)
1810Sstevel@tonic-gate 				printf("/peer");
1820Sstevel@tonic-gate 			else if (fp->fr_satype == FRI_LOOKUP)
1830Sstevel@tonic-gate 				printlookup(&fp->fr_ip.fi_src,
1840Sstevel@tonic-gate 					    &fp->fr_mip.fi_src);
1850Sstevel@tonic-gate 			else
1860Sstevel@tonic-gate 				printmask((u_32_t *)&fp->fr_smsk.s_addr);
1870Sstevel@tonic-gate 		} else
1880Sstevel@tonic-gate 			printhostmask(fp->fr_v, (u_32_t *)&fp->fr_src.s_addr,
1890Sstevel@tonic-gate 				      (u_32_t *)&fp->fr_smsk.s_addr);
1900Sstevel@tonic-gate 		if (fp->fr_scmp)
1910Sstevel@tonic-gate 			printportcmp(pr, &fp->fr_tuc.ftu_src);
1920Sstevel@tonic-gate 
1930Sstevel@tonic-gate 		printf(" to %s", fp->fr_flags & FR_NOTDSTIP ? "!" : "");
1940Sstevel@tonic-gate 		if (fp->fr_datype != FRI_NORMAL) {
1950Sstevel@tonic-gate 			printf("%s", fp->fr_ifname);
1960Sstevel@tonic-gate 			if (fp->fr_datype == FRI_BROADCAST)
1970Sstevel@tonic-gate 				printf("/bcast");
1980Sstevel@tonic-gate 			else if (fp->fr_datype == FRI_NETWORK)
1990Sstevel@tonic-gate 				printf("/net");
2000Sstevel@tonic-gate 			else if (fp->fr_datype == FRI_NETMASKED)
2010Sstevel@tonic-gate 				printf("/netmasked");
2020Sstevel@tonic-gate 			else if (fp->fr_datype == FRI_PEERADDR)
2030Sstevel@tonic-gate 				printf("/peer");
2040Sstevel@tonic-gate 			else if (fp->fr_datype == FRI_LOOKUP)
2050Sstevel@tonic-gate 				printlookup(&fp->fr_ip.fi_dst,
2060Sstevel@tonic-gate 					    &fp->fr_mip.fi_dst);
2070Sstevel@tonic-gate 			else
2080Sstevel@tonic-gate 				printmask((u_32_t *)&fp->fr_dmsk.s_addr);
2090Sstevel@tonic-gate 		} else
2100Sstevel@tonic-gate 			printhostmask(fp->fr_v, (u_32_t *)&fp->fr_dst.s_addr,
2110Sstevel@tonic-gate 				      (u_32_t *)&fp->fr_dmsk.s_addr);
2120Sstevel@tonic-gate 		if (fp->fr_dcmp)
2130Sstevel@tonic-gate 			printportcmp(pr, &fp->fr_tuc.ftu_dst);
2140Sstevel@tonic-gate 
2150Sstevel@tonic-gate 		if ((fp->fr_flx & FI_WITH) || (fp->fr_mflx & FI_WITH) ||
2160Sstevel@tonic-gate 		    fp->fr_optbits || fp->fr_optmask ||
2170Sstevel@tonic-gate 		    fp->fr_secbits || fp->fr_secmask) {
2180Sstevel@tonic-gate 			printf(" with");
2190Sstevel@tonic-gate 			if (fp->fr_optbits || fp->fr_optmask ||
2200Sstevel@tonic-gate 			    fp->fr_secbits || fp->fr_secmask) {
2210Sstevel@tonic-gate 				sec[0] = fp->fr_secmask;
2220Sstevel@tonic-gate 				sec[1] = fp->fr_secbits;
2230Sstevel@tonic-gate 				if (fp->fr_v == 4)
2240Sstevel@tonic-gate 					optprint(sec, fp->fr_optmask,
2250Sstevel@tonic-gate 						 fp->fr_optbits);
2260Sstevel@tonic-gate #ifdef	USE_INET6
2270Sstevel@tonic-gate 				else
2280Sstevel@tonic-gate 					optprintv6(sec, fp->fr_optmask,
2290Sstevel@tonic-gate 						   fp->fr_optbits);
2300Sstevel@tonic-gate #endif
2310Sstevel@tonic-gate 			} else if (fp->fr_mflx & FI_OPTIONS) {
2320Sstevel@tonic-gate 				if (!(fp->fr_flx & FI_OPTIONS))
2330Sstevel@tonic-gate 					printf(" not");
2340Sstevel@tonic-gate 				printf(" ipopts");
2350Sstevel@tonic-gate 			}
2360Sstevel@tonic-gate 			if (fp->fr_mflx & FI_SHORT) {
2370Sstevel@tonic-gate 				if (!(fp->fr_flx & FI_SHORT))
2380Sstevel@tonic-gate 					printf(" not");
2390Sstevel@tonic-gate 				printf(" short");
2400Sstevel@tonic-gate 			}
2410Sstevel@tonic-gate 			if (fp->fr_mflx & FI_FRAG) {
2420Sstevel@tonic-gate 				if (!(fp->fr_flx & FI_FRAG))
2430Sstevel@tonic-gate 					printf(" not");
2440Sstevel@tonic-gate 				printf(" frag");
2450Sstevel@tonic-gate 			}
2460Sstevel@tonic-gate 			if (fp->fr_mflx & FI_NATED) {
2470Sstevel@tonic-gate 				if (!(fp->fr_flx & FI_NATED))
2480Sstevel@tonic-gate 					printf(" not");
2490Sstevel@tonic-gate 				printf(" nat");
2500Sstevel@tonic-gate 			}
251*492Syx160601 			if (fp->fr_mflx & FI_MULTICAST) {
252*492Syx160601 				if (!(fp->fr_flx & FI_MULTICAST))
253*492Syx160601 					printf(" not");
254*492Syx160601 				printf(" multicast");
255*492Syx160601 			}
256*492Syx160601 			if (fp->fr_mflx & FI_BROADCAST) {
257*492Syx160601 				if (!(fp->fr_flx & FI_BROADCAST))
258*492Syx160601 					printf(" not");
259*492Syx160601 				printf(" bcast");
260*492Syx160601 			}
261*492Syx160601 			if (fp->fr_mflx & FI_MBCAST) {
262*492Syx160601 				if (!(fp->fr_flx & FI_MBCAST))
263*492Syx160601 					printf(" not");
264*492Syx160601 				printf(" mbcast");
265*492Syx160601 			}
266*492Syx160601 			if (fp->fr_mflx & FI_STATE) {
267*492Syx160601 				if (!(fp->fr_flx & FI_STATE))
268*492Syx160601 					printf(" not");
269*492Syx160601 				printf(" state");
270*492Syx160601 			}
271*492Syx160601 			if (fp->fr_mflx & FI_BADNAT) {
272*492Syx160601 				if (!(fp->fr_flx & FI_BADNAT))
273*492Syx160601 					printf(" not");
274*492Syx160601 				printf(" bad-nat");
275*492Syx160601 			}
276*492Syx160601 			if (fp->fr_mflx & FI_BAD) {
277*492Syx160601 				if (!(fp->fr_flx & FI_BAD))
278*492Syx160601 					printf(" not");
279*492Syx160601 				printf(" bad");
280*492Syx160601 			}
281*492Syx160601 			if (fp->fr_mflx & FI_OOW) {
282*492Syx160601 				if (!(fp->fr_flx & FI_OOW))
283*492Syx160601 					printf(" not");
284*492Syx160601 				printf(" oow");
285*492Syx160601 			}
2860Sstevel@tonic-gate 			if (fp->fr_mflx & FI_LOWTTL) {
2870Sstevel@tonic-gate 				if (!(fp->fr_flx & FI_LOWTTL))
2880Sstevel@tonic-gate 					printf(" not");
2890Sstevel@tonic-gate 				printf(" lowttl");
2900Sstevel@tonic-gate 			}
2910Sstevel@tonic-gate 			if (fp->fr_mflx & FI_BADSRC) {
2920Sstevel@tonic-gate 				if (!(fp->fr_flx & FI_BADSRC))
2930Sstevel@tonic-gate 					printf(" not");
2940Sstevel@tonic-gate 				printf(" bad-src");
2950Sstevel@tonic-gate 			}
2960Sstevel@tonic-gate 		}
2970Sstevel@tonic-gate 		if (fp->fr_proto == IPPROTO_ICMP && fp->fr_icmpm) {
2980Sstevel@tonic-gate 			int	type = fp->fr_icmp, code;
2990Sstevel@tonic-gate 
3000Sstevel@tonic-gate 			type = ntohs(fp->fr_icmp);
3010Sstevel@tonic-gate 			code = type & 0xff;
3020Sstevel@tonic-gate 			type /= 256;
3030Sstevel@tonic-gate 			if (type < (sizeof(icmptypes) / sizeof(char *) - 1) &&
3040Sstevel@tonic-gate 			    icmptypes[type])
3050Sstevel@tonic-gate 				printf(" icmp-type %s", icmptypes[type]);
3060Sstevel@tonic-gate 			else
3070Sstevel@tonic-gate 				printf(" icmp-type %d", type);
3080Sstevel@tonic-gate 			if (ntohs(fp->fr_icmpm) & 0xff)
3090Sstevel@tonic-gate 				printf(" code %d", code);
3100Sstevel@tonic-gate 		}
3110Sstevel@tonic-gate 		if ((fp->fr_proto == IPPROTO_TCP) &&
3120Sstevel@tonic-gate 		    (fp->fr_tcpf || fp->fr_tcpfm)) {
3130Sstevel@tonic-gate 			printf(" flags ");
3140Sstevel@tonic-gate 			if (fp->fr_tcpf & ~TCPF_ALL)
3150Sstevel@tonic-gate 				printf("0x%x", fp->fr_tcpf);
3160Sstevel@tonic-gate 			else
3170Sstevel@tonic-gate 				for (s = flagset, t = flags; *s; s++, t++)
3180Sstevel@tonic-gate 					if (fp->fr_tcpf & *t)
3190Sstevel@tonic-gate 						(void)putchar(*s);
3200Sstevel@tonic-gate 			if (fp->fr_tcpfm) {
3210Sstevel@tonic-gate 				(void)putchar('/');
3220Sstevel@tonic-gate 				if (fp->fr_tcpfm & ~TCPF_ALL)
3230Sstevel@tonic-gate 					printf("0x%x", fp->fr_tcpfm);
3240Sstevel@tonic-gate 				else
3250Sstevel@tonic-gate 					for (s = flagset, t = flags; *s;
3260Sstevel@tonic-gate 					     s++, t++)
3270Sstevel@tonic-gate 						if (fp->fr_tcpfm & *t)
3280Sstevel@tonic-gate 							(void)putchar(*s);
3290Sstevel@tonic-gate 			}
3300Sstevel@tonic-gate 		}
3310Sstevel@tonic-gate #ifdef IPFILTER_BPF
3320Sstevel@tonic-gate 	} else if (type == FR_T_BPFOPC) {
3330Sstevel@tonic-gate 		u_32_t *bp;
3340Sstevel@tonic-gate 		int i;
3350Sstevel@tonic-gate 
3360Sstevel@tonic-gate 		printf("{");
3370Sstevel@tonic-gate 		i = fp->fr_dsize / sizeof(*bp);
3380Sstevel@tonic-gate 
3390Sstevel@tonic-gate 		for (bp = fp->fr_data; i; i--, bp++)
3400Sstevel@tonic-gate 			printf(" 0x%08x", *bp);
3410Sstevel@tonic-gate 
3420Sstevel@tonic-gate 		printf(" }");
3430Sstevel@tonic-gate #endif
3440Sstevel@tonic-gate 	} else if (type == FR_T_COMPIPF) {
3450Sstevel@tonic-gate 		;
3460Sstevel@tonic-gate 	} else if (type == FR_T_CALLFUNC) {
3470Sstevel@tonic-gate 		printf("call function at %p", fp->fr_data);
3480Sstevel@tonic-gate 	} else {
3490Sstevel@tonic-gate 		printf("[unknown filter type %#x]", fp->fr_type);
3500Sstevel@tonic-gate 	}
3510Sstevel@tonic-gate 
3520Sstevel@tonic-gate 	if (fp->fr_flags & FR_KEEPSTATE) {
3530Sstevel@tonic-gate 		printf(" keep state");
3540Sstevel@tonic-gate 		if ((fp->fr_flags & (FR_STSTRICT|FR_NEWISN)) ||
3550Sstevel@tonic-gate 		    (fp->fr_statemax != 0) || (fp->fr_age[0] != 0)) {
3560Sstevel@tonic-gate 			printf(" (");
3570Sstevel@tonic-gate 			if (fp->fr_statemax != 0)
3580Sstevel@tonic-gate 				printf(" limit %u", fp->fr_statemax);
3590Sstevel@tonic-gate 			if (fp->fr_flags & FR_FRSTRICT)
3600Sstevel@tonic-gate 				printf(" strict");
3610Sstevel@tonic-gate 			if (fp->fr_flags & FR_NEWISN)
3620Sstevel@tonic-gate 				printf(" newisn");
3630Sstevel@tonic-gate 			if (fp->fr_age[0] || fp->fr_age[1])
3640Sstevel@tonic-gate 				printf(" age %d/%d", fp->fr_age[0],
3650Sstevel@tonic-gate 				       fp->fr_age[1]);
3660Sstevel@tonic-gate 			printf(" )");
3670Sstevel@tonic-gate 		}
3680Sstevel@tonic-gate 	}
3690Sstevel@tonic-gate 	if (fp->fr_flags & FR_KEEPFRAG) {
3700Sstevel@tonic-gate 		printf(" keep frags");
3710Sstevel@tonic-gate 		if (fp->fr_flags & (FR_FRSTRICT)) {
3720Sstevel@tonic-gate 			printf(" (");
3730Sstevel@tonic-gate 			if (fp->fr_flags & FR_FRSTRICT)
3740Sstevel@tonic-gate 				printf(" strict");
3750Sstevel@tonic-gate 			printf(" )");
3760Sstevel@tonic-gate 
3770Sstevel@tonic-gate 		}
3780Sstevel@tonic-gate 	}
3790Sstevel@tonic-gate 	if (fp->fr_isc != (struct ipscan *)-1) {
3800Sstevel@tonic-gate 		if (fp->fr_isctag[0])
3810Sstevel@tonic-gate 			printf(" scan %s", fp->fr_isctag);
3820Sstevel@tonic-gate 		else
3830Sstevel@tonic-gate 			printf(" scan *");
3840Sstevel@tonic-gate 	}
3850Sstevel@tonic-gate 	if (*fp->fr_grhead != '\0')
3860Sstevel@tonic-gate 		printf(" head %s", fp->fr_grhead);
3870Sstevel@tonic-gate 	if (*fp->fr_group != '\0')
3880Sstevel@tonic-gate 		printf(" group %s", fp->fr_group);
3890Sstevel@tonic-gate 	if (fp->fr_logtag != FR_NOLOGTAG)
3900Sstevel@tonic-gate 		printf(" log-tag %u", fp->fr_logtag);
3910Sstevel@tonic-gate 	if (fp->fr_pps)
3920Sstevel@tonic-gate 		printf(" pps %d", fp->fr_pps);
3930Sstevel@tonic-gate 	(void)putchar('\n');
3940Sstevel@tonic-gate }
395