xref: /illumos-gate/usr/src/cmd/ipf/lib/common/printfr.c (revision 7663b816)
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.37 2003/06/03 16:01:12 darrenr Exp $
7  *
8  * Copyright 2005 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 
17 void printlookup(addr, mask)
18 i6addr_t *addr, *mask;
19 {
20 	switch (addr->iplookuptype)
21 	{
22 	case IPLT_POOL :
23 		printf("pool/");
24 		break;
25 	case IPLT_HASH :
26 		printf("hash/");
27 		break;
28 	default :
29 		printf("lookup(%x)=", addr->iplookuptype);
30 		break;
31 	}
32 
33 	printf("%u", addr->iplookupnum);
34 	if (opts & OPT_UNDEF) {
35 		if (mask->iplookupptr == NULL) {
36 			printf("(!)");
37 		}
38 	}
39 }
40 
41 
42 /*
43  * print the filter structure in a useful way
44  */
45 void	printfr(fp, iocfunc)
46 struct	frentry	*fp;
47 ioctlfunc_t	iocfunc;
48 {
49 	struct protoent	*p;
50 	u_short	sec[2];
51 	u_32_t type;
52 	u_char *t;
53 	char *s;
54 	int pr;
55 
56 	pr = -2;
57 	type = fp->fr_type & ~FR_T_BUILTIN;
58 
59 	if ((fp->fr_type & FR_T_BUILTIN) != 0)
60 		printf("# Builtin: ");
61 
62 	if (fp->fr_type == FR_T_CALLFUNC) {
63 		;
64 	} else if (fp->fr_func != NULL) {
65 		printf("call");
66 		if ((fp->fr_flags & FR_CALLNOW) != 0)
67 			printf(" now");
68 		s = kvatoname(fp->fr_func, iocfunc);
69 		printf(" %s/%u", s ? s : "?", fp->fr_arg);
70 	} else if (FR_ISPASS(fp->fr_flags))
71 		printf("pass");
72 	else if (FR_ISBLOCK(fp->fr_flags)) {
73 		printf("block");
74 		if (fp->fr_flags & FR_RETICMP) {
75 			if ((fp->fr_flags & FR_RETMASK) == FR_FAKEICMP)
76 				printf(" return-icmp-as-dest");
77 			else if ((fp->fr_flags & FR_RETMASK) == FR_RETICMP)
78 				printf(" return-icmp");
79 			if (fp->fr_icode) {
80 				if (fp->fr_icode <= MAX_ICMPCODE)
81 					printf("(%s)",
82 						icmpcodes[(int)fp->fr_icode]);
83 				else
84 					printf("(%d)", fp->fr_icode);
85 			}
86 		} else if ((fp->fr_flags & FR_RETMASK) == FR_RETRST)
87 			printf(" return-rst");
88 	} else if ((fp->fr_flags & FR_LOGMASK) == FR_LOG) {
89 		printlog(fp);
90 	} else if (FR_ISACCOUNT(fp->fr_flags))
91 		printf("count");
92 	else if (FR_ISAUTH(fp->fr_flags))
93 		printf("auth");
94 	else if (FR_ISPREAUTH(fp->fr_flags))
95 		printf("preauth");
96 	else if (FR_ISNOMATCH(fp->fr_flags))
97 		printf("nomatch");
98 	else if (FR_ISSKIP(fp->fr_flags))
99 		printf("skip %u", fp->fr_arg);
100 	else {
101 		printf("%x", fp->fr_flags);
102 	}
103 
104 	if (fp->fr_flags & FR_OUTQUE)
105 		printf(" out ");
106 	else
107 		printf(" in ");
108 
109 	if (((fp->fr_flags & FR_LOGB) == FR_LOGB) ||
110 	    ((fp->fr_flags & FR_LOGP) == FR_LOGP)) {
111 		printlog(fp);
112 		putchar(' ');
113 	}
114 
115 	if (fp->fr_flags & FR_QUICK)
116 		printf("quick ");
117 
118 	if (*fp->fr_ifname) {
119 		printifname("on ", fp->fr_ifname, fp->fr_ifa);
120 		if (*fp->fr_ifnames[1] && strcmp(fp->fr_ifnames[1], "*"))
121 			printifname(",", fp->fr_ifnames[1], fp->fr_ifas[1]);
122 		putchar(' ');
123 
124 		if (*fp->fr_dif.fd_ifname)
125 			print_toif("dup-to", &fp->fr_dif);
126 		if (*fp->fr_tif.fd_ifname)
127 			print_toif("to", &fp->fr_tif);
128 		if (fp->fr_flags & FR_FASTROUTE)
129 			printf("fastroute ");
130 
131 		if ((*fp->fr_ifnames[2] && strcmp(fp->fr_ifnames[2], "*")) ||
132 		    (*fp->fr_ifnames[3] && strcmp(fp->fr_ifnames[3], "*"))) {
133 			if (fp->fr_flags & FR_OUTQUE)
134 				printf("in-via ");
135 			else
136 				printf("out-via ");
137 
138 			if (*fp->fr_ifnames[2]) {
139 				printifname("", fp->fr_ifnames[2],
140 					    fp->fr_ifas[2]);
141 				putchar(' ');
142 
143 				if (*fp->fr_ifnames[3]) {
144 					printifname(",", fp->fr_ifnames[3],
145 						    fp->fr_ifas[3]);
146 				}
147 			}
148 		}
149 	}
150 
151 	if (type == FR_T_IPF) {
152 		if (fp->fr_mip.fi_tos)
153 			printf("tos %#x ", fp->fr_tos);
154 		if (fp->fr_mip.fi_ttl)
155 			printf("ttl %d ", fp->fr_ttl);
156 		if (fp->fr_flx & FI_TCPUDP) {
157 			printf("proto tcp/udp ");
158 			pr = -1;
159 		} else if (fp->fr_mip.fi_p) {
160 			pr = fp->fr_ip.fi_p;
161 			if ((p = getprotobynumber(fp->fr_proto)))
162 				printf("proto %s ", p->p_name);
163 			else
164 				printf("proto %d ", fp->fr_proto);
165 		}
166 	}
167 
168 	if (type == FR_T_NONE) {
169 		printf("all");
170 	} else if (type == FR_T_IPF) {
171 		printf("from %s", fp->fr_flags & FR_NOTSRCIP ? "!" : "");
172 		if (fp->fr_satype != FRI_NORMAL) {
173 			printf("%s", fp->fr_ifname);
174 			if (fp->fr_satype == FRI_BROADCAST)
175 				printf("/bcast");
176 			else if (fp->fr_satype == FRI_NETWORK)
177 				printf("/net");
178 			else if (fp->fr_satype == FRI_NETMASKED)
179 				printf("/netmasked");
180 			else if (fp->fr_satype == FRI_PEERADDR)
181 				printf("/peer");
182 			else if (fp->fr_satype == FRI_LOOKUP)
183 				printlookup(&fp->fr_ip.fi_src,
184 					    &fp->fr_mip.fi_src);
185 			else
186 				printmask(fp->fr_v,
187 					  (u_32_t *)&fp->fr_smsk.s_addr);
188 		} else
189 			printhostmask(fp->fr_v, (u_32_t *)&fp->fr_src.s_addr,
190 				      (u_32_t *)&fp->fr_smsk.s_addr);
191 		if (fp->fr_scmp)
192 			printportcmp(pr, &fp->fr_tuc.ftu_src);
193 
194 		printf(" to %s", fp->fr_flags & FR_NOTDSTIP ? "!" : "");
195 		if (fp->fr_datype != FRI_NORMAL) {
196 			printf("%s", fp->fr_ifname);
197 			if (fp->fr_datype == FRI_BROADCAST)
198 				printf("/bcast");
199 			else if (fp->fr_datype == FRI_NETWORK)
200 				printf("/net");
201 			else if (fp->fr_datype == FRI_NETMASKED)
202 				printf("/netmasked");
203 			else if (fp->fr_datype == FRI_PEERADDR)
204 				printf("/peer");
205 			else if (fp->fr_datype == FRI_LOOKUP)
206 				printlookup(&fp->fr_ip.fi_dst,
207 					    &fp->fr_mip.fi_dst);
208 			else
209 				printmask(fp->fr_v,
210 					  (u_32_t *)&fp->fr_dmsk.s_addr);
211 		} else
212 			printhostmask(fp->fr_v, (u_32_t *)&fp->fr_dst.s_addr,
213 				      (u_32_t *)&fp->fr_dmsk.s_addr);
214 		if (fp->fr_dcmp)
215 			printportcmp(pr, &fp->fr_tuc.ftu_dst);
216 
217 		if ((fp->fr_flx & FI_WITH) || (fp->fr_mflx & FI_WITH) ||
218 		    fp->fr_optbits || fp->fr_optmask ||
219 		    fp->fr_secbits || fp->fr_secmask) {
220 			printf(" with");
221 			if (fp->fr_optbits || fp->fr_optmask ||
222 			    fp->fr_secbits || fp->fr_secmask) {
223 				sec[0] = fp->fr_secmask;
224 				sec[1] = fp->fr_secbits;
225 				if (fp->fr_v == 4)
226 					optprint(sec, fp->fr_optmask,
227 						 fp->fr_optbits);
228 #ifdef	USE_INET6
229 				else
230 					optprintv6(sec, fp->fr_optmask,
231 						   fp->fr_optbits);
232 #endif
233 			} else if (fp->fr_mflx & FI_OPTIONS) {
234 				if (!(fp->fr_flx & FI_OPTIONS))
235 					printf(" not");
236 				printf(" ipopts");
237 			}
238 			if (fp->fr_mflx & FI_SHORT) {
239 				if (!(fp->fr_flx & FI_SHORT))
240 					printf(" not");
241 				printf(" short");
242 			}
243 			if (fp->fr_mflx & FI_FRAG) {
244 				if (!(fp->fr_flx & FI_FRAG))
245 					printf(" not");
246 				printf(" frag");
247 			}
248 			if (fp->fr_mflx & FI_NATED) {
249 				if (!(fp->fr_flx & FI_NATED))
250 					printf(" not");
251 				printf(" nat");
252 			}
253 			if (fp->fr_mflx & FI_MULTICAST) {
254 				if (!(fp->fr_flx & FI_MULTICAST))
255 					printf(" not");
256 				printf(" multicast");
257 			}
258 			if (fp->fr_mflx & FI_BROADCAST) {
259 				if (!(fp->fr_flx & FI_BROADCAST))
260 					printf(" not");
261 				printf(" bcast");
262 			}
263 			if (fp->fr_mflx & FI_MBCAST) {
264 				if (!(fp->fr_flx & FI_MBCAST))
265 					printf(" not");
266 				printf(" mbcast");
267 			}
268 			if (fp->fr_mflx & FI_STATE) {
269 				if (!(fp->fr_flx & FI_STATE))
270 					printf(" not");
271 				printf(" state");
272 			}
273 			if (fp->fr_mflx & FI_BADNAT) {
274 				if (!(fp->fr_flx & FI_BADNAT))
275 					printf(" not");
276 				printf(" bad-nat");
277 			}
278 			if (fp->fr_mflx & FI_BAD) {
279 				if (!(fp->fr_flx & FI_BAD))
280 					printf(" not");
281 				printf(" bad");
282 			}
283 			if (fp->fr_mflx & FI_OOW) {
284 				if (!(fp->fr_flx & FI_OOW))
285 					printf(" not");
286 				printf(" oow");
287 			}
288 			if (fp->fr_mflx & FI_LOWTTL) {
289 				if (!(fp->fr_flx & FI_LOWTTL))
290 					printf(" not");
291 				printf(" lowttl");
292 			}
293 			if (fp->fr_mflx & FI_BADSRC) {
294 				if (!(fp->fr_flx & FI_BADSRC))
295 					printf(" not");
296 				printf(" bad-src");
297 			}
298 		}
299 		if ((fp->fr_proto == IPPROTO_ICMP
300 #ifdef	USE_INET6
301 		    || fp->fr_proto == IPPROTO_ICMPV6
302 #endif
303 		    ) && fp->fr_icmpm) {
304 			int	type = fp->fr_icmp, code;
305 
306 			type = ntohs(fp->fr_icmp);
307 			code = type & 0xff;
308 			type /= 256;
309 			if (type < (sizeof(icmptypes) / sizeof(char *) - 1) &&
310 			    icmptypes[type] && fp->fr_proto == IPPROTO_ICMP)
311 				printf(" icmp-type %s", icmptypes[type]);
312 			else
313 				printf(" icmp-type %d", type);
314 			if (ntohs(fp->fr_icmpm) & 0xff)
315 				printf(" code %d", code);
316 		}
317 		if ((fp->fr_proto == IPPROTO_TCP) &&
318 		    (fp->fr_tcpf || fp->fr_tcpfm)) {
319 			printf(" flags ");
320 			if (fp->fr_tcpf & ~TCPF_ALL)
321 				printf("0x%x", fp->fr_tcpf);
322 			else
323 				for (s = flagset, t = flags; *s; s++, t++)
324 					if (fp->fr_tcpf & *t)
325 						(void)putchar(*s);
326 			if (fp->fr_tcpfm) {
327 				(void)putchar('/');
328 				if (fp->fr_tcpfm & ~TCPF_ALL)
329 					printf("0x%x", fp->fr_tcpfm);
330 				else
331 					for (s = flagset, t = flags; *s;
332 					     s++, t++)
333 						if (fp->fr_tcpfm & *t)
334 							(void)putchar(*s);
335 			}
336 		}
337 #ifdef IPFILTER_BPF
338 	} else if (type == FR_T_BPFOPC) {
339 		u_32_t *bp;
340 		int i;
341 
342 		printf("{");
343 		i = fp->fr_dsize / sizeof(*bp);
344 
345 		for (bp = fp->fr_data; i; i--, bp++)
346 			printf(" 0x%08x", *bp);
347 
348 		printf(" }");
349 #endif
350 	} else if (type == FR_T_COMPIPF) {
351 		;
352 	} else if (type == FR_T_CALLFUNC) {
353 		printf("call function at %p", fp->fr_data);
354 	} else {
355 		printf("[unknown filter type %#x]", fp->fr_type);
356 	}
357 
358 	if (fp->fr_flags & FR_KEEPSTATE) {
359 		printf(" keep state");
360 		if ((fp->fr_flags & (FR_STSTRICT|FR_NEWISN)) ||
361 		    (fp->fr_statemax != 0) || (fp->fr_age[0] != 0)) {
362 			printf(" (");
363 			if (fp->fr_statemax != 0)
364 				printf(" limit %u", fp->fr_statemax);
365 			if (fp->fr_flags & FR_FRSTRICT)
366 				printf(" strict");
367 			if (fp->fr_flags & FR_NEWISN)
368 				printf(" newisn");
369 			if (fp->fr_age[0] || fp->fr_age[1])
370 				printf(" age %d/%d", fp->fr_age[0],
371 				       fp->fr_age[1]);
372 			printf(" )");
373 		}
374 	}
375 	if (fp->fr_flags & FR_KEEPFRAG) {
376 		printf(" keep frags");
377 		if (fp->fr_flags & (FR_FRSTRICT)) {
378 			printf(" (");
379 			if (fp->fr_flags & FR_FRSTRICT)
380 				printf(" strict");
381 			printf(" )");
382 
383 		}
384 	}
385 	if (fp->fr_isc != (struct ipscan *)-1) {
386 		if (fp->fr_isctag[0])
387 			printf(" scan %s", fp->fr_isctag);
388 		else
389 			printf(" scan *");
390 	}
391 	if (*fp->fr_grhead != '\0')
392 		printf(" head %s", fp->fr_grhead);
393 	if (*fp->fr_group != '\0')
394 		printf(" group %s", fp->fr_group);
395 	if (fp->fr_logtag != FR_NOLOGTAG)
396 		printf(" log-tag %u", fp->fr_logtag);
397 	if (fp->fr_pps)
398 		printf(" pps %d", fp->fr_pps);
399 	(void)putchar('\n');
400 }
401