1 /* $OpenBSD: pfctl.c,v 1.382 2020/01/16 01:02:20 kn Exp $ */ 2 3 /* 4 * Copyright (c) 2001 Daniel Hartmeier 5 * Copyright (c) 2002 - 2013 Henning Brauer <henning@openbsd.org> 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * - Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * - Redistributions in binary form must reproduce the above 15 * copyright notice, this list of conditions and the following 16 * disclaimer in the documentation and/or other materials provided 17 * with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 22 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 23 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 25 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 29 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 * 32 */ 33 34 #include <sys/types.h> 35 #include <sys/ioctl.h> 36 #include <sys/socket.h> 37 #include <sys/stat.h> 38 39 #include <net/if.h> 40 #include <netinet/in.h> 41 #include <net/pfvar.h> 42 #include <arpa/inet.h> 43 #include <sys/sysctl.h> 44 45 #include <err.h> 46 #include <errno.h> 47 #include <fcntl.h> 48 #include <limits.h> 49 #include <netdb.h> 50 #include <stdio.h> 51 #include <stdlib.h> 52 #include <string.h> 53 #include <unistd.h> 54 #include <syslog.h> 55 #include <stdarg.h> 56 #include <libgen.h> 57 58 #include "pfctl_parser.h" 59 #include "pfctl.h" 60 61 void usage(void); 62 int pfctl_enable(int, int); 63 int pfctl_disable(int, int); 64 void pfctl_clear_queues(struct pf_qihead *); 65 void pfctl_clear_stats(int, const char *, int); 66 void pfctl_clear_interface_flags(int, int); 67 int pfctl_clear_rules(int, int, char *); 68 void pfctl_clear_src_nodes(int, int); 69 void pfctl_clear_states(int, const char *, int); 70 struct addrinfo * 71 pfctl_addrprefix(char *, struct pf_addr *, int); 72 void pfctl_kill_src_nodes(int, int); 73 void pfctl_net_kill_states(int, const char *, int, int); 74 void pfctl_label_kill_states(int, const char *, int, int); 75 void pfctl_id_kill_states(int, int); 76 void pfctl_key_kill_states(int, const char *, int, int); 77 int pfctl_parse_host(char *, struct pf_rule_addr *); 78 void pfctl_init_options(struct pfctl *); 79 int pfctl_load_options(struct pfctl *); 80 int pfctl_load_limit(struct pfctl *, unsigned int, unsigned int); 81 int pfctl_load_timeout(struct pfctl *, unsigned int, unsigned int); 82 int pfctl_load_debug(struct pfctl *, unsigned int); 83 int pfctl_load_logif(struct pfctl *, char *); 84 int pfctl_load_hostid(struct pfctl *, unsigned int); 85 int pfctl_load_reassembly(struct pfctl *, u_int32_t); 86 int pfctl_load_syncookies(struct pfctl *, u_int8_t); 87 int pfctl_set_synflwats(struct pfctl *, u_int32_t, u_int32_t); 88 void pfctl_print_rule_counters(struct pf_rule *, int); 89 int pfctl_show_rules(int, char *, int, enum pfctl_show, char *, int, int, 90 long); 91 int pfctl_show_src_nodes(int, int); 92 int pfctl_show_states(int, const char *, int, long); 93 int pfctl_show_status(int, int); 94 int pfctl_show_timeouts(int, int); 95 int pfctl_show_limits(int, int); 96 void pfctl_debug(int, u_int32_t, int); 97 int pfctl_show_anchors(int, int, char *); 98 int pfctl_ruleset_trans(struct pfctl *, char *, struct pf_anchor *); 99 u_int pfctl_find_childqs(struct pfctl_qsitem *); 100 void pfctl_load_queue(struct pfctl *, u_int32_t, struct pfctl_qsitem *); 101 int pfctl_load_queues(struct pfctl *); 102 u_int pfctl_leafqueue_check(char *); 103 u_int pfctl_check_qassignments(struct pf_ruleset *); 104 int pfctl_load_ruleset(struct pfctl *, char *, struct pf_ruleset *, int); 105 int pfctl_load_rule(struct pfctl *, char *, struct pf_rule *, int); 106 const char *pfctl_lookup_option(char *, const char **); 107 void pfctl_state_store(int, const char *); 108 void pfctl_state_load(int, const char *); 109 void pfctl_reset(int, int); 110 int pfctl_walk_show(int, struct pfioc_ruleset *, void *); 111 int pfctl_walk_get(int, struct pfioc_ruleset *, void *); 112 int pfctl_walk_anchors(int, int, const char *, 113 int(*)(int, struct pfioc_ruleset *, void *), void *); 114 struct pfr_anchors * 115 pfctl_get_anchors(int, const char *, int); 116 int pfctl_recurse(int, int, const char *, 117 int(*)(int, int, struct pfr_anchoritem *)); 118 int pfctl_call_clearrules(int, int, struct pfr_anchoritem *); 119 int pfctl_call_cleartables(int, int, struct pfr_anchoritem *); 120 int pfctl_call_clearanchors(int, int, struct pfr_anchoritem *); 121 122 const char *clearopt; 123 char *rulesopt; 124 const char *showopt; 125 const char *debugopt; 126 char *anchoropt; 127 const char *optiopt = NULL; 128 char *pf_device = "/dev/pf"; 129 char *ifaceopt; 130 char *tableopt; 131 const char *tblcmdopt; 132 int src_node_killers; 133 char *src_node_kill[2]; 134 int state_killers; 135 char *state_kill[2]; 136 137 int dev = -1; 138 int first_title = 1; 139 int labels = 0; 140 int exit_val = 0; 141 142 #define INDENT(d, o) do { \ 143 if (o) { \ 144 int i; \ 145 for (i=0; i < d; i++) \ 146 printf(" "); \ 147 } \ 148 } while (0) \ 149 150 151 static const struct { 152 const char *name; 153 int index; 154 } pf_limits[] = { 155 { "states", PF_LIMIT_STATES }, 156 { "src-nodes", PF_LIMIT_SRC_NODES }, 157 { "frags", PF_LIMIT_FRAGS }, 158 { "tables", PF_LIMIT_TABLES }, 159 { "table-entries", PF_LIMIT_TABLE_ENTRIES }, 160 { "pktdelay-pkts", PF_LIMIT_PKTDELAY_PKTS }, 161 { NULL, 0 } 162 }; 163 164 struct pf_hint { 165 const char *name; 166 int timeout; 167 }; 168 static const struct pf_hint pf_hint_normal[] = { 169 { "tcp.first", 2 * 60 }, 170 { "tcp.opening", 30 }, 171 { "tcp.established", 24 * 60 * 60 }, 172 { "tcp.closing", 15 * 60 }, 173 { "tcp.finwait", 45 }, 174 { "tcp.closed", 90 }, 175 { "tcp.tsdiff", 30 }, 176 { NULL, 0 } 177 }; 178 static const struct pf_hint pf_hint_satellite[] = { 179 { "tcp.first", 3 * 60 }, 180 { "tcp.opening", 30 + 5 }, 181 { "tcp.established", 24 * 60 * 60 }, 182 { "tcp.closing", 15 * 60 + 5 }, 183 { "tcp.finwait", 45 + 5 }, 184 { "tcp.closed", 90 + 5 }, 185 { "tcp.tsdiff", 60 }, 186 { NULL, 0 } 187 }; 188 static const struct pf_hint pf_hint_conservative[] = { 189 { "tcp.first", 60 * 60 }, 190 { "tcp.opening", 15 * 60 }, 191 { "tcp.established", 5 * 24 * 60 * 60 }, 192 { "tcp.closing", 60 * 60 }, 193 { "tcp.finwait", 10 * 60 }, 194 { "tcp.closed", 3 * 60 }, 195 { "tcp.tsdiff", 60 }, 196 { NULL, 0 } 197 }; 198 static const struct pf_hint pf_hint_aggressive[] = { 199 { "tcp.first", 30 }, 200 { "tcp.opening", 5 }, 201 { "tcp.established", 5 * 60 * 60 }, 202 { "tcp.closing", 60 }, 203 { "tcp.finwait", 30 }, 204 { "tcp.closed", 30 }, 205 { "tcp.tsdiff", 10 }, 206 { NULL, 0 } 207 }; 208 209 static const struct { 210 const char *name; 211 const struct pf_hint *hint; 212 } pf_hints[] = { 213 { "normal", pf_hint_normal }, 214 { "satellite", pf_hint_satellite }, 215 { "high-latency", pf_hint_satellite }, 216 { "conservative", pf_hint_conservative }, 217 { "aggressive", pf_hint_aggressive }, 218 { NULL, NULL } 219 }; 220 221 static const char *clearopt_list[] = { 222 "rules", "Sources", "states", "info", "Tables", "osfp", "Reset", 223 "all", NULL 224 }; 225 226 static const char *showopt_list[] = { 227 "queue", "rules", "Anchors", "Sources", "states", "info", 228 "Interfaces", "labels", "timeouts", "memory", "Tables", "osfp", 229 "all", NULL 230 }; 231 232 static const char *tblcmdopt_list[] = { 233 "kill", "flush", "add", "delete", "replace", "show", 234 "test", "zero", "expire", NULL 235 }; 236 237 static const char *debugopt_list[] = { 238 "debug", "info", "notice", "warning", 239 "error", "crit", "alert", "emerg", 240 NULL 241 }; 242 243 static const char *optiopt_list[] = { 244 "none", "basic", "profile", NULL 245 }; 246 247 struct pf_qihead qspecs = TAILQ_HEAD_INITIALIZER(qspecs); 248 struct pf_qihead rootqs = TAILQ_HEAD_INITIALIZER(rootqs); 249 250 __dead void 251 usage(void) 252 { 253 extern char *__progname; 254 255 fprintf(stderr, "usage: %s [-deghNnPqrvz] ", __progname); 256 fprintf(stderr, "[-a anchor] [-D macro=value] [-F modifier]"); 257 fprintf(stderr, " [-f file]\n"); 258 fprintf(stderr, "\t[-i interface] [-K key] [-k key] [-L statefile]"); 259 fprintf(stderr, " [-o level]\n"); 260 fprintf(stderr, "\t[-p device] [-S statefile] [-s modifier [-R id]]\n"); 261 fprintf(stderr, "\t[-t table -T command [address ...]]"); 262 fprintf(stderr, " [-V rdomain] [-x level]\n"); 263 exit(1); 264 } 265 266 void 267 pfctl_err(int opts, int eval, const char *fmt, ...) 268 { 269 va_list ap; 270 271 va_start(ap, fmt); 272 273 if ((opts & PF_OPT_IGNFAIL) == 0) 274 verr(eval, fmt, ap); 275 else 276 vwarn(fmt, ap); 277 278 va_end(ap); 279 280 exit_val = eval; 281 } 282 283 void 284 pfctl_errx(int opts, int eval, const char *fmt, ...) 285 { 286 va_list ap; 287 288 va_start(ap, fmt); 289 290 if ((opts & PF_OPT_IGNFAIL) == 0) 291 verrx(eval, fmt, ap); 292 else 293 vwarnx(fmt, ap); 294 295 va_end(ap); 296 297 exit_val = eval; 298 } 299 300 int 301 pfctl_enable(int dev, int opts) 302 { 303 if (ioctl(dev, DIOCSTART) == -1) { 304 if (errno == EEXIST) 305 errx(1, "pf already enabled"); 306 else 307 err(1, "DIOCSTART"); 308 } 309 if ((opts & PF_OPT_QUIET) == 0) 310 fprintf(stderr, "pf enabled\n"); 311 312 return (0); 313 } 314 315 int 316 pfctl_disable(int dev, int opts) 317 { 318 if (ioctl(dev, DIOCSTOP) == -1) { 319 if (errno == ENOENT) 320 errx(1, "pf not enabled"); 321 else 322 err(1, "DIOCSTOP"); 323 } 324 if ((opts & PF_OPT_QUIET) == 0) 325 fprintf(stderr, "pf disabled\n"); 326 327 return (0); 328 } 329 330 void 331 pfctl_clear_stats(int dev, const char *iface, int opts) 332 { 333 struct pfioc_iface pi; 334 335 memset(&pi, 0, sizeof(pi)); 336 if (iface != NULL && strlcpy(pi.pfiio_name, iface, 337 sizeof(pi.pfiio_name)) >= sizeof(pi.pfiio_name)) 338 pfctl_errx(opts, 1, "invalid interface: %s", iface); 339 340 if (ioctl(dev, DIOCCLRSTATUS, &pi) == -1) 341 pfctl_err(opts, 1, "DIOCCLRSTATUS"); 342 if ((opts & PF_OPT_QUIET) == 0) { 343 fprintf(stderr, "pf: statistics cleared"); 344 if (iface != NULL) 345 fprintf(stderr, " for interface %s", iface); 346 fprintf(stderr, "\n"); 347 } 348 } 349 350 void 351 pfctl_clear_interface_flags(int dev, int opts) 352 { 353 struct pfioc_iface pi; 354 355 if ((opts & PF_OPT_NOACTION) == 0) { 356 bzero(&pi, sizeof(pi)); 357 pi.pfiio_flags = PFI_IFLAG_SKIP; 358 359 if (ioctl(dev, DIOCCLRIFFLAG, &pi) == -1) 360 pfctl_err(opts, 1, "DIOCCLRIFFLAG"); 361 if ((opts & PF_OPT_QUIET) == 0) 362 fprintf(stderr, "pf: interface flags reset\n"); 363 } 364 } 365 366 int 367 pfctl_clear_rules(int dev, int opts, char *anchorname) 368 { 369 struct pfr_buffer t; 370 371 memset(&t, 0, sizeof(t)); 372 t.pfrb_type = PFRB_TRANS; 373 if (pfctl_add_trans(&t, PF_TRANS_RULESET, anchorname) || 374 pfctl_trans(dev, &t, DIOCXBEGIN, 0) || 375 pfctl_trans(dev, &t, DIOCXCOMMIT, 0)) { 376 pfctl_err(opts, 1, "%s", __func__); 377 return (1); 378 } else if ((opts & PF_OPT_QUIET) == 0) 379 fprintf(stderr, "rules cleared\n"); 380 381 return (0); 382 } 383 384 void 385 pfctl_clear_src_nodes(int dev, int opts) 386 { 387 if (ioctl(dev, DIOCCLRSRCNODES) == -1) 388 pfctl_err(opts, 1, "DIOCCLRSRCNODES"); 389 if ((opts & PF_OPT_QUIET) == 0) 390 fprintf(stderr, "source tracking entries cleared\n"); 391 } 392 393 void 394 pfctl_clear_states(int dev, const char *iface, int opts) 395 { 396 struct pfioc_state_kill psk; 397 398 memset(&psk, 0, sizeof(psk)); 399 if (iface != NULL && strlcpy(psk.psk_ifname, iface, 400 sizeof(psk.psk_ifname)) >= sizeof(psk.psk_ifname)) 401 pfctl_errx(opts, 1, "invalid interface: %s", iface); 402 403 if (ioctl(dev, DIOCCLRSTATES, &psk) == -1) 404 pfctl_err(opts, 1, "DIOCCLRSTATES"); 405 if ((opts & PF_OPT_QUIET) == 0) 406 fprintf(stderr, "%d states cleared\n", psk.psk_killed); 407 } 408 409 struct addrinfo * 410 pfctl_addrprefix(char *addr, struct pf_addr *mask, int numeric) 411 { 412 char *p; 413 const char *errstr; 414 int prefix, ret_ga, q, r; 415 struct addrinfo hints, *res; 416 417 bzero(&hints, sizeof(hints)); 418 hints.ai_socktype = SOCK_DGRAM; /* dummy */ 419 if (numeric) 420 hints.ai_flags = AI_NUMERICHOST; 421 422 if ((p = strchr(addr, '/')) != NULL) { 423 *p++ = '\0'; 424 /* prefix only with numeric addresses */ 425 hints.ai_flags |= AI_NUMERICHOST; 426 } 427 428 if ((ret_ga = getaddrinfo(addr, NULL, &hints, &res))) { 429 errx(1, "getaddrinfo: %s", gai_strerror(ret_ga)); 430 /* NOTREACHED */ 431 } 432 433 if (p == NULL) 434 return res; 435 436 prefix = strtonum(p, 0, res->ai_family == AF_INET6 ? 128 : 32, &errstr); 437 if (errstr) 438 errx(1, "prefix is %s: %s", errstr, p); 439 440 q = prefix >> 3; 441 r = prefix & 7; 442 switch (res->ai_family) { 443 case AF_INET: 444 bzero(&mask->v4, sizeof(mask->v4)); 445 mask->v4.s_addr = htonl((u_int32_t) 446 (0xffffffffffULL << (32 - prefix))); 447 break; 448 case AF_INET6: 449 bzero(&mask->v6, sizeof(mask->v6)); 450 if (q > 0) 451 memset((void *)&mask->v6, 0xff, q); 452 if (r > 0) 453 *((u_char *)&mask->v6 + q) = 454 (0xff00 >> r) & 0xff; 455 break; 456 } 457 458 return res; 459 } 460 461 void 462 pfctl_kill_src_nodes(int dev, int opts) 463 { 464 struct pfioc_src_node_kill psnk; 465 struct addrinfo *res[2], *resp[2]; 466 struct sockaddr last_src, last_dst; 467 int killed, sources, dests; 468 469 killed = sources = dests = 0; 470 471 memset(&psnk, 0, sizeof(psnk)); 472 memset(&psnk.psnk_src.addr.v.a.mask, 0xff, 473 sizeof(psnk.psnk_src.addr.v.a.mask)); 474 memset(&last_src, 0xff, sizeof(last_src)); 475 memset(&last_dst, 0xff, sizeof(last_dst)); 476 477 res[0] = pfctl_addrprefix(src_node_kill[0], 478 &psnk.psnk_src.addr.v.a.mask, (opts & PF_OPT_NODNS)); 479 480 for (resp[0] = res[0]; resp[0]; resp[0] = resp[0]->ai_next) { 481 if (resp[0]->ai_addr == NULL) 482 continue; 483 /* We get lots of duplicates. Catch the easy ones */ 484 if (memcmp(&last_src, resp[0]->ai_addr, sizeof(last_src)) == 0) 485 continue; 486 last_src = *(struct sockaddr *)resp[0]->ai_addr; 487 488 psnk.psnk_af = resp[0]->ai_family; 489 sources++; 490 491 copy_satopfaddr(&psnk.psnk_src.addr.v.a.addr, resp[0]->ai_addr); 492 493 if (src_node_killers > 1) { 494 dests = 0; 495 memset(&psnk.psnk_dst.addr.v.a.mask, 0xff, 496 sizeof(psnk.psnk_dst.addr.v.a.mask)); 497 memset(&last_dst, 0xff, sizeof(last_dst)); 498 res[1] = pfctl_addrprefix(src_node_kill[1], 499 &psnk.psnk_dst.addr.v.a.mask, 500 (opts & PF_OPT_NODNS)); 501 for (resp[1] = res[1]; resp[1]; 502 resp[1] = resp[1]->ai_next) { 503 if (resp[1]->ai_addr == NULL) 504 continue; 505 if (psnk.psnk_af != resp[1]->ai_family) 506 continue; 507 508 if (memcmp(&last_dst, resp[1]->ai_addr, 509 sizeof(last_dst)) == 0) 510 continue; 511 last_dst = *(struct sockaddr *)resp[1]->ai_addr; 512 513 dests++; 514 515 copy_satopfaddr(&psnk.psnk_src.addr.v.a.addr, 516 resp[1]->ai_addr); 517 518 if (ioctl(dev, DIOCKILLSRCNODES, &psnk) == -1) 519 err(1, "DIOCKILLSRCNODES"); 520 killed += psnk.psnk_killed; 521 } 522 freeaddrinfo(res[1]); 523 } else { 524 if (ioctl(dev, DIOCKILLSRCNODES, &psnk) == -1) 525 err(1, "DIOCKILLSRCNODES"); 526 killed += psnk.psnk_killed; 527 } 528 } 529 530 freeaddrinfo(res[0]); 531 532 if ((opts & PF_OPT_QUIET) == 0) 533 fprintf(stderr, "killed %d src nodes from %d sources and %d " 534 "destinations\n", killed, sources, dests); 535 } 536 537 void 538 pfctl_net_kill_states(int dev, const char *iface, int opts, int rdomain) 539 { 540 struct pfioc_state_kill psk; 541 struct addrinfo *res[2], *resp[2]; 542 struct sockaddr last_src, last_dst; 543 int killed, sources, dests; 544 545 killed = sources = dests = 0; 546 547 memset(&psk, 0, sizeof(psk)); 548 memset(&psk.psk_src.addr.v.a.mask, 0xff, 549 sizeof(psk.psk_src.addr.v.a.mask)); 550 memset(&last_src, 0xff, sizeof(last_src)); 551 memset(&last_dst, 0xff, sizeof(last_dst)); 552 if (iface != NULL && strlcpy(psk.psk_ifname, iface, 553 sizeof(psk.psk_ifname)) >= sizeof(psk.psk_ifname)) 554 errx(1, "invalid interface: %s", iface); 555 556 psk.psk_rdomain = rdomain; 557 558 res[0] = pfctl_addrprefix(state_kill[0], 559 &psk.psk_src.addr.v.a.mask, (opts & PF_OPT_NODNS)); 560 561 for (resp[0] = res[0]; resp[0]; resp[0] = resp[0]->ai_next) { 562 if (resp[0]->ai_addr == NULL) 563 continue; 564 /* We get lots of duplicates. Catch the easy ones */ 565 if (memcmp(&last_src, resp[0]->ai_addr, sizeof(last_src)) == 0) 566 continue; 567 last_src = *(struct sockaddr *)resp[0]->ai_addr; 568 569 psk.psk_af = resp[0]->ai_family; 570 sources++; 571 572 copy_satopfaddr(&psk.psk_src.addr.v.a.addr, resp[0]->ai_addr); 573 574 if (state_killers > 1) { 575 dests = 0; 576 memset(&psk.psk_dst.addr.v.a.mask, 0xff, 577 sizeof(psk.psk_dst.addr.v.a.mask)); 578 memset(&last_dst, 0xff, sizeof(last_dst)); 579 res[1] = pfctl_addrprefix(state_kill[1], 580 &psk.psk_dst.addr.v.a.mask, 581 (opts & PF_OPT_NODNS)); 582 for (resp[1] = res[1]; resp[1]; 583 resp[1] = resp[1]->ai_next) { 584 if (resp[1]->ai_addr == NULL) 585 continue; 586 if (psk.psk_af != resp[1]->ai_family) 587 continue; 588 589 if (memcmp(&last_dst, resp[1]->ai_addr, 590 sizeof(last_dst)) == 0) 591 continue; 592 last_dst = *(struct sockaddr *)resp[1]->ai_addr; 593 594 dests++; 595 596 copy_satopfaddr(&psk.psk_src.addr.v.a.addr, 597 resp[1]->ai_addr); 598 599 if (ioctl(dev, DIOCKILLSTATES, &psk) == -1) 600 err(1, "DIOCKILLSTATES"); 601 killed += psk.psk_killed; 602 } 603 freeaddrinfo(res[1]); 604 } else { 605 if (ioctl(dev, DIOCKILLSTATES, &psk) == -1) 606 err(1, "DIOCKILLSTATES"); 607 killed += psk.psk_killed; 608 } 609 } 610 611 freeaddrinfo(res[0]); 612 613 if ((opts & PF_OPT_QUIET) == 0) 614 fprintf(stderr, "killed %d states from %d sources and %d " 615 "destinations\n", killed, sources, dests); 616 } 617 618 void 619 pfctl_label_kill_states(int dev, const char *iface, int opts, int rdomain) 620 { 621 struct pfioc_state_kill psk; 622 623 if (state_killers != 2 || (strlen(state_kill[1]) == 0)) { 624 warnx("no label specified"); 625 usage(); 626 } 627 memset(&psk, 0, sizeof(psk)); 628 if (iface != NULL && strlcpy(psk.psk_ifname, iface, 629 sizeof(psk.psk_ifname)) >= sizeof(psk.psk_ifname)) 630 errx(1, "invalid interface: %s", iface); 631 632 if (strlcpy(psk.psk_label, state_kill[1], sizeof(psk.psk_label)) >= 633 sizeof(psk.psk_label)) 634 errx(1, "label too long: %s", state_kill[1]); 635 636 psk.psk_rdomain = rdomain; 637 638 if (ioctl(dev, DIOCKILLSTATES, &psk) == -1) 639 err(1, "DIOCKILLSTATES"); 640 641 if ((opts & PF_OPT_QUIET) == 0) 642 fprintf(stderr, "killed %d states\n", psk.psk_killed); 643 } 644 645 void 646 pfctl_id_kill_states(int dev, int opts) 647 { 648 struct pfioc_state_kill psk; 649 650 if (state_killers != 2 || (strlen(state_kill[1]) == 0)) { 651 warnx("no id specified"); 652 usage(); 653 } 654 655 memset(&psk, 0, sizeof(psk)); 656 if ((sscanf(state_kill[1], "%llx/%x", 657 &psk.psk_pfcmp.id, &psk.psk_pfcmp.creatorid)) == 2) 658 HTONL(psk.psk_pfcmp.creatorid); 659 else if ((sscanf(state_kill[1], "%llx", &psk.psk_pfcmp.id)) == 1) { 660 psk.psk_pfcmp.creatorid = 0; 661 } else { 662 warnx("wrong id format specified"); 663 usage(); 664 } 665 if (psk.psk_pfcmp.id == 0) { 666 warnx("cannot kill id 0"); 667 usage(); 668 } 669 670 psk.psk_pfcmp.id = htobe64(psk.psk_pfcmp.id); 671 if (ioctl(dev, DIOCKILLSTATES, &psk) == -1) 672 err(1, "DIOCKILLSTATES"); 673 674 if ((opts & PF_OPT_QUIET) == 0) 675 fprintf(stderr, "killed %d states\n", psk.psk_killed); 676 } 677 678 void 679 pfctl_key_kill_states(int dev, const char *iface, int opts, int rdomain) 680 { 681 struct pfioc_state_kill psk; 682 char *s, *token, *tokens[4]; 683 struct protoent *p; 684 u_int i, sidx, didx; 685 686 if (state_killers != 2 || (strlen(state_kill[1]) == 0)) { 687 warnx("no key specified"); 688 usage(); 689 } 690 memset(&psk, 0, sizeof(psk)); 691 692 if (iface != NULL && strlcpy(psk.psk_ifname, iface, 693 sizeof(psk.psk_ifname)) >= sizeof(psk.psk_ifname)) 694 errx(1, "invalid interface: %s", iface); 695 696 psk.psk_rdomain = rdomain; 697 698 s = strdup(state_kill[1]); 699 if (!s) 700 errx(1, "pfctl_key_kill_states: strdup"); 701 i = 0; 702 while ((token = strsep(&s, " \t")) != NULL) 703 if (*token != '\0') { 704 if (i < 4) 705 tokens[i] = token; 706 i++; 707 } 708 if (i != 4) 709 errx(1, "pfctl_key_kill_states: key must be " 710 "\"protocol host1:port1 direction host2:port2\" format"); 711 712 if ((p = getprotobyname(tokens[0])) == NULL) 713 errx(1, "invalid protocol: %s", tokens[0]); 714 psk.psk_proto = p->p_proto; 715 716 if (strcmp(tokens[2], "->") == 0) { 717 sidx = 1; 718 didx = 3; 719 } else if (strcmp(tokens[2], "<-") == 0) { 720 sidx = 3; 721 didx = 1; 722 } else 723 errx(1, "invalid direction: %s", tokens[2]); 724 725 if (pfctl_parse_host(tokens[sidx], &psk.psk_src) == -1) 726 errx(1, "invalid host: %s", tokens[sidx]); 727 if (pfctl_parse_host(tokens[didx], &psk.psk_dst) == -1) 728 errx(1, "invalid host: %s", tokens[didx]); 729 730 if (ioctl(dev, DIOCKILLSTATES, &psk) == -1) 731 err(1, "DIOCKILLSTATES"); 732 733 if ((opts & PF_OPT_QUIET) == 0) 734 fprintf(stderr, "killed %d states\n", psk.psk_killed); 735 } 736 737 int 738 pfctl_parse_host(char *str, struct pf_rule_addr *addr) 739 { 740 char *s = NULL, *sbs, *sbe; 741 struct addrinfo hints, *ai; 742 743 s = strdup(str); 744 if (!s) 745 errx(1, "pfctl_parse_host: strdup"); 746 747 memset(&hints, 0, sizeof(hints)); 748 hints.ai_socktype = SOCK_DGRAM; /* dummy */ 749 hints.ai_flags = AI_NUMERICHOST; 750 751 if ((sbs = strchr(s, '[')) != NULL && (sbe = strrchr(s, ']')) != NULL) { 752 hints.ai_family = AF_INET6; 753 *(sbs++) = *sbe = '\0'; 754 } else if ((sbs = strchr(s, ':')) != NULL) { 755 hints.ai_family = AF_INET; 756 *(sbs++) = '\0'; 757 } else 758 goto error; 759 760 if (getaddrinfo(s, sbs, &hints, &ai) != 0) 761 goto error; 762 763 copy_satopfaddr(&addr->addr.v.a.addr, ai->ai_addr); 764 addr->port[0] = ai->ai_family == AF_INET6 ? 765 ((struct sockaddr_in6 *)ai->ai_addr)->sin6_port : 766 ((struct sockaddr_in *)ai->ai_addr)->sin_port; 767 768 freeaddrinfo(ai); 769 free(s); 770 771 memset(&addr->addr.v.a.mask, 0xff, sizeof(struct pf_addr)); 772 addr->port_op = PF_OP_EQ; 773 addr->addr.type = PF_ADDR_ADDRMASK; 774 775 return (0); 776 777 error: 778 free(s); 779 return (-1); 780 } 781 782 void 783 pfctl_print_rule_counters(struct pf_rule *rule, int opts) 784 { 785 if (opts & PF_OPT_DEBUG) { 786 const char *t[PF_SKIP_COUNT] = { "i", "d", "r", "f", 787 "p", "sa", "da", "sp", "dp" }; 788 int i; 789 790 printf(" [ Skip steps: "); 791 for (i = 0; i < PF_SKIP_COUNT; ++i) { 792 if (rule->skip[i].nr == rule->nr + 1) 793 continue; 794 printf("%s=", t[i]); 795 if (rule->skip[i].nr == -1) 796 printf("end "); 797 else 798 printf("%u ", rule->skip[i].nr); 799 } 800 printf("]\n"); 801 802 printf(" [ queue: qname=%s qid=%u pqname=%s pqid=%u ]\n", 803 rule->qname, rule->qid, rule->pqname, rule->pqid); 804 } 805 if (opts & PF_OPT_VERBOSE) { 806 printf(" [ Evaluations: %-8llu Packets: %-8llu " 807 "Bytes: %-10llu States: %-6u]\n", 808 (unsigned long long)rule->evaluations, 809 (unsigned long long)(rule->packets[0] + 810 rule->packets[1]), 811 (unsigned long long)(rule->bytes[0] + 812 rule->bytes[1]), rule->states_cur); 813 if (!(opts & PF_OPT_DEBUG)) 814 printf(" [ Inserted: uid %lu pid %lu " 815 "State Creations: %-6u]\n", 816 (unsigned long)rule->cuid, (unsigned long)rule->cpid, 817 rule->states_tot); 818 } 819 } 820 821 void 822 pfctl_print_title(char *title) 823 { 824 if (!first_title) 825 printf("\n"); 826 first_title = 0; 827 printf("%s\n", title); 828 } 829 830 int 831 pfctl_show_rules(int dev, char *path, int opts, enum pfctl_show format, 832 char *anchorname, int depth, int wildcard, long shownr) 833 { 834 struct pfioc_rule pr; 835 u_int32_t nr, mnr, header = 0; 836 int len = strlen(path), ret = 0; 837 char *npath, *p; 838 839 /* 840 * Truncate a trailing / and * on an anchorname before searching for 841 * the ruleset, this is syntactic sugar that doesn't actually make it 842 * to the kernel. 843 */ 844 if ((p = strrchr(anchorname, '/')) != NULL && 845 p[1] == '*' && p[2] == '\0') { 846 p[0] = '\0'; 847 } 848 849 memset(&pr, 0, sizeof(pr)); 850 if (anchorname[0] == '/') { 851 if ((npath = calloc(1, PATH_MAX)) == NULL) 852 err(1, "calloc"); 853 strlcpy(npath, anchorname, PATH_MAX); 854 } else { 855 if (path[0]) 856 snprintf(&path[len], PATH_MAX - len, "/%s", anchorname); 857 else 858 snprintf(&path[len], PATH_MAX - len, "%s", anchorname); 859 npath = path; 860 } 861 862 memcpy(pr.anchor, npath, sizeof(pr.anchor)); 863 if (opts & PF_OPT_SHOWALL) { 864 pr.rule.action = PF_PASS; 865 if (ioctl(dev, DIOCGETRULES, &pr) == -1) { 866 warnx("%s", pf_strerror(errno)); 867 ret = -1; 868 goto error; 869 } 870 header++; 871 if (format == PFCTL_SHOW_RULES && (pr.nr > 0 || header)) 872 pfctl_print_title("FILTER RULES:"); 873 else if (format == PFCTL_SHOW_LABELS && labels) 874 pfctl_print_title("LABEL COUNTERS:"); 875 } 876 if (opts & PF_OPT_CLRRULECTRS) 877 pr.action = PF_GET_CLR_CNTR; 878 879 pr.rule.action = PF_PASS; 880 if (ioctl(dev, DIOCGETRULES, &pr) == -1) { 881 warnx("%s", pf_strerror(errno)); 882 ret = -1; 883 goto error; 884 } 885 886 if (shownr < 0) { 887 mnr = pr.nr; 888 nr = 0; 889 } else if (shownr < pr.nr) { 890 nr = shownr; 891 mnr = shownr + 1; 892 } else { 893 warnx("rule %ld not found", shownr); 894 ret = -1; 895 goto error; 896 } 897 for (; nr < mnr; ++nr) { 898 pr.nr = nr; 899 if (ioctl(dev, DIOCGETRULE, &pr) == -1) { 900 warn("DIOCGETRULE"); 901 ret = -1; 902 goto error; 903 } 904 905 /* anchor is the same for all rules in it */ 906 if (pr.rule.anchor_wildcard == 0) 907 wildcard = 0; 908 909 switch (format) { 910 case PFCTL_SHOW_LABELS: 911 if (pr.rule.label[0]) { 912 INDENT(depth, !(opts & PF_OPT_VERBOSE)); 913 printf("%s %llu %llu %llu %llu" 914 " %llu %llu %llu %llu\n", 915 pr.rule.label, 916 (unsigned long long)pr.rule.evaluations, 917 (unsigned long long)(pr.rule.packets[0] + 918 pr.rule.packets[1]), 919 (unsigned long long)(pr.rule.bytes[0] + 920 pr.rule.bytes[1]), 921 (unsigned long long)pr.rule.packets[0], 922 (unsigned long long)pr.rule.bytes[0], 923 (unsigned long long)pr.rule.packets[1], 924 (unsigned long long)pr.rule.bytes[1], 925 (unsigned long long)pr.rule.states_tot); 926 } 927 break; 928 case PFCTL_SHOW_RULES: 929 if (pr.rule.label[0] && (opts & PF_OPT_SHOWALL)) 930 labels = 1; 931 INDENT(depth, !(opts & PF_OPT_VERBOSE)); 932 print_rule(&pr.rule, pr.anchor_call, opts); 933 934 /* 935 * If this is an 'unnamed' brace notation anchor OR 936 * the user has explicitly requested recursion, 937 * print it recursively. 938 */ 939 if (pr.anchor_call[0] && 940 (((p = strrchr(pr.anchor_call, '/')) ? 941 p[1] == '_' : pr.anchor_call[0] == '_') || 942 opts & PF_OPT_RECURSE)) { 943 printf(" {\n"); 944 pfctl_print_rule_counters(&pr.rule, opts); 945 pfctl_show_rules(dev, npath, opts, format, 946 pr.anchor_call, depth + 1, 947 pr.rule.anchor_wildcard, -1); 948 INDENT(depth, !(opts & PF_OPT_VERBOSE)); 949 printf("}\n"); 950 } else { 951 printf("\n"); 952 pfctl_print_rule_counters(&pr.rule, opts); 953 } 954 break; 955 case PFCTL_SHOW_NOTHING: 956 break; 957 } 958 } 959 960 /* 961 * If this anchor was called with a wildcard path, go through 962 * the rulesets in the anchor rather than the rules. 963 */ 964 if (wildcard && (opts & PF_OPT_RECURSE)) { 965 struct pfioc_ruleset prs; 966 u_int32_t mnr, nr; 967 968 memset(&prs, 0, sizeof(prs)); 969 memcpy(prs.path, npath, sizeof(prs.path)); 970 if (ioctl(dev, DIOCGETRULESETS, &prs) == -1) 971 errx(1, "%s", pf_strerror(errno)); 972 mnr = prs.nr; 973 974 for (nr = 0; nr < mnr; ++nr) { 975 prs.nr = nr; 976 if (ioctl(dev, DIOCGETRULESET, &prs) == -1) 977 errx(1, "%s", pf_strerror(errno)); 978 INDENT(depth, !(opts & PF_OPT_VERBOSE)); 979 printf("anchor \"%s\" all {\n", prs.name); 980 pfctl_show_rules(dev, npath, opts, 981 format, prs.name, depth + 1, 0, shownr); 982 INDENT(depth, !(opts & PF_OPT_VERBOSE)); 983 printf("}\n"); 984 } 985 path[len] = '\0'; 986 return (0); 987 } 988 989 error: 990 if (path != npath) 991 free(npath); 992 path[len] = '\0'; 993 return (ret); 994 } 995 996 int 997 pfctl_show_src_nodes(int dev, int opts) 998 { 999 struct pfioc_src_nodes psn; 1000 struct pf_src_node *p; 1001 char *inbuf = NULL, *newinbuf = NULL; 1002 size_t i, len = 0; 1003 1004 memset(&psn, 0, sizeof(psn)); 1005 for (;;) { 1006 psn.psn_len = len; 1007 if (len) { 1008 newinbuf = realloc(inbuf, len); 1009 if (newinbuf == NULL) 1010 err(1, "realloc"); 1011 psn.psn_buf = inbuf = newinbuf; 1012 } 1013 if (ioctl(dev, DIOCGETSRCNODES, &psn) == -1) { 1014 warn("DIOCGETSRCNODES"); 1015 free(inbuf); 1016 return (-1); 1017 } 1018 if (psn.psn_len + sizeof(struct pfioc_src_nodes) < len) 1019 break; 1020 if (len == 0 && psn.psn_len == 0) 1021 goto done; 1022 if (len == 0 && psn.psn_len != 0) 1023 len = psn.psn_len; 1024 if (psn.psn_len == 0) 1025 goto done; /* no src_nodes */ 1026 len *= 2; 1027 } 1028 p = psn.psn_src_nodes; 1029 if (psn.psn_len > 0 && (opts & PF_OPT_SHOWALL)) 1030 pfctl_print_title("SOURCE TRACKING NODES:"); 1031 for (i = 0; i < psn.psn_len; i += sizeof(*p)) { 1032 print_src_node(p, opts); 1033 p++; 1034 } 1035 done: 1036 free(inbuf); 1037 return (0); 1038 } 1039 1040 int 1041 pfctl_show_states(int dev, const char *iface, int opts, long shownr) 1042 { 1043 struct pfioc_states ps; 1044 struct pfsync_state *p; 1045 char *inbuf = NULL, *newinbuf = NULL; 1046 size_t i, len = 0; 1047 int dotitle = (opts & PF_OPT_SHOWALL); 1048 1049 memset(&ps, 0, sizeof(ps)); 1050 for (;;) { 1051 ps.ps_len = len; 1052 if (len) { 1053 newinbuf = realloc(inbuf, len); 1054 if (newinbuf == NULL) 1055 err(1, "realloc"); 1056 ps.ps_buf = inbuf = newinbuf; 1057 } 1058 if (ioctl(dev, DIOCGETSTATES, &ps) == -1) { 1059 warn("DIOCGETSTATES"); 1060 free(inbuf); 1061 return (-1); 1062 } 1063 if (ps.ps_len + sizeof(struct pfioc_states) < len) 1064 break; 1065 if (len == 0 && ps.ps_len == 0) 1066 goto done; 1067 if (len == 0 && ps.ps_len != 0) 1068 len = ps.ps_len; 1069 if (ps.ps_len == 0) 1070 goto done; /* no states */ 1071 len *= 2; 1072 } 1073 p = ps.ps_states; 1074 for (i = 0; i < ps.ps_len; i += sizeof(*p), p++) { 1075 if (iface != NULL && strcmp(p->ifname, iface)) 1076 continue; 1077 if (dotitle) { 1078 pfctl_print_title("STATES:"); 1079 dotitle = 0; 1080 } 1081 if (shownr < 0 || ntohl(p->rule) == shownr) 1082 print_state(p, opts); 1083 } 1084 done: 1085 free(inbuf); 1086 return (0); 1087 } 1088 1089 int 1090 pfctl_show_status(int dev, int opts) 1091 { 1092 struct pf_status status; 1093 struct pfctl_watermarks wats; 1094 struct pfioc_synflwats iocwats; 1095 1096 if (ioctl(dev, DIOCGETSTATUS, &status) == -1) { 1097 warn("DIOCGETSTATUS"); 1098 return (-1); 1099 } 1100 if (ioctl(dev, DIOCGETSYNFLWATS, &iocwats) == -1) { 1101 warn("DIOCGETSYNFLWATS"); 1102 return (-1); 1103 } 1104 wats.hi = iocwats.hiwat; 1105 wats.lo = iocwats.lowat; 1106 if (opts & PF_OPT_SHOWALL) 1107 pfctl_print_title("INFO:"); 1108 print_status(&status, &wats, opts); 1109 return (0); 1110 } 1111 1112 int 1113 pfctl_show_timeouts(int dev, int opts) 1114 { 1115 struct pfioc_tm pt; 1116 int i; 1117 1118 if (opts & PF_OPT_SHOWALL) 1119 pfctl_print_title("TIMEOUTS:"); 1120 memset(&pt, 0, sizeof(pt)); 1121 for (i = 0; pf_timeouts[i].name; i++) { 1122 pt.timeout = pf_timeouts[i].timeout; 1123 if (ioctl(dev, DIOCGETTIMEOUT, &pt) == -1) 1124 err(1, "DIOCGETTIMEOUT"); 1125 printf("%-20s %10d", pf_timeouts[i].name, pt.seconds); 1126 if (pf_timeouts[i].timeout >= PFTM_ADAPTIVE_START && 1127 pf_timeouts[i].timeout <= PFTM_ADAPTIVE_END) 1128 printf(" states"); 1129 else 1130 printf("s"); 1131 printf("\n"); 1132 } 1133 return (0); 1134 1135 } 1136 1137 int 1138 pfctl_show_limits(int dev, int opts) 1139 { 1140 struct pfioc_limit pl; 1141 int i; 1142 1143 if (opts & PF_OPT_SHOWALL) 1144 pfctl_print_title("LIMITS:"); 1145 memset(&pl, 0, sizeof(pl)); 1146 for (i = 0; pf_limits[i].name; i++) { 1147 pl.index = pf_limits[i].index; 1148 if (ioctl(dev, DIOCGETLIMIT, &pl) == -1) 1149 err(1, "DIOCGETLIMIT"); 1150 printf("%-13s ", pf_limits[i].name); 1151 if (pl.limit == UINT_MAX) 1152 printf("unlimited\n"); 1153 else 1154 printf("hard limit %8u\n", pl.limit); 1155 } 1156 return (0); 1157 } 1158 1159 /* callbacks for rule/nat/rdr/addr */ 1160 void 1161 pfctl_add_rule(struct pfctl *pf, struct pf_rule *r) 1162 { 1163 struct pf_rule *rule; 1164 struct pf_ruleset *rs; 1165 1166 rs = &pf->anchor->ruleset; 1167 1168 if ((rule = calloc(1, sizeof(*rule))) == NULL) 1169 err(1, "calloc"); 1170 bcopy(r, rule, sizeof(*rule)); 1171 1172 TAILQ_INSERT_TAIL(rs->rules.active.ptr, rule, entries); 1173 } 1174 1175 int 1176 pfctl_ruleset_trans(struct pfctl *pf, char *path, struct pf_anchor *a) 1177 { 1178 int osize = pf->trans->pfrb_size; 1179 1180 if (pfctl_add_trans(pf->trans, PF_TRANS_RULESET, path)) 1181 return (3); 1182 if (pfctl_add_trans(pf->trans, PF_TRANS_TABLE, path)) 1183 return (4); 1184 if (pfctl_trans(pf->dev, pf->trans, DIOCXBEGIN, osize)) 1185 return (5); 1186 1187 return (0); 1188 } 1189 1190 int 1191 pfctl_add_queue(struct pfctl *pf, struct pf_queuespec *q) 1192 { 1193 struct pfctl_qsitem *qi; 1194 1195 if (pf->anchor->name[0]) { 1196 printf("must not have queue definitions in an anchor\n"); 1197 return (1); 1198 } 1199 1200 if (q->parent[0] == '\0') { 1201 TAILQ_FOREACH(qi, &rootqs, entries) { 1202 if (strcmp(q->ifname, qi->qs.ifname)) 1203 continue; 1204 printf("A root queue is already defined on %s\n", 1205 qi->qs.ifname); 1206 return (1); 1207 } 1208 } 1209 1210 if ((qi = calloc(1, sizeof(*qi))) == NULL) 1211 err(1, "calloc"); 1212 bcopy(q, &qi->qs, sizeof(qi->qs)); 1213 TAILQ_INIT(&qi->children); 1214 1215 if (qi->qs.parent[0]) 1216 TAILQ_INSERT_TAIL(&qspecs, qi, entries); 1217 else 1218 TAILQ_INSERT_TAIL(&rootqs, qi, entries); 1219 1220 return (0); 1221 } 1222 1223 struct pfctl_qsitem * 1224 pfctl_find_queue(char *what, struct pf_qihead *where) 1225 { 1226 struct pfctl_qsitem *q; 1227 1228 TAILQ_FOREACH(q, where, entries) 1229 if (strcmp(q->qs.qname, what) == 0) 1230 return (q); 1231 1232 return (NULL); 1233 } 1234 1235 u_int 1236 pfctl_find_childqs(struct pfctl_qsitem *qi) 1237 { 1238 struct pfctl_qsitem *n, *p, *q; 1239 u_int flags = qi->qs.flags; 1240 1241 TAILQ_FOREACH(p, &qspecs, entries) { 1242 if (strcmp(p->qs.parent, qi->qs.qname)) 1243 continue; 1244 if (p->qs.ifname[0] && strcmp(p->qs.ifname, qi->qs.ifname)) 1245 continue; 1246 if (++p->matches > 10000) 1247 errx(1, "pfctl_find_childqs: excessive matches, loop?"); 1248 1249 if ((q = pfctl_find_queue(p->qs.qname, &qi->children)) == NULL) { 1250 /* insert */ 1251 if ((n = calloc(1, sizeof(*n))) == NULL) 1252 err(1, "calloc"); 1253 TAILQ_INIT(&n->children); 1254 bcopy(&p->qs, &n->qs, sizeof(n->qs)); 1255 TAILQ_INSERT_TAIL(&qi->children, n, entries); 1256 } else { 1257 if ((q->qs.ifname[0] && p->qs.ifname[0])) 1258 errx(1, "queue %s on %s respecified", 1259 q->qs.qname, q->qs.ifname); 1260 if (!q->qs.ifname[0] && !p->qs.ifname[0]) 1261 errx(1, "queue %s respecified", 1262 q->qs.qname); 1263 /* ifbound beats floating */ 1264 if (!q->qs.ifname[0]) 1265 bcopy(&p->qs, &q->qs, sizeof(q->qs)); 1266 } 1267 } 1268 1269 TAILQ_FOREACH(p, &qi->children, entries) 1270 flags |= pfctl_find_childqs(p); 1271 1272 if (!TAILQ_EMPTY(&qi->children)) { 1273 if (qi->qs.flags & PFQS_DEFAULT) 1274 errx(1, "default queue %s is not a leaf queue", 1275 qi->qs.qname); 1276 if (qi->qs.flags & PFQS_FLOWQUEUE) 1277 errx(1, "flow queue %s is not a leaf queue", 1278 qi->qs.qname); 1279 } 1280 1281 return (flags); 1282 } 1283 1284 void 1285 pfctl_load_queue(struct pfctl *pf, u_int32_t ticket, struct pfctl_qsitem *qi) 1286 { 1287 struct pfioc_queue q; 1288 struct pfctl_qsitem *p; 1289 1290 q.ticket = ticket; 1291 bcopy(&qi->qs, &q.queue, sizeof(q.queue)); 1292 if ((pf->opts & PF_OPT_NOACTION) == 0) 1293 if (ioctl(pf->dev, DIOCADDQUEUE, &q) == -1) 1294 err(1, "DIOCADDQUEUE"); 1295 if (pf->opts & PF_OPT_VERBOSE) 1296 print_queuespec(&qi->qs); 1297 1298 TAILQ_FOREACH(p, &qi->children, entries) { 1299 strlcpy(p->qs.ifname, qi->qs.ifname, IFNAMSIZ); 1300 pfctl_load_queue(pf, ticket, p); 1301 } 1302 } 1303 1304 int 1305 pfctl_load_queues(struct pfctl *pf) 1306 { 1307 struct pfctl_qsitem *qi, *tempqi; 1308 struct pf_queue_scspec *rtsc, *lssc, *ulsc; 1309 u_int32_t ticket; 1310 1311 TAILQ_FOREACH(qi, &qspecs, entries) { 1312 if (qi->matches == 0) 1313 errx(1, "queue %s: parent %s not found", qi->qs.qname, 1314 qi->qs.parent); 1315 1316 rtsc = &qi->qs.realtime; 1317 lssc = &qi->qs.linkshare; 1318 ulsc = &qi->qs.upperlimit; 1319 1320 if (rtsc->m1.percent || rtsc->m2.percent || 1321 lssc->m1.percent || lssc->m2.percent || 1322 ulsc->m1.percent || ulsc->m2.percent) 1323 errx(1, "only absolute bandwidth specs for now"); 1324 1325 /* Link sharing policy must be specified for child classes */ 1326 if (qi->qs.parent[0] != '\0' && 1327 lssc->m1.absolute == 0 && lssc->m2.absolute == 0) 1328 errx(1, "queue %s: no bandwidth was specified", 1329 qi->qs.qname); 1330 } 1331 1332 if ((pf->opts & PF_OPT_NOACTION) == 0) 1333 ticket = pfctl_get_ticket(pf->trans, PF_TRANS_RULESET, ""); 1334 1335 TAILQ_FOREACH_SAFE(qi, &rootqs, entries, tempqi) { 1336 TAILQ_REMOVE(&rootqs, qi, entries); 1337 pfctl_load_queue(pf, ticket, qi); 1338 TAILQ_INSERT_HEAD(&rootqs, qi, entries); 1339 } 1340 1341 return (0); 1342 } 1343 1344 void 1345 pfctl_clear_queues(struct pf_qihead *head) 1346 { 1347 struct pfctl_qsitem *qi; 1348 1349 while ((qi = TAILQ_FIRST(head)) != NULL) { 1350 TAILQ_REMOVE(head, qi, entries); 1351 pfctl_clear_queues(&qi->children); 1352 free(qi); 1353 } 1354 } 1355 1356 u_int 1357 pfctl_leafqueue_check(char *qname) 1358 { 1359 struct pfctl_qsitem *qi; 1360 if (qname == NULL || qname[0] == 0) 1361 return (0); 1362 1363 TAILQ_FOREACH(qi, &rootqs, entries) { 1364 if (strcmp(qname, qi->qs.qname)) 1365 continue; 1366 if (!TAILQ_EMPTY(&qi->children)) { 1367 printf("queue %s: packets must be assigned to leaf " 1368 "queues only\n", qname); 1369 return (1); 1370 } 1371 } 1372 TAILQ_FOREACH(qi, &qspecs, entries) { 1373 if (strcmp(qname, qi->qs.qname)) 1374 continue; 1375 if (!TAILQ_EMPTY(&qi->children)) { 1376 printf("queue %s: packets must be assigned to leaf " 1377 "queues only\n", qname); 1378 return (1); 1379 } 1380 } 1381 return (0); 1382 } 1383 1384 u_int 1385 pfctl_check_qassignments(struct pf_ruleset *rs) 1386 { 1387 struct pf_rule *r; 1388 struct pfctl_qsitem *qi; 1389 u_int flags, errs = 0; 1390 1391 /* main ruleset: need find_childqs to populate qi->children */ 1392 if (rs->anchor->path[0] == 0) { 1393 TAILQ_FOREACH(qi, &rootqs, entries) { 1394 flags = pfctl_find_childqs(qi); 1395 if (!(qi->qs.flags & PFQS_ROOTCLASS) && 1396 !TAILQ_EMPTY(&qi->children)) { 1397 if (qi->qs.flags & PFQS_FLOWQUEUE) 1398 errx(1, "root queue %s doesn't " 1399 "support hierarchy", 1400 qi->qs.qname); 1401 else 1402 errx(1, "no bandwidth was specified " 1403 "for root queue %s", qi->qs.qname); 1404 } 1405 if ((qi->qs.flags & PFQS_ROOTCLASS) && 1406 !(flags & PFQS_DEFAULT)) 1407 errx(1, "no default queue specified"); 1408 } 1409 } 1410 1411 TAILQ_FOREACH(r, rs->rules.active.ptr, entries) { 1412 if (r->anchor) 1413 errs += pfctl_check_qassignments(&r->anchor->ruleset); 1414 if (pfctl_leafqueue_check(r->qname) || 1415 pfctl_leafqueue_check(r->pqname)) 1416 errs++; 1417 } 1418 return (errs); 1419 } 1420 1421 int 1422 pfctl_load_ruleset(struct pfctl *pf, char *path, struct pf_ruleset *rs, 1423 int depth) 1424 { 1425 struct pf_rule *r; 1426 int error, len = strlen(path); 1427 int brace = 0; 1428 1429 pf->anchor = rs->anchor; 1430 1431 if (path[0]) 1432 snprintf(&path[len], PATH_MAX - len, "/%s", pf->anchor->name); 1433 else 1434 snprintf(&path[len], PATH_MAX - len, "%s", pf->anchor->path); 1435 1436 if (depth) { 1437 if (TAILQ_FIRST(rs->rules.active.ptr) != NULL) { 1438 brace++; 1439 if (pf->opts & PF_OPT_VERBOSE) 1440 printf(" {\n"); 1441 if ((pf->opts & PF_OPT_NOACTION) == 0 && 1442 (error = pfctl_ruleset_trans(pf, 1443 path, rs->anchor))) { 1444 printf("pfctl_load_ruleset: " 1445 "pfctl_ruleset_trans %d\n", error); 1446 goto error; 1447 } 1448 } else if (pf->opts & PF_OPT_VERBOSE) 1449 printf("\n"); 1450 } 1451 1452 if (pf->optimize) 1453 pfctl_optimize_ruleset(pf, rs); 1454 1455 while ((r = TAILQ_FIRST(rs->rules.active.ptr)) != NULL) { 1456 TAILQ_REMOVE(rs->rules.active.ptr, r, entries); 1457 if ((error = pfctl_load_rule(pf, path, r, depth))) 1458 goto error; 1459 if (r->anchor) { 1460 if ((error = pfctl_load_ruleset(pf, path, 1461 &r->anchor->ruleset, depth + 1))) 1462 goto error; 1463 } else if (pf->opts & PF_OPT_VERBOSE) 1464 printf("\n"); 1465 free(r); 1466 } 1467 if (brace && pf->opts & PF_OPT_VERBOSE) { 1468 INDENT(depth - 1, (pf->opts & PF_OPT_VERBOSE)); 1469 printf("}\n"); 1470 } 1471 path[len] = '\0'; 1472 return (0); 1473 1474 error: 1475 path[len] = '\0'; 1476 return (error); 1477 1478 } 1479 1480 int 1481 pfctl_load_rule(struct pfctl *pf, char *path, struct pf_rule *r, int depth) 1482 { 1483 char *name; 1484 struct pfioc_rule pr; 1485 int len = strlen(path); 1486 1487 bzero(&pr, sizeof(pr)); 1488 /* set up anchor before adding to path for anchor_call */ 1489 if ((pf->opts & PF_OPT_NOACTION) == 0) 1490 pr.ticket = pfctl_get_ticket(pf->trans, PF_TRANS_RULESET, path); 1491 if (strlcpy(pr.anchor, path, sizeof(pr.anchor)) >= sizeof(pr.anchor)) 1492 errx(1, "pfctl_load_rule: strlcpy"); 1493 1494 if (r->anchor) { 1495 if (r->anchor->match) { 1496 if (path[0]) 1497 snprintf(&path[len], PATH_MAX - len, 1498 "/%s", r->anchor->name); 1499 else 1500 snprintf(&path[len], PATH_MAX - len, 1501 "%s", r->anchor->name); 1502 name = r->anchor->name; 1503 } else 1504 name = r->anchor->path; 1505 } else 1506 name = ""; 1507 1508 if ((pf->opts & PF_OPT_NOACTION) == 0) { 1509 memcpy(&pr.rule, r, sizeof(pr.rule)); 1510 if (r->anchor && strlcpy(pr.anchor_call, name, 1511 sizeof(pr.anchor_call)) >= sizeof(pr.anchor_call)) 1512 errx(1, "pfctl_load_rule: strlcpy"); 1513 if (ioctl(pf->dev, DIOCADDRULE, &pr) == -1) 1514 err(1, "DIOCADDRULE"); 1515 } 1516 1517 if (pf->opts & PF_OPT_VERBOSE) { 1518 INDENT(depth, !(pf->opts & PF_OPT_VERBOSE2)); 1519 print_rule(r, name, pf->opts); 1520 } 1521 path[len] = '\0'; 1522 return (0); 1523 } 1524 1525 int 1526 pfctl_rules(int dev, char *filename, int opts, int optimize, 1527 char *anchorname, struct pfr_buffer *trans) 1528 { 1529 #define ERR(x) do { warn(x); goto _error; } while(0) 1530 #define ERRX(x) do { warnx(x); goto _error; } while(0) 1531 1532 struct pfr_buffer *t, buf; 1533 struct pfctl pf; 1534 struct pf_ruleset *rs; 1535 struct pfr_table trs; 1536 char *path = NULL; 1537 int osize; 1538 char *p; 1539 1540 bzero(&pf, sizeof(pf)); 1541 RB_INIT(&pf_anchors); 1542 memset(&pf_main_anchor, 0, sizeof(pf_main_anchor)); 1543 pf_init_ruleset(&pf_main_anchor.ruleset); 1544 if (trans == NULL) { 1545 bzero(&buf, sizeof(buf)); 1546 buf.pfrb_type = PFRB_TRANS; 1547 t = &buf; 1548 osize = 0; 1549 } else { 1550 t = trans; 1551 osize = t->pfrb_size; 1552 } 1553 1554 memset(&pf, 0, sizeof(pf)); 1555 memset(&trs, 0, sizeof(trs)); 1556 if ((path = calloc(1, PATH_MAX)) == NULL) 1557 ERRX("pfctl_rules: calloc"); 1558 if (strlcpy(trs.pfrt_anchor, anchorname, 1559 sizeof(trs.pfrt_anchor)) >= sizeof(trs.pfrt_anchor)) 1560 ERRX("pfctl_rules: strlcpy"); 1561 pf.dev = dev; 1562 pf.opts = opts; 1563 pf.optimize = optimize; 1564 1565 /* non-brace anchor, create without resolving the path */ 1566 if ((pf.anchor = calloc(1, sizeof(*pf.anchor))) == NULL) 1567 ERRX("pfctl_rules: calloc"); 1568 rs = &pf.anchor->ruleset; 1569 pf_init_ruleset(rs); 1570 rs->anchor = pf.anchor; 1571 if (strlcpy(pf.anchor->path, anchorname, 1572 sizeof(pf.anchor->path)) >= sizeof(pf.anchor->path)) 1573 errx(1, "%s: strlcpy", __func__); 1574 1575 if ((p = strrchr(anchorname, '/')) != NULL) { 1576 if (strlen(p) == 1) 1577 errx(1, "%s: bad anchor name %s", __func__, anchorname); 1578 } else 1579 p = anchorname; 1580 1581 if (strlcpy(pf.anchor->name, p, 1582 sizeof(pf.anchor->name)) >= sizeof(pf.anchor->name)) 1583 errx(1, "%s: strlcpy", __func__); 1584 1585 pf.astack[0] = pf.anchor; 1586 pf.asd = 0; 1587 pf.trans = t; 1588 pfctl_init_options(&pf); 1589 1590 if ((opts & PF_OPT_NOACTION) == 0) { 1591 /* 1592 * XXX For the time being we need to open transactions for 1593 * the main ruleset before parsing, because tables are still 1594 * loaded at parse time. 1595 */ 1596 if (pfctl_ruleset_trans(&pf, anchorname, pf.anchor)) 1597 ERRX("pfctl_rules"); 1598 pf.astack[0]->ruleset.tticket = 1599 pfctl_get_ticket(t, PF_TRANS_TABLE, anchorname); 1600 } 1601 1602 if (parse_config(filename, &pf) < 0) { 1603 if ((opts & PF_OPT_NOACTION) == 0) 1604 ERRX("Syntax error in config file: " 1605 "pf rules not loaded"); 1606 else 1607 goto _error; 1608 } 1609 1610 if (!anchorname[0] && (pfctl_check_qassignments(&pf.anchor->ruleset) || 1611 pfctl_load_queues(&pf))) { 1612 if ((opts & PF_OPT_NOACTION) == 0) 1613 ERRX("Unable to load queues into kernel"); 1614 else 1615 goto _error; 1616 } 1617 1618 if (pfctl_load_ruleset(&pf, path, rs, 0)) { 1619 if ((opts & PF_OPT_NOACTION) == 0) 1620 ERRX("Unable to load rules into kernel"); 1621 else 1622 goto _error; 1623 } 1624 1625 free(path); 1626 path = NULL; 1627 1628 if (trans == NULL) { 1629 /* 1630 * process "load anchor" directives that might have used queues 1631 */ 1632 if (pfctl_load_anchors(dev, &pf, t) == -1) 1633 ERRX("load anchors"); 1634 pfctl_clear_queues(&qspecs); 1635 pfctl_clear_queues(&rootqs); 1636 1637 if ((opts & PF_OPT_NOACTION) == 0) { 1638 if (!anchorname[0] && pfctl_load_options(&pf)) 1639 goto _error; 1640 if (pfctl_trans(dev, t, DIOCXCOMMIT, osize)) 1641 ERR("DIOCXCOMMIT"); 1642 } 1643 } 1644 return (0); 1645 1646 _error: 1647 if (trans == NULL) { /* main ruleset */ 1648 if ((opts & PF_OPT_NOACTION) == 0) 1649 if (pfctl_trans(dev, t, DIOCXROLLBACK, osize)) 1650 err(1, "DIOCXROLLBACK"); 1651 exit(1); 1652 } else { /* sub ruleset */ 1653 free(path); 1654 return (-1); 1655 } 1656 1657 #undef ERR 1658 #undef ERRX 1659 } 1660 1661 FILE * 1662 pfctl_fopen(const char *name, const char *mode) 1663 { 1664 struct stat st; 1665 FILE *fp; 1666 1667 fp = fopen(name, mode); 1668 if (fp == NULL) 1669 return (NULL); 1670 if (fstat(fileno(fp), &st) == -1) { 1671 fclose(fp); 1672 return (NULL); 1673 } 1674 if (S_ISDIR(st.st_mode)) { 1675 fclose(fp); 1676 errno = EISDIR; 1677 return (NULL); 1678 } 1679 return (fp); 1680 } 1681 1682 void 1683 pfctl_init_options(struct pfctl *pf) 1684 { 1685 int64_t mem; 1686 int mib[2], mcl; 1687 size_t size; 1688 1689 pf->timeout[PFTM_TCP_FIRST_PACKET] = PFTM_TCP_FIRST_PACKET_VAL; 1690 pf->timeout[PFTM_TCP_OPENING] = PFTM_TCP_OPENING_VAL; 1691 pf->timeout[PFTM_TCP_ESTABLISHED] = PFTM_TCP_ESTABLISHED_VAL; 1692 pf->timeout[PFTM_TCP_CLOSING] = PFTM_TCP_CLOSING_VAL; 1693 pf->timeout[PFTM_TCP_FIN_WAIT] = PFTM_TCP_FIN_WAIT_VAL; 1694 pf->timeout[PFTM_TCP_CLOSED] = PFTM_TCP_CLOSED_VAL; 1695 pf->timeout[PFTM_UDP_FIRST_PACKET] = PFTM_UDP_FIRST_PACKET_VAL; 1696 pf->timeout[PFTM_UDP_SINGLE] = PFTM_UDP_SINGLE_VAL; 1697 pf->timeout[PFTM_UDP_MULTIPLE] = PFTM_UDP_MULTIPLE_VAL; 1698 pf->timeout[PFTM_ICMP_FIRST_PACKET] = PFTM_ICMP_FIRST_PACKET_VAL; 1699 pf->timeout[PFTM_ICMP_ERROR_REPLY] = PFTM_ICMP_ERROR_REPLY_VAL; 1700 pf->timeout[PFTM_OTHER_FIRST_PACKET] = PFTM_OTHER_FIRST_PACKET_VAL; 1701 pf->timeout[PFTM_OTHER_SINGLE] = PFTM_OTHER_SINGLE_VAL; 1702 pf->timeout[PFTM_OTHER_MULTIPLE] = PFTM_OTHER_MULTIPLE_VAL; 1703 pf->timeout[PFTM_FRAG] = PFTM_FRAG_VAL; 1704 pf->timeout[PFTM_INTERVAL] = PFTM_INTERVAL_VAL; 1705 pf->timeout[PFTM_SRC_NODE] = PFTM_SRC_NODE_VAL; 1706 pf->timeout[PFTM_TS_DIFF] = PFTM_TS_DIFF_VAL; 1707 pf->timeout[PFTM_ADAPTIVE_START] = PFSTATE_ADAPT_START; 1708 pf->timeout[PFTM_ADAPTIVE_END] = PFSTATE_ADAPT_END; 1709 1710 pf->limit[PF_LIMIT_STATES] = PFSTATE_HIWAT; 1711 1712 pf->syncookieswat[0] = PF_SYNCOOKIES_LOWATPCT; 1713 pf->syncookieswat[1] = PF_SYNCOOKIES_HIWATPCT; 1714 1715 mib[0] = CTL_KERN; 1716 mib[1] = KERN_MAXCLUSTERS; 1717 size = sizeof(mcl); 1718 if (sysctl(mib, 2, &mcl, &size, NULL, 0) == -1) 1719 err(1, "sysctl"); 1720 pf->limit[PF_LIMIT_FRAGS] = mcl / 4; 1721 1722 pf->limit[PF_LIMIT_SRC_NODES] = PFSNODE_HIWAT; 1723 pf->limit[PF_LIMIT_TABLES] = PFR_KTABLE_HIWAT; 1724 pf->limit[PF_LIMIT_TABLE_ENTRIES] = PFR_KENTRY_HIWAT; 1725 pf->limit[PF_LIMIT_PKTDELAY_PKTS] = PF_PKTDELAY_MAXPKTS; 1726 1727 mib[0] = CTL_HW; 1728 mib[1] = HW_PHYSMEM64; 1729 size = sizeof(mem); 1730 if (sysctl(mib, 2, &mem, &size, NULL, 0) == -1) 1731 err(1, "sysctl"); 1732 if (mem <= 100*1024*1024) 1733 pf->limit[PF_LIMIT_TABLE_ENTRIES] = PFR_KENTRY_HIWAT_SMALL; 1734 1735 pf->debug = LOG_ERR; 1736 pf->debug_set = 0; 1737 pf->reassemble = PF_REASS_ENABLED; 1738 } 1739 1740 int 1741 pfctl_load_options(struct pfctl *pf) 1742 { 1743 int i, error = 0; 1744 1745 /* load limits */ 1746 for (i = 0; i < PF_LIMIT_MAX; i++) 1747 if (pfctl_load_limit(pf, i, pf->limit[i])) 1748 error = 1; 1749 1750 /* 1751 * If we've set the states limit, but haven't explicitly set adaptive 1752 * timeouts, do it now with a start of 60% and end of 120%. 1753 */ 1754 if (pf->limit_set[PF_LIMIT_STATES] && 1755 !pf->timeout_set[PFTM_ADAPTIVE_START] && 1756 !pf->timeout_set[PFTM_ADAPTIVE_END]) { 1757 pf->timeout[PFTM_ADAPTIVE_START] = 1758 (pf->limit[PF_LIMIT_STATES] / 10) * 6; 1759 pf->timeout_set[PFTM_ADAPTIVE_START] = 1; 1760 pf->timeout[PFTM_ADAPTIVE_END] = 1761 (pf->limit[PF_LIMIT_STATES] / 10) * 12; 1762 pf->timeout_set[PFTM_ADAPTIVE_END] = 1; 1763 } 1764 1765 /* load timeouts */ 1766 for (i = 0; i < PFTM_MAX; i++) 1767 if (pfctl_load_timeout(pf, i, pf->timeout[i])) 1768 error = 1; 1769 1770 /* load debug */ 1771 if (pf->debug_set && pfctl_load_debug(pf, pf->debug)) 1772 error = 1; 1773 1774 /* load logif */ 1775 if (pf->ifname_set && pfctl_load_logif(pf, pf->ifname)) 1776 error = 1; 1777 1778 /* load hostid */ 1779 if (pf->hostid_set && pfctl_load_hostid(pf, pf->hostid)) 1780 error = 1; 1781 1782 /* load reassembly settings */ 1783 if (pf->reass_set && pfctl_load_reassembly(pf, pf->reassemble)) 1784 error = 1; 1785 1786 /* load syncookies settings */ 1787 if (pf->syncookies_set && pfctl_load_syncookies(pf, pf->syncookies)) 1788 error = 1; 1789 if (pf->syncookieswat_set) { 1790 struct pfioc_limit pl; 1791 unsigned curlim; 1792 1793 if (pf->limit_set[PF_LIMIT_STATES]) 1794 curlim = pf->limit[PF_LIMIT_STATES]; 1795 else { 1796 memset(&pl, 0, sizeof(pl)); 1797 pl.index = pf_limits[PF_LIMIT_STATES].index; 1798 if (ioctl(dev, DIOCGETLIMIT, &pl) == -1) 1799 err(1, "DIOCGETLIMIT"); 1800 curlim = pl.limit; 1801 } 1802 if (pfctl_set_synflwats(pf, curlim * pf->syncookieswat[0]/100, 1803 curlim * pf->syncookieswat[1]/100)) 1804 error = 1; 1805 } 1806 1807 return (error); 1808 } 1809 1810 int 1811 pfctl_set_limit(struct pfctl *pf, const char *opt, unsigned int limit) 1812 { 1813 int i; 1814 1815 for (i = 0; pf_limits[i].name; i++) { 1816 if (strcasecmp(opt, pf_limits[i].name) == 0) { 1817 pf->limit[pf_limits[i].index] = limit; 1818 pf->limit_set[pf_limits[i].index] = 1; 1819 break; 1820 } 1821 } 1822 if (pf_limits[i].name == NULL) { 1823 warnx("Bad pool name."); 1824 return (1); 1825 } 1826 1827 if (pf->opts & PF_OPT_VERBOSE) 1828 printf("set limit %s %d\n", opt, limit); 1829 1830 return (0); 1831 } 1832 1833 int 1834 pfctl_load_limit(struct pfctl *pf, unsigned int index, unsigned int limit) 1835 { 1836 struct pfioc_limit pl; 1837 1838 memset(&pl, 0, sizeof(pl)); 1839 pl.index = index; 1840 pl.limit = limit; 1841 if (ioctl(pf->dev, DIOCSETLIMIT, &pl) == -1) { 1842 if (errno == EBUSY) 1843 warnx("Current pool size exceeds requested %s limit %u", 1844 pf_limits[index].name, limit); 1845 else 1846 warnx("Cannot set %s limit to %u", 1847 pf_limits[index].name, limit); 1848 return (1); 1849 } 1850 return (0); 1851 } 1852 1853 int 1854 pfctl_set_timeout(struct pfctl *pf, const char *opt, int seconds, int quiet) 1855 { 1856 int i; 1857 1858 for (i = 0; pf_timeouts[i].name; i++) { 1859 if (strcasecmp(opt, pf_timeouts[i].name) == 0) { 1860 pf->timeout[pf_timeouts[i].timeout] = seconds; 1861 pf->timeout_set[pf_timeouts[i].timeout] = 1; 1862 break; 1863 } 1864 } 1865 1866 if (pf_timeouts[i].name == NULL) { 1867 warnx("Bad timeout name."); 1868 return (1); 1869 } 1870 1871 1872 if (pf->opts & PF_OPT_VERBOSE && ! quiet) 1873 printf("set timeout %s %d\n", opt, seconds); 1874 1875 return (0); 1876 } 1877 1878 int 1879 pfctl_load_timeout(struct pfctl *pf, unsigned int timeout, unsigned int seconds) 1880 { 1881 struct pfioc_tm pt; 1882 1883 memset(&pt, 0, sizeof(pt)); 1884 pt.timeout = timeout; 1885 pt.seconds = seconds; 1886 if (ioctl(pf->dev, DIOCSETTIMEOUT, &pt) == -1) { 1887 warnx("DIOCSETTIMEOUT"); 1888 return (1); 1889 } 1890 return (0); 1891 } 1892 1893 int 1894 pfctl_set_synflwats(struct pfctl *pf, u_int32_t lowat, u_int32_t hiwat) 1895 { 1896 struct pfioc_synflwats ps; 1897 1898 memset(&ps, 0, sizeof(ps)); 1899 ps.hiwat = hiwat; 1900 ps.lowat = lowat; 1901 1902 if (ioctl(pf->dev, DIOCSETSYNFLWATS, &ps) == -1) { 1903 warnx("Cannot set synflood detection watermarks"); 1904 return (1); 1905 } 1906 return (0); 1907 } 1908 1909 int 1910 pfctl_set_reassembly(struct pfctl *pf, int on, int nodf) 1911 { 1912 pf->reass_set = 1; 1913 if (on) { 1914 pf->reassemble = PF_REASS_ENABLED; 1915 if (nodf) 1916 pf->reassemble |= PF_REASS_NODF; 1917 } else { 1918 pf->reassemble = 0; 1919 } 1920 1921 if (pf->opts & PF_OPT_VERBOSE) 1922 printf("set reassemble %s %s\n", on ? "yes" : "no", 1923 nodf ? "no-df" : ""); 1924 1925 return (0); 1926 } 1927 1928 int 1929 pfctl_set_syncookies(struct pfctl *pf, u_int8_t val, struct pfctl_watermarks *w) 1930 { 1931 if (val != PF_SYNCOOKIES_ADAPTIVE && w != NULL) { 1932 warnx("syncookies start/end only apply to adaptive"); 1933 return (1); 1934 } 1935 if (val == PF_SYNCOOKIES_ADAPTIVE && w != NULL) { 1936 if (!w->hi) 1937 w->hi = PF_SYNCOOKIES_HIWATPCT; 1938 if (!w->lo) 1939 w->lo = w->hi / 2; 1940 if (w->lo >= w->hi) { 1941 warnx("start must be higher than end"); 1942 return (1); 1943 } 1944 pf->syncookieswat[0] = w->lo; 1945 pf->syncookieswat[1] = w->hi; 1946 pf->syncookieswat_set = 1; 1947 } 1948 1949 if (pf->opts & PF_OPT_VERBOSE) { 1950 if (val == PF_SYNCOOKIES_NEVER) 1951 printf("set syncookies never\n"); 1952 else if (val == PF_SYNCOOKIES_ALWAYS) 1953 printf("set syncookies always\n"); 1954 else if (val == PF_SYNCOOKIES_ADAPTIVE) { 1955 if (pf->syncookieswat_set) 1956 printf("set syncookies adaptive (start %u%%, " 1957 "end %u%%)\n", pf->syncookieswat[1], 1958 pf->syncookieswat[0]); 1959 else 1960 printf("set syncookies adaptive\n"); 1961 } else { /* cannot happen */ 1962 warnx("king bula ate all syncookies"); 1963 return (1); 1964 } 1965 } 1966 1967 pf->syncookies_set = 1; 1968 pf->syncookies = val; 1969 return (0); 1970 } 1971 1972 int 1973 pfctl_set_optimization(struct pfctl *pf, const char *opt) 1974 { 1975 const struct pf_hint *hint; 1976 int i, r; 1977 1978 for (i = 0; pf_hints[i].name; i++) 1979 if (strcasecmp(opt, pf_hints[i].name) == 0) 1980 break; 1981 1982 hint = pf_hints[i].hint; 1983 if (hint == NULL) { 1984 warnx("invalid state timeouts optimization"); 1985 return (1); 1986 } 1987 1988 for (i = 0; hint[i].name; i++) 1989 if ((r = pfctl_set_timeout(pf, hint[i].name, 1990 hint[i].timeout, 1))) 1991 return (r); 1992 1993 if (pf->opts & PF_OPT_VERBOSE) 1994 printf("set optimization %s\n", opt); 1995 1996 return (0); 1997 } 1998 1999 int 2000 pfctl_set_logif(struct pfctl *pf, char *ifname) 2001 { 2002 if (!strcmp(ifname, "none")) { 2003 free(pf->ifname); 2004 pf->ifname = NULL; 2005 } else { 2006 pf->ifname = strdup(ifname); 2007 if (!pf->ifname) 2008 errx(1, "pfctl_set_logif: strdup"); 2009 } 2010 pf->ifname_set = 1; 2011 2012 if (pf->opts & PF_OPT_VERBOSE) 2013 printf("set loginterface %s\n", ifname); 2014 2015 return (0); 2016 } 2017 2018 int 2019 pfctl_load_logif(struct pfctl *pf, char *ifname) 2020 { 2021 struct pfioc_iface pi; 2022 2023 memset(&pi, 0, sizeof(pi)); 2024 if (ifname && strlcpy(pi.pfiio_name, ifname, 2025 sizeof(pi.pfiio_name)) >= sizeof(pi.pfiio_name)) { 2026 warnx("pfctl_load_logif: strlcpy"); 2027 return (1); 2028 } 2029 if (ioctl(pf->dev, DIOCSETSTATUSIF, &pi) == -1) { 2030 warnx("DIOCSETSTATUSIF"); 2031 return (1); 2032 } 2033 return (0); 2034 } 2035 2036 void 2037 pfctl_set_hostid(struct pfctl *pf, u_int32_t hostid) 2038 { 2039 HTONL(hostid); 2040 2041 pf->hostid = hostid; 2042 pf->hostid_set = 1; 2043 2044 if (pf->opts & PF_OPT_VERBOSE) 2045 printf("set hostid 0x%08x\n", ntohl(hostid)); 2046 } 2047 2048 int 2049 pfctl_load_hostid(struct pfctl *pf, u_int32_t hostid) 2050 { 2051 if (ioctl(dev, DIOCSETHOSTID, &hostid) == -1) { 2052 warnx("DIOCSETHOSTID"); 2053 return (1); 2054 } 2055 return (0); 2056 } 2057 2058 int 2059 pfctl_load_reassembly(struct pfctl *pf, u_int32_t reassembly) 2060 { 2061 if (ioctl(dev, DIOCSETREASS, &reassembly) == -1) { 2062 warnx("DIOCSETREASS"); 2063 return (1); 2064 } 2065 return (0); 2066 } 2067 2068 int 2069 pfctl_load_syncookies(struct pfctl *pf, u_int8_t val) 2070 { 2071 if (ioctl(dev, DIOCSETSYNCOOKIES, &val) == -1) { 2072 warnx("DIOCSETSYNCOOKIES"); 2073 return (1); 2074 } 2075 return (0); 2076 } 2077 2078 int 2079 pfctl_set_debug(struct pfctl *pf, char *d) 2080 { 2081 u_int32_t level; 2082 int loglevel; 2083 2084 if ((loglevel = string_to_loglevel(d)) >= 0) 2085 level = loglevel; 2086 else { 2087 warnx("unknown debug level \"%s\"", d); 2088 return (-1); 2089 } 2090 pf->debug = level; 2091 pf->debug_set = 1; 2092 2093 if ((pf->opts & PF_OPT_NOACTION) == 0) 2094 if (ioctl(dev, DIOCSETDEBUG, &level) == -1) 2095 err(1, "DIOCSETDEBUG"); 2096 2097 if (pf->opts & PF_OPT_VERBOSE) 2098 printf("set debug %s\n", d); 2099 2100 return (0); 2101 } 2102 2103 int 2104 pfctl_load_debug(struct pfctl *pf, unsigned int level) 2105 { 2106 if (ioctl(pf->dev, DIOCSETDEBUG, &level) == -1) { 2107 warnx("DIOCSETDEBUG"); 2108 return (1); 2109 } 2110 return (0); 2111 } 2112 2113 int 2114 pfctl_set_interface_flags(struct pfctl *pf, char *ifname, int flags, int how) 2115 { 2116 struct pfioc_iface pi; 2117 2118 bzero(&pi, sizeof(pi)); 2119 2120 pi.pfiio_flags = flags; 2121 2122 if (strlcpy(pi.pfiio_name, ifname, sizeof(pi.pfiio_name)) >= 2123 sizeof(pi.pfiio_name)) 2124 errx(1, "pfctl_set_interface_flags: strlcpy"); 2125 2126 if ((pf->opts & PF_OPT_NOACTION) == 0) { 2127 if (how == 0) { 2128 if (ioctl(pf->dev, DIOCCLRIFFLAG, &pi) == -1) 2129 err(1, "DIOCCLRIFFLAG"); 2130 } else { 2131 if (ioctl(pf->dev, DIOCSETIFFLAG, &pi) == -1) 2132 err(1, "DIOCSETIFFLAG"); 2133 } 2134 } 2135 return (0); 2136 } 2137 2138 void 2139 pfctl_debug(int dev, u_int32_t level, int opts) 2140 { 2141 struct pfr_buffer t; 2142 2143 memset(&t, 0, sizeof(t)); 2144 t.pfrb_type = PFRB_TRANS; 2145 if (pfctl_trans(dev, &t, DIOCXBEGIN, 0) || 2146 ioctl(dev, DIOCSETDEBUG, &level) == -1|| 2147 pfctl_trans(dev, &t, DIOCXCOMMIT, 0)) 2148 err(1, "pfctl_debug ioctl"); 2149 2150 if ((opts & PF_OPT_QUIET) == 0) 2151 fprintf(stderr, "debug level set to '%s'\n", 2152 loglevel_to_string(level)); 2153 } 2154 2155 int 2156 pfctl_walk_show(int opts, struct pfioc_ruleset *pr, void *warg) 2157 { 2158 if (pr->path[0]) { 2159 if (pr->path[0] != '_' || (opts & PF_OPT_VERBOSE)) 2160 printf(" %s/%s\n", pr->path, pr->name); 2161 } else if (pr->name[0] != '_' || (opts & PF_OPT_VERBOSE)) 2162 printf(" %s\n", pr->name); 2163 2164 return (0); 2165 } 2166 2167 int 2168 pfctl_walk_get(int opts, struct pfioc_ruleset *pr, void *warg) 2169 { 2170 struct pfr_anchoritem *pfra; 2171 struct pfr_anchors *anchors; 2172 int e; 2173 2174 anchors = (struct pfr_anchors *) warg; 2175 2176 pfra = malloc(sizeof(*pfra)); 2177 if (pfra == NULL) 2178 err(1, "%s", __func__); 2179 2180 if (pr->path[0]) 2181 e = asprintf(&pfra->pfra_anchorname, "%s/%s", pr->path, 2182 pr->name); 2183 else 2184 e = asprintf(&pfra->pfra_anchorname, "%s", pr->name); 2185 2186 if (e == -1) 2187 err(1, "%s", __func__); 2188 2189 2190 SLIST_INSERT_HEAD(anchors, pfra, pfra_sle); 2191 2192 return (0); 2193 } 2194 2195 int 2196 pfctl_walk_anchors(int dev, int opts, const char *anchor, 2197 int(walkf)(int, struct pfioc_ruleset *, void *), void *warg) 2198 { 2199 struct pfioc_ruleset pr; 2200 u_int32_t mnr, nr; 2201 2202 memset(&pr, 0, sizeof(pr)); 2203 strlcpy(pr.path, anchor, sizeof(pr.path)); 2204 if (ioctl(dev, DIOCGETRULESETS, &pr) == -1) 2205 errx(1, "%s", pf_strerror(errno)); 2206 mnr = pr.nr; 2207 for (nr = 0; nr < mnr; ++nr) { 2208 char sub[PATH_MAX]; 2209 2210 pr.nr = nr; 2211 if (ioctl(dev, DIOCGETRULESET, &pr) == -1) 2212 errx(1, "%s", pf_strerror(errno)); 2213 if (!strcmp(pr.name, PF_RESERVED_ANCHOR)) 2214 continue; 2215 sub[0] = '\0'; 2216 2217 if (walkf(opts, &pr, warg)) 2218 return (-1); 2219 2220 if (pr.path[0]) 2221 snprintf(sub, sizeof(sub), "%s/%s", 2222 pr.path, pr.name); 2223 else 2224 snprintf(sub, sizeof(sub), "%s", 2225 pr.name); 2226 if (pfctl_walk_anchors(dev, opts, sub, walkf, warg)) 2227 return (-1); 2228 } 2229 return (0); 2230 } 2231 2232 int 2233 pfctl_show_anchors(int dev, int opts, char *anchor) 2234 { 2235 return ( 2236 pfctl_walk_anchors(dev, opts, anchor, pfctl_walk_show, NULL)); 2237 } 2238 2239 struct pfr_anchors * 2240 pfctl_get_anchors(int dev, const char *anchor, int opts) 2241 { 2242 struct pfioc_ruleset pr; 2243 static struct pfr_anchors anchors; 2244 char *n; 2245 2246 SLIST_INIT(&anchors); 2247 2248 memset(&pr, 0, sizeof(pr)); 2249 if (*anchor != '\0') { 2250 n = dirname(anchor); 2251 if (n[0] != '.' && n[1] != '\0') 2252 strlcpy(pr.path, n, sizeof(pr.path)); 2253 n = basename(anchor); 2254 if (n != NULL) 2255 strlcpy(pr.name, n, sizeof(pr.name)); 2256 } 2257 2258 /* insert a root anchor first. */ 2259 pfctl_walk_get(opts, &pr, &anchors); 2260 2261 if (pfctl_walk_anchors(dev, opts, anchor, pfctl_walk_get, &anchors)) 2262 errx(1, 2263 "%s failed to retrieve list of anchors, can't continue", 2264 __func__); 2265 2266 return (&anchors); 2267 } 2268 2269 int 2270 pfctl_call_cleartables(int dev, int opts, struct pfr_anchoritem *pfra) 2271 { 2272 /* 2273 * PF_OPT_QUIET makes pfctl_clear_tables() to stop printing number of 2274 * tables cleared for given anchor. 2275 */ 2276 opts |= PF_OPT_QUIET; 2277 return ((pfctl_clear_tables(pfra->pfra_anchorname, opts) == -1) ? 2278 1 : 0); 2279 } 2280 2281 int 2282 pfctl_call_clearrules(int dev, int opts, struct pfr_anchoritem *pfra) 2283 { 2284 /* 2285 * PF_OPT_QUIET makes pfctl_clear_rules() to stop printing a 'rules 2286 * cleared' message for every anchor it deletes. 2287 */ 2288 opts |= PF_OPT_QUIET; 2289 return (pfctl_clear_rules(dev, opts, pfra->pfra_anchorname)); 2290 } 2291 2292 int 2293 pfctl_call_clearanchors(int dev, int opts, struct pfr_anchoritem *pfra) 2294 { 2295 int rv = 0; 2296 2297 rv |= pfctl_call_cleartables(dev, opts, pfra); 2298 rv |= pfctl_call_clearrules(dev, opts, pfra); 2299 2300 return (rv); 2301 } 2302 2303 int 2304 pfctl_recurse(int dev, int opts, const char *anchorname, 2305 int(*walkf)(int, int, struct pfr_anchoritem *)) 2306 { 2307 int rv = 0; 2308 struct pfr_anchors *anchors; 2309 struct pfr_anchoritem *pfra, *pfra_save; 2310 2311 anchors = pfctl_get_anchors(dev, anchorname, opts); 2312 /* 2313 * While traversing the list, pfctl_clear_*() must always return 2314 * so that failures on one anchor do not prevent clearing others. 2315 */ 2316 opts |= PF_OPT_IGNFAIL; 2317 printf("Removing:\n"); 2318 SLIST_FOREACH_SAFE(pfra, anchors, pfra_sle, pfra_save) { 2319 printf(" %s\n", (*pfra->pfra_anchorname == '\0') ? 2320 "/" : pfra->pfra_anchorname); 2321 rv |= walkf(dev, opts, pfra); 2322 SLIST_REMOVE(anchors, pfra, pfr_anchoritem, pfra_sle); 2323 free(pfra->pfra_anchorname); 2324 free(pfra); 2325 } 2326 2327 return (rv); 2328 } 2329 2330 const char * 2331 pfctl_lookup_option(char *cmd, const char **list) 2332 { 2333 const char *item = NULL; 2334 2335 if (cmd != NULL && *cmd) 2336 for (; *list; list++) 2337 if (!strncmp(cmd, *list, strlen(cmd))) { 2338 if (item == NULL) 2339 item = *list; 2340 else 2341 errx(1, "%s is ambigious", cmd); 2342 } 2343 2344 return (item); 2345 } 2346 2347 2348 void 2349 pfctl_state_store(int dev, const char *file) 2350 { 2351 FILE *f; 2352 struct pfioc_states ps; 2353 char *inbuf = NULL, *newinbuf = NULL; 2354 size_t n, len = 0; 2355 2356 f = fopen(file, "w"); 2357 if (f == NULL) 2358 err(1, "open: %s", file); 2359 2360 memset(&ps, 0, sizeof(ps)); 2361 for (;;) { 2362 ps.ps_len = len; 2363 if (len) { 2364 newinbuf = realloc(inbuf, len); 2365 if (newinbuf == NULL) 2366 err(1, "realloc"); 2367 ps.ps_buf = inbuf = newinbuf; 2368 } 2369 if (ioctl(dev, DIOCGETSTATES, &ps) == -1) 2370 err(1, "DIOCGETSTATES"); 2371 2372 if (ps.ps_len + sizeof(struct pfioc_states) < len) 2373 break; 2374 if (len == 0 && ps.ps_len == 0) 2375 goto done; 2376 if (len == 0 && ps.ps_len != 0) 2377 len = ps.ps_len; 2378 if (ps.ps_len == 0) 2379 goto done; /* no states */ 2380 len *= 2; 2381 } 2382 2383 n = ps.ps_len / sizeof(struct pfsync_state); 2384 if (fwrite(inbuf, sizeof(struct pfsync_state), n, f) < n) 2385 err(1, "fwrite"); 2386 2387 done: 2388 free(inbuf); 2389 fclose(f); 2390 } 2391 2392 void 2393 pfctl_state_load(int dev, const char *file) 2394 { 2395 FILE *f; 2396 struct pfioc_state ps; 2397 2398 f = fopen(file, "r"); 2399 if (f == NULL) 2400 err(1, "open: %s", file); 2401 2402 while (fread(&ps.state, sizeof(ps.state), 1, f) == 1) { 2403 if (ioctl(dev, DIOCADDSTATE, &ps) == -1) { 2404 switch (errno) { 2405 case EEXIST: 2406 case EINVAL: 2407 break; 2408 default: 2409 err(1, "DIOCADDSTATE"); 2410 } 2411 } 2412 } 2413 2414 fclose(f); 2415 } 2416 2417 void 2418 pfctl_reset(int dev, int opts) 2419 { 2420 struct pfctl pf; 2421 struct pfr_buffer t; 2422 int i; 2423 2424 pf.dev = dev; 2425 pfctl_init_options(&pf); 2426 2427 /* Force reset upon pfctl_load_options() */ 2428 pf.debug_set = 1; 2429 pf.reass_set = 1; 2430 pf.syncookieswat_set = 1; 2431 pf.syncookies_set = 1; 2432 pf.ifname = strdup("none"); 2433 if (pf.ifname == NULL) 2434 err(1, "%s: strdup", __func__); 2435 pf.ifname_set = 1; 2436 2437 memset(&t, 0, sizeof(t)); 2438 t.pfrb_type = PFRB_TRANS; 2439 if (pfctl_trans(dev, &t, DIOCXBEGIN, 0)) 2440 err(1, "%s: DIOCXBEGIN", __func__); 2441 2442 for (i = 0; pf_limits[i].name; i++) 2443 pf.limit_set[pf_limits[i].index] = 1; 2444 2445 for (i = 0; pf_timeouts[i].name; i++) 2446 pf.timeout_set[pf_timeouts[i].timeout] = 1; 2447 2448 pfctl_load_options(&pf); 2449 2450 if (pfctl_trans(dev, &t, DIOCXCOMMIT, 0)) 2451 err(1, "%s: DIOCXCOMMIT", __func__); 2452 2453 pfctl_clear_interface_flags(dev, opts); 2454 } 2455 2456 int 2457 main(int argc, char *argv[]) 2458 { 2459 int ch; 2460 int mode = O_RDONLY; 2461 int opts = 0; 2462 int optimize = PF_OPTIMIZE_BASIC; 2463 int level; 2464 int rdomain = 0; 2465 char anchorname[PATH_MAX]; 2466 int anchor_wildcard = 0; 2467 char *path; 2468 char *lfile = NULL, *sfile = NULL; 2469 const char *errstr; 2470 long shownr = -1; 2471 2472 if (argc < 2) 2473 usage(); 2474 2475 while ((ch = getopt(argc, argv, 2476 "a:dD:eqf:F:ghi:k:K:L:Nno:Pp:R:rS:s:t:T:vV:x:z")) != -1) { 2477 switch (ch) { 2478 case 'a': 2479 anchoropt = optarg; 2480 break; 2481 case 'd': 2482 opts |= PF_OPT_DISABLE; 2483 mode = O_RDWR; 2484 break; 2485 case 'D': 2486 if (pfctl_cmdline_symset(optarg) < 0) 2487 warnx("could not parse macro definition %s", 2488 optarg); 2489 break; 2490 case 'e': 2491 opts |= PF_OPT_ENABLE; 2492 mode = O_RDWR; 2493 break; 2494 case 'q': 2495 opts |= PF_OPT_QUIET; 2496 break; 2497 case 'F': 2498 clearopt = pfctl_lookup_option(optarg, clearopt_list); 2499 if (clearopt == NULL) { 2500 warnx("Unknown flush modifier '%s'", optarg); 2501 usage(); 2502 } 2503 mode = O_RDWR; 2504 break; 2505 case 'i': 2506 ifaceopt = optarg; 2507 break; 2508 case 'k': 2509 if (state_killers >= 2) { 2510 warnx("can only specify -k twice"); 2511 usage(); 2512 /* NOTREACHED */ 2513 } 2514 state_kill[state_killers++] = optarg; 2515 mode = O_RDWR; 2516 break; 2517 case 'K': 2518 if (src_node_killers >= 2) { 2519 warnx("can only specify -K twice"); 2520 usage(); 2521 /* NOTREACHED */ 2522 } 2523 src_node_kill[src_node_killers++] = optarg; 2524 mode = O_RDWR; 2525 break; 2526 case 'N': 2527 opts |= PF_OPT_NODNS; 2528 break; 2529 case 'n': 2530 opts |= PF_OPT_NOACTION; 2531 break; 2532 case 'r': 2533 opts |= PF_OPT_USEDNS; 2534 break; 2535 case 'R': 2536 shownr = strtonum(optarg, -1, LONG_MAX, &errstr); 2537 if (errstr) { 2538 warnx("invalid rule id: %s", errstr); 2539 usage(); 2540 } 2541 break; 2542 case 'f': 2543 rulesopt = optarg; 2544 mode = O_RDWR; 2545 break; 2546 case 'g': 2547 opts |= PF_OPT_DEBUG; 2548 break; 2549 case 'o': 2550 optiopt = pfctl_lookup_option(optarg, optiopt_list); 2551 if (optiopt == NULL) { 2552 warnx("Unknown optimization '%s'", optarg); 2553 usage(); 2554 } 2555 opts |= PF_OPT_OPTIMIZE; 2556 break; 2557 case 'P': 2558 opts |= PF_OPT_PORTNAMES; 2559 break; 2560 case 'p': 2561 pf_device = optarg; 2562 break; 2563 case 's': 2564 showopt = pfctl_lookup_option(optarg, showopt_list); 2565 if (showopt == NULL) { 2566 warnx("Unknown show modifier '%s'", optarg); 2567 usage(); 2568 } 2569 break; 2570 case 't': 2571 tableopt = optarg; 2572 break; 2573 case 'T': 2574 tblcmdopt = pfctl_lookup_option(optarg, tblcmdopt_list); 2575 if (tblcmdopt == NULL) { 2576 warnx("Unknown table command '%s'", optarg); 2577 usage(); 2578 } 2579 break; 2580 case 'v': 2581 if (opts & PF_OPT_VERBOSE) 2582 opts |= PF_OPT_VERBOSE2; 2583 opts |= PF_OPT_VERBOSE; 2584 break; 2585 case 'V': 2586 rdomain = strtonum(optarg, 0, RT_TABLEID_MAX, &errstr); 2587 if (errstr) { 2588 warnx("Invalid rdomain: %s", errstr); 2589 usage(); 2590 } 2591 break; 2592 case 'x': 2593 debugopt = pfctl_lookup_option(optarg, debugopt_list); 2594 if (debugopt == NULL) { 2595 warnx("Unknown debug level '%s'", optarg); 2596 usage(); 2597 } 2598 mode = O_RDWR; 2599 break; 2600 case 'z': 2601 opts |= PF_OPT_CLRRULECTRS; 2602 mode = O_RDWR; 2603 break; 2604 case 'S': 2605 sfile = optarg; 2606 break; 2607 case 'L': 2608 mode = O_RDWR; 2609 lfile = optarg; 2610 break; 2611 case 'h': 2612 /* FALLTHROUGH */ 2613 default: 2614 usage(); 2615 /* NOTREACHED */ 2616 } 2617 } 2618 2619 if ((opts & PF_OPT_NODNS) && (opts & PF_OPT_USEDNS)) 2620 errx(1, "-N and -r are mutually exclusive"); 2621 2622 if ((tblcmdopt == NULL) ^ (tableopt == NULL)) 2623 usage(); 2624 2625 if (tblcmdopt != NULL) { 2626 argc -= optind; 2627 argv += optind; 2628 ch = *tblcmdopt; 2629 mode = strchr("st", ch) ? O_RDONLY : O_RDWR; 2630 } else if (argc != optind) { 2631 warnx("unknown command line argument: %s ...", argv[optind]); 2632 usage(); 2633 /* NOTREACHED */ 2634 } 2635 2636 memset(anchorname, 0, sizeof(anchorname)); 2637 if (anchoropt != NULL) { 2638 if (anchoropt[0] == '\0') 2639 errx(1, "anchor name must not be empty"); 2640 if (mode == O_RDONLY && showopt == NULL && tblcmdopt == NULL) { 2641 warnx("anchors apply to -f, -F, -s, and -T only"); 2642 usage(); 2643 } 2644 if (mode == O_RDWR && tblcmdopt == NULL && 2645 (anchoropt[0] == '_' || strstr(anchoropt, "/_") != NULL)) 2646 errx(1, "anchor names beginning with '_' cannot " 2647 "be modified from the command line"); 2648 int len = strlen(anchoropt); 2649 2650 if (anchoropt[len - 1] == '*') { 2651 if (len >= 2 && anchoropt[len - 2] == '/') { 2652 anchoropt[len - 2] = '\0'; 2653 anchor_wildcard = 1; 2654 } else 2655 anchoropt[len - 1] = '\0'; 2656 opts |= PF_OPT_RECURSE; 2657 } 2658 if (strlcpy(anchorname, anchoropt, 2659 sizeof(anchorname)) >= sizeof(anchorname)) 2660 errx(1, "anchor name '%s' too long", 2661 anchoropt); 2662 } 2663 2664 if ((opts & PF_OPT_NOACTION) == 0) { 2665 dev = open(pf_device, mode); 2666 if (dev == -1) 2667 err(1, "%s", pf_device); 2668 } else { 2669 dev = open(pf_device, O_RDONLY); 2670 if (dev >= 0) 2671 opts |= PF_OPT_DUMMYACTION; 2672 /* turn off options */ 2673 opts &= ~ (PF_OPT_DISABLE | PF_OPT_ENABLE); 2674 clearopt = showopt = debugopt = NULL; 2675 } 2676 2677 if (opts & PF_OPT_DISABLE) 2678 if (pfctl_disable(dev, opts)) 2679 exit_val = 1; 2680 2681 if ((path = calloc(1, PATH_MAX)) == NULL) 2682 errx(1, "%s: calloc", __func__); 2683 2684 if (showopt != NULL) { 2685 switch (*showopt) { 2686 case 'A': 2687 pfctl_show_anchors(dev, opts, anchorname); 2688 break; 2689 case 'r': 2690 pfctl_load_fingerprints(dev, opts); 2691 pfctl_show_rules(dev, path, opts, PFCTL_SHOW_RULES, 2692 anchorname, 0, anchor_wildcard, shownr); 2693 break; 2694 case 'l': 2695 pfctl_load_fingerprints(dev, opts); 2696 pfctl_show_rules(dev, path, opts, PFCTL_SHOW_LABELS, 2697 anchorname, 0, anchor_wildcard, shownr); 2698 break; 2699 case 'q': 2700 pfctl_show_queues(dev, ifaceopt, opts, 2701 opts & PF_OPT_VERBOSE2); 2702 break; 2703 case 's': 2704 pfctl_show_states(dev, ifaceopt, opts, shownr); 2705 break; 2706 case 'S': 2707 pfctl_show_src_nodes(dev, opts); 2708 break; 2709 case 'i': 2710 pfctl_show_status(dev, opts); 2711 break; 2712 case 't': 2713 pfctl_show_timeouts(dev, opts); 2714 break; 2715 case 'm': 2716 pfctl_show_limits(dev, opts); 2717 break; 2718 case 'a': 2719 opts |= PF_OPT_SHOWALL; 2720 pfctl_load_fingerprints(dev, opts); 2721 2722 pfctl_show_rules(dev, path, opts, PFCTL_SHOW_RULES, 2723 anchorname, 0, 0, -1); 2724 pfctl_show_queues(dev, ifaceopt, opts, 2725 opts & PF_OPT_VERBOSE2); 2726 pfctl_show_states(dev, ifaceopt, opts, -1); 2727 pfctl_show_src_nodes(dev, opts); 2728 pfctl_show_status(dev, opts); 2729 pfctl_show_rules(dev, path, opts, PFCTL_SHOW_LABELS, 2730 anchorname, 0, 0, -1); 2731 pfctl_show_timeouts(dev, opts); 2732 pfctl_show_limits(dev, opts); 2733 pfctl_show_tables(anchorname, opts); 2734 pfctl_show_fingerprints(opts); 2735 break; 2736 case 'T': 2737 pfctl_show_tables(anchorname, opts); 2738 break; 2739 case 'o': 2740 pfctl_load_fingerprints(dev, opts); 2741 pfctl_show_fingerprints(opts); 2742 break; 2743 case 'I': 2744 pfctl_show_ifaces(ifaceopt, opts); 2745 break; 2746 } 2747 } 2748 2749 if ((opts & PF_OPT_CLRRULECTRS) && showopt == NULL) 2750 pfctl_show_rules(dev, path, opts, PFCTL_SHOW_NOTHING, 2751 anchorname, 0, 0, -1); 2752 2753 if (clearopt != NULL) { 2754 switch (*clearopt) { 2755 case 'r': 2756 if (opts & PF_OPT_RECURSE) 2757 pfctl_recurse(dev, opts, anchorname, 2758 pfctl_call_clearrules); 2759 else 2760 pfctl_clear_rules(dev, opts, anchorname); 2761 break; 2762 case 's': 2763 pfctl_clear_states(dev, ifaceopt, opts); 2764 break; 2765 case 'S': 2766 pfctl_clear_src_nodes(dev, opts); 2767 break; 2768 case 'i': 2769 pfctl_clear_stats(dev, ifaceopt, opts); 2770 break; 2771 case 'a': 2772 if (ifaceopt) { 2773 warnx("don't specify an interface with -Fall"); 2774 usage(); 2775 /* NOTREACHED */ 2776 } 2777 if (opts & PF_OPT_RECURSE) 2778 pfctl_recurse(dev, opts, anchorname, 2779 pfctl_call_clearanchors); 2780 else { 2781 pfctl_clear_tables(anchorname, opts); 2782 pfctl_clear_rules(dev, opts, anchorname); 2783 } 2784 2785 if (!*anchorname) { 2786 pfctl_clear_states(dev, ifaceopt, opts); 2787 pfctl_clear_src_nodes(dev, opts); 2788 pfctl_clear_stats(dev, ifaceopt, opts); 2789 pfctl_clear_fingerprints(dev, opts); 2790 pfctl_reset(dev, opts); 2791 } 2792 break; 2793 case 'o': 2794 pfctl_clear_fingerprints(dev, opts); 2795 break; 2796 case 'T': 2797 if ((opts & PF_OPT_RECURSE) == 0) 2798 pfctl_clear_tables(anchorname, opts); 2799 else 2800 pfctl_recurse(dev, opts, anchorname, 2801 pfctl_call_cleartables); 2802 break; 2803 case 'R': 2804 pfctl_reset(dev, opts); 2805 break; 2806 } 2807 } 2808 if (state_killers) { 2809 if (!strcmp(state_kill[0], "label")) 2810 pfctl_label_kill_states(dev, ifaceopt, opts, rdomain); 2811 else if (!strcmp(state_kill[0], "id")) 2812 pfctl_id_kill_states(dev, opts); 2813 else if (!strcmp(state_kill[0], "key")) 2814 pfctl_key_kill_states(dev, ifaceopt, opts, rdomain); 2815 else 2816 pfctl_net_kill_states(dev, ifaceopt, opts, rdomain); 2817 } 2818 2819 if (src_node_killers) 2820 pfctl_kill_src_nodes(dev, opts); 2821 2822 if (tblcmdopt != NULL) { 2823 exit_val = pfctl_table(argc, argv, tableopt, 2824 tblcmdopt, rulesopt, anchorname, opts); 2825 rulesopt = NULL; 2826 } 2827 if (optiopt != NULL) { 2828 switch (*optiopt) { 2829 case 'n': 2830 optimize = 0; 2831 break; 2832 case 'b': 2833 optimize |= PF_OPTIMIZE_BASIC; 2834 break; 2835 case 'o': 2836 case 'p': 2837 optimize |= PF_OPTIMIZE_PROFILE; 2838 break; 2839 } 2840 } 2841 2842 if (rulesopt != NULL && !anchorname[0]) { 2843 pfctl_clear_interface_flags(dev, opts | PF_OPT_QUIET); 2844 if (pfctl_file_fingerprints(dev, opts, PF_OSFP_FILE)) 2845 exit_val = 1; 2846 } 2847 2848 if (rulesopt != NULL) { 2849 if (pfctl_rules(dev, rulesopt, opts, optimize, 2850 anchorname, NULL)) 2851 exit_val = 1; 2852 } 2853 2854 if (opts & PF_OPT_ENABLE) 2855 if (pfctl_enable(dev, opts)) 2856 exit_val = 1; 2857 2858 if (debugopt != NULL) { 2859 if ((level = string_to_loglevel((char *)debugopt)) < 0) { 2860 switch (*debugopt) { 2861 case 'n': 2862 level = LOG_CRIT; 2863 break; 2864 case 'u': 2865 level = LOG_ERR; 2866 break; 2867 case 'm': 2868 level = LOG_NOTICE; 2869 break; 2870 case 'l': 2871 level = LOG_DEBUG; 2872 break; 2873 } 2874 } 2875 if (level >= 0) 2876 pfctl_debug(dev, level, opts); 2877 } 2878 2879 if (sfile != NULL) 2880 pfctl_state_store(dev, sfile); 2881 if (lfile != NULL) 2882 pfctl_state_load(dev, lfile); 2883 2884 exit(exit_val); 2885 } 2886 2887 char * 2888 pf_strerror(int errnum) 2889 { 2890 switch (errnum) { 2891 case ESRCH: 2892 return "Table does not exist"; 2893 case EINVAL: 2894 case ENOENT: 2895 return "Anchor does not exist"; 2896 default: 2897 return strerror(errnum); 2898 } 2899 } 2900