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