summaryrefslogtreecommitdiffstats
path: root/lib/libc/net/sctp_sys_calls.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/net/sctp_sys_calls.c')
-rw-r--r--lib/libc/net/sctp_sys_calls.c113
1 files changed, 107 insertions, 6 deletions
diff --git a/lib/libc/net/sctp_sys_calls.c b/lib/libc/net/sctp_sys_calls.c
index 922e034..715fcbd 100644
--- a/lib/libc/net/sctp_sys_calls.c
+++ b/lib/libc/net/sctp_sys_calls.c
@@ -240,7 +240,10 @@ sctp_bindx(int sd, struct sockaddr *addrs, int addrcnt, int flags)
{
struct sctp_getaddresses *gaddrs;
struct sockaddr *sa;
+ struct sockaddr_in *sin;
+ struct sockaddr_in6 *sin6;
int i, sz, argsz;
+ uint16_t sport = 0;
/* validate the flags */
if ((flags != SCTP_BINDX_ADD_ADDR) &&
@@ -260,12 +263,63 @@ sctp_bindx(int sd, struct sockaddr *addrs, int addrcnt, int flags)
errno = ENOMEM;
return (-1);
}
+ /* First pre-screen the addresses */
sa = addrs;
for (i = 0; i < addrcnt; i++) {
sz = sa->sa_len;
if (sa->sa_family == AF_INET) {
if (sa->sa_len != sizeof(struct sockaddr_in))
goto out_error;
+ sin = (struct sockaddr_in *)sa;
+ if (sin->sin_port) {
+ /* non-zero port, check or save */
+ if (sport) {
+ /* Check against our port */
+ if (sport != sin->sin_port) {
+ goto out_error;
+ }
+ } else {
+ /* save off the port */
+ sport = sin->sin_port;
+ }
+ }
+ } else if (sa->sa_family == AF_INET6) {
+ if (sa->sa_len != sizeof(struct sockaddr_in6))
+ goto out_error;
+ sin6 = (struct sockaddr_in6 *)sa;
+ if (sin6->sin6_port) {
+ /* non-zero port, check or save */
+ if (sport) {
+ /* Check against our port */
+ if (sport != sin6->sin6_port) {
+ goto out_error;
+ }
+ } else {
+ /* save off the port */
+ sport = sin6->sin6_port;
+ }
+ }
+ } else {
+ /* invalid address family specified */
+ goto out_error;
+ }
+
+
+ }
+ sa = addrs;
+ /*
+ * Now if there was a port mentioned, assure that the first address
+ * has that port to make sure it fails or succeeds correctly.
+ */
+ if (sport) {
+ sin = (struct sockaddr_in *)sa;
+ sin->sin_port = sport;
+ }
+ for (i = 0; i < addrcnt; i++) {
+ sz = sa->sa_len;
+ if (sa->sa_family == AF_INET) {
+ if (sa->sa_len != sizeof(struct sockaddr_in))
+ goto out_error;
} else if (sa->sa_family == AF_INET6) {
if (sa->sa_len != sizeof(struct sockaddr_in6))
goto out_error;
@@ -298,7 +352,55 @@ sctp_opt_info(int sd, sctp_assoc_t id, int opt, void *arg, socklen_t * size)
errno = EINVAL;
return (-1);
}
- *(sctp_assoc_t *) arg = id;
+ switch (opt) {
+ case SCTP_RTOINFO:
+ ((struct sctp_rtoinfo *)arg)->srto_assoc_id = id;
+ break;
+ case SCTP_ASSOCINFO:
+ ((struct sctp_assocparams *)arg)->sasoc_assoc_id = id;
+ break;
+ case SCTP_DEFAULT_SEND_PARAM:
+ ((struct sctp_assocparams *)arg)->sasoc_assoc_id = id;
+ break;
+ case SCTP_SET_PEER_PRIMARY_ADDR:
+ ((struct sctp_setpeerprim *)arg)->sspp_assoc_id = id;
+ break;
+ case SCTP_PRIMARY_ADDR:
+ ((struct sctp_setprim *)arg)->ssp_assoc_id = id;
+ break;
+ case SCTP_PEER_ADDR_PARAMS:
+ ((struct sctp_paddrparams *)arg)->spp_assoc_id = id;
+ break;
+ case SCTP_MAXSEG:
+ ((struct sctp_assoc_value *)arg)->assoc_id = id;
+ break;
+ case SCTP_AUTH_KEY:
+ ((struct sctp_authkey *)arg)->sca_assoc_id = id;
+ break;
+ case SCTP_AUTH_ACTIVE_KEY:
+ ((struct sctp_authkeyid *)arg)->scact_assoc_id = id;
+ break;
+ case SCTP_DELAYED_SACK:
+ ((struct sctp_sack_info *)arg)->sack_assoc_id = id;
+ break;
+ case SCTP_CONTEXT:
+ ((struct sctp_assoc_value *)arg)->assoc_id = id;
+ break;
+ case SCTP_STATUS:
+ ((struct sctp_status *)arg)->sstat_assoc_id = id;
+ break;
+ case SCTP_GET_PEER_ADDR_INFO:
+ ((struct sctp_paddrinfo *)arg)->spinfo_assoc_id = id;
+ break;
+ case SCTP_PEER_AUTH_CHUNKS:
+ ((struct sctp_authchunks *)arg)->gauth_assoc_id = id;
+ break;
+ case SCTP_LOCAL_AUTH_CHUNKS:
+ ((struct sctp_authchunks *)arg)->gauth_assoc_id = id;
+ break;
+ default:
+ break;
+ }
return (getsockopt(sd, IPPROTO_SCTP, opt, arg, size));
}
@@ -628,7 +730,10 @@ sctp_sendx(int sd, const void *msg, size_t msg_len,
int add_len, len, no_end_cx = 0;
struct sockaddr *at;
-
+ if (addrs == NULL) {
+ errno = EINVAL;
+ return (-1);
+ }
#ifdef SYS_sctp_generic_sendmsg
if (addrcnt < SCTP_SMALL_IOVEC_SIZE) {
socklen_t l;
@@ -643,10 +748,6 @@ sctp_sendx(int sd, const void *msg, size_t msg_len,
}
#endif
- if (addrs == NULL) {
- errno = EINVAL;
- return (-1);
- }
len = sizeof(int);
at = addrs;
cnt = 0;
OpenPOWER on IntegriCloud