1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 BNEP implementation for Linux Bluetooth stack (BlueZ). 4 Copyright (C) 2001-2002 Inventel Systemes 5 Written 2001-2002 by 6 Clément Moreau <clement.moreau@inventel.fr> 7 David Libault <david.libault@inventel.fr> 8 9 Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com> 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 15 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 18 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19 20 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 22 SOFTWARE IS DISCLAIMED. 23 */ 24 25 #include <linux/module.h> 26 #include <linux/kthread.h> 27 #include <linux/file.h> 28 #include <linux/etherdevice.h> 29 #include <linux/unaligned.h> 30 31 #include <net/bluetooth/bluetooth.h> 32 #include <net/bluetooth/l2cap.h> 33 #include <net/bluetooth/hci_core.h> 34 35 #include "bnep.h" 36 37 #define VERSION "1.3" 38 39 static bool compress_src = true; 40 static bool compress_dst = true; 41 42 static LIST_HEAD(bnep_session_list); 43 static DECLARE_RWSEM(bnep_session_sem); 44 45 static struct bnep_session *__bnep_get_session(u8 *dst) 46 { 47 struct bnep_session *s; 48 49 BT_DBG(""); 50 51 list_for_each_entry(s, &bnep_session_list, list) 52 if (ether_addr_equal(dst, s->eh.h_source)) 53 return s; 54 55 return NULL; 56 } 57 58 static void __bnep_link_session(struct bnep_session *s) 59 { 60 list_add(&s->list, &bnep_session_list); 61 } 62 63 static void __bnep_unlink_session(struct bnep_session *s) 64 { 65 list_del(&s->list); 66 } 67 68 static int bnep_send(struct bnep_session *s, void *data, size_t len) 69 { 70 struct socket *sock = s->sock; 71 struct kvec iv = { data, len }; 72 73 return kernel_sendmsg(sock, &s->msg, &iv, 1, len); 74 } 75 76 static int bnep_send_rsp(struct bnep_session *s, u8 ctrl, u16 resp) 77 { 78 struct bnep_control_rsp rsp; 79 rsp.type = BNEP_CONTROL; 80 rsp.ctrl = ctrl; 81 rsp.resp = htons(resp); 82 return bnep_send(s, &rsp, sizeof(rsp)); 83 } 84 85 #ifdef CONFIG_BT_BNEP_PROTO_FILTER 86 static inline void bnep_set_default_proto_filter(struct bnep_session *s) 87 { 88 /* (IPv4, ARP) */ 89 s->proto_filter[0].start = ETH_P_IP; 90 s->proto_filter[0].end = ETH_P_ARP; 91 /* (RARP, AppleTalk) */ 92 s->proto_filter[1].start = ETH_P_RARP; 93 s->proto_filter[1].end = ETH_P_AARP; 94 /* (IPX, IPv6) */ 95 s->proto_filter[2].start = ETH_P_IPX; 96 s->proto_filter[2].end = ETH_P_IPV6; 97 } 98 #endif 99 100 static int bnep_ctrl_set_netfilter(struct bnep_session *s, __be16 *data, int len) 101 { 102 int n; 103 104 if (len < 2) 105 return -EILSEQ; 106 107 n = get_unaligned_be16(data); 108 data++; 109 len -= 2; 110 111 if (len < n) 112 return -EILSEQ; 113 114 BT_DBG("filter len %d", n); 115 116 #ifdef CONFIG_BT_BNEP_PROTO_FILTER 117 n /= 4; 118 if (n <= BNEP_MAX_PROTO_FILTERS) { 119 struct bnep_proto_filter *f = s->proto_filter; 120 int i; 121 122 for (i = 0; i < n; i++) { 123 f[i].start = get_unaligned_be16(data++); 124 f[i].end = get_unaligned_be16(data++); 125 126 BT_DBG("proto filter start %u end %u", 127 f[i].start, f[i].end); 128 } 129 130 if (i < BNEP_MAX_PROTO_FILTERS) 131 memset(f + i, 0, sizeof(*f)); 132 133 if (n == 0) 134 bnep_set_default_proto_filter(s); 135 136 bnep_send_rsp(s, BNEP_FILTER_NET_TYPE_RSP, BNEP_SUCCESS); 137 } else { 138 bnep_send_rsp(s, BNEP_FILTER_NET_TYPE_RSP, BNEP_FILTER_LIMIT_REACHED); 139 } 140 #else 141 bnep_send_rsp(s, BNEP_FILTER_NET_TYPE_RSP, BNEP_FILTER_UNSUPPORTED_REQ); 142 #endif 143 return 0; 144 } 145 146 static int bnep_ctrl_set_mcfilter(struct bnep_session *s, u8 *data, int len) 147 { 148 int n; 149 150 if (len < 2) 151 return -EILSEQ; 152 153 n = get_unaligned_be16(data); 154 data += 2; 155 len -= 2; 156 157 if (len < n) 158 return -EILSEQ; 159 160 BT_DBG("filter len %d", n); 161 162 #ifdef CONFIG_BT_BNEP_MC_FILTER 163 n /= (ETH_ALEN * 2); 164 165 if (n > 0) { 166 int i; 167 168 s->mc_filter = 0; 169 170 /* Always send broadcast */ 171 set_bit(bnep_mc_hash(s->dev->broadcast), (ulong *) &s->mc_filter); 172 173 /* Add address ranges to the multicast hash */ 174 for (; n > 0; n--) { 175 u8 a1[6], *a2; 176 177 memcpy(a1, data, ETH_ALEN); 178 data += ETH_ALEN; 179 a2 = data; 180 data += ETH_ALEN; 181 182 BT_DBG("mc filter %pMR -> %pMR", a1, a2); 183 184 /* Iterate from a1 to a2 */ 185 set_bit(bnep_mc_hash(a1), (ulong *) &s->mc_filter); 186 while (memcmp(a1, a2, 6) < 0 && s->mc_filter != ~0LL) { 187 /* Increment a1 */ 188 i = 5; 189 while (i >= 0 && ++a1[i--] == 0) 190 ; 191 192 set_bit(bnep_mc_hash(a1), (ulong *) &s->mc_filter); 193 } 194 } 195 } 196 197 BT_DBG("mc filter hash 0x%llx", s->mc_filter); 198 199 bnep_send_rsp(s, BNEP_FILTER_MULTI_ADDR_RSP, BNEP_SUCCESS); 200 #else 201 bnep_send_rsp(s, BNEP_FILTER_MULTI_ADDR_RSP, BNEP_FILTER_UNSUPPORTED_REQ); 202 #endif 203 return 0; 204 } 205 206 static int bnep_rx_control_cmd(struct bnep_session *s, u8 cmd, void *data, 207 int len) 208 { 209 int err = 0; 210 211 switch (cmd) { 212 case BNEP_CMD_NOT_UNDERSTOOD: 213 case BNEP_SETUP_CONN_RSP: 214 case BNEP_FILTER_NET_TYPE_RSP: 215 case BNEP_FILTER_MULTI_ADDR_RSP: 216 /* Ignore these for now */ 217 break; 218 219 case BNEP_FILTER_NET_TYPE_SET: 220 err = bnep_ctrl_set_netfilter(s, data, len); 221 break; 222 223 case BNEP_FILTER_MULTI_ADDR_SET: 224 err = bnep_ctrl_set_mcfilter(s, data, len); 225 break; 226 227 case BNEP_SETUP_CONN_REQ: 228 /* Successful response should be sent only once */ 229 if (test_bit(BNEP_SETUP_RESPONSE, &s->flags) && 230 !test_and_set_bit(BNEP_SETUP_RSP_SENT, &s->flags)) 231 err = bnep_send_rsp(s, BNEP_SETUP_CONN_RSP, 232 BNEP_SUCCESS); 233 else 234 err = bnep_send_rsp(s, BNEP_SETUP_CONN_RSP, 235 BNEP_CONN_NOT_ALLOWED); 236 break; 237 238 default: { 239 u8 pkt[3]; 240 pkt[0] = BNEP_CONTROL; 241 pkt[1] = BNEP_CMD_NOT_UNDERSTOOD; 242 pkt[2] = cmd; 243 err = bnep_send(s, pkt, sizeof(pkt)); 244 } 245 break; 246 } 247 248 return err; 249 } 250 251 static int bnep_rx_control(struct bnep_session *s, void *data, int len) 252 { 253 if (len < 1) 254 return -EILSEQ; 255 256 return bnep_rx_control_cmd(s, *(u8 *)data, data + 1, len - 1); 257 } 258 259 static int bnep_rx_extension(struct bnep_session *s, struct sk_buff *skb) 260 { 261 struct bnep_ext_hdr *h; 262 int err = 0; 263 264 do { 265 h = (void *) skb->data; 266 if (!skb_pull(skb, sizeof(*h))) { 267 err = -EILSEQ; 268 break; 269 } 270 271 BT_DBG("type 0x%x len %u", h->type, h->len); 272 273 switch (h->type & BNEP_TYPE_MASK) { 274 case BNEP_EXT_CONTROL: 275 bnep_rx_control(s, skb->data, skb->len); 276 break; 277 278 default: 279 /* Unknown extension, skip it. */ 280 break; 281 } 282 283 if (!skb_pull(skb, h->len)) { 284 err = -EILSEQ; 285 break; 286 } 287 } while (!err && (h->type & BNEP_EXT_HEADER)); 288 289 return err; 290 } 291 292 static u8 __bnep_rx_hlen[] = { 293 ETH_HLEN, /* BNEP_GENERAL */ 294 0, /* BNEP_CONTROL */ 295 2, /* BNEP_COMPRESSED */ 296 ETH_ALEN + 2, /* BNEP_COMPRESSED_SRC_ONLY */ 297 ETH_ALEN + 2 /* BNEP_COMPRESSED_DST_ONLY */ 298 }; 299 300 static int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb) 301 { 302 struct net_device *dev = s->dev; 303 struct sk_buff *nskb; 304 u8 *data; 305 u8 type, ctrl_type; 306 307 dev->stats.rx_bytes += skb->len; 308 309 data = skb_pull_data(skb, sizeof(type)); 310 if (!data) 311 goto badframe; 312 type = *data; 313 314 if ((type & BNEP_TYPE_MASK) >= sizeof(__bnep_rx_hlen)) 315 goto badframe; 316 317 if ((type & BNEP_TYPE_MASK) == BNEP_CONTROL) { 318 data = skb_pull_data(skb, sizeof(ctrl_type)); 319 if (!data) 320 goto badframe; 321 ctrl_type = *data; 322 323 if (bnep_rx_control_cmd(s, ctrl_type, skb->data, skb->len) < 0) { 324 dev->stats.tx_errors++; 325 kfree_skb(skb); 326 return 0; 327 } 328 329 if (!(type & BNEP_EXT_HEADER)) { 330 kfree_skb(skb); 331 return 0; 332 } 333 334 /* Verify and pull ctrl message since it's already processed */ 335 switch (ctrl_type) { 336 case BNEP_SETUP_CONN_REQ: { 337 u8 uuid_size; 338 339 /* Pull uuid_size and the dst/src service UUIDs. */ 340 data = skb_pull_data(skb, sizeof(uuid_size)); 341 if (!data) 342 goto badframe; 343 uuid_size = *data; 344 if (!skb_pull(skb, uuid_size + uuid_size)) 345 goto badframe; 346 break; 347 } 348 case BNEP_FILTER_MULTI_ADDR_SET: 349 case BNEP_FILTER_NET_TYPE_SET: 350 /* Pull: len (2 b), data (len bytes) */ 351 data = skb_pull_data(skb, sizeof(u16)); 352 if (!data) 353 goto badframe; 354 if (!skb_pull(skb, get_unaligned_be16(data))) 355 goto badframe; 356 break; 357 default: 358 kfree_skb(skb); 359 return 0; 360 } 361 } else { 362 skb_reset_mac_header(skb); 363 364 /* Verify and pull out header */ 365 if (!skb_pull(skb, __bnep_rx_hlen[type & BNEP_TYPE_MASK])) 366 goto badframe; 367 368 s->eh.h_proto = get_unaligned((__be16 *) (skb->data - 2)); 369 } 370 371 if (type & BNEP_EXT_HEADER) { 372 if (bnep_rx_extension(s, skb) < 0) 373 goto badframe; 374 } 375 376 /* Strip 802.1p header */ 377 if (ntohs(s->eh.h_proto) == ETH_P_8021Q) { 378 if (!skb_pull(skb, 4)) 379 goto badframe; 380 s->eh.h_proto = get_unaligned((__be16 *) (skb->data - 2)); 381 } 382 383 /* We have to alloc new skb and copy data here :(. Because original skb 384 * may not be modified and because of the alignment requirements. */ 385 nskb = alloc_skb(2 + ETH_HLEN + skb->len, GFP_KERNEL); 386 if (!nskb) { 387 dev->stats.rx_dropped++; 388 kfree_skb(skb); 389 return -ENOMEM; 390 } 391 skb_reserve(nskb, 2); 392 393 /* Decompress header and construct ether frame */ 394 switch (type & BNEP_TYPE_MASK) { 395 case BNEP_COMPRESSED: 396 __skb_put_data(nskb, &s->eh, ETH_HLEN); 397 break; 398 399 case BNEP_COMPRESSED_SRC_ONLY: 400 __skb_put_data(nskb, s->eh.h_dest, ETH_ALEN); 401 __skb_put_data(nskb, skb_mac_header(skb), ETH_ALEN); 402 put_unaligned(s->eh.h_proto, (__be16 *) __skb_put(nskb, 2)); 403 break; 404 405 case BNEP_COMPRESSED_DST_ONLY: 406 __skb_put_data(nskb, skb_mac_header(skb), ETH_ALEN); 407 __skb_put_data(nskb, s->eh.h_source, ETH_ALEN); 408 put_unaligned(s->eh.h_proto, (__be16 *)__skb_put(nskb, 2)); 409 break; 410 411 case BNEP_GENERAL: 412 __skb_put_data(nskb, skb_mac_header(skb), ETH_ALEN * 2); 413 put_unaligned(s->eh.h_proto, (__be16 *) __skb_put(nskb, 2)); 414 break; 415 } 416 417 skb_copy_from_linear_data(skb, __skb_put(nskb, skb->len), skb->len); 418 kfree_skb(skb); 419 420 dev->stats.rx_packets++; 421 nskb->ip_summed = CHECKSUM_NONE; 422 nskb->protocol = eth_type_trans(nskb, dev); 423 netif_rx(nskb); 424 return 0; 425 426 badframe: 427 dev->stats.rx_errors++; 428 kfree_skb(skb); 429 return 0; 430 } 431 432 static u8 __bnep_tx_types[] = { 433 BNEP_GENERAL, 434 BNEP_COMPRESSED_SRC_ONLY, 435 BNEP_COMPRESSED_DST_ONLY, 436 BNEP_COMPRESSED 437 }; 438 439 static int bnep_tx_frame(struct bnep_session *s, struct sk_buff *skb) 440 { 441 struct ethhdr *eh = (void *) skb->data; 442 struct socket *sock = s->sock; 443 struct kvec iv[3]; 444 int len = 0, il = 0; 445 u8 type = 0; 446 447 BT_DBG("skb %p dev %p type %u", skb, skb->dev, skb->pkt_type); 448 449 if (!skb->dev) { 450 /* Control frame sent by us */ 451 goto send; 452 } 453 454 iv[il++] = (struct kvec) { &type, 1 }; 455 len++; 456 457 if (compress_src && ether_addr_equal(eh->h_dest, s->eh.h_source)) 458 type |= 0x01; 459 460 if (compress_dst && ether_addr_equal(eh->h_source, s->eh.h_dest)) 461 type |= 0x02; 462 463 if (type) 464 skb_pull(skb, ETH_ALEN * 2); 465 466 type = __bnep_tx_types[type]; 467 switch (type) { 468 case BNEP_COMPRESSED_SRC_ONLY: 469 iv[il++] = (struct kvec) { eh->h_source, ETH_ALEN }; 470 len += ETH_ALEN; 471 break; 472 473 case BNEP_COMPRESSED_DST_ONLY: 474 iv[il++] = (struct kvec) { eh->h_dest, ETH_ALEN }; 475 len += ETH_ALEN; 476 break; 477 } 478 479 send: 480 iv[il++] = (struct kvec) { skb->data, skb->len }; 481 len += skb->len; 482 483 /* FIXME: linearize skb */ 484 { 485 len = kernel_sendmsg(sock, &s->msg, iv, il, len); 486 } 487 kfree_skb(skb); 488 489 if (len > 0) { 490 s->dev->stats.tx_bytes += len; 491 s->dev->stats.tx_packets++; 492 return 0; 493 } 494 495 return len; 496 } 497 498 static int bnep_session(void *arg) 499 { 500 struct bnep_session *s = arg; 501 struct net_device *dev = s->dev; 502 struct sock *sk = s->sock->sk; 503 struct sk_buff *skb; 504 DEFINE_WAIT_FUNC(wait, woken_wake_function); 505 506 BT_DBG(""); 507 508 set_user_nice(current, -15); 509 510 add_wait_queue(sk_sleep(sk), &wait); 511 while (1) { 512 if (atomic_read(&s->terminate)) 513 break; 514 /* RX */ 515 while ((skb = skb_dequeue(&sk->sk_receive_queue))) { 516 skb_orphan(skb); 517 if (!skb_linearize(skb)) 518 bnep_rx_frame(s, skb); 519 else 520 kfree_skb(skb); 521 } 522 523 if (sk->sk_state != BT_CONNECTED) 524 break; 525 526 /* TX */ 527 while ((skb = skb_dequeue(&sk->sk_write_queue))) 528 if (bnep_tx_frame(s, skb)) 529 break; 530 netif_wake_queue(dev); 531 532 /* 533 * wait_woken() performs the necessary memory barriers 534 * for us; see the header comment for this primitive. 535 */ 536 wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT); 537 } 538 remove_wait_queue(sk_sleep(sk), &wait); 539 540 /* Cleanup session */ 541 down_write(&bnep_session_sem); 542 543 /* Delete network device */ 544 unregister_netdev(dev); 545 546 /* Wakeup user-space polling for socket errors */ 547 s->sock->sk->sk_err = EUNATCH; 548 549 wake_up_interruptible(sk_sleep(s->sock->sk)); 550 551 /* Release the socket */ 552 fput(s->sock->file); 553 554 __bnep_unlink_session(s); 555 556 up_write(&bnep_session_sem); 557 free_netdev(dev); 558 module_put_and_kthread_exit(0); 559 return 0; 560 } 561 562 static struct l2cap_conn *bnep_get_conn(struct bnep_session *session) 563 { 564 struct l2cap_chan *chan = l2cap_pi(session->sock->sk)->chan; 565 struct l2cap_conn *conn; 566 567 l2cap_chan_lock(chan); 568 conn = chan->conn; 569 if (conn) 570 l2cap_conn_get(conn); 571 l2cap_chan_unlock(chan); 572 573 return conn; 574 } 575 576 static const struct device_type bnep_type = { 577 .name = "bluetooth", 578 }; 579 580 int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock) 581 { 582 u32 valid_flags = BIT(BNEP_SETUP_RESPONSE); 583 struct net_device *dev; 584 struct bnep_session *s, *ss; 585 struct l2cap_conn *conn = NULL; 586 u8 dst[ETH_ALEN], src[ETH_ALEN]; 587 int err; 588 589 BT_DBG(""); 590 591 if (!l2cap_is_socket(sock)) 592 return -EBADFD; 593 594 if (req->flags & ~valid_flags) 595 return -EINVAL; 596 597 baswap((void *) dst, &l2cap_pi(sock->sk)->chan->dst); 598 baswap((void *) src, &l2cap_pi(sock->sk)->chan->src); 599 600 /* session struct allocated as private part of net_device */ 601 dev = alloc_netdev(sizeof(struct bnep_session), 602 (*req->device) ? req->device : "bnep%d", 603 NET_NAME_UNKNOWN, 604 bnep_net_setup); 605 if (!dev) 606 return -ENOMEM; 607 608 down_write(&bnep_session_sem); 609 610 ss = __bnep_get_session(dst); 611 if (ss && ss->state == BT_CONNECTED) { 612 err = -EEXIST; 613 goto failed; 614 } 615 616 s = netdev_priv(dev); 617 618 /* This is rx header therefore addresses are swapped. 619 * ie. eh.h_dest is our local address. */ 620 memcpy(s->eh.h_dest, &src, ETH_ALEN); 621 memcpy(s->eh.h_source, &dst, ETH_ALEN); 622 eth_hw_addr_set(dev, s->eh.h_dest); 623 624 s->dev = dev; 625 s->sock = sock; 626 s->role = req->role; 627 s->state = BT_CONNECTED; 628 s->flags = req->flags; 629 630 s->msg.msg_flags = MSG_NOSIGNAL; 631 632 #ifdef CONFIG_BT_BNEP_MC_FILTER 633 /* Set default mc filter to not filter out any mc addresses 634 * as defined in the BNEP specification (revision 0.95a) 635 * http://grouper.ieee.org/groups/802/15/Bluetooth/BNEP.pdf 636 */ 637 s->mc_filter = ~0LL; 638 #endif 639 640 #ifdef CONFIG_BT_BNEP_PROTO_FILTER 641 /* Set default protocol filter */ 642 bnep_set_default_proto_filter(s); 643 #endif 644 645 conn = bnep_get_conn(s); 646 if (!conn) { 647 err = -ENOTCONN; 648 goto failed; 649 } 650 651 SET_NETDEV_DEV(dev, &conn->hcon->dev); 652 SET_NETDEV_DEVTYPE(dev, &bnep_type); 653 654 err = register_netdev(dev); 655 l2cap_conn_put(conn); 656 conn = NULL; 657 if (err) 658 goto failed; 659 660 __bnep_link_session(s); 661 662 __module_get(THIS_MODULE); 663 s->task = kthread_run(bnep_session, s, "kbnepd %s", dev->name); 664 if (IS_ERR(s->task)) { 665 /* Session thread start failed, gotta cleanup. */ 666 module_put(THIS_MODULE); 667 unregister_netdev(dev); 668 __bnep_unlink_session(s); 669 err = PTR_ERR(s->task); 670 goto failed; 671 } 672 673 strcpy(req->device, dev->name); 674 up_write(&bnep_session_sem); 675 return 0; 676 677 failed: 678 if (conn) 679 l2cap_conn_put(conn); 680 up_write(&bnep_session_sem); 681 free_netdev(dev); 682 return err; 683 } 684 685 int bnep_del_connection(struct bnep_conndel_req *req) 686 { 687 u32 valid_flags = 0; 688 struct bnep_session *s; 689 int err = 0; 690 691 BT_DBG(""); 692 693 if (req->flags & ~valid_flags) 694 return -EINVAL; 695 696 down_read(&bnep_session_sem); 697 698 s = __bnep_get_session(req->dst); 699 if (s) { 700 atomic_inc(&s->terminate); 701 wake_up_interruptible(sk_sleep(s->sock->sk)); 702 } else 703 err = -ENOENT; 704 705 up_read(&bnep_session_sem); 706 return err; 707 } 708 709 static void __bnep_copy_ci(struct bnep_conninfo *ci, struct bnep_session *s) 710 { 711 u32 valid_flags = BIT(BNEP_SETUP_RESPONSE); 712 713 memset(ci, 0, sizeof(*ci)); 714 memcpy(ci->dst, s->eh.h_source, ETH_ALEN); 715 strcpy(ci->device, s->dev->name); 716 ci->flags = s->flags & valid_flags; 717 ci->state = s->state; 718 ci->role = s->role; 719 } 720 721 int bnep_get_connlist(struct bnep_connlist_req *req) 722 { 723 struct bnep_session *s; 724 int err = 0, n = 0; 725 726 down_read(&bnep_session_sem); 727 728 list_for_each_entry(s, &bnep_session_list, list) { 729 struct bnep_conninfo ci; 730 731 __bnep_copy_ci(&ci, s); 732 733 if (copy_to_user(req->ci, &ci, sizeof(ci))) { 734 err = -EFAULT; 735 break; 736 } 737 738 if (++n >= req->cnum) 739 break; 740 741 req->ci++; 742 } 743 req->cnum = n; 744 745 up_read(&bnep_session_sem); 746 return err; 747 } 748 749 int bnep_get_conninfo(struct bnep_conninfo *ci) 750 { 751 struct bnep_session *s; 752 int err = 0; 753 754 down_read(&bnep_session_sem); 755 756 s = __bnep_get_session(ci->dst); 757 if (s) 758 __bnep_copy_ci(ci, s); 759 else 760 err = -ENOENT; 761 762 up_read(&bnep_session_sem); 763 return err; 764 } 765 766 static int __init bnep_init(void) 767 { 768 char flt[50] = ""; 769 770 #ifdef CONFIG_BT_BNEP_PROTO_FILTER 771 strcat(flt, "protocol "); 772 #endif 773 774 #ifdef CONFIG_BT_BNEP_MC_FILTER 775 strcat(flt, "multicast"); 776 #endif 777 778 BT_INFO("BNEP (Ethernet Emulation) ver %s", VERSION); 779 if (flt[0]) 780 BT_INFO("BNEP filters: %s", flt); 781 782 return bnep_sock_init(); 783 } 784 785 static void __exit bnep_exit(void) 786 { 787 bnep_sock_cleanup(); 788 } 789 790 module_init(bnep_init); 791 module_exit(bnep_exit); 792 793 module_param(compress_src, bool, 0644); 794 MODULE_PARM_DESC(compress_src, "Compress sources headers"); 795 796 module_param(compress_dst, bool, 0644); 797 MODULE_PARM_DESC(compress_dst, "Compress destination headers"); 798 799 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>"); 800 MODULE_DESCRIPTION("Bluetooth BNEP ver " VERSION); 801 MODULE_VERSION(VERSION); 802 MODULE_LICENSE("GPL"); 803 MODULE_ALIAS("bt-proto-4"); 804