aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/hci_sock.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/bluetooth/hci_sock.c')
-rw-r--r--net/bluetooth/hci_sock.c67
1 files changed, 55 insertions, 12 deletions
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 83acd164d39e..29827c77f6ce 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -43,12 +43,14 @@
43#include <net/sock.h> 43#include <net/sock.h>
44 44
45#include <asm/system.h> 45#include <asm/system.h>
46#include <asm/uaccess.h> 46#include <linux/uaccess.h>
47#include <asm/unaligned.h> 47#include <asm/unaligned.h>
48 48
49#include <net/bluetooth/bluetooth.h> 49#include <net/bluetooth/bluetooth.h>
50#include <net/bluetooth/hci_core.h> 50#include <net/bluetooth/hci_core.h>
51 51
52static int enable_mgmt;
53
52/* ----- HCI socket interface ----- */ 54/* ----- HCI socket interface ----- */
53 55
54static inline int hci_test_bit(int nr, void *addr) 56static inline int hci_test_bit(int nr, void *addr)
@@ -102,6 +104,12 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
102 if (skb->sk == sk) 104 if (skb->sk == sk)
103 continue; 105 continue;
104 106
107 if (bt_cb(skb)->channel != hci_pi(sk)->channel)
108 continue;
109
110 if (bt_cb(skb)->channel == HCI_CHANNEL_CONTROL)
111 goto clone;
112
105 /* Apply filter */ 113 /* Apply filter */
106 flt = &hci_pi(sk)->filter; 114 flt = &hci_pi(sk)->filter;
107 115
@@ -125,11 +133,14 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
125 continue; 133 continue;
126 } 134 }
127 135
128 if (!(nskb = skb_clone(skb, GFP_ATOMIC))) 136clone:
137 nskb = skb_clone(skb, GFP_ATOMIC);
138 if (!nskb)
129 continue; 139 continue;
130 140
131 /* Put type byte before the data */ 141 /* Put type byte before the data */
132 memcpy(skb_push(nskb, 1), &bt_cb(nskb)->pkt_type, 1); 142 if (bt_cb(skb)->channel == HCI_CHANNEL_RAW)
143 memcpy(skb_push(nskb, 1), &bt_cb(nskb)->pkt_type, 1);
133 144
134 if (sock_queue_rcv_skb(sk, nskb)) 145 if (sock_queue_rcv_skb(sk, nskb))
135 kfree_skb(nskb); 146 kfree_skb(nskb);
@@ -352,25 +363,39 @@ static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long a
352 363
353static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len) 364static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
354{ 365{
355 struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr; 366 struct sockaddr_hci haddr;
356 struct sock *sk = sock->sk; 367 struct sock *sk = sock->sk;
357 struct hci_dev *hdev = NULL; 368 struct hci_dev *hdev = NULL;
358 int err = 0; 369 int len, err = 0;
359 370
360 BT_DBG("sock %p sk %p", sock, sk); 371 BT_DBG("sock %p sk %p", sock, sk);
361 372
362 if (!haddr || haddr->hci_family != AF_BLUETOOTH) 373 if (!addr)
374 return -EINVAL;
375
376 memset(&haddr, 0, sizeof(haddr));
377 len = min_t(unsigned int, sizeof(haddr), addr_len);
378 memcpy(&haddr, addr, len);
379
380 if (haddr.hci_family != AF_BLUETOOTH)
381 return -EINVAL;
382
383 if (haddr.hci_channel > HCI_CHANNEL_CONTROL)
384 return -EINVAL;
385
386 if (haddr.hci_channel == HCI_CHANNEL_CONTROL && !enable_mgmt)
363 return -EINVAL; 387 return -EINVAL;
364 388
365 lock_sock(sk); 389 lock_sock(sk);
366 390
367 if (hci_pi(sk)->hdev) { 391 if (sk->sk_state == BT_BOUND || hci_pi(sk)->hdev) {
368 err = -EALREADY; 392 err = -EALREADY;
369 goto done; 393 goto done;
370 } 394 }
371 395
372 if (haddr->hci_dev != HCI_DEV_NONE) { 396 if (haddr.hci_dev != HCI_DEV_NONE) {
373 if (!(hdev = hci_dev_get(haddr->hci_dev))) { 397 hdev = hci_dev_get(haddr.hci_dev);
398 if (!hdev) {
374 err = -ENODEV; 399 err = -ENODEV;
375 goto done; 400 goto done;
376 } 401 }
@@ -378,6 +403,7 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_le
378 atomic_inc(&hdev->promisc); 403 atomic_inc(&hdev->promisc);
379 } 404 }
380 405
406 hci_pi(sk)->channel = haddr.hci_channel;
381 hci_pi(sk)->hdev = hdev; 407 hci_pi(sk)->hdev = hdev;
382 sk->sk_state = BT_BOUND; 408 sk->sk_state = BT_BOUND;
383 409
@@ -457,7 +483,8 @@ static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
457 if (sk->sk_state == BT_CLOSED) 483 if (sk->sk_state == BT_CLOSED)
458 return 0; 484 return 0;
459 485
460 if (!(skb = skb_recv_datagram(sk, flags, noblock, &err))) 486 skb = skb_recv_datagram(sk, flags, noblock, &err);
487 if (!skb)
461 return err; 488 return err;
462 489
463 msg->msg_namelen = 0; 490 msg->msg_namelen = 0;
@@ -499,7 +526,19 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
499 526
500 lock_sock(sk); 527 lock_sock(sk);
501 528
502 if (!(hdev = hci_pi(sk)->hdev)) { 529 switch (hci_pi(sk)->channel) {
530 case HCI_CHANNEL_RAW:
531 break;
532 case HCI_CHANNEL_CONTROL:
533 err = mgmt_control(sk, msg, len);
534 goto done;
535 default:
536 err = -EINVAL;
537 goto done;
538 }
539
540 hdev = hci_pi(sk)->hdev;
541 if (!hdev) {
503 err = -EBADFD; 542 err = -EBADFD;
504 goto done; 543 goto done;
505 } 544 }
@@ -509,7 +548,8 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
509 goto done; 548 goto done;
510 } 549 }
511 550
512 if (!(skb = bt_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err))) 551 skb = bt_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err);
552 if (!skb)
513 goto done; 553 goto done;
514 554
515 if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) { 555 if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
@@ -826,3 +866,6 @@ void __exit hci_sock_cleanup(void)
826 866
827 proto_unregister(&hci_sk_proto); 867 proto_unregister(&hci_sk_proto);
828} 868}
869
870module_param(enable_mgmt, bool, 0644);
871MODULE_PARM_DESC(enable_mgmt, "Enable Management interface");