xref: /illumos-gate/usr/src/cmd/ipf/lib/common/printfr.c (revision d6c23f6f)
17c478bd9Sstevel@tonic-gate /*
2*d6c23f6fSyx  * Copyright (C) 2000-2005 by Darren Reed.
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * See the IPFILTER.LICENCE file for details on licencing.
57c478bd9Sstevel@tonic-gate  *
6ab25eeb5Syz  * $Id: printfr.c,v 1.43.2.12 2005/06/12 07:18:42 darrenr Exp $
77c478bd9Sstevel@tonic-gate  *
81b47e080Sdr  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
97c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
107c478bd9Sstevel@tonic-gate  */
117c478bd9Sstevel@tonic-gate 
127c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
137c478bd9Sstevel@tonic-gate 
147c478bd9Sstevel@tonic-gate #include "ipf.h"
157c478bd9Sstevel@tonic-gate 
167c478bd9Sstevel@tonic-gate /*
177c478bd9Sstevel@tonic-gate  * print the filter structure in a useful way
187c478bd9Sstevel@tonic-gate  */
printfr(fp,iocfunc)197c478bd9Sstevel@tonic-gate void	printfr(fp, iocfunc)
207c478bd9Sstevel@tonic-gate struct	frentry	*fp;
217c478bd9Sstevel@tonic-gate ioctlfunc_t	iocfunc;
227c478bd9Sstevel@tonic-gate {
237c478bd9Sstevel@tonic-gate 	struct protoent	*p;
247c478bd9Sstevel@tonic-gate 	u_short	sec[2];
257c478bd9Sstevel@tonic-gate 	u_32_t type;
267c478bd9Sstevel@tonic-gate 	u_char *t;
277c478bd9Sstevel@tonic-gate 	char *s;
287c478bd9Sstevel@tonic-gate 	int pr;
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate 	pr = -2;
317c478bd9Sstevel@tonic-gate 	type = fp->fr_type & ~FR_T_BUILTIN;
327c478bd9Sstevel@tonic-gate 
337c478bd9Sstevel@tonic-gate 	if ((fp->fr_type & FR_T_BUILTIN) != 0)
347c478bd9Sstevel@tonic-gate 		printf("# Builtin: ");
357c478bd9Sstevel@tonic-gate 
36ab25eeb5Syz 	if (fp->fr_collect != 0)
37ab25eeb5Syz 		printf("%u ", fp->fr_collect);
38ab25eeb5Syz 
397c478bd9Sstevel@tonic-gate 	if (fp->fr_type == FR_T_CALLFUNC) {
407c478bd9Sstevel@tonic-gate 		;
417c478bd9Sstevel@tonic-gate 	} else if (fp->fr_func != NULL) {
427c478bd9Sstevel@tonic-gate 		printf("call");
437c478bd9Sstevel@tonic-gate 		if ((fp->fr_flags & FR_CALLNOW) != 0)
447c478bd9Sstevel@tonic-gate 			printf(" now");
457c478bd9Sstevel@tonic-gate 		s = kvatoname(fp->fr_func, iocfunc);
467c478bd9Sstevel@tonic-gate 		printf(" %s/%u", s ? s : "?", fp->fr_arg);
477c478bd9Sstevel@tonic-gate 	} else if (FR_ISPASS(fp->fr_flags))
487c478bd9Sstevel@tonic-gate 		printf("pass");
497c478bd9Sstevel@tonic-gate 	else if (FR_ISBLOCK(fp->fr_flags)) {
507c478bd9Sstevel@tonic-gate 		printf("block");
517c478bd9Sstevel@tonic-gate 		if (fp->fr_flags & FR_RETICMP) {
527c478bd9Sstevel@tonic-gate 			if ((fp->fr_flags & FR_RETMASK) == FR_FAKEICMP)
537c478bd9Sstevel@tonic-gate 				printf(" return-icmp-as-dest");
547c478bd9Sstevel@tonic-gate 			else if ((fp->fr_flags & FR_RETMASK) == FR_RETICMP)
557c478bd9Sstevel@tonic-gate 				printf(" return-icmp");
567c478bd9Sstevel@tonic-gate 			if (fp->fr_icode) {
577c478bd9Sstevel@tonic-gate 				if (fp->fr_icode <= MAX_ICMPCODE)
587c478bd9Sstevel@tonic-gate 					printf("(%s)",
597c478bd9Sstevel@tonic-gate 						icmpcodes[(int)fp->fr_icode]);
607c478bd9Sstevel@tonic-gate 				else
617c478bd9Sstevel@tonic-gate 					printf("(%d)", fp->fr_icode);
627c478bd9Sstevel@tonic-gate 			}
637c478bd9Sstevel@tonic-gate 		} else if ((fp->fr_flags & FR_RETMASK) == FR_RETRST)
647c478bd9Sstevel@tonic-gate 			printf(" return-rst");
657c478bd9Sstevel@tonic-gate 	} else if ((fp->fr_flags & FR_LOGMASK) == FR_LOG) {
667c478bd9Sstevel@tonic-gate 		printlog(fp);
677c478bd9Sstevel@tonic-gate 	} else if (FR_ISACCOUNT(fp->fr_flags))
687c478bd9Sstevel@tonic-gate 		printf("count");
697c478bd9Sstevel@tonic-gate 	else if (FR_ISAUTH(fp->fr_flags))
707c478bd9Sstevel@tonic-gate 		printf("auth");
717c478bd9Sstevel@tonic-gate 	else if (FR_ISPREAUTH(fp->fr_flags))
727c478bd9Sstevel@tonic-gate 		printf("preauth");
737c478bd9Sstevel@tonic-gate 	else if (FR_ISNOMATCH(fp->fr_flags))
747c478bd9Sstevel@tonic-gate 		printf("nomatch");
757c478bd9Sstevel@tonic-gate 	else if (FR_ISSKIP(fp->fr_flags))
767c478bd9Sstevel@tonic-gate 		printf("skip %u", fp->fr_arg);
777c478bd9Sstevel@tonic-gate 	else {
787c478bd9Sstevel@tonic-gate 		printf("%x", fp->fr_flags);
797c478bd9Sstevel@tonic-gate 	}
807c478bd9Sstevel@tonic-gate 
817c478bd9Sstevel@tonic-gate 	if (fp->fr_flags & FR_OUTQUE)
827c478bd9Sstevel@tonic-gate 		printf(" out ");
837c478bd9Sstevel@tonic-gate 	else
847c478bd9Sstevel@tonic-gate 		printf(" in ");
857c478bd9Sstevel@tonic-gate 
867c478bd9Sstevel@tonic-gate 	if (((fp->fr_flags & FR_LOGB) == FR_LOGB) ||
877c478bd9Sstevel@tonic-gate 	    ((fp->fr_flags & FR_LOGP) == FR_LOGP)) {
887c478bd9Sstevel@tonic-gate 		printlog(fp);
897c478bd9Sstevel@tonic-gate 		putchar(' ');
907c478bd9Sstevel@tonic-gate 	}
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate 	if (fp->fr_flags & FR_QUICK)
937c478bd9Sstevel@tonic-gate 		printf("quick ");
947c478bd9Sstevel@tonic-gate 
957c478bd9Sstevel@tonic-gate 	if (*fp->fr_ifname) {
967c478bd9Sstevel@tonic-gate 		printifname("on ", fp->fr_ifname, fp->fr_ifa);
977c478bd9Sstevel@tonic-gate 		if (*fp->fr_ifnames[1] && strcmp(fp->fr_ifnames[1], "*"))
987c478bd9Sstevel@tonic-gate 			printifname(",", fp->fr_ifnames[1], fp->fr_ifas[1]);
997c478bd9Sstevel@tonic-gate 		putchar(' ');
100ab25eeb5Syz 	}
1017c478bd9Sstevel@tonic-gate 
102ab25eeb5Syz 	if (*fp->fr_dif.fd_ifname || (fp->fr_flags & FR_DUP))
103ab25eeb5Syz 		print_toif("dup-to", &fp->fr_dif);
104ab25eeb5Syz 	if (*fp->fr_tif.fd_ifname)
105ab25eeb5Syz 		print_toif("to", &fp->fr_tif);
106ab25eeb5Syz 	if (*fp->fr_rif.fd_ifname)
107ab25eeb5Syz 		print_toif("reply-to", &fp->fr_rif);
108ab25eeb5Syz 	if (fp->fr_flags & FR_FASTROUTE)
109ab25eeb5Syz 		printf("fastroute ");
1107c478bd9Sstevel@tonic-gate 
111ab25eeb5Syz 	if ((*fp->fr_ifnames[2] && strcmp(fp->fr_ifnames[2], "*")) ||
112ab25eeb5Syz 	    (*fp->fr_ifnames[3] && strcmp(fp->fr_ifnames[3], "*"))) {
113ab25eeb5Syz 		if (fp->fr_flags & FR_OUTQUE)
114ab25eeb5Syz 			printf("in-via ");
115ab25eeb5Syz 		else
116ab25eeb5Syz 			printf("out-via ");
117ab25eeb5Syz 
118ab25eeb5Syz 		if (*fp->fr_ifnames[2]) {
119ab25eeb5Syz 			printifname("", fp->fr_ifnames[2],
120ab25eeb5Syz 				    fp->fr_ifas[2]);
121ab25eeb5Syz 			putchar(' ');
1227c478bd9Sstevel@tonic-gate 
123ab25eeb5Syz 			if (*fp->fr_ifnames[3]) {
124ab25eeb5Syz 				printifname(",", fp->fr_ifnames[3],
125ab25eeb5Syz 					    fp->fr_ifas[3]);
1267c478bd9Sstevel@tonic-gate 			}
1277c478bd9Sstevel@tonic-gate 		}
1287c478bd9Sstevel@tonic-gate 	}
1297c478bd9Sstevel@tonic-gate 
1307c478bd9Sstevel@tonic-gate 	if (type == FR_T_IPF) {
1317c478bd9Sstevel@tonic-gate 		if (fp->fr_mip.fi_tos)
1327c478bd9Sstevel@tonic-gate 			printf("tos %#x ", fp->fr_tos);
1337c478bd9Sstevel@tonic-gate 		if (fp->fr_mip.fi_ttl)
1347c478bd9Sstevel@tonic-gate 			printf("ttl %d ", fp->fr_ttl);
1357c478bd9Sstevel@tonic-gate 		if (fp->fr_flx & FI_TCPUDP) {
1367c478bd9Sstevel@tonic-gate 			printf("proto tcp/udp ");
1377c478bd9Sstevel@tonic-gate 			pr = -1;
1387c478bd9Sstevel@tonic-gate 		} else if (fp->fr_mip.fi_p) {
1397c478bd9Sstevel@tonic-gate 			pr = fp->fr_ip.fi_p;
140ab25eeb5Syz 			p = getprotobynumber(pr);
141ab25eeb5Syz 			printf("proto ");
142ab25eeb5Syz 			printproto(p, pr, NULL);
143ab25eeb5Syz 			putchar(' ');
1447c478bd9Sstevel@tonic-gate 		}
1457c478bd9Sstevel@tonic-gate 	}
1467c478bd9Sstevel@tonic-gate 
1477c478bd9Sstevel@tonic-gate 	if (type == FR_T_NONE) {
1487c478bd9Sstevel@tonic-gate 		printf("all");
1497c478bd9Sstevel@tonic-gate 	} else if (type == FR_T_IPF) {
1507c478bd9Sstevel@tonic-gate 		printf("from %s", fp->fr_flags & FR_NOTSRCIP ? "!" : "");
151ab25eeb5Syz 		printaddr(fp->fr_v, fp->fr_satype, fp->fr_ifname,
152ab25eeb5Syz 			  &fp->fr_src.s_addr, &fp->fr_smsk.s_addr);
1537c478bd9Sstevel@tonic-gate 		if (fp->fr_scmp)
1547c478bd9Sstevel@tonic-gate 			printportcmp(pr, &fp->fr_tuc.ftu_src);
1557c478bd9Sstevel@tonic-gate 
1567c478bd9Sstevel@tonic-gate 		printf(" to %s", fp->fr_flags & FR_NOTDSTIP ? "!" : "");
157ab25eeb5Syz 		printaddr(fp->fr_v, fp->fr_datype, fp->fr_ifname,
158ab25eeb5Syz 			  &fp->fr_dst.s_addr, &fp->fr_dmsk.s_addr);
1597c478bd9Sstevel@tonic-gate 		if (fp->fr_dcmp)
1607c478bd9Sstevel@tonic-gate 			printportcmp(pr, &fp->fr_tuc.ftu_dst);
1617c478bd9Sstevel@tonic-gate 
1627663b816Sml 		if ((fp->fr_proto == IPPROTO_ICMP
1637663b816Sml #ifdef	USE_INET6
1647663b816Sml 		    || fp->fr_proto == IPPROTO_ICMPV6
1657663b816Sml #endif
1667663b816Sml 		    ) && fp->fr_icmpm) {
1677c478bd9Sstevel@tonic-gate 			int	type = fp->fr_icmp, code;
1687c478bd9Sstevel@tonic-gate 
1697c478bd9Sstevel@tonic-gate 			type = ntohs(fp->fr_icmp);
1707c478bd9Sstevel@tonic-gate 			code = type & 0xff;
1717c478bd9Sstevel@tonic-gate 			type /= 256;
1727c478bd9Sstevel@tonic-gate 			if (type < (sizeof(icmptypes) / sizeof(char *) - 1) &&
1737663b816Sml 			    icmptypes[type] && fp->fr_proto == IPPROTO_ICMP)
1747c478bd9Sstevel@tonic-gate 				printf(" icmp-type %s", icmptypes[type]);
1757c478bd9Sstevel@tonic-gate 			else
1767c478bd9Sstevel@tonic-gate 				printf(" icmp-type %d", type);
1777c478bd9Sstevel@tonic-gate 			if (ntohs(fp->fr_icmpm) & 0xff)
1787c478bd9Sstevel@tonic-gate 				printf(" code %d", code);
1797c478bd9Sstevel@tonic-gate 		}
1807c478bd9Sstevel@tonic-gate 		if ((fp->fr_proto == IPPROTO_TCP) &&
1817c478bd9Sstevel@tonic-gate 		    (fp->fr_tcpf || fp->fr_tcpfm)) {
1827c478bd9Sstevel@tonic-gate 			printf(" flags ");
1837c478bd9Sstevel@tonic-gate 			if (fp->fr_tcpf & ~TCPF_ALL)
1847c478bd9Sstevel@tonic-gate 				printf("0x%x", fp->fr_tcpf);
1857c478bd9Sstevel@tonic-gate 			else
1867c478bd9Sstevel@tonic-gate 				for (s = flagset, t = flags; *s; s++, t++)
1877c478bd9Sstevel@tonic-gate 					if (fp->fr_tcpf & *t)
1887c478bd9Sstevel@tonic-gate 						(void)putchar(*s);
1897c478bd9Sstevel@tonic-gate 			if (fp->fr_tcpfm) {
1907c478bd9Sstevel@tonic-gate 				(void)putchar('/');
1917c478bd9Sstevel@tonic-gate 				if (fp->fr_tcpfm & ~TCPF_ALL)
1927c478bd9Sstevel@tonic-gate 					printf("0x%x", fp->fr_tcpfm);
1937c478bd9Sstevel@tonic-gate 				else
1947c478bd9Sstevel@tonic-gate 					for (s = flagset, t = flags; *s;
1957c478bd9Sstevel@tonic-gate 					     s++, t++)
1967c478bd9Sstevel@tonic-gate 						if (fp->fr_tcpfm & *t)
1977c478bd9Sstevel@tonic-gate 							(void)putchar(*s);
1987c478bd9Sstevel@tonic-gate 			}
1997c478bd9Sstevel@tonic-gate 		}
2007c478bd9Sstevel@tonic-gate 	} else if (type == FR_T_BPFOPC) {
201ab25eeb5Syz 		fakebpf_t *fb;
2027c478bd9Sstevel@tonic-gate 		int i;
2037c478bd9Sstevel@tonic-gate 
204ab25eeb5Syz 		printf("bpf-v%d { \"", fp->fr_v);
205ab25eeb5Syz 		i = fp->fr_dsize / sizeof(*fb);
2067c478bd9Sstevel@tonic-gate 
207ab25eeb5Syz 		for (fb = fp->fr_data, s = ""; i; i--, fb++, s = " ")
208ab25eeb5Syz 			printf("%s%#x %#x %#x %#x", s, fb->fb_c, fb->fb_t,
209ab25eeb5Syz 			       fb->fb_f, fb->fb_k);
2107c478bd9Sstevel@tonic-gate 
211ab25eeb5Syz 		printf("\" }");
2127c478bd9Sstevel@tonic-gate 	} else if (type == FR_T_COMPIPF) {
2137c478bd9Sstevel@tonic-gate 		;
2147c478bd9Sstevel@tonic-gate 	} else if (type == FR_T_CALLFUNC) {
2157c478bd9Sstevel@tonic-gate 		printf("call function at %p", fp->fr_data);
2167c478bd9Sstevel@tonic-gate 	} else {
2177c478bd9Sstevel@tonic-gate 		printf("[unknown filter type %#x]", fp->fr_type);
2187c478bd9Sstevel@tonic-gate 	}
2197c478bd9Sstevel@tonic-gate 
220ab25eeb5Syz 	if ((type == FR_T_IPF) &&
221ab25eeb5Syz 	    ((fp->fr_flx & FI_WITH) || (fp->fr_mflx & FI_WITH) ||
222ab25eeb5Syz 	     fp->fr_optbits || fp->fr_optmask ||
223ab25eeb5Syz 	     fp->fr_secbits || fp->fr_secmask)) {
224ab25eeb5Syz 		char *comma = " ";
225ab25eeb5Syz 
226ab25eeb5Syz 		printf(" with");
227ab25eeb5Syz 		if (fp->fr_optbits || fp->fr_optmask ||
228ab25eeb5Syz 		    fp->fr_secbits || fp->fr_secmask) {
229ab25eeb5Syz 			sec[0] = fp->fr_secmask;
230ab25eeb5Syz 			sec[1] = fp->fr_secbits;
231ab25eeb5Syz 			if (fp->fr_v == 4)
232ab25eeb5Syz 				optprint(sec, fp->fr_optmask, fp->fr_optbits);
233ab25eeb5Syz #ifdef	USE_INET6
234ab25eeb5Syz 			else
235ab25eeb5Syz 				optprintv6(sec, fp->fr_optmask,
236ab25eeb5Syz 					   fp->fr_optbits);
237ab25eeb5Syz #endif
238ab25eeb5Syz 		} else if (fp->fr_mflx & FI_OPTIONS) {
239ab25eeb5Syz 			fputs(comma, stdout);
240ab25eeb5Syz 			if (!(fp->fr_flx & FI_OPTIONS))
241ab25eeb5Syz 				printf("not ");
242ab25eeb5Syz 			printf("ipopts");
243ab25eeb5Syz 			comma = ",";
244ab25eeb5Syz 		}
245ab25eeb5Syz 		if (fp->fr_mflx & FI_SHORT) {
246ab25eeb5Syz 			fputs(comma, stdout);
247ab25eeb5Syz 			if (!(fp->fr_flx & FI_SHORT))
248ab25eeb5Syz 				printf("not ");
249ab25eeb5Syz 			printf("short");
250ab25eeb5Syz 			comma = ",";
251ab25eeb5Syz 		}
252ab25eeb5Syz 		if (fp->fr_mflx & FI_FRAG) {
253ab25eeb5Syz 			fputs(comma, stdout);
254ab25eeb5Syz 			if (!(fp->fr_flx & FI_FRAG))
255ab25eeb5Syz 				printf("not ");
256ab25eeb5Syz 			printf("frag");
257ab25eeb5Syz 			comma = ",";
258ab25eeb5Syz 		}
259ab25eeb5Syz 		if (fp->fr_mflx & FI_FRAGBODY) {
260ab25eeb5Syz 			fputs(comma, stdout);
261ab25eeb5Syz 			if (!(fp->fr_flx & FI_FRAGBODY))
262ab25eeb5Syz 				printf("not ");
263ab25eeb5Syz 			printf("frag-body");
264ab25eeb5Syz