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