printfr.c revision 145510
1/*	$NetBSD$	*/
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.10 2005/03/16 15:38:13 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_type == FR_T_CALLFUNC) {
111		;
112	} else if (fp->fr_func != NULL) {
113		printf("call");
114		if ((fp->fr_flags & FR_CALLNOW) != 0)
115			printf(" now");
116		s = kvatoname(fp->fr_func, iocfunc);
117		printf(" %s/%u", s ? s : "?", fp->fr_arg);
118	} else if (FR_ISPASS(fp->fr_flags))
119		printf("pass");
120	else if (FR_ISBLOCK(fp->fr_flags)) {
121		printf("block");
122		if (fp->fr_flags & FR_RETICMP) {
123			if ((fp->fr_flags & FR_RETMASK) == FR_FAKEICMP)
124				printf(" return-icmp-as-dest");
125			else if ((fp->fr_flags & FR_RETMASK) == FR_RETICMP)
126				printf(" return-icmp");
127			if (fp->fr_icode) {
128				if (fp->fr_icode <= MAX_ICMPCODE)
129					printf("(%s)",
130						icmpcodes[(int)fp->fr_icode]);
131				else
132					printf("(%d)", fp->fr_icode);
133			}
134		} else if ((fp->fr_flags & FR_RETMASK) == FR_RETRST)
135			printf(" return-rst");
136	} else if ((fp->fr_flags & FR_LOGMASK) == FR_LOG) {
137		printlog(fp);
138	} else if (FR_ISACCOUNT(fp->fr_flags))
139		printf("count");
140	else if (FR_ISAUTH(fp->fr_flags))
141		printf("auth");
142	else if (FR_ISPREAUTH(fp->fr_flags))
143		printf("preauth");
144	else if (FR_ISNOMATCH(fp->fr_flags))
145		printf("nomatch");
146	else if (FR_ISSKIP(fp->fr_flags))
147		printf("skip %u", fp->fr_arg);
148	else {
149		printf("%x", fp->fr_flags);
150	}
151
152	if (fp->fr_flags & FR_OUTQUE)
153		printf(" out ");
154	else
155		printf(" in ");
156
157	if (((fp->fr_flags & FR_LOGB) == FR_LOGB) ||
158	    ((fp->fr_flags & FR_LOGP) == FR_LOGP)) {
159		printlog(fp);
160		putchar(' ');
161	}
162
163	if (fp->fr_flags & FR_QUICK)
164		printf("quick ");
165
166	if (*fp->fr_ifname) {
167		printifname("on ", fp->fr_ifname, fp->fr_ifa);
168		if (*fp->fr_ifnames[1] && strcmp(fp->fr_ifnames[1], "*"))
169			printifname(",", fp->fr_ifnames[1], fp->fr_ifas[1]);
170		putchar(' ');
171	}
172
173	if (*fp->fr_dif.fd_ifname || (fp->fr_flags & FR_DUP))
174		print_toif("dup-to", &fp->fr_dif);
175	if (*fp->fr_tif.fd_ifname)
176		print_toif("to", &fp->fr_tif);
177	if (*fp->fr_rif.fd_ifname)
178		print_toif("reply-to", &fp->fr_rif);
179	if (fp->fr_flags & FR_FASTROUTE)
180		printf("fastroute ");
181
182	if ((*fp->fr_ifnames[2] && strcmp(fp->fr_ifnames[2], "*")) ||
183	    (*fp->fr_ifnames[3] && strcmp(fp->fr_ifnames[3], "*"))) {
184		if (fp->fr_flags & FR_OUTQUE)
185			printf("in-via ");
186		else
187			printf("out-via ");
188
189		if (*fp->fr_ifnames[2]) {
190			printifname("", fp->fr_ifnames[2],
191				    fp->fr_ifas[2]);
192			putchar(' ');
193
194			if (*fp->fr_ifnames[3]) {
195				printifname(",", fp->fr_ifnames[3],
196					    fp->fr_ifas[3]);
197			}
198		}
199	}
200
201	if (type == FR_T_IPF) {
202		if (fp->fr_mip.fi_tos)
203			printf("tos %#x ", fp->fr_tos);
204		if (fp->fr_mip.fi_ttl)
205			printf("ttl %d ", fp->fr_ttl);
206		if (fp->fr_flx & FI_TCPUDP) {
207			printf("proto tcp/udp ");
208			pr = -1;
209		} else if (fp->fr_mip.fi_p) {
210			pr = fp->fr_ip.fi_p;
211			if ((p = getprotobynumber(fp->fr_proto)))
212				printf("proto %s ", p->p_name);
213			else
214				printf("proto %d ", fp->fr_proto);
215		}
216	}
217
218	if (type == FR_T_NONE) {
219		printf("all");
220	} else if (type == FR_T_IPF) {
221		printf("from %s", fp->fr_flags & FR_NOTSRCIP ? "!" : "");
222		printaddr(fp->fr_v, fp->fr_satype, fp->fr_ifname,
223			  &fp->fr_src.s_addr, &fp->fr_smsk.s_addr);
224		if (fp->fr_scmp)
225			printportcmp(pr, &fp->fr_tuc.ftu_src);
226
227		printf(" to %s", fp->fr_flags & FR_NOTDSTIP ? "!" : "");
228		printaddr(fp->fr_v, fp->fr_datype, fp->fr_ifname,
229			  &fp->fr_dst.s_addr, &fp->fr_dmsk.s_addr);
230		if (fp->fr_dcmp)
231			printportcmp(pr, &fp->fr_tuc.ftu_dst);
232
233		if (fp->fr_proto == IPPROTO_ICMP && fp->fr_icmpm) {
234			int	type = fp->fr_icmp, code;
235
236			type = ntohs(fp->fr_icmp);
237			code = type & 0xff;
238			type /= 256;
239			if (type < (sizeof(icmptypes) / sizeof(char *) - 1) &&
240			    icmptypes[type])
241				printf(" icmp-type %s", icmptypes[type]);
242			else
243				printf(" icmp-type %d", type);
244			if (ntohs(fp->fr_icmpm) & 0xff)
245				printf(" code %d", code);
246		}
247		if ((fp->fr_proto == IPPROTO_TCP) &&
248		    (fp->fr_tcpf || fp->fr_tcpfm)) {
249			printf(" flags ");
250			if (fp->fr_tcpf & ~TCPF_ALL)
251				printf("0x%x", fp->fr_tcpf);
252			else
253				for (s = flagset, t = flags; *s; s++, t++)
254					if (fp->fr_tcpf & *t)
255						(void)putchar(*s);
256			if (fp->fr_tcpfm) {
257				(void)putchar('/');
258				if (fp->fr_tcpfm & ~TCPF_ALL)
259					printf("0x%x", fp->fr_tcpfm);
260				else
261					for (s = flagset, t = flags; *s;
262					     s++, t++)
263						if (fp->fr_tcpfm & *t)
264							(void)putchar(*s);
265			}
266		}
267	} else if (type == FR_T_BPFOPC) {
268		fakebpf_t *fb;
269		int i;
270
271		printf("bpf-v%d { \"", fp->fr_v);
272		i = fp->fr_dsize / sizeof(*fb);
273
274		for (fb = fp->fr_data, s = ""; i; i--, fb++, s = " ")
275			printf("%s%#x %#x %#x %#x", s, fb->fb_c, fb->fb_t,
276			       fb->fb_f, fb->fb_k);
277
278		printf("\" }");
279	} else if (type == FR_T_COMPIPF) {
280		;
281	} else if (type == FR_T_CALLFUNC) {
282		printf("call function at %p", fp->fr_data);
283	} else {
284		printf("[unknown filter type %#x]", fp->fr_type);
285	}
286
287	if ((type == FR_T_IPF) &&
288	    ((fp->fr_flx & FI_WITH) || (fp->fr_mflx & FI_WITH) ||
289	     fp->fr_optbits || fp->fr_optmask ||
290	     fp->fr_secbits || fp->fr_secmask)) {
291		char *comma = " ";
292
293		printf(" with");
294		if (fp->fr_optbits || fp->fr_optmask ||
295		    fp->fr_secbits || fp->fr_secmask) {
296			sec[0] = fp->fr_secmask;
297			sec[1] = fp->fr_secbits;
298			if (fp->fr_v == 4)
299				optprint(sec, fp->fr_optmask, fp->fr_optbits);
300#ifdef	USE_INET6
301			else
302				optprintv6(sec, fp->fr_optmask,
303					   fp->fr_optbits);
304#endif
305		} else if (fp->fr_mflx & FI_OPTIONS) {
306			fputs(comma, stdout);
307			if (!(fp->fr_flx & FI_OPTIONS))
308				printf("not ");
309			printf("ipopts");
310			comma = ",";
311		}
312		if (fp->fr_mflx & FI_SHORT) {
313			fputs(comma, stdout);
314			if (!(fp->fr_flx & FI_SHORT))
315				printf("not ");
316			printf("short");
317			comma = ",";
318		}
319		if (fp->fr_mflx & FI_FRAG) {
320			fputs(comma, stdout);
321			if (!(fp->fr_flx & FI_FRAG))
322				printf("not ");
323			printf("frag");
324			comma = ",";
325		}
326		if (fp->fr_mflx & FI_FRAGBODY) {
327			fputs(comma, stdout);
328			if (!(fp->fr_flx & FI_FRAGBODY))
329				printf("not ");
330			printf("frag-body");
331			comma = ",";
332		}
333		if (fp->fr_mflx & FI_NATED) {
334			fputs(comma, stdout);
335			if (!(fp->fr_flx & FI_NATED))
336				printf("not ");
337			printf("nat");
338			comma = ",";
339		}
340		if (fp->fr_mflx & FI_LOWTTL) {
341			fputs(comma, stdout);
342			if (!(fp->fr_flx & FI_LOWTTL))
343				printf("not ");
344			printf("lowttl");
345			comma = ",";
346		}
347		if (fp->fr_mflx & FI_BAD) {
348			fputs(comma, stdout);
349			if (!(fp->fr_flx & FI_BAD))
350				printf("not ");
351			printf("bad");
352			comma = ",";
353		}
354		if (fp->fr_mflx & FI_BADSRC) {
355			fputs(comma, stdout);
356			if (!(fp->fr_flx & FI_BADSRC))
357				printf("not ");
358			printf("bad-src");
359			comma = ",";
360		}
361		if (fp->fr_mflx & FI_BADNAT) {
362			fputs(comma, stdout);
363			if (!(fp->fr_flx & FI_BADNAT))
364				printf("not ");
365			printf("bad-nat");
366			comma = ",";
367		}
368		if (fp->fr_mflx & FI_OOW) {
369			fputs(comma, stdout);
370			if (!(fp->fr_flx & FI_OOW))
371				printf("not ");
372			printf("oow");
373		}
374	}
375
376	if (fp->fr_flags & FR_KEEPSTATE) {
377		printf(" keep state");
378		if ((fp->fr_flags & (FR_STSTRICT|FR_NEWISN|FR_NOICMPERR|FR_STATESYNC)) ||
379		    (fp->fr_statemax != 0) || (fp->fr_age[0] != 0)) {
380			char *comma = "";
381			printf(" (");
382			if (fp->fr_statemax != 0) {
383				printf("limit %u", fp->fr_statemax);
384				comma = ",";
385			}
386			if (fp->fr_flags & FR_STSTRICT) {
387				printf("%sstrict", comma);
388				comma = ",";
389			}
390			if (fp->fr_flags & FR_NEWISN) {
391				printf("%snewisn", comma);
392				comma = ",";
393			}
394			if (fp->fr_flags & FR_NOICMPERR) {
395				printf("%sno-icmp-err", comma);
396				comma = ",";
397			}
398			if (fp->fr_flags & FR_STATESYNC) {
399				printf("%ssync", comma);
400				comma = ",";
401			}
402			if (fp->fr_age[0] || fp->fr_age[1])
403				printf("%sage %d/%d", comma, fp->fr_age[0],
404				       fp->fr_age[1]);
405			printf(")");
406		}
407	}
408	if (fp->fr_flags & FR_KEEPFRAG) {
409		printf(" keep frags");
410		if (fp->fr_flags & (FR_FRSTRICT)) {
411			printf(" (");
412			if (fp->fr_flags & FR_FRSTRICT)
413				printf(" strict");
414			printf(" )");
415
416		}
417	}
418	if (fp->fr_isc != (struct ipscan *)-1) {
419		if (fp->fr_isctag[0])
420			printf(" scan %s", fp->fr_isctag);
421		else
422			printf(" scan *");
423	}
424	if (*fp->fr_grhead != '\0')
425		printf(" head %s", fp->fr_grhead);
426	if (*fp->fr_group != '\0')
427		printf(" group %s", fp->fr_group);
428	if (fp->fr_logtag != FR_NOLOGTAG || *fp->fr_nattag.ipt_tag) {
429		char *s = "";
430
431		printf(" set-tag(");
432		if (fp->fr_logtag != FR_NOLOGTAG) {
433			printf("log=%u", fp->fr_logtag);
434			s = ", ";
435		}
436		if (*fp->fr_nattag.ipt_tag) {
437			printf("%snat=%-.*s", s, IPFTAG_LEN,
438				fp->fr_nattag.ipt_tag);
439		}
440		printf(")");
441	}
442	if (fp->fr_pps)
443		printf(" pps %d", fp->fr_pps);
444	(void)putchar('\n');
445}
446