diff options
author | Henning Brauer <henning@cvs.openbsd.org> | 2002-06-25 08:13:27 +0000 |
---|---|---|
committer | Henning Brauer <henning@cvs.openbsd.org> | 2002-06-25 08:13:27 +0000 |
commit | bc5e45eaa6b5ab08915bf407374757eca204ffbc (patch) | |
tree | fe646e020bb00a631cbd4137fa0490fb4c360c07 /sbin | |
parent | 013d571c5cb317eb071a32d992578f437cb220a9 (diff) |
move pfctl options -t, -m, -O and -l to pf.conf. These are set using the
"set" keyword. example rulefile:
set optimization aggressive
set timeout { tcp.closing 6, tcp.opening 6 }
set limit { states 1000, frags 1000 }
set loginterface wi0
pass out all keep state label "$nr:$srcaddr:$srcport:$dstaddr:$dstport"
block in all
fries@ is working on an updated pf.conf(5)
discussed at c2k2 and on icb
ok dhartmei@, kjell@
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/pfctl/parse.y | 123 | ||||
-rw-r--r-- | sbin/pfctl/pfctl.8 | 134 | ||||
-rw-r--r-- | sbin/pfctl/pfctl.c | 344 | ||||
-rw-r--r-- | sbin/pfctl/pfctl_parser.h | 8 |
4 files changed, 228 insertions, 381 deletions
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y index 7385c750da5..2412bad418c 100644 --- a/sbin/pfctl/parse.y +++ b/sbin/pfctl/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.106 2002/06/24 10:55:08 dhartmei Exp $ */ +/* $OpenBSD: parse.y,v 1.107 2002/06/25 08:13:25 henning Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -57,8 +57,9 @@ static int lineno = 1; static int errors = 0; static int rulestate = 0; -enum {PFCTL_STATE_NONE=0, PFCTL_STATE_SCRUB=1, - PFCTL_STATE_NAT=2, PFCTL_STATE_FILTER=3}; +enum {PFCTL_STATE_NONE=0, PFCTL_STATE_OPTION=1, + PFCTL_STATE_SCRUB=2, PFCTL_STATE_NAT=3, + PFCTL_STATE_FILTER=4}; struct node_if { char ifname[IFNAMSIZ]; @@ -141,6 +142,7 @@ void expand_rule(struct pf_rule *, struct node_if *, struct node_proto *, struct node_host *, struct node_port *, struct node_host *, struct node_port *, struct node_uid *, struct node_gid *, struct node_icmp *); +int check_rulestate(int); struct sym { struct sym *next; @@ -209,6 +211,7 @@ typedef struct { %token MINTTL IPV6ADDR ERROR ALLOWOPTS FASTROUTE ROUTETO DUPTO NO LABEL %token NOROUTE FRAGMENT USER GROUP MAXMSS MAXIMUM TTL %token FRAGNORM FRAGDROP FRAGCROP +%token SET OPTIMIZATION TIMEOUT LIMIT LOGINTERFACE %token <v.string> STRING %token <v.number> NUMBER %token <v.i> PORTUNARY PORTBINARY @@ -230,10 +233,13 @@ typedef struct { %type <v.string> label %type <v.keep_state> keep %type <v.state_opt> state_opt_spec state_opt_list state_opt_item +%type <v.timeout_spec> timeout_spec timeout_list +%type <v.limit_spec> limit_spec limit_list %% ruleset : /* empty */ | ruleset '\n' + | ruleset option '\n' | ruleset scrubrule '\n' | ruleset natrule '\n' | ruleset binatrule '\n' @@ -243,6 +249,34 @@ ruleset : /* empty */ | ruleset error '\n' { errors++; } ; +option : SET OPTIMIZATION STRING + { + if (pf->opts & PF_OPT_VERBOSE) + printf("set optimization %s\n", $3); + if (check_rulestate(PFCTL_STATE_OPTION)) + YYERROR; + if (pfctl_set_optimization(pf, $3) != 0) { + yyerror("unknown optimization %s", $3); + YYERROR; + } + } + | SET TIMEOUT timeout_spec + | SET TIMEOUT '{' timeout_list '}' + | SET LIMIT limit_spec + | SET LIMIT '{' limit_list '}' + | SET LOGINTERFACE STRING + { + if (pf->opts & PF_OPT_VERBOSE) + printf("set loginterface %s\n", $3); + if (check_rulestate(PFCTL_STATE_OPTION)) + YYERROR; + if (pfctl_set_logif(pf, $3) != 0) { + yyerror("error setting loginterface %s", $3); + YYERROR; + } + } + ; + varset : STRING PORTUNARY STRING { if (pf->opts & PF_OPT_VERBOSE) @@ -258,12 +292,8 @@ scrubrule : SCRUB dir interface fromto nodf minttl maxmss fragcache { struct pf_rule r; - if (rulestate > PFCTL_STATE_SCRUB) { - yyerror("Rules must be in order: " - "scrub, nat, filter"); + if (check_rulestate(PFCTL_STATE_SCRUB)) YYERROR; - } - rulestate = PFCTL_STATE_SCRUB; memset(&r, 0, sizeof(r)); @@ -289,7 +319,6 @@ scrubrule : SCRUB dir interface fromto nodf minttl maxmss fragcache r.min_ttl = $6; if ($7) r.max_mss = $7; - if ($8) r.rule_flag |= $8; @@ -305,12 +334,8 @@ pfrule : action dir log quick interface route af proto fromto struct pf_rule r; struct node_state_opt *o; - if (rulestate > PFCTL_STATE_FILTER) { - yyerror("Rules must be in order: " - "scrub, nat, filter"); + if (check_rulestate(PFCTL_STATE_FILTER)) YYERROR; - } - rulestate = PFCTL_STATE_FILTER; memset(&r, 0, sizeof(r)); @@ -403,7 +428,7 @@ action : PASS { $$.b1 = PF_PASS; $$.b2 = $$.w = 0; } ; blockspec : /* empty */ { $$.b2 = 0; $$.w = 0; } - | RETURNRST { $$.b2 = 1; $$.w = 0;} + | RETURNRST { $$.b2 = 1; $$.w = 0; } | RETURNRST '(' TTL NUMBER ')' { $$.w = $4; $$.b2 = 1; @@ -1228,12 +1253,8 @@ natrule : no NAT interface af proto fromto redirection { struct pf_nat nat; - if (rulestate > PFCTL_STATE_NAT) { - yyerror("Rules must be in order: " - "scrub, nat, filter"); + if (check_rulestate(PFCTL_STATE_NAT)) YYERROR; - } - rulestate = PFCTL_STATE_NAT; memset(&nat, 0, sizeof(nat)); @@ -1296,12 +1317,8 @@ binatrule : no BINAT interface af proto FROM address TO ipspec redirection { struct pf_binat binat; - if (rulestate > PFCTL_STATE_NAT) { - yyerror("Rules must be in order: " - "scrub, nat, filter"); + if (check_rulestate(PFCTL_STATE_NAT)) YYERROR; - } - rulestate = PFCTL_STATE_NAT; memset(&binat, 0, sizeof(binat)); @@ -1406,12 +1423,8 @@ rdrrule : no RDR interface af proto FROM ipspec TO ipspec dport redirection { struct pf_rdr rdr; - if (rulestate > PFCTL_STATE_NAT) { - yyerror("Rules must be in order: " - "scrub, nat, filter"); + if (check_rulestate(PFCTL_STATE_NAT)) YYERROR; - } - rulestate = PFCTL_STATE_NAT; memset(&rdr, 0, sizeof(rdr)); @@ -1583,6 +1596,40 @@ route : /* empty */ { $$.addr = NULL; } ; + +timeout_spec : STRING NUMBER + { + if (pf->opts & PF_OPT_VERBOSE) + printf("set timeout %s %us\n", $1, $2); + if (check_rulestate(PFCTL_STATE_OPTION)) + YYERROR; + if (pfctl_set_timeout(pf, $1, $2) != 0) { + yyerror("unknown timeout %s", $1); + YYERROR; + } + } + ; + +timeout_list : timeout_list ',' timeout_spec + | timeout_spec + ; + +limit_spec : STRING NUMBER + { + if (pf->opts & PF_OPT_VERBOSE) + printf("set limit %s %u\n", $1, $2); + if (check_rulestate(PFCTL_STATE_OPTION)) + YYERROR; + if (pfctl_set_limit(pf, $1, $2) != 0) { + yyerror("unable to set limit %s %u", $1, $2); + YYERROR; + } + } + +limit_list : limit_list ',' limit_spec + | limit_spec + ; + %% int @@ -2056,6 +2103,17 @@ expand_rdr(struct pf_rdr *r, struct node_if *interfaces, #undef LOOP_THROUGH int +check_rulestate(int desired_state) +{ + if (rulestate > desired_state) { + yyerror("Rules must be in order: options, scrub, nat, filter"); + return (1); + } + rulestate = desired_state; + return (0); +} + +int kw_cmp(k, e) const void *k, *e; { @@ -2088,8 +2146,10 @@ lookup(char *s) { "ipv6-icmp-type", ICMP6TYPE}, { "keep", KEEP}, { "label", LABEL}, + { "limit", LIMIT}, { "log", LOG}, { "log-all", LOGALL}, + { "loginterface", LOGINTERFACE}, { "max", MAXIMUM}, { "max-mss", MAXMSS}, { "min-ttl", MINTTL}, @@ -2099,6 +2159,7 @@ lookup(char *s) { "no-df", NODF}, { "no-route", NOROUTE}, { "on", ON}, + { "optimization", OPTIMIZATION}, { "out", OUT}, { "pass", PASS}, { "port", PORT}, @@ -2112,7 +2173,9 @@ lookup(char *s) { "return-rst", RETURNRST}, { "route-to", ROUTETO}, { "scrub", SCRUB}, + { "set", SET}, { "state", STATE}, + { "timeout", TIMEOUT}, { "to", TO}, { "ttl", TTL}, { "user", USER}, diff --git a/sbin/pfctl/pfctl.8 b/sbin/pfctl/pfctl.8 index e2175b12f8a..7abe7e5687b 100644 --- a/sbin/pfctl/pfctl.8 +++ b/sbin/pfctl/pfctl.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: pfctl.8,v 1.49 2002/06/11 06:49:19 kjell Exp $ +.\" $OpenBSD: pfctl.8,v 1.50 2002/06/25 08:13:25 henning Exp $ .\" .\" Copyright (c) 2001 Kjell Wooding. All rights reserved. .\" @@ -126,69 +126,21 @@ Example: .Ed .It Fl h Help. -.It Fl l Ar interface -Enable collection of packet and byte count statistics for interface named -.Ar interface . -These statistics can be viewed with the -.Fl s Ar info -option. -.It Fl m Ar modifier -Gets or sets hard limits on the memory pools used by the packet filter. -See -.Xr pool 9 -for an explanation of memory pools. -The modifier has the form name[=limit], where name specifies one of the -following pools and limit is either a positive integer (maximum number -of pool entries) or the string "inf" (removes the limit): -.Bl -tag -width "m states[=limit] " -compact -.It Fl m Ar states[=limit] -Maximum number of entries in the memory pool used by state table -entries (generated by 'keep state' rules). -.It Fl m Ar frags[=limit] -Maximum number of entries in the memory pool used for fragment -caching (generated by 'scrub' rules). -.It Fl m Ar all -Display all maxima, cannot be set. -.El .It Fl n Do not actually load rules, just parse them. .It Fl N -Load only the NAT rules present in the rule file. Filter rules are +Load only the NAT rules present in the rule file. Filter rules and options are ignored -.It Fl O Ar modifier -Optimize the engine to one of the following network topographies or -environments: -.Bl -tag -width "O high-latency " -compact -.It Fl O Ar default -A normal network environment. -Suitable for almost all networks. -.It Fl O Ar normal -Alias for -.Em default -.It Fl O Ar high-latency -A high-latency environment (such as a satellite connection) -.It Fl O Ar satellite -Alias for -.Em high-latency -.It Fl O Ar aggressive -Aggressively expire connections when they are likely no longer valid. -This can greatly reduce the memory usage of the firewall at the cost of -dropping idle connections early. -.It Fl O Ar conservative -Extremely conservative settings. -Pains will be taken to avoid dropping legitimate connections at the -expense of greater memory utilization (possibly much greater on a busy -network) and slightly increased processor utilization. -.El -Currently the optimizations only encompass the state table timeouts but much -more is planned in future revisions of the finite state machines (FSMs). .It Fl q Only print errors and warnings. .It Fl r Perform reverse DNS lookups on states when displaying them. .It Fl R -Load only the filter rules present in the rule file. NAT rules are +Load only the filter rules present in the rule file. NAT rules and options are ignored. +.It Fl O +Load only the options present in the rule file. Filter and NAT rules are +ignored .It Fl s Ar modifier Show filter parameters. Modifier names may be abbreviated: @@ -211,79 +163,13 @@ Show filter information (statistics and counters). .It Fl s Ar labels Show per-rule statistics (in terse format) of filter rules with labels, useful for accounting. +.It Fl s Ar timeouts +Show the current global timeouts. +.It Fl s Ar memory +Show the current pool memory hard limits. .It Fl s Ar all Show all of the above. .El -.It Fl t Ar modifier -Get a timeout or interval value. -Any of the modifiers may be set, with the exception of -.Em all , -by appending =<seconds> to the modifier without any whitespace seperating -the modifier, the equals and the number of seconds. -.Bl -tag -width "t interval " -compact -.It Fl t Ar all -Display all timeouts and intervals. -.It Fl t Ar interval -Interval between purging expired states and fragments. -.It Fl t Ar frag -Seconds before an unassembled fragment is expired. -.El -.Pp -When a packet matches a stateful connection, the seconds to live of the -connection will be updated to that of the proto.modifier which corresponds -to the connection state. -Each packet which matches this state will reset the TTL. -Tuning these values may improve the performance of the -firewall at the risk of dropping valid idled connections. -.Bl -tag -width "t tcp.established " -compact -.It Fl t Ar tcp.first -The state after the first packet. -.It Fl t Ar tcp.opening -The state before the destination host ever sends a packet. -.It Fl t Ar tcp.established -The fully established state. -.It Fl t Ar tcp.closing -The state after the first FIN has been sent. -.It Fl t Ar tcp.finwait -The state after both FINs have been exchanged and the connection is closed. -Some hosts (notably web servers on Solaris) send TCP packets even after closing -the connection. -Increasing tcp.finwait (and possibly tcp.closing) can prevent blocking of -such packets. -.It Fl t Ar tcp.closed -The state after one endpoint sends a RST. -.El -.Pp -ICMP and UDP are handled in a similar fashion to TCP but with a much more -limited set of states: -.Bl -tag -width "t udp.multiple " -compact -.It Fl t Ar udp.first -The state after the first packet. -.It Fl t Ar udp.single -The state if the source host sends more than one packet but the destination -host has never sent one back. -.It Fl t Ar udp.multiple -The state if both hosts have sent packets. -.It Fl t Ar icmp.first -The state after the first packet. -.It Fl t Ar icmp.error -The state after an icmp error came back in response to an icmp packet. -.El -.Pp -Other protocols are handled similarly to UDP: -.Bl -tag -width "t other.multiple " -compact -.It Fl t Ar other.first -.It Fl t Ar other.single -.It Fl t Ar other.multiple -.El -.Bd -literal -Example: - Timeout established connections after an hour of inactivity - # pfctl -t tcp.established=3600 - - Display the current established idle timeout - # pfctl -t tcp.established -.Ed .It Fl v Produce more verbose output. .It Fl x Ar level diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c index cfd99313bba..dd792d6c0b8 100644 --- a/sbin/pfctl/pfctl.c +++ b/sbin/pfctl/pfctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl.c,v 1.80 2002/06/14 17:31:30 henning Exp $ */ +/* $OpenBSD: pfctl.c,v 1.81 2002/06/25 08:13:26 henning Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -60,30 +60,20 @@ int pfctl_clear_rules(int, int); int pfctl_clear_nat(int, int); int pfctl_clear_states(int, int); int pfctl_kill_states(int, int); -int pfctl_hint(int, const char *, int); int pfctl_show_rules(int, int, int); int pfctl_show_nat(int); int pfctl_show_states(int, u_int8_t, int); int pfctl_show_status(int); +int pfctl_show_timeouts(int); +int pfctl_show_limits(int); int pfctl_rules(int, char *, int); -int pfctl_log(int, char *, int); -int pfctl_timeout(int, char *); -int pfctl_gettimeout(int, const char *); -int pfctl_settimeout(int, const char *, int); -int pfctl_limit(int, char *, int); -int pfctl_getlimit(int, const char *); -int pfctl_setlimit(int, const char *, unsigned int); int pfctl_debug(int, u_int32_t, int); int pfctl_clear_rule_counters(int, int); int opts = 0; char *clearopt; -char *hintopt; -char *logopt; char *rulesopt; char *showopt; -char *timeoutopt; -char *limitopt; char *debugopt; int state_killers; char *state_kill[2]; @@ -159,11 +149,10 @@ usage(void) { extern char *__progname; - fprintf(stderr, "usage: %s [-deqhnrvz] [-f file] ", __progname); - fprintf(stderr, "[-F modifier] [-k host] [-l interface]\n"); + fprintf(stderr, "usage: %s [-deqhnNrROvz] [-f file] ", __progname); + fprintf(stderr, "[-F modifier] [-k host]\n"); fprintf(stderr, " "); - fprintf(stderr, "[-m modifier] [-O level] [-s modifier] "); - fprintf(stderr, "[-t modifier] [-x level]\n"); + fprintf(stderr, "[-s modifier] [-x level]\n"); exit(1); } @@ -496,6 +485,41 @@ pfctl_show_status(int dev) return (0); } +int +pfctl_show_timeouts(int dev) +{ + struct pfioc_tm pt; + int i; + + for (i = 0; pf_timeouts[i].name; i++) { + pt.timeout = pf_timeouts[i].timeout; + if (ioctl(dev, DIOCGETTIMEOUT, &pt)) + err(1, "DIOCGETTIMEOUT"); + printf("%-20s %10ds\n", pf_timeouts[i].name, pt.seconds); + } + return (0); + +} + +int +pfctl_show_limits(int dev) +{ + struct pfioc_limit pl; + int i; + + for (i = 0; pf_limits[i].name; i++) { + pl.index = i; + if (ioctl(dev, DIOCGETLIMIT, &pl)) + err(1, "DIOCGETLIMIT"); + printf("%-10s ", pf_limits[i].name); + if (pl.limit == UINT_MAX) + printf("unlimited\n"); + else + printf("hard limit %6u\n", pl.limit); + } + return (0); +} + /* callbacks for rule/nat/rdr */ int @@ -629,214 +653,104 @@ pfctl_rules(int dev, char *filename, int opts) } int -pfctl_log(int dev, char *ifname, int opts) +pfctl_set_limit(struct pfctl *pf, const char *opt, unsigned int limit) { - struct pfioc_if pi; - - strlcpy(pi.ifname, ifname, sizeof(pi.ifname)); - if (ioctl(dev, DIOCSETSTATUSIF, &pi)) - err(1, "DIOCSETSTATUSIF"); - if ((opts & PF_OPT_QUIET) == 0) - fprintf(stderr, "now logging %s\n", pi.ifname); - return (0); -} - -int -pfctl_hint(int dev, const char *opt, int opts) -{ - const struct pf_hint *hint; - int i, r; - - for (i = 0; pf_hints[i].name; i++) - if (strcasecmp(opt, pf_hints[i].name) == 0) - break; - - hint = pf_hints[i].hint; - if (hint == NULL) { - warnx("Bad hint name. Format -O hint"); - return (1); - } - - for (i = 0; hint[i].name; i++) - if ((r = pfctl_settimeout(dev, hint[i].name, hint[i].timeout))) - return (r); - return (0); -} + struct pfioc_limit pl; + int i; -int -pfctl_limit(int dev, char *opt, int opts) -{ - char *arg, *serr = NULL; - unsigned int limit; - - arg = strchr(opt, '='); - if (arg == NULL) - return pfctl_getlimit(dev, opt); - else { - if (*arg) - *arg++ = 0; - if (strcasecmp(arg, "inf") == 0) - limit = UINT_MAX; - else { - limit = strtol(arg, &serr, 10); - if (*serr || !*arg) { - warnx("Bad limit argument. " - "Format -m name=limit"); - return (1); + if ((loadopt & (PFCTL_FLAG_OPTION | PFCTL_FLAG_ALL)) != 0) { + for (i = 0; pf_limits[i].name; i++) { + if (strcasecmp(opt, pf_limits[i].name) == 0) { + pl.index = i; + pl.limit = limit; + if ((pf->opts & PF_OPT_NOACTION) == 0) { + if (ioctl(pf->dev, DIOCSETLIMIT, &pl)) { + if (errno == EBUSY) { + warnx("Current pool " + "size exceeds " + "exceeds requested " + " hard limit"); + return (1); + } else + err(1, "DIOCSETLIMIT"); + } + } + break; } } - return pfctl_setlimit(dev, opt, limit); - } -} - -int -pfctl_getlimit(int dev, const char *opt) -{ - struct pfioc_limit pl; - int i, found = 0; - - for (i = 0; pf_limits[i].name; i++) { - if (strcmp(opt, "all") == 0 || - strcasecmp(opt, pf_limits[i].name) == 0) { - found = 1; - pl.index = i; - if (ioctl(dev, DIOCGETLIMIT, &pl)) - err(1, "DIOCGETLIMIT"); - printf("%-10s ", pf_limits[i].name); - if (pl.limit == UINT_MAX) - printf("unlimited\n"); - else - printf("hard limit %6u\n", pl.limit); + if (pf_limits[i].name == NULL) { + warnx("Bad pool name."); + return (1); } } - if (found == 0) { - warnx("Bad pool name. Format -m name[=<limit>]"); - return (1); - } return (0); } int -pfctl_setlimit(int dev, const char *opt, unsigned int limit) +pfctl_set_timeout(struct pfctl *pf, const char *opt, int seconds) { - struct pfioc_limit pl; + struct pfioc_tm pt; int i; - for (i = 0; pf_limits[i].name; i++) { - if (strcasecmp(opt, pf_limits[i].name) == 0) { - pl.index = i; - pl.limit = limit; - if (ioctl(dev, DIOCSETLIMIT, &pl)) { - if (errno == EBUSY) { - warnx("Current pool size exceeds " - "requested hard limit"); - return (1); - } else - err(1, "DIOCSETLIMIT"); - } - if ((opts & PF_OPT_QUIET) == 0) { - printf("%s ", pf_limits[i].name); - if (pl.limit == UINT_MAX) - printf("unlimited"); - else - printf("hard limit %u", pl.limit); - printf(" -> "); - if (limit == UINT_MAX) - printf("unlimited"); - else - printf("hard limit %u", limit); - printf("\n"); + if ((loadopt & (PFCTL_FLAG_OPTION | PFCTL_FLAG_ALL)) != 0) { + for (i = 0; pf_timeouts[i].name; i++) { + if (strcasecmp(opt, pf_timeouts[i].name) == 0) { + pt.timeout = pf_timeouts[i].timeout; + break; } - break; } - } - if (pf_limits[i].name == NULL) { - warnx("Bad pool name. Format -m name[=<limit>]"); - return (1); - } - return (0); -} -int -pfctl_timeout(int dev, char *opt) -{ - char *seconds, *serr = NULL; - int setval; - - seconds = strchr(opt, '='); - if (seconds == NULL) - return pfctl_gettimeout(dev, opt); - else { - /* Set the timeout value */ - if (*seconds != '\0') - *seconds++ = '\0'; /* Eat '=' */ - setval = strtol(seconds, &serr, 10); - if (*serr != '\0' || *seconds == '\0' || setval < 0) { - warnx("Bad timeout argument. Format -t name=seconds"); + if (pf_timeouts[i].name == NULL) { + warnx("Bad timeout name."); return (1); } - return pfctl_settimeout(dev, opt, setval); + + pt.seconds = seconds; + if ((pf->opts & PF_OPT_NOACTION) == 0) { + if (ioctl(pf->dev, DIOCSETTIMEOUT, &pt)) + err(1, "DIOCSETTIMEOUT"); + } } + return (0); } int -pfctl_gettimeout(int dev, const char *opt) +pfctl_set_optimization(struct pfctl *pf, const char *opt) { - struct pfioc_tm pt; - int i; + const struct pf_hint *hint; + int i, r; - for (i = 0; pf_timeouts[i].name; i++) { - if (strcmp(opt, "all") == 0) { - /* Need to dump all of the values */ - pt.timeout = pf_timeouts[i].timeout; - if (ioctl(dev, DIOCGETTIMEOUT, &pt)) - err(1, "DIOCGETTIMEOUT"); - printf("%-20s %ds\n", pf_timeouts[i].name, pt.seconds); - } else if (strcasecmp(opt, pf_timeouts[i].name) == 0) { - pt.timeout = pf_timeouts[i].timeout; - break; + if ((loadopt & (PFCTL_FLAG_OPTION | PFCTL_FLAG_ALL)) != 0) { + for (i = 0; pf_hints[i].name; i++) + if (strcasecmp(opt, pf_hints[i].name) == 0) + break; + + hint = pf_hints[i].hint; + if (hint == NULL) { + warnx("Bad hint name."); + return (1); } - } - if (strcmp(opt, "all") == 0) - return (0); - if (pf_timeouts[i].name == NULL) { - warnx("Bad timeout name. Format -t name[=<seconds>]"); - return (1); + for (i = 0; hint[i].name; i++) + if ((r = pfctl_set_timeout(pf, hint[i].name, + hint[i].timeout))) + return (r); } - - if (ioctl(dev, DIOCGETTIMEOUT, &pt)) - err(1, "DIOCGETTIMEOUT"); - if ((opts & PF_OPT_QUIET) == 0) - printf("%s timeout %ds\n", pf_timeouts[i].name, - pt.seconds); return (0); } int -pfctl_settimeout(int dev, const char *opt, int seconds) +pfctl_set_logif(struct pfctl *pf, char *ifname) { - struct pfioc_tm pt; - int i; + struct pfioc_if pi; - for (i = 0; pf_timeouts[i].name; i++) { - if (strcasecmp(opt, pf_timeouts[i].name) == 0) { - pt.timeout = pf_timeouts[i].timeout; - break; + if ((loadopt & (PFCTL_FLAG_OPTION | PFCTL_FLAG_ALL)) != 0) { + if ((pf->opts & PF_OPT_NOACTION) == 0) { + strlcpy(pi.ifname, ifname, sizeof(pi.ifname)); + if (ioctl(pf->dev, DIOCSETSTATUSIF, &pi)) + return (1); } } - - if (pf_timeouts[i].name == NULL) { - warnx("Bad timeout name. Format -t name[=<seconds>]"); - return (1); - } - - pt.seconds = seconds; - if (ioctl(dev, DIOCSETTIMEOUT, &pt)) - err(1, "DIOCSETTIMEOUT"); - if ((opts & PF_OPT_QUIET) == 0) - fprintf(stderr, "%s timeout %ds -> %ds\n", pf_timeouts[i].name, - pt.seconds, seconds); return (0); } @@ -887,7 +801,7 @@ main(int argc, char *argv[]) if (argc < 2) usage(); - while ((ch = getopt(argc, argv, "deqf:F:hk:l:m:nNO:rRs:St:vx:z")) != -1) { + while ((ch = getopt(argc, argv, "deqf:F:hk:nNOrRs:Svx:z")) != -1) { switch (ch) { case 'd': opts |= PF_OPT_DISABLE; @@ -913,15 +827,6 @@ main(int argc, char *argv[]) state_kill[state_killers++] = optarg; mode = O_RDWR; break; - case 'l': - logopt = optarg; - mode = O_RDWR; - break; - case 'm': - limitopt = optarg; - if (strchr(limitopt, '=') != NULL) - mode = O_RDWR; - break; case 'n': opts |= PF_OPT_NOACTION; break; @@ -929,10 +834,6 @@ main(int argc, char *argv[]) loadopt &= ~PFCTL_FLAG_ALL; loadopt |= PFCTL_FLAG_NAT; break; - case 'O': - hintopt = optarg; - mode = O_RDWR; - break; case 'r': opts |= PF_OPT_USEDNS; break; @@ -944,14 +845,13 @@ main(int argc, char *argv[]) loadopt &= ~PFCTL_FLAG_ALL; loadopt |= PFCTL_FLAG_FILTER; break; + case 'O': + loadopt &= ~PFCTL_FLAG_ALL; + loadopt |= PFCTL_FLAG_OPTION; + break; case 's': showopt = optarg; break; - case 't': - timeoutopt = optarg; - if (strchr(timeoutopt, '=') != NULL) - mode = O_RDWR; - break; case 'v': opts |= PF_OPT_VERBOSE; break; @@ -986,7 +886,7 @@ main(int argc, char *argv[]) } else { /* turn off options */ opts &= ~ (PF_OPT_DISABLE | PF_OPT_ENABLE); - clearopt = logopt = showopt = debugopt = NULL; + clearopt = showopt = debugopt = NULL; } if (opts & PF_OPT_DISABLE) @@ -1042,12 +942,20 @@ main(int argc, char *argv[]) case 'i': pfctl_show_status(dev); break; + case 't': + pfctl_show_timeouts(dev); + break; + case 'm': + pfctl_show_limits(dev); + break; case 'a': pfctl_show_rules(dev, opts, 0); pfctl_show_nat(dev); pfctl_show_states(dev, 0, opts); pfctl_show_status(dev); pfctl_show_rules(dev, opts, 1); + pfctl_show_timeouts(dev); + pfctl_show_limits(dev); break; default: warnx("Unknown show modifier '%s'", showopt); @@ -1055,22 +963,6 @@ main(int argc, char *argv[]) } } - if (logopt != NULL) - if (pfctl_log(dev, logopt, opts)) - error = 1; - - if (hintopt != NULL) - if (pfctl_hint(dev, hintopt, opts)) - error = 1; - - if (timeoutopt != NULL) - if (pfctl_timeout(dev, timeoutopt)) - error = 1; - - if (limitopt != NULL) - if (pfctl_limit(dev, limitopt, opts)) - error = 1; - if (opts & PF_OPT_ENABLE) if (pfctl_enable(dev, opts)) error = 1; diff --git a/sbin/pfctl/pfctl_parser.h b/sbin/pfctl/pfctl_parser.h index a0aa02c7105..c0967965d84 100644 --- a/sbin/pfctl/pfctl_parser.h +++ b/sbin/pfctl/pfctl_parser.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl_parser.h,v 1.24 2002/06/11 06:12:15 kjell Exp $ */ +/* $OpenBSD: pfctl_parser.h,v 1.25 2002/06/25 08:13:26 henning Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -68,6 +68,11 @@ int pfctl_add_nat(struct pfctl *, struct pf_nat *); int pfctl_add_binat(struct pfctl *, struct pf_binat *); int pfctl_add_rdr(struct pfctl *, struct pf_rdr *); +int pfctl_set_timeout(struct pfctl *, const char *, int); +int pfctl_set_optimization(struct pfctl *, const char *); +int pfctl_set_limit(struct pfctl *, const char *, unsigned int); +int pfctl_set_logif(struct pfctl *, char *); + int parse_rules(FILE *, struct pfctl *); int parse_flags(char *); @@ -103,6 +108,7 @@ struct pf_timeout { #define PFCTL_FLAG_ALL 0x01 #define PFCTL_FLAG_FILTER 0x02 #define PFCTL_FLAG_NAT 0x04 +#define PFCTL_FLAG_OPTION 0x08 extern const struct pf_timeout pf_timeouts[]; |