VirtualBox

source: vbox/trunk/src/VBox/Devices/Network/slirp/libalias/alias_mod.c@ 103068

Last change on this file since 103068 was 52683, checked in by vboxsync, 10 years ago

NAT: Fix #else /* VBOX */ comments to reflect the condition when that
#else is selected. While here, add spaces inside cramped #endif /*VBOX*/
comments.

Same object code is generated.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.9 KB
Line 
1/*-
2 * Copyright (c) 2005 Paolo Pisati <piso@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 */
27#ifndef VBOX
28#include <sys/cdefs.h>
29__FBSDID("$FreeBSD: src/sys/netinet/libalias/alias_mod.c,v 1.3.8.1 2009/04/15 03:14:26 kensmith Exp $");
30
31#ifdef _KERNEL
32#include <sys/libkern.h>
33#include <sys/param.h>
34#include <sys/lock.h>
35#include <sys/rwlock.h>
36#else
37#include <stdio.h>
38#include <string.h>
39#include <sys/types.h>
40#include <errno.h>
41#endif
42
43#include <netinet/in_systm.h>
44#include <netinet/in.h>
45#include <netinet/ip.h>
46
47#ifdef _KERNEL
48#include <netinet/libalias/alias_local.h>
49#include <netinet/libalias/alias_mod.h>
50#else
51#include "alias_local.h"
52#include "alias_mod.h"
53#endif
54
55/* Protocol and userland module handlers chains. */
56LIST_HEAD(handler_chain, proto_handler) handler_chain = LIST_HEAD_INITIALIZER(foo);
57#else /* VBOX */
58# include <slirp.h>
59# include "alias_local.h"
60# include "alias_mod.h"
61#endif /* VBOX */
62#ifdef _KERNEL
63struct rwlock handler_rw;
64#endif
65SLIST_HEAD(dll_chain, dll) dll_chain = SLIST_HEAD_INITIALIZER(foo);
66
67#ifdef _KERNEL
68
69#define LIBALIAS_RWLOCK_INIT() \
70 rw_init(&handler_rw, "Libalias_modules_rwlock")
71#define LIBALIAS_RWLOCK_DESTROY() rw_destroy(&handler_rw)
72#define LIBALIAS_WLOCK_ASSERT() \
73 rw_assert(&handler_rw, RA_WLOCKED)
74
75static __inline void
76LIBALIAS_RLOCK(void)
77{
78 rw_rlock(&handler_rw);
79}
80
81static __inline void
82LIBALIAS_RUNLOCK(void)
83{
84 rw_runlock(&handler_rw);
85}
86
87static __inline void
88LIBALIAS_WLOCK(void)
89{
90 rw_wlock(&handler_rw);
91}
92
93static __inline void
94LIBALIAS_WUNLOCK(void)
95{
96 rw_wunlock(&handler_rw);
97}
98
99static void
100_handler_chain_init(void)
101{
102
103 if (!rw_initialized(&handler_rw))
104 LIBALIAS_RWLOCK_INIT();
105}
106
107static void
108_handler_chain_destroy(void)
109{
110
111 if (rw_initialized(&handler_rw))
112 LIBALIAS_RWLOCK_DESTROY();
113}
114
115#else /* VBOX */
116# define LIBALIAS_WLOCK_ASSERT() ;
117# define LIBALIAS_RLOCK() \
118 do { \
119 int rc = RTCritSectRwEnterShared(&pData->CsRwHandlerChain); \
120 AssertRC(rc); \
121 } while (0)
122# define LIBALIAS_RUNLOCK() \
123 do { \
124 int rc = RTCritSectRwLeaveShared(&pData->CsRwHandlerChain); \
125 AssertRC(rc); \
126 } while (0)
127# define LIBALIAS_WLOCK() \
128 do { \
129 int rc = RTCritSectRwEnterExcl(&pData->CsRwHandlerChain); \
130 AssertRC(rc); \
131 } while (0)
132# define LIBALIAS_WUNLOCK() \
133 do { \
134 int rc = RTCritSectRwLeaveExcl(&pData->CsRwHandlerChain); \
135 AssertRC(rc); \
136 } while (0)
137# define _handler_chain_init() ;
138# define _handler_chain_destroy() ;
139#endif
140
141void
142handler_chain_init(void)
143{
144 _handler_chain_init();
145}
146
147void
148handler_chain_destroy(void)
149{
150 _handler_chain_destroy();
151}
152
153static int
154#ifdef VBOX
155_attach_handler(PNATState pData, struct proto_handler *p)
156#else
157_attach_handler(struct proto_handler *p)
158#endif
159{
160 struct proto_handler *b = NULL, *handler_chain_tail = NULL;
161
162 LIBALIAS_WLOCK_ASSERT();
163 LIST_FOREACH(b, &handler_chain, entries) {
164 if ((b->pri == p->pri) &&
165 (b->dir == p->dir) &&
166 (b->proto == p->proto))
167 return (EEXIST); /* Priority conflict. */
168 if (b->pri > p->pri) {
169 LIST_INSERT_BEFORE(b, p, entries);
170 return (0);
171 }
172
173 /* If the conditions above do not work, we should keep the last
174 * element of the list in order to insert *p right after it. */
175 handler_chain_tail = b;
176 }
177 /* End of list or found right position, inserts here. */
178 if (handler_chain_tail)
179 LIST_INSERT_AFTER(handler_chain_tail, p, entries);
180 else
181 LIST_INSERT_HEAD(&handler_chain, p, entries);
182 return (0);
183}
184
185static int
186#ifdef VBOX
187_detach_handler(PNATState pData, struct proto_handler *p)
188#else
189_detach_handler(struct proto_handler *p)
190#endif
191{
192 struct proto_handler *b, *b_tmp;;
193
194 LIBALIAS_WLOCK_ASSERT();
195 LIST_FOREACH_SAFE(b, &handler_chain, entries, b_tmp) {
196 if (b == p) {
197 LIST_REMOVE(b, entries);
198 return (0);
199 }
200 }
201 return (ENOENT); /* Handler not found. */
202}
203
204int
205#ifdef VBOX
206LibAliasAttachHandlers(PNATState pData, struct proto_handler *_p)
207#else
208LibAliasAttachHandlers(struct proto_handler *_p)
209#endif
210{
211 int i, error = -1;
212
213 LIBALIAS_WLOCK();
214 for (i=0; 1; i++) {
215 if (*((int *)&_p[i]) == EOH)
216 break;
217#ifdef VBOX
218 error = _attach_handler(pData, &_p[i]);
219#else
220 error = _attach_handler(&_p[i]);
221#endif
222 if (error != 0)
223 break;
224 }
225 LIBALIAS_WUNLOCK();
226 return (error);
227}
228
229int
230#ifdef VBOX
231LibAliasDetachHandlers(PNATState pData, struct proto_handler *_p)
232#else
233LibAliasDetachHandlers(struct proto_handler *_p)
234#endif
235{
236 int i, error = -1;
237
238 LIBALIAS_WLOCK();
239 for (i=0; 1; i++) {
240 if (*((int *)&_p[i]) == EOH)
241 break;
242#ifdef VBOX
243 error = _detach_handler(pData, &_p[i]);
244#else
245 error = _detach_handler(&_p[i]);
246#endif
247 if (error != 0)
248 break;
249 }
250 LIBALIAS_WUNLOCK();
251 return (error);
252}
253
254int
255#ifdef VBOX
256detach_handler(PNATState pData, struct proto_handler *_p)
257#else
258detach_handler(struct proto_handler *_p)
259#endif
260{
261 int error = -1;
262
263 LIBALIAS_WLOCK();
264#ifdef VBOX
265 error = _detach_handler(pData, _p);
266#else
267 error = _detach_handler(_p);
268#endif
269 LIBALIAS_WUNLOCK();
270 return (error);
271}
272
273int
274find_handler(int8_t dir, int8_t proto, struct libalias *la, struct ip *pip,
275 struct alias_data *ad)
276{
277#ifdef VBOX
278 PNATState pData = la->pData;
279#endif
280 struct proto_handler *p;
281 int error = ENOENT;
282
283 LIBALIAS_RLOCK();
284
285 LIST_FOREACH(p, &handler_chain, entries) {
286 if ((p->dir & dir) && (p->proto & proto))
287 if (p->fingerprint(la, pip, ad) == 0) {
288 error = p->protohandler(la, pip, ad);
289 break;
290 }
291 }
292 LIBALIAS_RUNLOCK();
293 return (error);
294}
295
296struct proto_handler *
297#ifdef VBOX
298first_handler(PNATState pData)
299#else
300first_handler(void)
301#endif
302{
303
304 return (LIST_FIRST(&handler_chain));
305}
306
307/* Dll manipulation code - this code is not thread safe... */
308
309int
310attach_dll(struct dll *p)
311{
312 struct dll *b;
313
314 SLIST_FOREACH(b, &dll_chain, next) {
315 if (!strncmp(b->name, p->name, DLL_LEN))
316 return (EEXIST); /* Dll name conflict. */
317 }
318 SLIST_INSERT_HEAD(&dll_chain, p, next);
319 return (0);
320}
321
322void *
323detach_dll(char *p)
324{
325 struct dll *b = NULL, *b_tmp;
326 void *error = NULL;
327
328 SLIST_FOREACH_SAFE(b, &dll_chain, next, b_tmp)
329 if (!strncmp(b->name, p, DLL_LEN)) {
330 SLIST_REMOVE(&dll_chain, b, dll, next);
331 error = b;
332 break;
333 }
334 return (error);
335}
336
337struct dll *
338walk_dll_chain(void)
339{
340 struct dll *t;
341
342 t = SLIST_FIRST(&dll_chain);
343 if (t == NULL)
344 return (NULL);
345 SLIST_REMOVE_HEAD(&dll_chain, next);
346 return (t);
347}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette