pfil.c revision 1.1 1 /* $NetBSD: pfil.c,v 1.1 1996/09/14 14:40:20 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.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34 #include <sys/param.h>
35 #include <sys/errno.h>
36 #include <sys/malloc.h>
37 #include <sys/socket.h>
38 #include <sys/socketvar.h>
39 #include <sys/systm.h>
40 #include <sys/proc.h>
41 #include <sys/queue.h>
42
43 #include <net/if.h>
44 #include <net/pfil.h>
45
46 typedef LIST_HEAD(, packet_filter_hook) pfil_list_t;
47 pfil_list_t pfil_in_list;
48 pfil_list_t pfil_out_list;
49 pfil_list_t pfil_bad_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 LIST_INIT(&pfil_bad_list);
64 done_pfil_init = 1;
65 }
66
67 /*
68 * pfil_add_hook() adds a function to the packet filter hook. the
69 * flags are:
70 * PFIL_IN call me on incoming packets
71 * PFIL_OUT call me on outgoing packets
72 * PFIL_BAD call me when rejecting a packet (that was
73 * not already reject by in/out filters).
74 * PFIL_ALL call me on all of the above
75 * PFIL_WAITOK OK to call malloc with M_WAITOK.
76 */
77 void
78 pfil_add_hook(func, flags)
79 int (*func) __P((void *, int, struct ifnet *, int,
80 struct mbuf **));
81 int flags;
82 {
83
84 if (done_pfil_init == 0)
85 pfil_init();
86
87 if (flags & PFIL_IN)
88 pfil_list_add(&pfil_in_list, func, flags);
89 if (flags & PFIL_OUT)
90 pfil_list_add(&pfil_out_list, func, flags);
91 if (flags & PFIL_BAD)
92 pfil_list_add(&pfil_bad_list, func, flags);
93 }
94
95 void
96 pfil_list_add(list, func, flags)
97 pfil_list_t *list;
98 int (*func) __P((void *, int, struct ifnet *, int,
99 struct mbuf **));
100 int flags;
101 {
102 struct packet_filter_hook *pfh;
103
104 pfh = (struct packet_filter_hook *)malloc(sizeof(*pfh), M_IFADDR,
105 flags & PFIL_WAITOK ? M_WAITOK : M_NOWAIT);
106 if (pfh == NULL)
107 panic("no memory for packet filter hook");
108
109 pfh->pfil_func = func;
110 LIST_INSERT_HEAD(list, pfh, pfil_link);
111 }
112
113 /*
114 * pfil_remove_hook removes a specific function from the packet filter
115 * hook list.
116 */
117 void
118 pfil_remove_hook(func, flags)
119 int (*func) __P((void *, int, struct ifnet *, int,
120 struct mbuf **));
121 int flags;
122 {
123
124 if (done_pfil_init == 0)
125 pfil_init();
126
127 if (flags & PFIL_IN)
128 pfil_list_remove(pfil_in_list.lh_first, func);
129 if (flags & PFIL_OUT)
130 pfil_list_remove(pfil_out_list.lh_first, func);
131 if (flags & PFIL_BAD)
132 pfil_list_remove(pfil_bad_list.lh_first, func);
133 }
134
135 /*
136 * pfil_list_remove is an internal function that takes a function off the
137 * specified list.
138 */
139 void
140 pfil_list_remove(list, func)
141 struct packet_filter_hook *list;
142 int (*func) __P((void *, int, struct ifnet *, int,
143 struct mbuf **));
144 {
145 struct packet_filter_hook *pfh;
146
147 for (pfh = list; pfh; pfh = pfh->pfil_link.le_next)
148 if (pfh->pfil_func == func) {
149 LIST_REMOVE(pfh, pfil_link);
150 free(pfh, M_IFADDR);
151 return;
152 }
153 printf("pfil_list_remove: no function on list\n");
154 #ifdef DIAGNOSTIC
155 panic("pfil_list_remove");
156 #endif
157 }
158
159 struct packet_filter_hook *
160 pfil_hook_get(flag)
161 int flag;
162 {
163 if (done_pfil_init)
164 switch (flag) {
165 case PFIL_IN:
166 return (pfil_in_list.lh_first);
167 case PFIL_OUT:
168 return (pfil_out_list.lh_first);
169 case PFIL_BAD:
170 return (pfil_bad_list.lh_first);
171 }
172 return NULL;
173 }
174