diff options
author | darrenr <darrenr@FreeBSD.org> | 2000-05-10 13:37:51 +0000 |
---|---|---|
committer | darrenr <darrenr@FreeBSD.org> | 2000-05-10 13:37:51 +0000 |
commit | 5419f3d5951bfa7ddfea18f6623c918e633fe2de (patch) | |
tree | c3a4574b3bb25074705fc76c643ac47195c55d27 /sys/net | |
parent | bc4bf27e62e20a5e26c1bd5352624188be07c599 (diff) | |
download | FreeBSD-src-5419f3d5951bfa7ddfea18f6623c918e633fe2de.zip FreeBSD-src-5419f3d5951bfa7ddfea18f6623c918e633fe2de.tar.gz |
Add pfil(9) subroutines and manpage from NetBSD.
Diffstat (limited to 'sys/net')
-rw-r--r-- | sys/net/pfil.9 | 134 | ||||
-rw-r--r-- | sys/net/pfil.c | 176 | ||||
-rw-r--r-- | sys/net/pfil.h | 81 |
3 files changed, 391 insertions, 0 deletions
diff --git a/sys/net/pfil.9 b/sys/net/pfil.9 new file mode 100644 index 0000000..a7eb36f --- /dev/null +++ b/sys/net/pfil.9 @@ -0,0 +1,134 @@ +.\" $FreeBSD$ +.\" +.\" Copyright (c) 1996 Matthew R. Green +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. The name of the author may not be used to endorse or promote products +.\" derived from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd August 4, 1996 +.Dt PFIL 9 +.Os +.Sh NAME +.Nm pfil , +.Nm pfil_hook_get , +.Nm pfil_add_hook , +.Nm pfil_remove_hook +.Nd packet filter interface +.Sh SYNOPSIS +.Fd #include <sys/param.h> +.Fd #include <sys/mbuf.h> +.Fd #include <net/if.h> +.Fd #include <net/pfil.h> +.Ft struct packet_filter_hook * +.Fn pfil_hook_get "int" "struct pfil_head *" +.Ft void +.Fn pfil_add_hook "int (*func)()" "int flags" "struct pfil_head *" +.Ft void +.Fn pfil_remove_hook "int (*func)()" "int flags" "struct pfil_head *" +.\"(void *, int, struct ifnet *, int, struct mbuf **) +.Sh DESCRIPTION +The +.Nm +interface allows a function to be called on every incoming or outgoing +packets. The hooks for these are embedded in the +.Fn ip_input +and +.Fn ip_output +routines. The +.Fn pfil_hook_get +function returns the first member of a particular hook, either the in or out +list. The +.Fn pfil_add_hook +function takes a function of the form below as it's first argument, and the +flags for which lists to add the function to. The possible values for these +flags are some combination of PFIL_IN and PFIL_OUT. The +.Fn pfil_remove_hook +removes a hook from the specified lists. +.Pp +The +.Va func +argument is a function with the following prototype. +.Pp +.Fn func "void *data" "int hlen" "struct ifnet *net" "int dir" "struct mbuf **m" +.Pp +The +.Va data +describes the packet. Currently, this may only be a pointer to a ip structure. The +.Va net +and +.Va m +arguments describe the network interface and the mbuf holding data for this +packet. The +.Va dir +is the direction; 0 for incoming packets and 1 for outgoing packets. if the function +returns non-zero, this signals an error and no further processing of this packet is +performed. The function should set errno to indicate the nature of the error. +It is the hook's responsibiliy to free the chain if the packet is being dropped. +.Pp +The +.Nm +interface is enabled in the kernel via the +.Sy PFIL_HOOKS +option. +.Sh RETURN VALUES +If successful +.Fn pfil_hook_get +returns the first member of the packet filter list, +.Fn pfil_add_hook +and +.Fn pfil_remove_hook +are expected to always succeed. +.Sh HISTORY +The +.Nm +interface first appeared in +.Nx 1.3 . +The +.Nm +input and output lists were originally implemented as +.Fd <sys/queue.h> +.Dv LIST +structures; +however this was changed in +.Nx 1.4 +to +.Dv TAILQ +structures. This change was to allow 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. +.Pp +The +.Nm +interface was changed in 1.4T to accept a 3rd parameter to both +.Fn pfil_add_hook +and +.Fn pfil_remove_hook +, introducing the capability of per-protocol filtering. This was done +primarily in order to support filtering of IPv6. +.Sh BUGS +The current +.Nm +implementation will need changes to suit a threaded kernel model. +.Sh SEE ALSO +.Xr bpf 4 diff --git a/sys/net/pfil.c b/sys/net/pfil.c new file mode 100644 index 0000000..67501ee --- /dev/null +++ b/sys/net/pfil.c @@ -0,0 +1,176 @@ +/* $FreeBSD$ */ + +/* + * Copyright (c) 1996 Matthew R. Green + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/param.h> +#include <sys/errno.h> +#include <sys/malloc.h> +#include <sys/socket.h> +#include <sys/socketvar.h> +#include <sys/systm.h> +#include <sys/proc.h> +#include <sys/queue.h> + +#include <net/if.h> +#include <net/pfil.h> + +static void pfil_init __P((struct pfil_head *)); +static int pfil_list_add(pfil_list_t *, + int (*) __P((void *, int, struct ifnet *, int, struct mbuf **)), int); +static int pfil_list_remove(pfil_list_t *, + int (*) __P((void *, int, struct ifnet *, int, struct mbuf **))); + +static void +pfil_init(ph) + struct pfil_head *ph; +{ + + TAILQ_INIT(&ph->ph_in); + TAILQ_INIT(&ph->ph_out); + ph->ph_init = 1; +} + +/* + * pfil_add_hook() adds a function to the packet filter hook. the + * flags are: + * PFIL_IN call me on incoming packets + * PFIL_OUT call me on outgoing packets + * PFIL_ALL call me on all of the above + * PFIL_WAITOK OK to call malloc with M_WAITOK. + */ +int +pfil_add_hook(func, flags, ph) + int (*func) __P((void *, int, struct ifnet *, int, + struct mbuf **)); + int flags; + struct pfil_head *ph; +{ + int err = 0; + + if (ph->ph_init == 0) + pfil_init(ph); + + if (flags & PFIL_IN) + err = pfil_list_add(&ph->ph_in, func, flags & ~PFIL_OUT); + if (err) + return err; + if (flags & PFIL_OUT) + err = pfil_list_add(&ph->ph_out, func, flags & ~PFIL_IN); + if (err) { + if (flags & PFIL_IN) + pfil_list_remove(&ph->ph_in, func); + return err; + } + return 0; +} + +static int +pfil_list_add(list, func, flags) + pfil_list_t *list; + int (*func) __P((void *, int, struct ifnet *, int, + struct mbuf **)); + int flags; +{ + struct packet_filter_hook *pfh; + + pfh = (struct packet_filter_hook *)malloc(sizeof(*pfh), M_IFADDR, + flags & PFIL_WAITOK ? M_WAITOK : M_NOWAIT); + if (pfh == NULL) + return ENOMEM; + pfh->pfil_func = func; + /* + * insert the input list in reverse order of the output list + * so that the same path is followed in or out of the kernel. + */ + + if (flags & PFIL_IN) + TAILQ_INSERT_HEAD(list, pfh, pfil_link); + else + TAILQ_INSERT_TAIL(list, pfh, pfil_link); + return 0; +} + +/* + * pfil_remove_hook removes a specific function from the packet filter + * hook list. + */ +int +pfil_remove_hook(func, flags, ph) + int (*func) __P((void *, int, struct ifnet *, int, + struct mbuf **)); + int flags; + struct pfil_head *ph; +{ + int err = 0; + + if (ph->ph_init == 0) + pfil_init(ph); + + if (flags & PFIL_IN) + err = pfil_list_remove(&ph->ph_in, func); + if ((err == 0) && (flags & PFIL_OUT)) + err = pfil_list_remove(&ph->ph_out, func); + return err; +} + +/* + * pfil_list_remove is an internal function that takes a function off the + * specified list. + */ +static int +pfil_list_remove(list, func) + pfil_list_t *list; + int (*func) __P((void *, int, struct ifnet *, int, + struct mbuf **)); +{ + struct packet_filter_hook *pfh; + + for (pfh = list->tqh_first; pfh; pfh = pfh->pfil_link.tqe_next) + if (pfh->pfil_func == func) { + TAILQ_REMOVE(list, pfh, pfil_link); + free(pfh, M_IFADDR); + return 0; + } + return ENOENT; +} + +struct packet_filter_hook * +pfil_hook_get(flag, ph) + int flag; + struct pfil_head *ph; +{ + if (ph->ph_init != 0) + switch (flag) { + case PFIL_IN: + return (ph->ph_in.tqh_first); + case PFIL_OUT: + return (ph->ph_out.tqh_first); + } + return NULL; +} diff --git a/sys/net/pfil.h b/sys/net/pfil.h new file mode 100644 index 0000000..7831328 --- /dev/null +++ b/sys/net/pfil.h @@ -0,0 +1,81 @@ +/* $FreeBSD$ */ + +/* + * Copyright (c) 1996 Matthew R. Green + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _NET_PFIL_H_ +#define _NET_PFIL_H_ + +#include <sys/queue.h> + +struct mbuf; +struct ifnet; + +/* + * The packet filter hooks are designed for anything to call them to + * possibly intercept the packet. + */ +struct packet_filter_hook { + TAILQ_ENTRY(packet_filter_hook) pfil_link; + int (*pfil_func) __P((void *, int, struct ifnet *, int, + struct mbuf **)); + int pfil_flags; +}; + +#define PFIL_IN 0x00000001 +#define PFIL_OUT 0x00000002 +#define PFIL_WAITOK 0x00000004 +#define PFIL_ALL (PFIL_IN|PFIL_OUT) + +typedef TAILQ_HEAD(pfil_list, packet_filter_hook) pfil_list_t; + +struct pfil_head { + pfil_list_t ph_in; + pfil_list_t ph_out; + int ph_init; +} pfil_head_t; + +struct packet_filter_hook *pfil_hook_get __P((int, struct pfil_head *)); +int pfil_add_hook __P((int (*func) __P((void *, int, + struct ifnet *, int, struct mbuf **)), int, struct pfil_head *)); +int pfil_remove_hook __P((int (*func) __P((void *, int, + struct ifnet *, int, struct mbuf **)), int, struct pfil_head *)); + +/* XXX */ +#if defined(_KERNEL) && !defined(_LKM) +#include "ipfilter.h" +#endif + +#if NIPFILTER > 0 +#ifdef PFIL_HOOKS +#undef PFIL_HOOKS +#endif +#define PFIL_HOOKS +#endif /* NIPFILTER */ + +#endif /* _NET_PFIL_H_ */ |