ciss(4): Sync with FreeBSD.
[dragonfly.git] / sys / netbt / hci_socket.c
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 };