aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Laier <mlaier@FreeBSD.org>2008-12-10 20:59:26 +0000
committerMax Laier <mlaier@FreeBSD.org>2008-12-10 20:59:26 +0000
commita13f3058fbd67e3bbda784171bacc8343faf6edf (patch)
tree195f9e255fb6bd332eeb80b937ecc4ed01f9ae96
parentb39deb12b639171038aee6f8770d9bbd44c34fd1 (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/Makefile6
-rw-r--r--authpf/authpf.897
-rw-r--r--authpf/authpf.c227
-rw-r--r--authpf/pathnames.h3
-rw-r--r--ftp-proxy/filter.c13
-rw-r--r--ftp-proxy/ftp-proxy.824
-rw-r--r--ftp-proxy/ftp-proxy.c5
-rw-r--r--man/pf.417
-rw-r--r--man/pf.conf.553
-rw-r--r--man/pfsync.48
-rw-r--r--pfctl/parse.y1026
-rw-r--r--pfctl/pf_print_state.c18
-rw-r--r--pfctl/pfctl.c39
-rw-r--r--pfctl/pfctl.h5
-rw-r--r--pfctl/pfctl_altq.c13
-rw-r--r--pfctl/pfctl_optimize.c13
-rw-r--r--pfctl/pfctl_parser.c4
-rw-r--r--pfctl/pfctl_parser.h6
-rw-r--r--pfctl/pfctl_qstats.c6
-rw-r--r--pfctl/pfctl_radix.c51
-rw-r--r--pflogd/pflogd.815
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);
}
diff --git a/man/pf.4 b/man/pf.4
index 3b6cec93ad4a..ab9ad88f82cc 100644
--- a/man/pf.4
+++ b/man/pf.4
@@ -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