diff options
Diffstat (limited to 'static/freebsd/man4/pf.4 3.html')
| -rw-r--r-- | static/freebsd/man4/pf.4 3.html | 1055 |
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> — <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="YES"</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 ‘/’ 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 + ⟨<span class="Pa">net/pfvar.h</span>⟩:</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 + ⟨<span class="Pa">net/pfvar.h</span>⟩.</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 "add rule" 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 ⟨<span class="Pa">net/pfvar.h</span>⟩ 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 <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; +}</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> |
