diff options
author | Vlad Yasevich <vladislav.yasevich@hp.com> | 2007-05-09 16:51:31 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-05-11 02:45:30 -0400 |
commit | 70b57b814ed5a93bf21d9dc5f8a7d23620a77e44 (patch) | |
tree | 28c6f5d4b02fb49b0b49fb740bb7214c23bed193 /net | |
parent | 8dc4984a6bdcaf56cdb458a7338c32c16f32540c (diff) |
[SCTP]: Correctly copy addresses in sctp_copy_laddrs
I broke the non-wildcard case recently. This is to fixes it.
Now, explictitly bound addresses can ge retrieved using the API.
Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/sctp/socket.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index f3c95f9bd413..4dcdabf56473 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -4164,6 +4164,7 @@ static int sctp_getsockopt_local_addrs_old(struct sock *sk, int len, | |||
4164 | rwlock_t *addr_lock; | 4164 | rwlock_t *addr_lock; |
4165 | int err = 0; | 4165 | int err = 0; |
4166 | void *addrs; | 4166 | void *addrs; |
4167 | void *buf; | ||
4167 | int bytes_copied = 0; | 4168 | int bytes_copied = 0; |
4168 | 4169 | ||
4169 | if (len != sizeof(struct sctp_getaddrs_old)) | 4170 | if (len != sizeof(struct sctp_getaddrs_old)) |
@@ -4217,13 +4218,14 @@ static int sctp_getsockopt_local_addrs_old(struct sock *sk, int len, | |||
4217 | } | 4218 | } |
4218 | } | 4219 | } |
4219 | 4220 | ||
4221 | buf = addrs; | ||
4220 | list_for_each(pos, &bp->address_list) { | 4222 | list_for_each(pos, &bp->address_list) { |
4221 | addr = list_entry(pos, struct sctp_sockaddr_entry, list); | 4223 | addr = list_entry(pos, struct sctp_sockaddr_entry, list); |
4222 | memcpy(&temp, &addr->a, sizeof(temp)); | 4224 | memcpy(&temp, &addr->a, sizeof(temp)); |
4223 | sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp); | 4225 | sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp); |
4224 | addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; | 4226 | addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; |
4225 | memcpy(addrs, &temp, addrlen); | 4227 | memcpy(buf, &temp, addrlen); |
4226 | to += addrlen; | 4228 | buf += addrlen; |
4227 | bytes_copied += addrlen; | 4229 | bytes_copied += addrlen; |
4228 | cnt ++; | 4230 | cnt ++; |
4229 | if (cnt >= getaddrs.addr_num) break; | 4231 | if (cnt >= getaddrs.addr_num) break; |
@@ -4266,6 +4268,7 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len, | |||
4266 | size_t space_left; | 4268 | size_t space_left; |
4267 | int bytes_copied = 0; | 4269 | int bytes_copied = 0; |
4268 | void *addrs; | 4270 | void *addrs; |
4271 | void *buf; | ||
4269 | 4272 | ||
4270 | if (len <= sizeof(struct sctp_getaddrs)) | 4273 | if (len <= sizeof(struct sctp_getaddrs)) |
4271 | return -EINVAL; | 4274 | return -EINVAL; |
@@ -4316,6 +4319,7 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len, | |||
4316 | } | 4319 | } |
4317 | } | 4320 | } |
4318 | 4321 | ||
4322 | buf = addrs; | ||
4319 | list_for_each(pos, &bp->address_list) { | 4323 | list_for_each(pos, &bp->address_list) { |
4320 | addr = list_entry(pos, struct sctp_sockaddr_entry, list); | 4324 | addr = list_entry(pos, struct sctp_sockaddr_entry, list); |
4321 | memcpy(&temp, &addr->a, sizeof(temp)); | 4325 | memcpy(&temp, &addr->a, sizeof(temp)); |
@@ -4325,8 +4329,8 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len, | |||
4325 | err = -ENOMEM; /*fixme: right error?*/ | 4329 | err = -ENOMEM; /*fixme: right error?*/ |
4326 | goto error; | 4330 | goto error; |
4327 | } | 4331 | } |
4328 | memcpy(addrs, &temp, addrlen); | 4332 | memcpy(buf, &temp, addrlen); |
4329 | to += addrlen; | 4333 | buf += addrlen; |
4330 | bytes_copied += addrlen; | 4334 | bytes_copied += addrlen; |
4331 | cnt ++; | 4335 | cnt ++; |
4332 | space_left -= addrlen; | 4336 | space_left -= addrlen; |