aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/l2cap.c
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2009-02-11 23:07:45 -0500
committerMarcel Holtmann <marcel@holtmann.org>2009-02-27 00:14:42 -0500
commitf29972de8e7476706ab3c01304a505e7c95d9040 (patch)
tree966729f6b80d0e149b0ece4367d27f52306cc8cb /net/bluetooth/l2cap.c
parente1027a7c69700301d14db03d2e049ee60c4f92df (diff)
Bluetooth: Add CID field to L2CAP socket address structure
In preparation for L2CAP fixed channel support, the CID value of a L2CAP connection needs to be accessible via the socket interface. The CID is the connection identifier and exists as source and destination value. So extend the L2CAP socket address structure with this field and change getsockname() and getpeername() to fill it in. The bind() and connect() functions have been modified to handle L2CAP socket address structures of variable sizes. This makes them future proof if additional fields need to be added. Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth/l2cap.c')
-rw-r--r--net/bluetooth/l2cap.c55
1 files changed, 34 insertions, 21 deletions
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 985366c36f48..7bba469b6828 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -770,17 +770,21 @@ static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol)
770 return 0; 770 return 0;
771} 771}
772 772
773static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len) 773static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
774{ 774{
775 struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
776 struct sock *sk = sock->sk; 775 struct sock *sk = sock->sk;
777 int err = 0; 776 struct sockaddr_l2 la;
777 int len, err = 0;
778 778
779 BT_DBG("sk %p, %s %d", sk, batostr(&la->l2_bdaddr), la->l2_psm); 779 BT_DBG("sk %p", sk);
780 780
781 if (!addr || addr->sa_family != AF_BLUETOOTH) 781 if (!addr || addr->sa_family != AF_BLUETOOTH)
782 return -EINVAL; 782 return -EINVAL;
783 783
784 memset(&la, 0, sizeof(la));
785 len = min_t(unsigned int, sizeof(la), alen);
786 memcpy(&la, addr, len);
787
784 lock_sock(sk); 788 lock_sock(sk);
785 789
786 if (sk->sk_state != BT_OPEN) { 790 if (sk->sk_state != BT_OPEN) {
@@ -788,7 +792,7 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_
788 goto done; 792 goto done;
789 } 793 }
790 794
791 if (la->l2_psm && btohs(la->l2_psm) < 0x1001 && 795 if (la.l2_psm && btohs(la.l2_psm) < 0x1001 &&
792 !capable(CAP_NET_BIND_SERVICE)) { 796 !capable(CAP_NET_BIND_SERVICE)) {
793 err = -EACCES; 797 err = -EACCES;
794 goto done; 798 goto done;
@@ -796,16 +800,16 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_
796 800
797 write_lock_bh(&l2cap_sk_list.lock); 801 write_lock_bh(&l2cap_sk_list.lock);
798 802
799 if (la->l2_psm && __l2cap_get_sock_by_addr(la->l2_psm, &la->l2_bdaddr)) { 803 if (la.l2_psm && __l2cap_get_sock_by_addr(la.l2_psm, &la.l2_bdaddr)) {
800 err = -EADDRINUSE; 804 err = -EADDRINUSE;
801 } else { 805 } else {
802 /* Save source address */ 806 /* Save source address */
803 bacpy(&bt_sk(sk)->src, &la->l2_bdaddr); 807 bacpy(&bt_sk(sk)->src, &la.l2_bdaddr);
804 l2cap_pi(sk)->psm = la->l2_psm; 808 l2cap_pi(sk)->psm = la.l2_psm;
805 l2cap_pi(sk)->sport = la->l2_psm; 809 l2cap_pi(sk)->sport = la.l2_psm;
806 sk->sk_state = BT_BOUND; 810 sk->sk_state = BT_BOUND;
807 811
808 if (btohs(la->l2_psm) == 0x0001 || btohs(la->l2_psm) == 0x0003) 812 if (btohs(la.l2_psm) == 0x0001 || btohs(la.l2_psm) == 0x0003)
809 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP; 813 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
810 } 814 }
811 815
@@ -826,7 +830,8 @@ static int l2cap_do_connect(struct sock *sk)
826 __u8 auth_type; 830 __u8 auth_type;
827 int err = 0; 831 int err = 0;
828 832
829 BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst), l2cap_pi(sk)->psm); 833 BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst),
834 l2cap_pi(sk)->psm);
830 835
831 if (!(hdev = hci_get_route(dst, src))) 836 if (!(hdev = hci_get_route(dst, src)))
832 return -EHOSTUNREACH; 837 return -EHOSTUNREACH;
@@ -906,20 +911,24 @@ done:
906 911
907static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags) 912static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
908{ 913{
909 struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
910 struct sock *sk = sock->sk; 914 struct sock *sk = sock->sk;
911 int err = 0; 915 struct sockaddr_l2 la;
916 int len, err = 0;
912 917
913 lock_sock(sk); 918 lock_sock(sk);
914 919
915 BT_DBG("sk %p", sk); 920 BT_DBG("sk %p", sk);
916 921
917 if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_l2)) { 922 if (!addr || addr->sa_family != AF_BLUETOOTH) {
918 err = -EINVAL; 923 err = -EINVAL;
919 goto done; 924 goto done;
920 } 925 }
921 926
922 if (sk->sk_type == SOCK_SEQPACKET && !la->l2_psm) { 927 memset(&la, 0, sizeof(la));
928 len = min_t(unsigned int, sizeof(la), alen);
929 memcpy(&la, addr, len);
930
931 if (sk->sk_type == SOCK_SEQPACKET && !la.l2_psm) {
923 err = -EINVAL; 932 err = -EINVAL;
924 goto done; 933 goto done;
925 } 934 }
@@ -946,8 +955,8 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
946 } 955 }
947 956
948 /* Set destination address and psm */ 957 /* Set destination address and psm */
949 bacpy(&bt_sk(sk)->dst, &la->l2_bdaddr); 958 bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr);
950 l2cap_pi(sk)->psm = la->l2_psm; 959 l2cap_pi(sk)->psm = la.l2_psm;
951 960
952 if ((err = l2cap_do_connect(sk))) 961 if ((err = l2cap_do_connect(sk)))
953 goto done; 962 goto done;
@@ -1071,12 +1080,16 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *l
1071 addr->sa_family = AF_BLUETOOTH; 1080 addr->sa_family = AF_BLUETOOTH;
1072 *len = sizeof(struct sockaddr_l2); 1081 *len = sizeof(struct sockaddr_l2);
1073 1082
1074 if (peer) 1083 if (peer) {
1084 la->l2_psm = l2cap_pi(sk)->psm;
1075 bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst); 1085 bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst);
1076 else 1086 la->l2_cid = htobs(l2cap_pi(sk)->dcid);
1087 } else {
1088 la->l2_psm = l2cap_pi(sk)->sport;
1077 bacpy(&la->l2_bdaddr, &bt_sk(sk)->src); 1089 bacpy(&la->l2_bdaddr, &bt_sk(sk)->src);
1090 la->l2_cid = htobs(l2cap_pi(sk)->scid);
1091 }
1078 1092
1079 la->l2_psm = l2cap_pi(sk)->psm;
1080 return 0; 1093 return 0;
1081} 1094}
1082 1095
@@ -1208,7 +1221,7 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us
1208{ 1221{
1209 struct sock *sk = sock->sk; 1222 struct sock *sk = sock->sk;
1210 struct l2cap_options opts; 1223 struct l2cap_options opts;
1211 int err = 0, len; 1224 int len, err = 0;
1212 u32 opt; 1225 u32 opt;
1213 1226
1214 BT_DBG("sk %p", sk); 1227 BT_DBG("sk %p", sk);