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 * 6*2393Syz155240 * $Id: printfr.c,v 1.43.2.12 2005/06/12 07:18:42 darrenr Exp $ 70Sstevel@tonic-gate * 8*2393Syz155240 * Copyright 2006 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 16*2393Syz155240 static void printaddr(int, int, char *, u_32_t *, u_32_t *); 17*2393Syz155240 18*2393Syz155240 static void printaddr(v, type, ifname, addr, mask) 19*2393Syz155240 int v, type; 20*2393Syz155240 char *ifname; 21*2393Syz155240 u_32_t *addr, *mask; 22*2393Syz155240 { 23*2393Syz155240 char *suffix; 24*2393Syz155240 25*2393Syz155240 switch (type) 26*2393Syz155240 { 27*2393Syz155240 case FRI_BROADCAST : 28*2393Syz155240 suffix = "/bcast"; 29*2393Syz155240 break; 30*2393Syz155240 31*2393Syz155240 case FRI_DYNAMIC : 32*2393Syz155240 printf("%s", ifname); 33*2393Syz155240 printmask(v, mask); 34*2393Syz155240 suffix = NULL; 35*2393Syz155240 break; 36*2393Syz155240 37*2393Syz155240 case FRI_NETWORK : 38*2393Syz155240 suffix = "/net"; 39*2393Syz155240 break; 40*2393Syz155240 41*2393Syz155240 case FRI_NETMASKED : 42*2393Syz155240 suffix = "/netmasked"; 43*2393Syz155240 break; 44*2393Syz155240 45*2393Syz155240 case FRI_PEERADDR : 46*2393Syz155240 suffix = "/peer"; 47*2393Syz155240 break; 48*2393Syz155240 49*2393Syz155240 case FRI_LOOKUP : 50*2393Syz155240 suffix = NULL; 51*2393Syz155240 printlookup((i6addr_t *)addr, (i6addr_t *)mask); 52*2393Syz155240 break; 53*2393Syz155240 54*2393Syz155240 case FRI_NORMAL : 55*2393Syz155240 printhostmask(v, addr, mask); 56*2393Syz155240 suffix = NULL; 57*2393Syz155240 break; 58*2393Syz155240 default : 59*2393Syz155240 printf("<%d>", type); 60*2393Syz155240 printmask(v, mask); 61*2393Syz155240 suffix = NULL; 62*2393Syz155240 break; 63*2393Syz155240 } 64*2393Syz155240 65*2393Syz155240 if (suffix != NULL) { 66*2393Syz155240 printf("%s/%s", ifname, suffix); 67*2393Syz155240 } 68*2393Syz155240 } 69*2393Syz155240 700Sstevel@tonic-gate 710Sstevel@tonic-gate void printlookup(addr, mask) 720Sstevel@tonic-gate i6addr_t *addr, *mask; 730Sstevel@tonic-gate { 740Sstevel@tonic-gate switch (addr->iplookuptype) 750Sstevel@tonic-gate { 760Sstevel@tonic-gate case IPLT_POOL : 770Sstevel@tonic-gate printf("pool/"); 780Sstevel@tonic-gate break; 790Sstevel@tonic-gate case IPLT_HASH : 800Sstevel@tonic-gate printf("hash/"); 810Sstevel@tonic-gate break; 820Sstevel@tonic-gate default : 830Sstevel@tonic-gate printf("lookup(%x)=", addr->iplookuptype); 840Sstevel@tonic-gate break; 850Sstevel@tonic-gate } 860Sstevel@tonic-gate 870Sstevel@tonic-gate printf("%u", addr->iplookupnum); 880Sstevel@tonic-gate if (opts & OPT_UNDEF) { 890Sstevel@tonic-gate if (mask->iplookupptr == NULL) { 900Sstevel@tonic-gate printf("(!)"); 910Sstevel@tonic-gate } 920Sstevel@tonic-gate } 930Sstevel@tonic-gate } 940Sstevel@tonic-gate 950Sstevel@tonic-gate 960Sstevel@tonic-gate /* 970Sstevel@tonic-gate * print the filter structure in a useful way 980Sstevel@tonic-gate */ 990Sstevel@tonic-gate void printfr(fp, iocfunc) 1000Sstevel@tonic-gate struct frentry *fp; 1010Sstevel@tonic-gate ioctlfunc_t iocfunc; 1020Sstevel@tonic-gate { 1030Sstevel@tonic-gate struct protoent *p; 1040Sstevel@tonic-gate u_short sec[2]; 1050Sstevel@tonic-gate u_32_t type; 1060Sstevel@tonic-gate u_char *t; 1070Sstevel@tonic-gate char *s; 1080Sstevel@tonic-gate int pr; 1090Sstevel@tonic-gate 1100Sstevel@tonic-gate pr = -2; 1110Sstevel@tonic-gate type = fp->fr_type & ~FR_T_BUILTIN; 1120Sstevel@tonic-gate 1130Sstevel@tonic-gate if ((fp->fr_type & FR_T_BUILTIN) != 0) 1140Sstevel@tonic-gate printf("# Builtin: "); 1150Sstevel@tonic-gate 116*2393Syz155240 if (fp->fr_collect != 0) 117*2393Syz155240 printf("%u ", fp->fr_collect); 118*2393Syz155240 1190Sstevel@tonic-gate if (fp->fr_type == FR_T_CALLFUNC) { 1200Sstevel@tonic-gate ; 1210Sstevel@tonic-gate } else if (fp->fr_func != NULL) { 1220Sstevel@tonic-gate printf("call"); 1230Sstevel@tonic-gate if ((fp->fr_flags & FR_CALLNOW) != 0) 1240Sstevel@tonic-gate printf(" now"); 1250Sstevel@tonic-gate s = kvatoname(fp->fr_func, iocfunc); 1260Sstevel@tonic-gate printf(" %s/%u", s ? s : "?", fp->fr_arg); 1270Sstevel@tonic-gate } else if (FR_ISPASS(fp->fr_flags)) 1280Sstevel@tonic-gate printf("pass"); 1290Sstevel@tonic-gate else if (FR_ISBLOCK(fp->fr_flags)) { 1300Sstevel@tonic-gate printf("block"); 1310Sstevel@tonic-gate if (fp->fr_flags & FR_RETICMP) { 1320Sstevel@tonic-gate if ((fp->fr_flags & FR_RETMASK) == FR_FAKEICMP) 1330Sstevel@tonic-gate printf(" return-icmp-as-dest"); 1340Sstevel@tonic-gate else if ((fp->fr_flags & FR_RETMASK) == FR_RETICMP) 1350Sstevel@tonic-gate printf(" return-icmp"); 1360Sstevel@tonic-gate if (fp->fr_icode) { 1370Sstevel@tonic-gate if (fp->fr_icode <= MAX_ICMPCODE) 1380Sstevel@tonic-gate printf("(%s)", 1390Sstevel@tonic-gate icmpcodes[(int)fp->fr_icode]); 1400Sstevel@tonic-gate else 1410Sstevel@tonic-gate printf("(%d)", fp->fr_icode); 1420Sstevel@tonic-gate } 1430Sstevel@tonic-gate } else if ((fp->fr_flags & FR_RETMASK) == FR_RETRST) 1440Sstevel@tonic-gate printf(" return-rst"); 1450Sstevel@tonic-gate } else if ((fp->fr_flags & FR_LOGMASK) == FR_LOG) { 1460Sstevel@tonic-gate printlog(fp); 1470Sstevel@tonic-gate } else if (FR_ISACCOUNT(fp->fr_flags)) 1480Sstevel@tonic-gate printf("count"); 1490Sstevel@tonic-gate else if (FR_ISAUTH(fp->fr_flags)) 1500Sstevel@tonic-gate printf("auth"); 1510Sstevel@tonic-gate else if (FR_ISPREAUTH(fp->fr_flags)) 1520Sstevel@tonic-gate printf("preauth"); 1530Sstevel@tonic-gate else if (FR_ISNOMATCH(fp->fr_flags)) 1540Sstevel@tonic-gate printf("nomatch"); 1550Sstevel@tonic-gate else if (FR_ISSKIP(fp->fr_flags)) 1560Sstevel@tonic-gate printf("skip %u", fp->fr_arg); 1570Sstevel@tonic-gate else { 1580Sstevel@tonic-gate printf("%x", fp->fr_flags); 1590Sstevel@tonic-gate } 1600Sstevel@tonic-gate 1610Sstevel@tonic-gate if (fp->fr_flags & FR_OUTQUE) 1620Sstevel@tonic-gate printf(" out "); 1630Sstevel@tonic-gate else 1640Sstevel@tonic-gate printf(" in "); 1650Sstevel@tonic-gate 1660Sstevel@tonic-gate if (((fp->fr_flags & FR_LOGB) == FR_LOGB) || 1670Sstevel@tonic-gate ((fp->fr_flags & FR_LOGP) == FR_LOGP)) { 1680Sstevel@tonic-gate printlog(fp); 1690Sstevel@tonic-gate putchar(' '); 1700Sstevel@tonic-gate } 1710Sstevel@tonic-gate 1720Sstevel@tonic-gate if (fp->fr_flags & FR_QUICK) 1730Sstevel@tonic-gate printf("quick "); 1740Sstevel@tonic-gate 1750Sstevel@tonic-gate if (*fp->fr_ifname) { 1760Sstevel@tonic-gate printifname("on ", fp->fr_ifname, fp->fr_ifa); 1770Sstevel@tonic-gate if (*fp->fr_ifnames[1] && strcmp(fp->fr_ifnames[1], "*")) 1780Sstevel@tonic-gate printifname(",", fp->fr_ifnames[1], fp->fr_ifas[1]); 1790Sstevel@tonic-gate putchar(' '); 180*2393Syz155240 } 1810Sstevel@tonic-gate 182*2393Syz155240 if (*fp->fr_dif.fd_ifname || (fp->fr_flags & FR_DUP)) 183*2393Syz155240 print_toif("dup-to", &fp->fr_dif); 184*2393Syz155240 if (*fp->fr_tif.fd_ifname) 185*2393Syz155240 print_toif("to", &fp->fr_tif); 186*2393Syz155240 if (*fp->fr_rif.fd_ifname) 187*2393Syz155240 print_toif("reply-to", &fp->fr_rif); 188*2393Syz155240 if (fp->fr_flags & FR_FASTROUTE) 189*2393Syz155240 printf("fastroute "); 1900Sstevel@tonic-gate 191*2393Syz155240 if ((*fp->fr_ifnames[2] && strcmp(fp->fr_ifnames[2], "*")) || 192*2393Syz155240 (*fp->fr_ifnames[3] && strcmp(fp->fr_ifnames[3], "*"))) { 193*2393Syz155240 if (fp->fr_flags & FR_OUTQUE) 194*2393Syz155240 printf("in-via "); 195*2393Syz155240 else 196*2393Syz155240 printf("out-via "); 1970Sstevel@tonic-gate 198*2393Syz155240 if (*fp->fr_ifnames[2]) { 199*2393Syz155240 printifname("", fp->fr_ifnames[2], 200*2393Syz155240 fp->fr_ifas[2]); 201*2393Syz155240 putchar(' '); 2020Sstevel@tonic-gate 203*2393Syz155240 if (*fp->fr_ifnames[3]) { 204*2393Syz155240 printifname(",", fp->fr_ifnames[3], 205*2393Syz155240 fp->fr_ifas[3]); 2060Sstevel@tonic-gate } 2070Sstevel@tonic-gate } 2080Sstevel@tonic-gate } 2090Sstevel@tonic-gate 2100Sstevel@tonic-gate if (type == FR_T_IPF) { 2110Sstevel@tonic-gate if (fp->fr_mip.fi_tos) 2120Sstevel@tonic-gate printf("tos %#x ", fp->fr_tos); 2130Sstevel@tonic-gate if (fp->fr_mip.fi_ttl) 2140Sstevel@tonic-gate printf("ttl %d ", fp->fr_ttl); 2150Sstevel@tonic-gate if (fp->fr_flx & FI_TCPUDP) { 2160Sstevel@tonic-gate printf("proto tcp/udp "); 2170Sstevel@tonic-gate pr = -1; 2180Sstevel@tonic-gate } else if (fp->fr_mip.fi_p) { 2190Sstevel@tonic-gate pr = fp->fr_ip.fi_p; 220*2393Syz155240 p = getprotobynumber(pr); 221*2393Syz155240 printf("proto "); 222*2393Syz155240 printproto(p, pr, NULL); 223*2393Syz155240 putchar(' '); 2240Sstevel@tonic-gate } 2250Sstevel@tonic-gate } 2260Sstevel@tonic-gate 2270Sstevel@tonic-gate if (type == FR_T_NONE) { 2280Sstevel@tonic-gate printf("all"); 2290Sstevel@tonic-gate } else if (type == FR_T_IPF) { 2300Sstevel@tonic-gate printf("from %s", fp->fr_flags & FR_NOTSRCIP ? "!" : ""); 231*2393Syz155240 printaddr(fp->fr_v, fp->fr_satype, fp->fr_ifname, 232*2393Syz155240 &fp->fr_src.s_addr, &fp->fr_smsk.s_addr); 2330Sstevel@tonic-gate if (fp->fr_scmp) 2340Sstevel@tonic-gate printportcmp(pr, &fp->fr_tuc.ftu_src); 2350Sstevel@tonic-gate 2360Sstevel@tonic-gate printf(" to %s", fp->fr_flags & FR_NOTDSTIP ? "!" : ""); 237*2393Syz155240 printaddr(fp->fr_v, fp->fr_datype, fp->fr_ifname, 238*2393Syz155240 &fp->fr_dst.s_addr, &fp->fr_dmsk.s_addr); 2390Sstevel@tonic-gate if (fp->fr_dcmp) 2400Sstevel@tonic-gate printportcmp(pr, &fp->fr_tuc.ftu_dst); 2410Sstevel@tonic-gate 242637Sml37995 if ((fp->fr_proto == IPPROTO_ICMP 243637Sml37995 #ifdef USE_INET6 244637Sml37995 || fp->fr_proto == IPPROTO_ICMPV6 245637Sml37995 #endif 246637Sml37995 ) && fp->fr_icmpm) { 2470Sstevel@tonic-gate int type = fp->fr_icmp, code; 2480Sstevel@tonic-gate 2490Sstevel@tonic-gate type = ntohs(fp->fr_icmp); 2500Sstevel@tonic-gate code = type & 0xff; 2510Sstevel@tonic-gate type /= 256; 2520Sstevel@tonic-gate if (type < (sizeof(icmptypes) / sizeof(char *) - 1) && 253637Sml37995 icmptypes[type] && fp->fr_proto == IPPROTO_ICMP) 2540Sstevel@tonic-gate printf(" icmp-type %s", icmptypes[type]); 2550Sstevel@tonic-gate else 2560Sstevel@tonic-gate printf(" icmp-type %d", type); 2570Sstevel@tonic-gate if (ntohs(fp->fr_icmpm) & 0xff) 2580Sstevel@tonic-gate printf(" code %d", code); 2590Sstevel@tonic-gate } 2600Sstevel@tonic-gate if ((fp->fr_proto == IPPROTO_TCP) && 2610Sstevel@tonic-gate (fp->fr_tcpf || fp->fr_tcpfm)) { 2620Sstevel@tonic-gate printf(" flags "); 2630Sstevel@tonic-gate if (fp->fr_tcpf & ~TCPF_ALL) 2640Sstevel@tonic-gate printf("0x%x", fp->fr_tcpf); 2650Sstevel@tonic-gate else 2660Sstevel@tonic-gate for (s = flagset, t = flags; *s; s++, t++) 2670Sstevel@tonic-gate if (fp->fr_tcpf & *t) 2680Sstevel@tonic-gate (void)putchar(*s); 2690Sstevel@tonic-gate if (fp->fr_tcpfm) { 2700Sstevel@tonic-gate (void)putchar('/'); 2710Sstevel@tonic-gate if (fp->fr_tcpfm & ~TCPF_ALL) 2720Sstevel@tonic-gate printf("0x%x", fp->fr_tcpfm); 2730Sstevel@tonic-gate else 2740Sstevel@tonic-gate for (s = flagset, t = flags; *s; 2750Sstevel@tonic-gate s++, t++) 2760Sstevel@tonic-gate if (fp->fr_tcpfm & *t) 2770Sstevel@tonic-gate (void)putchar(*s); 2780Sstevel@tonic-gate } 2790Sstevel@tonic-gate } 2800Sstevel@tonic-gate } else if (type == FR_T_BPFOPC) { 281*2393Syz155240 fakebpf_t *fb; 2820Sstevel@tonic-gate int i; 2830Sstevel@tonic-gate 284*2393Syz155240 printf("bpf-v%d { \"", fp->fr_v); 285*2393Syz155240 i = fp->fr_dsize / sizeof(*fb); 2860Sstevel@tonic-gate 287*2393Syz155240 for (fb = fp->fr_data, s = ""; i; i--, fb++, s = " ") 288*2393Syz155240 printf("%s%#x %#x %#x %#x", s, fb->fb_c, fb->fb_t, 289*2393Syz155240 fb->fb_f, fb->fb_k); 2900Sstevel@tonic-gate 291*2393Syz155240 printf("\" }"); 2920Sstevel@tonic-gate } else if (type == FR_T_COMPIPF) { 2930Sstevel@tonic-gate ; 2940Sstevel@tonic-gate } else if (type == FR_T_CALLFUNC) { 2950Sstevel@tonic-gate printf("call function at %p", fp->fr_data); 2960Sstevel@tonic-gate } else { 2970Sstevel@tonic-gate printf("[unknown filter type %#x]", fp->fr_type); 2980Sstevel@tonic-gate } 2990Sstevel@tonic-gate 300*2393Syz155240 if ((type == FR_T_IPF) && 301*2393Syz155240 ((fp->fr_flx & FI_WITH) || (fp->fr_mflx & FI_WITH) || 302*2393Syz155240 fp->fr_optbits || fp->fr_optmask || 303*2393Syz155240 fp->fr_secbits || fp->fr_secmask)) { 304*2393Syz155240 char *comma = " "; 305*2393Syz155240 306*2393Syz155240 printf(" with"); 307*2393Syz155240 if (fp->fr_optbits || fp->fr_optmask || 308*2393Syz155240 fp->fr_secbits || fp->fr_secmask) { 309*2393Syz155240 sec[0] = fp->fr_secmask; 310*2393Syz155240 sec[1] = fp->fr_secbits; 311*2393Syz155240 if (fp->fr_v == 4) 312*2393Syz155240 optprint(sec, fp->fr_optmask, fp->fr_optbits); 313*2393Syz155240 #ifdef USE_INET6 314*2393Syz155240 else 315*2393Syz155240 optprintv6(sec, fp->fr_optmask, 316*2393Syz155240 fp->fr_optbits); 317*2393Syz155240 #endif 318*2393Syz155240 } else if (fp->fr_mflx & FI_OPTIONS) { 319*2393Syz155240 fputs(comma, stdout); 320*2393Syz155240 if (!(fp->fr_flx & FI_OPTIONS)) 321*2393Syz155240 printf("not "); 322*2393Syz155240 printf("ipopts"); 323*2393Syz155240 comma = ","; 324*2393Syz155240 } 325*2393Syz155240 if (fp->fr_mflx & FI_SHORT) { 326*2393Syz155240 fputs(comma, stdout); 327*2393Syz155240 if (!(fp->fr_flx & FI_SHORT)) 328*2393Syz155240 printf("not "); 329*2393Syz155240 printf("short"); 330*2393Syz155240 comma = ","; 331*2393Syz155240 } 332*2393Syz155240 if (fp->fr_mflx & FI_FRAG) { 333*2393Syz155240 fputs(comma, stdout); 334*2393Syz155240 if (!(fp->fr_flx & FI_FRAG)) 335*2393Syz155240 printf("not "); 336*2393Syz155240 printf("frag"); 337*2393Syz155240 comma = ","; 338*2393Syz155240 } 339*2393Syz155240 if (fp->fr_mflx & FI_FRAGBODY) { 340*2393Syz155240 fputs(comma, stdout); 341*2393Syz155240 if (!(fp->fr_flx & FI_FRAGBODY)) 342*2393Syz155240 printf("not "); 343*2393Syz155240 printf("frag-body"); 344*2393Syz155240 comma = ","; 345*2393Syz155240 } 346*2393Syz155240 if (fp->fr_mflx & FI_NATED) { 347*2393Syz155240 fputs(comma, stdout); 348*2393Syz155240 if (!(fp->fr_flx & FI_NATED)) 349*2393Syz155240 printf("not "); 350*2393Syz155240 printf("nat"); 351*2393Syz155240 comma = ","; 352*2393Syz155240 } 353*2393Syz155240 if (fp->fr_mflx & FI_LOWTTL) { 354*2393Syz155240 fputs(comma, stdout); 355*2393Syz155240 if (!(fp->fr_flx & FI_LOWTTL)) 356*2393Syz155240 printf("not "); 357*2393Syz155240 printf("lowttl"); 358*2393Syz155240 comma = ","; 359*2393Syz155240 } 360*2393Syz155240 if (fp->fr_mflx & FI_BAD) { 361*2393Syz155240 fputs(comma, stdout); 362*2393Syz155240 if (!(fp->fr_flx & FI_BAD)) 363*2393Syz155240 printf("not "); 364*2393Syz155240 printf("bad"); 365*2393Syz155240 comma = ","; 366*2393Syz155240 } 367*2393Syz155240 if (fp->fr_mflx & FI_BADSRC) { 368*2393Syz155240 fputs(comma, stdout); 369*2393Syz155240 if (!(fp->fr_flx & FI_BADSRC)) 370*2393Syz155240 printf("not "); 371*2393Syz155240 printf("bad-src"); 372*2393Syz155240 comma = ","; 373*2393Syz155240 } 374*2393Syz155240 if (fp->fr_mflx & FI_BADNAT) { 375*2393Syz155240 fputs(comma, stdout); 376*2393Syz155240 if (!(fp->fr_flx & FI_BADNAT)) 377*2393Syz155240 printf("not "); 378*2393Syz155240 printf("bad-nat"); 379*2393Syz155240 comma = ","; 380*2393Syz155240 } 381*2393Syz155240 if (fp->fr_mflx & FI_OOW) { 382*2393Syz155240 fputs(comma, stdout); 383*2393Syz155240 if (!(fp->fr_flx & FI_OOW)) 384*2393Syz155240 printf("not "); 385*2393Syz155240 printf("oow"); 386*2393Syz155240 } 387*2393Syz155240 if (fp->fr_mflx & FI_MULTICAST) { 388*2393Syz155240 fputs(comma, stdout); 389*2393Syz155240 if (!(fp->fr_flx & FI_MULTICAST)) 390*2393Syz155240 printf("not "); 391*2393Syz155240 printf("multicast"); 392*2393Syz155240 comma = ","; 393*2393Syz155240 } 394*2393Syz155240 if (fp->fr_mflx & FI_BROADCAST) { 395*2393Syz155240 fputs(comma, stdout); 396*2393Syz155240 if (!(fp->fr_flx & FI_BROADCAST)) 397*2393Syz155240 printf("not "); 398*2393Syz155240 printf("bcast"); 399*2393Syz155240 comma = ","; 400*2393Syz155240 } 401*2393Syz155240 if (fp->fr_mflx & FI_MBCAST) { 402*2393Syz155240 fputs(comma, stdout); 403*2393Syz155240 if (!(fp->fr_flx & FI_MBCAST)) 404*2393Syz155240 printf("not "); 405*2393Syz155240 printf("mbcast"); 406*2393Syz155240 comma = ","; 407*2393Syz155240 } 408*2393Syz155240 if (fp->fr_mflx & FI_STATE) { 409*2393Syz155240 fputs(comma, stdout); 410*2393Syz155240 if (!(fp->fr_flx & FI_STATE)) 411*2393Syz155240 printf("not "); 412*2393Syz155240 printf("state"); 413*2393Syz155240 comma = ","; 414*2393Syz155240 } 415*2393Syz155240 } 416*2393Syz155240 4170Sstevel@tonic-gate if (fp->fr_flags & FR_KEEPSTATE) { 4180Sstevel@tonic-gate printf(" keep state"); 419*2393Syz155240 if ((fp->fr_flags & (FR_STSTRICT|FR_NEWISN|FR_NOICMPERR|FR_STATESYNC)) || 4200Sstevel@tonic-gate (fp->fr_statemax != 0) || (fp->fr_age[0] != 0)) { 421*2393Syz155240 char *comma = ""; 4220Sstevel@tonic-gate printf(" ("); 423*2393Syz155240 if (fp->fr_statemax != 0) { 424*2393Syz155240 printf("limit %u", fp->fr_statemax); 425*2393Syz155240 comma = ","; 426*2393Syz155240 } 427*2393Syz155240 if (fp->fr_flags & FR_STSTRICT) { 428*2393Syz155240 printf("%sstrict", comma); 429*2393Syz155240 comma = ","; 430*2393Syz155240 } 431*2393Syz155240 if (fp->fr_flags & FR_NEWISN) { 432*2393Syz155240 printf("%snewisn", comma); 433*2393Syz155240 comma = ","; 434*2393Syz155240 } 435*2393Syz155240 if (fp->fr_flags & FR_NOICMPERR) { 436*2393Syz155240 printf("%sno-icmp-err", comma); 437*2393Syz155240 comma = ","; 438*2393Syz155240 } 439*2393Syz155240 if (fp->fr_flags & FR_STATESYNC) { 440*2393Syz155240 printf("%ssync", comma); 441*2393Syz155240 comma = ","; 442*2393Syz155240 } 4430Sstevel@tonic-gate if (fp->fr_age[0] || fp->fr_age[1]) 444*2393Syz155240 printf("%sage %d/%d", comma, fp->fr_age[0], 4450Sstevel@tonic-gate fp->fr_age[1]); 446*2393Syz155240 printf(")"); 4470Sstevel@tonic-gate } 4480Sstevel@tonic-gate } 4490Sstevel@tonic-gate if (fp->fr_flags & FR_KEEPFRAG) { 4500Sstevel@tonic-gate printf(" keep frags"); 4510Sstevel@tonic-gate if (fp->fr_flags & (FR_FRSTRICT)) { 4520Sstevel@tonic-gate printf(" ("); 4530Sstevel@tonic-gate if (fp->fr_flags & FR_FRSTRICT) 4540Sstevel@tonic-gate printf(" strict"); 4550Sstevel@tonic-gate printf(" )"); 4560Sstevel@tonic-gate 4570Sstevel@tonic-gate } 4580Sstevel@tonic-gate } 4590Sstevel@tonic-gate if (fp->fr_isc != (struct ipscan *)-1) { 4600Sstevel@tonic-gate if (fp->fr_isctag[0]) 4610Sstevel@tonic-gate printf(" scan %s", fp->fr_isctag); 4620Sstevel@tonic-gate else 4630Sstevel@tonic-gate printf(" scan *"); 4640Sstevel@tonic-gate } 4650Sstevel@tonic-gate if (*fp->fr_grhead != '\0') 4660Sstevel@tonic-gate printf(" head %s", fp->fr_grhead); 4670Sstevel@tonic-gate if (*fp->fr_group != '\0') 4680Sstevel@tonic-gate printf(" group %s", fp->fr_group); 469*2393Syz155240 if (fp->fr_logtag != FR_NOLOGTAG || *fp->fr_nattag.ipt_tag) { 470*2393Syz155240 char *s = ""; 471*2393Syz155240 472*2393Syz155240 printf(" set-tag("); 473*2393Syz155240 if (fp->fr_logtag != FR_NOLOGTAG) { 474*2393Syz155240 printf("log=%u", fp->fr_logtag); 475*2393Syz155240 s = ", "; 476*2393Syz155240 } 477*2393Syz155240 if (*fp->fr_nattag.ipt_tag) { 478*2393Syz155240 printf("%snat=%-.*s", s, IPFTAG_LEN, 479*2393Syz155240 fp->fr_nattag.ipt_tag); 480*2393Syz155240 } 481*2393Syz155240 printf(")"); 482*2393Syz155240 } 4830Sstevel@tonic-gate if (fp->fr_pps) 4840Sstevel@tonic-gate printf(" pps %d", fp->fr_pps); 4850Sstevel@tonic-gate (void)putchar('\n'); 4860Sstevel@tonic-gate } 487