root/netbt/hci_socket.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. hci_security_check_opcode
  2. hci_security_check_event
  3. hci_drop
  4. hci_cmdwait_flush
  5. hci_send
  6. hci_usrreq
  7. hci_ctloutput
  8. hci_mtap

    1 /*      $OpenBSD: hci_socket.c,v 1.3 2007/06/02 01:46:01 uwe Exp $      */
    2 /*      $NetBSD: hci_socket.c,v 1.10 2007/03/31 18:17:13 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 #include <sys/cdefs.h>
   35 
   36 /* load symbolic names */
   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  * HCI SOCK_RAW Sockets - for control of Bluetooth Devices
   58  *
   59  */
   60 
   61 /*
   62  * the raw HCI protocol control block
   63  */
   64 struct hci_pcb {
   65         struct socket           *hp_socket;     /* socket */
   66         unsigned int            hp_flags;       /* flags */
   67         bdaddr_t                hp_laddr;       /* local address */
   68         bdaddr_t                hp_raddr;       /* remote address */
   69         struct hci_filter       hp_efilter;     /* user event filter */
   70         struct hci_filter       hp_pfilter;     /* user packet filter */
   71         LIST_ENTRY(hci_pcb)     hp_next;        /* next HCI pcb */
   72 };
   73 
   74 /* hp_flags */
   75 #define HCI_PRIVILEGED          (1<<0)  /* no security filter for root */
   76 #define HCI_DIRECTION           (1<<1)  /* direction control messages */
   77 #define HCI_PROMISCUOUS         (1<<2)  /* listen to all units */
   78 
   79 LIST_HEAD(hci_pcb_list, hci_pcb) hci_pcb = LIST_HEAD_INITIALIZER(hci_pcb);
   80 
   81 /* sysctl defaults */
   82 int hci_sendspace = HCI_CMD_PKT_SIZE;
   83 int hci_recvspace = 4096;
   84 
   85 /*
   86  * Security filter routines for unprivileged users.
   87  *      Allow all but a few critical events, and only permit read commands.
   88  */
   89 
   90 static int
   91 hci_security_check_opcode(uint16_t opcode)
   92 {
   93 
   94         switch (opcode) {
   95         /* Link control */
   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         /* Link policy */
  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;       /* No command parameters */
  118 
  119         /* Host controller and baseband */
  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;       /* No command parameters */
  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;       /* No command parameters */
  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;       /* No command parameters */
  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;       /* No command parameters */
  152 
  153         /* Informational */
  154         case HCI_CMD_READ_LOCAL_VER:
  155         case HCI_CMD_READ_LOCAL_COMMANDS:
  156         case HCI_CMD_READ_LOCAL_FEATURES:
  157                 return 0;       /* No command parameters */
  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;       /* No command parameters */
  164 
  165         /* Status */
  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         /* Testing */
  178         case HCI_CMD_READ_LOOPBACK_MODE:
  179                 return 0;       /* No command parameters */
  180         }
  181 
  182         return -1;      /* disallowed */
  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;      /* disallowed */
  194         }
  195 
  196         return 0;       /* ok */
  197 }
  198 
  199 /*
  200  * When command packet reaches the device, we can drop
  201  * it from the socket buffer (called from hci_output_acl)
  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  * HCI socket is going away and has some pending packets. We let them
  214  * go by design, but remove the context pointer as it will be invalid
  215  * and we no longer need to be notified.
  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  * HCI send packet
  240  *     This came from userland, so check it out.
  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         /* wants at least a header to start with */
  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         /* only allows CMD packets to be sent */
  261         if (hdr.type != HCI_CMD_PKT) {
  262                 err = EINVAL;
  263                 goto bad;
  264         }
  265 
  266         /* validates packet length */
  267         if (m->m_pkthdr.len != sizeof(hdr) + hdr.length) {
  268                 err = EMSGSIZE;
  269                 goto bad;
  270         }
  271 
  272         /* security checks for unprivileged users */
  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         /* finds destination */
  280         unit = hci_unit_lookup(addr);
  281         if (unit == NULL) {
  282                 err = ENETDOWN;
  283                 goto bad;
  284         }
  285 
  286         /* makes a copy for precious to keep */
  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);    /* enable drop callback */
  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         /* Sendss it */
  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  * User Request.
  315  * up is socket
  316  * m is either
  317  *      optional mbuf chain containing message
  318  *      ioctl command (PRU_CONTROL)
  319  * nam is either
  320  *      optional mbuf chain containing an address
  321  *      ioctl data (PRU_CONTROL)
  322  *      optionally, protocol number (PRU_ATTACH)
  323  * ctl is optional mbuf chain containing socket options
  324  * l is pointer to process requesting action (if any)
  325  *
  326  * we are responsible for disposing of m and ctl if
  327  * they are mbuf chains
  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                   /* XXX */
  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                  * Set default user filter. By default, socket only passes
  366                  * Command_Complete and Command_Status Events.
  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         /* anything after here *requires* a pcb */
  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                 /* XXX we cannot call soisdisconnected() here, as it sets
  388                  * SS_CANTRCVMORE and SS_CANTSENDMORE. The problem being,
  389                  * that soisconnected() does not clear these and if you
  390                  * try to reconnect this socket (which is permitted) you
  391                  * get a broken pipe when you try to write any data.
  392                  */
  393                 up->so_state &= ~SS_ISCONNECTED;
  394                 break;
  395 
  396         case PRU_ABORT:
  397                 soisdisconnected(up);
  398                 /* fall through to */
  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) /* have no use for this */
  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;               /* (no sense - Doh!) */
  493 
  494         case PRU_RCVD:
  495         case PRU_RCVOOB:
  496                 return EOPNOTSUPP;      /* (no release) */
  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  * get/set socket options
  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                   /* XXX */
  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: /* set event 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: /* set packet 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:  /* request direction ctl messages */
  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  * HCI mbuf tap routine
  612  *
  613  * copy packets to any raw HCI sockets that wish (and are
  614  * permitted) to see them
  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                  * filter according to source address
  638                  */
  639                 if ((pcb->hp_flags & HCI_PROMISCUOUS) == 0
  640                     && bdaddr_same(&pcb->hp_laddr, &sa.bt_bdaddr) == 0)
  641                         continue;
  642 
  643                 /*
  644                  * filter according to packet type filter
  645                  */
  646                 if (hci_filter_test(type, &pcb->hp_pfilter) == 0)
  647                         continue;
  648 
  649                 /*
  650                  * filter according to event/security filters
  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                  * create control messages
  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                  * copy to socket
  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 }

/* [<][>][^][v][top][bottom][index][help] */