blob: 4dda4574db3e603ad8ebd5ec6891c093dfdc6302 [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2000-2001 Qualcomm Incorporated
4
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090015 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090020 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth HCI sockets. */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <linux/module.h>
28
29#include <linux/types.h>
Randy Dunlap4fc268d2006-01-11 12:17:47 -080030#include <linux/capability.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <linux/errno.h>
32#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070033#include <linux/slab.h>
34#include <linux/poll.h>
35#include <linux/fcntl.h>
36#include <linux/init.h>
37#include <linux/skbuff.h>
38#include <linux/workqueue.h>
39#include <linux/interrupt.h>
Marcel Holtmann767c5eb2007-09-09 08:39:34 +020040#include <linux/compat.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070041#include <linux/socket.h>
42#include <linux/ioctl.h>
43#include <net/sock.h>
44
45#include <asm/system.h>
Andrei Emeltchenko70f230202010-12-01 16:58:25 +020046#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070047#include <asm/unaligned.h>
48
49#include <net/bluetooth/bluetooth.h>
50#include <net/bluetooth/hci_core.h>
51
Rusty Russelleb939922011-12-19 14:08:01 +000052static bool enable_mgmt;
Johan Hedberg03811012010-12-08 00:21:06 +020053
Linus Torvalds1da177e2005-04-16 15:20:36 -070054/* ----- HCI socket interface ----- */
55
56static inline int hci_test_bit(int nr, void *addr)
57{
58 return *((__u32 *) addr + (nr >> 5)) & ((__u32) 1 << (nr & 31));
59}
60
61/* Security filter */
62static struct hci_sec_filter hci_sec_filter = {
63 /* Packet types */
64 0x10,
65 /* Events */
Marcel Holtmanndd7f5522005-10-28 19:20:53 +020066 { 0x1000d9fe, 0x0000b00c },
Linus Torvalds1da177e2005-04-16 15:20:36 -070067 /* Commands */
68 {
69 { 0x0 },
70 /* OGF_LINK_CTL */
Marcel Holtmann7c631a62007-09-09 08:39:43 +020071 { 0xbe000006, 0x00000001, 0x00000000, 0x00 },
Linus Torvalds1da177e2005-04-16 15:20:36 -070072 /* OGF_LINK_POLICY */
Marcel Holtmann7c631a62007-09-09 08:39:43 +020073 { 0x00005200, 0x00000000, 0x00000000, 0x00 },
Linus Torvalds1da177e2005-04-16 15:20:36 -070074 /* OGF_HOST_CTL */
Marcel Holtmann7c631a62007-09-09 08:39:43 +020075 { 0xaab00200, 0x2b402aaa, 0x05220154, 0x00 },
Linus Torvalds1da177e2005-04-16 15:20:36 -070076 /* OGF_INFO_PARAM */
Marcel Holtmann7c631a62007-09-09 08:39:43 +020077 { 0x000002be, 0x00000000, 0x00000000, 0x00 },
Linus Torvalds1da177e2005-04-16 15:20:36 -070078 /* OGF_STATUS_PARAM */
Marcel Holtmann7c631a62007-09-09 08:39:43 +020079 { 0x000000ea, 0x00000000, 0x00000000, 0x00 }
Linus Torvalds1da177e2005-04-16 15:20:36 -070080 }
81};
82
83static struct bt_sock_list hci_sk_list = {
Robert P. J. Dayd5fb2962008-03-28 16:17:38 -070084 .lock = __RW_LOCK_UNLOCKED(hci_sk_list.lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -070085};
86
87/* Send frame to RAW socket */
Marcel Holtmann470fe1b2012-02-20 14:50:30 +010088void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070089{
90 struct sock *sk;
91 struct hlist_node *node;
92
93 BT_DBG("hdev %p len %d", hdev, skb->len);
94
95 read_lock(&hci_sk_list.lock);
Marcel Holtmann470fe1b2012-02-20 14:50:30 +010096
Linus Torvalds1da177e2005-04-16 15:20:36 -070097 sk_for_each(sk, node, &hci_sk_list.head) {
98 struct hci_filter *flt;
99 struct sk_buff *nskb;
100
101 if (sk->sk_state != BT_BOUND || hci_pi(sk)->hdev != hdev)
102 continue;
103
104 /* Don't send frame to the socket it came from */
105 if (skb->sk == sk)
106 continue;
107
Marcel Holtmann470fe1b2012-02-20 14:50:30 +0100108 if (hci_pi(sk)->channel != HCI_CHANNEL_RAW)
Johan Hedberga40c4062010-12-08 00:21:07 +0200109 continue;
110
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111 /* Apply filter */
112 flt = &hci_pi(sk)->filter;
113
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700114 if (!test_bit((bt_cb(skb)->pkt_type == HCI_VENDOR_PKT) ?
115 0 : (bt_cb(skb)->pkt_type & HCI_FLT_TYPE_BITS), &flt->type_mask))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116 continue;
117
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700118 if (bt_cb(skb)->pkt_type == HCI_EVENT_PKT) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700119 register int evt = (*(__u8 *)skb->data & HCI_FLT_EVENT_BITS);
120
121 if (!hci_test_bit(evt, &flt->event_mask))
122 continue;
123
David S. Miller4498c802006-11-21 16:17:41 -0800124 if (flt->opcode &&
125 ((evt == HCI_EV_CMD_COMPLETE &&
126 flt->opcode !=
Al Viro905f3ed2006-12-13 00:35:01 -0800127 get_unaligned((__le16 *)(skb->data + 3))) ||
David S. Miller4498c802006-11-21 16:17:41 -0800128 (evt == HCI_EV_CMD_STATUS &&
129 flt->opcode !=
Al Viro905f3ed2006-12-13 00:35:01 -0800130 get_unaligned((__le16 *)(skb->data + 4)))))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700131 continue;
132 }
133
Andrei Emeltchenko70f230202010-12-01 16:58:25 +0200134 nskb = skb_clone(skb, GFP_ATOMIC);
135 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700136 continue;
137
138 /* Put type byte before the data */
Marcel Holtmann470fe1b2012-02-20 14:50:30 +0100139 memcpy(skb_push(nskb, 1), &bt_cb(nskb)->pkt_type, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140
141 if (sock_queue_rcv_skb(sk, nskb))
142 kfree_skb(nskb);
143 }
Marcel Holtmann470fe1b2012-02-20 14:50:30 +0100144
145 read_unlock(&hci_sk_list.lock);
146}
147
148/* Send frame to control socket */
149void hci_send_to_control(struct sk_buff *skb, struct sock *skip_sk)
150{
151 struct sock *sk;
152 struct hlist_node *node;
153
154 BT_DBG("len %d", skb->len);
155
156 read_lock(&hci_sk_list.lock);
157
158 sk_for_each(sk, node, &hci_sk_list.head) {
159 struct sk_buff *nskb;
160
161 /* Skip the original socket */
162 if (sk == skip_sk)
163 continue;
164
165 if (sk->sk_state != BT_BOUND)
166 continue;
167
168 if (hci_pi(sk)->channel != HCI_CHANNEL_CONTROL)
169 continue;
170
171 nskb = skb_clone(skb, GFP_ATOMIC);
172 if (!nskb)
173 continue;
174
175 if (sock_queue_rcv_skb(sk, nskb))
176 kfree_skb(nskb);
177 }
178
Linus Torvalds1da177e2005-04-16 15:20:36 -0700179 read_unlock(&hci_sk_list.lock);
180}
181
182static int hci_sock_release(struct socket *sock)
183{
184 struct sock *sk = sock->sk;
Marcel Holtmann7b005bd2006-02-13 11:40:03 +0100185 struct hci_dev *hdev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700186
187 BT_DBG("sock %p sk %p", sock, sk);
188
189 if (!sk)
190 return 0;
191
Marcel Holtmann7b005bd2006-02-13 11:40:03 +0100192 hdev = hci_pi(sk)->hdev;
193
Linus Torvalds1da177e2005-04-16 15:20:36 -0700194 bt_sock_unlink(&hci_sk_list, sk);
195
196 if (hdev) {
197 atomic_dec(&hdev->promisc);
198 hci_dev_put(hdev);
199 }
200
201 sock_orphan(sk);
202
203 skb_queue_purge(&sk->sk_receive_queue);
204 skb_queue_purge(&sk->sk_write_queue);
205
206 sock_put(sk);
207 return 0;
208}
209
Antti Julkub2a66aa2011-06-15 12:01:14 +0300210static int hci_sock_blacklist_add(struct hci_dev *hdev, void __user *arg)
Johan Hedbergf0358562010-05-18 13:20:32 +0200211{
212 bdaddr_t bdaddr;
Antti Julku5e762442011-08-25 16:48:02 +0300213 int err;
Johan Hedbergf0358562010-05-18 13:20:32 +0200214
215 if (copy_from_user(&bdaddr, arg, sizeof(bdaddr)))
216 return -EFAULT;
217
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -0300218 hci_dev_lock(hdev);
Antti Julku5e762442011-08-25 16:48:02 +0300219
Johan Hedberg88c1fe42012-02-09 15:56:11 +0200220 err = hci_blacklist_add(hdev, &bdaddr, 0);
Antti Julku5e762442011-08-25 16:48:02 +0300221
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -0300222 hci_dev_unlock(hdev);
Antti Julku5e762442011-08-25 16:48:02 +0300223
224 return err;
Johan Hedbergf0358562010-05-18 13:20:32 +0200225}
226
Antti Julkub2a66aa2011-06-15 12:01:14 +0300227static int hci_sock_blacklist_del(struct hci_dev *hdev, void __user *arg)
Johan Hedbergf0358562010-05-18 13:20:32 +0200228{
229 bdaddr_t bdaddr;
Antti Julku5e762442011-08-25 16:48:02 +0300230 int err;
Johan Hedbergf0358562010-05-18 13:20:32 +0200231
232 if (copy_from_user(&bdaddr, arg, sizeof(bdaddr)))
233 return -EFAULT;
234
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -0300235 hci_dev_lock(hdev);
Antti Julku5e762442011-08-25 16:48:02 +0300236
Johan Hedberg88c1fe42012-02-09 15:56:11 +0200237 err = hci_blacklist_del(hdev, &bdaddr, 0);
Antti Julku5e762442011-08-25 16:48:02 +0300238
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -0300239 hci_dev_unlock(hdev);
Antti Julku5e762442011-08-25 16:48:02 +0300240
241 return err;
Johan Hedbergf0358562010-05-18 13:20:32 +0200242}
243
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900244/* Ioctls that require bound socket */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700245static inline int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg)
246{
247 struct hci_dev *hdev = hci_pi(sk)->hdev;
248
249 if (!hdev)
250 return -EBADFD;
251
252 switch (cmd) {
253 case HCISETRAW:
254 if (!capable(CAP_NET_ADMIN))
255 return -EACCES;
256
257 if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
258 return -EPERM;
259
260 if (arg)
261 set_bit(HCI_RAW, &hdev->flags);
262 else
263 clear_bit(HCI_RAW, &hdev->flags);
264
265 return 0;
266
Linus Torvalds1da177e2005-04-16 15:20:36 -0700267 case HCIGETCONNINFO:
Marcel Holtmann40be4922008-07-14 20:13:50 +0200268 return hci_get_conn_info(hdev, (void __user *) arg);
269
270 case HCIGETAUTHINFO:
271 return hci_get_auth_info(hdev, (void __user *) arg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700272
Johan Hedbergf0358562010-05-18 13:20:32 +0200273 case HCIBLOCKADDR:
274 if (!capable(CAP_NET_ADMIN))
275 return -EACCES;
Antti Julkub2a66aa2011-06-15 12:01:14 +0300276 return hci_sock_blacklist_add(hdev, (void __user *) arg);
Johan Hedbergf0358562010-05-18 13:20:32 +0200277
278 case HCIUNBLOCKADDR:
279 if (!capable(CAP_NET_ADMIN))
280 return -EACCES;
Antti Julkub2a66aa2011-06-15 12:01:14 +0300281 return hci_sock_blacklist_del(hdev, (void __user *) arg);
Johan Hedbergf0358562010-05-18 13:20:32 +0200282
Linus Torvalds1da177e2005-04-16 15:20:36 -0700283 default:
284 if (hdev->ioctl)
285 return hdev->ioctl(hdev, cmd, arg);
286 return -EINVAL;
287 }
288}
289
290static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
291{
292 struct sock *sk = sock->sk;
Marcel Holtmann40be4922008-07-14 20:13:50 +0200293 void __user *argp = (void __user *) arg;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700294 int err;
295
296 BT_DBG("cmd %x arg %lx", cmd, arg);
297
298 switch (cmd) {
299 case HCIGETDEVLIST:
300 return hci_get_dev_list(argp);
301
302 case HCIGETDEVINFO:
303 return hci_get_dev_info(argp);
304
305 case HCIGETCONNLIST:
306 return hci_get_conn_list(argp);
307
308 case HCIDEVUP:
309 if (!capable(CAP_NET_ADMIN))
310 return -EACCES;
311 return hci_dev_open(arg);
312
313 case HCIDEVDOWN:
314 if (!capable(CAP_NET_ADMIN))
315 return -EACCES;
316 return hci_dev_close(arg);
317
318 case HCIDEVRESET:
319 if (!capable(CAP_NET_ADMIN))
320 return -EACCES;
321 return hci_dev_reset(arg);
322
323 case HCIDEVRESTAT:
324 if (!capable(CAP_NET_ADMIN))
325 return -EACCES;
326 return hci_dev_reset_stat(arg);
327
328 case HCISETSCAN:
329 case HCISETAUTH:
330 case HCISETENCRYPT:
331 case HCISETPTYPE:
332 case HCISETLINKPOL:
333 case HCISETLINKMODE:
334 case HCISETACLMTU:
335 case HCISETSCOMTU:
336 if (!capable(CAP_NET_ADMIN))
337 return -EACCES;
338 return hci_dev_cmd(cmd, argp);
339
340 case HCIINQUIRY:
341 return hci_inquiry(argp);
342
343 default:
344 lock_sock(sk);
345 err = hci_sock_bound_ioctl(sk, cmd, arg);
346 release_sock(sk);
347 return err;
348 }
349}
350
351static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
352{
Johan Hedberg03811012010-12-08 00:21:06 +0200353 struct sockaddr_hci haddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700354 struct sock *sk = sock->sk;
355 struct hci_dev *hdev = NULL;
Johan Hedberg03811012010-12-08 00:21:06 +0200356 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700357
358 BT_DBG("sock %p sk %p", sock, sk);
359
Johan Hedberg03811012010-12-08 00:21:06 +0200360 if (!addr)
361 return -EINVAL;
362
363 memset(&haddr, 0, sizeof(haddr));
364 len = min_t(unsigned int, sizeof(haddr), addr_len);
365 memcpy(&haddr, addr, len);
366
367 if (haddr.hci_family != AF_BLUETOOTH)
368 return -EINVAL;
369
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370 lock_sock(sk);
371
Marcel Holtmann7cc2ade2012-02-20 14:50:35 +0100372 if (sk->sk_state == BT_BOUND) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373 err = -EALREADY;
374 goto done;
375 }
376
Marcel Holtmann7cc2ade2012-02-20 14:50:35 +0100377 switch (haddr.hci_channel) {
378 case HCI_CHANNEL_RAW:
379 if (hci_pi(sk)->hdev) {
380 err = -EALREADY;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381 goto done;
382 }
383
Marcel Holtmann7cc2ade2012-02-20 14:50:35 +0100384 if (haddr.hci_dev != HCI_DEV_NONE) {
385 hdev = hci_dev_get(haddr.hci_dev);
386 if (!hdev) {
387 err = -ENODEV;
388 goto done;
389 }
390
391 atomic_inc(&hdev->promisc);
392 }
393
394 hci_pi(sk)->hdev = hdev;
395 break;
396
397 case HCI_CHANNEL_CONTROL:
398 if (haddr.hci_dev != HCI_DEV_NONE || !enable_mgmt) {
399 err = -EINVAL;
400 goto done;
401 }
402
403 set_bit(HCI_PI_MGMT_INIT, &hci_pi(sk)->flags);
404 break;
405
406 default:
407 err = -EINVAL;
408 goto done;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409 }
410
Marcel Holtmann7cc2ade2012-02-20 14:50:35 +0100411
Johan Hedberg03811012010-12-08 00:21:06 +0200412 hci_pi(sk)->channel = haddr.hci_channel;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413 sk->sk_state = BT_BOUND;
414
415done:
416 release_sock(sk);
417 return err;
418}
419
420static int hci_sock_getname(struct socket *sock, struct sockaddr *addr, int *addr_len, int peer)
421{
422 struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr;
423 struct sock *sk = sock->sk;
Marcel Holtmann7b005bd2006-02-13 11:40:03 +0100424 struct hci_dev *hdev = hci_pi(sk)->hdev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425
426 BT_DBG("sock %p sk %p", sock, sk);
427
Marcel Holtmann7b005bd2006-02-13 11:40:03 +0100428 if (!hdev)
429 return -EBADFD;
430
Linus Torvalds1da177e2005-04-16 15:20:36 -0700431 lock_sock(sk);
432
433 *addr_len = sizeof(*haddr);
434 haddr->hci_family = AF_BLUETOOTH;
Marcel Holtmann7b005bd2006-02-13 11:40:03 +0100435 haddr->hci_dev = hdev->id;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700436
437 release_sock(sk);
438 return 0;
439}
440
441static inline void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
442{
443 __u32 mask = hci_pi(sk)->cmsg_mask;
444
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700445 if (mask & HCI_CMSG_DIR) {
446 int incoming = bt_cb(skb)->incoming;
447 put_cmsg(msg, SOL_HCI, HCI_CMSG_DIR, sizeof(incoming), &incoming);
448 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449
Patrick McHardya61bbcf2005-08-14 17:24:31 -0700450 if (mask & HCI_CMSG_TSTAMP) {
Johann Felix Sodenf6e623a2010-02-15 22:23:48 +0100451#ifdef CONFIG_COMPAT
452 struct compat_timeval ctv;
453#endif
Patrick McHardya61bbcf2005-08-14 17:24:31 -0700454 struct timeval tv;
Marcel Holtmann767c5eb2007-09-09 08:39:34 +0200455 void *data;
456 int len;
Patrick McHardya61bbcf2005-08-14 17:24:31 -0700457
458 skb_get_timestamp(skb, &tv);
Marcel Holtmann767c5eb2007-09-09 08:39:34 +0200459
David S. Miller1da97f82007-09-12 14:10:58 +0200460 data = &tv;
461 len = sizeof(tv);
462#ifdef CONFIG_COMPAT
Marcel Holtmann767c5eb2007-09-09 08:39:34 +0200463 if (msg->msg_flags & MSG_CMSG_COMPAT) {
Marcel Holtmann767c5eb2007-09-09 08:39:34 +0200464 ctv.tv_sec = tv.tv_sec;
465 ctv.tv_usec = tv.tv_usec;
466 data = &ctv;
467 len = sizeof(ctv);
Marcel Holtmann767c5eb2007-09-09 08:39:34 +0200468 }
David S. Miller1da97f82007-09-12 14:10:58 +0200469#endif
Marcel Holtmann767c5eb2007-09-09 08:39:34 +0200470
471 put_cmsg(msg, SOL_HCI, HCI_CMSG_TSTAMP, len, data);
Patrick McHardya61bbcf2005-08-14 17:24:31 -0700472 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700473}
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900474
475static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700476 struct msghdr *msg, size_t len, int flags)
477{
478 int noblock = flags & MSG_DONTWAIT;
479 struct sock *sk = sock->sk;
480 struct sk_buff *skb;
481 int copied, err;
482
483 BT_DBG("sock %p, sk %p", sock, sk);
484
485 if (flags & (MSG_OOB))
486 return -EOPNOTSUPP;
487
488 if (sk->sk_state == BT_CLOSED)
489 return 0;
490
Andrei Emeltchenko70f230202010-12-01 16:58:25 +0200491 skb = skb_recv_datagram(sk, flags, noblock, &err);
492 if (!skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700493 return err;
494
495 msg->msg_namelen = 0;
496
497 copied = skb->len;
498 if (len < copied) {
499 msg->msg_flags |= MSG_TRUNC;
500 copied = len;
501 }
502
Arnaldo Carvalho de Melobadff6d2007-03-13 13:06:52 -0300503 skb_reset_transport_header(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700504 err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
505
Marcel Holtmann3a208622012-02-20 14:50:34 +0100506 switch (hci_pi(sk)->channel) {
507 case HCI_CHANNEL_RAW:
508 hci_sock_cmsg(sk, msg, skb);
509 break;
510 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700511
512 skb_free_datagram(sk, skb);
513
514 return err ? : copied;
515}
516
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900517static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518 struct msghdr *msg, size_t len)
519{
520 struct sock *sk = sock->sk;
521 struct hci_dev *hdev;
522 struct sk_buff *skb;
523 int err;
524
525 BT_DBG("sock %p sk %p", sock, sk);
526
527 if (msg->msg_flags & MSG_OOB)
528 return -EOPNOTSUPP;
529
530 if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE))
531 return -EINVAL;
532
533 if (len < 4 || len > HCI_MAX_FRAME_SIZE)
534 return -EINVAL;
535
536 lock_sock(sk);
537
Johan Hedberg03811012010-12-08 00:21:06 +0200538 switch (hci_pi(sk)->channel) {
539 case HCI_CHANNEL_RAW:
540 break;
541 case HCI_CHANNEL_CONTROL:
542 err = mgmt_control(sk, msg, len);
543 goto done;
544 default:
545 err = -EINVAL;
546 goto done;
547 }
548
Andrei Emeltchenko70f230202010-12-01 16:58:25 +0200549 hdev = hci_pi(sk)->hdev;
550 if (!hdev) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551 err = -EBADFD;
552 goto done;
553 }
554
Marcel Holtmann7e21add2009-11-18 01:05:00 +0100555 if (!test_bit(HCI_UP, &hdev->flags)) {
556 err = -ENETDOWN;
557 goto done;
558 }
559
Andrei Emeltchenko70f230202010-12-01 16:58:25 +0200560 skb = bt_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err);
561 if (!skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700562 goto done;
563
564 if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
565 err = -EFAULT;
566 goto drop;
567 }
568
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700569 bt_cb(skb)->pkt_type = *((unsigned char *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570 skb_pull(skb, 1);
571 skb->dev = (void *) hdev;
572
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700573 if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) {
Harvey Harrison83985312008-05-02 16:25:46 -0700574 u16 opcode = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700575 u16 ogf = hci_opcode_ogf(opcode);
576 u16 ocf = hci_opcode_ocf(opcode);
577
578 if (((ogf > HCI_SFLT_MAX_OGF) ||
579 !hci_test_bit(ocf & HCI_FLT_OCF_BITS, &hci_sec_filter.ocf_mask[ogf])) &&
580 !capable(CAP_NET_RAW)) {
581 err = -EPERM;
582 goto drop;
583 }
584
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200585 if (test_bit(HCI_RAW, &hdev->flags) || (ogf == 0x3f)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700586 skb_queue_tail(&hdev->raw_q, skb);
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -0200587 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588 } else {
589 skb_queue_tail(&hdev->cmd_q, skb);
Gustavo F. Padovanc347b762011-12-14 23:53:47 -0200590 queue_work(hdev->workqueue, &hdev->cmd_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700591 }
592 } else {
593 if (!capable(CAP_NET_RAW)) {
594 err = -EPERM;
595 goto drop;
596 }
597
598 skb_queue_tail(&hdev->raw_q, skb);
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -0200599 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600 }
601
602 err = len;
603
604done:
605 release_sock(sk);
606 return err;
607
608drop:
609 kfree_skb(skb);
610 goto done;
611}
612
David S. Millerb7058842009-09-30 16:12:20 -0700613static int hci_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int len)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700614{
615 struct hci_ufilter uf = { .opcode = 0 };
616 struct sock *sk = sock->sk;
617 int err = 0, opt = 0;
618
619 BT_DBG("sk %p, opt %d", sk, optname);
620
621 lock_sock(sk);
622
Marcel Holtmann2f39cdb2012-02-20 14:50:32 +0100623 if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) {
624 err = -EINVAL;
625 goto done;
626 }
627
Linus Torvalds1da177e2005-04-16 15:20:36 -0700628 switch (optname) {
629 case HCI_DATA_DIR:
630 if (get_user(opt, (int __user *)optval)) {
631 err = -EFAULT;
632 break;
633 }
634
635 if (opt)
636 hci_pi(sk)->cmsg_mask |= HCI_CMSG_DIR;
637 else
638 hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_DIR;
639 break;
640
641 case HCI_TIME_STAMP:
642 if (get_user(opt, (int __user *)optval)) {
643 err = -EFAULT;
644 break;
645 }
646
647 if (opt)
648 hci_pi(sk)->cmsg_mask |= HCI_CMSG_TSTAMP;
649 else
650 hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_TSTAMP;
651 break;
652
653 case HCI_FILTER:
Marcel Holtmann0878b662007-05-05 00:35:59 +0200654 {
655 struct hci_filter *f = &hci_pi(sk)->filter;
656
657 uf.type_mask = f->type_mask;
658 uf.opcode = f->opcode;
659 uf.event_mask[0] = *((u32 *) f->event_mask + 0);
660 uf.event_mask[1] = *((u32 *) f->event_mask + 1);
661 }
662
Linus Torvalds1da177e2005-04-16 15:20:36 -0700663 len = min_t(unsigned int, len, sizeof(uf));
664 if (copy_from_user(&uf, optval, len)) {
665 err = -EFAULT;
666 break;
667 }
668
669 if (!capable(CAP_NET_RAW)) {
670 uf.type_mask &= hci_sec_filter.type_mask;
671 uf.event_mask[0] &= *((u32 *) hci_sec_filter.event_mask + 0);
672 uf.event_mask[1] &= *((u32 *) hci_sec_filter.event_mask + 1);
673 }
674
675 {
676 struct hci_filter *f = &hci_pi(sk)->filter;
677
678 f->type_mask = uf.type_mask;
679 f->opcode = uf.opcode;
680 *((u32 *) f->event_mask + 0) = uf.event_mask[0];
681 *((u32 *) f->event_mask + 1) = uf.event_mask[1];
682 }
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900683 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700684
685 default:
686 err = -ENOPROTOOPT;
687 break;
688 }
689
Marcel Holtmann2f39cdb2012-02-20 14:50:32 +0100690done:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700691 release_sock(sk);
692 return err;
693}
694
695static int hci_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
696{
697 struct hci_ufilter uf;
698 struct sock *sk = sock->sk;
Marcel Holtmanncedc5462012-02-20 14:50:33 +0100699 int len, opt, err = 0;
700
701 BT_DBG("sk %p, opt %d", sk, optname);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700702
703 if (get_user(len, optlen))
704 return -EFAULT;
705
Marcel Holtmanncedc5462012-02-20 14:50:33 +0100706 lock_sock(sk);
707
708 if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) {
709 err = -EINVAL;
710 goto done;
711 }
712
Linus Torvalds1da177e2005-04-16 15:20:36 -0700713 switch (optname) {
714 case HCI_DATA_DIR:
715 if (hci_pi(sk)->cmsg_mask & HCI_CMSG_DIR)
716 opt = 1;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900717 else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700718 opt = 0;
719
720 if (put_user(opt, optval))
Marcel Holtmanncedc5462012-02-20 14:50:33 +0100721 err = -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700722 break;
723
724 case HCI_TIME_STAMP:
725 if (hci_pi(sk)->cmsg_mask & HCI_CMSG_TSTAMP)
726 opt = 1;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900727 else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700728 opt = 0;
729
730 if (put_user(opt, optval))
Marcel Holtmanncedc5462012-02-20 14:50:33 +0100731 err = -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700732 break;
733
734 case HCI_FILTER:
735 {
736 struct hci_filter *f = &hci_pi(sk)->filter;
737
738 uf.type_mask = f->type_mask;
739 uf.opcode = f->opcode;
740 uf.event_mask[0] = *((u32 *) f->event_mask + 0);
741 uf.event_mask[1] = *((u32 *) f->event_mask + 1);
742 }
743
744 len = min_t(unsigned int, len, sizeof(uf));
745 if (copy_to_user(optval, &uf, len))
Marcel Holtmanncedc5462012-02-20 14:50:33 +0100746 err = -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700747 break;
748
749 default:
Marcel Holtmanncedc5462012-02-20 14:50:33 +0100750 err = -ENOPROTOOPT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700751 break;
752 }
753
Marcel Holtmanncedc5462012-02-20 14:50:33 +0100754done:
755 release_sock(sk);
756 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700757}
758
Eric Dumazet90ddc4f2005-12-22 12:49:22 -0800759static const struct proto_ops hci_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700760 .family = PF_BLUETOOTH,
761 .owner = THIS_MODULE,
762 .release = hci_sock_release,
763 .bind = hci_sock_bind,
764 .getname = hci_sock_getname,
765 .sendmsg = hci_sock_sendmsg,
766 .recvmsg = hci_sock_recvmsg,
767 .ioctl = hci_sock_ioctl,
768 .poll = datagram_poll,
769 .listen = sock_no_listen,
770 .shutdown = sock_no_shutdown,
771 .setsockopt = hci_sock_setsockopt,
772 .getsockopt = hci_sock_getsockopt,
773 .connect = sock_no_connect,
774 .socketpair = sock_no_socketpair,
775 .accept = sock_no_accept,
776 .mmap = sock_no_mmap
777};
778
779static struct proto hci_sk_proto = {
780 .name = "HCI",
781 .owner = THIS_MODULE,
782 .obj_size = sizeof(struct hci_pinfo)
783};
784
Eric Paris3f378b62009-11-05 22:18:14 -0800785static int hci_sock_create(struct net *net, struct socket *sock, int protocol,
786 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700787{
788 struct sock *sk;
789
790 BT_DBG("sock %p", sock);
791
792 if (sock->type != SOCK_RAW)
793 return -ESOCKTNOSUPPORT;
794
795 sock->ops = &hci_sock_ops;
796
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700797 sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &hci_sk_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700798 if (!sk)
799 return -ENOMEM;
800
801 sock_init_data(sock, sk);
802
803 sock_reset_flag(sk, SOCK_ZAPPED);
804
805 sk->sk_protocol = protocol;
806
807 sock->state = SS_UNCONNECTED;
808 sk->sk_state = BT_OPEN;
809
810 bt_sock_link(&hci_sk_list, sk);
811 return 0;
812}
813
814static int hci_sock_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
815{
816 struct hci_dev *hdev = (struct hci_dev *) ptr;
817 struct hci_ev_si_device ev;
818
819 BT_DBG("hdev %s event %ld", hdev->name, event);
820
821 /* Send event to sockets */
822 ev.event = event;
823 ev.dev_id = hdev->id;
824 hci_si_event(NULL, HCI_EV_SI_DEVICE, sizeof(ev), &ev);
825
826 if (event == HCI_DEV_UNREG) {
827 struct sock *sk;
828 struct hlist_node *node;
829
830 /* Detach sockets from device */
831 read_lock(&hci_sk_list.lock);
832 sk_for_each(sk, node, &hci_sk_list.head) {
Satyam Sharma4ce61d12007-05-16 23:50:16 -0700833 bh_lock_sock_nested(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700834 if (hci_pi(sk)->hdev == hdev) {
835 hci_pi(sk)->hdev = NULL;
836 sk->sk_err = EPIPE;
837 sk->sk_state = BT_OPEN;
838 sk->sk_state_change(sk);
839
840 hci_dev_put(hdev);
841 }
Satyam Sharma4ce61d12007-05-16 23:50:16 -0700842 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700843 }
844 read_unlock(&hci_sk_list.lock);
845 }
846
847 return NOTIFY_DONE;
848}
849
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +0000850static const struct net_proto_family hci_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700851 .family = PF_BLUETOOTH,
852 .owner = THIS_MODULE,
853 .create = hci_sock_create,
854};
855
856static struct notifier_block hci_sock_nblock = {
857 .notifier_call = hci_sock_dev_event
858};
859
860int __init hci_sock_init(void)
861{
862 int err;
863
864 err = proto_register(&hci_sk_proto, 0);
865 if (err < 0)
866 return err;
867
868 err = bt_sock_register(BTPROTO_HCI, &hci_sock_family_ops);
869 if (err < 0)
870 goto error;
871
872 hci_register_notifier(&hci_sock_nblock);
873
874 BT_INFO("HCI socket layer initialized");
875
876 return 0;
877
878error:
879 BT_ERR("HCI socket registration failed");
880 proto_unregister(&hci_sk_proto);
881 return err;
882}
883
Anand Gadiyarb7440a142011-02-22 12:43:09 +0530884void hci_sock_cleanup(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700885{
886 if (bt_sock_unregister(BTPROTO_HCI) < 0)
887 BT_ERR("HCI socket unregistration failed");
888
889 hci_unregister_notifier(&hci_sock_nblock);
890
891 proto_unregister(&hci_sk_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700892}
Johan Hedberg03811012010-12-08 00:21:06 +0200893
894module_param(enable_mgmt, bool, 0644);
895MODULE_PARM_DESC(enable_mgmt, "Enable Management interface");