1 /*
2 * ng_l2cap_cmds.h
3 */
4
5 /*-
6 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
7 *
8 * Copyright (c) Maksim Yevmenkin <m_evmenkin@yahoo.com>
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
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 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 * $Id: ng_l2cap_cmds.h,v 1.4 2003/04/01 18:15:26 max Exp $
33 * $FreeBSD$
34 */
35
36 #ifndef _NETGRAPH_L2CAP_CMDS_H_
37 #define _NETGRAPH_L2CAP_CMDS_H_
38
39 /******************************************************************************
40 ******************************************************************************
41 ** L2CAP to L2CAP signaling command macros
42 ******************************************************************************
43 ******************************************************************************/
44
45 /*
46 * Note: All L2CAP implementations are required to support minimal signaling
47 * MTU of 48 bytes. In order to simplify things we will send one command
48 * per one L2CAP packet. Given evrything above we can assume that one
49 * signaling packet will fit into single mbuf.
50 */
51
52 /* L2CAP_CommandRej */
53 #define _ng_l2cap_cmd_rej(_m, _ident, _reason, _mtu, _scid, _dcid) \
54 do { \
55 struct _cmd_rej { \
56 ng_l2cap_cmd_hdr_t hdr; \
57 ng_l2cap_cmd_rej_cp param; \
58 ng_l2cap_cmd_rej_data_t data; \
59 } __attribute__ ((packed)) *c = NULL; \
60 \
61 MGETHDR((_m), M_NOWAIT, MT_DATA); \
62 if ((_m) == NULL) \
63 break; \
64 \
65 c = mtod((_m), struct _cmd_rej *); \
66 c->hdr.code = NG_L2CAP_CMD_REJ; \
67 c->hdr.ident = (_ident); \
68 c->hdr.length = sizeof(c->param); \
69 \
70 c->param.reason = htole16((_reason)); \
71 \
72 if ((_reason) == NG_L2CAP_REJ_MTU_EXCEEDED) { \
73 c->data.mtu.mtu = htole16((_mtu)); \
74 c->hdr.length += sizeof(c->data.mtu); \
75 } else if ((_reason) == NG_L2CAP_REJ_INVALID_CID) { \
76 c->data.cid.scid = htole16((_scid)); \
77 c->data.cid.dcid = htole16((_dcid)); \
78 c->hdr.length += sizeof(c->data.cid); \
79 } \
80 \
81 (_m)->m_pkthdr.len = (_m)->m_len = sizeof(c->hdr) + \
82 c->hdr.length; \
83 \
84 c->hdr.length = htole16(c->hdr.length); \
85 } while (0)
86
87 /* L2CAP_ConnectReq */
88 #define _ng_l2cap_con_req(_m, _ident, _psm, _scid) \
89 do { \
90 struct _con_req { \
91 ng_l2cap_cmd_hdr_t hdr; \
92 ng_l2cap_con_req_cp param; \
93 } __attribute__ ((packed)) *c = NULL; \
94 \
95 MGETHDR((_m), M_NOWAIT, MT_DATA); \
96 if ((_m) == NULL) \
97 break; \
98 \
99 (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c); \
100 \
101 c = mtod((_m), struct _con_req *); \
102 c->hdr.code = NG_L2CAP_CON_REQ; \
103 c->hdr.ident = (_ident); \
104 c->hdr.length = htole16(sizeof(c->param)); \
105 \
106 c->param.psm = htole16((_psm)); \
107 c->param.scid = htole16((_scid)); \
108 } while (0)
109
110 /* L2CAP_ConnectRsp */
111 #define _ng_l2cap_con_rsp(_m, _ident, _dcid, _scid, _result, _status) \
112 do { \
113 struct _con_rsp { \
114 ng_l2cap_cmd_hdr_t hdr; \
115 ng_l2cap_con_rsp_cp param; \
116 } __attribute__ ((packed)) *c = NULL; \
117 \
118 MGETHDR((_m), M_NOWAIT, MT_DATA); \
119 if ((_m) == NULL) \
120 break; \
121 \
122 (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c); \
123 \
124 c = mtod((_m), struct _con_rsp *); \
125 c->hdr.code = NG_L2CAP_CON_RSP; \
126 c->hdr.ident = (_ident); \
127 c->hdr.length = htole16(sizeof(c->param)); \
128 \
129 c->param.dcid = htole16((_dcid)); \
130 c->param.scid = htole16((_scid)); \
131 c->param.result = htole16((_result)); \
132 c->param.status = htole16((_status)); \
133 } while (0)
134
135 /* L2CAP_ConfigReq */
136 #define _ng_l2cap_cfg_req(_m, _ident, _dcid, _flags, _data) \
137 do { \
138 struct _cfg_req { \
139 ng_l2cap_cmd_hdr_t hdr; \
140 ng_l2cap_cfg_req_cp param; \
141 } __attribute__ ((packed)) *c = NULL; \
142 \
143 MGETHDR((_m), M_NOWAIT, MT_DATA); \
144 if ((_m) == NULL) { \
145 NG_FREE_M((_data)); \
146 break; \
147 } \
148 \
149 (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c); \
150 \
151 c = mtod((_m), struct _cfg_req *); \
152 c->hdr.code = NG_L2CAP_CFG_REQ; \
153 c->hdr.ident = (_ident); \
154 c->hdr.length = sizeof(c->param); \
155 \
156 c->param.dcid = htole16((_dcid)); \
157 c->param.flags = htole16((_flags)); \
158 if ((_data) != NULL) { \
159 int l = (_data)->m_pkthdr.len; \
160 \
161 m_cat((_m), (_data)); \
162 c->hdr.length += l; \
163 (_m)->m_pkthdr.len += l; \
164 } \
165 \
166 c->hdr.length = htole16(c->hdr.length); \
167 } while (0)
168
169 /* L2CAP_ConfigRsp */
170 #define _ng_l2cap_cfg_rsp(_m, _ident, _scid, _flags, _result, _data) \
171 do { \
172 struct _cfg_rsp { \
173 ng_l2cap_cmd_hdr_t hdr; \
174 ng_l2cap_cfg_rsp_cp param; \
175 } __attribute__ ((packed)) *c = NULL; \
176 \
177 MGETHDR((_m), M_NOWAIT, MT_DATA); \
178 if ((_m) == NULL) { \
179 NG_FREE_M((_data)); \
180 break; \
181 } \
182 \
183 (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c); \
184 \
185 c = mtod((_m), struct _cfg_rsp *); \
186 c->hdr.code = NG_L2CAP_CFG_RSP; \
187 c->hdr.ident = (_ident); \
188 c->hdr.length = sizeof(c->param); \
189 \
190 c->param.scid = htole16((_scid)); \
191 c->param.flags = htole16((_flags)); \
192 c->param.result = htole16((_result)); \
193 if ((_data) != NULL) { \
194 int l = (_data)->m_pkthdr.len; \
195 \
196 m_cat((_m), (_data)); \
197 c->hdr.length += l; \
198 (_m)->m_pkthdr.len += l; \
199 } \
200 \
201 c->hdr.length = htole16(c->hdr.length); \
202 } while (0)
203
204 #define _ng_l2cap_cmd_urs(_m, _ident, _result) \
205 do { \
206 struct _cmd_urs{ \
207 ng_l2cap_cmd_hdr_t hdr; \
208 uint16_t result; \
209 } __attribute__ ((packed)) *c = NULL; \
210 \
211 MGETHDR((_m), M_NOWAIT, MT_DATA); \
212 \
213 (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c); \
214 \
215 c = mtod((_m), struct _cmd_urs *); \
216 c->hdr.code = NG_L2CAP_CMD_PARAM_UPDATE_RESPONSE; \
217 c->hdr.ident = (_ident); \
218 c->hdr.length = sizeof(c->result); \
219 \
220 c->result = htole16((_result)); \
221 } while (0)
222
223 /* Build configuration options */
224 #define _ng_l2cap_build_cfg_options(_m, _mtu, _flush_timo, _flow) \
225 do { \
226 u_int8_t *p = NULL; \
227 \
228 MGETHDR((_m), M_NOWAIT, MT_DATA); \
229 if ((_m) == NULL) \
230 break; \
231 \
232 (_m)->m_pkthdr.len = (_m)->m_len = 0; \
233 p = mtod((_m), u_int8_t *); \
234 \
235 if ((_mtu) != NULL) { \
236 struct _cfg_opt_mtu { \
237 ng_l2cap_cfg_opt_t hdr; \
238 u_int16_t val; \
239 } __attribute__ ((packed)) *o = NULL; \
240 \
241 o = (struct _cfg_opt_mtu *) p; \
242 o->hdr.type = NG_L2CAP_OPT_MTU; \
243 o->hdr.length = sizeof(o->val); \
244 o->val = htole16(*(u_int16_t *)(_mtu)); \
245 \
246 (_m)->m_pkthdr.len += sizeof(*o); \
247 p += sizeof(*o); \
248 } \
249 \
250 if ((_flush_timo) != NULL) { \
251 struct _cfg_opt_flush { \
252 ng_l2cap_cfg_opt_t hdr; \
253 u_int16_t val; \
254 } __attribute__ ((packed)) *o = NULL; \
255 \
256 o = (struct _cfg_opt_flush *) p; \
257 o->hdr.type = NG_L2CAP_OPT_FLUSH_TIMO; \
258 o->hdr.length = sizeof(o->val); \
259 o->val = htole16(*(u_int16_t *)(_flush_timo)); \
260 \
261 (_m)->m_pkthdr.len += sizeof(*o); \
262 p += sizeof(*o); \
263 } \
264 \
265 if ((_flow) != NULL) { \
266 struct _cfg_opt_flow { \
267 ng_l2cap_cfg_opt_t hdr; \
268 ng_l2cap_flow_t val; \
269 } __attribute__ ((packed)) *o = NULL; \
270 \
271 o = (struct _cfg_opt_flow *) p; \
272 o->hdr.type = NG_L2CAP_OPT_QOS; \
273 o->hdr.length = sizeof(o->val); \
274 o->val.flags = ((ng_l2cap_flow_p)(_flow))->flags; \
275 o->val.service_type = ((ng_l2cap_flow_p) \
276 (_flow))->service_type; \
277 o->val.token_rate = \
278 htole32(((ng_l2cap_flow_p)(_flow))->token_rate);\
279 o->val.token_bucket_size = \
280 htole32(((ng_l2cap_flow_p) \
281 (_flow))->token_bucket_size); \
282 o->val.peak_bandwidth = \
283 htole32(((ng_l2cap_flow_p) \
284 (_flow))->peak_bandwidth); \
285 o->val.latency = htole32(((ng_l2cap_flow_p) \
286 (_flow))->latency); \
287 o->val.delay_variation = \
288 htole32(((ng_l2cap_flow_p) \
289 (_flow))->delay_variation); \
290 \
291 (_m)->m_pkthdr.len += sizeof(*o); \
292 } \
293 \
294 (_m)->m_len = (_m)->m_pkthdr.len; \
295 } while (0)
296
297 /* L2CAP_DisconnectReq */
298 #define _ng_l2cap_discon_req(_m, _ident, _dcid, _scid) \
299 do { \
300 struct _discon_req { \
301 ng_l2cap_cmd_hdr_t hdr; \
302 ng_l2cap_discon_req_cp param; \
303 } __attribute__ ((packed)) *c = NULL; \
304 \
305 MGETHDR((_m), M_NOWAIT, MT_DATA); \
306 if ((_m) == NULL) \
307 break; \
308 \
309 (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c); \
310 \
311 c = mtod((_m), struct _discon_req *); \
312 c->hdr.code = NG_L2CAP_DISCON_REQ; \
313 c->hdr.ident = (_ident); \
314 c->hdr.length = htole16(sizeof(c->param)); \
315 \
316 c->param.dcid = htole16((_dcid)); \
317 c->param.scid = htole16((_scid)); \
318 } while (0)
319
320 /* L2CA_DisconnectRsp */
321 #define _ng_l2cap_discon_rsp(_m, _ident, _dcid, _scid) \
322 do { \
323 struct _discon_rsp { \
324 ng_l2cap_cmd_hdr_t hdr; \
325 ng_l2cap_discon_rsp_cp param; \
326 } __attribute__ ((packed)) *c = NULL; \
327 \
328 MGETHDR((_m), M_NOWAIT, MT_DATA); \
329 if ((_m) == NULL) \
330 break; \
331 \
332 (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c); \
333 \
334 c = mtod((_m), struct _discon_rsp *); \
335 c->hdr.code = NG_L2CAP_DISCON_RSP; \
336 c->hdr.ident = (_ident); \
337 c->hdr.length = htole16(sizeof(c->param)); \
338 \
339 c->param.dcid = htole16((_dcid)); \
340 c->param.scid = htole16((_scid)); \
341 } while (0)
342
343 /* L2CAP_EchoReq */
344 #define _ng_l2cap_echo_req(_m, _ident, _data, _size) \
345 do { \
346 ng_l2cap_cmd_hdr_t *c = NULL; \
347 \
348 MGETHDR((_m), M_NOWAIT, MT_DATA); \
349 if ((_m) == NULL) \
350 break; \
351 \
352 (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c); \
353 \
354 c = mtod((_m), ng_l2cap_cmd_hdr_t *); \
355 c->code = NG_L2CAP_ECHO_REQ; \
356 c->ident = (_ident); \
357 c->length = 0; \
358 \
359 if ((_data) != NULL) { \
360 m_copyback((_m), sizeof(*c), (_size), (_data)); \
361 c->length += (_size); \
362 } \
363 \
364 c->length = htole16(c->length); \
365 } while (0)
366
367 /* L2CAP_InfoReq */
368 #define _ng_l2cap_info_req(_m, _ident, _type) \
369 do { \
370 struct _info_req { \
371 ng_l2cap_cmd_hdr_t hdr; \
372 ng_l2cap_info_req_cp param; \
373 } __attribute__ ((packed)) *c = NULL; \
374 \
375 MGETHDR((_m), M_NOWAIT, MT_DATA); \
376 if ((_m) == NULL) \
377 break; \
378 \
379 (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c); \
380 \
381 c = mtod((_m), struct _info_req *); \
382 c->hdr.code = NG_L2CAP_INFO_REQ; \
383 c->hdr.ident = (_ident); \
384 c->hdr.length = htole16(sizeof(c->param)); \
385 \
386 c->param.type = htole16((_type)); \
387 } while (0)
388
389 /* L2CAP_InfoRsp */
390 #define _ng_l2cap_info_rsp(_m, _ident, _type, _result, _mtu) \
391 do { \
392 struct _info_rsp { \
393 ng_l2cap_cmd_hdr_t hdr; \
394 ng_l2cap_info_rsp_cp param; \
395 ng_l2cap_info_rsp_data_t data; \
396 } __attribute__ ((packed)) *c = NULL; \
397 \
398 MGETHDR((_m), M_NOWAIT, MT_DATA); \
399 if ((_m) == NULL) \
400 break; \
401 \
402 c = mtod((_m), struct _info_rsp *); \
403 c->hdr.code = NG_L2CAP_INFO_RSP; \
404 c->hdr.ident = (_ident); \
405 c->hdr.length = sizeof(c->param); \
406 \
407 c->param.type = htole16((_type)); \
408 c->param.result = htole16((_result)); \
409 \
410 if ((_result) == NG_L2CAP_SUCCESS) { \
411 switch ((_type)) { \
412 case NG_L2CAP_CONNLESS_MTU: \
413 c->data.mtu.mtu = htole16((_mtu)); \
414 c->hdr.length += sizeof((c->data.mtu.mtu)); \
415 break; \
416 } \
417 } \
418 \
419 (_m)->m_pkthdr.len = (_m)->m_len = sizeof(c->hdr) + \
420 c->hdr.length; \
421 \
422 c->hdr.length = htole16(c->hdr.length); \
423 } while (0)
424
425 void ng_l2cap_con_wakeup (ng_l2cap_con_p);
426 void ng_l2cap_con_fail (ng_l2cap_con_p, u_int16_t);
427 void ng_l2cap_process_command_timeout (node_p, hook_p, void *, int);
428
429 #endif /* ndef _NETGRAPH_L2CAP_CMDS_H_ */
Cache object: ad0f3627bfafc25f17fbcdbde9e9c031
|