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