diff options
| author | Sridhar Samudrala <sri@us.ibm.com> | 2003-08-25 00:30:47 -0700 |
|---|---|---|
| committer | Sridhar Samudrala <sri@us.ibm.com> | 2003-08-25 00:30:47 -0700 |
| commit | bfaa8bf5be42f488ac83f7fc2e20b0d923e20d0d (patch) | |
| tree | 0dea584e6197daa8991bdabbab7b802a6645fd34 | |
| parent | d2855c5dacd8dc87d6120b53e6de82c43745934a (diff) | |
| parent | 5c70f0a4734dc1424dbf9eb5215f9591afd750ba (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.h | 8 | ||||
| -rw-r--r-- | net/sctp/socket.c | 33 | ||||
| -rw-r--r-- | net/sctp/sysctl.c | 4 |
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; } |
