diff options
author | Max Laier <mlaier@FreeBSD.org> | 2008-12-10 20:59:26 +0000 |
---|---|---|
committer | Max Laier <mlaier@FreeBSD.org> | 2008-12-10 20:59:26 +0000 |
commit | a13f3058fbd67e3bbda784171bacc8343faf6edf (patch) | |
tree | 195f9e255fb6bd332eeb80b937ecc4ed01f9ae96 | |
parent | b39deb12b639171038aee6f8770d9bbd44c34fd1 (diff) |
Import OPENBSD_4_3_BASEvendor/pf/4.3
Notes
Notes:
svn path=/vendor/pf/dist/; revision=185880
svn path=/vendor/pf/4.3/; revision=185881; tag=vendor/pf/4.3
-rw-r--r-- | authpf/Makefile | 6 | ||||
-rw-r--r-- | authpf/authpf.8 | 97 | ||||
-rw-r--r-- | authpf/authpf.c | 227 | ||||
-rw-r--r-- | authpf/pathnames.h | 3 | ||||
-rw-r--r-- | ftp-proxy/filter.c | 13 | ||||
-rw-r--r-- | ftp-proxy/ftp-proxy.8 | 24 | ||||
-rw-r--r-- | ftp-proxy/ftp-proxy.c | 5 | ||||
-rw-r--r-- | man/pf.4 | 17 | ||||
-rw-r--r-- | man/pf.conf.5 | 53 | ||||
-rw-r--r-- | man/pfsync.4 | 8 | ||||
-rw-r--r-- | pfctl/parse.y | 1026 | ||||
-rw-r--r-- | pfctl/pf_print_state.c | 18 | ||||
-rw-r--r-- | pfctl/pfctl.c | 39 | ||||
-rw-r--r-- | pfctl/pfctl.h | 5 | ||||
-rw-r--r-- | pfctl/pfctl_altq.c | 13 | ||||
-rw-r--r-- | pfctl/pfctl_optimize.c | 13 | ||||
-rw-r--r-- | pfctl/pfctl_parser.c | 4 | ||||
-rw-r--r-- | pfctl/pfctl_parser.h | 6 | ||||
-rw-r--r-- | pfctl/pfctl_qstats.c | 6 | ||||
-rw-r--r-- | pfctl/pfctl_radix.c | 51 | ||||
-rw-r--r-- | pflogd/pflogd.8 | 15 |
21 files changed, 1059 insertions, 590 deletions
diff --git a/authpf/Makefile b/authpf/Makefile index 3e0538a8d233..100001a0a744 100644 --- a/authpf/Makefile +++ b/authpf/Makefile @@ -1,7 +1,11 @@ -# $OpenBSD: Makefile,v 1.12 2004/04/25 19:24:52 deraadt Exp $ +# $OpenBSD: Makefile,v 1.13 2008/02/14 01:49:17 mcbride Exp $ PROG= authpf MAN= authpf.8 + +LINKS= ${BINDIR}/authpf ${BINDIR}/authpf-noip +MLINKS+=authpf.8 authpf-noip.8 + BINOWN= root BINGRP= authpf BINMODE= 6555 diff --git a/authpf/authpf.8 b/authpf/authpf.8 index 566d3a9627c6..be1f0c46fde8 100644 --- a/authpf/authpf.8 +++ b/authpf/authpf.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: authpf.8,v 1.44 2007/05/31 19:20:22 jmc Exp $ +.\" $OpenBSD: authpf.8,v 1.45 2008/02/14 01:49:17 mcbride Exp $ .\" .\" Copyright (c) 1998-2007 Bob Beck (beck@openbsd.org>. All rights reserved. .\" @@ -14,14 +14,16 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate$ +.Dd $Mdocdate: May 31 2007 $ .Dt AUTHPF 8 .Os .Sh NAME -.Nm authpf +.Nm authpf , +.Nm authpf-noip .Nd authenticating gateway user shell .Sh SYNOPSIS .Nm authpf +.Nm authpf-noip .Sh DESCRIPTION .Nm is a user shell for authenticating gateways. @@ -30,43 +32,63 @@ It is used to change rules when a user authenticates and starts a session with .Xr sshd 8 and to undo these changes when the user's session exits. -It is designed for changing filter and translation rules for an individual -source IP address as long as a user maintains an active -.Xr ssh 1 -session. Typical use would be for a gateway that authenticates users before allowing them Internet use, or a gateway that allows different users into different places. +Combined with properly set up filter rules and secure switches, .Nm -logs the successful start and end of a session to -.Xr syslogd 8 . -This, combined with properly set up filter rules and secure switches, can be used to ensure users are held accountable for their network traffic. -.Pp -.Nm -can add filter and translation rules using the syntax described in -.Xr pf.conf 5 . -.Nm -requires that the +It is meant to be used with users who can connect via +.Xr ssh 1 +only, and requires the .Xr pf 4 -system be enabled before use. +subsystem to be enabled. +.Pp +.Nm authpf-noip +is a user shell +which allows multiple connections to take +place from the same IP address. +It is useful primarily in cases where connections are tunneled via +the gateway system, and can be directly associated with the user name. +It cannot ensure accountability when +classifying connections by IP address; +in this case the client's IP address +is not provided to the packet filter via the +.Ar client_ip +macro or the +.Ar authpf users +table. +Additionally, states associated with the client IP address +are not purged when the session is ended. +.Pp +To use either .Nm -can also maintain the list of IP address of connected users -in the "authpf_users" -.Pa table . +or +.Nm authpf-noip , +the user's shell needs to be set to +.Pa /usr/sbin/authpf +or +.Pa /usr/sbin/authpf-noip . .Pp .Nm -is meant to be used with users who can connect via +uses the +.Xr pf.conf 5 +syntax to change filter and translation rules for an individual +user or client IP address as long as a user maintains an active .Xr ssh 1 -only. -On startup, +session, and logs the successful start and end of a session to +.Xr syslogd 8 . .Nm retrieves the client's connecting IP address via the .Ev SSH_CLIENT environment variable and, after performing additional access checks, reads a template file to determine what filter and translation rules -(if any) to add. -On session exit the same rules that were added at startup are removed. +(if any) to add, and +maintains the list of IP addresses of connected users in the +.Ar authpf_users +table. +On session exit the same rules and table entries that were added at startup +are removed, and all states associated with the client's IP address are purged. .Pp Each .Nm @@ -496,6 +518,31 @@ table <authpf_users> persist anchor "authpf/*" from <authpf_users> rdr-anchor "authpf/*" from <authpf_users> .Ed +.Pp +.Sy Tunneled users +\- normally +.Nm +allows only one session per client IP address. +However in some cases, such as when connections are tunneled via +.Xr ssh 1 +or +.Xr ipsec 4 , +the connections can be authorized based on the userid of the user instead of +the client IP address. +In this case it is appropriate to use +.Nm authpf-noip +to allow multiple users behind a NAT gateway to connect. +In the +.Pa /etc/authpf/authpf.rules +example below, the remote user could tunnel a remote desktop session to their +workstation: +.Bd -literal +internal_if="bge0" +workstation_ip="10.2.3.4" + +pass out on $internal_if from (self) to $workstation_ip port 3389 \e + user $user_id +.Ed .Sh FILES .Bl -tag -width "/etc/authpf/authpf.conf" -compact .It Pa /etc/authpf/authpf.conf diff --git a/authpf/authpf.c b/authpf/authpf.c index 68adcd258eef..1416b0db917f 100644 --- a/authpf/authpf.c +++ b/authpf/authpf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: authpf.c,v 1.104 2007/02/24 17:35:08 beck Exp $ */ +/* $OpenBSD: authpf.c,v 1.107 2008/02/14 01:49:17 mcbride Exp $ */ /* * Copyright (C) 1998 - 2007 Bob Beck (beck@openbsd.org). @@ -46,6 +46,7 @@ static void print_message(char *); static int allowed_luser(char *); static int check_luser(char *, char *); static int remove_stale_rulesets(void); +static int recursive_ruleset_purge(char *, char *); static int change_filter(int, const char *, const char *); static int change_table(int, const char *); static void authpf_kill_states(void); @@ -54,6 +55,7 @@ int dev; /* pf device */ char anchorname[PF_ANCHOR_NAME_SIZE] = "authpf"; char rulesetname[MAXPATHLEN - PF_ANCHOR_NAME_SIZE - 2]; char tablename[PF_TABLE_NAME_SIZE] = "authpf_users"; +int user_ip = 1; /* controls whether $user_ip is set */ FILE *pidfp; char luser[MAXLOGNAME]; /* username */ @@ -65,6 +67,7 @@ struct timeval Tstart, Tend; /* start and end times of session */ volatile sig_atomic_t want_death; static void need_death(int signo); static __dead void do_death(int); +extern char *__progname; /* program name */ /* * User shell for authenticating gateways. Sole purpose is to allow @@ -85,6 +88,9 @@ main(int argc, char *argv[]) char *shell; login_cap_t *lc; + if (strcmp(__progname, "-authpf-noip") == 0) + user_ip = 0; + config = fopen(PATH_CONFFILE, "r"); if (config == NULL) { syslog(LOG_ERR, "can not open %s (%m)", PATH_CONFFILE); @@ -139,7 +145,8 @@ main(int argc, char *argv[]) login_close(lc); - if (strcmp(shell, PATH_AUTHPF_SHELL)) { + if (strcmp(shell, PATH_AUTHPF_SHELL) && + strcmp(shell, PATH_AUTHPF_SHELL_NOIP)) { syslog(LOG_ERR, "wrong shell for user %s, uid %u", pw->pw_name, pw->pw_uid); if (shell != pw->pw_shell) @@ -171,8 +178,9 @@ main(int argc, char *argv[]) } - /* Make our entry in /var/authpf as /var/authpf/ipaddr */ - n = snprintf(pidfile, sizeof(pidfile), "%s/%s", PATH_PIDFILE, ipsrc); + /* Make our entry in /var/authpf as ipaddr or username */ + n = snprintf(pidfile, sizeof(pidfile), "%s/%s", + PATH_PIDFILE, user_ip ? ipsrc : luser); if (n < 0 || (u_int)n >= sizeof(pidfile)) { syslog(LOG_ERR, "path to pidfile too long"); goto die; @@ -292,7 +300,7 @@ main(int argc, char *argv[]) printf("Unable to modify filters\r\n"); do_death(0); } - if (change_table(1, ipsrc) == -1) { + if (user_ip && change_table(1, ipsrc) == -1) { printf("Unable to modify table\r\n"); change_filter(0, luser, ipsrc); do_death(0); @@ -349,6 +357,8 @@ read_config(FILE *f) } i++; len = strlen(buf); + if (len == 0) + continue; if (buf[len - 1] != '\n' && !feof(f)) { syslog(LOG_ERR, "line %d too long in %s", i, PATH_CONFFILE); @@ -569,7 +579,7 @@ static int remove_stale_rulesets(void) { struct pfioc_ruleset prs; - u_int32_t nr, mnr; + u_int32_t nr; memset(&prs, 0, sizeof(prs)); strlcpy(prs.path, anchorname, sizeof(prs.path)); @@ -580,13 +590,12 @@ remove_stale_rulesets(void) return (1); } - mnr = prs.nr; - nr = 0; - while (nr < mnr) { + nr = prs.nr; + while (nr) { char *s, *t; pid_t pid; - prs.nr = nr; + prs.nr = nr - 1; if (ioctl(dev, DIOCGETRULESET, &prs)) return (1); errno = 0; @@ -598,111 +607,156 @@ remove_stale_rulesets(void) if (!prs.name[0] || errno || (*s && (t == prs.name || *s != ')'))) return (1); - if (kill(pid, 0) && errno != EPERM) { - int i; - struct pfioc_trans_e t_e[PF_RULESET_MAX+1]; - struct pfioc_trans t; - - bzero(&t, sizeof(t)); - bzero(t_e, sizeof(t_e)); - t.size = PF_RULESET_MAX+1; - t.esize = sizeof(t_e[0]); - t.array = t_e; - for (i = 0; i < PF_RULESET_MAX+1; ++i) { - t_e[i].rs_num = i; - snprintf(t_e[i].anchor, sizeof(t_e[i].anchor), - "%s/%s", anchorname, prs.name); - } - t_e[PF_RULESET_MAX].rs_num = PF_RULESET_TABLE; - if ((ioctl(dev, DIOCXBEGIN, &t) || - ioctl(dev, DIOCXCOMMIT, &t)) && - errno != EINVAL) + if ((kill(pid, 0) && errno != EPERM) || pid == getpid()) { + if (recursive_ruleset_purge(anchorname, prs.name)) return (1); - mnr--; - } else - nr++; + } + nr--; } return (0); } +static int +recursive_ruleset_purge(char *an, char *rs) +{ + struct pfioc_trans_e *t_e = NULL; + struct pfioc_trans *t = NULL; + struct pfioc_ruleset *prs = NULL; + int i; + + + /* purge rules */ + errno = 0; + if ((t = calloc(1, sizeof(struct pfioc_trans))) == NULL) + goto no_mem; + if ((t_e = calloc(PF_RULESET_MAX+1, + sizeof(struct pfioc_trans_e))) == NULL) + goto no_mem; + t->size = PF_RULESET_MAX+1; + t->esize = sizeof(struct pfioc_trans_e); + t->array = t_e; + for (i = 0; i < PF_RULESET_MAX+1; ++i) { + t_e[i].rs_num = i; + snprintf(t_e[i].anchor, sizeof(t_e[i].anchor), "%s/%s", an, rs); + } + t_e[PF_RULESET_MAX].rs_num = PF_RULESET_TABLE; + if ((ioctl(dev, DIOCXBEGIN, t) || + ioctl(dev, DIOCXCOMMIT, t)) && + errno != EINVAL) + goto cleanup; + + /* purge any children */ + if ((prs = calloc(1, sizeof(struct pfioc_ruleset))) == NULL) + goto no_mem; + snprintf(prs->path, sizeof(prs->path), "%s/%s", an, rs); + if (ioctl(dev, DIOCGETRULESETS, prs)) { + if (errno != EINVAL) + goto cleanup; + errno = 0; + } else { + int nr = prs->nr; + + while (nr) { + prs->nr = 0; + if (ioctl(dev, DIOCGETRULESET, prs)) + goto cleanup; + + if (recursive_ruleset_purge(prs->path, prs->name)) + goto cleanup; + nr--; + } + } + +no_mem: + if (errno == ENOMEM) + syslog(LOG_ERR, "calloc failed"); + +cleanup: + free(t); + free(t_e); + free(prs); + return (errno); +} + /* * Add/remove filter entries for user "luser" from ip "ipsrc" */ static int change_filter(int add, const char *luser, const char *ipsrc) { - char *pargv[13] = { - "pfctl", "-p", "/dev/pf", "-q", "-a", "anchor/ruleset", - "-D", "user_ip=X", "-D", "user_id=X", "-f", - "file", NULL - }; char *fdpath = NULL, *userstr = NULL, *ipstr = NULL; char *rsn = NULL, *fn = NULL; pid_t pid; gid_t gid; int s; - if (luser == NULL || !luser[0] || ipsrc == NULL || !ipsrc[0]) { - syslog(LOG_ERR, "invalid luser/ipsrc"); - goto error; - } - - if (asprintf(&rsn, "%s/%s", anchorname, rulesetname) == -1) - goto no_mem; - if (asprintf(&fdpath, "/dev/fd/%d", dev) == -1) - goto no_mem; - if (asprintf(&ipstr, "user_ip=%s", ipsrc) == -1) - goto no_mem; - if (asprintf(&userstr, "user_id=%s", luser) == -1) - goto no_mem; - if (add) { struct stat sb; + char *pargv[13] = { + "pfctl", "-p", "/dev/pf", "-q", "-a", "anchor/ruleset", + "-D", "user_id=X", "-D", "user_ip=X", "-f", "file", NULL + }; + + if (luser == NULL || !luser[0] || ipsrc == NULL || !ipsrc[0]) { + syslog(LOG_ERR, "invalid luser/ipsrc"); + goto error; + } - if (asprintf(&fn, "%s/%s/authpf.rules", PATH_USER_DIR, luser) - == -1) + if (asprintf(&rsn, "%s/%s", anchorname, rulesetname) == -1) + goto no_mem; + if (asprintf(&fdpath, "/dev/fd/%d", dev) == -1) + goto no_mem; + if (asprintf(&ipstr, "user_ip=%s", ipsrc) == -1) + goto no_mem; + if (asprintf(&userstr, "user_id=%s", luser) == -1) + goto no_mem; + if (asprintf(&fn, "%s/%s/authpf.rules", + PATH_USER_DIR, luser) == -1) goto no_mem; if (stat(fn, &sb) == -1) { free(fn); if ((fn = strdup(PATH_PFRULES)) == NULL) goto no_mem; } - } - pargv[2] = fdpath; - pargv[5] = rsn; - pargv[7] = userstr; - pargv[9] = ipstr; - if (!add) - pargv[11] = "/dev/null"; - else - pargv[11] = fn; - - switch (pid = fork()) { - case -1: - syslog(LOG_ERR, "fork failed"); - goto error; - case 0: - /* revoke group privs before exec */ - gid = getgid(); - if (setregid(gid, gid) == -1) { - err(1, "setregid"); + pargv[2] = fdpath; + pargv[5] = rsn; + pargv[7] = userstr; + if (user_ip) { + pargv[9] = ipstr; + pargv[11] = fn; + } else { + pargv[8] = "-f"; + pargv[9] = fn; + pargv[10] = NULL; } - execvp(PATH_PFCTL, pargv); - warn("exec of %s failed", PATH_PFCTL); - _exit(1); - } - /* parent */ - waitpid(pid, &s, 0); - if (s != 0) { - syslog(LOG_ERR, "pfctl exited abnormally"); - goto error; - } + switch (pid = fork()) { + case -1: + syslog(LOG_ERR, "fork failed"); + goto error; + case 0: + /* revoke group privs before exec */ + gid = getgid(); + if (setregid(gid, gid) == -1) { + err(1, "setregid"); + } + execvp(PATH_PFCTL, pargv); + warn("exec of %s failed", PATH_PFCTL); + _exit(1); + } + + /* parent */ + waitpid(pid, &s, 0); + if (s != 0) { + syslog(LOG_ERR, "pfctl exited abnormally"); + goto error; + } - if (add) { gettimeofday(&Tstart, NULL); syslog(LOG_INFO, "allowing %s, user %s", ipsrc, luser); } else { + remove_stale_rulesets(); + gettimeofday(&Tend, NULL); syslog(LOG_INFO, "removed %s, user %s - duration %ld seconds", ipsrc, luser, Tend.tv_sec - Tstart.tv_sec); @@ -819,9 +873,10 @@ do_death(int active) if (active) { change_filter(0, luser, ipsrc); - change_table(0, ipsrc); - authpf_kill_states(); - remove_stale_rulesets(); + if (user_ip) { + change_table(0, ipsrc); + authpf_kill_states(); + } } if (pidfile[0] && (pidfp != NULL)) if (unlink(pidfile) == -1) diff --git a/authpf/pathnames.h b/authpf/pathnames.h index 358bfd0c106d..e02cf77c9fe6 100644 --- a/authpf/pathnames.h +++ b/authpf/pathnames.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pathnames.h,v 1.7 2004/04/25 18:40:42 beck Exp $ */ +/* $OpenBSD: pathnames.h,v 1.8 2008/02/14 01:49:17 mcbride Exp $ */ /* * Copyright (C) 2002 Chris Kuethe (ckuethe@ualberta.ca) @@ -35,4 +35,5 @@ #define PATH_DEVFILE "/dev/pf" #define PATH_PIDFILE "/var/authpf" #define PATH_AUTHPF_SHELL "/usr/sbin/authpf" +#define PATH_AUTHPF_SHELL_NOIP "/usr/sbin/authpf-noip" #define PATH_PFCTL "/sbin/pfctl" diff --git a/ftp-proxy/filter.c b/ftp-proxy/filter.c index b33c541457aa..d99dfcbd6b17 100644 --- a/ftp-proxy/filter.c +++ b/ftp-proxy/filter.c @@ -1,4 +1,4 @@ -/* $OpenBSD: filter.c,v 1.6 2007/08/01 09:31:41 henning Exp $ */ +/* $OpenBSD: filter.c,v 1.7 2008/02/26 18:52:53 henning Exp $ */ /* * Copyright (c) 2004, 2005 Camiel Dobbelaar, <cd@sentia.nl> @@ -277,15 +277,13 @@ prepare_rule(u_int32_t id, int rs_num, struct sockaddr *src, } pfr.rule.dst.port_op = PF_OP_EQ; pfr.rule.dst.port[0] = htons(d_port); - if (tagname != NULL) - strlcpy(pfr.rule.tagname, tagname, sizeof pfr.rule.tagname); switch (rs_num) { case PF_RULESET_FILTER: /* - * pass quick [log] inet[6] proto tcp \ + * pass [quick] [log] inet[6] proto tcp \ * from $src to $dst port = $d_port flags S/SA keep state - * (max 1) [queue qname] + * (max 1) [queue qname] [tag tagname] */ pfr.rule.action = PF_PASS; pfr.rule.quick = 1; @@ -296,6 +294,11 @@ prepare_rule(u_int32_t id, int rs_num, struct sockaddr *src, pfr.rule.max_states = 1; if (qname != NULL) strlcpy(pfr.rule.qname, qname, sizeof pfr.rule.qname); + if (tagname != NULL) { + pfr.rule.quick = 0; + strlcpy(pfr.rule.tagname, tagname, + sizeof pfr.rule.tagname); + } break; case PF_RULESET_NAT: /* diff --git a/ftp-proxy/ftp-proxy.8 b/ftp-proxy/ftp-proxy.8 index d48997b05a65..30a75415c18f 100644 --- a/ftp-proxy/ftp-proxy.8 +++ b/ftp-proxy/ftp-proxy.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ftp-proxy.8,v 1.10 2007/08/01 15:45:41 jmc Exp $ +.\" $OpenBSD: ftp-proxy.8,v 1.11 2008/02/26 18:52:53 henning Exp $ .\" .\" Copyright (c) 2004, 2005 Camiel Dobbelaar, <cd@sentia.nl> .\" @@ -21,7 +21,7 @@ .Nm ftp-proxy .Nd Internet File Transfer Protocol proxy daemon .Sh SYNOPSIS -.Nm ftp-proxy +.Nm .Bk -words .Op Fl 6Adrv .Op Fl a Ar address @@ -59,7 +59,7 @@ facility for this. Assuming the FTP control connection is from $client to $server, the proxy connected to the server using the $proxy source address, and $port is negotiated, then -.Nm ftp-proxy +.Nm adds the following rules to the various anchors. (These example rules use inet, but the proxy also supports inet6.) .Pp @@ -132,9 +132,19 @@ connections to another proxy. Rewrite sourceport to 20 in active mode to suit ancient clients that insist on this RFC property. .It Fl T Ar tag -Automatically tag packets passing through the +The filter rules will add tag +.Ar tag +to data connections, and not match quick. +This way alternative rules that use the +.Ar tagged +keyword can be implemented following the +.Nm +anchor. +These rules can use special .Xr pf 4 -rule with the name supplied. +features like route-to, reply-to, label, rtable, overload, etc. that +.Nm +does not implement itself. .It Fl t Ar timeout Number of seconds that the control connection can be idle, before the proxy will disconnect. @@ -177,7 +187,7 @@ does not allow the ruleset to be modified if the system is running at a .Xr securelevel 7 higher than 1. At that level -.Nm ftp-proxy +.Nm cannot add rules to the anchors and FTP data connections may get blocked. .Pp Negotiated data connection ports below 1024 are not allowed. @@ -186,5 +196,5 @@ The negotiated IP address for active modes is ignored for security reasons. This makes third party file transfers impossible. .Pp -.Nm ftp-proxy +.Nm chroots to "/var/empty" and changes to user "proxy" to drop privileges. diff --git a/ftp-proxy/ftp-proxy.c b/ftp-proxy/ftp-proxy.c index 3a691859c329..1a3bdf55fbd2 100644 --- a/ftp-proxy/ftp-proxy.c +++ b/ftp-proxy/ftp-proxy.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ftp-proxy.c,v 1.15 2007/08/15 15:18:02 camield Exp $ */ +/* $OpenBSD: ftp-proxy.c,v 1.16 2008/02/26 18:52:53 henning Exp $ */ /* * Copyright (c) 2004, 2005 Camiel Dobbelaar, <cd@sentia.nl> @@ -1117,6 +1117,7 @@ usage(void) { fprintf(stderr, "usage: %s [-6Adrv] [-a address] [-b address]" " [-D level] [-m maxsessions]\n [-P port]" - " [-p port] [-q queue] [-R address] [-T tag] [-t timeout]\n", __progname); + " [-p port] [-q queue] [-R address] [-T tag]\n" + " [-t timeout]\n", __progname); exit(1); } @@ -1,4 +1,4 @@ -.\" $OpenBSD: pf.4,v 1.59 2007/05/31 19:19:51 jmc Exp $ +.\" $OpenBSD: pf.4,v 1.60 2007/12/02 12:08:04 pascoe Exp $ .\" .\" Copyright (C) 2001, Kjell Wooding. All rights reserved. .\" @@ -26,7 +26,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd $Mdocdate$ +.Dd $Mdocdate: May 31 2007 $ .Dt PF 4 .Os .Sh NAME @@ -292,14 +292,17 @@ if another process is concurrently updating a ruleset. Add a state entry. .Bd -literal struct pfioc_state { - u_int32_t nr; - struct pf_state state; + struct pfsync_state state; }; .Ed .It Dv DIOCGETSTATE Fa "struct pfioc_state *ps" -Extract the entry with the specified number -.Va nr -from the state table. +Extract the entry identified by the +.Va id +and +.Va creatorid +fields of the +.Va state +structure from the state table. .It Dv DIOCKILLSTATES Fa "struct pfioc_state_kill *psk" Remove matching entries from the state table. This ioctl returns the number of killed states in diff --git a/man/pf.conf.5 b/man/pf.conf.5 index b6b609e733cb..7624dc074050 100644 --- a/man/pf.conf.5 +++ b/man/pf.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: pf.conf.5,v 1.383 2007/07/17 16:27:38 jmc Exp $ +.\" $OpenBSD: pf.conf.5,v 1.393 2008/02/11 07:46:32 jmc Exp $ .\" .\" Copyright (c) 2002, Daniel Hartmeier .\" All rights reserved. @@ -27,7 +27,7 @@ .\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: June 26 2007 $ +.Dd $Mdocdate: Febuary 1 2008 $ .Dt PF.CONF 5 .Os .Sh NAME @@ -78,6 +78,17 @@ By default enforces this order (see .Ar set require-order below). +.Pp +Comments can be put anywhere in the file using a hash mark +.Pq Sq # , +and extend to the end of the current line. +.Pp +Additional configuration files can be included with the +.Ic include +keyword, for example: +.Bd -literal -offset indent +include "/etc/pf/sub.filter.conf" +.Ed .Sh MACROS Macros can be defined that will later be expanded in context. Macro names must start with a letter, and may contain letters, digits @@ -327,7 +338,8 @@ With 9000 state table entries, the timeout values are scaled to 50% (tcp.first 60, tcp.established 43200). .Pp .It Ar set loginterface -Enable collection of packet and byte count statistics for the given interface. +Enable collection of packet and byte count statistics for the given +interface or interface group. These statistics can be viewed using .Bd -literal -offset indent # pfctl -s info @@ -808,7 +820,7 @@ assigned. .Ar Priority mainly controls the time packets take to get sent out, while .Ar bandwidth -has primarily effects on throughput. +primarily affects throughput. .Ar hfsc supports both link-sharing and guaranteed real-time services. It employs a service curve based QoS model, @@ -1163,7 +1175,7 @@ or to the firewall itself. Note that redirecting external incoming connections to the loopback address, as in .Bd -literal -offset indent -rdr on ne3 inet proto tcp to port spamd -\*(Gt 127.0.0.1 port smtp +rdr on ne3 inet proto tcp to port smtp -\*(Gt 127.0.0.1 port spamd .Ed .Pp will effectively allow an external host to connect to daemons @@ -1442,6 +1454,14 @@ the route back to the packet's source address. Any address that matches the given table. .El .Pp +Ranges of addresses are specified by using the +.Sq - +operator. +For instance: +.Dq 10.1.1.10 - 10.1.1.12 +means all addresses from 10.1.1.10 to 10.1.1.12, +hence addresses 10.1.1.10, 10.1.1.11, and 10.1.1.12. +.Pp Interface names and interface group names can have modifiers appended: .Pp .Bl -tag -width xxxxxxxxxxxx -compact @@ -2023,8 +2043,8 @@ must be specified explicitly to apply options to a rule. .Bl -tag -width xxxx -compact .It Ar max Aq Ar number Limits the number of concurrent states the rule may create. -When this limit is reached, further packets matching the rule that would -create state are dropped, until existing states time out. +When this limit is reached, further packets that would create +state will not match this rule until existing states time out. .It Ar no-sync Prevent state changes for states created by this rule from appearing on the .Xr pfsync 4 @@ -2442,10 +2462,8 @@ into the anchor. .Pp Optionally, .Ar anchor -rules can specify the parameter's -direction, interface, address family, protocol and source/destination -address/port -using the same syntax as filter rules. +rules can specify packet filtering parameters using the same syntax as +filter rules. When parameters are used, the .Ar anchor rule is only evaluated for matching packets. @@ -2526,8 +2544,8 @@ anchor "external" on egress { .Ed .Pp Since the parser specification for anchor names is a string, any -reference to an anchor name containing solidus -.Pq Sq / +reference to an anchor name containing +.Sq / characters will require double quote .Pq Sq \&" characters around the anchor name. @@ -2749,10 +2767,11 @@ in BNF: .Bd -literal line = ( option | pf-rule | nat-rule | binat-rule | rdr-rule | antispoof-rule | altq-rule | queue-rule | trans-anchors | - anchor-rule | anchor-close | load-anchor | table-rule | ) + anchor-rule | anchor-close | load-anchor | table-rule | + include ) option = "set" ( [ "timeout" ( timeout | "{" timeout-list "}" ) ] | - [ "ruleset-optimization" [ "none" | "basic" | "profile" ]] | + [ "ruleset-optimization" [ "none" | "basic" | "profile" ]] | [ "optimization" [ "default" | "normal" | "high-latency" | "satellite" | "aggressive" | "conservative" ] ] @@ -2821,7 +2840,7 @@ queue-rule = "queue" string [ "on" interface-name ] queueopts-list subqueue anchor-rule = "anchor" [ string ] [ ( "in" | "out" ) ] [ "on" ifspec ] - [ af ] [ protospec ] [ hosts ] [ "{" ] + [ af ] [ protospec ] [ hosts ] [ filteropt-list ] [ "{" ] anchor-close = "}" @@ -2956,8 +2975,6 @@ Default location of OS fingerprints. Protocol name database. .It Pa /etc/services Service name database. -.It Pa /usr/share/pf -Example rulesets. .El .Sh SEE ALSO .Xr carp 4 , diff --git a/man/pfsync.4 b/man/pfsync.4 index 07f61874b6d1..027d46014d10 100644 --- a/man/pfsync.4 +++ b/man/pfsync.4 @@ -1,4 +1,4 @@ -.\" $OpenBSD: pfsync.4,v 1.25 2007/05/31 19:19:51 jmc Exp $ +.\" $OpenBSD: pfsync.4,v 1.26 2007/09/20 20:50:07 mpf Exp $ .\" .\" Copyright (c) 2002 Michael Shalayeff .\" Copyright (c) 2003-2004 Ryan McBride @@ -24,7 +24,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate$ +.Dd $Mdocdate: May 31 2007 $ .Dt PFSYNC 4 .Os .Sh NAME @@ -199,8 +199,8 @@ traffic through. The following should be added to the top of .Pa /etc/pf.conf : .Bd -literal -offset indent -pass quick on { sis2 } proto pfsync -pass on { sis0 sis1 } proto carp +pass quick on { sis2 } proto pfsync keep state (no-sync) +pass on { sis0 sis1 } proto carp keep state (no-sync) .Ed .Pp If it is preferable that one firewall handle the traffic, diff --git a/pfctl/parse.y b/pfctl/parse.y index a491f3ead7da..c41899631987 100644 --- a/pfctl/parse.y +++ b/pfctl/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.519 2007/06/21 19:30:03 henning Exp $ */ +/* $OpenBSD: parse.y,v 1.536 2008/02/01 06:58:45 mcbride Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -29,6 +29,7 @@ %{ #include <sys/types.h> #include <sys/socket.h> +#include <sys/stat.h> #include <net/if.h> #include <netinet/in.h> #include <netinet/in_systm.h> @@ -43,6 +44,7 @@ #include <altq/altq_hfsc.h> #include <stdio.h> +#include <unistd.h> #include <stdlib.h> #include <netdb.h> #include <stdarg.h> @@ -60,10 +62,7 @@ #include "pfctl.h" static struct pfctl *pf = NULL; -static FILE *fin = NULL; static int debug = 0; -static int lineno = 1; -static int errors = 0; static int rulestate = 0; static u_int16_t returnicmpdefault = (ICMP_UNREACH << 8) | ICMP_UNREACH_PORT; @@ -73,6 +72,39 @@ static int blockpolicy = PFRULE_DROP; static int require_order = 1; static int default_statelock; +TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files); +static struct file { + TAILQ_ENTRY(file) entry; + FILE *stream; + char *name; + int lineno; + int errors; +} *file; +struct file *pushfile(const char *, int); +int popfile(void); +int check_file_secrecy(int, const char *); +int yyparse(void); +int yylex(void); +int yyerror(const char *, ...); +int kw_cmp(const void *, const void *); +int lookup(char *); +int lgetc(int); +int lungetc(int); +int findeol(void); + +TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead); +struct sym { + TAILQ_ENTRY(sym) entry; + int used; + int persist; + char *nam; + char *val; +}; +int symset(const char *, const char *, int); +char *symget(const char *); + +int atoul(char *, u_long *); + enum { PFCTL_STATE_NONE, PFCTL_STATE_OPTION, @@ -199,12 +231,12 @@ struct filter_opts { char *tag; char *match_tag; u_int8_t match_tag_not; - int rtableid; + u_int rtableid; } filter_opts; struct antispoof_opts { char *label; - int rtableid; + u_int rtableid; } antispoof_opts; struct scrub_opts { @@ -218,7 +250,7 @@ struct scrub_opts { int fragcache; int randomid; int reassemble_tcp; - int rtableid; + u_int rtableid; } scrub_opts; struct queue_opts { @@ -255,61 +287,42 @@ struct pool_opts { struct node_hfsc_opts hfsc_opts; -int yyerror(const char *, ...); -int disallow_table(struct node_host *, const char *); -int disallow_urpf_failed(struct node_host *, const char *); -int disallow_alias(struct node_host *, const char *); -int rule_consistent(struct pf_rule *, int); -int filter_consistent(struct pf_rule *, int); -int nat_consistent(struct pf_rule *); -int rdr_consistent(struct pf_rule *); -int process_tabledef(char *, struct table_opts *); -int yyparse(void); -void expand_label_str(char *, size_t, const char *, const char *); -void expand_label_if(const char *, char *, size_t, const char *); -void expand_label_addr(const char *, char *, size_t, u_int8_t, - struct node_host *); -void expand_label_port(const char *, char *, size_t, struct node_port *); -void expand_label_proto(const char *, char *, size_t, u_int8_t); -void expand_label_nr(const char *, char *, size_t); -void expand_label(char *, size_t, const char *, u_int8_t, struct node_host *, - struct node_port *, struct node_host *, struct node_port *, - u_int8_t); -void expand_rule(struct pf_rule *, struct node_if *, struct node_host *, - struct node_proto *, struct node_os*, struct node_host *, - struct node_port *, struct node_host *, struct node_port *, - struct node_uid *, struct node_gid *, struct node_icmp *, - const char *); -int expand_altq(struct pf_altq *, struct node_if *, struct node_queue *, - struct node_queue_bw bwspec, struct node_queue_opt *); -int expand_queue(struct pf_altq *, struct node_if *, struct node_queue *, - struct node_queue_bw, struct node_queue_opt *); -int expand_skip_interface(struct node_if *); +int disallow_table(struct node_host *, const char *); +int disallow_urpf_failed(struct node_host *, const char *); +int disallow_alias(struct node_host *, const char *); +int rule_consistent(struct pf_rule *, int); +int filter_consistent(struct pf_rule *, int); +int nat_consistent(struct pf_rule *); +int rdr_consistent(struct pf_rule *); +int process_tabledef(char *, struct table_opts *); +void expand_label_str(char *, size_t, const char *, const char *); +void expand_label_if(const char *, char *, size_t, const char *); +void expand_label_addr(const char *, char *, size_t, u_int8_t, + struct node_host *); +void expand_label_port(const char *, char *, size_t, + struct node_port *); +void expand_label_proto(const char *, char *, size_t, u_int8_t); +void expand_label_nr(const char *, char *, size_t); +void expand_label(char *, size_t, const char *, u_int8_t, + struct node_host *, struct node_port *, struct node_host *, + struct node_port *, u_int8_t); +void expand_rule(struct pf_rule *, struct node_if *, + struct node_host *, struct node_proto *, struct node_os *, + struct node_host *, struct node_port *, struct node_host *, + struct node_port *, struct node_uid *, struct node_gid *, + struct node_icmp *, const char *); +int expand_altq(struct pf_altq *, struct node_if *, + struct node_queue *, struct node_queue_bw bwspec, + struct node_queue_opt *); +int expand_queue(struct pf_altq *, struct node_if *, + struct node_queue *, struct node_queue_bw, + struct node_queue_opt *); +int expand_skip_interface(struct node_if *); int check_rulestate(int); -int kw_cmp(const void *, const void *); -int lookup(char *); -int lgetc(FILE *); -int lungetc(int); -int findeol(void); -int yylex(void); -int atoul(char *, u_long *); int getservice(char *); int rule_label(struct pf_rule *, char *); -TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead); -struct sym { - TAILQ_ENTRY(sym) entries; - int used; - int persist; - char *nam; - char *val; -}; - - -int symset(const char *, const char *, int); -char *symget(const char *); - void mv_rules(struct pf_ruleset *, struct pf_ruleset *); void decide_address_family(struct node_host *, sa_family_t *); void remove_invalid_hosts(struct node_host **, sa_family_t *); @@ -327,10 +340,11 @@ struct loadanchors { typedef struct { union { - u_int32_t number; + int64_t number; + double probability; int i; char *string; - int rtableid; + u_int rtableid; struct { u_int8_t b1; u_int8_t b2; @@ -410,7 +424,7 @@ typedef struct { %token REASSEMBLE FRAGDROP FRAGCROP ANCHOR NATANCHOR RDRANCHOR BINATANCHOR %token SET OPTIMIZATION TIMEOUT LIMIT LOGINTERFACE BLOCKPOLICY RANDOMID %token REQUIREORDER SYNPROXY FINGERPRINTS NOSYNC DEBUG SKIP HOSTID -%token ANTISPOOF FOR +%token ANTISPOOF FOR INCLUDE %token BITMASK RANDOM SOURCEHASH ROUNDROBIN STATICPORT PROBABILITY %token ALTQ CBQ PRIQ HFSC BANDWIDTH TBRSIZE LINKSHARE REALTIME UPPERLIMIT %token QUEUE PRIORITY QLIMIT RTABLE @@ -419,10 +433,12 @@ typedef struct { %token MAXSRCCONN MAXSRCCONNRATE OVERLOAD FLUSH %token TAGGED TAG IFBOUND FLOATING STATEPOLICY ROUTE %token <v.string> STRING +%token <v.number> NUMBER %token <v.i> PORTBINARY %type <v.interface> interface if_list if_item_not if_item %type <v.number> number icmptype icmp6type uid gid %type <v.number> tos not yesno +%type <v.probability> probability %type <v.i> no dir af fragcache optimizer %type <v.i> sourcetrack flush unaryop statelock %type <v.b> action nataction natpasslog scrubaction @@ -430,9 +446,11 @@ typedef struct { %type <v.range> port rport %type <v.hashkey> hashkey %type <v.proto> proto proto_list proto_item +%type <v.number> protoval %type <v.icmp> icmpspec %type <v.icmp> icmp_list icmp_item %type <v.icmp> icmp6_list icmp6_item +%type <v.number> reticmpspec reticmp6spec %type <v.fromto> fromto %type <v.peer> ipportspec from to %type <v.host> ipspec xhost host dynaddr host_list @@ -444,7 +462,7 @@ typedef struct { %type <v.gid> gids gid_list gid_item %type <v.route> route %type <v.redirection> redirection redirpool -%type <v.string> label string tag anchorname +%type <v.string> label string stringall tag anchorname %type <v.keep_state> keep %type <v.state_opt> state_opt_spec state_opt_list state_opt_item %type <v.logquick> logquick quick log logopts logopt @@ -467,6 +485,7 @@ typedef struct { %% ruleset : /* empty */ + | ruleset include '\n' | ruleset '\n' | ruleset option '\n' | ruleset scrubrule '\n' @@ -481,7 +500,22 @@ ruleset : /* empty */ | ruleset antispoof '\n' | ruleset tabledef '\n' | '{' fakeanchor '}' '\n'; - | ruleset error '\n' { errors++; } + | ruleset error '\n' { file->errors++; } + ; + +include : INCLUDE STRING { + struct file *nfile; + + if ((nfile = pushfile($2, 0)) == NULL) { + yyerror("failed to include file %s", $2); + free($2); + YYERROR; + } + free($2); + + file = nfile; + lungetc('\n'); + } ; /* @@ -532,7 +566,7 @@ option : SET OPTIMIZATION STRING { | SET TIMEOUT '{' timeout_list '}' | SET LIMIT limit_spec | SET LIMIT '{' limit_list '}' - | SET LOGINTERFACE STRING { + | SET LOGINTERFACE stringall { if (check_rulestate(PFCTL_STATE_OPTION)) { free($3); YYERROR; @@ -545,7 +579,7 @@ option : SET OPTIMIZATION STRING { free($3); } | SET HOSTID number { - if ($3 == 0) { + if ($3 == 0 || $3 > UINT_MAX) { yyerror("hostid must be non-zero"); YYERROR; } @@ -624,6 +658,14 @@ option : SET OPTIMIZATION STRING { } ; +stringall : STRING { $$ = $1; } + | ALL { + if (($$ = strdup("all")) == NULL) { + err(1, "stringall: strdup"); + } + } + ; + string : string STRING { if (asprintf(&$$, "%s %s", $1, $2) == -1) err(1, "string: asprintf"); @@ -641,6 +683,19 @@ varset : STRING '=' string { free($1); free($3); } + | STRING '=' NUMBER { + char *s; + if (asprintf(&s, "%lld", $3) == -1) { + yyerror("string: asprintf"); + YYERROR; + } + if (pf->opts & PF_OPT_VERBOSE) + printf("%s = \"%s\"\n", $1, s); + if (symset($1, s, 0) == -1) + err(1, "cannot store variable %s", $1); + free($1); + free(s); + } ; anchorname : STRING { $$ = $1; } @@ -687,6 +742,7 @@ anchorrule : ANCHOR anchorname dir quick interface af proto fromto filter_opts pfa_anchor { struct pf_rule r; + struct node_proto *proto; if (check_rulestate(PFCTL_STATE_FILTER)) { if ($2) @@ -737,6 +793,55 @@ anchorrule : ANCHOR anchorname dir quick interface af proto fromto r.prob = $9.prob; r.rtableid = $9.rtableid; + if ($9.tag) + if (strlcpy(r.tagname, $9.tag, + PF_TAG_NAME_SIZE) >= PF_TAG_NAME_SIZE) { + yyerror("tag too long, max %u chars", + PF_TAG_NAME_SIZE - 1); + YYERROR; + } + if ($9.match_tag) + if (strlcpy(r.match_tagname, $9.match_tag, + PF_TAG_NAME_SIZE) >= PF_TAG_NAME_SIZE) { + yyerror("tag too long, max %u chars", + PF_TAG_NAME_SIZE - 1); + YYERROR; + } + r.match_tag_not = $9.match_tag_not; + if (rule_label(&r, $9.label)) + YYERROR; + free($9.label); + r.flags = $9.flags.b1; + r.flagset = $9.flags.b2; + if (($9.flags.b1 & $9.flags.b2) != $9.flags.b1) { + yyerror("flags always false"); + YYERROR; + } + if ($9.flags.b1 || $9.flags.b2 || $8.src_os) { + for (proto = $7; proto != NULL && + proto->proto != IPPROTO_TCP; + proto = proto->next) + ; /* nothing */ + if (proto == NULL && $7 != NULL) { + if ($9.flags.b1 || $9.flags.b2) + yyerror( + "flags only apply to tcp"); + if ($8.src_os) + yyerror( + "OS fingerprinting only " + "applies to tcp"); + YYERROR; + } + } + + r.tos = $9.tos; + + if ($9.keep.action) { + yyerror("cannot specify state handling " + "on anchors"); + YYERROR; + } + if ($9.match_tag) if (strlcpy(r.match_tagname, $9.match_tag, PF_TAG_NAME_SIZE) >= PF_TAG_NAME_SIZE) { @@ -751,8 +856,8 @@ anchorrule : ANCHOR anchorname dir quick interface af proto fromto expand_rule(&r, $5, NULL, $7, $8.src_os, $8.src.host, $8.src.port, $8.dst.host, $8.dst.port, - 0, 0, 0, pf->astack[pf->asd + 1] ? - pf->alast->name : $2); + $9.uid, $9.gid, $9.icmpspec, + pf->astack[pf->asd + 1] ? pf->alast->name : $2); free($2); pf->astack[pf->asd + 1] = NULL; } @@ -966,24 +1071,24 @@ scrub_opt : NODF { } scrub_opts.nodf = 1; } - | MINTTL number { + | MINTTL NUMBER { if (scrub_opts.marker & SOM_MINTTL) { yyerror("min-ttl cannot be respecified"); YYERROR; } - if ($2 > 255) { + if ($2 < 0 || $2 > 255) { yyerror("illegal min-ttl value %d", $2); YYERROR; } scrub_opts.marker |= SOM_MINTTL; scrub_opts.minttl = $2; } - | MAXMSS number { + | MAXMSS NUMBER { if (scrub_opts.marker & SOM_MAXMSS) { yyerror("max-mss cannot be respecified"); YYERROR; } - if ($2 > 65535) { + if ($2 < 0 || $2 > 65535) { yyerror("illegal max-mss value %d", $2); YYERROR; } @@ -1019,8 +1124,8 @@ scrub_opt : NODF { } scrub_opts.randomid = 1; } - | RTABLE number { - if ($2 > RT_TABLEID_MAX || $2 < 0) { + | RTABLE NUMBER { + if ($2 < 0 || $2 > RT_TABLEID_MAX) { yyerror("invalid rtable id"); YYERROR; } @@ -1162,8 +1267,8 @@ antispoof_opt : label { } antispoof_opts.label = $1; } - | RTABLE number { - if ($2 > RT_TABLEID_MAX || $2 < 0) { + | RTABLE NUMBER { + if ($2 < 0 || $2 > RT_TABLEID_MAX) { yyerror("invalid rtable id"); YYERROR; } @@ -1244,6 +1349,10 @@ table_opt : STRING { switch (n->addr.type) { case PF_ADDR_ADDRMASK: continue; /* ok */ + case PF_ADDR_RANGE: + yyerror("address ranges are not " + "permitted inside tables"); + break; case PF_ADDR_DYNIFTL: yyerror("dynamic addresses are not " "permitted inside tables"); @@ -1376,24 +1485,24 @@ queue_opt : BANDWIDTH bandwidth { queue_opts.marker |= QOM_BWSPEC; queue_opts.queue_bwspec = $2; } - | PRIORITY number { + | PRIORITY NUMBER { if (queue_opts.marker & QOM_PRIORITY) { yyerror("priority cannot be respecified"); YYERROR; } - if ($2 > 255) { + if ($2 < 0 || $2 > 255) { yyerror("priority out of range: max 255"); YYERROR; } queue_opts.marker |= QOM_PRIORITY; queue_opts.priority = $2; } - | QLIMIT number { + | QLIMIT NUMBER { if (queue_opts.marker & QOM_QLIMIT) { yyerror("qlimit cannot be respecified"); YYERROR; } - if ($2 > 65535) { + if ($2 < 0 || $2 > 65535) { yyerror("qlimit out of range: max 65535"); YYERROR; } @@ -1408,12 +1517,12 @@ queue_opt : BANDWIDTH bandwidth { queue_opts.marker |= QOM_SCHEDULER; queue_opts.scheduler = $1; } - | TBRSIZE number { + | TBRSIZE NUMBER { if (queue_opts.marker & QOM_TBRSIZE) { yyerror("tbrsize cannot be respecified"); YYERROR; } - if ($2 > 65535) { + if ($2 < 0 || $2 > 65535) { yyerror("tbrsize too big: max 65535"); YYERROR; } @@ -1456,6 +1565,14 @@ bandwidth : STRING { free($1); $$.bw_absolute = (u_int32_t)bps; } + | NUMBER { + if ($1 < 0 || $1 > UINT_MAX) { + yyerror("bandwidth number too big"); + YYERROR; + } + $$.bw_percent = 0; + $$.bw_absolute = $1; + } ; scheduler : CBQ { @@ -1552,8 +1669,12 @@ hfscopts_item : LINKSHARE bandwidth { hfsc_opts.linkshare.m2 = $2; hfsc_opts.linkshare.used = 1; } - | LINKSHARE '(' bandwidth comma number comma bandwidth ')' + | LINKSHARE '(' bandwidth comma NUMBER comma bandwidth ')' { + if ($5 < 0 || $5 > INT_MAX) { + yyerror("timing in curve out of range"); + YYERROR; + } if (hfsc_opts.linkshare.used) { yyerror("linkshare already specified"); YYERROR; @@ -1571,8 +1692,12 @@ hfscopts_item : LINKSHARE bandwidth { hfsc_opts.realtime.m2 = $2; hfsc_opts.realtime.used = 1; } - | REALTIME '(' bandwidth comma number comma bandwidth ')' + | REALTIME '(' bandwidth comma NUMBER comma bandwidth ')' { + if ($5 < 0 || $5 > INT_MAX) { + yyerror("timing in curve out of range"); + YYERROR; + } if (hfsc_opts.realtime.used) { yyerror("realtime already specified"); YYERROR; @@ -1590,8 +1715,12 @@ hfscopts_item : LINKSHARE bandwidth { hfsc_opts.upperlimit.m2 = $2; hfsc_opts.upperlimit.used = 1; } - | UPPERLIMIT '(' bandwidth comma number comma bandwidth ')' + | UPPERLIMIT '(' bandwidth comma NUMBER comma bandwidth ')' { + if ($5 < 0 || $5 > INT_MAX) { + yyerror("timing in curve out of range"); + YYERROR; + } if (hfsc_opts.upperlimit.used) { yyerror("upperlimit already specified"); YYERROR; @@ -2113,37 +2242,49 @@ filter_opt : USER uids { filter_opts.match_tag = $3; filter_opts.match_tag_not = $1; } - | PROBABILITY STRING { + | PROBABILITY probability { + double p; + + p = floor($2 * UINT_MAX + 0.5); + if (p < 0.0 || p > UINT_MAX) { + yyerror("invalid probability: %lf", p); + YYERROR; + } + filter_opts.prob = (u_int32_t)p; + if (filter_opts.prob == 0) + filter_opts.prob = 1; + } + | RTABLE NUMBER { + if ($2 < 0 || $2 > RT_TABLEID_MAX) { + yyerror("invalid rtable id"); + YYERROR; + } + filter_opts.rtableid = $2; + } + ; + +probability : STRING { char *e; - double p = strtod($2, &e); + double p = strtod($1, &e); if (*e == '%') { p *= 0.01; e++; } if (*e) { - yyerror("invalid probability: %s", $2); - free($2); - YYERROR; - } - p = floor(p * (UINT_MAX+1.0) + 0.5); - if (p < 1.0 || p >= (UINT_MAX+1.0)) { - yyerror("invalid probability: %s", $2); - free($2); + yyerror("invalid probability: %s", $1); + free($1); YYERROR; } - filter_opts.prob = (u_int32_t)p; - free($2); + free($1); + $$ = p; } - | RTABLE number { - if ($2 > RT_TABLEID_MAX || $2 < 0) { - yyerror("invalid rtable id"); - YYERROR; - } - filter_opts.rtableid = $2; + | NUMBER { + $$ = (double)$1; } ; + action : PASS { $$.b1 = PF_PASS; $$.b2 = $$.w = 0; } | BLOCK blockspec { $$ = $2; $$.b1 = PF_DROP; } ; @@ -2163,8 +2304,8 @@ blockspec : /* empty */ { $$.w = 0; $$.w2 = 0; } - | RETURNRST '(' TTL number ')' { - if ($4 > 255) { + | RETURNRST '(' TTL NUMBER ')' { + if ($4 < 0 || $4 > 255) { yyerror("illegal ttl value %d", $4); YYERROR; } @@ -2182,34 +2323,20 @@ blockspec : /* empty */ { $$.w = returnicmpdefault; $$.w2 = returnicmp6default; } - | RETURNICMP '(' STRING ')' { + | RETURNICMP '(' reticmpspec ')' { $$.b2 = PFRULE_RETURNICMP; - if (!($$.w = parseicmpspec($3, AF_INET))) { - free($3); - YYERROR; - } - free($3); - $$.w2 = returnicmp6default; + $$.w = $3; + $$.w2 = returnicmpdefault; } - | RETURNICMP6 '(' STRING ')' { + | RETURNICMP6 '(' reticmp6spec ')' { $$.b2 = PFRULE_RETURNICMP; $$.w = returnicmpdefault; - if (!($$.w2 = parseicmpspec($3, AF_INET6))) { - free($3); - YYERROR; - } - free($3); + $$.w2 = $3; } - | RETURNICMP '(' STRING comma STRING ')' { + | RETURNICMP '(' reticmpspec comma reticmp6spec ')' { $$.b2 = PFRULE_RETURNICMP; - if (!($$.w = parseicmpspec($3, AF_INET)) || - !($$.w2 = parseicmpspec($5, AF_INET6))) { - free($3); - free($5); - YYERROR; - } - free($3); - free($5); + $$.w = $3; + $$.w2 = $5; } | RETURN { $$.b2 = PFRULE_RETURN; @@ -2218,6 +2345,44 @@ blockspec : /* empty */ { } ; +reticmpspec : STRING { + if (!($$ = parseicmpspec($1, AF_INET))) { + free($1); + YYERROR; + } + free($1); + } + | NUMBER { + u_int8_t icmptype; + + if ($1 < 0 || $1 > 255) { + yyerror("invalid icmp code %lu", $1); + YYERROR; + } + icmptype = returnicmpdefault >> 8; + $$ = (icmptype << 8 | $1); + } + ; + +reticmp6spec : STRING { + if (!($$ = parseicmpspec($1, AF_INET6))) { + free($1); + YYERROR; + } + free($1); + } + | NUMBER { + u_int8_t icmptype; + + if ($1 < 0 || $1 > 255) { + yyerror("invalid icmp code %lu", $1); + YYERROR; + } + icmptype = returnicmp6default >> 8; + $$ = (icmptype << 8 | $1); + } + ; + dir : /* empty */ { $$ = 0; } | IN { $$ = PF_IN; } | OUT { $$ = PF_OUT; } @@ -2332,29 +2497,10 @@ proto_list : proto_item { $$ = $1; } } ; -proto_item : STRING { +proto_item : protoval { u_int8_t pr; - u_long ulval; - if (atoul($1, &ulval) == 0) { - if (ulval > 255) { - yyerror("protocol outside range"); - free($1); - YYERROR; - } - pr = (u_int8_t)ulval; - } else { - struct protoent *p; - - p = getprotobyname($1); - if (p == NULL) { - yyerror("unknown protocol %s", $1); - free($1); - YYERROR; - } - pr = p->p_proto; - } - free($1); + pr = (u_int8_t)$1; if (pr == 0) { yyerror("proto 0 cannot be used"); YYERROR; @@ -2368,6 +2514,26 @@ proto_item : STRING { } ; +protoval : STRING { + struct protoent *p; + + p = getprotobyname($1); + if (p == NULL) { + yyerror("unknown protocol %s", $1); + free($1); + YYERROR; + } + $$ = p->p_proto; + free($1); + } + | NUMBER { + if ($1 < 0 || $1 > 255) { + yyerror("protocol outside range"); + YYERROR; + } + } + ; + fromto : ALL { $$.src.host = NULL; $$.src.port = NULL; @@ -2495,10 +2661,43 @@ host : STRING { free($1); } - | STRING '/' number { + | STRING '-' STRING { + struct node_host *b, *e; + + if ((b = host($1)) == NULL || (e = host($3)) == NULL) { + free($1); + free($3); + yyerror("could not parse host specification"); + YYERROR; + } + if (b->af != e->af || + b->addr.type != PF_ADDR_ADDRMASK || + e->addr.type != PF_ADDR_ADDRMASK || + unmask(&b->addr.v.a.mask, b->af) != + (b->af == AF_INET ? 32 : 128) || + unmask(&e->addr.v.a.mask, e->af) != + (e->af == AF_INET ? 32 : 128) || + b->next != NULL || b->not || + e->next != NULL || e->not) { + free(b); + free(e); + free($1); + free($3); + yyerror("invalid address range"); + YYERROR; + } + memcpy(&b->addr.v.a.mask, &e->addr.v.a.addr, + sizeof(b->addr.v.a.mask)); + b->addr.type = PF_ADDR_RANGE; + $$ = b; + free(e); + free($1); + free($3); + } + | STRING '/' NUMBER { char *buf; - if (asprintf(&buf, "%s/%u", $1, $3) == -1) + if (asprintf(&buf, "%s/%lld", $1, $3) == -1) err(1, "host: asprintf"); free($1); if (($$ = host(buf)) == NULL) { @@ -2509,10 +2708,28 @@ host : STRING { } free(buf); } + | NUMBER '/' NUMBER { + char *buf; + + /* ie. for 10/8 parsing */ + if (asprintf(&buf, "%lld/%lld", $1, $3) == -1) + err(1, "host: asprintf"); + if (($$ = host(buf)) == NULL) { + /* error. "any" is handled elsewhere */ + free(buf); + yyerror("could not parse host specification"); + YYERROR; + } + free(buf); + } | dynaddr - | dynaddr '/' number { + | dynaddr '/' NUMBER { struct node_host *n; + if ($3 < 0 || $3 > 128) { + yyerror("bit number too big"); + YYERROR; + } $$ = $1; for (n = $1; n != NULL; n = n->next) set_ipmask(n, $3); @@ -2557,7 +2774,8 @@ host : STRING { } ; -number : STRING { +number : NUMBER + | STRING { u_long ulval; if (atoul($1, &ulval) == -1) { @@ -2705,6 +2923,14 @@ port : STRING { } free($1); } + | NUMBER { + if ($1 < 0 || $1 > 65535) { + yyerror("illegal port value %lu", $1); + YYERROR; + } + $$.a = ntohs($1); + $$.b = $$.t = 0; + } ; uids : uid_item { $$ = $1; } @@ -2762,31 +2988,27 @@ uid_item : uid { ; uid : STRING { - u_long ulval; - - if (atoul($1, &ulval) == -1) { - if (!strcmp($1, "unknown")) - $$ = UID_MAX; - else { - struct passwd *pw; + if (!strcmp($1, "unknown")) + $$ = UID_MAX; + else { + struct passwd *pw; - if ((pw = getpwnam($1)) == NULL) { - yyerror("unknown user %s", $1); - free($1); - YYERROR; - } - $$ = pw->pw_uid; - } - } else { - if (ulval >= UID_MAX) { + if ((pw = getpwnam($1)) == NULL) { + yyerror("unknown user %s", $1); free($1); - yyerror("illegal uid value %lu", ulval); YYERROR; } - $$ = ulval; + $$ = pw->pw_uid; } free($1); } + | NUMBER { + if ($1 < 0 || $1 >= UID_MAX) { + yyerror("illegal uid value %lu", $1); + YYERROR; + } + $$ = $1; + } ; gids : gid_item { $$ = $1; } @@ -2844,31 +3066,27 @@ gid_item : gid { ; gid : STRING { - u_long ulval; - - if (atoul($1, &ulval) == -1) { - if (!strcmp($1, "unknown")) - $$ = GID_MAX; - else { - struct group *grp; + if (!strcmp($1, "unknown")) + $$ = GID_MAX; + else { + struct group *grp; - if ((grp = getgrnam($1)) == NULL) { - yyerror("unknown group %s", $1); - free($1); - YYERROR; - } - $$ = grp->gr_gid; - } - } else { - if (ulval >= GID_MAX) { - yyerror("illegal gid value %lu", ulval); + if ((grp = getgrnam($1)) == NULL) { + yyerror("unknown group %s", $1); free($1); YYERROR; } - $$ = ulval; + $$ = grp->gr_gid; } free($1); } + | NUMBER { + if ($1 < 0 || $1 >= GID_MAX) { + yyerror("illegal gid value %lu", $1); + YYERROR; + } + $$ = $1; + } ; flag : STRING { @@ -2923,29 +3141,33 @@ icmp_item : icmptype { } | icmptype CODE STRING { const struct icmpcodeent *p; - u_long ulval; - if (atoul($3, &ulval) == 0) { - if (ulval > 255) { - free($3); - yyerror("illegal icmp-code %lu", ulval); - YYERROR; - } - } else { - if ((p = geticmpcodebyname($1-1, $3, - AF_INET)) == NULL) { - yyerror("unknown icmp-code %s", $3); - free($3); - YYERROR; - } - ulval = p->code; + if ((p = geticmpcodebyname($1-1, $3, AF_INET)) == NULL) { + yyerror("unknown icmp-code %s", $3); + free($3); + YYERROR; } + free($3); $$ = calloc(1, sizeof(struct node_icmp)); if ($$ == NULL) err(1, "icmp_item: calloc"); $$->type = $1; - $$->code = ulval + 1; + $$->code = p->code + 1; + $$->proto = IPPROTO_ICMP; + $$->next = NULL; + $$->tail = $$; + } + | icmptype CODE NUMBER { + if ($3 < 0 || $3 > 255) { + yyerror("illegal icmp-code %lu", $3); + YYERROR; + } + $$ = calloc(1, sizeof(struct node_icmp)); + if ($$ == NULL) + err(1, "icmp_item: calloc"); + $$->type = $1; + $$->code = $3 + 1; $$->proto = IPPROTO_ICMP; $$->next = NULL; $$->tail = $$; @@ -2964,30 +3186,33 @@ icmp6_item : icmp6type { } | icmp6type CODE STRING { const struct icmpcodeent *p; - u_long ulval; - if (atoul($3, &ulval) == 0) { - if (ulval > 255) { - yyerror("illegal icmp6-code %lu", - ulval); - free($3); - YYERROR; - } - } else { - if ((p = geticmpcodebyname($1-1, $3, - AF_INET6)) == NULL) { - yyerror("unknown icmp6-code %s", $3); - free($3); - YYERROR; - } - ulval = p->code; + if ((p = geticmpcodebyname($1-1, $3, AF_INET6)) == NULL) { + yyerror("unknown icmp6-code %s", $3); + free($3); + YYERROR; } free($3); + + $$ = calloc(1, sizeof(struct node_icmp)); + if ($$ == NULL) + err(1, "icmp_item: calloc"); + $$->type = $1; + $$->code = p->code + 1; + $$->proto = IPPROTO_ICMPV6; + $$->next = NULL; + $$->tail = $$; + } + | icmp6type CODE NUMBER { + if ($3 < 0 || $3 > 255) { + yyerror("illegal icmp-code %lu", $3); + YYERROR; + } $$ = calloc(1, sizeof(struct node_icmp)); if ($$ == NULL) err(1, "icmp_item: calloc"); $$->type = $1; - $$->code = ulval + 1; + $$->code = $3 + 1; $$->proto = IPPROTO_ICMPV6; $$->next = NULL; $$->tail = $$; @@ -2996,51 +3221,43 @@ icmp6_item : icmp6type { icmptype : STRING { const struct icmptypeent *p; - u_long ulval; - if (atoul($1, &ulval) == 0) { - if (ulval > 255) { - yyerror("illegal icmp-type %lu", ulval); - free($1); - YYERROR; - } - $$ = ulval + 1; - } else { - if ((p = geticmptypebyname($1, AF_INET)) == - NULL) { - yyerror("unknown icmp-type %s", $1); - free($1); - YYERROR; - } - $$ = p->type + 1; + if ((p = geticmptypebyname($1, AF_INET)) == NULL) { + yyerror("unknown icmp-type %s", $1); + free($1); + YYERROR; } + $$ = p->type + 1; free($1); } + | NUMBER { + if ($1 < 0 || $1 > 255) { + yyerror("illegal icmp-type %lu", $1); + YYERROR; + } + $$ = $1 + 1; + } ; icmp6type : STRING { const struct icmptypeent *p; - u_long ulval; - if (atoul($1, &ulval) == 0) { - if (ulval > 255) { - yyerror("illegal icmp6-type %lu", - ulval); - free($1); - YYERROR; - } - $$ = ulval + 1; - } else { - if ((p = geticmptypebyname($1, AF_INET6)) == - NULL) { - yyerror("unknown icmp6-type %s", $1); - free($1); - YYERROR; - } - $$ = p->type + 1; + if ((p = geticmptypebyname($1, AF_INET6)) == + NULL) { + yyerror("unknown icmp6-type %s", $1); + free($1); + YYERROR; } + $$ = p->type + 1; free($1); } + | NUMBER { + if ($1 < 0 || $1 > 255) { + yyerror("illegal icmp6-type %lu", $1); + YYERROR; + } + $$ = $1 + 1; + } ; tos : TOS STRING { @@ -3053,7 +3270,7 @@ tos : TOS STRING { else if ($2[0] == '0' && $2[1] == 'x') $$ = strtoul($2, NULL, 16); else - $$ = strtoul($2, NULL, 10); + $$ = 0; /* flag bad argument */ if (!$$ || $$ > 255) { yyerror("illegal tos value %s", $2); free($2); @@ -3061,6 +3278,13 @@ tos : TOS STRING { } free($2); } + | TOS NUMBER { + $$ = $2; + if (!$$ || $$ > 255) { + yyerror("illegal tos value %s", $2); + YYERROR; + } + } ; sourcetrack : SOURCETRACK { $$ = PF_SRCTRACK; } @@ -3113,7 +3337,11 @@ state_opt_list : state_opt_item { $$ = $1; } } ; -state_opt_item : MAXIMUM number { +state_opt_item : MAXIMUM NUMBER { + if ($2 < 0 || $2 > UINT_MAX) { + yyerror("only positive values permitted"); + YYERROR; + } $$ = calloc(1, sizeof(struct node_state_opt)); if ($$ == NULL) err(1, "state_opt_item: calloc"); @@ -3130,7 +3358,11 @@ state_opt_item : MAXIMUM number { $$->next = NULL; $$->tail = $$; } - | MAXSRCSTATES number { + | MAXSRCSTATES NUMBER { + if ($2 < 0 || $2 > UINT_MAX) { + yyerror("only positive values permitted"); + YYERROR; + } $$ = calloc(1, sizeof(struct node_state_opt)); if ($$ == NULL) err(1, "state_opt_item: calloc"); @@ -3139,7 +3371,11 @@ state_opt_item : MAXIMUM number { $$->next = NULL; $$->tail = $$; } - | MAXSRCCONN number { + | MAXSRCCONN NUMBER { + if ($2 < 0 || $2 > UINT_MAX) { + yyerror("only positive values permitted"); + YYERROR; + } $$ = calloc(1, sizeof(struct node_state_opt)); if ($$ == NULL) err(1, "state_opt_item: calloc"); @@ -3148,7 +3384,12 @@ state_opt_item : MAXIMUM number { $$->next = NULL; $$->tail = $$; } - | MAXSRCCONNRATE number '/' number { + | MAXSRCCONNRATE NUMBER '/' NUMBER { + if ($2 < 0 || $2 > UINT_MAX || + $4 < 0 || $4 > UINT_MAX) { + yyerror("only positive values permitted"); + YYERROR; + } $$ = calloc(1, sizeof(struct node_state_opt)); if ($$ == NULL) err(1, "state_opt_item: calloc"); @@ -3176,7 +3417,11 @@ state_opt_item : MAXIMUM number { $$->next = NULL; $$->tail = $$; } - | MAXSRCNODES number { + | MAXSRCNODES NUMBER { + if ($2 < 0 || $2 > UINT_MAX) { + yyerror("only positive values permitted"); + YYERROR; + } $$ = calloc(1, sizeof(struct node_state_opt)); if ($$ == NULL) err(1, "state_opt_item: calloc"); @@ -3203,9 +3448,13 @@ state_opt_item : MAXIMUM number { $$->next = NULL; $$->tail = $$; } - | STRING number { + | STRING NUMBER { int i; + if ($2 < 0 || $2 > UINT_MAX) { + yyerror("only positive values permitted"); + YYERROR; + } for (i = 0; pf_timeouts[i].name && strcmp(pf_timeouts[i].name, $1); ++i) ; /* nothing */ @@ -3282,6 +3531,14 @@ rport : STRING { } free($1); } + | NUMBER { + if ($1 < 0 || $1 > 65535) { + yyerror("illegal port value %ld", $1); + YYERROR; + } + $$.a = ntohs($1); + $$.b = $$.t = 0; + } ; redirspec : host { $$ = $1; } @@ -3808,8 +4065,8 @@ tagged : /* empty */ { $$.neg = 0; $$.name = NULL; } ; rtable : /* empty */ { $$ = -1; } - | RTABLE number { - if ($2 > RT_TABLEID_MAX || $2 < 0) { + | RTABLE NUMBER { + if ($2 < 0 || $2 > RT_TABLEID_MAX) { yyerror("invalid rtable id"); YYERROR; } @@ -3884,12 +4141,16 @@ route : /* empty */ { } ; -timeout_spec : STRING number +timeout_spec : STRING NUMBER { if (check_rulestate(PFCTL_STATE_OPTION)) { free($1); YYERROR; } + if ($2 < 0 || $2 > UINT_MAX) { + yyerror("only positive values permitted"); + YYERROR; + } if (pfctl_set_timeout(pf, $1, $2, 0) != 0) { yyerror("unknown timeout %s", $1); free($1); @@ -3903,12 +4164,16 @@ timeout_list : timeout_list comma timeout_spec | timeout_spec ; -limit_spec : STRING number +limit_spec : STRING NUMBER { if (check_rulestate(PFCTL_STATE_OPTION)) { free($1); YYERROR; } + if ($2 < 0 || $2 > UINT_MAX) { + yyerror("only positive values permitted"); + YYERROR; + } if (pfctl_set_limit(pf, $1, $2) != 0) { yyerror("unable to set limit %s %u", $1, $2); free($1); @@ -3954,11 +4219,10 @@ int yyerror(const char *fmt, ...) { va_list ap; - extern char *infile; - errors = 1; + file->errors++; va_start(ap, fmt); - fprintf(stderr, "%s:%d: ", infile, yylval.lineno); + fprintf(stderr, "%s:%d: ", file->name, yylval.lineno); vfprintf(stderr, fmt, ap); fprintf(stderr, "\n"); va_end(ap); @@ -4889,6 +5153,7 @@ lookup(char *s) { "icmp6-type", ICMP6TYPE}, { "if-bound", IFBOUND}, { "in", IN}, + { "include", INCLUDE}, { "inet", INET}, { "inet6", INET6}, { "keep", KEEP}, @@ -4990,9 +5255,9 @@ char pushback_buffer[MAXPUSHBACK]; int pushback_index = 0; int -lgetc(FILE *f) +lgetc(int quotec) { - int c, next; + int c, next; if (parsebuf) { /* Read character from the parsebuffer instead of input. */ @@ -5008,24 +5273,31 @@ lgetc(FILE *f) if (pushback_index) return (pushback_buffer[--pushback_index]); - while ((c = getc(f)) == '\\') { - next = getc(f); + if (quotec) { + if ((c = getc(file->stream)) == EOF) { + yyerror("reached end of file while parsing quoted string"); + if (popfile() == EOF) + return (EOF); + return (quotec); + } + return (c); + } + + while ((c = getc(file->stream)) == '\\') { + next = getc(file->stream); if (next != '\n') { c = next; break; } - yylval.lineno = lineno; - lineno++; - } - if (c == '\t' || c == ' ') { - /* Compress blanks to a single space. */ - do { - c = getc(f); - } while (c == '\t' || c == ' '); - ungetc(c, f); - c = ' '; + yylval.lineno = file->lineno; + file->lineno++; } + while (c == EOF) { + if (popfile() == EOF) + return (EOF); + c = getc(file->stream); + } return (c); } @@ -5055,9 +5327,9 @@ findeol(void) /* skip to either EOF or the first real EOL */ while (1) { - c = lgetc(fin); + c = lgetc(0); if (c == '\n') { - lineno++; + file->lineno++; break; } if (c == EOF) @@ -5071,21 +5343,21 @@ yylex(void) { char buf[8096]; char *p, *val; - int endc, c, next; + int quotec, next, c; int token; top: p = buf; - while ((c = lgetc(fin)) == ' ') + while ((c = lgetc(0)) == ' ' || c == '\t') ; /* nothing */ - yylval.lineno = lineno; + yylval.lineno = file->lineno; if (c == '#') - while ((c = lgetc(fin)) != '\n' && c != EOF) + while ((c = lgetc(0)) != '\n' && c != EOF) ; /* nothing */ if (c == '$' && parsebuf == NULL) { while (1) { - if ((c = lgetc(fin)) == EOF) + if ((c = lgetc(0)) == EOF) return (0); if (p + 1 >= buf + sizeof(buf) - 1) { @@ -5113,17 +5385,25 @@ top: switch (c) { case '\'': case '"': - endc = c; + quotec = c; while (1) { - if ((c = lgetc(fin)) == EOF) + if ((c = lgetc(quotec)) == EOF) return (0); - if (c == endc) { - *p = '\0'; - break; - } if (c == '\n') { - lineno++; + file->lineno++; continue; + } else if (c == '\\') { + if ((next = lgetc(quotec)) == EOF) + return (0); + if (next == quotec || c == ' ' || c == '\t') + c = next; + else if (next == '\n') + continue; + else + lungetc(next); + } else if (c == quotec) { + *p = '\0'; + break; } if (p + 1 >= buf + sizeof(buf) - 1) { yyerror("string too long"); @@ -5136,7 +5416,7 @@ top: err(1, "yylex: strdup"); return (STRING); case '<': - next = lgetc(fin); + next = lgetc(0); if (next == '>') { yylval.v.i = PF_OP_XRG; return (PORTBINARY); @@ -5144,7 +5424,7 @@ top: lungetc(next); break; case '>': - next = lgetc(fin); + next = lgetc(0); if (next == '<') { yylval.v.i = PF_OP_IRG; return (PORTBINARY); @@ -5152,13 +5432,49 @@ top: lungetc(next); break; case '-': - next = lgetc(fin); + next = lgetc(0); if (next == '>') return (ARROW); lungetc(next); break; } +#define allowed_to_end_number(x) \ + (isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=') + + if (c == '-' || isdigit(c)) { + do { + *p++ = c; + if ((unsigned)(p-buf) >= sizeof(buf)) { + yyerror("string too long"); + return (findeol()); + } + } while ((c = lgetc(0)) != EOF && isdigit(c)); + lungetc(c); + if (p == buf + 1 && buf[0] == '-') + goto nodigits; + if (c == EOF || allowed_to_end_number(c)) { + const char *errstr = NULL; + + *p = '\0'; + yylval.v.number = strtonum(buf, LLONG_MIN, + LLONG_MAX, &errstr); + if (errstr) { + yyerror("\"%s\" invalid number: %s", + buf, errstr); + return (findeol()); + } + return (NUMBER); + } else { +nodigits: + while (p > buf + 1) + lungetc(*--p); + c = *--p; + if (c == '-') + return (c); + } + } + #define allowed_in_string(x) \ (isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \ x != '{' && x != '}' && x != '<' && x != '>' && \ @@ -5172,7 +5488,7 @@ top: yyerror("string too long"); return (findeol()); } - } while ((c = lgetc(fin)) != EOF && (allowed_in_string(c))); + } while ((c = lgetc(0)) != EOF && (allowed_in_string(c))); lungetc(c); *p = '\0'; if ((token = lookup(buf)) == STRING) @@ -5181,8 +5497,8 @@ top: return (token); } if (c == '\n') { - yylval.lineno = lineno; - lineno++; + yylval.lineno = file->lineno; + file->lineno++; } if (c == EOF) return (0); @@ -5190,13 +5506,84 @@ top: } int -parse_rules(FILE *input, struct pfctl *xpf) +check_file_secrecy(int fd, const char *fname) { - struct sym *sym, *next; + struct stat st; + + if (fstat(fd, &st)) { + warn("cannot stat %s", fname); + return (-1); + } + if (st.st_uid != 0 && st.st_uid != getuid()) { + warnx("%s: owner not root or current user", fname); + return (-1); + } + if (st.st_mode & (S_IRWXG | S_IRWXO)) { + warnx("%s: group/world readable/writeable", fname); + return (-1); + } + return (0); +} + +struct file * +pushfile(const char *name, int secret) +{ + struct file *nfile; + + if ((nfile = calloc(1, sizeof(struct file))) == NULL || + (nfile->name = strdup(name)) == NULL) { + warn("malloc"); + return (NULL); + } + if (TAILQ_FIRST(&files) == NULL && strcmp(nfile->name, "-") == 0) { + nfile->stream = stdin; + free(nfile->name); + if ((nfile->name = strdup("stdin")) == NULL) { + warn("strdup"); + free(nfile); + return (NULL); + } + } else if ((nfile->stream = fopen(nfile->name, "r")) == NULL) { + warn("%s", nfile->name); + free(nfile->name); + free(nfile); + return (NULL); + } else if (secret && + check_file_secrecy(fileno(nfile->stream), nfile->name)) { + fclose(nfile->stream); + free(nfile->name); + free(nfile); + return (NULL); + } + nfile->lineno = 1; + TAILQ_INSERT_TAIL(&files, nfile, entry); + return (nfile); +} + +int +popfile(void) +{ + struct file *prev; + + if ((prev = TAILQ_PREV(file, files, entry)) != NULL) { + prev->errors += file->errors; + TAILQ_REMOVE(&files, file, entry); + fclose(file->stream); + free(file->name); + free(file); + file = prev; + return (0); + } + return (EOF); +} + +int +parse_config(char *filename, struct pfctl *xpf) +{ + int errors = 0; + struct sym *sym; - fin = input; pf = xpf; - lineno = 1; errors = 0; rulestate = PFCTL_STATE_NONE; returnicmpdefault = (ICMP_UNREACH << 8) | ICMP_UNREACH_PORT; @@ -5205,34 +5592,36 @@ parse_rules(FILE *input, struct pfctl *xpf) blockpolicy = PFRULE_DROP; require_order = 1; + if ((file = pushfile(filename, 0)) == NULL) { + warn("cannot open the main config file!"); + return (-1); + } + yyparse(); + errors = file->errors; + popfile(); /* Free macros and check which have not been used. */ - for (sym = TAILQ_FIRST(&symhead); sym != NULL; sym = next) { - next = TAILQ_NEXT(sym, entries); + while ((sym = TAILQ_FIRST(&symhead))) { if ((pf->opts & PF_OPT_VERBOSE2) && !sym->used) fprintf(stderr, "warning: macro '%s' not " "used\n", sym->nam); free(sym->nam); free(sym->val); - TAILQ_REMOVE(&symhead, sym, entries); + TAILQ_REMOVE(&symhead, sym, entry); free(sym); } return (errors ? -1 : 0); } -/* - * Over-designed efficiency is a French and German concept, so how about - * we wait until they discover this ugliness and make it all fancy. - */ int symset(const char *nam, const char *val, int persist) { struct sym *sym; for (sym = TAILQ_FIRST(&symhead); sym && strcmp(nam, sym->nam); - sym = TAILQ_NEXT(sym, entries)) + sym = TAILQ_NEXT(sym, entry)) ; /* nothing */ if (sym != NULL) { @@ -5241,7 +5630,7 @@ symset(const char *nam, const char *val, int persist) else { free(sym->nam); free(sym->val); - TAILQ_REMOVE(&symhead, sym, entries); + TAILQ_REMOVE(&symhead, sym, entry); free(sym); } } @@ -5261,7 +5650,7 @@ symset(const char *nam, const char *val, int persist) } sym->used = 0; sym->persist = persist; - TAILQ_INSERT_TAIL(&symhead, sym, entries); + TAILQ_INSERT_TAIL(&symhead, sym, entry); return (0); } @@ -5290,7 +5679,7 @@ symget(const char *nam) { struct sym *sym; - TAILQ_FOREACH(sym, &symhead, entries) + TAILQ_FOREACH(sym, &symhead, entry) if (strcmp(nam, sym->nam) == 0) { sym->used = 1; return (sym->val); @@ -5476,17 +5865,12 @@ int pfctl_load_anchors(int dev, struct pfctl *pf, struct pfr_buffer *trans) { struct loadanchors *la; - FILE *fin; TAILQ_FOREACH(la, &loadanchorshead, entries) { if (pf->opts & PF_OPT_VERBOSE) fprintf(stderr, "\nLoading anchor %s from %s\n", la->anchorname, la->filename); - if ((fin = pfctl_fopen(la->filename, "r")) == NULL) { - warn("%s", la->filename); - continue; - } - if (pfctl_rules(dev, la->filename, fin, pf->opts, pf->optimize, + if (pfctl_rules(dev, la->filename, pf->opts, pf->optimize, la->anchorname, trans) == -1) return (-1); } diff --git a/pfctl/pf_print_state.c b/pfctl/pf_print_state.c index e4830a1268f6..8489c38c73a0 100644 --- a/pfctl/pf_print_state.c +++ b/pfctl/pf_print_state.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf_print_state.c,v 1.45 2007/05/31 04:13:37 mcbride Exp $ */ +/* $OpenBSD: pf_print_state.c,v 1.46 2007/08/30 09:28:49 dhartmei Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -79,6 +79,19 @@ print_addr(struct pf_addr_wrap *addr, sa_family_t af, int verbose) else printf("<%s>", addr->v.tblname); return; + case PF_ADDR_RANGE: { + char buf[48]; + + if (inet_ntop(af, &addr->v.a.addr, buf, sizeof(buf)) == NULL) + printf("?"); + else + printf("%s", buf); + if (inet_ntop(af, &addr->v.a.mask, buf, sizeof(buf)) == NULL) + printf(" - ?"); + else + printf(" - %s", buf); + break; + } case PF_ADDR_ADDRMASK: if (PF_AZERO(&addr->v.a.addr, AF_INET6) && PF_AZERO(&addr->v.a.mask, AF_INET6)) @@ -108,7 +121,8 @@ print_addr(struct pf_addr_wrap *addr, sa_family_t af, int verbose) } /* mask if not _both_ address and mask are zero */ - if (!(PF_AZERO(&addr->v.a.addr, AF_INET6) && + if (addr->type != PF_ADDR_RANGE && + !(PF_AZERO(&addr->v.a.addr, AF_INET6) && PF_AZERO(&addr->v.a.mask, AF_INET6))) { int bits = unmask(&addr->v.a.mask, af); diff --git a/pfctl/pfctl.c b/pfctl/pfctl.c index 0aeb0fc78071..3829f2cb413f 100644 --- a/pfctl/pfctl.c +++ b/pfctl/pfctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl.c,v 1.268 2007/06/30 18:25:08 henning Exp $ */ +/* $OpenBSD: pfctl.c,v 1.273 2008/02/13 19:55:12 kettenis Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -119,8 +119,6 @@ int dev = -1; int first_title = 1; int labels = 0; -const char *infile; - #define INDENT(d, o) do { \ if (o) { \ int i; \ @@ -955,7 +953,7 @@ pfctl_show_src_nodes(int dev, int opts) struct pfioc_src_nodes psn; struct pf_src_node *p; char *inbuf = NULL, *newinbuf = NULL; - unsigned len = 0; + unsigned int len = 0; int i; memset(&psn, 0, sizeof(psn)); @@ -1000,7 +998,7 @@ pfctl_show_states(int dev, const char *iface, int opts) struct pfioc_states ps; struct pfsync_state *p; char *inbuf = NULL, *newinbuf = NULL; - unsigned len = 0; + unsigned int len = 0; int i, dotitle = (opts & PF_OPT_SHOWALL); memset(&ps, 0, sizeof(ps)); @@ -1337,7 +1335,7 @@ pfctl_add_altq(struct pfctl *pf, struct pf_altq *a) } int -pfctl_rules(int dev, char *filename, FILE *fin, int opts, int optimize, +pfctl_rules(int dev, char *filename, int opts, int optimize, char *anchorname, struct pfr_buffer *trans) { #define ERR(x) do { warn(x); goto _error; } while(0) @@ -1373,7 +1371,6 @@ pfctl_rules(int dev, char *filename, FILE *fin, int opts, int optimize, if (strlcpy(trs.pfrt_anchor, anchorname, sizeof(trs.pfrt_anchor)) >= sizeof(trs.pfrt_anchor)) ERRX("pfctl_rules: strlcpy"); - infile = filename; pf.dev = dev; pf.opts = opts; pf.optimize = optimize; @@ -1417,7 +1414,7 @@ pfctl_rules(int dev, char *filename, FILE *fin, int opts, int optimize, pfctl_get_ticket(t, PF_RULESET_TABLE, anchorname); } - if (parse_rules(fin, &pf) < 0) { + if (parse_config(filename, &pf) < 0) { if ((opts & PF_OPT_NOACTION) == 0) ERRX("Syntax error in config file: " "pf rules not loaded"); @@ -1443,11 +1440,6 @@ pfctl_rules(int dev, char *filename, FILE *fin, int opts, int optimize, if (check_commit_altq(dev, opts) != 0) ERRX("errors in altq config"); - if (fin != stdin) { - fclose(fin); - fin = NULL; - } - /* process "load anchor" directives */ if (!anchorname[0]) if (pfctl_load_anchors(dev, &pf, t) == -1) @@ -1469,8 +1461,6 @@ _error: err(1, "DIOCXROLLBACK"); exit(1); } else { /* sub ruleset */ - if (fin != NULL && fin != stdin) - fclose(fin); return (-1); } @@ -1502,7 +1492,8 @@ pfctl_fopen(const char *name, const char *mode) void pfctl_init_options(struct pfctl *pf) { - int mib[2], mem; + int64_t mem; + int mib[2]; size_t size; pf->timeout[PFTM_TCP_FIRST_PACKET] = PFTM_TCP_FIRST_PACKET_VAL; @@ -1533,7 +1524,7 @@ pfctl_init_options(struct pfctl *pf) pf->limit[PF_LIMIT_TABLE_ENTRIES] = PFR_KENTRY_HIWAT; mib[0] = CTL_HW; - mib[1] = HW_PHYSMEM; + mib[1] = HW_PHYSMEM64; size = sizeof(mem); (void) sysctl(mib, 2, &mem, &size, NULL, 0); if (mem <= 100*1024*1024) @@ -1559,7 +1550,7 @@ pfctl_load_options(struct pfctl *pf) } /* - * If we've set the limit, but havn't explicitly set adaptive + * If we've set the limit, but haven't explicitly set adaptive * timeouts, do it now with a start of 60% and end of 120%. */ if (pf->limit_set[PF_LIMIT_STATES] && @@ -1957,7 +1948,6 @@ main(int argc, char *argv[]) int optimize = PF_OPTIMIZE_BASIC; char anchorname[MAXPATHLEN]; char *path; - FILE *fin = NULL; if (argc < 2) usage(); @@ -2292,15 +2282,6 @@ main(int argc, char *argv[]) } } - if (rulesopt != NULL) { - if (strcmp(rulesopt, "-") == 0) { - fin = stdin; - rulesopt = "stdin"; - } else { - if ((fin = pfctl_fopen(rulesopt, "r")) == NULL) - err(1, "%s", rulesopt); - } - } if ((rulesopt != NULL) && (loadopt & PFCTL_FLAG_OPTION) && !anchorname[0]) if (pfctl_clear_interface_flags(dev, opts | PF_OPT_QUIET)) @@ -2315,7 +2296,7 @@ main(int argc, char *argv[]) if (anchorname[0] == '_' || strstr(anchorname, "/_") != NULL) errx(1, "anchor names beginning with '_' cannot " "be modified from the command line"); - if (pfctl_rules(dev, rulesopt, fin, opts, optimize, + if (pfctl_rules(dev, rulesopt, opts, optimize, anchorname, NULL)) error = 1; else if (!(opts & PF_OPT_NOACTION) && diff --git a/pfctl/pfctl.h b/pfctl/pfctl.h index 49cf6e75ec75..7b7156e735d8 100644 --- a/pfctl/pfctl.h +++ b/pfctl/pfctl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl.h,v 1.41 2007/05/31 04:13:37 mcbride Exp $ */ +/* $OpenBSD: pfctl.h,v 1.42 2007/12/05 12:01:47 chl Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -48,7 +48,6 @@ struct pfr_buffer { (var) != NULL; \ (var) = pfr_buf_next((buf), (var))) -void pfr_set_fd(int); int pfr_get_fd(void); int pfr_clr_tables(struct pfr_table *, int *, int); int pfr_add_tables(struct pfr_table *, int, int *, int); @@ -63,9 +62,7 @@ int pfr_set_addrs(struct pfr_table *, struct pfr_addr *, int, int *, int *, int *, int *, int); int pfr_get_addrs(struct pfr_table *, struct pfr_addr *, int *, int); int pfr_get_astats(struct pfr_table *, struct pfr_astats *, int *, int); -int pfr_clr_astats(struct pfr_table *, struct pfr_addr *, int, int *, int); int pfr_tst_addrs(struct pfr_table *, struct pfr_addr *, int, int *, int); -int pfr_set_tflags(struct pfr_table *, int, int, int, int *, int *, int); int pfr_ina_define(struct pfr_table *, struct pfr_addr *, int, int *, int *, int, int); void pfr_buf_clear(struct pfr_buffer *); diff --git a/pfctl/pfctl_altq.c b/pfctl/pfctl_altq.c index b2397fcd0785..d1a46609ccbb 100644 --- a/pfctl/pfctl_altq.c +++ b/pfctl/pfctl_altq.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl_altq.c,v 1.92 2007/05/27 05:15:17 claudio Exp $ */ +/* $OpenBSD: pfctl_altq.c,v 1.93 2007/10/15 02:16:35 deraadt Exp $ */ /* * Copyright (c) 2002 @@ -138,8 +138,8 @@ qname_to_qid(const char *qname) } void -print_altq(const struct pf_altq *a, unsigned level, struct node_queue_bw *bw, - struct node_queue_opt *qopts) +print_altq(const struct pf_altq *a, unsigned int level, + struct node_queue_bw *bw, struct node_queue_opt *qopts) { if (a->qname[0] != 0) { print_queue(a, level, bw, 1, qopts); @@ -175,10 +175,11 @@ print_altq(const struct pf_altq *a, unsigned level, struct node_queue_bw *bw, } void -print_queue(const struct pf_altq *a, unsigned level, struct node_queue_bw *bw, - int print_interface, struct node_queue_opt *qopts) +print_queue(const struct pf_altq *a, unsigned int level, + struct node_queue_bw *bw, int print_interface, + struct node_queue_opt *qopts) { - unsigned i; + unsigned int i; printf("queue "); for (i = 0; i < level; ++i) diff --git a/pfctl/pfctl_optimize.c b/pfctl/pfctl_optimize.c index 37d9320ac22a..8a80232cc5bb 100644 --- a/pfctl/pfctl_optimize.c +++ b/pfctl/pfctl_optimize.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl_optimize.c,v 1.13 2006/10/31 14:17:45 mcbride Exp $ */ +/* $OpenBSD: pfctl_optimize.c,v 1.16 2008/01/26 13:16:36 mcbride Exp $ */ /* * Copyright (c) 2004 Mike Frantzen <frantzen@openbsd.org> @@ -395,7 +395,7 @@ optimize_superblock(struct pfctl *pf, struct superblock *block) * out rules. */ - /* shortcut. there will be alot of 1-rule superblocks */ + /* shortcut. there will be a lot of 1-rule superblocks */ if (!TAILQ_NEXT(TAILQ_FIRST(&block->sb_rules), por_entry)) return (0); @@ -1313,8 +1313,9 @@ again: if (pfctl_define_table(tbl->pt_name, PFR_TFLAG_CONST, 1, - pf->anchor->name, tbl->pt_buf, pf->anchor->ruleset.tticket)) { - warn("failed to create table %s", tbl->pt_name); + pf->astack[0]->name, tbl->pt_buf, pf->astack[0]->ruleset.tticket)) { + warn("failed to create table %s in %s", + tbl->pt_name, pf->astack[0]->name); return (1); } return (0); @@ -1417,7 +1418,7 @@ superblock_inclusive(struct superblock *block, struct pf_opt_rule *por) return (0); /* - * Have to handle interface groups seperately. Consider the following + * Have to handle interface groups separately. Consider the following * rules: * block on EXTIFS to any port 22 * pass on em0 to any port 22 @@ -1465,7 +1466,7 @@ superblock_inclusive(struct superblock *block, struct pf_opt_rule *por) } if (closest >= 0) - DEBUG("superblock break @ %d on %s+%xh", + DEBUG("superblock break @ %d on %s+%lxh", por->por_rule.nr, pf_rule_desc[closest].prf_name, i - pf_rule_desc[closest].prf_offset - diff --git a/pfctl/pfctl_parser.c b/pfctl/pfctl_parser.c index e7b3b852735a..e88306b30f4b 100644 --- a/pfctl/pfctl_parser.c +++ b/pfctl/pfctl_parser.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl_parser.c,v 1.234 2006/10/31 23:46:24 mcbride Exp $ */ +/* $OpenBSD: pfctl_parser.c,v 1.235 2007/10/15 02:16:35 deraadt Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -491,7 +491,7 @@ print_status(struct pf_status *s, int opts) running = s->running ? "Enabled" : "Disabled"; if (s->since) { - unsigned sec, min, hrs, day = runtime; + unsigned int sec, min, hrs, day = runtime; sec = day % 60; day /= 60; diff --git a/pfctl/pfctl_parser.h b/pfctl/pfctl_parser.h index b901fb906ecc..97b0325ddc73 100644 --- a/pfctl/pfctl_parser.h +++ b/pfctl/pfctl_parser.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl_parser.h,v 1.86 2006/10/31 23:46:25 mcbride Exp $ */ +/* $OpenBSD: pfctl_parser.h,v 1.87 2007/10/13 16:35:18 deraadt Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -187,7 +187,7 @@ struct pf_opt_rule { TAILQ_HEAD(pf_opt_queue, pf_opt_rule); -int pfctl_rules(int, char *, FILE *, int, int, char *, struct pfr_buffer *); +int pfctl_rules(int, char *, int, int, char *, struct pfr_buffer *); int pfctl_optimize_ruleset(struct pfctl *, struct pf_ruleset *); int pfctl_add_rule(struct pfctl *, struct pf_rule *, const char *); @@ -204,7 +204,7 @@ int pfctl_set_hostid(struct pfctl *, u_int32_t); int pfctl_set_debug(struct pfctl *, char *); int pfctl_set_interface_flags(struct pfctl *, char *, int, int); -int parse_rules(FILE *, struct pfctl *); +int parse_config(char *, struct pfctl *); int parse_flags(char *); int pfctl_load_anchors(int, struct pfctl *, struct pfr_buffer *); diff --git a/pfctl/pfctl_qstats.c b/pfctl/pfctl_qstats.c index 1731ce9ba3be..ba0c18aef5b3 100644 --- a/pfctl/pfctl_qstats.c +++ b/pfctl/pfctl_qstats.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl_qstats.c,v 1.30 2004/04/27 21:47:32 kjc Exp $ */ +/* $OpenBSD: pfctl_qstats.c,v 1.31 2007/10/15 02:16:35 deraadt Exp $ */ /* * Copyright (c) Henning Brauer <henning@openbsd.org> @@ -233,8 +233,8 @@ pfctl_find_altq_node(struct pf_altq_node *root, const char *qname, } void -pfctl_print_altq_node(int dev, const struct pf_altq_node *node, unsigned level, - int opts) +pfctl_print_altq_node(int dev, const struct pf_altq_node *node, + unsigned int level, int opts) { const struct pf_altq_node *child; diff --git a/pfctl/pfctl_radix.c b/pfctl/pfctl_radix.c index 01ad4758ff1a..becd0305b836 100644 --- a/pfctl/pfctl_radix.c +++ b/pfctl/pfctl_radix.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl_radix.c,v 1.27 2005/05/21 21:03:58 henning Exp $ */ +/* $OpenBSD: pfctl_radix.c,v 1.28 2007/12/05 12:01:47 chl Exp $ */ /* * Copyright (c) 2002 Cedric Berger @@ -300,29 +300,6 @@ pfr_get_astats(struct pfr_table *tbl, struct pfr_astats *addr, int *size, } int -pfr_clr_astats(struct pfr_table *tbl, struct pfr_addr *addr, int size, - int *nzero, int flags) -{ - struct pfioc_table io; - - if (tbl == NULL || size < 0 || (size && addr == NULL)) { - errno = EINVAL; - return (-1); - } - bzero(&io, sizeof io); - io.pfrio_flags = flags; - io.pfrio_table = *tbl; - io.pfrio_buffer = addr; - io.pfrio_esize = sizeof(*addr); - io.pfrio_size = size; - if (ioctl(dev, DIOCRCLRASTATS, &io)) - return (-1); - if (nzero != NULL) - *nzero = io.pfrio_nzero; - return (0); -} - -int pfr_clr_tstats(struct pfr_table *tbl, int size, int *nzero, int flags) { struct pfioc_table io; @@ -344,32 +321,6 @@ pfr_clr_tstats(struct pfr_table *tbl, int size, int *nzero, int flags) } int -pfr_set_tflags(struct pfr_table *tbl, int size, int setflag, int clrflag, - int *nchange, int *ndel, int flags) -{ - struct pfioc_table io; - - if (size < 0 || (size && !tbl)) { - errno = EINVAL; - return (-1); - } - bzero(&io, sizeof io); - io.pfrio_flags = flags; - io.pfrio_buffer = tbl; - io.pfrio_esize = sizeof(*tbl); - io.pfrio_size = size; - io.pfrio_setflag = setflag; - io.pfrio_clrflag = clrflag; - if (ioctl(dev, DIOCRSETTFLAGS, &io)) - return (-1); - if (nchange) - *nchange = io.pfrio_nchange; - if (ndel) - *ndel = io.pfrio_ndel; - return (0); -} - -int pfr_tst_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size, int *nmatch, int flags) { diff --git a/pflogd/pflogd.8 b/pflogd/pflogd.8 index 4c5762b380b9..e16f866ea85b 100644 --- a/pflogd/pflogd.8 +++ b/pflogd/pflogd.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: pflogd.8,v 1.35 2007/05/31 19:19:47 jmc Exp $ +.\" $OpenBSD: pflogd.8,v 1.36 2008/01/14 17:03:42 okan Exp $ .\" .\" Copyright (c) 2001 Can Erkin Acar. All rights reserved. .\" @@ -24,7 +24,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate$ +.Dd $Mdocdate: May 31 2007 $ .Dt PFLOGD 8 .Os .Sh NAME @@ -118,13 +118,12 @@ By default, will use .Ar pflog0 . .It Fl p Ar pidfile -Writes a file containing the process ID of the program. +Writes a file containing the process ID of the program to +.Pa /var/run . The file name has the form -.Pa /var/run/pidname.pid . -If the option is not given, -.Ar pidfile -defaults to -.Pa pflogd . +.Ao Ar pidfile Ac Ns .pid . +The default is +.Ar pflogd . .It Fl s Ar snaplen Analyze at most the first .Ar snaplen |