diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2009-01-15 15:58:38 -0500 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2009-02-27 00:14:26 -0500 |
commit | 2af6b9d518ddfbc4d6990d5f9c9b1a05341c1cef (patch) | |
tree | 62b6f679495026ccf64c1b71d48cede452689b73 /net/bluetooth/l2cap.c | |
parent | 8c1b235594fbab9a13240a1dac12ea9fd99b6440 (diff) |
Bluetooth: Replace L2CAP link mode with security level
Change the L2CAP internals to use the new security levels and remove
the link mode details.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth/l2cap.c')
-rw-r--r-- | net/bluetooth/l2cap.c | 160 |
1 files changed, 110 insertions, 50 deletions
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index eadf09231866..e899a9371c00 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
@@ -78,8 +78,7 @@ static void l2cap_sock_timeout(unsigned long arg) | |||
78 | bh_lock_sock(sk); | 78 | bh_lock_sock(sk); |
79 | 79 | ||
80 | if (sk->sk_state == BT_CONNECT && | 80 | if (sk->sk_state == BT_CONNECT && |
81 | (l2cap_pi(sk)->link_mode & (L2CAP_LM_AUTH | | 81 | l2cap_pi(sk)->sec_level != BT_SECURITY_SDP) |
82 | L2CAP_LM_ENCRYPT | L2CAP_LM_SECURE))) | ||
83 | reason = ECONNREFUSED; | 82 | reason = ECONNREFUSED; |
84 | else | 83 | else |
85 | reason = ETIMEDOUT; | 84 | reason = ETIMEDOUT; |
@@ -259,23 +258,11 @@ static void l2cap_chan_del(struct sock *sk, int err) | |||
259 | } | 258 | } |
260 | 259 | ||
261 | /* Service level security */ | 260 | /* Service level security */ |
262 | static inline int l2cap_check_link_mode(struct sock *sk) | 261 | static inline int l2cap_check_security(struct sock *sk) |
263 | { | 262 | { |
264 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | 263 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; |
265 | 264 | ||
266 | if (l2cap_pi(sk)->link_mode & L2CAP_LM_SECURE) | 265 | return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level); |
267 | return hci_conn_security(conn->hcon, BT_SECURITY_HIGH); | ||
268 | |||
269 | if (l2cap_pi(sk)->link_mode & L2CAP_LM_ENCRYPT) | ||
270 | return hci_conn_security(conn->hcon, BT_SECURITY_MEDIUM); | ||
271 | |||
272 | if (l2cap_pi(sk)->link_mode & L2CAP_LM_AUTH) | ||
273 | return hci_conn_security(conn->hcon, BT_SECURITY_LOW); | ||
274 | |||
275 | if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) | ||
276 | return hci_conn_security(conn->hcon, BT_SECURITY_SDP); | ||
277 | |||
278 | return 1; | ||
279 | } | 266 | } |
280 | 267 | ||
281 | static inline u8 l2cap_get_ident(struct l2cap_conn *conn) | 268 | static inline u8 l2cap_get_ident(struct l2cap_conn *conn) |
@@ -317,7 +304,7 @@ static void l2cap_do_start(struct sock *sk) | |||
317 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | 304 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; |
318 | 305 | ||
319 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) { | 306 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) { |
320 | if (l2cap_check_link_mode(sk)) { | 307 | if (l2cap_check_security(sk)) { |
321 | struct l2cap_conn_req req; | 308 | struct l2cap_conn_req req; |
322 | req.scid = cpu_to_le16(l2cap_pi(sk)->scid); | 309 | req.scid = cpu_to_le16(l2cap_pi(sk)->scid); |
323 | req.psm = l2cap_pi(sk)->psm; | 310 | req.psm = l2cap_pi(sk)->psm; |
@@ -361,7 +348,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn) | |||
361 | } | 348 | } |
362 | 349 | ||
363 | if (sk->sk_state == BT_CONNECT) { | 350 | if (sk->sk_state == BT_CONNECT) { |
364 | if (l2cap_check_link_mode(sk)) { | 351 | if (l2cap_check_security(sk)) { |
365 | struct l2cap_conn_req req; | 352 | struct l2cap_conn_req req; |
366 | req.scid = cpu_to_le16(l2cap_pi(sk)->scid); | 353 | req.scid = cpu_to_le16(l2cap_pi(sk)->scid); |
367 | req.psm = l2cap_pi(sk)->psm; | 354 | req.psm = l2cap_pi(sk)->psm; |
@@ -376,7 +363,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn) | |||
376 | rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); | 363 | rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); |
377 | rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); | 364 | rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); |
378 | 365 | ||
379 | if (l2cap_check_link_mode(sk)) { | 366 | if (l2cap_check_security(sk)) { |
380 | if (bt_sk(sk)->defer_setup) { | 367 | if (bt_sk(sk)->defer_setup) { |
381 | struct sock *parent = bt_sk(sk)->parent; | 368 | struct sock *parent = bt_sk(sk)->parent; |
382 | rsp.result = cpu_to_le16(L2CAP_CR_PEND); | 369 | rsp.result = cpu_to_le16(L2CAP_CR_PEND); |
@@ -439,7 +426,7 @@ static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err) | |||
439 | read_lock(&l->lock); | 426 | read_lock(&l->lock); |
440 | 427 | ||
441 | for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) { | 428 | for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) { |
442 | if (l2cap_pi(sk)->link_mode & L2CAP_LM_RELIABLE) | 429 | if (l2cap_pi(sk)->force_reliable) |
443 | sk->sk_err = err; | 430 | sk->sk_err = err; |
444 | } | 431 | } |
445 | 432 | ||
@@ -690,11 +677,15 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent) | |||
690 | 677 | ||
691 | pi->imtu = l2cap_pi(parent)->imtu; | 678 | pi->imtu = l2cap_pi(parent)->imtu; |
692 | pi->omtu = l2cap_pi(parent)->omtu; | 679 | pi->omtu = l2cap_pi(parent)->omtu; |
693 | pi->link_mode = l2cap_pi(parent)->link_mode; | 680 | pi->sec_level = l2cap_pi(parent)->sec_level; |
681 | pi->role_switch = l2cap_pi(parent)->role_switch; | ||
682 | pi->force_reliable = l2cap_pi(parent)->force_reliable; | ||
694 | } else { | 683 | } else { |
695 | pi->imtu = L2CAP_DEFAULT_MTU; | 684 | pi->imtu = L2CAP_DEFAULT_MTU; |
696 | pi->omtu = 0; | 685 | pi->omtu = 0; |
697 | pi->link_mode = 0; | 686 | pi->sec_level = BT_SECURITY_LOW; |
687 | pi->role_switch = 0; | ||
688 | pi->force_reliable = 0; | ||
698 | } | 689 | } |
699 | 690 | ||
700 | /* Default config options */ | 691 | /* Default config options */ |
@@ -792,6 +783,9 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_ | |||
792 | l2cap_pi(sk)->psm = la->l2_psm; | 783 | l2cap_pi(sk)->psm = la->l2_psm; |
793 | l2cap_pi(sk)->sport = la->l2_psm; | 784 | l2cap_pi(sk)->sport = la->l2_psm; |
794 | sk->sk_state = BT_BOUND; | 785 | sk->sk_state = BT_BOUND; |
786 | |||
787 | if (btohs(la->l2_psm) == 0x0001) | ||
788 | l2cap_pi(sk)->sec_level = BT_SECURITY_SDP; | ||
795 | } | 789 | } |
796 | 790 | ||
797 | write_unlock_bh(&l2cap_sk_list.lock); | 791 | write_unlock_bh(&l2cap_sk_list.lock); |
@@ -808,7 +802,6 @@ static int l2cap_do_connect(struct sock *sk) | |||
808 | struct l2cap_conn *conn; | 802 | struct l2cap_conn *conn; |
809 | struct hci_conn *hcon; | 803 | struct hci_conn *hcon; |
810 | struct hci_dev *hdev; | 804 | struct hci_dev *hdev; |
811 | __u8 sec_level; | ||
812 | __u8 auth_type; | 805 | __u8 auth_type; |
813 | int err = 0; | 806 | int err = 0; |
814 | 807 | ||
@@ -821,37 +814,39 @@ static int l2cap_do_connect(struct sock *sk) | |||
821 | 814 | ||
822 | err = -ENOMEM; | 815 | err = -ENOMEM; |
823 | 816 | ||
824 | if (l2cap_pi(sk)->link_mode & L2CAP_LM_SECURE) | ||
825 | sec_level = BT_SECURITY_HIGH; | ||
826 | else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) | ||
827 | sec_level = BT_SECURITY_SDP; | ||
828 | else if (l2cap_pi(sk)->link_mode & L2CAP_LM_ENCRYPT) | ||
829 | sec_level = BT_SECURITY_MEDIUM; | ||
830 | else | ||
831 | sec_level = BT_SECURITY_LOW; | ||
832 | |||
833 | if (sk->sk_type == SOCK_RAW) { | 817 | if (sk->sk_type == SOCK_RAW) { |
834 | if (l2cap_pi(sk)->link_mode & L2CAP_LM_SECURE) | 818 | switch (l2cap_pi(sk)->sec_level) { |
819 | case BT_SECURITY_HIGH: | ||
835 | auth_type = HCI_AT_DEDICATED_BONDING_MITM; | 820 | auth_type = HCI_AT_DEDICATED_BONDING_MITM; |
836 | else if (l2cap_pi(sk)->link_mode & L2CAP_LM_ENCRYPT) | 821 | break; |
822 | case BT_SECURITY_MEDIUM: | ||
837 | auth_type = HCI_AT_DEDICATED_BONDING; | 823 | auth_type = HCI_AT_DEDICATED_BONDING; |
838 | else | 824 | break; |
825 | default: | ||
839 | auth_type = HCI_AT_NO_BONDING; | 826 | auth_type = HCI_AT_NO_BONDING; |
827 | break; | ||
828 | } | ||
840 | } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) { | 829 | } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) { |
841 | if (l2cap_pi(sk)->link_mode & L2CAP_LM_SECURE) | 830 | if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH) |
842 | auth_type = HCI_AT_NO_BONDING_MITM; | 831 | auth_type = HCI_AT_NO_BONDING_MITM; |
843 | else | 832 | else |
844 | auth_type = HCI_AT_NO_BONDING; | 833 | auth_type = HCI_AT_NO_BONDING; |
845 | } else { | 834 | } else { |
846 | if (l2cap_pi(sk)->link_mode & L2CAP_LM_SECURE) | 835 | switch (l2cap_pi(sk)->sec_level) { |
836 | case BT_SECURITY_HIGH: | ||
847 | auth_type = HCI_AT_GENERAL_BONDING_MITM; | 837 | auth_type = HCI_AT_GENERAL_BONDING_MITM; |
848 | else if (l2cap_pi(sk)->link_mode & L2CAP_LM_ENCRYPT) | 838 | break; |
839 | case BT_SECURITY_MEDIUM: | ||
849 | auth_type = HCI_AT_GENERAL_BONDING; | 840 | auth_type = HCI_AT_GENERAL_BONDING; |
850 | else | 841 | break; |
842 | default: | ||
851 | auth_type = HCI_AT_NO_BONDING; | 843 | auth_type = HCI_AT_NO_BONDING; |
844 | break; | ||
845 | } | ||
852 | } | 846 | } |
853 | 847 | ||
854 | hcon = hci_connect(hdev, ACL_LINK, dst, sec_level, auth_type); | 848 | hcon = hci_connect(hdev, ACL_LINK, dst, |
849 | l2cap_pi(sk)->sec_level, auth_type); | ||
855 | if (!hcon) | 850 | if (!hcon) |
856 | goto done; | 851 | goto done; |
857 | 852 | ||
@@ -1219,7 +1214,15 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us | |||
1219 | break; | 1214 | break; |
1220 | } | 1215 | } |
1221 | 1216 | ||
1222 | l2cap_pi(sk)->link_mode = opt; | 1217 | if (opt & L2CAP_LM_AUTH) |
1218 | l2cap_pi(sk)->sec_level = BT_SECURITY_LOW; | ||
1219 | if (opt & L2CAP_LM_ENCRYPT) | ||
1220 | l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM; | ||
1221 | if (opt & L2CAP_LM_SECURE) | ||
1222 | l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH; | ||
1223 | |||
1224 | l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER); | ||
1225 | l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE); | ||
1223 | break; | 1226 | break; |
1224 | 1227 | ||
1225 | default: | 1228 | default: |
@@ -1234,7 +1237,8 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us | |||
1234 | static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen) | 1237 | static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen) |
1235 | { | 1238 | { |
1236 | struct sock *sk = sock->sk; | 1239 | struct sock *sk = sock->sk; |
1237 | int err = 0; | 1240 | struct bt_security sec; |
1241 | int len, err = 0; | ||
1238 | u32 opt; | 1242 | u32 opt; |
1239 | 1243 | ||
1240 | BT_DBG("sk %p", sk); | 1244 | BT_DBG("sk %p", sk); |
@@ -1245,6 +1249,24 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch | |||
1245 | lock_sock(sk); | 1249 | lock_sock(sk); |
1246 | 1250 | ||
1247 | switch (optname) { | 1251 | switch (optname) { |
1252 | case BT_SECURITY: | ||
1253 | sec.level = BT_SECURITY_LOW; | ||
1254 | |||
1255 | len = min_t(unsigned int, sizeof(sec), optlen); | ||
1256 | if (copy_from_user((char *) &sec, optval, len)) { | ||
1257 | err = -EFAULT; | ||
1258 | break; | ||
1259 | } | ||
1260 | |||
1261 | if (sec.level < BT_SECURITY_LOW || | ||
1262 | sec.level > BT_SECURITY_HIGH) { | ||
1263 | err = -EINVAL; | ||
1264 | break; | ||
1265 | } | ||
1266 | |||
1267 | l2cap_pi(sk)->sec_level = sec.level; | ||
1268 | break; | ||
1269 | |||
1248 | case BT_DEFER_SETUP: | 1270 | case BT_DEFER_SETUP: |
1249 | if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) { | 1271 | if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) { |
1250 | err = -EINVAL; | 1272 | err = -EINVAL; |
@@ -1274,6 +1296,7 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __us | |||
1274 | struct l2cap_options opts; | 1296 | struct l2cap_options opts; |
1275 | struct l2cap_conninfo cinfo; | 1297 | struct l2cap_conninfo cinfo; |
1276 | int len, err = 0; | 1298 | int len, err = 0; |
1299 | u32 opt; | ||
1277 | 1300 | ||
1278 | BT_DBG("sk %p", sk); | 1301 | BT_DBG("sk %p", sk); |
1279 | 1302 | ||
@@ -1296,7 +1319,29 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __us | |||
1296 | break; | 1319 | break; |
1297 | 1320 | ||
1298 | case L2CAP_LM: | 1321 | case L2CAP_LM: |
1299 | if (put_user(l2cap_pi(sk)->link_mode, (u32 __user *) optval)) | 1322 | switch (l2cap_pi(sk)->sec_level) { |
1323 | case BT_SECURITY_LOW: | ||
1324 | opt = L2CAP_LM_AUTH; | ||
1325 | break; | ||
1326 | case BT_SECURITY_MEDIUM: | ||
1327 | opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT; | ||
1328 | break; | ||
1329 | case BT_SECURITY_HIGH: | ||
1330 | opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT | | ||
1331 | L2CAP_LM_SECURE; | ||
1332 | break; | ||
1333 | default: | ||
1334 | opt = 0; | ||
1335 | break; | ||
1336 | } | ||
1337 | |||
1338 | if (l2cap_pi(sk)->role_switch) | ||
1339 | opt |= L2CAP_LM_MASTER; | ||
1340 | |||
1341 | if (l2cap_pi(sk)->force_reliable) | ||
1342 | opt |= L2CAP_LM_RELIABLE; | ||
1343 | |||
1344 | if (put_user(opt, (u32 __user *) optval)) | ||
1300 | err = -EFAULT; | 1345 | err = -EFAULT; |
1301 | break; | 1346 | break; |
1302 | 1347 | ||
@@ -1329,6 +1374,7 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __us | |||
1329 | static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen) | 1374 | static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen) |
1330 | { | 1375 | { |
1331 | struct sock *sk = sock->sk; | 1376 | struct sock *sk = sock->sk; |
1377 | struct bt_security sec; | ||
1332 | int len, err = 0; | 1378 | int len, err = 0; |
1333 | 1379 | ||
1334 | BT_DBG("sk %p", sk); | 1380 | BT_DBG("sk %p", sk); |
@@ -1342,6 +1388,15 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch | |||
1342 | lock_sock(sk); | 1388 | lock_sock(sk); |
1343 | 1389 | ||
1344 | switch (optname) { | 1390 | switch (optname) { |
1391 | case BT_SECURITY: | ||
1392 | sec.level = l2cap_pi(sk)->sec_level; | ||
1393 | |||
1394 | len = min_t(unsigned int, len, sizeof(sec)); | ||
1395 | if (copy_to_user(optval, (char *) &sec, len)) | ||
1396 | err = -EFAULT; | ||
1397 | |||
1398 | break; | ||
1399 | |||
1345 | case BT_DEFER_SETUP: | 1400 | case BT_DEFER_SETUP: |
1346 | if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) { | 1401 | if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) { |
1347 | err = -EINVAL; | 1402 | err = -EINVAL; |
@@ -1771,7 +1826,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
1771 | l2cap_pi(sk)->ident = cmd->ident; | 1826 | l2cap_pi(sk)->ident = cmd->ident; |
1772 | 1827 | ||
1773 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) { | 1828 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) { |
1774 | if (l2cap_check_link_mode(sk)) { | 1829 | if (l2cap_check_security(sk)) { |
1775 | if (bt_sk(sk)->defer_setup) { | 1830 | if (bt_sk(sk)->defer_setup) { |
1776 | sk->sk_state = BT_CONNECT2; | 1831 | sk->sk_state = BT_CONNECT2; |
1777 | result = L2CAP_CR_PEND; | 1832 | result = L2CAP_CR_PEND; |
@@ -2299,10 +2354,15 @@ static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) | |||
2299 | continue; | 2354 | continue; |
2300 | 2355 | ||
2301 | if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) { | 2356 | if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) { |
2302 | lm1 |= (HCI_LM_ACCEPT | l2cap_pi(sk)->link_mode); | 2357 | lm1 |= HCI_LM_ACCEPT; |
2358 | if (l2cap_pi(sk)->role_switch) | ||
2359 | lm1 |= HCI_LM_MASTER; | ||
2303 | exact++; | 2360 | exact++; |
2304 | } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) | 2361 | } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) { |
2305 | lm2 |= (HCI_LM_ACCEPT | l2cap_pi(sk)->link_mode); | 2362 | lm2 |= HCI_LM_ACCEPT; |
2363 | if (l2cap_pi(sk)->role_switch) | ||
2364 | lm2 |= HCI_LM_MASTER; | ||
2365 | } | ||
2306 | } | 2366 | } |
2307 | read_unlock(&l2cap_sk_list.lock); | 2367 | read_unlock(&l2cap_sk_list.lock); |
2308 | 2368 | ||
@@ -2361,7 +2421,7 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | |||
2361 | bh_lock_sock(sk); | 2421 | bh_lock_sock(sk); |
2362 | 2422 | ||
2363 | if (!status && encrypt == 0x00 && | 2423 | if (!status && encrypt == 0x00 && |
2364 | (pi->link_mode & L2CAP_LM_SECURE) && | 2424 | pi->sec_level == BT_SECURITY_HIGH && |
2365 | (sk->sk_state == BT_CONNECTED || | 2425 | (sk->sk_state == BT_CONNECTED || |
2366 | sk->sk_state == BT_CONFIG)) { | 2426 | sk->sk_state == BT_CONFIG)) { |
2367 | __l2cap_sock_close(sk, ECONNREFUSED); | 2427 | __l2cap_sock_close(sk, ECONNREFUSED); |
@@ -2510,10 +2570,10 @@ static ssize_t l2cap_sysfs_show(struct class *dev, char *buf) | |||
2510 | sk_for_each(sk, node, &l2cap_sk_list.head) { | 2570 | sk_for_each(sk, node, &l2cap_sk_list.head) { |
2511 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 2571 | struct l2cap_pinfo *pi = l2cap_pi(sk); |
2512 | 2572 | ||
2513 | str += sprintf(str, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d 0x%x\n", | 2573 | str += sprintf(str, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n", |
2514 | batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), | 2574 | batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), |
2515 | sk->sk_state, btohs(pi->psm), pi->scid, pi->dcid, | 2575 | sk->sk_state, btohs(pi->psm), pi->scid, pi->dcid, |
2516 | pi->imtu, pi->omtu, pi->link_mode); | 2576 | pi->imtu, pi->omtu, pi->sec_level); |
2517 | } | 2577 | } |
2518 | 2578 | ||
2519 | read_unlock_bh(&l2cap_sk_list.lock); | 2579 | read_unlock_bh(&l2cap_sk_list.lock); |