Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 134736
b: refs/heads/master
c: f29972d
h: refs/heads/master
v: v3
  • Loading branch information
Marcel Holtmann committed Feb 27, 2009
1 parent e15031c commit 16cc53e
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 22 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: e1027a7c69700301d14db03d2e049ee60c4f92df
refs/heads/master: f29972de8e7476706ab3c01304a505e7c95d9040
1 change: 1 addition & 0 deletions trunk/include/net/bluetooth/l2cap.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ struct sockaddr_l2 {
sa_family_t l2_family;
__le16 l2_psm;
bdaddr_t l2_bdaddr;
__le16 l2_cid;
};

/* L2CAP socket options */
Expand Down
55 changes: 34 additions & 21 deletions trunk/net/bluetooth/l2cap.c
Original file line number Diff line number Diff line change
Expand Up @@ -770,42 +770,46 @@ static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol)
return 0;
}

static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
{
struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
struct sock *sk = sock->sk;
int err = 0;
struct sockaddr_l2 la;
int len, err = 0;

BT_DBG("sk %p, %s %d", sk, batostr(&la->l2_bdaddr), la->l2_psm);
BT_DBG("sk %p", sk);

if (!addr || addr->sa_family != AF_BLUETOOTH)
return -EINVAL;

memset(&la, 0, sizeof(la));
len = min_t(unsigned int, sizeof(la), alen);
memcpy(&la, addr, len);

lock_sock(sk);

if (sk->sk_state != BT_OPEN) {
err = -EBADFD;
goto done;
}

if (la->l2_psm && btohs(la->l2_psm) < 0x1001 &&
if (la.l2_psm && btohs(la.l2_psm) < 0x1001 &&
!capable(CAP_NET_BIND_SERVICE)) {
err = -EACCES;
goto done;
}

write_lock_bh(&l2cap_sk_list.lock);

if (la->l2_psm && __l2cap_get_sock_by_addr(la->l2_psm, &la->l2_bdaddr)) {
if (la.l2_psm && __l2cap_get_sock_by_addr(la.l2_psm, &la.l2_bdaddr)) {
err = -EADDRINUSE;
} else {
/* Save source address */
bacpy(&bt_sk(sk)->src, &la->l2_bdaddr);
l2cap_pi(sk)->psm = la->l2_psm;
l2cap_pi(sk)->sport = la->l2_psm;
bacpy(&bt_sk(sk)->src, &la.l2_bdaddr);
l2cap_pi(sk)->psm = la.l2_psm;
l2cap_pi(sk)->sport = la.l2_psm;
sk->sk_state = BT_BOUND;

if (btohs(la->l2_psm) == 0x0001 || btohs(la->l2_psm) == 0x0003)
if (btohs(la.l2_psm) == 0x0001 || btohs(la.l2_psm) == 0x0003)
l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
}

Expand All @@ -826,7 +830,8 @@ static int l2cap_do_connect(struct sock *sk)
__u8 auth_type;
int err = 0;

BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst), l2cap_pi(sk)->psm);
BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst),
l2cap_pi(sk)->psm);

if (!(hdev = hci_get_route(dst, src)))
return -EHOSTUNREACH;
Expand Down Expand Up @@ -906,20 +911,24 @@ static int l2cap_do_connect(struct sock *sk)

static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
{
struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
struct sock *sk = sock->sk;
int err = 0;
struct sockaddr_l2 la;
int len, err = 0;

lock_sock(sk);

BT_DBG("sk %p", sk);

if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_l2)) {
if (!addr || addr->sa_family != AF_BLUETOOTH) {
err = -EINVAL;
goto done;
}

if (sk->sk_type == SOCK_SEQPACKET && !la->l2_psm) {
memset(&la, 0, sizeof(la));
len = min_t(unsigned int, sizeof(la), alen);
memcpy(&la, addr, len);

if (sk->sk_type == SOCK_SEQPACKET && !la.l2_psm) {
err = -EINVAL;
goto done;
}
Expand All @@ -946,8 +955,8 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
}

/* Set destination address and psm */
bacpy(&bt_sk(sk)->dst, &la->l2_bdaddr);
l2cap_pi(sk)->psm = la->l2_psm;
bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr);
l2cap_pi(sk)->psm = la.l2_psm;

if ((err = l2cap_do_connect(sk)))
goto done;
Expand Down Expand Up @@ -1071,12 +1080,16 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *l
addr->sa_family = AF_BLUETOOTH;
*len = sizeof(struct sockaddr_l2);

if (peer)
if (peer) {
la->l2_psm = l2cap_pi(sk)->psm;
bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst);
else
la->l2_cid = htobs(l2cap_pi(sk)->dcid);
} else {
la->l2_psm = l2cap_pi(sk)->sport;
bacpy(&la->l2_bdaddr, &bt_sk(sk)->src);
la->l2_cid = htobs(l2cap_pi(sk)->scid);
}

la->l2_psm = l2cap_pi(sk)->psm;
return 0;
}

Expand Down Expand Up @@ -1208,7 +1221,7 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us
{
struct sock *sk = sock->sk;
struct l2cap_options opts;
int err = 0, len;
int len, err = 0;
u32 opt;

BT_DBG("sk %p", sk);
Expand Down

0 comments on commit 16cc53e

Please sign in to comment.