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