blob: 550f60197a6916d22ed4457e7b5ed4f239febcad [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
Duy Truong790f06d2013-02-13 16:38:12 -08003 Copyright (c) 2000-2001, 2011, The Linux Foundation. All rights reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004
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
Steve Mucklef132c6c2012-06-06 18:30:57 -070052static bool enable_mgmt = 1;
Marcel Holtmanncd82e612012-02-20 20:34:38 +010053
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 */
Johan Hedbergeec8d2b2010-12-16 10:17:38 +020088void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb,
89 struct sock *skip_sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -070090{
91 struct sock *sk;
92 struct hlist_node *node;
93
94 BT_DBG("hdev %p len %d", hdev, skb->len);
95
96 read_lock(&hci_sk_list.lock);
97 sk_for_each(sk, node, &hci_sk_list.head) {
98 struct hci_filter *flt;
99 struct sk_buff *nskb;
100
Johan Hedbergeec8d2b2010-12-16 10:17:38 +0200101 if (sk == skip_sk)
102 continue;
103
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104 if (sk->sk_state != BT_BOUND || hci_pi(sk)->hdev != hdev)
105 continue;
106
107 /* Don't send frame to the socket it came from */
108 if (skb->sk == sk)
109 continue;
110
Johan Hedberga40c4062010-12-08 00:21:07 +0200111 if (bt_cb(skb)->channel != hci_pi(sk)->channel)
112 continue;
113
114 if (bt_cb(skb)->channel == HCI_CHANNEL_CONTROL)
115 goto clone;
116
Linus Torvalds1da177e2005-04-16 15:20:36 -0700117 /* Apply filter */
118 flt = &hci_pi(sk)->filter;
119
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700120 if (!test_bit((bt_cb(skb)->pkt_type == HCI_VENDOR_PKT) ?
121 0 : (bt_cb(skb)->pkt_type & HCI_FLT_TYPE_BITS), &flt->type_mask))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122 continue;
123
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700124 if (bt_cb(skb)->pkt_type == HCI_EVENT_PKT) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125 register int evt = (*(__u8 *)skb->data & HCI_FLT_EVENT_BITS);
126
127 if (!hci_test_bit(evt, &flt->event_mask))
128 continue;
129
David S. Miller4498c802006-11-21 16:17:41 -0800130 if (flt->opcode &&
131 ((evt == HCI_EV_CMD_COMPLETE &&
132 flt->opcode !=
Al Viro905f3ed2006-12-13 00:35:01 -0800133 get_unaligned((__le16 *)(skb->data + 3))) ||
David S. Miller4498c802006-11-21 16:17:41 -0800134 (evt == HCI_EV_CMD_STATUS &&
135 flt->opcode !=
Al Viro905f3ed2006-12-13 00:35:01 -0800136 get_unaligned((__le16 *)(skb->data + 4)))))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700137 continue;
138 }
139
Johan Hedberga40c4062010-12-08 00:21:07 +0200140clone:
Marcel Holtmann470fe1b2012-02-20 14:50:30 +0100141 nskb = skb_clone(skb, GFP_ATOMIC);
142 if (!nskb)
143 continue;
144
Linus Torvalds1da177e2005-04-16 15:20:36 -0700145 /* Put type byte before the data */
Johan Hedberga40c4062010-12-08 00:21:07 +0200146 if (bt_cb(skb)->channel == HCI_CHANNEL_RAW)
147 memcpy(skb_push(nskb, 1), &bt_cb(nskb)->pkt_type, 1);
Marcel Holtmanncd82e612012-02-20 20:34:38 +0100148
149 if (sock_queue_rcv_skb(sk, nskb))
150 kfree_skb(nskb);
151 }
Marcel Holtmanncd82e612012-02-20 20:34:38 +0100152 read_unlock(&hci_sk_list.lock);
Marcel Holtmann040030e2012-02-20 14:50:37 +0100153}
154
Linus Torvalds1da177e2005-04-16 15:20:36 -0700155static int hci_sock_release(struct socket *sock)
156{
157 struct sock *sk = sock->sk;
Marcel Holtmann7b005bd2006-02-13 11:40:03 +0100158 struct hci_dev *hdev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700159
160 BT_DBG("sock %p sk %p", sock, sk);
161
162 if (!sk)
163 return 0;
164
Marcel Holtmann7b005bd2006-02-13 11:40:03 +0100165 hdev = hci_pi(sk)->hdev;
166
Linus Torvalds1da177e2005-04-16 15:20:36 -0700167 bt_sock_unlink(&hci_sk_list, sk);
168
169 if (hdev) {
170 atomic_dec(&hdev->promisc);
171 hci_dev_put(hdev);
172 }
173
174 sock_orphan(sk);
175
176 skb_queue_purge(&sk->sk_receive_queue);
177 skb_queue_purge(&sk->sk_write_queue);
178
179 sock_put(sk);
180 return 0;
181}
182
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700183struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
Johan Hedbergf0358562010-05-18 13:20:32 +0200184{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700185 struct list_head *p;
Johan Hedbergf0358562010-05-18 13:20:32 +0200186
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700187 list_for_each(p, &hdev->blacklist) {
188 struct bdaddr_list *b;
Johan Hedbergf0358562010-05-18 13:20:32 +0200189
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700190 b = list_entry(p, struct bdaddr_list, list);
Antti Julku5e762442011-08-25 16:48:02 +0300191
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700192 if (bacmp(bdaddr, &b->bdaddr) == 0)
193 return b;
194 }
Antti Julku5e762442011-08-25 16:48:02 +0300195
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700196 return NULL;
Johan Hedbergf0358562010-05-18 13:20:32 +0200197}
198
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700199static int hci_blacklist_add(struct hci_dev *hdev, void __user *arg)
Johan Hedbergf0358562010-05-18 13:20:32 +0200200{
201 bdaddr_t bdaddr;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700202 struct bdaddr_list *entry;
Johan Hedbergf0358562010-05-18 13:20:32 +0200203
204 if (copy_from_user(&bdaddr, arg, sizeof(bdaddr)))
205 return -EFAULT;
206
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700207 if (bacmp(&bdaddr, BDADDR_ANY) == 0)
208 return -EBADF;
Antti Julku5e762442011-08-25 16:48:02 +0300209
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700210 if (hci_blacklist_lookup(hdev, &bdaddr))
211 return -EEXIST;
Antti Julku5e762442011-08-25 16:48:02 +0300212
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700213 entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
214 if (!entry)
215 return -ENOMEM;
Antti Julku5e762442011-08-25 16:48:02 +0300216
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700217 bacpy(&entry->bdaddr, &bdaddr);
218
219 list_add(&entry->list, &hdev->blacklist);
220
221 return 0;
222}
223
224int hci_blacklist_clear(struct hci_dev *hdev)
225{
226 struct list_head *p, *n;
227
228 list_for_each_safe(p, n, &hdev->blacklist) {
229 struct bdaddr_list *b;
230
231 b = list_entry(p, struct bdaddr_list, list);
232
233 list_del(p);
234 kfree(b);
235 }
236
237 return 0;
238}
239
240static int hci_blacklist_del(struct hci_dev *hdev, void __user *arg)
241{
242 bdaddr_t bdaddr;
243 struct bdaddr_list *entry;
244
245 if (copy_from_user(&bdaddr, arg, sizeof(bdaddr)))
246 return -EFAULT;
247
248 if (bacmp(&bdaddr, BDADDR_ANY) == 0)
249 return hci_blacklist_clear(hdev);
250
251 entry = hci_blacklist_lookup(hdev, &bdaddr);
252 if (!entry)
253 return -ENOENT;
254
255 list_del(&entry->list);
256 kfree(entry);
257
258 return 0;
Johan Hedbergf0358562010-05-18 13:20:32 +0200259}
260
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900261/* Ioctls that require bound socket */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700262static inline int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg)
263{
264 struct hci_dev *hdev = hci_pi(sk)->hdev;
265
266 if (!hdev)
267 return -EBADFD;
268
269 switch (cmd) {
270 case HCISETRAW:
271 if (!capable(CAP_NET_ADMIN))
272 return -EACCES;
273
274 if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
275 return -EPERM;
276
277 if (arg)
278 set_bit(HCI_RAW, &hdev->flags);
279 else
280 clear_bit(HCI_RAW, &hdev->flags);
281
282 return 0;
283
Linus Torvalds1da177e2005-04-16 15:20:36 -0700284 case HCIGETCONNINFO:
Marcel Holtmann40be4922008-07-14 20:13:50 +0200285 return hci_get_conn_info(hdev, (void __user *) arg);
286
287 case HCIGETAUTHINFO:
288 return hci_get_auth_info(hdev, (void __user *) arg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700289
Johan Hedbergf0358562010-05-18 13:20:32 +0200290 case HCIBLOCKADDR:
291 if (!capable(CAP_NET_ADMIN))
292 return -EACCES;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700293 return hci_blacklist_add(hdev, (void __user *) arg);
Johan Hedbergf0358562010-05-18 13:20:32 +0200294
295 case HCIUNBLOCKADDR:
296 if (!capable(CAP_NET_ADMIN))
297 return -EACCES;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700298 return hci_blacklist_del(hdev, (void __user *) arg);
299
300 case HCISETAUTHINFO:
301 return hci_set_auth_info(hdev, (void __user *) arg);
Johan Hedbergf0358562010-05-18 13:20:32 +0200302
Linus Torvalds1da177e2005-04-16 15:20:36 -0700303 default:
304 if (hdev->ioctl)
305 return hdev->ioctl(hdev, cmd, arg);
306 return -EINVAL;
307 }
308}
309
310static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
311{
312 struct sock *sk = sock->sk;
Marcel Holtmann40be4922008-07-14 20:13:50 +0200313 void __user *argp = (void __user *) arg;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700314 int err;
315
316 BT_DBG("cmd %x arg %lx", cmd, arg);
317
318 switch (cmd) {
319 case HCIGETDEVLIST:
320 return hci_get_dev_list(argp);
321
322 case HCIGETDEVINFO:
323 return hci_get_dev_info(argp);
324
325 case HCIGETCONNLIST:
326 return hci_get_conn_list(argp);
327
328 case HCIDEVUP:
329 if (!capable(CAP_NET_ADMIN))
330 return -EACCES;
Brian Gixcfb536b2011-09-02 08:45:22 -0700331
332 err = hci_dev_open(arg);
333 if (!err || err == -EALREADY)
334 return 0;
335 else
336 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700337
338 case HCIDEVDOWN:
339 if (!capable(CAP_NET_ADMIN))
340 return -EACCES;
341 return hci_dev_close(arg);
342
343 case HCIDEVRESET:
344 if (!capable(CAP_NET_ADMIN))
345 return -EACCES;
346 return hci_dev_reset(arg);
347
348 case HCIDEVRESTAT:
349 if (!capable(CAP_NET_ADMIN))
350 return -EACCES;
351 return hci_dev_reset_stat(arg);
352
353 case HCISETSCAN:
354 case HCISETAUTH:
355 case HCISETENCRYPT:
356 case HCISETPTYPE:
357 case HCISETLINKPOL:
358 case HCISETLINKMODE:
359 case HCISETACLMTU:
360 case HCISETSCOMTU:
361 if (!capable(CAP_NET_ADMIN))
362 return -EACCES;
363 return hci_dev_cmd(cmd, argp);
364
365 case HCIINQUIRY:
366 return hci_inquiry(argp);
367
368 default:
369 lock_sock(sk);
370 err = hci_sock_bound_ioctl(sk, cmd, arg);
371 release_sock(sk);
372 return err;
373 }
374}
375
376static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
377{
Johan Hedberg03811012010-12-08 00:21:06 +0200378 struct sockaddr_hci haddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379 struct sock *sk = sock->sk;
380 struct hci_dev *hdev = NULL;
Johan Hedberg03811012010-12-08 00:21:06 +0200381 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700382
383 BT_DBG("sock %p sk %p", sock, sk);
384
Johan Hedberg03811012010-12-08 00:21:06 +0200385 if (!addr)
386 return -EINVAL;
387
388 memset(&haddr, 0, sizeof(haddr));
389 len = min_t(unsigned int, sizeof(haddr), addr_len);
390 memcpy(&haddr, addr, len);
391
392 if (haddr.hci_family != AF_BLUETOOTH)
393 return -EINVAL;
394
Gustavo F. Padovan17f9cc32010-12-22 23:00:34 -0200395 if (haddr.hci_channel > HCI_CHANNEL_CONTROL)
396 return -EINVAL;
397
398 if (haddr.hci_channel == HCI_CHANNEL_CONTROL && !enable_mgmt)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700399 return -EINVAL;
400
401 lock_sock(sk);
402
Johan Hedberg03811012010-12-08 00:21:06 +0200403 if (sk->sk_state == BT_BOUND || hci_pi(sk)->hdev) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700404 err = -EALREADY;
405 goto done;
406 }
407
Johan Hedberg03811012010-12-08 00:21:06 +0200408 if (haddr.hci_dev != HCI_DEV_NONE) {
409 hdev = hci_dev_get(haddr.hci_dev);
Andrei Emeltchenko70f230202010-12-01 16:58:25 +0200410 if (!hdev) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411 err = -ENODEV;
412 goto done;
413 }
414
415 atomic_inc(&hdev->promisc);
416 }
417
Johan Hedberg03811012010-12-08 00:21:06 +0200418 hci_pi(sk)->channel = haddr.hci_channel;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419 hci_pi(sk)->hdev = hdev;
420 sk->sk_state = BT_BOUND;
421
422done:
423 release_sock(sk);
424 return err;
425}
426
427static int hci_sock_getname(struct socket *sock, struct sockaddr *addr, int *addr_len, int peer)
428{
429 struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr;
430 struct sock *sk = sock->sk;
Marcel Holtmann7b005bd2006-02-13 11:40:03 +0100431 struct hci_dev *hdev = hci_pi(sk)->hdev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432
433 BT_DBG("sock %p sk %p", sock, sk);
434
Marcel Holtmann7b005bd2006-02-13 11:40:03 +0100435 if (!hdev)
436 return -EBADFD;
437
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438 lock_sock(sk);
439
440 *addr_len = sizeof(*haddr);
441 haddr->hci_family = AF_BLUETOOTH;
Marcel Holtmann7b005bd2006-02-13 11:40:03 +0100442 haddr->hci_dev = hdev->id;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700443
444 release_sock(sk);
445 return 0;
446}
447
448static inline void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
449{
450 __u32 mask = hci_pi(sk)->cmsg_mask;
451
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700452 if (mask & HCI_CMSG_DIR) {
453 int incoming = bt_cb(skb)->incoming;
454 put_cmsg(msg, SOL_HCI, HCI_CMSG_DIR, sizeof(incoming), &incoming);
455 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700456
Patrick McHardya61bbcf2005-08-14 17:24:31 -0700457 if (mask & HCI_CMSG_TSTAMP) {
Johann Felix Sodenf6e623a2010-02-15 22:23:48 +0100458#ifdef CONFIG_COMPAT
459 struct compat_timeval ctv;
460#endif
Patrick McHardya61bbcf2005-08-14 17:24:31 -0700461 struct timeval tv;
Marcel Holtmann767c5eb2007-09-09 08:39:34 +0200462 void *data;
463 int len;
Patrick McHardya61bbcf2005-08-14 17:24:31 -0700464
465 skb_get_timestamp(skb, &tv);
Marcel Holtmann767c5eb2007-09-09 08:39:34 +0200466
David S. Miller1da97f82007-09-12 14:10:58 +0200467 data = &tv;
468 len = sizeof(tv);
469#ifdef CONFIG_COMPAT
Marcel Holtmann767c5eb2007-09-09 08:39:34 +0200470 if (msg->msg_flags & MSG_CMSG_COMPAT) {
Marcel Holtmann767c5eb2007-09-09 08:39:34 +0200471 ctv.tv_sec = tv.tv_sec;
472 ctv.tv_usec = tv.tv_usec;
473 data = &ctv;
474 len = sizeof(ctv);
Marcel Holtmann767c5eb2007-09-09 08:39:34 +0200475 }
David S. Miller1da97f82007-09-12 14:10:58 +0200476#endif
Marcel Holtmann767c5eb2007-09-09 08:39:34 +0200477
478 put_cmsg(msg, SOL_HCI, HCI_CMSG_TSTAMP, len, data);
Patrick McHardya61bbcf2005-08-14 17:24:31 -0700479 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700480}
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900481
482static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700483 struct msghdr *msg, size_t len, int flags)
484{
485 int noblock = flags & MSG_DONTWAIT;
486 struct sock *sk = sock->sk;
487 struct sk_buff *skb;
488 int copied, err;
489
490 BT_DBG("sock %p, sk %p", sock, sk);
491
492 if (flags & (MSG_OOB))
493 return -EOPNOTSUPP;
494
495 if (sk->sk_state == BT_CLOSED)
496 return 0;
497
Andrei Emeltchenko70f230202010-12-01 16:58:25 +0200498 skb = skb_recv_datagram(sk, flags, noblock, &err);
499 if (!skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500 return err;
501
502 msg->msg_namelen = 0;
503
504 copied = skb->len;
505 if (len < copied) {
506 msg->msg_flags |= MSG_TRUNC;
507 copied = len;
508 }
509
Arnaldo Carvalho de Melobadff6d2007-03-13 13:06:52 -0300510 skb_reset_transport_header(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700511 err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
512
513 hci_sock_cmsg(sk, msg, skb);
514
515 skb_free_datagram(sk, skb);
516
517 return err ? : copied;
518}
519
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900520static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700521 struct msghdr *msg, size_t len)
522{
523 struct sock *sk = sock->sk;
524 struct hci_dev *hdev;
525 struct sk_buff *skb;
Peter Krystadfc60bda2012-01-24 12:42:43 -0800526 int reserve = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700527 int err;
528
529 BT_DBG("sock %p sk %p", sock, sk);
530
531 if (msg->msg_flags & MSG_OOB)
532 return -EOPNOTSUPP;
533
534 if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE))
535 return -EINVAL;
536
537 if (len < 4 || len > HCI_MAX_FRAME_SIZE)
538 return -EINVAL;
539
540 lock_sock(sk);
541
Johan Hedberg03811012010-12-08 00:21:06 +0200542 switch (hci_pi(sk)->channel) {
543 case HCI_CHANNEL_RAW:
544 break;
545 case HCI_CHANNEL_CONTROL:
546 err = mgmt_control(sk, msg, len);
547 goto done;
548 default:
549 err = -EINVAL;
550 goto done;
551 }
552
Andrei Emeltchenko70f230202010-12-01 16:58:25 +0200553 hdev = hci_pi(sk)->hdev;
554 if (!hdev) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700555 err = -EBADFD;
556 goto done;
557 }
558
Marcel Holtmann7e21add2009-11-18 01:05:00 +0100559 if (!test_bit(HCI_UP, &hdev->flags)) {
560 err = -ENETDOWN;
561 goto done;
562 }
563
Peter Krystadfc60bda2012-01-24 12:42:43 -0800564 /* Allocate extra headroom for Qualcomm PAL */
565 if (hdev->dev_type == HCI_AMP && hdev->manufacturer == 0x001d)
566 reserve = BT_SKB_RESERVE_80211;
567
568 skb = bt_skb_send_alloc(sk, len + reserve,
569 msg->msg_flags & MSG_DONTWAIT, &err);
Andrei Emeltchenko70f230202010-12-01 16:58:25 +0200570 if (!skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700571 goto done;
572
Peter Krystadfc60bda2012-01-24 12:42:43 -0800573 if (reserve)
574 skb_reserve(skb, reserve);
575
Linus Torvalds1da177e2005-04-16 15:20:36 -0700576 if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
577 err = -EFAULT;
578 goto drop;
579 }
580
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700581 bt_cb(skb)->pkt_type = *((unsigned char *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700582 skb_pull(skb, 1);
583 skb->dev = (void *) hdev;
584
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700585 if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) {
Harvey Harrison83985312008-05-02 16:25:46 -0700586 u16 opcode = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700587 u16 ogf = hci_opcode_ogf(opcode);
588 u16 ocf = hci_opcode_ocf(opcode);
589
590 if (((ogf > HCI_SFLT_MAX_OGF) ||
591 !hci_test_bit(ocf & HCI_FLT_OCF_BITS, &hci_sec_filter.ocf_mask[ogf])) &&
592 !capable(CAP_NET_RAW)) {
593 err = -EPERM;
594 goto drop;
595 }
596
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200597 if (test_bit(HCI_RAW, &hdev->flags) || (ogf == 0x3f)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598 skb_queue_tail(&hdev->raw_q, skb);
Marcel Holtmannc78ae282009-11-18 01:02:54 +0100599 tasklet_schedule(&hdev->tx_task);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600 } else {
601 skb_queue_tail(&hdev->cmd_q, skb);
Marcel Holtmannc78ae282009-11-18 01:02:54 +0100602 tasklet_schedule(&hdev->cmd_task);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700603 }
604 } else {
605 if (!capable(CAP_NET_RAW)) {
606 err = -EPERM;
607 goto drop;
608 }
609
610 skb_queue_tail(&hdev->raw_q, skb);
Marcel Holtmannc78ae282009-11-18 01:02:54 +0100611 tasklet_schedule(&hdev->tx_task);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700612 }
613
614 err = len;
615
616done:
617 release_sock(sk);
618 return err;
619
620drop:
621 kfree_skb(skb);
622 goto done;
623}
624
David S. Millerb7058842009-09-30 16:12:20 -0700625static int hci_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int len)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700626{
627 struct hci_ufilter uf = { .opcode = 0 };
628 struct sock *sk = sock->sk;
629 int err = 0, opt = 0;
630
631 BT_DBG("sk %p, opt %d", sk, optname);
632
633 lock_sock(sk);
634
635 switch (optname) {
636 case HCI_DATA_DIR:
637 if (get_user(opt, (int __user *)optval)) {
638 err = -EFAULT;
639 break;
640 }
641
642 if (opt)
643 hci_pi(sk)->cmsg_mask |= HCI_CMSG_DIR;
644 else
645 hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_DIR;
646 break;
647
648 case HCI_TIME_STAMP:
649 if (get_user(opt, (int __user *)optval)) {
650 err = -EFAULT;
651 break;
652 }
653
654 if (opt)
655 hci_pi(sk)->cmsg_mask |= HCI_CMSG_TSTAMP;
656 else
657 hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_TSTAMP;
658 break;
659
660 case HCI_FILTER:
Marcel Holtmann0878b662007-05-05 00:35:59 +0200661 {
662 struct hci_filter *f = &hci_pi(sk)->filter;
663
664 uf.type_mask = f->type_mask;
665 uf.opcode = f->opcode;
666 uf.event_mask[0] = *((u32 *) f->event_mask + 0);
667 uf.event_mask[1] = *((u32 *) f->event_mask + 1);
668 }
669
Linus Torvalds1da177e2005-04-16 15:20:36 -0700670 len = min_t(unsigned int, len, sizeof(uf));
671 if (copy_from_user(&uf, optval, len)) {
672 err = -EFAULT;
673 break;
674 }
675
676 if (!capable(CAP_NET_RAW)) {
677 uf.type_mask &= hci_sec_filter.type_mask;
678 uf.event_mask[0] &= *((u32 *) hci_sec_filter.event_mask + 0);
679 uf.event_mask[1] &= *((u32 *) hci_sec_filter.event_mask + 1);
680 }
681
682 {
683 struct hci_filter *f = &hci_pi(sk)->filter;
684
685 f->type_mask = uf.type_mask;
686 f->opcode = uf.opcode;
687 *((u32 *) f->event_mask + 0) = uf.event_mask[0];
688 *((u32 *) f->event_mask + 1) = uf.event_mask[1];
689 }
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900690 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700691
692 default:
693 err = -ENOPROTOOPT;
694 break;
695 }
696
697 release_sock(sk);
698 return err;
699}
700
701static int hci_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
702{
703 struct hci_ufilter uf;
704 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900705 int len, opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700706
707 if (get_user(len, optlen))
708 return -EFAULT;
709
710 switch (optname) {
711 case HCI_DATA_DIR:
712 if (hci_pi(sk)->cmsg_mask & HCI_CMSG_DIR)
713 opt = 1;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900714 else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700715 opt = 0;
716
717 if (put_user(opt, optval))
718 return -EFAULT;
719 break;
720
721 case HCI_TIME_STAMP:
722 if (hci_pi(sk)->cmsg_mask & HCI_CMSG_TSTAMP)
723 opt = 1;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900724 else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700725 opt = 0;
726
727 if (put_user(opt, optval))
728 return -EFAULT;
729 break;
730
731 case HCI_FILTER:
732 {
733 struct hci_filter *f = &hci_pi(sk)->filter;
734
735 uf.type_mask = f->type_mask;
736 uf.opcode = f->opcode;
737 uf.event_mask[0] = *((u32 *) f->event_mask + 0);
738 uf.event_mask[1] = *((u32 *) f->event_mask + 1);
739 }
740
741 len = min_t(unsigned int, len, sizeof(uf));
742 if (copy_to_user(optval, &uf, len))
743 return -EFAULT;
744 break;
745
746 default:
747 return -ENOPROTOOPT;
748 break;
749 }
750
751 return 0;
752}
753
Eric Dumazet90ddc4f2005-12-22 12:49:22 -0800754static const struct proto_ops hci_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700755 .family = PF_BLUETOOTH,
756 .owner = THIS_MODULE,
757 .release = hci_sock_release,
758 .bind = hci_sock_bind,
759 .getname = hci_sock_getname,
760 .sendmsg = hci_sock_sendmsg,
761 .recvmsg = hci_sock_recvmsg,
762 .ioctl = hci_sock_ioctl,
763 .poll = datagram_poll,
764 .listen = sock_no_listen,
765 .shutdown = sock_no_shutdown,
766 .setsockopt = hci_sock_setsockopt,
767 .getsockopt = hci_sock_getsockopt,
768 .connect = sock_no_connect,
769 .socketpair = sock_no_socketpair,
770 .accept = sock_no_accept,
771 .mmap = sock_no_mmap
772};
773
774static struct proto hci_sk_proto = {
775 .name = "HCI",
776 .owner = THIS_MODULE,
777 .obj_size = sizeof(struct hci_pinfo)
778};
779
Eric Paris3f378b62009-11-05 22:18:14 -0800780static int hci_sock_create(struct net *net, struct socket *sock, int protocol,
781 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700782{
783 struct sock *sk;
784
785 BT_DBG("sock %p", sock);
786
787 if (sock->type != SOCK_RAW)
788 return -ESOCKTNOSUPPORT;
789
790 sock->ops = &hci_sock_ops;
791
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700792 sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &hci_sk_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700793 if (!sk)
794 return -ENOMEM;
795
796 sock_init_data(sock, sk);
797
798 sock_reset_flag(sk, SOCK_ZAPPED);
799
800 sk->sk_protocol = protocol;
801
802 sock->state = SS_UNCONNECTED;
803 sk->sk_state = BT_OPEN;
804
805 bt_sock_link(&hci_sk_list, sk);
806 return 0;
807}
808
809static int hci_sock_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
810{
811 struct hci_dev *hdev = (struct hci_dev *) ptr;
812 struct hci_ev_si_device ev;
813
814 BT_DBG("hdev %s event %ld", hdev->name, event);
815
816 /* Send event to sockets */
817 ev.event = event;
818 ev.dev_id = hdev->id;
819 hci_si_event(NULL, HCI_EV_SI_DEVICE, sizeof(ev), &ev);
820
821 if (event == HCI_DEV_UNREG) {
822 struct sock *sk;
823 struct hlist_node *node;
824
825 /* Detach sockets from device */
826 read_lock(&hci_sk_list.lock);
827 sk_for_each(sk, node, &hci_sk_list.head) {
Satyam Sharma4ce61d12007-05-16 23:50:16 -0700828 local_bh_disable();
829 bh_lock_sock_nested(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700830 if (hci_pi(sk)->hdev == hdev) {
831 hci_pi(sk)->hdev = NULL;
832 sk->sk_err = EPIPE;
833 sk->sk_state = BT_OPEN;
834 sk->sk_state_change(sk);
835
836 hci_dev_put(hdev);
837 }
Satyam Sharma4ce61d12007-05-16 23:50:16 -0700838 bh_unlock_sock(sk);
839 local_bh_enable();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700840 }
841 read_unlock(&hci_sk_list.lock);
842 }
843
844 return NOTIFY_DONE;
845}
846
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +0000847static const struct net_proto_family hci_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700848 .family = PF_BLUETOOTH,
849 .owner = THIS_MODULE,
850 .create = hci_sock_create,
851};
852
853static struct notifier_block hci_sock_nblock = {
854 .notifier_call = hci_sock_dev_event
855};
856
857int __init hci_sock_init(void)
858{
859 int err;
860
861 err = proto_register(&hci_sk_proto, 0);
862 if (err < 0)
863 return err;
864
865 err = bt_sock_register(BTPROTO_HCI, &hci_sock_family_ops);
866 if (err < 0)
867 goto error;
868
869 hci_register_notifier(&hci_sock_nblock);
870
871 BT_INFO("HCI socket layer initialized");
872
873 return 0;
874
875error:
876 BT_ERR("HCI socket registration failed");
877 proto_unregister(&hci_sk_proto);
878 return err;
879}
880
Anand Gadiyarb7440a142011-02-22 12:43:09 +0530881void hci_sock_cleanup(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700882{
883 if (bt_sock_unregister(BTPROTO_HCI) < 0)
884 BT_ERR("HCI socket unregistration failed");
885
886 hci_unregister_notifier(&hci_sock_nblock);
887
888 proto_unregister(&hci_sk_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700889}
Johan Hedberg03811012010-12-08 00:21:06 +0200890
891module_param(enable_mgmt, bool, 0644);
892MODULE_PARM_DESC(enable_mgmt, "Enable Management interface");