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