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 */
printfr(fp,iocfunc)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