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