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