aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcvs2svn <cvs2svn@FreeBSD.org>2004-08-22 16:53:40 +0000
committercvs2svn <cvs2svn@FreeBSD.org>2004-08-22 16:53:40 +0000
commit5897943788391c9a9b3a61efa832fe803621d5c6 (patch)
tree958169248788d69649041f20ea06ea88c8d21d54
parent8a7574f3ced06b8564a828b8f9ffc0b905f9b7b5 (diff)
This commit was manufactured by cvs2svn to create tagvendor/pf/3.5.001
'pf-vendor-pf_openbsd_3_5_001'.
Notes
Notes: svn path=/vendor/pf/dist/; revision=134173 svn path=/vendor/pf/3.5.001/; revision=134174; tag=vendor/pf/3.5.001
-rw-r--r--contrib/pf/authpf/authpf.8495
-rw-r--r--contrib/pf/authpf/authpf.c911
-rw-r--r--contrib/pf/authpf/pathnames.h37
-rw-r--r--contrib/pf/ftp-proxy/ftp-proxy.8274
-rw-r--r--contrib/pf/ftp-proxy/ftp-proxy.c1329
-rw-r--r--contrib/pf/ftp-proxy/getline.c259
-rw-r--r--contrib/pf/ftp-proxy/util.c301
-rw-r--r--contrib/pf/ftp-proxy/util.h68
-rw-r--r--contrib/pf/man/pf.4837
-rw-r--r--contrib/pf/man/pf.conf.52632
-rw-r--r--contrib/pf/man/pf.os.5242
-rw-r--r--contrib/pf/man/pflog.489
-rw-r--r--contrib/pf/man/pfsync.4226
-rw-r--r--contrib/pf/pflogd/pflogd.8192
-rw-r--r--contrib/pf/pflogd/pflogd.c643
-rw-r--r--contrib/pf/pflogd/pflogd.h47
-rw-r--r--contrib/pf/pflogd/pidfile.c121
-rw-r--r--contrib/pf/pflogd/pidfile.h1
-rw-r--r--contrib/pf/pflogd/privsep.c305
-rw-r--r--contrib/pf/pflogd/privsep_fdpass.c120
20 files changed, 0 insertions, 9129 deletions
diff --git a/contrib/pf/authpf/authpf.8 b/contrib/pf/authpf/authpf.8
deleted file mode 100644
index b6977da2fce9..000000000000
--- a/contrib/pf/authpf/authpf.8
+++ /dev/null
@@ -1,495 +0,0 @@
-.\" $OpenBSD: authpf.8,v 1.31 2003/12/10 04:10:37 beck Exp $
-.\"
-.\" Copyright (c) 2002 Bob Beck (beck@openbsd.org>. 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.
-.\" 3. The name of the author may not be used to endorse or promote products
-.\" derived from this software without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
-.\"
-.Dd January 10, 2002
-.Dt AUTHPF 8
-.Os
-.Sh NAME
-.Nm authpf
-.Nd authenticating gateway user shell
-.Sh SYNOPSIS
-.Nm authpf
-.Sh DESCRIPTION
-.Nm
-is a user shell for authenticating gateways.
-It is used to change
-.Xr pf 4
-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.
-.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 before use.
-.Pp
-.Nm
-is meant to be used with users who can connect via
-.Xr ssh 1
-only.
-On startup,
-.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.
-.Pp
-Each
-.Nm
-process stores its rules in a separate ruleset inside a
-.Xr pf 4
-.Pa anchor
-shared by all
-.Nm
-processes.
-By default, the
-.Pa anchor
-name "authpf" is used, and the ruleset names equal the username and PID of the
-.Nm
-processes as "username(pid)".
-The following rules need to be added to the main ruleset
-.Pa /etc/pf.conf
-in order to cause evaluation of any
-.Nm
-rules:
-.Bd -literal -offset indent
-nat-anchor authpf
-rdr-anchor authpf
-binat-anchor authpf
-anchor authpf
-.Ed
-.Sh FILTER AND TRANSLATION RULES
-Filter and translation rules for
-.Nm
-use the same format described in
-.Xr pf.conf 5 .
-The only difference is that these rules may (and probably should) use
-the macro
-.Em user_ip ,
-which is assigned the connecting IP address whenever
-.Nm
-is run.
-Additionally, the macro
-.Em user_id
-is assigned the user name.
-.Pp
-Filter and nat rules will first be searched for in
-.Pa /etc/authpf/users/$USER/
-and then in
-.Pa /etc/authpf/ .
-Per-user rules from the
-.Pa /etc/authpf/users/$USER/
-directory are intended to be used when non-default rules
-are needed on an individual user basis.
-It is important to ensure that a user can not write or change
-these configuration files.
-.Pp
-Filter and translation rules are loaded from the file
-.Pa /etc/authpf/users/$USER/authpf.rules .
-If this file does not exist the file
-.Pa /etc/authpf/authpf.rules
-is used.
-The
-.Pa authpf.rules
-file must exist in one of the above locations for
-.Nm
-to run.
-.Pp
-Translation rules are also loaded from this file.
-The use of translation rules in an
-.Pa authpf.rules
-file is optional.
-.Sh CONFIGURATION
-Options are controlled by the
-.Pa /etc/authpf/authpf.conf
-file.
-If the file is empty, defaults are used for all
-configuration options.
-The file consists of pairs of the form
-.Li name=value ,
-one per line.
-Currently, the allowed values are as follows:
-.Bl -tag -width Ds
-.It anchor=name
-Use the specified
-.Pa anchor
-name instead of "authpf".
-.El
-.Sh USER MESSAGES
-On successful invocation,
-.Nm
-displays a message telling the user he or she has been authenticated.
-It will additionally display the contents of the file
-.Pa /etc/authpf/authpf.message
-if the file exists and is readable.
-.Pp
-There exist two methods for providing additional granularity to the control
-offered by
-.Nm
-- it is possible to set the gateway to explicitly allow users who have
-authenticated to
-.Xr ssh 1
-and deny access to only a few troublesome individuals.
-This is done by creating a file with the banned user's login name as the
-filename in
-.Pa /etc/authpf/banned/ .
-The contents of this file will be displayed to a banned user, thus providing
-a method for informing the user that they have been banned, and where they can
-go and how to get there if they want to have their service restored.
-This is the default behaviour.
-.Pp
-It is also possible to configure
-.Nm
-to only allow specific users access.
-This is done by listing their login names, one per line, in
-.Pa /etc/authpf/authpf.allow .
-If "*" is found on a line, then all usernames match.
-If
-.Nm
-is unable to verify the user's permission to use the gateway, it will
-print a brief message and die.
-It should be noted that a ban takes precedence over an allow.
-.Pp
-On failure, messages will be logged to
-.Xr syslogd 8
-for the system administrator.
-The user does not see these, but will be told the system is unavailable due to
-technical difficulties.
-The contents of the file
-.Pa /etc/authpf/authpf.problem
-will also be displayed if the file exists and is readable.
-.Sh CONFIGURATION ISSUES
-.Nm
-maintains the changed filter rules as long as the user maintains an
-active session.
-It is important to remember however, that the existence
-of this session means the user is authenticated.
-Because of this, it is important to configure
-.Xr sshd 8
-to ensure the security of the session, and to ensure that the network
-through which users connect is secure.
-.Xr sshd 8
-should be configured to use the
-.Ar ClientAliveInterval
-and
-.Ar ClientAliveCountMax
-parameters to ensure that a ssh session is terminated quickly if
-it becomes unresponsive, or if arp or address spoofing is used to
-hijack the session.
-Note that TCP keepalives are not sufficient for
-this, since they are not secure.
-.Pp
-.Nm
-will remove statetable entries that were created during a user's
-session.
-This ensures that there will be no unauthenticated traffic
-allowed to pass after the controlling
-.Xr ssh 1
-session has been closed.
-.Pp
-.Nm
-is designed for gateway machines which typically do not have regular
-(non-administrative) users using the machine.
-An administrator must remember that
-.Nm
-can be used to modify the filter rules through the environment in
-which it is run, and as such could be used to modify the filter rules
-(based on the contents of the configuration files) by regular
-users.
-In the case where a machine has regular users using it, as well
-as users with
-.Nm
-as their shell, the regular users should be prevented from running
-.Nm
-by using the
-.Pa /etc/authpf/authpf.allow
-or
-.Pa /etc/authpf/banned/
-facilities.
-.Pp
-.Nm
-modifies the packet filter and address translation rules, and because
-of this it needs to be configured carefully.
-.Nm
-will not run and will exit silently if the
-.Pa /etc/authpf/authpf.conf
-file does not exist.
-After considering the effect
-.Nm
-may have on the main packet filter rules, the system administrator may
-enable
-.Nm
-by creating an appropriate
-.Pa /etc/authpf/authpf.conf
-file.
-.Sh EXAMPLES
-.Sy Control Files
-\- To illustrate the user-specific access control
-mechanisms, let us consider a typical user named bob.
-Normally, as long as bob can authenticate himself, the
-.Nm
-program will load the appropriate rules.
-Enter the
-.Pa /etc/authpf/banned/
-directory.
-If bob has somehow fallen from grace in the eyes of the
-powers-that-be, they can prohibit him from using the gateway by creating
-the file
-.Pa /etc/authpf/banned/bob
-containing a message about why he has been banned from using the network.
-Once bob has done suitable penance, his access may be restored by moving or
-removing the file
-.Pa /etc/authpf/banned/bob .
-.Pp
-Now consider a workgroup containing alice, bob, carol and dave.
-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.
-At this point, even if eve could authenticate to
-.Xr sshd 8 ,
-she would not be allowed to use the gateway.
-Adding and removing users from
-the work group is a simple matter of maintaining a list of allowed userids.
-If bob once again manages to annoy the powers-that-be, they can ban him from
-using the gateway by creating the familiar
-.Pa /etc/authpf/banned/bob
-file.
-Though bob is listed in the allow file, he is prevented from using
-this gateway due to the existence of a ban file.
-.Pp
-.Sy Distributed Authentication
-\- It is often desirable to interface with a
-distributed password system rather than forcing the sysadmins to keep a large
-number of local password files in sync.
-The
-.Xr login.conf 5
-mechanism in
-.Ox
-can be used to fork the right shell.
-To make that happen,
-.Xr login.conf 5
-should have entries that look something like this:
-.Bd -literal -offset indent
-shell-default:shell=/bin/csh
-
-default:\e
- ...
- :shell=/usr/sbin/authpf
-
-daemon:\e
- ...
- :shell=/bin/csh:\e
- :tc=default:
-
-staff:\e
- ...
- :shell=/bin/csh:\e
- :tc=default:
-.Ed
-.Pp
-Using a default password file, all users will get
-.Nm
-as their shell except for root who will get
-.Pa /bin/csh .
-.Pp
-.Sy SSH Configuration
-\- As stated earlier,
-.Xr sshd 8
-must be properly configured to detect and defeat network attacks.
-To that end, the following options should be added to
-.Xr sshd_config 5 :
-.Bd -literal -offset indent
-Protocol 2
-ClientAliveInterval 15
-ClientAliveCountMax 3
-.Ed
-.Pp
-This ensures that unresponsive or spoofed sessions are terminated within a
-minute, since a hijacker should not be able to spoof ssh keepalive messages.
-.Pp
-.Sy Banners
-\- Once authenticated, the user is shown the contents of
-.Pa /etc/authpf/authpf.message .
-This message may be a screen-full of the appropriate use policy, the contents
-of
-.Pa /etc/motd
-or something as simple as the following:
-.Bd -literal -offset indent
-This means you will be held accountable by the powers that be
-for traffic originating from your machine, so please play nice.
-.Ed
-.Pp
-To tell the user where to go when the system is broken,
-.Pa /etc/authpf/authpf.problem
-could contain something like this:
-.Bd -literal -offset indent
-Sorry, there appears to be some system problem. To report this
-problem so we can fix it, please phone 1-900-314-1597 or send
-an email to remove@bulkmailerz.net.
-.Ed
-.Pp
-.Sy Packet Filter Rules
-\- In areas where this gateway is used to protect a
-wireless network (a hub with several hundred ports), the default rule set as
-well as the per-user rules should probably allow very few things beyond
-encrypted protocols like
-.Xr ssh 1 ,
-.Xr ssl 8 ,
-or
-.Xr ipsec 4 .
-On a securely switched network, with plug-in jacks for visitors who are
-given authentication accounts, you might want to allow out everything.
-In this context, a secure switch is one that tries to prevent address table
-overflow attacks.
-.Pp
-Example
-.Pa /etc/pf.conf :
-.Bd -literal
-# by default we allow internal clients to talk to us using
-# ssh and use us as a dns server.
-internal_if="fxp1"
-gateway_addr="10.0.1.1"
-nat-anchor authpf
-rdr-anchor authpf
-binat-anchor authpf
-block in on $internal_if from any to any
-pass in quick on $internal_if proto tcp from any to $gateway_addr \e
- port = ssh
-pass in quick on $internal_if proto udp from any to $gateway_addr \e
- port = domain
-anchor authpf
-.Ed
-.Pp
-.Sy For a switched, wired net
-\- This example
-.Pa /etc/authpf/authpf.rules
-makes no real restrictions; it turns the IP address on and off, logging
-TCP connections.
-.Bd -literal
-external_if = "xl0"
-internal_if = "fxp0"
-
-pass in log quick on $internal_if proto tcp from $user_ip to any \e
- keep state
-pass in quick on $internal_if from $user_ip to any
-.Ed
-.Pp
-.Sy For a wireless or shared net
-\- This example
-.Pa /etc/authpf/authpf.rules
-could be used for an insecure network (such as a public wireless network) where
-we might need to be a bit more restrictive.
-.Bd -literal
-internal_if="fxp1"
-ipsec_gw="10.2.3.4"
-
-# rdr ftp for proxying by ftp-proxy(8)
-rdr on $internal_if proto tcp from $user_ip to any port 21 \e
- -> 127.0.0.1 port 8081
-
-# allow out ftp, ssh, www and https only, and allow user to negotiate
-# ipsec with the ipsec server.
-pass in log quick on $internal_if proto tcp from $user_ip to any \e
- port { 21, 22, 80, 443 } flags S/SA
-pass in quick on $internal_if proto tcp from $user_ip to any \e
- port { 21, 22, 80, 443 }
-pass in quick proto udp from $user_ip to $ipsec_gw port = isakmp \e
- keep state
-pass in quick proto esp from $user_ip to $ipsec_gw
-.Ed
-.Pp
-.Sy Dealing with NAT
-\- The following
-.Pa /etc/authpf/authpf.rules
-shows how to deal with NAT, using tags:
-.Bd -literal
-ext_if = "fxp1"
-ext_addr = 129.128.11.10
-int_if = "fxp0"
-# nat and tag connections...
-nat on $ext_if from $user_ip to any tag $user_ip -> $ext_addr
-pass in quick on $int_if from $user_ip to any
-pass out log quick on $ext_if tagged $user_ip keep state
-.Ed
-.Pp
-With the above rules added by
-.Nm ,
-outbound connections corresponding to each users NAT'ed connections
-will be logged as in the example below, where the user may be identified
-from the ruleset name.
-.Bd -literal
-# tcpdump -n -e -ttt -i pflog0
-Oct 31 19:42:30.296553 rule 0.bbeck(20267).1/0(match): pass out on fxp1: \e
-129.128.11.10.60539 > 198.137.240.92.22: S 2131494121:2131494121(0) win \e
-16384 <mss 1460,nop,nop,sackOK> (DF)
-.Ed
-.Sh FILES
-.Bl -tag -width "/etc/authpf/authpf.conf" -compact
-.It Pa /etc/authpf/authpf.conf
-.It Pa /etc/authpf/authpf.allow
-.It Pa /etc/authpf/authpf.rules
-.It Pa /etc/authpf/authpf.message
-.It Pa /etc/authpf/authpf.problem
-.El
-.Sh SEE ALSO
-.Xr pf 4 ,
-.Xr pf.conf 5 ,
-.Xr ftp-proxy 8
-.Sh HISTORY
-The
-.Nm
-program first appeared in
-.Ox 3.1 .
-.Sh BUGS
-Configuration issues are tricky.
-The authenticating
-.Xr ssh 1
-connection may be secured, but if the network is not secured the user may
-expose insecure protocols to attackers on the same network, or enable other
-attackers on the network to pretend to be the user by spoofing their IP
-address.
-.Pp
-.Nm
-is not designed to prevent users from denying service to other users.
diff --git a/contrib/pf/authpf/authpf.c b/contrib/pf/authpf/authpf.c
deleted file mode 100644
index 515cf8edea2b..000000000000
--- a/contrib/pf/authpf/authpf.c
+++ /dev/null
@@ -1,911 +0,0 @@
-/* $OpenBSD: authpf.c,v 1.75 2004/01/29 01:55:10 deraadt Exp $ */
-
-/*
- * Copyright (C) 1998 - 2002 Bob Beck (beck@openbsd.org).
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 <sys/types.h>
-#include <sys/file.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-
-#include <net/if.h>
-#include <net/pfvar.h>
-#include <arpa/inet.h>
-
-#include <err.h>
-#include <errno.h>
-#include <pwd.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <syslog.h>
-#include <unistd.h>
-
-#include <pfctl_parser.h>
-#include <pfctl.h>
-
-#include "pathnames.h"
-
-extern int symset(const char *, const char *, int);
-
-static int read_config(FILE *);
-static void print_message(char *);
-static int allowed_luser(char *);
-static int check_luser(char *, char *);
-static int remove_stale_rulesets(void);
-static int change_filter(int, const char *, const char *);
-static void authpf_kill_states(void);
-
-int dev; /* pf device */
-char anchorname[PF_ANCHOR_NAME_SIZE] = "authpf";
-char rulesetname[PF_RULESET_NAME_SIZE];
-
-FILE *pidfp;
-char *infile; /* file name printed by yyerror() in parse.y */
-char luser[MAXLOGNAME]; /* username */
-char ipsrc[256]; /* ip as a string */
-char pidfile[MAXPATHLEN]; /* we save pid in this file. */
-
-struct timeval Tstart, Tend; /* start and end times of session */
-
-volatile sig_atomic_t want_death;
-static void need_death(int signo);
-static __dead void do_death(int);
-
-/*
- * User shell for authenticating gateways. Sole purpose is to allow
- * a user to ssh to a gateway, and have the gateway modify packet
- * filters to allow access, then remove access when the user finishes
- * up. Meant to be used only from ssh(1) connections.
- */
-int
-main(int argc, char *argv[])
-{
- int lockcnt = 0, n, pidfd;
- FILE *config;
- struct in_addr ina;
- struct passwd *pw;
- char *cp;
- uid_t uid;
-
- config = fopen(PATH_CONFFILE, "r");
-
- if ((cp = getenv("SSH_TTY")) == NULL) {
- syslog(LOG_ERR, "non-interactive session connection for authpf");
- exit(1);
- }
-
- if ((cp = getenv("SSH_CLIENT")) == NULL) {
- syslog(LOG_ERR, "cannot determine connection source");
- exit(1);
- }
-
- if (strlcpy(ipsrc, cp, sizeof(ipsrc)) >= sizeof(ipsrc)) {
- syslog(LOG_ERR, "SSH_CLIENT variable too long");
- exit(1);
- }
- cp = strchr(ipsrc, ' ');
- if (!cp) {
- syslog(LOG_ERR, "corrupt SSH_CLIENT variable %s", ipsrc);
- exit(1);
- }
- *cp = '\0';
- if (inet_pton(AF_INET, ipsrc, &ina) != 1) {
- syslog(LOG_ERR,
- "cannot determine IP from SSH_CLIENT %s", ipsrc);
- exit(1);
- }
- /* open the pf device */
- dev = open(PATH_DEVFILE, O_RDWR);
- if (dev == -1) {
- syslog(LOG_ERR, "cannot open packet filter device (%m)");
- goto die;
- }
-
- uid = getuid();
- pw = getpwuid(uid);
- if (pw == NULL) {
- syslog(LOG_ERR, "cannot find user for uid %u", uid);
- goto die;
- }
- if (strcmp(pw->pw_shell, PATH_AUTHPF_SHELL)) {
- syslog(LOG_ERR, "wrong shell for user %s, uid %u",
- pw->pw_name, pw->pw_uid);
- goto die;
- }
-
- /*
- * Paranoia, but this data _does_ come from outside authpf, and
- * truncation would be bad.
- */
- if (strlcpy(luser, pw->pw_name, sizeof(luser)) >= sizeof(luser)) {
- syslog(LOG_ERR, "username too long: %s", pw->pw_name);
- goto die;
- }
-
- if ((n = snprintf(rulesetname, sizeof(rulesetname), "%s(%ld)",
- luser, (long)getpid())) < 0 || n >= sizeof(rulesetname)) {
- syslog(LOG_INFO, "%s(%ld) too large, ruleset name will be %ld",
- luser, (long)getpid(), (long)getpid());
- if ((n = snprintf(rulesetname, sizeof(rulesetname), "%ld",
- (long)getpid())) < 0 || n >= sizeof(rulesetname)) {
- syslog(LOG_ERR, "pid too large for ruleset name");
- goto die;
- }
- }
-
-
- /* Make our entry in /var/authpf as /var/authpf/ipaddr */
- n = snprintf(pidfile, sizeof(pidfile), "%s/%s", PATH_PIDFILE, ipsrc);
- if (n < 0 || (u_int)n >= sizeof(pidfile)) {
- syslog(LOG_ERR, "path to pidfile too long");
- goto die;
- }
-
- /*
- * If someone else is already using this ip, then this person
- * wants to switch users - so kill the old process and exit
- * as well.
- *
- * Note, we could print a message and tell them to log out, but the
- * usual case of this is that someone has left themselves logged in,
- * with the authenticated connection iconized and someone else walks
- * up to use and automatically logs in before using. If this just
- * gets rid of the old one silently, the new user never knows they
- * could have used someone else's old authentication. If we
- * tell them to log out before switching users it is an invitation
- * for abuse.
- */
-
- do {
- int save_errno, otherpid = -1;
- char otherluser[MAXLOGNAME];
-
- if ((pidfd = open(pidfile, O_RDWR|O_CREAT, 0644)) == -1 ||
- (pidfp = fdopen(pidfd, "r+")) == NULL) {
- if (pidfd != -1)
- close(pidfd);
- syslog(LOG_ERR, "cannot open or create %s: %s", pidfile,
- strerror(errno));
- goto die;
- }
-
- if (flock(fileno(pidfp), LOCK_EX|LOCK_NB) == 0)
- break;
- save_errno = errno;
-
- /* Mark our pid, and username to our file. */
-
- rewind(pidfp);
- /* 31 == MAXLOGNAME - 1 */
- if (fscanf(pidfp, "%d\n%31s\n", &otherpid, otherluser) != 2)
- otherpid = -1;
- syslog(LOG_DEBUG, "tried to lock %s, in use by pid %d: %s",
- pidfile, otherpid, strerror(save_errno));
-
- if (otherpid > 0) {
- syslog(LOG_INFO,
- "killing prior auth (pid %d) of %s by user %s",
- otherpid, ipsrc, otherluser);
- if (kill((pid_t) otherpid, SIGTERM) == -1) {
- syslog(LOG_INFO,
- "could not kill process %d: (%m)",
- otherpid);
- }
- }
-
- /*
- * 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
- */
- if (++lockcnt > 10) {
- syslog(LOG_ERR, "cannot kill previous authpf (pid %d)",
- otherpid);
- goto dogdeath;
- }
- sleep(1);
-
- /* re-open, and try again. The previous authpf process
- * we killed above should unlink the file and release
- * it's lock, giving us a chance to get it now
- */
- fclose(pidfp);
- } while (1);
-
- /* revoke privs */
- seteuid(getuid());
- setuid(getuid());
-
- openlog("authpf", LOG_PID | LOG_NDELAY, LOG_DAEMON);
-
- if (!check_luser(PATH_BAN_DIR, luser) || !allowed_luser(luser)) {
- syslog(LOG_INFO, "user %s prohibited", luser);
- do_death(0);
- }
-
- if (config == NULL || read_config(config)) {
- syslog(LOG_INFO, "bad or nonexistent %s", PATH_CONFFILE);
- do_death(0);
- }
-
- if (remove_stale_rulesets()) {
- syslog(LOG_INFO, "error removing stale rulesets");
- do_death(0);
- }
-
- /* We appear to be making headway, so actually mark our pid */
- rewind(pidfp);
- fprintf(pidfp, "%ld\n%s\n", (long)getpid(), luser);
- fflush(pidfp);
- (void) ftruncate(fileno(pidfp), ftell(pidfp));
-
- if (change_filter(1, luser, ipsrc) == -1) {
- printf("Unable to modify filters\r\n");
- do_death(0);
- }
-
- signal(SIGTERM, need_death);
- signal(SIGINT, need_death);
- signal(SIGALRM, need_death);
- signal(SIGPIPE, need_death);
- signal(SIGHUP, need_death);
- signal(SIGSTOP, need_death);
- signal(SIGTSTP, need_death);
- while (1) {
- printf("\r\nHello %s, ", luser);
- printf("You are authenticated from host \"%s\"\r\n", ipsrc);
- setproctitle("%s@%s", luser, ipsrc);
- print_message(PATH_MESSAGE);
- while (1) {
- sleep(10);
- if (want_death)
- do_death(1);
- }
- }
-
- /* NOTREACHED */
-dogdeath:
- printf("\r\n\r\nSorry, this service is currently unavailable due to ");
- printf("technical difficulties\r\n\r\n");
- print_message(PATH_PROBLEM);
- printf("\r\nYour authentication process (pid %ld) was unable to run\n",
- (long)getpid());
- sleep(180); /* them lusers read reaaaaal slow */
-die:
- do_death(0);
-}
-
-/*
- * reads config file in PATH_CONFFILE to set optional behaviours up
- */
-static int
-read_config(FILE *f)
-{
- char buf[1024];
- int i = 0;
-
- do {
- char **ap;
- char *pair[4], *cp, *tp;
- int len;
-
- if (fgets(buf, sizeof(buf), f) == NULL) {
- fclose(f);
- return (0);
- }
- i++;
- len = strlen(buf);
- if (buf[len - 1] != '\n' && !feof(f)) {
- syslog(LOG_ERR, "line %d too long in %s", i,
- PATH_CONFFILE);
- return (1);
- }
- buf[len - 1] = '\0';
-
- for (cp = buf; *cp == ' ' || *cp == '\t'; cp++)
- ; /* nothing */
-
- if (!*cp || *cp == '#' || *cp == '\n')
- continue;
-
- for (ap = pair; ap < &pair[3] &&
- (*ap = strsep(&cp, "=")) != NULL; ) {
- if (**ap != '\0')
- ap++;
- }
- if (ap != &pair[2])
- goto parse_error;
-
- tp = pair[1] + strlen(pair[1]);
- while ((*tp == ' ' || *tp == '\t') && tp >= pair[1])
- *tp-- = '\0';
-
- if (strcasecmp(pair[0], "anchor") == 0) {
- if (!pair[1][0] || strlcpy(anchorname, pair[1],
- sizeof(anchorname)) >= sizeof(anchorname))
- goto parse_error;
- }
- } while (!feof(f) && !ferror(f));
- fclose(f);
- return (0);
-
-parse_error:
- fclose(f);
- syslog(LOG_ERR, "parse error, line %d of %s", i, PATH_CONFFILE);
- return (1);
-}
-
-
-/*
- * splatter a file to stdout - max line length of 1024,
- * used for spitting message files at users to tell them
- * they've been bad or we're unavailable.
- */
-static void
-print_message(char *filename)
-{
- char buf[1024];
- FILE *f;
-
- if ((f = fopen(filename, "r")) == NULL)
- return; /* fail silently, we don't care if it isn't there */
-
- do {
- if (fgets(buf, sizeof(buf), f) == NULL) {
- fflush(stdout);
- fclose(f);
- return;
- }
- } while (fputs(buf, stdout) != EOF && !feof(f));
- fflush(stdout);
- fclose(f);
-}
-
-/*
- * 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 .
- *
- * If /etc/authpf/authpf.allow does not exist, then we assume that
- * all users who are allowed in by sshd(8) are permitted to
- * use this gateway. If /etc/authpf/authpf.allow does exist, then a
- * user must be listed if the connection is to continue, else
- * the session terminates in the same manner as being banned.
- */
-static int
-allowed_luser(char *luser)
-{
- char *buf, *lbuf;
- int matched;
- size_t len;
- FILE *f;
-
- if ((f = fopen(PATH_ALLOWFILE, "r")) == NULL) {
- if (errno == ENOENT) {
- /*
- * allowfile doesn't exist, thus this gateway
- * isn't restricted to certain users...
- */
- return (1);
- }
-
- /*
- * luser may in fact be allowed, but we can't open
- * the file even though it's there. probably a config
- * problem.
- */
- syslog(LOG_ERR, "cannot open allowed users file %s (%s)",
- PATH_ALLOWFILE, strerror(errno));
- return (0);
- } else {
- /*
- * /etc/authpf/authpf.allow exists, thus we do a linear
- * search to see if they are allowed.
- * also, if username "*" exists, then this is a
- * "public" gateway, such as it is, so let
- * everyone use it.
- */
- lbuf = NULL;
- while ((buf = fgetln(f, &len))) {
- if (buf[len - 1] == '\n')
- buf[len - 1] = '\0';
- else {
- if ((lbuf = (char *)malloc(len + 1)) == NULL)
- err(1, NULL);
- memcpy(lbuf, buf, len);
- lbuf[len] = '\0';
- buf = lbuf;
- }
-
- matched = strcmp(luser, buf) == 0 || strcmp("*", buf) == 0;
-
- if (lbuf != NULL) {
- free(lbuf);
- lbuf = NULL;
- }
-
- if (matched)
- return (1); /* matched an allowed username */
- }
- syslog(LOG_INFO, "denied access to %s: not listed in %s",
- luser, PATH_ALLOWFILE);
-
- /* reuse buf */
- buf = "\n\nSorry, you are not allowed to use this facility!\n";
- fputs(buf, stdout);
- }
- fflush(stdout);
- return (0);
-}
-
-/*
- * check_luser checks to see if user "luser" has been banned
- * from using us by virtue of having an file of the same name
- * in the "luserdir" directory.
- *
- * If the user has been banned, we copy the contents of the file
- * to the user's screen. (useful for telling the user what to
- * do to get un-banned, or just to tell them they aren't
- * going to be un-banned.)
- */
-static int
-check_luser(char *luserdir, char *luser)
-{
- FILE *f;
- int n;
- char tmp[MAXPATHLEN];
-
- n = snprintf(tmp, sizeof(tmp), "%s/%s", luserdir, luser);
- if (n < 0 || (u_int)n >= sizeof(tmp)) {
- syslog(LOG_ERR, "provided banned directory line too long (%s)",
- luserdir);
- return (0);
- }
- if ((f = fopen(tmp, "r")) == NULL) {
- if (errno == ENOENT) {
- /*
- * file or dir doesn't exist, so therefore
- * this luser isn't banned.. all is well
- */
- return (1);
- } else {
- /*
- * luser may in fact be banned, but we can't open the
- * file even though it's there. probably a config
- * problem.
- */
- syslog(LOG_ERR, "cannot open banned file %s (%s)",
- tmp, strerror(errno));
- return (0);
- }
- } else {
- /*
- * luser is banned - spit the file at them to
- * tell what they can do and where they can go.
- */
- syslog(LOG_INFO, "denied access to %s: %s exists",
- luser, tmp);
-
- /* reuse tmp */
- strlcpy(tmp, "\n\n-**- Sorry, you have been banned! -**-\n\n",
- sizeof(tmp));
- while (fputs(tmp, stdout) != EOF && !feof(f)) {
- if (fgets(tmp, sizeof(tmp), f) == NULL) {
- fflush(stdout);
- return (0);
- }
- }
- }
- fflush(stdout);
- return (0);
-}
-
-/*
- * Search for rulesets left by other authpf processes (either because they
- * died ungracefully or were terminated) and remove them.
- */
-static int
-remove_stale_rulesets(void)
-{
- struct pfioc_ruleset prs;
- const int action[PF_RULESET_MAX] = { PF_SCRUB,
- PF_PASS, PF_NAT, PF_BINAT, PF_RDR };
- u_int32_t nr, mnr;
-
- memset(&prs, 0, sizeof(prs));
- strlcpy(prs.anchor, anchorname, sizeof(prs.anchor));
- if (ioctl(dev, DIOCGETRULESETS, &prs)) {
- if (errno == EINVAL)
- return (0);
- else
- return (1);
- }
-
- mnr = prs.nr;
- nr = 0;
- while (nr < mnr) {
- char *s, *t;
- pid_t pid;
-
- prs.nr = nr;
- if (ioctl(dev, DIOCGETRULESET, &prs))
- return (1);
- errno = 0;
- if ((t = strchr(prs.name, '(')) == NULL)
- t = prs.name;
- else
- t++;
- pid = strtoul(t, &s, 10);
- if (!prs.name[0] || errno ||
- (*s && (t == prs.name || *s != ')')))
- return (1);
- if (kill(pid, 0) && errno != EPERM) {
- int i;
-
- for (i = 0; i < PF_RULESET_MAX; ++i) {
- struct pfioc_rule pr;
-
- memset(&pr, 0, sizeof(pr));
- memcpy(pr.anchor, prs.anchor, sizeof(pr.anchor));
- memcpy(pr.ruleset, prs.name, sizeof(pr.ruleset));
- pr.rule.action = action[i];
- if ((ioctl(dev, DIOCBEGINRULES, &pr) ||
- ioctl(dev, DIOCCOMMITRULES, &pr)) &&
- errno != EINVAL)
- return (1);
- }
- mnr--;
- } else
- nr++;
- }
- return (0);
-}
-
-/*
- * Add/remove filter entries for user "luser" from ip "ipsrc"
- */
-static int
-change_filter(int add, const char *luser, const char *ipsrc)
-{
- char fn[MAXPATHLEN];
- FILE *f = NULL;
- struct pfctl pf;
- struct pfr_buffer t;
- int i;
-
- if (luser == NULL || !luser[0] || ipsrc == NULL || !ipsrc[0]) {
- syslog(LOG_ERR, "invalid luser/ipsrc");
- goto error;
- }
-
- if (add) {
- if ((i = snprintf(fn, sizeof(fn), "%s/%s/authpf.rules",
- PATH_USER_DIR, luser)) < 0 || i >= sizeof(fn)) {
- syslog(LOG_ERR, "user rule path too long");
- goto error;
- }
- if ((f = fopen(fn, "r")) == NULL && errno != ENOENT) {
- syslog(LOG_ERR, "cannot open %s (%m)", fn);
- goto error;
- }
- if (f == NULL) {
- if (strlcpy(fn, PATH_PFRULES, sizeof(fn)) >=
- sizeof(fn)) {
- syslog(LOG_ERR, "rule path too long");
- goto error;
- }
- if ((f = fopen(fn, "r")) == NULL) {
- syslog(LOG_ERR, "cannot open %s (%m)", fn);
- goto error;
- }
- }
- }
-
- if (pfctl_load_fingerprints(dev, 0)) {
- syslog(LOG_ERR, "unable to load kernel's OS fingerprints");
- goto error;
- }
- bzero(&t, sizeof(t));
- t.pfrb_type = PFRB_TRANS;
- memset(&pf, 0, sizeof(pf));
- for (i = 0; i < PF_RULESET_MAX; ++i) {
- if (pfctl_add_trans(&t, i, anchorname, rulesetname)) {
- syslog(LOG_ERR, "pfctl_add_trans %m");
- goto error;
- }
- }
- if (pfctl_trans(dev, &t, DIOCXBEGIN, 0)) {
- syslog(LOG_ERR, "DIOCXBEGIN (%s) %m", add?"add":"remove");
- goto error;
- }
-
- if (add) {
- if (symset("user_ip", ipsrc, 0) ||
- symset("user_id", luser, 0)) {
- syslog(LOG_ERR, "symset");
- goto error;
- }
-
- pf.dev = dev;
- pf.trans = &t;
- pf.anchor = anchorname;
- pf.ruleset = rulesetname;
-
- infile = fn;
- if (parse_rules(f, &pf) < 0) {
- syslog(LOG_ERR, "syntax error in rule file: "
- "authpf rules not loaded");
- goto error;
- }
-
- infile = NULL;
- fclose(f);
- f = NULL;
- }
-
- if (pfctl_trans(dev, &t, DIOCXCOMMIT, 0)) {
- syslog(LOG_ERR, "DIOCXCOMMIT (%s) %m", add?"add":"remove");
- goto error;
- }
-
- if (add) {
- gettimeofday(&Tstart, NULL);
- syslog(LOG_INFO, "allowing %s, user %s", ipsrc, luser);
- } else {
- gettimeofday(&Tend, NULL);
- syslog(LOG_INFO, "removed %s, user %s - duration %ld seconds",
- ipsrc, luser, Tend.tv_sec - Tstart.tv_sec);
- }
- return (0);
-
-error:
- if (f != NULL)
- fclose(f);
- if (pfctl_trans(dev, &t, DIOCXROLLBACK, 0))
- syslog(LOG_ERR, "DIOCXROLLBACK (%s) %m", add?"add":"remove");
-
- infile = NULL;
- return (-1);
-}
-
-/*
- * This is to kill off states that would otherwise be left behind stateful
- * rules. This means we don't need to allow in more traffic than we really
- * want to, since we don't have to worry about any luser sessions lasting
- * longer than their ssh session. This function is based on
- * pfctl_kill_states from pfctl.
- */
-static void
-authpf_kill_states(void)
-{
- struct pfioc_state_kill psk;
- struct in_addr target;
-
- memset(&psk, 0, sizeof(psk));
- psk.psk_af = AF_INET;
-
- inet_pton(AF_INET, ipsrc, &target);
-
- /* Kill all states from ipsrc */
- psk.psk_src.addr.v.a.addr.v4 = target;
- memset(&psk.psk_src.addr.v.a.mask, 0xff,
- sizeof(psk.psk_src.addr.v.a.mask));
- if (ioctl(dev, DIOCKILLSTATES, &psk))
- syslog(LOG_ERR, "DIOCKILLSTATES failed (%m)");
-
- /* Kill all states to ipsrc */
- psk.psk_af = AF_INET;
- memset(&psk.psk_src, 0, sizeof(psk.psk_src));
- psk.psk_dst.addr.v.a.addr.v4 = target;
- memset(&psk.psk_dst.addr.v.a.mask, 0xff,
- sizeof(psk.psk_dst.addr.v.a.mask));
- if (ioctl(dev, DIOCKILLSTATES, &psk))
- syslog(LOG_ERR, "DIOCKILLSTATES failed (%m)");
-}
-
-/* signal handler that makes us go away properly */
-static void
-need_death(int signo)
-{
- want_death = 1;
-}
-
-/*
- * function that removes our stuff when we go away.
- */
-static __dead void
-do_death(int active)
-{
- int ret = 0;
-
- if (active) {
- change_filter(0, luser, ipsrc);
- authpf_kill_states();
- remove_stale_rulesets();
- }
- if (pidfp)
- ftruncate(fileno(pidfp), 0);
- if (pidfile[0])
- if (unlink(pidfile) == -1)
- syslog(LOG_ERR, "cannot unlink %s (%m)", pidfile);
- exit(ret);
-}
-
-/*
- * callbacks for parse_rules(void)
- */
-
-int
-pfctl_add_rule(struct pfctl *pf, struct pf_rule *r)
-{
- u_int8_t rs_num;
- struct pfioc_rule pr;
-
- switch (r->action) {
- case PF_PASS:
- case PF_DROP:
- rs_num = PF_RULESET_FILTER;
- break;
- case PF_SCRUB:
- rs_num = PF_RULESET_SCRUB;
- break;
- case PF_NAT:
- case PF_NONAT:
- rs_num = PF_RULESET_NAT;
- break;
- case PF_RDR:
- case PF_NORDR:
- rs_num = PF_RULESET_RDR;
- break;
- case PF_BINAT:
- case PF_NOBINAT:
- rs_num = PF_RULESET_BINAT;
- break;
- default:
- syslog(LOG_ERR, "invalid rule action %d", r->action);
- return (1);
- }
-
- bzero(&pr, sizeof(pr));
- strlcpy(pr.anchor, pf->anchor, sizeof(pr.anchor));
- strlcpy(pr.ruleset, pf->ruleset, sizeof(pr.ruleset));
- if (pfctl_add_pool(pf, &r->rpool, r->af))
- return (1);
- pr.ticket = pfctl_get_ticket(pf->trans, rs_num, pf->anchor,
- pf->ruleset);
- pr.pool_ticket = pf->paddr.ticket;
- memcpy(&pr.rule, r, sizeof(pr.rule));
- if (ioctl(pf->dev, DIOCADDRULE, &pr)) {
- syslog(LOG_ERR, "DIOCADDRULE %m");
- return (1);
- }
- pfctl_clear_pool(&r->rpool);
- return (0);
-}
-
-int
-pfctl_add_pool(struct pfctl *pf, struct pf_pool *p, sa_family_t af)
-{
- struct pf_pooladdr *pa;
-
- if (ioctl(pf->dev, DIOCBEGINADDRS, &pf->paddr)) {
- syslog(LOG_ERR, "DIOCBEGINADDRS %m");
- return (1);
- }
- pf->paddr.af = af;
- TAILQ_FOREACH(pa, &p->list, entries) {
- memcpy(&pf->paddr.addr, pa, sizeof(struct pf_pooladdr));
- if (ioctl(pf->dev, DIOCADDADDR, &pf->paddr)) {
- syslog(LOG_ERR, "DIOCADDADDR %m");
- return (1);
- }
- }
- return (0);
-}
-
-void
-pfctl_clear_pool(struct pf_pool *pool)
-{
- struct pf_pooladdr *pa;
-
- while ((pa = TAILQ_FIRST(&pool->list)) != NULL) {
- TAILQ_REMOVE(&pool->list, pa, entries);
- free(pa);
- }
-}
-
-int
-pfctl_add_altq(struct pfctl *pf, struct pf_altq *a)
-{
- fprintf(stderr, "altq rules not supported in authpf\n");
- return (1);
-}
-
-int
-pfctl_set_optimization(struct pfctl *pf, const char *opt)
-{
- fprintf(stderr, "set optimization not supported in authpf\n");
- return (1);
-}
-
-int
-pfctl_set_logif(struct pfctl *pf, char *ifname)
-{
- fprintf(stderr, "set loginterface not supported in authpf\n");
- return (1);
-}
-
-int
-pfctl_set_hostid(struct pfctl *pf, u_int32_t hostid)
-{
- fprintf(stderr, "set hostid not supported in authpf\n");
- return (1);
-}
-
-int
-pfctl_set_timeout(struct pfctl *pf, const char *opt, int seconds, int quiet)
-{
- fprintf(stderr, "set timeout not supported in authpf\n");
- return (1);
-}
-
-int
-pfctl_set_limit(struct pfctl *pf, const char *opt, unsigned int limit)
-{
- fprintf(stderr, "set limit not supported in authpf\n");
- return (1);
-}
-
-int
-pfctl_set_debug(struct pfctl *pf, char *d)
-{
- fprintf(stderr, "set debug not supported in authpf\n");
- return (1);
-}
-
-int
-pfctl_define_table(char *name, int flags, int addrs, const char *anchor,
- const char *ruleset, struct pfr_buffer *ab, u_int32_t ticket)
-{
- fprintf(stderr, "table definitions not yet supported in authpf\n");
- return (1);
-}
-
-int
-pfctl_rules(int dev, char *filename, int opts, char *anchorname,
- char *rulesetname, struct pfr_buffer *t)
-{
- /* never called, no anchors inside anchors, but we need the stub */
- fprintf(stderr, "load anchor not supported from authpf\n");
- return (1);
-}
-
-void
-pfctl_print_title(char *title)
-{
-}
diff --git a/contrib/pf/authpf/pathnames.h b/contrib/pf/authpf/pathnames.h
deleted file mode 100644
index 97d1d7426b04..000000000000
--- a/contrib/pf/authpf/pathnames.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* $OpenBSD: pathnames.h,v 1.6 2003/06/03 20:38:59 beck Exp $ */
-
-/*
- * Copyright (C) 2002 Chris Kuethe (ckuethe@ualberta.ca)
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- */
-
-#define PATH_CONFFILE "/etc/authpf/authpf.conf"
-#define PATH_ALLOWFILE "/etc/authpf/authpf.allow"
-#define PATH_PFRULES "/etc/authpf/authpf.rules"
-#define PATH_PROBLEM "/etc/authpf/authpf.problem"
-#define PATH_MESSAGE "/etc/authpf/authpf.message"
-#define PATH_USER_DIR "/etc/authpf/users"
-#define PATH_BAN_DIR "/etc/authpf/banned"
-#define PATH_DEVFILE "/dev/pf"
-#define PATH_PIDFILE "/var/authpf"
-#define PATH_AUTHPF_SHELL "/usr/sbin/authpf"
diff --git a/contrib/pf/ftp-proxy/ftp-proxy.8 b/contrib/pf/ftp-proxy/ftp-proxy.8
deleted file mode 100644
index e68bdde495cc..000000000000
--- a/contrib/pf/ftp-proxy/ftp-proxy.8
+++ /dev/null
@@ -1,274 +0,0 @@
-.\" $OpenBSD: ftp-proxy.8,v 1.40 2004/03/16 08:50:07 jmc Exp $
-.\"
-.\" Copyright (c) 1996-2001
-.\" Obtuse Systems Corporation, 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.
-.\" 3. 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 OBTUSE SYSTEMS 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 OBTUSE 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.
-.\"
-.Dd August 17, 2001
-.Dt FTP-PROXY 8
-.Os
-.Sh NAME
-.Nm ftp-proxy
-.Nd Internet File Transfer Protocol proxy server
-.Sh SYNOPSIS
-.Nm ftp-proxy
-.Op Fl AnrVw
-.Op Fl a Ar address
-.Op Fl D Ar debuglevel
-.Op Fl g Ar group
-.Op Fl M Ar maxport
-.Op Fl m Ar minport
-.Op Fl t Ar timeout
-.Op Fl u Ar user
-.Sh DESCRIPTION
-.Nm
-is a proxy for the Internet File Transfer Protocol.
-The proxy uses
-.Xr pf 4
-and expects to have the FTP control connection as described in
-.Xr services 5
-redirected to it via a
-.Xr pf 4
-.Em rdr
-command.
-An example of how to do that is further down in this document.
-.Pp
-The options are as follows:
-.Bl -tag -width Ds
-.It Fl A
-Permit only anonymous FTP connections.
-The proxy will allow connections to log in to other sites as the user
-.Qq ftp
-or
-.Qq anonymous
-only.
-Any attempt to log in as another user will be blocked by the proxy.
-.It Fl a Ar address
-Specify the local IP address to use in
-.Xr bind 2
-as the source for connections made by
-.Nm ftp-proxy
-when connecting to destination FTP servers.
-This may be necessary if the interface address of
-your default route is not reachable from the destinations
-.Nm
-is attempting connections to, or this address is different from the one
-connections are being NATed to.
-In the usual case this means that
-.Ar address
-should be a publicly visible IP address assigned to one of
-the interfaces on the machine running
-.Nm
-and should be the same address to which you are translating traffic
-if you are using the
-.Fl n
-option.
-.It Fl D Ar debuglevel
-Specify a debug level, where the proxy emits verbose debug output
-into
-.Xr syslogd 8
-at level
-.Dv LOG_DEBUG .
-Meaningful values of debuglevel are 0-3, where 0 is no debug output and
-3 is lots of debug output, the default being 0.
-.It Fl g Ar group
-Specify the named group to drop group privileges to, after doing
-.Xr pf 4
-lookups which require root.
-By default,
-.Nm
-uses the default group of the user it drops privilege to.
-.It Fl M Ar maxport
-Specify the upper end of the port range the proxy will use for the
-data connections it establishes.
-The default is
-.Dv IPPORT_HILASTAUTO
-defined in
-.Aq Pa netinet/in.h
-as 65535.
-.It Fl m Ar minport
-Specify the lower end of the port range the proxy will use for all
-data connections it establishes.
-The default is
-.Dv IPPORT_HIFIRSTAUTO
-defined in
-.Aq Pa netinet/in.h
-as 49152.
-.It Fl n
-Activate network address translation
-.Pq NAT
-mode.
-In this mode, the proxy will not attempt to proxy passive mode
-.Pq PASV or EPSV
-data connections.
-In order for this to work, the machine running the proxy will need to
-be forwarding packets and doing network address translation to allow
-the outbound passive connections from the client to reach the server.
-See
-.Xr pf.conf 5
-for more details on NAT.
-The proxy only ignores passive mode data connections when using this flag;
-it will still proxy PORT and EPRT mode data connections.
-Without this flag,
-.Nm
-does not require any IP forwarding or NAT beyond the
-.Em rdr
-necessary to capture the FTP control connection.
-.It Fl r
-Use reverse host
-.Pq reverse DNS
-lookups for logging and libwrap use.
-By default,
-the proxy does not look up hostnames for libwrap or logging purposes.
-.It Fl t Ar timeout
-Specifies a timeout, in seconds.
-The proxy will exit and close open connections if it sees no data
-for the duration of the timeout.
-The default is 0, which means the proxy will not time out.
-.It Fl u Ar user
-Specify the named user to drop privilege to, after doing
-.Xr pf 4
-lookups which require root privilege.
-By default,
-.Nm
-drops privilege to the user
-.Em proxy .
-.Pp
-Running as root means that the source of data connections the proxy makes
-for PORT and EPRT will be the RFC mandated port 20.
-When running as a non-root user, the source of the data connections from
-.Nm
-will be chosen randomly from the range
-.Ar minport
-to
-.Ar maxport
-as described above.
-.It Fl V
-Be verbose.
-With this option the proxy logs the control commands
-sent by clients and the replies sent by the servers to
-.Xr syslogd 8 .
-.It Fl w
-Use the tcp wrapper access control library
-.Xr hosts_access 3 ,
-allowing connections to be allowed or denied based on the tcp wrapper's
-.Xr hosts.allow 5
-and
-.Xr hosts.deny 5
-files.
-The proxy does libwrap operations after determining the destination
-of the captured control connection, so that tcp wrapper rules may
-be written based on the destination as well as the source of FTP connections.
-.El
-.Pp
-.Nm ftp-proxy
-is run from
-.Xr inetd 8
-and requires that FTP connections are redirected to it using a
-.Em rdr
-rule.
-A typical way to do this would be to use a
-.Xr pf.conf 5
-rule such as
-.Bd -literal -offset 2n
-int_if = \&"xl0\&"
-rdr pass on $int_if proto tcp from any to any port 21 -> 127.0.0.1 port 8021
-.Ed
-.Pp
-.Xr inetd 8
-must then be configured to run
-.Nm
-on the port from above using
-.Bd -literal -offset 2n
-127.0.0.1:8021 stream tcp nowait root /usr/libexec/ftp-proxy ftp-proxy
-.Ed
-.Pp
-in
-.Xr inetd.conf 5 .
-.Pp
-.Nm
-accepts the redirected control connections and forwards them
-to the server.
-The proxy replaces the address and port number that the client
-sends through the control connection to the server with its own
-address and proxy port, where it listens for the data connection.
-When the server opens the data connection back to this port, the
-proxy forwards it to the client.
-The
-.Xr pf.conf 5
-rules need to let pass connections to these proxy ports
-(see options
-.Fl u , m ,
-and
-.Fl M
-above) in on the external interface.
-The following example allows only ports 49152 to 65535 to pass in
-statefully:
-.Bd -literal -offset indent
-block in on $ext_if proto tcp all
-pass in on $ext_if inet proto tcp from any to $ext_if \e
- port > 49151 keep state
-.Ed
-.Pp
-Alternatively, rules can make use of the fact that by default,
-.Nm
-runs as user
-.Qq proxy
-to allow the backchannel connections, as in the following example:
-.Bd -literal -offset indent
-block in on $ext_if proto tcp all
-pass in on $ext_if inet proto tcp from any to $ext_if \e
- user proxy keep state
-.Ed
-.Pp
-These examples do not cover the connections from the proxy to the
-foreign FTP server.
-If one does not pass outgoing connections by default additional rules
-are needed.
-.Sh SEE ALSO
-.Xr ftp 1 ,
-.Xr pf 4 ,
-.Xr hosts.allow 5 ,
-.Xr hosts.deny 5 ,
-.Xr inetd.conf 5 ,
-.Xr pf.conf 5 ,
-.Xr inetd 8 ,
-.Xr pfctl 8 ,
-.Xr syslogd 8
-.Sh BUGS
-Extended Passive mode
-.Pq EPSV
-is not supported by the proxy and will not work unless the proxy is run
-in network address translation mode.
-When not in network address translation mode, the proxy returns an error
-to the client, hopefully forcing the client to revert to passive mode
-.Pq PASV
-which is supported.
-EPSV will work in network address translation mode, assuming a
-.Xr pf.conf 5
-setup which allows the EPSV connections through to their destinations.
-.Pp
-IPv6 is not yet supported.
diff --git a/contrib/pf/ftp-proxy/ftp-proxy.c b/contrib/pf/ftp-proxy/ftp-proxy.c
deleted file mode 100644
index 18bc0a619a20..000000000000
--- a/contrib/pf/ftp-proxy/ftp-proxy.c
+++ /dev/null
@@ -1,1329 +0,0 @@
-/* $OpenBSD: ftp-proxy.c,v 1.35 2004/03/14 21:51:44 dhartmei Exp $ */
-
-/*
- * Copyright (c) 1996-2001
- * Obtuse Systems Corporation. 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.
- * 3. Neither the name of the Obtuse Systems 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 OBTUSE SYSTEMS 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 OBTUSE SYSTEMS CORPORATION 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.
- *
- */
-
-/*
- * ftp proxy, Originally based on juniper_ftp_proxy from the Obtuse
- * Systems juniper firewall, written by Dan Boulet <danny@obtuse.com>
- * and Bob Beck <beck@obtuse.com>
- *
- * This version basically passes everything through unchanged except
- * for the PORT and the * "227 Entering Passive Mode" reply.
- *
- * A PORT command is handled by noting the IP address and port number
- * specified and then configuring a listen port on some very high port
- * number and telling the server about it using a PORT message.
- * We then watch for an in-bound connection on the port from the server
- * and connect to the client's port when it happens.
- *
- * A "227 Entering Passive Mode" reply is handled by noting the IP address
- * and port number specified and then configuring a listen port on some
- * very high port number and telling the client about it using a
- * "227 Entering Passive Mode" reply.
- * We then watch for an in-bound connection on the port from the client
- * and connect to the server's port when it happens.
- *
- * supports tcp wrapper lookups/access control with the -w flag using
- * the real destination address - the tcp wrapper stuff is done after
- * the real destination address is retrieved from pf
- *
- */
-
-/*
- * TODO:
- * Plenty, this is very basic, with the idea to get it in clean first.
- *
- * - IPv6 and EPASV support
- * - Content filter support
- * - filename filter support
- * - per-user rules perhaps.
- */
-
-#include <sys/param.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-
-#include <net/if.h>
-#include <netinet/in.h>
-
-#include <arpa/inet.h>
-
-#include <ctype.h>
-#include <errno.h>
-#include <grp.h>
-#include <netdb.h>
-#include <pwd.h>
-#include <signal.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sysexits.h>
-#include <syslog.h>
-#include <unistd.h>
-
-#include "util.h"
-
-#ifdef LIBWRAP
-#include <tcpd.h>
-int allow_severity = LOG_INFO;
-int deny_severity = LOG_NOTICE;
-#endif /* LIBWRAP */
-
-int min_port = IPPORT_HIFIRSTAUTO;
-int max_port = IPPORT_HILASTAUTO;
-
-#define STARTBUFSIZE 1024 /* Must be at least 3 */
-
-/*
- * Variables used to support PORT mode connections.
- *
- * This gets a bit complicated.
- *
- * If PORT mode is on then client_listen_sa describes the socket that
- * the real client is listening on and server_listen_sa describes the
- * socket that we are listening on (waiting for the real server to connect
- * with us).
- *
- * If PASV mode is on then client_listen_sa describes the socket that
- * we are listening on (waiting for the real client to connect to us on)
- * and server_listen_sa describes the socket that the real server is
- * listening on.
- *
- * If the socket we are listening on gets a connection then we connect
- * to the other side's socket. Similarly, if a connected socket is
- * shutdown then we shutdown the other side's socket.
- */
-
-double xfer_start_time;
-
-struct sockaddr_in real_server_sa;
-struct sockaddr_in client_listen_sa;
-struct sockaddr_in server_listen_sa;
-
-int client_listen_socket = -1; /* Only used in PASV mode */
-int client_data_socket = -1; /* Connected socket to real client */
-int server_listen_socket = -1; /* Only used in PORT mode */
-int server_data_socket = -1; /* Connected socket to real server */
-int client_data_bytes, server_data_bytes;
-
-int AnonFtpOnly;
-int Verbose;
-int NatMode;
-
-char ClientName[NI_MAXHOST];
-char RealServerName[NI_MAXHOST];
-char OurName[NI_MAXHOST];
-
-char *User = "proxy";
-char *Group;
-
-extern int Debug_Level;
-extern int Use_Rdns;
-extern in_addr_t Bind_Addr;
-extern char *__progname;
-
-typedef enum {
- UNKNOWN_MODE,
- PORT_MODE,
- PASV_MODE,
- EPRT_MODE,
- EPSV_MODE
-} connection_mode_t;
-
-connection_mode_t connection_mode;
-
-extern void debuglog(int debug_level, const char *fmt, ...);
-double wallclock_time(void);
-void show_xfer_stats(void);
-void log_control_command (char *cmd, int client);
-int new_dataconn(int server);
-void do_client_cmd(struct csiob *client, struct csiob *server);
-void do_server_reply(struct csiob *server, struct csiob *client);
-static void
-usage(void)
-{
- syslog(LOG_NOTICE,
- "usage: %s [-AnrVw] [-a address] [-D debuglevel [-g group]"
- " [-M maxport] [-m minport] [-t timeout] [-u user]", __progname);
- exit(EX_USAGE);
-}
-
-static void
-close_client_data(void)
-{
- if (client_data_socket >= 0) {
- shutdown(client_data_socket, 2);
- close(client_data_socket);
- client_data_socket = -1;
- }
-}
-
-static void
-close_server_data(void)
-{
- if (server_data_socket >= 0) {
- shutdown(server_data_socket, 2);
- close(server_data_socket);
- server_data_socket = -1;
- }
-}
-
-static void
-drop_privs(void)
-{
- struct passwd *pw;
- struct group *gr;
- uid_t uid = 0;
- gid_t gid = 0;
-
- if (User != NULL) {
- pw = getpwnam(User);
- if (pw == NULL) {
- syslog(LOG_ERR, "cannot find user %s", User);
- exit(EX_USAGE);
- }
- uid = pw->pw_uid;
- gid = pw->pw_gid;
- }
-
- if (Group != NULL) {
- gr = getgrnam(Group);
- if (gr == NULL) {
- syslog(LOG_ERR, "cannot find group %s", Group);
- exit(EX_USAGE);
- }
- gid = gr->gr_gid;
- }
-
- if (gid != 0 && (setegid(gid) == -1 || setgid(gid) == -1)) {
- syslog(LOG_ERR, "cannot drop group privs (%m)");
- exit(EX_CONFIG);
- }
-
- if (uid != 0 && (seteuid(uid) == -1 || setuid(uid) == -1)) {
- syslog(LOG_ERR, "cannot drop root privs (%m)");
- exit(EX_CONFIG);
- }
-}
-
-#ifdef LIBWRAP
-/*
- * Check a connection against the tcpwrapper, log if we're going to
- * reject it, returns: 0 -> reject, 1 -> accept. We add in hostnames
- * if we are set to do reverse DNS, otherwise no.
- */
-static int
-check_host(struct sockaddr_in *client_sin, struct sockaddr_in *server_sin)
-{
- char cname[NI_MAXHOST];
- char sname[NI_MAXHOST];
- struct request_info request;
- int i;
-
- request_init(&request, RQ_DAEMON, __progname, RQ_CLIENT_SIN,
- client_sin, RQ_SERVER_SIN, server_sin, RQ_CLIENT_ADDR,
- inet_ntoa(client_sin->sin_addr), 0);
-
- if (Use_Rdns) {
- /*
- * We already looked these up, but we have to do it again
- * for tcp wrapper, to ensure that we get the DNS name, since
- * the tcp wrapper cares about these things, and we don't
- * want to pass in a printed address as a name.
- */
- i = getnameinfo((struct sockaddr *) &client_sin->sin_addr,
- sizeof(&client_sin->sin_addr), cname, sizeof(cname),
- NULL, 0, NI_NAMEREQD);
-
- if (i != 0 && i != EAI_NONAME && i != EAI_AGAIN)
- strlcpy(cname, STRING_UNKNOWN, sizeof(cname));
-
- i = getnameinfo((struct sockaddr *)&server_sin->sin_addr,
- sizeof(&server_sin->sin_addr), sname, sizeof(sname),
- NULL, 0, NI_NAMEREQD);
-
- if (i != 0 && i != EAI_NONAME && i != EAI_AGAIN)
- strlcpy(sname, STRING_UNKNOWN, sizeof(sname));
- } else {
- /*
- * ensure the TCP wrapper doesn't start doing
- * reverse DNS lookups if we aren't supposed to.
- */
- strlcpy(cname, STRING_UNKNOWN, sizeof(cname));
- strlcpy(sname, STRING_UNKNOWN, sizeof(sname));
- }
-
- request_set(&request, RQ_SERVER_ADDR, inet_ntoa(server_sin->sin_addr),
- 0);
- request_set(&request, RQ_CLIENT_NAME, cname, RQ_SERVER_NAME, sname, 0);
-
- if (!hosts_access(&request)) {
- syslog(LOG_NOTICE, "tcpwrappers rejected: %s -> %s",
- ClientName, RealServerName);
- return(0);
- }
- return(1);
-}
-#endif /* LIBWRAP */
-
-double
-wallclock_time(void)
-{
- struct timeval tv;
-
- gettimeofday(&tv, NULL);
- return(tv.tv_sec + tv.tv_usec / 1e6);
-}
-
-/*
- * Show the stats for this data transfer
- */
-void
-show_xfer_stats(void)
-{
- char tbuf[1000];
- double delta;
- size_t len;
- int i;
-
- if (!Verbose)
- return;
-
- delta = wallclock_time() - xfer_start_time;
-
- if (delta < 0.001)
- delta = 0.001;
-
- if (client_data_bytes == 0 && server_data_bytes == 0) {
- syslog(LOG_INFO,
- "data transfer complete (no bytes transferred)");
- return;
- }
-
- len = sizeof(tbuf);
-
- if (delta >= 60) {
- int idelta;
-
- idelta = delta + 0.5;
- if (idelta >= 60*60) {
- i = snprintf(tbuf, len,
- "data transfer complete (%dh %dm %ds",
- idelta / (60*60), (idelta % (60*60)) / 60,
- idelta % 60);
- if (i >= len)
- goto logit;
- len -= i;
- } else {
- i = snprintf(tbuf, len,
- "data transfer complete (%dm %ds", idelta / 60,
- idelta % 60);
- if (i >= len)
- goto logit;
- len -= i;
- }
- } else {
- i = snprintf(tbuf, len, "data transfer complete (%.1fs",
- delta);
- if (i >= len)
- goto logit;
- len -= i;
- }
-
- if (client_data_bytes > 0) {
- i = snprintf(&tbuf[strlen(tbuf)], len,
- ", %d bytes to server) (%.1fKB/s", client_data_bytes,
- (client_data_bytes / delta) / (double)1024);
- if (i >= len)
- goto logit;
- len -= i;
- }
- if (server_data_bytes > 0) {
- i = snprintf(&tbuf[strlen(tbuf)], len,
- ", %d bytes to client) (%.1fKB/s", server_data_bytes,
- (server_data_bytes / delta) / (double)1024);
- if (i >= len)
- goto logit;
- len -= i;
- }
- strlcat(tbuf, ")", sizeof(tbuf));
- logit:
- syslog(LOG_INFO, "%s", tbuf);
-}
-
-void
-log_control_command (char *cmd, int client)
-{
- /* log an ftp control command or reply */
- char *logstring;
- int level = LOG_DEBUG;
-
- if (!Verbose)
- return;
-
- /* don't log passwords */
- if (strncasecmp(cmd, "pass ", 5) == 0)
- logstring = "PASS XXXX";
- else
- logstring = cmd;
- if (client) {
- /* log interesting stuff at LOG_INFO, rest at LOG_DEBUG */
- if ((strncasecmp(cmd, "user ", 5) == 0) ||
- (strncasecmp(cmd, "retr ", 5) == 0) ||
- (strncasecmp(cmd, "cwd ", 4) == 0) ||
- (strncasecmp(cmd, "stor " ,5) == 0))
- level = LOG_INFO;
- }
- syslog(level, "%s %s", client ? "client:" : " server:",
- logstring);
-}
-
-/*
- * set ourselves up for a new data connection. Direction is toward client if
- * "server" is 0, towards server otherwise.
- */
-int
-new_dataconn(int server)
-{
- /*
- * Close existing data conn.
- */
-
- if (client_listen_socket != -1) {
- close(client_listen_socket);
- client_listen_socket = -1;
- }
- close_client_data();
-
- if (server_listen_socket != -1) {
- close(server_listen_socket);
- server_listen_socket = -1;
- }
- close_server_data();
-
- if (server) {
- bzero(&server_listen_sa, sizeof(server_listen_sa));
- server_listen_socket = get_backchannel_socket(SOCK_STREAM,
- min_port, max_port, -1, 1, &server_listen_sa);
-
- if (server_listen_socket == -1) {
- syslog(LOG_INFO, "server socket bind() failed (%m)");
- exit(EX_OSERR);
- }
- if (listen(server_listen_socket, 5) != 0) {
- syslog(LOG_INFO, "server socket listen() failed (%m)");
- exit(EX_OSERR);
- }
- } else {
- bzero(&client_listen_sa, sizeof(client_listen_sa));
- client_listen_socket = get_backchannel_socket(SOCK_STREAM,
- min_port, max_port, -1, 1, &client_listen_sa);
-
- if (client_listen_socket == -1) {
- syslog(LOG_NOTICE,
- "cannot get client listen socket (%m)");
- exit(EX_OSERR);
- }
- if (listen(client_listen_socket, 5) != 0) {
- syslog(LOG_NOTICE,
- "cannot listen on client socket (%m)");
- exit(EX_OSERR);
- }
- }
- return(0);
-}
-
-static void
-connect_pasv_backchannel(void)
-{
- struct sockaddr_in listen_sa;
- socklen_t salen;
-
- /*
- * We are about to accept a connection from the client.
- * This is a PASV data connection.
- */
- debuglog(2, "client listen socket ready");
-
- close_server_data();
- close_client_data();
-
- salen = sizeof(listen_sa);
- client_data_socket = accept(client_listen_socket,
- (struct sockaddr *)&listen_sa, &salen);
-
- if (client_data_socket < 0) {
- syslog(LOG_NOTICE, "accept() failed (%m)");
- exit(EX_OSERR);
- }
- close(client_listen_socket);
- client_listen_socket = -1;
- memset(&listen_sa, 0, sizeof(listen_sa));
-
- server_data_socket = get_backchannel_socket(SOCK_STREAM, min_port,
- max_port, -1, 1, &listen_sa);
- if (server_data_socket < 0) {
- syslog(LOG_NOTICE, "get_backchannel_socket() failed (%m)");
- exit(EX_OSERR);
- }
- if (connect(server_data_socket, (struct sockaddr *) &server_listen_sa,
- sizeof(server_listen_sa)) != 0) {
- syslog(LOG_NOTICE, "connect() failed (%m)");
- exit(EX_NOHOST);
- }
- client_data_bytes = 0;
- server_data_bytes = 0;
- xfer_start_time = wallclock_time();
-}
-
-static void
-connect_port_backchannel(void)
-{
- struct sockaddr_in listen_sa;
- socklen_t salen;
-
- /*
- * We are about to accept a connection from the server.
- * This is a PORT or EPRT data connection.
- */
- debuglog(2, "server listen socket ready");
-
- close_server_data();
- close_client_data();
-
- salen = sizeof(listen_sa);
- server_data_socket = accept(server_listen_socket,
- (struct sockaddr *)&listen_sa, &salen);
- if (server_data_socket < 0) {
- syslog(LOG_NOTICE, "accept() failed (%m)");
- exit(EX_OSERR);
- }
- close(server_listen_socket);
- server_listen_socket = -1;
-
- if (getuid() != 0) {
- /*
- * We're not running as root, so we get a backchannel
- * socket bound in our designated range, instead of
- * getting one bound to port 20 - This is deliberately
- * not RFC compliant.
- */
- bzero(&listen_sa.sin_addr, sizeof(struct in_addr));
- client_data_socket = get_backchannel_socket(SOCK_STREAM,
- min_port, max_port, -1, 1, &listen_sa);
- if (client_data_socket < 0) {
- syslog(LOG_NOTICE, "get_backchannel_socket() failed (%m)");
- exit(EX_OSERR);
- }
-
- } else {
-
- /*
- * We're root, get our backchannel socket bound to port
- * 20 here, so we're fully RFC compliant.
- */
- client_data_socket = socket(AF_INET, SOCK_STREAM, 0);
-
- salen = 1;
- listen_sa.sin_family = AF_INET;
- bzero(&listen_sa.sin_addr, sizeof(struct in_addr));
- listen_sa.sin_port = htons(20);
-
- if (setsockopt(client_data_socket, SOL_SOCKET, SO_REUSEADDR,
- &salen, sizeof(salen)) == -1) {
- syslog(LOG_NOTICE, "setsockopt() failed (%m)");
- exit(EX_OSERR);
- }
-
- if (bind(client_data_socket, (struct sockaddr *)&listen_sa,
- sizeof(listen_sa)) == - 1) {
- syslog(LOG_NOTICE, "data channel bind() failed (%m)");
- exit(EX_OSERR);
- }
- }
-
- if (connect(client_data_socket, (struct sockaddr *) &client_listen_sa,
- sizeof(client_listen_sa)) != 0) {
- syslog(LOG_INFO, "cannot connect data channel (%m)");
- exit(EX_NOHOST);
- }
-
- client_data_bytes = 0;
- server_data_bytes = 0;
- xfer_start_time = wallclock_time();
-}
-
-void
-do_client_cmd(struct csiob *client, struct csiob *server)
-{
- int i, j, rv;
- char tbuf[100];
- char *sendbuf = NULL;
-
- log_control_command((char *)client->line_buffer, 1);
-
- /* client->line_buffer is an ftp control command.
- * There is no reason for these to be very long.
- * In the interest of limiting buffer overrun attempts,
- * we catch them here.
- */
- if (strlen((char *)client->line_buffer) > 512) {
- syslog(LOG_NOTICE, "excessively long control command");
- exit(EX_DATAERR);
- }
-
- /*
- * Check the client user provided if needed
- */
- if (AnonFtpOnly && strncasecmp((char *)client->line_buffer, "user ",
- strlen("user ")) == 0) {
- char *cp;
-
- cp = (char *) client->line_buffer + strlen("user ");
- if ((strcasecmp(cp, "ftp\r\n") != 0) &&
- (strcasecmp(cp, "anonymous\r\n") != 0)) {
- /*
- * this isn't anonymous - give the client an
- * error before they send a password
- */
- snprintf(tbuf, sizeof(tbuf),
- "500 Only anonymous FTP is allowed\r\n");
- j = 0;
- i = strlen(tbuf);
- do {
- rv = send(client->fd, tbuf + j, i - j, 0);
- if (rv == -1 && errno != EAGAIN &&
- errno != EINTR)
- break;
- else if (rv != -1)
- j += rv;
- } while (j >= 0 && j < i);
- sendbuf = NULL;
- } else
- sendbuf = (char *)client->line_buffer;
- } else if ((strncasecmp((char *)client->line_buffer, "eprt ",
- strlen("eprt ")) == 0)) {
-
- /* Watch out for EPRT commands */
- char *line = NULL, *q, *p, *result[3], delim;
- struct addrinfo hints, *res = NULL;
- unsigned long proto;
-
- j = 0;
- line = strdup((char *)client->line_buffer+strlen("eprt "));
- if (line == NULL) {
- syslog(LOG_ERR, "insufficient memory");
- exit(EX_UNAVAILABLE);
- }
- p = line;
- delim = p[0];
- p++;
-
- memset(result,0, sizeof(result));
- for (i = 0; i < 3; i++) {
- q = strchr(p, delim);
- if (!q || *q != delim)
- goto parsefail;
- *q++ = '\0';
- result[i] = p;
- p = q;
- }
-
- proto = strtoul(result[0], &p, 10);
- if (!*result[0] || *p)
- goto protounsupp;
-
- memset(&hints, 0, sizeof(hints));
- if (proto != 1) /* 1 == AF_INET - all we support for now */
- goto protounsupp;
- hints.ai_family = AF_INET;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_flags = AI_NUMERICHOST; /*no DNS*/
- if (getaddrinfo(result[1], result[2], &hints, &res))
- goto parsefail;
- if (res->ai_next)
- goto parsefail;
- if (sizeof(client_listen_sa) < res->ai_addrlen)
- goto parsefail;
- memcpy(&client_listen_sa, res->ai_addr, res->ai_addrlen);
-
- debuglog(1, "client wants us to use %s:%u",
- inet_ntoa(client_listen_sa.sin_addr),
- htons(client_listen_sa.sin_port));
-
- /*
- * Configure our own listen socket and tell the server about it
- */
- new_dataconn(1);
- connection_mode = EPRT_MODE;
-
- debuglog(1, "we want server to use %s:%u",
- inet_ntoa(server->sa.sin_addr),
- ntohs(server_listen_sa.sin_port));
-
- snprintf(tbuf, sizeof(tbuf), "EPRT |%d|%s|%u|\r\n", 1,
- inet_ntoa(server->sa.sin_addr),
- ntohs(server_listen_sa.sin_port));
- debuglog(1, "to server (modified): %s", tbuf);
- sendbuf = tbuf;
- goto out;
-parsefail:
- snprintf(tbuf, sizeof(tbuf),
- "500 Invalid argument; rejected\r\n");
- sendbuf = NULL;
- goto out;
-protounsupp:
- /* we only support AF_INET for now */
- if (proto == 2)
- snprintf(tbuf, sizeof(tbuf),
- "522 Protocol not supported, use (1)\r\n");
- else
- snprintf(tbuf, sizeof(tbuf),
- "501 Protocol not supported\r\n");
- sendbuf = NULL;
-out:
- if (line)
- free(line);
- if (res)
- freeaddrinfo(res);
- if (sendbuf == NULL) {
- debuglog(1, "to client (modified): %s", tbuf);
- i = strlen(tbuf);
- do {
- rv = send(client->fd, tbuf + j, i - j, 0);
- if (rv == -1 && errno != EAGAIN &&
- errno != EINTR)
- break;
- else if (rv != -1)
- j += rv;
- } while (j >= 0 && j < i);
- }
- } else if (!NatMode && (strncasecmp((char *)client->line_buffer,
- "epsv", strlen("epsv")) == 0)) {
-
- /*
- * If we aren't in NAT mode, deal with EPSV.
- * EPSV is a problem - Unlike PASV, the reply from the
- * server contains *only* a port, we can't modify the reply
- * to the client and get the client to connect to us without
- * resorting to using a dynamic rdr rule we have to add in
- * for the reply to this connection, and take away afterwards.
- * so this will wait until we have the right solution for rule
- * additions/deletions in pf.
- *
- * in the meantime we just tell the client we don't do it,
- * and most clients should fall back to using PASV.
- */
-
- snprintf(tbuf, sizeof(tbuf),
- "500 EPSV command not understood\r\n");
- debuglog(1, "to client (modified): %s", tbuf);
- j = 0;
- i = strlen(tbuf);
- do {
- rv = send(client->fd, tbuf + j, i - j, 0);
- if (rv == -1 && errno != EAGAIN && errno != EINTR)
- break;
- else if (rv != -1)
- j += rv;
- } while (j >= 0 && j < i);
- sendbuf = NULL;
- } else if (strncasecmp((char *)client->line_buffer, "port ",
- strlen("port ")) == 0) {
- unsigned int values[6];
- char *tailptr;
-
- debuglog(1, "Got a PORT command");
-
- tailptr = (char *)&client->line_buffer[strlen("port ")];
- values[0] = 0;
-
- i = sscanf(tailptr, "%u,%u,%u,%u,%u,%u", &values[0],
- &values[1], &values[2], &values[3], &values[4],
- &values[5]);
- if (i != 6) {
- syslog(LOG_INFO, "malformed PORT command (%s)",
- client->line_buffer);
- exit(EX_DATAERR);
- }
-
- for (i = 0; i<6; i++) {
- if (values[i] > 255) {
- syslog(LOG_INFO,
- "malformed PORT command (%s)",
- client->line_buffer);
- exit(EX_DATAERR);
- }
- }
-
- client_listen_sa.sin_family = AF_INET;
- client_listen_sa.sin_addr.s_addr = htonl((values[0] << 24) |
- (values[1] << 16) | (values[2] << 8) |
- (values[3] << 0));
-
- client_listen_sa.sin_port = htons((values[4] << 8) |
- values[5]);
- debuglog(1, "client wants us to use %u.%u.%u.%u:%u",
- values[0], values[1], values[2], values[3],
- (values[4] << 8) | values[5]);
-
- /*
- * Configure our own listen socket and tell the server about it
- */
- new_dataconn(1);
- connection_mode = PORT_MODE;
-
- debuglog(1, "we want server to use %s:%u",
- inet_ntoa(server->sa.sin_addr),
- ntohs(server_listen_sa.sin_port));
-
- snprintf(tbuf, sizeof(tbuf), "PORT %u,%u,%u,%u,%u,%u\r\n",
- ((u_char *)&server->sa.sin_addr.s_addr)[0],
- ((u_char *)&server->sa.sin_addr.s_addr)[1],
- ((u_char *)&server->sa.sin_addr.s_addr)[2],
- ((u_char *)&server->sa.sin_addr.s_addr)[3],
- ((u_char *)&server_listen_sa.sin_port)[0],
- ((u_char *)&server_listen_sa.sin_port)[1]);
-
- debuglog(1, "to server (modified): %s", tbuf);
-
- sendbuf = tbuf;
- } else
- sendbuf = (char *)client->line_buffer;
-
- /*
- *send our (possibly modified) control command in sendbuf
- * on it's way to the server
- */
- if (sendbuf != NULL) {
- j = 0;
- i = strlen(sendbuf);
- do {
- rv = send(server->fd, sendbuf + j, i - j, 0);
- if (rv == -1 && errno != EAGAIN && errno != EINTR)
- break;
- else if (rv != -1)
- j += rv;
- } while (j >= 0 && j < i);
- }
-}
-
-void
-do_server_reply(struct csiob *server, struct csiob *client)
-{
- int code, i, j, rv;
- struct in_addr *iap;
- static int continuing = 0;
- char tbuf[100], *sendbuf, *p;
-
- log_control_command((char *)server->line_buffer, 0);
-
- if (strlen((char *)server->line_buffer) > 512) {
- /*
- * someone's playing games. Have a cow in the syslogs and
- * exit - we don't pass this on for fear of hurting
- * our other end, which might be poorly implemented.
- */
- syslog(LOG_NOTICE, "long FTP control reply");
- exit(EX_DATAERR);
- }
-
- /*
- * Watch out for "227 Entering Passive Mode ..." replies
- */
- code = strtol((char *)server->line_buffer, &p, 10);
- if (isspace(server->line_buffer[0]))
- code = 0;
- if (!*(server->line_buffer) || (*p != ' ' && *p != '-')) {
- if (continuing)
- goto sendit;
- syslog(LOG_INFO, "malformed control reply");
- exit(EX_DATAERR);
- }
- if (code <= 0 || code > 999) {
- if (continuing)
- goto sendit;
- syslog(LOG_INFO, "invalid server reply code %d", code);
- exit(EX_DATAERR);
- }
- if (*p == '-')
- continuing = 1;
- else
- continuing = 0;
- if (code == 227 && !NatMode) {
- unsigned int values[6];
- char *tailptr;
-
- debuglog(1, "Got a PASV reply");
- debuglog(1, "{%s}", (char *)server->line_buffer);
-
- tailptr = (char *)strchr((char *)server->line_buffer, '(');
- if (tailptr == NULL) {
- tailptr = strrchr((char *)server->line_buffer, ' ');
- if (tailptr == NULL) {
- syslog(LOG_NOTICE, "malformed 227 reply");
- exit(EX_DATAERR);
- }
- }
- tailptr++; /* skip past space or ( */
-
- values[0] = 0;
-
- i = sscanf(tailptr, "%u,%u,%u,%u,%u,%u", &values[0],
- &values[1], &values[2], &values[3], &values[4],
- &values[5]);
- if (i != 6) {
- syslog(LOG_INFO, "malformed PASV reply (%s)",
- client->line_buffer);
- exit(EX_DATAERR);
- }
- for (i = 0; i<6; i++)
- if (values[i] > 255) {
- syslog(LOG_INFO, "malformed PASV reply(%s)",
- client->line_buffer);
- exit(EX_DATAERR);
- }
-
- server_listen_sa.sin_family = AF_INET;
- server_listen_sa.sin_addr.s_addr = htonl((values[0] << 24) |
- (values[1] << 16) | (values[2] << 8) | (values[3] << 0));
- server_listen_sa.sin_port = htons((values[4] << 8) |
- values[5]);
-
- debuglog(1, "server wants us to use %s:%u",
- inet_ntoa(server_listen_sa.sin_addr), (values[4] << 8) |
- values[5]);
-
- new_dataconn(0);
- connection_mode = PASV_MODE;
- iap = &(server->sa.sin_addr);
-
- debuglog(1, "we want client to use %s:%u", inet_ntoa(*iap),
- htons(client_listen_sa.sin_port));
-
- snprintf(tbuf, sizeof(tbuf),
- "227 Entering Passive Mode (%u,%u,%u,%u,%u,%u)\r\n",
- ((u_char *)iap)[0], ((u_char *)iap)[1],
- ((u_char *)iap)[2], ((u_char *)iap)[3],
- ((u_char *)&client_listen_sa.sin_port)[0],
- ((u_char *)&client_listen_sa.sin_port)[1]);
- debuglog(1, "to client (modified): %s", tbuf);
- sendbuf = tbuf;
- } else {
- sendit:
- sendbuf = (char *)server->line_buffer;
- }
-
- /*
- * send our (possibly modified) control command in sendbuf
- * on it's way to the client
- */
- j = 0;
- i = strlen(sendbuf);
- do {
- rv = send(client->fd, sendbuf + j, i - j, 0);
- if (rv == -1 && errno != EAGAIN && errno != EINTR)
- break;
- else if (rv != -1)
- j += rv;
- } while (j >= 0 && j < i);
-
-}
-
-int
-main(int argc, char *argv[])
-{
- struct csiob client_iob, server_iob;
- struct sigaction new_sa, old_sa;
- int sval, ch, flags, i;
- socklen_t salen;
- int one = 1;
- long timeout_seconds = 0;
- struct timeval tv;
-#ifdef LIBWRAP
- int use_tcpwrapper = 0;
-#endif /* LIBWRAP */
-
- while ((ch = getopt(argc, argv, "a:D:g:m:M:t:u:AnVwr")) != -1) {
- char *p;
- switch (ch) {
- case 'a':
- if (!*optarg)
- usage();
- if ((Bind_Addr = inet_addr(optarg)) == INADDR_NONE) {
- syslog(LOG_NOTICE,
- "%s: invalid address", optarg);
- usage();
- }
- break;
- case 'A':
- AnonFtpOnly = 1; /* restrict to anon usernames only */
- break;
- case 'D':
- Debug_Level = strtol(optarg, &p, 10);
- if (!*optarg || *p)
- usage();
- break;
- case 'g':
- Group = optarg;
- break;
- case 'm':
- min_port = strtol(optarg, &p, 10);
- if (!*optarg || *p)
- usage();
- if (min_port < 0 || min_port > USHRT_MAX)
- usage();
- break;
- case 'M':
- max_port = strtol(optarg, &p, 10);
- if (!*optarg || *p)
- usage();
- if (max_port < 0 || max_port > USHRT_MAX)
- usage();
- break;
- case 'n':
- NatMode = 1; /* pass all passives, we're using NAT */
- break;
- case 'r':
- Use_Rdns = 1; /* look up hostnames */
- break;
- case 't':
- timeout_seconds = strtol(optarg, &p, 10);
- if (!*optarg || *p)
- usage();
- break;
- case 'u':
- User = optarg;
- break;
- case 'V':
- Verbose = 1;
- break;
-#ifdef LIBWRAP
- case 'w':
- use_tcpwrapper = 1; /* do the libwrap thing */
- break;
-#endif /* LIBWRAP */
- default:
- usage();
- /* NOTREACHED */
- }
- }
- argc -= optind;
- argv += optind;
-
- if (max_port < min_port)
- usage();
-
- openlog(__progname, LOG_NDELAY|LOG_PID, LOG_DAEMON);
-
- setlinebuf(stdout);
- setlinebuf(stderr);
-
- memset(&client_iob, 0, sizeof(client_iob));
- memset(&server_iob, 0, sizeof(server_iob));
-
- if (get_proxy_env(0, &real_server_sa, &client_iob.sa) == -1)
- exit(EX_PROTOCOL);
-
- /*
- * We may now drop root privs, as we have done our ioctl for
- * pf. If we do drop root, we can't make backchannel connections
- * for PORT and EPRT come from port 20, which is not strictly
- * RFC compliant. This shouldn't cause problems for all but
- * the stupidest ftp clients and the stupidest packet filters.
- */
- drop_privs();
-
- /*
- * We check_host after get_proxy_env so that checks are done
- * against the original destination endpoint, not the endpoint
- * of our side of the rdr. This allows the use of tcpwrapper
- * rules to restrict destinations as well as sources of connections
- * for ftp.
- */
- if (Use_Rdns)
- flags = 0;
- else
- flags = NI_NUMERICHOST | NI_NUMERICSERV;
-
- i = getnameinfo((struct sockaddr *)&client_iob.sa,
- sizeof(client_iob.sa), ClientName, sizeof(ClientName), NULL, 0,
- flags);
-
- if (i != 0 && i != EAI_NONAME && i != EAI_AGAIN) {
- debuglog(2, "name resolution failure (client)");
- exit(EX_OSERR);
- }
-
- i = getnameinfo((struct sockaddr *)&real_server_sa,
- sizeof(real_server_sa), RealServerName, sizeof(RealServerName),
- NULL, 0, flags);
-
- if (i != 0 && i != EAI_NONAME && i != EAI_AGAIN) {
- debuglog(2, "name resolution failure (server)");
- exit(EX_OSERR);
- }
-
-#ifdef LIBWRAP
- if (use_tcpwrapper && !check_host(&client_iob.sa, &real_server_sa))
- exit(EX_NOPERM);
-#endif
-
- client_iob.fd = 0;
-
- syslog(LOG_INFO, "accepted connection from %s:%u to %s:%u", ClientName,
- ntohs(client_iob.sa.sin_port), RealServerName,
- ntohs(real_server_sa.sin_port));
-
- server_iob.fd = get_backchannel_socket(SOCK_STREAM, min_port, max_port,
- -1, 1, &server_iob.sa);
-
- if (connect(server_iob.fd, (struct sockaddr *)&real_server_sa,
- sizeof(real_server_sa)) != 0) {
- syslog(LOG_INFO, "cannot connect to %s:%u (%m)", RealServerName,
- ntohs(real_server_sa.sin_port));
- exit(EX_NOHOST);
- }
-
- /*
- * Now that we are connected to the real server, get the name
- * of our end of the server socket so we know our IP address
- * from the real server's perspective.
- */
- salen = sizeof(server_iob.sa);
- getsockname(server_iob.fd, (struct sockaddr *)&server_iob.sa, &salen);
-
- i = getnameinfo((struct sockaddr *)&server_iob.sa,
- sizeof(server_iob.sa), OurName, sizeof(OurName), NULL, 0, flags);
-
- if (i != 0 && i != EAI_NONAME && i != EAI_AGAIN) {
- debuglog(2, "name resolution failure (local)");
- exit(EX_OSERR);
- }
-
- debuglog(1, "local socket is %s:%u", OurName,
- ntohs(server_iob.sa.sin_port));
-
- /* ignore SIGPIPE */
- bzero(&new_sa, sizeof(new_sa));
- new_sa.sa_handler = SIG_IGN;
- (void)sigemptyset(&new_sa.sa_mask);
- new_sa.sa_flags = SA_RESTART;
- if (sigaction(SIGPIPE, &new_sa, &old_sa) != 0) {
- syslog(LOG_ERR, "sigaction() failed (%m)");
- exit(EX_OSERR);
- }
-
- if (setsockopt(client_iob.fd, SOL_SOCKET, SO_OOBINLINE, (char *)&one,
- sizeof(one)) == -1) {
- syslog(LOG_NOTICE, "cannot set SO_OOBINLINE (%m)");
- exit(EX_OSERR);
- }
-
- client_iob.line_buffer_size = STARTBUFSIZE;
- client_iob.line_buffer = malloc(client_iob.line_buffer_size);
- client_iob.io_buffer_size = STARTBUFSIZE;
- client_iob.io_buffer = malloc(client_iob.io_buffer_size);
- client_iob.next_byte = 0;
- client_iob.io_buffer_len = 0;
- client_iob.alive = 1;
- client_iob.who = "client";
- client_iob.send_oob_flags = 0;
- client_iob.real_sa = client_iob.sa;
-
- server_iob.line_buffer_size = STARTBUFSIZE;
- server_iob.line_buffer = malloc(server_iob.line_buffer_size);
- server_iob.io_buffer_size = STARTBUFSIZE;
- server_iob.io_buffer = malloc(server_iob.io_buffer_size);
- server_iob.next_byte = 0;
- server_iob.io_buffer_len = 0;
- server_iob.alive = 1;
- server_iob.who = "server";
- server_iob.send_oob_flags = MSG_OOB;
- server_iob.real_sa = real_server_sa;
-
- if (client_iob.line_buffer == NULL || client_iob.io_buffer == NULL ||
- server_iob.line_buffer == NULL || server_iob.io_buffer == NULL) {
- syslog (LOG_NOTICE, "insufficient memory");
- exit(EX_UNAVAILABLE);
- }
-
- while (client_iob.alive || server_iob.alive) {
- int maxfd = 0;
- fd_set *fdsp;
-
- if (client_iob.fd > maxfd)
- maxfd = client_iob.fd;
- if (client_listen_socket > maxfd)
- maxfd = client_listen_socket;
- if (client_data_socket > maxfd)
- maxfd = client_data_socket;
- if (server_iob.fd > maxfd)
- maxfd = server_iob.fd;
- if (server_listen_socket > maxfd)
- maxfd = server_listen_socket;
- if (server_data_socket > maxfd)
- maxfd = server_data_socket;
-
- debuglog(3, "client is %s; server is %s",
- client_iob.alive ? "alive" : "dead",
- server_iob.alive ? "alive" : "dead");
-
- fdsp = (fd_set *)calloc(howmany(maxfd + 1, NFDBITS),
- sizeof(fd_mask));
- if (fdsp == NULL) {
- syslog(LOG_NOTICE, "insufficient memory");
- exit(EX_UNAVAILABLE);
- }
-
- if (client_iob.alive && telnet_getline(&client_iob,
- &server_iob)) {
- debuglog(3, "client line buffer is \"%s\"",
- (char *)client_iob.line_buffer);
- if (client_iob.line_buffer[0] != '\0')
- do_client_cmd(&client_iob, &server_iob);
- } else if (server_iob.alive && telnet_getline(&server_iob,
- &client_iob)) {
- debuglog(3, "server line buffer is \"%s\"",
- (char *)server_iob.line_buffer);
- if (server_iob.line_buffer[0] != '\0')
- do_server_reply(&server_iob, &client_iob);
- } else {
- if (client_iob.alive) {
- FD_SET(client_iob.fd, fdsp);
- if (client_listen_socket >= 0)
- FD_SET(client_listen_socket, fdsp);
- if (client_data_socket >= 0)
- FD_SET(client_data_socket, fdsp);
- }
- if (server_iob.alive) {
- FD_SET(server_iob.fd, fdsp);
- if (server_listen_socket >= 0)
- FD_SET(server_listen_socket, fdsp);
- if (server_data_socket >= 0)
- FD_SET(server_data_socket, fdsp);
- }
- tv.tv_sec = timeout_seconds;
- tv.tv_usec = 0;
-
- doselect:
- sval = select(maxfd + 1, fdsp, NULL, NULL,
- (tv.tv_sec == 0) ? NULL : &tv);
- if (sval == 0) {
- /*
- * This proxy has timed out. Expire it
- * quietly with an obituary in the syslogs
- * for any passing mourners.
- */
- syslog(LOG_INFO,
- "timeout: no data for %ld seconds",
- timeout_seconds);
- exit(EX_OK);
- }
- if (sval == -1) {
- if (errno == EINTR || errno == EAGAIN)
- goto doselect;
- syslog(LOG_NOTICE,
- "select() failed (%m)");
- exit(EX_OSERR);
- }
- if (client_data_socket >= 0 &&
- FD_ISSET(client_data_socket, fdsp)) {
- int rval;
-
- debuglog(3, "transfer: client to server");
- rval = xfer_data("client to server",
- client_data_socket,
- server_data_socket,
- client_iob.sa.sin_addr,
- real_server_sa.sin_addr);
- if (rval <= 0) {
- close_client_data();
- close_server_data();
- show_xfer_stats();
- } else
- client_data_bytes += rval;
- }
- if (server_data_socket >= 0 &&
- FD_ISSET(server_data_socket, fdsp)) {
- int rval;
-
- debuglog(3, "transfer: server to client");
- rval = xfer_data("server to client",
- server_data_socket,
- client_data_socket,
- real_server_sa.sin_addr,
- client_iob.sa.sin_addr);
- if (rval <= 0) {
- close_client_data();
- close_server_data();
- show_xfer_stats();
- } else
- server_data_bytes += rval;
- }
- if (server_listen_socket >= 0 &&
- FD_ISSET(server_listen_socket, fdsp)) {
- connect_port_backchannel();
- }
- if (client_listen_socket >= 0 &&
- FD_ISSET(client_listen_socket, fdsp)) {
- connect_pasv_backchannel();
- }
- if (client_iob.alive &&
- FD_ISSET(client_iob.fd, fdsp)) {
- client_iob.data_available = 1;
- }
- if (server_iob.alive &&
- FD_ISSET(server_iob.fd, fdsp)) {
- server_iob.data_available = 1;
- }
- }
- free(fdsp);
- if (client_iob.got_eof) {
- shutdown(server_iob.fd, 1);
- shutdown(client_iob.fd, 0);
- client_iob.got_eof = 0;
- client_iob.alive = 0;
- }
- if (server_iob.got_eof) {
- shutdown(client_iob.fd, 1);
- shutdown(server_iob.fd, 0);
- server_iob.got_eof = 0;
- server_iob.alive = 0;
- }
- }
-
- if (Verbose)
- syslog(LOG_INFO, "session ended");
-
- exit(EX_OK);
-}
diff --git a/contrib/pf/ftp-proxy/getline.c b/contrib/pf/ftp-proxy/getline.c
deleted file mode 100644
index 2be388340029..000000000000
--- a/contrib/pf/ftp-proxy/getline.c
+++ /dev/null
@@ -1,259 +0,0 @@
-/* $OpenBSD: getline.c,v 1.15 2003/06/28 01:04:57 deraadt Exp $ */
-
-/*
- * Copyright (c) 1985, 1988 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.
- * 3. 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.
- *
- * @(#)ftpcmd.y 5.24 (Berkeley) 2/25/91
- */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-
-#include <netinet/in.h>
-#include <arpa/telnet.h>
-
-#include <errno.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <sysexits.h>
-#include <syslog.h>
-#include <unistd.h>
-
-#include "util.h"
-
-int refill_buffer(struct csiob *iobp);
-
-/*
- * Refill the io buffer if we KNOW that data is available
- *
- * Returns 1 if any new data was obtained, 0 otherwise.
- */
-
-int
-refill_buffer(struct csiob *iobp)
-{
- int rqlen, rlen;
-
- if (!(iobp->data_available))
- return(0);
-
- if (iobp->got_eof)
- return(0);
-
- /*
- * The buffer has been entirely consumed if next_byte == io_buffer_len.
- * Otherwise, there is some still-to-be-used data in io_buffer.
- * Shuffle it to the start of the buffer.
- * Note that next_byte will never exceed io_buffer_len.
- * Also, note that we MUST use bcopy because the two regions could
- * overlap (memcpy isn't defined to work properly with overlapping
- * regions).
- */
- if (iobp->next_byte < iobp->io_buffer_len) {
- int dst_ix = 0;
- int src_ix = iobp->next_byte;
- int amount = iobp->io_buffer_len - iobp->next_byte;
-
- bcopy(&iobp->io_buffer[src_ix], &iobp->io_buffer[dst_ix],
- amount);
- iobp->io_buffer_len = amount;
- } else if (iobp->next_byte == iobp->io_buffer_len)
- iobp->io_buffer_len = 0;
- else {
- syslog(LOG_ERR, "next_byte(%d) > io_buffer_len(%d)",
- iobp->next_byte, iobp->io_buffer_len);
- exit(EX_OSERR);
- }
-
- iobp->next_byte = 0;
-
- /* don't do tiny reads, grow first if we need to */
- rqlen = iobp->io_buffer_size - iobp->io_buffer_len;
- if (rqlen <= 128) {
- char *tmp;
-
- iobp->io_buffer_size += 128;
- tmp = realloc(iobp->io_buffer, iobp->io_buffer_size);
- if (tmp == NULL) {
- syslog(LOG_INFO, "Insufficient memory");
- exit(EX_UNAVAILABLE);
- }
- iobp->io_buffer = tmp;
- rqlen = iobp->io_buffer_size - iobp->io_buffer_len;
- }
-
- /*
- * Always leave an unused byte at the end of the buffer
- * because the debug output uses that byte from time to time
- * to ensure that something that is being printed is \0 terminated.
- */
- rqlen -= 1;
-
- doread:
- rlen = read(iobp->fd, &iobp->io_buffer[iobp->io_buffer_len], rqlen);
- iobp->data_available = 0;
- switch (rlen) {
- case -1:
- if (errno == EAGAIN || errno == EINTR)
- goto doread;
- if (errno != ECONNRESET) {
- syslog(LOG_INFO, "read() failed on socket from %s (%m)",
- iobp->who);
- exit(EX_DATAERR);
- }
- /* fall through to EOF case */
- case 0:
- iobp->got_eof = 1;
- return(0);
- break;
- default:
- iobp->io_buffer_len += rlen;
- break;
- }
- return(1);
-}
-
-/*
- * telnet_getline - a hacked up version of fgets to ignore TELNET escape codes.
- *
- * This code is derived from the getline routine found in the UC Berkeley
- * ftpd code.
- *
- */
-
-int
-telnet_getline(struct csiob *iobp, struct csiob *telnet_passthrough)
-{
- unsigned char ch;
- int ix;
- char tbuf[100];
-
- iobp->line_buffer[0] = '\0';
-
- /*
- * If the buffer is empty then refill it right away.
- */
- if (iobp->next_byte == iobp->io_buffer_len)
- if (!refill_buffer(iobp))
- return(0);
-
- /*
- * Is there a telnet command in the buffer?
- */
- ch = iobp->io_buffer[iobp->next_byte];
- if (ch == IAC) {
- /*
- * Yes - buffer must have at least three bytes in it
- */
- if (iobp->io_buffer_len - iobp->next_byte < 3) {
- if (!refill_buffer(iobp))
- return(0);
- if (iobp->io_buffer_len - iobp->next_byte < 3)
- return(0);
- }
-
- iobp->next_byte++;
- ch = iobp->io_buffer[iobp->next_byte++];
-
- switch (ch) {
- case WILL:
- case WONT:
- case DO:
- case DONT:
- tbuf[0] = IAC;
- tbuf[1] = ch;
- tbuf[2] = iobp->io_buffer[iobp->next_byte++];
- (void)send(telnet_passthrough->fd, tbuf, 3,
- telnet_passthrough->send_oob_flags);
- break;
- case IAC:
- break;
- default:
- break;
- }
- return(1);
- } else {
- int clen;
-
- /*
- * Is there a newline in the buffer?
- */
- for (ix = iobp->next_byte; ix < iobp->io_buffer_len;
- ix += 1) {
- if (iobp->io_buffer[ix] == '\n')
- break;
- if (iobp->io_buffer[ix] == '\0') {
- syslog(LOG_INFO,
- "got NUL byte from %s - bye!",
- iobp->who);
- exit(EX_DATAERR);
- }
- }
-
- if (ix == iobp->io_buffer_len) {
- if (!refill_buffer(iobp))
- return(0);
- /*
- * Empty line returned
- * will try again soon!
- */
- return(1);
- }
-
- /*
- * Expand the line buffer if it isn't big enough. We
- * use a fudge factor of 5 rather than trying to
- * figure out exactly how to account for the '\0 \r\n' and
- * such. The correct fudge factor is 0, 1 or 2 but
- * anything higher also works. We also grow it by a
- * bunch to avoid having to do this often. Yes this is
- * nasty.
- */
- if (ix - iobp->next_byte > iobp->line_buffer_size - 5) {
- char *tmp;
-
- iobp->line_buffer_size = 256 + ix - iobp->next_byte;
- tmp = realloc(iobp->line_buffer,
- iobp->line_buffer_size);
- if (tmp == NULL) {
- syslog(LOG_INFO, "Insufficient memory");
- exit(EX_UNAVAILABLE);
- }
- iobp->line_buffer = tmp;
- }
-
- /* +1 is for the newline */
- clen = (ix+1) - iobp->next_byte;
- memcpy(iobp->line_buffer, &iobp->io_buffer[iobp->next_byte],
- clen);
- iobp->next_byte += clen;
- iobp->line_buffer[clen] = '\0';
- return(1);
- }
-}
diff --git a/contrib/pf/ftp-proxy/util.c b/contrib/pf/ftp-proxy/util.c
deleted file mode 100644
index 17a88cae6431..000000000000
--- a/contrib/pf/ftp-proxy/util.c
+++ /dev/null
@@ -1,301 +0,0 @@
-/* $OpenBSD: util.c,v 1.18 2004/01/22 16:10:30 beck Exp $ */
-
-/*
- * Copyright (c) 1996-2001
- * Obtuse Systems Corporation. 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.
- * 3. Neither the name of the Obtuse Systems 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 OBTUSE SYSTEMS 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 OBTUSE
- * SYSTEMS CORPORATION 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 <sys/types.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <sys/file.h>
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <net/if.h>
-#include <net/pfvar.h>
-
-#include <arpa/inet.h>
-
-#include <ctype.h>
-#include <errno.h>
-#include <netdb.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <sysexits.h>
-#include <syslog.h>
-#include <unistd.h>
-
-#include "util.h"
-
-int Debug_Level;
-int Use_Rdns;
-in_addr_t Bind_Addr = INADDR_NONE;
-
-void debuglog(int debug_level, const char *fmt, ...);
-
-void
-debuglog(int debug_level, const char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
-
- if (Debug_Level >= debug_level)
- vsyslog(LOG_DEBUG, fmt, ap);
- va_end(ap);
-}
-
-int
-get_proxy_env(int connected_fd, struct sockaddr_in *real_server_sa_ptr,
- struct sockaddr_in *client_sa_ptr)
-{
- struct pfioc_natlook natlook;
- socklen_t slen;
- int fd;
-
- slen = sizeof(*real_server_sa_ptr);
- if (getsockname(connected_fd, (struct sockaddr *)real_server_sa_ptr,
- &slen) != 0) {
- syslog(LOG_ERR, "getsockname() failed (%m)");
- return(-1);
- }
- slen = sizeof(*client_sa_ptr);
- if (getpeername(connected_fd, (struct sockaddr *)client_sa_ptr,
- &slen) != 0) {
- syslog(LOG_ERR, "getpeername() failed (%m)");
- return(-1);
- }
-
- /*
- * Build up the pf natlook structure.
- * Just for IPv4 right now
- */
- memset((void *)&natlook, 0, sizeof(natlook));
- natlook.af = AF_INET;
- natlook.saddr.addr32[0] = client_sa_ptr->sin_addr.s_addr;
- natlook.daddr.addr32[0] = real_server_sa_ptr->sin_addr.s_addr;
- natlook.proto = IPPROTO_TCP;
- natlook.sport = client_sa_ptr->sin_port;
- natlook.dport = real_server_sa_ptr->sin_port;
- natlook.direction = PF_OUT;
-
- /*
- * Open the pf device and lookup the mapping pair to find
- * the original address we were supposed to connect to.
- */
- fd = open("/dev/pf", O_RDWR);
- if (fd == -1) {
- syslog(LOG_ERR, "cannot open /dev/pf (%m)");
- exit(EX_UNAVAILABLE);
- }
-
- if (ioctl(fd, DIOCNATLOOK, &natlook) == -1) {
- syslog(LOG_INFO,
- "pf nat lookup failed %s:%hu (%m)",
- inet_ntoa(client_sa_ptr->sin_addr),
- ntohs(client_sa_ptr->sin_port));
- close(fd);
- return(-1);
- }
- close(fd);
-
- /*
- * Now jam the original address and port back into the into
- * destination sockaddr_in for the proxy to deal with.
- */
- memset((void *)real_server_sa_ptr, 0, sizeof(struct sockaddr_in));
- real_server_sa_ptr->sin_port = natlook.rdport;
- real_server_sa_ptr->sin_addr.s_addr = natlook.rdaddr.addr32[0];
- real_server_sa_ptr->sin_len = sizeof(struct sockaddr_in);
- real_server_sa_ptr->sin_family = AF_INET;
- return(0);
-}
-
-
-/*
- * Transfer one unit of data across a pair of sockets
- *
- * A unit of data is as much as we get with a single read(2) call.
- */
-int
-xfer_data(const char *what_read,int from_fd, int to_fd, struct in_addr from,
- struct in_addr to)
-{
- int rlen, offset, xerrno, mark, flags = 0;
- char tbuf[4096];
-
- /*
- * Are we at the OOB mark?
- */
- if (ioctl(from_fd, SIOCATMARK, &mark) < 0) {
- xerrno = errno;
- syslog(LOG_ERR, "cannot ioctl(SIOCATMARK) socket from %s (%m)",
- what_read);
- errno = xerrno;
- return(-1);
- }
- if (mark)
- flags = MSG_OOB; /* Yes - at the OOB mark */
-
-snarf:
- rlen = recv(from_fd, tbuf, sizeof(tbuf), flags);
- if (rlen == -1 && flags == MSG_OOB && errno == EINVAL) {
- /* OOB didn't work */
- flags = 0;
- rlen = recv(from_fd, tbuf, sizeof(tbuf), flags);
- }
- if (rlen == 0) {
- debuglog(3, "EOF on read socket");
- return(0);
- } else if (rlen == -1) {
- if (errno == EAGAIN || errno == EINTR)
- goto snarf;
- xerrno = errno;
- syslog(LOG_ERR, "xfer_data (%s): failed (%m) with flags 0%o",
- what_read, flags);
- errno = xerrno;
- return(-1);
- } else {
- offset = 0;
- debuglog(3, "got %d bytes from socket", rlen);
-
- while (offset < rlen) {
- int wlen;
- fling:
- wlen = send(to_fd, &tbuf[offset], rlen - offset,
- flags);
- if (wlen == 0) {
- debuglog(3, "zero-length write");
- goto fling;
- } else if (wlen == -1) {
- if (errno == EAGAIN || errno == EINTR)
- goto fling;
- xerrno = errno;
- syslog(LOG_INFO, "write failed (%m)");
- errno = xerrno;
- return(-1);
- } else {
- debuglog(3, "wrote %d bytes to socket",wlen);
- offset += wlen;
- }
- }
- return(offset);
- }
-}
-
-/*
- * get_backchannel_socket gets us a socket bound somewhere in a
- * particular range of ports
- */
-int
-get_backchannel_socket(int type, int min_port, int max_port, int start_port,
- int direction, struct sockaddr_in *sap)
-{
- int count;
-
- /*
- * Make sure that direction is 'defined' and that min_port is not
- * greater than max_port.
- */
- if (direction != -1)
- direction = 1;
-
- /* by default we go up by one port until we find one */
- if (min_port > max_port) {
- errno = EINVAL;
- return(-1);
- }
-
- count = 1 + max_port - min_port;
-
- /*
- * Pick a port we can bind to from within the range we want.
- * If the caller specifies -1 as the starting port number then
- * we pick one somewhere in the range to try.
- * This is an optimization intended to speedup port selection and
- * has NOTHING to do with security.
- */
- if (start_port == -1)
- start_port = (arc4random() % count) + min_port;
-
- if (start_port < min_port || start_port > max_port) {
- errno = EINVAL;
- return(-1);
- }
-
- while (count-- > 0) {
- struct sockaddr_in sa;
- int one, fd;
-
- fd = socket(AF_INET, type, 0);
-
- bzero(&sa, sizeof sa);
- sa.sin_family = AF_INET;
- if (Bind_Addr == INADDR_NONE)
- if (sap == NULL)
- sa.sin_addr.s_addr = INADDR_ANY;
- else
- sa.sin_addr.s_addr = sap->sin_addr.s_addr;
- else
- sa.sin_addr.s_addr = Bind_Addr;
-
- /*
- * Indicate that we want to reuse a port if it happens that the
- * port in question was a listen port recently.
- */
- one = 1;
- if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one,
- sizeof(one)) == -1)
- return(-1);
-
- sa.sin_port = htons(start_port);
-
- if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)) == 0) {
- if (sap != NULL)
- *sap = sa;
- return(fd);
- }
-
- if (errno != EADDRINUSE)
- return(-1);
-
- /* if it's in use, try the next port */
- close(fd);
-
- start_port += direction;
- if (start_port < min_port)
- start_port = max_port;
- else if (start_port > max_port)
- start_port = min_port;
- }
- errno = EAGAIN;
- return(-1);
-}
diff --git a/contrib/pf/ftp-proxy/util.h b/contrib/pf/ftp-proxy/util.h
deleted file mode 100644
index 597cd18d33bb..000000000000
--- a/contrib/pf/ftp-proxy/util.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* $OpenBSD: util.h,v 1.3 2002/05/23 10:22:14 deraadt Exp $ */
-
-/*
- * Copyright (c) 1996-2001
- * Obtuse Systems Corporation. 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 Obtuse Systems 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 OBTUSE SYSTEMS CORPORATION 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.
- */
-
-struct proxy_channel {
- int pc_to_fd, pc_from_fd;
- int pc_alive;
- int pc_nextbyte;
- int pc_flags;
- int pc_length;
- int pc_size;
- struct sockaddr_in pc_from_sa, pc_to_sa;
- int (*pc_filter)( void ** databuf, int datalen);
- char *pc_buffer;
-};
-
-struct csiob {
- int fd;
- int line_buffer_size, io_buffer_size, io_buffer_len, next_byte;
- unsigned char *io_buffer, *line_buffer;
- struct sockaddr_in sa, real_sa;
- char *who;
- char alive, got_eof, data_available;
- int send_oob_flags;
-};
-
-extern int telnet_getline(struct csiob *iobp,
- struct csiob *telnet_passthrough);
-
-extern int get_proxy_env(int fd, struct sockaddr_in *server_sa_ptr,
- struct sockaddr_in *client_sa_ptr);
-
-extern int get_backchannel_socket(int type, int min_port, int max_port,
- int start_port, int direction, struct sockaddr_in *sap);
-
-extern int xfer_data(const char *what_read, int from_fd, int to_fd,
- struct in_addr from, struct in_addr to);
-
-extern char *ProgName;
-
-
diff --git a/contrib/pf/man/pf.4 b/contrib/pf/man/pf.4
deleted file mode 100644
index df0ff6c0fb83..000000000000
--- a/contrib/pf/man/pf.4
+++ /dev/null
@@ -1,837 +0,0 @@
-.\" $OpenBSD: pf.4,v 1.48 2004/03/27 17:15:30 henning Exp $
-.\"
-.\" Copyright (C) 2001, Kjell Wooding. 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.
-.\" 3. Neither the name of the project 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 PROJECT 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 PROJECT 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.
-.\"
-.Dd June 24, 2001
-.Dt PF 4
-.Os
-.Sh NAME
-.Nm pf
-.Nd packet filter
-.Sh SYNOPSIS
-.Cd "pseudo-device pf"
-.Sh DESCRIPTION
-Packet filtering takes place in the kernel.
-A pseudo-device,
-.Pa /dev/pf ,
-allows userland processes to control the
-behavior of the packet filter through an
-.Xr ioctl 2
-interface.
-There are commands to enable and disable the filter, load rulesets,
-add and remove individual rules or state table entries,
-and retrieve statistics.
-The most commonly used functions are covered by
-.Xr pfctl 8 .
-.Pp
-Manipulations like loading a ruleset that involve more than a single
-ioctl call require a so-called ticket, which prevents the occurrence of
-multiple concurrent manipulations.
-.Pp
-Fields of ioctl parameter structures that refer to packet data (like
-addresses and ports) are generally expected in network byte-order.
-.Sh FILES
-.Bl -tag -width /dev/pf -compact
-.It Pa /dev/pf
-packet filtering device.
-.El
-.Sh IOCTL INTERFACE
-pf supports the following
-.Xr ioctl 2
-commands:
-.Bl -tag -width xxxxxx
-.It Dv DIOCSTART
-Starts the packet filter.
-.It Dv DIOCSTOP
-Stops the packet filter.
-.It Dv DIOCSTARTALTQ
-Starts the ALTQ bandwidth control system.
-.It Dv DIOCSTOPALTQ
-Stops the ALTQ bandwidth control system.
-.It Dv DIOCBEGINADDRS Fa "struct pfioc_pooladdr"
-.Bd -literal
-struct pfioc_pooladdr {
- u_int32_t action;
- u_int32_t ticket;
- u_int32_t nr;
- u_int32_t r_num;
- u_int8_t r_action;
- u_int8_t r_last;
- u_int8_t af;
- char anchor[PF_ANCHOR_NAME_SIZE];
- char ruleset[PF_RULESET_NAME_SIZE];
- struct pf_pooladdr addr;
-};
-.Ed
-.Pp
-Clears the buffer address pool
-and returns a
-.Va ticket
-for subsequent DIOCADDADDR, DIOCADDRULE and DIOCCHANGERULE calls.
-.It Dv DIOCADDADDR Fa "struct pfioc_pooladdr"
-.Pp
-Adds pool address
-.Va addr
-to the buffer address pool to be used in the following
-DIOCADDRULE or DIOCCHANGERULE call.
-All other members of the structure are ignored.
-.It Dv DIOCADDRULE Fa "struct pfioc_rule"
-.Bd -literal
-struct pfioc_rule {
- u_int32_t action;
- u_int32_t ticket;
- u_int32_t pool_ticket;
- u_int32_t nr;
- char anchor[PF_ANCHOR_NAME_SIZE];
- char ruleset[PF_RULESET_NAME_SIZE];
- struct pf_rule rule;
-};
-.Ed
-.Pp
-Adds
-.Va rule
-at the end of the inactive ruleset.
-Requires
-.Va ticket
-obtained through preceding DIOCXBEGIN call, and
-.Va pool_ticket
-obtained through DIOCBEGINADDRS call.
-DIOCADDADDR must also be called if any pool addresses are required.
-The optional
-.Va anchor
-and
-.Va ruleset
-names indicate the anchor and ruleset in which to append the rule.
-.Va nr
-and
-.Va action
-are ignored.
-.It Dv DIOCADDALTQ Fa "struct pfioc_altq"
-Adds
-.Bd -literal
-struct pfioc_altq {
- u_int32_t action;
- u_int32_t ticket;
- u_int32_t nr;
- struct pf_altq altq;
-};
-.Ed
-.It Dv DIOCGETRULES Fa "struct pfioc_rule"
-Returns
-.Va ticket
-for subsequent DIOCGETRULE calls and
-.Va nr
-of rules in the active ruleset.
-.It Dv DIOCGETRULE Fa "struct pfioc_rule"
-Returns
-.Va rule
-number
-.Va nr
-using
-.Va ticket
-obtained through a preceding DIOCGETRULES call.
-.It Dv DIOCGETADDRS Fa "struct pfioc_pooladdr"
-Returns
-.Va ticket
-for subsequent DIOCGETADDR calls and
-.Va nr
-of pool addresses in the rule specified with
-.Va r_action ,
-.Va r_num ,
-.Va anchor
-and
-.Va ruleset .
-.It Dv DIOCGETADDR Fa "struct pfioc_pooladdr"
-Returns pool address
-.Va addr
-number
-.Va nr
-from the rule specified with
-.Va r_action ,
-.Va r_num ,
-.Va anchor
-and
-.Va ruleset
-using
-.Va ticket
-obtained through a preceding DIOCGETADDRS call.
-.It Dv DIOCGETALTQS Fa "struct pfioc_altq"
-Returns
-.Va ticket
-for subsequent DIOCGETALTQ calls and
-.Va nr
-of queues in the active list.
-.It Dv DIOCGETALTQ Fa "struct pfioc_altq"
-Returns
-.Va altq
-number
-.Va nr
-using
-.Va ticket
-obtained through a preceding DIOCGETALTQS call.
-.It Dv DIOCGETQSTATS Fa "struct pfioc_qstats"
-Returns statistics on a queue.
-.Bd -literal
-struct pfioc_qstats {
- u_int32_t ticket;
- u_int32_t nr;
- void *buf;
- int nbytes;
- u_int8_t scheduler;
-};
-.Ed
-.Pp
-A pointer to a buffer of statistics
-.Va buf
-of length
-.Va nbytes
-for the queue specified by
-.Va nr .
-.It Dv DIOCADDSTATE Fa "struct pfioc_state"
-Adds a state entry.
-.It Dv DIOCGETSTATE Fa "struct pfioc_state"
-.Bd -literal
-struct pfioc_state {
- u_int32_t nr;
- struct pf_state state;
-};
-.Ed
-.Pp
-Extracts the entry with the specified number from the state table.
-.It Dv DIOCKILLSTATES Fa "struct pfioc_state_kill"
-Removes matching entries from the state table.
-Returns the number of killed states in psk_af.
-.Bd -literal
-struct pfioc_state_kill {
- int psk_af;
- int psk_proto;
- struct pf_rule_addr psk_src;
- struct pf_rule_addr psk_dst;
- char psk_ifname[IFNAMSIZ];
-};
-.Ed
-.It Dv DIOCCLRSTATES Fa "struct pfioc_state_kill"
-Clears all states.
-It works like
-.Dv DIOCKILLSTATES ,
-but ignores the psk_af, psk_proto, psk_src and psk_dst fields of the
-.Fa pfioc_state_kill
-structure.
-.It Dv DIOCSETSTATUSIF Fa "struct pfioc_if"
-.Bd -literal
-struct pfioc_if {
- char ifname[IFNAMSIZ];
-};
-.Ed
-.Pp
-Specifies the interface for which statistics are accumulated.
-.It Dv DIOCGETSTATUS Fa "struct pf_status"
-.Bd -literal
-struct pf_status {
- u_int64_t counters[PFRES_MAX];
- u_int64_t fcounters[FCNT_MAX];
- u_int64_t scounters[SCNT_MAX];
- u_int64_t pcounters[2][2][3];
- u_int64_t bcounters[2][2];
- u_int64_t stateid;
- u_int32_t running;
- u_int32_t states;
- u_int32_t src_nodes;
- u_int32_t since;
- u_int32_t debug;
- u_int32_t hostid;
- char ifname[IFNAMSIZ];
-};
-.Ed
-.Pp
-Gets the internal packet filter statistics.
-.It Dv DIOCCLRSTATUS
-Clears the internal packet filter statistics.
-.It Dv DIOCNATLOOK Fa "struct pfioc_natlook"
-Looks up a state table entry by source and destination addresses and ports.
-.Bd -literal
-struct pfioc_natlook {
- struct pf_addr saddr;
- struct pf_addr daddr;
- struct pf_addr rsaddr;
- struct pf_addr rdaddr;
- u_int16_t sport;
- u_int16_t dport;
- u_int16_t rsport;
- u_int16_t rdport;
- sa_family_t af;
- u_int8_t proto;
- u_int8_t direction;
-};
-.Ed
-.It Dv DIOCSETDEBUG Fa "u_int32_t"
-Sets the debug level.
-.Bd -literal
-enum { PF_DEBUG_NONE=0, PF_DEBUG_URGENT=1, PF_DEBUG_MISC=2 };
-.Ed
-.It Dv DIOCGETSTATES Fa "struct pfioc_states"
-.Bd -literal
-struct pfioc_states {
- int ps_len;
- union {
- caddr_t psu_buf;
- struct pf_state *psu_states;
- } ps_u;
-#define ps_buf ps_u.psu_buf
-#define ps_states ps_u.psu_states
-};
-.Ed
-.It Dv DIOCCHANGERULE Fa "struct pfioc_rule"
-Adds or removes the
-.Va rule
-in the ruleset specified by
-.Va rule.action .
-.Bd -literal
-enum { PF_CHANGE_ADD_HEAD=1, PF_CHANGE_ADD_TAIL=2,
- PF_CHANGE_ADD_BEFORE=3, PF_CHANGE_ADD_AFTER=4,
- PF_CHANGE_REMOVE=5, PF_CHANGE_GET_TICKET=6 };
-.Ed
-.Pp
-The type of operation to be performed is indicated by
-.Va action .
-.Pp
-.Va ticket
-must be set to the value obtained with PF_CHANGE_GET_TICKET
-for all actions except PF_CHANGE_GET_TICKET.
-.Va pool_ticket
-must be set to the value obtained with the DIOCBEGINADDRS call
-for all actions except PF_CHANGE_REMOVE and PF_CHANGE_GET_TICKET.
-.Pp
-.Va anchor
-and
-.Va ruleset
-indicate which anchor and ruleset the operation applies to.
-.Va nr
-indicates the rule number against which PF_CHANGE_ADD_BEFORE,
-PF_CHANGE_ADD_AFTER or PF_CHANGE_REMOVE actions are applied.
-.It Dv DIOCCHANGEADDR Fa "struct pfioc_pooladdr"
-Adds or removes a pool address
-.Va addr
-from a rule specified with
-.Va r_action ,
-.Va r_num ,
-.Va anchor
-and
-.Va ruleset .
-.It Dv DIOCSETTIMEOUT Fa "struct pfioc_tm"
-.Bd -literal
-struct pfioc_tm {
- int timeout;
- int seconds;
-};
-.Ed
-.It Dv DIOCGETTIMEOUT Fa "struct pfioc_tm"
-.It Dv DIOCCLRRULECTRS
-Clear per-rule statistics.
-.It Dv DIOCSETLIMIT Fa "struct pfioc_limit"
-Sets hard limits on the memory pools used by the packet filter.
-.Bd -literal
-struct pfioc_limit {
- int index;
- unsigned limit;
-};
-.Ed
-.It Dv DIOCGETLIMIT Fa "struct pfioc_limit"
-.It Dv DIOCRCLRTABLES Fa "struct pfioc_table"
-Clear all tables.
-All the IOCTLs that manipulate radix tables
-use the same structure described below.
-For
-.Dv DIOCRCLRTABLES, pfrio_ndel contains on exit the number
-of tables deleted.
-.Bd -literal
-struct pfioc_table {
- struct pfr_table pfrio_table;
- void *pfrio_buffer;
- int pfrio_esize;
- int pfrio_size;
- int pfrio_size2;
- int pfrio_nadd;
- int pfrio_ndel;
- int pfrio_nchange;
- int pfrio_flags;
- int pfrio_ticket;
-};
-#define pfrio_exists pfrio_nadd
-#define pfrio_nzero pfrio_nadd
-#define pfrio_nmatch pfrio_nadd
-#define pfrio_naddr pfrio_size2
-#define pfrio_setflag pfrio_size2
-#define pfrio_clrflag pfrio_nadd
-.Ed
-.It Dv DIOCRADDTABLES Fa "struct pfioc_table"
-Creates one or more tables.
-On entry, pfrio_buffer[pfrio_size] contains a table of pfr_table structures.
-On exit, pfrio_nadd contains the number of tables effectively created.
-.Bd -literal
-struct pfr_table {
- char pfrt_anchor[PF_ANCHOR_NAME_SIZE];
- char pfrt_ruleset[PF_RULESET_NAME_SIZE];
- char pfrt_name[PF_TABLE_NAME_SIZE];
- u_int32_t pfrt_flags;
- u_int8_t pfrt_fback;
-};
-.Ed
-.It Dv DIOCRDELTABLES Fa "struct pfioc_table"
-Deletes one or more tables.
-On entry, pfrio_buffer[pfrio_size] contains a table of pfr_table structures.
-On exit, pfrio_nadd contains the number of tables effectively deleted.
-.It Dv DIOCRGETTABLES Fa "struct pfioc_table"
-Get the list of all tables.
-On entry, pfrio_buffer[pfrio_size] contains a valid writeable buffer for
-pfr_table structures.
-On exit, pfrio_size contains the number of tables written into the buffer.
-If the buffer is too small, the kernel does not store anything but just
-returns the required buffer size, without error.
-.It Dv DIOCRGETTSTATS Fa "struct pfioc_table"
-Like
-.Dv DIOCRGETTABLES ,
-but returns an array of pfr_tstats structures.
-.Bd -literal
-struct pfr_tstats {
- struct pfr_table pfrts_t;
- u_int64_t pfrts_packets
- [PFR_DIR_MAX][PFR_OP_TABLE_MAX];
- u_int64_t pfrts_bytes
- [PFR_DIR_MAX][PFR_OP_TABLE_MAX];
- u_int64_t pfrts_match;
- u_int64_t pfrts_nomatch;
- long pfrts_tzero;
- int pfrts_cnt;
- int pfrts_refcnt[PFR_REFCNT_MAX];
-};
-#define pfrts_name pfrts_t.pfrt_name
-#define pfrts_flags pfrts_t.pfrt_flags
-.Ed
-.It Dv DIOCRCLRTSTATS Fa "struct pfioc_table"
-Clears the statistics of one or more tables.
-On entry, pfrio_buffer[pfrio_size] contains a table of pfr_table structures.
-On exit, pfrio_nzero contains the number of tables effectively cleared.
-.It Dv DIOCRCLRADDRS Fa "struct pfioc_table"
-Clear all addresses in a table.
-On entry, pfrio_table contains the table to clear.
-On exit, pfrio_ndel contains the number of addresses removed.
-.It Dv DIOCRADDADDRS Fa "struct pfioc_table"
-Add one or more addresses to a table.
-On entry, pfrio_table contains the table id and pfrio_buffer[pfrio_size]
-contains the list of pfr_addr structures to add.
-On exit, pfrio_nadd contains the number of addresses effectively added.
-.Bd -literal
-struct pfr_addr {
- union {
- struct in_addr _pfra_ip4addr;
- struct in6_addr _pfra_ip6addr;
- } pfra_u;
- u_int8_t pfra_af;
- u_int8_t pfra_net;
- u_int8_t pfra_not;
- u_int8_t pfra_fback;
-};
-#define pfra_ip4addr pfra_u._pfra_ip4addr
-#define pfra_ip6addr pfra_u._pfra_ip6addr
-.Ed
-.It Dv DIOCRDELADDRS Fa "struct pfioc_table"
-Delete one or more addresses from a table.
-On entry, pfrio_table contains the table id and pfrio_buffer[pfrio_size]
-contains the list of pfr_addr structures to delete.
-On exit, pfrio_ndel contains the number of addresses effectively deleted.
-.It Dv DIOCRSETADDRS Fa "struct pfioc_table"
-Replace the content of a table by a new address list.
-This is the most complicated command, which uses all the structure members.
-On entry, pfrio_table contains the table id and pfrio_buffer[pfrio_size]
-contains the new list of pfr_addr structures.
-In addition to that, if size2 is nonzero, pfrio_buffer[pfrio_size..pfrio_size2]
-must be a writeable buffer, into which the kernel can copy the addresses that
-have been deleted during the replace operation.
-On exit, pfrio_ndel, pfrio_nadd and pfrio_nchange contain the number of
-addresses deleted, added and changed by the kernel.
-If pfrio_size2 was set on
-entry, pfrio_size2 will point to the size of the buffer used, exactly like
-.Dv DIOCRGETADDRS .
-.It Dv DIOCRGETADDRS Fa "struct pfioc_table"
-Get all the addresses of a table.
-On entry, pfrio_table contains the table id and pfrio_buffer[pfrio_size]
-contains a valid writeable buffer for pfr_addr structures.
-On exit, pfrio_size contains the number of addresses written into the buffer.
-If the buffer was too small, the kernel does not store anything but just
-return the required buffer size, without returning an error.
-.It Dv DIOCRGETASTATS Fa "struct pfioc_table"
-Like
-.Dv DIOCRGETADDRS ,
-but returns an array of pfr_astats structures.
-.Bd -literal
-struct pfr_astats {
- struct pfr_addr pfras_a;
- u_int64_t pfras_packets
- [PFR_DIR_MAX][PFR_OP_ADDR_MAX];
- u_int64_t pfras_bytes
- [PFR_DIR_MAX][PFR_OP_ADDR_MAX];
- long pfras_tzero;
-};
-.Ed
-.It Dv DIOCRCLRASTATS Fa "struct pfioc_table"
-Clears the statistics of one or more addresses.
-On entry, pfrio_table contains the table id and pfrio_buffer[pfrio_size]
-contains a table of pfr_addr structures to clear.
-On exit, pfrio_nzero contains the number of addresses effectively cleared.
-.It Dv DIOCRTSTADDRS Fa "struct pfioc_table"
-Test if the given addresses match a table.
-On entry, pfrio_table contains the table id and pfrio_buffer[pfrio_size]
-contains a table of pfr_addr structures to test.
-On exit, the kernel updates the pfr_addr table by setting the pfra_fback
-member appropriately.
-.It Dv DIOCRSETTFLAGS Fa "struct pfioc_table"
-Change the
-.Va const
-or
-.Va persist
-flag of a table.
-On entry, pfrio_buffer[pfrio_size] contains a table of pfr_table structures,
-and pfrio_setflag contains the flags to add, while pfrio_clrflag contains the
-flags to remove.
-On exit, pfrio_nchange and pfrio_ndel contain the number of tables altered
-or deleted by the kernel.
-Yes, tables can be deleted if one removes the
-.Va persist
-flag of an unreferenced table.
-.It Dv DIOCRINADEFINE Fa "struct pfioc_table"
-Defines a table in the inactive set.
-On entry, pfrio_table contains the table id and pfrio_buffer[pfrio_size]
-contains the list of pfr_addr structures to put in the table.
-A valid ticket must also be supplied to pfrio_ticket.
-On exit, pfrio_nadd contains 0 if the table was already defined in the
-inactive list, or 1 if a new table has been created.
-pfrio_naddr contains the number of addresses effectively put in the table.
-.It Dv DIOCXBEGIN Fa "struct pfioc_trans"
-.Bd -literal
-#define PF_RULESET_ALTQ (PF_RULESET_MAX)
-#define PF_RULESET_TABLE (PF_RULESET_MAX+1)
-struct pfioc_trans {
- int size; /* number of elements */
- int esize; /* size of each element in bytes */
- struct pfioc_trans_e {
- int rs_num;
- char anchor[PF_ANCHOR_NAME_SIZE];
- char ruleset[PF_RULESET_NAME_SIZE];
- u_int32_t ticket;
- } *array;
-};
-.Ed
-.Pp
-Clears all the inactive rulesets specified in the
-.Fa "struct pfioc_trans_e"
-array.
-For each ruleset, a ticket is returned for subsequent "add rule" IOCTLs,
-as well as for the
-.Dv DIOCXCOMMIT
-and
-.Dv DIOCXROLLBACK
-calls.
-.It Dv DIOCXCOMMIT Fa "struct pfioc_trans"
-Atomically switch a vector of inactive rulesets to the active rulesets.
-Implemented as a standard 2-phase commit, which will either fail for all
-rulesets or completely succeed.
-All tickets need to be valid.
-Returns
-.Dv EBUSY
-if a concurrent process is trying to update some of the same rulesets
-concurrently.
-.It Dv DIOCXROLLBACK Fa "struct pfioc_trans"
-Clean up the kernel by undoing all changes that have taken place on the
-inactive rulesets since the last
-.Dv DIOCXBEGIN .
-.Dv DIOCXROLLBACK
-will silently ignore rulesets for which the ticket is invalid.
-.It Dv DIOCFPFLUSH
-Flush the passive OS fingerprint table.
-.It Dv DIOCFPADD Fa "struct pf_osfp_ioctl"
-.Bd -literal
-struct pf_osfp_ioctl {
- struct pf_osfp_entry {
- SLIST_ENTRY(pf_osfp_entry) fp_entry;
- pf_osfp_t fp_os;
- char fp_class_nm[PF_OSFP_LEN];
- char fp_version_nm[PF_OSFP_LEN];
- char fp_subtype_nm[PF_OSFP_LEN];
- } fp_os;
- u_int16_t fp_mss;
- u_int16_t fp_wsize;
- u_int16_t fp_psize;
- u_int8_t fp_ttl;
- u_int8_t fp_wscale;
- u_int8_t fp_flags;
- int fp_getnum;
-};
-.Ed
-.Pp
-Add a passive OS fingerprint to the table.
-Set
-.Va fp_os.fp_os
-to the packed fingerprint,
-.Va fp_os.fp_class_nm
-to the name of the class (Linux, Windows, etc),
-.Va fp_os.fp_version_nm
-to the name of the version (NT, 95, 98), and
-.Va fp_os.fp_subtype_nm
-to the name of the subtype or patchlevel.
-The members
-.Va fp_mss ,
-.Va fp_wsize ,
-.Va fp_psize ,
-.Va fp_ttl ,
-and
-.Va fp_wscale
-are set to the TCP MSS, the TCP window size, the IP length and the IP TTL of
-the TCP SYN packet respectively.
-The
-.Va fp_flags
-member is filled according to the net/pfvar.h include file PF_OSFP_* defines.
-The
-.Va fp_getnum
-is not used with this ioctl.
-.Pp
-The structure's slack space must be zeroed for correct operation; memset
-the whole structure to zero before filling and sending to the kernel.
-.It Dv DIOCFPGET Fa "struct pf_osfp_ioctl"
-.Bd -literal
-struct pf_osfp_ioctl {
- struct pf_osfp_entry {
- SLIST_ENTRY(pf_osfp_entry) fp_entry;
- pf_osfp_t fp_os;
- char fp_class_nm[PF_OSFP_LEN];
- char fp_version_nm[PF_OSFP_LEN];
- char fp_subtype_nm[PF_OSFP_LEN];
- } fp_os;
- u_int16_t fp_mss;
- u_int16_t fp_wsize;
- u_int16_t fp_psize;
- u_int8_t fp_ttl;
- u_int8_t fp_wscale;
- u_int8_t fp_flags;
- int fp_getnum;
-};
-.Ed
-.Pp
-Get the passive OS fingerprint number
-.Va fp_getnum
-from the kernel's fingerprint list.
-The rest of the structure members will come back filled.
-Get the whole list by repeatedly incrementing the
-.Va fp_getnum
-number until the ioctl returns EBUSY.
-.It Dv DIOCGETSRCNODES Fa "struct pfioc_src_nodes"
-.Bd -literal
-struct pfioc_src_nodes {
- int psn_len;
- union {
- caddr_t psu_buf;
- struct pf_src_node *psu_src_nodes;
- } psn_u;
-#define psn_buf psn_u.psu_buf
-#define psn_src_nodes psn_u.psu_src_nodes
-};
-.Ed
-.Pp
-Get the list of source nodes kept by the
-.Ar sticky-address
-and
-.Ar source-track
-options.
-The ioctl must be called once with
-.Va psn_len
-set to 0.
-If the ioctl returns without error,
-.Va psn_len
-will be set to the size of the buffer required to hold all the
-.Va pf_src_node
-structures held in the table.
-A buffer of this size should then be allocated, and a pointer to this buffer
-placed in
-.Va psn_buf .
-The ioctl must then be called again to fill this buffer with the actual
-source node data.
-After the ioctl call
-.Va psn_len
-will be set to the length of the buffer actually used.
-.It Dv DIOCCLRSRCNODES Fa "struct pfioc_table"
-Clear the tree of source tracking nodes.
-.It Dv DIOCIGETIFACES Fa "struct pfioc_iface"
-Gets the list of interfaces and interface drivers known to
-.Nm .
-All the IOCTLs that manipulate interfaces
-use the same structure described below:
-.Bd -literal
-struct pfioc_iface {
- char pfiio_name[IFNAMSIZ];
- void *pfiio_buffer;
- int pfiio_esize;
- int pfiio_size;
- int pfiio_nzero;
- int pfiio_flags;
-};
-
-#define PFI_FLAG_GROUP 0x0001 /* gets groups of interfaces */
-#define PFI_FLAG_INSTANCE 0x0002 /* gets single interfaces */
-#define PFI_FLAG_ALLMASK 0x0003
-.Ed
-.Pp
-If not empty,
-.Va pfiio_name
-can be used to restrict the search to a specific interface or driver.
-.Va pfiio_buffer[pfiio_size]
-is the user-supplied buffer for returning the data.
-On entry,
-.Va pfiio_size
-represents the number of
-.Va pfi_if
-entries that can fit into the buffer.
-The kernel will replace this value by the real number of entries it wants
-to return.
-.Va pfiio_esize
-should be set to sizeof(struct pfi_if).
-.Va pfiio_flags
-should be set to
-.Dv PFI_FLAG_GROUP , PFI_FLAG_INSTANCE ,
-or both to tell the kernel to return a group of interfaces
-(drivers, like "fxp"), real interface instances (like "fxp1") or both.
-The data is returned in the
-.Va pfi_if
-structure described below:
-.Bd -literal
-struct pfi_if {
- char pfif_name[IFNAMSIZ];
- u_int64_t pfif_packets[2][2][2];
- u_int64_t pfif_bytes[2][2][2];
- u_int64_t pfif_addcnt;
- u_int64_t pfif_delcnt;
- long pfif_tzero;
- int pfif_states;
- int pfif_rules;
- int pfif_flags;
-};
-
-#define PFI_IFLAG_GROUP 0x0001 /* group of interfaces */
-#define PFI_IFLAG_INSTANCE 0x0002 /* single instance */
-#define PFI_IFLAG_CLONABLE 0x0010 /* clonable group */
-#define PFI_IFLAG_DYNAMIC 0x0020 /* dynamic group */
-#define PFI_IFLAG_ATTACHED 0x0040 /* interface attached */
-#define PFI_IFLAG_REFERENCED 0x0080 /* referenced by rules */
-.Ed
-.It Dv DIOCICLRISTATS Fa "struct pfioc_iface"
-Clear the statistics counters of one or more interfaces.
-.Va pfiio_name
-and
-.Va pfrio_flags
-can be used to select which interfaces need to be cleared.
-The filtering process is the same as for
-.Dv DIOCIGETIFACES .
-.Va pfiio_nzero
-will be set by the kernel to the number of interfaces and drivers
-that have been cleared.
-.El
-.Sh EXAMPLES
-The following example demonstrates how to use the DIOCNATLOOK command
-to find the internal host/port of a NATed connection.
-.Bd -literal
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <sys/fcntl.h>
-#include <net/if.h>
-#include <netinet/in.h>
-#include <net/pfvar.h>
-#include <err.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-u_int32_t
-read_address(const char *s)
-{
- int a, b, c, d;
-
- sscanf(s, "%i.%i.%i.%i", &a, &b, &c, &d);
- return htonl(a << 24 | b << 16 | c << 8 | d);
-}
-
-void
-print_address(u_int32_t a)
-{
- a = ntohl(a);
- printf("%d.%d.%d.%d", a >> 24 & 255, a >> 16 & 255,
- a >> 8 & 255, a & 255);
-}
-
-int
-main(int argc, char *argv[])
-{
- struct pfioc_natlook nl;
- int dev;
-
- if (argc != 5) {
- printf("%s <gwy addr> <gwy port> <ext addr> <ext port>\\n",
- argv[0]);
- return 1;
- }
-
- dev = open("/dev/pf", O_RDWR);
- if (dev == -1)
- err(1, "open(\\"/dev/pf\\") failed");
-
- memset(&nl, 0, sizeof(struct pfioc_natlook));
- nl.saddr.v4.s_addr = read_address(argv[1]);
- nl.sport = htons(atoi(argv[2]));
- nl.daddr.v4.s_addr = read_address(argv[3]);
- nl.dport = htons(atoi(argv[4]));
- nl.af = AF_INET;
- nl.proto = IPPROTO_TCP;
- nl.direction = PF_IN;
-
- if (ioctl(dev, DIOCNATLOOK, &nl))
- err(1, "DIOCNATLOOK");
-
- printf("internal host ");
- print_address(nl.rsaddr.v4.s_addr);
- printf(":%u\\n", ntohs(nl.rsport));
- return 0;
-}
-.Ed
-.Sh SEE ALSO
-.Xr ioctl 2 ,
-.Xr bridge 4 ,
-.Xr pflog 4 ,
-.Xr pfsync 4 ,
-.Xr pfctl 8
-.Sh HISTORY
-The
-.Nm
-packet filtering mechanism first appeared in
-.Ox 3.0 .
diff --git a/contrib/pf/man/pf.conf.5 b/contrib/pf/man/pf.conf.5
deleted file mode 100644
index b5db41295518..000000000000
--- a/contrib/pf/man/pf.conf.5
+++ /dev/null
@@ -1,2632 +0,0 @@
-.\" $OpenBSD: pf.conf.5,v 1.292 2004/02/24 05:44:48 mcbride Exp $
-.\"
-.\" Copyright (c) 2002, Daniel Hartmeier
-.\" 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.
-.\"
-.Dd November 19, 2002
-.Dt PF.CONF 5
-.Os
-.Sh NAME
-.Nm pf.conf
-.Nd packet filter configuration file
-.Sh DESCRIPTION
-The
-.Xr pf 4
-packet filter modifies, drops or passes packets according to rules or
-definitions specified in
-.Nm pf.conf .
-.Sh STATEMENT ORDER
-There are seven types of statements in
-.Nm pf.conf :
-.Bl -tag -width xxxx
-.It Cm Macros
-User-defined variables may be defined and used later, simplifying
-the configuration file.
-Macros must be defined before they are referenced in
-.Nm pf.conf .
-.It Cm Tables
-Tables provide a mechanism for increasing the performance and flexibility of
-rules with large numbers of source or destination addresses.
-.It Cm Options
-Options tune the behaviour of the packet filtering engine.
-.It Cm Traffic Normalization Li (e.g. Em scrub )
-Traffic normalization protects internal machines against inconsistencies
-in Internet protocols and implementations.
-.It Cm Queueing
-Queueing provides rule-based bandwidth control.
-.It Cm Translation Li (Various forms of NAT)
-Translation rules specify how addresses are to be mapped or redirected to
-other addresses.
-.It Cm Packet Filtering
-Stateful and stateless packet filtering provides rule-based blocking or
-passing of packets.
-.El
-.Pp
-With the exception of
-.Cm macros
-and
-.Cm tables ,
-the types of statements should be grouped and appear in
-.Nm pf.conf
-in the order shown above, as this matches the operation of the underlying
-packet filtering engine.
-By default
-.Xr pfctl 8
-enforces this order (see
-.Ar set require-order
-below).
-.Sh MACROS
-Much like
-.Xr cpp 1
-or
-.Xr m4 1 ,
-macros can be defined that will later be expanded in context.
-Macro names must start with a letter, and may contain letters, digits
-and underscores.
-Macro names may not be reserved words (for example
-.Ar pass ,
-.Ar in ,
-.Ar out ) .
-Macros are not expanded inside quotes.
-.Pp
-For example,
-.Bd -literal -offset indent
-ext_if = \&"kue0\&"
-all_ifs = \&"{\&" $ext_if lo0 \&"}\&"
-pass out on $ext_if from any to any keep state
-pass in on $ext_if proto tcp from any to any port 25 keep state
-.Ed
-.Sh TABLES
-Tables are named structures which can hold a collection of addresses and
-networks.
-Lookups against tables in
-.Xr pf 4
-are relatively fast, making a single rule with tables much more efficient,
-in terms of
-processor usage and memory consumption, than a large number of rules which
-differ only in IP address (either created explicitly or automatically by rule
-expansion).
-.Pp
-Tables can be used as the source or destination of filter rules,
-.Ar scrub
-rules
-or
-translation rules such as
-.Ar nat
-or
-.Ar rdr
-(see below for details on the various rule types).
-Tables can also be used for the redirect address of
-.Ar nat
-and
-.Ar rdr
-rules and in the routing options of filter rules, but only for
-.Ar round-robin
-pools.
-.Pp
-Tables can be defined with any of the following
-.Xr pfctl 8
-mechanisms.
-As with macros, reserved words may not be used as table names.
-.Bl -tag -width "manually"
-.It Ar manually
-Persistent tables can be manually created with the
-.Ar add
-or
-.Ar replace
-option of
-.Xr pfctl 8 ,
-before or after the ruleset has been loaded.
-.It Pa pf.conf
-Table definitions can be placed directly in this file, and loaded at the
-same time as other rules are loaded, atomically.
-Table definitions inside
-.Nm pf.conf
-use the
-.Ar table
-statement, and are especially useful to define non-persistent tables.
-The contents of a pre-existing table defined without a list of addresses
-to initialize it is not altered when
-.Nm pf.conf
-is loaded.
-A table initialized with the empty list,
-.Li { } ,
-will be cleared on load.
-.El
-.Pp
-Tables may be defined with the following two attributes:
-.Bl -tag -width persist
-.It Ar persist
-The
-.Ar persist
-flag forces the kernel to keep the table even when no rules refer to it.
-If the flag is not set, the kernel will automatically remove the table
-when the last rule referring to it is flushed.
-.It Ar const
-The
-.Ar const
-flag prevents the user from altering the contents of the table once it
-has been created.
-Without that flag,
-.Xr pfctl 8
-can be used to add or remove addresses from the table at any time, even
-when running with
-.Xr securelevel 7
-= 2.
-.El
-.Pp
-For example,
-.Bd -literal -offset indent
-table <private> const { 10/8, 172.16/12, 192.168/16 }
-table <badhosts> persist
-block on fxp0 from { <private>, <badhosts> } to any
-.Ed
-.Pp
-creates a table called private, to hold RFC 1918 private network
-blocks, and a table called badhosts, which is initially empty.
-A filter rule is set up to block all traffic coming from addresses listed in
-either table.
-The private table cannot have its contents changed and the badhosts table
-will exist even when no active filter rules reference it.
-Addresses may later be added to the badhosts table, so that traffic from
-these hosts can be blocked by using
-.Bd -literal -offset indent
-# pfctl -t badhosts -Tadd 204.92.77.111
-.Ed
-.Pp
-A table can also be initialized with an address list specified in one or more
-external files, using the following syntax:
-.Bd -literal -offset indent
-table <spam> persist file \&"/etc/spammers\&" file \&"/etc/openrelays\&"
-block on fxp0 from <spam> to any
-.Ed
-.Pp
-The files
-.Pa /etc/spammers
-and
-.Pa /etc/openrelays
-list IP addresses, one per line.
-Any lines beginning with a # are treated as comments and ignored.
-In addition to being specified by IP address, hosts may also be
-specified by their hostname.
-When the resolver is called to add a hostname to a table,
-.Em all
-resulting IPv4 and IPv6 addresses are placed into the table.
-IP addresses can also be entered in a table by specifying a valid interface
-name or the
-.Em self
-keyword, in which case all addresses assigned to the interface(s) will be
-added to the table.
-.Sh OPTIONS
-.Xr pf 4
-may be tuned for various situations using the
-.Ar set
-command.
-.Bl -tag -width xxxx
-.It Ar set timeout
-.Pp
-.Bl -tag -width interval -compact
-.It Ar interval
-Interval between purging expired states and fragments.
-.It Ar frag
-Seconds before an unassembled fragment is expired.
-.It Ar src.track
-Length of time to retain a source tracking entry after the last state
-expires.
-.El
-.Pp
-When a packet matches a stateful connection, the seconds to live for the
-connection will be updated to that of the
-.Ar proto.modifier
-which corresponds to the connection state.
-Each packet which matches this state will reset the TTL.
-Tuning these values may improve the performance of the
-firewall at the risk of dropping valid idle connections.
-.Pp
-.Bl -tag -width xxxx -compact
-.It Ar tcp.first
-The state after the first packet.
-.It Ar tcp.opening
-The state before the destination host ever sends a packet.
-.It Ar tcp.established
-The fully established state.
-.It Ar tcp.closing
-The state after the first FIN has been sent.
-.It Ar tcp.finwait
-The state after both FINs have been exchanged and the connection is closed.
-Some hosts (notably web servers on Solaris) send TCP packets even after closing
-the connection.
-Increasing
-.Ar tcp.finwait
-(and possibly
-.Ar tcp.closing )
-can prevent blocking of such packets.
-.It Ar tcp.closed
-The state after one endpoint sends an RST.
-.El
-.Pp
-ICMP and UDP are handled in a fashion similar to TCP, but with a much more
-limited set of states:
-.Pp
-.Bl -tag -width xxxx -compact
-.It Ar udp.first
-The state after the first packet.
-.It Ar udp.single
-The state if the source host sends more than one packet but the destination
-host has never sent one back.
-.It Ar udp.multiple
-The state if both hosts have sent packets.
-.It Ar icmp.first
-The state after the first packet.
-.It Ar icmp.error
-The state after an ICMP error came back in response to an ICMP packet.
-.El
-.Pp
-Other protocols are handled similarly to UDP:
-.Pp
-.Bl -tag -width xxxx -compact
-.It Ar other.first
-.It Ar other.single
-.It Ar other.multiple
-.El
-.Pp
-Timeout values can be reduced adaptively as the number of state table
-entries grows.
-.Pp
-.Bl -tag -width xxxx -compact
-.It Ar adaptive.start
-When the number of state entries exceeds this value, adaptive scaling
-begins.
-All timeout values are scaled linearly with factor
-(adaptive.end - number of states) / (adaptive.end - adaptive.start).
-.It Ar adaptive.end
-When reaching this number of state entries, all timeout values become
-zero, effectively purging all state entries immediately.
-This value is used to define the scale factor, it should not actually
-be reached (set a lower state limit, see below).
-.El
-.Pp
-These values can be defined both globally and for each rule.
-When used on a per-rule basis, the values relate to the number of
-states created by the rule, otherwise to the total number of
-states.
-.Pp
-For example:
-.Bd -literal -offset indent
-set timeout tcp.first 120
-set timeout tcp.established 86400
-set timeout { adaptive.start 6000, adaptive.end 12000 }
-set limit states 10000
-.Ed
-.Pp
-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.
-These statistics can be viewed using
-.Bd -literal -offset indent
-# pfctl -s info
-.Ed
-.Pp
-In this example
-.Xr pf 4
-collects statistics on the interface named dc0:
-.Bd -literal -offset indent
-set loginterface dc0
-.Ed
-.Pp
-One can disable the loginterface using:
-.Bd -literal -offset indent
-set loginterface none
-.Ed
-.Pp
-.It Ar set limit
-Sets hard limits on the memory pools used by the packet filter.
-See
-.Xr pool 9
-for an explanation of memory pools.
-.Pp
-For example,
-.Bd -literal -offset indent
-set limit states 20000
-.Ed
-.Pp
-sets the maximum number of entries in the memory pool used by state table
-entries (generated by
-.Ar keep state
-rules) to 20000.
-Using
-.Bd -literal -offset indent
-set limit frags 20000
-.Ed
-.Pp
-sets the maximum number of entries in the memory pool used for fragment
-reassembly (generated by
-.Ar scrub
-rules) to 20000.
-Finally,
-.Bd -literal -offset indent
-set limit src-nodes 2000
-.Ed
-.Pp
-sets the maximum number of entries in the memory pool used for tracking
-source IP addresses (generated by the
-.Ar sticky-address
-and
-.Ar source-track
-options) to 2000.
-.Pp
-These can be combined:
-.Bd -literal -offset indent
-set limit { states 20000, frags 20000, src-nodes 2000 }
-.Ed
-.Pp
-.It Ar set optimization
-Optimize the engine for one of the following network environments:
-.Pp
-.Bl -tag -width xxxx -compact
-.It Ar normal
-A normal network environment.
-Suitable for almost all networks.
-.It Ar high-latency
-A high-latency environment (such as a satellite connection).
-.It Ar satellite
-Alias for
-.Ar high-latency .
-.It Ar aggressive
-Aggressively expire connections.
-This can greatly reduce the memory usage of the firewall at the cost of
-dropping idle connections early.
-.It Ar conservative
-Extremely conservative settings.
-Avoid dropping legitimate connections at the
-expense of greater memory utilization (possibly much greater on a busy
-network) and slightly increased processor utilization.
-.El
-.Pp
-For example:
-.Bd -literal -offset indent
-set optimization aggressive
-.Ed
-.Pp
-.It Ar set block-policy
-The
-.Ar block-policy
-option sets the default behaviour for the packet
-.Ar block
-action:
-.Pp
-.Bl -tag -width xxxxxxxx -compact
-.It Ar drop
-Packet is silently dropped.
-.It Ar return
-A TCP RST is returned for blocked TCP packets,
-an ICMP UNREACHABLE is returned for blocked UDP packets,
-and all other packets are silently dropped.
-.El
-.Pp
-For example:
-.Bd -literal -offset indent
-set block-policy return
-.Ed
-.It Ar set state-policy
-The
-.Ar state-policy
-option sets the default behaviour for states:
-.Pp
-.Bl -tag -width group-bound -compact
-.It Ar if-bound
-States are bound to interface.
-.It Ar group-bound
-States are bound to interface group (i.e. ppp)
-.It Ar floating
-States can match packets on any interfaces (the default).
-.El
-.Pp
-For example:
-.Bd -literal -offset indent
-set state-policy if-bound
-.Ed
-.It Ar set require-order
-By default
-.Xr pfctl 8
-enforces an ordering of the statement types in the ruleset to:
-.Em options ,
-.Em normalization ,
-.Em queueing ,
-.Em translation ,
-.Em filtering .
-Setting this option to
-.Ar no
-disables this enforcement.
-There may be non-trivial and non-obvious implications to an out of
-order ruleset.
-Consider carefully before disabling the order enforcement.
-.It Ar set fingerprints
-Load fingerprints of known operating systems from the given filename.
-By default fingerprints of known operating systems are automatically
-loaded from
-.Xr pf.os 5
-in
-.Pa /etc
-but can be overridden via this option.
-Setting this option may leave a small period of time where the fingerprints
-referenced by the currently active ruleset are inconsistent until the new
-ruleset finishes loading.
-.Pp
-For example:
-.Pp
-.Dl set fingerprints \&"/etc/pf.os.devel\&"
-.Pp
-.It Ar set debug
-Set the debug
-.Ar level
-to one of the following:
-.Pp
-.Bl -tag -width xxxxxxxxxxxx -compact
-.It Ar none
-Don't generate debug messages.
-.It Ar urgent
-Generate debug messages only for serious errors.
-.It Ar misc
-Generate debug messages for various errors.
-.It Ar loud
-Generate debug messages for common conditions.
-.El
-.El
-.Sh TRAFFIC NORMALIZATION
-Traffic normalization is used to sanitize packet content in such
-a way that there are no ambiguities in packet interpretation on
-the receiving side.
-The normalizer does IP fragment reassembly to prevent attacks
-that confuse intrusion detection systems by sending overlapping
-IP fragments.
-Packet normalization is invoked with the
-.Ar scrub
-directive.
-.Pp
-.Ar scrub
-has the following options:
-.Bl -tag -width xxxx
-.It Ar no-df
-Clears the
-.Ar dont-fragment
-bit from a matching IP packet.
-Some operating systems are known to generate fragmented packets with the
-.Ar dont-fragment
-bit set.
-This is particularly true with NFS.
-.Ar Scrub
-will drop such fragmented
-.Ar dont-fragment
-packets unless
-.Ar no-df
-is specified.
-.Pp
-Unfortunately some operating systems also generate their
-.Ar dont-fragment
-packets with a zero IP identification field.
-Clearing the
-.Ar dont-fragment
-bit on packets with a zero IP ID may cause deleterious results if an
-upstream router later fragments the packet.
-Using the
-.Ar random-id
-modifier (see below) is recommended in combination with the
-.Ar no-df
-modifier to ensure unique IP identifiers.
-.It Ar min-ttl <number>
-Enforces a minimum TTL for matching IP packets.
-.It Ar max-mss <number>
-Enforces a maximum MSS for matching TCP packets.
-.It Ar random-id
-Replaces the IP identification field with random values to compensate
-for predictable values generated by many hosts.
-This option only applies to outgoing packets that are not fragmented
-after the optional fragment reassembly.
-.It Ar fragment reassemble
-Using
-.Ar scrub
-rules, fragments can be reassembled by normalization.
-In this case, fragments are buffered until they form a complete
-packet, and only the completed packet is passed on to the filter.
-The advantage is that filter rules have to deal only with complete
-packets, and can ignore fragments.
-The drawback of caching fragments is the additional memory cost.
-But the full reassembly method is the only method that currently works
-with NAT.
-This is the default behavior of a
-.Ar scrub
-rule if no fragmentation modifier is supplied.
-.It Ar fragment crop
-The default fragment reassembly method is expensive, hence the option
-to crop is provided.
-In this case,
-.Xr pf 4
-will track the fragments and cache a small range descriptor.
-Duplicate fragments are dropped and overlaps are cropped.
-Thus data will only occur once on the wire with ambiguities resolving to
-the first occurrence.
-Unlike the
-.Ar fragment reassemble
-modifier, fragments are not buffered, they are passed as soon as they
-are received.
-The
-.Ar fragment crop
-reassembly mechanism does not yet work with NAT.
-.Pp
-.It Ar fragment drop-ovl
-This option is similar to the
-.Ar fragment crop
-modifier except that all overlapping or duplicate fragments will be
-dropped, and all further corresponding fragments will be
-dropped as well.
-.It Ar reassemble tcp
-Statefully normalizes TCP connections.
-.Ar scrub reassemble tcp
-rules may not have the direction (in/out) specified.
-.Ar reassemble tcp
-performs the following normalizations:
-.Pp
-.Bl -tag -width timeout -compact
-.It ttl
-Neither side of the connection is allowed to reduce their IP TTL.
-An attacker may send a packet such that it reaches the firewall, affects
-the firewall state, and expires before reaching the destination host.
-.Ar reassemble tcp
-will raise the TTL of all packets back up to the highest value seen on
-the connection.
-.It timeout modulation
-Modern TCP stacks will send a timestamp on every TCP packet and echo
-the other endpoint's timestamp back to them.
-Many operating systems will merely start the timestamp at zero when
-first booted, and increment it several times a second.
-The uptime of the host can be deduced by reading the timestamp and multiplying
-by a constant.
-Also observing several different timestamps can be used to count hosts
-behind a NAT device.
-And spoofing TCP packets into a connection requires knowing or guessing
-valid timestamps.
-Timestamps merely need to be monotonically increasing and not derived off a
-guessable base time.
-.Ar reassemble tcp
-will cause
-.Ar scrub
-to modulate the TCP timestamps with a random number.
-.El
-.El
-.Pp
-For example,
-.Bd -literal -offset indent
-scrub in on $ext_if all fragment reassemble
-.Ed
-.Sh QUEUEING
-Packets can be assigned to queues for the purpose of bandwidth
-control.
-At least two declarations are required to configure queues, and later
-any packet filtering rule can reference the defined queues by name.
-During the filtering component of
-.Nm pf.conf ,
-the last referenced
-.Ar queue
-name is where any packets from
-.Ar pass
-rules will be queued, while for
-.Ar block
-rules it specifies where any resulting ICMP or TCP RST
-packets should be queued.
-The
-.Ar scheduler
-defines the algorithm used to decide which packets get delayed, dropped, or
-sent out immediately.
-There are three
-.Ar schedulers
-currently supported.
-.Bl -tag -width xxxx
-.It Ar cbq
-Class Based Queueing.
-.Ar Queues
-attached to an interface build a tree, thus each
-.Ar queue
-can have further child
-.Ar queues .
-Each queue can have a
-.Ar priority
-and a
-.Ar bandwidth
-assigned.
-.Ar Priority
-mainly controls the time packets take to get sent out, while
-.Ar bandwidth
-has primarily effects on throughput.
-.It Ar priq
-Priority Queueing.
-.Ar Queues
-are flat attached to the interface, thus,
-.Ar queues
-cannot have further child
-.Ar queues .
-Each
-.Ar queue
-has a unique
-.Ar priority
-assigned, ranging from 0 to 15.
-Packets in the
-.Ar queue
-with the highest
-.Ar priority
-are processed first.
-.It Ar hfsc
-Hierarchical Fair Service Curve.
-.Ar Queues
-attached to an interface build a tree, thus each
-.Ar queue
-can have further child
-.Ar queues .
-Each queue can have a
-.Ar priority
-and a
-.Ar bandwidth
-assigned.
-.Ar Priority
-mainly controls the time packets take to get sent out, while
-.Ar bandwidth
-has primarily effects on throughput.
-.El
-.Pp
-The interfaces on which queueing should be activated are declared using
-the
-.Ar altq on
-declaration.
-.Ar altq on
-has the following keywords:
-.Bl -tag -width xxxx
-.It Ar <interface>
-Queueing is enabled on the named interface.
-.It Ar <scheduler>
-Specifies which queueing scheduler to use.
-Currently supported values
-are
-.Ar cbq
-for Class Based Queueing,
-.Ar priq
-for Priority Queueing and
-.Ar hfsc
-for the Hierarchical Fair Service Curve scheduler.
-.It Ar bandwidth <bw>
-The maximum bitrate for all queues on an
-interface may be specified using the
-.Ar bandwidth
-keyword.
-The value can be specified as an absolute value or as a
-percentage of the interface bandwidth.
-When using an absolute value, the suffixes
-.Ar b ,
-.Ar Kb ,
-.Ar Mb ,
-and
-.Ar Gb
-are used to represent bits, kilobits, megabits, and
-gigabits per second, respectively.
-The value must not exceed the interface bandwidth.
-If
-.Ar bandwidth
-is not specified, the interface bandwidth is used.
-.It Ar qlimit <limit>
-The maximum number of packets held in the queue.
-The default is 50.
-.It Ar tbrsize <size>
-Adjusts the size, in bytes, of the token bucket regulator.
-If not specified, heuristics based on the
-interface bandwidth are used to determine the size.
-.It Ar queue <list>
-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
-Class Based Queueing.
-Those four queues will be shown in a later example.
-.Bd -literal -offset indent
-altq on dc0 cbq bandwidth 5Mb queue { std, http, mail, ssh }
-.Ed
-.Pp
-Once interfaces are activated for queueing using the
-.Ar altq
-directive, a sequence of
-.Ar queue
-directives may be defined.
-The name associated with a
-.Ar queue
-must match a queue defined in the
-.Ar altq
-directive (e.g. mail), or, except for the
-.Ar priq
-.Ar scheduler ,
-in a parent
-.Ar queue
-declaration.
-The following keywords can be used:
-.Bl -tag -width xxxx
-.It Ar on <interface>
-Specifies the interface the queue operates on.
-If not given, it operates on all matching interfaces.
-.It Ar bandwidth <bw>
-Specifies the maximum bitrate to be processed by the queue.
-This value must not exceed the value of the parent
-.Ar queue
-and can be specified as an absolute value or a percentage of the parent
-queue's bandwidth.
-The
-.Ar priq
-scheduler does not support bandwidth specification.
-.It Ar priority <level>
-Between queues a priority level can be set.
-For
-.Ar cbq
-and
-.Ar hfsc ,
-the range is 0 to 7 and for
-.Ar priq ,
-the range is 0 to 15.
-The default for all is 1.
-.Ar Priq
-queues with a higher priority are always served first.
-.Ar Cbq
-and
-.Ar Hfsc
-queues with a higher priority are preferred in the case of overload.
-.It Ar qlimit <limit>
-The maximum number of packets held in the queue.
-The default is 50.
-.El
-.Pp
-The
-.Ar scheduler
-can get additional parameters with
-.Ar <scheduler> Ns Li (\& Ar <parameters> No ) .
-Parameters are as follows:
-.Bl -tag -width Fl
-.It Ar default
-Packets not matched by another queue are assigned to this one.
-Exactly one default queue is required.
-.It Ar red
-Enable RED (Random Early Detection) on this queue.
-RED drops packets with a probability proportional to the average
-queue length.
-.It Ar rio
-Enables RIO on this queue.
-RIO is RED with IN/OUT, thus running
-RED two times more than RIO would achieve the same effect.
-RIO is currently not supported in the GENERIC kernel.
-.It Ar ecn
-Enables ECN (Explicit Congestion Notification) on this queue.
-ECN implies RED.
-.El
-.Pp
-The
-.Ar cbq
-.Ar scheduler
-supports an additional option:
-.Bl -tag -width Fl
-.It Ar borrow
-The queue can borrow bandwidth from the parent.
-.El
-.Pp
-The
-.Ar hfsc
-.Ar scheduler
-supports some additional options:
-.Bl -tag -width Fl
-.It Ar realtime <sc>
-The minimum required bandwidth for the queue.
-.It Ar upperlimit <sc>
-The maximum allowed bandwidth for the queue.
-.It Ar linkshare <sc>
-The bandwidth share of a backlogged queue.
-.El
-.Pp
-<sc> is an acronym for
-.Ar service curve .
-.Pp
-The format for service curve specifications is
-.Ar ( m1 , d , m2 ) .
-.Ar m2
-controls the bandwidth assigned to the queue.
-.Ar m1
-and
-.Ar d
-are optional and can be used to control the initial bandwidth assignment.
-For the first
-.Ar d
-milliseconds the queue gets the bandwidth given as
-.Ar m1 ,
-afterwards the value given in
-.Ar m2 .
-.Pp
-Furthermore, with
-.Ar cbq
-and
-.Ar hfsc ,
-child queues can be specified as in an
-.Ar altq
-declaration, thus building a tree of queues using a part of
-their parent's bandwidth.
-.Pp
-Packets can be assigned to queues based on filter rules by using the
-.Ar queue
-keyword.
-Normally only one
-.Ar queue
-is specified; when a second one is specified it will instead be used for
-packets which have a
-.Em TOS
-of
-.Em lowdelay
-and for TCP ACKs with no data payload.
-.Pp
-To continue the previous example, the examples below would specify the
-four referenced
-queues, plus a few child queues.
-Interactive
-.Xr ssh 1
-sessions get priority over bulk transfers like
-.Xr scp 1
-and
-.Xr sftp 1 .
-The queues may then be referenced by filtering rules (see
-.Sx PACKET FILTERING
-below).
-.Bd -literal
-queue std bandwidth 10% cbq(default)
-queue http bandwidth 60% priority 2 cbq(borrow red) \e
- { employees, developers }
-queue developers bandwidth 75% cbq(borrow)
-queue employees bandwidth 15%
-queue mail bandwidth 10% priority 0 cbq(borrow ecn)
-queue ssh bandwidth 20% cbq(borrow) { ssh_interactive, ssh_bulk }
-queue ssh_interactive priority 7
-queue ssh_bulk priority 0
-
-block return out on dc0 inet all queue std
-pass out on dc0 inet proto tcp from $developerhosts to any port 80 \e
- keep state queue developers
-pass out on dc0 inet proto tcp from $employeehosts to any port 80 \e
- keep state queue employees
-pass out on dc0 inet proto tcp from any to any port 22 \e
- keep state queue(ssh_bulk, ssh_interactive)
-pass out on dc0 inet proto tcp from any to any port 25 \e
- keep state queue mail
-.Ed
-.Sh TRANSLATION
-Translation rules modify either the source or destination address of the
-packets associated with a stateful connection.
-A stateful connection is automatically created to track packets matching
-such a rule as long as they are not blocked by the filtering section of
-.Nm pf.conf .
-The translation engine modifies the specified address and/or port in the
-packet, recalculates IP, TCP and UDP checksums as necessary, and passes it to
-the packet filter for evaluation.
-.Pp
-Since translation occurs before filtering the filter
-engine will see packets as they look after any
-addresses and ports have been translated. Filter rules
-will therefore have to filter based on the translated
-address and port number.
-Packets that match a translation rule are only automatically passed if
-the
-.Ar pass
-modifier is given, otherwise they are
-still subject to
-.Ar block
-and
-.Ar pass
-rules.
-.Pp
-The state entry created permits
-.Xr pf 4
-to keep track of the original address for traffic associated with that state
-and correctly direct return traffic for that connection.
-.Pp
-Various types of translation are possible with pf:
-.Bl -tag -width xxxx
-.It Ar binat
-A
-.Ar binat
-rule specifies a bidirectional mapping between an external IP netblock
-and an internal IP netblock.
-.It Ar nat
-A
-.Ar nat
-rule specifies that IP addresses are to be changed as the packet
-traverses the given interface.
-This technique allows one or more IP addresses
-on the translating host to support network traffic for a larger range of
-machines on an "inside" network.
-Although in theory any IP address can be used on the inside, it is strongly
-recommended that one of the address ranges defined by RFC 1918 be used.
-These netblocks are:
-.Bd -literal
-10.0.0.0 - 10.255.255.255 (all of net 10, i.e., 10/8)
-172.16.0.0 - 172.31.255.255 (i.e., 172.16/12)
-192.168.0.0 - 192.168.255.255 (i.e., 192.168/16)
-.Ed
-.It Pa rdr
-The packet is redirected to another destination and possibly a
-different port.
-.Ar rdr
-rules can optionally specify port ranges instead of single ports.
-rdr ... port 2000:2999 -> ... port 4000
-redirects ports 2000 to 2999 (inclusive) to port 4000.
-rdr ... port 2000:2999 -> ... port 4000:*
-redirects port 2000 to 4000, 2001 to 4001, ..., 2999 to 4999.
-.El
-.Pp
-In addition to modifying the address, some translation rules may modify
-source or destination ports for
-.Xr tcp 4
-or
-.Xr udp 4
-connections; implicitly in the case of
-.Ar nat
-rules and explicitly in the case of
-.Ar rdr
-rules.
-Port numbers are never translated with a
-.Ar binat
-rule.
-.Pp
-For each packet processed by the translator, the translation rules are
-evaluated in sequential order, from first to last.
-The first matching rule decides what action is taken.
-.Pp
-The
-.Ar no
-option prefixed to a translation rule causes packets to remain untranslated,
-much in the same way as
-.Ar drop quick
-works in the packet filter (see below).
-If no rule matches the packet it is passed to the filter engine unmodified.
-.Pp
-Translation rules apply only to packets that pass through
-the specified interface, and if no interface is specified,
-translation is applied to packets on all interfaces.
-For instance, redirecting port 80 on an external interface to an internal
-web server will only work for connections originating from the outside.
-Connections to the address of the external interface from local hosts will
-not be redirected, since such packets do not actually pass through the
-external interface.
-Redirections cannot reflect packets back through the interface they arrive
-on, they can only be redirected to hosts connected to different interfaces
-or to the firewall itself.
-.Pp
-Note that redirecting external incoming connections to the loopback
-address, as in
-.Bd -literal -offset indent
-rdr on ne3 inet proto tcp to port 8025 -> 127.0.0.1 port 25
-.Ed
-.Pp
-will effectively allow an external host to connect to daemons
-bound solely to the loopback address, circumventing the traditional
-blocking of such connections on a real interface.
-Unless this effect is desired, any of the local non-loopback addresses
-should be used as redirection target instead, which allows external
-connections only to daemons bound to this address or not bound to
-any address.
-.Pp
-See
-.Sx TRANSLATION EXAMPLES
-below.
-.Sh PACKET FILTERING
-.Xr pf 4
-has the ability to
-.Ar block
-and
-.Ar pass
-packets based on attributes of their layer 3 (see
-.Xr ip 4
-and
-.Xr ip6 4 )
-and layer 4 (see
-.Xr icmp 4 ,
-.Xr icmp6 4 ,
-.Xr tcp 4 ,
-.Xr udp 4 )
-headers.
-In addition, packets may also be
-assigned to queues for the purpose of bandwidth control.
-.Pp
-For each packet processed by the packet filter, the filter rules are
-evaluated in sequential order, from first to last.
-The last matching rule decides what action is taken.
-.Pp
-The following actions can be used in the filter:
-.Bl -tag -width xxxx
-.It Ar block
-The packet is blocked.
-There are a number of ways in which a
-.Ar block
-rule can behave when blocking a packet.
-The default behaviour is to
-.Ar drop
-packets silently, however this can be overridden or made
-explicit either globally, by setting the
-.Ar block-policy
-option, or on a per-rule basis with one of the following options:
-.Pp
-.Bl -tag -width xxxx -compact
-.It Ar drop
-The packet is silently dropped.
-.It Ar return-rst
-This applies only to
-.Xr tcp 4
-packets, and issues a TCP RST which closes the
-connection.
-.It Ar return-icmp
-.It Ar return-icmp6
-This causes ICMP messages to be returned for packets which match the rule.
-By default this is an ICMP UNREACHABLE message, however this
-can be overridden by specifying a message as a code or number.
-.It Ar return
-This causes a TCP RST to be returned for
-.Xr tcp 4
-packets and an ICMP UNREACHABLE for UDP and other packets.
-.El
-.Pp
-Options returning packets have no effect if
-.Xr pf 4
-operates on a
-.Xr bridge 4 .
-.It Ar pass
-The packet is passed.
-.El
-.Pp
-If no rule matches the packet, the default action is
-.Ar pass .
-.Pp
-To block everything by default and only pass packets
-that match explicit rules, one uses
-.Bd -literal -offset indent
-block all
-.Ed
-.Pp
-as the first filter rule.
-.Pp
-See
-.Sx FILTER EXAMPLES
-below.
-.Sh PARAMETERS
-The rule parameters specify the packets to which a rule applies.
-A packet always comes in on, or goes out through, one interface.
-Most parameters are optional.
-If a parameter is specified, the rule only applies to packets with
-matching attributes.
-Certain parameters can be expressed as lists, in which case
-.Xr pfctl 8
-generates all needed rule combinations.
-.Bl -tag -width xxxx
-.It Ar in No or Ar out
-This rule applies to incoming or outgoing packets.
-If neither
-.Ar in
-nor
-.Ar out
-are specified, the rule will match packets in both directions.
-.It Ar log
-In addition to the action specified, a log message is generated.
-All packets for that connection are logged, unless the
-.Ar keep state ,
-.Ar modulate state
-or
-.Ar synproxy state
-options are specified, in which case only the
-packet that establishes the state is logged.
-(See
-.Ar keep state ,
-.Ar modulate state
-and
-.Ar synproxy state
-below).
-The logged packets are sent to the
-.Xr pflog 4
-interface.
-This interface is monitored by the
-.Xr pflogd 8
-logging daemon, which dumps the logged packets to the file
-.Pa /var/log/pflog
-in
-.Xr pcap 3
-binary format.
-.It Ar log-all
-Used with
-.Ar keep state ,
-.Ar modulate state
-or
-.Ar synproxy state
-rules to force logging of all packets for a connection.
-As with
-.Ar log ,
-packets are logged to
-.Xr pflog 4 .
-.It Ar quick
-If a packet matches a rule which has the
-.Ar quick
-option set, this rule
-is considered the last matching rule, and evaluation of subsequent rules
-is skipped.
-.It Ar on <interface>
-This rule applies only to packets coming in on, or going out through, this
-particular interface.
-It is also possible to simply give the interface driver name, like ppp or fxp,
-to make the rule match packets flowing through a group of interfaces.
-.It Ar <af>
-This rule applies only to packets of this address family.
-Supported values are
-.Ar inet
-and
-.Ar inet6 .
-.It Ar proto <protocol>
-This rule applies only to packets of this protocol.
-Common protocols are
-.Xr icmp 4 ,
-.Xr icmp6 4 ,
-.Xr tcp 4 ,
-and
-.Xr udp 4 .
-For a list of all the protocol name to number mappings used by
-.Xr pfctl 8 ,
-see the file
-.Em /etc/protocols .
-.It Xo
-.Ar from <source> port <source> os <source>
-.Ar to <dest> port <dest>
-.Xc
-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:
-.Pp
-.Bl -tag -width xxxxxxxxxxxx -compact
-.It Ar any
-Any address.
-.It Ar no-route
-Any address which is not currently routable.
-.It Ar <table>
-Any address that matches the given table.
-.El
-.Pp
-Interface names can have modifiers appended:
-.Pp
-.Bl -tag -width xxxxxxxxxxxx -compact
-.It Ar :network
-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).
-.It Ar :0
-Do not include interface aliases.
-.El
-.Pp
-Host names may also have the
-.Ar :0
-option appended to restrict the name resolution to the first of each
-v4 and v6 address found.
-.Pp
-Host name resolution and interface to address translation are done at
-ruleset load-time.
-When the address of an interface (or host name) changes (under DHCP or PPP,
-for instance), the ruleset must be reloaded for the change to be reflected
-in the kernel.
-Surrounding the interface name (and optional modifiers) in parentheses
-changes this behaviour.
-When the interface name is surrounded by parentheses, the rule is
-automatically updated whenever the interface changes its address.
-The ruleset does not need to be reloaded.
-This is especially useful with
-.Ar nat .
-.Pp
-Ports can be specified either by number or by name.
-For example, port 80 can be specified as
-.Em www .
-For a list of all port name to number mappings used by
-.Xr pfctl 8 ,
-see the file
-.Pa /etc/services .
-.Pp
-Ports and ranges of ports are specified by using these operators:
-.Bd -literal -offset indent
-= (equal)
-!= (unequal)
-< (less than)
-<= (less than or equal)
-> (greater than)
->= (greater than or equal)
-: (range including boundaries)
->< (range excluding boundaries)
-<> (except range)
-.Ed
-.Pp
-><, <> and :
-are binary operators (they take two arguments).
-For instance:
-.Bl -tag -width Fl
-.It Ar port 2000:2004
-means
-.Sq all ports >= 2000 and <= 2004 ,
-hence ports 2000, 2001, 2002, 2003 and 2004.
-.It Ar port 2000 >< 2004
-means
-.Sq all ports > 2000 and < 2004 ,
-hence ports 2001, 2002 and 2003.
-.It Ar port 2000 <> 2004
-means
-.Sq all ports < 2000 or > 2004 ,
-hence ports 1-1999 and 2005-65535.
-.El
-.Pp
-The operating system of the source host can be specified in the case of TCP
-rules with the
-.Ar OS
-modifier.
-See the
-.Sx OPERATING SYSTEM FINGERPRINTING
-section for more information.
-.Pp
-The host, port and OS specifications are optional, as in the following examples:
-.Bd -literal -offset indent
-pass in all
-pass in from any to any
-pass in proto tcp from any port <= 1024 to any
-pass in proto tcp from any to any port 25
-pass in proto tcp from 10.0.0.0/8 port > 1024 \e
- to ! 10.1.2.3 port != ssh
-pass in proto tcp from any os "OpenBSD" flags S/SA
-.Ed
-.It Ar all
-This is equivalent to "from any to any".
-.It Ar group <group>
-Similar to
-.Ar user ,
-this rule only applies to packets of sockets owned by the specified group.
-.It Ar user <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
-that opened the connection.
-For incoming connections to the firewall itself, this is the user that
-listens on the destination port.
-For forwarded connections, where the firewall is not a connection endpoint,
-the user and group are
-.Em unknown .
-.Pp
-All packets, both outgoing and incoming, of one connection are associated
-with the same user and group.
-Only TCP and UDP packets can be associated with users; for other protocols
-these parameters are ignored.
-.Pp
-User and group refer to the effective (as opposed to the real) IDs, in
-case the socket is created by a setuid/setgid process.
-User and group IDs are stored when a socket is created;
-when a process creates a listening socket as root (for instance, by
-binding to a privileged port) and subsequently changes to another
-user ID (to drop privileges), the credentials will remain root.
-.Pp
-User and group IDs can be specified as either numbers or names.
-The syntax is similar to the one for ports.
-The value
-.Em unknown
-matches packets of forwarded connections.
-.Em unknown
-can only be used with the operators
-.Cm =
-and
-.Cm != .
-Other constructs like
-.Cm user >= unknown
-are invalid.
-Forwarded packets with unknown user and group ID match only rules
-that explicitly compare against
-.Em unknown
-with the operators
-.Cm =
-or
-.Cm != .
-For instance
-.Cm user >= 0
-does not match forwarded packets.
-The following example allows only selected users to open outgoing
-connections:
-.Bd -literal -offset indent
-block out proto { tcp, udp } all
-pass out proto { tcp, udp } all \e
- user { < 1000, dhartmei } keep state
-.Ed
-.It Ar flags <a>/<b> | /<b>
-This rule only applies to TCP packets that have the flags
-.Ar <a>
-set out of set
-.Ar <b> .
-Flags not specified in
-.Ar <b>
-are ignored.
-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
-.It Ar flags S/S
-Flag SYN is set.
-The other flags are ignored.
-.It Ar flags S/SA
-Out of SYN and ACK, exactly SYN may be set.
-SYN, SYN+PSH and SYN+RST match, but SYN+ACK, ACK and ACK+RST do not.
-This is more restrictive than the previous example.
-.It Ar flags /SFRA
-If the first set is not specified, it defaults to none.
-All of SYN, FIN, RST and ACK must be unset.
-.El
-.It Ar icmp-type <type> code <code>
-.It Ar icmp6-type <type> code <code>
-This rule only applies to ICMP or ICMPv6 packets with the specified type
-and code.
-This parameter is only valid for rules that cover protocols ICMP or
-ICMP6.
-The protocol and the ICMP type indicator (icmp-type or icmp6-type)
-must match.
-.It Ar allow-opts
-By default, packets which contain IP options are blocked.
-When
-.Ar allow-opts
-is specified for a
-.Ar pass
-rule, packets that pass the filter based on that rule (last matching)
-do so even if they contain IP options.
-For packets that match state, the rule that initially created the
-state is used.
-The implicit
-.Ar pass
-rule that is used when a packet does not match any rules does not
-allow IP options.
-.It Ar label <string>
-Adds a label (name) to the rule, which can be used to identify the rule.
-For instance,
-pfctl -s labels
-shows per-rule statistics for rules that have labels.
-.Pp
-The following macros can be used in labels:
-.Pp
-.Bl -tag -width $srcaddr -compact -offset indent
-.It Ar $if
-The interface.
-.It Ar $srcaddr
-The source IP address.
-.It Ar $dstaddr
-The destination IP address.
-.It Ar $srcport
-The source port specification.
-.It Ar $dstport
-The destination port specification.
-.It Ar $proto
-The protocol name.
-.It Ar $nr
-The rule number.
-.El
-.Pp
-For example:
-.Bd -literal -offset indent
-ips = \&"{ 1.2.3.4, 1.2.3.5 }\&"
-pass in proto tcp from any to $ips \e
- port > 1023 label \&"$dstaddr:$dstport\&"
-.Ed
-.Pp
-expands to
-.Bd -literal -offset indent
-pass in inet proto tcp from any to 1.2.3.4 \e
- port > 1023 label \&"1.2.3.4:>1023\&"
-pass in inet proto tcp from any to 1.2.3.5 \e
- port > 1023 label \&"1.2.3.5:>1023\&"
-.Ed
-.Pp
-The macro expansion for the
-.Ar label
-directive occurs only at configuration file parse time, not during runtime.
-.It Ar queue <queue> | ( <queue> , <queue> )
-Packets matching this rule will be assigned to the specified queue.
-If two queues are given, packets which have a
-.Em tos
-of
-.Em lowdelay
-and TCP ACKs with no data payload will be assigned to the second one.
-See
-.Sx QUEUEING
-for setup details.
-.Pp
-For example:
-.Bd -literal -offset indent
-pass in proto tcp to port 25 queue mail
-pass in proto tcp to port 22 queue(ssh_bulk, ssh_prio)
-.Ed
-.It Ar tag <string>
-Packets matching this rule will be tagged with the
-specified string.
-The tag acts as an internal marker that can be used to
-identify these packets later on.
-This can be used, for example, to provide trust between
-interfaces and to determine if packets have been
-processed by translation rules.
-Tags are
-.Qq sticky ,
-meaning that the packet will be tagged even if the rule
-is not the last matching rule.
-Further matching rules can replace the tag with a
-new one but will not remove a previously applied tag.
-A packet is only ever assigned one tag at a time.
-.Ar pass
-rules that use the
-.Ar tag
-keyword must also use
-.Ar keep state ,
-.Ar modulate state
-or
-.Ar synproxy state .
-Packet tagging can be done during
-.Ar nat ,
-.Ar rdr ,
-or
-.Ar binat
-rules in addition to filter rules.
-Tags take the same macros as labels (see above).
-.It Ar tagged <string>
-Used with filter rules to specify that packets must already
-be tagged with the given tag in order to match the rule.
-Inverse tag matching can also be done
-by specifying the
-.Cm !\&
-operator before the
-.Ar tagged
-keyword.
-.El
-.Sh ROUTING
-If a packet matches a rule with a route option set, the packet filter will
-route the packet according to the type of route option.
-When such a rule creates state, the route option is also applied to all
-packets matching the same connection.
-.Bl -tag -width xxxx
-.It Ar fastroute
-The
-.Ar fastroute
-option does a normal route lookup to find the next hop for the packet.
-.It Ar route-to
-The
-.Ar route-to
-option routes the packet to the specified interface with an optional address
-for the next hop.
-When a
-.Ar route-to
-rule creates state, only packets that pass in the same direction as the
-filter rule specifies will be routed in this way.
-Packets passing in the opposite direction (replies) are not affected
-and are routed normally.
-.It Ar reply-to
-The
-.Ar reply-to
-option is similar to
-.Ar route-to ,
-but routes packets that pass in the opposite direction (replies) to the
-specified interface.
-Opposite direction is only defined in the context of a state entry, and
-.Ar route-to
-is useful only in rules that create state.
-It can be used on systems with multiple external connections to
-route all outgoing packets of a connection through the interface
-the incoming connection arrived through (symmetric routing enforcement).
-.It Ar dup-to
-The
-.Ar dup-to
-option creates a duplicate of the packet and routes it like
-.Ar route-to .
-The original packet gets routed as it normally would.
-.El
-.Sh POOL OPTIONS
-For
-.Ar nat
-and
-.Ar rdr
-rules, (as well as for the
-.Ar route-to ,
-.Ar reply-to
-and
-.Ar dup-to
-rule options) for which there is a single redirection address which has a
-subnet mask smaller than 32 for IPv4 or 128 for IPv6 (more than one IP
-address), a variety of different methods for assigning this address can be
-used:
-.Bl -tag -width xxxx
-.It Ar bitmask
-The
-.Ar bitmask
-option applies the network portion of the redirection address to the address
-to be modified (source with
-.Ar nat ,
-destination with
-.Ar rdr ) .
-.It Ar random
-The
-.Ar random
-option selects an address at random within the defined block of addresses.
-.It Ar source-hash
-The
-.Ar source-hash
-option uses a hash of the source address to determine the redirection address,
-ensuring that the redirection address is always the same for a given source.
-An optional key can be specified after this keyword either in hex or as a
-string; by default
-.Xr pfctl 8
-randomly generates a key for source-hash every time the
-ruleset is reloaded.
-.It Ar round-robin
-The
-.Ar round-robin
-option loops through the redirection address(es).
-.Pp
-When more than one redirection address is specified,
-.Ar round-robin
-is the only permitted pool type.
-.It Ar static-port
-With
-.Ar nat
-rules, the
-.Ar static-port
-option prevents
-.Xr pf 4
-from modifying the source port on TCP and UDP packets.
-.El
-.Pp
-Additionally, the
-.Ar sticky-address
-option can be specified to help ensure that multiple connections from the
-same source are mapped to the same redirection address.
-This option can be used with the
-.Ar random
-and
-.Ar round-robin
-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
-See
-.Sx STATEFUL TRACKING OPTIONS
-for more ways to control the source tracking.
-.Sh STATEFUL INSPECTION
-.Xr pf 4
-is a stateful packet filter, which means it can track the state of
-a connection.
-Instead of passing all traffic to port 25, for instance, it is possible
-to pass only the initial packet, and then begin to keep state.
-Subsequent traffic will flow because the filter is aware of the connection.
-.Pp
-If a packet matches a
-.Ar pass ... keep state
-rule, the filter creates a state for this connection and automatically
-lets pass all subsequent packets of that connection.
-.Pp
-Before any rules are evaluated, the filter checks whether the packet
-matches any state.
-If it does, the packet is passed without evaluation of any rules.
-.Pp
-States are removed after the connection is closed or has timed out.
-.Pp
-This has several advantages.
-Comparing a packet to a state involves checking its sequence numbers.
-If the sequence numbers are outside the narrow windows of expected
-values, the packet is dropped.
-This prevents spoofing attacks, such as when an attacker sends packets with
-a fake source address/port but does not know the connection's sequence
-numbers.
-.Pp
-Also, looking up states is usually faster than evaluating rules.
-If there are 50 rules, all of them are evaluated sequentially in O(n).
-Even with 50000 states, only 16 comparisons are needed to match a
-state, since states are stored in a binary search tree that allows
-searches in O(log2 n).
-.Pp
-For instance:
-.Bd -literal -offset indent
-block all
-pass out proto tcp from any to any flags S/SA keep state
-pass in proto tcp from any to any port 25 flags S/SA keep state
-.Ed
-.Pp
-This ruleset blocks everything by default.
-Only outgoing connections and incoming connections to port 25 are allowed.
-The initial packet of each connection has the SYN
-flag set, will be passed and creates state.
-All further packets of these connections are passed if they match a state.
-.Pp
-By default, packets coming in and out of any interface can match a state,
-but it is also possible to change that behaviour by assigning states to a
-single interface or a group of interfaces.
-.Pp
-The default policy is specified by the
-.Ar state-policy
-global option, but this can be adjusted on a per-rule basis by adding one
-of the
-.Ar if-bound ,
-.Ar group-bound
-or
-.Ar floating
-keywords to the
-.Ar keep state
-option.
-For example, if a rule is defined as:
-.Bd -literal -offset indent
-pass out on ppp from any to 10.12/16 keep state (group-bound)
-.Ed
-.Pp
-A state created on ppp0 would match packets an all PPP interfaces,
-but not packets flowing through fxp0 or any other interface.
-.Pp
-Keeping rules
-.Ar floating
-is the more flexible option when the firewall is in a dynamic routing
-environment.
-However, this has some security implications since a state created by one
-trusted network could allow potentially hostile packets coming in from other
-interfaces.
-.Pp
-Specifying
-.Ar flags S/SA
-restricts state creation to the initial SYN
-packet of the TCP handshake.
-One can also be less restrictive, and allow state creation from
-intermediate
-.Pq non-SYN
-packets.
-This will cause
-.Xr pf 4
-to synchronize to existing connections, for instance
-if one flushes the state table.
-.Pp
-For UDP, which is stateless by nature,
-.Ar keep state
-will create state as well.
-UDP packets are matched to states using only host addresses and ports.
-.Pp
-ICMP messages fall into two categories: ICMP error messages, which always
-refer to a TCP or UDP packet, are matched against the referred to connection.
-If one keeps state on a TCP connection, and an ICMP source quench message
-referring to this TCP connection arrives, it will be matched to the right
-state and get passed.
-.Pp
-For ICMP queries,
-.Ar keep state
-creates an ICMP state, and
-.Xr pf 4
-knows how to match ICMP replies to states.
-For example,
-.Bd -literal -offset indent
-pass out inet proto icmp all icmp-type echoreq keep state
-.Ed
-.Pp
-allows echo requests (such as those created by
-.Xr ping 8 )
-out, creates state, and matches incoming echo replies correctly to states.
-.Pp
-Note:
-.Ar nat , binat No and Ar rdr
-rules implicitly create state for connections.
-.Sh STATE MODULATION
-Much of the security derived from TCP is attributable to how well the
-initial sequence numbers (ISNs) are chosen.
-Some popular stack implementations choose
-.Em very
-poor ISNs and thus are normally susceptible to ISN prediction exploits.
-By applying a
-.Ar modulate state
-rule to a TCP connection,
-.Xr pf 4
-will create a high quality random sequence number for each connection
-endpoint.
-.Pp
-The
-.Ar modulate state
-directive implicitly keeps state on the rule and is
-only applicable to TCP connections.
-.Pp
-For instance:
-.Bd -literal -offset indent
-block all
-pass out proto tcp from any to any modulate state
-pass in proto tcp from any to any port 25 flags S/SA modulate state
-.Ed
-.Pp
-There are two caveats associated with state modulation:
-A
-.Ar modulate state
-rule can not be applied to a pre-existing but unmodulated connection.
-Such an application would desynchronize TCP's strict
-sequencing between the two endpoints.
-Instead,
-.Xr pf 4
-will treat the
-.Ar modulate state
-modifier as a
-.Ar keep state
-modifier and the pre-existing connection will be inferred without
-the protection conferred by modulation.
-.Pp
-The other caveat affects currently modulated states when the state table
-is lost (firewall reboot, flushing the state table, etc...).
-.Xr pf 4
-will not be able to infer a connection again after the state table flushes
-the connection's modulator.
-When the state is lost, the connection may be left dangling until the
-respective endpoints time out the connection.
-It is possible on a fast local network for the endpoints to start an ACK
-storm while trying to resynchronize after the loss of the modulator.
-Using a
-.Ar flags S/SA
-modifier on
-.Ar modulate state
-rules between fast networks is suggested to prevent ACK storms.
-.Sh SYN PROXY
-By default,
-.Xr pf 4
-passes packets that are part of a
-.Xr tcp 4
-handshake between the endpoints.
-The
-.Ar synproxy state
-option can be used to cause
-.Xr pf 4
-itself to complete the handshake with the active endpoint, perform a handshake
-with the passive endpoint, and then forward packets between the endpoints.
-.Pp
-No packets are sent to the passive endpoint before the active endpoint has
-completed the handshake, hence so-called SYN floods with spoofed source
-addresses will not reach the passive endpoint, as the sender can't complete the
-handshake.
-.Pp
-The proxy is transparent to both endpoints, they each see a single
-connection from/to the other endpoint.
-.Xr pf 4
-chooses random initial sequence numbers for both handshakes.
-Once the handshakes are completed, the sequence number modulators
-(see previous section) are used to translate further packets of the
-connection.
-Hence,
-.Ar synproxy state
-includes
-.Ar modulate state
-and
-.Ar keep state .
-.Pp
-Rules with
-.Ar synproxy
-will not work if
-.Xr pf 4
-operates on a
-.Xr bridge 4 .
-.Pp
-Example:
-.Bd -literal -offset indent
-pass in proto tcp from any to any port www flags S/SA synproxy state
-.Ed
-.Sh STATEFUL TRACKING OPTIONS
-All three of
-.Ar keep state ,
-.Ar modulate state
-and
-.Ar synproxy state
-support the following options:
-.Pp
-.Bl -tag -width xxxx -compact
-.It Ar max <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.
-.It Ar no-sync
-Prevent state changes for states created by this rule from appearing on the
-.Xr pfsync 4
-interface.
-.It Ar <timeout> <seconds>
-Changes the timeout values used for states created by this rule.
-.Pp
-When the
-.Ar source-track
-keyword is specified, the number of states per source IP is tracked.
-The following limits can be set:
-.Pp
-.Bl -tag -width xxxx -compact
-.It Ar max-src-nodes
-Limits the maximum number of source addresses which can simultaneously
-have state table entries.
-.It Ar max-src-states
-Limits the maximum number of simultaneous state entries that a single
-source address can create with this rule.
-.El
-For a list of all valid timeout names, see
-.Sx OPTIONS
-above.
-.Pp
-Multiple options can be specified, separated by commas:
-.Bd -literal
-pass in proto tcp from any to any \e
- port www flags S/SA keep state \e
- (max 100, source-track rule, max-src-nodes 75, \e
- max-src-states 3, tcp.established 60, tcp.closing 5)
-.Ed
-.El
-.Sh OPERATING SYSTEM FINGERPRINTING
-Passive OS Fingerprinting is a mechanism to inspect nuances of a TCP
-connection's initial SYN packet and guess at the host's operating system.
-Unfortunately these nuances are easily spoofed by an attacker so the
-fingerprint is not useful in making security decisions.
-But the fingerprint is typically accurate enough to make policy decisions
-upon.
-.Pp
-The fingerprints may be specified by operating system class, by
-version, or by subtype/patchlevel.
-The class of an operating system is typically the vender or genre
-and would be OpenBSD for the
-.Xr pf 4
-firewall itself.
-The version of the oldest available OpenBSD release on the main ftp site
-would be 2.6 and the fingerprint would be written
-.Pp
-.Dl \&"OpenBSD 2.6\&"
-.Pp
-The subtype of an operating system is typically used to describe the
-patchlevel if that patch led to changes in the TCP stack behavior.
-In the case of OpenBSD, the only subtype is for a fingerprint that was
-normalized by the
-.Ar no-df
-scrub option and would be specified as
-.Pp
-.Dl \&"OpenBSD 3.3 no-df\&"
-.Pp
-Fingerprints for most popular operating systems are provided by
-.Xr pf.os 5 .
-Once
-.Xr pf 4
-is running, a complete list of known operating system fingerprints may
-be listed by running:
-.Pp
-.Dl # pfctl -so
-.Pp
-Filter rules can enforce policy at any level of operating system specification
-assuming a fingerprint is present.
-Policy could limit traffic to approved operating systems or even ban traffic
-from hosts that aren't at the latest service pack.
-.Pp
-The
-.Ar unknown
-class can also be used as the fingerprint which will match packets for
-which no operating system fingerprint is known.
-.Pp
-Examples:
-.Bd -literal -offset indent
-pass out proto tcp from any os OpenBSD keep state
-block out proto tcp from any os Doors
-block out proto tcp from any os "Doors PT"
-block out proto tcp from any os "Doors PT SP3"
-block out from any os "unknown"
-pass on lo0 proto tcp from any os "OpenBSD 3.3 lo0" keep state
-.Ed
-.Pp
-Operating system fingerprinting is limited only to the TCP SYN packet.
-This means that it will not work on other protocols and will not match
-a currently established connection.
-.Pp
-Caveat: operating system fingerprints are occasionally wrong.
-There are three problems: an attacker can trivially craft his packets to
-appear as any operating system he chooses;
-an operating system patch could change the stack behavior and no fingerprints
-will match it until the database is updated;
-and multiple operating systems may have the same fingerprint.
-.Sh BLOCKING SPOOFED TRAFFIC
-"Spoofing" is the faking of IP addresses, typically for malicious
-purposes.
-The
-.Ar antispoof
-directive expands to a set of filter rules which will block all
-traffic with a source IP from the network(s) directly connected
-to the specified interface(s) from entering the system through
-any other interface.
-.Pp
-For example, the line
-.Bd -literal -offset indent
-antispoof for lo0
-.Ed
-.Pp
-expands to
-.Bd -literal -offset indent
-block drop in on ! lo0 inet from 127.0.0.1/8 to any
-block drop in on ! lo0 inet6 from ::1 to any
-.Ed
-.Pp
-For non-loopback interfaces, there are additional rules to block incoming
-packets with a source IP address identical to the interface's IP(s).
-For example, assuming the interface wi0 had an IP address of 10.0.0.1 and a
-netmask of 255.255.255.0,
-the line
-.Bd -literal -offset indent
-antispoof for wi0 inet
-.Ed
-.Pp
-expands to
-.Bd -literal -offset indent
-block drop in on ! wi0 inet from 10.0.0.0/24 to any
-block drop in inet from 10.0.0.1 to any
-.Ed
-.Pp
-Caveat: Rules created by the
-.Ar antispoof
-directive interfere with packets sent over loopback interfaces
-to local addresses.
-One should pass these explicitly.
-.Sh FRAGMENT HANDLING
-The size of IP datagrams (packets) can be significantly larger than the
-maximum transmission unit (MTU) of the network.
-In cases when it is necessary or more efficient to send such large packets,
-the large packet will be fragmented into many smaller packets that will each
-fit onto the wire.
-Unfortunately for a firewalling device, only the first logical fragment will
-contain the necessary header information for the subprotocol that allows
-.Xr pf 4
-to filter on things such as TCP ports or to perform NAT.
-.Pp
-Besides the use of
-.Ar scrub
-rules as described in
-.Sx TRAFFIC NORMALIZATION
-above, there are three options for handling fragments in the packet filter.
-.Pp
-One alternative is to filter individual fragments with filter rules.
-If no
-.Ar scrub
-rule applies to a fragment, it is passed to the filter.
-Filter rules with matching IP header parameters decide whether the
-fragment is passed or blocked, in the same way as complete packets
-are filtered.
-Without reassembly, fragments can only be filtered based on IP header
-fields (source/destination address, protocol), since subprotocol header
-fields are not available (TCP/UDP port numbers, ICMP code/type).
-The
-.Ar fragment
-option can be used to restrict filter rules to apply only to
-fragments, but not complete packets.
-Filter rules without the
-.Ar fragment
-option still apply to fragments, if they only specify IP header fields.
-For instance, the rule
-.Bd -literal -offset indent
-pass in proto tcp from any to any port 80
-.Ed
-.Pp
-never applies to a fragment, even if the fragment is part of a TCP
-packet with destination port 80, because without reassembly this information
-is not available for each fragment.
-This also means that fragments cannot create new or match existing
-state table entries, which makes stateful filtering and address
-translation (NAT, redirection) for fragments impossible.
-.Pp
-It's also possible to reassemble only certain fragments by specifying
-source or destination addresses or protocols as parameters in
-.Ar scrub
-rules.
-.Pp
-In most cases, the benefits of reassembly outweigh the additional
-memory cost, and it's recommended to use
-.Ar scrub
-rules to reassemble
-all fragments via the
-.Ar fragment reassemble
-modifier.
-.Pp
-The memory allocated for fragment caching can be limited using
-.Xr pfctl 8 .
-Once this limit is reached, fragments that would have to be cached
-are dropped until other entries time out.
-The timeout value can also be adjusted.
-.Pp
-Currently, only IPv4 fragments are supported and IPv6 fragments
-are blocked unconditionally.
-.Sh ANCHORS AND NAMED RULESETS
-Besides the main ruleset,
-.Xr pfctl 8
-can load named rulesets into
-.Ar anchor
-attachment points.
-An
-.Ar anchor
-contains a list of named rulesets.
-An
-.Ar anchor
-has a name which specifies where
-.Xr pfctl 8
-can be used to attach sub-rulesets.
-A named ruleset contains filter and translation rules, like the
-main ruleset.
-The main ruleset can reference
-.Ar anchor
-attachment points
-using the following kinds
-of rules:
-.Bl -tag -width xxxx
-.It Ar nat-anchor <name>
-Evaluates the
-.Ar nat
-rules of all named rulesets in the specified
-.Ar anchor .
-.It Ar rdr-anchor <name>
-Evaluates the
-.Ar rdr
-rules of all named rulesets in the specified
-.Ar anchor .
-.It Ar binat-anchor <name>
-Evaluates the
-.Ar binat
-rules of all named rulesets in the specified
-.Ar anchor .
-.It Ar anchor <name>
-Evaluates the filter rules of all named rulesets in the specified
-.Ar anchor .
-.It Ar load anchor <name>:<ruleset> from <file>
-Loads the rules from the specified file into the named
-ruleset
-.Ar <ruleset>
-attached to the anchor
-.Ar <name> .
-.El
-.Pp
-When evaluation of the main ruleset reaches an
-.Ar anchor
-rule,
-.Xr pf 4
-will proceed to evaluate all rules specified in the
-named rulesets attached to that
-.Ar anchor .
-.Pp
-Matching filter rules in named rulesets with the
-.Ar quick
-option and matching translation rules are final and abort the
-evaluation of both the rules in the
-.Ar anchor
-and the main ruleset.
-.Pp
-Only the main ruleset can contain
-.Ar anchor
-rules.
-.Pp
-When an
-.Ar anchor
-contains more than one named ruleset, they are evaluated
-in the alphabetical order of their names.
-.Pp
-Rules may contain
-.Ar anchor
-attachment points which do not contain any rules when the main ruleset
-is loaded, and later such named rulesets can be manipulated through
-.Xr pfctl 8
-without reloading the main ruleset.
-For example,
-.Bd -literal -offset indent
-ext_if = \&"kue0\&"
-block on $ext_if all
-anchor spam
-pass out on $ext_if all keep state
-pass in on $ext_if proto tcp from any \e
- to $ext_if port smtp keep state
-.Ed
-.Pp
-blocks all packets on the external interface by default, then evaluates
-all rulesets in the
-.Ar anchor
-named "spam", and finally passes all outgoing connections and
-incoming connections to port 25.
-.Bd -literal -offset indent
-# echo \&"block in quick from 1.2.3.4 to any\&" \&| \e
- pfctl -a spam:manual -f -
-.Ed
-.Pp
-loads a single ruleset containing a single rule into the
-.Ar anchor ,
-which blocks all packets from a specific address.
-.Pp
-The named ruleset can also be populated by adding a
-.Ar load anchor
-rule after the
-.Ar anchor
-rule:
-.Bd -literal -offset indent
-anchor spam
-load anchor spam:manual from "/etc/pf-spam.conf"
-.Ed
-.Pp
-When
-.Xr pfctl 8
-loads
-.Nm pf.conf ,
-it will also load all the rules from the file
-.Pa /etc/pf-spam.conf
-into the named ruleset.
-.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.
-When parameters are used, the
-.Ar anchor
-rule is only evaluated for matching packets.
-This allows conditional evaluation of named rulesets, like:
-.Bd -literal -offset indent
-block on $ext_if all
-anchor spam proto tcp from any to any port smtp
-pass out on $ext_if all keep state
-pass in on $ext_if proto tcp from any to $ext_if port smtp keep state
-.Ed
-.Pp
-The rules inside
-.Ar anchor
-spam are only evaluated for
-.Ar tcp
-packets with destination port 25.
-Hence,
-.Bd -literal -offset indent
-# echo \&"block in quick from 1.2.3.4 to any" \&| \e
- pfctl -a spam:manual -f -
-.Ed
-.Pp
-will only block connections from 1.2.3.4 to port 25.
-.Sh TRANSLATION EXAMPLES
-This example maps incoming requests on port 80 to port 8080, on
-which a daemon is running (because, for example, it is not run as root,
-and therefore lacks permission to bind to port 80).
-.Bd -literal
-# use a macro for the interface name, so it can be changed easily
-ext_if = \&"ne3\&"
-
-# map daemon on 8080 to appear to be on 80
-rdr on $ext_if proto tcp from any to any port 80 -> 127.0.0.1 port 8080
-.Ed
-.Pp
-If the
-.Ar pass
-modifier is given, packets matching the translation rule are passed without
-inspecting the filter rules:
-.Bd -literal
-rdr pass on $ext_if proto tcp from any to any port 80 -> 127.0.0.1 \e
- port 8080
-.Ed
-.Pp
-In the example below, vlan12 is configured as 192.168.168.1;
-the machine translates all packets coming from 192.168.168.0/24 to 204.92.77.111
-when they are going out any interface except vlan12.
-This has the net effect of making traffic from the 192.168.168.0/24
-network appear as though it is the Internet routable address
-204.92.77.111 to nodes behind any interface on the router except
-for the nodes on vlan12.
-(Thus, 192.168.168.1 can talk to the 192.168.168.0/24 nodes.)
-.Bd -literal
-nat on ! vlan12 from 192.168.168.0/24 to any -> 204.92.77.111
-.Ed
-.Pp
-In the example below, the machine sits between a fake internal 144.19.74.*
-network, and a routable external IP of 204.92.77.100.
-The
-.Ar no nat
-rule excludes protocol AH from being translated.
-.Bd -literal
-# NO NAT
-no nat on $ext_if proto ah from 144.19.74.0/24 to any
-nat on $ext_if from 144.19.74.0/24 to any -> 204.92.77.100
-.Ed
-.Pp
-In the example below, packets bound for one specific server, as well as those
-generated by the sysadmins are not proxied; all other connections are.
-.Bd -literal
-# NO RDR
-no rdr on $int_if proto { tcp, udp } from any to $server port 80
-no rdr on $int_if proto { tcp, udp } from $sysadmins to any port 80
-rdr on $int_if proto { tcp, udp } from any to any port 80 -> 127.0.0.1 \e
- port 80
-.Ed
-.Pp
-This longer example uses both a NAT and a redirection.
-The external interface has the address 157.161.48.183.
-On the internal interface, we are running
-.Xr ftp-proxy 8 ,
-listening for outbound ftp sessions captured to port 8021.
-.Bd -literal
-# NAT
-# Translate outgoing packets' source addresses (any protocol).
-# In this case, any address but the gateway's external address is mapped.
-nat on $ext_if inet from ! ($ext_if) to any -> ($ext_if)
-
-# NAT PROXYING
-# Map outgoing packets' source port to an assigned proxy port instead of
-# an arbitrary port.
-# In this case, proxy outgoing isakmp with port 500 on the gateway.
-nat on $ext_if inet proto udp from any port = isakmp to any -> ($ext_if) \e
- port 500
-
-# BINAT
-# Translate outgoing packets' source address (any protocol).
-# Translate incoming packets' destination address to an internal machine
-# (bidirectional).
-binat on $ext_if from 10.1.2.150 to any -> ($ext_if)
-
-# RDR
-# Translate incoming packets' destination addresses.
-# As an example, redirect a TCP and UDP port to an internal machine.
-rdr on $ext_if inet proto tcp from any to ($ext_if) port 8080 \e
- -> 10.1.2.151 port 22
-rdr on $ext_if inet proto udp from any to ($ext_if) port 8080 \e
- -> 10.1.2.151 port 53
-
-# RDR
-# Translate outgoing ftp control connections to send them to localhost
-# for proxying with ftp-proxy(8) running on port 8021.
-rdr on $int_if proto tcp from any to any port 21 -> 127.0.0.1 port 8021
-.Ed
-.Pp
-In this example, a NAT gateway is set up to translate internal addresses
-using a pool of public addresses (192.0.2.16/28) and to redirect
-incoming web server connections to a group of web servers on the internal
-network.
-.Bd -literal
-# NAT LOAD BALANCE
-# Translate outgoing packets' source addresses using an address pool.
-# A given source address is always translated to the same pool address by
-# using the source-hash keyword.
-nat on $ext_if inet from any to any -> 192.0.2.16/28 source-hash
-
-# RDR ROUND ROBIN
-# Translate incoming web server connections to a group of web servers on
-# the internal network.
-rdr on $ext_if proto tcp from any to any port 80 \e
- -> { 10.1.2.155, 10.1.2.160, 10.1.2.161 } round-robin
-.Ed
-.Sh FILTER EXAMPLES
-.Bd -literal
-# The external interface is kue0
-# (157.161.48.183, the only routable address)
-# and the private network is 10.0.0.0/8, for which we are doing NAT.
-
-# use a macro for the interface name, so it can be changed easily
-ext_if = \&"kue0\&"
-
-# normalize all incoming traffic
-scrub in on $ext_if all fragment reassemble
-
-# block and log everything by default
-block return log on $ext_if all
-
-# block anything coming from source we have no back routes for
-block in from no-route to any
-
-# block and log outgoing packets that do not have our address as source,
-# they are either spoofed or something is misconfigured (NAT disabled,
-# for instance), we want to be nice and do not send out garbage.
-block out log quick on $ext_if from ! 157.161.48.183 to any
-
-# silently drop broadcasts (cable modem noise)
-block in quick on $ext_if from any to 255.255.255.255
-
-# block and log incoming packets from reserved address space and invalid
-# addresses, they are either spoofed or misconfigured, we cannot reply to
-# them anyway (hence, no return-rst).
-block in log quick on $ext_if from { 10.0.0.0/8, 172.16.0.0/12, \e
- 192.168.0.0/16, 255.255.255.255/32 } to any
-
-# ICMP
-
-# pass out/in certain ICMP queries and keep state (ping)
-# state matching is done on host addresses and ICMP id (not type/code),
-# so replies (like 0/0 for 8/0) will match queries
-# ICMP error messages (which always refer to a TCP/UDP packet) are
-# handled by the TCP/UDP states
-pass on $ext_if inet proto icmp all icmp-type 8 code 0 keep state
-
-# UDP
-
-# pass out all UDP connections and keep state
-pass out on $ext_if proto udp all keep state
-
-# pass in certain UDP connections and keep state (DNS)
-pass in on $ext_if proto udp from any to any port domain keep state
-
-# TCP
-
-# pass out all TCP connections and modulate state
-pass out on $ext_if proto tcp all modulate state
-
-# pass in certain TCP connections and keep state (SSH, SMTP, DNS, IDENT)
-pass in on $ext_if proto tcp from any to any port { ssh, smtp, domain, \e
- auth } flags S/SA keep state
-
-# pass in data mode connections for ftp-proxy running on this host.
-# (see ftp-proxy(8) for details)
-pass in on $ext_if proto tcp from any to 157.161.48.183 port >= 49152 \e
- flags S/SA keep state
-
-# Do not allow Windows 9x SMTP connections since they are typically
-# a viral worm. Alternately we could limit these OSes to 1 connection each.
-block in on $ext_if proto tcp from any os {"Windows 95", "Windows 98"} \e
- to any port smtp
-
-# Packet Tagging
-
-# three interfaces: $int_if, $ext_if, and $wifi_if (wireless). NAT is
-# being done on $ext_if for all outgoing packets. tag packets in on
-# $int_if and pass those tagged packets out on $ext_if. all other
-# outgoing packets (i.e., packets from the wireless network) are only
-# permitted to access port 80.
-
-pass in on $int_if from any to any tag INTNET keep state
-pass in on $wifi_if from any to any keep state
-
-block out on $ext_if from any to any
-pass out quick on $ext_if tagged INTNET keep state
-pass out on $ext_if from any to any port 80 keep state
-
-# tag incoming packets as they are redirected to spamd(8). use the tag
-# to pass those packets through the packet filter.
-
-rdr on $ext_if inet proto tcp from <spammers> to port smtp \e
- tag SPAMD -> 127.0.0.1 port spamd
-
-block in on $ext_if
-pass in on $ext_if inet proto tcp tagged SPAMD keep state
-.Ed
-.Sh GRAMMAR
-Syntax for
-.Nm
-in BNF:
-.Bd -literal
-line = ( option | pf-rule | nat-rule | binat-rule | rdr-rule |
- antispoof-rule | altq-rule | queue-rule | anchor-rule |
- trans-anchors | load-anchors | table-rule )
-
-option = "set" ( [ "timeout" ( timeout | "{" timeout-list "}" ) ] |
- [ "optimization" [ "default" | "normal" |
- "high-latency" | "satellite" |
- "aggressive" | "conservative" ] ]
- [ "limit" ( limit-item | "{" limit-list "}" ) ] |
- [ "loginterface" ( interface-name | "none" ) ] |
- [ "block-policy" ( "drop" | "return" ) ] |
- [ "state-policy" ( "if-bound" | "group-bound" |
- "floating" ) ]
- [ "require-order" ( "yes" | "no" ) ]
- [ "fingerprints" filename ] |
- [ "debug" ( "none" | "urgent" | "misc" | "loud" ) ] )
-
-pf-rule = action [ ( "in" | "out" ) ]
- [ "log" | "log-all" ] [ "quick" ]
- [ "on" ifspec ] [ route ] [ af ] [ protospec ]
- hosts [ filteropt-list ]
-
-filteropt-list = filteropt-list filteropt | filteropt
-filteropt = user | group | flags | icmp-type | icmp6-type | tos |
- ( "keep" | "modulate" | "synproxy" ) "state"
- [ "(" state-opts ")" ] |
- "fragment" | "no-df" | "min-ttl" number |
- "max-mss" number | "random-id" | "reassemble tcp" |
- fragmentation | "allow-opts" |
- "label" string | "tag" string | [ ! ] "tagged" string
- "queue" ( string | "(" string [ [ "," ] string ] ")" )
-
-nat-rule = [ "no" ] "nat" [ "pass" ] [ "on" ifspec ] [ af ]
- [ protospec ] hosts [ "tag" string ]
- [ "->" ( redirhost | "{" redirhost-list "}" )
- [ portspec ] [ pooltype ] [ "static-port" ] ]
-
-binat-rule = [ "no" ] "binat" [ "pass" ] [ "on" interface-name ]
- [ af ] [ "proto" ( proto-name | proto-number ) ]
- "from" address [ "/" mask-bits ] "to" ipspec
- [ "tag" string ]
- [ "->" address [ "/" mask-bits ] ]
-
-rdr-rule = [ "no" ] "rdr" [ "pass" ] [ "on" ifspec ] [ af ]
- [ protospec ] hosts [ "tag" string ]
- [ "->" ( redirhost | "{" redirhost-list "}" )
- [ portspec ] [ pooltype ] ]
-
-antispoof-rule = "antispoof" [ "log" ] [ "quick" ]
- "for" ( interface-name | "{" interface-list "}" )
- [ af ] [ "label" string ]
-
-table-rule = "table" "<" string ">" [ tableopts-list ]
-tableopts-list = tableopts-list tableopts | tableopts
-tableopts = "persist" | "const" | "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"
-
-altq-rule = "altq on" interface-name queueopts-list
- "queue" subqueue
-queue-rule = "queue" string [ "on" interface-name ] queueopts-list
- subqueue
-
-anchor-rule = "anchor" string [ ( "in" | "out" ) ] [ "on" ifspec ]
- [ af ] [ "proto" ] [ protospec ] [ hosts ]
-
-trans-anchors = ( "nat-anchor" | "rdr-anchor" | "binat-anchor" ) string
- [ "on" ifspec ] [ af ] [ "proto" ] [ protospec ] [ hosts ]
-
-load-anchor = "load anchor" anchorname:rulesetname "from" filename
-
-queueopts-list = queueopts-list queueopts | queueopts
-queueopts = [ "bandwidth" bandwidth-spec ] |
- [ "qlimit" number ] | [ "tbrsize" number ] |
- [ "priority" number ] | [ schedulers ]
-schedulers = ( cbq-def | priq-def | hfsc-def )
-bandwidth-spec = "number" ( "b" | "Kb" | "Mb" | "Gb" | "%" )
-
-action = "pass" | "block" [ return ] | "scrub"
-return = "drop" | "return" | "return-rst" [ "( ttl" number ")" ] |
- "return-icmp" [ "(" icmpcode ["," icmp6code ] ")" ] |
- "return-icmp6" [ "(" icmp6code ")" ]
-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 ]
-route = "fastroute" |
- ( "route-to" | "reply-to" | "dup-to" )
- ( routehost | "{" routehost-list "}" )
- [ pooltype ]
-af = "inet" | "inet6"
-
-protospec = "proto" ( proto-name | proto-number |
- "{" proto-list "}" )
-proto-list = ( proto-name | proto-number ) [ [ "," ] proto-list ]
-
-hosts = "all" |
- "from" ( "any" | "no-route" | "self" | host |
- "{" host-list "}" ) [ port ] [ os ]
- "to" ( "any" | "no-route" | "self" | host |
- "{" host-list "}" ) [ port ]
-
-ipspec = "any" | host | "{" host-list "}"
-host = [ "!" ] ( address [ "/" mask-bits ] | "<" string ">" )
-redirhost = address [ "/" mask-bits ]
-routehost = ( interface-name [ address [ "/" mask-bits ] ] )
-address = ( interface-name | "(" interface-name ")" | hostname |
- ipv4-dotted-quad | ipv6-coloned-hex )
-host-list = host [ [ "," ] host-list ]
-redirhost-list = redirhost [ [ "," ] redirhost-list ]
-routehost-list = routehost [ [ "," ] routehost-list ]
-
-port = "port" ( unary-op | binary-op | "{" op-list "}" )
-portspec = "port" ( number | name ) [ ":" ( "*" | number | name ) ]
-os = "os" ( os-name | "{" os-list "}" )
-user = "user" ( unary-op | binary-op | "{" op-list "}" )
-group = "group" ( unary-op | binary-op | "{" op-list "}" )
-
-unary-op = [ "=" | "!=" | "<" | "<=" | ">" | ">=" ]
- ( name | number )
-binary-op = number ( "<>" | "><" | ":" ) number
-op-list = ( unary-op | binary-op ) [ [ "," ] op-list ]
-
-os-name = operating-system-name
-os-list = os-name [ [ "," ] os-list ]
-
-flags = "flags" [ flag-set ] "/" flag-set
-flag-set = [ "F" ] [ "S" ] [ "R" ] [ "P" ] [ "A" ] [ "U" ] [ "E" ]
- [ "W" ]
-
-icmp-type = "icmp-type" ( icmp-type-code | "{" icmp-list "}" )
-icmp6-type = "icmp6-type" ( icmp-type-code | "{" icmp-list "}" )
-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" |
- [ "0x" ] number )
-
-state-opts = state-opt [ [ "," ] state-opts ]
-state-opt = ( "max" number | "no-sync" | timeout |
- "source-track" [ ( "rule" | "global" ) ] |
- "max-src-nodes" number | "max-src-states" number |
- "if-bound" | "group-bound" | "floating" )
-
-fragmentation = [ "fragment reassemble" | "fragment crop" |
- "fragment drop-ovl" ]
-
-timeout-list = timeout [ [ "," ] timeout-list ]
-timeout = ( "tcp.first" | "tcp.opening" | "tcp.established" |
- "tcp.closing" | "tcp.finwait" | "tcp.closed" |
- "udp.first" | "udp.single" | "udp.multiple" |
- "icmp.first" | "icmp.error" |
- "other.first" | "other.single" | "other.multiple" |
- "frag" | "interval" | "src.track" |
- "adaptive.start" | "adaptive.end" ) number
-
-limit-list = limit-item [ [ "," ] limit-list ]
-limit-item = ( "states" | "frags" | "src-nodes" ) number
-
-pooltype = ( "bitmask" | "random" |
- "source-hash" [ ( hex-key | string-key ) ] |
- "round-robin" ) [ sticky-address ]
-
-subqueue = string | "{" queue-list "}"
-queue-list = string [ [ "," ] string ]
-cbq-def = "cbq" [ "(" cbq-opt [ [ "," ] cbq-opt ] ")" ]
-priq-def = "priq" [ "(" priq-opt [ [ "," ] priq-opt ] ")" ]
-hfsc-def = "hfsc" [ "(" hfsc-opt [ [ "," ] hfsc-opt ] ")" ]
-cbq-opt = ( "default" | "borrow" | "red" | "ecn" | "rio" )
-priq-opt = ( "default" | "red" | "ecn" | "rio" )
-hfsc-opt = ( "default" | "red" | "ecn" | "rio" |
- linkshare-sc | realtime-sc | upperlimit-sc )
-linkshare-sc = "linkshare" sc-spec
-realtime-sc = "realtime" sc-spec
-upperlimit-sc = "upperlimit" sc-spec
-sc-spec = ( bandwidth-spec |
- "(" bandwidth-spec number bandwidth-spec ")" )
-.Ed
-.Sh FILES
-.Bl -tag -width "/etc/protocols" -compact
-.It Pa /etc/hosts
-Host name database.
-.It Pa /etc/pf.conf
-Default location of the ruleset file.
-.It Pa /etc/pf.os
-Default location of OS fingerprints.
-.It Pa /etc/protocols
-Protocol name database.
-.It Pa /etc/services
-Service name database.
-.It Pa /usr/share/pf
-Example rulesets.
-.El
-.Sh SEE ALSO
-.Xr icmp 4 ,
-.Xr icmp6 4 ,
-.Xr ip 4 ,
-.Xr ip6 4 ,
-.Xr pf 4 ,
-.Xr pfsync 4 ,
-.Xr tcp 4 ,
-.Xr udp 4 ,
-.Xr hosts 5 ,
-.Xr pf.os 5 ,
-.Xr protocols 5 ,
-.Xr services 5 ,
-.Xr ftp-proxy 8 ,
-.Xr pfctl 8 ,
-.Xr pflogd 8
-.Sh HISTORY
-The
-.Nm
-file format first appeared in
-.Ox 3.0 .
diff --git a/contrib/pf/man/pf.os.5 b/contrib/pf/man/pf.os.5
deleted file mode 100644
index 9978174ba544..000000000000
--- a/contrib/pf/man/pf.os.5
+++ /dev/null
@@ -1,242 +0,0 @@
-.\" $OpenBSD: pf.os.5,v 1.5 2003/10/25 07:55:27 jmc Exp $
-.\"
-.\" Copyright (c) 2003 Mike Frantzen <frantzen@w4g.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.
-.Dd August 18, 2003
-.Dt PF.OS 5
-.Os
-.Sh NAME
-.Nm pf.os
-.Nd format of the operating system fingerprints file
-.Sh DESCRIPTION
-The
-.Xr pf 4
-firewall and the
-.Xr tcpdump 8
-program can both fingerprint the operating system of hosts that
-originate an IPv4 TCP connection.
-The file consists of newline-separated records, one per fingerprint,
-containing nine colon
-.Pq Ql \&:
-separated fields.
-These fields are as follows:
-.Pp
-.Bl -tag -width Description -offset indent -compact
-.It window
-The TCP window size.
-.It TTL
-The IP time to live.
-.It df
-The presence of the IPv4 don't fragment bit.
-.It packet size
-The size of the initial TCP packet.
-.It TCP options
-An ordered list of the TCP options.
-.It class
-The class of operating system.
-.It version
-The version of the operating system.
-.It subtype
-The subtype of patchlevel of the operating system.
-.It description
-The overall textual description of the operating system, version and subtype.
-.El
-.Pp
-The
-.Ar window
-field corresponds to the th->th_win field in the TCP header and is the
-source host's advertised TCP window size.
-It may be between zero and 65,535 inclusive.
-The window size may be given as a multiple of a constant by prepending
-the size with a percent sign
-.Sq %
-and the value will be used as a modulus.
-Three special values may be used for the window size:
-.Pp
-.Bl -tag -width xxx -offset indent -compact
-.It *
-An asterisk will wildcard the value so any window size will match.
-.It S
-Allow any window size which is a multiple of the maximum segment size (MSS).
-.It T
-Allow any window size which is a multiple of the maximum transmission unit
-(MTU).
-.El
-.Pp
-The
-.Ar ttl
-value is the initial time to live in the IP header.
-The fingerprint code will account for the volatility of the packet's TTL
-as it traverses a network.
-.Pp
-The
-.Ar df
-bit corresponds to the Don't Fragment bit in an IPv4 header.
-It tells intermediate routers not to fragment the packet and is used for
-path MTU discovery.
-It may be either a zero or a one.
-.Pp
-The
-.Ar packet size
-is the literal size of the full IP packet and is a function of all of
-the IP and TCP options.
-.Pp
-The
-.Ar TCP options
-field is an ordered list of the individual TCP options that appear in the
-SYN packet.
-Each option is described by a single character separated by a comma and
-certain ones may include a value.
-The options are:
-.Pp
-.Bl -tag -width Description -offset indent -compact
-.It Mnnn
-maximum segment size (MSS) option.
-The value is the maximum packet size of the network link which may
-include the
-.Sq %
-modulus or match all MSSes with the
-.Sq *
-value.
-.It N
-the NOP option (NO Operation).
-.It T[0]
-the timestamp option.
-Certain operating systems always start with a zero timestamp in which
-case a zero value is added to the option; otherwise no value is appended.
-.It S
-the Selective ACKnowledgement OK (SACKOK) option.
-.It Wnnn
-window scaling option.
-The value is the size of the window scaling which may include the
-.Sq %
-modulus or match all window scalings with the
-.Sq *
-value.
-.El
-.Pp
-No TCP options in the fingerprint may be given with a single dot
-.Sq \&. .
-.Pp
-An example of OpenBSD's TCP options are:
-.Pp
-.Dl M*,N,N,S,N,W0,N,N,T
-.Pp
-The first option
-.Ar M*
-is the MSS option and will match all values.
-The second and third options
-.Ar N
-will match two NOPs.
-The fourth option
-.Ar S
-will match the SACKOK option.
-The fifth
-.Ar N
-will match another NOP.
-The sixth
-.Ar W0
-will match a window scaling option with a zero scaling size.
-The seventh and eighth
-.Ar N
-options will match two NOPs.
-And the ninth and final option
-.Ar T
-will match the timestamp option with any time value.
-.Pp
-The TCP options in a fingerprint will only match packets with the
-exact same TCP options in the same order.
-.Pp
-The
-.Ar class
-field is the class, genre or vender of the operating system.
-.Pp
-The
-.Ar version
-is the version of the operating system.
-It is used to distinguish between different fingerprints of operating
-systems of the same class but different versions.
-.Pp
-The
-.Ar subtype
-is the subtype or patch level of the operating system version.
-It is used to distinguish between different fingerprints of operating
-systems of the same class and same version but slightly different
-patches or tweaking.
-.Pp
-The
-.Ar description
-is a general description of the operating system, its version,
-patchlevel and any further useful details.
-.Sh EXAMPLES
-The fingerprint of a plain
-.Ox 3.3
-host is:
-.Bd -literal
- 16384:64:1:64:M*,N,N,S,N,W0,N,N,T:OpenBSD:3.3::OpenBSD 3.3
-.Ed
-.Pp
-The fingerprint of an
-.Ox 3.3
-host behind a PF scrubbing firewall with a no-df rule would be:
-.Bd -literal
- 16384:64:0:64:M*,N,N,S,N,W0,N,N,T:OpenBSD:3.3:!df:OpenBSD 3.3 scrub no-df
-.Ed
-.Pp
-An absolutely braindead embedded operating system fingerprint could be:
-.Bd -literal
- 65535:255:0:40:.:DUMMY:1.1:p3:Dummy embedded OS v1.1p3
-.Ed
-.Pp
-The
-.Xr tcpdump 8
-output of
-.Bd -literal
- # tcpdump -s128 -c1 -nv 'tcp[13] == 2'
- 03:13:48.118526 10.0.0.1.3377 > 10.0.0.0.2: S [tcp sum ok] \e
- 534596083:534596083(0) win 57344 <mss 1460> (DF) [tos 0x10] \e
- (ttl 64, id 11315)
-.Ed
-.Pp
-almost translates into the following fingerprint
-.Bd -literal
- 57344:64:1:44:M1460: exampleOS:1.0::exampleOS 1.0
-.Ed
-.Pp
-.Xr tcpdump 8
-does not explicitly give the packet length.
-But it can usually be derived by adding the size of the IPv4 header to
-the size of the TCP header to the size of the TCP options.
-The size of both headers is typically twenty each and the usual
-sizes of the TCP options are:
-.Pp
-.Bl -tag -width timestamp -offset indent -compact
-.It mss
-four bytes.
-.It nop
-1 byte.
-.It sackOK
-two bytes.
-.It timestamp
-ten bytes.
-.It wscale
-three bytes.
-.El
-.Pp
-In the above example, the packet size comes out to 44 bytes.
-.Sh SEE ALSO
-.Xr pf 4 ,
-.Xr pf.conf 5 ,
-.Xr pfctl 8 ,
-.Xr tcpdump 8
diff --git a/contrib/pf/man/pflog.4 b/contrib/pf/man/pflog.4
deleted file mode 100644
index d7bee13a0835..000000000000
--- a/contrib/pf/man/pflog.4
+++ /dev/null
@@ -1,89 +0,0 @@
-.\" $OpenBSD: pflog.4,v 1.7 2004/03/21 19:47:59 miod Exp $
-.\"
-.\" Copyright (c) 2001 Tobias Weingartner
-.\" 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.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
-.\"
-.Dd December 10, 2001
-.Dt PFLOG 4
-.Os
-.Sh NAME
-.Nm pflog
-.Nd packet filter logging interface
-.Sh SYNOPSIS
-.Cd "pseudo-device pflog"
-.Sh DESCRIPTION
-The
-.Nm pflog
-interface is a pseudo-device which makes visible all packets logged by
-the packet filter,
-.Xr pf 4 .
-Logged packets can easily be monitored in real
-time by invoking
-.Xr tcpdump 8
-on the
-.Nm
-interface, or stored to disk using
-.Xr pflogd 8 .
-.Pp
-Each packet retrieved on this interface has a header associated
-with it of length
-.Dv PFLOG_HDRLEN .
-This header documents the address family, interface name, rule
-number, reason, action, and direction of the packet that was logged.
-This structure, defined in
-.Aq Pa net/if_pflog.h
-looks like
-.Bd -literal -offset indent
-struct pfloghdr {
- u_int8_t length;
- sa_family_t af;
- u_int8_t action;
- u_int8_t reason;
- char ifname[IFNAMSIZ];
- char ruleset[PF_RULESET_NAME_SIZE];
- u_int32_t rulenr;
- u_int32_t subrulenr;
- u_int8_t dir;
- u_int8_t pad[3];
-};
-.Ed
-.Sh EXAMPLES
-.Bd -literal -offset indent
-# ifconfig pflog0 up
-# tcpdump -n -e -ttt -i pflog0
-.Ed
-.Sh SEE ALSO
-.Xr inet 4 ,
-.Xr inet6 4 ,
-.Xr netintro 4 ,
-.Xr pf 4 ,
-.Xr ifconfig 8 ,
-.Xr pflogd 8 ,
-.Xr tcpdump 8
-.Sh HISTORY
-The
-.Nm
-device first appeared in
-.Ox 3.0 .
-.\" .Sh BUGS
-.\" Anything here?
diff --git a/contrib/pf/man/pfsync.4 b/contrib/pf/man/pfsync.4
deleted file mode 100644
index f7b39df4bcaa..000000000000
--- a/contrib/pf/man/pfsync.4
+++ /dev/null
@@ -1,226 +0,0 @@
-.\" $OpenBSD: pfsync.4,v 1.16 2004/03/22 21:04:36 jmc Exp $
-.\"
-.\" Copyright (c) 2002 Michael Shalayeff
-.\" 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.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 MIND,
-.\" 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.
-.\"
-.Dd November 29, 2002
-.Dt PFSYNC 4
-.Os
-.Sh NAME
-.Nm pfsync
-.Nd packet filter states table logging interface
-.Sh SYNOPSIS
-.Cd "pseudo-device pfsync"
-.Sh DESCRIPTION
-The
-.Nm
-interface is a pseudo-device which exposes certain changes to the state
-table used by
-.Xr pf 4 .
-State changes can be viewed by invoking
-.Xr tcpdump 8
-on the
-.Nm
-interface.
-If configured with a physical synchronisation interface,
-.Nm
-will also send state changes out on that interface using IP multicast,
-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
-.Nm
-over the network are not rebroadcast.
-States created by a rule marked with the
-.Ar no-sync
-keyword are omitted from the
-.Nm
-interface (see
-.Xr pf.conf 5
-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
-.Ar maxupd
-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, defined in
-.Aq Pa net/if_pfsync.h
-looks like:
-.Bd -literal -offset indent
-struct pfsync_header {
- u_int8_t version;
- u_int8_t af;
- u_int8_t action;
- u_int8_t count;
-};
-.Ed
-.Sh NETWORK SYNCHRONISATION
-States can be synchronised between two or more firewalls using this
-interface, by specifying a synchronisation interface using
-.Xr ifconfig 8 .
-For example, the following command sets fxp0 as the synchronisation
-interface.
-.Bd -literal -offset indent
-# ifconfig pfsync0 syncif fxp0
-.Ed
-.Pp
-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.
-.Pp
-It is important that the synchronisation interface be on a trusted
-network as there is no authentication on the protocol and it would
-be trivial to spoof packets which create states, bypassing the pf ruleset.
-Ideally, this is a network dedicated to pfsync messages,
-i.e. a crossover cable between two firewalls.
-.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.
-.Pp
-Both firewalls in this example have three
-.Xr sis 4
-interfaces.
-sis0 is the external interface, on the 10.0.0.0/24 subnet, sis1 is the
-internal interface, on the 192.168.0.0/24 subnet, and sis2 is the
-.Nm
-interface, using the 192.168.254.0/24 subnet.
-A crossover cable connects the two firewalls via their sis2 interfaces.
-On all three interfaces, firewall A uses the .254 address, while firewall B
-uses .253.
-The interfaces are configured as follows (firewall A unless otherwise
-indicated):
-.Pp
-.Pa /etc/hostname.sis0 :
-.Bd -literal -offset indent
-inet 10.0.0.254 255.255.255.0 NONE
-.Ed
-.Pp
-.Pa /etc/hostname.sis1 :
-.Bd -literal -offset indent
-inet 192.168.0.254 255.255.255.0 NONE
-.Ed
-.Pp
-.Pa /etc/hostname.sis2 :
-.Bd -literal -offset indent
-inet 192.168.254.254 255.255.255.0 NONE
-.Ed
-.Pp
-.Pa /etc/hostname.carp0 :
-.Bd -literal -offset indent
-inet 10.0.0.1 255.255.255.0 10.0.0.255 vhid 1 pass foo
-.Ed
-.Pp
-.Pa /etc/hostname.carp1 :
-.Bd -literal -offset indent
-inet 192.168.0.1 255.255.255.0 192.168.0.255 vhid 2 pass bar
-.Ed
-.Pp
-.Pa /etc/hostname.pfsync0 :
-.Bd -literal -offset indent
-up syncif sis2
-.Ed
-.Pp
-.Xr pf 4
-must also be configured to allow
-.Nm
-and
-.Xr carp 4
-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 keep state
-.Ed
-.Pp
-If it is preferable that one firewall handle the traffic,
-the
-.Ar advskew
-on the backup firewall's
-.Xr carp 4
-interfaces should be set to something higher than
-the primary's.
-For example, if firewall B is the backup, its
-.Pa /etc/hostname.carp1
-would look like this:
-.Bd -literal -offset indent
-inet 192.168.0.1 255.255.255.0 192.168.0.255 vhid 2 pass bar \e
- advskew 100
-.Ed
-.Pp
-The following must also be added to
-.Pa /etc/sysctl.conf :
-.Bd -literal -offset indent
-net.inet.carp.preempt=1
-.Ed
-.Sh SEE ALSO
-.Xr bpf 4 ,
-.Xr inet 4 ,
-.Xr inet6 4 ,
-.Xr netintro 4 ,
-.Xr pf 4 ,
-.Xr hostname.if 5 ,
-.Xr pf.conf 5 ,
-.Xr protocols 5 ,
-.Xr ifconfig 8 ,
-.Xr tcpdump 8
-.Sh HISTORY
-The
-.Nm
-device first appeared in
-.Ox 3.3 .
diff --git a/contrib/pf/pflogd/pflogd.8 b/contrib/pf/pflogd/pflogd.8
deleted file mode 100644
index ac8fe78aa0a7..000000000000
--- a/contrib/pf/pflogd/pflogd.8
+++ /dev/null
@@ -1,192 +0,0 @@
-.\" $OpenBSD: pflogd.8,v 1.24 2004/01/16 10:45:49 jmc Exp $
-.\"
-.\" Copyright (c) 2001 Can Erkin Acar. 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.
-.\" 3. The name of the author may not be used to endorse or promote products
-.\" derived from this software without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
-.\"
-.Dd July 9, 2001
-.Dt PFLOGD 8
-.Os
-.Sh NAME
-.Nm pflogd
-.Nd packet filter logging daemon
-.Sh SYNOPSIS
-.Nm pflogd
-.Op Fl Dx
-.Op Fl d Ar delay
-.Op Fl f Ar filename
-.Op Fl s Ar snaplen
-.Op Ar expression
-.Sh DESCRIPTION
-.Nm
-is a background daemon which reads packets logged by
-.Xr pf 4
-to the packet logging interface
-.Pa pflog0
-and writes the packets to a logfile (normally
-.Pa /var/log/pflog )
-in
-.Xr tcpdump 8
-binary format.
-These logs can be reviewed later using the
-.Fl r
-option of
-.Xr tcpdump 8 ,
-hopefully offline in case there are bugs in the packet parsing code of
-.Xr tcpdump 8 .
-.Pp
-.Nm
-closes and then re-opens the log file when it receives
-.Dv SIGHUP ,
-permitting
-.Xr newsyslog 8
-to rotate logfiles automatically.
-.Dv SIGALRM
-causes
-.Nm
-to flush the current logfile buffers to the disk, thus making the most
-recent logs available.
-The buffers are also flushed every
-.Ar delay
-seconds.
-.Pp
-If the log file contains data after a restart or a
-.Dv SIGHUP ,
-new logs are appended to the existing file.
-If the existing log file was created with a different snaplen,
-.Nm
-temporarily uses the old snaplen to keep the log file consistent.
-.Pp
-.Nm
-tries to preserve the integrity of the log file against I/O errors.
-Furthermore, integrity of an existing log file is verified before
-appending.
-If there is an invalid log file or an I/O error, logging is suspended until a
-.Dv SIGHUP
-or a
-.Dv SIGALRM
-is received.
-.Pp
-The options are as follows:
-.Bl -tag -width Ds
-.It Fl D
-Debugging mode.
-.Nm
-does not disassociate from the controlling terminal.
-.It Fl d Ar delay
-Time in seconds to delay between automatic flushes of the file.
-This may be specified with a value between 5 and 3600 seconds.
-If not specified, the default is 60 seconds.
-.It Fl f Ar filename
-Log output filename.
-Default is
-.Pa /var/log/pflog .
-.It Fl s Ar snaplen
-Analyze at most the first
-.Ar snaplen
-bytes of data from each packet rather than the default of 96.
-The default of 96 is adequate for IP, ICMP, TCP, and UDP headers but may
-truncate protocol information for other protocols.
-Other file parsers may desire a higher snaplen.
-.It Fl x
-Check the integrity of an existing log file, and return.
-.It Ar expression
-Selects which packets will be dumped, using the regular language of
-.Xr tcpdump 8 .
-.El
-.Sh FILES
-.Bl -tag -width /var/run/pflogd.pid -compact
-.It Pa /var/run/pflogd.pid
-Process ID of the currently running
-.Nm .
-.It Pa /var/log/pflog
-Default log file.
-.El
-.Sh EXAMPLES
-Log specific tcp packets to a different log file with a large snaplen
-(useful with a log-all rule to dump complete sessions):
-.Bd -literal -offset indent
-# pflogd -s 1600 -f suspicious.log port 80 and host evilhost
-.Ed
-.Pp
-Display binary logs:
-.Bd -literal -offset indent
-# tcpdump -n -e -ttt -r /var/log/pflog
-.Ed
-.Pp
-Display the logs in real time (this does not interfere with the
-operation of
-.Nm ) :
-.Bd -literal -offset indent
-# tcpdump -n -e -ttt -i pflog0
-.Ed
-.Pp
-Tcpdump has been extended to be able to filter on the pfloghdr
-structure defined in
-.Aq Ar net/if_pflog.h .
-Tcpdump can restrict the output
-to packets logged on a specified interface, a rule number, a reason,
-a direction, an IP family or an action.
-.Pp
-.Bl -tag -width "reason match " -compact
-.It ip
-Address family equals IPv4.
-.It ip6
-Address family equals IPv6.
-.It ifname kue0
-Interface name equals "kue0".
-.It on kue0
-Interface name equals "kue0".
-.It rulenum 10
-Rule number equals 10.
-.It reason match
-Reason equals match.
-Also accepts "bad-offset", "fragment", "short", "normalize" and "memory".
-.It action pass
-Action equals pass.
-Also accepts "block".
-.It inbound
-The direction was inbound.
-.It outbound
-The direction was outbound.
-.El
-.Pp
-Display the logs in real time of inbound packets that were blocked on
-the wi0 interface:
-.Bd -literal -offset indent
-# tcpdump -n -e -ttt -i pflog0 inbound and action block and on wi0
-.Ed
-.Sh SEE ALSO
-.Xr pcap 3 ,
-.Xr pf 4 ,
-.Xr pflog 4 ,
-.Xr pf.conf 5 ,
-.Xr newsyslog 8 ,
-.Xr tcpdump 8
-.Sh HISTORY
-The
-.Nm
-command appeared in
-.Ox 3.0 .
-.Sh AUTHORS
-Can Erkin Acar
diff --git a/contrib/pf/pflogd/pflogd.c b/contrib/pf/pflogd/pflogd.c
deleted file mode 100644
index 7e19ae66ebdb..000000000000
--- a/contrib/pf/pflogd/pflogd.c
+++ /dev/null
@@ -1,643 +0,0 @@
-/* $OpenBSD: pflogd.c,v 1.27 2004/02/13 19:01:57 otto Exp $ */
-
-/*
- * Copyright (c) 2001 Theo de Raadt
- * Copyright (c) 2001 Can Erkin Acar
- * 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.
- */
-
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <sys/file.h>
-#include <sys/stat.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <pcap-int.h>
-#include <pcap.h>
-#include <syslog.h>
-#include <signal.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <fcntl.h>
-#include <util.h>
-#include "pflogd.h"
-
-pcap_t *hpcap;
-static FILE *dpcap;
-
-int Debug = 0;
-static int snaplen = DEF_SNAPLEN;
-static int cur_snaplen = DEF_SNAPLEN;
-
-volatile sig_atomic_t gotsig_close, gotsig_alrm, gotsig_hup;
-
-char *filename = PFLOGD_LOG_FILE;
-char *interface = PFLOGD_DEFAULT_IF;
-char *filter = NULL;
-
-char errbuf[PCAP_ERRBUF_SIZE];
-
-int log_debug = 0;
-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 *);
-int flush_buffer(FILE *);
-int init_pcap(void);
-void logmsg(int, const char *, ...);
-void purge_buffer(void);
-int reset_dump(void);
-int scan_dump(FILE *, off_t);
-int set_snaplen(int);
-void set_suspended(int);
-void sig_alrm(int);
-void sig_close(int);
-void sig_hup(int);
-void usage(void);
-
-/* buffer must always be greater than snaplen */
-static int bufpkt = 0; /* number of packets in buffer */
-static int buflen = 0; /* allocated size of buffer */
-static char *buffer = NULL; /* packet buffer */
-static char *bufpos = NULL; /* position in buffer */
-static int bufleft = 0; /* bytes left in buffer */
-
-/* if error, stop logging but count dropped packets */
-static int suspended = -1;
-static long packets_dropped = 0;
-
-void
-set_suspended(int s)
-{
- if (suspended == s)
- return;
-
- suspended = s;
- setproctitle("[%s] -s %d -f %s",
- suspended ? "suspended" : "running", cur_snaplen, filename);
-}
-
-char *
-copy_argv(char * const *argv)
-{
- size_t len = 0, n;
- char *buf;
-
- if (argv == NULL)
- return (NULL);
-
- for (n = 0; argv[n]; n++)
- len += strlen(argv[n])+1;
- if (len == 0)
- return (NULL);
-
- buf = malloc(len);
- if (buf == NULL)
- return (NULL);
-
- strlcpy(buf, argv[0], len);
- for (n = 1; argv[n]; n++) {
- strlcat(buf, " ", len);
- strlcat(buf, argv[n], len);
- }
- return (buf);
-}
-
-void
-logmsg(int pri, const char *message, ...)
-{
- va_list ap;
- va_start(ap, message);
-
- if (log_debug) {
- vfprintf(stderr, message, ap);
- fprintf(stderr, "\n");
- } else
- vsyslog(pri, message, ap);
- va_end(ap);
-}
-
-__dead void
-usage(void)
-{
- fprintf(stderr, "usage: pflogd [-Dx] [-d delay] [-f filename] ");
- fprintf(stderr, "[-s snaplen] [expression]\n");
- exit(1);
-}
-
-void
-sig_close(int sig)
-{
- gotsig_close = 1;
-}
-
-void
-sig_hup(int sig)
-{
- gotsig_hup = 1;
-}
-
-void
-sig_alrm(int sig)
-{
- gotsig_alrm = 1;
-}
-
-void
-set_pcap_filter(void)
-{
- struct bpf_program bprog;
-
- if (pcap_compile(hpcap, &bprog, filter, PCAP_OPT_FIL, 0) < 0)
- logmsg(LOG_WARNING, "%s", pcap_geterr(hpcap));
- else {
- if (pcap_setfilter(hpcap, &bprog) < 0)
- logmsg(LOG_WARNING, "%s", pcap_geterr(hpcap));
- pcap_freecode(&bprog);
- }
-}
-
-int
-init_pcap(void)
-{
- hpcap = pcap_open_live(interface, snaplen, 1, PCAP_TO_MS, errbuf);
- if (hpcap == NULL) {
- logmsg(LOG_ERR, "Failed to initialize: %s", errbuf);
- return (-1);
- }
-
- if (pcap_datalink(hpcap) != DLT_PFLOG) {
- logmsg(LOG_ERR, "Invalid datalink type");
- pcap_close(hpcap);
- hpcap = NULL;
- return (-1);
- }
-
- set_pcap_filter();
-
- cur_snaplen = snaplen = pcap_snapshot(hpcap);
-
- /* lock */
- if (ioctl(pcap_fileno(hpcap), BIOCLOCK) < 0) {
- logmsg(LOG_ERR, "BIOCLOCK: %s", strerror(errno));
- return (-1);
- }
-
- return (0);
-}
-
-int
-set_snaplen(int snap)
-{
- if (priv_set_snaplen(snap))
- return (1);
-
- if (cur_snaplen > snap)
- purge_buffer();
-
- cur_snaplen = snap;
-
- return (0);
-}
-
-int
-reset_dump(void)
-{
- struct pcap_file_header hdr;
- struct stat st;
- int fd;
- FILE *fp;
-
- if (hpcap == NULL)
- return (-1);
-
- if (dpcap) {
- flush_buffer(dpcap);
- fclose(dpcap);
- dpcap = NULL;
- }
-
- /*
- * Basically reimplement pcap_dump_open() because it truncates
- * files and duplicates headers and such.
- */
- fd = priv_open_log();
- if (fd < 0)
- return (1);
-
- fp = fdopen(fd, "a+");
-
- if (fp == NULL) {
- logmsg(LOG_ERR, "Error: %s: %s", filename, strerror(errno));
- return (1);
- }
- if (fstat(fileno(fp), &st) == -1) {
- logmsg(LOG_ERR, "Error: %s: %s", filename, strerror(errno));
- return (1);
- }
-
- /* set FILE unbuffered, we do our own buffering */
- if (setvbuf(fp, NULL, _IONBF, 0)) {
- logmsg(LOG_ERR, "Failed to set output buffers");
- return (1);
- }
-
-#define TCPDUMP_MAGIC 0xa1b2c3d4
-
- if (st.st_size == 0) {
- if (snaplen != cur_snaplen) {
- logmsg(LOG_NOTICE, "Using snaplen %d", snaplen);
- if (set_snaplen(snaplen)) {
- logmsg(LOG_WARNING,
- "Failed, using old settings");
- }
- }
- hdr.magic = TCPDUMP_MAGIC;
- hdr.version_major = PCAP_VERSION_MAJOR;
- hdr.version_minor = PCAP_VERSION_MINOR;
- hdr.thiszone = hpcap->tzoff;
- hdr.snaplen = hpcap->snapshot;
- hdr.sigfigs = 0;
- hdr.linktype = hpcap->linktype;
-
- if (fwrite((char *)&hdr, sizeof(hdr), 1, fp) != 1) {
- fclose(fp);
- return (1);
- }
- } else if (scan_dump(fp, st.st_size)) {
- /* XXX move file and continue? */
- fclose(fp);
- return (1);
- }
-
- dpcap = fp;
-
- set_suspended(0);
- flush_buffer(fp);
-
- return (0);
-}
-
-int
-scan_dump(FILE *fp, off_t size)
-{
- struct pcap_file_header hdr;
- struct pcap_pkthdr ph;
- off_t pos;
-
- /*
- * Must read the file, compare the header against our new
- * options (in particular, snaplen) and adjust our options so
- * that we generate a correct file. Furthermore, check the file
- * for consistency so that we can append safely.
- *
- * XXX this may take a long time for large logs.
- */
- (void) fseek(fp, 0L, SEEK_SET);
-
- if (fread((char *)&hdr, sizeof(hdr), 1, fp) != 1) {
- logmsg(LOG_ERR, "Short file header");
- return (1);
- }
-
- if (hdr.magic != TCPDUMP_MAGIC ||
- hdr.version_major != PCAP_VERSION_MAJOR ||
- hdr.version_minor != PCAP_VERSION_MINOR ||
- hdr.linktype != hpcap->linktype ||
- hdr.snaplen > PFLOGD_MAXSNAPLEN) {
- logmsg(LOG_ERR, "Invalid/incompatible log file, move it away");
- return (1);
- }
-
- pos = sizeof(hdr);
-
- while (!feof(fp)) {
- off_t len = fread((char *)&ph, 1, sizeof(ph), fp);
- if (len == 0)
- break;
-
- if (len != sizeof(ph))
- goto error;
- if (ph.caplen > hdr.snaplen || ph.caplen > PFLOGD_MAXSNAPLEN)
- goto error;
- pos += sizeof(ph) + ph.caplen;
- if (pos > size)
- goto error;
- fseek(fp, ph.caplen, SEEK_CUR);
- }
-
- if (pos != size)
- goto error;
-
- if (hdr.snaplen != cur_snaplen) {
- logmsg(LOG_WARNING,
- "Existing file has different snaplen %u, using it",
- hdr.snaplen);
- if (set_snaplen(hdr.snaplen)) {
- logmsg(LOG_WARNING,
- "Failed, using old settings, offset %llu",
- (unsigned long long) size);
- }
- }
-
- return (0);
-
- error:
- logmsg(LOG_ERR, "Corrupted log file.");
- return (1);
-}
-
-/* dump a packet directly to the stream, which is unbuffered */
-void
-dump_packet_nobuf(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
-{
- FILE *f = (FILE *)user;
-
- if (suspended) {
- packets_dropped++;
- return;
- }
-
- if (fwrite((char *)h, sizeof(*h), 1, f) != 1) {
- /* try to undo header to prevent corruption */
- off_t pos = ftello(f);
- if (pos < sizeof(*h) ||
- ftruncate(fileno(f), pos - sizeof(*h))) {
- logmsg(LOG_ERR, "Write failed, corrupted logfile!");
- set_suspended(1);
- gotsig_close = 1;
- return;
- }
- goto error;
- }
-
- if (fwrite((char *)sp, h->caplen, 1, f) != 1)
- goto error;
-
- return;
-
-error:
- set_suspended(1);
- packets_dropped ++;
- logmsg(LOG_ERR, "Logging suspended: fwrite: %s", strerror(errno));
-}
-
-int
-flush_buffer(FILE *f)
-{
- off_t offset;
- int len = bufpos - buffer;
-
- if (len <= 0)
- return (0);
-
- offset = ftello(f);
- if (offset == (off_t)-1) {
- set_suspended(1);
- logmsg(LOG_ERR, "Logging suspended: ftello: %s",
- strerror(errno));
- return (1);
- }
-
- if (fwrite(buffer, len, 1, f) != 1) {
- set_suspended(1);
- logmsg(LOG_ERR, "Logging suspended: fwrite: %s",
- strerror(errno));
- ftruncate(fileno(f), offset);
- return (1);
- }
-
- set_suspended(0);
- bufpos = buffer;
- bufleft = buflen;
- bufpkt = 0;
-
- return (0);
-}
-
-void
-purge_buffer(void)
-{
- packets_dropped += bufpkt;
-
- set_suspended(0);
- bufpos = buffer;
- bufleft = buflen;
- bufpkt = 0;
-}
-
-/* append packet to the buffer, flushing if necessary */
-void
-dump_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
-{
- FILE *f = (FILE *)user;
- size_t len = sizeof(*h) + h->caplen;
-
- if (len < sizeof(*h) || h->caplen > (size_t)cur_snaplen) {
- logmsg(LOG_NOTICE, "invalid size %u (%u/%u), packet dropped",
- len, cur_snaplen, snaplen);
- packets_dropped++;
- return;
- }
-
- if (len <= bufleft)
- goto append;
-
- if (suspended) {
- packets_dropped++;
- return;
- }
-
- if (flush_buffer(f)) {
- packets_dropped++;
- return;
- }
-
- if (len > bufleft) {
- dump_packet_nobuf(user, h, sp);
- return;
- }
-
- append:
- memcpy(bufpos, h, sizeof(*h));
- memcpy(bufpos + sizeof(*h), sp, h->caplen);
-
- bufpos += len;
- bufleft -= len;
- bufpkt++;
-
- return;
-}
-
-int
-main(int argc, char **argv)
-{
- struct pcap_stat pstat;
- int ch, np, Xflag = 0;
- pcap_handler phandler = dump_packet;
-
- closefrom(STDERR_FILENO + 1);
-
- while ((ch = getopt(argc, argv, "Dxd:s:f:")) != -1) {
- switch (ch) {
- case 'D':
- Debug = 1;
- break;
- case 'd':
- delay = atoi(optarg);
- if (delay < 5 || delay > 60*60)
- usage();
- break;
- case 'f':
- filename = optarg;
- break;
- case 's':
- snaplen = atoi(optarg);
- if (snaplen <= 0)
- snaplen = DEF_SNAPLEN;
- if (snaplen > PFLOGD_MAXSNAPLEN)
- snaplen = PFLOGD_MAXSNAPLEN;
- break;
- case 'x':
- Xflag++;
- break;
- default:
- usage();
- }
-
- }
-
- log_debug = Debug;
- argc -= optind;
- argv += optind;
-
- 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);
- }
-
- (void)umask(S_IRWXG | S_IRWXO);
-
- /* filter will be used by the privileged process */
- if (argc) {
- filter = copy_argv(argv);
- if (filter == NULL)
- logmsg(LOG_NOTICE, "Failed to form filter expression");
- }
-
- /* initialize pcap before dropping privileges */
- if (init_pcap()) {
- logmsg(LOG_ERR, "Exiting, init failure");
- exit(1);
- }
-
- /* Privilege separation begins here */
- if (priv_init()) {
- logmsg(LOG_ERR, "unable to privsep");
- exit(1);
- }
-
- setproctitle("[initializing]");
- /* Process is now unprivileged and inside a chroot */
- signal(SIGTERM, sig_close);
- signal(SIGINT, sig_close);
- signal(SIGQUIT, sig_close);
- signal(SIGALRM, sig_alrm);
- signal(SIGHUP, sig_hup);
- alarm(delay);
-
- buffer = malloc(PFLOGD_BUFSIZE);
-
- if (buffer == NULL) {
- logmsg(LOG_WARNING, "Failed to allocate output buffer");
- phandler = dump_packet_nobuf;
- } else {
- bufleft = buflen = PFLOGD_BUFSIZE;
- bufpos = buffer;
- bufpkt = 0;
- }
-
- if (reset_dump()) {
- if (Xflag)
- return (1);
-
- logmsg(LOG_ERR, "Logging suspended: open error");
- set_suspended(1);
- } else if (Xflag)
- return (0);
-
- while (1) {
- np = pcap_dispatch(hpcap, PCAP_NUM_PKTS,
- dump_packet, (u_char *)dpcap);
- if (np < 0)
- logmsg(LOG_NOTICE, "%s", pcap_geterr(hpcap));
-
- if (gotsig_close)
- break;
- if (gotsig_hup) {
- if (reset_dump()) {
- logmsg(LOG_ERR,
- "Logging suspended: open error");
- set_suspended(1);
- }
- gotsig_hup = 0;
- }
-
- if (gotsig_alrm) {
- if (dpcap)
- flush_buffer(dpcap);
- gotsig_alrm = 0;
- alarm(delay);
- }
- }
-
- logmsg(LOG_NOTICE, "Exiting");
- if (dpcap) {
- flush_buffer(dpcap);
- fclose(dpcap);
- }
- 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);
-
- pcap_close(hpcap);
- if (!Debug)
- closelog();
- return (0);
-}
diff --git a/contrib/pf/pflogd/pflogd.h b/contrib/pf/pflogd/pflogd.h
deleted file mode 100644
index 3baecb66fe67..000000000000
--- a/contrib/pf/pflogd/pflogd.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* $OpenBSD: pflogd.h,v 1.2 2004/01/15 20:15:14 canacar Exp $ */
-
-/*
- * Copyright (c) 2003 Can Erkin Acar
- *
- * 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.
- */
-
-#include <sys/limits.h>
-#include <pcap.h>
-
-#define DEF_SNAPLEN 116 /* default plus allow for larger header of pflog */
-#define PCAP_TO_MS 500 /* pcap read timeout (ms) */
-#define PCAP_NUM_PKTS 1000 /* max number of packets to process at each loop */
-#define PCAP_OPT_FIL 1 /* filter optimization */
-#define FLUSH_DELAY 60 /* flush delay */
-
-#define PFLOGD_LOG_FILE "/var/log/pflog"
-#define PFLOGD_DEFAULT_IF "pflog0"
-
-#define PFLOGD_MAXSNAPLEN INT_MAX
-#define PFLOGD_BUFSIZE 65536 /* buffer size for incoming packets */
-
-void logmsg(int priority, const char *message, ...);
-
-/* Privilege separation */
-int priv_init(void);
-int priv_set_snaplen(int snaplen);
-int priv_open_log(void);
-pcap_t *pcap_open_live_fd(int fd, int snaplen, char *ebuf);
-
-void set_pcap_filter(void);
-/* File descriptor send/recv */
-void send_fd(int, int);
-int receive_fd(int);
-
-extern int Debug;
diff --git a/contrib/pf/pflogd/pidfile.c b/contrib/pf/pflogd/pidfile.c
deleted file mode 100644
index 61eca262efe2..000000000000
--- a/contrib/pf/pflogd/pidfile.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/* $OpenBSD: pidfile.c,v 1.5 2002/05/26 09:29:02 deraadt Exp $ */
-/* $NetBSD: pidfile.c,v 1.4 2001/02/19 22:43:42 cgd Exp $ */
-
-/*-
- * Copyright (c) 1999 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Jason R. Thorpe.
- *
- * 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.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$OpenBSD: pidfile.c,v 1.5 2002/05/26 09:29:02 deraadt Exp $";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/param.h>
-#include <errno.h>
-#include <paths.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#if defined(__FreeBSD__)
-#include "pidfile.h"
-#else
-#include <util.h>
-#endif
-
-static char *pidfile_path;
-static pid_t pidfile_pid;
-
-static void pidfile_cleanup(void);
-
-extern char *__progname;
-
-int
-pidfile(const char *basename)
-{
- FILE *f;
- int save_errno;
- pid_t pid;
-
- if (basename == NULL)
- basename = __progname;
-
- if (pidfile_path != NULL) {
- free(pidfile_path);
- pidfile_path = NULL;
- }
-
- /* _PATH_VARRUN includes trailing / */
- (void) asprintf(&pidfile_path, "%s%s.pid", _PATH_VARRUN, basename);
- if (pidfile_path == NULL)
- return (-1);
-
- if ((f = fopen(pidfile_path, "w")) == NULL) {
- save_errno = errno;
- free(pidfile_path);
- pidfile_path = NULL;
- errno = save_errno;
- return (-1);
- }
-
- pid = getpid();
- if (fprintf(f, "%ld\n", (long)pid) <= 0 || fclose(f) != 0) {
- save_errno = errno;
- (void) unlink(pidfile_path);
- free(pidfile_path);
- pidfile_path = NULL;
- errno = save_errno;
- return (-1);
- }
-
- pidfile_pid = pid;
- if (atexit(pidfile_cleanup) < 0) {
- save_errno = errno;
- (void) unlink(pidfile_path);
- free(pidfile_path);
- pidfile_path = NULL;
- pidfile_pid = 0;
- errno = save_errno;
- return (-1);
- }
-
- return (0);
-}
-
-static void
-pidfile_cleanup(void)
-{
-
- if (pidfile_path != NULL && pidfile_pid == getpid())
- (void) unlink(pidfile_path);
-}
diff --git a/contrib/pf/pflogd/pidfile.h b/contrib/pf/pflogd/pidfile.h
deleted file mode 100644
index 542325fdcdad..000000000000
--- a/contrib/pf/pflogd/pidfile.h
+++ /dev/null
@@ -1 +0,0 @@
-int pidfile(const char *);
diff --git a/contrib/pf/pflogd/privsep.c b/contrib/pf/pflogd/privsep.c
deleted file mode 100644
index 50807ada4e45..000000000000
--- a/contrib/pf/pflogd/privsep.c
+++ /dev/null
@@ -1,305 +0,0 @@
-/* $OpenBSD: privsep.c,v 1.8 2004/03/14 19:17:05 otto Exp $ */
-
-/*
- * Copyright (c) 2003 Can Erkin Acar
- * Copyright (c) 2003 Anil Madhavapeddy <anil@recoil.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.
- */
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-
-#include <net/if.h>
-#include <net/bpf.h>
-
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <pcap.h>
-#include <pcap-int.h>
-#include <pwd.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <syslog.h>
-#include <unistd.h>
-#include "pflogd.h"
-
-enum cmd_types {
- PRIV_SET_SNAPLEN, /* set the snaplength */
- PRIV_OPEN_LOG /* open logfile for appending */
-};
-
-static int priv_fd = -1;
-static volatile pid_t child_pid = -1;
-
-volatile sig_atomic_t gotsig_chld = 0;
-
-static void sig_pass_to_chld(int);
-static void sig_chld(int);
-static int may_read(int, void *, size_t);
-static void must_read(int, void *, size_t);
-static void must_write(int, void *, size_t);
-static int set_snaplen(int snap);
-
-/* bpf filter expression common to parent and child */
-extern char *filter;
-extern char *errbuf;
-extern char *filename;
-extern pcap_t *hpcap;
-
-/* based on syslogd privsep */
-int
-priv_init(void)
-{
- int i, fd, socks[2], cmd;
- int snaplen, ret;
- struct passwd *pw;
-
- for (i = 1; i < _NSIG; i++)
- signal(i, SIG_DFL);
-
- /* Create sockets */
- if (socketpair(AF_LOCAL, SOCK_STREAM, PF_UNSPEC, socks) == -1)
- err(1, "socketpair() failed");
-
- pw = getpwnam("_pflogd");
- if (pw == NULL)
- errx(1, "unknown user _pflogd");
- endpwent();
-
- child_pid = fork();
- if (child_pid < 0)
- err(1, "fork() failed");
-
- if (!child_pid) {
- gid_t gidset[1];
-
- /* Child - drop privileges and return */
- if (chroot(pw->pw_dir) != 0)
- err(1, "unable to chroot");
- if (chdir("/") != 0)
- err(1, "unable to chdir");
-
- gidset[0] = pw->pw_gid;
- if (setgroups(1, gidset) == -1)
- err(1, "setgroups() failed");
- if (setegid(pw->pw_gid) == -1)
- err(1, "setegid() failed");
- if (setgid(pw->pw_gid) == -1)
- err(1, "setgid() failed");
- if (seteuid(pw->pw_uid) == -1)
- err(1, "seteuid() failed");
- if (setuid(pw->pw_uid) == -1)
- err(1, "setuid() failed");
- close(socks[0]);
- priv_fd = socks[1];
- return 0;
- }
-
- /* Father */
- /* Pass ALRM/TERM/HUP through to child, and accept CHLD */
- signal(SIGALRM, sig_pass_to_chld);
- signal(SIGTERM, sig_pass_to_chld);
- signal(SIGHUP, sig_pass_to_chld);
- signal(SIGCHLD, sig_chld);
-
- setproctitle("[priv]");
- close(socks[1]);
-
- while (!gotsig_chld) {
- if (may_read(socks[0], &cmd, sizeof(int)))
- break;
- switch (cmd) {
- case PRIV_SET_SNAPLEN:
- logmsg(LOG_DEBUG,
- "[priv]: msg PRIV_SET_SNAPLENGTH received");
- must_read(socks[0], &snaplen, sizeof(int));
-
- ret = set_snaplen(snaplen);
- if (ret) {
- logmsg(LOG_NOTICE,
- "[priv]: set_snaplen failed for snaplen %d",
- snaplen);
- }
-
- must_write(socks[0], &ret, sizeof(int));
- break;
-
- case PRIV_OPEN_LOG:
- logmsg(LOG_DEBUG,
- "[priv]: msg PRIV_OPEN_LOG received");
- /* create or append logs but do not follow symlinks */
- fd = open(filename,
- O_RDWR|O_CREAT|O_APPEND|O_NONBLOCK|O_NOFOLLOW,
- 0600);
- if (fd < 0)
- logmsg(LOG_NOTICE,
- "[priv]: failed to open %s: %s",
- filename, strerror(errno));
- send_fd(socks[0], fd);
- close(fd);
- break;
-
- default:
- logmsg(LOG_ERR, "[priv]: unknown command %d", cmd);
- _exit(1);
- /* NOTREACHED */
- }
- }
-
- _exit(1);
-}
-
-/* this is called from parent */
-static int
-set_snaplen(int snap)
-{
- if (hpcap == NULL)
- return (1);
-
- hpcap->snapshot = snap;
- set_pcap_filter();
-
- return 0;
-}
-
-
-/*
- * send the snaplength to privileged process
- */
-int
-priv_set_snaplen(int snaplen)
-{
- int cmd, ret;
-
- if (priv_fd < 0)
- errx(1, "%s: called from privileged portion", __func__);
-
- cmd = PRIV_SET_SNAPLEN;
-
- must_write(priv_fd, &cmd, sizeof(int));
- must_write(priv_fd, &snaplen, sizeof(int));
-
- must_read(priv_fd, &ret, sizeof(int));
-
- /* also set hpcap->snapshot in child */
- if (ret == 0)
- hpcap->snapshot = snaplen;
-
- return (ret);
-}
-
-/* Open log-file */
-int
-priv_open_log(void)
-{
- int cmd, fd;
-
- if (priv_fd < 0)
- errx(1, "%s: called from privileged portion\n", __func__);
-
- cmd = PRIV_OPEN_LOG;
- must_write(priv_fd, &cmd, sizeof(int));
- fd = receive_fd(priv_fd);
-
- return (fd);
-}
-
-/* If priv parent gets a TERM or HUP, pass it through to child instead */
-static void
-sig_pass_to_chld(int sig)
-{
- int oerrno = errno;
-
- if (child_pid != -1)
- kill(child_pid, sig);
- errno = oerrno;
-}
-
-/* if parent gets a SIGCHLD, it will exit */
-static void
-sig_chld(int sig)
-{
- gotsig_chld = 1;
-}
-
-/* Read all data or return 1 for error. */
-static int
-may_read(int fd, void *buf, size_t n)
-{
- char *s = buf;
- ssize_t res, pos = 0;
-
- while (n > pos) {
- res = read(fd, s + pos, n - pos);
- switch (res) {
- case -1:
- if (errno == EINTR || errno == EAGAIN)
- continue;
- case 0:
- return (1);
- default:
- pos += res;
- }
- }
- return (0);
-}
-
-/* Read data with the assertion that it all must come through, or
- * else abort the process. Based on atomicio() from openssh. */
-static void
-must_read(int fd, void *buf, size_t n)
-{
- char *s = buf;
- ssize_t res, pos = 0;
-
- while (n > pos) {
- res = read(fd, s + pos, n - pos);
- switch (res) {
- case -1:
- if (errno == EINTR || errno == EAGAIN)
- continue;
- case 0:
- _exit(0);
- default:
- pos += res;
- }
- }
-}
-
-/* Write data with the assertion that it all has to be written, or
- * else abort the process. Based on atomicio() from openssh. */
-static void
-must_write(int fd, void *buf, size_t n)
-{
- char *s = buf;
- ssize_t res, pos = 0;
-
- while (n > pos) {
- res = write(fd, s + pos, n - pos);
- switch (res) {
- case -1:
- if (errno == EINTR || errno == EAGAIN)
- continue;
- case 0:
- _exit(0);
- default:
- pos += res;
- }
- }
-}
diff --git a/contrib/pf/pflogd/privsep_fdpass.c b/contrib/pf/pflogd/privsep_fdpass.c
deleted file mode 100644
index 166b6930b3bd..000000000000
--- a/contrib/pf/pflogd/privsep_fdpass.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/* $OpenBSD: privsep_fdpass.c,v 1.1 2003/10/22 18:51:55 canacar Exp $ */
-
-/*
- * Copyright 2001 Niels Provos <provos@citi.umich.edu>
- * All rights reserved.
- *
- * Copyright (c) 2002 Matthieu Herrb
- * 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.
- */
-#include <sys/param.h>
-#include <sys/uio.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include "pflogd.h"
-
-void
-send_fd(int sock, int fd)
-{
- struct msghdr msg;
- char tmp[CMSG_SPACE(sizeof(int))];
- struct cmsghdr *cmsg;
- struct iovec vec;
- int result = 0;
- ssize_t n;
-
- memset(&msg, 0, sizeof(msg));
-
- if (fd >= 0) {
- msg.msg_control = (caddr_t)tmp;
- msg.msg_controllen = CMSG_LEN(sizeof(int));
- cmsg = CMSG_FIRSTHDR(&msg);
- cmsg->cmsg_len = CMSG_LEN(sizeof(int));
- cmsg->cmsg_level = SOL_SOCKET;
- cmsg->cmsg_type = SCM_RIGHTS;
- *(int *)CMSG_DATA(cmsg) = fd;
- } else {
- result = errno;
- }
-
- vec.iov_base = &result;
- vec.iov_len = sizeof(int);
- msg.msg_iov = &vec;
- msg.msg_iovlen = 1;
-
- if ((n = sendmsg(sock, &msg, 0)) == -1)
- warn("%s: sendmsg(%d)", __func__, sock);
- if (n != sizeof(int))
- warnx("%s: sendmsg: expected sent 1 got %ld",
- __func__, (long)n);
-}
-
-int
-receive_fd(int sock)
-{
- struct msghdr msg;
- char tmp[CMSG_SPACE(sizeof(int))];
- struct cmsghdr *cmsg;
- struct iovec vec;
- ssize_t n;
- int result;
- int fd;
-
- memset(&msg, 0, sizeof(msg));
- vec.iov_base = &result;
- vec.iov_len = sizeof(int);
- msg.msg_iov = &vec;
- msg.msg_iovlen = 1;
- msg.msg_control = tmp;
- msg.msg_controllen = sizeof(tmp);
-
- if ((n = recvmsg(sock, &msg, 0)) == -1)
- warn("%s: recvmsg", __func__);
- if (n != sizeof(int))
- warnx("%s: recvmsg: expected received 1 got %ld",
- __func__, (long)n);
- if (result == 0) {
- cmsg = CMSG_FIRSTHDR(&msg);
- if (cmsg->cmsg_type != SCM_RIGHTS)
- warnx("%s: expected type %d got %d", __func__,
- SCM_RIGHTS, cmsg->cmsg_type);
- fd = (*(int *)CMSG_DATA(cmsg));
- return fd;
- } else {
- errno = result;
- return -1;
- }
-}