hci_socket.c revision 1.1 1 /* $NetBSD: hci_socket.c,v 1.1 2006/06/19 15:44:45 gdamore Exp $ */
2
3 /*-
4 * Copyright (c) 2005 Iain Hibbert.
5 * Copyright (c) 2006 Itronix Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of Itronix Inc. may not be used to endorse
17 * or promote products derived from this software without specific
18 * prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 * ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #include <sys/cdefs.h>
34 __KERNEL_RCSID(0, "$NetBSD: hci_socket.c,v 1.1 2006/06/19 15:44:45 gdamore Exp $");
35
36 #include "opt_bluetooth.h"
37 #ifdef BLUETOOTH_DEBUG
38 #define PRUREQUESTS
39 #define PRCOREQUESTS
40 #endif
41
42 #include <sys/param.h>
43 #include <sys/domain.h>
44 #include <sys/kauth.h>
45 #include <sys/kernel.h>
46 #include <sys/mbuf.h>
47 #include <sys/proc.h>
48 #include <sys/protosw.h>
49 #include <sys/socket.h>
50 #include <sys/socketvar.h>
51 #include <sys/systm.h>
52
53 #include <netbt/bluetooth.h>
54 #include <netbt/hci.h>
55
56 /*******************************************************************************
57 *
58 * HCI SOCK_RAW Sockets - for control of Bluetooth Devices
59 *
60 */
61
62 /*
63 * the raw HCI protocol control block
64 */
65 struct hci_pcb {
66 struct socket *hp_socket; /* socket */
67 unsigned int hp_flags; /* flags */
68 bdaddr_t hp_laddr; /* local address */
69 bdaddr_t hp_raddr; /* remote address */
70 struct hci_filter hp_efilter; /* user event filter */
71 struct hci_filter hp_pfilter; /* user packet filter */
72 LIST_ENTRY(hci_pcb) hp_next; /* next HCI pcb */
73 };
74
75 /* hp_flags */
76 #define HCI_PRIVILEGED (1<<0) /* no security filter for root */
77 #define HCI_DIRECTION (1<<1) /* direction control messages */
78 #define HCI_PROMISCUOUS (1<<2) /* listen to all units */
79
80 LIST_HEAD(hci_pcb_list, hci_pcb) hci_pcb = LIST_HEAD_INITIALIZER(hci_pcb);
81
82 /* sysctl defaults */
83 int hci_sendspace = HCI_CMD_PKT_SIZE;
84 int hci_recvspace = 4096;
85
86 /*
87 * Security filter routines
88 * The security mask is an bit array.
89 * If the bit is set, the opcode/event is permitted.
90 * I only allocate the security mask if needed, and give it back
91 * if requested as its quite a chunk. This could no doubt be made
92 * somewhat bit more memory efficient given that most OGF/OCF's are
93 * not used, but this way is quick.
94 */
95 #define HCI_OPCODE_MASK_SIZE 0x800
96
97 uint32_t *hci_event_mask = NULL;
98 uint32_t *hci_opcode_mask = NULL;
99
100 static __inline int
101 hci_security_check_opcode(uint16_t opcode)
102 {
103
104 return (hci_opcode_mask[opcode >> 5] & (1 << (opcode & 0x1f)));
105 }
106
107 static __inline int
108 hci_security_check_event(uint8_t event)
109 {
110
111 return (hci_event_mask[event >> 5] & (1 << (event & 0x1f)));
112 }
113
114 static __inline void
115 hci_security_set_opcode(uint16_t opcode)
116 {
117
118 hci_opcode_mask[opcode >> 5] |= (1 << (opcode & 0x1f));
119 }
120
121 static __inline void
122 hci_security_clr_event(uint8_t event)
123 {
124
125 hci_event_mask[event >> 5] &= ~(1 << (event & 0x1f));
126 }
127
128 static int
129 hci_security_init(void)
130 {
131
132 if (hci_event_mask)
133 return 0;
134
135 // XXX could wait?
136 hci_event_mask = malloc(HCI_EVENT_MASK_SIZE + HCI_OPCODE_MASK_SIZE,
137 M_BLUETOOTH, M_NOWAIT | M_ZERO);
138 if (hci_event_mask == NULL) {
139 DPRINTF("no memory\n");
140 return ENOMEM;
141 }
142
143 hci_opcode_mask = hci_event_mask + HCI_EVENT_MASK_SIZE;
144
145 /* Events */
146 /* enable all but a few critical events */
147 memset(hci_event_mask, 0xff,
148 HCI_EVENT_MASK_SIZE * sizeof(*hci_event_mask));
149 hci_security_clr_event(HCI_EVENT_RETURN_LINK_KEYS);
150 hci_security_clr_event(HCI_EVENT_LINK_KEY_NOTIFICATION);
151 hci_security_clr_event(HCI_EVENT_VENDOR);
152
153 /* Commands - Link control */
154 hci_security_set_opcode(HCI_CMD_INQUIRY);
155 hci_security_set_opcode(HCI_CMD_REMOTE_NAME_REQ);
156 hci_security_set_opcode(HCI_CMD_READ_REMOTE_FEATURES);
157 hci_security_set_opcode(HCI_CMD_READ_REMOTE_EXTENDED_FEATURES);
158 hci_security_set_opcode(HCI_CMD_READ_REMOTE_VER_INFO);
159 hci_security_set_opcode(HCI_CMD_READ_CLOCK_OFFSET);
160 hci_security_set_opcode(HCI_CMD_READ_LMP_HANDLE);
161
162 /* Commands - Link policy */
163 hci_security_set_opcode(HCI_CMD_ROLE_DISCOVERY);
164 hci_security_set_opcode(HCI_CMD_READ_LINK_POLICY_SETTINGS);
165 hci_security_set_opcode(HCI_CMD_READ_DEFAULT_LINK_POLICY_SETTINGS);
166
167 /* Commands - Host controller and baseband */
168 hci_security_set_opcode(HCI_CMD_READ_PIN_TYPE);
169 hci_security_set_opcode(HCI_CMD_READ_LOCAL_NAME);
170 hci_security_set_opcode(HCI_CMD_READ_CON_ACCEPT_TIMEOUT);
171 hci_security_set_opcode(HCI_CMD_READ_PAGE_TIMEOUT);
172 hci_security_set_opcode(HCI_CMD_READ_SCAN_ENABLE);
173 hci_security_set_opcode(HCI_CMD_READ_PAGE_SCAN_ACTIVITY);
174 hci_security_set_opcode(HCI_CMD_READ_INQUIRY_SCAN_ACTIVITY);
175 hci_security_set_opcode(HCI_CMD_READ_AUTH_ENABLE);
176 hci_security_set_opcode(HCI_CMD_READ_ENCRYPTION_MODE);
177 hci_security_set_opcode(HCI_CMD_READ_UNIT_CLASS);
178 hci_security_set_opcode(HCI_CMD_READ_VOICE_SETTING);
179 hci_security_set_opcode(HCI_CMD_READ_AUTO_FLUSH_TIMEOUT);
180 hci_security_set_opcode(HCI_CMD_READ_NUM_BROADCAST_RETRANS);
181 hci_security_set_opcode(HCI_CMD_READ_HOLD_MODE_ACTIVITY);
182 hci_security_set_opcode(HCI_CMD_READ_XMIT_LEVEL);
183 hci_security_set_opcode(HCI_CMD_READ_SCO_FLOW_CONTROL);
184 hci_security_set_opcode(HCI_CMD_READ_LINK_SUPERVISION_TIMEOUT);
185 hci_security_set_opcode(HCI_CMD_READ_NUM_SUPPORTED_IAC);
186 hci_security_set_opcode(HCI_CMD_READ_IAC_LAP);
187 hci_security_set_opcode(HCI_CMD_READ_PAGE_SCAN_PERIOD);
188 hci_security_set_opcode(HCI_CMD_READ_PAGE_SCAN);
189 hci_security_set_opcode(HCI_CMD_READ_INQUIRY_SCAN_TYPE);
190 hci_security_set_opcode(HCI_CMD_READ_INQUIRY_MODE);
191 hci_security_set_opcode(HCI_CMD_READ_PAGE_SCAN_TYPE);
192 hci_security_set_opcode(HCI_CMD_READ_AFH_ASSESSMENT);
193
194 /* Commands - Informational */
195 hci_security_set_opcode(HCI_CMD_READ_LOCAL_VER);
196 hci_security_set_opcode(HCI_CMD_READ_LOCAL_COMMANDS);
197 hci_security_set_opcode(HCI_CMD_READ_LOCAL_FEATURES);
198 hci_security_set_opcode(HCI_CMD_READ_LOCAL_EXTENDED_FEATURES);
199 hci_security_set_opcode(HCI_CMD_READ_BUFFER_SIZE);
200 hci_security_set_opcode(HCI_CMD_READ_COUNTRY_CODE);
201 hci_security_set_opcode(HCI_CMD_READ_BDADDR);
202
203 /* Commands - Status */
204 hci_security_set_opcode(HCI_CMD_READ_FAILED_CONTACT_CNTR);
205 hci_security_set_opcode(HCI_CMD_READ_LINK_QUALITY);
206 hci_security_set_opcode(HCI_CMD_READ_RSSI);
207 hci_security_set_opcode(HCI_CMD_READ_AFH_CHANNEL_MAP);
208 hci_security_set_opcode(HCI_CMD_READ_CLOCK);
209
210 /* Commands - Testing */
211 hci_security_set_opcode(HCI_CMD_READ_LOOPBACK_MODE);
212
213 return 0;
214 }
215
216 /*
217 * When command packet reaches the device, we can drop
218 * it from the socket buffer (called from hci_output_acl)
219 */
220 void
221 hci_drop(void *arg)
222 {
223 struct socket *so = arg;
224
225 sbdroprecord(&so->so_snd);
226 sowwakeup(so);
227 }
228
229 /*
230 * HCI socket is going away and has some pending packets. We let them
231 * go by design, but remove the context pointer as it will be invalid
232 * and we no longer need to be notified.
233 */
234 static void
235 hci_cmdwait_flush(struct socket *so)
236 {
237 struct hci_unit *unit;
238 struct socket *ctx;
239 struct mbuf *m;
240
241 DPRINTF("flushing %p\n", so);
242
243 SIMPLEQ_FOREACH(unit, &hci_unit_list, hci_next) {
244 m = MBUFQ_FIRST(&unit->hci_cmdwait);
245 while (m != NULL) {
246 ctx = M_GETCTX(m, struct socket *);
247 if (ctx == so)
248 M_SETCTX(m, NULL);
249
250 m = MBUFQ_NEXT(m);
251 }
252 }
253 }
254
255 /*
256 * HCI send packet
257 * This came from userland, so check it out.
258 */
259 static int
260 hci_send(struct hci_pcb *pcb, struct mbuf *m, bdaddr_t *addr)
261 {
262 struct hci_unit *unit;
263 struct mbuf *m0;
264 hci_cmd_hdr_t hdr;
265 int err;
266
267 KASSERT(m);
268 KASSERT(addr);
269
270 /* wants at least a header to start with */
271 if (m->m_pkthdr.len < sizeof(hdr)) {
272 err = EMSGSIZE;
273 goto bad;
274 }
275 m_copydata(m, 0, sizeof(hdr), &hdr);
276
277 /* only allows CMD packets to be sent */
278 if (hdr.type != HCI_CMD_PKT) {
279 err = EINVAL;
280 goto bad;
281 }
282
283 /* validates packet length */
284 if (m->m_pkthdr.len != sizeof(hdr) + hdr.length) {
285 err = EMSGSIZE;
286 goto bad;
287 }
288
289 /* security checks for unprivileged users */
290 if ((pcb->hp_flags & HCI_PRIVILEGED) == 0
291 && (hci_security_check_opcode(le16toh(hdr.opcode)) == 0)) {
292 err = EPERM;
293 goto bad;
294 }
295
296 /* finds destination */
297 unit = hci_unit_lookup(addr);
298 if (unit == NULL) {
299 err = ENETDOWN;
300 goto bad;
301 }
302
303 /* makess a copy for precious to keep */
304 m0 = m_copypacket(m, M_DONTWAIT);
305 if (m0 == NULL) {
306 err = ENOMEM;
307 goto bad;
308 }
309 sbappendrecord(&pcb->hp_socket->so_snd, m0);
310 M_SETCTX(m, pcb->hp_socket); /* enable drop callback */
311
312 DPRINTFN(2, "(%s) opcode (%03x|%04x)\n", unit->hci_devname,
313 HCI_OGF(le16toh(hdr.opcode)), HCI_OCF(le16toh(hdr.opcode)));
314
315 /* Sendss it */
316 if (unit->hci_num_cmd_pkts == 0)
317 MBUFQ_ENQUEUE(&unit->hci_cmdwait, m);
318 else
319 hci_output_cmd(unit, m);
320
321 return 0;
322
323 bad:
324 DPRINTF("packet (%d bytes) not sent (error %d)\n",
325 m->m_pkthdr.len, err);
326 if (m) m_freem(m);
327 return err;
328 }
329
330 /*
331 * User Request.
332 * up is socket
333 * m is either
334 * optional mbuf chain containing message
335 * ioctl command (PRU_CONTROL)
336 * nam is either
337 * optional mbuf chain containing an address
338 * ioctl data (PRU_CONTROL)
339 * optionally, protocol number (PRU_ATTACH)
340 * ctl is optional mbuf chain containing socket options
341 * l is pointer to process requesting action (if any)
342 *
343 * we are responsible for disposing of m and ctl if
344 * they are mbuf chains
345 */
346 int
347 hci_usrreq(struct socket *up, int req, struct mbuf *m,
348 struct mbuf *nam, struct mbuf *ctl, struct lwp *l)
349 {
350 struct hci_pcb *pcb = (struct hci_pcb *)up->so_pcb;
351 struct sockaddr_bt *sa;
352 struct proc *p;
353 int err = 0, flags;
354
355 DPRINTFN(2, "%s\n", prurequests[req]);
356
357 p = (l == NULL) ? NULL : l->l_proc;
358
359 switch(req) {
360 case PRU_CONTROL:
361 return hci_ioctl((unsigned long)m, (void *)nam, p);
362
363 case PRU_PURGEIF:
364 return EOPNOTSUPP;
365
366 case PRU_ATTACH:
367 if (pcb)
368 return EINVAL;
369
370 flags = 0;
371 if (p != NULL && kauth_authorize_generic(p->p_cred,
372 KAUTH_GENERIC_ISSUSER,
373 &p->p_acflag)) {
374 err = hci_security_init();
375 if (err)
376 return err;
377 } else {
378 flags = HCI_PRIVILEGED;
379 }
380
381 err = soreserve(up, hci_sendspace, hci_recvspace);
382 if (err)
383 return err;
384
385 pcb = malloc(sizeof(struct hci_pcb), M_PCB, M_NOWAIT | M_ZERO);
386 if (pcb == NULL)
387 return ENOMEM;
388
389 up->so_pcb = pcb;
390 pcb->hp_socket = up;
391 pcb->hp_flags = flags;
392
393 /*
394 * Set default user filter. By default, socket only passes
395 * Command_Complete and Command_Status Events.
396 */
397 hci_filter_set(HCI_EVENT_COMMAND_COMPL, &pcb->hp_efilter);
398 hci_filter_set(HCI_EVENT_COMMAND_STATUS, &pcb->hp_efilter);
399 hci_filter_set(HCI_EVENT_PKT, &pcb->hp_pfilter);
400
401 LIST_INSERT_HEAD(&hci_pcb, pcb, hp_next);
402
403 return 0;
404 }
405
406 /* anything after here *requires* a pcb */
407 if (pcb == NULL) {
408 err = EINVAL;
409 goto release;
410 }
411
412 switch(req) {
413 case PRU_DISCONNECT:
414 bdaddr_copy(&pcb->hp_raddr, BDADDR_ANY);
415
416 /* XXX we cannot call soisdisconnected() here, as it sets
417 * SS_CANTRCVMORE and SS_CANTSENDMORE. The problem being,
418 * that soisconnected() does not clear these and if you
419 * try to reconnect this socket (which is permitted) you
420 * get a broken pipe when you try to write any data.
421 */
422 up->so_state &= ~SS_ISCONNECTED;
423 break;
424
425 case PRU_ABORT:
426 soisdisconnected(up);
427 /* fall through to */
428 case PRU_DETACH:
429 if (up->so_snd.sb_mb != NULL)
430 hci_cmdwait_flush(up);
431
432 up->so_pcb = NULL;
433 LIST_REMOVE(pcb, hp_next);
434 free(pcb, M_PCB);
435 return 0;
436
437 case PRU_BIND:
438 KASSERT(nam);
439 sa = mtod(nam, struct sockaddr_bt *);
440
441 if (sa->bt_len != sizeof(struct sockaddr_bt))
442 return EINVAL;
443
444 if (sa->bt_family != AF_BLUETOOTH)
445 return EAFNOSUPPORT;
446
447 bdaddr_copy(&pcb->hp_laddr, &sa->bt_bdaddr);
448
449 if (bdaddr_any(&sa->bt_bdaddr))
450 pcb->hp_flags |= HCI_PROMISCUOUS;
451 else
452 pcb->hp_flags &= ~HCI_PROMISCUOUS;
453
454 return 0;
455
456 case PRU_CONNECT:
457 KASSERT(nam);
458 sa = mtod(nam, struct sockaddr_bt *);
459
460 if (sa->bt_len != sizeof(struct sockaddr_bt))
461 return EINVAL;
462
463 if (sa->bt_family != AF_BLUETOOTH)
464 return EAFNOSUPPORT;
465
466 if (hci_unit_lookup(&sa->bt_bdaddr) == NULL)
467 return EADDRNOTAVAIL;
468
469 bdaddr_copy(&pcb->hp_raddr, &sa->bt_bdaddr);
470 soisconnected(up);
471 return 0;
472
473 case PRU_PEERADDR:
474 KASSERT(nam);
475 sa = mtod(nam, struct sockaddr_bt *);
476
477 memset(sa, 0, sizeof(struct sockaddr_bt));
478 nam->m_len =
479 sa->bt_len = sizeof(struct sockaddr_bt);
480 sa->bt_family = AF_BLUETOOTH;
481 bdaddr_copy(&sa->bt_bdaddr, &pcb->hp_raddr);
482 return 0;
483
484 case PRU_SOCKADDR:
485 KASSERT(nam);
486 sa = mtod(nam, struct sockaddr_bt *);
487
488 memset(sa, 0, sizeof(struct sockaddr_bt));
489 nam->m_len =
490 sa->bt_len = sizeof(struct sockaddr_bt);
491 sa->bt_family = AF_BLUETOOTH;
492 bdaddr_copy(&sa->bt_bdaddr, &pcb->hp_laddr);
493 return 0;
494
495 case PRU_SHUTDOWN:
496 socantsendmore(up);
497 break;
498
499 case PRU_SEND:
500 sa = NULL;
501 if (nam) {
502 sa = mtod(nam, struct sockaddr_bt *);
503
504 if (sa->bt_len != sizeof(struct sockaddr_bt)) {
505 err = EINVAL;
506 goto release;
507 }
508
509 if (sa->bt_family != AF_BLUETOOTH) {
510 err = EAFNOSUPPORT;
511 goto release;
512 }
513 }
514
515 if (ctl) /* have no use for this */
516 m_freem(ctl);
517
518 return hci_send(pcb, m, (sa ? &sa->bt_bdaddr : &pcb->hp_raddr));
519
520 case PRU_SENSE:
521 return 0; /* (no sense - Doh!) */
522
523 case PRU_RCVD:
524 case PRU_RCVOOB:
525 return EOPNOTSUPP; /* (no release) */
526
527 case PRU_ACCEPT:
528 case PRU_CONNECT2:
529 case PRU_LISTEN:
530 case PRU_SENDOOB:
531 case PRU_FASTTIMO:
532 case PRU_SLOWTIMO:
533 case PRU_PROTORCV:
534 case PRU_PROTOSEND:
535 err = EOPNOTSUPP;
536 break;
537
538 default:
539 UNKNOWN(req);
540 err = EOPNOTSUPP;
541 break;
542 }
543
544 release:
545 if (m) m_freem(m);
546 if (ctl) m_freem(ctl);
547 return err;
548 }
549
550 /*
551 * System is short on memory.
552 */
553 void
554 hci_drain(void)
555 {
556
557 /*
558 * We can give the security masks back, if there
559 * are no unprivileged sockets in operation..
560 */
561 if (hci_event_mask) {
562 struct hci_pcb *pcb;
563
564 LIST_FOREACH(pcb, &hci_pcb, hp_next) {
565 if ((pcb->hp_flags & HCI_PRIVILEGED) == 0)
566 break;
567 }
568
569 if (pcb == NULL) {
570 free(hci_event_mask, M_BLUETOOTH);
571 hci_event_mask = NULL;
572 hci_opcode_mask = NULL;
573 }
574 }
575 }
576
577 /*
578 * get/set socket options
579 */
580 int
581 hci_ctloutput(int req, struct socket *so, int level,
582 int optname, struct mbuf **opt)
583 {
584 struct hci_pcb *pcb = (struct hci_pcb *)so->so_pcb;
585 struct mbuf *m;
586 int err = 0;
587
588 DPRINTFN(2, "req %s\n", prcorequests[req]);
589
590 if (pcb == NULL)
591 return EINVAL;
592
593 if (level != BTPROTO_HCI)
594 return 0;
595
596 switch(req) {
597 case PRCO_GETOPT:
598 m = m_get(M_WAIT, MT_SOOPTS);
599 switch (optname) {
600 case SO_HCI_EVT_FILTER:
601 m->m_len = sizeof(struct hci_filter);
602 memcpy(mtod(m, void *), &pcb->hp_efilter, m->m_len);
603 break;
604
605 case SO_HCI_PKT_FILTER:
606 m->m_len = sizeof(struct hci_filter);
607 memcpy(mtod(m, void *), &pcb->hp_pfilter, m->m_len);
608 break;
609
610 case SO_HCI_DIRECTION:
611 m->m_len = sizeof(int);
612 if (pcb->hp_flags & HCI_DIRECTION)
613 *mtod(m, int *) = 1;
614 else
615 *mtod(m, int *) = 0;
616 break;
617
618 default:
619 err = EINVAL;
620 m_freem(m);
621 m = NULL;
622 break;
623 }
624 *opt = m;
625 break;
626
627 case PRCO_SETOPT:
628 m = *opt;
629 if (m) switch (optname) {
630 case SO_HCI_EVT_FILTER: /* set event filter */
631 m->m_len = min(m->m_len, sizeof(struct hci_filter));
632 memcpy(&pcb->hp_efilter, mtod(m, void *), m->m_len);
633 break;
634
635 case SO_HCI_PKT_FILTER: /* set packet filter */
636 m->m_len = min(m->m_len, sizeof(struct hci_filter));
637 memcpy(&pcb->hp_pfilter, mtod(m, void *), m->m_len);
638 break;
639
640 case SO_HCI_DIRECTION: /* request direction ctl messages */
641 if (*mtod(m, int *))
642 pcb->hp_flags |= HCI_DIRECTION;
643 else
644 pcb->hp_flags &= ~HCI_DIRECTION;
645 break;
646
647 default:
648 err = EINVAL;
649 break;
650 }
651 m_freem(m);
652 break;
653
654 default:
655 err = EINVAL;
656 break;
657 }
658
659 return err;
660 }
661
662 /*
663 * HCI mbuf tap routine
664 *
665 * copy packets to any raw HCI sockets that wish (and are
666 * permitted) to see them
667 */
668 void
669 hci_mtap(struct mbuf *m, struct hci_unit *unit)
670 {
671 struct hci_pcb *pcb;
672 struct mbuf *m0, *ctlmsg, **ctl;
673 struct sockaddr_bt sa;
674 uint8_t type;
675 uint8_t event;
676 uint16_t opcode;
677
678 KASSERT(m->m_len >= sizeof(type));
679
680 type = *mtod(m, uint8_t *);
681
682 memset(&sa, 0, sizeof(sa));
683 sa.bt_len = sizeof(struct sockaddr_bt);
684 sa.bt_family = AF_BLUETOOTH;
685 bdaddr_copy(&sa.bt_bdaddr, &unit->hci_bdaddr);
686
687 LIST_FOREACH(pcb, &hci_pcb, hp_next) {
688 /*
689 * filter according to source address
690 */
691 if ((pcb->hp_flags & HCI_PROMISCUOUS) == 0
692 && bdaddr_same(&pcb->hp_laddr, &sa.bt_bdaddr) == 0)
693 continue;
694
695 /*
696 * filter according to packet type filter
697 */
698 if (hci_filter_test(type, &pcb->hp_pfilter) == 0)
699 continue;
700
701 /*
702 * filter according to event/security filters
703 */
704 switch(type) {
705 case HCI_EVENT_PKT:
706 KASSERT(m->m_len >= sizeof(hci_event_hdr_t));
707
708 event = mtod(m, hci_event_hdr_t *)->event;
709
710 if (hci_filter_test(event, &pcb->hp_efilter) == 0)
711 continue;
712
713 if ((pcb->hp_flags & HCI_PRIVILEGED) == 0
714 && hci_security_check_event(event) == 0)
715 continue;
716 break;
717
718 case HCI_CMD_PKT:
719 KASSERT(m->m_len >= sizeof(hci_cmd_hdr_t));
720
721 opcode = le16toh(mtod(m, hci_cmd_hdr_t *)->opcode);
722
723 if ((pcb->hp_flags & HCI_PRIVILEGED) == 0
724 && hci_security_check_opcode(opcode) == 0)
725 continue;
726 break;
727
728 case HCI_ACL_DATA_PKT:
729 case HCI_SCO_DATA_PKT:
730 default:
731 if ((pcb->hp_flags & HCI_PRIVILEGED) == 0)
732 continue;
733
734 break;
735 }
736
737 /*
738 * create control messages
739 */
740 ctlmsg = NULL;
741 ctl = &ctlmsg;
742 if (pcb->hp_flags & HCI_DIRECTION) {
743 int dir = m->m_flags & M_LINK0 ? 1 : 0;
744
745 *ctl = sbcreatecontrol((caddr_t)&dir, sizeof(dir),
746 SCM_HCI_DIRECTION, BTPROTO_HCI);
747
748 if (*ctl != NULL)
749 ctl = &((*ctl)->m_next);
750 }
751
752 /*
753 * copy to socket
754 */
755 m0 = m_copypacket(m, M_DONTWAIT);
756 if (m0 && sbappendaddr(&pcb->hp_socket->so_rcv,
757 (struct sockaddr *)&sa, m0, ctlmsg)) {
758 sorwakeup(pcb->hp_socket);
759 } else {
760 m_freem(ctlmsg);
761 m_freem(m0);
762 }
763 }
764 }
765