xref: /openbmc/linux/net/bluetooth/hci_sock.c (revision 1195fbb8d03e5a6d7e7e49a73592caeb113a0f70)
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>
291da177e4SLinus Torvalds 
301da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h>
311da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h>
32cd82e61cSMarcel Holtmann #include <net/bluetooth/hci_mon.h>
331da177e4SLinus Torvalds 
34801c1e8dSJohan Hedberg static LIST_HEAD(mgmt_chan_list);
35801c1e8dSJohan Hedberg static DEFINE_MUTEX(mgmt_chan_list_lock);
36801c1e8dSJohan Hedberg 
37cd82e61cSMarcel Holtmann static atomic_t monitor_promisc = ATOMIC_INIT(0);
38cd82e61cSMarcel Holtmann 
391da177e4SLinus Torvalds /* ----- HCI socket interface ----- */
401da177e4SLinus Torvalds 
41863def58SMarcel Holtmann /* Socket info */
42863def58SMarcel Holtmann #define hci_pi(sk) ((struct hci_pinfo *) sk)
43863def58SMarcel Holtmann 
44863def58SMarcel Holtmann struct hci_pinfo {
45863def58SMarcel Holtmann 	struct bt_sock    bt;
46863def58SMarcel Holtmann 	struct hci_dev    *hdev;
47863def58SMarcel Holtmann 	struct hci_filter filter;
48863def58SMarcel Holtmann 	__u32             cmsg_mask;
49863def58SMarcel Holtmann 	unsigned short    channel;
506befc644SMarcel Holtmann 	unsigned long     flags;
51863def58SMarcel Holtmann };
52863def58SMarcel Holtmann 
536befc644SMarcel Holtmann void hci_sock_set_flag(struct sock *sk, int nr)
546befc644SMarcel Holtmann {
556befc644SMarcel Holtmann 	set_bit(nr, &hci_pi(sk)->flags);
566befc644SMarcel Holtmann }
576befc644SMarcel Holtmann 
586befc644SMarcel Holtmann void hci_sock_clear_flag(struct sock *sk, int nr)
596befc644SMarcel Holtmann {
606befc644SMarcel Holtmann 	clear_bit(nr, &hci_pi(sk)->flags);
616befc644SMarcel Holtmann }
626befc644SMarcel Holtmann 
63c85be545SMarcel Holtmann int hci_sock_test_flag(struct sock *sk, int nr)
64c85be545SMarcel Holtmann {
65c85be545SMarcel Holtmann 	return test_bit(nr, &hci_pi(sk)->flags);
66c85be545SMarcel Holtmann }
67c85be545SMarcel Holtmann 
689391976aSJiri Slaby static inline int hci_test_bit(int nr, const void *addr)
691da177e4SLinus Torvalds {
709391976aSJiri Slaby 	return *((const __u32 *) addr + (nr >> 5)) & ((__u32) 1 << (nr & 31));
711da177e4SLinus Torvalds }
721da177e4SLinus Torvalds 
731da177e4SLinus Torvalds /* Security filter */
743ad254f7SMarcel Holtmann #define HCI_SFLT_MAX_OGF  5
753ad254f7SMarcel Holtmann 
763ad254f7SMarcel Holtmann struct hci_sec_filter {
773ad254f7SMarcel Holtmann 	__u32 type_mask;
783ad254f7SMarcel Holtmann 	__u32 event_mask[2];
793ad254f7SMarcel Holtmann 	__u32 ocf_mask[HCI_SFLT_MAX_OGF + 1][4];
803ad254f7SMarcel Holtmann };
813ad254f7SMarcel Holtmann 
827e67c112SMarcel Holtmann static const struct hci_sec_filter hci_sec_filter = {
831da177e4SLinus Torvalds 	/* Packet types */
841da177e4SLinus Torvalds 	0x10,
851da177e4SLinus Torvalds 	/* Events */
86dd7f5527SMarcel Holtmann 	{ 0x1000d9fe, 0x0000b00c },
871da177e4SLinus Torvalds 	/* Commands */
881da177e4SLinus Torvalds 	{
891da177e4SLinus Torvalds 		{ 0x0 },
901da177e4SLinus Torvalds 		/* OGF_LINK_CTL */
917c631a67SMarcel Holtmann 		{ 0xbe000006, 0x00000001, 0x00000000, 0x00 },
921da177e4SLinus Torvalds 		/* OGF_LINK_POLICY */
937c631a67SMarcel Holtmann 		{ 0x00005200, 0x00000000, 0x00000000, 0x00 },
941da177e4SLinus Torvalds 		/* OGF_HOST_CTL */
957c631a67SMarcel Holtmann 		{ 0xaab00200, 0x2b402aaa, 0x05220154, 0x00 },
961da177e4SLinus Torvalds 		/* OGF_INFO_PARAM */
977c631a67SMarcel Holtmann 		{ 0x000002be, 0x00000000, 0x00000000, 0x00 },
981da177e4SLinus Torvalds 		/* OGF_STATUS_PARAM */
997c631a67SMarcel Holtmann 		{ 0x000000ea, 0x00000000, 0x00000000, 0x00 }
1001da177e4SLinus Torvalds 	}
1011da177e4SLinus Torvalds };
1021da177e4SLinus Torvalds 
1031da177e4SLinus Torvalds static struct bt_sock_list hci_sk_list = {
104d5fb2962SRobert P. J. Day 	.lock = __RW_LOCK_UNLOCKED(hci_sk_list.lock)
1051da177e4SLinus Torvalds };
1061da177e4SLinus Torvalds 
107f81fe64fSMarcel Holtmann static bool is_filtered_packet(struct sock *sk, struct sk_buff *skb)
108f81fe64fSMarcel Holtmann {
109f81fe64fSMarcel Holtmann 	struct hci_filter *flt;
110f81fe64fSMarcel Holtmann 	int flt_type, flt_event;
111f81fe64fSMarcel Holtmann 
112f81fe64fSMarcel Holtmann 	/* Apply filter */
113f81fe64fSMarcel Holtmann 	flt = &hci_pi(sk)->filter;
114f81fe64fSMarcel Holtmann 
115f81fe64fSMarcel Holtmann 	if (bt_cb(skb)->pkt_type == HCI_VENDOR_PKT)
116f81fe64fSMarcel Holtmann 		flt_type = 0;
117f81fe64fSMarcel Holtmann 	else
118f81fe64fSMarcel Holtmann 		flt_type = bt_cb(skb)->pkt_type & HCI_FLT_TYPE_BITS;
119f81fe64fSMarcel Holtmann 
120f81fe64fSMarcel Holtmann 	if (!test_bit(flt_type, &flt->type_mask))
121f81fe64fSMarcel Holtmann 		return true;
122f81fe64fSMarcel Holtmann 
123f81fe64fSMarcel Holtmann 	/* Extra filter for event packets only */
124f81fe64fSMarcel Holtmann 	if (bt_cb(skb)->pkt_type != HCI_EVENT_PKT)
125f81fe64fSMarcel Holtmann 		return false;
126f81fe64fSMarcel Holtmann 
127f81fe64fSMarcel Holtmann 	flt_event = (*(__u8 *)skb->data & HCI_FLT_EVENT_BITS);
128f81fe64fSMarcel Holtmann 
129f81fe64fSMarcel Holtmann 	if (!hci_test_bit(flt_event, &flt->event_mask))
130f81fe64fSMarcel Holtmann 		return true;
131f81fe64fSMarcel Holtmann 
132f81fe64fSMarcel Holtmann 	/* Check filter only when opcode is set */
133f81fe64fSMarcel Holtmann 	if (!flt->opcode)
134f81fe64fSMarcel Holtmann 		return false;
135f81fe64fSMarcel Holtmann 
136f81fe64fSMarcel Holtmann 	if (flt_event == HCI_EV_CMD_COMPLETE &&
137f81fe64fSMarcel Holtmann 	    flt->opcode != get_unaligned((__le16 *)(skb->data + 3)))
138f81fe64fSMarcel Holtmann 		return true;
139f81fe64fSMarcel Holtmann 
140f81fe64fSMarcel Holtmann 	if (flt_event == HCI_EV_CMD_STATUS &&
141f81fe64fSMarcel Holtmann 	    flt->opcode != get_unaligned((__le16 *)(skb->data + 4)))
142f81fe64fSMarcel Holtmann 		return true;
143f81fe64fSMarcel Holtmann 
144f81fe64fSMarcel Holtmann 	return false;
145f81fe64fSMarcel Holtmann }
146f81fe64fSMarcel Holtmann 
1471da177e4SLinus Torvalds /* Send frame to RAW socket */
148470fe1b5SMarcel Holtmann void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
1491da177e4SLinus Torvalds {
1501da177e4SLinus Torvalds 	struct sock *sk;
151e0edf373SMarcel Holtmann 	struct sk_buff *skb_copy = NULL;
1521da177e4SLinus Torvalds 
1531da177e4SLinus Torvalds 	BT_DBG("hdev %p len %d", hdev, skb->len);
1541da177e4SLinus Torvalds 
1551da177e4SLinus Torvalds 	read_lock(&hci_sk_list.lock);
156470fe1b5SMarcel Holtmann 
157b67bfe0dSSasha Levin 	sk_for_each(sk, &hci_sk_list.head) {
1581da177e4SLinus Torvalds 		struct sk_buff *nskb;
1591da177e4SLinus Torvalds 
1601da177e4SLinus Torvalds 		if (sk->sk_state != BT_BOUND || hci_pi(sk)->hdev != hdev)
1611da177e4SLinus Torvalds 			continue;
1621da177e4SLinus Torvalds 
1631da177e4SLinus Torvalds 		/* Don't send frame to the socket it came from */
1641da177e4SLinus Torvalds 		if (skb->sk == sk)
1651da177e4SLinus Torvalds 			continue;
1661da177e4SLinus Torvalds 
16723500189SMarcel Holtmann 		if (hci_pi(sk)->channel == HCI_CHANNEL_RAW) {
168f81fe64fSMarcel Holtmann 			if (is_filtered_packet(sk, skb))
1691da177e4SLinus Torvalds 				continue;
17023500189SMarcel Holtmann 		} else if (hci_pi(sk)->channel == HCI_CHANNEL_USER) {
17123500189SMarcel Holtmann 			if (!bt_cb(skb)->incoming)
17223500189SMarcel Holtmann 				continue;
17323500189SMarcel Holtmann 			if (bt_cb(skb)->pkt_type != HCI_EVENT_PKT &&
17423500189SMarcel Holtmann 			    bt_cb(skb)->pkt_type != HCI_ACLDATA_PKT &&
17523500189SMarcel Holtmann 			    bt_cb(skb)->pkt_type != HCI_SCODATA_PKT)
17623500189SMarcel Holtmann 				continue;
17723500189SMarcel Holtmann 		} else {
17823500189SMarcel Holtmann 			/* Don't send frame to other channel types */
17923500189SMarcel Holtmann 			continue;
18023500189SMarcel Holtmann 		}
1811da177e4SLinus Torvalds 
182e0edf373SMarcel Holtmann 		if (!skb_copy) {
183e0edf373SMarcel Holtmann 			/* Create a private copy with headroom */
184bad93e9dSOctavian Purdila 			skb_copy = __pskb_copy_fclone(skb, 1, GFP_ATOMIC, true);
185e0edf373SMarcel Holtmann 			if (!skb_copy)
1861da177e4SLinus Torvalds 				continue;
1871da177e4SLinus Torvalds 
1881da177e4SLinus Torvalds 			/* Put type byte before the data */
189e0edf373SMarcel Holtmann 			memcpy(skb_push(skb_copy, 1), &bt_cb(skb)->pkt_type, 1);
190e0edf373SMarcel Holtmann 		}
191e0edf373SMarcel Holtmann 
192e0edf373SMarcel Holtmann 		nskb = skb_clone(skb_copy, GFP_ATOMIC);
193e0edf373SMarcel Holtmann 		if (!nskb)
194e0edf373SMarcel Holtmann 			continue;
1951da177e4SLinus Torvalds 
1961da177e4SLinus Torvalds 		if (sock_queue_rcv_skb(sk, nskb))
1971da177e4SLinus Torvalds 			kfree_skb(nskb);
1981da177e4SLinus Torvalds 	}
199470fe1b5SMarcel Holtmann 
200470fe1b5SMarcel Holtmann 	read_unlock(&hci_sk_list.lock);
201e0edf373SMarcel Holtmann 
202e0edf373SMarcel Holtmann 	kfree_skb(skb_copy);
203470fe1b5SMarcel Holtmann }
204470fe1b5SMarcel Holtmann 
2057129069eSJohan Hedberg /* Send frame to sockets with specific channel */
2067129069eSJohan Hedberg void hci_send_to_channel(unsigned short channel, struct sk_buff *skb,
207c08b1a1dSMarcel Holtmann 			 int flag, struct sock *skip_sk)
208470fe1b5SMarcel Holtmann {
209470fe1b5SMarcel Holtmann 	struct sock *sk;
210470fe1b5SMarcel Holtmann 
2117129069eSJohan Hedberg 	BT_DBG("channel %u len %d", channel, skb->len);
212470fe1b5SMarcel Holtmann 
213470fe1b5SMarcel Holtmann 	read_lock(&hci_sk_list.lock);
214470fe1b5SMarcel Holtmann 
215b67bfe0dSSasha Levin 	sk_for_each(sk, &hci_sk_list.head) {
216470fe1b5SMarcel Holtmann 		struct sk_buff *nskb;
217470fe1b5SMarcel Holtmann 
218c08b1a1dSMarcel Holtmann 		/* Ignore socket without the flag set */
219c85be545SMarcel Holtmann 		if (!hci_sock_test_flag(sk, flag))
220c08b1a1dSMarcel Holtmann 			continue;
221c08b1a1dSMarcel Holtmann 
222470fe1b5SMarcel Holtmann 		/* Skip the original socket */
223470fe1b5SMarcel Holtmann 		if (sk == skip_sk)
224470fe1b5SMarcel Holtmann 			continue;
225470fe1b5SMarcel Holtmann 
226470fe1b5SMarcel Holtmann 		if (sk->sk_state != BT_BOUND)
227470fe1b5SMarcel Holtmann 			continue;
228470fe1b5SMarcel Holtmann 
2297129069eSJohan Hedberg 		if (hci_pi(sk)->channel != channel)
230d7f72f61SMarcel Holtmann 			continue;
231d7f72f61SMarcel Holtmann 
232d7f72f61SMarcel Holtmann 		nskb = skb_clone(skb, GFP_ATOMIC);
233d7f72f61SMarcel Holtmann 		if (!nskb)
234d7f72f61SMarcel Holtmann 			continue;
235d7f72f61SMarcel Holtmann 
236d7f72f61SMarcel Holtmann 		if (sock_queue_rcv_skb(sk, nskb))
237d7f72f61SMarcel Holtmann 			kfree_skb(nskb);
238d7f72f61SMarcel Holtmann 	}
239d7f72f61SMarcel Holtmann 
240d7f72f61SMarcel Holtmann 	read_unlock(&hci_sk_list.lock);
241d7f72f61SMarcel Holtmann }
242d7f72f61SMarcel Holtmann 
243cd82e61cSMarcel Holtmann /* Send frame to monitor socket */
244cd82e61cSMarcel Holtmann void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb)
245cd82e61cSMarcel Holtmann {
246cd82e61cSMarcel Holtmann 	struct sk_buff *skb_copy = NULL;
2472b531294SMarcel Holtmann 	struct hci_mon_hdr *hdr;
248cd82e61cSMarcel Holtmann 	__le16 opcode;
249cd82e61cSMarcel Holtmann 
250cd82e61cSMarcel Holtmann 	if (!atomic_read(&monitor_promisc))
251cd82e61cSMarcel Holtmann 		return;
252cd82e61cSMarcel Holtmann 
253cd82e61cSMarcel Holtmann 	BT_DBG("hdev %p len %d", hdev, skb->len);
254cd82e61cSMarcel Holtmann 
255cd82e61cSMarcel Holtmann 	switch (bt_cb(skb)->pkt_type) {
256cd82e61cSMarcel Holtmann 	case HCI_COMMAND_PKT:
257dcf4adbfSJoe Perches 		opcode = cpu_to_le16(HCI_MON_COMMAND_PKT);
258cd82e61cSMarcel Holtmann 		break;
259cd82e61cSMarcel Holtmann 	case HCI_EVENT_PKT:
260dcf4adbfSJoe Perches 		opcode = cpu_to_le16(HCI_MON_EVENT_PKT);
261cd82e61cSMarcel Holtmann 		break;
262cd82e61cSMarcel Holtmann 	case HCI_ACLDATA_PKT:
263cd82e61cSMarcel Holtmann 		if (bt_cb(skb)->incoming)
264dcf4adbfSJoe Perches 			opcode = cpu_to_le16(HCI_MON_ACL_RX_PKT);
265cd82e61cSMarcel Holtmann 		else
266dcf4adbfSJoe Perches 			opcode = cpu_to_le16(HCI_MON_ACL_TX_PKT);
267cd82e61cSMarcel Holtmann 		break;
268cd82e61cSMarcel Holtmann 	case HCI_SCODATA_PKT:
269cd82e61cSMarcel Holtmann 		if (bt_cb(skb)->incoming)
270dcf4adbfSJoe Perches 			opcode = cpu_to_le16(HCI_MON_SCO_RX_PKT);
271cd82e61cSMarcel Holtmann 		else
272dcf4adbfSJoe Perches 			opcode = cpu_to_le16(HCI_MON_SCO_TX_PKT);
273cd82e61cSMarcel Holtmann 		break;
274cd82e61cSMarcel Holtmann 	default:
275cd82e61cSMarcel Holtmann 		return;
276cd82e61cSMarcel Holtmann 	}
277cd82e61cSMarcel Holtmann 
2782b531294SMarcel Holtmann 	/* Create a private copy with headroom */
2792b531294SMarcel Holtmann 	skb_copy = __pskb_copy_fclone(skb, HCI_MON_HDR_SIZE, GFP_ATOMIC, true);
2802b531294SMarcel Holtmann 	if (!skb_copy)
2812b531294SMarcel Holtmann 		return;
2822b531294SMarcel Holtmann 
2832b531294SMarcel Holtmann 	/* Put header before the data */
2842b531294SMarcel Holtmann 	hdr = (void *) skb_push(skb_copy, HCI_MON_HDR_SIZE);
2852b531294SMarcel Holtmann 	hdr->opcode = opcode;
2862b531294SMarcel Holtmann 	hdr->index = cpu_to_le16(hdev->id);
2872b531294SMarcel Holtmann 	hdr->len = cpu_to_le16(skb->len);
2882b531294SMarcel Holtmann 
289c08b1a1dSMarcel Holtmann 	hci_send_to_channel(HCI_CHANNEL_MONITOR, skb_copy,
290c08b1a1dSMarcel Holtmann 			    HCI_SOCK_TRUSTED, NULL);
291cd82e61cSMarcel Holtmann 	kfree_skb(skb_copy);
292cd82e61cSMarcel Holtmann }
293cd82e61cSMarcel Holtmann 
294cd82e61cSMarcel Holtmann static struct sk_buff *create_monitor_event(struct hci_dev *hdev, int event)
295cd82e61cSMarcel Holtmann {
296cd82e61cSMarcel Holtmann 	struct hci_mon_hdr *hdr;
297cd82e61cSMarcel Holtmann 	struct hci_mon_new_index *ni;
298cd82e61cSMarcel Holtmann 	struct sk_buff *skb;
299cd82e61cSMarcel Holtmann 	__le16 opcode;
300cd82e61cSMarcel Holtmann 
301cd82e61cSMarcel Holtmann 	switch (event) {
302cd82e61cSMarcel Holtmann 	case HCI_DEV_REG:
303cd82e61cSMarcel Holtmann 		skb = bt_skb_alloc(HCI_MON_NEW_INDEX_SIZE, GFP_ATOMIC);
304cd82e61cSMarcel Holtmann 		if (!skb)
305cd82e61cSMarcel Holtmann 			return NULL;
306cd82e61cSMarcel Holtmann 
307cd82e61cSMarcel Holtmann 		ni = (void *) skb_put(skb, HCI_MON_NEW_INDEX_SIZE);
308cd82e61cSMarcel Holtmann 		ni->type = hdev->dev_type;
309cd82e61cSMarcel Holtmann 		ni->bus = hdev->bus;
310cd82e61cSMarcel Holtmann 		bacpy(&ni->bdaddr, &hdev->bdaddr);
311cd82e61cSMarcel Holtmann 		memcpy(ni->name, hdev->name, 8);
312cd82e61cSMarcel Holtmann 
313dcf4adbfSJoe Perches 		opcode = cpu_to_le16(HCI_MON_NEW_INDEX);
314cd82e61cSMarcel Holtmann 		break;
315cd82e61cSMarcel Holtmann 
316cd82e61cSMarcel Holtmann 	case HCI_DEV_UNREG:
317cd82e61cSMarcel Holtmann 		skb = bt_skb_alloc(0, GFP_ATOMIC);
318cd82e61cSMarcel Holtmann 		if (!skb)
319cd82e61cSMarcel Holtmann 			return NULL;
320cd82e61cSMarcel Holtmann 
321dcf4adbfSJoe Perches 		opcode = cpu_to_le16(HCI_MON_DEL_INDEX);
322cd82e61cSMarcel Holtmann 		break;
323cd82e61cSMarcel Holtmann 
324cd82e61cSMarcel Holtmann 	default:
325cd82e61cSMarcel Holtmann 		return NULL;
326cd82e61cSMarcel Holtmann 	}
327cd82e61cSMarcel Holtmann 
328cd82e61cSMarcel Holtmann 	__net_timestamp(skb);
329cd82e61cSMarcel Holtmann 
330cd82e61cSMarcel Holtmann 	hdr = (void *) skb_push(skb, HCI_MON_HDR_SIZE);
331cd82e61cSMarcel Holtmann 	hdr->opcode = opcode;
332cd82e61cSMarcel Holtmann 	hdr->index = cpu_to_le16(hdev->id);
333cd82e61cSMarcel Holtmann 	hdr->len = cpu_to_le16(skb->len - HCI_MON_HDR_SIZE);
334cd82e61cSMarcel Holtmann 
335cd82e61cSMarcel Holtmann 	return skb;
336cd82e61cSMarcel Holtmann }
337cd82e61cSMarcel Holtmann 
338cd82e61cSMarcel Holtmann static void send_monitor_replay(struct sock *sk)
339cd82e61cSMarcel Holtmann {
340cd82e61cSMarcel Holtmann 	struct hci_dev *hdev;
341cd82e61cSMarcel Holtmann 
342cd82e61cSMarcel Holtmann 	read_lock(&hci_dev_list_lock);
343cd82e61cSMarcel Holtmann 
344cd82e61cSMarcel Holtmann 	list_for_each_entry(hdev, &hci_dev_list, list) {
345cd82e61cSMarcel Holtmann 		struct sk_buff *skb;
346cd82e61cSMarcel Holtmann 
347cd82e61cSMarcel Holtmann 		skb = create_monitor_event(hdev, HCI_DEV_REG);
348cd82e61cSMarcel Holtmann 		if (!skb)
349cd82e61cSMarcel Holtmann 			continue;
350cd82e61cSMarcel Holtmann 
351cd82e61cSMarcel Holtmann 		if (sock_queue_rcv_skb(sk, skb))
352cd82e61cSMarcel Holtmann 			kfree_skb(skb);
353cd82e61cSMarcel Holtmann 	}
354cd82e61cSMarcel Holtmann 
355cd82e61cSMarcel Holtmann 	read_unlock(&hci_dev_list_lock);
356cd82e61cSMarcel Holtmann }
357cd82e61cSMarcel Holtmann 
358040030efSMarcel Holtmann /* Generate internal stack event */
359040030efSMarcel Holtmann static void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
360040030efSMarcel Holtmann {
361040030efSMarcel Holtmann 	struct hci_event_hdr *hdr;
362040030efSMarcel Holtmann 	struct hci_ev_stack_internal *ev;
363040030efSMarcel Holtmann 	struct sk_buff *skb;
364040030efSMarcel Holtmann 
365040030efSMarcel Holtmann 	skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
366040030efSMarcel Holtmann 	if (!skb)
367040030efSMarcel Holtmann 		return;
368040030efSMarcel Holtmann 
369040030efSMarcel Holtmann 	hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
370040030efSMarcel Holtmann 	hdr->evt  = HCI_EV_STACK_INTERNAL;
371040030efSMarcel Holtmann 	hdr->plen = sizeof(*ev) + dlen;
372040030efSMarcel Holtmann 
373040030efSMarcel Holtmann 	ev  = (void *) skb_put(skb, sizeof(*ev) + dlen);
374040030efSMarcel Holtmann 	ev->type = type;
375040030efSMarcel Holtmann 	memcpy(ev->data, data, dlen);
376040030efSMarcel Holtmann 
377040030efSMarcel Holtmann 	bt_cb(skb)->incoming = 1;
378040030efSMarcel Holtmann 	__net_timestamp(skb);
379040030efSMarcel Holtmann 
380040030efSMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
381040030efSMarcel Holtmann 	hci_send_to_sock(hdev, skb);
382040030efSMarcel Holtmann 	kfree_skb(skb);
383040030efSMarcel Holtmann }
384040030efSMarcel Holtmann 
385040030efSMarcel Holtmann void hci_sock_dev_event(struct hci_dev *hdev, int event)
386040030efSMarcel Holtmann {
387040030efSMarcel Holtmann 	struct hci_ev_si_device ev;
388040030efSMarcel Holtmann 
389040030efSMarcel Holtmann 	BT_DBG("hdev %s event %d", hdev->name, event);
390040030efSMarcel Holtmann 
391cd82e61cSMarcel Holtmann 	/* Send event to monitor */
392cd82e61cSMarcel Holtmann 	if (atomic_read(&monitor_promisc)) {
393cd82e61cSMarcel Holtmann 		struct sk_buff *skb;
394cd82e61cSMarcel Holtmann 
395cd82e61cSMarcel Holtmann 		skb = create_monitor_event(hdev, event);
396cd82e61cSMarcel Holtmann 		if (skb) {
397c08b1a1dSMarcel Holtmann 			hci_send_to_channel(HCI_CHANNEL_MONITOR, skb,
398c08b1a1dSMarcel Holtmann 					    HCI_SOCK_TRUSTED, NULL);
399cd82e61cSMarcel Holtmann 			kfree_skb(skb);
400cd82e61cSMarcel Holtmann 		}
401cd82e61cSMarcel Holtmann 	}
402cd82e61cSMarcel Holtmann 
403040030efSMarcel Holtmann 	/* Send event to sockets */
404040030efSMarcel Holtmann 	ev.event  = event;
405040030efSMarcel Holtmann 	ev.dev_id = hdev->id;
406040030efSMarcel Holtmann 	hci_si_event(NULL, HCI_EV_SI_DEVICE, sizeof(ev), &ev);
407040030efSMarcel Holtmann 
408040030efSMarcel Holtmann 	if (event == HCI_DEV_UNREG) {
409040030efSMarcel Holtmann 		struct sock *sk;
410040030efSMarcel Holtmann 
411040030efSMarcel Holtmann 		/* Detach sockets from device */
412040030efSMarcel Holtmann 		read_lock(&hci_sk_list.lock);
413b67bfe0dSSasha Levin 		sk_for_each(sk, &hci_sk_list.head) {
414040030efSMarcel Holtmann 			bh_lock_sock_nested(sk);
415040030efSMarcel Holtmann 			if (hci_pi(sk)->hdev == hdev) {
416040030efSMarcel Holtmann 				hci_pi(sk)->hdev = NULL;
417040030efSMarcel Holtmann 				sk->sk_err = EPIPE;
418040030efSMarcel Holtmann 				sk->sk_state = BT_OPEN;
419040030efSMarcel Holtmann 				sk->sk_state_change(sk);
420040030efSMarcel Holtmann 
421040030efSMarcel Holtmann 				hci_dev_put(hdev);
422040030efSMarcel Holtmann 			}
423040030efSMarcel Holtmann 			bh_unlock_sock(sk);
424040030efSMarcel Holtmann 		}
425040030efSMarcel Holtmann 		read_unlock(&hci_sk_list.lock);
426040030efSMarcel Holtmann 	}
427040030efSMarcel Holtmann }
428040030efSMarcel Holtmann 
429801c1e8dSJohan Hedberg static struct hci_mgmt_chan *__hci_mgmt_chan_find(unsigned short channel)
430801c1e8dSJohan Hedberg {
431801c1e8dSJohan Hedberg 	struct hci_mgmt_chan *c;
432801c1e8dSJohan Hedberg 
433801c1e8dSJohan Hedberg 	list_for_each_entry(c, &mgmt_chan_list, list) {
434801c1e8dSJohan Hedberg 		if (c->channel == channel)
435801c1e8dSJohan Hedberg 			return c;
436801c1e8dSJohan Hedberg 	}
437801c1e8dSJohan Hedberg 
438801c1e8dSJohan Hedberg 	return NULL;
439801c1e8dSJohan Hedberg }
440801c1e8dSJohan Hedberg 
441801c1e8dSJohan Hedberg static struct hci_mgmt_chan *hci_mgmt_chan_find(unsigned short channel)
442801c1e8dSJohan Hedberg {
443801c1e8dSJohan Hedberg 	struct hci_mgmt_chan *c;
444801c1e8dSJohan Hedberg 
445801c1e8dSJohan Hedberg 	mutex_lock(&mgmt_chan_list_lock);
446801c1e8dSJohan Hedberg 	c = __hci_mgmt_chan_find(channel);
447801c1e8dSJohan Hedberg 	mutex_unlock(&mgmt_chan_list_lock);
448801c1e8dSJohan Hedberg 
449801c1e8dSJohan Hedberg 	return c;
450801c1e8dSJohan Hedberg }
451801c1e8dSJohan Hedberg 
452801c1e8dSJohan Hedberg int hci_mgmt_chan_register(struct hci_mgmt_chan *c)
453801c1e8dSJohan Hedberg {
454801c1e8dSJohan Hedberg 	if (c->channel < HCI_CHANNEL_CONTROL)
455801c1e8dSJohan Hedberg 		return -EINVAL;
456801c1e8dSJohan Hedberg 
457801c1e8dSJohan Hedberg 	mutex_lock(&mgmt_chan_list_lock);
458801c1e8dSJohan Hedberg 	if (__hci_mgmt_chan_find(c->channel)) {
459801c1e8dSJohan Hedberg 		mutex_unlock(&mgmt_chan_list_lock);
460801c1e8dSJohan Hedberg 		return -EALREADY;
461801c1e8dSJohan Hedberg 	}
462801c1e8dSJohan Hedberg 
463801c1e8dSJohan Hedberg 	list_add_tail(&c->list, &mgmt_chan_list);
464801c1e8dSJohan Hedberg 
465801c1e8dSJohan Hedberg 	mutex_unlock(&mgmt_chan_list_lock);
466801c1e8dSJohan Hedberg 
467801c1e8dSJohan Hedberg 	return 0;
468801c1e8dSJohan Hedberg }
469801c1e8dSJohan Hedberg EXPORT_SYMBOL(hci_mgmt_chan_register);
470801c1e8dSJohan Hedberg 
471801c1e8dSJohan Hedberg void hci_mgmt_chan_unregister(struct hci_mgmt_chan *c)
472801c1e8dSJohan Hedberg {
473801c1e8dSJohan Hedberg 	mutex_lock(&mgmt_chan_list_lock);
474801c1e8dSJohan Hedberg 	list_del(&c->list);
475801c1e8dSJohan Hedberg 	mutex_unlock(&mgmt_chan_list_lock);
476801c1e8dSJohan Hedberg }
477801c1e8dSJohan Hedberg EXPORT_SYMBOL(hci_mgmt_chan_unregister);
478801c1e8dSJohan Hedberg 
4791da177e4SLinus Torvalds static int hci_sock_release(struct socket *sock)
4801da177e4SLinus Torvalds {
4811da177e4SLinus Torvalds 	struct sock *sk = sock->sk;
4827b005bd3SMarcel Holtmann 	struct hci_dev *hdev;
4831da177e4SLinus Torvalds 
4841da177e4SLinus Torvalds 	BT_DBG("sock %p sk %p", sock, sk);
4851da177e4SLinus Torvalds 
4861da177e4SLinus Torvalds 	if (!sk)
4871da177e4SLinus Torvalds 		return 0;
4881da177e4SLinus Torvalds 
4897b005bd3SMarcel Holtmann 	hdev = hci_pi(sk)->hdev;
4907b005bd3SMarcel Holtmann 
491cd82e61cSMarcel Holtmann 	if (hci_pi(sk)->channel == HCI_CHANNEL_MONITOR)
492cd82e61cSMarcel Holtmann 		atomic_dec(&monitor_promisc);
493cd82e61cSMarcel Holtmann 
4941da177e4SLinus Torvalds 	bt_sock_unlink(&hci_sk_list, sk);
4951da177e4SLinus Torvalds 
4961da177e4SLinus Torvalds 	if (hdev) {
49723500189SMarcel Holtmann 		if (hci_pi(sk)->channel == HCI_CHANNEL_USER) {
49823500189SMarcel Holtmann 			mgmt_index_added(hdev);
499a358dc11SMarcel Holtmann 			hci_dev_clear_flag(hdev, HCI_USER_CHANNEL);
50023500189SMarcel Holtmann 			hci_dev_close(hdev->id);
50123500189SMarcel Holtmann 		}
50223500189SMarcel Holtmann 
5031da177e4SLinus Torvalds 		atomic_dec(&hdev->promisc);
5041da177e4SLinus Torvalds 		hci_dev_put(hdev);
5051da177e4SLinus Torvalds 	}
5061da177e4SLinus Torvalds 
5071da177e4SLinus Torvalds 	sock_orphan(sk);
5081da177e4SLinus Torvalds 
5091da177e4SLinus Torvalds 	skb_queue_purge(&sk->sk_receive_queue);
5101da177e4SLinus Torvalds 	skb_queue_purge(&sk->sk_write_queue);
5111da177e4SLinus Torvalds 
5121da177e4SLinus Torvalds 	sock_put(sk);
5131da177e4SLinus Torvalds 	return 0;
5141da177e4SLinus Torvalds }
5151da177e4SLinus Torvalds 
516b2a66aadSAntti Julku static int hci_sock_blacklist_add(struct hci_dev *hdev, void __user *arg)
517f0358568SJohan Hedberg {
518f0358568SJohan Hedberg 	bdaddr_t bdaddr;
5195e762444SAntti Julku 	int err;
520f0358568SJohan Hedberg 
521f0358568SJohan Hedberg 	if (copy_from_user(&bdaddr, arg, sizeof(bdaddr)))
522f0358568SJohan Hedberg 		return -EFAULT;
523f0358568SJohan Hedberg 
52409fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
5255e762444SAntti Julku 
526dcc36c16SJohan Hedberg 	err = hci_bdaddr_list_add(&hdev->blacklist, &bdaddr, BDADDR_BREDR);
5275e762444SAntti Julku 
52809fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
5295e762444SAntti Julku 
5305e762444SAntti Julku 	return err;
531f0358568SJohan Hedberg }
532f0358568SJohan Hedberg 
533b2a66aadSAntti Julku static int hci_sock_blacklist_del(struct hci_dev *hdev, void __user *arg)
534f0358568SJohan Hedberg {
535f0358568SJohan Hedberg 	bdaddr_t bdaddr;
5365e762444SAntti Julku 	int err;
537f0358568SJohan Hedberg 
538f0358568SJohan Hedberg 	if (copy_from_user(&bdaddr, arg, sizeof(bdaddr)))
539f0358568SJohan Hedberg 		return -EFAULT;
540f0358568SJohan Hedberg 
54109fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
5425e762444SAntti Julku 
543dcc36c16SJohan Hedberg 	err = hci_bdaddr_list_del(&hdev->blacklist, &bdaddr, BDADDR_BREDR);
5445e762444SAntti Julku 
54509fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
5465e762444SAntti Julku 
5475e762444SAntti Julku 	return err;
548f0358568SJohan Hedberg }
549f0358568SJohan Hedberg 
5501da177e4SLinus Torvalds /* Ioctls that require bound socket */
5516039aa73SGustavo Padovan static int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd,
5526039aa73SGustavo Padovan 				unsigned long arg)
5531da177e4SLinus Torvalds {
5541da177e4SLinus Torvalds 	struct hci_dev *hdev = hci_pi(sk)->hdev;
5551da177e4SLinus Torvalds 
5561da177e4SLinus Torvalds 	if (!hdev)
5571da177e4SLinus Torvalds 		return -EBADFD;
5581da177e4SLinus Torvalds 
559d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL))
5600736cfa8SMarcel Holtmann 		return -EBUSY;
5610736cfa8SMarcel Holtmann 
562d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
563fee746b0SMarcel Holtmann 		return -EOPNOTSUPP;
564fee746b0SMarcel Holtmann 
5655b69bef5SMarcel Holtmann 	if (hdev->dev_type != HCI_BREDR)
5665b69bef5SMarcel Holtmann 		return -EOPNOTSUPP;
5675b69bef5SMarcel Holtmann 
5681da177e4SLinus Torvalds 	switch (cmd) {
5691da177e4SLinus Torvalds 	case HCISETRAW:
5701da177e4SLinus Torvalds 		if (!capable(CAP_NET_ADMIN))
571bf5b30b8SZhao Hongjiang 			return -EPERM;
572db596681SMarcel Holtmann 		return -EOPNOTSUPP;
5731da177e4SLinus Torvalds 
5741da177e4SLinus Torvalds 	case HCIGETCONNINFO:
5751da177e4SLinus Torvalds 		return hci_get_conn_info(hdev, (void __user *) arg);
5761da177e4SLinus Torvalds 
57740be492fSMarcel Holtmann 	case HCIGETAUTHINFO:
57840be492fSMarcel Holtmann 		return hci_get_auth_info(hdev, (void __user *) arg);
57940be492fSMarcel Holtmann 
580f0358568SJohan Hedberg 	case HCIBLOCKADDR:
581f0358568SJohan Hedberg 		if (!capable(CAP_NET_ADMIN))
582bf5b30b8SZhao Hongjiang 			return -EPERM;
583b2a66aadSAntti Julku 		return hci_sock_blacklist_add(hdev, (void __user *) arg);
584f0358568SJohan Hedberg 
585f0358568SJohan Hedberg 	case HCIUNBLOCKADDR:
586f0358568SJohan Hedberg 		if (!capable(CAP_NET_ADMIN))
587bf5b30b8SZhao Hongjiang 			return -EPERM;
588b2a66aadSAntti Julku 		return hci_sock_blacklist_del(hdev, (void __user *) arg);
5890736cfa8SMarcel Holtmann 	}
590f0358568SJohan Hedberg 
591324d36edSMarcel Holtmann 	return -ENOIOCTLCMD;
5921da177e4SLinus Torvalds }
5931da177e4SLinus Torvalds 
5948fc9ced3SGustavo Padovan static int hci_sock_ioctl(struct socket *sock, unsigned int cmd,
5958fc9ced3SGustavo Padovan 			  unsigned long arg)
5961da177e4SLinus Torvalds {
5971da177e4SLinus Torvalds 	void __user *argp = (void __user *) arg;
5980736cfa8SMarcel Holtmann 	struct sock *sk = sock->sk;
5991da177e4SLinus Torvalds 	int err;
6001da177e4SLinus Torvalds 
6011da177e4SLinus Torvalds 	BT_DBG("cmd %x arg %lx", cmd, arg);
6021da177e4SLinus Torvalds 
603c1c4f956SMarcel Holtmann 	lock_sock(sk);
604c1c4f956SMarcel Holtmann 
605c1c4f956SMarcel Holtmann 	if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) {
606c1c4f956SMarcel Holtmann 		err = -EBADFD;
607c1c4f956SMarcel Holtmann 		goto done;
608c1c4f956SMarcel Holtmann 	}
609c1c4f956SMarcel Holtmann 
610c1c4f956SMarcel Holtmann 	release_sock(sk);
611c1c4f956SMarcel Holtmann 
6121da177e4SLinus Torvalds 	switch (cmd) {
6131da177e4SLinus Torvalds 	case HCIGETDEVLIST:
6141da177e4SLinus Torvalds 		return hci_get_dev_list(argp);
6151da177e4SLinus Torvalds 
6161da177e4SLinus Torvalds 	case HCIGETDEVINFO:
6171da177e4SLinus Torvalds 		return hci_get_dev_info(argp);
6181da177e4SLinus Torvalds 
6191da177e4SLinus Torvalds 	case HCIGETCONNLIST:
6201da177e4SLinus Torvalds 		return hci_get_conn_list(argp);
6211da177e4SLinus Torvalds 
6221da177e4SLinus Torvalds 	case HCIDEVUP:
6231da177e4SLinus Torvalds 		if (!capable(CAP_NET_ADMIN))
624bf5b30b8SZhao Hongjiang 			return -EPERM;
6251da177e4SLinus Torvalds 		return hci_dev_open(arg);
6261da177e4SLinus Torvalds 
6271da177e4SLinus Torvalds 	case HCIDEVDOWN:
6281da177e4SLinus Torvalds 		if (!capable(CAP_NET_ADMIN))
629bf5b30b8SZhao Hongjiang 			return -EPERM;
6301da177e4SLinus Torvalds 		return hci_dev_close(arg);
6311da177e4SLinus Torvalds 
6321da177e4SLinus Torvalds 	case HCIDEVRESET:
6331da177e4SLinus Torvalds 		if (!capable(CAP_NET_ADMIN))
634bf5b30b8SZhao Hongjiang 			return -EPERM;
6351da177e4SLinus Torvalds 		return hci_dev_reset(arg);
6361da177e4SLinus Torvalds 
6371da177e4SLinus Torvalds 	case HCIDEVRESTAT:
6381da177e4SLinus Torvalds 		if (!capable(CAP_NET_ADMIN))
639bf5b30b8SZhao Hongjiang 			return -EPERM;
6401da177e4SLinus Torvalds 		return hci_dev_reset_stat(arg);
6411da177e4SLinus Torvalds 
6421da177e4SLinus Torvalds 	case HCISETSCAN:
6431da177e4SLinus Torvalds 	case HCISETAUTH:
6441da177e4SLinus Torvalds 	case HCISETENCRYPT:
6451da177e4SLinus Torvalds 	case HCISETPTYPE:
6461da177e4SLinus Torvalds 	case HCISETLINKPOL:
6471da177e4SLinus Torvalds 	case HCISETLINKMODE:
6481da177e4SLinus Torvalds 	case HCISETACLMTU:
6491da177e4SLinus Torvalds 	case HCISETSCOMTU:
6501da177e4SLinus Torvalds 		if (!capable(CAP_NET_ADMIN))
651bf5b30b8SZhao Hongjiang 			return -EPERM;
6521da177e4SLinus Torvalds 		return hci_dev_cmd(cmd, argp);
6531da177e4SLinus Torvalds 
6541da177e4SLinus Torvalds 	case HCIINQUIRY:
6551da177e4SLinus Torvalds 		return hci_inquiry(argp);
656c1c4f956SMarcel Holtmann 	}
6571da177e4SLinus Torvalds 
6581da177e4SLinus Torvalds 	lock_sock(sk);
659c1c4f956SMarcel Holtmann 
6601da177e4SLinus Torvalds 	err = hci_sock_bound_ioctl(sk, cmd, arg);
661c1c4f956SMarcel Holtmann 
662c1c4f956SMarcel Holtmann done:
6631da177e4SLinus Torvalds 	release_sock(sk);
6641da177e4SLinus Torvalds 	return err;
6651da177e4SLinus Torvalds }
6661da177e4SLinus Torvalds 
6678fc9ced3SGustavo Padovan static int hci_sock_bind(struct socket *sock, struct sockaddr *addr,
6688fc9ced3SGustavo Padovan 			 int addr_len)
6691da177e4SLinus Torvalds {
6700381101fSJohan Hedberg 	struct sockaddr_hci haddr;
6711da177e4SLinus Torvalds 	struct sock *sk = sock->sk;
6721da177e4SLinus Torvalds 	struct hci_dev *hdev = NULL;
6730381101fSJohan Hedberg 	int len, err = 0;
6741da177e4SLinus Torvalds 
6751da177e4SLinus Torvalds 	BT_DBG("sock %p sk %p", sock, sk);
6761da177e4SLinus Torvalds 
6770381101fSJohan Hedberg 	if (!addr)
6780381101fSJohan Hedberg 		return -EINVAL;
6790381101fSJohan Hedberg 
6800381101fSJohan Hedberg 	memset(&haddr, 0, sizeof(haddr));
6810381101fSJohan Hedberg 	len = min_t(unsigned int, sizeof(haddr), addr_len);
6820381101fSJohan Hedberg 	memcpy(&haddr, addr, len);
6830381101fSJohan Hedberg 
6840381101fSJohan Hedberg 	if (haddr.hci_family != AF_BLUETOOTH)
6850381101fSJohan Hedberg 		return -EINVAL;
6860381101fSJohan Hedberg 
6871da177e4SLinus Torvalds 	lock_sock(sk);
6881da177e4SLinus Torvalds 
6897cc2ade2SMarcel Holtmann 	if (sk->sk_state == BT_BOUND) {
6907cc2ade2SMarcel Holtmann 		err = -EALREADY;
6917cc2ade2SMarcel Holtmann 		goto done;
6927cc2ade2SMarcel Holtmann 	}
6937cc2ade2SMarcel Holtmann 
6947cc2ade2SMarcel Holtmann 	switch (haddr.hci_channel) {
6957cc2ade2SMarcel Holtmann 	case HCI_CHANNEL_RAW:
6967cc2ade2SMarcel Holtmann 		if (hci_pi(sk)->hdev) {
6971da177e4SLinus Torvalds 			err = -EALREADY;
6981da177e4SLinus Torvalds 			goto done;
6991da177e4SLinus Torvalds 		}
7001da177e4SLinus Torvalds 
7010381101fSJohan Hedberg 		if (haddr.hci_dev != HCI_DEV_NONE) {
7020381101fSJohan Hedberg 			hdev = hci_dev_get(haddr.hci_dev);
70370f23020SAndrei Emeltchenko 			if (!hdev) {
7041da177e4SLinus Torvalds 				err = -ENODEV;
7051da177e4SLinus Torvalds 				goto done;
7061da177e4SLinus Torvalds 			}
7071da177e4SLinus Torvalds 
7081da177e4SLinus Torvalds 			atomic_inc(&hdev->promisc);
7091da177e4SLinus Torvalds 		}
7101da177e4SLinus Torvalds 
7111da177e4SLinus Torvalds 		hci_pi(sk)->hdev = hdev;
7127cc2ade2SMarcel Holtmann 		break;
7137cc2ade2SMarcel Holtmann 
71423500189SMarcel Holtmann 	case HCI_CHANNEL_USER:
71523500189SMarcel Holtmann 		if (hci_pi(sk)->hdev) {
71623500189SMarcel Holtmann 			err = -EALREADY;
71723500189SMarcel Holtmann 			goto done;
71823500189SMarcel Holtmann 		}
71923500189SMarcel Holtmann 
72023500189SMarcel Holtmann 		if (haddr.hci_dev == HCI_DEV_NONE) {
72123500189SMarcel Holtmann 			err = -EINVAL;
72223500189SMarcel Holtmann 			goto done;
72323500189SMarcel Holtmann 		}
72423500189SMarcel Holtmann 
72510a8b86fSMarcel Holtmann 		if (!capable(CAP_NET_ADMIN)) {
72623500189SMarcel Holtmann 			err = -EPERM;
72723500189SMarcel Holtmann 			goto done;
72823500189SMarcel Holtmann 		}
72923500189SMarcel Holtmann 
73023500189SMarcel Holtmann 		hdev = hci_dev_get(haddr.hci_dev);
73123500189SMarcel Holtmann 		if (!hdev) {
73223500189SMarcel Holtmann 			err = -ENODEV;
73323500189SMarcel Holtmann 			goto done;
73423500189SMarcel Holtmann 		}
73523500189SMarcel Holtmann 
73623500189SMarcel Holtmann 		if (test_bit(HCI_UP, &hdev->flags) ||
73723500189SMarcel Holtmann 		    test_bit(HCI_INIT, &hdev->flags) ||
738d7a5a11dSMarcel Holtmann 		    hci_dev_test_flag(hdev, HCI_SETUP) ||
739d7a5a11dSMarcel Holtmann 		    hci_dev_test_flag(hdev, HCI_CONFIG)) {
74023500189SMarcel Holtmann 			err = -EBUSY;
74123500189SMarcel Holtmann 			hci_dev_put(hdev);
74223500189SMarcel Holtmann 			goto done;
74323500189SMarcel Holtmann 		}
74423500189SMarcel Holtmann 
745238be788SMarcel Holtmann 		if (hci_dev_test_and_set_flag(hdev, HCI_USER_CHANNEL)) {
74623500189SMarcel Holtmann 			err = -EUSERS;
74723500189SMarcel Holtmann 			hci_dev_put(hdev);
74823500189SMarcel Holtmann 			goto done;
74923500189SMarcel Holtmann 		}
75023500189SMarcel Holtmann 
75123500189SMarcel Holtmann 		mgmt_index_removed(hdev);
75223500189SMarcel Holtmann 
75323500189SMarcel Holtmann 		err = hci_dev_open(hdev->id);
75423500189SMarcel Holtmann 		if (err) {
755a358dc11SMarcel Holtmann 			hci_dev_clear_flag(hdev, HCI_USER_CHANNEL);
756c6521401SMarcel Holtmann 			mgmt_index_added(hdev);
75723500189SMarcel Holtmann 			hci_dev_put(hdev);
75823500189SMarcel Holtmann 			goto done;
75923500189SMarcel Holtmann 		}
76023500189SMarcel Holtmann 
76123500189SMarcel Holtmann 		atomic_inc(&hdev->promisc);
76223500189SMarcel Holtmann 
76323500189SMarcel Holtmann 		hci_pi(sk)->hdev = hdev;
76423500189SMarcel Holtmann 		break;
76523500189SMarcel Holtmann 
766cd82e61cSMarcel Holtmann 	case HCI_CHANNEL_MONITOR:
767cd82e61cSMarcel Holtmann 		if (haddr.hci_dev != HCI_DEV_NONE) {
768cd82e61cSMarcel Holtmann 			err = -EINVAL;
769cd82e61cSMarcel Holtmann 			goto done;
770cd82e61cSMarcel Holtmann 		}
771cd82e61cSMarcel Holtmann 
772cd82e61cSMarcel Holtmann 		if (!capable(CAP_NET_RAW)) {
773cd82e61cSMarcel Holtmann 			err = -EPERM;
774cd82e61cSMarcel Holtmann 			goto done;
775cd82e61cSMarcel Holtmann 		}
776cd82e61cSMarcel Holtmann 
77750ebc055SMarcel Holtmann 		/* The monitor interface is restricted to CAP_NET_RAW
77850ebc055SMarcel Holtmann 		 * capabilities and with that implicitly trusted.
77950ebc055SMarcel Holtmann 		 */
78050ebc055SMarcel Holtmann 		hci_sock_set_flag(sk, HCI_SOCK_TRUSTED);
78150ebc055SMarcel Holtmann 
782cd82e61cSMarcel Holtmann 		send_monitor_replay(sk);
783cd82e61cSMarcel Holtmann 
784cd82e61cSMarcel Holtmann 		atomic_inc(&monitor_promisc);
785cd82e61cSMarcel Holtmann 		break;
786cd82e61cSMarcel Holtmann 
7877cc2ade2SMarcel Holtmann 	default:
788801c1e8dSJohan Hedberg 		if (!hci_mgmt_chan_find(haddr.hci_channel)) {
7897cc2ade2SMarcel Holtmann 			err = -EINVAL;
7907cc2ade2SMarcel Holtmann 			goto done;
7917cc2ade2SMarcel Holtmann 		}
7927cc2ade2SMarcel Holtmann 
793801c1e8dSJohan Hedberg 		if (haddr.hci_dev != HCI_DEV_NONE) {
794801c1e8dSJohan Hedberg 			err = -EINVAL;
795801c1e8dSJohan Hedberg 			goto done;
796801c1e8dSJohan Hedberg 		}
797801c1e8dSJohan Hedberg 
798*1195fbb8SMarcel Holtmann 		/* Users with CAP_NET_ADMIN capabilities are allowed
799*1195fbb8SMarcel Holtmann 		 * access to all management commands and events. For
800*1195fbb8SMarcel Holtmann 		 * untrusted users the interface is restricted and
801*1195fbb8SMarcel Holtmann 		 * also only untrusted events are sent.
80250ebc055SMarcel Holtmann 		 */
803*1195fbb8SMarcel Holtmann 		if (capable(CAP_NET_ADMIN))
80450ebc055SMarcel Holtmann 			hci_sock_set_flag(sk, HCI_SOCK_TRUSTED);
80550ebc055SMarcel Holtmann 
806f9207338SMarcel Holtmann 		/* At the moment the index and unconfigured index events
807f9207338SMarcel Holtmann 		 * are enabled unconditionally. Setting them on each
808f9207338SMarcel Holtmann 		 * socket when binding keeps this functionality. They
809f9207338SMarcel Holtmann 		 * however might be cleared later and then sending of these
810f9207338SMarcel Holtmann 		 * events will be disabled, but that is then intentional.
811f9207338SMarcel Holtmann 		 */
812f9207338SMarcel Holtmann 		if (haddr.hci_channel == HCI_CHANNEL_CONTROL) {
813f9207338SMarcel Holtmann 			hci_sock_set_flag(sk, HCI_MGMT_INDEX_EVENTS);
814f9207338SMarcel Holtmann 			hci_sock_set_flag(sk, HCI_MGMT_UNCONF_INDEX_EVENTS);
815f9207338SMarcel Holtmann 		}
816801c1e8dSJohan Hedberg 		break;
817801c1e8dSJohan Hedberg 	}
818801c1e8dSJohan Hedberg 
8197cc2ade2SMarcel Holtmann 
8207cc2ade2SMarcel Holtmann 	hci_pi(sk)->channel = haddr.hci_channel;
8211da177e4SLinus Torvalds 	sk->sk_state = BT_BOUND;
8221da177e4SLinus Torvalds 
8231da177e4SLinus Torvalds done:
8241da177e4SLinus Torvalds 	release_sock(sk);
8251da177e4SLinus Torvalds 	return err;
8261da177e4SLinus Torvalds }
8271da177e4SLinus Torvalds 
8288fc9ced3SGustavo Padovan static int hci_sock_getname(struct socket *sock, struct sockaddr *addr,
8298fc9ced3SGustavo Padovan 			    int *addr_len, int peer)
8301da177e4SLinus Torvalds {
8311da177e4SLinus Torvalds 	struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr;
8321da177e4SLinus Torvalds 	struct sock *sk = sock->sk;
8339d4b68b2SMarcel Holtmann 	struct hci_dev *hdev;
8349d4b68b2SMarcel Holtmann 	int err = 0;
8351da177e4SLinus Torvalds 
8361da177e4SLinus Torvalds 	BT_DBG("sock %p sk %p", sock, sk);
8371da177e4SLinus Torvalds 
83806f43cbcSMarcel Holtmann 	if (peer)
83906f43cbcSMarcel Holtmann 		return -EOPNOTSUPP;
84006f43cbcSMarcel Holtmann 
8411da177e4SLinus Torvalds 	lock_sock(sk);
8421da177e4SLinus Torvalds 
8439d4b68b2SMarcel Holtmann 	hdev = hci_pi(sk)->hdev;
8449d4b68b2SMarcel Holtmann 	if (!hdev) {
8459d4b68b2SMarcel Holtmann 		err = -EBADFD;
8469d4b68b2SMarcel Holtmann 		goto done;
8479d4b68b2SMarcel Holtmann 	}
8489d4b68b2SMarcel Holtmann 
8491da177e4SLinus Torvalds 	*addr_len = sizeof(*haddr);
8501da177e4SLinus Torvalds 	haddr->hci_family = AF_BLUETOOTH;
8517b005bd3SMarcel Holtmann 	haddr->hci_dev    = hdev->id;
8529d4b68b2SMarcel Holtmann 	haddr->hci_channel= hci_pi(sk)->channel;
8531da177e4SLinus Torvalds 
8549d4b68b2SMarcel Holtmann done:
8551da177e4SLinus Torvalds 	release_sock(sk);
8569d4b68b2SMarcel Holtmann 	return err;
8571da177e4SLinus Torvalds }
8581da177e4SLinus Torvalds 
8596039aa73SGustavo Padovan static void hci_sock_cmsg(struct sock *sk, struct msghdr *msg,
8606039aa73SGustavo Padovan 			  struct sk_buff *skb)
8611da177e4SLinus Torvalds {
8621da177e4SLinus Torvalds 	__u32 mask = hci_pi(sk)->cmsg_mask;
8631da177e4SLinus Torvalds 
8640d48d939SMarcel Holtmann 	if (mask & HCI_CMSG_DIR) {
8650d48d939SMarcel Holtmann 		int incoming = bt_cb(skb)->incoming;
8668fc9ced3SGustavo Padovan 		put_cmsg(msg, SOL_HCI, HCI_CMSG_DIR, sizeof(incoming),
8678fc9ced3SGustavo Padovan 			 &incoming);
8680d48d939SMarcel Holtmann 	}
8691da177e4SLinus Torvalds 
870a61bbcf2SPatrick McHardy 	if (mask & HCI_CMSG_TSTAMP) {
871f6e623a6SJohann Felix Soden #ifdef CONFIG_COMPAT
872f6e623a6SJohann Felix Soden 		struct compat_timeval ctv;
873f6e623a6SJohann Felix Soden #endif
874a61bbcf2SPatrick McHardy 		struct timeval tv;
875767c5eb5SMarcel Holtmann 		void *data;
876767c5eb5SMarcel Holtmann 		int len;
877a61bbcf2SPatrick McHardy 
878a61bbcf2SPatrick McHardy 		skb_get_timestamp(skb, &tv);
879767c5eb5SMarcel Holtmann 
8801da97f83SDavid S. Miller 		data = &tv;
8811da97f83SDavid S. Miller 		len = sizeof(tv);
8821da97f83SDavid S. Miller #ifdef CONFIG_COMPAT
883da88cea1SH. J. Lu 		if (!COMPAT_USE_64BIT_TIME &&
884da88cea1SH. J. Lu 		    (msg->msg_flags & MSG_CMSG_COMPAT)) {
885767c5eb5SMarcel Holtmann 			ctv.tv_sec = tv.tv_sec;
886767c5eb5SMarcel Holtmann 			ctv.tv_usec = tv.tv_usec;
887767c5eb5SMarcel Holtmann 			data = &ctv;
888767c5eb5SMarcel Holtmann 			len = sizeof(ctv);
889767c5eb5SMarcel Holtmann 		}
8901da97f83SDavid S. Miller #endif
891767c5eb5SMarcel Holtmann 
892767c5eb5SMarcel Holtmann 		put_cmsg(msg, SOL_HCI, HCI_CMSG_TSTAMP, len, data);
893a61bbcf2SPatrick McHardy 	}
8941da177e4SLinus Torvalds }
8951da177e4SLinus Torvalds 
8961b784140SYing Xue static int hci_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
8971b784140SYing Xue 			    int flags)
8981da177e4SLinus Torvalds {
8991da177e4SLinus Torvalds 	int noblock = flags & MSG_DONTWAIT;
9001da177e4SLinus Torvalds 	struct sock *sk = sock->sk;
9011da177e4SLinus Torvalds 	struct sk_buff *skb;
9021da177e4SLinus Torvalds 	int copied, err;
9031da177e4SLinus Torvalds 
9041da177e4SLinus Torvalds 	BT_DBG("sock %p, sk %p", sock, sk);
9051da177e4SLinus Torvalds 
9061da177e4SLinus Torvalds 	if (flags & (MSG_OOB))
9071da177e4SLinus Torvalds 		return -EOPNOTSUPP;
9081da177e4SLinus Torvalds 
9091da177e4SLinus Torvalds 	if (sk->sk_state == BT_CLOSED)
9101da177e4SLinus Torvalds 		return 0;
9111da177e4SLinus Torvalds 
91270f23020SAndrei Emeltchenko 	skb = skb_recv_datagram(sk, flags, noblock, &err);
91370f23020SAndrei Emeltchenko 	if (!skb)
9141da177e4SLinus Torvalds 		return err;
9151da177e4SLinus Torvalds 
9161da177e4SLinus Torvalds 	copied = skb->len;
9171da177e4SLinus Torvalds 	if (len < copied) {
9181da177e4SLinus Torvalds 		msg->msg_flags |= MSG_TRUNC;
9191da177e4SLinus Torvalds 		copied = len;
9201da177e4SLinus Torvalds 	}
9211da177e4SLinus Torvalds 
922badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
92351f3d02bSDavid S. Miller 	err = skb_copy_datagram_msg(skb, 0, msg, copied);
9241da177e4SLinus Torvalds 
9253a208627SMarcel Holtmann 	switch (hci_pi(sk)->channel) {
9263a208627SMarcel Holtmann 	case HCI_CHANNEL_RAW:
9271da177e4SLinus Torvalds 		hci_sock_cmsg(sk, msg, skb);
9283a208627SMarcel Holtmann 		break;
92923500189SMarcel Holtmann 	case HCI_CHANNEL_USER:
930cd82e61cSMarcel Holtmann 	case HCI_CHANNEL_MONITOR:
931cd82e61cSMarcel Holtmann 		sock_recv_timestamp(msg, sk, skb);
932cd82e61cSMarcel Holtmann 		break;
933801c1e8dSJohan Hedberg 	default:
934801c1e8dSJohan Hedberg 		if (hci_mgmt_chan_find(hci_pi(sk)->channel))
935801c1e8dSJohan Hedberg 			sock_recv_timestamp(msg, sk, skb);
936801c1e8dSJohan Hedberg 		break;
9373a208627SMarcel Holtmann 	}
9381da177e4SLinus Torvalds 
9391da177e4SLinus Torvalds 	skb_free_datagram(sk, skb);
9401da177e4SLinus Torvalds 
9411da177e4SLinus Torvalds 	return err ? : copied;
9421da177e4SLinus Torvalds }
9431da177e4SLinus Torvalds 
9441b784140SYing Xue static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg,
9451b784140SYing Xue 			    size_t len)
9461da177e4SLinus Torvalds {
9471da177e4SLinus Torvalds 	struct sock *sk = sock->sk;
948801c1e8dSJohan Hedberg 	struct hci_mgmt_chan *chan;
9491da177e4SLinus Torvalds 	struct hci_dev *hdev;
9501da177e4SLinus Torvalds 	struct sk_buff *skb;
9511da177e4SLinus Torvalds 	int err;
9521da177e4SLinus Torvalds 
9531da177e4SLinus Torvalds 	BT_DBG("sock %p sk %p", sock, sk);
9541da177e4SLinus Torvalds 
9551da177e4SLinus Torvalds 	if (msg->msg_flags & MSG_OOB)
9561da177e4SLinus Torvalds 		return -EOPNOTSUPP;
9571da177e4SLinus Torvalds 
9581da177e4SLinus Torvalds 	if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE))
9591da177e4SLinus Torvalds 		return -EINVAL;
9601da177e4SLinus Torvalds 
9611da177e4SLinus Torvalds 	if (len < 4 || len > HCI_MAX_FRAME_SIZE)
9621da177e4SLinus Torvalds 		return -EINVAL;
9631da177e4SLinus Torvalds 
9641da177e4SLinus Torvalds 	lock_sock(sk);
9651da177e4SLinus Torvalds 
9660381101fSJohan Hedberg 	switch (hci_pi(sk)->channel) {
9670381101fSJohan Hedberg 	case HCI_CHANNEL_RAW:
96823500189SMarcel Holtmann 	case HCI_CHANNEL_USER:
9690381101fSJohan Hedberg 		break;
970cd82e61cSMarcel Holtmann 	case HCI_CHANNEL_MONITOR:
971cd82e61cSMarcel Holtmann 		err = -EOPNOTSUPP;
972cd82e61cSMarcel Holtmann 		goto done;
9730381101fSJohan Hedberg 	default:
974801c1e8dSJohan Hedberg 		mutex_lock(&mgmt_chan_list_lock);
975801c1e8dSJohan Hedberg 		chan = __hci_mgmt_chan_find(hci_pi(sk)->channel);
976801c1e8dSJohan Hedberg 		if (chan)
9776d785aa3SJohan Hedberg 			err = mgmt_control(chan, sk, msg, len);
978801c1e8dSJohan Hedberg 		else
9790381101fSJohan Hedberg 			err = -EINVAL;
980801c1e8dSJohan Hedberg 
981801c1e8dSJohan Hedberg 		mutex_unlock(&mgmt_chan_list_lock);
9820381101fSJohan Hedberg 		goto done;
9830381101fSJohan Hedberg 	}
9840381101fSJohan Hedberg 
98570f23020SAndrei Emeltchenko 	hdev = hci_pi(sk)->hdev;
98670f23020SAndrei Emeltchenko 	if (!hdev) {
9871da177e4SLinus Torvalds 		err = -EBADFD;
9881da177e4SLinus Torvalds 		goto done;
9891da177e4SLinus Torvalds 	}
9901da177e4SLinus Torvalds 
9917e21addcSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags)) {
9927e21addcSMarcel Holtmann 		err = -ENETDOWN;
9937e21addcSMarcel Holtmann 		goto done;
9947e21addcSMarcel Holtmann 	}
9957e21addcSMarcel Holtmann 
99670f23020SAndrei Emeltchenko 	skb = bt_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err);
99770f23020SAndrei Emeltchenko 	if (!skb)
9981da177e4SLinus Torvalds 		goto done;
9991da177e4SLinus Torvalds 
10006ce8e9ceSAl Viro 	if (memcpy_from_msg(skb_put(skb, len), msg, len)) {
10011da177e4SLinus Torvalds 		err = -EFAULT;
10021da177e4SLinus Torvalds 		goto drop;
10031da177e4SLinus Torvalds 	}
10041da177e4SLinus Torvalds 
10050d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = *((unsigned char *) skb->data);
10061da177e4SLinus Torvalds 	skb_pull(skb, 1);
10071da177e4SLinus Torvalds 
10081bc5ad16SMarcel Holtmann 	if (hci_pi(sk)->channel == HCI_CHANNEL_USER) {
10091bc5ad16SMarcel Holtmann 		/* No permission check is needed for user channel
10101bc5ad16SMarcel Holtmann 		 * since that gets enforced when binding the socket.
10111bc5ad16SMarcel Holtmann 		 *
10121bc5ad16SMarcel Holtmann 		 * However check that the packet type is valid.
10131bc5ad16SMarcel Holtmann 		 */
10141bc5ad16SMarcel Holtmann 		if (bt_cb(skb)->pkt_type != HCI_COMMAND_PKT &&
10151bc5ad16SMarcel Holtmann 		    bt_cb(skb)->pkt_type != HCI_ACLDATA_PKT &&
10161bc5ad16SMarcel Holtmann 		    bt_cb(skb)->pkt_type != HCI_SCODATA_PKT) {
10171bc5ad16SMarcel Holtmann 			err = -EINVAL;
10181bc5ad16SMarcel Holtmann 			goto drop;
10191bc5ad16SMarcel Holtmann 		}
10201bc5ad16SMarcel Holtmann 
10211bc5ad16SMarcel Holtmann 		skb_queue_tail(&hdev->raw_q, skb);
10221bc5ad16SMarcel Holtmann 		queue_work(hdev->workqueue, &hdev->tx_work);
10231bc5ad16SMarcel Holtmann 	} else if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) {
102483985319SHarvey Harrison 		u16 opcode = get_unaligned_le16(skb->data);
10251da177e4SLinus Torvalds 		u16 ogf = hci_opcode_ogf(opcode);
10261da177e4SLinus Torvalds 		u16 ocf = hci_opcode_ocf(opcode);
10271da177e4SLinus Torvalds 
10281da177e4SLinus Torvalds 		if (((ogf > HCI_SFLT_MAX_OGF) ||
10293bb3c755SGustavo Padovan 		     !hci_test_bit(ocf & HCI_FLT_OCF_BITS,
10303bb3c755SGustavo Padovan 				   &hci_sec_filter.ocf_mask[ogf])) &&
10311da177e4SLinus Torvalds 		    !capable(CAP_NET_RAW)) {
10321da177e4SLinus Torvalds 			err = -EPERM;
10331da177e4SLinus Torvalds 			goto drop;
10341da177e4SLinus Torvalds 		}
10351da177e4SLinus Torvalds 
1036fee746b0SMarcel Holtmann 		if (ogf == 0x3f) {
10371da177e4SLinus Torvalds 			skb_queue_tail(&hdev->raw_q, skb);
10383eff45eaSGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->tx_work);
10391da177e4SLinus Torvalds 		} else {
104049c922bbSStephen Hemminger 			/* Stand-alone HCI commands must be flagged as
104111714b3dSJohan Hedberg 			 * single-command requests.
104211714b3dSJohan Hedberg 			 */
10436368c235SEyal Birger 			bt_cb(skb)->req_start = 1;
104411714b3dSJohan Hedberg 
10451da177e4SLinus Torvalds 			skb_queue_tail(&hdev->cmd_q, skb);
1046c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
10471da177e4SLinus Torvalds 		}
10481da177e4SLinus Torvalds 	} else {
10491da177e4SLinus Torvalds 		if (!capable(CAP_NET_RAW)) {
10501da177e4SLinus Torvalds 			err = -EPERM;
10511da177e4SLinus Torvalds 			goto drop;
10521da177e4SLinus Torvalds 		}
10531da177e4SLinus Torvalds 
10541da177e4SLinus Torvalds 		skb_queue_tail(&hdev->raw_q, skb);
10553eff45eaSGustavo F. Padovan 		queue_work(hdev->workqueue, &hdev->tx_work);
10561da177e4SLinus Torvalds 	}
10571da177e4SLinus Torvalds 
10581da177e4SLinus Torvalds 	err = len;
10591da177e4SLinus Torvalds 
10601da177e4SLinus Torvalds done:
10611da177e4SLinus Torvalds 	release_sock(sk);
10621da177e4SLinus Torvalds 	return err;
10631da177e4SLinus Torvalds 
10641da177e4SLinus Torvalds drop:
10651da177e4SLinus Torvalds 	kfree_skb(skb);
10661da177e4SLinus Torvalds 	goto done;
10671da177e4SLinus Torvalds }
10681da177e4SLinus Torvalds 
10698fc9ced3SGustavo Padovan static int hci_sock_setsockopt(struct socket *sock, int level, int optname,
10708fc9ced3SGustavo Padovan 			       char __user *optval, unsigned int len)
10711da177e4SLinus Torvalds {
10721da177e4SLinus Torvalds 	struct hci_ufilter uf = { .opcode = 0 };
10731da177e4SLinus Torvalds 	struct sock *sk = sock->sk;
10741da177e4SLinus Torvalds 	int err = 0, opt = 0;
10751da177e4SLinus Torvalds 
10761da177e4SLinus Torvalds 	BT_DBG("sk %p, opt %d", sk, optname);
10771da177e4SLinus Torvalds 
10781da177e4SLinus Torvalds 	lock_sock(sk);
10791da177e4SLinus Torvalds 
10802f39cdb7SMarcel Holtmann 	if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) {
1081c2371e80SMarcel Holtmann 		err = -EBADFD;
10822f39cdb7SMarcel Holtmann 		goto done;
10832f39cdb7SMarcel Holtmann 	}
10842f39cdb7SMarcel Holtmann 
10851da177e4SLinus Torvalds 	switch (optname) {
10861da177e4SLinus Torvalds 	case HCI_DATA_DIR:
10871da177e4SLinus Torvalds 		if (get_user(opt, (int __user *)optval)) {
10881da177e4SLinus Torvalds 			err = -EFAULT;
10891da177e4SLinus Torvalds 			break;
10901da177e4SLinus Torvalds 		}
10911da177e4SLinus Torvalds 
10921da177e4SLinus Torvalds 		if (opt)
10931da177e4SLinus Torvalds 			hci_pi(sk)->cmsg_mask |= HCI_CMSG_DIR;
10941da177e4SLinus Torvalds 		else
10951da177e4SLinus Torvalds 			hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_DIR;
10961da177e4SLinus Torvalds 		break;
10971da177e4SLinus Torvalds 
10981da177e4SLinus Torvalds 	case HCI_TIME_STAMP:
10991da177e4SLinus Torvalds 		if (get_user(opt, (int __user *)optval)) {
11001da177e4SLinus Torvalds 			err = -EFAULT;
11011da177e4SLinus Torvalds 			break;
11021da177e4SLinus Torvalds 		}
11031da177e4SLinus Torvalds 
11041da177e4SLinus Torvalds 		if (opt)
11051da177e4SLinus Torvalds 			hci_pi(sk)->cmsg_mask |= HCI_CMSG_TSTAMP;
11061da177e4SLinus Torvalds 		else
11071da177e4SLinus Torvalds 			hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_TSTAMP;
11081da177e4SLinus Torvalds 		break;
11091da177e4SLinus Torvalds 
11101da177e4SLinus Torvalds 	case HCI_FILTER:
11110878b666SMarcel Holtmann 		{
11120878b666SMarcel Holtmann 			struct hci_filter *f = &hci_pi(sk)->filter;
11130878b666SMarcel Holtmann 
11140878b666SMarcel Holtmann 			uf.type_mask = f->type_mask;
11150878b666SMarcel Holtmann 			uf.opcode    = f->opcode;
11160878b666SMarcel Holtmann 			uf.event_mask[0] = *((u32 *) f->event_mask + 0);
11170878b666SMarcel Holtmann 			uf.event_mask[1] = *((u32 *) f->event_mask + 1);
11180878b666SMarcel Holtmann 		}
11190878b666SMarcel Holtmann 
11201da177e4SLinus Torvalds 		len = min_t(unsigned int, len, sizeof(uf));
11211da177e4SLinus Torvalds 		if (copy_from_user(&uf, optval, len)) {
11221da177e4SLinus Torvalds 			err = -EFAULT;
11231da177e4SLinus Torvalds 			break;
11241da177e4SLinus Torvalds 		}
11251da177e4SLinus Torvalds 
11261da177e4SLinus Torvalds 		if (!capable(CAP_NET_RAW)) {
11271da177e4SLinus Torvalds 			uf.type_mask &= hci_sec_filter.type_mask;
11281da177e4SLinus Torvalds 			uf.event_mask[0] &= *((u32 *) hci_sec_filter.event_mask + 0);
11291da177e4SLinus Torvalds 			uf.event_mask[1] &= *((u32 *) hci_sec_filter.event_mask + 1);
11301da177e4SLinus Torvalds 		}
11311da177e4SLinus Torvalds 
11321da177e4SLinus Torvalds 		{
11331da177e4SLinus Torvalds 			struct hci_filter *f = &hci_pi(sk)->filter;
11341da177e4SLinus Torvalds 
11351da177e4SLinus Torvalds 			f->type_mask = uf.type_mask;
11361da177e4SLinus Torvalds 			f->opcode    = uf.opcode;
11371da177e4SLinus Torvalds 			*((u32 *) f->event_mask + 0) = uf.event_mask[0];
11381da177e4SLinus Torvalds 			*((u32 *) f->event_mask + 1) = uf.event_mask[1];
11391da177e4SLinus Torvalds 		}
11401da177e4SLinus Torvalds 		break;
11411da177e4SLinus Torvalds 
11421da177e4SLinus Torvalds 	default:
11431da177e4SLinus Torvalds 		err = -ENOPROTOOPT;
11441da177e4SLinus Torvalds 		break;
11451da177e4SLinus Torvalds 	}
11461da177e4SLinus Torvalds 
11472f39cdb7SMarcel Holtmann done:
11481da177e4SLinus Torvalds 	release_sock(sk);
11491da177e4SLinus Torvalds 	return err;
11501da177e4SLinus Torvalds }
11511da177e4SLinus Torvalds 
11528fc9ced3SGustavo Padovan static int hci_sock_getsockopt(struct socket *sock, int level, int optname,
11538fc9ced3SGustavo Padovan 			       char __user *optval, int __user *optlen)
11541da177e4SLinus Torvalds {
11551da177e4SLinus Torvalds 	struct hci_ufilter uf;
11561da177e4SLinus Torvalds 	struct sock *sk = sock->sk;
1157cedc5469SMarcel Holtmann 	int len, opt, err = 0;
1158cedc5469SMarcel Holtmann 
1159cedc5469SMarcel Holtmann 	BT_DBG("sk %p, opt %d", sk, optname);
11601da177e4SLinus Torvalds 
11611da177e4SLinus Torvalds 	if (get_user(len, optlen))
11621da177e4SLinus Torvalds 		return -EFAULT;
11631da177e4SLinus Torvalds 
1164cedc5469SMarcel Holtmann 	lock_sock(sk);
1165cedc5469SMarcel Holtmann 
1166cedc5469SMarcel Holtmann 	if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) {
1167c2371e80SMarcel Holtmann 		err = -EBADFD;
1168cedc5469SMarcel Holtmann 		goto done;
1169cedc5469SMarcel Holtmann 	}
1170cedc5469SMarcel Holtmann 
11711da177e4SLinus Torvalds 	switch (optname) {
11721da177e4SLinus Torvalds 	case HCI_DATA_DIR:
11731da177e4SLinus Torvalds 		if (hci_pi(sk)->cmsg_mask & HCI_CMSG_DIR)
11741da177e4SLinus Torvalds 			opt = 1;
11751da177e4SLinus Torvalds 		else
11761da177e4SLinus Torvalds 			opt = 0;
11771da177e4SLinus Torvalds 
11781da177e4SLinus Torvalds 		if (put_user(opt, optval))
1179cedc5469SMarcel Holtmann 			err = -EFAULT;
11801da177e4SLinus Torvalds 		break;
11811da177e4SLinus Torvalds 
11821da177e4SLinus Torvalds 	case HCI_TIME_STAMP:
11831da177e4SLinus Torvalds 		if (hci_pi(sk)->cmsg_mask & HCI_CMSG_TSTAMP)
11841da177e4SLinus Torvalds 			opt = 1;
11851da177e4SLinus Torvalds 		else
11861da177e4SLinus Torvalds 			opt = 0;
11871da177e4SLinus Torvalds 
11881da177e4SLinus Torvalds 		if (put_user(opt, optval))
1189cedc5469SMarcel Holtmann 			err = -EFAULT;
11901da177e4SLinus Torvalds 		break;
11911da177e4SLinus Torvalds 
11921da177e4SLinus Torvalds 	case HCI_FILTER:
11931da177e4SLinus Torvalds 		{
11941da177e4SLinus Torvalds 			struct hci_filter *f = &hci_pi(sk)->filter;
11951da177e4SLinus Torvalds 
1196e15ca9a0SMathias Krause 			memset(&uf, 0, sizeof(uf));
11971da177e4SLinus Torvalds 			uf.type_mask = f->type_mask;
11981da177e4SLinus Torvalds 			uf.opcode    = f->opcode;
11991da177e4SLinus Torvalds 			uf.event_mask[0] = *((u32 *) f->event_mask + 0);
12001da177e4SLinus Torvalds 			uf.event_mask[1] = *((u32 *) f->event_mask + 1);
12011da177e4SLinus Torvalds 		}
12021da177e4SLinus Torvalds 
12031da177e4SLinus Torvalds 		len = min_t(unsigned int, len, sizeof(uf));
12041da177e4SLinus Torvalds 		if (copy_to_user(optval, &uf, len))
1205cedc5469SMarcel Holtmann 			err = -EFAULT;
12061da177e4SLinus Torvalds 		break;
12071da177e4SLinus Torvalds 
12081da177e4SLinus Torvalds 	default:
1209cedc5469SMarcel Holtmann 		err = -ENOPROTOOPT;
12101da177e4SLinus Torvalds 		break;
12111da177e4SLinus Torvalds 	}
12121da177e4SLinus Torvalds 
1213cedc5469SMarcel Holtmann done:
1214cedc5469SMarcel Holtmann 	release_sock(sk);
1215cedc5469SMarcel Holtmann 	return err;
12161da177e4SLinus Torvalds }
12171da177e4SLinus Torvalds 
121890ddc4f0SEric Dumazet static const struct proto_ops hci_sock_ops = {
12191da177e4SLinus Torvalds 	.family		= PF_BLUETOOTH,
12201da177e4SLinus Torvalds 	.owner		= THIS_MODULE,
12211da177e4SLinus Torvalds 	.release	= hci_sock_release,
12221da177e4SLinus Torvalds 	.bind		= hci_sock_bind,
12231da177e4SLinus Torvalds 	.getname	= hci_sock_getname,
12241da177e4SLinus Torvalds 	.sendmsg	= hci_sock_sendmsg,
12251da177e4SLinus Torvalds 	.recvmsg	= hci_sock_recvmsg,
12261da177e4SLinus Torvalds 	.ioctl		= hci_sock_ioctl,
12271da177e4SLinus Torvalds 	.poll		= datagram_poll,
12281da177e4SLinus Torvalds 	.listen		= sock_no_listen,
12291da177e4SLinus Torvalds 	.shutdown	= sock_no_shutdown,
12301da177e4SLinus Torvalds 	.setsockopt	= hci_sock_setsockopt,
12311da177e4SLinus Torvalds 	.getsockopt	= hci_sock_getsockopt,
12321da177e4SLinus Torvalds 	.connect	= sock_no_connect,
12331da177e4SLinus Torvalds 	.socketpair	= sock_no_socketpair,
12341da177e4SLinus Torvalds 	.accept		= sock_no_accept,
12351da177e4SLinus Torvalds 	.mmap		= sock_no_mmap
12361da177e4SLinus Torvalds };
12371da177e4SLinus Torvalds 
12381da177e4SLinus Torvalds static struct proto hci_sk_proto = {
12391da177e4SLinus Torvalds 	.name		= "HCI",
12401da177e4SLinus Torvalds 	.owner		= THIS_MODULE,
12411da177e4SLinus Torvalds 	.obj_size	= sizeof(struct hci_pinfo)
12421da177e4SLinus Torvalds };
12431da177e4SLinus Torvalds 
12443f378b68SEric Paris static int hci_sock_create(struct net *net, struct socket *sock, int protocol,
12453f378b68SEric Paris 			   int kern)
12461da177e4SLinus Torvalds {
12471da177e4SLinus Torvalds 	struct sock *sk;
12481da177e4SLinus Torvalds 
12491da177e4SLinus Torvalds 	BT_DBG("sock %p", sock);
12501da177e4SLinus Torvalds 
12511da177e4SLinus Torvalds 	if (sock->type != SOCK_RAW)
12521da177e4SLinus Torvalds 		return -ESOCKTNOSUPPORT;
12531da177e4SLinus Torvalds 
12541da177e4SLinus Torvalds 	sock->ops = &hci_sock_ops;
12551da177e4SLinus Torvalds 
12566257ff21SPavel Emelyanov 	sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &hci_sk_proto);
12571da177e4SLinus Torvalds 	if (!sk)
12581da177e4SLinus Torvalds 		return -ENOMEM;
12591da177e4SLinus Torvalds 
12601da177e4SLinus Torvalds 	sock_init_data(sock, sk);
12611da177e4SLinus Torvalds 
12621da177e4SLinus Torvalds 	sock_reset_flag(sk, SOCK_ZAPPED);
12631da177e4SLinus Torvalds 
12641da177e4SLinus Torvalds 	sk->sk_protocol = protocol;
12651da177e4SLinus Torvalds 
12661da177e4SLinus Torvalds 	sock->state = SS_UNCONNECTED;
12671da177e4SLinus Torvalds 	sk->sk_state = BT_OPEN;
12681da177e4SLinus Torvalds 
12691da177e4SLinus Torvalds 	bt_sock_link(&hci_sk_list, sk);
12701da177e4SLinus Torvalds 	return 0;
12711da177e4SLinus Torvalds }
12721da177e4SLinus Torvalds 
1273ec1b4cf7SStephen Hemminger static const struct net_proto_family hci_sock_family_ops = {
12741da177e4SLinus Torvalds 	.family	= PF_BLUETOOTH,
12751da177e4SLinus Torvalds 	.owner	= THIS_MODULE,
12761da177e4SLinus Torvalds 	.create	= hci_sock_create,
12771da177e4SLinus Torvalds };
12781da177e4SLinus Torvalds 
12791da177e4SLinus Torvalds int __init hci_sock_init(void)
12801da177e4SLinus Torvalds {
12811da177e4SLinus Torvalds 	int err;
12821da177e4SLinus Torvalds 
1283b0a8e282SMarcel Holtmann 	BUILD_BUG_ON(sizeof(struct sockaddr_hci) > sizeof(struct sockaddr));
1284b0a8e282SMarcel Holtmann 
12851da177e4SLinus Torvalds 	err = proto_register(&hci_sk_proto, 0);
12861da177e4SLinus Torvalds 	if (err < 0)
12871da177e4SLinus Torvalds 		return err;
12881da177e4SLinus Torvalds 
12891da177e4SLinus Torvalds 	err = bt_sock_register(BTPROTO_HCI, &hci_sock_family_ops);
1290f7c86637SMasatake YAMATO 	if (err < 0) {
1291f7c86637SMasatake YAMATO 		BT_ERR("HCI socket registration failed");
12921da177e4SLinus Torvalds 		goto error;
1293f7c86637SMasatake YAMATO 	}
1294f7c86637SMasatake YAMATO 
1295b0316615SAl Viro 	err = bt_procfs_init(&init_net, "hci", &hci_sk_list, NULL);
1296f7c86637SMasatake YAMATO 	if (err < 0) {
1297f7c86637SMasatake YAMATO 		BT_ERR("Failed to create HCI proc file");
1298f7c86637SMasatake YAMATO 		bt_sock_unregister(BTPROTO_HCI);
1299f7c86637SMasatake YAMATO 		goto error;
1300f7c86637SMasatake YAMATO 	}
13011da177e4SLinus Torvalds 
13021da177e4SLinus Torvalds 	BT_INFO("HCI socket layer initialized");
13031da177e4SLinus Torvalds 
13041da177e4SLinus Torvalds 	return 0;
13051da177e4SLinus Torvalds 
13061da177e4SLinus Torvalds error:
13071da177e4SLinus Torvalds 	proto_unregister(&hci_sk_proto);
13081da177e4SLinus Torvalds 	return err;
13091da177e4SLinus Torvalds }
13101da177e4SLinus Torvalds 
1311b7440a14SAnand Gadiyar void hci_sock_cleanup(void)
13121da177e4SLinus Torvalds {
1313f7c86637SMasatake YAMATO 	bt_procfs_cleanup(&init_net, "hci");
13145e9d7f86SDavid Herrmann 	bt_sock_unregister(BTPROTO_HCI);
13151da177e4SLinus Torvalds 	proto_unregister(&hci_sk_proto);
13161da177e4SLinus Torvalds }
1317