xref: /openbmc/linux/net/bluetooth/hci_sock.c (revision ac71494934c475e3f51e5e3e64a12f57618d82a4)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds    BlueZ - Bluetooth protocol stack for Linux
31da177e4SLinus Torvalds    Copyright (C) 2000-2001 Qualcomm Incorporated
41da177e4SLinus Torvalds 
51da177e4SLinus Torvalds    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
61da177e4SLinus Torvalds 
71da177e4SLinus Torvalds    This program is free software; you can redistribute it and/or modify
81da177e4SLinus Torvalds    it under the terms of the GNU General Public License version 2 as
91da177e4SLinus Torvalds    published by the Free Software Foundation;
101da177e4SLinus Torvalds 
111da177e4SLinus Torvalds    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
121da177e4SLinus Torvalds    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
131da177e4SLinus Torvalds    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
141da177e4SLinus Torvalds    IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
151da177e4SLinus Torvalds    CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
161da177e4SLinus Torvalds    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
171da177e4SLinus Torvalds    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
181da177e4SLinus Torvalds    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
191da177e4SLinus Torvalds 
201da177e4SLinus Torvalds    ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
211da177e4SLinus Torvalds    COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
221da177e4SLinus Torvalds    SOFTWARE IS DISCLAIMED.
231da177e4SLinus Torvalds */
241da177e4SLinus Torvalds 
251da177e4SLinus Torvalds /* Bluetooth HCI sockets. */
261da177e4SLinus Torvalds 
278c520a59SGustavo Padovan #include <linux/export.h>
281da177e4SLinus Torvalds #include <asm/unaligned.h>
29dd31506dSMarcel Holtmann #include <generated/compile.h>
30dd31506dSMarcel Holtmann #include <generated/utsrelease.h>
311da177e4SLinus Torvalds 
321da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h>
331da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h>
34cd82e61cSMarcel Holtmann #include <net/bluetooth/hci_mon.h>
35fa4335d7SJohan Hedberg #include <net/bluetooth/mgmt.h>
36fa4335d7SJohan Hedberg 
37fa4335d7SJohan Hedberg #include "mgmt_util.h"
381da177e4SLinus Torvalds 
39801c1e8dSJohan Hedberg static LIST_HEAD(mgmt_chan_list);
40801c1e8dSJohan Hedberg static DEFINE_MUTEX(mgmt_chan_list_lock);
41801c1e8dSJohan Hedberg 
42cd82e61cSMarcel Holtmann static atomic_t monitor_promisc = ATOMIC_INIT(0);
43cd82e61cSMarcel Holtmann 
441da177e4SLinus Torvalds /* ----- HCI socket interface ----- */
451da177e4SLinus Torvalds 
46863def58SMarcel Holtmann /* Socket info */
47863def58SMarcel Holtmann #define hci_pi(sk) ((struct hci_pinfo *) sk)
48863def58SMarcel Holtmann 
49863def58SMarcel Holtmann struct hci_pinfo {
50863def58SMarcel Holtmann 	struct bt_sock    bt;
51863def58SMarcel Holtmann 	struct hci_dev    *hdev;
52863def58SMarcel Holtmann 	struct hci_filter filter;
53863def58SMarcel Holtmann 	__u32             cmsg_mask;
54863def58SMarcel Holtmann 	unsigned short    channel;
556befc644SMarcel Holtmann 	unsigned long     flags;
56863def58SMarcel Holtmann };
57863def58SMarcel Holtmann 
586befc644SMarcel Holtmann void hci_sock_set_flag(struct sock *sk, int nr)
596befc644SMarcel Holtmann {
606befc644SMarcel Holtmann 	set_bit(nr, &hci_pi(sk)->flags);
616befc644SMarcel Holtmann }
626befc644SMarcel Holtmann 
636befc644SMarcel Holtmann void hci_sock_clear_flag(struct sock *sk, int nr)
646befc644SMarcel Holtmann {
656befc644SMarcel Holtmann 	clear_bit(nr, &hci_pi(sk)->flags);
666befc644SMarcel Holtmann }
676befc644SMarcel Holtmann 
68c85be545SMarcel Holtmann int hci_sock_test_flag(struct sock *sk, int nr)
69c85be545SMarcel Holtmann {
70c85be545SMarcel Holtmann 	return test_bit(nr, &hci_pi(sk)->flags);
71c85be545SMarcel Holtmann }
72c85be545SMarcel Holtmann 
73d0f172b1SJohan Hedberg unsigned short hci_sock_get_channel(struct sock *sk)
74d0f172b1SJohan Hedberg {
75d0f172b1SJohan Hedberg 	return hci_pi(sk)->channel;
76d0f172b1SJohan Hedberg }
77d0f172b1SJohan Hedberg 
789391976aSJiri Slaby static inline int hci_test_bit(int nr, const void *addr)
791da177e4SLinus Torvalds {
809391976aSJiri Slaby 	return *((const __u32 *) addr + (nr >> 5)) & ((__u32) 1 << (nr & 31));
811da177e4SLinus Torvalds }
821da177e4SLinus Torvalds 
831da177e4SLinus Torvalds /* Security filter */
843ad254f7SMarcel Holtmann #define HCI_SFLT_MAX_OGF  5
853ad254f7SMarcel Holtmann 
863ad254f7SMarcel Holtmann struct hci_sec_filter {
873ad254f7SMarcel Holtmann 	__u32 type_mask;
883ad254f7SMarcel Holtmann 	__u32 event_mask[2];
893ad254f7SMarcel Holtmann 	__u32 ocf_mask[HCI_SFLT_MAX_OGF + 1][4];
903ad254f7SMarcel Holtmann };
913ad254f7SMarcel Holtmann 
927e67c112SMarcel Holtmann static const struct hci_sec_filter hci_sec_filter = {
931da177e4SLinus Torvalds 	/* Packet types */
941da177e4SLinus Torvalds 	0x10,
951da177e4SLinus Torvalds 	/* Events */
96dd7f5527SMarcel Holtmann 	{ 0x1000d9fe, 0x0000b00c },
971da177e4SLinus Torvalds 	/* Commands */
981da177e4SLinus Torvalds 	{
991da177e4SLinus Torvalds 		{ 0x0 },
1001da177e4SLinus Torvalds 		/* OGF_LINK_CTL */
1017c631a67SMarcel Holtmann 		{ 0xbe000006, 0x00000001, 0x00000000, 0x00 },
1021da177e4SLinus Torvalds 		/* OGF_LINK_POLICY */
1037c631a67SMarcel Holtmann 		{ 0x00005200, 0x00000000, 0x00000000, 0x00 },
1041da177e4SLinus Torvalds 		/* OGF_HOST_CTL */
1057c631a67SMarcel Holtmann 		{ 0xaab00200, 0x2b402aaa, 0x05220154, 0x00 },
1061da177e4SLinus Torvalds 		/* OGF_INFO_PARAM */
1077c631a67SMarcel Holtmann 		{ 0x000002be, 0x00000000, 0x00000000, 0x00 },
1081da177e4SLinus Torvalds 		/* OGF_STATUS_PARAM */
1097c631a67SMarcel Holtmann 		{ 0x000000ea, 0x00000000, 0x00000000, 0x00 }
1101da177e4SLinus Torvalds 	}
1111da177e4SLinus Torvalds };
1121da177e4SLinus Torvalds 
1131da177e4SLinus Torvalds static struct bt_sock_list hci_sk_list = {
114d5fb2962SRobert P. J. Day 	.lock = __RW_LOCK_UNLOCKED(hci_sk_list.lock)
1151da177e4SLinus Torvalds };
1161da177e4SLinus Torvalds 
117f81fe64fSMarcel Holtmann static bool is_filtered_packet(struct sock *sk, struct sk_buff *skb)
118f81fe64fSMarcel Holtmann {
119f81fe64fSMarcel Holtmann 	struct hci_filter *flt;
120f81fe64fSMarcel Holtmann 	int flt_type, flt_event;
121f81fe64fSMarcel Holtmann 
122f81fe64fSMarcel Holtmann 	/* Apply filter */
123f81fe64fSMarcel Holtmann 	flt = &hci_pi(sk)->filter;
124f81fe64fSMarcel Holtmann 
125d79f34e3SMarcel Holtmann 	flt_type = hci_skb_pkt_type(skb) & HCI_FLT_TYPE_BITS;
126f81fe64fSMarcel Holtmann 
127f81fe64fSMarcel Holtmann 	if (!test_bit(flt_type, &flt->type_mask))
128f81fe64fSMarcel Holtmann 		return true;
129f81fe64fSMarcel Holtmann 
130f81fe64fSMarcel Holtmann 	/* Extra filter for event packets only */
131d79f34e3SMarcel Holtmann 	if (hci_skb_pkt_type(skb) != HCI_EVENT_PKT)
132f81fe64fSMarcel Holtmann 		return false;
133f81fe64fSMarcel Holtmann 
134f81fe64fSMarcel Holtmann 	flt_event = (*(__u8 *)skb->data & HCI_FLT_EVENT_BITS);
135f81fe64fSMarcel Holtmann 
136f81fe64fSMarcel Holtmann 	if (!hci_test_bit(flt_event, &flt->event_mask))
137f81fe64fSMarcel Holtmann 		return true;
138f81fe64fSMarcel Holtmann 
139f81fe64fSMarcel Holtmann 	/* Check filter only when opcode is set */
140f81fe64fSMarcel Holtmann 	if (!flt->opcode)
141f81fe64fSMarcel Holtmann 		return false;
142f81fe64fSMarcel Holtmann 
143f81fe64fSMarcel Holtmann 	if (flt_event == HCI_EV_CMD_COMPLETE &&
144f81fe64fSMarcel Holtmann 	    flt->opcode != get_unaligned((__le16 *)(skb->data + 3)))
145f81fe64fSMarcel Holtmann 		return true;
146f81fe64fSMarcel Holtmann 
147f81fe64fSMarcel Holtmann 	if (flt_event == HCI_EV_CMD_STATUS &&
148f81fe64fSMarcel Holtmann 	    flt->opcode != get_unaligned((__le16 *)(skb->data + 4)))
149f81fe64fSMarcel Holtmann 		return true;
150f81fe64fSMarcel Holtmann 
151f81fe64fSMarcel Holtmann 	return false;
152f81fe64fSMarcel Holtmann }
153f81fe64fSMarcel Holtmann 
1541da177e4SLinus Torvalds /* Send frame to RAW socket */
155470fe1b5SMarcel Holtmann void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
1561da177e4SLinus Torvalds {
1571da177e4SLinus Torvalds 	struct sock *sk;
158e0edf373SMarcel Holtmann 	struct sk_buff *skb_copy = NULL;
1591da177e4SLinus Torvalds 
1601da177e4SLinus Torvalds 	BT_DBG("hdev %p len %d", hdev, skb->len);
1611da177e4SLinus Torvalds 
1621da177e4SLinus Torvalds 	read_lock(&hci_sk_list.lock);
163470fe1b5SMarcel Holtmann 
164b67bfe0dSSasha Levin 	sk_for_each(sk, &hci_sk_list.head) {
1651da177e4SLinus Torvalds 		struct sk_buff *nskb;
1661da177e4SLinus Torvalds 
1671da177e4SLinus Torvalds 		if (sk->sk_state != BT_BOUND || hci_pi(sk)->hdev != hdev)
1681da177e4SLinus Torvalds 			continue;
1691da177e4SLinus Torvalds 
1701da177e4SLinus Torvalds 		/* Don't send frame to the socket it came from */
1711da177e4SLinus Torvalds 		if (skb->sk == sk)
1721da177e4SLinus Torvalds 			continue;
1731da177e4SLinus Torvalds 
17423500189SMarcel Holtmann 		if (hci_pi(sk)->channel == HCI_CHANNEL_RAW) {
175d79f34e3SMarcel Holtmann 			if (hci_skb_pkt_type(skb) != HCI_COMMAND_PKT &&
176d79f34e3SMarcel Holtmann 			    hci_skb_pkt_type(skb) != HCI_EVENT_PKT &&
177d79f34e3SMarcel Holtmann 			    hci_skb_pkt_type(skb) != HCI_ACLDATA_PKT &&
178d79f34e3SMarcel Holtmann 			    hci_skb_pkt_type(skb) != HCI_SCODATA_PKT)
179bb77543eSMarcel Holtmann 				continue;
180f81fe64fSMarcel Holtmann 			if (is_filtered_packet(sk, skb))
1811da177e4SLinus Torvalds 				continue;
18223500189SMarcel Holtmann 		} else if (hci_pi(sk)->channel == HCI_CHANNEL_USER) {
18323500189SMarcel Holtmann 			if (!bt_cb(skb)->incoming)
18423500189SMarcel Holtmann 				continue;
185d79f34e3SMarcel Holtmann 			if (hci_skb_pkt_type(skb) != HCI_EVENT_PKT &&
186d79f34e3SMarcel Holtmann 			    hci_skb_pkt_type(skb) != HCI_ACLDATA_PKT &&
187d79f34e3SMarcel Holtmann 			    hci_skb_pkt_type(skb) != HCI_SCODATA_PKT)
18823500189SMarcel Holtmann 				continue;
18923500189SMarcel Holtmann 		} else {
19023500189SMarcel Holtmann 			/* Don't send frame to other channel types */
19123500189SMarcel Holtmann 			continue;
19223500189SMarcel Holtmann 		}
1931da177e4SLinus Torvalds 
194e0edf373SMarcel Holtmann 		if (!skb_copy) {
195e0edf373SMarcel Holtmann 			/* Create a private copy with headroom */
196bad93e9dSOctavian Purdila 			skb_copy = __pskb_copy_fclone(skb, 1, GFP_ATOMIC, true);
197e0edf373SMarcel Holtmann 			if (!skb_copy)
1981da177e4SLinus Torvalds 				continue;
1991da177e4SLinus Torvalds 
2001da177e4SLinus Torvalds 			/* Put type byte before the data */
201d79f34e3SMarcel Holtmann 			memcpy(skb_push(skb_copy, 1), &hci_skb_pkt_type(skb), 1);
202e0edf373SMarcel Holtmann 		}
203e0edf373SMarcel Holtmann 
204e0edf373SMarcel Holtmann 		nskb = skb_clone(skb_copy, GFP_ATOMIC);
205e0edf373SMarcel Holtmann 		if (!nskb)
206e0edf373SMarcel Holtmann 			continue;
2071da177e4SLinus Torvalds 
2081da177e4SLinus Torvalds 		if (sock_queue_rcv_skb(sk, nskb))
2091da177e4SLinus Torvalds 			kfree_skb(nskb);
2101da177e4SLinus Torvalds 	}
211470fe1b5SMarcel Holtmann 
212470fe1b5SMarcel Holtmann 	read_unlock(&hci_sk_list.lock);
213e0edf373SMarcel Holtmann 
214e0edf373SMarcel Holtmann 	kfree_skb(skb_copy);
215470fe1b5SMarcel Holtmann }
216470fe1b5SMarcel Holtmann 
2177129069eSJohan Hedberg /* Send frame to sockets with specific channel */
2187129069eSJohan Hedberg void hci_send_to_channel(unsigned short channel, struct sk_buff *skb,
219c08b1a1dSMarcel Holtmann 			 int flag, struct sock *skip_sk)
220470fe1b5SMarcel Holtmann {
221470fe1b5SMarcel Holtmann 	struct sock *sk;
222470fe1b5SMarcel Holtmann 
2237129069eSJohan Hedberg 	BT_DBG("channel %u len %d", channel, skb->len);
224470fe1b5SMarcel Holtmann 
225470fe1b5SMarcel Holtmann 	read_lock(&hci_sk_list.lock);
226470fe1b5SMarcel Holtmann 
227b67bfe0dSSasha Levin 	sk_for_each(sk, &hci_sk_list.head) {
228470fe1b5SMarcel Holtmann 		struct sk_buff *nskb;
229470fe1b5SMarcel Holtmann 
230c08b1a1dSMarcel Holtmann 		/* Ignore socket without the flag set */
231c85be545SMarcel Holtmann 		if (!hci_sock_test_flag(sk, flag))
232c08b1a1dSMarcel Holtmann 			continue;
233c08b1a1dSMarcel Holtmann 
234470fe1b5SMarcel Holtmann 		/* Skip the original socket */
235470fe1b5SMarcel Holtmann 		if (sk == skip_sk)
236470fe1b5SMarcel Holtmann 			continue;
237470fe1b5SMarcel Holtmann 
238470fe1b5SMarcel Holtmann 		if (sk->sk_state != BT_BOUND)
239470fe1b5SMarcel Holtmann 			continue;
240470fe1b5SMarcel Holtmann 
2417129069eSJohan Hedberg 		if (hci_pi(sk)->channel != channel)
242d7f72f61SMarcel Holtmann 			continue;
243d7f72f61SMarcel Holtmann 
244d7f72f61SMarcel Holtmann 		nskb = skb_clone(skb, GFP_ATOMIC);
245d7f72f61SMarcel Holtmann 		if (!nskb)
246d7f72f61SMarcel Holtmann 			continue;
247d7f72f61SMarcel Holtmann 
248d7f72f61SMarcel Holtmann 		if (sock_queue_rcv_skb(sk, nskb))
249d7f72f61SMarcel Holtmann 			kfree_skb(nskb);
250d7f72f61SMarcel Holtmann 	}
251d7f72f61SMarcel Holtmann 
252d7f72f61SMarcel Holtmann 	read_unlock(&hci_sk_list.lock);
253d7f72f61SMarcel Holtmann }
254d7f72f61SMarcel Holtmann 
255cd82e61cSMarcel Holtmann /* Send frame to monitor socket */
256cd82e61cSMarcel Holtmann void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb)
257cd82e61cSMarcel Holtmann {
258cd82e61cSMarcel Holtmann 	struct sk_buff *skb_copy = NULL;
2592b531294SMarcel Holtmann 	struct hci_mon_hdr *hdr;
260cd82e61cSMarcel Holtmann 	__le16 opcode;
261cd82e61cSMarcel Holtmann 
262cd82e61cSMarcel Holtmann 	if (!atomic_read(&monitor_promisc))
263cd82e61cSMarcel Holtmann 		return;
264cd82e61cSMarcel Holtmann 
265cd82e61cSMarcel Holtmann 	BT_DBG("hdev %p len %d", hdev, skb->len);
266cd82e61cSMarcel Holtmann 
267d79f34e3SMarcel Holtmann 	switch (hci_skb_pkt_type(skb)) {
268cd82e61cSMarcel Holtmann 	case HCI_COMMAND_PKT:
269dcf4adbfSJoe Perches 		opcode = cpu_to_le16(HCI_MON_COMMAND_PKT);
270cd82e61cSMarcel Holtmann 		break;
271cd82e61cSMarcel Holtmann 	case HCI_EVENT_PKT:
272dcf4adbfSJoe Perches 		opcode = cpu_to_le16(HCI_MON_EVENT_PKT);
273cd82e61cSMarcel Holtmann 		break;
274cd82e61cSMarcel Holtmann 	case HCI_ACLDATA_PKT:
275cd82e61cSMarcel Holtmann 		if (bt_cb(skb)->incoming)
276dcf4adbfSJoe Perches 			opcode = cpu_to_le16(HCI_MON_ACL_RX_PKT);
277cd82e61cSMarcel Holtmann 		else
278dcf4adbfSJoe Perches 			opcode = cpu_to_le16(HCI_MON_ACL_TX_PKT);
279cd82e61cSMarcel Holtmann 		break;
280cd82e61cSMarcel Holtmann 	case HCI_SCODATA_PKT:
281cd82e61cSMarcel Holtmann 		if (bt_cb(skb)->incoming)
282dcf4adbfSJoe Perches 			opcode = cpu_to_le16(HCI_MON_SCO_RX_PKT);
283cd82e61cSMarcel Holtmann 		else
284dcf4adbfSJoe Perches 			opcode = cpu_to_le16(HCI_MON_SCO_TX_PKT);
285cd82e61cSMarcel Holtmann 		break;
286e875ff84SMarcel Holtmann 	case HCI_DIAG_PKT:
287e875ff84SMarcel Holtmann 		opcode = cpu_to_le16(HCI_MON_VENDOR_DIAG);
288e875ff84SMarcel Holtmann 		break;
289cd82e61cSMarcel Holtmann 	default:
290cd82e61cSMarcel Holtmann 		return;
291cd82e61cSMarcel Holtmann 	}
292cd82e61cSMarcel Holtmann 
2932b531294SMarcel Holtmann 	/* Create a private copy with headroom */
2942b531294SMarcel Holtmann 	skb_copy = __pskb_copy_fclone(skb, HCI_MON_HDR_SIZE, GFP_ATOMIC, true);
2952b531294SMarcel Holtmann 	if (!skb_copy)
2962b531294SMarcel Holtmann 		return;
2972b531294SMarcel Holtmann 
2982b531294SMarcel Holtmann 	/* Put header before the data */
2992b531294SMarcel Holtmann 	hdr = (void *)skb_push(skb_copy, HCI_MON_HDR_SIZE);
3002b531294SMarcel Holtmann 	hdr->opcode = opcode;
3012b531294SMarcel Holtmann 	hdr->index = cpu_to_le16(hdev->id);
3022b531294SMarcel Holtmann 	hdr->len = cpu_to_le16(skb->len);
3032b531294SMarcel Holtmann 
304c08b1a1dSMarcel Holtmann 	hci_send_to_channel(HCI_CHANNEL_MONITOR, skb_copy,
305c08b1a1dSMarcel Holtmann 			    HCI_SOCK_TRUSTED, NULL);
306cd82e61cSMarcel Holtmann 	kfree_skb(skb_copy);
307cd82e61cSMarcel Holtmann }
308cd82e61cSMarcel Holtmann 
309cd82e61cSMarcel Holtmann static struct sk_buff *create_monitor_event(struct hci_dev *hdev, int event)
310cd82e61cSMarcel Holtmann {
311cd82e61cSMarcel Holtmann 	struct hci_mon_hdr *hdr;
312cd82e61cSMarcel Holtmann 	struct hci_mon_new_index *ni;
3136c566dd5SMarcel Holtmann 	struct hci_mon_index_info *ii;
314cd82e61cSMarcel Holtmann 	struct sk_buff *skb;
315cd82e61cSMarcel Holtmann 	__le16 opcode;
316cd82e61cSMarcel Holtmann 
317cd82e61cSMarcel Holtmann 	switch (event) {
318cd82e61cSMarcel Holtmann 	case HCI_DEV_REG:
319cd82e61cSMarcel Holtmann 		skb = bt_skb_alloc(HCI_MON_NEW_INDEX_SIZE, GFP_ATOMIC);
320cd82e61cSMarcel Holtmann 		if (!skb)
321cd82e61cSMarcel Holtmann 			return NULL;
322cd82e61cSMarcel Holtmann 
323cd82e61cSMarcel Holtmann 		ni = (void *)skb_put(skb, HCI_MON_NEW_INDEX_SIZE);
324cd82e61cSMarcel Holtmann 		ni->type = hdev->dev_type;
325cd82e61cSMarcel Holtmann 		ni->bus = hdev->bus;
326cd82e61cSMarcel Holtmann 		bacpy(&ni->bdaddr, &hdev->bdaddr);
327cd82e61cSMarcel Holtmann 		memcpy(ni->name, hdev->name, 8);
328cd82e61cSMarcel Holtmann 
329dcf4adbfSJoe Perches 		opcode = cpu_to_le16(HCI_MON_NEW_INDEX);
330cd82e61cSMarcel Holtmann 		break;
331cd82e61cSMarcel Holtmann 
332cd82e61cSMarcel Holtmann 	case HCI_DEV_UNREG:
333cd82e61cSMarcel Holtmann 		skb = bt_skb_alloc(0, GFP_ATOMIC);
334cd82e61cSMarcel Holtmann 		if (!skb)
335cd82e61cSMarcel Holtmann 			return NULL;
336cd82e61cSMarcel Holtmann 
337dcf4adbfSJoe Perches 		opcode = cpu_to_le16(HCI_MON_DEL_INDEX);
338cd82e61cSMarcel Holtmann 		break;
339cd82e61cSMarcel Holtmann 
340e131d74aSMarcel Holtmann 	case HCI_DEV_SETUP:
341e131d74aSMarcel Holtmann 		if (hdev->manufacturer == 0xffff)
342e131d74aSMarcel Holtmann 			return NULL;
343e131d74aSMarcel Holtmann 
344e131d74aSMarcel Holtmann 		/* fall through */
345e131d74aSMarcel Holtmann 
3466c566dd5SMarcel Holtmann 	case HCI_DEV_UP:
3476c566dd5SMarcel Holtmann 		skb = bt_skb_alloc(HCI_MON_INDEX_INFO_SIZE, GFP_ATOMIC);
3486c566dd5SMarcel Holtmann 		if (!skb)
3496c566dd5SMarcel Holtmann 			return NULL;
3506c566dd5SMarcel Holtmann 
3516c566dd5SMarcel Holtmann 		ii = (void *)skb_put(skb, HCI_MON_INDEX_INFO_SIZE);
3526c566dd5SMarcel Holtmann 		bacpy(&ii->bdaddr, &hdev->bdaddr);
3536c566dd5SMarcel Holtmann 		ii->manufacturer = cpu_to_le16(hdev->manufacturer);
3546c566dd5SMarcel Holtmann 
3556c566dd5SMarcel Holtmann 		opcode = cpu_to_le16(HCI_MON_INDEX_INFO);
3566c566dd5SMarcel Holtmann 		break;
3576c566dd5SMarcel Holtmann 
35822db3cbcSMarcel Holtmann 	case HCI_DEV_OPEN:
35922db3cbcSMarcel Holtmann 		skb = bt_skb_alloc(0, GFP_ATOMIC);
36022db3cbcSMarcel Holtmann 		if (!skb)
36122db3cbcSMarcel Holtmann 			return NULL;
36222db3cbcSMarcel Holtmann 
36322db3cbcSMarcel Holtmann 		opcode = cpu_to_le16(HCI_MON_OPEN_INDEX);
36422db3cbcSMarcel Holtmann 		break;
36522db3cbcSMarcel Holtmann 
36622db3cbcSMarcel Holtmann 	case HCI_DEV_CLOSE:
36722db3cbcSMarcel Holtmann 		skb = bt_skb_alloc(0, GFP_ATOMIC);
36822db3cbcSMarcel Holtmann 		if (!skb)
36922db3cbcSMarcel Holtmann 			return NULL;
37022db3cbcSMarcel Holtmann 
37122db3cbcSMarcel Holtmann 		opcode = cpu_to_le16(HCI_MON_CLOSE_INDEX);
37222db3cbcSMarcel Holtmann 		break;
37322db3cbcSMarcel Holtmann 
374cd82e61cSMarcel Holtmann 	default:
375cd82e61cSMarcel Holtmann 		return NULL;
376cd82e61cSMarcel Holtmann 	}
377cd82e61cSMarcel Holtmann 
378cd82e61cSMarcel Holtmann 	__net_timestamp(skb);
379cd82e61cSMarcel Holtmann 
380cd82e61cSMarcel Holtmann 	hdr = (void *)skb_push(skb, HCI_MON_HDR_SIZE);
381cd82e61cSMarcel Holtmann 	hdr->opcode = opcode;
382cd82e61cSMarcel Holtmann 	hdr->index = cpu_to_le16(hdev->id);
383cd82e61cSMarcel Holtmann 	hdr->len = cpu_to_le16(skb->len - HCI_MON_HDR_SIZE);
384cd82e61cSMarcel Holtmann 
385cd82e61cSMarcel Holtmann 	return skb;
386cd82e61cSMarcel Holtmann }
387cd82e61cSMarcel Holtmann 
388dd31506dSMarcel Holtmann static void send_monitor_note(struct sock *sk, const char *text)
389dd31506dSMarcel Holtmann {
390dd31506dSMarcel Holtmann 	size_t len = strlen(text);
391dd31506dSMarcel Holtmann 	struct hci_mon_hdr *hdr;
392dd31506dSMarcel Holtmann 	struct sk_buff *skb;
393dd31506dSMarcel Holtmann 
394dd31506dSMarcel Holtmann 	skb = bt_skb_alloc(len + 1, GFP_ATOMIC);
395dd31506dSMarcel Holtmann 	if (!skb)
396dd31506dSMarcel Holtmann 		return;
397dd31506dSMarcel Holtmann 
398dd31506dSMarcel Holtmann 	strcpy(skb_put(skb, len + 1), text);
399dd31506dSMarcel Holtmann 
400dd31506dSMarcel Holtmann 	__net_timestamp(skb);
401dd31506dSMarcel Holtmann 
402dd31506dSMarcel Holtmann 	hdr = (void *)skb_push(skb, HCI_MON_HDR_SIZE);
403dd31506dSMarcel Holtmann 	hdr->opcode = cpu_to_le16(HCI_MON_SYSTEM_NOTE);
404dd31506dSMarcel Holtmann 	hdr->index = cpu_to_le16(HCI_DEV_NONE);
405dd31506dSMarcel Holtmann 	hdr->len = cpu_to_le16(skb->len - HCI_MON_HDR_SIZE);
406dd31506dSMarcel Holtmann 
407dd31506dSMarcel Holtmann 	if (sock_queue_rcv_skb(sk, skb))
408dd31506dSMarcel Holtmann 		kfree_skb(skb);
409dd31506dSMarcel Holtmann }
410dd31506dSMarcel Holtmann 
411cd82e61cSMarcel Holtmann static void send_monitor_replay(struct sock *sk)
412cd82e61cSMarcel Holtmann {
413cd82e61cSMarcel Holtmann 	struct hci_dev *hdev;
414cd82e61cSMarcel Holtmann 
415cd82e61cSMarcel Holtmann 	read_lock(&hci_dev_list_lock);
416cd82e61cSMarcel Holtmann 
417cd82e61cSMarcel Holtmann 	list_for_each_entry(hdev, &hci_dev_list, list) {
418cd82e61cSMarcel Holtmann 		struct sk_buff *skb;
419cd82e61cSMarcel Holtmann 
420cd82e61cSMarcel Holtmann 		skb = create_monitor_event(hdev, HCI_DEV_REG);
421cd82e61cSMarcel Holtmann 		if (!skb)
422cd82e61cSMarcel Holtmann 			continue;
423cd82e61cSMarcel Holtmann 
424cd82e61cSMarcel Holtmann 		if (sock_queue_rcv_skb(sk, skb))
425cd82e61cSMarcel Holtmann 			kfree_skb(skb);
42622db3cbcSMarcel Holtmann 
42722db3cbcSMarcel Holtmann 		if (!test_bit(HCI_RUNNING, &hdev->flags))
42822db3cbcSMarcel Holtmann 			continue;
42922db3cbcSMarcel Holtmann 
43022db3cbcSMarcel Holtmann 		skb = create_monitor_event(hdev, HCI_DEV_OPEN);
43122db3cbcSMarcel Holtmann 		if (!skb)
43222db3cbcSMarcel Holtmann 			continue;
43322db3cbcSMarcel Holtmann 
43422db3cbcSMarcel Holtmann 		if (sock_queue_rcv_skb(sk, skb))
43522db3cbcSMarcel Holtmann 			kfree_skb(skb);
4366c566dd5SMarcel Holtmann 
437e131d74aSMarcel Holtmann 		if (test_bit(HCI_UP, &hdev->flags))
4386c566dd5SMarcel Holtmann 			skb = create_monitor_event(hdev, HCI_DEV_UP);
439e131d74aSMarcel Holtmann 		else if (hci_dev_test_flag(hdev, HCI_SETUP))
440e131d74aSMarcel Holtmann 			skb = create_monitor_event(hdev, HCI_DEV_SETUP);
441e131d74aSMarcel Holtmann 		else
442e131d74aSMarcel Holtmann 			skb = NULL;
4436c566dd5SMarcel Holtmann 
444e131d74aSMarcel Holtmann 		if (skb) {
4456c566dd5SMarcel Holtmann 			if (sock_queue_rcv_skb(sk, skb))
4466c566dd5SMarcel Holtmann 				kfree_skb(skb);
447cd82e61cSMarcel Holtmann 		}
448e131d74aSMarcel Holtmann 	}
449cd82e61cSMarcel Holtmann 
450cd82e61cSMarcel Holtmann 	read_unlock(&hci_dev_list_lock);
451cd82e61cSMarcel Holtmann }
452cd82e61cSMarcel Holtmann 
453040030efSMarcel Holtmann /* Generate internal stack event */
454040030efSMarcel Holtmann static void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
455040030efSMarcel Holtmann {
456040030efSMarcel Holtmann 	struct hci_event_hdr *hdr;
457040030efSMarcel Holtmann 	struct hci_ev_stack_internal *ev;
458040030efSMarcel Holtmann 	struct sk_buff *skb;
459040030efSMarcel Holtmann 
460040030efSMarcel Holtmann 	skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
461040030efSMarcel Holtmann 	if (!skb)
462040030efSMarcel Holtmann 		return;
463040030efSMarcel Holtmann 
464040030efSMarcel Holtmann 	hdr = (void *)skb_put(skb, HCI_EVENT_HDR_SIZE);
465040030efSMarcel Holtmann 	hdr->evt  = HCI_EV_STACK_INTERNAL;
466040030efSMarcel Holtmann 	hdr->plen = sizeof(*ev) + dlen;
467040030efSMarcel Holtmann 
468040030efSMarcel Holtmann 	ev  = (void *)skb_put(skb, sizeof(*ev) + dlen);
469040030efSMarcel Holtmann 	ev->type = type;
470040030efSMarcel Holtmann 	memcpy(ev->data, data, dlen);
471040030efSMarcel Holtmann 
472040030efSMarcel Holtmann 	bt_cb(skb)->incoming = 1;
473040030efSMarcel Holtmann 	__net_timestamp(skb);
474040030efSMarcel Holtmann 
475d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_EVENT_PKT;
476040030efSMarcel Holtmann 	hci_send_to_sock(hdev, skb);
477040030efSMarcel Holtmann 	kfree_skb(skb);
478040030efSMarcel Holtmann }
479040030efSMarcel Holtmann 
480040030efSMarcel Holtmann void hci_sock_dev_event(struct hci_dev *hdev, int event)
481040030efSMarcel Holtmann {
482040030efSMarcel Holtmann 	BT_DBG("hdev %s event %d", hdev->name, event);
483040030efSMarcel Holtmann 
484cd82e61cSMarcel Holtmann 	if (atomic_read(&monitor_promisc)) {
485cd82e61cSMarcel Holtmann 		struct sk_buff *skb;
486cd82e61cSMarcel Holtmann 
487ed1b28a4SMarcel Holtmann 		/* Send event to monitor */
488cd82e61cSMarcel Holtmann 		skb = create_monitor_event(hdev, event);
489cd82e61cSMarcel Holtmann 		if (skb) {
490c08b1a1dSMarcel Holtmann 			hci_send_to_channel(HCI_CHANNEL_MONITOR, skb,
491c08b1a1dSMarcel Holtmann 					    HCI_SOCK_TRUSTED, NULL);
492cd82e61cSMarcel Holtmann 			kfree_skb(skb);
493cd82e61cSMarcel Holtmann 		}
494cd82e61cSMarcel Holtmann 	}
495cd82e61cSMarcel Holtmann 
496ed1b28a4SMarcel Holtmann 	if (event <= HCI_DEV_DOWN) {
497ed1b28a4SMarcel Holtmann 		struct hci_ev_si_device ev;
498ed1b28a4SMarcel Holtmann 
499040030efSMarcel Holtmann 		/* Send event to sockets */
500040030efSMarcel Holtmann 		ev.event  = event;
501040030efSMarcel Holtmann 		ev.dev_id = hdev->id;
502040030efSMarcel Holtmann 		hci_si_event(NULL, HCI_EV_SI_DEVICE, sizeof(ev), &ev);
503ed1b28a4SMarcel Holtmann 	}
504040030efSMarcel Holtmann 
505040030efSMarcel Holtmann 	if (event == HCI_DEV_UNREG) {
506040030efSMarcel Holtmann 		struct sock *sk;
507040030efSMarcel Holtmann 
508040030efSMarcel Holtmann 		/* Detach sockets from device */
509040030efSMarcel Holtmann 		read_lock(&hci_sk_list.lock);
510b67bfe0dSSasha Levin 		sk_for_each(sk, &hci_sk_list.head) {
511040030efSMarcel Holtmann 			bh_lock_sock_nested(sk);
512040030efSMarcel Holtmann 			if (hci_pi(sk)->hdev == hdev) {
513040030efSMarcel Holtmann 				hci_pi(sk)->hdev = NULL;
514040030efSMarcel Holtmann 				sk->sk_err = EPIPE;
515040030efSMarcel Holtmann 				sk->sk_state = BT_OPEN;
516040030efSMarcel Holtmann 				sk->sk_state_change(sk);
517040030efSMarcel Holtmann 
518040030efSMarcel Holtmann 				hci_dev_put(hdev);
519040030efSMarcel Holtmann 			}
520040030efSMarcel Holtmann 			bh_unlock_sock(sk);
521040030efSMarcel Holtmann 		}
522040030efSMarcel Holtmann 		read_unlock(&hci_sk_list.lock);
523040030efSMarcel Holtmann 	}
524040030efSMarcel Holtmann }
525040030efSMarcel Holtmann 
526801c1e8dSJohan Hedberg static struct hci_mgmt_chan *__hci_mgmt_chan_find(unsigned short channel)
527801c1e8dSJohan Hedberg {
528801c1e8dSJohan Hedberg 	struct hci_mgmt_chan *c;
529801c1e8dSJohan Hedberg 
530801c1e8dSJohan Hedberg 	list_for_each_entry(c, &mgmt_chan_list, list) {
531801c1e8dSJohan Hedberg 		if (c->channel == channel)
532801c1e8dSJohan Hedberg 			return c;
533801c1e8dSJohan Hedberg 	}
534801c1e8dSJohan Hedberg 
535801c1e8dSJohan Hedberg 	return NULL;
536801c1e8dSJohan Hedberg }
537801c1e8dSJohan Hedberg 
538801c1e8dSJohan Hedberg static struct hci_mgmt_chan *hci_mgmt_chan_find(unsigned short channel)
539801c1e8dSJohan Hedberg {
540801c1e8dSJohan Hedberg 	struct hci_mgmt_chan *c;
541801c1e8dSJohan Hedberg 
542801c1e8dSJohan Hedberg 	mutex_lock(&mgmt_chan_list_lock);
543801c1e8dSJohan Hedberg 	c = __hci_mgmt_chan_find(channel);
544801c1e8dSJohan Hedberg 	mutex_unlock(&mgmt_chan_list_lock);
545801c1e8dSJohan Hedberg 
546801c1e8dSJohan Hedberg 	return c;
547801c1e8dSJohan Hedberg }
548801c1e8dSJohan Hedberg 
549801c1e8dSJohan Hedberg int hci_mgmt_chan_register(struct hci_mgmt_chan *c)
550801c1e8dSJohan Hedberg {
551801c1e8dSJohan Hedberg 	if (c->channel < HCI_CHANNEL_CONTROL)
552801c1e8dSJohan Hedberg 		return -EINVAL;
553801c1e8dSJohan Hedberg 
554801c1e8dSJohan Hedberg 	mutex_lock(&mgmt_chan_list_lock);
555801c1e8dSJohan Hedberg 	if (__hci_mgmt_chan_find(c->channel)) {
556801c1e8dSJohan Hedberg 		mutex_unlock(&mgmt_chan_list_lock);
557801c1e8dSJohan Hedberg 		return -EALREADY;
558801c1e8dSJohan Hedberg 	}
559801c1e8dSJohan Hedberg 
560801c1e8dSJohan Hedberg 	list_add_tail(&c->list, &mgmt_chan_list);
561801c1e8dSJohan Hedberg 
562801c1e8dSJohan Hedberg 	mutex_unlock(&mgmt_chan_list_lock);
563801c1e8dSJohan Hedberg 
564801c1e8dSJohan Hedberg 	return 0;
565801c1e8dSJohan Hedberg }
566801c1e8dSJohan Hedberg EXPORT_SYMBOL(hci_mgmt_chan_register);
567801c1e8dSJohan Hedberg 
568801c1e8dSJohan Hedberg void hci_mgmt_chan_unregister(struct hci_mgmt_chan *c)
569801c1e8dSJohan Hedberg {
570801c1e8dSJohan Hedberg 	mutex_lock(&mgmt_chan_list_lock);
571801c1e8dSJohan Hedberg 	list_del(&c->list);
572801c1e8dSJohan Hedberg 	mutex_unlock(&mgmt_chan_list_lock);
573801c1e8dSJohan Hedberg }
574801c1e8dSJohan Hedberg EXPORT_SYMBOL(hci_mgmt_chan_unregister);
575801c1e8dSJohan Hedberg 
5761da177e4SLinus Torvalds static int hci_sock_release(struct socket *sock)
5771da177e4SLinus Torvalds {
5781da177e4SLinus Torvalds 	struct sock *sk = sock->sk;
5797b005bd3SMarcel Holtmann 	struct hci_dev *hdev;
5801da177e4SLinus Torvalds 
5811da177e4SLinus Torvalds 	BT_DBG("sock %p sk %p", sock, sk);
5821da177e4SLinus Torvalds 
5831da177e4SLinus Torvalds 	if (!sk)
5841da177e4SLinus Torvalds 		return 0;
5851da177e4SLinus Torvalds 
5867b005bd3SMarcel Holtmann 	hdev = hci_pi(sk)->hdev;
5877b005bd3SMarcel Holtmann 
588cd82e61cSMarcel Holtmann 	if (hci_pi(sk)->channel == HCI_CHANNEL_MONITOR)
589cd82e61cSMarcel Holtmann 		atomic_dec(&monitor_promisc);
590cd82e61cSMarcel Holtmann 
5911da177e4SLinus Torvalds 	bt_sock_unlink(&hci_sk_list, sk);
5921da177e4SLinus Torvalds 
5931da177e4SLinus Torvalds 	if (hdev) {
59423500189SMarcel Holtmann 		if (hci_pi(sk)->channel == HCI_CHANNEL_USER) {
5956b3cc1dbSSimon Fels 			/* When releasing an user channel exclusive access,
5966b3cc1dbSSimon Fels 			 * call hci_dev_do_close directly instead of calling
5976b3cc1dbSSimon Fels 			 * hci_dev_close to ensure the exclusive access will
5986b3cc1dbSSimon Fels 			 * be released and the controller brought back down.
5996b3cc1dbSSimon Fels 			 *
6006b3cc1dbSSimon Fels 			 * The checking of HCI_AUTO_OFF is not needed in this
6016b3cc1dbSSimon Fels 			 * case since it will have been cleared already when
6026b3cc1dbSSimon Fels 			 * opening the user channel.
6036b3cc1dbSSimon Fels 			 */
6046b3cc1dbSSimon Fels 			hci_dev_do_close(hdev);
6059380f9eaSLoic Poulain 			hci_dev_clear_flag(hdev, HCI_USER_CHANNEL);
6069380f9eaSLoic Poulain 			mgmt_index_added(hdev);
60723500189SMarcel Holtmann 		}
60823500189SMarcel Holtmann 
6091da177e4SLinus Torvalds 		atomic_dec(&hdev->promisc);
6101da177e4SLinus Torvalds 		hci_dev_put(hdev);
6111da177e4SLinus Torvalds 	}
6121da177e4SLinus Torvalds 
6131da177e4SLinus Torvalds 	sock_orphan(sk);
6141da177e4SLinus Torvalds 
6151da177e4SLinus Torvalds 	skb_queue_purge(&sk->sk_receive_queue);
6161da177e4SLinus Torvalds 	skb_queue_purge(&sk->sk_write_queue);
6171da177e4SLinus Torvalds 
6181da177e4SLinus Torvalds 	sock_put(sk);
6191da177e4SLinus Torvalds 	return 0;
6201da177e4SLinus Torvalds }
6211da177e4SLinus Torvalds 
622b2a66aadSAntti Julku static int hci_sock_blacklist_add(struct hci_dev *hdev, void __user *arg)
623f0358568SJohan Hedberg {
624f0358568SJohan Hedberg 	bdaddr_t bdaddr;
6255e762444SAntti Julku 	int err;
626f0358568SJohan Hedberg 
627f0358568SJohan Hedberg 	if (copy_from_user(&bdaddr, arg, sizeof(bdaddr)))
628f0358568SJohan Hedberg 		return -EFAULT;
629f0358568SJohan Hedberg 
63009fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
6315e762444SAntti Julku 
632dcc36c16SJohan Hedberg 	err = hci_bdaddr_list_add(&hdev->blacklist, &bdaddr, BDADDR_BREDR);
6335e762444SAntti Julku 
63409fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
6355e762444SAntti Julku 
6365e762444SAntti Julku 	return err;
637f0358568SJohan Hedberg }
638f0358568SJohan Hedberg 
639b2a66aadSAntti Julku static int hci_sock_blacklist_del(struct hci_dev *hdev, void __user *arg)
640f0358568SJohan Hedberg {
641f0358568SJohan Hedberg 	bdaddr_t bdaddr;
6425e762444SAntti Julku 	int err;
643f0358568SJohan Hedberg 
644f0358568SJohan Hedberg 	if (copy_from_user(&bdaddr, arg, sizeof(bdaddr)))
645f0358568SJohan Hedberg 		return -EFAULT;
646f0358568SJohan Hedberg 
64709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
6485e762444SAntti Julku 
649dcc36c16SJohan Hedberg 	err = hci_bdaddr_list_del(&hdev->blacklist, &bdaddr, BDADDR_BREDR);
6505e762444SAntti Julku 
65109fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
6525e762444SAntti Julku 
6535e762444SAntti Julku 	return err;
654f0358568SJohan Hedberg }
655f0358568SJohan Hedberg 
6561da177e4SLinus Torvalds /* Ioctls that require bound socket */
6576039aa73SGustavo Padovan static int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd,
6586039aa73SGustavo Padovan 				unsigned long arg)
6591da177e4SLinus Torvalds {
6601da177e4SLinus Torvalds 	struct hci_dev *hdev = hci_pi(sk)->hdev;
6611da177e4SLinus Torvalds 
6621da177e4SLinus Torvalds 	if (!hdev)
6631da177e4SLinus Torvalds 		return -EBADFD;
6641da177e4SLinus Torvalds 
665d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL))
6660736cfa8SMarcel Holtmann 		return -EBUSY;
6670736cfa8SMarcel Holtmann 
668d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
669fee746b0SMarcel Holtmann 		return -EOPNOTSUPP;
670fee746b0SMarcel Holtmann 
6715b69bef5SMarcel Holtmann 	if (hdev->dev_type != HCI_BREDR)
6725b69bef5SMarcel Holtmann 		return -EOPNOTSUPP;
6735b69bef5SMarcel Holtmann 
6741da177e4SLinus Torvalds 	switch (cmd) {
6751da177e4SLinus Torvalds 	case HCISETRAW:
6761da177e4SLinus Torvalds 		if (!capable(CAP_NET_ADMIN))
677bf5b30b8SZhao Hongjiang 			return -EPERM;
678db596681SMarcel Holtmann 		return -EOPNOTSUPP;
6791da177e4SLinus Torvalds 
6801da177e4SLinus Torvalds 	case HCIGETCONNINFO:
6811da177e4SLinus Torvalds 		return hci_get_conn_info(hdev, (void __user *)arg);
6821da177e4SLinus Torvalds 
68340be492fSMarcel Holtmann 	case HCIGETAUTHINFO:
68440be492fSMarcel Holtmann 		return hci_get_auth_info(hdev, (void __user *)arg);
68540be492fSMarcel Holtmann 
686f0358568SJohan Hedberg 	case HCIBLOCKADDR:
687f0358568SJohan Hedberg 		if (!capable(CAP_NET_ADMIN))
688bf5b30b8SZhao Hongjiang 			return -EPERM;
689b2a66aadSAntti Julku 		return hci_sock_blacklist_add(hdev, (void __user *)arg);
690f0358568SJohan Hedberg 
691f0358568SJohan Hedberg 	case HCIUNBLOCKADDR:
692f0358568SJohan Hedberg 		if (!capable(CAP_NET_ADMIN))
693bf5b30b8SZhao Hongjiang 			return -EPERM;
694b2a66aadSAntti Julku 		return hci_sock_blacklist_del(hdev, (void __user *)arg);
6950736cfa8SMarcel Holtmann 	}
696f0358568SJohan Hedberg 
697324d36edSMarcel Holtmann 	return -ENOIOCTLCMD;
6981da177e4SLinus Torvalds }
6991da177e4SLinus Torvalds 
7008fc9ced3SGustavo Padovan static int hci_sock_ioctl(struct socket *sock, unsigned int cmd,
7018fc9ced3SGustavo Padovan 			  unsigned long arg)
7021da177e4SLinus Torvalds {
7031da177e4SLinus Torvalds 	void __user *argp = (void __user *)arg;
7040736cfa8SMarcel Holtmann 	struct sock *sk = sock->sk;
7051da177e4SLinus Torvalds 	int err;
7061da177e4SLinus Torvalds 
7071da177e4SLinus Torvalds 	BT_DBG("cmd %x arg %lx", cmd, arg);
7081da177e4SLinus Torvalds 
709c1c4f956SMarcel Holtmann 	lock_sock(sk);
710c1c4f956SMarcel Holtmann 
711c1c4f956SMarcel Holtmann 	if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) {
712c1c4f956SMarcel Holtmann 		err = -EBADFD;
713c1c4f956SMarcel Holtmann 		goto done;
714c1c4f956SMarcel Holtmann 	}
715c1c4f956SMarcel Holtmann 
716c1c4f956SMarcel Holtmann 	release_sock(sk);
717c1c4f956SMarcel Holtmann 
7181da177e4SLinus Torvalds 	switch (cmd) {
7191da177e4SLinus Torvalds 	case HCIGETDEVLIST:
7201da177e4SLinus Torvalds 		return hci_get_dev_list(argp);
7211da177e4SLinus Torvalds 
7221da177e4SLinus Torvalds 	case HCIGETDEVINFO:
7231da177e4SLinus Torvalds 		return hci_get_dev_info(argp);
7241da177e4SLinus Torvalds 
7251da177e4SLinus Torvalds 	case HCIGETCONNLIST:
7261da177e4SLinus Torvalds 		return hci_get_conn_list(argp);
7271da177e4SLinus Torvalds 
7281da177e4SLinus Torvalds 	case HCIDEVUP:
7291da177e4SLinus Torvalds 		if (!capable(CAP_NET_ADMIN))
730bf5b30b8SZhao Hongjiang 			return -EPERM;
7311da177e4SLinus Torvalds 		return hci_dev_open(arg);
7321da177e4SLinus Torvalds 
7331da177e4SLinus Torvalds 	case HCIDEVDOWN:
7341da177e4SLinus Torvalds 		if (!capable(CAP_NET_ADMIN))
735bf5b30b8SZhao Hongjiang 			return -EPERM;
7361da177e4SLinus Torvalds 		return hci_dev_close(arg);
7371da177e4SLinus Torvalds 
7381da177e4SLinus Torvalds 	case HCIDEVRESET:
7391da177e4SLinus Torvalds 		if (!capable(CAP_NET_ADMIN))
740bf5b30b8SZhao Hongjiang 			return -EPERM;
7411da177e4SLinus Torvalds 		return hci_dev_reset(arg);
7421da177e4SLinus Torvalds 
7431da177e4SLinus Torvalds 	case HCIDEVRESTAT:
7441da177e4SLinus Torvalds 		if (!capable(CAP_NET_ADMIN))
745bf5b30b8SZhao Hongjiang 			return -EPERM;
7461da177e4SLinus Torvalds 		return hci_dev_reset_stat(arg);
7471da177e4SLinus Torvalds 
7481da177e4SLinus Torvalds 	case HCISETSCAN:
7491da177e4SLinus Torvalds 	case HCISETAUTH:
7501da177e4SLinus Torvalds 	case HCISETENCRYPT:
7511da177e4SLinus Torvalds 	case HCISETPTYPE:
7521da177e4SLinus Torvalds 	case HCISETLINKPOL:
7531da177e4SLinus Torvalds 	case HCISETLINKMODE:
7541da177e4SLinus Torvalds 	case HCISETACLMTU:
7551da177e4SLinus Torvalds 	case HCISETSCOMTU:
7561da177e4SLinus Torvalds 		if (!capable(CAP_NET_ADMIN))
757bf5b30b8SZhao Hongjiang 			return -EPERM;
7581da177e4SLinus Torvalds 		return hci_dev_cmd(cmd, argp);
7591da177e4SLinus Torvalds 
7601da177e4SLinus Torvalds 	case HCIINQUIRY:
7611da177e4SLinus Torvalds 		return hci_inquiry(argp);
762c1c4f956SMarcel Holtmann 	}
7631da177e4SLinus Torvalds 
7641da177e4SLinus Torvalds 	lock_sock(sk);
765c1c4f956SMarcel Holtmann 
7661da177e4SLinus Torvalds 	err = hci_sock_bound_ioctl(sk, cmd, arg);
767c1c4f956SMarcel Holtmann 
768c1c4f956SMarcel Holtmann done:
7691da177e4SLinus Torvalds 	release_sock(sk);
7701da177e4SLinus Torvalds 	return err;
7711da177e4SLinus Torvalds }
7721da177e4SLinus Torvalds 
7738fc9ced3SGustavo Padovan static int hci_sock_bind(struct socket *sock, struct sockaddr *addr,
7748fc9ced3SGustavo Padovan 			 int addr_len)
7751da177e4SLinus Torvalds {
7760381101fSJohan Hedberg 	struct sockaddr_hci haddr;
7771da177e4SLinus Torvalds 	struct sock *sk = sock->sk;
7781da177e4SLinus Torvalds 	struct hci_dev *hdev = NULL;
7790381101fSJohan Hedberg 	int len, err = 0;
7801da177e4SLinus Torvalds 
7811da177e4SLinus Torvalds 	BT_DBG("sock %p sk %p", sock, sk);
7821da177e4SLinus Torvalds 
7830381101fSJohan Hedberg 	if (!addr)
7840381101fSJohan Hedberg 		return -EINVAL;
7850381101fSJohan Hedberg 
7860381101fSJohan Hedberg 	memset(&haddr, 0, sizeof(haddr));
7870381101fSJohan Hedberg 	len = min_t(unsigned int, sizeof(haddr), addr_len);
7880381101fSJohan Hedberg 	memcpy(&haddr, addr, len);
7890381101fSJohan Hedberg 
7900381101fSJohan Hedberg 	if (haddr.hci_family != AF_BLUETOOTH)
7910381101fSJohan Hedberg 		return -EINVAL;
7920381101fSJohan Hedberg 
7931da177e4SLinus Torvalds 	lock_sock(sk);
7941da177e4SLinus Torvalds 
7957cc2ade2SMarcel Holtmann 	if (sk->sk_state == BT_BOUND) {
7967cc2ade2SMarcel Holtmann 		err = -EALREADY;
7977cc2ade2SMarcel Holtmann 		goto done;
7987cc2ade2SMarcel Holtmann 	}
7997cc2ade2SMarcel Holtmann 
8007cc2ade2SMarcel Holtmann 	switch (haddr.hci_channel) {
8017cc2ade2SMarcel Holtmann 	case HCI_CHANNEL_RAW:
8027cc2ade2SMarcel Holtmann 		if (hci_pi(sk)->hdev) {
8031da177e4SLinus Torvalds 			err = -EALREADY;
8041da177e4SLinus Torvalds 			goto done;
8051da177e4SLinus Torvalds 		}
8061da177e4SLinus Torvalds 
8070381101fSJohan Hedberg 		if (haddr.hci_dev != HCI_DEV_NONE) {
8080381101fSJohan Hedberg 			hdev = hci_dev_get(haddr.hci_dev);
80970f23020SAndrei Emeltchenko 			if (!hdev) {
8101da177e4SLinus Torvalds 				err = -ENODEV;
8111da177e4SLinus Torvalds 				goto done;
8121da177e4SLinus Torvalds 			}
8131da177e4SLinus Torvalds 
8141da177e4SLinus Torvalds 			atomic_inc(&hdev->promisc);
8151da177e4SLinus Torvalds 		}
8161da177e4SLinus Torvalds 
8171da177e4SLinus Torvalds 		hci_pi(sk)->hdev = hdev;
8187cc2ade2SMarcel Holtmann 		break;
8197cc2ade2SMarcel Holtmann 
82023500189SMarcel Holtmann 	case HCI_CHANNEL_USER:
82123500189SMarcel Holtmann 		if (hci_pi(sk)->hdev) {
82223500189SMarcel Holtmann 			err = -EALREADY;
82323500189SMarcel Holtmann 			goto done;
82423500189SMarcel Holtmann 		}
82523500189SMarcel Holtmann 
82623500189SMarcel Holtmann 		if (haddr.hci_dev == HCI_DEV_NONE) {
82723500189SMarcel Holtmann 			err = -EINVAL;
82823500189SMarcel Holtmann 			goto done;
82923500189SMarcel Holtmann 		}
83023500189SMarcel Holtmann 
83110a8b86fSMarcel Holtmann 		if (!capable(CAP_NET_ADMIN)) {
83223500189SMarcel Holtmann 			err = -EPERM;
83323500189SMarcel Holtmann 			goto done;
83423500189SMarcel Holtmann 		}
83523500189SMarcel Holtmann 
83623500189SMarcel Holtmann 		hdev = hci_dev_get(haddr.hci_dev);
83723500189SMarcel Holtmann 		if (!hdev) {
83823500189SMarcel Holtmann 			err = -ENODEV;
83923500189SMarcel Holtmann 			goto done;
84023500189SMarcel Holtmann 		}
84123500189SMarcel Holtmann 
842781f899fSMarcel Holtmann 		if (test_bit(HCI_INIT, &hdev->flags) ||
843d7a5a11dSMarcel Holtmann 		    hci_dev_test_flag(hdev, HCI_SETUP) ||
844781f899fSMarcel Holtmann 		    hci_dev_test_flag(hdev, HCI_CONFIG) ||
845781f899fSMarcel Holtmann 		    (!hci_dev_test_flag(hdev, HCI_AUTO_OFF) &&
846781f899fSMarcel Holtmann 		     test_bit(HCI_UP, &hdev->flags))) {
84723500189SMarcel Holtmann 			err = -EBUSY;
84823500189SMarcel Holtmann 			hci_dev_put(hdev);
84923500189SMarcel Holtmann 			goto done;
85023500189SMarcel Holtmann 		}
85123500189SMarcel Holtmann 
852238be788SMarcel Holtmann 		if (hci_dev_test_and_set_flag(hdev, HCI_USER_CHANNEL)) {
85323500189SMarcel Holtmann 			err = -EUSERS;
85423500189SMarcel Holtmann 			hci_dev_put(hdev);
85523500189SMarcel Holtmann 			goto done;
85623500189SMarcel Holtmann 		}
85723500189SMarcel Holtmann 
85823500189SMarcel Holtmann 		mgmt_index_removed(hdev);
85923500189SMarcel Holtmann 
86023500189SMarcel Holtmann 		err = hci_dev_open(hdev->id);
86123500189SMarcel Holtmann 		if (err) {
862781f899fSMarcel Holtmann 			if (err == -EALREADY) {
863781f899fSMarcel Holtmann 				/* In case the transport is already up and
864781f899fSMarcel Holtmann 				 * running, clear the error here.
865781f899fSMarcel Holtmann 				 *
866781f899fSMarcel Holtmann 				 * This can happen when opening an user
867781f899fSMarcel Holtmann 				 * channel and HCI_AUTO_OFF grace period
868781f899fSMarcel Holtmann 				 * is still active.
869781f899fSMarcel Holtmann 				 */
870781f899fSMarcel Holtmann 				err = 0;
871781f899fSMarcel Holtmann 			} else {
872a358dc11SMarcel Holtmann 				hci_dev_clear_flag(hdev, HCI_USER_CHANNEL);
873c6521401SMarcel Holtmann 				mgmt_index_added(hdev);
87423500189SMarcel Holtmann 				hci_dev_put(hdev);
87523500189SMarcel Holtmann 				goto done;
87623500189SMarcel Holtmann 			}
877781f899fSMarcel Holtmann 		}
87823500189SMarcel Holtmann 
87923500189SMarcel Holtmann 		atomic_inc(&hdev->promisc);
88023500189SMarcel Holtmann 
88123500189SMarcel Holtmann 		hci_pi(sk)->hdev = hdev;
88223500189SMarcel Holtmann 		break;
88323500189SMarcel Holtmann 
884cd82e61cSMarcel Holtmann 	case HCI_CHANNEL_MONITOR:
885cd82e61cSMarcel Holtmann 		if (haddr.hci_dev != HCI_DEV_NONE) {
886cd82e61cSMarcel Holtmann 			err = -EINVAL;
887cd82e61cSMarcel Holtmann 			goto done;
888cd82e61cSMarcel Holtmann 		}
889cd82e61cSMarcel Holtmann 
890cd82e61cSMarcel Holtmann 		if (!capable(CAP_NET_RAW)) {
891cd82e61cSMarcel Holtmann 			err = -EPERM;
892cd82e61cSMarcel Holtmann 			goto done;
893cd82e61cSMarcel Holtmann 		}
894cd82e61cSMarcel Holtmann 
89550ebc055SMarcel Holtmann 		/* The monitor interface is restricted to CAP_NET_RAW
89650ebc055SMarcel Holtmann 		 * capabilities and with that implicitly trusted.
89750ebc055SMarcel Holtmann 		 */
89850ebc055SMarcel Holtmann 		hci_sock_set_flag(sk, HCI_SOCK_TRUSTED);
89950ebc055SMarcel Holtmann 
900dd31506dSMarcel Holtmann 		send_monitor_note(sk, "Linux version " UTS_RELEASE
901dd31506dSMarcel Holtmann 				      " (" UTS_MACHINE ")");
902dd31506dSMarcel Holtmann 		send_monitor_note(sk, "Bluetooth subsystem version "
903dd31506dSMarcel Holtmann 				      BT_SUBSYS_VERSION);
904cd82e61cSMarcel Holtmann 		send_monitor_replay(sk);
905cd82e61cSMarcel Holtmann 
906cd82e61cSMarcel Holtmann 		atomic_inc(&monitor_promisc);
907cd82e61cSMarcel Holtmann 		break;
908cd82e61cSMarcel Holtmann 
909*ac714949SMarcel Holtmann 	case HCI_CHANNEL_LOGGING:
910*ac714949SMarcel Holtmann 		if (haddr.hci_dev != HCI_DEV_NONE) {
911*ac714949SMarcel Holtmann 			err = -EINVAL;
912*ac714949SMarcel Holtmann 			goto done;
913*ac714949SMarcel Holtmann 		}
914*ac714949SMarcel Holtmann 
915*ac714949SMarcel Holtmann 		if (!capable(CAP_NET_ADMIN)) {
916*ac714949SMarcel Holtmann 			err = -EPERM;
917*ac714949SMarcel Holtmann 			goto done;
918*ac714949SMarcel Holtmann 		}
919*ac714949SMarcel Holtmann 		break;
920*ac714949SMarcel Holtmann 
9217cc2ade2SMarcel Holtmann 	default:
922801c1e8dSJohan Hedberg 		if (!hci_mgmt_chan_find(haddr.hci_channel)) {
9237cc2ade2SMarcel Holtmann 			err = -EINVAL;
9247cc2ade2SMarcel Holtmann 			goto done;
9257cc2ade2SMarcel Holtmann 		}
9267cc2ade2SMarcel Holtmann 
927801c1e8dSJohan Hedberg 		if (haddr.hci_dev != HCI_DEV_NONE) {
928801c1e8dSJohan Hedberg 			err = -EINVAL;
929801c1e8dSJohan Hedberg 			goto done;
930801c1e8dSJohan Hedberg 		}
931801c1e8dSJohan Hedberg 
9321195fbb8SMarcel Holtmann 		/* Users with CAP_NET_ADMIN capabilities are allowed
9331195fbb8SMarcel Holtmann 		 * access to all management commands and events. For
9341195fbb8SMarcel Holtmann 		 * untrusted users the interface is restricted and
9351195fbb8SMarcel Holtmann 		 * also only untrusted events are sent.
93650ebc055SMarcel Holtmann 		 */
9371195fbb8SMarcel Holtmann 		if (capable(CAP_NET_ADMIN))
93850ebc055SMarcel Holtmann 			hci_sock_set_flag(sk, HCI_SOCK_TRUSTED);
93950ebc055SMarcel Holtmann 
940f9207338SMarcel Holtmann 		/* At the moment the index and unconfigured index events
941f9207338SMarcel Holtmann 		 * are enabled unconditionally. Setting them on each
942f9207338SMarcel Holtmann 		 * socket when binding keeps this functionality. They
943f9207338SMarcel Holtmann 		 * however might be cleared later and then sending of these
944f9207338SMarcel Holtmann 		 * events will be disabled, but that is then intentional.
945f6b7712eSMarcel Holtmann 		 *
946f6b7712eSMarcel Holtmann 		 * This also enables generic events that are safe to be
947f6b7712eSMarcel Holtmann 		 * received by untrusted users. Example for such events
948f6b7712eSMarcel Holtmann 		 * are changes to settings, class of device, name etc.
949f9207338SMarcel Holtmann 		 */
950f9207338SMarcel Holtmann 		if (haddr.hci_channel == HCI_CHANNEL_CONTROL) {
951f9207338SMarcel Holtmann 			hci_sock_set_flag(sk, HCI_MGMT_INDEX_EVENTS);
952f9207338SMarcel Holtmann 			hci_sock_set_flag(sk, HCI_MGMT_UNCONF_INDEX_EVENTS);
953f6b7712eSMarcel Holtmann 			hci_sock_set_flag(sk, HCI_MGMT_GENERIC_EVENTS);
954f9207338SMarcel Holtmann 		}
955801c1e8dSJohan Hedberg 		break;
956801c1e8dSJohan Hedberg 	}
957801c1e8dSJohan Hedberg 
9587cc2ade2SMarcel Holtmann 
9597cc2ade2SMarcel Holtmann 	hci_pi(sk)->channel = haddr.hci_channel;
9601da177e4SLinus Torvalds 	sk->sk_state = BT_BOUND;
9611da177e4SLinus Torvalds 
9621da177e4SLinus Torvalds done:
9631da177e4SLinus Torvalds 	release_sock(sk);
9641da177e4SLinus Torvalds 	return err;
9651da177e4SLinus Torvalds }
9661da177e4SLinus Torvalds 
9678fc9ced3SGustavo Padovan static int hci_sock_getname(struct socket *sock, struct sockaddr *addr,
9688fc9ced3SGustavo Padovan 			    int *addr_len, int peer)
9691da177e4SLinus Torvalds {
9701da177e4SLinus Torvalds 	struct sockaddr_hci *haddr = (struct sockaddr_hci *)addr;
9711da177e4SLinus Torvalds 	struct sock *sk = sock->sk;
9729d4b68b2SMarcel Holtmann 	struct hci_dev *hdev;
9739d4b68b2SMarcel Holtmann 	int err = 0;
9741da177e4SLinus Torvalds 
9751da177e4SLinus Torvalds 	BT_DBG("sock %p sk %p", sock, sk);
9761da177e4SLinus Torvalds 
97706f43cbcSMarcel Holtmann 	if (peer)
97806f43cbcSMarcel Holtmann 		return -EOPNOTSUPP;
97906f43cbcSMarcel Holtmann 
9801da177e4SLinus Torvalds 	lock_sock(sk);
9811da177e4SLinus Torvalds 
9829d4b68b2SMarcel Holtmann 	hdev = hci_pi(sk)->hdev;
9839d4b68b2SMarcel Holtmann 	if (!hdev) {
9849d4b68b2SMarcel Holtmann 		err = -EBADFD;
9859d4b68b2SMarcel Holtmann 		goto done;
9869d4b68b2SMarcel Holtmann 	}
9879d4b68b2SMarcel Holtmann 
9881da177e4SLinus Torvalds 	*addr_len = sizeof(*haddr);
9891da177e4SLinus Torvalds 	haddr->hci_family = AF_BLUETOOTH;
9907b005bd3SMarcel Holtmann 	haddr->hci_dev    = hdev->id;
9919d4b68b2SMarcel Holtmann 	haddr->hci_channel= hci_pi(sk)->channel;
9921da177e4SLinus Torvalds 
9939d4b68b2SMarcel Holtmann done:
9941da177e4SLinus Torvalds 	release_sock(sk);
9959d4b68b2SMarcel Holtmann 	return err;
9961da177e4SLinus Torvalds }
9971da177e4SLinus Torvalds 
9986039aa73SGustavo Padovan static void hci_sock_cmsg(struct sock *sk, struct msghdr *msg,
9996039aa73SGustavo Padovan 			  struct sk_buff *skb)
10001da177e4SLinus Torvalds {
10011da177e4SLinus Torvalds 	__u32 mask = hci_pi(sk)->cmsg_mask;
10021da177e4SLinus Torvalds 
10030d48d939SMarcel Holtmann 	if (mask & HCI_CMSG_DIR) {
10040d48d939SMarcel Holtmann 		int incoming = bt_cb(skb)->incoming;
10058fc9ced3SGustavo Padovan 		put_cmsg(msg, SOL_HCI, HCI_CMSG_DIR, sizeof(incoming),
10068fc9ced3SGustavo Padovan 			 &incoming);
10070d48d939SMarcel Holtmann 	}
10081da177e4SLinus Torvalds 
1009a61bbcf2SPatrick McHardy 	if (mask & HCI_CMSG_TSTAMP) {
1010f6e623a6SJohann Felix Soden #ifdef CONFIG_COMPAT
1011f6e623a6SJohann Felix Soden 		struct compat_timeval ctv;
1012f6e623a6SJohann Felix Soden #endif
1013a61bbcf2SPatrick McHardy 		struct timeval tv;
1014767c5eb5SMarcel Holtmann 		void *data;
1015767c5eb5SMarcel Holtmann 		int len;
1016a61bbcf2SPatrick McHardy 
1017a61bbcf2SPatrick McHardy 		skb_get_timestamp(skb, &tv);
1018767c5eb5SMarcel Holtmann 
10191da97f83SDavid S. Miller 		data = &tv;
10201da97f83SDavid S. Miller 		len = sizeof(tv);
10211da97f83SDavid S. Miller #ifdef CONFIG_COMPAT
1022da88cea1SH. J. Lu 		if (!COMPAT_USE_64BIT_TIME &&
1023da88cea1SH. J. Lu 		    (msg->msg_flags & MSG_CMSG_COMPAT)) {
1024767c5eb5SMarcel Holtmann 			ctv.tv_sec = tv.tv_sec;
1025767c5eb5SMarcel Holtmann 			ctv.tv_usec = tv.tv_usec;
1026767c5eb5SMarcel Holtmann 			data = &ctv;
1027767c5eb5SMarcel Holtmann 			len = sizeof(ctv);
1028767c5eb5SMarcel Holtmann 		}
10291da97f83SDavid S. Miller #endif
1030767c5eb5SMarcel Holtmann 
1031767c5eb5SMarcel Holtmann 		put_cmsg(msg, SOL_HCI, HCI_CMSG_TSTAMP, len, data);
1032a61bbcf2SPatrick McHardy 	}
10331da177e4SLinus Torvalds }
10341da177e4SLinus Torvalds 
10358528d3f7SMarcel Holtmann static int hci_sock_recvmsg(struct socket *sock, struct msghdr *msg,
10368528d3f7SMarcel Holtmann 			    size_t len, int flags)
10371da177e4SLinus Torvalds {
10381da177e4SLinus Torvalds 	int noblock = flags & MSG_DONTWAIT;
10391da177e4SLinus Torvalds 	struct sock *sk = sock->sk;
10401da177e4SLinus Torvalds 	struct sk_buff *skb;
10411da177e4SLinus Torvalds 	int copied, err;
10421da177e4SLinus Torvalds 
10431da177e4SLinus Torvalds 	BT_DBG("sock %p, sk %p", sock, sk);
10441da177e4SLinus Torvalds 
1045d94a6104SMarcel Holtmann 	if (flags & MSG_OOB)
10461da177e4SLinus Torvalds 		return -EOPNOTSUPP;
10471da177e4SLinus Torvalds 
1048*ac714949SMarcel Holtmann 	if (hci_pi(sk)->channel == HCI_CHANNEL_LOGGING)
1049*ac714949SMarcel Holtmann 		return -EOPNOTSUPP;
1050*ac714949SMarcel Holtmann 
10511da177e4SLinus Torvalds 	if (sk->sk_state == BT_CLOSED)
10521da177e4SLinus Torvalds 		return 0;
10531da177e4SLinus Torvalds 
105470f23020SAndrei Emeltchenko 	skb = skb_recv_datagram(sk, flags, noblock, &err);
105570f23020SAndrei Emeltchenko 	if (!skb)
10561da177e4SLinus Torvalds 		return err;
10571da177e4SLinus Torvalds 
10581da177e4SLinus Torvalds 	copied = skb->len;
10591da177e4SLinus Torvalds 	if (len < copied) {
10601da177e4SLinus Torvalds 		msg->msg_flags |= MSG_TRUNC;
10611da177e4SLinus Torvalds 		copied = len;
10621da177e4SLinus Torvalds 	}
10631da177e4SLinus Torvalds 
1064badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
106551f3d02bSDavid S. Miller 	err = skb_copy_datagram_msg(skb, 0, msg, copied);
10661da177e4SLinus Torvalds 
10673a208627SMarcel Holtmann 	switch (hci_pi(sk)->channel) {
10683a208627SMarcel Holtmann 	case HCI_CHANNEL_RAW:
10691da177e4SLinus Torvalds 		hci_sock_cmsg(sk, msg, skb);
10703a208627SMarcel Holtmann 		break;
107123500189SMarcel Holtmann 	case HCI_CHANNEL_USER:
1072cd82e61cSMarcel Holtmann 	case HCI_CHANNEL_MONITOR:
1073cd82e61cSMarcel Holtmann 		sock_recv_timestamp(msg, sk, skb);
1074cd82e61cSMarcel Holtmann 		break;
1075801c1e8dSJohan Hedberg 	default:
1076801c1e8dSJohan Hedberg 		if (hci_mgmt_chan_find(hci_pi(sk)->channel))
1077801c1e8dSJohan Hedberg 			sock_recv_timestamp(msg, sk, skb);
1078801c1e8dSJohan Hedberg 		break;
10793a208627SMarcel Holtmann 	}
10801da177e4SLinus Torvalds 
10811da177e4SLinus Torvalds 	skb_free_datagram(sk, skb);
10821da177e4SLinus Torvalds 
10831da177e4SLinus Torvalds 	return err ? : copied;
10841da177e4SLinus Torvalds }
10851da177e4SLinus Torvalds 
1086fa4335d7SJohan Hedberg static int hci_mgmt_cmd(struct hci_mgmt_chan *chan, struct sock *sk,
1087fa4335d7SJohan Hedberg 			struct msghdr *msg, size_t msglen)
1088fa4335d7SJohan Hedberg {
1089fa4335d7SJohan Hedberg 	void *buf;
1090fa4335d7SJohan Hedberg 	u8 *cp;
1091fa4335d7SJohan Hedberg 	struct mgmt_hdr *hdr;
1092fa4335d7SJohan Hedberg 	u16 opcode, index, len;
1093fa4335d7SJohan Hedberg 	struct hci_dev *hdev = NULL;
1094fa4335d7SJohan Hedberg 	const struct hci_mgmt_handler *handler;
1095fa4335d7SJohan Hedberg 	bool var_len, no_hdev;
1096fa4335d7SJohan Hedberg 	int err;
1097fa4335d7SJohan Hedberg 
1098fa4335d7SJohan Hedberg 	BT_DBG("got %zu bytes", msglen);
1099fa4335d7SJohan Hedberg 
1100fa4335d7SJohan Hedberg 	if (msglen < sizeof(*hdr))
1101fa4335d7SJohan Hedberg 		return -EINVAL;
1102fa4335d7SJohan Hedberg 
1103fa4335d7SJohan Hedberg 	buf = kmalloc(msglen, GFP_KERNEL);
1104fa4335d7SJohan Hedberg 	if (!buf)
1105fa4335d7SJohan Hedberg 		return -ENOMEM;
1106fa4335d7SJohan Hedberg 
1107fa4335d7SJohan Hedberg 	if (memcpy_from_msg(buf, msg, msglen)) {
1108fa4335d7SJohan Hedberg 		err = -EFAULT;
1109fa4335d7SJohan Hedberg 		goto done;
1110fa4335d7SJohan Hedberg 	}
1111fa4335d7SJohan Hedberg 
1112fa4335d7SJohan Hedberg 	hdr = buf;
1113fa4335d7SJohan Hedberg 	opcode = __le16_to_cpu(hdr->opcode);
1114fa4335d7SJohan Hedberg 	index = __le16_to_cpu(hdr->index);
1115fa4335d7SJohan Hedberg 	len = __le16_to_cpu(hdr->len);
1116fa4335d7SJohan Hedberg 
1117fa4335d7SJohan Hedberg 	if (len != msglen - sizeof(*hdr)) {
1118fa4335d7SJohan Hedberg 		err = -EINVAL;
1119fa4335d7SJohan Hedberg 		goto done;
1120fa4335d7SJohan Hedberg 	}
1121fa4335d7SJohan Hedberg 
1122fa4335d7SJohan Hedberg 	if (opcode >= chan->handler_count ||
1123fa4335d7SJohan Hedberg 	    chan->handlers[opcode].func == NULL) {
1124fa4335d7SJohan Hedberg 		BT_DBG("Unknown op %u", opcode);
1125fa4335d7SJohan Hedberg 		err = mgmt_cmd_status(sk, index, opcode,
1126fa4335d7SJohan Hedberg 				      MGMT_STATUS_UNKNOWN_COMMAND);
1127fa4335d7SJohan Hedberg 		goto done;
1128fa4335d7SJohan Hedberg 	}
1129fa4335d7SJohan Hedberg 
1130fa4335d7SJohan Hedberg 	handler = &chan->handlers[opcode];
1131fa4335d7SJohan Hedberg 
1132fa4335d7SJohan Hedberg 	if (!hci_sock_test_flag(sk, HCI_SOCK_TRUSTED) &&
1133fa4335d7SJohan Hedberg 	    !(handler->flags & HCI_MGMT_UNTRUSTED)) {
1134fa4335d7SJohan Hedberg 		err = mgmt_cmd_status(sk, index, opcode,
1135fa4335d7SJohan Hedberg 				      MGMT_STATUS_PERMISSION_DENIED);
1136fa4335d7SJohan Hedberg 		goto done;
1137fa4335d7SJohan Hedberg 	}
1138fa4335d7SJohan Hedberg 
1139fa4335d7SJohan Hedberg 	if (index != MGMT_INDEX_NONE) {
1140fa4335d7SJohan Hedberg 		hdev = hci_dev_get(index);
1141fa4335d7SJohan Hedberg 		if (!hdev) {
1142fa4335d7SJohan Hedberg 			err = mgmt_cmd_status(sk, index, opcode,
1143fa4335d7SJohan Hedberg 					      MGMT_STATUS_INVALID_INDEX);
1144fa4335d7SJohan Hedberg 			goto done;
1145fa4335d7SJohan Hedberg 		}
1146fa4335d7SJohan Hedberg 
1147fa4335d7SJohan Hedberg 		if (hci_dev_test_flag(hdev, HCI_SETUP) ||
1148fa4335d7SJohan Hedberg 		    hci_dev_test_flag(hdev, HCI_CONFIG) ||
1149fa4335d7SJohan Hedberg 		    hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
1150fa4335d7SJohan Hedberg 			err = mgmt_cmd_status(sk, index, opcode,
1151fa4335d7SJohan Hedberg 					      MGMT_STATUS_INVALID_INDEX);
1152fa4335d7SJohan Hedberg 			goto done;
1153fa4335d7SJohan Hedberg 		}
1154fa4335d7SJohan Hedberg 
1155fa4335d7SJohan Hedberg 		if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
1156fa4335d7SJohan Hedberg 		    !(handler->flags & HCI_MGMT_UNCONFIGURED)) {
1157fa4335d7SJohan Hedberg 			err = mgmt_cmd_status(sk, index, opcode,
1158fa4335d7SJohan Hedberg 					      MGMT_STATUS_INVALID_INDEX);
1159fa4335d7SJohan Hedberg 			goto done;
1160fa4335d7SJohan Hedberg 		}
1161fa4335d7SJohan Hedberg 	}
1162fa4335d7SJohan Hedberg 
1163fa4335d7SJohan Hedberg 	no_hdev = (handler->flags & HCI_MGMT_NO_HDEV);
1164fa4335d7SJohan Hedberg 	if (no_hdev != !hdev) {
1165fa4335d7SJohan Hedberg 		err = mgmt_cmd_status(sk, index, opcode,
1166fa4335d7SJohan Hedberg 				      MGMT_STATUS_INVALID_INDEX);
1167fa4335d7SJohan Hedberg 		goto done;
1168fa4335d7SJohan Hedberg 	}
1169fa4335d7SJohan Hedberg 
1170fa4335d7SJohan Hedberg 	var_len = (handler->flags & HCI_MGMT_VAR_LEN);
1171fa4335d7SJohan Hedberg 	if ((var_len && len < handler->data_len) ||
1172fa4335d7SJohan Hedberg 	    (!var_len && len != handler->data_len)) {
1173fa4335d7SJohan Hedberg 		err = mgmt_cmd_status(sk, index, opcode,
1174fa4335d7SJohan Hedberg 				      MGMT_STATUS_INVALID_PARAMS);
1175fa4335d7SJohan Hedberg 		goto done;
1176fa4335d7SJohan Hedberg 	}
1177fa4335d7SJohan Hedberg 
1178fa4335d7SJohan Hedberg 	if (hdev && chan->hdev_init)
1179fa4335d7SJohan Hedberg 		chan->hdev_init(sk, hdev);
1180fa4335d7SJohan Hedberg 
1181fa4335d7SJohan Hedberg 	cp = buf + sizeof(*hdr);
1182fa4335d7SJohan Hedberg 
1183fa4335d7SJohan Hedberg 	err = handler->func(sk, hdev, cp, len);
1184fa4335d7SJohan Hedberg 	if (err < 0)
1185fa4335d7SJohan Hedberg 		goto done;
1186fa4335d7SJohan Hedberg 
1187fa4335d7SJohan Hedberg 	err = msglen;
1188fa4335d7SJohan Hedberg 
1189fa4335d7SJohan Hedberg done:
1190fa4335d7SJohan Hedberg 	if (hdev)
1191fa4335d7SJohan Hedberg 		hci_dev_put(hdev);
1192fa4335d7SJohan Hedberg 
1193fa4335d7SJohan Hedberg 	kfree(buf);
1194fa4335d7SJohan Hedberg 	return err;
1195fa4335d7SJohan Hedberg }
1196fa4335d7SJohan Hedberg 
1197*ac714949SMarcel Holtmann static int hci_logging_frame(struct sock *sk, struct msghdr *msg, int len)
1198*ac714949SMarcel Holtmann {
1199*ac714949SMarcel Holtmann 	struct hci_mon_hdr *hdr;
1200*ac714949SMarcel Holtmann 	struct sk_buff *skb;
1201*ac714949SMarcel Holtmann 	struct hci_dev *hdev;
1202*ac714949SMarcel Holtmann 	u16 index;
1203*ac714949SMarcel Holtmann 	int err;
1204*ac714949SMarcel Holtmann 
1205*ac714949SMarcel Holtmann 	/* The logging frame consists at minimum of the standard header,
1206*ac714949SMarcel Holtmann 	 * the priority byte, the ident length byte and at least one string
1207*ac714949SMarcel Holtmann 	 * terminator NUL byte. Anything shorter are invalid packets.
1208*ac714949SMarcel Holtmann 	 */
1209*ac714949SMarcel Holtmann 	if (len < sizeof(*hdr) + 3)
1210*ac714949SMarcel Holtmann 		return -EINVAL;
1211*ac714949SMarcel Holtmann 
1212*ac714949SMarcel Holtmann 	skb = bt_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err);
1213*ac714949SMarcel Holtmann 	if (!skb)
1214*ac714949SMarcel Holtmann 		return err;
1215*ac714949SMarcel Holtmann 
1216*ac714949SMarcel Holtmann 	if (memcpy_from_msg(skb_put(skb, len), msg, len)) {
1217*ac714949SMarcel Holtmann 		err = -EFAULT;
1218*ac714949SMarcel Holtmann 		goto drop;
1219*ac714949SMarcel Holtmann 	}
1220*ac714949SMarcel Holtmann 
1221*ac714949SMarcel Holtmann 	hdr = (void *)skb->data;
1222*ac714949SMarcel Holtmann 
1223*ac714949SMarcel Holtmann 	if (__le16_to_cpu(hdr->len) != len - sizeof(*hdr)) {
1224*ac714949SMarcel Holtmann 		err = -EINVAL;
1225*ac714949SMarcel Holtmann 		goto drop;
1226*ac714949SMarcel Holtmann 	}
1227*ac714949SMarcel Holtmann 
1228*ac714949SMarcel Holtmann 	if (__le16_to_cpu(hdr->opcode) == 0x0000) {
1229*ac714949SMarcel Holtmann 		__u8 priority = skb->data[sizeof(*hdr)];
1230*ac714949SMarcel Holtmann 		__u8 ident_len = skb->data[sizeof(*hdr) + 1];
1231*ac714949SMarcel Holtmann 
1232*ac714949SMarcel Holtmann 		/* Only the priorities 0-7 are valid and with that any other
1233*ac714949SMarcel Holtmann 		 * value results in an invalid packet.
1234*ac714949SMarcel Holtmann 		 *
1235*ac714949SMarcel Holtmann 		 * The priority byte is followed by an ident length byte and
1236*ac714949SMarcel Holtmann 		 * the NUL terminated ident string. Check that the ident
1237*ac714949SMarcel Holtmann 		 * length is not overflowing the packet and also that the
1238*ac714949SMarcel Holtmann 		 * ident string itself is NUL terminated. In case the ident
1239*ac714949SMarcel Holtmann 		 * length is zero, the length value actually doubles as NUL
1240*ac714949SMarcel Holtmann 		 * terminator identifier.
1241*ac714949SMarcel Holtmann 		 *
1242*ac714949SMarcel Holtmann 		 * The message follows the ident string (if present) and
1243*ac714949SMarcel Holtmann 		 * must be NUL terminated. Otherwise it is not a valid packet.
1244*ac714949SMarcel Holtmann 		 */
1245*ac714949SMarcel Holtmann 		if (priority > 7 || skb->data[len - 1] != 0x00 ||
1246*ac714949SMarcel Holtmann 		    ident_len > len - sizeof(*hdr) - 3 ||
1247*ac714949SMarcel Holtmann 		    skb->data[sizeof(*hdr) + ident_len + 1] != 0x00) {
1248*ac714949SMarcel Holtmann 			err = -EINVAL;
1249*ac714949SMarcel Holtmann 			goto drop;
1250*ac714949SMarcel Holtmann 		}
1251*ac714949SMarcel Holtmann 	} else {
1252*ac714949SMarcel Holtmann 		err = -EINVAL;
1253*ac714949SMarcel Holtmann 		goto drop;
1254*ac714949SMarcel Holtmann 	}
1255*ac714949SMarcel Holtmann 
1256*ac714949SMarcel Holtmann 	index = __le16_to_cpu(hdr->index);
1257*ac714949SMarcel Holtmann 
1258*ac714949SMarcel Holtmann 	if (index != MGMT_INDEX_NONE) {
1259*ac714949SMarcel Holtmann 		hdev = hci_dev_get(index);
1260*ac714949SMarcel Holtmann 		if (!hdev) {
1261*ac714949SMarcel Holtmann 			err = -ENODEV;
1262*ac714949SMarcel Holtmann 			goto drop;
1263*ac714949SMarcel Holtmann 		}
1264*ac714949SMarcel Holtmann 	} else {
1265*ac714949SMarcel Holtmann 		hdev = NULL;
1266*ac714949SMarcel Holtmann 	}
1267*ac714949SMarcel Holtmann 
1268*ac714949SMarcel Holtmann 	hdr->opcode = cpu_to_le16(HCI_MON_USER_LOGGING);
1269*ac714949SMarcel Holtmann 
1270*ac714949SMarcel Holtmann 	hci_send_to_channel(HCI_CHANNEL_MONITOR, skb, HCI_SOCK_TRUSTED, NULL);
1271*ac714949SMarcel Holtmann 	err = len;
1272*ac714949SMarcel Holtmann 
1273*ac714949SMarcel Holtmann 	if (hdev)
1274*ac714949SMarcel Holtmann 		hci_dev_put(hdev);
1275*ac714949SMarcel Holtmann 
1276*ac714949SMarcel Holtmann drop:
1277*ac714949SMarcel Holtmann 	kfree_skb(skb);
1278*ac714949SMarcel Holtmann 	return err;
1279*ac714949SMarcel Holtmann }
1280*ac714949SMarcel Holtmann 
12811b784140SYing Xue static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg,
12821b784140SYing Xue 			    size_t len)
12831da177e4SLinus Torvalds {
12841da177e4SLinus Torvalds 	struct sock *sk = sock->sk;
1285801c1e8dSJohan Hedberg 	struct hci_mgmt_chan *chan;
12861da177e4SLinus Torvalds 	struct hci_dev *hdev;
12871da177e4SLinus Torvalds 	struct sk_buff *skb;
12881da177e4SLinus Torvalds 	int err;
12891da177e4SLinus Torvalds 
12901da177e4SLinus Torvalds 	BT_DBG("sock %p sk %p", sock, sk);
12911da177e4SLinus Torvalds 
12921da177e4SLinus Torvalds 	if (msg->msg_flags & MSG_OOB)
12931da177e4SLinus Torvalds 		return -EOPNOTSUPP;
12941da177e4SLinus Torvalds 
12951da177e4SLinus Torvalds 	if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE))
12961da177e4SLinus Torvalds 		return -EINVAL;
12971da177e4SLinus Torvalds 
12981da177e4SLinus Torvalds 	if (len < 4 || len > HCI_MAX_FRAME_SIZE)
12991da177e4SLinus Torvalds 		return -EINVAL;
13001da177e4SLinus Torvalds 
13011da177e4SLinus Torvalds 	lock_sock(sk);
13021da177e4SLinus Torvalds 
13030381101fSJohan Hedberg 	switch (hci_pi(sk)->channel) {
13040381101fSJohan Hedberg 	case HCI_CHANNEL_RAW:
130523500189SMarcel Holtmann 	case HCI_CHANNEL_USER:
13060381101fSJohan Hedberg 		break;
1307cd82e61cSMarcel Holtmann 	case HCI_CHANNEL_MONITOR:
1308cd82e61cSMarcel Holtmann 		err = -EOPNOTSUPP;
1309cd82e61cSMarcel Holtmann 		goto done;
1310*ac714949SMarcel Holtmann 	case HCI_CHANNEL_LOGGING:
1311*ac714949SMarcel Holtmann 		err = hci_logging_frame(sk, msg, len);
1312*ac714949SMarcel Holtmann 		goto done;
13130381101fSJohan Hedberg 	default:
1314801c1e8dSJohan Hedberg 		mutex_lock(&mgmt_chan_list_lock);
1315801c1e8dSJohan Hedberg 		chan = __hci_mgmt_chan_find(hci_pi(sk)->channel);
1316801c1e8dSJohan Hedberg 		if (chan)
1317fa4335d7SJohan Hedberg 			err = hci_mgmt_cmd(chan, sk, msg, len);
1318801c1e8dSJohan Hedberg 		else
13190381101fSJohan Hedberg 			err = -EINVAL;
1320801c1e8dSJohan Hedberg 
1321801c1e8dSJohan Hedberg 		mutex_unlock(&mgmt_chan_list_lock);
13220381101fSJohan Hedberg 		goto done;
13230381101fSJohan Hedberg 	}
13240381101fSJohan Hedberg 
132570f23020SAndrei Emeltchenko 	hdev = hci_pi(sk)->hdev;
132670f23020SAndrei Emeltchenko 	if (!hdev) {
13271da177e4SLinus Torvalds 		err = -EBADFD;
13281da177e4SLinus Torvalds 		goto done;
13291da177e4SLinus Torvalds 	}
13301da177e4SLinus Torvalds 
13317e21addcSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags)) {
13327e21addcSMarcel Holtmann 		err = -ENETDOWN;
13337e21addcSMarcel Holtmann 		goto done;
13347e21addcSMarcel Holtmann 	}
13357e21addcSMarcel Holtmann 
133670f23020SAndrei Emeltchenko 	skb = bt_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err);
133770f23020SAndrei Emeltchenko 	if (!skb)
13381da177e4SLinus Torvalds 		goto done;
13391da177e4SLinus Torvalds 
13406ce8e9ceSAl Viro 	if (memcpy_from_msg(skb_put(skb, len), msg, len)) {
13411da177e4SLinus Torvalds 		err = -EFAULT;
13421da177e4SLinus Torvalds 		goto drop;
13431da177e4SLinus Torvalds 	}
13441da177e4SLinus Torvalds 
13458528d3f7SMarcel Holtmann 	hci_skb_pkt_type(skb) = skb->data[0];
13461da177e4SLinus Torvalds 	skb_pull(skb, 1);
13471da177e4SLinus Torvalds 
13481bc5ad16SMarcel Holtmann 	if (hci_pi(sk)->channel == HCI_CHANNEL_USER) {
13491bc5ad16SMarcel Holtmann 		/* No permission check is needed for user channel
13501bc5ad16SMarcel Holtmann 		 * since that gets enforced when binding the socket.
13511bc5ad16SMarcel Holtmann 		 *
13521bc5ad16SMarcel Holtmann 		 * However check that the packet type is valid.
13531bc5ad16SMarcel Holtmann 		 */
1354d79f34e3SMarcel Holtmann 		if (hci_skb_pkt_type(skb) != HCI_COMMAND_PKT &&
1355d79f34e3SMarcel Holtmann 		    hci_skb_pkt_type(skb) != HCI_ACLDATA_PKT &&
1356d79f34e3SMarcel Holtmann 		    hci_skb_pkt_type(skb) != HCI_SCODATA_PKT) {
13571bc5ad16SMarcel Holtmann 			err = -EINVAL;
13581bc5ad16SMarcel Holtmann 			goto drop;
13591bc5ad16SMarcel Holtmann 		}
13601bc5ad16SMarcel Holtmann 
13611bc5ad16SMarcel Holtmann 		skb_queue_tail(&hdev->raw_q, skb);
13621bc5ad16SMarcel Holtmann 		queue_work(hdev->workqueue, &hdev->tx_work);
1363d79f34e3SMarcel Holtmann 	} else if (hci_skb_pkt_type(skb) == HCI_COMMAND_PKT) {
136483985319SHarvey Harrison 		u16 opcode = get_unaligned_le16(skb->data);
13651da177e4SLinus Torvalds 		u16 ogf = hci_opcode_ogf(opcode);
13661da177e4SLinus Torvalds 		u16 ocf = hci_opcode_ocf(opcode);
13671da177e4SLinus Torvalds 
13681da177e4SLinus Torvalds 		if (((ogf > HCI_SFLT_MAX_OGF) ||
13693bb3c755SGustavo Padovan 		     !hci_test_bit(ocf & HCI_FLT_OCF_BITS,
13703bb3c755SGustavo Padovan 				   &hci_sec_filter.ocf_mask[ogf])) &&
13711da177e4SLinus Torvalds 		    !capable(CAP_NET_RAW)) {
13721da177e4SLinus Torvalds 			err = -EPERM;
13731da177e4SLinus Torvalds 			goto drop;
13741da177e4SLinus Torvalds 		}
13751da177e4SLinus Torvalds 
13761982162bSMarcel Holtmann 		/* Since the opcode has already been extracted here, store
13771982162bSMarcel Holtmann 		 * a copy of the value for later use by the drivers.
13781982162bSMarcel Holtmann 		 */
13791982162bSMarcel Holtmann 		hci_skb_opcode(skb) = opcode;
13801982162bSMarcel Holtmann 
1381fee746b0SMarcel Holtmann 		if (ogf == 0x3f) {
13821da177e4SLinus Torvalds 			skb_queue_tail(&hdev->raw_q, skb);
13833eff45eaSGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->tx_work);
13841da177e4SLinus Torvalds 		} else {
138549c922bbSStephen Hemminger 			/* Stand-alone HCI commands must be flagged as
138611714b3dSJohan Hedberg 			 * single-command requests.
138711714b3dSJohan Hedberg 			 */
138844d27137SJohan Hedberg 			bt_cb(skb)->hci.req_flags |= HCI_REQ_START;
138911714b3dSJohan Hedberg 
13901da177e4SLinus Torvalds 			skb_queue_tail(&hdev->cmd_q, skb);
1391c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
13921da177e4SLinus Torvalds 		}
13931da177e4SLinus Torvalds 	} else {
13941da177e4SLinus Torvalds 		if (!capable(CAP_NET_RAW)) {
13951da177e4SLinus Torvalds 			err = -EPERM;
13961da177e4SLinus Torvalds 			goto drop;
13971da177e4SLinus Torvalds 		}
13981da177e4SLinus Torvalds 
1399d79f34e3SMarcel Holtmann 		if (hci_skb_pkt_type(skb) != HCI_ACLDATA_PKT &&
1400d79f34e3SMarcel Holtmann 		    hci_skb_pkt_type(skb) != HCI_SCODATA_PKT) {
1401bb77543eSMarcel Holtmann 			err = -EINVAL;
1402bb77543eSMarcel Holtmann 			goto drop;
1403bb77543eSMarcel Holtmann 		}
1404bb77543eSMarcel Holtmann 
14051da177e4SLinus Torvalds 		skb_queue_tail(&hdev->raw_q, skb);
14063eff45eaSGustavo F. Padovan 		queue_work(hdev->workqueue, &hdev->tx_work);
14071da177e4SLinus Torvalds 	}
14081da177e4SLinus Torvalds 
14091da177e4SLinus Torvalds 	err = len;
14101da177e4SLinus Torvalds 
14111da177e4SLinus Torvalds done:
14121da177e4SLinus Torvalds 	release_sock(sk);
14131da177e4SLinus Torvalds 	return err;
14141da177e4SLinus Torvalds 
14151da177e4SLinus Torvalds drop:
14161da177e4SLinus Torvalds 	kfree_skb(skb);
14171da177e4SLinus Torvalds 	goto done;
14181da177e4SLinus Torvalds }
14191da177e4SLinus Torvalds 
14208fc9ced3SGustavo Padovan static int hci_sock_setsockopt(struct socket *sock, int level, int optname,
14218fc9ced3SGustavo Padovan 			       char __user *optval, unsigned int len)
14221da177e4SLinus Torvalds {
14231da177e4SLinus Torvalds 	struct hci_ufilter uf = { .opcode = 0 };
14241da177e4SLinus Torvalds 	struct sock *sk = sock->sk;
14251da177e4SLinus Torvalds 	int err = 0, opt = 0;
14261da177e4SLinus Torvalds 
14271da177e4SLinus Torvalds 	BT_DBG("sk %p, opt %d", sk, optname);
14281da177e4SLinus Torvalds 
14291da177e4SLinus Torvalds 	lock_sock(sk);
14301da177e4SLinus Torvalds 
14312f39cdb7SMarcel Holtmann 	if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) {
1432c2371e80SMarcel Holtmann 		err = -EBADFD;
14332f39cdb7SMarcel Holtmann 		goto done;
14342f39cdb7SMarcel Holtmann 	}
14352f39cdb7SMarcel Holtmann 
14361da177e4SLinus Torvalds 	switch (optname) {
14371da177e4SLinus Torvalds 	case HCI_DATA_DIR:
14381da177e4SLinus Torvalds 		if (get_user(opt, (int __user *)optval)) {
14391da177e4SLinus Torvalds 			err = -EFAULT;
14401da177e4SLinus Torvalds 			break;
14411da177e4SLinus Torvalds 		}
14421da177e4SLinus Torvalds 
14431da177e4SLinus Torvalds 		if (opt)
14441da177e4SLinus Torvalds 			hci_pi(sk)->cmsg_mask |= HCI_CMSG_DIR;
14451da177e4SLinus Torvalds 		else
14461da177e4SLinus Torvalds 			hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_DIR;
14471da177e4SLinus Torvalds 		break;
14481da177e4SLinus Torvalds 
14491da177e4SLinus Torvalds 	case HCI_TIME_STAMP:
14501da177e4SLinus Torvalds 		if (get_user(opt, (int __user *)optval)) {
14511da177e4SLinus Torvalds 			err = -EFAULT;
14521da177e4SLinus Torvalds 			break;
14531da177e4SLinus Torvalds 		}
14541da177e4SLinus Torvalds 
14551da177e4SLinus Torvalds 		if (opt)
14561da177e4SLinus Torvalds 			hci_pi(sk)->cmsg_mask |= HCI_CMSG_TSTAMP;
14571da177e4SLinus Torvalds 		else
14581da177e4SLinus Torvalds 			hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_TSTAMP;
14591da177e4SLinus Torvalds 		break;
14601da177e4SLinus Torvalds 
14611da177e4SLinus Torvalds 	case HCI_FILTER:
14620878b666SMarcel Holtmann 		{
14630878b666SMarcel Holtmann 			struct hci_filter *f = &hci_pi(sk)->filter;
14640878b666SMarcel Holtmann 
14650878b666SMarcel Holtmann 			uf.type_mask = f->type_mask;
14660878b666SMarcel Holtmann 			uf.opcode    = f->opcode;
14670878b666SMarcel Holtmann 			uf.event_mask[0] = *((u32 *) f->event_mask + 0);
14680878b666SMarcel Holtmann 			uf.event_mask[1] = *((u32 *) f->event_mask + 1);
14690878b666SMarcel Holtmann 		}
14700878b666SMarcel Holtmann 
14711da177e4SLinus Torvalds 		len = min_t(unsigned int, len, sizeof(uf));
14721da177e4SLinus Torvalds 		if (copy_from_user(&uf, optval, len)) {
14731da177e4SLinus Torvalds 			err = -EFAULT;
14741da177e4SLinus Torvalds 			break;
14751da177e4SLinus Torvalds 		}
14761da177e4SLinus Torvalds 
14771da177e4SLinus Torvalds 		if (!capable(CAP_NET_RAW)) {
14781da177e4SLinus Torvalds 			uf.type_mask &= hci_sec_filter.type_mask;
14791da177e4SLinus Torvalds 			uf.event_mask[0] &= *((u32 *) hci_sec_filter.event_mask + 0);
14801da177e4SLinus Torvalds 			uf.event_mask[1] &= *((u32 *) hci_sec_filter.event_mask + 1);
14811da177e4SLinus Torvalds 		}
14821da177e4SLinus Torvalds 
14831da177e4SLinus Torvalds 		{
14841da177e4SLinus Torvalds 			struct hci_filter *f = &hci_pi(sk)->filter;
14851da177e4SLinus Torvalds 
14861da177e4SLinus Torvalds 			f->type_mask = uf.type_mask;
14871da177e4SLinus Torvalds 			f->opcode    = uf.opcode;
14881da177e4SLinus Torvalds 			*((u32 *) f->event_mask + 0) = uf.event_mask[0];
14891da177e4SLinus Torvalds 			*((u32 *) f->event_mask + 1) = uf.event_mask[1];
14901da177e4SLinus Torvalds 		}
14911da177e4SLinus Torvalds 		break;
14921da177e4SLinus Torvalds 
14931da177e4SLinus Torvalds 	default:
14941da177e4SLinus Torvalds 		err = -ENOPROTOOPT;
14951da177e4SLinus Torvalds 		break;
14961da177e4SLinus Torvalds 	}
14971da177e4SLinus Torvalds 
14982f39cdb7SMarcel Holtmann done:
14991da177e4SLinus Torvalds 	release_sock(sk);
15001da177e4SLinus Torvalds 	return err;
15011da177e4SLinus Torvalds }
15021da177e4SLinus Torvalds 
15038fc9ced3SGustavo Padovan static int hci_sock_getsockopt(struct socket *sock, int level, int optname,
15048fc9ced3SGustavo Padovan 			       char __user *optval, int __user *optlen)
15051da177e4SLinus Torvalds {
15061da177e4SLinus Torvalds 	struct hci_ufilter uf;
15071da177e4SLinus Torvalds 	struct sock *sk = sock->sk;
1508cedc5469SMarcel Holtmann 	int len, opt, err = 0;
1509cedc5469SMarcel Holtmann 
1510cedc5469SMarcel Holtmann 	BT_DBG("sk %p, opt %d", sk, optname);
15111da177e4SLinus Torvalds 
15121da177e4SLinus Torvalds 	if (get_user(len, optlen))
15131da177e4SLinus Torvalds 		return -EFAULT;
15141da177e4SLinus Torvalds 
1515cedc5469SMarcel Holtmann 	lock_sock(sk);
1516cedc5469SMarcel Holtmann 
1517cedc5469SMarcel Holtmann 	if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) {
1518c2371e80SMarcel Holtmann 		err = -EBADFD;
1519cedc5469SMarcel Holtmann 		goto done;
1520cedc5469SMarcel Holtmann 	}
1521cedc5469SMarcel Holtmann 
15221da177e4SLinus Torvalds 	switch (optname) {
15231da177e4SLinus Torvalds 	case HCI_DATA_DIR:
15241da177e4SLinus Torvalds 		if (hci_pi(sk)->cmsg_mask & HCI_CMSG_DIR)
15251da177e4SLinus Torvalds 			opt = 1;
15261da177e4SLinus Torvalds 		else
15271da177e4SLinus Torvalds 			opt = 0;
15281da177e4SLinus Torvalds 
15291da177e4SLinus Torvalds 		if (put_user(opt, optval))
1530cedc5469SMarcel Holtmann 			err = -EFAULT;
15311da177e4SLinus Torvalds 		break;
15321da177e4SLinus Torvalds 
15331da177e4SLinus Torvalds 	case HCI_TIME_STAMP:
15341da177e4SLinus Torvalds 		if (hci_pi(sk)->cmsg_mask & HCI_CMSG_TSTAMP)
15351da177e4SLinus Torvalds 			opt = 1;
15361da177e4SLinus Torvalds 		else
15371da177e4SLinus Torvalds 			opt = 0;
15381da177e4SLinus Torvalds 
15391da177e4SLinus Torvalds 		if (put_user(opt, optval))
1540cedc5469SMarcel Holtmann 			err = -EFAULT;
15411da177e4SLinus Torvalds 		break;
15421da177e4SLinus Torvalds 
15431da177e4SLinus Torvalds 	case HCI_FILTER:
15441da177e4SLinus Torvalds 		{
15451da177e4SLinus Torvalds 			struct hci_filter *f = &hci_pi(sk)->filter;
15461da177e4SLinus Torvalds 
1547e15ca9a0SMathias Krause 			memset(&uf, 0, sizeof(uf));
15481da177e4SLinus Torvalds 			uf.type_mask = f->type_mask;
15491da177e4SLinus Torvalds 			uf.opcode    = f->opcode;
15501da177e4SLinus Torvalds 			uf.event_mask[0] = *((u32 *) f->event_mask + 0);
15511da177e4SLinus Torvalds 			uf.event_mask[1] = *((u32 *) f->event_mask + 1);
15521da177e4SLinus Torvalds 		}
15531da177e4SLinus Torvalds 
15541da177e4SLinus Torvalds 		len = min_t(unsigned int, len, sizeof(uf));
15551da177e4SLinus Torvalds 		if (copy_to_user(optval, &uf, len))
1556cedc5469SMarcel Holtmann 			err = -EFAULT;
15571da177e4SLinus Torvalds 		break;
15581da177e4SLinus Torvalds 
15591da177e4SLinus Torvalds 	default:
1560cedc5469SMarcel Holtmann 		err = -ENOPROTOOPT;
15611da177e4SLinus Torvalds 		break;
15621da177e4SLinus Torvalds 	}
15631da177e4SLinus Torvalds 
1564cedc5469SMarcel Holtmann done:
1565cedc5469SMarcel Holtmann 	release_sock(sk);
1566cedc5469SMarcel Holtmann 	return err;
15671da177e4SLinus Torvalds }
15681da177e4SLinus Torvalds 
156990ddc4f0SEric Dumazet static const struct proto_ops hci_sock_ops = {
15701da177e4SLinus Torvalds 	.family		= PF_BLUETOOTH,
15711da177e4SLinus Torvalds 	.owner		= THIS_MODULE,
15721da177e4SLinus Torvalds 	.release	= hci_sock_release,
15731da177e4SLinus Torvalds 	.bind		= hci_sock_bind,
15741da177e4SLinus Torvalds 	.getname	= hci_sock_getname,
15751da177e4SLinus Torvalds 	.sendmsg	= hci_sock_sendmsg,
15761da177e4SLinus Torvalds 	.recvmsg	= hci_sock_recvmsg,
15771da177e4SLinus Torvalds 	.ioctl		= hci_sock_ioctl,
15781da177e4SLinus Torvalds 	.poll		= datagram_poll,
15791da177e4SLinus Torvalds 	.listen		= sock_no_listen,
15801da177e4SLinus Torvalds 	.shutdown	= sock_no_shutdown,
15811da177e4SLinus Torvalds 	.setsockopt	= hci_sock_setsockopt,
15821da177e4SLinus Torvalds 	.getsockopt	= hci_sock_getsockopt,
15831da177e4SLinus Torvalds 	.connect	= sock_no_connect,
15841da177e4SLinus Torvalds 	.socketpair	= sock_no_socketpair,
15851da177e4SLinus Torvalds 	.accept		= sock_no_accept,
15861da177e4SLinus Torvalds 	.mmap		= sock_no_mmap
15871da177e4SLinus Torvalds };
15881da177e4SLinus Torvalds 
15891da177e4SLinus Torvalds static struct proto hci_sk_proto = {
15901da177e4SLinus Torvalds 	.name		= "HCI",
15911da177e4SLinus Torvalds 	.owner		= THIS_MODULE,
15921da177e4SLinus Torvalds 	.obj_size	= sizeof(struct hci_pinfo)
15931da177e4SLinus Torvalds };
15941da177e4SLinus Torvalds 
15953f378b68SEric Paris static int hci_sock_create(struct net *net, struct socket *sock, int protocol,
15963f378b68SEric Paris 			   int kern)
15971da177e4SLinus Torvalds {
15981da177e4SLinus Torvalds 	struct sock *sk;
15991da177e4SLinus Torvalds 
16001da177e4SLinus Torvalds 	BT_DBG("sock %p", sock);
16011da177e4SLinus Torvalds 
16021da177e4SLinus Torvalds 	if (sock->type != SOCK_RAW)
16031da177e4SLinus Torvalds 		return -ESOCKTNOSUPPORT;
16041da177e4SLinus Torvalds 
16051da177e4SLinus Torvalds 	sock->ops = &hci_sock_ops;
16061da177e4SLinus Torvalds 
160711aa9c28SEric W. Biederman 	sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &hci_sk_proto, kern);
16081da177e4SLinus Torvalds 	if (!sk)
16091da177e4SLinus Torvalds 		return -ENOMEM;
16101da177e4SLinus Torvalds 
16111da177e4SLinus Torvalds 	sock_init_data(sock, sk);
16121da177e4SLinus Torvalds 
16131da177e4SLinus Torvalds 	sock_reset_flag(sk, SOCK_ZAPPED);
16141da177e4SLinus Torvalds 
16151da177e4SLinus Torvalds 	sk->sk_protocol = protocol;
16161da177e4SLinus Torvalds 
16171da177e4SLinus Torvalds 	sock->state = SS_UNCONNECTED;
16181da177e4SLinus Torvalds 	sk->sk_state = BT_OPEN;
16191da177e4SLinus Torvalds 
16201da177e4SLinus Torvalds 	bt_sock_link(&hci_sk_list, sk);
16211da177e4SLinus Torvalds 	return 0;
16221da177e4SLinus Torvalds }
16231da177e4SLinus Torvalds 
1624ec1b4cf7SStephen Hemminger static const struct net_proto_family hci_sock_family_ops = {
16251da177e4SLinus Torvalds 	.family	= PF_BLUETOOTH,
16261da177e4SLinus Torvalds 	.owner	= THIS_MODULE,
16271da177e4SLinus Torvalds 	.create	= hci_sock_create,
16281da177e4SLinus Torvalds };
16291da177e4SLinus Torvalds 
16301da177e4SLinus Torvalds int __init hci_sock_init(void)
16311da177e4SLinus Torvalds {
16321da177e4SLinus Torvalds 	int err;
16331da177e4SLinus Torvalds 
1634b0a8e282SMarcel Holtmann 	BUILD_BUG_ON(sizeof(struct sockaddr_hci) > sizeof(struct sockaddr));
1635b0a8e282SMarcel Holtmann 
16361da177e4SLinus Torvalds 	err = proto_register(&hci_sk_proto, 0);
16371da177e4SLinus Torvalds 	if (err < 0)
16381da177e4SLinus Torvalds 		return err;
16391da177e4SLinus Torvalds 
16401da177e4SLinus Torvalds 	err = bt_sock_register(BTPROTO_HCI, &hci_sock_family_ops);
1641f7c86637SMasatake YAMATO 	if (err < 0) {
1642f7c86637SMasatake YAMATO 		BT_ERR("HCI socket registration failed");
16431da177e4SLinus Torvalds 		goto error;
1644f7c86637SMasatake YAMATO 	}
1645f7c86637SMasatake YAMATO 
1646b0316615SAl Viro 	err = bt_procfs_init(&init_net, "hci", &hci_sk_list, NULL);
1647f7c86637SMasatake YAMATO 	if (err < 0) {
1648f7c86637SMasatake YAMATO 		BT_ERR("Failed to create HCI proc file");
1649f7c86637SMasatake YAMATO 		bt_sock_unregister(BTPROTO_HCI);
1650f7c86637SMasatake YAMATO 		goto error;
1651f7c86637SMasatake YAMATO 	}
16521da177e4SLinus Torvalds 
16531da177e4SLinus Torvalds 	BT_INFO("HCI socket layer initialized");
16541da177e4SLinus Torvalds 
16551da177e4SLinus Torvalds 	return 0;
16561da177e4SLinus Torvalds 
16571da177e4SLinus Torvalds error:
16581da177e4SLinus Torvalds 	proto_unregister(&hci_sk_proto);
16591da177e4SLinus Torvalds 	return err;
16601da177e4SLinus Torvalds }
16611da177e4SLinus Torvalds 
1662b7440a14SAnand Gadiyar void hci_sock_cleanup(void)
16631da177e4SLinus Torvalds {
1664f7c86637SMasatake YAMATO 	bt_procfs_cleanup(&init_net, "hci");
16655e9d7f86SDavid Herrmann 	bt_sock_unregister(BTPROTO_HCI);
16661da177e4SLinus Torvalds 	proto_unregister(&hci_sk_proto);
16671da177e4SLinus Torvalds }
1668