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