xref: /dragonfly/sys/netbt/hci_socket.c (revision ef3ac1d1)
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