home | help
PFIL(9) 		    Kernel Developer's Manual			 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 invoked 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 transforma-
     tions.

     Packet filtering points are registered with pfil_head_register().	 Filter-
     ing  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  con-
     stant  indicating	what kind of header is present on the packet at the fil-
     tering point.  Filtering points may be unregistered with the  pfil_head_un-
     register() function.

     Packet  filters  register/unregister themselves with a filtering point with
     the pfil_add_hook() and pfil_remove_hook()  functions,  respectively.   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 network 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	process-
     ing 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 structure 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
     bpf(4), if_bridge(4)

HISTORY
     The pfil interface first appeared in NetBSD 1.3.  The pfil input and output
     lists were originally implemented as <sys/queue.h> LIST structures; however
     this was changed in NetBSD 1.4 to TAILQ structures.  This change was to al-
     low the input and output filters 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 parameter to both
     pfil_add_hook() and pfil_remove_hook(), introducing the capability 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 arbitrary 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 if_bridge(4) diverts AF_INET and  AF_INET6  traffic  according  to  its
     sysctl settings, 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 dead-
     lock).  This means that traffic may be dropped unconditionally for a  short
     period of time.  pfil_run_hooks() will return ENOBUFS to indicate this.

FreeBSD 9.0		       September 29, 2004			 PFIL(9)

home | help