MFC
This commit is contained in:
commit
40a034576b
4
UPDATING
4
UPDATING
@ -22,6 +22,10 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 9.x IS SLOW:
|
||||
machines to maximize performance. (To disable malloc debugging, run
|
||||
ln -s aj /etc/malloc.conf.)
|
||||
|
||||
20110628:
|
||||
The packet filter (pf) code has been updated to OpenBSD 4.5.
|
||||
You need to update userland tools to be in sync with kernel.
|
||||
|
||||
20110608:
|
||||
The following sysctls and tunables are retired on x86 platforms:
|
||||
machdep.hlt_cpus
|
||||
|
@ -35,7 +35,7 @@
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/limits.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -6,6 +6,7 @@
|
||||
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License. You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing.
|
||||
.\" See the License for the specific language governing permissions and limitations under the License. When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with
|
||||
.\" the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
.\" Copyright 2011 by Delphix. All rights reserved.
|
||||
.TH zfs 1M "24 Sep 2009" "SunOS 5.11" "System Administration Commands"
|
||||
.SH NAME
|
||||
zfs \- configures ZFS file systems
|
||||
@ -389,7 +390,7 @@ This property can also be referred to by its shortened column name, \fBavail\fR.
|
||||
.ad
|
||||
.sp .6
|
||||
.RS 4n
|
||||
The compression ratio achieved for this dataset, expressed as a multiplier. Compression can be turned on by running: \fBzfs set compression=on \fIdataset\fR\fR. The default value is \fBoff\fR.
|
||||
For non-snapshots, the compression ratio achieved for the \fBused\fR space of this dataset, expressed as a multiplier. The \fBused\fR property includes descendant datasets, and, for clones, does not include the space shared with the origin snapshot. For snapshots, the \fBcompressratio\fR is the same as the \fBrefcompressratio\fR property. Compression can be turned on by running: \fBzfs set compression=on \fIdataset\fR\fR. The default value is \fBoff\fR.
|
||||
.RE
|
||||
|
||||
.sp
|
||||
@ -449,6 +450,17 @@ The amount of data that is accessible by this dataset, which may or may not be s
|
||||
This property can also be referred to by its shortened column name, \fBrefer\fR.
|
||||
.RE
|
||||
|
||||
.sp
|
||||
.ne 2
|
||||
.mk
|
||||
.na
|
||||
\fB\fBrefcompressratio\fR\fR
|
||||
.ad
|
||||
.sp .6
|
||||
.RS 4n
|
||||
The compression ratio achieved for the \fBreferenced\fR space of this dataset, expressed as a multiplier. See also the \fBcompressratio\fR property.
|
||||
.RE
|
||||
|
||||
.sp
|
||||
.ne 2
|
||||
.mk
|
||||
@ -1278,7 +1290,7 @@ Recursively destroy all dependents, including cloned file systems outside the ta
|
||||
Force an unmount of any file systems using the \fBunmount -f\fR command. This option has no effect on non-file systems or unmounted file systems.
|
||||
.RE
|
||||
|
||||
Extreme care should be taken when applying either the \fB-r\fR or the \fB-f\fR options, as they can destroy large portions of a pool and cause unexpected behavior for mounted file systems in use.
|
||||
Extreme care should be taken when applying either the \fB-r\fR or the \fB-R\fR options, as they can destroy large portions of a pool and cause unexpected behavior for mounted file systems in use.
|
||||
.RE
|
||||
|
||||
.sp
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
@ -1292,7 +1292,7 @@ static int
|
||||
zfs_do_get(int argc, char **argv)
|
||||
{
|
||||
zprop_get_cbdata_t cb = { 0 };
|
||||
int i, c, flags = 0;
|
||||
int i, c, flags = ZFS_ITER_ARGS_CAN_BE_PATHS;
|
||||
char *value, *fields;
|
||||
int ret;
|
||||
int limit = 0;
|
||||
|
@ -22,6 +22,7 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2011 by Delphix. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
@ -2038,6 +2039,7 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
|
||||
}
|
||||
break;
|
||||
|
||||
case ZFS_PROP_REFRATIO:
|
||||
case ZFS_PROP_COMPRESSRATIO:
|
||||
if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
|
||||
return (-1);
|
||||
|
@ -405,7 +405,18 @@ bpf_filter(pc, p, wirelen, buflen)
|
||||
continue;
|
||||
|
||||
case BPF_JMP|BPF_JA:
|
||||
#if defined(KERNEL) || defined(_KERNEL)
|
||||
/*
|
||||
* No backward jumps allowed.
|
||||
*/
|
||||
pc += pc->k;
|
||||
#else
|
||||
/*
|
||||
* XXX - we currently implement "ip6 protochain"
|
||||
* with backward jumps, so sign-extend pc->k.
|
||||
*/
|
||||
pc += (bpf_int32)pc->k;
|
||||
#endif
|
||||
continue;
|
||||
|
||||
case BPF_JMP|BPF_JGT|BPF_K:
|
||||
|
@ -2716,14 +2716,14 @@ sendpkt(
|
||||
|
||||
for (slot = ERRORCACHESIZE; --slot >= 0; )
|
||||
if(dest->ss_family == AF_INET) {
|
||||
if (badaddrs[slot].port == ((struct sockaddr_in*)dest)->sin_port &&
|
||||
if (badaddrs[slot].port == SRCPORT(dest) &&
|
||||
badaddrs[slot].addr.s_addr == ((struct sockaddr_in*)dest)->sin_addr.s_addr)
|
||||
break;
|
||||
}
|
||||
#ifdef INCLUDE_IPV6_SUPPORT
|
||||
else if (dest->ss_family == AF_INET6) {
|
||||
if (badaddrs6[slot].port == ((struct sockaddr_in6*)dest)->sin6_port &&
|
||||
badaddrs6[slot].addr.s6_addr == ((struct sockaddr_in6*)dest)->sin6_addr.s6_addr)
|
||||
if (badaddrs6[slot].port == SRCPORT(dest) &&
|
||||
!memcmp(&badaddrs6[slot].addr, &((struct sockaddr_in6*)dest)->sin6_addr, sizeof(struct in6_addr)))
|
||||
break;
|
||||
}
|
||||
#endif /* INCLUDE_IPV6_SUPPORT */
|
||||
|
@ -1,5 +1,5 @@
|
||||
.\" $FreeBSD$
|
||||
.\" $OpenBSD: authpf.8,v 1.43 2007/02/24 17:21:04 beck Exp $
|
||||
.\" $OpenBSD: authpf.8,v 1.47 2009/01/06 03:11:50 mcbride Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1998-2007 Bob Beck (beck@openbsd.org>. All rights reserved.
|
||||
.\"
|
||||
@ -15,14 +15,16 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd March 28, 2006
|
||||
.Dd January 6 2009
|
||||
.Dt AUTHPF 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm authpf
|
||||
.Nm authpf ,
|
||||
.Nm authpf-noip
|
||||
.Nd authenticating gateway user shell
|
||||
.Sh SYNOPSIS
|
||||
.Nm authpf
|
||||
.Nm authpf-noip
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
is a user shell for authenticating gateways.
|
||||
@ -31,47 +33,63 @@ It is used to change
|
||||
rules when a user authenticates and starts a session with
|
||||
.Xr sshd 8
|
||||
and to undo these changes when the user's session exits.
|
||||
It is designed for changing filter and translation rules for an individual
|
||||
source IP address as long as a user maintains an active
|
||||
.Xr ssh 1
|
||||
session.
|
||||
Typical use would be for a gateway that authenticates users before
|
||||
allowing them Internet use, or a gateway that allows different users into
|
||||
different places.
|
||||
Combined with properly set up filter rules and secure switches,
|
||||
.Nm
|
||||
logs the successful start and end of a session to
|
||||
.Xr syslogd 8 .
|
||||
This, combined with properly set up filter rules and secure switches,
|
||||
can be used to ensure users are held accountable for their network traffic.
|
||||
.Pp
|
||||
.Nm
|
||||
can add filter and translation rules using the syntax described in
|
||||
.Xr pf.conf 5 .
|
||||
.Nm
|
||||
requires that the
|
||||
.Xr pf 4
|
||||
system be enabled and a
|
||||
.Xr fdescfs 5
|
||||
file system be mounted at
|
||||
.Pa /dev/fd
|
||||
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
|
||||
It is meant to be used with users who can connect via
|
||||
.Xr ssh 1
|
||||
only.
|
||||
On startup,
|
||||
only, and requires the
|
||||
.Xr pf 4
|
||||
subsystem to be enabled.
|
||||
.Pp
|
||||
.Nm authpf-noip
|
||||
is a user shell
|
||||
which allows multiple connections to take
|
||||
place from the same IP address.
|
||||
It is useful primarily in cases where connections are tunneled via
|
||||
the gateway system, and can be directly associated with the user name.
|
||||
It cannot ensure accountability when
|
||||
classifying connections by IP address;
|
||||
in this case the client's IP address
|
||||
is not provided to the packet filter via the
|
||||
.Ar client_ip
|
||||
macro or the
|
||||
.Ar authpf_users
|
||||
table.
|
||||
Additionally, states associated with the client IP address
|
||||
are not purged when the session is ended.
|
||||
.Pp
|
||||
To use either
|
||||
.Nm
|
||||
or
|
||||
.Nm authpf-noip ,
|
||||
the user's shell needs to be set to
|
||||
.Pa /usr/sbin/authpf
|
||||
or
|
||||
.Pa /usr/sbin/authpf-noip .
|
||||
.Pp
|
||||
.Nm
|
||||
uses the
|
||||
.Xr pf.conf 5
|
||||
syntax to change filter and translation rules for an individual
|
||||
user or client IP address as long as a user maintains an active
|
||||
.Xr ssh 1
|
||||
session, and logs the successful start and end of a session to
|
||||
.Xr syslogd 8 .
|
||||
.Nm
|
||||
retrieves the client's connecting IP address via the
|
||||
.Ev SSH_CLIENT
|
||||
environment variable and, after performing additional access checks,
|
||||
reads a template file to determine what filter and translation rules
|
||||
(if any) to add.
|
||||
On session exit the same rules that were added at startup are removed.
|
||||
(if any) to add, and
|
||||
maintains the list of IP addresses of connected users in the
|
||||
.Ar authpf_users
|
||||
table.
|
||||
On session exit the same rules and table entries that were added at startup
|
||||
are removed, and all states associated with the client's IP address are purged.
|
||||
.Pp
|
||||
Each
|
||||
.Nm
|
||||
@ -185,6 +203,9 @@ It is also possible to configure
|
||||
to only allow specific users access.
|
||||
This is done by listing their login names, one per line, in
|
||||
.Pa /etc/authpf/authpf.allow .
|
||||
A group of users can also be indicated by prepending "%" to the group name,
|
||||
and all members of a login class can be indicated by prepending "@" to the
|
||||
login class name.
|
||||
If "*" is found on a line, then all usernames match.
|
||||
If
|
||||
.Nm
|
||||
@ -297,7 +318,8 @@ They have a
|
||||
wireless network which they would like to protect from unauthorized use.
|
||||
To accomplish this, they create the file
|
||||
.Pa /etc/authpf/authpf.allow
|
||||
which lists their login ids, one per line.
|
||||
which lists their login ids, group prepended with "%", or login class
|
||||
prepended with "@", one per line.
|
||||
At this point, even if eve could authenticate to
|
||||
.Xr sshd 8 ,
|
||||
she would not be allowed to use the gateway.
|
||||
@ -501,6 +523,31 @@ table <authpf_users> persist
|
||||
anchor "authpf/*" from <authpf_users>
|
||||
rdr-anchor "authpf/*" from <authpf_users>
|
||||
.Ed
|
||||
.Pp
|
||||
.Sy Tunneled users
|
||||
\- normally
|
||||
.Nm
|
||||
allows only one session per client IP address.
|
||||
However in some cases, such as when connections are tunneled via
|
||||
.Xr ssh 1
|
||||
or
|
||||
.Xr ipsec 4 ,
|
||||
the connections can be authorized based on the userid of the user instead of
|
||||
the client IP address.
|
||||
In this case it is appropriate to use
|
||||
.Nm authpf-noip
|
||||
to allow multiple users behind a NAT gateway to connect.
|
||||
In the
|
||||
.Pa /etc/authpf/authpf.rules
|
||||
example below, the remote user could tunnel a remote desktop session to their
|
||||
workstation:
|
||||
.Bd -literal
|
||||
internal_if="bge0"
|
||||
workstation_ip="10.2.3.4"
|
||||
|
||||
pass out on $internal_if from (self) to $workstation_ip port 3389 \e
|
||||
user $user_id
|
||||
.Ed
|
||||
.Sh FILES
|
||||
.Bl -tag -width "/etc/authpf/authpf.conf" -compact
|
||||
.It Pa /etc/authpf/authpf.conf
|
||||
@ -512,7 +559,6 @@ rdr-anchor "authpf/*" from <authpf_users>
|
||||
.Sh SEE ALSO
|
||||
.Xr pf 4 ,
|
||||
.Xr pf.conf 5 ,
|
||||
.Xr fdescfs 5 ,
|
||||
.Xr securelevel 7 ,
|
||||
.Xr ftp-proxy 8
|
||||
.Sh HISTORY
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: authpf.c,v 1.104 2007/02/24 17:35:08 beck Exp $ */
|
||||
/* $OpenBSD: authpf.c,v 1.112 2009/01/10 19:08:53 miod Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1998 - 2007 Bob Beck (beck@openbsd.org).
|
||||
@ -19,7 +19,7 @@
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
#include <login_cap.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -48,10 +49,11 @@ __FBSDID("$FreeBSD$");
|
||||
#include "pathnames.h"
|
||||
|
||||
static int read_config(FILE *);
|
||||
static void print_message(char *);
|
||||
static int allowed_luser(char *);
|
||||
static int check_luser(char *, char *);
|
||||
static void print_message(const char *);
|
||||
static int allowed_luser(struct passwd *);
|
||||
static int check_luser(const char *, char *);
|
||||
static int remove_stale_rulesets(void);
|
||||
static int recursive_ruleset_purge(char *, char *);
|
||||
static int change_filter(int, const char *, const char *);
|
||||
static int change_table(int, const char *);
|
||||
static void authpf_kill_states(void);
|
||||
@ -60,8 +62,10 @@ int dev; /* pf device */
|
||||
char anchorname[PF_ANCHOR_NAME_SIZE] = "authpf";
|
||||
char rulesetname[MAXPATHLEN - PF_ANCHOR_NAME_SIZE - 2];
|
||||
char tablename[PF_TABLE_NAME_SIZE] = "authpf_users";
|
||||
int user_ip = 1; /* controls whether $user_ip is set */
|
||||
|
||||
FILE *pidfp;
|
||||
int pidfd = -1;
|
||||
char luser[MAXLOGNAME]; /* username */
|
||||
char ipsrc[256]; /* ip as a string */
|
||||
char pidfile[MAXPATHLEN]; /* we save pid in this file. */
|
||||
@ -75,6 +79,7 @@ static __dead2 void do_death(int);
|
||||
#else
|
||||
static __dead void do_death(int);
|
||||
#endif
|
||||
extern char *__progname; /* program name */
|
||||
|
||||
/*
|
||||
* User shell for authenticating gateways. Sole purpose is to allow
|
||||
@ -83,21 +88,24 @@ static __dead void do_death(int);
|
||||
* up. Meant to be used only from ssh(1) connections.
|
||||
*/
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
main(void)
|
||||
{
|
||||
int lockcnt = 0, n, pidfd;
|
||||
int lockcnt = 0, n;
|
||||
FILE *config;
|
||||
struct in6_addr ina;
|
||||
struct passwd *pw;
|
||||
char *cp;
|
||||
gid_t gid;
|
||||
uid_t uid;
|
||||
char *shell;
|
||||
const char *shell;
|
||||
login_cap_t *lc;
|
||||
|
||||
if (strcmp(__progname, "-authpf-noip") == 0)
|
||||
user_ip = 0;
|
||||
|
||||
config = fopen(PATH_CONFFILE, "r");
|
||||
if (config == NULL) {
|
||||
syslog(LOG_ERR, "can not open %s (%m)", PATH_CONFFILE);
|
||||
syslog(LOG_ERR, "cannot open %s (%m)", PATH_CONFFILE);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -142,23 +150,34 @@ main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
if ((lc = login_getclass(pw->pw_class)) != NULL)
|
||||
shell = (char *)login_getcapstr(lc, "shell", pw->pw_shell,
|
||||
shell = login_getcapstr(lc, "shell", pw->pw_shell,
|
||||
pw->pw_shell);
|
||||
else
|
||||
shell = pw->pw_shell;
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
login_close(lc);
|
||||
#endif
|
||||
|
||||
if (strcmp(shell, PATH_AUTHPF_SHELL)) {
|
||||
if (strcmp(shell, PATH_AUTHPF_SHELL) &&
|
||||
strcmp(shell, PATH_AUTHPF_SHELL_NOIP)) {
|
||||
syslog(LOG_ERR, "wrong shell for user %s, uid %u",
|
||||
pw->pw_name, pw->pw_uid);
|
||||
#ifdef __FreeBSD__
|
||||
login_close(lc);
|
||||
#else
|
||||
if (shell != pw->pw_shell)
|
||||
free(shell);
|
||||
#endif
|
||||
goto die;
|
||||
}
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
login_close(lc);
|
||||
#else
|
||||
if (shell != pw->pw_shell)
|
||||
free(shell);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Paranoia, but this data _does_ come from outside authpf, and
|
||||
@ -181,13 +200,22 @@ main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
|
||||
/* Make our entry in /var/authpf as /var/authpf/ipaddr */
|
||||
n = snprintf(pidfile, sizeof(pidfile), "%s/%s", PATH_PIDFILE, ipsrc);
|
||||
/* Make our entry in /var/authpf as ipaddr or username */
|
||||
n = snprintf(pidfile, sizeof(pidfile), "%s/%s",
|
||||
PATH_PIDFILE, user_ip ? ipsrc : luser);
|
||||
if (n < 0 || (u_int)n >= sizeof(pidfile)) {
|
||||
syslog(LOG_ERR, "path to pidfile too long");
|
||||
goto die;
|
||||
}
|
||||
|
||||
signal(SIGTERM, need_death);
|
||||
signal(SIGINT, need_death);
|
||||
signal(SIGALRM, need_death);
|
||||
signal(SIGPIPE, need_death);
|
||||
signal(SIGHUP, need_death);
|
||||
signal(SIGQUIT, need_death);
|
||||
signal(SIGTSTP, need_death);
|
||||
|
||||
/*
|
||||
* If someone else is already using this ip, then this person
|
||||
* wants to switch users - so kill the old process and exit
|
||||
@ -241,15 +269,17 @@ main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
/*
|
||||
* we try to kill the previous process and acquire the lock
|
||||
* We try to kill the previous process and acquire the lock
|
||||
* for 10 seconds, trying once a second. if we can't after
|
||||
* 10 attempts we log an error and give up
|
||||
* 10 attempts we log an error and give up.
|
||||
*/
|
||||
if (++lockcnt > 10) {
|
||||
syslog(LOG_ERR, "cannot kill previous authpf (pid %d)",
|
||||
otherpid);
|
||||
if (want_death || ++lockcnt > 10) {
|
||||
if (!want_death)
|
||||
syslog(LOG_ERR, "cannot kill previous authpf (pid %d)",
|
||||
otherpid);
|
||||
fclose(pidfp);
|
||||
pidfp = NULL;
|
||||
pidfd = -1;
|
||||
goto dogdeath;
|
||||
}
|
||||
sleep(1);
|
||||
@ -260,6 +290,7 @@ main(int argc, char *argv[])
|
||||
*/
|
||||
fclose(pidfp);
|
||||
pidfp = NULL;
|
||||
pidfd = -1;
|
||||
} while (1);
|
||||
|
||||
/* whack the group list */
|
||||
@ -277,7 +308,7 @@ main(int argc, char *argv[])
|
||||
}
|
||||
openlog("authpf", LOG_PID | LOG_NDELAY, LOG_DAEMON);
|
||||
|
||||
if (!check_luser(PATH_BAN_DIR, luser) || !allowed_luser(luser)) {
|
||||
if (!check_luser(PATH_BAN_DIR, luser) || !allowed_luser(pw)) {
|
||||
syslog(LOG_INFO, "user %s prohibited", luser);
|
||||
do_death(0);
|
||||
}
|
||||
@ -302,19 +333,12 @@ main(int argc, char *argv[])
|
||||
printf("Unable to modify filters\r\n");
|
||||
do_death(0);
|
||||
}
|
||||
if (change_table(1, ipsrc) == -1) {
|
||||
if (user_ip && change_table(1, ipsrc) == -1) {
|
||||
printf("Unable to modify table\r\n");
|
||||
change_filter(0, luser, ipsrc);
|
||||
do_death(0);
|
||||
}
|
||||
|
||||
signal(SIGTERM, need_death);
|
||||
signal(SIGINT, need_death);
|
||||
signal(SIGALRM, need_death);
|
||||
signal(SIGPIPE, need_death);
|
||||
signal(SIGHUP, need_death);
|
||||
signal(SIGQUIT, need_death);
|
||||
signal(SIGTSTP, need_death);
|
||||
while (1) {
|
||||
printf("\r\nHello %s. ", luser);
|
||||
printf("You are authenticated from host \"%s\"\r\n", ipsrc);
|
||||
@ -337,8 +361,6 @@ dogdeath:
|
||||
sleep(180); /* them lusers read reaaaaal slow */
|
||||
die:
|
||||
do_death(0);
|
||||
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
@ -361,6 +383,8 @@ read_config(FILE *f)
|
||||
}
|
||||
i++;
|
||||
len = strlen(buf);
|
||||
if (len == 0)
|
||||
continue;
|
||||
if (buf[len - 1] != '\n' && !feof(f)) {
|
||||
syslog(LOG_ERR, "line %d too long in %s", i,
|
||||
PATH_CONFFILE);
|
||||
@ -413,7 +437,7 @@ parse_error:
|
||||
* they've been bad or we're unavailable.
|
||||
*/
|
||||
static void
|
||||
print_message(char *filename)
|
||||
print_message(const char *filename)
|
||||
{
|
||||
char buf[1024];
|
||||
FILE *f;
|
||||
@ -436,6 +460,7 @@ print_message(char *filename)
|
||||
* allowed_luser checks to see if user "luser" is allowed to
|
||||
* use this gateway by virtue of being listed in an allowed
|
||||
* users file, namely /etc/authpf/authpf.allow .
|
||||
* Users may be listed by <username>, %<group>, or @<login_class>.
|
||||
*
|
||||
* If /etc/authpf/authpf.allow does not exist, then we assume that
|
||||
* all users who are allowed in by sshd(8) are permitted to
|
||||
@ -444,9 +469,9 @@ print_message(char *filename)
|
||||
* the session terminates in the same manner as being banned.
|
||||
*/
|
||||
static int
|
||||
allowed_luser(char *luser)
|
||||
allowed_luser(struct passwd *pw)
|
||||
{
|
||||
char *buf, *lbuf;
|
||||
char *buf,*lbuf;
|
||||
int matched;
|
||||
size_t len;
|
||||
FILE *f;
|
||||
@ -476,8 +501,14 @@ allowed_luser(char *luser)
|
||||
* "public" gateway, such as it is, so let
|
||||
* everyone use it.
|
||||
*/
|
||||
int gl_init = 0, ngroups = NGROUPS + 1;
|
||||
gid_t groups[NGROUPS + 1];
|
||||
|
||||
lbuf = NULL;
|
||||
matched = 0;
|
||||
|
||||
while ((buf = fgetln(f, &len))) {
|
||||
|
||||
if (buf[len - 1] == '\n')
|
||||
buf[len - 1] = '\0';
|
||||
else {
|
||||
@ -488,7 +519,40 @@ allowed_luser(char *luser)
|
||||
buf = lbuf;
|
||||
}
|
||||
|
||||
matched = strcmp(luser, buf) == 0 || strcmp("*", buf) == 0;
|
||||
if (buf[0] == '@') {
|
||||
/* check login class */
|
||||
if (strcmp(pw->pw_class, buf + 1) == 0)
|
||||
matched++;
|
||||
} else if (buf[0] == '%') {
|
||||
/* check group membership */
|
||||
int cnt;
|
||||
struct group *group;
|
||||
|
||||
if ((group = getgrnam(buf + 1)) == NULL) {
|
||||
syslog(LOG_ERR,
|
||||
"invalid group '%s' in %s (%s)",
|
||||
buf + 1, PATH_ALLOWFILE,
|
||||
strerror(errno));
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (!gl_init) {
|
||||
(void) getgrouplist(pw->pw_name,
|
||||
pw->pw_gid, groups, &ngroups);
|
||||
gl_init++;
|
||||
}
|
||||
|
||||
for ( cnt = 0; cnt < ngroups; cnt++) {
|
||||
if (group->gr_gid == groups[cnt]) {
|
||||
matched++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* check username and wildcard */
|
||||
matched = strcmp(pw->pw_name, buf) == 0 ||
|
||||
strcmp("*", buf) == 0;
|
||||
}
|
||||
|
||||
if (lbuf != NULL) {
|
||||
free(lbuf);
|
||||
@ -496,13 +560,13 @@ allowed_luser(char *luser)
|
||||
}
|
||||
|
||||
if (matched)
|
||||
return (1); /* matched an allowed username */
|
||||
return (1); /* matched an allowed user/group */
|
||||
}
|
||||
syslog(LOG_INFO, "denied access to %s: not listed in %s",
|
||||
luser, PATH_ALLOWFILE);
|
||||
pw->pw_name, PATH_ALLOWFILE);
|
||||
|
||||
/* reuse buf */
|
||||
buf = "\n\nSorry, you are not allowed to use this facility!\n";
|
||||
sprintf(buf, "%s", "\n\nSorry, you are not allowed to use this facility!\n");
|
||||
fputs(buf, stdout);
|
||||
}
|
||||
fflush(stdout);
|
||||
@ -520,13 +584,13 @@ allowed_luser(char *luser)
|
||||
* going to be un-banned.)
|
||||
*/
|
||||
static int
|
||||
check_luser(char *luserdir, char *luser)
|
||||
check_luser(const char *luserdir, char *l_user)
|
||||
{
|
||||
FILE *f;
|
||||
int n;
|
||||
char tmp[MAXPATHLEN];
|
||||
|
||||
n = snprintf(tmp, sizeof(tmp), "%s/%s", luserdir, luser);
|
||||
n = snprintf(tmp, sizeof(tmp), "%s/%s", luserdir, l_user);
|
||||
if (n < 0 || (u_int)n >= sizeof(tmp)) {
|
||||
syslog(LOG_ERR, "provided banned directory line too long (%s)",
|
||||
luserdir);
|
||||
@ -555,7 +619,7 @@ check_luser(char *luserdir, char *luser)
|
||||
* tell what they can do and where they can go.
|
||||
*/
|
||||
syslog(LOG_INFO, "denied access to %s: %s exists",
|
||||
luser, tmp);
|
||||
l_user, tmp);
|
||||
|
||||
/* reuse tmp */
|
||||
strlcpy(tmp, "\n\n-**- Sorry, you have been banned! -**-\n\n",
|
||||
@ -581,7 +645,7 @@ static int
|
||||
remove_stale_rulesets(void)
|
||||
{
|
||||
struct pfioc_ruleset prs;
|
||||
u_int32_t nr, mnr;
|
||||
u_int32_t nr;
|
||||
|
||||
memset(&prs, 0, sizeof(prs));
|
||||
strlcpy(prs.path, anchorname, sizeof(prs.path));
|
||||
@ -592,13 +656,12 @@ remove_stale_rulesets(void)
|
||||
return (1);
|
||||
}
|
||||
|
||||
mnr = prs.nr;
|
||||
nr = 0;
|
||||
while (nr < mnr) {
|
||||
nr = prs.nr;
|
||||
while (nr) {
|
||||
char *s, *t;
|
||||
pid_t pid;
|
||||
|
||||
prs.nr = nr;
|
||||
prs.nr = nr - 1;
|
||||
if (ioctl(dev, DIOCGETRULESET, &prs))
|
||||
return (1);
|
||||
errno = 0;
|
||||
@ -610,119 +673,159 @@ remove_stale_rulesets(void)
|
||||
if (!prs.name[0] || errno ||
|
||||
(*s && (t == prs.name || *s != ')')))
|
||||
return (1);
|
||||
if (kill(pid, 0) && errno != EPERM) {
|
||||
int i;
|
||||
struct pfioc_trans_e t_e[PF_RULESET_MAX+1];
|
||||
struct pfioc_trans t;
|
||||
|
||||
bzero(&t, sizeof(t));
|
||||
bzero(t_e, sizeof(t_e));
|
||||
t.size = PF_RULESET_MAX+1;
|
||||
t.esize = sizeof(t_e[0]);
|
||||
t.array = t_e;
|
||||
for (i = 0; i < PF_RULESET_MAX+1; ++i) {
|
||||
t_e[i].rs_num = i;
|
||||
snprintf(t_e[i].anchor, sizeof(t_e[i].anchor),
|
||||
"%s/%s", anchorname, prs.name);
|
||||
}
|
||||
t_e[PF_RULESET_MAX].rs_num = PF_RULESET_TABLE;
|
||||
if ((ioctl(dev, DIOCXBEGIN, &t) ||
|
||||
ioctl(dev, DIOCXCOMMIT, &t)) &&
|
||||
errno != EINVAL)
|
||||
if ((kill(pid, 0) && errno != EPERM) || pid == getpid()) {
|
||||
if (recursive_ruleset_purge(anchorname, prs.name))
|
||||
return (1);
|
||||
mnr--;
|
||||
} else
|
||||
nr++;
|
||||
}
|
||||
nr--;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
recursive_ruleset_purge(char *an, char *rs)
|
||||
{
|
||||
struct pfioc_trans_e *t_e = NULL;
|
||||
struct pfioc_trans *t = NULL;
|
||||
struct pfioc_ruleset *prs = NULL;
|
||||
int i;
|
||||
|
||||
|
||||
/* purge rules */
|
||||
errno = 0;
|
||||
if ((t = calloc(1, sizeof(struct pfioc_trans))) == NULL)
|
||||
goto no_mem;
|
||||
if ((t_e = calloc(PF_RULESET_MAX+1,
|
||||
sizeof(struct pfioc_trans_e))) == NULL)
|
||||
goto no_mem;
|
||||
t->size = PF_RULESET_MAX+1;
|
||||
t->esize = sizeof(struct pfioc_trans_e);
|
||||
t->array = t_e;
|
||||
for (i = 0; i < PF_RULESET_MAX+1; ++i) {
|
||||
t_e[i].rs_num = i;
|
||||
snprintf(t_e[i].anchor, sizeof(t_e[i].anchor), "%s/%s", an, rs);
|
||||
}
|
||||
t_e[PF_RULESET_MAX].rs_num = PF_RULESET_TABLE;
|
||||
if ((ioctl(dev, DIOCXBEGIN, t) ||
|
||||
ioctl(dev, DIOCXCOMMIT, t)) &&
|
||||
errno != EINVAL)
|
||||
goto cleanup;
|
||||
|
||||
/* purge any children */
|
||||
if ((prs = calloc(1, sizeof(struct pfioc_ruleset))) == NULL)
|
||||
goto no_mem;
|
||||
snprintf(prs->path, sizeof(prs->path), "%s/%s", an, rs);
|
||||
if (ioctl(dev, DIOCGETRULESETS, prs)) {
|
||||
if (errno != EINVAL)
|
||||
goto cleanup;
|
||||
errno = 0;
|
||||
} else {
|
||||
int nr = prs->nr;
|
||||
|
||||
while (nr) {
|
||||
prs->nr = 0;
|
||||
if (ioctl(dev, DIOCGETRULESET, prs))
|
||||
goto cleanup;
|
||||
|
||||
if (recursive_ruleset_purge(prs->path, prs->name))
|
||||
goto cleanup;
|
||||
nr--;
|
||||
}
|
||||
}
|
||||
|
||||
no_mem:
|
||||
if (errno == ENOMEM)
|
||||
syslog(LOG_ERR, "calloc failed");
|
||||
|
||||
cleanup:
|
||||
free(t);
|
||||
free(t_e);
|
||||
free(prs);
|
||||
return (errno);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add/remove filter entries for user "luser" from ip "ipsrc"
|
||||
*/
|
||||
static int
|
||||
change_filter(int add, const char *luser, const char *ipsrc)
|
||||
change_filter(int add, const char *l_user, const char *ip_src)
|
||||
{
|
||||
char *pargv[13] = {
|
||||
"pfctl", "-p", "/dev/pf", "-q", "-a", "anchor/ruleset",
|
||||
"-D", "user_ip=X", "-D", "user_id=X", "-f",
|
||||
"file", NULL
|
||||
};
|
||||
char *fdpath = NULL, *userstr = NULL, *ipstr = NULL;
|
||||
char *rsn = NULL, *fn = NULL;
|
||||
pid_t pid;
|
||||
gid_t gid;
|
||||
int s;
|
||||
|
||||
if (luser == NULL || !luser[0] || ipsrc == NULL || !ipsrc[0]) {
|
||||
syslog(LOG_ERR, "invalid luser/ipsrc");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (asprintf(&rsn, "%s/%s", anchorname, rulesetname) == -1)
|
||||
goto no_mem;
|
||||
if (asprintf(&fdpath, "/dev/fd/%d", dev) == -1)
|
||||
goto no_mem;
|
||||
if (asprintf(&ipstr, "user_ip=%s", ipsrc) == -1)
|
||||
goto no_mem;
|
||||
if (asprintf(&userstr, "user_id=%s", luser) == -1)
|
||||
goto no_mem;
|
||||
|
||||
if (add) {
|
||||
struct stat sb;
|
||||
char *pargv[13] = {
|
||||
"pfctl", "-p", "/dev/pf", "-q", "-a", "anchor/ruleset",
|
||||
"-D", "user_id=X", "-D", "user_ip=X", "-f", "file", NULL
|
||||
};
|
||||
|
||||
if (asprintf(&fn, "%s/%s/authpf.rules", PATH_USER_DIR, luser)
|
||||
== -1)
|
||||
if (l_user == NULL || !l_user[0] || ip_src == NULL || !ip_src[0]) {
|
||||
syslog(LOG_ERR, "invalid luser/ipsrc");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (asprintf(&rsn, "%s/%s", anchorname, rulesetname) == -1)
|
||||
goto no_mem;
|
||||
if (asprintf(&fdpath, "/dev/fd/%d", dev) == -1)
|
||||
goto no_mem;
|
||||
if (asprintf(&ipstr, "user_ip=%s", ip_src) == -1)
|
||||
goto no_mem;
|
||||
if (asprintf(&userstr, "user_id=%s", l_user) == -1)
|
||||
goto no_mem;
|
||||
if (asprintf(&fn, "%s/%s/authpf.rules",
|
||||
PATH_USER_DIR, l_user) == -1)
|
||||
goto no_mem;
|
||||
if (stat(fn, &sb) == -1) {
|
||||
free(fn);
|
||||
if ((fn = strdup(PATH_PFRULES)) == NULL)
|
||||
goto no_mem;
|
||||
}
|
||||
}
|
||||
pargv[2] = fdpath;
|
||||
pargv[5] = rsn;
|
||||
pargv[7] = userstr;
|
||||
pargv[9] = ipstr;
|
||||
if (!add)
|
||||
pargv[11] = "/dev/null";
|
||||
else
|
||||
pargv[11] = fn;
|
||||
|
||||
switch (pid = fork()) {
|
||||
case -1:
|
||||
syslog(LOG_ERR, "fork failed");
|
||||
goto error;
|
||||
case 0:
|
||||
/* revoke group privs before exec */
|
||||
gid = getgid();
|
||||
if (setregid(gid, gid) == -1) {
|
||||
err(1, "setregid");
|
||||
pargv[2] = fdpath;
|
||||
pargv[5] = rsn;
|
||||
pargv[7] = userstr;
|
||||
if (user_ip) {
|
||||
pargv[9] = ipstr;
|
||||
pargv[11] = fn;
|
||||
} else {
|
||||
pargv[8] = "-f";
|
||||
pargv[9] = fn;
|
||||
pargv[10] = NULL;
|
||||
}
|
||||
execvp(PATH_PFCTL, pargv);
|
||||
warn("exec of %s failed", PATH_PFCTL);
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
/* parent */
|
||||
waitpid(pid, &s, 0);
|
||||
if (s != 0) {
|
||||
syslog(LOG_ERR, "pfctl exited abnormally");
|
||||
goto error;
|
||||
}
|
||||
switch (pid = fork()) {
|
||||
case -1:
|
||||
syslog(LOG_ERR, "fork failed");
|
||||
goto error;
|
||||
case 0:
|
||||
/* revoke group privs before exec */
|
||||
gid = getgid();
|
||||
if (setregid(gid, gid) == -1) {
|
||||
err(1, "setregid");
|
||||
}
|
||||
execvp(PATH_PFCTL, pargv);
|
||||
warn("exec of %s failed", PATH_PFCTL);
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
/* parent */
|
||||
waitpid(pid, &s, 0);
|
||||
if (s != 0) {
|
||||
syslog(LOG_ERR, "pfctl exited abnormally");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (add) {
|
||||
gettimeofday(&Tstart, NULL);
|
||||
syslog(LOG_INFO, "allowing %s, user %s", ipsrc, luser);
|
||||
syslog(LOG_INFO, "allowing %s, user %s", ip_src, l_user);
|
||||
} else {
|
||||
remove_stale_rulesets();
|
||||
|
||||
gettimeofday(&Tend, NULL);
|
||||
#ifdef __FreeBSD__
|
||||
syslog(LOG_INFO, "removed %s, user %s - duration %jd seconds",
|
||||
ipsrc, luser, (intmax_t)(Tend.tv_sec - Tstart.tv_sec));
|
||||
#else
|
||||
syslog(LOG_INFO, "removed %s, user %s - duration %ld seconds",
|
||||
ipsrc, luser, Tend.tv_sec - Tstart.tv_sec);
|
||||
#endif
|
||||
syslog(LOG_INFO, "removed %s, user %s - duration %ju seconds",
|
||||
ip_src, l_user, (uintmax_t)(Tend.tv_sec - Tstart.tv_sec));
|
||||
}
|
||||
return (0);
|
||||
no_mem:
|
||||
@ -740,7 +843,7 @@ error:
|
||||
* Add/remove this IP from the "authpf_users" table.
|
||||
*/
|
||||
static int
|
||||
change_table(int add, const char *ipsrc)
|
||||
change_table(int add, const char *ip_src)
|
||||
{
|
||||
struct pfioc_table io;
|
||||
struct pfr_addr addr;
|
||||
@ -753,12 +856,12 @@ change_table(int add, const char *ipsrc)
|
||||
io.pfrio_size = 1;
|
||||
|
||||
bzero(&addr, sizeof(addr));
|
||||
if (ipsrc == NULL || !ipsrc[0])
|
||||
if (ip_src == NULL || !ip_src[0])
|
||||
return (-1);
|
||||
if (inet_pton(AF_INET, ipsrc, &addr.pfra_ip4addr) == 1) {
|
||||
if (inet_pton(AF_INET, ip_src, &addr.pfra_ip4addr) == 1) {
|
||||
addr.pfra_af = AF_INET;
|
||||
addr.pfra_net = 32;
|
||||
} else if (inet_pton(AF_INET6, ipsrc, &addr.pfra_ip6addr) == 1) {
|
||||
} else if (inet_pton(AF_INET6, ip_src, &addr.pfra_ip6addr) == 1) {
|
||||
addr.pfra_af = AF_INET6;
|
||||
addr.pfra_net = 128;
|
||||
} else {
|
||||
@ -769,7 +872,7 @@ change_table(int add, const char *ipsrc)
|
||||
if (ioctl(dev, add ? DIOCRADDADDRS : DIOCRDELADDRS, &io) &&
|
||||
errno != ESRCH) {
|
||||
syslog(LOG_ERR, "cannot %s %s from table %s: %s",
|
||||
add ? "add" : "remove", ipsrc, tablename,
|
||||
add ? "add" : "remove", ip_src, tablename,
|
||||
strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
@ -821,7 +924,7 @@ authpf_kill_states(void)
|
||||
|
||||
/* signal handler that makes us go away properly */
|
||||
static void
|
||||
need_death(int signo)
|
||||
need_death(int signo __unused)
|
||||
{
|
||||
want_death = 1;
|
||||
}
|
||||
@ -840,11 +943,12 @@ do_death(int active)
|
||||
|
||||
if (active) {
|
||||
change_filter(0, luser, ipsrc);
|
||||
change_table(0, ipsrc);
|
||||
authpf_kill_states();
|
||||
remove_stale_rulesets();
|
||||
if (user_ip) {
|
||||
change_table(0, ipsrc);
|
||||
authpf_kill_states();
|
||||
}
|
||||
}
|
||||
if (pidfile[0] && (pidfp != NULL))
|
||||
if (pidfile[0] && pidfd != -1)
|
||||
if (unlink(pidfile) == -1)
|
||||
syslog(LOG_ERR, "cannot unlink %s (%m)", pidfile);
|
||||
exit(ret);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: pathnames.h,v 1.7 2004/04/25 18:40:42 beck Exp $ */
|
||||
/* $OpenBSD: pathnames.h,v 1.8 2008/02/14 01:49:17 mcbride Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2002 Chris Kuethe (ckuethe@ualberta.ca)
|
||||
@ -35,4 +35,5 @@
|
||||
#define PATH_DEVFILE "/dev/pf"
|
||||
#define PATH_PIDFILE "/var/authpf"
|
||||
#define PATH_AUTHPF_SHELL "/usr/sbin/authpf"
|
||||
#define PATH_AUTHPF_SHELL_NOIP "/usr/sbin/authpf-noip"
|
||||
#define PATH_PFCTL "/sbin/pfctl"
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: filter.c,v 1.5 2006/12/01 07:31:21 camield Exp $ */
|
||||
/* $OpenBSD: filter.c,v 1.8 2008/06/13 07:25:26 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004, 2005 Camiel Dobbelaar, <cd@sentia.nl>
|
||||
@ -53,7 +53,7 @@ static struct pfioc_rule pfr;
|
||||
static struct pfioc_trans pft;
|
||||
static struct pfioc_trans_e pfte[TRANS_SIZE];
|
||||
static int dev, rule_log;
|
||||
static char *qname;
|
||||
static const char *qname, *tagname;
|
||||
|
||||
int
|
||||
add_filter(u_int32_t id, u_int8_t dir, struct sockaddr *src,
|
||||
@ -159,11 +159,12 @@ do_rollback(void)
|
||||
}
|
||||
|
||||
void
|
||||
init_filter(char *opt_qname, int opt_verbose)
|
||||
init_filter(const char *opt_qname, const char *opt_tagname, int opt_verbose)
|
||||
{
|
||||
struct pf_status status;
|
||||
|
||||
qname = opt_qname;
|
||||
tagname = opt_tagname;
|
||||
|
||||
if (opt_verbose == 1)
|
||||
rule_log = PF_LOG;
|
||||
@ -172,7 +173,7 @@ init_filter(char *opt_qname, int opt_verbose)
|
||||
|
||||
dev = open("/dev/pf", O_RDWR);
|
||||
if (dev == -1)
|
||||
err(1, "/dev/pf");
|
||||
err(1, "open /dev/pf");
|
||||
if (ioctl(dev, DIOCGETSTATUS, &status) == -1)
|
||||
err(1, "DIOCGETSTATUS");
|
||||
if (!status.running)
|
||||
@ -280,9 +281,9 @@ prepare_rule(u_int32_t id, int rs_num, struct sockaddr *src,
|
||||
switch (rs_num) {
|
||||
case PF_RULESET_FILTER:
|
||||
/*
|
||||
* pass quick [log] inet[6] proto tcp \
|
||||
* pass [quick] [log] inet[6] proto tcp \
|
||||
* from $src to $dst port = $d_port flags S/SA keep state
|
||||
* (max 1) [queue qname]
|
||||
* (max 1) [queue qname] [tag tagname]
|
||||
*/
|
||||
pfr.rule.action = PF_PASS;
|
||||
pfr.rule.quick = 1;
|
||||
@ -293,6 +294,11 @@ prepare_rule(u_int32_t id, int rs_num, struct sockaddr *src,
|
||||
pfr.rule.max_states = 1;
|
||||
if (qname != NULL)
|
||||
strlcpy(pfr.rule.qname, qname, sizeof pfr.rule.qname);
|
||||
if (tagname != NULL) {
|
||||
pfr.rule.quick = 0;
|
||||
strlcpy(pfr.rule.tagname, tagname,
|
||||
sizeof pfr.rule.tagname);
|
||||
}
|
||||
break;
|
||||
case PF_RULESET_NAT:
|
||||
/*
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: filter.h,v 1.3 2005/06/07 14:12:07 camield Exp $ */
|
||||
/* $OpenBSD: filter.h,v 1.4 2007/08/01 09:31:41 henning Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004, 2005 Camiel Dobbelaar, <cd@sentia.nl>
|
||||
@ -26,6 +26,6 @@ int add_rdr(u_int32_t, struct sockaddr *, struct sockaddr *, u_int16_t,
|
||||
struct sockaddr *, u_int16_t);
|
||||
int do_commit(void);
|
||||
int do_rollback(void);
|
||||
void init_filter(char *, int);
|
||||
void init_filter(const char *, const char *, int);
|
||||
int prepare_commit(u_int32_t);
|
||||
int server_lookup(struct sockaddr *, struct sockaddr *, struct sockaddr *);
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $OpenBSD: ftp-proxy.8,v 1.7 2006/12/30 13:01:54 camield Exp $
|
||||
.\" $OpenBSD: ftp-proxy.8,v 1.11 2008/02/26 18:52:53 henning Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2004, 2005 Camiel Dobbelaar, <cd@sentia.nl>
|
||||
.\"
|
||||
@ -16,14 +16,15 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd November 28, 2004
|
||||
.Dd February 26, 2008
|
||||
.Dt FTP-PROXY 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm ftp-proxy
|
||||
.Nd Internet File Transfer Protocol proxy daemon
|
||||
.Sh SYNOPSIS
|
||||
.Nm ftp-proxy
|
||||
.Nm
|
||||
.Bk -words
|
||||
.Op Fl 6Adrv
|
||||
.Op Fl a Ar address
|
||||
.Op Fl b Ar address
|
||||
@ -33,7 +34,9 @@
|
||||
.Op Fl p Ar port
|
||||
.Op Fl q Ar queue
|
||||
.Op Fl R Ar address
|
||||
.Op Fl T Ar tag
|
||||
.Op Fl t Ar timeout
|
||||
.Ek
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
is a proxy for the Internet File Transfer Protocol.
|
||||
@ -58,7 +61,7 @@ facility for this.
|
||||
Assuming the FTP control connection is from $client to $server, the
|
||||
proxy connected to the server using the $proxy source address, and
|
||||
$port is negotiated, then
|
||||
.Nm ftp-proxy
|
||||
.Nm
|
||||
adds the following rules to the various anchors.
|
||||
(These example rules use inet, but the proxy also supports inet6.)
|
||||
.Pp
|
||||
@ -130,6 +133,20 @@ connections to another proxy.
|
||||
.It Fl r
|
||||
Rewrite sourceport to 20 in active mode to suit ancient clients that insist
|
||||
on this RFC property.
|
||||
.It Fl T Ar tag
|
||||
The filter rules will add tag
|
||||
.Ar tag
|
||||
to data connections, and not match quick.
|
||||
This way alternative rules that use the
|
||||
.Ar tagged
|
||||
keyword can be implemented following the
|
||||
.Nm
|
||||
anchor.
|
||||
These rules can use special
|
||||
.Xr pf 4
|
||||
features like route-to, reply-to, label, rtable, overload, etc. that
|
||||
.Nm
|
||||
does not implement itself.
|
||||
.It Fl t Ar timeout
|
||||
Number of seconds that the control connection can be idle, before the
|
||||
proxy will disconnect.
|
||||
@ -172,7 +189,7 @@ does not allow the ruleset to be modified if the system is running at a
|
||||
.Xr securelevel 7
|
||||
higher than 1.
|
||||
At that level
|
||||
.Nm ftp-proxy
|
||||
.Nm
|
||||
cannot add rules to the anchors and FTP data connections may get blocked.
|
||||
.Pp
|
||||
Negotiated data connection ports below 1024 are not allowed.
|
||||
@ -181,5 +198,5 @@ The negotiated IP address for active modes is ignored for security
|
||||
reasons.
|
||||
This makes third party file transfers impossible.
|
||||
.Pp
|
||||
.Nm ftp-proxy
|
||||
.Nm
|
||||
chroots to "/var/empty" and changes to user "proxy" to drop privileges.
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: ftp-proxy.c,v 1.13 2006/12/30 13:24:00 camield Exp $ */
|
||||
/* $OpenBSD: ftp-proxy.c,v 1.19 2008/06/13 07:25:26 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004, 2005 Camiel Dobbelaar, <cd@sentia.nl>
|
||||
@ -61,6 +61,14 @@ __FBSDID("$FreeBSD$");
|
||||
#define PF_NAT_PROXY_PORT_LOW 50001
|
||||
#define PF_NAT_PROXY_PORT_HIGH 65535
|
||||
|
||||
#ifndef LIST_END
|
||||
#define LIST_END(a) NULL
|
||||
#endif
|
||||
|
||||
#ifndef getrtable
|
||||
#define getrtable(a) 0
|
||||
#endif
|
||||
|
||||
#define sstosa(ss) ((struct sockaddr *)(ss))
|
||||
|
||||
enum { CMD_NONE = 0, CMD_PORT, CMD_EPRT, CMD_PASV, CMD_EPSV };
|
||||
@ -94,7 +102,7 @@ int client_parse_cmd(struct session *s);
|
||||
void client_read(struct bufferevent *, void *);
|
||||
int drop_privs(void);
|
||||
void end_session(struct session *);
|
||||
int exit_daemon(void);
|
||||
void exit_daemon(void);
|
||||
int getline(char *, size_t *);
|
||||
void handle_connection(const int, short, void *);
|
||||
void handle_signal(int, short, void *);
|
||||
@ -105,6 +113,7 @@ u_int16_t pick_proxy_port(void);
|
||||
void proxy_reply(int, struct sockaddr *, u_int16_t);
|
||||
void server_error(struct bufferevent *, short, void *);
|
||||
int server_parse(struct session *s);
|
||||
int allow_data_connection(struct session *s);
|
||||
void server_read(struct bufferevent *, void *);
|
||||
const char *sock_ntop(struct sockaddr *);
|
||||
void usage(void);
|
||||
@ -115,14 +124,14 @@ size_t linelen;
|
||||
char ntop_buf[NTOP_BUFS][INET6_ADDRSTRLEN];
|
||||
|
||||
struct sockaddr_storage fixed_server_ss, fixed_proxy_ss;
|
||||
char *fixed_server, *fixed_server_port, *fixed_proxy, *listen_ip, *listen_port,
|
||||
*qname;
|
||||
const char *fixed_server, *fixed_server_port, *fixed_proxy, *listen_ip, *listen_port,
|
||||
*qname, *tagname;
|
||||
int anonymous_only, daemonize, id_count, ipv6_mode, loglevel, max_sessions,
|
||||
rfc_mode, session_count, timeout, verbose;
|
||||
extern char *__progname;
|
||||
|
||||
void
|
||||
client_error(struct bufferevent *bufev, short what, void *arg)
|
||||
client_error(struct bufferevent *bufev __unused, short what, void *arg)
|
||||
{
|
||||
struct session *s = arg;
|
||||
|
||||
@ -152,8 +161,19 @@ client_parse(struct session *s)
|
||||
return (1);
|
||||
|
||||
if (linebuf[0] == 'P' || linebuf[0] == 'p' ||
|
||||
linebuf[0] == 'E' || linebuf[0] == 'e')
|
||||
return (client_parse_cmd(s));
|
||||
linebuf[0] == 'E' || linebuf[0] == 'e') {
|
||||
if (!client_parse_cmd(s))
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Allow active mode connections immediately, instead of
|
||||
* waiting for a positive reply from the server. Some
|
||||
* rare servers/proxies try to probe or setup the data
|
||||
* connection before an actual transfer request.
|
||||
*/
|
||||
if (s->cmd == CMD_PORT || s->cmd == CMD_EPRT)
|
||||
return (allow_data_connection(s));
|
||||
}
|
||||
|
||||
if (anonymous_only && (linebuf[0] == 'U' || linebuf[0] == 'u'))
|
||||
return (client_parse_anon(s));
|
||||
@ -220,14 +240,14 @@ void
|
||||
client_read(struct bufferevent *bufev, void *arg)
|
||||
{
|
||||
struct session *s = arg;
|
||||
size_t buf_avail, read;
|
||||
size_t buf_avail, clientread;
|
||||
int n;
|
||||
|
||||
do {
|
||||
buf_avail = sizeof s->cbuf - s->cbuf_valid;
|
||||
read = bufferevent_read(bufev, s->cbuf + s->cbuf_valid,
|
||||
clientread = bufferevent_read(bufev, s->cbuf + s->cbuf_valid,
|
||||
buf_avail);
|
||||
s->cbuf_valid += read;
|
||||
s->cbuf_valid += clientread;
|
||||
|
||||
while ((n = getline(s->cbuf, &s->cbuf_valid)) > 0) {
|
||||
logmsg(LOG_DEBUG, "#%d client: %s", s->id, linebuf);
|
||||
@ -244,7 +264,7 @@ client_read(struct bufferevent *bufev, void *arg)
|
||||
end_session(s);
|
||||
return;
|
||||
}
|
||||
} while (read == buf_avail);
|
||||
} while (clientread == buf_avail);
|
||||
}
|
||||
|
||||
int
|
||||
@ -269,10 +289,16 @@ drop_privs(void)
|
||||
void
|
||||
end_session(struct session *s)
|
||||
{
|
||||
int err;
|
||||
int serr;
|
||||
|
||||
logmsg(LOG_INFO, "#%d ending session", s->id);
|
||||
|
||||
/* Flush output buffers. */
|
||||
if (s->client_bufev && s->client_fd != -1)
|
||||
evbuffer_write(s->client_bufev->output, s->client_fd);
|
||||
if (s->server_bufev && s->server_fd != -1)
|
||||
evbuffer_write(s->server_bufev->output, s->server_fd);
|
||||
|
||||
if (s->client_fd != -1)
|
||||
close(s->client_fd);
|
||||
if (s->server_fd != -1)
|
||||
@ -284,33 +310,29 @@ end_session(struct session *s)
|
||||
bufferevent_free(s->server_bufev);
|
||||
|
||||
/* Remove rulesets by commiting empty ones. */
|
||||
err = 0;
|
||||
serr = 0;
|
||||
if (prepare_commit(s->id) == -1)
|
||||
err = errno;
|
||||
serr = errno;
|
||||
else if (do_commit() == -1) {
|
||||
err = errno;
|
||||
serr = errno;
|
||||
do_rollback();
|
||||
}
|
||||
if (err)
|
||||
if (serr)
|
||||
logmsg(LOG_ERR, "#%d pf rule removal failed: %s", s->id,
|
||||
strerror(err));
|
||||
strerror(serr));
|
||||
|
||||
LIST_REMOVE(s, entry);
|
||||
free(s);
|
||||
session_count--;
|
||||
}
|
||||
|
||||
int
|
||||
void
|
||||
exit_daemon(void)
|
||||
{
|
||||
struct session *s, *next;
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
LIST_FOREACH_SAFE(s, &sessions, entry, next) {
|
||||
#else
|
||||
for (s = LIST_FIRST(&sessions); s != LIST_END(&sessions); s = next) {
|
||||
next = LIST_NEXT(s, entry);
|
||||
#endif
|
||||
end_session(s);
|
||||
}
|
||||
|
||||
@ -318,9 +340,6 @@ exit_daemon(void)
|
||||
closelog();
|
||||
|
||||
exit(0);
|
||||
|
||||
/* NOTREACHED */
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
@ -361,7 +380,7 @@ getline(char *buf, size_t *valid)
|
||||
}
|
||||
|
||||
void
|
||||
handle_connection(const int listen_fd, short event, void *ev)
|
||||
handle_connection(const int listen_fd, short event __unused, void *ev __unused)
|
||||
{
|
||||
struct sockaddr_storage tmp_ss;
|
||||
struct sockaddr *client_sa, *server_sa, *fixed_server_sa;
|
||||
@ -508,13 +527,13 @@ handle_connection(const int listen_fd, short event, void *ev)
|
||||
}
|
||||
|
||||
void
|
||||
handle_signal(int sig, short event, void *arg)
|
||||
handle_signal(int sig, short event __unused, void *arg __unused)
|
||||
{
|
||||
/*
|
||||
* Signal handler rules don't apply, libevent decouples for us.
|
||||
*/
|
||||
|
||||
logmsg(LOG_ERR, "%s exiting on signal %d", __progname, sig);
|
||||
logmsg(LOG_ERR, "exiting on signal %d", sig);
|
||||
|
||||
exit_daemon();
|
||||
}
|
||||
@ -567,10 +586,7 @@ logmsg(int pri, const char *message, ...)
|
||||
/* We don't care about truncation. */
|
||||
vsnprintf(buf, sizeof buf, message, ap);
|
||||
#ifdef __FreeBSD__
|
||||
/* XXX: strnvis might be nice to have */
|
||||
strvisx(visbuf, buf,
|
||||
MIN((sizeof(visbuf) / 4) - 1, strlen(buf)),
|
||||
VIS_CSTYLE | VIS_NL);
|
||||
strvis(visbuf, buf, VIS_CSTYLE | VIS_NL);
|
||||
#else
|
||||
strnvis(visbuf, buf, sizeof visbuf, VIS_CSTYLE | VIS_NL);
|
||||
#endif
|
||||
@ -602,6 +618,7 @@ main(int argc, char *argv[])
|
||||
max_sessions = 100;
|
||||
qname = NULL;
|
||||
rfc_mode = 0;
|
||||
tagname = NULL;
|
||||
timeout = 24 * 3600;
|
||||
verbose = 0;
|
||||
|
||||
@ -609,7 +626,7 @@ main(int argc, char *argv[])
|
||||
id_count = 1;
|
||||
session_count = 0;
|
||||
|
||||
while ((ch = getopt(argc, argv, "6Aa:b:D:dm:P:p:q:R:rt:v")) != -1) {
|
||||
while ((ch = getopt(argc, argv, "6Aa:b:D:dm:P:p:q:R:rT:t:v")) != -1) {
|
||||
switch (ch) {
|
||||
case '6':
|
||||
ipv6_mode = 1;
|
||||
@ -654,6 +671,11 @@ main(int argc, char *argv[])
|
||||
case 'r':
|
||||
rfc_mode = 1;
|
||||
break;
|
||||
case 'T':
|
||||
if (strlen(optarg) >= PF_TAG_NAME_SIZE)
|
||||
errx(1, "tagname too long");
|
||||
tagname = optarg;
|
||||
break;
|
||||
case 't':
|
||||
timeout = strtonum(optarg, 0, 86400, &errstr);
|
||||
if (errstr)
|
||||
@ -734,7 +756,7 @@ main(int argc, char *argv[])
|
||||
freeaddrinfo(res);
|
||||
|
||||
/* Initialize pf. */
|
||||
init_filter(qname, verbose);
|
||||
init_filter(qname, tagname, verbose);
|
||||
|
||||
if (daemonize) {
|
||||
if (daemon(0, 0) == -1)
|
||||
@ -830,14 +852,15 @@ u_int16_t
|
||||
pick_proxy_port(void)
|
||||
{
|
||||
/* Random should be good enough for avoiding port collisions. */
|
||||
return (IPPORT_HIFIRSTAUTO + (arc4random() %
|
||||
(IPPORT_HILASTAUTO - IPPORT_HIFIRSTAUTO)));
|
||||
return (IPPORT_HIFIRSTAUTO +
|
||||
arc4random_uniform(IPPORT_HILASTAUTO - IPPORT_HIFIRSTAUTO));
|
||||
}
|
||||
|
||||
void
|
||||
proxy_reply(int cmd, struct sockaddr *sa, u_int16_t port)
|
||||
{
|
||||
int i, r;
|
||||
u_int i;
|
||||
int r = 0;
|
||||
|
||||
switch (cmd) {
|
||||
case CMD_PORT:
|
||||
@ -864,7 +887,7 @@ proxy_reply(int cmd, struct sockaddr *sa, u_int16_t port)
|
||||
break;
|
||||
}
|
||||
|
||||
if (r < 0 || r >= sizeof linebuf) {
|
||||
if (r < 0 || ((u_int)r) >= sizeof linebuf) {
|
||||
logmsg(LOG_ERR, "proxy_reply failed: %d", r);
|
||||
linebuf[0] = '\0';
|
||||
linelen = 0;
|
||||
@ -881,7 +904,7 @@ proxy_reply(int cmd, struct sockaddr *sa, u_int16_t port)
|
||||
}
|
||||
|
||||
void
|
||||
server_error(struct bufferevent *bufev, short what, void *arg)
|
||||
server_error(struct bufferevent *bufev __unused, short what, void *arg)
|
||||
{
|
||||
struct session *s = arg;
|
||||
|
||||
@ -902,12 +925,26 @@ server_error(struct bufferevent *bufev, short what, void *arg)
|
||||
int
|
||||
server_parse(struct session *s)
|
||||
{
|
||||
struct sockaddr *client_sa, *orig_sa, *proxy_sa, *server_sa;
|
||||
int prepared = 0;
|
||||
|
||||
if (s->cmd == CMD_NONE || linelen < 4 || linebuf[0] != '2')
|
||||
goto out;
|
||||
|
||||
if ((s->cmd == CMD_PASV && strncmp("227 ", linebuf, 4) == 0) ||
|
||||
(s->cmd == CMD_EPSV && strncmp("229 ", linebuf, 4) == 0))
|
||||
return (allow_data_connection(s));
|
||||
|
||||
out:
|
||||
s->cmd = CMD_NONE;
|
||||
s->port = 0;
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
allow_data_connection(struct session *s)
|
||||
{
|
||||
struct sockaddr *client_sa, *orig_sa, *proxy_sa, *server_sa;
|
||||
int prepared = 0;
|
||||
|
||||
/*
|
||||
* The pf rules below do quite some NAT rewriting, to keep up
|
||||
* appearances. Points to keep in mind:
|
||||
@ -932,8 +969,7 @@ server_parse(struct session *s)
|
||||
orig_sa = sstosa(&s->server_ss);
|
||||
|
||||
/* Passive modes. */
|
||||
if ((s->cmd == CMD_PASV && strncmp("227 ", linebuf, 4) == 0) ||
|
||||
(s->cmd == CMD_EPSV && strncmp("229 ", linebuf, 4) == 0)) {
|
||||
if (s->cmd == CMD_PASV || s->cmd == CMD_EPSV) {
|
||||
s->port = parse_port(s->cmd);
|
||||
if (s->port < MIN_PORT) {
|
||||
logmsg(LOG_CRIT, "#%d bad port in '%s'", s->id,
|
||||
@ -974,8 +1010,7 @@ server_parse(struct session *s)
|
||||
}
|
||||
|
||||
/* Active modes. */
|
||||
if ((s->cmd == CMD_PORT || s->cmd == CMD_EPRT) &&
|
||||
strncmp("200 ", linebuf, 4) == 0) {
|
||||
if (s->cmd == CMD_PORT || s->cmd == CMD_EPRT) {
|
||||
logmsg(LOG_INFO, "#%d active: server to client port %d"
|
||||
" via port %d", s->id, s->port, s->proxy_port);
|
||||
|
||||
@ -1025,7 +1060,6 @@ server_parse(struct session *s)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
out:
|
||||
s->cmd = CMD_NONE;
|
||||
s->port = 0;
|
||||
|
||||
@ -1042,16 +1076,16 @@ void
|
||||
server_read(struct bufferevent *bufev, void *arg)
|
||||
{
|
||||
struct session *s = arg;
|
||||
size_t buf_avail, read;
|
||||
size_t buf_avail, srvread;
|
||||
int n;
|
||||
|
||||
bufferevent_settimeout(bufev, timeout, 0);
|
||||
|
||||
do {
|
||||
buf_avail = sizeof s->sbuf - s->sbuf_valid;
|
||||
read = bufferevent_read(bufev, s->sbuf + s->sbuf_valid,
|
||||
srvread = bufferevent_read(bufev, s->sbuf + s->sbuf_valid,
|
||||
buf_avail);
|
||||
s->sbuf_valid += read;
|
||||
s->sbuf_valid += srvread;
|
||||
|
||||
while ((n = getline(s->sbuf, &s->sbuf_valid)) > 0) {
|
||||
logmsg(LOG_DEBUG, "#%d server: %s", s->id, linebuf);
|
||||
@ -1068,7 +1102,7 @@ server_read(struct bufferevent *bufev, void *arg)
|
||||
end_session(s);
|
||||
return;
|
||||
}
|
||||
} while (read == buf_avail);
|
||||
} while (srvread == buf_avail);
|
||||
}
|
||||
|
||||
const char *
|
||||
@ -1102,6 +1136,7 @@ usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [-6Adrv] [-a address] [-b address]"
|
||||
" [-D level] [-m maxsessions]\n [-P port]"
|
||||
" [-p port] [-q queue] [-R address] [-t timeout]\n", __progname);
|
||||
" [-p port] [-q queue] [-R address] [-T tag]\n"
|
||||
" [-t timeout]\n", __progname);
|
||||
exit(1);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $OpenBSD: pf.4,v 1.58 2007/02/09 11:39:06 henning Exp $
|
||||
.\" $OpenBSD: pf.4,v 1.62 2008/09/10 14:57:37 jmc Exp $
|
||||
.\"
|
||||
.\" Copyright (C) 2001, Kjell Wooding. All rights reserved.
|
||||
.\"
|
||||
@ -28,7 +28,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd February 7, 2005
|
||||
.Dd September 10 2008
|
||||
.Dt PF 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -294,14 +294,17 @@ if another process is concurrently updating a ruleset.
|
||||
Add a state entry.
|
||||
.Bd -literal
|
||||
struct pfioc_state {
|
||||
u_int32_t nr;
|
||||
struct pf_state state;
|
||||
struct pfsync_state state;
|
||||
};
|
||||
.Ed
|
||||
.It Dv DIOCGETSTATE Fa "struct pfioc_state *ps"
|
||||
Extract the entry with the specified number
|
||||
.Va nr
|
||||
from the state table.
|
||||
Extract the entry identified by the
|
||||
.Va id
|
||||
and
|
||||
.Va creatorid
|
||||
fields of the
|
||||
.Va state
|
||||
structure from the state table.
|
||||
.It Dv DIOCKILLSTATES Fa "struct pfioc_state_kill *psk"
|
||||
Remove matching entries from the state table.
|
||||
This ioctl returns the number of killed states in
|
||||
@ -1049,12 +1052,14 @@ internal interface description.
|
||||
The filtering process is the same as for
|
||||
.Dv DIOCIGETIFACES .
|
||||
.Bd -literal
|
||||
#define PFI_IFLAG_SKIP 0x0100 /* skip filtering on interface */
|
||||
#define PFI_IFLAG_SKIP 0x0100 /* skip filtering on interface */
|
||||
.Ed
|
||||
.It Dv DIOCCLRIFFLAG Fa "struct pfioc_iface *io"
|
||||
Works as
|
||||
.Dv DIOCSETIFFLAG
|
||||
above but clears the flags.
|
||||
.It Dv DIOCKILLSRCNODES Fa "struct pfioc_iface *io"
|
||||
Explicitly remove source tracking nodes.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width /dev/pf -compact
|
||||
@ -1133,6 +1138,7 @@ main(int argc, char *argv[])
|
||||
.Xr altq 4 ,
|
||||
.Xr if_bridge 4 ,
|
||||
.Xr pflog 4 ,
|
||||
.Xr pflow 4 ,
|
||||
.Xr pfsync 4 ,
|
||||
.Xr pfctl 8 ,
|
||||
.Xr altq 9
|
||||
|
@ -1,5 +1,5 @@
|
||||
.\" $FreeBSD$
|
||||
.\" $OpenBSD: pf.conf.5,v 1.393 2008/02/11 07:46:32 jmc Exp $
|
||||
.\" $FreeBSD$
|
||||
.\" $OpenBSD: pf.conf.5,v 1.406 2009/01/31 19:37:12 sobrado Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2002, Daniel Hartmeier
|
||||
.\" All rights reserved.
|
||||
@ -28,7 +28,7 @@
|
||||
.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
.\" POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd June 10, 2008
|
||||
.Dd January 31 2009
|
||||
.Dt PF.CONF 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -79,6 +79,17 @@ By default
|
||||
enforces this order (see
|
||||
.Ar set require-order
|
||||
below).
|
||||
.Pp
|
||||
Comments can be put anywhere in the file using a hash mark
|
||||
.Pq Sq # ,
|
||||
and extend to the end of the current line.
|
||||
.Pp
|
||||
Additional configuration files can be included with the
|
||||
.Ic include
|
||||
keyword, for example:
|
||||
.Bd -literal -offset indent
|
||||
include "/etc/pf/sub.filter.conf"
|
||||
.Ed
|
||||
.Sh MACROS
|
||||
Macros can be defined that will later be expanded in context.
|
||||
Macro names must start with a letter, and may contain letters, digits
|
||||
@ -154,7 +165,7 @@ A table initialized with the empty list,
|
||||
will be cleared on load.
|
||||
.El
|
||||
.Pp
|
||||
Tables may be defined with the following two attributes:
|
||||
Tables may be defined with the following attributes:
|
||||
.Bl -tag -width persist
|
||||
.It Ar persist
|
||||
The
|
||||
@ -173,6 +184,11 @@ can be used to add or remove addresses from the table at any time, even
|
||||
when running with
|
||||
.Xr securelevel 7
|
||||
= 2.
|
||||
.It Ar counters
|
||||
The
|
||||
.Ar counters
|
||||
flag enables per-address packet and byte counters which can be displayed with
|
||||
.Xr pfctl 8 .
|
||||
.El
|
||||
.Pp
|
||||
For example,
|
||||
@ -328,7 +344,8 @@ With 9000 state table entries, the timeout values are scaled to 50%
|
||||
(tcp.first 60, tcp.established 43200).
|
||||
.Pp
|
||||
.It Ar set loginterface
|
||||
Enable collection of packet and byte count statistics for the given interface.
|
||||
Enable collection of packet and byte count statistics for the given
|
||||
interface or interface group.
|
||||
These statistics can be viewed using
|
||||
.Bd -literal -offset indent
|
||||
# pfctl -s info
|
||||
@ -403,9 +420,10 @@ set limit { states 20000, frags 20000, src-nodes 2000 }
|
||||
.Bl -tag -width xxxxxxxx -compact
|
||||
.It Ar none
|
||||
Disable the ruleset optimizer.
|
||||
This is the default behaviour.
|
||||
.It Ar basic
|
||||
Enable basic ruleset optimization, which does four things to improve the
|
||||
Enable basic ruleset optimization.
|
||||
This is the default behaviour.
|
||||
Basic ruleset optimization does four things to improve the
|
||||
performance of ruleset evaluations:
|
||||
.Pp
|
||||
.Bl -enum -compact
|
||||
@ -500,6 +518,16 @@ For example:
|
||||
.Bd -literal -offset indent
|
||||
set state-policy if-bound
|
||||
.Ed
|
||||
.It Ar set state-defaults
|
||||
The
|
||||
.Ar state-defaults
|
||||
option sets the state options for states created from rules
|
||||
without an explicit
|
||||
.Ar keep state .
|
||||
For example:
|
||||
.Bd -literal -offset indent
|
||||
set state-defaults pflow, no-sync
|
||||
.Ed
|
||||
.It Ar set hostid
|
||||
The 32-bit
|
||||
.Ar hostid
|
||||
@ -617,6 +645,19 @@ modifier to ensure unique IP identifiers.
|
||||
Enforces a minimum TTL for matching IP packets.
|
||||
.It Ar max-mss Aq Ar number
|
||||
Enforces a maximum MSS for matching TCP packets.
|
||||
.It Xo Ar set-tos Aq Ar string
|
||||
.No \*(Ba Aq Ar number
|
||||
.Xc
|
||||
Enforces a
|
||||
.Em TOS
|
||||
for matching IP packets.
|
||||
.Em TOS
|
||||
may be
|
||||
given as one of
|
||||
.Ar lowdelay ,
|
||||
.Ar throughput ,
|
||||
.Ar reliability ,
|
||||
or as either hex or decimal.
|
||||
.It Ar random-id
|
||||
Replaces the IP identification field with random values to compensate
|
||||
for predictable values generated by many hosts.
|
||||
@ -725,7 +766,7 @@ much in the same way as
|
||||
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/ALTQ
|
||||
.Sh QUEUEING
|
||||
The ALTQ system is currently not available in the GENERIC kernel nor as
|
||||
loadable modules.
|
||||
In order to use the herein after called queueing options one has to use a
|
||||
@ -816,7 +857,7 @@ assigned.
|
||||
.Ar Priority
|
||||
mainly controls the time packets take to get sent out, while
|
||||
.Ar bandwidth
|
||||
has primarily effects on throughput.
|
||||
primarily affects throughput.
|
||||
.Ar hfsc
|
||||
supports both link-sharing and guaranteed real-time services.
|
||||
It employs a service curve based QoS model,
|
||||
@ -879,7 +920,7 @@ Defines a list of subqueues to create on an interface.
|
||||
.El
|
||||
.Pp
|
||||
In the following example, the interface dc0
|
||||
should queue up to 5 Mbit/s in four second-level queues using
|
||||
should queue up to 5Mbps in four second-level queues using
|
||||
Class Based Queueing.
|
||||
Those four queues will be shown in a later example.
|
||||
.Bd -literal -offset indent
|
||||
@ -1171,7 +1212,7 @@ or to the firewall itself.
|
||||
Note that redirecting external incoming connections to the loopback
|
||||
address, as in
|
||||
.Bd -literal -offset indent
|
||||
rdr on ne3 inet proto tcp to port spamd -\*(Gt 127.0.0.1 port smtp
|
||||
rdr on ne3 inet proto tcp to port smtp -\*(Gt 127.0.0.1 port spamd
|
||||
.Ed
|
||||
.Pp
|
||||
will effectively allow an external host to connect to daemons
|
||||
@ -1256,7 +1297,7 @@ block all
|
||||
.Ed
|
||||
.It Ar pass
|
||||
The packet is passed;
|
||||
state is created state unless the
|
||||
state is created unless the
|
||||
.Ar no state
|
||||
option is specified.
|
||||
.El
|
||||
@ -1432,7 +1473,8 @@ This rule applies only to packets with the specified source and destination
|
||||
addresses and ports.
|
||||
.Pp
|
||||
Addresses can be specified in CIDR notation (matching netblocks), as
|
||||
symbolic host names or interface names, or as any of the following keywords:
|
||||
symbolic host names, interface names or interface group names, or as any
|
||||
of the following keywords:
|
||||
.Pp
|
||||
.Bl -tag -width xxxxxxxxxxxxxx -compact
|
||||
.It Ar any
|
||||
@ -1454,7 +1496,15 @@ the route back to the packet's source address.
|
||||
Any address that matches the given table.
|
||||
.El
|
||||
.Pp
|
||||
Interface names can have modifiers appended:
|
||||
Ranges of addresses are specified by using the
|
||||
.Sq -
|
||||
operator.
|
||||
For instance:
|
||||
.Dq 10.1.1.10 - 10.1.1.12
|
||||
means all addresses from 10.1.1.10 to 10.1.1.12,
|
||||
hence addresses 10.1.1.10, 10.1.1.11, and 10.1.1.12.
|
||||
.Pp
|
||||
Interface names and interface group names can have modifiers appended:
|
||||
.Pp
|
||||
.Bl -tag -width xxxxxxxxxxxx -compact
|
||||
.It Ar :network
|
||||
@ -1462,7 +1512,7 @@ Translates to the network(s) attached to the interface.
|
||||
.It Ar :broadcast
|
||||
Translates to the interface's broadcast address(es).
|
||||
.It Ar :peer
|
||||
Translates to the point to point interface's peer address(es).
|
||||
Translates to the point-to-point interface's peer address(es).
|
||||
.It Ar :0
|
||||
Do not include interface aliases.
|
||||
.El
|
||||
@ -1552,17 +1602,6 @@ This is equivalent to "from any to any".
|
||||
Similar to
|
||||
.Ar user ,
|
||||
this rule only applies to packets of sockets owned by the specified group.
|
||||
.Pp
|
||||
The use of
|
||||
.Ar group
|
||||
or
|
||||
.Ar user
|
||||
in
|
||||
.Va debug.mpsafenet Ns = Ns 1
|
||||
environments may result in a deadlock.
|
||||
Please see the
|
||||
.Sx BUGS
|
||||
section for details.
|
||||
.It Ar user Aq Ar user
|
||||
This rule only applies to packets of sockets owned by the specified user.
|
||||
For outgoing connections initiated from the firewall, this is the user
|
||||
@ -1628,7 +1667,7 @@ Flags not specified in
|
||||
are ignored.
|
||||
For stateful connections, the default is
|
||||
.Ar flags S/SA .
|
||||
To indicate that flags should not be checkd at all, specify
|
||||
To indicate that flags should not be checked at all, specify
|
||||
.Ar flags any .
|
||||
The flags are: (F)IN, (S)YN, (R)ST, (P)USH, (A)CK, (U)RG, (E)CE, and C(W)R.
|
||||
.Bl -tag -width Fl
|
||||
@ -1780,7 +1819,7 @@ of
|
||||
.Em lowdelay
|
||||
and TCP ACKs with no data payload will be assigned to the second one.
|
||||
See
|
||||
.Sx QUEUEING/ALTQ
|
||||
.Sx QUEUEING
|
||||
for setup details.
|
||||
.Pp
|
||||
For example:
|
||||
@ -1811,7 +1850,8 @@ or
|
||||
rules in addition to filter rules.
|
||||
Tags take the same macros as labels (see above).
|
||||
.It Ar tagged Aq Ar string
|
||||
Used with filter or translation rules to specify that packets must already
|
||||
Used with filter, translation or scrub 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
|
||||
@ -1822,6 +1862,22 @@ keyword.
|
||||
.It Ar rtable Aq Ar number
|
||||
Used to select an alternate routing table for the routing lookup.
|
||||
Only effective before the route lookup happened, i.e. when filtering inbound.
|
||||
.It Xo Ar divert-to Aq Ar host
|
||||
.Ar port Aq Ar port
|
||||
.Xc
|
||||
Used to redirect packets to a local socket bound to
|
||||
.Ar host
|
||||
and
|
||||
.Ar port .
|
||||
The packets will not be modified, so
|
||||
.Xr getsockname 2
|
||||
on the socket will return the original destination address of the packet.
|
||||
.It Ar divert-reply
|
||||
Used to receive replies for sockets that are bound to addresses
|
||||
which are not local to the machine.
|
||||
See
|
||||
.Xr setsockopt 2
|
||||
for information on how to bind these sockets.
|
||||
.It Ar probability Aq Ar number
|
||||
A probability attribute can be attached to a rule, with a value set between
|
||||
0 and 1, bounds not included.
|
||||
@ -1940,7 +1996,7 @@ pool options.
|
||||
Note that by default these associations are destroyed as soon as there are
|
||||
no longer states which refer to them; in order to make the mappings last
|
||||
beyond the lifetime of the states, increase the global options with
|
||||
.Ar set timeout source-track
|
||||
.Ar set timeout src.track .
|
||||
See
|
||||
.Sx STATEFUL TRACKING OPTIONS
|
||||
for more ways to control the source tracking.
|
||||
@ -2026,7 +2082,7 @@ Rules with
|
||||
will not work if
|
||||
.Xr pf 4
|
||||
operates on a
|
||||
.Xr if_bridge 4 .
|
||||
.Xr bridge 4 .
|
||||
.Pp
|
||||
Example:
|
||||
.Bd -literal -offset indent
|
||||
@ -2046,8 +2102,8 @@ must be specified explicitly to apply options to a rule.
|
||||
.Bl -tag -width xxxx -compact
|
||||
.It Ar max Aq Ar number
|
||||
Limits the number of concurrent states the rule may create.
|
||||
When this limit is reached, further packets matching the rule that would
|
||||
create state are dropped, until existing states time out.
|
||||
When this limit is reached, further packets that would create
|
||||
state will not match this rule until existing states time out.
|
||||
.It Ar no-sync
|
||||
Prevent state changes for states created by this rule from appearing on the
|
||||
.Xr pfsync 4
|
||||
@ -2064,8 +2120,12 @@ Uses a sloppy TCP connection tracker that does not check sequence
|
||||
numbers at all, which makes insertion and ICMP teardown attacks way
|
||||
easier.
|
||||
This is intended to be used in situations where one does not see all
|
||||
packets of a connection, i.e. in asymmetric routing situations.
|
||||
packets of a connection, e.g. in asymmetric routing situations.
|
||||
Cannot be used with modulate or synproxy state.
|
||||
.It Ar pflow
|
||||
States created by this rule are exported on the
|
||||
.Xr pflow 4
|
||||
interface.
|
||||
.El
|
||||
.Pp
|
||||
Multiple options can be specified, separated by commas:
|
||||
@ -2472,10 +2532,8 @@ into the anchor.
|
||||
.Pp
|
||||
Optionally,
|
||||
.Ar anchor
|
||||
rules can specify the parameter's
|
||||
direction, interface, address family, protocol and source/destination
|
||||
address/port
|
||||
using the same syntax as filter rules.
|
||||
rules can specify packet filtering parameters using the same syntax as
|
||||
filter rules.
|
||||
When parameters are used, the
|
||||
.Ar anchor
|
||||
rule is only evaluated for matching packets.
|
||||
@ -2779,10 +2837,11 @@ in BNF:
|
||||
.Bd -literal
|
||||
line = ( option | pf-rule | nat-rule | binat-rule | rdr-rule |
|
||||
antispoof-rule | altq-rule | queue-rule | trans-anchors |
|
||||
anchor-rule | anchor-close | load-anchor | table-rule | )
|
||||
anchor-rule | anchor-close | load-anchor | table-rule |
|
||||
include )
|
||||
|
||||
option = "set" ( [ "timeout" ( timeout | "{" timeout-list "}" ) ] |
|
||||
[ "ruleset-optimization" [ "none" | "basic" | "profile" ]] |
|
||||
[ "ruleset-optimization" [ "none" | "basic" | "profile" ]] |
|
||||
[ "optimization" [ "default" | "normal" |
|
||||
"high-latency" | "satellite" |
|
||||
"aggressive" | "conservative" ] ]
|
||||
@ -2790,9 +2849,10 @@ option = "set" ( [ "timeout" ( timeout | "{" timeout-list "}" ) ] |
|
||||
[ "loginterface" ( interface-name | "none" ) ] |
|
||||
[ "block-policy" ( "drop" | "return" ) ] |
|
||||
[ "state-policy" ( "if-bound" | "floating" ) ]
|
||||
[ "state-defaults" state-opts ]
|
||||
[ "require-order" ( "yes" | "no" ) ]
|
||||
[ "fingerprints" filename ] |
|
||||
[ "skip on" ( interface-name | "{" interface-list "}" ) ] |
|
||||
[ "skip on" ifspec ] |
|
||||
[ "debug" ( "none" | "urgent" | "misc" | "loud" ) ] )
|
||||
|
||||
pf-rule = action [ ( "in" | "out" ) ]
|
||||
@ -2804,10 +2864,10 @@ logopts = logopt [ "," logopts ]
|
||||
logopt = "all" | "user" | "to" interface-name
|
||||
|
||||
filteropt-list = filteropt-list filteropt | filteropt
|
||||
filteropt = user | group | flags | icmp-type | icmp6-type | tos |
|
||||
filteropt = user | group | flags | icmp-type | icmp6-type | "tos" tos |
|
||||
( "no" | "keep" | "modulate" | "synproxy" ) "state"
|
||||
[ "(" state-opts ")" ] |
|
||||
"fragment" | "no-df" | "min-ttl" number |
|
||||
"fragment" | "no-df" | "min-ttl" number | "set-tos" tos |
|
||||
"max-mss" number | "random-id" | "reassemble tcp" |
|
||||
fragmentation | "allow-opts" |
|
||||
"label" string | "tag" string | [ ! ] "tagged" string |
|
||||
@ -2834,17 +2894,16 @@ rdr-rule = [ "no" ] "rdr" [ "pass" [ "log" [ "(" logopts ")" ] ] ]
|
||||
[ portspec ] [ pooltype ] ]
|
||||
|
||||
antispoof-rule = "antispoof" [ "log" ] [ "quick" ]
|
||||
"for" ( interface-name | "{" interface-list "}" )
|
||||
[ af ] [ "label" string ]
|
||||
"for" ifspec [ af ] [ "label" string ]
|
||||
|
||||
table-rule = "table" "\*(Lt" string "\*(Gt" [ tableopts-list ]
|
||||
tableopts-list = tableopts-list tableopts | tableopts
|
||||
tableopts = "persist" | "const" | "file" string |
|
||||
tableopts = "persist" | "const" | "counters" | "file" string |
|
||||
"{" [ tableaddr-list ] "}"
|
||||
tableaddr-list = tableaddr-list [ "," ] tableaddr-spec | tableaddr-spec
|
||||
tableaddr-spec = [ "!" ] tableaddr [ "/" mask-bits ]
|
||||
tableaddr = hostname | ipv4-dotted-quad | ipv6-coloned-hex |
|
||||
interface-name | "self"
|
||||
tableaddr = hostname | ifspec | "self" |
|
||||
ipv4-dotted-quad | ipv6-coloned-hex
|
||||
|
||||
altq-rule = "altq on" interface-name queueopts-list
|
||||
"queue" subqueue
|
||||
@ -2852,7 +2911,7 @@ queue-rule = "queue" string [ "on" interface-name ] queueopts-list
|
||||
subqueue
|
||||
|
||||
anchor-rule = "anchor" [ string ] [ ( "in" | "out" ) ] [ "on" ifspec ]
|
||||
[ af ] [ protospec ] [ hosts ] [ "{" ]
|
||||
[ af ] [ protospec ] [ hosts ] [ filteropt-list ] [ "{" ]
|
||||
|
||||
anchor-close = "}"
|
||||
|
||||
@ -2875,8 +2934,10 @@ return = "drop" | "return" | "return-rst" [ "( ttl" number ")" ] |
|
||||
icmpcode = ( icmp-code-name | icmp-code-number )
|
||||
icmp6code = ( icmp6-code-name | icmp6-code-number )
|
||||
|
||||
ifspec = ( [ "!" ] interface-name ) | "{" interface-list "}"
|
||||
interface-list = [ "!" ] interface-name [ [ "," ] interface-list ]
|
||||
ifspec = ( [ "!" ] ( interface-name | interface-group ) ) |
|
||||
"{" interface-list "}"
|
||||
interface-list = [ "!" ] ( interface-name | interface-group )
|
||||
[ [ "," ] interface-list ]
|
||||
route = ( "route-to" | "reply-to" | "dup-to" )
|
||||
( routehost | "{" routehost-list "}" )
|
||||
[ pooltype ]
|
||||
@ -2896,8 +2957,9 @@ ipspec = "any" | host | "{" host-list "}"
|
||||
host = [ "!" ] ( address [ "/" mask-bits ] | "\*(Lt" string "\*(Gt" )
|
||||
redirhost = address [ "/" mask-bits ]
|
||||
routehost = "(" interface-name [ address [ "/" mask-bits ] ] ")"
|
||||
address = ( interface-name | "(" interface-name ")" | hostname |
|
||||
ipv4-dotted-quad | ipv6-coloned-hex )
|
||||
address = ( interface-name | interface-group |
|
||||
"(" ( interface-name | interface-group ) ")" |
|
||||
hostname | ipv4-dotted-quad | ipv6-coloned-hex )
|
||||
host-list = host [ [ "," ] host-list ]
|
||||
redirhost-list = redirhost [ [ "," ] redirhost-list ]
|
||||
routehost-list = routehost [ [ "," ] routehost-list ]
|
||||
@ -2926,11 +2988,11 @@ icmp-type-code = ( icmp-type-name | icmp-type-number )
|
||||
[ "code" ( icmp-code-name | icmp-code-number ) ]
|
||||
icmp-list = icmp-type-code [ [ "," ] icmp-list ]
|
||||
|
||||
tos = "tos" ( "lowdelay" | "throughput" | "reliability" |
|
||||
tos = ( "lowdelay" | "throughput" | "reliability" |
|
||||
[ "0x" ] number )
|
||||
|
||||
state-opts = state-opt [ [ "," ] state-opts ]
|
||||
state-opt = ( "max" number | "no-sync" | timeout | sloppy |
|
||||
state-opt = ( "max" number | "no-sync" | timeout | "sloppy" | "pflow" |
|
||||
"source-track" [ ( "rule" | "global" ) ] |
|
||||
"max-src-nodes" number | "max-src-states" number |
|
||||
"max-src-conn" number |
|
||||
@ -2971,9 +3033,10 @@ realtime-sc = "realtime" sc-spec
|
||||
upperlimit-sc = "upperlimit" sc-spec
|
||||
sc-spec = ( bandwidth-spec |
|
||||
"(" bandwidth-spec number bandwidth-spec ")" )
|
||||
include = "include" filename
|
||||
.Ed
|
||||
.Sh FILES
|
||||
.Bl -tag -width "/usr/share/examples/pf" -compact
|
||||
.Bl -tag -width "/etc/protocols" -compact
|
||||
.It Pa /etc/hosts
|
||||
Host name database.
|
||||
.It Pa /etc/pf.conf
|
||||
@ -2984,8 +3047,6 @@ Default location of OS fingerprints.
|
||||
Protocol name database.
|
||||
.It Pa /etc/services
|
||||
Service name database.
|
||||
.It Pa /usr/share/examples/pf
|
||||
Example rulesets.
|
||||
.El
|
||||
.Sh BUGS
|
||||
Due to a lock order reversal (LOR) with the socket layer, the use of the
|
||||
@ -3017,6 +3078,7 @@ Rules with a route label do not match any traffic.
|
||||
.Xr ip 4 ,
|
||||
.Xr ip6 4 ,
|
||||
.Xr pf 4 ,
|
||||
.Xr pflow 4 ,
|
||||
.Xr pfsync 4 ,
|
||||
.Xr route 4 ,
|
||||
.Xr tcp 4 ,
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $OpenBSD: pf.os.5,v 1.7 2005/11/16 20:07:18 stevesk Exp $
|
||||
.\" $OpenBSD: pf.os.5,v 1.8 2007/05/31 19:19:58 jmc Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2003 Mike Frantzen <frantzen@w4g.org>
|
||||
.\"
|
||||
@ -16,7 +16,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd August 18, 2003
|
||||
.Dd May 31 2007
|
||||
.Dt PF.OS 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -217,7 +217,7 @@ almost translates into the following fingerprint
|
||||
57344:64:1:44:M1460: exampleOS:1.0::exampleOS 1.0
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr tcpdump 1 ,
|
||||
.Xr pf 4 ,
|
||||
.Xr pf.conf 5 ,
|
||||
.Xr pfctl 8
|
||||
.Xr pfctl 8 ,
|
||||
.Xr tcpdump 1
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $OpenBSD: pflog.4,v 1.9 2006/10/25 12:51:31 jmc Exp $
|
||||
.\" $OpenBSD: pflog.4,v 1.10 2007/05/31 19:19:51 jmc Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2001 Tobias Weingartner
|
||||
.\" All rights reserved.
|
||||
@ -25,7 +25,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd December 10, 2001
|
||||
.Dd May 31 2007
|
||||
.Dt PFLOG 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -36,7 +36,7 @@
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm pflog
|
||||
interface is a pseudo-device which makes visible all packets logged by
|
||||
interface is a device which makes visible all packets logged by
|
||||
the packet filter,
|
||||
.Xr pf 4 .
|
||||
Logged packets can easily be monitored in real
|
||||
@ -91,13 +91,13 @@ and monitor all packets logged on it:
|
||||
# tcpdump -n -e -ttt -i pflog1
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr tcpdump 1
|
||||
.Xr inet 4 ,
|
||||
.Xr inet6 4 ,
|
||||
.Xr netintro 4 ,
|
||||
.Xr pf 4 ,
|
||||
.Xr ifconfig 8 ,
|
||||
.Xr pflogd 8
|
||||
.Xr pflogd 8 ,
|
||||
.Xr tcpdump 1
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $OpenBSD: pfsync.4,v 1.24 2006/10/23 07:05:49 jmc Exp $
|
||||
.\" $OpenBSD: pfsync.4,v 1.28 2009/02/17 10:05:18 dlg Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2002 Michael Shalayeff
|
||||
.\" Copyright (c) 2003-2004 Ryan McBride
|
||||
@ -26,12 +26,12 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd June 6, 2006
|
||||
.Dd February 17 2009
|
||||
.Dt PFSYNC 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm pfsync
|
||||
.Nd packet filter state table logging interface
|
||||
.Nd packet filter state table sychronisation interface
|
||||
.Sh SYNOPSIS
|
||||
.Cd "device pfsync"
|
||||
.Sh DESCRIPTION
|
||||
@ -40,26 +40,25 @@ The
|
||||
interface is a pseudo-device which exposes certain changes to the state
|
||||
table used by
|
||||
.Xr pf 4 .
|
||||
.\" XXX: not yet!
|
||||
.\" State changes can be viewed by invoking
|
||||
.\" .Xr tcpdump 1
|
||||
.\" on the
|
||||
.\" .Nm
|
||||
.\" interface.
|
||||
State changes can be viewed by invoking
|
||||
.Xr tcpdump 1
|
||||
on the
|
||||
.Nm
|
||||
interface.
|
||||
If configured with a physical synchronisation interface,
|
||||
.Nm
|
||||
will send state changes out on that interface using IP multicast,
|
||||
will also send state changes out on that interface,
|
||||
and insert state changes received on that interface from other systems
|
||||
into the state table.
|
||||
.Pp
|
||||
By default, all local changes to the state table are exposed via
|
||||
.Nm .
|
||||
However, state changes from packets received by
|
||||
State changes from packets received by
|
||||
.Nm
|
||||
over the network are not rebroadcast.
|
||||
States created by a rule marked with the
|
||||
Updates to states created by a rule marked with the
|
||||
.Ar no-sync
|
||||
keyword are omitted from the
|
||||
keyword are ignored by the
|
||||
.Nm
|
||||
interface (see
|
||||
.Xr pf.conf 5
|
||||
@ -67,33 +66,19 @@ for details).
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
interface will attempt to collapse multiple updates of the same
|
||||
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
|
||||
interface will attempt to collapse multiple state updates into a single
|
||||
packet where possible.
|
||||
The maximum number of times a single state can be updated before a
|
||||
.Nm
|
||||
packet will be sent out is controlled by the
|
||||
.Ar maxupd
|
||||
parameter to ifconfig
|
||||
(see
|
||||
.Xr ifconfig 8
|
||||
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
|
||||
table entries attached in this packet.
|
||||
This structure is defined in
|
||||
.Aq Pa net/if_pfsync.h
|
||||
as:
|
||||
.Bd -literal -offset indent
|
||||
struct pfsync_header {
|
||||
u_int8_t version;
|
||||
u_int8_t af;
|
||||
u_int8_t action;
|
||||
u_int8_t count;
|
||||
};
|
||||
.Ed
|
||||
The sending out of a
|
||||
.Nm
|
||||
packet will be delayed by a maximum of one second.
|
||||
.Sh NETWORK SYNCHRONISATION
|
||||
States can be synchronised between two or more firewalls using this
|
||||
interface, by specifying a synchronisation interface using
|
||||
@ -104,18 +89,16 @@ interface:
|
||||
# ifconfig pfsync0 syncdev fxp0
|
||||
.Ed
|
||||
.Pp
|
||||
It is important that the underlying synchronisation interface is up
|
||||
and has an IP address assigned.
|
||||
.Pp
|
||||
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
|
||||
interface using IP multicast packets to the 244.0.0.240 group address.
|
||||
An alternative destination address for
|
||||
.Nm
|
||||
packets can be 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 .
|
||||
keyword.
|
||||
This can be used in combination with
|
||||
.Xr ipsec 4
|
||||
to protect the synchronisation traffic.
|
||||
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,
|
||||
@ -127,50 +110,19 @@ e.g.:
|
||||
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.
|
||||
Either run the pfsync protocol on a trusted network \- ideally a network
|
||||
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
|
||||
For
|
||||
.Nm
|
||||
to start its operation automatically at the system boot time,
|
||||
.Va pfsync_enable
|
||||
and
|
||||
.Va pfsync_syncdev
|
||||
variables should be used in
|
||||
.Xr rc.conf 5 .
|
||||
It is not advisable to set up
|
||||
.Nm
|
||||
with common network interface configuration variables of
|
||||
.Xr rc.conf 5
|
||||
because
|
||||
.Nm
|
||||
must start after its
|
||||
.Cm syncdev ,
|
||||
which cannot be always ensured in the latter case.
|
||||
.\" XXX: not yet!
|
||||
.\" .Pp
|
||||
.\" There is a one-to-one correspondence between packets seen by
|
||||
.\" .Xr bpf 4
|
||||
.\" on the
|
||||
.\" .Nm
|
||||
.\" interface, and packets sent out on the synchronisation interface, i.e.\&
|
||||
.\" a packet with 4 state deletion messages on
|
||||
.\" .Nm
|
||||
.\" means that the same 4 deletions were sent out on the synchronisation
|
||||
.\" interface.
|
||||
.\" However, the actual packet contents may differ as the messages
|
||||
.\" sent over the network are "compressed" where possible, containing
|
||||
.\" only the necessary information.
|
||||
.Sh EXAMPLES
|
||||
.Nm
|
||||
and
|
||||
.Xr carp 4
|
||||
can be used together to provide automatic failover of a pair of firewalls
|
||||
configured in parallel.
|
||||
One firewall handles all traffic \- if it dies or
|
||||
is shut down, the second firewall takes over automatically.
|
||||
One firewall will handle all traffic until it dies, is shut down, or is
|
||||
manually demoted, at which point the second firewall will take over
|
||||
automatically.
|
||||
.Pp
|
||||
Both firewalls in this example have three
|
||||
.Xr sis 4
|
||||
@ -208,12 +160,12 @@ traffic through.
|
||||
The following should be added to the top of
|
||||
.Pa /etc/pf.conf :
|
||||
.Bd -literal -offset indent
|
||||
pass quick on { sis2 } proto pfsync
|
||||
pass on { sis0 sis1 } proto carp
|
||||
pass quick on { sis2 } proto pfsync keep state (no-sync)
|
||||
pass on { sis0 sis1 } proto carp keep state (no-sync)
|
||||
.Ed
|
||||
.Pp
|
||||
If it is preferable that one firewall handle the traffic,
|
||||
the
|
||||
It is preferable that one firewall handle the forwarding of all the traffic,
|
||||
therefore the
|
||||
.Ar advskew
|
||||
on the backup firewall's
|
||||
.Xr carp 4
|
||||
@ -221,6 +173,7 @@ interfaces should be set to something higher than
|
||||
the primary's.
|
||||
For example, if firewall B is the backup, its
|
||||
carp1 configuration would look like this:
|
||||
would look like this:
|
||||
.Bd -literal -offset indent
|
||||
ifconfig_carp1="vhid 2 pass bar advskew 100 192.168.0.1/24"
|
||||
.Ed
|
||||
@ -230,16 +183,10 @@ The following must also be added to
|
||||
.Bd -literal -offset indent
|
||||
net.inet.carp.preempt=1
|
||||
.Ed
|
||||
.Sh BUGS
|
||||
Possibility to view state changes using
|
||||
.Xr tcpdump 1
|
||||
has not been ported from
|
||||
.Ox
|
||||
yet.
|
||||
.Sh SEE ALSO
|
||||
.Xr bpf 4 ,
|
||||
.Xr carp 4 ,
|
||||
.Xr ifconfig 8 ,
|
||||
.Xr enc 4 ,
|
||||
.Xr inet 4 ,
|
||||
.Xr inet6 4 ,
|
||||
.Xr ipsec 4 ,
|
||||
@ -247,16 +194,20 @@ yet.
|
||||
.Xr pf 4 ,
|
||||
.Xr pf.conf 5 ,
|
||||
.Xr protocols 5 ,
|
||||
.Xr rc.conf 5
|
||||
.Xr rc.conf 5 ,
|
||||
.Xr ifconfig 8 ,
|
||||
.Xr ifstated 8 ,
|
||||
.Xr tcpdump 8
|
||||
.Xr tcpdump 1
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
device first appeared in
|
||||
.Ox 3.3 .
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
device was imported to
|
||||
.Fx 5.3 .
|
||||
protocol and kernel implementation were significantly modified between
|
||||
.Ox 4.4
|
||||
and
|
||||
.Ox 4.5 .
|
||||
The two protocols are incompatible and will not interoperate.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: pf_print_state.c,v 1.44 2007/03/01 17:20:53 deraadt Exp $ */
|
||||
/* $OpenBSD: pf_print_state.c,v 1.52 2008/08/12 16:40:18 david Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Daniel Hartmeier
|
||||
@ -35,7 +35,10 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/endian.h>
|
||||
#define betoh64 be64toh
|
||||
#endif
|
||||
#include <net/if.h>
|
||||
#define TCPSTATES
|
||||
#include <netinet/tcp_fsm.h>
|
||||
@ -83,6 +86,19 @@ print_addr(struct pf_addr_wrap *addr, sa_family_t af, int verbose)
|
||||
else
|
||||
printf("<%s>", addr->v.tblname);
|
||||
return;
|
||||
case PF_ADDR_RANGE: {
|
||||
char buf[48];
|
||||
|
||||
if (inet_ntop(af, &addr->v.a.addr, buf, sizeof(buf)) == NULL)
|
||||
printf("?");
|
||||
else
|
||||
printf("%s", buf);
|
||||
if (inet_ntop(af, &addr->v.a.mask, buf, sizeof(buf)) == NULL)
|
||||
printf(" - ?");
|
||||
else
|
||||
printf(" - %s", buf);
|
||||
break;
|
||||
}
|
||||
case PF_ADDR_ADDRMASK:
|
||||
if (PF_AZERO(&addr->v.a.addr, AF_INET6) &&
|
||||
PF_AZERO(&addr->v.a.mask, AF_INET6))
|
||||
@ -112,7 +128,8 @@ print_addr(struct pf_addr_wrap *addr, sa_family_t af, int verbose)
|
||||
}
|
||||
|
||||
/* mask if not _both_ address and mask are zero */
|
||||
if (!(PF_AZERO(&addr->v.a.addr, AF_INET6) &&
|
||||
if (addr->type != PF_ADDR_RANGE &&
|
||||
!(PF_AZERO(&addr->v.a.addr, AF_INET6) &&
|
||||
PF_AZERO(&addr->v.a.mask, AF_INET6))) {
|
||||
int bits = unmask(&addr->v.a.mask, af);
|
||||
|
||||
@ -155,17 +172,15 @@ print_name(struct pf_addr *addr, sa_family_t af)
|
||||
}
|
||||
|
||||
void
|
||||
print_host(struct pf_state_host *h, sa_family_t af, int opts)
|
||||
print_host(struct pf_addr *addr, u_int16_t port, sa_family_t af, int opts)
|
||||
{
|
||||
u_int16_t p = ntohs(h->port);
|
||||
|
||||
if (opts & PF_OPT_USEDNS)
|
||||
print_name(&h->addr, af);
|
||||
print_name(addr, af);
|
||||
else {
|
||||
struct pf_addr_wrap aw;
|
||||
|
||||
memset(&aw, 0, sizeof(aw));
|
||||
aw.v.a.addr = h->addr;
|
||||
aw.v.a.addr = *addr;
|
||||
if (af == AF_INET)
|
||||
aw.v.a.mask.addr32[0] = 0xffffffff;
|
||||
else {
|
||||
@ -175,57 +190,72 @@ print_host(struct pf_state_host *h, sa_family_t af, int opts)
|
||||
print_addr(&aw, af, opts & PF_OPT_VERBOSE2);
|
||||
}
|
||||
|
||||
if (p) {
|
||||
if (port) {
|
||||
if (af == AF_INET)
|
||||
printf(":%u", p);
|
||||
printf(":%u", ntohs(port));
|
||||
else
|
||||
printf("[%u]", p);
|
||||
printf("[%u]", ntohs(port));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
print_seq(struct pf_state_peer *p)
|
||||
print_seq(struct pfsync_state_peer *p)
|
||||
{
|
||||
if (p->seqdiff)
|
||||
printf("[%u + %u](+%u)", p->seqlo, p->seqhi - p->seqlo,
|
||||
p->seqdiff);
|
||||
printf("[%u + %u](+%u)", ntohl(p->seqlo),
|
||||
ntohl(p->seqhi) - ntohl(p->seqlo), ntohl(p->seqdiff));
|
||||
else
|
||||
printf("[%u + %u]", p->seqlo, p->seqhi - p->seqlo);
|
||||
printf("[%u + %u]", ntohl(p->seqlo),
|
||||
ntohl(p->seqhi) - ntohl(p->seqlo));
|
||||
}
|
||||
|
||||
void
|
||||
print_state(struct pf_state *s, int opts)
|
||||
print_state(struct pfsync_state *s, int opts)
|
||||
{
|
||||
struct pf_state_peer *src, *dst;
|
||||
struct pfsync_state_peer *src, *dst;
|
||||
struct pfsync_state_key *sk, *nk;
|
||||
struct protoent *p;
|
||||
int min, sec;
|
||||
|
||||
if (s->direction == PF_OUT) {
|
||||
src = &s->src;
|
||||
dst = &s->dst;
|
||||
sk = &s->key[PF_SK_STACK];
|
||||
nk = &s->key[PF_SK_WIRE];
|
||||
if (s->proto == IPPROTO_ICMP || s->proto == IPPROTO_ICMPV6)
|
||||
sk->port[0] = nk->port[0];
|
||||
} else {
|
||||
src = &s->dst;
|
||||
dst = &s->src;
|
||||
sk = &s->key[PF_SK_WIRE];
|
||||
nk = &s->key[PF_SK_STACK];
|
||||
if (s->proto == IPPROTO_ICMP || s->proto == IPPROTO_ICMPV6)
|
||||
sk->port[1] = nk->port[1];
|
||||
}
|
||||
printf("%s ", s->u.ifname);
|
||||
printf("%s ", s->ifname);
|
||||
if ((p = getprotobynumber(s->proto)) != NULL)
|
||||
printf("%s ", p->p_name);
|
||||
else
|
||||
printf("%u ", s->proto);
|
||||
if (PF_ANEQ(&s->lan.addr, &s->gwy.addr, s->af) ||
|
||||
(s->lan.port != s->gwy.port)) {
|
||||
print_host(&s->lan, s->af, opts);
|
||||
if (s->direction == PF_OUT)
|
||||
printf(" -> ");
|
||||
else
|
||||
printf(" <- ");
|
||||
|
||||
print_host(&nk->addr[1], nk->port[1], s->af, opts);
|
||||
if (PF_ANEQ(&nk->addr[1], &sk->addr[1], s->af) ||
|
||||
nk->port[1] != sk->port[1]) {
|
||||
printf(" (");
|
||||
print_host(&sk->addr[1], sk->port[1], s->af, opts);
|
||||
printf(")");
|
||||
}
|
||||
print_host(&s->gwy, s->af, opts);
|
||||
if (s->direction == PF_OUT)
|
||||
printf(" -> ");
|
||||
else
|
||||
printf(" <- ");
|
||||
print_host(&s->ext, s->af, opts);
|
||||
print_host(&nk->addr[0], nk->port[0], s->af, opts);
|
||||
if (PF_ANEQ(&nk->addr[0], &sk->addr[0], s->af) ||
|
||||
nk->port[0] != sk->port[0]) {
|
||||
printf(" (");
|
||||
print_host(&sk->addr[0], sk->port[0], s->af, opts);
|
||||
printf(")");
|
||||
}
|
||||
|
||||
printf(" ");
|
||||
if (s->proto == IPPROTO_TCP) {
|
||||
@ -271,45 +301,63 @@ print_state(struct pf_state *s, int opts)
|
||||
}
|
||||
|
||||
if (opts & PF_OPT_VERBOSE) {
|
||||
sec = s->creation % 60;
|
||||
s->creation /= 60;
|
||||
min = s->creation % 60;
|
||||
s->creation /= 60;
|
||||
printf(" age %.2u:%.2u:%.2u", s->creation, min, sec);
|
||||
sec = s->expire % 60;
|
||||
s->expire /= 60;
|
||||
min = s->expire % 60;
|
||||
s->expire /= 60;
|
||||
printf(", expires in %.2u:%.2u:%.2u", s->expire, min, sec);
|
||||
u_int64_t packets[2];
|
||||
u_int64_t bytes[2];
|
||||
u_int32_t creation = ntohl(s->creation);
|
||||
u_int32_t expire = ntohl(s->expire);
|
||||
|
||||
sec = creation % 60;
|
||||
creation /= 60;
|
||||
min = creation % 60;
|
||||
creation /= 60;
|
||||
printf(" age %.2u:%.2u:%.2u", creation, min, sec);
|
||||
sec = expire % 60;
|
||||
expire /= 60;
|
||||
min = expire % 60;
|
||||
expire /= 60;
|
||||
printf(", expires in %.2u:%.2u:%.2u", expire, min, sec);
|
||||
|
||||
bcopy(s->packets[0], &packets[0], sizeof(u_int64_t));
|
||||
bcopy(s->packets[1], &packets[1], sizeof(u_int64_t));
|
||||
bcopy(s->bytes[0], &bytes[0], sizeof(u_int64_t));
|
||||
bcopy(s->bytes[1], &bytes[1], sizeof(u_int64_t));
|
||||
printf(", %llu:%llu pkts, %llu:%llu bytes",
|
||||
#ifdef __FreeBSD__
|
||||
(unsigned long long)s->packets[0],
|
||||
(unsigned long long)s->packets[1],
|
||||
(unsigned long long)s->bytes[0],
|
||||
(unsigned long long)s->bytes[1]);
|
||||
(unsigned long long)betoh64(packets[0]),
|
||||
(unsigned long long)betoh64(packets[1]),
|
||||
(unsigned long long)betoh64(bytes[0]),
|
||||
(unsigned long long)betoh64(bytes[1]));
|
||||
#else
|
||||
s->packets[0], s->packets[1], s->bytes[0], s->bytes[1]);
|
||||
betoh64(packets[0]),
|
||||
betoh64(packets[1]),
|
||||
betoh64(bytes[0]),
|
||||
betoh64(bytes[1]));
|
||||
#endif
|
||||
if (s->anchor.nr != -1)
|
||||
printf(", anchor %u", s->anchor.nr);
|
||||
if (s->rule.nr != -1)
|
||||
printf(", rule %u", s->rule.nr);
|
||||
if (ntohl(s->anchor) != -1)
|
||||
printf(", anchor %u", ntohl(s->anchor));
|
||||
if (ntohl(s->rule) != -1)
|
||||
printf(", rule %u", ntohl(s->rule));
|
||||
if (s->state_flags & PFSTATE_SLOPPY)
|
||||
printf(", sloppy");
|
||||
if (s->src_node != NULL)
|
||||
if (s->state_flags & PFSTATE_PFLOW)
|
||||
printf(", pflow");
|
||||
if (s->sync_flags & PFSYNC_FLAG_SRCNODE)
|
||||
printf(", source-track");
|
||||
if (s->nat_src_node != NULL)
|
||||
if (s->sync_flags & PFSYNC_FLAG_NATSRCNODE)
|
||||
printf(", sticky-address");
|
||||
printf("\n");
|
||||
}
|
||||
if (opts & PF_OPT_VERBOSE2) {
|
||||
printf(" id: %016llx creatorid: %08x%s\n",
|
||||
u_int64_t id;
|
||||
|
||||
bcopy(&s->id, &id, sizeof(u_int64_t));
|
||||
printf(" id: %016llx creatorid: %08x",
|
||||
#ifdef __FreeBSD__
|
||||
(unsigned long long)be64toh(s->id), ntohl(s->creatorid),
|
||||
(unsigned long long)betoh64(id), ntohl(s->creatorid));
|
||||
#else
|
||||
betoh64(s->id), ntohl(s->creatorid),
|
||||
betoh64(id), ntohl(s->creatorid));
|
||||
#endif
|
||||
((s->sync_flags & PFSTATE_NOSYNC) ? " (no-sync)" : ""));
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $OpenBSD: pfctl.8,v 1.128 2007/01/30 21:01:56 jmc Exp $
|
||||
.\" $OpenBSD: pfctl.8,v 1.138 2008/06/10 20:55:02 mcbride Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2001 Kjell Wooding. All rights reserved.
|
||||
.\"
|
||||
@ -26,12 +26,12 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd June 13, 2011
|
||||
.Dd June 21, 2011
|
||||
.Dt PFCTL 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm pfctl
|
||||
.Nd "control the packet filter (PF) and network address translation (NAT) device"
|
||||
.Nd control the packet filter (PF) device
|
||||
.Sh SYNOPSIS
|
||||
.Nm pfctl
|
||||
.Bk -words
|
||||
@ -43,15 +43,18 @@
|
||||
.Op Fl f Ar file
|
||||
.Op Fl i Ar interface
|
||||
.Op Fl K Ar host | network
|
||||
.Op Fl k Ar host | network
|
||||
.Op Fl o Op Ar level
|
||||
.Xo
|
||||
.Oo Fl k
|
||||
.Ar host | network | label | id
|
||||
.Oc Xc
|
||||
.Op Fl o Ar level
|
||||
.Op Fl p Ar device
|
||||
.Op Fl s Ar modifier
|
||||
.Oo
|
||||
.Fl t Ar table
|
||||
.Xo
|
||||
.Oo Fl t Ar table
|
||||
.Fl T Ar command
|
||||
.Op Ar address ...
|
||||
.Oc
|
||||
.Op Ar address ... Oc
|
||||
.Xc
|
||||
.Op Fl x Ar level
|
||||
.Ek
|
||||
.Sh DESCRIPTION
|
||||
@ -85,7 +88,7 @@ When the variable
|
||||
is set to
|
||||
.Dv YES
|
||||
in
|
||||
.Xr rc.conf.local 5 ,
|
||||
.Xr rc.conf.local 8 ,
|
||||
the rule file specified with the variable
|
||||
.Va pf_rules
|
||||
is loaded automatically by the
|
||||
@ -211,7 +214,7 @@ Flush the NAT rules.
|
||||
Flush the queue rules.
|
||||
.It Fl F Cm rules
|
||||
Flush the filter rules.
|
||||
.It Fl F Cm state
|
||||
.It Fl F Cm states
|
||||
Flush the state table (NAT and filter).
|
||||
.It Fl F Cm Sources
|
||||
Flush the source tracking table.
|
||||
@ -251,22 +254,28 @@ or
|
||||
.Fl K Ar network
|
||||
option may be specified, which will kill all the source tracking
|
||||
entries from the first host/network to the second.
|
||||
.It Fl k Ar host | network
|
||||
Kill all of the state entries originating from the specified
|
||||
.Ar host
|
||||
.It Xo
|
||||
.Fl k
|
||||
.Ar host | network | label | id
|
||||
.Xc
|
||||
Kill all of the state entries matching the specified
|
||||
.Ar host ,
|
||||
.Ar network ,
|
||||
.Ar label ,
|
||||
or
|
||||
.Ar network .
|
||||
.Ar id .
|
||||
.Pp
|
||||
For example, to kill all of the state entries originating from
|
||||
.Dq host :
|
||||
.Pp
|
||||
.Dl # pfctl -k host
|
||||
.Pp
|
||||
A second
|
||||
.Fl k Ar host
|
||||
or
|
||||
.Fl k Ar network
|
||||
option may be specified, which will kill all the state entries
|
||||
from the first host/network to the second.
|
||||
For example, to kill all of the state entries originating from
|
||||
.Dq host :
|
||||
.Pp
|
||||
.Dl # pfctl -k host
|
||||
.Pp
|
||||
To kill all of the state entries from
|
||||
.Dq host1
|
||||
to
|
||||
@ -283,6 +292,32 @@ To kill all states with the target
|
||||
.Dq host2 :
|
||||
.Pp
|
||||
.Dl # pfctl -k 0.0.0.0/0 -k host2
|
||||
.Pp
|
||||
It is also possible to kill states by rule label or state ID.
|
||||
In this mode the first
|
||||
.Fl k
|
||||
argument is used to specify the type
|
||||
of the second argument.
|
||||
The following command would kill all states that have been created
|
||||
from rules carrying the label
|
||||
.Dq foobar :
|
||||
.Pp
|
||||
.Dl # pfctl -k label -k foobar
|
||||
.Pp
|
||||
To kill one specific state by its unique state ID
|
||||
(as shown by pfctl -s state -vv),
|
||||
use the
|
||||
.Ar id
|
||||
modifier and as a second argument the state ID and optional creator ID.
|
||||
To kill a state with ID 4823e84500000003 use:
|
||||
.Pp
|
||||
.Dl # pfctl -k id -k 4823e84500000003
|
||||
.Pp
|
||||
To kill a state with ID 4823e84500000018 created from a backup
|
||||
firewall with hostid 00000002 use:
|
||||
.Pp
|
||||
.Dl # pfctl -k id -k 4823e84500000018/2
|
||||
.Pp
|
||||
.It Fl m
|
||||
Merge in explicitly given options without resetting those
|
||||
which are omitted.
|
||||
@ -298,58 +333,20 @@ 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 Op Ar level
|
||||
Control the ruleset optimizer.
|
||||
The ruleset optimizer attempts to improve rulesets by removing rule
|
||||
duplication and making better use of rule ordering.
|
||||
.It Fl o Ar level
|
||||
Control the ruleset optimizer, overriding any rule file settings.
|
||||
.Pp
|
||||
.Bl -tag -width xxxxxxxxxxxx -compact
|
||||
.It Fl o Cm none
|
||||
Disable the ruleset optimizer.
|
||||
.It Fl o Cm basic
|
||||
Enable basic ruleset optimizations.
|
||||
This is the default behaviour.
|
||||
.It Fl o Cm profile
|
||||
Enable basic ruleset optimizations with profiling.
|
||||
.El
|
||||
.Pp
|
||||
.Cm basic
|
||||
optimization does 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
|
||||
If
|
||||
.Cm profile
|
||||
is specified, the currently loaded ruleset will be examined 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.
|
||||
.Pp
|
||||
To retain compatibility with previous behaviour, a single
|
||||
.Fl o
|
||||
without any options will enable
|
||||
.Cm basic
|
||||
optimizations, and a second
|
||||
.Fl o
|
||||
will enable profiling.
|
||||
For further information on the ruleset optimizer, see
|
||||
.Xr pf.conf 5 .
|
||||
.It Fl P
|
||||
Do not perform service name lookup for port specific rules,
|
||||
instead display the ports numerically.
|
||||
@ -407,7 +404,7 @@ If
|
||||
.Fl v
|
||||
is specified, all anchors attached under the target anchor will be
|
||||
displayed recursively.
|
||||
.It Fl s Cm state
|
||||
.It Fl s Cm states
|
||||
Show the contents of the state table.
|
||||
.It Fl s Cm Sources
|
||||
Show the contents of the source tracking table.
|
||||
@ -418,7 +415,7 @@ When used together with
|
||||
source tracking statistics are also shown.
|
||||
.It Fl s Cm labels
|
||||
Show per-rule statistics (label, evaluations, packets total, bytes total,
|
||||
packets in, bytes in, packets out, bytes out) of
|
||||
packets in, bytes in, packets out, bytes out, state creations) of
|
||||
filter rules with labels, useful for accounting.
|
||||
.It Fl s Cm timeouts
|
||||
Show the current global timeouts.
|
||||
@ -529,7 +526,7 @@ attributes.
|
||||
The address/network has been cleared (statistics).
|
||||
.El
|
||||
.Pp
|
||||
Each table maintains a set of counters that can be retrieved using the
|
||||
Each table can maintain a set of counters that can be retrieved using the
|
||||
.Fl v
|
||||
flag of
|
||||
.Nm .
|
||||
@ -540,7 +537,7 @@ 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
|
||||
# printf "table <test> counters { ftp.openbsd.org }\en \e
|
||||
pass out to <test>\en" | pfctl -f-
|
||||
# ping -qc10 ftp.openbsd.org
|
||||
.Ed
|
||||
@ -574,7 +571,7 @@ the number of rules which reference the table, and the global
|
||||
packet statistics for the whole table:
|
||||
.Bd -literal -offset indent
|
||||
# pfctl -vvsTables
|
||||
--a-r- test
|
||||
--a-r-C test
|
||||
Addresses: 1
|
||||
Cleared: Thu Feb 13 18:55:18 2003
|
||||
References: [ Anchors: 0 Rules: 1 ]
|
||||
@ -634,6 +631,8 @@ 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 from anchors attached below it.
|
||||
.It C
|
||||
This flag is set when per-address counters are enabled on the table.
|
||||
.El
|
||||
.It Fl t Ar table
|
||||
Specify the name of the table.
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: pfctl.c,v 1.262 2007/03/01 17:20:53 deraadt Exp $ */
|
||||
/* $OpenBSD: pfctl.c,v 1.278 2008/08/31 20:18:17 jmc Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Daniel Hartmeier
|
||||
@ -39,6 +39,10 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/endian.h>
|
||||
#endif
|
||||
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/pfvar.h>
|
||||
@ -59,10 +63,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include "pfctl_parser.h"
|
||||
#include "pfctl.h"
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#define HTONL(x) (x) = htonl((__uint32_t)(x))
|
||||
#endif
|
||||
|
||||
void usage(void);
|
||||
int pfctl_enable(int, int);
|
||||
int pfctl_disable(int, int);
|
||||
@ -75,7 +75,9 @@ int pfctl_clear_src_nodes(int, int);
|
||||
int pfctl_clear_states(int, const char *, int);
|
||||
void pfctl_addrprefix(char *, struct pf_addr *);
|
||||
int pfctl_kill_src_nodes(int, const char *, int);
|
||||
int pfctl_kill_states(int, const char *, int);
|
||||
int pfctl_net_kill_states(int, const char *, int);
|
||||
int pfctl_label_kill_states(int, const char *, int);
|
||||
int pfctl_id_kill_states(int, const char *, int);
|
||||
void pfctl_init_options(struct pfctl *);
|
||||
int pfctl_load_options(struct pfctl *);
|
||||
int pfctl_load_limit(struct pfctl *, unsigned int, unsigned int);
|
||||
@ -126,8 +128,6 @@ int dev = -1;
|
||||
int first_title = 1;
|
||||
int labels = 0;
|
||||
|
||||
const char *infile;
|
||||
|
||||
#define INDENT(d, o) do { \
|
||||
if (o) { \
|
||||
int i; \
|
||||
@ -208,11 +208,11 @@ static const struct {
|
||||
|
||||
static const char *clearopt_list[] = {
|
||||
"nat", "queue", "rules", "Sources",
|
||||
"state", "info", "Tables", "osfp", "all", NULL
|
||||
"states", "info", "Tables", "osfp", "all", NULL
|
||||
};
|
||||
|
||||
static const char *showopt_list[] = {
|
||||
"nat", "queue", "rules", "Anchors", "Sources", "state", "info",
|
||||
"nat", "queue", "rules", "Anchors", "Sources", "states", "info",
|
||||
"Interfaces", "labels", "timeouts", "memory", "Tables", "osfp",
|
||||
"all", NULL
|
||||
};
|
||||
@ -227,7 +227,7 @@ static const char *debugopt_list[] = {
|
||||
};
|
||||
|
||||
static const char *optiopt_list[] = {
|
||||
"o", "none", "basic", "profile", NULL
|
||||
"none", "basic", "profile", NULL
|
||||
};
|
||||
|
||||
void
|
||||
@ -237,10 +237,11 @@ usage(void)
|
||||
|
||||
fprintf(stderr, "usage: %s [-AdeghmNnOPqRrvz] ", __progname);
|
||||
fprintf(stderr, "[-a anchor] [-D macro=value] [-F modifier]\n");
|
||||
fprintf(stderr, "\t[-f file] [-i interface] [-K host | network] ");
|
||||
fprintf(stderr, "[-k host | network ]\n");
|
||||
fprintf(stderr, "\t[-o [level]] [-p device] [-s modifier ]\n");
|
||||
fprintf(stderr, "\t[-t table -T command [address ...]] [-x level]\n");
|
||||
fprintf(stderr, "\t[-f file] [-i interface] [-K host | network]\n");
|
||||
fprintf(stderr, "\t[-k host | network | label | id] ");
|
||||
fprintf(stderr, "[-o level] [-p device]\n");
|
||||
fprintf(stderr, "\t[-s modifier] ");
|
||||
fprintf(stderr, "[-t table -T command [address ...]] [-x level]\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -389,7 +390,7 @@ pfctl_clear_states(int dev, const char *iface, int opts)
|
||||
if (ioctl(dev, DIOCCLRSTATES, &psk))
|
||||
err(1, "DIOCCLRSTATES");
|
||||
if ((opts & PF_OPT_QUIET) == 0)
|
||||
fprintf(stderr, "%d states cleared\n", psk.psk_af);
|
||||
fprintf(stderr, "%d states cleared\n", psk.psk_killed);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -528,17 +529,13 @@ pfctl_kill_src_nodes(int dev, const char *iface, int opts)
|
||||
|
||||
if (ioctl(dev, DIOCKILLSRCNODES, &psnk))
|
||||
err(1, "DIOCKILLSRCNODES");
|
||||
killed += psnk.psnk_af;
|
||||
/* fixup psnk.psnk_af */
|
||||
psnk.psnk_af = resp[1]->ai_family;
|
||||
killed += psnk.psnk_killed;
|
||||
}
|
||||
freeaddrinfo(res[1]);
|
||||
} else {
|
||||
if (ioctl(dev, DIOCKILLSRCNODES, &psnk))
|
||||
err(1, "DIOCKILLSRCNODES");
|
||||
killed += psnk.psnk_af;
|
||||
/* fixup psnk.psnk_af */
|
||||
psnk.psnk_af = res[0]->ai_family;
|
||||
killed += psnk.psnk_killed;
|
||||
}
|
||||
}
|
||||
|
||||
@ -551,7 +548,7 @@ pfctl_kill_src_nodes(int dev, const char *iface, int opts)
|
||||
}
|
||||
|
||||
int
|
||||
pfctl_kill_states(int dev, const char *iface, int opts)
|
||||
pfctl_net_kill_states(int dev, const char *iface, int opts)
|
||||
{
|
||||
struct pfioc_state_kill psk;
|
||||
struct addrinfo *res[2], *resp[2];
|
||||
@ -638,17 +635,13 @@ pfctl_kill_states(int dev, const char *iface, int opts)
|
||||
|
||||
if (ioctl(dev, DIOCKILLSTATES, &psk))
|
||||
err(1, "DIOCKILLSTATES");
|
||||
killed += psk.psk_af;
|
||||
/* fixup psk.psk_af */
|
||||
psk.psk_af = resp[1]->ai_family;
|
||||
killed += psk.psk_killed;
|
||||
}
|
||||
freeaddrinfo(res[1]);
|
||||
} else {
|
||||
if (ioctl(dev, DIOCKILLSTATES, &psk))
|
||||
err(1, "DIOCKILLSTATES");
|
||||
killed += psk.psk_af;
|
||||
/* fixup psk.psk_af */
|
||||
psk.psk_af = res[0]->ai_family;
|
||||
killed += psk.psk_killed;
|
||||
}
|
||||
}
|
||||
|
||||
@ -660,6 +653,68 @@ pfctl_kill_states(int dev, const char *iface, int opts)
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pfctl_label_kill_states(int dev, const char *iface, int opts)
|
||||
{
|
||||
struct pfioc_state_kill psk;
|
||||
|
||||
if (state_killers != 2 || (strlen(state_kill[1]) == 0)) {
|
||||
warnx("no label specified");
|
||||
usage();
|
||||
}
|
||||
memset(&psk, 0, sizeof(psk));
|
||||
if (iface != NULL && strlcpy(psk.psk_ifname, iface,
|
||||
sizeof(psk.psk_ifname)) >= sizeof(psk.psk_ifname))
|
||||
errx(1, "invalid interface: %s", iface);
|
||||
|
||||
if (strlcpy(psk.psk_label, state_kill[1], sizeof(psk.psk_label)) >=
|
||||
sizeof(psk.psk_label))
|
||||
errx(1, "label too long: %s", state_kill[1]);
|
||||
|
||||
if (ioctl(dev, DIOCKILLSTATES, &psk))
|
||||
err(1, "DIOCKILLSTATES");
|
||||
|
||||
if ((opts & PF_OPT_QUIET) == 0)
|
||||
fprintf(stderr, "killed %d states\n", psk.psk_killed);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pfctl_id_kill_states(int dev, const char *iface, int opts)
|
||||
{
|
||||
struct pfioc_state_kill psk;
|
||||
|
||||
if (state_killers != 2 || (strlen(state_kill[1]) == 0)) {
|
||||
warnx("no id specified");
|
||||
usage();
|
||||
}
|
||||
|
||||
memset(&psk, 0, sizeof(psk));
|
||||
if ((sscanf(state_kill[1], "%jx/%x",
|
||||
&psk.psk_pfcmp.id, &psk.psk_pfcmp.creatorid)) == 2)
|
||||
HTONL(psk.psk_pfcmp.creatorid);
|
||||
else if ((sscanf(state_kill[1], "%jx", &psk.psk_pfcmp.id)) == 1) {
|
||||
psk.psk_pfcmp.creatorid = 0;
|
||||
} else {
|
||||
warnx("wrong id format specified");
|
||||
usage();
|
||||
}
|
||||
if (psk.psk_pfcmp.id == 0) {
|
||||
warnx("cannot kill id 0");
|
||||
usage();
|
||||
}
|
||||
|
||||
psk.psk_pfcmp.id = htobe64(psk.psk_pfcmp.id);
|
||||
if (ioctl(dev, DIOCKILLSTATES, &psk))
|
||||
err(1, "DIOCKILLSTATES");
|
||||
|
||||
if ((opts & PF_OPT_QUIET) == 0)
|
||||
fprintf(stderr, "killed %d states\n", psk.psk_killed);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pfctl_get_pool(int dev, struct pf_pool *pool, u_int32_t nr,
|
||||
u_int32_t ticket, int r_action, char *anchorname)
|
||||
@ -747,10 +802,12 @@ pfctl_print_rule_counters(struct pf_rule *rule, int opts)
|
||||
(unsigned long long)(rule->packets[0] +
|
||||
rule->packets[1]),
|
||||
(unsigned long long)(rule->bytes[0] +
|
||||
rule->bytes[1]), rule->states);
|
||||
rule->bytes[1]), rule->states_cur);
|
||||
if (!(opts & PF_OPT_DEBUG))
|
||||
printf(" [ Inserted: uid %u pid %u ]\n",
|
||||
(unsigned)rule->cuid, (unsigned)rule->cpid);
|
||||
printf(" [ Inserted: uid %u pid %u "
|
||||
"State Creations: %-6u]\n",
|
||||
(unsigned)rule->cuid, (unsigned)rule->cpid,
|
||||
rule->states_tot);
|
||||
}
|
||||
}
|
||||
|
||||
@ -818,19 +875,6 @@ pfctl_show_rules(int dev, char *path, int opts, enum pfctl_show format,
|
||||
|
||||
switch (format) {
|
||||
case PFCTL_SHOW_LABELS:
|
||||
if (pr.rule.label[0]) {
|
||||
printf("%s ", pr.rule.label);
|
||||
printf("%llu %llu %llu %llu %llu %llu %llu\n",
|
||||
(unsigned long long)pr.rule.evaluations,
|
||||
(unsigned long long)(pr.rule.packets[0] +
|
||||
pr.rule.packets[1]),
|
||||
(unsigned long long)(pr.rule.bytes[0] +
|
||||
pr.rule.bytes[1]),
|
||||
(unsigned long long)pr.rule.packets[0],
|
||||
(unsigned long long)pr.rule.bytes[0],
|
||||
(unsigned long long)pr.rule.packets[1],
|
||||
(unsigned long long)pr.rule.bytes[1]);
|
||||
}
|
||||
break;
|
||||
case PFCTL_SHOW_RULES:
|
||||
if (pr.rule.label[0] && (opts & PF_OPT_SHOWALL))
|
||||
@ -864,8 +908,9 @@ pfctl_show_rules(int dev, char *path, int opts, enum pfctl_show format,
|
||||
switch (format) {
|
||||
case PFCTL_SHOW_LABELS:
|
||||
if (pr.rule.label[0]) {
|
||||
printf("%s ", pr.rule.label);
|
||||
printf("%llu %llu %llu %llu %llu %llu %llu\n",
|
||||
printf("%s %llu %llu %llu %llu"
|
||||
" %llu %llu %llu %llu\n",
|
||||
pr.rule.label,
|
||||
(unsigned long long)pr.rule.evaluations,
|
||||
(unsigned long long)(pr.rule.packets[0] +
|
||||
pr.rule.packets[1]),
|
||||
@ -874,7 +919,8 @@ pfctl_show_rules(int dev, char *path, int opts, enum pfctl_show format,
|
||||
(unsigned long long)pr.rule.packets[0],
|
||||
(unsigned long long)pr.rule.bytes[0],
|
||||
(unsigned long long)pr.rule.packets[1],
|
||||
(unsigned long long)pr.rule.bytes[1]);
|
||||
(unsigned long long)pr.rule.bytes[1],
|
||||
(unsigned long long)pr.rule.states_tot);
|
||||
}
|
||||
break;
|
||||
case PFCTL_SHOW_RULES:
|
||||
@ -967,7 +1013,7 @@ pfctl_show_src_nodes(int dev, int opts)
|
||||
struct pfioc_src_nodes psn;
|
||||
struct pf_src_node *p;
|
||||
char *inbuf = NULL, *newinbuf = NULL;
|
||||
unsigned len = 0;
|
||||
unsigned int len = 0;
|
||||
int i;
|
||||
|
||||
memset(&psn, 0, sizeof(psn));
|
||||
@ -1010,9 +1056,9 @@ int
|
||||
pfctl_show_states(int dev, const char *iface, int opts)
|
||||
{
|
||||
struct pfioc_states ps;
|
||||
struct pf_state *p;
|
||||
struct pfsync_state *p;
|
||||
char *inbuf = NULL, *newinbuf = NULL;
|
||||
unsigned len = 0;
|
||||
unsigned int len = 0;
|
||||
int i, dotitle = (opts & PF_OPT_SHOWALL);
|
||||
|
||||
memset(&ps, 0, sizeof(ps));
|
||||
@ -1041,7 +1087,7 @@ pfctl_show_states(int dev, const char *iface, int opts)
|
||||
}
|
||||
p = ps.ps_states;
|
||||
for (i = 0; i < ps.ps_len; i += sizeof(*p), p++) {
|
||||
if (iface != NULL && strcmp(p->u.ifname, iface))
|
||||
if (iface != NULL && strcmp(p->ifname, iface))
|
||||
continue;
|
||||
if (dotitle) {
|
||||
pfctl_print_title("STATES:");
|
||||
@ -1163,7 +1209,7 @@ pfctl_add_rule(struct pfctl *pf, struct pf_rule *r, const char *anchor_call)
|
||||
r->anchor->ruleset.anchor = r->anchor;
|
||||
if (strlcpy(r->anchor->path, anchor_call,
|
||||
sizeof(rule->anchor->path)) >= sizeof(rule->anchor->path))
|
||||
errx(1, "pfctl_add_rule: strlcpy");
|
||||
errx(1, "pfctl_add_rule: strlcpy");
|
||||
if ((p = strrchr(anchor_call, '/')) != NULL) {
|
||||
if (!strlen(p))
|
||||
err(1, "pfctl_add_rule: bad anchor name %s",
|
||||
@ -1172,7 +1218,7 @@ pfctl_add_rule(struct pfctl *pf, struct pf_rule *r, const char *anchor_call)
|
||||
p = (char *)anchor_call;
|
||||
if (strlcpy(r->anchor->name, p,
|
||||
sizeof(rule->anchor->name)) >= sizeof(rule->anchor->name))
|
||||
errx(1, "pfctl_add_rule: strlcpy");
|
||||
errx(1, "pfctl_add_rule: strlcpy");
|
||||
}
|
||||
|
||||
if ((rule = calloc(1, sizeof(*rule))) == NULL)
|
||||
@ -1197,7 +1243,7 @@ pfctl_ruleset_trans(struct pfctl *pf, char *path, struct pf_anchor *a)
|
||||
return (1);
|
||||
}
|
||||
if (a == pf->astack[0] && ((altqsupport &&
|
||||
(pf->loadopt & PFCTL_FLAG_ALTQ) != 0))) {
|
||||
(pf->loadopt & PFCTL_FLAG_ALTQ) != 0))) {
|
||||
if (pfctl_add_trans(pf->trans, PF_RULESET_ALTQ, path))
|
||||
return (2);
|
||||
}
|
||||
@ -1350,7 +1396,7 @@ pfctl_add_altq(struct pfctl *pf, struct pf_altq *a)
|
||||
}
|
||||
|
||||
int
|
||||
pfctl_rules(int dev, char *filename, FILE *fin, int opts, int optimize,
|
||||
pfctl_rules(int dev, char *filename, int opts, int optimize,
|
||||
char *anchorname, struct pfr_buffer *trans)
|
||||
{
|
||||
#define ERR(x) do { warn(x); goto _error; } while(0)
|
||||
@ -1386,7 +1432,6 @@ pfctl_rules(int dev, char *filename, FILE *fin, int opts, int optimize,
|
||||
if (strlcpy(trs.pfrt_anchor, anchorname,
|
||||
sizeof(trs.pfrt_anchor)) >= sizeof(trs.pfrt_anchor))
|
||||
ERRX("pfctl_rules: strlcpy");
|
||||
infile = filename;
|
||||
pf.dev = dev;
|
||||
pf.opts = opts;
|
||||
pf.optimize = optimize;
|
||||
@ -1430,7 +1475,7 @@ pfctl_rules(int dev, char *filename, FILE *fin, int opts, int optimize,
|
||||
pfctl_get_ticket(t, PF_RULESET_TABLE, anchorname);
|
||||
}
|
||||
|
||||
if (parse_rules(fin, &pf) < 0) {
|
||||
if (parse_config(filename, &pf) < 0) {
|
||||
if ((opts & PF_OPT_NOACTION) == 0)
|
||||
ERRX("Syntax error in config file: "
|
||||
"pf rules not loaded");
|
||||
@ -1456,11 +1501,6 @@ pfctl_rules(int dev, char *filename, FILE *fin, int opts, int optimize,
|
||||
if (check_commit_altq(dev, opts) != 0)
|
||||
ERRX("errors in altq config");
|
||||
|
||||
if (fin != stdin) {
|
||||
fclose(fin);
|
||||
fin = NULL;
|
||||
}
|
||||
|
||||
/* process "load anchor" directives */
|
||||
if (!anchorname[0])
|
||||
if (pfctl_load_anchors(dev, &pf, t) == -1)
|
||||
@ -1482,8 +1522,6 @@ _error:
|
||||
err(1, "DIOCXROLLBACK");
|
||||
exit(1);
|
||||
} else { /* sub ruleset */
|
||||
if (fin != NULL && fin != stdin)
|
||||
fclose(fin);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@ -1515,7 +1553,8 @@ pfctl_fopen(const char *name, const char *mode)
|
||||
void
|
||||
pfctl_init_options(struct pfctl *pf)
|
||||
{
|
||||
int mib[2], mem;
|
||||
int64_t mem;
|
||||
int mib[2];
|
||||
size_t size;
|
||||
|
||||
pf->timeout[PFTM_TCP_FIRST_PACKET] = PFTM_TCP_FIRST_PACKET_VAL;
|
||||
@ -1546,9 +1585,14 @@ pfctl_init_options(struct pfctl *pf)
|
||||
pf->limit[PF_LIMIT_TABLE_ENTRIES] = PFR_KENTRY_HIWAT;
|
||||
|
||||
mib[0] = CTL_HW;
|
||||
#ifdef __FreeBSD__
|
||||
mib[1] = HW_PHYSMEM;
|
||||
#else
|
||||
mib[1] = HW_PHYSMEM64;
|
||||
#endif
|
||||
size = sizeof(mem);
|
||||
(void) sysctl(mib, 2, &mem, &size, NULL, 0);
|
||||
if (sysctl(mib, 2, &mem, &size, NULL, 0) == -1)
|
||||
err(1, "sysctl");
|
||||
if (mem <= 100*1024*1024)
|
||||
pf->limit[PF_LIMIT_TABLE_ENTRIES] = PFR_KENTRY_HIWAT_SMALL;
|
||||
|
||||
@ -1572,7 +1616,7 @@ pfctl_load_options(struct pfctl *pf)
|
||||
}
|
||||
|
||||
/*
|
||||
* If we've set the limit, but havn't explicitly set adaptive
|
||||
* If we've set the limit, but haven't explicitly set adaptive
|
||||
* timeouts, do it now with a start of 60% and end of 120%.
|
||||
*/
|
||||
if (pf->limit_set[PF_LIMIT_STATES] &&
|
||||
@ -1897,9 +1941,6 @@ pfctl_debug(int dev, u_int32_t level, int opts)
|
||||
int
|
||||
pfctl_test_altqsupport(int dev, int opts)
|
||||
{
|
||||
#if defined(__FreeBSD__) && !defined(ENABLE_ALTQ)
|
||||
return (0);
|
||||
#else
|
||||
struct pfioc_altq pa;
|
||||
|
||||
if (ioctl(dev, DIOCGETALTQS, &pa)) {
|
||||
@ -1912,7 +1953,6 @@ pfctl_test_altqsupport(int dev, int opts)
|
||||
err(1, "DIOCGETALTQS");
|
||||
}
|
||||
return (1);
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
@ -1971,16 +2011,15 @@ main(int argc, char *argv[])
|
||||
int ch;
|
||||
int mode = O_RDONLY;
|
||||
int opts = 0;
|
||||
int optimize = 0;
|
||||
int optimize = PF_OPTIMIZE_BASIC;
|
||||
char anchorname[MAXPATHLEN];
|
||||
char *path;
|
||||
FILE *fin = NULL;
|
||||
|
||||
if (argc < 2)
|
||||
usage();
|
||||
|
||||
while ((ch = getopt(argc, argv,
|
||||
"a:AdD:eqf:F:ghi:k:K:mnNOo::Pp:rRs:t:T:vx:z")) != -1) {
|
||||
"a:AdD:eqf:F:ghi:k:K:mnNOo:Pp:rRs:t:T:vx:z")) != -1) {
|
||||
switch (ch) {
|
||||
case 'a':
|
||||
anchoropt = optarg;
|
||||
@ -2056,24 +2095,11 @@ main(int argc, char *argv[])
|
||||
loadopt |= PFCTL_FLAG_FILTER;
|
||||
break;
|
||||
case 'o':
|
||||
if (optarg) {
|
||||
optiopt = pfctl_lookup_option(optarg,
|
||||
optiopt_list);
|
||||
if (optiopt == NULL) {
|
||||
warnx("Unknown optimization '%s'",
|
||||
optarg);
|
||||
usage();
|
||||
}
|
||||
optiopt = pfctl_lookup_option(optarg, optiopt_list);
|
||||
if (optiopt == NULL) {
|
||||
warnx("Unknown optimization '%s'", optarg);
|
||||
usage();
|
||||
}
|
||||
if (opts & PF_OPT_OPTIMIZE) {
|
||||
if (optiopt != NULL) {
|
||||
warnx("Cannot specify -o multiple times"
|
||||
"with optimizer level");
|
||||
usage();
|
||||
}
|
||||
optimize |= PF_OPTIMIZE_PROFILE;
|
||||
}
|
||||
optimize |= PF_OPTIMIZE_BASIC;
|
||||
opts |= PF_OPT_OPTIMIZE;
|
||||
break;
|
||||
case 'O':
|
||||
@ -2303,8 +2329,14 @@ main(int argc, char *argv[])
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (state_killers)
|
||||
pfctl_kill_states(dev, ifaceopt, opts);
|
||||
if (state_killers) {
|
||||
if (!strcmp(state_kill[0], "label"))
|
||||
pfctl_label_kill_states(dev, ifaceopt, opts);
|
||||
else if (!strcmp(state_kill[0], "id"))
|
||||
pfctl_id_kill_states(dev, ifaceopt, opts);
|
||||
else
|
||||
pfctl_net_kill_states(dev, ifaceopt, opts);
|
||||
}
|
||||
|
||||
if (src_node_killers)
|
||||
pfctl_kill_src_nodes(dev, ifaceopt, opts);
|
||||
@ -2329,15 +2361,6 @@ main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
if (rulesopt != NULL) {
|
||||
if (strcmp(rulesopt, "-") == 0) {
|
||||
fin = stdin;
|
||||
rulesopt = "stdin";
|
||||
} else {
|
||||
if ((fin = pfctl_fopen(rulesopt, "r")) == NULL)
|
||||
err(1, "%s", rulesopt);
|
||||
}
|
||||
}
|
||||
if ((rulesopt != NULL) && (loadopt & PFCTL_FLAG_OPTION) &&
|
||||
!anchorname[0])
|
||||
if (pfctl_clear_interface_flags(dev, opts | PF_OPT_QUIET))
|
||||
@ -2352,7 +2375,7 @@ main(int argc, char *argv[])
|
||||
if (anchorname[0] == '_' || strstr(anchorname, "/_") != NULL)
|
||||
errx(1, "anchor names beginning with '_' cannot "
|
||||
"be modified from the command line");
|
||||
if (pfctl_rules(dev, rulesopt, fin, opts, optimize,
|
||||
if (pfctl_rules(dev, rulesopt, opts, optimize,
|
||||
anchorname, NULL))
|
||||
error = 1;
|
||||
else if (!(opts & PF_OPT_NOACTION) &&
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: pfctl.h,v 1.40 2007/02/09 11:25:27 henning Exp $ */
|
||||
/* $OpenBSD: pfctl.h,v 1.42 2007/12/05 12:01:47 chl Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Daniel Hartmeier
|
||||
@ -49,7 +49,6 @@ struct pfr_buffer {
|
||||
(var) != NULL; \
|
||||
(var) = pfr_buf_next((buf), (var)))
|
||||
|
||||
void pfr_set_fd(int);
|
||||
int pfr_get_fd(void);
|
||||
int pfr_clr_tables(struct pfr_table *, int *, int);
|
||||
int pfr_add_tables(struct pfr_table *, int, int *, int);
|
||||
@ -64,9 +63,7 @@ int pfr_set_addrs(struct pfr_table *, struct pfr_addr *, int, int *,
|
||||
int *, int *, int *, int);
|
||||
int pfr_get_addrs(struct pfr_table *, struct pfr_addr *, int *, int);
|
||||
int pfr_get_astats(struct pfr_table *, struct pfr_astats *, int *, int);
|
||||
int pfr_clr_astats(struct pfr_table *, struct pfr_addr *, int, int *, int);
|
||||
int pfr_tst_addrs(struct pfr_table *, struct pfr_addr *, int, int *, int);
|
||||
int pfr_set_tflags(struct pfr_table *, int, int, int, int *, int *, int);
|
||||
int pfr_ina_define(struct pfr_table *, struct pfr_addr *, int, int *,
|
||||
int *, int, int);
|
||||
void pfr_buf_clear(struct pfr_buffer *);
|
||||
@ -91,6 +88,8 @@ FILE *pfctl_fopen(const char *, const char *);
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
extern int altqsupport;
|
||||
extern int dummynetsupport;
|
||||
#define HTONL(x) (x) = htonl((__uint32_t)(x))
|
||||
#endif
|
||||
|
||||
#ifndef DEFAULT_PRIORITY
|
||||
@ -117,9 +116,9 @@ struct pf_altq *pfaltq_lookup(const char *);
|
||||
char *rate2str(double);
|
||||
|
||||
void print_addr(struct pf_addr_wrap *, sa_family_t, int);
|
||||
void print_host(struct pf_state_host *, sa_family_t, int);
|
||||
void print_seq(struct pf_state_peer *);
|
||||
void print_state(struct pf_state *, int);
|
||||
void print_host(struct pf_addr *, u_int16_t p, sa_family_t, int);
|
||||
void print_seq(struct pfsync_state_peer *);
|
||||
void print_state(struct pfsync_state *, int);
|
||||
int unmask(struct pf_addr *, sa_family_t);
|
||||
|
||||
int pfctl_cmdline_symset(char *);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: pfctl_altq.c,v 1.91 2006/11/28 00:08:50 henning Exp $ */
|
||||
/* $OpenBSD: pfctl_altq.c,v 1.93 2007/10/15 02:16:35 deraadt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2002
|
||||
@ -21,7 +21,7 @@
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
@ -78,7 +78,7 @@ static int gsc_add_seg(struct gen_sc *, double, double, double,
|
||||
static double sc_x2y(struct service_curve *, double);
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
u_int32_t getifspeed(int, char *);
|
||||
u_int32_t getifspeed(int, char *);
|
||||
#else
|
||||
u_int32_t getifspeed(char *);
|
||||
#endif
|
||||
@ -145,8 +145,8 @@ qname_to_qid(const char *qname)
|
||||
}
|
||||
|
||||
void
|
||||
print_altq(const struct pf_altq *a, unsigned level, struct node_queue_bw *bw,
|
||||
struct node_queue_opt *qopts)
|
||||
print_altq(const struct pf_altq *a, unsigned int level,
|
||||
struct node_queue_bw *bw, struct node_queue_opt *qopts)
|
||||
{
|
||||
if (a->qname[0] != 0) {
|
||||
print_queue(a, level, bw, 1, qopts);
|
||||
@ -157,6 +157,7 @@ print_altq(const struct pf_altq *a, unsigned level, struct node_queue_bw *bw,
|
||||
if (a->local_flags & PFALTQ_FLAG_IF_REMOVED)
|
||||
printf("INACTIVE ");
|
||||
#endif
|
||||
|
||||
printf("altq on %s ", a->ifname);
|
||||
|
||||
switch (a->scheduler) {
|
||||
@ -186,10 +187,11 @@ print_altq(const struct pf_altq *a, unsigned level, struct node_queue_bw *bw,
|
||||
}
|
||||
|
||||
void
|
||||
print_queue(const struct pf_altq *a, unsigned level, struct node_queue_bw *bw,
|
||||
int print_interface, struct node_queue_opt *qopts)
|
||||
print_queue(const struct pf_altq *a, unsigned int level,
|
||||
struct node_queue_bw *bw, int print_interface,
|
||||
struct node_queue_opt *qopts)
|
||||
{
|
||||
unsigned i;
|
||||
unsigned int i;
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
if (a->local_flags & PFALTQ_FLAG_IF_REMOVED)
|
||||
@ -893,9 +895,6 @@ print_hfsc_opts(const struct pf_altq *a, const struct node_queue_opt *qopts)
|
||||
/*
|
||||
* admission control using generalized service curve
|
||||
*/
|
||||
#ifndef INFINITY
|
||||
#define INFINITY HUGE_VAL /* positive infinity defined in <math.h> */
|
||||
#endif
|
||||
|
||||
/* add a new service curve to a generalized service curve */
|
||||
static void
|
||||
@ -1132,8 +1131,6 @@ getifspeed(char *ifname)
|
||||
ifr.ifr_data = (caddr_t)&ifrdat;
|
||||
if (ioctl(s, SIOCGIFDATA, (caddr_t)&ifr) == -1)
|
||||
err(1, "SIOCGIFDATA");
|
||||
if (shutdown(s, SHUT_RDWR) == -1)
|
||||
err(1, "shutdown");
|
||||
if (close(s))
|
||||
err(1, "close");
|
||||
return ((u_int32_t)ifrdat.ifi_baudrate);
|
||||
@ -1158,8 +1155,6 @@ getifmtu(char *ifname)
|
||||
#else
|
||||
err(1, "SIOCGIFMTU");
|
||||
#endif
|
||||
if (shutdown(s, SHUT_RDWR) == -1)
|
||||
err(1, "shutdown");
|
||||
if (close(s))
|
||||
err(1, "close");
|
||||
if (ifr.ifr_mtu > 0)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: pfctl_optimize.c,v 1.13 2006/10/31 14:17:45 mcbride Exp $ */
|
||||
/* $OpenBSD: pfctl_optimize.c,v 1.17 2008/05/06 03:45:21 mpf Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004 Mike Frantzen <frantzen@openbsd.org>
|
||||
@ -185,7 +185,8 @@ struct pf_rule_field {
|
||||
PF_RULE_FIELD(packets, DC),
|
||||
PF_RULE_FIELD(bytes, DC),
|
||||
PF_RULE_FIELD(kif, DC),
|
||||
PF_RULE_FIELD(states, DC),
|
||||
PF_RULE_FIELD(states_cur, DC),
|
||||
PF_RULE_FIELD(states_tot, DC),
|
||||
PF_RULE_FIELD(src_nodes, DC),
|
||||
PF_RULE_FIELD(nr, DC),
|
||||
PF_RULE_FIELD(entries, DC),
|
||||
@ -201,6 +202,7 @@ struct pf_rule_field {
|
||||
PF_RULE_FIELD(natpass, NEVER),
|
||||
PF_RULE_FIELD(max_mss, NEVER),
|
||||
PF_RULE_FIELD(min_ttl, NEVER),
|
||||
PF_RULE_FIELD(set_tos, NEVER),
|
||||
};
|
||||
|
||||
|
||||
@ -398,7 +400,7 @@ optimize_superblock(struct pfctl *pf, struct superblock *block)
|
||||
* out rules.
|
||||
*/
|
||||
|
||||
/* shortcut. there will be alot of 1-rule superblocks */
|
||||
/* shortcut. there will be a lot of 1-rule superblocks */
|
||||
if (!TAILQ_NEXT(TAILQ_FIRST(&block->sb_rules), por_entry))
|
||||
return (0);
|
||||
|
||||
@ -1320,8 +1322,9 @@ again:
|
||||
|
||||
|
||||
if (pfctl_define_table(tbl->pt_name, PFR_TFLAG_CONST, 1,
|
||||
pf->anchor->name, tbl->pt_buf, pf->anchor->ruleset.tticket)) {
|
||||
warn("failed to create table %s", tbl->pt_name);
|
||||
pf->astack[0]->name, tbl->pt_buf, pf->astack[0]->ruleset.tticket)) {
|
||||
warn("failed to create table %s in %s",
|
||||
tbl->pt_name, pf->astack[0]->name);
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
@ -1424,7 +1427,7 @@ superblock_inclusive(struct superblock *block, struct pf_opt_rule *por)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Have to handle interface groups seperately. Consider the following
|
||||
* Have to handle interface groups separately. Consider the following
|
||||
* rules:
|
||||
* block on EXTIFS to any port 22
|
||||
* pass on em0 to any port 22
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: pfctl_osfp.c,v 1.15 2006/12/13 05:10:15 itojun Exp $ */
|
||||
/* $OpenBSD: pfctl_osfp.c,v 1.14 2006/04/08 02:13:14 ray Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003 Mike Frantzen <frantzen@openbsd.org>
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: pfctl_parser.c,v 1.234 2006/10/31 23:46:24 mcbride Exp $ */
|
||||
/* $OpenBSD: pfctl_parser.c,v 1.240 2008/06/10 20:55:02 mcbride Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Daniel Hartmeier
|
||||
@ -52,7 +52,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <netdb.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
@ -500,7 +499,7 @@ print_status(struct pf_status *s, int opts)
|
||||
running = s->running ? "Enabled" : "Disabled";
|
||||
|
||||
if (s->since) {
|
||||
unsigned sec, min, hrs, day = runtime;
|
||||
unsigned int sec, min, hrs, day = runtime;
|
||||
|
||||
sec = day % 60;
|
||||
day /= 60;
|
||||
@ -581,7 +580,11 @@ print_status(struct pf_status *s, int opts)
|
||||
s->src_nodes, "");
|
||||
for (i = 0; i < SCNT_MAX; i++) {
|
||||
printf(" %-25s %14lld ", pf_scounters[i],
|
||||
(unsigned long long)s->scounters[i]);
|
||||
#ifdef __FreeBSD__
|
||||
(long long)s->scounters[i]);
|
||||
#else
|
||||
s->scounters[i]);
|
||||
#endif
|
||||
if (runtime > 0)
|
||||
printf("%14.1f/s\n",
|
||||
(double)s->scounters[i] / (double)runtime);
|
||||
@ -952,6 +955,12 @@ print_rule(struct pf_rule *r, const char *anchor_call, int verbose, int numeric)
|
||||
printf("sloppy");
|
||||
opts = 0;
|
||||
}
|
||||
if (r->rule_flag & PFRULE_PFLOW) {
|
||||
if (!opts)
|
||||
printf(", ");
|
||||
printf("pflow");
|
||||
opts = 0;
|
||||
}
|
||||
for (i = 0; i < PFTM_MAX; ++i)
|
||||
if (r->timeout[i]) {
|
||||
int j;
|
||||
@ -979,6 +988,8 @@ print_rule(struct pf_rule *r, const char *anchor_call, int verbose, int numeric)
|
||||
printf(" min-ttl %d", r->min_ttl);
|
||||
if (r->max_mss)
|
||||
printf(" max-mss %d", r->max_mss);
|
||||
if (r->rule_flag & PFRULE_SET_TOS)
|
||||
printf(" set-tos 0x%2.2x", r->set_tos);
|
||||
if (r->allow_opts)
|
||||
printf(" allow-opts");
|
||||
if (r->action == PF_SCRUB) {
|
||||
@ -1007,6 +1018,26 @@ print_rule(struct pf_rule *r, const char *anchor_call, int verbose, int numeric)
|
||||
}
|
||||
if (r->rtableid != -1)
|
||||
printf(" rtable %u", r->rtableid);
|
||||
if (r->divert.port) {
|
||||
#ifdef __FreeBSD__
|
||||
printf(" divert-to %u", ntohs(r->divert.port));
|
||||
#else
|
||||
if (PF_AZERO(&r->divert.addr, r->af)) {
|
||||
printf(" divert-reply");
|
||||
} else {
|
||||
/* XXX cut&paste from print_addr */
|
||||
char buf[48];
|
||||
|
||||
printf(" divert-to ");
|
||||
if (inet_ntop(r->af, &r->divert.addr, buf,
|
||||
sizeof(buf)) == NULL)
|
||||
printf("?");
|
||||
else
|
||||
printf("%s", buf);
|
||||
printf(" port %u", ntohs(r->divert.port));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (!anchor_call[0] && (r->action == PF_NAT ||
|
||||
r->action == PF_BINAT || r->action == PF_RDR)) {
|
||||
printf(" -> ");
|
||||
@ -1027,6 +1058,8 @@ print_tabledef(const char *name, int flags, int addrs,
|
||||
printf(" const");
|
||||
if (flags & PFR_TFLAG_PERSIST)
|
||||
printf(" persist");
|
||||
if (flags & PFR_TFLAG_COUNTERS)
|
||||
printf(" counters");
|
||||
SIMPLEQ_FOREACH(ti, nodes, entries) {
|
||||
if (ti->file) {
|
||||
printf(" file \"%s\"", ti->file);
|
||||
|
@ -172,10 +172,10 @@ struct node_queue_opt {
|
||||
#define SIMPLEQ_END(head) NULL
|
||||
#define SIMPLEQ_EMPTY STAILQ_EMPTY
|
||||
#define SIMPLEQ_NEXT STAILQ_NEXT
|
||||
/*#define SIMPLEQ_FOREACH STAILQ_FOREACH*/
|
||||
#define SIMPLEQ_FOREACH(var, head, field) \
|
||||
for((var) = SIMPLEQ_FIRST(head); \
|
||||
(var) != SIMPLEQ_END(head); \
|
||||
/*#define SIMPLEQ_FOREACH STAILQ_FOREACH*/
|
||||
#define SIMPLEQ_FOREACH(var, head, field) \
|
||||
for((var) = SIMPLEQ_FIRST(head); \
|
||||
(var) != SIMPLEQ_END(head); \
|
||||
(var) = SIMPLEQ_NEXT(var, field))
|
||||
#define SIMPLEQ_INIT STAILQ_INIT
|
||||
#define SIMPLEQ_INSERT_HEAD STAILQ_INSERT_HEAD
|
||||
@ -213,7 +213,7 @@ struct pf_opt_rule {
|
||||
|
||||
TAILQ_HEAD(pf_opt_queue, pf_opt_rule);
|
||||
|
||||
int pfctl_rules(int, char *, FILE *, int, int, char *, struct pfr_buffer *);
|
||||
int pfctl_rules(int, char *, int, int, char *, struct pfr_buffer *);
|
||||
int pfctl_optimize_ruleset(struct pfctl *, struct pf_ruleset *);
|
||||
|
||||
int pfctl_add_rule(struct pfctl *, struct pf_rule *, const char *);
|
||||
@ -230,7 +230,7 @@ int pfctl_set_hostid(struct pfctl *, u_int32_t);
|
||||
int pfctl_set_debug(struct pfctl *, char *);
|
||||
int pfctl_set_interface_flags(struct pfctl *, char *, int, int);
|
||||
|
||||
int parse_rules(FILE *, struct pfctl *);
|
||||
int parse_config(char *, struct pfctl *);
|
||||
int parse_flags(char *);
|
||||
int pfctl_load_anchors(int, struct pfctl *, struct pfr_buffer *);
|
||||
|
||||
|
@ -73,7 +73,7 @@ void pfctl_insert_altq_node(struct pf_altq_node **,
|
||||
struct pf_altq_node *pfctl_find_altq_node(struct pf_altq_node *,
|
||||
const char *, const char *);
|
||||
void pfctl_print_altq_node(int, const struct pf_altq_node *,
|
||||
unsigned, int);
|
||||
unsigned, int);
|
||||
void print_cbqstats(struct queue_stats);
|
||||
void print_priqstats(struct queue_stats);
|
||||
void print_hfscstats(struct queue_stats);
|
||||
@ -185,8 +185,8 @@ pfctl_update_qstats(int dev, struct pf_altq_node **root)
|
||||
}
|
||||
}
|
||||
#ifdef __FreeBSD__
|
||||
else if (pa.altq.local_flags & PFALTQ_FLAG_IF_REMOVED) {
|
||||
memset(&qstats.data, 0, sizeof(qstats.data));
|
||||
else if (pa.altq.local_flags & PFALTQ_FLAG_IF_REMOVED) {
|
||||
memset(&qstats.data, 0, sizeof(qstats.data));
|
||||
if ((node = pfctl_find_altq_node(*root, pa.altq.qname,
|
||||
pa.altq.ifname)) != NULL) {
|
||||
memcpy(&node->qstats.data, &qstats.data,
|
||||
@ -194,7 +194,7 @@ pfctl_update_qstats(int dev, struct pf_altq_node **root)
|
||||
update_avg(node);
|
||||
} else {
|
||||
pfctl_insert_altq_node(root, pa.altq, qstats);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -262,8 +262,8 @@ pfctl_find_altq_node(struct pf_altq_node *root, const char *qname,
|
||||
}
|
||||
|
||||
void
|
||||
pfctl_print_altq_node(int dev, const struct pf_altq_node *node, unsigned level,
|
||||
int opts)
|
||||
pfctl_print_altq_node(int dev, const struct pf_altq_node *node,
|
||||
unsigned int level, int opts)
|
||||
{
|
||||
const struct pf_altq_node *child;
|
||||
|
||||
@ -302,11 +302,11 @@ pfctl_print_altq_nodestat(int dev, const struct pf_altq_node *a)
|
||||
{
|
||||
if (a->altq.qid == 0)
|
||||
return;
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
if (a->altq.local_flags & PFALTQ_FLAG_IF_REMOVED)
|
||||
return;
|
||||
#endif
|
||||
|
||||
switch (a->altq.scheduler) {
|
||||
case ALTQT_CBQ:
|
||||
print_cbqstats(a->qstats);
|
||||
|
@ -30,6 +30,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
@ -299,29 +302,6 @@ pfr_get_astats(struct pfr_table *tbl, struct pfr_astats *addr, int *size,
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pfr_clr_astats(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
int *nzero, int flags)
|
||||
{
|
||||
struct pfioc_table io;
|
||||
|
||||
if (tbl == NULL || size < 0 || (size && addr == NULL)) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
bzero(&io, sizeof io);
|
||||
io.pfrio_flags = flags;
|
||||
io.pfrio_table = *tbl;
|
||||
io.pfrio_buffer = addr;
|
||||
io.pfrio_esize = sizeof(*addr);
|
||||
io.pfrio_size = size;
|
||||
if (ioctl(dev, DIOCRCLRASTATS, &io))
|
||||
return (-1);
|
||||
if (nzero != NULL)
|
||||
*nzero = io.pfrio_nzero;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pfr_clr_tstats(struct pfr_table *tbl, int size, int *nzero, int flags)
|
||||
{
|
||||
@ -343,32 +323,6 @@ pfr_clr_tstats(struct pfr_table *tbl, int size, int *nzero, int flags)
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pfr_set_tflags(struct pfr_table *tbl, int size, int setflag, int clrflag,
|
||||
int *nchange, int *ndel, int flags)
|
||||
{
|
||||
struct pfioc_table io;
|
||||
|
||||
if (size < 0 || (size && !tbl)) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
bzero(&io, sizeof io);
|
||||
io.pfrio_flags = flags;
|
||||
io.pfrio_buffer = tbl;
|
||||
io.pfrio_esize = sizeof(*tbl);
|
||||
io.pfrio_size = size;
|
||||
io.pfrio_setflag = setflag;
|
||||
io.pfrio_clrflag = clrflag;
|
||||
if (ioctl(dev, DIOCRSETTFLAGS, &io))
|
||||
return (-1);
|
||||
if (nchange)
|
||||
*nchange = io.pfrio_nchange;
|
||||
if (ndel)
|
||||
*ndel = io.pfrio_ndel;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pfr_tst_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
int *nmatch, int flags)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: pfctl_table.c,v 1.66 2007/03/01 17:20:54 deraadt Exp $ */
|
||||
/* $OpenBSD: pfctl_table.c,v 1.67 2008/06/10 20:55:02 mcbride Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2002 Cedric Berger
|
||||
@ -275,12 +275,14 @@ pfctl_table(int argc, char *argv[], char *tname, const char *command,
|
||||
if (b.pfrb_size <= b.pfrb_msize)
|
||||
break;
|
||||
}
|
||||
PFRB_FOREACH(p, &b)
|
||||
PFRB_FOREACH(p, &b) {
|
||||
((struct pfr_astats *)p)->pfras_a.pfra_fback = 0;
|
||||
if (time(NULL) - ((struct pfr_astats *)p)->pfras_tzero >
|
||||
lifetime)
|
||||
lifetime)
|
||||
if (pfr_buf_add(&b2,
|
||||
&((struct pfr_astats *)p)->pfras_a))
|
||||
err(1, "duplicate buffer");
|
||||
}
|
||||
|
||||
if (opts & PF_OPT_VERBOSE)
|
||||
flags |= PFR_FLAG_FEEDBACK;
|
||||
@ -367,13 +369,14 @@ print_table(struct pfr_table *ta, int verbose, int debug)
|
||||
if (!debug && !(ta->pfrt_flags & PFR_TFLAG_ACTIVE))
|
||||
return;
|
||||
if (verbose) {
|
||||
printf("%c%c%c%c%c%c\t%s",
|
||||
printf("%c%c%c%c%c%c%c\t%s",
|
||||
(ta->pfrt_flags & PFR_TFLAG_CONST) ? 'c' : '-',
|
||||
(ta->pfrt_flags & PFR_TFLAG_PERSIST) ? 'p' : '-',
|
||||
(ta->pfrt_flags & PFR_TFLAG_ACTIVE) ? 'a' : '-',
|
||||
(ta->pfrt_flags & PFR_TFLAG_INACTIVE) ? 'i' : '-',
|
||||
(ta->pfrt_flags & PFR_TFLAG_REFERENCED) ? 'r' : '-',
|
||||
(ta->pfrt_flags & PFR_TFLAG_REFDANCHOR) ? 'h' : '-',
|
||||
(ta->pfrt_flags & PFR_TFLAG_COUNTERS) ? 'C' : '-',
|
||||
ta->pfrt_name);
|
||||
if (ta->pfrt_anchor[0])
|
||||
printf("\t%s", ta->pfrt_anchor);
|
||||
@ -428,7 +431,7 @@ void
|
||||
print_addrx(struct pfr_addr *ad, struct pfr_addr *rad, int dns)
|
||||
{
|
||||
char ch, buf[256] = "{error}";
|
||||
char fb[] = { ' ', 'M', 'A', 'D', 'C', 'Z', 'X', ' ', 'Y' };
|
||||
char fb[] = { ' ', 'M', 'A', 'D', 'C', 'Z', 'X', ' ', 'Y', ' ' };
|
||||
unsigned int fback, hostnet;
|
||||
|
||||
fback = (rad != NULL) ? rad->pfra_fback : ad->pfra_fback;
|
||||
@ -477,6 +480,8 @@ print_astats(struct pfr_astats *as, int dns)
|
||||
|
||||
print_addrx(&as->pfras_a, NULL, dns);
|
||||
printf("\tCleared: %s", ctime(&time));
|
||||
if (as->pfras_a.pfra_fback == PFR_FB_NOCOUNT)
|
||||
return;
|
||||
for (dir = 0; dir < PFR_DIR_MAX; dir++)
|
||||
for (op = 0; op < PFR_OP_ADDR_MAX; op++)
|
||||
printf("\t%-12s [ Packets: %-18llu Bytes: %-18llu ]\n",
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $OpenBSD: pflogd.8,v 1.32 2006/12/08 10:26:38 joel Exp $
|
||||
.\" $OpenBSD: pflogd.8,v 1.37 2008/10/22 08:16:49 henning Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2001 Can Erkin Acar. All rights reserved.
|
||||
.\"
|
||||
@ -26,7 +26,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd July 9, 2001
|
||||
.Dd October 22 2008
|
||||
.Dt PFLOGD 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -34,12 +34,14 @@
|
||||
.Nd packet filter logging daemon
|
||||
.Sh SYNOPSIS
|
||||
.Nm pflogd
|
||||
.Bk -words
|
||||
.Op Fl Dx
|
||||
.Op Fl d Ar delay
|
||||
.Op Fl f Ar filename
|
||||
.Op Fl i Ar interface
|
||||
.Op Fl s Ar snaplen
|
||||
.Op Ar expression
|
||||
.Ek
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
is a background daemon which reads packets logged by
|
||||
@ -94,6 +96,13 @@ or a
|
||||
.Dv SIGALRM
|
||||
is received.
|
||||
.Pp
|
||||
.Nm
|
||||
will also log the pcap statistics for the
|
||||
.Xr pflog 4
|
||||
interface to syslog when a
|
||||
.Dv SIGUSR1
|
||||
is received.
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl D
|
||||
@ -116,6 +125,11 @@ By default,
|
||||
.Nm
|
||||
will use
|
||||
.Ar pflog0 .
|
||||
Writes a file containing the process ID of the program to
|
||||
.Pa /var/run .
|
||||
The file name has the form
|
||||
The default is
|
||||
.Ar pflogd .
|
||||
.It Fl s Ar snaplen
|
||||
Analyze at most the first
|
||||
.Ar snaplen
|
||||
@ -204,12 +218,12 @@ the wi0 interface:
|
||||
# tcpdump -n -e -ttt -i pflog0 inbound and action block and on wi0
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr tcpdump 1 ,
|
||||
.Xr pcap 3 ,
|
||||
.Xr pf 4 ,
|
||||
.Xr pflog 4 ,
|
||||
.Xr pf.conf 5 ,
|
||||
.Xr newsyslog 8
|
||||
.Xr newsyslog 8 ,
|
||||
.Xr tcpdump 1
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: pflogd.c,v 1.37 2006/10/26 13:34:47 jmc Exp $ */
|
||||
/* $OpenBSD: pflogd.c,v 1.46 2008/10/22 08:16:49 henning Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Theo de Raadt
|
||||
@ -37,9 +37,8 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
#ifdef __FreeBSD__
|
||||
#include <net/bpf.h> /* BIOCLOCK */
|
||||
#endif
|
||||
#include <sys/socket.h>
|
||||
#include <net/if.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -48,15 +47,16 @@ __FBSDID("$FreeBSD$");
|
||||
#include <pcap.h>
|
||||
#include <syslog.h>
|
||||
#include <signal.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <fcntl.h>
|
||||
#ifdef __FreeBSD__
|
||||
#include <ifaddrs.h>
|
||||
#include "pidfile.h"
|
||||
#else
|
||||
#include <util.h>
|
||||
#endif
|
||||
|
||||
#include "pflogd.h"
|
||||
|
||||
pcap_t *hpcap;
|
||||
@ -66,7 +66,7 @@ int Debug = 0;
|
||||
static int snaplen = DEF_SNAPLEN;
|
||||
static int cur_snaplen = DEF_SNAPLEN;
|
||||
|
||||
volatile sig_atomic_t gotsig_close, gotsig_alrm, gotsig_hup;
|
||||
volatile sig_atomic_t gotsig_close, gotsig_alrm, gotsig_hup, gotsig_usr1;
|
||||
|
||||
char *filename = PFLOGD_LOG_FILE;
|
||||
char *interface = PFLOGD_DEFAULT_IF;
|
||||
@ -80,7 +80,9 @@ unsigned int delay = FLUSH_DELAY;
|
||||
char *copy_argv(char * const *);
|
||||
void dump_packet(u_char *, const struct pcap_pkthdr *, const u_char *);
|
||||
void dump_packet_nobuf(u_char *, const struct pcap_pkthdr *, const u_char *);
|
||||
void log_pcap_stats(void);
|
||||
int flush_buffer(FILE *);
|
||||
int if_exists(char *);
|
||||
int init_pcap(void);
|
||||
void logmsg(int, const char *, ...);
|
||||
void purge_buffer(void);
|
||||
@ -89,6 +91,7 @@ int scan_dump(FILE *, off_t);
|
||||
int set_snaplen(int);
|
||||
void set_suspended(int);
|
||||
void sig_alrm(int);
|
||||
void sig_usr1(int);
|
||||
void sig_close(int);
|
||||
void sig_hup(int);
|
||||
void usage(void);
|
||||
@ -166,8 +169,8 @@ __dead void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: pflogd [-Dx] [-d delay] [-f filename]");
|
||||
fprintf(stderr, " [-i interface] [-s snaplen]\n");
|
||||
fprintf(stderr, " [expression]\n");
|
||||
fprintf(stderr, " [-i interface] [-p pidfile]\n");
|
||||
fprintf(stderr, " [-s snaplen] [expression]\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -189,6 +192,12 @@ sig_alrm(int sig)
|
||||
gotsig_alrm = 1;
|
||||
}
|
||||
|
||||
void
|
||||
sig_usr1(int sig)
|
||||
{
|
||||
gotsig_usr1 = 1;
|
||||
}
|
||||
|
||||
void
|
||||
set_pcap_filter(void)
|
||||
{
|
||||
@ -203,6 +212,51 @@ set_pcap_filter(void)
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
if_exists(char *ifname)
|
||||
{
|
||||
#ifdef __FreeBSD__
|
||||
struct ifaddrs *ifdata, *mb;
|
||||
int exists = 0;
|
||||
|
||||
getifaddrs(&ifdata);
|
||||
if (ifdata == NULL)
|
||||
return (0);
|
||||
|
||||
for (mb = ifdata; mb != NULL; mb = mb->ifa_next) {
|
||||
if (mb == NULL)
|
||||
continue;
|
||||
if (strlen(ifname) != strlen(mb->ifa_name))
|
||||
continue;
|
||||
if (strncmp(ifname, mb->ifa_name, strlen(ifname)) != 0)
|
||||
continue;
|
||||
exists = 1;
|
||||
break;
|
||||
}
|
||||
freeifaddrs(ifdata);
|
||||
|
||||
return (exists);
|
||||
#else
|
||||
int s;
|
||||
struct ifreq ifr;
|
||||
struct if_data ifrdat;
|
||||
|
||||
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
|
||||
err(1, "socket");
|
||||
bzero(&ifr, sizeof(ifr));
|
||||
if (strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)) >=
|
||||
sizeof(ifr.ifr_name))
|
||||
errx(1, "main ifr_name: strlcpy");
|
||||
ifr.ifr_data = (caddr_t)&ifrdat;
|
||||
if (ioctl(s, SIOCGIFDATA, (caddr_t)&ifr) == -1)
|
||||
return (0);
|
||||
if (close(s))
|
||||
err(1, "close");
|
||||
|
||||
return (1);
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
init_pcap(void)
|
||||
{
|
||||
@ -554,10 +608,10 @@ dump_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
|
||||
return;
|
||||
}
|
||||
|
||||
append:
|
||||
append:
|
||||
#ifdef __FreeBSD__
|
||||
sh.ts.tv_sec = (bpf_int32)h->ts.tv_sec;
|
||||
sh.ts.tv_usec = (bpf_int32)h->ts.tv_usec;
|
||||
sh.ts.tv_sec = (bpf_int32)h->ts.tv_sec;
|
||||
sh.ts.tv_usec = (bpf_int32)h->ts.tv_usec;
|
||||
sh.caplen = h->caplen;
|
||||
sh.len = h->len;
|
||||
|
||||
@ -575,17 +629,31 @@ dump_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
log_pcap_stats(void)
|
||||
{
|
||||
struct pcap_stat pstat;
|
||||
if (pcap_stats(hpcap, &pstat) < 0)
|
||||
logmsg(LOG_WARNING, "Reading stats: %s", pcap_geterr(hpcap));
|
||||
else
|
||||
logmsg(LOG_NOTICE,
|
||||
"%u packets received, %u/%u dropped (kernel/pflogd)",
|
||||
pstat.ps_recv, pstat.ps_drop, packets_dropped);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
struct pcap_stat pstat;
|
||||
int ch, np, Xflag = 0;
|
||||
int ch, np, ret, Xflag = 0;
|
||||
pcap_handler phandler = dump_packet;
|
||||
const char *errstr = NULL;
|
||||
char *pidf = NULL;
|
||||
|
||||
ret = 0;
|
||||
|
||||
closefrom(STDERR_FILENO + 1);
|
||||
|
||||
while ((ch = getopt(argc, argv, "Dxd:f:i:s:")) != -1) {
|
||||
while ((ch = getopt(argc, argv, "Dxd:f:i:p:s:")) != -1) {
|
||||
switch (ch) {
|
||||
case 'D':
|
||||
Debug = 1;
|
||||
@ -601,6 +669,9 @@ main(int argc, char **argv)
|
||||
case 'i':
|
||||
interface = optarg;
|
||||
break;
|
||||
case 'p':
|
||||
pidf = optarg;
|
||||
break;
|
||||
case 's':
|
||||
snaplen = strtonum(optarg, 0, PFLOGD_MAXSNAPLEN,
|
||||
&errstr);
|
||||
@ -622,13 +693,21 @@ main(int argc, char **argv)
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
/* does interface exist */
|
||||
if (!if_exists(interface)) {
|
||||
warn("Failed to initialize: %s", interface);
|
||||
logmsg(LOG_ERR, "Failed to initialize: %s", interface);
|
||||
logmsg(LOG_ERR, "Exiting, init failure");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!Debug) {
|
||||
openlog("pflogd", LOG_PID | LOG_CONS, LOG_DAEMON);
|
||||
if (daemon(0, 0)) {
|
||||
logmsg(LOG_WARNING, "Failed to become daemon: %s",
|
||||
strerror(errno));
|
||||
}
|
||||
pidfile(NULL);
|
||||
pidfile(pidf);
|
||||
}
|
||||
|
||||
tzset();
|
||||
@ -659,6 +738,7 @@ main(int argc, char **argv)
|
||||
signal(SIGINT, sig_close);
|
||||
signal(SIGQUIT, sig_close);
|
||||
signal(SIGALRM, sig_alrm);
|
||||
signal(SIGUSR1, sig_usr1);
|
||||
signal(SIGHUP, sig_hup);
|
||||
alarm(delay);
|
||||
|
||||
@ -686,13 +766,12 @@ main(int argc, char **argv)
|
||||
np = pcap_dispatch(hpcap, PCAP_NUM_PKTS,
|
||||
phandler, (u_char *)dpcap);
|
||||
if (np < 0) {
|
||||
#ifdef __FreeBSD__
|
||||
if (errno == ENXIO) {
|
||||
logmsg(LOG_ERR,
|
||||
"Device not/no longer configured");
|
||||
if (!if_exists(interface) == -1) {
|
||||
logmsg(LOG_NOTICE, "interface %s went away",
|
||||
interface);
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
logmsg(LOG_NOTICE, "%s", pcap_geterr(hpcap));
|
||||
}
|
||||
|
||||
@ -715,6 +794,11 @@ main(int argc, char **argv)
|
||||
gotsig_alrm = 0;
|
||||
alarm(delay);
|
||||
}
|
||||
|
||||
if (gotsig_usr1) {
|
||||
log_pcap_stats();
|
||||
gotsig_usr1 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
logmsg(LOG_NOTICE, "Exiting");
|
||||
@ -724,15 +808,9 @@ main(int argc, char **argv)
|
||||
}
|
||||
purge_buffer();
|
||||
|
||||
if (pcap_stats(hpcap, &pstat) < 0)
|
||||
logmsg(LOG_WARNING, "Reading stats: %s", pcap_geterr(hpcap));
|
||||
else
|
||||
logmsg(LOG_NOTICE,
|
||||
"%u packets received, %u/%u dropped (kernel/pflogd)",
|
||||
pstat.ps_recv, pstat.ps_drop, packets_dropped);
|
||||
|
||||
log_pcap_stats();
|
||||
pcap_close(hpcap);
|
||||
if (!Debug)
|
||||
closelog();
|
||||
return (0);
|
||||
return (ret);
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/bpf.h>
|
||||
@ -31,20 +32,13 @@ __FBSDID("$FreeBSD$");
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#ifndef __FreeBSD__
|
||||
#include <pcap.h>
|
||||
#include <pcap-int.h>
|
||||
#endif
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef __FreeBSD__
|
||||
/* XXX: pcap pollutes namespace with strlcpy if not present previously */
|
||||
#include <pcap.h>
|
||||
#include <pcap-int.h>
|
||||
#endif
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
#include "pflogd.h"
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: privsep_fdpass.c,v 1.2 2004/08/13 02:51:48 djm Exp $ */
|
||||
/* $OpenBSD: privsep_fdpass.c,v 1.5 2008/03/24 16:11:08 deraadt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 2001 Niels Provos <provos@citi.umich.edu>
|
||||
@ -50,7 +50,10 @@ void
|
||||
send_fd(int sock, int fd)
|
||||
{
|
||||
struct msghdr msg;
|
||||
char tmp[CMSG_SPACE(sizeof(int))];
|
||||
union {
|
||||
struct cmsghdr hdr;
|
||||
char buf[CMSG_SPACE(sizeof(int))];
|
||||
} cmsgbuf;
|
||||
struct cmsghdr *cmsg;
|
||||
struct iovec vec;
|
||||
int result = 0;
|
||||
@ -59,8 +62,8 @@ send_fd(int sock, int fd)
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
|
||||
if (fd >= 0) {
|
||||
msg.msg_control = (caddr_t)tmp;
|
||||
msg.msg_controllen = CMSG_LEN(sizeof(int));
|
||||
msg.msg_control = (caddr_t)&cmsgbuf.buf;
|
||||
msg.msg_controllen = sizeof(cmsgbuf.buf);
|
||||
cmsg = CMSG_FIRSTHDR(&msg);
|
||||
cmsg->cmsg_len = CMSG_LEN(sizeof(int));
|
||||
cmsg->cmsg_level = SOL_SOCKET;
|
||||
@ -86,7 +89,10 @@ int
|
||||
receive_fd(int sock)
|
||||
{
|
||||
struct msghdr msg;
|
||||
char tmp[CMSG_SPACE(sizeof(int))];
|
||||
union {
|
||||
struct cmsghdr hdr;
|
||||
char buf[CMSG_SPACE(sizeof(int))];
|
||||
} cmsgbuf;
|
||||
struct cmsghdr *cmsg;
|
||||
struct iovec vec;
|
||||
ssize_t n;
|
||||
@ -98,8 +104,8 @@ receive_fd(int sock)
|
||||
vec.iov_len = sizeof(int);
|
||||
msg.msg_iov = &vec;
|
||||
msg.msg_iovlen = 1;
|
||||
msg.msg_control = tmp;
|
||||
msg.msg_controllen = sizeof(tmp);
|
||||
msg.msg_control = &cmsgbuf.buf;
|
||||
msg.msg_controllen = sizeof(cmsgbuf.buf);
|
||||
|
||||
if ((n = recvmsg(sock, &msg, 0)) == -1)
|
||||
warn("%s: recvmsg", __func__);
|
||||
|
@ -1618,7 +1618,7 @@ gethostinfo(register char *hostname)
|
||||
register char **p;
|
||||
register u_int32_t addr, *ap;
|
||||
|
||||
if (strlen(hostname) > 64) {
|
||||
if (strlen(hostname) >= MAXHOSTNAMELEN) {
|
||||
Fprintf(stderr, "%s: hostname \"%.32s...\" is too long\n",
|
||||
prog, hostname);
|
||||
exit(1);
|
||||
|
@ -1,5 +1,5 @@
|
||||
# <pre>
|
||||
# @(#)antarctica 8.8
|
||||
# @(#)antarctica 8.9
|
||||
# This file is in the public domain, so clarified as of
|
||||
# 2009-05-17 by Arthur David Olson.
|
||||
|
||||
@ -19,18 +19,6 @@
|
||||
# I made up all time zone abbreviations mentioned here; corrections welcome!
|
||||
# FORMAT is `zzz' and GMTOFF is 0 for locations while uninhabited.
|
||||
|
||||
# These rules are stolen from the `europe' file.
|
||||
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
|
||||
Rule RussAQ 1981 1984 - Apr 1 0:00 1:00 S
|
||||
Rule RussAQ 1981 1983 - Oct 1 0:00 0 -
|
||||
Rule RussAQ 1984 1991 - Sep lastSun 2:00s 0 -
|
||||
Rule RussAQ 1985 1991 - Mar lastSun 2:00s 1:00 S
|
||||
Rule RussAQ 1992 only - Mar lastSat 23:00 1:00 S
|
||||
Rule RussAQ 1992 only - Sep lastSat 23:00 0 -
|
||||
Rule RussAQ 1993 max - Mar lastSun 2:00s 1:00 S
|
||||
Rule RussAQ 1993 1995 - Sep lastSun 2:00s 0 -
|
||||
Rule RussAQ 1996 max - Oct lastSun 2:00s 0 -
|
||||
|
||||
# These rules are stolen from the `southamerica' file.
|
||||
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
|
||||
Rule ArgAQ 1964 1966 - Mar 1 0:00 0 -
|
||||
|
@ -1,4 +1,4 @@
|
||||
# @(#)asia 8.64
|
||||
# @(#)asia 8.65
|
||||
# This file is in the public domain, so clarified as of
|
||||
# 2009-05-17 by Arthur David Olson.
|
||||
|
||||
@ -77,6 +77,10 @@ Rule RussiaAsia 1993 max - Mar lastSun 2:00s 1:00 S
|
||||
Rule RussiaAsia 1993 1995 - Sep lastSun 2:00s 0 -
|
||||
Rule RussiaAsia 1996 max - Oct lastSun 2:00s 0 -
|
||||
|
||||
# From Arthur David Olson (2011-06-15):
|
||||
# While Russia abandoned DST in 2011, Armenia may choose to
|
||||
# follow Russia's "old" rules.
|
||||
|
||||
# Afghanistan
|
||||
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
|
||||
Zone Asia/Kabul 4:36:48 - LMT 1890
|
||||
|
@ -1,5 +1,5 @@
|
||||
# <pre>
|
||||
# @(#)europe 8.32
|
||||
# @(#)europe 8.33
|
||||
# This file is in the public domain, so clarified as of
|
||||
# 2009-05-17 by Arthur David Olson.
|
||||
|
||||
@ -565,6 +565,26 @@ Rule Russia 1993 max - Mar lastSun 2:00s 1:00 S
|
||||
Rule Russia 1993 1995 - Sep lastSun 2:00s 0 -
|
||||
Rule Russia 1996 max - Oct lastSun 2:00s 0 -
|
||||
|
||||
# From Alexander Krivenyshev (2011-06-14):
|
||||
# According to Kremlin press service, Russian President Dmitry Medvedev
|
||||
# signed a federal law "On calculation of time" on June 9, 2011.
|
||||
# According to the law Russia is abolishing daylight saving time.
|
||||
#
|
||||
# Medvedev signed a law "On the Calculation of Time" (in russian):
|
||||
# <a href="http://bmockbe.ru/events/?ID=7583">
|
||||
# http://bmockbe.ru/events/?ID=7583
|
||||
# </a>
|
||||
#
|
||||
# Medvedev signed a law on the calculation of the time (in russian):
|
||||
# <a href="http://www.regnum.ru/news/polit/1413906.html">
|
||||
# http://www.regnum.ru/news/polit/1413906.html
|
||||
# </a>
|
||||
|
||||
# From Arthur David Olson (2011-06-15):
|
||||
# Take "abolishing daylight saving time" to mean that time is now considered
|
||||
# to be standard.
|
||||
# At least for now, keep the "old" Russia rules for the benefit of Belarus.
|
||||
|
||||
# These are for backward compatibility with older versions.
|
||||
|
||||
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
|
||||
@ -2013,7 +2033,8 @@ Zone Europe/Kaliningrad 1:22:00 - LMT 1893 Apr
|
||||
1:00 C-Eur CE%sT 1945
|
||||
2:00 Poland CE%sT 1946
|
||||
3:00 Russia MSK/MSD 1991 Mar 31 2:00s
|
||||
2:00 Russia EE%sT
|
||||
2:00 Russia EE%sT 2011 Mar 27 2:00s
|
||||
3:00 - EET
|
||||
#
|
||||
# From Oscar van Vlijmen (2001-08-25): [This region consists of]
|
||||
# Respublika Adygeya, Arkhangel'skaya oblast',
|
||||
@ -2042,7 +2063,8 @@ Zone Europe/Moscow 2:30:20 - LMT 1880
|
||||
2:00 - EET 1930 Jun 21
|
||||
3:00 Russia MSK/MSD 1991 Mar 31 2:00s
|
||||
2:00 Russia EE%sT 1992 Jan 19 2:00s
|
||||
3:00 Russia MSK/MSD
|
||||
3:00 Russia MSK/MSD 2011 Mar 27 2:00s
|
||||
4:00 - MSK
|
||||
#
|
||||
# Astrakhanskaya oblast', Kirovskaya oblast', Saratovskaya oblast',
|
||||
# Volgogradskaya oblast'. Shanks & Pottenger say Kirov is still at +0400
|
||||
@ -2055,7 +2077,8 @@ Zone Europe/Volgograd 2:57:40 - LMT 1920 Jan 3
|
||||
4:00 Russia VOL%sT 1989 Mar 26 2:00s # Volgograd T
|
||||
3:00 Russia VOL%sT 1991 Mar 31 2:00s
|
||||
4:00 - VOLT 1992 Mar 29 2:00s
|
||||
3:00 Russia VOL%sT
|
||||
3:00 Russia VOL%sT 2011 Mar 27 2:00s
|
||||
4:00 - VOLT
|
||||
#
|
||||
# From Oscar van Vlijmen (2001-08-25): [This region consists of]
|
||||
# Samarskaya oblast', Udmyrtskaya respublika
|
||||
@ -2067,7 +2090,8 @@ Zone Europe/Samara 3:20:36 - LMT 1919 Jul 1 2:00
|
||||
2:00 Russia KUY%sT 1991 Sep 29 2:00s
|
||||
3:00 - KUYT 1991 Oct 20 3:00
|
||||
4:00 Russia SAM%sT 2010 Mar 28 2:00s # Samara Time
|
||||
3:00 Russia SAM%sT
|
||||
3:00 Russia SAM%sT 2011 Mar 27 2:00s
|
||||
4:00 - SAMT
|
||||
|
||||
#
|
||||
# From Oscar van Vlijmen (2001-08-25): [This region consists of]
|
||||
@ -2080,7 +2104,8 @@ Zone Asia/Yekaterinburg 4:02:24 - LMT 1919 Jul 15 4:00
|
||||
4:00 - SVET 1930 Jun 21 # Sverdlovsk Time
|
||||
5:00 Russia SVE%sT 1991 Mar 31 2:00s
|
||||
4:00 Russia SVE%sT 1992 Jan 19 2:00s
|
||||
5:00 Russia YEK%sT # Yekaterinburg Time
|
||||
5:00 Russia YEK%sT 2011 Mar 27 2:00s
|
||||
6:00 - YEKT # Yekaterinburg Time
|
||||
#
|
||||
# From Oscar van Vlijmen (2001-08-25): [This region consists of]
|
||||
# Respublika Altaj, Altajskij kraj, Omskaya oblast'.
|
||||
@ -2088,7 +2113,8 @@ Zone Asia/Omsk 4:53:36 - LMT 1919 Nov 14
|
||||
5:00 - OMST 1930 Jun 21 # Omsk TIme
|
||||
6:00 Russia OMS%sT 1991 Mar 31 2:00s
|
||||
5:00 Russia OMS%sT 1992 Jan 19 2:00s
|
||||
6:00 Russia OMS%sT
|
||||
6:00 Russia OMS%sT 2011 Mar 27 2:00s
|
||||
7:00 - OMST
|
||||
#
|
||||
# From Paul Eggert (2006-08-19): I'm guessing about Tomsk here; it's
|
||||
# not clear when it switched from +7 to +6.
|
||||
@ -2098,7 +2124,8 @@ Zone Asia/Novosibirsk 5:31:40 - LMT 1919 Dec 14 6:00
|
||||
7:00 Russia NOV%sT 1991 Mar 31 2:00s
|
||||
6:00 Russia NOV%sT 1992 Jan 19 2:00s
|
||||
7:00 Russia NOV%sT 1993 May 23 # say Shanks & P.
|
||||
6:00 Russia NOV%sT
|
||||
6:00 Russia NOV%sT 2011 Mar 27 2:00s
|
||||
7:00 - NOVT
|
||||
|
||||
# From Alexander Krivenyshev (2009-10-13):
|
||||
# Kemerovo oblast' (Kemerovo region) in Russia will change current time zone on
|
||||
@ -2131,7 +2158,8 @@ Zone Asia/Novokuznetsk 5:48:48 - NMT 1920 Jan 6
|
||||
7:00 Russia KRA%sT 1991 Mar 31 2:00s
|
||||
6:00 Russia KRA%sT 1992 Jan 19 2:00s
|
||||
7:00 Russia KRA%sT 2010 Mar 28 2:00s
|
||||
6:00 Russia NOV%sT # Novosibirsk/Novokuznetsk Time
|
||||
6:00 Russia NOV%sT 2011 Mar 27 2:00s
|
||||
7:00 - NOVT # Novosibirsk/Novokuznetsk Time
|
||||
|
||||
#
|
||||
# From Oscar van Vlijmen (2001-08-25): [This region consists of]
|
||||
@ -2142,7 +2170,8 @@ Zone Asia/Krasnoyarsk 6:11:20 - LMT 1920 Jan 6
|
||||
6:00 - KRAT 1930 Jun 21 # Krasnoyarsk Time
|
||||
7:00 Russia KRA%sT 1991 Mar 31 2:00s
|
||||
6:00 Russia KRA%sT 1992 Jan 19 2:00s
|
||||
7:00 Russia KRA%sT
|
||||
7:00 Russia KRA%sT 2011 Mar 27 2:00s
|
||||
8:00 - KRAT
|
||||
#
|
||||
# From Oscar van Vlijmen (2001-08-25): [This region consists of]
|
||||
# Respublika Buryatiya, Irkutskaya oblast',
|
||||
@ -2152,7 +2181,8 @@ Zone Asia/Irkutsk 6:57:20 - LMT 1880
|
||||
7:00 - IRKT 1930 Jun 21 # Irkutsk Time
|
||||
8:00 Russia IRK%sT 1991 Mar 31 2:00s
|
||||
7:00 Russia IRK%sT 1992 Jan 19 2:00s
|
||||
8:00 Russia IRK%sT
|
||||
8:00 Russia IRK%sT 2011 Mar 27 2:00s
|
||||
9:00 - IRKT
|
||||
#
|
||||
# From Oscar van Vlijmen (2003-10-18): [This region consists of]
|
||||
# Aginskij Buryatskij avtonomnyj okrug, Amurskaya oblast',
|
||||
@ -2175,7 +2205,8 @@ Zone Asia/Yakutsk 8:38:40 - LMT 1919 Dec 15
|
||||
8:00 - YAKT 1930 Jun 21 # Yakutsk Time
|
||||
9:00 Russia YAK%sT 1991 Mar 31 2:00s
|
||||
8:00 Russia YAK%sT 1992 Jan 19 2:00s
|
||||
9:00 Russia YAK%sT
|
||||
9:00 Russia YAK%sT 2011 Mar 27 2:00s
|
||||
10:00 - YAKT
|
||||
#
|
||||
# From Oscar van Vlijmen (2003-10-18): [This region consists of]
|
||||
# Evrejskaya avtonomnaya oblast', Khabarovskij kraj, Primorskij kraj,
|
||||
@ -2188,7 +2219,8 @@ Zone Asia/Vladivostok 8:47:44 - LMT 1922 Nov 15
|
||||
9:00 - VLAT 1930 Jun 21 # Vladivostok Time
|
||||
10:00 Russia VLA%sT 1991 Mar 31 2:00s
|
||||
9:00 Russia VLA%sST 1992 Jan 19 2:00s
|
||||
10:00 Russia VLA%sT
|
||||
10:00 Russia VLA%sT 2011 Mar 27 2:00s
|
||||
11:00 - VLAT
|
||||
#
|
||||
# Sakhalinskaya oblast'.
|
||||
# The Zone name should be Yuzhno-Sakhalinsk, but that's too long.
|
||||
@ -2198,7 +2230,8 @@ Zone Asia/Sakhalin 9:30:48 - LMT 1905 Aug 23
|
||||
11:00 Russia SAK%sT 1991 Mar 31 2:00s # Sakhalin T.
|
||||
10:00 Russia SAK%sT 1992 Jan 19 2:00s
|
||||
11:00 Russia SAK%sT 1997 Mar lastSun 2:00s
|
||||
10:00 Russia SAK%sT
|
||||
10:00 Russia SAK%sT 2011 Mar 27 2:00s
|
||||
11:00 - SAKT
|
||||
#
|
||||
# From Oscar van Vlijmen (2003-10-18): [This region consists of]
|
||||
# Magadanskaya oblast', Respublika Sakha (Yakutiya).
|
||||
@ -2211,7 +2244,8 @@ Zone Asia/Magadan 10:03:12 - LMT 1924 May 2
|
||||
10:00 - MAGT 1930 Jun 21 # Magadan Time
|
||||
11:00 Russia MAG%sT 1991 Mar 31 2:00s
|
||||
10:00 Russia MAG%sT 1992 Jan 19 2:00s
|
||||
11:00 Russia MAG%sT
|
||||
11:00 Russia MAG%sT 2011 Mar 27 2:00s
|
||||
12:00 - MAGT
|
||||
#
|
||||
# From Oscar van Vlijmen (2001-08-25): [This region consists of]
|
||||
# Kamchatskaya oblast', Koryakskij avtonomnyj okrug.
|
||||
@ -2222,7 +2256,8 @@ Zone Asia/Kamchatka 10:34:36 - LMT 1922 Nov 10
|
||||
12:00 Russia PET%sT 1991 Mar 31 2:00s
|
||||
11:00 Russia PET%sT 1992 Jan 19 2:00s
|
||||
12:00 Russia PET%sT 2010 Mar 28 2:00s
|
||||
11:00 Russia PET%sT
|
||||
11:00 Russia PET%sT 2011 Mar 27 2:00s
|
||||
12:00 - PETT
|
||||
#
|
||||
# Chukotskij avtonomnyj okrug
|
||||
Zone Asia/Anadyr 11:49:56 - LMT 1924 May 2
|
||||
@ -2231,7 +2266,8 @@ Zone Asia/Anadyr 11:49:56 - LMT 1924 May 2
|
||||
12:00 Russia ANA%sT 1991 Mar 31 2:00s
|
||||
11:00 Russia ANA%sT 1992 Jan 19 2:00s
|
||||
12:00 Russia ANA%sT 2010 Mar 28 2:00s
|
||||
11:00 Russia ANA%sT
|
||||
11:00 Russia ANA%sT 2011 Mar 27 2:00s
|
||||
12:00 - ANAT
|
||||
|
||||
# Serbia
|
||||
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
|
||||
|
@ -1,5 +1,5 @@
|
||||
# <pre>
|
||||
# @(#)southamerica 8.49
|
||||
# @(#)southamerica 8.50
|
||||
# This file is in the public domain, so clarified as of
|
||||
# 2009-05-17 by Arthur David Olson.
|
||||
|
||||
@ -1276,6 +1276,14 @@ Zone America/Curacao -4:35:44 - LMT 1912 Feb 12 # Willemstad
|
||||
-4:30 - ANT 1965 # Netherlands Antilles Time
|
||||
-4:00 - AST
|
||||
|
||||
# From Arthur David Olson (2011-06-15):
|
||||
# At least for now, use links for places with new iso3166 codes.
|
||||
# The name "Lower Prince's Quarter" is both longer than fourteen charaters
|
||||
# and contains an apostrophe; use "Lower_Princes" below.
|
||||
|
||||
Link America/Curacao America/Lower_Princes # Sint Maarten
|
||||
Link America/Curacao America/Kralendijk # Bonaire, Sint Estatius and Saba
|
||||
|
||||
# Ecuador
|
||||
#
|
||||
# From Paul Eggert (2007-03-04):
|
||||
|
@ -1,5 +1,5 @@
|
||||
# <pre>
|
||||
# @(#)zone.tab 8.43
|
||||
# @(#)zone.tab 8.45
|
||||
# This file is in the public domain, so clarified as of
|
||||
# 2009-05-17 by Arthur David Olson.
|
||||
#
|
||||
@ -32,7 +32,6 @@ AG +1703-06148 America/Antigua
|
||||
AI +1812-06304 America/Anguilla
|
||||
AL +4120+01950 Europe/Tirane
|
||||
AM +4011+04430 Asia/Yerevan
|
||||
AN +1211-06900 America/Curacao
|
||||
AO -0848+01314 Africa/Luanda
|
||||
AQ -7750+16636 Antarctica/McMurdo McMurdo Station, Ross Island
|
||||
AQ -9000+00000 Antarctica/South_Pole Amundsen-Scott Station, South Pole
|
||||
@ -87,6 +86,7 @@ BL +1753-06251 America/St_Barthelemy
|
||||
BM +3217-06446 Atlantic/Bermuda
|
||||
BN +0456+11455 Asia/Brunei
|
||||
BO -1630-06809 America/La_Paz
|
||||
BQ +120903-0681636 America/Kralendijk
|
||||
BR -0351-03225 America/Noronha Atlantic islands
|
||||
BR -0127-04829 America/Belem Amapa, E Para
|
||||
BR -0343-03830 America/Fortaleza NE Brazil (MA, PI, CE, RN, PB)
|
||||
@ -155,6 +155,7 @@ CO +0436-07405 America/Bogota
|
||||
CR +0956-08405 America/Costa_Rica
|
||||
CU +2308-08222 America/Havana
|
||||
CV +1455-02331 Atlantic/Cape_Verde
|
||||
CW +1211-06900 America/Curacao
|
||||
CX -1025+10543 Indian/Christmas
|
||||
CY +3510+03322 Asia/Nicosia
|
||||
CZ +5005+01426 Europe/Prague
|
||||
@ -362,6 +363,7 @@ SO +0204+04522 Africa/Mogadishu
|
||||
SR +0550-05510 America/Paramaribo
|
||||
ST +0020+00644 Africa/Sao_Tome
|
||||
SV +1342-08912 America/El_Salvador
|
||||
SX +180305-0630250 America/Lower_Princes
|
||||
SY +3330+03618 Asia/Damascus
|
||||
SZ -2618+03106 Africa/Mbabane
|
||||
TC +2128-07108 America/Grand_Turk
|
||||
|
@ -1533,15 +1533,7 @@ nomatch 32 {
|
||||
match "bus" "uhub[0-9]+";
|
||||
match "mode" "host";
|
||||
match "vendor" "0x083a";
|
||||
match "product" "0x4506";
|
||||
action "kldload if_uath";
|
||||
};
|
||||
|
||||
nomatch 32 {
|
||||
match "bus" "uhub[0-9]+";
|
||||
match "mode" "host";
|
||||
match "vendor" "0x083a";
|
||||
match "product" "0x4506";
|
||||
match "product" "(0x4505|0x4506)";
|
||||
action "kldload if_zyd";
|
||||
};
|
||||
|
||||
|
@ -4,15 +4,14 @@
|
||||
|
||||
SRCS= crt1.c crti.S crtn.S
|
||||
OBJS= ${SRCS:N*.h:R:S/$/.o/g}
|
||||
OBJS+= gcrt1.o
|
||||
CFLAGS+= -Wall -Wno-unused \
|
||||
-I${.CURDIR}/../common \
|
||||
OBJS+= Scrt1.o gcrt1.o
|
||||
CFLAGS+= -I${.CURDIR}/../common \
|
||||
-I${.CURDIR}/../../libc/include
|
||||
|
||||
all: ${OBJS}
|
||||
|
||||
CLEANFILES= ${OBJS}
|
||||
CLEANFILES+= crt1.s gcrt1.s
|
||||
CLEANFILES+= crt1.s gcrt1.s Scrt1.s
|
||||
|
||||
# See the comment in lib/csu/common/crtbrand.c for the reason crt1.c is not
|
||||
# directly compiled to .o files.
|
||||
@ -31,6 +30,13 @@ gcrt1.s: crt1.c
|
||||
gcrt1.o: gcrt1.s
|
||||
${CC} ${CFLAGS} -c -o ${.TARGET} gcrt1.s
|
||||
|
||||
Scrt1.s: crt1.c
|
||||
${CC} ${CFLAGS} -fPIC -DPIC -S -o ${.TARGET} ${.CURDIR}/crt1.c
|
||||
sed -i "" -e '/\.note\.ABI-tag/s/progbits/note/' ${.TARGET}
|
||||
|
||||
Scrt1.o: Scrt1.s
|
||||
${CC} ${CFLAGS} -c -o ${.TARGET} Scrt1.s
|
||||
|
||||
realinstall:
|
||||
${INSTALL} -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \
|
||||
${OBJS} ${DESTDIR}${LIBDIR}
|
||||
|
@ -175,7 +175,7 @@ prefix, corresponding with the device used to facilitate the user login
|
||||
session.
|
||||
If no TTY character device is used, this field is left blank.
|
||||
This field is only applicable to entries of type
|
||||
.Dv USER_PROCESS
|
||||
.Dv USER_PROCESS
|
||||
and
|
||||
.Dv LOGIN_PROCESS .
|
||||
.It Fa ut_host
|
||||
@ -473,7 +473,7 @@ are extensions.
|
||||
.Sh HISTORY
|
||||
These functions appeared in
|
||||
.Fx 9.0 .
|
||||
They replaced the
|
||||
They replaced the
|
||||
.In utmp.h
|
||||
interface.
|
||||
.Sh AUTHORS
|
||||
|
@ -167,7 +167,7 @@ group IDs for the child process are changed as specified in the
|
||||
attributes object referenced by
|
||||
.Fa attrp .
|
||||
.It
|
||||
The file actions specified by the spawn file actions object are
|
||||
The file actions specified by the spawn file actions object are
|
||||
performed in the order in which they were added to the spawn file
|
||||
actions object.
|
||||
.It
|
||||
|
@ -182,7 +182,7 @@ process_file_actions(const posix_spawn_file_actions_t fa)
|
||||
if (error)
|
||||
return (error);
|
||||
}
|
||||
return (0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -193,7 +193,7 @@ do_posix_spawn(pid_t *pid, const char *path,
|
||||
{
|
||||
pid_t p;
|
||||
volatile int error = 0;
|
||||
|
||||
|
||||
p = vfork();
|
||||
switch (p) {
|
||||
case -1:
|
||||
|
@ -57,7 +57,7 @@ futx_open(const char *file)
|
||||
errno = EFTYPE;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
fp = fdopen(fd, "r+");
|
||||
if (fp == NULL) {
|
||||
_close(fd);
|
||||
@ -103,7 +103,7 @@ utx_active_add(const struct futx *fu)
|
||||
/* Allow us to overwrite unused records. */
|
||||
if (partial == -1) {
|
||||
partial = ftello(fp);
|
||||
/*
|
||||
/*
|
||||
* Distinguish errors from valid values so we
|
||||
* don't overwrite good data by accident.
|
||||
*/
|
||||
|
@ -82,7 +82,7 @@ ptsname(int fildes)
|
||||
/* Make sure fildes points to a master device. */
|
||||
if (__isptmaster(fildes) != 0)
|
||||
goto done;
|
||||
|
||||
|
||||
if (fdevname_r(fildes, pt_slave + (sizeof _PATH_DEV - 1),
|
||||
sizeof pt_slave - (sizeof _PATH_DEV - 1)) != NULL)
|
||||
ret = pt_slave;
|
||||
|
@ -127,7 +127,7 @@ argument is non-null it must point to at least 65 characters of buffer space.
|
||||
.Xr sha 3
|
||||
.Sh HISTORY
|
||||
These functions appeared in
|
||||
.Fx 4.0 .
|
||||
.Fx 6.0 .
|
||||
.Sh AUTHORS
|
||||
The core hash routines were implemented by Colin Percival based on
|
||||
the published
|
||||
|
@ -127,7 +127,7 @@ argument is non-null it must point to at least 65 characters of buffer space.
|
||||
.Xr sha 3
|
||||
.Sh HISTORY
|
||||
These functions appeared in
|
||||
.Fx 4.0 .
|
||||
.Fx 9.0 .
|
||||
.Sh AUTHORS
|
||||
The core hash routines were implemented by Colin Percival based on
|
||||
the published
|
||||
|
@ -636,7 +636,7 @@ libusb_clear_halt(struct libusb20_device *pdev, uint8_t endpoint)
|
||||
return (LIBUSB_ERROR_INVALID_PARAM);
|
||||
|
||||
CTX_LOCK(dev->ctx);
|
||||
err = libusb20_tr_open(xfer, 0, 0, endpoint);
|
||||
err = libusb20_tr_open(xfer, 0, 1, endpoint);
|
||||
CTX_UNLOCK(dev->ctx);
|
||||
|
||||
if (err != 0 && err != LIBUSB20_ERROR_BUSY)
|
||||
|
@ -21,6 +21,7 @@ MAN= hastctl.8
|
||||
|
||||
NO_WFORMAT=
|
||||
CFLAGS+=-I${.CURDIR}/../hastd
|
||||
CFLAGS+=-DHAVE_CAPSICUM
|
||||
CFLAGS+=-DINET
|
||||
.if ${MK_INET6_SUPPORT} != "no"
|
||||
CFLAGS+=-DINET6
|
||||
|
@ -20,8 +20,9 @@ SRCS+= y.tab.h
|
||||
MAN= hastd.8 hast.conf.5
|
||||
|
||||
NO_WFORMAT=
|
||||
CFLAGS+=-DPROTO_TCP_DEFAULT_PORT=8457
|
||||
CFLAGS+=-I${.CURDIR}
|
||||
CFLAGS+=-DHAVE_CAPSICUM
|
||||
CFLAGS+=-DPROTO_TCP_DEFAULT_PORT=8457
|
||||
CFLAGS+=-DINET
|
||||
.if ${MK_INET6_SUPPORT} != "no"
|
||||
CFLAGS+=-DINET6
|
||||
|
@ -31,7 +31,9 @@
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef HAVE_CAPSICUM
|
||||
#include <sys/capability.h>
|
||||
#endif
|
||||
#include <sys/param.h>
|
||||
#include <sys/disk.h>
|
||||
#include <sys/ioctl.h>
|
||||
@ -230,9 +232,15 @@ drop_privs(struct hast_resource *res)
|
||||
* ioctls and secondary uses ioctls to handle BIO_DELETE and BIO_FLUSH.
|
||||
* For now capsicum is only used to sandbox hastctl.
|
||||
*/
|
||||
if (res == NULL)
|
||||
#ifdef HAVE_CAPSICUM
|
||||
if (res == NULL) {
|
||||
capsicum = (cap_enter() == 0);
|
||||
else
|
||||
if (!capsicum) {
|
||||
pjdlog_common(LOG_DEBUG, 1, errno,
|
||||
"Unable to sandbox using capsicum");
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
capsicum = false;
|
||||
|
||||
/*
|
||||
|
@ -8,7 +8,7 @@ MAN= pflogd.8
|
||||
|
||||
CFLAGS+=-include ${.CURDIR}/../../lib/libpcap/config.h
|
||||
|
||||
LDADD= -lpcap -lutil
|
||||
LDADD= -lpcap
|
||||
DPADD= ${LIBPCAP} ${LIBUTIL}
|
||||
|
||||
WARNS?= 2
|
||||
|
@ -176,7 +176,6 @@ NA NAM 516 Namibia
|
||||
NR NRU 520 Nauru
|
||||
NP NPL 524 Nepal
|
||||
NL NLD 528 Netherlands
|
||||
AN ANT 530 Netherlands Antilles
|
||||
NC NCL 540 New Caledonia
|
||||
NZ NZL 554 New Zealand
|
||||
NI NIC 558 Nicaragua
|
||||
|
@ -63,6 +63,15 @@
|
||||
# SHAREMODE ASCII text file mode. [${NOBINMODE}]
|
||||
#
|
||||
#
|
||||
# CONFDIR Base path for configuration files. [/etc]
|
||||
#
|
||||
# CONFOWN Configuration file owner. [root]
|
||||
#
|
||||
# CONFGRP Configuration file group. [wheel]
|
||||
#
|
||||
# CONFMODE Configuration file mode. [644]
|
||||
#
|
||||
#
|
||||
# DOCDIR Base path for system documentation (e.g. PSD, USD,
|
||||
# handbook, FAQ etc.). [${SHAREDIR}/doc]
|
||||
#
|
||||
@ -145,6 +154,11 @@ SHAREOWN?= root
|
||||
SHAREGRP?= wheel
|
||||
SHAREMODE?= ${NOBINMODE}
|
||||
|
||||
CONFDIR?= /etc
|
||||
CONFOWN?= root
|
||||
CONFGRP?= wheel
|
||||
CONFMODE?= 644
|
||||
|
||||
MANDIR?= ${SHAREDIR}/man/man
|
||||
MANOWN?= ${SHAREOWN}
|
||||
MANGRP?= ${SHAREGRP}
|
||||
|
@ -37,43 +37,6 @@
|
||||
.globl start
|
||||
.code16
|
||||
|
||||
start: jmp main # Start recognizably
|
||||
|
||||
/*
|
||||
* This is the start of a standard BIOS Parameter Block (BPB). Most bootable
|
||||
* FAT disks have this at the start of their MBR. While normal BIOS's will
|
||||
* work fine without this section, IBM's El Torito emulation "fixes" up the
|
||||
* BPB by writing into the memory copy of the MBR. Rather than have data
|
||||
* written into our code, we'll define a BPB to work around it.
|
||||
* The data marked with (T) indicates a field required for a ThinkPad to
|
||||
* recognize the disk and (W) indicates fields written from IBM BIOS code.
|
||||
* The use of the BPB is based on what OpenBSD and NetBSD implemented in
|
||||
* their boot code but the required fields were determined by trial and error.
|
||||
*
|
||||
* Note: If additional space is needed in boot1, one solution would be to
|
||||
* move the "prompt" message data (below) to replace the OEM ID.
|
||||
*/
|
||||
.org 0x03, 0x00
|
||||
oemid: .space 0x08, 0x00 # OEM ID
|
||||
|
||||
.org 0x0b, 0x00
|
||||
bpb: .word 512 # sector size (T)
|
||||
.byte 0 # sectors/clustor
|
||||
.word 0 # reserved sectors
|
||||
.byte 0 # number of FATs
|
||||
.word 0 # root entries
|
||||
.word 0 # small sectors
|
||||
.byte 0 # media type (W)
|
||||
.word 0 # sectors/fat
|
||||
.word 18 # sectors per track (T)
|
||||
.word 2 # number of heads (T)
|
||||
.long 0 # hidden sectors (W)
|
||||
.long 0 # large sectors
|
||||
|
||||
.org 0x24, 0x00
|
||||
ebpb: .byte 0 # BIOS physical drive number (W)
|
||||
|
||||
.org 0x25,0x90
|
||||
/*
|
||||
* Load the rest of zfsboot2 and BTX up, copy the parts to the right locations,
|
||||
* and start it all up.
|
||||
@ -83,25 +46,24 @@ ebpb: .byte 0 # BIOS physical drive number (W)
|
||||
* Setup the segment registers to flat addressing (segment 0) and setup the
|
||||
* stack to end just below the start of our code.
|
||||
*/
|
||||
main: cld # String ops inc
|
||||
start: cld # String ops inc
|
||||
xor %cx,%cx # Zero
|
||||
mov %cx,%es # Address
|
||||
mov %cx,%ds # data
|
||||
mov %cx,%ss # Set up
|
||||
mov $start,%sp # stack
|
||||
/*
|
||||
* If we are on a hard drive, then load the MBR and look for the first
|
||||
* FreeBSD slice. We use the fake partition entry below that points to
|
||||
* the MBR when we call nread. The first pass looks for the first active
|
||||
* FreeBSD slice. The second pass looks for the first non-active FreeBSD
|
||||
* slice if the first one fails.
|
||||
* Load the MBR and look for the first FreeBSD slice. We use the fake
|
||||
* partition entry below that points to the MBR when we call read.
|
||||
* The first pass looks for the first active FreeBSD slice. The
|
||||
* second pass looks for the first non-active FreeBSD slice if the
|
||||
* first one fails.
|
||||
*/
|
||||
call check_edd # Make sure EDD works
|
||||
mov $part4,%si # Dummy partition
|
||||
cmpb $0x80,%dl # Hard drive?
|
||||
jb main.4 # No
|
||||
xor %eax,%eax # Read MBR
|
||||
movl $MEM_BUF,%ebx # from first
|
||||
callw nread # sector
|
||||
call read # sector
|
||||
mov $0x1,%cx # Two passes
|
||||
main.1: mov $MEM_BUF+PRT_OFF,%si # Partition table
|
||||
movb $0x1,%dh # Partition
|
||||
@ -122,10 +84,6 @@ main.3: add $0x10,%si # Next entry
|
||||
*/
|
||||
mov $msg_part,%si # Message
|
||||
jmp error # Error
|
||||
/*
|
||||
* Floppies use partition 0 of drive 0.
|
||||
*/
|
||||
main.4: xor %dx,%dx # Partition:drive
|
||||
|
||||
/*
|
||||
* Ok, we have a slice and drive in %dx now, so use that to locate and
|
||||
@ -153,7 +111,7 @@ main.5: mov %dx,MEM_ARG # Save args
|
||||
movl $1024,%eax # Offset to boot2
|
||||
mov $MEM_BTX,%ebx # Destination buffer
|
||||
main.6: pushal # Save params
|
||||
callw nread # Read disk
|
||||
call read # Read disk
|
||||
popal # Restore
|
||||
incl %eax # Advance to
|
||||
add $SIZ_SEC,%ebx # next sector
|
||||
@ -200,16 +158,16 @@ seta20.3: sti # Enable interrupts
|
||||
|
||||
|
||||
/*
|
||||
* Trampoline used to call read from within zfsldr. Sets up an EDD
|
||||
* packet on the stack and passes it to read. We assume that the
|
||||
* destination address is always segment-aligned.
|
||||
* Read a sector from the disk. Sets up an EDD packet on the stack
|
||||
* and passes it to read. We assume that the destination address is
|
||||
* always segment-aligned.
|
||||
*
|
||||
* %eax - int - LBA to read in relative to partition start
|
||||
* %ebx - ptr - destination address
|
||||
* %dl - byte - drive to read from
|
||||
* %si - ptr - MBR partition entry
|
||||
*/
|
||||
nread: xor %ecx,%ecx # Get
|
||||
read: xor %ecx,%ecx # Get
|
||||
addl 0x8(%si),%eax # LBA
|
||||
adc $0,%ecx
|
||||
pushl %ecx # Starting absolute block
|
||||
@ -219,12 +177,13 @@ nread: xor %ecx,%ecx # Get
|
||||
push $0 # transfer buffer
|
||||
push $0x1 # Read 1 sector
|
||||
push $0x10 # Size of packet
|
||||
mov %sp,%bp # Packet pointer
|
||||
callw read # Read from disk
|
||||
jc nread.1 # If error, fail
|
||||
lea 0x10(%bp),%sp # Clear stack
|
||||
mov %sp,%si # Packet pointer
|
||||
mov $0x42,%ah # BIOS: Extended
|
||||
int $0x13 # read
|
||||
jc read.1 # If error, fail
|
||||
lea 0x10(%si),%sp # Clear stack
|
||||
ret # If success, return
|
||||
nread.1: mov %ah,%al # Format
|
||||
read.1: mov %ah,%al # Format
|
||||
mov $read_err,%di # error
|
||||
call hex8 # code
|
||||
mov $msg_read,%si # Set the error message and
|
||||
@ -250,36 +209,26 @@ putstr.0: mov $0x7,%bx # Page:attribute
|
||||
putstr: lodsb # Get char
|
||||
testb %al,%al # End of string?
|
||||
jne putstr.0 # No
|
||||
|
||||
ret # To caller
|
||||
/*
|
||||
* Reads sectors from the disk. If EDD is enabled, then check if it is
|
||||
* installed and use it if it is. If it is not installed or not enabled, then
|
||||
* fall back to using CHS. Since we use a LBA, if we are using CHS, we have to
|
||||
* fetch the drive parameters from the BIOS and divide it out ourselves.
|
||||
* Call with:
|
||||
*
|
||||
* %dl - byte - drive number
|
||||
* stack - 10 bytes - EDD Packet
|
||||
* Check to see if the disk supports EDD. zfsboot requires EDD and does not
|
||||
* support older C/H/S disk I/O.
|
||||
*/
|
||||
read: cmpb $0x80,%dl # Hard drive?
|
||||
jb read.1 # No, use CHS
|
||||
check_edd: cmpb $0x80,%dl # Hard drive?
|
||||
jb check_edd.1 # No, fail to boot
|
||||
mov $0x55aa,%bx # Magic
|
||||
push %dx # Save
|
||||
movb $0x41,%ah # BIOS: Check
|
||||
int $0x13 # extensions present
|
||||
pop %dx # Restore
|
||||
jc read.1 # If error, use CHS
|
||||
jc check_edd.1 # If error, fail
|
||||
cmp $0xaa55,%bx # Magic?
|
||||
jne read.1 # No, so use CHS
|
||||
jne check_edd.1 # No, so fail
|
||||
testb $0x1,%cl # Packet interface?
|
||||
jz read.1 # No, so use CHS
|
||||
mov %bp,%si # Disk packet
|
||||
movb $0x42,%ah # BIOS: Extended
|
||||
int $0x13 # read
|
||||
retw # To caller
|
||||
read.1: mov $msg_chs,%si
|
||||
jmp error
|
||||
|
||||
jz check_edd.1 # No, so fail
|
||||
ret # EDD ok, keep booting
|
||||
check_edd.1: mov $msg_chs,%si # Warn that CHS is
|
||||
jmp error # unsupported and fail
|
||||
/*
|
||||
* AL to hex, saving the result to [EDI].
|
||||
*/
|
||||
|
@ -20,6 +20,7 @@
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011 by Delphix. All rights reserved.
|
||||
*/
|
||||
|
||||
/* Portions Copyright 2010 Robert Milkowski */
|
||||
@ -311,6 +312,9 @@ zfs_prop_init(void)
|
||||
zprop_register_number(ZFS_PROP_COMPRESSRATIO, "compressratio", 0,
|
||||
PROP_READONLY, ZFS_TYPE_DATASET,
|
||||
"<1.00x or higher if compressed>", "RATIO");
|
||||
zprop_register_number(ZFS_PROP_REFRATIO, "refcompressratio", 0,
|
||||
PROP_READONLY, ZFS_TYPE_DATASET,
|
||||
"<1.00x or higher if compressed>", "REFRATIO");
|
||||
zprop_register_number(ZFS_PROP_VOLBLOCKSIZE, "volblocksize",
|
||||
ZVOL_DEFAULT_BLOCKSIZE, PROP_ONETIME,
|
||||
ZFS_TYPE_VOLUME, "512 to 128k, power of 2", "VOLBLOCK");
|
||||
|
@ -20,6 +20,7 @@
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011 by Delphix. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <sys/dmu_objset.h>
|
||||
@ -2150,7 +2151,7 @@ dsl_dataset_sync(dsl_dataset_t *ds, zio_t *zio, dmu_tx_t *tx)
|
||||
void
|
||||
dsl_dataset_stats(dsl_dataset_t *ds, nvlist_t *nv)
|
||||
{
|
||||
uint64_t refd, avail, uobjs, aobjs;
|
||||
uint64_t refd, avail, uobjs, aobjs, ratio;
|
||||
|
||||
dsl_dir_stats(ds->ds_dir, nv);
|
||||
|
||||
@ -2177,6 +2178,11 @@ dsl_dataset_stats(dsl_dataset_t *ds, nvlist_t *nv)
|
||||
dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_DEFER_DESTROY,
|
||||
DS_IS_DEFER_DESTROY(ds) ? 1 : 0);
|
||||
|
||||
ratio = ds->ds_phys->ds_compressed_bytes == 0 ? 100 :
|
||||
(ds->ds_phys->ds_uncompressed_bytes * 100 /
|
||||
ds->ds_phys->ds_compressed_bytes);
|
||||
dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_REFRATIO, ratio);
|
||||
|
||||
if (ds->ds_phys->ds_next_snap_obj) {
|
||||
/*
|
||||
* This is a snapshot; override the dd's space used with
|
||||
@ -2184,10 +2190,7 @@ dsl_dataset_stats(dsl_dataset_t *ds, nvlist_t *nv)
|
||||
*/
|
||||
dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USED,
|
||||
ds->ds_phys->ds_unique_bytes);
|
||||
dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_COMPRESSRATIO,
|
||||
ds->ds_phys->ds_compressed_bytes == 0 ? 100 :
|
||||
(ds->ds_phys->ds_uncompressed_bytes * 100 /
|
||||
ds->ds_phys->ds_compressed_bytes));
|
||||
dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_COMPRESSRATIO, ratio);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,9 +71,16 @@
|
||||
* 1<<zfs_vdev_cache_bshift byte reads by the vdev_cache (aka software
|
||||
* track buffer). At most zfs_vdev_cache_size bytes will be kept in each
|
||||
* vdev's vdev_cache.
|
||||
*
|
||||
* TODO: Note that with the current ZFS code, it turns out that the
|
||||
* vdev cache is not helpful, and in some cases actually harmful. It
|
||||
* is better if we disable this. Once some time has passed, we should
|
||||
* actually remove this to simplify the code. For now we just disable
|
||||
* it by setting the zfs_vdev_cache_size to zero. Note that Solaris 11
|
||||
* has made these same changes.
|
||||
*/
|
||||
int zfs_vdev_cache_max = 1<<14; /* 16KB */
|
||||
int zfs_vdev_cache_size = 10ULL << 20; /* 10MB */
|
||||
int zfs_vdev_cache_size = 0;
|
||||
int zfs_vdev_cache_bshift = 16;
|
||||
|
||||
#define VCBS (1 << zfs_vdev_cache_bshift) /* 64KB */
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011 by Delphix. All rights reserved.
|
||||
*/
|
||||
|
||||
/* Portions Copyright 2010 Robert Milkowski */
|
||||
@ -124,6 +125,7 @@ typedef enum {
|
||||
ZFS_PROP_DEDUP,
|
||||
ZFS_PROP_MLSLABEL,
|
||||
ZFS_PROP_SYNC,
|
||||
ZFS_PROP_REFRATIO,
|
||||
ZFS_NUM_PROPS
|
||||
} zfs_prop_t;
|
||||
|
||||
|
@ -386,14 +386,14 @@ contrib/pf/net/pf_if.c optional pf inet \
|
||||
compile-with "${NORMAL_C} -I$S/contrib/pf"
|
||||
contrib/pf/net/pf_ioctl.c optional pf inet \
|
||||
compile-with "${NORMAL_C} -I$S/contrib/pf"
|
||||
contrib/pf/net/pf_lb.c optional pf inet \
|
||||
compile-with "${NORMAL_C} -I$S/contrib/pf"
|
||||
contrib/pf/net/pf_norm.c optional pf inet \
|
||||
compile-with "${NORMAL_C} -I$S/contrib/pf"
|
||||
contrib/pf/net/pf_osfp.c optional pf inet \
|
||||
compile-with "${NORMAL_C} -I$S/contrib/pf"
|
||||
contrib/pf/net/pf_ruleset.c optional pf inet \
|
||||
compile-with "${NORMAL_C} -I$S/contrib/pf"
|
||||
contrib/pf/net/pf_subr.c optional pf inet \
|
||||
compile-with "${NORMAL_C} -I$S/contrib/pf"
|
||||
contrib/pf/net/pf_table.c optional pf inet \
|
||||
compile-with "${NORMAL_C} -I$S/contrib/pf"
|
||||
contrib/pf/netinet/in4_cksum.c optional pf inet
|
||||
|
@ -514,11 +514,9 @@ mark_ecn(struct mbuf *m, struct altq_pktattr *pktattr, int flags)
|
||||
struct mbuf *m0;
|
||||
struct pf_mtag *at;
|
||||
void *hdr;
|
||||
int af;
|
||||
|
||||
at = pf_find_mtag(m);
|
||||
if (at != NULL) {
|
||||
af = at->af;
|
||||
hdr = at->hdr;
|
||||
#ifdef ALTQ3_COMPAT
|
||||
} else if (pktattr != NULL) {
|
||||
@ -528,9 +526,6 @@ mark_ecn(struct mbuf *m, struct altq_pktattr *pktattr, int flags)
|
||||
} else
|
||||
return (0);
|
||||
|
||||
if (af != AF_INET && af != AF_INET6)
|
||||
return (0);
|
||||
|
||||
/* verify that pattr_hdr is within the mbuf data */
|
||||
for (m0 = m; m0 != NULL; m0 = m0->m_next)
|
||||
if (((caddr_t)hdr >= m0->m_data) &&
|
||||
@ -541,8 +536,8 @@ mark_ecn(struct mbuf *m, struct altq_pktattr *pktattr, int flags)
|
||||
return (0);
|
||||
}
|
||||
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
switch (((struct ip *)hdr)->ip_v) {
|
||||
case IPVERSION:
|
||||
if (flags & REDF_ECN4) {
|
||||
struct ip *ip = hdr;
|
||||
u_int8_t otos;
|
||||
@ -575,7 +570,7 @@ mark_ecn(struct mbuf *m, struct altq_pktattr *pktattr, int flags)
|
||||
}
|
||||
break;
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
case (IPV6_VERSION >> 4):
|
||||
if (flags & REDF_ECN6) {
|
||||
struct ip6_hdr *ip6 = hdr;
|
||||
u_int32_t flowlabel;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: if_pflog.c,v 1.22 2006/12/15 09:31:20 otto Exp $ */
|
||||
/* $OpenBSD: if_pflog.c,v 1.26 2007/10/18 21:58:18 mpf Exp $ */
|
||||
/*
|
||||
* The authors of this code are John Ioannidis (ji@tla.org),
|
||||
* Angelos D. Keromytis (kermit@csd.uch.gr) and
|
||||
@ -99,11 +99,11 @@ __FBSDID("$FreeBSD$");
|
||||
#include <net/pfvar.h>
|
||||
#include <net/if_pflog.h>
|
||||
|
||||
#ifdef INET
|
||||
#ifdef __FreeBSD__
|
||||
#ifdef INET
|
||||
#include <machine/in_cksum.h>
|
||||
#endif
|
||||
#endif
|
||||
#endif /* INET */
|
||||
#endif /* __FreeBSD__ */
|
||||
|
||||
#define PFLOGMTU (32768 + MHLEN + MLEN)
|
||||
|
||||
@ -115,7 +115,11 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
void pflogattach(int);
|
||||
int pflogoutput(struct ifnet *, struct mbuf *, struct sockaddr *,
|
||||
struct route *);
|
||||
#ifdef __FreeBSD__
|
||||
struct route *);
|
||||
#else
|
||||
struct rtentry *);
|
||||
#endif
|
||||
int pflogioctl(struct ifnet *, u_long, caddr_t);
|
||||
void pflogstart(struct ifnet *);
|
||||
#ifdef __FreeBSD__
|
||||
@ -128,7 +132,7 @@ int pflog_clone_destroy(struct ifnet *);
|
||||
|
||||
LIST_HEAD(, pflog_softc) pflogif_list;
|
||||
#ifdef __FreeBSD__
|
||||
IFC_SIMPLE_DECLARE(pflog, 1);
|
||||
IFC_SIMPLE_DECLARE(pflog, 1);
|
||||
#else
|
||||
struct if_clone pflog_cloner =
|
||||
IF_CLONE_INITIALIZER("pflog", pflog_clone_create, pflog_clone_destroy);
|
||||
@ -136,10 +140,6 @@ struct if_clone pflog_cloner =
|
||||
|
||||
struct ifnet *pflogifs[PFLOGIFS_MAX]; /* for fast access */
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
extern int ifqmaxlen;
|
||||
#endif
|
||||
|
||||
void
|
||||
pflogattach(int npflog)
|
||||
{
|
||||
@ -147,9 +147,6 @@ pflogattach(int npflog)
|
||||
LIST_INIT(&pflogif_list);
|
||||
for (i = 0; i < PFLOGIFS_MAX; i++)
|
||||
pflogifs[i] = NULL;
|
||||
#ifndef __FreeBSD__
|
||||
(void) pflog_clone_create(&pflog_cloner, 0);
|
||||
#endif
|
||||
if_clone_attach(&pflog_cloner);
|
||||
}
|
||||
|
||||
@ -168,9 +165,9 @@ pflog_clone_create(struct if_clone *ifc, int unit)
|
||||
if (unit >= PFLOGIFS_MAX)
|
||||
return (EINVAL);
|
||||
|
||||
if ((pflogif = malloc(sizeof(*pflogif), M_DEVBUF, M_NOWAIT)) == NULL)
|
||||
if ((pflogif = malloc(sizeof(*pflogif),
|
||||
M_DEVBUF, M_NOWAIT|M_ZERO)) == NULL)
|
||||
return (ENOMEM);
|
||||
bzero(pflogif, sizeof(*pflogif));
|
||||
|
||||
pflogif->sc_unit = unit;
|
||||
#ifdef __FreeBSD__
|
||||
@ -209,6 +206,7 @@ pflog_clone_create(struct if_clone *ifc, int unit)
|
||||
|
||||
s = splnet();
|
||||
#ifdef __FreeBSD__
|
||||
/* XXX: Why pf(4) lock?! Better add a pflog lock?! */
|
||||
PF_LOCK();
|
||||
#endif
|
||||
LIST_INSERT_HEAD(&pflogif_list, pflogif, sc_list);
|
||||
@ -289,7 +287,11 @@ pflogstart(struct ifnet *ifp)
|
||||
|
||||
int
|
||||
pflogoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
|
||||
struct route *ro)
|
||||
#ifdef __FreeBSD__
|
||||
struct route *rt)
|
||||
#else
|
||||
struct rtentry *rt)
|
||||
#endif
|
||||
{
|
||||
m_freem(m);
|
||||
return (0);
|
||||
@ -300,9 +302,6 @@ int
|
||||
pflogioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
{
|
||||
switch (cmd) {
|
||||
case SIOCSIFADDR:
|
||||
case SIOCAIFADDR:
|
||||
case SIOCSIFDSTADDR:
|
||||
case SIOCSIFFLAGS:
|
||||
#ifdef __FreeBSD__
|
||||
if (ifp->if_flags & IFF_UP)
|
||||
@ -317,7 +316,7 @@ pflogioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
return (EINVAL);
|
||||
return (ENOTTY);
|
||||
}
|
||||
|
||||
return (0);
|
||||
@ -333,7 +332,7 @@ pflog_packet(struct pfi_kif *kif, struct mbuf *m, sa_family_t af, u_int8_t dir,
|
||||
struct pfloghdr hdr;
|
||||
|
||||
if (kif == NULL || m == NULL || rm == NULL || pd == NULL)
|
||||
return (-1);
|
||||
return ( 1);
|
||||
|
||||
if ((ifn = pflogifs[rm->logif]) == NULL || !ifn->if_bpf)
|
||||
return (0);
|
||||
@ -347,7 +346,7 @@ pflog_packet(struct pfi_kif *kif, struct mbuf *m, sa_family_t af, u_int8_t dir,
|
||||
|
||||
if (am == NULL) {
|
||||
hdr.rulenr = htonl(rm->nr);
|
||||
hdr.subrulenr = -1;
|
||||
hdr.subrulenr = 1;
|
||||
} else {
|
||||
hdr.rulenr = htonl(am->nr);
|
||||
hdr.subrulenr = htonl(rm->nr);
|
||||
@ -357,11 +356,11 @@ pflog_packet(struct pfi_kif *kif, struct mbuf *m, sa_family_t af, u_int8_t dir,
|
||||
}
|
||||
if (rm->log & PF_LOG_SOCKET_LOOKUP && !pd->lookup.done)
|
||||
#ifdef __FreeBSD__
|
||||
/*
|
||||
/*
|
||||
* XXX: This should not happen as we force an early lookup
|
||||
* via debug.pfugidhack
|
||||
*/
|
||||
; /* empty */
|
||||
; /* empty */
|
||||
#else
|
||||
pd->lookup.done = pf_socket_lookup(dir, pd);
|
||||
#endif
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* $FreeBSD$ */
|
||||
/* $OpenBSD: if_pflog.h,v 1.14 2006/10/25 11:27:01 henning Exp $ */
|
||||
/* $OpenBSD: if_pflog.h,v 1.13 2006/10/23 12:46:09 henning Exp $ */
|
||||
/*
|
||||
* Copyright 2001 Niels Provos <provos@citi.umich.edu>
|
||||
* All rights reserved.
|
||||
@ -26,11 +25,10 @@
|
||||
*/
|
||||
|
||||
#ifndef _NET_IF_PFLOG_H_
|
||||
#define _NET_IF_PFLOG_H_
|
||||
#define _NET_IF_PFLOG_H_
|
||||
|
||||
#define PFLOGIFS_MAX 16
|
||||
|
||||
#ifdef _KERNEL
|
||||
struct pflog_softc {
|
||||
#ifdef __FreeBSD__
|
||||
struct ifnet *sc_ifp; /* the interface pointer */
|
||||
@ -40,9 +38,8 @@ struct pflog_softc {
|
||||
int sc_unit;
|
||||
LIST_ENTRY(pflog_softc) sc_list;
|
||||
};
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#define PFLOG_RULESET_NAME_SIZE 16
|
||||
#define PFLOG_RULESET_NAME_SIZE 16
|
||||
|
||||
struct pfloghdr {
|
||||
u_int8_t length;
|
||||
@ -61,9 +58,9 @@ struct pfloghdr {
|
||||
u_int8_t pad[3];
|
||||
};
|
||||
|
||||
#define PFLOG_HDRLEN sizeof(struct pfloghdr)
|
||||
#define PFLOG_HDRLEN sizeof(struct pfloghdr)
|
||||
/* minus pad, also used as a signature */
|
||||
#define PFLOG_REAL_HDRLEN offsetof(struct pfloghdr, pad)
|
||||
#define PFLOG_REAL_HDRLEN offsetof(struct pfloghdr, pad)
|
||||
|
||||
/* XXX remove later when old format logs are no longer needed */
|
||||
struct old_pfloghdr {
|
||||
@ -74,23 +71,24 @@ struct old_pfloghdr {
|
||||
u_short action;
|
||||
u_short dir;
|
||||
};
|
||||
#define OLD_PFLOG_HDRLEN sizeof(struct old_pfloghdr)
|
||||
#define OLD_PFLOG_HDRLEN sizeof(struct old_pfloghdr)
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
struct pf_rule;
|
||||
struct pf_ruleset;
|
||||
struct pfi_kif;
|
||||
struct pf_pdesc;
|
||||
|
||||
#if 0
|
||||
typedef int pflog_packet_t(struct pfi_kif *, struct mbuf *, sa_family_t,
|
||||
u_int8_t, u_int8_t, struct pf_rule *, struct pf_rule *,
|
||||
struct pf_ruleset *, struct pf_pdesc *);
|
||||
extern pflog_packet_t *pflog_packet_ptr;
|
||||
#define PFLOG_PACKET(i,x,a,b,c,d,e,f,g,h) do { \
|
||||
if (pflog_packet_ptr != NULL) \
|
||||
pflog_packet_ptr(i,a,b,c,d,e,f,g,h); \
|
||||
#endif
|
||||
#define PFLOG_PACKET(i,x,a,b,c,d,e,f,g,h) do { \
|
||||
if (pflog_packet_ptr != NULL) \
|
||||
pflog_packet_ptr(i,a,b,c,d,e,f,g,h); \
|
||||
} while (0)
|
||||
#else /* ! __FreeBSD__ */
|
||||
#if NPFLOG > 0
|
||||
@ -98,6 +96,6 @@ extern pflog_packet_t *pflog_packet_ptr;
|
||||
#else
|
||||
#define PFLOG_PACKET(i,x,a,b,c,d,e,f,g,h) ((void)0)
|
||||
#endif /* NPFLOG > 0 */
|
||||
#endif /* __FreeBSD__ */
|
||||
#endif
|
||||
#endif /* _KERNEL */
|
||||
#endif /* _NET_IF_PFLOG_H_ */
|
||||
|
126
sys/contrib/pf/net/if_pflow.h
Normal file
126
sys/contrib/pf/net/if_pflow.h
Normal file
@ -0,0 +1,126 @@
|
||||
/* $OpenBSD: if_pflow.h,v 1.5 2009/02/27 11:09:36 gollo Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Henning Brauer <henning@openbsd.org>
|
||||
* Copyright (c) 2008 Joerg Goltermann <jg@osn.de>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _NET_IF_PFLOW_H_
|
||||
#define _NET_IF_PFLOW_H_
|
||||
|
||||
#define PFLOW_ID_LEN sizeof(u_int64_t)
|
||||
|
||||
#define PFLOW_MAXFLOWS 30
|
||||
#define PFLOW_VERSION 5
|
||||
#define PFLOW_ENGINE_TYPE 42
|
||||
#define PFLOW_ENGINE_ID 42
|
||||
#define PFLOW_MAXBYTES 0xffffffff
|
||||
#define PFLOW_TIMEOUT 30
|
||||
|
||||
struct pflow_flow {
|
||||
u_int32_t src_ip;
|
||||
u_int32_t dest_ip;
|
||||
u_int32_t nexthop_ip;
|
||||
u_int16_t if_index_in;
|
||||
u_int16_t if_index_out;
|
||||
u_int32_t flow_packets;
|
||||
u_int32_t flow_octets;
|
||||
u_int32_t flow_start;
|
||||
u_int32_t flow_finish;
|
||||
u_int16_t src_port;
|
||||
u_int16_t dest_port;
|
||||
u_int8_t pad1;
|
||||
u_int8_t tcp_flags;
|
||||
u_int8_t protocol;
|
||||
u_int8_t tos;
|
||||
u_int16_t src_as;
|
||||
u_int16_t dest_as;
|
||||
u_int8_t src_mask;
|
||||
u_int8_t dest_mask;
|
||||
u_int16_t pad2;
|
||||
} __packed;
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
extern int pflow_ok;
|
||||
|
||||
struct pflow_softc {
|
||||
struct ifnet sc_if;
|
||||
struct ifnet *sc_pflow_ifp;
|
||||
|
||||
unsigned int sc_count;
|
||||
unsigned int sc_maxcount;
|
||||
u_int64_t sc_gcounter;
|
||||
struct ip_moptions sc_imo;
|
||||
#ifdef __FreeBSD__
|
||||
struct callout sc_tmo;
|
||||
#else
|
||||
struct timeout sc_tmo;
|
||||
#endif
|
||||
struct in_addr sc_sender_ip;
|
||||
u_int16_t sc_sender_port;
|
||||
struct in_addr sc_receiver_ip;
|
||||
u_int16_t sc_receiver_port;
|
||||
struct mbuf *sc_mbuf; /* current cumulative mbuf */
|
||||
SLIST_ENTRY(pflow_softc) sc_next;
|
||||
};
|
||||
|
||||
extern struct pflow_softc *pflowif;
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
struct pflow_header {
|
||||
u_int16_t version;
|
||||
u_int16_t count;
|
||||
u_int32_t uptime_ms;
|
||||
u_int32_t time_sec;
|
||||
u_int32_t time_nanosec;
|
||||
u_int32_t flow_sequence;
|
||||
u_int8_t engine_type;
|
||||
u_int8_t engine_id;
|
||||
u_int8_t reserved1;
|
||||
u_int8_t reserved2;
|
||||
} __packed;
|
||||
|
||||
#define PFLOW_HDRLEN sizeof(struct pflow_header)
|
||||
|
||||
struct pflowstats {
|
||||
u_int64_t pflow_flows;
|
||||
u_int64_t pflow_packets;
|
||||
u_int64_t pflow_onomem;
|
||||
u_int64_t pflow_oerrors;
|
||||
};
|
||||
|
||||
/*
|
||||
* Configuration structure for SIOCSETPFLOW SIOCGETPFLOW
|
||||
*/
|
||||
struct pflowreq {
|
||||
struct in_addr sender_ip;
|
||||
struct in_addr receiver_ip;
|
||||
u_int16_t receiver_port;
|
||||
u_int16_t addrmask;
|
||||
#define PFLOW_MASK_SRCIP 0x01
|
||||
#define PFLOW_MASK_DSTIP 0x02
|
||||
#define PFLOW_MASK_DSTPRT 0x04
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
int export_pflow(struct pf_state *);
|
||||
int pflow_sysctl(int *, u_int, void *, size_t *, void *, size_t);
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* _NET_IF_PFLOW_H_ */
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,4 @@
|
||||
/* $FreeBSD$ */
|
||||
/* $OpenBSD: if_pfsync.h,v 1.30 2006/10/31 14:49:01 henning Exp $ */
|
||||
/* $OpenBSD: if_pfsync.h,v 1.35 2008/06/29 08:42:15 mcbride Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Michael Shalayeff
|
||||
@ -27,227 +26,217 @@
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 David Gwynne <dlg@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _NET_IF_PFSYNC_H_
|
||||
#define _NET_IF_PFSYNC_H_
|
||||
#define _NET_IF_PFSYNC_H_
|
||||
|
||||
#define PFSYNC_VERSION 5
|
||||
#define PFSYNC_DFLTTL 255
|
||||
|
||||
#define PFSYNC_ID_LEN sizeof(u_int64_t)
|
||||
|
||||
struct pfsync_state_scrub {
|
||||
u_int16_t pfss_flags;
|
||||
u_int8_t pfss_ttl; /* stashed TTL */
|
||||
#define PFSYNC_SCRUB_FLAG_VALID 0x01
|
||||
u_int8_t scrub_flag;
|
||||
u_int32_t pfss_ts_mod; /* timestamp modulation */
|
||||
} __packed;
|
||||
|
||||
struct pfsync_state_host {
|
||||
struct pf_addr addr;
|
||||
u_int16_t port;
|
||||
u_int16_t pad[3];
|
||||
} __packed;
|
||||
|
||||
struct pfsync_state_peer {
|
||||
struct pfsync_state_scrub scrub; /* state is scrubbed */
|
||||
u_int32_t seqlo; /* Max sequence number sent */
|
||||
u_int32_t seqhi; /* Max the other end ACKd + win */
|
||||
u_int32_t seqdiff; /* Sequence number modulator */
|
||||
u_int16_t max_win; /* largest window (pre scaling) */
|
||||
u_int16_t mss; /* Maximum segment size option */
|
||||
u_int8_t state; /* active state level */
|
||||
u_int8_t wscale; /* window scaling factor */
|
||||
u_int8_t pad[6];
|
||||
} __packed;
|
||||
|
||||
struct pfsync_state {
|
||||
u_int32_t id[2];
|
||||
char ifname[IFNAMSIZ];
|
||||
struct pfsync_state_host lan;
|
||||
struct pfsync_state_host gwy;
|
||||
struct pfsync_state_host ext;
|
||||
struct pfsync_state_peer src;
|
||||
struct pfsync_state_peer dst;
|
||||
struct pf_addr rt_addr;
|
||||
u_int32_t rule;
|
||||
u_int32_t anchor;
|
||||
u_int32_t nat_rule;
|
||||
u_int32_t creation;
|
||||
u_int32_t expire;
|
||||
u_int32_t packets[2][2];
|
||||
u_int32_t bytes[2][2];
|
||||
u_int32_t creatorid;
|
||||
sa_family_t af;
|
||||
u_int8_t proto;
|
||||
u_int8_t direction;
|
||||
u_int8_t log;
|
||||
u_int8_t state_flags;
|
||||
u_int8_t timeout;
|
||||
u_int8_t sync_flags;
|
||||
u_int8_t updates;
|
||||
} __packed;
|
||||
|
||||
#define PFSYNC_FLAG_COMPRESS 0x01
|
||||
#define PFSYNC_FLAG_STALE 0x02
|
||||
|
||||
#ifdef PFSYNC_TDB
|
||||
struct pfsync_tdb {
|
||||
u_int32_t spi;
|
||||
union sockaddr_union dst;
|
||||
u_int32_t rpl;
|
||||
u_int64_t cur_bytes;
|
||||
u_int8_t sproto;
|
||||
u_int8_t updates;
|
||||
u_int8_t pad[2];
|
||||
} __packed;
|
||||
#endif
|
||||
|
||||
struct pfsync_state_upd {
|
||||
u_int32_t id[2];
|
||||
struct pfsync_state_peer src;
|
||||
struct pfsync_state_peer dst;
|
||||
u_int32_t creatorid;
|
||||
u_int32_t expire;
|
||||
u_int8_t timeout;
|
||||
u_int8_t updates;
|
||||
u_int8_t pad[6];
|
||||
} __packed;
|
||||
|
||||
struct pfsync_state_del {
|
||||
u_int32_t id[2];
|
||||
u_int32_t creatorid;
|
||||
struct {
|
||||
u_int8_t state;
|
||||
} src;
|
||||
struct {
|
||||
u_int8_t state;
|
||||
} dst;
|
||||
u_int8_t pad[2];
|
||||
} __packed;
|
||||
|
||||
struct pfsync_state_upd_req {
|
||||
u_int32_t id[2];
|
||||
u_int32_t creatorid;
|
||||
u_int32_t pad;
|
||||
} __packed;
|
||||
|
||||
struct pfsync_state_clr {
|
||||
char ifname[IFNAMSIZ];
|
||||
u_int32_t creatorid;
|
||||
u_int32_t pad;
|
||||
} __packed;
|
||||
|
||||
struct pfsync_state_bus {
|
||||
u_int32_t creatorid;
|
||||
u_int32_t endtime;
|
||||
u_int8_t status;
|
||||
#define PFSYNC_BUS_START 1
|
||||
#define PFSYNC_BUS_END 2
|
||||
u_int8_t pad[7];
|
||||
} __packed;
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
union sc_statep {
|
||||
struct pfsync_state *s;
|
||||
struct pfsync_state_upd *u;
|
||||
struct pfsync_state_del *d;
|
||||
struct pfsync_state_clr *c;
|
||||
struct pfsync_state_bus *b;
|
||||
struct pfsync_state_upd_req *r;
|
||||
};
|
||||
|
||||
#ifdef PFSYNC_TDB
|
||||
union sc_tdb_statep {
|
||||
struct pfsync_tdb *t;
|
||||
};
|
||||
#endif
|
||||
|
||||
extern int pfsync_sync_ok;
|
||||
|
||||
struct pfsync_softc {
|
||||
#ifdef __FreeBSD__
|
||||
struct ifnet *sc_ifp;
|
||||
#else
|
||||
struct ifnet sc_if;
|
||||
#endif
|
||||
struct ifnet *sc_sync_ifp;
|
||||
|
||||
struct ip_moptions sc_imo;
|
||||
#ifdef __FreeBSD__
|
||||
struct callout sc_tmo;
|
||||
#ifdef PFSYNC_TDB
|
||||
struct callout sc_tdb_tmo;
|
||||
#endif
|
||||
struct callout sc_bulk_tmo;
|
||||
struct callout sc_bulkfail_tmo;
|
||||
#else
|
||||
struct timeout sc_tmo;
|
||||
struct timeout sc_tdb_tmo;
|
||||
struct timeout sc_bulk_tmo;
|
||||
struct timeout sc_bulkfail_tmo;
|
||||
#endif
|
||||
struct in_addr sc_sync_peer;
|
||||
struct in_addr sc_sendaddr;
|
||||
struct mbuf *sc_mbuf; /* current cumulative mbuf */
|
||||
struct mbuf *sc_mbuf_net; /* current cumulative mbuf */
|
||||
#ifdef PFSYNC_TDB
|
||||
struct mbuf *sc_mbuf_tdb; /* dito for TDB updates */
|
||||
#endif
|
||||
#ifdef __FreeBSD__
|
||||
struct ifqueue sc_ifq;
|
||||
struct task sc_send_task;
|
||||
#endif
|
||||
union sc_statep sc_statep;
|
||||
union sc_statep sc_statep_net;
|
||||
#ifdef PFSYNC_TDB
|
||||
union sc_tdb_statep sc_statep_tdb;
|
||||
#endif
|
||||
u_int32_t sc_ureq_received;
|
||||
u_int32_t sc_ureq_sent;
|
||||
struct pf_state *sc_bulk_send_next;
|
||||
struct pf_state *sc_bulk_terminator;
|
||||
int sc_bulk_tries;
|
||||
int sc_maxcount; /* number of states in mtu */
|
||||
int sc_maxupdates; /* number of updates/state */
|
||||
#ifdef __FreeBSD__
|
||||
eventhandler_tag sc_detachtag;
|
||||
#endif
|
||||
};
|
||||
|
||||
extern struct pfsync_softc *pfsyncif;
|
||||
#endif
|
||||
|
||||
|
||||
struct pfsync_header {
|
||||
u_int8_t version;
|
||||
#define PFSYNC_VERSION 3
|
||||
u_int8_t af;
|
||||
u_int8_t action;
|
||||
#define PFSYNC_ACT_CLR 0 /* clear all states */
|
||||
#define PFSYNC_ACT_INS 1 /* insert state */
|
||||
#define PFSYNC_ACT_UPD 2 /* update state */
|
||||
#define PFSYNC_ACT_DEL 3 /* delete state */
|
||||
#define PFSYNC_ACT_UPD_C 4 /* "compressed" state update */
|
||||
#define PFSYNC_ACT_DEL_C 5 /* "compressed" state delete */
|
||||
#define PFSYNC_ACT_INS_F 6 /* insert fragment */
|
||||
#define PFSYNC_ACT_DEL_F 7 /* delete fragments */
|
||||
#define PFSYNC_ACT_UREQ 8 /* request "uncompressed" state */
|
||||
#define PFSYNC_ACT_BUS 9 /* Bulk Update Status */
|
||||
#define PFSYNC_ACT_TDB_UPD 10 /* TDB replay counter update */
|
||||
#define PFSYNC_ACT_MAX 11
|
||||
u_int8_t count;
|
||||
u_int8_t pf_chksum[PF_MD5_DIGEST_LENGTH];
|
||||
#define PFSYNC_ACT_INS_ACK 2 /* ack of insterted state */
|
||||
#define PFSYNC_ACT_UPD 3 /* update state */
|
||||
#define PFSYNC_ACT_UPD_C 4 /* "compressed" update state */
|
||||
#define PFSYNC_ACT_UPD_REQ 5 /* request "uncompressed" state */
|
||||
#define PFSYNC_ACT_DEL 6 /* delete state */
|
||||
#define PFSYNC_ACT_DEL_C 7 /* "compressed" delete state */
|
||||
#define PFSYNC_ACT_INS_F 8 /* insert fragment */
|
||||
#define PFSYNC_ACT_DEL_F 9 /* delete fragments */
|
||||
#define PFSYNC_ACT_BUS 10 /* bulk update status */
|
||||
#define PFSYNC_ACT_TDB 11 /* TDB replay counter update */
|
||||
#define PFSYNC_ACT_EOF 12 /* end of frame */
|
||||
#define PFSYNC_ACT_MAX 13
|
||||
|
||||
#define PFSYNC_ACTIONS "CLR ST", \
|
||||
"INS ST", \
|
||||
"INS ST ACK", \
|
||||
"UPD ST", \
|
||||
"UPD ST COMP", \
|
||||
"UPD ST REQ", \
|
||||
"DEL ST", \
|
||||
"DEL ST COMP", \
|
||||
"INS FR", \
|
||||
"DEL FR", \
|
||||
"BULK UPD STAT", \
|
||||
"TDB UPD", \
|
||||
"EOF"
|
||||
|
||||
#define PFSYNC_HMAC_LEN 20
|
||||
|
||||
/*
|
||||
* A pfsync frame is built from a header followed by several sections which
|
||||
* are all prefixed with their own subheaders. Frames must be terminated with
|
||||
* an EOF subheader.
|
||||
*
|
||||
* | ... |
|
||||
* | IP header |
|
||||
* +============================+
|
||||
* | pfsync_header |
|
||||
* +----------------------------+
|
||||
* | pfsync_subheader |
|
||||
* +----------------------------+
|
||||
* | first action fields |
|
||||
* | ... |
|
||||
* +----------------------------+
|
||||
* | pfsync_subheader |
|
||||
* +----------------------------+
|
||||
* | second action fields |
|
||||
* | ... |
|
||||
* +----------------------------+
|
||||
* | EOF pfsync_subheader |
|
||||
* +----------------------------+
|
||||
* | HMAC |
|
||||
* +============================+
|
||||
*/
|
||||
|
||||
/*
|
||||
* Frame header
|
||||
*/
|
||||
|
||||
struct pfsync_header {
|
||||
u_int8_t version;
|
||||
u_int8_t _pad;
|
||||
u_int16_t len;
|
||||
u_int8_t pfcksum[PF_MD5_DIGEST_LENGTH];
|
||||
} __packed;
|
||||
|
||||
#define PFSYNC_BULKPACKETS 1 /* # of packets per timeout */
|
||||
#define PFSYNC_MAX_BULKTRIES 12
|
||||
#define PFSYNC_HDRLEN sizeof(struct pfsync_header)
|
||||
#define PFSYNC_ACTIONS \
|
||||
"CLR ST", "INS ST", "UPD ST", "DEL ST", \
|
||||
"UPD ST COMP", "DEL ST COMP", "INS FR", "DEL FR", \
|
||||
"UPD REQ", "BLK UPD STAT", "TDB UPD"
|
||||
/*
|
||||
* Frame region subheader
|
||||
*/
|
||||
|
||||
#define PFSYNC_DFLTTL 255
|
||||
struct pfsync_subheader {
|
||||
u_int8_t action;
|
||||
u_int8_t _pad;
|
||||
u_int16_t count;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* CLR
|
||||
*/
|
||||
|
||||
struct pfsync_clr {
|
||||
char ifname[IFNAMSIZ];
|
||||
u_int32_t creatorid;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* INS, UPD, DEL
|
||||
*/
|
||||
|
||||
/* these use struct pfsync_state in pfvar.h */
|
||||
|
||||
/*
|
||||
* INS_ACK
|
||||
*/
|
||||
|
||||
struct pfsync_ins_ack {
|
||||
u_int64_t id;
|
||||
u_int32_t creatorid;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* UPD_C
|
||||
*/
|
||||
|
||||
struct pfsync_upd_c {
|
||||
u_int64_t id;
|
||||
struct pfsync_state_peer src;
|
||||
struct pfsync_state_peer dst;
|
||||
u_int32_t creatorid;
|
||||
u_int32_t expire;
|
||||
u_int8_t timeout;
|
||||
u_int8_t _pad[3];
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* UPD_REQ
|
||||
*/
|
||||
|
||||
struct pfsync_upd_req {
|
||||
u_int64_t id;
|
||||
u_int32_t creatorid;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* DEL_C
|
||||
*/
|
||||
|
||||
struct pfsync_del_c {
|
||||
u_int64_t id;
|
||||
u_int32_t creatorid;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* INS_F, DEL_F
|
||||
*/
|
||||
|
||||
/* not implemented (yet) */
|
||||
|
||||
/*
|
||||
* BUS
|
||||
*/
|
||||
|
||||
struct pfsync_bus {
|
||||
u_int32_t creatorid;
|
||||
u_int32_t endtime;
|
||||
u_int8_t status;
|
||||
#define PFSYNC_BUS_START 1
|
||||
#define PFSYNC_BUS_END 2
|
||||
u_int8_t _pad[3];
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* TDB
|
||||
*/
|
||||
|
||||
struct pfsync_tdb {
|
||||
u_int32_t spi;
|
||||
union sockaddr_union dst;
|
||||
u_int32_t rpl;
|
||||
u_int64_t cur_bytes;
|
||||
u_int8_t sproto;
|
||||
u_int8_t updates;
|
||||
u_int8_t _pad[2];
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* EOF
|
||||
*/
|
||||
|
||||
struct pfsync_eof {
|
||||
u_int8_t hmac[PFSYNC_HMAC_LEN];
|
||||
} __packed;
|
||||
|
||||
#define PFSYNC_HDRLEN sizeof(struct pfsync_header)
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Names for PFSYNC sysctl objects
|
||||
*/
|
||||
#define PFSYNCCTL_STATS 1 /* PFSYNC stats */
|
||||
#define PFSYNCCTL_MAXID 2
|
||||
|
||||
#define PFSYNCCTL_NAMES { \
|
||||
{ 0, 0 }, \
|
||||
{ "stats", CTLTYPE_STRUCT }, \
|
||||
}
|
||||
|
||||
struct pfsyncstats {
|
||||
u_int64_t pfsyncs_ipackets; /* total input packets, IPv4 */
|
||||
@ -280,96 +269,56 @@ struct pfsyncreq {
|
||||
};
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#define SIOCSETPFSYNC _IOW('i', 247, struct ifreq)
|
||||
#define SIOCGETPFSYNC _IOWR('i', 248, struct ifreq)
|
||||
#define SIOCSETPFSYNC _IOW('i', 247, struct ifreq)
|
||||
#define SIOCGETPFSYNC _IOWR('i', 248, struct ifreq)
|
||||
#endif
|
||||
|
||||
#define pf_state_peer_hton(s,d) do { \
|
||||
(d)->seqlo = htonl((s)->seqlo); \
|
||||
(d)->seqhi = htonl((s)->seqhi); \
|
||||
(d)->seqdiff = htonl((s)->seqdiff); \
|
||||
(d)->max_win = htons((s)->max_win); \
|
||||
(d)->mss = htons((s)->mss); \
|
||||
(d)->state = (s)->state; \
|
||||
(d)->wscale = (s)->wscale; \
|
||||
if ((s)->scrub) { \
|
||||
(d)->scrub.pfss_flags = \
|
||||
htons((s)->scrub->pfss_flags & PFSS_TIMESTAMP); \
|
||||
(d)->scrub.pfss_ttl = (s)->scrub->pfss_ttl; \
|
||||
(d)->scrub.pfss_ts_mod = htonl((s)->scrub->pfss_ts_mod);\
|
||||
(d)->scrub.scrub_flag = PFSYNC_SCRUB_FLAG_VALID; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define pf_state_peer_ntoh(s,d) do { \
|
||||
(d)->seqlo = ntohl((s)->seqlo); \
|
||||
(d)->seqhi = ntohl((s)->seqhi); \
|
||||
(d)->seqdiff = ntohl((s)->seqdiff); \
|
||||
(d)->max_win = ntohs((s)->max_win); \
|
||||
(d)->mss = ntohs((s)->mss); \
|
||||
(d)->state = (s)->state; \
|
||||
(d)->wscale = (s)->wscale; \
|
||||
if ((s)->scrub.scrub_flag == PFSYNC_SCRUB_FLAG_VALID && \
|
||||
(d)->scrub != NULL) { \
|
||||
(d)->scrub->pfss_flags = \
|
||||
ntohs((s)->scrub.pfss_flags) & PFSS_TIMESTAMP; \
|
||||
(d)->scrub->pfss_ttl = (s)->scrub.pfss_ttl; \
|
||||
(d)->scrub->pfss_ts_mod = ntohl((s)->scrub.pfss_ts_mod);\
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define pf_state_host_hton(s,d) do { \
|
||||
bcopy(&(s)->addr, &(d)->addr, sizeof((d)->addr)); \
|
||||
(d)->port = (s)->port; \
|
||||
} while (0)
|
||||
|
||||
#define pf_state_host_ntoh(s,d) do { \
|
||||
bcopy(&(s)->addr, &(d)->addr, sizeof((d)->addr)); \
|
||||
(d)->port = (s)->port; \
|
||||
} while (0)
|
||||
|
||||
#define pf_state_counter_hton(s,d) do { \
|
||||
d[0] = htonl((s>>32)&0xffffffff); \
|
||||
d[1] = htonl(s&0xffffffff); \
|
||||
} while (0)
|
||||
|
||||
#define pf_state_counter_ntoh(s,d) do { \
|
||||
d = ntohl(s[0]); \
|
||||
d = d<<32; \
|
||||
d += ntohl(s[1]); \
|
||||
} while (0)
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
/*
|
||||
* this shows where a pf state is with respect to the syncing.
|
||||
*/
|
||||
#define PFSYNC_S_INS 0x00
|
||||
#define PFSYNC_S_IACK 0x01
|
||||
#define PFSYNC_S_UPD 0x02
|
||||
#define PFSYNC_S_UPD_C 0x03
|
||||
#define PFSYNC_S_DEL 0x04
|
||||
#define PFSYNC_S_COUNT 0x05
|
||||
|
||||
#define PFSYNC_S_DEFER 0xfe
|
||||
#define PFSYNC_S_NONE 0xff
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
void pfsync_input(struct mbuf *, __unused int);
|
||||
void pfsync_input(struct mbuf *, __unused int);
|
||||
#else
|
||||
void pfsync_input(struct mbuf *, ...);
|
||||
void pfsync_input(struct mbuf *, ...);
|
||||
#endif
|
||||
int pfsync_clear_states(u_int32_t, char *);
|
||||
int pfsync_pack_state(u_int8_t, struct pf_state *, int);
|
||||
#define pfsync_insert_state(st) do { \
|
||||
if ((st->rule.ptr->rule_flag & PFRULE_NOSYNC) || \
|
||||
(st->proto == IPPROTO_PFSYNC)) \
|
||||
st->sync_flags |= PFSTATE_NOSYNC; \
|
||||
else if (!st->sync_flags) \
|
||||
pfsync_pack_state(PFSYNC_ACT_INS, (st), \
|
||||
PFSYNC_FLAG_COMPRESS); \
|
||||
st->sync_flags &= ~PFSTATE_FROMSYNC; \
|
||||
} while (0)
|
||||
#define pfsync_update_state(st) do { \
|
||||
if (!st->sync_flags) \
|
||||
pfsync_pack_state(PFSYNC_ACT_UPD, (st), \
|
||||
PFSYNC_FLAG_COMPRESS); \
|
||||
st->sync_flags &= ~PFSTATE_FROMSYNC; \
|
||||
} while (0)
|
||||
#define pfsync_delete_state(st) do { \
|
||||
if (!st->sync_flags) \
|
||||
pfsync_pack_state(PFSYNC_ACT_DEL, (st), \
|
||||
PFSYNC_FLAG_COMPRESS); \
|
||||
} while (0)
|
||||
#ifdef PFSYNC_TDB
|
||||
int pfsync_update_tdb(struct tdb *, int);
|
||||
int pfsync_sysctl(int *, u_int, void *, size_t *,
|
||||
void *, size_t);
|
||||
|
||||
#define PFSYNC_SI_IOCTL 0x01
|
||||
#define PFSYNC_SI_CKSUM 0x02
|
||||
#define PFSYNC_SI_ACK 0x04
|
||||
int pfsync_state_import(struct pfsync_state *, u_int8_t);
|
||||
#ifndef __FreeBSD__
|
||||
void pfsync_state_export(struct pfsync_state *,
|
||||
struct pf_state *);
|
||||
#endif
|
||||
|
||||
void pfsync_insert_state(struct pf_state *);
|
||||
void pfsync_update_state(struct pf_state *);
|
||||
void pfsync_delete_state(struct pf_state *);
|
||||
void pfsync_clear_states(u_int32_t, const char *);
|
||||
|
||||
#ifdef notyet
|
||||
void pfsync_update_tdb(struct tdb *, int);
|
||||
void pfsync_delete_tdb(struct tdb *);
|
||||
#endif
|
||||
|
||||
int pfsync_defer(struct pf_state *, struct mbuf *);
|
||||
|
||||
int pfsync_up(void);
|
||||
int pfsync_state_in_use(struct pf_state *);
|
||||
#endif
|
||||
|
||||
#endif /* _NET_IF_PFSYNC_H_ */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: pf_if.c,v 1.46 2006/12/13 09:01:59 itojun Exp $ */
|
||||
/* $OpenBSD: pf_if.c,v 1.54 2008/06/14 16:55:28 mk Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 2005 Henning Brauer <henning@openbsd.org>
|
||||
@ -54,6 +54,9 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/device.h>
|
||||
#endif
|
||||
#include <sys/time.h>
|
||||
#ifndef __FreeBSD__
|
||||
#include <sys/pool.h>
|
||||
#endif
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_types.h>
|
||||
@ -73,25 +76,35 @@ __FBSDID("$FreeBSD$");
|
||||
#include <netinet/ip6.h>
|
||||
#endif /* INET6 */
|
||||
|
||||
struct pfi_kif *pfi_all = NULL;
|
||||
struct pfi_statehead pfi_statehead;
|
||||
#ifdef __FreeBSD__
|
||||
uma_zone_t pfi_addr_pl;
|
||||
VNET_DEFINE(struct pfi_kif *, pfi_all);
|
||||
VNET_DEFINE(uma_zone_t, pfi_addr_pl);
|
||||
VNET_DEFINE(struct pfi_ifhead, pfi_ifs);
|
||||
#define V_pfi_ifs VNET(pfi_ifs)
|
||||
VNET_DEFINE(long, pfi_update);
|
||||
#define V_pfi_update VNET(pfi_update)
|
||||
VNET_DEFINE(struct pfr_addr *, pfi_buffer);
|
||||
#define V_pfi_buffer VNET(pfi_buffer)
|
||||
VNET_DEFINE(int, pfi_buffer_cnt);
|
||||
#define V_pfi_buffer_cnt VNET(pfi_buffer_cnt)
|
||||
VNET_DEFINE(int, pfi_buffer_max);
|
||||
#define V_pfi_buffer_max VNET(pfi_buffer_max)
|
||||
#else
|
||||
struct pfi_kif *pfi_all = NULL;
|
||||
struct pool pfi_addr_pl;
|
||||
#endif
|
||||
struct pfi_ifhead pfi_ifs;
|
||||
long pfi_update = 1;
|
||||
struct pfr_addr *pfi_buffer;
|
||||
int pfi_buffer_cnt;
|
||||
int pfi_buffer_max;
|
||||
#endif
|
||||
#ifdef __FreeBSD__
|
||||
eventhandler_tag pfi_attach_cookie = NULL;
|
||||
eventhandler_tag pfi_detach_cookie = NULL;
|
||||
eventhandler_tag pfi_attach_group_cookie = NULL;
|
||||
eventhandler_tag pfi_change_group_cookie = NULL;
|
||||
eventhandler_tag pfi_detach_group_cookie = NULL;
|
||||
eventhandler_tag pfi_ifaddr_event_cookie = NULL;
|
||||
eventhandler_tag pfi_attach_cookie;
|
||||
eventhandler_tag pfi_detach_cookie;
|
||||
eventhandler_tag pfi_attach_group_cookie;
|
||||
eventhandler_tag pfi_change_group_cookie;
|
||||
eventhandler_tag pfi_detach_group_cookie;
|
||||
eventhandler_tag pfi_ifaddr_event_cookie;
|
||||
#endif
|
||||
|
||||
void pfi_kif_update(struct pfi_kif *);
|
||||
@ -107,11 +120,10 @@ int pfi_unmask(void *);
|
||||
#ifdef __FreeBSD__
|
||||
void pfi_attach_ifnet_event(void * __unused, struct ifnet *);
|
||||
void pfi_detach_ifnet_event(void * __unused, struct ifnet *);
|
||||
void pfi_attach_group_event(void * __unused, struct ifg_group *);
|
||||
void pfi_change_group_event(void * __unused, char *);
|
||||
void pfi_detach_group_event(void * __unused, struct ifg_group *);
|
||||
void pfi_attach_group_event(void *, struct ifg_group *);
|
||||
void pfi_change_group_event(void *, char *);
|
||||
void pfi_detach_group_event(void *, struct ifg_group *);
|
||||
void pfi_ifaddr_event(void * __unused, struct ifnet *);
|
||||
|
||||
#endif
|
||||
|
||||
RB_PROTOTYPE(pfi_ifhead, pfi_kif, pfik_tree, pfi_if_compare);
|
||||
@ -123,22 +135,31 @@ RB_GENERATE(pfi_ifhead, pfi_kif, pfik_tree, pfi_if_compare);
|
||||
void
|
||||
pfi_initialize(void)
|
||||
{
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
if (V_pfi_all != NULL) /* already initialized */
|
||||
#else
|
||||
if (pfi_all != NULL) /* already initialized */
|
||||
#endif
|
||||
return;
|
||||
|
||||
TAILQ_INIT(&pfi_statehead);
|
||||
#ifndef __FreeBSD__
|
||||
pool_init(&pfi_addr_pl, sizeof(struct pfi_dynaddr), 0, 0, 0,
|
||||
pool_init(&V_pfi_addr_pl, sizeof(struct pfi_dynaddr), 0, 0, 0,
|
||||
"pfiaddrpl", &pool_allocator_nointr);
|
||||
#endif
|
||||
#ifdef __FreeBSD__
|
||||
V_pfi_buffer_max = 64;
|
||||
V_pfi_buffer = malloc(V_pfi_buffer_max * sizeof(*V_pfi_buffer),
|
||||
PFI_MTYPE, M_WAITOK);
|
||||
|
||||
if ((V_pfi_all = pfi_kif_get(IFG_ALL)) == NULL)
|
||||
#else
|
||||
pfi_buffer_max = 64;
|
||||
pfi_buffer = malloc(pfi_buffer_max * sizeof(*pfi_buffer),
|
||||
PFI_MTYPE, M_WAITOK);
|
||||
|
||||
if ((pfi_all = pfi_kif_get(IFG_ALL)) == NULL)
|
||||
#endif
|
||||
panic("pfi_kif_get for pfi_all failed");
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
struct ifg_group *ifg;
|
||||
struct ifnet *ifp;
|
||||
@ -155,11 +176,11 @@ pfi_initialize(void)
|
||||
pfi_detach_cookie = EVENTHANDLER_REGISTER(ifnet_departure_event,
|
||||
pfi_detach_ifnet_event, NULL, EVENTHANDLER_PRI_ANY);
|
||||
pfi_attach_group_cookie = EVENTHANDLER_REGISTER(group_attach_event,
|
||||
pfi_attach_group_event, NULL, EVENTHANDLER_PRI_ANY);
|
||||
pfi_attach_group_event, curvnet, EVENTHANDLER_PRI_ANY);
|
||||
pfi_change_group_cookie = EVENTHANDLER_REGISTER(group_change_event,
|
||||
pfi_change_group_event, NULL, EVENTHANDLER_PRI_ANY);
|
||||
pfi_change_group_event, curvnet, EVENTHANDLER_PRI_ANY);
|
||||
pfi_detach_group_cookie = EVENTHANDLER_REGISTER(group_detach_event,
|
||||
pfi_detach_group_event, NULL, EVENTHANDLER_PRI_ANY);
|
||||
pfi_detach_group_event, curvnet, EVENTHANDLER_PRI_ANY);
|
||||
pfi_ifaddr_event_cookie = EVENTHANDLER_REGISTER(ifaddr_event,
|
||||
pfi_ifaddr_event, NULL, EVENTHANDLER_PRI_ANY);
|
||||
#endif
|
||||
@ -180,18 +201,18 @@ pfi_cleanup(void)
|
||||
EVENTHANDLER_DEREGISTER(ifaddr_event, pfi_ifaddr_event_cookie);
|
||||
PF_LOCK();
|
||||
|
||||
pfi_all = NULL;
|
||||
while ((p = RB_MIN(pfi_ifhead, &pfi_ifs))) {
|
||||
V_pfi_all = NULL;
|
||||
while ((p = RB_MIN(pfi_ifhead, &V_pfi_ifs))) {
|
||||
if (p->pfik_rules || p->pfik_states) {
|
||||
printf("pfi_cleanup: dangling refs for %s\n",
|
||||
p->pfik_name);
|
||||
}
|
||||
|
||||
RB_REMOVE(pfi_ifhead, &pfi_ifs, p);
|
||||
RB_REMOVE(pfi_ifhead, &V_pfi_ifs, p);
|
||||
free(p, PFI_MTYPE);
|
||||
}
|
||||
|
||||
free(pfi_buffer, PFI_MTYPE);
|
||||
free(V_pfi_buffer, PFI_MTYPE);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -203,18 +224,21 @@ pfi_kif_get(const char *kif_name)
|
||||
|
||||
bzero(&s, sizeof(s));
|
||||
strlcpy(s.pfik_name, kif_name, sizeof(s.pfik_name));
|
||||
#ifdef __FreeBSD__
|
||||
if ((kif = RB_FIND(pfi_ifhead, &V_pfi_ifs, (struct pfi_kif *)&s)) != NULL)
|
||||
#else
|
||||
if ((kif = RB_FIND(pfi_ifhead, &pfi_ifs, (struct pfi_kif *)&s)) != NULL)
|
||||
#endif
|
||||
return (kif);
|
||||
|
||||
/* create new one */
|
||||
#ifdef __FreeBSD__
|
||||
if ((kif = malloc(sizeof(*kif), PFI_MTYPE, M_NOWAIT)) == NULL)
|
||||
if ((kif = malloc(sizeof(*kif), PFI_MTYPE, M_NOWAIT | M_ZERO)) == NULL)
|
||||
#else
|
||||
if ((kif = malloc(sizeof(*kif), PFI_MTYPE, M_DONTWAIT)) == NULL)
|
||||
if ((kif = malloc(sizeof(*kif), PFI_MTYPE, M_DONTWAIT|M_ZERO)) == NULL)
|
||||
#endif
|
||||
return (NULL);
|
||||
|
||||
bzero(kif, sizeof(*kif));
|
||||
strlcpy(kif->pfik_name, kif_name, sizeof(kif->pfik_name));
|
||||
#ifdef __FreeBSD__
|
||||
/*
|
||||
@ -230,7 +254,12 @@ pfi_kif_get(const char *kif_name)
|
||||
#endif
|
||||
TAILQ_INIT(&kif->pfik_dynaddrs);
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
RB_INSERT(pfi_ifhead, &V_pfi_ifs, kif);
|
||||
#else
|
||||
RB_INSERT(pfi_ifhead, &pfi_ifs, kif);
|
||||
#endif
|
||||
|
||||
return (kif);
|
||||
}
|
||||
|
||||
@ -242,8 +271,7 @@ pfi_kif_ref(struct pfi_kif *kif, enum pfi_kif_refs what)
|
||||
kif->pfik_rules++;
|
||||
break;
|
||||
case PFI_KIF_REF_STATE:
|
||||
if (!kif->pfik_states++)
|
||||
TAILQ_INSERT_TAIL(&pfi_statehead, kif, pfik_w_states);
|
||||
kif->pfik_states++;
|
||||
break;
|
||||
default:
|
||||
panic("pfi_kif_ref with unknown type");
|
||||
@ -271,20 +299,27 @@ pfi_kif_unref(struct pfi_kif *kif, enum pfi_kif_refs what)
|
||||
printf("pfi_kif_unref: state refcount <= 0\n");
|
||||
return;
|
||||
}
|
||||
if (!--kif->pfik_states)
|
||||
TAILQ_REMOVE(&pfi_statehead, kif, pfik_w_states);
|
||||
kif->pfik_states--;
|
||||
break;
|
||||
default:
|
||||
panic("pfi_kif_unref with unknown type");
|
||||
}
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
if (kif->pfik_ifp != NULL || kif->pfik_group != NULL || kif == V_pfi_all)
|
||||
#else
|
||||
if (kif->pfik_ifp != NULL || kif->pfik_group != NULL || kif == pfi_all)
|
||||
#endif
|
||||
return;
|
||||
|
||||
if (kif->pfik_rules || kif->pfik_states)
|
||||
return;
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
RB_REMOVE(pfi_ifhead, &V_pfi_ifs, kif);
|
||||
#else
|
||||
RB_REMOVE(pfi_ifhead, &pfi_ifs, kif);
|
||||
#endif
|
||||
free(kif, PFI_MTYPE);
|
||||
}
|
||||
|
||||
@ -312,7 +347,11 @@ pfi_attach_ifnet(struct ifnet *ifp)
|
||||
|
||||
pfi_initialize();
|
||||
s = splsoftnet();
|
||||
#ifdef __FreeBSD__
|
||||
V_pfi_update++;
|
||||
#else
|
||||
pfi_update++;
|
||||
#endif
|
||||
if ((kif = pfi_kif_get(ifp->if_xname)) == NULL)
|
||||
panic("pfi_kif_get failed");
|
||||
|
||||
@ -341,7 +380,11 @@ pfi_detach_ifnet(struct ifnet *ifp)
|
||||
return;
|
||||
|
||||
s = splsoftnet();
|
||||
#ifdef __FreeBSD__
|
||||
V_pfi_update++;
|
||||
#else
|
||||
pfi_update++;
|
||||
#endif
|
||||
#ifndef __FreeBSD__
|
||||
hook_disestablish(ifp->if_addrhooks, kif->pfik_ah_cookie);
|
||||
#endif
|
||||
@ -361,7 +404,11 @@ pfi_attach_ifgroup(struct ifg_group *ifg)
|
||||
|
||||
pfi_initialize();
|
||||
s = splsoftnet();
|
||||
#ifdef __FreeBSD__
|
||||
V_pfi_update++;
|
||||
#else
|
||||
pfi_update++;
|
||||
#endif
|
||||
if ((kif = pfi_kif_get(ifg->ifg_group)) == NULL)
|
||||
panic("pfi_kif_get failed");
|
||||
|
||||
@ -381,7 +428,11 @@ pfi_detach_ifgroup(struct ifg_group *ifg)
|
||||
return;
|
||||
|
||||
s = splsoftnet();
|
||||
#ifdef __FreeBSD__
|
||||
V_pfi_update++;
|
||||
#else
|
||||
pfi_update++;
|
||||
#endif
|
||||
|
||||
kif->pfik_group = NULL;
|
||||
ifg->ifg_pf_kif = NULL;
|
||||
@ -396,7 +447,11 @@ pfi_group_change(const char *group)
|
||||
int s;
|
||||
|
||||
s = splsoftnet();
|
||||
#ifdef __FreeBSD__
|
||||
V_pfi_update++;
|
||||
#else
|
||||
pfi_update++;
|
||||
#endif
|
||||
if ((kif = pfi_kif_get(group)) == NULL)
|
||||
panic("pfi_kif_get failed");
|
||||
|
||||
@ -450,9 +505,14 @@ pfi_dynaddr_setup(struct pf_addr_wrap *aw, sa_family_t af)
|
||||
|
||||
if (aw->type != PF_ADDR_DYNIFTL)
|
||||
return (0);
|
||||
if ((dyn = pool_get(&pfi_addr_pl, PR_NOWAIT)) == NULL)
|
||||
#ifdef __FreeBSD__
|
||||
/* XXX: revisit! */
|
||||
if ((dyn = pool_get(&V_pfi_addr_pl, PR_WAITOK | PR_ZERO))
|
||||
#else
|
||||
if ((dyn = pool_get(&pfi_addr_pl, PR_WAITOK | PR_LIMITFAIL | PR_ZERO))
|
||||
#endif
|
||||
== NULL)
|
||||
return (1);
|
||||
bzero(dyn, sizeof(*dyn));
|
||||
|
||||
s = splsoftnet();
|
||||
if (!strcmp(aw->v.ifname, "self"))
|
||||
@ -485,7 +545,7 @@ pfi_dynaddr_setup(struct pf_addr_wrap *aw, sa_family_t af)
|
||||
goto _bad;
|
||||
}
|
||||
|
||||
if ((dyn->pfid_kt = pfr_attach_table(ruleset, tblname)) == NULL) {
|
||||
if ((dyn->pfid_kt = pfr_attach_table(ruleset, tblname, 1)) == NULL) {
|
||||
rv = 1;
|
||||
goto _bad;
|
||||
}
|
||||
@ -507,7 +567,11 @@ _bad:
|
||||
pf_remove_if_empty_ruleset(ruleset);
|
||||
if (dyn->pfid_kif != NULL)
|
||||
pfi_kif_unref(dyn->pfid_kif, PFI_KIF_REF_RULE);
|
||||
#ifdef __FreeBSD__
|
||||
pool_put(&V_pfi_addr_pl, dyn);
|
||||
#else
|
||||
pool_put(&pfi_addr_pl, dyn);
|
||||
#endif
|
||||
splx(s);
|
||||
return (rv);
|
||||
}
|
||||
@ -541,10 +605,18 @@ pfi_dynaddr_update(struct pfi_dynaddr *dyn)
|
||||
kif = dyn->pfid_kif;
|
||||
kt = dyn->pfid_kt;
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
if (kt->pfrkt_larg != V_pfi_update) {
|
||||
#else
|
||||
if (kt->pfrkt_larg != pfi_update) {
|
||||
#endif
|
||||
/* this table needs to be brought up-to-date */
|
||||
pfi_table_update(kt, kif, dyn->pfid_net, dyn->pfid_iflags);
|
||||
#ifdef __FreeBSD__
|
||||
kt->pfrkt_larg = V_pfi_update;
|
||||
#else
|
||||
kt->pfrkt_larg = pfi_update;
|
||||
#endif
|
||||
}
|
||||
pfr_dynaddr_update(kt, dyn);
|
||||
}
|
||||
@ -555,7 +627,11 @@ pfi_table_update(struct pfr_ktable *kt, struct pfi_kif *kif, int net, int flags)
|
||||
int e, size2 = 0;
|
||||
struct ifg_member *ifgm;
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
V_pfi_buffer_cnt = 0;
|
||||
#else
|
||||
pfi_buffer_cnt = 0;
|
||||
#endif
|
||||
|
||||
if (kif->pfik_ifp != NULL)
|
||||
pfi_instance_add(kif->pfik_ifp, net, flags);
|
||||
@ -563,10 +639,17 @@ pfi_table_update(struct pfr_ktable *kt, struct pfi_kif *kif, int net, int flags)
|
||||
TAILQ_FOREACH(ifgm, &kif->pfik_group->ifg_members, ifgm_next)
|
||||
pfi_instance_add(ifgm->ifgm_ifp, net, flags);
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
if ((e = pfr_set_addrs(&kt->pfrkt_t, V_pfi_buffer, V_pfi_buffer_cnt, &size2,
|
||||
NULL, NULL, NULL, 0, PFR_TFLAG_ALLMASK)))
|
||||
printf("pfi_table_update: cannot set %d new addresses "
|
||||
"into table %s: %d\n", V_pfi_buffer_cnt, kt->pfrkt_name, e);
|
||||
#else
|
||||
if ((e = pfr_set_addrs(&kt->pfrkt_t, pfi_buffer, pfi_buffer_cnt, &size2,
|
||||
NULL, NULL, NULL, 0, PFR_TFLAG_ALLMASK)))
|
||||
printf("pfi_table_update: cannot set %d new addresses "
|
||||
"into table %s: %d\n", pfi_buffer_cnt, kt->pfrkt_name, e);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@ -587,9 +670,9 @@ pfi_instance_add(struct ifnet *ifp, int net, int flags)
|
||||
#ifdef __FreeBSD__
|
||||
/*
|
||||
* XXX: For point-to-point interfaces, (ifname:0) and IPv4,
|
||||
* jump over addresses without a proper route to work
|
||||
* around a problem with ppp not fully removing the
|
||||
* address used during IPCP.
|
||||
* jump over addresses without a proper route to work
|
||||
* around a problem with ppp not fully removing the
|
||||
* address used during IPCP.
|
||||
*/
|
||||
if ((ifp->if_flags & IFF_POINTOPOINT) &&
|
||||
!(ia->ifa_flags & IFA_ROUTE) &&
|
||||
@ -644,15 +727,24 @@ pfi_address_add(struct sockaddr *sa, int af, int net)
|
||||
struct pfr_addr *p;
|
||||
int i;
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
if (V_pfi_buffer_cnt >= V_pfi_buffer_max) {
|
||||
int new_max = V_pfi_buffer_max * 2;
|
||||
#else
|
||||
if (pfi_buffer_cnt >= pfi_buffer_max) {
|
||||
int new_max = pfi_buffer_max * 2;
|
||||
#endif
|
||||
|
||||
if (new_max > PFI_BUFFER_MAX) {
|
||||
printf("pfi_address_add: address buffer full (%d/%d)\n",
|
||||
#ifdef __FreeBSD__
|
||||
V_pfi_buffer_cnt, PFI_BUFFER_MAX);
|
||||
#else
|
||||
pfi_buffer_cnt, PFI_BUFFER_MAX);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
p = malloc(new_max * sizeof(*pfi_buffer), PFI_MTYPE,
|
||||
p = malloc(new_max * sizeof(*V_pfi_buffer), PFI_MTYPE,
|
||||
#ifdef __FreeBSD__
|
||||
M_NOWAIT);
|
||||
#else
|
||||
@ -660,18 +752,34 @@ pfi_address_add(struct sockaddr *sa, int af, int net)
|
||||
#endif
|
||||
if (p == NULL) {
|
||||
printf("pfi_address_add: no memory to grow buffer "
|
||||
#ifdef __FreeBSD__
|
||||
"(%d/%d)\n", V_pfi_buffer_cnt, PFI_BUFFER_MAX);
|
||||
#else
|
||||
"(%d/%d)\n", pfi_buffer_cnt, PFI_BUFFER_MAX);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
memcpy(p, pfi_buffer, pfi_buffer_max * sizeof(*pfi_buffer));
|
||||
#ifdef __FreeBSD__
|
||||
memcpy(V_pfi_buffer, p, V_pfi_buffer_cnt * sizeof(*V_pfi_buffer));
|
||||
/* no need to zero buffer */
|
||||
free(V_pfi_buffer, PFI_MTYPE);
|
||||
V_pfi_buffer = p;
|
||||
V_pfi_buffer_max = new_max;
|
||||
#else
|
||||
memcpy(pfi_buffer, p, pfi_buffer_cnt * sizeof(*pfi_buffer));
|
||||
/* no need to zero buffer */
|
||||
free(pfi_buffer, PFI_MTYPE);
|
||||
pfi_buffer = p;
|
||||
pfi_buffer_max = new_max;
|
||||
#endif
|
||||
}
|
||||
if (af == AF_INET && net > 32)
|
||||
net = 128;
|
||||
#ifdef __FreeBSD__
|
||||
p = V_pfi_buffer + V_pfi_buffer_cnt++;
|
||||
#else
|
||||
p = pfi_buffer + pfi_buffer_cnt++;
|
||||
#endif
|
||||
bzero(p, sizeof(*p));
|
||||
p->pfra_af = af;
|
||||
p->pfra_net = net;
|
||||
@ -704,7 +812,11 @@ pfi_dynaddr_remove(struct pf_addr_wrap *aw)
|
||||
aw->p.dyn->pfid_kif = NULL;
|
||||
pfr_detach_table(aw->p.dyn->pfid_kt);
|
||||
aw->p.dyn->pfid_kt = NULL;
|
||||
#ifdef __FreeBSD__
|
||||
pool_put(&V_pfi_addr_pl, aw->p.dyn);
|
||||
#else
|
||||
pool_put(&pfi_addr_pl, aw->p.dyn);
|
||||
#endif
|
||||
aw->p.dyn = NULL;
|
||||
splx(s);
|
||||
}
|
||||
@ -725,7 +837,11 @@ pfi_kifaddr_update(void *v)
|
||||
struct pfi_kif *kif = (struct pfi_kif *)v;
|
||||
|
||||
s = splsoftnet();
|
||||
#ifdef __FreeBSD__
|
||||
V_pfi_update++;
|
||||
#else
|
||||
pfi_update++;
|
||||
#endif
|
||||
pfi_kif_update(kif);
|
||||
splx(s);
|
||||
}
|
||||
@ -737,49 +853,61 @@ pfi_if_compare(struct pfi_kif *p, struct pfi_kif *q)
|
||||
}
|
||||
|
||||
void
|
||||
pfi_fill_oldstatus(struct pf_status *pfs)
|
||||
pfi_update_status(const char *name, struct pf_status *pfs)
|
||||
{
|
||||
struct pfi_kif *p;
|
||||
struct pfi_kif_cmp key;
|
||||
struct pfi_kif_cmp key;
|
||||
struct ifg_member p_member, *ifgm;
|
||||
TAILQ_HEAD(, ifg_member) ifg_members;
|
||||
int i, j, k, s;
|
||||
|
||||
strlcpy(key.pfik_name, pfs->ifname, sizeof(key.pfik_name));
|
||||
strlcpy(key.pfik_name, name, sizeof(key.pfik_name));
|
||||
s = splsoftnet();
|
||||
#ifdef __FreeBSD__
|
||||
p = RB_FIND(pfi_ifhead, &V_pfi_ifs, (struct pfi_kif *)&key);
|
||||
#else
|
||||
p = RB_FIND(pfi_ifhead, &pfi_ifs, (struct pfi_kif *)&key);
|
||||
#endif
|
||||
if (p == NULL) {
|
||||
splx(s);
|
||||
return;
|
||||
}
|
||||
bzero(pfs->pcounters, sizeof(pfs->pcounters));
|
||||
bzero(pfs->bcounters, sizeof(pfs->bcounters));
|
||||
for (i = 0; i < 2; i++)
|
||||
for (j = 0; j < 2; j++)
|
||||
for (k = 0; k < 2; k++) {
|
||||
pfs->pcounters[i][j][k] =
|
||||
p->pfik_packets[i][j][k];
|
||||
pfs->bcounters[i][j] +=
|
||||
p->pfik_bytes[i][j][k];
|
||||
}
|
||||
splx(s);
|
||||
}
|
||||
|
||||
int
|
||||
pfi_clr_istats(const char *name)
|
||||
{
|
||||
struct pfi_kif *p;
|
||||
int s;
|
||||
|
||||
s = splsoftnet();
|
||||
RB_FOREACH(p, pfi_ifhead, &pfi_ifs) {
|
||||
if (pfi_skip_if(name, p))
|
||||
if (p->pfik_group != NULL) {
|
||||
bcopy(&p->pfik_group->ifg_members, &ifg_members,
|
||||
sizeof(ifg_members));
|
||||
} else {
|
||||
/* build a temporary list for p only */
|
||||
bzero(&p_member, sizeof(p_member));
|
||||
p_member.ifgm_ifp = p->pfik_ifp;
|
||||
TAILQ_INIT(&ifg_members);
|
||||
TAILQ_INSERT_TAIL(&ifg_members, &p_member, ifgm_next);
|
||||
}
|
||||
if (pfs) {
|
||||
bzero(pfs->pcounters, sizeof(pfs->pcounters));
|
||||
bzero(pfs->bcounters, sizeof(pfs->bcounters));
|
||||
}
|
||||
TAILQ_FOREACH(ifgm, &ifg_members, ifgm_next) {
|
||||
if (ifgm->ifgm_ifp == NULL)
|
||||
continue;
|
||||
bzero(p->pfik_packets, sizeof(p->pfik_packets));
|
||||
bzero(p->pfik_bytes, sizeof(p->pfik_bytes));
|
||||
p->pfik_tzero = time_second;
|
||||
p = (struct pfi_kif *)ifgm->ifgm_ifp->if_pf_kif;
|
||||
|
||||
/* just clear statistics */
|
||||
if (pfs == NULL) {
|
||||
bzero(p->pfik_packets, sizeof(p->pfik_packets));
|
||||
bzero(p->pfik_bytes, sizeof(p->pfik_bytes));
|
||||
p->pfik_tzero = time_second;
|
||||
continue;
|
||||
}
|
||||
for (i = 0; i < 2; i++)
|
||||
for (j = 0; j < 2; j++)
|
||||
for (k = 0; k < 2; k++) {
|
||||
pfs->pcounters[i][j][k] +=
|
||||
p->pfik_packets[i][j][k];
|
||||
pfs->bcounters[i][j] +=
|
||||
p->pfik_bytes[i][j][k];
|
||||
}
|
||||
}
|
||||
splx(s);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
@ -792,8 +920,13 @@ pfi_get_ifaces(const char *name, struct pfi_kif *buf, int *size)
|
||||
#endif
|
||||
|
||||
s = splsoftnet();
|
||||
#ifdef __FreeBSD__
|
||||
for (p = RB_MIN(pfi_ifhead, &V_pfi_ifs); p; p = nextp) {
|
||||
nextp = RB_NEXT(pfi_ifhead, &V_pfi_ifs, p);
|
||||
#else
|
||||
for (p = RB_MIN(pfi_ifhead, &pfi_ifs); p; p = nextp) {
|
||||
nextp = RB_NEXT(pfi_ifhead, &pfi_ifs, p);
|
||||
#endif
|
||||
if (pfi_skip_if(name, p))
|
||||
continue;
|
||||
if (*size > n++) {
|
||||
@ -810,7 +943,11 @@ pfi_get_ifaces(const char *name, struct pfi_kif *buf, int *size)
|
||||
splx(s);
|
||||
return (EFAULT);
|
||||
}
|
||||
#ifdef __FreeBSD__
|
||||
nextp = RB_NEXT(pfi_ifhead, &V_pfi_ifs, p);
|
||||
#else
|
||||
nextp = RB_NEXT(pfi_ifhead, &pfi_ifs, p);
|
||||
#endif
|
||||
pfi_kif_unref(p, PFI_KIF_REF_RULE);
|
||||
}
|
||||
}
|
||||
@ -845,7 +982,11 @@ pfi_set_flags(const char *name, int flags)
|
||||
int s;
|
||||
|
||||
s = splsoftnet();
|
||||
#ifdef __FreeBSD__
|
||||
RB_FOREACH(p, pfi_ifhead, &V_pfi_ifs) {
|
||||
#else
|
||||
RB_FOREACH(p, pfi_ifhead, &pfi_ifs) {
|
||||
#endif
|
||||
if (pfi_skip_if(name, p))
|
||||
continue;
|
||||
p->pfik_flags |= flags;
|
||||
@ -861,7 +1002,11 @@ pfi_clear_flags(const char *name, int flags)
|
||||
int s;
|
||||
|
||||
s = splsoftnet();
|
||||
#ifdef __FreeBSD__
|
||||
RB_FOREACH(p, pfi_ifhead, &V_pfi_ifs) {
|
||||
#else
|
||||
RB_FOREACH(p, pfi_ifhead, &pfi_ifs) {
|
||||
#endif
|
||||
if (pfi_skip_if(name, p))
|
||||
continue;
|
||||
p->pfik_flags &= ~flags;
|
||||
@ -894,55 +1039,73 @@ pfi_unmask(void *addr)
|
||||
void
|
||||
pfi_attach_ifnet_event(void *arg __unused, struct ifnet *ifp)
|
||||
{
|
||||
|
||||
CURVNET_SET(ifp->if_vnet);
|
||||
PF_LOCK();
|
||||
pfi_attach_ifnet(ifp);
|
||||
#ifdef ALTQ
|
||||
pf_altq_ifnet_event(ifp, 0);
|
||||
#endif
|
||||
PF_UNLOCK();
|
||||
CURVNET_RESTORE();
|
||||
}
|
||||
|
||||
void
|
||||
pfi_detach_ifnet_event(void *arg __unused, struct ifnet *ifp)
|
||||
{
|
||||
|
||||
CURVNET_SET(ifp->if_vnet);
|
||||
PF_LOCK();
|
||||
pfi_detach_ifnet(ifp);
|
||||
#ifdef ALTQ
|
||||
pf_altq_ifnet_event(ifp, 1);
|
||||
#endif
|
||||
PF_UNLOCK();
|
||||
CURVNET_RESTORE();
|
||||
}
|
||||
|
||||
void
|
||||
pfi_attach_group_event(void *arg __unused, struct ifg_group *ifg)
|
||||
pfi_attach_group_event(void *arg , struct ifg_group *ifg)
|
||||
{
|
||||
|
||||
CURVNET_SET((struct vnet *)arg);
|
||||
PF_LOCK();
|
||||
pfi_attach_ifgroup(ifg);
|
||||
PF_UNLOCK();
|
||||
CURVNET_RESTORE();
|
||||
}
|
||||
|
||||
void
|
||||
pfi_change_group_event(void *arg __unused, char *gname)
|
||||
pfi_change_group_event(void *arg, char *gname)
|
||||
{
|
||||
|
||||
CURVNET_SET((struct vnet *)arg);
|
||||
PF_LOCK();
|
||||
pfi_group_change(gname);
|
||||
PF_UNLOCK();
|
||||
CURVNET_RESTORE();
|
||||
}
|
||||
|
||||
void
|
||||
pfi_detach_group_event(void *arg __unused, struct ifg_group *ifg)
|
||||
pfi_detach_group_event(void *arg, struct ifg_group *ifg)
|
||||
{
|
||||
|
||||
CURVNET_SET((struct vnet *)arg);
|
||||
PF_LOCK();
|
||||
pfi_detach_ifgroup(ifg);
|
||||
PF_UNLOCK();
|
||||
CURVNET_RESTORE();
|
||||
}
|
||||
|
||||
void
|
||||
pfi_ifaddr_event(void *arg __unused, struct ifnet *ifp)
|
||||
{
|
||||
|
||||
CURVNET_SET(ifp->if_vnet);
|
||||
PF_LOCK();
|
||||
if (ifp && ifp->if_pf_kif)
|
||||
pfi_kifaddr_update(ifp->if_pf_kif);
|
||||
PF_UNLOCK();
|
||||
CURVNET_RESTORE();
|
||||
}
|
||||
#endif /* __FreeBSD__ */
|
||||
|
File diff suppressed because it is too large
Load Diff
792
sys/contrib/pf/net/pf_lb.c
Normal file
792
sys/contrib/pf/net/pf_lb.c
Normal file
@ -0,0 +1,792 @@
|
||||
/* $OpenBSD: pf_lb.c,v 1.2 2009/02/12 02:13:15 sthen Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Daniel Hartmeier
|
||||
* Copyright (c) 2002 - 2008 Henning Brauer
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Effort sponsored in part by the Defense Advanced Research Projects
|
||||
* Agency (DARPA) and Air Force Research Laboratory, Air Force
|
||||
* Materiel Command, USAF, under agreement number F30602-01-2-0537.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include "opt_inet.h"
|
||||
#include "opt_inet6.h"
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include "opt_bpf.h"
|
||||
#include "opt_pf.h"
|
||||
|
||||
#ifdef DEV_BPF
|
||||
#define NBPFILTER DEV_BPF
|
||||
#else
|
||||
#define NBPFILTER 0
|
||||
#endif
|
||||
|
||||
#ifdef DEV_PFLOG
|
||||
#define NPFLOG DEV_PFLOG
|
||||
#else
|
||||
#define NPFLOG 0
|
||||
#endif
|
||||
|
||||
#ifdef DEV_PFSYNC
|
||||
#define NPFSYNC DEV_PFSYNC
|
||||
#else
|
||||
#define NPFSYNC 0
|
||||
#endif
|
||||
|
||||
#ifdef DEV_PFLOW
|
||||
#define NPFLOW DEV_PFLOW
|
||||
#else
|
||||
#define NPFLOW 0
|
||||
#endif
|
||||
|
||||
#else
|
||||
#include "bpfilter.h"
|
||||
#include "pflog.h"
|
||||
#include "pfsync.h"
|
||||
#include "pflow.h"
|
||||
#endif
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/filio.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/time.h>
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
#ifndef __FreeBSD__
|
||||
#include <sys/pool.h>
|
||||
#endif
|
||||
#include <sys/proc.h>
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/kthread.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/sx.h>
|
||||
#else
|
||||
#include <sys/rwlock.h>
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/md5.h>
|
||||
#else
|
||||
#include <crypto/md5.h>
|
||||
#endif
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/bpf.h>
|
||||
#include <net/route.h>
|
||||
#include <net/radix_mpath.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_var.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip_var.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <netinet/tcp_seq.h>
|
||||
#include <netinet/udp.h>
|
||||
#include <netinet/ip_icmp.h>
|
||||
#include <netinet/in_pcb.h>
|
||||
#include <netinet/tcp_timer.h>
|
||||
#include <netinet/tcp_var.h>
|
||||
#include <netinet/udp_var.h>
|
||||
#include <netinet/icmp_var.h>
|
||||
#include <netinet/if_ether.h>
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
#include <dev/rndvar.h>
|
||||
#endif
|
||||
#include <net/pfvar.h>
|
||||
#include <net/if_pflog.h>
|
||||
#include <net/if_pflow.h>
|
||||
|
||||
#if NPFSYNC > 0
|
||||
#include <net/if_pfsync.h>
|
||||
#endif /* NPFSYNC > 0 */
|
||||
|
||||
#ifdef INET6
|
||||
#include <netinet/ip6.h>
|
||||
#include <netinet/in_pcb.h>
|
||||
#include <netinet/icmp6.h>
|
||||
#include <netinet6/nd6.h>
|
||||
#endif /* INET6 */
|
||||
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#define DPFPRINTF(n, x) if (V_pf_status.debug >= (n)) printf x
|
||||
#else
|
||||
#define DPFPRINTF(n, x) if (pf_status.debug >= (n)) printf x
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Global variables
|
||||
*/
|
||||
|
||||
void pf_hash(struct pf_addr *, struct pf_addr *,
|
||||
struct pf_poolhashkey *, sa_family_t);
|
||||
struct pf_rule *pf_match_translation(struct pf_pdesc *, struct mbuf *,
|
||||
int, int, struct pfi_kif *,
|
||||
struct pf_addr *, u_int16_t, struct pf_addr *,
|
||||
u_int16_t, int);
|
||||
int pf_get_sport(sa_family_t, u_int8_t, struct pf_rule *,
|
||||
struct pf_addr *, struct pf_addr *, u_int16_t,
|
||||
struct pf_addr *, u_int16_t*, u_int16_t, u_int16_t,
|
||||
struct pf_src_node **);
|
||||
|
||||
#define mix(a,b,c) \
|
||||
do { \
|
||||
a -= b; a -= c; a ^= (c >> 13); \
|
||||
b -= c; b -= a; b ^= (a << 8); \
|
||||
c -= a; c -= b; c ^= (b >> 13); \
|
||||
a -= b; a -= c; a ^= (c >> 12); \
|
||||
b -= c; b -= a; b ^= (a << 16); \
|
||||
c -= a; c -= b; c ^= (b >> 5); \
|
||||
a -= b; a -= c; a ^= (c >> 3); \
|
||||
b -= c; b -= a; b ^= (a << 10); \
|
||||
c -= a; c -= b; c ^= (b >> 15); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* hash function based on bridge_hash in if_bridge.c
|
||||
*/
|
||||
void
|
||||
pf_hash(struct pf_addr *inaddr, struct pf_addr *hash,
|
||||
struct pf_poolhashkey *key, sa_family_t af)
|
||||
{
|
||||
u_int32_t a = 0x9e3779b9, b = 0x9e3779b9, c = key->key32[0];
|
||||
|
||||
switch (af) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
a += inaddr->addr32[0];
|
||||
b += key->key32[1];
|
||||
mix(a, b, c);
|
||||
hash->addr32[0] = c + key->key32[2];
|
||||
break;
|
||||
#endif /* INET */
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
a += inaddr->addr32[0];
|
||||
b += inaddr->addr32[2];
|
||||
mix(a, b, c);
|
||||
hash->addr32[0] = c;
|
||||
a += inaddr->addr32[1];
|
||||
b += inaddr->addr32[3];
|
||||
c += key->key32[1];
|
||||
mix(a, b, c);
|
||||
hash->addr32[1] = c;
|
||||
a += inaddr->addr32[2];
|
||||
b += inaddr->addr32[1];
|
||||
c += key->key32[2];
|
||||
mix(a, b, c);
|
||||
hash->addr32[2] = c;
|
||||
a += inaddr->addr32[3];
|
||||
b += inaddr->addr32[0];
|
||||
c += key->key32[3];
|
||||
mix(a, b, c);
|
||||
hash->addr32[3] = c;
|
||||
break;
|
||||
#endif /* INET6 */
|
||||
}
|
||||
}
|
||||
|
||||
struct pf_rule *
|
||||
pf_match_translation(struct pf_pdesc *pd, struct mbuf *m, int off,
|
||||
int direction, struct pfi_kif *kif, struct pf_addr *saddr, u_int16_t sport,
|
||||
struct pf_addr *daddr, u_int16_t dport, int rs_num)
|
||||
{
|
||||
struct pf_rule *r, *rm = NULL;
|
||||
struct pf_ruleset *ruleset = NULL;
|
||||
int tag = -1;
|
||||
int rtableid = -1;
|
||||
int asd = 0;
|
||||
|
||||
r = TAILQ_FIRST(pf_main_ruleset.rules[rs_num].active.ptr);
|
||||
while (r && rm == NULL) {
|
||||
struct pf_rule_addr *src = NULL, *dst = NULL;
|
||||
struct pf_addr_wrap *xdst = NULL;
|
||||
|
||||
if (r->action == PF_BINAT && direction == PF_IN) {
|
||||
src = &r->dst;
|
||||
if (r->rpool.cur != NULL)
|
||||
xdst = &r->rpool.cur->addr;
|
||||
} else {
|
||||
src = &r->src;
|
||||
dst = &r->dst;
|
||||
}
|
||||
|
||||
r->evaluations++;
|
||||
if (pfi_kif_match(r->kif, kif) == r->ifnot)
|
||||
r = r->skip[PF_SKIP_IFP].ptr;
|
||||
else if (r->direction && r->direction != direction)
|
||||
r = r->skip[PF_SKIP_DIR].ptr;
|
||||
else if (r->af && r->af != pd->af)
|
||||
r = r->skip[PF_SKIP_AF].ptr;
|
||||
else if (r->proto && r->proto != pd->proto)
|
||||
r = r->skip[PF_SKIP_PROTO].ptr;
|
||||
else if (PF_MISMATCHAW(&src->addr, saddr, pd->af,
|
||||
src->neg, kif))
|
||||
r = r->skip[src == &r->src ? PF_SKIP_SRC_ADDR :
|
||||
PF_SKIP_DST_ADDR].ptr;
|
||||
else if (src->port_op && !pf_match_port(src->port_op,
|
||||
src->port[0], src->port[1], sport))
|
||||
r = r->skip[src == &r->src ? PF_SKIP_SRC_PORT :
|
||||
PF_SKIP_DST_PORT].ptr;
|
||||
else if (dst != NULL &&
|
||||
PF_MISMATCHAW(&dst->addr, daddr, pd->af, dst->neg, NULL))
|
||||
r = r->skip[PF_SKIP_DST_ADDR].ptr;
|
||||
else if (xdst != NULL && PF_MISMATCHAW(xdst, daddr, pd->af,
|
||||
0, NULL))
|
||||
r = TAILQ_NEXT(r, entries);
|
||||
else if (dst != NULL && dst->port_op &&
|
||||
!pf_match_port(dst->port_op, dst->port[0],
|
||||
dst->port[1], dport))
|
||||
r = r->skip[PF_SKIP_DST_PORT].ptr;
|
||||
#ifdef __FreeBSD__
|
||||
else if (r->match_tag && !pf_match_tag(m, r, &tag, pd->pf_mtag))
|
||||
#else
|
||||
else if (r->match_tag && !pf_match_tag(m, r, &tag))
|
||||
#endif
|
||||
r = TAILQ_NEXT(r, entries);
|
||||
else if (r->os_fingerprint != PF_OSFP_ANY && (pd->proto !=
|
||||
IPPROTO_TCP || !pf_osfp_match(pf_osfp_fingerprint(pd, m,
|
||||
off, pd->hdr.tcp), r->os_fingerprint)))
|
||||
r = TAILQ_NEXT(r, entries);
|
||||
else {
|
||||
if (r->tag)
|
||||
tag = r->tag;
|
||||
if (r->rtableid >= 0)
|
||||
rtableid = r->rtableid;
|
||||
if (r->anchor == NULL) {
|
||||
rm = r;
|
||||
} else
|
||||
pf_step_into_anchor(&asd, &ruleset, rs_num,
|
||||
&r, NULL, NULL);
|
||||
}
|
||||
if (r == NULL)
|
||||
pf_step_out_of_anchor(&asd, &ruleset, rs_num, &r,
|
||||
NULL, NULL);
|
||||
}
|
||||
#ifdef __FreeBSD__
|
||||
if (pf_tag_packet(m, tag, rtableid, pd->pf_mtag))
|
||||
#else
|
||||
if (pf_tag_packet(m, tag, rtableid))
|
||||
#endif
|
||||
return (NULL);
|
||||
if (rm != NULL && (rm->action == PF_NONAT ||
|
||||
rm->action == PF_NORDR || rm->action == PF_NOBINAT))
|
||||
return (NULL);
|
||||
return (rm);
|
||||
}
|
||||
|
||||
int
|
||||
pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r,
|
||||
struct pf_addr *saddr, struct pf_addr *daddr, u_int16_t dport,
|
||||
struct pf_addr *naddr, u_int16_t *nport, u_int16_t low, u_int16_t high,
|
||||
struct pf_src_node **sn)
|
||||
{
|
||||
struct pf_state_key_cmp key;
|
||||
struct pf_addr init_addr;
|
||||
u_int16_t cut;
|
||||
|
||||
bzero(&init_addr, sizeof(init_addr));
|
||||
if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn))
|
||||
return (1);
|
||||
|
||||
if (proto == IPPROTO_ICMP) {
|
||||
low = 1;
|
||||
high = 65535;
|
||||
}
|
||||
|
||||
do {
|
||||
key.af = af;
|
||||
key.proto = proto;
|
||||
PF_ACPY(&key.addr[1], daddr, key.af);
|
||||
PF_ACPY(&key.addr[0], naddr, key.af);
|
||||
key.port[1] = dport;
|
||||
|
||||
/*
|
||||
* port search; start random, step;
|
||||
* similar 2 portloop in in_pcbbind
|
||||
*/
|
||||
if (!(proto == IPPROTO_TCP || proto == IPPROTO_UDP ||
|
||||
proto == IPPROTO_ICMP)) {
|
||||
key.port[0] = dport;
|
||||
if (pf_find_state_all(&key, PF_IN, NULL) == NULL)
|
||||
return (0);
|
||||
} else if (low == 0 && high == 0) {
|
||||
key.port[0] = *nport;
|
||||
if (pf_find_state_all(&key, PF_IN, NULL) == NULL)
|
||||
return (0);
|
||||
} else if (low == high) {
|
||||
key.port[0] = htons(low);
|
||||
if (pf_find_state_all(&key, PF_IN, NULL) == NULL) {
|
||||
*nport = htons(low);
|
||||
return (0);
|
||||
}
|
||||
} else {
|
||||
u_int16_t tmp;
|
||||
|
||||
if (low > high) {
|
||||
tmp = low;
|
||||
low = high;
|
||||
high = tmp;
|
||||
}
|
||||
/* low < high */
|
||||
#ifdef __FreeBSD__
|
||||
cut = htonl(arc4random()) % (1 + high - low) + low;
|
||||
#else
|
||||
cut = arc4random_uniform(1 + high - low) + low;
|
||||
#endif
|
||||
/* low <= cut <= high */
|
||||
for (tmp = cut; tmp <= high; ++(tmp)) {
|
||||
key.port[0] = htons(tmp);
|
||||
if (pf_find_state_all(&key, PF_IN, NULL) ==
|
||||
#ifdef __FreeBSD__
|
||||
NULL) {
|
||||
#else
|
||||
NULL && !in_baddynamic(tmp, proto)) {
|
||||
#endif
|
||||
*nport = htons(tmp);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
for (tmp = cut - 1; tmp >= low; --(tmp)) {
|
||||
key.port[0] = htons(tmp);
|
||||
if (pf_find_state_all(&key, PF_IN, NULL) ==
|
||||
#ifdef __FreeBSD__
|
||||
NULL) {
|
||||
#else
|
||||
NULL && !in_baddynamic(tmp, proto)) {
|
||||
#endif
|
||||
*nport = htons(tmp);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (r->rpool.opts & PF_POOL_TYPEMASK) {
|
||||
case PF_POOL_RANDOM:
|
||||
case PF_POOL_ROUNDROBIN:
|
||||
if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn))
|
||||
return (1);
|
||||
break;
|
||||
case PF_POOL_NONE:
|
||||
case PF_POOL_SRCHASH:
|
||||
case PF_POOL_BITMASK:
|
||||
default:
|
||||
return (1);
|
||||
}
|
||||
} while (! PF_AEQ(&init_addr, naddr, af) );
|
||||
return (1); /* none available */
|
||||
}
|
||||
|
||||
int
|
||||
pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr,
|
||||
struct pf_addr *naddr, struct pf_addr *init_addr, struct pf_src_node **sn)
|
||||
{
|
||||
unsigned char hash[16];
|
||||
struct pf_pool *rpool = &r->rpool;
|
||||
struct pf_addr *raddr = &rpool->cur->addr.v.a.addr;
|
||||
struct pf_addr *rmask = &rpool->cur->addr.v.a.mask;
|
||||
struct pf_pooladdr *acur = rpool->cur;
|
||||
struct pf_src_node k;
|
||||
|
||||
if (*sn == NULL && r->rpool.opts & PF_POOL_STICKYADDR &&
|
||||
(r->rpool.opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) {
|
||||
k.af = af;
|
||||
PF_ACPY(&k.addr, saddr, af);
|
||||
if (r->rule_flag & PFRULE_RULESRCTRACK ||
|
||||
r->rpool.opts & PF_POOL_STICKYADDR)
|
||||
k.rule.ptr = r;
|
||||
else
|
||||
k.rule.ptr = NULL;
|
||||
#ifdef __FreeBSD__
|
||||
V_pf_status.scounters[SCNT_SRC_NODE_SEARCH]++;
|
||||
*sn = RB_FIND(pf_src_tree, &V_tree_src_tracking, &k);
|
||||
#else
|
||||
pf_status.scounters[SCNT_SRC_NODE_SEARCH]++;
|
||||
*sn = RB_FIND(pf_src_tree, &tree_src_tracking, &k);
|
||||
#endif
|
||||
if (*sn != NULL && !PF_AZERO(&(*sn)->raddr, af)) {
|
||||
PF_ACPY(naddr, &(*sn)->raddr, af);
|
||||
#ifdef __FreeBSD__
|
||||
if (V_pf_status.debug >= PF_DEBUG_MISC) {
|
||||
#else
|
||||
if (pf_status.debug >= PF_DEBUG_MISC) {
|
||||
#endif
|
||||
printf("pf_map_addr: src tracking maps ");
|
||||
pf_print_host(&k.addr, 0, af);
|
||||
printf(" to ");
|
||||
pf_print_host(naddr, 0, af);
|
||||
printf("\n");
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
if (rpool->cur->addr.type == PF_ADDR_NOROUTE)
|
||||
return (1);
|
||||
if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
|
||||
switch (af) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
if (rpool->cur->addr.p.dyn->pfid_acnt4 < 1 &&
|
||||
(rpool->opts & PF_POOL_TYPEMASK) !=
|
||||
PF_POOL_ROUNDROBIN)
|
||||
return (1);
|
||||
raddr = &rpool->cur->addr.p.dyn->pfid_addr4;
|
||||
rmask = &rpool->cur->addr.p.dyn->pfid_mask4;
|
||||
break;
|
||||
#endif /* INET */
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
if (rpool->cur->addr.p.dyn->pfid_acnt6 < 1 &&
|
||||
(rpool->opts & PF_POOL_TYPEMASK) !=
|
||||
PF_POOL_ROUNDROBIN)
|
||||
return (1);
|
||||
raddr = &rpool->cur->addr.p.dyn->pfid_addr6;
|
||||
rmask = &rpool->cur->addr.p.dyn->pfid_mask6;
|
||||
break;
|
||||
#endif /* INET6 */
|
||||
}
|
||||
} else if (rpool->cur->addr.type == PF_ADDR_TABLE) {
|
||||
if ((rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_ROUNDROBIN)
|
||||
return (1); /* unsupported */
|
||||
} else {
|
||||
raddr = &rpool->cur->addr.v.a.addr;
|
||||
rmask = &rpool->cur->addr.v.a.mask;
|
||||
}
|
||||
|
||||
switch (rpool->opts & PF_POOL_TYPEMASK) {
|
||||
case PF_POOL_NONE:
|
||||
PF_ACPY(naddr, raddr, af);
|
||||
break;
|
||||
case PF_POOL_BITMASK:
|
||||
PF_POOLMASK(naddr, raddr, rmask, saddr, af);
|
||||
break;
|
||||
case PF_POOL_RANDOM:
|
||||
if (init_addr != NULL && PF_AZERO(init_addr, af)) {
|
||||
switch (af) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
rpool->counter.addr32[0] = htonl(arc4random());
|
||||
break;
|
||||
#endif /* INET */
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
if (rmask->addr32[3] != 0xffffffff)
|
||||
rpool->counter.addr32[3] =
|
||||
htonl(arc4random());
|
||||
else
|
||||
break;
|
||||
if (rmask->addr32[2] != 0xffffffff)
|
||||
rpool->counter.addr32[2] =
|
||||
htonl(arc4random());
|
||||
else
|
||||
break;
|
||||
if (rmask->addr32[1] != 0xffffffff)
|
||||
rpool->counter.addr32[1] =
|
||||
htonl(arc4random());
|
||||
else
|
||||
break;
|
||||
if (rmask->addr32[0] != 0xffffffff)
|
||||
rpool->counter.addr32[0] =
|
||||
htonl(arc4random());
|
||||
break;
|
||||
#endif /* INET6 */
|
||||
}
|
||||
PF_POOLMASK(naddr, raddr, rmask, &rpool->counter, af);
|
||||
PF_ACPY(init_addr, naddr, af);
|
||||
|
||||
} else {
|
||||
PF_AINC(&rpool->counter, af);
|
||||
PF_POOLMASK(naddr, raddr, rmask, &rpool->counter, af);
|
||||
}
|
||||
break;
|
||||
case PF_POOL_SRCHASH:
|
||||
pf_hash(saddr, (struct pf_addr *)&hash, &rpool->key, af);
|
||||
PF_POOLMASK(naddr, raddr, rmask, (struct pf_addr *)&hash, af);
|
||||
break;
|
||||
case PF_POOL_ROUNDROBIN:
|
||||
if (rpool->cur->addr.type == PF_ADDR_TABLE) {
|
||||
if (!pfr_pool_get(rpool->cur->addr.p.tbl,
|
||||
&rpool->tblidx, &rpool->counter,
|
||||
&raddr, &rmask, af))
|
||||
goto get_addr;
|
||||
} else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
|
||||
if (!pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt,
|
||||
&rpool->tblidx, &rpool->counter,
|
||||
&raddr, &rmask, af))
|
||||
goto get_addr;
|
||||
} else if (pf_match_addr(0, raddr, rmask, &rpool->counter, af))
|
||||
goto get_addr;
|
||||
|
||||
try_next:
|
||||
if ((rpool->cur = TAILQ_NEXT(rpool->cur, entries)) == NULL)
|
||||
rpool->cur = TAILQ_FIRST(&rpool->list);
|
||||
if (rpool->cur->addr.type == PF_ADDR_TABLE) {
|
||||
rpool->tblidx = -1;
|
||||
if (pfr_pool_get(rpool->cur->addr.p.tbl,
|
||||
&rpool->tblidx, &rpool->counter,
|
||||
&raddr, &rmask, af)) {
|
||||
/* table contains no address of type 'af' */
|
||||
if (rpool->cur != acur)
|
||||
goto try_next;
|
||||
return (1);
|
||||
}
|
||||
} else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
|
||||
rpool->tblidx = -1;
|
||||
if (pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt,
|
||||
&rpool->tblidx, &rpool->counter,
|
||||
&raddr, &rmask, af)) {
|
||||
/* table contains no address of type 'af' */
|
||||
if (rpool->cur != acur)
|
||||
goto try_next;
|
||||
return (1);
|
||||
}
|
||||
} else {
|
||||
raddr = &rpool->cur->addr.v.a.addr;
|
||||
rmask = &rpool->cur->addr.v.a.mask;
|
||||
PF_ACPY(&rpool->counter, raddr, af);
|
||||
}
|
||||
|
||||
get_addr:
|
||||
PF_ACPY(naddr, &rpool->counter, af);
|
||||
if (init_addr != NULL && PF_AZERO(init_addr, af))
|
||||
PF_ACPY(init_addr, naddr, af);
|
||||
PF_AINC(&rpool->counter, af);
|
||||
break;
|
||||
}
|
||||
if (*sn != NULL)
|
||||
PF_ACPY(&(*sn)->raddr, naddr, af);
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
if (V_pf_status.debug >= PF_DEBUG_MISC &&
|
||||
#else
|
||||
if (pf_status.debug >= PF_DEBUG_MISC &&
|
||||
#endif
|
||||
(rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) {
|
||||
printf("pf_map_addr: selected address ");
|
||||
pf_print_host(naddr, 0, af);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
struct pf_rule *
|
||||
pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, int direction,
|
||||
struct pfi_kif *kif, struct pf_src_node **sn,
|
||||
struct pf_state_key **skw, struct pf_state_key **sks,
|
||||
struct pf_state_key **skp, struct pf_state_key **nkp,
|
||||
struct pf_addr *saddr, struct pf_addr *daddr,
|
||||
u_int16_t sport, u_int16_t dport)
|
||||
{
|
||||
struct pf_rule *r = NULL;
|
||||
|
||||
|
||||
if (direction == PF_OUT) {
|
||||
r = pf_match_translation(pd, m, off, direction, kif, saddr,
|
||||
sport, daddr, dport, PF_RULESET_BINAT);
|
||||
if (r == NULL)
|
||||
r = pf_match_translation(pd, m, off, direction, kif,
|
||||
saddr, sport, daddr, dport, PF_RULESET_NAT);
|
||||
} else {
|
||||
r = pf_match_translation(pd, m, off, direction, kif, saddr,
|
||||
sport, daddr, dport, PF_RULESET_RDR);
|
||||
if (r == NULL)
|
||||
r = pf_match_translation(pd, m, off, direction, kif,
|
||||
saddr, sport, daddr, dport, PF_RULESET_BINAT);
|
||||
}
|
||||
|
||||
if (r != NULL) {
|
||||
struct pf_addr *naddr;
|
||||
u_int16_t *nport;
|
||||
|
||||
if (pf_state_key_setup(pd, r, skw, sks, skp, nkp,
|
||||
saddr, daddr, sport, dport))
|
||||
return r;
|
||||
|
||||
/* XXX We only modify one side for now. */
|
||||
naddr = &(*nkp)->addr[1];
|
||||
nport = &(*nkp)->port[1];
|
||||
|
||||
switch (r->action) {
|
||||
case PF_NONAT:
|
||||
case PF_NOBINAT:
|
||||
case PF_NORDR:
|
||||
return (NULL);
|
||||
case PF_NAT:
|
||||
if (pf_get_sport(pd->af, pd->proto, r, saddr,
|
||||
daddr, dport, naddr, nport, r->rpool.proxy_port[0],
|
||||
r->rpool.proxy_port[1], sn)) {
|
||||
DPFPRINTF(PF_DEBUG_MISC,
|
||||
("pf: NAT proxy port allocation "
|
||||
"(%u-%u) failed\n",
|
||||
r->rpool.proxy_port[0],
|
||||
r->rpool.proxy_port[1]));
|
||||
return (NULL);
|
||||
}
|
||||
break;
|
||||
case PF_BINAT:
|
||||
switch (direction) {
|
||||
case PF_OUT:
|
||||
if (r->rpool.cur->addr.type == PF_ADDR_DYNIFTL){
|
||||
switch (pd->af) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
if (r->rpool.cur->addr.p.dyn->
|
||||
pfid_acnt4 < 1)
|
||||
return (NULL);
|
||||
PF_POOLMASK(naddr,
|
||||
&r->rpool.cur->addr.p.dyn->
|
||||
pfid_addr4,
|
||||
&r->rpool.cur->addr.p.dyn->
|
||||
pfid_mask4,
|
||||
saddr, AF_INET);
|
||||
break;
|
||||
#endif /* INET */
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
if (r->rpool.cur->addr.p.dyn->
|
||||
pfid_acnt6 < 1)
|
||||
return (NULL);
|
||||
PF_POOLMASK(naddr,
|
||||
&r->rpool.cur->addr.p.dyn->
|
||||
pfid_addr6,
|
||||
&r->rpool.cur->addr.p.dyn->
|
||||
pfid_mask6,
|
||||
saddr, AF_INET6);
|
||||
break;
|
||||
#endif /* INET6 */
|
||||
}
|
||||
} else
|
||||
PF_POOLMASK(naddr,
|
||||
&r->rpool.cur->addr.v.a.addr,
|
||||
&r->rpool.cur->addr.v.a.mask,
|
||||
saddr, pd->af);
|
||||
break;
|
||||
case PF_IN:
|
||||
if (r->src.addr.type == PF_ADDR_DYNIFTL) {
|
||||
switch (pd->af) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
if (r->src.addr.p.dyn->
|
||||
pfid_acnt4 < 1)
|
||||
return (NULL);
|
||||
PF_POOLMASK(naddr,
|
||||
&r->src.addr.p.dyn->
|
||||
pfid_addr4,
|
||||
&r->src.addr.p.dyn->
|
||||
pfid_mask4,
|
||||
daddr, AF_INET);
|
||||
break;
|
||||
#endif /* INET */
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
if (r->src.addr.p.dyn->
|
||||
pfid_acnt6 < 1)
|
||||
return (NULL);
|
||||
PF_POOLMASK(naddr,
|
||||
&r->src.addr.p.dyn->
|
||||
pfid_addr6,
|
||||
&r->src.addr.p.dyn->
|
||||
pfid_mask6,
|
||||
daddr, AF_INET6);
|
||||
break;
|
||||
#endif /* INET6 */
|
||||
}
|
||||
} else
|
||||
PF_POOLMASK(naddr,
|
||||
&r->src.addr.v.a.addr,
|
||||
&r->src.addr.v.a.mask, daddr,
|
||||
pd->af);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PF_RDR: {
|
||||
if (pf_map_addr(pd->af, r, saddr, naddr, NULL, sn))
|
||||
return (NULL);
|
||||
if ((r->rpool.opts & PF_POOL_TYPEMASK) ==
|
||||
PF_POOL_BITMASK)
|
||||
PF_POOLMASK(naddr, naddr,
|
||||
&r->rpool.cur->addr.v.a.mask, daddr,
|
||||
pd->af);
|
||||
|
||||
if (r->rpool.proxy_port[1]) {
|
||||
u_int32_t tmp_nport;
|
||||
|
||||
tmp_nport = ((ntohs(dport) -
|
||||
ntohs(r->dst.port[0])) %
|
||||
(r->rpool.proxy_port[1] -
|
||||
r->rpool.proxy_port[0] + 1)) +
|
||||
r->rpool.proxy_port[0];
|
||||
|
||||
/* wrap around if necessary */
|
||||
if (tmp_nport > 65535)
|
||||
tmp_nport -= 65535;
|
||||
*nport = htons((u_int16_t)tmp_nport);
|
||||
} else if (r->rpool.proxy_port[0])
|
||||
*nport = htons(r->rpool.proxy_port[0]);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return (NULL);
|
||||
}
|
||||
/*
|
||||
* Translation was a NOP.
|
||||
* Pretend there was no match.
|
||||
*/
|
||||
if (!bcmp(*skp, *nkp, sizeof(struct pf_state_key_cmp))) {
|
||||
#ifdef __FreeBSD__
|
||||
pool_put(&V_pf_state_key_pl, *nkp);
|
||||
pool_put(&V_pf_state_key_pl, *skp);
|
||||
#else
|
||||
pool_put(&pf_state_key_pl, *nkp);
|
||||
pool_put(&pf_state_key_pl, *skp);
|
||||
#endif
|
||||
*skw = *sks = *nkp = *skp = NULL;
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
|
||||
return (r);
|
||||
}
|
||||
|
@ -37,15 +37,17 @@
|
||||
#define PF_TAG_GENERATED 0x01
|
||||
#define PF_TAG_FRAGCACHE 0x02
|
||||
#define PF_TAG_TRANSLATE_LOCALHOST 0x04
|
||||
#define PF_PACKET_LOOPED 0x08
|
||||
#define PF_FASTFWD_OURS_PRESENT 0x10
|
||||
|
||||
struct pf_mtag {
|
||||
void *hdr; /* saved hdr pos in mbuf, for ECN */
|
||||
u_int rtableid; /* alternate routing table id */
|
||||
void *statekey; /* pf stackside statekey */
|
||||
u_int32_t qid; /* queue id */
|
||||
u_int rtableid; /* alternate routing table id */
|
||||
u_int16_t tag; /* tag id */
|
||||
u_int8_t flags;
|
||||
u_int8_t routed;
|
||||
sa_family_t af; /* for ECN */
|
||||
};
|
||||
|
||||
static __inline struct pf_mtag *pf_find_mtag(struct mbuf *);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: pf_norm.c,v 1.107 2006/04/16 00:59:52 pascoe Exp $ */
|
||||
/* $OpenBSD: pf_norm.c,v 1.114 2009/01/29 14:11:45 henning Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 2001 Niels Provos <provos@citi.umich.edu>
|
||||
@ -34,9 +34,9 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef DEV_PFLOG
|
||||
#define NPFLOG DEV_PFLOG
|
||||
#define NPFLOG DEV_PFLOG
|
||||
#else
|
||||
#define NPFLOG 0
|
||||
#define NPFLOG 0
|
||||
#endif
|
||||
#else
|
||||
#include "pflog.h"
|
||||
@ -78,8 +78,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <net/pfvar.h>
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
#include <inttypes.h>
|
||||
|
||||
struct pf_frent {
|
||||
LIST_ENTRY(pf_frent) fr_next;
|
||||
struct ip *fr_ip;
|
||||
@ -118,17 +116,35 @@ struct pf_fragment {
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
TAILQ_HEAD(pf_fragqueue, pf_fragment);
|
||||
TAILQ_HEAD(pf_cachequeue, pf_fragment);
|
||||
VNET_DEFINE(struct pf_fragqueue, pf_fragqueue);
|
||||
#define V_pf_fragqueue VNET(pf_fragqueue)
|
||||
VNET_DEFINE(struct pf_cachequeue, pf_cachequeue);
|
||||
#define V_pf_cachequeue VNET(pf_cachequeue)
|
||||
#else
|
||||
TAILQ_HEAD(pf_fragqueue, pf_fragment) pf_fragqueue;
|
||||
TAILQ_HEAD(pf_cachequeue, pf_fragment) pf_cachequeue;
|
||||
#endif
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
static __inline int pf_frag_compare(struct pf_fragment *,
|
||||
struct pf_fragment *);
|
||||
#else
|
||||
static int pf_frag_compare(struct pf_fragment *,
|
||||
static int pf_frag_compare(struct pf_fragment *,
|
||||
struct pf_fragment *);
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
RB_HEAD(pf_frag_tree, pf_fragment);
|
||||
VNET_DEFINE(struct pf_frag_tree, pf_frag_tree);
|
||||
#define V_pf_frag_tree VNET(pf_frag_tree)
|
||||
VNET_DEFINE(struct pf_frag_tree, pf_cache_tree);
|
||||
#define V_pf_cache_tree VNET(pf_cache_tree)
|
||||
#else
|
||||
RB_HEAD(pf_frag_tree, pf_fragment) pf_frag_tree, pf_cache_tree;
|
||||
#endif
|
||||
RB_PROTOTYPE(pf_frag_tree, pf_fragment, fr_entry, pf_frag_compare);
|
||||
RB_GENERATE(pf_frag_tree, pf_fragment, fr_entry, pf_frag_compare);
|
||||
|
||||
@ -143,24 +159,45 @@ struct mbuf *pf_reassemble(struct mbuf **, struct pf_fragment **,
|
||||
struct mbuf *pf_fragcache(struct mbuf **, struct ip*,
|
||||
struct pf_fragment **, int, int, int *);
|
||||
int pf_normalize_tcpopt(struct pf_rule *, struct mbuf *,
|
||||
struct tcphdr *, int);
|
||||
|
||||
struct tcphdr *, int, sa_family_t);
|
||||
void pf_scrub_ip(struct mbuf **, u_int32_t, u_int8_t,
|
||||
u_int8_t);
|
||||
#ifdef INET6
|
||||
void pf_scrub_ip6(struct mbuf **, u_int8_t);
|
||||
#endif
|
||||
#ifdef __FreeBSD__
|
||||
#define DPFPRINTF(x) do { \
|
||||
if (V_pf_status.debug >= PF_DEBUG_MISC) { \
|
||||
printf("%s: ", __func__); \
|
||||
printf x ; \
|
||||
} \
|
||||
} while(0)
|
||||
#else
|
||||
#define DPFPRINTF(x) do { \
|
||||
if (pf_status.debug >= PF_DEBUG_MISC) { \
|
||||
printf("%s: ", __func__); \
|
||||
printf x ; \
|
||||
} \
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
/* Globals */
|
||||
#ifdef __FreeBSD__
|
||||
uma_zone_t pf_frent_pl, pf_frag_pl, pf_cache_pl, pf_cent_pl;
|
||||
uma_zone_t pf_state_scrub_pl;
|
||||
VNET_DEFINE(uma_zone_t, pf_frent_pl);
|
||||
VNET_DEFINE(uma_zone_t, pf_frag_pl);
|
||||
VNET_DEFINE(uma_zone_t, pf_cache_pl);
|
||||
VNET_DEFINE(uma_zone_t, pf_cent_pl);
|
||||
VNET_DEFINE(uma_zone_t, pf_state_scrub_pl);
|
||||
|
||||
VNET_DEFINE(int, pf_nfrents);
|
||||
#define V_pf_nfrents VNET(pf_nfrents)
|
||||
VNET_DEFINE(int, pf_ncache);
|
||||
#define V_pf_ncache VNET(pf_ncache)
|
||||
#else
|
||||
struct pool pf_frent_pl, pf_frag_pl, pf_cache_pl, pf_cent_pl;
|
||||
struct pool pf_state_scrub_pl;
|
||||
#endif
|
||||
int pf_nfrents, pf_ncache;
|
||||
#endif
|
||||
|
||||
void
|
||||
pf_normalize_init(void)
|
||||
@ -171,9 +208,9 @@ pf_normalize_init(void)
|
||||
* No high water mark support(It's hint not hard limit).
|
||||
* uma_zone_set_max(pf_frag_pl, PFFRAG_FRAG_HIWAT);
|
||||
*/
|
||||
uma_zone_set_max(pf_frent_pl, PFFRAG_FRENT_HIWAT);
|
||||
uma_zone_set_max(pf_cache_pl, PFFRAG_FRCACHE_HIWAT);
|
||||
uma_zone_set_max(pf_cent_pl, PFFRAG_FRCENT_HIWAT);
|
||||
uma_zone_set_max(V_pf_frent_pl, PFFRAG_FRENT_HIWAT);
|
||||
uma_zone_set_max(V_pf_cache_pl, PFFRAG_FRCACHE_HIWAT);
|
||||
uma_zone_set_max(V_pf_cent_pl, PFFRAG_FRCENT_HIWAT);
|
||||
#else
|
||||
pool_init(&pf_frent_pl, sizeof(struct pf_frent), 0, 0, 0, "pffrent",
|
||||
NULL);
|
||||
@ -192,8 +229,13 @@ pf_normalize_init(void)
|
||||
pool_sethardlimit(&pf_cent_pl, PFFRAG_FRCENT_HIWAT, NULL, 0);
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
TAILQ_INIT(&V_pf_fragqueue);
|
||||
TAILQ_INIT(&V_pf_cachequeue);
|
||||
#else
|
||||
TAILQ_INIT(&pf_fragqueue);
|
||||
TAILQ_INIT(&pf_cachequeue);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
@ -224,14 +266,20 @@ void
|
||||
pf_purge_expired_fragments(void)
|
||||
{
|
||||
struct pf_fragment *frag;
|
||||
#ifdef __FreeBSD__
|
||||
u_int32_t expire = time_second -
|
||||
V_pf_default_rule.timeout[PFTM_FRAG];
|
||||
#else
|
||||
u_int32_t expire = time_second -
|
||||
pf_default_rule.timeout[PFTM_FRAG];
|
||||
#endif
|
||||
|
||||
while ((frag = TAILQ_LAST(&pf_fragqueue, pf_fragqueue)) != NULL) {
|
||||
#ifdef __FreeBSD__
|
||||
while ((frag = TAILQ_LAST(&V_pf_fragqueue, pf_fragqueue)) != NULL) {
|
||||
KASSERT((BUFFER_FRAGMENTS(frag)),
|
||||
("BUFFER_FRAGMENTS(frag) == 0: %s", __FUNCTION__));
|
||||
("BUFFER_FRAGMENTS(frag) == 0: %s", __FUNCTION__));
|
||||
#else
|
||||
while ((frag = TAILQ_LAST(&pf_fragqueue, pf_fragqueue)) != NULL) {
|
||||
KASSERT(BUFFER_FRAGMENTS(frag));
|
||||
#endif
|
||||
if (frag->fr_timeout > expire)
|
||||
@ -241,11 +289,12 @@ pf_purge_expired_fragments(void)
|
||||
pf_free_fragment(frag);
|
||||
}
|
||||
|
||||
while ((frag = TAILQ_LAST(&pf_cachequeue, pf_cachequeue)) != NULL) {
|
||||
#ifdef __FreeBSD__
|
||||
while ((frag = TAILQ_LAST(&V_pf_cachequeue, pf_cachequeue)) != NULL) {
|
||||
KASSERT((!BUFFER_FRAGMENTS(frag)),
|
||||
("BUFFER_FRAGMENTS(frag) != 0: %s", __FUNCTION__));
|
||||
("BUFFER_FRAGMENTS(frag) != 0: %s", __FUNCTION__));
|
||||
#else
|
||||
while ((frag = TAILQ_LAST(&pf_cachequeue, pf_cachequeue)) != NULL) {
|
||||
KASSERT(!BUFFER_FRAGMENTS(frag));
|
||||
#endif
|
||||
if (frag->fr_timeout > expire)
|
||||
@ -254,8 +303,8 @@ pf_purge_expired_fragments(void)
|
||||
DPFPRINTF(("expiring %d(%p)\n", frag->fr_id, frag));
|
||||
pf_free_fragment(frag);
|
||||
#ifdef __FreeBSD__
|
||||
KASSERT((TAILQ_EMPTY(&pf_cachequeue) ||
|
||||
TAILQ_LAST(&pf_cachequeue, pf_cachequeue) != frag),
|
||||
KASSERT((TAILQ_EMPTY(&V_pf_cachequeue) ||
|
||||
TAILQ_LAST(&V_pf_cachequeue, pf_cachequeue) != frag),
|
||||
("!(TAILQ_EMPTY() || TAILQ_LAST() == farg): %s",
|
||||
__FUNCTION__));
|
||||
#else
|
||||
@ -275,22 +324,44 @@ pf_flush_fragments(void)
|
||||
struct pf_fragment *frag;
|
||||
int goal;
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
goal = V_pf_nfrents * 9 / 10;
|
||||
DPFPRINTF(("trying to free > %d frents\n",
|
||||
V_pf_nfrents - goal));
|
||||
while (goal < V_pf_nfrents) {
|
||||
#else
|
||||
goal = pf_nfrents * 9 / 10;
|
||||
DPFPRINTF(("trying to free > %d frents\n",
|
||||
pf_nfrents - goal));
|
||||
while (goal < pf_nfrents) {
|
||||
#endif
|
||||
#ifdef __FreeBSD__
|
||||
frag = TAILQ_LAST(&V_pf_fragqueue, pf_fragqueue);
|
||||
#else
|
||||
frag = TAILQ_LAST(&pf_fragqueue, pf_fragqueue);
|
||||
#endif
|
||||
if (frag == NULL)
|
||||
break;
|
||||
pf_free_fragment(frag);
|
||||
}
|
||||
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
goal = V_pf_ncache * 9 / 10;
|
||||
DPFPRINTF(("trying to free > %d cache entries\n",
|
||||
V_pf_ncache - goal));
|
||||
while (goal < V_pf_ncache) {
|
||||
#else
|
||||
goal = pf_ncache * 9 / 10;
|
||||
DPFPRINTF(("trying to free > %d cache entries\n",
|
||||
pf_ncache - goal));
|
||||
while (goal < pf_ncache) {
|
||||
#endif
|
||||
#ifdef __FreeBSD__
|
||||
frag = TAILQ_LAST(&V_pf_cachequeue, pf_cachequeue);
|
||||
#else
|
||||
frag = TAILQ_LAST(&pf_cachequeue, pf_cachequeue);
|
||||
#endif
|
||||
if (frag == NULL)
|
||||
break;
|
||||
pf_free_fragment(frag);
|
||||
@ -312,8 +383,13 @@ pf_free_fragment(struct pf_fragment *frag)
|
||||
LIST_REMOVE(frent, fr_next);
|
||||
|
||||
m_freem(frent->fr_m);
|
||||
#ifdef __FreeBSD__
|
||||
pool_put(&V_pf_frent_pl, frent);
|
||||
V_pf_nfrents--;
|
||||
#else
|
||||
pool_put(&pf_frent_pl, frent);
|
||||
pf_nfrents--;
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
for (frcache = LIST_FIRST(&frag->fr_cache); frcache;
|
||||
@ -325,15 +401,18 @@ pf_free_fragment(struct pf_fragment *frag)
|
||||
LIST_FIRST(&frag->fr_cache)->fr_off >
|
||||
frcache->fr_end),
|
||||
("! (LIST_EMPTY() || LIST_FIRST()->fr_off >"
|
||||
" frcache->fr_end): %s", __FUNCTION__));
|
||||
" frcache->fr_end): %s", __FUNCTION__));
|
||||
|
||||
pool_put(&V_pf_cent_pl, frcache);
|
||||
V_pf_ncache--;
|
||||
#else
|
||||
KASSERT(LIST_EMPTY(&frag->fr_cache) ||
|
||||
LIST_FIRST(&frag->fr_cache)->fr_off >
|
||||
frcache->fr_end);
|
||||
#endif
|
||||
|
||||
pool_put(&pf_cent_pl, frcache);
|
||||
pf_ncache--;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -362,11 +441,21 @@ pf_find_fragment(struct ip *ip, struct pf_frag_tree *tree)
|
||||
/* XXX Are we sure we want to update the timeout? */
|
||||
frag->fr_timeout = time_second;
|
||||
if (BUFFER_FRAGMENTS(frag)) {
|
||||
#ifdef __FreeBSD__
|
||||
TAILQ_REMOVE(&V_pf_fragqueue, frag, frag_next);
|
||||
TAILQ_INSERT_HEAD(&V_pf_fragqueue, frag, frag_next);
|
||||
#else
|
||||
TAILQ_REMOVE(&pf_fragqueue, frag, frag_next);
|
||||
TAILQ_INSERT_HEAD(&pf_fragqueue, frag, frag_next);
|
||||
#endif
|
||||
} else {
|
||||
#ifdef __FreeBSD__
|
||||
TAILQ_REMOVE(&V_pf_cachequeue, frag, frag_next);
|
||||
TAILQ_INSERT_HEAD(&V_pf_cachequeue, frag, frag_next);
|
||||
#else
|
||||
TAILQ_REMOVE(&pf_cachequeue, frag, frag_next);
|
||||
TAILQ_INSERT_HEAD(&pf_cachequeue, frag, frag_next);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -379,13 +468,25 @@ void
|
||||
pf_remove_fragment(struct pf_fragment *frag)
|
||||
{
|
||||
if (BUFFER_FRAGMENTS(frag)) {
|
||||
#ifdef __FreeBSD__
|
||||
RB_REMOVE(pf_frag_tree, &V_pf_frag_tree, frag);
|
||||
TAILQ_REMOVE(&V_pf_fragqueue, frag, frag_next);
|
||||
pool_put(&V_pf_frag_pl, frag);
|
||||
#else
|
||||
RB_REMOVE(pf_frag_tree, &pf_frag_tree, frag);
|
||||
TAILQ_REMOVE(&pf_fragqueue, frag, frag_next);
|
||||
pool_put(&pf_frag_pl, frag);
|
||||
#endif
|
||||
} else {
|
||||
#ifdef __FreeBSD__
|
||||
RB_REMOVE(pf_frag_tree, &V_pf_cache_tree, frag);
|
||||
TAILQ_REMOVE(&V_pf_cachequeue, frag, frag_next);
|
||||
pool_put(&V_pf_cache_pl, frag);
|
||||
#else
|
||||
RB_REMOVE(pf_frag_tree, &pf_cache_tree, frag);
|
||||
TAILQ_REMOVE(&pf_cachequeue, frag, frag_next);
|
||||
pool_put(&pf_cache_pl, frag);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -416,10 +517,18 @@ pf_reassemble(struct mbuf **m0, struct pf_fragment **frag,
|
||||
|
||||
/* Create a new reassembly queue for this packet */
|
||||
if (*frag == NULL) {
|
||||
#ifdef __FreeBSD__
|
||||
*frag = pool_get(&V_pf_frag_pl, PR_NOWAIT);
|
||||
#else
|
||||
*frag = pool_get(&pf_frag_pl, PR_NOWAIT);
|
||||
#endif
|
||||
if (*frag == NULL) {
|
||||
pf_flush_fragments();
|
||||
#ifdef __FreeBSD__
|
||||
*frag = pool_get(&V_pf_frag_pl, PR_NOWAIT);
|
||||
#else
|
||||
*frag = pool_get(&pf_frag_pl, PR_NOWAIT);
|
||||
#endif
|
||||
if (*frag == NULL)
|
||||
goto drop_fragment;
|
||||
}
|
||||
@ -433,8 +542,13 @@ pf_reassemble(struct mbuf **m0, struct pf_fragment **frag,
|
||||
(*frag)->fr_timeout = time_second;
|
||||
LIST_INIT(&(*frag)->fr_queue);
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
RB_INSERT(pf_frag_tree, &V_pf_frag_tree, *frag);
|
||||
TAILQ_INSERT_HEAD(&V_pf_fragqueue, *frag, frag_next);
|
||||
#else
|
||||
RB_INSERT(pf_frag_tree, &pf_frag_tree, *frag);
|
||||
TAILQ_INSERT_HEAD(&pf_fragqueue, *frag, frag_next);
|
||||
#endif
|
||||
|
||||
/* We do not have a previous fragment */
|
||||
frep = NULL;
|
||||
@ -499,8 +613,13 @@ pf_reassemble(struct mbuf **m0, struct pf_fragment **frag,
|
||||
next = LIST_NEXT(frea, fr_next);
|
||||
m_freem(frea->fr_m);
|
||||
LIST_REMOVE(frea, fr_next);
|
||||
#ifdef __FreeBSD__
|
||||
pool_put(&V_pf_frent_pl, frea);
|
||||
V_pf_nfrents--;
|
||||
#else
|
||||
pool_put(&pf_frent_pl, frea);
|
||||
pf_nfrents--;
|
||||
#endif
|
||||
}
|
||||
|
||||
insert:
|
||||
@ -560,26 +679,36 @@ pf_reassemble(struct mbuf **m0, struct pf_fragment **frag,
|
||||
m2 = m->m_next;
|
||||
m->m_next = NULL;
|
||||
m_cat(m, m2);
|
||||
#ifdef __FreeBSD__
|
||||
pool_put(&V_pf_frent_pl, frent);
|
||||
V_pf_nfrents--;
|
||||
#else
|
||||
pool_put(&pf_frent_pl, frent);
|
||||
pf_nfrents--;
|
||||
#endif
|
||||
for (frent = next; frent != NULL; frent = next) {
|
||||
next = LIST_NEXT(frent, fr_next);
|
||||
|
||||
m2 = frent->fr_m;
|
||||
#ifdef __FreeBSD__
|
||||
pool_put(&V_pf_frent_pl, frent);
|
||||
V_pf_nfrents--;
|
||||
#else
|
||||
pool_put(&pf_frent_pl, frent);
|
||||
pf_nfrents--;
|
||||
#endif
|
||||
#ifdef __FreeBSD__
|
||||
m->m_pkthdr.csum_flags &= m2->m_pkthdr.csum_flags;
|
||||
m->m_pkthdr.csum_data += m2->m_pkthdr.csum_data;
|
||||
#endif
|
||||
m_cat(m, m2);
|
||||
}
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
while (m->m_pkthdr.csum_data & 0xffff0000)
|
||||
m->m_pkthdr.csum_data = (m->m_pkthdr.csum_data & 0xffff) +
|
||||
(m->m_pkthdr.csum_data >> 16);
|
||||
#endif
|
||||
|
||||
ip->ip_src = (*frag)->fr_src;
|
||||
ip->ip_dst = (*frag)->fr_dst;
|
||||
|
||||
@ -606,8 +735,13 @@ pf_reassemble(struct mbuf **m0, struct pf_fragment **frag,
|
||||
|
||||
drop_fragment:
|
||||
/* Oops - fail safe - drop packet */
|
||||
#ifdef __FreeBSD__
|
||||
pool_put(&V_pf_frent_pl, frent);
|
||||
V_pf_nfrents--;
|
||||
#else
|
||||
pool_put(&pf_frent_pl, frent);
|
||||
pf_nfrents--;
|
||||
#endif
|
||||
m_freem(m);
|
||||
return (NULL);
|
||||
}
|
||||
@ -632,22 +766,40 @@ pf_fragcache(struct mbuf **m0, struct ip *h, struct pf_fragment **frag, int mff,
|
||||
|
||||
/* Create a new range queue for this packet */
|
||||
if (*frag == NULL) {
|
||||
#ifdef __FreeBSD__
|
||||
*frag = pool_get(&V_pf_cache_pl, PR_NOWAIT);
|
||||
#else
|
||||
*frag = pool_get(&pf_cache_pl, PR_NOWAIT);
|
||||
#endif
|
||||
if (*frag == NULL) {
|
||||
pf_flush_fragments();
|
||||
#ifdef __FreeBSD__
|
||||
*frag = pool_get(&V_pf_cache_pl, PR_NOWAIT);
|
||||
#else
|
||||
*frag = pool_get(&pf_cache_pl, PR_NOWAIT);
|
||||
#endif
|
||||
if (*frag == NULL)
|
||||
goto no_mem;
|
||||
}
|
||||
|
||||
/* Get an entry for the queue */
|
||||
#ifdef __FreeBSD__
|
||||
cur = pool_get(&V_pf_cent_pl, PR_NOWAIT);
|
||||
if (cur == NULL) {
|
||||
pool_put(&V_pf_cache_pl, *frag);
|
||||
#else
|
||||
cur = pool_get(&pf_cent_pl, PR_NOWAIT);
|
||||
if (cur == NULL) {
|
||||
pool_put(&pf_cache_pl, *frag);
|
||||
#endif
|
||||
*frag = NULL;
|
||||
goto no_mem;
|
||||
}
|
||||
#ifdef __FreeBSD__
|
||||
V_pf_ncache++;
|
||||
#else
|
||||
pf_ncache++;
|
||||
#endif
|
||||
|
||||
(*frag)->fr_flags = PFFRAG_NOBUFFER;
|
||||
(*frag)->fr_max = 0;
|
||||
@ -662,8 +814,13 @@ pf_fragcache(struct mbuf **m0, struct ip *h, struct pf_fragment **frag, int mff,
|
||||
LIST_INIT(&(*frag)->fr_cache);
|
||||
LIST_INSERT_HEAD(&(*frag)->fr_cache, cur, fr_next);
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
RB_INSERT(pf_frag_tree, &V_pf_cache_tree, *frag);
|
||||
TAILQ_INSERT_HEAD(&V_pf_cachequeue, *frag, frag_next);
|
||||
#else
|
||||
RB_INSERT(pf_frag_tree, &pf_cache_tree, *frag);
|
||||
TAILQ_INSERT_HEAD(&pf_cachequeue, *frag, frag_next);
|
||||
#endif
|
||||
|
||||
DPFPRINTF(("fragcache[%d]: new %d-%d\n", h->ip_id, off, max));
|
||||
|
||||
@ -782,10 +939,18 @@ pf_fragcache(struct mbuf **m0, struct ip *h, struct pf_fragment **frag, int mff,
|
||||
h->ip_id, -precut, frp->fr_off, frp->fr_end, off,
|
||||
max));
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
cur = pool_get(&V_pf_cent_pl, PR_NOWAIT);
|
||||
#else
|
||||
cur = pool_get(&pf_cent_pl, PR_NOWAIT);
|
||||
#endif
|
||||
if (cur == NULL)
|
||||
goto no_mem;
|
||||
#ifdef __FreeBSD__
|
||||
V_pf_ncache++;
|
||||
#else
|
||||
pf_ncache++;
|
||||
#endif
|
||||
|
||||
cur->fr_off = off;
|
||||
cur->fr_end = max;
|
||||
@ -842,10 +1007,18 @@ pf_fragcache(struct mbuf **m0, struct ip *h, struct pf_fragment **frag, int mff,
|
||||
h->ip_id, -aftercut, off, max, fra->fr_off,
|
||||
fra->fr_end));
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
cur = pool_get(&V_pf_cent_pl, PR_NOWAIT);
|
||||
#else
|
||||
cur = pool_get(&pf_cent_pl, PR_NOWAIT);
|
||||
#endif
|
||||
if (cur == NULL)
|
||||
goto no_mem;
|
||||
#ifdef __FreeBSD__
|
||||
V_pf_ncache++;
|
||||
#else
|
||||
pf_ncache++;
|
||||
#endif
|
||||
|
||||
cur->fr_off = off;
|
||||
cur->fr_end = max;
|
||||
@ -863,8 +1036,13 @@ pf_fragcache(struct mbuf **m0, struct ip *h, struct pf_fragment **frag, int mff,
|
||||
max, fra->fr_off, fra->fr_end));
|
||||
fra->fr_off = cur->fr_off;
|
||||
LIST_REMOVE(cur, fr_next);
|
||||
#ifdef __FreeBSD__
|
||||
pool_put(&V_pf_cent_pl, cur);
|
||||
V_pf_ncache--;
|
||||
#else
|
||||
pool_put(&pf_cent_pl, cur);
|
||||
pf_ncache--;
|
||||
#endif
|
||||
cur = NULL;
|
||||
|
||||
} else if (frp && fra->fr_off <= frp->fr_end) {
|
||||
@ -881,8 +1059,13 @@ pf_fragcache(struct mbuf **m0, struct ip *h, struct pf_fragment **frag, int mff,
|
||||
max, fra->fr_off, fra->fr_end));
|
||||
fra->fr_off = frp->fr_off;
|
||||
LIST_REMOVE(frp, fr_next);
|
||||
#ifdef __FreeBSD__
|
||||
pool_put(&V_pf_cent_pl, frp);
|
||||
V_pf_ncache--;
|
||||
#else
|
||||
pool_put(&pf_cent_pl, frp);
|
||||
pf_ncache--;
|
||||
#endif
|
||||
frp = NULL;
|
||||
|
||||
}
|
||||
@ -965,6 +1148,7 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason,
|
||||
u_int16_t max;
|
||||
int ip_len;
|
||||
int ip_off;
|
||||
int tag = -1;
|
||||
|
||||
r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_SCRUB].active.ptr);
|
||||
while (r != NULL) {
|
||||
@ -985,6 +1169,12 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason,
|
||||
(struct pf_addr *)&h->ip_dst.s_addr, AF_INET,
|
||||
r->dst.neg, NULL))
|
||||
r = r->skip[PF_SKIP_DST_ADDR].ptr;
|
||||
#ifdef __FreeBSD__
|
||||
else if (r->match_tag && !pf_match_tag(m, r, &tag, pd->pf_mtag))
|
||||
#else
|
||||
else if (r->match_tag && !pf_match_tag(m, r, &tag))
|
||||
#endif
|
||||
r = TAILQ_NEXT(r, entries);
|
||||
else
|
||||
break;
|
||||
}
|
||||
@ -1043,7 +1233,11 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason,
|
||||
if ((r->rule_flag & (PFRULE_FRAGCROP|PFRULE_FRAGDROP)) == 0) {
|
||||
/* Fully buffer all of the fragments */
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
frag = pf_find_fragment(h, &V_pf_frag_tree);
|
||||
#else
|
||||
frag = pf_find_fragment(h, &pf_frag_tree);
|
||||
#endif
|
||||
|
||||
/* Check if we saw the last fragment already */
|
||||
if (frag != NULL && (frag->fr_flags & PFFRAG_SEENLAST) &&
|
||||
@ -1051,12 +1245,20 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason,
|
||||
goto bad;
|
||||
|
||||
/* Get an entry for the fragment queue */
|
||||
#ifdef __FreeBSD__
|
||||
frent = pool_get(&V_pf_frent_pl, PR_NOWAIT);
|
||||
#else
|
||||
frent = pool_get(&pf_frent_pl, PR_NOWAIT);
|
||||
#endif
|
||||
if (frent == NULL) {
|
||||
REASON_SET(reason, PFRES_MEMORY);
|
||||
return (PF_DROP);
|
||||
}
|
||||
#ifdef __FreeBSD__
|
||||
V_pf_nfrents++;
|
||||
#else
|
||||
pf_nfrents++;
|
||||
#endif
|
||||
frent->fr_ip = h;
|
||||
frent->fr_m = m;
|
||||
|
||||
@ -1087,7 +1289,11 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason,
|
||||
/* non-buffering fragment cache (drops or masks overlaps) */
|
||||
int nomem = 0;
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
if (dir == PF_OUT && pd->pf_mtag->flags & PF_TAG_FRAGCACHE) {
|
||||
#else
|
||||
if (dir == PF_OUT && m->m_pkthdr.pf.flags & PF_TAG_FRAGCACHE) {
|
||||
#endif
|
||||
/*
|
||||
* Already passed the fragment cache in the
|
||||
* input direction. If we continued, it would
|
||||
@ -1096,7 +1302,11 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason,
|
||||
goto fragment_pass;
|
||||
}
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
frag = pf_find_fragment(h, &V_pf_cache_tree);
|
||||
#else
|
||||
frag = pf_find_fragment(h, &pf_cache_tree);
|
||||
#endif
|
||||
|
||||
/* Check if we saw the last fragment already */
|
||||
if (frag != NULL && (frag->fr_flags & PFFRAG_SEENLAST) &&
|
||||
@ -1127,7 +1337,11 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason,
|
||||
}
|
||||
#endif
|
||||
if (dir == PF_IN)
|
||||
#ifdef __FreeBSD__
|
||||
pd->pf_mtag->flags |= PF_TAG_FRAGCACHE;
|
||||
#else
|
||||
m->m_pkthdr.pf.flags |= PF_TAG_FRAGCACHE;
|
||||
#endif
|
||||
|
||||
if (frag != NULL && (frag->fr_flags & PFFRAG_DROP))
|
||||
goto drop;
|
||||
@ -1143,33 +1357,11 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason,
|
||||
h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_off, h->ip_off, 0);
|
||||
}
|
||||
|
||||
/* Enforce a minimum ttl, may cause endless packet loops */
|
||||
if (r->min_ttl && h->ip_ttl < r->min_ttl) {
|
||||
u_int16_t ip_ttl = h->ip_ttl;
|
||||
|
||||
h->ip_ttl = r->min_ttl;
|
||||
h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_ttl, h->ip_ttl, 0);
|
||||
}
|
||||
|
||||
if (r->rule_flag & PFRULE_RANDOMID) {
|
||||
u_int16_t ip_id = h->ip_id;
|
||||
|
||||
h->ip_id = ip_randomid();
|
||||
h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_id, h->ip_id, 0);
|
||||
}
|
||||
if ((r->rule_flag & (PFRULE_FRAGCROP|PFRULE_FRAGDROP)) == 0)
|
||||
pd->flags |= PFDESC_IP_REAS;
|
||||
|
||||
return (PF_PASS);
|
||||
/* not missing a return here */
|
||||
|
||||
fragment_pass:
|
||||
/* Enforce a minimum ttl, may cause endless packet loops */
|
||||
if (r->min_ttl && h->ip_ttl < r->min_ttl) {
|
||||
u_int16_t ip_ttl = h->ip_ttl;
|
||||
pf_scrub_ip(&m, r->rule_flag, r->min_ttl, r->set_tos);
|
||||
|
||||
h->ip_ttl = r->min_ttl;
|
||||
h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_ttl, h->ip_ttl, 0);
|
||||
}
|
||||
if ((r->rule_flag & (PFRULE_FRAGCROP|PFRULE_FRAGDROP)) == 0)
|
||||
pd->flags |= PFDESC_IP_REAS;
|
||||
return (PF_PASS);
|
||||
@ -1339,9 +1531,7 @@ pf_normalize_ip6(struct mbuf **m0, int dir, struct pfi_kif *kif,
|
||||
if (sizeof(struct ip6_hdr) + plen > m->m_pkthdr.len)
|
||||
goto shortpkt;
|
||||
|
||||
/* Enforce a minimum ttl, may cause endless packet loops */
|
||||
if (r->min_ttl && h->ip6_hlim < r->min_ttl)
|
||||
h->ip6_hlim = r->min_ttl;
|
||||
pf_scrub_ip6(&m, r->min_ttl);
|
||||
|
||||
return (PF_PASS);
|
||||
|
||||
@ -1479,12 +1669,16 @@ pf_normalize_tcp(int dir, struct pfi_kif *kif, struct mbuf *m, int ipoff,
|
||||
}
|
||||
|
||||
/* Process options */
|
||||
if (r->max_mss && pf_normalize_tcpopt(r, m, th, off))
|
||||
if (r->max_mss && pf_normalize_tcpopt(r, m, th, off, pd->af))
|
||||
rewrite = 1;
|
||||
|
||||
/* copy back packet headers if we sanitized */
|
||||
if (rewrite)
|
||||
#ifdef __FreeBSD__
|
||||
m_copyback(m, off, sizeof(*th), (caddr_t)th);
|
||||
#else
|
||||
m_copyback(m, off, sizeof(*th), th);
|
||||
#endif
|
||||
|
||||
return (PF_PASS);
|
||||
|
||||
@ -1506,11 +1700,13 @@ pf_normalize_tcp_init(struct mbuf *m, int off, struct pf_pdesc *pd,
|
||||
#ifdef __FreeBSD__
|
||||
KASSERT((src->scrub == NULL),
|
||||
("pf_normalize_tcp_init: src->scrub != NULL"));
|
||||
|
||||
src->scrub = pool_get(&V_pf_state_scrub_pl, PR_NOWAIT);
|
||||
#else
|
||||
KASSERT(src->scrub == NULL);
|
||||
#endif
|
||||
|
||||
src->scrub = pool_get(&pf_state_scrub_pl, PR_NOWAIT);
|
||||
#endif
|
||||
if (src->scrub == NULL)
|
||||
return (1);
|
||||
bzero(src->scrub, sizeof(*src->scrub));
|
||||
@ -1586,10 +1782,17 @@ pf_normalize_tcp_init(struct mbuf *m, int off, struct pf_pdesc *pd,
|
||||
void
|
||||
pf_normalize_tcp_cleanup(struct pf_state *state)
|
||||
{
|
||||
#ifdef __FreeBSD__
|
||||
if (state->src.scrub)
|
||||
pool_put(&V_pf_state_scrub_pl, state->src.scrub);
|
||||
if (state->dst.scrub)
|
||||
pool_put(&V_pf_state_scrub_pl, state->dst.scrub);
|
||||
#else
|
||||
if (state->src.scrub)
|
||||
pool_put(&pf_state_scrub_pl, state->src.scrub);
|
||||
if (state->dst.scrub)
|
||||
pool_put(&pf_state_scrub_pl, state->dst.scrub);
|
||||
#endif
|
||||
|
||||
/* Someday... flush the TCP segment reassembly descriptors. */
|
||||
}
|
||||
@ -1667,7 +1870,11 @@ pf_normalize_tcp_stateful(struct mbuf *m, int off, struct pf_pdesc *pd,
|
||||
|
||||
if (got_ts) {
|
||||
/* Huh? Multiple timestamps!? */
|
||||
#ifdef __FreeBSD__
|
||||
if (V_pf_status.debug >= PF_DEBUG_MISC) {
|
||||
#else
|
||||
if (pf_status.debug >= PF_DEBUG_MISC) {
|
||||
#endif
|
||||
DPFPRINTF(("multiple TS??"));
|
||||
pf_print_state(state);
|
||||
printf("\n");
|
||||
@ -1736,7 +1943,11 @@ pf_normalize_tcp_stateful(struct mbuf *m, int off, struct pf_pdesc *pd,
|
||||
if (src->scrub && (src->scrub->pfss_flags & PFSS_PAWS) &&
|
||||
(uptime.tv_sec - src->scrub->pfss_last.tv_sec > TS_MAX_IDLE ||
|
||||
time_second - state->creation > TS_MAX_CONN)) {
|
||||
#ifdef __FreeBSD__
|
||||
if (V_pf_status.debug >= PF_DEBUG_MISC) {
|
||||
#else
|
||||
if (pf_status.debug >= PF_DEBUG_MISC) {
|
||||
#endif
|
||||
DPFPRINTF(("src idled out of PAWS\n"));
|
||||
pf_print_state(state);
|
||||
printf("\n");
|
||||
@ -1746,7 +1957,11 @@ pf_normalize_tcp_stateful(struct mbuf *m, int off, struct pf_pdesc *pd,
|
||||
}
|
||||
if (dst->scrub && (dst->scrub->pfss_flags & PFSS_PAWS) &&
|
||||
uptime.tv_sec - dst->scrub->pfss_last.tv_sec > TS_MAX_IDLE) {
|
||||
#ifdef __FreeBSD__
|
||||
if (V_pf_status.debug >= PF_DEBUG_MISC) {
|
||||
#else
|
||||
if (pf_status.debug >= PF_DEBUG_MISC) {
|
||||
#endif
|
||||
DPFPRINTF(("dst idled out of PAWS\n"));
|
||||
pf_print_state(state);
|
||||
printf("\n");
|
||||
@ -1807,7 +2022,7 @@ pf_normalize_tcp_stateful(struct mbuf *m, int off, struct pf_pdesc *pd,
|
||||
* network conditions that re-order packets and
|
||||
* cause our view of them to decrease. For now the
|
||||
* only lowerbound we can safely determine is that
|
||||
* the TS echo will never be less than the orginal
|
||||
* the TS echo will never be less than the original
|
||||
* TS. XXX There is probably a better lowerbound.
|
||||
* Remove TS_MAX_CONN with better lowerbound check.
|
||||
* tescr >= other original TS
|
||||
@ -1830,7 +2045,11 @@ pf_normalize_tcp_stateful(struct mbuf *m, int off, struct pf_pdesc *pd,
|
||||
* this packet.
|
||||
*/
|
||||
if ((ts_fudge = state->rule.ptr->timeout[PFTM_TS_DIFF]) == 0)
|
||||
#ifdef __FreeBSD__
|
||||
ts_fudge = V_pf_default_rule.timeout[PFTM_TS_DIFF];
|
||||
#else
|
||||
ts_fudge = pf_default_rule.timeout[PFTM_TS_DIFF];
|
||||
#endif
|
||||
|
||||
|
||||
/* Calculate max ticks since the last timestamp */
|
||||
@ -1838,7 +2057,7 @@ pf_normalize_tcp_stateful(struct mbuf *m, int off, struct pf_pdesc *pd,
|
||||
#define TS_MICROSECS 1000000 /* microseconds per second */
|
||||
#ifdef __FreeBSD__
|
||||
#ifndef timersub
|
||||
#define timersub(tvp, uvp, vvp) \
|
||||
#define timersub(tvp, uvp, vvp) \
|
||||
do { \
|
||||
(vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \
|
||||
(vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \
|
||||
@ -1895,7 +2114,11 @@ pf_normalize_tcp_stateful(struct mbuf *m, int off, struct pf_pdesc *pd,
|
||||
"\n", dst->scrub->pfss_tsval,
|
||||
dst->scrub->pfss_tsecr, dst->scrub->pfss_tsval0));
|
||||
#endif
|
||||
#ifdef __FreeBSD__
|
||||
if (V_pf_status.debug >= PF_DEBUG_MISC) {
|
||||
#else
|
||||
if (pf_status.debug >= PF_DEBUG_MISC) {
|
||||
#endif
|
||||
pf_print_state(state);
|
||||
pf_print_flags(th->th_flags);
|
||||
printf("\n");
|
||||
@ -1943,7 +2166,11 @@ pf_normalize_tcp_stateful(struct mbuf *m, int off, struct pf_pdesc *pd,
|
||||
* Hey! Someone tried to sneak a packet in. Or the
|
||||
* stack changed its RFC1323 behavior?!?!
|
||||
*/
|
||||
#ifdef __FreeBSD__
|
||||
if (V_pf_status.debug >= PF_DEBUG_MISC) {
|
||||
#else
|
||||
if (pf_status.debug >= PF_DEBUG_MISC) {
|
||||
#endif
|
||||
DPFPRINTF(("Did not receive expected RFC1323 "
|
||||
"timestamp\n"));
|
||||
pf_print_state(state);
|
||||
@ -1970,7 +2197,11 @@ pf_normalize_tcp_stateful(struct mbuf *m, int off, struct pf_pdesc *pd,
|
||||
src->scrub->pfss_flags |= PFSS_DATA_TS;
|
||||
else {
|
||||
src->scrub->pfss_flags |= PFSS_DATA_NOTS;
|
||||
#ifdef __FreeBSD__
|
||||
if (V_pf_status.debug >= PF_DEBUG_MISC && dst->scrub &&
|
||||
#else
|
||||
if (pf_status.debug >= PF_DEBUG_MISC && dst->scrub &&
|
||||
#endif
|
||||
(dst->scrub->pfss_flags & PFSS_TIMESTAMP)) {
|
||||
/* Don't warn if other host rejected RFC1323 */
|
||||
DPFPRINTF(("Broken RFC1323 stack did not "
|
||||
@ -2018,17 +2249,25 @@ pf_normalize_tcp_stateful(struct mbuf *m, int off, struct pf_pdesc *pd,
|
||||
|
||||
int
|
||||
pf_normalize_tcpopt(struct pf_rule *r, struct mbuf *m, struct tcphdr *th,
|
||||
int off)
|
||||
int off, sa_family_t af)
|
||||
{
|
||||
u_int16_t *mss;
|
||||
int thoff;
|
||||
int opt, cnt, optlen = 0;
|
||||
int rewrite = 0;
|
||||
u_char *optp;
|
||||
#ifdef __FreeBSD__
|
||||
u_char opts[TCP_MAXOLEN];
|
||||
#else
|
||||
u_char opts[MAX_TCPOPTLEN];
|
||||
#endif
|
||||
u_char *optp = opts;
|
||||
|
||||
thoff = th->th_off << 2;
|
||||
cnt = thoff - sizeof(struct tcphdr);
|
||||
optp = mtod(m, caddr_t) + off + sizeof(struct tcphdr);
|
||||
|
||||
if (cnt > 0 && !pf_pull_hdr(m, off + sizeof(*th), opts, cnt,
|
||||
NULL, NULL, af))
|
||||
return (rewrite);
|
||||
|
||||
for (; cnt > 0; cnt -= optlen, optp += optlen) {
|
||||
opt = optp[0];
|
||||
@ -2058,5 +2297,63 @@ pf_normalize_tcpopt(struct pf_rule *r, struct mbuf *m, struct tcphdr *th,
|
||||
}
|
||||
}
|
||||
|
||||
if (rewrite)
|
||||
m_copyback(m, off + sizeof(*th), thoff - sizeof(*th), opts);
|
||||
|
||||
return (rewrite);
|
||||
}
|
||||
|
||||
void
|
||||
pf_scrub_ip(struct mbuf **m0, u_int32_t flags, u_int8_t min_ttl, u_int8_t tos)
|
||||
{
|
||||
struct mbuf *m = *m0;
|
||||
struct ip *h = mtod(m, struct ip *);
|
||||
|
||||
/* Clear IP_DF if no-df was requested */
|
||||
if (flags & PFRULE_NODF && h->ip_off & htons(IP_DF)) {
|
||||
u_int16_t ip_off = h->ip_off;
|
||||
|
||||
h->ip_off &= htons(~IP_DF);
|
||||
h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_off, h->ip_off, 0);
|
||||
}
|
||||
|
||||
/* Enforce a minimum ttl, may cause endless packet loops */
|
||||
if (min_ttl && h->ip_ttl < min_ttl) {
|
||||
u_int16_t ip_ttl = h->ip_ttl;
|
||||
|
||||
h->ip_ttl = min_ttl;
|
||||
h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_ttl, h->ip_ttl, 0);
|
||||
}
|
||||
|
||||
/* Enforce tos */
|
||||
if (flags & PFRULE_SET_TOS) {
|
||||
u_int16_t ov, nv;
|
||||
|
||||
ov = *(u_int16_t *)h;
|
||||
h->ip_tos = tos;
|
||||
nv = *(u_int16_t *)h;
|
||||
|
||||
h->ip_sum = pf_cksum_fixup(h->ip_sum, ov, nv, 0);
|
||||
}
|
||||
|
||||
/* random-id, but not for fragments */
|
||||
if (flags & PFRULE_RANDOMID && !(h->ip_off & ~htons(IP_DF))) {
|
||||
u_int16_t ip_id = h->ip_id;
|
||||
|
||||
h->ip_id = ip_randomid();
|
||||
h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_id, h->ip_id, 0);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef INET6
|
||||
void
|
||||
pf_scrub_ip6(struct mbuf **m0, u_int8_t min_ttl)
|
||||
{
|
||||
struct mbuf *m = *m0;
|
||||
struct ip6_hdr *h = mtod(m, struct ip6_hdr *);
|
||||
|
||||
/* Enforce a minimum ttl, may cause endless packet loops */
|
||||
if (min_ttl && h->ip6_hlim < min_ttl)
|
||||
h->ip6_hlim = min_ttl;
|
||||
}
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: pf_osfp.c,v 1.12 2006/12/13 18:14:10 itojun Exp $ */
|
||||
/* $OpenBSD: pf_osfp.c,v 1.14 2008/06/12 18:17:01 henning Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003 Mike Frantzen <frantzen@w4g.org>
|
||||
@ -25,7 +25,10 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#ifdef _KERNEL
|
||||
# include <sys/systm.h>
|
||||
#include <sys/systm.h>
|
||||
#ifndef __FreeBSD__
|
||||
#include <sys/pool.h>
|
||||
#endif
|
||||
#endif /* _KERNEL */
|
||||
#include <sys/mbuf.h>
|
||||
|
||||
@ -42,10 +45,17 @@ __FBSDID("$FreeBSD$");
|
||||
#include <netinet6/in6_var.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _KERNEL
|
||||
# define DPFPRINTF(format, x...) \
|
||||
#ifdef __FreeBSD__
|
||||
#define DPFPRINTF(format, x...) \
|
||||
if (V_pf_status.debug >= PF_DEBUG_NOISY) \
|
||||
printf(format , ##x)
|
||||
#else
|
||||
#define DPFPRINTF(format, x...) \
|
||||
if (pf_status.debug >= PF_DEBUG_NOISY) \
|
||||
printf(format , ##x)
|
||||
#endif
|
||||
#ifdef __FreeBSD__
|
||||
typedef uma_zone_t pool_t;
|
||||
#else
|
||||
@ -55,33 +65,43 @@ typedef struct pool pool_t;
|
||||
#else
|
||||
/* Userland equivalents so we can lend code to tcpdump et al. */
|
||||
|
||||
# include <arpa/inet.h>
|
||||
# include <errno.h>
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
# include <netdb.h>
|
||||
# define pool_t int
|
||||
# define pool_get(pool, flags) malloc(*(pool))
|
||||
# define pool_put(pool, item) free(item)
|
||||
# define pool_init(pool, size, a, ao, f, m, p) (*(pool)) = (size)
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <netdb.h>
|
||||
#define pool_t int
|
||||
#define pool_get(pool, flags) malloc(*(pool))
|
||||
#define pool_put(pool, item) free(item)
|
||||
#define pool_init(pool, size, a, ao, f, m, p) (*(pool)) = (size)
|
||||
|
||||
# ifdef __FreeBSD__
|
||||
# define NTOHS(x) (x) = ntohs((u_int16_t)(x))
|
||||
# endif
|
||||
#ifdef __FreeBSD__
|
||||
#define NTOHS(x) (x) = ntohs((u_int16_t)(x))
|
||||
#endif
|
||||
|
||||
# ifdef PFDEBUG
|
||||
# include <sys/stdarg.h>
|
||||
# define DPFPRINTF(format, x...) fprintf(stderr, format , ##x)
|
||||
# else
|
||||
# define DPFPRINTF(format, x...) ((void)0)
|
||||
# endif /* PFDEBUG */
|
||||
#ifdef PFDEBUG
|
||||
#include <sys/stdarg.h>
|
||||
#define DPFPRINTF(format, x...) fprintf(stderr, format , ##x)
|
||||
#else
|
||||
#define DPFPRINTF(format, x...) ((void)0)
|
||||
#endif /* PFDEBUG */
|
||||
#endif /* _KERNEL */
|
||||
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
SLIST_HEAD(pf_osfp_list, pf_os_fingerprint);
|
||||
VNET_DEFINE(struct pf_osfp_list, pf_osfp_list);
|
||||
#define V_pf_osfp_list VNET(pf_osfp_list)
|
||||
VNET_DEFINE(pool_t, pf_osfp_entry_pl);
|
||||
#define pf_osfp_entry_pl VNET(pf_osfp_entry_pl)
|
||||
VNET_DEFINE(pool_t, pf_osfp_pl);
|
||||
#define pf_osfp_pl VNET(pf_osfp_pl)
|
||||
#else
|
||||
SLIST_HEAD(pf_osfp_list, pf_os_fingerprint) pf_osfp_list;
|
||||
pool_t pf_osfp_entry_pl;
|
||||
pool_t pf_osfp_pl;
|
||||
#endif
|
||||
|
||||
struct pf_os_fingerprint *pf_osfp_find(struct pf_osfp_list *,
|
||||
struct pf_os_fingerprint *, u_int8_t);
|
||||
@ -264,7 +284,11 @@ pf_osfp_fingerprint_hdr(const struct ip *ip, const struct ip6_hdr *ip6, const st
|
||||
(fp.fp_flags & PF_OSFP_WSCALE_DC) ? "*" : "",
|
||||
fp.fp_wscale);
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
if ((fpresult = pf_osfp_find(&V_pf_osfp_list, &fp,
|
||||
#else
|
||||
if ((fpresult = pf_osfp_find(&pf_osfp_list, &fp,
|
||||
#endif
|
||||
PF_OSFP_MAXTTL_OFFSET)))
|
||||
return (&fpresult->fp_oses);
|
||||
return (NULL);
|
||||
@ -310,20 +334,23 @@ pf_osfp_initialize(void)
|
||||
{
|
||||
#if defined(__FreeBSD__) && defined(_KERNEL)
|
||||
int error = ENOMEM;
|
||||
|
||||
|
||||
do {
|
||||
pf_osfp_entry_pl = pf_osfp_pl = NULL;
|
||||
UMA_CREATE(pf_osfp_entry_pl, struct pf_osfp_entry, "pfospfen");
|
||||
UMA_CREATE(pf_osfp_pl, struct pf_os_fingerprint, "pfosfp");
|
||||
error = 0;
|
||||
} while(0);
|
||||
|
||||
SLIST_INIT(&V_pf_osfp_list);
|
||||
#else
|
||||
pool_init(&pf_osfp_entry_pl, sizeof(struct pf_osfp_entry), 0, 0, 0,
|
||||
"pfosfpen", &pool_allocator_nointr);
|
||||
pool_init(&pf_osfp_pl, sizeof(struct pf_os_fingerprint), 0, 0, 0,
|
||||
"pfosfp", &pool_allocator_nointr);
|
||||
#endif
|
||||
SLIST_INIT(&pf_osfp_list);
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#ifdef _KERNEL
|
||||
return (error);
|
||||
@ -337,6 +364,7 @@ pf_osfp_initialize(void)
|
||||
void
|
||||
pf_osfp_cleanup(void)
|
||||
{
|
||||
|
||||
UMA_DESTROY(pf_osfp_entry_pl);
|
||||
UMA_DESTROY(pf_osfp_pl);
|
||||
}
|
||||
@ -349,8 +377,13 @@ pf_osfp_flush(void)
|
||||
struct pf_os_fingerprint *fp;
|
||||
struct pf_osfp_entry *entry;
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
while ((fp = SLIST_FIRST(&V_pf_osfp_list))) {
|
||||
SLIST_REMOVE_HEAD(&V_pf_osfp_list, fp_next);
|
||||
#else
|
||||
while ((fp = SLIST_FIRST(&pf_osfp_list))) {
|
||||
SLIST_REMOVE_HEAD(&pf_osfp_list, fp_next);
|
||||
#endif
|
||||
while ((entry = SLIST_FIRST(&fp->fp_oses))) {
|
||||
SLIST_REMOVE_HEAD(&fp->fp_oses, fp_entry);
|
||||
pool_put(&pf_osfp_entry_pl, entry);
|
||||
@ -377,6 +410,7 @@ pf_osfp_add(struct pf_osfp_ioctl *fpioc)
|
||||
fpadd.fp_wscale = fpioc->fp_wscale;
|
||||
fpadd.fp_ttl = fpioc->fp_ttl;
|
||||
|
||||
#if 0 /* XXX RYAN wants to fix logging */
|
||||
DPFPRINTF("adding osfp %s %s %s = %s%d:%d:%d:%s%d:0x%llx %d "
|
||||
"(TS=%s,M=%s%d,W=%s%d) %x\n",
|
||||
fpioc->fp_os.fp_class_nm, fpioc->fp_os.fp_version_nm,
|
||||
@ -400,17 +434,31 @@ pf_osfp_add(struct pf_osfp_ioctl *fpioc)
|
||||
(fpadd.fp_flags & PF_OSFP_WSCALE_DC) ? "*" : "",
|
||||
fpadd.fp_wscale,
|
||||
fpioc->fp_os.fp_os);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
if ((fp = pf_osfp_find_exact(&V_pf_osfp_list, &fpadd))) {
|
||||
#else
|
||||
if ((fp = pf_osfp_find_exact(&pf_osfp_list, &fpadd))) {
|
||||
#endif
|
||||
SLIST_FOREACH(entry, &fp->fp_oses, fp_entry) {
|
||||
if (PF_OSFP_ENTRY_EQ(entry, &fpioc->fp_os))
|
||||
return (EEXIST);
|
||||
}
|
||||
if ((entry = pool_get(&pf_osfp_entry_pl, PR_NOWAIT)) == NULL)
|
||||
if ((entry = pool_get(&pf_osfp_entry_pl,
|
||||
#ifdef __FreeBSD__
|
||||
PR_NOWAIT)) == NULL)
|
||||
#else
|
||||
PR_WAITOK|PR_LIMITFAIL)) == NULL)
|
||||
#endif
|
||||
return (ENOMEM);
|
||||
} else {
|
||||
if ((fp = pool_get(&pf_osfp_pl, PR_NOWAIT)) == NULL)
|
||||
if ((fp = pool_get(&pf_osfp_pl,
|
||||
#ifdef __FreeBSD__
|
||||
PR_NOWAIT)) == NULL)
|
||||
#else
|
||||
PR_WAITOK|PR_LIMITFAIL)) == NULL)
|
||||
#endif
|
||||
return (ENOMEM);
|
||||
memset(fp, 0, sizeof(*fp));
|
||||
fp->fp_tcpopts = fpioc->fp_tcpopts;
|
||||
@ -422,11 +470,20 @@ pf_osfp_add(struct pf_osfp_ioctl *fpioc)
|
||||
fp->fp_wscale = fpioc->fp_wscale;
|
||||
fp->fp_ttl = fpioc->fp_ttl;
|
||||
SLIST_INIT(&fp->fp_oses);
|
||||
if ((entry = pool_get(&pf_osfp_entry_pl, PR_NOWAIT)) == NULL) {
|
||||
if ((entry = pool_get(&pf_osfp_entry_pl,
|
||||
#ifdef __FreeBSD__
|
||||
PR_NOWAIT)) == NULL) {
|
||||
#else
|
||||
PR_WAITOK|PR_LIMITFAIL)) == NULL) {
|
||||
#endif
|
||||
pool_put(&pf_osfp_pl, fp);
|
||||
return (ENOMEM);
|
||||
}
|
||||
#ifdef __FreeBSD__
|
||||
pf_osfp_insert(&V_pf_osfp_list, fp);
|
||||
#else
|
||||
pf_osfp_insert(&pf_osfp_list, fp);
|
||||
#endif
|
||||
}
|
||||
memcpy(entry, &fpioc->fp_os, sizeof(*entry));
|
||||
|
||||
@ -452,7 +509,7 @@ pf_osfp_find(struct pf_osfp_list *list, struct pf_os_fingerprint *find,
|
||||
{
|
||||
struct pf_os_fingerprint *f;
|
||||
|
||||
#define MATCH_INT(_MOD, _DC, _field) \
|
||||
#define MATCH_INT(_MOD, _DC, _field) \
|
||||
if ((f->fp_flags & _DC) == 0) { \
|
||||
if ((f->fp_flags & _MOD) == 0) { \
|
||||
if (f->_field != find->_field) \
|
||||
@ -480,10 +537,11 @@ pf_osfp_find(struct pf_osfp_list *list, struct pf_os_fingerprint *find,
|
||||
if (find->fp_mss == 0)
|
||||
continue;
|
||||
|
||||
/* Some "smart" NAT devices and DSL routers will tweak the MSS size and
|
||||
/*
|
||||
* Some "smart" NAT devices and DSL routers will tweak the MSS size and
|
||||
* will set it to whatever is suitable for the link type.
|
||||
*/
|
||||
#define SMART_MSS 1460
|
||||
#define SMART_MSS 1460
|
||||
if ((find->fp_wsize % find->fp_mss ||
|
||||
find->fp_wsize / find->fp_mss !=
|
||||
f->fp_wsize) &&
|
||||
@ -495,8 +553,8 @@ pf_osfp_find(struct pf_osfp_list *list, struct pf_os_fingerprint *find,
|
||||
if (find->fp_mss == 0)
|
||||
continue;
|
||||
|
||||
#define MTUOFF (sizeof(struct ip) + sizeof(struct tcphdr))
|
||||
#define SMART_MTU (SMART_MSS + MTUOFF)
|
||||
#define MTUOFF (sizeof(struct ip) + sizeof(struct tcphdr))
|
||||
#define SMART_MTU (SMART_MSS + MTUOFF)
|
||||
if ((find->fp_wsize % (find->fp_mss + MTUOFF) ||
|
||||
find->fp_wsize / (find->fp_mss + MTUOFF) !=
|
||||
f->fp_wsize) &&
|
||||
@ -567,7 +625,11 @@ pf_osfp_get(struct pf_osfp_ioctl *fpioc)
|
||||
|
||||
|
||||
memset(fpioc, 0, sizeof(*fpioc));
|
||||
#ifdef __FreeBSD__
|
||||
SLIST_FOREACH(fp, &V_pf_osfp_list, fp_next) {
|
||||
#else
|
||||
SLIST_FOREACH(fp, &pf_osfp_list, fp_next) {
|
||||
#endif
|
||||
SLIST_FOREACH(entry, &fp->fp_oses, fp_entry) {
|
||||
if (i++ == num) {
|
||||
fpioc->fp_mss = fp->fp_mss;
|
||||
@ -594,7 +656,11 @@ pf_osfp_validate(void)
|
||||
{
|
||||
struct pf_os_fingerprint *f, *f2, find;
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
SLIST_FOREACH(f, &V_pf_osfp_list, fp_next) {
|
||||
#else
|
||||
SLIST_FOREACH(f, &pf_osfp_list, fp_next) {
|
||||
#endif
|
||||
memcpy(&find, f, sizeof(find));
|
||||
|
||||
/* We do a few MSS/th_win percolations to make things unique */
|
||||
@ -606,7 +672,11 @@ pf_osfp_validate(void)
|
||||
find.fp_wsize *= (find.fp_mss + 40);
|
||||
else if (f->fp_flags & PF_OSFP_WSIZE_MOD)
|
||||
find.fp_wsize *= 2;
|
||||
#ifdef __FreeBSD__
|
||||
if (f != (f2 = pf_osfp_find(&V_pf_osfp_list, &find, 0))) {
|
||||
#else
|
||||
if (f != (f2 = pf_osfp_find(&pf_osfp_list, &find, 0))) {
|
||||
#endif
|
||||
if (f2)
|
||||
printf("Found \"%s %s %s\" instead of "
|
||||
"\"%s %s %s\"\n",
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: pf_ruleset.c,v 1.1 2006/10/27 13:56:51 mcbride Exp $ */
|
||||
/* $OpenBSD: pf_ruleset.c,v 1.2 2008/12/18 15:31:37 dhill Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Daniel Hartmeier
|
||||
@ -61,48 +61,55 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
|
||||
#ifdef _KERNEL
|
||||
# define DPFPRINTF(format, x...) \
|
||||
if (pf_status.debug >= PF_DEBUG_NOISY) \
|
||||
printf(format , ##x)
|
||||
#ifdef __FreeBSD__
|
||||
#define rs_malloc(x) malloc(x, M_TEMP, M_NOWAIT)
|
||||
#define DPFPRINTF(format, x...) \
|
||||
if (V_pf_status.debug >= PF_DEBUG_NOISY) \
|
||||
printf(format , ##x)
|
||||
#else
|
||||
#define rs_malloc(x) malloc(x, M_TEMP, M_WAITOK)
|
||||
#define DPFPRINTF(format, x...) \
|
||||
if (pf_status.debug >= PF_DEBUG_NOISY) \
|
||||
printf(format , ##x)
|
||||
#endif
|
||||
#ifdef __FreeBSD__
|
||||
#define rs_malloc(x) malloc(x, M_TEMP, M_NOWAIT|M_ZERO)
|
||||
#else
|
||||
#define rs_malloc(x) malloc(x, M_TEMP, M_WAITOK|M_CANFAIL|M_ZERO)
|
||||
#endif
|
||||
#define rs_free(x) free(x, M_TEMP)
|
||||
|
||||
#else
|
||||
/* Userland equivalents so we can lend code to pfctl et al. */
|
||||
|
||||
# include <arpa/inet.h>
|
||||
# include <errno.h>
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
# define rs_malloc(x) malloc(x)
|
||||
# define rs_free(x) free(x)
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#define rs_malloc(x) calloc(1, x)
|
||||
#define rs_free(x) free(x)
|
||||
|
||||
# ifdef PFDEBUG
|
||||
# include <sys/stdarg.h>
|
||||
# define DPFPRINTF(format, x...) fprintf(stderr, format , ##x)
|
||||
# else
|
||||
# define DPFPRINTF(format, x...) ((void)0)
|
||||
# endif /* PFDEBUG */
|
||||
#ifdef PFDEBUG
|
||||
#include <sys/stdarg.h>
|
||||
#define DPFPRINTF(format, x...) fprintf(stderr, format , ##x)
|
||||
#else
|
||||
#define DPFPRINTF(format, x...) ((void)0)
|
||||
#endif /* PFDEBUG */
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(_KERNEL)
|
||||
#undef V_pf_anchors
|
||||
#define V_pf_anchors pf_anchors
|
||||
|
||||
#undef pf_main_ruleset
|
||||
#define pf_main_ruleset pf_main_anchor.ruleset
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__) && defined(_KERNEL)
|
||||
VNET_DEFINE(struct pf_anchor_global, pf_anchors);
|
||||
VNET_DEFINE(struct pf_anchor, pf_main_anchor);
|
||||
#else
|
||||
struct pf_anchor_global pf_anchors;
|
||||
struct pf_anchor pf_main_anchor;
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
/* XXX: hum? */
|
||||
int pf_get_ruleset_number(u_int8_t);
|
||||
void pf_init_ruleset(struct pf_ruleset *);
|
||||
int pf_anchor_setup(struct pf_rule *,
|
||||
const struct pf_ruleset *, const char *);
|
||||
int pf_anchor_copyout(const struct pf_ruleset *,
|
||||
const struct pf_rule *, struct pfioc_rule *);
|
||||
void pf_anchor_remove(struct pf_rule *);
|
||||
#endif
|
||||
|
||||
static __inline int pf_anchor_compare(struct pf_anchor *, struct pf_anchor *);
|
||||
@ -168,9 +175,14 @@ pf_find_anchor(const char *path)
|
||||
struct pf_anchor *key, *found;
|
||||
|
||||
key = (struct pf_anchor *)rs_malloc(sizeof(*key));
|
||||
memset(key, 0, sizeof(*key));
|
||||
if (key == NULL)
|
||||
return (NULL);
|
||||
strlcpy(key->path, path, sizeof(key->path));
|
||||
#ifdef __FreeBSD__
|
||||
found = RB_FIND(pf_anchor_global, &V_pf_anchors, key);
|
||||
#else
|
||||
found = RB_FIND(pf_anchor_global, &pf_anchors, key);
|
||||
#endif
|
||||
rs_free(key);
|
||||
return (found);
|
||||
}
|
||||
@ -210,7 +222,8 @@ pf_find_or_create_ruleset(const char *path)
|
||||
if (ruleset != NULL)
|
||||
return (ruleset);
|
||||
p = (char *)rs_malloc(MAXPATHLEN);
|
||||
bzero(p, MAXPATHLEN);
|
||||
if (p == NULL)
|
||||
return (NULL);
|
||||
strlcpy(p, path, MAXPATHLEN);
|
||||
while (parent == NULL && (q = strrchr(p, '/')) != NULL) {
|
||||
*q = 0;
|
||||
@ -242,7 +255,6 @@ pf_find_or_create_ruleset(const char *path)
|
||||
rs_free(p);
|
||||
return (NULL);
|
||||
}
|
||||
memset(anchor, 0, sizeof(*anchor));
|
||||
RB_INIT(&anchor->children);
|
||||
strlcpy(anchor->name, q, sizeof(anchor->name));
|
||||
if (parent != NULL) {
|
||||
@ -251,7 +263,11 @@ pf_find_or_create_ruleset(const char *path)
|
||||
strlcat(anchor->path, "/", sizeof(anchor->path));
|
||||
}
|
||||
strlcat(anchor->path, anchor->name, sizeof(anchor->path));
|
||||
#ifdef __FreeBSD__
|
||||
if ((dup = RB_INSERT(pf_anchor_global, &V_pf_anchors, anchor)) !=
|
||||
#else
|
||||
if ((dup = RB_INSERT(pf_anchor_global, &pf_anchors, anchor)) !=
|
||||
#endif
|
||||
NULL) {
|
||||
printf("pf_find_or_create_ruleset: RB_INSERT1 "
|
||||
"'%s' '%s' collides with '%s' '%s'\n",
|
||||
@ -268,7 +284,11 @@ pf_find_or_create_ruleset(const char *path)
|
||||
"RB_INSERT2 '%s' '%s' collides with "
|
||||
"'%s' '%s'\n", anchor->path, anchor->name,
|
||||
dup->path, dup->name);
|
||||
#ifdef __FreeBSD__
|
||||
RB_REMOVE(pf_anchor_global, &V_pf_anchors,
|
||||
#else
|
||||
RB_REMOVE(pf_anchor_global, &pf_anchors,
|
||||
#endif
|
||||
anchor);
|
||||
rs_free(anchor);
|
||||
rs_free(p);
|
||||
@ -304,7 +324,11 @@ pf_remove_if_empty_ruleset(struct pf_ruleset *ruleset)
|
||||
!TAILQ_EMPTY(ruleset->rules[i].inactive.ptr) ||
|
||||
ruleset->rules[i].inactive.open)
|
||||
return;
|
||||
#ifdef __FreeBSD__
|
||||
RB_REMOVE(pf_anchor_global, &V_pf_anchors, ruleset->anchor);
|
||||
#else
|
||||
RB_REMOVE(pf_anchor_global, &pf_anchors, ruleset->anchor);
|
||||
#endif
|
||||
if ((parent = ruleset->anchor->parent) != NULL)
|
||||
RB_REMOVE(pf_anchor_node, &parent->children,
|
||||
ruleset->anchor);
|
||||
@ -328,7 +352,8 @@ pf_anchor_setup(struct pf_rule *r, const struct pf_ruleset *s,
|
||||
if (!name[0])
|
||||
return (0);
|
||||
path = (char *)rs_malloc(MAXPATHLEN);
|
||||
bzero(path, MAXPATHLEN);
|
||||
if (path == NULL)
|
||||
return (1);
|
||||
if (name[0] == '/')
|
||||
strlcpy(path, name + 1, MAXPATHLEN);
|
||||
else {
|
||||
@ -386,7 +411,8 @@ pf_anchor_copyout(const struct pf_ruleset *rs, const struct pf_rule *r,
|
||||
int i;
|
||||
|
||||
a = (char *)rs_malloc(MAXPATHLEN);
|
||||
bzero(a, MAXPATHLEN);
|
||||
if (a == NULL)
|
||||
return (1);
|
||||
if (rs->anchor == NULL)
|
||||
a[0] = 0;
|
||||
else
|
||||
|
@ -1,168 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_inet6.h"
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/libkern.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/md5.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/random.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/bpf.h>
|
||||
#include <net/route.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_var.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip_var.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <netinet/tcp_seq.h>
|
||||
#include <netinet/udp.h>
|
||||
#include <netinet/ip_icmp.h>
|
||||
#include <netinet/in_pcb.h>
|
||||
#include <netinet/tcp_timer.h>
|
||||
#include <netinet/tcp_var.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <net/pfvar.h>
|
||||
|
||||
/*
|
||||
* Following is where TCP initial sequence number generation occurs.
|
||||
*
|
||||
* There are two places where we must use initial sequence numbers:
|
||||
* 1. In SYN-ACK packets.
|
||||
* 2. In SYN packets.
|
||||
*
|
||||
* All ISNs for SYN-ACK packets are generated by the syncache. See
|
||||
* tcp_syncache.c for details.
|
||||
*
|
||||
* The ISNs in SYN packets must be monotonic; TIME_WAIT recycling
|
||||
* depends on this property. In addition, these ISNs should be
|
||||
* unguessable so as to prevent connection hijacking. To satisfy
|
||||
* the requirements of this situation, the algorithm outlined in
|
||||
* RFC 1948 is used, with only small modifications.
|
||||
*
|
||||
* Implementation details:
|
||||
*
|
||||
* Time is based off the system timer, and is corrected so that it
|
||||
* increases by one megabyte per second. This allows for proper
|
||||
* recycling on high speed LANs while still leaving over an hour
|
||||
* before rollover.
|
||||
*
|
||||
* As reading the *exact* system time is too expensive to be done
|
||||
* whenever setting up a TCP connection, we increment the time
|
||||
* offset in two ways. First, a small random positive increment
|
||||
* is added to isn_offset for each connection that is set up.
|
||||
* Second, the function tcp_isn_tick fires once per clock tick
|
||||
* and increments isn_offset as necessary so that sequence numbers
|
||||
* are incremented at approximately ISN_BYTES_PER_SECOND. The
|
||||
* random positive increments serve only to ensure that the same
|
||||
* exact sequence number is never sent out twice (as could otherwise
|
||||
* happen when a port is recycled in less than the system tick
|
||||
* interval.)
|
||||
*
|
||||
* net.inet.tcp.isn_reseed_interval controls the number of seconds
|
||||
* between seeding of isn_secret. This is normally set to zero,
|
||||
* as reseeding should not be necessary.
|
||||
*
|
||||
* Locking of the global variables isn_secret, isn_last_reseed, isn_offset,
|
||||
* isn_offset_old, and isn_ctx is performed using the TCP pcbinfo lock. In
|
||||
* general, this means holding an exclusive (write) lock.
|
||||
*/
|
||||
|
||||
#define ISN_BYTES_PER_SECOND 1048576
|
||||
#define ISN_STATIC_INCREMENT 4096
|
||||
#define ISN_RANDOM_INCREMENT (4096 - 1)
|
||||
|
||||
static u_char pf_isn_secret[32];
|
||||
static int pf_isn_last_reseed;
|
||||
static u_int32_t pf_isn_offset;
|
||||
|
||||
u_int32_t
|
||||
pf_new_isn(struct pf_state *s)
|
||||
{
|
||||
MD5_CTX isn_ctx;
|
||||
u_int32_t md5_buffer[4];
|
||||
u_int32_t new_isn;
|
||||
struct pf_state_host *src, *dst;
|
||||
|
||||
/* Seed if this is the first use, reseed if requested. */
|
||||
if (pf_isn_last_reseed == 0) {
|
||||
read_random(&pf_isn_secret, sizeof(pf_isn_secret));
|
||||
pf_isn_last_reseed = ticks;
|
||||
}
|
||||
|
||||
if (s->direction == PF_IN) {
|
||||
src = &s->ext;
|
||||
dst = &s->gwy;
|
||||
} else {
|
||||
src = &s->lan;
|
||||
dst = &s->ext;
|
||||
}
|
||||
|
||||
/* Compute the md5 hash and return the ISN. */
|
||||
MD5Init(&isn_ctx);
|
||||
MD5Update(&isn_ctx, (u_char *) &dst->port, sizeof(u_short));
|
||||
MD5Update(&isn_ctx, (u_char *) &src->port, sizeof(u_short));
|
||||
#ifdef INET6
|
||||
if (s->af == AF_INET6) {
|
||||
MD5Update(&isn_ctx, (u_char *) &dst->addr,
|
||||
sizeof(struct in6_addr));
|
||||
MD5Update(&isn_ctx, (u_char *) &src->addr,
|
||||
sizeof(struct in6_addr));
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
MD5Update(&isn_ctx, (u_char *) &dst->addr,
|
||||
sizeof(struct in_addr));
|
||||
MD5Update(&isn_ctx, (u_char *) &src->addr,
|
||||
sizeof(struct in_addr));
|
||||
}
|
||||
MD5Update(&isn_ctx, (u_char *) &pf_isn_secret, sizeof(pf_isn_secret));
|
||||
MD5Final((u_char *) &md5_buffer, &isn_ctx);
|
||||
new_isn = (tcp_seq) md5_buffer[0];
|
||||
pf_isn_offset += ISN_STATIC_INCREMENT +
|
||||
(arc4random() & ISN_RANDOM_INCREMENT);
|
||||
new_isn += pf_isn_offset;
|
||||
return (new_isn);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -36,7 +36,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/kthread.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
@ -102,7 +102,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <sys/module.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/bus.h>
|
||||
#include <machine/bus.h>
|
||||
#include <sys/rman.h>
|
||||
|
@ -31,6 +31,8 @@
|
||||
#define AR9287_EEP_MINOR_VER_b AR9287_EEP_MINOR_VER
|
||||
#define AR9287_EEP_NO_BACK_VER AR9287_EEP_MINOR_VER_1
|
||||
|
||||
#define AR9287_RDEXT_DEFAULT 0x1F
|
||||
|
||||
#define AR9287_EEP_START_LOC 128
|
||||
#define AR9287_HTC_EEP_START_LOC 256
|
||||
#define AR9287_NUM_2G_CAL_PIERS 3
|
||||
|
@ -320,6 +320,7 @@ ar9287Attach(uint16_t devid, HAL_SOFTC sc,
|
||||
/* Read Reg Domain */
|
||||
AH_PRIVATE(ah)->ah_currentRD =
|
||||
ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, AH_NULL);
|
||||
AH_PRIVATE(ah)->ah_currentRDext = AR9287_RDEXT_DEFAULT;
|
||||
|
||||
/*
|
||||
* ah_miscMode is populated by ar5416FillCapabilityInfo()
|
||||
|
@ -62,7 +62,6 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
#include <sys/bus.h>
|
||||
|
||||
#include <dev/pci/pcivar.h>
|
||||
|
||||
|
@ -60,7 +60,6 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
#include <sys/bus.h>
|
||||
|
||||
#include <dev/dc/if_dcreg.h>
|
||||
|
||||
|
@ -44,9 +44,6 @@ __FBSDID("$FreeBSD$");
|
||||
* thanks to Matt Thomas for figuring out FreeBSD vs NetBSD vs etc.. diffs.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
|
@ -57,7 +57,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <net/if_types.h>
|
||||
#include <net/bpf.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_media.h>
|
||||
#include <net/if_vlan_var.h>
|
||||
|
||||
|
@ -38,8 +38,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/systm.h>
|
||||
#include <machine/bus.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
|
||||
#include <dev/fdc/fdcvar.h>
|
||||
#include <dev/pccard/pccardvar.h>
|
||||
#include "pccarddevs.h"
|
||||
|
@ -3012,8 +3012,10 @@ static uint32_t fxp_ucode_d101a[] = D101_A_RCVBUNDLE_UCODE;
|
||||
static uint32_t fxp_ucode_d101b0[] = D101_B0_RCVBUNDLE_UCODE;
|
||||
static uint32_t fxp_ucode_d101ma[] = D101M_B_RCVBUNDLE_UCODE;
|
||||
static uint32_t fxp_ucode_d101s[] = D101S_RCVBUNDLE_UCODE;
|
||||
#ifdef notyet
|
||||
static uint32_t fxp_ucode_d102[] = D102_B_RCVBUNDLE_UCODE;
|
||||
static uint32_t fxp_ucode_d102c[] = D102_C_RCVBUNDLE_UCODE;
|
||||
#endif
|
||||
static uint32_t fxp_ucode_d102e[] = D102_E_RCVBUNDLE_UCODE;
|
||||
|
||||
#define UCODE(x) x, sizeof(x)/sizeof(uint32_t)
|
||||
@ -3031,12 +3033,16 @@ static const struct ucode {
|
||||
D101M_CPUSAVER_DWORD, D101M_CPUSAVER_BUNDLE_MAX_DWORD },
|
||||
{ FXP_REV_82559S_A, UCODE(fxp_ucode_d101s),
|
||||
D101S_CPUSAVER_DWORD, D101S_CPUSAVER_BUNDLE_MAX_DWORD },
|
||||
#ifdef notyet
|
||||
{ FXP_REV_82550, UCODE(fxp_ucode_d102),
|
||||
D102_B_CPUSAVER_DWORD, D102_B_CPUSAVER_BUNDLE_MAX_DWORD },
|
||||
{ FXP_REV_82550_C, UCODE(fxp_ucode_d102c),
|
||||
D102_C_CPUSAVER_DWORD, D102_C_CPUSAVER_BUNDLE_MAX_DWORD },
|
||||
#endif
|
||||
{ FXP_REV_82551_F, UCODE(fxp_ucode_d102e),
|
||||
D102_E_CPUSAVER_DWORD, D102_E_CPUSAVER_BUNDLE_MAX_DWORD },
|
||||
{ FXP_REV_82551_10, UCODE(fxp_ucode_d102e),
|
||||
D102_E_CPUSAVER_DWORD, D102_E_CPUSAVER_BUNDLE_MAX_DWORD },
|
||||
{ 0, NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
@ -49,9 +49,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <net/if_types.h>
|
||||
#include <net/netisr.h>
|
||||
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/socket.h>
|
||||
#include <net/netisr.h>
|
||||
#include <net/route.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
|
@ -54,12 +54,9 @@ __FBSDID("$FreeBSD$");
|
||||
#include <cam/scsi/scsi_all.h>
|
||||
#include <cam/scsi/scsi_message.h>
|
||||
|
||||
#include <sys/bus.h>
|
||||
#include <sys/conf.h>
|
||||
#include <machine/md_var.h>
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <dev/mfi/mfireg.h>
|
||||
#include <dev/mfi/mfi_ioctl.h>
|
||||
|
@ -39,7 +39,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/socket.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
|
@ -79,7 +79,7 @@ ptydev_fdopen(struct cdev *dev, int fflags, struct thread *td, struct file *fp)
|
||||
/* Raise a warning when a legacy PTY has been allocated. */
|
||||
if (pty_warningcnt > 0) {
|
||||
pty_warningcnt--;
|
||||
log(LOG_INFO, "pid %d (%s) is using legacy pty devices%s\n",
|
||||
log(LOG_INFO, "pid %d (%s) is using legacy pty devices%s\n",
|
||||
td->td_proc->p_pid, td->td_name,
|
||||
pty_warningcnt ? "" : " - not logging anymore");
|
||||
}
|
||||
@ -139,8 +139,8 @@ static int
|
||||
pty_modevent(module_t mod, int type, void *data)
|
||||
{
|
||||
|
||||
switch(type) {
|
||||
case MOD_LOAD:
|
||||
switch(type) {
|
||||
case MOD_LOAD:
|
||||
EVENTHANDLER_REGISTER(dev_clone, pty_clone, 0, 1000);
|
||||
make_dev_credf(MAKEDEV_ETERNAL_KLD, &ptmx_cdevsw, 0, NULL,
|
||||
UID_ROOT, GID_WHEEL, 0666, "ptmx");
|
||||
|
@ -87,7 +87,6 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <dev/mii/mii.h>
|
||||
|
@ -158,7 +158,7 @@ snp_read(struct cdev *dev, struct uio *uio, int flag)
|
||||
error = devfs_get_cdevpriv((void **)&ss);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
|
||||
tp = ss->snp_tty;
|
||||
if (tp == NULL || tty_gone(tp))
|
||||
return (EIO);
|
||||
@ -198,7 +198,7 @@ snp_write(struct cdev *dev, struct uio *uio, int flag)
|
||||
error = devfs_get_cdevpriv((void **)&ss);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
|
||||
tp = ss->snp_tty;
|
||||
if (tp == NULL || tty_gone(tp))
|
||||
return (EIO);
|
||||
|
@ -643,7 +643,7 @@ scteken_copy(void *arg, const teken_rect_t *r, const teken_pos_t *p)
|
||||
|
||||
while (src < end) {
|
||||
sc_vtb_move(&scp->vtb, src, dst, width);
|
||||
|
||||
|
||||
src += scp->xsize;
|
||||
dst += scp->xsize;
|
||||
}
|
||||
@ -658,7 +658,7 @@ scteken_copy(void *arg, const teken_rect_t *r, const teken_pos_t *p)
|
||||
|
||||
while (src >= end) {
|
||||
sc_vtb_move(&scp->vtb, src, dst, width);
|
||||
|
||||
|
||||
src -= scp->xsize;
|
||||
dst -= scp->xsize;
|
||||
}
|
||||
|
@ -42,7 +42,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <sys/bus.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/file.h>
|
||||
|
@ -62,7 +62,6 @@
|
||||
#include <dev/usb/usb_transfer.h>
|
||||
#include <dev/usb/usb_msctest.h>
|
||||
#include <dev/usb/usb_debug.h>
|
||||
#include <dev/usb/usb_busdma.h>
|
||||
#include <dev/usb/usb_device.h>
|
||||
#include <dev/usb/usb_request.h>
|
||||
#include <dev/usb/usb_util.h>
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user