blob: 95ccb21c8f6a9b2478eba4e5d9dd95dd37c6ceb2 [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 Truonge833aca2013-02-12 13:35:08 -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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700502 copied = skb->len;
503 if (len < copied) {
504 msg->msg_flags |= MSG_TRUNC;
505 copied = len;
506 }
507
Arnaldo Carvalho de Melobadff6d2007-03-13 13:06:52 -0300508 skb_reset_transport_header(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509 err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
510
511 hci_sock_cmsg(sk, msg, skb);
512
513 skb_free_datagram(sk, skb);
514
515 return err ? : copied;
516}
517
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900518static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700519 struct msghdr *msg, size_t len)
520{
521 struct sock *sk = sock->sk;
522 struct hci_dev *hdev;
523 struct sk_buff *skb;
Peter Krystadfc60bda2012-01-24 12:42:43 -0800524 int reserve = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700525 int err;
526
527 BT_DBG("sock %p sk %p", sock, sk);
528
529 if (msg->msg_flags & MSG_OOB)
530 return -EOPNOTSUPP;
531
532 if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE))
533 return -EINVAL;
534
535 if (len < 4 || len > HCI_MAX_FRAME_SIZE)
536 return -EINVAL;
537
538 lock_sock(sk);
539
Johan Hedberg03811012010-12-08 00:21:06 +0200540 switch (hci_pi(sk)->channel) {
541 case HCI_CHANNEL_RAW:
542 break;
543 case HCI_CHANNEL_CONTROL:
544 err = mgmt_control(sk, msg, len);
545 goto done;
546 default:
547 err = -EINVAL;
548 goto done;
549 }
550
Andrei Emeltchenko70f230202010-12-01 16:58:25 +0200551 hdev = hci_pi(sk)->hdev;
552 if (!hdev) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700553 err = -EBADFD;
554 goto done;
555 }
556
Marcel Holtmann7e21add2009-11-18 01:05:00 +0100557 if (!test_bit(HCI_UP, &hdev->flags)) {
558 err = -ENETDOWN;
559 goto done;
560 }
561
Peter Krystadfc60bda2012-01-24 12:42:43 -0800562 /* Allocate extra headroom for Qualcomm PAL */
563 if (hdev->dev_type == HCI_AMP && hdev->manufacturer == 0x001d)
564 reserve = BT_SKB_RESERVE_80211;
565
566 skb = bt_skb_send_alloc(sk, len + reserve,
567 msg->msg_flags & MSG_DONTWAIT, &err);
Andrei Emeltchenko70f230202010-12-01 16:58:25 +0200568 if (!skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569 goto done;
570
Peter Krystadfc60bda2012-01-24 12:42:43 -0800571 if (reserve)
572 skb_reserve(skb, reserve);
573
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574 if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
575 err = -EFAULT;
576 goto drop;
577 }
578
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700579 bt_cb(skb)->pkt_type = *((unsigned char *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700580 skb_pull(skb, 1);
581 skb->dev = (void *) hdev;
582
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700583 if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) {
Harvey Harrison83985312008-05-02 16:25:46 -0700584 u16 opcode = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585 u16 ogf = hci_opcode_ogf(opcode);
586 u16 ocf = hci_opcode_ocf(opcode);
587
588 if (((ogf > HCI_SFLT_MAX_OGF) ||
589 !hci_test_bit(ocf & HCI_FLT_OCF_BITS, &hci_sec_filter.ocf_mask[ogf])) &&
590 !capable(CAP_NET_RAW)) {
591 err = -EPERM;
592 goto drop;
593 }
594
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200595 if (test_bit(HCI_RAW, &hdev->flags) || (ogf == 0x3f)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700596 skb_queue_tail(&hdev->raw_q, skb);
Marcel Holtmannc78ae282009-11-18 01:02:54 +0100597 tasklet_schedule(&hdev->tx_task);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598 } else {
599 skb_queue_tail(&hdev->cmd_q, skb);
Marcel Holtmannc78ae282009-11-18 01:02:54 +0100600 tasklet_schedule(&hdev->cmd_task);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700601 }
602 } else {
603 if (!capable(CAP_NET_RAW)) {
604 err = -EPERM;
605 goto drop;
606 }
607
608 skb_queue_tail(&hdev->raw_q, skb);
Marcel Holtmannc78ae282009-11-18 01:02:54 +0100609 tasklet_schedule(&hdev->tx_task);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610 }
611
612 err = len;
613
614done:
615 release_sock(sk);
616 return err;
617
618drop:
619 kfree_skb(skb);
620 goto done;
621}
622
David S. Millerb7058842009-09-30 16:12:20 -0700623static int hci_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int len)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624{
625 struct hci_ufilter uf = { .opcode = 0 };
626 struct sock *sk = sock->sk;
627 int err = 0, opt = 0;
628
629 BT_DBG("sk %p, opt %d", sk, optname);
630
631 lock_sock(sk);
632
633 switch (optname) {
634 case HCI_DATA_DIR:
635 if (get_user(opt, (int __user *)optval)) {
636 err = -EFAULT;
637 break;
638 }
639
640 if (opt)
641 hci_pi(sk)->cmsg_mask |= HCI_CMSG_DIR;
642 else
643 hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_DIR;
644 break;
645
646 case HCI_TIME_STAMP:
647 if (get_user(opt, (int __user *)optval)) {
648 err = -EFAULT;
649 break;
650 }
651
652 if (opt)
653 hci_pi(sk)->cmsg_mask |= HCI_CMSG_TSTAMP;
654 else
655 hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_TSTAMP;
656 break;
657
658 case HCI_FILTER:
Marcel Holtmann0878b662007-05-05 00:35:59 +0200659 {
660 struct hci_filter *f = &hci_pi(sk)->filter;
661
662 uf.type_mask = f->type_mask;
663 uf.opcode = f->opcode;
664 uf.event_mask[0] = *((u32 *) f->event_mask + 0);
665 uf.event_mask[1] = *((u32 *) f->event_mask + 1);
666 }
667
Linus Torvalds1da177e2005-04-16 15:20:36 -0700668 len = min_t(unsigned int, len, sizeof(uf));
669 if (copy_from_user(&uf, optval, len)) {
670 err = -EFAULT;
671 break;
672 }
673
674 if (!capable(CAP_NET_RAW)) {
675 uf.type_mask &= hci_sec_filter.type_mask;
676 uf.event_mask[0] &= *((u32 *) hci_sec_filter.event_mask + 0);
677 uf.event_mask[1] &= *((u32 *) hci_sec_filter.event_mask + 1);
678 }
679
680 {
681 struct hci_filter *f = &hci_pi(sk)->filter;
682
683 f->type_mask = uf.type_mask;
684 f->opcode = uf.opcode;
685 *((u32 *) f->event_mask + 0) = uf.event_mask[0];
686 *((u32 *) f->event_mask + 1) = uf.event_mask[1];
687 }
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900688 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700689
690 default:
691 err = -ENOPROTOOPT;
692 break;
693 }
694
695 release_sock(sk);
696 return err;
697}
698
699static int hci_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
700{
701 struct hci_ufilter uf;
702 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900703 int len, opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700704
705 if (get_user(len, optlen))
706 return -EFAULT;
707
708 switch (optname) {
709 case HCI_DATA_DIR:
710 if (hci_pi(sk)->cmsg_mask & HCI_CMSG_DIR)
711 opt = 1;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900712 else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700713 opt = 0;
714
715 if (put_user(opt, optval))
716 return -EFAULT;
717 break;
718
719 case HCI_TIME_STAMP:
720 if (hci_pi(sk)->cmsg_mask & HCI_CMSG_TSTAMP)
721 opt = 1;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900722 else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700723 opt = 0;
724
725 if (put_user(opt, optval))
726 return -EFAULT;
727 break;
728
729 case HCI_FILTER:
730 {
731 struct hci_filter *f = &hci_pi(sk)->filter;
732
733 uf.type_mask = f->type_mask;
734 uf.opcode = f->opcode;
735 uf.event_mask[0] = *((u32 *) f->event_mask + 0);
736 uf.event_mask[1] = *((u32 *) f->event_mask + 1);
737 }
738
739 len = min_t(unsigned int, len, sizeof(uf));
740 if (copy_to_user(optval, &uf, len))
741 return -EFAULT;
742 break;
743
744 default:
745 return -ENOPROTOOPT;
746 break;
747 }
748
749 return 0;
750}
751
Eric Dumazet90ddc4f2005-12-22 12:49:22 -0800752static const struct proto_ops hci_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700753 .family = PF_BLUETOOTH,
754 .owner = THIS_MODULE,
755 .release = hci_sock_release,
756 .bind = hci_sock_bind,
757 .getname = hci_sock_getname,
758 .sendmsg = hci_sock_sendmsg,
759 .recvmsg = hci_sock_recvmsg,
760 .ioctl = hci_sock_ioctl,
761 .poll = datagram_poll,
762 .listen = sock_no_listen,
763 .shutdown = sock_no_shutdown,
764 .setsockopt = hci_sock_setsockopt,
765 .getsockopt = hci_sock_getsockopt,
766 .connect = sock_no_connect,
767 .socketpair = sock_no_socketpair,
768 .accept = sock_no_accept,
769 .mmap = sock_no_mmap
770};
771
772static struct proto hci_sk_proto = {
773 .name = "HCI",
774 .owner = THIS_MODULE,
775 .obj_size = sizeof(struct hci_pinfo)
776};
777
Eric Paris3f378b62009-11-05 22:18:14 -0800778static int hci_sock_create(struct net *net, struct socket *sock, int protocol,
779 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700780{
781 struct sock *sk;
782
783 BT_DBG("sock %p", sock);
784
785 if (sock->type != SOCK_RAW)
786 return -ESOCKTNOSUPPORT;
787
788 sock->ops = &hci_sock_ops;
789
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700790 sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &hci_sk_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700791 if (!sk)
792 return -ENOMEM;
793
794 sock_init_data(sock, sk);
795
796 sock_reset_flag(sk, SOCK_ZAPPED);
797
798 sk->sk_protocol = protocol;
799
800 sock->state = SS_UNCONNECTED;
801 sk->sk_state = BT_OPEN;
802
803 bt_sock_link(&hci_sk_list, sk);
804 return 0;
805}
806
807static int hci_sock_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
808{
809 struct hci_dev *hdev = (struct hci_dev *) ptr;
810 struct hci_ev_si_device ev;
811
812 BT_DBG("hdev %s event %ld", hdev->name, event);
813
814 /* Send event to sockets */
815 ev.event = event;
816 ev.dev_id = hdev->id;
817 hci_si_event(NULL, HCI_EV_SI_DEVICE, sizeof(ev), &ev);
818
819 if (event == HCI_DEV_UNREG) {
820 struct sock *sk;
821 struct hlist_node *node;
822
823 /* Detach sockets from device */
824 read_lock(&hci_sk_list.lock);
825 sk_for_each(sk, node, &hci_sk_list.head) {
Satyam Sharma4ce61d12007-05-16 23:50:16 -0700826 local_bh_disable();
827 bh_lock_sock_nested(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700828 if (hci_pi(sk)->hdev == hdev) {
829 hci_pi(sk)->hdev = NULL;
830 sk->sk_err = EPIPE;
831 sk->sk_state = BT_OPEN;
832 sk->sk_state_change(sk);
833
834 hci_dev_put(hdev);
835 }
Satyam Sharma4ce61d12007-05-16 23:50:16 -0700836 bh_unlock_sock(sk);
837 local_bh_enable();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700838 }
839 read_unlock(&hci_sk_list.lock);
840 }
841
842 return NOTIFY_DONE;
843}
844
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +0000845static const struct net_proto_family hci_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700846 .family = PF_BLUETOOTH,
847 .owner = THIS_MODULE,
848 .create = hci_sock_create,
849};
850
851static struct notifier_block hci_sock_nblock = {
852 .notifier_call = hci_sock_dev_event
853};
854
855int __init hci_sock_init(void)
856{
857 int err;
858
859 err = proto_register(&hci_sk_proto, 0);
860 if (err < 0)
861 return err;
862
863 err = bt_sock_register(BTPROTO_HCI, &hci_sock_family_ops);
864 if (err < 0)
865 goto error;
866
867 hci_register_notifier(&hci_sock_nblock);
868
869 BT_INFO("HCI socket layer initialized");
870
871 return 0;
872
873error:
874 BT_ERR("HCI socket registration failed");
875 proto_unregister(&hci_sk_proto);
876 return err;
877}
878
Anand Gadiyarb7440a142011-02-22 12:43:09 +0530879void hci_sock_cleanup(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700880{
881 if (bt_sock_unregister(BTPROTO_HCI) < 0)
882 BT_ERR("HCI socket unregistration failed");
883
884 hci_unregister_notifier(&hci_sock_nblock);
885
886 proto_unregister(&hci_sk_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700887}
Johan Hedberg03811012010-12-08 00:21:06 +0200888
889module_param(enable_mgmt, bool, 0644);
890MODULE_PARM_DESC(enable_mgmt, "Enable Management interface");