summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSridhar Samudrala <sri@us.ibm.com>2003-08-25 00:30:47 -0700
committerSridhar Samudrala <sri@us.ibm.com>2003-08-25 00:30:47 -0700
commitbfaa8bf5be42f488ac83f7fc2e20b0d923e20d0d (patch)
tree0dea584e6197daa8991bdabbab7b802a6645fd34
parentd2855c5dacd8dc87d6120b53e6de82c43745934a (diff)
parent5c70f0a4734dc1424dbf9eb5215f9591afd750ba (diff)
Merge us.ibm.com:/home/sridhar/BK/linux-2.6.0-test4
into us.ibm.com:/home/sridhar/BK/lksctp-2.6.0-test4
-rw-r--r--include/net/sctp/user.h8
-rw-r--r--net/sctp/socket.c33
-rw-r--r--net/sctp/sysctl.c4
3 files changed, 24 insertions, 21 deletions
diff --git a/include/net/sctp/user.h b/include/net/sctp/user.h
index da96859dba92..45f96479510f 100644
--- a/include/net/sctp/user.h
+++ b/include/net/sctp/user.h
@@ -551,13 +551,15 @@ struct sctp_status {
};
/*
- * 8.3, 8.5 get all peer/local addresses on a socket
- * This parameter struct is for getsockopt
+ * 8.3, 8.5 get all peer/local addresses in an association.
+ * 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 {
sctp_assoc_t assoc_id;
int addr_num;
- struct sockaddr_storage *addrs;
+ struct sockaddr *addrs;
};
/* These are bit fields for msghdr->msg_flags. See section 5.1. */
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 99c4a4914d08..0fb64f708c5a 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -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,
- char *optval, int *optlen)
+ char *optval, int *optlen)
{
sctp_assoc_t id;
struct sctp_association *asoc;
@@ -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)))
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);
if (!asoc)
return -EINVAL;
@@ -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,
- char *optval, int *optlen)
+ char *optval, int *optlen)
{
struct sctp_association *asoc;
struct list_head *pos;
int cnt = 0;
struct sctp_getaddrs getaddrs;
struct sctp_transport *from;
- struct sockaddr_storage *to;
+ void *to;
union sctp_addr temp;
struct sctp_opt *sp = sctp_sk(sk);
+ int addrlen;
if (len != sizeof(struct sctp_getaddrs))
return -EINVAL;
@@ -2600,21 +2599,21 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len,
return -EFAULT;
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);
if (!asoc)
return -EINVAL;
- to = getaddrs.addrs;
+ to = (void *)getaddrs.addrs;
list_for_each(pos, &asoc->peer.transport_addr_list) {
from = list_entry(pos, struct sctp_transport, transports);
memcpy(&temp, &from->ipaddr, sizeof(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;
- to ++;
+ to += addrlen ;
cnt ++;
if (cnt >= getaddrs.addr_num) break;
}
@@ -2673,9 +2672,10 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
int cnt = 0;
struct sctp_getaddrs getaddrs;
struct sctp_sockaddr_entry *from;
- struct sockaddr_storage *to;
+ void *to;
union sctp_addr temp;
struct sctp_opt *sp = sctp_sk(sk);
+ int addrlen;
if (len != sizeof(struct sctp_getaddrs))
return -EINVAL;
@@ -2699,16 +2699,17 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
bp = &asoc->base.bind_addr;
}
- to = getaddrs.addrs;
+ to = (void *)getaddrs.addrs;
list_for_each(pos, &bp->address_list) {
from = list_entry(pos,
struct sctp_sockaddr_entry,
list);
memcpy(&temp, &from->a, sizeof(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;
- to ++;
+ to += addrlen;
cnt ++;
if (cnt >= getaddrs.addr_num) break;
}
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c
index cdcf6d09d24f..edffe9cc8f21 100644
--- a/net/sctp/sysctl.c
+++ b/net/sctp/sysctl.c
@@ -214,7 +214,7 @@ static int sctp_sysctl_jiffies_ms(ctl_table *table, int __user *name, int nlen,
if (olen != sizeof (int))
return -EINVAL;
}
- if (put_user((*(int *)(table->data) / HZ) * 1000,
+ if (put_user((*(int *)(table->data) * 1000) / HZ,
(int *)oldval) ||
(oldlenp && put_user(sizeof (int), oldlenp)))
return -EFAULT;
@@ -228,7 +228,7 @@ static int sctp_sysctl_jiffies_ms(ctl_table *table, int __user *name, int nlen,
if (get_user(new, (int *)newval))
return -EFAULT;
- *(int *)(table->data) = (new * HZ) * 1000;
+ *(int *)(table->data) = (new * HZ) / 1000;
}
return 1;
}