diff options
author | Gustavo F. Padovan <padovan@profusion.mobi> | 2011-02-03 23:52:55 -0500 |
---|---|---|
committer | Gustavo F. Padovan <padovan@profusion.mobi> | 2011-02-07 22:43:31 -0500 |
commit | 99f4808db0c052f3c92a689ec2841618bf2ce14a (patch) | |
tree | 7cac9efa87d13303b978c091cbfd899d7085d2e4 /net/bluetooth/l2cap_sock.c | |
parent | 33575df7be6748292f88453f29319af6d639c5c8 (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.c | 145 |
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 | ||
280 | static 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 | |||
364 | static 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 | |||
280 | static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen) | 425 | static 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; |