diff options
Diffstat (limited to 'net/sctp/socket.c')
-rw-r--r-- | net/sctp/socket.c | 325 |
1 files changed, 0 insertions, 325 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index a4577a75c6c0..d2681a6bc6fa 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -4348,90 +4348,6 @@ static int sctp_getsockopt_initmsg(struct sock *sk, int len, char __user *optval | |||
4348 | return 0; | 4348 | return 0; |
4349 | } | 4349 | } |
4350 | 4350 | ||
4351 | static int sctp_getsockopt_peer_addrs_num_old(struct sock *sk, int len, | ||
4352 | char __user *optval, | ||
4353 | int __user *optlen) | ||
4354 | { | ||
4355 | sctp_assoc_t id; | ||
4356 | struct sctp_association *asoc; | ||
4357 | struct list_head *pos; | ||
4358 | int cnt = 0; | ||
4359 | |||
4360 | if (len < sizeof(sctp_assoc_t)) | ||
4361 | return -EINVAL; | ||
4362 | |||
4363 | if (copy_from_user(&id, optval, sizeof(sctp_assoc_t))) | ||
4364 | return -EFAULT; | ||
4365 | |||
4366 | printk(KERN_WARNING "SCTP: Use of SCTP_GET_PEER_ADDRS_NUM_OLD " | ||
4367 | "socket option deprecated\n"); | ||
4368 | /* For UDP-style sockets, id specifies the association to query. */ | ||
4369 | asoc = sctp_id2assoc(sk, id); | ||
4370 | if (!asoc) | ||
4371 | return -EINVAL; | ||
4372 | |||
4373 | list_for_each(pos, &asoc->peer.transport_addr_list) { | ||
4374 | cnt ++; | ||
4375 | } | ||
4376 | |||
4377 | return cnt; | ||
4378 | } | ||
4379 | |||
4380 | /* | ||
4381 | * Old API for getting list of peer addresses. Does not work for 32-bit | ||
4382 | * programs running on a 64-bit kernel | ||
4383 | */ | ||
4384 | static int sctp_getsockopt_peer_addrs_old(struct sock *sk, int len, | ||
4385 | char __user *optval, | ||
4386 | int __user *optlen) | ||
4387 | { | ||
4388 | struct sctp_association *asoc; | ||
4389 | int cnt = 0; | ||
4390 | struct sctp_getaddrs_old getaddrs; | ||
4391 | struct sctp_transport *from; | ||
4392 | void __user *to; | ||
4393 | union sctp_addr temp; | ||
4394 | struct sctp_sock *sp = sctp_sk(sk); | ||
4395 | int addrlen; | ||
4396 | |||
4397 | if (len < sizeof(struct sctp_getaddrs_old)) | ||
4398 | return -EINVAL; | ||
4399 | |||
4400 | len = sizeof(struct sctp_getaddrs_old); | ||
4401 | |||
4402 | if (copy_from_user(&getaddrs, optval, len)) | ||
4403 | return -EFAULT; | ||
4404 | |||
4405 | if (getaddrs.addr_num <= 0) return -EINVAL; | ||
4406 | |||
4407 | printk(KERN_WARNING "SCTP: Use of SCTP_GET_PEER_ADDRS_OLD " | ||
4408 | "socket option deprecated\n"); | ||
4409 | |||
4410 | /* For UDP-style sockets, id specifies the association to query. */ | ||
4411 | asoc = sctp_id2assoc(sk, getaddrs.assoc_id); | ||
4412 | if (!asoc) | ||
4413 | return -EINVAL; | ||
4414 | |||
4415 | to = (void __user *)getaddrs.addrs; | ||
4416 | list_for_each_entry(from, &asoc->peer.transport_addr_list, | ||
4417 | transports) { | ||
4418 | memcpy(&temp, &from->ipaddr, sizeof(temp)); | ||
4419 | sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp); | ||
4420 | addrlen = sctp_get_af_specific(sk->sk_family)->sockaddr_len; | ||
4421 | if (copy_to_user(to, &temp, addrlen)) | ||
4422 | return -EFAULT; | ||
4423 | to += addrlen ; | ||
4424 | cnt ++; | ||
4425 | if (cnt >= getaddrs.addr_num) break; | ||
4426 | } | ||
4427 | getaddrs.addr_num = cnt; | ||
4428 | if (put_user(len, optlen)) | ||
4429 | return -EFAULT; | ||
4430 | if (copy_to_user(optval, &getaddrs, len)) | ||
4431 | return -EFAULT; | ||
4432 | |||
4433 | return 0; | ||
4434 | } | ||
4435 | 4351 | ||
4436 | static int sctp_getsockopt_peer_addrs(struct sock *sk, int len, | 4352 | static int sctp_getsockopt_peer_addrs(struct sock *sk, int len, |
4437 | char __user *optval, int __user *optlen) | 4353 | char __user *optval, int __user *optlen) |
@@ -4484,125 +4400,6 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len, | |||
4484 | return 0; | 4400 | return 0; |
4485 | } | 4401 | } |
4486 | 4402 | ||
4487 | static int sctp_getsockopt_local_addrs_num_old(struct sock *sk, int len, | ||
4488 | char __user *optval, | ||
4489 | int __user *optlen) | ||
4490 | { | ||
4491 | sctp_assoc_t id; | ||
4492 | struct sctp_bind_addr *bp; | ||
4493 | struct sctp_association *asoc; | ||
4494 | struct sctp_sockaddr_entry *addr; | ||
4495 | int cnt = 0; | ||
4496 | |||
4497 | if (len < sizeof(sctp_assoc_t)) | ||
4498 | return -EINVAL; | ||
4499 | |||
4500 | if (copy_from_user(&id, optval, sizeof(sctp_assoc_t))) | ||
4501 | return -EFAULT; | ||
4502 | |||
4503 | printk(KERN_WARNING "SCTP: Use of SCTP_GET_LOCAL_ADDRS_NUM_OLD " | ||
4504 | "socket option deprecated\n"); | ||
4505 | |||
4506 | /* | ||
4507 | * For UDP-style sockets, id specifies the association to query. | ||
4508 | * If the id field is set to the value '0' then the locally bound | ||
4509 | * addresses are returned without regard to any particular | ||
4510 | * association. | ||
4511 | */ | ||
4512 | if (0 == id) { | ||
4513 | bp = &sctp_sk(sk)->ep->base.bind_addr; | ||
4514 | } else { | ||
4515 | asoc = sctp_id2assoc(sk, id); | ||
4516 | if (!asoc) | ||
4517 | return -EINVAL; | ||
4518 | bp = &asoc->base.bind_addr; | ||
4519 | } | ||
4520 | |||
4521 | /* If the endpoint is bound to 0.0.0.0 or ::0, count the valid | ||
4522 | * addresses from the global local address list. | ||
4523 | */ | ||
4524 | if (sctp_list_single_entry(&bp->address_list)) { | ||
4525 | addr = list_entry(bp->address_list.next, | ||
4526 | struct sctp_sockaddr_entry, list); | ||
4527 | if (sctp_is_any(sk, &addr->a)) { | ||
4528 | rcu_read_lock(); | ||
4529 | list_for_each_entry_rcu(addr, | ||
4530 | &sctp_local_addr_list, list) { | ||
4531 | if (!addr->valid) | ||
4532 | continue; | ||
4533 | |||
4534 | if ((PF_INET == sk->sk_family) && | ||
4535 | (AF_INET6 == addr->a.sa.sa_family)) | ||
4536 | continue; | ||
4537 | |||
4538 | if ((PF_INET6 == sk->sk_family) && | ||
4539 | inet_v6_ipv6only(sk) && | ||
4540 | (AF_INET == addr->a.sa.sa_family)) | ||
4541 | continue; | ||
4542 | |||
4543 | cnt++; | ||
4544 | } | ||
4545 | rcu_read_unlock(); | ||
4546 | } else { | ||
4547 | cnt = 1; | ||
4548 | } | ||
4549 | goto done; | ||
4550 | } | ||
4551 | |||
4552 | /* Protection on the bound address list is not needed, | ||
4553 | * since in the socket option context we hold the socket lock, | ||
4554 | * so there is no way that the bound address list can change. | ||
4555 | */ | ||
4556 | list_for_each_entry(addr, &bp->address_list, list) { | ||
4557 | cnt ++; | ||
4558 | } | ||
4559 | done: | ||
4560 | return cnt; | ||
4561 | } | ||
4562 | |||
4563 | /* Helper function that copies local addresses to user and returns the number | ||
4564 | * of addresses copied. | ||
4565 | */ | ||
4566 | static int sctp_copy_laddrs_old(struct sock *sk, __u16 port, | ||
4567 | int max_addrs, void *to, | ||
4568 | int *bytes_copied) | ||
4569 | { | ||
4570 | struct sctp_sockaddr_entry *addr; | ||
4571 | union sctp_addr temp; | ||
4572 | int cnt = 0; | ||
4573 | int addrlen; | ||
4574 | |||
4575 | rcu_read_lock(); | ||
4576 | list_for_each_entry_rcu(addr, &sctp_local_addr_list, list) { | ||
4577 | if (!addr->valid) | ||
4578 | continue; | ||
4579 | |||
4580 | if ((PF_INET == sk->sk_family) && | ||
4581 | (AF_INET6 == addr->a.sa.sa_family)) | ||
4582 | continue; | ||
4583 | if ((PF_INET6 == sk->sk_family) && | ||
4584 | inet_v6_ipv6only(sk) && | ||
4585 | (AF_INET == addr->a.sa.sa_family)) | ||
4586 | continue; | ||
4587 | memcpy(&temp, &addr->a, sizeof(temp)); | ||
4588 | if (!temp.v4.sin_port) | ||
4589 | temp.v4.sin_port = htons(port); | ||
4590 | |||
4591 | sctp_get_pf_specific(sk->sk_family)->addr_v4map(sctp_sk(sk), | ||
4592 | &temp); | ||
4593 | addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; | ||
4594 | memcpy(to, &temp, addrlen); | ||
4595 | |||
4596 | to += addrlen; | ||
4597 | *bytes_copied += addrlen; | ||
4598 | cnt ++; | ||
4599 | if (cnt >= max_addrs) break; | ||
4600 | } | ||
4601 | rcu_read_unlock(); | ||
4602 | |||
4603 | return cnt; | ||
4604 | } | ||
4605 | |||
4606 | static int sctp_copy_laddrs(struct sock *sk, __u16 port, void *to, | 4403 | static int sctp_copy_laddrs(struct sock *sk, __u16 port, void *to, |
4607 | size_t space_left, int *bytes_copied) | 4404 | size_t space_left, int *bytes_copied) |
4608 | { | 4405 | { |
@@ -4646,112 +4443,6 @@ static int sctp_copy_laddrs(struct sock *sk, __u16 port, void *to, | |||
4646 | return cnt; | 4443 | return cnt; |
4647 | } | 4444 | } |
4648 | 4445 | ||
4649 | /* Old API for getting list of local addresses. Does not work for 32-bit | ||
4650 | * programs running on a 64-bit kernel | ||
4651 | */ | ||
4652 | static int sctp_getsockopt_local_addrs_old(struct sock *sk, int len, | ||
4653 | char __user *optval, int __user *optlen) | ||
4654 | { | ||
4655 | struct sctp_bind_addr *bp; | ||
4656 | struct sctp_association *asoc; | ||
4657 | int cnt = 0; | ||
4658 | struct sctp_getaddrs_old getaddrs; | ||
4659 | struct sctp_sockaddr_entry *addr; | ||
4660 | void __user *to; | ||
4661 | union sctp_addr temp; | ||
4662 | struct sctp_sock *sp = sctp_sk(sk); | ||
4663 | int addrlen; | ||
4664 | int err = 0; | ||
4665 | void *addrs; | ||
4666 | void *buf; | ||
4667 | int bytes_copied = 0; | ||
4668 | |||
4669 | if (len < sizeof(struct sctp_getaddrs_old)) | ||
4670 | return -EINVAL; | ||
4671 | |||
4672 | len = sizeof(struct sctp_getaddrs_old); | ||
4673 | if (copy_from_user(&getaddrs, optval, len)) | ||
4674 | return -EFAULT; | ||
4675 | |||
4676 | if (getaddrs.addr_num <= 0 || | ||
4677 | getaddrs.addr_num >= (INT_MAX / sizeof(union sctp_addr))) | ||
4678 | return -EINVAL; | ||
4679 | |||
4680 | printk(KERN_WARNING "SCTP: Use of SCTP_GET_LOCAL_ADDRS_OLD " | ||
4681 | "socket option deprecated\n"); | ||
4682 | |||
4683 | /* | ||
4684 | * For UDP-style sockets, id specifies the association to query. | ||
4685 | * If the id field is set to the value '0' then the locally bound | ||
4686 | * addresses are returned without regard to any particular | ||
4687 | * association. | ||
4688 | */ | ||
4689 | if (0 == getaddrs.assoc_id) { | ||
4690 | bp = &sctp_sk(sk)->ep->base.bind_addr; | ||
4691 | } else { | ||
4692 | asoc = sctp_id2assoc(sk, getaddrs.assoc_id); | ||
4693 | if (!asoc) | ||
4694 | return -EINVAL; | ||
4695 | bp = &asoc->base.bind_addr; | ||
4696 | } | ||
4697 | |||
4698 | to = getaddrs.addrs; | ||
4699 | |||
4700 | /* Allocate space for a local instance of packed array to hold all | ||
4701 | * the data. We store addresses here first and then put write them | ||
4702 | * to the user in one shot. | ||
4703 | */ | ||
4704 | addrs = kmalloc(sizeof(union sctp_addr) * getaddrs.addr_num, | ||
4705 | GFP_KERNEL); | ||
4706 | if (!addrs) | ||
4707 | return -ENOMEM; | ||
4708 | |||
4709 | /* If the endpoint is bound to 0.0.0.0 or ::0, get the valid | ||
4710 | * addresses from the global local address list. | ||
4711 | */ | ||
4712 | if (sctp_list_single_entry(&bp->address_list)) { | ||
4713 | addr = list_entry(bp->address_list.next, | ||
4714 | struct sctp_sockaddr_entry, list); | ||
4715 | if (sctp_is_any(sk, &addr->a)) { | ||
4716 | cnt = sctp_copy_laddrs_old(sk, bp->port, | ||
4717 | getaddrs.addr_num, | ||
4718 | addrs, &bytes_copied); | ||
4719 | goto copy_getaddrs; | ||
4720 | } | ||
4721 | } | ||
4722 | |||
4723 | buf = addrs; | ||
4724 | /* Protection on the bound address list is not needed since | ||
4725 | * in the socket option context we hold a socket lock and | ||
4726 | * thus the bound address list can't change. | ||
4727 | */ | ||
4728 | list_for_each_entry(addr, &bp->address_list, list) { | ||
4729 | memcpy(&temp, &addr->a, sizeof(temp)); | ||
4730 | sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp); | ||
4731 | addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; | ||
4732 | memcpy(buf, &temp, addrlen); | ||
4733 | buf += addrlen; | ||
4734 | bytes_copied += addrlen; | ||
4735 | cnt ++; | ||
4736 | if (cnt >= getaddrs.addr_num) break; | ||
4737 | } | ||
4738 | |||
4739 | copy_getaddrs: | ||
4740 | /* copy the entire address list into the user provided space */ | ||
4741 | if (copy_to_user(to, addrs, bytes_copied)) { | ||
4742 | err = -EFAULT; | ||
4743 | goto error; | ||
4744 | } | ||
4745 | |||
4746 | /* copy the leading structure back to user */ | ||
4747 | getaddrs.addr_num = cnt; | ||
4748 | if (copy_to_user(optval, &getaddrs, len)) | ||
4749 | err = -EFAULT; | ||
4750 | |||
4751 | error: | ||
4752 | kfree(addrs); | ||
4753 | return err; | ||
4754 | } | ||
4755 | 4446 | ||
4756 | static int sctp_getsockopt_local_addrs(struct sock *sk, int len, | 4447 | static int sctp_getsockopt_local_addrs(struct sock *sk, int len, |
4757 | char __user *optval, int __user *optlen) | 4448 | char __user *optval, int __user *optlen) |
@@ -5602,22 +5293,6 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname, | |||
5602 | case SCTP_INITMSG: | 5293 | case SCTP_INITMSG: |
5603 | retval = sctp_getsockopt_initmsg(sk, len, optval, optlen); | 5294 | retval = sctp_getsockopt_initmsg(sk, len, optval, optlen); |
5604 | break; | 5295 | break; |
5605 | case SCTP_GET_PEER_ADDRS_NUM_OLD: | ||
5606 | retval = sctp_getsockopt_peer_addrs_num_old(sk, len, optval, | ||
5607 | optlen); | ||
5608 | break; | ||
5609 | case SCTP_GET_LOCAL_ADDRS_NUM_OLD: | ||
5610 | retval = sctp_getsockopt_local_addrs_num_old(sk, len, optval, | ||
5611 | optlen); | ||
5612 | break; | ||
5613 | case SCTP_GET_PEER_ADDRS_OLD: | ||
5614 | retval = sctp_getsockopt_peer_addrs_old(sk, len, optval, | ||
5615 | optlen); | ||
5616 | break; | ||
5617 | case SCTP_GET_LOCAL_ADDRS_OLD: | ||
5618 | retval = sctp_getsockopt_local_addrs_old(sk, len, optval, | ||
5619 | optlen); | ||
5620 | break; | ||
5621 | case SCTP_GET_PEER_ADDRS: | 5296 | case SCTP_GET_PEER_ADDRS: |
5622 | retval = sctp_getsockopt_peer_addrs(sk, len, optval, | 5297 | retval = sctp_getsockopt_peer_addrs(sk, len, optval, |
5623 | optlen); | 5298 | optlen); |