blob: cf940bd7a2b0533fd32a1da89e95ee0a8729e938 [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;
Marcel Holtmanne0edf372012-02-20 14:50:36 +010092 struct sk_buff *skb_copy = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -070093
94 BT_DBG("hdev %p len %d", hdev, skb->len);
95
96 read_lock(&hci_sk_list.lock);
Marcel Holtmann470fe1b2012-02-20 14:50:30 +010097
Linus Torvalds1da177e2005-04-16 15:20:36 -070098 sk_for_each(sk, node, &hci_sk_list.head) {
99 struct hci_filter *flt;
100 struct sk_buff *nskb;
101
102 if (sk->sk_state != BT_BOUND || hci_pi(sk)->hdev != hdev)
103 continue;
104
105 /* Don't send frame to the socket it came from */
106 if (skb->sk == sk)
107 continue;
108
Marcel Holtmann470fe1b2012-02-20 14:50:30 +0100109 if (hci_pi(sk)->channel != HCI_CHANNEL_RAW)
Johan Hedberga40c4062010-12-08 00:21:07 +0200110 continue;
111
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112 /* Apply filter */
113 flt = &hci_pi(sk)->filter;
114
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700115 if (!test_bit((bt_cb(skb)->pkt_type == HCI_VENDOR_PKT) ?
116 0 : (bt_cb(skb)->pkt_type & HCI_FLT_TYPE_BITS), &flt->type_mask))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700117 continue;
118
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700119 if (bt_cb(skb)->pkt_type == HCI_EVENT_PKT) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120 register int evt = (*(__u8 *)skb->data & HCI_FLT_EVENT_BITS);
121
122 if (!hci_test_bit(evt, &flt->event_mask))
123 continue;
124
David S. Miller4498c802006-11-21 16:17:41 -0800125 if (flt->opcode &&
126 ((evt == HCI_EV_CMD_COMPLETE &&
127 flt->opcode !=
Al Viro905f3ed2006-12-13 00:35:01 -0800128 get_unaligned((__le16 *)(skb->data + 3))) ||
David S. Miller4498c802006-11-21 16:17:41 -0800129 (evt == HCI_EV_CMD_STATUS &&
130 flt->opcode !=
Al Viro905f3ed2006-12-13 00:35:01 -0800131 get_unaligned((__le16 *)(skb->data + 4)))))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132 continue;
133 }
134
Marcel Holtmanne0edf372012-02-20 14:50:36 +0100135 if (!skb_copy) {
136 /* Create a private copy with headroom */
137 skb_copy = __pskb_copy(skb, 1, GFP_ATOMIC);
138 if (!skb_copy)
139 continue;
140
141 /* Put type byte before the data */
142 memcpy(skb_push(skb_copy, 1), &bt_cb(skb)->pkt_type, 1);
143 }
144
145 nskb = skb_clone(skb_copy, GFP_ATOMIC);
Andrei Emeltchenko70f230202010-12-01 16:58:25 +0200146 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700147 continue;
148
Linus Torvalds1da177e2005-04-16 15:20:36 -0700149 if (sock_queue_rcv_skb(sk, nskb))
150 kfree_skb(nskb);
151 }
Marcel Holtmann470fe1b2012-02-20 14:50:30 +0100152
153 read_unlock(&hci_sk_list.lock);
Marcel Holtmanne0edf372012-02-20 14:50:36 +0100154
155 kfree_skb(skb_copy);
Marcel Holtmann470fe1b2012-02-20 14:50:30 +0100156}
157
158/* Send frame to control socket */
159void hci_send_to_control(struct sk_buff *skb, struct sock *skip_sk)
160{
161 struct sock *sk;
162 struct hlist_node *node;
163
164 BT_DBG("len %d", skb->len);
165
166 read_lock(&hci_sk_list.lock);
167
168 sk_for_each(sk, node, &hci_sk_list.head) {
169 struct sk_buff *nskb;
170
171 /* Skip the original socket */
172 if (sk == skip_sk)
173 continue;
174
175 if (sk->sk_state != BT_BOUND)
176 continue;
177
178 if (hci_pi(sk)->channel != HCI_CHANNEL_CONTROL)
179 continue;
180
181 nskb = skb_clone(skb, GFP_ATOMIC);
182 if (!nskb)
183 continue;
184
185 if (sock_queue_rcv_skb(sk, nskb))
186 kfree_skb(nskb);
187 }
188
Linus Torvalds1da177e2005-04-16 15:20:36 -0700189 read_unlock(&hci_sk_list.lock);
190}
191
192static int hci_sock_release(struct socket *sock)
193{
194 struct sock *sk = sock->sk;
Marcel Holtmann7b005bd2006-02-13 11:40:03 +0100195 struct hci_dev *hdev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700196
197 BT_DBG("sock %p sk %p", sock, sk);
198
199 if (!sk)
200 return 0;
201
Marcel Holtmann7b005bd2006-02-13 11:40:03 +0100202 hdev = hci_pi(sk)->hdev;
203
Linus Torvalds1da177e2005-04-16 15:20:36 -0700204 bt_sock_unlink(&hci_sk_list, sk);
205
206 if (hdev) {
207 atomic_dec(&hdev->promisc);
208 hci_dev_put(hdev);
209 }
210
211 sock_orphan(sk);
212
213 skb_queue_purge(&sk->sk_receive_queue);
214 skb_queue_purge(&sk->sk_write_queue);
215
216 sock_put(sk);
217 return 0;
218}
219
Antti Julkub2a66aa2011-06-15 12:01:14 +0300220static int hci_sock_blacklist_add(struct hci_dev *hdev, void __user *arg)
Johan Hedbergf0358562010-05-18 13:20:32 +0200221{
222 bdaddr_t bdaddr;
Antti Julku5e762442011-08-25 16:48:02 +0300223 int err;
Johan Hedbergf0358562010-05-18 13:20:32 +0200224
225 if (copy_from_user(&bdaddr, arg, sizeof(bdaddr)))
226 return -EFAULT;
227
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -0300228 hci_dev_lock(hdev);
Antti Julku5e762442011-08-25 16:48:02 +0300229
Johan Hedberg88c1fe42012-02-09 15:56:11 +0200230 err = hci_blacklist_add(hdev, &bdaddr, 0);
Antti Julku5e762442011-08-25 16:48:02 +0300231
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -0300232 hci_dev_unlock(hdev);
Antti Julku5e762442011-08-25 16:48:02 +0300233
234 return err;
Johan Hedbergf0358562010-05-18 13:20:32 +0200235}
236
Antti Julkub2a66aa2011-06-15 12:01:14 +0300237static int hci_sock_blacklist_del(struct hci_dev *hdev, void __user *arg)
Johan Hedbergf0358562010-05-18 13:20:32 +0200238{
239 bdaddr_t bdaddr;
Antti Julku5e762442011-08-25 16:48:02 +0300240 int err;
Johan Hedbergf0358562010-05-18 13:20:32 +0200241
242 if (copy_from_user(&bdaddr, arg, sizeof(bdaddr)))
243 return -EFAULT;
244
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -0300245 hci_dev_lock(hdev);
Antti Julku5e762442011-08-25 16:48:02 +0300246
Johan Hedberg88c1fe42012-02-09 15:56:11 +0200247 err = hci_blacklist_del(hdev, &bdaddr, 0);
Antti Julku5e762442011-08-25 16:48:02 +0300248
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -0300249 hci_dev_unlock(hdev);
Antti Julku5e762442011-08-25 16:48:02 +0300250
251 return err;
Johan Hedbergf0358562010-05-18 13:20:32 +0200252}
253
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900254/* Ioctls that require bound socket */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700255static inline int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg)
256{
257 struct hci_dev *hdev = hci_pi(sk)->hdev;
258
259 if (!hdev)
260 return -EBADFD;
261
262 switch (cmd) {
263 case HCISETRAW:
264 if (!capable(CAP_NET_ADMIN))
265 return -EACCES;
266
267 if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
268 return -EPERM;
269
270 if (arg)
271 set_bit(HCI_RAW, &hdev->flags);
272 else
273 clear_bit(HCI_RAW, &hdev->flags);
274
275 return 0;
276
Linus Torvalds1da177e2005-04-16 15:20:36 -0700277 case HCIGETCONNINFO:
Marcel Holtmann40be4922008-07-14 20:13:50 +0200278 return hci_get_conn_info(hdev, (void __user *) arg);
279
280 case HCIGETAUTHINFO:
281 return hci_get_auth_info(hdev, (void __user *) arg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282
Johan Hedbergf0358562010-05-18 13:20:32 +0200283 case HCIBLOCKADDR:
284 if (!capable(CAP_NET_ADMIN))
285 return -EACCES;
Antti Julkub2a66aa2011-06-15 12:01:14 +0300286 return hci_sock_blacklist_add(hdev, (void __user *) arg);
Johan Hedbergf0358562010-05-18 13:20:32 +0200287
288 case HCIUNBLOCKADDR:
289 if (!capable(CAP_NET_ADMIN))
290 return -EACCES;
Antti Julkub2a66aa2011-06-15 12:01:14 +0300291 return hci_sock_blacklist_del(hdev, (void __user *) arg);
Johan Hedbergf0358562010-05-18 13:20:32 +0200292
Linus Torvalds1da177e2005-04-16 15:20:36 -0700293 default:
294 if (hdev->ioctl)
295 return hdev->ioctl(hdev, cmd, arg);
296 return -EINVAL;
297 }
298}
299
300static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
301{
302 struct sock *sk = sock->sk;
Marcel Holtmann40be4922008-07-14 20:13:50 +0200303 void __user *argp = (void __user *) arg;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700304 int err;
305
306 BT_DBG("cmd %x arg %lx", cmd, arg);
307
308 switch (cmd) {
309 case HCIGETDEVLIST:
310 return hci_get_dev_list(argp);
311
312 case HCIGETDEVINFO:
313 return hci_get_dev_info(argp);
314
315 case HCIGETCONNLIST:
316 return hci_get_conn_list(argp);
317
318 case HCIDEVUP:
319 if (!capable(CAP_NET_ADMIN))
320 return -EACCES;
321 return hci_dev_open(arg);
322
323 case HCIDEVDOWN:
324 if (!capable(CAP_NET_ADMIN))
325 return -EACCES;
326 return hci_dev_close(arg);
327
328 case HCIDEVRESET:
329 if (!capable(CAP_NET_ADMIN))
330 return -EACCES;
331 return hci_dev_reset(arg);
332
333 case HCIDEVRESTAT:
334 if (!capable(CAP_NET_ADMIN))
335 return -EACCES;
336 return hci_dev_reset_stat(arg);
337
338 case HCISETSCAN:
339 case HCISETAUTH:
340 case HCISETENCRYPT:
341 case HCISETPTYPE:
342 case HCISETLINKPOL:
343 case HCISETLINKMODE:
344 case HCISETACLMTU:
345 case HCISETSCOMTU:
346 if (!capable(CAP_NET_ADMIN))
347 return -EACCES;
348 return hci_dev_cmd(cmd, argp);
349
350 case HCIINQUIRY:
351 return hci_inquiry(argp);
352
353 default:
354 lock_sock(sk);
355 err = hci_sock_bound_ioctl(sk, cmd, arg);
356 release_sock(sk);
357 return err;
358 }
359}
360
361static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
362{
Johan Hedberg03811012010-12-08 00:21:06 +0200363 struct sockaddr_hci haddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700364 struct sock *sk = sock->sk;
365 struct hci_dev *hdev = NULL;
Johan Hedberg03811012010-12-08 00:21:06 +0200366 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700367
368 BT_DBG("sock %p sk %p", sock, sk);
369
Johan Hedberg03811012010-12-08 00:21:06 +0200370 if (!addr)
371 return -EINVAL;
372
373 memset(&haddr, 0, sizeof(haddr));
374 len = min_t(unsigned int, sizeof(haddr), addr_len);
375 memcpy(&haddr, addr, len);
376
377 if (haddr.hci_family != AF_BLUETOOTH)
378 return -EINVAL;
379
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380 lock_sock(sk);
381
Marcel Holtmann7cc2ade2012-02-20 14:50:35 +0100382 if (sk->sk_state == BT_BOUND) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383 err = -EALREADY;
384 goto done;
385 }
386
Marcel Holtmann7cc2ade2012-02-20 14:50:35 +0100387 switch (haddr.hci_channel) {
388 case HCI_CHANNEL_RAW:
389 if (hci_pi(sk)->hdev) {
390 err = -EALREADY;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700391 goto done;
392 }
393
Marcel Holtmann7cc2ade2012-02-20 14:50:35 +0100394 if (haddr.hci_dev != HCI_DEV_NONE) {
395 hdev = hci_dev_get(haddr.hci_dev);
396 if (!hdev) {
397 err = -ENODEV;
398 goto done;
399 }
400
401 atomic_inc(&hdev->promisc);
402 }
403
404 hci_pi(sk)->hdev = hdev;
405 break;
406
407 case HCI_CHANNEL_CONTROL:
408 if (haddr.hci_dev != HCI_DEV_NONE || !enable_mgmt) {
409 err = -EINVAL;
410 goto done;
411 }
412
413 set_bit(HCI_PI_MGMT_INIT, &hci_pi(sk)->flags);
414 break;
415
416 default:
417 err = -EINVAL;
418 goto done;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419 }
420
Marcel Holtmann7cc2ade2012-02-20 14:50:35 +0100421
Johan Hedberg03811012010-12-08 00:21:06 +0200422 hci_pi(sk)->channel = haddr.hci_channel;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423 sk->sk_state = BT_BOUND;
424
425done:
426 release_sock(sk);
427 return err;
428}
429
430static int hci_sock_getname(struct socket *sock, struct sockaddr *addr, int *addr_len, int peer)
431{
432 struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr;
433 struct sock *sk = sock->sk;
Marcel Holtmann7b005bd2006-02-13 11:40:03 +0100434 struct hci_dev *hdev = hci_pi(sk)->hdev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435
436 BT_DBG("sock %p sk %p", sock, sk);
437
Marcel Holtmann7b005bd2006-02-13 11:40:03 +0100438 if (!hdev)
439 return -EBADFD;
440
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441 lock_sock(sk);
442
443 *addr_len = sizeof(*haddr);
444 haddr->hci_family = AF_BLUETOOTH;
Marcel Holtmann7b005bd2006-02-13 11:40:03 +0100445 haddr->hci_dev = hdev->id;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446
447 release_sock(sk);
448 return 0;
449}
450
451static inline void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
452{
453 __u32 mask = hci_pi(sk)->cmsg_mask;
454
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700455 if (mask & HCI_CMSG_DIR) {
456 int incoming = bt_cb(skb)->incoming;
457 put_cmsg(msg, SOL_HCI, HCI_CMSG_DIR, sizeof(incoming), &incoming);
458 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700459
Patrick McHardya61bbcf2005-08-14 17:24:31 -0700460 if (mask & HCI_CMSG_TSTAMP) {
Johann Felix Sodenf6e623a2010-02-15 22:23:48 +0100461#ifdef CONFIG_COMPAT
462 struct compat_timeval ctv;
463#endif
Patrick McHardya61bbcf2005-08-14 17:24:31 -0700464 struct timeval tv;
Marcel Holtmann767c5eb2007-09-09 08:39:34 +0200465 void *data;
466 int len;
Patrick McHardya61bbcf2005-08-14 17:24:31 -0700467
468 skb_get_timestamp(skb, &tv);
Marcel Holtmann767c5eb2007-09-09 08:39:34 +0200469
David S. Miller1da97f82007-09-12 14:10:58 +0200470 data = &tv;
471 len = sizeof(tv);
472#ifdef CONFIG_COMPAT
Marcel Holtmann767c5eb2007-09-09 08:39:34 +0200473 if (msg->msg_flags & MSG_CMSG_COMPAT) {
Marcel Holtmann767c5eb2007-09-09 08:39:34 +0200474 ctv.tv_sec = tv.tv_sec;
475 ctv.tv_usec = tv.tv_usec;
476 data = &ctv;
477 len = sizeof(ctv);
Marcel Holtmann767c5eb2007-09-09 08:39:34 +0200478 }
David S. Miller1da97f82007-09-12 14:10:58 +0200479#endif
Marcel Holtmann767c5eb2007-09-09 08:39:34 +0200480
481 put_cmsg(msg, SOL_HCI, HCI_CMSG_TSTAMP, len, data);
Patrick McHardya61bbcf2005-08-14 17:24:31 -0700482 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700483}
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900484
485static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700486 struct msghdr *msg, size_t len, int flags)
487{
488 int noblock = flags & MSG_DONTWAIT;
489 struct sock *sk = sock->sk;
490 struct sk_buff *skb;
491 int copied, err;
492
493 BT_DBG("sock %p, sk %p", sock, sk);
494
495 if (flags & (MSG_OOB))
496 return -EOPNOTSUPP;
497
498 if (sk->sk_state == BT_CLOSED)
499 return 0;
500
Andrei Emeltchenko70f230202010-12-01 16:58:25 +0200501 skb = skb_recv_datagram(sk, flags, noblock, &err);
502 if (!skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700503 return err;
504
505 msg->msg_namelen = 0;
506
507 copied = skb->len;
508 if (len < copied) {
509 msg->msg_flags |= MSG_TRUNC;
510 copied = len;
511 }
512
Arnaldo Carvalho de Melobadff6d2007-03-13 13:06:52 -0300513 skb_reset_transport_header(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700514 err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
515
Marcel Holtmann3a208622012-02-20 14:50:34 +0100516 switch (hci_pi(sk)->channel) {
517 case HCI_CHANNEL_RAW:
518 hci_sock_cmsg(sk, msg, skb);
519 break;
520 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700521
522 skb_free_datagram(sk, skb);
523
524 return err ? : copied;
525}
526
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900527static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700528 struct msghdr *msg, size_t len)
529{
530 struct sock *sk = sock->sk;
531 struct hci_dev *hdev;
532 struct sk_buff *skb;
533 int err;
534
535 BT_DBG("sock %p sk %p", sock, sk);
536
537 if (msg->msg_flags & MSG_OOB)
538 return -EOPNOTSUPP;
539
540 if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE))
541 return -EINVAL;
542
543 if (len < 4 || len > HCI_MAX_FRAME_SIZE)
544 return -EINVAL;
545
546 lock_sock(sk);
547
Johan Hedberg03811012010-12-08 00:21:06 +0200548 switch (hci_pi(sk)->channel) {
549 case HCI_CHANNEL_RAW:
550 break;
551 case HCI_CHANNEL_CONTROL:
552 err = mgmt_control(sk, msg, len);
553 goto done;
554 default:
555 err = -EINVAL;
556 goto done;
557 }
558
Andrei Emeltchenko70f230202010-12-01 16:58:25 +0200559 hdev = hci_pi(sk)->hdev;
560 if (!hdev) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700561 err = -EBADFD;
562 goto done;
563 }
564
Marcel Holtmann7e21add2009-11-18 01:05:00 +0100565 if (!test_bit(HCI_UP, &hdev->flags)) {
566 err = -ENETDOWN;
567 goto done;
568 }
569
Andrei Emeltchenko70f230202010-12-01 16:58:25 +0200570 skb = bt_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err);
571 if (!skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700572 goto done;
573
574 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);
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -0200597 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598 } else {
599 skb_queue_tail(&hdev->cmd_q, skb);
Gustavo F. Padovanc347b762011-12-14 23:53:47 -0200600 queue_work(hdev->workqueue, &hdev->cmd_work);
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);
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -0200609 queue_work(hdev->workqueue, &hdev->tx_work);
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
Marcel Holtmann2f39cdb2012-02-20 14:50:32 +0100633 if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) {
634 err = -EINVAL;
635 goto done;
636 }
637
Linus Torvalds1da177e2005-04-16 15:20:36 -0700638 switch (optname) {
639 case HCI_DATA_DIR:
640 if (get_user(opt, (int __user *)optval)) {
641 err = -EFAULT;
642 break;
643 }
644
645 if (opt)
646 hci_pi(sk)->cmsg_mask |= HCI_CMSG_DIR;
647 else
648 hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_DIR;
649 break;
650
651 case HCI_TIME_STAMP:
652 if (get_user(opt, (int __user *)optval)) {
653 err = -EFAULT;
654 break;
655 }
656
657 if (opt)
658 hci_pi(sk)->cmsg_mask |= HCI_CMSG_TSTAMP;
659 else
660 hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_TSTAMP;
661 break;
662
663 case HCI_FILTER:
Marcel Holtmann0878b662007-05-05 00:35:59 +0200664 {
665 struct hci_filter *f = &hci_pi(sk)->filter;
666
667 uf.type_mask = f->type_mask;
668 uf.opcode = f->opcode;
669 uf.event_mask[0] = *((u32 *) f->event_mask + 0);
670 uf.event_mask[1] = *((u32 *) f->event_mask + 1);
671 }
672
Linus Torvalds1da177e2005-04-16 15:20:36 -0700673 len = min_t(unsigned int, len, sizeof(uf));
674 if (copy_from_user(&uf, optval, len)) {
675 err = -EFAULT;
676 break;
677 }
678
679 if (!capable(CAP_NET_RAW)) {
680 uf.type_mask &= hci_sec_filter.type_mask;
681 uf.event_mask[0] &= *((u32 *) hci_sec_filter.event_mask + 0);
682 uf.event_mask[1] &= *((u32 *) hci_sec_filter.event_mask + 1);
683 }
684
685 {
686 struct hci_filter *f = &hci_pi(sk)->filter;
687
688 f->type_mask = uf.type_mask;
689 f->opcode = uf.opcode;
690 *((u32 *) f->event_mask + 0) = uf.event_mask[0];
691 *((u32 *) f->event_mask + 1) = uf.event_mask[1];
692 }
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900693 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700694
695 default:
696 err = -ENOPROTOOPT;
697 break;
698 }
699
Marcel Holtmann2f39cdb2012-02-20 14:50:32 +0100700done:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700701 release_sock(sk);
702 return err;
703}
704
705static int hci_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
706{
707 struct hci_ufilter uf;
708 struct sock *sk = sock->sk;
Marcel Holtmanncedc5462012-02-20 14:50:33 +0100709 int len, opt, err = 0;
710
711 BT_DBG("sk %p, opt %d", sk, optname);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700712
713 if (get_user(len, optlen))
714 return -EFAULT;
715
Marcel Holtmanncedc5462012-02-20 14:50:33 +0100716 lock_sock(sk);
717
718 if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) {
719 err = -EINVAL;
720 goto done;
721 }
722
Linus Torvalds1da177e2005-04-16 15:20:36 -0700723 switch (optname) {
724 case HCI_DATA_DIR:
725 if (hci_pi(sk)->cmsg_mask & HCI_CMSG_DIR)
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_TIME_STAMP:
735 if (hci_pi(sk)->cmsg_mask & HCI_CMSG_TSTAMP)
736 opt = 1;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900737 else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700738 opt = 0;
739
740 if (put_user(opt, optval))
Marcel Holtmanncedc5462012-02-20 14:50:33 +0100741 err = -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700742 break;
743
744 case HCI_FILTER:
745 {
746 struct hci_filter *f = &hci_pi(sk)->filter;
747
748 uf.type_mask = f->type_mask;
749 uf.opcode = f->opcode;
750 uf.event_mask[0] = *((u32 *) f->event_mask + 0);
751 uf.event_mask[1] = *((u32 *) f->event_mask + 1);
752 }
753
754 len = min_t(unsigned int, len, sizeof(uf));
755 if (copy_to_user(optval, &uf, len))
Marcel Holtmanncedc5462012-02-20 14:50:33 +0100756 err = -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700757 break;
758
759 default:
Marcel Holtmanncedc5462012-02-20 14:50:33 +0100760 err = -ENOPROTOOPT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700761 break;
762 }
763
Marcel Holtmanncedc5462012-02-20 14:50:33 +0100764done:
765 release_sock(sk);
766 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700767}
768
Eric Dumazet90ddc4f2005-12-22 12:49:22 -0800769static const struct proto_ops hci_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700770 .family = PF_BLUETOOTH,
771 .owner = THIS_MODULE,
772 .release = hci_sock_release,
773 .bind = hci_sock_bind,
774 .getname = hci_sock_getname,
775 .sendmsg = hci_sock_sendmsg,
776 .recvmsg = hci_sock_recvmsg,
777 .ioctl = hci_sock_ioctl,
778 .poll = datagram_poll,
779 .listen = sock_no_listen,
780 .shutdown = sock_no_shutdown,
781 .setsockopt = hci_sock_setsockopt,
782 .getsockopt = hci_sock_getsockopt,
783 .connect = sock_no_connect,
784 .socketpair = sock_no_socketpair,
785 .accept = sock_no_accept,
786 .mmap = sock_no_mmap
787};
788
789static struct proto hci_sk_proto = {
790 .name = "HCI",
791 .owner = THIS_MODULE,
792 .obj_size = sizeof(struct hci_pinfo)
793};
794
Eric Paris3f378b62009-11-05 22:18:14 -0800795static int hci_sock_create(struct net *net, struct socket *sock, int protocol,
796 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700797{
798 struct sock *sk;
799
800 BT_DBG("sock %p", sock);
801
802 if (sock->type != SOCK_RAW)
803 return -ESOCKTNOSUPPORT;
804
805 sock->ops = &hci_sock_ops;
806
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700807 sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &hci_sk_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700808 if (!sk)
809 return -ENOMEM;
810
811 sock_init_data(sock, sk);
812
813 sock_reset_flag(sk, SOCK_ZAPPED);
814
815 sk->sk_protocol = protocol;
816
817 sock->state = SS_UNCONNECTED;
818 sk->sk_state = BT_OPEN;
819
820 bt_sock_link(&hci_sk_list, sk);
821 return 0;
822}
823
824static int hci_sock_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
825{
826 struct hci_dev *hdev = (struct hci_dev *) ptr;
827 struct hci_ev_si_device ev;
828
829 BT_DBG("hdev %s event %ld", hdev->name, event);
830
831 /* Send event to sockets */
832 ev.event = event;
833 ev.dev_id = hdev->id;
834 hci_si_event(NULL, HCI_EV_SI_DEVICE, sizeof(ev), &ev);
835
836 if (event == HCI_DEV_UNREG) {
837 struct sock *sk;
838 struct hlist_node *node;
839
840 /* Detach sockets from device */
841 read_lock(&hci_sk_list.lock);
842 sk_for_each(sk, node, &hci_sk_list.head) {
Satyam Sharma4ce61d12007-05-16 23:50:16 -0700843 bh_lock_sock_nested(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700844 if (hci_pi(sk)->hdev == hdev) {
845 hci_pi(sk)->hdev = NULL;
846 sk->sk_err = EPIPE;
847 sk->sk_state = BT_OPEN;
848 sk->sk_state_change(sk);
849
850 hci_dev_put(hdev);
851 }
Satyam Sharma4ce61d12007-05-16 23:50:16 -0700852 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700853 }
854 read_unlock(&hci_sk_list.lock);
855 }
856
857 return NOTIFY_DONE;
858}
859
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +0000860static const struct net_proto_family hci_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700861 .family = PF_BLUETOOTH,
862 .owner = THIS_MODULE,
863 .create = hci_sock_create,
864};
865
866static struct notifier_block hci_sock_nblock = {
867 .notifier_call = hci_sock_dev_event
868};
869
870int __init hci_sock_init(void)
871{
872 int err;
873
874 err = proto_register(&hci_sk_proto, 0);
875 if (err < 0)
876 return err;
877
878 err = bt_sock_register(BTPROTO_HCI, &hci_sock_family_ops);
879 if (err < 0)
880 goto error;
881
882 hci_register_notifier(&hci_sock_nblock);
883
884 BT_INFO("HCI socket layer initialized");
885
886 return 0;
887
888error:
889 BT_ERR("HCI socket registration failed");
890 proto_unregister(&hci_sk_proto);
891 return err;
892}
893
Anand Gadiyarb7440a142011-02-22 12:43:09 +0530894void hci_sock_cleanup(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700895{
896 if (bt_sock_unregister(BTPROTO_HCI) < 0)
897 BT_ERR("HCI socket unregistration failed");
898
899 hci_unregister_notifier(&hci_sock_nblock);
900
901 proto_unregister(&hci_sk_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700902}
Johan Hedberg03811012010-12-08 00:21:06 +0200903
904module_param(enable_mgmt, bool, 0644);
905MODULE_PARM_DESC(enable_mgmt, "Enable Management interface");