1 /* $DragonFly: src/sys/netbt/hci_socket.c,v 1.3 2008/06/20 20:52:29 aggelos Exp $ */ 2 /* $OpenBSD: src/sys/netbt/hci_socket.c,v 1.5 2008/02/24 21:34:48 uwe Exp $ */ 3 /* $NetBSD: hci_socket.c,v 1.14 2008/02/10 17:40:54 plunky Exp $ */ 4 5 /*- 6 * Copyright (c) 2005 Iain Hibbert. 7 * Copyright (c) 2006 Itronix Inc. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. The name of Itronix Inc. may not be used to endorse 19 * or promote products derived from this software without specific 20 * prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 25 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY 26 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 27 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 29 * ON ANY THEORY OF LIABILITY, WHETHER IN 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 * POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35 /* load symbolic names */ 36 #ifdef BLUETOOTH_DEBUG 37 #define PRUREQUESTS 38 #define PRCOREQUESTS 39 #endif 40 41 #include <sys/param.h> 42 #include <sys/domain.h> 43 #include <sys/kernel.h> 44 #include <sys/mbuf.h> 45 #include <sys/proc.h> 46 #include <sys/priv.h> 47 #include <sys/protosw.h> 48 #include <sys/socket.h> 49 #include <sys/socketvar.h> 50 #include <sys/systm.h> 51 #include <sys/endian.h> 52 #include <net/if.h> 53 #include <net/if_var.h> 54 #include <sys/sysctl.h> 55 56 #include <sys/thread2.h> 57 #include <sys/socketvar2.h> 58 #include <sys/msgport2.h> 59 60 #include <netbt/bluetooth.h> 61 #include <netbt/hci.h> 62 63 /******************************************************************************* 64 * 65 * HCI SOCK_RAW Sockets - for control of Bluetooth Devices 66 * 67 */ 68 69 /* 70 * the raw HCI protocol control block 71 */ 72 struct hci_pcb { 73 struct socket *hp_socket; /* socket */ 74 unsigned int hp_flags; /* flags */ 75 bdaddr_t hp_laddr; /* local address */ 76 bdaddr_t hp_raddr; /* remote address */ 77 struct hci_filter hp_efilter; /* user event filter */ 78 struct hci_filter hp_pfilter; /* user packet filter */ 79 LIST_ENTRY(hci_pcb) hp_next; /* next HCI pcb */ 80 }; 81 82 /* hp_flags */ 83 #define HCI_PRIVILEGED (1<<0) /* no security filter for root */ 84 #define HCI_DIRECTION (1<<1) /* direction control messages */ 85 #define HCI_PROMISCUOUS (1<<2) /* listen to all units */ 86 87 LIST_HEAD(hci_pcb_list, hci_pcb) hci_pcb = LIST_HEAD_INITIALIZER(hci_pcb); 88 89 /* sysctl defaults */ 90 int hci_sendspace = HCI_CMD_PKT_SIZE; 91 int hci_recvspace = 4096; 92 93 extern struct pr_usrreqs hci_usrreqs; 94 95 /* Prototypes for usrreqs methods. */ 96 static void hci_sdetach(netmsg_t msg); 97 98 /* supported commands opcode table */ 99 static const struct { 100 uint16_t opcode; 101 uint8_t offs; /* 0 - 63 */ 102 uint8_t mask; /* bit 0 - 7 */ 103 int16_t length; /* -1 if privileged */ 104 } hci_cmds[] = { 105 { HCI_CMD_INQUIRY, 106 0, 0x01, sizeof(hci_inquiry_cp) }, 107 { HCI_CMD_INQUIRY_CANCEL, 108 0, 0x02, -1 }, 109 { HCI_CMD_PERIODIC_INQUIRY, 110 0, 0x04, -1 }, 111 { HCI_CMD_EXIT_PERIODIC_INQUIRY, 112 0, 0x08, -1 }, 113 { HCI_CMD_CREATE_CON, 114 0, 0x10, -1 }, 115 { HCI_CMD_DISCONNECT, 116 0, 0x20, -1 }, 117 { HCI_CMD_ADD_SCO_CON, 118 0, 0x40, -1 }, 119 { HCI_CMD_CREATE_CON_CANCEL, 120 0, 0x80, -1 }, 121 { HCI_CMD_ACCEPT_CON, 122 1, 0x01, -1 }, 123 { HCI_CMD_REJECT_CON, 124 1, 0x02, -1 }, 125 { HCI_CMD_LINK_KEY_REP, 126 1, 0x04, -1 }, 127 { HCI_CMD_LINK_KEY_NEG_REP, 128 1, 0x08, -1 }, 129 { HCI_CMD_PIN_CODE_REP, 130 1, 0x10, -1 }, 131 { HCI_CMD_PIN_CODE_NEG_REP, 132 1, 0x20, -1 }, 133 { HCI_CMD_CHANGE_CON_PACKET_TYPE, 134 1, 0x40, -1 }, 135 { HCI_CMD_AUTH_REQ, 136 1, 0x80, -1 }, 137 { HCI_CMD_SET_CON_ENCRYPTION, 138 2, 0x01, -1 }, 139 { HCI_CMD_CHANGE_CON_LINK_KEY, 140 2, 0x02, -1 }, 141 { HCI_CMD_MASTER_LINK_KEY, 142 2, 0x04, -1 }, 143 { HCI_CMD_REMOTE_NAME_REQ, 144 2, 0x08, sizeof(hci_remote_name_req_cp) }, 145 { HCI_CMD_REMOTE_NAME_REQ_CANCEL, 146 2, 0x10, -1 }, 147 { HCI_CMD_READ_REMOTE_FEATURES, 148 2, 0x20, sizeof(hci_read_remote_features_cp) }, 149 { HCI_CMD_READ_REMOTE_EXTENDED_FEATURES, 150 2, 0x40, sizeof(hci_read_remote_extended_features_cp) }, 151 { HCI_CMD_READ_REMOTE_VER_INFO, 152 2, 0x80, sizeof(hci_read_remote_ver_info_cp) }, 153 { HCI_CMD_READ_CLOCK_OFFSET, 154 3, 0x01, sizeof(hci_read_clock_offset_cp) }, 155 { HCI_CMD_READ_LMP_HANDLE, 156 3, 0x02, sizeof(hci_read_lmp_handle_cp) }, 157 { HCI_CMD_HOLD_MODE, 158 4, 0x02, -1 }, 159 { HCI_CMD_SNIFF_MODE, 160 4, 0x04, -1 }, 161 { HCI_CMD_EXIT_SNIFF_MODE, 162 4, 0x08, -1 }, 163 { HCI_CMD_PARK_MODE, 164 4, 0x10, -1 }, 165 { HCI_CMD_EXIT_PARK_MODE, 166 4, 0x20, -1 }, 167 { HCI_CMD_QOS_SETUP, 168 4, 0x40, -1 }, 169 { HCI_CMD_ROLE_DISCOVERY, 170 4, 0x80, sizeof(hci_role_discovery_cp) }, 171 { HCI_CMD_SWITCH_ROLE, 172 5, 0x01, -1 }, 173 { HCI_CMD_READ_LINK_POLICY_SETTINGS, 174 5, 0x02, sizeof(hci_read_link_policy_settings_cp) }, 175 { HCI_CMD_WRITE_LINK_POLICY_SETTINGS, 176 5, 0x04, -1 }, 177 { HCI_CMD_READ_DEFAULT_LINK_POLICY_SETTINGS, 178 5, 0x08, 0 }, 179 { HCI_CMD_WRITE_DEFAULT_LINK_POLICY_SETTINGS, 180 5, 0x10, -1 }, 181 { HCI_CMD_FLOW_SPECIFICATION, 182 5, 0x20, -1 }, 183 { HCI_CMD_SET_EVENT_MASK, 184 5, 0x40, -1 }, 185 { HCI_CMD_RESET, 186 5, 0x80, -1 }, 187 { HCI_CMD_SET_EVENT_FILTER, 188 6, 0x01, -1 }, 189 { HCI_CMD_FLUSH, 190 6, 0x02, -1 }, 191 { HCI_CMD_READ_PIN_TYPE, 192 6, 0x04, 0 }, 193 { HCI_CMD_WRITE_PIN_TYPE, 194 6, 0x08, -1 }, 195 { HCI_CMD_CREATE_NEW_UNIT_KEY, 196 6, 0x10, -1 }, 197 { HCI_CMD_READ_STORED_LINK_KEY, 198 6, 0x20, -1 }, 199 { HCI_CMD_WRITE_STORED_LINK_KEY, 200 6, 0x40, -1 }, 201 { HCI_CMD_DELETE_STORED_LINK_KEY, 202 6, 0x80, -1 }, 203 { HCI_CMD_WRITE_LOCAL_NAME, 204 7, 0x01, -1 }, 205 { HCI_CMD_READ_LOCAL_NAME, 206 7, 0x02, 0 }, 207 { HCI_CMD_READ_CON_ACCEPT_TIMEOUT, 208 7, 0x04, 0 }, 209 { HCI_CMD_WRITE_CON_ACCEPT_TIMEOUT, 210 7, 0x08, -1 }, 211 { HCI_CMD_READ_PAGE_TIMEOUT, 212 7, 0x10, 0 }, 213 { HCI_CMD_WRITE_PAGE_TIMEOUT, 214 7, 0x20, -1 }, 215 { HCI_CMD_READ_SCAN_ENABLE, 216 7, 0x40, 0 }, 217 { HCI_CMD_WRITE_SCAN_ENABLE, 218 7, 0x80, -1 }, 219 { HCI_CMD_READ_PAGE_SCAN_ACTIVITY, 220 8, 0x01, 0 }, 221 { HCI_CMD_WRITE_PAGE_SCAN_ACTIVITY, 222 8, 0x02, -1 }, 223 { HCI_CMD_READ_INQUIRY_SCAN_ACTIVITY, 224 8, 0x04, 0 }, 225 { HCI_CMD_WRITE_INQUIRY_SCAN_ACTIVITY, 226 8, 0x08, -1 }, 227 { HCI_CMD_READ_AUTH_ENABLE, 228 8, 0x10, 0 }, 229 { HCI_CMD_WRITE_AUTH_ENABLE, 230 8, 0x20, -1 }, 231 { HCI_CMD_READ_ENCRYPTION_MODE, 232 8, 0x40, 0 }, 233 { HCI_CMD_WRITE_ENCRYPTION_MODE, 234 8, 0x80, -1 }, 235 { HCI_CMD_READ_UNIT_CLASS, 236 9, 0x01, 0 }, 237 { HCI_CMD_WRITE_UNIT_CLASS, 238 9, 0x02, -1 }, 239 { HCI_CMD_READ_VOICE_SETTING, 240 9, 0x04, 0 }, 241 { HCI_CMD_WRITE_VOICE_SETTING, 242 9, 0x08, -1 }, 243 { HCI_CMD_READ_AUTO_FLUSH_TIMEOUT, 244 9, 0x10, sizeof(hci_read_auto_flush_timeout_cp) }, 245 { HCI_CMD_WRITE_AUTO_FLUSH_TIMEOUT, 246 9, 0x20, -1 }, 247 { HCI_CMD_READ_NUM_BROADCAST_RETRANS, 248 9, 0x40, 0 }, 249 { HCI_CMD_WRITE_NUM_BROADCAST_RETRANS, 250 9, 0x80, -1 }, 251 { HCI_CMD_READ_HOLD_MODE_ACTIVITY, 252 10, 0x01, 0 }, 253 { HCI_CMD_WRITE_HOLD_MODE_ACTIVITY, 254 10, 0x02, -1 }, 255 { HCI_CMD_READ_XMIT_LEVEL, 256 10, 0x04, sizeof(hci_read_xmit_level_cp) }, 257 { HCI_CMD_READ_SCO_FLOW_CONTROL, 258 10, 0x08, 0 }, 259 { HCI_CMD_WRITE_SCO_FLOW_CONTROL, 260 10, 0x10, -1 }, 261 { HCI_CMD_HC2H_FLOW_CONTROL, 262 10, 0x20, -1 }, 263 { HCI_CMD_HOST_BUFFER_SIZE, 264 10, 0x40, -1 }, 265 { HCI_CMD_HOST_NUM_COMPL_PKTS, 266 10, 0x80, -1 }, 267 { HCI_CMD_READ_LINK_SUPERVISION_TIMEOUT, 268 11, 0x01, sizeof(hci_read_link_supervision_timeout_cp) }, 269 { HCI_CMD_WRITE_LINK_SUPERVISION_TIMEOUT, 270 11, 0x02, -1 }, 271 { HCI_CMD_READ_NUM_SUPPORTED_IAC, 272 11, 0x04, 0 }, 273 { HCI_CMD_READ_IAC_LAP, 274 11, 0x08, 0 }, 275 { HCI_CMD_WRITE_IAC_LAP, 276 11, 0x10, -1 }, 277 { HCI_CMD_READ_PAGE_SCAN_PERIOD, 278 11, 0x20, 0 }, 279 { HCI_CMD_WRITE_PAGE_SCAN_PERIOD, 280 11, 0x40, -1 }, 281 { HCI_CMD_READ_PAGE_SCAN, 282 11, 0x80, 0 }, 283 { HCI_CMD_WRITE_PAGE_SCAN, 284 12, 0x01, -1 }, 285 { HCI_CMD_SET_AFH_CLASSIFICATION, 286 12, 0x02, -1 }, 287 { HCI_CMD_READ_INQUIRY_SCAN_TYPE, 288 12, 0x10, 0 }, 289 { HCI_CMD_WRITE_INQUIRY_SCAN_TYPE, 290 12, 0x20, -1 }, 291 { HCI_CMD_READ_INQUIRY_MODE, 292 12, 0x40, 0 }, 293 { HCI_CMD_WRITE_INQUIRY_MODE, 294 12, 0x80, -1 }, 295 { HCI_CMD_READ_PAGE_SCAN_TYPE, 296 13, 0x01, 0 }, 297 { HCI_CMD_WRITE_PAGE_SCAN_TYPE, 298 13, 0x02, -1 }, 299 { HCI_CMD_READ_AFH_ASSESSMENT, 300 13, 0x04, 0 }, 301 { HCI_CMD_WRITE_AFH_ASSESSMENT, 302 13, 0x08, -1 }, 303 { HCI_CMD_READ_LOCAL_VER, 304 14, 0x08, 0 }, 305 { HCI_CMD_READ_LOCAL_COMMANDS, 306 14, 0x10, 0 }, 307 { HCI_CMD_READ_LOCAL_FEATURES, 308 14, 0x20, 0 }, 309 { HCI_CMD_READ_LOCAL_EXTENDED_FEATURES, 310 14, 0x40, sizeof(hci_read_local_extended_features_cp) }, 311 { HCI_CMD_READ_BUFFER_SIZE, 312 14, 0x80, 0 }, 313 { HCI_CMD_READ_COUNTRY_CODE, 314 15, 0x01, 0 }, 315 { HCI_CMD_READ_BDADDR, 316 15, 0x02, 0 }, 317 { HCI_CMD_READ_FAILED_CONTACT_CNTR, 318 15, 0x04, sizeof(hci_read_failed_contact_cntr_cp) }, 319 { HCI_CMD_RESET_FAILED_CONTACT_CNTR, 320 15, 0x08, -1 }, 321 { HCI_CMD_READ_LINK_QUALITY, 322 15, 0x10, sizeof(hci_read_link_quality_cp) }, 323 { HCI_CMD_READ_RSSI, 324 15, 0x20, sizeof(hci_read_rssi_cp) }, 325 { HCI_CMD_READ_AFH_CHANNEL_MAP, 326 15, 0x40, sizeof(hci_read_afh_channel_map_cp) }, 327 { HCI_CMD_READ_CLOCK, 328 15, 0x80, sizeof(hci_read_clock_cp) }, 329 { HCI_CMD_READ_LOOPBACK_MODE, 330 16, 0x01, 0 }, 331 { HCI_CMD_WRITE_LOOPBACK_MODE, 332 16, 0x02, -1 }, 333 { HCI_CMD_ENABLE_UNIT_UNDER_TEST, 334 16, 0x04, -1 }, 335 { HCI_CMD_SETUP_SCO_CON, 336 16, 0x08, -1 }, 337 { HCI_CMD_ACCEPT_SCO_CON_REQ, 338 16, 0x10, -1 }, 339 { HCI_CMD_REJECT_SCO_CON_REQ, 340 16, 0x20, -1 }, 341 { HCI_CMD_READ_EXTENDED_INQUIRY_RSP, 342 17, 0x01, 0 }, 343 { HCI_CMD_WRITE_EXTENDED_INQUIRY_RSP, 344 17, 0x02, -1 }, 345 { HCI_CMD_REFRESH_ENCRYPTION_KEY, 346 17, 0x04, -1 }, 347 { HCI_CMD_SNIFF_SUBRATING, 348 17, 0x10, -1 }, 349 { HCI_CMD_READ_SIMPLE_PAIRING_MODE, 350 17, 0x20, 0 }, 351 { HCI_CMD_WRITE_SIMPLE_PAIRING_MODE, 352 17, 0x40, -1 }, 353 { HCI_CMD_READ_LOCAL_OOB_DATA, 354 17, 0x80, -1 }, 355 { HCI_CMD_READ_INQUIRY_RSP_XMIT_POWER, 356 18, 0x01, 0 }, 357 { HCI_CMD_WRITE_INQUIRY_RSP_XMIT_POWER, 358 18, 0x02, -1 }, 359 { HCI_CMD_READ_DEFAULT_ERRDATA_REPORTING, 360 18, 0x04, 0 }, 361 { HCI_CMD_WRITE_DEFAULT_ERRDATA_REPORTING, 362 18, 0x08, -1 }, 363 { HCI_CMD_IO_CAPABILITY_REP, 364 18, 0x80, -1 }, 365 { HCI_CMD_USER_CONFIRM_REP, 366 19, 0x01, -1 }, 367 { HCI_CMD_USER_CONFIRM_NEG_REP, 368 19, 0x02, -1 }, 369 { HCI_CMD_USER_PASSKEY_REP, 370 19, 0x04, -1 }, 371 { HCI_CMD_USER_PASSKEY_NEG_REP, 372 19, 0x08, -1 }, 373 { HCI_CMD_OOB_DATA_REP, 374 19, 0x10, -1 }, 375 { HCI_CMD_WRITE_SIMPLE_PAIRING_DEBUG_MODE, 376 19, 0x20, -1 }, 377 { HCI_CMD_ENHANCED_FLUSH, 378 19, 0x40, -1 }, 379 { HCI_CMD_OOB_DATA_NEG_REP, 380 19, 0x80, -1 }, 381 { HCI_CMD_SEND_KEYPRESS_NOTIFICATION, 382 20, 0x40, -1 }, 383 { HCI_CMD_IO_CAPABILITY_NEG_REP, 384 20, 0x80, -1 }, 385 }; 386 387 /* 388 * Security filter routines for unprivileged users. 389 * Allow all but a few critical events, and only permit read commands. 390 * If a unit is given, verify the command is supported. 391 */ 392 393 static int 394 hci_security_check_opcode(struct hci_unit *unit, uint16_t opcode) 395 { 396 int i; 397 398 for (i = 0 ; i < sizeof(hci_cmds) / sizeof(hci_cmds[0]); i++) { 399 if (opcode != hci_cmds[i].opcode) 400 continue; 401 402 if (unit == NULL 403 || (unit->hci_cmds[hci_cmds[i].offs] & hci_cmds[i].mask)) 404 return hci_cmds[i].length; 405 406 break; 407 } 408 409 return -1; 410 } 411 412 static int 413 hci_security_check_event(uint8_t event) 414 { 415 416 switch (event) { 417 case HCI_EVENT_RETURN_LINK_KEYS: 418 case HCI_EVENT_LINK_KEY_NOTIFICATION: 419 case HCI_EVENT_USER_CONFIRM_REQ: 420 case HCI_EVENT_USER_PASSKEY_NOTIFICATION: 421 case HCI_EVENT_VENDOR: 422 return -1; /* disallowed */ 423 } 424 425 return 0; /* ok */ 426 } 427 428 /* 429 * When command packet reaches the device, we can drop 430 * it from the socket buffer (called from hci_output_acl) 431 */ 432 void 433 hci_drop(void *arg) 434 { 435 struct socket *so = arg; 436 437 sbdroprecord(&so->so_snd.sb); 438 sowwakeup(so); 439 } 440 441 /* 442 * HCI socket is going away and has some pending packets. We let them 443 * go by design, but remove the context pointer as it will be invalid 444 * and we no longer need to be notified. 445 */ 446 static void 447 hci_cmdwait_flush(struct socket *so) 448 { 449 struct hci_unit *unit; 450 struct socket *ctx; 451 struct mbuf *m; 452 453 DPRINTF("flushing %p\n", so); 454 455 TAILQ_FOREACH(unit, &hci_unit_list, hci_next) { 456 IF_POLL(&unit->hci_cmdwait, m); 457 while (m != NULL) { 458 ctx = M_GETCTX(m, struct socket *); 459 if (ctx == so) 460 M_SETCTX(m, NULL); 461 462 m = m->m_nextpkt; 463 } 464 } 465 } 466 467 /* 468 * HCI send packet 469 * This came from userland, so check it out. 470 */ 471 static int 472 hci_send(struct hci_pcb *pcb, struct mbuf *m, bdaddr_t *addr) 473 { 474 struct hci_unit *unit; 475 struct mbuf *m0; 476 hci_cmd_hdr_t hdr; 477 int err; 478 479 KKASSERT(m != NULL); 480 KKASSERT(addr != NULL); 481 482 /* wants at least a header to start with */ 483 if (m->m_pkthdr.len < sizeof(hdr)) { 484 err = EMSGSIZE; 485 goto bad; 486 } 487 m_copydata(m, 0, sizeof(hdr), (caddr_t)&hdr); 488 hdr.opcode = letoh16(hdr.opcode); 489 490 /* only allows CMD packets to be sent */ 491 if (hdr.type != HCI_CMD_PKT) { 492 err = EINVAL; 493 goto bad; 494 } 495 496 /* validates packet length */ 497 if (m->m_pkthdr.len != sizeof(hdr) + hdr.length) { 498 err = EMSGSIZE; 499 goto bad; 500 } 501 502 /* finds destination */ 503 unit = hci_unit_lookup(addr); 504 if (unit == NULL) { 505 err = ENETDOWN; 506 goto bad; 507 } 508 509 /* security checks for unprivileged users */ 510 if ((pcb->hp_flags & HCI_PRIVILEGED) == 0 511 && hci_security_check_opcode(unit, hdr.opcode) != hdr.length) { 512 err = EPERM; 513 goto bad; 514 } 515 516 /* makes a copy for precious to keep */ 517 m0 = m_copym(m, 0, M_COPYALL, MB_DONTWAIT); 518 if (m0 == NULL) { 519 err = ENOMEM; 520 goto bad; 521 } 522 sbappendrecord(&pcb->hp_socket->so_snd.sb, m0); 523 M_SETCTX(m, pcb->hp_socket); /* enable drop callback */ 524 525 DPRINTFN(2, "(%s) opcode (%03x|%04x)\n", 526 device_get_nameunit(unit->hci_dev), 527 HCI_OGF(hdr.opcode), HCI_OCF(hdr.opcode)); 528 529 /* Sendss it */ 530 if (unit->hci_num_cmd_pkts == 0) 531 IF_ENQUEUE(&unit->hci_cmdwait, m); 532 else 533 hci_output_cmd(unit, m); 534 535 return 0; 536 537 bad: 538 DPRINTF("packet (%d bytes) not sent (error %d)\n", 539 m->m_pkthdr.len, err); 540 if (m) m_freem(m); 541 return err; 542 } 543 544 /* 545 * Implementation of usrreqs. 546 * 547 * NOTE: (so) is referenced from soabort*() and netmsg_pru_abort() 548 * will sofree() it when we return. 549 */ 550 static void 551 hci_sabort(netmsg_t msg) 552 { 553 /* struct hci_pcb *pcb = (struct hci_pcb *)so->so_pcb; */ 554 555 soisdisconnected(msg->abort.base.nm_so); 556 hci_sdetach(msg); 557 /* msg now invalid */ 558 } 559 560 static void 561 hci_sdetach(netmsg_t msg) 562 { 563 struct socket *so = msg->detach.base.nm_so; 564 struct hci_pcb *pcb = (struct hci_pcb *)so->so_pcb; 565 int error; 566 567 if (pcb == NULL) { 568 error = EINVAL; 569 } else { 570 if (so->so_snd.ssb_mb != NULL) 571 hci_cmdwait_flush(so); 572 573 so->so_pcb = NULL; 574 sofree(so); /* remove pcb ref */ 575 576 LIST_REMOVE(pcb, hp_next); 577 kfree(pcb, M_PCB); 578 error = 0; 579 } 580 lwkt_replymsg(&msg->detach.base.lmsg, error); 581 } 582 583 static void 584 hci_sdisconnect(netmsg_t msg) 585 { 586 struct socket *so = msg->disconnect.base.nm_so; 587 struct hci_pcb *pcb = (struct hci_pcb *)so->so_pcb; 588 int error; 589 590 if (pcb) { 591 bdaddr_copy(&pcb->hp_raddr, BDADDR_ANY); 592 /* 593 * XXX We cannot call soisdisconnected() here, as it sets 594 * SS_CANTRCVMORE and SS_CANTSENDMORE. The problem is that 595 * soisconnected() does not clear these and if you try to 596 * reconnect this socket (which is permitted) you get a 597 * broken pipe when you try to write any data. 598 */ 599 soclrstate(so, SS_ISCONNECTED); 600 error = 0; 601 } else { 602 error = EINVAL; 603 } 604 lwkt_replymsg(&msg->disconnect.base.lmsg, error); 605 } 606 607 static void 608 hci_scontrol(netmsg_t msg) 609 { 610 int error; 611 612 error = hci_ioctl(msg->control.nm_cmd, 613 (void *)msg->control.nm_data, 614 NULL); 615 lwkt_replymsg(&msg->control.base.lmsg, error); 616 } 617 618 static void 619 hci_sattach(netmsg_t msg) 620 { 621 struct socket *so = msg->attach.base.nm_so; 622 struct hci_pcb *pcb = (struct hci_pcb *)so->so_pcb; 623 int error; 624 625 if (pcb) { 626 error = EINVAL; 627 goto out; 628 } 629 630 error = soreserve(so, hci_sendspace, hci_recvspace,NULL); 631 if (error) 632 goto out; 633 634 pcb = kmalloc(sizeof *pcb, M_PCB, M_NOWAIT | M_ZERO); 635 if (pcb == NULL) { 636 error = ENOMEM; 637 goto out; 638 } 639 640 soreference(so); 641 so->so_pcb = pcb; 642 pcb->hp_socket = so; 643 644 if (curproc == NULL || priv_check(curthread, PRIV_ROOT) == 0) 645 pcb->hp_flags |= HCI_PRIVILEGED; 646 647 /* 648 * Set default user filter. By default, socket only passes 649 * Command_Complete and Command_Status Events. 650 */ 651 hci_filter_set(HCI_EVENT_COMMAND_COMPL, &pcb->hp_efilter); 652 hci_filter_set(HCI_EVENT_COMMAND_STATUS, &pcb->hp_efilter); 653 hci_filter_set(HCI_EVENT_PKT, &pcb->hp_pfilter); 654 655 crit_enter(); 656 LIST_INSERT_HEAD(&hci_pcb, pcb, hp_next); 657 crit_exit(); 658 error = 0; 659 out: 660 lwkt_replymsg(&msg->attach.base.lmsg, error); 661 } 662 663 static void 664 hci_sbind(netmsg_t msg) 665 { 666 struct socket *so = msg->bind.base.nm_so; 667 struct sockaddr *nam = msg->bind.nm_nam; 668 struct hci_pcb *pcb = (struct hci_pcb *)so->so_pcb; 669 struct sockaddr_bt *sa; 670 int error; 671 672 KKASSERT(nam != NULL); 673 sa = (struct sockaddr_bt *)nam; 674 675 if (sa->bt_len != sizeof(struct sockaddr_bt)) { 676 error = EINVAL; 677 goto out; 678 } 679 680 if (sa->bt_family != AF_BLUETOOTH) { 681 error = EAFNOSUPPORT; 682 goto out; 683 } 684 685 bdaddr_copy(&pcb->hp_laddr, &sa->bt_bdaddr); 686 687 if (bdaddr_any(&sa->bt_bdaddr)) 688 pcb->hp_flags |= HCI_PROMISCUOUS; 689 else 690 pcb->hp_flags &= ~HCI_PROMISCUOUS; 691 error = 0; 692 out: 693 lwkt_replymsg(&msg->bind.base.lmsg, error); 694 } 695 696 static void 697 hci_sconnect(netmsg_t msg) 698 { 699 struct socket *so = msg->connect.base.nm_so; 700 struct sockaddr *nam = msg->connect.nm_nam; 701 struct hci_pcb *pcb = (struct hci_pcb *)so->so_pcb; 702 struct sockaddr_bt *sa; 703 int error; 704 705 KKASSERT(nam != NULL); 706 sa = (struct sockaddr_bt *)nam; 707 708 if (sa->bt_len != sizeof(struct sockaddr_bt)) { 709 error = EINVAL; 710 goto out; 711 } 712 713 if (sa->bt_family != AF_BLUETOOTH) { 714 error = EAFNOSUPPORT; 715 goto out; 716 } 717 718 if (hci_unit_lookup(&sa->bt_bdaddr) == NULL) { 719 error = EADDRNOTAVAIL; 720 goto out; 721 } 722 bdaddr_copy(&pcb->hp_raddr, &sa->bt_bdaddr); 723 soisconnected(so); 724 error = 0; 725 out: 726 lwkt_replymsg(&msg->connect.base.lmsg, error); 727 } 728 729 static void 730 hci_speeraddr(netmsg_t msg) 731 { 732 struct socket *so = msg->peeraddr.base.nm_so; 733 struct sockaddr **nam = msg->peeraddr.nm_nam; 734 struct hci_pcb *pcb = (struct hci_pcb *)so->so_pcb; 735 struct sockaddr_bt *sa; 736 737 KKASSERT(nam != NULL); 738 sa = (struct sockaddr_bt *)nam; 739 740 memset(sa, 0, sizeof(struct sockaddr_bt)); 741 sa->bt_len = sizeof(struct sockaddr_bt); 742 sa->bt_family = AF_BLUETOOTH; 743 bdaddr_copy(&sa->bt_bdaddr, &pcb->hp_raddr); 744 745 lwkt_replymsg(&msg->connect.base.lmsg, 0); 746 } 747 748 static void 749 hci_ssockaddr(netmsg_t msg) 750 { 751 struct socket *so = msg->sockaddr.base.nm_so; 752 struct sockaddr **nam = msg->sockaddr.nm_nam; 753 struct hci_pcb *pcb = (struct hci_pcb *)so->so_pcb; 754 struct sockaddr_bt *sa; 755 756 KKASSERT(nam != NULL); 757 sa = (struct sockaddr_bt *)nam; 758 759 memset(sa, 0, sizeof(struct sockaddr_bt)); 760 sa->bt_len = sizeof(struct sockaddr_bt); 761 sa->bt_family = AF_BLUETOOTH; 762 bdaddr_copy(&sa->bt_bdaddr, &pcb->hp_laddr); 763 764 lwkt_replymsg(&msg->connect.base.lmsg, 0); 765 } 766 767 static void 768 hci_sshutdown(netmsg_t msg) 769 { 770 struct socket *so = msg->shutdown.base.nm_so; 771 772 socantsendmore(so); 773 lwkt_replymsg(&msg->connect.base.lmsg, 0); 774 } 775 776 static void 777 hci_ssend(netmsg_t msg) 778 { 779 struct socket *so = msg->send.base.nm_so; 780 struct mbuf *m = msg->send.nm_m; 781 struct sockaddr *addr = msg->send.nm_addr; 782 struct mbuf *control = msg->send.nm_control; 783 struct hci_pcb *pcb = (struct hci_pcb *)so->so_pcb; 784 struct sockaddr_bt *sa; 785 int error; 786 787 sa = NULL; 788 if (addr) { 789 sa = (struct sockaddr_bt *)addr; 790 791 if (sa->bt_len != sizeof(struct sockaddr_bt)) { 792 error = EINVAL; 793 goto out; 794 } 795 796 if (sa->bt_family != AF_BLUETOOTH) { 797 error = EAFNOSUPPORT; 798 goto out; 799 } 800 } 801 802 /* have no use for this */ 803 if (control) { 804 m_freem(control); 805 control = NULL; 806 } 807 error = hci_send(pcb, m, (sa ? &sa->bt_bdaddr : &pcb->hp_raddr)); 808 m = NULL; 809 810 out: 811 if (m) 812 m_freem(m); 813 if (control) 814 m_freem(control); 815 lwkt_replymsg(&msg->send.base.lmsg, error); 816 } 817 818 /* 819 * get/set socket options 820 */ 821 void 822 hci_ctloutput(netmsg_t msg) 823 { 824 struct socket *so = msg->ctloutput.base.nm_so; 825 struct sockopt *sopt = msg->ctloutput.nm_sopt; 826 struct hci_pcb *pcb = (struct hci_pcb *)so->so_pcb; 827 int idir = 0; 828 int error = 0; 829 830 #ifdef notyet /* XXX */ 831 DPRINTFN(2, "req %s\n", prcorequests[req]); 832 #endif 833 834 if (pcb == NULL) { 835 error = EINVAL; 836 goto out; 837 } 838 839 if (sopt->sopt_level != BTPROTO_HCI) { 840 error = ENOPROTOOPT; 841 goto out; 842 } 843 844 switch(sopt->sopt_dir) { 845 case PRCO_GETOPT: 846 switch (sopt->sopt_name) { 847 case SO_HCI_EVT_FILTER: 848 soopt_from_kbuf(sopt, &pcb->hp_efilter, 849 sizeof(struct hci_filter)); 850 break; 851 852 case SO_HCI_PKT_FILTER: 853 soopt_from_kbuf(sopt, &pcb->hp_pfilter, 854 sizeof(struct hci_filter)); 855 break; 856 857 case SO_HCI_DIRECTION: 858 if (pcb->hp_flags & HCI_DIRECTION) 859 idir = 1; 860 else 861 idir = 0; 862 soopt_from_kbuf(sopt, &idir, sizeof(int)); 863 break; 864 865 default: 866 error = ENOPROTOOPT; 867 break; 868 } 869 break; 870 871 case PRCO_SETOPT: 872 switch (sopt->sopt_name) { 873 case SO_HCI_EVT_FILTER: /* set event filter */ 874 error = soopt_to_kbuf(sopt, &pcb->hp_efilter, 875 sizeof(struct hci_filter), 876 sizeof(struct hci_filter)); 877 break; 878 879 case SO_HCI_PKT_FILTER: /* set packet filter */ 880 error = soopt_to_kbuf(sopt, &pcb->hp_pfilter, 881 sizeof(struct hci_filter), 882 sizeof(struct hci_filter)); 883 break; 884 885 case SO_HCI_DIRECTION: /* request direction ctl messages */ 886 error = soopt_to_kbuf(sopt, &idir, sizeof(int), 887 sizeof(int)); 888 if (error) 889 break; 890 if (idir) 891 pcb->hp_flags |= HCI_DIRECTION; 892 else 893 pcb->hp_flags &= ~HCI_DIRECTION; 894 break; 895 896 default: 897 error = ENOPROTOOPT; 898 break; 899 } 900 break; 901 902 default: 903 error = ENOPROTOOPT; 904 break; 905 } 906 out: 907 lwkt_replymsg(&msg->ctloutput.base.lmsg, error); 908 } 909 910 /* 911 * HCI mbuf tap routine 912 * 913 * copy packets to any raw HCI sockets that wish (and are 914 * permitted) to see them 915 */ 916 void 917 hci_mtap(struct mbuf *m, struct hci_unit *unit) 918 { 919 struct hci_pcb *pcb; 920 struct mbuf *m0, *ctlmsg, **ctl; 921 struct sockaddr_bt sa; 922 uint8_t type; 923 uint8_t event; 924 uint16_t opcode; 925 926 KKASSERT(m->m_len >= sizeof(type)); 927 928 type = *mtod(m, uint8_t *); 929 930 memset(&sa, 0, sizeof(sa)); 931 sa.bt_len = sizeof(struct sockaddr_bt); 932 sa.bt_family = AF_BLUETOOTH; 933 bdaddr_copy(&sa.bt_bdaddr, &unit->hci_bdaddr); 934 935 LIST_FOREACH(pcb, &hci_pcb, hp_next) { 936 /* 937 * filter according to source address 938 */ 939 if ((pcb->hp_flags & HCI_PROMISCUOUS) == 0 940 && bdaddr_same(&pcb->hp_laddr, &sa.bt_bdaddr) == 0) 941 continue; 942 943 /* 944 * filter according to packet type filter 945 */ 946 if (hci_filter_test(type, &pcb->hp_pfilter) == 0) 947 continue; 948 949 /* 950 * filter according to event/security filters 951 */ 952 switch(type) { 953 case HCI_EVENT_PKT: 954 KKASSERT(m->m_len >= sizeof(hci_event_hdr_t)); 955 956 event = mtod(m, hci_event_hdr_t *)->event; 957 958 if (hci_filter_test(event, &pcb->hp_efilter) == 0) 959 continue; 960 961 if ((pcb->hp_flags & HCI_PRIVILEGED) == 0 962 && hci_security_check_event(event) == -1) 963 continue; 964 break; 965 966 case HCI_CMD_PKT: 967 KKASSERT(m->m_len >= sizeof(hci_cmd_hdr_t)); 968 969 opcode = letoh16(mtod(m, hci_cmd_hdr_t *)->opcode); 970 971 if ((pcb->hp_flags & HCI_PRIVILEGED) == 0 972 && hci_security_check_opcode(NULL, opcode) == -1) 973 continue; 974 break; 975 976 case HCI_ACL_DATA_PKT: 977 case HCI_SCO_DATA_PKT: 978 default: 979 if ((pcb->hp_flags & HCI_PRIVILEGED) == 0) 980 continue; 981 982 break; 983 } 984 985 /* 986 * create control messages 987 */ 988 ctlmsg = NULL; 989 ctl = &ctlmsg; 990 if (pcb->hp_flags & HCI_DIRECTION) { 991 int dir = m->m_flags & IFF_LINK0 ? 1 : 0; 992 993 *ctl = sbcreatecontrol((void *)&dir, sizeof(dir), 994 SCM_HCI_DIRECTION, BTPROTO_HCI); 995 996 if (*ctl != NULL) 997 ctl = &((*ctl)->m_next); 998 } 999 1000 /* 1001 * copy to socket 1002 */ 1003 m0 = m_copym(m, 0, M_COPYALL, MB_DONTWAIT); 1004 if (m0 && sbappendaddr(&pcb->hp_socket->so_rcv.sb, 1005 (struct sockaddr *)&sa, m0, ctlmsg)) { 1006 sorwakeup(pcb->hp_socket); 1007 } else { 1008 m_freem(ctlmsg); 1009 m_freem(m0); 1010 } 1011 } 1012 } 1013 1014 struct pr_usrreqs hci_usrreqs = { 1015 .pru_abort = hci_sabort, 1016 .pru_accept = pr_generic_notsupp, 1017 .pru_attach = hci_sattach, 1018 .pru_bind = hci_sbind, 1019 .pru_connect = hci_sconnect, 1020 .pru_connect2 = pr_generic_notsupp, 1021 .pru_control = hci_scontrol, 1022 .pru_detach = hci_sdetach, 1023 .pru_disconnect = hci_sdisconnect, 1024 .pru_listen = pr_generic_notsupp, 1025 .pru_peeraddr = hci_speeraddr, 1026 .pru_rcvd = pr_generic_notsupp, 1027 .pru_rcvoob = pr_generic_notsupp, 1028 .pru_send = hci_ssend, 1029 .pru_sense = pru_sense_null, 1030 .pru_shutdown = hci_sshutdown, 1031 .pru_sockaddr = hci_ssockaddr, 1032 .pru_sosend = sosend, 1033 .pru_soreceive = soreceive 1034 }; 1035