summaryrefslogtreecommitdiffstats
path: root/share/man/man4/pf.4
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/man/man4/pf.4
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/man/man4/pf.4')
-rw-r--r--share/man/man4/pf.41175
1 files changed, 1175 insertions, 0 deletions
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 .
OpenPOWER on IntegriCloud