xref: /onnv-gate/usr/src/cmd/ipf/lib/common/printfr.c (revision 7176:101cc5da1498)
10Sstevel@tonic-gate /*
2*7176Syx160601  * Copyright (C) 2000-2005 by Darren Reed.
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * See the IPFILTER.LICENCE file for details on licencing.
50Sstevel@tonic-gate  *
62393Syz155240  * $Id: printfr.c,v 1.43.2.12 2005/06/12 07:18:42 darrenr Exp $
70Sstevel@tonic-gate  *
85868Sdr146992  * Copyright 2008 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  * print the filter structure in a useful way
180Sstevel@tonic-gate  */
printfr(fp,iocfunc)190Sstevel@tonic-gate void	printfr(fp, iocfunc)
200Sstevel@tonic-gate struct	frentry	*fp;
210Sstevel@tonic-gate ioctlfunc_t	iocfunc;
220Sstevel@tonic-gate {
230Sstevel@tonic-gate 	struct protoent	*p;
240Sstevel@tonic-gate 	u_short	sec[2];
250Sstevel@tonic-gate 	u_32_t type;
260Sstevel@tonic-gate 	u_char *t;
270Sstevel@tonic-gate 	char *s;
280Sstevel@tonic-gate 	int pr;
290Sstevel@tonic-gate 
300Sstevel@tonic-gate 	pr = -2;
310Sstevel@tonic-gate 	type = fp->fr_type & ~FR_T_BUILTIN;
320Sstevel@tonic-gate 
330Sstevel@tonic-gate 	if ((fp->fr_type & FR_T_BUILTIN) != 0)
340Sstevel@tonic-gate 		printf("# Builtin: ");
350Sstevel@tonic-gate 
362393Syz155240 	if (fp->fr_collect != 0)
372393Syz155240 		printf("%u ", fp->fr_collect);
382393Syz155240 
390Sstevel@tonic-gate 	if (fp->fr_type == FR_T_CALLFUNC) {
400Sstevel@tonic-gate 		;
410Sstevel@tonic-gate 	} else if (fp->fr_func != NULL) {
420Sstevel@tonic-gate 		printf("call");
430Sstevel@tonic-gate 		if ((fp->fr_flags & FR_CALLNOW) != 0)
440Sstevel@tonic-gate 			printf(" now");
450Sstevel@tonic-gate 		s = kvatoname(fp->fr_func, iocfunc);
460Sstevel@tonic-gate 		printf(" %s/%u", s ? s : "?", fp->fr_arg);
470Sstevel@tonic-gate 	} else if (FR_ISPASS(fp->fr_flags))
480Sstevel@tonic-gate 		printf("pass");
490Sstevel@tonic-gate 	else if (FR_ISBLOCK(fp->fr_flags)) {
500Sstevel@tonic-gate 		printf("block");
510Sstevel@tonic-gate 		if (fp->fr_flags & FR_RETICMP) {
520Sstevel@tonic-gate 			if ((fp->fr_flags & FR_RETMASK) == FR_FAKEICMP)
530Sstevel@tonic-gate 				printf(" return-icmp-as-dest");
540Sstevel@tonic-gate 			else if ((fp->fr_flags & FR_RETMASK) == FR_RETICMP)
550Sstevel@tonic-gate 				printf(" return-icmp");
560Sstevel@tonic-gate 			if (fp->fr_icode) {
570Sstevel@tonic-gate 				if (fp->fr_icode <= MAX_ICMPCODE)
580Sstevel@tonic-gate 					printf("(%s)",
590Sstevel@tonic-gate 						icmpcodes[(int)fp->fr_icode]);
600Sstevel@tonic-gate 				else
610Sstevel@tonic-gate 					printf("(%d)", fp->fr_icode);
620Sstevel@tonic-gate 			}
630Sstevel@tonic-gate 		} else if ((fp->fr_flags & FR_RETMASK) == FR_RETRST)
640Sstevel@tonic-gate 			printf(" return-rst");
650Sstevel@tonic-gate 	} else if ((fp->fr_flags & FR_LOGMASK) == FR_LOG) {
660Sstevel@tonic-gate 		printlog(fp);
670Sstevel@tonic-gate 	} else if (FR_ISACCOUNT(fp->fr_flags))
680Sstevel@tonic-gate 		printf("count");
690Sstevel@tonic-gate 	else if (FR_ISAUTH(fp->fr_flags))
700Sstevel@tonic-gate 		printf("auth");
710Sstevel@tonic-gate 	else if (FR_ISPREAUTH(fp->fr_flags))
720Sstevel@tonic-gate 		printf("preauth");
730Sstevel@tonic-gate 	else if (FR_ISNOMATCH(fp->fr_flags))
740Sstevel@tonic-gate 		printf("nomatch");
750Sstevel@tonic-gate 	else if (FR_ISSKIP(fp->fr_flags))
760Sstevel@tonic-gate 		printf("skip %u", fp->fr_arg);
770Sstevel@tonic-gate 	else {
780Sstevel@tonic-gate 		printf("%x", fp->fr_flags);
790Sstevel@tonic-gate 	}
800Sstevel@tonic-gate 
810Sstevel@tonic-gate 	if (fp->fr_flags & FR_OUTQUE)
820Sstevel@tonic-gate 		printf(" out ");
830Sstevel@tonic-gate 	else
840Sstevel@tonic-gate 		printf(" in ");
850Sstevel@tonic-gate 
860Sstevel@tonic-gate 	if (((fp->fr_flags & FR_LOGB) == FR_LOGB) ||
870Sstevel@tonic-gate 	    ((fp->fr_flags & FR_LOGP) == FR_LOGP)) {
880Sstevel@tonic-gate 		printlog(fp);
890Sstevel@tonic-gate 		putchar(' ');
900Sstevel@tonic-gate 	}
910Sstevel@tonic-gate 
920Sstevel@tonic-gate 	if (fp->fr_flags & FR_QUICK)
930Sstevel@tonic-gate 		printf("quick ");
940Sstevel@tonic-gate 
950Sstevel@tonic-gate 	if (*fp->fr_ifname) {
960Sstevel@tonic-gate 		printifname("on ", fp->fr_ifname, fp->fr_ifa);
970Sstevel@tonic-gate 		if (*fp->fr_ifnames[1] && strcmp(fp->fr_ifnames[1], "*"))
980Sstevel@tonic-gate 			printifname(",", fp->fr_ifnames[1], fp->fr_ifas[1]);
990Sstevel@tonic-gate 		putchar(' ');
1002393Syz155240 	}
1010Sstevel@tonic-gate 
1022393Syz155240 	if (*fp->fr_dif.fd_ifname || (fp->fr_flags & FR_DUP))
1032393Syz155240 		print_toif("dup-to", &fp->fr_dif);
1042393Syz155240 	if (*fp->fr_tif.fd_ifname)
1052393Syz155240 		print_toif("to", &fp->fr_tif);
1062393Syz155240 	if (*fp->fr_rif.fd_ifname)
1072393Syz155240 		print_toif("reply-to", &fp->fr_rif);
1082393Syz155240 	if (fp->fr_flags & FR_FASTROUTE)
1092393Syz155240 		printf("fastroute ");
1100Sstevel@tonic-gate 
1112393Syz155240 	if ((*fp->fr_ifnames[2] && strcmp(fp->fr_ifnames[2], "*")) ||
1122393Syz155240 	    (*fp->fr_ifnames[3] && strcmp(fp->fr_ifnames[3], "*"))) {
1132393Syz155240 		if (fp->fr_flags & FR_OUTQUE)
1142393Syz155240 			printf("in-via ");
1152393Syz155240 		else
1162393Syz155240 			printf("out-via ");
1170Sstevel@tonic-gate 
1182393Syz155240 		if (*fp->fr_ifnames[2]) {
1192393Syz155240 			printifname("", fp->fr_ifnames[2],
1202393Syz155240 				    fp->fr_ifas[2]);
1212393Syz155240 			putchar(' ');
1220Sstevel@tonic-gate 
1232393Syz155240 			if (*fp->fr_ifnames[3]) {
1242393Syz155240 				printifname(",", fp->fr_ifnames[3],
1252393Syz155240 					    fp->fr_ifas[3]);
1260Sstevel@tonic-gate 			}
1270Sstevel@tonic-gate 		}
1280Sstevel@tonic-gate 	}
1290Sstevel@tonic-gate 
1300Sstevel@tonic-gate 	if (type == FR_T_IPF) {
1310Sstevel@tonic-gate 		if (fp->fr_mip.fi_tos)
1320Sstevel@tonic-gate 			printf("tos %#x ", fp->fr_tos);
1330Sstevel@tonic-gate 		if (fp->fr_mip.fi_ttl)
1340Sstevel@tonic-gate 			printf("ttl %d ", fp->fr_ttl);
1350Sstevel@tonic-gate 		if (fp->fr_flx & FI_TCPUDP) {
1360Sstevel@tonic-gate 			printf("proto tcp/udp ");
1370Sstevel@tonic-gate 			pr = -1;
1380Sstevel@tonic-gate 		} else if (fp->fr_mip.fi_p) {
1390Sstevel@tonic-gate 			pr = fp->fr_ip.fi_p;
1402393Syz155240 			p = getprotobynumber(pr);
1412393Syz155240 			printf("proto ");
1422393Syz155240 			printproto(p, pr, NULL);
1432393Syz155240 			putchar(' ');
1440Sstevel@tonic-gate 		}
1450Sstevel@tonic-gate 	}
1460Sstevel@tonic-gate 
1470Sstevel@tonic-gate 	if (type == FR_T_NONE) {
1480Sstevel@tonic-gate 		printf("all");
1490Sstevel@tonic-gate 	} else if (type == FR_T_IPF) {
1500Sstevel@tonic-gate 		printf("from %s", fp->fr_flags & FR_NOTSRCIP ? "!" : "");
1512393Syz155240 		printaddr(fp->fr_v, fp->fr_satype, fp->fr_ifname,
1522393Syz155240 			  &fp->fr_src.s_addr, &fp->fr_smsk.s_addr);
1530Sstevel@tonic-gate 		if (fp->fr_scmp)
1540Sstevel@tonic-gate 			printportcmp(pr, &fp->fr_tuc.ftu_src);
1550Sstevel@tonic-gate 
1560Sstevel@tonic-gate 		printf(" to %s", fp->fr_flags & FR_NOTDSTIP ? "!" : "");
1572393Syz155240 		printaddr(fp->fr_v, fp->fr_datype, fp->fr_ifname,
1582393Syz155240 			  &fp->fr_dst.s_addr, &fp->fr_dmsk.s_addr);
1590Sstevel@tonic-gate 		if (fp->fr_dcmp)
1600Sstevel@tonic-gate 			printportcmp(pr, &fp->fr_tuc.ftu_dst);
1610Sstevel@tonic-gate 
162637Sml37995 		if ((fp->fr_proto == IPPROTO_ICMP
163637Sml37995 #ifdef	USE_INET6
164637Sml37995 		    || fp->fr_proto == IPPROTO_ICMPV6
165637Sml37995 #endif
166637Sml37995 		    ) && fp->fr_icmpm) {
1670Sstevel@tonic-gate 			int	type = fp->fr_icmp, code;
1680Sstevel@tonic-gate 
1690Sstevel@tonic-gate 			type = ntohs(fp->fr_icmp);
1700Sstevel@tonic-gate 			code = type & 0xff;
1710Sstevel@tonic-gate 			type /= 256;
1720Sstevel@tonic-gate 			if (type < (sizeof(icmptypes) / sizeof(char *) - 1) &&
173637Sml37995 			    icmptypes[type] && fp->fr_proto == IPPROTO_ICMP)
1740Sstevel@tonic-gate 				printf(" icmp-type %s", icmptypes[type]);
1750Sstevel@tonic-gate 			else
1760Sstevel@tonic-gate 				printf(" icmp-type %d", type);
1770Sstevel@tonic-gate 			if (ntohs(fp->fr_icmpm) & 0xff)
1780Sstevel@tonic-gate 				printf(" code %d", code);
1790Sstevel@tonic-gate 		}
1800Sstevel@tonic-gate 		if ((fp->fr_proto == IPPROTO_TCP) &&
1810Sstevel@tonic-gate 		    (fp->fr_tcpf || fp->fr_tcpfm)) {
1820Sstevel@tonic-gate 			printf(" flags ");
1830Sstevel@tonic-gate 			if (fp->fr_tcpf & ~TCPF_ALL)
1840Sstevel@tonic-gate 				printf("0x%x", fp->fr_tcpf);
1850Sstevel@tonic-gate 			else
1860Sstevel@tonic-gate 				for (s = flagset, t = flags; *s; s++, t++)
1870Sstevel@tonic-gate 					if (fp->fr_tcpf & *t)
1880Sstevel@tonic-gate 						(void)putchar(*s);
1890Sstevel@tonic-gate 			if (fp->fr_tcpfm) {
1900Sstevel@tonic-gate 				(void)putchar('/');
1910Sstevel@tonic-gate 				if (fp->fr_tcpfm & ~TCPF_ALL)
1920Sstevel@tonic-gate 					printf("0x%x", fp->fr_tcpfm);
1930Sstevel@tonic-gate 				else
1940Sstevel@tonic-gate 					for (s = flagset, t = flags; *s;
1950Sstevel@tonic-gate 					     s++, t++)
1960Sstevel@tonic-gate 						if (fp->fr_tcpfm & *t)
1970Sstevel@tonic-gate 							(void)putchar(*s);
1980Sstevel@tonic-gate 			}
1990Sstevel@tonic-gate 		}
2000Sstevel@tonic-gate 	} else if (type == FR_T_BPFOPC) {
2012393Syz155240 		fakebpf_t *fb;
2020Sstevel@tonic-gate 		int i;
2030Sstevel@tonic-gate 
2042393Syz155240 		printf("bpf-v%d { \"", fp->fr_v);
2052393Syz155240 		i = fp->fr_dsize / sizeof(*fb);
2060Sstevel@tonic-gate 
2072393Syz155240 		for (fb = fp->fr_data, s = ""; i; i--, fb++, s = " ")
2082393Syz155240 			printf("%s%#x %#x %#x %#x", s, fb->fb_c, fb->fb_t,
2092393Syz155240 			       fb->fb_f, fb->fb_k);
2100Sstevel@tonic-gate 
2112393Syz155240 		printf("\" }");
2120Sstevel@tonic-gate 	} else if (type == FR_T_COMPIPF) {
2130Sstevel@tonic-gate 		;
2140Sstevel@tonic-gate 	} else if (type == FR_T_CALLFUNC) {
2150Sstevel@tonic-gate 		printf("call function at %p", fp->fr_data);
2160Sstevel@tonic-gate 	} else {
2170Sstevel@tonic-gate 		printf("[unknown filter type %#x]", fp->fr_type);
2180Sstevel@tonic-gate 	}
2190Sstevel@tonic-gate 
2202393Syz155240 	if ((type == FR_T_IPF) &&
2212393Syz155240 	    ((fp->fr_flx & FI_WITH) || (fp->fr_mflx & FI_WITH) ||
2222393Syz155240 	     fp->fr_optbits || fp->fr_optmask ||
2232393Syz155240 	     fp->fr_secbits || fp->fr_secmask)) {
2242393Syz155240 		char *comma = " ";
2252393Syz155240 
2262393Syz155240 		printf(" with");
2272393Syz155240 		if (fp->fr_optbits || fp->fr_optmask ||
2282393Syz155240 		    fp->fr_secbits || fp->fr_secmask) {
2292393Syz155240 			sec[0] = fp->fr_secmask;
2302393Syz155240 			sec[1] = fp->fr_secbits;
2312393Syz155240 			if (fp->fr_v == 4)
2322393Syz155240 				optprint(sec, fp->fr_optmask, fp->fr_optbits);
2332393Syz155240 #ifdef	USE_INET6
2342393Syz155240 			else
2352393Syz155240 				optprintv6(sec, fp->fr_optmask,
2362393Syz155240 					   fp->fr_optbits);
2372393Syz155240 #endif
2382393Syz155240 		} else if (fp->fr_mflx & FI_OPTIONS) {
2392393Syz155240 			fputs(comma, stdout);
2402393Syz155240 			if (!(fp->fr_flx & FI_OPTIONS))
2412393Syz155240 				printf("not ");
2422393Syz155240 			printf("ipopts");
2432393Syz155240 			comma = ",";
2442393Syz155240 		}
2452393Syz155240 		if (fp->fr_mflx & FI_SHORT) {
2462393Syz155240 			fputs(comma, stdout);
2472393Syz155240 			if (!(fp->fr_flx & FI_SHORT))
2482393Syz155240 				printf("not ");
2492393Syz155240 			printf("short");
2502393Syz155240 			comma = ",";
2512393Syz155240 		}
2522393Syz155240 		if (fp->fr_mflx & FI_FRAG) {
2532393Syz155240 			fputs(comma, stdout);
2542393Syz155240 			if (!(fp->fr_flx & FI_FRAG))
2552393Syz155240 				printf("not ");
2562393Syz155240 			printf("frag");
2572393Syz155240 			comma = ",";
2582393Syz155240 		}
2592393Syz155240 		if (fp->fr_mflx & FI_FRAGBODY) {
2602393Syz155240 			fputs(comma, stdout);
2612393Syz155240 			if (!(fp->fr_flx & FI_FRAGBODY))
2622393Syz155240 				printf("not ");
2632393Syz155240 			printf("frag-body");
2642393Syz155240 			comma = ",";
2652393Syz155240 		}
2662393Syz155240 		if (fp->fr_mflx & FI_NATED) {
2672393Syz155240 			fputs(comma, stdout);
2682393Syz155240 			if (!(fp->fr_flx & FI_NATED))
2692393Syz155240 				printf("not ");
2702393Syz155240 			printf("nat");
2712393Syz155240 			comma = ",";
2722393Syz155240 		}
2732393Syz155240 		if (fp->fr_mflx & FI_LOWTTL) {
2742393Syz155240 			fputs(comma, stdout);
2752393Syz155240 			if (!(fp->fr_flx & FI_LOWTTL))
2762393Syz155240 				printf("not ");
2772393Syz155240 			printf("lowttl");
2782393Syz155240 			comma = ",";
2792393Syz155240 		}
2802393Syz155240 		if (fp->fr_mflx & FI_BAD) {
2812393Syz155240 			fputs(comma, stdout);
2822393Syz155240 			if (!(fp->fr_flx & FI_BAD))
2832393Syz155240 				printf("not ");
2842393Syz155240 			printf("bad");
2852393Syz155240 			comma = ",";
2862393Syz155240 		}
2872393Syz155240 		if (fp->fr_mflx & FI_BADSRC) {
2882393Syz155240 			fputs(comma, stdout);
2892393Syz155240 			if (!(fp->fr_flx & FI_BADSRC))
2902393Syz155240 				printf("not ");
2912393Syz155240 			printf("bad-src");
2922393Syz155240 			comma = ",";
2932393Syz155240 		}
2942393Syz155240 		if (fp->fr_mflx & FI_BADNAT) {
2952393Syz155240 			fputs(comma, stdout);
2962393Syz155240 			if (!(fp->fr_flx & FI_BADNAT))
2972393Syz155240 				printf("not ");
2982393Syz155240 			printf("bad-nat");
2992393Syz155240 			comma = ",";
3002393Syz155240 		}
3012393Syz155240 		if (fp->fr_mflx & FI_OOW) {
3022393Syz155240 			fputs(comma, stdout);
3032393Syz155240 			if (!(fp->fr_flx & FI_OOW))
3042393Syz155240 				printf("not ");
3052393Syz155240 			printf("oow");
3062393Syz155240 		}
3072393Syz155240 		if (fp->fr_mflx & FI_MULTICAST) {
3082393Syz155240 			fputs(comma, stdout);
3092393Syz155240 			if (!(fp->fr_flx & FI_MULTICAST))
3102393Syz155240 				printf("not ");
3115868Sdr146992 			printf("mcast");
3122393Syz155240 			comma = ",";
3132393Syz155240 		}
3142393Syz155240 		if (fp->fr_mflx & FI_BROADCAST) {
3152393Syz155240 			fputs(comma, stdout);
3162393Syz155240 			if (!(fp->fr_flx & FI_BROADCAST))
3172393Syz155240 				printf("not ");
3182393Syz155240 			printf("bcast");
3192393Syz155240 			comma = ",";
3202393Syz155240 		}
3212393Syz155240 		if (fp->fr_mflx & FI_MBCAST) {
3222393Syz155240 			fputs(comma, stdout);
3232393Syz155240 			if (!(fp->fr_flx & FI_MBCAST))
3242393Syz155240 				printf("not ");
3252393Syz155240 			printf("mbcast");
3262393Syz155240 			comma = ",";
3272393Syz155240 		}
3282393Syz155240 		if (fp->fr_mflx & FI_STATE) {
3292393Syz155240 			fputs(comma, stdout);
3302393Syz155240 			if (!(fp->fr_flx & FI_STATE))
3312393Syz155240 				printf("not ");
3322393Syz155240 			printf("state");
3332393Syz155240 			comma = ",";
3342393Syz155240 		}
3352393Syz155240 	}
3362393Syz155240 
3370Sstevel@tonic-gate 	if (fp->fr_flags & FR_KEEPSTATE) {
3380Sstevel@tonic-gate 		printf(" keep state");
3392393Syz155240 		if ((fp->fr_flags & (FR_STSTRICT|FR_NEWISN|FR_NOICMPERR|FR_STATESYNC)) ||
3400Sstevel@tonic-gate 		    (fp->fr_statemax != 0) || (fp->fr_age[0] != 0)) {
3412393Syz155240 			char *comma = "";
3420Sstevel@tonic-gate 			printf(" (");
3432393Syz155240 			if (fp->fr_statemax != 0) {
3442393Syz155240 				printf("limit %u", fp->fr_statemax);
3452393Syz155240 				comma = ",";
3462393Syz155240 			}
3472393Syz155240 			if (fp->fr_flags & FR_STSTRICT) {
3482393Syz155240 				printf("%sstrict", comma);
3492393Syz155240 				comma = ",";
3502393Syz155240 			}
3512393Syz155240 			if (fp->fr_flags & FR_NEWISN) {
3522393Syz155240 				printf("%snewisn", comma);
3532393Syz155240 				comma = ",";
3542393Syz155240 			}
3552393Syz155240 			if (fp->fr_flags & FR_NOICMPERR) {
3562393Syz155240 				printf("%sno-icmp-err", comma);
3572393Syz155240 				comma = ",";
3582393Syz155240 			}
3592393Syz155240 			if (fp->fr_flags & FR_STATESYNC) {
3602393Syz155240 				printf("%ssync", comma);
3612393Syz155240 				comma = ",";
3622393Syz155240 			}
3630Sstevel@tonic-gate 			if (fp->fr_age[0] || fp->fr_age[1])
3642393Syz155240 				printf("%sage %d/%d", comma, fp->fr_age[0],
3650Sstevel@tonic-gate 				       fp->fr_age[1]);
3662393Syz155240 			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);
3892393Syz155240 	if (fp->fr_logtag != FR_NOLOGTAG || *fp->fr_nattag.ipt_tag) {
3902393Syz155240 		char *s = "";
3912393Syz155240 
3922393Syz155240 		printf(" set-tag(");
3932393Syz155240 		if (fp->fr_logtag != FR_NOLOGTAG) {
3942393Syz155240 			printf("log=%u", fp->fr_logtag);
3952393Syz155240 			s = ", ";
3962393Syz155240 		}
3972393Syz155240 		if (*fp->fr_nattag.ipt_tag) {
3982393Syz155240 			printf("%snat=%-.*s", s, IPFTAG_LEN,
3992393Syz155240 				fp->fr_nattag.ipt_tag);
4002393Syz155240 		}
4012393Syz155240 		printf(")");
4022393Syz155240 	}
4030Sstevel@tonic-gate 	if (fp->fr_pps)
4040Sstevel@tonic-gate 		printf(" pps %d", fp->fr_pps);
4050Sstevel@tonic-gate 	(void)putchar('\n');
4060Sstevel@tonic-gate }
407