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 device *bnep_get_device(struct bnep_session *session) 563 { 564 struct l2cap_conn *conn = l2cap_pi(session->sock->sk)->chan->conn; 565 566 if (!conn || !conn->hcon) 567 return NULL; 568 569 return &conn->hcon->dev; 570 } 571 572 static const struct device_type bnep_type = { 573 .name = "bluetooth", 574 }; 575 576 int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock) 577 { 578 u32 valid_flags = BIT(BNEP_SETUP_RESPONSE); 579 struct net_device *dev; 580 struct bnep_session *s, *ss; 581 u8 dst[ETH_ALEN], src[ETH_ALEN]; 582 int err; 583 584 BT_DBG(""); 585 586 if (!l2cap_is_socket(sock)) 587 return -EBADFD; 588 589 if (req->flags & ~valid_flags) 590 return -EINVAL; 591 592 baswap((void *) dst, &l2cap_pi(sock->sk)->chan->dst); 593 baswap((void *) src, &l2cap_pi(sock->sk)->chan->src); 594 595 /* session struct allocated as private part of net_device */ 596 dev = alloc_netdev(sizeof(struct bnep_session), 597 (*req->device) ? req->device : "bnep%d", 598 NET_NAME_UNKNOWN, 599 bnep_net_setup); 600 if (!dev) 601 return -ENOMEM; 602 603 down_write(&bnep_session_sem); 604 605 ss = __bnep_get_session(dst); 606 if (ss && ss->state == BT_CONNECTED) { 607 err = -EEXIST; 608 goto failed; 609 } 610 611 s = netdev_priv(dev); 612 613 /* This is rx header therefore addresses are swapped. 614 * ie. eh.h_dest is our local address. */ 615 memcpy(s->eh.h_dest, &src, ETH_ALEN); 616 memcpy(s->eh.h_source, &dst, ETH_ALEN); 617 eth_hw_addr_set(dev, s->eh.h_dest); 618 619 s->dev = dev; 620 s->sock = sock; 621 s->role = req->role; 622 s->state = BT_CONNECTED; 623 s->flags = req->flags; 624 625 s->msg.msg_flags = MSG_NOSIGNAL; 626 627 #ifdef CONFIG_BT_BNEP_MC_FILTER 628 /* Set default mc filter to not filter out any mc addresses 629 * as defined in the BNEP specification (revision 0.95a) 630 * http://grouper.ieee.org/groups/802/15/Bluetooth/BNEP.pdf 631 */ 632 s->mc_filter = ~0LL; 633 #endif 634 635 #ifdef CONFIG_BT_BNEP_PROTO_FILTER 636 /* Set default protocol filter */ 637 bnep_set_default_proto_filter(s); 638 #endif 639 640 SET_NETDEV_DEV(dev, bnep_get_device(s)); 641 SET_NETDEV_DEVTYPE(dev, &bnep_type); 642 643 err = register_netdev(dev); 644 if (err) 645 goto failed; 646 647 __bnep_link_session(s); 648 649 __module_get(THIS_MODULE); 650 s->task = kthread_run(bnep_session, s, "kbnepd %s", dev->name); 651 if (IS_ERR(s->task)) { 652 /* Session thread start failed, gotta cleanup. */ 653 module_put(THIS_MODULE); 654 unregister_netdev(dev); 655 __bnep_unlink_session(s); 656 err = PTR_ERR(s->task); 657 goto failed; 658 } 659 660 strcpy(req->device, dev->name); 661 up_write(&bnep_session_sem); 662 return 0; 663 664 failed: 665 up_write(&bnep_session_sem); 666 free_netdev(dev); 667 return err; 668 } 669 670 int bnep_del_connection(struct bnep_conndel_req *req) 671 { 672 u32 valid_flags = 0; 673 struct bnep_session *s; 674 int err = 0; 675 676 BT_DBG(""); 677 678 if (req->flags & ~valid_flags) 679 return -EINVAL; 680 681 down_read(&bnep_session_sem); 682 683 s = __bnep_get_session(req->dst); 684 if (s) { 685 atomic_inc(&s->terminate); 686 wake_up_interruptible(sk_sleep(s->sock->sk)); 687 } else 688 err = -ENOENT; 689 690 up_read(&bnep_session_sem); 691 return err; 692 } 693 694 static void __bnep_copy_ci(struct bnep_conninfo *ci, struct bnep_session *s) 695 { 696 u32 valid_flags = BIT(BNEP_SETUP_RESPONSE); 697 698 memset(ci, 0, sizeof(*ci)); 699 memcpy(ci->dst, s->eh.h_source, ETH_ALEN); 700 strcpy(ci->device, s->dev->name); 701 ci->flags = s->flags & valid_flags; 702 ci->state = s->state; 703 ci->role = s->role; 704 } 705 706 int bnep_get_connlist(struct bnep_connlist_req *req) 707 { 708 struct bnep_session *s; 709 int err = 0, n = 0; 710 711 down_read(&bnep_session_sem); 712 713 list_for_each_entry(s, &bnep_session_list, list) { 714 struct bnep_conninfo ci; 715 716 __bnep_copy_ci(&ci, s); 717 718 if (copy_to_user(req->ci, &ci, sizeof(ci))) { 719 err = -EFAULT; 720 break; 721 } 722 723 if (++n >= req->cnum) 724 break; 725 726 req->ci++; 727 } 728 req->cnum = n; 729 730 up_read(&bnep_session_sem); 731 return err; 732 } 733 734 int bnep_get_conninfo(struct bnep_conninfo *ci) 735 { 736 struct bnep_session *s; 737 int err = 0; 738 739 down_read(&bnep_session_sem); 740 741 s = __bnep_get_session(ci->dst); 742 if (s) 743 __bnep_copy_ci(ci, s); 744 else 745 err = -ENOENT; 746 747 up_read(&bnep_session_sem); 748 return err; 749 } 750 751 static int __init bnep_init(void) 752 { 753 char flt[50] = ""; 754 755 #ifdef CONFIG_BT_BNEP_PROTO_FILTER 756 strcat(flt, "protocol "); 757 #endif 758 759 #ifdef CONFIG_BT_BNEP_MC_FILTER 760 strcat(flt, "multicast"); 761 #endif 762 763 BT_INFO("BNEP (Ethernet Emulation) ver %s", VERSION); 764 if (flt[0]) 765 BT_INFO("BNEP filters: %s", flt); 766 767 return bnep_sock_init(); 768 } 769 770 static void __exit bnep_exit(void) 771 { 772 bnep_sock_cleanup(); 773 } 774 775 module_init(bnep_init); 776 module_exit(bnep_exit); 777 778 module_param(compress_src, bool, 0644); 779 MODULE_PARM_DESC(compress_src, "Compress sources headers"); 780 781 module_param(compress_dst, bool, 0644); 782 MODULE_PARM_DESC(compress_dst, "Compress destination headers"); 783 784 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>"); 785 MODULE_DESCRIPTION("Bluetooth BNEP ver " VERSION); 786 MODULE_VERSION(VERSION); 787 MODULE_LICENSE("GPL"); 788 MODULE_ALIAS("bt-proto-4"); 789