/* $NetBSD: pfil.h,v 1.22 2003/06/23 12:57:08 martin Exp $ */ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 2019 Gleb Smirnoff * 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 enum pfil_types { PFIL_TYPE_IP4, PFIL_TYPE_IP6, PFIL_TYPE_ETHERNET, }; #define MAXPFILNAME 64 struct pfilioc_head { char pio_name[MAXPFILNAME]; int pio_nhooksin; int pio_nhooksout; enum pfil_types pio_type; }; struct pfilioc_hook { char pio_module[MAXPFILNAME]; char pio_ruleset[MAXPFILNAME]; int pio_flags; enum pfil_types pio_type; }; struct pfilioc_list { u_int pio_nheads; u_int pio_nhooks; struct pfilioc_head *pio_heads; struct pfilioc_hook *pio_hooks; }; struct pfilioc_link { char pio_name[MAXPFILNAME]; char pio_module[MAXPFILNAME]; char pio_ruleset[MAXPFILNAME]; int pio_flags; }; #define PFILDEV "pfil" #define PFILIOC_LISTHEADS _IOWR('P', 1, struct pfilioc_list) #define PFILIOC_LISTHOOKS _IOWR('P', 2, struct pfilioc_list) #define PFILIOC_LINK _IOW('P', 3, struct pfilioc_link) #define PFIL_IN 0x00010000 #define PFIL_OUT 0x00020000 #define PFIL_FWD 0x00040000 #define PFIL_DIR(f) ((f) & (PFIL_IN|PFIL_OUT)) #define PFIL_HEADPTR 0x00100000 #define PFIL_HOOKPTR 0x00200000 #define PFIL_APPEND 0x00400000 #define PFIL_UNLINK 0x00800000 #ifdef _KERNEL struct mbuf; struct ifnet; struct inpcb; typedef enum { PFIL_PASS = 0, PFIL_DROPPED, PFIL_CONSUMED, PFIL_REALLOCED, } pfil_return_t; typedef pfil_return_t (*pfil_mbuf_chk_t)(struct mbuf **, struct ifnet *, int, void *, struct inpcb *); typedef pfil_return_t (*pfil_mem_chk_t)(void *, u_int, int, struct ifnet *, void *, struct mbuf **); /* * A pfil head is created by a packet intercept point. * * A pfil hook is created by a packet filter. * * Hooks are chained on heads. Historically some hooking happens * automatically, e.g. ipfw(4), pf(4) and ipfilter(4) would register * theirselves on IPv4 and IPv6 input/output. */ typedef struct pfil_hook * pfil_hook_t; typedef struct pfil_head * pfil_head_t; /* * Give us a chance to modify pfil_xxx_args structures in future. */ #define PFIL_VERSION 2 /* Argument structure used by packet filters to register themselves. */ struct pfil_hook_args { int pa_version; int pa_flags; enum pfil_types pa_type; pfil_mbuf_chk_t pa_mbuf_chk; pfil_mem_chk_t pa_mem_chk; void *pa_ruleset; const char *pa_modname; const char *pa_rulname; }; /* Public functions for pfil hook management by packet filters. */ pfil_hook_t pfil_add_hook(struct pfil_hook_args *); void pfil_remove_hook(pfil_hook_t); /* Argument structure used by ioctl() and packet filters to set filters. */ struct pfil_link_args { int pa_version; int pa_flags; union { const char *pa_headname; pfil_head_t pa_head; }; union { struct { const char *pa_modname; const char *pa_rulname; }; pfil_hook_t pa_hook; }; }; /* Public function to configure filter chains. Used by ioctl() and filters. */ int pfil_link(struct pfil_link_args *); /* Argument structure used by inspection points to register themselves. */ struct pfil_head_args { int pa_version; int pa_flags; enum pfil_types pa_type; const char *pa_headname; }; /* Public functions for pfil head management by inspection points. */ pfil_head_t pfil_head_register(struct pfil_head_args *); void pfil_head_unregister(pfil_head_t); /* Public functions to run the packet inspection by inspection points. */ int pfil_mem_in(struct pfil_head *, void *, u_int, struct ifnet *, struct mbuf **); int pfil_mem_out(struct pfil_head *, void *, u_int, struct ifnet *, struct mbuf **); int pfil_mbuf_in(struct pfil_head *, struct mbuf **, struct ifnet *, struct inpcb *inp); int pfil_mbuf_out(struct pfil_head *, struct mbuf **, struct ifnet *, struct inpcb *inp); int pfil_mbuf_fwd(struct pfil_head *, struct mbuf **, struct ifnet *, struct inpcb *); /* * Minimally exposed structure to avoid function call in case of absence * of any filters by protocols and macros to do the check. */ struct _pfil_head { int head_nhooksin; int head_nhooksout; }; #define PFIL_HOOKED_IN(p) (((struct _pfil_head *)(p))->head_nhooksin > 0) #define PFIL_HOOKED_OUT(p) (((struct _pfil_head *)(p))->head_nhooksout > 0) #endif /* _KERNEL */ #endif /* _NET_PFIL_H_ */