xref: /linux/net/bluetooth/bnep/core.c (revision 47902f3611b392209e2a412bf7ec02dca95e666d)
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->sk_sleep, &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->sk_sleep, &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(s->sock->sk->sk_sleep);
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(s->sock->sk->sk_sleep);
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 	memcpy(ci->dst, s->eh.h_source, ETH_ALEN);
652 	strcpy(ci->device, s->dev->name);
653 	ci->flags = s->flags;
654 	ci->state = s->state;
655 	ci->role  = s->role;
656 }
657 
658 int bnep_get_connlist(struct bnep_connlist_req *req)
659 {
660 	struct list_head *p;
661 	int err = 0, n = 0;
662 
663 	down_read(&bnep_session_sem);
664 
665 	list_for_each(p, &bnep_session_list) {
666 		struct bnep_session *s;
667 		struct bnep_conninfo ci;
668 
669 		s = list_entry(p, struct bnep_session, list);
670 
671 		__bnep_copy_ci(&ci, s);
672 
673 		if (copy_to_user(req->ci, &ci, sizeof(ci))) {
674 			err = -EFAULT;
675 			break;
676 		}
677 
678 		if (++n >= req->cnum)
679 			break;
680 
681 		req->ci++;
682 	}
683 	req->cnum = n;
684 
685 	up_read(&bnep_session_sem);
686 	return err;
687 }
688 
689 int bnep_get_conninfo(struct bnep_conninfo *ci)
690 {
691 	struct bnep_session *s;
692 	int err = 0;
693 
694 	down_read(&bnep_session_sem);
695 
696 	s = __bnep_get_session(ci->dst);
697 	if (s)
698 		__bnep_copy_ci(ci, s);
699 	else
700 		err = -ENOENT;
701 
702 	up_read(&bnep_session_sem);
703 	return err;
704 }
705 
706 static int __init bnep_init(void)
707 {
708 	char flt[50] = "";
709 
710 	l2cap_load();
711 
712 #ifdef CONFIG_BT_BNEP_PROTO_FILTER
713 	strcat(flt, "protocol ");
714 #endif
715 
716 #ifdef CONFIG_BT_BNEP_MC_FILTER
717 	strcat(flt, "multicast");
718 #endif
719 
720 	BT_INFO("BNEP (Ethernet Emulation) ver %s", VERSION);
721 	if (flt[0])
722 		BT_INFO("BNEP filters: %s", flt);
723 
724 	bnep_sock_init();
725 	return 0;
726 }
727 
728 static void __exit bnep_exit(void)
729 {
730 	bnep_sock_cleanup();
731 }
732 
733 module_init(bnep_init);
734 module_exit(bnep_exit);
735 
736 module_param(compress_src, bool, 0644);
737 MODULE_PARM_DESC(compress_src, "Compress sources headers");
738 
739 module_param(compress_dst, bool, 0644);
740 MODULE_PARM_DESC(compress_dst, "Compress destination headers");
741 
742 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
743 MODULE_DESCRIPTION("Bluetooth BNEP ver " VERSION);
744 MODULE_VERSION(VERSION);
745 MODULE_LICENSE("GPL");
746 MODULE_ALIAS("bt-proto-4");
747