This source file includes following definitions.
- hci_security_check_opcode
- hci_security_check_event
- hci_drop
- hci_cmdwait_flush
- hci_send
- hci_usrreq
- hci_ctloutput
- hci_mtap
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 #include <sys/cdefs.h>
35
36
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/kernel.h>
45 #include <sys/mbuf.h>
46 #include <sys/proc.h>
47 #include <sys/protosw.h>
48 #include <sys/socket.h>
49 #include <sys/socketvar.h>
50 #include <sys/systm.h>
51
52 #include <netbt/bluetooth.h>
53 #include <netbt/hci.h>
54
55
56
57
58
59
60
61
62
63
64 struct hci_pcb {
65 struct socket *hp_socket;
66 unsigned int hp_flags;
67 bdaddr_t hp_laddr;
68 bdaddr_t hp_raddr;
69 struct hci_filter hp_efilter;
70 struct hci_filter hp_pfilter;
71 LIST_ENTRY(hci_pcb) hp_next;
72 };
73
74
75 #define HCI_PRIVILEGED (1<<0)
76 #define HCI_DIRECTION (1<<1)
77 #define HCI_PROMISCUOUS (1<<2)
78
79 LIST_HEAD(hci_pcb_list, hci_pcb) hci_pcb = LIST_HEAD_INITIALIZER(hci_pcb);
80
81
82 int hci_sendspace = HCI_CMD_PKT_SIZE;
83 int hci_recvspace = 4096;
84
85
86
87
88
89
90 static int
91 hci_security_check_opcode(uint16_t opcode)
92 {
93
94 switch (opcode) {
95
96 case HCI_CMD_INQUIRY:
97 return sizeof(hci_inquiry_cp);
98 case HCI_CMD_REMOTE_NAME_REQ:
99 return sizeof(hci_remote_name_req_cp);
100 case HCI_CMD_READ_REMOTE_FEATURES:
101 return sizeof(hci_read_remote_features_cp);
102 case HCI_CMD_READ_REMOTE_EXTENDED_FEATURES:
103 return sizeof(hci_read_remote_extended_features_cp);
104 case HCI_CMD_READ_REMOTE_VER_INFO:
105 return sizeof(hci_read_remote_ver_info_cp);
106 case HCI_CMD_READ_CLOCK_OFFSET:
107 return sizeof(hci_read_clock_offset_cp);
108 case HCI_CMD_READ_LMP_HANDLE:
109 return sizeof(hci_read_lmp_handle_cp);
110
111
112 case HCI_CMD_ROLE_DISCOVERY:
113 return sizeof(hci_role_discovery_cp);
114 case HCI_CMD_READ_LINK_POLICY_SETTINGS:
115 return sizeof(hci_read_link_policy_settings_cp);
116 case HCI_CMD_READ_DEFAULT_LINK_POLICY_SETTINGS:
117 return 0;
118
119
120 case HCI_CMD_READ_PIN_TYPE:
121 case HCI_CMD_READ_LOCAL_NAME:
122 case HCI_CMD_READ_CON_ACCEPT_TIMEOUT:
123 case HCI_CMD_READ_PAGE_TIMEOUT:
124 case HCI_CMD_READ_SCAN_ENABLE:
125 case HCI_CMD_READ_PAGE_SCAN_ACTIVITY:
126 case HCI_CMD_READ_INQUIRY_SCAN_ACTIVITY:
127 case HCI_CMD_READ_AUTH_ENABLE:
128 case HCI_CMD_READ_ENCRYPTION_MODE:
129 case HCI_CMD_READ_UNIT_CLASS:
130 case HCI_CMD_READ_VOICE_SETTING:
131 return 0;
132 case HCI_CMD_READ_AUTO_FLUSH_TIMEOUT:
133 return sizeof(hci_read_auto_flush_timeout_cp);
134 case HCI_CMD_READ_NUM_BROADCAST_RETRANS:
135 case HCI_CMD_READ_HOLD_MODE_ACTIVITY:
136 return 0;
137 case HCI_CMD_READ_XMIT_LEVEL:
138 return sizeof(hci_read_xmit_level_cp);
139 case HCI_CMD_READ_SCO_FLOW_CONTROL:
140 return 0;
141 case HCI_CMD_READ_LINK_SUPERVISION_TIMEOUT:
142 return sizeof(hci_read_link_supervision_timeout_cp);
143 case HCI_CMD_READ_NUM_SUPPORTED_IAC:
144 case HCI_CMD_READ_IAC_LAP:
145 case HCI_CMD_READ_PAGE_SCAN_PERIOD:
146 case HCI_CMD_READ_PAGE_SCAN:
147 case HCI_CMD_READ_INQUIRY_SCAN_TYPE:
148 case HCI_CMD_READ_INQUIRY_MODE:
149 case HCI_CMD_READ_PAGE_SCAN_TYPE:
150 case HCI_CMD_READ_AFH_ASSESSMENT:
151 return 0;
152
153
154 case HCI_CMD_READ_LOCAL_VER:
155 case HCI_CMD_READ_LOCAL_COMMANDS:
156 case HCI_CMD_READ_LOCAL_FEATURES:
157 return 0;
158 case HCI_CMD_READ_LOCAL_EXTENDED_FEATURES:
159 return sizeof(hci_read_local_extended_features_cp);
160 case HCI_CMD_READ_BUFFER_SIZE:
161 case HCI_CMD_READ_COUNTRY_CODE:
162 case HCI_CMD_READ_BDADDR:
163 return 0;
164
165
166 case HCI_CMD_READ_FAILED_CONTACT_CNTR:
167 return sizeof(hci_read_failed_contact_cntr_cp);
168 case HCI_CMD_READ_LINK_QUALITY:
169 return sizeof(hci_read_link_quality_cp);
170 case HCI_CMD_READ_RSSI:
171 return sizeof(hci_read_rssi_cp);
172 case HCI_CMD_READ_AFH_CHANNEL_MAP:
173 return sizeof(hci_read_afh_channel_map_cp);
174 case HCI_CMD_READ_CLOCK:
175 return sizeof(hci_read_clock_cp);
176
177
178 case HCI_CMD_READ_LOOPBACK_MODE:
179 return 0;
180 }
181
182 return -1;
183 }
184
185 static int
186 hci_security_check_event(uint8_t event)
187 {
188
189 switch (event) {
190 case HCI_EVENT_RETURN_LINK_KEYS:
191 case HCI_EVENT_LINK_KEY_NOTIFICATION:
192 case HCI_EVENT_VENDOR:
193 return -1;
194 }
195
196 return 0;
197 }
198
199
200
201
202
203 void
204 hci_drop(void *arg)
205 {
206 struct socket *so = arg;
207
208 sbdroprecord(&so->so_snd);
209 sowwakeup(so);
210 }
211
212
213
214
215
216
217 static void
218 hci_cmdwait_flush(struct socket *so)
219 {
220 struct hci_unit *unit;
221 struct socket *ctx;
222 struct mbuf *m;
223
224 DPRINTF("flushing %p\n", so);
225
226 TAILQ_FOREACH(unit, &hci_unit_list, hci_next) {
227 IF_POLL(&unit->hci_cmdwait, m);
228 while (m != NULL) {
229 ctx = M_GETCTX(m, struct socket *);
230 if (ctx == so)
231 M_SETCTX(m, NULL);
232
233 m = m->m_nextpkt;
234 }
235 }
236 }
237
238
239
240
241
242 static int
243 hci_send(struct hci_pcb *pcb, struct mbuf *m, bdaddr_t *addr)
244 {
245 struct hci_unit *unit;
246 struct mbuf *m0;
247 hci_cmd_hdr_t hdr;
248 int err;
249
250 KASSERT(m != NULL);
251 KASSERT(addr != NULL);
252
253
254 if (m->m_pkthdr.len < sizeof(hdr)) {
255 err = EMSGSIZE;
256 goto bad;
257 }
258 m_copydata(m, 0, sizeof(hdr), (caddr_t)&hdr);
259
260
261 if (hdr.type != HCI_CMD_PKT) {
262 err = EINVAL;
263 goto bad;
264 }
265
266
267 if (m->m_pkthdr.len != sizeof(hdr) + hdr.length) {
268 err = EMSGSIZE;
269 goto bad;
270 }
271
272
273 if ((pcb->hp_flags & HCI_PRIVILEGED) == 0
274 && hci_security_check_opcode(letoh16(hdr.opcode)) != hdr.length) {
275 err = EPERM;
276 goto bad;
277 }
278
279
280 unit = hci_unit_lookup(addr);
281 if (unit == NULL) {
282 err = ENETDOWN;
283 goto bad;
284 }
285
286
287 m0 = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
288 if (m0 == NULL) {
289 err = ENOMEM;
290 goto bad;
291 }
292 sbappendrecord(&pcb->hp_socket->so_snd, m0);
293 M_SETCTX(m, pcb->hp_socket);
294
295 DPRINTFN(2, "(%s) opcode (%03x|%04x)\n", unit->hci_devname,
296 HCI_OGF(letoh16(hdr.opcode)), HCI_OCF(letoh16(hdr.opcode)));
297
298
299 if (unit->hci_num_cmd_pkts == 0)
300 IF_ENQUEUE(&unit->hci_cmdwait, m);
301 else
302 hci_output_cmd(unit, m);
303
304 return 0;
305
306 bad:
307 DPRINTF("packet (%d bytes) not sent (error %d)\n",
308 m->m_pkthdr.len, err);
309 if (m) m_freem(m);
310 return err;
311 }
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329 int
330 hci_usrreq(struct socket *up, int req, struct mbuf *m,
331 struct mbuf *nam, struct mbuf *ctl)
332 {
333 struct hci_pcb *pcb = (struct hci_pcb *)up->so_pcb;
334 struct sockaddr_bt *sa;
335 int err = 0;
336
337 #ifdef notyet
338 DPRINTFN(2, "%s\n", prurequests[req]);
339 #endif
340
341 switch(req) {
342 case PRU_CONTROL:
343 return hci_ioctl((unsigned long)m, (void *)nam, curproc);
344
345 case PRU_ATTACH:
346 if (pcb)
347 return EINVAL;
348
349 err = soreserve(up, hci_sendspace, hci_recvspace);
350 if (err)
351 return err;
352
353 pcb = malloc(sizeof *pcb, M_PCB, M_NOWAIT);
354 if (pcb == NULL)
355 return ENOMEM;
356 bzero(pcb, sizeof *pcb);
357
358 up->so_pcb = pcb;
359 pcb->hp_socket = up;
360
361 if (curproc == NULL || suser(curproc, 0) == 0)
362 pcb->hp_flags |= HCI_PRIVILEGED;
363
364
365
366
367
368 hci_filter_set(HCI_EVENT_COMMAND_COMPL, &pcb->hp_efilter);
369 hci_filter_set(HCI_EVENT_COMMAND_STATUS, &pcb->hp_efilter);
370 hci_filter_set(HCI_EVENT_PKT, &pcb->hp_pfilter);
371
372 LIST_INSERT_HEAD(&hci_pcb, pcb, hp_next);
373
374 return 0;
375 }
376
377
378 if (pcb == NULL) {
379 err = EINVAL;
380 goto release;
381 }
382
383 switch(req) {
384 case PRU_DISCONNECT:
385 bdaddr_copy(&pcb->hp_raddr, BDADDR_ANY);
386
387
388
389
390
391
392
393 up->so_state &= ~SS_ISCONNECTED;
394 break;
395
396 case PRU_ABORT:
397 soisdisconnected(up);
398
399 case PRU_DETACH:
400 if (up->so_snd.sb_mb != NULL)
401 hci_cmdwait_flush(up);
402
403 up->so_pcb = NULL;
404 LIST_REMOVE(pcb, hp_next);
405 free(pcb, M_PCB);
406 return 0;
407
408 case PRU_BIND:
409 KASSERT(nam != NULL);
410 sa = mtod(nam, struct sockaddr_bt *);
411
412 if (sa->bt_len != sizeof(struct sockaddr_bt))
413 return EINVAL;
414
415 if (sa->bt_family != AF_BLUETOOTH)
416 return EAFNOSUPPORT;
417
418 bdaddr_copy(&pcb->hp_laddr, &sa->bt_bdaddr);
419
420 if (bdaddr_any(&sa->bt_bdaddr))
421 pcb->hp_flags |= HCI_PROMISCUOUS;
422 else
423 pcb->hp_flags &= ~HCI_PROMISCUOUS;
424
425 return 0;
426
427 case PRU_CONNECT:
428 KASSERT(nam != NULL);
429 sa = mtod(nam, struct sockaddr_bt *);
430
431 if (sa->bt_len != sizeof(struct sockaddr_bt))
432 return EINVAL;
433
434 if (sa->bt_family != AF_BLUETOOTH)
435 return EAFNOSUPPORT;
436
437 if (hci_unit_lookup(&sa->bt_bdaddr) == NULL)
438 return EADDRNOTAVAIL;
439
440 bdaddr_copy(&pcb->hp_raddr, &sa->bt_bdaddr);
441 soisconnected(up);
442 return 0;
443
444 case PRU_PEERADDR:
445 KASSERT(nam != NULL);
446 sa = mtod(nam, struct sockaddr_bt *);
447
448 memset(sa, 0, sizeof(struct sockaddr_bt));
449 nam->m_len =
450 sa->bt_len = sizeof(struct sockaddr_bt);
451 sa->bt_family = AF_BLUETOOTH;
452 bdaddr_copy(&sa->bt_bdaddr, &pcb->hp_raddr);
453 return 0;
454
455 case PRU_SOCKADDR:
456 KASSERT(nam != NULL);
457 sa = mtod(nam, struct sockaddr_bt *);
458
459 memset(sa, 0, sizeof(struct sockaddr_bt));
460 nam->m_len =
461 sa->bt_len = sizeof(struct sockaddr_bt);
462 sa->bt_family = AF_BLUETOOTH;
463 bdaddr_copy(&sa->bt_bdaddr, &pcb->hp_laddr);
464 return 0;
465
466 case PRU_SHUTDOWN:
467 socantsendmore(up);
468 break;
469
470 case PRU_SEND:
471 sa = NULL;
472 if (nam) {
473 sa = mtod(nam, struct sockaddr_bt *);
474
475 if (sa->bt_len != sizeof(struct sockaddr_bt)) {
476 err = EINVAL;
477 goto release;
478 }
479
480 if (sa->bt_family != AF_BLUETOOTH) {
481 err = EAFNOSUPPORT;
482 goto release;
483 }
484 }
485
486 if (ctl)
487 m_freem(ctl);
488
489 return hci_send(pcb, m, (sa ? &sa->bt_bdaddr : &pcb->hp_raddr));
490
491 case PRU_SENSE:
492 return 0;
493
494 case PRU_RCVD:
495 case PRU_RCVOOB:
496 return EOPNOTSUPP;
497
498 case PRU_ACCEPT:
499 case PRU_CONNECT2:
500 case PRU_LISTEN:
501 case PRU_SENDOOB:
502 case PRU_FASTTIMO:
503 case PRU_SLOWTIMO:
504 case PRU_PROTORCV:
505 case PRU_PROTOSEND:
506 err = EOPNOTSUPP;
507 break;
508
509 default:
510 UNKNOWN(req);
511 err = EOPNOTSUPP;
512 break;
513 }
514
515 release:
516 if (m)
517 m_freem(m);
518 if (ctl)
519 m_freem(ctl);
520 return err;
521 }
522
523
524
525
526 int
527 hci_ctloutput(int req, struct socket *so, int level,
528 int optname, struct mbuf **opt)
529 {
530 struct hci_pcb *pcb = (struct hci_pcb *)so->so_pcb;
531 struct mbuf *m;
532 int err = 0;
533
534 #ifdef notyet
535 DPRINTFN(2, "req %s\n", prcorequests[req]);
536 #endif
537
538 if (pcb == NULL)
539 return EINVAL;
540
541 if (level != BTPROTO_HCI)
542 return ENOPROTOOPT;
543
544 switch(req) {
545 case PRCO_GETOPT:
546 m = m_get(M_WAIT, MT_SOOPTS);
547 switch (optname) {
548 case SO_HCI_EVT_FILTER:
549 m->m_len = sizeof(struct hci_filter);
550 memcpy(mtod(m, void *), &pcb->hp_efilter, m->m_len);
551 break;
552
553 case SO_HCI_PKT_FILTER:
554 m->m_len = sizeof(struct hci_filter);
555 memcpy(mtod(m, void *), &pcb->hp_pfilter, m->m_len);
556 break;
557
558 case SO_HCI_DIRECTION:
559 m->m_len = sizeof(int);
560 if (pcb->hp_flags & HCI_DIRECTION)
561 *mtod(m, int *) = 1;
562 else
563 *mtod(m, int *) = 0;
564 break;
565
566 default:
567 err = ENOPROTOOPT;
568 m_freem(m);
569 m = NULL;
570 break;
571 }
572 *opt = m;
573 break;
574
575 case PRCO_SETOPT:
576 m = *opt;
577 if (m) switch (optname) {
578 case SO_HCI_EVT_FILTER:
579 m->m_len = min(m->m_len, sizeof(struct hci_filter));
580 memcpy(&pcb->hp_efilter, mtod(m, void *), m->m_len);
581 break;
582
583 case SO_HCI_PKT_FILTER:
584 m->m_len = min(m->m_len, sizeof(struct hci_filter));
585 memcpy(&pcb->hp_pfilter, mtod(m, void *), m->m_len);
586 break;
587
588 case SO_HCI_DIRECTION:
589 if (*mtod(m, int *))
590 pcb->hp_flags |= HCI_DIRECTION;
591 else
592 pcb->hp_flags &= ~HCI_DIRECTION;
593 break;
594
595 default:
596 err = ENOPROTOOPT;
597 break;
598 }
599 m_freem(m);
600 break;
601
602 default:
603 err = ENOPROTOOPT;
604 break;
605 }
606
607 return err;
608 }
609
610
611
612
613
614
615
616 void
617 hci_mtap(struct mbuf *m, struct hci_unit *unit)
618 {
619 struct hci_pcb *pcb;
620 struct mbuf *m0, *ctlmsg, **ctl;
621 struct sockaddr_bt sa;
622 uint8_t type;
623 uint8_t event;
624 uint16_t opcode;
625
626 KASSERT(m->m_len >= sizeof(type));
627
628 type = *mtod(m, uint8_t *);
629
630 memset(&sa, 0, sizeof(sa));
631 sa.bt_len = sizeof(struct sockaddr_bt);
632 sa.bt_family = AF_BLUETOOTH;
633 bdaddr_copy(&sa.bt_bdaddr, &unit->hci_bdaddr);
634
635 LIST_FOREACH(pcb, &hci_pcb, hp_next) {
636
637
638
639 if ((pcb->hp_flags & HCI_PROMISCUOUS) == 0
640 && bdaddr_same(&pcb->hp_laddr, &sa.bt_bdaddr) == 0)
641 continue;
642
643
644
645
646 if (hci_filter_test(type, &pcb->hp_pfilter) == 0)
647 continue;
648
649
650
651
652 switch(type) {
653 case HCI_EVENT_PKT:
654 KASSERT(m->m_len >= sizeof(hci_event_hdr_t));
655
656 event = mtod(m, hci_event_hdr_t *)->event;
657
658 if (hci_filter_test(event, &pcb->hp_efilter) == 0)
659 continue;
660
661 if ((pcb->hp_flags & HCI_PRIVILEGED) == 0
662 && hci_security_check_event(event) == -1)
663 continue;
664 break;
665
666 case HCI_CMD_PKT:
667 KASSERT(m->m_len >= sizeof(hci_cmd_hdr_t));
668
669 opcode = letoh16(mtod(m, hci_cmd_hdr_t *)->opcode);
670
671 if ((pcb->hp_flags & HCI_PRIVILEGED) == 0
672 && hci_security_check_opcode(opcode) == -1)
673 continue;
674 break;
675
676 case HCI_ACL_DATA_PKT:
677 case HCI_SCO_DATA_PKT:
678 default:
679 if ((pcb->hp_flags & HCI_PRIVILEGED) == 0)
680 continue;
681
682 break;
683 }
684
685
686
687
688 ctlmsg = NULL;
689 ctl = &ctlmsg;
690 if (pcb->hp_flags & HCI_DIRECTION) {
691 int dir = m->m_flags & M_LINK0 ? 1 : 0;
692
693 *ctl = sbcreatecontrol((void *)&dir, sizeof(dir),
694 SCM_HCI_DIRECTION, BTPROTO_HCI);
695
696 if (*ctl != NULL)
697 ctl = &((*ctl)->m_next);
698 }
699
700
701
702
703 m0 = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
704 if (m0 && sbappendaddr(&pcb->hp_socket->so_rcv,
705 (struct sockaddr *)&sa, m0, ctlmsg)) {
706 sorwakeup(pcb->hp_socket);
707 } else {
708 m_freem(ctlmsg);
709 m_freem(m0);
710 }
711 }
712 }