Back to home page

OSCL-LXR

 
 

    


0001 /*
0002    BNEP implementation for Linux Bluetooth stack (BlueZ).
0003    Copyright (C) 2001-2002 Inventel Systemes
0004    Written 2001-2002 by
0005     Clément Moreau <clement.moreau@inventel.fr>
0006     David Libault  <david.libault@inventel.fr>
0007 
0008    Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
0009 
0010    This program is free software; you can redistribute it and/or modify
0011    it under the terms of the GNU General Public License version 2 as
0012    published by the Free Software Foundation;
0013 
0014    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
0015    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
0017    IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
0018    CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
0019    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
0020    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
0021    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
0022 
0023    ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
0024    COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
0025    SOFTWARE IS DISCLAIMED.
0026 */
0027 
0028 #include <linux/module.h>
0029 #include <linux/kthread.h>
0030 #include <linux/file.h>
0031 #include <linux/etherdevice.h>
0032 #include <asm/unaligned.h>
0033 
0034 #include <net/bluetooth/bluetooth.h>
0035 #include <net/bluetooth/l2cap.h>
0036 #include <net/bluetooth/hci_core.h>
0037 
0038 #include "bnep.h"
0039 
0040 #define VERSION "1.3"
0041 
0042 static bool compress_src = true;
0043 static bool compress_dst = true;
0044 
0045 static LIST_HEAD(bnep_session_list);
0046 static DECLARE_RWSEM(bnep_session_sem);
0047 
0048 static struct bnep_session *__bnep_get_session(u8 *dst)
0049 {
0050     struct bnep_session *s;
0051 
0052     BT_DBG("");
0053 
0054     list_for_each_entry(s, &bnep_session_list, list)
0055         if (ether_addr_equal(dst, s->eh.h_source))
0056             return s;
0057 
0058     return NULL;
0059 }
0060 
0061 static void __bnep_link_session(struct bnep_session *s)
0062 {
0063     list_add(&s->list, &bnep_session_list);
0064 }
0065 
0066 static void __bnep_unlink_session(struct bnep_session *s)
0067 {
0068     list_del(&s->list);
0069 }
0070 
0071 static int bnep_send(struct bnep_session *s, void *data, size_t len)
0072 {
0073     struct socket *sock = s->sock;
0074     struct kvec iv = { data, len };
0075 
0076     return kernel_sendmsg(sock, &s->msg, &iv, 1, len);
0077 }
0078 
0079 static int bnep_send_rsp(struct bnep_session *s, u8 ctrl, u16 resp)
0080 {
0081     struct bnep_control_rsp rsp;
0082     rsp.type = BNEP_CONTROL;
0083     rsp.ctrl = ctrl;
0084     rsp.resp = htons(resp);
0085     return bnep_send(s, &rsp, sizeof(rsp));
0086 }
0087 
0088 #ifdef CONFIG_BT_BNEP_PROTO_FILTER
0089 static inline void bnep_set_default_proto_filter(struct bnep_session *s)
0090 {
0091     /* (IPv4, ARP)  */
0092     s->proto_filter[0].start = ETH_P_IP;
0093     s->proto_filter[0].end   = ETH_P_ARP;
0094     /* (RARP, AppleTalk) */
0095     s->proto_filter[1].start = ETH_P_RARP;
0096     s->proto_filter[1].end   = ETH_P_AARP;
0097     /* (IPX, IPv6) */
0098     s->proto_filter[2].start = ETH_P_IPX;
0099     s->proto_filter[2].end   = ETH_P_IPV6;
0100 }
0101 #endif
0102 
0103 static int bnep_ctrl_set_netfilter(struct bnep_session *s, __be16 *data, int len)
0104 {
0105     int n;
0106 
0107     if (len < 2)
0108         return -EILSEQ;
0109 
0110     n = get_unaligned_be16(data);
0111     data++;
0112     len -= 2;
0113 
0114     if (len < n)
0115         return -EILSEQ;
0116 
0117     BT_DBG("filter len %d", n);
0118 
0119 #ifdef CONFIG_BT_BNEP_PROTO_FILTER
0120     n /= 4;
0121     if (n <= BNEP_MAX_PROTO_FILTERS) {
0122         struct bnep_proto_filter *f = s->proto_filter;
0123         int i;
0124 
0125         for (i = 0; i < n; i++) {
0126             f[i].start = get_unaligned_be16(data++);
0127             f[i].end   = get_unaligned_be16(data++);
0128 
0129             BT_DBG("proto filter start %u end %u",
0130                    f[i].start, f[i].end);
0131         }
0132 
0133         if (i < BNEP_MAX_PROTO_FILTERS)
0134             memset(f + i, 0, sizeof(*f));
0135 
0136         if (n == 0)
0137             bnep_set_default_proto_filter(s);
0138 
0139         bnep_send_rsp(s, BNEP_FILTER_NET_TYPE_RSP, BNEP_SUCCESS);
0140     } else {
0141         bnep_send_rsp(s, BNEP_FILTER_NET_TYPE_RSP, BNEP_FILTER_LIMIT_REACHED);
0142     }
0143 #else
0144     bnep_send_rsp(s, BNEP_FILTER_NET_TYPE_RSP, BNEP_FILTER_UNSUPPORTED_REQ);
0145 #endif
0146     return 0;
0147 }
0148 
0149 static int bnep_ctrl_set_mcfilter(struct bnep_session *s, u8 *data, int len)
0150 {
0151     int n;
0152 
0153     if (len < 2)
0154         return -EILSEQ;
0155 
0156     n = get_unaligned_be16(data);
0157     data += 2;
0158     len -= 2;
0159 
0160     if (len < n)
0161         return -EILSEQ;
0162 
0163     BT_DBG("filter len %d", n);
0164 
0165 #ifdef CONFIG_BT_BNEP_MC_FILTER
0166     n /= (ETH_ALEN * 2);
0167 
0168     if (n > 0) {
0169         int i;
0170 
0171         s->mc_filter = 0;
0172 
0173         /* Always send broadcast */
0174         set_bit(bnep_mc_hash(s->dev->broadcast), (ulong *) &s->mc_filter);
0175 
0176         /* Add address ranges to the multicast hash */
0177         for (; n > 0; n--) {
0178             u8 a1[6], *a2;
0179 
0180             memcpy(a1, data, ETH_ALEN);
0181             data += ETH_ALEN;
0182             a2 = data;
0183             data += ETH_ALEN;
0184 
0185             BT_DBG("mc filter %pMR -> %pMR", a1, a2);
0186 
0187             /* Iterate from a1 to a2 */
0188             set_bit(bnep_mc_hash(a1), (ulong *) &s->mc_filter);
0189             while (memcmp(a1, a2, 6) < 0 && s->mc_filter != ~0LL) {
0190                 /* Increment a1 */
0191                 i = 5;
0192                 while (i >= 0 && ++a1[i--] == 0)
0193                     ;
0194 
0195                 set_bit(bnep_mc_hash(a1), (ulong *) &s->mc_filter);
0196             }
0197         }
0198     }
0199 
0200     BT_DBG("mc filter hash 0x%llx", s->mc_filter);
0201 
0202     bnep_send_rsp(s, BNEP_FILTER_MULTI_ADDR_RSP, BNEP_SUCCESS);
0203 #else
0204     bnep_send_rsp(s, BNEP_FILTER_MULTI_ADDR_RSP, BNEP_FILTER_UNSUPPORTED_REQ);
0205 #endif
0206     return 0;
0207 }
0208 
0209 static int bnep_rx_control(struct bnep_session *s, void *data, int len)
0210 {
0211     u8  cmd = *(u8 *)data;
0212     int err = 0;
0213 
0214     data++;
0215     len--;
0216 
0217     switch (cmd) {
0218     case BNEP_CMD_NOT_UNDERSTOOD:
0219     case BNEP_SETUP_CONN_RSP:
0220     case BNEP_FILTER_NET_TYPE_RSP:
0221     case BNEP_FILTER_MULTI_ADDR_RSP:
0222         /* Ignore these for now */
0223         break;
0224 
0225     case BNEP_FILTER_NET_TYPE_SET:
0226         err = bnep_ctrl_set_netfilter(s, data, len);
0227         break;
0228 
0229     case BNEP_FILTER_MULTI_ADDR_SET:
0230         err = bnep_ctrl_set_mcfilter(s, data, len);
0231         break;
0232 
0233     case BNEP_SETUP_CONN_REQ:
0234         /* Successful response should be sent only once */
0235         if (test_bit(BNEP_SETUP_RESPONSE, &s->flags) &&
0236             !test_and_set_bit(BNEP_SETUP_RSP_SENT, &s->flags))
0237             err = bnep_send_rsp(s, BNEP_SETUP_CONN_RSP,
0238                         BNEP_SUCCESS);
0239         else
0240             err = bnep_send_rsp(s, BNEP_SETUP_CONN_RSP,
0241                         BNEP_CONN_NOT_ALLOWED);
0242         break;
0243 
0244     default: {
0245             u8 pkt[3];
0246             pkt[0] = BNEP_CONTROL;
0247             pkt[1] = BNEP_CMD_NOT_UNDERSTOOD;
0248             pkt[2] = cmd;
0249             err = bnep_send(s, pkt, sizeof(pkt));
0250         }
0251         break;
0252     }
0253 
0254     return err;
0255 }
0256 
0257 static int bnep_rx_extension(struct bnep_session *s, struct sk_buff *skb)
0258 {
0259     struct bnep_ext_hdr *h;
0260     int err = 0;
0261 
0262     do {
0263         h = (void *) skb->data;
0264         if (!skb_pull(skb, sizeof(*h))) {
0265             err = -EILSEQ;
0266             break;
0267         }
0268 
0269         BT_DBG("type 0x%x len %u", h->type, h->len);
0270 
0271         switch (h->type & BNEP_TYPE_MASK) {
0272         case BNEP_EXT_CONTROL:
0273             bnep_rx_control(s, skb->data, skb->len);
0274             break;
0275 
0276         default:
0277             /* Unknown extension, skip it. */
0278             break;
0279         }
0280 
0281         if (!skb_pull(skb, h->len)) {
0282             err = -EILSEQ;
0283             break;
0284         }
0285     } while (!err && (h->type & BNEP_EXT_HEADER));
0286 
0287     return err;
0288 }
0289 
0290 static u8 __bnep_rx_hlen[] = {
0291     ETH_HLEN,     /* BNEP_GENERAL */
0292     0,            /* BNEP_CONTROL */
0293     2,            /* BNEP_COMPRESSED */
0294     ETH_ALEN + 2, /* BNEP_COMPRESSED_SRC_ONLY */
0295     ETH_ALEN + 2  /* BNEP_COMPRESSED_DST_ONLY */
0296 };
0297 
0298 static int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb)
0299 {
0300     struct net_device *dev = s->dev;
0301     struct sk_buff *nskb;
0302     u8 type, ctrl_type;
0303 
0304     dev->stats.rx_bytes += skb->len;
0305 
0306     type = *(u8 *) skb->data;
0307     skb_pull(skb, 1);
0308     ctrl_type = *(u8 *)skb->data;
0309 
0310     if ((type & BNEP_TYPE_MASK) >= sizeof(__bnep_rx_hlen))
0311         goto badframe;
0312 
0313     if ((type & BNEP_TYPE_MASK) == BNEP_CONTROL) {
0314         if (bnep_rx_control(s, skb->data, skb->len) < 0) {
0315             dev->stats.tx_errors++;
0316             kfree_skb(skb);
0317             return 0;
0318         }
0319 
0320         if (!(type & BNEP_EXT_HEADER)) {
0321             kfree_skb(skb);
0322             return 0;
0323         }
0324 
0325         /* Verify and pull ctrl message since it's already processed */
0326         switch (ctrl_type) {
0327         case BNEP_SETUP_CONN_REQ:
0328             /* Pull: ctrl type (1 b), len (1 b), data (len bytes) */
0329             if (!skb_pull(skb, 2 + *(u8 *)(skb->data + 1) * 2))
0330                 goto badframe;
0331             break;
0332         case BNEP_FILTER_MULTI_ADDR_SET:
0333         case BNEP_FILTER_NET_TYPE_SET:
0334             /* Pull: ctrl type (1 b), len (2 b), data (len bytes) */
0335             if (!skb_pull(skb, 3 + *(u16 *)(skb->data + 1) * 2))
0336                 goto badframe;
0337             break;
0338         default:
0339             kfree_skb(skb);
0340             return 0;
0341         }
0342     } else {
0343         skb_reset_mac_header(skb);
0344 
0345         /* Verify and pull out header */
0346         if (!skb_pull(skb, __bnep_rx_hlen[type & BNEP_TYPE_MASK]))
0347             goto badframe;
0348 
0349         s->eh.h_proto = get_unaligned((__be16 *) (skb->data - 2));
0350     }
0351 
0352     if (type & BNEP_EXT_HEADER) {
0353         if (bnep_rx_extension(s, skb) < 0)
0354             goto badframe;
0355     }
0356 
0357     /* Strip 802.1p header */
0358     if (ntohs(s->eh.h_proto) == ETH_P_8021Q) {
0359         if (!skb_pull(skb, 4))
0360             goto badframe;
0361         s->eh.h_proto = get_unaligned((__be16 *) (skb->data - 2));
0362     }
0363 
0364     /* We have to alloc new skb and copy data here :(. Because original skb
0365      * may not be modified and because of the alignment requirements. */
0366     nskb = alloc_skb(2 + ETH_HLEN + skb->len, GFP_KERNEL);
0367     if (!nskb) {
0368         dev->stats.rx_dropped++;
0369         kfree_skb(skb);
0370         return -ENOMEM;
0371     }
0372     skb_reserve(nskb, 2);
0373 
0374     /* Decompress header and construct ether frame */
0375     switch (type & BNEP_TYPE_MASK) {
0376     case BNEP_COMPRESSED:
0377         __skb_put_data(nskb, &s->eh, ETH_HLEN);
0378         break;
0379 
0380     case BNEP_COMPRESSED_SRC_ONLY:
0381         __skb_put_data(nskb, s->eh.h_dest, ETH_ALEN);
0382         __skb_put_data(nskb, skb_mac_header(skb), ETH_ALEN);
0383         put_unaligned(s->eh.h_proto, (__be16 *) __skb_put(nskb, 2));
0384         break;
0385 
0386     case BNEP_COMPRESSED_DST_ONLY:
0387         __skb_put_data(nskb, skb_mac_header(skb), ETH_ALEN);
0388         __skb_put_data(nskb, s->eh.h_source, ETH_ALEN + 2);
0389         break;
0390 
0391     case BNEP_GENERAL:
0392         __skb_put_data(nskb, skb_mac_header(skb), ETH_ALEN * 2);
0393         put_unaligned(s->eh.h_proto, (__be16 *) __skb_put(nskb, 2));
0394         break;
0395     }
0396 
0397     skb_copy_from_linear_data(skb, __skb_put(nskb, skb->len), skb->len);
0398     kfree_skb(skb);
0399 
0400     dev->stats.rx_packets++;
0401     nskb->ip_summed = CHECKSUM_NONE;
0402     nskb->protocol  = eth_type_trans(nskb, dev);
0403     netif_rx(nskb);
0404     return 0;
0405 
0406 badframe:
0407     dev->stats.rx_errors++;
0408     kfree_skb(skb);
0409     return 0;
0410 }
0411 
0412 static u8 __bnep_tx_types[] = {
0413     BNEP_GENERAL,
0414     BNEP_COMPRESSED_SRC_ONLY,
0415     BNEP_COMPRESSED_DST_ONLY,
0416     BNEP_COMPRESSED
0417 };
0418 
0419 static int bnep_tx_frame(struct bnep_session *s, struct sk_buff *skb)
0420 {
0421     struct ethhdr *eh = (void *) skb->data;
0422     struct socket *sock = s->sock;
0423     struct kvec iv[3];
0424     int len = 0, il = 0;
0425     u8 type = 0;
0426 
0427     BT_DBG("skb %p dev %p type %u", skb, skb->dev, skb->pkt_type);
0428 
0429     if (!skb->dev) {
0430         /* Control frame sent by us */
0431         goto send;
0432     }
0433 
0434     iv[il++] = (struct kvec) { &type, 1 };
0435     len++;
0436 
0437     if (compress_src && ether_addr_equal(eh->h_dest, s->eh.h_source))
0438         type |= 0x01;
0439 
0440     if (compress_dst && ether_addr_equal(eh->h_source, s->eh.h_dest))
0441         type |= 0x02;
0442 
0443     if (type)
0444         skb_pull(skb, ETH_ALEN * 2);
0445 
0446     type = __bnep_tx_types[type];
0447     switch (type) {
0448     case BNEP_COMPRESSED_SRC_ONLY:
0449         iv[il++] = (struct kvec) { eh->h_source, ETH_ALEN };
0450         len += ETH_ALEN;
0451         break;
0452 
0453     case BNEP_COMPRESSED_DST_ONLY:
0454         iv[il++] = (struct kvec) { eh->h_dest, ETH_ALEN };
0455         len += ETH_ALEN;
0456         break;
0457     }
0458 
0459 send:
0460     iv[il++] = (struct kvec) { skb->data, skb->len };
0461     len += skb->len;
0462 
0463     /* FIXME: linearize skb */
0464     {
0465         len = kernel_sendmsg(sock, &s->msg, iv, il, len);
0466     }
0467     kfree_skb(skb);
0468 
0469     if (len > 0) {
0470         s->dev->stats.tx_bytes += len;
0471         s->dev->stats.tx_packets++;
0472         return 0;
0473     }
0474 
0475     return len;
0476 }
0477 
0478 static int bnep_session(void *arg)
0479 {
0480     struct bnep_session *s = arg;
0481     struct net_device *dev = s->dev;
0482     struct sock *sk = s->sock->sk;
0483     struct sk_buff *skb;
0484     DEFINE_WAIT_FUNC(wait, woken_wake_function);
0485 
0486     BT_DBG("");
0487 
0488     set_user_nice(current, -15);
0489 
0490     add_wait_queue(sk_sleep(sk), &wait);
0491     while (1) {
0492         if (atomic_read(&s->terminate))
0493             break;
0494         /* RX */
0495         while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
0496             skb_orphan(skb);
0497             if (!skb_linearize(skb))
0498                 bnep_rx_frame(s, skb);
0499             else
0500                 kfree_skb(skb);
0501         }
0502 
0503         if (sk->sk_state != BT_CONNECTED)
0504             break;
0505 
0506         /* TX */
0507         while ((skb = skb_dequeue(&sk->sk_write_queue)))
0508             if (bnep_tx_frame(s, skb))
0509                 break;
0510         netif_wake_queue(dev);
0511 
0512         /*
0513          * wait_woken() performs the necessary memory barriers
0514          * for us; see the header comment for this primitive.
0515          */
0516         wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT);
0517     }
0518     remove_wait_queue(sk_sleep(sk), &wait);
0519 
0520     /* Cleanup session */
0521     down_write(&bnep_session_sem);
0522 
0523     /* Delete network device */
0524     unregister_netdev(dev);
0525 
0526     /* Wakeup user-space polling for socket errors */
0527     s->sock->sk->sk_err = EUNATCH;
0528 
0529     wake_up_interruptible(sk_sleep(s->sock->sk));
0530 
0531     /* Release the socket */
0532     fput(s->sock->file);
0533 
0534     __bnep_unlink_session(s);
0535 
0536     up_write(&bnep_session_sem);
0537     free_netdev(dev);
0538     module_put_and_kthread_exit(0);
0539     return 0;
0540 }
0541 
0542 static struct device *bnep_get_device(struct bnep_session *session)
0543 {
0544     struct l2cap_conn *conn = l2cap_pi(session->sock->sk)->chan->conn;
0545 
0546     if (!conn || !conn->hcon)
0547         return NULL;
0548 
0549     return &conn->hcon->dev;
0550 }
0551 
0552 static struct device_type bnep_type = {
0553     .name   = "bluetooth",
0554 };
0555 
0556 int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
0557 {
0558     u32 valid_flags = BIT(BNEP_SETUP_RESPONSE);
0559     struct net_device *dev;
0560     struct bnep_session *s, *ss;
0561     u8 dst[ETH_ALEN], src[ETH_ALEN];
0562     int err;
0563 
0564     BT_DBG("");
0565 
0566     if (!l2cap_is_socket(sock))
0567         return -EBADFD;
0568 
0569     if (req->flags & ~valid_flags)
0570         return -EINVAL;
0571 
0572     baswap((void *) dst, &l2cap_pi(sock->sk)->chan->dst);
0573     baswap((void *) src, &l2cap_pi(sock->sk)->chan->src);
0574 
0575     /* session struct allocated as private part of net_device */
0576     dev = alloc_netdev(sizeof(struct bnep_session),
0577                (*req->device) ? req->device : "bnep%d",
0578                NET_NAME_UNKNOWN,
0579                bnep_net_setup);
0580     if (!dev)
0581         return -ENOMEM;
0582 
0583     down_write(&bnep_session_sem);
0584 
0585     ss = __bnep_get_session(dst);
0586     if (ss && ss->state == BT_CONNECTED) {
0587         err = -EEXIST;
0588         goto failed;
0589     }
0590 
0591     s = netdev_priv(dev);
0592 
0593     /* This is rx header therefore addresses are swapped.
0594      * ie. eh.h_dest is our local address. */
0595     memcpy(s->eh.h_dest,   &src, ETH_ALEN);
0596     memcpy(s->eh.h_source, &dst, ETH_ALEN);
0597     eth_hw_addr_set(dev, s->eh.h_dest);
0598 
0599     s->dev   = dev;
0600     s->sock  = sock;
0601     s->role  = req->role;
0602     s->state = BT_CONNECTED;
0603     s->flags = req->flags;
0604 
0605     s->msg.msg_flags = MSG_NOSIGNAL;
0606 
0607 #ifdef CONFIG_BT_BNEP_MC_FILTER
0608     /* Set default mc filter to not filter out any mc addresses
0609      * as defined in the BNEP specification (revision 0.95a)
0610      * http://grouper.ieee.org/groups/802/15/Bluetooth/BNEP.pdf
0611      */
0612     s->mc_filter = ~0LL;
0613 #endif
0614 
0615 #ifdef CONFIG_BT_BNEP_PROTO_FILTER
0616     /* Set default protocol filter */
0617     bnep_set_default_proto_filter(s);
0618 #endif
0619 
0620     SET_NETDEV_DEV(dev, bnep_get_device(s));
0621     SET_NETDEV_DEVTYPE(dev, &bnep_type);
0622 
0623     err = register_netdev(dev);
0624     if (err)
0625         goto failed;
0626 
0627     __bnep_link_session(s);
0628 
0629     __module_get(THIS_MODULE);
0630     s->task = kthread_run(bnep_session, s, "kbnepd %s", dev->name);
0631     if (IS_ERR(s->task)) {
0632         /* Session thread start failed, gotta cleanup. */
0633         module_put(THIS_MODULE);
0634         unregister_netdev(dev);
0635         __bnep_unlink_session(s);
0636         err = PTR_ERR(s->task);
0637         goto failed;
0638     }
0639 
0640     up_write(&bnep_session_sem);
0641     strcpy(req->device, dev->name);
0642     return 0;
0643 
0644 failed:
0645     up_write(&bnep_session_sem);
0646     free_netdev(dev);
0647     return err;
0648 }
0649 
0650 int bnep_del_connection(struct bnep_conndel_req *req)
0651 {
0652     u32 valid_flags = 0;
0653     struct bnep_session *s;
0654     int  err = 0;
0655 
0656     BT_DBG("");
0657 
0658     if (req->flags & ~valid_flags)
0659         return -EINVAL;
0660 
0661     down_read(&bnep_session_sem);
0662 
0663     s = __bnep_get_session(req->dst);
0664     if (s) {
0665         atomic_inc(&s->terminate);
0666         wake_up_interruptible(sk_sleep(s->sock->sk));
0667     } else
0668         err = -ENOENT;
0669 
0670     up_read(&bnep_session_sem);
0671     return err;
0672 }
0673 
0674 static void __bnep_copy_ci(struct bnep_conninfo *ci, struct bnep_session *s)
0675 {
0676     u32 valid_flags = BIT(BNEP_SETUP_RESPONSE);
0677 
0678     memset(ci, 0, sizeof(*ci));
0679     memcpy(ci->dst, s->eh.h_source, ETH_ALEN);
0680     strcpy(ci->device, s->dev->name);
0681     ci->flags = s->flags & valid_flags;
0682     ci->state = s->state;
0683     ci->role  = s->role;
0684 }
0685 
0686 int bnep_get_connlist(struct bnep_connlist_req *req)
0687 {
0688     struct bnep_session *s;
0689     int err = 0, n = 0;
0690 
0691     down_read(&bnep_session_sem);
0692 
0693     list_for_each_entry(s, &bnep_session_list, list) {
0694         struct bnep_conninfo ci;
0695 
0696         __bnep_copy_ci(&ci, s);
0697 
0698         if (copy_to_user(req->ci, &ci, sizeof(ci))) {
0699             err = -EFAULT;
0700             break;
0701         }
0702 
0703         if (++n >= req->cnum)
0704             break;
0705 
0706         req->ci++;
0707     }
0708     req->cnum = n;
0709 
0710     up_read(&bnep_session_sem);
0711     return err;
0712 }
0713 
0714 int bnep_get_conninfo(struct bnep_conninfo *ci)
0715 {
0716     struct bnep_session *s;
0717     int err = 0;
0718 
0719     down_read(&bnep_session_sem);
0720 
0721     s = __bnep_get_session(ci->dst);
0722     if (s)
0723         __bnep_copy_ci(ci, s);
0724     else
0725         err = -ENOENT;
0726 
0727     up_read(&bnep_session_sem);
0728     return err;
0729 }
0730 
0731 static int __init bnep_init(void)
0732 {
0733     char flt[50] = "";
0734 
0735 #ifdef CONFIG_BT_BNEP_PROTO_FILTER
0736     strcat(flt, "protocol ");
0737 #endif
0738 
0739 #ifdef CONFIG_BT_BNEP_MC_FILTER
0740     strcat(flt, "multicast");
0741 #endif
0742 
0743     BT_INFO("BNEP (Ethernet Emulation) ver %s", VERSION);
0744     if (flt[0])
0745         BT_INFO("BNEP filters: %s", flt);
0746 
0747     bnep_sock_init();
0748     return 0;
0749 }
0750 
0751 static void __exit bnep_exit(void)
0752 {
0753     bnep_sock_cleanup();
0754 }
0755 
0756 module_init(bnep_init);
0757 module_exit(bnep_exit);
0758 
0759 module_param(compress_src, bool, 0644);
0760 MODULE_PARM_DESC(compress_src, "Compress sources headers");
0761 
0762 module_param(compress_dst, bool, 0644);
0763 MODULE_PARM_DESC(compress_dst, "Compress destination headers");
0764 
0765 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
0766 MODULE_DESCRIPTION("Bluetooth BNEP ver " VERSION);
0767 MODULE_VERSION(VERSION);
0768 MODULE_LICENSE("GPL");
0769 MODULE_ALIAS("bt-proto-4");