FreeBSD kernel netgraph code
ng_btsocket_l2cap_raw.c
Go to the documentation of this file.
1/*
2 * ng_btsocket_l2cap_raw.c
3 */
4
5/*-
6 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
7 *
8 * Copyright (c) 2001-2002 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_btsocket_l2cap_raw.c,v 1.12 2003/09/14 23:29:06 max Exp $
33 * $FreeBSD$
34 */
35
36#include <sys/param.h>
37#include <sys/systm.h>
38#include <sys/bitstring.h>
39#include <sys/domain.h>
40#include <sys/errno.h>
41#include <sys/filedesc.h>
42#include <sys/ioccom.h>
43#include <sys/kernel.h>
44#include <sys/lock.h>
45#include <sys/malloc.h>
46#include <sys/mbuf.h>
47#include <sys/mutex.h>
48#include <sys/priv.h>
49#include <sys/protosw.h>
50#include <sys/queue.h>
51#include <sys/socket.h>
52#include <sys/socketvar.h>
53#include <sys/sysctl.h>
54#include <sys/taskqueue.h>
55
56#include <net/vnet.h>
57
58#include <netgraph/ng_message.h>
59#include <netgraph/netgraph.h>
65
66/* MALLOC define */
67#ifdef NG_SEPARATE_MALLOC
69 "netgraph_btsocks_l2cap_raw", "Netgraph Bluetooth raw L2CAP sockets");
70#else
71#define M_NETGRAPH_BTSOCKET_L2CAP_RAW M_NETGRAPH
72#endif /* NG_SEPARATE_MALLOC */
73
74/* Netgraph node methods */
82
83static void ng_btsocket_l2cap_raw_input (void *, int);
84static void ng_btsocket_l2cap_raw_rtclean (void *, int);
85static void ng_btsocket_l2cap_raw_get_token (u_int32_t *);
86
88 (hook_p, int, void *, int);
90 (ng_btsocket_l2cap_raw_pcb_p, int, void *, int);
91
92#define ng_btsocket_l2cap_raw_wakeup_input_task() \
93 taskqueue_enqueue(taskqueue_swi, &ng_btsocket_l2cap_raw_queue_task)
94
95#define ng_btsocket_l2cap_raw_wakeup_route_task() \
96 taskqueue_enqueue(taskqueue_swi, &ng_btsocket_l2cap_raw_rt_task)
97
98/* Netgraph type descriptor */
99static struct ng_type typestruct = {
109};
110
111/* Globals */
112extern int ifqmaxlen;
119static LIST_HEAD(, ng_btsocket_l2cap_raw_pcb) ng_btsocket_l2cap_raw_sockets;
120static struct mtx ng_btsocket_l2cap_raw_sockets_mtx;
121static u_int32_t ng_btsocket_l2cap_raw_token;
122static struct mtx ng_btsocket_l2cap_raw_token_mtx;
123static LIST_HEAD(, ng_btsocket_l2cap_rtentry) ng_btsocket_l2cap_raw_rt;
124static struct mtx ng_btsocket_l2cap_raw_rt_mtx;
125static struct task ng_btsocket_l2cap_raw_rt_task;
126static struct timeval ng_btsocket_l2cap_raw_lasttime;
127static int ng_btsocket_l2cap_raw_curpps;
128
129/* Sysctl tree */
130SYSCTL_DECL(_net_bluetooth_l2cap_sockets);
131static SYSCTL_NODE(_net_bluetooth_l2cap_sockets, OID_AUTO, raw,
132 CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
133 "Bluetooth raw L2CAP sockets family");
134SYSCTL_UINT(_net_bluetooth_l2cap_sockets_raw, OID_AUTO, debug_level,
135 CTLFLAG_RW,
137 "Bluetooth raw L2CAP sockets debug level");
138SYSCTL_UINT(_net_bluetooth_l2cap_sockets_raw, OID_AUTO, ioctl_timeout,
139 CTLFLAG_RW,
141 "Bluetooth raw L2CAP sockets ioctl timeout");
142SYSCTL_UINT(_net_bluetooth_l2cap_sockets_raw, OID_AUTO, queue_len,
143 CTLFLAG_RD,
145 "Bluetooth raw L2CAP sockets input queue length");
146SYSCTL_UINT(_net_bluetooth_l2cap_sockets_raw, OID_AUTO, queue_maxlen,
147 CTLFLAG_RD,
149 "Bluetooth raw L2CAP sockets input queue max. length");
150SYSCTL_UINT(_net_bluetooth_l2cap_sockets_raw, OID_AUTO, queue_drops,
151 CTLFLAG_RD,
153 "Bluetooth raw L2CAP sockets input queue drops");
154
155/* Debug */
156#define NG_BTSOCKET_L2CAP_RAW_INFO \
157 if (ng_btsocket_l2cap_raw_debug_level >= NG_BTSOCKET_INFO_LEVEL && \
158 ppsratecheck(&ng_btsocket_l2cap_raw_lasttime, &ng_btsocket_l2cap_raw_curpps, 1)) \
159 printf
160
161#define NG_BTSOCKET_L2CAP_RAW_WARN \
162 if (ng_btsocket_l2cap_raw_debug_level >= NG_BTSOCKET_WARN_LEVEL && \
163 ppsratecheck(&ng_btsocket_l2cap_raw_lasttime, &ng_btsocket_l2cap_raw_curpps, 1)) \
164 printf
165
166#define NG_BTSOCKET_L2CAP_RAW_ERR \
167 if (ng_btsocket_l2cap_raw_debug_level >= NG_BTSOCKET_ERR_LEVEL && \
168 ppsratecheck(&ng_btsocket_l2cap_raw_lasttime, &ng_btsocket_l2cap_raw_curpps, 1)) \
169 printf
170
171#define NG_BTSOCKET_L2CAP_RAW_ALERT \
172 if (ng_btsocket_l2cap_raw_debug_level >= NG_BTSOCKET_ALERT_LEVEL && \
173 ppsratecheck(&ng_btsocket_l2cap_raw_lasttime, &ng_btsocket_l2cap_raw_curpps, 1)) \
174 printf
175
176/*****************************************************************************
177 *****************************************************************************
178 ** Netgraph node interface
179 *****************************************************************************
180 *****************************************************************************/
181
182/*
183 * Netgraph node constructor. Do not allow to create node of this type.
184 */
185
186static int
188{
189 return (EINVAL);
190} /* ng_btsocket_l2cap_raw_node_constructor */
191
192/*
193 * Do local shutdown processing. Let old node go and create new fresh one.
194 */
195
196static int
198{
199 int error = 0;
200
201 NG_NODE_UNREF(node);
202
203 /* Create new node */
205 if (error != 0) {
207"%s: Could not create Netgraph node, error=%d\n", __func__, error);
208
210
211 return (error);
212 }
213
216 if (error != 0) {
218"%s: Could not name Netgraph node, error=%d\n", __func__, error);
219
222
223 return (error);
224 }
225
226 return (0);
227} /* ng_btsocket_l2cap_raw_node_shutdown */
228
229/*
230 * We allow any hook to be connected to the node.
231 */
232
233static int
235{
236 return (0);
237} /* ng_btsocket_l2cap_raw_node_newhook */
238
239/*
240 * Just say "YEP, that's OK by me!"
241 */
242
243static int
245{
246 NG_HOOK_SET_PRIVATE(hook, NULL);
247 NG_HOOK_REF(hook); /* Keep extra reference to the hook */
248
249 return (0);
250} /* ng_btsocket_l2cap_raw_node_connect */
251
252/*
253 * Hook disconnection. Schedule route cleanup task
254 */
255
256static int
258{
259 /*
260 * If hook has private information than we must have this hook in
261 * the routing table and must schedule cleaning for the routing table.
262 * Otherwise hook was connected but we never got "hook_info" message,
263 * so we have never added this hook to the routing table and it save
264 * to just delete it.
265 */
266
267 if (NG_HOOK_PRIVATE(hook) != NULL)
269
270 NG_HOOK_UNREF(hook); /* Remove extra reference */
271
272 return (0);
273} /* ng_btsocket_l2cap_raw_node_disconnect */
274
275/*
276 * Process incoming messages
277 */
278
279static int
281{
282 struct ng_mesg *msg = NGI_MSG(item); /* item still has message */
283 int error = 0;
284
285 if (msg != NULL && msg->header.typecookie == NGM_L2CAP_COOKIE) {
286 /*
287 * NGM_L2CAP_NODE_HOOK_INFO is special message initiated by
288 * L2CAP layer. Ignore all other messages if they are not
289 * replies or token is zero
290 */
291
292 if (msg->header.cmd != NGM_L2CAP_NODE_HOOK_INFO) {
293 if (msg->header.token == 0 ||
294 !(msg->header.flags & NGF_RESP)) {
295 NG_FREE_ITEM(item);
296 return (0);
297 }
298 }
299
303"%s: Input queue is full\n", __func__);
304
306 NG_FREE_ITEM(item);
307 error = ENOBUFS;
308 } else {
309 if (hook != NULL) {
310 NG_HOOK_REF(hook);
311 NGI_SET_HOOK(item, hook);
312 }
313
316 }
318 } else {
319 NG_FREE_ITEM(item);
320 error = EINVAL;
321 }
322
323 return (error);
324} /* ng_btsocket_l2cap_raw_node_rcvmsg */
325
326/*
327 * Receive data on a hook
328 */
329
330static int
332{
333 NG_FREE_ITEM(item);
334
335 return (EINVAL);
336} /* ng_btsocket_l2cap_raw_node_rcvdata */
337
338/*****************************************************************************
339 *****************************************************************************
340 ** Socket interface
341 *****************************************************************************
342 *****************************************************************************/
343
344/*
345 * L2CAP sockets input routine
346 */
347
348static void
349ng_btsocket_l2cap_raw_input(void *context, int pending)
350{
351 item_p item = NULL;
352 hook_p hook = NULL;
353 struct ng_mesg *msg = NULL;
354
355 for (;;) {
359
360 if (item == NULL)
361 break;
362
363 KASSERT((item->el_flags & NGQF_TYPE) == NGQF_MESG,
364("%s: invalid item type=%ld\n", __func__, (item->el_flags & NGQF_TYPE)));
365
366 NGI_GET_MSG(item, msg);
367 NGI_GET_HOOK(item, hook);
368 NG_FREE_ITEM(item);
369
370 switch (msg->header.cmd) {
373
374 if (hook == NULL || NG_HOOK_NOT_VALID(hook) ||
375 msg->header.arglen != sizeof(bdaddr_t))
376 break;
377
378 if (bcmp(msg->data, NG_HCI_BDADDR_ANY,
379 sizeof(bdaddr_t)) == 0)
380 break;
381
383 NG_HOOK_PRIVATE(hook);
384 if (rt == NULL) {
385 rt = malloc(sizeof(*rt),
387 M_NOWAIT|M_ZERO);
388 if (rt == NULL)
389 break;
390
391 NG_HOOK_SET_PRIVATE(hook, rt);
392
393 mtx_lock(&ng_btsocket_l2cap_raw_rt_mtx);
394
395 LIST_INSERT_HEAD(&ng_btsocket_l2cap_raw_rt,
396 rt, next);
397 } else
398 mtx_lock(&ng_btsocket_l2cap_raw_rt_mtx);
399
400 bcopy(msg->data, &rt->src, sizeof(rt->src));
401 rt->hook = hook;
402
404"%s: Updating hook \"%s\", src bdaddr=%x:%x:%x:%x:%x:%x\n",
405 __func__, NG_HOOK_NAME(hook),
406 rt->src.b[5], rt->src.b[4], rt->src.b[3],
407 rt->src.b[2], rt->src.b[1], rt->src.b[0]);
408
409 mtx_unlock(&ng_btsocket_l2cap_raw_rt_mtx);
410 } break;
411
420
421 mtx_lock(&ng_btsocket_l2cap_raw_sockets_mtx);
422
423 LIST_FOREACH(pcb,&ng_btsocket_l2cap_raw_sockets,next) {
424 mtx_lock(&pcb->pcb_mtx);
425
426 if (pcb->token == msg->header.token) {
427 pcb->msg = msg;
428 msg = NULL;
429 wakeup(&pcb->msg);
430 mtx_unlock(&pcb->pcb_mtx);
431 break;
432 }
433
434 mtx_unlock(&pcb->pcb_mtx);
435 }
436
437 mtx_unlock(&ng_btsocket_l2cap_raw_sockets_mtx);
438 } break;
439
440 default:
442"%s: Unknown message, cmd=%d\n", __func__, msg->header.cmd);
443 break;
444 }
445
446 if (hook != NULL)
447 NG_HOOK_UNREF(hook); /* remove extra reference */
448
449 NG_FREE_MSG(msg); /* Checks for msg != NULL */
450 }
451} /* ng_btsocket_l2cap_raw_input */
452
453/*
454 * Route cleanup task. Gets scheduled when hook is disconnected. Here we
455 * will find all sockets that use "invalid" hook and disconnect them.
456 */
457
458static void
459ng_btsocket_l2cap_raw_rtclean(void *context, int pending)
460{
463
464 /*
465 * First disconnect all sockets that use "invalid" hook
466 */
467
468 mtx_lock(&ng_btsocket_l2cap_raw_sockets_mtx);
469
470 LIST_FOREACH(pcb, &ng_btsocket_l2cap_raw_sockets, next) {
471 mtx_lock(&pcb->pcb_mtx);
472
473 if (pcb->rt != NULL &&
474 pcb->rt->hook != NULL && NG_HOOK_NOT_VALID(pcb->rt->hook)) {
475 if (pcb->so != NULL &&
476 pcb->so->so_state & SS_ISCONNECTED)
477 soisdisconnected(pcb->so);
478
479 pcb->rt = NULL;
480 }
481
482 mtx_unlock(&pcb->pcb_mtx);
483 }
484
485 mtx_unlock(&ng_btsocket_l2cap_raw_sockets_mtx);
486
487 /*
488 * Now cleanup routing table
489 */
490
491 mtx_lock(&ng_btsocket_l2cap_raw_rt_mtx);
492
493 for (rt = LIST_FIRST(&ng_btsocket_l2cap_raw_rt); rt != NULL; ) {
494 ng_btsocket_l2cap_rtentry_p rt_next = LIST_NEXT(rt, next);
495
496 if (rt->hook != NULL && NG_HOOK_NOT_VALID(rt->hook)) {
497 LIST_REMOVE(rt, next);
498
499 NG_HOOK_SET_PRIVATE(rt->hook, NULL);
500 NG_HOOK_UNREF(rt->hook); /* Remove extra reference */
501
502 bzero(rt, sizeof(*rt));
504 }
505
506 rt = rt_next;
507 }
508
509 mtx_unlock(&ng_btsocket_l2cap_raw_rt_mtx);
510} /* ng_btsocket_l2cap_raw_rtclean */
511
512/*
513 * Initialize everything
514 */
515
516static void
517ng_btsocket_l2cap_raw_init(void *arg __unused)
518{
519 int error = 0;
520
524
525 /* Register Netgraph node type */
526 error = ng_newtype(&typestruct);
527 if (error != 0) {
529"%s: Could not register Netgraph node type, error=%d\n", __func__, error);
530
531 return;
532 }
533
534 /* Create Netgrapg node */
536 if (error != 0) {
538"%s: Could not create Netgraph node, error=%d\n", __func__, error);
539
541
542 return;
543 }
544
547 if (error != 0) {
549"%s: Could not name Netgraph node, error=%d\n", __func__, error);
550
553
554 return;
555 }
556
557 /* Create input queue */
560 "btsocks_l2cap_raw_queue_mtx", NULL, MTX_DEF);
563
564 /* Create list of sockets */
565 LIST_INIT(&ng_btsocket_l2cap_raw_sockets);
566 mtx_init(&ng_btsocket_l2cap_raw_sockets_mtx,
567 "btsocks_l2cap_raw_sockets_mtx", NULL, MTX_DEF);
568
569 /* Tokens */
570 ng_btsocket_l2cap_raw_token = 0;
571 mtx_init(&ng_btsocket_l2cap_raw_token_mtx,
572 "btsocks_l2cap_raw_token_mtx", NULL, MTX_DEF);
573
574 /* Routing table */
575 LIST_INIT(&ng_btsocket_l2cap_raw_rt);
576 mtx_init(&ng_btsocket_l2cap_raw_rt_mtx,
577 "btsocks_l2cap_raw_rt_mtx", NULL, MTX_DEF);
578 TASK_INIT(&ng_btsocket_l2cap_raw_rt_task, 0,
580} /* ng_btsocket_l2cap_raw_init */
581SYSINIT(ng_btsocket_l2cap_raw_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD,
583
584/*
585 * Abort connection on socket
586 */
587
588void
590{
591
593} /* ng_btsocket_l2cap_raw_abort */
594
595void
597{
598
600} /* ng_btsocket_l2cap_raw_close */
601
602/*
603 * Create and attach new socket
604 */
605
606int
607ng_btsocket_l2cap_raw_attach(struct socket *so, int proto, struct thread *td)
608{
610 int error;
611
612 if (pcb != NULL)
613 return (EISCONN);
614
615 if (ng_btsocket_l2cap_raw_node == NULL)
616 return (EPROTONOSUPPORT);
617 if (so->so_type != SOCK_RAW)
618 return (ESOCKTNOSUPPORT);
619
620 /* Reserve send and receive space if it is not reserved yet */
621 error = soreserve(so, NG_BTSOCKET_L2CAP_RAW_SENDSPACE,
623 if (error != 0)
624 return (error);
625
626 /* Allocate the PCB */
627 pcb = malloc(sizeof(*pcb),
628 M_NETGRAPH_BTSOCKET_L2CAP_RAW, M_NOWAIT|M_ZERO);
629 if (pcb == NULL)
630 return (ENOMEM);
631
632 /* Link the PCB and the socket */
633 so->so_pcb = (caddr_t) pcb;
634 pcb->so = so;
635
636 if (priv_check(td, PRIV_NETBLUETOOTH_RAW) == 0)
638
639 mtx_init(&pcb->pcb_mtx, "btsocks_l2cap_raw_pcb_mtx", NULL, MTX_DEF);
640
641 /* Add the PCB to the list */
642 mtx_lock(&ng_btsocket_l2cap_raw_sockets_mtx);
643 LIST_INSERT_HEAD(&ng_btsocket_l2cap_raw_sockets, pcb, next);
644 mtx_unlock(&ng_btsocket_l2cap_raw_sockets_mtx);
645
646 return (0);
647} /* ng_btsocket_l2cap_raw_attach */
648
649/*
650 * Bind socket
651 */
652
653int
654ng_btsocket_l2cap_raw_bind(struct socket *so, struct sockaddr *nam,
655 struct thread *td)
656{
658 struct sockaddr_l2cap *sa = (struct sockaddr_l2cap *) nam;
660
661 if (pcb == NULL)
662 return (EINVAL);
663 if (ng_btsocket_l2cap_raw_node == NULL)
664 return (EINVAL);
665
666 if (sa == NULL)
667 return (EINVAL);
668 if (sa->l2cap_family != AF_BLUETOOTH)
669 return (EAFNOSUPPORT);
670 if((sa->l2cap_len != sizeof(*sa))&&
671 (sa->l2cap_len != sizeof(struct sockaddr_l2cap_compat)))
672 return (EINVAL);
673
674 if (bcmp(&sa->l2cap_bdaddr, NG_HCI_BDADDR_ANY,
675 sizeof(sa->l2cap_bdaddr)) != 0) {
676 mtx_lock(&ng_btsocket_l2cap_raw_rt_mtx);
677
678 LIST_FOREACH(rt, &ng_btsocket_l2cap_raw_rt, next) {
679 if (rt->hook == NULL || NG_HOOK_NOT_VALID(rt->hook))
680 continue;
681
682 if (bcmp(&sa->l2cap_bdaddr, &rt->src,
683 sizeof(rt->src)) == 0)
684 break;
685 }
686
687 mtx_unlock(&ng_btsocket_l2cap_raw_rt_mtx);
688
689 if (rt == NULL)
690 return (ENETDOWN);
691 } else
692 rt = NULL;
693
694 mtx_lock(&pcb->pcb_mtx);
695 bcopy(&sa->l2cap_bdaddr, &pcb->src, sizeof(pcb->src));
696 pcb->rt = rt;
697 mtx_unlock(&pcb->pcb_mtx);
698
699 return (0);
700} /* ng_btsocket_l2cap_raw_bind */
701
702/*
703 * Connect socket
704 */
705
706int
707ng_btsocket_l2cap_raw_connect(struct socket *so, struct sockaddr *nam,
708 struct thread *td)
709{
711 struct sockaddr_l2cap *sa = (struct sockaddr_l2cap *) nam;
713 int error;
714
715 if (pcb == NULL)
716 return (EINVAL);
717 if (ng_btsocket_l2cap_raw_node == NULL)
718 return (EINVAL);
719
720 if (sa == NULL)
721 return (EINVAL);
722 if (sa->l2cap_family != AF_BLUETOOTH)
723 return (EAFNOSUPPORT);
724 if((sa->l2cap_len != sizeof(*sa))&&
725 (sa->l2cap_len != sizeof(struct sockaddr_l2cap_compat)))
726 return (EINVAL);
727
728 if (bcmp(&sa->l2cap_bdaddr, NG_HCI_BDADDR_ANY, sizeof(bdaddr_t)) == 0)
729 return (EINVAL);
730
731 mtx_lock(&pcb->pcb_mtx);
732
733 bcopy(&sa->l2cap_bdaddr, &pcb->dst, sizeof(pcb->dst));
734
735 if (bcmp(&pcb->src, &pcb->dst, sizeof(pcb->src)) == 0) {
736 mtx_unlock(&pcb->pcb_mtx);
737
738 return (EADDRNOTAVAIL);
739 }
740
741 /*
742 * If there is route already - use it
743 */
744
745 if (pcb->rt != NULL) {
746 soisconnected(so);
747 mtx_unlock(&pcb->pcb_mtx);
748
749 return (0);
750 }
751
752 /*
753 * Find the first hook that does not match specified destination address
754 */
755
756 mtx_lock(&ng_btsocket_l2cap_raw_rt_mtx);
757
758 LIST_FOREACH(rt, &ng_btsocket_l2cap_raw_rt, next) {
759 if (rt->hook == NULL || NG_HOOK_NOT_VALID(rt->hook))
760 continue;
761
762 if (bcmp(&pcb->dst, &rt->src, sizeof(rt->src)) != 0)
763 break;
764 }
765
766 if (rt != NULL) {
767 soisconnected(so);
768
769 pcb->rt = rt;
770 bcopy(&rt->src, &pcb->src, sizeof(pcb->src));
771
772 error = 0;
773 } else
774 error = ENETDOWN;
775
776 mtx_unlock(&ng_btsocket_l2cap_raw_rt_mtx);
777 mtx_unlock(&pcb->pcb_mtx);
778
779 return (error);
780} /* ng_btsocket_l2cap_raw_connect */
781
782/*
783 * Process ioctl's calls on socket
784 */
785
786int
787ng_btsocket_l2cap_raw_control(struct socket *so, u_long cmd, caddr_t data,
788 struct ifnet *ifp, struct thread *td)
789{
791 struct ng_mesg *msg = NULL;
792 int error = 0;
793
794 if (pcb == NULL)
795 return (EINVAL);
796 if (ng_btsocket_l2cap_raw_node == NULL)
797 return (EINVAL);
798
799 mtx_lock(&pcb->pcb_mtx);
800
801 /* Check if we route info */
802 if (pcb->rt == NULL) {
803 mtx_unlock(&pcb->pcb_mtx);
804 return (EHOSTUNREACH);
805 }
806
807 /* Check if we have pending ioctl() */
808 if (pcb->token != 0) {
809 mtx_unlock(&pcb->pcb_mtx);
810 return (EBUSY);
811 }
812
813 switch (cmd) {
817
820 &p->flags, sizeof(p->flags));
821 } break;
822
826
829 &p->debug, sizeof(p->debug));
830 } break;
831
835
839 &p->debug, sizeof(p->debug));
840 else
841 error = EPERM;
842 } break;
843
847 ng_l2cap_node_con_list_ep *p1 = NULL;
848 ng_l2cap_node_con_ep *p2 = NULL;
849
850 if (p->num_connections == 0 ||
852 p->connections == NULL) {
853 mtx_unlock(&pcb->pcb_mtx);
854 return (EINVAL);
855 }
856
858 0, M_NOWAIT);
859 if (msg == NULL) {
860 mtx_unlock(&pcb->pcb_mtx);
861 return (ENOMEM);
862 }
864 pcb->token = msg->header.token;
865 pcb->msg = NULL;
866
868 pcb->rt->hook, 0);
869 if (error != 0) {
870 pcb->token = 0;
871 mtx_unlock(&pcb->pcb_mtx);
872 return (error);
873 }
874
875 error = msleep(&pcb->msg, &pcb->pcb_mtx, PZERO|PCATCH, "l2ctl",
877 pcb->token = 0;
878
879 if (error != 0) {
880 mtx_unlock(&pcb->pcb_mtx);
881 return (error);
882 }
883
884 msg = pcb->msg;
885 pcb->msg = NULL;
886
887 mtx_unlock(&pcb->pcb_mtx);
888
889 if (msg != NULL &&
891 /* Return data back to user space */
892 p1 = (ng_l2cap_node_con_list_ep *)(msg->data);
893 p2 = (ng_l2cap_node_con_ep *)(p1 + 1);
894
896 p1->num_connections);
897 if (p->num_connections > 0)
898 error = copyout((caddr_t) p2,
899 (caddr_t) p->connections,
900 p->num_connections * sizeof(*p2));
901 } else
902 error = EINVAL;
903
904 NG_FREE_MSG(msg); /* checks for != NULL */
905 return (error);
906 } /* NOTREACHED */
907
912 ng_l2cap_node_chan_ep *p2 = NULL;
913
914 if (p->num_channels == 0 ||
916 p->channels == NULL) {
917 mtx_unlock(&pcb->pcb_mtx);
918 return (EINVAL);
919 }
920
922 NGM_L2CAP_NODE_GET_CHAN_LIST, 0, M_NOWAIT);
923 if (msg == NULL) {
924 mtx_unlock(&pcb->pcb_mtx);
925 return (ENOMEM);
926 }
928 pcb->token = msg->header.token;
929 pcb->msg = NULL;
930
932 pcb->rt->hook, 0);
933 if (error != 0) {
934 pcb->token = 0;
935 mtx_unlock(&pcb->pcb_mtx);
936 return (error);
937 }
938
939 error = msleep(&pcb->msg, &pcb->pcb_mtx, PZERO|PCATCH, "l2ctl",
941 pcb->token = 0;
942
943 if (error != 0) {
944 mtx_unlock(&pcb->pcb_mtx);
945 return (error);
946 }
947
948 msg = pcb->msg;
949 pcb->msg = NULL;
950
951 mtx_unlock(&pcb->pcb_mtx);
952
953 if (msg != NULL &&
955 /* Return data back to user space */
956 p1 = (ng_l2cap_node_chan_list_ep *)(msg->data);
957 p2 = (ng_l2cap_node_chan_ep *)(p1 + 1);
958
960 p1->num_channels);
961 if (p->num_channels > 0)
962 error = copyout((caddr_t) p2,
963 (caddr_t) p->channels,
964 p->num_channels * sizeof(*p2));
965 } else
966 error = EINVAL;
967
968 NG_FREE_MSG(msg); /* checks for != NULL */
969 return (error);
970 } /* NOTREACHED */
971
973 struct ng_btsocket_l2cap_raw_ping *p =
975 ng_l2cap_l2ca_ping_ip *ip = NULL;
976 ng_l2cap_l2ca_ping_op *op = NULL;
977
978 if ((p->echo_size != 0 && p->echo_data == NULL) ||
980 mtx_unlock(&pcb->pcb_mtx);
981 return (EINVAL);
982 }
983
985 NGM_L2CAP_L2CA_PING, sizeof(*ip) + p->echo_size,
986 M_NOWAIT);
987 if (msg == NULL) {
988 mtx_unlock(&pcb->pcb_mtx);
989 return (ENOMEM);
990 }
992 pcb->token = msg->header.token;
993 pcb->msg = NULL;
994
995 ip = (ng_l2cap_l2ca_ping_ip *)(msg->data);
996 bcopy(&pcb->dst, &ip->bdaddr, sizeof(ip->bdaddr));
997 ip->echo_size = p->echo_size;
998
999 if (ip->echo_size > 0) {
1000 mtx_unlock(&pcb->pcb_mtx);
1001 error = copyin(p->echo_data, ip + 1, p->echo_size);
1002 mtx_lock(&pcb->pcb_mtx);
1003
1004 if (error != 0) {
1005 NG_FREE_MSG(msg);
1006 pcb->token = 0;
1007 mtx_unlock(&pcb->pcb_mtx);
1008 return (error);
1009 }
1010 }
1011
1013 pcb->rt->hook, 0);
1014 if (error != 0) {
1015 pcb->token = 0;
1016 mtx_unlock(&pcb->pcb_mtx);
1017 return (error);
1018 }
1019
1020 error = msleep(&pcb->msg, &pcb->pcb_mtx, PZERO|PCATCH, "l2ctl",
1022 pcb->token = 0;
1023
1024 if (error != 0) {
1025 mtx_unlock(&pcb->pcb_mtx);
1026 return (error);
1027 }
1028
1029 msg = pcb->msg;
1030 pcb->msg = NULL;
1031
1032 mtx_unlock(&pcb->pcb_mtx);
1033
1034 if (msg != NULL &&
1035 msg->header.cmd == NGM_L2CAP_L2CA_PING) {
1036 /* Return data back to the user space */
1037 op = (ng_l2cap_l2ca_ping_op *)(msg->data);
1038 p->result = op->result;
1039 p->echo_size = min(p->echo_size, op->echo_size);
1040
1041 if (p->echo_size > 0)
1042 error = copyout(op + 1, p->echo_data,
1043 p->echo_size);
1044 } else
1045 error = EINVAL;
1046
1047 NG_FREE_MSG(msg); /* checks for != NULL */
1048 return (error);
1049 } /* NOTREACHED */
1050
1054 ng_l2cap_l2ca_get_info_ip *ip = NULL;
1055 ng_l2cap_l2ca_get_info_op *op = NULL;
1056
1058 mtx_unlock(&pcb->pcb_mtx);
1059 return (EPERM);
1060 }
1061
1062 if (p->info_size != 0 && p->info_data == NULL) {
1063 mtx_unlock(&pcb->pcb_mtx);
1064 return (EINVAL);
1065 }
1066
1068 NGM_L2CAP_L2CA_GET_INFO, sizeof(*ip) + p->info_size,
1069 M_NOWAIT);
1070 if (msg == NULL) {
1071 mtx_unlock(&pcb->pcb_mtx);
1072 return (ENOMEM);
1073 }
1075 pcb->token = msg->header.token;
1076 pcb->msg = NULL;
1077
1078 ip = (ng_l2cap_l2ca_get_info_ip *)(msg->data);
1079 bcopy(&pcb->dst, &ip->bdaddr, sizeof(ip->bdaddr));
1080 ip->info_type = p->info_type;
1081
1083 pcb->rt->hook, 0);
1084 if (error != 0) {
1085 pcb->token = 0;
1086 mtx_unlock(&pcb->pcb_mtx);
1087 return (error);
1088 }
1089
1090 error = msleep(&pcb->msg, &pcb->pcb_mtx, PZERO|PCATCH, "l2ctl",
1092 pcb->token = 0;
1093
1094 if (error != 0) {
1095 mtx_unlock(&pcb->pcb_mtx);
1096 return (error);
1097 }
1098
1099 msg = pcb->msg;
1100 pcb->msg = NULL;
1101
1102 mtx_unlock(&pcb->pcb_mtx);
1103
1104 if (msg != NULL &&
1106 /* Return data back to the user space */
1107 op = (ng_l2cap_l2ca_get_info_op *)(msg->data);
1108 p->result = op->result;
1109 p->info_size = min(p->info_size, op->info_size);
1110
1111 if (p->info_size > 0)
1112 error = copyout(op + 1, p->info_data,
1113 p->info_size);
1114 } else
1115 error = EINVAL;
1116
1117 NG_FREE_MSG(msg); /* checks for != NULL */
1118 return (error);
1119 } /* NOTREACHED */
1120
1124
1127 &p->timeout, sizeof(p->timeout));
1128 } break;
1129
1133
1137 &p->timeout, sizeof(p->timeout));
1138 else
1139 error = EPERM;
1140 } break;
1141
1142 default:
1143 error = EINVAL;
1144 break;
1145 }
1146
1147 mtx_unlock(&pcb->pcb_mtx);
1148
1149 return (error);
1150} /* ng_btsocket_l2cap_raw_control */
1151
1152/*
1153 * Detach and destroy socket
1154 */
1155
1156void
1158{
1160
1161 KASSERT(pcb != NULL, ("nt_btsocket_l2cap_raw_detach: pcb == NULL"));
1162 if (ng_btsocket_l2cap_raw_node == NULL)
1163 return;
1164
1165 mtx_lock(&ng_btsocket_l2cap_raw_sockets_mtx);
1166 mtx_lock(&pcb->pcb_mtx);
1167
1168 LIST_REMOVE(pcb, next);
1169
1170 mtx_unlock(&pcb->pcb_mtx);
1171 mtx_unlock(&ng_btsocket_l2cap_raw_sockets_mtx);
1172
1173 mtx_destroy(&pcb->pcb_mtx);
1174
1175 bzero(pcb, sizeof(*pcb));
1177
1178 so->so_pcb = NULL;
1179} /* ng_btsocket_l2cap_raw_detach */
1180
1181/*
1182 * Disconnect socket
1183 */
1184
1185int
1187{
1189
1190 if (pcb == NULL)
1191 return (EINVAL);
1192 if (ng_btsocket_l2cap_raw_node == NULL)
1193 return (EINVAL);
1194
1195 mtx_lock(&pcb->pcb_mtx);
1196 pcb->rt = NULL;
1197 soisdisconnected(so);
1198 mtx_unlock(&pcb->pcb_mtx);
1199
1200 return (0);
1201} /* ng_btsocket_l2cap_raw_disconnect */
1202
1203/*
1204 * Get peer address
1205 */
1206
1207int
1208ng_btsocket_l2cap_raw_peeraddr(struct socket *so, struct sockaddr **nam)
1209{
1211 struct sockaddr_l2cap sa;
1212
1213 if (pcb == NULL)
1214 return (EINVAL);
1215 if (ng_btsocket_l2cap_raw_node == NULL)
1216 return (EINVAL);
1217
1218 mtx_lock(&pcb->pcb_mtx);
1219 bcopy(&pcb->dst, &sa.l2cap_bdaddr, sizeof(sa.l2cap_bdaddr));
1220 mtx_unlock(&pcb->pcb_mtx);
1221
1222 sa.l2cap_psm = 0;
1223 sa.l2cap_len = sizeof(sa);
1224 sa.l2cap_family = AF_BLUETOOTH;
1225 sa.l2cap_cid = 0;
1227
1228 *nam = sodupsockaddr((struct sockaddr *) &sa, M_NOWAIT);
1229
1230 return ((*nam == NULL)? ENOMEM : 0);
1231} /* ng_btsocket_l2cap_raw_peeraddr */
1232
1233/*
1234 * Send data to socket
1235 */
1236
1237int
1238ng_btsocket_l2cap_raw_send(struct socket *so, int flags, struct mbuf *m,
1239 struct sockaddr *nam, struct mbuf *control, struct thread *td)
1240{
1241 NG_FREE_M(m); /* Checks for m != NULL */
1243
1244 return (EOPNOTSUPP);
1245} /* ng_btsocket_l2cap_raw_send */
1246
1247/*
1248 * Get socket address
1249 */
1250
1251int
1252ng_btsocket_l2cap_raw_sockaddr(struct socket *so, struct sockaddr **nam)
1253{
1255 struct sockaddr_l2cap sa;
1256
1257 if (pcb == NULL)
1258 return (EINVAL);
1259 if (ng_btsocket_l2cap_raw_node == NULL)
1260 return (EINVAL);
1261
1262 mtx_lock(&pcb->pcb_mtx);
1263 bcopy(&pcb->src, &sa.l2cap_bdaddr, sizeof(sa.l2cap_bdaddr));
1264 mtx_unlock(&pcb->pcb_mtx);
1265
1266 sa.l2cap_psm = 0;
1267 sa.l2cap_len = sizeof(sa);
1268 sa.l2cap_family = AF_BLUETOOTH;
1269 sa.l2cap_cid = 0;
1271 *nam = sodupsockaddr((struct sockaddr *) &sa, M_NOWAIT);
1272
1273 return ((*nam == NULL)? ENOMEM : 0);
1274} /* ng_btsocket_l2cap_raw_sockaddr */
1275
1276/*
1277 * Get next token
1278 */
1279
1280static void
1282{
1283 mtx_lock(&ng_btsocket_l2cap_raw_token_mtx);
1284
1285 if (++ ng_btsocket_l2cap_raw_token == 0)
1286 ng_btsocket_l2cap_raw_token = 1;
1287
1288 *token = ng_btsocket_l2cap_raw_token;
1289
1290 mtx_unlock(&ng_btsocket_l2cap_raw_token_mtx);
1291} /* ng_btsocket_l2cap_raw_get_token */
1292
1293/*
1294 * Send Netgraph message to the node - do not expect reply
1295 */
1296
1297static int
1298ng_btsocket_l2cap_raw_send_ngmsg(hook_p hook, int cmd, void *arg, int arglen)
1299{
1300 struct ng_mesg *msg = NULL;
1301 int error = 0;
1302
1303 NG_MKMESSAGE(msg, NGM_L2CAP_COOKIE, cmd, arglen, M_NOWAIT);
1304 if (msg == NULL)
1305 return (ENOMEM);
1306
1307 if (arg != NULL && arglen > 0)
1308 bcopy(arg, msg->data, arglen);
1309
1310 NG_SEND_MSG_HOOK(error, ng_btsocket_l2cap_raw_node, msg, hook, 0);
1311
1312 return (error);
1313} /* ng_btsocket_l2cap_raw_send_ngmsg */
1314
1315/*
1316 * Send Netgraph message to the node (no data) and wait for reply
1317 */
1318
1319static int
1321 int cmd, void *rsp, int rsplen)
1322{
1323 struct ng_mesg *msg = NULL;
1324 int error = 0;
1325
1326 mtx_assert(&pcb->pcb_mtx, MA_OWNED);
1327
1328 NG_MKMESSAGE(msg, NGM_L2CAP_COOKIE, cmd, 0, M_NOWAIT);
1329 if (msg == NULL)
1330 return (ENOMEM);
1331
1333 pcb->token = msg->header.token;
1334 pcb->msg = NULL;
1335
1337 pcb->rt->hook, 0);
1338 if (error != 0) {
1339 pcb->token = 0;
1340 return (error);
1341 }
1342
1343 error = msleep(&pcb->msg, &pcb->pcb_mtx, PZERO|PCATCH, "l2ctl",
1345 pcb->token = 0;
1346
1347 if (error != 0)
1348 return (error);
1349
1350 if (pcb->msg != NULL && pcb->msg->header.cmd == cmd)
1351 bcopy(pcb->msg->data, rsp, rsplen);
1352 else
1353 error = EINVAL;
1354
1355 NG_FREE_MSG(pcb->msg); /* checks for != NULL */
1356
1357 return (0);
1358} /* ng_btsocket_l2cap_raw_send_sync_ngmsg */
uint8_t flags
Definition: netflow.h:14
#define NGI_SET_HOOK(i, h)
Definition: netgraph.h:842
int ng_connect_t(hook_p hook)
Definition: netgraph.h:104
#define NGI_MSG(i)
Definition: netgraph.h:834
#define NGI_GET_HOOK(i, h)
Definition: netgraph.h:870
#define NG_FREE_M(m)
Definition: netgraph.h:946
#define NG_HOOK_UNREF(hook)
Definition: netgraph.h:332
#define NG_HOOK_NOT_VALID(hook)
Definition: netgraph.h:337
int ng_rcvmsg_t(node_p node, item_p item, hook_p lasthook)
Definition: netgraph.h:105
#define NGQF_TYPE
Definition: netgraph.h:668
int ng_disconnect_t(hook_p hook)
Definition: netgraph.h:107
int ng_newtype(struct ng_type *tp)
Definition: ng_base.c:1272
#define NG_NODE_UNREF(node)
Definition: netgraph.h:607
#define NG_HOOK_SET_PRIVATE(hook, val)
Definition: netgraph.h:333
#define NGQF_MESG
Definition: netgraph.h:669
#define NG_HOOK_REF(hook)
Definition: netgraph.h:330
int ng_rcvdata_t(hook_p hook, item_p item)
Definition: netgraph.h:106
int ng_shutdown_t(node_p node)
Definition: netgraph.h:101
#define NG_HOOK_NAME(hook)
Definition: netgraph.h:331
#define NG_FREE_ITEM(item)
Definition: netgraph.h:847
int ng_make_node_common(struct ng_type *typep, node_p *nodep)
Definition: ng_base.c:642
int ng_name_node(node_p node, const char *name)
Definition: ng_base.c:852
int ng_constructor_t(node_p node)
Definition: netgraph.h:99
#define NG_FREE_MSG(msg)
Definition: netgraph.h:938
#define NG_ABI_VERSION
Definition: netgraph.h:77
#define NGI_GET_MSG(i, m)
Definition: netgraph.h:858
#define NG_SEND_MSG_HOOK(error, here, msg, hook, retaddr)
Definition: netgraph.h:958
int ng_newhook_t(node_p node, hook_p hook, const char *name)
Definition: netgraph.h:102
#define NG_HOOK_PRIVATE(hook)
Definition: netgraph.h:336
SYSCTL_NODE(_net, OID_AUTO, bluetooth, CTLFLAG_RW|CTLFLAG_MPSAFE, 0, "Bluetooth family")
u_int32_t bluetooth_l2cap_rtx_timeout(void)
Definition: ng_bluetooth.c:203
SYSCTL_UINT(_net_bluetooth_hci, OID_AUTO, max_neighbor_age, CTLFLAG_RW, &bluetooth_hci_max_neighbor_age_value, 600, "Maximal HCI neighbor cache entry age (sec)")
#define NG_BT_ITEMQ_ENQUEUE(q, i)
Definition: ng_bluetooth.h:184
#define NG_BT_ITEMQ_FULL(q)
Definition: ng_bluetooth.h:180
#define BDADDR_BREDR
Definition: ng_bluetooth.h:229
#define NG_BT_ITEMQ_INIT(q, _maxlen)
Definition: ng_bluetooth.h:163
#define NG_BT_ITEMQ_DEQUEUE(q, i)
Definition: ng_bluetooth.h:190
#define NG_BT_ITEMQ_DROP(q)
Definition: ng_bluetooth.h:182
#define SIOC_L2CAP_L2CA_GET_INFO
Definition: ng_btsocket.h:276
#define SIOC_L2CAP_NODE_GET_FLAGS
Definition: ng_btsocket.h:284
#define SIOC_L2CAP_NODE_GET_DEBUG
Definition: ng_btsocket.h:292
#define SIOC_L2CAP_NODE_SET_AUTO_DISCON_TIMO
Definition: ng_btsocket.h:325
#define SIOC_L2CAP_NODE_GET_AUTO_DISCON_TIMO
Definition: ng_btsocket.h:322
#define NG_BTSOCKET_L2CAP_RAW_NODE_TYPE
Definition: ng_btsocket.h:362
#define SIOC_L2CAP_L2CA_PING
Definition: ng_btsocket.h:265
#define SIOC_L2CAP_NODE_GET_CON_LIST
Definition: ng_btsocket.h:304
#define SIOC_L2CAP_NODE_SET_DEBUG
Definition: ng_btsocket.h:295
#define NG_BTSOCKET_WARN_LEVEL
Definition: ng_btsocket.h:372
#define SIOC_L2CAP_NODE_GET_CHAN_LIST
Definition: ng_btsocket.h:313
#define NG_BTSOCKET_L2CAP_RAW_SENDSPACE
#define so2l2cap_raw_pcb(so)
#define NG_BTSOCKET_L2CAP_RAW_RECVSPACE
#define NG_BTSOCKET_L2CAP_RAW_PRIVILEGED
static int ng_btsocket_l2cap_raw_send_sync_ngmsg(ng_btsocket_l2cap_raw_pcb_p, int, void *, int)
static struct mtx ng_btsocket_l2cap_raw_queue_mtx
void ng_btsocket_l2cap_raw_close(struct socket *so)
int ng_btsocket_l2cap_raw_disconnect(struct socket *so)
void ng_btsocket_l2cap_raw_detach(struct socket *so)
static void ng_btsocket_l2cap_raw_rtclean(void *, int)
static struct task ng_btsocket_l2cap_raw_queue_task
static u_int32_t ng_btsocket_l2cap_raw_ioctl_timeout
static ng_rcvmsg_t ng_btsocket_l2cap_raw_node_rcvmsg
static ng_constructor_t ng_btsocket_l2cap_raw_node_constructor
int ifqmaxlen
static void ng_btsocket_l2cap_raw_input(void *, int)
int ng_btsocket_l2cap_raw_sockaddr(struct socket *so, struct sockaddr **nam)
#define ng_btsocket_l2cap_raw_wakeup_route_task()
#define M_NETGRAPH_BTSOCKET_L2CAP_RAW
static node_p ng_btsocket_l2cap_raw_node
static u_int32_t ng_btsocket_l2cap_raw_debug_level
static ng_rcvdata_t ng_btsocket_l2cap_raw_node_rcvdata
#define NG_BTSOCKET_L2CAP_RAW_INFO
static ng_connect_t ng_btsocket_l2cap_raw_node_connect
static struct ng_type typestruct
int ng_btsocket_l2cap_raw_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp, struct thread *td)
static LIST_HEAD(ng_btsocket_l2cap_raw_pcb)
#define NG_BTSOCKET_L2CAP_RAW_ERR
int ng_btsocket_l2cap_raw_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, struct mbuf *control, struct thread *td)
int ng_btsocket_l2cap_raw_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
SYSINIT(ng_btsocket_l2cap_raw_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, ng_btsocket_l2cap_raw_init, NULL)
void ng_btsocket_l2cap_raw_abort(struct socket *so)
static ng_shutdown_t ng_btsocket_l2cap_raw_node_shutdown
static ng_newhook_t ng_btsocket_l2cap_raw_node_newhook
static int ng_btsocket_l2cap_raw_send_ngmsg(hook_p, int, void *, int)
#define NG_BTSOCKET_L2CAP_RAW_ALERT
int ng_btsocket_l2cap_raw_attach(struct socket *so, int proto, struct thread *td)
int ng_btsocket_l2cap_raw_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
static ng_disconnect_t ng_btsocket_l2cap_raw_node_disconnect
#define ng_btsocket_l2cap_raw_wakeup_input_task()
static void ng_btsocket_l2cap_raw_init(void *arg __unused)
static void ng_btsocket_l2cap_raw_get_token(u_int32_t *)
static struct ng_bt_itemq ng_btsocket_l2cap_raw_queue
#define NG_BTSOCKET_L2CAP_RAW_WARN
int ng_btsocket_l2cap_raw_peeraddr(struct socket *so, struct sockaddr **nam)
u_int8_t control
MALLOC_DEFINE(M_NG_CCATM, "ng_ccatm", "netgraph uni api node")
#define NG_HCI_BDADDR_ANY
Definition: ng_hci.h:450
#define min(a, b)
Definition: ng_hci_cmds.c:60
#define NGM_L2CAP_NODE_GET_CHAN_LIST
Definition: ng_l2cap.h:681
#define NGM_L2CAP_NODE_GET_AUTO_DISCON_TIMO
Definition: ng_l2cap.h:702
#define NGM_L2CAP_NODE_SET_DEBUG
Definition: ng_l2cap.h:649
#define NGM_L2CAP_L2CA_PING
Definition: ng_l2cap.h:558
#define NGM_L2CAP_COOKIE
Definition: ng_l2cap.h:60
#define NGM_L2CAP_NODE_GET_CON_LIST
Definition: ng_l2cap.h:657
#define NGM_L2CAP_NODE_GET_FLAGS
Definition: ng_l2cap.h:644
#define NGM_L2CAP_NODE_GET_DEBUG
Definition: ng_l2cap.h:648
#define NGM_L2CAP_L2CA_GET_INFO
Definition: ng_l2cap.h:575
#define NG_L2CAP_MAX_CON_NUM
Definition: ng_l2cap.h:678
#define NGM_L2CAP_NODE_SET_AUTO_DISCON_TIMO
Definition: ng_l2cap.h:703
#define NG_L2CAP_MAX_CHAN_NUM
Definition: ng_l2cap.h:699
#define NG_L2CAP_MAX_ECHO_SIZE
Definition: ng_l2cap.h:281
#define NGM_L2CAP_NODE_HOOK_INFO
Definition: ng_l2cap.h:652
#define NGF_RESP
Definition: ng_message.h:101
#define NG_MKMESSAGE(msg, cookie, cmdid, len, how)
Definition: ng_message.h:378
char *const name
Definition: ng_ppp.c:261
cmd
Definition: ng_pppoe.h:74
uint8_t data[]
Definition: ng_ubt_var.h:2
u_int32_t maxlen
Definition: ng_bluetooth.h:157
u_int32_t drops
Definition: ng_bluetooth.h:158
u_int32_t len
Definition: ng_bluetooth.h:156
ng_l2cap_node_auto_discon_ep timeout
Definition: ng_btsocket.h:320
ng_l2cap_node_chan_ep * channels
Definition: ng_btsocket.h:311
ng_l2cap_node_con_ep * connections
Definition: ng_btsocket.h:302
ng_l2cap_node_debug_ep debug
Definition: ng_btsocket.h:290
ng_l2cap_node_flags_ep flags
Definition: ng_btsocket.h:282
ng_btsocket_l2cap_rtentry_p rt
u_long el_flags
Definition: netgraph.h:636
u_int16_t echo_size
Definition: ng_l2cap.h:562
u_int16_t echo_size
Definition: ng_l2cap.h:570
u_int32_t arglen
Definition: ng_message.h:62
u_int32_t token
Definition: ng_message.h:65
u_int32_t typecookie
Definition: ng_message.h:66
u_int32_t flags
Definition: ng_message.h:64
struct ng_mesg::ng_msghdr header
char data[]
Definition: ng_message.h:69
u_int32_t version
Definition: netgraph.h:1077
u_char l2cap_len
Definition: ng_btsocket.h:234
u_int16_t l2cap_cid
Definition: ng_btsocket.h:238
u_int8_t l2cap_bdaddr_type
Definition: ng_btsocket.h:239
u_int16_t l2cap_psm
Definition: ng_btsocket.h:236
bdaddr_t l2cap_bdaddr
Definition: ng_btsocket.h:237
u_char l2cap_family
Definition: ng_btsocket.h:235