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