xref: /openbsd/share/man/man4/pf.4 (revision db3296cf)
1.\"	$OpenBSD: pf.4,v 1.32 2003/06/06 10:29:41 jmc Exp $
2.\"
3.\" Copyright (C) 2001, Kjell Wooding.  All rights reserved.
4.\"
5.\" Redistribution and use in source and binary forms, with or without
6.\" modification, are permitted provided that the following conditions
7.\" are met:
8.\" 1. Redistributions of source code must retain the above copyright
9.\"    notice, this list of conditions and the following disclaimer.
10.\" 2. Redistributions in binary form must reproduce the above copyright
11.\"    notice, this list of conditions and the following disclaimer in the
12.\"    documentation and/or other materials provided with the distribution.
13.\" 3. Neither the name of the project nor the names of its contributors
14.\"    may be used to endorse or promote products derived from this software
15.\"    without specific prior written permission.
16.\"
17.\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
18.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
21.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27.\" SUCH DAMAGE.
28.\"
29.Dd June 24, 2001
30.Dt PF 4
31.Os
32.Sh NAME
33.Nm pf
34.Nd packet filter
35.Sh SYNOPSIS
36.Cd "pseudo-device pf 1"
37.Sh DESCRIPTION
38Packet filtering takes place in the kernel.
39A pseudo-device,
40.Pa /dev/pf ,
41allows userland processes to control the
42behavior of the packet filter through an
43.Xr ioctl 2
44interface.
45There are commands to enable and disable the filter, load rulesets,
46add and remove individual rules or state table entries,
47and retrieve statistics.
48The most commonly used functions are covered by
49.Xr pfctl 8 .
50.Pp
51Manipulations like loading a ruleset that involve more than a single
52ioctl call require a so-called ticket, which prevents the occurrence of
53multiple concurrent manipulations.
54.Pp
55Fields of ioctl parameter structures that refer to packet data (like
56addresses and ports) are generally expected in network byte-order.
57.Sh FILES
58.Bl -tag -width /dev/pf -compact
59.It Pa /dev/pf
60packet filtering device.
61.El
62.Sh IOCTL INTERFACE
63pf supports the following
64.Xr ioctl 2
65commands:
66.Bl -tag -width xxxxxx
67.It Dv DIOCSTART
68Starts the packet filter.
69.It Dv DIOCSTOP
70Stops the packet filter.
71.It Dv DIOCSTARTALTQ
72Starts the ALTQ bandwidth control system.
73.It Dv DIOCSTOPALTQ
74Stops the ALTQ bandwidth control system.
75.It Dv DIOCBEGINADDRS  Fa "u_int32_t"
76Clears the buffer address pool
77and returns a ticket for subsequent DIOCADDADDR, DIOCADDRULE and
78DIOCCHANGERULE calls.
79.It Dv DIOCADDADDR     Fa "struct pfioc_pooladdr"
80.Bd -literal
81struct pfioc_pooladdr {
82	u_int32_t		action;
83	u_int32_t		ticket;
84	u_int32_t		nr;
85	u_int32_t		r_num;
86	u_int8_t		r_action;
87	u_int8_t		r_last;
88	u_int8_t		af;
89	char			anchor[PF_ANCHOR_NAME_SIZE];
90	char			ruleset[PF_RULESET_NAME_SIZE];
91	struct pf_pooladdr	addr;
92};
93.Ed
94.Pp
95Adds pool address
96.Va addr
97to the buffer address pool to be used in the following
98DIOCADDRULE or DIOCCHANGERULE call.
99All other members of the structure are ignored.
100.It Dv DIOCBEGINRULES  Fa "u_int32_t"
101Clears the inactive ruleset for the type of rule indicated by
102.Va rule.action
103and returns a ticket for subsequent
104DIOCADDRULE and DIOCCOMMITRULES calls.
105.It Dv DIOCADDRULE     Fa "struct pfioc_rule"
106.Bd -literal
107struct pfioc_rule {
108	u_int32_t	action;
109	u_int32_t	ticket;
110	u_int32_t	pool_ticket;
111	u_int32_t	nr;
112	char		anchor[PF_ANCHOR_NAME_SIZE];
113	char		ruleset[PF_RULESET_NAME_SIZE];
114	struct pf_rule	rule;
115};
116.Ed
117.Pp
118Adds
119.Va rule
120at the end of the inactive ruleset.
121Requires
122.Va ticket
123obtained through preceding DIOCBEGINRULES call, and
124.Va pool_ticket
125obtained through DIOCBEGINADDRS call.
126DIOCADDADDR must also be called if any pool addresses are required.
127The optional
128.Va anchor
129and
130.Va ruleset
131names indicate the anchor and ruleset in which to append the rule.
132.Va nr
133and
134.Va action
135are ignored.
136.It Dv DIOCCOMMITRULES Fa "u_int32_t"
137Switch inactive to active filter ruleset.
138Requires
139.Va ticket .
140.It Dv DIOCBEGINALTQS  Fa "u_int32_t"
141Clears the inactive list of queues and returns a ticket for subsequent
142DIOCADDALTQ and DIOCCOMMITALTQS calls.
143.It Dv DIOCADDALTQ     Fa "struct pfioc_altq"
144Adds
145.Bd -literal
146struct pfioc_altq {
147	u_int32_t	ticket;
148	u_int32_t	nr;
149	struct pf_altq   altq;
150};
151.Ed
152.It Dv DIOCCOMMITALTQS Fa "u_int32_t"
153Switch inactive to active list of queues.
154Requires
155.Va ticket .
156.It Dv DIOCGETRULES    Fa "struct pfioc_rule"
157Returns
158.Va ticket
159for subsequent DIOCGETRULE calls and
160.Va nr
161of rules in the active ruleset.
162.It Dv DIOCGETRULE     Fa "struct pfioc_rule"
163Returns
164.Va rule
165number
166.Va nr
167using
168.Va ticket
169obtained through a preceding DIOCGETRULES call.
170.It Dv DIOCGETADDRS    Fa "struct pfioc_pooladdr"
171Returns
172.Va ticket
173for subsequent DIOCGETADDR calls and
174.Va nr
175of pool addresses in the rule specified with
176.Va r_action ,
177.Va r_num ,
178.Va anchor
179and
180.Va ruleset .
181.It Dv DIOCGETADDR     Fa "struct pfioc_pooladdr"
182Returns pool address
183.Va addr
184number
185.Va nr
186from the rule specified with
187.Va r_action ,
188.Va r_num ,
189.Va anchor
190and
191.Va ruleset
192using
193.Va ticket
194obtained through a preceding DIOCGETADDRS call.
195.It Dv DIOCGETALTQS    Fa "struct pfioc_altq"
196Returns
197.Va ticket
198for subsequent DIOCGETALTQ calls and
199.Va nr
200of queues in the active list.
201.It Dv DIOCGETALTQ     Fa "struct pfioc_altq"
202Returns
203.Va altq
204number
205.Va nr
206using
207.Va ticket
208obtained through a preceding DIOCGETALTQS call.
209.It Dv DIOCGETQSTATS   Fa "struct pfioc_qstats"
210Returns statistics on a queue.
211.Bd -literal
212struct pfioc_qstats {
213	u_int32_t	 ticket;
214	u_int32_t	 nr;
215	void		*buf;
216	int		 nbytes;
217	u_int8_t	 scheduler;
218};
219.Ed
220.Pp
221A pointer to a buffer of statistics
222.Va buf
223of length
224.Va nbytes
225for the queue specified by
226.Va nr .
227.It Dv DIOCCLRSTATES
228Clears the state table.
229.It Dv DIOCADDSTATE    Fa "struct pfioc_state"
230Adds a state entry.
231.It Dv DIOCGETSTATE    Fa "struct pfioc_state"
232.Bd -literal
233struct pfioc_state {
234	u_int32_t	 nr;
235	struct pf_state	 state;
236};
237.Ed
238.Pp
239Extracts the entry with the specified number from the state table.
240.It Dv DIOCKILLSTATES  Fa "struct pfioc_state_kill"
241Removes matching entries from the state table.
242Returns the number of killed states in psk_af.
243.Bd -literal
244struct pfioc_state_kill {
245	int			psk_af;
246	int			psk_proto;
247	struct pf_rule_addr	psk_src;
248	struct pf_rule_addr	psk_dst;
249};
250.Ed
251.It Dv DIOCSETSTATUSIF Fa "struct pfioc_if"
252.Bd -literal
253struct pfioc_if {
254	char		 ifname[IFNAMSIZ];
255};
256.Ed
257.Pp
258Specifies the interface for which statistics are accumulated.
259.It Dv DIOCGETSTATUS   Fa "struct pf_status"
260.Bd -literal
261struct pf_status {
262	u_int64_t	 counters[PFRES_MAX];
263	u_int64_t	 fcounters[FCNT_MAX];
264	u_int64_t	 pcounters[2][2][3];
265	u_int64_t	 bcounters[2][2];
266	u_int32_t	 running;
267	u_int32_t	 states;
268	u_int32_t	 since;
269	u_int32_t	 debug;
270};
271.Ed
272.Pp
273Gets the internal packet filter statistics.
274.It Dv DIOCCLRSTATUS
275Clears the internal packet filter statistics.
276.It Dv DIOCNATLOOK     Fa "struct pfioc_natlook"
277Looks up a state table entry by source and destination addresses and ports.
278.Bd -literal
279struct pfioc_natlook {
280	struct pf_addr	 saddr;
281	struct pf_addr	 daddr;
282	struct pf_addr	 rsaddr;
283	struct pf_addr	 rdaddr;
284	u_int16_t	 sport;
285	u_int16_t	 dport;
286	u_int16_t	 rsport;
287	u_int16_t	 rdport;
288	u_int8_t	 af;
289	u_int8_t	 proto;
290	u_int8_t	 direction;
291};
292.Ed
293.It Dv DIOCSETDEBUG    Fa "u_int32_t"
294Sets the debug level.
295.Bd -literal
296enum	{ PF_DEBUG_NONE=0, PF_DEBUG_URGENT=1, PF_DEBUG_MISC=2 };
297.Ed
298.It Dv DIOCGETSTATES   Fa "struct pfioc_states"
299.Bd -literal
300struct pfioc_states {
301	int	ps_len;
302	union {
303		caddr_t psu_buf;
304		struct pf_state *psu_states;
305	} ps_u;
306#define ps_buf		ps_u.psu_buf
307#define ps_states	ps_u.psu_states
308};
309.Ed
310.It Dv DIOCCHANGERULE  Fa "struct pfioc_rule"
311Adds or removes the
312.Va rule
313in the ruleset specified by
314.Va rule.action .
315.Bd -literal
316enum	{ PF_CHANGE_ADD_HEAD=1, PF_CHANGE_ADD_TAIL=2,
317	  PF_CHANGE_ADD_BEFORE=3, PF_CHANGE_ADD_AFTER=4,
318	  PF_CHANGE_REMOVE=5, PF_CHANGE_GET_TICKET=6 };
319.Ed
320.Pp
321The type of operation to be performed is indicated by
322.Va action .
323.Pp
324.Va ticket
325must be set to the value obtained with PF_CHANGE_GET_TICKET
326for all actions except PF_CHANGE_GET_TICKET.
327.Va pool_ticket
328must be set to the value obtained with the DIOCBEGINADDRS call
329for all actions except PF_CHANGE_REMOVE and PF_CHANGE_GET_TICKET.
330.Pp
331.Va anchor
332and
333.Va ruleset
334indicate which anchor and ruleset the operation applies to.
335.Va nr
336indicates the rule number against which PF_CHANGE_ADD_BEFORE,
337PF_CHANGE_ADD_AFTER or PF_CHANGE_REMOVE actions are applied.
338.It Dv DIOCCHANGEADDR  Fa "struct pfioc_addr"
339Adds or removes a pool address
340.Va addr
341from a rule specified with
342.Va r_action ,
343.Va r_num ,
344.Va anchor
345and
346.Va ruleset .
347.It Dv DIOCSETTIMEOUT  Fa "struct pfioc_tm"
348.Bd -literal
349struct pfioc_tm {
350	int		 timeout;
351	int		 seconds;
352};
353.Ed
354.It Dv DIOCGETTIMEOUT  Fa "struct pfioc_tm"
355.It Dv DIOCCLRRULECTRS
356Clear per-rule statistics.
357.It Dv DIOCSETLIMIT   Fa "struct pfioc_limit"
358Sets hard limits on the memory pools used by the packet filter.
359.Bd -literal
360struct pfioc_limit {
361	int		index;
362	unsigned	limit;
363};
364.Ed
365.It Dv DIOCGETLIMIT   Fa "struct pfioc_limit"
366.It Dv DIOCRCLRTABLES Fa "struct pfioc_table"
367Clear all tables.
368All the IOCTLs that manipulate radix tables
369use the same structure described below.
370For
371.Dv DIOCRCLRTABLES, pfrio_ndel contains on exit the number
372of tables deleted.
373.Bd -literal
374struct pfioc_table {
375        struct pfr_table         pfrio_table;
376        void                    *pfrio_buffer;
377        int                      pfrio_esize;
378        int                      pfrio_size;
379        int                      pfrio_size2;
380        int                      pfrio_nadd;
381        int                      pfrio_ndel;
382        int                      pfrio_nchange;
383        int                      pfrio_flags;
384        int                      pfrio_ticket;
385};
386#define pfrio_exists    pfrio_nadd
387#define pfrio_nzero     pfrio_nadd
388#define pfrio_nmatch    pfrio_nadd
389#define pfrio_naddr     pfrio_size2
390#define pfrio_setflag   pfrio_size2
391#define pfrio_clrflag   pfrio_nadd
392.Ed
393.It Dv DIOCRADDTABLES Fa "struct pfioc_table"
394Creates one or more tables.
395On entry, pfrio_buffer[pfrio_size] contains a table of pfr_table structures.
396On exit, pfrio_nadd contains the number of tables effectively created.
397.Bd -literal
398struct pfr_table {
399        char                     pfrt_anchor[PF_ANCHOR_NAME_SIZE];
400        char                     pfrt_ruleset[PF_RULESET_NAME_SIZE];
401        char                     pfrt_name[PF_TABLE_NAME_SIZE];
402        u_int32_t                pfrt_flags;
403        u_int8_t                 pfrt_fback;
404};
405.Ed
406.It Dv DIOCRDELTABLES Fa "struct pfioc_table"
407Deletes one or more tables.
408On entry, pfrio_buffer[pfrio_size] contains a table of pfr_table structures.
409On exit, pfrio_nadd contains the number of tables effectively deleted.
410.It Dv DIOCRGETTABLES Fa "struct pfioc_table"
411Get the list of all tables.
412On entry, pfrio_buffer[pfrio_size] contains a valid writeable buffer for
413pfr_table structures.
414On exit, pfrio_size contains the number of tables written into the buffer.
415If the buffer is too small, the kernel does not store anything but just
416returns the required buffer size, without error.
417.It Dv DIOCRGETTSTATS Fa "struct pfioc_table"
418Like
419.Dv DIOCRGETTABLES ,
420but returns an array of pfr_tstats structures.
421.Bd -literal
422struct pfr_tstats {
423        struct pfr_table pfrts_t;
424        u_int64_t        pfrts_packets
425                             [PFR_DIR_MAX][PFR_OP_TABLE_MAX];
426        u_int64_t        pfrts_bytes
427                             [PFR_DIR_MAX][PFR_OP_TABLE_MAX];
428        u_int64_t        pfrts_match;
429        u_int64_t        pfrts_nomatch;
430        long             pfrts_tzero;
431        int              pfrts_cnt;
432        int              pfrts_refcnt[PFR_REFCNT_MAX];
433};
434#define pfrts_name      pfrts_t.pfrt_name
435#define pfrts_flags     pfrts_t.pfrt_flags
436.Ed
437.It Dv DIOCRCLRTSTATS Fa "struct pfioc_table"
438Clears the statistics of one or more tables.
439On entry, pfrio_buffer[pfrio_size] contains a table of pfr_table structures.
440On exit, pfrio_nzero contains the number of tables effectively cleared.
441.It Dv DIOCRCLRADDRS Fa "struct pfioc_table"
442Clear all addresses in a table.
443On entry, pfrio_table contains the table to clear.
444On exit, pfrio_ndel contains the number of addresses removed.
445.It Dv DIOCRADDADDRS Fa "struct pfioc_table"
446Add one or more addresses to a table.
447On entry, pfrio_table contains the table id and pfrio_buffer[pfrio_size]
448contains the list of pfr_addr structures to add.
449On exit, pfrio_nadd contains the number of addresses effectively added.
450.Bd -literal
451struct pfr_addr {
452        union {
453                struct in_addr   _pfra_ip4addr;
454                struct in6_addr  _pfra_ip6addr;
455        }                pfra_u;
456        u_int8_t         pfra_af;
457        u_int8_t         pfra_net;
458        u_int8_t         pfra_not;
459        u_int8_t         pfra_fback;
460};
461#define pfra_ip4addr    pfra_u._pfra_ip4addr
462#define pfra_ip6addr    pfra_u._pfra_ip6addr
463.Ed
464.It Dv DIOCRDELADDRS Fa "struct pfioc_table"
465Delete one or more addresses from a table.
466On entry, pfrio_table contains the table id and pfrio_buffer[pfrio_size]
467contains the list of pfr_addr structures to delete.
468On exit, pfrio_ndel contains the number of addresses effectively deleted.
469.It Dv DIOCRSETADDRS Fa "struct pfioc_table"
470Replace the content of a table by a new address list.
471This is the most complicated command, which uses all the structure members.
472On entry, pfrio_table contains the table id and pfrio_buffer[pfrio_size]
473contains the new list of pfr_addr structures.
474In addition to that, if size2 is nonzero, pfrio_buffer[pfrio_size..pfrio_size2]
475must be a writeable buffer, into which the kernel can copy the addresses that
476have been deleted during the replace operation.
477On exit, pfrio_ndel, pfrio_nadd and pfrio_nchange contain the number of
478addresses deleted, added and changed by the kernel.
479If pfrio_size2 was set on
480entry, pfrio_size2 will point to the size of the buffer used, exactly like
481.Dv DIOCRGETADDRS .
482.It Dv DIOCRGETADDRS Fa "struct pfioc_table"
483Get all the addresses of a table.
484On entry, pfrio_table contains the table id and pfrio_buffer[pfrio_size]
485contains a valid writeable buffer for pfr_addr structures.
486On exit, pfrio_size contains the number of addresses written into the buffer.
487If the buffer was too small, the kernel does not store anything but just
488return the required buffer size, without returning an error.
489.It Dv DIOCRGETASTATS Fa "struct pfioc_table"
490Like
491.Dv DIOCRGETADDRS ,
492but returns an array of pfr_astats structures.
493.Bd -literal
494struct pfr_astats {
495        struct pfr_addr  pfras_a;
496        u_int64_t        pfras_packets
497                             [PFR_DIR_MAX][PFR_OP_ADDR_MAX];
498        u_int64_t        pfras_bytes
499                             [PFR_DIR_MAX][PFR_OP_ADDR_MAX];
500        long             pfras_tzero;
501};
502.Ed
503.It Dv DIOCRCLRASTATS Fa "struct pfioc_table"
504Clears the statistics of one or more addresses.
505On entry, pfrio_table contains the table id and pfrio_buffer[pfrio_size]
506contains a table of pfr_addr structures to clear.
507On exit, pfrio_nzero contains the number of addresses effectively cleared.
508.It Dv DIOCRTSTADDRS Fa "struct pfioc_table"
509Test if the given addresses match a table.
510On entry, pfrio_table contains the table id and pfrio_buffer[pfrio_size]
511contains a table of pfr_addr structures to test.
512On exit, the kernel updates the pfr_addr table by setting the pfra_fback
513member appropriately.
514.It Dv DIOCRSETTFLAGS Fa "struct pfioc_table"
515Change the
516.Va const
517or
518.Va persist
519flag of a table.
520On entry, pfrio_buffer[pfrio_size] contains a table of pfr_table structures,
521and pfrio_setflag contains the flags to add, while pfrio_clrflag contains the
522flags to remove.
523On exit, pfrio_nchange and pfrio_ndel contain the number of tables altered
524or deleted by the kernel.
525Yes, tables can be deleted if one removes the
526.Va persist
527flag of an unreferenced table.
528.It Dv DIOCRINABEGIN Fa "struct pfioc_table"
529Starts a transaction with the inactive set of tables.
530Cleans up any leftover from a previously aborted transaction, and returns
531a new ticket.
532On exit, pfrio_ndel contains the number of leftover table deleted, and
533pfrio_ticket contains a valid ticket to use for the following two IOCTLs.
534.It Dv DIOCRINACOMMIT Fa "struct pfioc_table"
535Commit the inactive set of tables into the active set.
536While copying the addresses, do a best effort to keep statistics for
537addresses present before and after the commit.
538On entry, io->pfrio_ticket takes a valid ticket.
539On exit, io->pfrio_nadd and io->pfrio_nchange contain the number of tables
540added and altered by the commit operation.
541.It Dv DIOCRINADEFINE Fa "struct pfioc_table"
542Defines a table in the inactive set.
543On entry, pfrio_table contains the table id and pfrio_buffer[pfrio_size]
544contains the list of pfr_addr structures to put in the table.
545A valid ticket must also be supplied to pfrio_ticket.
546On exit, pfrio_nadd contains 0 if the table was already defined in the
547inactive list, or 1 if a new table has been created.
548pfrio_naddr contains the number of addresses effectively put in the table.
549.El
550.Sh EXAMPLES
551The following example demonstrates how to use the DIOCNATLOOK command
552to find the internal host/port of a NATed connection.
553.Bd -literal
554#include <sys/types.h>
555#include <sys/socket.h>
556#include <sys/ioctl.h>
557#include <sys/fcntl.h>
558#include <net/if.h>
559#include <netinet/in.h>
560#include <net/pfvar.h>
561#include <stdio.h>
562
563u_int32_t
564read_address(const char *s)
565{
566	int a, b, c, d;
567
568	sscanf(s, "%i.%i.%i.%i", &a, &b, &c, &d);
569	return htonl(a << 24 | b << 16 | c << 8 | d);
570}
571
572void
573print_address(u_int32_t a)
574{
575	a = ntohl(a);
576	printf("%d.%d.%d.%d", a >> 24 & 255, a >> 16 & 255,
577	    a >> 8 & 255, a & 255);
578}
579
580int
581main(int argc, char *argv[])
582{
583	struct pfioc_natlook nl;
584	int dev;
585
586	if (argc != 5) {
587		printf("%s <gwy addr> <gwy port> <ext addr> <ext port>\\n",
588		    argv[0]);
589		return 1;
590	}
591
592	dev = open("/dev/pf", O_RDWR);
593	if (dev == -1)
594		err(1, "open(\\"/dev/pf\\") failed");
595
596	memset(&nl, 0, sizeof(struct pfioc_natlook));
597	nl.saddr.v4.s_addr	= read_address(argv[1]);
598	nl.sport		= htons(atoi(argv[2]));
599	nl.daddr.v4.s_addr	= read_address(argv[3]);
600	nl.dport		= htons(atoi(argv[4]));
601	nl.af			= AF_INET;
602	nl.proto		= IPPROTO_TCP;
603	nl.direction		= PF_IN;
604
605	if (ioctl(dev, DIOCNATLOOK, &nl))
606		err(1, "DIOCNATLOOK");
607
608	printf("internal host ");
609	print_address(nl.rsaddr.v4.s_addr);
610	printf(":%u\\n", ntohs(nl.rsport));
611	return 0;
612}
613.Ed
614.Sh SEE ALSO
615.Xr ioctl 2 ,
616.Xr bridge 4 ,
617.Xr pflog 4 ,
618.Xr pfsync 4 ,
619.Xr pfctl 8
620.Sh HISTORY
621The
622.Nm
623packet filtering mechanism first appeared in
624.Ox 3.0 .
625