xref: /freebsd-src/sys/netinet/sctp_usrreq.c (revision 3abc9103eb34adbb48853f2361206eba207d6c4f)
1 /*-
2  * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * a) Redistributions of source code must retain the above copyright notice,
8  *   this list of conditions and the following disclaimer.
9  *
10  * b) Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in
12  *   the documentation and/or other materials provided with the distribution.
13  *
14  * c) Neither the name of Cisco Systems, Inc. nor the names of its
15  *    contributors may be used to endorse or promote products derived
16  *    from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28  * THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 /* $KAME: sctp_usrreq.c,v 1.48 2005/03/07 23:26:08 itojun Exp $	 */
32 
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
35 #include <netinet/sctp_os.h>
36 #include <sys/proc.h>
37 #include <netinet/sctp_pcb.h>
38 #include <netinet/sctp_header.h>
39 #include <netinet/sctp_var.h>
40 #if defined(INET6)
41 #include <netinet6/sctp6_var.h>
42 #endif
43 #include <netinet/sctp_sysctl.h>
44 #include <netinet/sctp_output.h>
45 #include <netinet/sctp_uio.h>
46 #include <netinet/sctp_asconf.h>
47 #include <netinet/sctputil.h>
48 #include <netinet/sctp_indata.h>
49 #include <netinet/sctp_timer.h>
50 #include <netinet/sctp_auth.h>
51 #include <netinet/sctp_bsd_addr.h>
52 #include <netinet/sctp_cc_functions.h>
53 
54 
55 
56 
57 void
58 sctp_init(void)
59 {
60 	/* Init the SCTP pcb in sctp_pcb.c */
61 	u_long sb_max_adj;
62 
63 	sctp_pcb_init();
64 
65 
66 	if ((nmbclusters / 8) > SCTP_ASOC_MAX_CHUNKS_ON_QUEUE)
67 		sctp_max_chunks_on_queue = (nmbclusters / 8);
68 	/*
69 	 * Allow a user to take no more than 1/2 the number of clusters or
70 	 * the SB_MAX whichever is smaller for the send window.
71 	 */
72 	sb_max_adj = (u_long)((u_quad_t) (SB_MAX) * MCLBYTES / (MSIZE + MCLBYTES));
73 	sctp_sendspace = min((min(SB_MAX, sb_max_adj)),
74 	    (((uint32_t) nmbclusters / 2) * SCTP_DEFAULT_MAXSEGMENT));
75 	/*
76 	 * Now for the recv window, should we take the same amount? or
77 	 * should I do 1/2 the SB_MAX instead in the SB_MAX min above. For
78 	 * now I will just copy.
79 	 */
80 	sctp_recvspace = sctp_sendspace;
81 
82 }
83 
84 
85 
86 /*
87  * cleanup of the sctppcbinfo structure.
88  * Assumes that the sctppcbinfo lock is held.
89  */
90 void
91 sctp_pcbinfo_cleanup(void)
92 {
93 	/* free the hash tables */
94 	if (sctppcbinfo.sctp_asochash != NULL)
95 		SCTP_HASH_FREE(sctppcbinfo.sctp_asochash, sctppcbinfo.hashasocmark);
96 	if (sctppcbinfo.sctp_ephash != NULL)
97 		SCTP_HASH_FREE(sctppcbinfo.sctp_ephash, sctppcbinfo.hashmark);
98 	if (sctppcbinfo.sctp_tcpephash != NULL)
99 		SCTP_HASH_FREE(sctppcbinfo.sctp_tcpephash, sctppcbinfo.hashtcpmark);
100 	if (sctppcbinfo.sctp_restarthash != NULL)
101 		SCTP_HASH_FREE(sctppcbinfo.sctp_restarthash, sctppcbinfo.hashrestartmark);
102 }
103 
104 
105 static void
106 sctp_pathmtu_adjustment(struct sctp_inpcb *inp,
107     struct sctp_tcb *stcb,
108     struct sctp_nets *net,
109     uint16_t nxtsz)
110 {
111 	struct sctp_tmit_chunk *chk;
112 
113 	/* Adjust that too */
114 	stcb->asoc.smallest_mtu = nxtsz;
115 	/* now off to subtract IP_DF flag if needed */
116 #ifdef SCTP_PRINT_FOR_B_AND_M
117 	SCTP_PRINTF("sctp_pathmtu_adjust called inp:%p stcb:%p net:%p nxtsz:%d\n",
118 	    inp, stcb, net, nxtsz);
119 #endif
120 	TAILQ_FOREACH(chk, &stcb->asoc.send_queue, sctp_next) {
121 		if ((chk->send_size + IP_HDR_SIZE) > nxtsz) {
122 			chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
123 		}
124 	}
125 	TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
126 		if ((chk->send_size + IP_HDR_SIZE) > nxtsz) {
127 			/*
128 			 * For this guy we also mark for immediate resend
129 			 * since we sent to big of chunk
130 			 */
131 			chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
132 			if (chk->sent != SCTP_DATAGRAM_RESEND) {
133 				sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
134 			}
135 			chk->sent = SCTP_DATAGRAM_RESEND;
136 			chk->rec.data.doing_fast_retransmit = 0;
137 			if (sctp_logging_level & SCTP_FLIGHT_LOGGING_ENABLE) {
138 				sctp_misc_ints(SCTP_FLIGHT_LOG_DOWN_PMTU,
139 				    chk->whoTo->flight_size,
140 				    chk->book_size,
141 				    (uintptr_t) chk->whoTo,
142 				    chk->rec.data.TSN_seq);
143 			}
144 			/* Clear any time so NO RTT is being done */
145 			chk->do_rtt = 0;
146 			sctp_flight_size_decrease(chk);
147 			sctp_total_flight_decrease(stcb, chk);
148 		}
149 	}
150 }
151 
152 static void
153 sctp_notify_mbuf(struct sctp_inpcb *inp,
154     struct sctp_tcb *stcb,
155     struct sctp_nets *net,
156     struct ip *ip,
157     struct sctphdr *sh)
158 {
159 	struct icmp *icmph;
160 	int totsz, tmr_stopped = 0;
161 	uint16_t nxtsz;
162 
163 	/* protection */
164 	if ((inp == NULL) || (stcb == NULL) || (net == NULL) ||
165 	    (ip == NULL) || (sh == NULL)) {
166 		if (stcb != NULL) {
167 			SCTP_TCB_UNLOCK(stcb);
168 		}
169 		return;
170 	}
171 	/* First job is to verify the vtag matches what I would send */
172 	if (ntohl(sh->v_tag) != (stcb->asoc.peer_vtag)) {
173 		SCTP_TCB_UNLOCK(stcb);
174 		return;
175 	}
176 	icmph = (struct icmp *)((caddr_t)ip - (sizeof(struct icmp) -
177 	    sizeof(struct ip)));
178 	if (icmph->icmp_type != ICMP_UNREACH) {
179 		/* We only care about unreachable */
180 		SCTP_TCB_UNLOCK(stcb);
181 		return;
182 	}
183 	if (icmph->icmp_code != ICMP_UNREACH_NEEDFRAG) {
184 		/* not a unreachable message due to frag. */
185 		SCTP_TCB_UNLOCK(stcb);
186 		return;
187 	}
188 	totsz = ip->ip_len;
189 
190 	nxtsz = ntohs(icmph->icmp_seq);
191 	if (nxtsz == 0) {
192 		/*
193 		 * old type router that does not tell us what the next size
194 		 * mtu is. Rats we will have to guess (in a educated fashion
195 		 * of course)
196 		 */
197 		nxtsz = find_next_best_mtu(totsz);
198 	}
199 	/* Stop any PMTU timer */
200 	if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
201 		tmr_stopped = 1;
202 		sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net,
203 		    SCTP_FROM_SCTP_USRREQ + SCTP_LOC_1);
204 	}
205 	/* Adjust destination size limit */
206 	if (net->mtu > nxtsz) {
207 		net->mtu = nxtsz;
208 	}
209 	/* now what about the ep? */
210 	if (stcb->asoc.smallest_mtu > nxtsz) {
211 #ifdef SCTP_PRINT_FOR_B_AND_M
212 		SCTP_PRINTF("notify_mbuf (ICMP) calls sctp_pathmtu_adjust mtu:%d\n",
213 		    nxtsz);
214 #endif
215 		sctp_pathmtu_adjustment(inp, stcb, net, nxtsz);
216 	}
217 	if (tmr_stopped)
218 		sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net);
219 
220 	SCTP_TCB_UNLOCK(stcb);
221 }
222 
223 
224 void
225 sctp_notify(struct sctp_inpcb *inp,
226     int error,
227     struct sctphdr *sh,
228     struct sockaddr *to,
229     struct sctp_tcb *stcb,
230     struct sctp_nets *net)
231 {
232 	/* protection */
233 	if ((inp == NULL) || (stcb == NULL) || (net == NULL) ||
234 	    (sh == NULL) || (to == NULL)) {
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 		return;
240 	}
241 	/* FIX ME FIX ME PROTOPT i.e. no SCTP should ALWAYS be an ABORT */
242 
243 	if ((error == EHOSTUNREACH) ||	/* Host is not reachable */
244 	    (error == EHOSTDOWN) ||	/* Host is down */
245 	    (error == ECONNREFUSED) ||	/* Host refused the connection, (not
246 					 * an abort?) */
247 	    (error == ENOPROTOOPT)	/* SCTP is not present on host */
248 	    ) {
249 		/*
250 		 * Hmm reachablity problems we must examine closely. If its
251 		 * not reachable, we may have lost a network. Or if there is
252 		 * NO protocol at the other end named SCTP. well we consider
253 		 * it a OOTB abort.
254 		 */
255 		if ((error == EHOSTUNREACH) || (error == EHOSTDOWN)) {
256 			if (net->dest_state & SCTP_ADDR_REACHABLE) {
257 				/* Ok that destination is NOT reachable */
258 				SCTP_PRINTF("ICMP (thresh %d/%d) takes interface %p down\n",
259 				    net->error_count,
260 				    net->failure_threshold,
261 				    net);
262 
263 				net->dest_state &= ~SCTP_ADDR_REACHABLE;
264 				net->dest_state |= SCTP_ADDR_NOT_REACHABLE;
265 				/*
266 				 * JRS 5/14/07 - If a destination is
267 				 * unreachable, the PF bit is turned off.
268 				 * This allows an unambiguous use of the PF
269 				 * bit for destinations that are reachable
270 				 * but potentially failed. If the
271 				 * destination is set to the unreachable
272 				 * state, also set the destination to the PF
273 				 * state.
274 				 */
275 				/*
276 				 * Add debug message here if destination is
277 				 * not in PF state.
278 				 */
279 				/* Stop any running T3 timers here? */
280 				if (sctp_cmt_on_off && sctp_cmt_pf) {
281 					net->dest_state &= ~SCTP_ADDR_PF;
282 					SCTPDBG(SCTP_DEBUG_TIMER4, "Destination %p moved from PF to unreachable.\n",
283 					    net);
284 				}
285 				net->error_count = net->failure_threshold + 1;
286 				sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN,
287 				    stcb, SCTP_FAILED_THRESHOLD,
288 				    (void *)net);
289 			}
290 			if (stcb) {
291 				SCTP_TCB_UNLOCK(stcb);
292 			}
293 		} else {
294 			/*
295 			 * Here the peer is either playing tricks on us,
296 			 * including an address that belongs to someone who
297 			 * does not support SCTP OR was a userland
298 			 * implementation that shutdown and now is dead. In
299 			 * either case treat it like a OOTB abort with no
300 			 * TCB
301 			 */
302 			sctp_abort_notification(stcb, SCTP_PEER_FAULTY);
303 			sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_2);
304 			/* no need to unlock here, since the TCB is gone */
305 		}
306 	} else {
307 		/* Send all others to the app */
308 		if (stcb) {
309 			SCTP_TCB_UNLOCK(stcb);
310 		}
311 		if (inp->sctp_socket) {
312 #ifdef SCTP_LOCK_LOGGING
313 			if (sctp_logging_level & SCTP_LOCK_LOGGING_ENABLE) {
314 				sctp_log_lock(inp, stcb, SCTP_LOG_LOCK_SOCK);
315 			}
316 #endif
317 			SOCK_LOCK(inp->sctp_socket);
318 			inp->sctp_socket->so_error = error;
319 			sctp_sowwakeup(inp, inp->sctp_socket);
320 			SOCK_UNLOCK(inp->sctp_socket);
321 		}
322 	}
323 }
324 
325 void
326 sctp_ctlinput(cmd, sa, vip)
327 	int cmd;
328 	struct sockaddr *sa;
329 	void *vip;
330 {
331 	struct ip *ip = vip;
332 	struct sctphdr *sh;
333 	uint32_t vrf_id;
334 
335 	/* FIX, for non-bsd is this right? */
336 	vrf_id = SCTP_DEFAULT_VRFID;
337 	if (sa->sa_family != AF_INET ||
338 	    ((struct sockaddr_in *)sa)->sin_addr.s_addr == INADDR_ANY) {
339 		return;
340 	}
341 	if (PRC_IS_REDIRECT(cmd)) {
342 		ip = 0;
343 	} else if ((unsigned)cmd >= PRC_NCMDS || inetctlerrmap[cmd] == 0) {
344 		return;
345 	}
346 	if (ip) {
347 		struct sctp_inpcb *inp = NULL;
348 		struct sctp_tcb *stcb = NULL;
349 		struct sctp_nets *net = NULL;
350 		struct sockaddr_in to, from;
351 
352 		sh = (struct sctphdr *)((caddr_t)ip + (ip->ip_hl << 2));
353 		bzero(&to, sizeof(to));
354 		bzero(&from, sizeof(from));
355 		from.sin_family = to.sin_family = AF_INET;
356 		from.sin_len = to.sin_len = sizeof(to);
357 		from.sin_port = sh->src_port;
358 		from.sin_addr = ip->ip_src;
359 		to.sin_port = sh->dest_port;
360 		to.sin_addr = ip->ip_dst;
361 
362 		/*
363 		 * 'to' holds the dest of the packet that failed to be sent.
364 		 * 'from' holds our local endpoint address. Thus we reverse
365 		 * the to and the from in the lookup.
366 		 */
367 		stcb = sctp_findassociation_addr_sa((struct sockaddr *)&from,
368 		    (struct sockaddr *)&to,
369 		    &inp, &net, 1, vrf_id);
370 		if (stcb != NULL && inp && (inp->sctp_socket != NULL)) {
371 			if (cmd != PRC_MSGSIZE) {
372 				int cm;
373 
374 				if (cmd == PRC_HOSTDEAD) {
375 					cm = EHOSTUNREACH;
376 				} else {
377 					cm = inetctlerrmap[cmd];
378 				}
379 				sctp_notify(inp, cm, sh,
380 				    (struct sockaddr *)&to, stcb,
381 				    net);
382 			} else {
383 				/* handle possible ICMP size messages */
384 				sctp_notify_mbuf(inp, stcb, net, ip, sh);
385 			}
386 		} else {
387 			if ((stcb == NULL) && (inp != NULL)) {
388 				/* reduce ref-count */
389 				SCTP_INP_WLOCK(inp);
390 				SCTP_INP_DECR_REF(inp);
391 				SCTP_INP_WUNLOCK(inp);
392 			}
393 		}
394 	}
395 	return;
396 }
397 
398 static int
399 sctp_getcred(SYSCTL_HANDLER_ARGS)
400 {
401 	struct xucred xuc;
402 	struct sockaddr_in addrs[2];
403 	struct sctp_inpcb *inp;
404 	struct sctp_nets *net;
405 	struct sctp_tcb *stcb;
406 	int error;
407 	uint32_t vrf_id;
408 
409 	/* FIX, for non-bsd is this right? */
410 	vrf_id = SCTP_DEFAULT_VRFID;
411 
412 	error = priv_check(req->td, PRIV_NETINET_GETCRED);
413 
414 	if (error)
415 		return (error);
416 
417 	error = SYSCTL_IN(req, addrs, sizeof(addrs));
418 	if (error)
419 		return (error);
420 
421 	stcb = sctp_findassociation_addr_sa(sintosa(&addrs[0]),
422 	    sintosa(&addrs[1]),
423 	    &inp, &net, 1, vrf_id);
424 	if (stcb == NULL || inp == NULL || inp->sctp_socket == NULL) {
425 		if ((inp != NULL) && (stcb == NULL)) {
426 			/* reduce ref-count */
427 			SCTP_INP_WLOCK(inp);
428 			SCTP_INP_DECR_REF(inp);
429 			goto cred_can_cont;
430 		}
431 		error = ENOENT;
432 		goto out;
433 	}
434 	SCTP_TCB_UNLOCK(stcb);
435 	/*
436 	 * We use the write lock here, only since in the error leg we need
437 	 * it. If we used RLOCK, then we would have to
438 	 * wlock/decr/unlock/rlock. Which in theory could create a hole.
439 	 * Better to use higher wlock.
440 	 */
441 	SCTP_INP_WLOCK(inp);
442 cred_can_cont:
443 	error = cr_canseesocket(req->td->td_ucred, inp->sctp_socket);
444 	if (error) {
445 		SCTP_INP_WUNLOCK(inp);
446 		goto out;
447 	}
448 	cru2x(inp->sctp_socket->so_cred, &xuc);
449 	SCTP_INP_WUNLOCK(inp);
450 	error = SYSCTL_OUT(req, &xuc, sizeof(struct xucred));
451 out:
452 	return (error);
453 }
454 
455 SYSCTL_PROC(_net_inet_sctp, OID_AUTO, getcred, CTLTYPE_OPAQUE | CTLFLAG_RW,
456     0, 0, sctp_getcred, "S,ucred", "Get the ucred of a SCTP connection");
457 
458 
459 static void
460 sctp_abort(struct socket *so)
461 {
462 	struct sctp_inpcb *inp;
463 	uint32_t flags;
464 
465 	inp = (struct sctp_inpcb *)so->so_pcb;
466 	if (inp == 0)
467 		return;
468 
469 sctp_must_try_again:
470 	flags = inp->sctp_flags;
471 #ifdef SCTP_LOG_CLOSING
472 	sctp_log_closing(inp, NULL, 17);
473 #endif
474 	if (((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
475 	    (atomic_cmpset_int(&inp->sctp_flags, flags, (flags | SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_CLOSE_IP)))) {
476 #ifdef SCTP_LOG_CLOSING
477 		sctp_log_closing(inp, NULL, 16);
478 #endif
479 		sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT,
480 		    SCTP_CALLED_AFTER_CMPSET_OFCLOSE);
481 		SOCK_LOCK(so);
482 		SCTP_SB_CLEAR(so->so_snd);
483 		/*
484 		 * same for the rcv ones, they are only here for the
485 		 * accounting/select.
486 		 */
487 		SCTP_SB_CLEAR(so->so_rcv);
488 
489 		/* Now null out the reference, we are completely detached. */
490 		so->so_pcb = NULL;
491 		SOCK_UNLOCK(so);
492 	} else {
493 		flags = inp->sctp_flags;
494 		if ((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) {
495 			goto sctp_must_try_again;
496 		}
497 	}
498 	return;
499 }
500 
501 static int
502 sctp_attach(struct socket *so, int proto, struct thread *p)
503 {
504 	struct sctp_inpcb *inp;
505 	struct inpcb *ip_inp;
506 	int error;
507 	uint32_t vrf_id = SCTP_DEFAULT_VRFID;
508 
509 #ifdef IPSEC
510 	uint32_t flags;
511 
512 #endif
513 	inp = (struct sctp_inpcb *)so->so_pcb;
514 	if (inp != 0) {
515 		return EINVAL;
516 	}
517 	error = SCTP_SORESERVE(so, sctp_sendspace, sctp_recvspace);
518 	if (error) {
519 		return error;
520 	}
521 	error = sctp_inpcb_alloc(so, vrf_id);
522 	if (error) {
523 		return error;
524 	}
525 	inp = (struct sctp_inpcb *)so->so_pcb;
526 	SCTP_INP_WLOCK(inp);
527 
528 	inp->sctp_flags &= ~SCTP_PCB_FLAGS_BOUND_V6;	/* I'm not v6! */
529 	ip_inp = &inp->ip_inp.inp;
530 	ip_inp->inp_vflag |= INP_IPV4;
531 	ip_inp->inp_ip_ttl = ip_defttl;
532 
533 #ifdef IPSEC
534 	error = ipsec_init_policy(so, &ip_inp->inp_sp);
535 #ifdef SCTP_LOG_CLOSING
536 	sctp_log_closing(inp, NULL, 17);
537 #endif
538 	if (error != 0) {
539 		flags = inp->sctp_flags;
540 		if (((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
541 		    (atomic_cmpset_int(&inp->sctp_flags, flags, (flags | SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_CLOSE_IP)))) {
542 #ifdef SCTP_LOG_CLOSING
543 			sctp_log_closing(inp, NULL, 15);
544 #endif
545 			SCTP_INP_WUNLOCK(inp);
546 			sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT,
547 			    SCTP_CALLED_AFTER_CMPSET_OFCLOSE);
548 		} else {
549 			SCTP_INP_WUNLOCK(inp);
550 		}
551 		return error;
552 	}
553 #endif				/* IPSEC */
554 	SCTP_INP_WUNLOCK(inp);
555 	return 0;
556 }
557 
558 static int
559 sctp_bind(struct socket *so, struct sockaddr *addr, struct thread *p)
560 {
561 	struct sctp_inpcb *inp;
562 	int error;
563 
564 #ifdef INET6
565 	if (addr && addr->sa_family != AF_INET)
566 		/* must be a v4 address! */
567 		return EINVAL;
568 #endif				/* INET6 */
569 	if (addr && (addr->sa_len != sizeof(struct sockaddr_in))) {
570 		return EINVAL;
571 	}
572 	inp = (struct sctp_inpcb *)so->so_pcb;
573 	if (inp == 0)
574 		return EINVAL;
575 
576 	error = sctp_inpcb_bind(so, addr, p);
577 	return error;
578 }
579 
580 static void
581 sctp_close(struct socket *so)
582 {
583 	struct sctp_inpcb *inp;
584 	uint32_t flags;
585 
586 	inp = (struct sctp_inpcb *)so->so_pcb;
587 	if (inp == 0)
588 		return;
589 
590 	/*
591 	 * Inform all the lower layer assoc that we are done.
592 	 */
593 sctp_must_try_again:
594 	flags = inp->sctp_flags;
595 #ifdef SCTP_LOG_CLOSING
596 	sctp_log_closing(inp, NULL, 17);
597 #endif
598 	if (((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
599 	    (atomic_cmpset_int(&inp->sctp_flags, flags, (flags | SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_CLOSE_IP)))) {
600 		if (((so->so_options & SO_LINGER) && (so->so_linger == 0)) ||
601 		    (so->so_rcv.sb_cc > 0)) {
602 #ifdef SCTP_LOG_CLOSING
603 			sctp_log_closing(inp, NULL, 13);
604 #endif
605 			sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT,
606 			    SCTP_CALLED_AFTER_CMPSET_OFCLOSE);
607 		} else {
608 #ifdef SCTP_LOG_CLOSING
609 			sctp_log_closing(inp, NULL, 14);
610 #endif
611 			sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_GRACEFUL_CLOSE,
612 			    SCTP_CALLED_AFTER_CMPSET_OFCLOSE);
613 		}
614 		/*
615 		 * The socket is now detached, no matter what the state of
616 		 * the SCTP association.
617 		 */
618 		SOCK_LOCK(so);
619 		SCTP_SB_CLEAR(so->so_snd);
620 		/*
621 		 * same for the rcv ones, they are only here for the
622 		 * accounting/select.
623 		 */
624 		SCTP_SB_CLEAR(so->so_rcv);
625 
626 		/* Now null out the reference, we are completely detached. */
627 		so->so_pcb = NULL;
628 		SOCK_UNLOCK(so);
629 	} else {
630 		flags = inp->sctp_flags;
631 		if ((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) {
632 			goto sctp_must_try_again;
633 		}
634 	}
635 	return;
636 }
637 
638 
639 int
640 sctp_sendm(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
641     struct mbuf *control, struct thread *p);
642 
643 
644 int
645 sctp_sendm(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
646     struct mbuf *control, struct thread *p)
647 {
648 	struct sctp_inpcb *inp;
649 	int error;
650 
651 	inp = (struct sctp_inpcb *)so->so_pcb;
652 	if (inp == 0) {
653 		if (control) {
654 			sctp_m_freem(control);
655 			control = NULL;
656 		}
657 		sctp_m_freem(m);
658 		return EINVAL;
659 	}
660 	/* Got to have an to address if we are NOT a connected socket */
661 	if ((addr == NULL) &&
662 	    ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) ||
663 	    (inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE))
664 	    ) {
665 		goto connected_type;
666 	} else if (addr == NULL) {
667 		error = EDESTADDRREQ;
668 		sctp_m_freem(m);
669 		if (control) {
670 			sctp_m_freem(control);
671 			control = NULL;
672 		}
673 		return (error);
674 	}
675 #ifdef INET6
676 	if (addr->sa_family != AF_INET) {
677 		/* must be a v4 address! */
678 		sctp_m_freem(m);
679 		if (control) {
680 			sctp_m_freem(control);
681 			control = NULL;
682 		}
683 		error = EDESTADDRREQ;
684 		return EINVAL;
685 	}
686 #endif				/* INET6 */
687 connected_type:
688 	/* now what about control */
689 	if (control) {
690 		if (inp->control) {
691 			SCTP_PRINTF("huh? control set?\n");
692 			sctp_m_freem(inp->control);
693 			inp->control = NULL;
694 		}
695 		inp->control = control;
696 	}
697 	/* Place the data */
698 	if (inp->pkt) {
699 		SCTP_BUF_NEXT(inp->pkt_last) = m;
700 		inp->pkt_last = m;
701 	} else {
702 		inp->pkt_last = inp->pkt = m;
703 	}
704 	if (
705 	/* FreeBSD uses a flag passed */
706 	    ((flags & PRUS_MORETOCOME) == 0)
707 	    ) {
708 		/*
709 		 * note with the current version this code will only be used
710 		 * by OpenBSD-- NetBSD, FreeBSD, and MacOS have methods for
711 		 * re-defining sosend to use the sctp_sosend. One can
712 		 * optionally switch back to this code (by changing back the
713 		 * definitions) but this is not advisable. This code is used
714 		 * by FreeBSD when sending a file with sendfile() though.
715 		 */
716 		int ret;
717 
718 		ret = sctp_output(inp, inp->pkt, addr, inp->control, p, flags);
719 		inp->pkt = NULL;
720 		inp->control = NULL;
721 		return (ret);
722 	} else {
723 		return (0);
724 	}
725 }
726 
727 static int
728 sctp_disconnect(struct socket *so)
729 {
730 	struct sctp_inpcb *inp;
731 
732 	inp = (struct sctp_inpcb *)so->so_pcb;
733 	if (inp == NULL) {
734 		return (ENOTCONN);
735 	}
736 	SCTP_INP_RLOCK(inp);
737 	if (inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) {
738 		if (SCTP_LIST_EMPTY(&inp->sctp_asoc_list)) {
739 			/* No connection */
740 			SCTP_INP_RUNLOCK(inp);
741 			return (0);
742 		} else {
743 			struct sctp_association *asoc;
744 			struct sctp_tcb *stcb;
745 
746 			stcb = LIST_FIRST(&inp->sctp_asoc_list);
747 			if (stcb == NULL) {
748 				SCTP_INP_RUNLOCK(inp);
749 				return (EINVAL);
750 			}
751 			SCTP_TCB_LOCK(stcb);
752 			asoc = &stcb->asoc;
753 			if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
754 				/* We are about to be freed, out of here */
755 				SCTP_TCB_UNLOCK(stcb);
756 				SCTP_INP_RUNLOCK(inp);
757 				return (0);
758 			}
759 			if (((so->so_options & SO_LINGER) &&
760 			    (so->so_linger == 0)) ||
761 			    (so->so_rcv.sb_cc > 0)) {
762 				if (SCTP_GET_STATE(asoc) !=
763 				    SCTP_STATE_COOKIE_WAIT) {
764 					/* Left with Data unread */
765 					struct mbuf *err;
766 
767 					err = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr), 0, M_DONTWAIT, 1, MT_DATA);
768 					if (err) {
769 						/*
770 						 * Fill in the user
771 						 * initiated abort
772 						 */
773 						struct sctp_paramhdr *ph;
774 
775 						ph = mtod(err, struct sctp_paramhdr *);
776 						SCTP_BUF_LEN(err) = sizeof(struct sctp_paramhdr);
777 						ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
778 						ph->param_length = htons(SCTP_BUF_LEN(err));
779 					}
780 					sctp_send_abort_tcb(stcb, err);
781 					SCTP_STAT_INCR_COUNTER32(sctps_aborted);
782 				}
783 				SCTP_INP_RUNLOCK(inp);
784 				if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) ||
785 				    (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
786 					SCTP_STAT_DECR_GAUGE32(sctps_currestab);
787 				}
788 				sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_3);
789 				/* No unlock tcb assoc is gone */
790 				return (0);
791 			}
792 			if (TAILQ_EMPTY(&asoc->send_queue) &&
793 			    TAILQ_EMPTY(&asoc->sent_queue) &&
794 			    (asoc->stream_queue_cnt == 0)) {
795 				/* there is nothing queued to send, so done */
796 				if (asoc->locked_on_sending) {
797 					goto abort_anyway;
798 				}
799 				if ((SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT) &&
800 				    (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_ACK_SENT)) {
801 					/* only send SHUTDOWN 1st time thru */
802 					sctp_stop_timers_for_shutdown(stcb);
803 					sctp_send_shutdown(stcb,
804 					    stcb->asoc.primary_destination);
805 					sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3);
806 					if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) ||
807 					    (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
808 						SCTP_STAT_DECR_GAUGE32(sctps_currestab);
809 					}
810 					asoc->state = SCTP_STATE_SHUTDOWN_SENT;
811 					sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
812 					    stcb->sctp_ep, stcb,
813 					    asoc->primary_destination);
814 					sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
815 					    stcb->sctp_ep, stcb,
816 					    asoc->primary_destination);
817 				}
818 			} else {
819 				/*
820 				 * we still got (or just got) data to send,
821 				 * so set SHUTDOWN_PENDING
822 				 */
823 				/*
824 				 * XXX sockets draft says that SCTP_EOF
825 				 * should be sent with no data. currently,
826 				 * we will allow user data to be sent first
827 				 * and move to SHUTDOWN-PENDING
828 				 */
829 				asoc->state |= SCTP_STATE_SHUTDOWN_PENDING;
830 				sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, stcb->sctp_ep, stcb,
831 				    asoc->primary_destination);
832 				if (asoc->locked_on_sending) {
833 					/* Locked to send out the data */
834 					struct sctp_stream_queue_pending *sp;
835 
836 					sp = TAILQ_LAST(&asoc->locked_on_sending->outqueue, sctp_streamhead);
837 					if (sp == NULL) {
838 						SCTP_PRINTF("Error, sp is NULL, locked on sending is non-null strm:%d\n",
839 						    asoc->locked_on_sending->stream_no);
840 					} else {
841 						if ((sp->length == 0) && (sp->msg_is_complete == 0))
842 							asoc->state |= SCTP_STATE_PARTIAL_MSG_LEFT;
843 					}
844 				}
845 				if (TAILQ_EMPTY(&asoc->send_queue) &&
846 				    TAILQ_EMPTY(&asoc->sent_queue) &&
847 				    (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT)) {
848 					struct mbuf *op_err;
849 
850 			abort_anyway:
851 					op_err = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
852 					    0, M_DONTWAIT, 1, MT_DATA);
853 					if (op_err) {
854 						/*
855 						 * Fill in the user
856 						 * initiated abort
857 						 */
858 						struct sctp_paramhdr *ph;
859 						uint32_t *ippp;
860 
861 						SCTP_BUF_LEN(op_err) =
862 						    (sizeof(struct sctp_paramhdr) + sizeof(uint32_t));
863 						ph = mtod(op_err,
864 						    struct sctp_paramhdr *);
865 						ph->param_type = htons(
866 						    SCTP_CAUSE_USER_INITIATED_ABT);
867 						ph->param_length = htons(SCTP_BUF_LEN(op_err));
868 						ippp = (uint32_t *) (ph + 1);
869 						*ippp = htonl(SCTP_FROM_SCTP_USRREQ + SCTP_LOC_4);
870 					}
871 					stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_USRREQ + SCTP_LOC_4;
872 					sctp_send_abort_tcb(stcb, op_err);
873 					SCTP_STAT_INCR_COUNTER32(sctps_aborted);
874 					if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) ||
875 					    (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
876 						SCTP_STAT_DECR_GAUGE32(sctps_currestab);
877 					}
878 					SCTP_INP_RUNLOCK(inp);
879 					sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_5);
880 					return (0);
881 				}
882 			}
883 			SCTP_TCB_UNLOCK(stcb);
884 			SCTP_INP_RUNLOCK(inp);
885 			return (0);
886 		}
887 		/* not reached */
888 	} else {
889 		/* UDP model does not support this */
890 		SCTP_INP_RUNLOCK(inp);
891 		return EOPNOTSUPP;
892 	}
893 }
894 
895 int
896 sctp_shutdown(struct socket *so)
897 {
898 	struct sctp_inpcb *inp;
899 
900 	inp = (struct sctp_inpcb *)so->so_pcb;
901 	if (inp == 0) {
902 		return EINVAL;
903 	}
904 	SCTP_INP_RLOCK(inp);
905 	/* For UDP model this is a invalid call */
906 	if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) {
907 		/* Restore the flags that the soshutdown took away. */
908 		so->so_rcv.sb_state &= ~SBS_CANTRCVMORE;
909 		/* This proc will wakeup for read and do nothing (I hope) */
910 		SCTP_INP_RUNLOCK(inp);
911 		return (EOPNOTSUPP);
912 	}
913 	/*
914 	 * Ok if we reach here its the TCP model and it is either a SHUT_WR
915 	 * or SHUT_RDWR. This means we put the shutdown flag against it.
916 	 */
917 	{
918 		struct sctp_tcb *stcb;
919 		struct sctp_association *asoc;
920 
921 		socantsendmore(so);
922 
923 		stcb = LIST_FIRST(&inp->sctp_asoc_list);
924 		if (stcb == NULL) {
925 			/*
926 			 * Ok we hit the case that the shutdown call was
927 			 * made after an abort or something. Nothing to do
928 			 * now.
929 			 */
930 			SCTP_INP_RUNLOCK(inp);
931 			return (0);
932 		}
933 		SCTP_TCB_LOCK(stcb);
934 		asoc = &stcb->asoc;
935 		if (TAILQ_EMPTY(&asoc->send_queue) &&
936 		    TAILQ_EMPTY(&asoc->sent_queue) &&
937 		    (asoc->stream_queue_cnt == 0)) {
938 			if (asoc->locked_on_sending) {
939 				goto abort_anyway;
940 			}
941 			/* there is nothing queued to send, so I'm done... */
942 			if (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT) {
943 				/* only send SHUTDOWN the first time through */
944 				sctp_stop_timers_for_shutdown(stcb);
945 				sctp_send_shutdown(stcb,
946 				    stcb->asoc.primary_destination);
947 				sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3);
948 				if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) ||
949 				    (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
950 					SCTP_STAT_DECR_GAUGE32(sctps_currestab);
951 				}
952 				asoc->state = SCTP_STATE_SHUTDOWN_SENT;
953 				sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
954 				    stcb->sctp_ep, stcb,
955 				    asoc->primary_destination);
956 				sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
957 				    stcb->sctp_ep, stcb,
958 				    asoc->primary_destination);
959 			}
960 		} else {
961 			/*
962 			 * we still got (or just got) data to send, so set
963 			 * SHUTDOWN_PENDING
964 			 */
965 			asoc->state |= SCTP_STATE_SHUTDOWN_PENDING;
966 			sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, stcb->sctp_ep, stcb,
967 			    asoc->primary_destination);
968 
969 			if (asoc->locked_on_sending) {
970 				/* Locked to send out the data */
971 				struct sctp_stream_queue_pending *sp;
972 
973 				sp = TAILQ_LAST(&asoc->locked_on_sending->outqueue, sctp_streamhead);
974 				if (sp == NULL) {
975 					SCTP_PRINTF("Error, sp is NULL, locked on sending is non-null strm:%d\n",
976 					    asoc->locked_on_sending->stream_no);
977 				} else {
978 					if ((sp->length == 0) && (sp->msg_is_complete == 0)) {
979 						asoc->state |= SCTP_STATE_PARTIAL_MSG_LEFT;
980 					}
981 				}
982 			}
983 			if (TAILQ_EMPTY(&asoc->send_queue) &&
984 			    TAILQ_EMPTY(&asoc->sent_queue) &&
985 			    (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT)) {
986 				struct mbuf *op_err;
987 
988 		abort_anyway:
989 				op_err = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
990 				    0, M_DONTWAIT, 1, MT_DATA);
991 				if (op_err) {
992 					/* Fill in the user initiated abort */
993 					struct sctp_paramhdr *ph;
994 					uint32_t *ippp;
995 
996 					SCTP_BUF_LEN(op_err) =
997 					    sizeof(struct sctp_paramhdr) + sizeof(uint32_t);
998 					ph = mtod(op_err,
999 					    struct sctp_paramhdr *);
1000 					ph->param_type = htons(
1001 					    SCTP_CAUSE_USER_INITIATED_ABT);
1002 					ph->param_length = htons(SCTP_BUF_LEN(op_err));
1003 					ippp = (uint32_t *) (ph + 1);
1004 					*ippp = htonl(SCTP_FROM_SCTP_USRREQ + SCTP_LOC_6);
1005 				}
1006 				stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_USRREQ + SCTP_LOC_6;
1007 				sctp_abort_an_association(stcb->sctp_ep, stcb,
1008 				    SCTP_RESPONSE_TO_USER_REQ,
1009 				    op_err);
1010 				goto skip_unlock;
1011 			}
1012 		}
1013 		SCTP_TCB_UNLOCK(stcb);
1014 	}
1015 skip_unlock:
1016 	SCTP_INP_RUNLOCK(inp);
1017 	return 0;
1018 }
1019 
1020 /*
1021  * copies a "user" presentable address and removes embedded scope, etc.
1022  * returns 0 on success, 1 on error
1023  */
1024 static uint32_t
1025 sctp_fill_user_address(struct sockaddr_storage *ss, struct sockaddr *sa)
1026 {
1027 	struct sockaddr_in6 lsa6;
1028 
1029 	sa = (struct sockaddr *)sctp_recover_scope((struct sockaddr_in6 *)sa,
1030 	    &lsa6);
1031 	memcpy(ss, sa, sa->sa_len);
1032 	return (0);
1033 }
1034 
1035 
1036 
1037 static size_t
1038 sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp,
1039     struct sctp_tcb *stcb,
1040     size_t limit,
1041     struct sockaddr_storage *sas,
1042     uint32_t vrf_id)
1043 {
1044 	struct sctp_ifn *sctp_ifn;
1045 	struct sctp_ifa *sctp_ifa;
1046 	int loopback_scope, ipv4_local_scope, local_scope, site_scope;
1047 	size_t actual;
1048 	int ipv4_addr_legal, ipv6_addr_legal;
1049 	struct sctp_vrf *vrf;
1050 
1051 	actual = 0;
1052 	if (limit <= 0)
1053 		return (actual);
1054 
1055 	if (stcb) {
1056 		/* Turn on all the appropriate scope */
1057 		loopback_scope = stcb->asoc.loopback_scope;
1058 		ipv4_local_scope = stcb->asoc.ipv4_local_scope;
1059 		local_scope = stcb->asoc.local_scope;
1060 		site_scope = stcb->asoc.site_scope;
1061 	} else {
1062 		/* Turn on ALL scope, since we look at the EP */
1063 		loopback_scope = ipv4_local_scope = local_scope =
1064 		    site_scope = 1;
1065 	}
1066 	ipv4_addr_legal = ipv6_addr_legal = 0;
1067 	if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
1068 		ipv6_addr_legal = 1;
1069 		if (SCTP_IPV6_V6ONLY(inp) == 0) {
1070 			ipv4_addr_legal = 1;
1071 		}
1072 	} else {
1073 		ipv4_addr_legal = 1;
1074 	}
1075 	vrf = sctp_find_vrf(vrf_id);
1076 	if (vrf == NULL) {
1077 		return (0);
1078 	}
1079 	if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
1080 		LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
1081 			if ((loopback_scope == 0) &&
1082 			    SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) {
1083 				/* Skip loopback if loopback_scope not set */
1084 				continue;
1085 			}
1086 			LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
1087 				if (stcb) {
1088 					/*
1089 					 * For the BOUND-ALL case, the list
1090 					 * associated with a TCB is Always
1091 					 * considered a reverse list.. i.e.
1092 					 * it lists addresses that are NOT
1093 					 * part of the association. If this
1094 					 * is one of those we must skip it.
1095 					 */
1096 					if (sctp_is_addr_restricted(stcb,
1097 					    sctp_ifa)) {
1098 						continue;
1099 					}
1100 				}
1101 				if ((sctp_ifa->address.sa.sa_family == AF_INET) &&
1102 				    (ipv4_addr_legal)) {
1103 					struct sockaddr_in *sin;
1104 
1105 					sin = (struct sockaddr_in *)&sctp_ifa->address.sa;
1106 					if (sin->sin_addr.s_addr == 0) {
1107 						/*
1108 						 * we skip unspecifed
1109 						 * addresses
1110 						 */
1111 						continue;
1112 					}
1113 					if ((ipv4_local_scope == 0) &&
1114 					    (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
1115 						continue;
1116 					}
1117 					if (inp->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) {
1118 						in6_sin_2_v4mapsin6(sin, (struct sockaddr_in6 *)sas);
1119 						((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport;
1120 						sas = (struct sockaddr_storage *)((caddr_t)sas + sizeof(struct sockaddr_in6));
1121 						actual += sizeof(sizeof(struct sockaddr_in6));
1122 					} else {
1123 						memcpy(sas, sin, sizeof(*sin));
1124 						((struct sockaddr_in *)sas)->sin_port = inp->sctp_lport;
1125 						sas = (struct sockaddr_storage *)((caddr_t)sas + sizeof(*sin));
1126 						actual += sizeof(*sin);
1127 					}
1128 					if (actual >= limit) {
1129 						return (actual);
1130 					}
1131 				} else if ((sctp_ifa->address.sa.sa_family == AF_INET6) &&
1132 				    (ipv6_addr_legal)) {
1133 					struct sockaddr_in6 *sin6;
1134 
1135 					sin6 = (struct sockaddr_in6 *)&sctp_ifa->address.sa;
1136 					if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
1137 						/*
1138 						 * we skip unspecifed
1139 						 * addresses
1140 						 */
1141 						continue;
1142 					}
1143 					if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
1144 						if (local_scope == 0)
1145 							continue;
1146 						if (sin6->sin6_scope_id == 0) {
1147 							if (sa6_recoverscope(sin6) != 0)
1148 								/*
1149 								 * bad link
1150 								 * local
1151 								 * address
1152 								 */
1153 								continue;
1154 						}
1155 					}
1156 					if ((site_scope == 0) &&
1157 					    (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) {
1158 						continue;
1159 					}
1160 					memcpy(sas, sin6, sizeof(*sin6));
1161 					((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport;
1162 					sas = (struct sockaddr_storage *)((caddr_t)sas + sizeof(*sin6));
1163 					actual += sizeof(*sin6);
1164 					if (actual >= limit) {
1165 						return (actual);
1166 					}
1167 				}
1168 			}
1169 		}
1170 	} else {
1171 		struct sctp_laddr *laddr;
1172 
1173 		/* The list is a NEGATIVE list */
1174 		LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
1175 			if (stcb) {
1176 				if (sctp_is_addr_restricted(stcb, laddr->ifa)) {
1177 					continue;
1178 				}
1179 			}
1180 			if (sctp_fill_user_address(sas, &laddr->ifa->address.sa))
1181 				continue;
1182 
1183 			((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport;
1184 			sas = (struct sockaddr_storage *)((caddr_t)sas +
1185 			    laddr->ifa->address.sa.sa_len);
1186 			actual += laddr->ifa->address.sa.sa_len;
1187 			if (actual >= limit) {
1188 				return (actual);
1189 			}
1190 		}
1191 	}
1192 	return (actual);
1193 }
1194 
1195 static size_t
1196 sctp_fill_up_addresses(struct sctp_inpcb *inp,
1197     struct sctp_tcb *stcb,
1198     size_t limit,
1199     struct sockaddr_storage *sas)
1200 {
1201 	size_t size = 0;
1202 
1203 	/* fill up addresses for the endpoint's default vrf */
1204 	size = sctp_fill_up_addresses_vrf(inp, stcb, limit, sas,
1205 	    inp->def_vrf_id);
1206 	return (size);
1207 }
1208 
1209 static int
1210 sctp_count_max_addresses_vrf(struct sctp_inpcb *inp, uint32_t vrf_id)
1211 {
1212 	int cnt = 0;
1213 	struct sctp_vrf *vrf = NULL;
1214 
1215 	/*
1216 	 * In both sub-set bound an bound_all cases we return the MAXIMUM
1217 	 * number of addresses that you COULD get. In reality the sub-set
1218 	 * bound may have an exclusion list for a given TCB OR in the
1219 	 * bound-all case a TCB may NOT include the loopback or other
1220 	 * addresses as well.
1221 	 */
1222 	vrf = sctp_find_vrf(vrf_id);
1223 	if (vrf == NULL) {
1224 		return (0);
1225 	}
1226 	if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
1227 		struct sctp_ifn *sctp_ifn;
1228 		struct sctp_ifa *sctp_ifa;
1229 
1230 		LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
1231 			LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
1232 				/* Count them if they are the right type */
1233 				if (sctp_ifa->address.sa.sa_family == AF_INET) {
1234 					if (inp->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)
1235 						cnt += sizeof(struct sockaddr_in6);
1236 					else
1237 						cnt += sizeof(struct sockaddr_in);
1238 
1239 				} else if (sctp_ifa->address.sa.sa_family == AF_INET6)
1240 					cnt += sizeof(struct sockaddr_in6);
1241 			}
1242 		}
1243 	} else {
1244 		struct sctp_laddr *laddr;
1245 
1246 		LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
1247 			if (laddr->ifa->address.sa.sa_family == AF_INET) {
1248 				if (inp->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)
1249 					cnt += sizeof(struct sockaddr_in6);
1250 				else
1251 					cnt += sizeof(struct sockaddr_in);
1252 
1253 			} else if (laddr->ifa->address.sa.sa_family == AF_INET6)
1254 				cnt += sizeof(struct sockaddr_in6);
1255 		}
1256 	}
1257 	return (cnt);
1258 }
1259 
1260 static int
1261 sctp_count_max_addresses(struct sctp_inpcb *inp)
1262 {
1263 	int cnt = 0;
1264 
1265 	/* count addresses for the endpoint's default VRF */
1266 	cnt = sctp_count_max_addresses_vrf(inp, inp->def_vrf_id);
1267 	return (cnt);
1268 }
1269 
1270 static int
1271 sctp_do_connect_x(struct socket *so, struct sctp_inpcb *inp, void *optval,
1272     size_t optsize, void *p, int delay)
1273 {
1274 	int error = 0;
1275 	int creat_lock_on = 0;
1276 	struct sctp_tcb *stcb = NULL;
1277 	struct sockaddr *sa;
1278 	int num_v6 = 0, num_v4 = 0, *totaddrp, totaddr;
1279 	int added = 0;
1280 	uint32_t vrf_id;
1281 	int bad_addresses = 0;
1282 	sctp_assoc_t *a_id;
1283 
1284 	SCTPDBG(SCTP_DEBUG_PCB1, "Connectx called\n");
1285 
1286 	if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
1287 	    (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) {
1288 		/* We are already connected AND the TCP model */
1289 		return (EADDRINUSE);
1290 	}
1291 	if (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) {
1292 		return (EINVAL);
1293 	}
1294 	if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
1295 		SCTP_INP_RLOCK(inp);
1296 		stcb = LIST_FIRST(&inp->sctp_asoc_list);
1297 		SCTP_INP_RUNLOCK(inp);
1298 	}
1299 	if (stcb) {
1300 		return (EALREADY);
1301 	}
1302 	SCTP_INP_INCR_REF(inp);
1303 	SCTP_ASOC_CREATE_LOCK(inp);
1304 	creat_lock_on = 1;
1305 	if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
1306 	    (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) {
1307 		error = EFAULT;
1308 		goto out_now;
1309 	}
1310 	totaddrp = (int *)optval;
1311 	totaddr = *totaddrp;
1312 	sa = (struct sockaddr *)(totaddrp + 1);
1313 	stcb = sctp_connectx_helper_find(inp, sa, &totaddr, &num_v4, &num_v6, &error, (optsize - sizeof(int)), &bad_addresses);
1314 	if ((stcb != NULL) || bad_addresses) {
1315 		/* Already have or am bring up an association */
1316 		SCTP_ASOC_CREATE_UNLOCK(inp);
1317 		creat_lock_on = 0;
1318 		if (stcb)
1319 			SCTP_TCB_UNLOCK(stcb);
1320 		if (bad_addresses == 0)
1321 			error = EALREADY;
1322 		goto out_now;
1323 	}
1324 #ifdef INET6
1325 	if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) &&
1326 	    (num_v6 > 0)) {
1327 		error = EINVAL;
1328 		goto out_now;
1329 	}
1330 	if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
1331 	    (num_v4 > 0)) {
1332 		struct in6pcb *inp6;
1333 
1334 		inp6 = (struct in6pcb *)inp;
1335 		if (SCTP_IPV6_V6ONLY(inp6)) {
1336 			/*
1337 			 * if IPV6_V6ONLY flag, ignore connections destined
1338 			 * to a v4 addr or v4-mapped addr
1339 			 */
1340 			error = EINVAL;
1341 			goto out_now;
1342 		}
1343 	}
1344 #endif				/* INET6 */
1345 	if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) ==
1346 	    SCTP_PCB_FLAGS_UNBOUND) {
1347 		/* Bind a ephemeral port */
1348 		error = sctp_inpcb_bind(so, NULL, p);
1349 		if (error) {
1350 			goto out_now;
1351 		}
1352 	}
1353 	/* FIX ME: do we want to pass in a vrf on the connect call? */
1354 	vrf_id = inp->def_vrf_id;
1355 
1356 	/* We are GOOD to go */
1357 	stcb = sctp_aloc_assoc(inp, sa, 1, &error, 0, vrf_id);
1358 	if (stcb == NULL) {
1359 		/* Gak! no memory */
1360 		goto out_now;
1361 	}
1362 	stcb->asoc.state = SCTP_STATE_COOKIE_WAIT;
1363 	/* move to second address */
1364 	if (sa->sa_family == AF_INET)
1365 		sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in));
1366 	else
1367 		sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in6));
1368 
1369 	error = 0;
1370 	added = sctp_connectx_helper_add(stcb, sa, (totaddr - 1), &error);
1371 	/* Fill in the return id */
1372 	if (error) {
1373 		sctp_free_assoc(inp, stcb, SCTP_PCBFREE_FORCE, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_12);
1374 		goto out_now;
1375 	}
1376 	a_id = (sctp_assoc_t *) optval;
1377 	*a_id = sctp_get_associd(stcb);
1378 
1379 	/* initialize authentication parameters for the assoc */
1380 	sctp_initialize_auth_params(inp, stcb);
1381 
1382 	if (delay) {
1383 		/* doing delayed connection */
1384 		stcb->asoc.delayed_connection = 1;
1385 		sctp_timer_start(SCTP_TIMER_TYPE_INIT, inp, stcb, stcb->asoc.primary_destination);
1386 	} else {
1387 		(void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered);
1388 		sctp_send_initiate(inp, stcb);
1389 	}
1390 	SCTP_TCB_UNLOCK(stcb);
1391 	if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) {
1392 		stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED;
1393 		/* Set the connected flag so we can queue data */
1394 		soisconnecting(so);
1395 	}
1396 out_now:
1397 	if (creat_lock_on) {
1398 		SCTP_ASOC_CREATE_UNLOCK(inp);
1399 	}
1400 	SCTP_INP_DECR_REF(inp);
1401 	return error;
1402 }
1403 
1404 #define SCTP_FIND_STCB(inp, stcb, assoc_id) { \
1405 	if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||\
1406 	    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) { \
1407 		SCTP_INP_RLOCK(inp); \
1408 		stcb = LIST_FIRST(&inp->sctp_asoc_list); \
1409 		if (stcb) { \
1410 			SCTP_TCB_LOCK(stcb); \
1411                 } \
1412 		SCTP_INP_RUNLOCK(inp); \
1413 	} else if (assoc_id != 0) { \
1414 		stcb = sctp_findassociation_ep_asocid(inp, assoc_id, 1); \
1415 		if (stcb == NULL) { \
1416 			error = ENOENT; \
1417 			break; \
1418 		} \
1419 	} else { \
1420 		stcb = NULL; \
1421         } \
1422   }
1423 
1424 
1425 #define SCTP_CHECK_AND_CAST(destp, srcp, type, size)  {\
1426 	if (size < sizeof(type)) { \
1427 		error = EINVAL; \
1428 		break; \
1429 	} else { \
1430 		destp = (type *)srcp; \
1431 	} \
1432       }
1433 
1434 static int
1435 sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
1436     void *p)
1437 {
1438 	struct sctp_inpcb *inp;
1439 	int error, val = 0;
1440 	struct sctp_tcb *stcb = NULL;
1441 
1442 	if (optval == NULL) {
1443 		return (EINVAL);
1444 	}
1445 	inp = (struct sctp_inpcb *)so->so_pcb;
1446 	if (inp == 0)
1447 		return EINVAL;
1448 	error = 0;
1449 
1450 	switch (optname) {
1451 	case SCTP_NODELAY:
1452 	case SCTP_AUTOCLOSE:
1453 	case SCTP_EXPLICIT_EOR:
1454 	case SCTP_AUTO_ASCONF:
1455 	case SCTP_DISABLE_FRAGMENTS:
1456 	case SCTP_I_WANT_MAPPED_V4_ADDR:
1457 	case SCTP_USE_EXT_RCVINFO:
1458 		SCTP_INP_RLOCK(inp);
1459 		switch (optname) {
1460 		case SCTP_DISABLE_FRAGMENTS:
1461 			val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NO_FRAGMENT);
1462 			break;
1463 		case SCTP_I_WANT_MAPPED_V4_ADDR:
1464 			val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4);
1465 			break;
1466 		case SCTP_AUTO_ASCONF:
1467 			val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTO_ASCONF);
1468 			break;
1469 		case SCTP_EXPLICIT_EOR:
1470 			val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXPLICIT_EOR);
1471 			break;
1472 		case SCTP_NODELAY:
1473 			val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NODELAY);
1474 			break;
1475 		case SCTP_USE_EXT_RCVINFO:
1476 			val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXT_RCVINFO);
1477 			break;
1478 		case SCTP_AUTOCLOSE:
1479 			if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTOCLOSE))
1480 				val = TICKS_TO_SEC(inp->sctp_ep.auto_close_time);
1481 			else
1482 				val = 0;
1483 			break;
1484 
1485 		default:
1486 			error = ENOPROTOOPT;
1487 		}		/* end switch (sopt->sopt_name) */
1488 		if (optname != SCTP_AUTOCLOSE) {
1489 			/* make it an "on/off" value */
1490 			val = (val != 0);
1491 		}
1492 		if (*optsize < sizeof(val)) {
1493 			error = EINVAL;
1494 		}
1495 		SCTP_INP_RUNLOCK(inp);
1496 		if (error == 0) {
1497 			/* return the option value */
1498 			*(int *)optval = val;
1499 			*optsize = sizeof(val);
1500 		}
1501 		break;
1502 	case SCTP_GET_PACKET_LOG:
1503 		{
1504 #ifdef  SCTP_PACKET_LOGGING
1505 			uint8_t *target;
1506 			int ret;
1507 
1508 			SCTP_CHECK_AND_CAST(target, optval, uint8_t, *optsize);
1509 			ret = sctp_copy_out_packet_log(target, (int)*optsize);
1510 			*optsize = ret;
1511 #else
1512 			error = EOPNOTSUPP;
1513 #endif
1514 			break;
1515 		}
1516 	case SCTP_PARTIAL_DELIVERY_POINT:
1517 		{
1518 			uint32_t *value;
1519 
1520 			SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize);
1521 			*value = inp->partial_delivery_point;
1522 			*optsize = sizeof(uint32_t);
1523 		}
1524 		break;
1525 	case SCTP_FRAGMENT_INTERLEAVE:
1526 		{
1527 			uint32_t *value;
1528 
1529 			SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize);
1530 			if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE)) {
1531 				if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS)) {
1532 					*value = SCTP_FRAG_LEVEL_2;
1533 				} else {
1534 					*value = SCTP_FRAG_LEVEL_1;
1535 				}
1536 			} else {
1537 				*value = SCTP_FRAG_LEVEL_0;
1538 			}
1539 			*optsize = sizeof(uint32_t);
1540 		}
1541 		break;
1542 	case SCTP_CMT_ON_OFF:
1543 		{
1544 			struct sctp_assoc_value *av;
1545 
1546 			SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
1547 			if (sctp_cmt_on_off) {
1548 				SCTP_FIND_STCB(inp, stcb, av->assoc_id);
1549 				if (stcb) {
1550 					av->assoc_value = stcb->asoc.sctp_cmt_on_off;
1551 					SCTP_TCB_UNLOCK(stcb);
1552 
1553 				} else {
1554 					error = ENOTCONN;
1555 				}
1556 			} else {
1557 				error = ENOPROTOOPT;
1558 			}
1559 			*optsize = sizeof(*av);
1560 		}
1561 		break;
1562 		/* JRS - Get socket option for pluggable congestion control */
1563 	case SCTP_PLUGGABLE_CC:
1564 		{
1565 			struct sctp_assoc_value *av;
1566 
1567 			SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
1568 			SCTP_FIND_STCB(inp, stcb, av->assoc_id);
1569 			if (stcb) {
1570 				av->assoc_value = stcb->asoc.congestion_control_module;
1571 				SCTP_TCB_UNLOCK(stcb);
1572 			} else {
1573 				av->assoc_value = inp->sctp_ep.sctp_default_cc_module;
1574 			}
1575 			*optsize = sizeof(*av);
1576 		}
1577 		break;
1578 	case SCTP_GET_ADDR_LEN:
1579 		{
1580 			struct sctp_assoc_value *av;
1581 
1582 			SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
1583 			error = EINVAL;
1584 #ifdef INET
1585 			if (av->assoc_value == AF_INET) {
1586 				av->assoc_value = sizeof(struct sockaddr_in);
1587 				error = 0;
1588 			}
1589 #endif
1590 #ifdef INET6
1591 			if (av->assoc_value == AF_INET6) {
1592 				av->assoc_value = sizeof(struct sockaddr_in6);
1593 				error = 0;
1594 			}
1595 #endif
1596 			*optsize = sizeof(*av);
1597 		}
1598 		break;
1599 	case SCTP_GET_ASSOC_NUMBER:
1600 		{
1601 			uint32_t *value, cnt;
1602 
1603 			SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize);
1604 			cnt = 0;
1605 			SCTP_INP_RLOCK(inp);
1606 			LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
1607 				cnt++;
1608 			}
1609 			SCTP_INP_RUNLOCK(inp);
1610 			*value = cnt;
1611 			*optsize = sizeof(uint32_t);
1612 		}
1613 		break;
1614 
1615 	case SCTP_GET_ASSOC_ID_LIST:
1616 		{
1617 			struct sctp_assoc_ids *ids;
1618 			unsigned int at, limit;
1619 
1620 			SCTP_CHECK_AND_CAST(ids, optval, struct sctp_assoc_ids, *optsize);
1621 			at = 0;
1622 			limit = *optsize / sizeof(sctp_assoc_t);
1623 			SCTP_INP_RLOCK(inp);
1624 			LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
1625 				if (at < limit) {
1626 					ids->gaids_assoc_id[at++] = sctp_get_associd(stcb);
1627 				} else {
1628 					error = EINVAL;
1629 					break;
1630 				}
1631 			}
1632 			SCTP_INP_RUNLOCK(inp);
1633 			*optsize = at * sizeof(sctp_assoc_t);
1634 		}
1635 		break;
1636 	case SCTP_CONTEXT:
1637 		{
1638 			struct sctp_assoc_value *av;
1639 
1640 			SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
1641 			SCTP_FIND_STCB(inp, stcb, av->assoc_id);
1642 
1643 			if (stcb) {
1644 				av->assoc_value = stcb->asoc.context;
1645 				SCTP_TCB_UNLOCK(stcb);
1646 			} else {
1647 				SCTP_INP_RLOCK(inp);
1648 				av->assoc_value = inp->sctp_context;
1649 				SCTP_INP_RUNLOCK(inp);
1650 			}
1651 			*optsize = sizeof(*av);
1652 		}
1653 		break;
1654 	case SCTP_VRF_ID:
1655 		{
1656 			uint32_t *default_vrfid;
1657 
1658 			SCTP_CHECK_AND_CAST(default_vrfid, optval, uint32_t, *optsize);
1659 			*default_vrfid = inp->def_vrf_id;
1660 			break;
1661 		}
1662 	case SCTP_GET_ASOC_VRF:
1663 		{
1664 			struct sctp_assoc_value *id;
1665 
1666 			SCTP_CHECK_AND_CAST(id, optval, struct sctp_assoc_value, *optsize);
1667 			SCTP_FIND_STCB(inp, stcb, id->assoc_id);
1668 			if (stcb == NULL) {
1669 				error = EINVAL;
1670 				break;
1671 			}
1672 			id->assoc_value = stcb->asoc.vrf_id;
1673 			break;
1674 		}
1675 	case SCTP_GET_VRF_IDS:
1676 		{
1677 			error = EOPNOTSUPP;
1678 			break;
1679 		}
1680 	case SCTP_GET_NONCE_VALUES:
1681 		{
1682 			struct sctp_get_nonce_values *gnv;
1683 
1684 			SCTP_CHECK_AND_CAST(gnv, optval, struct sctp_get_nonce_values, *optsize);
1685 			SCTP_FIND_STCB(inp, stcb, gnv->gn_assoc_id);
1686 
1687 			if (stcb) {
1688 				gnv->gn_peers_tag = stcb->asoc.peer_vtag;
1689 				gnv->gn_local_tag = stcb->asoc.my_vtag;
1690 				SCTP_TCB_UNLOCK(stcb);
1691 			} else {
1692 				error = ENOTCONN;
1693 			}
1694 			*optsize = sizeof(*gnv);
1695 		}
1696 		break;
1697 	case SCTP_DELAYED_SACK:
1698 		{
1699 			struct sctp_sack_info *sack;
1700 
1701 			SCTP_CHECK_AND_CAST(sack, optval, struct sctp_sack_info, *optsize);
1702 			SCTP_FIND_STCB(inp, stcb, sack->sack_assoc_id);
1703 			if (stcb) {
1704 				sack->sack_delay = stcb->asoc.delayed_ack;
1705 				sack->sack_freq = stcb->asoc.sack_freq;
1706 				SCTP_TCB_UNLOCK(stcb);
1707 			} else {
1708 				SCTP_INP_RLOCK(inp);
1709 				sack->sack_delay = TICKS_TO_MSEC(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV]);
1710 				sack->sack_freq = inp->sctp_ep.sctp_sack_freq;
1711 				SCTP_INP_RUNLOCK(inp);
1712 			}
1713 			*optsize = sizeof(*sack);
1714 		}
1715 		break;
1716 
1717 	case SCTP_GET_SNDBUF_USE:
1718 		{
1719 			struct sctp_sockstat *ss;
1720 
1721 			SCTP_CHECK_AND_CAST(ss, optval, struct sctp_sockstat, *optsize);
1722 			SCTP_FIND_STCB(inp, stcb, ss->ss_assoc_id);
1723 
1724 			if (stcb) {
1725 				ss->ss_total_sndbuf = stcb->asoc.total_output_queue_size;
1726 				ss->ss_total_recv_buf = (stcb->asoc.size_on_reasm_queue +
1727 				    stcb->asoc.size_on_all_streams);
1728 				SCTP_TCB_UNLOCK(stcb);
1729 			} else {
1730 				error = ENOTCONN;
1731 			}
1732 			*optsize = sizeof(struct sctp_sockstat);
1733 		}
1734 		break;
1735 	case SCTP_MAX_BURST:
1736 		{
1737 			uint8_t *value;
1738 
1739 			SCTP_CHECK_AND_CAST(value, optval, uint8_t, *optsize);
1740 
1741 			SCTP_INP_RLOCK(inp);
1742 			*value = inp->sctp_ep.max_burst;
1743 			SCTP_INP_RUNLOCK(inp);
1744 			*optsize = sizeof(uint8_t);
1745 		}
1746 		break;
1747 	case SCTP_MAXSEG:
1748 		{
1749 			struct sctp_assoc_value *av;
1750 			int ovh;
1751 
1752 			SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
1753 			SCTP_FIND_STCB(inp, stcb, av->assoc_id);
1754 
1755 			if (stcb) {
1756 				av->assoc_value = sctp_get_frag_point(stcb, &stcb->asoc);
1757 				SCTP_TCB_UNLOCK(stcb);
1758 			} else {
1759 				SCTP_INP_RLOCK(inp);
1760 				if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
1761 					ovh = SCTP_MED_OVERHEAD;
1762 				} else {
1763 					ovh = SCTP_MED_V4_OVERHEAD;
1764 				}
1765 				if (inp->sctp_frag_point >= SCTP_DEFAULT_MAXSEGMENT)
1766 					av->assoc_value = 0;
1767 				else
1768 					av->assoc_value = inp->sctp_frag_point - ovh;
1769 				SCTP_INP_RUNLOCK(inp);
1770 			}
1771 			*optsize = sizeof(struct sctp_assoc_value);
1772 		}
1773 		break;
1774 	case SCTP_GET_STAT_LOG:
1775 		error = sctp_fill_stat_log(optval, optsize);
1776 		break;
1777 	case SCTP_EVENTS:
1778 		{
1779 			struct sctp_event_subscribe *events;
1780 
1781 			SCTP_CHECK_AND_CAST(events, optval, struct sctp_event_subscribe, *optsize);
1782 			memset(events, 0, sizeof(*events));
1783 			SCTP_INP_RLOCK(inp);
1784 			if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT))
1785 				events->sctp_data_io_event = 1;
1786 
1787 			if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVASSOCEVNT))
1788 				events->sctp_association_event = 1;
1789 
1790 			if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVPADDREVNT))
1791 				events->sctp_address_event = 1;
1792 
1793 			if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVSENDFAILEVNT))
1794 				events->sctp_send_failure_event = 1;
1795 
1796 			if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVPEERERR))
1797 				events->sctp_peer_error_event = 1;
1798 
1799 			if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT))
1800 				events->sctp_shutdown_event = 1;
1801 
1802 			if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PDAPIEVNT))
1803 				events->sctp_partial_delivery_event = 1;
1804 
1805 			if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_ADAPTATIONEVNT))
1806 				events->sctp_adaptation_layer_event = 1;
1807 
1808 			if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTHEVNT))
1809 				events->sctp_authentication_event = 1;
1810 
1811 			if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_STREAM_RESETEVNT))
1812 				events->sctp_stream_reset_events = 1;
1813 			SCTP_INP_RUNLOCK(inp);
1814 			*optsize = sizeof(struct sctp_event_subscribe);
1815 		}
1816 		break;
1817 
1818 	case SCTP_ADAPTATION_LAYER:
1819 		{
1820 			uint32_t *value;
1821 
1822 			SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize);
1823 
1824 			SCTP_INP_RLOCK(inp);
1825 			*value = inp->sctp_ep.adaptation_layer_indicator;
1826 			SCTP_INP_RUNLOCK(inp);
1827 			*optsize = sizeof(uint32_t);
1828 		}
1829 		break;
1830 	case SCTP_SET_INITIAL_DBG_SEQ:
1831 		{
1832 			uint32_t *value;
1833 
1834 			SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize);
1835 			SCTP_INP_RLOCK(inp);
1836 			*value = inp->sctp_ep.initial_sequence_debug;
1837 			SCTP_INP_RUNLOCK(inp);
1838 			*optsize = sizeof(uint32_t);
1839 		}
1840 		break;
1841 	case SCTP_GET_LOCAL_ADDR_SIZE:
1842 		{
1843 			uint32_t *value;
1844 
1845 			SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize);
1846 			SCTP_INP_RLOCK(inp);
1847 			*value = sctp_count_max_addresses(inp);
1848 			SCTP_INP_RUNLOCK(inp);
1849 			*optsize = sizeof(uint32_t);
1850 		}
1851 		break;
1852 	case SCTP_GET_REMOTE_ADDR_SIZE:
1853 		{
1854 			uint32_t *value;
1855 			size_t size;
1856 			struct sctp_nets *net;
1857 
1858 			SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize);
1859 			/* FIXME MT: change to sctp_assoc_value? */
1860 			SCTP_FIND_STCB(inp, stcb, (sctp_assoc_t) * value);
1861 
1862 			if (stcb) {
1863 				size = 0;
1864 				/* Count the sizes */
1865 				TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
1866 					if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) ||
1867 					    (((struct sockaddr *)&net->ro._l_addr)->sa_family == AF_INET6)) {
1868 						size += sizeof(struct sockaddr_in6);
1869 					} else if (((struct sockaddr *)&net->ro._l_addr)->sa_family == AF_INET) {
1870 						size += sizeof(struct sockaddr_in);
1871 					} else {
1872 						/* huh */
1873 						break;
1874 					}
1875 				}
1876 				SCTP_TCB_UNLOCK(stcb);
1877 				*value = (uint32_t) size;
1878 			} else {
1879 				error = ENOTCONN;
1880 			}
1881 			*optsize = sizeof(uint32_t);
1882 		}
1883 		break;
1884 	case SCTP_GET_PEER_ADDRESSES:
1885 		/*
1886 		 * Get the address information, an array is passed in to
1887 		 * fill up we pack it.
1888 		 */
1889 		{
1890 			size_t cpsz, left;
1891 			struct sockaddr_storage *sas;
1892 			struct sctp_nets *net;
1893 			struct sctp_getaddresses *saddr;
1894 
1895 			SCTP_CHECK_AND_CAST(saddr, optval, struct sctp_getaddresses, *optsize);
1896 			SCTP_FIND_STCB(inp, stcb, saddr->sget_assoc_id);
1897 
1898 			if (stcb) {
1899 				left = (*optsize) - sizeof(struct sctp_getaddresses);
1900 				*optsize = sizeof(struct sctp_getaddresses);
1901 				sas = (struct sockaddr_storage *)&saddr->addr[0];
1902 
1903 				TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
1904 					if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) ||
1905 					    (((struct sockaddr *)&net->ro._l_addr)->sa_family == AF_INET6)) {
1906 						cpsz = sizeof(struct sockaddr_in6);
1907 					} else if (((struct sockaddr *)&net->ro._l_addr)->sa_family == AF_INET) {
1908 						cpsz = sizeof(struct sockaddr_in);
1909 					} else {
1910 						/* huh */
1911 						break;
1912 					}
1913 					if (left < cpsz) {
1914 						/* not enough room. */
1915 						break;
1916 					}
1917 					if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
1918 					    (((struct sockaddr *)&net->ro._l_addr)->sa_family == AF_INET)) {
1919 						/* Must map the address */
1920 						in6_sin_2_v4mapsin6((struct sockaddr_in *)&net->ro._l_addr,
1921 						    (struct sockaddr_in6 *)sas);
1922 					} else {
1923 						memcpy(sas, &net->ro._l_addr, cpsz);
1924 					}
1925 					((struct sockaddr_in *)sas)->sin_port = stcb->rport;
1926 
1927 					sas = (struct sockaddr_storage *)((caddr_t)sas + cpsz);
1928 					left -= cpsz;
1929 					*optsize += cpsz;
1930 				}
1931 				SCTP_TCB_UNLOCK(stcb);
1932 			} else {
1933 				error = ENOENT;
1934 			}
1935 		}
1936 		break;
1937 	case SCTP_GET_LOCAL_ADDRESSES:
1938 		{
1939 			size_t limit, actual;
1940 			struct sockaddr_storage *sas;
1941 			struct sctp_getaddresses *saddr;
1942 
1943 			SCTP_CHECK_AND_CAST(saddr, optval, struct sctp_getaddresses, *optsize);
1944 			SCTP_FIND_STCB(inp, stcb, saddr->sget_assoc_id);
1945 
1946 			sas = (struct sockaddr_storage *)&saddr->addr[0];
1947 			limit = *optsize - sizeof(sctp_assoc_t);
1948 			actual = sctp_fill_up_addresses(inp, stcb, limit, sas);
1949 			if (stcb) {
1950 				SCTP_TCB_UNLOCK(stcb);
1951 			}
1952 			*optsize = sizeof(struct sockaddr_storage) + actual;
1953 		}
1954 		break;
1955 	case SCTP_PEER_ADDR_PARAMS:
1956 		{
1957 			struct sctp_paddrparams *paddrp;
1958 			struct sctp_nets *net;
1959 
1960 			SCTP_CHECK_AND_CAST(paddrp, optval, struct sctp_paddrparams, *optsize);
1961 			SCTP_FIND_STCB(inp, stcb, paddrp->spp_assoc_id);
1962 
1963 			net = NULL;
1964 			if (stcb) {
1965 				net = sctp_findnet(stcb, (struct sockaddr *)&paddrp->spp_address);
1966 			} else {
1967 				/*
1968 				 * We increment here since
1969 				 * sctp_findassociation_ep_addr() wil do a
1970 				 * decrement if it finds the stcb as long as
1971 				 * the locked tcb (last argument) is NOT a
1972 				 * TCB.. aka NULL.
1973 				 */
1974 				SCTP_INP_INCR_REF(inp);
1975 				stcb = sctp_findassociation_ep_addr(&inp, (struct sockaddr *)&paddrp->spp_address, &net, NULL, NULL);
1976 				if (stcb == NULL) {
1977 					SCTP_INP_DECR_REF(inp);
1978 				}
1979 			}
1980 
1981 			if (stcb) {
1982 				/* Applys to the specific association */
1983 				paddrp->spp_flags = 0;
1984 				if (net) {
1985 					int ovh;
1986 
1987 					if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
1988 						ovh = SCTP_MED_OVERHEAD;
1989 					} else {
1990 						ovh = SCTP_MED_V4_OVERHEAD;
1991 					}
1992 
1993 
1994 					paddrp->spp_pathmaxrxt = net->failure_threshold;
1995 					paddrp->spp_pathmtu = net->mtu - ovh;
1996 					/* get flags for HB */
1997 					if (net->dest_state & SCTP_ADDR_NOHB)
1998 						paddrp->spp_flags |= SPP_HB_DISABLE;
1999 					else
2000 						paddrp->spp_flags |= SPP_HB_ENABLE;
2001 					/* get flags for PMTU */
2002 					if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
2003 						paddrp->spp_flags |= SPP_PMTUD_ENABLE;
2004 					} else {
2005 						paddrp->spp_flags |= SPP_PMTUD_DISABLE;
2006 					}
2007 #ifdef INET
2008 					if (net->ro._l_addr.sin.sin_family == AF_INET) {
2009 						paddrp->spp_ipv4_tos = net->tos_flowlabel & 0x000000fc;
2010 						paddrp->spp_flags |= SPP_IPV4_TOS;
2011 					}
2012 #endif
2013 #ifdef INET6
2014 					if (net->ro._l_addr.sin6.sin6_family == AF_INET6) {
2015 						paddrp->spp_ipv6_flowlabel = net->tos_flowlabel;
2016 						paddrp->spp_flags |= SPP_IPV6_FLOWLABEL;
2017 					}
2018 #endif
2019 				} else {
2020 					/*
2021 					 * No destination so return default
2022 					 * value
2023 					 */
2024 					int cnt = 0;
2025 
2026 					paddrp->spp_pathmaxrxt = stcb->asoc.def_net_failure;
2027 					paddrp->spp_pathmtu = sctp_get_frag_point(stcb, &stcb->asoc);
2028 #ifdef INET
2029 					paddrp->spp_ipv4_tos = stcb->asoc.default_tos & 0x000000fc;
2030 					paddrp->spp_flags |= SPP_IPV4_TOS;
2031 #endif
2032 #ifdef INET6
2033 					paddrp->spp_ipv6_flowlabel = stcb->asoc.default_flowlabel;
2034 					paddrp->spp_flags |= SPP_IPV6_FLOWLABEL;
2035 #endif
2036 					/* default settings should be these */
2037 					if (stcb->asoc.hb_is_disabled == 0) {
2038 						paddrp->spp_flags |= SPP_HB_ENABLE;
2039 					} else {
2040 						paddrp->spp_flags |= SPP_HB_DISABLE;
2041 					}
2042 					TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
2043 						if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
2044 							cnt++;
2045 						}
2046 					}
2047 					if (cnt) {
2048 						paddrp->spp_flags |= SPP_PMTUD_ENABLE;
2049 					}
2050 				}
2051 				paddrp->spp_hbinterval = stcb->asoc.heart_beat_delay;
2052 				paddrp->spp_assoc_id = sctp_get_associd(stcb);
2053 				SCTP_TCB_UNLOCK(stcb);
2054 			} else {
2055 				/* Use endpoint defaults */
2056 				SCTP_INP_RLOCK(inp);
2057 				paddrp->spp_pathmaxrxt = inp->sctp_ep.def_net_failure;
2058 				paddrp->spp_hbinterval = TICKS_TO_MSEC(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]);
2059 				paddrp->spp_assoc_id = (sctp_assoc_t) 0;
2060 				/* get inp's default */
2061 #ifdef INET
2062 				paddrp->spp_ipv4_tos = inp->ip_inp.inp.inp_ip_tos;
2063 				paddrp->spp_flags |= SPP_IPV4_TOS;
2064 #endif
2065 #ifdef INET6
2066 				if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
2067 					paddrp->spp_ipv6_flowlabel = ((struct in6pcb *)inp)->in6p_flowinfo;
2068 					paddrp->spp_flags |= SPP_IPV6_FLOWLABEL;
2069 				}
2070 #endif
2071 				/* can't return this */
2072 				paddrp->spp_pathmtu = 0;
2073 
2074 				/* default behavior, no stcb */
2075 				paddrp->spp_flags = SPP_PMTUD_ENABLE;
2076 
2077 				if (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_DONOT_HEARTBEAT)) {
2078 					paddrp->spp_flags |= SPP_HB_ENABLE;
2079 				} else {
2080 					paddrp->spp_flags |= SPP_HB_DISABLE;
2081 				}
2082 				SCTP_INP_RUNLOCK(inp);
2083 			}
2084 			*optsize = sizeof(struct sctp_paddrparams);
2085 		}
2086 		break;
2087 	case SCTP_GET_PEER_ADDR_INFO:
2088 		{
2089 			struct sctp_paddrinfo *paddri;
2090 			struct sctp_nets *net;
2091 
2092 			SCTP_CHECK_AND_CAST(paddri, optval, struct sctp_paddrinfo, *optsize);
2093 			SCTP_FIND_STCB(inp, stcb, paddri->spinfo_assoc_id);
2094 
2095 			net = NULL;
2096 			if (stcb) {
2097 				net = sctp_findnet(stcb, (struct sockaddr *)&paddri->spinfo_address);
2098 			} else {
2099 				/*
2100 				 * We increment here since
2101 				 * sctp_findassociation_ep_addr() wil do a
2102 				 * decrement if it finds the stcb as long as
2103 				 * the locked tcb (last argument) is NOT a
2104 				 * TCB.. aka NULL.
2105 				 */
2106 				SCTP_INP_INCR_REF(inp);
2107 				stcb = sctp_findassociation_ep_addr(&inp, (struct sockaddr *)&paddri->spinfo_address, &net, NULL, NULL);
2108 				if (stcb == NULL) {
2109 					SCTP_INP_DECR_REF(inp);
2110 				}
2111 			}
2112 
2113 			if ((stcb) && (net)) {
2114 				paddri->spinfo_state = net->dest_state & (SCTP_REACHABLE_MASK | SCTP_ADDR_NOHB);
2115 				paddri->spinfo_cwnd = net->cwnd;
2116 				paddri->spinfo_srtt = ((net->lastsa >> 2) + net->lastsv) >> 1;
2117 				paddri->spinfo_rto = net->RTO;
2118 				paddri->spinfo_assoc_id = sctp_get_associd(stcb);
2119 				SCTP_TCB_UNLOCK(stcb);
2120 			} else {
2121 				if (stcb) {
2122 					SCTP_TCB_UNLOCK(stcb);
2123 				}
2124 				error = ENOENT;
2125 			}
2126 			*optsize = sizeof(struct sctp_paddrinfo);
2127 		}
2128 		break;
2129 	case SCTP_PCB_STATUS:
2130 		{
2131 			struct sctp_pcbinfo *spcb;
2132 
2133 			SCTP_CHECK_AND_CAST(spcb, optval, struct sctp_pcbinfo, *optsize);
2134 			sctp_fill_pcbinfo(spcb);
2135 			*optsize = sizeof(struct sctp_pcbinfo);
2136 		}
2137 		break;
2138 
2139 	case SCTP_STATUS:
2140 		{
2141 			struct sctp_nets *net;
2142 			struct sctp_status *sstat;
2143 
2144 			SCTP_CHECK_AND_CAST(sstat, optval, struct sctp_status, *optsize);
2145 			SCTP_FIND_STCB(inp, stcb, sstat->sstat_assoc_id);
2146 
2147 			if (stcb == NULL) {
2148 				error = EINVAL;
2149 				break;
2150 			}
2151 			/*
2152 			 * I think passing the state is fine since
2153 			 * sctp_constants.h will be available to the user
2154 			 * land.
2155 			 */
2156 			sstat->sstat_state = stcb->asoc.state;
2157 			sstat->sstat_rwnd = stcb->asoc.peers_rwnd;
2158 			sstat->sstat_unackdata = stcb->asoc.sent_queue_cnt;
2159 			/*
2160 			 * We can't include chunks that have been passed to
2161 			 * the socket layer. Only things in queue.
2162 			 */
2163 			sstat->sstat_penddata = (stcb->asoc.cnt_on_reasm_queue +
2164 			    stcb->asoc.cnt_on_all_streams);
2165 
2166 
2167 			sstat->sstat_instrms = stcb->asoc.streamincnt;
2168 			sstat->sstat_outstrms = stcb->asoc.streamoutcnt;
2169 			sstat->sstat_fragmentation_point = sctp_get_frag_point(stcb, &stcb->asoc);
2170 			memcpy(&sstat->sstat_primary.spinfo_address,
2171 			    &stcb->asoc.primary_destination->ro._l_addr,
2172 			    ((struct sockaddr *)(&stcb->asoc.primary_destination->ro._l_addr))->sa_len);
2173 			net = stcb->asoc.primary_destination;
2174 			((struct sockaddr_in *)&sstat->sstat_primary.spinfo_address)->sin_port = stcb->rport;
2175 			/*
2176 			 * Again the user can get info from sctp_constants.h
2177 			 * for what the state of the network is.
2178 			 */
2179 			sstat->sstat_primary.spinfo_state = net->dest_state & SCTP_REACHABLE_MASK;
2180 			sstat->sstat_primary.spinfo_cwnd = net->cwnd;
2181 			sstat->sstat_primary.spinfo_srtt = net->lastsa;
2182 			sstat->sstat_primary.spinfo_rto = net->RTO;
2183 			sstat->sstat_primary.spinfo_mtu = net->mtu;
2184 			sstat->sstat_primary.spinfo_assoc_id = sctp_get_associd(stcb);
2185 			SCTP_TCB_UNLOCK(stcb);
2186 			*optsize = sizeof(*sstat);
2187 		}
2188 		break;
2189 	case SCTP_RTOINFO:
2190 		{
2191 			struct sctp_rtoinfo *srto;
2192 
2193 			SCTP_CHECK_AND_CAST(srto, optval, struct sctp_rtoinfo, *optsize);
2194 			SCTP_FIND_STCB(inp, stcb, srto->srto_assoc_id);
2195 
2196 			if (stcb) {
2197 				srto->srto_initial = stcb->asoc.initial_rto;
2198 				srto->srto_max = stcb->asoc.maxrto;
2199 				srto->srto_min = stcb->asoc.minrto;
2200 				SCTP_TCB_UNLOCK(stcb);
2201 			} else {
2202 				SCTP_INP_RLOCK(inp);
2203 				srto->srto_initial = inp->sctp_ep.initial_rto;
2204 				srto->srto_max = inp->sctp_ep.sctp_maxrto;
2205 				srto->srto_min = inp->sctp_ep.sctp_minrto;
2206 				SCTP_INP_RUNLOCK(inp);
2207 			}
2208 			*optsize = sizeof(*srto);
2209 		}
2210 		break;
2211 	case SCTP_ASSOCINFO:
2212 		{
2213 			struct sctp_assocparams *sasoc;
2214 			uint32_t oldval;
2215 
2216 			SCTP_CHECK_AND_CAST(sasoc, optval, struct sctp_assocparams, *optsize);
2217 			SCTP_FIND_STCB(inp, stcb, sasoc->sasoc_assoc_id);
2218 
2219 			if (stcb) {
2220 				oldval = sasoc->sasoc_cookie_life;
2221 				sasoc->sasoc_cookie_life = TICKS_TO_MSEC(stcb->asoc.cookie_life);
2222 				sasoc->sasoc_asocmaxrxt = stcb->asoc.max_send_times;
2223 				sasoc->sasoc_number_peer_destinations = stcb->asoc.numnets;
2224 				sasoc->sasoc_peer_rwnd = stcb->asoc.peers_rwnd;
2225 				sasoc->sasoc_local_rwnd = stcb->asoc.my_rwnd;
2226 				SCTP_TCB_UNLOCK(stcb);
2227 			} else {
2228 				SCTP_INP_RLOCK(inp);
2229 				sasoc->sasoc_cookie_life = TICKS_TO_MSEC(inp->sctp_ep.def_cookie_life);
2230 				sasoc->sasoc_asocmaxrxt = inp->sctp_ep.max_send_times;
2231 				sasoc->sasoc_number_peer_destinations = 0;
2232 				sasoc->sasoc_peer_rwnd = 0;
2233 				sasoc->sasoc_local_rwnd = sbspace(&inp->sctp_socket->so_rcv);
2234 				SCTP_INP_RUNLOCK(inp);
2235 			}
2236 			*optsize = sizeof(*sasoc);
2237 		}
2238 		break;
2239 	case SCTP_DEFAULT_SEND_PARAM:
2240 		{
2241 			struct sctp_sndrcvinfo *s_info;
2242 
2243 			SCTP_CHECK_AND_CAST(s_info, optval, struct sctp_sndrcvinfo, *optsize);
2244 			SCTP_FIND_STCB(inp, stcb, s_info->sinfo_assoc_id);
2245 
2246 			if (stcb) {
2247 				memcpy(s_info, &stcb->asoc.def_send, sizeof(stcb->asoc.def_send));
2248 				SCTP_TCB_UNLOCK(stcb);
2249 			} else {
2250 				SCTP_INP_RLOCK(inp);
2251 				memcpy(s_info, &inp->def_send, sizeof(inp->def_send));
2252 				SCTP_INP_RUNLOCK(inp);
2253 			}
2254 			*optsize = sizeof(*s_info);
2255 		}
2256 		break;
2257 	case SCTP_INITMSG:
2258 		{
2259 			struct sctp_initmsg *sinit;
2260 
2261 			SCTP_CHECK_AND_CAST(sinit, optval, struct sctp_initmsg, *optsize);
2262 			SCTP_INP_RLOCK(inp);
2263 			sinit->sinit_num_ostreams = inp->sctp_ep.pre_open_stream_count;
2264 			sinit->sinit_max_instreams = inp->sctp_ep.max_open_streams_intome;
2265 			sinit->sinit_max_attempts = inp->sctp_ep.max_init_times;
2266 			sinit->sinit_max_init_timeo = inp->sctp_ep.initial_init_rto_max;
2267 			SCTP_INP_RUNLOCK(inp);
2268 			*optsize = sizeof(*sinit);
2269 		}
2270 		break;
2271 	case SCTP_PRIMARY_ADDR:
2272 		/* we allow a "get" operation on this */
2273 		{
2274 			struct sctp_setprim *ssp;
2275 
2276 			SCTP_CHECK_AND_CAST(ssp, optval, struct sctp_setprim, *optsize);
2277 			SCTP_FIND_STCB(inp, stcb, ssp->ssp_assoc_id);
2278 
2279 			if (stcb) {
2280 				/* simply copy out the sockaddr_storage... */
2281 				int len;
2282 
2283 				len = *optsize;
2284 				if (len > stcb->asoc.primary_destination->ro._l_addr.sa.sa_len)
2285 					len = stcb->asoc.primary_destination->ro._l_addr.sa.sa_len;
2286 
2287 				memcpy(&ssp->ssp_addr,
2288 				    &stcb->asoc.primary_destination->ro._l_addr,
2289 				    len);
2290 				SCTP_TCB_UNLOCK(stcb);
2291 			} else {
2292 				error = EINVAL;
2293 			}
2294 			*optsize = sizeof(*ssp);
2295 		}
2296 		break;
2297 
2298 	case SCTP_HMAC_IDENT:
2299 		{
2300 			struct sctp_hmacalgo *shmac;
2301 			sctp_hmaclist_t *hmaclist;
2302 			uint32_t size;
2303 			int i;
2304 
2305 			SCTP_CHECK_AND_CAST(shmac, optval, struct sctp_hmacalgo, *optsize);
2306 
2307 			SCTP_INP_RLOCK(inp);
2308 			hmaclist = inp->sctp_ep.local_hmacs;
2309 			if (hmaclist == NULL) {
2310 				/* no HMACs to return */
2311 				*optsize = sizeof(*shmac);
2312 				SCTP_INP_RUNLOCK(inp);
2313 				break;
2314 			}
2315 			/* is there room for all of the hmac ids? */
2316 			size = sizeof(*shmac) + (hmaclist->num_algo *
2317 			    sizeof(shmac->shmac_idents[0]));
2318 			if ((size_t)(*optsize) < size) {
2319 				error = EINVAL;
2320 				SCTP_INP_RUNLOCK(inp);
2321 				break;
2322 			}
2323 			/* copy in the list */
2324 			for (i = 0; i < hmaclist->num_algo; i++)
2325 				shmac->shmac_idents[i] = hmaclist->hmac[i];
2326 			SCTP_INP_RUNLOCK(inp);
2327 			*optsize = size;
2328 			break;
2329 		}
2330 	case SCTP_AUTH_ACTIVE_KEY:
2331 		{
2332 			struct sctp_authkeyid *scact;
2333 
2334 			SCTP_CHECK_AND_CAST(scact, optval, struct sctp_authkeyid, *optsize);
2335 			SCTP_FIND_STCB(inp, stcb, scact->scact_assoc_id);
2336 
2337 			if (stcb) {
2338 				/* get the active key on the assoc */
2339 				scact->scact_keynumber = stcb->asoc.authinfo.assoc_keyid;
2340 				SCTP_TCB_UNLOCK(stcb);
2341 			} else {
2342 				/* get the endpoint active key */
2343 				SCTP_INP_RLOCK(inp);
2344 				scact->scact_keynumber = inp->sctp_ep.default_keyid;
2345 				SCTP_INP_RUNLOCK(inp);
2346 			}
2347 			*optsize = sizeof(*scact);
2348 			break;
2349 		}
2350 	case SCTP_LOCAL_AUTH_CHUNKS:
2351 		{
2352 			struct sctp_authchunks *sac;
2353 			sctp_auth_chklist_t *chklist = NULL;
2354 			size_t size = 0;
2355 
2356 			SCTP_CHECK_AND_CAST(sac, optval, struct sctp_authchunks, *optsize);
2357 			SCTP_FIND_STCB(inp, stcb, sac->gauth_assoc_id);
2358 
2359 			if (stcb) {
2360 				/* get off the assoc */
2361 				chklist = stcb->asoc.local_auth_chunks;
2362 				/* is there enough space? */
2363 				size = sctp_auth_get_chklist_size(chklist);
2364 				if (*optsize < (sizeof(struct sctp_authchunks) + size)) {
2365 					error = EINVAL;
2366 				} else {
2367 					/* copy in the chunks */
2368 					(void)sctp_serialize_auth_chunks(chklist, sac->gauth_chunks);
2369 				}
2370 				SCTP_TCB_UNLOCK(stcb);
2371 			} else {
2372 				/* get off the endpoint */
2373 				SCTP_INP_RLOCK(inp);
2374 				chklist = inp->sctp_ep.local_auth_chunks;
2375 				/* is there enough space? */
2376 				size = sctp_auth_get_chklist_size(chklist);
2377 				if (*optsize < (sizeof(struct sctp_authchunks) + size)) {
2378 					error = EINVAL;
2379 				} else {
2380 					/* copy in the chunks */
2381 					(void)sctp_serialize_auth_chunks(chklist, sac->gauth_chunks);
2382 				}
2383 				SCTP_INP_RUNLOCK(inp);
2384 			}
2385 			*optsize = sizeof(struct sctp_authchunks) + size;
2386 			break;
2387 		}
2388 	case SCTP_PEER_AUTH_CHUNKS:
2389 		{
2390 			struct sctp_authchunks *sac;
2391 			sctp_auth_chklist_t *chklist = NULL;
2392 			size_t size = 0;
2393 
2394 			SCTP_CHECK_AND_CAST(sac, optval, struct sctp_authchunks, *optsize);
2395 			SCTP_FIND_STCB(inp, stcb, sac->gauth_assoc_id);
2396 
2397 			if (stcb) {
2398 				/* get off the assoc */
2399 				chklist = stcb->asoc.peer_auth_chunks;
2400 				/* is there enough space? */
2401 				size = sctp_auth_get_chklist_size(chklist);
2402 				if (*optsize < (sizeof(struct sctp_authchunks) + size)) {
2403 					error = EINVAL;
2404 				} else {
2405 					/* copy in the chunks */
2406 					(void)sctp_serialize_auth_chunks(chklist, sac->gauth_chunks);
2407 				}
2408 				SCTP_TCB_UNLOCK(stcb);
2409 			} else {
2410 				error = ENOENT;
2411 			}
2412 			*optsize = sizeof(struct sctp_authchunks) + size;
2413 			break;
2414 		}
2415 
2416 
2417 	default:
2418 		error = ENOPROTOOPT;
2419 		*optsize = 0;
2420 		break;
2421 	}			/* end switch (sopt->sopt_name) */
2422 	return (error);
2423 }
2424 
2425 static int
2426 sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
2427     void *p)
2428 {
2429 	int error, set_opt;
2430 	uint32_t *mopt;
2431 	struct sctp_tcb *stcb = NULL;
2432 	struct sctp_inpcb *inp;
2433 	uint32_t vrf_id;
2434 
2435 	if (optval == NULL) {
2436 		SCTP_PRINTF("optval is NULL\n");
2437 		return (EINVAL);
2438 	}
2439 	inp = (struct sctp_inpcb *)so->so_pcb;
2440 	if (inp == 0) {
2441 		SCTP_PRINTF("inp is NULL?\n");
2442 		return EINVAL;
2443 	}
2444 	vrf_id = inp->def_vrf_id;
2445 
2446 	error = 0;
2447 	switch (optname) {
2448 	case SCTP_NODELAY:
2449 	case SCTP_AUTOCLOSE:
2450 	case SCTP_AUTO_ASCONF:
2451 	case SCTP_EXPLICIT_EOR:
2452 	case SCTP_DISABLE_FRAGMENTS:
2453 	case SCTP_USE_EXT_RCVINFO:
2454 	case SCTP_I_WANT_MAPPED_V4_ADDR:
2455 		/* copy in the option value */
2456 		SCTP_CHECK_AND_CAST(mopt, optval, uint32_t, optsize);
2457 		set_opt = 0;
2458 		if (error)
2459 			break;
2460 		switch (optname) {
2461 		case SCTP_DISABLE_FRAGMENTS:
2462 			set_opt = SCTP_PCB_FLAGS_NO_FRAGMENT;
2463 			break;
2464 		case SCTP_AUTO_ASCONF:
2465 			set_opt = SCTP_PCB_FLAGS_AUTO_ASCONF;
2466 			break;
2467 		case SCTP_EXPLICIT_EOR:
2468 			set_opt = SCTP_PCB_FLAGS_EXPLICIT_EOR;
2469 			break;
2470 		case SCTP_USE_EXT_RCVINFO:
2471 			set_opt = SCTP_PCB_FLAGS_EXT_RCVINFO;
2472 			break;
2473 		case SCTP_I_WANT_MAPPED_V4_ADDR:
2474 			if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
2475 				set_opt = SCTP_PCB_FLAGS_NEEDS_MAPPED_V4;
2476 			} else {
2477 				return (EINVAL);
2478 			}
2479 			break;
2480 		case SCTP_NODELAY:
2481 			set_opt = SCTP_PCB_FLAGS_NODELAY;
2482 			break;
2483 		case SCTP_AUTOCLOSE:
2484 			if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
2485 			    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
2486 				return (EINVAL);
2487 			}
2488 			set_opt = SCTP_PCB_FLAGS_AUTOCLOSE;
2489 			/*
2490 			 * The value is in ticks. Note this does not effect
2491 			 * old associations, only new ones.
2492 			 */
2493 			inp->sctp_ep.auto_close_time = SEC_TO_TICKS(*mopt);
2494 			break;
2495 		}
2496 		SCTP_INP_WLOCK(inp);
2497 		if (*mopt != 0) {
2498 			sctp_feature_on(inp, set_opt);
2499 		} else {
2500 			sctp_feature_off(inp, set_opt);
2501 		}
2502 		SCTP_INP_WUNLOCK(inp);
2503 		break;
2504 	case SCTP_PARTIAL_DELIVERY_POINT:
2505 		{
2506 			uint32_t *value;
2507 
2508 			SCTP_CHECK_AND_CAST(value, optval, uint32_t, optsize);
2509 			if (*value > SCTP_SB_LIMIT_RCV(so)) {
2510 				error = EINVAL;
2511 				break;
2512 			}
2513 			inp->partial_delivery_point = *value;
2514 		}
2515 		break;
2516 	case SCTP_FRAGMENT_INTERLEAVE:
2517 		/* not yet until we re-write sctp_recvmsg() */
2518 		{
2519 			uint32_t *level;
2520 
2521 			SCTP_CHECK_AND_CAST(level, optval, uint32_t, optsize);
2522 			if (*level == SCTP_FRAG_LEVEL_2) {
2523 				sctp_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE);
2524 				sctp_feature_on(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS);
2525 			} else if (*level == SCTP_FRAG_LEVEL_1) {
2526 				sctp_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE);
2527 				sctp_feature_off(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS);
2528 			} else if (*level == SCTP_FRAG_LEVEL_0) {
2529 				sctp_feature_off(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE);
2530 				sctp_feature_off(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS);
2531 
2532 			} else {
2533 				error = EINVAL;
2534 			}
2535 		}
2536 		break;
2537 	case SCTP_CMT_ON_OFF:
2538 		{
2539 			struct sctp_assoc_value *av;
2540 
2541 			SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
2542 			if (sctp_cmt_on_off) {
2543 				SCTP_FIND_STCB(inp, stcb, av->assoc_id);
2544 				if (stcb) {
2545 					stcb->asoc.sctp_cmt_on_off = (uint8_t) av->assoc_value;
2546 					SCTP_TCB_UNLOCK(stcb);
2547 				} else {
2548 					error = ENOTCONN;
2549 				}
2550 			} else {
2551 				error = ENOPROTOOPT;
2552 			}
2553 		}
2554 		break;
2555 		/* JRS - Set socket option for pluggable congestion control */
2556 	case SCTP_PLUGGABLE_CC:
2557 		{
2558 			struct sctp_assoc_value *av;
2559 
2560 			SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
2561 			SCTP_FIND_STCB(inp, stcb, av->assoc_id);
2562 			if (stcb) {
2563 				switch (av->assoc_value) {
2564 					/*
2565 					 * JRS - Standard TCP congestion
2566 					 * control
2567 					 */
2568 				case SCTP_CC_RFC2581:
2569 					{
2570 						stcb->asoc.congestion_control_module = SCTP_CC_RFC2581;
2571 						stcb->asoc.cc_functions.sctp_set_initial_cc_param = &sctp_set_initial_cc_param;
2572 						stcb->asoc.cc_functions.sctp_cwnd_update_after_sack = &sctp_cwnd_update_after_sack;
2573 						stcb->asoc.cc_functions.sctp_cwnd_update_after_fr = &sctp_cwnd_update_after_fr;
2574 						stcb->asoc.cc_functions.sctp_cwnd_update_after_timeout = &sctp_cwnd_update_after_timeout;
2575 						stcb->asoc.cc_functions.sctp_cwnd_update_after_ecn_echo = &sctp_cwnd_update_after_ecn_echo;
2576 						stcb->asoc.cc_functions.sctp_cwnd_update_after_packet_dropped = &sctp_cwnd_update_after_packet_dropped;
2577 						stcb->asoc.cc_functions.sctp_cwnd_update_after_output = &sctp_cwnd_update_after_output;
2578 						stcb->asoc.cc_functions.sctp_cwnd_update_after_fr_timer = &sctp_cwnd_update_after_fr_timer;
2579 						SCTP_TCB_UNLOCK(stcb);
2580 						break;
2581 					}
2582 					/*
2583 					 * JRS - High Speed TCP congestion
2584 					 * control (Floyd)
2585 					 */
2586 				case SCTP_CC_HSTCP:
2587 					{
2588 						stcb->asoc.congestion_control_module = SCTP_CC_HSTCP;
2589 						stcb->asoc.cc_functions.sctp_set_initial_cc_param = &sctp_set_initial_cc_param;
2590 						stcb->asoc.cc_functions.sctp_cwnd_update_after_sack = &sctp_hs_cwnd_update_after_sack;
2591 						stcb->asoc.cc_functions.sctp_cwnd_update_after_fr = &sctp_hs_cwnd_update_after_fr;
2592 						stcb->asoc.cc_functions.sctp_cwnd_update_after_timeout = &sctp_cwnd_update_after_timeout;
2593 						stcb->asoc.cc_functions.sctp_cwnd_update_after_ecn_echo = &sctp_cwnd_update_after_ecn_echo;
2594 						stcb->asoc.cc_functions.sctp_cwnd_update_after_packet_dropped = &sctp_cwnd_update_after_packet_dropped;
2595 						stcb->asoc.cc_functions.sctp_cwnd_update_after_output = &sctp_cwnd_update_after_output;
2596 						stcb->asoc.cc_functions.sctp_cwnd_update_after_fr_timer = &sctp_cwnd_update_after_fr_timer;
2597 						SCTP_TCB_UNLOCK(stcb);
2598 						break;
2599 					}
2600 					/* JRS - HTCP congestion control */
2601 				case SCTP_CC_HTCP:
2602 					{
2603 						stcb->asoc.congestion_control_module = SCTP_CC_HTCP;
2604 						stcb->asoc.cc_functions.sctp_set_initial_cc_param = &sctp_htcp_set_initial_cc_param;
2605 						stcb->asoc.cc_functions.sctp_cwnd_update_after_sack = &sctp_htcp_cwnd_update_after_sack;
2606 						stcb->asoc.cc_functions.sctp_cwnd_update_after_fr = &sctp_htcp_cwnd_update_after_fr;
2607 						stcb->asoc.cc_functions.sctp_cwnd_update_after_timeout = &sctp_htcp_cwnd_update_after_timeout;
2608 						stcb->asoc.cc_functions.sctp_cwnd_update_after_ecn_echo = &sctp_htcp_cwnd_update_after_ecn_echo;
2609 						stcb->asoc.cc_functions.sctp_cwnd_update_after_packet_dropped = &sctp_cwnd_update_after_packet_dropped;
2610 						stcb->asoc.cc_functions.sctp_cwnd_update_after_output = &sctp_cwnd_update_after_output;
2611 						stcb->asoc.cc_functions.sctp_cwnd_update_after_fr_timer = &sctp_htcp_cwnd_update_after_fr_timer;
2612 						SCTP_TCB_UNLOCK(stcb);
2613 						break;
2614 					}
2615 					/*
2616 					 * JRS - All other values are
2617 					 * invalid
2618 					 */
2619 				default:
2620 					{
2621 						error = EINVAL;
2622 						SCTP_TCB_UNLOCK(stcb);
2623 						break;
2624 					}
2625 				}
2626 			} else {
2627 				switch (av->assoc_value) {
2628 				case SCTP_CC_RFC2581:
2629 				case SCTP_CC_HSTCP:
2630 				case SCTP_CC_HTCP:
2631 					inp->sctp_ep.sctp_default_cc_module = av->assoc_value;
2632 					break;
2633 				default:
2634 					error = EINVAL;
2635 					break;
2636 				};
2637 			}
2638 		}
2639 		break;
2640 	case SCTP_CLR_STAT_LOG:
2641 		error = EOPNOTSUPP;
2642 		break;
2643 	case SCTP_CONTEXT:
2644 		{
2645 			struct sctp_assoc_value *av;
2646 
2647 			SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
2648 			SCTP_FIND_STCB(inp, stcb, av->assoc_id);
2649 
2650 			if (stcb) {
2651 				stcb->asoc.context = av->assoc_value;
2652 				SCTP_TCB_UNLOCK(stcb);
2653 			} else {
2654 				SCTP_INP_WLOCK(inp);
2655 				inp->sctp_context = av->assoc_value;
2656 				SCTP_INP_WUNLOCK(inp);
2657 			}
2658 		}
2659 		break;
2660 	case SCTP_VRF_ID:
2661 		{
2662 			uint32_t *default_vrfid;
2663 
2664 			SCTP_CHECK_AND_CAST(default_vrfid, optval, uint32_t, optsize);
2665 			if (*default_vrfid > SCTP_MAX_VRF_ID) {
2666 				error = EINVAL;
2667 				break;
2668 			}
2669 			inp->def_vrf_id = *default_vrfid;
2670 			break;
2671 		}
2672 	case SCTP_DEL_VRF_ID:
2673 		{
2674 			error = EOPNOTSUPP;
2675 			break;
2676 		}
2677 	case SCTP_ADD_VRF_ID:
2678 		{
2679 			error = EOPNOTSUPP;
2680 			break;
2681 		}
2682 	case SCTP_DELAYED_SACK:
2683 		{
2684 			struct sctp_sack_info *sack;
2685 
2686 			SCTP_CHECK_AND_CAST(sack, optval, struct sctp_sack_info, optsize);
2687 			SCTP_FIND_STCB(inp, stcb, sack->sack_assoc_id);
2688 			if (sack->sack_delay) {
2689 				if (sack->sack_delay > SCTP_MAX_SACK_DELAY)
2690 					sack->sack_delay = SCTP_MAX_SACK_DELAY;
2691 			}
2692 			if (stcb) {
2693 				if (sack->sack_delay) {
2694 					if (MSEC_TO_TICKS(sack->sack_delay) < 1) {
2695 						sack->sack_delay = TICKS_TO_MSEC(1);
2696 					}
2697 					stcb->asoc.delayed_ack = sack->sack_delay;
2698 				}
2699 				if (sack->sack_freq) {
2700 					stcb->asoc.sack_freq = sack->sack_freq;
2701 				}
2702 				SCTP_TCB_UNLOCK(stcb);
2703 			} else {
2704 				SCTP_INP_WLOCK(inp);
2705 				if (sack->sack_delay) {
2706 					if (MSEC_TO_TICKS(sack->sack_delay) < 1) {
2707 						sack->sack_delay = TICKS_TO_MSEC(1);
2708 					}
2709 					inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV] = MSEC_TO_TICKS(sack->sack_delay);
2710 				}
2711 				if (sack->sack_freq) {
2712 					inp->sctp_ep.sctp_sack_freq = sack->sack_freq;
2713 				}
2714 				SCTP_INP_WUNLOCK(inp);
2715 			}
2716 			break;
2717 		}
2718 	case SCTP_AUTH_CHUNK:
2719 		{
2720 			struct sctp_authchunk *sauth;
2721 
2722 			SCTP_CHECK_AND_CAST(sauth, optval, struct sctp_authchunk, optsize);
2723 
2724 			SCTP_INP_WLOCK(inp);
2725 			if (sctp_auth_add_chunk(sauth->sauth_chunk, inp->sctp_ep.local_auth_chunks))
2726 				error = EINVAL;
2727 			SCTP_INP_WUNLOCK(inp);
2728 			break;
2729 		}
2730 	case SCTP_AUTH_KEY:
2731 		{
2732 			struct sctp_authkey *sca;
2733 			struct sctp_keyhead *shared_keys;
2734 			sctp_sharedkey_t *shared_key;
2735 			sctp_key_t *key = NULL;
2736 			size_t size;
2737 
2738 			SCTP_CHECK_AND_CAST(sca, optval, struct sctp_authkey, optsize);
2739 			SCTP_FIND_STCB(inp, stcb, sca->sca_assoc_id);
2740 			size = optsize - sizeof(*sca);
2741 
2742 			if (stcb) {
2743 				/* set it on the assoc */
2744 				shared_keys = &stcb->asoc.shared_keys;
2745 				/* clear the cached keys for this key id */
2746 				sctp_clear_cachedkeys(stcb, sca->sca_keynumber);
2747 				/*
2748 				 * create the new shared key and
2749 				 * insert/replace it
2750 				 */
2751 				if (size > 0) {
2752 					key = sctp_set_key(sca->sca_key, (uint32_t) size);
2753 					if (key == NULL) {
2754 						error = ENOMEM;
2755 						SCTP_TCB_UNLOCK(stcb);
2756 						break;
2757 					}
2758 				}
2759 				shared_key = sctp_alloc_sharedkey();
2760 				if (shared_key == NULL) {
2761 					sctp_free_key(key);
2762 					error = ENOMEM;
2763 					SCTP_TCB_UNLOCK(stcb);
2764 					break;
2765 				}
2766 				shared_key->key = key;
2767 				shared_key->keyid = sca->sca_keynumber;
2768 				sctp_insert_sharedkey(shared_keys, shared_key);
2769 				SCTP_TCB_UNLOCK(stcb);
2770 			} else {
2771 				/* set it on the endpoint */
2772 				SCTP_INP_WLOCK(inp);
2773 				shared_keys = &inp->sctp_ep.shared_keys;
2774 				/*
2775 				 * clear the cached keys on all assocs for
2776 				 * this key id
2777 				 */
2778 				sctp_clear_cachedkeys_ep(inp, sca->sca_keynumber);
2779 				/*
2780 				 * create the new shared key and
2781 				 * insert/replace it
2782 				 */
2783 				if (size > 0) {
2784 					key = sctp_set_key(sca->sca_key, (uint32_t) size);
2785 					if (key == NULL) {
2786 						error = ENOMEM;
2787 						SCTP_INP_WUNLOCK(inp);
2788 						break;
2789 					}
2790 				}
2791 				shared_key = sctp_alloc_sharedkey();
2792 				if (shared_key == NULL) {
2793 					sctp_free_key(key);
2794 					error = ENOMEM;
2795 					SCTP_INP_WUNLOCK(inp);
2796 					break;
2797 				}
2798 				shared_key->key = key;
2799 				shared_key->keyid = sca->sca_keynumber;
2800 				sctp_insert_sharedkey(shared_keys, shared_key);
2801 				SCTP_INP_WUNLOCK(inp);
2802 			}
2803 			break;
2804 		}
2805 	case SCTP_HMAC_IDENT:
2806 		{
2807 			struct sctp_hmacalgo *shmac;
2808 			sctp_hmaclist_t *hmaclist;
2809 			uint32_t hmacid;
2810 			size_t size, i, found;
2811 
2812 			SCTP_CHECK_AND_CAST(shmac, optval, struct sctp_hmacalgo, optsize);
2813 			size = (optsize - sizeof(*shmac)) / sizeof(shmac->shmac_idents[0]);
2814 			hmaclist = sctp_alloc_hmaclist(size);
2815 			if (hmaclist == NULL) {
2816 				error = ENOMEM;
2817 				break;
2818 			}
2819 			for (i = 0; i < size; i++) {
2820 				hmacid = shmac->shmac_idents[i];
2821 				if (sctp_auth_add_hmacid(hmaclist, (uint16_t) hmacid)) {
2822 					 /* invalid HMACs were found */ ;
2823 					error = EINVAL;
2824 					sctp_free_hmaclist(hmaclist);
2825 					goto sctp_set_hmac_done;
2826 				}
2827 			}
2828 			found = 0;
2829 			for (i = 0; i < hmaclist->num_algo; i++) {
2830 				if (hmaclist->hmac[i] == SCTP_AUTH_HMAC_ID_SHA1) {
2831 					/* already in list */
2832 					found = 1;
2833 				}
2834 			}
2835 			if (!found) {
2836 				sctp_free_hmaclist(hmaclist);
2837 				error = EINVAL;
2838 				break;
2839 			}
2840 			/* set it on the endpoint */
2841 			SCTP_INP_WLOCK(inp);
2842 			if (inp->sctp_ep.local_hmacs)
2843 				sctp_free_hmaclist(inp->sctp_ep.local_hmacs);
2844 			inp->sctp_ep.local_hmacs = hmaclist;
2845 			SCTP_INP_WUNLOCK(inp);
2846 	sctp_set_hmac_done:
2847 			break;
2848 		}
2849 	case SCTP_AUTH_ACTIVE_KEY:
2850 		{
2851 			struct sctp_authkeyid *scact;
2852 
2853 			SCTP_CHECK_AND_CAST(scact, optval, struct sctp_authkeyid, optsize);
2854 			SCTP_FIND_STCB(inp, stcb, scact->scact_assoc_id);
2855 
2856 			/* set the active key on the right place */
2857 			if (stcb) {
2858 				/* set the active key on the assoc */
2859 				if (sctp_auth_setactivekey(stcb, scact->scact_keynumber))
2860 					error = EINVAL;
2861 				SCTP_TCB_UNLOCK(stcb);
2862 			} else {
2863 				/* set the active key on the endpoint */
2864 				SCTP_INP_WLOCK(inp);
2865 				if (sctp_auth_setactivekey_ep(inp, scact->scact_keynumber))
2866 					error = EINVAL;
2867 				SCTP_INP_WUNLOCK(inp);
2868 			}
2869 			break;
2870 		}
2871 	case SCTP_AUTH_DELETE_KEY:
2872 		{
2873 			struct sctp_authkeyid *scdel;
2874 
2875 			SCTP_CHECK_AND_CAST(scdel, optval, struct sctp_authkeyid, optsize);
2876 			SCTP_FIND_STCB(inp, stcb, scdel->scact_assoc_id);
2877 
2878 			/* delete the key from the right place */
2879 			if (stcb) {
2880 				if (sctp_delete_sharedkey(stcb, scdel->scact_keynumber))
2881 					error = EINVAL;
2882 				SCTP_TCB_UNLOCK(stcb);
2883 			} else {
2884 				SCTP_INP_WLOCK(inp);
2885 				if (sctp_delete_sharedkey_ep(inp, scdel->scact_keynumber))
2886 					error = EINVAL;
2887 				SCTP_INP_WUNLOCK(inp);
2888 			}
2889 			break;
2890 		}
2891 
2892 	case SCTP_RESET_STREAMS:
2893 		{
2894 			struct sctp_stream_reset *strrst;
2895 			uint8_t send_in = 0, send_tsn = 0, send_out = 0;
2896 			int i;
2897 
2898 			SCTP_CHECK_AND_CAST(strrst, optval, struct sctp_stream_reset, optsize);
2899 			SCTP_FIND_STCB(inp, stcb, strrst->strrst_assoc_id);
2900 
2901 			if (stcb == NULL) {
2902 				error = ENOENT;
2903 				break;
2904 			}
2905 			if (stcb->asoc.peer_supports_strreset == 0) {
2906 				/*
2907 				 * Peer does not support it, we return
2908 				 * protocol not supported since this is true
2909 				 * for this feature and this peer, not the
2910 				 * socket request in general.
2911 				 */
2912 				error = EPROTONOSUPPORT;
2913 				SCTP_TCB_UNLOCK(stcb);
2914 				break;
2915 			}
2916 			if (stcb->asoc.stream_reset_outstanding) {
2917 				error = EALREADY;
2918 				SCTP_TCB_UNLOCK(stcb);
2919 				break;
2920 			}
2921 			if (strrst->strrst_flags == SCTP_RESET_LOCAL_RECV) {
2922 				send_in = 1;
2923 			} else if (strrst->strrst_flags == SCTP_RESET_LOCAL_SEND) {
2924 				send_out = 1;
2925 			} else if (strrst->strrst_flags == SCTP_RESET_BOTH) {
2926 				send_in = 1;
2927 				send_out = 1;
2928 			} else if (strrst->strrst_flags == SCTP_RESET_TSN) {
2929 				send_tsn = 1;
2930 			} else {
2931 				error = EINVAL;
2932 				SCTP_TCB_UNLOCK(stcb);
2933 				break;
2934 			}
2935 			for (i = 0; i < strrst->strrst_num_streams; i++) {
2936 				if ((send_in) &&
2937 
2938 				    (strrst->strrst_list[i] > stcb->asoc.streamincnt)) {
2939 					error = EINVAL;
2940 					goto get_out;
2941 				}
2942 				if ((send_out) &&
2943 				    (strrst->strrst_list[i] > stcb->asoc.streamoutcnt)) {
2944 					error = EINVAL;
2945 					goto get_out;
2946 				}
2947 			}
2948 			if (error) {
2949 		get_out:
2950 				SCTP_TCB_UNLOCK(stcb);
2951 				break;
2952 			}
2953 			error = sctp_send_str_reset_req(stcb, strrst->strrst_num_streams,
2954 			    strrst->strrst_list,
2955 			    send_out, (stcb->asoc.str_reset_seq_in - 3),
2956 			    send_in, send_tsn);
2957 
2958 			sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_STRRST_REQ);
2959 			SCTP_TCB_UNLOCK(stcb);
2960 		}
2961 		break;
2962 
2963 	case SCTP_CONNECT_X:
2964 		if (optsize < (sizeof(int) + sizeof(struct sockaddr_in))) {
2965 			error = EINVAL;
2966 			break;
2967 		}
2968 		error = sctp_do_connect_x(so, inp, optval, optsize, p, 0);
2969 		break;
2970 
2971 	case SCTP_CONNECT_X_DELAYED:
2972 		if (optsize < (sizeof(int) + sizeof(struct sockaddr_in))) {
2973 			error = EINVAL;
2974 			break;
2975 		}
2976 		error = sctp_do_connect_x(so, inp, optval, optsize, p, 1);
2977 		break;
2978 
2979 	case SCTP_CONNECT_X_COMPLETE:
2980 		{
2981 			struct sockaddr *sa;
2982 			struct sctp_nets *net;
2983 
2984 			/* FIXME MT: check correct? */
2985 			SCTP_CHECK_AND_CAST(sa, optval, struct sockaddr, optsize);
2986 
2987 			/* find tcb */
2988 			if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2989 				SCTP_INP_RLOCK(inp);
2990 				stcb = LIST_FIRST(&inp->sctp_asoc_list);
2991 				if (stcb) {
2992 					SCTP_TCB_LOCK(stcb);
2993 					net = sctp_findnet(stcb, sa);
2994 				}
2995 				SCTP_INP_RUNLOCK(inp);
2996 			} else {
2997 				/*
2998 				 * We increment here since
2999 				 * sctp_findassociation_ep_addr() wil do a
3000 				 * decrement if it finds the stcb as long as
3001 				 * the locked tcb (last argument) is NOT a
3002 				 * TCB.. aka NULL.
3003 				 */
3004 				SCTP_INP_INCR_REF(inp);
3005 				stcb = sctp_findassociation_ep_addr(&inp, sa, &net, NULL, NULL);
3006 				if (stcb == NULL) {
3007 					SCTP_INP_DECR_REF(inp);
3008 				}
3009 			}
3010 
3011 			if (stcb == NULL) {
3012 				error = ENOENT;
3013 				break;
3014 			}
3015 			if (stcb->asoc.delayed_connection == 1) {
3016 				stcb->asoc.delayed_connection = 0;
3017 				(void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered);
3018 				sctp_timer_stop(SCTP_TIMER_TYPE_INIT, inp, stcb,
3019 				    stcb->asoc.primary_destination,
3020 				    SCTP_FROM_SCTP_USRREQ + SCTP_LOC_9);
3021 				sctp_send_initiate(inp, stcb);
3022 			} else {
3023 				/*
3024 				 * already expired or did not use delayed
3025 				 * connectx
3026 				 */
3027 				error = EALREADY;
3028 			}
3029 			SCTP_TCB_UNLOCK(stcb);
3030 		}
3031 		break;
3032 	case SCTP_MAX_BURST:
3033 		{
3034 			uint8_t *burst;
3035 
3036 			SCTP_CHECK_AND_CAST(burst, optval, uint8_t, optsize);
3037 
3038 			SCTP_INP_WLOCK(inp);
3039 			if (*burst) {
3040 				inp->sctp_ep.max_burst = *burst;
3041 			}
3042 			SCTP_INP_WUNLOCK(inp);
3043 		}
3044 		break;
3045 	case SCTP_MAXSEG:
3046 		{
3047 			struct sctp_assoc_value *av;
3048 			int ovh;
3049 
3050 			SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
3051 			SCTP_FIND_STCB(inp, stcb, av->assoc_id);
3052 
3053 			if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
3054 				ovh = SCTP_MED_OVERHEAD;
3055 			} else {
3056 				ovh = SCTP_MED_V4_OVERHEAD;
3057 			}
3058 			if (stcb) {
3059 				if (av->assoc_value) {
3060 					stcb->asoc.sctp_frag_point = (av->assoc_value + ovh);
3061 				} else {
3062 					stcb->asoc.sctp_frag_point = SCTP_DEFAULT_MAXSEGMENT;
3063 				}
3064 				SCTP_TCB_UNLOCK(stcb);
3065 			} else {
3066 				SCTP_INP_WLOCK(inp);
3067 				/*
3068 				 * FIXME MT: I think this is not in tune
3069 				 * with the API ID
3070 				 */
3071 				if (av->assoc_value) {
3072 					inp->sctp_frag_point = (av->assoc_value + ovh);
3073 				} else {
3074 					inp->sctp_frag_point = SCTP_DEFAULT_MAXSEGMENT;
3075 				}
3076 				SCTP_INP_WUNLOCK(inp);
3077 			}
3078 		}
3079 		break;
3080 	case SCTP_EVENTS:
3081 		{
3082 			struct sctp_event_subscribe *events;
3083 
3084 			SCTP_CHECK_AND_CAST(events, optval, struct sctp_event_subscribe, optsize);
3085 
3086 			SCTP_INP_WLOCK(inp);
3087 			if (events->sctp_data_io_event) {
3088 				sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT);
3089 			} else {
3090 				sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT);
3091 			}
3092 
3093 			if (events->sctp_association_event) {
3094 				sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVASSOCEVNT);
3095 			} else {
3096 				sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVASSOCEVNT);
3097 			}
3098 
3099 			if (events->sctp_address_event) {
3100 				sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVPADDREVNT);
3101 			} else {
3102 				sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVPADDREVNT);
3103 			}
3104 
3105 			if (events->sctp_send_failure_event) {
3106 				sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVSENDFAILEVNT);
3107 			} else {
3108 				sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVSENDFAILEVNT);
3109 			}
3110 
3111 			if (events->sctp_peer_error_event) {
3112 				sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVPEERERR);
3113 			} else {
3114 				sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVPEERERR);
3115 			}
3116 
3117 			if (events->sctp_shutdown_event) {
3118 				sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT);
3119 			} else {
3120 				sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT);
3121 			}
3122 
3123 			if (events->sctp_partial_delivery_event) {
3124 				sctp_feature_on(inp, SCTP_PCB_FLAGS_PDAPIEVNT);
3125 			} else {
3126 				sctp_feature_off(inp, SCTP_PCB_FLAGS_PDAPIEVNT);
3127 			}
3128 
3129 			if (events->sctp_adaptation_layer_event) {
3130 				sctp_feature_on(inp, SCTP_PCB_FLAGS_ADAPTATIONEVNT);
3131 			} else {
3132 				sctp_feature_off(inp, SCTP_PCB_FLAGS_ADAPTATIONEVNT);
3133 			}
3134 
3135 			if (events->sctp_authentication_event) {
3136 				sctp_feature_on(inp, SCTP_PCB_FLAGS_AUTHEVNT);
3137 			} else {
3138 				sctp_feature_off(inp, SCTP_PCB_FLAGS_AUTHEVNT);
3139 			}
3140 
3141 			if (events->sctp_stream_reset_events) {
3142 				sctp_feature_on(inp, SCTP_PCB_FLAGS_STREAM_RESETEVNT);
3143 			} else {
3144 				sctp_feature_off(inp, SCTP_PCB_FLAGS_STREAM_RESETEVNT);
3145 			}
3146 			SCTP_INP_WUNLOCK(inp);
3147 		}
3148 		break;
3149 
3150 	case SCTP_ADAPTATION_LAYER:
3151 		{
3152 			struct sctp_setadaptation *adap_bits;
3153 
3154 			SCTP_CHECK_AND_CAST(adap_bits, optval, struct sctp_setadaptation, optsize);
3155 			SCTP_INP_WLOCK(inp);
3156 			inp->sctp_ep.adaptation_layer_indicator = adap_bits->ssb_adaptation_ind;
3157 			SCTP_INP_WUNLOCK(inp);
3158 		}
3159 		break;
3160 #ifdef SCTP_DEBUG
3161 	case SCTP_SET_INITIAL_DBG_SEQ:
3162 		{
3163 			uint32_t *vvv;
3164 
3165 			SCTP_CHECK_AND_CAST(vvv, optval, uint32_t, optsize);
3166 			SCTP_INP_WLOCK(inp);
3167 			inp->sctp_ep.initial_sequence_debug = *vvv;
3168 			SCTP_INP_WUNLOCK(inp);
3169 		}
3170 		break;
3171 #endif
3172 	case SCTP_DEFAULT_SEND_PARAM:
3173 		{
3174 			struct sctp_sndrcvinfo *s_info;
3175 
3176 			SCTP_CHECK_AND_CAST(s_info, optval, struct sctp_sndrcvinfo, optsize);
3177 			SCTP_FIND_STCB(inp, stcb, s_info->sinfo_assoc_id);
3178 
3179 			if (stcb) {
3180 				if (s_info->sinfo_stream <= stcb->asoc.streamoutcnt) {
3181 					memcpy(&stcb->asoc.def_send, s_info, min(optsize, sizeof(stcb->asoc.def_send)));
3182 				} else {
3183 					error = EINVAL;
3184 				}
3185 				SCTP_TCB_UNLOCK(stcb);
3186 			} else {
3187 				SCTP_INP_WLOCK(inp);
3188 				memcpy(&inp->def_send, s_info, min(optsize, sizeof(inp->def_send)));
3189 				SCTP_INP_WUNLOCK(inp);
3190 			}
3191 		}
3192 		break;
3193 	case SCTP_PEER_ADDR_PARAMS:
3194 		/* Applys to the specific association */
3195 		{
3196 			struct sctp_paddrparams *paddrp;
3197 			struct sctp_nets *net;
3198 
3199 			SCTP_CHECK_AND_CAST(paddrp, optval, struct sctp_paddrparams, optsize);
3200 			SCTP_FIND_STCB(inp, stcb, paddrp->spp_assoc_id);
3201 			net = NULL;
3202 			if (stcb) {
3203 				net = sctp_findnet(stcb, (struct sockaddr *)&paddrp->spp_address);
3204 			} else {
3205 				/*
3206 				 * We increment here since
3207 				 * sctp_findassociation_ep_addr() wil do a
3208 				 * decrement if it finds the stcb as long as
3209 				 * the locked tcb (last argument) is NOT a
3210 				 * TCB.. aka NULL.
3211 				 */
3212 				SCTP_INP_INCR_REF(inp);
3213 				stcb = sctp_findassociation_ep_addr(&inp,
3214 				    (struct sockaddr *)&paddrp->spp_address,
3215 				    &net, NULL, NULL);
3216 				if (stcb == NULL) {
3217 					SCTP_INP_DECR_REF(inp);
3218 				}
3219 			}
3220 			/* sanity checks */
3221 			if ((paddrp->spp_flags & SPP_HB_ENABLE) && (paddrp->spp_flags & SPP_HB_DISABLE)) {
3222 				if (stcb)
3223 					SCTP_TCB_UNLOCK(stcb);
3224 				return (EINVAL);
3225 			}
3226 			if ((paddrp->spp_flags & SPP_PMTUD_ENABLE) && (paddrp->spp_flags & SPP_PMTUD_DISABLE)) {
3227 				if (stcb)
3228 					SCTP_TCB_UNLOCK(stcb);
3229 				return (EINVAL);
3230 			}
3231 			if (stcb) {
3232 				/************************TCB SPECIFIC SET ******************/
3233 				/*
3234 				 * do we change the timer for HB, we run
3235 				 * only one?
3236 				 */
3237 				int ovh = 0;
3238 
3239 				if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
3240 					ovh = SCTP_MED_OVERHEAD;
3241 				} else {
3242 					ovh = SCTP_MED_V4_OVERHEAD;
3243 				}
3244 
3245 				if (paddrp->spp_hbinterval)
3246 					stcb->asoc.heart_beat_delay = paddrp->spp_hbinterval;
3247 				else if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO)
3248 					stcb->asoc.heart_beat_delay = 0;
3249 
3250 				/* network sets ? */
3251 				if (net) {
3252 					/************************NET SPECIFIC SET ******************/
3253 					if (paddrp->spp_flags & SPP_HB_DEMAND) {
3254 						/* on demand HB */
3255 						if (sctp_send_hb(stcb, 1, net) < 0) {
3256 							/* asoc destroyed */
3257 							error = EINVAL;
3258 							break;
3259 						}
3260 					}
3261 					if (paddrp->spp_flags & SPP_HB_DISABLE) {
3262 						net->dest_state |= SCTP_ADDR_NOHB;
3263 					}
3264 					if (paddrp->spp_flags & SPP_HB_ENABLE) {
3265 						net->dest_state &= ~SCTP_ADDR_NOHB;
3266 					}
3267 					if ((paddrp->spp_flags & SPP_PMTUD_DISABLE) && (paddrp->spp_pathmtu >= SCTP_SMALLEST_PMTU)) {
3268 						if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
3269 							sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net,
3270 							    SCTP_FROM_SCTP_USRREQ + SCTP_LOC_10);
3271 						}
3272 						if (paddrp->spp_pathmtu > SCTP_DEFAULT_MINSEGMENT) {
3273 							net->mtu = paddrp->spp_pathmtu + ovh;
3274 							if (net->mtu < stcb->asoc.smallest_mtu) {
3275 #ifdef SCTP_PRINT_FOR_B_AND_M
3276 								SCTP_PRINTF("SCTP_PMTU_DISABLE calls sctp_pathmtu_adjustment:%d\n",
3277 								    net->mtu);
3278 #endif
3279 								sctp_pathmtu_adjustment(inp, stcb, net, net->mtu);
3280 							}
3281 						}
3282 					}
3283 					if (paddrp->spp_flags & SPP_PMTUD_ENABLE) {
3284 						if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
3285 							sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net);
3286 						}
3287 					}
3288 					if (paddrp->spp_pathmaxrxt)
3289 						net->failure_threshold = paddrp->spp_pathmaxrxt;
3290 #ifdef INET
3291 					if (paddrp->spp_flags & SPP_IPV4_TOS) {
3292 						if (net->ro._l_addr.sin.sin_family == AF_INET) {
3293 							net->tos_flowlabel = paddrp->spp_ipv4_tos & 0x000000fc;
3294 						}
3295 					}
3296 #endif
3297 #ifdef INET6
3298 					if (paddrp->spp_flags & SPP_IPV6_FLOWLABEL) {
3299 						if (net->ro._l_addr.sin6.sin6_family == AF_INET6) {
3300 							net->tos_flowlabel = paddrp->spp_ipv6_flowlabel;
3301 						}
3302 					}
3303 #endif
3304 				} else {
3305 					/************************ASSOC ONLY -- NO NET SPECIFIC SET ******************/
3306 					if (paddrp->spp_pathmaxrxt)
3307 						stcb->asoc.def_net_failure = paddrp->spp_pathmaxrxt;
3308 
3309 					if (paddrp->spp_flags & SPP_HB_ENABLE) {
3310 						/* Turn back on the timer */
3311 						stcb->asoc.hb_is_disabled = 0;
3312 						sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net);
3313 					}
3314 					if ((paddrp->spp_flags & SPP_PMTUD_DISABLE) && (paddrp->spp_pathmtu >= SCTP_SMALLEST_PMTU)) {
3315 						TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
3316 							if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
3317 								sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net,
3318 								    SCTP_FROM_SCTP_USRREQ + SCTP_LOC_10);
3319 							}
3320 							if (paddrp->spp_pathmtu > SCTP_DEFAULT_MINSEGMENT) {
3321 								net->mtu = paddrp->spp_pathmtu + ovh;
3322 								if (net->mtu < stcb->asoc.smallest_mtu) {
3323 #ifdef SCTP_PRINT_FOR_B_AND_M
3324 									SCTP_PRINTF("SCTP_PMTU_DISABLE calls sctp_pathmtu_adjustment:%d\n",
3325 									    net->mtu);
3326 #endif
3327 									sctp_pathmtu_adjustment(inp, stcb, net, net->mtu);
3328 								}
3329 							}
3330 						}
3331 					}
3332 					if (paddrp->spp_flags & SPP_PMTUD_ENABLE) {
3333 						TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
3334 							if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
3335 								sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net);
3336 							}
3337 						}
3338 					}
3339 					if (paddrp->spp_flags & SPP_HB_DISABLE) {
3340 						int cnt_of_unconf = 0;
3341 						struct sctp_nets *lnet;
3342 
3343 						stcb->asoc.hb_is_disabled = 1;
3344 						TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) {
3345 							if (lnet->dest_state & SCTP_ADDR_UNCONFIRMED) {
3346 								cnt_of_unconf++;
3347 							}
3348 						}
3349 						/*
3350 						 * stop the timer ONLY if we
3351 						 * have no unconfirmed
3352 						 * addresses
3353 						 */
3354 						if (cnt_of_unconf == 0) {
3355 							TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
3356 								sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net,
3357 								    SCTP_FROM_SCTP_USRREQ + SCTP_LOC_11);
3358 							}
3359 						}
3360 					}
3361 					if (paddrp->spp_flags & SPP_HB_ENABLE) {
3362 						/* start up the timer. */
3363 						TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
3364 							sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net);
3365 						}
3366 					}
3367 #ifdef INET
3368 					if (paddrp->spp_flags & SPP_IPV4_TOS)
3369 						stcb->asoc.default_tos = paddrp->spp_ipv4_tos & 0x000000fc;
3370 #endif
3371 #ifdef INET6
3372 					if (paddrp->spp_flags & SPP_IPV6_FLOWLABEL)
3373 						stcb->asoc.default_flowlabel = paddrp->spp_ipv6_flowlabel;
3374 #endif
3375 
3376 				}
3377 				SCTP_TCB_UNLOCK(stcb);
3378 			} else {
3379 				/************************NO TCB, SET TO default stuff ******************/
3380 				SCTP_INP_WLOCK(inp);
3381 				/*
3382 				 * For the TOS/FLOWLABEL stuff you set it
3383 				 * with the options on the socket
3384 				 */
3385 				if (paddrp->spp_pathmaxrxt) {
3386 					inp->sctp_ep.def_net_failure = paddrp->spp_pathmaxrxt;
3387 				}
3388 				if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO)
3389 					inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = 0;
3390 				else if (paddrp->spp_hbinterval) {
3391 					if (paddrp->spp_hbinterval > SCTP_MAX_HB_INTERVAL)
3392 						paddrp->spp_hbinterval = SCTP_MAX_HB_INTERVAL;
3393 					inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = MSEC_TO_TICKS(paddrp->spp_hbinterval);
3394 				}
3395 				if (paddrp->spp_flags & SPP_HB_ENABLE) {
3396 					sctp_feature_off(inp, SCTP_PCB_FLAGS_DONOT_HEARTBEAT);
3397 
3398 				} else if (paddrp->spp_flags & SPP_HB_DISABLE) {
3399 					sctp_feature_on(inp, SCTP_PCB_FLAGS_DONOT_HEARTBEAT);
3400 				}
3401 				SCTP_INP_WUNLOCK(inp);
3402 			}
3403 		}
3404 		break;
3405 	case SCTP_RTOINFO:
3406 		{
3407 			struct sctp_rtoinfo *srto;
3408 			uint32_t new_init, new_min, new_max;
3409 
3410 			SCTP_CHECK_AND_CAST(srto, optval, struct sctp_rtoinfo, optsize);
3411 			SCTP_FIND_STCB(inp, stcb, srto->srto_assoc_id);
3412 
3413 			if (stcb) {
3414 				if (srto->srto_initial)
3415 					new_init = srto->srto_initial;
3416 				else
3417 					new_init = stcb->asoc.initial_rto;
3418 				if (srto->srto_max)
3419 					new_max = srto->srto_max;
3420 				else
3421 					new_max = stcb->asoc.maxrto;
3422 				if (srto->srto_min)
3423 					new_min = srto->srto_min;
3424 				else
3425 					new_min = stcb->asoc.minrto;
3426 				if ((new_min <= new_init) && (new_init <= new_max)) {
3427 					stcb->asoc.initial_rto = new_init;
3428 					stcb->asoc.maxrto = new_max;
3429 					stcb->asoc.minrto = new_min;
3430 				} else {
3431 					error = EDOM;
3432 				}
3433 				SCTP_TCB_UNLOCK(stcb);
3434 			} else {
3435 				SCTP_INP_WLOCK(inp);
3436 				if (srto->srto_initial)
3437 					new_init = srto->srto_initial;
3438 				else
3439 					new_init = inp->sctp_ep.initial_rto;
3440 				if (srto->srto_max)
3441 					new_max = srto->srto_max;
3442 				else
3443 					new_max = inp->sctp_ep.sctp_maxrto;
3444 				if (srto->srto_min)
3445 					new_min = srto->srto_min;
3446 				else
3447 					new_min = inp->sctp_ep.sctp_minrto;
3448 				if ((new_min <= new_init) && (new_init <= new_max)) {
3449 					inp->sctp_ep.initial_rto = new_init;
3450 					inp->sctp_ep.sctp_maxrto = new_max;
3451 					inp->sctp_ep.sctp_minrto = new_min;
3452 				} else {
3453 					error = EDOM;
3454 				}
3455 				SCTP_INP_WUNLOCK(inp);
3456 			}
3457 		}
3458 		break;
3459 	case SCTP_ASSOCINFO:
3460 		{
3461 			struct sctp_assocparams *sasoc;
3462 
3463 			SCTP_CHECK_AND_CAST(sasoc, optval, struct sctp_assocparams, optsize);
3464 			SCTP_FIND_STCB(inp, stcb, sasoc->sasoc_assoc_id);
3465 			if (sasoc->sasoc_cookie_life) {
3466 				/* boundary check the cookie life */
3467 				if (sasoc->sasoc_cookie_life < 1000)
3468 					sasoc->sasoc_cookie_life = 1000;
3469 				if (sasoc->sasoc_cookie_life > SCTP_MAX_COOKIE_LIFE) {
3470 					sasoc->sasoc_cookie_life = SCTP_MAX_COOKIE_LIFE;
3471 				}
3472 			}
3473 			if (stcb) {
3474 				if (sasoc->sasoc_asocmaxrxt)
3475 					stcb->asoc.max_send_times = sasoc->sasoc_asocmaxrxt;
3476 				sasoc->sasoc_number_peer_destinations = stcb->asoc.numnets;
3477 				sasoc->sasoc_peer_rwnd = 0;
3478 				sasoc->sasoc_local_rwnd = 0;
3479 				if (sasoc->sasoc_cookie_life) {
3480 					stcb->asoc.cookie_life = sasoc->sasoc_cookie_life;
3481 
3482 				}
3483 				SCTP_TCB_UNLOCK(stcb);
3484 			} else {
3485 				SCTP_INP_WLOCK(inp);
3486 				if (sasoc->sasoc_asocmaxrxt)
3487 					inp->sctp_ep.max_send_times = sasoc->sasoc_asocmaxrxt;
3488 				sasoc->sasoc_number_peer_destinations = 0;
3489 				sasoc->sasoc_peer_rwnd = 0;
3490 				sasoc->sasoc_local_rwnd = 0;
3491 				if (sasoc->sasoc_cookie_life) {
3492 					inp->sctp_ep.def_cookie_life = MSEC_TO_TICKS(sasoc->sasoc_cookie_life);
3493 				}
3494 				SCTP_INP_WUNLOCK(inp);
3495 			}
3496 		}
3497 		break;
3498 	case SCTP_INITMSG:
3499 		{
3500 			struct sctp_initmsg *sinit;
3501 
3502 			SCTP_CHECK_AND_CAST(sinit, optval, struct sctp_initmsg, optsize);
3503 			SCTP_INP_WLOCK(inp);
3504 			if (sinit->sinit_num_ostreams)
3505 				inp->sctp_ep.pre_open_stream_count = sinit->sinit_num_ostreams;
3506 
3507 			if (sinit->sinit_max_instreams)
3508 				inp->sctp_ep.max_open_streams_intome = sinit->sinit_max_instreams;
3509 
3510 			if (sinit->sinit_max_attempts)
3511 				inp->sctp_ep.max_init_times = sinit->sinit_max_attempts;
3512 
3513 			if (sinit->sinit_max_init_timeo)
3514 				inp->sctp_ep.initial_init_rto_max = sinit->sinit_max_init_timeo;
3515 			SCTP_INP_WUNLOCK(inp);
3516 		}
3517 		break;
3518 	case SCTP_PRIMARY_ADDR:
3519 		{
3520 			struct sctp_setprim *spa;
3521 			struct sctp_nets *net, *lnet;
3522 
3523 			SCTP_CHECK_AND_CAST(spa, optval, struct sctp_setprim, optsize);
3524 			SCTP_FIND_STCB(inp, stcb, spa->ssp_assoc_id);
3525 
3526 			net = NULL;
3527 			if (stcb) {
3528 				net = sctp_findnet(stcb, (struct sockaddr *)&spa->ssp_addr);
3529 			} else {
3530 				/*
3531 				 * We increment here since
3532 				 * sctp_findassociation_ep_addr() wil do a
3533 				 * decrement if it finds the stcb as long as
3534 				 * the locked tcb (last argument) is NOT a
3535 				 * TCB.. aka NULL.
3536 				 */
3537 				SCTP_INP_INCR_REF(inp);
3538 				stcb = sctp_findassociation_ep_addr(&inp,
3539 				    (struct sockaddr *)&spa->ssp_addr,
3540 				    &net, NULL, NULL);
3541 				if (stcb == NULL) {
3542 					SCTP_INP_DECR_REF(inp);
3543 				}
3544 			}
3545 
3546 			if ((stcb) && (net)) {
3547 				if ((net != stcb->asoc.primary_destination) &&
3548 				    (!(net->dest_state & SCTP_ADDR_UNCONFIRMED))) {
3549 					/* Ok we need to set it */
3550 					lnet = stcb->asoc.primary_destination;
3551 					if (sctp_set_primary_addr(stcb, (struct sockaddr *)NULL, net) == 0) {
3552 						if (net->dest_state & SCTP_ADDR_SWITCH_PRIMARY) {
3553 							net->dest_state |= SCTP_ADDR_DOUBLE_SWITCH;
3554 						}
3555 						net->dest_state |= SCTP_ADDR_SWITCH_PRIMARY;
3556 					}
3557 				}
3558 			} else {
3559 				error = EINVAL;
3560 			}
3561 			if (stcb) {
3562 				SCTP_TCB_UNLOCK(stcb);
3563 			}
3564 		}
3565 		break;
3566 	case SCTP_SET_DYNAMIC_PRIMARY:
3567 		{
3568 			union sctp_sockstore *ss;
3569 
3570 			error = priv_check(curthread,
3571 			    PRIV_NETINET_RESERVEDPORT);
3572 			if (error)
3573 				break;
3574 
3575 			SCTP_CHECK_AND_CAST(ss, optval, union sctp_sockstore, optsize);
3576 			/* SUPER USER CHECK? */
3577 			error = sctp_dynamic_set_primary(&ss->sa, vrf_id);
3578 		}
3579 		break;
3580 	case SCTP_SET_PEER_PRIMARY_ADDR:
3581 		{
3582 			struct sctp_setpeerprim *sspp;
3583 
3584 			SCTP_CHECK_AND_CAST(sspp, optval, struct sctp_setpeerprim, optsize);
3585 			SCTP_FIND_STCB(inp, stcb, sspp->sspp_assoc_id);
3586 			if (stcb != NULL) {
3587 				struct sctp_ifa *ifa;
3588 
3589 				ifa = sctp_find_ifa_by_addr((struct sockaddr *)&sspp->sspp_addr,
3590 				    stcb->asoc.vrf_id, 0);
3591 				if (ifa == NULL) {
3592 					error = EINVAL;
3593 					goto out_of_it;
3594 				}
3595 				if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) {
3596 					/*
3597 					 * Must validate the ifa found is in
3598 					 * our ep
3599 					 */
3600 					struct sctp_laddr *laddr;
3601 					int found = 0;
3602 
3603 					LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
3604 						if (laddr->ifa == NULL) {
3605 							SCTPDBG(SCTP_DEBUG_OUTPUT1, "%s: NULL ifa\n",
3606 							    __FUNCTION__);
3607 							continue;
3608 						}
3609 						if (laddr->ifa == ifa) {
3610 							found = 1;
3611 							break;
3612 						}
3613 					}
3614 					if (!found) {
3615 						error = EINVAL;
3616 						goto out_of_it;
3617 					}
3618 				}
3619 				if (sctp_set_primary_ip_address_sa(stcb,
3620 				    (struct sockaddr *)&sspp->sspp_addr) != 0) {
3621 					error = EINVAL;
3622 				}
3623 		out_of_it:
3624 				SCTP_TCB_UNLOCK(stcb);
3625 			} else {
3626 				error = EINVAL;
3627 			}
3628 
3629 		}
3630 		break;
3631 	case SCTP_BINDX_ADD_ADDR:
3632 		{
3633 			struct sctp_getaddresses *addrs;
3634 			int sz;
3635 			struct thread *td;
3636 			int prison = 0;
3637 
3638 			td = (struct thread *)p;
3639 			if (jailed(td->td_ucred)) {
3640 				prison = 1;
3641 			}
3642 			SCTP_CHECK_AND_CAST(addrs, optval, struct sctp_getaddresses,
3643 			    optsize);
3644 			if (addrs->addr->sa_family == AF_INET) {
3645 				sz = sizeof(struct sctp_getaddresses) - sizeof(struct sockaddr) + sizeof(struct sockaddr_in);
3646 				if (optsize < sz) {
3647 					error = EINVAL;
3648 					break;
3649 				}
3650 				if (prison && prison_ip(td->td_ucred, 0, &(((struct sockaddr_in *)(addrs->addr))->sin_addr.s_addr))) {
3651 					error = EADDRNOTAVAIL;
3652 				}
3653 			} else if (addrs->addr->sa_family == AF_INET6) {
3654 				sz = sizeof(struct sctp_getaddresses) - sizeof(struct sockaddr) + sizeof(struct sockaddr_in6);
3655 				if (optsize < sz) {
3656 					error = EINVAL;
3657 					break;
3658 				}
3659 				/* JAIL XXXX Add else here for V6 */
3660 			}
3661 			sctp_bindx_add_address(so, inp, addrs->addr,
3662 			    addrs->sget_assoc_id, vrf_id,
3663 			    &error, p);
3664 		}
3665 		break;
3666 	case SCTP_BINDX_REM_ADDR:
3667 		{
3668 			struct sctp_getaddresses *addrs;
3669 			int sz;
3670 			struct thread *td;
3671 			int prison = 0;
3672 
3673 			td = (struct thread *)p;
3674 			if (jailed(td->td_ucred)) {
3675 				prison = 1;
3676 			}
3677 			SCTP_CHECK_AND_CAST(addrs, optval, struct sctp_getaddresses, optsize);
3678 			if (addrs->addr->sa_family == AF_INET) {
3679 				sz = sizeof(struct sctp_getaddresses) - sizeof(struct sockaddr) + sizeof(struct sockaddr_in);
3680 				if (optsize < sz) {
3681 					error = EINVAL;
3682 					break;
3683 				}
3684 				if (prison && prison_ip(td->td_ucred, 0, &(((struct sockaddr_in *)(addrs->addr))->sin_addr.s_addr))) {
3685 					error = EADDRNOTAVAIL;
3686 				}
3687 			} else if (addrs->addr->sa_family == AF_INET6) {
3688 				sz = sizeof(struct sctp_getaddresses) - sizeof(struct sockaddr) + sizeof(struct sockaddr_in6);
3689 				if (optsize < sz) {
3690 					error = EINVAL;
3691 					break;
3692 				}
3693 				/* JAIL XXXX Add else here for V6 */
3694 			}
3695 			sctp_bindx_delete_address(so, inp, addrs->addr,
3696 			    addrs->sget_assoc_id, vrf_id,
3697 			    &error);
3698 		}
3699 		break;
3700 	default:
3701 		error = ENOPROTOOPT;
3702 		break;
3703 	}			/* end switch (opt) */
3704 	return (error);
3705 }
3706 
3707 
3708 int
3709 sctp_ctloutput(struct socket *so, struct sockopt *sopt)
3710 {
3711 	void *optval = NULL;
3712 	size_t optsize = 0;
3713 	struct sctp_inpcb *inp;
3714 	void *p;
3715 	int error = 0;
3716 
3717 	inp = (struct sctp_inpcb *)so->so_pcb;
3718 	if (inp == 0) {
3719 		/* I made the same as TCP since we are not setup? */
3720 		return (ECONNRESET);
3721 	}
3722 	if (sopt->sopt_level != IPPROTO_SCTP) {
3723 		/* wrong proto level... send back up to IP */
3724 #ifdef INET6
3725 		if (INP_CHECK_SOCKAF(so, AF_INET6))
3726 			error = ip6_ctloutput(so, sopt);
3727 		else
3728 #endif				/* INET6 */
3729 			error = ip_ctloutput(so, sopt);
3730 		return (error);
3731 	}
3732 	optsize = sopt->sopt_valsize;
3733 	if (optsize) {
3734 		SCTP_MALLOC(optval, void *, optsize, SCTP_M_SOCKOPT);
3735 		if (optval == NULL) {
3736 			return (ENOBUFS);
3737 		}
3738 		error = sooptcopyin(sopt, optval, optsize, optsize);
3739 		if (error) {
3740 			SCTP_FREE(optval, SCTP_M_SOCKOPT);
3741 			goto out;
3742 		}
3743 	}
3744 	p = (void *)sopt->sopt_td;
3745 	if (sopt->sopt_dir == SOPT_SET) {
3746 		error = sctp_setopt(so, sopt->sopt_name, optval, optsize, p);
3747 	} else if (sopt->sopt_dir == SOPT_GET) {
3748 		error = sctp_getopt(so, sopt->sopt_name, optval, &optsize, p);
3749 	} else {
3750 		error = EINVAL;
3751 	}
3752 	if ((error == 0) && (optval != NULL)) {
3753 		error = sooptcopyout(sopt, optval, optsize);
3754 		SCTP_FREE(optval, SCTP_M_SOCKOPT);
3755 	} else if (optval != NULL) {
3756 		SCTP_FREE(optval, SCTP_M_SOCKOPT);
3757 	}
3758 out:
3759 	return (error);
3760 }
3761 
3762 
3763 static int
3764 sctp_connect(struct socket *so, struct sockaddr *addr, struct thread *p)
3765 {
3766 	int error = 0;
3767 	int create_lock_on = 0;
3768 	uint32_t vrf_id;
3769 	struct sctp_inpcb *inp;
3770 	struct sctp_tcb *stcb = NULL;
3771 
3772 	inp = (struct sctp_inpcb *)so->so_pcb;
3773 	if (inp == 0) {
3774 		/* I made the same as TCP since we are not setup? */
3775 		return (ECONNRESET);
3776 	}
3777 	if (addr == NULL)
3778 		return EINVAL;
3779 
3780 	if ((addr->sa_family == AF_INET6) && (addr->sa_len != sizeof(struct sockaddr_in6))) {
3781 		return (EINVAL);
3782 	}
3783 	if ((addr->sa_family == AF_INET) && (addr->sa_len != sizeof(struct sockaddr_in))) {
3784 		return (EINVAL);
3785 	}
3786 	SCTP_ASOC_CREATE_LOCK(inp);
3787 	create_lock_on = 1;
3788 
3789 	SCTP_INP_INCR_REF(inp);
3790 	if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
3791 	    (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) {
3792 		/* Should I really unlock ? */
3793 		error = EFAULT;
3794 		goto out_now;
3795 	}
3796 #ifdef INET6
3797 	if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) &&
3798 	    (addr->sa_family == AF_INET6)) {
3799 		error = EINVAL;
3800 		goto out_now;
3801 	}
3802 #endif				/* INET6 */
3803 	if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) ==
3804 	    SCTP_PCB_FLAGS_UNBOUND) {
3805 		/* Bind a ephemeral port */
3806 		error = sctp_inpcb_bind(so, NULL, p);
3807 		if (error) {
3808 			goto out_now;
3809 		}
3810 	}
3811 	/* Now do we connect? */
3812 	if (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) {
3813 		error = EINVAL;
3814 		goto out_now;
3815 	}
3816 	if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
3817 	    (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) {
3818 		/* We are already connected AND the TCP model */
3819 		error = EADDRINUSE;
3820 		goto out_now;
3821 	}
3822 	if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
3823 		SCTP_INP_RLOCK(inp);
3824 		stcb = LIST_FIRST(&inp->sctp_asoc_list);
3825 		SCTP_INP_RUNLOCK(inp);
3826 	} else {
3827 		/*
3828 		 * We increment here since sctp_findassociation_ep_addr()
3829 		 * wil do a decrement if it finds the stcb as long as the
3830 		 * locked tcb (last argument) is NOT a TCB.. aka NULL.
3831 		 */
3832 		SCTP_INP_INCR_REF(inp);
3833 		stcb = sctp_findassociation_ep_addr(&inp, addr, NULL, NULL, NULL);
3834 		if (stcb == NULL) {
3835 			SCTP_INP_DECR_REF(inp);
3836 		} else {
3837 			SCTP_TCB_LOCK(stcb);
3838 		}
3839 	}
3840 	if (stcb != NULL) {
3841 		/* Already have or am bring up an association */
3842 		error = EALREADY;
3843 		goto out_now;
3844 	}
3845 	vrf_id = inp->def_vrf_id;
3846 	/* We are GOOD to go */
3847 	stcb = sctp_aloc_assoc(inp, addr, 1, &error, 0, vrf_id);
3848 	if (stcb == NULL) {
3849 		/* Gak! no memory */
3850 		goto out_now;
3851 	}
3852 	if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) {
3853 		stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED;
3854 		/* Set the connected flag so we can queue data */
3855 		soisconnecting(so);
3856 	}
3857 	stcb->asoc.state = SCTP_STATE_COOKIE_WAIT;
3858 	(void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered);
3859 
3860 	/* initialize authentication parameters for the assoc */
3861 	sctp_initialize_auth_params(inp, stcb);
3862 
3863 	sctp_send_initiate(inp, stcb);
3864 	SCTP_TCB_UNLOCK(stcb);
3865 out_now:
3866 	if (create_lock_on) {
3867 		SCTP_ASOC_CREATE_UNLOCK(inp);
3868 	}
3869 	SCTP_INP_DECR_REF(inp);
3870 	return error;
3871 }
3872 
3873 int
3874 sctp_listen(struct socket *so, int backlog, struct thread *p)
3875 {
3876 	/*
3877 	 * Note this module depends on the protocol processing being called
3878 	 * AFTER any socket level flags and backlog are applied to the
3879 	 * socket. The traditional way that the socket flags are applied is
3880 	 * AFTER protocol processing. We have made a change to the
3881 	 * sys/kern/uipc_socket.c module to reverse this but this MUST be in
3882 	 * place if the socket API for SCTP is to work properly.
3883 	 */
3884 
3885 	int error = 0;
3886 	struct sctp_inpcb *inp;
3887 
3888 	inp = (struct sctp_inpcb *)so->so_pcb;
3889 	if (inp == 0) {
3890 		/* I made the same as TCP since we are not setup? */
3891 		return (ECONNRESET);
3892 	}
3893 	SCTP_INP_RLOCK(inp);
3894 #ifdef SCTP_LOCK_LOGGING
3895 	if (sctp_logging_level & SCTP_LOCK_LOGGING_ENABLE) {
3896 		sctp_log_lock(inp, (struct sctp_tcb *)NULL, SCTP_LOG_LOCK_SOCK);
3897 	}
3898 #endif
3899 	SOCK_LOCK(so);
3900 	error = solisten_proto_check(so);
3901 	if (error) {
3902 		SOCK_UNLOCK(so);
3903 		SCTP_INP_RUNLOCK(inp);
3904 		return (error);
3905 	}
3906 	if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
3907 	    (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) {
3908 		/* We are already connected AND the TCP model */
3909 		SCTP_INP_RUNLOCK(inp);
3910 		SOCK_UNLOCK(so);
3911 		return (EADDRINUSE);
3912 	}
3913 	if (inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) {
3914 		/* We must do a bind. */
3915 		SOCK_UNLOCK(so);
3916 		SCTP_INP_RUNLOCK(inp);
3917 		if ((error = sctp_inpcb_bind(so, NULL, p))) {
3918 			/* bind error, probably perm */
3919 			return (error);
3920 		}
3921 		SOCK_LOCK(so);
3922 	} else {
3923 		SCTP_INP_RUNLOCK(inp);
3924 	}
3925 	/* It appears for 7.0 and on, we must always call this. */
3926 	solisten_proto(so, backlog);
3927 	if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) {
3928 		/* remove the ACCEPTCONN flag for one-to-many sockets */
3929 		so->so_options &= ~SO_ACCEPTCONN;
3930 	}
3931 	if (backlog == 0) {
3932 		/* turning off listen */
3933 		so->so_options &= ~SO_ACCEPTCONN;
3934 	}
3935 	SOCK_UNLOCK(so);
3936 	return (error);
3937 }
3938 
3939 static int sctp_defered_wakeup_cnt = 0;
3940 
3941 int
3942 sctp_accept(struct socket *so, struct sockaddr **addr)
3943 {
3944 	struct sctp_tcb *stcb;
3945 	struct sctp_inpcb *inp;
3946 	union sctp_sockstore store;
3947 
3948 	int error;
3949 
3950 	inp = (struct sctp_inpcb *)so->so_pcb;
3951 
3952 	if (inp == 0) {
3953 		return (ECONNRESET);
3954 	}
3955 	SCTP_INP_RLOCK(inp);
3956 	if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) {
3957 		SCTP_INP_RUNLOCK(inp);
3958 		return (ENOTSUP);
3959 	}
3960 	if (so->so_state & SS_ISDISCONNECTED) {
3961 		SCTP_INP_RUNLOCK(inp);
3962 		return (ECONNABORTED);
3963 	}
3964 	stcb = LIST_FIRST(&inp->sctp_asoc_list);
3965 	if (stcb == NULL) {
3966 		SCTP_INP_RUNLOCK(inp);
3967 		return (ECONNRESET);
3968 	}
3969 	SCTP_TCB_LOCK(stcb);
3970 	SCTP_INP_RUNLOCK(inp);
3971 	store = stcb->asoc.primary_destination->ro._l_addr;
3972 	SCTP_TCB_UNLOCK(stcb);
3973 	if (store.sa.sa_family == AF_INET) {
3974 		struct sockaddr_in *sin;
3975 
3976 		SCTP_MALLOC_SONAME(sin, struct sockaddr_in *, sizeof *sin);
3977 		sin->sin_family = AF_INET;
3978 		sin->sin_len = sizeof(*sin);
3979 		sin->sin_port = ((struct sockaddr_in *)&store)->sin_port;
3980 		sin->sin_addr = ((struct sockaddr_in *)&store)->sin_addr;
3981 		*addr = (struct sockaddr *)sin;
3982 	} else {
3983 		struct sockaddr_in6 *sin6;
3984 
3985 		SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof *sin6);
3986 		sin6->sin6_family = AF_INET6;
3987 		sin6->sin6_len = sizeof(*sin6);
3988 		sin6->sin6_port = ((struct sockaddr_in6 *)&store)->sin6_port;
3989 
3990 		sin6->sin6_addr = ((struct sockaddr_in6 *)&store)->sin6_addr;
3991 		if ((error = sa6_recoverscope(sin6)) != 0) {
3992 			SCTP_FREE_SONAME(sin6);
3993 			return (error);
3994 		}
3995 		*addr = (struct sockaddr *)sin6;
3996 	}
3997 	/* Wake any delayed sleep action */
3998 	if (inp->sctp_flags & SCTP_PCB_FLAGS_DONT_WAKE) {
3999 		SCTP_INP_WLOCK(inp);
4000 		inp->sctp_flags &= ~SCTP_PCB_FLAGS_DONT_WAKE;
4001 		if (inp->sctp_flags & SCTP_PCB_FLAGS_WAKEOUTPUT) {
4002 			inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEOUTPUT;
4003 			SCTP_INP_WUNLOCK(inp);
4004 			SOCKBUF_LOCK(&inp->sctp_socket->so_snd);
4005 			if (sowriteable(inp->sctp_socket)) {
4006 				sowwakeup_locked(inp->sctp_socket);
4007 			} else {
4008 				SOCKBUF_UNLOCK(&inp->sctp_socket->so_snd);
4009 			}
4010 			SCTP_INP_WLOCK(inp);
4011 		}
4012 		if (inp->sctp_flags & SCTP_PCB_FLAGS_WAKEINPUT) {
4013 			inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEINPUT;
4014 			SCTP_INP_WUNLOCK(inp);
4015 			SOCKBUF_LOCK(&inp->sctp_socket->so_rcv);
4016 			if (soreadable(inp->sctp_socket)) {
4017 				sctp_defered_wakeup_cnt++;
4018 				sorwakeup_locked(inp->sctp_socket);
4019 			} else {
4020 				SOCKBUF_UNLOCK(&inp->sctp_socket->so_rcv);
4021 			}
4022 			SCTP_INP_WLOCK(inp);
4023 		}
4024 		SCTP_INP_WUNLOCK(inp);
4025 	}
4026 	return (0);
4027 }
4028 
4029 int
4030 sctp_ingetaddr(struct socket *so, struct sockaddr **addr)
4031 {
4032 	struct sockaddr_in *sin;
4033 	uint32_t vrf_id;
4034 	struct sctp_inpcb *inp;
4035 	struct sctp_ifa *sctp_ifa;
4036 
4037 	/*
4038 	 * Do the malloc first in case it blocks.
4039 	 */
4040 	SCTP_MALLOC_SONAME(sin, struct sockaddr_in *, sizeof *sin);
4041 	sin->sin_family = AF_INET;
4042 	sin->sin_len = sizeof(*sin);
4043 	inp = (struct sctp_inpcb *)so->so_pcb;
4044 	if (!inp) {
4045 		SCTP_FREE_SONAME(sin);
4046 		return ECONNRESET;
4047 	}
4048 	SCTP_INP_RLOCK(inp);
4049 	sin->sin_port = inp->sctp_lport;
4050 	if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
4051 		if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
4052 			struct sctp_tcb *stcb;
4053 			struct sockaddr_in *sin_a;
4054 			struct sctp_nets *net;
4055 			int fnd;
4056 
4057 			stcb = LIST_FIRST(&inp->sctp_asoc_list);
4058 			if (stcb == NULL) {
4059 				goto notConn;
4060 			}
4061 			fnd = 0;
4062 			sin_a = NULL;
4063 			SCTP_TCB_LOCK(stcb);
4064 			TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
4065 				sin_a = (struct sockaddr_in *)&net->ro._l_addr;
4066 				if (sin_a == NULL)
4067 					/* this will make coverity happy */
4068 					continue;
4069 
4070 				if (sin_a->sin_family == AF_INET) {
4071 					fnd = 1;
4072 					break;
4073 				}
4074 			}
4075 			if ((!fnd) || (sin_a == NULL)) {
4076 				/* punt */
4077 				SCTP_TCB_UNLOCK(stcb);
4078 				goto notConn;
4079 			}
4080 			vrf_id = inp->def_vrf_id;
4081 			sctp_ifa = sctp_source_address_selection(inp,
4082 			    stcb,
4083 			    (sctp_route_t *) & net->ro,
4084 			    net, 0, vrf_id);
4085 			if (sctp_ifa) {
4086 				sin->sin_addr = sctp_ifa->address.sin.sin_addr;
4087 				sctp_free_ifa(sctp_ifa);
4088 			}
4089 			SCTP_TCB_UNLOCK(stcb);
4090 		} else {
4091 			/* For the bound all case you get back 0 */
4092 	notConn:
4093 			sin->sin_addr.s_addr = 0;
4094 		}
4095 
4096 	} else {
4097 		/* Take the first IPv4 address in the list */
4098 		struct sctp_laddr *laddr;
4099 		int fnd = 0;
4100 
4101 		LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
4102 			if (laddr->ifa->address.sa.sa_family == AF_INET) {
4103 				struct sockaddr_in *sin_a;
4104 
4105 				sin_a = (struct sockaddr_in *)&laddr->ifa->address.sa;
4106 				sin->sin_addr = sin_a->sin_addr;
4107 				fnd = 1;
4108 				break;
4109 			}
4110 		}
4111 		if (!fnd) {
4112 			SCTP_FREE_SONAME(sin);
4113 			SCTP_INP_RUNLOCK(inp);
4114 			return ENOENT;
4115 		}
4116 	}
4117 	SCTP_INP_RUNLOCK(inp);
4118 	(*addr) = (struct sockaddr *)sin;
4119 	return (0);
4120 }
4121 
4122 int
4123 sctp_peeraddr(struct socket *so, struct sockaddr **addr)
4124 {
4125 	struct sockaddr_in *sin = (struct sockaddr_in *)*addr;
4126 	int fnd;
4127 	struct sockaddr_in *sin_a;
4128 	struct sctp_inpcb *inp;
4129 	struct sctp_tcb *stcb;
4130 	struct sctp_nets *net;
4131 
4132 	/* Do the malloc first in case it blocks. */
4133 	inp = (struct sctp_inpcb *)so->so_pcb;
4134 	if ((inp == NULL) ||
4135 	    ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)) {
4136 		/* UDP type and listeners will drop out here */
4137 		return (ENOTCONN);
4138 	}
4139 	SCTP_MALLOC_SONAME(sin, struct sockaddr_in *, sizeof *sin);
4140 	sin->sin_family = AF_INET;
4141 	sin->sin_len = sizeof(*sin);
4142 
4143 	/* We must recapture incase we blocked */
4144 	inp = (struct sctp_inpcb *)so->so_pcb;
4145 	if (!inp) {
4146 		SCTP_FREE_SONAME(sin);
4147 		return ECONNRESET;
4148 	}
4149 	SCTP_INP_RLOCK(inp);
4150 	stcb = LIST_FIRST(&inp->sctp_asoc_list);
4151 	if (stcb) {
4152 		SCTP_TCB_LOCK(stcb);
4153 	}
4154 	SCTP_INP_RUNLOCK(inp);
4155 	if (stcb == NULL) {
4156 		SCTP_FREE_SONAME(sin);
4157 		return ECONNRESET;
4158 	}
4159 	fnd = 0;
4160 	TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
4161 		sin_a = (struct sockaddr_in *)&net->ro._l_addr;
4162 		if (sin_a->sin_family == AF_INET) {
4163 			fnd = 1;
4164 			sin->sin_port = stcb->rport;
4165 			sin->sin_addr = sin_a->sin_addr;
4166 			break;
4167 		}
4168 	}
4169 	SCTP_TCB_UNLOCK(stcb);
4170 	if (!fnd) {
4171 		/* No IPv4 address */
4172 		SCTP_FREE_SONAME(sin);
4173 		return ENOENT;
4174 	}
4175 	(*addr) = (struct sockaddr *)sin;
4176 	return (0);
4177 }
4178 
4179 struct pr_usrreqs sctp_usrreqs = {
4180 	.pru_abort = sctp_abort,
4181 	.pru_accept = sctp_accept,
4182 	.pru_attach = sctp_attach,
4183 	.pru_bind = sctp_bind,
4184 	.pru_connect = sctp_connect,
4185 	.pru_control = in_control,
4186 	.pru_close = sctp_close,
4187 	.pru_detach = sctp_close,
4188 	.pru_sopoll = sopoll_generic,
4189 	.pru_disconnect = sctp_disconnect,
4190 	.pru_listen = sctp_listen,
4191 	.pru_peeraddr = sctp_peeraddr,
4192 	.pru_send = sctp_sendm,
4193 	.pru_shutdown = sctp_shutdown,
4194 	.pru_sockaddr = sctp_ingetaddr,
4195 	.pru_sosend = sctp_sosend,
4196 	.pru_soreceive = sctp_soreceive
4197 };
4198