1 /* $NetBSD: pfil.c,v 1.5 1996/12/20 08:40:46 mrg Exp $ */ 2 3 /* 4 * Copyright (c) 1996 Matthew R. Green 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Matthew R. Green for 18 * the NetBSD Project. 19 * 4. 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 #include <sys/param.h> 36 #include <sys/errno.h> 37 #include <sys/malloc.h> 38 #include <sys/socket.h> 39 #include <sys/socketvar.h> 40 #include <sys/systm.h> 41 #include <sys/proc.h> 42 #include <sys/queue.h> 43 44 #include <net/if.h> 45 #include <net/pfil.h> 46 47 typedef LIST_HEAD(, packet_filter_hook) pfil_list_t; 48 pfil_list_t pfil_in_list; 49 pfil_list_t pfil_out_list; 50 static int done_pfil_init; 51 52 void pfil_init __P((void)); 53 void pfil_list_add(pfil_list_t *, 54 int (*) __P((void *, int, struct ifnet *, int, struct mbuf **)), int); 55 void pfil_list_remove(struct packet_filter_hook *, 56 int (*) __P((void *, int, struct ifnet *, int, struct mbuf **))); 57 58 void 59 pfil_init() 60 { 61 LIST_INIT(&pfil_in_list); 62 LIST_INIT(&pfil_out_list); 63 done_pfil_init = 1; 64 } 65 66 /* 67 * pfil_add_hook() adds a function to the packet filter hook. the 68 * flags are: 69 * PFIL_IN call me on incoming packets 70 * PFIL_OUT call me on outgoing packets 71 * PFIL_ALL call me on all of the above 72 * PFIL_WAITOK OK to call malloc with M_WAITOK. 73 */ 74 void 75 pfil_add_hook(func, flags) 76 int (*func) __P((void *, int, struct ifnet *, int, 77 struct mbuf **)); 78 int flags; 79 { 80 81 if (done_pfil_init == 0) 82 pfil_init(); 83 84 if (flags & PFIL_IN) 85 pfil_list_add(&pfil_in_list, func, flags); 86 if (flags & PFIL_OUT) 87 pfil_list_add(&pfil_out_list, func, flags); 88 } 89 90 void 91 pfil_list_add(list, func, flags) 92 pfil_list_t *list; 93 int (*func) __P((void *, int, struct ifnet *, int, 94 struct mbuf **)); 95 int flags; 96 { 97 struct packet_filter_hook *pfh; 98 99 pfh = (struct packet_filter_hook *)malloc(sizeof(*pfh), M_IFADDR, 100 flags & PFIL_WAITOK ? M_WAITOK : M_NOWAIT); 101 if (pfh == NULL) 102 panic("no memory for packet filter hook"); 103 104 pfh->pfil_func = func; 105 LIST_INSERT_HEAD(list, pfh, pfil_link); 106 } 107 108 /* 109 * pfil_remove_hook removes a specific function from the packet filter 110 * hook list. 111 */ 112 void 113 pfil_remove_hook(func, flags) 114 int (*func) __P((void *, int, struct ifnet *, int, 115 struct mbuf **)); 116 int flags; 117 { 118 119 if (done_pfil_init == 0) 120 pfil_init(); 121 122 if (flags & PFIL_IN) 123 pfil_list_remove(pfil_in_list.lh_first, func); 124 if (flags & PFIL_OUT) 125 pfil_list_remove(pfil_out_list.lh_first, func); 126 } 127 128 /* 129 * pfil_list_remove is an internal function that takes a function off the 130 * specified list. 131 */ 132 void 133 pfil_list_remove(list, func) 134 struct packet_filter_hook *list; 135 int (*func) __P((void *, int, struct ifnet *, int, 136 struct mbuf **)); 137 { 138 struct packet_filter_hook *pfh; 139 140 for (pfh = list; pfh; pfh = pfh->pfil_link.le_next) 141 if (pfh->pfil_func == func) { 142 LIST_REMOVE(pfh, pfil_link); 143 free(pfh, M_IFADDR); 144 return; 145 } 146 printf("pfil_list_remove: no function on list\n"); 147 #ifdef DIAGNOSTIC 148 panic("pfil_list_remove"); 149 #endif 150 } 151 152 struct packet_filter_hook * 153 pfil_hook_get(flag) 154 int flag; 155 { 156 if (done_pfil_init) 157 switch (flag) { 158 case PFIL_IN: 159 return (pfil_in_list.lh_first); 160 case PFIL_OUT: 161 return (pfil_out_list.lh_first); 162 } 163 return NULL; 164 } 165