Import pf userland from OpenBSD 3.7 (OPENBSD_3_7 as of today)
This commit is contained in:
parent
51d3d6ad22
commit
511d1c13c3
@ -1,4 +1,4 @@
|
||||
.\" $OpenBSD: authpf.8,v 1.31 2003/12/10 04:10:37 beck Exp $
|
||||
.\" $OpenBSD: authpf.8,v 1.38 2005/01/04 09:57:04 jmc Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2002 Bob Beck (beck@openbsd.org>. All rights reserved.
|
||||
.\"
|
||||
@ -60,6 +60,10 @@ can add filter and translation rules using the syntax described in
|
||||
requires that the
|
||||
.Xr pf 4
|
||||
system be enabled before use.
|
||||
.Nm
|
||||
can also maintain the list of IP address of connected users
|
||||
in the "authpf_users"
|
||||
.Pa table .
|
||||
.Pp
|
||||
.Nm
|
||||
is meant to be used with users who can connect via
|
||||
@ -93,11 +97,16 @@ in order to cause evaluation of any
|
||||
.Nm
|
||||
rules:
|
||||
.Bd -literal -offset indent
|
||||
nat-anchor authpf
|
||||
rdr-anchor authpf
|
||||
binat-anchor authpf
|
||||
anchor authpf
|
||||
nat-anchor "authpf/*"
|
||||
rdr-anchor "authpf/*"
|
||||
binat-anchor "authpf/*"
|
||||
anchor "authpf/*"
|
||||
.Ed
|
||||
.Pp
|
||||
The "/*" at the end of the anchor name is required for
|
||||
.Xr pf 4
|
||||
to process the rulesets attached to the anchor by
|
||||
.Nm authpf .
|
||||
.Sh FILTER AND TRANSLATION RULES
|
||||
Filter and translation rules for
|
||||
.Nm
|
||||
@ -113,10 +122,14 @@ Additionally, the macro
|
||||
.Em user_id
|
||||
is assigned the user name.
|
||||
.Pp
|
||||
Filter and nat rules will first be searched for in
|
||||
Filter and translation rules are stored in a file called
|
||||
.Pa authpf.rules .
|
||||
This file will first be searched for in
|
||||
.Pa /etc/authpf/users/$USER/
|
||||
and then in
|
||||
.Pa /etc/authpf/ .
|
||||
Only one of these files will be used if both are present.
|
||||
.Pp
|
||||
Per-user rules from the
|
||||
.Pa /etc/authpf/users/$USER/
|
||||
directory are intended to be used when non-default rules
|
||||
@ -124,21 +137,11 @@ are needed on an individual user basis.
|
||||
It is important to ensure that a user can not write or change
|
||||
these configuration files.
|
||||
.Pp
|
||||
Filter and translation rules are loaded from the file
|
||||
.Pa /etc/authpf/users/$USER/authpf.rules .
|
||||
If this file does not exist the file
|
||||
.Pa /etc/authpf/authpf.rules
|
||||
is used.
|
||||
The
|
||||
.Pa authpf.rules
|
||||
file must exist in one of the above locations for
|
||||
.Nm
|
||||
to run.
|
||||
.Pp
|
||||
Translation rules are also loaded from this file.
|
||||
The use of translation rules in an
|
||||
.Pa authpf.rules
|
||||
file is optional.
|
||||
.Sh CONFIGURATION
|
||||
Options are controlled by the
|
||||
.Pa /etc/authpf/authpf.conf
|
||||
@ -154,6 +157,10 @@ Currently, the allowed values are as follows:
|
||||
Use the specified
|
||||
.Pa anchor
|
||||
name instead of "authpf".
|
||||
.It table=name
|
||||
Use the specified
|
||||
.Pa table
|
||||
name instead of "authpf_users".
|
||||
.El
|
||||
.Sh USER MESSAGES
|
||||
On successful invocation,
|
||||
@ -218,9 +225,15 @@ it becomes unresponsive, or if arp or address spoofing is used to
|
||||
hijack the session.
|
||||
Note that TCP keepalives are not sufficient for
|
||||
this, since they are not secure.
|
||||
Also note that
|
||||
.Ar AllowTcpForwarding
|
||||
should be disabled for
|
||||
.Nm
|
||||
users to prevent them from circumventing restrictions imposed by the
|
||||
packet filter ruleset.
|
||||
.Pp
|
||||
.Nm
|
||||
will remove statetable entries that were created during a user's
|
||||
will remove state table entries that were created during a user's
|
||||
session.
|
||||
This ensures that there will be no unauthenticated traffic
|
||||
allowed to pass after the controlling
|
||||
@ -391,15 +404,15 @@ Example
|
||||
# ssh and use us as a dns server.
|
||||
internal_if="fxp1"
|
||||
gateway_addr="10.0.1.1"
|
||||
nat-anchor authpf
|
||||
rdr-anchor authpf
|
||||
binat-anchor authpf
|
||||
nat-anchor "authpf/*"
|
||||
rdr-anchor "authpf/*"
|
||||
binat-anchor "authpf/*"
|
||||
block in on $internal_if from any to any
|
||||
pass in quick on $internal_if proto tcp from any to $gateway_addr \e
|
||||
port = ssh
|
||||
pass in quick on $internal_if proto udp from any to $gateway_addr \e
|
||||
port = domain
|
||||
anchor authpf
|
||||
anchor "authpf/*"
|
||||
.Ed
|
||||
.Pp
|
||||
.Sy For a switched, wired net
|
||||
@ -465,6 +478,33 @@ Oct 31 19:42:30.296553 rule 0.bbeck(20267).1/0(match): pass out on fxp1: \e
|
||||
129.128.11.10.60539 > 198.137.240.92.22: S 2131494121:2131494121(0) win \e
|
||||
16384 <mss 1460,nop,nop,sackOK> (DF)
|
||||
.Ed
|
||||
.Pp
|
||||
.Sy Using the authpf_users table
|
||||
\- Simple
|
||||
.Nm
|
||||
settings can be implemented without an anchor by just using the "authpf_users"
|
||||
.Pa table .
|
||||
For example, the following
|
||||
.Xr pf.conf 5
|
||||
lines will give SMTP and IMAP access to logged in users:
|
||||
.Bd -literal
|
||||
table <authpf_users> persist
|
||||
pass in on $ext_if proto tcp from <authpf_users> \e
|
||||
to port { smtp imap } keep state
|
||||
.Ed
|
||||
.Pp
|
||||
It is also possible to use the "authpf_users"
|
||||
.Pa table
|
||||
in combination with anchors.
|
||||
For example,
|
||||
.Xr pf 4
|
||||
processing can be sped up by looking up the anchor
|
||||
only for packets coming from logged in users:
|
||||
.Bd -literal
|
||||
table <authpf_users> persist
|
||||
anchor "authpf/*" from <authpf_users>
|
||||
rdr-anchor "authpf/*" from <authpf_users>
|
||||
.Ed
|
||||
.Sh FILES
|
||||
.Bl -tag -width "/etc/authpf/authpf.conf" -compact
|
||||
.It Pa /etc/authpf/authpf.conf
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: authpf.c,v 1.75 2004/01/29 01:55:10 deraadt Exp $ */
|
||||
/* $OpenBSD: authpf.c,v 1.89 2005/02/10 04:24:15 joel Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1998 - 2002 Bob Beck (beck@openbsd.org).
|
||||
@ -29,7 +29,9 @@
|
||||
#include <sys/file.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/pfvar.h>
|
||||
@ -37,6 +39,7 @@
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <login_cap.h>
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
@ -45,9 +48,6 @@
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <pfctl_parser.h>
|
||||
#include <pfctl.h>
|
||||
|
||||
#include "pathnames.h"
|
||||
|
||||
extern int symset(const char *, const char *, int);
|
||||
@ -58,11 +58,13 @@ static int allowed_luser(char *);
|
||||
static int check_luser(char *, char *);
|
||||
static int remove_stale_rulesets(void);
|
||||
static int change_filter(int, const char *, const char *);
|
||||
static int change_table(int, const char *, const char *);
|
||||
static void authpf_kill_states(void);
|
||||
|
||||
int dev; /* pf device */
|
||||
char anchorname[PF_ANCHOR_NAME_SIZE] = "authpf";
|
||||
char rulesetname[PF_RULESET_NAME_SIZE];
|
||||
char rulesetname[MAXPATHLEN - PF_ANCHOR_NAME_SIZE - 2];
|
||||
char tablename[PF_TABLE_NAME_SIZE] = "authpf_users";
|
||||
|
||||
FILE *pidfp;
|
||||
char *infile; /* file name printed by yyerror() in parse.y */
|
||||
@ -87,10 +89,12 @@ main(int argc, char *argv[])
|
||||
{
|
||||
int lockcnt = 0, n, pidfd;
|
||||
FILE *config;
|
||||
struct in_addr ina;
|
||||
struct in6_addr ina;
|
||||
struct passwd *pw;
|
||||
char *cp;
|
||||
uid_t uid;
|
||||
char *shell;
|
||||
login_cap_t *lc;
|
||||
|
||||
config = fopen(PATH_CONFFILE, "r");
|
||||
|
||||
@ -114,7 +118,8 @@ main(int argc, char *argv[])
|
||||
exit(1);
|
||||
}
|
||||
*cp = '\0';
|
||||
if (inet_pton(AF_INET, ipsrc, &ina) != 1) {
|
||||
if (inet_pton(AF_INET, ipsrc, &ina) != 1 &&
|
||||
inet_pton(AF_INET6, ipsrc, &ina) != 1) {
|
||||
syslog(LOG_ERR,
|
||||
"cannot determine IP from SSH_CLIENT %s", ipsrc);
|
||||
exit(1);
|
||||
@ -128,16 +133,31 @@ main(int argc, char *argv[])
|
||||
|
||||
uid = getuid();
|
||||
pw = getpwuid(uid);
|
||||
endpwent();
|
||||
if (pw == NULL) {
|
||||
syslog(LOG_ERR, "cannot find user for uid %u", uid);
|
||||
goto die;
|
||||
}
|
||||
if (strcmp(pw->pw_shell, PATH_AUTHPF_SHELL)) {
|
||||
|
||||
if ((lc = login_getclass(pw->pw_class)) != NULL)
|
||||
shell = login_getcapstr(lc, "shell", pw->pw_shell,
|
||||
pw->pw_shell);
|
||||
else
|
||||
shell = pw->pw_shell;
|
||||
|
||||
login_close(lc);
|
||||
|
||||
if (strcmp(shell, PATH_AUTHPF_SHELL)) {
|
||||
syslog(LOG_ERR, "wrong shell for user %s, uid %u",
|
||||
pw->pw_name, pw->pw_uid);
|
||||
if (shell != pw->pw_shell)
|
||||
free(shell);
|
||||
goto die;
|
||||
}
|
||||
|
||||
if (shell != pw->pw_shell)
|
||||
free(shell);
|
||||
|
||||
/*
|
||||
* Paranoia, but this data _does_ come from outside authpf, and
|
||||
* truncation would be bad.
|
||||
@ -148,11 +168,11 @@ main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
if ((n = snprintf(rulesetname, sizeof(rulesetname), "%s(%ld)",
|
||||
luser, (long)getpid())) < 0 || n >= sizeof(rulesetname)) {
|
||||
luser, (long)getpid())) < 0 || (u_int)n >= sizeof(rulesetname)) {
|
||||
syslog(LOG_INFO, "%s(%ld) too large, ruleset name will be %ld",
|
||||
luser, (long)getpid(), (long)getpid());
|
||||
if ((n = snprintf(rulesetname, sizeof(rulesetname), "%ld",
|
||||
(long)getpid())) < 0 || n >= sizeof(rulesetname)) {
|
||||
(long)getpid())) < 0 || (u_int)n >= sizeof(rulesetname)) {
|
||||
syslog(LOG_ERR, "pid too large for ruleset name");
|
||||
goto die;
|
||||
}
|
||||
@ -262,12 +282,17 @@ main(int argc, char *argv[])
|
||||
rewind(pidfp);
|
||||
fprintf(pidfp, "%ld\n%s\n", (long)getpid(), luser);
|
||||
fflush(pidfp);
|
||||
(void) ftruncate(fileno(pidfp), ftell(pidfp));
|
||||
(void) ftruncate(fileno(pidfp), ftello(pidfp));
|
||||
|
||||
if (change_filter(1, luser, ipsrc) == -1) {
|
||||
printf("Unable to modify filters\r\n");
|
||||
do_death(0);
|
||||
}
|
||||
if (change_table(1, luser, ipsrc) == -1) {
|
||||
printf("Unable to modify table\r\n");
|
||||
change_filter(0, luser, ipsrc);
|
||||
do_death(0);
|
||||
}
|
||||
|
||||
signal(SIGTERM, need_death);
|
||||
signal(SIGINT, need_death);
|
||||
@ -277,7 +302,7 @@ main(int argc, char *argv[])
|
||||
signal(SIGSTOP, need_death);
|
||||
signal(SIGTSTP, need_death);
|
||||
while (1) {
|
||||
printf("\r\nHello %s, ", luser);
|
||||
printf("\r\nHello %s. ", luser);
|
||||
printf("You are authenticated from host \"%s\"\r\n", ipsrc);
|
||||
setproctitle("%s@%s", luser, ipsrc);
|
||||
print_message(PATH_MESSAGE);
|
||||
@ -350,6 +375,11 @@ read_config(FILE *f)
|
||||
sizeof(anchorname)) >= sizeof(anchorname))
|
||||
goto parse_error;
|
||||
}
|
||||
if (strcasecmp(pair[0], "table") == 0) {
|
||||
if (!pair[1][0] || strlcpy(tablename, pair[1],
|
||||
sizeof(tablename)) >= sizeof(tablename))
|
||||
goto parse_error;
|
||||
}
|
||||
} while (!feof(f) && !ferror(f));
|
||||
fclose(f);
|
||||
return (0);
|
||||
@ -533,12 +563,10 @@ static int
|
||||
remove_stale_rulesets(void)
|
||||
{
|
||||
struct pfioc_ruleset prs;
|
||||
const int action[PF_RULESET_MAX] = { PF_SCRUB,
|
||||
PF_PASS, PF_NAT, PF_BINAT, PF_RDR };
|
||||
u_int32_t nr, mnr;
|
||||
|
||||
memset(&prs, 0, sizeof(prs));
|
||||
strlcpy(prs.anchor, anchorname, sizeof(prs.anchor));
|
||||
strlcpy(prs.path, anchorname, sizeof(prs.path));
|
||||
if (ioctl(dev, DIOCGETRULESETS, &prs)) {
|
||||
if (errno == EINVAL)
|
||||
return (0);
|
||||
@ -565,20 +593,25 @@ remove_stale_rulesets(void)
|
||||
(*s && (t == prs.name || *s != ')')))
|
||||
return (1);
|
||||
if (kill(pid, 0) && errno != EPERM) {
|
||||
int i;
|
||||
int i;
|
||||
struct pfioc_trans_e t_e[PF_RULESET_MAX+1];
|
||||
struct pfioc_trans t;
|
||||
|
||||
for (i = 0; i < PF_RULESET_MAX; ++i) {
|
||||
struct pfioc_rule pr;
|
||||
|
||||
memset(&pr, 0, sizeof(pr));
|
||||
memcpy(pr.anchor, prs.anchor, sizeof(pr.anchor));
|
||||
memcpy(pr.ruleset, prs.name, sizeof(pr.ruleset));
|
||||
pr.rule.action = action[i];
|
||||
if ((ioctl(dev, DIOCBEGINRULES, &pr) ||
|
||||
ioctl(dev, DIOCCOMMITRULES, &pr)) &&
|
||||
errno != EINVAL)
|
||||
return (1);
|
||||
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)
|
||||
return (1);
|
||||
mnr--;
|
||||
} else
|
||||
nr++;
|
||||
@ -592,85 +625,67 @@ remove_stale_rulesets(void)
|
||||
static int
|
||||
change_filter(int add, const char *luser, const char *ipsrc)
|
||||
{
|
||||
char fn[MAXPATHLEN];
|
||||
FILE *f = NULL;
|
||||
struct pfctl pf;
|
||||
struct pfr_buffer t;
|
||||
int i;
|
||||
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;
|
||||
int s;
|
||||
|
||||
if (luser == NULL || !luser[0] || ipsrc == NULL || !ipsrc[0]) {
|
||||
syslog(LOG_ERR, "invalid luser/ipsrc");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (add) {
|
||||
if ((i = snprintf(fn, sizeof(fn), "%s/%s/authpf.rules",
|
||||
PATH_USER_DIR, luser)) < 0 || i >= sizeof(fn)) {
|
||||
syslog(LOG_ERR, "user rule path too long");
|
||||
goto error;
|
||||
}
|
||||
if ((f = fopen(fn, "r")) == NULL && errno != ENOENT) {
|
||||
syslog(LOG_ERR, "cannot open %s (%m)", fn);
|
||||
goto error;
|
||||
}
|
||||
if (f == NULL) {
|
||||
if (strlcpy(fn, PATH_PFRULES, sizeof(fn)) >=
|
||||
sizeof(fn)) {
|
||||
syslog(LOG_ERR, "rule path too long");
|
||||
goto error;
|
||||
}
|
||||
if ((f = fopen(fn, "r")) == NULL) {
|
||||
syslog(LOG_ERR, "cannot open %s (%m)", fn);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pfctl_load_fingerprints(dev, 0)) {
|
||||
syslog(LOG_ERR, "unable to load kernel's OS fingerprints");
|
||||
goto error;
|
||||
}
|
||||
bzero(&t, sizeof(t));
|
||||
t.pfrb_type = PFRB_TRANS;
|
||||
memset(&pf, 0, sizeof(pf));
|
||||
for (i = 0; i < PF_RULESET_MAX; ++i) {
|
||||
if (pfctl_add_trans(&t, i, anchorname, rulesetname)) {
|
||||
syslog(LOG_ERR, "pfctl_add_trans %m");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
if (pfctl_trans(dev, &t, DIOCXBEGIN, 0)) {
|
||||
syslog(LOG_ERR, "DIOCXBEGIN (%s) %m", add?"add":"remove");
|
||||
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) {
|
||||
if (symset("user_ip", ipsrc, 0) ||
|
||||
symset("user_id", luser, 0)) {
|
||||
syslog(LOG_ERR, "symset");
|
||||
goto error;
|
||||
struct stat sb;
|
||||
|
||||
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;
|
||||
|
||||
pf.dev = dev;
|
||||
pf.trans = &t;
|
||||
pf.anchor = anchorname;
|
||||
pf.ruleset = rulesetname;
|
||||
|
||||
infile = fn;
|
||||
if (parse_rules(f, &pf) < 0) {
|
||||
syslog(LOG_ERR, "syntax error in rule file: "
|
||||
"authpf rules not loaded");
|
||||
goto error;
|
||||
}
|
||||
|
||||
infile = NULL;
|
||||
fclose(f);
|
||||
f = NULL;
|
||||
switch (pid = fork()) {
|
||||
case -1:
|
||||
err(1, "fork failed");
|
||||
case 0:
|
||||
execvp(PATH_PFCTL, pargv);
|
||||
warn("exec of %s failed", PATH_PFCTL);
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
if (pfctl_trans(dev, &t, DIOCXCOMMIT, 0)) {
|
||||
syslog(LOG_ERR, "DIOCXCOMMIT (%s) %m", add?"add":"remove");
|
||||
goto error;
|
||||
/* parent */
|
||||
waitpid(pid, &s, 0);
|
||||
if (s != 0) {
|
||||
if (WIFEXITED(s)) {
|
||||
syslog(LOG_ERR, "pfctl exited abnormally");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if (add) {
|
||||
@ -682,17 +697,62 @@ change_filter(int add, const char *luser, const char *ipsrc)
|
||||
ipsrc, luser, Tend.tv_sec - Tstart.tv_sec);
|
||||
}
|
||||
return (0);
|
||||
|
||||
no_mem:
|
||||
syslog(LOG_ERR, "malloc failed");
|
||||
error:
|
||||
if (f != NULL)
|
||||
fclose(f);
|
||||
if (pfctl_trans(dev, &t, DIOCXROLLBACK, 0))
|
||||
syslog(LOG_ERR, "DIOCXROLLBACK (%s) %m", add?"add":"remove");
|
||||
|
||||
free(fdpath);
|
||||
fdpath = NULL;
|
||||
free(rsn);
|
||||
rsn = NULL;
|
||||
free(userstr);
|
||||
userstr = NULL;
|
||||
free(ipstr);
|
||||
ipstr = NULL;
|
||||
free(fn);
|
||||
fn = NULL;
|
||||
infile = NULL;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add/remove this IP from the "authpf_users" table.
|
||||
*/
|
||||
static int
|
||||
change_table(int add, const char *luser, const char *ipsrc)
|
||||
{
|
||||
struct pfioc_table io;
|
||||
struct pfr_addr addr;
|
||||
|
||||
bzero(&io, sizeof(io));
|
||||
strlcpy(io.pfrio_table.pfrt_name, tablename, sizeof(io.pfrio_table));
|
||||
io.pfrio_buffer = &addr;
|
||||
io.pfrio_esize = sizeof(addr);
|
||||
io.pfrio_size = 1;
|
||||
|
||||
bzero(&addr, sizeof(addr));
|
||||
if (ipsrc == NULL || !ipsrc[0])
|
||||
return (-1);
|
||||
if (inet_pton(AF_INET, ipsrc, &addr.pfra_ip4addr) == 1) {
|
||||
addr.pfra_af = AF_INET;
|
||||
addr.pfra_net = 32;
|
||||
} else if (inet_pton(AF_INET6, ipsrc, &addr.pfra_ip6addr) == 1) {
|
||||
addr.pfra_af = AF_INET6;
|
||||
addr.pfra_net = 128;
|
||||
} else {
|
||||
syslog(LOG_ERR, "invalid ipsrc");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (ioctl(dev, add ? DIOCRADDADDRS : DIOCRDELADDRS, &io) &&
|
||||
errno != ESRCH) {
|
||||
syslog(LOG_ERR, "cannot %s %s from table %s: %s",
|
||||
add ? "add" : "remove", ipsrc, tablename,
|
||||
strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is to kill off states that would otherwise be left behind stateful
|
||||
* rules. This means we don't need to allow in more traffic than we really
|
||||
@ -704,24 +764,32 @@ static void
|
||||
authpf_kill_states(void)
|
||||
{
|
||||
struct pfioc_state_kill psk;
|
||||
struct in_addr target;
|
||||
struct pf_addr target;
|
||||
|
||||
memset(&psk, 0, sizeof(psk));
|
||||
psk.psk_af = AF_INET;
|
||||
memset(&target, 0, sizeof(target));
|
||||
|
||||
inet_pton(AF_INET, ipsrc, &target);
|
||||
if (inet_pton(AF_INET, ipsrc, &target.v4) == 1)
|
||||
psk.psk_af = AF_INET;
|
||||
else if (inet_pton(AF_INET6, ipsrc, &target.v6) == 1)
|
||||
psk.psk_af = AF_INET6;
|
||||
else {
|
||||
syslog(LOG_ERR, "inet_pton(%s) failed", ipsrc);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Kill all states from ipsrc */
|
||||
psk.psk_src.addr.v.a.addr.v4 = target;
|
||||
memcpy(&psk.psk_src.addr.v.a.addr, &target,
|
||||
sizeof(psk.psk_src.addr.v.a.addr));
|
||||
memset(&psk.psk_src.addr.v.a.mask, 0xff,
|
||||
sizeof(psk.psk_src.addr.v.a.mask));
|
||||
if (ioctl(dev, DIOCKILLSTATES, &psk))
|
||||
syslog(LOG_ERR, "DIOCKILLSTATES failed (%m)");
|
||||
|
||||
/* Kill all states to ipsrc */
|
||||
psk.psk_af = AF_INET;
|
||||
memset(&psk.psk_src, 0, sizeof(psk.psk_src));
|
||||
psk.psk_dst.addr.v.a.addr.v4 = target;
|
||||
memcpy(&psk.psk_dst.addr.v.a.addr, &target,
|
||||
sizeof(psk.psk_dst.addr.v.a.addr));
|
||||
memset(&psk.psk_dst.addr.v.a.mask, 0xff,
|
||||
sizeof(psk.psk_dst.addr.v.a.mask));
|
||||
if (ioctl(dev, DIOCKILLSTATES, &psk))
|
||||
@ -745,6 +813,7 @@ do_death(int active)
|
||||
|
||||
if (active) {
|
||||
change_filter(0, luser, ipsrc);
|
||||
change_table(0, luser, ipsrc);
|
||||
authpf_kill_states();
|
||||
remove_stale_rulesets();
|
||||
}
|
||||
@ -755,157 +824,3 @@ do_death(int active)
|
||||
syslog(LOG_ERR, "cannot unlink %s (%m)", pidfile);
|
||||
exit(ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* callbacks for parse_rules(void)
|
||||
*/
|
||||
|
||||
int
|
||||
pfctl_add_rule(struct pfctl *pf, struct pf_rule *r)
|
||||
{
|
||||
u_int8_t rs_num;
|
||||
struct pfioc_rule pr;
|
||||
|
||||
switch (r->action) {
|
||||
case PF_PASS:
|
||||
case PF_DROP:
|
||||
rs_num = PF_RULESET_FILTER;
|
||||
break;
|
||||
case PF_SCRUB:
|
||||
rs_num = PF_RULESET_SCRUB;
|
||||
break;
|
||||
case PF_NAT:
|
||||
case PF_NONAT:
|
||||
rs_num = PF_RULESET_NAT;
|
||||
break;
|
||||
case PF_RDR:
|
||||
case PF_NORDR:
|
||||
rs_num = PF_RULESET_RDR;
|
||||
break;
|
||||
case PF_BINAT:
|
||||
case PF_NOBINAT:
|
||||
rs_num = PF_RULESET_BINAT;
|
||||
break;
|
||||
default:
|
||||
syslog(LOG_ERR, "invalid rule action %d", r->action);
|
||||
return (1);
|
||||
}
|
||||
|
||||
bzero(&pr, sizeof(pr));
|
||||
strlcpy(pr.anchor, pf->anchor, sizeof(pr.anchor));
|
||||
strlcpy(pr.ruleset, pf->ruleset, sizeof(pr.ruleset));
|
||||
if (pfctl_add_pool(pf, &r->rpool, r->af))
|
||||
return (1);
|
||||
pr.ticket = pfctl_get_ticket(pf->trans, rs_num, pf->anchor,
|
||||
pf->ruleset);
|
||||
pr.pool_ticket = pf->paddr.ticket;
|
||||
memcpy(&pr.rule, r, sizeof(pr.rule));
|
||||
if (ioctl(pf->dev, DIOCADDRULE, &pr)) {
|
||||
syslog(LOG_ERR, "DIOCADDRULE %m");
|
||||
return (1);
|
||||
}
|
||||
pfctl_clear_pool(&r->rpool);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pfctl_add_pool(struct pfctl *pf, struct pf_pool *p, sa_family_t af)
|
||||
{
|
||||
struct pf_pooladdr *pa;
|
||||
|
||||
if (ioctl(pf->dev, DIOCBEGINADDRS, &pf->paddr)) {
|
||||
syslog(LOG_ERR, "DIOCBEGINADDRS %m");
|
||||
return (1);
|
||||
}
|
||||
pf->paddr.af = af;
|
||||
TAILQ_FOREACH(pa, &p->list, entries) {
|
||||
memcpy(&pf->paddr.addr, pa, sizeof(struct pf_pooladdr));
|
||||
if (ioctl(pf->dev, DIOCADDADDR, &pf->paddr)) {
|
||||
syslog(LOG_ERR, "DIOCADDADDR %m");
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
pfctl_clear_pool(struct pf_pool *pool)
|
||||
{
|
||||
struct pf_pooladdr *pa;
|
||||
|
||||
while ((pa = TAILQ_FIRST(&pool->list)) != NULL) {
|
||||
TAILQ_REMOVE(&pool->list, pa, entries);
|
||||
free(pa);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
pfctl_add_altq(struct pfctl *pf, struct pf_altq *a)
|
||||
{
|
||||
fprintf(stderr, "altq rules not supported in authpf\n");
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
pfctl_set_optimization(struct pfctl *pf, const char *opt)
|
||||
{
|
||||
fprintf(stderr, "set optimization not supported in authpf\n");
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
pfctl_set_logif(struct pfctl *pf, char *ifname)
|
||||
{
|
||||
fprintf(stderr, "set loginterface not supported in authpf\n");
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
pfctl_set_hostid(struct pfctl *pf, u_int32_t hostid)
|
||||
{
|
||||
fprintf(stderr, "set hostid not supported in authpf\n");
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
pfctl_set_timeout(struct pfctl *pf, const char *opt, int seconds, int quiet)
|
||||
{
|
||||
fprintf(stderr, "set timeout not supported in authpf\n");
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
pfctl_set_limit(struct pfctl *pf, const char *opt, unsigned int limit)
|
||||
{
|
||||
fprintf(stderr, "set limit not supported in authpf\n");
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
pfctl_set_debug(struct pfctl *pf, char *d)
|
||||
{
|
||||
fprintf(stderr, "set debug not supported in authpf\n");
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
pfctl_define_table(char *name, int flags, int addrs, const char *anchor,
|
||||
const char *ruleset, struct pfr_buffer *ab, u_int32_t ticket)
|
||||
{
|
||||
fprintf(stderr, "table definitions not yet supported in authpf\n");
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
pfctl_rules(int dev, char *filename, int opts, char *anchorname,
|
||||
char *rulesetname, struct pfr_buffer *t)
|
||||
{
|
||||
/* never called, no anchors inside anchors, but we need the stub */
|
||||
fprintf(stderr, "load anchor not supported from authpf\n");
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
pfctl_print_title(char *title)
|
||||
{
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: pathnames.h,v 1.6 2003/06/03 20:38:59 beck Exp $ */
|
||||
/* $OpenBSD: pathnames.h,v 1.7 2004/04/25 18:40:42 beck Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2002 Chris Kuethe (ckuethe@ualberta.ca)
|
||||
@ -35,3 +35,4 @@
|
||||
#define PATH_DEVFILE "/dev/pf"
|
||||
#define PATH_PIDFILE "/var/authpf"
|
||||
#define PATH_AUTHPF_SHELL "/usr/sbin/authpf"
|
||||
#define PATH_PFCTL "/sbin/pfctl"
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $OpenBSD: ftp-proxy.8,v 1.40 2004/03/16 08:50:07 jmc Exp $
|
||||
.\" $OpenBSD: ftp-proxy.8,v 1.42 2004/11/19 00:47:23 jmc Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1996-2001
|
||||
.\" Obtuse Systems Corporation, All rights reserved.
|
||||
@ -35,14 +35,18 @@
|
||||
.Nd Internet File Transfer Protocol proxy server
|
||||
.Sh SYNOPSIS
|
||||
.Nm ftp-proxy
|
||||
.Bk -words
|
||||
.Op Fl AnrVw
|
||||
.Op Fl a Ar address
|
||||
.Op Fl D Ar debuglevel
|
||||
.Op Fl g Ar group
|
||||
.Op Fl M Ar maxport
|
||||
.Op Fl m Ar minport
|
||||
.Op Fl R Ar address[:port]
|
||||
.Op Fl S Ar address
|
||||
.Op Fl t Ar timeout
|
||||
.Op Fl u Ar user
|
||||
.Ek
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
is a proxy for the Internet File Transfer Protocol.
|
||||
@ -137,12 +141,27 @@ Without this flag,
|
||||
does not require any IP forwarding or NAT beyond the
|
||||
.Em rdr
|
||||
necessary to capture the FTP control connection.
|
||||
.It Fl R Ar address:[port]
|
||||
Reverse proxy mode for FTP servers running behind a NAT gateway.
|
||||
In this mode, no redirection is needed.
|
||||
The proxy is run from
|
||||
.Xr inetd 8
|
||||
on the port that external clients connect to (usually 21).
|
||||
Control connections and passive data connections are forwarded
|
||||
to the server.
|
||||
.It Fl r
|
||||
Use reverse host
|
||||
.Pq reverse DNS
|
||||
lookups for logging and libwrap use.
|
||||
By default,
|
||||
the proxy does not look up hostnames for libwrap or logging purposes.
|
||||
.It Fl S Ar address
|
||||
Source address to use for data connections made by the proxy.
|
||||
Useful when there are multiple addresses (aliases) available
|
||||
to the proxy.
|
||||
Clients may expect data connections to have the same source
|
||||
address as the control connections, and reject or drop other
|
||||
connections.
|
||||
.It Fl t Ar timeout
|
||||
Specifies a timeout, in seconds.
|
||||
The proxy will exit and close open connections if it sees no data
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: ftp-proxy.c,v 1.35 2004/03/14 21:51:44 dhartmei Exp $ */
|
||||
/* $OpenBSD: ftp-proxy.c,v 1.41 2005/03/05 23:11:19 cloder Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996-2001
|
||||
@ -128,6 +128,8 @@ double xfer_start_time;
|
||||
struct sockaddr_in real_server_sa;
|
||||
struct sockaddr_in client_listen_sa;
|
||||
struct sockaddr_in server_listen_sa;
|
||||
struct sockaddr_in proxy_sa;
|
||||
struct in_addr src_addr;
|
||||
|
||||
int client_listen_socket = -1; /* Only used in PASV mode */
|
||||
int client_data_socket = -1; /* Connected socket to real client */
|
||||
@ -138,13 +140,14 @@ int client_data_bytes, server_data_bytes;
|
||||
int AnonFtpOnly;
|
||||
int Verbose;
|
||||
int NatMode;
|
||||
int ReverseMode;
|
||||
|
||||
char ClientName[NI_MAXHOST];
|
||||
char RealServerName[NI_MAXHOST];
|
||||
char OurName[NI_MAXHOST];
|
||||
|
||||
char *User = "proxy";
|
||||
char *Group;
|
||||
const char *User = "proxy";
|
||||
const char *Group;
|
||||
|
||||
extern int Debug_Level;
|
||||
extern int Use_Rdns;
|
||||
@ -172,8 +175,9 @@ static void
|
||||
usage(void)
|
||||
{
|
||||
syslog(LOG_NOTICE,
|
||||
"usage: %s [-AnrVw] [-a address] [-D debuglevel [-g group]"
|
||||
" [-M maxport] [-m minport] [-t timeout] [-u user]", __progname);
|
||||
"usage: %s [-AnrVw] [-a address] [-D debuglevel] [-g group]"
|
||||
" [-M maxport] [-m minport] [-R address[:port]] [-S address]"
|
||||
" [-t timeout] [-u user]", __progname);
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
|
||||
@ -313,7 +317,7 @@ show_xfer_stats(void)
|
||||
char tbuf[1000];
|
||||
double delta;
|
||||
size_t len;
|
||||
int i;
|
||||
int i = -1;
|
||||
|
||||
if (!Verbose)
|
||||
return;
|
||||
@ -340,21 +344,21 @@ show_xfer_stats(void)
|
||||
"data transfer complete (%dh %dm %ds",
|
||||
idelta / (60*60), (idelta % (60*60)) / 60,
|
||||
idelta % 60);
|
||||
if (i >= len)
|
||||
if (i == -1 || i >= len)
|
||||
goto logit;
|
||||
len -= i;
|
||||
} else {
|
||||
i = snprintf(tbuf, len,
|
||||
"data transfer complete (%dm %ds", idelta / 60,
|
||||
idelta % 60);
|
||||
if (i >= len)
|
||||
if (i == -1 || i >= len)
|
||||
goto logit;
|
||||
len -= i;
|
||||
}
|
||||
} else {
|
||||
i = snprintf(tbuf, len, "data transfer complete (%.1fs",
|
||||
delta);
|
||||
if (i >= len)
|
||||
if (i == -1 || i >= len)
|
||||
goto logit;
|
||||
len -= i;
|
||||
}
|
||||
@ -363,7 +367,7 @@ show_xfer_stats(void)
|
||||
i = snprintf(&tbuf[strlen(tbuf)], len,
|
||||
", %d bytes to server) (%.1fKB/s", client_data_bytes,
|
||||
(client_data_bytes / delta) / (double)1024);
|
||||
if (i >= len)
|
||||
if (i == -1 || i >= len)
|
||||
goto logit;
|
||||
len -= i;
|
||||
}
|
||||
@ -371,20 +375,21 @@ show_xfer_stats(void)
|
||||
i = snprintf(&tbuf[strlen(tbuf)], len,
|
||||
", %d bytes to client) (%.1fKB/s", server_data_bytes,
|
||||
(server_data_bytes / delta) / (double)1024);
|
||||
if (i >= len)
|
||||
if (i == -1 || i >= len)
|
||||
goto logit;
|
||||
len -= i;
|
||||
}
|
||||
strlcat(tbuf, ")", sizeof(tbuf));
|
||||
logit:
|
||||
syslog(LOG_INFO, "%s", tbuf);
|
||||
if (i != -1)
|
||||
syslog(LOG_INFO, "%s", tbuf);
|
||||
}
|
||||
|
||||
void
|
||||
log_control_command (char *cmd, int client)
|
||||
{
|
||||
/* log an ftp control command or reply */
|
||||
char *logstring;
|
||||
const char *logstring;
|
||||
int level = LOG_DEBUG;
|
||||
|
||||
if (!Verbose)
|
||||
@ -537,7 +542,7 @@ connect_port_backchannel(void)
|
||||
* getting one bound to port 20 - This is deliberately
|
||||
* not RFC compliant.
|
||||
*/
|
||||
bzero(&listen_sa.sin_addr, sizeof(struct in_addr));
|
||||
bcopy(&src_addr, &listen_sa.sin_addr, sizeof(struct in_addr));
|
||||
client_data_socket = get_backchannel_socket(SOCK_STREAM,
|
||||
min_port, max_port, -1, 1, &listen_sa);
|
||||
if (client_data_socket < 0) {
|
||||
@ -555,7 +560,7 @@ connect_port_backchannel(void)
|
||||
|
||||
salen = 1;
|
||||
listen_sa.sin_family = AF_INET;
|
||||
bzero(&listen_sa.sin_addr, sizeof(struct in_addr));
|
||||
bcopy(&src_addr, &listen_sa.sin_addr, sizeof(struct in_addr));
|
||||
listen_sa.sin_port = htons(20);
|
||||
|
||||
if (setsockopt(client_data_socket, SOL_SOCKET, SO_REUSEADDR,
|
||||
@ -925,7 +930,10 @@ do_server_reply(struct csiob *server, struct csiob *client)
|
||||
|
||||
new_dataconn(0);
|
||||
connection_mode = PASV_MODE;
|
||||
iap = &(server->sa.sin_addr);
|
||||
if (ReverseMode)
|
||||
iap = &(proxy_sa.sin_addr);
|
||||
else
|
||||
iap = &(server->sa.sin_addr);
|
||||
|
||||
debuglog(1, "we want client to use %s:%u", inet_ntoa(*iap),
|
||||
htons(client_listen_sa.sin_port));
|
||||
@ -973,7 +981,7 @@ main(int argc, char *argv[])
|
||||
int use_tcpwrapper = 0;
|
||||
#endif /* LIBWRAP */
|
||||
|
||||
while ((ch = getopt(argc, argv, "a:D:g:m:M:t:u:AnVwr")) != -1) {
|
||||
while ((ch = getopt(argc, argv, "a:D:g:m:M:R:S:t:u:AnVwr")) != -1) {
|
||||
char *p;
|
||||
switch (ch) {
|
||||
case 'a':
|
||||
@ -1016,6 +1024,41 @@ main(int argc, char *argv[])
|
||||
case 'r':
|
||||
Use_Rdns = 1; /* look up hostnames */
|
||||
break;
|
||||
case 'R': {
|
||||
char *s, *t;
|
||||
|
||||
if (!*optarg)
|
||||
usage();
|
||||
if ((s = strdup(optarg)) == NULL) {
|
||||
syslog (LOG_NOTICE,
|
||||
"Insufficient memory (malloc failed)");
|
||||
exit(EX_UNAVAILABLE);
|
||||
}
|
||||
memset(&real_server_sa, 0, sizeof(real_server_sa));
|
||||
real_server_sa.sin_len = sizeof(struct sockaddr_in);
|
||||
real_server_sa.sin_family = AF_INET;
|
||||
t = strchr(s, ':');
|
||||
if (t == NULL)
|
||||
real_server_sa.sin_port = htons(21);
|
||||
else {
|
||||
long port = strtol(t + 1, &p, 10);
|
||||
|
||||
if (*p || port <= 0 || port > 65535)
|
||||
usage();
|
||||
real_server_sa.sin_port = htons(port);
|
||||
*t = 0;
|
||||
}
|
||||
real_server_sa.sin_addr.s_addr = inet_addr(s);
|
||||
if (real_server_sa.sin_addr.s_addr == INADDR_NONE)
|
||||
usage();
|
||||
free(s);
|
||||
ReverseMode = 1;
|
||||
break;
|
||||
}
|
||||
case 'S':
|
||||
if (!inet_aton(optarg, &src_addr))
|
||||
usage();
|
||||
break;
|
||||
case 't':
|
||||
timeout_seconds = strtol(optarg, &p, 10);
|
||||
if (!*optarg || *p)
|
||||
@ -1051,7 +1094,8 @@ main(int argc, char *argv[])
|
||||
memset(&client_iob, 0, sizeof(client_iob));
|
||||
memset(&server_iob, 0, sizeof(server_iob));
|
||||
|
||||
if (get_proxy_env(0, &real_server_sa, &client_iob.sa) == -1)
|
||||
if (get_proxy_env(0, &real_server_sa, &client_iob.sa,
|
||||
&proxy_sa) == -1)
|
||||
exit(EX_PROTOCOL);
|
||||
|
||||
/*
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: getline.c,v 1.15 2003/06/28 01:04:57 deraadt Exp $ */
|
||||
/* $OpenBSD: getline.c,v 1.16 2004/09/16 04:50:51 deraadt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1985, 1988 Regents of the University of California.
|
||||
@ -96,7 +96,7 @@ refill_buffer(struct csiob *iobp)
|
||||
/* don't do tiny reads, grow first if we need to */
|
||||
rqlen = iobp->io_buffer_size - iobp->io_buffer_len;
|
||||
if (rqlen <= 128) {
|
||||
char *tmp;
|
||||
unsigned char *tmp;
|
||||
|
||||
iobp->io_buffer_size += 128;
|
||||
tmp = realloc(iobp->io_buffer, iobp->io_buffer_size);
|
||||
@ -152,7 +152,7 @@ telnet_getline(struct csiob *iobp, struct csiob *telnet_passthrough)
|
||||
{
|
||||
unsigned char ch;
|
||||
int ix;
|
||||
char tbuf[100];
|
||||
unsigned char tbuf[100];
|
||||
|
||||
iobp->line_buffer[0] = '\0';
|
||||
|
||||
@ -236,7 +236,7 @@ telnet_getline(struct csiob *iobp, struct csiob *telnet_passthrough)
|
||||
* nasty.
|
||||
*/
|
||||
if (ix - iobp->next_byte > iobp->line_buffer_size - 5) {
|
||||
char *tmp;
|
||||
unsigned char *tmp;
|
||||
|
||||
iobp->line_buffer_size = 256 + ix - iobp->next_byte;
|
||||
tmp = realloc(iobp->line_buffer,
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: util.c,v 1.18 2004/01/22 16:10:30 beck Exp $ */
|
||||
/* $OpenBSD: util.c,v 1.19 2004/07/06 19:49:11 dhartmei Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996-2001
|
||||
@ -56,6 +56,8 @@
|
||||
|
||||
#include "util.h"
|
||||
|
||||
extern int ReverseMode;
|
||||
|
||||
int Debug_Level;
|
||||
int Use_Rdns;
|
||||
in_addr_t Bind_Addr = INADDR_NONE;
|
||||
@ -75,14 +77,14 @@ debuglog(int debug_level, const char *fmt, ...)
|
||||
|
||||
int
|
||||
get_proxy_env(int connected_fd, struct sockaddr_in *real_server_sa_ptr,
|
||||
struct sockaddr_in *client_sa_ptr)
|
||||
struct sockaddr_in *client_sa_ptr, struct sockaddr_in *proxy_sa_ptr)
|
||||
{
|
||||
struct pfioc_natlook natlook;
|
||||
socklen_t slen;
|
||||
int fd;
|
||||
|
||||
slen = sizeof(*real_server_sa_ptr);
|
||||
if (getsockname(connected_fd, (struct sockaddr *)real_server_sa_ptr,
|
||||
slen = sizeof(*proxy_sa_ptr);
|
||||
if (getsockname(connected_fd, (struct sockaddr *)proxy_sa_ptr,
|
||||
&slen) != 0) {
|
||||
syslog(LOG_ERR, "getsockname() failed (%m)");
|
||||
return(-1);
|
||||
@ -94,6 +96,9 @@ get_proxy_env(int connected_fd, struct sockaddr_in *real_server_sa_ptr,
|
||||
return(-1);
|
||||
}
|
||||
|
||||
if (ReverseMode)
|
||||
return(0);
|
||||
|
||||
/*
|
||||
* Build up the pf natlook structure.
|
||||
* Just for IPv4 right now
|
||||
@ -101,10 +106,10 @@ get_proxy_env(int connected_fd, struct sockaddr_in *real_server_sa_ptr,
|
||||
memset((void *)&natlook, 0, sizeof(natlook));
|
||||
natlook.af = AF_INET;
|
||||
natlook.saddr.addr32[0] = client_sa_ptr->sin_addr.s_addr;
|
||||
natlook.daddr.addr32[0] = real_server_sa_ptr->sin_addr.s_addr;
|
||||
natlook.daddr.addr32[0] = proxy_sa_ptr->sin_addr.s_addr;
|
||||
natlook.proto = IPPROTO_TCP;
|
||||
natlook.sport = client_sa_ptr->sin_port;
|
||||
natlook.dport = real_server_sa_ptr->sin_port;
|
||||
natlook.dport = proxy_sa_ptr->sin_port;
|
||||
natlook.direction = PF_OUT;
|
||||
|
||||
/*
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: util.h,v 1.3 2002/05/23 10:22:14 deraadt Exp $ */
|
||||
/* $OpenBSD: util.h,v 1.5 2005/02/24 15:49:08 dhartmei Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996-2001
|
||||
@ -46,7 +46,7 @@ struct csiob {
|
||||
int line_buffer_size, io_buffer_size, io_buffer_len, next_byte;
|
||||
unsigned char *io_buffer, *line_buffer;
|
||||
struct sockaddr_in sa, real_sa;
|
||||
char *who;
|
||||
const char *who;
|
||||
char alive, got_eof, data_available;
|
||||
int send_oob_flags;
|
||||
};
|
||||
@ -55,7 +55,7 @@ extern int telnet_getline(struct csiob *iobp,
|
||||
struct csiob *telnet_passthrough);
|
||||
|
||||
extern int get_proxy_env(int fd, struct sockaddr_in *server_sa_ptr,
|
||||
struct sockaddr_in *client_sa_ptr);
|
||||
struct sockaddr_in *client_sa_ptr, struct sockaddr_in *proxy_sa_ptr);
|
||||
|
||||
extern int get_backchannel_socket(int type, int min_port, int max_port,
|
||||
int start_port, int direction, struct sockaddr_in *sap);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
.\" $OpenBSD: pf.conf.5,v 1.292 2004/02/24 05:44:48 mcbride Exp $
|
||||
.\" $OpenBSD: pf.conf.5,v 1.326 2005/03/01 18:10:44 jmc Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2002, Daniel Hartmeier
|
||||
.\" All rights reserved.
|
||||
@ -229,7 +229,7 @@ command.
|
||||
.Bl -tag -width xxxx
|
||||
.It Ar set timeout
|
||||
.Pp
|
||||
.Bl -tag -width interval -compact
|
||||
.Bl -tag -width "src.track" -compact
|
||||
.It Ar interval
|
||||
Interval between purging expired states and fragments.
|
||||
.It Ar frag
|
||||
@ -483,6 +483,16 @@ For example:
|
||||
.Pp
|
||||
.Dl set fingerprints \&"/etc/pf.os.devel\&"
|
||||
.Pp
|
||||
.It Ar set skip on <ifspec>
|
||||
List interfaces for which packets should not be filtered.
|
||||
Packets passing in or out on such interfaces are passed as if pf was
|
||||
disabled, i.e. pf does not process them in any way.
|
||||
This can be useful on loopback and other virtual interfaces, when
|
||||
packet filtering is not desired and can have unexpected effects.
|
||||
For example:
|
||||
.Pp
|
||||
.Dl set skip on lo0
|
||||
.Pp
|
||||
.It Ar set debug
|
||||
Set the debug
|
||||
.Ar level
|
||||
@ -547,7 +557,7 @@ Enforces a maximum MSS for matching TCP packets.
|
||||
.It Ar random-id
|
||||
Replaces the IP identification field with random values to compensate
|
||||
for predictable values generated by many hosts.
|
||||
This option only applies to outgoing packets that are not fragmented
|
||||
This option only applies to packets that are not fragmented
|
||||
after the optional fragment reassembly.
|
||||
.It Ar fragment reassemble
|
||||
Using
|
||||
@ -601,7 +611,7 @@ the firewall state, and expires before reaching the destination host.
|
||||
.Ar reassemble tcp
|
||||
will raise the TTL of all packets back up to the highest value seen on
|
||||
the connection.
|
||||
.It timeout modulation
|
||||
.It timestamp modulation
|
||||
Modern TCP stacks will send a timestamp on every TCP packet and echo
|
||||
the other endpoint's timestamp back to them.
|
||||
Many operating systems will merely start the timestamp at zero when
|
||||
@ -618,6 +628,24 @@ guessable base time.
|
||||
will cause
|
||||
.Ar scrub
|
||||
to modulate the TCP timestamps with a random number.
|
||||
.It extended PAWS checks
|
||||
There is a problem with TCP on long fat pipes, in that a packet might get
|
||||
delayed for longer than it takes the connection to wrap its 32-bit sequence
|
||||
space.
|
||||
In such an occurrence, the old packet would be indistinguishable from a
|
||||
new packet and would be accepted as such.
|
||||
The solution to this is called PAWS: Protection Against Wrapped Sequence
|
||||
numbers.
|
||||
It protects against it by making sure the timestamp on each packet does
|
||||
not go backwards.
|
||||
.Ar reassemble tcp
|
||||
also makes sure the timestamp on the packet does not go forward more
|
||||
than the RFC allows.
|
||||
By doing this,
|
||||
.Xr pf 4
|
||||
artificially extends the security of TCP sequence numbers by 10 to 18
|
||||
bits when the host uses appropriately randomized timestamps, since a
|
||||
blind attacker would have to guess the timestamp as well.
|
||||
.El
|
||||
.El
|
||||
.Pp
|
||||
@ -625,6 +653,15 @@ For example,
|
||||
.Bd -literal -offset indent
|
||||
scrub in on $ext_if all fragment reassemble
|
||||
.Ed
|
||||
.Pp
|
||||
The
|
||||
.Ar no
|
||||
option prefixed to a scrub rule causes matching packets to remain unscrubbed,
|
||||
much in the same way as
|
||||
.Ar drop quick
|
||||
works in the packet filter (see below).
|
||||
This mechanism should be used when it is necessary to exclude specific packets
|
||||
from broader scrub rules.
|
||||
.Sh QUEUEING
|
||||
Packets can be assigned to queues for the purpose of bandwidth
|
||||
control.
|
||||
@ -664,6 +701,18 @@ assigned.
|
||||
mainly controls the time packets take to get sent out, while
|
||||
.Ar bandwidth
|
||||
has primarily effects on throughput.
|
||||
.Ar cbq
|
||||
achieves both partitioning and sharing of link bandwidth
|
||||
by hierarchically structured classes.
|
||||
Each class has its own
|
||||
.Ar queue
|
||||
and is assigned its share of
|
||||
.Ar bandwidth .
|
||||
A child class can borrow bandwidth from its parent class
|
||||
as long as excess bandwidth is available
|
||||
(see the option
|
||||
.Ar borrow ,
|
||||
below).
|
||||
.It Ar priq
|
||||
Priority Queueing.
|
||||
.Ar Queues
|
||||
@ -697,6 +746,14 @@ assigned.
|
||||
mainly controls the time packets take to get sent out, while
|
||||
.Ar bandwidth
|
||||
has primarily effects on throughput.
|
||||
.Ar hfsc
|
||||
supports both link-sharing and guaranteed real-time services.
|
||||
It employs a service curve based QoS model,
|
||||
and its unique feature is an ability to decouple
|
||||
.Ar delay
|
||||
and
|
||||
.Ar bandwidth
|
||||
allocation.
|
||||
.El
|
||||
.Pp
|
||||
The interfaces on which queueing should be activated are declared using
|
||||
@ -782,6 +839,7 @@ This value must not exceed the value of the parent
|
||||
.Ar queue
|
||||
and can be specified as an absolute value or a percentage of the parent
|
||||
queue's bandwidth.
|
||||
If not specified, defaults to 100% of the parent queue's bandwidth.
|
||||
The
|
||||
.Ar priq
|
||||
scheduler does not support bandwidth specification.
|
||||
@ -910,8 +968,8 @@ queue developers bandwidth 75% cbq(borrow)
|
||||
queue employees bandwidth 15%
|
||||
queue mail bandwidth 10% priority 0 cbq(borrow ecn)
|
||||
queue ssh bandwidth 20% cbq(borrow) { ssh_interactive, ssh_bulk }
|
||||
queue ssh_interactive priority 7
|
||||
queue ssh_bulk priority 0
|
||||
queue ssh_interactive bandwidth 50% priority 7 cbq(borrow)
|
||||
queue ssh_bulk bandwidth 50% priority 0 cbq(borrow)
|
||||
|
||||
block return out on dc0 inet all queue std
|
||||
pass out on dc0 inet proto tcp from $developerhosts to any port 80 \e
|
||||
@ -935,8 +993,8 @@ the packet filter for evaluation.
|
||||
.Pp
|
||||
Since translation occurs before filtering the filter
|
||||
engine will see packets as they look after any
|
||||
addresses and ports have been translated. Filter rules
|
||||
will therefore have to filter based on the translated
|
||||
addresses and ports have been translated.
|
||||
Filter rules will therefore have to filter based on the translated
|
||||
address and port number.
|
||||
Packets that match a translation rule are only automatically passed if
|
||||
the
|
||||
@ -1098,10 +1156,11 @@ This causes a TCP RST to be returned for
|
||||
packets and an ICMP UNREACHABLE for UDP and other packets.
|
||||
.El
|
||||
.Pp
|
||||
Options returning packets have no effect if
|
||||
Options returning ICMP packets currently have no effect if
|
||||
.Xr pf 4
|
||||
operates on a
|
||||
.Xr bridge 4 .
|
||||
.Xr bridge 4 ,
|
||||
as the code to support this feature has not yet been implemented.
|
||||
.It Ar pass
|
||||
The packet is passed.
|
||||
.El
|
||||
@ -1212,9 +1271,16 @@ addresses and ports.
|
||||
Addresses can be specified in CIDR notation (matching netblocks), as
|
||||
symbolic host names or interface names, or as any of the following keywords:
|
||||
.Pp
|
||||
.Bl -tag -width xxxxxxxxxxxx -compact
|
||||
.Bl -tag -width xxxxxxxxxxxxxx -compact
|
||||
.It Ar any
|
||||
Any address.
|
||||
.It Ar route <label>
|
||||
Any address whose associated route has label
|
||||
.Ar <label> .
|
||||
See
|
||||
.Xr route 4
|
||||
and
|
||||
.Xr route 8 .
|
||||
.It Ar no-route
|
||||
Any address which is not currently routable.
|
||||
.It Ar <table>
|
||||
@ -1308,6 +1374,7 @@ pass in proto tcp from any to any port 25
|
||||
pass in proto tcp from 10.0.0.0/8 port > 1024 \e
|
||||
to ! 10.1.2.3 port != ssh
|
||||
pass in proto tcp from any os "OpenBSD" flags S/SA
|
||||
pass in proto tcp from route "DTAG"
|
||||
.Ed
|
||||
.It Ar all
|
||||
This is equivalent to "from any to any".
|
||||
@ -1392,9 +1459,18 @@ All of SYN, FIN, RST and ACK must be unset.
|
||||
.It Ar icmp6-type <type> code <code>
|
||||
This rule only applies to ICMP or ICMPv6 packets with the specified type
|
||||
and code.
|
||||
Text names for ICMP types and codes are listed in
|
||||
.Xr icmp 4
|
||||
and
|
||||
.Xr icmp6 4 .
|
||||
This parameter is only valid for rules that cover protocols ICMP or
|
||||
ICMP6.
|
||||
The protocol and the ICMP type indicator (icmp-type or icmp6-type)
|
||||
The protocol and the ICMP type indicator
|
||||
.Po
|
||||
.Ar icmp-type
|
||||
or
|
||||
.Ar icmp6-type
|
||||
.Pc
|
||||
must match.
|
||||
.It Ar allow-opts
|
||||
By default, packets which contain IP options are blocked.
|
||||
@ -1500,7 +1576,7 @@ or
|
||||
rules in addition to filter rules.
|
||||
Tags take the same macros as labels (see above).
|
||||
.It Ar tagged <string>
|
||||
Used with filter rules to specify that packets must already
|
||||
Used with filter or translation rules to specify that packets must already
|
||||
be tagged with the given tag in order to match the rule.
|
||||
Inverse tag matching can also be done
|
||||
by specifying the
|
||||
@ -1508,6 +1584,15 @@ by specifying the
|
||||
operator before the
|
||||
.Ar tagged
|
||||
keyword.
|
||||
.It Ar probability <number>
|
||||
A probability attribute can be attached to a rule, with a value set between
|
||||
0 and 1, bounds not included.
|
||||
In that case, the rule will be honoured using the given probability value
|
||||
only.
|
||||
For example, the following rule will drop 20% of incoming ICMP packets:
|
||||
.Bd -literal -offset indent
|
||||
block in proto icmp probability 20%
|
||||
.Ed
|
||||
.El
|
||||
.Sh ROUTING
|
||||
If a packet matches a rule with a route option set, the packet filter will
|
||||
@ -1538,7 +1623,7 @@ option is similar to
|
||||
but routes packets that pass in the opposite direction (replies) to the
|
||||
specified interface.
|
||||
Opposite direction is only defined in the context of a state entry, and
|
||||
.Ar route-to
|
||||
.Ar reply-to
|
||||
is useful only in rules that create state.
|
||||
It can be used on systems with multiple external connections to
|
||||
route all outgoing packets of a connection through the interface
|
||||
@ -1855,32 +1940,96 @@ Prevent state changes for states created by this rule from appearing on the
|
||||
interface.
|
||||
.It Ar <timeout> <seconds>
|
||||
Changes the timeout values used for states created by this rule.
|
||||
.Pp
|
||||
When the
|
||||
.Ar source-track
|
||||
keyword is specified, the number of states per source IP is tracked.
|
||||
The following limits can be set:
|
||||
.Pp
|
||||
.Bl -tag -width xxxx -compact
|
||||
.It Ar max-src-nodes
|
||||
Limits the maximum number of source addresses which can simultaneously
|
||||
have state table entries.
|
||||
.It Ar max-src-states
|
||||
Limits the maximum number of simultaneous state entries that a single
|
||||
source address can create with this rule.
|
||||
.El
|
||||
For a list of all valid timeout names, see
|
||||
.Sx OPTIONS
|
||||
above.
|
||||
.El
|
||||
.Pp
|
||||
Multiple options can be specified, separated by commas:
|
||||
.Bd -literal
|
||||
.Bd -literal -offset indent
|
||||
pass in proto tcp from any to any \e
|
||||
port www flags S/SA keep state \e
|
||||
(max 100, source-track rule, max-src-nodes 75, \e
|
||||
max-src-states 3, tcp.established 60, tcp.closing 5)
|
||||
.Ed
|
||||
.Pp
|
||||
When the
|
||||
.Ar source-track
|
||||
keyword is specified, the number of states per source IP is tracked.
|
||||
.Pp
|
||||
.Bl -tag -width xxxx -compact
|
||||
.It Ar source-track rule
|
||||
The maximum number of states created by this rule is limited by the rule's
|
||||
.Ar max-src-nodes
|
||||
and
|
||||
.Ar max-src-state
|
||||
options.
|
||||
Only state entries created by this particular rule count toward the rule's
|
||||
limits.
|
||||
.It Ar source-track global
|
||||
The number of states created by all rules that use this option is limited.
|
||||
Each rule can specify different
|
||||
.Ar max-src-nodes
|
||||
and
|
||||
.Ar max-src-states
|
||||
options, however state entries created by any participating rule count towards
|
||||
each individual rule's limits.
|
||||
.El
|
||||
.Pp
|
||||
The following limits can be set:
|
||||
.Pp
|
||||
.Bl -tag -width xxxx -compact
|
||||
.It Ar max-src-nodes <number>
|
||||
Limits the maximum number of source addresses which can simultaneously
|
||||
have state table entries.
|
||||
.It Ar max-src-states <number>
|
||||
Limits the maximum number of simultaneous state entries that a single
|
||||
source address can create with this rule.
|
||||
.El
|
||||
.Pp
|
||||
For stateful TCP connections, limits on established connections (connections
|
||||
which have completed the TCP 3-way handshake) can also be enforced
|
||||
per source IP.
|
||||
.Pp
|
||||
.Bl -tag -width xxxx -compact
|
||||
.It Ar max-src-conn <number>
|
||||
Limits the maximum number of simultaneous TCP connections which have
|
||||
completed the 3-way handshake that a single host can make.
|
||||
.It Ar max-src-conn-rate <number> / <seconds>
|
||||
Limit the rate of new connections over a time interval.
|
||||
The connection rate is an approximation calculated as a moving average.
|
||||
.El
|
||||
.Pp
|
||||
Because the 3-way handshake ensures that the source address is not being
|
||||
spoofed, more aggressive action can be taken based on these limits.
|
||||
With the
|
||||
.Ar overload <table>
|
||||
state option, source IP addresses which hit either of the limits on
|
||||
established connections will be added to the named table.
|
||||
This table can be used in the ruleset to block further activity from
|
||||
the offending host, redirect it to a tarpit process, or restrict its
|
||||
bandwidth.
|
||||
.Pp
|
||||
The optional
|
||||
.Ar flush
|
||||
keyword kills all states created by the matching rule which originate
|
||||
from the host which exceeds these limits.
|
||||
The
|
||||
.Ar global
|
||||
modifier to the flush command kills all states originating from the
|
||||
offending host, regardless of which rule created the state.
|
||||
.Pp
|
||||
For example, the following rules will protect the webserver against
|
||||
hosts making more than 100 connections in 10 seconds.
|
||||
Any host which connects faster than this rate will have its address added
|
||||
to the <bad_hosts> table and have all states originating from it flushed.
|
||||
Any new packets arriving from this host will be dropped unconditionally
|
||||
by the block rule.
|
||||
.Bd -literal -offset indent
|
||||
block quick from <bad_hosts>
|
||||
pass in on $ext_if proto tcp to $webserver port www flags S/SA keep state \e
|
||||
(max-src-conn-rate 100/10, overload <bad_hosts> flush global)
|
||||
.Ed
|
||||
.Sh OPERATING SYSTEM FINGERPRINTING
|
||||
Passive OS Fingerprinting is a mechanism to inspect nuances of a TCP
|
||||
connection's initial SYN packet and guess at the host's operating system.
|
||||
@ -1891,7 +2040,7 @@ upon.
|
||||
.Pp
|
||||
The fingerprints may be specified by operating system class, by
|
||||
version, or by subtype/patchlevel.
|
||||
The class of an operating system is typically the vender or genre
|
||||
The class of an operating system is typically the vendor or genre
|
||||
and would be OpenBSD for the
|
||||
.Xr pf 4
|
||||
firewall itself.
|
||||
@ -2056,84 +2205,87 @@ The timeout value can also be adjusted.
|
||||
.Pp
|
||||
Currently, only IPv4 fragments are supported and IPv6 fragments
|
||||
are blocked unconditionally.
|
||||
.Sh ANCHORS AND NAMED RULESETS
|
||||
.Sh ANCHORS
|
||||
Besides the main ruleset,
|
||||
.Xr pfctl 8
|
||||
can load named rulesets into
|
||||
can load rulesets into
|
||||
.Ar anchor
|
||||
attachment points.
|
||||
An
|
||||
.Ar anchor
|
||||
contains a list of named rulesets.
|
||||
is a container that can hold rules, address tables, and other anchors.
|
||||
.Pp
|
||||
An
|
||||
.Ar anchor
|
||||
has a name which specifies where
|
||||
has a name which specifies the path where
|
||||
.Xr pfctl 8
|
||||
can be used to attach sub-rulesets.
|
||||
A named ruleset contains filter and translation rules, like the
|
||||
main ruleset.
|
||||
The main ruleset can reference
|
||||
can be used to access the anchor to perform operations on it, such as
|
||||
attaching child anchors to it or loading rules into it.
|
||||
Anchors may be nested, with components separated by
|
||||
.Sq /
|
||||
characters, similar to how file system hierarchies are laid out.
|
||||
The main ruleset is actually the default anchor, so filter and
|
||||
translation rules, for example, may also be contained in any anchor.
|
||||
.Pp
|
||||
An anchor can reference another
|
||||
.Ar anchor
|
||||
attachment points
|
||||
attachment point
|
||||
using the following kinds
|
||||
of rules:
|
||||
.Bl -tag -width xxxx
|
||||
.It Ar nat-anchor <name>
|
||||
Evaluates the
|
||||
.Ar nat
|
||||
rules of all named rulesets in the specified
|
||||
rules in the specified
|
||||
.Ar anchor .
|
||||
.It Ar rdr-anchor <name>
|
||||
Evaluates the
|
||||
.Ar rdr
|
||||
rules of all named rulesets in the specified
|
||||
rules in the specified
|
||||
.Ar anchor .
|
||||
.It Ar binat-anchor <name>
|
||||
Evaluates the
|
||||
.Ar binat
|
||||
rules of all named rulesets in the specified
|
||||
rules in the specified
|
||||
.Ar anchor .
|
||||
.It Ar anchor <name>
|
||||
Evaluates the filter rules of all named rulesets in the specified
|
||||
Evaluates the filter rules in the specified
|
||||
.Ar anchor .
|
||||
.It Ar load anchor <name>:<ruleset> from <file>
|
||||
Loads the rules from the specified file into the named
|
||||
ruleset
|
||||
.Ar <ruleset>
|
||||
attached to the anchor
|
||||
.Ar <name> .
|
||||
.It Ar load anchor <name> from <file>
|
||||
Loads the rules from the specified file into the
|
||||
anchor
|
||||
.Ar name .
|
||||
.El
|
||||
.Pp
|
||||
When evaluation of the main ruleset reaches an
|
||||
.Ar anchor
|
||||
rule,
|
||||
.Xr pf 4
|
||||
will proceed to evaluate all rules specified in the
|
||||
named rulesets attached to that
|
||||
.Ar anchor .
|
||||
will proceed to evaluate all rules specified in that anchor.
|
||||
.Pp
|
||||
Matching filter rules in named rulesets with the
|
||||
Matching filter and translation rules in anchors with the
|
||||
.Ar quick
|
||||
option and matching translation rules are final and abort the
|
||||
evaluation of both the rules in the
|
||||
.Ar anchor
|
||||
option are final and abort the evaluation of the rules in other
|
||||
anchors
|
||||
and the main ruleset.
|
||||
.Pp
|
||||
Only the main ruleset can contain
|
||||
.Ar anchor
|
||||
rules.
|
||||
.Pp
|
||||
When an
|
||||
rules are evaluated relative to the anchor in which they are contained.
|
||||
For example, all
|
||||
.Ar anchor
|
||||
contains more than one named ruleset, they are evaluated
|
||||
in the alphabetical order of their names.
|
||||
rules specified in the main ruleset will reference anchor
|
||||
attachment points underneath the main ruleset, and
|
||||
.Ar anchor
|
||||
rules specified in a file loaded from a
|
||||
.Ar load anchor
|
||||
rule will be attached under that anchor point.
|
||||
.Pp
|
||||
Rules may contain
|
||||
Rules may be contained in
|
||||
.Ar anchor
|
||||
attachment points which do not contain any rules when the main ruleset
|
||||
is loaded, and later such named rulesets can be manipulated through
|
||||
is loaded, and later such anchors can be manipulated through
|
||||
.Xr pfctl 8
|
||||
without reloading the main ruleset.
|
||||
without reloading the main ruleset or other anchors.
|
||||
For example,
|
||||
.Bd -literal -offset indent
|
||||
ext_if = \&"kue0\&"
|
||||
@ -2145,27 +2297,27 @@ pass in on $ext_if proto tcp from any \e
|
||||
.Ed
|
||||
.Pp
|
||||
blocks all packets on the external interface by default, then evaluates
|
||||
all rulesets in the
|
||||
all rules in the
|
||||
.Ar anchor
|
||||
named "spam", and finally passes all outgoing connections and
|
||||
incoming connections to port 25.
|
||||
.Bd -literal -offset indent
|
||||
# echo \&"block in quick from 1.2.3.4 to any\&" \&| \e
|
||||
pfctl -a spam:manual -f -
|
||||
pfctl -a spam -f -
|
||||
.Ed
|
||||
.Pp
|
||||
loads a single ruleset containing a single rule into the
|
||||
This loads a single rule into the
|
||||
.Ar anchor ,
|
||||
which blocks all packets from a specific address.
|
||||
.Pp
|
||||
The named ruleset can also be populated by adding a
|
||||
The anchor can also be populated by adding a
|
||||
.Ar load anchor
|
||||
rule after the
|
||||
.Ar anchor
|
||||
rule:
|
||||
.Bd -literal -offset indent
|
||||
anchor spam
|
||||
load anchor spam:manual from "/etc/pf-spam.conf"
|
||||
load anchor spam from "/etc/pf-spam.conf"
|
||||
.Ed
|
||||
.Pp
|
||||
When
|
||||
@ -2174,7 +2326,7 @@ loads
|
||||
.Nm pf.conf ,
|
||||
it will also load all the rules from the file
|
||||
.Pa /etc/pf-spam.conf
|
||||
into the named ruleset.
|
||||
into the anchor.
|
||||
.Pp
|
||||
Optionally,
|
||||
.Ar anchor
|
||||
@ -2185,7 +2337,7 @@ using the same syntax as filter rules.
|
||||
When parameters are used, the
|
||||
.Ar anchor
|
||||
rule is only evaluated for matching packets.
|
||||
This allows conditional evaluation of named rulesets, like:
|
||||
This allows conditional evaluation of anchors, like:
|
||||
.Bd -literal -offset indent
|
||||
block on $ext_if all
|
||||
anchor spam proto tcp from any to any port smtp
|
||||
@ -2201,10 +2353,56 @@ packets with destination port 25.
|
||||
Hence,
|
||||
.Bd -literal -offset indent
|
||||
# echo \&"block in quick from 1.2.3.4 to any" \&| \e
|
||||
pfctl -a spam:manual -f -
|
||||
pfctl -a spam -f -
|
||||
.Ed
|
||||
.Pp
|
||||
will only block connections from 1.2.3.4 to port 25.
|
||||
.Pp
|
||||
Anchors may end with the asterisk
|
||||
.Pq Sq *
|
||||
character, which signifies that all anchors attached at that point
|
||||
should be evaluated in the alphabetical ordering of their anchor name.
|
||||
For example,
|
||||
.Bd -literal -offset indent
|
||||
anchor "spam/*"
|
||||
.Ed
|
||||
.Pp
|
||||
will evaluate each rule in each anchor attached to the
|
||||
.Li spam
|
||||
anchor.
|
||||
Note that it will only evaluate anchors that are directly attached to the
|
||||
.Li spam
|
||||
anchor, and will not descend to evaluate anchors recursively.
|
||||
.Pp
|
||||
Since anchors are evaluated relative to the anchor in which they are
|
||||
contained, there is a mechanism for accessing the parent and ancestor
|
||||
anchors of a given anchor.
|
||||
Similar to file system path name resolution, if the sequence
|
||||
.Dq ..
|
||||
appears as an anchor path component, the parent anchor of the current
|
||||
anchor in the path evaluation at that point will become the new current
|
||||
anchor.
|
||||
As an example, consider the following:
|
||||
.Bd -literal -offset indent
|
||||
# echo ' anchor "spam/allowed" ' | pfctl -f -
|
||||
# echo -e ' anchor "../banned" \en pass' | \e
|
||||
pfctl -a spam/allowed -f -
|
||||
.Ed
|
||||
.Pp
|
||||
Evaluation of the main ruleset will lead into the
|
||||
.Li spam/allowed
|
||||
anchor, which will evaluate the rules in the
|
||||
.Li spam/banned
|
||||
anchor, if any, before finally evaluating the
|
||||
.Ar pass
|
||||
rule.
|
||||
.Pp
|
||||
Since the parser specification for anchor names is a string, any
|
||||
reference to an anchor name containing solidus
|
||||
.Pq Sq /
|
||||
characters will require double quote
|
||||
.Pq Sq \&"
|
||||
characters around the anchor name.
|
||||
.Sh TRANSLATION EXAMPLES
|
||||
This example maps incoming requests on port 80 to port 8080, on
|
||||
which a daemon is running (because, for example, it is not run as root,
|
||||
@ -2281,7 +2479,7 @@ nat on $ext_if inet proto udp from any port = isakmp to any -> ($ext_if) \e
|
||||
# Translate outgoing packets' source address (any protocol).
|
||||
# Translate incoming packets' destination address to an internal machine
|
||||
# (bidirectional).
|
||||
binat on $ext_if from 10.1.2.150 to any -> ($ext_if)
|
||||
binat on $ext_if from 10.1.2.150 to any -> $ext_if
|
||||
|
||||
# RDR
|
||||
# Translate incoming packets' destination addresses.
|
||||
@ -2395,7 +2593,7 @@ pass in on $wifi_if from any to any keep state
|
||||
|
||||
block out on $ext_if from any to any
|
||||
pass out quick on $ext_if tagged INTNET keep state
|
||||
pass out on $ext_if from any to any port 80 keep state
|
||||
pass out on $ext_if proto tcp from any to any port 80 keep state
|
||||
|
||||
# tag incoming packets as they are redirected to spamd(8). use the tag
|
||||
# to pass those packets through the packet filter.
|
||||
@ -2422,7 +2620,7 @@ option = "set" ( [ "timeout" ( timeout | "{" timeout-list "}" ) ] |
|
||||
[ "limit" ( limit-item | "{" limit-list "}" ) ] |
|
||||
[ "loginterface" ( interface-name | "none" ) ] |
|
||||
[ "block-policy" ( "drop" | "return" ) ] |
|
||||
[ "state-policy" ( "if-bound" | "group-bound" |
|
||||
[ "state-policy" ( "if-bound" | "group-bound" |
|
||||
"floating" ) ]
|
||||
[ "require-order" ( "yes" | "no" ) ]
|
||||
[ "fingerprints" filename ] |
|
||||
@ -2441,21 +2639,22 @@ filteropt = user | group | flags | icmp-type | icmp6-type | tos |
|
||||
"max-mss" number | "random-id" | "reassemble tcp" |
|
||||
fragmentation | "allow-opts" |
|
||||
"label" string | "tag" string | [ ! ] "tagged" string
|
||||
"queue" ( string | "(" string [ [ "," ] string ] ")" )
|
||||
"queue" ( string | "(" string [ [ "," ] string ] ")" ) |
|
||||
"probability" number"%"
|
||||
|
||||
nat-rule = [ "no" ] "nat" [ "pass" ] [ "on" ifspec ] [ af ]
|
||||
[ protospec ] hosts [ "tag" string ]
|
||||
[ protospec ] hosts [ "tag" string ] [ "tagged" string ]
|
||||
[ "->" ( redirhost | "{" redirhost-list "}" )
|
||||
[ portspec ] [ pooltype ] [ "static-port" ] ]
|
||||
|
||||
binat-rule = [ "no" ] "binat" [ "pass" ] [ "on" interface-name ]
|
||||
[ af ] [ "proto" ( proto-name | proto-number ) ]
|
||||
"from" address [ "/" mask-bits ] "to" ipspec
|
||||
[ "tag" string ]
|
||||
[ "tag" string ] [ "tagged" string ]
|
||||
[ "->" address [ "/" mask-bits ] ]
|
||||
|
||||
rdr-rule = [ "no" ] "rdr" [ "pass" ] [ "on" ifspec ] [ af ]
|
||||
[ protospec ] hosts [ "tag" string ]
|
||||
[ protospec ] hosts [ "tag" string ] [ "tagged" string ]
|
||||
[ "->" ( redirhost | "{" redirhost-list "}" )
|
||||
[ portspec ] [ pooltype ] ]
|
||||
|
||||
@ -2483,7 +2682,7 @@ anchor-rule = "anchor" string [ ( "in" | "out" ) ] [ "on" ifspec ]
|
||||
trans-anchors = ( "nat-anchor" | "rdr-anchor" | "binat-anchor" ) string
|
||||
[ "on" ifspec ] [ af ] [ "proto" ] [ protospec ] [ hosts ]
|
||||
|
||||
load-anchor = "load anchor" anchorname:rulesetname "from" filename
|
||||
load-anchor = "load anchor" string "from" filename
|
||||
|
||||
queueopts-list = queueopts-list queueopts | queueopts
|
||||
queueopts = [ "bandwidth" bandwidth-spec ] |
|
||||
@ -2492,7 +2691,7 @@ queueopts = [ "bandwidth" bandwidth-spec ] |
|
||||
schedulers = ( cbq-def | priq-def | hfsc-def )
|
||||
bandwidth-spec = "number" ( "b" | "Kb" | "Mb" | "Gb" | "%" )
|
||||
|
||||
action = "pass" | "block" [ return ] | "scrub"
|
||||
action = "pass" | "block" [ return ] | [ "no" ] "scrub"
|
||||
return = "drop" | "return" | "return-rst" [ "( ttl" number ")" ] |
|
||||
"return-icmp" [ "(" icmpcode ["," icmp6code ] ")" ] |
|
||||
"return-icmp6" [ "(" icmp6code ")" ]
|
||||
@ -2513,9 +2712,9 @@ proto-list = ( proto-name | proto-number ) [ [ "," ] proto-list ]
|
||||
|
||||
hosts = "all" |
|
||||
"from" ( "any" | "no-route" | "self" | host |
|
||||
"{" host-list "}" ) [ port ] [ os ]
|
||||
"{" host-list "}" | "route" string ) [ port ] [ os ]
|
||||
"to" ( "any" | "no-route" | "self" | host |
|
||||
"{" host-list "}" ) [ port ]
|
||||
"{" host-list "}" | "route" string ) [ port ]
|
||||
|
||||
ipspec = "any" | host | "{" host-list "}"
|
||||
host = [ "!" ] ( address [ "/" mask-bits ] | "<" string ">" )
|
||||
@ -2557,7 +2756,10 @@ tos = "tos" ( "lowdelay" | "throughput" | "reliability" |
|
||||
state-opts = state-opt [ [ "," ] state-opts ]
|
||||
state-opt = ( "max" number | "no-sync" | timeout |
|
||||
"source-track" [ ( "rule" | "global" ) ] |
|
||||
"max-src-nodes" number | "max-src-states" number |
|
||||
"max-src-nodes" number | "max-src-states" number |
|
||||
"max-src-conn" number |
|
||||
"max-src-conn-rate" number "/" number |
|
||||
"overload" "<" string ">" [ "flush" ] |
|
||||
"if-bound" | "group-bound" | "floating" )
|
||||
|
||||
fragmentation = [ "fragment reassemble" | "fragment crop" |
|
||||
@ -2616,6 +2818,7 @@ Example rulesets.
|
||||
.Xr ip6 4 ,
|
||||
.Xr pf 4 ,
|
||||
.Xr pfsync 4 ,
|
||||
.Xr route 4 ,
|
||||
.Xr tcp 4 ,
|
||||
.Xr udp 4 ,
|
||||
.Xr hosts 5 ,
|
||||
@ -2624,7 +2827,8 @@ Example rulesets.
|
||||
.Xr services 5 ,
|
||||
.Xr ftp-proxy 8 ,
|
||||
.Xr pfctl 8 ,
|
||||
.Xr pflogd 8
|
||||
.Xr pflogd 8 ,
|
||||
.Xr route 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $OpenBSD: pf.os.5,v 1.5 2003/10/25 07:55:27 jmc Exp $
|
||||
.\" $OpenBSD: pf.os.5,v 1.6 2004/03/31 11:13:03 dhartmei Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2003 Mike Frantzen <frantzen@w4g.org>
|
||||
.\"
|
||||
@ -160,7 +160,7 @@ exact same TCP options in the same order.
|
||||
.Pp
|
||||
The
|
||||
.Ar class
|
||||
field is the class, genre or vender of the operating system.
|
||||
field is the class, genre or vendor of the operating system.
|
||||
.Pp
|
||||
The
|
||||
.Ar version
|
||||
|
@ -1,6 +1,7 @@
|
||||
.\" $OpenBSD: pfsync.4,v 1.16 2004/03/22 21:04:36 jmc Exp $
|
||||
.\" $OpenBSD: pfsync.4,v 1.22 2005/02/24 15:53:17 jmc Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2002 Michael Shalayeff
|
||||
.\" Copyright (c) 2003-2004 Ryan McBride
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
@ -28,7 +29,7 @@
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm pfsync
|
||||
.Nd packet filter states table logging interface
|
||||
.Nd packet filter state table logging interface
|
||||
.Sh SYNOPSIS
|
||||
.Cd "pseudo-device pfsync"
|
||||
.Sh DESCRIPTION
|
||||
@ -68,20 +69,20 @@ state into one message where possible.
|
||||
The maximum number of times this can be done before the update is sent out
|
||||
is controlled by the
|
||||
.Ar maxupd
|
||||
to ifconfig.
|
||||
parameter to ifconfig
|
||||
(see
|
||||
.Xr ifconfig 8
|
||||
and the example below for more details)
|
||||
and the example below for more details).
|
||||
.Pp
|
||||
Each packet retrieved on this interface has a header associated
|
||||
with it of length
|
||||
.Dv PFSYNC_HDRLEN .
|
||||
The header indicates the version of the protocol, address family,
|
||||
action taken on the following states and the number of state
|
||||
action taken on the following states, and the number of state
|
||||
table entries attached in this packet.
|
||||
This structure, defined in
|
||||
This structure is defined in
|
||||
.Aq Pa net/if_pfsync.h
|
||||
looks like:
|
||||
as:
|
||||
.Bd -literal -offset indent
|
||||
struct pfsync_header {
|
||||
u_int8_t version;
|
||||
@ -95,21 +96,35 @@ States can be synchronised between two or more firewalls using this
|
||||
interface, by specifying a synchronisation interface using
|
||||
.Xr ifconfig 8 .
|
||||
For example, the following command sets fxp0 as the synchronisation
|
||||
interface.
|
||||
interface:
|
||||
.Bd -literal -offset indent
|
||||
# ifconfig pfsync0 syncif fxp0
|
||||
# ifconfig pfsync0 syncdev fxp0
|
||||
.Ed
|
||||
.Pp
|
||||
State change messages are sent out on the synchronisation
|
||||
By default, state change messages are sent out on the synchronisation
|
||||
interface using IP multicast packets.
|
||||
The protocol is IP protocol 240, PFSYNC, and the multicast group
|
||||
used is 224.0.0.240.
|
||||
When a peer address is specified using the
|
||||
.Ic syncpeer
|
||||
keyword, the peer address is used as a destination for the pfsync traffic,
|
||||
and the traffic can then be protected using
|
||||
.Xr ipsec 4 .
|
||||
In such a configuration, the syncdev should be set to the
|
||||
.Xr enc 4
|
||||
interface, as this is where the traffic arrives when it is decapsulated,
|
||||
e.g.:
|
||||
.Bd -literal -offset indent
|
||||
# ifconfig pfsync0 syncpeer 10.0.0.2 syncdev enc0
|
||||
.Ed
|
||||
.Pp
|
||||
It is important that the synchronisation interface be on a trusted
|
||||
network as there is no authentication on the protocol and it would
|
||||
It is important that the pfsync traffic be well secured
|
||||
as there is no authentication on the protocol and it would
|
||||
be trivial to spoof packets which create states, bypassing the pf ruleset.
|
||||
Ideally, this is a network dedicated to pfsync messages,
|
||||
i.e. a crossover cable between two firewalls.
|
||||
Either run the pfsync protocol on a trusted network \- ideally a network
|
||||
dedicated to pfsync messages such as a crossover cable between two firewalls,
|
||||
or specify a peer address and protect the traffic with
|
||||
.Xr ipsec 4 .
|
||||
.Pp
|
||||
There is a one-to-one correspondence between packets seen by
|
||||
.Xr bpf 4
|
||||
@ -135,8 +150,8 @@ is shut down, the second firewall takes over automatically.
|
||||
Both firewalls in this example have three
|
||||
.Xr sis 4
|
||||
interfaces.
|
||||
sis0 is the external interface, on the 10.0.0.0/24 subnet, sis1 is the
|
||||
internal interface, on the 192.168.0.0/24 subnet, and sis2 is the
|
||||
sis0 is the external interface, on the 10.0.0.0/24 subnet; sis1 is the
|
||||
internal interface, on the 192.168.0.0/24 subnet; and sis2 is the
|
||||
.Nm
|
||||
interface, using the 192.168.254.0/24 subnet.
|
||||
A crossover cable connects the two firewalls via their sis2 interfaces.
|
||||
@ -172,7 +187,7 @@ inet 192.168.0.1 255.255.255.0 192.168.0.255 vhid 2 pass bar
|
||||
.Pp
|
||||
.Pa /etc/hostname.pfsync0 :
|
||||
.Bd -literal -offset indent
|
||||
up syncif sis2
|
||||
up syncdev sis2
|
||||
.Ed
|
||||
.Pp
|
||||
.Xr pf 4
|
||||
@ -210,8 +225,11 @@ net.inet.carp.preempt=1
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr bpf 4 ,
|
||||
.Xr carp 4 ,
|
||||
.Xr enc 4 ,
|
||||
.Xr inet 4 ,
|
||||
.Xr inet6 4 ,
|
||||
.Xr ipsec 4 ,
|
||||
.Xr netintro 4 ,
|
||||
.Xr pf 4 ,
|
||||
.Xr hostname.if 5 ,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: pf_print_state.c,v 1.39 2004/02/10 17:48:08 henning Exp $ */
|
||||
/* $OpenBSD: pf_print_state.c,v 1.40 2004/12/10 22:13:26 henning Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Daniel Hartmeier
|
||||
@ -96,6 +96,9 @@ print_addr(struct pf_addr_wrap *addr, sa_family_t af, int verbose)
|
||||
case PF_ADDR_NOROUTE:
|
||||
printf("no-route");
|
||||
return;
|
||||
case PF_ADDR_RTLABEL:
|
||||
printf("route \"%s\"", addr->v.rtlabelname);
|
||||
return;
|
||||
default:
|
||||
printf("?");
|
||||
return;
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $OpenBSD: pfctl.8,v 1.110 2004/03/20 09:31:42 david Exp $
|
||||
.\" $OpenBSD: pfctl.8,v 1.118 2005/01/05 23:41:45 jmc Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2001 Kjell Wooding. All rights reserved.
|
||||
.\"
|
||||
@ -33,17 +33,23 @@
|
||||
.Sh SYNOPSIS
|
||||
.Nm pfctl
|
||||
.Bk -words
|
||||
.Op Fl AdeghNnOqRrvz
|
||||
.Op Fl a Ar anchor Ns Op Ar :ruleset
|
||||
.Op Fl D Ar macro=value
|
||||
.Op Fl AdeghmNnOoqRrvz
|
||||
.Op Fl a Ar anchor
|
||||
.Xo
|
||||
.Oo Fl D
|
||||
.Ar macro Ns = Ns Ar value Oc
|
||||
.Xc
|
||||
.Op Fl F Ar modifier
|
||||
.Op Fl f Ar file
|
||||
.Op Fl i Ar interface
|
||||
.Op Fl k Ar host
|
||||
.Op Fl p Ar device
|
||||
.Op Fl s Ar modifier
|
||||
.Op Fl T Ar command Op Ar address ...
|
||||
.Op Fl t Ar table
|
||||
.Oo Xo
|
||||
.Fl t Ar table
|
||||
.Fl T Ar command
|
||||
.Op Ar address ... Oc
|
||||
.Xc
|
||||
.Op Fl x Ar level
|
||||
.Ek
|
||||
.Sh DESCRIPTION
|
||||
@ -72,9 +78,14 @@ supported.
|
||||
Translation rules are described in
|
||||
.Xr pf.conf 5 .
|
||||
.Pp
|
||||
When the variable pf is set to YES in
|
||||
.Xr rc.conf 8 ,
|
||||
the rule file specified with the variable pf_rules
|
||||
When the variable
|
||||
.Va pf
|
||||
is set to
|
||||
.Dv YES
|
||||
in
|
||||
.Xr rc.conf.local 8 ,
|
||||
the rule file specified with the variable
|
||||
.Va pf_rules
|
||||
is loaded automatically by the
|
||||
.Xr rc 8
|
||||
scripts and the packet filter is enabled.
|
||||
@ -85,7 +96,7 @@ Forwarding can be enabled by setting the
|
||||
variables
|
||||
.Em net.inet.ip.forwarding
|
||||
and/or
|
||||
.Em net.inet6.ip6.forwarding ,
|
||||
.Em net.inet6.ip6.forwarding
|
||||
to 1.
|
||||
Set them permanently in
|
||||
.Xr sysctl.conf 5 .
|
||||
@ -98,48 +109,59 @@ The options are as follows:
|
||||
.It Fl A
|
||||
Load only the queue rules present in the rule file.
|
||||
Other rules and options are ignored.
|
||||
.It Fl a Ar anchor Ns Op Ar :ruleset
|
||||
.It Fl a Ar anchor
|
||||
Apply flags
|
||||
.Fl f ,
|
||||
.Fl F
|
||||
.Fl F ,
|
||||
and
|
||||
.Fl s
|
||||
only to the rules in the specified
|
||||
.Ar anchor
|
||||
and optional named ruleset
|
||||
.Ar ruleset .
|
||||
.Ar anchor .
|
||||
In addition to the main ruleset,
|
||||
.Nm
|
||||
can load and manipulate additional rulesets by name.
|
||||
Named rulesets are attached at
|
||||
.Ar anchor
|
||||
points, which are also referenced by name.
|
||||
can load and manipulate additional rulesets by name,
|
||||
called anchors.
|
||||
The main ruleset is the default anchor.
|
||||
.Pp
|
||||
Anchors are referenced by name and may be nested,
|
||||
with the various components of the anchor path separated by
|
||||
.Sq /
|
||||
characters, similar to how file system hierarchies are laid out.
|
||||
The last component of the anchor path is where ruleset operations are
|
||||
performed.
|
||||
.Pp
|
||||
Evaluation of
|
||||
.Ar anchor
|
||||
rules from the main ruleset is described in
|
||||
.Xr pf.conf 5 .
|
||||
For example, to show all filter rules inside anchor
|
||||
.Li foo :
|
||||
.Pp
|
||||
For example, the following will show all filter rules (see the
|
||||
.Fl s
|
||||
flag below) inside the anchor
|
||||
.Li authpf/smith(1234) ,
|
||||
which would have been created for user smith by
|
||||
.Xr authpf 8 ,
|
||||
PID 1234:
|
||||
.Bd -literal -offset indent
|
||||
# pfctl -a foo -s rules
|
||||
# pfctl -a "authpf/smith(1234)" -s rules
|
||||
.Ed
|
||||
.Pp
|
||||
Private tables can also be put inside subrulesets, either by having table
|
||||
Private tables can also be put inside anchors, either by having table
|
||||
statements in the
|
||||
.Xr pf.conf 5
|
||||
file that is loaded in the anchor, or by using regular table commands as in:
|
||||
file that is loaded in the anchor, or by using regular table commands, as in:
|
||||
.Bd -literal -offset indent
|
||||
# pfctl -a foo:bar -t mytable -T add 1.2.3.4 5.6.7.8
|
||||
# pfctl -a foo/bar -t mytable -T add 1.2.3.4 5.6.7.8
|
||||
.Ed
|
||||
.Pp
|
||||
When a rule referring to a table is loaded in an anchor, the rule will use the
|
||||
private table if one is defined, and then fallback to the table defined in the
|
||||
private table if one is defined, and then fall back to the table defined in the
|
||||
main ruleset, if there is one.
|
||||
This is similar to C rules for variables.
|
||||
This is similar to C rules for variable scope.
|
||||
It is possible to create distinct tables with the same name in the global
|
||||
ruleset and in an anchor, but this is often bad design and a warning will be
|
||||
issued in that case.
|
||||
.It Fl D Ar macro=value
|
||||
.It Fl D Ar macro Ns = Ns Ar value
|
||||
Define
|
||||
.Ar macro
|
||||
to be set to
|
||||
@ -158,23 +180,23 @@ Flush the filter parameters specified by
|
||||
(may be abbreviated):
|
||||
.Pp
|
||||
.Bl -tag -width xxxxxxxxxxxx -compact
|
||||
.It Fl F Ar nat
|
||||
.It Fl F Cm nat
|
||||
Flush the NAT rules.
|
||||
.It Fl F Ar queue
|
||||
.It Fl F Cm queue
|
||||
Flush the queue rules.
|
||||
.It Fl F Ar rules
|
||||
.It Fl F Cm rules
|
||||
Flush the filter rules.
|
||||
.It Fl F Ar state
|
||||
.It Fl F Cm state
|
||||
Flush the state table (NAT and filter).
|
||||
.It Fl F Ar Sources
|
||||
.It Fl F Cm Sources
|
||||
Flush the source tracking table.
|
||||
.It Fl F Ar info
|
||||
.It Fl F Cm info
|
||||
Flush the filter information (statistics that are not bound to rules).
|
||||
.It Fl F Ar Tables
|
||||
.It Fl F Cm Tables
|
||||
Flush the tables.
|
||||
.It Fl F Ar osfp
|
||||
.It Fl F Cm osfp
|
||||
Flush the passive operating system fingerprints.
|
||||
.It Fl F Ar all
|
||||
.It Fl F Cm all
|
||||
Flush all of the above.
|
||||
.El
|
||||
.It Fl f Ar file
|
||||
@ -216,6 +238,13 @@ to
|
||||
.Bd -literal -offset indent
|
||||
# pfctl -k host1 -k host2
|
||||
.Ed
|
||||
.It Fl m
|
||||
Merge in explicitly given options without resetting those
|
||||
which are omitted.
|
||||
Allows single options to be modified without disturbing the others:
|
||||
.Bd -literal -offset indent
|
||||
# echo "set loginterface fxp0" | pfctl -mf -
|
||||
.Ed
|
||||
.It Fl N
|
||||
Load only the NAT rules present in the rule file.
|
||||
Other rules and options are ignored.
|
||||
@ -224,6 +253,39 @@ Do not actually load rules, just parse them.
|
||||
.It Fl O
|
||||
Load only the options present in the rule file.
|
||||
Other rules and options are ignored.
|
||||
.It Fl o
|
||||
Enable the ruleset optimizer.
|
||||
The ruleset optimizer attempts to improve rulesets by removing rule
|
||||
duplication and making better use of rule ordering.
|
||||
Specifically, it does four things:
|
||||
.Pp
|
||||
.Bl -enum -compact
|
||||
.It
|
||||
remove duplicate rules
|
||||
.It
|
||||
remove rules that are a subset of another rule
|
||||
.It
|
||||
combine multiple rules into a table when advantageous
|
||||
.It
|
||||
re-order the rules to improve evaluation performance
|
||||
.El
|
||||
.Pp
|
||||
A second
|
||||
.Fl o
|
||||
may be specified to use the currently loaded ruleset as a feedback profile
|
||||
to tailor the optimization of the
|
||||
.Ar quick
|
||||
rules to the actual network behavior.
|
||||
.Pp
|
||||
It is important to note that the ruleset optimizer will modify the ruleset
|
||||
to improve performance.
|
||||
A side effect of the ruleset modification is that per-rule accounting
|
||||
statistics will have different meanings than before.
|
||||
If per-rule accounting is important for billing purposes or whatnot, either
|
||||
the ruleset optimizer should not be used or a
|
||||
.Ar label
|
||||
field should be added to all of the accounting rules to act as optimization
|
||||
barriers.
|
||||
.It Fl p Ar device
|
||||
Use the device file
|
||||
.Ar device
|
||||
@ -242,9 +304,9 @@ Show the filter parameters specified by
|
||||
(may be abbreviated):
|
||||
.Pp
|
||||
.Bl -tag -width xxxxxxxxxxxxx -compact
|
||||
.It Fl s Ar nat
|
||||
.It Fl s Cm nat
|
||||
Show the currently loaded NAT rules.
|
||||
.It Fl s Ar queue
|
||||
.It Fl s Cm queue
|
||||
Show the currently loaded queue rules.
|
||||
When used together with
|
||||
.Fl v ,
|
||||
@ -254,51 +316,58 @@ When used together with
|
||||
.Nm
|
||||
will loop and show updated queue statistics every five seconds, including
|
||||
measured bandwidth and packets per second.
|
||||
.It Fl s Ar rules
|
||||
.It Fl s Cm rules
|
||||
Show the currently loaded filter rules.
|
||||
When used together with
|
||||
.Fl v ,
|
||||
the per-rule statistics (number of evaluations,
|
||||
packets and bytes) are also shown.
|
||||
Note that the 'skip step' optimization done automatically by the kernel
|
||||
Note that the
|
||||
.Dq skip step
|
||||
optimization done automatically by the kernel
|
||||
will skip evaluation of rules where possible.
|
||||
Packets passed statefully are counted in the rule that created the state
|
||||
(even though the rule isn't evaluated more than once for the entire
|
||||
connection).
|
||||
.It Fl s Ar Anchors
|
||||
Show the currently loaded anchors.
|
||||
.It Fl s Cm Anchors
|
||||
Show the currently loaded anchors directly attached to the main ruleset.
|
||||
If
|
||||
.Fl a Ar anchor
|
||||
is specified as well, the named rulesets currently loaded in the specified
|
||||
anchor are shown instead.
|
||||
.It Fl s Ar state
|
||||
is specified as well, the anchors loaded directly below the given
|
||||
.Ar anchor
|
||||
are shown instead.
|
||||
If
|
||||
.Fl v
|
||||
is specified, all anchors attached under the target anchor will be
|
||||
displayed recursively.
|
||||
.It Fl s Cm state
|
||||
Show the contents of the state table.
|
||||
.It Fl s Ar Sources
|
||||
.It Fl s Cm Sources
|
||||
Show the contents of the source tracking table.
|
||||
.It Fl s Ar info
|
||||
.It Fl s Cm info
|
||||
Show filter information (statistics and counters).
|
||||
When used together with
|
||||
.Fl v ,
|
||||
source tracking statistics are also shown.
|
||||
.It Fl s Ar labels
|
||||
.It Fl s Cm labels
|
||||
Show per-rule statistics (label, evaluations, packets, bytes) of
|
||||
filter rules with labels, useful for accounting.
|
||||
.It Fl s Ar timeouts
|
||||
.It Fl s Cm timeouts
|
||||
Show the current global timeouts.
|
||||
.It Fl s Ar memory
|
||||
.It Fl s Cm memory
|
||||
Show the current pool memory hard limits.
|
||||
.It Fl s Ar Tables
|
||||
.It Fl s Cm Tables
|
||||
Show the list of tables.
|
||||
.It Fl s Ar osfp
|
||||
.It Fl s Cm osfp
|
||||
Show the list of operating system fingerprints.
|
||||
.It Fl s Ar Interfaces
|
||||
.It Fl s Cm Interfaces
|
||||
Show the list of interfaces and interface drivers available to PF.
|
||||
When used together with a double
|
||||
.Fl v ,
|
||||
interface statistics are also shown.
|
||||
.Fl i
|
||||
can be used to select an interface or a group of interfaces.
|
||||
.It Fl s Ar all
|
||||
.It Fl s Cm all
|
||||
Show all of the above, except for the lists of interfaces and operating
|
||||
system fingerprints.
|
||||
.El
|
||||
@ -309,25 +378,25 @@ Specify the
|
||||
Commands include:
|
||||
.Pp
|
||||
.Bl -tag -width xxxxxxxxxxxx -compact
|
||||
.It Fl T Ar kill
|
||||
.It Fl T Cm kill
|
||||
Kill a table.
|
||||
.It Fl T Ar flush
|
||||
.It Fl T Cm flush
|
||||
Flush all addresses of a table.
|
||||
.It Fl T Ar add
|
||||
.It Fl T Cm add
|
||||
Add one or more addresses in a table.
|
||||
Automatically create a nonexisting table.
|
||||
.It Fl T Ar delete
|
||||
.It Fl T Cm delete
|
||||
Delete one or more addresses from a table.
|
||||
.It Fl T Ar replace
|
||||
.It Fl T Cm replace
|
||||
Replace the addresses of the table.
|
||||
Automatically create a nonexisting table.
|
||||
.It Fl T Ar show
|
||||
.It Fl T Cm show
|
||||
Show the content (addresses) of a table.
|
||||
.It Fl T Ar test
|
||||
.It Fl T Cm test
|
||||
Test if the given addresses match a table.
|
||||
.It Fl T Ar zero
|
||||
.It Fl T Cm zero
|
||||
Clear all the statistics of a table.
|
||||
.It Fl T Ar load
|
||||
.It Fl T Cm load
|
||||
Load only the table definitions from
|
||||
.Xr pf.conf 5 .
|
||||
This is used in conjunction with the
|
||||
@ -339,16 +408,18 @@ flag, as in:
|
||||
.El
|
||||
.Pp
|
||||
For the
|
||||
.Ar add ,
|
||||
.Ar delete ,
|
||||
.Ar replace
|
||||
.Cm add ,
|
||||
.Cm delete ,
|
||||
.Cm replace ,
|
||||
and
|
||||
.Ar test
|
||||
.Cm test
|
||||
commands, the list of addresses can be specified either directly on the command
|
||||
line and/or in an unformatted text file, using the
|
||||
.Fl f
|
||||
flag.
|
||||
Comments starting with a "#" are allowed in the text file.
|
||||
Comments starting with a
|
||||
.Sq #
|
||||
are allowed in the text file.
|
||||
With these commands, the
|
||||
.Fl v
|
||||
flag can also be used once or twice, in which case
|
||||
@ -365,11 +436,17 @@ The address/network has been changed (negated).
|
||||
.It D
|
||||
The address/network has been deleted.
|
||||
.It M
|
||||
The address matches (test operation only).
|
||||
The address matches
|
||||
.Po
|
||||
.Cm test
|
||||
operation only
|
||||
.Pc .
|
||||
.It X
|
||||
The address/network is duplicated and therefore ignored.
|
||||
.It Y
|
||||
The address/network cannot be added/deleted due to conflicting "!" attribute.
|
||||
The address/network cannot be added/deleted due to conflicting
|
||||
.Sq \&!
|
||||
attributes.
|
||||
.It Z
|
||||
The address/network has been cleared (statistics).
|
||||
.El
|
||||
@ -381,8 +458,8 @@ flag of
|
||||
For example, the following commands define a wide open firewall which will keep
|
||||
track of packets going to or coming from the
|
||||
.Ox
|
||||
ftp server.
|
||||
The following commands configure the firewall and send 10 pings to the ftp
|
||||
FTP server.
|
||||
The following commands configure the firewall and send 10 pings to the FTP
|
||||
server:
|
||||
.Bd -literal -offset indent
|
||||
# printf "table <test> { ftp.openbsd.org }\en \e
|
||||
@ -391,11 +468,11 @@ server:
|
||||
.Ed
|
||||
.Pp
|
||||
We can now use the table
|
||||
.Ar show
|
||||
.Cm show
|
||||
command to output, for each address and packet direction, the number of packets
|
||||
and bytes that are being passed or blocked by rules referencing the table.
|
||||
The time at which the current accounting started is also shown with the
|
||||
.Ar Cleared
|
||||
.Dq Cleared
|
||||
line.
|
||||
.Bd -literal -offset indent
|
||||
# pfctl -t test -vTshow
|
||||
@ -411,7 +488,8 @@ Similarly, it is possible to view global information about the tables
|
||||
by using the
|
||||
.Fl v
|
||||
modifier twice and the
|
||||
.Ar show Tables
|
||||
.Fl s
|
||||
.Cm Tables
|
||||
command.
|
||||
This will display the number of addresses on each table,
|
||||
the number of rules which reference the table, and the global
|
||||
@ -432,16 +510,18 @@ packet statistics for the whole table:
|
||||
.Ed
|
||||
.Pp
|
||||
As we can see here, only one packet \- the initial ping request \- matched the
|
||||
table; but all packets passing as the result of the state are correctly
|
||||
table, but all packets passing as the result of the state are correctly
|
||||
accounted for.
|
||||
Reloading the table(s) or ruleset will not affect packet accounting in any way.
|
||||
The two
|
||||
.Ar XPass
|
||||
.Dq XPass
|
||||
counters are incremented instead of the
|
||||
.Ar Pass
|
||||
counters when a "stateful" packet is passed but doesn't match the table
|
||||
anymore.
|
||||
This will happen in our example if someone flushes the table while the ping
|
||||
.Dq Pass
|
||||
counters when a
|
||||
.Dq stateful
|
||||
packet is passed but doesn't match the table anymore.
|
||||
This will happen in our example if someone flushes the table while the
|
||||
.Xr ping 8
|
||||
command is running.
|
||||
.Pp
|
||||
When used with a single
|
||||
@ -455,11 +535,11 @@ The flags are defined as follows:
|
||||
For constant tables, which cannot be altered outside
|
||||
.Xr pf.conf 5 .
|
||||
.It p
|
||||
For persistent tables, which don't get automatically flushed when no rules
|
||||
For persistent tables, which don't get automatically killed when no rules
|
||||
refer to them.
|
||||
.It a
|
||||
For tables which are part of the
|
||||
.Ar active
|
||||
.Em active
|
||||
tableset.
|
||||
Tables without this flag do not really exist, cannot contain addresses, and are
|
||||
only listed if the
|
||||
@ -467,7 +547,7 @@ only listed if the
|
||||
flag is given.
|
||||
.It i
|
||||
For tables which are part of the
|
||||
.Ar inactive
|
||||
.Em inactive
|
||||
tableset.
|
||||
This flag can only be witnessed briefly during the loading of
|
||||
.Xr pf.conf 5 .
|
||||
@ -475,7 +555,7 @@ This flag can only be witnessed briefly during the loading of
|
||||
For tables which are referenced (used) by rules.
|
||||
.It h
|
||||
This flag is set when a table in the main ruleset is hidden by one or more
|
||||
tables of the same name in sub-rulesets (anchors).
|
||||
tables of the same name from anchors attached below it.
|
||||
.El
|
||||
.It Fl t Ar table
|
||||
Specify the name of the table.
|
||||
@ -484,20 +564,20 @@ Produce more verbose output.
|
||||
A second use of
|
||||
.Fl v
|
||||
will produce even more verbose output including ruleset warnings.
|
||||
See previous section for its effect on table commands.
|
||||
See the previous section for its effect on table commands.
|
||||
.It Fl x Ar level
|
||||
Set the debug
|
||||
.Ar level
|
||||
(may be abbreviated) to one of the following:
|
||||
.Pp
|
||||
.Bl -tag -width xxxxxxxxxxxx -compact
|
||||
.It Fl x Ar none
|
||||
.It Fl x Cm none
|
||||
Don't generate debug messages.
|
||||
.It Fl x Ar urgent
|
||||
.It Fl x Cm urgent
|
||||
Generate debug messages only for serious errors.
|
||||
.It Fl x Ar misc
|
||||
.It Fl x Cm misc
|
||||
Generate debug messages for various errors.
|
||||
.It Fl x Ar loud
|
||||
.It Fl x Cm loud
|
||||
Generate debug messages for common conditions.
|
||||
.El
|
||||
.It Fl z
|
||||
@ -507,12 +587,15 @@ Clear per-rule statistics.
|
||||
.Bl -tag -width "/etc/pf.conf" -compact
|
||||
.It Pa /etc/pf.conf
|
||||
Packet filter rules file.
|
||||
.It Pa /etc/pf.os
|
||||
Passive operating system fingerprint database.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr pf 4 ,
|
||||
.Xr pf.conf 5 ,
|
||||
.Xr pf.os 5 ,
|
||||
.Xr sysctl.conf 5 ,
|
||||
.Xr authpf 8 ,
|
||||
.Xr ftp-proxy 8 ,
|
||||
.Xr rc 8 ,
|
||||
.Xr rc.conf 8 ,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: pfctl.h,v 1.33 2004/02/19 21:37:01 cedric Exp $ */
|
||||
/* $OpenBSD: pfctl.h,v 1.37 2005/01/05 18:23:10 mcbride Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Daniel Hartmeier
|
||||
@ -64,8 +64,6 @@ 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_begin(struct pfr_table *, int *, int *, int);
|
||||
int pfr_ina_commit(struct pfr_table *, 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 *);
|
||||
@ -79,13 +77,14 @@ int pfi_get_ifaces(const char *, struct pfi_if *, int *, int);
|
||||
int pfi_clr_istats(const char *, int *, int);
|
||||
|
||||
void pfctl_print_title(char *);
|
||||
int pfctl_clear_tables(const char *, const char *, int);
|
||||
int pfctl_show_tables(const char *, const char *, int);
|
||||
int pfctl_clear_tables(const char *, int);
|
||||
int pfctl_show_tables(const char *, int);
|
||||
int pfctl_command_tables(int, char *[], char *, const char *, char *,
|
||||
const char *, const char *, int);
|
||||
const char *, int);
|
||||
int pfctl_show_altq(int, const char *, int, int);
|
||||
void warn_namespace_collision(const char *);
|
||||
int pfctl_show_ifaces(const char *, int);
|
||||
FILE *pfctl_fopen(const char *, const char *);
|
||||
|
||||
#ifndef DEFAULT_PRIORITY
|
||||
#define DEFAULT_PRIORITY 1
|
||||
@ -103,6 +102,8 @@ struct segment {
|
||||
double x, y, d, m;
|
||||
};
|
||||
|
||||
extern int loadopt;
|
||||
|
||||
int check_commit_altq(int, int);
|
||||
void pfaltq_store(struct pf_altq *);
|
||||
void pfaltq_free(struct pf_altq *);
|
||||
@ -116,9 +117,9 @@ void print_state(struct pf_state *, int);
|
||||
int unmask(struct pf_addr *, sa_family_t);
|
||||
|
||||
int pfctl_cmdline_symset(char *);
|
||||
int pfctl_add_trans(struct pfr_buffer *, int, const char *, const char *);
|
||||
int pfctl_add_trans(struct pfr_buffer *, int, const char *);
|
||||
u_int32_t
|
||||
pfctl_get_ticket(struct pfr_buffer *, int, const char *, const char *);
|
||||
pfctl_get_ticket(struct pfr_buffer *, int, const char *);
|
||||
int pfctl_trans(int, struct pfr_buffer *, u_long, int);
|
||||
|
||||
#endif /* _PFCTL_H_ */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: pfctl_altq.c,v 1.83 2004/03/14 21:51:44 dhartmei Exp $ */
|
||||
/* $OpenBSD: pfctl_altq.c,v 1.86 2005/02/28 14:04:51 henning Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2002
|
||||
@ -304,7 +304,8 @@ eval_pfqueue(struct pfctl *pf, struct pf_altq *pa, struct node_queue_bw *bw,
|
||||
struct node_queue_opt *opts)
|
||||
{
|
||||
/* should be merged with expand_queue */
|
||||
struct pf_altq *if_pa, *parent;
|
||||
struct pf_altq *if_pa, *parent, *altq;
|
||||
u_int32_t bwsum;
|
||||
int error = 0;
|
||||
|
||||
/* find the corresponding interface and copy fields used by queues */
|
||||
@ -336,22 +337,35 @@ eval_pfqueue(struct pfctl *pf, struct pf_altq *pa, struct node_queue_bw *bw,
|
||||
pa->qlimit = DEFAULT_QLIMIT;
|
||||
|
||||
if (pa->scheduler == ALTQT_CBQ || pa->scheduler == ALTQT_HFSC) {
|
||||
if ((pa->bandwidth = eval_bwspec(bw,
|
||||
parent == NULL ? 0 : parent->bandwidth)) == 0) {
|
||||
fprintf(stderr, "bandwidth for %s invalid (%d / %d)\n",
|
||||
pa->qname, bw->bw_absolute, bw->bw_percent);
|
||||
return (1);
|
||||
}
|
||||
pa->bandwidth = eval_bwspec(bw,
|
||||
parent == NULL ? 0 : parent->bandwidth);
|
||||
|
||||
if (pa->bandwidth > pa->ifbandwidth) {
|
||||
fprintf(stderr, "bandwidth for %s higher than "
|
||||
"interface\n", pa->qname);
|
||||
return (1);
|
||||
}
|
||||
if (parent != NULL && pa->bandwidth > parent->bandwidth) {
|
||||
fprintf(stderr, "bandwidth for %s higher than parent\n",
|
||||
pa->qname);
|
||||
return (1);
|
||||
/* check the sum of the child bandwidth is under parent's */
|
||||
if (parent != NULL) {
|
||||
if (pa->bandwidth > parent->bandwidth) {
|
||||
warnx("bandwidth for %s higher than parent",
|
||||
pa->qname);
|
||||
return (1);
|
||||
}
|
||||
bwsum = 0;
|
||||
TAILQ_FOREACH(altq, &altqs, entries) {
|
||||
if (strncmp(altq->ifname, pa->ifname,
|
||||
IFNAMSIZ) == 0 &&
|
||||
altq->qname[0] != 0 &&
|
||||
strncmp(altq->parent, pa->parent,
|
||||
PF_QNAME_SIZE) == 0)
|
||||
bwsum += altq->bandwidth;
|
||||
}
|
||||
bwsum += pa->bandwidth;
|
||||
if (bwsum > parent->bandwidth) {
|
||||
warnx("the sum of the child bandwidth higher"
|
||||
" than parent \"%s\"", parent->qname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -695,7 +709,7 @@ eval_pfqueue_hfsc(struct pfctl *pf, struct pf_altq *pa)
|
||||
* for the real-time service curve, the sum of the service curves
|
||||
* should not exceed 80% of the interface bandwidth. 20% is reserved
|
||||
* not to over-commit the actual interface bandwidth.
|
||||
* for the link-sharing service curve, the sum of the child service
|
||||
* for the linkshare service curve, the sum of the child service
|
||||
* curve should not exceed the parent service curve.
|
||||
* for the upper-limit service curve, the assigned bandwidth should
|
||||
* be smaller than the interface bandwidth, and the upper-limit should
|
||||
@ -722,7 +736,7 @@ eval_pfqueue_hfsc(struct pfctl *pf, struct pf_altq *pa)
|
||||
if (strncmp(altq->parent, pa->parent, PF_QNAME_SIZE) != 0)
|
||||
continue;
|
||||
|
||||
/* if the class has a link-sharing service curve, add it. */
|
||||
/* if the class has a linkshare service curve, add it. */
|
||||
if (opts->lssc_m2 != 0 && altq->pq_u.hfsc_opts.lssc_m2 != 0) {
|
||||
sc.m1 = altq->pq_u.hfsc_opts.lssc_m1;
|
||||
sc.d = altq->pq_u.hfsc_opts.lssc_d;
|
||||
@ -733,22 +747,35 @@ eval_pfqueue_hfsc(struct pfctl *pf, struct pf_altq *pa)
|
||||
|
||||
/* check the real-time service curve. reserve 20% of interface bw */
|
||||
if (opts->rtsc_m2 != 0) {
|
||||
/* add this queue to the sum */
|
||||
sc.m1 = opts->rtsc_m1;
|
||||
sc.d = opts->rtsc_d;
|
||||
sc.m2 = opts->rtsc_m2;
|
||||
gsc_add_sc(&rtsc, &sc);
|
||||
/* compare the sum with 80% of the interface */
|
||||
sc.m1 = 0;
|
||||
sc.d = 0;
|
||||
sc.m2 = pa->ifbandwidth / 100 * 80;
|
||||
if (!is_gsc_under_sc(&rtsc, &sc)) {
|
||||
warnx("real-time sc exceeds the interface bandwidth");
|
||||
warnx("real-time sc exceeds 80%% of the interface "
|
||||
"bandwidth (%s)", rate2str((double)sc.m2));
|
||||
goto err_ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* check the link-sharing service curve. */
|
||||
/* check the linkshare service curve. */
|
||||
if (opts->lssc_m2 != 0) {
|
||||
/* add this queue to the child sum */
|
||||
sc.m1 = opts->lssc_m1;
|
||||
sc.d = opts->lssc_d;
|
||||
sc.m2 = opts->lssc_m2;
|
||||
gsc_add_sc(&lssc, &sc);
|
||||
/* compare the sum of the children with parent's sc */
|
||||
sc.m1 = parent->pq_u.hfsc_opts.lssc_m1;
|
||||
sc.d = parent->pq_u.hfsc_opts.lssc_d;
|
||||
sc.m2 = parent->pq_u.hfsc_opts.lssc_m2;
|
||||
if (!is_gsc_under_sc(&lssc, &sc)) {
|
||||
warnx("link-sharing sc exceeds parent's sc");
|
||||
warnx("linkshare sc exceeds parent's sc");
|
||||
goto err_ret;
|
||||
}
|
||||
}
|
||||
@ -1075,6 +1102,7 @@ getifspeed(char *ifname)
|
||||
|
||||
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
|
||||
err(1, "socket");
|
||||
bzero(&ifr, sizeof(ifr));
|
||||
if (strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)) >=
|
||||
sizeof(ifr.ifr_name))
|
||||
errx(1, "getifspeed: strlcpy");
|
||||
@ -1096,6 +1124,7 @@ getifmtu(char *ifname)
|
||||
|
||||
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
|
||||
err(1, "socket");
|
||||
bzero(&ifr, sizeof(ifr));
|
||||
if (strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)) >=
|
||||
sizeof(ifr.ifr_name))
|
||||
errx(1, "getifmtu: strlcpy");
|
||||
|
1563
contrib/pf/pfctl/pfctl_optimize.c
Normal file
1563
contrib/pf/pfctl/pfctl_optimize.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: pfctl_osfp.c,v 1.8 2004/02/27 10:42:00 henning Exp $ */
|
||||
/* $OpenBSD: pfctl_osfp.c,v 1.12 2005/02/17 13:18:00 aaron Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003 Mike Frantzen <frantzen@openbsd.org>
|
||||
@ -97,8 +97,8 @@ pfctl_file_fingerprints(int dev, int opts, const char *fp_filename)
|
||||
|
||||
pfctl_flush_my_fingerprints(&classes);
|
||||
|
||||
if ((in = fopen(fp_filename, "r")) == NULL) {
|
||||
warn("fopen(%s)", fp_filename);
|
||||
if ((in = pfctl_fopen(fp_filename, "r")) == NULL) {
|
||||
warn("%s", fp_filename);
|
||||
return (1);
|
||||
}
|
||||
class = version = subtype = desc = tcpopts = NULL;
|
||||
@ -276,9 +276,9 @@ pfctl_flush_my_fingerprints(struct name_list *list)
|
||||
while ((nm = LIST_FIRST(list)) != NULL) {
|
||||
LIST_REMOVE(nm, nm_entry);
|
||||
pfctl_flush_my_fingerprints(&nm->nm_sublist);
|
||||
fingerprint_count--;
|
||||
free(nm);
|
||||
}
|
||||
fingerprint_count = 0;
|
||||
class_count = 0;
|
||||
}
|
||||
|
||||
@ -348,7 +348,7 @@ pfctl_get_fingerprint(const char *name)
|
||||
|
||||
if ((wr_name = strdup(name)) == NULL)
|
||||
err(1, "malloc");
|
||||
if ((ptr = index(wr_name, ' ')) == NULL) {
|
||||
if ((ptr = strchr(wr_name, ' ')) == NULL) {
|
||||
free(wr_name);
|
||||
return (PF_OSFP_NOMATCH);
|
||||
}
|
||||
@ -508,9 +508,9 @@ found:
|
||||
strlcat(buf, " ", len);
|
||||
strlcat(buf, version_name, len);
|
||||
if (subtype_name) {
|
||||
if (index(version_name, ' '))
|
||||
if (strchr(version_name, ' '))
|
||||
strlcat(buf, " ", len);
|
||||
else if (index(version_name, '.') &&
|
||||
else if (strchr(version_name, '.') &&
|
||||
isdigit(*subtype_name))
|
||||
strlcat(buf, ".", len);
|
||||
else
|
||||
@ -702,9 +702,8 @@ fingerprint_name_entry(struct name_list *list, char *name)
|
||||
nm_entry = calloc(1, sizeof(*nm_entry));
|
||||
if (nm_entry == NULL)
|
||||
err(1, "calloc");
|
||||
LIST_INIT(&nm_entry->nm_sublist);
|
||||
strlcpy(nm_entry->nm_name, name,
|
||||
sizeof(nm_entry->nm_name));
|
||||
LIST_INIT(&nm_entry->nm_sublist);
|
||||
strlcpy(nm_entry->nm_name, name, sizeof(nm_entry->nm_name));
|
||||
}
|
||||
LIST_INSERT_HEAD(list, nm_entry, nm_entry);
|
||||
return (nm_entry);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: pfctl_parser.c,v 1.194 2004/03/15 15:25:44 dhartmei Exp $ */
|
||||
/* $OpenBSD: pfctl_parser.c,v 1.211 2004/12/07 10:33:41 dhartmei Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Daniel Hartmeier
|
||||
@ -34,6 +34,8 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/proc.h>
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
@ -62,6 +64,7 @@ void print_ugid (u_int8_t, unsigned, unsigned, const char *, unsigned);
|
||||
void print_flags (u_int8_t);
|
||||
void print_fromto(struct pf_rule_addr *, pf_osfp_t,
|
||||
struct pf_rule_addr *, u_int8_t, u_int8_t, int);
|
||||
int ifa_skip_if(const char *filter, struct node_host *p);
|
||||
|
||||
struct node_host *host_if(const char *, int);
|
||||
struct node_host *host_v4(const char *, int);
|
||||
@ -182,6 +185,7 @@ const struct pf_timeout pf_timeouts[] = {
|
||||
{ "tcp.closing", PFTM_TCP_CLOSING },
|
||||
{ "tcp.finwait", PFTM_TCP_FIN_WAIT },
|
||||
{ "tcp.closed", PFTM_TCP_CLOSED },
|
||||
{ "tcp.tsdiff", PFTM_TS_DIFF },
|
||||
{ "udp.first", PFTM_UDP_FIRST_PACKET },
|
||||
{ "udp.single", PFTM_UDP_SINGLE },
|
||||
{ "udp.multiple", PFTM_UDP_MULTIPLE },
|
||||
@ -362,13 +366,13 @@ print_fromto(struct pf_rule_addr *src, pf_osfp_t osfp, struct pf_rule_addr *dst,
|
||||
PF_AZERO(&src->addr.v.a.mask, AF_INET6) &&
|
||||
PF_AZERO(&dst->addr.v.a.addr, AF_INET6) &&
|
||||
PF_AZERO(&dst->addr.v.a.mask, AF_INET6) &&
|
||||
!src->not && !dst->not &&
|
||||
!src->neg && !dst->neg &&
|
||||
!src->port_op && !dst->port_op &&
|
||||
osfp == PF_OSFP_ANY)
|
||||
printf(" all");
|
||||
else {
|
||||
printf(" from ");
|
||||
if (src->not)
|
||||
if (src->neg)
|
||||
printf("! ");
|
||||
print_addr(&src->addr, af, verbose);
|
||||
if (src->port_op)
|
||||
@ -380,7 +384,7 @@ print_fromto(struct pf_rule_addr *src, pf_osfp_t osfp, struct pf_rule_addr *dst,
|
||||
sizeof(buf)));
|
||||
|
||||
printf(" to ");
|
||||
if (dst->not)
|
||||
if (dst->neg)
|
||||
printf("! ");
|
||||
print_addr(&dst->addr, af, verbose);
|
||||
if (dst->port_op)
|
||||
@ -468,6 +472,7 @@ print_pool(struct pf_pool *pool, u_int16_t p1, u_int16_t p2,
|
||||
}
|
||||
|
||||
const char *pf_reasons[PFRES_MAX+1] = PFRES_NAMES;
|
||||
const char *pf_lcounters[LCNT_MAX+1] = LCNT_NAMES;
|
||||
const char *pf_fcounters[FCNT_MAX+1] = FCNT_NAMES;
|
||||
const char *pf_scounters[FCNT_MAX+1] = FCNT_NAMES;
|
||||
|
||||
@ -570,6 +575,18 @@ print_status(struct pf_status *s, int opts)
|
||||
else
|
||||
printf("%14s\n", "");
|
||||
}
|
||||
if (opts & PF_OPT_VERBOSE) {
|
||||
printf("Limit Counters\n");
|
||||
for (i = 0; i < LCNT_MAX; i++) {
|
||||
printf(" %-25s %14lld ", pf_lcounters[i],
|
||||
s->lcounters[i]);
|
||||
if (runtime > 0)
|
||||
printf("%14.1f/s\n",
|
||||
(double)s->lcounters[i] / (double)runtime);
|
||||
else
|
||||
printf("%14s\n", "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -589,7 +606,9 @@ print_src_node(struct pf_src_node *sn, int opts)
|
||||
printf(" -> ");
|
||||
aw.v.a.addr = sn->raddr;
|
||||
print_addr(&aw, sn->af, opts & PF_OPT_VERBOSE2);
|
||||
printf(" (%d states)\n", sn->states);
|
||||
printf(" ( states %u, connections %u, rate %u.%u/%us )\n", sn->states,
|
||||
sn->conn, sn->conn_rate.count / 1000,
|
||||
(sn->conn_rate.count % 1000) / 100, sn->conn_rate.seconds);
|
||||
if (opts & PF_OPT_VERBOSE) {
|
||||
sec = sn->creation % 60;
|
||||
sn->creation /= 60;
|
||||
@ -624,21 +643,22 @@ print_src_node(struct pf_src_node *sn, int opts)
|
||||
}
|
||||
|
||||
void
|
||||
print_rule(struct pf_rule *r, int verbose)
|
||||
print_rule(struct pf_rule *r, const char *anchor_call, int verbose)
|
||||
{
|
||||
static const char *actiontypes[] = { "pass", "block", "scrub", "nat",
|
||||
"no nat", "binat", "no binat", "rdr", "no rdr" };
|
||||
static const char *actiontypes[] = { "pass", "block", "scrub",
|
||||
"no scrub", "nat", "no nat", "binat", "no binat", "rdr", "no rdr" };
|
||||
static const char *anchortypes[] = { "anchor", "anchor", "anchor",
|
||||
"nat-anchor", "nat-anchor", "binat-anchor", "binat-anchor",
|
||||
"rdr-anchor", "rdr-anchor" };
|
||||
"anchor", "nat-anchor", "nat-anchor", "binat-anchor",
|
||||
"binat-anchor", "rdr-anchor", "rdr-anchor" };
|
||||
int i, opts;
|
||||
|
||||
if (verbose)
|
||||
printf("@%d ", r->nr);
|
||||
if (r->action > PF_NORDR)
|
||||
printf("action(%d)", r->action);
|
||||
else if (r->anchorname[0])
|
||||
printf("%s %s", anchortypes[r->action], r->anchorname);
|
||||
else if (anchor_call[0])
|
||||
printf("%s \"%s\"", anchortypes[r->action],
|
||||
anchor_call);
|
||||
else {
|
||||
printf("%s", actiontypes[r->action]);
|
||||
if (r->natpass)
|
||||
@ -778,6 +798,21 @@ print_rule(struct pf_rule *r, int verbose)
|
||||
printf(" modulate state");
|
||||
else if (r->keep_state == PF_STATE_SYNPROXY)
|
||||
printf(" synproxy state");
|
||||
if (r->prob) {
|
||||
char buf[20];
|
||||
|
||||
snprintf(buf, sizeof(buf), "%f", r->prob*100.0/(UINT_MAX+1.0));
|
||||
for (i = strlen(buf)-1; i > 0; i--) {
|
||||
if (buf[i] == '0')
|
||||
buf[i] = '\0';
|
||||
else {
|
||||
if (buf[i] == '.')
|
||||
buf[i] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf(" probability %s%%", buf);
|
||||
}
|
||||
opts = 0;
|
||||
if (r->max_states || r->max_src_nodes || r->max_src_states)
|
||||
opts = 1;
|
||||
@ -818,12 +853,35 @@ print_rule(struct pf_rule *r, int verbose)
|
||||
printf("max-src-states %u", r->max_src_states);
|
||||
opts = 0;
|
||||
}
|
||||
if (r->max_src_conn) {
|
||||
if (!opts)
|
||||
printf(", ");
|
||||
printf("max-src-conn %u", r->max_src_conn);
|
||||
opts = 0;
|
||||
}
|
||||
if (r->max_src_conn_rate.limit) {
|
||||
if (!opts)
|
||||
printf(", ");
|
||||
printf("max-src-conn-rate %u/%u",
|
||||
r->max_src_conn_rate.limit,
|
||||
r->max_src_conn_rate.seconds);
|
||||
opts = 0;
|
||||
}
|
||||
if (r->max_src_nodes) {
|
||||
if (!opts)
|
||||
printf(", ");
|
||||
printf("max-src-nodes %u", r->max_src_nodes);
|
||||
opts = 0;
|
||||
}
|
||||
if (r->overload_tblname[0]) {
|
||||
if (!opts)
|
||||
printf(", ");
|
||||
printf("overload <%s>", r->overload_tblname);
|
||||
if (r->flush)
|
||||
printf(" flush");
|
||||
if (r->flush & PF_FLUSH_GLOBAL)
|
||||
printf(" global");
|
||||
}
|
||||
if (r->rule_flag & PFRULE_IFBOUND) {
|
||||
if (!opts)
|
||||
printf(", ");
|
||||
@ -838,11 +896,17 @@ print_rule(struct pf_rule *r, int verbose)
|
||||
}
|
||||
for (i = 0; i < PFTM_MAX; ++i)
|
||||
if (r->timeout[i]) {
|
||||
int j;
|
||||
|
||||
if (!opts)
|
||||
printf(", ");
|
||||
opts = 0;
|
||||
printf("%s %u", pf_timeouts[i].name,
|
||||
r->timeout[i]);
|
||||
for (j = 0; j < sizeof(pf_timeouts) /
|
||||
sizeof(pf_timeouts[0]); ++j)
|
||||
if (pf_timeouts[j].timeout == i)
|
||||
break;
|
||||
printf("%s %u", j == PFTM_MAX ? "inv.timeout" :
|
||||
pf_timeouts[j].name, r->timeout[i]);
|
||||
}
|
||||
printf(")");
|
||||
}
|
||||
@ -882,7 +946,7 @@ print_rule(struct pf_rule *r, int verbose)
|
||||
printf(" !");
|
||||
printf(" tagged %s", r->match_tagname);
|
||||
}
|
||||
if (!r->anchorname[0] && (r->action == PF_NAT ||
|
||||
if (!anchor_call[0] && (r->action == PF_NAT ||
|
||||
r->action == PF_BINAT || r->action == PF_RDR)) {
|
||||
printf(" -> ");
|
||||
print_pool(&r->rpool, r->rpool.proxy_port[0],
|
||||
@ -949,9 +1013,7 @@ set_ipmask(struct node_host *h, u_int8_t b)
|
||||
int i, j = 0;
|
||||
|
||||
m = &h->addr.v.a.mask;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
m->addr32[i] = 0;
|
||||
memset(m, 0, sizeof(*m));
|
||||
|
||||
while (b >= 32) {
|
||||
m->addr32[j++] = 0xffffffff;
|
||||
@ -1003,8 +1065,6 @@ ifa_load(void)
|
||||
{
|
||||
struct ifaddrs *ifap, *ifa;
|
||||
struct node_host *n = NULL, *h = NULL;
|
||||
struct pfr_buffer b;
|
||||
struct pfi_if *p;
|
||||
|
||||
if (getifaddrs(&ifap) < 0)
|
||||
err(1, "getifaddrs");
|
||||
@ -1080,43 +1140,6 @@ ifa_load(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* add interface groups, including clonable and dynamic stuff */
|
||||
bzero(&b, sizeof(b));
|
||||
b.pfrb_type = PFRB_IFACES;
|
||||
for (;;) {
|
||||
if (pfr_buf_grow(&b, b.pfrb_size))
|
||||
err(1, "ifa_load: pfr_buf_grow");
|
||||
b.pfrb_size = b.pfrb_msize;
|
||||
if (pfi_get_ifaces(NULL, b.pfrb_caddr, &b.pfrb_size,
|
||||
PFI_FLAG_GROUP))
|
||||
err(1, "ifa_load: pfi_get_ifaces");
|
||||
if (b.pfrb_size <= b.pfrb_msize)
|
||||
break;
|
||||
}
|
||||
PFRB_FOREACH(p, &b) {
|
||||
n = calloc(1, sizeof(struct node_host));
|
||||
if (n == NULL)
|
||||
err(1, "address: calloc");
|
||||
n->af = AF_LINK;
|
||||
n->ifa_flags = PF_IFA_FLAG_GROUP;
|
||||
if (p->pfif_flags & PFI_IFLAG_DYNAMIC)
|
||||
n->ifa_flags |= PF_IFA_FLAG_DYNAMIC;
|
||||
if (p->pfif_flags & PFI_IFLAG_CLONABLE)
|
||||
n->ifa_flags |= PF_IFA_FLAG_CLONABLE;
|
||||
if (!strcmp(p->pfif_name, "lo"))
|
||||
n->ifa_flags |= IFF_LOOPBACK;
|
||||
if ((n->ifname = strdup(p->pfif_name)) == NULL)
|
||||
err(1, "ifa_load: strdup");
|
||||
n->next = NULL;
|
||||
n->tail = n;
|
||||
if (h == NULL)
|
||||
h = n;
|
||||
else {
|
||||
h->tail->next = n;
|
||||
h->tail = n;
|
||||
}
|
||||
}
|
||||
|
||||
iftab = h;
|
||||
freeifaddrs(ifap);
|
||||
}
|
||||
@ -1125,12 +1148,7 @@ struct node_host *
|
||||
ifa_exists(const char *ifa_name, int group_ok)
|
||||
{
|
||||
struct node_host *n;
|
||||
char *p, buf[IFNAMSIZ];
|
||||
int group;
|
||||
|
||||
group = !isdigit(ifa_name[strlen(ifa_name) - 1]);
|
||||
if (group && !group_ok)
|
||||
return (NULL);
|
||||
if (iftab == NULL)
|
||||
ifa_load();
|
||||
|
||||
@ -1138,19 +1156,7 @@ ifa_exists(const char *ifa_name, int group_ok)
|
||||
if (n->af == AF_LINK && !strncmp(n->ifname, ifa_name, IFNAMSIZ))
|
||||
return (n);
|
||||
}
|
||||
if (!group) {
|
||||
/* look for clonable and/or dynamic interface */
|
||||
strlcpy(buf, ifa_name, sizeof(buf));
|
||||
for (p = buf + strlen(buf) - 1; p > buf && isdigit(*p); p--)
|
||||
*p = '\0';
|
||||
for (n = iftab; n != NULL; n = n->next)
|
||||
if (n->af == AF_LINK &&
|
||||
!strncmp(n->ifname, buf, IFNAMSIZ))
|
||||
break;
|
||||
if (n != NULL && n->ifa_flags &
|
||||
(PF_IFA_FLAG_DYNAMIC | PF_IFA_FLAG_CLONABLE))
|
||||
return (n); /* XXX */
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
@ -1158,19 +1164,17 @@ struct node_host *
|
||||
ifa_lookup(const char *ifa_name, int flags)
|
||||
{
|
||||
struct node_host *p = NULL, *h = NULL, *n = NULL;
|
||||
int return_all = 0, got4 = 0, got6 = 0;
|
||||
int got4 = 0, got6 = 0;
|
||||
const char *last_if = NULL;
|
||||
|
||||
if (!strncmp(ifa_name, "self", IFNAMSIZ))
|
||||
return_all = 1;
|
||||
ifa_name = NULL;
|
||||
|
||||
if (iftab == NULL)
|
||||
ifa_load();
|
||||
|
||||
for (p = iftab; p; p = p->next) {
|
||||
if (!((p->af == AF_INET || p->af == AF_INET6) &&
|
||||
(!strncmp(p->ifname, ifa_name, strlen(ifa_name)) ||
|
||||
return_all)))
|
||||
if (ifa_skip_if(ifa_name, p))
|
||||
continue;
|
||||
if ((flags & PFI_AFLAG_BROADCAST) && p->af != AF_INET)
|
||||
continue;
|
||||
@ -1234,6 +1238,28 @@ ifa_lookup(const char *ifa_name, int flags)
|
||||
return (h);
|
||||
}
|
||||
|
||||
int
|
||||
ifa_skip_if(const char *filter, struct node_host *p)
|
||||
{
|
||||
int n;
|
||||
|
||||
if (p->af != AF_INET && p->af != AF_INET6)
|
||||
return (1);
|
||||
if (filter == NULL || !*filter)
|
||||
return (0);
|
||||
if (!strcmp(p->ifname, filter))
|
||||
return (0); /* exact match */
|
||||
n = strlen(filter);
|
||||
if (n < 1 || n >= IFNAMSIZ)
|
||||
return (1); /* sanity check */
|
||||
if (filter[n-1] >= '0' && filter[n-1] <= '9')
|
||||
return (1); /* only do exact match in that case */
|
||||
if (strncmp(p->ifname, filter, n))
|
||||
return (1); /* prefix doesn't match */
|
||||
return (p->ifname[n] < '0' || p->ifname[n] > '9');
|
||||
}
|
||||
|
||||
|
||||
struct node_host *
|
||||
host(const char *s)
|
||||
{
|
||||
@ -1244,7 +1270,7 @@ host(const char *s)
|
||||
if ((p = strrchr(s, '/')) != NULL) {
|
||||
mask = strtol(p+1, &q, 0);
|
||||
if (!q || *q || mask > 128 || q == (p+1)) {
|
||||
fprintf(stderr, "invalid netmask\n");
|
||||
fprintf(stderr, "invalid netmask '%s'\n", p);
|
||||
return (NULL);
|
||||
}
|
||||
if ((ps = malloc(strlen(s) - strlen(p) + 1)) == NULL)
|
||||
@ -1398,7 +1424,7 @@ host_dns(const char *s, int v4mask, int v6mask)
|
||||
char *p, *ps;
|
||||
|
||||
if ((ps = strdup(s)) == NULL)
|
||||
err(1, "host_if: strdup");
|
||||
err(1, "host_dns: strdup");
|
||||
if ((p = strrchr(ps, ':')) != NULL && !strcmp(p, ":0")) {
|
||||
noalias = 1;
|
||||
*p = '\0';
|
||||
@ -1407,8 +1433,10 @@ host_dns(const char *s, int v4mask, int v6mask)
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM; /* DUMMY */
|
||||
error = getaddrinfo(ps, NULL, &hints, &res0);
|
||||
if (error)
|
||||
if (error) {
|
||||
free(ps);
|
||||
return (h);
|
||||
}
|
||||
|
||||
for (res = res0; res; res = res->ai_next) {
|
||||
if (res->ai_family != AF_INET &&
|
||||
@ -1532,33 +1560,28 @@ append_addr_host(struct pfr_buffer *b, struct node_host *n, int test, int not)
|
||||
}
|
||||
|
||||
int
|
||||
pfctl_add_trans(struct pfr_buffer *buf, int rs_num, const char *anchor,
|
||||
const char *ruleset)
|
||||
pfctl_add_trans(struct pfr_buffer *buf, int rs_num, const char *anchor)
|
||||
{
|
||||
struct pfioc_trans_e trans;
|
||||
|
||||
bzero(&trans, sizeof(trans));
|
||||
trans.rs_num = rs_num;
|
||||
if (strlcpy(trans.anchor, anchor,
|
||||
sizeof(trans.anchor)) >= sizeof(trans.anchor) ||
|
||||
strlcpy(trans.ruleset, ruleset,
|
||||
sizeof(trans.ruleset)) >= sizeof(trans.ruleset))
|
||||
sizeof(trans.anchor)) >= sizeof(trans.anchor))
|
||||
errx(1, "pfctl_add_trans: strlcpy");
|
||||
|
||||
return pfr_buf_add(buf, &trans);
|
||||
}
|
||||
|
||||
u_int32_t
|
||||
pfctl_get_ticket(struct pfr_buffer *buf, int rs_num, const char *anchor,
|
||||
const char *ruleset)
|
||||
pfctl_get_ticket(struct pfr_buffer *buf, int rs_num, const char *anchor)
|
||||
{
|
||||
struct pfioc_trans_e *p;
|
||||
|
||||
PFRB_FOREACH(p, buf)
|
||||
if (rs_num == p->rs_num && !strcmp(anchor, p->anchor) &&
|
||||
!strcmp(ruleset, p->ruleset))
|
||||
if (rs_num == p->rs_num && !strcmp(anchor, p->anchor))
|
||||
return (p->ticket);
|
||||
errx(1, "pfr_get_ticket: assertion failed");
|
||||
errx(1, "pfctl_get_ticket: assertion failed");
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: pfctl_parser.h,v 1.74 2004/02/10 22:26:56 dhartmei Exp $ */
|
||||
/* $OpenBSD: pfctl_parser.h,v 1.80 2005/02/07 18:18:14 david Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Daniel Hartmeier
|
||||
@ -46,6 +46,9 @@
|
||||
#define PF_OPT_DUMMYACTION 0x0100
|
||||
#define PF_OPT_DEBUG 0x0200
|
||||
#define PF_OPT_SHOWALL 0x0400
|
||||
#define PF_OPT_OPTIMIZE 0x0800
|
||||
#define PF_OPT_OPTIMIZE_PROFILE 0x1000
|
||||
#define PF_OPT_MERGE 0x2000
|
||||
|
||||
#define PF_TH_ALL 0xFF
|
||||
|
||||
@ -59,6 +62,11 @@
|
||||
NULL \
|
||||
}
|
||||
|
||||
struct pfr_buffer; /* forward definition */
|
||||
struct pf_opt_rule;
|
||||
TAILQ_HEAD(pf_opt_queue, pf_opt_rule);
|
||||
|
||||
|
||||
struct pfctl {
|
||||
int dev;
|
||||
int opts;
|
||||
@ -72,11 +80,26 @@ struct pfctl {
|
||||
struct pfr_buffer *trans;
|
||||
const char *anchor;
|
||||
const char *ruleset;
|
||||
struct pf_opt_queue opt_queue;
|
||||
|
||||
/* 'set foo' options */
|
||||
u_int32_t timeout[PFTM_MAX];
|
||||
u_int32_t limit[PF_LIMIT_MAX];
|
||||
u_int32_t debug;
|
||||
u_int32_t hostid;
|
||||
char *ifname;
|
||||
|
||||
u_int8_t timeout_set[PFTM_MAX];
|
||||
u_int8_t limit_set[PF_LIMIT_MAX];
|
||||
u_int8_t debug_set;
|
||||
u_int8_t hostid_set;
|
||||
u_int8_t ifname_set;
|
||||
};
|
||||
|
||||
struct node_if {
|
||||
char ifname[IFNAMSIZ];
|
||||
u_int8_t not;
|
||||
u_int8_t dynamic; /* antispoof */
|
||||
u_int ifa_flags;
|
||||
struct node_if *next;
|
||||
struct node_if *tail;
|
||||
@ -141,11 +164,33 @@ struct node_tinit { /* table initializer */
|
||||
char *file;
|
||||
};
|
||||
|
||||
struct pfr_buffer; /* forward definition */
|
||||
|
||||
int pfctl_rules(int, char *, int, char *, char *, struct pfr_buffer *);
|
||||
/* optimizer created tables */
|
||||
struct pf_opt_tbl {
|
||||
char pt_name[PF_TABLE_NAME_SIZE];
|
||||
int pt_rulecount;
|
||||
int pt_generated;
|
||||
struct node_tinithead pt_nodes;
|
||||
struct pfr_buffer *pt_buf;
|
||||
};
|
||||
#define PF_OPT_TABLE_PREFIX "__automatic_"
|
||||
|
||||
int pfctl_add_rule(struct pfctl *, struct pf_rule *);
|
||||
/* optimizer pf_rule container */
|
||||
struct pf_opt_rule {
|
||||
struct pf_rule por_rule;
|
||||
struct pf_opt_tbl *por_src_tbl;
|
||||
struct pf_opt_tbl *por_dst_tbl;
|
||||
char por_anchor[MAXPATHLEN];
|
||||
u_int64_t por_profile_count;
|
||||
TAILQ_ENTRY(pf_opt_rule) por_entry;
|
||||
TAILQ_ENTRY(pf_opt_rule) por_skip_entry[PF_SKIP_COUNT];
|
||||
};
|
||||
|
||||
|
||||
int pfctl_rules(int, char *, int, char *, struct pfr_buffer *);
|
||||
int pfctl_optimize_rules(struct pfctl *);
|
||||
|
||||
int pfctl_add_rule(struct pfctl *, struct pf_rule *, const char *);
|
||||
int pfctl_add_altq(struct pfctl *, struct pf_altq *);
|
||||
int pfctl_add_pool(struct pfctl *, struct pf_pool *, sa_family_t);
|
||||
void pfctl_clear_pool(struct pf_pool *);
|
||||
@ -156,6 +201,7 @@ int pfctl_set_limit(struct pfctl *, const char *, unsigned int);
|
||||
int pfctl_set_logif(struct pfctl *, char *);
|
||||
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_flags(char *);
|
||||
@ -163,7 +209,7 @@ int pfctl_load_anchors(int, int, struct pfr_buffer *);
|
||||
|
||||
void print_pool(struct pf_pool *, u_int16_t, u_int16_t, sa_family_t, int);
|
||||
void print_src_node(struct pf_src_node *, int);
|
||||
void print_rule(struct pf_rule *, int);
|
||||
void print_rule(struct pf_rule *, const char *, int);
|
||||
void print_tabledef(const char *, int, int, struct node_tinithead *);
|
||||
void print_status(struct pf_status *, int);
|
||||
|
||||
@ -177,8 +223,8 @@ void print_altq(const struct pf_altq *, unsigned, struct node_queue_bw *,
|
||||
void print_queue(const struct pf_altq *, unsigned, struct node_queue_bw *,
|
||||
int, struct node_queue_opt *);
|
||||
|
||||
int pfctl_define_table(char *, int, int, const char *, const char *,
|
||||
struct pfr_buffer *, u_int32_t);
|
||||
int pfctl_define_table(char *, int, int, const char *, struct pfr_buffer *,
|
||||
u_int32_t);
|
||||
|
||||
void pfctl_clear_fingerprints(int, int);
|
||||
int pfctl_file_fingerprints(int, int, const char *);
|
||||
@ -219,6 +265,7 @@ extern const struct pf_timeout pf_timeouts[];
|
||||
|
||||
void set_ipmask(struct node_host *, u_int8_t);
|
||||
int check_netmask(struct node_host *, sa_family_t);
|
||||
int unmask(struct pf_addr *, sa_family_t);
|
||||
void ifa_load(void);
|
||||
struct node_host *ifa_exists(const char *, int);
|
||||
struct node_host *ifa_lookup(const char *, int);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: pfctl_qstats.c,v 1.29 2004/03/15 15:25:44 dhartmei Exp $ */
|
||||
/* $OpenBSD: pfctl_qstats.c,v 1.30 2004/04/27 21:47:32 kjc Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) Henning Brauer <henning@openbsd.org>
|
||||
@ -90,6 +90,8 @@ pfctl_show_altq(int dev, const char *iface, int opts, int verbose2)
|
||||
if ((nodes = pfctl_update_qstats(dev, &root)) < 0)
|
||||
return (-1);
|
||||
|
||||
if (nodes == 0)
|
||||
printf("No queue in use\n");
|
||||
for (node = root; node != NULL; node = node->next) {
|
||||
if (iface != NULL && strcmp(node->altq.ifname, iface))
|
||||
continue;
|
||||
@ -100,11 +102,11 @@ pfctl_show_altq(int dev, const char *iface, int opts, int verbose2)
|
||||
pfctl_print_altq_node(dev, node, 0, opts);
|
||||
}
|
||||
|
||||
while (verbose2) {
|
||||
while (verbose2 && nodes > 0) {
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
sleep(STAT_INTERVAL);
|
||||
if (pfctl_update_qstats(dev, &root) == -1)
|
||||
if ((nodes = pfctl_update_qstats(dev, &root)) == -1)
|
||||
return (-1);
|
||||
for (node = root; node != NULL; node = node->next) {
|
||||
if (iface != NULL && strcmp(node->altq.ifname, iface))
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: pfctl_radix.c,v 1.24 2004/02/10 18:29:30 henning Exp $ */
|
||||
/* $OpenBSD: pfctl_radix.c,v 1.26 2004/06/14 20:44:22 cedric Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2002 Cedric Berger
|
||||
@ -392,44 +392,6 @@ pfr_tst_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pfr_ina_begin(struct pfr_table *trs, int *ticket, int *ndel, int flags)
|
||||
{
|
||||
struct pfioc_table io;
|
||||
|
||||
bzero(&io, sizeof io);
|
||||
if (trs != NULL)
|
||||
io.pfrio_table = *trs;
|
||||
io.pfrio_flags = flags;
|
||||
if (ioctl(dev, DIOCRINABEGIN, &io))
|
||||
return (-1);
|
||||
if (ndel != NULL)
|
||||
*ndel = io.pfrio_ndel;
|
||||
if (ticket != NULL)
|
||||
*ticket = io.pfrio_ticket;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pfr_ina_commit(struct pfr_table *trs, int ticket, int *nadd, int *nchange,
|
||||
int flags)
|
||||
{
|
||||
struct pfioc_table io;
|
||||
|
||||
bzero(&io, sizeof io);
|
||||
if (trs != NULL)
|
||||
io.pfrio_table = *trs;
|
||||
io.pfrio_flags = flags;
|
||||
io.pfrio_ticket = ticket;
|
||||
if (ioctl(dev, DIOCRINACOMMIT, &io))
|
||||
return (-1);
|
||||
if (nadd != NULL)
|
||||
*nadd = io.pfrio_nadd;
|
||||
if (nchange != NULL)
|
||||
*nchange = io.pfrio_nchange;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pfr_ina_define(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
int *nadd, int *naddr, int ticket, int flags)
|
||||
@ -605,7 +567,7 @@ pfr_buf_load(struct pfr_buffer *b, char *file, int nonetwork,
|
||||
if (!strcmp(file, "-"))
|
||||
fp = stdin;
|
||||
else {
|
||||
fp = fopen(file, "r");
|
||||
fp = pfctl_fopen(file, "r");
|
||||
if (fp == NULL)
|
||||
return (-1);
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* $OpenBSD: pfctl_table.c,v 1.59 2004/03/15 15:25:44 dhartmei Exp $ */
|
||||
/* add $OpenBSD: pfctl_table.c,v 1.61 2004/06/12 22:22:44 cedric Exp $ */
|
||||
/* $OpenBSD: pfctl_table.c,v 1.62 2004/12/22 17:17:55 dhartmei Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2002 Cedric Berger
|
||||
@ -54,7 +53,7 @@
|
||||
|
||||
extern void usage(void);
|
||||
static int pfctl_table(int, char *[], char *, const char *, char *,
|
||||
const char *, const char *, int);
|
||||
const char *, int);
|
||||
static void print_table(struct pfr_table *, int, int);
|
||||
static void print_tstats(struct pfr_tstats *, int);
|
||||
static int load_addr(struct pfr_buffer *, int, char *[], char *, int);
|
||||
@ -103,31 +102,29 @@ static const char *istats_text[2][2][2] = {
|
||||
} while(0)
|
||||
|
||||
int
|
||||
pfctl_clear_tables(const char *anchor, const char *ruleset, int opts)
|
||||
pfctl_clear_tables(const char *anchor, int opts)
|
||||
{
|
||||
return pfctl_table(0, NULL, NULL, "-F", NULL, anchor, ruleset, opts);
|
||||
return pfctl_table(0, NULL, NULL, "-F", NULL, anchor, opts);
|
||||
}
|
||||
|
||||
int
|
||||
pfctl_show_tables(const char *anchor, const char *ruleset, int opts)
|
||||
pfctl_show_tables(const char *anchor, int opts)
|
||||
{
|
||||
return pfctl_table(0, NULL, NULL, "-s", NULL, anchor, ruleset, opts);
|
||||
return pfctl_table(0, NULL, NULL, "-s", NULL, anchor, opts);
|
||||
}
|
||||
|
||||
int
|
||||
pfctl_command_tables(int argc, char *argv[], char *tname,
|
||||
const char *command, char *file, const char *anchor, const char *ruleset,
|
||||
int opts)
|
||||
const char *command, char *file, const char *anchor, int opts)
|
||||
{
|
||||
if (tname == NULL || command == NULL)
|
||||
usage();
|
||||
return pfctl_table(argc, argv, tname, command, file, anchor, ruleset,
|
||||
opts);
|
||||
return pfctl_table(argc, argv, tname, command, file, anchor, opts);
|
||||
}
|
||||
|
||||
int
|
||||
pfctl_table(int argc, char *argv[], char *tname, const char *command,
|
||||
char *file, const char *anchor, const char *ruleset, int opts)
|
||||
char *file, const char *anchor, int opts)
|
||||
{
|
||||
struct pfr_table table;
|
||||
struct pfr_buffer b, b2;
|
||||
@ -152,9 +149,7 @@ pfctl_table(int argc, char *argv[], char *tname, const char *command,
|
||||
errx(1, "pfctl_table: strlcpy");
|
||||
}
|
||||
if (strlcpy(table.pfrt_anchor, anchor,
|
||||
sizeof(table.pfrt_anchor)) >= sizeof(table.pfrt_anchor) ||
|
||||
strlcpy(table.pfrt_ruleset, ruleset,
|
||||
sizeof(table.pfrt_ruleset)) >= sizeof(table.pfrt_ruleset))
|
||||
sizeof(table.pfrt_anchor)) >= sizeof(table.pfrt_anchor))
|
||||
errx(1, "pfctl_table: strlcpy");
|
||||
|
||||
if (!strcmp(command, "-F")) {
|
||||
@ -344,8 +339,6 @@ print_table(struct pfr_table *ta, int verbose, int debug)
|
||||
ta->pfrt_name);
|
||||
if (ta->pfrt_anchor[0])
|
||||
printf("\t%s", ta->pfrt_anchor);
|
||||
if (ta->pfrt_ruleset[0])
|
||||
printf(":%s", ta->pfrt_ruleset);
|
||||
puts("");
|
||||
} else
|
||||
puts(ta->pfrt_name);
|
||||
@ -463,16 +456,14 @@ radix_perror(void)
|
||||
|
||||
int
|
||||
pfctl_define_table(char *name, int flags, int addrs, const char *anchor,
|
||||
const char *ruleset, struct pfr_buffer *ab, u_int32_t ticket)
|
||||
struct pfr_buffer *ab, u_int32_t ticket)
|
||||
{
|
||||
struct pfr_table tbl;
|
||||
|
||||
bzero(&tbl, sizeof(tbl));
|
||||
if (strlcpy(tbl.pfrt_name, name, sizeof(tbl.pfrt_name)) >=
|
||||
sizeof(tbl.pfrt_name) || strlcpy(tbl.pfrt_anchor, anchor,
|
||||
sizeof(tbl.pfrt_anchor)) >= sizeof(tbl.pfrt_anchor) ||
|
||||
strlcpy(tbl.pfrt_ruleset, ruleset, sizeof(tbl.pfrt_ruleset)) >=
|
||||
sizeof(tbl.pfrt_ruleset))
|
||||
sizeof(tbl.pfrt_anchor)) >= sizeof(tbl.pfrt_anchor))
|
||||
errx(1, "pfctl_define_table: strlcpy");
|
||||
tbl.pfrt_flags = flags;
|
||||
|
||||
@ -586,7 +577,8 @@ print_iface(struct pfi_if *p, int opts)
|
||||
oprintf(flags, PFI_IFLAG_GROUP, "group", &first, 0);
|
||||
oprintf(flags, PFI_IFLAG_CLONABLE, "clonable", &first, 0);
|
||||
oprintf(flags, PFI_IFLAG_DYNAMIC, "dynamic", &first, 0);
|
||||
oprintf(flags, PFI_IFLAG_ATTACHED, "attached", &first, 1);
|
||||
oprintf(flags, PFI_IFLAG_ATTACHED, "attached", &first, 0);
|
||||
oprintf(flags, PFI_IFLAG_SKIP, "skipped", &first, 1);
|
||||
printf("\n");
|
||||
|
||||
if (!(opts & PF_OPT_VERBOSE2))
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $OpenBSD: pflogd.8,v 1.24 2004/01/16 10:45:49 jmc Exp $
|
||||
.\" $OpenBSD: pflogd.8,v 1.25 2005/01/02 18:15:02 jmc Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2001 Can Erkin Acar. All rights reserved.
|
||||
.\"
|
||||
@ -161,7 +161,8 @@ Interface name equals "kue0".
|
||||
Rule number equals 10.
|
||||
.It reason match
|
||||
Reason equals match.
|
||||
Also accepts "bad-offset", "fragment", "short", "normalize" and "memory".
|
||||
Also accepts "bad-offset", "fragment", "bad-timestamp", "short",
|
||||
"normalize" and "memory".
|
||||
.It action pass
|
||||
Action equals pass.
|
||||
Also accepts "block".
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: pflogd.c,v 1.27 2004/02/13 19:01:57 otto Exp $ */
|
||||
/* $OpenBSD: pflogd.c,v 1.33 2005/02/09 12:09:30 henning Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Theo de Raadt
|
||||
@ -255,16 +255,19 @@ reset_dump(void)
|
||||
fp = fdopen(fd, "a+");
|
||||
|
||||
if (fp == NULL) {
|
||||
close(fd);
|
||||
logmsg(LOG_ERR, "Error: %s: %s", filename, strerror(errno));
|
||||
return (1);
|
||||
}
|
||||
if (fstat(fileno(fp), &st) == -1) {
|
||||
fclose(fp);
|
||||
logmsg(LOG_ERR, "Error: %s: %s", filename, strerror(errno));
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* set FILE unbuffered, we do our own buffering */
|
||||
if (setvbuf(fp, NULL, _IONBF, 0)) {
|
||||
fclose(fp);
|
||||
logmsg(LOG_ERR, "Failed to set output buffers");
|
||||
return (1);
|
||||
}
|
||||
@ -275,6 +278,7 @@ reset_dump(void)
|
||||
if (snaplen != cur_snaplen) {
|
||||
logmsg(LOG_NOTICE, "Using snaplen %d", snaplen);
|
||||
if (set_snaplen(snaplen)) {
|
||||
fclose(fp);
|
||||
logmsg(LOG_WARNING,
|
||||
"Failed, using old settings");
|
||||
}
|
||||
@ -386,8 +390,9 @@ dump_packet_nobuf(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
|
||||
}
|
||||
|
||||
if (fwrite((char *)h, sizeof(*h), 1, f) != 1) {
|
||||
/* try to undo header to prevent corruption */
|
||||
off_t pos = ftello(f);
|
||||
|
||||
/* try to undo header to prevent corruption */
|
||||
if (pos < sizeof(*h) ||
|
||||
ftruncate(fileno(f), pos - sizeof(*h))) {
|
||||
logmsg(LOG_ERR, "Write failed, corrupted logfile!");
|
||||
@ -485,7 +490,7 @@ dump_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
|
||||
return;
|
||||
}
|
||||
|
||||
append:
|
||||
append:
|
||||
memcpy(bufpos, h, sizeof(*h));
|
||||
memcpy(bufpos + sizeof(*h), sp, h->caplen);
|
||||
|
||||
@ -502,6 +507,7 @@ main(int argc, char **argv)
|
||||
struct pcap_stat pstat;
|
||||
int ch, np, Xflag = 0;
|
||||
pcap_handler phandler = dump_packet;
|
||||
const char *errstr = NULL;
|
||||
|
||||
closefrom(STDERR_FILENO + 1);
|
||||
|
||||
@ -511,18 +517,19 @@ main(int argc, char **argv)
|
||||
Debug = 1;
|
||||
break;
|
||||
case 'd':
|
||||
delay = atoi(optarg);
|
||||
if (delay < 5 || delay > 60*60)
|
||||
delay = strtonum(optarg, 5, 60*60, &errstr);
|
||||
if (errstr)
|
||||
usage();
|
||||
break;
|
||||
case 'f':
|
||||
filename = optarg;
|
||||
break;
|
||||
case 's':
|
||||
snaplen = atoi(optarg);
|
||||
snaplen = strtonum(optarg, 0, PFLOGD_MAXSNAPLEN,
|
||||
&errstr);
|
||||
if (snaplen <= 0)
|
||||
snaplen = DEF_SNAPLEN;
|
||||
if (snaplen > PFLOGD_MAXSNAPLEN)
|
||||
if (errstr)
|
||||
snaplen = PFLOGD_MAXSNAPLEN;
|
||||
break;
|
||||
case 'x':
|
||||
@ -547,6 +554,7 @@ main(int argc, char **argv)
|
||||
pidfile(NULL);
|
||||
}
|
||||
|
||||
tzset();
|
||||
(void)umask(S_IRWXG | S_IRWXO);
|
||||
|
||||
/* filter will be used by the privileged process */
|
||||
@ -599,7 +607,7 @@ main(int argc, char **argv)
|
||||
|
||||
while (1) {
|
||||
np = pcap_dispatch(hpcap, PCAP_NUM_PKTS,
|
||||
dump_packet, (u_char *)dpcap);
|
||||
phandler, (u_char *)dpcap);
|
||||
if (np < 0)
|
||||
logmsg(LOG_NOTICE, "%s", pcap_geterr(hpcap));
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: privsep.c,v 1.8 2004/03/14 19:17:05 otto Exp $ */
|
||||
/* $OpenBSD: privsep.c,v 1.13 2004/12/22 09:21:02 otto Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003 Can Erkin Acar
|
||||
@ -67,7 +67,7 @@ int
|
||||
priv_init(void)
|
||||
{
|
||||
int i, fd, socks[2], cmd;
|
||||
int snaplen, ret;
|
||||
int snaplen, ret, olderrno;
|
||||
struct passwd *pw;
|
||||
|
||||
for (i = 1; i < _NSIG; i++)
|
||||
@ -112,10 +112,12 @@ priv_init(void)
|
||||
}
|
||||
|
||||
/* Father */
|
||||
/* Pass ALRM/TERM/HUP through to child, and accept CHLD */
|
||||
/* Pass ALRM/TERM/HUP/INT/QUIT through to child, and accept CHLD */
|
||||
signal(SIGALRM, sig_pass_to_chld);
|
||||
signal(SIGTERM, sig_pass_to_chld);
|
||||
signal(SIGHUP, sig_pass_to_chld);
|
||||
signal(SIGINT, sig_pass_to_chld);
|
||||
signal(SIGQUIT, sig_pass_to_chld);
|
||||
signal(SIGCHLD, sig_chld);
|
||||
|
||||
setproctitle("[priv]");
|
||||
@ -147,12 +149,14 @@ priv_init(void)
|
||||
fd = open(filename,
|
||||
O_RDWR|O_CREAT|O_APPEND|O_NONBLOCK|O_NOFOLLOW,
|
||||
0600);
|
||||
olderrno = errno;
|
||||
send_fd(socks[0], fd);
|
||||
if (fd < 0)
|
||||
logmsg(LOG_NOTICE,
|
||||
"[priv]: failed to open %s: %s",
|
||||
filename, strerror(errno));
|
||||
send_fd(socks[0], fd);
|
||||
close(fd);
|
||||
filename, strerror(olderrno));
|
||||
else
|
||||
close(fd);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -211,7 +215,7 @@ priv_open_log(void)
|
||||
int cmd, fd;
|
||||
|
||||
if (priv_fd < 0)
|
||||
errx(1, "%s: called from privileged portion\n", __func__);
|
||||
errx(1, "%s: called from privileged portion", __func__);
|
||||
|
||||
cmd = PRIV_OPEN_LOG;
|
||||
must_write(priv_fd, &cmd, sizeof(int));
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: privsep_fdpass.c,v 1.1 2003/10/22 18:51:55 canacar Exp $ */
|
||||
/* $OpenBSD: privsep_fdpass.c,v 1.2 2004/08/13 02:51:48 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 2001 Niels Provos <provos@citi.umich.edu>
|
||||
@ -108,6 +108,10 @@ receive_fd(int sock)
|
||||
__func__, (long)n);
|
||||
if (result == 0) {
|
||||
cmsg = CMSG_FIRSTHDR(&msg);
|
||||
if (cmsg == NULL) {
|
||||
warnx("%s: no message header", __func__);
|
||||
return -1;
|
||||
}
|
||||
if (cmsg->cmsg_type != SCM_RIGHTS)
|
||||
warnx("%s: expected type %d got %d", __func__,
|
||||
SCM_RIGHTS, cmsg->cmsg_type);
|
||||
|
Loading…
x
Reference in New Issue
Block a user