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