Commit 5c70f0a4 authored by Sridhar Samudrala's avatar Sridhar Samudrala

[SCTP] draft07 API changes: sctp_getpaddrs(), sctp_getladdrs() now

return a packed array of sockaddr_in/sockaddr_in6 structures instead
of an array of sockaddr_storage structures.
parent a144b646
...@@ -551,13 +551,15 @@ struct sctp_status { ...@@ -551,13 +551,15 @@ struct sctp_status {
}; };
/* /*
* 8.3, 8.5 get all peer/local addresses on a socket * 8.3, 8.5 get all peer/local addresses in an association.
* This parameter struct is for getsockopt * This parameter struct is used by SCTP_GET_PEER_ADDRS and
* SCTP_GET_LOCAL_ADDRS socket options used internally to implement
* sctp_getpaddrs() and sctp_getladdrs() API.
*/ */
struct sctp_getaddrs { struct sctp_getaddrs {
sctp_assoc_t assoc_id; sctp_assoc_t assoc_id;
int addr_num; int addr_num;
struct sockaddr_storage *addrs; struct sockaddr *addrs;
}; };
/* These are bit fields for msghdr->msg_flags. See section 5.1. */ /* These are bit fields for msghdr->msg_flags. See section 5.1. */
......
...@@ -2552,7 +2552,7 @@ static int sctp_getsockopt_initmsg(struct sock *sk, int len, char *optval, int * ...@@ -2552,7 +2552,7 @@ static int sctp_getsockopt_initmsg(struct sock *sk, int len, char *optval, int *
} }
static int sctp_getsockopt_peer_addrs_num(struct sock *sk, int len, static int sctp_getsockopt_peer_addrs_num(struct sock *sk, int len,
char *optval, int *optlen) char *optval, int *optlen)
{ {
sctp_assoc_t id; sctp_assoc_t id;
struct sctp_association *asoc; struct sctp_association *asoc;
...@@ -2565,9 +2565,7 @@ static int sctp_getsockopt_peer_addrs_num(struct sock *sk, int len, ...@@ -2565,9 +2565,7 @@ static int sctp_getsockopt_peer_addrs_num(struct sock *sk, int len,
if (copy_from_user(&id, optval, sizeof(sctp_assoc_t))) if (copy_from_user(&id, optval, sizeof(sctp_assoc_t)))
return -EFAULT; return -EFAULT;
/* /* For UDP-style sockets, id specifies the association to query. */
* For UDP-style sockets, id specifies the association to query.
*/
asoc = sctp_id2assoc(sk, id); asoc = sctp_id2assoc(sk, id);
if (!asoc) if (!asoc)
return -EINVAL; return -EINVAL;
...@@ -2582,16 +2580,17 @@ static int sctp_getsockopt_peer_addrs_num(struct sock *sk, int len, ...@@ -2582,16 +2580,17 @@ static int sctp_getsockopt_peer_addrs_num(struct sock *sk, int len,
} }
static int sctp_getsockopt_peer_addrs(struct sock *sk, int len, static int sctp_getsockopt_peer_addrs(struct sock *sk, int len,
char *optval, int *optlen) char *optval, int *optlen)
{ {
struct sctp_association *asoc; struct sctp_association *asoc;
struct list_head *pos; struct list_head *pos;
int cnt = 0; int cnt = 0;
struct sctp_getaddrs getaddrs; struct sctp_getaddrs getaddrs;
struct sctp_transport *from; struct sctp_transport *from;
struct sockaddr_storage *to; void *to;
union sctp_addr temp; union sctp_addr temp;
struct sctp_opt *sp = sctp_sk(sk); struct sctp_opt *sp = sctp_sk(sk);
int addrlen;
if (len != sizeof(struct sctp_getaddrs)) if (len != sizeof(struct sctp_getaddrs))
return -EINVAL; return -EINVAL;
...@@ -2600,21 +2599,21 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len, ...@@ -2600,21 +2599,21 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len,
return -EFAULT; return -EFAULT;
if (getaddrs.addr_num <= 0) return -EINVAL; if (getaddrs.addr_num <= 0) return -EINVAL;
/*
* For UDP-style sockets, id specifies the association to query. /* For UDP-style sockets, id specifies the association to query. */
*/
asoc = sctp_id2assoc(sk, getaddrs.assoc_id); asoc = sctp_id2assoc(sk, getaddrs.assoc_id);
if (!asoc) if (!asoc)
return -EINVAL; return -EINVAL;
to = getaddrs.addrs; to = (void *)getaddrs.addrs;
list_for_each(pos, &asoc->peer.transport_addr_list) { list_for_each(pos, &asoc->peer.transport_addr_list) {
from = list_entry(pos, struct sctp_transport, transports); from = list_entry(pos, struct sctp_transport, transports);
memcpy(&temp, &from->ipaddr, sizeof(temp)); memcpy(&temp, &from->ipaddr, sizeof(temp));
sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp); sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp);
if (copy_to_user(to, &temp, sizeof(temp))) addrlen = sctp_get_af_specific(sk->sk_family)->sockaddr_len;
if (copy_to_user(to, &temp, addrlen))
return -EFAULT; return -EFAULT;
to ++; to += addrlen ;
cnt ++; cnt ++;
if (cnt >= getaddrs.addr_num) break; if (cnt >= getaddrs.addr_num) break;
} }
...@@ -2673,9 +2672,10 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len, ...@@ -2673,9 +2672,10 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
int cnt = 0; int cnt = 0;
struct sctp_getaddrs getaddrs; struct sctp_getaddrs getaddrs;
struct sctp_sockaddr_entry *from; struct sctp_sockaddr_entry *from;
struct sockaddr_storage *to; void *to;
union sctp_addr temp; union sctp_addr temp;
struct sctp_opt *sp = sctp_sk(sk); struct sctp_opt *sp = sctp_sk(sk);
int addrlen;
if (len != sizeof(struct sctp_getaddrs)) if (len != sizeof(struct sctp_getaddrs))
return -EINVAL; return -EINVAL;
...@@ -2699,16 +2699,17 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len, ...@@ -2699,16 +2699,17 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
bp = &asoc->base.bind_addr; bp = &asoc->base.bind_addr;
} }
to = getaddrs.addrs; to = (void *)getaddrs.addrs;
list_for_each(pos, &bp->address_list) { list_for_each(pos, &bp->address_list) {
from = list_entry(pos, from = list_entry(pos,
struct sctp_sockaddr_entry, struct sctp_sockaddr_entry,
list); list);
memcpy(&temp, &from->a, sizeof(temp)); memcpy(&temp, &from->a, sizeof(temp));
sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp); sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp);
if (copy_to_user(to, &temp, sizeof(temp))) addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len;
if (copy_to_user(to, &temp, addrlen))
return -EFAULT; return -EFAULT;
to ++; to += addrlen;
cnt ++; cnt ++;
if (cnt >= getaddrs.addr_num) break; if (cnt >= getaddrs.addr_num) break;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment