summaryrefslogtreecommitdiff
path: root/static/freebsd/man4/pf.4 3.html
diff options
context:
space:
mode:
Diffstat (limited to 'static/freebsd/man4/pf.4 3.html')
-rw-r--r--static/freebsd/man4/pf.4 3.html1055
1 files changed, 1055 insertions, 0 deletions
diff --git a/static/freebsd/man4/pf.4 3.html b/static/freebsd/man4/pf.4 3.html
new file mode 100644
index 00000000..f9e8f3ee
--- /dev/null
+++ b/static/freebsd/man4/pf.4 3.html
@@ -0,0 +1,1055 @@
+<table class="head">
+ <tr>
+ <td class="head-ltitle">PF(4)</td>
+ <td class="head-vol">Device Drivers Manual</td>
+ <td class="head-rtitle">PF(4)</td>
+ </tr>
+</table>
+<div class="manual-text">
+<section class="Sh">
+<h1 class="Sh" id="NAME"><a class="permalink" href="#NAME">NAME</a></h1>
+<p class="Pp"><code class="Nm">pf</code> &#x2014; <span class="Nd">packet
+ filter</span></p>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="SYNOPSIS"><a class="permalink" href="#SYNOPSIS">SYNOPSIS</a></h1>
+<p class="Pp"><code class="Cd">device pf</code>
+ <br/>
+ <code class="Cd">options PF_DEFAULT_TO_DROP</code></p>
+<p class="Pp">In <a class="Xr">rc.conf(5)</a>:
+ <br/>
+ <code class="Cd">pf_enable=&quot;YES&quot;</code></p>
+<p class="Pp">In <a class="Xr">loader.conf(5)</a>:
+ <br/>
+ <code class="Cd">net.pf.states_hashsize</code>
+ <br/>
+ <code class="Cd">net.pf.source_nodes_hashsize</code>
+ <br/>
+ <code class="Cd">net.pf.rule_tag_hashsize</code>
+ <br/>
+ <code class="Cd">net.pf.udpendpoint_hashsize</code>
+ <br/>
+ <code class="Cd">net.pf.default_to_drop</code></p>
+<p class="Pp">In <a class="Xr">sysctl.conf(5)</a>:
+ <br/>
+ <code class="Cd">net.pf.request_maxcount</code>
+ <br/>
+ <code class="Cd">net.pf.filter_local</code></p>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="DESCRIPTION"><a class="permalink" href="#DESCRIPTION">DESCRIPTION</a></h1>
+<p class="Pp">Packet filtering takes place in the kernel. A pseudo-device,
+ <span class="Pa">/dev/pf</span>, allows userland processes to control the
+ behavior of the packet filter through an <a class="Xr">ioctl(2)</a>
+ 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
+ <a class="Xr">pfctl(8)</a>.</p>
+<p class="Pp" id="ticket">Manipulations like loading a ruleset that involve more
+ than a single <a class="Xr">ioctl(2)</a> call require a so-called
+ <a class="permalink" href="#ticket"><i class="Em">ticket</i></a>, which
+ prevents the occurrence of multiple concurrent manipulations.</p>
+<p class="Pp">Fields of <a class="Xr">ioctl(2)</a> parameter structures that
+ refer to packet data (like addresses and ports) are generally expected in
+ network byte-order.</p>
+<p class="Pp" id="anchors">Rules and address tables are contained in so-called
+ <a class="permalink" href="#anchors"><i class="Em">anchors</i></a>. When
+ servicing an <a class="Xr">ioctl(2)</a> 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 &#x2018;/&#x2019; 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.</p>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="SYSCTL_VARIABLES"><a class="permalink" href="#SYSCTL_VARIABLES">SYSCTL
+ VARIABLES</a></h1>
+<p class="Pp">The following variables can be entered at the
+ <a class="Xr">loader(8)</a> prompt, set in <a class="Xr">loader.conf(5)</a>,
+ <a class="Xr">sysctl.conf(5)</a>, or changed at runtime with
+ <a class="Xr">sysctl(8)</a>:</p>
+<dl class="Bl-tag">
+ <dt id="net.pf.filter_local"><var class="Va">net.pf.filter_local</var></dt>
+ <dd>This tells <code class="Nm">pf</code> to also filter on the loopback
+ output hook. This is typically used to allow redirect rules to adjust the
+ source address.</dd>
+ <dt id="net.pf.request_maxcount"><var class="Va">net.pf.request_maxcount</var></dt>
+ <dd>The maximum number of items in a single ioctl call.</dd>
+</dl>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="LOADER_TUNABLES"><a class="permalink" href="#LOADER_TUNABLES">LOADER
+ TUNABLES</a></h1>
+<p class="Pp">The following tunables can be entered at the
+ <a class="Xr">loader(8)</a> prompt, or set in
+ <a class="Xr">loader.conf(5)</a>:</p>
+<dl class="Bl-tag">
+ <dt id="net.pf.states_hashsize"><var class="Va">net.pf.states_hashsize</var></dt>
+ <dd>Size of hash table that stores states. Should be power of 2. Default value
+ is 131072.</dd>
+ <dt id="net.pf.source_nodes_hashsize"><var class="Va">net.pf.source_nodes_hashsize</var></dt>
+ <dd>Size of hash table that stores source nodes. Should be power of 2. Default
+ value is 32768.</dd>
+ <dt id="net.pf.rule_tag_hashsize"><var class="Va">net.pf.rule_tag_hashsize</var></dt>
+ <dd>Size of the hash table that stores tags.</dd>
+ <dt id="net.pf.udpendpoint_hashsize"><var class="Va">net.pf.udpendpoint_hashsize</var></dt>
+ <dd>Size of hash table that store UDP endpoint mappings. Should be power of 2.
+ Default value is 32768.</dd>
+ <dt id="net.pf.default_to_drop"><var class="Va">net.pf.default_to_drop</var></dt>
+ <dd>This value overrides <code class="Cd">options PF_DEFAULT_TO_DROP</code>
+ from kernel configuration file.</dd>
+ <dt id="net.pf.filter_local~2"><var class="Va">net.pf.filter_local</var></dt>
+ <dd>This tells <code class="Nm">pf</code> to also filter on the loopback
+ output hook. This is typically used to allow redirect rules to adjust the
+ source address.</dd>
+ <dt id="net.pf.request_maxcount~2"><var class="Va">net.pf.request_maxcount</var></dt>
+ <dd>The maximum number of items in a single ioctl call.</dd>
+</dl>
+<p class="Pp">Read only <a class="Xr">sysctl(8)</a> variables with matching
+ names are provided to obtain current values at runtime.</p>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="KERNEL_OPTIONS"><a class="permalink" href="#KERNEL_OPTIONS">KERNEL
+ OPTIONS</a></h1>
+<p class="Pp">The following options in the kernel configuration file are related
+ to <code class="Nm">pf</code> operation:</p>
+<p class="Pp"></p>
+<dl class="Bl-tag Bl-compact">
+ <dt id="PF_DEFAULT_TO_DROP"><a class="permalink" href="#PF_DEFAULT_TO_DROP"><code class="Dv">PF_DEFAULT_TO_DROP</code></a></dt>
+ <dd>Change default policy to drop by default</dd>
+</dl>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="IOCTL_INTERFACE"><a class="permalink" href="#IOCTL_INTERFACE">IOCTL
+ INTERFACE</a></h1>
+<p class="Pp"><code class="Nm">pf</code> supports the following
+ <a class="Xr">ioctl(2)</a> commands, available through
+ &#x27E8;<span class="Pa">net/pfvar.h</span>&#x27E9;:</p>
+<dl class="Bl-tag">
+ <dt id="DIOCSTART"><a class="permalink" href="#DIOCSTART"><code class="Dv">DIOCSTART</code></a></dt>
+ <dd>Start the packet filter.</dd>
+ <dt id="DIOCSTOP"><a class="permalink" href="#DIOCSTOP"><code class="Dv">DIOCSTOP</code></a></dt>
+ <dd>Stop the packet filter.</dd>
+ <dt id="DIOCSTARTALTQ"><a class="permalink" href="#DIOCSTARTALTQ"><code class="Dv">DIOCSTARTALTQ</code></a></dt>
+ <dd>Start the ALTQ bandwidth control system (see
+ <a class="Xr">altq(9)</a>).</dd>
+ <dt id="DIOCSTOPALTQ"><a class="permalink" href="#DIOCSTOPALTQ"><code class="Dv">DIOCSTOPALTQ</code></a></dt>
+ <dd>Stop the ALTQ bandwidth control system.</dd>
+ <dt id="DIOCBEGINADDRS"><a class="permalink" href="#DIOCBEGINADDRS"><code class="Dv">DIOCBEGINADDRS</code></a>
+ <var class="Fa">struct pfioc_pooladdr *pp</var></dt>
+ <dd>
+ <div class="Bd Pp Li">
+ <pre>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;
+};</pre>
+ </div>
+ <p class="Pp">Clear the buffer address pool and get a
+ <var class="Va">ticket</var> for subsequent
+ <code class="Dv">DIOCADDADDR</code>,
+ <code class="Dv">DIOCADDRULE</code>, and
+ <code class="Dv">DIOCCHANGERULE</code> calls.</p>
+ </dd>
+ <dt id="DIOCADDADDR"><a class="permalink" href="#DIOCADDADDR"><code class="Dv">DIOCADDADDR</code></a>
+ <var class="Fa">struct pfioc_pooladdr *pp</var></dt>
+ <dd>
+ <p class="Pp">Add the pool address <var class="Va">addr</var> to the buffer
+ address pool to be used in the following
+ <code class="Dv">DIOCADDRULE</code> or
+ <code class="Dv">DIOCCHANGERULE</code> call. All other members of the
+ structure are ignored.</p>
+ </dd>
+ <dt id="DIOCADDRULE"><a class="permalink" href="#DIOCADDRULE"><code class="Dv">DIOCADDRULE</code></a>
+ <var class="Fa">struct pfioc_rule *pr</var></dt>
+ <dd>
+ <div class="Bd Pp Li">
+ <pre>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;
+};</pre>
+ </div>
+ <p class="Pp">Add <var class="Va">rule</var> at the end of the inactive
+ ruleset. This call requires a <var class="Va">ticket</var> obtained
+ through a preceding <code class="Dv">DIOCXBEGIN</code> call and a
+ <var class="Va">pool_ticket</var> obtained through a
+ <code class="Dv">DIOCBEGINADDRS</code> call.
+ <code class="Dv">DIOCADDADDR</code> must also be called if any pool
+ addresses are required. The optional <var class="Va">anchor</var> name
+ indicates the anchor in which to append the rule.
+ <var class="Va">nr</var> and <var class="Va">action</var> are
+ ignored.</p>
+ </dd>
+ <dt id="DIOCADDALTQ"><a class="permalink" href="#DIOCADDALTQ"><code class="Dv">DIOCADDALTQ</code></a>
+ <var class="Fa">struct pfioc_altq *pa</var></dt>
+ <dd>Add an ALTQ discipline or queue.
+ <div class="Bd Pp Li">
+ <pre>struct pfioc_altq {
+ u_int32_t action;
+ u_int32_t ticket;
+ u_int32_t nr;
+ struct pf_altq altq;
+};</pre>
+ </div>
+ </dd>
+ <dt id="DIOCGETRULES"><a class="permalink" href="#DIOCGETRULES"><code class="Dv">DIOCGETRULES</code></a>
+ <var class="Fa">struct pfioc_rule *pr</var></dt>
+ <dd>Get a <var class="Va">ticket</var> for subsequent
+ <code class="Dv">DIOCGETRULE</code> calls and the number
+ <var class="Va">nr</var> of rules in the active ruleset.</dd>
+ <dt id="DIOCGETRULE"><a class="permalink" href="#DIOCGETRULE"><code class="Dv">DIOCGETRULE</code></a>
+ <var class="Fa">struct pfioc_rule *pr</var></dt>
+ <dd>Get a <var class="Va">rule</var> by its number <var class="Va">nr</var>
+ using the <var class="Va">ticket</var> obtained through a preceding
+ <code class="Dv">DIOCGETRULES</code> call. If <var class="Va">action</var>
+ is set to <code class="Dv">PF_GET_CLR_CNTR</code>, the per-rule statistics
+ on the requested rule are cleared.</dd>
+ <dt id="DIOCGETADDRS"><a class="permalink" href="#DIOCGETADDRS"><code class="Dv">DIOCGETADDRS</code></a>
+ <var class="Fa">struct pfioc_pooladdr *pp</var></dt>
+ <dd>Get a <var class="Va">ticket</var> for subsequent
+ <code class="Dv">DIOCGETADDR</code> calls and the number
+ <var class="Va">nr</var> of pool addresses in the rule specified with
+ <var class="Va">r_action</var>, <var class="Va">r_num</var>, and
+ <var class="Va">anchor</var>.</dd>
+ <dt id="DIOCGETADDR"><a class="permalink" href="#DIOCGETADDR"><code class="Dv">DIOCGETADDR</code></a>
+ <var class="Fa">struct pfioc_pooladdr *pp</var></dt>
+ <dd>Get the pool address <var class="Va">addr</var> by its number
+ <var class="Va">nr</var> from the rule specified with
+ <var class="Va">r_action</var>, <var class="Va">r_num</var>, and
+ <var class="Va">anchor</var> using the <var class="Va">ticket</var>
+ obtained through a preceding <code class="Dv">DIOCGETADDRS</code>
+ call.</dd>
+ <dt id="DIOCGETALTQS"><a class="permalink" href="#DIOCGETALTQS"><code class="Dv">DIOCGETALTQS</code></a>
+ <var class="Fa">struct pfioc_altq *pa</var></dt>
+ <dd>Get a <var class="Va">ticket</var> for subsequent
+ <code class="Dv">DIOCGETALTQ</code> calls and the number
+ <var class="Va">nr</var> of queues in the active list.</dd>
+ <dt id="DIOCGETALTQ"><a class="permalink" href="#DIOCGETALTQ"><code class="Dv">DIOCGETALTQ</code></a>
+ <var class="Fa">struct pfioc_altq *pa</var></dt>
+ <dd>Get the queueing discipline <var class="Va">altq</var> by its number
+ <var class="Va">nr</var> using the <var class="Va">ticket</var> obtained
+ through a preceding <code class="Dv">DIOCGETALTQS</code> call.</dd>
+ <dt id="DIOCGETQSTATS"><a class="permalink" href="#DIOCGETQSTATS"><code class="Dv">DIOCGETQSTATS</code></a>
+ <var class="Fa">struct pfioc_qstats *pq</var></dt>
+ <dd>Get the statistics on a queue.
+ <div class="Bd Pp Li">
+ <pre>struct pfioc_qstats {
+ u_int32_t ticket;
+ u_int32_t nr;
+ void *buf;
+ int nbytes;
+ u_int8_t scheduler;
+};</pre>
+ </div>
+ <p class="Pp">This call fills in a pointer to the buffer of statistics
+ <var class="Va">buf</var>, of length <var class="Va">nbytes</var>, for
+ the queue specified by <var class="Va">nr</var>.</p>
+ </dd>
+ <dt id="DIOCGETRULESETS"><a class="permalink" href="#DIOCGETRULESETS"><code class="Dv">DIOCGETRULESETS</code></a>
+ <var class="Fa">struct pfioc_ruleset *pr</var></dt>
+ <dd>
+ <div class="Bd Pp Li">
+ <pre>struct pfioc_ruleset {
+ u_int32_t nr;
+ char path[MAXPATHLEN];
+ char name[PF_ANCHOR_NAME_SIZE];
+};</pre>
+ </div>
+ <p class="Pp">Get the number <var class="Va">nr</var> of rulesets (i.e.,
+ anchors) directly attached to the anchor named by
+ <var class="Va">path</var> for use in subsequent
+ <code class="Dv">DIOCGETRULESET</code> calls. Nested anchors, since they
+ are not directly attached to the given anchor, will not be included.
+ This ioctl returns <code class="Er">ENOENT</code> if the parent anchor
+ given at <var class="Va">path</var> does not exist.</p>
+ </dd>
+ <dt id="DIOCGETRULESET"><a class="permalink" href="#DIOCGETRULESET"><code class="Dv">DIOCGETRULESET</code></a>
+ <var class="Fa">struct pfioc_ruleset *pr</var></dt>
+ <dd>Get a ruleset (i.e., an anchor) <var class="Va">name</var> by its number
+ <var class="Va">nr</var> from the given anchor <var class="Va">path</var>,
+ the maximum number of which can be obtained from a preceding
+ <code class="Dv">DIOCGETRULESETS</code> call. This ioctl returns
+ <code class="Er">ENOENT</code> if the parent anchor given by
+ <var class="Va">path</var> does not exist or <code class="Er">EBUSY</code>
+ if the index passed in by <var class="Va">nr</var> is greater than the
+ number of anchors.</dd>
+ <dt id="DIOCADDSTATE"><a class="permalink" href="#DIOCADDSTATE"><code class="Dv">DIOCADDSTATE</code></a>
+ <var class="Fa">struct pfioc_state *ps</var></dt>
+ <dd>Add a state entry.
+ <div class="Bd Pp Li">
+ <pre>struct pfioc_state {
+ struct pfsync_state state;
+};</pre>
+ </div>
+ </dd>
+ <dt id="DIOCGETSTATENV"><a class="permalink" href="#DIOCGETSTATENV"><code class="Dv">DIOCGETSTATENV</code></a>
+ <var class="Fa">struct pfioc_nv *nv</var></dt>
+ <dd>Extract the entry identified by the <var class="Va">id</var> and
+ <var class="Va">creatorid</var> fields of the <var class="Va">state</var>
+ nvlist from the state table.</dd>
+ <dt id="DIOCKILLSTATESNV"><a class="permalink" href="#DIOCKILLSTATESNV"><code class="Dv">DIOCKILLSTATESNV</code></a>
+ <var class="Fa">struct pfioc_nv nv</var></dt>
+ <dd>Remove matching entries from the state table. This ioctl returns the
+ number of killed states in <var class="Va">killed</var>.
+ <div class="Bd Pp Li">
+ <pre>nvlist pf_state_cmp {
+ number id;
+ number creatorid;
+ number direction;
+};
+
+nvlist pf_kill {
+ nvlist pf_state_cmp cmp;
+ number af;
+ number proto;
+ nvlist pf_rule_addr src;
+ nvlist pf_rule_addr dst;
+ string ifname[IFNAMSIZ];
+ string label[PF_RULE_LABEL_SIZE];
+};</pre>
+ </div>
+ </dd>
+ <dt id="DIOCCLRSTATESNV"><a class="permalink" href="#DIOCCLRSTATESNV"><code class="Dv">DIOCCLRSTATESNV</code></a>
+ <var class="Fa">struct pfioc_nv nv</var></dt>
+ <dd>Clear all states. It works like <code class="Dv">DIOCKILLSTATESNV</code>,
+ but ignores the <var class="Va">af</var>, <var class="Va">proto</var>,
+ <var class="Va">src</var>, and <var class="Va">dst</var> fields of the
+ <var class="Vt">pf_kill</var> nvlist.</dd>
+ <dt id="DIOCSETSTATUSIF"><a class="permalink" href="#DIOCSETSTATUSIF"><code class="Dv">DIOCSETSTATUSIF</code></a>
+ <var class="Fa">struct pfioc_if *pi</var></dt>
+ <dd>Specify the interface for which statistics are accumulated.
+ <div class="Bd Pp Li">
+ <pre>struct pfioc_if {
+ char ifname[IFNAMSIZ];
+};</pre>
+ </div>
+ </dd>
+ <dt id="DIOCGETSTATUS"><a class="permalink" href="#DIOCGETSTATUS"><code class="Dv">DIOCGETSTATUS</code></a>
+ <var class="Fa">struct pf_status *s</var></dt>
+ <dd>Get the internal packet filter statistics.
+ <div class="Bd Pp Li">
+ <pre>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];
+};</pre>
+ </div>
+ </dd>
+ <dt id="DIOCCLRSTATUS"><a class="permalink" href="#DIOCCLRSTATUS"><code class="Dv">DIOCCLRSTATUS</code></a></dt>
+ <dd>Clear the internal packet filter statistics.</dd>
+ <dt id="DIOCNATLOOK"><a class="permalink" href="#DIOCNATLOOK"><code class="Dv">DIOCNATLOOK</code></a>
+ <var class="Fa">struct pfioc_natlook *pnl</var></dt>
+ <dd>Look up a state table entry by source and destination addresses and ports.
+ <div class="Bd Pp Li">
+ <pre>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;
+};</pre>
+ </div>
+ </dd>
+ <dt id="DIOCSETDEBUG"><a class="permalink" href="#DIOCSETDEBUG"><code class="Dv">DIOCSETDEBUG</code></a>
+ <var class="Fa">u_int32_t *level</var></dt>
+ <dd>Set the debug level.
+ <div class="Bd Pp Li">
+ <pre>enum { PF_DEBUG_NONE, PF_DEBUG_URGENT, PF_DEBUG_MISC,
+ PF_DEBUG_NOISY };</pre>
+ </div>
+ </dd>
+ <dt id="DIOCGETSTATESV2"><a class="permalink" href="#DIOCGETSTATESV2"><code class="Dv">DIOCGETSTATESV2</code></a>
+ <var class="Fa">struct pfioc_states_v2 *ps</var></dt>
+ <dd>Get state table entries.
+ <div class="Bd Pp Li">
+ <pre>struct pfioc_states_v2 {
+ int ps_len;
+ uint64_t ps_req_version;
+ union {
+ void *ps_buf;
+ struct pf_state_export *ps_states;
+ };
+};
+
+struct pf_state_export {
+ uint64_t version;
+ uint64_t id;
+ char ifname[IFNAMSIZ];
+ char orig_ifname[IFNAMSIZ];
+ struct pf_state_key_export key[2];
+ struct pf_state_peer_export src;
+ struct pf_state_peer_export dst;
+ struct pf_addr rt_addr;
+ uint32_t rule;
+ uint32_t anchor;
+ uint32_t nat_rule;
+ uint32_t creation;
+ uint32_t expire;
+ uint32_t spare0;
+ uint64_t packets[2];
+ uint64_t bytes[2];
+ uint32_t creatorid;
+ uint32_t spare1;
+ sa_family_t af;
+ uint8_t proto;
+ uint8_t direction;
+ uint8_t log;
+ uint8_t state_flags_compat;
+ uint8_t timeout;
+ uint8_t sync_flags;
+ uint8_t updates;
+ uint16_t state_flags;
+ uint16_t qid;
+ uint16_t pqid;
+ uint16_t dnpipe;
+ uint16_t dnrpipe;
+ int32_t rtableid;
+ uint8_t min_ttl;
+ uint8_t set_tos;
+ uint16_t max_mss;
+ uint8_t set_prio[2];
+ uint8_t rt;
+ char rt_ifname[IFNAMSIZ];
+ uint8_t spare[72];
+};</pre>
+ </div>
+ </dd>
+ <dt id="DIOCCHANGERULE"><a class="permalink" href="#DIOCCHANGERULE"><code class="Dv">DIOCCHANGERULE</code></a>
+ <var class="Fa">struct pfioc_rule *pcr</var></dt>
+ <dd>Add or remove the <var class="Va">rule</var> in the ruleset specified by
+ <var class="Va">rule.action</var>.
+ <p class="Pp">The type of operation to be performed is indicated by
+ <var class="Va">action</var>, which can be any of the following:</p>
+ <div class="Bd Pp Li">
+ <pre>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 };</pre>
+ </div>
+ <p class="Pp"><var class="Va">ticket</var> must be set to the value obtained
+ with <code class="Dv">PF_CHANGE_GET_TICKET</code> for all actions except
+ <code class="Dv">PF_CHANGE_GET_TICKET</code>.
+ <var class="Va">pool_ticket</var> must be set to the value obtained with
+ the <code class="Dv">DIOCBEGINADDRS</code> call for all actions except
+ <code class="Dv">PF_CHANGE_REMOVE</code> and
+ <code class="Dv">PF_CHANGE_GET_TICKET</code>.
+ <var class="Va">anchor</var> indicates to which anchor the operation
+ applies. <var class="Va">nr</var> indicates the rule number against
+ which <code class="Dv">PF_CHANGE_ADD_BEFORE</code>,
+ <code class="Dv">PF_CHANGE_ADD_AFTER</code>, or
+ <code class="Dv">PF_CHANGE_REMOVE</code> actions are applied.</p>
+ </dd>
+ <dt id="DIOCCHANGEADDR"><a class="permalink" href="#DIOCCHANGEADDR"><code class="Dv">DIOCCHANGEADDR</code></a>
+ <var class="Fa">struct pfioc_pooladdr *pca</var></dt>
+ <dd>Add or remove the pool address <var class="Va">addr</var> from the rule
+ specified by <var class="Va">r_action</var>, <var class="Va">r_num</var>,
+ and <var class="Va">anchor</var>.</dd>
+ <dt id="DIOCSETTIMEOUT"><a class="permalink" href="#DIOCSETTIMEOUT"><code class="Dv">DIOCSETTIMEOUT</code></a>
+ <var class="Fa">struct pfioc_tm *pt</var></dt>
+ <dd>
+ <div class="Bd Pp Li">
+ <pre>struct pfioc_tm {
+ int timeout;
+ int seconds;
+};</pre>
+ </div>
+ <p class="Pp">Set the state timeout of <var class="Va">timeout</var> to
+ <var class="Va">seconds</var>. The old value will be placed into
+ <var class="Va">seconds</var>. For possible values of
+ <var class="Va">timeout</var>, consult the
+ <code class="Dv">PFTM_*</code> values in
+ &#x27E8;<span class="Pa">net/pfvar.h</span>&#x27E9;.</p>
+ </dd>
+ <dt id="DIOCGETTIMEOUT"><a class="permalink" href="#DIOCGETTIMEOUT"><code class="Dv">DIOCGETTIMEOUT</code></a>
+ <var class="Fa">struct pfioc_tm *pt</var></dt>
+ <dd>Get the state timeout of <var class="Va">timeout</var>. The value will be
+ placed into the <var class="Va">seconds</var> field.</dd>
+ <dt id="DIOCCLRRULECTRS"><a class="permalink" href="#DIOCCLRRULECTRS"><code class="Dv">DIOCCLRRULECTRS</code></a></dt>
+ <dd>Clear per-rule statistics.</dd>
+ <dt id="DIOCSETLIMIT"><a class="permalink" href="#DIOCSETLIMIT"><code class="Dv">DIOCSETLIMIT</code></a>
+ <var class="Fa">struct pfioc_limit *pl</var></dt>
+ <dd>Set the hard limits on the memory pools used by the packet filter.
+ <div class="Bd Pp Li">
+ <pre>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 };</pre>
+ </div>
+ </dd>
+ <dt id="DIOCGETLIMIT"><a class="permalink" href="#DIOCGETLIMIT"><code class="Dv">DIOCGETLIMIT</code></a>
+ <var class="Fa">struct pfioc_limit *pl</var></dt>
+ <dd>Get the hard <var class="Va">limit</var> for the memory pool indicated by
+ <var class="Va">index</var>.</dd>
+ <dt id="DIOCRCLRTABLES"><a class="permalink" href="#DIOCRCLRTABLES"><code class="Dv">DIOCRCLRTABLES</code></a>
+ <var class="Fa">struct pfioc_table *io</var></dt>
+ <dd>Clear all tables. All the ioctls that manipulate radix tables use the same
+ structure described below. For <code class="Dv">DIOCRCLRTABLES</code>,
+ <var class="Va">pfrio_ndel</var> contains on exit the number of tables
+ deleted.
+ <div class="Bd Pp Li">
+ <pre>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</pre>
+ </div>
+ </dd>
+ <dt id="DIOCRADDTABLES"><a class="permalink" href="#DIOCRADDTABLES"><code class="Dv">DIOCRADDTABLES</code></a>
+ <var class="Fa">struct pfioc_table *io</var></dt>
+ <dd>Create one or more tables. On entry, <var class="Va">pfrio_buffer</var>
+ must point to an array of <var class="Vt">struct pfr_table</var>
+ containing at least <var class="Vt">pfrio_size</var> elements.
+ <var class="Vt">pfrio_esize</var> must be the size of
+ <var class="Vt">struct pfr_table</var>. On exit,
+ <var class="Va">pfrio_nadd</var> contains the number of tables effectively
+ created.
+ <div class="Bd Pp Li">
+ <pre>struct pfr_table {
+ char pfrt_anchor[MAXPATHLEN];
+ char pfrt_name[PF_TABLE_NAME_SIZE];
+ u_int32_t pfrt_flags;
+ u_int8_t pfrt_fback;
+};</pre>
+ </div>
+ </dd>
+ <dt id="DIOCRDELTABLES"><a class="permalink" href="#DIOCRDELTABLES"><code class="Dv">DIOCRDELTABLES</code></a>
+ <var class="Fa">struct pfioc_table *io</var></dt>
+ <dd>Delete one or more tables. On entry, <var class="Va">pfrio_buffer</var>
+ must point to an array of <var class="Vt">struct pfr_table</var>
+ containing at least <var class="Vt">pfrio_size</var> elements.
+ <var class="Vt">pfrio_esize</var> must be the size of
+ <var class="Vt">struct pfr_table</var>. On exit,
+ <var class="Va">pfrio_ndel</var> contains the number of tables effectively
+ deleted.</dd>
+ <dt id="DIOCRGETTABLES"><a class="permalink" href="#DIOCRGETTABLES"><code class="Dv">DIOCRGETTABLES</code></a>
+ <var class="Fa">struct pfioc_table *io</var></dt>
+ <dd>Get the list of all tables. On entry,
+ <var class="Va">pfrio_buffer[pfrio_size]</var> contains a valid writeable
+ buffer for <var class="Vt">pfr_table</var> structures. On exit,
+ <var class="Va">pfrio_size</var> 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.</dd>
+ <dt id="DIOCRGETTSTATS"><a class="permalink" href="#DIOCRGETTSTATS"><code class="Dv">DIOCRGETTSTATS</code></a>
+ <var class="Fa">struct pfioc_table *io</var></dt>
+ <dd>This call is like <code class="Dv">DIOCRGETTABLES</code> but is used to
+ get an array of <var class="Vt">pfr_tstats</var> structures.
+ <div class="Bd Pp Li">
+ <pre>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;
+ time_t 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</pre>
+ </div>
+ </dd>
+ <dt id="DIOCRCLRTSTATS"><a class="permalink" href="#DIOCRCLRTSTATS"><code class="Dv">DIOCRCLRTSTATS</code></a>
+ <var class="Fa">struct pfioc_table *io</var></dt>
+ <dd>Clear the statistics of one or more tables. On entry,
+ <var class="Va">pfrio_buffer</var> must point to an array of
+ <var class="Vt">struct pfr_table</var> containing at least
+ <var class="Vt">pfrio_size</var> elements.
+ <var class="Vt">pfrio_esize</var> must be the size of
+ <var class="Vt">struct pfr_table</var>. On exit,
+ <var class="Va">pfrio_nzero</var> contains the number of tables
+ effectively cleared.</dd>
+ <dt id="DIOCRCLRADDRS"><a class="permalink" href="#DIOCRCLRADDRS"><code class="Dv">DIOCRCLRADDRS</code></a>
+ <var class="Fa">struct pfioc_table *io</var></dt>
+ <dd>Clear all addresses in a table. On entry,
+ <var class="Va">pfrio_table</var> contains the table to clear. On exit,
+ <var class="Va">pfrio_ndel</var> contains the number of addresses
+ removed.</dd>
+ <dt id="DIOCRADDADDRS"><a class="permalink" href="#DIOCRADDADDRS"><code class="Dv">DIOCRADDADDRS</code></a>
+ <var class="Fa">struct pfioc_table *io</var></dt>
+ <dd>Add one or more addresses to a table. On entry,
+ <var class="Va">pfrio_table</var> contains the table ID and
+ <var class="Va">pfrio_buffer</var> must point to an array of
+ <var class="Vt">struct pfr_addr</var> containing at least
+ <var class="Vt">pfrio_size</var> elements to add to the table.
+ <var class="Vt">pfrio_esize</var> must be the size of
+ <var class="Vt">struct pfr_addr</var>. On exit,
+ <var class="Va">pfrio_nadd</var> contains the number of addresses
+ effectively added.
+ <div class="Bd Pp Li">
+ <pre>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</pre>
+ </div>
+ </dd>
+ <dt id="DIOCRDELADDRS"><a class="permalink" href="#DIOCRDELADDRS"><code class="Dv">DIOCRDELADDRS</code></a>
+ <var class="Fa">struct pfioc_table *io</var></dt>
+ <dd>Delete one or more addresses from a table. On entry,
+ <var class="Va">pfrio_table</var> contains the table ID and
+ <var class="Va">pfrio_buffer</var> must point to an array of
+ <var class="Vt">struct pfr_addr</var> containing at least
+ <var class="Vt">pfrio_size</var> elements to delete from the table.
+ <var class="Vt">pfrio_esize</var> must be the size of
+ <var class="Vt">struct pfr_addr</var>. On exit,
+ <var class="Va">pfrio_ndel</var> contains the number of addresses
+ effectively deleted.</dd>
+ <dt id="DIOCRSETADDRS"><a class="permalink" href="#DIOCRSETADDRS"><code class="Dv">DIOCRSETADDRS</code></a>
+ <var class="Fa">struct pfioc_table *io</var></dt>
+ <dd>Replace the content of a table by a new address list. This is the most
+ complicated command, which uses all the structure members.
+ <p class="Pp">On entry, <var class="Va">pfrio_table</var> contains the table
+ ID and <var class="Va">pfrio_buffer</var> must point to an array of
+ <var class="Vt">struct pfr_addr</var> containing at least
+ <var class="Vt">pfrio_size</var> elements which become the new contents
+ of the table. <var class="Vt">pfrio_esize</var> must be the size of
+ <var class="Vt">struct pfr_addr</var>. Additionally, if
+ <var class="Va">pfrio_size2</var> is non-zero,
+ <var class="Va">pfrio_buffer[pfrio_size..pfrio_size2]</var> must be a
+ writeable buffer, into which the kernel can copy the addresses that have
+ been deleted during the replace operation. On exit,
+ <var class="Va">pfrio_ndel</var>, <var class="Va">pfrio_nadd</var>, and
+ <var class="Va">pfrio_nchange</var> contain the number of addresses
+ deleted, added, and changed by the kernel. If
+ <var class="Va">pfrio_size2</var> was set on entry,
+ <var class="Va">pfrio_size2</var> will point to the size of the buffer
+ used, exactly like <code class="Dv">DIOCRGETADDRS</code>.</p>
+ </dd>
+ <dt id="DIOCRGETADDRS"><a class="permalink" href="#DIOCRGETADDRS"><code class="Dv">DIOCRGETADDRS</code></a>
+ <var class="Fa">struct pfioc_table *io</var></dt>
+ <dd>Get all the addresses of a table. On entry,
+ <var class="Va">pfrio_table</var> contains the table ID and
+ <var class="Va">pfrio_buffer[pfrio_size]</var> contains a valid writeable
+ buffer for <var class="Vt">pfr_addr</var> structures. On exit,
+ <var class="Va">pfrio_size</var> 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.</dd>
+ <dt id="DIOCRGETASTATS"><a class="permalink" href="#DIOCRGETASTATS"><code class="Dv">DIOCRGETASTATS</code></a>
+ <var class="Fa">struct pfioc_table *io</var></dt>
+ <dd>This call is like <code class="Dv">DIOCRGETADDRS</code> but is used to get
+ an array of <var class="Vt">pfr_astats</var> structures.
+ <div class="Bd Pp Li">
+ <pre>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];
+ time_t pfras_tzero;
+};</pre>
+ </div>
+ </dd>
+ <dt id="DIOCRCLRASTATS"><a class="permalink" href="#DIOCRCLRASTATS"><code class="Dv">DIOCRCLRASTATS</code></a>
+ <var class="Fa">struct pfioc_table *io</var></dt>
+ <dd>Clear the statistics of one or more addresses. On entry,
+ <var class="Va">pfrio_table</var> contains the table ID and
+ <var class="Va">pfrio_buffer</var> must point to an array of
+ <var class="Vt">struct pfr_addr</var> containing at least
+ <var class="Vt">pfrio_size</var> elements to be cleared from the table.
+ <var class="Vt">pfrio_esize</var> must be the size of
+ <var class="Vt">struct pfr_addr</var>. On exit,
+ <var class="Va">pfrio_nzero</var> contains the number of addresses
+ effectively cleared.</dd>
+ <dt id="DIOCRTSTADDRS"><a class="permalink" href="#DIOCRTSTADDRS"><code class="Dv">DIOCRTSTADDRS</code></a>
+ <var class="Fa">struct pfioc_table *io</var></dt>
+ <dd>Test if the given addresses match a table. On entry,
+ <var class="Va">pfrio_table</var> contains the table ID and
+ <var class="Va">pfrio_buffer</var> must point to an array of
+ <var class="Vt">struct pfr_addr</var> containing at least
+ <var class="Vt">pfrio_size</var> elements, each of which will be tested
+ for a match in the table. <var class="Vt">pfrio_esize</var> must be the
+ size of <var class="Vt">struct pfr_addr</var>. On exit, the kernel updates
+ the <var class="Vt">pfr_addr</var> array by setting the
+ <var class="Va">pfra_fback</var> member appropriately.</dd>
+ <dt id="DIOCRSETTFLAGS"><a class="permalink" href="#DIOCRSETTFLAGS"><code class="Dv">DIOCRSETTFLAGS</code></a>
+ <var class="Fa">struct pfioc_table *io</var></dt>
+ <dd>Change the <code class="Dv">PFR_TFLAG_CONST</code> or
+ <code class="Dv">PFR_TFLAG_PERSIST</code> flags of a table. On entry,
+ <var class="Va">pfrio_buffer</var> must point to an array of
+ <var class="Vt">struct pfr_table</var> containing at least
+ <var class="Vt">pfrio_size</var> elements.
+ <var class="Va">pfrio_esize</var> must be the size of
+ <var class="Vt">struct pfr_table</var>.
+ <var class="Va">pfrio_setflag</var> must contain the flags to add, while
+ <var class="Va">pfrio_clrflag</var> must contain the flags to remove. On
+ exit, <var class="Va">pfrio_nchange</var> and
+ <var class="Va">pfrio_ndel</var> contain the number of tables altered or
+ deleted by the kernel. Yes, tables can be deleted if one removes the
+ <code class="Dv">PFR_TFLAG_PERSIST</code> flag of an unreferenced
+ table.</dd>
+ <dt id="DIOCRINADEFINE"><a class="permalink" href="#DIOCRINADEFINE"><code class="Dv">DIOCRINADEFINE</code></a>
+ <var class="Fa">struct pfioc_table *io</var></dt>
+ <dd>Defines a table in the inactive set. On entry,
+ <var class="Va">pfrio_table</var> contains the table ID and
+ <var class="Va">pfrio_buffer[pfrio_size]</var> contains an array of
+ <var class="Vt">pfr_addr</var> structures to put in the table. A valid
+ ticket must also be supplied to <var class="Va">pfrio_ticket</var>. On
+ exit, <var class="Va">pfrio_nadd</var> contains 0 if the table was already
+ defined in the inactive list or 1 if a new table has been created.
+ <var class="Va">pfrio_naddr</var> contains the number of addresses
+ effectively put in the table.</dd>
+ <dt id="DIOCXBEGIN"><a class="permalink" href="#DIOCXBEGIN"><code class="Dv">DIOCXBEGIN</code></a>
+ <var class="Fa">struct pfioc_trans *io</var></dt>
+ <dd>
+ <div class="Bd Pp Li">
+ <pre>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;
+};</pre>
+ </div>
+ <p class="Pp">Clear all the inactive rulesets specified in the
+ <var class="Vt">pfioc_trans_e</var> array. For each ruleset, a ticket is
+ returned for subsequent &quot;add rule&quot; ioctls, as well as for the
+ <code class="Dv">DIOCXCOMMIT</code> and
+ <code class="Dv">DIOCXROLLBACK</code> calls.</p>
+ <p class="Pp">Ruleset types, identified by <var class="Va">rs_num</var>,
+ include the following:</p>
+ <p class="Pp"></p>
+ <div class="Bd-indent">
+ <dl class="Bl-tag Bl-compact">
+ <dt id="PF_RULESET_SCRUB"><a class="permalink" href="#PF_RULESET_SCRUB"><code class="Dv">PF_RULESET_SCRUB</code></a></dt>
+ <dd>Scrub (packet normalization) rules.</dd>
+ <dt id="PF_RULESET_FILTER"><a class="permalink" href="#PF_RULESET_FILTER"><code class="Dv">PF_RULESET_FILTER</code></a></dt>
+ <dd>Filter rules.</dd>
+ <dt id="PF_RULESET_NAT"><a class="permalink" href="#PF_RULESET_NAT"><code class="Dv">PF_RULESET_NAT</code></a></dt>
+ <dd>NAT (Network Address Translation) rules.</dd>
+ <dt id="PF_RULESET_BINAT"><a class="permalink" href="#PF_RULESET_BINAT"><code class="Dv">PF_RULESET_BINAT</code></a></dt>
+ <dd>Bidirectional NAT rules.</dd>
+ <dt id="PF_RULESET_RDR"><a class="permalink" href="#PF_RULESET_RDR"><code class="Dv">PF_RULESET_RDR</code></a></dt>
+ <dd>Redirect rules.</dd>
+ <dt id="PF_RULESET_ALTQ"><a class="permalink" href="#PF_RULESET_ALTQ"><code class="Dv">PF_RULESET_ALTQ</code></a></dt>
+ <dd>ALTQ disciplines.</dd>
+ <dt id="PF_RULESET_TABLE"><a class="permalink" href="#PF_RULESET_TABLE"><code class="Dv">PF_RULESET_TABLE</code></a></dt>
+ <dd>Address tables.</dd>
+ </dl>
+ </div>
+ </dd>
+ <dt id="DIOCXCOMMIT"><a class="permalink" href="#DIOCXCOMMIT"><code class="Dv">DIOCXCOMMIT</code></a>
+ <var class="Fa">struct pfioc_trans *io</var></dt>
+ <dd>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 <code class="Er">EBUSY</code> if another process is
+ concurrently updating some of the same rulesets.</dd>
+ <dt id="DIOCXROLLBACK"><a class="permalink" href="#DIOCXROLLBACK"><code class="Dv">DIOCXROLLBACK</code></a>
+ <var class="Fa">struct pfioc_trans *io</var></dt>
+ <dd>Clean up the kernel by undoing all changes that have taken place on the
+ inactive rulesets since the last <code class="Dv">DIOCXBEGIN</code>.
+ <code class="Dv">DIOCXROLLBACK</code> will silently ignore rulesets for
+ which the ticket is invalid.</dd>
+ <dt id="DIOCSETHOSTID"><a class="permalink" href="#DIOCSETHOSTID"><code class="Dv">DIOCSETHOSTID</code></a>
+ <var class="Fa">u_int32_t *hostid</var></dt>
+ <dd>Set the host ID, which is used by <a class="Xr">pfsync(4)</a> to identify
+ which host created state table entries.</dd>
+ <dt id="DIOCOSFPFLUSH"><a class="permalink" href="#DIOCOSFPFLUSH"><code class="Dv">DIOCOSFPFLUSH</code></a></dt>
+ <dd>Flush the passive OS fingerprint table.</dd>
+ <dt id="DIOCOSFPADD"><a class="permalink" href="#DIOCOSFPADD"><code class="Dv">DIOCOSFPADD</code></a>
+ <var class="Fa">struct pf_osfp_ioctl *io</var></dt>
+ <dd>
+ <div class="Bd Pp Li">
+ <pre>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;
+};</pre>
+ </div>
+ <p class="Pp">Add a passive OS fingerprint to the table. Set
+ <var class="Va">fp_os.fp_os</var> to the packed fingerprint,
+ <var class="Va">fp_os.fp_class_nm</var> to the name of the class (Linux,
+ Windows, etc), <var class="Va">fp_os.fp_version_nm</var> to the name of
+ the version (NT, 95, 98), and <var class="Va">fp_os.fp_subtype_nm</var>
+ to the name of the subtype or patchlevel. The members
+ <var class="Va">fp_mss</var>, <var class="Va">fp_wsize</var>,
+ <var class="Va">fp_psize</var>, <var class="Va">fp_ttl</var>,
+ <var class="Va">fp_optcnt</var>, and <var class="Va">fp_wscale</var> 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.</p>
+ <p class="Pp">The <var class="Va">fp_flags</var> member is filled according
+ to the &#x27E8;<span class="Pa">net/pfvar.h</span>&#x27E9; include file
+ <code class="Dv">PF_OSFP_*</code> defines. The
+ <var class="Va">fp_tcpopts</var> member contains packed TCP options.
+ Each option uses <code class="Dv">PF_OSFP_TCPOPT_BITS</code> bits in the
+ packed value. Options include any of
+ <code class="Dv">PF_OSFP_TCPOPT_NOP</code>,
+ <code class="Dv">PF_OSFP_TCPOPT_SACK</code>,
+ <code class="Dv">PF_OSFP_TCPOPT_WSCALE</code>,
+ <code class="Dv">PF_OSFP_TCPOPT_MSS</code>, or
+ <code class="Dv">PF_OSFP_TCPOPT_TS</code>.</p>
+ <p class="Pp">The <var class="Va">fp_getnum</var> member is not used with
+ this ioctl.</p>
+ <p class="Pp">The structure's slack space must be zeroed for correct
+ operation; <a class="Xr">memset(3)</a> the whole structure to zero
+ before filling and sending to the kernel.</p>
+ </dd>
+ <dt id="DIOCOSFPGET"><a class="permalink" href="#DIOCOSFPGET"><code class="Dv">DIOCOSFPGET</code></a>
+ <var class="Fa">struct pf_osfp_ioctl *io</var></dt>
+ <dd>Get the passive OS fingerprint number <var class="Va">fp_getnum</var> from
+ the kernel's fingerprint list. The rest of the structure members will come
+ back filled. Get the whole list by repeatedly incrementing the
+ <var class="Va">fp_getnum</var> number until the ioctl returns
+ <code class="Er">EBUSY</code>.</dd>
+ <dt id="DIOCGETSRCNODES"><a class="permalink" href="#DIOCGETSRCNODES"><code class="Dv">DIOCGETSRCNODES</code></a>
+ <var class="Fa">struct pfioc_src_nodes *psn</var></dt>
+ <dd>
+ <div class="Bd Pp Li">
+ <pre>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
+};</pre>
+ </div>
+ <p class="Pp">Get the list of source nodes kept by sticky addresses and
+ source tracking. The ioctl must be called once with
+ <var class="Va">psn_len</var> set to 0. If the ioctl returns without
+ error, <var class="Va">psn_len</var> will be set to the size of the
+ buffer required to hold all the <var class="Va">pf_src_node</var>
+ structures held in the table. A buffer of this size should then be
+ allocated, and a pointer to this buffer placed in
+ <var class="Va">psn_buf</var>. The ioctl must then be called again to
+ fill this buffer with the actual source node data. After that call,
+ <var class="Va">psn_len</var> will be set to the length of the buffer
+ actually used.</p>
+ </dd>
+ <dt id="DIOCCLRSRCNODES"><a class="permalink" href="#DIOCCLRSRCNODES"><code class="Dv">DIOCCLRSRCNODES</code></a></dt>
+ <dd>Clear the tree of source tracking nodes.</dd>
+ <dt id="DIOCIGETIFACES"><a class="permalink" href="#DIOCIGETIFACES"><code class="Dv">DIOCIGETIFACES</code></a>
+ <var class="Fa">struct pfioc_iface *io</var></dt>
+ <dd>Get the list of interfaces and interface groups known to
+ <code class="Nm">pf</code>. All the ioctls that manipulate interfaces use
+ the same structure described below:
+ <div class="Bd Pp Li">
+ <pre>struct pfioc_iface {
+ char pfiio_name[IFNAMSIZ];
+ void *pfiio_buffer;
+ int pfiio_esize;
+ int pfiio_size;
+ int pfiio_nzero;
+ int pfiio_flags;
+};</pre>
+ </div>
+ <p class="Pp">If not empty, <var class="Va">pfiio_name</var> can be used to
+ restrict the search to a specific interface or group.
+ <var class="Va">pfiio_buffer[pfiio_size]</var> is the user-supplied
+ buffer for returning the data. On entry,
+ <var class="Va">pfiio_size</var> contains the number of
+ <var class="Vt">pfi_kif</var> entries that can fit into the buffer. The
+ kernel will replace this value by the real number of entries it wants to
+ return. <var class="Va">pfiio_esize</var> should be set to
+ <code class="Li">sizeof(struct pfi_kif)</code>.</p>
+ <p class="Pp">The data is returned in the <var class="Vt">pfi_kif</var>
+ structure described below:</p>
+ <div class="Bd Pp Li">
+ <pre>struct pfi_kif {
+ char pfik_name[IFNAMSIZ];
+ union {
+ RB_ENTRY(pfi_kif) pfik_tree;
+ LIST_ENTRY(pfi_kif) pfik_list;
+ };
+ u_int64_t pfik_packets[2][2][2];
+ u_int64_t pfik_bytes[2][2][2];
+ u_int32_t pfik_tzero;
+ u_int pfik_flags;
+ struct ifnet *pfik_ifp;
+ struct ifg_group *pfik_group;
+ u_int pfik_rulerefs;
+ TAILQ_HEAD(, pfi_dynaddr) pfik_dynaddrs;
+};</pre>
+ </div>
+ </dd>
+ <dt id="DIOCSETIFFLAG"><a class="permalink" href="#DIOCSETIFFLAG"><code class="Dv">DIOCSETIFFLAG</code></a>
+ <var class="Fa">struct pfioc_iface *io</var></dt>
+ <dd>Set the user settable flags (described above) of the
+ <code class="Nm">pf</code> internal interface description. The filtering
+ process is the same as for <code class="Dv">DIOCIGETIFACES</code>.
+ <div class="Bd Pp Li">
+ <pre>#define PFI_IFLAG_SKIP 0x0100 /* skip filtering on interface */</pre>
+ </div>
+ </dd>
+ <dt id="DIOCCLRIFFLAG"><a class="permalink" href="#DIOCCLRIFFLAG"><code class="Dv">DIOCCLRIFFLAG</code></a>
+ <var class="Fa">struct pfioc_iface *io</var></dt>
+ <dd>Works as <code class="Dv">DIOCSETIFFLAG</code> above but clears the
+ flags.</dd>
+ <dt id="DIOCKILLSRCNODES"><a class="permalink" href="#DIOCKILLSRCNODES"><code class="Dv">DIOCKILLSRCNODES</code></a>
+ <var class="Fa">struct pfioc_iface *io</var></dt>
+ <dd>Explicitly remove source tracking nodes.</dd>
+</dl>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="FILES"><a class="permalink" href="#FILES">FILES</a></h1>
+<dl class="Bl-tag Bl-compact">
+ <dt><span class="Pa">/dev/pf</span></dt>
+ <dd>packet filtering device.</dd>
+</dl>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="EXAMPLES"><a class="permalink" href="#EXAMPLES">EXAMPLES</a></h1>
+<p class="Pp">The following example demonstrates how to use the
+ <code class="Dv">DIOCNATLOOK</code> command to find the internal host/port
+ of a NATed connection:</p>
+<div class="Bd Pp Li">
+<pre>#include &lt;sys/types.h&gt;
+#include &lt;sys/socket.h&gt;
+#include &lt;sys/ioctl.h&gt;
+#include &lt;sys/fcntl.h&gt;
+#include &lt;net/if.h&gt;
+#include &lt;netinet/in.h&gt;
+#include &lt;net/pfvar.h&gt;
+#include &lt;err.h&gt;
+#include &lt;stdio.h&gt;
+#include &lt;stdlib.h&gt;
+
+u_int32_t
+read_address(const char *s)
+{
+ int a, b, c, d;
+
+ sscanf(s, &quot;%i.%i.%i.%i&quot;, &amp;a, &amp;b, &amp;c, &amp;d);
+ return htonl(a &lt;&lt; 24 | b &lt;&lt; 16 | c &lt;&lt; 8 | d);
+}
+
+void
+print_address(u_int32_t a)
+{
+ a = ntohl(a);
+ printf(&quot;%d.%d.%d.%d&quot;, a &gt;&gt; 24 &amp; 255, a &gt;&gt; 16 &amp; 255,
+ a &gt;&gt; 8 &amp; 255, a &amp; 255);
+}
+
+int
+main(int argc, char *argv[])
+{
+ struct pfioc_natlook nl;
+ int dev;
+
+ if (argc != 5) {
+ printf(&quot;%s &lt;gwy addr&gt; &lt;gwy port&gt; &lt;ext addr&gt; &lt;ext port&gt;\n&quot;,
+ argv[0]);
+ return 1;
+ }
+
+ dev = open(&quot;/dev/pf&quot;, O_RDWR);
+ if (dev == -1)
+ err(1, &quot;open(\&quot;/dev/pf\&quot;) failed&quot;);
+
+ memset(&amp;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, &amp;nl))
+ err(1, &quot;DIOCNATLOOK&quot;);
+
+ printf(&quot;internal host &quot;);
+ print_address(nl.rsaddr.v4.s_addr);
+ printf(&quot;:%u\n&quot;, ntohs(nl.rsport));
+ return 0;
+}</pre>
+</div>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="SEE_ALSO"><a class="permalink" href="#SEE_ALSO">SEE
+ ALSO</a></h1>
+<p class="Pp"><a class="Xr">ioctl(2)</a>, <a class="Xr">altq(4)</a>,
+ <a class="Xr">if_bridge(4)</a>, <a class="Xr">pflog(4)</a>,
+ <a class="Xr">pfsync(4)</a>, <a class="Xr">pfctl(8)</a>,
+ <a class="Xr">altq(9)</a></p>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="HISTORY"><a class="permalink" href="#HISTORY">HISTORY</a></h1>
+<p class="Pp">The <code class="Nm">pf</code> packet filtering mechanism first
+ appeared in <span class="Ux">OpenBSD 3.0</span> and then
+ <span class="Ux">FreeBSD 5.2</span>.</p>
+<p class="Pp">This implementation is derived from <span class="Ux">OpenBSD
+ 4.5</span>. A number of individual features, improvements, bug fixes and
+ security fixes have been ported from later versions of
+ <span class="Ux">OpenBSD</span>. It has been heavily modified to be capable
+ of running in multithreaded <span class="Ux">FreeBSD</span> kernel and scale
+ its performance on multiple CPUs.</p>
+</section>
+</div>
+<table class="foot">
+ <tr>
+ <td class="foot-date">July 2, 2025</td>
+ <td class="foot-os">FreeBSD 15.0</td>
+ </tr>
+</table>