Home | History | Annotate | Download | only in usrsctplib
      1 /*-
      2  * Copyright (c) 1982, 1986, 1988, 1990, 1993
      3  *      The Regents of the University of California.
      4  * Copyright (c) 2004 The FreeBSD Foundation
      5  * Copyright (c) 2004-2008 Robert N. M. Watson
      6  * Copyright (c) 2009-2010 Brad Penoff
      7  * Copyright (c) 2009-2010 Humaira Kamal
      8  * Copyright (c) 2011-2012 Irene Ruengeler
      9  * Copyright (c) 2011-2012 Michael Tuexen
     10  * All rights reserved.
     11  *
     12  * Redistribution and use in source and binary forms, with or without
     13  * modification, are permitted provided that the following conditions
     14  * are met:
     15  * 1. Redistributions of source code must retain the above copyright
     16  *    notice, this list of conditions and the following disclaimer.
     17  * 2. Redistributions in binary form must reproduce the above copyright
     18  *    notice, this list of conditions and the following disclaimer in the
     19  *    documentation and/or other materials provided with the distribution.
     20  *
     21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     31  * SUCH DAMAGE.
     32  *
     33  */
     34 
     35 #include <netinet/sctp_os.h>
     36 #include <netinet/sctp_pcb.h>
     37 #include <netinet/sctputil.h>
     38 #include <netinet/sctp_var.h>
     39 #include <netinet/sctp_sysctl.h>
     40 #include <netinet/sctp_input.h>
     41 #include <netinet/sctp_peeloff.h>
     42 #ifdef INET6
     43 #include <netinet6/sctp6_var.h>
     44 #endif
     45 #if defined(__Userspace_os_Linux)
     46 #define __FAVOR_BSD    /* (on Ubuntu at least) enables UDP header field names like BSD in RFC 768 */
     47 #endif
     48 #if !defined (__Userspace_os_Windows)
     49 #include <netinet/udp.h>
     50 #include <arpa/inet.h>
     51 #else
     52 #include <user_socketvar.h>
     53 #endif
     54 userland_mutex_t accept_mtx;
     55 userland_cond_t accept_cond;
     56 #ifdef _WIN32
     57 #include <time.h>
     58 #include <sys/timeb.h>
     59 #endif
     60 
     61 MALLOC_DEFINE(M_PCB, "sctp_pcb", "sctp pcb");
     62 MALLOC_DEFINE(M_SONAME, "sctp_soname", "sctp soname");
     63 #define MAXLEN_MBUF_CHAIN  32
     64 
     65 /* Prototypes */
     66 extern int sctp_sosend(struct socket *so, struct sockaddr *addr, struct uio *uio,
     67                        struct mbuf *top, struct mbuf *control, int flags,
     68                      /* proc is a dummy in __Userspace__ and will not be passed to sctp_lower_sosend */                       struct proc *p);
     69 
     70 extern int sctp_attach(struct socket *so, int proto, uint32_t vrf_id);
     71 extern int sctpconn_attach(struct socket *so, int proto, uint32_t vrf_id);
     72 
     73 void
     74 usrsctp_init(uint16_t port,
     75              int (*conn_output)(void *addr, void *buffer, size_t length, uint8_t tos, uint8_t set_df),
     76              void (*debug_printf)(const char *format, ...))
     77 {
     78 	sctp_init(port, conn_output, debug_printf);
     79 }
     80 
     81 
     82 /* Taken from  usr/src/sys/kern/uipc_sockbuf.c and modified for __Userspace__*/
     83 /*
     84  * Socantsendmore indicates that no more data will be sent on the socket; it
     85  * would normally be applied to a socket when the user informs the system
     86  * that no more data is to be sent, by the protocol code (in case
     87  * PRU_SHUTDOWN).  Socantrcvmore indicates that no more data will be
     88  * received, and will normally be applied to the socket by a protocol when it
     89  * detects that the peer will send no more data.  Data queued for reading in
     90  * the socket may yet be read.
     91  */
     92 
     93 void socantrcvmore_locked(struct socket *so)
     94 {
     95 	SOCKBUF_LOCK_ASSERT(&so->so_rcv);
     96 	so->so_rcv.sb_state |= SBS_CANTRCVMORE;
     97 	sorwakeup_locked(so);
     98 }
     99 
    100 void socantrcvmore(struct socket *so)
    101 {
    102 	SOCKBUF_LOCK(&so->so_rcv);
    103 	socantrcvmore_locked(so);
    104 }
    105 
    106 void
    107 socantsendmore_locked(struct socket *so)
    108 {
    109 	SOCKBUF_LOCK_ASSERT(&so->so_snd);
    110 	so->so_snd.sb_state |= SBS_CANTSENDMORE;
    111 	sowwakeup_locked(so);
    112 }
    113 
    114 void
    115 socantsendmore(struct socket *so)
    116 {
    117 	SOCKBUF_LOCK(&so->so_snd);
    118 	socantsendmore_locked(so);
    119 }
    120 
    121 
    122 
    123 /* Taken from  usr/src/sys/kern/uipc_sockbuf.c and called within sctp_lower_sosend.
    124  */
    125 int
    126 sbwait(struct sockbuf *sb)
    127 {
    128 #if defined(__Userspace__) /* __Userspace__ */
    129 
    130 	SOCKBUF_LOCK_ASSERT(sb);
    131 
    132 	sb->sb_flags |= SB_WAIT;
    133 #if defined (__Userspace_os_Windows)
    134 	if (SleepConditionVariableCS(&(sb->sb_cond), &(sb->sb_mtx), INFINITE))
    135 		return 0;
    136 	else
    137 		return -1;
    138 #else
    139 	return (pthread_cond_wait(&(sb->sb_cond), &(sb->sb_mtx)));
    140 #endif
    141 
    142 #else
    143 	SOCKBUF_LOCK_ASSERT(sb);
    144 
    145 	sb->sb_flags |= SB_WAIT;
    146 	return (msleep(&sb->sb_cc, &sb->sb_mtx,
    147 	    (sb->sb_flags & SB_NOINTR) ? PSOCK : PSOCK | PCATCH, "sbwait",
    148 	    sb->sb_timeo));
    149 #endif
    150 }
    151 
    152 
    153 
    154 
    155 /* Taken from  /src/sys/kern/uipc_socket.c
    156  * and modified for __Userspace__
    157  */
    158 static struct socket *
    159 soalloc(void)
    160 {
    161 	struct socket *so;
    162 
    163 	/*
    164 	 * soalloc() sets of socket layer state for a socket,
    165 	 * called only by socreate() and sonewconn().
    166 	 *
    167 	 * sodealloc() tears down socket layer state for a socket,
    168 	 * called only by sofree() and sonewconn().
    169 	 * __Userspace__ TODO : Make sure so is properly deallocated
    170 	 * when tearing down the connection.
    171 	 */
    172 
    173 	so = (struct socket *)malloc(sizeof(struct socket));
    174 
    175 	if (so == NULL) {
    176 		return (NULL);
    177 	}
    178 	memset(so, 0, sizeof(struct socket));
    179 
    180 	/* __Userspace__ Initializing the socket locks here */
    181 	SOCKBUF_LOCK_INIT(&so->so_snd, "so_snd");
    182 	SOCKBUF_LOCK_INIT(&so->so_rcv, "so_rcv");
    183 	SOCKBUF_COND_INIT(&so->so_snd);
    184 	SOCKBUF_COND_INIT(&so->so_rcv);
    185 	SOCK_COND_INIT(so); /* timeo_cond */
    186 
    187 	/* __Userspace__ Any ref counting required here? Will we have any use for aiojobq?
    188 	   What about gencnt and numopensockets?*/
    189 	TAILQ_INIT(&so->so_aiojobq);
    190 	return (so);
    191 }
    192 
    193 static void
    194 sodealloc(struct socket *so)
    195 {
    196 
    197 	KASSERT(so->so_count == 0, ("sodealloc(): so_count %d", so->so_count));
    198 	KASSERT(so->so_pcb == NULL, ("sodealloc(): so_pcb != NULL"));
    199 
    200 	SOCKBUF_COND_DESTROY(&so->so_snd);
    201 	SOCKBUF_COND_DESTROY(&so->so_rcv);
    202 
    203 	SOCK_COND_DESTROY(so);
    204 
    205 	SOCKBUF_LOCK_DESTROY(&so->so_snd);
    206 	SOCKBUF_LOCK_DESTROY(&so->so_rcv);
    207 
    208 	free(so);
    209 }
    210 
    211 /* Taken from  /src/sys/kern/uipc_socket.c
    212  * and modified for __Userspace__
    213  */
    214 void
    215 sofree(struct socket *so)
    216 {
    217 	struct socket *head;
    218 
    219 	ACCEPT_LOCK_ASSERT();
    220 	SOCK_LOCK_ASSERT(so);
    221 	/* SS_NOFDREF unset in accept call.  this condition seems irrelevent
    222 	 *  for __Userspace__...
    223 	 */
    224 	if (so->so_count != 0 ||
    225 	    (so->so_state & SS_PROTOREF) || (so->so_qstate & SQ_COMP)) {
    226 		SOCK_UNLOCK(so);
    227 		ACCEPT_UNLOCK();
    228 		return;
    229 	}
    230 	head = so->so_head;
    231 	if (head != NULL) {
    232 		KASSERT((so->so_qstate & SQ_COMP) != 0 ||
    233 		    (so->so_qstate & SQ_INCOMP) != 0,
    234 		    ("sofree: so_head != NULL, but neither SQ_COMP nor "
    235 		    "SQ_INCOMP"));
    236 		KASSERT((so->so_qstate & SQ_COMP) == 0 ||
    237 		    (so->so_qstate & SQ_INCOMP) == 0,
    238 		    ("sofree: so->so_qstate is SQ_COMP and also SQ_INCOMP"));
    239 		TAILQ_REMOVE(&head->so_incomp, so, so_list);
    240 		head->so_incqlen--;
    241 		so->so_qstate &= ~SQ_INCOMP;
    242 		so->so_head = NULL;
    243 	}
    244 	KASSERT((so->so_qstate & SQ_COMP) == 0 &&
    245 	    (so->so_qstate & SQ_INCOMP) == 0,
    246 	    ("sofree: so_head == NULL, but still SQ_COMP(%d) or SQ_INCOMP(%d)",
    247 	    so->so_qstate & SQ_COMP, so->so_qstate & SQ_INCOMP));
    248 	if (so->so_options & SCTP_SO_ACCEPTCONN) {
    249 		KASSERT((TAILQ_EMPTY(&so->so_comp)), ("sofree: so_comp populated"));
    250 		KASSERT((TAILQ_EMPTY(&so->so_incomp)), ("sofree: so_comp populated"));
    251 	}
    252 	SOCK_UNLOCK(so);
    253 	ACCEPT_UNLOCK();
    254 	sctp_close(so); /* was...    sctp_detach(so); */
    255 	/*
    256 	 * From this point on, we assume that no other references to this
    257 	 * socket exist anywhere else in the stack.  Therefore, no locks need
    258 	 * to be acquired or held.
    259 	 *
    260 	 * We used to do a lot of socket buffer and socket locking here, as
    261 	 * well as invoke sorflush() and perform wakeups.  The direct call to
    262 	 * dom_dispose() and sbrelease_internal() are an inlining of what was
    263 	 * necessary from sorflush().
    264 	 *
    265 	 * Notice that the socket buffer and kqueue state are torn down
    266 	 * before calling pru_detach.  This means that protocols shold not
    267 	 * assume they can perform socket wakeups, etc, in their detach code.
    268 	 */
    269 	sodealloc(so);
    270 }
    271 
    272 
    273 
    274 /* Taken from  /src/sys/kern/uipc_socket.c */
    275 int
    276 soabort(so)
    277 	struct socket *so;
    278 {
    279 	int error;
    280 #if defined(INET6)
    281 	struct sctp_inpcb *inp;
    282 #endif
    283 
    284 #if defined(INET6)
    285 	inp = (struct sctp_inpcb *)so->so_pcb;
    286 	if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
    287 		error = sctp6_abort(so);
    288 	} else {
    289 #if defined(INET)
    290 		error = sctp_abort(so);
    291 #else
    292 		error = EAFNOSUPPORT;
    293 #endif
    294 	}
    295 #elif defined(INET)
    296 	error = sctp_abort(so);
    297 #else
    298 	error = EAFNOSUPPORT;
    299 #endif
    300 	if (error) {
    301 		sofree(so);
    302 		return error;
    303 	}
    304 	return (0);
    305 }
    306 
    307 
    308 /* Taken from  usr/src/sys/kern/uipc_socket.c and called within sctp_connect (sctp_usrreq.c).
    309  *  We use sctp_connect for send_one_init_real in ms1.
    310  */
    311 void
    312 soisconnecting(struct socket *so)
    313 {
    314 
    315 	SOCK_LOCK(so);
    316 	so->so_state &= ~(SS_ISCONNECTED|SS_ISDISCONNECTING);
    317 	so->so_state |= SS_ISCONNECTING;
    318 	SOCK_UNLOCK(so);
    319 }
    320 
    321 /* Taken from  usr/src/sys/kern/uipc_socket.c and called within sctp_disconnect (sctp_usrreq.c).
    322  *  TODO Do we use sctp_disconnect?
    323  */
    324 void
    325 soisdisconnecting(struct socket *so)
    326 {
    327 
    328         /*
    329          * Note: This code assumes that SOCK_LOCK(so) and
    330          * SOCKBUF_LOCK(&so->so_rcv) are the same.
    331          */
    332         SOCKBUF_LOCK(&so->so_rcv);
    333         so->so_state &= ~SS_ISCONNECTING;
    334         so->so_state |= SS_ISDISCONNECTING;
    335         so->so_rcv.sb_state |= SBS_CANTRCVMORE;
    336         sorwakeup_locked(so);
    337         SOCKBUF_LOCK(&so->so_snd);
    338         so->so_snd.sb_state |= SBS_CANTSENDMORE;
    339         sowwakeup_locked(so);
    340         wakeup("dummy",so);
    341         /* requires 2 args but this was in orig */
    342         /* wakeup(&so->so_timeo); */
    343 }
    344 
    345 
    346 /* Taken from sys/kern/kern_synch.c and
    347    modified for __Userspace__
    348 */
    349 
    350 /*
    351  * Make all threads sleeping on the specified identifier runnable.
    352  * Associating wakeup with so_timeo identifier and timeo_cond
    353  * condition variable. TODO. If we use iterator thread then we need to
    354  * modify wakeup so it can distinguish between iterator identifier and
    355  * timeo identifier.
    356  */
    357 void
    358 wakeup(ident, so)
    359 	void *ident;
    360 	struct socket *so;
    361 {
    362 	SOCK_LOCK(so);
    363 #if defined (__Userspace_os_Windows)
    364 	WakeAllConditionVariable(&(so)->timeo_cond);
    365 #else
    366 	pthread_cond_broadcast(&(so)->timeo_cond);
    367 #endif
    368 	SOCK_UNLOCK(so);
    369 }
    370 
    371 
    372 /*
    373  * Make a thread sleeping on the specified identifier runnable.
    374  * May wake more than one thread if a target thread is currently
    375  * swapped out.
    376  */
    377 void
    378 wakeup_one(ident)
    379 	void *ident;
    380 {
    381 	/* __Userspace__ Check: We are using accept_cond for wakeup_one.
    382 	  It seems that wakeup_one is only called within
    383 	  soisconnected() and sonewconn() with ident &head->so_timeo
    384 	  head is so->so_head, which is back pointer to listen socket
    385 	  This seems to indicate that the use of accept_cond is correct
    386 	  since socket where accepts occur is so_head in all
    387 	  subsidiary sockets.
    388 	 */
    389 	ACCEPT_LOCK();
    390 #if defined (__Userspace_os_Windows)
    391 	WakeAllConditionVariable(&accept_cond);
    392 #else
    393 	pthread_cond_broadcast(&accept_cond);
    394 #endif
    395 	ACCEPT_UNLOCK();
    396 }
    397 
    398 
    399 /* Called within sctp_process_cookie_[existing/new] */
    400 void
    401 soisconnected(struct socket *so)
    402 {
    403 	struct socket *head;
    404 
    405 	ACCEPT_LOCK();
    406 	SOCK_LOCK(so);
    407 	so->so_state &= ~(SS_ISCONNECTING|SS_ISDISCONNECTING|SS_ISCONFIRMING);
    408 	so->so_state |= SS_ISCONNECTED;
    409 	head = so->so_head;
    410 	if (head != NULL && (so->so_qstate & SQ_INCOMP)) {
    411 		SOCK_UNLOCK(so);
    412 		TAILQ_REMOVE(&head->so_incomp, so, so_list);
    413 		head->so_incqlen--;
    414 		so->so_qstate &= ~SQ_INCOMP;
    415 		TAILQ_INSERT_TAIL(&head->so_comp, so, so_list);
    416 		head->so_qlen++;
    417 		so->so_qstate |= SQ_COMP;
    418 		ACCEPT_UNLOCK();
    419 		sorwakeup(head);
    420 		wakeup_one(&head->so_timeo);
    421 		return;
    422 	}
    423 	SOCK_UNLOCK(so);
    424 	ACCEPT_UNLOCK();
    425 	wakeup(&so->so_timeo, so);
    426 	sorwakeup(so);
    427 	sowwakeup(so);
    428 
    429 }
    430 
    431 /* called within sctp_handle_cookie_echo */
    432 
    433 struct socket *
    434 sonewconn(struct socket *head, int connstatus)
    435 {
    436 	struct socket *so;
    437 	int over;
    438 
    439 	ACCEPT_LOCK();
    440 	over = (head->so_qlen > 3 * head->so_qlimit / 2);
    441 	ACCEPT_UNLOCK();
    442 #ifdef REGRESSION
    443 	if (regression_sonewconn_earlytest && over)
    444 #else
    445 	if (over)
    446 #endif
    447 		return (NULL);
    448 	so = soalloc();
    449 	if (so == NULL)
    450 		return (NULL);
    451 	so->so_head = head;
    452 	so->so_type = head->so_type;
    453 	so->so_options = head->so_options &~ SCTP_SO_ACCEPTCONN;
    454 	so->so_linger = head->so_linger;
    455 	so->so_state = head->so_state | SS_NOFDREF;
    456 	so->so_dom = head->so_dom;
    457 #ifdef MAC
    458 	SOCK_LOCK(head);
    459 	mac_create_socket_from_socket(head, so);
    460 	SOCK_UNLOCK(head);
    461 #endif
    462 	if (soreserve(so, head->so_snd.sb_hiwat, head->so_rcv.sb_hiwat)) {
    463 		sodealloc(so);
    464 		return (NULL);
    465 	}
    466 	switch (head->so_dom) {
    467 #ifdef INET
    468 	case AF_INET:
    469 		if (sctp_attach(so, IPPROTO_SCTP, SCTP_DEFAULT_VRFID)) {
    470 			sodealloc(so);
    471 			return (NULL);
    472 		}
    473 		break;
    474 #endif
    475 #ifdef INET6
    476 	case AF_INET6:
    477 		if (sctp6_attach(so, IPPROTO_SCTP, SCTP_DEFAULT_VRFID)) {
    478 			sodealloc(so);
    479 			return (NULL);
    480 		}
    481 		break;
    482 #endif
    483 	case AF_CONN:
    484 		if (sctpconn_attach(so, IPPROTO_SCTP, SCTP_DEFAULT_VRFID)) {
    485 			sodealloc(so);
    486 			return (NULL);
    487 		}
    488 		break;
    489 	default:
    490 		sodealloc(so);
    491 		return (NULL);
    492 		break;
    493 	}
    494 	so->so_rcv.sb_lowat = head->so_rcv.sb_lowat;
    495 	so->so_snd.sb_lowat = head->so_snd.sb_lowat;
    496 	so->so_rcv.sb_timeo = head->so_rcv.sb_timeo;
    497 	so->so_snd.sb_timeo = head->so_snd.sb_timeo;
    498 	so->so_rcv.sb_flags |= head->so_rcv.sb_flags & SB_AUTOSIZE;
    499 	so->so_snd.sb_flags |= head->so_snd.sb_flags & SB_AUTOSIZE;
    500 	so->so_state |= connstatus;
    501 	ACCEPT_LOCK();
    502 	if (connstatus) {
    503 		TAILQ_INSERT_TAIL(&head->so_comp, so, so_list);
    504 		so->so_qstate |= SQ_COMP;
    505 		head->so_qlen++;
    506 	} else {
    507 		/*
    508 		 * Keep removing sockets from the head until there's room for
    509 		 * us to insert on the tail.  In pre-locking revisions, this
    510 		 * was a simple if(), but as we could be racing with other
    511 		 * threads and soabort() requires dropping locks, we must
    512 		 * loop waiting for the condition to be true.
    513 		 */
    514 		while (head->so_incqlen > head->so_qlimit) {
    515 			struct socket *sp;
    516 			sp = TAILQ_FIRST(&head->so_incomp);
    517 			TAILQ_REMOVE(&head->so_incomp, sp, so_list);
    518 			head->so_incqlen--;
    519 			sp->so_qstate &= ~SQ_INCOMP;
    520 			sp->so_head = NULL;
    521 			ACCEPT_UNLOCK();
    522 			soabort(sp);
    523 			ACCEPT_LOCK();
    524 		}
    525 		TAILQ_INSERT_TAIL(&head->so_incomp, so, so_list);
    526 		so->so_qstate |= SQ_INCOMP;
    527 		head->so_incqlen++;
    528 	}
    529 	ACCEPT_UNLOCK();
    530 	if (connstatus) {
    531 		sorwakeup(head);
    532 		wakeup_one(&head->so_timeo);
    533 	}
    534 	return (so);
    535 
    536 }
    537 
    538 /* From /src/sys/sys/sysproto.h */
    539 struct sctp_generic_sendmsg_args {
    540 	int sd;
    541 	caddr_t msg;
    542 	int mlen;
    543 	caddr_t to;
    544 	socklen_t tolen;  /* was __socklen_t */
    545 	struct sctp_sndrcvinfo * sinfo;
    546 	int flags;
    547 };
    548 
    549 struct sctp_generic_recvmsg_args {
    550         int sd;
    551         struct iovec *iov;
    552         int iovlen;
    553         struct sockaddr *from;
    554         socklen_t *fromlenaddr; /* was __socklen_t */
    555         struct sctp_sndrcvinfo *sinfo;
    556         int *msg_flags;
    557 };
    558 
    559 
    560  /*
    561    Source: /src/sys/gnu/fs/xfs/FreeBSD/xfs_ioctl.c
    562  */
    563 static __inline__ int
    564 copy_to_user(void *dst, void *src, int len) {
    565 	memcpy(dst, src, len);
    566 	return 0;
    567 }
    568 
    569 static __inline__ int
    570 copy_from_user(void *dst, void *src, int len) {
    571 	memcpy(dst, src, len);
    572 	return 0;
    573 }
    574 
    575 /*
    576  References:
    577  src/sys/dev/lmc/if_lmc.h:
    578  src/sys/powerpc/powerpc/copyinout.c
    579  src/sys/sys/systm.h
    580 */
    581 # define copyin(u, k, len)	copy_from_user(k, u, len)
    582 
    583 /* References:
    584    src/sys/powerpc/powerpc/copyinout.c
    585    src/sys/sys/systm.h
    586 */
    587 # define copyout(k, u, len)	copy_to_user(u, k, len)
    588 
    589 
    590 /* copyiniov definition copied/modified from src/sys/kern/kern_subr.c */
    591 int
    592 copyiniov(struct iovec *iovp, u_int iovcnt, struct iovec **iov, int error)
    593 {
    594 	u_int iovlen;
    595 
    596 	*iov = NULL;
    597 	if (iovcnt > UIO_MAXIOV)
    598 		return (error);
    599 	iovlen = iovcnt * sizeof (struct iovec);
    600 	*iov = malloc(iovlen); /*, M_IOV, M_WAITOK); */
    601 	error = copyin(iovp, *iov, iovlen);
    602 	if (error) {
    603 		free(*iov); /*, M_IOV); */
    604 		*iov = NULL;
    605 	}
    606 	return (error);
    607 }
    608 
    609 /* (__Userspace__) version of uiomove */
    610 int
    611 uiomove(void *cp, int n, struct uio *uio)
    612 {
    613 	struct iovec *iov;
    614 	int cnt;
    615 	int error = 0;
    616 
    617 	if ((uio->uio_rw != UIO_READ) &&
    618 	    (uio->uio_rw != UIO_WRITE)) {
    619 		return (EINVAL);
    620 	}
    621 
    622 	while (n > 0 && uio->uio_resid) {
    623 		iov = uio->uio_iov;
    624 		cnt = iov->iov_len;
    625 		if (cnt == 0) {
    626 			uio->uio_iov++;
    627 			uio->uio_iovcnt--;
    628 			continue;
    629 		}
    630 		if (cnt > n)
    631 			cnt = n;
    632 
    633 		switch (uio->uio_segflg) {
    634 
    635 		case UIO_USERSPACE:
    636 			if (uio->uio_rw == UIO_READ)
    637 				error = copyout(cp, iov->iov_base, cnt);
    638 			else
    639 				error = copyin(iov->iov_base, cp, cnt);
    640 			if (error)
    641 				goto out;
    642 			break;
    643 
    644 		case UIO_SYSSPACE:
    645 			if (uio->uio_rw == UIO_READ)
    646 				bcopy(cp, iov->iov_base, cnt);
    647 			else
    648 				bcopy(iov->iov_base, cp, cnt);
    649 			break;
    650 		}
    651 		iov->iov_base = (char *)iov->iov_base + cnt;
    652 		iov->iov_len -= cnt;
    653 		uio->uio_resid -= cnt;
    654 		uio->uio_offset += cnt;
    655 		cp = (char *)cp + cnt;
    656 		n -= cnt;
    657 	}
    658 out:
    659 	return (error);
    660 }
    661 
    662 
    663 /* Source: src/sys/kern/uipc_syscalls.c */
    664 int
    665 getsockaddr(namp, uaddr, len)
    666 	struct sockaddr **namp;
    667 	caddr_t uaddr;
    668 	size_t len;
    669 {
    670 	struct sockaddr *sa;
    671 	int error;
    672 
    673 	if (len > SOCK_MAXADDRLEN)
    674 		return (ENAMETOOLONG);
    675 	if (len < offsetof(struct sockaddr, sa_data))
    676 		return (EINVAL);
    677 	MALLOC(sa, struct sockaddr *, len, M_SONAME, M_WAITOK);
    678 	error = copyin(uaddr, sa, len);
    679 	if (error) {
    680 		FREE(sa, M_SONAME);
    681 	} else {
    682 #ifdef HAVE_SA_LEN
    683 		sa->sa_len = len;
    684 #endif
    685 		*namp = sa;
    686 	}
    687 	return (error);
    688 }
    689 
    690 
    691 /* Taken from  /src/lib/libc/net/sctp_sys_calls.c
    692  * and modified for __Userspace__
    693  * calling sctp_generic_sendmsg from this function
    694  */
    695 ssize_t
    696 userspace_sctp_sendmsg(struct socket *so,
    697                        const void *data,
    698                        size_t len,
    699                        struct sockaddr *to,
    700                        socklen_t tolen,
    701                        u_int32_t ppid,
    702                        u_int32_t flags,
    703                        u_int16_t stream_no,
    704                        u_int32_t timetolive,
    705                        u_int32_t context)
    706 {
    707 	struct sctp_sndrcvinfo sndrcvinfo, *sinfo = &sndrcvinfo;
    708 	struct uio auio;
    709 	struct iovec iov[1];
    710 
    711 	sinfo->sinfo_ppid = ppid;
    712 	sinfo->sinfo_flags = flags;
    713 	sinfo->sinfo_stream = stream_no;
    714 	sinfo->sinfo_timetolive = timetolive;
    715 	sinfo->sinfo_context = context;
    716 	sinfo->sinfo_assoc_id = 0;
    717 
    718 
    719 	/* Perform error checks on destination (to) */
    720 	if (tolen > SOCK_MAXADDRLEN){
    721 		errno = ENAMETOOLONG;
    722 		return (-1);
    723 	}
    724 	if ((tolen > 0) &&
    725 	    ((to == NULL) || (tolen < (socklen_t)sizeof(struct sockaddr)))) {
    726 		errno = EINVAL;
    727 		return (-1);
    728 	}
    729 	/* Adding the following as part of defensive programming, in case the application
    730 	   does not do it when preparing the destination address.*/
    731 #ifdef HAVE_SA_LEN
    732 	if (to != NULL) {
    733 		to->sa_len = tolen;
    734 	}
    735 #endif
    736 
    737 	iov[0].iov_base = (caddr_t)data;
    738 	iov[0].iov_len = len;
    739 
    740 	auio.uio_iov =  iov;
    741 	auio.uio_iovcnt = 1;
    742 	auio.uio_segflg = UIO_USERSPACE;
    743 	auio.uio_rw = UIO_WRITE;
    744 	auio.uio_offset = 0;			/* XXX */
    745 	auio.uio_resid = len;
    746 	errno = sctp_lower_sosend(so, to, &auio, NULL, NULL, 0, sinfo);
    747 	if (errno == 0) {
    748 		return (len - auio.uio_resid);
    749 	} else {
    750 		return (-1);
    751 	}
    752 }
    753 
    754 
    755 ssize_t
    756 usrsctp_sendv(struct socket *so,
    757               const void *data,
    758               size_t len,
    759               struct sockaddr *to,
    760               int addrcnt,
    761               void *info,
    762               socklen_t infolen,
    763               unsigned int infotype,
    764               int flags)
    765 {
    766 	struct sctp_sndrcvinfo sinfo;
    767 	struct uio auio;
    768 	struct iovec iov[1];
    769 	int use_sinfo;
    770 
    771 	if (so == NULL) {
    772 		errno = EBADF;
    773 		return (-1);
    774 	}
    775 	memset(&sinfo, 0, sizeof(struct sctp_sndrcvinfo));
    776 	use_sinfo = 0;
    777 	switch (infotype) {
    778 	case SCTP_SENDV_NOINFO:
    779 		if ((infolen != 0) || (info != NULL)) {
    780 			errno = EINVAL;
    781 			return (-1);
    782 		}
    783 		break;
    784 	case SCTP_SENDV_SNDINFO:
    785 		if ((info == NULL) || (infolen != sizeof(struct sctp_sndinfo))) {
    786 			errno = EINVAL;
    787 			return (-1);
    788 		}
    789 		sinfo.sinfo_stream = ((struct sctp_sndinfo *)info)->snd_sid;
    790 		sinfo.sinfo_flags = ((struct sctp_sndinfo *)info)->snd_flags;
    791 		sinfo.sinfo_ppid = ((struct sctp_sndinfo *)info)->snd_ppid;
    792 		sinfo.sinfo_context = ((struct sctp_sndinfo *)info)->snd_context;
    793 		sinfo.sinfo_assoc_id = ((struct sctp_sndinfo *)info)->snd_assoc_id;
    794 		use_sinfo = 1;
    795 		break;
    796 	case SCTP_SENDV_PRINFO:
    797 		if ((info == NULL) || (infolen != sizeof(struct sctp_prinfo))) {
    798 			errno = EINVAL;
    799 			return (-1);
    800 		}
    801 		sinfo.sinfo_stream = 0;
    802 		sinfo.sinfo_flags = PR_SCTP_POLICY(((struct sctp_prinfo *)info)->pr_policy);
    803 		sinfo.sinfo_timetolive = ((struct sctp_prinfo *)info)->pr_value;
    804 		use_sinfo = 1;
    805 		break;
    806 	case SCTP_SENDV_AUTHINFO:
    807 		errno = EINVAL;
    808 		return (-1);
    809 	case SCTP_SENDV_SPA:
    810 		if ((info == NULL) || (infolen != sizeof(struct sctp_sendv_spa))) {
    811 			errno = EINVAL;
    812 			return (-1);
    813 		}
    814 		if (((struct sctp_sendv_spa *)info)->sendv_flags & SCTP_SEND_SNDINFO_VALID) {
    815 			sinfo.sinfo_stream = ((struct sctp_sendv_spa *)info)->sendv_sndinfo.snd_sid;
    816 			sinfo.sinfo_flags = ((struct sctp_sendv_spa *)info)->sendv_sndinfo.snd_flags;
    817 			sinfo.sinfo_ppid = ((struct sctp_sendv_spa *)info)->sendv_sndinfo.snd_ppid;
    818 			sinfo.sinfo_context = ((struct sctp_sendv_spa *)info)->sendv_sndinfo.snd_context;
    819 			sinfo.sinfo_assoc_id = ((struct sctp_sendv_spa *)info)->sendv_sndinfo.snd_assoc_id;
    820 		} else {
    821 			sinfo.sinfo_flags = 0;
    822 			sinfo.sinfo_stream = 0;
    823 		}
    824 		if (((struct sctp_sendv_spa *)info)->sendv_flags & SCTP_SEND_PRINFO_VALID) {
    825 			sinfo.sinfo_flags |= PR_SCTP_POLICY(((struct sctp_sendv_spa *)info)->sendv_prinfo.pr_policy);
    826 			sinfo.sinfo_timetolive = ((struct sctp_sendv_spa *)info)->sendv_prinfo.pr_value;
    827 		}
    828 		if (((struct sctp_sendv_spa *)info)->sendv_flags & SCTP_SEND_AUTHINFO_VALID) {
    829 			errno = EINVAL;
    830 			return (-1);
    831 		}
    832 		use_sinfo = 1;
    833 		break;
    834 	default:
    835 		errno = EINVAL;
    836 		return (-1);
    837 	}
    838 
    839 	/* Perform error checks on destination (to) */
    840 	if (addrcnt > 1) {
    841 		errno = EINVAL;
    842 		return (-1);
    843 	}
    844 
    845 	iov[0].iov_base = (caddr_t)data;
    846 	iov[0].iov_len = len;
    847 
    848 	auio.uio_iov =  iov;
    849 	auio.uio_iovcnt = 1;
    850 	auio.uio_segflg = UIO_USERSPACE;
    851 	auio.uio_rw = UIO_WRITE;
    852 	auio.uio_offset = 0;			/* XXX */
    853 	auio.uio_resid = len;
    854 	errno = sctp_lower_sosend(so, to, &auio, NULL, NULL, flags, use_sinfo ? &sinfo : NULL);
    855 	if (errno == 0) {
    856 		return (len - auio.uio_resid);
    857 	} else {
    858 		return (-1);
    859 	}
    860 }
    861 
    862 
    863 ssize_t
    864 userspace_sctp_sendmbuf(struct socket *so,
    865     struct mbuf* mbufdata,
    866     size_t len,
    867     struct sockaddr *to,
    868     socklen_t tolen,
    869     u_int32_t ppid,
    870     u_int32_t flags,
    871     u_int16_t stream_no,
    872     u_int32_t timetolive,
    873     u_int32_t context)
    874 {
    875 
    876     struct sctp_sndrcvinfo sndrcvinfo, *sinfo = &sndrcvinfo;
    877     /*    struct uio auio;
    878           struct iovec iov[1]; */
    879     int error = 0;
    880     int uflags = 0;
    881     int retvalsendmsg;
    882 
    883     sinfo->sinfo_ppid = ppid;
    884     sinfo->sinfo_flags = flags;
    885     sinfo->sinfo_stream = stream_no;
    886     sinfo->sinfo_timetolive = timetolive;
    887     sinfo->sinfo_context = context;
    888     sinfo->sinfo_assoc_id = 0;
    889 
    890     /* Perform error checks on destination (to) */
    891     if (tolen > SOCK_MAXADDRLEN){
    892         error = (ENAMETOOLONG);
    893         goto sendmsg_return;
    894     }
    895     if (tolen < (socklen_t)offsetof(struct sockaddr, sa_data)){
    896         error = (EINVAL);
    897         goto sendmsg_return;
    898     }
    899     /* Adding the following as part of defensive programming, in case the application
    900        does not do it when preparing the destination address.*/
    901 #ifdef HAVE_SA_LEN
    902     to->sa_len = tolen;
    903 #endif
    904 
    905     error = sctp_lower_sosend(so, to, NULL/*uio*/,
    906                               (struct mbuf *)mbufdata, (struct mbuf *)NULL,
    907                               uflags, sinfo);
    908 sendmsg_return:
    909     /* TODO: Needs a condition for non-blocking when error is EWOULDBLOCK */
    910     if (0 == error)
    911         retvalsendmsg = len;
    912     else if(error == EWOULDBLOCK) {
    913         errno = EWOULDBLOCK;
    914         retvalsendmsg = (-1);
    915     } else {
    916         SCTP_PRINTF("%s: error = %d\n", __func__, error);
    917         errno = error;
    918         retvalsendmsg = (-1);
    919     }
    920     return retvalsendmsg;
    921 
    922 }
    923 
    924 
    925 /* taken from usr.lib/sctp_sys_calls.c and needed here */
    926 #define        SCTP_SMALL_IOVEC_SIZE 2
    927 
    928 /* Taken from  /src/lib/libc/net/sctp_sys_calls.c
    929  * and modified for __Userspace__
    930  * calling sctp_generic_recvmsg from this function
    931  */
    932 ssize_t
    933 userspace_sctp_recvmsg(struct socket *so,
    934     void *dbuf,
    935     size_t len,
    936     struct sockaddr *from,
    937     socklen_t *fromlenp,
    938     struct sctp_sndrcvinfo *sinfo,
    939     int *msg_flags)
    940 {
    941 	struct uio auio;
    942 	struct iovec iov[SCTP_SMALL_IOVEC_SIZE];
    943 	struct iovec *tiov;
    944 	int iovlen = 1;
    945 	int error = 0;
    946 	int ulen, i, retval;
    947 	socklen_t fromlen;
    948 
    949 	iov[0].iov_base = dbuf;
    950 	iov[0].iov_len = len;
    951 
    952 	auio.uio_iov = iov;
    953 	auio.uio_iovcnt = iovlen;
    954 	auio.uio_segflg = UIO_USERSPACE;
    955 	auio.uio_rw = UIO_READ;
    956 	auio.uio_offset = 0;			/* XXX */
    957 	auio.uio_resid = 0;
    958 	tiov = iov;
    959 	for (i = 0; i <iovlen; i++, tiov++) {
    960 		if ((auio.uio_resid += tiov->iov_len) < 0) {
    961 			error = EINVAL;
    962 			SCTP_PRINTF("%s: error = %d\n", __func__, error);
    963 			return (-1);
    964 		}
    965 	}
    966 	ulen = auio.uio_resid;
    967 	if (fromlenp != NULL) {
    968 		fromlen = *fromlenp;
    969 	} else {
    970 		fromlen = 0;
    971 	}
    972 	error = sctp_sorecvmsg(so, &auio, (struct mbuf **)NULL,
    973 		    from, fromlen, msg_flags,
    974 		    (struct sctp_sndrcvinfo *)sinfo, 1);
    975 
    976 	if (error) {
    977 		if (auio.uio_resid != (int)ulen &&
    978 		    (error == EINTR ||
    979 #if !defined(__Userspace_os_NetBSD)
    980 		     error == ERESTART ||
    981 #endif
    982 		     error == EWOULDBLOCK)) {
    983 			error = 0;
    984 		}
    985 	}
    986 	if ((fromlenp != NULL) && (fromlen > 0) && (from != NULL)) {
    987 		switch (from->sa_family) {
    988 #if defined(INET)
    989 		case AF_INET:
    990 			*fromlenp = sizeof(struct sockaddr_in);
    991 			break;
    992 #endif
    993 #if defined(INET6)
    994 		case AF_INET6:
    995 			*fromlenp = sizeof(struct sockaddr_in6);
    996 			break;
    997 #endif
    998 		case AF_CONN:
    999 			*fromlenp = sizeof(struct sockaddr_conn);
   1000 			break;
   1001 		default:
   1002 			*fromlenp = 0;
   1003 			break;
   1004 		}
   1005 		if (*fromlenp > fromlen) {
   1006 			*fromlenp = fromlen;
   1007 		}
   1008 	}
   1009 	if (error == 0){
   1010 		/* ready return value */
   1011 		retval = (int)ulen - auio.uio_resid;
   1012 		return (retval);
   1013 	} else {
   1014 		SCTP_PRINTF("%s: error = %d\n", __func__, error);
   1015 		return (-1);
   1016 	}
   1017 }
   1018 
   1019 ssize_t
   1020 usrsctp_recvv(struct socket *so,
   1021     void *dbuf,
   1022     size_t len,
   1023     struct sockaddr *from,
   1024     socklen_t *fromlenp,
   1025     void *info,
   1026     socklen_t *infolen,
   1027     unsigned int *infotype,
   1028     int *msg_flags)
   1029 {
   1030 	struct uio auio;
   1031 	struct iovec iov[SCTP_SMALL_IOVEC_SIZE];
   1032 	struct iovec *tiov;
   1033 	int iovlen = 1;
   1034 	int ulen, i;
   1035 	socklen_t fromlen;
   1036 	struct sctp_rcvinfo *rcv;
   1037 	struct sctp_recvv_rn *rn;
   1038 	struct sctp_extrcvinfo seinfo;
   1039 
   1040 	if (so == NULL) {
   1041 		errno = EBADF;
   1042 		return (-1);
   1043 	}
   1044 	iov[0].iov_base = dbuf;
   1045 	iov[0].iov_len = len;
   1046 
   1047 	auio.uio_iov = iov;
   1048 	auio.uio_iovcnt = iovlen;
   1049 	auio.uio_segflg = UIO_USERSPACE;
   1050 	auio.uio_rw = UIO_READ;
   1051 	auio.uio_offset = 0;			/* XXX */
   1052 	auio.uio_resid = 0;
   1053 	tiov = iov;
   1054 	for (i = 0; i <iovlen; i++, tiov++) {
   1055 		if ((auio.uio_resid += tiov->iov_len) < 0) {
   1056 			errno = EINVAL;
   1057 			return (-1);
   1058 		}
   1059 	}
   1060 	ulen = auio.uio_resid;
   1061 	if (fromlenp != NULL) {
   1062 		fromlen = *fromlenp;
   1063 	} else {
   1064 		fromlen = 0;
   1065 	}
   1066 	errno = sctp_sorecvmsg(so, &auio, (struct mbuf **)NULL,
   1067 		    from, fromlen, msg_flags,
   1068 		    (struct sctp_sndrcvinfo *)&seinfo, 1);
   1069 	if (errno) {
   1070 		if (auio.uio_resid != (int)ulen &&
   1071 		    (errno == EINTR ||
   1072 #if !defined(__Userspace_os_NetBSD)
   1073 		     errno == ERESTART ||
   1074 #endif
   1075 		     errno == EWOULDBLOCK)) {
   1076 			errno = 0;
   1077 		}
   1078 	}
   1079 	if ((*msg_flags & MSG_NOTIFICATION) == 0) {
   1080 		struct sctp_inpcb *inp;
   1081 
   1082 		inp = (struct sctp_inpcb *)so->so_pcb;
   1083 		if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVNXTINFO) &&
   1084 		    sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVRCVINFO) &&
   1085 		    *infolen >= (socklen_t)sizeof(struct sctp_recvv_rn) &&
   1086 		    seinfo.sreinfo_next_flags & SCTP_NEXT_MSG_AVAIL) {
   1087 			rn = (struct sctp_recvv_rn *)info;
   1088 			rn->recvv_rcvinfo.rcv_sid = seinfo.sinfo_stream;
   1089 			rn->recvv_rcvinfo.rcv_ssn = seinfo.sinfo_ssn;
   1090 			rn->recvv_rcvinfo.rcv_flags = seinfo.sinfo_flags;
   1091 			rn->recvv_rcvinfo.rcv_ppid = seinfo.sinfo_ppid;
   1092 			rn->recvv_rcvinfo.rcv_context = seinfo.sinfo_context;
   1093 			rn->recvv_rcvinfo.rcv_tsn = seinfo.sinfo_tsn;
   1094 			rn->recvv_rcvinfo.rcv_cumtsn = seinfo.sinfo_cumtsn;
   1095 			rn->recvv_rcvinfo.rcv_assoc_id = seinfo.sinfo_assoc_id;
   1096 			rn->recvv_nxtinfo.nxt_sid = seinfo.sreinfo_next_stream;
   1097 			rn->recvv_nxtinfo.nxt_flags = 0;
   1098 			if (seinfo.sreinfo_next_flags & SCTP_NEXT_MSG_IS_UNORDERED) {
   1099 				rn->recvv_nxtinfo.nxt_flags |= SCTP_UNORDERED;
   1100 			}
   1101 			if (seinfo.sreinfo_next_flags & SCTP_NEXT_MSG_IS_NOTIFICATION) {
   1102 				rn->recvv_nxtinfo.nxt_flags |= SCTP_NOTIFICATION;
   1103 			}
   1104 			if (seinfo.sreinfo_next_flags & SCTP_NEXT_MSG_ISCOMPLETE) {
   1105 				rn->recvv_nxtinfo.nxt_flags |= SCTP_COMPLETE;
   1106 			}
   1107 			rn->recvv_nxtinfo.nxt_ppid = seinfo.sreinfo_next_ppid;
   1108 			rn->recvv_nxtinfo.nxt_length = seinfo.sreinfo_next_length;
   1109 			rn->recvv_nxtinfo.nxt_assoc_id = seinfo.sreinfo_next_aid;
   1110 			*infolen = (socklen_t)sizeof(struct sctp_recvv_rn);
   1111 			*infotype = SCTP_RECVV_RN;
   1112 		} else if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVRCVINFO) &&
   1113 		           *infolen >= (socklen_t)sizeof(struct sctp_rcvinfo)) {
   1114 			rcv = (struct sctp_rcvinfo *)info;
   1115 			rcv->rcv_sid = seinfo.sinfo_stream;
   1116 			rcv->rcv_ssn = seinfo.sinfo_ssn;
   1117 			rcv->rcv_flags = seinfo.sinfo_flags;
   1118 			rcv->rcv_ppid = seinfo.sinfo_ppid;
   1119 			rcv->rcv_context = seinfo.sinfo_context;
   1120 			rcv->rcv_tsn = seinfo.sinfo_tsn;
   1121 			rcv->rcv_cumtsn = seinfo.sinfo_cumtsn;
   1122 			rcv->rcv_assoc_id = seinfo.sinfo_assoc_id;
   1123 			*infolen = (socklen_t)sizeof(struct sctp_rcvinfo);
   1124 			*infotype = SCTP_RECVV_RCVINFO;
   1125 		} else {
   1126 			*infotype = SCTP_RECVV_NOINFO;
   1127 			*infolen = 0;
   1128 		}
   1129 	}
   1130 	if ((fromlenp != NULL) && (fromlen > 0) && (from != NULL)) {
   1131 		switch (from->sa_family) {
   1132 #if defined(INET)
   1133 		case AF_INET:
   1134 			*fromlenp = sizeof(struct sockaddr_in);
   1135 			break;
   1136 #endif
   1137 #if defined(INET6)
   1138 		case AF_INET6:
   1139 			*fromlenp = sizeof(struct sockaddr_in6);
   1140 			break;
   1141 #endif
   1142 		case AF_CONN:
   1143 			*fromlenp = sizeof(struct sockaddr_conn);
   1144 			break;
   1145 		default:
   1146 			*fromlenp = 0;
   1147 			break;
   1148 		}
   1149 		if (*fromlenp > fromlen) {
   1150 			*fromlenp = fromlen;
   1151 		}
   1152 	}
   1153 	if (errno == 0) {
   1154 		/* ready return value */
   1155 		return ((int)ulen - auio.uio_resid);
   1156 	} else {
   1157 		return (-1);
   1158 	}
   1159 }
   1160 
   1161 
   1162 
   1163 
   1164 #if defined(__Userspace__)
   1165 /* Taken from  /src/sys/kern/uipc_socket.c
   1166  * and modified for __Userspace__
   1167  * socreate returns a socket.  The socket should be
   1168  * closed with soclose().
   1169  */
   1170 int
   1171 socreate(int dom, struct socket **aso, int type, int proto)
   1172 {
   1173 	struct socket *so;
   1174 	int error;
   1175 
   1176 	if ((dom != AF_CONN) && (dom != AF_INET) && (dom != AF_INET6)) {
   1177 		return (EINVAL);
   1178 	}
   1179 	if ((type != SOCK_STREAM) && (type != SOCK_SEQPACKET)) {
   1180 		return (EINVAL);
   1181 	}
   1182 	if (proto != IPPROTO_SCTP) {
   1183 		return (EINVAL);
   1184 	}
   1185 
   1186 	so = soalloc();
   1187 	if (so == NULL) {
   1188 		return (ENOBUFS);
   1189 	}
   1190 
   1191 	/*
   1192 	 * so_incomp represents a queue of connections that
   1193 	 * must be completed at protocol level before being
   1194 	 * returned. so_comp field heads a list of sockets
   1195 	 * that are ready to be returned to the listening process
   1196 	 *__Userspace__ These queues are being used at a number of places like accept etc.
   1197 	 */
   1198 	TAILQ_INIT(&so->so_incomp);
   1199 	TAILQ_INIT(&so->so_comp);
   1200 	so->so_type = type;
   1201 	so->so_count = 1;
   1202 	so->so_dom = dom;
   1203 	/*
   1204 	 * Auto-sizing of socket buffers is managed by the protocols and
   1205 	 * the appropriate flags must be set in the pru_attach function.
   1206 	 * For __Userspace__ The pru_attach function in this case is sctp_attach.
   1207 	 */
   1208 	switch (dom) {
   1209 #if defined(INET)
   1210 	case AF_INET:
   1211 		error = sctp_attach(so, proto, SCTP_DEFAULT_VRFID);
   1212 		break;
   1213 #endif
   1214 #if defined(INET6)
   1215 	case AF_INET6:
   1216 		error = sctp6_attach(so, proto, SCTP_DEFAULT_VRFID);
   1217 		break;
   1218 #endif
   1219 	case AF_CONN:
   1220 		error = sctpconn_attach(so, proto, SCTP_DEFAULT_VRFID);
   1221 		break;
   1222 	default:
   1223 		error = EAFNOSUPPORT;
   1224 		break;
   1225 	}
   1226 	if (error) {
   1227 		KASSERT(so->so_count == 1, ("socreate: so_count %d", so->so_count));
   1228 		so->so_count = 0;
   1229 		sodealloc(so);
   1230 		return (error);
   1231 	}
   1232 	*aso = so;
   1233 	return (0);
   1234 }
   1235 #else
   1236 /* The kernel version for reference is below. The #else
   1237    should be removed once the __Userspace__
   1238    version is tested.
   1239  * socreate returns a socket with a ref count of 1.  The socket should be
   1240  * closed with soclose().
   1241  */
   1242 int
   1243 socreate(int dom, struct socket **aso, int type, int proto,
   1244     struct ucred *cred, struct thread *td)
   1245 {
   1246 	struct protosw *prp;
   1247 	struct socket *so;
   1248 	int error;
   1249 
   1250 	if (proto)
   1251 		prp = pffindproto(dom, proto, type);
   1252 	else
   1253 		prp = pffindtype(dom, type);
   1254 
   1255 	if (prp == NULL || prp->pr_usrreqs->pru_attach == NULL ||
   1256 	    prp->pr_usrreqs->pru_attach == pru_attach_notsupp)
   1257 		return (EPROTONOSUPPORT);
   1258 
   1259 	if (jailed(cred) && jail_socket_unixiproute_only &&
   1260 	    prp->pr_domain->dom_family != PF_LOCAL &&
   1261 	    prp->pr_domain->dom_family != PF_INET &&
   1262 	    prp->pr_domain->dom_family != PF_ROUTE) {
   1263 		return (EPROTONOSUPPORT);
   1264 	}
   1265 
   1266 	if (prp->pr_type != type)
   1267 		return (EPROTOTYPE);
   1268 	so = soalloc();
   1269 	if (so == NULL)
   1270 		return (ENOBUFS);
   1271 
   1272 	TAILQ_INIT(&so->so_incomp);
   1273 	TAILQ_INIT(&so->so_comp);
   1274 	so->so_type = type;
   1275 	so->so_cred = crhold(cred);
   1276 	so->so_proto = prp;
   1277 #ifdef MAC
   1278 	mac_create_socket(cred, so);
   1279 #endif
   1280 	knlist_init(&so->so_rcv.sb_sel.si_note, SOCKBUF_MTX(&so->so_rcv),
   1281 	    NULL, NULL, NULL);
   1282 	knlist_init(&so->so_snd.sb_sel.si_note, SOCKBUF_MTX(&so->so_snd),
   1283 	    NULL, NULL, NULL);
   1284 	so->so_count = 1;
   1285 	/*
   1286 	 * Auto-sizing of socket buffers is managed by the protocols and
   1287 	 * the appropriate flags must be set in the pru_attach function.
   1288 	 */
   1289 	error = (*prp->pr_usrreqs->pru_attach)(so, proto, td);
   1290 	if (error) {
   1291 		KASSERT(so->so_count == 1, ("socreate: so_count %d",
   1292 		    so->so_count));
   1293 		so->so_count = 0;
   1294 		sodealloc(so);
   1295 		return (error);
   1296 	}
   1297 	*aso = so;
   1298 	return (0);
   1299 }
   1300 #endif
   1301 
   1302 
   1303 
   1304 
   1305 /* Taken from  /src/sys/kern/uipc_syscalls.c
   1306  * and modified for __Userspace__
   1307  * Removing struct thread td.
   1308  */
   1309 struct socket *
   1310 userspace_socket(int domain, int type, int protocol)
   1311 {
   1312 	struct socket *so = NULL;
   1313 
   1314 	errno = socreate(domain, &so, type, protocol);
   1315 	if (errno) {
   1316 		return (NULL);
   1317 	}
   1318 	/*
   1319 	 * The original socket call returns the file descriptor fd.
   1320 	 * td->td_retval[0] = fd.
   1321 	 * We are returning struct socket *so.
   1322 	 */
   1323 	return (so);
   1324 }
   1325 
   1326 struct socket *
   1327 usrsctp_socket(int domain, int type, int protocol,
   1328 	       int (*receive_cb)(struct socket *sock, union sctp_sockstore addr, void *data,
   1329                                  size_t datalen, struct sctp_rcvinfo, int flags, void *ulp_info),
   1330 	       int (*send_cb)(struct socket *sock, uint32_t sb_free),
   1331 	       uint32_t sb_threshold,
   1332 	       void *ulp_info)
   1333 {
   1334 	struct socket *so;
   1335 
   1336 	if ((protocol = IPPROTO_SCTP) && (SCTP_BASE_VAR(sctp_pcb_initialized) == 0)) {
   1337 		errno = EPROTONOSUPPORT;
   1338 		return (NULL);
   1339 	}
   1340 	if ((receive_cb == NULL) &&
   1341 	    ((send_cb != NULL) || (sb_threshold != 0) || (ulp_info != NULL))) {
   1342 		errno = EINVAL;
   1343 		return (NULL);
   1344 	}
   1345 	if ((domain == AF_CONN) && (SCTP_BASE_VAR(conn_output) == NULL)) {
   1346 		errno = EAFNOSUPPORT;
   1347 		return (NULL);
   1348 	}
   1349 	errno = socreate(domain, &so, type, protocol);
   1350 	if (errno) {
   1351 		return (NULL);
   1352 	}
   1353 	/*
   1354 	 * The original socket call returns the file descriptor fd.
   1355 	 * td->td_retval[0] = fd.
   1356 	 * We are returning struct socket *so.
   1357 	 */
   1358 	register_recv_cb(so, receive_cb);
   1359 	register_send_cb(so, sb_threshold, send_cb);
   1360 	register_ulp_info(so, ulp_info);
   1361 	return (so);
   1362 }
   1363 
   1364 
   1365 u_long	sb_max = SB_MAX;
   1366 u_long sb_max_adj =
   1367        SB_MAX * MCLBYTES / (MSIZE + MCLBYTES); /* adjusted sb_max */
   1368 
   1369 static	u_long sb_efficiency = 8;	/* parameter for sbreserve() */
   1370 
   1371 /*
   1372  * Allot mbufs to a sockbuf.  Attempt to scale mbmax so that mbcnt doesn't
   1373  * become limiting if buffering efficiency is near the normal case.
   1374  */
   1375 int
   1376 sbreserve_locked(struct sockbuf *sb, u_long cc, struct socket *so)
   1377 {
   1378 	SOCKBUF_LOCK_ASSERT(sb);
   1379 	sb->sb_mbmax = (u_int)min(cc * sb_efficiency, sb_max);
   1380 	sb->sb_hiwat = cc;
   1381 	if (sb->sb_lowat > (int)sb->sb_hiwat)
   1382 		sb->sb_lowat = (int)sb->sb_hiwat;
   1383 	return (1);
   1384 }
   1385 
   1386 static int
   1387 sbreserve(struct sockbuf *sb, u_long cc, struct socket *so)
   1388 {
   1389 	int error;
   1390 
   1391 	SOCKBUF_LOCK(sb);
   1392 	error = sbreserve_locked(sb, cc, so);
   1393 	SOCKBUF_UNLOCK(sb);
   1394 	return (error);
   1395 }
   1396 
   1397 #if defined(__Userspace__)
   1398 int
   1399 soreserve(struct socket *so, u_long sndcc, u_long rcvcc)
   1400 {
   1401 	SOCKBUF_LOCK(&so->so_snd);
   1402 	SOCKBUF_LOCK(&so->so_rcv);
   1403 	so->so_snd.sb_hiwat = (uint32_t)sndcc;
   1404 	so->so_rcv.sb_hiwat = (uint32_t)rcvcc;
   1405 
   1406 	if (sbreserve_locked(&so->so_snd, sndcc, so) == 0) {
   1407 		goto bad;
   1408 	}
   1409 	if (sbreserve_locked(&so->so_rcv, rcvcc, so) == 0) {
   1410 		goto bad;
   1411 	}
   1412 	if (so->so_rcv.sb_lowat == 0)
   1413 		so->so_rcv.sb_lowat = 1;
   1414 	if (so->so_snd.sb_lowat == 0)
   1415 		so->so_snd.sb_lowat = MCLBYTES;
   1416 	if (so->so_snd.sb_lowat > (int)so->so_snd.sb_hiwat)
   1417 		so->so_snd.sb_lowat = (int)so->so_snd.sb_hiwat;
   1418 	SOCKBUF_UNLOCK(&so->so_rcv);
   1419 	SOCKBUF_UNLOCK(&so->so_snd);
   1420 	return (0);
   1421 
   1422  bad:
   1423 	SOCKBUF_UNLOCK(&so->so_rcv);
   1424 	SOCKBUF_UNLOCK(&so->so_snd);
   1425 	return (ENOBUFS);
   1426 }
   1427 #else /* kernel version for reference */
   1428 int
   1429 soreserve(struct socket *so, u_long sndcc, u_long rcvcc)
   1430 {
   1431 	struct thread *td = curthread;
   1432 
   1433 	SOCKBUF_LOCK(&so->so_snd);
   1434 	SOCKBUF_LOCK(&so->so_rcv);
   1435 	if (sbreserve_locked(&so->so_snd, sndcc, so, td) == 0)
   1436 		goto bad;
   1437 	if (sbreserve_locked(&so->so_rcv, rcvcc, so, td) == 0)
   1438 		goto bad2;
   1439 	if (so->so_rcv.sb_lowat == 0)
   1440 		so->so_rcv.sb_lowat = 1;
   1441 	if (so->so_snd.sb_lowat == 0)
   1442 		so->so_snd.sb_lowat = MCLBYTES;
   1443 	if (so->so_snd.sb_lowat > so->so_snd.sb_hiwat)
   1444 		so->so_snd.sb_lowat = so->so_snd.sb_hiwat;
   1445 	SOCKBUF_UNLOCK(&so->so_rcv);
   1446 	SOCKBUF_UNLOCK(&so->so_snd);
   1447 	return (0);
   1448 bad2:
   1449 	sbrelease_locked(&so->so_snd, so);
   1450 bad:
   1451 	SOCKBUF_UNLOCK(&so->so_rcv);
   1452 	SOCKBUF_UNLOCK(&so->so_snd);
   1453 	return (ENOBUFS);
   1454 }
   1455 #endif
   1456 
   1457 
   1458 
   1459 
   1460 
   1461 /* Taken from  /src/sys/kern/uipc_sockbuf.c
   1462  * and modified for __Userspace__
   1463  */
   1464 
   1465 #if defined(__Userspace__)
   1466 void
   1467 sowakeup(struct socket *so, struct sockbuf *sb)
   1468 {
   1469 
   1470 	SOCKBUF_LOCK_ASSERT(sb);
   1471 
   1472 	sb->sb_flags &= ~SB_SEL;
   1473 	if (sb->sb_flags & SB_WAIT) {
   1474 		sb->sb_flags &= ~SB_WAIT;
   1475 #if defined (__Userspace_os_Windows)
   1476 		WakeAllConditionVariable(&(sb)->sb_cond);
   1477 #else
   1478 		pthread_cond_broadcast(&(sb)->sb_cond);
   1479 #endif
   1480 	}
   1481 	SOCKBUF_UNLOCK(sb);
   1482 	/*__Userspace__ what todo about so_upcall?*/
   1483 
   1484 }
   1485 #else /* kernel version for reference */
   1486 /*
   1487  * Wakeup processes waiting on a socket buffer.  Do asynchronous notification
   1488  * via SIGIO if the socket has the SS_ASYNC flag set.
   1489  *
   1490  * Called with the socket buffer lock held; will release the lock by the end
   1491  * of the function.  This allows the caller to acquire the socket buffer lock
   1492  * while testing for the need for various sorts of wakeup and hold it through
   1493  * to the point where it's no longer required.  We currently hold the lock
   1494  * through calls out to other subsystems (with the exception of kqueue), and
   1495  * then release it to avoid lock order issues.  It's not clear that's
   1496  * correct.
   1497  */
   1498 void
   1499 sowakeup(struct socket *so, struct sockbuf *sb)
   1500 {
   1501 
   1502 	SOCKBUF_LOCK_ASSERT(sb);
   1503 
   1504 	selwakeuppri(&sb->sb_sel, PSOCK);
   1505 	sb->sb_flags &= ~SB_SEL;
   1506 	if (sb->sb_flags & SB_WAIT) {
   1507 		sb->sb_flags &= ~SB_WAIT;
   1508 		wakeup(&sb->sb_cc);
   1509 	}
   1510 	KNOTE_LOCKED(&sb->sb_sel.si_note, 0);
   1511 	SOCKBUF_UNLOCK(sb);
   1512 	if ((so->so_state & SS_ASYNC) && so->so_sigio != NULL)
   1513 		pgsigio(&so->so_sigio, SIGIO, 0);
   1514 	if (sb->sb_flags & SB_UPCALL)
   1515 		(*so->so_upcall)(so, so->so_upcallarg, M_NOWAIT);
   1516 	if (sb->sb_flags & SB_AIO)
   1517 		aio_swake(so, sb);
   1518 	mtx_assert(SOCKBUF_MTX(sb), MA_NOTOWNED);
   1519 }
   1520 #endif
   1521 
   1522 
   1523 
   1524 /* Taken from  /src/sys/kern/uipc_socket.c
   1525  * and modified for __Userspace__
   1526  */
   1527 
   1528 int
   1529 sobind(struct socket *so, struct sockaddr *nam)
   1530 {
   1531 	switch (nam->sa_family) {
   1532 #if defined(INET)
   1533 	case AF_INET:
   1534 		return (sctp_bind(so, nam));
   1535 #endif
   1536 #if defined(INET6)
   1537 	case AF_INET6:
   1538 		return (sctp6_bind(so, nam, NULL));
   1539 #endif
   1540 	case AF_CONN:
   1541 		return (sctpconn_bind(so, nam));
   1542 	default:
   1543 		return EAFNOSUPPORT;
   1544 	}
   1545 }
   1546 
   1547 /* Taken from  /src/sys/kern/uipc_syscalls.c
   1548  * and modified for __Userspace__
   1549  */
   1550 
   1551 int
   1552 usrsctp_bind(struct socket *so, struct sockaddr *name, int namelen)
   1553 {
   1554 	struct sockaddr *sa;
   1555 
   1556 	if (so == NULL) {
   1557 		errno = EBADF;
   1558 		return (-1);
   1559 	}
   1560 	if ((errno = getsockaddr(&sa, (caddr_t)name, namelen)) != 0)
   1561 		return (-1);
   1562 
   1563 	errno = sobind(so, sa);
   1564 	FREE(sa, M_SONAME);
   1565 	if (errno) {
   1566 		return (-1);
   1567 	} else {
   1568 		return (0);
   1569 	}
   1570 }
   1571 
   1572 int
   1573 userspace_bind(struct socket *so, struct sockaddr *name, int namelen)
   1574 {
   1575 	return (usrsctp_bind(so, name, namelen));
   1576 }
   1577 
   1578 /* Taken from  /src/sys/kern/uipc_socket.c
   1579  * and modified for __Userspace__
   1580  */
   1581 
   1582 int
   1583 solisten(struct socket *so, int backlog)
   1584 {
   1585 	if (so == NULL) {
   1586 		return (EBADF);
   1587 	} else {
   1588 		return (sctp_listen(so, backlog, NULL));
   1589 	}
   1590 }
   1591 
   1592 
   1593 int
   1594 solisten_proto_check(struct socket *so)
   1595 {
   1596 
   1597 	SOCK_LOCK_ASSERT(so);
   1598 
   1599 	if (so->so_state & (SS_ISCONNECTED | SS_ISCONNECTING |
   1600 	    SS_ISDISCONNECTING))
   1601 		return (EINVAL);
   1602 	return (0);
   1603 }
   1604 
   1605 static int somaxconn = SOMAXCONN;
   1606 
   1607 void
   1608 solisten_proto(struct socket *so, int backlog)
   1609 {
   1610 
   1611 	SOCK_LOCK_ASSERT(so);
   1612 
   1613 	if (backlog < 0 || backlog > somaxconn)
   1614 		backlog = somaxconn;
   1615 	so->so_qlimit = backlog;
   1616 	so->so_options |= SCTP_SO_ACCEPTCONN;
   1617 }
   1618 
   1619 
   1620 
   1621 
   1622 /* Taken from  /src/sys/kern/uipc_syscalls.c
   1623  * and modified for __Userspace__
   1624  */
   1625 
   1626 int
   1627 usrsctp_listen(struct socket *so, int backlog)
   1628 {
   1629 	errno = solisten(so, backlog);
   1630 	if (errno) {
   1631 		return (-1);
   1632 	} else {
   1633 		return (0);
   1634 	}
   1635 }
   1636 
   1637 int
   1638 userspace_listen(struct socket *so, int backlog)
   1639 {
   1640 	return (usrsctp_listen(so, backlog));
   1641 }
   1642 
   1643 /* Taken from  /src/sys/kern/uipc_socket.c
   1644  * and modified for __Userspace__
   1645  */
   1646 
   1647 int
   1648 soaccept(struct socket *so, struct sockaddr **nam)
   1649 {
   1650 	int error;
   1651 
   1652 	SOCK_LOCK(so);
   1653 	KASSERT((so->so_state & SS_NOFDREF) != 0, ("soaccept: !NOFDREF"));
   1654 	so->so_state &= ~SS_NOFDREF;
   1655 	SOCK_UNLOCK(so);
   1656 	error = sctp_accept(so, nam);
   1657 	return (error);
   1658 }
   1659 
   1660 
   1661 
   1662 /* Taken from  /src/sys/kern/uipc_syscalls.c
   1663  * kern_accept modified for __Userspace__
   1664  */
   1665 int
   1666 user_accept(struct socket *head,  struct sockaddr **name, socklen_t *namelen, struct socket **ptr_accept_ret_sock)
   1667 {
   1668 	struct sockaddr *sa = NULL;
   1669 	int error;
   1670 	struct socket *so = NULL;
   1671 
   1672 
   1673 	if (name) {
   1674 		*name = NULL;
   1675 	}
   1676 
   1677 	if ((head->so_options & SCTP_SO_ACCEPTCONN) == 0) {
   1678 		error = EINVAL;
   1679 		goto done;
   1680 	}
   1681 
   1682 	ACCEPT_LOCK();
   1683 	if ((head->so_state & SS_NBIO) && TAILQ_EMPTY(&head->so_comp)) {
   1684 		ACCEPT_UNLOCK();
   1685 		error = EWOULDBLOCK;
   1686 		goto noconnection;
   1687 	}
   1688 	while (TAILQ_EMPTY(&head->so_comp) && head->so_error == 0) {
   1689 		if (head->so_rcv.sb_state & SBS_CANTRCVMORE) {
   1690 			head->so_error = ECONNABORTED;
   1691 			break;
   1692 		}
   1693 #if defined (__Userspace_os_Windows)
   1694 		if (SleepConditionVariableCS(&accept_cond, &accept_mtx, INFINITE))
   1695 			error = 0;
   1696 		else
   1697 			error = GetLastError();
   1698 #else
   1699 		error = pthread_cond_wait(&accept_cond, &accept_mtx);
   1700 #endif
   1701 		if (error) {
   1702 			ACCEPT_UNLOCK();
   1703 			goto noconnection;
   1704 		}
   1705 	}
   1706 	if (head->so_error) {
   1707 		error = head->so_error;
   1708 		head->so_error = 0;
   1709 		ACCEPT_UNLOCK();
   1710 		goto noconnection;
   1711 	}
   1712 	so = TAILQ_FIRST(&head->so_comp);
   1713 	KASSERT(!(so->so_qstate & SQ_INCOMP), ("accept1: so SQ_INCOMP"));
   1714 	KASSERT(so->so_qstate & SQ_COMP, ("accept1: so not SQ_COMP"));
   1715 
   1716 	/*
   1717 	 * Before changing the flags on the socket, we have to bump the
   1718 	 * reference count.  Otherwise, if the protocol calls sofree(),
   1719 	 * the socket will be released due to a zero refcount.
   1720 	 */
   1721 	SOCK_LOCK(so);			/* soref() and so_state update */
   1722 	soref(so);			/* file descriptor reference */
   1723 
   1724 	TAILQ_REMOVE(&head->so_comp, so, so_list);
   1725 	head->so_qlen--;
   1726 	so->so_state |= (head->so_state & SS_NBIO);
   1727 	so->so_qstate &= ~SQ_COMP;
   1728 	so->so_head = NULL;
   1729 	SOCK_UNLOCK(so);
   1730 	ACCEPT_UNLOCK();
   1731 
   1732 
   1733 	/*
   1734 	 * The original accept returns fd value via td->td_retval[0] = fd;
   1735 	 * we will return the socket for accepted connection.
   1736 	 */
   1737 
   1738 	error = soaccept(so, &sa);
   1739 	if (error) {
   1740 		/*
   1741 		 * return a namelen of zero for older code which might
   1742 		 * ignore the return value from accept.
   1743 		 */
   1744 		if (name)
   1745 			*namelen = 0;
   1746 		goto noconnection;
   1747 	}
   1748 	if (sa == NULL) {
   1749 		if (name)
   1750 			*namelen = 0;
   1751 		goto done;
   1752 	}
   1753 	if (name) {
   1754 #ifdef HAVE_SA_LEN
   1755 		/* check sa_len before it is destroyed */
   1756 		if (*namelen > sa->sa_len) {
   1757 			*namelen = sa->sa_len;
   1758 		}
   1759 #else
   1760 		socklen_t sa_len;
   1761 
   1762 		switch (sa->sa_family) {
   1763 #ifdef INET
   1764 		case AF_INET:
   1765 			sa_len = sizeof(struct sockaddr_in);
   1766 			break;
   1767 #endif
   1768 #ifdef INET6
   1769 		case AF_INET6:
   1770 			sa_len = sizeof(struct sockaddr_in6);
   1771 			break;
   1772 #endif
   1773 		case AF_CONN:
   1774 			sa_len = sizeof(struct sockaddr_conn);
   1775 			break;
   1776 		default:
   1777 			sa_len = 0;
   1778 			break;
   1779 		}
   1780 		if (*namelen > sa_len) {
   1781 			*namelen = sa_len;
   1782 		}
   1783 #endif
   1784 		*name = sa;
   1785 		sa = NULL;
   1786 	}
   1787 noconnection:
   1788 	if (sa) {
   1789 		FREE(sa, M_SONAME);
   1790 	}
   1791 
   1792 done:
   1793 	*ptr_accept_ret_sock = so;
   1794 	return (error);
   1795 }
   1796 
   1797 
   1798 
   1799 /* Taken from  /src/sys/kern/uipc_syscalls.c
   1800  * and modified for __Userspace__
   1801  */
   1802 /*
   1803  * accept1()
   1804  */
   1805 static int
   1806 accept1(struct socket *so, struct sockaddr *aname, socklen_t *anamelen, struct socket **ptr_accept_ret_sock)
   1807 {
   1808 	struct sockaddr *name;
   1809 	socklen_t namelen;
   1810 	int error;
   1811 
   1812 	if (so == NULL) {
   1813 		return (EBADF);
   1814 	}
   1815 	if (aname == NULL) {
   1816 		return (user_accept(so, NULL, NULL, ptr_accept_ret_sock));
   1817 	}
   1818 
   1819 	error = copyin(anamelen, &namelen, sizeof (namelen));
   1820 	if (error)
   1821 		return (error);
   1822 
   1823 	error = user_accept(so, &name, &namelen, ptr_accept_ret_sock);
   1824 
   1825 	/*
   1826 	 * return a namelen of zero for older code which might
   1827 	 * ignore the return value from accept.
   1828 	 */
   1829 	if (error) {
   1830 		(void) copyout(&namelen,
   1831 		    anamelen, sizeof(*anamelen));
   1832 		return (error);
   1833 	}
   1834 
   1835 	if (error == 0 && name != NULL) {
   1836 		error = copyout(name, aname, namelen);
   1837 	}
   1838 	if (error == 0) {
   1839 		error = copyout(&namelen, anamelen, sizeof(namelen));
   1840 	}
   1841 
   1842 	if (name) {
   1843 		FREE(name, M_SONAME);
   1844 	}
   1845 	return (error);
   1846 }
   1847 
   1848 struct socket *
   1849 usrsctp_accept(struct socket *so, struct sockaddr *aname, socklen_t *anamelen)
   1850 {
   1851 	struct socket *accept_return_sock;
   1852 
   1853 	errno = accept1(so, aname, anamelen, &accept_return_sock);
   1854 	if (errno) {
   1855 		return (NULL);
   1856 	} else {
   1857 		return (accept_return_sock);
   1858 	}
   1859 }
   1860 
   1861 struct socket *
   1862 userspace_accept(struct socket *so, struct sockaddr *aname, socklen_t *anamelen)
   1863 {
   1864 	return (usrsctp_accept(so, aname, anamelen));
   1865 }
   1866 
   1867 struct socket *
   1868 usrsctp_peeloff(struct socket *head, sctp_assoc_t id)
   1869 {
   1870 	struct socket *so;
   1871 
   1872 	if ((errno = sctp_can_peel_off(head, id)) != 0) {
   1873 		return (NULL);
   1874 	}
   1875 	if ((so = sonewconn(head, SS_ISCONNECTED)) == NULL) {
   1876 		return (NULL);
   1877 	}
   1878 	ACCEPT_LOCK();
   1879 	SOCK_LOCK(so);
   1880 	soref(so);
   1881 	TAILQ_REMOVE(&head->so_comp, so, so_list);
   1882 	head->so_qlen--;
   1883 	so->so_state |= (head->so_state & SS_NBIO);
   1884 	so->so_qstate &= ~SQ_COMP;
   1885 	so->so_head = NULL;
   1886 	SOCK_UNLOCK(so);
   1887 	ACCEPT_UNLOCK();
   1888 	if ((errno = sctp_do_peeloff(head, so, id)) != 0) {
   1889 		so->so_count = 0;
   1890 		sodealloc(so);
   1891 		return (NULL);
   1892 	}
   1893 	return (so);
   1894 }
   1895 
   1896 int
   1897 sodisconnect(struct socket *so)
   1898 {
   1899 	int error;
   1900 
   1901 	if ((so->so_state & SS_ISCONNECTED) == 0)
   1902 		return (ENOTCONN);
   1903 	if (so->so_state & SS_ISDISCONNECTING)
   1904 		return (EALREADY);
   1905 	error = sctp_disconnect(so);
   1906 	return (error);
   1907 }
   1908 
   1909 int
   1910 usrsctp_set_non_blocking(struct socket *so, int onoff)
   1911 {
   1912 	if (so == NULL) {
   1913 		errno = EBADF;
   1914 		return (-1);
   1915 	}
   1916 	SOCK_LOCK(so);
   1917 	if (onoff != 0) {
   1918 		so->so_state |= SS_NBIO;
   1919 	} else {
   1920 		so->so_state &= ~SS_NBIO;
   1921 	}
   1922 	SOCK_UNLOCK(so);
   1923 	return (0);
   1924 }
   1925 
   1926 int
   1927 usrsctp_get_non_blocking(struct socket *so)
   1928 {
   1929 	int result;
   1930 
   1931 	if (so == NULL) {
   1932 		errno = EBADF;
   1933 		return (-1);
   1934 	}
   1935 	SOCK_LOCK(so);
   1936 	if (so->so_state | SS_NBIO) {
   1937 		result = 1;
   1938 	} else {
   1939 		result = 0;
   1940 	}
   1941 	SOCK_UNLOCK(so);
   1942 	return (result);
   1943 }
   1944 
   1945 int
   1946 soconnect(struct socket *so, struct sockaddr *nam)
   1947 {
   1948 	int error;
   1949 
   1950 	if (so->so_options & SCTP_SO_ACCEPTCONN)
   1951 		return (EOPNOTSUPP);
   1952 	/*
   1953 	 * If protocol is connection-based, can only connect once.
   1954 	 * Otherwise, if connected, try to disconnect first.  This allows
   1955 	 * user to disconnect by connecting to, e.g., a null address.
   1956 	 */
   1957 	if (so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING) && (error = sodisconnect(so))) {
   1958 		error = EISCONN;
   1959 	} else {
   1960 		/*
   1961 		 * Prevent accumulated error from previous connection from
   1962 		 * biting us.
   1963 		 */
   1964 		so->so_error = 0;
   1965 		switch (nam->sa_family) {
   1966 #if defined(INET)
   1967 		case AF_INET:
   1968 			error = sctp_connect(so, nam);
   1969 			break;
   1970 #endif
   1971 #if defined(INET6)
   1972 		case AF_INET6:
   1973 			error = sctp6_connect(so, nam);
   1974 			break;
   1975 #endif
   1976 		case AF_CONN:
   1977 			error = sctpconn_connect(so, nam);
   1978 			break;
   1979 		default:
   1980 			error = EAFNOSUPPORT;
   1981 		}
   1982 	}
   1983 
   1984 	return (error);
   1985 }
   1986 
   1987 
   1988 
   1989 int user_connect(struct socket *so, struct sockaddr *sa)
   1990 {
   1991 	int error;
   1992 	int interrupted = 0;
   1993 
   1994 	if (so == NULL) {
   1995 		error = EBADF;
   1996 		goto done1;
   1997 	}
   1998 	if (so->so_state & SS_ISCONNECTING) {
   1999 		error = EALREADY;
   2000 		goto done1;
   2001 	}
   2002 
   2003 	error = soconnect(so, sa);
   2004 	if (error) {
   2005 		goto bad;
   2006 	}
   2007 	if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
   2008 		error = EINPROGRESS;
   2009 		goto done1;
   2010 	}
   2011 
   2012 	SOCK_LOCK(so);
   2013 	while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
   2014 #if defined (__Userspace_os_Windows)
   2015 		if (SleepConditionVariableCS(SOCK_COND(so), SOCK_MTX(so), INFINITE))
   2016 			error = 0;
   2017 		else
   2018 			error = -1;
   2019 #else
   2020 		error = pthread_cond_wait(SOCK_COND(so), SOCK_MTX(so));
   2021 #endif
   2022 		if (error) {
   2023 #if defined(__Userspace_os_NetBSD)
   2024 			if (error == EINTR) {
   2025 #else
   2026 			if (error == EINTR || error == ERESTART) {
   2027 #endif
   2028 				interrupted = 1;
   2029 			}
   2030 			break;
   2031 		}
   2032 	}
   2033 	if (error == 0) {
   2034 		error = so->so_error;
   2035 		so->so_error = 0;
   2036 	}
   2037 	SOCK_UNLOCK(so);
   2038 
   2039 bad:
   2040 	if (!interrupted) {
   2041 		so->so_state &= ~SS_ISCONNECTING;
   2042 	}
   2043 #if !defined(__Userspace_os_NetBSD)
   2044 	if (error == ERESTART) {
   2045 		error = EINTR;
   2046 	}
   2047 #endif
   2048 done1:
   2049 	return (error);
   2050 }
   2051 
   2052 int usrsctp_connect(struct socket *so, struct sockaddr *name, int namelen)
   2053 {
   2054 	struct sockaddr *sa;
   2055 
   2056 	errno = getsockaddr(&sa, (caddr_t)name, namelen);
   2057 	if (errno)
   2058 		return (-1);
   2059 
   2060 	errno = user_connect(so, sa);
   2061 	FREE(sa, M_SONAME);
   2062 	if (errno) {
   2063 		return (-1);
   2064 	} else {
   2065 		return (0);
   2066 	}
   2067 }
   2068 
   2069 int userspace_connect(struct socket *so, struct sockaddr *name, int namelen)
   2070 {
   2071 	return (usrsctp_connect(so, name, namelen));
   2072 }
   2073 
   2074 #define SCTP_STACK_BUF_SIZE         2048
   2075 
   2076 void
   2077 usrsctp_close(struct socket *so) {
   2078 	if (so != NULL) {
   2079 		if (so->so_options & SCTP_SO_ACCEPTCONN) {
   2080 			struct socket *sp;
   2081 
   2082 			ACCEPT_LOCK();
   2083 			while ((sp = TAILQ_FIRST(&so->so_comp)) != NULL) {
   2084 				TAILQ_REMOVE(&so->so_comp, sp, so_list);
   2085 				so->so_qlen--;
   2086 				sp->so_qstate &= ~SQ_COMP;
   2087 				sp->so_head = NULL;
   2088 				ACCEPT_UNLOCK();
   2089 				soabort(sp);
   2090 				ACCEPT_LOCK();
   2091 			}
   2092 			ACCEPT_UNLOCK();
   2093 		}
   2094 		ACCEPT_LOCK();
   2095 		SOCK_LOCK(so);
   2096 		sorele(so);
   2097 	}
   2098 }
   2099 
   2100 void
   2101 userspace_close(struct socket *so)
   2102 {
   2103 	usrsctp_close(so);
   2104 }
   2105 
   2106 int
   2107 usrsctp_shutdown(struct socket *so, int how)
   2108 {
   2109 	if (!(how == SHUT_RD || how == SHUT_WR || how == SHUT_RDWR)) {
   2110 		errno = EINVAL;
   2111 		return (-1);
   2112 	}
   2113 	if (so == NULL) {
   2114 		errno = EBADF;
   2115 		return (-1);
   2116 	}
   2117 	sctp_flush(so, how);
   2118 	if (how != SHUT_WR)
   2119 		 socantrcvmore(so);
   2120 	if (how != SHUT_RD) {
   2121 		errno = sctp_shutdown(so);
   2122 		if (errno) {
   2123 			return (-1);
   2124 		} else {
   2125 			return (0);
   2126 		}
   2127 	}
   2128 	return (0);
   2129 }
   2130 
   2131 int
   2132 userspace_shutdown(struct socket *so, int how)
   2133 {
   2134 	return (usrsctp_shutdown(so, how));
   2135 }
   2136 
   2137 int
   2138 usrsctp_finish(void)
   2139 {
   2140 	if (SCTP_BASE_VAR(sctp_pcb_initialized) == 0) {
   2141 		return (0);
   2142 	}
   2143 	if (SCTP_INP_INFO_TRYLOCK()) {
   2144 		if (!LIST_EMPTY(&SCTP_BASE_INFO(listhead))) {
   2145 			SCTP_INP_INFO_RUNLOCK();
   2146 			return (-1);
   2147 		}
   2148 		SCTP_INP_INFO_RUNLOCK();
   2149 	} else {
   2150 		return (-1);
   2151 	}
   2152 	sctp_finish();
   2153 	return (0);
   2154 }
   2155 
   2156 int
   2157 userspace_finish(void)
   2158 {
   2159 	return (usrsctp_finish());
   2160 }
   2161 
   2162 /* needed from sctp_usrreq.c */
   2163 int
   2164 sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize, void *p);
   2165 
   2166 int
   2167 usrsctp_setsockopt(struct socket *so, int level, int option_name,
   2168                    const void *option_value, socklen_t option_len)
   2169 {
   2170 	if (so == NULL) {
   2171 		errno = EBADF;
   2172 		return (-1);
   2173 	}
   2174 	switch (level) {
   2175 	case SOL_SOCKET:
   2176 	{
   2177 		switch (option_name) {
   2178 		case SO_RCVBUF:
   2179 			if (option_len < (socklen_t)sizeof(int)) {
   2180 				errno = EINVAL;
   2181 				return (-1);
   2182 			} else {
   2183 				int *buf_size;
   2184 
   2185 				buf_size = (int *)option_value;
   2186 				if (*buf_size < 1) {
   2187 					errno = EINVAL;
   2188 					return (-1);
   2189 				}
   2190 				sbreserve(&so->so_rcv, (u_long)*buf_size, so);
   2191 				return (0);
   2192 			}
   2193 			break;
   2194 		case SO_SNDBUF:
   2195 			if (option_len < (socklen_t)sizeof(int)) {
   2196 				errno = EINVAL;
   2197 				return (-1);
   2198 			} else {
   2199 				int *buf_size;
   2200 
   2201 				buf_size = (int *)option_value;
   2202 				if (*buf_size < 1) {
   2203 					errno = EINVAL;
   2204 					return (-1);
   2205 				}
   2206 				sbreserve(&so->so_snd, (u_long)*buf_size, so);
   2207 				return (0);
   2208 			}
   2209 			break;
   2210 		case SO_LINGER:
   2211 			if (option_len < (socklen_t)sizeof(struct linger)) {
   2212 				errno = EINVAL;
   2213 				return (-1);
   2214 			} else {
   2215 				struct linger *l;
   2216 
   2217 				l = (struct linger *)option_value;
   2218 				so->so_linger = l->l_linger;
   2219 				if (l->l_onoff) {
   2220 					so->so_options |= SCTP_SO_LINGER;
   2221 				} else {
   2222 					so->so_options &= ~SCTP_SO_LINGER;
   2223 				}
   2224 				return (0);
   2225 			}
   2226 		default:
   2227 			errno = EINVAL;
   2228 			return (-1);
   2229 		}
   2230 	}
   2231 	case IPPROTO_SCTP:
   2232 		errno = sctp_setopt(so, option_name, (void *) option_value, (size_t)option_len, NULL);
   2233 		if (errno) {
   2234 			return (-1);
   2235 		} else {
   2236 			return (0);
   2237 		}
   2238 	default:
   2239 		errno = ENOPROTOOPT;
   2240 		return (-1);
   2241 	}
   2242 }
   2243 
   2244 int
   2245 userspace_setsockopt(struct socket *so, int level, int option_name,
   2246                      const void *option_value, socklen_t option_len)
   2247 {
   2248 	return (usrsctp_setsockopt(so, level, option_name, option_value, option_len));
   2249 }
   2250 
   2251 /* needed from sctp_usrreq.c */
   2252 int
   2253 sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
   2254 	    void *p);
   2255 
   2256 int
   2257 usrsctp_getsockopt(struct socket *so, int level, int option_name,
   2258                    void *option_value, socklen_t *option_len)
   2259 {
   2260 	if (so == NULL) {
   2261 		errno = EBADF;
   2262 		return (-1);
   2263 	}
   2264 	if (option_len == NULL) {
   2265 		errno = EFAULT;
   2266 		return (-1);
   2267 	}
   2268 	switch (level) {
   2269 	case SOL_SOCKET:
   2270 		switch (option_name) {
   2271 		case SO_RCVBUF:
   2272 			if (*option_len < (socklen_t)sizeof(int)) {
   2273 				errno = EINVAL;
   2274 				return (-1);
   2275 			} else {
   2276 				int *buf_size;
   2277 
   2278 				buf_size = (int *)option_value;
   2279 				*buf_size = so->so_rcv.sb_hiwat;;
   2280 				*option_len = (socklen_t)sizeof(int);
   2281 				return (0);
   2282 			}
   2283 			break;
   2284 		case SO_SNDBUF:
   2285 			if (*option_len < (socklen_t)sizeof(int)) {
   2286 				errno = EINVAL;
   2287 				return (-1);
   2288 			} else {
   2289 				int *buf_size;
   2290 
   2291 				buf_size = (int *)option_value;
   2292 				*buf_size = so->so_snd.sb_hiwat;
   2293 				*option_len = (socklen_t)sizeof(int);
   2294 				return (0);
   2295 			}
   2296 			break;
   2297 		case SO_LINGER:
   2298 			if (*option_len < (socklen_t)sizeof(struct linger)) {
   2299 				errno = EINVAL;
   2300 				return (-1);
   2301 			} else {
   2302 				struct linger *l;
   2303 
   2304 				l = (struct linger *)option_value;
   2305 				l->l_linger = so->so_linger;
   2306 				if (so->so_options & SCTP_SO_LINGER) {
   2307 					l->l_onoff = 1;
   2308 				} else {
   2309 					l->l_onoff = 0;
   2310 				}
   2311 				*option_len = (socklen_t)sizeof(struct linger);
   2312 				return (0);
   2313 			}
   2314 		default:
   2315 			errno = EINVAL;
   2316 			return (-1);
   2317 		}
   2318 	case IPPROTO_SCTP:
   2319 	{
   2320 		size_t len;
   2321 
   2322 		len = (size_t)*option_len;
   2323 		errno = sctp_getopt(so, option_name, option_value, &len, NULL);
   2324 		*option_len = (socklen_t)len;
   2325 		if (errno) {
   2326 			return (-1);
   2327 		} else {
   2328 			return (0);
   2329 		}
   2330 	}
   2331 	default:
   2332 		errno = ENOPROTOOPT;
   2333 		return (-1);
   2334 	}
   2335 }
   2336 
   2337 int
   2338 userspace_getsockopt(struct socket *so, int level, int option_name,
   2339                      void *option_value, socklen_t *option_len)
   2340 {
   2341 	return (usrsctp_getsockopt(so, level, option_name, option_value, option_len));
   2342 }
   2343 
   2344 int
   2345 usrsctp_bindx(struct socket *so, struct sockaddr *addrs, int addrcnt, int flags)
   2346 {
   2347 	struct sctp_getaddresses *gaddrs;
   2348 	struct sockaddr *sa;
   2349 #ifdef INET
   2350 	struct sockaddr_in *sin;
   2351 #endif
   2352 #ifdef INET6
   2353 	struct sockaddr_in6 *sin6;
   2354 #endif
   2355 	int i;
   2356 	size_t argsz;
   2357 #if defined(INET) || defined(INET6)
   2358 	uint16_t sport = 0;
   2359 #endif
   2360 
   2361 	/* validate the flags */
   2362 	if ((flags != SCTP_BINDX_ADD_ADDR) &&
   2363 	    (flags != SCTP_BINDX_REM_ADDR)) {
   2364 		errno = EFAULT;
   2365 		return (-1);
   2366 	}
   2367 	/* validate the address count and list */
   2368 	if ((addrcnt <= 0) || (addrs == NULL)) {
   2369 		errno = EINVAL;
   2370 		return (-1);
   2371 	}
   2372 	/* First pre-screen the addresses */
   2373 	sa = addrs;
   2374 	for (i = 0; i < addrcnt; i++) {
   2375 		switch (sa->sa_family) {
   2376 #ifdef INET
   2377 		case AF_INET:
   2378 #ifdef HAVE_SA_LEN
   2379 			if (sa->sa_len != sizeof(struct sockaddr_in)) {
   2380 				errno = EINVAL;
   2381 				return (-1);
   2382 			}
   2383 #endif
   2384 			sin = (struct sockaddr_in *)sa;
   2385 			if (sin->sin_port) {
   2386 				/* non-zero port, check or save */
   2387 				if (sport) {
   2388 					/* Check against our port */
   2389 					if (sport != sin->sin_port) {
   2390 						errno = EINVAL;
   2391 						return (-1);
   2392 					}
   2393 				} else {
   2394 					/* save off the port */
   2395 					sport = sin->sin_port;
   2396 				}
   2397 			}
   2398 #ifndef HAVE_SA_LEN
   2399 			sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in));
   2400 #endif
   2401 			break;
   2402 #endif
   2403 #ifdef INET6
   2404 		case AF_INET6:
   2405 #ifdef HAVE_SA_LEN
   2406 			if (sa->sa_len != sizeof(struct sockaddr_in6)) {
   2407 				errno = EINVAL;
   2408 				return (-1);
   2409 			}
   2410 #endif
   2411 			sin6 = (struct sockaddr_in6 *)sa;
   2412 			if (sin6->sin6_port) {
   2413 				/* non-zero port, check or save */
   2414 				if (sport) {
   2415 					/* Check against our port */
   2416 					if (sport != sin6->sin6_port) {
   2417 						errno = EINVAL;
   2418 						return (-1);
   2419 					}
   2420 				} else {
   2421 					/* save off the port */
   2422 					sport = sin6->sin6_port;
   2423 				}
   2424 			}
   2425 #ifndef HAVE_SA_LEN
   2426 			sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in6));
   2427 #endif
   2428 			break;
   2429 #endif
   2430 		default:
   2431 			/* Invalid address family specified. */
   2432 			errno = EAFNOSUPPORT;
   2433 			return (-1);
   2434 		}
   2435 #ifdef HAVE_SA_LEN
   2436 		sa = (struct sockaddr *)((caddr_t)sa + sa->sa_len);
   2437 #endif
   2438 	}
   2439 	argsz = sizeof(struct sctp_getaddresses) +
   2440 	        sizeof(struct sockaddr_storage);
   2441 	if ((gaddrs = (struct sctp_getaddresses *)malloc(argsz)) == NULL) {
   2442 		errno = ENOMEM;
   2443 		return (-1);
   2444 	}
   2445 	sa = addrs;
   2446 	for (i = 0; i < addrcnt; i++) {
   2447 #ifndef HAVE_SA_LEN
   2448 		size_t sa_len;
   2449 #endif
   2450 		memset(gaddrs, 0, argsz);
   2451 		gaddrs->sget_assoc_id = 0;
   2452 #ifdef HAVE_SA_LEN
   2453 		memcpy(gaddrs->addr, sa, sa->sa_len);
   2454 		if (usrsctp_setsockopt(so, IPPROTO_SCTP, flags, gaddrs, (socklen_t)argsz) != 0) {
   2455 			free(gaddrs);
   2456 			return (-1);
   2457 		}
   2458 		sa = (struct sockaddr *)((caddr_t)sa + sa->sa_len);
   2459 #else
   2460 		switch (sa->sa_family) {
   2461 #ifdef INET
   2462 		case AF_INET:
   2463 			sa_len = sizeof(struct sockaddr_in);
   2464 			break;
   2465 #endif
   2466 #ifdef INET6
   2467 		case AF_INET6:
   2468 			sa_len = sizeof(struct sockaddr_in6);
   2469 			break;
   2470 #endif
   2471 		default:
   2472 			sa_len = 0;
   2473 			break;
   2474 		}
   2475 		memcpy(gaddrs->addr, sa, sa_len);
   2476 		/*
   2477 		 * Now, if there was a port mentioned, assure that the
   2478 		 * first address has that port to make sure it fails or
   2479 		 * succeeds correctly.
   2480 		 */
   2481 #if defined(INET) || defined(INET6)
   2482 		if ((i == 0) && (sport != 0)) {
   2483 			switch (gaddrs->addr->sa_family) {
   2484 #ifdef INET
   2485 			case AF_INET:
   2486 				sin = (struct sockaddr_in *)gaddrs->addr;
   2487 				sin->sin_port = sport;
   2488 				break;
   2489 #endif
   2490 #ifdef INET6
   2491 			case AF_INET6:
   2492 				sin6 = (struct sockaddr_in6 *)gaddrs->addr;
   2493 				sin6->sin6_port = sport;
   2494 				break;
   2495 #endif
   2496 			}
   2497 		}
   2498 #endif
   2499 		if (usrsctp_setsockopt(so, IPPROTO_SCTP, flags, gaddrs, (socklen_t)argsz) != 0) {
   2500 			free(gaddrs);
   2501 			return (-1);
   2502 		}
   2503 		sa = (struct sockaddr *)((caddr_t)sa + sa_len);
   2504 #endif
   2505 	}
   2506 	free(gaddrs);
   2507 	return (0);
   2508 }
   2509 
   2510 int
   2511 usrsctp_connectx(struct socket *so,
   2512                  const struct sockaddr *addrs, int addrcnt,
   2513                  sctp_assoc_t *id)
   2514 {
   2515 #if defined(INET) || defined(INET6)
   2516 	char buf[SCTP_STACK_BUF_SIZE];
   2517 	int i, ret, cnt, *aa;
   2518 	char *cpto;
   2519 	const struct sockaddr *at;
   2520 	sctp_assoc_t *p_id;
   2521 	size_t len = sizeof(int);
   2522 
   2523 	/* validate the address count and list */
   2524 	if ((addrs == NULL) || (addrcnt <= 0)) {
   2525 		errno = EINVAL;
   2526 		return (-1);
   2527 	}
   2528 	at = addrs;
   2529 	cnt = 0;
   2530 	cpto = ((caddr_t)buf + sizeof(int));
   2531 	/* validate all the addresses and get the size */
   2532 	for (i = 0; i < addrcnt; i++) {
   2533 		switch (at->sa_family) {
   2534 #ifdef INET
   2535 		case AF_INET:
   2536 #ifdef HAVE_SA_LEN
   2537 			if (at->sa_len != sizeof(struct sockaddr_in)) {
   2538 				errno = EINVAL;
   2539 				return (-1);
   2540 			}
   2541 #endif
   2542 			memcpy(cpto, at, sizeof(struct sockaddr_in));
   2543 			cpto = ((caddr_t)cpto + sizeof(struct sockaddr_in));
   2544 			len += sizeof(struct sockaddr_in);
   2545 			at = (struct sockaddr *)((caddr_t)at + sizeof(struct sockaddr_in));
   2546 			break;
   2547 #endif
   2548 #ifdef INET6
   2549 		case AF_INET6:
   2550 #ifdef HAVE_SA_LEN
   2551 			if (at->sa_len != sizeof(struct sockaddr_in6)) {
   2552 				errno = EINVAL;
   2553 				return (-1);
   2554 			}
   2555 #endif
   2556 			if (IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)at)->sin6_addr)) {
   2557 				in6_sin6_2_sin((struct sockaddr_in *)cpto, (struct sockaddr_in6 *)at);
   2558 				cpto = ((caddr_t)cpto + sizeof(struct sockaddr_in));
   2559 				len += sizeof(struct sockaddr_in);
   2560 			} else {
   2561 				memcpy(cpto, at, sizeof(struct sockaddr_in6));
   2562 				cpto = ((caddr_t)cpto + sizeof(struct sockaddr_in6));
   2563 				len += sizeof(struct sockaddr_in6);
   2564 			}
   2565 			at = (struct sockaddr *)((caddr_t)at + sizeof(struct sockaddr_in6));
   2566 			break;
   2567 #endif
   2568 		default:
   2569 			errno = EINVAL;
   2570 			return (-1);
   2571 		}
   2572 		if (len > (sizeof(buf) - sizeof(int))) {
   2573 			/* Never enough memory */
   2574 			errno = E2BIG;
   2575 			return (-1);
   2576 		}
   2577 		cnt++;
   2578 	}
   2579 	/* do we have any? */
   2580 	if (cnt == 0) {
   2581 		errno = EINVAL;
   2582 		return (-1);
   2583 	}
   2584 	aa = (int *)buf;
   2585 	*aa = cnt;
   2586 	ret = usrsctp_setsockopt(so, IPPROTO_SCTP, SCTP_CONNECT_X, (void *)buf, (socklen_t)len);
   2587 	if ((ret == 0) && id) {
   2588 		p_id = (sctp_assoc_t *)buf;
   2589 		*id = *p_id;
   2590 	}
   2591 	return (ret);
   2592 #else
   2593 	errno = EINVAL;
   2594 	return (-1);
   2595 #endif
   2596 }
   2597 
   2598 int
   2599 usrsctp_getpaddrs(struct socket *so, sctp_assoc_t id, struct sockaddr **raddrs)
   2600 {
   2601 	struct sctp_getaddresses *addrs;
   2602 	struct sockaddr *sa;
   2603 	sctp_assoc_t asoc;
   2604 	caddr_t lim;
   2605 	socklen_t opt_len;
   2606 	int cnt;
   2607 
   2608 	if (raddrs == NULL) {
   2609 		errno = EFAULT;
   2610 		return (-1);
   2611 	}
   2612 	asoc = id;
   2613 	opt_len = (socklen_t)sizeof(sctp_assoc_t);
   2614 	if (usrsctp_getsockopt(so, IPPROTO_SCTP, SCTP_GET_REMOTE_ADDR_SIZE, &asoc, &opt_len) != 0) {
   2615 		return (-1);
   2616 	}
   2617 	/* size required is returned in 'asoc' */
   2618 	opt_len = (socklen_t)((size_t)asoc + sizeof(struct sctp_getaddresses));
   2619 	addrs = calloc(1, (size_t)opt_len);
   2620 	if (addrs == NULL) {
   2621 		errno = ENOMEM;
   2622 		return (-1);
   2623 	}
   2624 	addrs->sget_assoc_id = id;
   2625 	/* Now lets get the array of addresses */
   2626 	if (usrsctp_getsockopt(so, IPPROTO_SCTP, SCTP_GET_PEER_ADDRESSES, addrs, &opt_len) != 0) {
   2627 		free(addrs);
   2628 		return (-1);
   2629 	}
   2630 	*raddrs = (struct sockaddr *)&addrs->addr[0];
   2631 	cnt = 0;
   2632 	sa = (struct sockaddr *)&addrs->addr[0];
   2633 	lim = (caddr_t)addrs + opt_len;
   2634 #ifdef HAVE_SA_LEN
   2635 	while (((caddr_t)sa < lim) && (sa->sa_len > 0)) {
   2636 		sa = (struct sockaddr *)((caddr_t)sa + sa->sa_len);
   2637 #else
   2638 	while ((caddr_t)sa < lim) {
   2639 		switch (sa->sa_family) {
   2640 #ifdef INET
   2641 		case AF_INET:
   2642 			sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in));
   2643 			break;
   2644 #endif
   2645 #ifdef INET6
   2646 		case AF_INET6:
   2647 			sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in6));
   2648 			break;
   2649 #endif
   2650 		case AF_CONN:
   2651 			sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_conn));
   2652 			break;
   2653 		default:
   2654 			return (cnt);
   2655 			break;
   2656 		}
   2657 #endif
   2658 		cnt++;
   2659 	}
   2660 	return (cnt);
   2661 }
   2662 
   2663 void
   2664 usrsctp_freepaddrs(struct sockaddr *addrs)
   2665 {
   2666 	/* Take away the hidden association id */
   2667 	void *fr_addr;
   2668 
   2669 	fr_addr = (void *)((caddr_t)addrs - sizeof(sctp_assoc_t));
   2670 	/* Now free it */
   2671 	free(fr_addr);
   2672 }
   2673 
   2674 int
   2675 usrsctp_getladdrs(struct socket *so, sctp_assoc_t id, struct sockaddr **raddrs)
   2676 {
   2677 	struct sctp_getaddresses *addrs;
   2678 	caddr_t lim;
   2679 	struct sockaddr *sa;
   2680 	size_t size_of_addresses;
   2681 	socklen_t opt_len;
   2682 	int cnt;
   2683 
   2684 	if (raddrs == NULL) {
   2685 		errno = EFAULT;
   2686 		return (-1);
   2687 	}
   2688 	size_of_addresses = 0;
   2689 	opt_len = (socklen_t)sizeof(int);
   2690 	if (usrsctp_getsockopt(so, IPPROTO_SCTP, SCTP_GET_LOCAL_ADDR_SIZE, &size_of_addresses, &opt_len) != 0) {
   2691 		errno = ENOMEM;
   2692 		return (-1);
   2693 	}
   2694 	if (size_of_addresses == 0) {
   2695 		errno = ENOTCONN;
   2696 		return (-1);
   2697 	}
   2698 	opt_len = (socklen_t)(size_of_addresses +
   2699 	                      sizeof(struct sockaddr_storage) +
   2700 	                      sizeof(struct sctp_getaddresses));
   2701 	addrs = calloc(1, (size_t)opt_len);
   2702 	if (addrs == NULL) {
   2703 		errno = ENOMEM;
   2704 		return (-1);
   2705 	}
   2706 	addrs->sget_assoc_id = id;
   2707 	/* Now lets get the array of addresses */
   2708 	if (usrsctp_getsockopt(so, IPPROTO_SCTP, SCTP_GET_LOCAL_ADDRESSES, addrs, &opt_len) != 0) {
   2709 		free(addrs);
   2710 		errno = ENOMEM;
   2711 		return (-1);
   2712 	}
   2713 	*raddrs = (struct sockaddr *)&addrs->addr[0];
   2714 	cnt = 0;
   2715 	sa = (struct sockaddr *)&addrs->addr[0];
   2716 	lim = (caddr_t)addrs + opt_len;
   2717 #ifdef HAVE_SA_LEN
   2718 	while (((caddr_t)sa < lim) && (sa->sa_len > 0)) {
   2719 		sa = (struct sockaddr *)((caddr_t)sa + sa->sa_len);
   2720 #else
   2721 	while ((caddr_t)sa < lim) {
   2722 		switch (sa->sa_family) {
   2723 #ifdef INET
   2724 		case AF_INET:
   2725 			sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in));
   2726 			break;
   2727 #endif
   2728 #ifdef INET6
   2729 		case AF_INET6:
   2730 			sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in6));
   2731 			break;
   2732 #endif
   2733 		case AF_CONN:
   2734 			sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_conn));
   2735 			break;
   2736 		default:
   2737 			return (cnt);
   2738 			break;
   2739 		}
   2740 #endif
   2741 		cnt++;
   2742 	}
   2743 	return (cnt);
   2744 }
   2745 
   2746 void
   2747 usrsctp_freeladdrs(struct sockaddr *addrs)
   2748 {
   2749 	/* Take away the hidden association id */
   2750 	void *fr_addr;
   2751 
   2752 	fr_addr = (void *)((caddr_t)addrs - sizeof(sctp_assoc_t));
   2753 	/* Now free it */
   2754 	free(fr_addr);
   2755 }
   2756 
   2757 #ifdef INET
   2758 void
   2759 sctp_userspace_ip_output(int *result, struct mbuf *o_pak,
   2760                          sctp_route_t *ro, void *stcb,
   2761                          uint32_t vrf_id)
   2762 {
   2763 	struct mbuf *m;
   2764 	struct mbuf *m_orig;
   2765 	int iovcnt;
   2766 	int send_len;
   2767 	int len;
   2768 	int send_count;
   2769 	struct ip *ip;
   2770 	struct udphdr *udp;
   2771 #if !defined (__Userspace_os_Windows)
   2772 	int res;
   2773 #endif
   2774 	struct sockaddr_in dst;
   2775 #if defined (__Userspace_os_Windows)
   2776 	WSAMSG win_msg_hdr;
   2777 	int win_sent_len;
   2778 	WSABUF send_iovec[MAXLEN_MBUF_CHAIN];
   2779 	WSABUF winbuf;
   2780 #else
   2781 	struct iovec send_iovec[MAXLEN_MBUF_CHAIN];
   2782 	struct msghdr msg_hdr;
   2783 #endif
   2784 	int use_udp_tunneling;
   2785 
   2786 	*result = 0;
   2787 
   2788 	m = SCTP_HEADER_TO_CHAIN(o_pak);
   2789 	m_orig = m;
   2790 
   2791 	len = sizeof(struct ip);
   2792 	if (SCTP_BUF_LEN(m) < len) {
   2793 		if ((m = m_pullup(m, len)) == 0) {
   2794 			SCTP_PRINTF("Can not get the IP header in the first mbuf.\n");
   2795 			return;
   2796 		}
   2797 	}
   2798 	ip = mtod(m, struct ip *);
   2799 	use_udp_tunneling = (ip->ip_p == IPPROTO_UDP);
   2800 
   2801 	if (use_udp_tunneling) {
   2802 		len = sizeof(struct ip) + sizeof(struct udphdr);
   2803 		if (SCTP_BUF_LEN(m) < len) {
   2804 			if ((m = m_pullup(m, len)) == 0) {
   2805 				SCTP_PRINTF("Can not get the UDP/IP header in the first mbuf.\n");
   2806 				return;
   2807 			}
   2808 			ip = mtod(m, struct ip *);
   2809 		}
   2810 		udp = (struct udphdr *)(ip + 1);
   2811 	} else {
   2812 		udp = NULL;
   2813 	}
   2814 
   2815 	if (!use_udp_tunneling) {
   2816 		if (ip->ip_src.s_addr == INADDR_ANY) {
   2817 			/* TODO get addr of outgoing interface */
   2818 			SCTP_PRINTF("Why did the SCTP implementation did not choose a source address?\n");
   2819 		}
   2820 		/* TODO need to worry about ro->ro_dst as in ip_output? */
   2821 #if defined(__Userspace_os_Linux) || defined (__Userspace_os_Windows)
   2822 		/* need to put certain fields into network order for Linux */
   2823 		ip->ip_len = htons(ip->ip_len);
   2824 		ip->ip_off = 0;
   2825 #endif
   2826 	}
   2827 
   2828 	memset((void *)&dst, 0, sizeof(struct sockaddr_in));
   2829 	dst.sin_family = AF_INET;
   2830 	dst.sin_addr.s_addr = ip->ip_dst.s_addr;
   2831 #ifdef HAVE_SIN_LEN
   2832 	dst.sin_len = sizeof(struct sockaddr_in);
   2833 #endif
   2834 	if (use_udp_tunneling) {
   2835 		dst.sin_port = udp->uh_dport;
   2836 	} else {
   2837 		dst.sin_port = 0;
   2838 	}
   2839 
   2840 	/* tweak the mbuf chain */
   2841 	if (use_udp_tunneling) {
   2842 		m_adj(m, sizeof(struct ip) + sizeof(struct udphdr));
   2843 	}
   2844 
   2845 	send_len = SCTP_HEADER_LEN(m); /* length of entire packet */
   2846 	send_count = 0;
   2847 	for (iovcnt = 0; m != NULL && iovcnt < MAXLEN_MBUF_CHAIN; m = m->m_next, iovcnt++) {
   2848 #if !defined (__Userspace_os_Windows)
   2849 		send_iovec[iovcnt].iov_base = (caddr_t)m->m_data;
   2850 		send_iovec[iovcnt].iov_len = SCTP_BUF_LEN(m);
   2851 		send_count += send_iovec[iovcnt].iov_len;
   2852 #else
   2853 		send_iovec[iovcnt].buf = (caddr_t)m->m_data;
   2854 		send_iovec[iovcnt].len = SCTP_BUF_LEN(m);
   2855 		send_count += send_iovec[iovcnt].len;
   2856 #endif
   2857 	}
   2858 
   2859 	if (m != NULL) {
   2860 		SCTP_PRINTF("mbuf chain couldn't be copied completely\n");
   2861 		goto free_mbuf;
   2862 	}
   2863 
   2864 #if !defined (__Userspace_os_Windows)
   2865 	msg_hdr.msg_name = (struct sockaddr *) &dst;
   2866 	msg_hdr.msg_namelen = sizeof(struct sockaddr_in);
   2867 	msg_hdr.msg_iov = send_iovec;
   2868 	msg_hdr.msg_iovlen = iovcnt;
   2869 	msg_hdr.msg_control = NULL;
   2870 	msg_hdr.msg_controllen = 0;
   2871 	msg_hdr.msg_flags = 0;
   2872 
   2873 	if ((!use_udp_tunneling) && (SCTP_BASE_VAR(userspace_rawsctp) > -1)) {
   2874 		if ((res = sendmsg(SCTP_BASE_VAR(userspace_rawsctp), &msg_hdr, MSG_DONTWAIT)) != send_len) {
   2875 			*result = errno;
   2876 		}
   2877 	}
   2878 	if ((use_udp_tunneling) && (SCTP_BASE_VAR(userspace_udpsctp) > -1)) {
   2879 		if ((res = sendmsg(SCTP_BASE_VAR(userspace_udpsctp), &msg_hdr, MSG_DONTWAIT)) != send_len) {
   2880 			*result = errno;
   2881 		}
   2882 	}
   2883 #else
   2884 	win_msg_hdr.name = (struct sockaddr *) &dst;
   2885 	win_msg_hdr.namelen = sizeof(struct sockaddr_in);
   2886 	win_msg_hdr.lpBuffers = (LPWSABUF)send_iovec;
   2887 	win_msg_hdr.dwBufferCount = iovcnt;
   2888 	winbuf.len = 0;
   2889 	winbuf.buf = NULL;
   2890 	win_msg_hdr.Control = winbuf;
   2891 	win_msg_hdr.dwFlags = 0;
   2892 
   2893 	if ((!use_udp_tunneling) && (SCTP_BASE_VAR(userspace_rawsctp) > -1)) {
   2894 		if (WSASendTo(SCTP_BASE_VAR(userspace_rawsctp), (LPWSABUF) send_iovec, iovcnt, &win_sent_len, win_msg_hdr.dwFlags, win_msg_hdr.name, (int) win_msg_hdr.namelen, NULL, NULL) != 0) {
   2895 			*result = WSAGetLastError();
   2896 		} else if (win_sent_len != send_len) {
   2897 			*result = WSAGetLastError();
   2898 		}
   2899 	}
   2900 	if ((use_udp_tunneling) && (SCTP_BASE_VAR(userspace_udpsctp) > -1)) {
   2901 		if (WSASendTo(SCTP_BASE_VAR(userspace_udpsctp), (LPWSABUF) send_iovec, iovcnt, &win_sent_len, win_msg_hdr.dwFlags, win_msg_hdr.name, (int) win_msg_hdr.namelen, NULL, NULL) != 0) {
   2902 			*result = WSAGetLastError();
   2903 		} else if (win_sent_len != send_len) {
   2904 			*result = WSAGetLastError();
   2905 		}
   2906 	}
   2907 #endif
   2908 free_mbuf:
   2909 	sctp_m_freem(m_orig);
   2910 }
   2911 #endif
   2912 
   2913 #if defined (INET6)
   2914 void sctp_userspace_ip6_output(int *result, struct mbuf *o_pak,
   2915                                             struct route_in6 *ro, void *stcb,
   2916                                             uint32_t vrf_id)
   2917 {
   2918 	struct mbuf *m;
   2919 	struct mbuf *m_orig;
   2920 	int iovcnt;
   2921 	int send_len;
   2922 	int len;
   2923 	int send_count;
   2924 	struct ip6_hdr *ip6;
   2925 	struct udphdr *udp;
   2926 #if !defined (__Userspace_os_Windows)
   2927 	int res;
   2928 #endif
   2929 	struct sockaddr_in6 dst;
   2930 #if defined (__Userspace_os_Windows)
   2931 	WSAMSG win_msg_hdr;
   2932 	int win_sent_len;
   2933 	WSABUF send_iovec[MAXLEN_MBUF_CHAIN];
   2934 	WSABUF winbuf;
   2935 #else
   2936 	struct iovec send_iovec[MAXLEN_MBUF_CHAIN];
   2937 	struct msghdr msg_hdr;
   2938 #endif
   2939 	int use_udp_tunneling;
   2940 
   2941 	*result = 0;
   2942 
   2943 	m = SCTP_HEADER_TO_CHAIN(o_pak);
   2944 	m_orig = m;
   2945 
   2946 	len = sizeof(struct ip6_hdr);
   2947 
   2948 	if (SCTP_BUF_LEN(m) < len) {
   2949 		if ((m = m_pullup(m, len)) == 0) {
   2950 			SCTP_PRINTF("Can not get the IP header in the first mbuf.\n");
   2951 			return;
   2952 		}
   2953 	}
   2954 
   2955 	ip6 = mtod(m, struct ip6_hdr *);
   2956 	use_udp_tunneling = (ip6->ip6_nxt == IPPROTO_UDP);
   2957 
   2958 	if (use_udp_tunneling) {
   2959 		len = sizeof(struct ip6_hdr) + sizeof(struct udphdr);
   2960 		if (SCTP_BUF_LEN(m) < len) {
   2961 			if ((m = m_pullup(m, len)) == 0) {
   2962 				SCTP_PRINTF("Can not get the UDP/IP header in the first mbuf.\n");
   2963 				return;
   2964 			}
   2965 			ip6 = mtod(m, struct ip6_hdr *);
   2966 		}
   2967 		udp = (struct udphdr *)(ip6 + 1);
   2968 	} else {
   2969 		udp = NULL;
   2970 	}
   2971 
   2972 	if (!use_udp_tunneling) {
   2973 		if (ip6->ip6_src.s6_addr == in6addr_any.s6_addr) {
   2974 			/* TODO get addr of outgoing interface */
   2975 			SCTP_PRINTF("Why did the SCTP implementation did not choose a source address?\n");
   2976 		}
   2977 		/* TODO need to worry about ro->ro_dst as in ip_output? */
   2978 #if defined(__Userspace_os_Linux) || defined (__Userspace_os_Windows)
   2979 		/* need to put certain fields into network order for Linux */
   2980 		ip6->ip6_plen = htons(ip6->ip6_plen);
   2981 #endif
   2982 	}
   2983 
   2984 	memset((void *)&dst, 0, sizeof(struct sockaddr_in6));
   2985 	dst.sin6_family = AF_INET6;
   2986 	dst.sin6_addr = ip6->ip6_dst;
   2987 #ifdef HAVE_SIN6_LEN
   2988 	dst.sin6_len = sizeof(struct sockaddr_in6);
   2989 #endif
   2990 
   2991 	if (use_udp_tunneling) {
   2992 		dst.sin6_port = udp->uh_dport;
   2993 	} else {
   2994 		dst.sin6_port = 0;
   2995 	}
   2996 
   2997 	/* tweak the mbuf chain */
   2998 	if (use_udp_tunneling) {
   2999 		m_adj(m, sizeof(struct ip6_hdr) + sizeof(struct udphdr));
   3000 	} else {
   3001 	  m_adj(m, sizeof(struct ip6_hdr));
   3002 	}
   3003 
   3004 	send_len = SCTP_HEADER_LEN(m); /* length of entire packet */
   3005 	send_count = 0;
   3006 	for (iovcnt = 0; m != NULL && iovcnt < MAXLEN_MBUF_CHAIN; m = m->m_next, iovcnt++) {
   3007 #if !defined (__Userspace_os_Windows)
   3008 		send_iovec[iovcnt].iov_base = (caddr_t)m->m_data;
   3009 		send_iovec[iovcnt].iov_len = SCTP_BUF_LEN(m);
   3010 		send_count += send_iovec[iovcnt].iov_len;
   3011 #else
   3012 		send_iovec[iovcnt].buf = (caddr_t)m->m_data;
   3013 		send_iovec[iovcnt].len = SCTP_BUF_LEN(m);
   3014 		send_count += send_iovec[iovcnt].len;
   3015 #endif
   3016 	}
   3017 	if (m != NULL) {
   3018 		SCTP_PRINTF("mbuf chain couldn't be copied completely\n");
   3019 		goto free_mbuf;
   3020 	}
   3021 
   3022 #if !defined (__Userspace_os_Windows)
   3023 	msg_hdr.msg_name = (struct sockaddr *) &dst;
   3024 	msg_hdr.msg_namelen = sizeof(struct sockaddr_in6);
   3025 	msg_hdr.msg_iov = send_iovec;
   3026 	msg_hdr.msg_iovlen = iovcnt;
   3027 	msg_hdr.msg_control = NULL;
   3028 	msg_hdr.msg_controllen = 0;
   3029 	msg_hdr.msg_flags = 0;
   3030 
   3031 	if ((!use_udp_tunneling) && (SCTP_BASE_VAR(userspace_rawsctp6) > -1)) {
   3032 		if ((res = sendmsg(SCTP_BASE_VAR(userspace_rawsctp6), &msg_hdr, MSG_DONTWAIT)) != send_len) {
   3033 			*result = errno;
   3034 		}
   3035 	}
   3036 	if ((use_udp_tunneling) && (SCTP_BASE_VAR(userspace_udpsctp6) > -1)) {
   3037 		if ((res = sendmsg(SCTP_BASE_VAR(userspace_udpsctp6), &msg_hdr, MSG_DONTWAIT)) != send_len) {
   3038 			*result = errno;
   3039 		}
   3040 	}
   3041 #else
   3042 	win_msg_hdr.name = (struct sockaddr *) &dst;
   3043 	win_msg_hdr.namelen = sizeof(struct sockaddr_in6);
   3044 	win_msg_hdr.lpBuffers = (LPWSABUF)send_iovec;
   3045 	win_msg_hdr.dwBufferCount = iovcnt;
   3046 	winbuf.len = 0;
   3047 	winbuf.buf = NULL;
   3048 	win_msg_hdr.Control = winbuf;
   3049 	win_msg_hdr.dwFlags = 0;
   3050 
   3051 	if ((!use_udp_tunneling) && (SCTP_BASE_VAR(userspace_rawsctp6) > -1)) {
   3052 		if (WSASendTo(SCTP_BASE_VAR(userspace_rawsctp6), (LPWSABUF) send_iovec, iovcnt, &win_sent_len, win_msg_hdr.dwFlags, win_msg_hdr.name, (int) win_msg_hdr.namelen, NULL, NULL) != 0) {
   3053 			*result = WSAGetLastError();
   3054 		} else if (win_sent_len != send_len) {
   3055 			*result = WSAGetLastError();
   3056 		}
   3057 	}
   3058 	if ((use_udp_tunneling) && (SCTP_BASE_VAR(userspace_udpsctp6) > -1)) {
   3059 		if (WSASendTo(SCTP_BASE_VAR(userspace_udpsctp6), (LPWSABUF) send_iovec, iovcnt, &win_sent_len, win_msg_hdr.dwFlags, win_msg_hdr.name, (int) win_msg_hdr.namelen, NULL, NULL) != 0) {
   3060 			*result = WSAGetLastError();
   3061 		} else if (win_sent_len != send_len) {
   3062 			*result = WSAGetLastError();
   3063 		}
   3064 	}
   3065 #endif
   3066 free_mbuf:
   3067 	sctp_m_freem(m_orig);
   3068 }
   3069 #endif
   3070 
   3071 void
   3072 usrsctp_register_address(void *addr)
   3073 {
   3074 	struct sockaddr_conn sconn;
   3075 
   3076 	memset(&sconn, 0, sizeof(struct sockaddr_conn));
   3077 	sconn.sconn_family = AF_CONN;
   3078 #ifdef HAVE_SCONN_LEN
   3079 	sconn.sconn_len = sizeof(struct sockaddr_conn);
   3080 #endif
   3081 	sconn.sconn_port = 0;
   3082 	sconn.sconn_addr = addr;
   3083 	sctp_add_addr_to_vrf(SCTP_DEFAULT_VRFID,
   3084 	                     NULL,
   3085 	                     0xffffffff,
   3086 	                     0,
   3087 	                     "conn",
   3088 	                     NULL,
   3089 	                     (struct sockaddr *)&sconn,
   3090 	                     0,
   3091 	                     0);
   3092 }
   3093 
   3094 void
   3095 usrsctp_deregister_address(void *addr)
   3096 {
   3097 	struct sockaddr_conn sconn;
   3098 
   3099 	memset(&sconn, 0, sizeof(struct sockaddr_conn));
   3100 	sconn.sconn_family = AF_CONN;
   3101 #ifdef HAVE_SCONN_LEN
   3102 	sconn.sconn_len = sizeof(struct sockaddr_conn);
   3103 #endif
   3104 	sconn.sconn_port = 0;
   3105 	sconn.sconn_addr = addr;
   3106 	sctp_del_addr_from_vrf(SCTP_DEFAULT_VRFID,
   3107 	                       (struct sockaddr *)&sconn,
   3108 	                       0xffffffff,
   3109 	                       "conn");
   3110 }
   3111 
   3112 #define PREAMBLE_FORMAT "\n%c %02d:%02d:%02d.%06ld "
   3113 #define PREAMBLE_LENGTH 19
   3114 #define HEADER "0000 "
   3115 #define TRAILER "# SCTP_PACKET\n"
   3116 
   3117 char *
   3118 usrsctp_dumppacket(void *buf, size_t len, int outbound)
   3119 {
   3120 	size_t i, pos;
   3121 	char *dump_buf, *packet;
   3122 #ifdef _WIN32
   3123 	struct timeb tb;
   3124 	struct tm t;
   3125 #else
   3126 	struct timeval tv;
   3127 	struct tm *t;
   3128 	time_t sec;
   3129 #endif
   3130 
   3131 	if ((len == 0) || (buf == NULL)) {
   3132 		return (NULL);
   3133 	}
   3134 	if ((dump_buf = malloc(PREAMBLE_LENGTH + strlen(HEADER) + 3 * len + strlen(TRAILER) + 1)) == NULL) {
   3135 		return (NULL);
   3136 	}
   3137 	pos = 0;
   3138 #ifdef _WIN32
   3139 	ftime(&tb);
   3140 	localtime_s(&t, &tb.time);
   3141 	_snprintf_s(dump_buf, PREAMBLE_LENGTH + 1, PREAMBLE_LENGTH, PREAMBLE_FORMAT,
   3142 	            outbound ? 'O' : 'I',
   3143 	            t.tm_hour, t.tm_min, t.tm_sec, (long)(1000 * tb.millitm));
   3144 #else
   3145 	gettimeofday(&tv, NULL);
   3146 	sec = (time_t)tv.tv_sec;
   3147 	t = localtime((const time_t *)&sec);
   3148 	snprintf(dump_buf, PREAMBLE_LENGTH + 1, PREAMBLE_FORMAT,
   3149 	         outbound ? 'O' : 'I',
   3150 	         t->tm_hour, t->tm_min, t->tm_sec, (long)tv.tv_usec);
   3151 #endif
   3152 	pos += PREAMBLE_LENGTH;
   3153 #ifdef _WIN32
   3154 	strncpy_s(dump_buf + pos, strlen(HEADER) + 1, HEADER, strlen(HEADER));
   3155 #else
   3156 	strcpy(dump_buf + pos, HEADER);
   3157 #endif
   3158 	pos += strlen(HEADER);
   3159 	packet = (char *)buf;
   3160 	for (i = 0; i < len; i++) {
   3161 		uint8_t byte, low, high;
   3162 
   3163 		byte = (uint8_t)packet[i];
   3164 		high = byte / 16;
   3165 		low = byte % 16;
   3166 		dump_buf[pos++] = high < 10 ? '0' + high : 'a' + (high - 10);
   3167 		dump_buf[pos++] = low < 10 ? '0' + low : 'a' + (low - 10);
   3168 		dump_buf[pos++] = ' ';
   3169 	}
   3170 #ifdef _WIN32
   3171 	strncpy_s(dump_buf + pos, strlen(TRAILER) + 1, TRAILER, strlen(TRAILER));
   3172 #else
   3173 	strcpy(dump_buf + pos, TRAILER);
   3174 #endif
   3175 	pos += strlen(TRAILER);
   3176 	dump_buf[pos++] = '\0';
   3177 	return (dump_buf);
   3178 }
   3179 
   3180 void
   3181 usrsctp_freedumpbuffer(char *buf)
   3182 {
   3183 	free(buf);
   3184 }
   3185 
   3186 void
   3187 usrsctp_conninput(void *addr, const void *buffer, size_t length, uint8_t ecn_bits)
   3188 {
   3189 	struct sockaddr_conn src, dst;
   3190 	struct mbuf *m;
   3191 	struct sctphdr *sh;
   3192 	struct sctp_chunkhdr *ch;
   3193 
   3194 	SCTP_STAT_INCR(sctps_recvpackets);
   3195 	SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
   3196 	memset(&src, 0, sizeof(struct sockaddr_conn));
   3197 	src.sconn_family = AF_CONN;
   3198 #ifdef HAVE_SCONN_LEN
   3199 	src.sconn_len = sizeof(struct sockaddr_conn);
   3200 #endif
   3201 	src.sconn_addr = addr;
   3202 	memset(&dst, 0, sizeof(struct sockaddr_conn));
   3203 	dst.sconn_family = AF_CONN;
   3204 #ifdef HAVE_SCONN_LEN
   3205 	dst.sconn_len = sizeof(struct sockaddr_conn);
   3206 #endif
   3207 	dst.sconn_addr = addr;
   3208 	if ((m = sctp_get_mbuf_for_msg(length, 1, M_NOWAIT, 0, MT_DATA)) == NULL) {
   3209 		return;
   3210 	}
   3211 	m_copyback(m, 0, length, (caddr_t)buffer);
   3212 	if (SCTP_BUF_LEN(m) < (int)(sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr))) {
   3213 		if ((m = m_pullup(m, sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr))) == NULL) {
   3214 			SCTP_STAT_INCR(sctps_hdrops);
   3215 			return;
   3216 		}
   3217 	}
   3218 	sh = mtod(m, struct sctphdr *);;
   3219 	ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(struct sctphdr));
   3220 	src.sconn_port = sh->src_port;
   3221 	dst.sconn_port = sh->dest_port;
   3222 	sctp_common_input_processing(&m, 0, sizeof(struct sctphdr), length,
   3223 	                             (struct sockaddr *)&src,
   3224 	                             (struct sockaddr *)&dst,
   3225 	                             sh, ch,
   3226 #if !defined(SCTP_WITH_NO_CSUM)
   3227 	                             1,
   3228 #endif
   3229 	                             ecn_bits,
   3230 	                             SCTP_DEFAULT_VRFID, 0);
   3231 	if (m) {
   3232 		sctp_m_freem(m);
   3233 	}
   3234 	return;
   3235 }
   3236 
   3237 
   3238 #define USRSCTP_SYSCTL_SET_DEF(__field) \
   3239 void usrsctp_sysctl_set_ ## __field(uint32_t value) { \
   3240 	SCTP_BASE_SYSCTL(__field) = value; \
   3241 }
   3242 
   3243 USRSCTP_SYSCTL_SET_DEF(sctp_sendspace)
   3244 USRSCTP_SYSCTL_SET_DEF(sctp_recvspace)
   3245 USRSCTP_SYSCTL_SET_DEF(sctp_auto_asconf)
   3246 USRSCTP_SYSCTL_SET_DEF(sctp_multiple_asconfs)
   3247 USRSCTP_SYSCTL_SET_DEF(sctp_ecn_enable)
   3248 USRSCTP_SYSCTL_SET_DEF(sctp_strict_sacks)
   3249 #if !defined(SCTP_WITH_NO_CSUM)
   3250 USRSCTP_SYSCTL_SET_DEF(sctp_no_csum_on_loopback)
   3251 #endif
   3252 USRSCTP_SYSCTL_SET_DEF(sctp_peer_chunk_oh)
   3253 USRSCTP_SYSCTL_SET_DEF(sctp_max_burst_default)
   3254 USRSCTP_SYSCTL_SET_DEF(sctp_max_chunks_on_queue)
   3255 USRSCTP_SYSCTL_SET_DEF(sctp_hashtblsize)
   3256 USRSCTP_SYSCTL_SET_DEF(sctp_pcbtblsize)
   3257 USRSCTP_SYSCTL_SET_DEF(sctp_min_split_point)
   3258 USRSCTP_SYSCTL_SET_DEF(sctp_chunkscale)
   3259 USRSCTP_SYSCTL_SET_DEF(sctp_delayed_sack_time_default)
   3260 USRSCTP_SYSCTL_SET_DEF(sctp_sack_freq_default)
   3261 USRSCTP_SYSCTL_SET_DEF(sctp_system_free_resc_limit)
   3262 USRSCTP_SYSCTL_SET_DEF(sctp_asoc_free_resc_limit)
   3263 USRSCTP_SYSCTL_SET_DEF(sctp_heartbeat_interval_default)
   3264 USRSCTP_SYSCTL_SET_DEF(sctp_pmtu_raise_time_default)
   3265 USRSCTP_SYSCTL_SET_DEF(sctp_shutdown_guard_time_default)
   3266 USRSCTP_SYSCTL_SET_DEF(sctp_secret_lifetime_default)
   3267 USRSCTP_SYSCTL_SET_DEF(sctp_rto_max_default)
   3268 USRSCTP_SYSCTL_SET_DEF(sctp_rto_min_default)
   3269 USRSCTP_SYSCTL_SET_DEF(sctp_rto_initial_default)
   3270 USRSCTP_SYSCTL_SET_DEF(sctp_init_rto_max_default)
   3271 USRSCTP_SYSCTL_SET_DEF(sctp_valid_cookie_life_default)
   3272 USRSCTP_SYSCTL_SET_DEF(sctp_init_rtx_max_default)
   3273 USRSCTP_SYSCTL_SET_DEF(sctp_assoc_rtx_max_default)
   3274 USRSCTP_SYSCTL_SET_DEF(sctp_path_rtx_max_default)
   3275 USRSCTP_SYSCTL_SET_DEF(sctp_add_more_threshold)
   3276 USRSCTP_SYSCTL_SET_DEF(sctp_nr_outgoing_streams_default)
   3277 USRSCTP_SYSCTL_SET_DEF(sctp_cmt_on_off)
   3278 USRSCTP_SYSCTL_SET_DEF(sctp_cmt_use_dac)
   3279 USRSCTP_SYSCTL_SET_DEF(sctp_nr_sack_on_off)
   3280 USRSCTP_SYSCTL_SET_DEF(sctp_use_cwnd_based_maxburst)
   3281 USRSCTP_SYSCTL_SET_DEF(sctp_asconf_auth_nochk)
   3282 USRSCTP_SYSCTL_SET_DEF(sctp_auth_disable)
   3283 USRSCTP_SYSCTL_SET_DEF(sctp_nat_friendly)
   3284 USRSCTP_SYSCTL_SET_DEF(sctp_L2_abc_variable)
   3285 USRSCTP_SYSCTL_SET_DEF(sctp_mbuf_threshold_count)
   3286 USRSCTP_SYSCTL_SET_DEF(sctp_do_drain)
   3287 USRSCTP_SYSCTL_SET_DEF(sctp_hb_maxburst)
   3288 USRSCTP_SYSCTL_SET_DEF(sctp_abort_if_one_2_one_hits_limit)
   3289 USRSCTP_SYSCTL_SET_DEF(sctp_strict_data_order)
   3290 USRSCTP_SYSCTL_SET_DEF(sctp_min_residual)
   3291 USRSCTP_SYSCTL_SET_DEF(sctp_max_retran_chunk)
   3292 USRSCTP_SYSCTL_SET_DEF(sctp_logging_level)
   3293 USRSCTP_SYSCTL_SET_DEF(sctp_default_cc_module)
   3294 USRSCTP_SYSCTL_SET_DEF(sctp_default_frag_interleave)
   3295 USRSCTP_SYSCTL_SET_DEF(sctp_mobility_base)
   3296 USRSCTP_SYSCTL_SET_DEF(sctp_mobility_fasthandoff)
   3297 USRSCTP_SYSCTL_SET_DEF(sctp_inits_include_nat_friendly)
   3298 USRSCTP_SYSCTL_SET_DEF(sctp_udp_tunneling_port)
   3299 USRSCTP_SYSCTL_SET_DEF(sctp_enable_sack_immediately)
   3300 USRSCTP_SYSCTL_SET_DEF(sctp_vtag_time_wait)
   3301 USRSCTP_SYSCTL_SET_DEF(sctp_blackhole)
   3302 USRSCTP_SYSCTL_SET_DEF(sctp_diag_info_code)
   3303 USRSCTP_SYSCTL_SET_DEF(sctp_fr_max_burst_default)
   3304 USRSCTP_SYSCTL_SET_DEF(sctp_path_pf_threshold)
   3305 USRSCTP_SYSCTL_SET_DEF(sctp_default_ss_module)
   3306 USRSCTP_SYSCTL_SET_DEF(sctp_rttvar_bw)
   3307 USRSCTP_SYSCTL_SET_DEF(sctp_rttvar_rtt)
   3308 USRSCTP_SYSCTL_SET_DEF(sctp_rttvar_eqret)
   3309 USRSCTP_SYSCTL_SET_DEF(sctp_steady_step)
   3310 USRSCTP_SYSCTL_SET_DEF(sctp_use_dccc_ecn)
   3311 USRSCTP_SYSCTL_SET_DEF(sctp_buffer_splitting)
   3312 USRSCTP_SYSCTL_SET_DEF(sctp_initial_cwnd)
   3313 #ifdef SCTP_DEBUG
   3314 USRSCTP_SYSCTL_SET_DEF(sctp_debug_on)
   3315 #endif
   3316 
   3317 #define USRSCTP_SYSCTL_GET_DEF(__field) \
   3318 uint32_t usrsctp_sysctl_get_ ## __field(void) { \
   3319 	return SCTP_BASE_SYSCTL(__field); \
   3320 }
   3321 
   3322 USRSCTP_SYSCTL_GET_DEF(sctp_sendspace)
   3323 USRSCTP_SYSCTL_GET_DEF(sctp_recvspace)
   3324 USRSCTP_SYSCTL_GET_DEF(sctp_auto_asconf)
   3325 USRSCTP_SYSCTL_GET_DEF(sctp_multiple_asconfs)
   3326 USRSCTP_SYSCTL_GET_DEF(sctp_ecn_enable)
   3327 USRSCTP_SYSCTL_GET_DEF(sctp_strict_sacks)
   3328 #if !defined(SCTP_WITH_NO_CSUM)
   3329 USRSCTP_SYSCTL_GET_DEF(sctp_no_csum_on_loopback)
   3330 #endif
   3331 USRSCTP_SYSCTL_GET_DEF(sctp_peer_chunk_oh)
   3332 USRSCTP_SYSCTL_GET_DEF(sctp_max_burst_default)
   3333 USRSCTP_SYSCTL_GET_DEF(sctp_max_chunks_on_queue)
   3334 USRSCTP_SYSCTL_GET_DEF(sctp_hashtblsize)
   3335 USRSCTP_SYSCTL_GET_DEF(sctp_pcbtblsize)
   3336 USRSCTP_SYSCTL_GET_DEF(sctp_min_split_point)
   3337 USRSCTP_SYSCTL_GET_DEF(sctp_chunkscale)
   3338 USRSCTP_SYSCTL_GET_DEF(sctp_delayed_sack_time_default)
   3339 USRSCTP_SYSCTL_GET_DEF(sctp_sack_freq_default)
   3340 USRSCTP_SYSCTL_GET_DEF(sctp_system_free_resc_limit)
   3341 USRSCTP_SYSCTL_GET_DEF(sctp_asoc_free_resc_limit)
   3342 USRSCTP_SYSCTL_GET_DEF(sctp_heartbeat_interval_default)
   3343 USRSCTP_SYSCTL_GET_DEF(sctp_pmtu_raise_time_default)
   3344 USRSCTP_SYSCTL_GET_DEF(sctp_shutdown_guard_time_default)
   3345 USRSCTP_SYSCTL_GET_DEF(sctp_secret_lifetime_default)
   3346 USRSCTP_SYSCTL_GET_DEF(sctp_rto_max_default)
   3347 USRSCTP_SYSCTL_GET_DEF(sctp_rto_min_default)
   3348 USRSCTP_SYSCTL_GET_DEF(sctp_rto_initial_default)
   3349 USRSCTP_SYSCTL_GET_DEF(sctp_init_rto_max_default)
   3350 USRSCTP_SYSCTL_GET_DEF(sctp_valid_cookie_life_default)
   3351 USRSCTP_SYSCTL_GET_DEF(sctp_init_rtx_max_default)
   3352 USRSCTP_SYSCTL_GET_DEF(sctp_assoc_rtx_max_default)
   3353 USRSCTP_SYSCTL_GET_DEF(sctp_path_rtx_max_default)
   3354 USRSCTP_SYSCTL_GET_DEF(sctp_add_more_threshold)
   3355 USRSCTP_SYSCTL_GET_DEF(sctp_nr_outgoing_streams_default)
   3356 USRSCTP_SYSCTL_GET_DEF(sctp_cmt_on_off)
   3357 USRSCTP_SYSCTL_GET_DEF(sctp_cmt_use_dac)
   3358 USRSCTP_SYSCTL_GET_DEF(sctp_nr_sack_on_off)
   3359 USRSCTP_SYSCTL_GET_DEF(sctp_use_cwnd_based_maxburst)
   3360 USRSCTP_SYSCTL_GET_DEF(sctp_asconf_auth_nochk)
   3361 USRSCTP_SYSCTL_GET_DEF(sctp_auth_disable)
   3362 USRSCTP_SYSCTL_GET_DEF(sctp_nat_friendly)
   3363 USRSCTP_SYSCTL_GET_DEF(sctp_L2_abc_variable)
   3364 USRSCTP_SYSCTL_GET_DEF(sctp_mbuf_threshold_count)
   3365 USRSCTP_SYSCTL_GET_DEF(sctp_do_drain)
   3366 USRSCTP_SYSCTL_GET_DEF(sctp_hb_maxburst)
   3367 USRSCTP_SYSCTL_GET_DEF(sctp_abort_if_one_2_one_hits_limit)
   3368 USRSCTP_SYSCTL_GET_DEF(sctp_strict_data_order)
   3369 USRSCTP_SYSCTL_GET_DEF(sctp_min_residual)
   3370 USRSCTP_SYSCTL_GET_DEF(sctp_max_retran_chunk)
   3371 USRSCTP_SYSCTL_GET_DEF(sctp_logging_level)
   3372 USRSCTP_SYSCTL_GET_DEF(sctp_default_cc_module)
   3373 USRSCTP_SYSCTL_GET_DEF(sctp_default_frag_interleave)
   3374 USRSCTP_SYSCTL_GET_DEF(sctp_mobility_base)
   3375 USRSCTP_SYSCTL_GET_DEF(sctp_mobility_fasthandoff)
   3376 USRSCTP_SYSCTL_GET_DEF(sctp_inits_include_nat_friendly)
   3377 USRSCTP_SYSCTL_GET_DEF(sctp_udp_tunneling_port)
   3378 USRSCTP_SYSCTL_GET_DEF(sctp_enable_sack_immediately)
   3379 USRSCTP_SYSCTL_GET_DEF(sctp_vtag_time_wait)
   3380 USRSCTP_SYSCTL_GET_DEF(sctp_blackhole)
   3381 USRSCTP_SYSCTL_GET_DEF(sctp_diag_info_code)
   3382 USRSCTP_SYSCTL_GET_DEF(sctp_fr_max_burst_default)
   3383 USRSCTP_SYSCTL_GET_DEF(sctp_path_pf_threshold)
   3384 USRSCTP_SYSCTL_GET_DEF(sctp_default_ss_module)
   3385 USRSCTP_SYSCTL_GET_DEF(sctp_rttvar_bw)
   3386 USRSCTP_SYSCTL_GET_DEF(sctp_rttvar_rtt)
   3387 USRSCTP_SYSCTL_GET_DEF(sctp_rttvar_eqret)
   3388 USRSCTP_SYSCTL_GET_DEF(sctp_steady_step)
   3389 USRSCTP_SYSCTL_GET_DEF(sctp_use_dccc_ecn)
   3390 USRSCTP_SYSCTL_GET_DEF(sctp_buffer_splitting)
   3391 USRSCTP_SYSCTL_GET_DEF(sctp_initial_cwnd)
   3392 #ifdef SCTP_DEBUG
   3393 USRSCTP_SYSCTL_GET_DEF(sctp_debug_on)
   3394 #endif
   3395 
   3396 void usrsctp_get_stat(struct sctpstat *stat)
   3397 {
   3398 	*stat = SCTP_BASE_STATS;
   3399 }
   3400