summaryrefslogtreecommitdiffstats
path: root/share
diff options
context:
space:
mode:
authorglebius <glebius@FreeBSD.org>2012-09-14 11:51:49 +0000
committerglebius <glebius@FreeBSD.org>2012-09-14 11:51:49 +0000
commit0ccf4838d7a8b4da2c3beaac7ea1fd977aa0ed11 (patch)
treeec60da6e90cde2e87aa91ac9450c84ce3446233a /share
parentf99fc207edf21e7c05c1147864077ce3fe1f3e2c (diff)
downloadFreeBSD-src-0ccf4838d7a8b4da2c3beaac7ea1fd977aa0ed11.zip
FreeBSD-src-0ccf4838d7a8b4da2c3beaac7ea1fd977aa0ed11.tar.gz
o Create directory sys/netpfil, where all packet filters should
reside, and move there ipfw(4) and pf(4). o Move most modified parts of pf out of contrib. Actual movements: sys/contrib/pf/net/*.c -> sys/netpfil/pf/ sys/contrib/pf/net/*.h -> sys/net/ contrib/pf/pfctl/*.c -> sbin/pfctl contrib/pf/pfctl/*.h -> sbin/pfctl contrib/pf/pfctl/pfctl.8 -> sbin/pfctl contrib/pf/pfctl/*.4 -> share/man/man4 contrib/pf/pfctl/*.5 -> share/man/man5 sys/netinet/ipfw -> sys/netpfil/ipfw The arguable movement is pf/net/*.h -> sys/net. There are future plans to refactor pf includes, so I decided not to break things twice. Not modified bits of pf left in contrib: authpf, ftp-proxy, tftp-proxy, pflogd. The ipfw(4) movement is planned to be merged to stable/9, to make head and stable match. Discussed with: bz, luigi
Diffstat (limited to 'share')
-rw-r--r--share/man/man4/Makefile3
-rw-r--r--share/man/man4/pf.41175
-rw-r--r--share/man/man4/pflog.4107
-rw-r--r--share/man/man4/pfsync.4229
-rw-r--r--share/man/man5/Makefile2
-rw-r--r--share/man/man5/pf.conf.53066
-rw-r--r--share/man/man5/pf.os.5223
7 files changed, 4805 insertions, 0 deletions
diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile
index dded119..7f01768 100644
--- a/share/man/man4/Makefile
+++ b/share/man/man4/Makefile
@@ -354,6 +354,9 @@ MAN= aac.4 \
pcii.4 \
pcm.4 \
pcn.4 \
+ pf.4 \
+ pflog.4 \
+ pfsync.4 \
pim.4 \
polling.4 \
ppbus.4 \
diff --git a/share/man/man4/pf.4 b/share/man/man4/pf.4
new file mode 100644
index 0000000..635078d
--- /dev/null
+++ b/share/man/man4/pf.4
@@ -0,0 +1,1175 @@
+.\" $OpenBSD: pf.4,v 1.62 2008/09/10 14:57:37 jmc 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.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd June 29 2012
+.Dt PF 4
+.Os
+.Sh NAME
+.Nm pf
+.Nd packet filter
+.Sh SYNOPSIS
+.Cd "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
+.Xr ioctl 2
+call require a so-called
+.Em ticket ,
+which prevents the occurrence of
+multiple concurrent manipulations.
+.Pp
+Fields of
+.Xr ioctl 2
+parameter structures that refer to packet data (like
+addresses and ports) are generally expected in network byte-order.
+.Pp
+Rules and address tables are contained in so-called
+.Em anchors .
+When servicing an
+.Xr ioctl 2
+request, if the anchor field of the argument structure is empty,
+the kernel will use the default anchor (i.e., the main ruleset)
+in operations.
+Anchors are specified by name and may be nested, with components
+separated by
+.Sq /
+characters, similar to how file system hierarchies are laid out.
+The final component of the anchor path is the anchor under which
+operations will be performed.
+.Sh SYSCTL VARIABLES AND LOADER TUNABLES
+The following
+.Xr loader 8
+tunables are available.
+.Bl -tag -width indent
+.It Va net.pf.states_hashsize
+Size of hash tables that store states.
+Should be power of 2.
+Default value is 32768.
+.It Va net.pf.source_nodes_hashsize
+Size of hash table that store source nodes.
+Should be power of 2.
+Default value is 8192.
+.El
+.Pp
+Read only
+.Xr sysctl 8
+variables with matching names are provided to obtain current values
+at runtime.
+.Sh IOCTL INTERFACE
+.Nm
+supports the following
+.Xr ioctl 2
+commands, available through
+.Aq Pa net/pfvar.h :
+.Bl -tag -width xxxxxx
+.It Dv DIOCSTART
+Start the packet filter.
+.It Dv DIOCSTOP
+Stop the packet filter.
+.It Dv DIOCSTARTALTQ
+Start the ALTQ bandwidth control system (see
+.Xr altq 9 ) .
+.It Dv DIOCSTOPALTQ
+Stop the ALTQ bandwidth control system.
+.It Dv DIOCBEGINADDRS Fa "struct pfioc_pooladdr *pp"
+.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[MAXPATHLEN];
+ struct pf_pooladdr addr;
+};
+.Ed
+.Pp
+Clear the buffer address pool and get a
+.Va ticket
+for subsequent
+.Dv DIOCADDADDR ,
+.Dv DIOCADDRULE ,
+and
+.Dv DIOCCHANGERULE
+calls.
+.It Dv DIOCADDADDR Fa "struct pfioc_pooladdr *pp"
+.Pp
+Add the pool address
+.Va addr
+to the buffer address pool to be used in the following
+.Dv DIOCADDRULE
+or
+.Dv DIOCCHANGERULE
+call.
+All other members of the structure are ignored.
+.It Dv DIOCADDRULE Fa "struct pfioc_rule *pr"
+.Bd -literal
+struct pfioc_rule {
+ u_int32_t action;
+ u_int32_t ticket;
+ u_int32_t pool_ticket;
+ u_int32_t nr;
+ char anchor[MAXPATHLEN];
+ char anchor_call[MAXPATHLEN];
+ struct pf_rule rule;
+};
+.Ed
+.Pp
+Add
+.Va rule
+at the end of the inactive ruleset.
+This call requires a
+.Va ticket
+obtained through a preceding
+.Dv DIOCXBEGIN
+call and a
+.Va pool_ticket
+obtained through a
+.Dv DIOCBEGINADDRS
+call.
+.Dv DIOCADDADDR
+must also be called if any pool addresses are required.
+The optional
+.Va anchor
+name indicates the anchor in which to append the rule.
+.Va nr
+and
+.Va action
+are ignored.
+.It Dv DIOCADDALTQ Fa "struct pfioc_altq *pa"
+Add an ALTQ discipline or queue.
+.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 *pr"
+Get a
+.Va ticket
+for subsequent
+.Dv DIOCGETRULE
+calls and the number
+.Va nr
+of rules in the active ruleset.
+.It Dv DIOCGETRULE Fa "struct pfioc_rule *pr"
+Get a
+.Va rule
+by its number
+.Va nr
+using the
+.Va ticket
+obtained through a preceding
+.Dv DIOCGETRULES
+call.
+If
+.Va action
+is set to
+.Dv PF_GET_CLR_CNTR ,
+the per-rule statistics on the requested rule are cleared.
+.It Dv DIOCGETADDRS Fa "struct pfioc_pooladdr *pp"
+Get a
+.Va ticket
+for subsequent
+.Dv DIOCGETADDR
+calls and the number
+.Va nr
+of pool addresses in the rule specified with
+.Va r_action ,
+.Va r_num ,
+and
+.Va anchor .
+.It Dv DIOCGETADDR Fa "struct pfioc_pooladdr *pp"
+Get the pool address
+.Va addr
+by its number
+.Va nr
+from the rule specified with
+.Va r_action ,
+.Va r_num ,
+and
+.Va anchor
+using the
+.Va ticket
+obtained through a preceding
+.Dv DIOCGETADDRS
+call.
+.It Dv DIOCGETALTQS Fa "struct pfioc_altq *pa"
+Get a
+.Va ticket
+for subsequent
+.Dv DIOCGETALTQ
+calls and the number
+.Va nr
+of queues in the active list.
+.It Dv DIOCGETALTQ Fa "struct pfioc_altq *pa"
+Get the queueing discipline
+.Va altq
+by its number
+.Va nr
+using the
+.Va ticket
+obtained through a preceding
+.Dv DIOCGETALTQS
+call.
+.It Dv DIOCGETQSTATS Fa "struct pfioc_qstats *pq"
+Get the 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
+This call fills in a pointer to the buffer of statistics
+.Va buf ,
+of length
+.Va nbytes ,
+for the queue specified by
+.Va nr .
+.It Dv DIOCGETRULESETS Fa "struct pfioc_ruleset *pr"
+.Bd -literal
+struct pfioc_ruleset {
+ u_int32_t nr;
+ char path[MAXPATHLEN];
+ char name[PF_ANCHOR_NAME_SIZE];
+};
+.Ed
+.Pp
+Get the number
+.Va nr
+of rulesets (i.e., anchors) directly attached to the anchor named by
+.Va path
+for use in subsequent
+.Dv DIOCGETRULESET
+calls.
+Nested anchors, since they are not directly attached to the given
+anchor, will not be included.
+This ioctl returns
+.Er EINVAL
+if the given anchor does not exist.
+.It Dv DIOCGETRULESET Fa "struct pfioc_ruleset *pr"
+Get a ruleset (i.e., an anchor)
+.Va name
+by its number
+.Va nr
+from the given anchor
+.Va path ,
+the maximum number of which can be obtained from a preceding
+.Dv DIOCGETRULESETS
+call.
+This ioctl returns
+.Er EINVAL
+if the given anchor does not exist or
+.Er EBUSY
+if another process is concurrently updating a ruleset.
+.It Dv DIOCADDSTATE Fa "struct pfioc_state *ps"
+Add a state entry.
+.Bd -literal
+struct pfioc_state {
+ struct pfsync_state state;
+};
+.Ed
+.It Dv DIOCGETSTATE Fa "struct pfioc_state *ps"
+Extract the entry identified by the
+.Va id
+and
+.Va creatorid
+fields of the
+.Va state
+structure from the state table.
+.It Dv DIOCKILLSTATES Fa "struct pfioc_state_kill *psk"
+Remove matching entries from the state table.
+This ioctl returns the number of killed states in
+.Va psk_killed .
+.Bd -literal
+struct pfioc_state_kill {
+ struct pf_state_cmp psk_pfcmp;
+ sa_family_t psk_af;
+ int psk_proto;
+ struct pf_rule_addr psk_src;
+ struct pf_rule_addr psk_dst;
+ char psk_ifname[IFNAMSIZ];
+ char psk_label[PF_RULE_LABEL_SIZE];
+ u_int psk_killed;
+};
+.Ed
+.It Dv DIOCCLRSTATES Fa "struct pfioc_state_kill *psk"
+Clear all states.
+It works like
+.Dv DIOCKILLSTATES ,
+but ignores the
+.Va psk_af ,
+.Va psk_proto ,
+.Va psk_src ,
+and
+.Va psk_dst
+fields of the
+.Vt pfioc_state_kill
+structure.
+.It Dv DIOCSETSTATUSIF Fa "struct pfioc_if *pi"
+Specify the interface for which statistics are accumulated.
+.Bd -literal
+struct pfioc_if {
+ char ifname[IFNAMSIZ];
+};
+.Ed
+.It Dv DIOCGETSTATUS Fa "struct pf_status *s"
+Get the internal packet filter statistics.
+.Bd -literal
+struct pf_status {
+ u_int64_t counters[PFRES_MAX];
+ u_int64_t lcounters[LCNT_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_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];
+ u_int8_t pf_chksum[MD5_DIGEST_LENGTH];
+};
+.Ed
+.It Dv DIOCCLRSTATUS
+Clear the internal packet filter statistics.
+.It Dv DIOCNATLOOK Fa "struct pfioc_natlook *pnl"
+Look 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 *level"
+Set the debug level.
+.Bd -literal
+enum { PF_DEBUG_NONE, PF_DEBUG_URGENT, PF_DEBUG_MISC,
+ PF_DEBUG_NOISY };
+.Ed
+.It Dv DIOCGETSTATES Fa "struct pfioc_states *ps"
+Get state table entries.
+.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
+.Pp
+If
+.Va ps_len
+is non-zero on entry, as many states as possible that can fit into this
+size will be copied into the supplied buffer
+.Va ps_states .
+On exit,
+.Va ps_len
+is always set to the total size required to hold all state table entries
+(i.e., it is set to
+.Li sizeof(struct pf_state) * nr ) .
+.It Dv DIOCCHANGERULE Fa "struct pfioc_rule *pcr"
+Add or remove the
+.Va rule
+in the ruleset specified by
+.Va rule.action .
+.Pp
+The type of operation to be performed is indicated by
+.Va action ,
+which can be any of the following:
+.Bd -literal
+enum { PF_CHANGE_NONE, PF_CHANGE_ADD_HEAD, PF_CHANGE_ADD_TAIL,
+ PF_CHANGE_ADD_BEFORE, PF_CHANGE_ADD_AFTER,
+ PF_CHANGE_REMOVE, PF_CHANGE_GET_TICKET };
+.Ed
+.Pp
+.Va ticket
+must be set to the value obtained with
+.Dv PF_CHANGE_GET_TICKET
+for all actions except
+.Dv PF_CHANGE_GET_TICKET .
+.Va pool_ticket
+must be set to the value obtained with the
+.Dv DIOCBEGINADDRS
+call for all actions except
+.Dv PF_CHANGE_REMOVE
+and
+.Dv PF_CHANGE_GET_TICKET .
+.Va anchor
+indicates to which anchor the operation applies.
+.Va nr
+indicates the rule number against which
+.Dv PF_CHANGE_ADD_BEFORE ,
+.Dv PF_CHANGE_ADD_AFTER ,
+or
+.Dv PF_CHANGE_REMOVE
+actions are applied.
+.\" It Dv DIOCCHANGEALTQ Fa "struct pfioc_altq *pcr"
+.It Dv DIOCCHANGEADDR Fa "struct pfioc_pooladdr *pca"
+Add or remove the pool address
+.Va addr
+from the rule specified by
+.Va r_action ,
+.Va r_num ,
+and
+.Va anchor .
+.It Dv DIOCSETTIMEOUT Fa "struct pfioc_tm *pt"
+.Bd -literal
+struct pfioc_tm {
+ int timeout;
+ int seconds;
+};
+.Ed
+.Pp
+Set the state timeout of
+.Va timeout
+to
+.Va seconds .
+The old value will be placed into
+.Va seconds .
+For possible values of
+.Va timeout ,
+consult the
+.Dv PFTM_*
+values in
+.Aq Pa net/pfvar.h .
+.It Dv DIOCGETTIMEOUT Fa "struct pfioc_tm *pt"
+Get the state timeout of
+.Va timeout .
+The value will be placed into the
+.Va seconds
+field.
+.It Dv DIOCCLRRULECTRS
+Clear per-rule statistics.
+.It Dv DIOCSETLIMIT Fa "struct pfioc_limit *pl"
+Set the hard limits on the memory pools used by the packet filter.
+.Bd -literal
+struct pfioc_limit {
+ int index;
+ unsigned limit;
+};
+
+enum { PF_LIMIT_STATES, PF_LIMIT_SRC_NODES, PF_LIMIT_FRAGS,
+ PF_LIMIT_TABLE_ENTRIES, PF_LIMIT_MAX };
+.Ed
+.It Dv DIOCGETLIMIT Fa "struct pfioc_limit *pl"
+Get the hard
+.Va limit
+for the memory pool indicated by
+.Va index .
+.It Dv DIOCRCLRTABLES Fa "struct pfioc_table *io"
+Clear all tables.
+All the ioctls that manipulate radix tables
+use the same structure described below.
+For
+.Dv DIOCRCLRTABLES ,
+.Va 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;
+ u_int32_t 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 *io"
+Create one or more tables.
+On entry,
+.Va pfrio_buffer
+must point to an array of
+.Vt struct pfr_table
+containing at least
+.Vt pfrio_size
+elements.
+.Vt pfrio_esize
+must be the size of
+.Vt struct pfr_table .
+On exit,
+.Va pfrio_nadd
+contains the number of tables effectively created.
+.Bd -literal
+struct pfr_table {
+ char pfrt_anchor[MAXPATHLEN];
+ 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 *io"
+Delete one or more tables.
+On entry,
+.Va pfrio_buffer
+must point to an array of
+.Vt struct pfr_table
+containing at least
+.Vt pfrio_size
+elements.
+.Vt pfrio_esize
+must be the size of
+.Vt struct pfr_table .
+On exit,
+.Va pfrio_ndel
+contains the number of tables effectively deleted.
+.It Dv DIOCRGETTABLES Fa "struct pfioc_table *io"
+Get the list of all tables.
+On entry,
+.Va pfrio_buffer[pfrio_size]
+contains a valid writeable buffer for
+.Vt pfr_table
+structures.
+On exit,
+.Va 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 *io"
+This call is like
+.Dv DIOCRGETTABLES
+but is used to get an array of
+.Vt 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 *io"
+Clear the statistics of one or more tables.
+On entry,
+.Va pfrio_buffer
+must point to an array of
+.Vt struct pfr_table
+containing at least
+.Vt pfrio_size
+elements.
+.Vt pfrio_esize
+must be the size of
+.Vt struct pfr_table .
+On exit,
+.Va pfrio_nzero
+contains the number of tables effectively cleared.
+.It Dv DIOCRCLRADDRS Fa "struct pfioc_table *io"
+Clear all addresses in a table.
+On entry,
+.Va pfrio_table
+contains the table to clear.
+On exit,
+.Va pfrio_ndel
+contains the number of addresses removed.
+.It Dv DIOCRADDADDRS Fa "struct pfioc_table *io"
+Add one or more addresses to a table.
+On entry,
+.Va pfrio_table
+contains the table ID and
+.Va pfrio_buffer
+must point to an array of
+.Vt struct pfr_addr
+containing at least
+.Vt pfrio_size
+elements to add to the table.
+.Vt pfrio_esize
+must be the size of
+.Vt struct pfr_addr .
+On exit,
+.Va 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 *io"
+Delete one or more addresses from a table.
+On entry,
+.Va pfrio_table
+contains the table ID and
+.Va pfrio_buffer
+must point to an array of
+.Vt struct pfr_addr
+containing at least
+.Vt pfrio_size
+elements to delete from the table.
+.Vt pfrio_esize
+must be the size of
+.Vt struct pfr_addr .
+On exit,
+.Va pfrio_ndel
+contains the number of addresses effectively deleted.
+.It Dv DIOCRSETADDRS Fa "struct pfioc_table *io"
+Replace the content of a table by a new address list.
+This is the most complicated command, which uses all the structure members.
+.Pp
+On entry,
+.Va pfrio_table
+contains the table ID and
+.Va pfrio_buffer
+must point to an array of
+.Vt struct pfr_addr
+containing at least
+.Vt pfrio_size
+elements which become the new contents of the table.
+.Vt pfrio_esize
+must be the size of
+.Vt struct pfr_addr .
+Additionally, if
+.Va pfrio_size2
+is non-zero,
+.Va 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,
+.Va pfrio_ndel ,
+.Va pfrio_nadd ,
+and
+.Va pfrio_nchange
+contain the number of addresses deleted, added, and changed by the
+kernel.
+If
+.Va pfrio_size2
+was set on entry,
+.Va pfrio_size2
+will point to the size of the buffer used, exactly like
+.Dv DIOCRGETADDRS .
+.It Dv DIOCRGETADDRS Fa "struct pfioc_table *io"
+Get all the addresses of a table.
+On entry,
+.Va pfrio_table
+contains the table ID and
+.Va pfrio_buffer[pfrio_size]
+contains a valid writeable buffer for
+.Vt pfr_addr
+structures.
+On exit,
+.Va 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
+returns the required buffer size, without returning an error.
+.It Dv DIOCRGETASTATS Fa "struct pfioc_table *io"
+This call is like
+.Dv DIOCRGETADDRS
+but is used to get an array of
+.Vt 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 *io"
+Clear the statistics of one or more addresses.
+On entry,
+.Va pfrio_table
+contains the table ID and
+.Va pfrio_buffer
+must point to an array of
+.Vt struct pfr_addr
+containing at least
+.Vt pfrio_size
+elements to be cleared from the table.
+.Vt pfrio_esize
+must be the size of
+.Vt struct pfr_addr .
+On exit,
+.Va pfrio_nzero
+contains the number of addresses effectively cleared.
+.It Dv DIOCRTSTADDRS Fa "struct pfioc_table *io"
+Test if the given addresses match a table.
+On entry,
+.Va pfrio_table
+contains the table ID and
+.Va pfrio_buffer
+must point to an array of
+.Vt struct pfr_addr
+containing at least
+.Vt pfrio_size
+elements, each of which will be tested for a match in the table.
+.Vt pfrio_esize
+must be the size of
+.Vt struct pfr_addr .
+On exit, the kernel updates the
+.Vt pfr_addr
+array by setting the
+.Va pfra_fback
+member appropriately.
+.It Dv DIOCRSETTFLAGS Fa "struct pfioc_table *io"
+Change the
+.Dv PFR_TFLAG_CONST
+or
+.Dv PFR_TFLAG_PERSIST
+flags of a table.
+On entry,
+.Va pfrio_buffer
+must point to an array of
+.Vt struct pfr_table
+containing at least
+.Vt pfrio_size
+elements.
+.Va pfrio_esize
+must be the size of
+.Vt struct pfr_table .
+.Va pfrio_setflag
+must contain the flags to add, while
+.Va pfrio_clrflag
+must contain the flags to remove.
+On exit,
+.Va pfrio_nchange
+and
+.Va pfrio_ndel
+contain the number of tables altered or deleted by the kernel.
+Yes, tables can be deleted if one removes the
+.Dv PFR_TFLAG_PERSIST
+flag of an unreferenced table.
+.It Dv DIOCRINADEFINE Fa "struct pfioc_table *io"
+Defines a table in the inactive set.
+On entry,
+.Va pfrio_table
+contains the table ID and
+.Va pfrio_buffer[pfrio_size]
+contains an array of
+.Vt pfr_addr
+structures to put in the table.
+A valid ticket must also be supplied to
+.Va pfrio_ticket .
+On exit,
+.Va pfrio_nadd
+contains 0 if the table was already defined in the inactive list
+or 1 if a new table has been created.
+.Va pfrio_naddr
+contains the number of addresses effectively put in the table.
+.It Dv DIOCXBEGIN Fa "struct pfioc_trans *io"
+.Bd -literal
+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[MAXPATHLEN];
+ u_int32_t ticket;
+ } *array;
+};
+.Ed
+.Pp
+Clear all the inactive rulesets specified in the
+.Vt 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.
+.Pp
+Ruleset types, identified by
+.Va rs_num ,
+include the following:
+.Pp
+.Bl -tag -width PF_RULESET_FILTER -offset ind -compact
+.It Dv PF_RULESET_SCRUB
+Scrub (packet normalization) rules.
+.It Dv PF_RULESET_FILTER
+Filter rules.
+.It Dv PF_RULESET_NAT
+NAT (Network Address Translation) rules.
+.It Dv PF_RULESET_BINAT
+Bidirectional NAT rules.
+.It Dv PF_RULESET_RDR
+Redirect rules.
+.It Dv PF_RULESET_ALTQ
+ALTQ disciplines.
+.It Dv PF_RULESET_TABLE
+Address tables.
+.El
+.It Dv DIOCXCOMMIT Fa "struct pfioc_trans *io"
+Atomically switch a vector of inactive rulesets to the active rulesets.
+This call is implemented as a standard two-phase commit, which will either
+fail for all rulesets or completely succeed.
+All tickets need to be valid.
+This ioctl returns
+.Er EBUSY
+if another process is concurrently updating some of the same rulesets.
+.It Dv DIOCXROLLBACK Fa "struct pfioc_trans *io"
+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 DIOCSETHOSTID Fa "u_int32_t *hostid"
+Set the host ID, which is used by
+.Xr pfsync 4
+to identify which host created state table entries.
+.It Dv DIOCOSFPFLUSH
+Flush the passive OS fingerprint table.
+.It Dv DIOCOSFPADD Fa "struct pf_osfp_ioctl *io"
+.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;
+ pf_tcpopts_t fp_tcpopts;
+ u_int16_t fp_wsize;
+ u_int16_t fp_psize;
+ u_int16_t fp_mss;
+ u_int16_t fp_flags;
+ u_int8_t fp_optcnt;
+ u_int8_t fp_wscale;
+ u_int8_t fp_ttl;
+ 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 ,
+.Va fp_optcnt ,
+and
+.Va fp_wscale
+are set to the TCP MSS, the TCP window size, the IP length, the IP TTL,
+the number of TCP options, and the TCP window scaling constant of the
+TCP SYN packet, respectively.
+.Pp
+The
+.Va fp_flags
+member is filled according to the
+.Aq Pa net/pfvar.h
+include file
+.Dv PF_OSFP_*
+defines.
+The
+.Va fp_tcpopts
+member contains packed TCP options.
+Each option uses
+.Dv PF_OSFP_TCPOPT_BITS
+bits in the packed value.
+Options include any of
+.Dv PF_OSFP_TCPOPT_NOP ,
+.Dv PF_OSFP_TCPOPT_SACK ,
+.Dv PF_OSFP_TCPOPT_WSCALE ,
+.Dv PF_OSFP_TCPOPT_MSS ,
+or
+.Dv PF_OSFP_TCPOPT_TS .
+.Pp
+The
+.Va fp_getnum
+member is not used with this ioctl.
+.Pp
+The structure's slack space must be zeroed for correct operation;
+.Xr memset 3
+the whole structure to zero before filling and sending to the kernel.
+.It Dv DIOCOSFPGET Fa "struct pf_osfp_ioctl *io"
+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
+.Er EBUSY .
+.It Dv DIOCGETSRCNODES Fa "struct pfioc_src_nodes *psn"
+.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 sticky addresses and source
+tracking.
+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 that call,
+.Va psn_len
+will be set to the length of the buffer actually used.
+.It Dv DIOCCLRSRCNODES
+Clear the tree of source tracking nodes.
+.It Dv DIOCIGETIFACES Fa "struct pfioc_iface *io"
+Get 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;
+};
+.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
+contains the number of
+.Vt pfi_kif
+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
+.Li sizeof(struct pfi_kif) .
+.Pp
+The data is returned in the
+.Vt pfi_kif
+structure described below:
+.Bd -literal
+struct pfi_kif {
+ RB_ENTRY(pfi_kif) pfik_tree;
+ char pfik_name[IFNAMSIZ];
+ u_int64_t pfik_packets[2][2][2];
+ u_int64_t pfik_bytes[2][2][2];
+ u_int32_t pfik_tzero;
+ int pfik_flags;
+ struct pf_state_tree_lan_ext pfik_lan_ext;
+ struct pf_state_tree_ext_gwy pfik_ext_gwy;
+ TAILQ_ENTRY(pfi_kif) pfik_w_states;
+ void *pfik_ah_cookie;
+ struct ifnet *pfik_ifp;
+ struct ifg_group *pfik_group;
+ int pfik_states;
+ int pfik_rules;
+ TAILQ_HEAD(, pfi_dynaddr) pfik_dynaddrs;
+};
+.Ed
+.It Dv DIOCSETIFFLAG Fa "struct pfioc_iface *io"
+Set the user setable flags (described above) of the
+.Nm
+internal interface description.
+The filtering process is the same as for
+.Dv DIOCIGETIFACES .
+.Bd -literal
+#define PFI_IFLAG_SKIP 0x0100 /* skip filtering on interface */
+.Ed
+.It Dv DIOCCLRIFFLAG Fa "struct pfioc_iface *io"
+Works as
+.Dv DIOCSETIFFLAG
+above but clears the flags.
+.It Dv DIOCKILLSRCNODES Fa "struct pfioc_iface *io"
+Explicitly remove source tracking nodes.
+.El
+.Sh FILES
+.Bl -tag -width /dev/pf -compact
+.It Pa /dev/pf
+packet filtering device.
+.El
+.Sh EXAMPLES
+The following example demonstrates how to use the
+.Dv 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 altq 4 ,
+.Xr if_bridge 4 ,
+.Xr pflog 4 ,
+.Xr pflow 4 ,
+.Xr pfsync 4 ,
+.Xr pfctl 8 ,
+.Xr altq 9
+.Sh HISTORY
+The
+.Nm
+packet filtering mechanism first appeared in
+.Ox 3.0
+and then
+.Fx 5.2 .
+.Pp
+This implementation matches
+.Ox 4.5 .
diff --git a/share/man/man4/pflog.4 b/share/man/man4/pflog.4
new file mode 100644
index 0000000..c1039a3
--- /dev/null
+++ b/share/man/man4/pflog.4
@@ -0,0 +1,107 @@
+.\" $OpenBSD: pflog.4,v 1.10 2007/05/31 19:19:51 jmc 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.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd May 31 2007
+.Dt PFLOG 4
+.Os
+.Sh NAME
+.Nm pflog
+.Nd packet filter logging interface
+.Sh SYNOPSIS
+.Cd "device pflog"
+.Sh DESCRIPTION
+The
+.Nm pflog
+interface is a device which makes visible all packets logged by
+the packet filter,
+.Xr pf 4 .
+Logged packets can easily be monitored in real
+time by invoking
+.Xr tcpdump 1
+on the
+.Nm
+interface, or stored to disk using
+.Xr pflogd 8 .
+.Pp
+The pflog0 interface is created automatically at boot if both
+.Xr pf 4
+and
+.Xr pflogd 8
+are enabled;
+further instances can be created using
+.Xr ifconfig 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;
+ uid_t uid;
+ pid_t pid;
+ uid_t rule_uid;
+ pid_t rule_pid;
+ u_int8_t dir;
+ u_int8_t pad[3];
+};
+.Ed
+.Sh EXAMPLES
+Create a
+.Nm
+interface
+and monitor all packets logged on it:
+.Bd -literal -offset indent
+# ifconfig pflog1 up
+# tcpdump -n -e -ttt -i pflog1
+.Ed
+.Sh SEE ALSO
+.Xr inet 4 ,
+.Xr inet6 4 ,
+.Xr netintro 4 ,
+.Xr pf 4 ,
+.Xr ifconfig 8 ,
+.Xr pflogd 8 ,
+.Xr tcpdump 1
+.Sh HISTORY
+The
+.Nm
+device first appeared in
+.Ox 3.0 .
+.\" .Sh BUGS
+.\" Anything here?
diff --git a/share/man/man4/pfsync.4 b/share/man/man4/pfsync.4
new file mode 100644
index 0000000..b00bf9d
--- /dev/null
+++ b/share/man/man4/pfsync.4
@@ -0,0 +1,229 @@
+.\" $OpenBSD: pfsync.4,v 1.28 2009/02/17 10:05:18 dlg Exp $
+.\"
+.\" Copyright (c) 2002 Michael Shalayeff
+.\" Copyright (c) 2003-2004 Ryan McBride
+.\" 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.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd December 20 2011
+.Dt PFSYNC 4
+.Os
+.Sh NAME
+.Nm pfsync
+.Nd packet filter state table sychronisation interface
+.Sh SYNOPSIS
+.Cd "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 1
+on the
+.Nm
+interface.
+If configured with a physical synchronisation interface,
+.Nm
+will also send state changes out on that interface,
+and insert state changes received on that interface from other systems
+into the state table.
+.Pp
+By default, all local changes to the state table are exposed via
+.Nm .
+State changes from packets received by
+.Nm
+over the network are not rebroadcast.
+Updates to states created by a rule marked with the
+.Ar no-sync
+keyword are ignored by the
+.Nm
+interface (see
+.Xr pf.conf 5
+for details).
+.Pp
+The
+.Nm
+interface will attempt to collapse multiple state updates into a single
+packet where possible.
+The maximum number of times a single state can be updated before a
+.Nm
+packet will be sent out is controlled by the
+.Ar maxupd
+parameter to ifconfig
+(see
+.Xr ifconfig 8
+and the example below for more details).
+The sending out of a
+.Nm
+packet will be delayed by a maximum of one second.
+.Sh NETWORK SYNCHRONISATION
+States can be synchronised between two or more firewalls using this
+interface, by specifying a synchronisation interface using
+.Xr ifconfig 8 .
+For example, the following command sets fxp0 as the synchronisation
+interface:
+.Bd -literal -offset indent
+# ifconfig pfsync0 syncdev fxp0
+.Ed
+.Pp
+By default, state change messages are sent out on the synchronisation
+interface using IP multicast packets to the 244.0.0.240 group address.
+An alternative destination address for
+.Nm
+packets can be specified using the
+.Ic syncpeer
+keyword.
+This can be used in combination with
+.Xr ipsec 4
+to protect the synchronisation traffic.
+In such a configuration, the syncdev should be set to the
+.Xr enc 4
+interface, as this is where the traffic arrives when it is decapsulated,
+e.g.:
+.Bd -literal -offset indent
+# ifconfig pfsync0 syncpeer 10.0.0.2 syncdev enc0
+.Ed
+.Pp
+It is important that the pfsync traffic be well secured
+as there is no authentication on the protocol and it would
+be trivial to spoof packets which create states, bypassing the pf ruleset.
+Either run the pfsync protocol on a trusted network \- ideally a network
+dedicated to pfsync messages such as a crossover cable between two firewalls,
+or specify a peer address and protect the traffic with
+.Xr ipsec 4 .
+.Pp
+.Nm
+has the following
+.Xr sysctl 8
+tunables:
+.Bl -tag -width ".Va net.pfsync"
+.It Va net.pfsync.carp_demotion_factor
+Value added to
+.Va net.inet.carp.demotion
+while
+.Nm
+tries to perform its bulk update.
+See
+.Xr carp 4
+for more information.
+Default value is 240.
+.El
+.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 will handle all traffic until it dies, is shut down, or is
+manually demoted, at which point the second firewall will take over
+automatically.
+.Pp
+Both firewalls in this example have three
+.Xr sis 4
+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
+Interfaces configuration in
+.Pa /etc/rc.conf :
+.Bd -literal -offset indent
+network_interfaces="lo0 sis0 sis1 sis2"
+ifconfig_sis0="10.0.0.254/24"
+ifconfig_sis0_alias0="inet 10.0.0.1/24 vhid 1 pass foo"
+ifconfig_sis1="192.168.0.254/24"
+ifconfig_sis1_alias0="inet 192.168.0.1/24 vhid 2 pass bar"
+ifconfig_sis2="192.168.254.254/24"
+pfsync_enable="YES"
+pfsync_syncdev="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 keep state (no-sync)
+pass on { sis0 sis1 } proto carp keep state (no-sync)
+.Ed
+.Pp
+It is preferable that one firewall handle the forwarding of all the traffic,
+therefore the
+.Ar advskew
+on the backup firewall's
+.Xr carp 4
+vhids should be set to something higher than
+the primary's.
+For example, if firewall B is the backup, its
+carp1 configuration would look like this:
+would look like this:
+.Bd -literal -offset indent
+ifconfig_sis1_alias0="inet 192.168.0.1/24 vhid 2 pass bar 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 carp 4 ,
+.Xr enc 4 ,
+.Xr inet 4 ,
+.Xr inet6 4 ,
+.Xr ipsec 4 ,
+.Xr netintro 4 ,
+.Xr pf 4 ,
+.Xr pf.conf 5 ,
+.Xr protocols 5 ,
+.Xr rc.conf 5 ,
+.Xr ifconfig 8 ,
+.Xr tcpdump 1
+.Sh HISTORY
+The
+.Nm
+device first appeared in
+.Ox 3.3 .
+It was first imported to
+.Fx 5.3 .
+.Pp
+The
+.Nm
+protocol and kernel implementation were significantly modified in
+.Fx 9.0 .
+The newer protocol is not compatible with older one and will not interoperate
+with it.
diff --git a/share/man/man5/Makefile b/share/man/man5/Makefile
index c7a3c59..2c56fc8 100644
--- a/share/man/man5/Makefile
+++ b/share/man/man5/Makefile
@@ -50,6 +50,8 @@ MAN= acct.5 \
passwd.5 \
pbm.5 \
periodic.conf.5 \
+ pf.conf.5 \
+ pf.os.5 \
phones.5 \
portindex.5 \
portsnap.conf.5 \
diff --git a/share/man/man5/pf.conf.5 b/share/man/man5/pf.conf.5
new file mode 100644
index 0000000..fc86111
--- /dev/null
+++ b/share/man/man5/pf.conf.5
@@ -0,0 +1,3066 @@
+.\" $FreeBSD$
+.\" $OpenBSD: pf.conf.5,v 1.406 2009/01/31 19:37:12 sobrado 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 June 29 2012
+.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
+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).
+.Pp
+Comments can be put anywhere in the file using a hash mark
+.Pq Sq # ,
+and extend to the end of the current line.
+.Pp
+Additional configuration files can be included with the
+.Ic include
+keyword, for example:
+.Bd -literal -offset indent
+include "/etc/pf/sub.filter.conf"
+.Ed
+.Sh MACROS
+Macros can be defined that will later be expanded in context.
+Macro names must start with a letter, and may contain letters, digits
+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
+pass in on $ext_if proto tcp from any to any port 25
+.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 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.
+.It Ar counters
+The
+.Ar counters
+flag enables per-address packet and byte counters which can be displayed with
+.Xr pfctl 8 .
+.El
+.Pp
+For example,
+.Bd -literal -offset indent
+table \*(Ltprivate\*(Gt const { 10/8, 172.16/12, 192.168/16 }
+table \*(Ltbadhosts\*(Gt persist
+block on fxp0 from { \*(Ltprivate\*(Gt, \*(Ltbadhosts\*(Gt } 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 \*(Ltspam\*(Gt persist file \&"/etc/spammers\&" file \&"/etc/openrelays\&"
+block on fxp0 from \*(Ltspam\*(Gt 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, a valid interface group 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 "src.track" -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
+Adaptive timeouts are enabled by default, with an adaptive.start value
+equal to 60% of the state limit, and an adaptive.end value equal to
+120% of the state limit.
+They can be disabled by setting both adaptive.start and adaptive.end to 0.
+.Pp
+The adaptive timeout 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 or interface group.
+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 zone 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 pass
+rules which do not specify
+.Ar no state )
+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.
+Using
+.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 src.track
+options) to 2000.
+Using
+.Bd -literal -offset indent
+set limit tables 1000
+set limit table-entries 100000
+.Ed
+.Pp
+sets limits on the memory pools used by tables.
+The first limits the number of tables that can exist to 1000.
+The second limits the overall number of addresses that can be stored
+in tables to 100000.
+.Pp
+Various limits can be combined on a single line:
+.Bd -literal -offset indent
+set limit { states 20000, frags 20000, src-nodes 2000 }
+.Ed
+.Pp
+.It Ar set ruleset-optimization
+.Bl -tag -width xxxxxxxx -compact
+.It Ar none
+Disable the ruleset optimizer.
+.It Ar basic
+Enable basic ruleset optimization.
+This is the default behaviour.
+Basic ruleset optimization does four things to improve the
+performance of ruleset evaluations:
+.Pp
+.Bl -enum -compact
+.It
+remove duplicate rules
+.It
+remove rules that are a subset of another rule
+.It
+combine multiple rules into a table when advantageous
+.It
+re-order the rules to improve evaluation performance
+.El
+.Pp
+.It Ar profile
+Uses the currently loaded ruleset as a feedback profile to tailor the
+ordering of quick rules to actual network traffic.
+.El
+.Pp
+It is important to note that the ruleset optimizer will modify the ruleset
+to improve performance.
+A side effect of the ruleset modification is that per-rule accounting
+statistics will have different meanings than before.
+If per-rule accounting is important for billing purposes or whatnot,
+either the ruleset optimizer should not be used or a label field should
+be added to all of the accounting rules to act as optimization barriers.
+.Pp
+Optimization can also be set as a command-line argument to
+.Xr pfctl 8 ,
+overriding the settings in
+.Nm .
+.It Ar set optimization
+Optimize state timeouts 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 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 state-defaults
+The
+.Ar state-defaults
+option sets the state options for states created from rules
+without an explicit
+.Ar keep state .
+For example:
+.Bd -literal -offset indent
+set state-defaults pflow, no-sync
+.Ed
+.It Ar set hostid
+The 32-bit
+.Ar hostid
+identifies this firewall's state table entries to other firewalls
+in a
+.Xr pfsync 4
+failover cluster.
+By default the hostid is set to a pseudo-random value, however it may be
+desirable to manually configure it, for example to more easily identify the
+source of state table entries.
+.Bd -literal -offset indent
+set hostid 1
+.Ed
+.Pp
+The hostid may be specified in either decimal or hexadecimal.
+.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 skip on Aq Ar ifspec
+List interfaces for which packets should not be filtered.
+Packets passing in or out on such interfaces are passed as if pf was
+disabled, i.e. pf does not process them in any way.
+This can be useful on loopback and other virtual interfaces, when
+packet filtering is not desired and can have unexpected effects.
+For example:
+.Pp
+.Dl set skip on lo0
+.Pp
+.It Ar set debug
+Set the debug
+.Ar level
+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 Aq Ar number
+Enforces a minimum TTL for matching IP packets.
+.It Ar max-mss Aq Ar number
+Enforces a maximum MSS for matching TCP packets.
+.It Xo Ar set-tos Aq Ar string
+.No \*(Ba Aq Ar number
+.Xc
+Enforces a
+.Em TOS
+for matching IP packets.
+.Em TOS
+may be
+given as one of
+.Ar lowdelay ,
+.Ar throughput ,
+.Ar reliability ,
+or as either hex or decimal.
+.It Ar random-id
+Replaces the IP identification field with random values to compensate
+for predictable values generated by many hosts.
+This option only applies to 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 timestamp modulation
+Modern TCP stacks will send a timestamp on every TCP packet and echo
+the other endpoint's timestamp back to them.
+Many operating systems will merely start the timestamp at zero when
+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.
+.It extended PAWS checks
+There is a problem with TCP on long fat pipes, in that a packet might get
+delayed for longer than it takes the connection to wrap its 32-bit sequence
+space.
+In such an occurrence, the old packet would be indistinguishable from a
+new packet and would be accepted as such.
+The solution to this is called PAWS: Protection Against Wrapped Sequence
+numbers.
+It protects against it by making sure the timestamp on each packet does
+not go backwards.
+.Ar reassemble tcp
+also makes sure the timestamp on the packet does not go forward more
+than the RFC allows.
+By doing this,
+.Xr pf 4
+artificially extends the security of TCP sequence numbers by 10 to 18
+bits when the host uses appropriately randomized timestamps, since a
+blind attacker would have to guess the timestamp as well.
+.El
+.El
+.Pp
+For example,
+.Bd -literal -offset indent
+scrub in on $ext_if all fragment reassemble
+.Ed
+.Pp
+The
+.Ar no
+option prefixed to a scrub rule causes matching packets to remain unscrubbed,
+much in the same way as
+.Ar drop quick
+works in the packet filter (see below).
+This mechanism should be used when it is necessary to exclude specific packets
+from broader scrub rules.
+.Sh QUEUEING
+The ALTQ system is currently not available in the GENERIC kernel nor as
+loadable modules.
+In order to use the herein after called queueing options one has to use a
+custom built kernel.
+Please refer to
+.Xr altq 4
+to learn about the related kernel options.
+.Pp
+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.
+.Ar cbq
+achieves both partitioning and sharing of link bandwidth
+by hierarchically structured classes.
+Each class has its own
+.Ar queue
+and is assigned its share of
+.Ar bandwidth .
+A child class can borrow bandwidth from its parent class
+as long as excess bandwidth is available
+(see the option
+.Ar borrow ,
+below).
+.It Ar priq
+Priority Queueing.
+.Ar Queues
+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
+primarily affects throughput.
+.Ar hfsc
+supports both link-sharing and guaranteed real-time services.
+It employs a service curve based QoS model,
+and its unique feature is an ability to decouple
+.Ar delay
+and
+.Ar bandwidth
+allocation.
+.El
+.Pp
+The interfaces on which queueing should be activated are declared using
+the
+.Ar altq on
+declaration.
+.Ar altq on
+has the following keywords:
+.Bl -tag -width xxxx
+.It Aq Ar interface
+Queueing is enabled on the named interface.
+.It Aq 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 Aq Ar 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
+(but take note that some interfaces do not know their bandwidth,
+or can adapt their bandwidth rates).
+.It Ar qlimit Aq Ar limit
+The maximum number of packets held in the queue.
+The default is 50.
+.It Ar tbrsize Aq Ar 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 Aq Ar list
+Defines a list of subqueues to create on an interface.
+.El
+.Pp
+In the following example, the interface dc0
+should queue up to 5Mbps in four second-level queues using
+Class Based Queueing.
+Those four queues will be shown in a later example.
+.Bd -literal -offset indent
+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 Aq Ar interface
+Specifies the interface the queue operates on.
+If not given, it operates on all matching interfaces.
+.It Ar bandwidth Aq Ar 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.
+If not specified, defaults to 100% of the parent queue's bandwidth.
+The
+.Ar priq
+scheduler does not support bandwidth specification.
+.It Ar priority Aq Ar 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 Aq Ar limit
+The maximum number of packets held in the queue.
+The default is 50.
+.El
+.Pp
+The
+.Ar scheduler
+can get additional parameters with
+.Xo Aq Ar scheduler
+.Pf ( Aq Ar parameters ) .
+.Xc
+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 Aq Ar sc
+The minimum required bandwidth for the queue.
+.It Ar upperlimit Aq Ar sc
+The maximum allowed bandwidth for the queue.
+.It Ar linkshare Aq Ar sc
+The bandwidth share of a backlogged queue.
+.El
+.Pp
+.Aq Ar 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 bandwidth 50% priority 7 cbq(borrow)
+queue ssh_bulk bandwidth 50% priority 0 cbq(borrow)
+
+block return out on dc0 inet all queue std
+pass out on dc0 inet proto tcp from $developerhosts to any port 80 \e
+ queue developers
+pass out on dc0 inet proto tcp from $employeehosts to any port 80 \e
+ queue employees
+pass out on dc0 inet proto tcp from any to any port 22 \e
+ queue(ssh_bulk, ssh_interactive)
+pass out on dc0 inet proto tcp from any to any port 25 \e
+ 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 -\*(Gt ... port 4000
+redirects ports 2000 to 2999 (inclusive) to port 4000.
+rdr ... port 2000:2999 -\*(Gt ... 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
+Evaluation order of the translation rules is dependent on the type
+of the translation rules and of the direction of a packet.
+.Ar binat
+rules are always evaluated first.
+Then either the
+.Ar rdr
+rules are evaluated on an inbound packet or the
+.Ar nat
+rules on an outbound packet.
+Rules of the same type are evaluated in the same order in which they
+appear in the ruleset.
+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 smtp -\*(Gt 127.0.0.1 port spamd
+.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.
+If no rule matches the packet, the default action is to pass
+the packet.
+.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 ICMP packets currently have no effect if
+.Xr pf 4
+operates on a
+.Xr if_bridge 4 ,
+as the code to support this feature has not yet been implemented.
+.Pp
+The simplest mechanism to block everything by default and only pass
+packets that match explicit rules is specify a first filter rule of:
+.Bd -literal -offset indent
+block all
+.Ed
+.It Ar pass
+The packet is passed;
+state is created unless the
+.Ar no state
+option is specified.
+.El
+.Pp
+By default
+.Xr pf 4
+filters packets statefully; the first time a packet matches a
+.Ar pass
+rule, a state entry is created; for subsequent packets the filter checks
+whether the packet matches any state.
+If it does, the packet is passed without evaluation of any rules.
+After the connection is closed or times out, the state entry is automatically
+removed.
+.Pp
+This has several advantages.
+For TCP connections, comparing a packet to a state involves checking
+its sequence numbers, as well as TCP timestamps if a
+.Ar scrub reassemble tcp
+rule applies to the connection.
+If these values 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.
+Similarly,
+.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
+.Ed
+.Pp
+allows echo requests (such as those created by
+.Xr ping 8 )
+out statefully, and matches incoming echo replies correctly to states.
+.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
+Furthermore, correct handling of ICMP error messages is critical to
+many protocols, particularly TCP.
+.Xr pf 4
+matches ICMP error messages to the correct connection, checks them against
+connection parameters, and passes them if appropriate.
+For example if an ICMP source quench message referring to a stateful TCP
+connection arrives, it will be matched to the state and get passed.
+.Pp
+Finally, state tracking is required for
+.Ar nat , binat No and Ar rdr
+rules, in order to track address and port translations and reverse the
+translation on returning packets.
+.Pp
+.Xr pf 4
+will also create state for other protocols which are effectively stateless by
+nature.
+UDP packets are matched to states using only host addresses and ports,
+and other protocols are matched to states using only the host addresses.
+.Pp
+If stateless filtering of individual packets is desired,
+the
+.Ar no state
+keyword can be used to specify that state will not be created
+if this is the last matching rule.
+A number of parameters can also be set to affect how
+.Xr pf 4
+handles state tracking.
+See
+.Sx STATEFUL TRACKING OPTIONS
+below for further details.
+.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.
+Only the packet that establishes the state is logged,
+unless the
+.Ar no state
+option is specified.
+The logged packets are sent to a
+.Xr pflog 4
+interface, by default
+.Ar pflog0 .
+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 to force logging of all packets for a connection.
+This is not necessary when
+.Ar no state
+is explicitly specified.
+As with
+.Ar log ,
+packets are logged to
+.Xr pflog 4 .
+.It Ar log (user)
+Logs the
+.Ux
+user ID of the user that owns the socket and the PID of the process that
+has the socket open where the packet is sourced from or destined to
+(depending on which socket is local).
+This is in addition to the normal information logged.
+.Pp
+Only the first packet
+logged via
+.Ar log (all, user)
+will have the user credentials logged when using stateful matching.
+.It Ar log (to Aq Ar interface )
+Send logs to the specified
+.Xr pflog 4
+interface instead of
+.Ar pflog0 .
+.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 Aq Ar interface
+This rule applies only to packets coming in on, or going out through, this
+particular interface or interface group.
+For more information on interface groups,
+see the
+.Ic group
+keyword in
+.Xr ifconfig 8 .
+.It Aq Ar af
+This rule applies only to packets of this address family.
+Supported values are
+.Ar inet
+and
+.Ar inet6 .
+.It Ar proto Aq Ar 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 Aq Ar source
+.Ar port Aq Ar source
+.Ar os Aq Ar source
+.Ar to Aq Ar dest
+.Ar port Aq Ar 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, interface names or interface group names, or as any
+of the following keywords:
+.Pp
+.Bl -tag -width xxxxxxxxxxxxxx -compact
+.It Ar any
+Any address.
+.It Ar no-route
+Any address which is not currently routable.
+.It Ar urpf-failed
+Any source address that fails a unicast reverse path forwarding (URPF)
+check, i.e. packets coming in on an interface other than that which holds
+the route back to the packet's source address.
+.It Aq Ar table
+Any address that matches the given table.
+.El
+.Pp
+Ranges of addresses are specified by using the
+.Sq -
+operator.
+For instance:
+.Dq 10.1.1.10 - 10.1.1.12
+means all addresses from 10.1.1.10 to 10.1.1.12,
+hence addresses 10.1.1.10, 10.1.1.11, and 10.1.1.12.
+.Pp
+Interface names and interface group names can have modifiers appended:
+.Pp
+.Bl -tag -width xxxxxxxxxxxx -compact
+.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)
+\*(Lt (less than)
+\*(Le (less than or equal)
+\*(Gt (greater than)
+\*(Ge (greater than or equal)
+: (range including boundaries)
+\*(Gt\*(Lt (range excluding boundaries)
+\*(Lt\*(Gt (except range)
+.Ed
+.Pp
+.Sq \*(Gt\*(Lt ,
+.Sq \*(Lt\*(Gt
+and
+.Sq \&:
+are binary operators (they take two arguments).
+For instance:
+.Bl -tag -width Fl
+.It Ar port 2000:2004
+means
+.Sq all ports \*(Ge 2000 and \*(Le 2004 ,
+hence ports 2000, 2001, 2002, 2003 and 2004.
+.It Ar port 2000 \*(Gt\*(Lt 2004
+means
+.Sq all ports \*(Gt 2000 and \*(Lt 2004 ,
+hence ports 2001, 2002 and 2003.
+.It Ar port 2000 \*(Lt\*(Gt 2004
+means
+.Sq all ports \*(Lt 2000 or \*(Gt 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 \*(Le 1024 to any
+pass in proto tcp from any to any port 25
+pass in proto tcp from 10.0.0.0/8 port \*(Gt 1024 \e
+ to ! 10.1.2.3 port != ssh
+pass in proto tcp from any os "OpenBSD"
+.Ed
+.It Ar all
+This is equivalent to "from any to any".
+.It Ar group Aq Ar group
+Similar to
+.Ar user ,
+this rule only applies to packets of sockets owned by the specified group.
+.It Ar user Aq Ar user
+This rule only applies to packets of sockets owned by the specified user.
+For outgoing connections initiated from the firewall, this is the user
+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 \*(Ge 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 \*(Ge 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 user { \*(Lt 1000, dhartmei }
+.Ed
+.It Xo Ar flags Aq Ar a
+.Pf / Ns Aq Ar b
+.No \*(Ba / Ns Aq Ar b
+.No \*(Ba any
+.Xc
+This rule only applies to TCP packets that have the flags
+.Aq Ar a
+set out of set
+.Aq Ar b .
+Flags not specified in
+.Aq Ar b
+are ignored.
+For stateful connections, the default is
+.Ar flags S/SA .
+To indicate that flags should not be checked at all, specify
+.Ar flags any .
+The flags are: (F)IN, (S)YN, (R)ST, (P)USH, (A)CK, (U)RG, (E)CE, and C(W)R.
+.Bl -tag -width Fl
+.It Ar flags S/S
+Flag SYN is set.
+The other flags are ignored.
+.It Ar flags S/SA
+This is the default setting for stateful connections.
+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
+.Pp
+Because
+.Ar flags S/SA
+is applied by default (unless
+.Ar no state
+is specified), only the initial SYN packet of a TCP handshake will create
+a state for a TCP connection.
+It is possible to be less restrictive, and allow state creation from
+intermediate
+.Pq non-SYN
+packets, by specifying
+.Ar flags any .
+This will cause
+.Xr pf 4
+to synchronize to existing connections, for instance
+if one flushes the state table.
+However, states created from such intermediate packets may be missing
+connection details such as the TCP window scaling factor.
+States which modify the packet flow, such as those affected by
+.Ar nat , binat No or Ar rdr
+rules,
+.Ar modulate No or Ar synproxy state
+options, or scrubbed with
+.Ar reassemble tcp
+will also not be recoverable from intermediate packets.
+Such connections will stall and time out.
+.It Xo Ar icmp-type Aq Ar type
+.Ar code Aq Ar code
+.Xc
+.It Xo Ar icmp6-type Aq Ar type
+.Ar code Aq Ar code
+.Xc
+This rule only applies to ICMP or ICMPv6 packets with the specified type
+and code.
+Text names for ICMP types and codes are listed in
+.Xr icmp 4
+and
+.Xr icmp6 4 .
+This parameter is only valid for rules that cover protocols ICMP or
+ICMP6.
+The protocol and the ICMP type indicator
+.Po
+.Ar icmp-type
+or
+.Ar icmp6-type
+.Pc
+must match.
+.It Xo Ar tos Aq Ar string
+.No \*(Ba Aq Ar number
+.Xc
+This rule applies to packets with the specified
+.Em TOS
+bits set.
+.Em TOS
+may be
+given as one of
+.Ar lowdelay ,
+.Ar throughput ,
+.Ar reliability ,
+or as either hex or decimal.
+.Pp
+For example, the following rules are identical:
+.Bd -literal -offset indent
+pass all tos lowdelay
+pass all tos 0x10
+pass all tos 16
+.Ed
+.It Ar allow-opts
+By default, IPv4 packets with IP options or IPv6 packets with routing
+extension headers 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 or routing extension headers.
+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 Aq Ar 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 \*(Gt 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 \*(Gt 1023 label \&"1.2.3.4:\*(Gt1023\&"
+pass in inet proto tcp from any to 1.2.3.5 \e
+ port \*(Gt 1023 label \&"1.2.3.5:\*(Gt1023\&"
+.Ed
+.Pp
+The macro expansion for the
+.Ar label
+directive occurs only at configuration file parse time, not during runtime.
+.It Xo Ar queue Aq Ar queue
+.No \*(Ba ( Aq Ar queue ,
+.Aq Ar queue )
+.Xc
+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 Aq Ar 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.
+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 Aq Ar string
+Used with filter, translation or scrub rules
+to specify that packets must already
+be tagged with the given tag in order to match the rule.
+Inverse tag matching can also be done
+by specifying the
+.Cm !\&
+operator before the
+.Ar tagged
+keyword.
+.It Ar rtable Aq Ar number
+Used to select an alternate routing table for the routing lookup.
+Only effective before the route lookup happened, i.e. when filtering inbound.
+.It Xo Ar divert-to Aq Ar host
+.Ar port Aq Ar port
+.Xc
+Used to redirect packets to a local socket bound to
+.Ar host
+and
+.Ar port .
+The packets will not be modified, so
+.Xr getsockname 2
+on the socket will return the original destination address of the packet.
+.It Ar divert-reply
+Used to receive replies for sockets that are bound to addresses
+which are not local to the machine.
+See
+.Xr setsockopt 2
+for information on how to bind these sockets.
+.It Ar probability Aq Ar number
+A probability attribute can be attached to a rule, with a value set between
+0 and 1, bounds not included.
+In that case, the rule will be honoured using the given probability value
+only.
+For example, the following rule will drop 20% of incoming ICMP packets:
+.Bd -literal -offset indent
+block in proto icmp probability 20%
+.Ed
+.El
+.Sh ROUTING
+If a packet matches a rule with a route option set, the packet filter will
+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 reply-to
+is useful only in rules that create state.
+It can be used on systems with multiple external connections to
+route all outgoing packets of a connection through the interface
+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 src.track .
+See
+.Sx STATEFUL TRACKING OPTIONS
+for more ways to control the source tracking.
+.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/SFRA modulate state
+.Ed
+.Pp
+Note that modulated connections will not recover 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.
+The default
+.Ar flags
+settings (or a more strict equivalent) should be used on
+.Ar modulate state
+rules to prevent ACK storms.
+.Pp
+Note that alternative methods are available
+to prevent loss of the state table
+and allow for firewall failover.
+See
+.Xr carp 4
+and
+.Xr pfsync 4
+for further information.
+.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.
+.Ar synproxy state
+includes
+.Ar modulate 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 synproxy state
+.Ed
+.Sh STATEFUL TRACKING OPTIONS
+A number of options related to stateful tracking can be applied on a
+per-rule basis.
+.Ar keep state ,
+.Ar modulate state
+and
+.Ar synproxy state
+support these options, and
+.Ar keep state
+must be specified explicitly to apply options to a rule.
+.Pp
+.Bl -tag -width xxxx -compact
+.It Ar max Aq Ar number
+Limits the number of concurrent states the rule may create.
+When this limit is reached, further packets that would create
+state will not match this rule until existing states time out.
+.It Ar no-sync
+Prevent state changes for states created by this rule from appearing on the
+.Xr pfsync 4
+interface.
+.It Xo Aq Ar timeout
+.Aq Ar seconds
+.Xc
+Changes the timeout values used for states created by this rule.
+For a list of all valid timeout names, see
+.Sx OPTIONS
+above.
+.It Ar sloppy
+Uses a sloppy TCP connection tracker that does not check sequence
+numbers at all, which makes insertion and ICMP teardown attacks way
+easier.
+This is intended to be used in situations where one does not see all
+packets of a connection, e.g. in asymmetric routing situations.
+Cannot be used with modulate or synproxy state.
+.It Ar pflow
+States created by this rule are exported on the
+.Xr pflow 4
+interface.
+.El
+.Pp
+Multiple options can be specified, separated by commas:
+.Bd -literal -offset indent
+pass in proto tcp from any to any \e
+ port www keep state \e
+ (max 100, source-track rule, max-src-nodes 75, \e
+ max-src-states 3, tcp.established 60, tcp.closing 5)
+.Ed
+.Pp
+When the
+.Ar source-track
+keyword is specified, the number of states per source IP is tracked.
+.Pp
+.Bl -tag -width xxxx -compact
+.It Ar source-track rule
+The maximum number of states created by this rule is limited by the rule's
+.Ar max-src-nodes
+and
+.Ar max-src-states
+options.
+Only state entries created by this particular rule count toward the rule's
+limits.
+.It Ar source-track global
+The number of states created by all rules that use this option is limited.
+Each rule can specify different
+.Ar max-src-nodes
+and
+.Ar max-src-states
+options, however state entries created by any participating rule count towards
+each individual rule's limits.
+.El
+.Pp
+The following limits can be set:
+.Pp
+.Bl -tag -width xxxx -compact
+.It Ar max-src-nodes Aq Ar number
+Limits the maximum number of source addresses which can simultaneously
+have state table entries.
+.It Ar max-src-states Aq Ar number
+Limits the maximum number of simultaneous state entries that a single
+source address can create with this rule.
+.El
+.Pp
+For stateful TCP connections, limits on established connections (connections
+which have completed the TCP 3-way handshake) can also be enforced
+per source IP.
+.Pp
+.Bl -tag -width xxxx -compact
+.It Ar max-src-conn Aq Ar number
+Limits the maximum number of simultaneous TCP connections which have
+completed the 3-way handshake that a single host can make.
+.It Xo Ar max-src-conn-rate Aq Ar number
+.No / Aq Ar seconds
+.Xc
+Limit the rate of new connections over a time interval.
+The connection rate is an approximation calculated as a moving average.
+.El
+.Pp
+Because the 3-way handshake ensures that the source address is not being
+spoofed, more aggressive action can be taken based on these limits.
+With the
+.Ar overload Aq Ar table
+state option, source IP addresses which hit either of the limits on
+established connections will be added to the named table.
+This table can be used in the ruleset to block further activity from
+the offending host, redirect it to a tarpit process, or restrict its
+bandwidth.
+.Pp
+The optional
+.Ar flush
+keyword kills all states created by the matching rule which originate
+from the host which exceeds these limits.
+The
+.Ar global
+modifier to the flush command kills all states originating from the
+offending host, regardless of which rule created the state.
+.Pp
+For example, the following rules will protect the webserver against
+hosts making more than 100 connections in 10 seconds.
+Any host which connects faster than this rate will have its address added
+to the
+.Aq bad_hosts
+table and have all states originating from it flushed.
+Any new packets arriving from this host will be dropped unconditionally
+by the block rule.
+.Bd -literal -offset indent
+block quick from \*(Ltbad_hosts\*(Gt
+pass in on $ext_if proto tcp to $webserver port www keep state \e
+ (max-src-conn-rate 100/10, overload \*(Ltbad_hosts\*(Gt flush global)
+.Ed
+.Sh OPERATING SYSTEM FINGERPRINTING
+Passive OS Fingerprinting is a mechanism to inspect nuances of a TCP
+connection's initial SYN packet and guess at the host's operating system.
+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 vendor or genre
+and would be
+.Ox
+for the
+.Xr pf 4
+firewall itself.
+The version of the oldest available
+.Ox
+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
+.Ox ,
+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
+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"
+.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
+Besides the main ruleset,
+.Xr pfctl 8
+can load rulesets into
+.Ar anchor
+attachment points.
+An
+.Ar anchor
+is a container that can hold rules, address tables, and other anchors.
+.Pp
+An
+.Ar anchor
+has a name which specifies the path where
+.Xr pfctl 8
+can be used to access the anchor to perform operations on it, such as
+attaching child anchors to it or loading rules into it.
+Anchors may be nested, with components separated by
+.Sq /
+characters, similar to how file system hierarchies are laid out.
+The main ruleset is actually the default anchor, so filter and
+translation rules, for example, may also be contained in any anchor.
+.Pp
+An anchor can reference another
+.Ar anchor
+attachment point
+using the following kinds
+of rules:
+.Bl -tag -width xxxx
+.It Ar nat-anchor Aq Ar name
+Evaluates the
+.Ar nat
+rules in the specified
+.Ar anchor .
+.It Ar rdr-anchor Aq Ar name
+Evaluates the
+.Ar rdr
+rules in the specified
+.Ar anchor .
+.It Ar binat-anchor Aq Ar name
+Evaluates the
+.Ar binat
+rules in the specified
+.Ar anchor .
+.It Ar anchor Aq Ar name
+Evaluates the filter rules in the specified
+.Ar anchor .
+.It Xo Ar load anchor
+.Aq Ar name
+.Ar from Aq Ar file
+.Xc
+Loads the rules from the specified file into the
+anchor
+.Ar name .
+.El
+.Pp
+When evaluation of the main ruleset reaches an
+.Ar anchor
+rule,
+.Xr pf 4
+will proceed to evaluate all rules specified in that anchor.
+.Pp
+Matching filter and translation rules marked with the
+.Ar quick
+option are final and abort the evaluation of the rules in other
+anchors and the main ruleset.
+If the
+.Ar anchor
+itself is marked with the
+.Ar quick
+option,
+ruleset evaluation will terminate when the anchor is exited if the packet is
+matched by any rule within the anchor.
+.Pp
+.Ar anchor
+rules are evaluated relative to the anchor in which they are contained.
+For example, all
+.Ar anchor
+rules specified in the main ruleset will reference anchor
+attachment points underneath the main ruleset, and
+.Ar anchor
+rules specified in a file loaded from a
+.Ar load anchor
+rule will be attached under that anchor point.
+.Pp
+Rules may be contained in
+.Ar anchor
+attachment points which do not contain any rules when the main ruleset
+is loaded, and later such anchors can be manipulated through
+.Xr pfctl 8
+without reloading the main ruleset or other anchors.
+For example,
+.Bd -literal -offset indent
+ext_if = \&"kue0\&"
+block on $ext_if all
+anchor spam
+pass out on $ext_if all
+pass in on $ext_if proto tcp from any \e
+ to $ext_if port smtp
+.Ed
+.Pp
+blocks all packets on the external interface by default, then evaluates
+all rules in the
+.Ar anchor
+named "spam", and finally passes all outgoing connections and
+incoming connections to port 25.
+.Bd -literal -offset indent
+# echo \&"block in quick from 1.2.3.4 to any\&" \&| \e
+ pfctl -a spam -f -
+.Ed
+.Pp
+This loads a single rule into the
+.Ar anchor ,
+which blocks all packets from a specific address.
+.Pp
+The anchor can also be populated by adding a
+.Ar load anchor
+rule after the
+.Ar anchor
+rule:
+.Bd -literal -offset indent
+anchor spam
+load anchor spam 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 anchor.
+.Pp
+Optionally,
+.Ar anchor
+rules can specify packet filtering parameters using the same syntax as
+filter rules.
+When parameters are used, the
+.Ar anchor
+rule is only evaluated for matching packets.
+This allows conditional evaluation of anchors, like:
+.Bd -literal -offset indent
+block on $ext_if all
+anchor spam proto tcp from any to any port smtp
+pass out on $ext_if all
+pass in on $ext_if proto tcp from any to $ext_if port smtp
+.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 -f -
+.Ed
+.Pp
+will only block connections from 1.2.3.4 to port 25.
+.Pp
+Anchors may end with the asterisk
+.Pq Sq *
+character, which signifies that all anchors attached at that point
+should be evaluated in the alphabetical ordering of their anchor name.
+For example,
+.Bd -literal -offset indent
+anchor "spam/*"
+.Ed
+.Pp
+will evaluate each rule in each anchor attached to the
+.Li spam
+anchor.
+Note that it will only evaluate anchors that are directly attached to the
+.Li spam
+anchor, and will not descend to evaluate anchors recursively.
+.Pp
+Since anchors are evaluated relative to the anchor in which they are
+contained, there is a mechanism for accessing the parent and ancestor
+anchors of a given anchor.
+Similar to file system path name resolution, if the sequence
+.Dq ..
+appears as an anchor path component, the parent anchor of the current
+anchor in the path evaluation at that point will become the new current
+anchor.
+As an example, consider the following:
+.Bd -literal -offset indent
+# echo ' anchor "spam/allowed" ' | pfctl -f -
+# echo -e ' anchor "../banned" \en pass' | \e
+ pfctl -a spam/allowed -f -
+.Ed
+.Pp
+Evaluation of the main ruleset will lead into the
+.Li spam/allowed
+anchor, which will evaluate the rules in the
+.Li spam/banned
+anchor, if any, before finally evaluating the
+.Ar pass
+rule.
+.Pp
+Filter rule
+.Ar anchors
+can also be loaded inline in the ruleset within a brace ('{' '}') delimited
+block.
+Brace delimited blocks may contain rules or other brace-delimited blocks.
+When anchors are loaded this way the anchor name becomes optional.
+.Bd -literal -offset indent
+anchor "external" on egress {
+ block
+ anchor out {
+ pass proto tcp from any to port { 25, 80, 443 }
+ }
+ pass in proto tcp to any port 22
+}
+.Ed
+.Pp
+Since the parser specification for anchor names is a string, any
+reference to an anchor name containing
+.Sq /
+characters will require double quote
+.Pq Sq \&"
+characters around the anchor name.
+.Sh TRANSLATION EXAMPLES
+This example maps incoming requests on port 80 to port 8080, on
+which a daemon is running (because, for example, it is not run as root,
+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 -\*(Gt 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 -\*(Gt 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 -\*(Gt 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 -\*(Gt 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 -\*(Gt 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 localhost, we are running
+.Xr ftp-proxy 8 ,
+waiting for FTP sessions to be redirected to it.
+The three mandatory anchors for
+.Xr ftp-proxy 8
+are omitted from this example; see the
+.Xr ftp-proxy 8
+manpage.
+.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 -\*(Gt ($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 -\*(Gt ($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 -\*(Gt $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
+ -\*(Gt 10.1.2.151 port 22
+rdr on $ext_if inet proto udp from any to ($ext_if) port 8080 \e
+ -\*(Gt 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 -\*(Gt 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 -\*(Gt 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
+ -\*(Gt { 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 packets whose ingress interface does not match the one in
+# the route back to their source address
+block in from urpf-failed 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
+
+# UDP
+
+# pass out all UDP connections and keep state
+pass out on $ext_if proto udp all
+
+# pass in certain UDP connections and keep state (DNS)
+pass in on $ext_if proto udp from any to any port domain
+
+# 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 }
+
+# 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
+
+# IPv6
+# pass in/out all IPv6 traffic: note that we have to enable this in two
+# different ways, on both our physical interface and our tunnel
+pass quick on gif0 inet6
+pass quick on $ext_if proto ipv6
+
+# 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
+pass in on $wifi_if from any to any
+
+block out on $ext_if from any to any
+pass out quick on $ext_if tagged INTNET
+pass out on $ext_if proto tcp from any to any port 80
+
+# 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 \*(Ltspammers\*(Gt to port smtp \e
+ tag SPAMD -\*(Gt 127.0.0.1 port spamd
+
+block in on $ext_if
+pass in on $ext_if inet proto tcp tagged SPAMD
+.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 | trans-anchors |
+ anchor-rule | anchor-close | load-anchor | table-rule |
+ include )
+
+option = "set" ( [ "timeout" ( timeout | "{" timeout-list "}" ) ] |
+ [ "ruleset-optimization" [ "none" | "basic" | "profile" ]] |
+ [ "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" | "floating" ) ]
+ [ "state-defaults" state-opts ]
+ [ "require-order" ( "yes" | "no" ) ]
+ [ "fingerprints" filename ] |
+ [ "skip on" ifspec ] |
+ [ "debug" ( "none" | "urgent" | "misc" | "loud" ) ] )
+
+pf-rule = action [ ( "in" | "out" ) ]
+ [ "log" [ "(" logopts ")"] ] [ "quick" ]
+ [ "on" ifspec ] [ "fastroute" | route ] [ af ] [ protospec ]
+ hosts [ filteropt-list ]
+
+logopts = logopt [ "," logopts ]
+logopt = "all" | "user" | "to" interface-name
+
+filteropt-list = filteropt-list filteropt | filteropt
+filteropt = user | group | flags | icmp-type | icmp6-type | "tos" tos |
+ ( "no" | "keep" | "modulate" | "synproxy" ) "state"
+ [ "(" state-opts ")" ] |
+ "fragment" | "no-df" | "min-ttl" number | "set-tos" tos |
+ "max-mss" number | "random-id" | "reassemble tcp" |
+ fragmentation | "allow-opts" |
+ "label" string | "tag" string | [ ! ] "tagged" string |
+ "queue" ( string | "(" string [ [ "," ] string ] ")" ) |
+ "rtable" number | "probability" number"%"
+
+nat-rule = [ "no" ] "nat" [ "pass" [ "log" [ "(" logopts ")" ] ] ]
+ [ "on" ifspec ] [ af ]
+ [ protospec ] hosts [ "tag" string ] [ "tagged" string ]
+ [ "-\*(Gt" ( redirhost | "{" redirhost-list "}" )
+ [ portspec ] [ pooltype ] [ "static-port" ] ]
+
+binat-rule = [ "no" ] "binat" [ "pass" [ "log" [ "(" logopts ")" ] ] ]
+ [ "on" interface-name ] [ af ]
+ [ "proto" ( proto-name | proto-number ) ]
+ "from" address [ "/" mask-bits ] "to" ipspec
+ [ "tag" string ] [ "tagged" string ]
+ [ "-\*(Gt" address [ "/" mask-bits ] ]
+
+rdr-rule = [ "no" ] "rdr" [ "pass" [ "log" [ "(" logopts ")" ] ] ]
+ [ "on" ifspec ] [ af ]
+ [ protospec ] hosts [ "tag" string ] [ "tagged" string ]
+ [ "-\*(Gt" ( redirhost | "{" redirhost-list "}" )
+ [ portspec ] [ pooltype ] ]
+
+antispoof-rule = "antispoof" [ "log" ] [ "quick" ]
+ "for" ifspec [ af ] [ "label" string ]
+
+table-rule = "table" "\*(Lt" string "\*(Gt" [ tableopts-list ]
+tableopts-list = tableopts-list tableopts | tableopts
+tableopts = "persist" | "const" | "counters" | "file" string |
+ "{" [ tableaddr-list ] "}"
+tableaddr-list = tableaddr-list [ "," ] tableaddr-spec | tableaddr-spec
+tableaddr-spec = [ "!" ] tableaddr [ "/" mask-bits ]
+tableaddr = hostname | ifspec | "self" |
+ ipv4-dotted-quad | ipv6-coloned-hex
+
+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 ] [ protospec ] [ hosts ] [ filteropt-list ] [ "{" ]
+
+anchor-close = "}"
+
+trans-anchors = ( "nat-anchor" | "rdr-anchor" | "binat-anchor" ) string
+ [ "on" ifspec ] [ af ] [ "proto" ] [ protospec ] [ hosts ]
+
+load-anchor = "load anchor" string "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 ] | [ "no" ] "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-group ) ) |
+ "{" interface-list "}"
+interface-list = [ "!" ] ( interface-name | interface-group )
+ [ [ "," ] interface-list ]
+route = ( "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" | "urpf-failed" | "self" | host |
+ "{" host-list "}" ) [ port ] [ os ]
+ "to" ( "any" | "no-route" | "self" | host |
+ "{" host-list "}" ) [ port ]
+
+ipspec = "any" | host | "{" host-list "}"
+host = [ "!" ] ( address [ "/" mask-bits ] | "\*(Lt" string "\*(Gt" )
+redirhost = address [ "/" mask-bits ]
+routehost = "(" interface-name [ address [ "/" mask-bits ] ] ")"
+address = ( interface-name | interface-group |
+ "(" ( interface-name | interface-group ) ")" |
+ hostname | ipv4-dotted-quad | ipv6-coloned-hex )
+host-list = host [ [ "," ] host-list ]
+redirhost-list = redirhost [ [ "," ] redirhost-list ]
+routehost-list = routehost [ [ "," ] routehost-list ]
+
+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 = [ "=" | "!=" | "\*(Lt" | "\*(Le" | "\*(Gt" | "\*(Ge" ]
+ ( name | number )
+binary-op = number ( "\*(Lt\*(Gt" | "\*(Gt\*(Lt" | ":" ) 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 | "any" )
+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 = ( "lowdelay" | "throughput" | "reliability" |
+ [ "0x" ] number )
+
+state-opts = state-opt [ [ "," ] state-opts ]
+state-opt = ( "max" number | "no-sync" | timeout | "sloppy" | "pflow" |
+ "source-track" [ ( "rule" | "global" ) ] |
+ "max-src-nodes" number | "max-src-states" number |
+ "max-src-conn" number |
+ "max-src-conn-rate" number "/" number |
+ "overload" "\*(Lt" string "\*(Gt" [ "flush" ] |
+ "if-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 ")" )
+include = "include" filename
+.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.
+.El
+.Sh SEE ALSO
+.Xr altq 4 ,
+.Xr carp 4 ,
+.Xr icmp 4 ,
+.Xr icmp6 4 ,
+.Xr ip 4 ,
+.Xr ip6 4 ,
+.Xr pf 4 ,
+.Xr pflow 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/share/man/man5/pf.os.5 b/share/man/man5/pf.os.5
new file mode 100644
index 0000000..5930525
--- /dev/null
+++ b/share/man/man5/pf.os.5
@@ -0,0 +1,223 @@
+.\" $OpenBSD: pf.os.5,v 1.8 2007/05/31 19:19:58 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.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd May 31 2007
+.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 1
+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 vendor 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 1
+output of
+.Bd -literal
+ # tcpdump -s128 -c1 -nv 'tcp[13] == 2'
+ 03:13:48.118526 10.0.0.1.3377 > 10.0.0.2.80: S [tcp sum ok] \e
+ 534596083:534596083(0) win 57344 <mss 1460> (DF) [tos 0x10] \e
+ (ttl 64, id 11315, len 44)
+.Ed
+.Pp
+almost translates into the following fingerprint
+.Bd -literal
+ 57344:64:1:44:M1460: exampleOS:1.0::exampleOS 1.0
+.Ed
+.Sh SEE ALSO
+.Xr pf 4 ,
+.Xr pf.conf 5 ,
+.Xr pfctl 8 ,
+.Xr tcpdump 1
OpenPOWER on IntegriCloud