pfil.c revision 1.5
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 47typedef LIST_HEAD(, packet_filter_hook) pfil_list_t; 48pfil_list_t pfil_in_list; 49pfil_list_t pfil_out_list; 50static int done_pfil_init; 51 52void pfil_init __P((void)); 53void pfil_list_add(pfil_list_t *, 54 int (*) __P((void *, int, struct ifnet *, int, struct mbuf **)), int); 55void pfil_list_remove(struct packet_filter_hook *, 56 int (*) __P((void *, int, struct ifnet *, int, struct mbuf **))); 57 58void 59pfil_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 */ 74void 75pfil_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 90void 91pfil_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 */ 112void 113pfil_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 */ 132void 133pfil_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 152struct packet_filter_hook * 153pfil_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