aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/l2cap_sock.c
diff options
context:
space:
mode:
authorGustavo F. Padovan <padovan@profusion.mobi>2011-02-03 23:52:55 -0500
committerGustavo F. Padovan <padovan@profusion.mobi>2011-02-07 22:43:31 -0500
commit99f4808db0c052f3c92a689ec2841618bf2ce14a (patch)
tree7cac9efa87d13303b978c091cbfd899d7085d2e4 /net/bluetooth/l2cap_sock.c
parent33575df7be6748292f88453f29319af6d639c5c8 (diff)
Bluetooth: move l2cap_sock_getsockopt() to l2cap_sock.c
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net/bluetooth/l2cap_sock.c')
-rw-r--r--net/bluetooth/l2cap_sock.c145
1 files changed, 145 insertions, 0 deletions
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 1bbe8a06189b..b7d5ae9c6bdf 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -277,6 +277,151 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *l
277 return 0; 277 return 0;
278} 278}
279 279
280static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
281{
282 struct sock *sk = sock->sk;
283 struct l2cap_options opts;
284 struct l2cap_conninfo cinfo;
285 int len, err = 0;
286 u32 opt;
287
288 BT_DBG("sk %p", sk);
289
290 if (get_user(len, optlen))
291 return -EFAULT;
292
293 lock_sock(sk);
294
295 switch (optname) {
296 case L2CAP_OPTIONS:
297 opts.imtu = l2cap_pi(sk)->imtu;
298 opts.omtu = l2cap_pi(sk)->omtu;
299 opts.flush_to = l2cap_pi(sk)->flush_to;
300 opts.mode = l2cap_pi(sk)->mode;
301 opts.fcs = l2cap_pi(sk)->fcs;
302 opts.max_tx = l2cap_pi(sk)->max_tx;
303 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
304
305 len = min_t(unsigned int, len, sizeof(opts));
306 if (copy_to_user(optval, (char *) &opts, len))
307 err = -EFAULT;
308
309 break;
310
311 case L2CAP_LM:
312 switch (l2cap_pi(sk)->sec_level) {
313 case BT_SECURITY_LOW:
314 opt = L2CAP_LM_AUTH;
315 break;
316 case BT_SECURITY_MEDIUM:
317 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
318 break;
319 case BT_SECURITY_HIGH:
320 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
321 L2CAP_LM_SECURE;
322 break;
323 default:
324 opt = 0;
325 break;
326 }
327
328 if (l2cap_pi(sk)->role_switch)
329 opt |= L2CAP_LM_MASTER;
330
331 if (l2cap_pi(sk)->force_reliable)
332 opt |= L2CAP_LM_RELIABLE;
333
334 if (put_user(opt, (u32 __user *) optval))
335 err = -EFAULT;
336 break;
337
338 case L2CAP_CONNINFO:
339 if (sk->sk_state != BT_CONNECTED &&
340 !(sk->sk_state == BT_CONNECT2 &&
341 bt_sk(sk)->defer_setup)) {
342 err = -ENOTCONN;
343 break;
344 }
345
346 cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
347 memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3);
348
349 len = min_t(unsigned int, len, sizeof(cinfo));
350 if (copy_to_user(optval, (char *) &cinfo, len))
351 err = -EFAULT;
352
353 break;
354
355 default:
356 err = -ENOPROTOOPT;
357 break;
358 }
359
360 release_sock(sk);
361 return err;
362}
363
364static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
365{
366 struct sock *sk = sock->sk;
367 struct bt_security sec;
368 int len, err = 0;
369
370 BT_DBG("sk %p", sk);
371
372 if (level == SOL_L2CAP)
373 return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);
374
375 if (level != SOL_BLUETOOTH)
376 return -ENOPROTOOPT;
377
378 if (get_user(len, optlen))
379 return -EFAULT;
380
381 lock_sock(sk);
382
383 switch (optname) {
384 case BT_SECURITY:
385 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
386 && sk->sk_type != SOCK_RAW) {
387 err = -EINVAL;
388 break;
389 }
390
391 sec.level = l2cap_pi(sk)->sec_level;
392
393 len = min_t(unsigned int, len, sizeof(sec));
394 if (copy_to_user(optval, (char *) &sec, len))
395 err = -EFAULT;
396
397 break;
398
399 case BT_DEFER_SETUP:
400 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
401 err = -EINVAL;
402 break;
403 }
404
405 if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval))
406 err = -EFAULT;
407
408 break;
409
410 case BT_FLUSHABLE:
411 if (put_user(l2cap_pi(sk)->flushable, (u32 __user *) optval))
412 err = -EFAULT;
413
414 break;
415
416 default:
417 err = -ENOPROTOOPT;
418 break;
419 }
420
421 release_sock(sk);
422 return err;
423}
424
280static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen) 425static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
281{ 426{
282 struct sock *sk = sock->sk; 427 struct sock *sk = sock->sk;