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