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