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