1.\" $NetBSD: pfil.9,v 1.38 2018/01/17 08:34:15 uwe Exp $ 2.\" 3.\" Copyright (c) 1996 Matthew R. Green 4.\" All rights reserved. 5.\" 6.\" Redistribution and use in source and binary forms, with or without 7.\" modification, are permitted provided that the following conditions 8.\" are met: 9.\" 1. Redistributions of source code must retain the above copyright 10.\" notice, this list of conditions and the following disclaimer. 11.\" 2. Redistributions in binary form must reproduce the above copyright 12.\" notice, this list of conditions and the following disclaimer in the 13.\" documentation and/or other materials provided with the distribution. 14.\" 15.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 22.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25.\" SUCH DAMAGE. 26.\" 27.Dd January 17, 2018 28.Dt PFIL 9 29.Os 30.Sh NAME 31.Nm pfil , 32.Nm pfil_head_register , 33.Nm pfil_head_unregister , 34.Nm pfil_head_get , 35.Nm pfil_hook_get , 36.Nm pfil_add_hook , 37.Nm pfil_remove_hook , 38.Nm pfil_run_hooks , 39.Nm pfil_add_ihook , 40.Nm pfil_remove_ihook , 41.Nm pfil_run_addrhooks , 42.Nm pfil_run_ifhooks 43.Nd packet filter interface 44.Sh SYNOPSIS 45.In sys/param.h 46.In sys/mbuf.h 47.In net/if.h 48.In net/pfil.h 49.Ft int 50.Fn pfil_head_register "struct pfil_head *ph" 51.Ft int 52.Fn pfil_head_unregister "struct pfil_head *ph" 53.Ft struct pfil_head * 54.Fn pfil_head_get "int af" "u_long dlt" 55.Ft struct packet_filter_hook * 56.Fn pfil_hook_get "int dir" "struct pfil_head *ph" 57.Ft int 58.Fn pfil_add_hook "int (*func)()" "void *arg" "int flags" "struct pfil_head *ph" 59.Ft int 60.Fn pfil_remove_hook "int (*func)()" "void *arg" "int flags" "struct pfil_head *ph" 61.Ft int 62.Fn (*func) "void *arg" "struct mbuf **mp" "struct ifnet *" "int dir" 63.Ft int 64.Fn pfil_run_hooks "struct pfil_head *ph" "struct mbuf **mp" "struct ifnet *ifp" "int dir" 65.Ft int 66.Fn pfil_add_ihook "void (*ifunc)()" "void *arg" "int flags" "struct pfil_head *ph" 67.Ft int 68.Fn pfil_remove_ihook "void (*ifunc)()" "void *arg" "int flags" "struct pfil_head *ph" 69.Ft void 70.Fn (*ifunc) "void *arg" "unsigned long cmd" "void *ptr" 71.Ft void 72.Fn pfil_run_addrhooks "struct pfil_head *ph" "unsigned long" "struct ifaddr *ifa" 73.Ft void 74.Fn pfil_run_ifhooks "struct pfil_head *ph" "unsigned long" "struct ifnet *ifp" 75.Sh DESCRIPTION 76The 77.Nm 78framework allows for a specified function to be invoked for every 79incoming or outgoing packet for a particular network I/O stream. 80These hooks may be used to implement a firewall or perform packet 81transformations. 82.Pp 83Packet filtering points are registered with 84.Fn pfil_head_register . 85Filtering points are identified by a key 86.Vt ( void * ) 87and a data link type 88.Vt ( int ) 89in the 90.Vt pfil_head 91structure. 92Packet filters use the key and data link type to look up the filtering 93point with which they register themselves. 94The key is unique to the filtering point. 95The data link type is a 96.Xr bpf 4 97.Dv DLT_ Ns Ar type 98constant indicating what kind of header is present on the packet 99at the filtering point. 100Filtering points may be unregistered with the 101.Fn pfil_head_unregister 102function. 103.Pp 104Packet filters register/unregister themselves with a filtering point 105with the 106.Fn pfil_add_hook 107and 108.Fn pfil_remove_hook 109functions, respectively. 110The head is looked up using the 111.Fn pfil_head_get 112function, which takes the key and data link type that the packet filter 113expects. 114Filters may provide an argument to be passed to the filter when 115invoked on a packet. 116.Pp 117When a filter is invoked, the packet appears just as if it 118.Dq came off the wire . 119That is, all protocol fields are in network byte order. 120The filter is called with its specified argument, the pointer to the 121pointer to the mbuf containing the packet, the pointer to the network 122interface that the packet is traversing, and the direction (either 123.Dv PFIL_IN 124or 125.Dv PFIL_OUT , 126see also below) that the packet is traveling. 127The filter may change which mbuf the 128.Vt "mbuf **" 129argument references. 130The filter returns an errno if the packet processing is to stop, or 0 131if the processing is to continue. 132If the packet processing is to stop, it is the responsibility of the 133filter to free the packet. 134.Pp 135The 136.Fa flags 137parameter, used in the 138.Fn pfil_add_hook 139and 140.Fn pfil_remove_hook 141functions, indicates when the filter should be called. 142The flags are: 143.Pp 144.Bl -tag -offset indent -width ".Dv PFIL_ALL" -compact 145.It Dv PFIL_IN 146call me on incoming packets 147.It Dv PFIL_OUT 148call me on outgoing packets 149.It Dv PFIL_ALL 150call me on all of the above 151.El 152.Pp 153By the same token, event handlers register/unregister themselves 154with the 155.Fn pfil_add_ihook 156and 157.Fn pfil_remove_ihook 158functions, respectively. 159The event handler is called with its specified argument, the event id 160(either 161.Dv PFIL_IFNET_ATTACH 162or 163.Dv PFIL_IFNET_DETACH , 164see also below) or ioctl number, and the pointer 165to the network interface or the pointer to the ifaddr. 166.Pp 167The 168.Fa flags 169parameter, used in the 170.Fn pfil_add_ihook 171and 172.Fn pfil_remove_ihook 173functions, indicates when the filter should be called. 174The flags are: 175.Pp 176.Bl -tag -offset indent -width ".Dv PFIL_IFADDR" -compact 177.It Dv PFIL_IFADDR 178call me on interface reconfig 179.Fa ( cmd 180is ioctl #) 181.It Dv PFIL_IFNET 182call me on interface attach/detach 183.Fa ( cmd 184is either 185.Dv PFIL_IFNET_ATTACH 186or 187.Dv PFIL_IFNET_DETACH ) 188.El 189.Sh SEE ALSO 190.Xr bpf 4 191.Sh HISTORY 192The 193.Nm 194interface first appeared in 195.Nx 1.3 . 196The 197.Nm 198input and output lists were originally implemented as 199.In sys/queue.h 200.Dv LIST 201structures; 202however this was changed in 203.Nx 1.4 204to 205.Dv TAILQ 206structures. 207This change was to allow the input and output filters to be processed in 208reverse order, to allow the same path to be taken, in or out of the kernel. 209.Pp 210The 211.Nm 212interface was changed in 1.4T to accept a 3rd parameter to both 213.Fn pfil_add_hook 214and 215.Fn pfil_remove_hook , 216introducing the capability of per-protocol filtering. 217This was done primarily in order to support filtering of IPv6. 218.Pp 219In 1.5K, the 220.Nm 221framework was changed to work with an arbitrary number of filtering points, 222as well as be less IP-centric. 223.Pp 224.Fn pfil_add_ihook 225and 226.Fn pfil_remove_ihook 227were added in 228.Nx 8.0 . 229.Sh AUTHORS 230.An -nosplit 231The 232.Nm 233interface was designed and implemented by 234.An Matthew R. Green , 235with help from 236.An Darren Reed , 237.An Jason R. Thorpe , 238and 239.An Charles M. Hannum . 240.An Darren Reed 241added support for IPv6 in addition to IPv4. 242.An Jason R. Thorpe 243added support for multiple hooks and other clean up. 244.Sh BUGS 245The current 246.Nm 247implementation will need changes to suit a threaded kernel model. 248