tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

sctp_usrreq.c (258391B)


      1 /*-
      2 * SPDX-License-Identifier: BSD-3-Clause
      3 *
      4 * Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved.
      5 * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
      6 * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
      7 *
      8 * Redistribution and use in source and binary forms, with or without
      9 * modification, are permitted provided that the following conditions are met:
     10 *
     11 * a) Redistributions of source code must retain the above copyright notice,
     12 *    this list of conditions and the following disclaimer.
     13 *
     14 * b) Redistributions in binary form must reproduce the above copyright
     15 *    notice, this list of conditions and the following disclaimer in
     16 *    the documentation and/or other materials provided with the distribution.
     17 *
     18 * c) Neither the name of Cisco Systems, Inc. nor the names of its
     19 *    contributors may be used to endorse or promote products derived
     20 *    from this software without specific prior written permission.
     21 *
     22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     24 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     25 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
     26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
     32 * THE POSSIBILITY OF SUCH DAMAGE.
     33 */
     34 
     35 #include <netinet/sctp_os.h>
     36 #if defined(__FreeBSD__) && !defined(__Userspace__)
     37 #include <sys/proc.h>
     38 #endif
     39 #include <netinet/sctp_pcb.h>
     40 #include <netinet/sctp_header.h>
     41 #include <netinet/sctp_var.h>
     42 #ifdef INET6
     43 #include <netinet6/sctp6_var.h>
     44 #endif
     45 #include <netinet/sctp_sysctl.h>
     46 #include <netinet/sctp_output.h>
     47 #include <netinet/sctp_uio.h>
     48 #include <netinet/sctp_asconf.h>
     49 #include <netinet/sctputil.h>
     50 #include <netinet/sctp_indata.h>
     51 #include <netinet/sctp_timer.h>
     52 #include <netinet/sctp_auth.h>
     53 #include <netinet/sctp_bsd_addr.h>
     54 #if defined(__Userspace__)
     55 #include <netinet/sctp_callout.h>
     56 #else
     57 #include <netinet/udp.h>
     58 #endif
     59 #if defined(__FreeBSD__) && !defined(__Userspace__)
     60 #include <sys/eventhandler.h>
     61 #endif
     62 #if defined(HAVE_SCTP_PEELOFF_SOCKOPT)
     63 #include <netinet/sctp_peeloff.h>
     64 #endif				/* HAVE_SCTP_PEELOFF_SOCKOPT */
     65 
     66 #if defined(_WIN32) && !defined(_MSC_VER)
     67 #include <minmax.h>
     68 #endif
     69 
     70 extern const struct sctp_cc_functions sctp_cc_functions[];
     71 extern const struct sctp_ss_functions sctp_ss_functions[];
     72 
     73 #if defined(__Userspace__)
     74 void
     75 sctp_init(uint16_t port,
     76          int (*conn_output)(void *addr, void *buffer, size_t length, uint8_t tos, uint8_t set_df),
     77          void (*debug_printf)(const char *format, ...), int start_threads)
     78 #elif defined(__APPLE__) && (!defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) &&!defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION))
     79 void
     80 sctp_init(struct protosw *pp SCTP_UNUSED, struct domain *dp SCTP_UNUSED)
     81 #elif defined(__FreeBSD__)
     82 static void
     83 sctp_init(void *arg SCTP_UNUSED)
     84 #else
     85 void
     86 sctp_init(void)
     87 #endif
     88 {
     89 #if !defined(__Userspace__)
     90 u_long sb_max_adj;
     91 
     92 #else
     93 init_random();
     94 #endif
     95 /* Initialize and modify the sysctled variables */
     96 sctp_init_sysctls();
     97 #if defined(__Userspace__)
     98 SCTP_BASE_SYSCTL(sctp_udp_tunneling_port) = port;
     99 #else
    100 #if defined(__APPLE__) && !defined(__Userspace__)
    101 sb_max_adj = (u_long)((u_quad_t) (sb_max) * MCLBYTES / (MSIZE + MCLBYTES));
    102 SCTP_BASE_SYSCTL(sctp_sendspace) = sb_max_adj;
    103 #else
    104 if ((nmbclusters / 8) > SCTP_ASOC_MAX_CHUNKS_ON_QUEUE)
    105 	SCTP_BASE_SYSCTL(sctp_max_chunks_on_queue) = (nmbclusters / 8);
    106 /*
    107  * Allow a user to take no more than 1/2 the number of clusters or
    108  * the SB_MAX, whichever is smaller, for the send window.
    109  */
    110 sb_max_adj = (u_long)((u_quad_t) (SB_MAX) * MCLBYTES / (MSIZE + MCLBYTES));
    111 SCTP_BASE_SYSCTL(sctp_sendspace) = min(sb_max_adj,
    112     (((uint32_t)nmbclusters / 2) * MCLBYTES));
    113 #endif
    114 /*
    115  * Now for the recv window, should we take the same amount? or
    116  * should I do 1/2 the SB_MAX instead in the SB_MAX min above. For
    117  * now I will just copy.
    118  */
    119 SCTP_BASE_SYSCTL(sctp_recvspace) = SCTP_BASE_SYSCTL(sctp_sendspace);
    120 #endif
    121 SCTP_BASE_VAR(first_time) = 0;
    122 SCTP_BASE_VAR(sctp_pcb_initialized) = 0;
    123 #if defined(__Userspace__)
    124 #if !defined(_WIN32)
    125 #if defined(INET) || defined(INET6)
    126 SCTP_BASE_VAR(userspace_route) = -1;
    127 #endif
    128 #endif
    129 #ifdef INET
    130 SCTP_BASE_VAR(userspace_rawsctp) = -1;
    131 SCTP_BASE_VAR(userspace_udpsctp) = -1;
    132 #endif
    133 #ifdef INET6
    134 SCTP_BASE_VAR(userspace_rawsctp6) = -1;
    135 SCTP_BASE_VAR(userspace_udpsctp6) = -1;
    136 #endif
    137 SCTP_BASE_VAR(timer_thread_should_exit) = 0;
    138 SCTP_BASE_VAR(conn_output) = conn_output;
    139 SCTP_BASE_VAR(debug_printf) = debug_printf;
    140 SCTP_BASE_VAR(crc32c_offloaded) = 0;
    141 SCTP_BASE_VAR(iterator_thread_started) = 0;
    142 SCTP_BASE_VAR(timer_thread_started) = 0;
    143 #endif
    144 #if defined(__Userspace__)
    145 sctp_pcb_init(start_threads);
    146 if (start_threads) {
    147 	sctp_start_timer_thread();
    148 }
    149 #else
    150 sctp_pcb_init();
    151 #endif
    152 #if defined(SCTP_PACKET_LOGGING)
    153 SCTP_BASE_VAR(packet_log_writers) = 0;
    154 SCTP_BASE_VAR(packet_log_end) = 0;
    155 memset(&SCTP_BASE_VAR(packet_log_buffer), 0, SCTP_PACKET_LOG_SIZE);
    156 #endif
    157 #if defined(__APPLE__) && !defined(__Userspace__)
    158 SCTP_BASE_VAR(sctp_main_timer_ticks) = 0;
    159 sctp_start_main_timer();
    160 timeout(sctp_delayed_startup, NULL, 1);
    161 #endif
    162 #if defined(__FreeBSD__) && !defined(__Userspace__)
    163 SCTP_BASE_VAR(eh_tag) = EVENTHANDLER_REGISTER(rt_addrmsg,
    164     sctp_addr_change_event_handler, NULL, EVENTHANDLER_PRI_FIRST);
    165 #endif
    166 }
    167 #if defined(__FreeBSD__) && !defined(__Userspace__)
    168 VNET_SYSINIT(sctp_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, sctp_init, NULL);
    169 
    170 #ifdef VIMAGE
    171 static void
    172 sctp_finish(void *unused __unused)
    173 {
    174 EVENTHANDLER_DEREGISTER(rt_addrmsg, SCTP_BASE_VAR(eh_tag));
    175 sctp_pcb_finish();
    176 }
    177 VNET_SYSUNINIT(sctp, SI_SUB_PROTO_DOMAIN, SI_ORDER_FOURTH, sctp_finish, NULL);
    178 #endif
    179 #else
    180 void
    181 sctp_finish(void)
    182 {
    183 #if defined(__APPLE__) && !defined(__Userspace__)
    184 untimeout(sctp_delayed_startup, NULL);
    185 sctp_over_udp_stop();
    186 sctp_address_monitor_stop();
    187 sctp_stop_main_timer();
    188 #endif
    189 #if defined(__Userspace__)
    190 #if defined(INET) || defined(INET6)
    191 recv_thread_destroy();
    192 #endif
    193 sctp_stop_timer_thread();
    194 #endif
    195 sctp_pcb_finish();
    196 #if defined(_WIN32) && !defined(__Userspace__)
    197 sctp_finish_sysctls();
    198 #endif
    199 #if defined(__Userspace__)
    200 finish_random();
    201 #endif
    202 }
    203 #endif
    204 
    205 void
    206 sctp_pathmtu_adjustment(struct sctp_tcb *stcb, uint32_t mtu, bool resend)
    207 {
    208 struct sctp_association *asoc;
    209 struct sctp_tmit_chunk *chk;
    210 uint32_t overhead;
    211 
    212 asoc = &stcb->asoc;
    213 KASSERT(mtu < asoc->smallest_mtu,
    214         ("Currently only reducing association MTU %u supported (MTU %u)",
    215         asoc->smallest_mtu, mtu));
    216 asoc->smallest_mtu = mtu;
    217 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
    218 	overhead = SCTP_MIN_OVERHEAD;
    219 } else {
    220 #if defined(__Userspace__)
    221 	if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUND_CONN) {
    222 		overhead = sizeof(struct sctphdr);
    223 	} else {
    224 		overhead = SCTP_MIN_V4_OVERHEAD;
    225 	}
    226 #else
    227 	overhead = SCTP_MIN_V4_OVERHEAD;
    228 #endif
    229 }
    230 if (asoc->idata_supported) {
    231 	if (sctp_auth_is_required_chunk(SCTP_IDATA, asoc->peer_auth_chunks)) {
    232 		overhead += sctp_get_auth_chunk_len(asoc->peer_hmac_id);
    233 	}
    234 } else {
    235 	if (sctp_auth_is_required_chunk(SCTP_DATA, asoc->peer_auth_chunks)) {
    236 		overhead += sctp_get_auth_chunk_len(asoc->peer_hmac_id);
    237 	}
    238 }
    239 KASSERT(overhead % 4 == 0,
    240         ("overhead (%u) not a multiple of 4", overhead));
    241 TAILQ_FOREACH(chk, &asoc->send_queue, sctp_next) {
    242 	if (((uint32_t)chk->send_size + overhead) > mtu) {
    243 		chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
    244 	}
    245 }
    246 TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) {
    247 	if (((uint32_t)chk->send_size + overhead) > mtu) {
    248 		chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
    249 		if (resend && chk->sent < SCTP_DATAGRAM_RESEND) {
    250 			/*
    251 			 * If requested, mark the chunk for immediate
    252 			 * resend, since we sent it being too big.
    253 			 */
    254 			sctp_flight_size_decrease(chk);
    255 			sctp_total_flight_decrease(stcb, chk);
    256 			chk->sent = SCTP_DATAGRAM_RESEND;
    257 			sctp_ucount_incr(asoc->sent_queue_retran_cnt);
    258 			chk->rec.data.doing_fast_retransmit = 0;
    259 			if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FLIGHT_LOGGING_ENABLE) {
    260 				sctp_misc_ints(SCTP_FLIGHT_LOG_DOWN_PMTU,
    261 				               chk->whoTo->flight_size,
    262 				               chk->book_size,
    263 				               (uint32_t)(uintptr_t)chk->whoTo,
    264 				               chk->rec.data.tsn);
    265 			}
    266 			/* Clear any time, so NO RTT is being done. */
    267 			if (chk->do_rtt == 1) {
    268 				chk->do_rtt = 0;
    269 				chk->whoTo->rto_needed = 1;
    270 			}
    271 		}
    272 	}
    273 }
    274 }
    275 
    276 #ifdef INET
    277 #if !defined(__Userspace__)
    278 void
    279 sctp_notify(struct sctp_inpcb *inp,
    280            struct sctp_tcb *stcb,
    281            struct sctp_nets *net,
    282            uint8_t icmp_type,
    283            uint8_t icmp_code,
    284            uint16_t ip_len,
    285            uint32_t next_mtu)
    286 {
    287 #if defined(__APPLE__) && !defined(__Userspace__)
    288 struct socket *so;
    289 #endif
    290 int timer_stopped;
    291 
    292 if (icmp_type != ICMP_UNREACH) {
    293 	/* We only care about unreachable */
    294 	SCTP_TCB_UNLOCK(stcb);
    295 	return;
    296 }
    297 if ((icmp_code == ICMP_UNREACH_NET) ||
    298     (icmp_code == ICMP_UNREACH_HOST) ||
    299     (icmp_code == ICMP_UNREACH_NET_UNKNOWN) ||
    300     (icmp_code == ICMP_UNREACH_HOST_UNKNOWN) ||
    301     (icmp_code == ICMP_UNREACH_ISOLATED) ||
    302     (icmp_code == ICMP_UNREACH_NET_PROHIB) ||
    303     (icmp_code == ICMP_UNREACH_HOST_PROHIB) ||
    304 #if defined(__NetBSD__)
    305     (icmp_code == ICMP_UNREACH_ADMIN_PROHIBIT)) {
    306 #else
    307     (icmp_code == ICMP_UNREACH_FILTER_PROHIB)) {
    308 #endif
    309 	/* Mark the net unreachable. */
    310 	if (net->dest_state & SCTP_ADDR_REACHABLE) {
    311 		/* OK, that destination is NOT reachable. */
    312 		net->dest_state &= ~SCTP_ADDR_REACHABLE;
    313 		net->dest_state &= ~SCTP_ADDR_PF;
    314 		sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN,
    315 		                stcb, 0,
    316 		                (void *)net, SCTP_SO_NOT_LOCKED);
    317 	}
    318 	SCTP_TCB_UNLOCK(stcb);
    319 } else  if ((icmp_code == ICMP_UNREACH_PROTOCOL) ||
    320 	    (icmp_code == ICMP_UNREACH_PORT)) {
    321 	/* Treat it like an ABORT. */
    322 	sctp_abort_notification(stcb, true, false, 0, NULL, SCTP_SO_NOT_LOCKED);
    323 #if defined(__APPLE__) && !defined(__Userspace__)
    324 	so = SCTP_INP_SO(inp);
    325 	atomic_add_int(&stcb->asoc.refcnt, 1);
    326 	SCTP_TCB_UNLOCK(stcb);
    327 	SCTP_SOCKET_LOCK(so, 1);
    328 	SCTP_TCB_LOCK(stcb);
    329 	atomic_subtract_int(&stcb->asoc.refcnt, 1);
    330 #endif
    331 	(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
    332 	                      SCTP_FROM_SCTP_USRREQ + SCTP_LOC_2);
    333 #if defined(__APPLE__) && !defined(__Userspace__)
    334 	SCTP_SOCKET_UNLOCK(so, 1);
    335 	/* SCTP_TCB_UNLOCK(stcb); MT: I think this is not needed.*/
    336 #endif
    337 	/* no need to unlock here, since the TCB is gone */
    338 } else if (icmp_code == ICMP_UNREACH_NEEDFRAG) {
    339 	if (net->dest_state & SCTP_ADDR_NO_PMTUD) {
    340 		SCTP_TCB_UNLOCK(stcb);
    341 		return;
    342 	}
    343 	/* Find the next (smaller) MTU */
    344 	if (next_mtu == 0) {
    345 		/*
    346 		 * Old type router that does not tell us what the next
    347 		 * MTU is.
    348 		 * Rats we will have to guess (in a educated fashion
    349 		 * of course).
    350 		 */
    351 		next_mtu = sctp_get_prev_mtu(ip_len);
    352 	}
    353 	/* Stop the PMTU timer. */
    354 	if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
    355 		timer_stopped = 1;
    356 		sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net,
    357 		                SCTP_FROM_SCTP_USRREQ + SCTP_LOC_1);
    358 	} else {
    359 		timer_stopped = 0;
    360 	}
    361 	/* Update the path MTU. */
    362 	if (net->port) {
    363 		next_mtu -= sizeof(struct udphdr);
    364 	}
    365 	if (net->mtu > next_mtu) {
    366 		net->mtu = next_mtu;
    367 #if defined(__FreeBSD__) && !defined(__Userspace__)
    368 		if (net->port) {
    369 			sctp_hc_set_mtu(&net->ro._l_addr, inp->fibnum, next_mtu + sizeof(struct udphdr));
    370 		} else {
    371 			sctp_hc_set_mtu(&net->ro._l_addr, inp->fibnum, next_mtu);
    372 		}
    373 #endif
    374 	}
    375 	/* Update the association MTU */
    376 	if (stcb->asoc.smallest_mtu > next_mtu) {
    377 		sctp_pathmtu_adjustment(stcb, next_mtu, true);
    378 	}
    379 	/* Finally, start the PMTU timer if it was running before. */
    380 	if (timer_stopped) {
    381 		sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net);
    382 	}
    383 	SCTP_TCB_UNLOCK(stcb);
    384 } else {
    385 	SCTP_TCB_UNLOCK(stcb);
    386 }
    387 }
    388 #endif
    389 
    390 #if !defined(__Userspace__)
    391 #if defined(__FreeBSD__)
    392 void sctp_ctlinput(struct icmp *icmp)
    393 {
    394 struct ip *inner_ip, *outer_ip;
    395 struct sctphdr *sh;
    396 struct sctp_inpcb *inp;
    397 struct sctp_tcb *stcb;
    398 struct sctp_nets *net;
    399 struct sctp_init_chunk *ch;
    400 struct sockaddr_in src, dst;
    401 
    402 if (icmp_errmap(icmp) == 0)
    403 	return;
    404 
    405 outer_ip = (struct ip *)((caddr_t)icmp - sizeof(struct ip));
    406 inner_ip = &icmp->icmp_ip;
    407 sh = (struct sctphdr *)((caddr_t)inner_ip + (inner_ip->ip_hl << 2));
    408 memset(&src, 0, sizeof(struct sockaddr_in));
    409 src.sin_family = AF_INET;
    410 src.sin_len = sizeof(struct sockaddr_in);
    411 src.sin_port = sh->src_port;
    412 src.sin_addr = inner_ip->ip_src;
    413 memset(&dst, 0, sizeof(struct sockaddr_in));
    414 dst.sin_family = AF_INET;
    415 dst.sin_len = sizeof(struct sockaddr_in);
    416 dst.sin_port = sh->dest_port;
    417 dst.sin_addr = inner_ip->ip_dst;
    418 /*
    419  * 'dst' holds the dest of the packet that failed to be sent.
    420  * 'src' holds our local endpoint address. Thus we reverse
    421  * the dst and the src in the lookup.
    422  */
    423 inp = NULL;
    424 net = NULL;
    425 stcb = sctp_findassociation_addr_sa((struct sockaddr *)&dst,
    426                                     (struct sockaddr *)&src,
    427                                     &inp, &net, 1,
    428                                     SCTP_DEFAULT_VRFID);
    429 if ((stcb != NULL) &&
    430     (net != NULL) &&
    431     (inp != NULL)) {
    432 	/* Check the verification tag */
    433 	if (ntohl(sh->v_tag) != 0) {
    434 		/*
    435 		 * This must be the verification tag used for
    436 		 * sending out packets. We don't consider
    437 		 * packets reflecting the verification tag.
    438 		 */
    439 		if (ntohl(sh->v_tag) != stcb->asoc.peer_vtag) {
    440 			SCTP_TCB_UNLOCK(stcb);
    441 			return;
    442 		}
    443 	} else {
    444 		if (ntohs(outer_ip->ip_len) >=
    445 		    sizeof(struct ip) +
    446 		    8 + (inner_ip->ip_hl << 2) + 20) {
    447 			/*
    448 			 * In this case we can check if we
    449 			 * got an INIT chunk and if the
    450 			 * initiate tag matches.
    451 			 */
    452 			ch = (struct sctp_init_chunk *)(sh + 1);
    453 			if ((ch->ch.chunk_type != SCTP_INITIATION) ||
    454 			    (ntohl(ch->init.initiate_tag) != stcb->asoc.my_vtag)) {
    455 				SCTP_TCB_UNLOCK(stcb);
    456 				return;
    457 			}
    458 		} else {
    459 			SCTP_TCB_UNLOCK(stcb);
    460 			return;
    461 		}
    462 	}
    463 	sctp_notify(inp, stcb, net,
    464 	            icmp->icmp_type,
    465 	            icmp->icmp_code,
    466 	            ntohs(inner_ip->ip_len),
    467 	            (uint32_t)ntohs(icmp->icmp_nextmtu));
    468 } else {
    469 	if ((stcb == NULL) && (inp != NULL)) {
    470 		/* reduce ref-count */
    471 		SCTP_INP_WLOCK(inp);
    472 		SCTP_INP_DECR_REF(inp);
    473 		SCTP_INP_WUNLOCK(inp);
    474 	}
    475 	if (stcb) {
    476 		SCTP_TCB_UNLOCK(stcb);
    477 	}
    478 }
    479 }
    480 #else
    481 void
    482 #if defined(__APPLE__) && !defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) && !defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION) && !defined(APPLE_ELCAPITAN)
    483 sctp_ctlinput(int cmd, struct sockaddr *sa, void *vip, struct ifnet *ifp SCTP_UNUSED)
    484 #else
    485 sctp_ctlinput(int cmd, struct sockaddr *sa, void *vip)
    486 #endif
    487 {
    488 struct ip *inner_ip;
    489 struct sctphdr *sh;
    490 struct icmp *icmp;
    491 struct sctp_inpcb *inp;
    492 struct sctp_tcb *stcb;
    493 struct sctp_nets *net;
    494 struct sockaddr_in src, dst;
    495 
    496 #if !defined(__FreeBSD__) && !defined(__Userspace__)
    497 if (sa->sa_family != AF_INET ||
    498     ((struct sockaddr_in *)sa)->sin_addr.s_addr == INADDR_ANY) {
    499 	return;
    500 }
    501 #endif
    502 if (PRC_IS_REDIRECT(cmd)) {
    503 	vip = NULL;
    504 } else if ((unsigned)cmd >= PRC_NCMDS || inetctlerrmap[cmd] == 0) {
    505 	return;
    506 }
    507 if (vip != NULL) {
    508 	inner_ip = (struct ip *)vip;
    509 	icmp = (struct icmp *)((caddr_t)inner_ip -
    510 	    (sizeof(struct icmp) - sizeof(struct ip)));
    511 	sh = (struct sctphdr *)((caddr_t)inner_ip + (inner_ip->ip_hl << 2));
    512 	memset(&src, 0, sizeof(struct sockaddr_in));
    513 	src.sin_family = AF_INET;
    514 #ifdef HAVE_SIN_LEN
    515 	src.sin_len = sizeof(struct sockaddr_in);
    516 #endif
    517 	src.sin_port = sh->src_port;
    518 	src.sin_addr = inner_ip->ip_src;
    519 	memset(&dst, 0, sizeof(struct sockaddr_in));
    520 	dst.sin_family = AF_INET;
    521 #ifdef HAVE_SIN_LEN
    522 	dst.sin_len = sizeof(struct sockaddr_in);
    523 #endif
    524 	dst.sin_port = sh->dest_port;
    525 	dst.sin_addr = inner_ip->ip_dst;
    526 	/*
    527 	 * 'dst' holds the dest of the packet that failed to be sent.
    528 	 * 'src' holds our local endpoint address. Thus we reverse
    529 	 * the dst and the src in the lookup.
    530 	 */
    531 	inp = NULL;
    532 	net = NULL;
    533 	stcb = sctp_findassociation_addr_sa((struct sockaddr *)&dst,
    534 	                                    (struct sockaddr *)&src,
    535 	                                    &inp, &net, 1,
    536 	                                    SCTP_DEFAULT_VRFID);
    537 	if ((stcb != NULL) &&
    538 	    (net != NULL) &&
    539 	    (inp != NULL)) {
    540 		/* Check the verification tag */
    541 		if (ntohl(sh->v_tag) != 0) {
    542 			/*
    543 			 * This must be the verification tag used for
    544 			 * sending out packets. We don't consider
    545 			 * packets reflecting the verification tag.
    546 			 */
    547 			if (ntohl(sh->v_tag) != stcb->asoc.peer_vtag) {
    548 				SCTP_TCB_UNLOCK(stcb);
    549 				return;
    550 			}
    551 		} else {
    552 			SCTP_TCB_UNLOCK(stcb);
    553 			return;
    554 		}
    555 		sctp_notify(inp, stcb, net,
    556 		            icmp->icmp_type,
    557 		            icmp->icmp_code,
    558 		            inner_ip->ip_len,
    559 		            (uint32_t)ntohs(icmp->icmp_nextmtu));
    560 #if defined(__Userspace__)
    561 		if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
    562 		    (stcb->sctp_socket != NULL)) {
    563 			struct socket *upcall_socket;
    564 
    565 			upcall_socket = stcb->sctp_socket;
    566 			SOCK_LOCK(upcall_socket);
    567 			soref(upcall_socket);
    568 			SOCK_UNLOCK(upcall_socket);
    569 			if ((upcall_socket->so_upcall != NULL) &&
    570 			    (upcall_socket->so_error != 0)) {
    571 				(*upcall_socket->so_upcall)(upcall_socket, upcall_socket->so_upcallarg, M_NOWAIT);
    572 			}
    573 			ACCEPT_LOCK();
    574 			SOCK_LOCK(upcall_socket);
    575 			sorele(upcall_socket);
    576 		}
    577 #endif
    578 	} else {
    579 		if ((stcb == NULL) && (inp != NULL)) {
    580 			/* reduce ref-count */
    581 			SCTP_INP_WLOCK(inp);
    582 			SCTP_INP_DECR_REF(inp);
    583 			SCTP_INP_WUNLOCK(inp);
    584 		}
    585 		if (stcb) {
    586 			SCTP_TCB_UNLOCK(stcb);
    587 		}
    588 	}
    589 }
    590 return;
    591 }
    592 #endif
    593 #endif
    594 #endif
    595 
    596 #if defined(__FreeBSD__) && !defined(__Userspace__)
    597 static int
    598 sctp_getcred(SYSCTL_HANDLER_ARGS)
    599 {
    600 struct xucred xuc;
    601 struct sockaddr_in addrs[2];
    602 struct sctp_inpcb *inp;
    603 struct sctp_nets *net;
    604 struct sctp_tcb *stcb;
    605 int error;
    606 uint32_t vrf_id;
    607 
    608 /* FIX, for non-bsd is this right? */
    609 vrf_id = SCTP_DEFAULT_VRFID;
    610 
    611 error = priv_check(req->td, PRIV_NETINET_GETCRED);
    612 
    613 if (error)
    614 	return (error);
    615 
    616 error = SYSCTL_IN(req, addrs, sizeof(addrs));
    617 if (error)
    618 	return (error);
    619 
    620 stcb = sctp_findassociation_addr_sa(sintosa(&addrs[1]),
    621     sintosa(&addrs[0]),
    622     &inp, &net, 1, vrf_id);
    623 if (stcb == NULL || inp == NULL || inp->sctp_socket == NULL) {
    624 	if ((inp != NULL) && (stcb == NULL)) {
    625 		/* reduce ref-count */
    626 		SCTP_INP_WLOCK(inp);
    627 		SCTP_INP_DECR_REF(inp);
    628 		goto cred_can_cont;
    629 	}
    630 
    631 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT);
    632 	error = ENOENT;
    633 	goto out;
    634 }
    635 SCTP_TCB_UNLOCK(stcb);
    636 /* We use the write lock here, only
    637  * since in the error leg we need it.
    638  * If we used RLOCK, then we would have
    639  * to wlock/decr/unlock/rlock. Which
    640  * in theory could create a hole. Better
    641  * to use higher wlock.
    642  */
    643 SCTP_INP_WLOCK(inp);
    644 cred_can_cont:
    645 error = cr_canseesocket(req->td->td_ucred, inp->sctp_socket);
    646 if (error) {
    647 	SCTP_INP_WUNLOCK(inp);
    648 	goto out;
    649 }
    650 cru2x(inp->sctp_socket->so_cred, &xuc);
    651 SCTP_INP_WUNLOCK(inp);
    652 error = SYSCTL_OUT(req, &xuc, sizeof(struct xucred));
    653 out:
    654 return (error);
    655 }
    656 
    657 SYSCTL_PROC(_net_inet_sctp, OID_AUTO, getcred,
    658    CTLTYPE_OPAQUE | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
    659    0, 0, sctp_getcred, "S,ucred",
    660    "Get the ucred of a SCTP connection");
    661 #endif
    662 
    663 #if defined(__FreeBSD__) && !defined(__Userspace__)
    664 void
    665 #else
    666 int
    667 #endif
    668 sctp_abort(struct socket *so)
    669 {
    670 #if defined(__FreeBSD__) && !defined(__Userspace__)
    671 struct epoch_tracker et;
    672 #endif
    673 struct sctp_inpcb *inp;
    674 
    675 inp = (struct sctp_inpcb *)so->so_pcb;
    676 if (inp == NULL) {
    677 #if defined(__FreeBSD__) && !defined(__Userspace__)
    678 	return;
    679 #else
    680 	SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
    681 	return (EINVAL);
    682 #endif
    683 }
    684 
    685 SCTP_INP_WLOCK(inp);
    686 #if defined(__FreeBSD__) && !defined(__Userspace__)
    687 NET_EPOCH_ENTER(et);
    688 #endif
    689 #ifdef SCTP_LOG_CLOSING
    690 sctp_log_closing(inp, NULL, 17);
    691 #endif
    692 if (((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0)) {
    693 	inp->sctp_flags |= SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_CLOSE_IP;
    694 #ifdef SCTP_LOG_CLOSING
    695 	sctp_log_closing(inp, NULL, 16);
    696 #endif
    697 	SCTP_INP_WUNLOCK(inp);
    698 	sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT,
    699 	                SCTP_CALLED_AFTER_CMPSET_OFCLOSE);
    700 	SOCK_LOCK(so);
    701 #if defined(__FreeBSD__) && !defined(__Userspace__)
    702 	KASSERT(!SOLISTENING(so),
    703 	        ("sctp_abort: called on listening socket %p", so));
    704 #endif
    705 	SCTP_SB_CLEAR(so->so_snd);
    706 	SCTP_SB_CLEAR(so->so_rcv);
    707 #if defined(__APPLE__) && !defined(__Userspace__)
    708 	so->so_usecount--;
    709 #else
    710 	/* Now null out the reference, we are completely detached. */
    711 	so->so_pcb = NULL;
    712 #endif
    713 	SOCK_UNLOCK(so);
    714 } else {
    715 	SCTP_INP_WUNLOCK(inp);
    716 }
    717 #if defined(__FreeBSD__) && !defined(__Userspace__)
    718 NET_EPOCH_EXIT(et);
    719 #else
    720 return (0);
    721 #endif
    722 }
    723 
    724 #ifdef INET
    725 #if defined(__Userspace__)
    726 int
    727 #else
    728 static int
    729 #endif
    730 #if defined(__Userspace__)
    731 sctp_attach(struct socket *so, int proto SCTP_UNUSED, uint32_t vrf_id)
    732 #elif defined(__FreeBSD__)
    733 sctp_attach(struct socket *so, int proto SCTP_UNUSED, struct thread *p SCTP_UNUSED)
    734 #elif defined(_WIN32)
    735 sctp_attach(struct socket *so, int proto SCTP_UNUSED, PKTHREAD p SCTP_UNUSED)
    736 #else
    737 sctp_attach(struct socket *so, int proto SCTP_UNUSED, struct proc *p SCTP_UNUSED)
    738 #endif
    739 {
    740 struct sctp_inpcb *inp;
    741 struct inpcb *ip_inp;
    742 int error;
    743 #if !defined(__Userspace__)
    744 uint32_t vrf_id = SCTP_DEFAULT_VRFID;
    745 #endif
    746 
    747 inp = (struct sctp_inpcb *)so->so_pcb;
    748 if (inp != NULL) {
    749 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
    750 	return (EINVAL);
    751 }
    752 if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
    753 	error = SCTP_SORESERVE(so, SCTP_BASE_SYSCTL(sctp_sendspace), SCTP_BASE_SYSCTL(sctp_recvspace));
    754 	if (error) {
    755 		return (error);
    756 	}
    757 }
    758 error = sctp_inpcb_alloc(so, vrf_id);
    759 if (error) {
    760 	return (error);
    761 }
    762 inp = (struct sctp_inpcb *)so->so_pcb;
    763 SCTP_INP_WLOCK(inp);
    764 inp->sctp_flags &= ~SCTP_PCB_FLAGS_BOUND_V6;	/* I'm not v6! */
    765 ip_inp = &inp->ip_inp.inp;
    766 ip_inp->inp_vflag |= INP_IPV4;
    767 ip_inp->inp_ip_ttl = MODULE_GLOBAL(ip_defttl);
    768 SCTP_INP_WUNLOCK(inp);
    769 return (0);
    770 }
    771 
    772 #if defined(__Userspace__)
    773 int
    774 sctp_bind(struct socket *so, struct sockaddr *addr) {
    775 void *p = NULL;
    776 #elif defined(__FreeBSD__)
    777 static int
    778 sctp_bind(struct socket *so, struct sockaddr *addr, struct thread *p)
    779 {
    780 #elif defined(__APPLE__)
    781 static int
    782 sctp_bind(struct socket *so, struct sockaddr *addr, struct proc *p) {
    783 #elif defined(_WIN32)
    784 static int
    785 sctp_bind(struct socket *so, struct sockaddr *addr, PKTHREAD p) {
    786 #else
    787 static int
    788 sctp_bind(struct socket *so, struct mbuf *nam, struct proc *p)
    789 {
    790 struct sockaddr *addr = nam ? mtod(nam, struct sockaddr *): NULL;
    791 
    792 #endif
    793 struct sctp_inpcb *inp;
    794 
    795 inp = (struct sctp_inpcb *)so->so_pcb;
    796 if (inp == NULL) {
    797 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
    798 	return (EINVAL);
    799 }
    800 if (addr != NULL) {
    801 #ifdef HAVE_SA_LEN
    802 	if ((addr->sa_family != AF_INET) ||
    803 	    (addr->sa_len != sizeof(struct sockaddr_in))) {
    804 #else
    805 	if (addr->sa_family != AF_INET) {
    806 #endif
    807 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
    808 		return (EINVAL);
    809 	}
    810 }
    811 return (sctp_inpcb_bind(so, addr, NULL, p));
    812 }
    813 
    814 #endif
    815 #if defined(__Userspace__)
    816 
    817 int
    818 sctpconn_attach(struct socket *so, int proto SCTP_UNUSED, uint32_t vrf_id)
    819 {
    820 struct sctp_inpcb *inp;
    821 struct inpcb *ip_inp;
    822 int error;
    823 
    824 inp = (struct sctp_inpcb *)so->so_pcb;
    825 if (inp != NULL) {
    826 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
    827 	return (EINVAL);
    828 }
    829 if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
    830 	error = SCTP_SORESERVE(so, SCTP_BASE_SYSCTL(sctp_sendspace), SCTP_BASE_SYSCTL(sctp_recvspace));
    831 	if (error) {
    832 		return (error);
    833 	}
    834 }
    835 error = sctp_inpcb_alloc(so, vrf_id);
    836 if (error) {
    837 	return (error);
    838 }
    839 inp = (struct sctp_inpcb *)so->so_pcb;
    840 SCTP_INP_WLOCK(inp);
    841 inp->sctp_flags &= ~SCTP_PCB_FLAGS_BOUND_V6;
    842 inp->sctp_flags |= SCTP_PCB_FLAGS_BOUND_CONN;
    843 ip_inp = &inp->ip_inp.inp;
    844 ip_inp->inp_vflag |= INP_CONN;
    845 ip_inp->inp_ip_ttl = MODULE_GLOBAL(ip_defttl);
    846 SCTP_INP_WUNLOCK(inp);
    847 return (0);
    848 }
    849 
    850 int
    851 sctpconn_bind(struct socket *so, struct sockaddr *addr)
    852 {
    853 struct sctp_inpcb *inp;
    854 
    855 inp = (struct sctp_inpcb *)so->so_pcb;
    856 if (inp == NULL) {
    857 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
    858 	return (EINVAL);
    859 }
    860 if (addr != NULL) {
    861 #ifdef HAVE_SA_LEN
    862 	if ((addr->sa_family != AF_CONN) ||
    863 	    (addr->sa_len != sizeof(struct sockaddr_conn))) {
    864 #else
    865 	if (addr->sa_family != AF_CONN) {
    866 #endif
    867 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
    868 		return (EINVAL);
    869 	}
    870 }
    871 return (sctp_inpcb_bind(so, addr, NULL, NULL));
    872 }
    873 
    874 #endif
    875 #if defined(__FreeBSD__) || defined(_WIN32) || defined(__Userspace__)
    876 void
    877 sctp_close(struct socket *so)
    878 {
    879 #if defined(__FreeBSD__) && !defined(__Userspace__)
    880 struct epoch_tracker et;
    881 #endif
    882 struct sctp_inpcb *inp;
    883 
    884 inp = (struct sctp_inpcb *)so->so_pcb;
    885 if (inp == NULL)
    886 	return;
    887 
    888 /* Inform all the lower layer assoc that we
    889  * are done.
    890  */
    891 SCTP_INP_WLOCK(inp);
    892 #if defined(__FreeBSD__) && !defined(__Userspace__)
    893 NET_EPOCH_ENTER(et);
    894 #endif
    895 #ifdef SCTP_LOG_CLOSING
    896 sctp_log_closing(inp, NULL, 17);
    897 #endif
    898 if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) {
    899 	inp->sctp_flags |= SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_CLOSE_IP;
    900 #if defined(__Userspace__)
    901 	if (((so->so_options & SCTP_SO_LINGER) && (so->so_linger == 0)) ||
    902 #else
    903 	if (((so->so_options & SO_LINGER) && (so->so_linger == 0)) ||
    904 #endif
    905 	    (SCTP_SBAVAIL(&so->so_rcv) > 0)) {
    906 #ifdef SCTP_LOG_CLOSING
    907 		sctp_log_closing(inp, NULL, 13);
    908 #endif
    909 		SCTP_INP_WUNLOCK(inp);
    910 		sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT,
    911 		                SCTP_CALLED_AFTER_CMPSET_OFCLOSE);
    912 	} else {
    913 #ifdef SCTP_LOG_CLOSING
    914 		sctp_log_closing(inp, NULL, 14);
    915 #endif
    916 		SCTP_INP_WUNLOCK(inp);
    917 		sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_GRACEFUL_CLOSE,
    918 		                SCTP_CALLED_AFTER_CMPSET_OFCLOSE);
    919 	}
    920 	/* The socket is now detached, no matter what
    921 	 * the state of the SCTP association.
    922 	 */
    923 	SOCK_LOCK(so);
    924 #if defined(__FreeBSD__) && !defined(__Userspace__)
    925 	if (!SOLISTENING(so)) {
    926 		SCTP_SB_CLEAR(so->so_snd);
    927 		SCTP_SB_CLEAR(so->so_rcv);
    928 	}
    929 #else
    930 	SCTP_SB_CLEAR(so->so_snd);
    931 	SCTP_SB_CLEAR(so->so_rcv);
    932 #endif
    933 #if !(defined(__APPLE__) && !defined(__Userspace__))
    934 	/* Now null out the reference, we are completely detached. */
    935 	so->so_pcb = NULL;
    936 #endif
    937 	SOCK_UNLOCK(so);
    938 } else {
    939 	SCTP_INP_WUNLOCK(inp);
    940 }
    941 #if defined(__FreeBSD__) && !defined(__Userspace__)
    942 NET_EPOCH_EXIT(et);
    943 #endif
    944 }
    945 #else
    946 int
    947 sctp_detach(struct socket *so)
    948 {
    949 struct sctp_inpcb *inp;
    950 uint32_t flags;
    951 
    952 inp = (struct sctp_inpcb *)so->so_pcb;
    953 if (inp == NULL) {
    954 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
    955 	return (EINVAL);
    956 }
    957 sctp_must_try_again:
    958 flags = inp->sctp_flags;
    959 #ifdef SCTP_LOG_CLOSING
    960 sctp_log_closing(inp, NULL, 17);
    961 #endif
    962 if (((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
    963     (atomic_cmpset_int(&inp->sctp_flags, flags, (flags | SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_CLOSE_IP)))) {
    964 	if (((so->so_options & SO_LINGER) && (so->so_linger == 0)) ||
    965 	    (SCTP_SBAVAIL(&so->so_rcv) > 0)) {
    966 #ifdef SCTP_LOG_CLOSING
    967 		sctp_log_closing(inp, NULL, 13);
    968 #endif
    969 		sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT,
    970 		                SCTP_CALLED_AFTER_CMPSET_OFCLOSE);
    971 	} else {
    972 #ifdef SCTP_LOG_CLOSING
    973 		sctp_log_closing(inp, NULL, 13);
    974 #endif
    975 		sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_GRACEFUL_CLOSE,
    976 		                SCTP_CALLED_AFTER_CMPSET_OFCLOSE);
    977 	}
    978 	/* The socket is now detached, no matter what
    979 	 * the state of the SCTP association.
    980 	 */
    981 	SCTP_SB_CLEAR(so->so_snd);
    982 	/* same for the rcv ones, they are only
    983 	 * here for the accounting/select.
    984 	 */
    985 	SCTP_SB_CLEAR(so->so_rcv);
    986 #if !(defined(__APPLE__) && !defined(__Userspace__))
    987 	/* Now disconnect */
    988 	so->so_pcb = NULL;
    989 #endif
    990 } else {
    991 	flags = inp->sctp_flags;
    992 	if ((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) {
    993 		goto sctp_must_try_again;
    994 	}
    995 }
    996 return (0);
    997 }
    998 #endif
    999 
   1000 #if defined(__Userspace__)
   1001 /* __Userspace__ is not calling sctp_sendm */
   1002 #endif
   1003 #if !(defined(_WIN32) && !defined(__Userspace__))
   1004 int
   1005 #if defined(__FreeBSD__) && !defined(__Userspace__)
   1006 sctp_sendm(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
   1007    struct mbuf *control, struct thread *p);
   1008 
   1009 #else
   1010 sctp_sendm(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
   1011    struct mbuf *control, struct proc *p);
   1012 
   1013 #endif
   1014 int
   1015 #if defined(__FreeBSD__) && !defined(__Userspace__)
   1016 sctp_sendm(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
   1017    struct mbuf *control, struct thread *p)
   1018 {
   1019 #else
   1020 sctp_sendm(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
   1021    struct mbuf *control, struct proc *p)
   1022 {
   1023 #endif
   1024 struct sctp_inpcb *inp;
   1025 int error;
   1026 
   1027 inp = (struct sctp_inpcb *)so->so_pcb;
   1028 if (inp == NULL) {
   1029 	if (control) {
   1030 		sctp_m_freem(control);
   1031 		control = NULL;
   1032 	}
   1033 	SCTP_LTRACE_ERR_RET_PKT(m, inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   1034 	sctp_m_freem(m);
   1035 	return (EINVAL);
   1036 }
   1037 /* Got to have an to address if we are NOT a connected socket */
   1038 if ((addr == NULL) &&
   1039     ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) ||
   1040     (inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE))) {
   1041 	goto connected_type;
   1042 }
   1043 
   1044 error = 0;
   1045 if (addr == NULL) {
   1046 	SCTP_LTRACE_ERR_RET_PKT(m, inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EDESTADDRREQ);
   1047 	error = EDESTADDRREQ;
   1048 } else if (addr->sa_family != AF_INET) {
   1049 	SCTP_LTRACE_ERR_RET_PKT(m, inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EAFNOSUPPORT);
   1050 	error = EAFNOSUPPORT;
   1051 #if defined(HAVE_SA_LEN)
   1052 } else if (addr->sa_len != sizeof(struct sockaddr_in)) {
   1053 	SCTP_LTRACE_ERR_RET_PKT(m, inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   1054 	error = EINVAL;
   1055 #endif
   1056 }
   1057 if (error != 0) {
   1058 	sctp_m_freem(m);
   1059 	if (control) {
   1060 		sctp_m_freem(control);
   1061 		control = NULL;
   1062 	}
   1063 	return (error);
   1064 }
   1065 connected_type:
   1066 /* now what about control */
   1067 if (control) {
   1068 	if (inp->control) {
   1069 		sctp_m_freem(inp->control);
   1070 		inp->control = NULL;
   1071 	}
   1072 	inp->control = control;
   1073 }
   1074 /* Place the data */
   1075 if (inp->pkt) {
   1076 	SCTP_BUF_NEXT(inp->pkt_last) = m;
   1077 	inp->pkt_last = m;
   1078 } else {
   1079 	inp->pkt_last = inp->pkt = m;
   1080 }
   1081 if (
   1082 #if (defined(__FreeBSD__) || defined(__APPLE__)) && !defined(__Userspace__)
   1083 /* FreeBSD uses a flag passed */
   1084     ((flags & PRUS_MORETOCOME) == 0)
   1085 #else
   1086     1			/* Open BSD does not have any "more to come"
   1087 			 * indication */
   1088 #endif
   1089     ) {
   1090 	/*
   1091 	 * note with the current version this code will only be used
   1092 	 * by OpenBSD-- NetBSD, FreeBSD, and MacOS have methods for
   1093 	 * re-defining sosend to use the sctp_sosend. One can
   1094 	 * optionally switch back to this code (by changing back the
   1095 	 * definitions) but this is not advisable. This code is used
   1096 	 * by FreeBSD when sending a file with sendfile() though.
   1097 	 */
   1098 #if defined(__FreeBSD__) && !defined(__Userspace__)
   1099 	struct epoch_tracker et;
   1100 #endif
   1101 	int ret;
   1102 
   1103 #if defined(__FreeBSD__) && !defined(__Userspace__)
   1104 NET_EPOCH_ENTER(et);
   1105 #endif
   1106 	ret = sctp_output(inp, inp->pkt, addr, inp->control, p, flags);
   1107 #if defined(__FreeBSD__) && !defined(__Userspace__)
   1108 NET_EPOCH_EXIT(et);
   1109 #endif
   1110 	inp->pkt = NULL;
   1111 	inp->control = NULL;
   1112 	return (ret);
   1113 } else {
   1114 	return (0);
   1115 }
   1116 }
   1117 #endif
   1118 
   1119 int
   1120 sctp_disconnect(struct socket *so)
   1121 {
   1122 #if defined(__FreeBSD__) && !defined(__Userspace__)
   1123 struct epoch_tracker et;
   1124 #endif
   1125 struct sctp_inpcb *inp;
   1126 struct sctp_association *asoc;
   1127 struct sctp_tcb *stcb;
   1128 
   1129 inp = (struct sctp_inpcb *)so->so_pcb;
   1130 if (inp == NULL) {
   1131 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTCONN);
   1132 	return (ENOTCONN);
   1133 }
   1134 SCTP_INP_RLOCK(inp);
   1135 KASSERT(inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE ||
   1136         inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL,
   1137         ("Not a one-to-one style socket"));
   1138 stcb = LIST_FIRST(&inp->sctp_asoc_list);
   1139 if (stcb == NULL) {
   1140 	SCTP_INP_RUNLOCK(inp);
   1141 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTCONN);
   1142 	return (ENOTCONN);
   1143 }
   1144 SCTP_TCB_LOCK(stcb);
   1145 asoc = &stcb->asoc;
   1146 if (asoc->state & SCTP_STATE_ABOUT_TO_BE_FREED) {
   1147 	/* We are about to be freed, out of here */
   1148 	SCTP_TCB_UNLOCK(stcb);
   1149 	SCTP_INP_RUNLOCK(inp);
   1150 	return (0);
   1151 }
   1152 #if defined(__FreeBSD__) && !defined(__Userspace__)
   1153 NET_EPOCH_ENTER(et);
   1154 #endif
   1155 #if defined(__Userspace__)
   1156 if (((so->so_options & SCTP_SO_LINGER) && (so->so_linger == 0)) ||
   1157     (SCTP_SBAVAIL(&so->so_rcv) > 0)) {
   1158 #else
   1159 if (((so->so_options & SO_LINGER) && (so->so_linger == 0)) ||
   1160     (SCTP_SBAVAIL(&so->so_rcv) > 0)) {
   1161 #endif
   1162 	if (SCTP_GET_STATE(stcb) != SCTP_STATE_COOKIE_WAIT) {
   1163 		/* Left with Data unread */
   1164 		struct mbuf *op_err;
   1165 
   1166 		op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
   1167 		sctp_send_abort_tcb(stcb, op_err, SCTP_SO_LOCKED);
   1168 		SCTP_STAT_INCR_COUNTER32(sctps_aborted);
   1169 	}
   1170 	SCTP_INP_RUNLOCK(inp);
   1171 	if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
   1172 	    (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
   1173 		SCTP_STAT_DECR_GAUGE32(sctps_currestab);
   1174 	}
   1175 	(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
   1176 	                      SCTP_FROM_SCTP_USRREQ + SCTP_LOC_3);
   1177 	/* No unlock tcb assoc is gone */
   1178 #if defined(__FreeBSD__) && !defined(__Userspace__)
   1179 	NET_EPOCH_EXIT(et);
   1180 #endif
   1181 	return (0);
   1182 }
   1183 if (TAILQ_EMPTY(&asoc->send_queue) &&
   1184     TAILQ_EMPTY(&asoc->sent_queue) &&
   1185     (asoc->stream_queue_cnt == 0)) {
   1186 	/* there is nothing queued to send, so done */
   1187 	if ((*asoc->ss_functions.sctp_ss_is_user_msgs_incomplete)(stcb, asoc)) {
   1188 		goto abort_anyway;
   1189 	}
   1190 	if ((SCTP_GET_STATE(stcb) != SCTP_STATE_SHUTDOWN_SENT) &&
   1191 	    (SCTP_GET_STATE(stcb) != SCTP_STATE_SHUTDOWN_ACK_SENT)) {
   1192 		/* only send SHUTDOWN 1st time thru */
   1193 		struct sctp_nets *netp;
   1194 
   1195 		if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
   1196 		    (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
   1197 			SCTP_STAT_DECR_GAUGE32(sctps_currestab);
   1198 		}
   1199 		SCTP_SET_STATE(stcb, SCTP_STATE_SHUTDOWN_SENT);
   1200 		sctp_stop_timers_for_shutdown(stcb);
   1201 		if (stcb->asoc.alternate) {
   1202 			netp = stcb->asoc.alternate;
   1203 		} else {
   1204 			netp = stcb->asoc.primary_destination;
   1205 		}
   1206 		sctp_send_shutdown(stcb,netp);
   1207 		sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
   1208 		                 stcb->sctp_ep, stcb, netp);
   1209 		sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
   1210 		                 stcb->sctp_ep, stcb, NULL);
   1211 		sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_CLOSING, SCTP_SO_LOCKED);
   1212 	}
   1213 } else {
   1214 	/*
   1215 	 * we still got (or just got) data to send,
   1216 	 * so set SHUTDOWN_PENDING
   1217 	 */
   1218 	/*
   1219 	 * XXX sockets draft says that SCTP_EOF
   1220 	 * should be sent with no data. currently,
   1221 	 * we will allow user data to be sent first
   1222 	 * and move to SHUTDOWN-PENDING
   1223 	 */
   1224 	SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_SHUTDOWN_PENDING);
   1225 	if ((*asoc->ss_functions.sctp_ss_is_user_msgs_incomplete)(stcb, asoc)) {
   1226 		SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_PARTIAL_MSG_LEFT);
   1227 	}
   1228 	if (TAILQ_EMPTY(&asoc->send_queue) &&
   1229 	    TAILQ_EMPTY(&asoc->sent_queue) &&
   1230 	    (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT)) {
   1231 		struct mbuf *op_err;
   1232 	abort_anyway:
   1233 		op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
   1234 		stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_USRREQ + SCTP_LOC_4;
   1235 		sctp_send_abort_tcb(stcb, op_err, SCTP_SO_LOCKED);
   1236 		SCTP_STAT_INCR_COUNTER32(sctps_aborted);
   1237 		if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
   1238 		    (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
   1239 			SCTP_STAT_DECR_GAUGE32(sctps_currestab);
   1240 		}
   1241 		SCTP_INP_RUNLOCK(inp);
   1242 		(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
   1243 		                      SCTP_FROM_SCTP_USRREQ + SCTP_LOC_5);
   1244 #if defined(__FreeBSD__) && !defined(__Userspace__)
   1245 		NET_EPOCH_EXIT(et);
   1246 #endif
   1247 		return (0);
   1248 	} else {
   1249 		sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_CLOSING, SCTP_SO_LOCKED);
   1250 	}
   1251 }
   1252 soisdisconnecting(so);
   1253 #if defined(__FreeBSD__) && !defined(__Userspace__)
   1254 NET_EPOCH_EXIT(et);
   1255 #endif
   1256 SCTP_TCB_UNLOCK(stcb);
   1257 SCTP_INP_RUNLOCK(inp);
   1258 return (0);
   1259 }
   1260 
   1261 #if defined(__FreeBSD__) || defined(_WIN32) || defined(__Userspace__)
   1262 int
   1263 sctp_flush(struct socket *so, int how)
   1264 {
   1265 #if defined(__FreeBSD__) && !defined(__Userspace__)
   1266 struct epoch_tracker et;
   1267 #endif
   1268 struct sctp_tcb *stcb;
   1269 struct sctp_queued_to_read *control, *ncontrol;
   1270 struct sctp_inpcb *inp;
   1271 struct mbuf *m, *op_err;
   1272 bool need_to_abort = false;
   1273 
   1274 /*
   1275  * For 1-to-1 style sockets, flush the read queue and trigger an
   1276  * ungraceful shutdown of the association, if and only if user messages
   1277  * are lost. Loosing notifications does not need to be signalled to the
   1278  * peer.
   1279  */
   1280 if (how == PRU_FLUSH_WR) {
   1281 	/* This function is only relevant for the read directions. */
   1282 	return (0);
   1283 }
   1284 inp = (struct sctp_inpcb *)so->so_pcb;
   1285 if (inp == NULL) {
   1286 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   1287 	return (EINVAL);
   1288 }
   1289 SCTP_INP_WLOCK(inp);
   1290 if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) {
   1291 	/* For 1-to-many style sockets this function does nothing. */
   1292 	SCTP_INP_WUNLOCK(inp);
   1293 	return (0);
   1294 }
   1295 stcb = LIST_FIRST(&inp->sctp_asoc_list);
   1296 if (stcb != NULL) {
   1297 	SCTP_TCB_LOCK(stcb);
   1298 }
   1299 SCTP_INP_READ_LOCK(inp);
   1300 inp->sctp_flags |= SCTP_PCB_FLAGS_SOCKET_CANT_READ;
   1301 SOCK_LOCK(so);
   1302 TAILQ_FOREACH_SAFE(control, &inp->read_queue, next, ncontrol) {
   1303 	if ((control->spec_flags & M_NOTIFICATION) == 0) {
   1304 		need_to_abort = true;
   1305 	}
   1306 	TAILQ_REMOVE(&inp->read_queue, control, next);
   1307 	control->on_read_q = 0;
   1308 	for (m = control->data; m; m = SCTP_BUF_NEXT(m)) {
   1309 		sctp_sbfree(control, control->stcb, &so->so_rcv, m);
   1310 	}
   1311 	if (control->on_strm_q == 0) {
   1312 		sctp_free_remote_addr(control->whoFrom);
   1313 		if (control->data) {
   1314 			sctp_m_freem(control->data);
   1315 			control->data = NULL;
   1316 		}
   1317 		sctp_free_a_readq(stcb, control);
   1318 	} else {
   1319 		if (stcb != NULL) {
   1320 			stcb->asoc.size_on_all_streams += control->length;
   1321 		}
   1322 	}
   1323 }
   1324 SOCK_UNLOCK(so);
   1325 SCTP_INP_READ_UNLOCK(inp);
   1326 if (need_to_abort && (stcb != NULL)) {
   1327 	inp->last_abort_code = SCTP_FROM_SCTP_USRREQ + SCTP_LOC_6;
   1328 	SCTP_INP_WUNLOCK(inp);
   1329 	op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, "");
   1330 #if defined(__FreeBSD__) && !defined(__Userspace__)
   1331 	NET_EPOCH_ENTER(et);
   1332 #endif
   1333 	sctp_abort_an_association(inp, stcb, op_err, false, SCTP_SO_LOCKED);
   1334 #if defined(__FreeBSD__) && !defined(__Userspace__)
   1335 	NET_EPOCH_EXIT(et);
   1336 #endif
   1337 	return (ECONNABORTED);
   1338 }
   1339 if (stcb != NULL) {
   1340 	SCTP_TCB_UNLOCK(stcb);
   1341 }
   1342 SCTP_INP_WUNLOCK(inp);
   1343 return (0);
   1344 }
   1345 #endif
   1346 
   1347 int
   1348 sctp_shutdown(struct socket *so)
   1349 {
   1350 struct sctp_inpcb *inp;
   1351 
   1352 inp = (struct sctp_inpcb *)so->so_pcb;
   1353 if (inp == NULL) {
   1354 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   1355 	return (EINVAL);
   1356 }
   1357 SCTP_INP_RLOCK(inp);
   1358 /* For UDP model this is a invalid call */
   1359 if (!((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   1360       (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL))) {
   1361 	/* Restore the flags that the soshutdown took away. */
   1362 #if (defined(__FreeBSD__) || defined(_WIN32)) && !defined(__Userspace__)
   1363 	SOCKBUF_LOCK(&so->so_rcv);
   1364 	so->so_rcv.sb_state &= ~SBS_CANTRCVMORE;
   1365 	SOCKBUF_UNLOCK(&so->so_rcv);
   1366 #else
   1367 	SOCK_LOCK(so);
   1368 	so->so_state &= ~SS_CANTRCVMORE;
   1369 	SOCK_UNLOCK(so);
   1370 #endif
   1371 	/* This proc will wakeup for read and do nothing (I hope) */
   1372 	SCTP_INP_RUNLOCK(inp);
   1373 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP);
   1374 	return (EOPNOTSUPP);
   1375 } else {
   1376 	/*
   1377 	 * Ok, if we reach here its the TCP model and it is either
   1378 	 * a SHUT_WR or SHUT_RDWR.
   1379 	 * This means we put the shutdown flag against it.
   1380 	 */
   1381 #if defined(__FreeBSD__) && !defined(__Userspace__)
   1382 	struct epoch_tracker et;
   1383 #endif
   1384 	struct sctp_tcb *stcb;
   1385 	struct sctp_association *asoc;
   1386 	struct sctp_nets *netp;
   1387 
   1388 	if ((so->so_state &
   1389 	     (SS_ISCONNECTED|SS_ISCONNECTING|SS_ISDISCONNECTING)) == 0) {
   1390 		SCTP_INP_RUNLOCK(inp);
   1391 		return (ENOTCONN);
   1392 	}
   1393 	socantsendmore(so);
   1394 
   1395 	stcb = LIST_FIRST(&inp->sctp_asoc_list);
   1396 	if (stcb == NULL) {
   1397 		/*
   1398 		 * Ok, we hit the case that the shutdown call was
   1399 		 * made after an abort or something. Nothing to do
   1400 		 * now.
   1401 		 */
   1402 		SCTP_INP_RUNLOCK(inp);
   1403 		return (0);
   1404 	}
   1405 	SCTP_TCB_LOCK(stcb);
   1406 	asoc = &stcb->asoc;
   1407 	if (asoc->state & SCTP_STATE_ABOUT_TO_BE_FREED) {
   1408 		SCTP_TCB_UNLOCK(stcb);
   1409 		SCTP_INP_RUNLOCK(inp);
   1410 		return (0);
   1411 	}
   1412 	if ((SCTP_GET_STATE(stcb) != SCTP_STATE_COOKIE_WAIT) &&
   1413 	    (SCTP_GET_STATE(stcb) != SCTP_STATE_COOKIE_ECHOED) &&
   1414 	    (SCTP_GET_STATE(stcb) != SCTP_STATE_OPEN)) {
   1415 		/* If we are not in or before ESTABLISHED, there is
   1416 		 * no protocol action required.
   1417 		 */
   1418 		SCTP_TCB_UNLOCK(stcb);
   1419 		SCTP_INP_RUNLOCK(inp);
   1420 		return (0);
   1421 	}
   1422 #if defined(__FreeBSD__) && !defined(__Userspace__)
   1423 	NET_EPOCH_ENTER(et);
   1424 #endif
   1425 	if (stcb->asoc.alternate) {
   1426 		netp = stcb->asoc.alternate;
   1427 	} else {
   1428 		netp = stcb->asoc.primary_destination;
   1429 	}
   1430 	if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) &&
   1431 	    TAILQ_EMPTY(&asoc->send_queue) &&
   1432 	    TAILQ_EMPTY(&asoc->sent_queue) &&
   1433 	    (asoc->stream_queue_cnt == 0)) {
   1434 		if ((*asoc->ss_functions.sctp_ss_is_user_msgs_incomplete)(stcb, asoc)) {
   1435 			goto abort_anyway;
   1436 		}
   1437 		/* there is nothing queued to send, so I'm done... */
   1438 		SCTP_STAT_DECR_GAUGE32(sctps_currestab);
   1439 		SCTP_SET_STATE(stcb, SCTP_STATE_SHUTDOWN_SENT);
   1440 		sctp_stop_timers_for_shutdown(stcb);
   1441 		sctp_send_shutdown(stcb, netp);
   1442 		sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
   1443 		                 stcb->sctp_ep, stcb, netp);
   1444 		sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
   1445 		                 stcb->sctp_ep, stcb, NULL);
   1446 	} else {
   1447 		/*
   1448 		 * We still got (or just got) data to send, so set
   1449 		 * SHUTDOWN_PENDING.
   1450 		 */
   1451 		SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_SHUTDOWN_PENDING);
   1452 		if ((*asoc->ss_functions.sctp_ss_is_user_msgs_incomplete)(stcb, asoc)) {
   1453 			SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_PARTIAL_MSG_LEFT);
   1454 		}
   1455 		if (TAILQ_EMPTY(&asoc->send_queue) &&
   1456 		    TAILQ_EMPTY(&asoc->sent_queue) &&
   1457 		    (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT)) {
   1458 			struct mbuf *op_err;
   1459 		abort_anyway:
   1460 			op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
   1461 			stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_USRREQ + SCTP_LOC_6;
   1462 			SCTP_INP_RUNLOCK(inp);
   1463 			sctp_abort_an_association(stcb->sctp_ep, stcb,
   1464 			                          op_err, false, SCTP_SO_LOCKED);
   1465 #if defined(__FreeBSD__) && !defined(__Userspace__)
   1466 			NET_EPOCH_EXIT(et);
   1467 #endif
   1468 			return (0);
   1469 		}
   1470 	}
   1471 	/* XXX: Why do this in the case where we have still data queued? */
   1472 	sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_CLOSING, SCTP_SO_LOCKED);
   1473 	SCTP_TCB_UNLOCK(stcb);
   1474 	SCTP_INP_RUNLOCK(inp);
   1475 #if defined(__FreeBSD__) && !defined(__Userspace__)
   1476 	NET_EPOCH_EXIT(et);
   1477 #endif
   1478 	return (0);
   1479 }
   1480 }
   1481 
   1482 /*
   1483 * copies a "user" presentable address and removes embedded scope, etc.
   1484 * returns 0 on success, 1 on error
   1485 */
   1486 static uint32_t
   1487 sctp_fill_user_address(struct sockaddr *dst, struct sockaddr *src)
   1488 {
   1489 #ifdef INET6
   1490 #if defined(SCTP_EMBEDDED_V6_SCOPE)
   1491 struct sockaddr_in6 lsa6;
   1492 
   1493 src = (struct sockaddr *)sctp_recover_scope((struct sockaddr_in6 *)src,
   1494     &lsa6);
   1495 #endif
   1496 #endif
   1497 #ifdef HAVE_SA_LEN
   1498 memcpy(dst, src, src->sa_len);
   1499 #else
   1500 switch (src->sa_family) {
   1501 #ifdef INET
   1502 case AF_INET:
   1503 	memcpy(dst, src, sizeof(struct sockaddr_in));
   1504 	break;
   1505 #endif
   1506 #ifdef INET6
   1507 case AF_INET6:
   1508 	memcpy(dst, src, sizeof(struct sockaddr_in6));
   1509 	break;
   1510 #endif
   1511 #if defined(__Userspace__)
   1512 case AF_CONN:
   1513 	memcpy(dst, src, sizeof(struct sockaddr_conn));
   1514 	break;
   1515 #endif
   1516 default:
   1517 	/* TSNH */
   1518 	break;
   1519 }
   1520 #endif
   1521 return (0);
   1522 }
   1523 
   1524 static size_t
   1525 sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp,
   1526                           struct sctp_tcb *stcb,
   1527                           size_t limit,
   1528                           struct sockaddr *addr,
   1529                           uint32_t vrf_id)
   1530 {
   1531 struct sctp_ifn *sctp_ifn;
   1532 struct sctp_ifa *sctp_ifa;
   1533 size_t actual;
   1534 int loopback_scope;
   1535 #if defined(INET)
   1536 int ipv4_local_scope, ipv4_addr_legal;
   1537 #endif
   1538 #if defined(INET6)
   1539 int local_scope, site_scope, ipv6_addr_legal;
   1540 #endif
   1541 #if defined(__Userspace__)
   1542 int conn_addr_legal;
   1543 #endif
   1544 struct sctp_vrf *vrf;
   1545 
   1546 SCTP_IPI_ADDR_LOCK_ASSERT();
   1547 actual = 0;
   1548 if (limit == 0)
   1549 	return (actual);
   1550 
   1551 if (stcb) {
   1552 	/* Turn on all the appropriate scope */
   1553 	loopback_scope = stcb->asoc.scope.loopback_scope;
   1554 #if defined(INET)
   1555 	ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope;
   1556 	ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal;
   1557 #endif
   1558 #if defined(INET6)
   1559 	local_scope = stcb->asoc.scope.local_scope;
   1560 	site_scope = stcb->asoc.scope.site_scope;
   1561 	ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal;
   1562 #endif
   1563 #if defined(__Userspace__)
   1564 	conn_addr_legal = stcb->asoc.scope.conn_addr_legal;
   1565 #endif
   1566 } else {
   1567 	/* Use generic values for endpoints. */
   1568 	loopback_scope = 1;
   1569 #if defined(INET)
   1570 	ipv4_local_scope = 1;
   1571 #endif
   1572 #if defined(INET6)
   1573 	local_scope = 1;
   1574 	site_scope = 1;
   1575 #endif
   1576 	if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
   1577 #if defined(INET6)
   1578 		ipv6_addr_legal = 1;
   1579 #endif
   1580 #if defined(INET)
   1581 		if (SCTP_IPV6_V6ONLY(inp)) {
   1582 			ipv4_addr_legal = 0;
   1583 		} else {
   1584 			ipv4_addr_legal = 1;
   1585 		}
   1586 #endif
   1587 #if defined(__Userspace__)
   1588 		conn_addr_legal = 0;
   1589 #endif
   1590 	} else {
   1591 #if defined(INET6)
   1592 		ipv6_addr_legal = 0;
   1593 #endif
   1594 #if defined(__Userspace__)
   1595 		if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_CONN) {
   1596 			conn_addr_legal = 1;
   1597 #if defined(INET)
   1598 			ipv4_addr_legal = 0;
   1599 #endif
   1600 		} else {
   1601 			conn_addr_legal = 0;
   1602 #if defined(INET)
   1603 			ipv4_addr_legal = 1;
   1604 #endif
   1605 		}
   1606 #else
   1607 #if defined(INET)
   1608 		ipv4_addr_legal = 1;
   1609 #endif
   1610 #endif
   1611 	}
   1612 }
   1613 vrf = sctp_find_vrf(vrf_id);
   1614 if (vrf == NULL) {
   1615 	return (0);
   1616 }
   1617 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
   1618 	LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
   1619 		if ((loopback_scope == 0) &&
   1620 		    SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) {
   1621 			/* Skip loopback if loopback_scope not set */
   1622 			continue;
   1623 		}
   1624 		LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
   1625 			if (stcb) {
   1626 				/*
   1627 				 * For the BOUND-ALL case, the list
   1628 				 * associated with a TCB is Always
   1629 				 * considered a reverse list.. i.e.
   1630 				 * it lists addresses that are NOT
   1631 				 * part of the association. If this
   1632 				 * is one of those we must skip it.
   1633 				 */
   1634 				if (sctp_is_addr_restricted(stcb,
   1635 				                            sctp_ifa)) {
   1636 					continue;
   1637 				}
   1638 			}
   1639 			switch (sctp_ifa->address.sa.sa_family) {
   1640 #ifdef INET
   1641 			case AF_INET:
   1642 				if (ipv4_addr_legal) {
   1643 					struct sockaddr_in *sin;
   1644 
   1645 					sin = &sctp_ifa->address.sin;
   1646 					if (sin->sin_addr.s_addr == 0) {
   1647 						/*
   1648 						 * we skip unspecified
   1649 						 * addresses
   1650 						 */
   1651 						continue;
   1652 					}
   1653 #if defined(__FreeBSD__) && !defined(__Userspace__)
   1654 					if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
   1655 					                     &sin->sin_addr) != 0) {
   1656 						continue;
   1657 					}
   1658 #endif
   1659 					if ((ipv4_local_scope == 0) &&
   1660 					    (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
   1661 						continue;
   1662 					}
   1663 #ifdef INET6
   1664 					if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) {
   1665 						if (actual + sizeof(struct sockaddr_in6) > limit) {
   1666 							return (actual);
   1667 						}
   1668 						in6_sin_2_v4mapsin6(sin, (struct sockaddr_in6 *)addr);
   1669 						((struct sockaddr_in6 *)addr)->sin6_port = inp->sctp_lport;
   1670 						addr = (struct sockaddr *)((caddr_t)addr + sizeof(struct sockaddr_in6));
   1671 						actual += sizeof(struct sockaddr_in6);
   1672 					} else {
   1673 #endif
   1674 						if (actual + sizeof(struct sockaddr_in) > limit) {
   1675 							return (actual);
   1676 						}
   1677 						memcpy(addr, sin, sizeof(struct sockaddr_in));
   1678 						((struct sockaddr_in *)addr)->sin_port = inp->sctp_lport;
   1679 						addr = (struct sockaddr *)((caddr_t)addr + sizeof(struct sockaddr_in));
   1680 						actual += sizeof(struct sockaddr_in);
   1681 #ifdef INET6
   1682 					}
   1683 #endif
   1684 				} else {
   1685 					continue;
   1686 				}
   1687 				break;
   1688 #endif
   1689 #ifdef INET6
   1690 			case AF_INET6:
   1691 				if (ipv6_addr_legal) {
   1692 					struct sockaddr_in6 *sin6;
   1693 
   1694 #if defined(SCTP_EMBEDDED_V6_SCOPE) && !defined(SCTP_KAME)
   1695 					struct sockaddr_in6 lsa6;
   1696 #endif
   1697 					sin6 = &sctp_ifa->address.sin6;
   1698 					if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
   1699 						/*
   1700 						 * we skip unspecified
   1701 						 * addresses
   1702 						 */
   1703 						continue;
   1704 					}
   1705 #if defined(__FreeBSD__) && !defined(__Userspace__)
   1706 					if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
   1707 					                     &sin6->sin6_addr) != 0) {
   1708 						continue;
   1709 					}
   1710 #endif
   1711 					if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
   1712 						if (local_scope == 0)
   1713 							continue;
   1714 #if defined(SCTP_EMBEDDED_V6_SCOPE)
   1715 						if (sin6->sin6_scope_id == 0) {
   1716 #ifdef SCTP_KAME
   1717 							if (sa6_recoverscope(sin6) != 0)
   1718 								/*
   1719 								 * bad link
   1720 								 * local
   1721 								 * address
   1722 								 */
   1723 								continue;
   1724 #else
   1725 							lsa6 = *sin6;
   1726 							if (in6_recoverscope(&lsa6,
   1727 									     &lsa6.sin6_addr,
   1728 									     NULL))
   1729 								/*
   1730 								 * bad link
   1731 								 * local
   1732 								 * address
   1733 								 */
   1734 							continue;
   1735 							sin6 = &lsa6;
   1736 #endif				/* SCTP_KAME */
   1737 						}
   1738 #endif /* SCTP_EMBEDDED_V6_SCOPE */
   1739 					}
   1740 					if ((site_scope == 0) &&
   1741 					    (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) {
   1742 						continue;
   1743 					}
   1744 					if (actual + sizeof(struct sockaddr_in6) > limit) {
   1745 						return (actual);
   1746 					}
   1747 					memcpy(addr, sin6, sizeof(struct sockaddr_in6));
   1748 					((struct sockaddr_in6 *)addr)->sin6_port = inp->sctp_lport;
   1749 					addr = (struct sockaddr *)((caddr_t)addr + sizeof(struct sockaddr_in6));
   1750 					actual += sizeof(struct sockaddr_in6);
   1751 				} else {
   1752 					continue;
   1753 				}
   1754 				break;
   1755 #endif
   1756 #if defined(__Userspace__)
   1757 			case AF_CONN:
   1758 				if (conn_addr_legal) {
   1759 					if (actual + sizeof(struct sockaddr_conn) > limit) {
   1760 						return (actual);
   1761 					}
   1762 					memcpy(addr, &sctp_ifa->address.sconn, sizeof(struct sockaddr_conn));
   1763 					((struct sockaddr_conn *)addr)->sconn_port = inp->sctp_lport;
   1764 					addr = (struct sockaddr *)((caddr_t)addr + sizeof(struct sockaddr_conn));
   1765 					actual += sizeof(struct sockaddr_conn);
   1766 				} else {
   1767 					continue;
   1768 				}
   1769 #endif
   1770 			default:
   1771 				/* TSNH */
   1772 				break;
   1773 			}
   1774 		}
   1775 	}
   1776 } else {
   1777 	struct sctp_laddr *laddr;
   1778 	size_t sa_len;
   1779 
   1780 	LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
   1781 		if (stcb) {
   1782 			if (sctp_is_addr_restricted(stcb, laddr->ifa)) {
   1783 				continue;
   1784 			}
   1785 		}
   1786 #ifdef HAVE_SA_LEN
   1787 		sa_len = laddr->ifa->address.sa.sa_len;
   1788 #else
   1789 		switch (laddr->ifa->address.sa.sa_family) {
   1790 #ifdef INET
   1791 		case AF_INET:
   1792 			sa_len = sizeof(struct sockaddr_in);
   1793 			break;
   1794 #endif
   1795 #ifdef INET6
   1796 		case AF_INET6:
   1797 			sa_len = sizeof(struct sockaddr_in6);
   1798 			break;
   1799 #endif
   1800 #if defined(__Userspace__)
   1801 		case AF_CONN:
   1802 			sa_len = sizeof(struct sockaddr_conn);
   1803 			break;
   1804 #endif
   1805 		default:
   1806 			/* TSNH */
   1807 			sa_len = 0;
   1808 			break;
   1809 		}
   1810 #endif
   1811 		if (actual + sa_len > limit) {
   1812 			return (actual);
   1813 		}
   1814 		if (sctp_fill_user_address(addr, &laddr->ifa->address.sa))
   1815 			continue;
   1816 		switch (laddr->ifa->address.sa.sa_family) {
   1817 #ifdef INET
   1818 		case AF_INET:
   1819 			((struct sockaddr_in *)addr)->sin_port = inp->sctp_lport;
   1820 			break;
   1821 #endif
   1822 #ifdef INET6
   1823 		case AF_INET6:
   1824 			((struct sockaddr_in6 *)addr)->sin6_port = inp->sctp_lport;
   1825 			break;
   1826 #endif
   1827 #if defined(__Userspace__)
   1828 		case AF_CONN:
   1829 			((struct sockaddr_conn *)addr)->sconn_port = inp->sctp_lport;
   1830 			break;
   1831 #endif
   1832 		default:
   1833 			/* TSNH */
   1834 			break;
   1835 		}
   1836 		addr = (struct sockaddr *)((caddr_t)addr + sa_len);
   1837 		actual += sa_len;
   1838 	}
   1839 }
   1840 return (actual);
   1841 }
   1842 
   1843 static size_t
   1844 sctp_fill_up_addresses(struct sctp_inpcb *inp,
   1845                       struct sctp_tcb *stcb,
   1846                       size_t limit,
   1847                       struct sockaddr *addr)
   1848 {
   1849 size_t size;
   1850 #ifdef SCTP_MVRF
   1851 uint32_t id;
   1852 #endif
   1853 
   1854 SCTP_IPI_ADDR_RLOCK();
   1855 #ifdef SCTP_MVRF
   1856 /*
   1857 * FIX ME: ?? this WILL report duplicate addresses if they appear
   1858 * in more than one VRF.
   1859 */
   1860 /* fill up addresses for all VRFs on the endpoint */
   1861 size = 0;
   1862 for (id = 0; (id < inp->num_vrfs) && (size < limit); id++) {
   1863 	size += sctp_fill_up_addresses_vrf(inp, stcb, limit, addr,
   1864 	                                   inp->m_vrf_ids[id]);
   1865 	addr = (struct sockaddr *)((caddr_t)addr + size);
   1866 }
   1867 #else
   1868 /* fill up addresses for the endpoint's default vrf */
   1869 size = sctp_fill_up_addresses_vrf(inp, stcb, limit, addr,
   1870                                   inp->def_vrf_id);
   1871 #endif
   1872 SCTP_IPI_ADDR_RUNLOCK();
   1873 return (size);
   1874 }
   1875 
   1876 static size_t
   1877 sctp_max_size_addresses_vrf(struct sctp_inpcb *inp, uint32_t vrf_id)
   1878 {
   1879 struct sctp_vrf *vrf;
   1880 size_t size;
   1881 
   1882 /*
   1883  * In both sub-set bound an bound_all cases we return the size of
   1884  * the maximum number of addresses that you could get. In reality
   1885  * the sub-set bound may have an exclusion list for a given TCB or
   1886  * in the bound-all case a TCB may NOT include the loopback or other
   1887  * addresses as well.
   1888  */
   1889 SCTP_IPI_ADDR_LOCK_ASSERT();
   1890 vrf = sctp_find_vrf(vrf_id);
   1891 if (vrf == NULL) {
   1892 	return (0);
   1893 }
   1894 size = 0;
   1895 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
   1896 	struct sctp_ifn *sctp_ifn;
   1897 	struct sctp_ifa *sctp_ifa;
   1898 
   1899 	LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
   1900 		LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
   1901 			/* Count them if they are the right type */
   1902 			switch (sctp_ifa->address.sa.sa_family) {
   1903 #ifdef INET
   1904 			case AF_INET:
   1905 #ifdef INET6
   1906 				if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4))
   1907 					size += sizeof(struct sockaddr_in6);
   1908 				else
   1909 					size += sizeof(struct sockaddr_in);
   1910 #else
   1911 				size += sizeof(struct sockaddr_in);
   1912 #endif
   1913 				break;
   1914 #endif
   1915 #ifdef INET6
   1916 			case AF_INET6:
   1917 				size += sizeof(struct sockaddr_in6);
   1918 				break;
   1919 #endif
   1920 #if defined(__Userspace__)
   1921 			case AF_CONN:
   1922 				size += sizeof(struct sockaddr_conn);
   1923 				break;
   1924 #endif
   1925 			default:
   1926 				break;
   1927 			}
   1928 		}
   1929 	}
   1930 } else {
   1931 	struct sctp_laddr *laddr;
   1932 
   1933 	LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
   1934 		switch (laddr->ifa->address.sa.sa_family) {
   1935 #ifdef INET
   1936 		case AF_INET:
   1937 #ifdef INET6
   1938 			if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4))
   1939 				size += sizeof(struct sockaddr_in6);
   1940 			else
   1941 				size += sizeof(struct sockaddr_in);
   1942 #else
   1943 			size += sizeof(struct sockaddr_in);
   1944 #endif
   1945 			break;
   1946 #endif
   1947 #ifdef INET6
   1948 		case AF_INET6:
   1949 			size += sizeof(struct sockaddr_in6);
   1950 			break;
   1951 #endif
   1952 #if defined(__Userspace__)
   1953 		case AF_CONN:
   1954 			size += sizeof(struct sockaddr_conn);
   1955 			break;
   1956 #endif
   1957 		default:
   1958 			break;
   1959 		}
   1960 	}
   1961 }
   1962 return (size);
   1963 }
   1964 
   1965 static size_t
   1966 sctp_max_size_addresses(struct sctp_inpcb *inp)
   1967 {
   1968 size_t size;
   1969 #ifdef SCTP_MVRF
   1970 int id;
   1971 #endif
   1972 
   1973 SCTP_IPI_ADDR_RLOCK();
   1974 #ifdef SCTP_MVRF
   1975 /*
   1976 * FIX ME: ?? this WILL count duplicate addresses if they appear
   1977 * in more than one VRF.
   1978 */
   1979 /* Maximum size of all addresses for all VRFs on the endpoint */
   1980 size = 0;
   1981 for (id = 0; id < inp->num_vrfs; id++) {
   1982 	size += sctp_max_size_addresses_vrf(inp, inp->m_vrf_ids[id]);
   1983 }
   1984 #else
   1985 /* Maximum size of all addresses for the endpoint's default VRF */
   1986 size = sctp_max_size_addresses_vrf(inp, inp->def_vrf_id);
   1987 #endif
   1988 SCTP_IPI_ADDR_RUNLOCK();
   1989 return (size);
   1990 }
   1991 
   1992 static int
   1993 sctp_do_connect_x(struct socket *so, struct sctp_inpcb *inp, void *optval,
   1994 	  size_t optsize, void *p, int delay)
   1995 {
   1996 int error;
   1997 int creat_lock_on = 0;
   1998 struct sctp_tcb *stcb = NULL;
   1999 struct sockaddr *sa;
   2000 unsigned int num_v6 = 0, num_v4 = 0, *totaddrp, totaddr;
   2001 uint32_t vrf_id;
   2002 sctp_assoc_t *a_id;
   2003 
   2004 SCTPDBG(SCTP_DEBUG_PCB1, "Connectx called\n");
   2005 
   2006 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
   2007     (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) {
   2008 	/* We are already connected AND the TCP model */
   2009 	SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EADDRINUSE);
   2010 	return (EADDRINUSE);
   2011 }
   2012 
   2013 if ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) &&
   2014     (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_PORTREUSE))) {
   2015 	SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   2016 	return (EINVAL);
   2017 }
   2018 
   2019 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
   2020 	SCTP_INP_RLOCK(inp);
   2021 	stcb = LIST_FIRST(&inp->sctp_asoc_list);
   2022 	SCTP_INP_RUNLOCK(inp);
   2023 }
   2024 if (stcb) {
   2025 	SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY);
   2026 	return (EALREADY);
   2027 }
   2028 SCTP_INP_INCR_REF(inp);
   2029 SCTP_ASOC_CREATE_LOCK(inp);
   2030 creat_lock_on = 1;
   2031 if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
   2032     (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) {
   2033 	SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EFAULT);
   2034 	error = EFAULT;
   2035 	goto out_now;
   2036 }
   2037 totaddrp = (unsigned int *)optval;
   2038 totaddr = *totaddrp;
   2039 sa = (struct sockaddr *)(totaddrp + 1);
   2040 error = sctp_connectx_helper_find(inp, sa, totaddr, &num_v4, &num_v6, (unsigned int)(optsize - sizeof(int)));
   2041 if (error != 0) {
   2042 	/* Already have or am bring up an association */
   2043 	SCTP_ASOC_CREATE_UNLOCK(inp);
   2044 	creat_lock_on = 0;
   2045 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
   2046 	goto out_now;
   2047 }
   2048 #ifdef INET6
   2049 if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) &&
   2050     (num_v6 > 0)) {
   2051 	error = EINVAL;
   2052 	goto out_now;
   2053 }
   2054 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
   2055     (num_v4 > 0)) {
   2056 	if (SCTP_IPV6_V6ONLY(inp)) {
   2057 		/*
   2058 		 * if IPV6_V6ONLY flag, ignore connections destined
   2059 		 * to a v4 addr or v4-mapped addr
   2060 		 */
   2061 		SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   2062 		error = EINVAL;
   2063 		goto out_now;
   2064 	}
   2065 }
   2066 #endif				/* INET6 */
   2067 if (inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) {
   2068 	/* Bind a ephemeral port */
   2069 	error = sctp_inpcb_bind(so, NULL, NULL, p);
   2070 	if (error) {
   2071 		goto out_now;
   2072 	}
   2073 }
   2074 
   2075 /* FIX ME: do we want to pass in a vrf on the connect call? */
   2076 vrf_id = inp->def_vrf_id;
   2077 
   2078 /* We are GOOD to go */
   2079 stcb = sctp_aloc_assoc_connected(inp, sa, &error, 0, 0, vrf_id,
   2080                                  inp->sctp_ep.pre_open_stream_count,
   2081                                  inp->sctp_ep.port,
   2082 #if defined(__FreeBSD__) && !defined(__Userspace__)
   2083                                  (struct thread *)p,
   2084 #elif defined(_WIN32) && !defined(__Userspace__)
   2085                                  (PKTHREAD)p,
   2086 #else
   2087                                  (struct proc *)p,
   2088 #endif
   2089                                  SCTP_INITIALIZE_AUTH_PARAMS);
   2090 if (stcb == NULL) {
   2091 	/* Gak! no memory */
   2092 	goto out_now;
   2093 }
   2094 SCTP_SET_STATE(stcb, SCTP_STATE_COOKIE_WAIT);
   2095 /* move to second address */
   2096 switch (sa->sa_family) {
   2097 #ifdef INET
   2098 case AF_INET:
   2099 	sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in));
   2100 	break;
   2101 #endif
   2102 #ifdef INET6
   2103 case AF_INET6:
   2104 	sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in6));
   2105 	break;
   2106 #endif
   2107 default:
   2108 	break;
   2109 }
   2110 
   2111 error = 0;
   2112 sctp_connectx_helper_add(stcb, sa, (totaddr-1), &error);
   2113 /* Fill in the return id */
   2114 if (error) {
   2115 	goto out_now;
   2116 }
   2117 a_id = (sctp_assoc_t *)optval;
   2118 *a_id = sctp_get_associd(stcb);
   2119 
   2120 if (delay) {
   2121 	/* doing delayed connection */
   2122 	stcb->asoc.delayed_connection = 1;
   2123 	sctp_timer_start(SCTP_TIMER_TYPE_INIT, inp, stcb, stcb->asoc.primary_destination);
   2124 } else {
   2125 	(void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered);
   2126 	sctp_send_initiate(inp, stcb, SCTP_SO_LOCKED);
   2127 }
   2128 SCTP_TCB_UNLOCK(stcb);
   2129 out_now:
   2130 if (creat_lock_on) {
   2131 	SCTP_ASOC_CREATE_UNLOCK(inp);
   2132 }
   2133 SCTP_INP_DECR_REF(inp);
   2134 return (error);
   2135 }
   2136 
   2137 #define SCTP_FIND_STCB(inp, stcb, assoc_id) { \
   2138 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||\
   2139     (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) { \
   2140 	SCTP_INP_RLOCK(inp); \
   2141 	stcb = LIST_FIRST(&inp->sctp_asoc_list); \
   2142 	if (stcb) { \
   2143 		SCTP_TCB_LOCK(stcb); \
   2144 	} \
   2145 	SCTP_INP_RUNLOCK(inp); \
   2146 } else if (assoc_id > SCTP_ALL_ASSOC) { \
   2147 	stcb = sctp_findassociation_ep_asocid(inp, assoc_id, 1); \
   2148 	if (stcb == NULL) { \
   2149 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); \
   2150 		error = ENOENT; \
   2151 		break; \
   2152 	} \
   2153 } else { \
   2154 	stcb = NULL; \
   2155 } \
   2156 }
   2157 
   2158 #define SCTP_CHECK_AND_CAST(destp, srcp, type, size) {\
   2159 if (size < sizeof(type)) { \
   2160 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); \
   2161 	error = EINVAL; \
   2162 	break; \
   2163 } else { \
   2164 	destp = (type *)srcp; \
   2165 } \
   2166 }
   2167 
   2168 #if defined(__Userspace__)
   2169 int
   2170 #else
   2171 static int
   2172 #endif
   2173 sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
   2174     void *p) {
   2175 struct sctp_inpcb *inp = NULL;
   2176 int error, val = 0;
   2177 struct sctp_tcb *stcb = NULL;
   2178 
   2179 if (optval == NULL) {
   2180 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   2181 	return (EINVAL);
   2182 }
   2183 
   2184 inp = (struct sctp_inpcb *)so->so_pcb;
   2185 if (inp == NULL) {
   2186 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   2187 	return EINVAL;
   2188 }
   2189 error = 0;
   2190 
   2191 switch (optname) {
   2192 case SCTP_NODELAY:
   2193 case SCTP_AUTOCLOSE:
   2194 case SCTP_EXPLICIT_EOR:
   2195 case SCTP_AUTO_ASCONF:
   2196 case SCTP_DISABLE_FRAGMENTS:
   2197 case SCTP_I_WANT_MAPPED_V4_ADDR:
   2198 case SCTP_USE_EXT_RCVINFO:
   2199 	SCTP_INP_RLOCK(inp);
   2200 	switch (optname) {
   2201 	case SCTP_DISABLE_FRAGMENTS:
   2202 		val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NO_FRAGMENT);
   2203 		break;
   2204 	case SCTP_I_WANT_MAPPED_V4_ADDR:
   2205 		val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4);
   2206 		break;
   2207 	case SCTP_AUTO_ASCONF:
   2208 		if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
   2209 			/* only valid for bound all sockets */
   2210 			val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTO_ASCONF);
   2211 		} else {
   2212 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   2213 			error = EINVAL;
   2214 			goto flags_out;
   2215 		}
   2216 		break;
   2217 	case SCTP_EXPLICIT_EOR:
   2218 		val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXPLICIT_EOR);
   2219 		break;
   2220 	case SCTP_NODELAY:
   2221 		val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NODELAY);
   2222 		break;
   2223 	case SCTP_USE_EXT_RCVINFO:
   2224 		val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXT_RCVINFO);
   2225 		break;
   2226 	case SCTP_AUTOCLOSE:
   2227 		if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTOCLOSE))
   2228 			val = sctp_ticks_to_secs(inp->sctp_ep.auto_close_time);
   2229 		else
   2230 			val = 0;
   2231 		break;
   2232 
   2233 	default:
   2234 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT);
   2235 		error = ENOPROTOOPT;
   2236 	} /* end switch (sopt->sopt_name) */
   2237 	if (*optsize < sizeof(val)) {
   2238 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   2239 		error = EINVAL;
   2240 	}
   2241 flags_out:
   2242 	SCTP_INP_RUNLOCK(inp);
   2243 	if (error == 0) {
   2244 		/* return the option value */
   2245 		*(int *)optval = val;
   2246 		*optsize = sizeof(val);
   2247 	}
   2248 	break;
   2249        case SCTP_GET_PACKET_LOG:
   2250 {
   2251 #ifdef  SCTP_PACKET_LOGGING
   2252 	uint8_t *target;
   2253 	int ret;
   2254 
   2255 	SCTP_CHECK_AND_CAST(target, optval, uint8_t, *optsize);
   2256 	ret = sctp_copy_out_packet_log(target , (int)*optsize);
   2257 	*optsize = ret;
   2258 #else
   2259 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP);
   2260 	error = EOPNOTSUPP;
   2261 #endif
   2262 	break;
   2263 }
   2264 case SCTP_REUSE_PORT:
   2265 {
   2266 	uint32_t *value;
   2267 
   2268 	if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE)) {
   2269 		/* Can't do this for a 1-m socket */
   2270 		error = EINVAL;
   2271 		break;
   2272 	}
   2273 	SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize);
   2274 	*value = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE);
   2275 	*optsize = sizeof(uint32_t);
   2276 	break;
   2277 }
   2278 case SCTP_PARTIAL_DELIVERY_POINT:
   2279 {
   2280 	uint32_t *value;
   2281 
   2282 	SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize);
   2283 	*value = inp->partial_delivery_point;
   2284 	*optsize = sizeof(uint32_t);
   2285 	break;
   2286 }
   2287 case SCTP_FRAGMENT_INTERLEAVE:
   2288 {
   2289 	uint32_t *value;
   2290 
   2291 	SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize);
   2292 	if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE)) {
   2293 		if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS)) {
   2294 			*value = SCTP_FRAG_LEVEL_2;
   2295 		} else {
   2296 			*value = SCTP_FRAG_LEVEL_1;
   2297 		}
   2298 	} else {
   2299 		*value = SCTP_FRAG_LEVEL_0;
   2300 	}
   2301 	*optsize = sizeof(uint32_t);
   2302 	break;
   2303 }
   2304 case SCTP_INTERLEAVING_SUPPORTED:
   2305 {
   2306 	struct sctp_assoc_value *av;
   2307 
   2308 	SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
   2309 	SCTP_FIND_STCB(inp, stcb, av->assoc_id);
   2310 
   2311 	if (stcb) {
   2312 		av->assoc_value = stcb->asoc.idata_supported;
   2313 		SCTP_TCB_UNLOCK(stcb);
   2314 	} else {
   2315 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   2316 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   2317 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   2318 		     (av->assoc_id == SCTP_FUTURE_ASSOC))) {
   2319 			SCTP_INP_RLOCK(inp);
   2320 			if (inp->idata_supported) {
   2321 				av->assoc_value = 1;
   2322 			} else {
   2323 				av->assoc_value = 0;
   2324 			}
   2325 			SCTP_INP_RUNLOCK(inp);
   2326 		} else {
   2327 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   2328 			error = EINVAL;
   2329 		}
   2330 	}
   2331 	if (error == 0) {
   2332 		*optsize = sizeof(struct sctp_assoc_value);
   2333 	}
   2334 	break;
   2335 }
   2336 case SCTP_CMT_ON_OFF:
   2337 {
   2338 	struct sctp_assoc_value *av;
   2339 
   2340 	SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
   2341 	SCTP_FIND_STCB(inp, stcb, av->assoc_id);
   2342 	if (stcb) {
   2343 		av->assoc_value = stcb->asoc.sctp_cmt_on_off;
   2344 		SCTP_TCB_UNLOCK(stcb);
   2345 	} else {
   2346 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   2347 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   2348 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   2349 		     (av->assoc_id == SCTP_FUTURE_ASSOC))) {
   2350 			SCTP_INP_RLOCK(inp);
   2351 			av->assoc_value = inp->sctp_cmt_on_off;
   2352 			SCTP_INP_RUNLOCK(inp);
   2353 		} else {
   2354 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   2355 			error = EINVAL;
   2356 		}
   2357 	}
   2358 	if (error == 0) {
   2359 		*optsize = sizeof(struct sctp_assoc_value);
   2360 	}
   2361 	break;
   2362 }
   2363 case SCTP_PLUGGABLE_CC:
   2364 {
   2365 	struct sctp_assoc_value *av;
   2366 
   2367 	SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
   2368 	SCTP_FIND_STCB(inp, stcb, av->assoc_id);
   2369 	if (stcb) {
   2370 		av->assoc_value = stcb->asoc.congestion_control_module;
   2371 		SCTP_TCB_UNLOCK(stcb);
   2372 	} else {
   2373 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   2374 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   2375 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   2376 		     (av->assoc_id == SCTP_FUTURE_ASSOC))) {
   2377 			SCTP_INP_RLOCK(inp);
   2378 			av->assoc_value = inp->sctp_ep.sctp_default_cc_module;
   2379 			SCTP_INP_RUNLOCK(inp);
   2380 		} else {
   2381 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   2382 			error = EINVAL;
   2383 		}
   2384 	}
   2385 	if (error == 0) {
   2386 		*optsize = sizeof(struct sctp_assoc_value);
   2387 	}
   2388 	break;
   2389 }
   2390 case SCTP_CC_OPTION:
   2391 {
   2392 	struct sctp_cc_option *cc_opt;
   2393 
   2394 	SCTP_CHECK_AND_CAST(cc_opt, optval, struct sctp_cc_option, *optsize);
   2395 	SCTP_FIND_STCB(inp, stcb, cc_opt->aid_value.assoc_id);
   2396 	if (stcb == NULL) {
   2397 		error = EINVAL;
   2398 	} else {
   2399 		if (stcb->asoc.cc_functions.sctp_cwnd_socket_option == NULL) {
   2400 			error = ENOTSUP;
   2401 		} else {
   2402 			error = (*stcb->asoc.cc_functions.sctp_cwnd_socket_option)(stcb, 0, cc_opt);
   2403 			*optsize = sizeof(struct sctp_cc_option);
   2404 		}
   2405 		SCTP_TCB_UNLOCK(stcb);
   2406 	}
   2407 	break;
   2408 }
   2409 case SCTP_STREAM_SCHEDULER:
   2410 {
   2411 	struct sctp_assoc_value *av;
   2412 
   2413 	SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
   2414 	SCTP_FIND_STCB(inp, stcb, av->assoc_id);
   2415 	if (stcb) {
   2416 		av->assoc_value = stcb->asoc.stream_scheduling_module;
   2417 		SCTP_TCB_UNLOCK(stcb);
   2418 	} else {
   2419 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   2420 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   2421 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   2422 		     (av->assoc_id == SCTP_FUTURE_ASSOC))) {
   2423 			SCTP_INP_RLOCK(inp);
   2424 			av->assoc_value = inp->sctp_ep.sctp_default_ss_module;
   2425 			SCTP_INP_RUNLOCK(inp);
   2426 		} else {
   2427 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   2428 			error = EINVAL;
   2429 		}
   2430 	}
   2431 	if (error == 0) {
   2432 		*optsize = sizeof(struct sctp_assoc_value);
   2433 	}
   2434 	break;
   2435 }
   2436 case SCTP_STREAM_SCHEDULER_VALUE:
   2437 {
   2438 	struct sctp_stream_value *av;
   2439 
   2440 	SCTP_CHECK_AND_CAST(av, optval, struct sctp_stream_value, *optsize);
   2441 	SCTP_FIND_STCB(inp, stcb, av->assoc_id);
   2442 	if (stcb) {
   2443 		if ((av->stream_id >= stcb->asoc.streamoutcnt) ||
   2444 		    (stcb->asoc.ss_functions.sctp_ss_get_value(stcb, &stcb->asoc, &stcb->asoc.strmout[av->stream_id],
   2445 		                                               &av->stream_value) < 0)) {
   2446 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   2447 			error = EINVAL;
   2448 		} else {
   2449 			*optsize = sizeof(struct sctp_stream_value);
   2450 		}
   2451 		SCTP_TCB_UNLOCK(stcb);
   2452 	} else {
   2453 		/* Can't get stream value without association */
   2454 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   2455 		error = EINVAL;
   2456 	}
   2457 	break;
   2458 }
   2459 case SCTP_GET_ADDR_LEN:
   2460 {
   2461 	struct sctp_assoc_value *av;
   2462 
   2463 	SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
   2464 	error = EINVAL;
   2465 #ifdef INET
   2466 	if (av->assoc_value == AF_INET) {
   2467 		av->assoc_value = sizeof(struct sockaddr_in);
   2468 		error = 0;
   2469 	}
   2470 #endif
   2471 #ifdef INET6
   2472 	if (av->assoc_value == AF_INET6) {
   2473 		av->assoc_value = sizeof(struct sockaddr_in6);
   2474 		error = 0;
   2475 	}
   2476 #endif
   2477 #if defined(__Userspace__)
   2478 	if (av->assoc_value == AF_CONN) {
   2479 		av->assoc_value = sizeof(struct sockaddr_conn);
   2480 		error = 0;
   2481 	}
   2482 #endif
   2483 	if (error) {
   2484 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
   2485 	} else {
   2486 		*optsize = sizeof(struct sctp_assoc_value);
   2487 	}
   2488 	break;
   2489 }
   2490 case SCTP_GET_ASSOC_NUMBER:
   2491 {
   2492 	uint32_t *value, cnt;
   2493 
   2494 	SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize);
   2495 	SCTP_INP_RLOCK(inp);
   2496 	if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   2497 	    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
   2498 		/* Can't do this for a 1-1 socket */
   2499 		error = EINVAL;
   2500 		SCTP_INP_RUNLOCK(inp);
   2501 		break;
   2502 	}
   2503 	cnt = 0;
   2504 	LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
   2505 		cnt++;
   2506 	}
   2507 	SCTP_INP_RUNLOCK(inp);
   2508 	*value = cnt;
   2509 	*optsize = sizeof(uint32_t);
   2510 	break;
   2511 }
   2512 case SCTP_GET_ASSOC_ID_LIST:
   2513 {
   2514 	struct sctp_assoc_ids *ids;
   2515 	uint32_t at;
   2516 	size_t limit;
   2517 
   2518 	SCTP_CHECK_AND_CAST(ids, optval, struct sctp_assoc_ids, *optsize);
   2519 	SCTP_INP_RLOCK(inp);
   2520 	if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   2521 	    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
   2522 		/* Can't do this for a 1-1 socket */
   2523 		error = EINVAL;
   2524 		SCTP_INP_RUNLOCK(inp);
   2525 		break;
   2526 	}
   2527 	at = 0;
   2528 	limit = (*optsize - sizeof(uint32_t)) / sizeof(sctp_assoc_t);
   2529 	LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
   2530 		if (at < limit) {
   2531 			ids->gaids_assoc_id[at++] = sctp_get_associd(stcb);
   2532 			if (at == 0) {
   2533 				error = EINVAL;
   2534 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
   2535 				break;
   2536 			}
   2537 		} else {
   2538 			error = EINVAL;
   2539 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
   2540 			break;
   2541 		}
   2542 	}
   2543 	SCTP_INP_RUNLOCK(inp);
   2544 	if (error == 0) {
   2545 		ids->gaids_number_of_ids = at;
   2546 		*optsize = ((at * sizeof(sctp_assoc_t)) + sizeof(uint32_t));
   2547 	}
   2548 	break;
   2549 }
   2550 case SCTP_CONTEXT:
   2551 {
   2552 	struct sctp_assoc_value *av;
   2553 
   2554 	SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
   2555 	SCTP_FIND_STCB(inp, stcb, av->assoc_id);
   2556 
   2557 	if (stcb) {
   2558 		av->assoc_value = stcb->asoc.context;
   2559 		SCTP_TCB_UNLOCK(stcb);
   2560 	} else {
   2561 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   2562 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   2563 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   2564 		     (av->assoc_id == SCTP_FUTURE_ASSOC))) {
   2565 			SCTP_INP_RLOCK(inp);
   2566 			av->assoc_value = inp->sctp_context;
   2567 			SCTP_INP_RUNLOCK(inp);
   2568 		} else {
   2569 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   2570 			error = EINVAL;
   2571 		}
   2572 	}
   2573 	if (error == 0) {
   2574 		*optsize = sizeof(struct sctp_assoc_value);
   2575 	}
   2576 	break;
   2577 }
   2578 case SCTP_VRF_ID:
   2579 {
   2580 	uint32_t *default_vrfid;
   2581 
   2582 	SCTP_CHECK_AND_CAST(default_vrfid, optval, uint32_t, *optsize);
   2583 	*default_vrfid = inp->def_vrf_id;
   2584 	*optsize = sizeof(uint32_t);
   2585 	break;
   2586 }
   2587 case SCTP_GET_ASOC_VRF:
   2588 {
   2589 	struct sctp_assoc_value *id;
   2590 
   2591 	SCTP_CHECK_AND_CAST(id, optval, struct sctp_assoc_value, *optsize);
   2592 	SCTP_FIND_STCB(inp, stcb, id->assoc_id);
   2593 	if (stcb == NULL) {
   2594 		error = EINVAL;
   2595 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
   2596 	} else {
   2597 		id->assoc_value = stcb->asoc.vrf_id;
   2598 		SCTP_TCB_UNLOCK(stcb);
   2599 		*optsize = sizeof(struct sctp_assoc_value);
   2600 	}
   2601 	break;
   2602 }
   2603 case SCTP_GET_VRF_IDS:
   2604 {
   2605 #ifdef SCTP_MVRF
   2606 	int siz_needed;
   2607 	uint32_t *vrf_ids;
   2608 
   2609 	SCTP_CHECK_AND_CAST(vrf_ids, optval, uint32_t, *optsize);
   2610 	siz_needed = inp->num_vrfs * sizeof(uint32_t);
   2611 	if (*optsize < siz_needed) {
   2612 		error = EINVAL;
   2613 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
   2614 	} else {
   2615 		memcpy(vrf_ids, inp->m_vrf_ids, siz_needed);
   2616 		*optsize = siz_needed;
   2617 	}
   2618 #else
   2619 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP);
   2620 	error = EOPNOTSUPP;
   2621 #endif
   2622 	break;
   2623 }
   2624 case SCTP_GET_NONCE_VALUES:
   2625 {
   2626 	struct sctp_get_nonce_values *gnv;
   2627 
   2628 	SCTP_CHECK_AND_CAST(gnv, optval, struct sctp_get_nonce_values, *optsize);
   2629 	SCTP_FIND_STCB(inp, stcb, gnv->gn_assoc_id);
   2630 
   2631 	if (stcb) {
   2632 		gnv->gn_peers_tag = stcb->asoc.peer_vtag;
   2633 		gnv->gn_local_tag = stcb->asoc.my_vtag;
   2634 		SCTP_TCB_UNLOCK(stcb);
   2635 		*optsize = sizeof(struct sctp_get_nonce_values);
   2636 	} else {
   2637 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTCONN);
   2638 		error = ENOTCONN;
   2639 	}
   2640 	break;
   2641 }
   2642 case SCTP_DELAYED_SACK:
   2643 {
   2644 	struct sctp_sack_info *sack;
   2645 
   2646 	SCTP_CHECK_AND_CAST(sack, optval, struct sctp_sack_info, *optsize);
   2647 	SCTP_FIND_STCB(inp, stcb, sack->sack_assoc_id);
   2648 	if (stcb) {
   2649 		sack->sack_delay = stcb->asoc.delayed_ack;
   2650 		sack->sack_freq = stcb->asoc.sack_freq;
   2651 		SCTP_TCB_UNLOCK(stcb);
   2652 	} else {
   2653 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   2654 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   2655 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   2656 		     (sack->sack_assoc_id == SCTP_FUTURE_ASSOC))) {
   2657 			SCTP_INP_RLOCK(inp);
   2658 			sack->sack_delay = sctp_ticks_to_msecs(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV]);
   2659 			sack->sack_freq = inp->sctp_ep.sctp_sack_freq;
   2660 			SCTP_INP_RUNLOCK(inp);
   2661 		} else {
   2662 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   2663 			error = EINVAL;
   2664 		}
   2665 	}
   2666 	if (error == 0) {
   2667 		*optsize = sizeof(struct sctp_sack_info);
   2668 	}
   2669 	break;
   2670 }
   2671 case SCTP_GET_SNDBUF_USE:
   2672 {
   2673 	struct sctp_sockstat *ss;
   2674 
   2675 	SCTP_CHECK_AND_CAST(ss, optval, struct sctp_sockstat, *optsize);
   2676 	SCTP_FIND_STCB(inp, stcb, ss->ss_assoc_id);
   2677 
   2678 	if (stcb) {
   2679 		ss->ss_total_sndbuf = stcb->asoc.total_output_queue_size;
   2680 		ss->ss_total_recv_buf = (stcb->asoc.size_on_reasm_queue +
   2681 					 stcb->asoc.size_on_all_streams);
   2682 		SCTP_TCB_UNLOCK(stcb);
   2683 		*optsize = sizeof(struct sctp_sockstat);
   2684 	} else {
   2685 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTCONN);
   2686 		error = ENOTCONN;
   2687 	}
   2688 	break;
   2689 }
   2690 case SCTP_MAX_BURST:
   2691 {
   2692 	struct sctp_assoc_value *av;
   2693 
   2694 	SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
   2695 	SCTP_FIND_STCB(inp, stcb, av->assoc_id);
   2696 
   2697 	if (stcb) {
   2698 		av->assoc_value = stcb->asoc.max_burst;
   2699 		SCTP_TCB_UNLOCK(stcb);
   2700 	} else {
   2701 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   2702 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   2703 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   2704 		     (av->assoc_id == SCTP_FUTURE_ASSOC))) {
   2705 			SCTP_INP_RLOCK(inp);
   2706 			av->assoc_value = inp->sctp_ep.max_burst;
   2707 			SCTP_INP_RUNLOCK(inp);
   2708 		} else {
   2709 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   2710 			error = EINVAL;
   2711 		}
   2712 	}
   2713 	if (error == 0) {
   2714 		*optsize = sizeof(struct sctp_assoc_value);
   2715 	}
   2716 	break;
   2717 }
   2718 case SCTP_MAXSEG:
   2719 {
   2720 	struct sctp_assoc_value *av;
   2721 
   2722 	SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
   2723 	SCTP_FIND_STCB(inp, stcb, av->assoc_id);
   2724 
   2725 	if (stcb) {
   2726 		av->assoc_value = stcb->asoc.sctp_frag_point;
   2727 		SCTP_TCB_UNLOCK(stcb);
   2728 	} else {
   2729 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   2730 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   2731 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   2732 		     (av->assoc_id == SCTP_FUTURE_ASSOC))) {
   2733 			SCTP_INP_RLOCK(inp);
   2734 			av->assoc_value = inp->sctp_frag_point;
   2735 			SCTP_INP_RUNLOCK(inp);
   2736 		} else {
   2737 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   2738 			error = EINVAL;
   2739 		}
   2740 	}
   2741 	if (error == 0) {
   2742 		*optsize = sizeof(struct sctp_assoc_value);
   2743 	}
   2744 	break;
   2745 }
   2746 case SCTP_GET_STAT_LOG:
   2747 	error = sctp_fill_stat_log(optval, optsize);
   2748 	break;
   2749 case SCTP_EVENTS:
   2750 {
   2751 	struct sctp_event_subscribe *events;
   2752 
   2753 	SCTP_CHECK_AND_CAST(events, optval, struct sctp_event_subscribe, *optsize);
   2754 	memset(events, 0, sizeof(struct sctp_event_subscribe));
   2755 	SCTP_INP_RLOCK(inp);
   2756 	if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT))
   2757 		events->sctp_data_io_event = 1;
   2758 
   2759 	if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVASSOCEVNT))
   2760 		events->sctp_association_event = 1;
   2761 
   2762 	if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVPADDREVNT))
   2763 		events->sctp_address_event = 1;
   2764 
   2765 	if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVSENDFAILEVNT))
   2766 		events->sctp_send_failure_event = 1;
   2767 
   2768 	if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVPEERERR))
   2769 		events->sctp_peer_error_event = 1;
   2770 
   2771 	if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT))
   2772 		events->sctp_shutdown_event = 1;
   2773 
   2774 	if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PDAPIEVNT))
   2775 		events->sctp_partial_delivery_event = 1;
   2776 
   2777 	if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_ADAPTATIONEVNT))
   2778 		events->sctp_adaptation_layer_event = 1;
   2779 
   2780 	if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTHEVNT))
   2781 		events->sctp_authentication_event = 1;
   2782 
   2783 	if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_DRYEVNT))
   2784 		events->sctp_sender_dry_event = 1;
   2785 
   2786 	if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_STREAM_RESETEVNT))
   2787 		events->sctp_stream_reset_event = 1;
   2788 	SCTP_INP_RUNLOCK(inp);
   2789 	*optsize = sizeof(struct sctp_event_subscribe);
   2790 	break;
   2791 }
   2792 case SCTP_ADAPTATION_LAYER:
   2793 {
   2794 	uint32_t *value;
   2795 
   2796 	SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize);
   2797 
   2798 	SCTP_INP_RLOCK(inp);
   2799 	*value = inp->sctp_ep.adaptation_layer_indicator;
   2800 	SCTP_INP_RUNLOCK(inp);
   2801 	*optsize = sizeof(uint32_t);
   2802 	break;
   2803 }
   2804 case SCTP_SET_INITIAL_DBG_SEQ:
   2805 {
   2806 	uint32_t *value;
   2807 
   2808 	SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize);
   2809 	SCTP_INP_RLOCK(inp);
   2810 	*value = inp->sctp_ep.initial_sequence_debug;
   2811 	SCTP_INP_RUNLOCK(inp);
   2812 	*optsize = sizeof(uint32_t);
   2813 	break;
   2814 }
   2815 case SCTP_GET_LOCAL_ADDR_SIZE:
   2816 {
   2817 	uint32_t *value;
   2818 
   2819 	SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize);
   2820 	SCTP_INP_RLOCK(inp);
   2821 	*value = (uint32_t)sctp_max_size_addresses(inp);
   2822 	SCTP_INP_RUNLOCK(inp);
   2823 	*optsize = sizeof(uint32_t);
   2824 	break;
   2825 }
   2826 case SCTP_GET_REMOTE_ADDR_SIZE:
   2827 {
   2828 	uint32_t *value;
   2829 	struct sctp_nets *net;
   2830 	size_t size;
   2831 
   2832 	SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize);
   2833 	/* FIXME MT: change to sctp_assoc_value? */
   2834 	SCTP_FIND_STCB(inp, stcb, (sctp_assoc_t)*value);
   2835 
   2836 	if (stcb != NULL) {
   2837 		size = 0;
   2838 		/* Count the sizes */
   2839 		TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
   2840 			switch (net->ro._l_addr.sa.sa_family) {
   2841 #ifdef INET
   2842 			case AF_INET:
   2843 #ifdef INET6
   2844 				if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) {
   2845 					size += sizeof(struct sockaddr_in6);
   2846 				} else {
   2847 					size += sizeof(struct sockaddr_in);
   2848 				}
   2849 #else
   2850 				size += sizeof(struct sockaddr_in);
   2851 #endif
   2852 				break;
   2853 #endif
   2854 #ifdef INET6
   2855 			case AF_INET6:
   2856 				size += sizeof(struct sockaddr_in6);
   2857 				break;
   2858 #endif
   2859 #if defined(__Userspace__)
   2860 			case AF_CONN:
   2861 				size += sizeof(struct sockaddr_conn);
   2862 				break;
   2863 #endif
   2864 			default:
   2865 				break;
   2866 			}
   2867 		}
   2868 		SCTP_TCB_UNLOCK(stcb);
   2869 		*value = (uint32_t)size;
   2870 		*optsize = sizeof(uint32_t);
   2871 	} else {
   2872 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   2873 		    ((sctp_assoc_t)*value <= SCTP_ALL_ASSOC)) {
   2874 			error = EINVAL;
   2875 		} else {
   2876 			error = ENOENT;
   2877 		}
   2878 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
   2879 	}
   2880 	break;
   2881 }
   2882 case SCTP_GET_PEER_ADDRESSES:
   2883 	/*
   2884 	 * Get the address information, an array is passed in to
   2885 	 * fill up we pack it.
   2886 	 */
   2887 {
   2888 	size_t cpsz, left;
   2889 	struct sockaddr *addr;
   2890 	struct sctp_nets *net;
   2891 	struct sctp_getaddresses *saddr;
   2892 
   2893 	SCTP_CHECK_AND_CAST(saddr, optval, struct sctp_getaddresses, *optsize);
   2894 	SCTP_FIND_STCB(inp, stcb, saddr->sget_assoc_id);
   2895 
   2896 	if (stcb != NULL) {
   2897 		left = *optsize - offsetof(struct sctp_getaddresses, addr);
   2898 		*optsize = offsetof(struct sctp_getaddresses, addr);
   2899 		addr = &saddr->addr[0].sa;
   2900 
   2901 		TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
   2902 			switch (net->ro._l_addr.sa.sa_family) {
   2903 #ifdef INET
   2904 			case AF_INET:
   2905 #ifdef INET6
   2906 				if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) {
   2907 					cpsz = sizeof(struct sockaddr_in6);
   2908 				} else {
   2909 					cpsz = sizeof(struct sockaddr_in);
   2910 				}
   2911 #else
   2912 				cpsz = sizeof(struct sockaddr_in);
   2913 #endif
   2914 				break;
   2915 #endif
   2916 #ifdef INET6
   2917 			case AF_INET6:
   2918 				cpsz = sizeof(struct sockaddr_in6);
   2919 				break;
   2920 #endif
   2921 #if defined(__Userspace__)
   2922 			case AF_CONN:
   2923 				cpsz = sizeof(struct sockaddr_conn);
   2924 				break;
   2925 #endif
   2926 			default:
   2927 				cpsz = 0;
   2928 				break;
   2929 			}
   2930 			if (cpsz == 0) {
   2931 				break;
   2932 			}
   2933 			if (left < cpsz) {
   2934 				/* not enough room. */
   2935 				break;
   2936 			}
   2937 #if defined(INET) && defined(INET6)
   2938 			if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) &&
   2939 			    (net->ro._l_addr.sa.sa_family == AF_INET)) {
   2940 				/* Must map the address */
   2941 				in6_sin_2_v4mapsin6(&net->ro._l_addr.sin,
   2942 				                    (struct sockaddr_in6 *)addr);
   2943 			} else {
   2944 				memcpy(addr, &net->ro._l_addr, cpsz);
   2945 			}
   2946 #else
   2947 			memcpy(addr, &net->ro._l_addr, cpsz);
   2948 #endif
   2949 			((struct sockaddr_in *)addr)->sin_port = stcb->rport;
   2950 
   2951 			addr = (struct sockaddr *)((caddr_t)addr + cpsz);
   2952 			left -= cpsz;
   2953 			*optsize += cpsz;
   2954 		}
   2955 		SCTP_TCB_UNLOCK(stcb);
   2956 	} else {
   2957 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   2958 		    (saddr->sget_assoc_id <= SCTP_ALL_ASSOC)) {
   2959 			error = EINVAL;
   2960 		} else {
   2961 			error = ENOENT;
   2962 		}
   2963 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
   2964 	}
   2965 	break;
   2966 }
   2967 case SCTP_GET_LOCAL_ADDRESSES:
   2968 {
   2969 	size_t limit, actual;
   2970 	struct sctp_getaddresses *saddr;
   2971 
   2972 	SCTP_CHECK_AND_CAST(saddr, optval, struct sctp_getaddresses, *optsize);
   2973 	SCTP_FIND_STCB(inp, stcb, saddr->sget_assoc_id);
   2974 
   2975 	if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   2976 	    ((saddr->sget_assoc_id == SCTP_CURRENT_ASSOC) ||
   2977 	     (saddr->sget_assoc_id == SCTP_ALL_ASSOC))) {
   2978 		error = EINVAL;
   2979 	} else {
   2980 		limit = *optsize - offsetof(struct sctp_getaddresses, addr);
   2981 		actual = sctp_fill_up_addresses(inp, stcb, limit, &saddr->addr[0].sa);
   2982 		*optsize = offsetof(struct sctp_getaddresses, addr) + actual;
   2983 	}
   2984 	if (stcb != NULL) {
   2985 		SCTP_TCB_UNLOCK(stcb);
   2986 	}
   2987 	break;
   2988 }
   2989 case SCTP_PEER_ADDR_PARAMS:
   2990 {
   2991 	struct sctp_paddrparams *paddrp;
   2992 	struct sctp_nets *net;
   2993 	struct sockaddr *addr;
   2994 #if defined(INET) && defined(INET6)
   2995 	struct sockaddr_in sin_store;
   2996 #endif
   2997 
   2998 	SCTP_CHECK_AND_CAST(paddrp, optval, struct sctp_paddrparams, *optsize);
   2999 	SCTP_FIND_STCB(inp, stcb, paddrp->spp_assoc_id);
   3000 
   3001 #if defined(INET) && defined(INET6)
   3002 	if (paddrp->spp_address.ss_family == AF_INET6) {
   3003 		struct sockaddr_in6 *sin6;
   3004 
   3005 		sin6 = (struct sockaddr_in6 *)&paddrp->spp_address;
   3006 		if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
   3007 			in6_sin6_2_sin(&sin_store, sin6);
   3008 			addr = (struct sockaddr *)&sin_store;
   3009 		} else {
   3010 			addr = (struct sockaddr *)&paddrp->spp_address;
   3011 		}
   3012 	} else {
   3013 		addr = (struct sockaddr *)&paddrp->spp_address;
   3014 	}
   3015 #else
   3016 	addr = (struct sockaddr *)&paddrp->spp_address;
   3017 #endif
   3018 	if (stcb != NULL) {
   3019 		net = sctp_findnet(stcb, addr);
   3020 	} else {
   3021 		/* We increment here since sctp_findassociation_ep_addr() wil
   3022 		 * do a decrement if it finds the stcb as long as the locked
   3023 		 * tcb (last argument) is NOT a TCB.. aka NULL.
   3024 		 */
   3025 		net = NULL;
   3026 		SCTP_INP_INCR_REF(inp);
   3027 		stcb = sctp_findassociation_ep_addr(&inp, addr, &net, NULL, NULL);
   3028 		if (stcb == NULL) {
   3029 			SCTP_INP_DECR_REF(inp);
   3030 		}
   3031 	}
   3032 	if ((stcb != NULL) && (net == NULL)) {
   3033 #ifdef INET
   3034 		if (addr->sa_family == AF_INET) {
   3035 			struct sockaddr_in *sin;
   3036 
   3037 			sin = (struct sockaddr_in *)addr;
   3038 			if (sin->sin_addr.s_addr != INADDR_ANY) {
   3039 				error = EINVAL;
   3040 				SCTP_TCB_UNLOCK(stcb);
   3041 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
   3042 				break;
   3043 			}
   3044 		} else
   3045 #endif
   3046 #ifdef INET6
   3047 		if (addr->sa_family == AF_INET6) {
   3048 			struct sockaddr_in6 *sin6;
   3049 
   3050 			sin6 = (struct sockaddr_in6 *)addr;
   3051 			if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
   3052 				error = EINVAL;
   3053 				SCTP_TCB_UNLOCK(stcb);
   3054 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
   3055 				break;
   3056 			}
   3057 		} else
   3058 #endif
   3059 #if defined(__Userspace__)
   3060 		if (addr->sa_family == AF_CONN) {
   3061 			struct sockaddr_conn *sconn;
   3062 
   3063 			sconn = (struct sockaddr_conn *)addr;
   3064 			if (sconn->sconn_addr != NULL) {
   3065 				error = EINVAL;
   3066 				SCTP_TCB_UNLOCK(stcb);
   3067 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
   3068 				break;
   3069 			}
   3070 		} else
   3071 #endif
   3072 		{
   3073 			error = EAFNOSUPPORT;
   3074 			SCTP_TCB_UNLOCK(stcb);
   3075 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
   3076 			break;
   3077 		}
   3078 	}
   3079 
   3080 	if (stcb != NULL) {
   3081 		/* Applies to the specific association */
   3082 		paddrp->spp_flags = 0;
   3083 		if (net != NULL) {
   3084 			paddrp->spp_hbinterval = net->heart_beat_delay;
   3085 			paddrp->spp_pathmaxrxt = net->failure_threshold;
   3086 			paddrp->spp_pathmtu = net->mtu;
   3087 			switch (net->ro._l_addr.sa.sa_family) {
   3088 #ifdef INET
   3089 			case AF_INET:
   3090 				paddrp->spp_pathmtu -= SCTP_MIN_V4_OVERHEAD;
   3091 				break;
   3092 #endif
   3093 #ifdef INET6
   3094 			case AF_INET6:
   3095 				paddrp->spp_pathmtu -= SCTP_MIN_OVERHEAD;
   3096 				break;
   3097 #endif
   3098 #if defined(__Userspace__)
   3099 			case AF_CONN:
   3100 				paddrp->spp_pathmtu -= sizeof(struct sctphdr);
   3101 				break;
   3102 #endif
   3103 			default:
   3104 				break;
   3105 			}
   3106 			/* get flags for HB */
   3107 			if (net->dest_state & SCTP_ADDR_NOHB) {
   3108 				paddrp->spp_flags |= SPP_HB_DISABLE;
   3109 			} else {
   3110 				paddrp->spp_flags |= SPP_HB_ENABLE;
   3111 			}
   3112 			/* get flags for PMTU */
   3113 			if (net->dest_state & SCTP_ADDR_NO_PMTUD) {
   3114 				paddrp->spp_flags |= SPP_PMTUD_DISABLE;
   3115 			} else {
   3116 				paddrp->spp_flags |= SPP_PMTUD_ENABLE;
   3117 			}
   3118 			if (net->dscp & 0x01) {
   3119 				paddrp->spp_dscp = net->dscp & 0xfc;
   3120 				paddrp->spp_flags |= SPP_DSCP;
   3121 			}
   3122 #ifdef INET6
   3123 			if ((net->ro._l_addr.sa.sa_family == AF_INET6) &&
   3124 			    (net->flowlabel & 0x80000000)) {
   3125 				paddrp->spp_ipv6_flowlabel = net->flowlabel & 0x000fffff;
   3126 				paddrp->spp_flags |= SPP_IPV6_FLOWLABEL;
   3127 			}
   3128 #endif
   3129 		} else {
   3130 			/*
   3131 			 * No destination so return default
   3132 			 * value
   3133 			 */
   3134 			paddrp->spp_pathmaxrxt = stcb->asoc.def_net_failure;
   3135 			paddrp->spp_pathmtu = stcb->asoc.default_mtu;
   3136 			if (stcb->asoc.default_dscp & 0x01) {
   3137 				paddrp->spp_dscp = stcb->asoc.default_dscp & 0xfc;
   3138 				paddrp->spp_flags |= SPP_DSCP;
   3139 			}
   3140 #ifdef INET6
   3141 			if (stcb->asoc.default_flowlabel & 0x80000000) {
   3142 				paddrp->spp_ipv6_flowlabel = stcb->asoc.default_flowlabel & 0x000fffff;
   3143 				paddrp->spp_flags |= SPP_IPV6_FLOWLABEL;
   3144 			}
   3145 #endif
   3146 			/* default settings should be these */
   3147 			if (sctp_stcb_is_feature_on(inp, stcb, SCTP_PCB_FLAGS_DONOT_HEARTBEAT)) {
   3148 				paddrp->spp_flags |= SPP_HB_DISABLE;
   3149 			} else {
   3150 				paddrp->spp_flags |= SPP_HB_ENABLE;
   3151 			}
   3152 			if (sctp_stcb_is_feature_on(inp, stcb, SCTP_PCB_FLAGS_DO_NOT_PMTUD)) {
   3153 				paddrp->spp_flags |= SPP_PMTUD_DISABLE;
   3154 			} else {
   3155 				paddrp->spp_flags |= SPP_PMTUD_ENABLE;
   3156 			}
   3157 			paddrp->spp_hbinterval = stcb->asoc.heart_beat_delay;
   3158 		}
   3159 		paddrp->spp_assoc_id = sctp_get_associd(stcb);
   3160 		SCTP_TCB_UNLOCK(stcb);
   3161 	} else {
   3162 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   3163 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   3164 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   3165 		     (paddrp->spp_assoc_id == SCTP_FUTURE_ASSOC))) {
   3166 			/* Use endpoint defaults */
   3167 			SCTP_INP_RLOCK(inp);
   3168 			paddrp->spp_pathmaxrxt = inp->sctp_ep.def_net_failure;
   3169 			paddrp->spp_hbinterval = sctp_ticks_to_msecs(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]);
   3170 			paddrp->spp_assoc_id = SCTP_FUTURE_ASSOC;
   3171 			/* get inp's default */
   3172 			if (inp->sctp_ep.default_dscp & 0x01) {
   3173 				paddrp->spp_dscp = inp->sctp_ep.default_dscp & 0xfc;
   3174 				paddrp->spp_flags |= SPP_DSCP;
   3175 			}
   3176 #ifdef INET6
   3177 			if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
   3178 			    (inp->sctp_ep.default_flowlabel & 0x80000000)) {
   3179 				paddrp->spp_ipv6_flowlabel = inp->sctp_ep.default_flowlabel & 0x000fffff;
   3180 				paddrp->spp_flags |= SPP_IPV6_FLOWLABEL;
   3181 			}
   3182 #endif
   3183 			paddrp->spp_pathmtu = inp->sctp_ep.default_mtu;
   3184 
   3185 			if (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_DONOT_HEARTBEAT)) {
   3186 				paddrp->spp_flags |= SPP_HB_ENABLE;
   3187 			} else {
   3188 				paddrp->spp_flags |= SPP_HB_DISABLE;
   3189 			}
   3190 			if (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_DO_NOT_PMTUD)) {
   3191 				paddrp->spp_flags |= SPP_PMTUD_ENABLE;
   3192 			} else {
   3193 				paddrp->spp_flags |= SPP_PMTUD_DISABLE;
   3194 			}
   3195 			SCTP_INP_RUNLOCK(inp);
   3196 		} else {
   3197 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   3198 			error = EINVAL;
   3199 		}
   3200 	}
   3201 	if (error == 0) {
   3202 		*optsize = sizeof(struct sctp_paddrparams);
   3203 	}
   3204 	break;
   3205 }
   3206 case SCTP_GET_PEER_ADDR_INFO:
   3207 {
   3208 	struct sctp_paddrinfo *paddri;
   3209 	struct sctp_nets *net;
   3210 	struct sockaddr *addr;
   3211 #if defined(INET) && defined(INET6)
   3212 	struct sockaddr_in sin_store;
   3213 #endif
   3214 
   3215 	SCTP_CHECK_AND_CAST(paddri, optval, struct sctp_paddrinfo, *optsize);
   3216 	SCTP_FIND_STCB(inp, stcb, paddri->spinfo_assoc_id);
   3217 
   3218 #if defined(INET) && defined(INET6)
   3219 	if (paddri->spinfo_address.ss_family == AF_INET6) {
   3220 		struct sockaddr_in6 *sin6;
   3221 
   3222 		sin6 = (struct sockaddr_in6 *)&paddri->spinfo_address;
   3223 		if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
   3224 			in6_sin6_2_sin(&sin_store, sin6);
   3225 			addr = (struct sockaddr *)&sin_store;
   3226 		} else {
   3227 			addr = (struct sockaddr *)&paddri->spinfo_address;
   3228 		}
   3229 	} else {
   3230 		addr = (struct sockaddr *)&paddri->spinfo_address;
   3231 	}
   3232 #else
   3233 	addr = (struct sockaddr *)&paddri->spinfo_address;
   3234 #endif
   3235 	if (stcb != NULL) {
   3236 		net = sctp_findnet(stcb, addr);
   3237 	} else {
   3238 		/* We increment here since sctp_findassociation_ep_addr() wil
   3239 		 * do a decrement if it finds the stcb as long as the locked
   3240 		 * tcb (last argument) is NOT a TCB.. aka NULL.
   3241 		 */
   3242 		net = NULL;
   3243 		SCTP_INP_INCR_REF(inp);
   3244 		stcb = sctp_findassociation_ep_addr(&inp, addr, &net, NULL, NULL);
   3245 		if (stcb == NULL) {
   3246 			SCTP_INP_DECR_REF(inp);
   3247 		}
   3248 	}
   3249 
   3250 	if ((stcb != NULL) && (net != NULL)) {
   3251 		if (net->dest_state & SCTP_ADDR_UNCONFIRMED) {
   3252 			/* It's unconfirmed */
   3253 			paddri->spinfo_state = SCTP_UNCONFIRMED;
   3254 		} else if (net->dest_state & SCTP_ADDR_REACHABLE) {
   3255 			/* It's active */
   3256 			paddri->spinfo_state = SCTP_ACTIVE;
   3257 		} else {
   3258 			/* It's inactive */
   3259 			paddri->spinfo_state = SCTP_INACTIVE;
   3260 		}
   3261 		paddri->spinfo_cwnd = net->cwnd;
   3262 		paddri->spinfo_srtt = net->lastsa >> SCTP_RTT_SHIFT;
   3263 		paddri->spinfo_rto = net->RTO;
   3264 		paddri->spinfo_assoc_id = sctp_get_associd(stcb);
   3265 		paddri->spinfo_mtu = net->mtu;
   3266 		switch (addr->sa_family) {
   3267 #if defined(INET)
   3268 		case AF_INET:
   3269 			paddri->spinfo_mtu -= SCTP_MIN_V4_OVERHEAD;
   3270 			break;
   3271 #endif
   3272 #if defined(INET6)
   3273 		case AF_INET6:
   3274 			paddri->spinfo_mtu -= SCTP_MIN_OVERHEAD;
   3275 			break;
   3276 #endif
   3277 #if defined(__Userspace__)
   3278 		case AF_CONN:
   3279 			paddri->spinfo_mtu -= sizeof(struct sctphdr);
   3280 			break;
   3281 #endif
   3282 		default:
   3283 			break;
   3284 		}
   3285 		SCTP_TCB_UNLOCK(stcb);
   3286 		*optsize = sizeof(struct sctp_paddrinfo);
   3287 	} else {
   3288 		if (stcb != NULL) {
   3289 			SCTP_TCB_UNLOCK(stcb);
   3290 		}
   3291 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT);
   3292 		error = ENOENT;
   3293 	}
   3294 	break;
   3295 }
   3296 case SCTP_PCB_STATUS:
   3297 {
   3298 	struct sctp_pcbinfo *spcb;
   3299 
   3300 	SCTP_CHECK_AND_CAST(spcb, optval, struct sctp_pcbinfo, *optsize);
   3301 	sctp_fill_pcbinfo(spcb);
   3302 	*optsize = sizeof(struct sctp_pcbinfo);
   3303 	break;
   3304 }
   3305 case SCTP_STATUS:
   3306 {
   3307 	struct sctp_nets *net;
   3308 	struct sctp_status *sstat;
   3309 
   3310 	SCTP_CHECK_AND_CAST(sstat, optval, struct sctp_status, *optsize);
   3311 	SCTP_FIND_STCB(inp, stcb, sstat->sstat_assoc_id);
   3312 
   3313 	if (stcb == NULL) {
   3314 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   3315 		error = EINVAL;
   3316 		break;
   3317 	}
   3318 	sstat->sstat_state = sctp_map_assoc_state(stcb->asoc.state);
   3319 	sstat->sstat_assoc_id = sctp_get_associd(stcb);
   3320 	sstat->sstat_rwnd = stcb->asoc.peers_rwnd;
   3321 	sstat->sstat_unackdata = stcb->asoc.sent_queue_cnt;
   3322 	/*
   3323 	 * We can't include chunks that have been passed to
   3324 	 * the socket layer. Only things in queue.
   3325 	 */
   3326 	sstat->sstat_penddata = (stcb->asoc.cnt_on_reasm_queue +
   3327 				 stcb->asoc.cnt_on_all_streams);
   3328 	sstat->sstat_instrms = stcb->asoc.streamincnt;
   3329 	sstat->sstat_outstrms = stcb->asoc.streamoutcnt;
   3330 	sstat->sstat_fragmentation_point = sctp_get_frag_point(stcb);
   3331 	net = stcb->asoc.primary_destination;
   3332 	if (net != NULL) {
   3333 #ifdef HAVE_SA_LEN
   3334 		memcpy(&sstat->sstat_primary.spinfo_address,
   3335 		       &net->ro._l_addr,
   3336 		       ((struct sockaddr *)(&net->ro._l_addr))->sa_len);
   3337 #else
   3338 		switch (stcb->asoc.primary_destination->ro._l_addr.sa.sa_family) {
   3339 #if defined(INET)
   3340 		case AF_INET:
   3341 			memcpy(&sstat->sstat_primary.spinfo_address,
   3342 			       &net->ro._l_addr,
   3343 			       sizeof(struct sockaddr_in));
   3344 			break;
   3345 #endif
   3346 #if defined(INET6)
   3347 		case AF_INET6:
   3348 			memcpy(&sstat->sstat_primary.spinfo_address,
   3349 			       &net->ro._l_addr,
   3350 			       sizeof(struct sockaddr_in6));
   3351 			break;
   3352 #endif
   3353 #if defined(__Userspace__)
   3354 		case AF_CONN:
   3355 			memcpy(&sstat->sstat_primary.spinfo_address,
   3356 			       &net->ro._l_addr,
   3357 			       sizeof(struct sockaddr_conn));
   3358 			break;
   3359 #endif
   3360 		default:
   3361 			break;
   3362 		}
   3363 #endif
   3364 		((struct sockaddr_in *)&sstat->sstat_primary.spinfo_address)->sin_port = stcb->rport;
   3365 		/*
   3366 		 * Again the user can get info from sctp_constants.h
   3367 		 * for what the state of the network is.
   3368 		 */
   3369 		if (net->dest_state & SCTP_ADDR_UNCONFIRMED) {
   3370 			/* It's unconfirmed */
   3371 			sstat->sstat_primary.spinfo_state = SCTP_UNCONFIRMED;
   3372 		} else if (net->dest_state & SCTP_ADDR_REACHABLE) {
   3373 			/* It's active */
   3374 			sstat->sstat_primary.spinfo_state = SCTP_ACTIVE;
   3375 		} else {
   3376 			/* It's inactive */
   3377 			sstat->sstat_primary.spinfo_state = SCTP_INACTIVE;
   3378 		}
   3379 		sstat->sstat_primary.spinfo_cwnd = net->cwnd;
   3380 		sstat->sstat_primary.spinfo_srtt = net->lastsa >> SCTP_RTT_SHIFT;
   3381 		sstat->sstat_primary.spinfo_rto = net->RTO;
   3382 		sstat->sstat_primary.spinfo_mtu = net->mtu;
   3383 		switch (stcb->asoc.primary_destination->ro._l_addr.sa.sa_family) {
   3384 #if defined(INET)
   3385 		case AF_INET:
   3386 			sstat->sstat_primary.spinfo_mtu -= SCTP_MIN_V4_OVERHEAD;
   3387 			break;
   3388 #endif
   3389 #if defined(INET6)
   3390 		case AF_INET6:
   3391 			sstat->sstat_primary.spinfo_mtu -= SCTP_MIN_OVERHEAD;
   3392 			break;
   3393 #endif
   3394 #if defined(__Userspace__)
   3395 		case AF_CONN:
   3396 			sstat->sstat_primary.spinfo_mtu -= sizeof(struct sctphdr);
   3397 			break;
   3398 #endif
   3399 		default:
   3400 			break;
   3401 		}
   3402 	} else {
   3403 		memset(&sstat->sstat_primary, 0, sizeof(struct sctp_paddrinfo));
   3404 	}
   3405 	sstat->sstat_primary.spinfo_assoc_id = sctp_get_associd(stcb);
   3406 	SCTP_TCB_UNLOCK(stcb);
   3407 	*optsize = sizeof(struct sctp_status);
   3408 	break;
   3409 }
   3410 case SCTP_RTOINFO:
   3411 {
   3412 	struct sctp_rtoinfo *srto;
   3413 
   3414 	SCTP_CHECK_AND_CAST(srto, optval, struct sctp_rtoinfo, *optsize);
   3415 	SCTP_FIND_STCB(inp, stcb, srto->srto_assoc_id);
   3416 
   3417 	if (stcb) {
   3418 		srto->srto_initial = stcb->asoc.initial_rto;
   3419 		srto->srto_max = stcb->asoc.maxrto;
   3420 		srto->srto_min = stcb->asoc.minrto;
   3421 		SCTP_TCB_UNLOCK(stcb);
   3422 	} else {
   3423 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   3424 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   3425 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   3426 		     (srto->srto_assoc_id == SCTP_FUTURE_ASSOC))) {
   3427 			SCTP_INP_RLOCK(inp);
   3428 			srto->srto_initial = inp->sctp_ep.initial_rto;
   3429 			srto->srto_max = inp->sctp_ep.sctp_maxrto;
   3430 			srto->srto_min = inp->sctp_ep.sctp_minrto;
   3431 			SCTP_INP_RUNLOCK(inp);
   3432 		} else {
   3433 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   3434 			error = EINVAL;
   3435 		}
   3436 	}
   3437 	if (error == 0) {
   3438 		*optsize = sizeof(struct sctp_rtoinfo);
   3439 	}
   3440 	break;
   3441 }
   3442 case SCTP_TIMEOUTS:
   3443 {
   3444 	struct sctp_timeouts *stimo;
   3445 
   3446 	SCTP_CHECK_AND_CAST(stimo, optval, struct sctp_timeouts, *optsize);
   3447 	SCTP_FIND_STCB(inp, stcb, stimo->stimo_assoc_id);
   3448 
   3449 	if (stcb) {
   3450 		stimo->stimo_init= stcb->asoc.timoinit;
   3451 		stimo->stimo_data= stcb->asoc.timodata;
   3452 		stimo->stimo_sack= stcb->asoc.timosack;
   3453 		stimo->stimo_shutdown= stcb->asoc.timoshutdown;
   3454 		stimo->stimo_heartbeat= stcb->asoc.timoheartbeat;
   3455 		stimo->stimo_cookie= stcb->asoc.timocookie;
   3456 		stimo->stimo_shutdownack= stcb->asoc.timoshutdownack;
   3457 		SCTP_TCB_UNLOCK(stcb);
   3458 		*optsize = sizeof(struct sctp_timeouts);
   3459 	} else {
   3460 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   3461 		error = EINVAL;
   3462 	}
   3463 	break;
   3464 }
   3465 case SCTP_ASSOCINFO:
   3466 {
   3467 	struct sctp_assocparams *sasoc;
   3468 
   3469 	SCTP_CHECK_AND_CAST(sasoc, optval, struct sctp_assocparams, *optsize);
   3470 	SCTP_FIND_STCB(inp, stcb, sasoc->sasoc_assoc_id);
   3471 
   3472 	if (stcb) {
   3473 		sasoc->sasoc_cookie_life = sctp_ticks_to_msecs(stcb->asoc.cookie_life);
   3474 		sasoc->sasoc_asocmaxrxt = stcb->asoc.max_send_times;
   3475 		sasoc->sasoc_number_peer_destinations = stcb->asoc.numnets;
   3476 		sasoc->sasoc_peer_rwnd = stcb->asoc.peers_rwnd;
   3477 		sasoc->sasoc_local_rwnd = stcb->asoc.my_rwnd;
   3478 		SCTP_TCB_UNLOCK(stcb);
   3479 	} else {
   3480 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   3481 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   3482 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   3483 		     (sasoc->sasoc_assoc_id == SCTP_FUTURE_ASSOC))) {
   3484 			SCTP_INP_RLOCK(inp);
   3485 			sasoc->sasoc_cookie_life = sctp_ticks_to_msecs(inp->sctp_ep.def_cookie_life);
   3486 			sasoc->sasoc_asocmaxrxt = inp->sctp_ep.max_send_times;
   3487 			sasoc->sasoc_number_peer_destinations = 0;
   3488 			sasoc->sasoc_peer_rwnd = 0;
   3489 			sasoc->sasoc_local_rwnd = (uint32_t)sbspace(&inp->sctp_socket->so_rcv);
   3490 			SCTP_INP_RUNLOCK(inp);
   3491 		} else {
   3492 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   3493 			error = EINVAL;
   3494 		}
   3495 	}
   3496 	if (error == 0) {
   3497 		*optsize = sizeof(struct sctp_assocparams);
   3498 	}
   3499 	break;
   3500 }
   3501 case SCTP_DEFAULT_SEND_PARAM:
   3502 {
   3503 	struct sctp_sndrcvinfo *s_info;
   3504 
   3505 	SCTP_CHECK_AND_CAST(s_info, optval, struct sctp_sndrcvinfo, *optsize);
   3506 	SCTP_FIND_STCB(inp, stcb, s_info->sinfo_assoc_id);
   3507 
   3508 	if (stcb) {
   3509 		memcpy(s_info, &stcb->asoc.def_send, sizeof(stcb->asoc.def_send));
   3510 		SCTP_TCB_UNLOCK(stcb);
   3511 	} else {
   3512 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   3513 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   3514 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   3515 		     (s_info->sinfo_assoc_id == SCTP_FUTURE_ASSOC))) {
   3516 			SCTP_INP_RLOCK(inp);
   3517 			memcpy(s_info, &inp->def_send, sizeof(inp->def_send));
   3518 			SCTP_INP_RUNLOCK(inp);
   3519 		} else {
   3520 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   3521 			error = EINVAL;
   3522 		}
   3523 	}
   3524 	if (error == 0) {
   3525 		*optsize = sizeof(struct sctp_sndrcvinfo);
   3526 	}
   3527 	break;
   3528 }
   3529 case SCTP_INITMSG:
   3530 {
   3531 	struct sctp_initmsg *sinit;
   3532 
   3533 	SCTP_CHECK_AND_CAST(sinit, optval, struct sctp_initmsg, *optsize);
   3534 	SCTP_INP_RLOCK(inp);
   3535 	sinit->sinit_num_ostreams = inp->sctp_ep.pre_open_stream_count;
   3536 	sinit->sinit_max_instreams = inp->sctp_ep.max_open_streams_intome;
   3537 	sinit->sinit_max_attempts = inp->sctp_ep.max_init_times;
   3538 	sinit->sinit_max_init_timeo = inp->sctp_ep.initial_init_rto_max;
   3539 	SCTP_INP_RUNLOCK(inp);
   3540 	*optsize = sizeof(struct sctp_initmsg);
   3541 	break;
   3542 }
   3543 case SCTP_PRIMARY_ADDR:
   3544 	/* we allow a "get" operation on this */
   3545 {
   3546 	struct sctp_setprim *ssp;
   3547 
   3548 	SCTP_CHECK_AND_CAST(ssp, optval, struct sctp_setprim, *optsize);
   3549 	SCTP_FIND_STCB(inp, stcb, ssp->ssp_assoc_id);
   3550 
   3551 	if (stcb) {
   3552 		union sctp_sockstore *addr;
   3553 
   3554 		addr = &stcb->asoc.primary_destination->ro._l_addr;
   3555 		switch (addr->sa.sa_family) {
   3556 #ifdef INET
   3557 		case AF_INET:
   3558 #ifdef INET6
   3559 			if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) {
   3560 				in6_sin_2_v4mapsin6(&addr->sin,
   3561 				                    (struct sockaddr_in6 *)&ssp->ssp_addr);
   3562 			} else {
   3563 				memcpy(&ssp->ssp_addr, &addr->sin, sizeof(struct sockaddr_in));
   3564 			}
   3565 #else
   3566 			memcpy(&ssp->ssp_addr, &addr->sin, sizeof(struct sockaddr_in));
   3567 #endif
   3568 			break;
   3569 #endif
   3570 #ifdef INET6
   3571 		case AF_INET6:
   3572 			memcpy(&ssp->ssp_addr, &addr->sin6, sizeof(struct sockaddr_in6));
   3573 			break;
   3574 #endif
   3575 #if defined(__Userspace__)
   3576 		case AF_CONN:
   3577 			memcpy(&ssp->ssp_addr, &addr->sconn, sizeof(struct sockaddr_conn));
   3578 			break;
   3579 #endif
   3580 		default:
   3581 			break;
   3582 		}
   3583 		SCTP_TCB_UNLOCK(stcb);
   3584 		*optsize = sizeof(struct sctp_setprim);
   3585 	} else {
   3586 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   3587 		error = EINVAL;
   3588 	}
   3589 	break;
   3590 }
   3591 case SCTP_HMAC_IDENT:
   3592 {
   3593 	struct sctp_hmacalgo *shmac;
   3594 	sctp_hmaclist_t *hmaclist;
   3595 	size_t size;
   3596 	int i;
   3597 
   3598 	SCTP_CHECK_AND_CAST(shmac, optval, struct sctp_hmacalgo, *optsize);
   3599 
   3600 	SCTP_INP_RLOCK(inp);
   3601 	hmaclist = inp->sctp_ep.local_hmacs;
   3602 	if (hmaclist == NULL) {
   3603 		/* no HMACs to return */
   3604 		*optsize = sizeof(*shmac);
   3605 		SCTP_INP_RUNLOCK(inp);
   3606 		break;
   3607 	}
   3608 	/* is there room for all of the hmac ids? */
   3609 	size = sizeof(*shmac) + (hmaclist->num_algo *
   3610 	                         sizeof(shmac->shmac_idents[0]));
   3611 	if (*optsize < size) {
   3612 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   3613 		error = EINVAL;
   3614 		SCTP_INP_RUNLOCK(inp);
   3615 		break;
   3616 	}
   3617 	/* copy in the list */
   3618 	shmac->shmac_number_of_idents = hmaclist->num_algo;
   3619 	for (i = 0; i < hmaclist->num_algo; i++) {
   3620 		shmac->shmac_idents[i] = hmaclist->hmac[i];
   3621 	}
   3622 	SCTP_INP_RUNLOCK(inp);
   3623 	*optsize = size;
   3624 	break;
   3625 }
   3626 case SCTP_AUTH_ACTIVE_KEY:
   3627 {
   3628 	struct sctp_authkeyid *scact;
   3629 
   3630 	SCTP_CHECK_AND_CAST(scact, optval, struct sctp_authkeyid, *optsize);
   3631 	SCTP_FIND_STCB(inp, stcb, scact->scact_assoc_id);
   3632 
   3633 	if (stcb) {
   3634 		/* get the active key on the assoc */
   3635 		scact->scact_keynumber = stcb->asoc.authinfo.active_keyid;
   3636 		SCTP_TCB_UNLOCK(stcb);
   3637 	} else {
   3638 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   3639 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   3640 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   3641 		     (scact->scact_assoc_id == SCTP_FUTURE_ASSOC))) {
   3642 			/* get the endpoint active key */
   3643 			SCTP_INP_RLOCK(inp);
   3644 			scact->scact_keynumber = inp->sctp_ep.default_keyid;
   3645 			SCTP_INP_RUNLOCK(inp);
   3646 		} else {
   3647 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   3648 			error = EINVAL;
   3649 		}
   3650 	}
   3651 	if (error == 0) {
   3652 		*optsize = sizeof(struct sctp_authkeyid);
   3653 	}
   3654 	break;
   3655 }
   3656 case SCTP_LOCAL_AUTH_CHUNKS:
   3657 {
   3658 	struct sctp_authchunks *sac;
   3659 	sctp_auth_chklist_t *chklist = NULL;
   3660 	size_t size = 0;
   3661 
   3662 	SCTP_CHECK_AND_CAST(sac, optval, struct sctp_authchunks, *optsize);
   3663 	SCTP_FIND_STCB(inp, stcb, sac->gauth_assoc_id);
   3664 
   3665 	if (stcb) {
   3666 		/* get off the assoc */
   3667 		chklist = stcb->asoc.local_auth_chunks;
   3668 		/* is there enough space? */
   3669 		size = sctp_auth_get_chklist_size(chklist);
   3670 		if (*optsize < (sizeof(struct sctp_authchunks) + size)) {
   3671 			error = EINVAL;
   3672 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
   3673 		} else {
   3674 			/* copy in the chunks */
   3675 			(void)sctp_serialize_auth_chunks(chklist, sac->gauth_chunks);
   3676 			sac->gauth_number_of_chunks = (uint32_t)size;
   3677 			*optsize = sizeof(struct sctp_authchunks) + size;
   3678 		}
   3679 		SCTP_TCB_UNLOCK(stcb);
   3680 	} else {
   3681 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   3682 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   3683 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   3684 		     (sac->gauth_assoc_id == SCTP_FUTURE_ASSOC))) {
   3685 			/* get off the endpoint */
   3686 			SCTP_INP_RLOCK(inp);
   3687 			chklist = inp->sctp_ep.local_auth_chunks;
   3688 			/* is there enough space? */
   3689 			size = sctp_auth_get_chklist_size(chklist);
   3690 			if (*optsize < (sizeof(struct sctp_authchunks) + size)) {
   3691 				error = EINVAL;
   3692 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
   3693 			} else {
   3694 				/* copy in the chunks */
   3695 				(void)sctp_serialize_auth_chunks(chklist, sac->gauth_chunks);
   3696 				sac->gauth_number_of_chunks = (uint32_t)size;
   3697 				*optsize = sizeof(struct sctp_authchunks) + size;
   3698 			}
   3699 			SCTP_INP_RUNLOCK(inp);
   3700 		} else {
   3701 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   3702 			error = EINVAL;
   3703 		}
   3704 	}
   3705 	break;
   3706 }
   3707 case SCTP_PEER_AUTH_CHUNKS:
   3708 {
   3709 	struct sctp_authchunks *sac;
   3710 	sctp_auth_chklist_t *chklist = NULL;
   3711 	size_t size = 0;
   3712 
   3713 	SCTP_CHECK_AND_CAST(sac, optval, struct sctp_authchunks, *optsize);
   3714 	SCTP_FIND_STCB(inp, stcb, sac->gauth_assoc_id);
   3715 
   3716 	if (stcb) {
   3717 		/* get off the assoc */
   3718 		chklist = stcb->asoc.peer_auth_chunks;
   3719 		/* is there enough space? */
   3720 		size = sctp_auth_get_chklist_size(chklist);
   3721 		if (*optsize < (sizeof(struct sctp_authchunks) + size)) {
   3722 			error = EINVAL;
   3723 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
   3724 		} else {
   3725 			/* copy in the chunks */
   3726 			(void)sctp_serialize_auth_chunks(chklist, sac->gauth_chunks);
   3727 			sac->gauth_number_of_chunks = (uint32_t)size;
   3728 			*optsize = sizeof(struct sctp_authchunks) + size;
   3729 		}
   3730 		SCTP_TCB_UNLOCK(stcb);
   3731 	} else {
   3732 	        SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT);
   3733 		error = ENOENT;
   3734 	}
   3735 	break;
   3736 }
   3737 #if defined(HAVE_SCTP_PEELOFF_SOCKOPT)
   3738 case SCTP_PEELOFF:
   3739 {
   3740 	struct sctp_peeloff_opt *peeloff;
   3741 
   3742 	SCTP_CHECK_AND_CAST(peeloff, optval, struct sctp_peeloff_opt, *optsize);
   3743 	/* do the peeloff */
   3744 	error = sctp_peeloff_option(p, peeloff);
   3745 	if (error == 0) {
   3746 		*optsize = sizeof(struct sctp_peeloff_opt);
   3747 	}
   3748 }
   3749 break;
   3750 #endif /* HAVE_SCTP_PEELOFF_SOCKOPT */
   3751 case SCTP_EVENT:
   3752 {
   3753 	struct sctp_event *event;
   3754 	uint32_t event_type;
   3755 
   3756 	SCTP_CHECK_AND_CAST(event, optval, struct sctp_event, *optsize);
   3757 	SCTP_FIND_STCB(inp, stcb, event->se_assoc_id);
   3758 
   3759 	switch (event->se_type) {
   3760 	case SCTP_ASSOC_CHANGE:
   3761 		event_type = SCTP_PCB_FLAGS_RECVASSOCEVNT;
   3762 		break;
   3763 	case SCTP_PEER_ADDR_CHANGE:
   3764 		event_type = SCTP_PCB_FLAGS_RECVPADDREVNT;
   3765 		break;
   3766 	case SCTP_REMOTE_ERROR:
   3767 		event_type = SCTP_PCB_FLAGS_RECVPEERERR;
   3768 		break;
   3769 	case SCTP_SEND_FAILED:
   3770 		event_type = SCTP_PCB_FLAGS_RECVSENDFAILEVNT;
   3771 		break;
   3772 	case SCTP_SHUTDOWN_EVENT:
   3773 		event_type = SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT;
   3774 		break;
   3775 	case SCTP_ADAPTATION_INDICATION:
   3776 		event_type = SCTP_PCB_FLAGS_ADAPTATIONEVNT;
   3777 		break;
   3778 	case SCTP_PARTIAL_DELIVERY_EVENT:
   3779 		event_type = SCTP_PCB_FLAGS_PDAPIEVNT;
   3780 		break;
   3781 	case SCTP_AUTHENTICATION_EVENT:
   3782 		event_type = SCTP_PCB_FLAGS_AUTHEVNT;
   3783 		break;
   3784 	case SCTP_STREAM_RESET_EVENT:
   3785 		event_type = SCTP_PCB_FLAGS_STREAM_RESETEVNT;
   3786 		break;
   3787 	case SCTP_SENDER_DRY_EVENT:
   3788 		event_type = SCTP_PCB_FLAGS_DRYEVNT;
   3789 		break;
   3790 	case SCTP_NOTIFICATIONS_STOPPED_EVENT:
   3791 		event_type = 0;
   3792 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTSUP);
   3793 		error = ENOTSUP;
   3794 		break;
   3795 	case SCTP_ASSOC_RESET_EVENT:
   3796 		event_type = SCTP_PCB_FLAGS_ASSOC_RESETEVNT;
   3797 		break;
   3798 	case SCTP_STREAM_CHANGE_EVENT:
   3799 		event_type = SCTP_PCB_FLAGS_STREAM_CHANGEEVNT;
   3800 		break;
   3801 	case SCTP_SEND_FAILED_EVENT:
   3802 		event_type = SCTP_PCB_FLAGS_RECVNSENDFAILEVNT;
   3803 		break;
   3804 	default:
   3805 		event_type = 0;
   3806 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   3807 		error = EINVAL;
   3808 		break;
   3809 	}
   3810 	if (event_type > 0) {
   3811 		if (stcb) {
   3812 			event->se_on = sctp_stcb_is_feature_on(inp, stcb, event_type);
   3813 		} else {
   3814 			if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   3815 			    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   3816 			    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   3817 			     (event->se_assoc_id == SCTP_FUTURE_ASSOC))) {
   3818 				SCTP_INP_RLOCK(inp);
   3819 				event->se_on = sctp_is_feature_on(inp, event_type);
   3820 				SCTP_INP_RUNLOCK(inp);
   3821 			} else {
   3822 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   3823 				error = EINVAL;
   3824 			}
   3825 		}
   3826 	}
   3827 	if (stcb != NULL) {
   3828 		SCTP_TCB_UNLOCK(stcb);
   3829 	}
   3830 	if (error == 0) {
   3831 		*optsize = sizeof(struct sctp_event);
   3832 	}
   3833 	break;
   3834 }
   3835 case SCTP_RECVRCVINFO:
   3836 	if (*optsize < sizeof(int)) {
   3837 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   3838 		error = EINVAL;
   3839 	} else {
   3840 		SCTP_INP_RLOCK(inp);
   3841 		*(int *)optval = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVRCVINFO);
   3842 		SCTP_INP_RUNLOCK(inp);
   3843 		*optsize = sizeof(int);
   3844 	}
   3845 	break;
   3846 case SCTP_RECVNXTINFO:
   3847 	if (*optsize < sizeof(int)) {
   3848 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   3849 		error = EINVAL;
   3850 	} else {
   3851 		SCTP_INP_RLOCK(inp);
   3852 		*(int *)optval = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVNXTINFO);
   3853 		SCTP_INP_RUNLOCK(inp);
   3854 		*optsize = sizeof(int);
   3855 	}
   3856 	break;
   3857 case SCTP_DEFAULT_SNDINFO:
   3858 {
   3859 	struct sctp_sndinfo *info;
   3860 
   3861 	SCTP_CHECK_AND_CAST(info, optval, struct sctp_sndinfo, *optsize);
   3862 	SCTP_FIND_STCB(inp, stcb, info->snd_assoc_id);
   3863 
   3864 	if (stcb) {
   3865 		info->snd_sid = stcb->asoc.def_send.sinfo_stream;
   3866 		info->snd_flags = stcb->asoc.def_send.sinfo_flags;
   3867 		info->snd_flags &= 0xfff0;
   3868 		info->snd_ppid = stcb->asoc.def_send.sinfo_ppid;
   3869 		info->snd_context = stcb->asoc.def_send.sinfo_context;
   3870 		SCTP_TCB_UNLOCK(stcb);
   3871 	} else {
   3872 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   3873 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   3874 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   3875 		     (info->snd_assoc_id == SCTP_FUTURE_ASSOC))) {
   3876 			SCTP_INP_RLOCK(inp);
   3877 			info->snd_sid = inp->def_send.sinfo_stream;
   3878 			info->snd_flags = inp->def_send.sinfo_flags;
   3879 			info->snd_flags &= 0xfff0;
   3880 			info->snd_ppid = inp->def_send.sinfo_ppid;
   3881 			info->snd_context = inp->def_send.sinfo_context;
   3882 			SCTP_INP_RUNLOCK(inp);
   3883 		} else {
   3884 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   3885 			error = EINVAL;
   3886 		}
   3887 	}
   3888 	if (error == 0) {
   3889 		*optsize = sizeof(struct sctp_sndinfo);
   3890 	}
   3891 	break;
   3892 }
   3893 case SCTP_DEFAULT_PRINFO:
   3894 {
   3895 	struct sctp_default_prinfo *info;
   3896 
   3897 	SCTP_CHECK_AND_CAST(info, optval, struct sctp_default_prinfo, *optsize);
   3898 	SCTP_FIND_STCB(inp, stcb, info->pr_assoc_id);
   3899 
   3900 	if (stcb) {
   3901 		info->pr_policy = PR_SCTP_POLICY(stcb->asoc.def_send.sinfo_flags);
   3902 		info->pr_value = stcb->asoc.def_send.sinfo_timetolive;
   3903 		SCTP_TCB_UNLOCK(stcb);
   3904 	} else {
   3905 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   3906 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   3907 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   3908 		     (info->pr_assoc_id == SCTP_FUTURE_ASSOC))) {
   3909 			SCTP_INP_RLOCK(inp);
   3910 			info->pr_policy = PR_SCTP_POLICY(inp->def_send.sinfo_flags);
   3911 			info->pr_value = inp->def_send.sinfo_timetolive;
   3912 			SCTP_INP_RUNLOCK(inp);
   3913 		} else {
   3914 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   3915 			error = EINVAL;
   3916 		}
   3917 	}
   3918 	if (error == 0) {
   3919 		*optsize = sizeof(struct sctp_default_prinfo);
   3920 	}
   3921 	break;
   3922 }
   3923 case SCTP_PEER_ADDR_THLDS:
   3924 {
   3925 	struct sctp_paddrthlds *thlds;
   3926 	struct sctp_nets *net;
   3927 	struct sockaddr *addr;
   3928 #if defined(INET) && defined(INET6)
   3929 	struct sockaddr_in sin_store;
   3930 #endif
   3931 
   3932 	SCTP_CHECK_AND_CAST(thlds, optval, struct sctp_paddrthlds, *optsize);
   3933 	SCTP_FIND_STCB(inp, stcb, thlds->spt_assoc_id);
   3934 
   3935 #if defined(INET) && defined(INET6)
   3936 	if (thlds->spt_address.ss_family == AF_INET6) {
   3937 		struct sockaddr_in6 *sin6;
   3938 
   3939 		sin6 = (struct sockaddr_in6 *)&thlds->spt_address;
   3940 		if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
   3941 			in6_sin6_2_sin(&sin_store, sin6);
   3942 			addr = (struct sockaddr *)&sin_store;
   3943 		} else {
   3944 			addr = (struct sockaddr *)&thlds->spt_address;
   3945 		}
   3946 	} else {
   3947 		addr = (struct sockaddr *)&thlds->spt_address;
   3948 	}
   3949 #else
   3950 	addr = (struct sockaddr *)&thlds->spt_address;
   3951 #endif
   3952 	if (stcb != NULL) {
   3953 		net = sctp_findnet(stcb, addr);
   3954 	} else {
   3955 		/* We increment here since sctp_findassociation_ep_addr() wil
   3956 		 * do a decrement if it finds the stcb as long as the locked
   3957 		 * tcb (last argument) is NOT a TCB.. aka NULL.
   3958 		 */
   3959 		net = NULL;
   3960 		SCTP_INP_INCR_REF(inp);
   3961 		stcb = sctp_findassociation_ep_addr(&inp, addr, &net, NULL, NULL);
   3962 		if (stcb == NULL) {
   3963 			SCTP_INP_DECR_REF(inp);
   3964 		}
   3965 	}
   3966 	if ((stcb != NULL) && (net == NULL)) {
   3967 #ifdef INET
   3968 		if (addr->sa_family == AF_INET) {
   3969 			struct sockaddr_in *sin;
   3970 
   3971 			sin = (struct sockaddr_in *)addr;
   3972 			if (sin->sin_addr.s_addr != INADDR_ANY) {
   3973 				error = EINVAL;
   3974 				SCTP_TCB_UNLOCK(stcb);
   3975 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
   3976 				break;
   3977 			}
   3978 		} else
   3979 #endif
   3980 #ifdef INET6
   3981 		if (addr->sa_family == AF_INET6) {
   3982 			struct sockaddr_in6 *sin6;
   3983 
   3984 			sin6 = (struct sockaddr_in6 *)addr;
   3985 			if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
   3986 				error = EINVAL;
   3987 				SCTP_TCB_UNLOCK(stcb);
   3988 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
   3989 				break;
   3990 			}
   3991 		} else
   3992 #endif
   3993 #if defined(__Userspace__)
   3994 		if (addr->sa_family == AF_CONN) {
   3995 			struct sockaddr_conn *sconn;
   3996 
   3997 			sconn = (struct sockaddr_conn *)addr;
   3998 			if (sconn->sconn_addr != NULL) {
   3999 				error = EINVAL;
   4000 				SCTP_TCB_UNLOCK(stcb);
   4001 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
   4002 				break;
   4003 			}
   4004 		} else
   4005 #endif
   4006 		{
   4007 			error = EAFNOSUPPORT;
   4008 			SCTP_TCB_UNLOCK(stcb);
   4009 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
   4010 			break;
   4011 		}
   4012 	}
   4013 
   4014 	if (stcb != NULL) {
   4015 		if (net != NULL) {
   4016 			thlds->spt_pathmaxrxt = net->failure_threshold;
   4017 			thlds->spt_pathpfthld = net->pf_threshold;
   4018 			thlds->spt_pathcpthld = 0xffff;
   4019 		} else {
   4020 			thlds->spt_pathmaxrxt = stcb->asoc.def_net_failure;
   4021 			thlds->spt_pathpfthld = stcb->asoc.def_net_pf_threshold;
   4022 			thlds->spt_pathcpthld = 0xffff;
   4023 		}
   4024 		thlds->spt_assoc_id = sctp_get_associd(stcb);
   4025 		SCTP_TCB_UNLOCK(stcb);
   4026 	} else {
   4027 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   4028 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   4029 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   4030 		     (thlds->spt_assoc_id == SCTP_FUTURE_ASSOC))) {
   4031 			/* Use endpoint defaults */
   4032 			SCTP_INP_RLOCK(inp);
   4033 			thlds->spt_pathmaxrxt = inp->sctp_ep.def_net_failure;
   4034 			thlds->spt_pathpfthld = inp->sctp_ep.def_net_pf_threshold;
   4035 			thlds->spt_pathcpthld = 0xffff;
   4036 			SCTP_INP_RUNLOCK(inp);
   4037 		} else {
   4038 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   4039 			error = EINVAL;
   4040 		}
   4041 	}
   4042 	if (error == 0) {
   4043 		*optsize = sizeof(struct sctp_paddrthlds);
   4044 	}
   4045 	break;
   4046 }
   4047 case SCTP_REMOTE_UDP_ENCAPS_PORT:
   4048 {
   4049 	struct sctp_udpencaps *encaps;
   4050 	struct sctp_nets *net;
   4051 	struct sockaddr *addr;
   4052 #if defined(INET) && defined(INET6)
   4053 	struct sockaddr_in sin_store;
   4054 #endif
   4055 
   4056 	SCTP_CHECK_AND_CAST(encaps, optval, struct sctp_udpencaps, *optsize);
   4057 	SCTP_FIND_STCB(inp, stcb, encaps->sue_assoc_id);
   4058 
   4059 #if defined(INET) && defined(INET6)
   4060 	if (encaps->sue_address.ss_family == AF_INET6) {
   4061 		struct sockaddr_in6 *sin6;
   4062 
   4063 		sin6 = (struct sockaddr_in6 *)&encaps->sue_address;
   4064 		if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
   4065 			in6_sin6_2_sin(&sin_store, sin6);
   4066 			addr = (struct sockaddr *)&sin_store;
   4067 		} else {
   4068 			addr = (struct sockaddr *)&encaps->sue_address;
   4069 		}
   4070 	} else {
   4071 		addr = (struct sockaddr *)&encaps->sue_address;
   4072 	}
   4073 #else
   4074 	addr = (struct sockaddr *)&encaps->sue_address;
   4075 #endif
   4076 	if (stcb) {
   4077 		net = sctp_findnet(stcb, addr);
   4078 	} else {
   4079 		/* We increment here since sctp_findassociation_ep_addr() wil
   4080 		 * do a decrement if it finds the stcb as long as the locked
   4081 		 * tcb (last argument) is NOT a TCB.. aka NULL.
   4082 		 */
   4083 		net = NULL;
   4084 		SCTP_INP_INCR_REF(inp);
   4085 		stcb = sctp_findassociation_ep_addr(&inp, addr, &net, NULL, NULL);
   4086 		if (stcb == NULL) {
   4087 			SCTP_INP_DECR_REF(inp);
   4088 		}
   4089 	}
   4090 	if ((stcb != NULL) && (net == NULL)) {
   4091 #ifdef INET
   4092 		if (addr->sa_family == AF_INET) {
   4093 			struct sockaddr_in *sin;
   4094 
   4095 			sin = (struct sockaddr_in *)addr;
   4096 			if (sin->sin_addr.s_addr != INADDR_ANY) {
   4097 				error = EINVAL;
   4098 				SCTP_TCB_UNLOCK(stcb);
   4099 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
   4100 				break;
   4101 			}
   4102 		} else
   4103 #endif
   4104 #ifdef INET6
   4105 		if (addr->sa_family == AF_INET6) {
   4106 			struct sockaddr_in6 *sin6;
   4107 
   4108 			sin6 = (struct sockaddr_in6 *)addr;
   4109 			if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
   4110 				error = EINVAL;
   4111 				SCTP_TCB_UNLOCK(stcb);
   4112 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
   4113 				break;
   4114 			}
   4115 		} else
   4116 #endif
   4117 #if defined(__Userspace__)
   4118 		if (addr->sa_family == AF_CONN) {
   4119 			struct sockaddr_conn *sconn;
   4120 
   4121 			sconn = (struct sockaddr_conn *)addr;
   4122 			if (sconn->sconn_addr != NULL) {
   4123 				error = EINVAL;
   4124 				SCTP_TCB_UNLOCK(stcb);
   4125 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
   4126 				break;
   4127 			}
   4128 		} else
   4129 #endif
   4130 		{
   4131 			error = EAFNOSUPPORT;
   4132 			SCTP_TCB_UNLOCK(stcb);
   4133 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
   4134 			break;
   4135 		}
   4136 	}
   4137 
   4138 	if (stcb != NULL) {
   4139 		if (net) {
   4140 			encaps->sue_port = net->port;
   4141 		} else {
   4142 			encaps->sue_port = stcb->asoc.port;
   4143 		}
   4144 		SCTP_TCB_UNLOCK(stcb);
   4145 	} else {
   4146 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   4147 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   4148 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   4149 		     (encaps->sue_assoc_id == SCTP_FUTURE_ASSOC))) {
   4150 			SCTP_INP_RLOCK(inp);
   4151 			encaps->sue_port = inp->sctp_ep.port;
   4152 			SCTP_INP_RUNLOCK(inp);
   4153 		} else {
   4154 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   4155 			error = EINVAL;
   4156 		}
   4157 	}
   4158 	if (error == 0) {
   4159 		*optsize = sizeof(struct sctp_udpencaps);
   4160 	}
   4161 	break;
   4162 }
   4163 case SCTP_ECN_SUPPORTED:
   4164 {
   4165 	struct sctp_assoc_value *av;
   4166 
   4167 	SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
   4168 	SCTP_FIND_STCB(inp, stcb, av->assoc_id);
   4169 
   4170 	if (stcb) {
   4171 		av->assoc_value = stcb->asoc.ecn_supported;
   4172 		SCTP_TCB_UNLOCK(stcb);
   4173 	} else {
   4174 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   4175 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   4176 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   4177 		     (av->assoc_id == SCTP_FUTURE_ASSOC))) {
   4178 			SCTP_INP_RLOCK(inp);
   4179 			av->assoc_value = inp->ecn_supported;
   4180 			SCTP_INP_RUNLOCK(inp);
   4181 		} else {
   4182 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   4183 			error = EINVAL;
   4184 		}
   4185 	}
   4186 	if (error == 0) {
   4187 		*optsize = sizeof(struct sctp_assoc_value);
   4188 	}
   4189 	break;
   4190 }
   4191 case SCTP_PR_SUPPORTED:
   4192 {
   4193 	struct sctp_assoc_value *av;
   4194 
   4195 	SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
   4196 	SCTP_FIND_STCB(inp, stcb, av->assoc_id);
   4197 
   4198 	if (stcb) {
   4199 		av->assoc_value = stcb->asoc.prsctp_supported;
   4200 		SCTP_TCB_UNLOCK(stcb);
   4201 	} else {
   4202 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   4203 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   4204 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   4205 		     (av->assoc_id == SCTP_FUTURE_ASSOC))) {
   4206 			SCTP_INP_RLOCK(inp);
   4207 			av->assoc_value = inp->prsctp_supported;
   4208 			SCTP_INP_RUNLOCK(inp);
   4209 		} else {
   4210 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   4211 			error = EINVAL;
   4212 		}
   4213 	}
   4214 	if (error == 0) {
   4215 		*optsize = sizeof(struct sctp_assoc_value);
   4216 	}
   4217 	break;
   4218 }
   4219 case SCTP_AUTH_SUPPORTED:
   4220 {
   4221 	struct sctp_assoc_value *av;
   4222 
   4223 	SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
   4224 	SCTP_FIND_STCB(inp, stcb, av->assoc_id);
   4225 
   4226 	if (stcb) {
   4227 		av->assoc_value = stcb->asoc.auth_supported;
   4228 		SCTP_TCB_UNLOCK(stcb);
   4229 	} else {
   4230 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   4231 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   4232 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   4233 		     (av->assoc_id == SCTP_FUTURE_ASSOC))) {
   4234 			SCTP_INP_RLOCK(inp);
   4235 			av->assoc_value = inp->auth_supported;
   4236 			SCTP_INP_RUNLOCK(inp);
   4237 		} else {
   4238 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   4239 			error = EINVAL;
   4240 		}
   4241 	}
   4242 	if (error == 0) {
   4243 		*optsize = sizeof(struct sctp_assoc_value);
   4244 	}
   4245 	break;
   4246 }
   4247 case SCTP_ASCONF_SUPPORTED:
   4248 {
   4249 	struct sctp_assoc_value *av;
   4250 
   4251 	SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
   4252 	SCTP_FIND_STCB(inp, stcb, av->assoc_id);
   4253 
   4254 	if (stcb) {
   4255 		av->assoc_value = stcb->asoc.asconf_supported;
   4256 		SCTP_TCB_UNLOCK(stcb);
   4257 	} else {
   4258 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   4259 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   4260 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   4261 		     (av->assoc_id == SCTP_FUTURE_ASSOC))) {
   4262 			SCTP_INP_RLOCK(inp);
   4263 			av->assoc_value = inp->asconf_supported;
   4264 			SCTP_INP_RUNLOCK(inp);
   4265 		} else {
   4266 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   4267 			error = EINVAL;
   4268 		}
   4269 	}
   4270 	if (error == 0) {
   4271 		*optsize = sizeof(struct sctp_assoc_value);
   4272 	}
   4273 	break;
   4274 }
   4275 case SCTP_RECONFIG_SUPPORTED:
   4276 {
   4277 	struct sctp_assoc_value *av;
   4278 
   4279 	SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
   4280 	SCTP_FIND_STCB(inp, stcb, av->assoc_id);
   4281 
   4282 	if (stcb) {
   4283 		av->assoc_value = stcb->asoc.reconfig_supported;
   4284 		SCTP_TCB_UNLOCK(stcb);
   4285 	} else {
   4286 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   4287 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   4288 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   4289 		     (av->assoc_id == SCTP_FUTURE_ASSOC))) {
   4290 			SCTP_INP_RLOCK(inp);
   4291 			av->assoc_value = inp->reconfig_supported;
   4292 			SCTP_INP_RUNLOCK(inp);
   4293 		} else {
   4294 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   4295 			error = EINVAL;
   4296 		}
   4297 	}
   4298 	if (error == 0) {
   4299 		*optsize = sizeof(struct sctp_assoc_value);
   4300 	}
   4301 	break;
   4302 }
   4303 case SCTP_NRSACK_SUPPORTED:
   4304 {
   4305 	struct sctp_assoc_value *av;
   4306 
   4307 	SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
   4308 	SCTP_FIND_STCB(inp, stcb, av->assoc_id);
   4309 
   4310 	if (stcb) {
   4311 		av->assoc_value = stcb->asoc.nrsack_supported;
   4312 		SCTP_TCB_UNLOCK(stcb);
   4313 	} else {
   4314 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   4315 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   4316 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   4317 		     (av->assoc_id == SCTP_FUTURE_ASSOC))) {
   4318 			SCTP_INP_RLOCK(inp);
   4319 			av->assoc_value = inp->nrsack_supported;
   4320 			SCTP_INP_RUNLOCK(inp);
   4321 		} else {
   4322 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   4323 			error = EINVAL;
   4324 		}
   4325 	}
   4326 	if (error == 0) {
   4327 		*optsize = sizeof(struct sctp_assoc_value);
   4328 	}
   4329 	break;
   4330 }
   4331 case SCTP_PKTDROP_SUPPORTED:
   4332 {
   4333 	struct sctp_assoc_value *av;
   4334 
   4335 	SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
   4336 	SCTP_FIND_STCB(inp, stcb, av->assoc_id);
   4337 
   4338 	if (stcb) {
   4339 		av->assoc_value = stcb->asoc.pktdrop_supported;
   4340 		SCTP_TCB_UNLOCK(stcb);
   4341 	} else {
   4342 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   4343 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   4344 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   4345 		     (av->assoc_id == SCTP_FUTURE_ASSOC))) {
   4346 			SCTP_INP_RLOCK(inp);
   4347 			av->assoc_value = inp->pktdrop_supported;
   4348 			SCTP_INP_RUNLOCK(inp);
   4349 		} else {
   4350 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   4351 			error = EINVAL;
   4352 		}
   4353 	}
   4354 	if (error == 0) {
   4355 		*optsize = sizeof(struct sctp_assoc_value);
   4356 	}
   4357 	break;
   4358 }
   4359 case SCTP_ENABLE_STREAM_RESET:
   4360 {
   4361 	struct sctp_assoc_value *av;
   4362 
   4363 	SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
   4364 	SCTP_FIND_STCB(inp, stcb, av->assoc_id);
   4365 
   4366 	if (stcb) {
   4367 		av->assoc_value = (uint32_t)stcb->asoc.local_strreset_support;
   4368 		SCTP_TCB_UNLOCK(stcb);
   4369 	} else {
   4370 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   4371 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   4372 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   4373 		     (av->assoc_id == SCTP_FUTURE_ASSOC))) {
   4374 			SCTP_INP_RLOCK(inp);
   4375 			av->assoc_value = (uint32_t)inp->local_strreset_support;
   4376 			SCTP_INP_RUNLOCK(inp);
   4377 		} else {
   4378 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   4379 			error = EINVAL;
   4380 		}
   4381 	}
   4382 	if (error == 0) {
   4383 		*optsize = sizeof(struct sctp_assoc_value);
   4384 	}
   4385 	break;
   4386 }
   4387 case SCTP_PR_STREAM_STATUS:
   4388 {
   4389 	struct sctp_prstatus *sprstat;
   4390 	uint16_t sid;
   4391 	uint16_t policy;
   4392 
   4393 	SCTP_CHECK_AND_CAST(sprstat, optval, struct sctp_prstatus, *optsize);
   4394 	SCTP_FIND_STCB(inp, stcb, sprstat->sprstat_assoc_id);
   4395 
   4396 	sid = sprstat->sprstat_sid;
   4397 	policy = sprstat->sprstat_policy;
   4398 #if defined(SCTP_DETAILED_STR_STATS)
   4399 	if ((stcb != NULL) &&
   4400 	    (sid < stcb->asoc.streamoutcnt) &&
   4401 	    (policy != SCTP_PR_SCTP_NONE) &&
   4402 	    ((policy <= SCTP_PR_SCTP_MAX) ||
   4403 	     (policy == SCTP_PR_SCTP_ALL))) {
   4404 		if (policy == SCTP_PR_SCTP_ALL) {
   4405 			sprstat->sprstat_abandoned_unsent = stcb->asoc.strmout[sid].abandoned_unsent[0];
   4406 			sprstat->sprstat_abandoned_sent = stcb->asoc.strmout[sid].abandoned_sent[0];
   4407 		} else {
   4408 			sprstat->sprstat_abandoned_unsent = stcb->asoc.strmout[sid].abandoned_unsent[policy];
   4409 			sprstat->sprstat_abandoned_sent = stcb->asoc.strmout[sid].abandoned_sent[policy];
   4410 		}
   4411 #else
   4412 	if ((stcb != NULL) &&
   4413 	    (sid < stcb->asoc.streamoutcnt) &&
   4414 	    (policy == SCTP_PR_SCTP_ALL)) {
   4415 		sprstat->sprstat_abandoned_unsent = stcb->asoc.strmout[sid].abandoned_unsent[0];
   4416 		sprstat->sprstat_abandoned_sent = stcb->asoc.strmout[sid].abandoned_sent[0];
   4417 #endif
   4418 	} else {
   4419 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   4420 		error = EINVAL;
   4421 	}
   4422 	if (stcb != NULL) {
   4423 		SCTP_TCB_UNLOCK(stcb);
   4424 	}
   4425 	if (error == 0) {
   4426 		*optsize = sizeof(struct sctp_prstatus);
   4427 	}
   4428 	break;
   4429 }
   4430 case SCTP_PR_ASSOC_STATUS:
   4431 {
   4432 	struct sctp_prstatus *sprstat;
   4433 	uint16_t policy;
   4434 
   4435 	SCTP_CHECK_AND_CAST(sprstat, optval, struct sctp_prstatus, *optsize);
   4436 	SCTP_FIND_STCB(inp, stcb, sprstat->sprstat_assoc_id);
   4437 
   4438 	policy = sprstat->sprstat_policy;
   4439 	if ((stcb != NULL) &&
   4440 	    (policy != SCTP_PR_SCTP_NONE) &&
   4441 	    ((policy <= SCTP_PR_SCTP_MAX) ||
   4442 	     (policy == SCTP_PR_SCTP_ALL))) {
   4443 		if (policy == SCTP_PR_SCTP_ALL) {
   4444 			sprstat->sprstat_abandoned_unsent = stcb->asoc.abandoned_unsent[0];
   4445 			sprstat->sprstat_abandoned_sent = stcb->asoc.abandoned_sent[0];
   4446 		} else {
   4447 			sprstat->sprstat_abandoned_unsent = stcb->asoc.abandoned_unsent[policy];
   4448 			sprstat->sprstat_abandoned_sent = stcb->asoc.abandoned_sent[policy];
   4449 		}
   4450 	} else {
   4451 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   4452 		error = EINVAL;
   4453 	}
   4454 	if (stcb != NULL) {
   4455 		SCTP_TCB_UNLOCK(stcb);
   4456 	}
   4457 	if (error == 0) {
   4458 		*optsize = sizeof(struct sctp_prstatus);
   4459 	}
   4460 	break;
   4461 }
   4462 case SCTP_MAX_CWND:
   4463 {
   4464 	struct sctp_assoc_value *av;
   4465 
   4466 	SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
   4467 	SCTP_FIND_STCB(inp, stcb, av->assoc_id);
   4468 
   4469 	if (stcb) {
   4470 		av->assoc_value = stcb->asoc.max_cwnd;
   4471 		SCTP_TCB_UNLOCK(stcb);
   4472 	} else {
   4473 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   4474 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   4475 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   4476 		     (av->assoc_id == SCTP_FUTURE_ASSOC))) {
   4477 			SCTP_INP_RLOCK(inp);
   4478 			av->assoc_value = inp->max_cwnd;
   4479 			SCTP_INP_RUNLOCK(inp);
   4480 		} else {
   4481 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   4482 			error = EINVAL;
   4483 		}
   4484 	}
   4485 	if (error == 0) {
   4486 		*optsize = sizeof(struct sctp_assoc_value);
   4487 	}
   4488 	break;
   4489 }
   4490 default:
   4491 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT);
   4492 	error = ENOPROTOOPT;
   4493 	break;
   4494 } /* end switch (sopt->sopt_name) */
   4495 if (error) {
   4496 	*optsize = 0;
   4497 }
   4498 return (error);
   4499 }
   4500 
   4501 #if defined(__Userspace__)
   4502 int
   4503 #else
   4504 static int
   4505 #endif
   4506 sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
   4507     void *p)
   4508 {
   4509 int error, set_opt;
   4510 uint32_t *mopt;
   4511 struct sctp_tcb *stcb = NULL;
   4512 struct sctp_inpcb *inp = NULL;
   4513 uint32_t vrf_id;
   4514 
   4515 if (optval == NULL) {
   4516 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   4517 	return (EINVAL);
   4518 }
   4519 inp = (struct sctp_inpcb *)so->so_pcb;
   4520 if (inp == NULL) {
   4521 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   4522 	return (EINVAL);
   4523 }
   4524 vrf_id = inp->def_vrf_id;
   4525 
   4526 error = 0;
   4527 switch (optname) {
   4528 case SCTP_NODELAY:
   4529 case SCTP_AUTOCLOSE:
   4530 case SCTP_AUTO_ASCONF:
   4531 case SCTP_EXPLICIT_EOR:
   4532 case SCTP_DISABLE_FRAGMENTS:
   4533 case SCTP_USE_EXT_RCVINFO:
   4534 case SCTP_I_WANT_MAPPED_V4_ADDR:
   4535 	/* copy in the option value */
   4536 	SCTP_CHECK_AND_CAST(mopt, optval, uint32_t, optsize);
   4537 	set_opt = 0;
   4538 	if (error)
   4539 		break;
   4540 	switch (optname) {
   4541 	case SCTP_DISABLE_FRAGMENTS:
   4542 		set_opt = SCTP_PCB_FLAGS_NO_FRAGMENT;
   4543 		break;
   4544 	case SCTP_AUTO_ASCONF:
   4545 		/*
   4546 		 * NOTE: we don't really support this flag
   4547 		 */
   4548 		if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
   4549 			/* only valid for bound all sockets */
   4550 			if ((SCTP_BASE_SYSCTL(sctp_auto_asconf) == 0) &&
   4551 			    (*mopt != 0)) {
   4552 				/* forbidden by admin */
   4553 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EPERM);
   4554 				return (EPERM);
   4555 			}
   4556 			set_opt = SCTP_PCB_FLAGS_AUTO_ASCONF;
   4557 		} else {
   4558 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   4559 			return (EINVAL);
   4560 		}
   4561 		break;
   4562 	case SCTP_EXPLICIT_EOR:
   4563 		set_opt = SCTP_PCB_FLAGS_EXPLICIT_EOR;
   4564 		break;
   4565 	case SCTP_USE_EXT_RCVINFO:
   4566 		set_opt = SCTP_PCB_FLAGS_EXT_RCVINFO;
   4567 		break;
   4568 	case SCTP_I_WANT_MAPPED_V4_ADDR:
   4569 		if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
   4570 			set_opt = SCTP_PCB_FLAGS_NEEDS_MAPPED_V4;
   4571 		} else {
   4572 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   4573 			return (EINVAL);
   4574 		}
   4575 		break;
   4576 	case SCTP_NODELAY:
   4577 		set_opt = SCTP_PCB_FLAGS_NODELAY;
   4578 		break;
   4579 	case SCTP_AUTOCLOSE:
   4580 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   4581 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
   4582 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   4583 			return (EINVAL);
   4584 		}
   4585 		set_opt = SCTP_PCB_FLAGS_AUTOCLOSE;
   4586 		/*
   4587 		 * The value is in ticks. Note this does not effect
   4588 		 * old associations, only new ones.
   4589 		 */
   4590 		inp->sctp_ep.auto_close_time = sctp_secs_to_ticks(*mopt);
   4591 		break;
   4592 	}
   4593 	SCTP_INP_WLOCK(inp);
   4594 	if (*mopt != 0) {
   4595 		sctp_feature_on(inp, set_opt);
   4596 	} else {
   4597 		sctp_feature_off(inp, set_opt);
   4598 	}
   4599 	SCTP_INP_WUNLOCK(inp);
   4600 	break;
   4601 case SCTP_REUSE_PORT:
   4602 {
   4603 	SCTP_CHECK_AND_CAST(mopt, optval, uint32_t, optsize);
   4604 	if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == 0) {
   4605 		/* Can't set it after we are bound */
   4606 		error = EINVAL;
   4607 		break;
   4608 	}
   4609 	if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE)) {
   4610 		/* Can't do this for a 1-m socket */
   4611 		error = EINVAL;
   4612 		break;
   4613 	}
   4614 	if (optval)
   4615 		sctp_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE);
   4616 	else
   4617 		sctp_feature_off(inp, SCTP_PCB_FLAGS_PORTREUSE);
   4618 	break;
   4619 }
   4620 case SCTP_PARTIAL_DELIVERY_POINT:
   4621 {
   4622 	uint32_t *value;
   4623 
   4624 	SCTP_CHECK_AND_CAST(value, optval, uint32_t, optsize);
   4625 	if (*value > SCTP_SB_LIMIT_RCV(so)) {
   4626 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   4627 		error = EINVAL;
   4628 		break;
   4629 	}
   4630 	inp->partial_delivery_point = *value;
   4631 	break;
   4632 }
   4633 case SCTP_FRAGMENT_INTERLEAVE:
   4634 	/* not yet until we re-write sctp_recvmsg() */
   4635 {
   4636 	uint32_t *level;
   4637 
   4638 	SCTP_CHECK_AND_CAST(level, optval, uint32_t, optsize);
   4639 	if (*level == SCTP_FRAG_LEVEL_2) {
   4640 		sctp_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE);
   4641 		sctp_feature_on(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS);
   4642 	} else if (*level == SCTP_FRAG_LEVEL_1) {
   4643 		sctp_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE);
   4644 		sctp_feature_off(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS);
   4645 	} else if (*level == SCTP_FRAG_LEVEL_0) {
   4646 		sctp_feature_off(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE);
   4647 		sctp_feature_off(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS);
   4648 
   4649 	} else {
   4650 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   4651 		error = EINVAL;
   4652 	}
   4653 	break;
   4654 }
   4655 case SCTP_INTERLEAVING_SUPPORTED:
   4656 {
   4657 	struct sctp_assoc_value *av;
   4658 
   4659 	SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
   4660 	SCTP_FIND_STCB(inp, stcb, av->assoc_id);
   4661 
   4662 	if (stcb) {
   4663 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   4664 		error = EINVAL;
   4665 		SCTP_TCB_UNLOCK(stcb);
   4666 	} else {
   4667 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   4668 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   4669 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   4670 		     (av->assoc_id == SCTP_FUTURE_ASSOC))) {
   4671 			SCTP_INP_WLOCK(inp);
   4672 			if (av->assoc_value == 0) {
   4673 				inp->idata_supported = 0;
   4674 			} else {
   4675 				if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE)) &&
   4676 				    (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS))) {
   4677 					inp->idata_supported = 1;
   4678 				} else {
   4679 					/* Must have Frag interleave and stream interleave on */
   4680 					SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   4681 					error = EINVAL;
   4682 				}
   4683 			}
   4684 			SCTP_INP_WUNLOCK(inp);
   4685 		} else {
   4686 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   4687 			error = EINVAL;
   4688 		}
   4689 	}
   4690 	break;
   4691 }
   4692 case SCTP_CMT_ON_OFF:
   4693 	if (SCTP_BASE_SYSCTL(sctp_cmt_on_off)) {
   4694 		struct sctp_assoc_value *av;
   4695 
   4696 		SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
   4697 		if (av->assoc_value > SCTP_CMT_MAX) {
   4698 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   4699 			error = EINVAL;
   4700 			break;
   4701 		}
   4702 		SCTP_FIND_STCB(inp, stcb, av->assoc_id);
   4703 		if (stcb) {
   4704 			stcb->asoc.sctp_cmt_on_off = av->assoc_value;
   4705 			SCTP_TCB_UNLOCK(stcb);
   4706 		} else {
   4707 			if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   4708 			    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   4709 			    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   4710 			     ((av->assoc_id == SCTP_FUTURE_ASSOC) ||
   4711 			      (av->assoc_id == SCTP_ALL_ASSOC)))) {
   4712 				SCTP_INP_WLOCK(inp);
   4713 				inp->sctp_cmt_on_off = av->assoc_value;
   4714 				SCTP_INP_WUNLOCK(inp);
   4715 			}
   4716 			if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   4717 			    ((av->assoc_id == SCTP_CURRENT_ASSOC) ||
   4718 			     (av->assoc_id == SCTP_ALL_ASSOC))) {
   4719 				SCTP_INP_RLOCK(inp);
   4720 				LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
   4721 					SCTP_TCB_LOCK(stcb);
   4722 					stcb->asoc.sctp_cmt_on_off = av->assoc_value;
   4723 					SCTP_TCB_UNLOCK(stcb);
   4724 				}
   4725 				SCTP_INP_RUNLOCK(inp);
   4726 			}
   4727 		}
   4728 	} else {
   4729 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT);
   4730 		error = ENOPROTOOPT;
   4731 	}
   4732 	break;
   4733 case SCTP_PLUGGABLE_CC:
   4734 {
   4735 	struct sctp_assoc_value *av;
   4736 	struct sctp_nets *net;
   4737 
   4738 	SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
   4739 	if ((av->assoc_value != SCTP_CC_RFC2581) &&
   4740 	    (av->assoc_value != SCTP_CC_HSTCP) &&
   4741 	    (av->assoc_value != SCTP_CC_HTCP) &&
   4742 	    (av->assoc_value != SCTP_CC_RTCC)) {
   4743 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   4744 		error = EINVAL;
   4745 		break;
   4746 	}
   4747 	SCTP_FIND_STCB(inp, stcb, av->assoc_id);
   4748 	if (stcb) {
   4749 		stcb->asoc.cc_functions = sctp_cc_functions[av->assoc_value];
   4750 		stcb->asoc.congestion_control_module = av->assoc_value;
   4751 		if (stcb->asoc.cc_functions.sctp_set_initial_cc_param != NULL) {
   4752 			TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
   4753 				stcb->asoc.cc_functions.sctp_set_initial_cc_param(stcb, net);
   4754 			}
   4755 		}
   4756 		SCTP_TCB_UNLOCK(stcb);
   4757 	} else {
   4758 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   4759 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   4760 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   4761 		     ((av->assoc_id == SCTP_FUTURE_ASSOC) ||
   4762 		      (av->assoc_id == SCTP_ALL_ASSOC)))) {
   4763 			SCTP_INP_WLOCK(inp);
   4764 			inp->sctp_ep.sctp_default_cc_module = av->assoc_value;
   4765 			SCTP_INP_WUNLOCK(inp);
   4766 		}
   4767 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   4768 		    ((av->assoc_id == SCTP_CURRENT_ASSOC) ||
   4769 		     (av->assoc_id == SCTP_ALL_ASSOC))) {
   4770 			SCTP_INP_RLOCK(inp);
   4771 			LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
   4772 				SCTP_TCB_LOCK(stcb);
   4773 				stcb->asoc.cc_functions = sctp_cc_functions[av->assoc_value];
   4774 				stcb->asoc.congestion_control_module = av->assoc_value;
   4775 				if (stcb->asoc.cc_functions.sctp_set_initial_cc_param != NULL) {
   4776 					TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
   4777 						stcb->asoc.cc_functions.sctp_set_initial_cc_param(stcb, net);
   4778 					}
   4779 				}
   4780 				SCTP_TCB_UNLOCK(stcb);
   4781 			}
   4782 			SCTP_INP_RUNLOCK(inp);
   4783 		}
   4784 	}
   4785 	break;
   4786 }
   4787 case SCTP_CC_OPTION:
   4788 {
   4789 	struct sctp_cc_option *cc_opt;
   4790 
   4791 	SCTP_CHECK_AND_CAST(cc_opt, optval, struct sctp_cc_option, optsize);
   4792 	SCTP_FIND_STCB(inp, stcb, cc_opt->aid_value.assoc_id);
   4793 	if (stcb == NULL) {
   4794 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   4795 		    (cc_opt->aid_value.assoc_id == SCTP_CURRENT_ASSOC)) {
   4796 			SCTP_INP_RLOCK(inp);
   4797 			LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
   4798 				SCTP_TCB_LOCK(stcb);
   4799 				if (stcb->asoc.cc_functions.sctp_cwnd_socket_option) {
   4800 					(*stcb->asoc.cc_functions.sctp_cwnd_socket_option)(stcb, 1, cc_opt);
   4801 				}
   4802 				SCTP_TCB_UNLOCK(stcb);
   4803 			}
   4804 			SCTP_INP_RUNLOCK(inp);
   4805 		} else {
   4806 			error = EINVAL;
   4807 		}
   4808 	} else {
   4809 		if (stcb->asoc.cc_functions.sctp_cwnd_socket_option == NULL) {
   4810 			error = ENOTSUP;
   4811 		} else {
   4812 			error = (*stcb->asoc.cc_functions.sctp_cwnd_socket_option)(stcb, 1,
   4813 										   cc_opt);
   4814 		}
   4815 		SCTP_TCB_UNLOCK(stcb);
   4816 	}
   4817 	break;
   4818 }
   4819 case SCTP_STREAM_SCHEDULER:
   4820 {
   4821 	struct sctp_assoc_value *av;
   4822 
   4823 	SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
   4824 	if ((av->assoc_value != SCTP_SS_DEFAULT) &&
   4825 	    (av->assoc_value != SCTP_SS_RR) &&
   4826 	    (av->assoc_value != SCTP_SS_RR_PKT) &&
   4827 	    (av->assoc_value != SCTP_SS_PRIO) &&
   4828 	    (av->assoc_value != SCTP_SS_FB) &&
   4829 	    (av->assoc_value != SCTP_SS_FCFS)) {
   4830 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   4831 		error = EINVAL;
   4832 		break;
   4833 	}
   4834 	SCTP_FIND_STCB(inp, stcb, av->assoc_id);
   4835 	if (stcb) {
   4836 		stcb->asoc.ss_functions.sctp_ss_clear(stcb, &stcb->asoc, true);
   4837 		stcb->asoc.ss_functions = sctp_ss_functions[av->assoc_value];
   4838 		stcb->asoc.stream_scheduling_module = av->assoc_value;
   4839 		stcb->asoc.ss_functions.sctp_ss_init(stcb, &stcb->asoc);
   4840 		SCTP_TCB_UNLOCK(stcb);
   4841 	} else {
   4842 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   4843 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   4844 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   4845 		     ((av->assoc_id == SCTP_FUTURE_ASSOC) ||
   4846 		      (av->assoc_id == SCTP_ALL_ASSOC)))) {
   4847 			SCTP_INP_WLOCK(inp);
   4848 			inp->sctp_ep.sctp_default_ss_module = av->assoc_value;
   4849 			SCTP_INP_WUNLOCK(inp);
   4850 		}
   4851 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   4852 		    ((av->assoc_id == SCTP_CURRENT_ASSOC) ||
   4853 		     (av->assoc_id == SCTP_ALL_ASSOC))) {
   4854 			SCTP_INP_RLOCK(inp);
   4855 			LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
   4856 				SCTP_TCB_LOCK(stcb);
   4857 				stcb->asoc.ss_functions.sctp_ss_clear(stcb, &stcb->asoc, true);
   4858 				stcb->asoc.ss_functions = sctp_ss_functions[av->assoc_value];
   4859 				stcb->asoc.stream_scheduling_module = av->assoc_value;
   4860 				stcb->asoc.ss_functions.sctp_ss_init(stcb, &stcb->asoc);
   4861 				SCTP_TCB_UNLOCK(stcb);
   4862 			}
   4863 			SCTP_INP_RUNLOCK(inp);
   4864 		}
   4865 	}
   4866 	break;
   4867 }
   4868 case SCTP_STREAM_SCHEDULER_VALUE:
   4869 {
   4870 	struct sctp_stream_value *av;
   4871 
   4872 	SCTP_CHECK_AND_CAST(av, optval, struct sctp_stream_value, optsize);
   4873 	SCTP_FIND_STCB(inp, stcb, av->assoc_id);
   4874 	if (stcb) {
   4875 		if ((av->stream_id >= stcb->asoc.streamoutcnt) ||
   4876 		    (stcb->asoc.ss_functions.sctp_ss_set_value(stcb, &stcb->asoc, &stcb->asoc.strmout[av->stream_id],
   4877 		                                               av->stream_value) < 0)) {
   4878 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   4879 			error = EINVAL;
   4880 		}
   4881 		SCTP_TCB_UNLOCK(stcb);
   4882 	} else {
   4883 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   4884 		    (av->assoc_id == SCTP_CURRENT_ASSOC)) {
   4885 			SCTP_INP_RLOCK(inp);
   4886 			LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
   4887 				SCTP_TCB_LOCK(stcb);
   4888 				if (av->stream_id < stcb->asoc.streamoutcnt) {
   4889 					stcb->asoc.ss_functions.sctp_ss_set_value(stcb,
   4890 					                                          &stcb->asoc,
   4891 					                                          &stcb->asoc.strmout[av->stream_id],
   4892 					                                          av->stream_value);
   4893 				}
   4894 				SCTP_TCB_UNLOCK(stcb);
   4895 			}
   4896 			SCTP_INP_RUNLOCK(inp);
   4897 		} else {
   4898 			/* Can't set stream value without association */
   4899 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   4900 			error = EINVAL;
   4901 		}
   4902 	}
   4903 	break;
   4904 }
   4905 case SCTP_CLR_STAT_LOG:
   4906 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP);
   4907 	error = EOPNOTSUPP;
   4908 	break;
   4909 case SCTP_CONTEXT:
   4910 {
   4911 	struct sctp_assoc_value *av;
   4912 
   4913 	SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
   4914 	SCTP_FIND_STCB(inp, stcb, av->assoc_id);
   4915 
   4916 	if (stcb) {
   4917 		stcb->asoc.context = av->assoc_value;
   4918 		SCTP_TCB_UNLOCK(stcb);
   4919 	} else {
   4920 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   4921 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   4922 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   4923 		     ((av->assoc_id == SCTP_FUTURE_ASSOC) ||
   4924 		      (av->assoc_id == SCTP_ALL_ASSOC)))) {
   4925 			SCTP_INP_WLOCK(inp);
   4926 			inp->sctp_context = av->assoc_value;
   4927 			SCTP_INP_WUNLOCK(inp);
   4928 		}
   4929 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   4930 		    ((av->assoc_id == SCTP_CURRENT_ASSOC) ||
   4931 		     (av->assoc_id == SCTP_ALL_ASSOC))) {
   4932 			SCTP_INP_RLOCK(inp);
   4933 			LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
   4934 				SCTP_TCB_LOCK(stcb);
   4935 				stcb->asoc.context = av->assoc_value;
   4936 				SCTP_TCB_UNLOCK(stcb);
   4937 			}
   4938 			SCTP_INP_RUNLOCK(inp);
   4939 		}
   4940 	}
   4941 	break;
   4942 }
   4943 case SCTP_VRF_ID:
   4944 {
   4945 	uint32_t *default_vrfid;
   4946 #ifdef SCTP_MVRF
   4947 	int i;
   4948 #endif
   4949 	SCTP_CHECK_AND_CAST(default_vrfid, optval, uint32_t, optsize);
   4950 	if (*default_vrfid > SCTP_MAX_VRF_ID) {
   4951 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   4952 		error = EINVAL;
   4953 		break;
   4954 	}
   4955 #ifdef SCTP_MVRF
   4956 	for (i = 0; i < inp->num_vrfs; i++) {
   4957 		/* The VRF must be in the VRF list */
   4958 		if (*default_vrfid == inp->m_vrf_ids[i]) {
   4959 			SCTP_INP_WLOCK(inp);
   4960 			inp->def_vrf_id = *default_vrfid;
   4961 			SCTP_INP_WUNLOCK(inp);
   4962 			goto sctp_done;
   4963 		}
   4964 	}
   4965 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   4966 	error = EINVAL;
   4967 #else
   4968 	inp->def_vrf_id = *default_vrfid;
   4969 #endif
   4970 #ifdef SCTP_MVRF
   4971 sctp_done:
   4972 #endif
   4973 	break;
   4974 }
   4975 case SCTP_DEL_VRF_ID:
   4976 {
   4977 #ifdef SCTP_MVRF
   4978 	uint32_t *del_vrfid;
   4979 	int i, fnd = 0;
   4980 
   4981 	SCTP_CHECK_AND_CAST(del_vrfid, optval, uint32_t, optsize);
   4982 	if (*del_vrfid > SCTP_MAX_VRF_ID) {
   4983 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   4984 		error = EINVAL;
   4985 		break;
   4986 	}
   4987 	if (inp->num_vrfs == 1) {
   4988 		/* Can't delete last one */
   4989 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   4990 		error = EINVAL;
   4991 		break;
   4992 	}
   4993 	if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == 0) {
   4994 		/* Can't add more once you are bound */
   4995 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   4996 		error = EINVAL;
   4997 		break;
   4998 	}
   4999 	SCTP_INP_WLOCK(inp);
   5000 	for (i = 0; i < inp->num_vrfs; i++) {
   5001 		if (*del_vrfid == inp->m_vrf_ids[i]) {
   5002 			fnd = 1;
   5003 			break;
   5004 		}
   5005 	}
   5006 	if (!fnd) {
   5007 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   5008 		error = EINVAL;
   5009 		break;
   5010 	}
   5011 	if (i != (inp->num_vrfs - 1)) {
   5012 		/* Take bottom one and move to this slot */
   5013 		inp->m_vrf_ids[i] = inp->m_vrf_ids[(inp->num_vrfs-1)];
   5014 	}
   5015 	if (*del_vrfid == inp->def_vrf_id) {
   5016 		/* Take the first one as the new default */
   5017 		inp->def_vrf_id = inp->m_vrf_ids[0];
   5018 	}
   5019 	/* Drop the number by one killing last one */
   5020 	inp->num_vrfs--;
   5021 #else
   5022 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP);
   5023 	error = EOPNOTSUPP;
   5024 #endif
   5025 	break;
   5026 }
   5027 case SCTP_ADD_VRF_ID:
   5028 {
   5029 #ifdef SCTP_MVRF
   5030 	uint32_t *add_vrfid;
   5031 	int i;
   5032 
   5033 	SCTP_CHECK_AND_CAST(add_vrfid, optval, uint32_t, optsize);
   5034 	if (*add_vrfid > SCTP_MAX_VRF_ID) {
   5035 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   5036 		error = EINVAL;
   5037 		break;
   5038 	}
   5039 	if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == 0) {
   5040 		/* Can't add more once you are bound */
   5041 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   5042 		error = EINVAL;
   5043 		break;
   5044 	}
   5045 	SCTP_INP_WLOCK(inp);
   5046 	/* Verify its not already here */
   5047 	for (i = 0; i < inp->num_vrfs; i++) {
   5048 		if (*add_vrfid == inp->m_vrf_ids[i]) {
   5049 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY);
   5050 			error = EALREADY;
   5051 			SCTP_INP_WUNLOCK(inp);
   5052 			break;
   5053 		}
   5054 	}
   5055 	if ((inp->num_vrfs + 1) > inp->vrf_size) {
   5056 		/* need to grow array */
   5057 		uint32_t *tarray;
   5058 		SCTP_MALLOC(tarray, uint32_t *,
   5059 			    (sizeof(uint32_t) * (inp->vrf_size + SCTP_DEFAULT_VRF_SIZE)),
   5060 			    SCTP_M_MVRF);
   5061 		if (tarray == NULL) {
   5062 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOMEM);
   5063 			error = ENOMEM;
   5064 			SCTP_INP_WUNLOCK(inp);
   5065 			break;
   5066 		}
   5067 		memcpy(tarray, inp->m_vrf_ids, (sizeof(uint32_t) * inp->vrf_size));
   5068 		SCTP_FREE(inp->m_vrf_ids, SCTP_M_MVRF);
   5069 		inp->m_vrf_ids = tarray;
   5070 		inp->vrf_size += SCTP_DEFAULT_VRF_SIZE;
   5071 	}
   5072 	inp->m_vrf_ids[inp->num_vrfs] = *add_vrfid;
   5073 	inp->num_vrfs++;
   5074 	SCTP_INP_WUNLOCK(inp);
   5075 #else
   5076 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP);
   5077 	error = EOPNOTSUPP;
   5078 #endif
   5079 	break;
   5080 }
   5081 case SCTP_DELAYED_SACK:
   5082 {
   5083 	struct sctp_sack_info *sack;
   5084 
   5085 	SCTP_CHECK_AND_CAST(sack, optval, struct sctp_sack_info, optsize);
   5086 	SCTP_FIND_STCB(inp, stcb, sack->sack_assoc_id);
   5087 	if (sack->sack_delay) {
   5088 		if (sack->sack_delay > SCTP_MAX_SACK_DELAY) {
   5089 			error = EINVAL;
   5090 			if (stcb != NULL) {
   5091 				SCTP_TCB_UNLOCK(stcb);
   5092 			}
   5093 			break;
   5094 		}
   5095 	}
   5096 	if (stcb) {
   5097 		if (sack->sack_delay) {
   5098 			stcb->asoc.delayed_ack = sack->sack_delay;
   5099 		}
   5100 		if (sack->sack_freq) {
   5101 			stcb->asoc.sack_freq = sack->sack_freq;
   5102 		}
   5103 		SCTP_TCB_UNLOCK(stcb);
   5104 	} else {
   5105 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   5106 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   5107 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   5108 		     ((sack->sack_assoc_id == SCTP_FUTURE_ASSOC) ||
   5109 		      (sack->sack_assoc_id == SCTP_ALL_ASSOC)))) {
   5110 			SCTP_INP_WLOCK(inp);
   5111 			if (sack->sack_delay) {
   5112 				inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV] = sctp_msecs_to_ticks(sack->sack_delay);
   5113 			}
   5114 			if (sack->sack_freq) {
   5115 				inp->sctp_ep.sctp_sack_freq = sack->sack_freq;
   5116 			}
   5117 			SCTP_INP_WUNLOCK(inp);
   5118 		}
   5119 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   5120 		    ((sack->sack_assoc_id == SCTP_CURRENT_ASSOC) ||
   5121 		     (sack->sack_assoc_id == SCTP_ALL_ASSOC))) {
   5122 			SCTP_INP_RLOCK(inp);
   5123 			LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
   5124 				SCTP_TCB_LOCK(stcb);
   5125 				if (sack->sack_delay) {
   5126 					stcb->asoc.delayed_ack = sack->sack_delay;
   5127 				}
   5128 				if (sack->sack_freq) {
   5129 					stcb->asoc.sack_freq = sack->sack_freq;
   5130 				}
   5131 				SCTP_TCB_UNLOCK(stcb);
   5132 			}
   5133 			SCTP_INP_RUNLOCK(inp);
   5134 		}
   5135 	}
   5136 	break;
   5137 }
   5138 case SCTP_AUTH_CHUNK:
   5139 {
   5140 	struct sctp_authchunk *sauth;
   5141 
   5142 	SCTP_CHECK_AND_CAST(sauth, optval, struct sctp_authchunk, optsize);
   5143 
   5144 	SCTP_INP_WLOCK(inp);
   5145 	if (sctp_auth_add_chunk(sauth->sauth_chunk, inp->sctp_ep.local_auth_chunks)) {
   5146 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   5147 		error = EINVAL;
   5148 	} else {
   5149 		inp->auth_supported = 1;
   5150 	}
   5151 	SCTP_INP_WUNLOCK(inp);
   5152 	break;
   5153 }
   5154 case SCTP_AUTH_KEY:
   5155 {
   5156 	struct sctp_authkey *sca;
   5157 	struct sctp_keyhead *shared_keys;
   5158 	sctp_sharedkey_t *shared_key;
   5159 	sctp_key_t *key = NULL;
   5160 	size_t size;
   5161 
   5162 	SCTP_CHECK_AND_CAST(sca, optval, struct sctp_authkey, optsize);
   5163 	if (sca->sca_keylength == 0) {
   5164 		size = optsize - sizeof(struct sctp_authkey);
   5165 	} else {
   5166 		if (sca->sca_keylength + sizeof(struct sctp_authkey) <= optsize) {
   5167 			size = sca->sca_keylength;
   5168 		} else {
   5169 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   5170 			error = EINVAL;
   5171 			break;
   5172 		}
   5173 	}
   5174 	SCTP_FIND_STCB(inp, stcb, sca->sca_assoc_id);
   5175 
   5176 	if (stcb) {
   5177 		shared_keys = &stcb->asoc.shared_keys;
   5178 		/* clear the cached keys for this key id */
   5179 		sctp_clear_cachedkeys(stcb, sca->sca_keynumber);
   5180 		/*
   5181 		 * create the new shared key and
   5182 		 * insert/replace it
   5183 		 */
   5184 		if (size > 0) {
   5185 			key = sctp_set_key(sca->sca_key, (uint32_t) size);
   5186 			if (key == NULL) {
   5187 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOMEM);
   5188 				error = ENOMEM;
   5189 				SCTP_TCB_UNLOCK(stcb);
   5190 				break;
   5191 			}
   5192 		}
   5193 		shared_key = sctp_alloc_sharedkey();
   5194 		if (shared_key == NULL) {
   5195 			sctp_free_key(key);
   5196 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOMEM);
   5197 			error = ENOMEM;
   5198 			SCTP_TCB_UNLOCK(stcb);
   5199 			break;
   5200 		}
   5201 		shared_key->key = key;
   5202 		shared_key->keyid = sca->sca_keynumber;
   5203 		error = sctp_insert_sharedkey(shared_keys, shared_key);
   5204 		SCTP_TCB_UNLOCK(stcb);
   5205 	} else {
   5206 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   5207 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   5208 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   5209 		     ((sca->sca_assoc_id == SCTP_FUTURE_ASSOC) ||
   5210 		      (sca->sca_assoc_id == SCTP_ALL_ASSOC)))) {
   5211 			SCTP_INP_WLOCK(inp);
   5212 			shared_keys = &inp->sctp_ep.shared_keys;
   5213 			/*
   5214 			 * clear the cached keys on all assocs for
   5215 			 * this key id
   5216 			 */
   5217 			sctp_clear_cachedkeys_ep(inp, sca->sca_keynumber);
   5218 			/*
   5219 			 * create the new shared key and
   5220 			 * insert/replace it
   5221 			 */
   5222 			if (size > 0) {
   5223 				key = sctp_set_key(sca->sca_key, (uint32_t) size);
   5224 				if (key == NULL) {
   5225 					SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOMEM);
   5226 					error = ENOMEM;
   5227 					SCTP_INP_WUNLOCK(inp);
   5228 					break;
   5229 				}
   5230 			}
   5231 			shared_key = sctp_alloc_sharedkey();
   5232 			if (shared_key == NULL) {
   5233 				sctp_free_key(key);
   5234 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOMEM);
   5235 				error = ENOMEM;
   5236 				SCTP_INP_WUNLOCK(inp);
   5237 				break;
   5238 			}
   5239 			shared_key->key = key;
   5240 			shared_key->keyid = sca->sca_keynumber;
   5241 			error = sctp_insert_sharedkey(shared_keys, shared_key);
   5242 			SCTP_INP_WUNLOCK(inp);
   5243 		}
   5244 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   5245 		    ((sca->sca_assoc_id == SCTP_CURRENT_ASSOC) ||
   5246 		     (sca->sca_assoc_id == SCTP_ALL_ASSOC))) {
   5247 			SCTP_INP_RLOCK(inp);
   5248 			LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
   5249 				SCTP_TCB_LOCK(stcb);
   5250 				shared_keys = &stcb->asoc.shared_keys;
   5251 				/* clear the cached keys for this key id */
   5252 				sctp_clear_cachedkeys(stcb, sca->sca_keynumber);
   5253 				/*
   5254 				 * create the new shared key and
   5255 				 * insert/replace it
   5256 				 */
   5257 				if (size > 0) {
   5258 					key = sctp_set_key(sca->sca_key, (uint32_t) size);
   5259 					if (key == NULL) {
   5260 						SCTP_TCB_UNLOCK(stcb);
   5261 						continue;
   5262 					}
   5263 				}
   5264 				shared_key = sctp_alloc_sharedkey();
   5265 				if (shared_key == NULL) {
   5266 					sctp_free_key(key);
   5267 					SCTP_TCB_UNLOCK(stcb);
   5268 					continue;
   5269 				}
   5270 				shared_key->key = key;
   5271 				shared_key->keyid = sca->sca_keynumber;
   5272 				error = sctp_insert_sharedkey(shared_keys, shared_key);
   5273 				SCTP_TCB_UNLOCK(stcb);
   5274 			}
   5275 			SCTP_INP_RUNLOCK(inp);
   5276 		}
   5277 	}
   5278 	break;
   5279 }
   5280 case SCTP_HMAC_IDENT:
   5281 {
   5282 	struct sctp_hmacalgo *shmac;
   5283 	sctp_hmaclist_t *hmaclist;
   5284 	uint16_t hmacid;
   5285 	uint32_t i;
   5286 
   5287 	SCTP_CHECK_AND_CAST(shmac, optval, struct sctp_hmacalgo, optsize);
   5288 	if ((optsize < sizeof(struct sctp_hmacalgo) + shmac->shmac_number_of_idents * sizeof(uint16_t)) ||
   5289 	    (shmac->shmac_number_of_idents > 0xffff)) {
   5290 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   5291 		error = EINVAL;
   5292 		break;
   5293 	}
   5294 
   5295 	hmaclist = sctp_alloc_hmaclist((uint16_t)shmac->shmac_number_of_idents);
   5296 	if (hmaclist == NULL) {
   5297 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOMEM);
   5298 		error = ENOMEM;
   5299 		break;
   5300 	}
   5301 	for (i = 0; i < shmac->shmac_number_of_idents; i++) {
   5302 		hmacid = shmac->shmac_idents[i];
   5303 		if (sctp_auth_add_hmacid(hmaclist, hmacid)) {
   5304 			/* invalid HMACs were found */;
   5305 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   5306 			error = EINVAL;
   5307 			sctp_free_hmaclist(hmaclist);
   5308 			goto sctp_set_hmac_done;
   5309 		}
   5310 	}
   5311 	for (i = 0; i < hmaclist->num_algo; i++) {
   5312 		if (hmaclist->hmac[i] == SCTP_AUTH_HMAC_ID_SHA1) {
   5313 			/* already in list */
   5314 			break;
   5315 		}
   5316 	}
   5317 	if (i == hmaclist->num_algo) {
   5318 		/* not found in list */
   5319 		sctp_free_hmaclist(hmaclist);
   5320 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   5321 		error = EINVAL;
   5322 		break;
   5323 	}
   5324 	/* set it on the endpoint */
   5325 	SCTP_INP_WLOCK(inp);
   5326 	if (inp->sctp_ep.local_hmacs)
   5327 		sctp_free_hmaclist(inp->sctp_ep.local_hmacs);
   5328 	inp->sctp_ep.local_hmacs = hmaclist;
   5329 	SCTP_INP_WUNLOCK(inp);
   5330 sctp_set_hmac_done:
   5331 	break;
   5332 }
   5333 case SCTP_AUTH_ACTIVE_KEY:
   5334 {
   5335 	struct sctp_authkeyid *scact;
   5336 
   5337 	SCTP_CHECK_AND_CAST(scact, optval, struct sctp_authkeyid, optsize);
   5338 	SCTP_FIND_STCB(inp, stcb, scact->scact_assoc_id);
   5339 
   5340 	/* set the active key on the right place */
   5341 	if (stcb) {
   5342 		/* set the active key on the assoc */
   5343 		if (sctp_auth_setactivekey(stcb,
   5344 					   scact->scact_keynumber)) {
   5345 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL,
   5346 					    SCTP_FROM_SCTP_USRREQ,
   5347 					    EINVAL);
   5348 			error = EINVAL;
   5349 		}
   5350 		SCTP_TCB_UNLOCK(stcb);
   5351 	} else {
   5352 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   5353 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   5354 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   5355 		     ((scact->scact_assoc_id == SCTP_FUTURE_ASSOC) ||
   5356 		      (scact->scact_assoc_id == SCTP_ALL_ASSOC)))) {
   5357 			SCTP_INP_WLOCK(inp);
   5358 			if (sctp_auth_setactivekey_ep(inp, scact->scact_keynumber)) {
   5359 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   5360 				error = EINVAL;
   5361 			}
   5362 			SCTP_INP_WUNLOCK(inp);
   5363 		}
   5364 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   5365 		    ((scact->scact_assoc_id == SCTP_CURRENT_ASSOC) ||
   5366 		     (scact->scact_assoc_id == SCTP_ALL_ASSOC))) {
   5367 			SCTP_INP_RLOCK(inp);
   5368 			LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
   5369 				SCTP_TCB_LOCK(stcb);
   5370 				sctp_auth_setactivekey(stcb, scact->scact_keynumber);
   5371 				SCTP_TCB_UNLOCK(stcb);
   5372 			}
   5373 			SCTP_INP_RUNLOCK(inp);
   5374 		}
   5375 	}
   5376 	break;
   5377 }
   5378 case SCTP_AUTH_DELETE_KEY:
   5379 {
   5380 	struct sctp_authkeyid *scdel;
   5381 
   5382 	SCTP_CHECK_AND_CAST(scdel, optval, struct sctp_authkeyid, optsize);
   5383 	SCTP_FIND_STCB(inp, stcb, scdel->scact_assoc_id);
   5384 
   5385 	/* delete the key from the right place */
   5386 	if (stcb) {
   5387 		if (sctp_delete_sharedkey(stcb, scdel->scact_keynumber)) {
   5388 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   5389 			error = EINVAL;
   5390 		}
   5391 		SCTP_TCB_UNLOCK(stcb);
   5392 	} else {
   5393 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   5394 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   5395 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   5396 		     ((scdel->scact_assoc_id == SCTP_FUTURE_ASSOC) ||
   5397 		      (scdel->scact_assoc_id == SCTP_ALL_ASSOC)))) {
   5398 			SCTP_INP_WLOCK(inp);
   5399 			if (sctp_delete_sharedkey_ep(inp, scdel->scact_keynumber)) {
   5400 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   5401 				error = EINVAL;
   5402 			}
   5403 			SCTP_INP_WUNLOCK(inp);
   5404 		}
   5405 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   5406 		    ((scdel->scact_assoc_id == SCTP_CURRENT_ASSOC) ||
   5407 		     (scdel->scact_assoc_id == SCTP_ALL_ASSOC))) {
   5408 			SCTP_INP_RLOCK(inp);
   5409 			LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
   5410 				SCTP_TCB_LOCK(stcb);
   5411 				sctp_delete_sharedkey(stcb, scdel->scact_keynumber);
   5412 				SCTP_TCB_UNLOCK(stcb);
   5413 			}
   5414 			SCTP_INP_RUNLOCK(inp);
   5415 		}
   5416 	}
   5417 	break;
   5418 }
   5419 case SCTP_AUTH_DEACTIVATE_KEY:
   5420 {
   5421 	struct sctp_authkeyid *keyid;
   5422 
   5423 	SCTP_CHECK_AND_CAST(keyid, optval, struct sctp_authkeyid, optsize);
   5424 	SCTP_FIND_STCB(inp, stcb, keyid->scact_assoc_id);
   5425 
   5426 	/* deactivate the key from the right place */
   5427 	if (stcb) {
   5428 		if (sctp_deact_sharedkey(stcb, keyid->scact_keynumber)) {
   5429 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   5430 			error = EINVAL;
   5431 		}
   5432 		SCTP_TCB_UNLOCK(stcb);
   5433 	} else {
   5434 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   5435 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   5436 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   5437 		     ((keyid->scact_assoc_id == SCTP_FUTURE_ASSOC) ||
   5438 		      (keyid->scact_assoc_id == SCTP_ALL_ASSOC)))) {
   5439 			SCTP_INP_WLOCK(inp);
   5440 			if (sctp_deact_sharedkey_ep(inp, keyid->scact_keynumber)) {
   5441 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   5442 				error = EINVAL;
   5443 			}
   5444 			SCTP_INP_WUNLOCK(inp);
   5445 		}
   5446 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   5447 		    ((keyid->scact_assoc_id == SCTP_CURRENT_ASSOC) ||
   5448 		     (keyid->scact_assoc_id == SCTP_ALL_ASSOC))) {
   5449 			SCTP_INP_RLOCK(inp);
   5450 			LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
   5451 				SCTP_TCB_LOCK(stcb);
   5452 				sctp_deact_sharedkey(stcb, keyid->scact_keynumber);
   5453 				SCTP_TCB_UNLOCK(stcb);
   5454 			}
   5455 			SCTP_INP_RUNLOCK(inp);
   5456 		}
   5457 	}
   5458 	break;
   5459 }
   5460 case SCTP_ENABLE_STREAM_RESET:
   5461 {
   5462 	struct sctp_assoc_value *av;
   5463 
   5464 	SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
   5465 	if (av->assoc_value & (~SCTP_ENABLE_VALUE_MASK)) {
   5466 	        SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   5467 		error = EINVAL;
   5468 		break;
   5469 	}
   5470 	SCTP_FIND_STCB(inp, stcb, av->assoc_id);
   5471 	if (stcb) {
   5472 		stcb->asoc.local_strreset_support = (uint8_t)av->assoc_value;
   5473 		SCTP_TCB_UNLOCK(stcb);
   5474 	} else {
   5475 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   5476 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   5477 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   5478 		     ((av->assoc_id == SCTP_FUTURE_ASSOC) ||
   5479 		      (av->assoc_id == SCTP_ALL_ASSOC)))) {
   5480 			SCTP_INP_WLOCK(inp);
   5481 			inp->local_strreset_support = (uint8_t)av->assoc_value;
   5482 			SCTP_INP_WUNLOCK(inp);
   5483 		}
   5484 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   5485 		    ((av->assoc_id == SCTP_CURRENT_ASSOC) ||
   5486 		     (av->assoc_id == SCTP_ALL_ASSOC))) {
   5487 			SCTP_INP_RLOCK(inp);
   5488 			LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
   5489 				SCTP_TCB_LOCK(stcb);
   5490 				stcb->asoc.local_strreset_support = (uint8_t)av->assoc_value;
   5491 				SCTP_TCB_UNLOCK(stcb);
   5492 			}
   5493 			SCTP_INP_RUNLOCK(inp);
   5494 		}
   5495 	}
   5496 	break;
   5497 }
   5498 case SCTP_RESET_STREAMS:
   5499 {
   5500 	struct sctp_reset_streams *strrst;
   5501 	int i, send_out = 0;
   5502 	int send_in = 0;
   5503 
   5504 	SCTP_CHECK_AND_CAST(strrst, optval, struct sctp_reset_streams, optsize);
   5505 	SCTP_FIND_STCB(inp, stcb, strrst->srs_assoc_id);
   5506 	if (stcb == NULL) {
   5507 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT);
   5508 		error = ENOENT;
   5509 		break;
   5510 	}
   5511 	if (stcb->asoc.reconfig_supported == 0) {
   5512 		/*
   5513 		 * Peer does not support the chunk type.
   5514 		 */
   5515 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP);
   5516 		error = EOPNOTSUPP;
   5517 		SCTP_TCB_UNLOCK(stcb);
   5518 		break;
   5519 	}
   5520 	if (SCTP_GET_STATE(stcb) != SCTP_STATE_OPEN) {
   5521 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   5522 		error = EINVAL;
   5523 		SCTP_TCB_UNLOCK(stcb);
   5524 		break;
   5525 	}
   5526 	if (sizeof(struct sctp_reset_streams) +
   5527 	    strrst->srs_number_streams * sizeof(uint16_t) > optsize) {
   5528 		error = EINVAL;
   5529 		SCTP_TCB_UNLOCK(stcb);
   5530 		break;
   5531 	}
   5532 	if (strrst->srs_flags & SCTP_STREAM_RESET_INCOMING) {
   5533 		send_in = 1;
   5534 		if (stcb->asoc.stream_reset_outstanding) {
   5535 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY);
   5536 			error = EALREADY;
   5537 			SCTP_TCB_UNLOCK(stcb);
   5538 			break;
   5539 		}
   5540 	}
   5541 	if (strrst->srs_flags & SCTP_STREAM_RESET_OUTGOING) {
   5542 		send_out = 1;
   5543 	}
   5544 	if ((strrst->srs_number_streams > SCTP_MAX_STREAMS_AT_ONCE_RESET) && send_in) {
   5545 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOMEM);
   5546 		error = ENOMEM;
   5547 		SCTP_TCB_UNLOCK(stcb);
   5548 		break;
   5549 	}
   5550 	if ((send_in == 0) && (send_out == 0)) {
   5551 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   5552 		error = EINVAL;
   5553 		SCTP_TCB_UNLOCK(stcb);
   5554 		break;
   5555 	}
   5556 	for (i = 0; i < strrst->srs_number_streams; i++) {
   5557 		if ((send_in) &&
   5558 		    (strrst->srs_stream_list[i] >= stcb->asoc.streamincnt)) {
   5559 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   5560 			error = EINVAL;
   5561 			break;
   5562 		}
   5563 		if ((send_out) &&
   5564 		    (strrst->srs_stream_list[i] >= stcb->asoc.streamoutcnt)) {
   5565 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   5566 			error = EINVAL;
   5567 			break;
   5568 		}
   5569 	}
   5570 	if (error) {
   5571 		SCTP_TCB_UNLOCK(stcb);
   5572 		break;
   5573 	}
   5574 	if (send_out) {
   5575 		int cnt;
   5576 		uint16_t strm;
   5577 		if (strrst->srs_number_streams) {
   5578 			for (i = 0, cnt = 0; i < strrst->srs_number_streams; i++) {
   5579 				strm = strrst->srs_stream_list[i];
   5580 				if (stcb->asoc.strmout[strm].state == SCTP_STREAM_OPEN) {
   5581 					stcb->asoc.strmout[strm].state = SCTP_STREAM_RESET_PENDING;
   5582 					cnt++;
   5583 				}
   5584 			}
   5585 		} else {
   5586 			/* Its all */
   5587 			for (i = 0, cnt = 0; i < stcb->asoc.streamoutcnt; i++) {
   5588 				if (stcb->asoc.strmout[i].state == SCTP_STREAM_OPEN) {
   5589 					stcb->asoc.strmout[i].state = SCTP_STREAM_RESET_PENDING;
   5590 					cnt++;
   5591 				}
   5592 			}
   5593 		}
   5594 	}
   5595 	if (send_in) {
   5596 		error = sctp_send_str_reset_req(stcb, strrst->srs_number_streams,
   5597 						strrst->srs_stream_list,
   5598 						send_in, 0, 0, 0, 0, 0);
   5599 	} else {
   5600 		error = sctp_send_stream_reset_out_if_possible(stcb, SCTP_SO_LOCKED);
   5601 	}
   5602 	if (error == 0) {
   5603 		sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_STRRST_REQ, SCTP_SO_LOCKED);
   5604 	} else {
   5605 		 /*
   5606 		  * For outgoing streams don't report any problems in
   5607 		  * sending the request to the application.
   5608 		  * XXX: Double check resetting incoming streams.
   5609 		  */
   5610 		error = 0;
   5611 	}
   5612 	SCTP_TCB_UNLOCK(stcb);
   5613 	break;
   5614 }
   5615 case SCTP_ADD_STREAMS:
   5616 {
   5617 	struct sctp_add_streams *stradd;
   5618 	uint8_t addstream = 0;
   5619 	uint16_t add_o_strmcnt = 0;
   5620 	uint16_t add_i_strmcnt = 0;
   5621 
   5622 	SCTP_CHECK_AND_CAST(stradd, optval, struct sctp_add_streams, optsize);
   5623 	SCTP_FIND_STCB(inp, stcb, stradd->sas_assoc_id);
   5624 	if (stcb == NULL) {
   5625 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT);
   5626 		error = ENOENT;
   5627 		break;
   5628 	}
   5629 	if (stcb->asoc.reconfig_supported == 0) {
   5630 		/*
   5631 		 * Peer does not support the chunk type.
   5632 		 */
   5633 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP);
   5634 		error = EOPNOTSUPP;
   5635 		SCTP_TCB_UNLOCK(stcb);
   5636 		break;
   5637 	}
   5638 	if (SCTP_GET_STATE(stcb) != SCTP_STATE_OPEN) {
   5639 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   5640 		error = EINVAL;
   5641 		SCTP_TCB_UNLOCK(stcb);
   5642 		break;
   5643 	}
   5644 	if (stcb->asoc.stream_reset_outstanding) {
   5645 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY);
   5646 		error = EALREADY;
   5647 		SCTP_TCB_UNLOCK(stcb);
   5648 		break;
   5649 	}
   5650 	if ((stradd->sas_outstrms == 0) &&
   5651 	    (stradd->sas_instrms == 0)) {
   5652 		error = EINVAL;
   5653 		goto skip_stuff;
   5654 	}
   5655 	if (stradd->sas_outstrms) {
   5656 		addstream = 1;
   5657 		/* We allocate here */
   5658 		add_o_strmcnt = stradd->sas_outstrms;
   5659 		if ((((int)add_o_strmcnt) + ((int)stcb->asoc.streamoutcnt)) > 0x0000ffff) {
   5660 			/* You can't have more than 64k */
   5661 			error = EINVAL;
   5662 			goto skip_stuff;
   5663 		}
   5664 	}
   5665 	if (stradd->sas_instrms) {
   5666 		int cnt;
   5667 
   5668 		addstream |= 2;
   5669 		/* We allocate inside sctp_send_str_reset_req() */
   5670 		add_i_strmcnt = stradd->sas_instrms;
   5671 		cnt = add_i_strmcnt;
   5672 		cnt += stcb->asoc.streamincnt;
   5673 		if (cnt > 0x0000ffff) {
   5674 			/* You can't have more than 64k */
   5675 			error = EINVAL;
   5676 			goto skip_stuff;
   5677 		}
   5678 		if (cnt > (int)stcb->asoc.max_inbound_streams) {
   5679 			/* More than you are allowed */
   5680 			error = EINVAL;
   5681 			goto skip_stuff;
   5682 		}
   5683 	}
   5684 	error = sctp_send_str_reset_req(stcb, 0, NULL, 0, 0, addstream, add_o_strmcnt, add_i_strmcnt, 0);
   5685 	sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_STRRST_REQ, SCTP_SO_LOCKED);
   5686 skip_stuff:
   5687 	SCTP_TCB_UNLOCK(stcb);
   5688 	break;
   5689 }
   5690 case SCTP_RESET_ASSOC:
   5691 {
   5692 	int i;
   5693 	uint32_t *value;
   5694 
   5695 	SCTP_CHECK_AND_CAST(value, optval, uint32_t, optsize);
   5696 	SCTP_FIND_STCB(inp, stcb, (sctp_assoc_t) *value);
   5697 	if (stcb == NULL) {
   5698 	        SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT);
   5699 		error = ENOENT;
   5700 		break;
   5701 	}
   5702 	if (stcb->asoc.reconfig_supported == 0) {
   5703 		/*
   5704 		 * Peer does not support the chunk type.
   5705 		 */
   5706 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP);
   5707 		error = EOPNOTSUPP;
   5708 		SCTP_TCB_UNLOCK(stcb);
   5709 		break;
   5710 	}
   5711 	if (SCTP_GET_STATE(stcb) != SCTP_STATE_OPEN) {
   5712 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   5713 		error = EINVAL;
   5714 		SCTP_TCB_UNLOCK(stcb);
   5715 		break;
   5716 	}
   5717 	if (stcb->asoc.stream_reset_outstanding) {
   5718 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY);
   5719 		error = EALREADY;
   5720 		SCTP_TCB_UNLOCK(stcb);
   5721 		break;
   5722 	}
   5723 	/* Is there any data pending in the send or sent queues? */
   5724 	if (!TAILQ_EMPTY(&stcb->asoc.send_queue) ||
   5725 	    !TAILQ_EMPTY(&stcb->asoc.sent_queue)) {
   5726 	busy_out:
   5727 		error = EBUSY;
   5728 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
   5729 		SCTP_TCB_UNLOCK(stcb);
   5730 		break;
   5731 	}
   5732 	/* Do any streams have data queued? */
   5733 	for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
   5734 		if (!TAILQ_EMPTY(&stcb->asoc.strmout[i].outqueue)) {
   5735 			goto busy_out;
   5736 		}
   5737 	}
   5738 	error = sctp_send_str_reset_req(stcb, 0, NULL, 0, 1, 0, 0, 0, 0);
   5739 	sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_STRRST_REQ, SCTP_SO_LOCKED);
   5740 	SCTP_TCB_UNLOCK(stcb);
   5741 	break;
   5742 }
   5743 case SCTP_CONNECT_X:
   5744 	if (optsize < (sizeof(int) + sizeof(struct sockaddr_in))) {
   5745 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   5746 		error = EINVAL;
   5747 		break;
   5748 	}
   5749 	error = sctp_do_connect_x(so, inp, optval, optsize, p, 0);
   5750 	break;
   5751 case SCTP_CONNECT_X_DELAYED:
   5752 	if (optsize < (sizeof(int) + sizeof(struct sockaddr_in))) {
   5753 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   5754 		error = EINVAL;
   5755 		break;
   5756 	}
   5757 	error = sctp_do_connect_x(so, inp, optval, optsize, p, 1);
   5758 	break;
   5759 case SCTP_CONNECT_X_COMPLETE:
   5760 {
   5761 	struct sockaddr *sa;
   5762 
   5763 	/* FIXME MT: check correct? */
   5764 	SCTP_CHECK_AND_CAST(sa, optval, struct sockaddr, optsize);
   5765 
   5766 	/* find tcb */
   5767 	if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
   5768 		SCTP_INP_RLOCK(inp);
   5769 		stcb = LIST_FIRST(&inp->sctp_asoc_list);
   5770 		if (stcb) {
   5771 			SCTP_TCB_LOCK(stcb);
   5772 		}
   5773 		SCTP_INP_RUNLOCK(inp);
   5774 	} else {
   5775 		/* We increment here since sctp_findassociation_ep_addr() wil
   5776 		 * do a decrement if it finds the stcb as long as the locked
   5777 		 * tcb (last argument) is NOT a TCB.. aka NULL.
   5778 		 */
   5779 		SCTP_INP_INCR_REF(inp);
   5780 		stcb = sctp_findassociation_ep_addr(&inp, sa, NULL, NULL, NULL);
   5781 		if (stcb == NULL) {
   5782 			SCTP_INP_DECR_REF(inp);
   5783 		}
   5784 	}
   5785 
   5786 	if (stcb == NULL) {
   5787 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT);
   5788 		error = ENOENT;
   5789 		break;
   5790 	}
   5791 	if (stcb->asoc.delayed_connection == 1) {
   5792 		stcb->asoc.delayed_connection = 0;
   5793 		(void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered);
   5794 		sctp_timer_stop(SCTP_TIMER_TYPE_INIT, inp, stcb,
   5795 				stcb->asoc.primary_destination,
   5796 				SCTP_FROM_SCTP_USRREQ + SCTP_LOC_8);
   5797 		sctp_send_initiate(inp, stcb, SCTP_SO_LOCKED);
   5798 	} else {
   5799 		/*
   5800 		 * already expired or did not use delayed
   5801 		 * connectx
   5802 		 */
   5803 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY);
   5804 		error = EALREADY;
   5805 	}
   5806 	SCTP_TCB_UNLOCK(stcb);
   5807 	break;
   5808 }
   5809 case SCTP_MAX_BURST:
   5810 {
   5811 	struct sctp_assoc_value *av;
   5812 
   5813 	SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
   5814 	SCTP_FIND_STCB(inp, stcb, av->assoc_id);
   5815 
   5816 	if (stcb) {
   5817 		stcb->asoc.max_burst = av->assoc_value;
   5818 		SCTP_TCB_UNLOCK(stcb);
   5819 	} else {
   5820 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   5821 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   5822 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   5823 		     ((av->assoc_id == SCTP_FUTURE_ASSOC) ||
   5824 		      (av->assoc_id == SCTP_ALL_ASSOC)))) {
   5825 			SCTP_INP_WLOCK(inp);
   5826 			inp->sctp_ep.max_burst = av->assoc_value;
   5827 			SCTP_INP_WUNLOCK(inp);
   5828 		}
   5829 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   5830 		    ((av->assoc_id == SCTP_CURRENT_ASSOC) ||
   5831 		     (av->assoc_id == SCTP_ALL_ASSOC))) {
   5832 			SCTP_INP_RLOCK(inp);
   5833 			LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
   5834 				SCTP_TCB_LOCK(stcb);
   5835 				stcb->asoc.max_burst = av->assoc_value;
   5836 				SCTP_TCB_UNLOCK(stcb);
   5837 			}
   5838 			SCTP_INP_RUNLOCK(inp);
   5839 		}
   5840 	}
   5841 	break;
   5842 }
   5843 case SCTP_MAXSEG:
   5844 {
   5845 	struct sctp_assoc_value *av;
   5846 
   5847 	SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
   5848 	SCTP_FIND_STCB(inp, stcb, av->assoc_id);
   5849 
   5850 	if (stcb) {
   5851 		stcb->asoc.sctp_frag_point = av->assoc_value;
   5852 		SCTP_TCB_UNLOCK(stcb);
   5853 	} else {
   5854 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   5855 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   5856 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   5857 		     (av->assoc_id == SCTP_FUTURE_ASSOC))) {
   5858 			SCTP_INP_WLOCK(inp);
   5859 			inp->sctp_frag_point = av->assoc_value;
   5860 			SCTP_INP_WUNLOCK(inp);
   5861 		} else {
   5862 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   5863 			error = EINVAL;
   5864 		}
   5865 	}
   5866 	break;
   5867 }
   5868 case SCTP_EVENTS:
   5869 {
   5870 	struct sctp_event_subscribe *events;
   5871 
   5872 	SCTP_CHECK_AND_CAST(events, optval, struct sctp_event_subscribe, optsize);
   5873 
   5874 	SCTP_INP_WLOCK(inp);
   5875 	if (events->sctp_data_io_event) {
   5876 		sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT);
   5877 	} else {
   5878 		sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT);
   5879 	}
   5880 
   5881 	if (events->sctp_association_event) {
   5882 		sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVASSOCEVNT);
   5883 	} else {
   5884 		sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVASSOCEVNT);
   5885 	}
   5886 
   5887 	if (events->sctp_address_event) {
   5888 		sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVPADDREVNT);
   5889 	} else {
   5890 		sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVPADDREVNT);
   5891 	}
   5892 
   5893 	if (events->sctp_send_failure_event) {
   5894 		sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVSENDFAILEVNT);
   5895 	} else {
   5896 		sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVSENDFAILEVNT);
   5897 	}
   5898 
   5899 	if (events->sctp_peer_error_event) {
   5900 		sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVPEERERR);
   5901 	} else {
   5902 		sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVPEERERR);
   5903 	}
   5904 
   5905 	if (events->sctp_shutdown_event) {
   5906 		sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT);
   5907 	} else {
   5908 		sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT);
   5909 	}
   5910 
   5911 	if (events->sctp_partial_delivery_event) {
   5912 		sctp_feature_on(inp, SCTP_PCB_FLAGS_PDAPIEVNT);
   5913 	} else {
   5914 		sctp_feature_off(inp, SCTP_PCB_FLAGS_PDAPIEVNT);
   5915 	}
   5916 
   5917 	if (events->sctp_adaptation_layer_event) {
   5918 		sctp_feature_on(inp, SCTP_PCB_FLAGS_ADAPTATIONEVNT);
   5919 	} else {
   5920 		sctp_feature_off(inp, SCTP_PCB_FLAGS_ADAPTATIONEVNT);
   5921 	}
   5922 
   5923 	if (events->sctp_authentication_event) {
   5924 		sctp_feature_on(inp, SCTP_PCB_FLAGS_AUTHEVNT);
   5925 	} else {
   5926 		sctp_feature_off(inp, SCTP_PCB_FLAGS_AUTHEVNT);
   5927 	}
   5928 
   5929 	if (events->sctp_sender_dry_event) {
   5930 		sctp_feature_on(inp, SCTP_PCB_FLAGS_DRYEVNT);
   5931 	} else {
   5932 		sctp_feature_off(inp, SCTP_PCB_FLAGS_DRYEVNT);
   5933 	}
   5934 
   5935 	if (events->sctp_stream_reset_event) {
   5936 		sctp_feature_on(inp, SCTP_PCB_FLAGS_STREAM_RESETEVNT);
   5937 	} else {
   5938 		sctp_feature_off(inp, SCTP_PCB_FLAGS_STREAM_RESETEVNT);
   5939 	}
   5940 
   5941 	LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
   5942 		SCTP_TCB_LOCK(stcb);
   5943 		if (events->sctp_association_event) {
   5944 			sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_RECVASSOCEVNT);
   5945 		} else {
   5946 			sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_RECVASSOCEVNT);
   5947 		}
   5948 		if (events->sctp_address_event) {
   5949 			sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_RECVPADDREVNT);
   5950 		} else {
   5951 			sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_RECVPADDREVNT);
   5952 		}
   5953 		if (events->sctp_send_failure_event) {
   5954 			sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_RECVSENDFAILEVNT);
   5955 		} else {
   5956 			sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_RECVSENDFAILEVNT);
   5957 		}
   5958 		if (events->sctp_peer_error_event) {
   5959 			sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_RECVPEERERR);
   5960 		} else {
   5961 			sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_RECVPEERERR);
   5962 		}
   5963 		if (events->sctp_shutdown_event) {
   5964 			sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT);
   5965 		} else {
   5966 			sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT);
   5967 		}
   5968 		if (events->sctp_partial_delivery_event) {
   5969 			sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_PDAPIEVNT);
   5970 		} else {
   5971 			sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_PDAPIEVNT);
   5972 		}
   5973 		if (events->sctp_adaptation_layer_event) {
   5974 			sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_ADAPTATIONEVNT);
   5975 		} else {
   5976 			sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_ADAPTATIONEVNT);
   5977 		}
   5978 		if (events->sctp_authentication_event) {
   5979 			sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_AUTHEVNT);
   5980 		} else {
   5981 			sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_AUTHEVNT);
   5982 		}
   5983 		if (events->sctp_sender_dry_event) {
   5984 			sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_DRYEVNT);
   5985 		} else {
   5986 			sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_DRYEVNT);
   5987 		}
   5988 		if (events->sctp_stream_reset_event) {
   5989 			sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_STREAM_RESETEVNT);
   5990 		} else {
   5991 			sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_STREAM_RESETEVNT);
   5992 		}
   5993 		SCTP_TCB_UNLOCK(stcb);
   5994 	}
   5995 	/* Send up the sender dry event only for 1-to-1 style sockets. */
   5996 	if (events->sctp_sender_dry_event) {
   5997 		if (((inp->sctp_flags & (SCTP_PCB_FLAGS_TCPTYPE | SCTP_PCB_FLAGS_IN_TCPPOOL)) != 0) &&
   5998 		    !SCTP_IS_LISTENING(inp)) {
   5999 			stcb = LIST_FIRST(&inp->sctp_asoc_list);
   6000 			if (stcb != NULL) {
   6001 				SCTP_TCB_LOCK(stcb);
   6002 				if (TAILQ_EMPTY(&stcb->asoc.send_queue) &&
   6003 				    TAILQ_EMPTY(&stcb->asoc.sent_queue) &&
   6004 				    (stcb->asoc.stream_queue_cnt == 0)) {
   6005 					sctp_ulp_notify(SCTP_NOTIFY_SENDER_DRY, stcb, 0, NULL, SCTP_SO_LOCKED);
   6006 				}
   6007 				SCTP_TCB_UNLOCK(stcb);
   6008 			}
   6009 		}
   6010 	}
   6011 	SCTP_INP_WUNLOCK(inp);
   6012 	break;
   6013 }
   6014 case SCTP_ADAPTATION_LAYER:
   6015 {
   6016 	struct sctp_setadaptation *adap_bits;
   6017 
   6018 	SCTP_CHECK_AND_CAST(adap_bits, optval, struct sctp_setadaptation, optsize);
   6019 	SCTP_INP_WLOCK(inp);
   6020 	inp->sctp_ep.adaptation_layer_indicator = adap_bits->ssb_adaptation_ind;
   6021 	inp->sctp_ep.adaptation_layer_indicator_provided = 1;
   6022 	SCTP_INP_WUNLOCK(inp);
   6023 	break;
   6024 }
   6025 #ifdef SCTP_DEBUG
   6026 case SCTP_SET_INITIAL_DBG_SEQ:
   6027 {
   6028 	uint32_t *vvv;
   6029 
   6030 	SCTP_CHECK_AND_CAST(vvv, optval, uint32_t, optsize);
   6031 	SCTP_INP_WLOCK(inp);
   6032 	inp->sctp_ep.initial_sequence_debug = *vvv;
   6033 	SCTP_INP_WUNLOCK(inp);
   6034 	break;
   6035 }
   6036 #endif
   6037 case SCTP_DEFAULT_SEND_PARAM:
   6038 {
   6039 	struct sctp_sndrcvinfo *s_info;
   6040 
   6041 	SCTP_CHECK_AND_CAST(s_info, optval, struct sctp_sndrcvinfo, optsize);
   6042 	SCTP_FIND_STCB(inp, stcb, s_info->sinfo_assoc_id);
   6043 
   6044 	if (stcb) {
   6045 		if (s_info->sinfo_stream < stcb->asoc.streamoutcnt) {
   6046 			memcpy(&stcb->asoc.def_send, s_info, min(optsize, sizeof(stcb->asoc.def_send)));
   6047 		} else {
   6048 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   6049 			error = EINVAL;
   6050 		}
   6051 		SCTP_TCB_UNLOCK(stcb);
   6052 	} else {
   6053 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   6054 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   6055 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   6056 		     ((s_info->sinfo_assoc_id == SCTP_FUTURE_ASSOC) ||
   6057 		      (s_info->sinfo_assoc_id == SCTP_ALL_ASSOC)))) {
   6058 			SCTP_INP_WLOCK(inp);
   6059 			memcpy(&inp->def_send, s_info, min(optsize, sizeof(inp->def_send)));
   6060 			SCTP_INP_WUNLOCK(inp);
   6061 		}
   6062 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   6063 		    ((s_info->sinfo_assoc_id == SCTP_CURRENT_ASSOC) ||
   6064 		     (s_info->sinfo_assoc_id == SCTP_ALL_ASSOC))) {
   6065 			SCTP_INP_RLOCK(inp);
   6066 			LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
   6067 				SCTP_TCB_LOCK(stcb);
   6068 				if (s_info->sinfo_stream < stcb->asoc.streamoutcnt) {
   6069 					memcpy(&stcb->asoc.def_send, s_info, min(optsize, sizeof(stcb->asoc.def_send)));
   6070 				}
   6071 				SCTP_TCB_UNLOCK(stcb);
   6072 			}
   6073 			SCTP_INP_RUNLOCK(inp);
   6074 		}
   6075 	}
   6076 	break;
   6077 }
   6078 case SCTP_PEER_ADDR_PARAMS:
   6079 {
   6080 	struct sctp_paddrparams *paddrp;
   6081 	struct sctp_nets *net;
   6082 	struct sockaddr *addr;
   6083 #if defined(INET) && defined(INET6)
   6084 	struct sockaddr_in sin_store;
   6085 #endif
   6086 
   6087 	SCTP_CHECK_AND_CAST(paddrp, optval, struct sctp_paddrparams, optsize);
   6088 	SCTP_FIND_STCB(inp, stcb, paddrp->spp_assoc_id);
   6089 
   6090 #if defined(INET) && defined(INET6)
   6091 	if (paddrp->spp_address.ss_family == AF_INET6) {
   6092 		struct sockaddr_in6 *sin6;
   6093 
   6094 		sin6 = (struct sockaddr_in6 *)&paddrp->spp_address;
   6095 		if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
   6096 			in6_sin6_2_sin(&sin_store, sin6);
   6097 			addr = (struct sockaddr *)&sin_store;
   6098 		} else {
   6099 			addr = (struct sockaddr *)&paddrp->spp_address;
   6100 		}
   6101 	} else {
   6102 		addr = (struct sockaddr *)&paddrp->spp_address;
   6103 	}
   6104 #else
   6105 	addr = (struct sockaddr *)&paddrp->spp_address;
   6106 #endif
   6107 	if (stcb != NULL) {
   6108 		net = sctp_findnet(stcb, addr);
   6109 	} else {
   6110 		/* We increment here since sctp_findassociation_ep_addr() wil
   6111 		 * do a decrement if it finds the stcb as long as the locked
   6112 		 * tcb (last argument) is NOT a TCB.. aka NULL.
   6113 		 */
   6114 		net = NULL;
   6115 		SCTP_INP_INCR_REF(inp);
   6116 		stcb = sctp_findassociation_ep_addr(&inp, addr,
   6117 		                                    &net, NULL, NULL);
   6118 		if (stcb == NULL) {
   6119 			SCTP_INP_DECR_REF(inp);
   6120 		}
   6121 	}
   6122 	if ((stcb != NULL) && (net == NULL)) {
   6123 #ifdef INET
   6124 		if (addr->sa_family == AF_INET) {
   6125 			struct sockaddr_in *sin;
   6126 
   6127 			sin = (struct sockaddr_in *)addr;
   6128 			if (sin->sin_addr.s_addr != INADDR_ANY) {
   6129 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   6130 				SCTP_TCB_UNLOCK(stcb);
   6131 				error = EINVAL;
   6132 				break;
   6133 			}
   6134 		} else
   6135 #endif
   6136 #ifdef INET6
   6137 		if (addr->sa_family == AF_INET6) {
   6138 			struct sockaddr_in6 *sin6;
   6139 
   6140 			sin6 = (struct sockaddr_in6 *)addr;
   6141 			if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
   6142 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   6143 				SCTP_TCB_UNLOCK(stcb);
   6144 				error = EINVAL;
   6145 				break;
   6146 			}
   6147 		} else
   6148 #endif
   6149 #if defined(__Userspace__)
   6150 		if (addr->sa_family == AF_CONN) {
   6151 			struct sockaddr_conn *sconn;
   6152 
   6153 			sconn = (struct sockaddr_conn *)addr;
   6154 			if (sconn->sconn_addr != NULL) {
   6155 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   6156 				SCTP_TCB_UNLOCK(stcb);
   6157 				error = EINVAL;
   6158 				break;
   6159 			}
   6160 		} else
   6161 #endif
   6162 		{
   6163 			error = EAFNOSUPPORT;
   6164 			SCTP_TCB_UNLOCK(stcb);
   6165 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
   6166 			break;
   6167 		}
   6168 	}
   6169 	/* sanity checks */
   6170 	if ((paddrp->spp_flags & SPP_HB_ENABLE) && (paddrp->spp_flags & SPP_HB_DISABLE)) {
   6171 		if (stcb)
   6172 			SCTP_TCB_UNLOCK(stcb);
   6173 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   6174 		return (EINVAL);
   6175 	}
   6176 
   6177 	if ((paddrp->spp_flags & SPP_PMTUD_ENABLE) && (paddrp->spp_flags & SPP_PMTUD_DISABLE)) {
   6178 		if (stcb)
   6179 			SCTP_TCB_UNLOCK(stcb);
   6180 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   6181 		return (EINVAL);
   6182 	}
   6183 	if ((paddrp->spp_flags & SPP_PMTUD_DISABLE) &&
   6184 	    (paddrp->spp_pathmtu > 0) &&
   6185 	    ((paddrp->spp_pathmtu < SCTP_SMALLEST_PMTU) ||
   6186 	     (paddrp->spp_pathmtu > SCTP_LARGEST_PMTU))) {
   6187 		if (stcb)
   6188 			SCTP_TCB_UNLOCK(stcb);
   6189 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   6190 		return (EINVAL);
   6191 	}
   6192 
   6193 	if (stcb != NULL) {
   6194 		/************************TCB SPECIFIC SET ******************/
   6195 		if (net != NULL) {
   6196 			/************************NET SPECIFIC SET ******************/
   6197 			if (paddrp->spp_flags & SPP_HB_DISABLE) {
   6198 				if (((net->dest_state & SCTP_ADDR_UNCONFIRMED) == 0) &&
   6199 				    ((net->dest_state & SCTP_ADDR_NOHB) == 0)) {
   6200 					sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net,
   6201 					                SCTP_FROM_SCTP_USRREQ + SCTP_LOC_9);
   6202 				}
   6203 				net->dest_state |= SCTP_ADDR_NOHB;
   6204 			}
   6205 			if (paddrp->spp_flags & SPP_HB_ENABLE) {
   6206 				if (paddrp->spp_hbinterval) {
   6207 					net->heart_beat_delay = paddrp->spp_hbinterval;
   6208 				} else if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO) {
   6209 					net->heart_beat_delay = 0;
   6210 				}
   6211 				sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net,
   6212 				                SCTP_FROM_SCTP_USRREQ + SCTP_LOC_10);
   6213 				sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net);
   6214 				net->dest_state &= ~SCTP_ADDR_NOHB;
   6215 			}
   6216 			if (paddrp->spp_flags & SPP_HB_DEMAND) {
   6217 				if (SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) {
   6218 					sctp_send_hb(stcb, net, SCTP_SO_LOCKED);
   6219 					sctp_chunk_output(inp, stcb,  SCTP_OUTPUT_FROM_SOCKOPT, SCTP_SO_LOCKED);
   6220 					sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net);
   6221 				}
   6222 			}
   6223 			if (paddrp->spp_flags & SPP_PMTUD_DISABLE) {
   6224 				if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
   6225 					sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net,
   6226 					                SCTP_FROM_SCTP_USRREQ + SCTP_LOC_11);
   6227 				}
   6228 				net->dest_state |= SCTP_ADDR_NO_PMTUD;
   6229 				if (paddrp->spp_pathmtu > 0) {
   6230 					net->mtu = paddrp->spp_pathmtu;
   6231 					switch (net->ro._l_addr.sa.sa_family) {
   6232 #ifdef INET
   6233 					case AF_INET:
   6234 						net->mtu += SCTP_MIN_V4_OVERHEAD;
   6235 						break;
   6236 #endif
   6237 #ifdef INET6
   6238 					case AF_INET6:
   6239 						net->mtu += SCTP_MIN_OVERHEAD;
   6240 						break;
   6241 #endif
   6242 #if defined(__Userspace__)
   6243 					case AF_CONN:
   6244 						net->mtu += sizeof(struct sctphdr);
   6245 						break;
   6246 #endif
   6247 					default:
   6248 						break;
   6249 					}
   6250 					if (net->mtu < stcb->asoc.smallest_mtu) {
   6251 						sctp_pathmtu_adjustment(stcb, net->mtu, true);
   6252 					}
   6253 				}
   6254 			}
   6255 			if (paddrp->spp_flags & SPP_PMTUD_ENABLE) {
   6256 				if (!SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
   6257 					sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net);
   6258 				}
   6259 				net->dest_state &= ~SCTP_ADDR_NO_PMTUD;
   6260 			}
   6261 			if (paddrp->spp_pathmaxrxt > 0) {
   6262 				if (net->dest_state & SCTP_ADDR_PF) {
   6263 					if (net->error_count > paddrp->spp_pathmaxrxt) {
   6264 						net->dest_state &= ~SCTP_ADDR_PF;
   6265 					}
   6266 				} else {
   6267 					if ((net->error_count <= paddrp->spp_pathmaxrxt) &&
   6268 					    (net->error_count > net->pf_threshold)) {
   6269 						net->dest_state |= SCTP_ADDR_PF;
   6270 						sctp_send_hb(stcb, net, SCTP_SO_LOCKED);
   6271 						sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT,
   6272 						                stcb->sctp_ep, stcb, net,
   6273 						                SCTP_FROM_SCTP_USRREQ + SCTP_LOC_12);
   6274 						sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net);
   6275 					}
   6276 				}
   6277 				if (net->dest_state & SCTP_ADDR_REACHABLE) {
   6278 					if (net->error_count > paddrp->spp_pathmaxrxt) {
   6279 						net->dest_state &= ~SCTP_ADDR_REACHABLE;
   6280 						sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN, stcb, 0, net, SCTP_SO_LOCKED);
   6281 					}
   6282 				} else {
   6283 					if (net->error_count <= paddrp->spp_pathmaxrxt) {
   6284 						net->dest_state |= SCTP_ADDR_REACHABLE;
   6285 						sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_UP, stcb, 0, net, SCTP_SO_LOCKED);
   6286 					}
   6287 				}
   6288 				net->failure_threshold = paddrp->spp_pathmaxrxt;
   6289 			}
   6290 			if (paddrp->spp_flags & SPP_DSCP) {
   6291 				net->dscp = paddrp->spp_dscp & 0xfc;
   6292 				net->dscp |= 0x01;
   6293 			}
   6294 #ifdef INET6
   6295 			if (paddrp->spp_flags & SPP_IPV6_FLOWLABEL) {
   6296 				if (net->ro._l_addr.sa.sa_family == AF_INET6) {
   6297 					net->flowlabel = paddrp->spp_ipv6_flowlabel & 0x000fffff;
   6298 					net->flowlabel |= 0x80000000;
   6299 				}
   6300 			}
   6301 #endif
   6302 		} else {
   6303 			/************************ASSOC ONLY -- NO NET SPECIFIC SET ******************/
   6304 			if (paddrp->spp_pathmaxrxt > 0) {
   6305 				stcb->asoc.def_net_failure = paddrp->spp_pathmaxrxt;
   6306 				TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
   6307 					if (net->dest_state & SCTP_ADDR_PF) {
   6308 						if (net->error_count > paddrp->spp_pathmaxrxt) {
   6309 							net->dest_state &= ~SCTP_ADDR_PF;
   6310 						}
   6311 					} else {
   6312 						if ((net->error_count <= paddrp->spp_pathmaxrxt) &&
   6313 						    (net->error_count > net->pf_threshold)) {
   6314 							net->dest_state |= SCTP_ADDR_PF;
   6315 							sctp_send_hb(stcb, net, SCTP_SO_LOCKED);
   6316 							sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT,
   6317 							                stcb->sctp_ep, stcb, net,
   6318 							                SCTP_FROM_SCTP_USRREQ + SCTP_LOC_13);
   6319 							sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net);
   6320 						}
   6321 					}
   6322 					if (net->dest_state & SCTP_ADDR_REACHABLE) {
   6323 						if (net->error_count > paddrp->spp_pathmaxrxt) {
   6324 							net->dest_state &= ~SCTP_ADDR_REACHABLE;
   6325 							sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN, stcb, 0, net, SCTP_SO_LOCKED);
   6326 						}
   6327 					} else {
   6328 						if (net->error_count <= paddrp->spp_pathmaxrxt) {
   6329 							net->dest_state |= SCTP_ADDR_REACHABLE;
   6330 							sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_UP, stcb, 0, net, SCTP_SO_LOCKED);
   6331 						}
   6332 					}
   6333 					net->failure_threshold = paddrp->spp_pathmaxrxt;
   6334 				}
   6335 			}
   6336 			if (paddrp->spp_flags & SPP_HB_ENABLE) {
   6337 				if (paddrp->spp_hbinterval != 0) {
   6338 					stcb->asoc.heart_beat_delay = paddrp->spp_hbinterval;
   6339 				} else if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO) {
   6340 					stcb->asoc.heart_beat_delay = 0;
   6341 				}
   6342 				/* Turn back on the timer */
   6343 				TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
   6344 					if (paddrp->spp_hbinterval != 0) {
   6345 						net->heart_beat_delay = paddrp->spp_hbinterval;
   6346 					} else if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO) {
   6347 						net->heart_beat_delay = 0;
   6348 					}
   6349 					if (net->dest_state & SCTP_ADDR_NOHB) {
   6350 						net->dest_state &= ~SCTP_ADDR_NOHB;
   6351 					}
   6352 					sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net,
   6353 							SCTP_FROM_SCTP_USRREQ + SCTP_LOC_14);
   6354 					sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net);
   6355 				}
   6356 				sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_DONOT_HEARTBEAT);
   6357 			}
   6358 			if (paddrp->spp_flags & SPP_HB_DISABLE) {
   6359 				TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
   6360 					if ((net->dest_state & SCTP_ADDR_NOHB) == 0) {
   6361 						net->dest_state |= SCTP_ADDR_NOHB;
   6362 						if ((net->dest_state & SCTP_ADDR_UNCONFIRMED) == 0) {
   6363 							sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT,
   6364 							                inp, stcb, net,
   6365 							                SCTP_FROM_SCTP_USRREQ + SCTP_LOC_15);
   6366 						}
   6367 					}
   6368 				}
   6369 				sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_DONOT_HEARTBEAT);
   6370 			}
   6371 			if (paddrp->spp_flags & SPP_PMTUD_DISABLE) {
   6372 				TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
   6373 					if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
   6374 						sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net,
   6375 						                SCTP_FROM_SCTP_USRREQ + SCTP_LOC_16);
   6376 					}
   6377 					net->dest_state |= SCTP_ADDR_NO_PMTUD;
   6378 					if (paddrp->spp_pathmtu > 0) {
   6379 						net->mtu = paddrp->spp_pathmtu;
   6380 						switch (net->ro._l_addr.sa.sa_family) {
   6381 #ifdef INET
   6382 						case AF_INET:
   6383 							net->mtu += SCTP_MIN_V4_OVERHEAD;
   6384 							break;
   6385 #endif
   6386 #ifdef INET6
   6387 						case AF_INET6:
   6388 							net->mtu += SCTP_MIN_OVERHEAD;
   6389 							break;
   6390 #endif
   6391 #if defined(__Userspace__)
   6392 						case AF_CONN:
   6393 							net->mtu += sizeof(struct sctphdr);
   6394 							break;
   6395 #endif
   6396 						default:
   6397 							break;
   6398 						}
   6399 						if (net->mtu < stcb->asoc.smallest_mtu) {
   6400 							sctp_pathmtu_adjustment(stcb, net->mtu, true);
   6401 						}
   6402 					}
   6403 				}
   6404 				if (paddrp->spp_pathmtu > 0) {
   6405 					stcb->asoc.default_mtu = paddrp->spp_pathmtu;
   6406 				}
   6407 				sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_DO_NOT_PMTUD);
   6408 			}
   6409 			if (paddrp->spp_flags & SPP_PMTUD_ENABLE) {
   6410 				TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
   6411 					if (!SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
   6412 						sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net);
   6413 					}
   6414 					net->dest_state &= ~SCTP_ADDR_NO_PMTUD;
   6415 				}
   6416 				stcb->asoc.default_mtu = 0;
   6417 				sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_DO_NOT_PMTUD);
   6418 			}
   6419 			if (paddrp->spp_flags & SPP_DSCP) {
   6420 				TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
   6421 					net->dscp = paddrp->spp_dscp & 0xfc;
   6422 					net->dscp |= 0x01;
   6423 				}
   6424 				stcb->asoc.default_dscp = paddrp->spp_dscp & 0xfc;
   6425 				stcb->asoc.default_dscp |= 0x01;
   6426 			}
   6427 #ifdef INET6
   6428 			if (paddrp->spp_flags & SPP_IPV6_FLOWLABEL) {
   6429 				TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
   6430 					if (net->ro._l_addr.sa.sa_family == AF_INET6) {
   6431 						net->flowlabel = paddrp->spp_ipv6_flowlabel & 0x000fffff;
   6432 						net->flowlabel |= 0x80000000;
   6433 					}
   6434 				}
   6435 				stcb->asoc.default_flowlabel = paddrp->spp_ipv6_flowlabel & 0x000fffff;
   6436 				stcb->asoc.default_flowlabel |= 0x80000000;
   6437 			}
   6438 #endif
   6439 		}
   6440 		SCTP_TCB_UNLOCK(stcb);
   6441 	} else {
   6442 		/************************NO TCB, SET TO default stuff ******************/
   6443 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   6444 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   6445 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   6446 		     (paddrp->spp_assoc_id == SCTP_FUTURE_ASSOC))) {
   6447 			SCTP_INP_WLOCK(inp);
   6448 			/*
   6449 			 * For the TOS/FLOWLABEL stuff you set it
   6450 			 * with the options on the socket
   6451 			 */
   6452 			if (paddrp->spp_pathmaxrxt > 0) {
   6453 				inp->sctp_ep.def_net_failure = paddrp->spp_pathmaxrxt;
   6454 			}
   6455 
   6456 			if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO)
   6457 				inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = 0;
   6458 			else if (paddrp->spp_hbinterval != 0) {
   6459 				if (paddrp->spp_hbinterval > SCTP_MAX_HB_INTERVAL)
   6460 					paddrp->spp_hbinterval= SCTP_MAX_HB_INTERVAL;
   6461 				inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = sctp_msecs_to_ticks(paddrp->spp_hbinterval);
   6462 			}
   6463 
   6464 			if (paddrp->spp_flags & SPP_HB_ENABLE) {
   6465 				if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO) {
   6466 					inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = 0;
   6467 				} else if (paddrp->spp_hbinterval) {
   6468 					inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = sctp_msecs_to_ticks(paddrp->spp_hbinterval);
   6469 				}
   6470 				sctp_feature_off(inp, SCTP_PCB_FLAGS_DONOT_HEARTBEAT);
   6471 			} else if (paddrp->spp_flags & SPP_HB_DISABLE) {
   6472 				sctp_feature_on(inp, SCTP_PCB_FLAGS_DONOT_HEARTBEAT);
   6473 			}
   6474 			if (paddrp->spp_flags & SPP_PMTUD_ENABLE) {
   6475 				inp->sctp_ep.default_mtu = 0;
   6476 				sctp_feature_off(inp, SCTP_PCB_FLAGS_DO_NOT_PMTUD);
   6477 			} else if (paddrp->spp_flags & SPP_PMTUD_DISABLE) {
   6478 				if (paddrp->spp_pathmtu > 0) {
   6479 					inp->sctp_ep.default_mtu = paddrp->spp_pathmtu;
   6480 				}
   6481 				sctp_feature_on(inp, SCTP_PCB_FLAGS_DO_NOT_PMTUD);
   6482 			}
   6483 			if (paddrp->spp_flags & SPP_DSCP) {
   6484 				inp->sctp_ep.default_dscp = paddrp->spp_dscp & 0xfc;
   6485 				inp->sctp_ep.default_dscp |= 0x01;
   6486 			}
   6487 #ifdef INET6
   6488 			if (paddrp->spp_flags & SPP_IPV6_FLOWLABEL) {
   6489 				if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
   6490 					inp->sctp_ep.default_flowlabel = paddrp->spp_ipv6_flowlabel & 0x000fffff;
   6491 					inp->sctp_ep.default_flowlabel |= 0x80000000;
   6492 				}
   6493 			}
   6494 #endif
   6495 			SCTP_INP_WUNLOCK(inp);
   6496 		} else {
   6497 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   6498 			error = EINVAL;
   6499 		}
   6500 	}
   6501 	break;
   6502 }
   6503 case SCTP_RTOINFO:
   6504 {
   6505 	struct sctp_rtoinfo *srto;
   6506 	uint32_t new_init, new_min, new_max;
   6507 
   6508 	SCTP_CHECK_AND_CAST(srto, optval, struct sctp_rtoinfo, optsize);
   6509 	SCTP_FIND_STCB(inp, stcb, srto->srto_assoc_id);
   6510 
   6511 	if (stcb) {
   6512 		if (srto->srto_initial)
   6513 			new_init = srto->srto_initial;
   6514 		else
   6515 			new_init = stcb->asoc.initial_rto;
   6516 		if (srto->srto_max)
   6517 			new_max = srto->srto_max;
   6518 		else
   6519 			new_max = stcb->asoc.maxrto;
   6520 		if (srto->srto_min)
   6521 			new_min = srto->srto_min;
   6522 		else
   6523 			new_min = stcb->asoc.minrto;
   6524 		if ((new_min <= new_init) && (new_init <= new_max)) {
   6525 			stcb->asoc.initial_rto = new_init;
   6526 			stcb->asoc.maxrto = new_max;
   6527 			stcb->asoc.minrto = new_min;
   6528 		} else {
   6529 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   6530 			error = EINVAL;
   6531 		}
   6532 		SCTP_TCB_UNLOCK(stcb);
   6533 	} else {
   6534 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   6535 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   6536 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   6537 		     (srto->srto_assoc_id == SCTP_FUTURE_ASSOC))) {
   6538 			SCTP_INP_WLOCK(inp);
   6539 			if (srto->srto_initial)
   6540 				new_init = srto->srto_initial;
   6541 			else
   6542 				new_init = inp->sctp_ep.initial_rto;
   6543 			if (srto->srto_max)
   6544 				new_max = srto->srto_max;
   6545 			else
   6546 				new_max = inp->sctp_ep.sctp_maxrto;
   6547 			if (srto->srto_min)
   6548 				new_min = srto->srto_min;
   6549 			else
   6550 				new_min = inp->sctp_ep.sctp_minrto;
   6551 			if ((new_min <= new_init) && (new_init <= new_max)) {
   6552 				inp->sctp_ep.initial_rto = new_init;
   6553 				inp->sctp_ep.sctp_maxrto = new_max;
   6554 				inp->sctp_ep.sctp_minrto = new_min;
   6555 			} else {
   6556 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   6557 				error = EINVAL;
   6558 			}
   6559 			SCTP_INP_WUNLOCK(inp);
   6560 		} else {
   6561 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   6562 			error = EINVAL;
   6563 		}
   6564 	}
   6565 	break;
   6566 }
   6567 case SCTP_ASSOCINFO:
   6568 {
   6569 	struct sctp_assocparams *sasoc;
   6570 
   6571 	SCTP_CHECK_AND_CAST(sasoc, optval, struct sctp_assocparams, optsize);
   6572 	SCTP_FIND_STCB(inp, stcb, sasoc->sasoc_assoc_id);
   6573 	if (sasoc->sasoc_cookie_life > 0) {
   6574 		/* boundary check the cookie life */
   6575 		if (sasoc->sasoc_cookie_life < SCTP_MIN_COOKIE_LIFE) {
   6576 			sasoc->sasoc_cookie_life = SCTP_MIN_COOKIE_LIFE;
   6577 		}
   6578 		if (sasoc->sasoc_cookie_life > SCTP_MAX_COOKIE_LIFE) {
   6579 			sasoc->sasoc_cookie_life = SCTP_MAX_COOKIE_LIFE;
   6580 		}
   6581 	}
   6582 	if (stcb) {
   6583 		if (sasoc->sasoc_asocmaxrxt > 0) {
   6584 			stcb->asoc.max_send_times = sasoc->sasoc_asocmaxrxt;
   6585 		}
   6586 		if (sasoc->sasoc_cookie_life > 0) {
   6587 			stcb->asoc.cookie_life = sctp_msecs_to_ticks(sasoc->sasoc_cookie_life);
   6588 		}
   6589 		SCTP_TCB_UNLOCK(stcb);
   6590 	} else {
   6591 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   6592 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   6593 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   6594 		     (sasoc->sasoc_assoc_id == SCTP_FUTURE_ASSOC))) {
   6595 			SCTP_INP_WLOCK(inp);
   6596 			if (sasoc->sasoc_asocmaxrxt > 0) {
   6597 				inp->sctp_ep.max_send_times = sasoc->sasoc_asocmaxrxt;
   6598 			}
   6599 			if (sasoc->sasoc_cookie_life > 0) {
   6600 				inp->sctp_ep.def_cookie_life = sctp_msecs_to_ticks(sasoc->sasoc_cookie_life);
   6601 			}
   6602 			SCTP_INP_WUNLOCK(inp);
   6603 		} else {
   6604 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   6605 			error = EINVAL;
   6606 		}
   6607 	}
   6608 	break;
   6609 }
   6610 case SCTP_INITMSG:
   6611 {
   6612 	struct sctp_initmsg *sinit;
   6613 
   6614 	SCTP_CHECK_AND_CAST(sinit, optval, struct sctp_initmsg, optsize);
   6615 	SCTP_INP_WLOCK(inp);
   6616 	if (sinit->sinit_num_ostreams)
   6617 		inp->sctp_ep.pre_open_stream_count = sinit->sinit_num_ostreams;
   6618 
   6619 	if (sinit->sinit_max_instreams)
   6620 		inp->sctp_ep.max_open_streams_intome = sinit->sinit_max_instreams;
   6621 
   6622 	if (sinit->sinit_max_attempts)
   6623 		inp->sctp_ep.max_init_times = sinit->sinit_max_attempts;
   6624 
   6625 	if (sinit->sinit_max_init_timeo)
   6626 		inp->sctp_ep.initial_init_rto_max = sinit->sinit_max_init_timeo;
   6627 	SCTP_INP_WUNLOCK(inp);
   6628 	break;
   6629 }
   6630 case SCTP_PRIMARY_ADDR:
   6631 {
   6632 	struct sctp_setprim *spa;
   6633 	struct sctp_nets *net;
   6634 	struct sockaddr *addr;
   6635 #if defined(INET) && defined(INET6)
   6636 	struct sockaddr_in sin_store;
   6637 #endif
   6638 
   6639 	SCTP_CHECK_AND_CAST(spa, optval, struct sctp_setprim, optsize);
   6640 	SCTP_FIND_STCB(inp, stcb, spa->ssp_assoc_id);
   6641 
   6642 #if defined(INET) && defined(INET6)
   6643 	if (spa->ssp_addr.ss_family == AF_INET6) {
   6644 		struct sockaddr_in6 *sin6;
   6645 
   6646 		sin6 = (struct sockaddr_in6 *)&spa->ssp_addr;
   6647 		if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
   6648 			in6_sin6_2_sin(&sin_store, sin6);
   6649 			addr = (struct sockaddr *)&sin_store;
   6650 		} else {
   6651 			addr = (struct sockaddr *)&spa->ssp_addr;
   6652 		}
   6653 	} else {
   6654 		addr = (struct sockaddr *)&spa->ssp_addr;
   6655 	}
   6656 #else
   6657 	addr = (struct sockaddr *)&spa->ssp_addr;
   6658 #endif
   6659 	if (stcb != NULL) {
   6660 		net = sctp_findnet(stcb, addr);
   6661 	} else {
   6662 		/* We increment here since sctp_findassociation_ep_addr() wil
   6663 		 * do a decrement if it finds the stcb as long as the locked
   6664 		 * tcb (last argument) is NOT a TCB.. aka NULL.
   6665 		 */
   6666 		net = NULL;
   6667 		SCTP_INP_INCR_REF(inp);
   6668 		stcb = sctp_findassociation_ep_addr(&inp, addr,
   6669 		                                    &net, NULL, NULL);
   6670 		if (stcb == NULL) {
   6671 			SCTP_INP_DECR_REF(inp);
   6672 		}
   6673 	}
   6674 
   6675 	if ((stcb != NULL) && (net != NULL)) {
   6676 		if (net != stcb->asoc.primary_destination) {
   6677 			if ((net->dest_state & SCTP_ADDR_UNCONFIRMED) == 0) {
   6678 				/* Ok we need to set it */
   6679 				if (sctp_set_primary_addr(stcb, (struct sockaddr *)NULL, net) == 0) {
   6680 					if ((stcb->asoc.alternate) &&
   6681 					    ((net->dest_state & SCTP_ADDR_PF) == 0) &&
   6682 					    (net->dest_state & SCTP_ADDR_REACHABLE)) {
   6683 						sctp_free_remote_addr(stcb->asoc.alternate);
   6684 						stcb->asoc.alternate = NULL;
   6685 					}
   6686 				} else {
   6687 					SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   6688 					error = EINVAL;
   6689 				}
   6690 			} else {
   6691 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   6692 				error = EINVAL;
   6693 			}
   6694 		}
   6695 	} else {
   6696 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   6697 		error = EINVAL;
   6698 	}
   6699 	if (stcb != NULL) {
   6700 		SCTP_TCB_UNLOCK(stcb);
   6701 	}
   6702 	break;
   6703 }
   6704 case SCTP_SET_DYNAMIC_PRIMARY:
   6705 {
   6706 	union sctp_sockstore *ss;
   6707 #ifdef SCTP_MVRF
   6708 	int i, fnd = 0;
   6709 #endif
   6710 #if !defined(_WIN32) && !defined(__Userspace__)
   6711 #if defined(__APPLE__)
   6712 	struct proc *proc;
   6713 #endif
   6714 #if defined(__FreeBSD__)
   6715 	error = priv_check(curthread,
   6716 			   PRIV_NETINET_RESERVEDPORT);
   6717 #elif defined(__APPLE__)
   6718 	proc = (struct proc *)p;
   6719 	if (p) {
   6720 		error = suser(proc->p_ucred, &proc->p_acflag);
   6721 	} else {
   6722 		break;
   6723 	}
   6724 #else
   6725 	error = suser(p, 0);
   6726 #endif
   6727 	if (error)
   6728 		break;
   6729 #endif
   6730 
   6731 	SCTP_CHECK_AND_CAST(ss, optval, union sctp_sockstore, optsize);
   6732 	/* SUPER USER CHECK? */
   6733 #ifdef SCTP_MVRF
   6734 	for (i = 0; i < inp->num_vrfs; i++) {
   6735 		if (vrf_id == inp->m_vrf_ids[i]) {
   6736 			fnd = 1;
   6737 			break;
   6738 		}
   6739 	}
   6740 	if (!fnd) {
   6741 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   6742 		error = EINVAL;
   6743 		break;
   6744 	}
   6745 #endif
   6746 	error = sctp_dynamic_set_primary(&ss->sa, vrf_id);
   6747 	break;
   6748 }
   6749 case SCTP_SET_PEER_PRIMARY_ADDR:
   6750 {
   6751 	struct sctp_setpeerprim *sspp;
   6752 	struct sockaddr *addr;
   6753 #if defined(INET) && defined(INET6)
   6754 	struct sockaddr_in sin_store;
   6755 #endif
   6756 
   6757 	SCTP_CHECK_AND_CAST(sspp, optval, struct sctp_setpeerprim, optsize);
   6758 	SCTP_FIND_STCB(inp, stcb, sspp->sspp_assoc_id);
   6759 	if (stcb != NULL) {
   6760 		struct sctp_ifa *ifa;
   6761 
   6762 #if defined(INET) && defined(INET6)
   6763 		if (sspp->sspp_addr.ss_family == AF_INET6) {
   6764 			struct sockaddr_in6 *sin6;
   6765 
   6766 			sin6 = (struct sockaddr_in6 *)&sspp->sspp_addr;
   6767 			if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
   6768 				in6_sin6_2_sin(&sin_store, sin6);
   6769 				addr = (struct sockaddr *)&sin_store;
   6770 			} else {
   6771 				addr = (struct sockaddr *)&sspp->sspp_addr;
   6772 			}
   6773 		} else {
   6774 			addr = (struct sockaddr *)&sspp->sspp_addr;
   6775 		}
   6776 #else
   6777 		addr = (struct sockaddr *)&sspp->sspp_addr;
   6778 #endif
   6779 		ifa = sctp_find_ifa_by_addr(addr, stcb->asoc.vrf_id, SCTP_ADDR_NOT_LOCKED);
   6780 		if (ifa == NULL) {
   6781 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   6782 			error = EINVAL;
   6783 			goto out_of_it;
   6784 		}
   6785 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) {
   6786 			/* Must validate the ifa found is in our ep */
   6787 			struct sctp_laddr *laddr;
   6788 			int found = 0;
   6789 
   6790 			LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
   6791 				if (laddr->ifa == NULL) {
   6792 					SCTPDBG(SCTP_DEBUG_OUTPUT1, "%s: NULL ifa\n",
   6793 						__func__);
   6794 					continue;
   6795 				}
   6796 				if ((sctp_is_addr_restricted(stcb, laddr->ifa)) &&
   6797 				    (!sctp_is_addr_pending(stcb, laddr->ifa))) {
   6798 					continue;
   6799 				}
   6800 				if (laddr->ifa == ifa) {
   6801 					found = 1;
   6802 					break;
   6803 				}
   6804 			}
   6805 			if (!found) {
   6806 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   6807 				error = EINVAL;
   6808 				goto out_of_it;
   6809 			}
   6810 #if defined(__FreeBSD__) && !defined(__Userspace__)
   6811 		} else {
   6812 			switch (addr->sa_family) {
   6813 #ifdef INET
   6814 			case AF_INET:
   6815 			{
   6816 				struct sockaddr_in *sin;
   6817 
   6818 				sin = (struct sockaddr_in *)addr;
   6819 				if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
   6820 				                     &sin->sin_addr) != 0) {
   6821 					SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   6822 					error = EINVAL;
   6823 					goto out_of_it;
   6824 				}
   6825 				break;
   6826 			}
   6827 #endif
   6828 #ifdef INET6
   6829 			case AF_INET6:
   6830 			{
   6831 				struct sockaddr_in6 *sin6;
   6832 
   6833 				sin6 = (struct sockaddr_in6 *)addr;
   6834 				if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
   6835 				                     &sin6->sin6_addr) != 0) {
   6836 					SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   6837 					error = EINVAL;
   6838 					goto out_of_it;
   6839 				}
   6840 				break;
   6841 			}
   6842 #endif
   6843 			default:
   6844 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   6845 				error = EINVAL;
   6846 				goto out_of_it;
   6847 			}
   6848 #endif
   6849 		}
   6850 		if (sctp_set_primary_ip_address_sa(stcb, addr) != 0) {
   6851 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   6852 			error = EINVAL;
   6853 		}
   6854 		sctp_chunk_output(inp, stcb,  SCTP_OUTPUT_FROM_SOCKOPT, SCTP_SO_LOCKED);
   6855 	out_of_it:
   6856 		SCTP_TCB_UNLOCK(stcb);
   6857 	} else {
   6858 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   6859 		error = EINVAL;
   6860 	}
   6861 	break;
   6862 }
   6863 case SCTP_BINDX_ADD_ADDR:
   6864 {
   6865 	struct sockaddr *sa;
   6866 #if defined(__FreeBSD__) && !defined(__Userspace__)
   6867 	struct thread *td;
   6868 
   6869 	td = (struct thread *)p;
   6870 #endif
   6871 	SCTP_CHECK_AND_CAST(sa, optval, struct sockaddr, optsize);
   6872 #ifdef INET
   6873 	if (sa->sa_family == AF_INET) {
   6874 		if (optsize < sizeof(struct sockaddr_in)) {
   6875 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   6876 			error = EINVAL;
   6877 			break;
   6878 		}
   6879 #if defined(__FreeBSD__) && !defined(__Userspace__)
   6880 		if (td != NULL &&
   6881 		    (error = prison_local_ip4(td->td_ucred, &(((struct sockaddr_in *)sa)->sin_addr)))) {
   6882 			SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, error);
   6883 			break;
   6884 		}
   6885 #endif
   6886 	} else
   6887 #endif
   6888 #ifdef INET6
   6889 	if (sa->sa_family == AF_INET6) {
   6890 		if (optsize < sizeof(struct sockaddr_in6)) {
   6891 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   6892 			error = EINVAL;
   6893 			break;
   6894 		}
   6895 #if defined(__FreeBSD__) && !defined(__Userspace__)
   6896 		if (td != NULL &&
   6897 		    (error = prison_local_ip6(td->td_ucred,
   6898 		                              &(((struct sockaddr_in6 *)sa)->sin6_addr),
   6899 		                              (SCTP_IPV6_V6ONLY(inp) != 0))) != 0) {
   6900 			SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, error);
   6901 			break;
   6902 		}
   6903 #endif
   6904 	} else
   6905 #endif
   6906 	{
   6907 		error = EAFNOSUPPORT;
   6908 		break;
   6909 	}
   6910 	sctp_bindx_add_address(so, inp, sa, vrf_id, &error, p);
   6911 	break;
   6912 }
   6913 case SCTP_BINDX_REM_ADDR:
   6914 {
   6915 	struct sockaddr *sa;
   6916 #if defined(__FreeBSD__) && !defined(__Userspace__)
   6917 	struct thread *td;
   6918 	td = (struct thread *)p;
   6919 
   6920 #endif
   6921 	SCTP_CHECK_AND_CAST(sa, optval, struct sockaddr, optsize);
   6922 #ifdef INET
   6923 	if (sa->sa_family == AF_INET) {
   6924 		if (optsize < sizeof(struct sockaddr_in)) {
   6925 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   6926 			error = EINVAL;
   6927 			break;
   6928 		}
   6929 #if defined(__FreeBSD__) && !defined(__Userspace__)
   6930 		if (td != NULL &&
   6931 		    (error = prison_local_ip4(td->td_ucred, &(((struct sockaddr_in *)sa)->sin_addr)))) {
   6932 			SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, error);
   6933 			break;
   6934 		}
   6935 #endif
   6936 	} else
   6937 #endif
   6938 #ifdef INET6
   6939 	if (sa->sa_family == AF_INET6) {
   6940 		if (optsize < sizeof(struct sockaddr_in6)) {
   6941 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   6942 			error = EINVAL;
   6943 			break;
   6944 		}
   6945 #if defined(__FreeBSD__) && !defined(__Userspace__)
   6946 		if (td != NULL &&
   6947 		    (error = prison_local_ip6(td->td_ucred,
   6948 		                              &(((struct sockaddr_in6 *)sa)->sin6_addr),
   6949 		                              (SCTP_IPV6_V6ONLY(inp) != 0))) != 0) {
   6950 			SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, error);
   6951 			break;
   6952 		}
   6953 #endif
   6954 	} else
   6955 #endif
   6956 	{
   6957 		error = EAFNOSUPPORT;
   6958 		break;
   6959 	}
   6960 	sctp_bindx_delete_address(inp, sa, vrf_id, &error);
   6961 	break;
   6962 }
   6963 #if defined(__APPLE__) && !defined(__Userspace__)
   6964 case SCTP_LISTEN_FIX:
   6965 	/* only applies to one-to-many sockets */
   6966 	if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) {
   6967 		/* make sure the ACCEPTCONN flag is OFF */
   6968 		so->so_options &= ~SO_ACCEPTCONN;
   6969 	} else {
   6970 		/* otherwise, not allowed */
   6971 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   6972 		error = EINVAL;
   6973 	}
   6974 	break;
   6975 #endif
   6976 case SCTP_EVENT:
   6977 {
   6978 	struct sctp_event *event;
   6979 	uint32_t event_type;
   6980 
   6981 	SCTP_CHECK_AND_CAST(event, optval, struct sctp_event, optsize);
   6982 	SCTP_FIND_STCB(inp, stcb, event->se_assoc_id);
   6983 	switch (event->se_type) {
   6984 	case SCTP_ASSOC_CHANGE:
   6985 		event_type = SCTP_PCB_FLAGS_RECVASSOCEVNT;
   6986 		break;
   6987 	case SCTP_PEER_ADDR_CHANGE:
   6988 		event_type = SCTP_PCB_FLAGS_RECVPADDREVNT;
   6989 		break;
   6990 	case SCTP_REMOTE_ERROR:
   6991 		event_type = SCTP_PCB_FLAGS_RECVPEERERR;
   6992 		break;
   6993 	case SCTP_SEND_FAILED:
   6994 		event_type = SCTP_PCB_FLAGS_RECVSENDFAILEVNT;
   6995 		break;
   6996 	case SCTP_SHUTDOWN_EVENT:
   6997 		event_type = SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT;
   6998 		break;
   6999 	case SCTP_ADAPTATION_INDICATION:
   7000 		event_type = SCTP_PCB_FLAGS_ADAPTATIONEVNT;
   7001 		break;
   7002 	case SCTP_PARTIAL_DELIVERY_EVENT:
   7003 		event_type = SCTP_PCB_FLAGS_PDAPIEVNT;
   7004 		break;
   7005 	case SCTP_AUTHENTICATION_EVENT:
   7006 		event_type = SCTP_PCB_FLAGS_AUTHEVNT;
   7007 		break;
   7008 	case SCTP_STREAM_RESET_EVENT:
   7009 		event_type = SCTP_PCB_FLAGS_STREAM_RESETEVNT;
   7010 		break;
   7011 	case SCTP_SENDER_DRY_EVENT:
   7012 		event_type = SCTP_PCB_FLAGS_DRYEVNT;
   7013 		break;
   7014 	case SCTP_NOTIFICATIONS_STOPPED_EVENT:
   7015 		event_type = 0;
   7016 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTSUP);
   7017 		error = ENOTSUP;
   7018 		break;
   7019 	case SCTP_ASSOC_RESET_EVENT:
   7020 		event_type = SCTP_PCB_FLAGS_ASSOC_RESETEVNT;
   7021 		break;
   7022 	case SCTP_STREAM_CHANGE_EVENT:
   7023 		event_type = SCTP_PCB_FLAGS_STREAM_CHANGEEVNT;
   7024 		break;
   7025 	case SCTP_SEND_FAILED_EVENT:
   7026 		event_type = SCTP_PCB_FLAGS_RECVNSENDFAILEVNT;
   7027 		break;
   7028 	default:
   7029 		event_type = 0;
   7030 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   7031 		error = EINVAL;
   7032 		break;
   7033 	}
   7034 	if (event_type > 0) {
   7035 		if (stcb) {
   7036 			if (event->se_on) {
   7037 				sctp_stcb_feature_on(inp, stcb, event_type);
   7038 				if (event_type == SCTP_PCB_FLAGS_DRYEVNT) {
   7039 					if (TAILQ_EMPTY(&stcb->asoc.send_queue) &&
   7040 					    TAILQ_EMPTY(&stcb->asoc.sent_queue) &&
   7041 					    (stcb->asoc.stream_queue_cnt == 0)) {
   7042 						sctp_ulp_notify(SCTP_NOTIFY_SENDER_DRY, stcb,  0, NULL, SCTP_SO_LOCKED);
   7043 					}
   7044 				}
   7045 			} else {
   7046 				sctp_stcb_feature_off(inp, stcb, event_type);
   7047 			}
   7048 			SCTP_TCB_UNLOCK(stcb);
   7049 		} else {
   7050 			/*
   7051 			 * We don't want to send up a storm of events,
   7052 			 * so return an error for sender dry events
   7053 			 */
   7054 			if ((event_type == SCTP_PCB_FLAGS_DRYEVNT) &&
   7055 			    (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   7056 			    ((event->se_assoc_id == SCTP_ALL_ASSOC) ||
   7057 			     (event->se_assoc_id == SCTP_CURRENT_ASSOC))) {
   7058 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTSUP);
   7059 				error = ENOTSUP;
   7060 				break;
   7061 			}
   7062 			if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   7063 			    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   7064 			    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   7065 			     ((event->se_assoc_id == SCTP_FUTURE_ASSOC) ||
   7066 			      (event->se_assoc_id == SCTP_ALL_ASSOC)))) {
   7067 				SCTP_INP_WLOCK(inp);
   7068 				if (event->se_on) {
   7069 					sctp_feature_on(inp, event_type);
   7070 				} else {
   7071 					sctp_feature_off(inp, event_type);
   7072 				}
   7073 				SCTP_INP_WUNLOCK(inp);
   7074 			}
   7075 			if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   7076 			    ((event->se_assoc_id == SCTP_CURRENT_ASSOC) ||
   7077 			     (event->se_assoc_id == SCTP_ALL_ASSOC))) {
   7078 				SCTP_INP_RLOCK(inp);
   7079 				LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
   7080 					SCTP_TCB_LOCK(stcb);
   7081 					if (event->se_on) {
   7082 						sctp_stcb_feature_on(inp, stcb, event_type);
   7083 					} else {
   7084 						sctp_stcb_feature_off(inp, stcb, event_type);
   7085 					}
   7086 					SCTP_TCB_UNLOCK(stcb);
   7087 				}
   7088 				SCTP_INP_RUNLOCK(inp);
   7089 			}
   7090 		}
   7091 	} else {
   7092 		if (stcb) {
   7093 			SCTP_TCB_UNLOCK(stcb);
   7094 		}
   7095 	}
   7096 	break;
   7097 }
   7098 case SCTP_RECVRCVINFO:
   7099 {
   7100 	int *onoff;
   7101 
   7102 	SCTP_CHECK_AND_CAST(onoff, optval, int, optsize);
   7103 	SCTP_INP_WLOCK(inp);
   7104 	if (*onoff != 0) {
   7105 		sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVRCVINFO);
   7106 	} else {
   7107 		sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVRCVINFO);
   7108 	}
   7109 	SCTP_INP_WUNLOCK(inp);
   7110 	break;
   7111 }
   7112 case SCTP_RECVNXTINFO:
   7113 {
   7114 	int *onoff;
   7115 
   7116 	SCTP_CHECK_AND_CAST(onoff, optval, int, optsize);
   7117 	SCTP_INP_WLOCK(inp);
   7118 	if (*onoff != 0) {
   7119 		sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVNXTINFO);
   7120 	} else {
   7121 		sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVNXTINFO);
   7122 	}
   7123 	SCTP_INP_WUNLOCK(inp);
   7124 	break;
   7125 }
   7126 case SCTP_DEFAULT_SNDINFO:
   7127 {
   7128 	struct sctp_sndinfo *info;
   7129 	uint16_t policy;
   7130 
   7131 	SCTP_CHECK_AND_CAST(info, optval, struct sctp_sndinfo, optsize);
   7132 	SCTP_FIND_STCB(inp, stcb, info->snd_assoc_id);
   7133 
   7134 	if (stcb) {
   7135 		if (info->snd_sid < stcb->asoc.streamoutcnt) {
   7136 			stcb->asoc.def_send.sinfo_stream = info->snd_sid;
   7137 			policy = PR_SCTP_POLICY(stcb->asoc.def_send.sinfo_flags);
   7138 			stcb->asoc.def_send.sinfo_flags = info->snd_flags;
   7139 			stcb->asoc.def_send.sinfo_flags |= policy;
   7140 			stcb->asoc.def_send.sinfo_ppid = info->snd_ppid;
   7141 			stcb->asoc.def_send.sinfo_context = info->snd_context;
   7142 		} else {
   7143 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   7144 			error = EINVAL;
   7145 		}
   7146 		SCTP_TCB_UNLOCK(stcb);
   7147 	} else {
   7148 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   7149 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   7150 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   7151 		     ((info->snd_assoc_id == SCTP_FUTURE_ASSOC) ||
   7152 		      (info->snd_assoc_id == SCTP_ALL_ASSOC)))) {
   7153 			SCTP_INP_WLOCK(inp);
   7154 			inp->def_send.sinfo_stream = info->snd_sid;
   7155 			policy = PR_SCTP_POLICY(inp->def_send.sinfo_flags);
   7156 			inp->def_send.sinfo_flags = info->snd_flags;
   7157 			inp->def_send.sinfo_flags |= policy;
   7158 			inp->def_send.sinfo_ppid = info->snd_ppid;
   7159 			inp->def_send.sinfo_context = info->snd_context;
   7160 			SCTP_INP_WUNLOCK(inp);
   7161 		}
   7162 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   7163 		    ((info->snd_assoc_id == SCTP_CURRENT_ASSOC) ||
   7164 		     (info->snd_assoc_id == SCTP_ALL_ASSOC))) {
   7165 			SCTP_INP_RLOCK(inp);
   7166 			LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
   7167 				SCTP_TCB_LOCK(stcb);
   7168 				if (info->snd_sid < stcb->asoc.streamoutcnt) {
   7169 					stcb->asoc.def_send.sinfo_stream = info->snd_sid;
   7170 					policy = PR_SCTP_POLICY(stcb->asoc.def_send.sinfo_flags);
   7171 					stcb->asoc.def_send.sinfo_flags = info->snd_flags;
   7172 					stcb->asoc.def_send.sinfo_flags |= policy;
   7173 					stcb->asoc.def_send.sinfo_ppid = info->snd_ppid;
   7174 					stcb->asoc.def_send.sinfo_context = info->snd_context;
   7175 				}
   7176 				SCTP_TCB_UNLOCK(stcb);
   7177 			}
   7178 			SCTP_INP_RUNLOCK(inp);
   7179 		}
   7180 	}
   7181 	break;
   7182 }
   7183 case SCTP_DEFAULT_PRINFO:
   7184 {
   7185 	struct sctp_default_prinfo *info;
   7186 
   7187 	SCTP_CHECK_AND_CAST(info, optval, struct sctp_default_prinfo, optsize);
   7188 	SCTP_FIND_STCB(inp, stcb, info->pr_assoc_id);
   7189 
   7190 	if (info->pr_policy > SCTP_PR_SCTP_MAX) {
   7191 		if (stcb) {
   7192 			SCTP_TCB_UNLOCK(stcb);
   7193 		}
   7194 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   7195 		error = EINVAL;
   7196 		break;
   7197 	}
   7198 	if (stcb) {
   7199 		stcb->asoc.def_send.sinfo_flags &= 0xfff0;
   7200 		stcb->asoc.def_send.sinfo_flags |= info->pr_policy;
   7201 		stcb->asoc.def_send.sinfo_timetolive = info->pr_value;
   7202 		SCTP_TCB_UNLOCK(stcb);
   7203 	} else {
   7204 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   7205 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   7206 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   7207 		     ((info->pr_assoc_id == SCTP_FUTURE_ASSOC) ||
   7208 		      (info->pr_assoc_id == SCTP_ALL_ASSOC)))) {
   7209 			SCTP_INP_WLOCK(inp);
   7210 			inp->def_send.sinfo_flags &= 0xfff0;
   7211 			inp->def_send.sinfo_flags |= info->pr_policy;
   7212 			inp->def_send.sinfo_timetolive = info->pr_value;
   7213 			SCTP_INP_WUNLOCK(inp);
   7214 		}
   7215 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   7216 		    ((info->pr_assoc_id == SCTP_CURRENT_ASSOC) ||
   7217 		     (info->pr_assoc_id == SCTP_ALL_ASSOC))) {
   7218 			SCTP_INP_RLOCK(inp);
   7219 			LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
   7220 				SCTP_TCB_LOCK(stcb);
   7221 				stcb->asoc.def_send.sinfo_flags &= 0xfff0;
   7222 				stcb->asoc.def_send.sinfo_flags |= info->pr_policy;
   7223 				stcb->asoc.def_send.sinfo_timetolive = info->pr_value;
   7224 				SCTP_TCB_UNLOCK(stcb);
   7225 			}
   7226 			SCTP_INP_RUNLOCK(inp);
   7227 		}
   7228 	}
   7229 	break;
   7230 }
   7231 case SCTP_PEER_ADDR_THLDS:
   7232 	/* Applies to the specific association */
   7233 {
   7234 	struct sctp_paddrthlds *thlds;
   7235 	struct sctp_nets *net;
   7236 	struct sockaddr *addr;
   7237 #if defined(INET) && defined(INET6)
   7238 	struct sockaddr_in sin_store;
   7239 #endif
   7240 
   7241 	SCTP_CHECK_AND_CAST(thlds, optval, struct sctp_paddrthlds, optsize);
   7242 	SCTP_FIND_STCB(inp, stcb, thlds->spt_assoc_id);
   7243 
   7244 #if defined(INET) && defined(INET6)
   7245 	if (thlds->spt_address.ss_family == AF_INET6) {
   7246 		struct sockaddr_in6 *sin6;
   7247 
   7248 		sin6 = (struct sockaddr_in6 *)&thlds->spt_address;
   7249 		if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
   7250 			in6_sin6_2_sin(&sin_store, sin6);
   7251 			addr = (struct sockaddr *)&sin_store;
   7252 		} else {
   7253 			addr = (struct sockaddr *)&thlds->spt_address;
   7254 		}
   7255 	} else {
   7256 		addr = (struct sockaddr *)&thlds->spt_address;
   7257 	}
   7258 #else
   7259 	addr = (struct sockaddr *)&thlds->spt_address;
   7260 #endif
   7261 	if (stcb != NULL) {
   7262 		net = sctp_findnet(stcb, addr);
   7263 	} else {
   7264 		/* We increment here since sctp_findassociation_ep_addr() wil
   7265 		 * do a decrement if it finds the stcb as long as the locked
   7266 		 * tcb (last argument) is NOT a TCB.. aka NULL.
   7267 		 */
   7268 		net = NULL;
   7269 		SCTP_INP_INCR_REF(inp);
   7270 		stcb = sctp_findassociation_ep_addr(&inp, addr,
   7271 		                                    &net, NULL, NULL);
   7272 		if (stcb == NULL) {
   7273 			SCTP_INP_DECR_REF(inp);
   7274 		}
   7275 	}
   7276 	if ((stcb != NULL) && (net == NULL)) {
   7277 #ifdef INET
   7278 		if (addr->sa_family == AF_INET) {
   7279 			struct sockaddr_in *sin;
   7280 
   7281 			sin = (struct sockaddr_in *)addr;
   7282 			if (sin->sin_addr.s_addr != INADDR_ANY) {
   7283 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   7284 				SCTP_TCB_UNLOCK(stcb);
   7285 				error = EINVAL;
   7286 				break;
   7287 			}
   7288 		} else
   7289 #endif
   7290 #ifdef INET6
   7291 		if (addr->sa_family == AF_INET6) {
   7292 			struct sockaddr_in6 *sin6;
   7293 
   7294 			sin6 = (struct sockaddr_in6 *)addr;
   7295 			if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
   7296 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   7297 				SCTP_TCB_UNLOCK(stcb);
   7298 				error = EINVAL;
   7299 				break;
   7300 			}
   7301 		} else
   7302 #endif
   7303 #if defined(__Userspace__)
   7304 		if (addr->sa_family == AF_CONN) {
   7305 			struct sockaddr_conn *sconn;
   7306 
   7307 			sconn = (struct sockaddr_conn *)addr;
   7308 			if (sconn->sconn_addr != NULL) {
   7309 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   7310 				SCTP_TCB_UNLOCK(stcb);
   7311 				error = EINVAL;
   7312 				break;
   7313 			}
   7314 		} else
   7315 #endif
   7316 		{
   7317 			error = EAFNOSUPPORT;
   7318 			SCTP_TCB_UNLOCK(stcb);
   7319 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
   7320 			break;
   7321 		}
   7322 	}
   7323 	if (thlds->spt_pathcpthld != 0xffff) {
   7324 		if (stcb != NULL) {
   7325 			SCTP_TCB_UNLOCK(stcb);
   7326 		}
   7327 		error = EINVAL;
   7328 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
   7329 		break;
   7330 	}
   7331 	if (stcb != NULL) {
   7332 		if (net != NULL) {
   7333 			net->failure_threshold = thlds->spt_pathmaxrxt;
   7334 			net->pf_threshold = thlds->spt_pathpfthld;
   7335 			if (net->dest_state & SCTP_ADDR_PF) {
   7336 				if ((net->error_count > net->failure_threshold) ||
   7337 				    (net->error_count <= net->pf_threshold)) {
   7338 					net->dest_state &= ~SCTP_ADDR_PF;
   7339 				}
   7340 			} else {
   7341 				if ((net->error_count > net->pf_threshold) &&
   7342 				    (net->error_count <= net->failure_threshold)) {
   7343 					net->dest_state |= SCTP_ADDR_PF;
   7344 					sctp_send_hb(stcb, net, SCTP_SO_LOCKED);
   7345 					sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT,
   7346 					                stcb->sctp_ep, stcb, net,
   7347 					                SCTP_FROM_SCTP_USRREQ + SCTP_LOC_17);
   7348 					sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net);
   7349 				}
   7350 			}
   7351 			if (net->dest_state & SCTP_ADDR_REACHABLE) {
   7352 				if (net->error_count > net->failure_threshold) {
   7353 					net->dest_state &= ~SCTP_ADDR_REACHABLE;
   7354 					sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN, stcb, 0, net, SCTP_SO_LOCKED);
   7355 				}
   7356 			} else {
   7357 				if (net->error_count <= net->failure_threshold) {
   7358 					net->dest_state |= SCTP_ADDR_REACHABLE;
   7359 					sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_UP, stcb, 0, net, SCTP_SO_LOCKED);
   7360 				}
   7361 			}
   7362 		} else {
   7363 			TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
   7364 				net->failure_threshold = thlds->spt_pathmaxrxt;
   7365 				net->pf_threshold = thlds->spt_pathpfthld;
   7366 				if (net->dest_state & SCTP_ADDR_PF) {
   7367 					if ((net->error_count > net->failure_threshold) ||
   7368 					    (net->error_count <= net->pf_threshold)) {
   7369 						net->dest_state &= ~SCTP_ADDR_PF;
   7370 					}
   7371 				} else {
   7372 					if ((net->error_count > net->pf_threshold) &&
   7373 					    (net->error_count <= net->failure_threshold)) {
   7374 						net->dest_state |= SCTP_ADDR_PF;
   7375 						sctp_send_hb(stcb, net, SCTP_SO_LOCKED);
   7376 						sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT,
   7377 						                stcb->sctp_ep, stcb, net,
   7378 						                SCTP_FROM_SCTP_USRREQ + SCTP_LOC_18);
   7379 						sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net);
   7380 					}
   7381 				}
   7382 				if (net->dest_state & SCTP_ADDR_REACHABLE) {
   7383 					if (net->error_count > net->failure_threshold) {
   7384 						net->dest_state &= ~SCTP_ADDR_REACHABLE;
   7385 						sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN, stcb, 0, net, SCTP_SO_LOCKED);
   7386 					}
   7387 				} else {
   7388 					if (net->error_count <= net->failure_threshold) {
   7389 						net->dest_state |= SCTP_ADDR_REACHABLE;
   7390 						sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_UP, stcb, 0, net, SCTP_SO_LOCKED);
   7391 					}
   7392 				}
   7393 			}
   7394 			stcb->asoc.def_net_failure = thlds->spt_pathmaxrxt;
   7395 			stcb->asoc.def_net_pf_threshold = thlds->spt_pathpfthld;
   7396 		}
   7397 		SCTP_TCB_UNLOCK(stcb);
   7398 	} else {
   7399 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   7400 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   7401 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   7402 		     (thlds->spt_assoc_id == SCTP_FUTURE_ASSOC))) {
   7403 			SCTP_INP_WLOCK(inp);
   7404 			inp->sctp_ep.def_net_failure = thlds->spt_pathmaxrxt;
   7405 			inp->sctp_ep.def_net_pf_threshold = thlds->spt_pathpfthld;
   7406 			SCTP_INP_WUNLOCK(inp);
   7407 		} else {
   7408 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   7409 			error = EINVAL;
   7410 		}
   7411 	}
   7412 	break;
   7413 }
   7414 case SCTP_REMOTE_UDP_ENCAPS_PORT:
   7415 {
   7416 	struct sctp_udpencaps *encaps;
   7417 	struct sctp_nets *net;
   7418 	struct sockaddr *addr;
   7419 #if defined(INET) && defined(INET6)
   7420 	struct sockaddr_in sin_store;
   7421 #endif
   7422 
   7423 	SCTP_CHECK_AND_CAST(encaps, optval, struct sctp_udpencaps, optsize);
   7424 	SCTP_FIND_STCB(inp, stcb, encaps->sue_assoc_id);
   7425 
   7426 #if defined(INET) && defined(INET6)
   7427 	if (encaps->sue_address.ss_family == AF_INET6) {
   7428 		struct sockaddr_in6 *sin6;
   7429 
   7430 		sin6 = (struct sockaddr_in6 *)&encaps->sue_address;
   7431 		if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
   7432 			in6_sin6_2_sin(&sin_store, sin6);
   7433 			addr = (struct sockaddr *)&sin_store;
   7434 		} else {
   7435 			addr = (struct sockaddr *)&encaps->sue_address;
   7436 		}
   7437 	} else {
   7438 		addr = (struct sockaddr *)&encaps->sue_address;
   7439 	}
   7440 #else
   7441 	addr = (struct sockaddr *)&encaps->sue_address;
   7442 #endif
   7443 	if (stcb != NULL) {
   7444 		net = sctp_findnet(stcb, addr);
   7445 	} else {
   7446 		/* We increment here since sctp_findassociation_ep_addr() wil
   7447 		 * do a decrement if it finds the stcb as long as the locked
   7448 		 * tcb (last argument) is NOT a TCB.. aka NULL.
   7449 		 */
   7450 		net = NULL;
   7451 		SCTP_INP_INCR_REF(inp);
   7452 		stcb = sctp_findassociation_ep_addr(&inp, addr, &net, NULL, NULL);
   7453 		if (stcb == NULL) {
   7454 			SCTP_INP_DECR_REF(inp);
   7455 		}
   7456 	}
   7457 	if ((stcb != NULL) && (net == NULL)) {
   7458 #ifdef INET
   7459 		if (addr->sa_family == AF_INET) {
   7460 			struct sockaddr_in *sin;
   7461 
   7462 			sin = (struct sockaddr_in *)addr;
   7463 			if (sin->sin_addr.s_addr != INADDR_ANY) {
   7464 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   7465 				SCTP_TCB_UNLOCK(stcb);
   7466 				error = EINVAL;
   7467 				break;
   7468 			}
   7469 		} else
   7470 #endif
   7471 #ifdef INET6
   7472 		if (addr->sa_family == AF_INET6) {
   7473 			struct sockaddr_in6 *sin6;
   7474 
   7475 			sin6 = (struct sockaddr_in6 *)addr;
   7476 			if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
   7477 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   7478 				SCTP_TCB_UNLOCK(stcb);
   7479 				error = EINVAL;
   7480 				break;
   7481 			}
   7482 		} else
   7483 #endif
   7484 #if defined(__Userspace__)
   7485 		if (addr->sa_family == AF_CONN) {
   7486 			struct sockaddr_conn *sconn;
   7487 
   7488 			sconn = (struct sockaddr_conn *)addr;
   7489 			if (sconn->sconn_addr != NULL) {
   7490 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   7491 				SCTP_TCB_UNLOCK(stcb);
   7492 				error = EINVAL;
   7493 				break;
   7494 			}
   7495 		} else
   7496 #endif
   7497 		{
   7498 				error = EAFNOSUPPORT;
   7499 				SCTP_TCB_UNLOCK(stcb);
   7500 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
   7501 				break;
   7502 			}
   7503 	}
   7504 
   7505 	if (stcb != NULL) {
   7506 		if (net != NULL) {
   7507 			net->port = encaps->sue_port;
   7508 		} else {
   7509 			stcb->asoc.port = encaps->sue_port;
   7510 		}
   7511 		SCTP_TCB_UNLOCK(stcb);
   7512 	} else {
   7513 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   7514 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   7515 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   7516 		     (encaps->sue_assoc_id == SCTP_FUTURE_ASSOC))) {
   7517 			SCTP_INP_WLOCK(inp);
   7518 			inp->sctp_ep.port = encaps->sue_port;
   7519 			SCTP_INP_WUNLOCK(inp);
   7520 		} else {
   7521 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   7522 			error = EINVAL;
   7523 		}
   7524 	}
   7525 	break;
   7526 }
   7527 case SCTP_ECN_SUPPORTED:
   7528 {
   7529 	struct sctp_assoc_value *av;
   7530 
   7531 	SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
   7532 	SCTP_FIND_STCB(inp, stcb, av->assoc_id);
   7533 
   7534 	if (stcb) {
   7535 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   7536 		error = EINVAL;
   7537 		SCTP_TCB_UNLOCK(stcb);
   7538 	} else {
   7539 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   7540 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   7541 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   7542 		     (av->assoc_id == SCTP_FUTURE_ASSOC))) {
   7543 			SCTP_INP_WLOCK(inp);
   7544 			if (av->assoc_value == 0) {
   7545 				inp->ecn_supported = 0;
   7546 			} else {
   7547 				inp->ecn_supported = 1;
   7548 			}
   7549 			SCTP_INP_WUNLOCK(inp);
   7550 		} else {
   7551 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   7552 			error = EINVAL;
   7553 		}
   7554 	}
   7555 	break;
   7556 }
   7557 case SCTP_PR_SUPPORTED:
   7558 {
   7559 	struct sctp_assoc_value *av;
   7560 
   7561 	SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
   7562 	SCTP_FIND_STCB(inp, stcb, av->assoc_id);
   7563 
   7564 	if (stcb) {
   7565 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   7566 		error = EINVAL;
   7567 		SCTP_TCB_UNLOCK(stcb);
   7568 	} else {
   7569 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   7570 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   7571 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   7572 		     (av->assoc_id == SCTP_FUTURE_ASSOC))) {
   7573 			SCTP_INP_WLOCK(inp);
   7574 			if (av->assoc_value == 0) {
   7575 				inp->prsctp_supported = 0;
   7576 			} else {
   7577 				inp->prsctp_supported = 1;
   7578 			}
   7579 			SCTP_INP_WUNLOCK(inp);
   7580 		} else {
   7581 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   7582 			error = EINVAL;
   7583 		}
   7584 	}
   7585 	break;
   7586 }
   7587 case SCTP_AUTH_SUPPORTED:
   7588 {
   7589 	struct sctp_assoc_value *av;
   7590 
   7591 	SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
   7592 	SCTP_FIND_STCB(inp, stcb, av->assoc_id);
   7593 
   7594 	if (stcb) {
   7595 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   7596 		error = EINVAL;
   7597 		SCTP_TCB_UNLOCK(stcb);
   7598 	} else {
   7599 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   7600 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   7601 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   7602 		     (av->assoc_id == SCTP_FUTURE_ASSOC))) {
   7603 			if ((av->assoc_value == 0) &&
   7604 			    (inp->asconf_supported == 1)) {
   7605 			    	/* AUTH is required for ASCONF */
   7606 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   7607 				error = EINVAL;
   7608 			} else {
   7609 				SCTP_INP_WLOCK(inp);
   7610 				if (av->assoc_value == 0) {
   7611 					inp->auth_supported = 0;
   7612 				} else {
   7613 					inp->auth_supported = 1;
   7614 				}
   7615 				SCTP_INP_WUNLOCK(inp);
   7616 			}
   7617 		} else {
   7618 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   7619 			error = EINVAL;
   7620 		}
   7621 	}
   7622 	break;
   7623 }
   7624 case SCTP_ASCONF_SUPPORTED:
   7625 {
   7626 	struct sctp_assoc_value *av;
   7627 
   7628 	SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
   7629 	SCTP_FIND_STCB(inp, stcb, av->assoc_id);
   7630 
   7631 	if (stcb) {
   7632 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   7633 		error = EINVAL;
   7634 		SCTP_TCB_UNLOCK(stcb);
   7635 	} else {
   7636 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   7637 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   7638 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   7639 		     (av->assoc_id == SCTP_FUTURE_ASSOC))) {
   7640 			if ((av->assoc_value != 0) &&
   7641 			    (inp->auth_supported == 0)) {
   7642 			    	/* AUTH is required for ASCONF */
   7643 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   7644 				error = EINVAL;
   7645 			} else {
   7646 				SCTP_INP_WLOCK(inp);
   7647 				if (av->assoc_value == 0) {
   7648 					inp->asconf_supported = 0;
   7649 					sctp_auth_delete_chunk(SCTP_ASCONF,
   7650 					                       inp->sctp_ep.local_auth_chunks);
   7651 					sctp_auth_delete_chunk(SCTP_ASCONF_ACK,
   7652 					                       inp->sctp_ep.local_auth_chunks);
   7653 				} else {
   7654 					inp->asconf_supported = 1;
   7655 					sctp_auth_add_chunk(SCTP_ASCONF,
   7656 					                    inp->sctp_ep.local_auth_chunks);
   7657 					sctp_auth_add_chunk(SCTP_ASCONF_ACK,
   7658 					                    inp->sctp_ep.local_auth_chunks);
   7659 				}
   7660 				SCTP_INP_WUNLOCK(inp);
   7661 			}
   7662 		} else {
   7663 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   7664 			error = EINVAL;
   7665 		}
   7666 	}
   7667 	break;
   7668 }
   7669 case SCTP_RECONFIG_SUPPORTED:
   7670 {
   7671 	struct sctp_assoc_value *av;
   7672 
   7673 	SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
   7674 	SCTP_FIND_STCB(inp, stcb, av->assoc_id);
   7675 
   7676 	if (stcb) {
   7677 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   7678 		error = EINVAL;
   7679 		SCTP_TCB_UNLOCK(stcb);
   7680 	} else {
   7681 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   7682 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   7683 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   7684 		     (av->assoc_id == SCTP_FUTURE_ASSOC))) {
   7685 			SCTP_INP_WLOCK(inp);
   7686 			if (av->assoc_value == 0) {
   7687 				inp->reconfig_supported = 0;
   7688 			} else {
   7689 				inp->reconfig_supported = 1;
   7690 			}
   7691 			SCTP_INP_WUNLOCK(inp);
   7692 		} else {
   7693 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   7694 			error = EINVAL;
   7695 		}
   7696 	}
   7697 	break;
   7698 }
   7699 case SCTP_NRSACK_SUPPORTED:
   7700 {
   7701 	struct sctp_assoc_value *av;
   7702 
   7703 	SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
   7704 	SCTP_FIND_STCB(inp, stcb, av->assoc_id);
   7705 
   7706 	if (stcb) {
   7707 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   7708 		error = EINVAL;
   7709 		SCTP_TCB_UNLOCK(stcb);
   7710 	} else {
   7711 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   7712 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   7713 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   7714 		     (av->assoc_id == SCTP_FUTURE_ASSOC))) {
   7715 			SCTP_INP_WLOCK(inp);
   7716 			if (av->assoc_value == 0) {
   7717 				inp->nrsack_supported = 0;
   7718 			} else {
   7719 				inp->nrsack_supported = 1;
   7720 			}
   7721 			SCTP_INP_WUNLOCK(inp);
   7722 		} else {
   7723 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   7724 			error = EINVAL;
   7725 		}
   7726 	}
   7727 	break;
   7728 }
   7729 case SCTP_PKTDROP_SUPPORTED:
   7730 {
   7731 	struct sctp_assoc_value *av;
   7732 
   7733 	SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
   7734 	SCTP_FIND_STCB(inp, stcb, av->assoc_id);
   7735 
   7736 	if (stcb) {
   7737 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   7738 		error = EINVAL;
   7739 		SCTP_TCB_UNLOCK(stcb);
   7740 	} else {
   7741 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   7742 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   7743 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   7744 		     (av->assoc_id == SCTP_FUTURE_ASSOC))) {
   7745 			SCTP_INP_WLOCK(inp);
   7746 			if (av->assoc_value == 0) {
   7747 				inp->pktdrop_supported = 0;
   7748 			} else {
   7749 				inp->pktdrop_supported = 1;
   7750 			}
   7751 			SCTP_INP_WUNLOCK(inp);
   7752 		} else {
   7753 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   7754 			error = EINVAL;
   7755 		}
   7756 	}
   7757 	break;
   7758 }
   7759 case SCTP_MAX_CWND:
   7760 {
   7761 	struct sctp_assoc_value *av;
   7762 	struct sctp_nets *net;
   7763 
   7764 	SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
   7765 	SCTP_FIND_STCB(inp, stcb, av->assoc_id);
   7766 
   7767 	if (stcb) {
   7768 		stcb->asoc.max_cwnd = av->assoc_value;
   7769 		if (stcb->asoc.max_cwnd > 0) {
   7770 			TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
   7771 				if ((net->cwnd > stcb->asoc.max_cwnd) &&
   7772 				    (net->cwnd > (net->mtu - sizeof(struct sctphdr)))) {
   7773 					net->cwnd = stcb->asoc.max_cwnd;
   7774 					if (net->cwnd < (net->mtu - sizeof(struct sctphdr))) {
   7775 						net->cwnd = net->mtu - sizeof(struct sctphdr);
   7776 					}
   7777 				}
   7778 			}
   7779 		}
   7780 		SCTP_TCB_UNLOCK(stcb);
   7781 	} else {
   7782 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   7783 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
   7784 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
   7785 		     (av->assoc_id == SCTP_FUTURE_ASSOC))) {
   7786 			SCTP_INP_WLOCK(inp);
   7787 			inp->max_cwnd = av->assoc_value;
   7788 			SCTP_INP_WUNLOCK(inp);
   7789 		} else {
   7790 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   7791 			error = EINVAL;
   7792 		}
   7793 	}
   7794 	break;
   7795 }
   7796 case SCTP_ACCEPT_ZERO_CHECKSUM:
   7797 {
   7798 	uint32_t *value;
   7799 
   7800 	SCTP_CHECK_AND_CAST(value, optval, uint32_t, optsize);
   7801 	if ((*value == SCTP_EDMID_NONE) ||
   7802 	    (*value == SCTP_EDMID_LOWER_LAYER_DTLS)) {
   7803 		SCTP_INP_WLOCK(inp);
   7804 		inp->rcv_edmid = *value;
   7805 		SCTP_INP_WUNLOCK(inp);
   7806 	} else {
   7807 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   7808 		error = EINVAL;
   7809 	}
   7810 	break;
   7811 }
   7812 
   7813 default:
   7814 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT);
   7815 	error = ENOPROTOOPT;
   7816 	break;
   7817 } /* end switch (opt) */
   7818 return (error);
   7819 }
   7820 
   7821 #if !defined(__Userspace__)
   7822 int
   7823 sctp_ctloutput(struct socket *so, struct sockopt *sopt)
   7824 {
   7825 #if defined(__FreeBSD__)
   7826 struct epoch_tracker et;
   7827 struct sctp_inpcb *inp;
   7828 #endif
   7829 void *optval = NULL;
   7830 void *p;
   7831 size_t optsize = 0;
   7832 int error = 0;
   7833 
   7834 #if defined(__FreeBSD__)
   7835 if ((sopt->sopt_level == SOL_SOCKET) &&
   7836     (sopt->sopt_name == SO_SETFIB)) {
   7837 	inp = (struct sctp_inpcb *)so->so_pcb;
   7838 	if (inp == NULL) {
   7839 		SCTP_LTRACE_ERR_RET(so->so_pcb, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOBUFS);
   7840 		return (EINVAL);
   7841 	}
   7842 	SCTP_INP_WLOCK(inp);
   7843 	inp->fibnum = so->so_fibnum;
   7844 	SCTP_INP_WUNLOCK(inp);
   7845 	return (0);
   7846 }
   7847 #endif
   7848 if (sopt->sopt_level != IPPROTO_SCTP) {
   7849 	/* wrong proto level... send back up to IP */
   7850 #ifdef INET6
   7851 	if (INP_CHECK_SOCKAF(so, AF_INET6))
   7852 		error = ip6_ctloutput(so, sopt);
   7853 #endif				/* INET6 */
   7854 #if defined(INET) && defined(INET6)
   7855 	else
   7856 #endif
   7857 #ifdef INET
   7858 		error = ip_ctloutput(so, sopt);
   7859 #endif
   7860 	return (error);
   7861 }
   7862 optsize = sopt->sopt_valsize;
   7863 if (optsize > SCTP_SOCKET_OPTION_LIMIT) {
   7864 	SCTP_LTRACE_ERR_RET(so->so_pcb, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOBUFS);
   7865 	return (ENOBUFS);
   7866 }
   7867 if (optsize) {
   7868 	SCTP_MALLOC(optval, void *, optsize, SCTP_M_SOCKOPT);
   7869 	if (optval == NULL) {
   7870 		SCTP_LTRACE_ERR_RET(so->so_pcb, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOBUFS);
   7871 		return (ENOBUFS);
   7872 	}
   7873 	error = sooptcopyin(sopt, optval, optsize, optsize);
   7874 	if (error) {
   7875 		SCTP_FREE(optval, SCTP_M_SOCKOPT);
   7876 		goto out;
   7877 	}
   7878 }
   7879 #if defined(__FreeBSD__) || defined(_WIN32)
   7880 p = (void *)sopt->sopt_td;
   7881 #else
   7882 p = (void *)sopt->sopt_p;
   7883 #endif
   7884 if (sopt->sopt_dir == SOPT_SET) {
   7885 #if defined(__FreeBSD__)
   7886 	NET_EPOCH_ENTER(et);
   7887 #endif
   7888 	error = sctp_setopt(so, sopt->sopt_name, optval, optsize, p);
   7889 #if defined(__FreeBSD__)
   7890 	NET_EPOCH_EXIT(et);
   7891 #endif
   7892 } else if (sopt->sopt_dir == SOPT_GET) {
   7893 	error = sctp_getopt(so, sopt->sopt_name, optval, &optsize, p);
   7894 } else {
   7895 	SCTP_LTRACE_ERR_RET(so->so_pcb, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   7896 	error = EINVAL;
   7897 }
   7898 if ((error == 0) && (optval != NULL)) {
   7899 	error = sooptcopyout(sopt, optval, optsize);
   7900 	SCTP_FREE(optval, SCTP_M_SOCKOPT);
   7901 } else if (optval != NULL) {
   7902 	SCTP_FREE(optval, SCTP_M_SOCKOPT);
   7903 }
   7904 out:
   7905 return (error);
   7906 }
   7907 #endif
   7908 
   7909 #ifdef INET
   7910 #if defined(__Userspace__)
   7911 int
   7912 sctp_connect(struct socket *so, struct sockaddr *addr)
   7913 {
   7914 void *p = NULL;
   7915 #elif defined(__FreeBSD__)
   7916 static int
   7917 sctp_connect(struct socket *so, struct sockaddr *addr, struct thread *p)
   7918 {
   7919 #elif defined(__APPLE__)
   7920 static int
   7921 sctp_connect(struct socket *so, struct sockaddr *addr, struct proc *p)
   7922 {
   7923 #elif defined(_WIN32)
   7924 static int
   7925 sctp_connect(struct socket *so, struct sockaddr *addr, PKTHREAD p)
   7926 {
   7927 #else
   7928 static int
   7929 sctp_connect(struct socket *so, struct mbuf *nam, struct proc *p)
   7930 {
   7931 struct sockaddr *addr = mtod(nam, struct sockaddr *);
   7932 
   7933 #endif
   7934 #if defined(__FreeBSD__) && !defined(__Userspace__)
   7935 struct epoch_tracker et;
   7936 #endif
   7937 #ifdef SCTP_MVRF
   7938 int i, fnd = 0;
   7939 #endif
   7940 int error = 0;
   7941 int create_lock_on = 0;
   7942 uint32_t vrf_id;
   7943 struct sctp_inpcb *inp;
   7944 struct sctp_tcb *stcb = NULL;
   7945 
   7946 inp = (struct sctp_inpcb *)so->so_pcb;
   7947 if (inp == NULL) {
   7948 	/* I made the same as TCP since we are not setup? */
   7949 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   7950 	return (ECONNRESET);
   7951 }
   7952 if (addr == NULL) {
   7953 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   7954 	return EINVAL;
   7955 }
   7956 
   7957 #if defined(__Userspace__)
   7958 /* TODO __Userspace__ falls into this code for IPv6 stuff at the moment... */
   7959 #endif
   7960 #if !defined(_WIN32) && !defined(__linux__) && !defined(__EMSCRIPTEN__)
   7961 switch (addr->sa_family) {
   7962 #ifdef INET6
   7963 case AF_INET6:
   7964 {
   7965 #if defined(__FreeBSD__) && !defined(__Userspace__)
   7966 	struct sockaddr_in6 *sin6;
   7967 
   7968 #endif
   7969 	if (addr->sa_len != sizeof(struct sockaddr_in6)) {
   7970 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   7971 		return (EINVAL);
   7972 	}
   7973 #if defined(__FreeBSD__) && !defined(__Userspace__)
   7974 	sin6 = (struct sockaddr_in6 *)addr;
   7975 	if (p != NULL && (error = prison_remote_ip6(p->td_ucred, &sin6->sin6_addr)) != 0) {
   7976 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
   7977 		return (error);
   7978 	}
   7979 #endif
   7980 	break;
   7981 }
   7982 #endif
   7983 #ifdef INET
   7984 case AF_INET:
   7985 {
   7986 #if defined(__FreeBSD__) && !defined(__Userspace__)
   7987 	struct sockaddr_in *sin;
   7988 
   7989 #endif
   7990 #if !defined(_WIN32)
   7991 	if (addr->sa_len != sizeof(struct sockaddr_in)) {
   7992 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   7993 		return (EINVAL);
   7994 	}
   7995 #endif
   7996 #if defined(__FreeBSD__) && !defined(__Userspace__)
   7997 	sin = (struct sockaddr_in *)addr;
   7998 	if (p != NULL && (error = prison_remote_ip4(p->td_ucred, &sin->sin_addr)) != 0) {
   7999 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
   8000 		return (error);
   8001 	}
   8002 #endif
   8003 	break;
   8004 }
   8005 #endif
   8006 default:
   8007 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EAFNOSUPPORT);
   8008 	return (EAFNOSUPPORT);
   8009 }
   8010 #endif
   8011 SCTP_INP_INCR_REF(inp);
   8012 SCTP_ASOC_CREATE_LOCK(inp);
   8013 create_lock_on = 1;
   8014 #if defined(__FreeBSD__) && !defined(__Userspace__)
   8015 NET_EPOCH_ENTER(et);
   8016 #endif
   8017 
   8018 if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
   8019     (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) {
   8020 	/* Should I really unlock ? */
   8021 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EFAULT);
   8022 	error = EFAULT;
   8023 	goto out_now;
   8024 }
   8025 #ifdef INET6
   8026 if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) &&
   8027     (addr->sa_family == AF_INET6)) {
   8028 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   8029 	error = EINVAL;
   8030 	goto out_now;
   8031 }
   8032 #endif
   8033 #if defined(__Userspace__)
   8034 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_CONN) &&
   8035     (addr->sa_family != AF_CONN)) {
   8036 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   8037 	error = EINVAL;
   8038 	goto out_now;
   8039 }
   8040 #endif
   8041 if (inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) {
   8042 	/* Bind a ephemeral port */
   8043 	error = sctp_inpcb_bind(so, NULL, NULL, p);
   8044 	if (error) {
   8045 		goto out_now;
   8046 	}
   8047 }
   8048 /* Now do we connect? */
   8049 if ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) &&
   8050     (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_PORTREUSE))) {
   8051 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   8052 	error = EINVAL;
   8053 	goto out_now;
   8054 }
   8055 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
   8056     (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) {
   8057 	/* We are already connected AND the TCP model */
   8058 	SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EADDRINUSE);
   8059 	error = EADDRINUSE;
   8060 	goto out_now;
   8061 }
   8062 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
   8063 	SCTP_INP_RLOCK(inp);
   8064 	stcb = LIST_FIRST(&inp->sctp_asoc_list);
   8065 	SCTP_INP_RUNLOCK(inp);
   8066 } else {
   8067 	/* We increment here since sctp_findassociation_ep_addr() will
   8068 	 * do a decrement if it finds the stcb as long as the locked
   8069 	 * tcb (last argument) is NOT a TCB.. aka NULL.
   8070 	 */
   8071 	SCTP_INP_INCR_REF(inp);
   8072 	stcb = sctp_findassociation_ep_addr(&inp, addr, NULL, NULL, NULL);
   8073 	if (stcb == NULL) {
   8074 		SCTP_INP_DECR_REF(inp);
   8075 	} else {
   8076 		SCTP_TCB_UNLOCK(stcb);
   8077 	}
   8078 }
   8079 if (stcb != NULL) {
   8080 	/* Already have or am bring up an association */
   8081 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY);
   8082 	error = EALREADY;
   8083 	goto out_now;
   8084 }
   8085 
   8086 vrf_id = inp->def_vrf_id;
   8087 #ifdef SCTP_MVRF
   8088 for (i = 0; i < inp->num_vrfs; i++) {
   8089 	if (vrf_id == inp->m_vrf_ids[i]) {
   8090 		fnd = 1;
   8091 		break;
   8092 	}
   8093 }
   8094 if (!fnd) {
   8095 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   8096 	error = EINVAL;
   8097 	goto out_now;
   8098 }
   8099 #endif
   8100 /* We are GOOD to go */
   8101 stcb = sctp_aloc_assoc_connected(inp, addr, &error, 0, 0, vrf_id,
   8102                                  inp->sctp_ep.pre_open_stream_count,
   8103                                  inp->sctp_ep.port, p,
   8104                                  SCTP_INITIALIZE_AUTH_PARAMS);
   8105 if (stcb == NULL) {
   8106 	/* Gak! no memory */
   8107 	goto out_now;
   8108 }
   8109 SCTP_SET_STATE(stcb, SCTP_STATE_COOKIE_WAIT);
   8110 (void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered);
   8111 
   8112 sctp_send_initiate(inp, stcb, SCTP_SO_LOCKED);
   8113 SCTP_TCB_UNLOCK(stcb);
   8114 out_now:
   8115 #if defined(__FreeBSD__) && !defined(__Userspace__)
   8116 NET_EPOCH_EXIT(et);
   8117 #endif
   8118 if (create_lock_on) {
   8119 	SCTP_ASOC_CREATE_UNLOCK(inp);
   8120 }
   8121 SCTP_INP_DECR_REF(inp);
   8122 return (error);
   8123 }
   8124 #endif
   8125 
   8126 #if defined(__Userspace__)
   8127 int
   8128 sctpconn_connect(struct socket *so, struct sockaddr *addr)
   8129 {
   8130 #ifdef SCTP_MVRF
   8131 int i, fnd = 0;
   8132 #endif
   8133 void *p = NULL;
   8134 int error = 0;
   8135 int create_lock_on = 0;
   8136 uint32_t vrf_id;
   8137 struct sctp_inpcb *inp;
   8138 struct sctp_tcb *stcb = NULL;
   8139 
   8140 inp = (struct sctp_inpcb *)so->so_pcb;
   8141 if (inp == NULL) {
   8142 	/* I made the same as TCP since we are not setup? */
   8143 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   8144 	return (ECONNRESET);
   8145 }
   8146 if (addr == NULL) {
   8147 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   8148 	return EINVAL;
   8149 }
   8150 switch (addr->sa_family) {
   8151 #ifdef INET
   8152 case AF_INET:
   8153 #ifdef HAVE_SA_LEN
   8154 	if (addr->sa_len != sizeof(struct sockaddr_in)) {
   8155 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   8156 		return (EINVAL);
   8157 	}
   8158 #endif
   8159 	break;
   8160 #endif
   8161 #ifdef INET6
   8162 case AF_INET6:
   8163 #ifdef HAVE_SA_LEN
   8164 	if (addr->sa_len != sizeof(struct sockaddr_in6)) {
   8165 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   8166 		return (EINVAL);
   8167 	}
   8168 #endif
   8169 	break;
   8170 #endif
   8171 case AF_CONN:
   8172 #ifdef HAVE_SA_LEN
   8173 	if (addr->sa_len != sizeof(struct sockaddr_conn)) {
   8174 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   8175 		return (EINVAL);
   8176 	}
   8177 #endif
   8178 	break;
   8179 default:
   8180 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EAFNOSUPPORT);
   8181 	return (EAFNOSUPPORT);
   8182 }
   8183 SCTP_INP_INCR_REF(inp);
   8184 SCTP_ASOC_CREATE_LOCK(inp);
   8185 create_lock_on = 1;
   8186 
   8187 
   8188 if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
   8189     (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) {
   8190 	/* Should I really unlock ? */
   8191 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EFAULT);
   8192         error = EFAULT;
   8193 	goto out_now;
   8194 }
   8195 #ifdef INET6
   8196 if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) &&
   8197     (addr->sa_family == AF_INET6)) {
   8198 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   8199 	error = EINVAL;
   8200 	goto out_now;
   8201 }
   8202 #endif
   8203 if (inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) {
   8204 	/* Bind a ephemeral port */
   8205 	error = sctp_inpcb_bind(so, NULL, NULL, p);
   8206 	if (error) {
   8207 		goto out_now;
   8208 	}
   8209 }
   8210 /* Now do we connect? */
   8211 if ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) &&
   8212     (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_PORTREUSE))) {
   8213 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   8214 	error = EINVAL;
   8215 	goto out_now;
   8216 }
   8217 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
   8218     (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) {
   8219 	/* We are already connected AND the TCP model */
   8220 	SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EADDRINUSE);
   8221 	error = EADDRINUSE;
   8222 	goto out_now;
   8223 }
   8224 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
   8225 	SCTP_INP_RLOCK(inp);
   8226 	stcb = LIST_FIRST(&inp->sctp_asoc_list);
   8227 	SCTP_INP_RUNLOCK(inp);
   8228 } else {
   8229 	/* We increment here since sctp_findassociation_ep_addr() will
   8230 	 * do a decrement if it finds the stcb as long as the locked
   8231 	 * tcb (last argument) is NOT a TCB.. aka NULL.
   8232 	 */
   8233 	SCTP_INP_INCR_REF(inp);
   8234 	stcb = sctp_findassociation_ep_addr(&inp, addr, NULL, NULL, NULL);
   8235 	if (stcb == NULL) {
   8236 		SCTP_INP_DECR_REF(inp);
   8237 	} else {
   8238 		SCTP_TCB_UNLOCK(stcb);
   8239 	}
   8240 }
   8241 if (stcb != NULL) {
   8242 	/* Already have or am bring up an association */
   8243 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY);
   8244 	error = EALREADY;
   8245 	goto out_now;
   8246 }
   8247 
   8248 vrf_id = inp->def_vrf_id;
   8249 #ifdef SCTP_MVRF
   8250 for (i = 0; i < inp->num_vrfs; i++) {
   8251 	if (vrf_id == inp->m_vrf_ids[i]) {
   8252 		fnd = 1;
   8253 		break;
   8254 	}
   8255 }
   8256 if (!fnd) {
   8257 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   8258 	error = EINVAL;
   8259 	goto out_now;
   8260 }
   8261 #endif
   8262 /* We are GOOD to go */
   8263 stcb = sctp_aloc_assoc_connected(inp, addr, &error, 0, 0, vrf_id,
   8264                                  inp->sctp_ep.pre_open_stream_count,
   8265                                  inp->sctp_ep.port, p,
   8266                                  SCTP_INITIALIZE_AUTH_PARAMS);
   8267 if (stcb == NULL) {
   8268 	/* Gak! no memory */
   8269 	goto out_now;
   8270 }
   8271 SCTP_SET_STATE(stcb, SCTP_STATE_COOKIE_WAIT);
   8272 (void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered);
   8273 
   8274 sctp_send_initiate(inp, stcb, SCTP_SO_LOCKED);
   8275 SCTP_TCB_UNLOCK(stcb);
   8276 out_now:
   8277 if (create_lock_on) {
   8278 	SCTP_ASOC_CREATE_UNLOCK(inp);
   8279 }
   8280 
   8281 SCTP_INP_DECR_REF(inp);
   8282 return (error);
   8283 }
   8284 #endif
   8285 int
   8286 #if defined(__Userspace__)
   8287 sctp_listen(struct socket *so, int backlog, struct proc *p)
   8288 #elif defined(__FreeBSD__)
   8289 sctp_listen(struct socket *so, int backlog, struct thread *p)
   8290 #elif defined(_WIN32)
   8291 sctp_listen(struct socket *so, int backlog, PKTHREAD p)
   8292 #else
   8293 sctp_listen(struct socket *so, struct proc *p)
   8294 #endif
   8295 {
   8296 /*
   8297  * Note this module depends on the protocol processing being called
   8298  * AFTER any socket level flags and backlog are applied to the
   8299  * socket. The traditional way that the socket flags are applied is
   8300  * AFTER protocol processing. We have made a change to the
   8301  * sys/kern/uipc_socket.c module to reverse this but this MUST be in
   8302  * place if the socket API for SCTP is to work properly.
   8303  */
   8304 
   8305 int error = 0;
   8306 struct sctp_inpcb *inp;
   8307 
   8308 inp = (struct sctp_inpcb *)so->so_pcb;
   8309 if (inp == NULL) {
   8310 	/* I made the same as TCP since we are not setup? */
   8311 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   8312 	return (ECONNRESET);
   8313 }
   8314 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE)) {
   8315 	/* See if we have a listener */
   8316 	struct sctp_inpcb *tinp;
   8317 	union sctp_sockstore store;
   8318 
   8319 	if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) {
   8320 		/* not bound all */
   8321 		struct sctp_laddr *laddr;
   8322 
   8323 		LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
   8324 			memcpy(&store, &laddr->ifa->address, sizeof(store));
   8325 			switch (store.sa.sa_family) {
   8326 #ifdef INET
   8327 			case AF_INET:
   8328 				store.sin.sin_port = inp->sctp_lport;
   8329 				break;
   8330 #endif
   8331 #ifdef INET6
   8332 			case AF_INET6:
   8333 				store.sin6.sin6_port = inp->sctp_lport;
   8334 				break;
   8335 #endif
   8336 #if defined(__Userspace__)
   8337 			case AF_CONN:
   8338 				store.sconn.sconn_port = inp->sctp_lport;
   8339 				break;
   8340 #endif
   8341 			default:
   8342 				break;
   8343 			}
   8344 			tinp = sctp_pcb_findep(&store.sa, 0, 0, inp->def_vrf_id);
   8345 			if (tinp && (tinp != inp) &&
   8346 			    ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) == 0) &&
   8347 			    ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
   8348 			    (SCTP_IS_LISTENING(tinp))) {
   8349 				/* we have a listener already and its not this inp. */
   8350 				SCTP_INP_DECR_REF(tinp);
   8351 				return (EADDRINUSE);
   8352 			} else if (tinp) {
   8353 				SCTP_INP_DECR_REF(tinp);
   8354 			}
   8355 		}
   8356 	} else {
   8357 		/* Setup a local addr bound all */
   8358 		memset(&store, 0, sizeof(store));
   8359 #ifdef INET6
   8360 		if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
   8361 			store.sa.sa_family = AF_INET6;
   8362 #ifdef HAVE_SA_LEN
   8363 			store.sa.sa_len = sizeof(struct sockaddr_in6);
   8364 #endif
   8365 		}
   8366 #endif
   8367 #if defined(__Userspace__)
   8368 		if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_CONN) {
   8369 			store.sa.sa_family = AF_CONN;
   8370 #ifdef HAVE_SA_LEN
   8371 			store.sa.sa_len = sizeof(struct sockaddr_conn);
   8372 #endif
   8373 		}
   8374 #endif
   8375 #ifdef INET
   8376 #if defined(__Userspace__)
   8377 		if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) &&
   8378 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_CONN) == 0)) {
   8379 #else
   8380 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
   8381 #endif
   8382 			store.sa.sa_family = AF_INET;
   8383 #ifdef HAVE_SA_LEN
   8384 			store.sa.sa_len = sizeof(struct sockaddr_in);
   8385 #endif
   8386 		}
   8387 #endif
   8388 		switch (store.sa.sa_family) {
   8389 #ifdef INET
   8390 		case AF_INET:
   8391 			store.sin.sin_port = inp->sctp_lport;
   8392 			break;
   8393 #endif
   8394 #ifdef INET6
   8395 		case AF_INET6:
   8396 			store.sin6.sin6_port = inp->sctp_lport;
   8397 			break;
   8398 #endif
   8399 #if defined(__Userspace__)
   8400 		case AF_CONN:
   8401 			store.sconn.sconn_port = inp->sctp_lport;
   8402 			break;
   8403 #endif
   8404 		default:
   8405 			break;
   8406 		}
   8407 		tinp = sctp_pcb_findep(&store.sa, 0, 0, inp->def_vrf_id);
   8408 		if (tinp && (tinp != inp) &&
   8409 		    ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) == 0) &&
   8410 		    ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
   8411 		    (SCTP_IS_LISTENING(tinp))) {
   8412 			/* we have a listener already and its not this inp. */
   8413 			SCTP_INP_DECR_REF(tinp);
   8414 			return (EADDRINUSE);
   8415 		} else if (tinp) {
   8416 			SCTP_INP_DECR_REF(tinp);
   8417 		}
   8418 	}
   8419 }
   8420 SCTP_INP_INFO_WLOCK();
   8421 SCTP_INP_WLOCK(inp);
   8422 #ifdef SCTP_LOCK_LOGGING
   8423 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) {
   8424 	sctp_log_lock(inp, (struct sctp_tcb *)NULL, SCTP_LOG_LOCK_SOCK);
   8425 }
   8426 #endif
   8427 if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE)) &&
   8428     (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
   8429 	/* The unlucky case
   8430 	 * - We are in the tcp pool with this guy.
   8431 	 * - Someone else is in the main inp slot.
   8432 	 * - We must move this guy (the listener) to the main slot
   8433 	 * - We must then move the guy that was listener to the TCP Pool.
   8434 	 */
   8435 	if (sctp_swap_inpcb_for_listen(inp)) {
   8436 		error = EADDRINUSE;
   8437 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
   8438 		goto out;
   8439 	}
   8440 }
   8441 #if defined(__FreeBSD__) || defined(__Userspace__)
   8442 SOCK_LOCK(so);
   8443 error = solisten_proto_check(so);
   8444 if (error) {
   8445 	SOCK_UNLOCK(so);
   8446 	goto out;
   8447 }
   8448 #endif
   8449 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
   8450     (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) {
   8451 	SOCK_UNLOCK(so);
   8452 #if defined(__FreeBSD__) && !defined(__Userspace__)
   8453 	solisten_proto_abort(so);
   8454 #endif
   8455 	error = EADDRINUSE;
   8456 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
   8457 	goto out;
   8458 }
   8459 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
   8460     ((inp->sctp_flags & SCTP_PCB_FLAGS_WAS_CONNECTED) ||
   8461      (inp->sctp_flags & SCTP_PCB_FLAGS_WAS_ABORTED))) {
   8462 	SOCK_UNLOCK(so);
   8463 #if defined(__FreeBSD__) && !defined(__Userspace__)
   8464 	solisten_proto_abort(so);
   8465 #endif
   8466 	error = EINVAL;
   8467 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
   8468 	goto out;
   8469 }
   8470 if (inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) {
   8471 	if ((error = sctp_inpcb_bind_locked(inp, NULL, NULL, p))) {
   8472 		SOCK_UNLOCK(so);
   8473 #if defined(__FreeBSD__) && !defined(__Userspace__)
   8474 		solisten_proto_abort(so);
   8475 #endif
   8476 		/* bind error, probably perm */
   8477 		goto out;
   8478 	}
   8479 }
   8480 #if defined(__FreeBSD__) && !defined(__Userspace__)
   8481 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) == 0) {
   8482 	solisten_proto(so, backlog);
   8483 	SOCK_UNLOCK(so);
   8484 	inp->sctp_flags |= SCTP_PCB_FLAGS_ACCEPTING;
   8485 } else {
   8486 	solisten_proto_abort(so);
   8487 	SOCK_UNLOCK(so);
   8488 	if (backlog > 0) {
   8489 		inp->sctp_flags |= SCTP_PCB_FLAGS_ACCEPTING;
   8490 	} else {
   8491 		inp->sctp_flags &= ~SCTP_PCB_FLAGS_ACCEPTING;
   8492 	}
   8493 }
   8494 #elif defined(_WIN32) || defined(__Userspace__)
   8495 solisten_proto(so, backlog);
   8496 #endif
   8497 #if !(defined(__FreeBSD__) && !defined(__Userspace__))
   8498 if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) {
   8499 	/* remove the ACCEPTCONN flag for one-to-many sockets */
   8500 #if defined(__Userspace__)
   8501 	so->so_options &= ~SCTP_SO_ACCEPTCONN;
   8502 #else
   8503 	so->so_options &= ~SO_ACCEPTCONN;
   8504 #endif
   8505 }
   8506 SOCK_UNLOCK(so);
   8507 if (backlog > 0) {
   8508 	inp->sctp_flags |= SCTP_PCB_FLAGS_ACCEPTING;
   8509 } else {
   8510 	inp->sctp_flags &= ~SCTP_PCB_FLAGS_ACCEPTING;
   8511 }
   8512 #endif
   8513 out:
   8514 SCTP_INP_WUNLOCK(inp);
   8515 SCTP_INP_INFO_WUNLOCK();
   8516 return (error);
   8517 }
   8518 
   8519 static int sctp_defered_wakeup_cnt = 0;
   8520 
   8521 int
   8522 sctp_accept(struct socket *so, struct sockaddr **addr)
   8523 {
   8524 struct sctp_tcb *stcb;
   8525 struct sctp_inpcb *inp;
   8526 union sctp_sockstore store;
   8527 #ifdef INET6
   8528 #if defined(SCTP_KAME) && defined(SCTP_EMBEDDED_V6_SCOPE)
   8529 int error;
   8530 #endif
   8531 #endif
   8532 inp = (struct sctp_inpcb *)so->so_pcb;
   8533 
   8534 if (inp == NULL) {
   8535 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   8536 	return (ECONNRESET);
   8537 }
   8538 SCTP_INP_WLOCK(inp);
   8539 if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) {
   8540 	SCTP_INP_WUNLOCK(inp);
   8541 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP);
   8542 	return (EOPNOTSUPP);
   8543 }
   8544 if (so->so_state & SS_ISDISCONNECTED) {
   8545 	SCTP_INP_WUNLOCK(inp);
   8546 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ECONNABORTED);
   8547 	return (ECONNABORTED);
   8548 }
   8549 stcb = LIST_FIRST(&inp->sctp_asoc_list);
   8550 if (stcb == NULL) {
   8551 	SCTP_INP_WUNLOCK(inp);
   8552 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   8553 	return (ECONNRESET);
   8554 }
   8555 SCTP_TCB_LOCK(stcb);
   8556 store = stcb->asoc.primary_destination->ro._l_addr;
   8557 SCTP_CLEAR_SUBSTATE(stcb, SCTP_STATE_IN_ACCEPT_QUEUE);
   8558 /* Wake any delayed sleep action */
   8559 if (inp->sctp_flags & SCTP_PCB_FLAGS_DONT_WAKE) {
   8560 	inp->sctp_flags &= ~SCTP_PCB_FLAGS_DONT_WAKE;
   8561 	if (inp->sctp_flags & SCTP_PCB_FLAGS_WAKEOUTPUT) {
   8562 		inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEOUTPUT;
   8563 		SOCKBUF_LOCK(&inp->sctp_socket->so_snd);
   8564 		if (sowriteable(inp->sctp_socket)) {
   8565 #if defined(__Userspace__)
   8566 			/*__Userspace__ calling sowwakup_locked because of SOCKBUF_LOCK above. */
   8567 #endif
   8568 #if defined(__FreeBSD__) || defined(_WIN32) || defined(__Userspace__)
   8569 			sowwakeup_locked(inp->sctp_socket);
   8570 #else
   8571 #if defined(__APPLE__)
   8572 			/* socket is locked */
   8573 #endif
   8574 			sowwakeup(inp->sctp_socket);
   8575 #endif
   8576 		} else {
   8577 			SOCKBUF_UNLOCK(&inp->sctp_socket->so_snd);
   8578 		}
   8579 	}
   8580 	if (inp->sctp_flags & SCTP_PCB_FLAGS_WAKEINPUT) {
   8581 		inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEINPUT;
   8582 		SOCKBUF_LOCK(&inp->sctp_socket->so_rcv);
   8583 		if (soreadable(inp->sctp_socket)) {
   8584 			sctp_defered_wakeup_cnt++;
   8585 #if defined(__Userspace__)
   8586 			/*__Userspace__ calling sorwakup_locked because of SOCKBUF_LOCK above */
   8587 #endif
   8588 #if defined(__FreeBSD__) || defined(_WIN32) || defined(__Userspace__)
   8589 			sorwakeup_locked(inp->sctp_socket);
   8590 #else
   8591 #if defined(__APPLE__)
   8592 			/* socket is locked */
   8593 #endif
   8594 			sorwakeup(inp->sctp_socket);
   8595 #endif
   8596 		} else {
   8597 			SOCKBUF_UNLOCK(&inp->sctp_socket->so_rcv);
   8598 		}
   8599 	}
   8600 }
   8601 SCTP_INP_WUNLOCK(inp);
   8602 if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
   8603 	sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
   8604 	                SCTP_FROM_SCTP_USRREQ + SCTP_LOC_19);
   8605 } else {
   8606 	SCTP_TCB_UNLOCK(stcb);
   8607 }
   8608 switch (store.sa.sa_family) {
   8609 #ifdef INET
   8610 case AF_INET:
   8611 {
   8612 	struct sockaddr_in *sin;
   8613 
   8614 	SCTP_MALLOC_SONAME(sin, struct sockaddr_in *, sizeof *sin);
   8615 	if (sin == NULL)
   8616 		return (ENOMEM);
   8617 	sin->sin_family = AF_INET;
   8618 #ifdef HAVE_SIN_LEN
   8619 	sin->sin_len = sizeof(*sin);
   8620 #endif
   8621 	sin->sin_port = store.sin.sin_port;
   8622 	sin->sin_addr = store.sin.sin_addr;
   8623 	*addr = (struct sockaddr *)sin;
   8624 	break;
   8625 }
   8626 #endif
   8627 #ifdef INET6
   8628 case AF_INET6:
   8629 {
   8630 	struct sockaddr_in6 *sin6;
   8631 
   8632 	SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof *sin6);
   8633 	if (sin6 == NULL)
   8634 		return (ENOMEM);
   8635 	sin6->sin6_family = AF_INET6;
   8636 #ifdef HAVE_SIN6_LEN
   8637 	sin6->sin6_len = sizeof(*sin6);
   8638 #endif
   8639 	sin6->sin6_port = store.sin6.sin6_port;
   8640 	sin6->sin6_addr = store.sin6.sin6_addr;
   8641 #if defined(SCTP_EMBEDDED_V6_SCOPE)
   8642 #ifdef SCTP_KAME
   8643 	if ((error = sa6_recoverscope(sin6)) != 0) {
   8644 		SCTP_FREE_SONAME(sin6);
   8645 		return (error);
   8646 	}
   8647 #else
   8648 	if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr))
   8649 		/*
   8650 		 * sin6->sin6_scope_id =
   8651 		 * ntohs(sin6->sin6_addr.s6_addr16[1]);
   8652 		 */
   8653 		in6_recoverscope(sin6, &sin6->sin6_addr, NULL);	/* skip ifp check */
   8654 	else
   8655 		sin6->sin6_scope_id = 0;	/* XXX */
   8656 #endif /* SCTP_KAME */
   8657 #endif /* SCTP_EMBEDDED_V6_SCOPE */
   8658 	*addr = (struct sockaddr *)sin6;
   8659 	break;
   8660 }
   8661 #endif
   8662 #if defined(__Userspace__)
   8663 case AF_CONN:
   8664 {
   8665 	struct sockaddr_conn *sconn;
   8666 
   8667 	SCTP_MALLOC_SONAME(sconn, struct sockaddr_conn *, sizeof(struct sockaddr_conn));
   8668 	if (sconn == NULL) {
   8669 		return (ENOMEM);
   8670 	}
   8671 	sconn->sconn_family = AF_CONN;
   8672 #ifdef HAVE_SCONN_LEN
   8673 	sconn->sconn_len = sizeof(struct sockaddr_conn);
   8674 #endif
   8675 	sconn->sconn_port = store.sconn.sconn_port;
   8676 	sconn->sconn_addr = store.sconn.sconn_addr;
   8677 	*addr = (struct sockaddr *)sconn;
   8678 	break;
   8679 }
   8680 #endif
   8681 default:
   8682 	/* TSNH */
   8683 	break;
   8684 }
   8685 return (0);
   8686 }
   8687 
   8688 #ifdef INET
   8689 int
   8690 #if !defined(__Userspace__)
   8691 sctp_ingetaddr(struct socket *so, struct sockaddr **addr)
   8692 {
   8693 struct sockaddr_in *sin;
   8694 #else
   8695 sctp_ingetaddr(struct socket *so, struct mbuf *nam)
   8696 {
   8697 struct sockaddr_in *sin = mtod(nam, struct sockaddr_in *);
   8698 #endif
   8699 uint32_t vrf_id;
   8700 struct sctp_inpcb *inp;
   8701 struct sctp_ifa *sctp_ifa;
   8702 
   8703 /*
   8704  * Do the malloc first in case it blocks.
   8705  */
   8706 #if !defined(__Userspace__)
   8707 SCTP_MALLOC_SONAME(sin, struct sockaddr_in *, sizeof *sin);
   8708 if (sin == NULL)
   8709 	return (ENOMEM);
   8710 #else
   8711 SCTP_BUF_LEN(nam) = sizeof(*sin);
   8712 memset(sin, 0, sizeof(*sin));
   8713 #endif
   8714 sin->sin_family = AF_INET;
   8715 #ifdef HAVE_SIN_LEN
   8716 sin->sin_len = sizeof(*sin);
   8717 #endif
   8718 inp = (struct sctp_inpcb *)so->so_pcb;
   8719 if (!inp) {
   8720 #if !defined(__Userspace__)
   8721 	SCTP_FREE_SONAME(sin);
   8722 #endif
   8723 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   8724 	return (ECONNRESET);
   8725 }
   8726 SCTP_INP_RLOCK(inp);
   8727 sin->sin_port = inp->sctp_lport;
   8728 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
   8729 	if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
   8730 		struct sctp_tcb *stcb;
   8731 		struct sockaddr_in *sin_a;
   8732 		struct sctp_nets *net;
   8733 		int fnd;
   8734 
   8735 		stcb = LIST_FIRST(&inp->sctp_asoc_list);
   8736 		if (stcb == NULL) {
   8737 			goto notConn;
   8738 		}
   8739 		fnd = 0;
   8740 		sin_a = NULL;
   8741 		SCTP_TCB_LOCK(stcb);
   8742 		TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
   8743 			sin_a = (struct sockaddr_in *)&net->ro._l_addr;
   8744 			if (sin_a == NULL)
   8745 				/* this will make coverity happy */
   8746 				continue;
   8747 
   8748 			if (sin_a->sin_family == AF_INET) {
   8749 				fnd = 1;
   8750 				break;
   8751 			}
   8752 		}
   8753 		if ((!fnd) || (sin_a == NULL)) {
   8754 			/* punt */
   8755 			SCTP_TCB_UNLOCK(stcb);
   8756 			goto notConn;
   8757 		}
   8758 
   8759 		vrf_id = inp->def_vrf_id;
   8760 		sctp_ifa = sctp_source_address_selection(inp,
   8761 							 stcb,
   8762 							 (sctp_route_t *)&net->ro,
   8763 							 net, 0, vrf_id);
   8764 		if (sctp_ifa) {
   8765 			sin->sin_addr = sctp_ifa->address.sin.sin_addr;
   8766 			sctp_free_ifa(sctp_ifa);
   8767 		}
   8768 		SCTP_TCB_UNLOCK(stcb);
   8769 	} else {
   8770 		/* For the bound all case you get back 0 */
   8771 notConn:
   8772 		sin->sin_addr.s_addr = 0;
   8773 	}
   8774 
   8775 } else {
   8776 	/* Take the first IPv4 address in the list */
   8777 	struct sctp_laddr *laddr;
   8778 	int fnd = 0;
   8779 
   8780 	LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
   8781 		if (laddr->ifa->address.sa.sa_family == AF_INET) {
   8782 			struct sockaddr_in *sin_a;
   8783 
   8784 			sin_a = &laddr->ifa->address.sin;
   8785 			sin->sin_addr = sin_a->sin_addr;
   8786 			fnd = 1;
   8787 			break;
   8788 		}
   8789 	}
   8790 	if (!fnd) {
   8791 #if !defined(__Userspace__)
   8792 		SCTP_FREE_SONAME(sin);
   8793 #endif
   8794 		SCTP_INP_RUNLOCK(inp);
   8795 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT);
   8796 		return (ENOENT);
   8797 	}
   8798 }
   8799 SCTP_INP_RUNLOCK(inp);
   8800 #if !defined(__Userspace__)
   8801 (*addr) = (struct sockaddr *)sin;
   8802 #endif
   8803 return (0);
   8804 }
   8805 
   8806 int
   8807 #if !defined(__Userspace__)
   8808 sctp_peeraddr(struct socket *so, struct sockaddr **addr)
   8809 {
   8810 struct sockaddr_in *sin;
   8811 #else
   8812 sctp_peeraddr(struct socket *so, struct mbuf *nam)
   8813 {
   8814 struct sockaddr_in *sin = mtod(nam, struct sockaddr_in *);
   8815 
   8816 #endif
   8817 int fnd;
   8818 struct sockaddr_in *sin_a;
   8819 struct sctp_inpcb *inp;
   8820 struct sctp_tcb *stcb;
   8821 struct sctp_nets *net;
   8822 
   8823 /* Do the malloc first in case it blocks. */
   8824 #if !defined(__Userspace__)
   8825 SCTP_MALLOC_SONAME(sin, struct sockaddr_in *, sizeof *sin);
   8826 if (sin == NULL)
   8827 	return (ENOMEM);
   8828 #else
   8829 SCTP_BUF_LEN(nam) = sizeof(*sin);
   8830 memset(sin, 0, sizeof(*sin));
   8831 #endif
   8832 sin->sin_family = AF_INET;
   8833 #ifdef HAVE_SIN_LEN
   8834 sin->sin_len = sizeof(*sin);
   8835 #endif
   8836 
   8837 inp = (struct sctp_inpcb *)so->so_pcb;
   8838 if ((inp == NULL) ||
   8839     ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)) {
   8840 	/* UDP type and listeners will drop out here */
   8841 #if !defined(__Userspace__)
   8842 	SCTP_FREE_SONAME(sin);
   8843 #endif
   8844 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTCONN);
   8845 	return (ENOTCONN);
   8846 }
   8847 SCTP_INP_RLOCK(inp);
   8848 stcb = LIST_FIRST(&inp->sctp_asoc_list);
   8849 if (stcb) {
   8850 	SCTP_TCB_LOCK(stcb);
   8851 }
   8852 SCTP_INP_RUNLOCK(inp);
   8853 if (stcb == NULL) {
   8854 #if !defined(__Userspace__)
   8855 	SCTP_FREE_SONAME(sin);
   8856 #endif
   8857 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
   8858 	return (ECONNRESET);
   8859 }
   8860 fnd = 0;
   8861 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
   8862 	sin_a = (struct sockaddr_in *)&net->ro._l_addr;
   8863 	if (sin_a->sin_family == AF_INET) {
   8864 		fnd = 1;
   8865 		sin->sin_port = stcb->rport;
   8866 		sin->sin_addr = sin_a->sin_addr;
   8867 		break;
   8868 	}
   8869 }
   8870 SCTP_TCB_UNLOCK(stcb);
   8871 if (!fnd) {
   8872 	/* No IPv4 address */
   8873 #if !defined(__Userspace__)
   8874 	SCTP_FREE_SONAME(sin);
   8875 #endif
   8876 	SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT);
   8877 	return (ENOENT);
   8878 }
   8879 #if !defined(__Userspace__)
   8880 (*addr) = (struct sockaddr *)sin;
   8881 #endif
   8882 return (0);
   8883 }
   8884 
   8885 #if !defined(__Userspace__)
   8886 #if defined(__FreeBSD__)
   8887 #define	SCTP_PROTOSW						\
   8888 .pr_protocol =	IPPROTO_SCTP,				\
   8889 .pr_ctloutput =	sctp_ctloutput,				\
   8890 .pr_abort =	sctp_abort,				\
   8891 .pr_accept =	sctp_accept,				\
   8892 .pr_attach =	sctp_attach,				\
   8893 .pr_bind =	sctp_bind,				\
   8894 .pr_connect =	sctp_connect,				\
   8895 .pr_control =	in_control,				\
   8896 .pr_close =	sctp_close,				\
   8897 .pr_detach =	sctp_close,				\
   8898 .pr_sopoll =	sopoll_generic,				\
   8899 .pr_flush =	sctp_flush,				\
   8900 .pr_disconnect = sctp_disconnect,			\
   8901 .pr_listen =	sctp_listen,				\
   8902 .pr_peeraddr =	sctp_peeraddr,				\
   8903 .pr_send =	sctp_sendm,				\
   8904 .pr_shutdown =	sctp_shutdown,				\
   8905 .pr_sockaddr =	sctp_ingetaddr,				\
   8906 .pr_sosend =	sctp_sosend,				\
   8907 .pr_soreceive =	sctp_soreceive				\
   8908 
   8909 struct protosw sctp_seqpacket_protosw = {
   8910 .pr_type =	SOCK_SEQPACKET,
   8911 .pr_flags =	PR_WANTRCVD,
   8912 SCTP_PROTOSW
   8913 };
   8914 
   8915 struct protosw sctp_stream_protosw = {
   8916 .pr_type =      SOCK_STREAM,
   8917 .pr_flags =	PR_CONNREQUIRED | PR_WANTRCVD,
   8918 SCTP_PROTOSW
   8919 };
   8920 #else
   8921 struct pr_usrreqs sctp_usrreqs = {
   8922 #if defined(__APPLE__)
   8923 .pru_abort = sctp_abort,
   8924 .pru_accept = sctp_accept,
   8925 .pru_attach = sctp_attach,
   8926 .pru_bind = sctp_bind,
   8927 .pru_connect = sctp_connect,
   8928 .pru_connect2 = pru_connect2_notsupp,
   8929 .pru_control = in_control,
   8930 .pru_detach = sctp_detach,
   8931 .pru_disconnect = sctp_disconnect,
   8932 .pru_listen = sctp_listen,
   8933 .pru_peeraddr = sctp_peeraddr,
   8934 .pru_rcvd = NULL,
   8935 .pru_rcvoob = pru_rcvoob_notsupp,
   8936 .pru_send = sctp_sendm,
   8937 .pru_sense = pru_sense_null,
   8938 .pru_shutdown = sctp_shutdown,
   8939 .pru_sockaddr = sctp_ingetaddr,
   8940 .pru_sosend = sctp_sosend,
   8941 .pru_soreceive = sctp_soreceive,
   8942 .pru_sopoll = sopoll
   8943 #elif defined(_WIN32) && !defined(__Userspace__)
   8944 sctp_abort,
   8945 sctp_accept,
   8946 sctp_attach,
   8947 sctp_bind,
   8948 sctp_connect,
   8949 pru_connect2_notsupp,
   8950 NULL,
   8951 NULL,
   8952 sctp_disconnect,
   8953 sctp_listen,
   8954 sctp_peeraddr,
   8955 NULL,
   8956 pru_rcvoob_notsupp,
   8957 NULL,
   8958 pru_sense_null,
   8959 sctp_shutdown,
   8960 sctp_flush,
   8961 sctp_ingetaddr,
   8962 sctp_sosend,
   8963 sctp_soreceive,
   8964 sopoll_generic,
   8965 NULL,
   8966 sctp_close
   8967 #endif
   8968 };
   8969 #endif
   8970 #endif
   8971 #endif
   8972 
   8973 #if defined(__Userspace__)
   8974 int
   8975 register_recv_cb(struct socket *so,
   8976                 int (*receive_cb)(struct socket *sock, union sctp_sockstore addr, void *data,
   8977                 size_t datalen, struct sctp_rcvinfo, int flags, void *ulp_info))
   8978 {
   8979 struct sctp_inpcb *inp;
   8980 
   8981 inp = (struct sctp_inpcb *) so->so_pcb;
   8982 if (inp == NULL) {
   8983 	return (0);
   8984 }
   8985 SCTP_INP_WLOCK(inp);
   8986 inp->recv_callback = receive_cb;
   8987 SCTP_INP_WUNLOCK(inp);
   8988 return (1);
   8989 }
   8990 
   8991 int
   8992 register_send_cb(struct socket *so, uint32_t sb_threshold, int (*send_cb)(struct socket *sock, uint32_t sb_free, void *ulp_info))
   8993 {
   8994 struct sctp_inpcb *inp;
   8995 
   8996 inp = (struct sctp_inpcb *) so->so_pcb;
   8997 if (inp == NULL) {
   8998 	return (0);
   8999 }
   9000 SCTP_INP_WLOCK(inp);
   9001 inp->send_callback = send_cb;
   9002 inp->send_sb_threshold = sb_threshold;
   9003 SCTP_INP_WUNLOCK(inp);
   9004 /* FIXME change to current amount free. This will be the full buffer
   9005  * the first time this is registered but it could be only a portion
   9006  * of the send buffer if this is called a second time e.g. if the
   9007  * threshold changes.
   9008  */
   9009 return (1);
   9010 }
   9011 
   9012 int
   9013 register_ulp_info (struct socket *so, void *ulp_info)
   9014 {
   9015 struct sctp_inpcb *inp;
   9016 
   9017 inp = (struct sctp_inpcb *) so->so_pcb;
   9018 if (inp == NULL) {
   9019 	return (0);
   9020 }
   9021 SCTP_INP_WLOCK(inp);
   9022 inp->ulp_info = ulp_info;
   9023 SCTP_INP_WUNLOCK(inp);
   9024 return (1);
   9025 }
   9026 
   9027 int
   9028 retrieve_ulp_info (struct socket *so, void **pulp_info)
   9029 {
   9030 struct sctp_inpcb *inp;
   9031 
   9032 if (pulp_info == NULL) {
   9033 	return (0);
   9034 }
   9035 
   9036 inp = (struct sctp_inpcb *) so->so_pcb;
   9037 if (inp == NULL) {
   9038 	return (0);
   9039 }
   9040 SCTP_INP_RLOCK(inp);
   9041 *pulp_info = inp->ulp_info;
   9042 SCTP_INP_RUNLOCK(inp);
   9043 return (1);
   9044 }
   9045 #endif