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