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