xref: /openbmc/linux/net/bluetooth/bnep/core.c (revision c67ce71d)
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 #include <linux/kthread.h>
30 #include <linux/file.h>
31 #include <linux/etherdevice.h>
32 #include <asm/unaligned.h>
33 
34 #include <net/bluetooth/bluetooth.h>
35 #include <net/bluetooth/l2cap.h>
36 #include <net/bluetooth/hci_core.h>
37 
38 #include "bnep.h"
39 
40 #define VERSION "1.3"
41 
42 static bool compress_src = true;
43 static bool compress_dst = true;
44 
45 static LIST_HEAD(bnep_session_list);
46 static DECLARE_RWSEM(bnep_session_sem);
47 
48 static struct bnep_session *__bnep_get_session(u8 *dst)
49 {
50 	struct bnep_session *s;
51 
52 	BT_DBG("");
53 
54 	list_for_each_entry(s, &bnep_session_list, list)
55 		if (ether_addr_equal(dst, s->eh.h_source))
56 			return s;
57 
58 	return NULL;
59 }
60 
61 static void __bnep_link_session(struct bnep_session *s)
62 {
63 	list_add(&s->list, &bnep_session_list);
64 }
65 
66 static void __bnep_unlink_session(struct bnep_session *s)
67 {
68 	list_del(&s->list);
69 }
70 
71 static int bnep_send(struct bnep_session *s, void *data, size_t len)
72 {
73 	struct socket *sock = s->sock;
74 	struct kvec iv = { data, len };
75 
76 	return kernel_sendmsg(sock, &s->msg, &iv, 1, len);
77 }
78 
79 static int bnep_send_rsp(struct bnep_session *s, u8 ctrl, u16 resp)
80 {
81 	struct bnep_control_rsp rsp;
82 	rsp.type = BNEP_CONTROL;
83 	rsp.ctrl = ctrl;
84 	rsp.resp = htons(resp);
85 	return bnep_send(s, &rsp, sizeof(rsp));
86 }
87 
88 #ifdef CONFIG_BT_BNEP_PROTO_FILTER
89 static inline void bnep_set_default_proto_filter(struct bnep_session *s)
90 {
91 	/* (IPv4, ARP)  */
92 	s->proto_filter[0].start = ETH_P_IP;
93 	s->proto_filter[0].end   = ETH_P_ARP;
94 	/* (RARP, AppleTalk) */
95 	s->proto_filter[1].start = ETH_P_RARP;
96 	s->proto_filter[1].end   = ETH_P_AARP;
97 	/* (IPX, IPv6) */
98 	s->proto_filter[2].start = ETH_P_IPX;
99 	s->proto_filter[2].end   = ETH_P_IPV6;
100 }
101 #endif
102 
103 static int bnep_ctrl_set_netfilter(struct bnep_session *s, __be16 *data, int len)
104 {
105 	int n;
106 
107 	if (len < 2)
108 		return -EILSEQ;
109 
110 	n = get_unaligned_be16(data);
111 	data++;
112 	len -= 2;
113 
114 	if (len < n)
115 		return -EILSEQ;
116 
117 	BT_DBG("filter len %d", n);
118 
119 #ifdef CONFIG_BT_BNEP_PROTO_FILTER
120 	n /= 4;
121 	if (n <= BNEP_MAX_PROTO_FILTERS) {
122 		struct bnep_proto_filter *f = s->proto_filter;
123 		int i;
124 
125 		for (i = 0; i < n; i++) {
126 			f[i].start = get_unaligned_be16(data++);
127 			f[i].end   = get_unaligned_be16(data++);
128 
129 			BT_DBG("proto filter start %u end %u",
130 			       f[i].start, f[i].end);
131 		}
132 
133 		if (i < BNEP_MAX_PROTO_FILTERS)
134 			memset(f + i, 0, sizeof(*f));
135 
136 		if (n == 0)
137 			bnep_set_default_proto_filter(s);
138 
139 		bnep_send_rsp(s, BNEP_FILTER_NET_TYPE_RSP, BNEP_SUCCESS);
140 	} else {
141 		bnep_send_rsp(s, BNEP_FILTER_NET_TYPE_RSP, BNEP_FILTER_LIMIT_REACHED);
142 	}
143 #else
144 	bnep_send_rsp(s, BNEP_FILTER_NET_TYPE_RSP, BNEP_FILTER_UNSUPPORTED_REQ);
145 #endif
146 	return 0;
147 }
148 
149 static int bnep_ctrl_set_mcfilter(struct bnep_session *s, u8 *data, int len)
150 {
151 	int n;
152 
153 	if (len < 2)
154 		return -EILSEQ;
155 
156 	n = get_unaligned_be16(data);
157 	data += 2;
158 	len -= 2;
159 
160 	if (len < n)
161 		return -EILSEQ;
162 
163 	BT_DBG("filter len %d", n);
164 
165 #ifdef CONFIG_BT_BNEP_MC_FILTER
166 	n /= (ETH_ALEN * 2);
167 
168 	if (n > 0) {
169 		int i;
170 
171 		s->mc_filter = 0;
172 
173 		/* Always send broadcast */
174 		set_bit(bnep_mc_hash(s->dev->broadcast), (ulong *) &s->mc_filter);
175 
176 		/* Add address ranges to the multicast hash */
177 		for (; n > 0; n--) {
178 			u8 a1[6], *a2;
179 
180 			memcpy(a1, data, ETH_ALEN);
181 			data += ETH_ALEN;
182 			a2 = data;
183 			data += ETH_ALEN;
184 
185 			BT_DBG("mc filter %pMR -> %pMR", a1, a2);
186 
187 			/* Iterate from a1 to a2 */
188 			set_bit(bnep_mc_hash(a1), (ulong *) &s->mc_filter);
189 			while (memcmp(a1, a2, 6) < 0 && s->mc_filter != ~0LL) {
190 				/* Increment a1 */
191 				i = 5;
192 				while (i >= 0 && ++a1[i--] == 0)
193 					;
194 
195 				set_bit(bnep_mc_hash(a1), (ulong *) &s->mc_filter);
196 			}
197 		}
198 	}
199 
200 	BT_DBG("mc filter hash 0x%llx", s->mc_filter);
201 
202 	bnep_send_rsp(s, BNEP_FILTER_MULTI_ADDR_RSP, BNEP_SUCCESS);
203 #else
204 	bnep_send_rsp(s, BNEP_FILTER_MULTI_ADDR_RSP, BNEP_FILTER_UNSUPPORTED_REQ);
205 #endif
206 	return 0;
207 }
208 
209 static int bnep_rx_control(struct bnep_session *s, void *data, int len)
210 {
211 	u8  cmd = *(u8 *)data;
212 	int err = 0;
213 
214 	data++;
215 	len--;
216 
217 	switch (cmd) {
218 	case BNEP_CMD_NOT_UNDERSTOOD:
219 	case BNEP_SETUP_CONN_RSP:
220 	case BNEP_FILTER_NET_TYPE_RSP:
221 	case BNEP_FILTER_MULTI_ADDR_RSP:
222 		/* Ignore these for now */
223 		break;
224 
225 	case BNEP_FILTER_NET_TYPE_SET:
226 		err = bnep_ctrl_set_netfilter(s, data, len);
227 		break;
228 
229 	case BNEP_FILTER_MULTI_ADDR_SET:
230 		err = bnep_ctrl_set_mcfilter(s, data, len);
231 		break;
232 
233 	case BNEP_SETUP_CONN_REQ:
234 		/* Successful response should be sent only once */
235 		if (test_bit(BNEP_SETUP_RESPONSE, &s->flags) &&
236 		    !test_and_set_bit(BNEP_SETUP_RSP_SENT, &s->flags))
237 			err = bnep_send_rsp(s, BNEP_SETUP_CONN_RSP,
238 					    BNEP_SUCCESS);
239 		else
240 			err = bnep_send_rsp(s, BNEP_SETUP_CONN_RSP,
241 					    BNEP_CONN_NOT_ALLOWED);
242 		break;
243 
244 	default: {
245 			u8 pkt[3];
246 			pkt[0] = BNEP_CONTROL;
247 			pkt[1] = BNEP_CMD_NOT_UNDERSTOOD;
248 			pkt[2] = cmd;
249 			err = bnep_send(s, pkt, sizeof(pkt));
250 		}
251 		break;
252 	}
253 
254 	return err;
255 }
256 
257 static int bnep_rx_extension(struct bnep_session *s, struct sk_buff *skb)
258 {
259 	struct bnep_ext_hdr *h;
260 	int err = 0;
261 
262 	do {
263 		h = (void *) skb->data;
264 		if (!skb_pull(skb, sizeof(*h))) {
265 			err = -EILSEQ;
266 			break;
267 		}
268 
269 		BT_DBG("type 0x%x len %u", h->type, h->len);
270 
271 		switch (h->type & BNEP_TYPE_MASK) {
272 		case BNEP_EXT_CONTROL:
273 			bnep_rx_control(s, skb->data, skb->len);
274 			break;
275 
276 		default:
277 			/* Unknown extension, skip it. */
278 			break;
279 		}
280 
281 		if (!skb_pull(skb, h->len)) {
282 			err = -EILSEQ;
283 			break;
284 		}
285 	} while (!err && (h->type & BNEP_EXT_HEADER));
286 
287 	return err;
288 }
289 
290 static u8 __bnep_rx_hlen[] = {
291 	ETH_HLEN,     /* BNEP_GENERAL */
292 	0,            /* BNEP_CONTROL */
293 	2,            /* BNEP_COMPRESSED */
294 	ETH_ALEN + 2, /* BNEP_COMPRESSED_SRC_ONLY */
295 	ETH_ALEN + 2  /* BNEP_COMPRESSED_DST_ONLY */
296 };
297 
298 static int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb)
299 {
300 	struct net_device *dev = s->dev;
301 	struct sk_buff *nskb;
302 	u8 type, ctrl_type;
303 
304 	dev->stats.rx_bytes += skb->len;
305 
306 	type = *(u8 *) skb->data;
307 	skb_pull(skb, 1);
308 	ctrl_type = *(u8 *)skb->data;
309 
310 	if ((type & BNEP_TYPE_MASK) >= sizeof(__bnep_rx_hlen))
311 		goto badframe;
312 
313 	if ((type & BNEP_TYPE_MASK) == BNEP_CONTROL) {
314 		if (bnep_rx_control(s, skb->data, skb->len) < 0) {
315 			dev->stats.tx_errors++;
316 			kfree_skb(skb);
317 			return 0;
318 		}
319 
320 		if (!(type & BNEP_EXT_HEADER)) {
321 			kfree_skb(skb);
322 			return 0;
323 		}
324 
325 		/* Verify and pull ctrl message since it's already processed */
326 		switch (ctrl_type) {
327 		case BNEP_SETUP_CONN_REQ:
328 			/* Pull: ctrl type (1 b), len (1 b), data (len bytes) */
329 			if (!skb_pull(skb, 2 + *(u8 *)(skb->data + 1) * 2))
330 				goto badframe;
331 			break;
332 		case BNEP_FILTER_MULTI_ADDR_SET:
333 		case BNEP_FILTER_NET_TYPE_SET:
334 			/* Pull: ctrl type (1 b), len (2 b), data (len bytes) */
335 			if (!skb_pull(skb, 3 + *(u16 *)(skb->data + 1) * 2))
336 				goto badframe;
337 			break;
338 		default:
339 			kfree_skb(skb);
340 			return 0;
341 		}
342 	} else {
343 		skb_reset_mac_header(skb);
344 
345 		/* Verify and pull out header */
346 		if (!skb_pull(skb, __bnep_rx_hlen[type & BNEP_TYPE_MASK]))
347 			goto badframe;
348 
349 		s->eh.h_proto = get_unaligned((__be16 *) (skb->data - 2));
350 	}
351 
352 	if (type & BNEP_EXT_HEADER) {
353 		if (bnep_rx_extension(s, skb) < 0)
354 			goto badframe;
355 	}
356 
357 	/* Strip 802.1p header */
358 	if (ntohs(s->eh.h_proto) == ETH_P_8021Q) {
359 		if (!skb_pull(skb, 4))
360 			goto badframe;
361 		s->eh.h_proto = get_unaligned((__be16 *) (skb->data - 2));
362 	}
363 
364 	/* We have to alloc new skb and copy data here :(. Because original skb
365 	 * may not be modified and because of the alignment requirements. */
366 	nskb = alloc_skb(2 + ETH_HLEN + skb->len, GFP_KERNEL);
367 	if (!nskb) {
368 		dev->stats.rx_dropped++;
369 		kfree_skb(skb);
370 		return -ENOMEM;
371 	}
372 	skb_reserve(nskb, 2);
373 
374 	/* Decompress header and construct ether frame */
375 	switch (type & BNEP_TYPE_MASK) {
376 	case BNEP_COMPRESSED:
377 		__skb_put_data(nskb, &s->eh, ETH_HLEN);
378 		break;
379 
380 	case BNEP_COMPRESSED_SRC_ONLY:
381 		__skb_put_data(nskb, s->eh.h_dest, ETH_ALEN);
382 		__skb_put_data(nskb, skb_mac_header(skb), ETH_ALEN);
383 		put_unaligned(s->eh.h_proto, (__be16 *) __skb_put(nskb, 2));
384 		break;
385 
386 	case BNEP_COMPRESSED_DST_ONLY:
387 		__skb_put_data(nskb, skb_mac_header(skb), ETH_ALEN);
388 		__skb_put_data(nskb, s->eh.h_source, ETH_ALEN);
389 		put_unaligned(s->eh.h_proto, (__be16 *)__skb_put(nskb, 2));
390 		break;
391 
392 	case BNEP_GENERAL:
393 		__skb_put_data(nskb, skb_mac_header(skb), ETH_ALEN * 2);
394 		put_unaligned(s->eh.h_proto, (__be16 *) __skb_put(nskb, 2));
395 		break;
396 	}
397 
398 	skb_copy_from_linear_data(skb, __skb_put(nskb, skb->len), skb->len);
399 	kfree_skb(skb);
400 
401 	dev->stats.rx_packets++;
402 	nskb->ip_summed = CHECKSUM_NONE;
403 	nskb->protocol  = eth_type_trans(nskb, dev);
404 	netif_rx(nskb);
405 	return 0;
406 
407 badframe:
408 	dev->stats.rx_errors++;
409 	kfree_skb(skb);
410 	return 0;
411 }
412 
413 static u8 __bnep_tx_types[] = {
414 	BNEP_GENERAL,
415 	BNEP_COMPRESSED_SRC_ONLY,
416 	BNEP_COMPRESSED_DST_ONLY,
417 	BNEP_COMPRESSED
418 };
419 
420 static int bnep_tx_frame(struct bnep_session *s, struct sk_buff *skb)
421 {
422 	struct ethhdr *eh = (void *) skb->data;
423 	struct socket *sock = s->sock;
424 	struct kvec iv[3];
425 	int len = 0, il = 0;
426 	u8 type = 0;
427 
428 	BT_DBG("skb %p dev %p type %u", skb, skb->dev, skb->pkt_type);
429 
430 	if (!skb->dev) {
431 		/* Control frame sent by us */
432 		goto send;
433 	}
434 
435 	iv[il++] = (struct kvec) { &type, 1 };
436 	len++;
437 
438 	if (compress_src && ether_addr_equal(eh->h_dest, s->eh.h_source))
439 		type |= 0x01;
440 
441 	if (compress_dst && ether_addr_equal(eh->h_source, s->eh.h_dest))
442 		type |= 0x02;
443 
444 	if (type)
445 		skb_pull(skb, ETH_ALEN * 2);
446 
447 	type = __bnep_tx_types[type];
448 	switch (type) {
449 	case BNEP_COMPRESSED_SRC_ONLY:
450 		iv[il++] = (struct kvec) { eh->h_source, ETH_ALEN };
451 		len += ETH_ALEN;
452 		break;
453 
454 	case BNEP_COMPRESSED_DST_ONLY:
455 		iv[il++] = (struct kvec) { eh->h_dest, ETH_ALEN };
456 		len += ETH_ALEN;
457 		break;
458 	}
459 
460 send:
461 	iv[il++] = (struct kvec) { skb->data, skb->len };
462 	len += skb->len;
463 
464 	/* FIXME: linearize skb */
465 	{
466 		len = kernel_sendmsg(sock, &s->msg, iv, il, len);
467 	}
468 	kfree_skb(skb);
469 
470 	if (len > 0) {
471 		s->dev->stats.tx_bytes += len;
472 		s->dev->stats.tx_packets++;
473 		return 0;
474 	}
475 
476 	return len;
477 }
478 
479 static int bnep_session(void *arg)
480 {
481 	struct bnep_session *s = arg;
482 	struct net_device *dev = s->dev;
483 	struct sock *sk = s->sock->sk;
484 	struct sk_buff *skb;
485 	DEFINE_WAIT_FUNC(wait, woken_wake_function);
486 
487 	BT_DBG("");
488 
489 	set_user_nice(current, -15);
490 
491 	add_wait_queue(sk_sleep(sk), &wait);
492 	while (1) {
493 		if (atomic_read(&s->terminate))
494 			break;
495 		/* RX */
496 		while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
497 			skb_orphan(skb);
498 			if (!skb_linearize(skb))
499 				bnep_rx_frame(s, skb);
500 			else
501 				kfree_skb(skb);
502 		}
503 
504 		if (sk->sk_state != BT_CONNECTED)
505 			break;
506 
507 		/* TX */
508 		while ((skb = skb_dequeue(&sk->sk_write_queue)))
509 			if (bnep_tx_frame(s, skb))
510 				break;
511 		netif_wake_queue(dev);
512 
513 		/*
514 		 * wait_woken() performs the necessary memory barriers
515 		 * for us; see the header comment for this primitive.
516 		 */
517 		wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT);
518 	}
519 	remove_wait_queue(sk_sleep(sk), &wait);
520 
521 	/* Cleanup session */
522 	down_write(&bnep_session_sem);
523 
524 	/* Delete network device */
525 	unregister_netdev(dev);
526 
527 	/* Wakeup user-space polling for socket errors */
528 	s->sock->sk->sk_err = EUNATCH;
529 
530 	wake_up_interruptible(sk_sleep(s->sock->sk));
531 
532 	/* Release the socket */
533 	fput(s->sock->file);
534 
535 	__bnep_unlink_session(s);
536 
537 	up_write(&bnep_session_sem);
538 	free_netdev(dev);
539 	module_put_and_kthread_exit(0);
540 	return 0;
541 }
542 
543 static struct device *bnep_get_device(struct bnep_session *session)
544 {
545 	struct l2cap_conn *conn = l2cap_pi(session->sock->sk)->chan->conn;
546 
547 	if (!conn || !conn->hcon)
548 		return NULL;
549 
550 	return &conn->hcon->dev;
551 }
552 
553 static struct device_type bnep_type = {
554 	.name	= "bluetooth",
555 };
556 
557 int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
558 {
559 	u32 valid_flags = BIT(BNEP_SETUP_RESPONSE);
560 	struct net_device *dev;
561 	struct bnep_session *s, *ss;
562 	u8 dst[ETH_ALEN], src[ETH_ALEN];
563 	int err;
564 
565 	BT_DBG("");
566 
567 	if (!l2cap_is_socket(sock))
568 		return -EBADFD;
569 
570 	if (req->flags & ~valid_flags)
571 		return -EINVAL;
572 
573 	baswap((void *) dst, &l2cap_pi(sock->sk)->chan->dst);
574 	baswap((void *) src, &l2cap_pi(sock->sk)->chan->src);
575 
576 	/* session struct allocated as private part of net_device */
577 	dev = alloc_netdev(sizeof(struct bnep_session),
578 			   (*req->device) ? req->device : "bnep%d",
579 			   NET_NAME_UNKNOWN,
580 			   bnep_net_setup);
581 	if (!dev)
582 		return -ENOMEM;
583 
584 	down_write(&bnep_session_sem);
585 
586 	ss = __bnep_get_session(dst);
587 	if (ss && ss->state == BT_CONNECTED) {
588 		err = -EEXIST;
589 		goto failed;
590 	}
591 
592 	s = netdev_priv(dev);
593 
594 	/* This is rx header therefore addresses are swapped.
595 	 * ie. eh.h_dest is our local address. */
596 	memcpy(s->eh.h_dest,   &src, ETH_ALEN);
597 	memcpy(s->eh.h_source, &dst, ETH_ALEN);
598 	eth_hw_addr_set(dev, s->eh.h_dest);
599 
600 	s->dev   = dev;
601 	s->sock  = sock;
602 	s->role  = req->role;
603 	s->state = BT_CONNECTED;
604 	s->flags = req->flags;
605 
606 	s->msg.msg_flags = MSG_NOSIGNAL;
607 
608 #ifdef CONFIG_BT_BNEP_MC_FILTER
609 	/* Set default mc filter to not filter out any mc addresses
610 	 * as defined in the BNEP specification (revision 0.95a)
611 	 * http://grouper.ieee.org/groups/802/15/Bluetooth/BNEP.pdf
612 	 */
613 	s->mc_filter = ~0LL;
614 #endif
615 
616 #ifdef CONFIG_BT_BNEP_PROTO_FILTER
617 	/* Set default protocol filter */
618 	bnep_set_default_proto_filter(s);
619 #endif
620 
621 	SET_NETDEV_DEV(dev, bnep_get_device(s));
622 	SET_NETDEV_DEVTYPE(dev, &bnep_type);
623 
624 	err = register_netdev(dev);
625 	if (err)
626 		goto failed;
627 
628 	__bnep_link_session(s);
629 
630 	__module_get(THIS_MODULE);
631 	s->task = kthread_run(bnep_session, s, "kbnepd %s", dev->name);
632 	if (IS_ERR(s->task)) {
633 		/* Session thread start failed, gotta cleanup. */
634 		module_put(THIS_MODULE);
635 		unregister_netdev(dev);
636 		__bnep_unlink_session(s);
637 		err = PTR_ERR(s->task);
638 		goto failed;
639 	}
640 
641 	up_write(&bnep_session_sem);
642 	strcpy(req->device, dev->name);
643 	return 0;
644 
645 failed:
646 	up_write(&bnep_session_sem);
647 	free_netdev(dev);
648 	return err;
649 }
650 
651 int bnep_del_connection(struct bnep_conndel_req *req)
652 {
653 	u32 valid_flags = 0;
654 	struct bnep_session *s;
655 	int  err = 0;
656 
657 	BT_DBG("");
658 
659 	if (req->flags & ~valid_flags)
660 		return -EINVAL;
661 
662 	down_read(&bnep_session_sem);
663 
664 	s = __bnep_get_session(req->dst);
665 	if (s) {
666 		atomic_inc(&s->terminate);
667 		wake_up_interruptible(sk_sleep(s->sock->sk));
668 	} else
669 		err = -ENOENT;
670 
671 	up_read(&bnep_session_sem);
672 	return err;
673 }
674 
675 static void __bnep_copy_ci(struct bnep_conninfo *ci, struct bnep_session *s)
676 {
677 	u32 valid_flags = BIT(BNEP_SETUP_RESPONSE);
678 
679 	memset(ci, 0, sizeof(*ci));
680 	memcpy(ci->dst, s->eh.h_source, ETH_ALEN);
681 	strcpy(ci->device, s->dev->name);
682 	ci->flags = s->flags & valid_flags;
683 	ci->state = s->state;
684 	ci->role  = s->role;
685 }
686 
687 int bnep_get_connlist(struct bnep_connlist_req *req)
688 {
689 	struct bnep_session *s;
690 	int err = 0, n = 0;
691 
692 	down_read(&bnep_session_sem);
693 
694 	list_for_each_entry(s, &bnep_session_list, list) {
695 		struct bnep_conninfo ci;
696 
697 		__bnep_copy_ci(&ci, s);
698 
699 		if (copy_to_user(req->ci, &ci, sizeof(ci))) {
700 			err = -EFAULT;
701 			break;
702 		}
703 
704 		if (++n >= req->cnum)
705 			break;
706 
707 		req->ci++;
708 	}
709 	req->cnum = n;
710 
711 	up_read(&bnep_session_sem);
712 	return err;
713 }
714 
715 int bnep_get_conninfo(struct bnep_conninfo *ci)
716 {
717 	struct bnep_session *s;
718 	int err = 0;
719 
720 	down_read(&bnep_session_sem);
721 
722 	s = __bnep_get_session(ci->dst);
723 	if (s)
724 		__bnep_copy_ci(ci, s);
725 	else
726 		err = -ENOENT;
727 
728 	up_read(&bnep_session_sem);
729 	return err;
730 }
731 
732 static int __init bnep_init(void)
733 {
734 	char flt[50] = "";
735 
736 #ifdef CONFIG_BT_BNEP_PROTO_FILTER
737 	strcat(flt, "protocol ");
738 #endif
739 
740 #ifdef CONFIG_BT_BNEP_MC_FILTER
741 	strcat(flt, "multicast");
742 #endif
743 
744 	BT_INFO("BNEP (Ethernet Emulation) ver %s", VERSION);
745 	if (flt[0])
746 		BT_INFO("BNEP filters: %s", flt);
747 
748 	return bnep_sock_init();
749 }
750 
751 static void __exit bnep_exit(void)
752 {
753 	bnep_sock_cleanup();
754 }
755 
756 module_init(bnep_init);
757 module_exit(bnep_exit);
758 
759 module_param(compress_src, bool, 0644);
760 MODULE_PARM_DESC(compress_src, "Compress sources headers");
761 
762 module_param(compress_dst, bool, 0644);
763 MODULE_PARM_DESC(compress_dst, "Compress destination headers");
764 
765 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
766 MODULE_DESCRIPTION("Bluetooth BNEP ver " VERSION);
767 MODULE_VERSION(VERSION);
768 MODULE_LICENSE("GPL");
769 MODULE_ALIAS("bt-proto-4");
770