1878ed226SJulian Elischer /* 2878ed226SJulian Elischer * ng_btsocket.c 3c398230bSWarner Losh */ 4c398230bSWarner Losh 5c398230bSWarner Losh /*- 6fe267a55SPedro F. Giffuni * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 7fe267a55SPedro F. Giffuni * 8878ed226SJulian Elischer * Copyright (c) 2001-2002 Maksim Yevmenkin <m_evmenkin@yahoo.com> 9878ed226SJulian Elischer * All rights reserved. 10878ed226SJulian Elischer * 11878ed226SJulian Elischer * Redistribution and use in source and binary forms, with or without 12878ed226SJulian Elischer * modification, are permitted provided that the following conditions 13878ed226SJulian Elischer * are met: 14878ed226SJulian Elischer * 1. Redistributions of source code must retain the above copyright 15878ed226SJulian Elischer * notice, this list of conditions and the following disclaimer. 16878ed226SJulian Elischer * 2. Redistributions in binary form must reproduce the above copyright 17878ed226SJulian Elischer * notice, this list of conditions and the following disclaimer in the 18878ed226SJulian Elischer * documentation and/or other materials provided with the distribution. 19878ed226SJulian Elischer * 20878ed226SJulian Elischer * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21878ed226SJulian Elischer * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22878ed226SJulian Elischer * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23878ed226SJulian Elischer * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 24878ed226SJulian Elischer * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25878ed226SJulian Elischer * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26878ed226SJulian Elischer * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27878ed226SJulian Elischer * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28878ed226SJulian Elischer * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29878ed226SJulian Elischer * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30878ed226SJulian Elischer * SUCH DAMAGE. 31878ed226SJulian Elischer * 320986ab12SMaksim Yevmenkin * $Id: ng_btsocket.c,v 1.4 2003/09/14 23:29:06 max Exp $ 33878ed226SJulian Elischer * $FreeBSD$ 34878ed226SJulian Elischer */ 35878ed226SJulian Elischer 36878ed226SJulian Elischer #include <sys/param.h> 37878ed226SJulian Elischer #include <sys/systm.h> 380986ab12SMaksim Yevmenkin #include <sys/bitstring.h> 39878ed226SJulian Elischer #include <sys/errno.h> 40878ed226SJulian Elischer #include <sys/domain.h> 41878ed226SJulian Elischer #include <sys/kernel.h> 42878ed226SJulian Elischer #include <sys/lock.h> 4321da5727SMaksim Yevmenkin #include <sys/mbuf.h> 44878ed226SJulian Elischer #include <sys/mutex.h> 45878ed226SJulian Elischer #include <sys/protosw.h> 46878ed226SJulian Elischer #include <sys/socket.h> 47878ed226SJulian Elischer #include <sys/socketvar.h> 48878ed226SJulian Elischer #include <sys/sysctl.h> 49f2bb1caeSJulian Elischer #include <sys/taskqueue.h> 50d0728d71SRobert Watson 51719fb725SCraig Rodrigues #include <net/vnet.h> 52719fb725SCraig Rodrigues 53878ed226SJulian Elischer #include <netgraph/ng_message.h> 54878ed226SJulian Elischer #include <netgraph/netgraph.h> 55b84b10f9SMaksim Yevmenkin #include <netgraph/bluetooth/include/ng_bluetooth.h> 56b84b10f9SMaksim Yevmenkin #include <netgraph/bluetooth/include/ng_hci.h> 57b84b10f9SMaksim Yevmenkin #include <netgraph/bluetooth/include/ng_l2cap.h> 58b84b10f9SMaksim Yevmenkin #include <netgraph/bluetooth/include/ng_btsocket.h> 59b84b10f9SMaksim Yevmenkin #include <netgraph/bluetooth/include/ng_btsocket_hci_raw.h> 60b84b10f9SMaksim Yevmenkin #include <netgraph/bluetooth/include/ng_btsocket_l2cap.h> 61b84b10f9SMaksim Yevmenkin #include <netgraph/bluetooth/include/ng_btsocket_rfcomm.h> 6248698a83SMaksim Yevmenkin #include <netgraph/bluetooth/include/ng_btsocket_sco.h> 63878ed226SJulian Elischer 64878ed226SJulian Elischer static int ng_btsocket_modevent (module_t, int, void *); 6548698a83SMaksim Yevmenkin 6648698a83SMaksim Yevmenkin /* 67878ed226SJulian Elischer * Definitions of protocols supported in the BLUETOOTH domain 68878ed226SJulian Elischer */ 69878ed226SJulian Elischer 70*e7d02be1SGleb Smirnoff /* Bluetooth raw HCI sockets */ 71*e7d02be1SGleb Smirnoff static struct protosw ng_btsocket_hci_raw_protosw = { 72303989a2SRuslan Ermilov .pr_type = SOCK_RAW, 73303989a2SRuslan Ermilov .pr_protocol = BLUETOOTH_PROTO_HCI, 74303989a2SRuslan Ermilov .pr_flags = PR_ATOMIC|PR_ADDR, 75303989a2SRuslan Ermilov .pr_ctloutput = ng_btsocket_hci_raw_ctloutput, 76*e7d02be1SGleb Smirnoff .pr_abort = ng_btsocket_hci_raw_abort, 77*e7d02be1SGleb Smirnoff .pr_attach = ng_btsocket_hci_raw_attach, 78*e7d02be1SGleb Smirnoff .pr_bind = ng_btsocket_hci_raw_bind, 79*e7d02be1SGleb Smirnoff .pr_connect = ng_btsocket_hci_raw_connect, 80*e7d02be1SGleb Smirnoff .pr_control = ng_btsocket_hci_raw_control, 81*e7d02be1SGleb Smirnoff .pr_detach = ng_btsocket_hci_raw_detach, 82*e7d02be1SGleb Smirnoff .pr_disconnect = ng_btsocket_hci_raw_disconnect, 83*e7d02be1SGleb Smirnoff .pr_peeraddr = ng_btsocket_hci_raw_peeraddr, 84*e7d02be1SGleb Smirnoff .pr_send = ng_btsocket_hci_raw_send, 85*e7d02be1SGleb Smirnoff .pr_sockaddr = ng_btsocket_hci_raw_sockaddr, 86*e7d02be1SGleb Smirnoff .pr_close = ng_btsocket_hci_raw_close, 87*e7d02be1SGleb Smirnoff }; 88*e7d02be1SGleb Smirnoff 89*e7d02be1SGleb Smirnoff /* Bluetooth raw L2CAP sockets */ 90*e7d02be1SGleb Smirnoff static struct protosw ng_btsocket_l2cap_raw_protosw = { 91303989a2SRuslan Ermilov .pr_type = SOCK_RAW, 92303989a2SRuslan Ermilov .pr_protocol = BLUETOOTH_PROTO_L2CAP, 93303989a2SRuslan Ermilov .pr_flags = PR_ATOMIC|PR_ADDR, 94*e7d02be1SGleb Smirnoff .pr_abort = ng_btsocket_l2cap_raw_abort, 95*e7d02be1SGleb Smirnoff .pr_attach = ng_btsocket_l2cap_raw_attach, 96*e7d02be1SGleb Smirnoff .pr_bind = ng_btsocket_l2cap_raw_bind, 97*e7d02be1SGleb Smirnoff .pr_connect = ng_btsocket_l2cap_raw_connect, 98*e7d02be1SGleb Smirnoff .pr_control = ng_btsocket_l2cap_raw_control, 99*e7d02be1SGleb Smirnoff .pr_detach = ng_btsocket_l2cap_raw_detach, 100*e7d02be1SGleb Smirnoff .pr_disconnect = ng_btsocket_l2cap_raw_disconnect, 101*e7d02be1SGleb Smirnoff .pr_peeraddr = ng_btsocket_l2cap_raw_peeraddr, 102*e7d02be1SGleb Smirnoff .pr_send = ng_btsocket_l2cap_raw_send, 103*e7d02be1SGleb Smirnoff .pr_sockaddr = ng_btsocket_l2cap_raw_sockaddr, 104*e7d02be1SGleb Smirnoff .pr_close = ng_btsocket_l2cap_raw_close, 105*e7d02be1SGleb Smirnoff }; 106*e7d02be1SGleb Smirnoff 107*e7d02be1SGleb Smirnoff /* Bluetooth SEQPACKET L2CAP sockets */ 108*e7d02be1SGleb Smirnoff static struct protosw ng_btsocket_l2cap_protosw = { 109303989a2SRuslan Ermilov .pr_type = SOCK_SEQPACKET, 110303989a2SRuslan Ermilov .pr_protocol = BLUETOOTH_PROTO_L2CAP, 111303989a2SRuslan Ermilov .pr_flags = PR_ATOMIC|PR_CONNREQUIRED, 112303989a2SRuslan Ermilov .pr_ctloutput = ng_btsocket_l2cap_ctloutput, 113*e7d02be1SGleb Smirnoff .pr_abort = ng_btsocket_l2cap_abort, 114*e7d02be1SGleb Smirnoff .pr_accept = ng_btsocket_l2cap_accept, 115*e7d02be1SGleb Smirnoff .pr_attach = ng_btsocket_l2cap_attach, 116*e7d02be1SGleb Smirnoff .pr_bind = ng_btsocket_l2cap_bind, 117*e7d02be1SGleb Smirnoff .pr_connect = ng_btsocket_l2cap_connect, 118*e7d02be1SGleb Smirnoff .pr_control = ng_btsocket_l2cap_control, 119*e7d02be1SGleb Smirnoff .pr_detach = ng_btsocket_l2cap_detach, 120*e7d02be1SGleb Smirnoff .pr_disconnect = ng_btsocket_l2cap_disconnect, 121*e7d02be1SGleb Smirnoff .pr_listen = ng_btsocket_l2cap_listen, 122*e7d02be1SGleb Smirnoff .pr_peeraddr = ng_btsocket_l2cap_peeraddr, 123*e7d02be1SGleb Smirnoff .pr_send = ng_btsocket_l2cap_send, 124*e7d02be1SGleb Smirnoff .pr_sockaddr = ng_btsocket_l2cap_sockaddr, 125*e7d02be1SGleb Smirnoff .pr_close = ng_btsocket_l2cap_close, 126*e7d02be1SGleb Smirnoff }; 127*e7d02be1SGleb Smirnoff 128*e7d02be1SGleb Smirnoff /* Bluetooth STREAM RFCOMM sockets */ 129*e7d02be1SGleb Smirnoff static struct protosw ng_btsocket_rfcomm_protosw = { 130303989a2SRuslan Ermilov .pr_type = SOCK_STREAM, 131303989a2SRuslan Ermilov .pr_protocol = BLUETOOTH_PROTO_RFCOMM, 132303989a2SRuslan Ermilov .pr_flags = PR_CONNREQUIRED, 133303989a2SRuslan Ermilov .pr_ctloutput = ng_btsocket_rfcomm_ctloutput, 134*e7d02be1SGleb Smirnoff .pr_abort = ng_btsocket_rfcomm_abort, 135*e7d02be1SGleb Smirnoff .pr_accept = ng_btsocket_rfcomm_accept, 136*e7d02be1SGleb Smirnoff .pr_attach = ng_btsocket_rfcomm_attach, 137*e7d02be1SGleb Smirnoff .pr_bind = ng_btsocket_rfcomm_bind, 138*e7d02be1SGleb Smirnoff .pr_connect = ng_btsocket_rfcomm_connect, 139*e7d02be1SGleb Smirnoff .pr_control = ng_btsocket_rfcomm_control, 140*e7d02be1SGleb Smirnoff .pr_detach = ng_btsocket_rfcomm_detach, 141*e7d02be1SGleb Smirnoff .pr_disconnect = ng_btsocket_rfcomm_disconnect, 142*e7d02be1SGleb Smirnoff .pr_listen = ng_btsocket_rfcomm_listen, 143*e7d02be1SGleb Smirnoff .pr_peeraddr = ng_btsocket_rfcomm_peeraddr, 144*e7d02be1SGleb Smirnoff .pr_send = ng_btsocket_rfcomm_send, 145*e7d02be1SGleb Smirnoff .pr_sockaddr = ng_btsocket_rfcomm_sockaddr, 146*e7d02be1SGleb Smirnoff .pr_close = ng_btsocket_rfcomm_close, 147*e7d02be1SGleb Smirnoff }; 148*e7d02be1SGleb Smirnoff 149*e7d02be1SGleb Smirnoff /* Bluetooth SEQPACKET SCO sockets */ 150*e7d02be1SGleb Smirnoff static struct protosw ng_btsocket_sco_protosw = { 15148698a83SMaksim Yevmenkin .pr_type = SOCK_SEQPACKET, 15248698a83SMaksim Yevmenkin .pr_protocol = BLUETOOTH_PROTO_SCO, 15348698a83SMaksim Yevmenkin .pr_flags = PR_ATOMIC|PR_CONNREQUIRED, 15448698a83SMaksim Yevmenkin .pr_ctloutput = ng_btsocket_sco_ctloutput, 155*e7d02be1SGleb Smirnoff .pr_abort = ng_btsocket_sco_abort, 156*e7d02be1SGleb Smirnoff .pr_accept = ng_btsocket_sco_accept, 157*e7d02be1SGleb Smirnoff .pr_attach = ng_btsocket_sco_attach, 158*e7d02be1SGleb Smirnoff .pr_bind = ng_btsocket_sco_bind, 159*e7d02be1SGleb Smirnoff .pr_connect = ng_btsocket_sco_connect, 160*e7d02be1SGleb Smirnoff .pr_control = ng_btsocket_sco_control, 161*e7d02be1SGleb Smirnoff .pr_detach = ng_btsocket_sco_detach, 162*e7d02be1SGleb Smirnoff .pr_disconnect = ng_btsocket_sco_disconnect, 163*e7d02be1SGleb Smirnoff .pr_listen = ng_btsocket_sco_listen, 164*e7d02be1SGleb Smirnoff .pr_peeraddr = ng_btsocket_sco_peeraddr, 165*e7d02be1SGleb Smirnoff .pr_send = ng_btsocket_sco_send, 166*e7d02be1SGleb Smirnoff .pr_sockaddr = ng_btsocket_sco_sockaddr, 167*e7d02be1SGleb Smirnoff .pr_close = ng_btsocket_sco_close, 168878ed226SJulian Elischer }; 1698dfea464SPedro F. Giffuni 170878ed226SJulian Elischer /* 171878ed226SJulian Elischer * BLUETOOTH domain 172878ed226SJulian Elischer */ 173878ed226SJulian Elischer 174d0728d71SRobert Watson static struct domain ng_btsocket_domain = { 175303989a2SRuslan Ermilov .dom_family = AF_BLUETOOTH, 176303989a2SRuslan Ermilov .dom_name = "bluetooth", 177*e7d02be1SGleb Smirnoff .dom_nprotosw = 5, 178*e7d02be1SGleb Smirnoff .dom_protosw = { 179*e7d02be1SGleb Smirnoff &ng_btsocket_hci_raw_protosw, 180*e7d02be1SGleb Smirnoff &ng_btsocket_l2cap_raw_protosw, 181*e7d02be1SGleb Smirnoff &ng_btsocket_l2cap_protosw, 182*e7d02be1SGleb Smirnoff &ng_btsocket_rfcomm_protosw, 183*e7d02be1SGleb Smirnoff &ng_btsocket_sco_protosw, 184*e7d02be1SGleb Smirnoff }, 185878ed226SJulian Elischer }; 186878ed226SJulian Elischer 187878ed226SJulian Elischer /* 188878ed226SJulian Elischer * Socket sysctl tree 189878ed226SJulian Elischer */ 190878ed226SJulian Elischer 1917029da5cSPawel Biernacki SYSCTL_NODE(_net_bluetooth_hci, OID_AUTO, sockets, 1927029da5cSPawel Biernacki CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 1937029da5cSPawel Biernacki "Bluetooth HCI sockets family"); 1947029da5cSPawel Biernacki SYSCTL_NODE(_net_bluetooth_l2cap, OID_AUTO, sockets, 1957029da5cSPawel Biernacki CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 1967029da5cSPawel Biernacki "Bluetooth L2CAP sockets family"); 1977029da5cSPawel Biernacki SYSCTL_NODE(_net_bluetooth_rfcomm, OID_AUTO, sockets, 1987029da5cSPawel Biernacki CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 1997029da5cSPawel Biernacki "Bluetooth RFCOMM sockets family"); 2007029da5cSPawel Biernacki SYSCTL_NODE(_net_bluetooth_sco, OID_AUTO, sockets, 2017029da5cSPawel Biernacki CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 2027029da5cSPawel Biernacki "Bluetooth SCO sockets family"); 203878ed226SJulian Elischer 204878ed226SJulian Elischer /* 205878ed226SJulian Elischer * Module 206878ed226SJulian Elischer */ 207878ed226SJulian Elischer 208878ed226SJulian Elischer static moduledata_t ng_btsocket_mod = { 209878ed226SJulian Elischer "ng_btsocket", 210878ed226SJulian Elischer ng_btsocket_modevent, 211878ed226SJulian Elischer NULL 212878ed226SJulian Elischer }; 213878ed226SJulian Elischer 2144f240affSMax Laier DECLARE_MODULE(ng_btsocket, ng_btsocket_mod, SI_SUB_PROTO_DOMAIN, 2154f240affSMax Laier SI_ORDER_ANY); 216878ed226SJulian Elischer MODULE_VERSION(ng_btsocket, NG_BLUETOOTH_VERSION); 217878ed226SJulian Elischer MODULE_DEPEND(ng_btsocket, ng_bluetooth, NG_BLUETOOTH_VERSION, 218878ed226SJulian Elischer NG_BLUETOOTH_VERSION, NG_BLUETOOTH_VERSION); 219878ed226SJulian Elischer MODULE_DEPEND(ng_btsocket, netgraph, NG_ABI_VERSION, 220878ed226SJulian Elischer NG_ABI_VERSION, NG_ABI_VERSION); 221878ed226SJulian Elischer 222878ed226SJulian Elischer /* 223878ed226SJulian Elischer * Handle loading and unloading for this node type. 224878ed226SJulian Elischer * This is to handle auxiliary linkages (e.g protocol domain addition). 225878ed226SJulian Elischer */ 226878ed226SJulian Elischer 227878ed226SJulian Elischer static int 228878ed226SJulian Elischer ng_btsocket_modevent(module_t mod, int event, void *data) 229878ed226SJulian Elischer { 230878ed226SJulian Elischer int error = 0; 231878ed226SJulian Elischer 232878ed226SJulian Elischer switch (event) { 233878ed226SJulian Elischer case MOD_LOAD: 234878ed226SJulian Elischer break; 235878ed226SJulian Elischer 236878ed226SJulian Elischer case MOD_UNLOAD: 237878ed226SJulian Elischer /* XXX can't unload protocol domain yet */ 238878ed226SJulian Elischer error = EBUSY; 239878ed226SJulian Elischer break; 240878ed226SJulian Elischer 241878ed226SJulian Elischer default: 242878ed226SJulian Elischer error = EOPNOTSUPP; 243878ed226SJulian Elischer break; 244878ed226SJulian Elischer } 245878ed226SJulian Elischer 246878ed226SJulian Elischer return (error); 247878ed226SJulian Elischer } /* ng_btsocket_modevent */ 248878ed226SJulian Elischer 249644ca084SGleb Smirnoff DOMAIN_SET(ng_btsocket_); 250