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