Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/netgraph/ng_UI.c
34372 views
1
/*
2
* ng_UI.c
3
*/
4
5
/*-
6
* Copyright (c) 1996-1999 Whistle Communications, Inc.
7
* All rights reserved.
8
*
9
* Subject to the following obligations and disclaimer of warranty, use and
10
* redistribution of this software, in source or object code forms, with or
11
* without modifications are expressly permitted by Whistle Communications;
12
* provided, however, that:
13
* 1. Any and all reproductions of the source or object code must include the
14
* copyright notice above and the following disclaimer of warranties; and
15
* 2. No rights are granted, in any manner or form, to use Whistle
16
* Communications, Inc. trademarks, including the mark "WHISTLE
17
* COMMUNICATIONS" on advertising, endorsements, or otherwise except as
18
* such appears in the above copyright notice or in the software.
19
*
20
* THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
21
* TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
22
* REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
23
* INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
24
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
25
* WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
26
* REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
27
* SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
28
* IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
29
* RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
30
* WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
31
* PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
32
* SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
33
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35
* THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
36
* OF SUCH DAMAGE.
37
*
38
* Author: Julian Elischer <[email protected]>
39
* $Whistle: ng_UI.c,v 1.14 1999/11/01 09:24:51 julian Exp $
40
*/
41
42
#include <sys/param.h>
43
#include <sys/systm.h>
44
#include <sys/errno.h>
45
#include <sys/kernel.h>
46
#include <sys/malloc.h>
47
#include <sys/mbuf.h>
48
#include <sys/errno.h>
49
50
#include <netgraph/ng_message.h>
51
#include <netgraph/netgraph.h>
52
#include <netgraph/ng_UI.h>
53
54
/*
55
* DEFINITIONS
56
*/
57
58
/* Everything, starting with sdlc on has defined UI as 0x03 */
59
#define HDLC_UI 0x03
60
61
/* Node private data */
62
struct ng_UI_private {
63
hook_p downlink;
64
hook_p uplink;
65
};
66
typedef struct ng_UI_private *priv_p;
67
68
/* Netgraph node methods */
69
static ng_constructor_t ng_UI_constructor;
70
static ng_rcvmsg_t ng_UI_rcvmsg;
71
static ng_shutdown_t ng_UI_shutdown;
72
static ng_newhook_t ng_UI_newhook;
73
static ng_rcvdata_t ng_UI_rcvdata;
74
static ng_disconnect_t ng_UI_disconnect;
75
76
/* Node type descriptor */
77
static struct ng_type typestruct = {
78
.version = NG_ABI_VERSION,
79
.name = NG_UI_NODE_TYPE,
80
.constructor = ng_UI_constructor,
81
.rcvmsg = ng_UI_rcvmsg,
82
.shutdown = ng_UI_shutdown,
83
.newhook = ng_UI_newhook,
84
.rcvdata = ng_UI_rcvdata,
85
.disconnect = ng_UI_disconnect,
86
};
87
NETGRAPH_INIT(UI, &typestruct);
88
89
/************************************************************************
90
NETGRAPH NODE STUFF
91
************************************************************************/
92
93
/*
94
* Create a newborn node. We start with an implicit reference.
95
*/
96
97
static int
98
ng_UI_constructor(node_p node)
99
{
100
priv_p priv;
101
102
/* Allocate private structure */
103
priv = malloc(sizeof(*priv), M_NETGRAPH, M_WAITOK | M_ZERO);
104
NG_NODE_SET_PRIVATE(node, priv);
105
return (0);
106
}
107
108
/*
109
* Give our ok for a hook to be added
110
*/
111
static int
112
ng_UI_newhook(node_p node, hook_p hook, const char *name)
113
{
114
const priv_p priv = NG_NODE_PRIVATE(node);
115
116
if (!strcmp(name, NG_UI_HOOK_DOWNSTREAM)) {
117
if (priv->downlink)
118
return (EISCONN);
119
priv->downlink = hook;
120
} else if (!strcmp(name, NG_UI_HOOK_UPSTREAM)) {
121
if (priv->uplink)
122
return (EISCONN);
123
priv->uplink = hook;
124
} else
125
return (EINVAL);
126
return (0);
127
}
128
129
/*
130
* Receive a control message
131
*/
132
static int
133
ng_UI_rcvmsg(node_p node, item_p item, hook_p lasthook)
134
{
135
int error;
136
const priv_p priv = NG_NODE_PRIVATE(node);
137
struct ng_mesg *msg;
138
139
msg = NGI_MSG(item); /* only peeking */
140
if ((msg->header.typecookie == NGM_FLOW_COOKIE) && lasthook) {
141
if (lasthook == priv->downlink) {
142
if (priv->uplink) {
143
NG_FWD_ITEM_HOOK(error, item, priv->uplink);
144
return (error);
145
}
146
} else {
147
if (priv->downlink) {
148
NG_FWD_ITEM_HOOK(error, item, priv->downlink);
149
return (error);
150
}
151
}
152
}
153
154
NG_FREE_ITEM(item);
155
return (EINVAL);
156
}
157
158
#define MAX_ENCAPS_HDR 1
159
#define ERROUT(x) do { error = (x); goto done; } while (0)
160
161
/*
162
* Receive a data frame
163
*/
164
static int
165
ng_UI_rcvdata(hook_p hook, item_p item)
166
{
167
const node_p node = NG_HOOK_NODE(hook);
168
const priv_p priv = NG_NODE_PRIVATE(node);
169
struct mbuf *m;
170
int error = 0;
171
172
NGI_GET_M(item, m);
173
if (hook == priv->downlink) {
174
u_char *start, *ptr;
175
176
if (m->m_len < MAX_ENCAPS_HDR
177
&& !(m = m_pullup(m, MAX_ENCAPS_HDR)))
178
ERROUT(ENOBUFS);
179
ptr = start = mtod(m, u_char *);
180
181
/* Must be UI frame */
182
if (*ptr++ != HDLC_UI)
183
ERROUT(0);
184
185
m_adj(m, ptr - start);
186
NG_FWD_NEW_DATA(error, item, priv->uplink, m); /* m -> NULL */
187
} else if (hook == priv->uplink) {
188
M_PREPEND(m, 1, M_NOWAIT); /* Prepend IP NLPID */
189
if (!m)
190
ERROUT(ENOBUFS);
191
mtod(m, u_char *)[0] = HDLC_UI;
192
NG_FWD_NEW_DATA(error, item, priv->downlink, m); /* m -> NULL */
193
} else
194
panic("%s", __func__);
195
196
done:
197
NG_FREE_M(m); /* does nothing if m == NULL */
198
if (item)
199
NG_FREE_ITEM(item);
200
return (error);
201
}
202
203
/*
204
* Shutdown node
205
*/
206
static int
207
ng_UI_shutdown(node_p node)
208
{
209
const priv_p priv = NG_NODE_PRIVATE(node);
210
211
/* Take down netgraph node */
212
free(priv, M_NETGRAPH);
213
NG_NODE_SET_PRIVATE(node, NULL);
214
NG_NODE_UNREF(node);
215
return (0);
216
}
217
218
/*
219
* Hook disconnection
220
*/
221
static int
222
ng_UI_disconnect(hook_p hook)
223
{
224
const priv_p priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
225
226
if (hook == priv->downlink)
227
priv->downlink = NULL;
228
else if (hook == priv->uplink)
229
priv->uplink = NULL;
230
else
231
panic("%s", __func__);
232
/*
233
* If we are not already shutting down,
234
* and we have no more hooks, then DO shut down.
235
*/
236
if ((NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0)
237
&& (NG_NODE_IS_VALID(NG_HOOK_NODE(hook)))) {
238
ng_rmnode_self(NG_HOOK_NODE(hook));
239
}
240
return (0);
241
}
242
243