1 /*
2 * ng_gif_demux.c
3 *
4 * Copyright 2001 The Aerospace Corporation. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
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. The name of The Aerospace Corporation may not be used to endorse or
16 * promote products derived from this software.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AEROSPACE CORPORATION ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AEROSPACE CORPORATION BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
30 *
31 * Copyright (c) 1996-1999 Whistle Communications, Inc.
32 * All rights reserved.
33 *
34 * Subject to the following obligations and disclaimer of warranty, use and
35 * redistribution of this software, in source or object code forms, with or
36 * without modifications are expressly permitted by Whistle Communications;
37 * provided, however, that:
38 * 1. Any and all reproductions of the source or object code must include the
39 * copyright notice above and the following disclaimer of warranties; and
40 * 2. No rights are granted, in any manner or form, to use Whistle
41 * Communications, Inc. trademarks, including the mark "WHISTLE
42 * COMMUNICATIONS" on advertising, endorsements, or otherwise except as
43 * such appears in the above copyright notice or in the software.
44 *
45 * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
46 * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
47 * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
48 * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
49 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
50 * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
51 * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
52 * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
53 * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
54 * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
55 * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
56 * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
57 * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
60 * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
61 * OF SUCH DAMAGE.
62 *
63 * $FreeBSD: releng/5.3/sys/netgraph/ng_gif_demux.c 136588 2004-10-16 08:43:07Z cvs2svn $
64 */
65
66 /*
67 * ng_gif_demux(4) netgraph node type
68 *
69 * Packets received on the "gif" hook have their type header removed
70 * and are passed to the appropriate hook protocol hook. Packets
71 * recieved on a protocol hook have a type header added back and are
72 * passed out the gif hook. The currently supported protocol hooks are:
73 */
74
75 #include <sys/param.h>
76 #include <sys/systm.h>
77 #include <sys/kernel.h>
78 #include <sys/malloc.h>
79 #include <sys/ctype.h>
80 #include <sys/mbuf.h>
81 #include <sys/errno.h>
82 #include <sys/socket.h>
83
84 #include <netgraph/ng_message.h>
85 #include <netgraph/netgraph.h>
86 #include <netgraph/ng_parse.h>
87 #include <netgraph/ng_gif_demux.h>
88
89 #ifdef NG_SEPARATE_MALLOC
90 MALLOC_DEFINE(M_NETGRAPH_GIF_DEMUX, "netgraph_gif_demux",
91 "netgraph gif demux node");
92 #else
93 #define M_NETGRAPH_GIF_DEMUX M_NETGRAPH
94 #endif
95
96 /* This struct describes one address family */
97 struct iffam {
98 sa_family_t family; /* Address family */
99 const char *hookname; /* Name for hook */
100 };
101 typedef const struct iffam *iffam_p;
102
103 /* List of address families supported by our interface */
104 const static struct iffam gFamilies[] = {
105 { AF_INET, NG_GIF_DEMUX_HOOK_INET },
106 { AF_INET6, NG_GIF_DEMUX_HOOK_INET6 },
107 { AF_APPLETALK, NG_GIF_DEMUX_HOOK_ATALK },
108 { AF_IPX, NG_GIF_DEMUX_HOOK_IPX },
109 { AF_ATM, NG_GIF_DEMUX_HOOK_ATM },
110 { AF_NATM, NG_GIF_DEMUX_HOOK_NATM },
111 };
112 #define NUM_FAMILIES (sizeof(gFamilies) / sizeof(*gFamilies))
113
114 /* Per-node private data */
115 struct ng_gif_demux_private {
116 node_p node; /* Our netgraph node */
117 hook_p gif; /* The gif hook */
118 hook_p hooks[NUM_FAMILIES]; /* The protocol hooks */
119 };
120 typedef struct ng_gif_demux_private *priv_p;
121
122 /* Netgraph node methods */
123 static ng_constructor_t ng_gif_demux_constructor;
124 static ng_rcvmsg_t ng_gif_demux_rcvmsg;
125 static ng_shutdown_t ng_gif_demux_shutdown;
126 static ng_newhook_t ng_gif_demux_newhook;
127 static ng_rcvdata_t ng_gif_demux_rcvdata;
128 static ng_disconnect_t ng_gif_demux_disconnect;
129
130 /* Helper stuff */
131 static iffam_p get_iffam_from_af(sa_family_t family);
132 static iffam_p get_iffam_from_hook(priv_p priv, hook_p hook);
133 static iffam_p get_iffam_from_name(const char *name);
134 static hook_p *get_hook_from_iffam(priv_p priv, iffam_p iffam);
135
136 /******************************************************************
137 NETGRAPH PARSE TYPES
138 ******************************************************************/
139
140 /* List of commands and how to convert arguments to/from ASCII */
141 static const struct ng_cmdlist ng_gif_demux_cmdlist[] = {
142 { 0 }
143 };
144
145 /* Node type descriptor */
146 static struct ng_type ng_gif_demux_typestruct = {
147 .version = NG_ABI_VERSION,
148 .name = NG_GIF_DEMUX_NODE_TYPE,
149 .constructor = ng_gif_demux_constructor,
150 .rcvmsg = ng_gif_demux_rcvmsg,
151 .shutdown = ng_gif_demux_shutdown,
152 .newhook = ng_gif_demux_newhook,
153 .rcvdata = ng_gif_demux_rcvdata,
154 .disconnect = ng_gif_demux_disconnect,
155 .cmdlist = ng_gif_demux_cmdlist,
156 };
157 NETGRAPH_INIT(gif_demux, &ng_gif_demux_typestruct);
158
159 /************************************************************************
160 HELPER STUFF
161 ************************************************************************/
162
163 /*
164 * Get the family descriptor from the family ID
165 */
166 static __inline iffam_p
167 get_iffam_from_af(sa_family_t family)
168 {
169 iffam_p iffam;
170 int k;
171
172 for (k = 0; k < NUM_FAMILIES; k++) {
173 iffam = &gFamilies[k];
174 if (iffam->family == family)
175 return (iffam);
176 }
177 return (NULL);
178 }
179
180 /*
181 * Get the family descriptor from the hook
182 */
183 static __inline iffam_p
184 get_iffam_from_hook(priv_p priv, hook_p hook)
185 {
186 int k;
187
188 for (k = 0; k < NUM_FAMILIES; k++)
189 if (priv->hooks[k] == hook)
190 return (&gFamilies[k]);
191 return (NULL);
192 }
193
194 /*
195 * Get the hook from the iffam descriptor
196 */
197
198 static __inline hook_p *
199 get_hook_from_iffam(priv_p priv, iffam_p iffam)
200 {
201 return (&priv->hooks[iffam - gFamilies]);
202 }
203
204 /*
205 * Get the iffam descriptor from the name
206 */
207 static __inline iffam_p
208 get_iffam_from_name(const char *name)
209 {
210 iffam_p iffam;
211 int k;
212
213 for (k = 0; k < NUM_FAMILIES; k++) {
214 iffam = &gFamilies[k];
215 if (!strcmp(iffam->hookname, name))
216 return (iffam);
217 }
218 return (NULL);
219 }
220
221 /******************************************************************
222 NETGRAPH NODE METHODS
223 ******************************************************************/
224
225 /*
226 * Node constructor
227 */
228 static int
229 ng_gif_demux_constructor(node_p node)
230 {
231 priv_p priv;
232
233 /* Allocate and initialize private info */
234 MALLOC(priv, priv_p, sizeof(*priv), M_NETGRAPH_GIF_DEMUX,
235 M_NOWAIT | M_ZERO);
236 if (priv == NULL)
237 return (ENOMEM);
238 priv->node = node;
239
240 NG_NODE_SET_PRIVATE(node, priv);
241
242 /* Done */
243 return (0);
244 }
245
246 /*
247 * Method for attaching a new hook
248 */
249 static int
250 ng_gif_demux_newhook(node_p node, hook_p hook, const char *name)
251 {
252 const priv_p priv = NG_NODE_PRIVATE(node);
253 iffam_p iffam;
254 hook_p *hookptr;
255
256 if (strcmp(NG_GIF_DEMUX_HOOK_GIF, name) == 0)
257 hookptr = &priv->gif;
258 else {
259 iffam = get_iffam_from_name(name);
260 if (iffam == NULL)
261 return (EPFNOSUPPORT);
262 hookptr = get_hook_from_iffam(NG_NODE_PRIVATE(node), iffam);
263 }
264 if (*hookptr != NULL)
265 return (EISCONN);
266 *hookptr = hook;
267 return (0);
268 }
269
270 /*
271 * Receive a control message
272 */
273 static int
274 ng_gif_demux_rcvmsg(node_p node, item_p item, hook_p lasthook)
275 {
276 struct ng_mesg *resp = NULL;
277 int error = 0;
278 struct ng_mesg *msg;
279
280 NGI_GET_MSG(item, msg);
281 switch (msg->header.typecookie) {
282 case NGM_GIF_DEMUX_COOKIE:
283 switch (msg->header.cmd) {
284 /* XXX: Add commands here. */
285 default:
286 error = EINVAL;
287 break;
288 }
289 break;
290 default:
291 error = EINVAL;
292 break;
293 }
294
295 /* Done */
296 NG_RESPOND_MSG(error, node, item, resp);
297 NG_FREE_MSG(msg);
298 return (error);
299 }
300
301 /*
302 * Receive data on a hook
303 */
304 static int
305 ng_gif_demux_rcvdata(hook_p hook, item_p item)
306 {
307 const node_p node = NG_HOOK_NODE(hook);
308 const priv_p priv = NG_NODE_PRIVATE(node);
309 iffam_p iffam;
310 hook_p outhook;
311 int error = 0;
312 struct mbuf *m;
313
314 /* Pull the mbuf out of the item for processing. */
315 NGI_GET_M(item, m);
316
317 if (hook == priv->gif) {
318 /*
319 * Pull off the address family header and find the
320 * output hook.
321 */
322 if (m->m_pkthdr.len < sizeof(sa_family_t)) {
323 NG_FREE_M(m);
324 NG_FREE_ITEM(item);
325 return (EINVAL);
326 }
327 if (m->m_len < sizeof(sa_family_t)
328 && (m = m_pullup(m, sizeof(sa_family_t))) == NULL) {
329 NG_FREE_ITEM(item);
330 return (ENOBUFS);
331 }
332 iffam = get_iffam_from_af(*mtod(m, sa_family_t *));
333 if (iffam == NULL) {
334 NG_FREE_M(m);
335 NG_FREE_ITEM(item);
336 return (EINVAL);
337 }
338 outhook = *get_hook_from_iffam(priv, iffam);
339 m_adj(m, sizeof(sa_family_t));
340 } else {
341 /*
342 * Add address family header and set the output hook.
343 */
344 iffam = get_iffam_from_hook(priv, hook);
345 M_PREPEND(m, sizeof (iffam->family), M_DONTWAIT);
346 if (m == NULL) {
347 NG_FREE_M(m);
348 NG_FREE_ITEM(item);
349 return (ENOBUFS);
350 }
351 bcopy(&iffam->family, mtod(m, sa_family_t *),
352 sizeof(iffam->family));
353 outhook = priv->gif;
354 }
355
356 /* Stuff the mbuf back in. */
357 NGI_M(item) = m;
358
359 /* Deliver packet */
360 NG_FWD_ITEM_HOOK(error, item, outhook);
361 return (error);
362 }
363
364 /*
365 * Shutdown node
366 */
367 static int
368 ng_gif_demux_shutdown(node_p node)
369 {
370 const priv_p priv = NG_NODE_PRIVATE(node);
371
372 FREE(priv, M_NETGRAPH_GIF_DEMUX);
373 NG_NODE_SET_PRIVATE(node, NULL);
374 NG_NODE_UNREF(node);
375 return (0);
376 }
377
378 /*
379 * Hook disconnection.
380 */
381 static int
382 ng_gif_demux_disconnect(hook_p hook)
383 {
384 const priv_p priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
385 iffam_p iffam;
386
387 if (hook == priv->gif)
388 priv->gif = NULL;
389 else {
390 iffam = get_iffam_from_hook(priv, hook);
391 if (iffam == NULL)
392 panic(__func__);
393 *get_hook_from_iffam(priv, iffam) = NULL;
394 }
395
396 return (0);
397 }
Cache object: 76b6f1258351759de408431cc78f6d41
|