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.2/sys/netgraph/ng_gif_demux.c 111926 2003-03-05 19:24:24Z peter $
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 NG_ABI_VERSION,
148 NG_GIF_DEMUX_NODE_TYPE,
149 NULL,
150 ng_gif_demux_constructor,
151 ng_gif_demux_rcvmsg,
152 ng_gif_demux_shutdown,
153 ng_gif_demux_newhook,
154 NULL,
155 NULL,
156 ng_gif_demux_rcvdata,
157 ng_gif_demux_disconnect,
158 ng_gif_demux_cmdlist,
159 };
160 NETGRAPH_INIT(gif_demux, &ng_gif_demux_typestruct);
161
162 /************************************************************************
163 HELPER STUFF
164 ************************************************************************/
165
166 /*
167 * Get the family descriptor from the family ID
168 */
169 static __inline__ iffam_p
170 get_iffam_from_af(sa_family_t family)
171 {
172 iffam_p iffam;
173 int k;
174
175 for (k = 0; k < NUM_FAMILIES; k++) {
176 iffam = &gFamilies[k];
177 if (iffam->family == family)
178 return (iffam);
179 }
180 return (NULL);
181 }
182
183 /*
184 * Get the family descriptor from the hook
185 */
186 static __inline__ iffam_p
187 get_iffam_from_hook(priv_p priv, hook_p hook)
188 {
189 int k;
190
191 for (k = 0; k < NUM_FAMILIES; k++)
192 if (priv->hooks[k] == hook)
193 return (&gFamilies[k]);
194 return (NULL);
195 }
196
197 /*
198 * Get the hook from the iffam descriptor
199 */
200
201 static __inline__ hook_p *
202 get_hook_from_iffam(priv_p priv, iffam_p iffam)
203 {
204 return (&priv->hooks[iffam - gFamilies]);
205 }
206
207 /*
208 * Get the iffam descriptor from the name
209 */
210 static __inline__ iffam_p
211 get_iffam_from_name(const char *name)
212 {
213 iffam_p iffam;
214 int k;
215
216 for (k = 0; k < NUM_FAMILIES; k++) {
217 iffam = &gFamilies[k];
218 if (!strcmp(iffam->hookname, name))
219 return (iffam);
220 }
221 return (NULL);
222 }
223
224 /******************************************************************
225 NETGRAPH NODE METHODS
226 ******************************************************************/
227
228 /*
229 * Node constructor
230 */
231 static int
232 ng_gif_demux_constructor(node_p node)
233 {
234 priv_p priv;
235
236 /* Allocate and initialize private info */
237 MALLOC(priv, priv_p, sizeof(*priv), M_NETGRAPH_GIF_DEMUX,
238 M_NOWAIT | M_ZERO);
239 if (priv == NULL)
240 return (ENOMEM);
241 priv->node = node;
242
243 NG_NODE_SET_PRIVATE(node, priv);
244
245 /* Done */
246 return (0);
247 }
248
249 /*
250 * Method for attaching a new hook
251 */
252 static int
253 ng_gif_demux_newhook(node_p node, hook_p hook, const char *name)
254 {
255 const priv_p priv = NG_NODE_PRIVATE(node);
256 iffam_p iffam;
257 hook_p *hookptr;
258
259 if (strcmp(NG_GIF_DEMUX_HOOK_GIF, name) == 0)
260 hookptr = &priv->gif;
261 else {
262 iffam = get_iffam_from_name(name);
263 if (iffam == NULL)
264 return (EPFNOSUPPORT);
265 hookptr = get_hook_from_iffam(NG_NODE_PRIVATE(node), iffam);
266 }
267 if (*hookptr != NULL)
268 return (EISCONN);
269 *hookptr = hook;
270 return (0);
271 }
272
273 /*
274 * Receive a control message
275 */
276 static int
277 ng_gif_demux_rcvmsg(node_p node, item_p item, hook_p lasthook)
278 {
279 struct ng_mesg *resp = NULL;
280 int error = 0;
281 struct ng_mesg *msg;
282
283 NGI_GET_MSG(item, msg);
284 switch (msg->header.typecookie) {
285 case NGM_GIF_DEMUX_COOKIE:
286 switch (msg->header.cmd) {
287 /* XXX: Add commands here. */
288 default:
289 error = EINVAL;
290 break;
291 }
292 break;
293 default:
294 error = EINVAL;
295 break;
296 }
297
298 /* Done */
299 NG_RESPOND_MSG(error, node, item, resp);
300 NG_FREE_MSG(msg);
301 return (error);
302 }
303
304 /*
305 * Receive data on a hook
306 */
307 static int
308 ng_gif_demux_rcvdata(hook_p hook, item_p item)
309 {
310 const node_p node = NG_HOOK_NODE(hook);
311 const priv_p priv = NG_NODE_PRIVATE(node);
312 iffam_p iffam;
313 hook_p outhook;
314 int error = 0;
315 struct mbuf *m;
316
317 /* Pull the mbuf out of the item for processing. */
318 NGI_GET_M(item, m);
319
320 if (hook == priv->gif) {
321 /*
322 * Pull off the address family header and find the
323 * output hook.
324 */
325 if (m->m_pkthdr.len < sizeof(sa_family_t)) {
326 NG_FREE_M(m);
327 NG_FREE_ITEM(item);
328 return (EINVAL);
329 }
330 if (m->m_len < sizeof(sa_family_t)
331 && (m = m_pullup(m, sizeof(sa_family_t))) == NULL) {
332 NG_FREE_ITEM(item);
333 return (ENOBUFS);
334 }
335 iffam = get_iffam_from_af(*mtod(m, sa_family_t *));
336 if (iffam == NULL) {
337 NG_FREE_M(m);
338 NG_FREE_ITEM(item);
339 return (EINVAL);
340 }
341 outhook = *get_hook_from_iffam(priv, iffam);
342 m_adj(m, sizeof(sa_family_t));
343 } else {
344 /*
345 * Add address family header and set the output hook.
346 */
347 iffam = get_iffam_from_hook(priv, hook);
348 M_PREPEND(m, sizeof (iffam->family), M_DONTWAIT);
349 if (m == NULL) {
350 NG_FREE_M(m);
351 NG_FREE_ITEM(item);
352 return (ENOBUFS);
353 }
354 bcopy(&iffam->family, mtod(m, sa_family_t *),
355 sizeof(iffam->family));
356 outhook = priv->gif;
357 }
358
359 /* Stuff the mbuf back in. */
360 NGI_M(item) = m;
361
362 /* Deliver packet */
363 NG_FWD_ITEM_HOOK(error, item, outhook);
364 return (error);
365 }
366
367 /*
368 * Shutdown node
369 */
370 static int
371 ng_gif_demux_shutdown(node_p node)
372 {
373 const priv_p priv = NG_NODE_PRIVATE(node);
374
375 FREE(priv, M_NETGRAPH_GIF_DEMUX);
376 NG_NODE_SET_PRIVATE(node, NULL);
377 NG_NODE_UNREF(node);
378 return (0);
379 }
380
381 /*
382 * Hook disconnection.
383 */
384 static int
385 ng_gif_demux_disconnect(hook_p hook)
386 {
387 const priv_p priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
388 iffam_p iffam;
389
390 if (hook == priv->gif)
391 priv->gif = NULL;
392 else {
393 iffam = get_iffam_from_hook(priv, hook);
394 if (iffam == NULL)
395 panic(__func__);
396 *get_hook_from_iffam(priv, iffam) = NULL;
397 }
398
399 return (0);
400 }
Cache object: 5989741774d7fec2bfd28ded011ea370
|