pfil(9)
NAME
- pfil, pfil_head_register, pfil_head_unregister,
- pfil_head_get,
 pfil_hook_get, pfil_add_hook, pfil_remove_hook,
- pfil_run_hooks - packet
 filter interface
SYNOPSIS
#include <sys/param.h> #include <sys/mbuf.h> #include <net/if.h> #include <net/pfil.h> int pfil_head_register(struct pfil_head *head); int pfil_head_unregister(struct pfil_head *head); struct pfil_head * pfil_head_get(int af, u_long dlt); struct packet_filter_hook * pfil_hook_get(int dir, struct pfil_head *head); void pfil_add_hook(int (*func)(), void *arg, int flags, struct pfil_head *); void pfil_remove_hook(int (*func)(), void *arg, int flags, struct pfil_head *); int (*func)(void *arg, struct mbuf **mp, struct ifnet *, int dir, struct inpcb *); int pfil_run_hooks(struct pfil_head *head, struct mbuf **mp, struct ifnet *, int dir, struct inpcb *);
DESCRIPTION
- The pfil framework allows for a specified function to be in
- voked for
 every incoming or outgoing packet for a particular network
- I/O stream.
 These hooks may be used to implement a firewall or perform
- packet transformations.
- Packet filtering points are registered with
- pfil_head_register(). Filtering points are identified by a key (void *) and a data
- link type (int)
 in the pfil_head structure. Packet filters use the key and
- data link
 type to look up the filtering point with which they register
- themselves.
 The key is unique to the filtering point. The data link
- type is a bpf(4)
 DLT constant indicating what kind of header is present on
- the packet at
 the filtering point. Filtering points may be unregistered
- with the
 pfil_head_unregister() function.
- Packet filters register/unregister themselves with a filter
- ing point with
 the pfil_add_hook() and pfil_remove_hook() functions, re
- spectively.  The
 head is looked up using the pfil_head_get() function, which
- takes the key
 and data link type that the packet filter expects. Filters
- may provide
 an argument to be passed to the filter when invoked on a
- packet.
- When a filter is invoked, the packet appears just as if it
- ``came off the
 wire''. That is, all protocol fields are in network byte
- order.  The
 filter is called with its specified argument, the pointer to
- the pointer
 to the mbuf containing the packet, the pointer to the net
- work interface
 that the packet is traversing, and the direction (PFIL_IN or
- PFIL_OUT)
 that the packet is traveling. The filter may change which
- mbuf the
 mbuf ** argument references. The filter returns an error
- (errno) if the
 packet processing is to stop, or 0 if the processing is to
- continue.  If
 the packet processing is to stop, it is the responsibility
- of the filter
 to free the packet.
RETURN VALUES
- If successful, pfil_head_get() returns the pfil_head struc
- ture for the
 given key/dlt. The pfil_add_hook() and pfil_remove_hook()
- functions
 return 0 if successful. If called with flag PFIL_WAITOK,
 pfil_remove_hook() is expected to always succeed.
- The pfil_head_unregister() function might sleep!
SEE ALSO
HISTORY
- The pfil interface first appeared in NetBSD 1.3. The pfil
- input and output lists were originally implemented as #include
- <sys/queue.h>
 LIST structures; however this was changed in NetBSD 1.4 to
- TAILQ structures. This change was to allow the input and output fil
- ters to be processed in reverse order, to allow the same path to be taken,
- in or out of
 the kernel.
- The pfil interface was changed in 1.4T to accept a 3rd pa
- rameter to both
 pfil_add_hook() and pfil_remove_hook(), introducing the ca
- pability of
 per-protocol filtering. This was done primarily in order to
- support filtering of IPv6.
- In 1.5K, the pfil framework was changed to work with an ar
- bitrary number
 of filtering points, as well as be less IP-centric.
- Fine-grained locking was added in FreeBSD 5.2.
BUGS
The pfil_hook_get() function is only safe for internal use.
- FreeBSD  implements  only  hooks  for  AF_INET and AF_INET6.
- Packets diverted
 through these hooks have data in host byte order contrary to
- the above
 statements.
- The bridge(4) diverts inbound AF_INET traffic, but contrary
- to the above
 statements, the data is provided in host byte order.
- When a pfil_head is being modified, no traffic is diverted
- (to avoid
 deadlock). This means that traffic may be dropped uncondi
- tionally for a
 short period of time. pfil_run_hooks() will return ENOBUFS
- to indicate
 this.
- BSD September 29, 2004