1 /* $NetBSD: hci_socket.c,v 1.1 2006/06/19 15:44:45 gdamore 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.1 2006/06/19 15:44:45 gdamore Exp $"); 35 36 #include "opt_bluetooth.h" 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 unsigned int hp_flags; /* flags */ 68 bdaddr_t hp_laddr; /* local address */ 69 bdaddr_t hp_raddr; /* remote address */ 70 struct hci_filter hp_efilter; /* user event filter */ 71 struct hci_filter hp_pfilter; /* user packet filter */ 72 LIST_ENTRY(hci_pcb) hp_next; /* next HCI pcb */ 73 }; 74 75 /* hp_flags */ 76 #define HCI_PRIVILEGED (1<<0) /* no security filter for root */ 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 /* 87 * Security filter routines 88 * The security mask is an bit array. 89 * If the bit is set, the opcode/event is permitted. 90 * I only allocate the security mask if needed, and give it back 91 * if requested as its quite a chunk. This could no doubt be made 92 * somewhat bit more memory efficient given that most OGF/OCF's are 93 * not used, but this way is quick. 94 */ 95 #define HCI_OPCODE_MASK_SIZE 0x800 96 97 uint32_t *hci_event_mask = NULL; 98 uint32_t *hci_opcode_mask = NULL; 99 100 static __inline int 101 hci_security_check_opcode(uint16_t opcode) 102 { 103 104 return (hci_opcode_mask[opcode >> 5] & (1 << (opcode & 0x1f))); 105 } 106 107 static __inline int 108 hci_security_check_event(uint8_t event) 109 { 110 111 return (hci_event_mask[event >> 5] & (1 << (event & 0x1f))); 112 } 113 114 static __inline void 115 hci_security_set_opcode(uint16_t opcode) 116 { 117 118 hci_opcode_mask[opcode >> 5] |= (1 << (opcode & 0x1f)); 119 } 120 121 static __inline void 122 hci_security_clr_event(uint8_t event) 123 { 124 125 hci_event_mask[event >> 5] &= ~(1 << (event & 0x1f)); 126 } 127 128 static int 129 hci_security_init(void) 130 { 131 132 if (hci_event_mask) 133 return 0; 134 135 // XXX could wait? 136 hci_event_mask = malloc(HCI_EVENT_MASK_SIZE + HCI_OPCODE_MASK_SIZE, 137 M_BLUETOOTH, M_NOWAIT | M_ZERO); 138 if (hci_event_mask == NULL) { 139 DPRINTF("no memory\n"); 140 return ENOMEM; 141 } 142 143 hci_opcode_mask = hci_event_mask + HCI_EVENT_MASK_SIZE; 144 145 /* Events */ 146 /* enable all but a few critical events */ 147 memset(hci_event_mask, 0xff, 148 HCI_EVENT_MASK_SIZE * sizeof(*hci_event_mask)); 149 hci_security_clr_event(HCI_EVENT_RETURN_LINK_KEYS); 150 hci_security_clr_event(HCI_EVENT_LINK_KEY_NOTIFICATION); 151 hci_security_clr_event(HCI_EVENT_VENDOR); 152 153 /* Commands - Link control */ 154 hci_security_set_opcode(HCI_CMD_INQUIRY); 155 hci_security_set_opcode(HCI_CMD_REMOTE_NAME_REQ); 156 hci_security_set_opcode(HCI_CMD_READ_REMOTE_FEATURES); 157 hci_security_set_opcode(HCI_CMD_READ_REMOTE_EXTENDED_FEATURES); 158 hci_security_set_opcode(HCI_CMD_READ_REMOTE_VER_INFO); 159 hci_security_set_opcode(HCI_CMD_READ_CLOCK_OFFSET); 160 hci_security_set_opcode(HCI_CMD_READ_LMP_HANDLE); 161 162 /* Commands - Link policy */ 163 hci_security_set_opcode(HCI_CMD_ROLE_DISCOVERY); 164 hci_security_set_opcode(HCI_CMD_READ_LINK_POLICY_SETTINGS); 165 hci_security_set_opcode(HCI_CMD_READ_DEFAULT_LINK_POLICY_SETTINGS); 166 167 /* Commands - Host controller and baseband */ 168 hci_security_set_opcode(HCI_CMD_READ_PIN_TYPE); 169 hci_security_set_opcode(HCI_CMD_READ_LOCAL_NAME); 170 hci_security_set_opcode(HCI_CMD_READ_CON_ACCEPT_TIMEOUT); 171 hci_security_set_opcode(HCI_CMD_READ_PAGE_TIMEOUT); 172 hci_security_set_opcode(HCI_CMD_READ_SCAN_ENABLE); 173 hci_security_set_opcode(HCI_CMD_READ_PAGE_SCAN_ACTIVITY); 174 hci_security_set_opcode(HCI_CMD_READ_INQUIRY_SCAN_ACTIVITY); 175 hci_security_set_opcode(HCI_CMD_READ_AUTH_ENABLE); 176 hci_security_set_opcode(HCI_CMD_READ_ENCRYPTION_MODE); 177 hci_security_set_opcode(HCI_CMD_READ_UNIT_CLASS); 178 hci_security_set_opcode(HCI_CMD_READ_VOICE_SETTING); 179 hci_security_set_opcode(HCI_CMD_READ_AUTO_FLUSH_TIMEOUT); 180 hci_security_set_opcode(HCI_CMD_READ_NUM_BROADCAST_RETRANS); 181 hci_security_set_opcode(HCI_CMD_READ_HOLD_MODE_ACTIVITY); 182 hci_security_set_opcode(HCI_CMD_READ_XMIT_LEVEL); 183 hci_security_set_opcode(HCI_CMD_READ_SCO_FLOW_CONTROL); 184 hci_security_set_opcode(HCI_CMD_READ_LINK_SUPERVISION_TIMEOUT); 185 hci_security_set_opcode(HCI_CMD_READ_NUM_SUPPORTED_IAC); 186 hci_security_set_opcode(HCI_CMD_READ_IAC_LAP); 187 hci_security_set_opcode(HCI_CMD_READ_PAGE_SCAN_PERIOD); 188 hci_security_set_opcode(HCI_CMD_READ_PAGE_SCAN); 189 hci_security_set_opcode(HCI_CMD_READ_INQUIRY_SCAN_TYPE); 190 hci_security_set_opcode(HCI_CMD_READ_INQUIRY_MODE); 191 hci_security_set_opcode(HCI_CMD_READ_PAGE_SCAN_TYPE); 192 hci_security_set_opcode(HCI_CMD_READ_AFH_ASSESSMENT); 193 194 /* Commands - Informational */ 195 hci_security_set_opcode(HCI_CMD_READ_LOCAL_VER); 196 hci_security_set_opcode(HCI_CMD_READ_LOCAL_COMMANDS); 197 hci_security_set_opcode(HCI_CMD_READ_LOCAL_FEATURES); 198 hci_security_set_opcode(HCI_CMD_READ_LOCAL_EXTENDED_FEATURES); 199 hci_security_set_opcode(HCI_CMD_READ_BUFFER_SIZE); 200 hci_security_set_opcode(HCI_CMD_READ_COUNTRY_CODE); 201 hci_security_set_opcode(HCI_CMD_READ_BDADDR); 202 203 /* Commands - Status */ 204 hci_security_set_opcode(HCI_CMD_READ_FAILED_CONTACT_CNTR); 205 hci_security_set_opcode(HCI_CMD_READ_LINK_QUALITY); 206 hci_security_set_opcode(HCI_CMD_READ_RSSI); 207 hci_security_set_opcode(HCI_CMD_READ_AFH_CHANNEL_MAP); 208 hci_security_set_opcode(HCI_CMD_READ_CLOCK); 209 210 /* Commands - Testing */ 211 hci_security_set_opcode(HCI_CMD_READ_LOOPBACK_MODE); 212 213 return 0; 214 } 215 216 /* 217 * When command packet reaches the device, we can drop 218 * it from the socket buffer (called from hci_output_acl) 219 */ 220 void 221 hci_drop(void *arg) 222 { 223 struct socket *so = arg; 224 225 sbdroprecord(&so->so_snd); 226 sowwakeup(so); 227 } 228 229 /* 230 * HCI socket is going away and has some pending packets. We let them 231 * go by design, but remove the context pointer as it will be invalid 232 * and we no longer need to be notified. 233 */ 234 static void 235 hci_cmdwait_flush(struct socket *so) 236 { 237 struct hci_unit *unit; 238 struct socket *ctx; 239 struct mbuf *m; 240 241 DPRINTF("flushing %p\n", so); 242 243 SIMPLEQ_FOREACH(unit, &hci_unit_list, hci_next) { 244 m = MBUFQ_FIRST(&unit->hci_cmdwait); 245 while (m != NULL) { 246 ctx = M_GETCTX(m, struct socket *); 247 if (ctx == so) 248 M_SETCTX(m, NULL); 249 250 m = MBUFQ_NEXT(m); 251 } 252 } 253 } 254 255 /* 256 * HCI send packet 257 * This came from userland, so check it out. 258 */ 259 static int 260 hci_send(struct hci_pcb *pcb, struct mbuf *m, bdaddr_t *addr) 261 { 262 struct hci_unit *unit; 263 struct mbuf *m0; 264 hci_cmd_hdr_t hdr; 265 int err; 266 267 KASSERT(m); 268 KASSERT(addr); 269 270 /* wants at least a header to start with */ 271 if (m->m_pkthdr.len < sizeof(hdr)) { 272 err = EMSGSIZE; 273 goto bad; 274 } 275 m_copydata(m, 0, sizeof(hdr), &hdr); 276 277 /* only allows CMD packets to be sent */ 278 if (hdr.type != HCI_CMD_PKT) { 279 err = EINVAL; 280 goto bad; 281 } 282 283 /* validates packet length */ 284 if (m->m_pkthdr.len != sizeof(hdr) + hdr.length) { 285 err = EMSGSIZE; 286 goto bad; 287 } 288 289 /* security checks for unprivileged users */ 290 if ((pcb->hp_flags & HCI_PRIVILEGED) == 0 291 && (hci_security_check_opcode(le16toh(hdr.opcode)) == 0)) { 292 err = EPERM; 293 goto bad; 294 } 295 296 /* finds destination */ 297 unit = hci_unit_lookup(addr); 298 if (unit == NULL) { 299 err = ENETDOWN; 300 goto bad; 301 } 302 303 /* makess a copy for precious to keep */ 304 m0 = m_copypacket(m, M_DONTWAIT); 305 if (m0 == NULL) { 306 err = ENOMEM; 307 goto bad; 308 } 309 sbappendrecord(&pcb->hp_socket->so_snd, m0); 310 M_SETCTX(m, pcb->hp_socket); /* enable drop callback */ 311 312 DPRINTFN(2, "(%s) opcode (%03x|%04x)\n", unit->hci_devname, 313 HCI_OGF(le16toh(hdr.opcode)), HCI_OCF(le16toh(hdr.opcode))); 314 315 /* Sendss it */ 316 if (unit->hci_num_cmd_pkts == 0) 317 MBUFQ_ENQUEUE(&unit->hci_cmdwait, m); 318 else 319 hci_output_cmd(unit, m); 320 321 return 0; 322 323 bad: 324 DPRINTF("packet (%d bytes) not sent (error %d)\n", 325 m->m_pkthdr.len, err); 326 if (m) m_freem(m); 327 return err; 328 } 329 330 /* 331 * User Request. 332 * up is socket 333 * m is either 334 * optional mbuf chain containing message 335 * ioctl command (PRU_CONTROL) 336 * nam is either 337 * optional mbuf chain containing an address 338 * ioctl data (PRU_CONTROL) 339 * optionally, protocol number (PRU_ATTACH) 340 * ctl is optional mbuf chain containing socket options 341 * l is pointer to process requesting action (if any) 342 * 343 * we are responsible for disposing of m and ctl if 344 * they are mbuf chains 345 */ 346 int 347 hci_usrreq(struct socket *up, int req, struct mbuf *m, 348 struct mbuf *nam, struct mbuf *ctl, struct lwp *l) 349 { 350 struct hci_pcb *pcb = (struct hci_pcb *)up->so_pcb; 351 struct sockaddr_bt *sa; 352 struct proc *p; 353 int err = 0, flags; 354 355 DPRINTFN(2, "%s\n", prurequests[req]); 356 357 p = (l == NULL) ? NULL : l->l_proc; 358 359 switch(req) { 360 case PRU_CONTROL: 361 return hci_ioctl((unsigned long)m, (void *)nam, p); 362 363 case PRU_PURGEIF: 364 return EOPNOTSUPP; 365 366 case PRU_ATTACH: 367 if (pcb) 368 return EINVAL; 369 370 flags = 0; 371 if (p != NULL && kauth_authorize_generic(p->p_cred, 372 KAUTH_GENERIC_ISSUSER, 373 &p->p_acflag)) { 374 err = hci_security_init(); 375 if (err) 376 return err; 377 } else { 378 flags = HCI_PRIVILEGED; 379 } 380 381 err = soreserve(up, hci_sendspace, hci_recvspace); 382 if (err) 383 return err; 384 385 pcb = malloc(sizeof(struct hci_pcb), M_PCB, M_NOWAIT | M_ZERO); 386 if (pcb == NULL) 387 return ENOMEM; 388 389 up->so_pcb = pcb; 390 pcb->hp_socket = up; 391 pcb->hp_flags = flags; 392 393 /* 394 * Set default user filter. By default, socket only passes 395 * Command_Complete and Command_Status Events. 396 */ 397 hci_filter_set(HCI_EVENT_COMMAND_COMPL, &pcb->hp_efilter); 398 hci_filter_set(HCI_EVENT_COMMAND_STATUS, &pcb->hp_efilter); 399 hci_filter_set(HCI_EVENT_PKT, &pcb->hp_pfilter); 400 401 LIST_INSERT_HEAD(&hci_pcb, pcb, hp_next); 402 403 return 0; 404 } 405 406 /* anything after here *requires* a pcb */ 407 if (pcb == NULL) { 408 err = EINVAL; 409 goto release; 410 } 411 412 switch(req) { 413 case PRU_DISCONNECT: 414 bdaddr_copy(&pcb->hp_raddr, BDADDR_ANY); 415 416 /* XXX we cannot call soisdisconnected() here, as it sets 417 * SS_CANTRCVMORE and SS_CANTSENDMORE. The problem being, 418 * that soisconnected() does not clear these and if you 419 * try to reconnect this socket (which is permitted) you 420 * get a broken pipe when you try to write any data. 421 */ 422 up->so_state &= ~SS_ISCONNECTED; 423 break; 424 425 case PRU_ABORT: 426 soisdisconnected(up); 427 /* fall through to */ 428 case PRU_DETACH: 429 if (up->so_snd.sb_mb != NULL) 430 hci_cmdwait_flush(up); 431 432 up->so_pcb = NULL; 433 LIST_REMOVE(pcb, hp_next); 434 free(pcb, M_PCB); 435 return 0; 436 437 case PRU_BIND: 438 KASSERT(nam); 439 sa = mtod(nam, struct sockaddr_bt *); 440 441 if (sa->bt_len != sizeof(struct sockaddr_bt)) 442 return EINVAL; 443 444 if (sa->bt_family != AF_BLUETOOTH) 445 return EAFNOSUPPORT; 446 447 bdaddr_copy(&pcb->hp_laddr, &sa->bt_bdaddr); 448 449 if (bdaddr_any(&sa->bt_bdaddr)) 450 pcb->hp_flags |= HCI_PROMISCUOUS; 451 else 452 pcb->hp_flags &= ~HCI_PROMISCUOUS; 453 454 return 0; 455 456 case PRU_CONNECT: 457 KASSERT(nam); 458 sa = mtod(nam, struct sockaddr_bt *); 459 460 if (sa->bt_len != sizeof(struct sockaddr_bt)) 461 return EINVAL; 462 463 if (sa->bt_family != AF_BLUETOOTH) 464 return EAFNOSUPPORT; 465 466 if (hci_unit_lookup(&sa->bt_bdaddr) == NULL) 467 return EADDRNOTAVAIL; 468 469 bdaddr_copy(&pcb->hp_raddr, &sa->bt_bdaddr); 470 soisconnected(up); 471 return 0; 472 473 case PRU_PEERADDR: 474 KASSERT(nam); 475 sa = mtod(nam, struct sockaddr_bt *); 476 477 memset(sa, 0, sizeof(struct sockaddr_bt)); 478 nam->m_len = 479 sa->bt_len = sizeof(struct sockaddr_bt); 480 sa->bt_family = AF_BLUETOOTH; 481 bdaddr_copy(&sa->bt_bdaddr, &pcb->hp_raddr); 482 return 0; 483 484 case PRU_SOCKADDR: 485 KASSERT(nam); 486 sa = mtod(nam, struct sockaddr_bt *); 487 488 memset(sa, 0, sizeof(struct sockaddr_bt)); 489 nam->m_len = 490 sa->bt_len = sizeof(struct sockaddr_bt); 491 sa->bt_family = AF_BLUETOOTH; 492 bdaddr_copy(&sa->bt_bdaddr, &pcb->hp_laddr); 493 return 0; 494 495 case PRU_SHUTDOWN: 496 socantsendmore(up); 497 break; 498 499 case PRU_SEND: 500 sa = NULL; 501 if (nam) { 502 sa = mtod(nam, struct sockaddr_bt *); 503 504 if (sa->bt_len != sizeof(struct sockaddr_bt)) { 505 err = EINVAL; 506 goto release; 507 } 508 509 if (sa->bt_family != AF_BLUETOOTH) { 510 err = EAFNOSUPPORT; 511 goto release; 512 } 513 } 514 515 if (ctl) /* have no use for this */ 516 m_freem(ctl); 517 518 return hci_send(pcb, m, (sa ? &sa->bt_bdaddr : &pcb->hp_raddr)); 519 520 case PRU_SENSE: 521 return 0; /* (no sense - Doh!) */ 522 523 case PRU_RCVD: 524 case PRU_RCVOOB: 525 return EOPNOTSUPP; /* (no release) */ 526 527 case PRU_ACCEPT: 528 case PRU_CONNECT2: 529 case PRU_LISTEN: 530 case PRU_SENDOOB: 531 case PRU_FASTTIMO: 532 case PRU_SLOWTIMO: 533 case PRU_PROTORCV: 534 case PRU_PROTOSEND: 535 err = EOPNOTSUPP; 536 break; 537 538 default: 539 UNKNOWN(req); 540 err = EOPNOTSUPP; 541 break; 542 } 543 544 release: 545 if (m) m_freem(m); 546 if (ctl) m_freem(ctl); 547 return err; 548 } 549 550 /* 551 * System is short on memory. 552 */ 553 void 554 hci_drain(void) 555 { 556 557 /* 558 * We can give the security masks back, if there 559 * are no unprivileged sockets in operation.. 560 */ 561 if (hci_event_mask) { 562 struct hci_pcb *pcb; 563 564 LIST_FOREACH(pcb, &hci_pcb, hp_next) { 565 if ((pcb->hp_flags & HCI_PRIVILEGED) == 0) 566 break; 567 } 568 569 if (pcb == NULL) { 570 free(hci_event_mask, M_BLUETOOTH); 571 hci_event_mask = NULL; 572 hci_opcode_mask = NULL; 573 } 574 } 575 } 576 577 /* 578 * get/set socket options 579 */ 580 int 581 hci_ctloutput(int req, struct socket *so, int level, 582 int optname, struct mbuf **opt) 583 { 584 struct hci_pcb *pcb = (struct hci_pcb *)so->so_pcb; 585 struct mbuf *m; 586 int err = 0; 587 588 DPRINTFN(2, "req %s\n", prcorequests[req]); 589 590 if (pcb == NULL) 591 return EINVAL; 592 593 if (level != BTPROTO_HCI) 594 return 0; 595 596 switch(req) { 597 case PRCO_GETOPT: 598 m = m_get(M_WAIT, MT_SOOPTS); 599 switch (optname) { 600 case SO_HCI_EVT_FILTER: 601 m->m_len = sizeof(struct hci_filter); 602 memcpy(mtod(m, void *), &pcb->hp_efilter, m->m_len); 603 break; 604 605 case SO_HCI_PKT_FILTER: 606 m->m_len = sizeof(struct hci_filter); 607 memcpy(mtod(m, void *), &pcb->hp_pfilter, m->m_len); 608 break; 609 610 case SO_HCI_DIRECTION: 611 m->m_len = sizeof(int); 612 if (pcb->hp_flags & HCI_DIRECTION) 613 *mtod(m, int *) = 1; 614 else 615 *mtod(m, int *) = 0; 616 break; 617 618 default: 619 err = EINVAL; 620 m_freem(m); 621 m = NULL; 622 break; 623 } 624 *opt = m; 625 break; 626 627 case PRCO_SETOPT: 628 m = *opt; 629 if (m) switch (optname) { 630 case SO_HCI_EVT_FILTER: /* set event filter */ 631 m->m_len = min(m->m_len, sizeof(struct hci_filter)); 632 memcpy(&pcb->hp_efilter, mtod(m, void *), m->m_len); 633 break; 634 635 case SO_HCI_PKT_FILTER: /* set packet filter */ 636 m->m_len = min(m->m_len, sizeof(struct hci_filter)); 637 memcpy(&pcb->hp_pfilter, mtod(m, void *), m->m_len); 638 break; 639 640 case SO_HCI_DIRECTION: /* request direction ctl messages */ 641 if (*mtod(m, int *)) 642 pcb->hp_flags |= HCI_DIRECTION; 643 else 644 pcb->hp_flags &= ~HCI_DIRECTION; 645 break; 646 647 default: 648 err = EINVAL; 649 break; 650 } 651 m_freem(m); 652 break; 653 654 default: 655 err = EINVAL; 656 break; 657 } 658 659 return err; 660 } 661 662 /* 663 * HCI mbuf tap routine 664 * 665 * copy packets to any raw HCI sockets that wish (and are 666 * permitted) to see them 667 */ 668 void 669 hci_mtap(struct mbuf *m, struct hci_unit *unit) 670 { 671 struct hci_pcb *pcb; 672 struct mbuf *m0, *ctlmsg, **ctl; 673 struct sockaddr_bt sa; 674 uint8_t type; 675 uint8_t event; 676 uint16_t opcode; 677 678 KASSERT(m->m_len >= sizeof(type)); 679 680 type = *mtod(m, uint8_t *); 681 682 memset(&sa, 0, sizeof(sa)); 683 sa.bt_len = sizeof(struct sockaddr_bt); 684 sa.bt_family = AF_BLUETOOTH; 685 bdaddr_copy(&sa.bt_bdaddr, &unit->hci_bdaddr); 686 687 LIST_FOREACH(pcb, &hci_pcb, hp_next) { 688 /* 689 * filter according to source address 690 */ 691 if ((pcb->hp_flags & HCI_PROMISCUOUS) == 0 692 && bdaddr_same(&pcb->hp_laddr, &sa.bt_bdaddr) == 0) 693 continue; 694 695 /* 696 * filter according to packet type filter 697 */ 698 if (hci_filter_test(type, &pcb->hp_pfilter) == 0) 699 continue; 700 701 /* 702 * filter according to event/security filters 703 */ 704 switch(type) { 705 case HCI_EVENT_PKT: 706 KASSERT(m->m_len >= sizeof(hci_event_hdr_t)); 707 708 event = mtod(m, hci_event_hdr_t *)->event; 709 710 if (hci_filter_test(event, &pcb->hp_efilter) == 0) 711 continue; 712 713 if ((pcb->hp_flags & HCI_PRIVILEGED) == 0 714 && hci_security_check_event(event) == 0) 715 continue; 716 break; 717 718 case HCI_CMD_PKT: 719 KASSERT(m->m_len >= sizeof(hci_cmd_hdr_t)); 720 721 opcode = le16toh(mtod(m, hci_cmd_hdr_t *)->opcode); 722 723 if ((pcb->hp_flags & HCI_PRIVILEGED) == 0 724 && hci_security_check_opcode(opcode) == 0) 725 continue; 726 break; 727 728 case HCI_ACL_DATA_PKT: 729 case HCI_SCO_DATA_PKT: 730 default: 731 if ((pcb->hp_flags & HCI_PRIVILEGED) == 0) 732 continue; 733 734 break; 735 } 736 737 /* 738 * create control messages 739 */ 740 ctlmsg = NULL; 741 ctl = &ctlmsg; 742 if (pcb->hp_flags & HCI_DIRECTION) { 743 int dir = m->m_flags & M_LINK0 ? 1 : 0; 744 745 *ctl = sbcreatecontrol((caddr_t)&dir, sizeof(dir), 746 SCM_HCI_DIRECTION, BTPROTO_HCI); 747 748 if (*ctl != NULL) 749 ctl = &((*ctl)->m_next); 750 } 751 752 /* 753 * copy to socket 754 */ 755 m0 = m_copypacket(m, M_DONTWAIT); 756 if (m0 && sbappendaddr(&pcb->hp_socket->so_rcv, 757 (struct sockaddr *)&sa, m0, ctlmsg)) { 758 sorwakeup(pcb->hp_socket); 759 } else { 760 m_freem(ctlmsg); 761 m_freem(m0); 762 } 763 } 764 } 765