1 /* $FreeBSD$ */ 2 /* $NetBSD: pfil.h,v 1.22 2003/06/23 12:57:08 martin Exp $ */ 3 4 /*- 5 * SPDX-License-Identifier: BSD-3-Clause 6 * 7 * Copyright (c) 2019 Gleb Smirnoff <glebius@FreeBSD.org> 8 * Copyright (c) 1996 Matthew R. Green 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. The name of the author may not be used to endorse or promote products 20 * derived from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35 #ifndef _NET_PFIL_H_ 36 #define _NET_PFIL_H_ 37 38 #include <sys/ioccom.h> 39 40 enum pfil_types { 41 PFIL_TYPE_IP4, 42 PFIL_TYPE_IP6, 43 PFIL_TYPE_ETHERNET, 44 }; 45 46 #define MAXPFILNAME 64 47 48 struct pfilioc_head { 49 char pio_name[MAXPFILNAME]; 50 int pio_nhooksin; 51 int pio_nhooksout; 52 enum pfil_types pio_type; 53 }; 54 55 struct pfilioc_hook { 56 char pio_module[MAXPFILNAME]; 57 char pio_ruleset[MAXPFILNAME]; 58 int pio_flags; 59 enum pfil_types pio_type; 60 }; 61 62 struct pfilioc_list { 63 u_int pio_nheads; 64 u_int pio_nhooks; 65 struct pfilioc_head *pio_heads; 66 struct pfilioc_hook *pio_hooks; 67 }; 68 69 struct pfilioc_link { 70 char pio_name[MAXPFILNAME]; 71 char pio_module[MAXPFILNAME]; 72 char pio_ruleset[MAXPFILNAME]; 73 int pio_flags; 74 }; 75 76 #define PFILDEV "pfil" 77 #define PFILIOC_LISTHEADS _IOWR('P', 1, struct pfilioc_list) 78 #define PFILIOC_LISTHOOKS _IOWR('P', 2, struct pfilioc_list) 79 #define PFILIOC_LINK _IOW('P', 3, struct pfilioc_link) 80 81 #define PFIL_IN 0x00010000 82 #define PFIL_OUT 0x00020000 83 #define PFIL_FWD 0x00040000 84 #define PFIL_DIR(f) ((f) & (PFIL_IN|PFIL_OUT)) 85 #define PFIL_MEMPTR 0x00080000 86 #define PFIL_HEADPTR 0x00100000 87 #define PFIL_HOOKPTR 0x00200000 88 #define PFIL_APPEND 0x00400000 89 #define PFIL_UNLINK 0x00800000 90 #define PFIL_LENMASK 0x0000ffff 91 #define PFIL_LENGTH(f) ((f) & PFIL_LENMASK) 92 93 #ifdef _KERNEL 94 struct mbuf; 95 struct ifnet; 96 struct inpcb; 97 98 typedef union { 99 struct mbuf **m; 100 void *mem; 101 uintptr_t __ui; 102 } pfil_packet_t __attribute__((__transparent_union__)); 103 104 static inline pfil_packet_t 105 pfil_packet_align(pfil_packet_t p) 106 { 107 108 return ((pfil_packet_t ) (((uintptr_t)(p).mem + 109 (_Alignof(void *) - 1)) & - _Alignof(void *))); 110 } 111 112 static inline struct mbuf * 113 pfil_mem2mbuf(void *v) 114 { 115 116 return (*(struct mbuf **) (((uintptr_t)(v) + 117 (_Alignof(void *) - 1)) & - _Alignof(void *))); 118 } 119 120 typedef enum { 121 PFIL_PASS = 0, 122 PFIL_DROPPED, 123 PFIL_CONSUMED, 124 PFIL_REALLOCED, 125 } pfil_return_t; 126 127 typedef pfil_return_t (*pfil_func_t)(pfil_packet_t, struct ifnet *, int, 128 void *, struct inpcb *); 129 /* 130 * A pfil head is created by a packet intercept point. 131 * 132 * A pfil hook is created by a packet filter. 133 * 134 * Hooks are chained on heads. Historically some hooking happens 135 * automatically, e.g. ipfw(4), pf(4) and ipfilter(4) would register 136 * theirselves on IPv4 and IPv6 input/output. 137 */ 138 139 typedef struct pfil_hook * pfil_hook_t; 140 typedef struct pfil_head * pfil_head_t; 141 142 /* 143 * Give us a chance to modify pfil_xxx_args structures in future. 144 */ 145 #define PFIL_VERSION 1 146 147 /* Argument structure used by packet filters to register themselves. */ 148 struct pfil_hook_args { 149 int pa_version; 150 int pa_flags; 151 enum pfil_types pa_type; 152 pfil_func_t pa_func; 153 void *pa_ruleset; 154 const char *pa_modname; 155 const char *pa_rulname; 156 }; 157 158 /* Public functions for pfil hook management by packet filters. */ 159 pfil_hook_t pfil_add_hook(struct pfil_hook_args *); 160 void pfil_remove_hook(pfil_hook_t); 161 162 /* Argument structure used by ioctl() and packet filters to set filters. */ 163 struct pfil_link_args { 164 int pa_version; 165 int pa_flags; 166 union { 167 const char *pa_headname; 168 pfil_head_t pa_head; 169 }; 170 union { 171 struct { 172 const char *pa_modname; 173 const char *pa_rulname; 174 }; 175 pfil_hook_t pa_hook; 176 }; 177 }; 178 179 /* Public function to configure filter chains. Used by ioctl() and filters. */ 180 int pfil_link(struct pfil_link_args *); 181 182 /* Argument structure used by inspection points to register themselves. */ 183 struct pfil_head_args { 184 int pa_version; 185 int pa_flags; 186 enum pfil_types pa_type; 187 const char *pa_headname; 188 }; 189 190 /* Public functions for pfil head management by inspection points. */ 191 pfil_head_t pfil_head_register(struct pfil_head_args *); 192 void pfil_head_unregister(pfil_head_t); 193 194 /* Public functions to run the packet inspection by inspection points. */ 195 int pfil_run_hooks(struct pfil_head *, pfil_packet_t, struct ifnet *, int, 196 struct inpcb *inp); 197 /* 198 * Minimally exposed structure to avoid function call in case of absence 199 * of any filters by protocols and macros to do the check. 200 */ 201 struct _pfil_head { 202 int head_nhooksin; 203 int head_nhooksout; 204 }; 205 #define PFIL_HOOKED_IN(p) (((struct _pfil_head *)(p))->head_nhooksin > 0) 206 #define PFIL_HOOKED_OUT(p) (((struct _pfil_head *)(p))->head_nhooksout > 0) 207 208 /* 209 * Alloc mbuf to be used instead of memory pointer. 210 */ 211 int pfil_realloc(pfil_packet_t *, int, struct ifnet *); 212 213 #endif /* _KERNEL */ 214 #endif /* _NET_PFIL_H_ */ 215