Home | History | Annotate | Line # | Download | only in lib
      1 /*	$NetBSD: printfr.c,v 1.2 2012/07/22 14:27:36 darrenr Exp $	*/
      2 
      3 /*
      4  * Copyright (C) 2012 by Darren Reed.
      5  *
      6  * See the IPFILTER.LICENCE file for details on licencing.
      7  *
      8  * Id: printfr.c,v 1.1.1.2 2012/07/22 13:44:40 darrenr Exp $
      9  */
     10 
     11 #include "ipf.h"
     12 
     13 
     14 /*
     15  * print the filter structure in a useful way
     16  */
     17 void
     18 printfr(fp, iocfunc)
     19 	struct	frentry	*fp;
     20 	ioctlfunc_t	iocfunc;
     21 {
     22 	struct protoent	*p;
     23 	u_short	sec[2];
     24 	u_32_t type;
     25 	int pr, af;
     26 	char *s;
     27 	int hash;
     28 
     29 	pr = -2;
     30 	type = fp->fr_type & ~FR_T_BUILTIN;
     31 
     32 	if ((fp->fr_type & FR_T_BUILTIN) != 0)
     33 		PRINTF("# Builtin: ");
     34 
     35 	if (fp->fr_collect != 0)
     36 		PRINTF("%u ", fp->fr_collect);
     37 
     38 	if (fp->fr_type == FR_T_CALLFUNC) {
     39 		;
     40 	} else if (fp->fr_func != NULL) {
     41 		PRINTF("call");
     42 		if ((fp->fr_flags & FR_CALLNOW) != 0)
     43 			PRINTF(" now");
     44 		s = kvatoname(fp->fr_func, iocfunc);
     45 		PRINTF(" %s/%u", s ? s : "?", fp->fr_arg);
     46 	} else if (FR_ISPASS(fp->fr_flags))
     47 		PRINTF("pass");
     48 	else if (FR_ISBLOCK(fp->fr_flags)) {
     49 		PRINTF("block");
     50 	} else if ((fp->fr_flags & FR_LOGMASK) == FR_LOG) {
     51 		printlog(fp);
     52 	} else if (FR_ISACCOUNT(fp->fr_flags))
     53 		PRINTF("count");
     54 	else if (FR_ISAUTH(fp->fr_flags))
     55 		PRINTF("auth");
     56 	else if (FR_ISPREAUTH(fp->fr_flags))
     57 		PRINTF("preauth");
     58 	else if (FR_ISNOMATCH(fp->fr_flags))
     59 		PRINTF("nomatch");
     60 	else if (FR_ISDECAPS(fp->fr_flags))
     61 		PRINTF("decapsulate");
     62 	else if (FR_ISSKIP(fp->fr_flags))
     63 		PRINTF("skip %u", fp->fr_arg);
     64 	else {
     65 		PRINTF("%x", fp->fr_flags);
     66 	}
     67 	if (fp->fr_flags & FR_RETICMP) {
     68 		if ((fp->fr_flags & FR_RETMASK) == FR_FAKEICMP)
     69 			PRINTF(" return-icmp-as-dest");
     70 		else if ((fp->fr_flags & FR_RETMASK) == FR_RETICMP)
     71 			PRINTF(" return-icmp");
     72 		if (fp->fr_icode) {
     73 			if (fp->fr_icode <= MAX_ICMPCODE)
     74 				PRINTF("(%s)",
     75 					icmpcodes[(int)fp->fr_icode]);
     76 			else
     77 				PRINTF("(%d)", fp->fr_icode);
     78 		}
     79 	} else if ((fp->fr_flags & FR_RETMASK) == FR_RETRST)
     80 		PRINTF(" return-rst");
     81 
     82 	if (fp->fr_flags & FR_OUTQUE)
     83 		PRINTF(" out ");
     84 	else if (fp->fr_flags & FR_INQUE)
     85 		PRINTF(" in ");
     86 
     87 	if (((fp->fr_flags & FR_LOGB) == FR_LOGB) ||
     88 	    ((fp->fr_flags & FR_LOGP) == FR_LOGP)) {
     89 		printlog(fp);
     90 		putchar(' ');
     91 	}
     92 
     93 	if (fp->fr_flags & FR_QUICK)
     94 		PRINTF("quick ");
     95 
     96 	if (fp->fr_ifnames[0] != -1) {
     97 		printifname("on ", fp->fr_names + fp->fr_ifnames[0],
     98 			    fp->fr_ifa);
     99 		if (fp->fr_ifnames[1] != -1 &&
    100 		    strcmp(fp->fr_names + fp->fr_ifnames[1], "*"))
    101 			printifname(",", fp->fr_names + fp->fr_ifnames[1],
    102 				    fp->fr_ifas[1]);
    103 		putchar(' ');
    104 	}
    105 
    106 	if (fp->fr_tif.fd_name != -1)
    107 		print_toif(fp->fr_family, "to", fp->fr_names, &fp->fr_tif);
    108 	if (fp->fr_dif.fd_name != -1)
    109 		print_toif(fp->fr_family, "dup-to", fp->fr_names,
    110 			   &fp->fr_dif);
    111 	if (fp->fr_rif.fd_name != -1)
    112 		print_toif(fp->fr_family, "reply-to", fp->fr_names,
    113 			   &fp->fr_rif);
    114 	if (fp->fr_flags & FR_FASTROUTE)
    115 		PRINTF("fastroute ");
    116 
    117 	if ((fp->fr_ifnames[2] != -1 &&
    118 	     strcmp(fp->fr_names + fp->fr_ifnames[2], "*")) ||
    119 	    (fp->fr_ifnames[3] != -1 &&
    120 		 strcmp(fp->fr_names + fp->fr_ifnames[3], "*"))) {
    121 		if (fp->fr_flags & FR_OUTQUE)
    122 			PRINTF("in-via ");
    123 		else
    124 			PRINTF("out-via ");
    125 
    126 		if (fp->fr_ifnames[2] != -1) {
    127 			printifname("", fp->fr_names + fp->fr_ifnames[2],
    128 				    fp->fr_ifas[2]);
    129 			if (fp->fr_ifnames[3] != -1) {
    130 				printifname(",",
    131 					    fp->fr_names + fp->fr_ifnames[3],
    132 					    fp->fr_ifas[3]);
    133 			}
    134 			putchar(' ');
    135 		}
    136 	}
    137 
    138 	if (fp->fr_family == AF_INET) {
    139 		PRINTF("inet ");
    140 		af = AF_INET;
    141 #ifdef USE_INET6
    142 	} else if (fp->fr_family == AF_INET6) {
    143 		PRINTF("inet6 ");
    144 		af = AF_INET6;
    145 #endif
    146 	} else {
    147 		af = -1;
    148 	}
    149 
    150 	if (type == FR_T_IPF) {
    151 		if (fp->fr_mip.fi_tos)
    152 			PRINTF("tos %#x ", fp->fr_tos);
    153 		if (fp->fr_mip.fi_ttl)
    154 			PRINTF("ttl %d ", fp->fr_ttl);
    155 		if (fp->fr_flx & FI_TCPUDP) {
    156 			PRINTF("proto tcp/udp ");
    157 			pr = -1;
    158 		} else if (fp->fr_mip.fi_p) {
    159 			pr = fp->fr_ip.fi_p;
    160 			p = getprotobynumber(pr);
    161 			PRINTF("proto ");
    162 			printproto(p, pr, NULL);
    163 			putchar(' ');
    164 		}
    165 	}
    166 
    167 	switch (type)
    168 	{
    169 	case FR_T_NONE :
    170 		PRINTF("all");
    171 		break;
    172 
    173 	case FR_T_IPF :
    174 		PRINTF("from %s", fp->fr_flags & FR_NOTSRCIP ? "!" : "");
    175 		printaddr(af, fp->fr_satype, fp->fr_names, fp->fr_ifnames[0],
    176 			  &fp->fr_src.s_addr, &fp->fr_smsk.s_addr);
    177 		if (fp->fr_scmp)
    178 			printportcmp(pr, &fp->fr_tuc.ftu_src);
    179 
    180 		PRINTF(" to %s", fp->fr_flags & FR_NOTDSTIP ? "!" : "");
    181 		printaddr(af, fp->fr_datype, fp->fr_names, fp->fr_ifnames[0],
    182 			  &fp->fr_dst.s_addr, &fp->fr_dmsk.s_addr);
    183 		if (fp->fr_dcmp)
    184 			printportcmp(pr, &fp->fr_tuc.ftu_dst);
    185 
    186 		if (((fp->fr_proto == IPPROTO_ICMP) ||
    187 		     (fp->fr_proto == IPPROTO_ICMPV6)) && fp->fr_icmpm) {
    188 			int	type = fp->fr_icmp, code;
    189 			char	*name;
    190 
    191 			type = ntohs(fp->fr_icmp);
    192 			code = type & 0xff;
    193 			type /= 256;
    194 			name = icmptypename(fp->fr_family, type);
    195 			if (name == NULL)
    196 				PRINTF(" icmp-type %d", type);
    197 			else
    198 				PRINTF(" icmp-type %s", name);
    199 			if (ntohs(fp->fr_icmpm) & 0xff)
    200 				PRINTF(" code %d", code);
    201 		}
    202 		if ((fp->fr_proto == IPPROTO_TCP) &&
    203 		    (fp->fr_tcpf || fp->fr_tcpfm)) {
    204 			PRINTF(" flags ");
    205 			printtcpflags(fp->fr_tcpf, fp->fr_tcpfm);
    206 		}
    207 		break;
    208 
    209 	case FR_T_BPFOPC :
    210 	    {
    211 		fakebpf_t *fb;
    212 		int i;
    213 
    214 		PRINTF("bpf-v%d { \"", fp->fr_family);
    215 		i = fp->fr_dsize / sizeof(*fb);
    216 
    217 		for (fb = fp->fr_data, s = ""; i; i--, fb++, s = " ")
    218 			PRINTF("%s%#x %#x %#x %#x", s, fb->fb_c, fb->fb_t,
    219 			       fb->fb_f, fb->fb_k);
    220 
    221 		PRINTF("\" }");
    222 		break;
    223 	    }
    224 
    225 	case FR_T_COMPIPF :
    226 		break;
    227 
    228 	case FR_T_CALLFUNC :
    229 		PRINTF("call function at %p", fp->fr_data);
    230 		break;
    231 
    232 	case FR_T_IPFEXPR :
    233 		PRINTF("exp { \"");
    234 		printipfexpr(fp->fr_data);
    235 		PRINTF("\" } ");
    236 		break;
    237 
    238 	default :
    239 		PRINTF("[unknown filter type %#x]", fp->fr_type);
    240 		break;
    241 	}
    242 
    243 	if ((type == FR_T_IPF) &&
    244 	    ((fp->fr_flx & FI_WITH) || (fp->fr_mflx & FI_WITH) ||
    245 	     fp->fr_optbits || fp->fr_optmask ||
    246 	     fp->fr_secbits || fp->fr_secmask)) {
    247 		char *comma = " ";
    248 
    249 		PRINTF(" with");
    250 		if (fp->fr_optbits || fp->fr_optmask ||
    251 		    fp->fr_secbits || fp->fr_secmask) {
    252 			sec[0] = fp->fr_secmask;
    253 			sec[1] = fp->fr_secbits;
    254 			if (fp->fr_family == AF_INET)
    255 				optprint(sec, fp->fr_optmask, fp->fr_optbits);
    256 #ifdef	USE_INET6
    257 			else
    258 				optprintv6(sec, fp->fr_optmask,
    259 					   fp->fr_optbits);
    260 #endif
    261 		} else if (fp->fr_mflx & FI_OPTIONS) {
    262 			fputs(comma, stdout);
    263 			if (!(fp->fr_flx & FI_OPTIONS))
    264 				PRINTF("not ");
    265 			PRINTF("ipopts");
    266 			comma = ",";
    267 		}
    268 		if (fp->fr_mflx & FI_SHORT) {
    269 			fputs(comma, stdout);
    270 			if (!(fp->fr_flx & FI_SHORT))
    271 				PRINTF("not ");
    272 			PRINTF("short");
    273 			comma = ",";
    274 		}
    275 		if (fp->fr_mflx & FI_FRAG) {
    276 			fputs(comma, stdout);
    277 			if (!(fp->fr_flx & FI_FRAG))
    278 				PRINTF("not ");
    279 			PRINTF("frag");
    280 			comma = ",";
    281 		}
    282 		if (fp->fr_mflx & FI_FRAGBODY) {
    283 			fputs(comma, stdout);
    284 			if (!(fp->fr_flx & FI_FRAGBODY))
    285 				PRINTF("not ");
    286 			PRINTF("frag-body");
    287 			comma = ",";
    288 		}
    289 		if (fp->fr_mflx & FI_NATED) {
    290 			fputs(comma, stdout);
    291 			if (!(fp->fr_flx & FI_NATED))
    292 				PRINTF("not ");
    293 			PRINTF("nat");
    294 			comma = ",";
    295 		}
    296 		if (fp->fr_mflx & FI_LOWTTL) {
    297 			fputs(comma, stdout);
    298 			if (!(fp->fr_flx & FI_LOWTTL))
    299 				PRINTF("not ");
    300 			PRINTF("lowttl");
    301 			comma = ",";
    302 		}
    303 		if (fp->fr_mflx & FI_BAD) {
    304 			fputs(comma, stdout);
    305 			if (!(fp->fr_flx & FI_BAD))
    306 				PRINTF("not ");
    307 			PRINTF("bad");
    308 			comma = ",";
    309 		}
    310 		if (fp->fr_mflx & FI_BADSRC) {
    311 			fputs(comma, stdout);
    312 			if (!(fp->fr_flx & FI_BADSRC))
    313 				PRINTF("not ");
    314 			PRINTF("bad-src");
    315 			comma = ",";
    316 		}
    317 		if (fp->fr_mflx & FI_BADNAT) {
    318 			fputs(comma, stdout);
    319 			if (!(fp->fr_flx & FI_BADNAT))
    320 				PRINTF("not ");
    321 			PRINTF("bad-nat");
    322 			comma = ",";
    323 		}
    324 		if (fp->fr_mflx & FI_OOW) {
    325 			fputs(comma, stdout);
    326 			if (!(fp->fr_flx & FI_OOW))
    327 				PRINTF("not ");
    328 			PRINTF("oow");
    329 			comma = ",";
    330 		}
    331 		if (fp->fr_mflx & FI_MBCAST) {
    332 			fputs(comma, stdout);
    333 			if (!(fp->fr_flx & FI_MBCAST))
    334 				PRINTF("not ");
    335 			PRINTF("mbcast");
    336 			comma = ",";
    337 		}
    338 		if (fp->fr_mflx & FI_BROADCAST) {
    339 			fputs(comma, stdout);
    340 			if (!(fp->fr_flx & FI_BROADCAST))
    341 				PRINTF("not ");
    342 			PRINTF("bcast");
    343 			comma = ",";
    344 		}
    345 		if (fp->fr_mflx & FI_MULTICAST) {
    346 			fputs(comma, stdout);
    347 			if (!(fp->fr_flx & FI_MULTICAST))
    348 				PRINTF("not ");
    349 			PRINTF("mcast");
    350 			comma = ",";
    351 		}
    352 		if (fp->fr_mflx & FI_STATE) {
    353 			fputs(comma, stdout);
    354 			if (!(fp->fr_flx & FI_STATE))
    355 				PRINTF("not ");
    356 			PRINTF("state");
    357 			comma = ",";
    358 		}
    359 		if (fp->fr_mflx & FI_V6EXTHDR) {
    360 			fputs(comma, stdout);
    361 			if (!(fp->fr_flx & FI_V6EXTHDR))
    362 				PRINTF("not ");
    363 			PRINTF("v6hdrs");
    364 			comma = ",";
    365 		}
    366 	}
    367 
    368 	if (fp->fr_flags & FR_KEEPSTATE) {
    369 		host_track_t *src = &fp->fr_srctrack;
    370 		PRINTF(" keep state");
    371 		if ((fp->fr_flags & (FR_STSTRICT|FR_NEWISN|
    372 				     FR_NOICMPERR|FR_STATESYNC)) ||
    373 		    (fp->fr_statemax != 0) || (fp->fr_age[0] != 0) ||
    374 		    (src->ht_max_nodes != 0)) {
    375 			char *comma = "";
    376 			PRINTF(" (");
    377 			if (fp->fr_statemax != 0) {
    378 				PRINTF("limit %u", fp->fr_statemax);
    379 				comma = ",";
    380 			}
    381 			if (src->ht_max_nodes != 0) {
    382 				PRINTF("%smax-nodes %d", comma,
    383 				       src->ht_max_nodes);
    384 				if (src->ht_max_per_node)
    385 					PRINTF(", max-per-src %d/%d",
    386 					       src->ht_max_per_node,
    387 					       src->ht_netmask);
    388 				comma = ",";
    389 			}
    390 			if (fp->fr_flags & FR_STSTRICT) {
    391 				PRINTF("%sstrict", comma);
    392 				comma = ",";
    393 			}
    394 			if (fp->fr_flags & FR_STLOOSE) {
    395 				PRINTF("%sloose", comma);
    396 				comma = ",";
    397 			}
    398 			if (fp->fr_flags & FR_NEWISN) {
    399 				PRINTF("%snewisn", comma);
    400 				comma = ",";
    401 			}
    402 			if (fp->fr_flags & FR_NOICMPERR) {
    403 				PRINTF("%sno-icmp-err", comma);
    404 				comma = ",";
    405 			}
    406 			if (fp->fr_flags & FR_STATESYNC) {
    407 				PRINTF("%ssync", comma);
    408 				comma = ",";
    409 			}
    410 			if (fp->fr_age[0] || fp->fr_age[1])
    411 				PRINTF("%sage %d/%d", comma, fp->fr_age[0],
    412 				       fp->fr_age[1]);
    413 			PRINTF(")");
    414 		}
    415 	}
    416 	if (fp->fr_flags & FR_KEEPFRAG) {
    417 		PRINTF(" keep frags");
    418 		if (fp->fr_flags & (FR_FRSTRICT)) {
    419 			PRINTF(" (");
    420 			if (fp->fr_flags & FR_FRSTRICT)
    421 				PRINTF("strict");
    422 			PRINTF(")");
    423 
    424 		}
    425 	}
    426 	if (fp->fr_isc != (struct ipscan *)-1) {
    427 		if (fp->fr_isctag != -1)
    428 			PRINTF(" scan %s", fp->fr_isctag + fp->fr_names);
    429 		else
    430 			PRINTF(" scan *");
    431 	}
    432 	if (fp->fr_grhead != -1)
    433 		PRINTF(" head %s", fp->fr_names + fp->fr_grhead);
    434 	if (fp->fr_group != -1)
    435 		PRINTF(" group %s", fp->fr_names + fp->fr_group);
    436 	if (fp->fr_logtag != FR_NOLOGTAG || *fp->fr_nattag.ipt_tag) {
    437 		char *s = "";
    438 
    439 		PRINTF(" set-tag(");
    440 		if (fp->fr_logtag != FR_NOLOGTAG) {
    441 			PRINTF("log=%u", fp->fr_logtag);
    442 			s = ", ";
    443 		}
    444 		if (*fp->fr_nattag.ipt_tag) {
    445 			PRINTF("%snat=%-.*s", s, IPFTAG_LEN,
    446 				fp->fr_nattag.ipt_tag);
    447 		}
    448 		PRINTF(")");
    449 	}
    450 
    451 	if (fp->fr_pps)
    452 		PRINTF(" pps %d", fp->fr_pps);
    453 
    454 	if (fp->fr_comment != -1)
    455 		PRINTF(" comment \"%s\"", fp->fr_names + fp->fr_comment);
    456 
    457 	hash = 0;
    458 	if ((fp->fr_flags & FR_KEEPSTATE) && (opts & OPT_VERBOSE)) {
    459 		PRINTF(" # count %d", fp->fr_statecnt);
    460 		if (fp->fr_die != 0)
    461 			PRINTF(" rule-ttl %u", fp->fr_die);
    462 		hash = 1;
    463 	} else if (fp->fr_die != 0) {
    464 		PRINTF(" # rule-ttl %u", fp->fr_die);
    465 		hash = 1;
    466 	}
    467 	if (opts & OPT_DEBUG) {
    468 		if (hash == 0)
    469 			putchar('#');
    470 		PRINTF(" ref %d", fp->fr_ref);
    471 	}
    472 	(void)putchar('\n');
    473 }
    474