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