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