1 /* $NetBSD: hci_socket.c,v 1.19 2009/08/10 20:22:06 plunky Exp $ */ 2 3 /*- 4 * Copyright (c) 2005 Iain Hibbert. 5 * Copyright (c) 2006 Itronix Inc. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of Itronix Inc. may not be used to endorse 17 * or promote products derived from this software without specific 18 * prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY 24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 27 * ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #include <sys/cdefs.h> 34 __KERNEL_RCSID(0, "$NetBSD: hci_socket.c,v 1.19 2009/08/10 20:22:06 plunky Exp $"); 35 36 /* load symbolic names */ 37 #ifdef BLUETOOTH_DEBUG 38 #define PRUREQUESTS 39 #define PRCOREQUESTS 40 #endif 41 42 #include <sys/param.h> 43 #include <sys/domain.h> 44 #include <sys/kauth.h> 45 #include <sys/kernel.h> 46 #include <sys/mbuf.h> 47 #include <sys/proc.h> 48 #include <sys/protosw.h> 49 #include <sys/socket.h> 50 #include <sys/socketvar.h> 51 #include <sys/systm.h> 52 53 #include <netbt/bluetooth.h> 54 #include <netbt/hci.h> 55 56 /******************************************************************************* 57 * 58 * HCI SOCK_RAW Sockets - for control of Bluetooth Devices 59 * 60 */ 61 62 /* 63 * the raw HCI protocol control block 64 */ 65 struct hci_pcb { 66 struct socket *hp_socket; /* socket */ 67 kauth_cred_t hp_cred; /* owner credential */ 68 unsigned int hp_flags; /* flags */ 69 bdaddr_t hp_laddr; /* local address */ 70 bdaddr_t hp_raddr; /* remote address */ 71 struct hci_filter hp_efilter; /* user event filter */ 72 struct hci_filter hp_pfilter; /* user packet filter */ 73 LIST_ENTRY(hci_pcb) hp_next; /* next HCI pcb */ 74 }; 75 76 /* hp_flags */ 77 #define HCI_DIRECTION (1<<1) /* direction control messages */ 78 #define HCI_PROMISCUOUS (1<<2) /* listen to all units */ 79 80 LIST_HEAD(hci_pcb_list, hci_pcb) hci_pcb = LIST_HEAD_INITIALIZER(hci_pcb); 81 82 /* sysctl defaults */ 83 int hci_sendspace = HCI_CMD_PKT_SIZE; 84 int hci_recvspace = 4096; 85 86 /* unprivileged commands opcode table */ 87 static const struct { 88 uint16_t opcode; 89 uint8_t offs; /* 0 - 63 */ 90 uint8_t mask; /* bit 0 - 7 */ 91 uint8_t length; /* approved length */ 92 } hci_cmds[] = { 93 { HCI_CMD_INQUIRY, 94 0, 0x01, sizeof(hci_inquiry_cp) }, 95 { HCI_CMD_REMOTE_NAME_REQ, 96 2, 0x08, sizeof(hci_remote_name_req_cp) }, 97 { HCI_CMD_READ_REMOTE_FEATURES, 98 2, 0x20, sizeof(hci_read_remote_features_cp) }, 99 { HCI_CMD_READ_REMOTE_EXTENDED_FEATURES, 100 2, 0x40, sizeof(hci_read_remote_extended_features_cp) }, 101 { HCI_CMD_READ_REMOTE_VER_INFO, 102 2, 0x80, sizeof(hci_read_remote_ver_info_cp) }, 103 { HCI_CMD_READ_CLOCK_OFFSET, 104 3, 0x01, sizeof(hci_read_clock_offset_cp) }, 105 { HCI_CMD_READ_LMP_HANDLE, 106 3, 0x02, sizeof(hci_read_lmp_handle_cp) }, 107 { HCI_CMD_ROLE_DISCOVERY, 108 4, 0x80, sizeof(hci_role_discovery_cp) }, 109 { HCI_CMD_READ_LINK_POLICY_SETTINGS, 110 5, 0x02, sizeof(hci_read_link_policy_settings_cp) }, 111 { HCI_CMD_READ_DEFAULT_LINK_POLICY_SETTINGS, 112 5, 0x08, 0 }, 113 { HCI_CMD_READ_PIN_TYPE, 114 6, 0x04, 0 }, 115 { HCI_CMD_READ_LOCAL_NAME, 116 7, 0x02, 0 }, 117 { HCI_CMD_READ_CON_ACCEPT_TIMEOUT, 118 7, 0x04, 0 }, 119 { HCI_CMD_READ_PAGE_TIMEOUT, 120 7, 0x10, 0 }, 121 { HCI_CMD_READ_SCAN_ENABLE, 122 7, 0x40, 0 }, 123 { HCI_CMD_READ_PAGE_SCAN_ACTIVITY, 124 8, 0x01, 0 }, 125 { HCI_CMD_READ_INQUIRY_SCAN_ACTIVITY, 126 8, 0x04, 0 }, 127 { HCI_CMD_READ_AUTH_ENABLE, 128 8, 0x10, 0 }, 129 { HCI_CMD_READ_ENCRYPTION_MODE, 130 8, 0x40, 0 }, 131 { HCI_CMD_READ_UNIT_CLASS, 132 9, 0x01, 0 }, 133 { HCI_CMD_READ_VOICE_SETTING, 134 9, 0x04, 0 }, 135 { HCI_CMD_READ_AUTO_FLUSH_TIMEOUT, 136 9, 0x10, sizeof(hci_read_auto_flush_timeout_cp) }, 137 { HCI_CMD_READ_NUM_BROADCAST_RETRANS, 138 9, 0x40, 0 }, 139 { HCI_CMD_READ_HOLD_MODE_ACTIVITY, 140 10, 0x01, 0 }, 141 { HCI_CMD_READ_XMIT_LEVEL, 142 10, 0x04, sizeof(hci_read_xmit_level_cp) }, 143 { HCI_CMD_READ_SCO_FLOW_CONTROL, 144 10, 0x08, 0 }, 145 { HCI_CMD_READ_LINK_SUPERVISION_TIMEOUT, 146 11, 0x01, sizeof(hci_read_link_supervision_timeout_cp) }, 147 { HCI_CMD_READ_NUM_SUPPORTED_IAC, 148 11, 0x04, 0 }, 149 { HCI_CMD_READ_IAC_LAP, 150 11, 0x08, 0 }, 151 { HCI_CMD_READ_PAGE_SCAN_PERIOD, 152 11, 0x20, 0 }, 153 { HCI_CMD_READ_PAGE_SCAN, 154 11, 0x80, 0 }, 155 { HCI_CMD_READ_INQUIRY_SCAN_TYPE, 156 12, 0x10, 0 }, 157 { HCI_CMD_READ_INQUIRY_MODE, 158 12, 0x40, 0 }, 159 { HCI_CMD_READ_PAGE_SCAN_TYPE, 160 13, 0x01, 0 }, 161 { HCI_CMD_READ_AFH_ASSESSMENT, 162 13, 0x04, 0 }, 163 { HCI_CMD_READ_LOCAL_VER, 164 14, 0x08, 0 }, 165 { HCI_CMD_READ_LOCAL_COMMANDS, 166 14, 0x10, 0 }, 167 { HCI_CMD_READ_LOCAL_FEATURES, 168 14, 0x20, 0 }, 169 { HCI_CMD_READ_LOCAL_EXTENDED_FEATURES, 170 14, 0x40, sizeof(hci_read_local_extended_features_cp) }, 171 { HCI_CMD_READ_BUFFER_SIZE, 172 14, 0x80, 0 }, 173 { HCI_CMD_READ_COUNTRY_CODE, 174 15, 0x01, 0 }, 175 { HCI_CMD_READ_BDADDR, 176 15, 0x02, 0 }, 177 { HCI_CMD_READ_FAILED_CONTACT_CNTR, 178 15, 0x04, sizeof(hci_read_failed_contact_cntr_cp) }, 179 { HCI_CMD_READ_LINK_QUALITY, 180 15, 0x10, sizeof(hci_read_link_quality_cp) }, 181 { HCI_CMD_READ_RSSI, 182 15, 0x20, sizeof(hci_read_rssi_cp) }, 183 { HCI_CMD_READ_AFH_CHANNEL_MAP, 184 15, 0x40, sizeof(hci_read_afh_channel_map_cp) }, 185 { HCI_CMD_READ_CLOCK, 186 15, 0x80, sizeof(hci_read_clock_cp) }, 187 { HCI_CMD_READ_LOOPBACK_MODE, 188 16, 0x01, 0 }, 189 { HCI_CMD_READ_EXTENDED_INQUIRY_RSP, 190 17, 0x01, 0 }, 191 { HCI_CMD_READ_SIMPLE_PAIRING_MODE, 192 17, 0x20, 0 }, 193 { HCI_CMD_READ_INQUIRY_RSP_XMIT_POWER, 194 18, 0x01, 0 }, 195 { HCI_CMD_READ_DEFAULT_ERRDATA_REPORTING, 196 18, 0x04, 0 }, 197 }; 198 199 /* 200 * supply a basic device send/recv policy 201 */ 202 static int 203 hci_device_cb(kauth_cred_t cred, kauth_action_t action, void *cookie, 204 void *arg0, void *arg1, void *arg2, void *arg3) 205 { 206 int i, result; 207 208 result = KAUTH_RESULT_DEFER; 209 210 switch (action) { 211 case KAUTH_DEVICE_BLUETOOTH_SEND: { 212 struct hci_unit *unit = (struct hci_unit *)arg0; 213 hci_cmd_hdr_t *hdr = (hci_cmd_hdr_t *)arg1; 214 215 /* 216 * Allow sending unprivileged commands if the packet size 217 * is correct and the unit claims to support it 218 */ 219 220 if (hdr->type != HCI_CMD_PKT) 221 break; 222 223 for (i = 0; i < __arraycount(hci_cmds); i++) { 224 if (hdr->opcode == hci_cmds[i].opcode 225 && hdr->length == hci_cmds[i].length 226 && (unit->hci_cmds[hci_cmds[i].offs] & hci_cmds[i].mask)) { 227 result = KAUTH_RESULT_ALLOW; 228 break; 229 } 230 } 231 232 break; 233 } 234 235 case KAUTH_DEVICE_BLUETOOTH_RECV: 236 switch((uint8_t)(uintptr_t)arg0) { 237 case HCI_CMD_PKT: { 238 uint16_t opcode = (uint16_t)(uintptr_t)arg1; 239 240 /* 241 * Allow to see any unprivileged command packet 242 */ 243 244 for (i = 0; i < __arraycount(hci_cmds); i++) { 245 if (opcode == hci_cmds[i].opcode) { 246 result = KAUTH_RESULT_ALLOW; 247 break; 248 } 249 } 250 251 break; 252 } 253 254 case HCI_EVENT_PKT: { 255 uint8_t event = (uint8_t)(uintptr_t)arg1; 256 257 /* 258 * Allow to receive most events 259 */ 260 261 switch (event) { 262 case HCI_EVENT_RETURN_LINK_KEYS: 263 case HCI_EVENT_LINK_KEY_NOTIFICATION: 264 case HCI_EVENT_USER_CONFIRM_REQ: 265 case HCI_EVENT_USER_PASSKEY_NOTIFICATION: 266 case HCI_EVENT_VENDOR: 267 break; 268 269 default: 270 result = KAUTH_RESULT_ALLOW; 271 break; 272 } 273 274 break; 275 } 276 277 case HCI_ACL_DATA_PKT: 278 case HCI_SCO_DATA_PKT: { 279 /* uint16_t handle = (uint16_t)(uintptr_t)arg1; */ 280 /* 281 * don't normally allow receiving data packets 282 */ 283 break; 284 } 285 286 default: 287 break; 288 } 289 290 break; 291 292 default: 293 break; 294 } 295 296 return result; 297 } 298 299 /* 300 * HCI protocol init routine, 301 * - set up a kauth listener to provide basic packet access policy 302 */ 303 void 304 hci_init(void) 305 { 306 307 if (kauth_listen_scope(KAUTH_SCOPE_DEVICE, hci_device_cb, NULL) == NULL) 308 panic("Bluetooth HCI: cannot listen on device scope"); 309 } 310 311 /* 312 * When command packet reaches the device, we can drop 313 * it from the socket buffer (called from hci_output_acl) 314 */ 315 void 316 hci_drop(void *arg) 317 { 318 struct socket *so = arg; 319 320 sbdroprecord(&so->so_snd); 321 sowwakeup(so); 322 } 323 324 /* 325 * HCI socket is going away and has some pending packets. We let them 326 * go by design, but remove the context pointer as it will be invalid 327 * and we no longer need to be notified. 328 */ 329 static void 330 hci_cmdwait_flush(struct socket *so) 331 { 332 struct hci_unit *unit; 333 struct socket *ctx; 334 struct mbuf *m; 335 336 DPRINTF("flushing %p\n", so); 337 338 SIMPLEQ_FOREACH(unit, &hci_unit_list, hci_next) { 339 m = MBUFQ_FIRST(&unit->hci_cmdwait); 340 while (m != NULL) { 341 ctx = M_GETCTX(m, struct socket *); 342 if (ctx == so) 343 M_SETCTX(m, NULL); 344 345 m = MBUFQ_NEXT(m); 346 } 347 } 348 } 349 350 /* 351 * HCI send packet 352 * This came from userland, so check it out. 353 */ 354 static int 355 hci_send(struct hci_pcb *pcb, struct mbuf *m, bdaddr_t *addr) 356 { 357 struct hci_unit *unit; 358 struct mbuf *m0; 359 hci_cmd_hdr_t hdr; 360 int err; 361 362 KASSERT(m != NULL); 363 KASSERT(addr != NULL); 364 365 /* wants at least a header to start with */ 366 if (m->m_pkthdr.len < sizeof(hdr)) { 367 err = EMSGSIZE; 368 goto bad; 369 } 370 m_copydata(m, 0, sizeof(hdr), &hdr); 371 hdr.opcode = le16toh(hdr.opcode); 372 373 /* only allows CMD packets to be sent */ 374 if (hdr.type != HCI_CMD_PKT) { 375 err = EINVAL; 376 goto bad; 377 } 378 379 /* validates packet length */ 380 if (m->m_pkthdr.len != sizeof(hdr) + hdr.length) { 381 err = EMSGSIZE; 382 goto bad; 383 } 384 385 /* finds destination */ 386 unit = hci_unit_lookup(addr); 387 if (unit == NULL) { 388 err = ENETDOWN; 389 goto bad; 390 } 391 392 /* security checks for unprivileged users */ 393 if (pcb->hp_cred != NULL 394 && kauth_authorize_device(pcb->hp_cred, 395 KAUTH_DEVICE_BLUETOOTH_SEND, 396 unit, &hdr, NULL, NULL) != 0) { 397 err = EPERM; 398 goto bad; 399 } 400 401 /* makess a copy for precious to keep */ 402 m0 = m_copypacket(m, M_DONTWAIT); 403 if (m0 == NULL) { 404 err = ENOMEM; 405 goto bad; 406 } 407 sbappendrecord(&pcb->hp_socket->so_snd, m0); 408 M_SETCTX(m, pcb->hp_socket); /* enable drop callback */ 409 410 DPRINTFN(2, "(%s) opcode (%03x|%04x)\n", device_xname(unit->hci_dev), 411 HCI_OGF(hdr.opcode), HCI_OCF(hdr.opcode)); 412 413 /* Sendss it */ 414 if (unit->hci_num_cmd_pkts == 0) 415 MBUFQ_ENQUEUE(&unit->hci_cmdwait, m); 416 else 417 hci_output_cmd(unit, m); 418 419 return 0; 420 421 bad: 422 DPRINTF("packet (%d bytes) not sent (error %d)\n", 423 m->m_pkthdr.len, err); 424 if (m) m_freem(m); 425 return err; 426 } 427 428 /* 429 * User Request. 430 * up is socket 431 * m is either 432 * optional mbuf chain containing message 433 * ioctl command (PRU_CONTROL) 434 * nam is either 435 * optional mbuf chain containing an address 436 * ioctl data (PRU_CONTROL) 437 * optionally, protocol number (PRU_ATTACH) 438 * ctl is optional mbuf chain containing socket options 439 * l is pointer to process requesting action (if any) 440 * 441 * we are responsible for disposing of m and ctl if 442 * they are mbuf chains 443 */ 444 int 445 hci_usrreq(struct socket *up, int req, struct mbuf *m, 446 struct mbuf *nam, struct mbuf *ctl, struct lwp *l) 447 { 448 struct hci_pcb *pcb = (struct hci_pcb *)up->so_pcb; 449 struct sockaddr_bt *sa; 450 int err = 0; 451 452 DPRINTFN(2, "%s\n", prurequests[req]); 453 454 switch(req) { 455 case PRU_CONTROL: 456 mutex_enter(bt_lock); 457 err = hci_ioctl((unsigned long)m, (void *)nam, l); 458 mutex_exit(bt_lock); 459 return err; 460 461 case PRU_PURGEIF: 462 return EOPNOTSUPP; 463 464 case PRU_ATTACH: 465 if (up->so_lock == NULL) { 466 mutex_obj_hold(bt_lock); 467 up->so_lock = bt_lock; 468 solock(up); 469 } 470 KASSERT(solocked(up)); 471 if (pcb) 472 return EINVAL; 473 err = soreserve(up, hci_sendspace, hci_recvspace); 474 if (err) 475 return err; 476 477 pcb = malloc(sizeof(struct hci_pcb), M_PCB, M_NOWAIT | M_ZERO); 478 if (pcb == NULL) 479 return ENOMEM; 480 481 up->so_pcb = pcb; 482 pcb->hp_socket = up; 483 484 if (l != NULL) 485 pcb->hp_cred = kauth_cred_dup(l->l_cred); 486 487 /* 488 * Set default user filter. By default, socket only passes 489 * Command_Complete and Command_Status Events. 490 */ 491 hci_filter_set(HCI_EVENT_COMMAND_COMPL, &pcb->hp_efilter); 492 hci_filter_set(HCI_EVENT_COMMAND_STATUS, &pcb->hp_efilter); 493 hci_filter_set(HCI_EVENT_PKT, &pcb->hp_pfilter); 494 495 LIST_INSERT_HEAD(&hci_pcb, pcb, hp_next); 496 497 return 0; 498 } 499 500 /* anything after here *requires* a pcb */ 501 if (pcb == NULL) { 502 err = EINVAL; 503 goto release; 504 } 505 506 switch(req) { 507 case PRU_DISCONNECT: 508 bdaddr_copy(&pcb->hp_raddr, BDADDR_ANY); 509 510 /* XXX we cannot call soisdisconnected() here, as it sets 511 * SS_CANTRCVMORE and SS_CANTSENDMORE. The problem being, 512 * that soisconnected() does not clear these and if you 513 * try to reconnect this socket (which is permitted) you 514 * get a broken pipe when you try to write any data. 515 */ 516 up->so_state &= ~SS_ISCONNECTED; 517 break; 518 519 case PRU_ABORT: 520 soisdisconnected(up); 521 /* fall through to */ 522 case PRU_DETACH: 523 if (up->so_snd.sb_mb != NULL) 524 hci_cmdwait_flush(up); 525 526 if (pcb->hp_cred != NULL) 527 kauth_cred_free(pcb->hp_cred); 528 529 up->so_pcb = NULL; 530 LIST_REMOVE(pcb, hp_next); 531 free(pcb, M_PCB); 532 return 0; 533 534 case PRU_BIND: 535 KASSERT(nam != NULL); 536 sa = mtod(nam, struct sockaddr_bt *); 537 538 if (sa->bt_len != sizeof(struct sockaddr_bt)) 539 return EINVAL; 540 541 if (sa->bt_family != AF_BLUETOOTH) 542 return EAFNOSUPPORT; 543 544 bdaddr_copy(&pcb->hp_laddr, &sa->bt_bdaddr); 545 546 if (bdaddr_any(&sa->bt_bdaddr)) 547 pcb->hp_flags |= HCI_PROMISCUOUS; 548 else 549 pcb->hp_flags &= ~HCI_PROMISCUOUS; 550 551 return 0; 552 553 case PRU_CONNECT: 554 KASSERT(nam != NULL); 555 sa = mtod(nam, struct sockaddr_bt *); 556 557 if (sa->bt_len != sizeof(struct sockaddr_bt)) 558 return EINVAL; 559 560 if (sa->bt_family != AF_BLUETOOTH) 561 return EAFNOSUPPORT; 562 563 if (hci_unit_lookup(&sa->bt_bdaddr) == NULL) 564 return EADDRNOTAVAIL; 565 566 bdaddr_copy(&pcb->hp_raddr, &sa->bt_bdaddr); 567 soisconnected(up); 568 return 0; 569 570 case PRU_PEERADDR: 571 KASSERT(nam != NULL); 572 sa = mtod(nam, struct sockaddr_bt *); 573 574 memset(sa, 0, sizeof(struct sockaddr_bt)); 575 nam->m_len = 576 sa->bt_len = sizeof(struct sockaddr_bt); 577 sa->bt_family = AF_BLUETOOTH; 578 bdaddr_copy(&sa->bt_bdaddr, &pcb->hp_raddr); 579 return 0; 580 581 case PRU_SOCKADDR: 582 KASSERT(nam != NULL); 583 sa = mtod(nam, struct sockaddr_bt *); 584 585 memset(sa, 0, sizeof(struct sockaddr_bt)); 586 nam->m_len = 587 sa->bt_len = sizeof(struct sockaddr_bt); 588 sa->bt_family = AF_BLUETOOTH; 589 bdaddr_copy(&sa->bt_bdaddr, &pcb->hp_laddr); 590 return 0; 591 592 case PRU_SHUTDOWN: 593 socantsendmore(up); 594 break; 595 596 case PRU_SEND: 597 sa = NULL; 598 if (nam) { 599 sa = mtod(nam, struct sockaddr_bt *); 600 601 if (sa->bt_len != sizeof(struct sockaddr_bt)) { 602 err = EINVAL; 603 goto release; 604 } 605 606 if (sa->bt_family != AF_BLUETOOTH) { 607 err = EAFNOSUPPORT; 608 goto release; 609 } 610 } 611 612 if (ctl) /* have no use for this */ 613 m_freem(ctl); 614 615 return hci_send(pcb, m, (sa ? &sa->bt_bdaddr : &pcb->hp_raddr)); 616 617 case PRU_SENSE: 618 return 0; /* (no sense - Doh!) */ 619 620 case PRU_RCVD: 621 case PRU_RCVOOB: 622 return EOPNOTSUPP; /* (no release) */ 623 624 case PRU_ACCEPT: 625 case PRU_CONNECT2: 626 case PRU_LISTEN: 627 case PRU_SENDOOB: 628 case PRU_FASTTIMO: 629 case PRU_SLOWTIMO: 630 case PRU_PROTORCV: 631 case PRU_PROTOSEND: 632 err = EOPNOTSUPP; 633 break; 634 635 default: 636 UNKNOWN(req); 637 err = EOPNOTSUPP; 638 break; 639 } 640 641 release: 642 if (m) 643 m_freem(m); 644 if (ctl) 645 m_freem(ctl); 646 return err; 647 } 648 649 /* 650 * get/set socket options 651 */ 652 int 653 hci_ctloutput(int req, struct socket *so, struct sockopt *sopt) 654 { 655 struct hci_pcb *pcb = (struct hci_pcb *)so->so_pcb; 656 int optval, err = 0; 657 658 DPRINTFN(2, "req %s\n", prcorequests[req]); 659 660 if (pcb == NULL) 661 return EINVAL; 662 663 if (sopt->sopt_level != BTPROTO_HCI) 664 return ENOPROTOOPT; 665 666 switch(req) { 667 case PRCO_GETOPT: 668 switch (sopt->sopt_name) { 669 case SO_HCI_EVT_FILTER: 670 err = sockopt_set(sopt, &pcb->hp_efilter, 671 sizeof(struct hci_filter)); 672 673 break; 674 675 case SO_HCI_PKT_FILTER: 676 err = sockopt_set(sopt, &pcb->hp_pfilter, 677 sizeof(struct hci_filter)); 678 679 break; 680 681 case SO_HCI_DIRECTION: 682 err = sockopt_setint(sopt, 683 (pcb->hp_flags & HCI_DIRECTION ? 1 : 0)); 684 685 break; 686 687 default: 688 err = ENOPROTOOPT; 689 break; 690 } 691 break; 692 693 case PRCO_SETOPT: 694 switch (sopt->sopt_name) { 695 case SO_HCI_EVT_FILTER: /* set event filter */ 696 err = sockopt_get(sopt, &pcb->hp_efilter, 697 sizeof(pcb->hp_efilter)); 698 699 break; 700 701 case SO_HCI_PKT_FILTER: /* set packet filter */ 702 err = sockopt_get(sopt, &pcb->hp_pfilter, 703 sizeof(pcb->hp_pfilter)); 704 705 break; 706 707 case SO_HCI_DIRECTION: /* request direction ctl messages */ 708 err = sockopt_getint(sopt, &optval); 709 if (err) 710 break; 711 712 if (optval) 713 pcb->hp_flags |= HCI_DIRECTION; 714 else 715 pcb->hp_flags &= ~HCI_DIRECTION; 716 break; 717 718 default: 719 err = ENOPROTOOPT; 720 break; 721 } 722 break; 723 724 default: 725 err = ENOPROTOOPT; 726 break; 727 } 728 729 return err; 730 } 731 732 /* 733 * HCI mbuf tap routine 734 * 735 * copy packets to any raw HCI sockets that wish (and are 736 * permitted) to see them 737 */ 738 void 739 hci_mtap(struct mbuf *m, struct hci_unit *unit) 740 { 741 struct hci_pcb *pcb; 742 struct mbuf *m0, *ctlmsg, **ctl; 743 struct sockaddr_bt sa; 744 uint8_t type; 745 uint8_t event; 746 uint16_t arg1; 747 748 KASSERT(m->m_len >= sizeof(type)); 749 750 type = *mtod(m, uint8_t *); 751 752 memset(&sa, 0, sizeof(sa)); 753 sa.bt_len = sizeof(struct sockaddr_bt); 754 sa.bt_family = AF_BLUETOOTH; 755 bdaddr_copy(&sa.bt_bdaddr, &unit->hci_bdaddr); 756 757 LIST_FOREACH(pcb, &hci_pcb, hp_next) { 758 /* 759 * filter according to source address 760 */ 761 if ((pcb->hp_flags & HCI_PROMISCUOUS) == 0 762 && bdaddr_same(&pcb->hp_laddr, &sa.bt_bdaddr) == 0) 763 continue; 764 765 /* 766 * filter according to packet type filter 767 */ 768 if (hci_filter_test(type, &pcb->hp_pfilter) == 0) 769 continue; 770 771 /* 772 * filter according to event/security filters 773 */ 774 switch(type) { 775 case HCI_EVENT_PKT: 776 KASSERT(m->m_len >= sizeof(hci_event_hdr_t)); 777 778 event = mtod(m, hci_event_hdr_t *)->event; 779 780 if (hci_filter_test(event, &pcb->hp_efilter) == 0) 781 continue; 782 783 arg1 = event; 784 break; 785 786 case HCI_CMD_PKT: 787 KASSERT(m->m_len >= sizeof(hci_cmd_hdr_t)); 788 arg1 = le16toh(mtod(m, hci_cmd_hdr_t *)->opcode); 789 break; 790 791 case HCI_ACL_DATA_PKT: 792 KASSERT(m->m_len >= sizeof(hci_acldata_hdr_t)); 793 arg1 = le16toh(mtod(m, hci_acldata_hdr_t *)->con_handle); 794 arg1 = HCI_CON_HANDLE(arg1); 795 break; 796 797 case HCI_SCO_DATA_PKT: 798 KASSERT(m->m_len >= sizeof(hci_scodata_hdr_t)); 799 arg1 = le16toh(mtod(m, hci_scodata_hdr_t *)->con_handle); 800 arg1 = HCI_CON_HANDLE(arg1); 801 break; 802 803 default: 804 arg1 = 0; 805 break; 806 } 807 808 if (pcb->hp_cred != NULL 809 && kauth_authorize_device(pcb->hp_cred, 810 KAUTH_DEVICE_BLUETOOTH_RECV, 811 KAUTH_ARG(type), KAUTH_ARG(arg1), NULL, NULL) != 0) 812 continue; 813 814 /* 815 * create control messages 816 */ 817 ctlmsg = NULL; 818 ctl = &ctlmsg; 819 if (pcb->hp_flags & HCI_DIRECTION) { 820 int dir = m->m_flags & M_LINK0 ? 1 : 0; 821 822 *ctl = sbcreatecontrol(&dir, sizeof(dir), 823 SCM_HCI_DIRECTION, BTPROTO_HCI); 824 825 if (*ctl != NULL) 826 ctl = &((*ctl)->m_next); 827 } 828 829 /* 830 * copy to socket 831 */ 832 m0 = m_copypacket(m, M_DONTWAIT); 833 if (m0 && sbappendaddr(&pcb->hp_socket->so_rcv, 834 (struct sockaddr *)&sa, m0, ctlmsg)) { 835 sorwakeup(pcb->hp_socket); 836 } else { 837 m_freem(ctlmsg); 838 m_freem(m0); 839 } 840 } 841 } 842