pfil.c revision 1.2
1/* $NetBSD: pfil.c,v 1.2 1996/10/05 23:41:53 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; 50pfil_list_t pfil_bad_list; 51static int done_pfil_init; 52 53void pfil_init __P((void)); 54void pfil_list_add(pfil_list_t *, 55 int (*) __P((void *, int, struct ifnet *, int, struct mbuf **)), int); 56void pfil_list_remove(struct packet_filter_hook *, 57 int (*) __P((void *, int, struct ifnet *, int, struct mbuf **))); 58 59void 60pfil_init() 61{ 62 LIST_INIT(&pfil_in_list); 63 LIST_INIT(&pfil_out_list); 64 LIST_INIT(&pfil_bad_list); 65 done_pfil_init = 1; 66} 67 68/* 69 * pfil_add_hook() adds a function to the packet filter hook. the 70 * flags are: 71 * PFIL_IN call me on incoming packets 72 * PFIL_OUT call me on outgoing packets 73 * PFIL_BAD call me when rejecting a packet (that was 74 * not already reject by in/out filters). 75 * PFIL_ALL call me on all of the above 76 * PFIL_WAITOK OK to call malloc with M_WAITOK. 77 */ 78void 79pfil_add_hook(func, flags) 80 int (*func) __P((void *, int, struct ifnet *, int, 81 struct mbuf **)); 82 int flags; 83{ 84 85 if (done_pfil_init == 0) 86 pfil_init(); 87 88 if (flags & PFIL_IN) 89 pfil_list_add(&pfil_in_list, func, flags); 90 if (flags & PFIL_OUT) 91 pfil_list_add(&pfil_out_list, func, flags); 92 if (flags & PFIL_BAD) 93 pfil_list_add(&pfil_bad_list, func, flags); 94} 95 96void 97pfil_list_add(list, func, flags) 98 pfil_list_t *list; 99 int (*func) __P((void *, int, struct ifnet *, int, 100 struct mbuf **)); 101 int flags; 102{ 103 struct packet_filter_hook *pfh; 104 105 pfh = (struct packet_filter_hook *)malloc(sizeof(*pfh), M_IFADDR, 106 flags & PFIL_WAITOK ? M_WAITOK : M_NOWAIT); 107 if (pfh == NULL) 108 panic("no memory for packet filter hook"); 109 110 pfh->pfil_func = func; 111 LIST_INSERT_HEAD(list, pfh, pfil_link); 112} 113 114/* 115 * pfil_remove_hook removes a specific function from the packet filter 116 * hook list. 117 */ 118void 119pfil_remove_hook(func, flags) 120 int (*func) __P((void *, int, struct ifnet *, int, 121 struct mbuf **)); 122 int flags; 123{ 124 125 if (done_pfil_init == 0) 126 pfil_init(); 127 128 if (flags & PFIL_IN) 129 pfil_list_remove(pfil_in_list.lh_first, func); 130 if (flags & PFIL_OUT) 131 pfil_list_remove(pfil_out_list.lh_first, func); 132 if (flags & PFIL_BAD) 133 pfil_list_remove(pfil_bad_list.lh_first, func); 134} 135 136/* 137 * pfil_list_remove is an internal function that takes a function off the 138 * specified list. 139 */ 140void 141pfil_list_remove(list, func) 142 struct packet_filter_hook *list; 143 int (*func) __P((void *, int, struct ifnet *, int, 144 struct mbuf **)); 145{ 146 struct packet_filter_hook *pfh; 147 148 for (pfh = list; pfh; pfh = pfh->pfil_link.le_next) 149 if (pfh->pfil_func == func) { 150 LIST_REMOVE(pfh, pfil_link); 151 free(pfh, M_IFADDR); 152 return; 153 } 154 printf("pfil_list_remove: no function on list\n"); 155#ifdef DIAGNOSTIC 156 panic("pfil_list_remove"); 157#endif 158} 159 160struct packet_filter_hook * 161pfil_hook_get(flag) 162 int flag; 163{ 164 if (done_pfil_init) 165 switch (flag) { 166 case PFIL_IN: 167 return (pfil_in_list.lh_first); 168 case PFIL_OUT: 169 return (pfil_out_list.lh_first); 170 case PFIL_BAD: 171 return (pfil_bad_list.lh_first); 172 } 173 return NULL; 174} 175