03d4d1245d583164e9a623caece340684300a848
[linux-2.6.git] / net / bluetooth / bnep / core.c
1 /*
2    BNEP implementation for Linux Bluetooth stack (BlueZ).
3    Copyright (C) 2001-2002 Inventel Systemes
4    Written 2001-2002 by
5         ClĂ©ment Moreau <clement.moreau@inventel.fr>
6         David Libault  <david.libault@inventel.fr>
7
8    Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License version 2 as
12    published by the Free Software Foundation;
13
14    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
17    IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
18    CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
19    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
21    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23    ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
24    COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
25    SOFTWARE IS DISCLAIMED.
26 */
27
28 #include <linux/module.h>
29
30 #include <linux/kernel.h>
31 #include <linux/sched.h>
32 #include <linux/signal.h>
33 #include <linux/init.h>
34 #include <linux/wait.h>
35 #include <linux/freezer.h>
36 #include <linux/errno.h>
37 #include <linux/net.h>
38 #include <linux/slab.h>
39 #include <net/sock.h>
40
41 #include <linux/socket.h>
42 #include <linux/file.h>
43
44 #include <linux/netdevice.h>
45 #include <linux/etherdevice.h>
46 #include <linux/skbuff.h>
47
48 #include <asm/unaligned.h>
49
50 #include <net/bluetooth/bluetooth.h>
51 #include <net/bluetooth/hci_core.h>
52 #include <net/bluetooth/l2cap.h>
53
54 #include "bnep.h"
55
56 #define VERSION "1.3"
57
58 static int compress_src = 1;
59 static int compress_dst = 1;
60
61 static LIST_HEAD(bnep_session_list);
62 static DECLARE_RWSEM(bnep_session_sem);
63
64 static struct bnep_session *__bnep_get_session(u8 *dst)
65 {
66         struct bnep_session *s;
67         struct list_head *p;
68
69         BT_DBG("");
70
71         list_for_each(p, &bnep_session_list) {
72                 s = list_entry(p, struct bnep_session, list);
73                 if (!compare_ether_addr(dst, s->eh.h_source))
74                         return s;
75         }
76         return NULL;
77 }
78
79 static void __bnep_link_session(struct bnep_session *s)
80 {
81         /* It's safe to call __module_get() here because sessions are added
82            by the socket layer which has to hold the reference to this module.
83          */
84         __module_get(THIS_MODULE);
85         list_add(&s->list, &bnep_session_list);
86 }
87
88 static void __bnep_unlink_session(struct bnep_session *s)
89 {
90         list_del(&s->list);
91         module_put(THIS_MODULE);
92 }
93
94 static int bnep_send(struct bnep_session *s, void *data, size_t len)
95 {
96         struct socket *sock = s->sock;
97         struct kvec iv = { data, len };
98
99         return kernel_sendmsg(sock, &s->msg, &iv, 1, len);
100 }
101
102 static int bnep_send_rsp(struct bnep_session *s, u8 ctrl, u16 resp)
103 {
104         struct bnep_control_rsp rsp;
105         rsp.type = BNEP_CONTROL;
106         rsp.ctrl = ctrl;
107         rsp.resp = htons(resp);
108         return bnep_send(s, &rsp, sizeof(rsp));
109 }
110
111 #ifdef CONFIG_BT_BNEP_PROTO_FILTER
112 static inline void bnep_set_default_proto_filter(struct bnep_session *s)
113 {
114         /* (IPv4, ARP)  */
115         s->proto_filter[0].start = ETH_P_IP;
116         s->proto_filter[0].end   = ETH_P_ARP;
117         /* (RARP, AppleTalk) */
118         s->proto_filter[1].start = ETH_P_RARP;
119         s->proto_filter[1].end   = ETH_P_AARP;
120         /* (IPX, IPv6) */
121         s->proto_filter[2].start = ETH_P_IPX;
122         s->proto_filter[2].end   = ETH_P_IPV6;
123 }
124 #endif
125
126 static int bnep_ctrl_set_netfilter(struct bnep_session *s, __be16 *data, int len)
127 {
128         int n;
129
130         if (len < 2)
131                 return -EILSEQ;
132
133         n = get_unaligned_be16(data);
134         data++; len -= 2;
135
136         if (len < n)
137                 return -EILSEQ;
138
139         BT_DBG("filter len %d", n);
140
141 #ifdef CONFIG_BT_BNEP_PROTO_FILTER
142         n /= 4;
143         if (n <= BNEP_MAX_PROTO_FILTERS) {
144                 struct bnep_proto_filter *f = s->proto_filter;
145                 int i;
146
147                 for (i = 0; i < n; i++) {
148                         f[i].start = get_unaligned_be16(data++);
149                         f[i].end   = get_unaligned_be16(data++);
150
151                         BT_DBG("proto filter start %d end %d",
152                                 f[i].start, f[i].end);
153                 }
154
155                 if (i < BNEP_MAX_PROTO_FILTERS)
156                         memset(f + i, 0, sizeof(*f));
157
158                 if (n == 0)
159                         bnep_set_default_proto_filter(s);
160
161                 bnep_send_rsp(s, BNEP_FILTER_NET_TYPE_RSP, BNEP_SUCCESS);
162         } else {
163                 bnep_send_rsp(s, BNEP_FILTER_NET_TYPE_RSP, BNEP_FILTER_LIMIT_REACHED);
164         }
165 #else
166         bnep_send_rsp(s, BNEP_FILTER_NET_TYPE_RSP, BNEP_FILTER_UNSUPPORTED_REQ);
167 #endif
168         return 0;
169 }
170
171 static int bnep_ctrl_set_mcfilter(struct bnep_session *s, u8 *data, int len)
172 {
173         int n;
174
175         if (len < 2)
176                 return -EILSEQ;
177
178         n = get_unaligned_be16(data);
179         data += 2; len -= 2;
180
181         if (len < n)
182                 return -EILSEQ;
183
184         BT_DBG("filter len %d", n);
185
186 #ifdef CONFIG_BT_BNEP_MC_FILTER
187         n /= (ETH_ALEN * 2);
188
189         if (n > 0) {
190                 s->mc_filter = 0;
191
192                 /* Always send broadcast */
193                 set_bit(bnep_mc_hash(s->dev->broadcast), (ulong *) &s->mc_filter);
194
195                 /* Add address ranges to the multicast hash */
196                 for (; n > 0; n--) {
197                         u8 a1[6], *a2;
198
199                         memcpy(a1, data, ETH_ALEN); data += ETH_ALEN;
200                         a2 = data; data += ETH_ALEN;
201
202                         BT_DBG("mc filter %s -> %s",
203                                 batostr((void *) a1), batostr((void *) a2));
204
205                         #define INCA(a) { int i = 5; while (i >=0 && ++a[i--] == 0); }
206
207                         /* Iterate from a1 to a2 */
208                         set_bit(bnep_mc_hash(a1), (ulong *) &s->mc_filter);
209                         while (memcmp(a1, a2, 6) < 0 && s->mc_filter != ~0LL) {
210                                 INCA(a1);
211                                 set_bit(bnep_mc_hash(a1), (ulong *) &s->mc_filter);
212                         }
213                 }
214         }
215
216         BT_DBG("mc filter hash 0x%llx", s->mc_filter);
217
218         bnep_send_rsp(s, BNEP_FILTER_MULTI_ADDR_RSP, BNEP_SUCCESS);
219 #else
220         bnep_send_rsp(s, BNEP_FILTER_MULTI_ADDR_RSP, BNEP_FILTER_UNSUPPORTED_REQ);
221 #endif
222         return 0;
223 }
224
225 static int bnep_rx_control(struct bnep_session *s, void *data, int len)
226 {
227         u8  cmd = *(u8 *)data;
228         int err = 0;
229
230         data++; len--;
231
232         switch (cmd) {
233         case BNEP_CMD_NOT_UNDERSTOOD:
234         case BNEP_SETUP_CONN_RSP:
235         case BNEP_FILTER_NET_TYPE_RSP:
236         case BNEP_FILTER_MULTI_ADDR_RSP:
237                 /* Ignore these for now */
238                 break;
239
240         case BNEP_FILTER_NET_TYPE_SET:
241                 err = bnep_ctrl_set_netfilter(s, data, len);
242                 break;
243
244         case BNEP_FILTER_MULTI_ADDR_SET:
245                 err = bnep_ctrl_set_mcfilter(s, data, len);
246                 break;
247
248         case BNEP_SETUP_CONN_REQ:
249                 err = bnep_send_rsp(s, BNEP_SETUP_CONN_RSP, BNEP_CONN_NOT_ALLOWED);
250                 break;
251
252         default: {
253                         u8 pkt[3];
254                         pkt[0] = BNEP_CONTROL;
255                         pkt[1] = BNEP_CMD_NOT_UNDERSTOOD;
256                         pkt[2] = cmd;
257                         bnep_send(s, pkt, sizeof(pkt));
258                 }
259                 break;
260         }
261
262         return err;
263 }
264
265 static int bnep_rx_extension(struct bnep_session *s, struct sk_buff *skb)
266 {
267         struct bnep_ext_hdr *h;
268         int err = 0;
269
270         do {
271                 h = (void *) skb->data;
272                 if (!skb_pull(skb, sizeof(*h))) {
273                         err = -EILSEQ;
274                         break;
275                 }
276
277                 BT_DBG("type 0x%x len %d", h->type, h->len);
278
279                 switch (h->type & BNEP_TYPE_MASK) {
280                 case BNEP_EXT_CONTROL:
281                         bnep_rx_control(s, skb->data, skb->len);
282                         break;
283
284                 default:
285                         /* Unknown extension, skip it. */
286                         break;
287                 }
288
289                 if (!skb_pull(skb, h->len)) {
290                         err = -EILSEQ;
291                         break;
292                 }
293         } while (!err && (h->type & BNEP_EXT_HEADER));
294
295         return err;
296 }
297
298 static u8 __bnep_rx_hlen[] = {
299         ETH_HLEN,     /* BNEP_GENERAL */
300         0,            /* BNEP_CONTROL */
301         2,            /* BNEP_COMPRESSED */
302         ETH_ALEN + 2, /* BNEP_COMPRESSED_SRC_ONLY */
303         ETH_ALEN + 2  /* BNEP_COMPRESSED_DST_ONLY */
304 };
305 #define BNEP_RX_TYPES   (sizeof(__bnep_rx_hlen) - 1)
306
307 static inline int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb)
308 {
309         struct net_device *dev = s->dev;
310         struct sk_buff *nskb;
311         u8 type;
312
313         dev->stats.rx_bytes += skb->len;
314
315         type = *(u8 *) skb->data; skb_pull(skb, 1);
316
317         if ((type & BNEP_TYPE_MASK) > BNEP_RX_TYPES)
318                 goto badframe;
319
320         if ((type & BNEP_TYPE_MASK) == BNEP_CONTROL) {
321                 bnep_rx_control(s, skb->data, skb->len);
322                 kfree_skb(skb);
323                 return 0;
324         }
325
326         skb_reset_mac_header(skb);
327
328         /* Verify and pull out header */
329         if (!skb_pull(skb, __bnep_rx_hlen[type & BNEP_TYPE_MASK]))
330                 goto badframe;
331
332         s->eh.h_proto = get_unaligned((__be16 *) (skb->data - 2));
333
334         if (type & BNEP_EXT_HEADER) {
335                 if (bnep_rx_extension(s, skb) < 0)
336                         goto badframe;
337         }
338
339         /* Strip 802.1p header */
340         if (ntohs(s->eh.h_proto) == 0x8100) {
341                 if (!skb_pull(skb, 4))
342                         goto badframe;
343                 s->eh.h_proto = get_unaligned((__be16 *) (skb->data - 2));
344         }
345
346         /* We have to alloc new skb and copy data here :(. Because original skb
347          * may not be modified and because of the alignment requirements. */
348         nskb = alloc_skb(2 + ETH_HLEN + skb->len, GFP_KERNEL);
349         if (!nskb) {
350                 dev->stats.rx_dropped++;
351                 kfree_skb(skb);
352                 return -ENOMEM;
353         }
354         skb_reserve(nskb, 2);
355
356         /* Decompress header and construct ether frame */
357         switch (type & BNEP_TYPE_MASK) {
358         case BNEP_COMPRESSED:
359                 memcpy(__skb_put(nskb, ETH_HLEN), &s->eh, ETH_HLEN);
360                 break;
361
362         case BNEP_COMPRESSED_SRC_ONLY:
363                 memcpy(__skb_put(nskb, ETH_ALEN), s->eh.h_dest, ETH_ALEN);
364                 memcpy(__skb_put(nskb, ETH_ALEN), skb_mac_header(skb), ETH_ALEN);
365                 put_unaligned(s->eh.h_proto, (__be16 *) __skb_put(nskb, 2));
366                 break;
367
368         case BNEP_COMPRESSED_DST_ONLY:
369                 memcpy(__skb_put(nskb, ETH_ALEN), skb_mac_header(skb),
370                        ETH_ALEN);
371                 memcpy(__skb_put(nskb, ETH_ALEN + 2), s->eh.h_source,
372                        ETH_ALEN + 2);
373                 break;
374
375         case BNEP_GENERAL:
376                 memcpy(__skb_put(nskb, ETH_ALEN * 2), skb_mac_header(skb),
377                        ETH_ALEN * 2);
378                 put_unaligned(s->eh.h_proto, (__be16 *) __skb_put(nskb, 2));
379                 break;
380         }
381
382         skb_copy_from_linear_data(skb, __skb_put(nskb, skb->len), skb->len);
383         kfree_skb(skb);
384
385         dev->stats.rx_packets++;
386         nskb->ip_summed = CHECKSUM_NONE;
387         nskb->protocol  = eth_type_trans(nskb, dev);
388         netif_rx_ni(nskb);
389         return 0;
390
391 badframe:
392         dev->stats.rx_errors++;
393         kfree_skb(skb);
394         return 0;
395 }
396
397 static u8 __bnep_tx_types[] = {
398         BNEP_GENERAL,
399         BNEP_COMPRESSED_SRC_ONLY,
400         BNEP_COMPRESSED_DST_ONLY,
401         BNEP_COMPRESSED
402 };
403
404 static inline int bnep_tx_frame(struct bnep_session *s, struct sk_buff *skb)
405 {
406         struct ethhdr *eh = (void *) skb->data;
407         struct socket *sock = s->sock;
408         struct kvec iv[3];
409         int len = 0, il = 0;
410         u8 type = 0;
411
412         BT_DBG("skb %p dev %p type %d", skb, skb->dev, skb->pkt_type);
413
414         if (!skb->dev) {
415                 /* Control frame sent by us */
416                 goto send;
417         }
418
419         iv[il++] = (struct kvec) { &type, 1 };
420         len++;
421
422         if (compress_src && !compare_ether_addr(eh->h_dest, s->eh.h_source))
423                 type |= 0x01;
424
425         if (compress_dst && !compare_ether_addr(eh->h_source, s->eh.h_dest))
426                 type |= 0x02;
427
428         if (type)
429                 skb_pull(skb, ETH_ALEN * 2);
430
431         type = __bnep_tx_types[type];
432         switch (type) {
433         case BNEP_COMPRESSED_SRC_ONLY:
434                 iv[il++] = (struct kvec) { eh->h_source, ETH_ALEN };
435                 len += ETH_ALEN;
436                 break;
437
438         case BNEP_COMPRESSED_DST_ONLY:
439                 iv[il++] = (struct kvec) { eh->h_dest, ETH_ALEN };
440                 len += ETH_ALEN;
441                 break;
442         }
443
444 send:
445         iv[il++] = (struct kvec) { skb->data, skb->len };
446         len += skb->len;
447
448         /* FIXME: linearize skb */
449         {
450                 len = kernel_sendmsg(sock, &s->msg, iv, il, len);
451         }
452         kfree_skb(skb);
453
454         if (len > 0) {
455                 s->dev->stats.tx_bytes += len;
456                 s->dev->stats.tx_packets++;
457                 return 0;
458         }
459
460         return len;
461 }
462
463 static int bnep_session(void *arg)
464 {
465         struct bnep_session *s = arg;
466         struct net_device *dev = s->dev;
467         struct sock *sk = s->sock->sk;
468         struct sk_buff *skb;
469         wait_queue_t wait;
470
471         BT_DBG("");
472
473         daemonize("kbnepd %s", dev->name);
474         set_user_nice(current, -15);
475
476         init_waitqueue_entry(&wait, current);
477         add_wait_queue(sk_sleep(sk), &wait);
478         while (!atomic_read(&s->killed)) {
479                 set_current_state(TASK_INTERRUPTIBLE);
480
481                 // RX
482                 while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
483                         skb_orphan(skb);
484                         bnep_rx_frame(s, skb);
485                 }
486
487                 if (sk->sk_state != BT_CONNECTED)
488                         break;
489
490                 // TX
491                 while ((skb = skb_dequeue(&sk->sk_write_queue)))
492                         if (bnep_tx_frame(s, skb))
493                                 break;
494                 netif_wake_queue(dev);
495
496                 schedule();
497         }
498         set_current_state(TASK_RUNNING);
499         remove_wait_queue(sk_sleep(sk), &wait);
500
501         /* Cleanup session */
502         down_write(&bnep_session_sem);
503
504         /* Delete network device */
505         unregister_netdev(dev);
506
507         /* Wakeup user-space polling for socket errors */
508         s->sock->sk->sk_err = EUNATCH;
509
510         wake_up_interruptible(sk_sleep(s->sock->sk));
511
512         /* Release the socket */
513         fput(s->sock->file);
514
515         __bnep_unlink_session(s);
516
517         up_write(&bnep_session_sem);
518         free_netdev(dev);
519         return 0;
520 }
521
522 static struct device *bnep_get_device(struct bnep_session *session)
523 {
524         bdaddr_t *src = &bt_sk(session->sock->sk)->src;
525         bdaddr_t *dst = &bt_sk(session->sock->sk)->dst;
526         struct hci_dev *hdev;
527         struct hci_conn *conn;
528
529         hdev = hci_get_route(dst, src);
530         if (!hdev)
531                 return NULL;
532
533         conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
534
535         hci_dev_put(hdev);
536
537         return conn ? &conn->dev : NULL;
538 }
539
540 static struct device_type bnep_type = {
541         .name   = "bluetooth",
542 };
543
544 int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
545 {
546         struct net_device *dev;
547         struct bnep_session *s, *ss;
548         u8 dst[ETH_ALEN], src[ETH_ALEN];
549         int err;
550
551         BT_DBG("");
552
553         baswap((void *) dst, &bt_sk(sock->sk)->dst);
554         baswap((void *) src, &bt_sk(sock->sk)->src);
555
556         /* session struct allocated as private part of net_device */
557         dev = alloc_netdev(sizeof(struct bnep_session),
558                            (*req->device) ? req->device : "bnep%d",
559                            bnep_net_setup);
560         if (!dev)
561                 return -ENOMEM;
562
563         down_write(&bnep_session_sem);
564
565         ss = __bnep_get_session(dst);
566         if (ss && ss->state == BT_CONNECTED) {
567                 err = -EEXIST;
568                 goto failed;
569         }
570
571         s = netdev_priv(dev);
572
573         /* This is rx header therefore addresses are swapped.
574          * ie eh.h_dest is our local address. */
575         memcpy(s->eh.h_dest,   &src, ETH_ALEN);
576         memcpy(s->eh.h_source, &dst, ETH_ALEN);
577         memcpy(dev->dev_addr, s->eh.h_dest, ETH_ALEN);
578
579         s->dev   = dev;
580         s->sock  = sock;
581         s->role  = req->role;
582         s->state = BT_CONNECTED;
583
584         s->msg.msg_flags = MSG_NOSIGNAL;
585
586 #ifdef CONFIG_BT_BNEP_MC_FILTER
587         /* Set default mc filter */
588         set_bit(bnep_mc_hash(dev->broadcast), (ulong *) &s->mc_filter);
589 #endif
590
591 #ifdef CONFIG_BT_BNEP_PROTO_FILTER
592         /* Set default protocol filter */
593         bnep_set_default_proto_filter(s);
594 #endif
595
596         SET_NETDEV_DEV(dev, bnep_get_device(s));
597         SET_NETDEV_DEVTYPE(dev, &bnep_type);
598
599         err = register_netdev(dev);
600         if (err) {
601                 goto failed;
602         }
603
604         __bnep_link_session(s);
605
606         err = kernel_thread(bnep_session, s, CLONE_KERNEL);
607         if (err < 0) {
608                 /* Session thread start failed, gotta cleanup. */
609                 unregister_netdev(dev);
610                 __bnep_unlink_session(s);
611                 goto failed;
612         }
613
614         up_write(&bnep_session_sem);
615         strcpy(req->device, dev->name);
616         return 0;
617
618 failed:
619         up_write(&bnep_session_sem);
620         free_netdev(dev);
621         return err;
622 }
623
624 int bnep_del_connection(struct bnep_conndel_req *req)
625 {
626         struct bnep_session *s;
627         int  err = 0;
628
629         BT_DBG("");
630
631         down_read(&bnep_session_sem);
632
633         s = __bnep_get_session(req->dst);
634         if (s) {
635                 /* Wakeup user-space which is polling for socket errors.
636                  * This is temporary hack until we have shutdown in L2CAP */
637                 s->sock->sk->sk_err = EUNATCH;
638
639                 /* Kill session thread */
640                 atomic_inc(&s->killed);
641                 wake_up_interruptible(sk_sleep(s->sock->sk));
642         } else
643                 err = -ENOENT;
644
645         up_read(&bnep_session_sem);
646         return err;
647 }
648
649 static void __bnep_copy_ci(struct bnep_conninfo *ci, struct bnep_session *s)
650 {
651         memset(ci, 0, sizeof(*ci));
652         memcpy(ci->dst, s->eh.h_source, ETH_ALEN);
653         strcpy(ci->device, s->dev->name);
654         ci->flags = s->flags;
655         ci->state = s->state;
656         ci->role  = s->role;
657 }
658
659 int bnep_get_connlist(struct bnep_connlist_req *req)
660 {
661         struct list_head *p;
662         int err = 0, n = 0;
663
664         down_read(&bnep_session_sem);
665
666         list_for_each(p, &bnep_session_list) {
667                 struct bnep_session *s;
668                 struct bnep_conninfo ci;
669
670                 s = list_entry(p, struct bnep_session, list);
671
672                 __bnep_copy_ci(&ci, s);
673
674                 if (copy_to_user(req->ci, &ci, sizeof(ci))) {
675                         err = -EFAULT;
676                         break;
677                 }
678
679                 if (++n >= req->cnum)
680                         break;
681
682                 req->ci++;
683         }
684         req->cnum = n;
685
686         up_read(&bnep_session_sem);
687         return err;
688 }
689
690 int bnep_get_conninfo(struct bnep_conninfo *ci)
691 {
692         struct bnep_session *s;
693         int err = 0;
694
695         down_read(&bnep_session_sem);
696
697         s = __bnep_get_session(ci->dst);
698         if (s)
699                 __bnep_copy_ci(ci, s);
700         else
701                 err = -ENOENT;
702
703         up_read(&bnep_session_sem);
704         return err;
705 }
706
707 static int __init bnep_init(void)
708 {
709         char flt[50] = "";
710
711 #ifdef CONFIG_BT_BNEP_PROTO_FILTER
712         strcat(flt, "protocol ");
713 #endif
714
715 #ifdef CONFIG_BT_BNEP_MC_FILTER
716         strcat(flt, "multicast");
717 #endif
718
719         BT_INFO("BNEP (Ethernet Emulation) ver %s", VERSION);
720         if (flt[0])
721                 BT_INFO("BNEP filters: %s", flt);
722
723         bnep_sock_init();
724         return 0;
725 }
726
727 static void __exit bnep_exit(void)
728 {
729         bnep_sock_cleanup();
730 }
731
732 module_init(bnep_init);
733 module_exit(bnep_exit);
734
735 module_param(compress_src, bool, 0644);
736 MODULE_PARM_DESC(compress_src, "Compress sources headers");
737
738 module_param(compress_dst, bool, 0644);
739 MODULE_PARM_DESC(compress_dst, "Compress destination headers");
740
741 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
742 MODULE_DESCRIPTION("Bluetooth BNEP ver " VERSION);
743 MODULE_VERSION(VERSION);
744 MODULE_LICENSE("GPL");
745 MODULE_ALIAS("bt-proto-4");