6 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
8 * Copyright (c) Maksim Yevmenkin <m_evmenkin@yahoo.com>
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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
32 * $Id: ng_l2cap_cmds.h,v 1.4 2003/04/01 18:15:26 max Exp $
36 #ifndef _NETGRAPH_L2CAP_CMDS_H_
37 #define _NETGRAPH_L2CAP_CMDS_H_
39 /******************************************************************************
40 ******************************************************************************
41 ** L2CAP to L2CAP signaling command macros
42 ******************************************************************************
43 ******************************************************************************/
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.
52 /* L2CAP_CommandRej */
53 #define _ng_l2cap_cmd_rej(_m, _ident, _reason, _mtu, _scid, _dcid) \
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; \
61 MGETHDR((_m), M_NOWAIT, MT_DATA); \
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); \
70 c->param.reason = htole16((_reason)); \
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); \
81 (_m)->m_pkthdr.len = (_m)->m_len = sizeof(c->hdr) + \
84 c->hdr.length = htole16(c->hdr.length); \
87 /* L2CAP_ConnectReq */
88 #define _ng_l2cap_con_req(_m, _ident, _psm, _scid) \
91 ng_l2cap_cmd_hdr_t hdr; \
92 ng_l2cap_con_req_cp param; \
93 } __attribute__ ((packed)) *c = NULL; \
95 MGETHDR((_m), M_NOWAIT, MT_DATA); \
99 (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c); \
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)); \
106 c->param.psm = htole16((_psm)); \
107 c->param.scid = htole16((_scid)); \
110 /* L2CAP_ConnectRsp */
111 #define _ng_l2cap_con_rsp(_m, _ident, _dcid, _scid, _result, _status) \
114 ng_l2cap_cmd_hdr_t hdr; \
115 ng_l2cap_con_rsp_cp param; \
116 } __attribute__ ((packed)) *c = NULL; \
118 MGETHDR((_m), M_NOWAIT, MT_DATA); \
122 (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c); \
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)); \
129 c->param.dcid = htole16((_dcid)); \
130 c->param.scid = htole16((_scid)); \
131 c->param.result = htole16((_result)); \
132 c->param.status = htole16((_status)); \
135 /* L2CAP_ConfigReq */
136 #define _ng_l2cap_cfg_req(_m, _ident, _dcid, _flags, _data) \
139 ng_l2cap_cmd_hdr_t hdr; \
140 ng_l2cap_cfg_req_cp param; \
141 } __attribute__ ((packed)) *c = NULL; \
143 MGETHDR((_m), M_NOWAIT, MT_DATA); \
144 if ((_m) == NULL) { \
145 NG_FREE_M((_data)); \
149 (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c); \
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); \
156 c->param.dcid = htole16((_dcid)); \
157 c->param.flags = htole16((_flags)); \
158 if ((_data) != NULL) { \
159 int l = (_data)->m_pkthdr.len; \
161 m_cat((_m), (_data)); \
162 c->hdr.length += l; \
163 (_m)->m_pkthdr.len += l; \
166 c->hdr.length = htole16(c->hdr.length); \
169 /* L2CAP_ConfigRsp */
170 #define _ng_l2cap_cfg_rsp(_m, _ident, _scid, _flags, _result, _data) \
173 ng_l2cap_cmd_hdr_t hdr; \
174 ng_l2cap_cfg_rsp_cp param; \
175 } __attribute__ ((packed)) *c = NULL; \
177 MGETHDR((_m), M_NOWAIT, MT_DATA); \
178 if ((_m) == NULL) { \
179 NG_FREE_M((_data)); \
183 (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c); \
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); \
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; \
196 m_cat((_m), (_data)); \
197 c->hdr.length += l; \
198 (_m)->m_pkthdr.len += l; \
201 c->hdr.length = htole16(c->hdr.length); \
204 #define _ng_l2cap_cmd_urs(_m, _ident, _result) \
207 ng_l2cap_cmd_hdr_t hdr; \
209 } __attribute__ ((packed)) *c = NULL; \
211 MGETHDR((_m), M_NOWAIT, MT_DATA); \
213 (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c); \
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); \
220 c->result = htole16((_result)); \
223 /* Build configuration options */
224 #define _ng_l2cap_build_cfg_options(_m, _mtu, _flush_timo, _flow) \
226 u_int8_t *p = NULL; \
228 MGETHDR((_m), M_NOWAIT, MT_DATA); \
232 (_m)->m_pkthdr.len = (_m)->m_len = 0; \
233 p = mtod((_m), u_int8_t *); \
235 if ((_mtu) != NULL) { \
236 struct _cfg_opt_mtu { \
237 ng_l2cap_cfg_opt_t hdr; \
239 } __attribute__ ((packed)) *o = NULL; \
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)); \
246 (_m)->m_pkthdr.len += sizeof(*o); \
250 if ((_flush_timo) != NULL) { \
251 struct _cfg_opt_flush { \
252 ng_l2cap_cfg_opt_t hdr; \
254 } __attribute__ ((packed)) *o = NULL; \
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)); \
261 (_m)->m_pkthdr.len += sizeof(*o); \
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; \
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); \
291 (_m)->m_pkthdr.len += sizeof(*o); \
294 (_m)->m_len = (_m)->m_pkthdr.len; \
297 /* L2CAP_DisconnectReq */
298 #define _ng_l2cap_discon_req(_m, _ident, _dcid, _scid) \
300 struct _discon_req { \
301 ng_l2cap_cmd_hdr_t hdr; \
302 ng_l2cap_discon_req_cp param; \
303 } __attribute__ ((packed)) *c = NULL; \
305 MGETHDR((_m), M_NOWAIT, MT_DATA); \
309 (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c); \
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)); \
316 c->param.dcid = htole16((_dcid)); \
317 c->param.scid = htole16((_scid)); \
320 /* L2CA_DisconnectRsp */
321 #define _ng_l2cap_discon_rsp(_m, _ident, _dcid, _scid) \
323 struct _discon_rsp { \
324 ng_l2cap_cmd_hdr_t hdr; \
325 ng_l2cap_discon_rsp_cp param; \
326 } __attribute__ ((packed)) *c = NULL; \
328 MGETHDR((_m), M_NOWAIT, MT_DATA); \
332 (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c); \
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)); \
339 c->param.dcid = htole16((_dcid)); \
340 c->param.scid = htole16((_scid)); \
344 #define _ng_l2cap_echo_req(_m, _ident, _data, _size) \
346 ng_l2cap_cmd_hdr_t *c = NULL; \
348 MGETHDR((_m), M_NOWAIT, MT_DATA); \
352 (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c); \
354 c = mtod((_m), ng_l2cap_cmd_hdr_t *); \
355 c->code = NG_L2CAP_ECHO_REQ; \
356 c->ident = (_ident); \
359 if ((_data) != NULL) { \
360 m_copyback((_m), sizeof(*c), (_size), (_data)); \
361 c->length += (_size); \
364 c->length = htole16(c->length); \
368 #define _ng_l2cap_info_req(_m, _ident, _type) \
371 ng_l2cap_cmd_hdr_t hdr; \
372 ng_l2cap_info_req_cp param; \
373 } __attribute__ ((packed)) *c = NULL; \
375 MGETHDR((_m), M_NOWAIT, MT_DATA); \
379 (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c); \
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)); \
386 c->param.type = htole16((_type)); \
390 #define _ng_l2cap_info_rsp(_m, _ident, _type, _result, _mtu) \
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; \
398 MGETHDR((_m), M_NOWAIT, MT_DATA); \
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); \
407 c->param.type = htole16((_type)); \
408 c->param.result = htole16((_result)); \
410 if ((_result) == NG_L2CAP_SUCCESS) { \
412 case NG_L2CAP_CONNLESS_MTU: \
413 c->data.mtu.mtu = htole16((_mtu)); \
414 c->hdr.length += sizeof((c->data.mtu.mtu)); \
419 (_m)->m_pkthdr.len = (_m)->m_len = sizeof(c->hdr) + \
422 c->hdr.length = htole16(c->hdr.length); \
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);
429 #endif /* ndef _NETGRAPH_L2CAP_CMDS_H_ */