blob: 612bc2af05a9632440645fec8b64afefbe876561 [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
Gustavo F. Padovan17f9cc32010-12-22 23:00:34 -0200370 if (haddr.hci_channel > HCI_CHANNEL_CONTROL)
371 return -EINVAL;
372
Johan Hedberg14c0b602011-12-15 00:47:37 +0200373 if (haddr.hci_channel == HCI_CHANNEL_CONTROL) {
374 if (!enable_mgmt)
375 return -EINVAL;
376 set_bit(HCI_PI_MGMT_INIT, &hci_pi(sk)->flags);
377 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378
379 lock_sock(sk);
380
Johan Hedberg03811012010-12-08 00:21:06 +0200381 if (sk->sk_state == BT_BOUND || hci_pi(sk)->hdev) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700382 err = -EALREADY;
383 goto done;
384 }
385
Johan Hedberg03811012010-12-08 00:21:06 +0200386 if (haddr.hci_dev != HCI_DEV_NONE) {
387 hdev = hci_dev_get(haddr.hci_dev);
Andrei Emeltchenko70f230202010-12-01 16:58:25 +0200388 if (!hdev) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700389 err = -ENODEV;
390 goto done;
391 }
392
393 atomic_inc(&hdev->promisc);
394 }
395
Johan Hedberg03811012010-12-08 00:21:06 +0200396 hci_pi(sk)->channel = haddr.hci_channel;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397 hci_pi(sk)->hdev = hdev;
398 sk->sk_state = BT_BOUND;
399
400done:
401 release_sock(sk);
402 return err;
403}
404
405static int hci_sock_getname(struct socket *sock, struct sockaddr *addr, int *addr_len, int peer)
406{
407 struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr;
408 struct sock *sk = sock->sk;
Marcel Holtmann7b005bd2006-02-13 11:40:03 +0100409 struct hci_dev *hdev = hci_pi(sk)->hdev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410
411 BT_DBG("sock %p sk %p", sock, sk);
412
Marcel Holtmann7b005bd2006-02-13 11:40:03 +0100413 if (!hdev)
414 return -EBADFD;
415
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416 lock_sock(sk);
417
418 *addr_len = sizeof(*haddr);
419 haddr->hci_family = AF_BLUETOOTH;
Marcel Holtmann7b005bd2006-02-13 11:40:03 +0100420 haddr->hci_dev = hdev->id;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421
422 release_sock(sk);
423 return 0;
424}
425
426static inline void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
427{
428 __u32 mask = hci_pi(sk)->cmsg_mask;
429
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700430 if (mask & HCI_CMSG_DIR) {
431 int incoming = bt_cb(skb)->incoming;
432 put_cmsg(msg, SOL_HCI, HCI_CMSG_DIR, sizeof(incoming), &incoming);
433 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700434
Patrick McHardya61bbcf2005-08-14 17:24:31 -0700435 if (mask & HCI_CMSG_TSTAMP) {
Johann Felix Sodenf6e623a2010-02-15 22:23:48 +0100436#ifdef CONFIG_COMPAT
437 struct compat_timeval ctv;
438#endif
Patrick McHardya61bbcf2005-08-14 17:24:31 -0700439 struct timeval tv;
Marcel Holtmann767c5eb2007-09-09 08:39:34 +0200440 void *data;
441 int len;
Patrick McHardya61bbcf2005-08-14 17:24:31 -0700442
443 skb_get_timestamp(skb, &tv);
Marcel Holtmann767c5eb2007-09-09 08:39:34 +0200444
David S. Miller1da97f82007-09-12 14:10:58 +0200445 data = &tv;
446 len = sizeof(tv);
447#ifdef CONFIG_COMPAT
Marcel Holtmann767c5eb2007-09-09 08:39:34 +0200448 if (msg->msg_flags & MSG_CMSG_COMPAT) {
Marcel Holtmann767c5eb2007-09-09 08:39:34 +0200449 ctv.tv_sec = tv.tv_sec;
450 ctv.tv_usec = tv.tv_usec;
451 data = &ctv;
452 len = sizeof(ctv);
Marcel Holtmann767c5eb2007-09-09 08:39:34 +0200453 }
David S. Miller1da97f82007-09-12 14:10:58 +0200454#endif
Marcel Holtmann767c5eb2007-09-09 08:39:34 +0200455
456 put_cmsg(msg, SOL_HCI, HCI_CMSG_TSTAMP, len, data);
Patrick McHardya61bbcf2005-08-14 17:24:31 -0700457 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700458}
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900459
460static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700461 struct msghdr *msg, size_t len, int flags)
462{
463 int noblock = flags & MSG_DONTWAIT;
464 struct sock *sk = sock->sk;
465 struct sk_buff *skb;
466 int copied, err;
467
468 BT_DBG("sock %p, sk %p", sock, sk);
469
470 if (flags & (MSG_OOB))
471 return -EOPNOTSUPP;
472
473 if (sk->sk_state == BT_CLOSED)
474 return 0;
475
Andrei Emeltchenko70f230202010-12-01 16:58:25 +0200476 skb = skb_recv_datagram(sk, flags, noblock, &err);
477 if (!skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700478 return err;
479
480 msg->msg_namelen = 0;
481
482 copied = skb->len;
483 if (len < copied) {
484 msg->msg_flags |= MSG_TRUNC;
485 copied = len;
486 }
487
Arnaldo Carvalho de Melobadff6d2007-03-13 13:06:52 -0300488 skb_reset_transport_header(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700489 err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
490
491 hci_sock_cmsg(sk, msg, skb);
492
493 skb_free_datagram(sk, skb);
494
495 return err ? : copied;
496}
497
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900498static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700499 struct msghdr *msg, size_t len)
500{
501 struct sock *sk = sock->sk;
502 struct hci_dev *hdev;
503 struct sk_buff *skb;
504 int err;
505
506 BT_DBG("sock %p sk %p", sock, sk);
507
508 if (msg->msg_flags & MSG_OOB)
509 return -EOPNOTSUPP;
510
511 if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE))
512 return -EINVAL;
513
514 if (len < 4 || len > HCI_MAX_FRAME_SIZE)
515 return -EINVAL;
516
517 lock_sock(sk);
518
Johan Hedberg03811012010-12-08 00:21:06 +0200519 switch (hci_pi(sk)->channel) {
520 case HCI_CHANNEL_RAW:
521 break;
522 case HCI_CHANNEL_CONTROL:
523 err = mgmt_control(sk, msg, len);
524 goto done;
525 default:
526 err = -EINVAL;
527 goto done;
528 }
529
Andrei Emeltchenko70f230202010-12-01 16:58:25 +0200530 hdev = hci_pi(sk)->hdev;
531 if (!hdev) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700532 err = -EBADFD;
533 goto done;
534 }
535
Marcel Holtmann7e21add2009-11-18 01:05:00 +0100536 if (!test_bit(HCI_UP, &hdev->flags)) {
537 err = -ENETDOWN;
538 goto done;
539 }
540
Andrei Emeltchenko70f230202010-12-01 16:58:25 +0200541 skb = bt_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err);
542 if (!skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700543 goto done;
544
545 if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
546 err = -EFAULT;
547 goto drop;
548 }
549
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700550 bt_cb(skb)->pkt_type = *((unsigned char *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551 skb_pull(skb, 1);
552 skb->dev = (void *) hdev;
553
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700554 if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) {
Harvey Harrison83985312008-05-02 16:25:46 -0700555 u16 opcode = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556 u16 ogf = hci_opcode_ogf(opcode);
557 u16 ocf = hci_opcode_ocf(opcode);
558
559 if (((ogf > HCI_SFLT_MAX_OGF) ||
560 !hci_test_bit(ocf & HCI_FLT_OCF_BITS, &hci_sec_filter.ocf_mask[ogf])) &&
561 !capable(CAP_NET_RAW)) {
562 err = -EPERM;
563 goto drop;
564 }
565
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200566 if (test_bit(HCI_RAW, &hdev->flags) || (ogf == 0x3f)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567 skb_queue_tail(&hdev->raw_q, skb);
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -0200568 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569 } else {
570 skb_queue_tail(&hdev->cmd_q, skb);
Gustavo F. Padovanc347b762011-12-14 23:53:47 -0200571 queue_work(hdev->workqueue, &hdev->cmd_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700572 }
573 } else {
574 if (!capable(CAP_NET_RAW)) {
575 err = -EPERM;
576 goto drop;
577 }
578
579 skb_queue_tail(&hdev->raw_q, skb);
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -0200580 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581 }
582
583 err = len;
584
585done:
586 release_sock(sk);
587 return err;
588
589drop:
590 kfree_skb(skb);
591 goto done;
592}
593
David S. Millerb7058842009-09-30 16:12:20 -0700594static int hci_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int len)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700595{
596 struct hci_ufilter uf = { .opcode = 0 };
597 struct sock *sk = sock->sk;
598 int err = 0, opt = 0;
599
600 BT_DBG("sk %p, opt %d", sk, optname);
601
602 lock_sock(sk);
603
Marcel Holtmann2f39cdb2012-02-20 14:50:32 +0100604 if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) {
605 err = -EINVAL;
606 goto done;
607 }
608
Linus Torvalds1da177e2005-04-16 15:20:36 -0700609 switch (optname) {
610 case HCI_DATA_DIR:
611 if (get_user(opt, (int __user *)optval)) {
612 err = -EFAULT;
613 break;
614 }
615
616 if (opt)
617 hci_pi(sk)->cmsg_mask |= HCI_CMSG_DIR;
618 else
619 hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_DIR;
620 break;
621
622 case HCI_TIME_STAMP:
623 if (get_user(opt, (int __user *)optval)) {
624 err = -EFAULT;
625 break;
626 }
627
628 if (opt)
629 hci_pi(sk)->cmsg_mask |= HCI_CMSG_TSTAMP;
630 else
631 hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_TSTAMP;
632 break;
633
634 case HCI_FILTER:
Marcel Holtmann0878b662007-05-05 00:35:59 +0200635 {
636 struct hci_filter *f = &hci_pi(sk)->filter;
637
638 uf.type_mask = f->type_mask;
639 uf.opcode = f->opcode;
640 uf.event_mask[0] = *((u32 *) f->event_mask + 0);
641 uf.event_mask[1] = *((u32 *) f->event_mask + 1);
642 }
643
Linus Torvalds1da177e2005-04-16 15:20:36 -0700644 len = min_t(unsigned int, len, sizeof(uf));
645 if (copy_from_user(&uf, optval, len)) {
646 err = -EFAULT;
647 break;
648 }
649
650 if (!capable(CAP_NET_RAW)) {
651 uf.type_mask &= hci_sec_filter.type_mask;
652 uf.event_mask[0] &= *((u32 *) hci_sec_filter.event_mask + 0);
653 uf.event_mask[1] &= *((u32 *) hci_sec_filter.event_mask + 1);
654 }
655
656 {
657 struct hci_filter *f = &hci_pi(sk)->filter;
658
659 f->type_mask = uf.type_mask;
660 f->opcode = uf.opcode;
661 *((u32 *) f->event_mask + 0) = uf.event_mask[0];
662 *((u32 *) f->event_mask + 1) = uf.event_mask[1];
663 }
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900664 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700665
666 default:
667 err = -ENOPROTOOPT;
668 break;
669 }
670
Marcel Holtmann2f39cdb2012-02-20 14:50:32 +0100671done:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700672 release_sock(sk);
673 return err;
674}
675
676static int hci_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
677{
678 struct hci_ufilter uf;
679 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900680 int len, opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700681
682 if (get_user(len, optlen))
683 return -EFAULT;
684
685 switch (optname) {
686 case HCI_DATA_DIR:
687 if (hci_pi(sk)->cmsg_mask & HCI_CMSG_DIR)
688 opt = 1;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900689 else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700690 opt = 0;
691
692 if (put_user(opt, optval))
693 return -EFAULT;
694 break;
695
696 case HCI_TIME_STAMP:
697 if (hci_pi(sk)->cmsg_mask & HCI_CMSG_TSTAMP)
698 opt = 1;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900699 else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700700 opt = 0;
701
702 if (put_user(opt, optval))
703 return -EFAULT;
704 break;
705
706 case HCI_FILTER:
707 {
708 struct hci_filter *f = &hci_pi(sk)->filter;
709
710 uf.type_mask = f->type_mask;
711 uf.opcode = f->opcode;
712 uf.event_mask[0] = *((u32 *) f->event_mask + 0);
713 uf.event_mask[1] = *((u32 *) f->event_mask + 1);
714 }
715
716 len = min_t(unsigned int, len, sizeof(uf));
717 if (copy_to_user(optval, &uf, len))
718 return -EFAULT;
719 break;
720
721 default:
722 return -ENOPROTOOPT;
723 break;
724 }
725
726 return 0;
727}
728
Eric Dumazet90ddc4f2005-12-22 12:49:22 -0800729static const struct proto_ops hci_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700730 .family = PF_BLUETOOTH,
731 .owner = THIS_MODULE,
732 .release = hci_sock_release,
733 .bind = hci_sock_bind,
734 .getname = hci_sock_getname,
735 .sendmsg = hci_sock_sendmsg,
736 .recvmsg = hci_sock_recvmsg,
737 .ioctl = hci_sock_ioctl,
738 .poll = datagram_poll,
739 .listen = sock_no_listen,
740 .shutdown = sock_no_shutdown,
741 .setsockopt = hci_sock_setsockopt,
742 .getsockopt = hci_sock_getsockopt,
743 .connect = sock_no_connect,
744 .socketpair = sock_no_socketpair,
745 .accept = sock_no_accept,
746 .mmap = sock_no_mmap
747};
748
749static struct proto hci_sk_proto = {
750 .name = "HCI",
751 .owner = THIS_MODULE,
752 .obj_size = sizeof(struct hci_pinfo)
753};
754
Eric Paris3f378b62009-11-05 22:18:14 -0800755static int hci_sock_create(struct net *net, struct socket *sock, int protocol,
756 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700757{
758 struct sock *sk;
759
760 BT_DBG("sock %p", sock);
761
762 if (sock->type != SOCK_RAW)
763 return -ESOCKTNOSUPPORT;
764
765 sock->ops = &hci_sock_ops;
766
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700767 sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &hci_sk_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700768 if (!sk)
769 return -ENOMEM;
770
771 sock_init_data(sock, sk);
772
773 sock_reset_flag(sk, SOCK_ZAPPED);
774
775 sk->sk_protocol = protocol;
776
777 sock->state = SS_UNCONNECTED;
778 sk->sk_state = BT_OPEN;
779
780 bt_sock_link(&hci_sk_list, sk);
781 return 0;
782}
783
784static int hci_sock_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
785{
786 struct hci_dev *hdev = (struct hci_dev *) ptr;
787 struct hci_ev_si_device ev;
788
789 BT_DBG("hdev %s event %ld", hdev->name, event);
790
791 /* Send event to sockets */
792 ev.event = event;
793 ev.dev_id = hdev->id;
794 hci_si_event(NULL, HCI_EV_SI_DEVICE, sizeof(ev), &ev);
795
796 if (event == HCI_DEV_UNREG) {
797 struct sock *sk;
798 struct hlist_node *node;
799
800 /* Detach sockets from device */
801 read_lock(&hci_sk_list.lock);
802 sk_for_each(sk, node, &hci_sk_list.head) {
Satyam Sharma4ce61d12007-05-16 23:50:16 -0700803 bh_lock_sock_nested(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700804 if (hci_pi(sk)->hdev == hdev) {
805 hci_pi(sk)->hdev = NULL;
806 sk->sk_err = EPIPE;
807 sk->sk_state = BT_OPEN;
808 sk->sk_state_change(sk);
809
810 hci_dev_put(hdev);
811 }
Satyam Sharma4ce61d12007-05-16 23:50:16 -0700812 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813 }
814 read_unlock(&hci_sk_list.lock);
815 }
816
817 return NOTIFY_DONE;
818}
819
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +0000820static const struct net_proto_family hci_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700821 .family = PF_BLUETOOTH,
822 .owner = THIS_MODULE,
823 .create = hci_sock_create,
824};
825
826static struct notifier_block hci_sock_nblock = {
827 .notifier_call = hci_sock_dev_event
828};
829
830int __init hci_sock_init(void)
831{
832 int err;
833
834 err = proto_register(&hci_sk_proto, 0);
835 if (err < 0)
836 return err;
837
838 err = bt_sock_register(BTPROTO_HCI, &hci_sock_family_ops);
839 if (err < 0)
840 goto error;
841
842 hci_register_notifier(&hci_sock_nblock);
843
844 BT_INFO("HCI socket layer initialized");
845
846 return 0;
847
848error:
849 BT_ERR("HCI socket registration failed");
850 proto_unregister(&hci_sk_proto);
851 return err;
852}
853
Anand Gadiyarb7440a142011-02-22 12:43:09 +0530854void hci_sock_cleanup(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855{
856 if (bt_sock_unregister(BTPROTO_HCI) < 0)
857 BT_ERR("HCI socket unregistration failed");
858
859 hci_unregister_notifier(&hci_sock_nblock);
860
861 proto_unregister(&hci_sk_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700862}
Johan Hedberg03811012010-12-08 00:21:06 +0200863
864module_param(enable_mgmt, bool, 0644);
865MODULE_PARM_DESC(enable_mgmt, "Enable Management interface");