xref: /openbmc/linux/net/bluetooth/hci_sock.c (revision c85be545ea23a4fe590c89683242a9be823394e0)
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 
63*c85be545SMarcel Holtmann int hci_sock_test_flag(struct sock *sk, int nr)
64*c85be545SMarcel Holtmann {
65*c85be545SMarcel Holtmann 	return test_bit(nr, &hci_pi(sk)->flags);
66*c85be545SMarcel Holtmann }
67*c85be545SMarcel 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 */
219*c85be545SMarcel 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 
798801c1e8dSJohan Hedberg 		if (!capable(CAP_NET_ADMIN)) {
799801c1e8dSJohan Hedberg 			err = -EPERM;
800801c1e8dSJohan Hedberg 			goto done;
801801c1e8dSJohan Hedberg 		}
802801c1e8dSJohan Hedberg 
80350ebc055SMarcel Holtmann 		/* Since the access to control channels is currently
80450ebc055SMarcel Holtmann 		 * restricted to CAP_NET_ADMIN capabilities, every
80550ebc055SMarcel Holtmann 		 * socket is implicitly trusted.
80650ebc055SMarcel Holtmann 		 */
80750ebc055SMarcel Holtmann 		hci_sock_set_flag(sk, HCI_SOCK_TRUSTED);
80850ebc055SMarcel Holtmann 
809f9207338SMarcel Holtmann 		/* At the moment the index and unconfigured index events
810f9207338SMarcel Holtmann 		 * are enabled unconditionally. Setting them on each
811f9207338SMarcel Holtmann 		 * socket when binding keeps this functionality. They
812f9207338SMarcel Holtmann 		 * however might be cleared later and then sending of these
813f9207338SMarcel Holtmann 		 * events will be disabled, but that is then intentional.
814f9207338SMarcel Holtmann 		 */
815f9207338SMarcel Holtmann 		if (haddr.hci_channel == HCI_CHANNEL_CONTROL) {
816f9207338SMarcel Holtmann 			hci_sock_set_flag(sk, HCI_MGMT_INDEX_EVENTS);
817f9207338SMarcel Holtmann 			hci_sock_set_flag(sk, HCI_MGMT_UNCONF_INDEX_EVENTS);
818f9207338SMarcel Holtmann 		}
819801c1e8dSJohan Hedberg 		break;
820801c1e8dSJohan Hedberg 	}
821801c1e8dSJohan Hedberg 
8227cc2ade2SMarcel Holtmann 
8237cc2ade2SMarcel Holtmann 	hci_pi(sk)->channel = haddr.hci_channel;
8241da177e4SLinus Torvalds 	sk->sk_state = BT_BOUND;
8251da177e4SLinus Torvalds 
8261da177e4SLinus Torvalds done:
8271da177e4SLinus Torvalds 	release_sock(sk);
8281da177e4SLinus Torvalds 	return err;
8291da177e4SLinus Torvalds }
8301da177e4SLinus Torvalds 
8318fc9ced3SGustavo Padovan static int hci_sock_getname(struct socket *sock, struct sockaddr *addr,
8328fc9ced3SGustavo Padovan 			    int *addr_len, int peer)
8331da177e4SLinus Torvalds {
8341da177e4SLinus Torvalds 	struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr;
8351da177e4SLinus Torvalds 	struct sock *sk = sock->sk;
8369d4b68b2SMarcel Holtmann 	struct hci_dev *hdev;
8379d4b68b2SMarcel Holtmann 	int err = 0;
8381da177e4SLinus Torvalds 
8391da177e4SLinus Torvalds 	BT_DBG("sock %p sk %p", sock, sk);
8401da177e4SLinus Torvalds 
84106f43cbcSMarcel Holtmann 	if (peer)
84206f43cbcSMarcel Holtmann 		return -EOPNOTSUPP;
84306f43cbcSMarcel Holtmann 
8441da177e4SLinus Torvalds 	lock_sock(sk);
8451da177e4SLinus Torvalds 
8469d4b68b2SMarcel Holtmann 	hdev = hci_pi(sk)->hdev;
8479d4b68b2SMarcel Holtmann 	if (!hdev) {
8489d4b68b2SMarcel Holtmann 		err = -EBADFD;
8499d4b68b2SMarcel Holtmann 		goto done;
8509d4b68b2SMarcel Holtmann 	}
8519d4b68b2SMarcel Holtmann 
8521da177e4SLinus Torvalds 	*addr_len = sizeof(*haddr);
8531da177e4SLinus Torvalds 	haddr->hci_family = AF_BLUETOOTH;
8547b005bd3SMarcel Holtmann 	haddr->hci_dev    = hdev->id;
8559d4b68b2SMarcel Holtmann 	haddr->hci_channel= hci_pi(sk)->channel;
8561da177e4SLinus Torvalds 
8579d4b68b2SMarcel Holtmann done:
8581da177e4SLinus Torvalds 	release_sock(sk);
8599d4b68b2SMarcel Holtmann 	return err;
8601da177e4SLinus Torvalds }
8611da177e4SLinus Torvalds 
8626039aa73SGustavo Padovan static void hci_sock_cmsg(struct sock *sk, struct msghdr *msg,
8636039aa73SGustavo Padovan 			  struct sk_buff *skb)
8641da177e4SLinus Torvalds {
8651da177e4SLinus Torvalds 	__u32 mask = hci_pi(sk)->cmsg_mask;
8661da177e4SLinus Torvalds 
8670d48d939SMarcel Holtmann 	if (mask & HCI_CMSG_DIR) {
8680d48d939SMarcel Holtmann 		int incoming = bt_cb(skb)->incoming;
8698fc9ced3SGustavo Padovan 		put_cmsg(msg, SOL_HCI, HCI_CMSG_DIR, sizeof(incoming),
8708fc9ced3SGustavo Padovan 			 &incoming);
8710d48d939SMarcel Holtmann 	}
8721da177e4SLinus Torvalds 
873a61bbcf2SPatrick McHardy 	if (mask & HCI_CMSG_TSTAMP) {
874f6e623a6SJohann Felix Soden #ifdef CONFIG_COMPAT
875f6e623a6SJohann Felix Soden 		struct compat_timeval ctv;
876f6e623a6SJohann Felix Soden #endif
877a61bbcf2SPatrick McHardy 		struct timeval tv;
878767c5eb5SMarcel Holtmann 		void *data;
879767c5eb5SMarcel Holtmann 		int len;
880a61bbcf2SPatrick McHardy 
881a61bbcf2SPatrick McHardy 		skb_get_timestamp(skb, &tv);
882767c5eb5SMarcel Holtmann 
8831da97f83SDavid S. Miller 		data = &tv;
8841da97f83SDavid S. Miller 		len = sizeof(tv);
8851da97f83SDavid S. Miller #ifdef CONFIG_COMPAT
886da88cea1SH. J. Lu 		if (!COMPAT_USE_64BIT_TIME &&
887da88cea1SH. J. Lu 		    (msg->msg_flags & MSG_CMSG_COMPAT)) {
888767c5eb5SMarcel Holtmann 			ctv.tv_sec = tv.tv_sec;
889767c5eb5SMarcel Holtmann 			ctv.tv_usec = tv.tv_usec;
890767c5eb5SMarcel Holtmann 			data = &ctv;
891767c5eb5SMarcel Holtmann 			len = sizeof(ctv);
892767c5eb5SMarcel Holtmann 		}
8931da97f83SDavid S. Miller #endif
894767c5eb5SMarcel Holtmann 
895767c5eb5SMarcel Holtmann 		put_cmsg(msg, SOL_HCI, HCI_CMSG_TSTAMP, len, data);
896a61bbcf2SPatrick McHardy 	}
8971da177e4SLinus Torvalds }
8981da177e4SLinus Torvalds 
8991b784140SYing Xue static int hci_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
9001b784140SYing Xue 			    int flags)
9011da177e4SLinus Torvalds {
9021da177e4SLinus Torvalds 	int noblock = flags & MSG_DONTWAIT;
9031da177e4SLinus Torvalds 	struct sock *sk = sock->sk;
9041da177e4SLinus Torvalds 	struct sk_buff *skb;
9051da177e4SLinus Torvalds 	int copied, err;
9061da177e4SLinus Torvalds 
9071da177e4SLinus Torvalds 	BT_DBG("sock %p, sk %p", sock, sk);
9081da177e4SLinus Torvalds 
9091da177e4SLinus Torvalds 	if (flags & (MSG_OOB))
9101da177e4SLinus Torvalds 		return -EOPNOTSUPP;
9111da177e4SLinus Torvalds 
9121da177e4SLinus Torvalds 	if (sk->sk_state == BT_CLOSED)
9131da177e4SLinus Torvalds 		return 0;
9141da177e4SLinus Torvalds 
91570f23020SAndrei Emeltchenko 	skb = skb_recv_datagram(sk, flags, noblock, &err);
91670f23020SAndrei Emeltchenko 	if (!skb)
9171da177e4SLinus Torvalds 		return err;
9181da177e4SLinus Torvalds 
9191da177e4SLinus Torvalds 	copied = skb->len;
9201da177e4SLinus Torvalds 	if (len < copied) {
9211da177e4SLinus Torvalds 		msg->msg_flags |= MSG_TRUNC;
9221da177e4SLinus Torvalds 		copied = len;
9231da177e4SLinus Torvalds 	}
9241da177e4SLinus Torvalds 
925badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
92651f3d02bSDavid S. Miller 	err = skb_copy_datagram_msg(skb, 0, msg, copied);
9271da177e4SLinus Torvalds 
9283a208627SMarcel Holtmann 	switch (hci_pi(sk)->channel) {
9293a208627SMarcel Holtmann 	case HCI_CHANNEL_RAW:
9301da177e4SLinus Torvalds 		hci_sock_cmsg(sk, msg, skb);
9313a208627SMarcel Holtmann 		break;
93223500189SMarcel Holtmann 	case HCI_CHANNEL_USER:
933cd82e61cSMarcel Holtmann 	case HCI_CHANNEL_MONITOR:
934cd82e61cSMarcel Holtmann 		sock_recv_timestamp(msg, sk, skb);
935cd82e61cSMarcel Holtmann 		break;
936801c1e8dSJohan Hedberg 	default:
937801c1e8dSJohan Hedberg 		if (hci_mgmt_chan_find(hci_pi(sk)->channel))
938801c1e8dSJohan Hedberg 			sock_recv_timestamp(msg, sk, skb);
939801c1e8dSJohan Hedberg 		break;
9403a208627SMarcel Holtmann 	}
9411da177e4SLinus Torvalds 
9421da177e4SLinus Torvalds 	skb_free_datagram(sk, skb);
9431da177e4SLinus Torvalds 
9441da177e4SLinus Torvalds 	return err ? : copied;
9451da177e4SLinus Torvalds }
9461da177e4SLinus Torvalds 
9471b784140SYing Xue static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg,
9481b784140SYing Xue 			    size_t len)
9491da177e4SLinus Torvalds {
9501da177e4SLinus Torvalds 	struct sock *sk = sock->sk;
951801c1e8dSJohan Hedberg 	struct hci_mgmt_chan *chan;
9521da177e4SLinus Torvalds 	struct hci_dev *hdev;
9531da177e4SLinus Torvalds 	struct sk_buff *skb;
9541da177e4SLinus Torvalds 	int err;
9551da177e4SLinus Torvalds 
9561da177e4SLinus Torvalds 	BT_DBG("sock %p sk %p", sock, sk);
9571da177e4SLinus Torvalds 
9581da177e4SLinus Torvalds 	if (msg->msg_flags & MSG_OOB)
9591da177e4SLinus Torvalds 		return -EOPNOTSUPP;
9601da177e4SLinus Torvalds 
9611da177e4SLinus Torvalds 	if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE))
9621da177e4SLinus Torvalds 		return -EINVAL;
9631da177e4SLinus Torvalds 
9641da177e4SLinus Torvalds 	if (len < 4 || len > HCI_MAX_FRAME_SIZE)
9651da177e4SLinus Torvalds 		return -EINVAL;
9661da177e4SLinus Torvalds 
9671da177e4SLinus Torvalds 	lock_sock(sk);
9681da177e4SLinus Torvalds 
9690381101fSJohan Hedberg 	switch (hci_pi(sk)->channel) {
9700381101fSJohan Hedberg 	case HCI_CHANNEL_RAW:
97123500189SMarcel Holtmann 	case HCI_CHANNEL_USER:
9720381101fSJohan Hedberg 		break;
973cd82e61cSMarcel Holtmann 	case HCI_CHANNEL_MONITOR:
974cd82e61cSMarcel Holtmann 		err = -EOPNOTSUPP;
975cd82e61cSMarcel Holtmann 		goto done;
9760381101fSJohan Hedberg 	default:
977801c1e8dSJohan Hedberg 		mutex_lock(&mgmt_chan_list_lock);
978801c1e8dSJohan Hedberg 		chan = __hci_mgmt_chan_find(hci_pi(sk)->channel);
979801c1e8dSJohan Hedberg 		if (chan)
9806d785aa3SJohan Hedberg 			err = mgmt_control(chan, sk, msg, len);
981801c1e8dSJohan Hedberg 		else
9820381101fSJohan Hedberg 			err = -EINVAL;
983801c1e8dSJohan Hedberg 
984801c1e8dSJohan Hedberg 		mutex_unlock(&mgmt_chan_list_lock);
9850381101fSJohan Hedberg 		goto done;
9860381101fSJohan Hedberg 	}
9870381101fSJohan Hedberg 
98870f23020SAndrei Emeltchenko 	hdev = hci_pi(sk)->hdev;
98970f23020SAndrei Emeltchenko 	if (!hdev) {
9901da177e4SLinus Torvalds 		err = -EBADFD;
9911da177e4SLinus Torvalds 		goto done;
9921da177e4SLinus Torvalds 	}
9931da177e4SLinus Torvalds 
9947e21addcSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags)) {
9957e21addcSMarcel Holtmann 		err = -ENETDOWN;
9967e21addcSMarcel Holtmann 		goto done;
9977e21addcSMarcel Holtmann 	}
9987e21addcSMarcel Holtmann 
99970f23020SAndrei Emeltchenko 	skb = bt_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err);
100070f23020SAndrei Emeltchenko 	if (!skb)
10011da177e4SLinus Torvalds 		goto done;
10021da177e4SLinus Torvalds 
10036ce8e9ceSAl Viro 	if (memcpy_from_msg(skb_put(skb, len), msg, len)) {
10041da177e4SLinus Torvalds 		err = -EFAULT;
10051da177e4SLinus Torvalds 		goto drop;
10061da177e4SLinus Torvalds 	}
10071da177e4SLinus Torvalds 
10080d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = *((unsigned char *) skb->data);
10091da177e4SLinus Torvalds 	skb_pull(skb, 1);
10101da177e4SLinus Torvalds 
10111bc5ad16SMarcel Holtmann 	if (hci_pi(sk)->channel == HCI_CHANNEL_USER) {
10121bc5ad16SMarcel Holtmann 		/* No permission check is needed for user channel
10131bc5ad16SMarcel Holtmann 		 * since that gets enforced when binding the socket.
10141bc5ad16SMarcel Holtmann 		 *
10151bc5ad16SMarcel Holtmann 		 * However check that the packet type is valid.
10161bc5ad16SMarcel Holtmann 		 */
10171bc5ad16SMarcel Holtmann 		if (bt_cb(skb)->pkt_type != HCI_COMMAND_PKT &&
10181bc5ad16SMarcel Holtmann 		    bt_cb(skb)->pkt_type != HCI_ACLDATA_PKT &&
10191bc5ad16SMarcel Holtmann 		    bt_cb(skb)->pkt_type != HCI_SCODATA_PKT) {
10201bc5ad16SMarcel Holtmann 			err = -EINVAL;
10211bc5ad16SMarcel Holtmann 			goto drop;
10221bc5ad16SMarcel Holtmann 		}
10231bc5ad16SMarcel Holtmann 
10241bc5ad16SMarcel Holtmann 		skb_queue_tail(&hdev->raw_q, skb);
10251bc5ad16SMarcel Holtmann 		queue_work(hdev->workqueue, &hdev->tx_work);
10261bc5ad16SMarcel Holtmann 	} else if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) {
102783985319SHarvey Harrison 		u16 opcode = get_unaligned_le16(skb->data);
10281da177e4SLinus Torvalds 		u16 ogf = hci_opcode_ogf(opcode);
10291da177e4SLinus Torvalds 		u16 ocf = hci_opcode_ocf(opcode);
10301da177e4SLinus Torvalds 
10311da177e4SLinus Torvalds 		if (((ogf > HCI_SFLT_MAX_OGF) ||
10323bb3c755SGustavo Padovan 		     !hci_test_bit(ocf & HCI_FLT_OCF_BITS,
10333bb3c755SGustavo Padovan 				   &hci_sec_filter.ocf_mask[ogf])) &&
10341da177e4SLinus Torvalds 		    !capable(CAP_NET_RAW)) {
10351da177e4SLinus Torvalds 			err = -EPERM;
10361da177e4SLinus Torvalds 			goto drop;
10371da177e4SLinus Torvalds 		}
10381da177e4SLinus Torvalds 
1039fee746b0SMarcel Holtmann 		if (ogf == 0x3f) {
10401da177e4SLinus Torvalds 			skb_queue_tail(&hdev->raw_q, skb);
10413eff45eaSGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->tx_work);
10421da177e4SLinus Torvalds 		} else {
104349c922bbSStephen Hemminger 			/* Stand-alone HCI commands must be flagged as
104411714b3dSJohan Hedberg 			 * single-command requests.
104511714b3dSJohan Hedberg 			 */
10466368c235SEyal Birger 			bt_cb(skb)->req_start = 1;
104711714b3dSJohan Hedberg 
10481da177e4SLinus Torvalds 			skb_queue_tail(&hdev->cmd_q, skb);
1049c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
10501da177e4SLinus Torvalds 		}
10511da177e4SLinus Torvalds 	} else {
10521da177e4SLinus Torvalds 		if (!capable(CAP_NET_RAW)) {
10531da177e4SLinus Torvalds 			err = -EPERM;
10541da177e4SLinus Torvalds 			goto drop;
10551da177e4SLinus Torvalds 		}
10561da177e4SLinus Torvalds 
10571da177e4SLinus Torvalds 		skb_queue_tail(&hdev->raw_q, skb);
10583eff45eaSGustavo F. Padovan 		queue_work(hdev->workqueue, &hdev->tx_work);
10591da177e4SLinus Torvalds 	}
10601da177e4SLinus Torvalds 
10611da177e4SLinus Torvalds 	err = len;
10621da177e4SLinus Torvalds 
10631da177e4SLinus Torvalds done:
10641da177e4SLinus Torvalds 	release_sock(sk);
10651da177e4SLinus Torvalds 	return err;
10661da177e4SLinus Torvalds 
10671da177e4SLinus Torvalds drop:
10681da177e4SLinus Torvalds 	kfree_skb(skb);
10691da177e4SLinus Torvalds 	goto done;
10701da177e4SLinus Torvalds }
10711da177e4SLinus Torvalds 
10728fc9ced3SGustavo Padovan static int hci_sock_setsockopt(struct socket *sock, int level, int optname,
10738fc9ced3SGustavo Padovan 			       char __user *optval, unsigned int len)
10741da177e4SLinus Torvalds {
10751da177e4SLinus Torvalds 	struct hci_ufilter uf = { .opcode = 0 };
10761da177e4SLinus Torvalds 	struct sock *sk = sock->sk;
10771da177e4SLinus Torvalds 	int err = 0, opt = 0;
10781da177e4SLinus Torvalds 
10791da177e4SLinus Torvalds 	BT_DBG("sk %p, opt %d", sk, optname);
10801da177e4SLinus Torvalds 
10811da177e4SLinus Torvalds 	lock_sock(sk);
10821da177e4SLinus Torvalds 
10832f39cdb7SMarcel Holtmann 	if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) {
1084c2371e80SMarcel Holtmann 		err = -EBADFD;
10852f39cdb7SMarcel Holtmann 		goto done;
10862f39cdb7SMarcel Holtmann 	}
10872f39cdb7SMarcel Holtmann 
10881da177e4SLinus Torvalds 	switch (optname) {
10891da177e4SLinus Torvalds 	case HCI_DATA_DIR:
10901da177e4SLinus Torvalds 		if (get_user(opt, (int __user *)optval)) {
10911da177e4SLinus Torvalds 			err = -EFAULT;
10921da177e4SLinus Torvalds 			break;
10931da177e4SLinus Torvalds 		}
10941da177e4SLinus Torvalds 
10951da177e4SLinus Torvalds 		if (opt)
10961da177e4SLinus Torvalds 			hci_pi(sk)->cmsg_mask |= HCI_CMSG_DIR;
10971da177e4SLinus Torvalds 		else
10981da177e4SLinus Torvalds 			hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_DIR;
10991da177e4SLinus Torvalds 		break;
11001da177e4SLinus Torvalds 
11011da177e4SLinus Torvalds 	case HCI_TIME_STAMP:
11021da177e4SLinus Torvalds 		if (get_user(opt, (int __user *)optval)) {
11031da177e4SLinus Torvalds 			err = -EFAULT;
11041da177e4SLinus Torvalds 			break;
11051da177e4SLinus Torvalds 		}
11061da177e4SLinus Torvalds 
11071da177e4SLinus Torvalds 		if (opt)
11081da177e4SLinus Torvalds 			hci_pi(sk)->cmsg_mask |= HCI_CMSG_TSTAMP;
11091da177e4SLinus Torvalds 		else
11101da177e4SLinus Torvalds 			hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_TSTAMP;
11111da177e4SLinus Torvalds 		break;
11121da177e4SLinus Torvalds 
11131da177e4SLinus Torvalds 	case HCI_FILTER:
11140878b666SMarcel Holtmann 		{
11150878b666SMarcel Holtmann 			struct hci_filter *f = &hci_pi(sk)->filter;
11160878b666SMarcel Holtmann 
11170878b666SMarcel Holtmann 			uf.type_mask = f->type_mask;
11180878b666SMarcel Holtmann 			uf.opcode    = f->opcode;
11190878b666SMarcel Holtmann 			uf.event_mask[0] = *((u32 *) f->event_mask + 0);
11200878b666SMarcel Holtmann 			uf.event_mask[1] = *((u32 *) f->event_mask + 1);
11210878b666SMarcel Holtmann 		}
11220878b666SMarcel Holtmann 
11231da177e4SLinus Torvalds 		len = min_t(unsigned int, len, sizeof(uf));
11241da177e4SLinus Torvalds 		if (copy_from_user(&uf, optval, len)) {
11251da177e4SLinus Torvalds 			err = -EFAULT;
11261da177e4SLinus Torvalds 			break;
11271da177e4SLinus Torvalds 		}
11281da177e4SLinus Torvalds 
11291da177e4SLinus Torvalds 		if (!capable(CAP_NET_RAW)) {
11301da177e4SLinus Torvalds 			uf.type_mask &= hci_sec_filter.type_mask;
11311da177e4SLinus Torvalds 			uf.event_mask[0] &= *((u32 *) hci_sec_filter.event_mask + 0);
11321da177e4SLinus Torvalds 			uf.event_mask[1] &= *((u32 *) hci_sec_filter.event_mask + 1);
11331da177e4SLinus Torvalds 		}
11341da177e4SLinus Torvalds 
11351da177e4SLinus Torvalds 		{
11361da177e4SLinus Torvalds 			struct hci_filter *f = &hci_pi(sk)->filter;
11371da177e4SLinus Torvalds 
11381da177e4SLinus Torvalds 			f->type_mask = uf.type_mask;
11391da177e4SLinus Torvalds 			f->opcode    = uf.opcode;
11401da177e4SLinus Torvalds 			*((u32 *) f->event_mask + 0) = uf.event_mask[0];
11411da177e4SLinus Torvalds 			*((u32 *) f->event_mask + 1) = uf.event_mask[1];
11421da177e4SLinus Torvalds 		}
11431da177e4SLinus Torvalds 		break;
11441da177e4SLinus Torvalds 
11451da177e4SLinus Torvalds 	default:
11461da177e4SLinus Torvalds 		err = -ENOPROTOOPT;
11471da177e4SLinus Torvalds 		break;
11481da177e4SLinus Torvalds 	}
11491da177e4SLinus Torvalds 
11502f39cdb7SMarcel Holtmann done:
11511da177e4SLinus Torvalds 	release_sock(sk);
11521da177e4SLinus Torvalds 	return err;
11531da177e4SLinus Torvalds }
11541da177e4SLinus Torvalds 
11558fc9ced3SGustavo Padovan static int hci_sock_getsockopt(struct socket *sock, int level, int optname,
11568fc9ced3SGustavo Padovan 			       char __user *optval, int __user *optlen)
11571da177e4SLinus Torvalds {
11581da177e4SLinus Torvalds 	struct hci_ufilter uf;
11591da177e4SLinus Torvalds 	struct sock *sk = sock->sk;
1160cedc5469SMarcel Holtmann 	int len, opt, err = 0;
1161cedc5469SMarcel Holtmann 
1162cedc5469SMarcel Holtmann 	BT_DBG("sk %p, opt %d", sk, optname);
11631da177e4SLinus Torvalds 
11641da177e4SLinus Torvalds 	if (get_user(len, optlen))
11651da177e4SLinus Torvalds 		return -EFAULT;
11661da177e4SLinus Torvalds 
1167cedc5469SMarcel Holtmann 	lock_sock(sk);
1168cedc5469SMarcel Holtmann 
1169cedc5469SMarcel Holtmann 	if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) {
1170c2371e80SMarcel Holtmann 		err = -EBADFD;
1171cedc5469SMarcel Holtmann 		goto done;
1172cedc5469SMarcel Holtmann 	}
1173cedc5469SMarcel Holtmann 
11741da177e4SLinus Torvalds 	switch (optname) {
11751da177e4SLinus Torvalds 	case HCI_DATA_DIR:
11761da177e4SLinus Torvalds 		if (hci_pi(sk)->cmsg_mask & HCI_CMSG_DIR)
11771da177e4SLinus Torvalds 			opt = 1;
11781da177e4SLinus Torvalds 		else
11791da177e4SLinus Torvalds 			opt = 0;
11801da177e4SLinus Torvalds 
11811da177e4SLinus Torvalds 		if (put_user(opt, optval))
1182cedc5469SMarcel Holtmann 			err = -EFAULT;
11831da177e4SLinus Torvalds 		break;
11841da177e4SLinus Torvalds 
11851da177e4SLinus Torvalds 	case HCI_TIME_STAMP:
11861da177e4SLinus Torvalds 		if (hci_pi(sk)->cmsg_mask & HCI_CMSG_TSTAMP)
11871da177e4SLinus Torvalds 			opt = 1;
11881da177e4SLinus Torvalds 		else
11891da177e4SLinus Torvalds 			opt = 0;
11901da177e4SLinus Torvalds 
11911da177e4SLinus Torvalds 		if (put_user(opt, optval))
1192cedc5469SMarcel Holtmann 			err = -EFAULT;
11931da177e4SLinus Torvalds 		break;
11941da177e4SLinus Torvalds 
11951da177e4SLinus Torvalds 	case HCI_FILTER:
11961da177e4SLinus Torvalds 		{
11971da177e4SLinus Torvalds 			struct hci_filter *f = &hci_pi(sk)->filter;
11981da177e4SLinus Torvalds 
1199e15ca9a0SMathias Krause 			memset(&uf, 0, sizeof(uf));
12001da177e4SLinus Torvalds 			uf.type_mask = f->type_mask;
12011da177e4SLinus Torvalds 			uf.opcode    = f->opcode;
12021da177e4SLinus Torvalds 			uf.event_mask[0] = *((u32 *) f->event_mask + 0);
12031da177e4SLinus Torvalds 			uf.event_mask[1] = *((u32 *) f->event_mask + 1);
12041da177e4SLinus Torvalds 		}
12051da177e4SLinus Torvalds 
12061da177e4SLinus Torvalds 		len = min_t(unsigned int, len, sizeof(uf));
12071da177e4SLinus Torvalds 		if (copy_to_user(optval, &uf, len))
1208cedc5469SMarcel Holtmann 			err = -EFAULT;
12091da177e4SLinus Torvalds 		break;
12101da177e4SLinus Torvalds 
12111da177e4SLinus Torvalds 	default:
1212cedc5469SMarcel Holtmann 		err = -ENOPROTOOPT;
12131da177e4SLinus Torvalds 		break;
12141da177e4SLinus Torvalds 	}
12151da177e4SLinus Torvalds 
1216cedc5469SMarcel Holtmann done:
1217cedc5469SMarcel Holtmann 	release_sock(sk);
1218cedc5469SMarcel Holtmann 	return err;
12191da177e4SLinus Torvalds }
12201da177e4SLinus Torvalds 
122190ddc4f0SEric Dumazet static const struct proto_ops hci_sock_ops = {
12221da177e4SLinus Torvalds 	.family		= PF_BLUETOOTH,
12231da177e4SLinus Torvalds 	.owner		= THIS_MODULE,
12241da177e4SLinus Torvalds 	.release	= hci_sock_release,
12251da177e4SLinus Torvalds 	.bind		= hci_sock_bind,
12261da177e4SLinus Torvalds 	.getname	= hci_sock_getname,
12271da177e4SLinus Torvalds 	.sendmsg	= hci_sock_sendmsg,
12281da177e4SLinus Torvalds 	.recvmsg	= hci_sock_recvmsg,
12291da177e4SLinus Torvalds 	.ioctl		= hci_sock_ioctl,
12301da177e4SLinus Torvalds 	.poll		= datagram_poll,
12311da177e4SLinus Torvalds 	.listen		= sock_no_listen,
12321da177e4SLinus Torvalds 	.shutdown	= sock_no_shutdown,
12331da177e4SLinus Torvalds 	.setsockopt	= hci_sock_setsockopt,
12341da177e4SLinus Torvalds 	.getsockopt	= hci_sock_getsockopt,
12351da177e4SLinus Torvalds 	.connect	= sock_no_connect,
12361da177e4SLinus Torvalds 	.socketpair	= sock_no_socketpair,
12371da177e4SLinus Torvalds 	.accept		= sock_no_accept,
12381da177e4SLinus Torvalds 	.mmap		= sock_no_mmap
12391da177e4SLinus Torvalds };
12401da177e4SLinus Torvalds 
12411da177e4SLinus Torvalds static struct proto hci_sk_proto = {
12421da177e4SLinus Torvalds 	.name		= "HCI",
12431da177e4SLinus Torvalds 	.owner		= THIS_MODULE,
12441da177e4SLinus Torvalds 	.obj_size	= sizeof(struct hci_pinfo)
12451da177e4SLinus Torvalds };
12461da177e4SLinus Torvalds 
12473f378b68SEric Paris static int hci_sock_create(struct net *net, struct socket *sock, int protocol,
12483f378b68SEric Paris 			   int kern)
12491da177e4SLinus Torvalds {
12501da177e4SLinus Torvalds 	struct sock *sk;
12511da177e4SLinus Torvalds 
12521da177e4SLinus Torvalds 	BT_DBG("sock %p", sock);
12531da177e4SLinus Torvalds 
12541da177e4SLinus Torvalds 	if (sock->type != SOCK_RAW)
12551da177e4SLinus Torvalds 		return -ESOCKTNOSUPPORT;
12561da177e4SLinus Torvalds 
12571da177e4SLinus Torvalds 	sock->ops = &hci_sock_ops;
12581da177e4SLinus Torvalds 
12596257ff21SPavel Emelyanov 	sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &hci_sk_proto);
12601da177e4SLinus Torvalds 	if (!sk)
12611da177e4SLinus Torvalds 		return -ENOMEM;
12621da177e4SLinus Torvalds 
12631da177e4SLinus Torvalds 	sock_init_data(sock, sk);
12641da177e4SLinus Torvalds 
12651da177e4SLinus Torvalds 	sock_reset_flag(sk, SOCK_ZAPPED);
12661da177e4SLinus Torvalds 
12671da177e4SLinus Torvalds 	sk->sk_protocol = protocol;
12681da177e4SLinus Torvalds 
12691da177e4SLinus Torvalds 	sock->state = SS_UNCONNECTED;
12701da177e4SLinus Torvalds 	sk->sk_state = BT_OPEN;
12711da177e4SLinus Torvalds 
12721da177e4SLinus Torvalds 	bt_sock_link(&hci_sk_list, sk);
12731da177e4SLinus Torvalds 	return 0;
12741da177e4SLinus Torvalds }
12751da177e4SLinus Torvalds 
1276ec1b4cf7SStephen Hemminger static const struct net_proto_family hci_sock_family_ops = {
12771da177e4SLinus Torvalds 	.family	= PF_BLUETOOTH,
12781da177e4SLinus Torvalds 	.owner	= THIS_MODULE,
12791da177e4SLinus Torvalds 	.create	= hci_sock_create,
12801da177e4SLinus Torvalds };
12811da177e4SLinus Torvalds 
12821da177e4SLinus Torvalds int __init hci_sock_init(void)
12831da177e4SLinus Torvalds {
12841da177e4SLinus Torvalds 	int err;
12851da177e4SLinus Torvalds 
1286b0a8e282SMarcel Holtmann 	BUILD_BUG_ON(sizeof(struct sockaddr_hci) > sizeof(struct sockaddr));
1287b0a8e282SMarcel Holtmann 
12881da177e4SLinus Torvalds 	err = proto_register(&hci_sk_proto, 0);
12891da177e4SLinus Torvalds 	if (err < 0)
12901da177e4SLinus Torvalds 		return err;
12911da177e4SLinus Torvalds 
12921da177e4SLinus Torvalds 	err = bt_sock_register(BTPROTO_HCI, &hci_sock_family_ops);
1293f7c86637SMasatake YAMATO 	if (err < 0) {
1294f7c86637SMasatake YAMATO 		BT_ERR("HCI socket registration failed");
12951da177e4SLinus Torvalds 		goto error;
1296f7c86637SMasatake YAMATO 	}
1297f7c86637SMasatake YAMATO 
1298b0316615SAl Viro 	err = bt_procfs_init(&init_net, "hci", &hci_sk_list, NULL);
1299f7c86637SMasatake YAMATO 	if (err < 0) {
1300f7c86637SMasatake YAMATO 		BT_ERR("Failed to create HCI proc file");
1301f7c86637SMasatake YAMATO 		bt_sock_unregister(BTPROTO_HCI);
1302f7c86637SMasatake YAMATO 		goto error;
1303f7c86637SMasatake YAMATO 	}
13041da177e4SLinus Torvalds 
13051da177e4SLinus Torvalds 	BT_INFO("HCI socket layer initialized");
13061da177e4SLinus Torvalds 
13071da177e4SLinus Torvalds 	return 0;
13081da177e4SLinus Torvalds 
13091da177e4SLinus Torvalds error:
13101da177e4SLinus Torvalds 	proto_unregister(&hci_sk_proto);
13111da177e4SLinus Torvalds 	return err;
13121da177e4SLinus Torvalds }
13131da177e4SLinus Torvalds 
1314b7440a14SAnand Gadiyar void hci_sock_cleanup(void)
13151da177e4SLinus Torvalds {
1316f7c86637SMasatake YAMATO 	bt_procfs_cleanup(&init_net, "hci");
13175e9d7f86SDavid Herrmann 	bt_sock_unregister(BTPROTO_HCI);
13181da177e4SLinus Torvalds 	proto_unregister(&hci_sk_proto);
13191da177e4SLinus Torvalds }
1320