sctp_usrreq.c revision 163959
1/*-
2 * Copyright (c) 2001-2006, 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: head/sys/netinet/sctp_usrreq.c 163959 2006-11-03 21:19:54Z rrs $");
35
36
37#include "opt_ipsec.h"
38#include "opt_inet6.h"
39#include "opt_inet.h"
40
41#include "opt_sctp.h"
42
43#include <sys/param.h>
44#include <sys/systm.h>
45#include <sys/kernel.h>
46#include <sys/malloc.h>
47#include <sys/mbuf.h>
48#include <sys/domain.h>
49#include <sys/proc.h>
50#include <sys/protosw.h>
51#include <sys/socket.h>
52#include <sys/socketvar.h>
53#include <sys/sysctl.h>
54#include <sys/syslog.h>
55#include <net/if.h>
56#include <net/if_types.h>
57#include <net/if_var.h>
58#include <net/route.h>
59#include <netinet/in.h>
60#include <netinet/in_systm.h>
61#include <netinet/ip.h>
62#include <netinet/ip6.h>
63#include <netinet/in_pcb.h>
64#include <netinet/in_var.h>
65#include <netinet/ip_var.h>
66#include <netinet6/ip6_var.h>
67#include <netinet6/in6_var.h>
68#include <netinet6/scope6_var.h>
69#include <netinet/ip_icmp.h>
70#include <netinet/icmp_var.h>
71#include <netinet/sctp_os.h>
72#include <netinet/sctp_pcb.h>
73#include <netinet/sctp_header.h>
74#include <netinet/sctp_var.h>
75#include <netinet/sctp_output.h>
76#include <netinet/sctp_bsd_addr.h>
77#include <netinet/sctp_uio.h>
78#include <netinet/sctp_asconf.h>
79#include <netinet/sctputil.h>
80#include <netinet/sctp_indata.h>
81#include <netinet/sctp_asconf.h>
82#include <netinet/sctp_timer.h>
83#include <netinet/sctp_auth.h>
84#ifdef IPSEC
85#include <netinet6/ipsec.h>
86#include <netkey/key.h>
87#endif				/* IPSEC */
88
89
90
91
92#ifndef in6pcb
93#define in6pcb		inpcb
94#endif
95#ifndef sotoin6pcb
96#define sotoin6pcb      sotoinpcb
97#endif
98
99
100
101/*
102 * sysctl tunable variables
103 */
104int sctp_sendspace = (128 * 1024);
105int sctp_recvspace = 128 * (1024 +
106#ifdef INET6
107    sizeof(struct sockaddr_in6)
108#else
109    sizeof(struct sockaddr_in)
110#endif
111);
112int sctp_mbuf_threshold_count = SCTP_DEFAULT_MBUFS_IN_CHAIN;
113int sctp_auto_asconf = SCTP_DEFAULT_AUTO_ASCONF;
114int sctp_ecn_enable = 1;
115int sctp_ecn_nonce = 0;
116int sctp_strict_sacks = 0;
117int sctp_no_csum_on_loopback = 1;
118int sctp_strict_init = 1;
119int sctp_abort_if_one_2_one_hits_limit = 0;
120int sctp_strict_data_order = 0;
121
122int sctp_peer_chunk_oh = sizeof(struct mbuf);
123int sctp_max_burst_default = SCTP_DEF_MAX_BURST;
124int sctp_use_cwnd_based_maxburst = 1;
125int sctp_do_drain = 1;
126int sctp_warm_the_crc32_table = 0;
127
128unsigned int sctp_max_chunks_on_queue = SCTP_ASOC_MAX_CHUNKS_ON_QUEUE;
129unsigned int sctp_delayed_sack_time_default = SCTP_RECV_MSEC;
130unsigned int sctp_heartbeat_interval_default = SCTP_HB_DEFAULT_MSEC;
131unsigned int sctp_pmtu_raise_time_default = SCTP_DEF_PMTU_RAISE_SEC;
132unsigned int sctp_shutdown_guard_time_default = SCTP_DEF_MAX_SHUTDOWN_SEC;
133unsigned int sctp_secret_lifetime_default = SCTP_DEFAULT_SECRET_LIFE_SEC;
134unsigned int sctp_rto_max_default = SCTP_RTO_UPPER_BOUND;
135unsigned int sctp_rto_min_default = SCTP_RTO_LOWER_BOUND;
136unsigned int sctp_rto_initial_default = SCTP_RTO_INITIAL;
137unsigned int sctp_init_rto_max_default = SCTP_RTO_UPPER_BOUND;
138unsigned int sctp_valid_cookie_life_default = SCTP_DEFAULT_COOKIE_LIFE;
139unsigned int sctp_init_rtx_max_default = SCTP_DEF_MAX_INIT;
140unsigned int sctp_assoc_rtx_max_default = SCTP_DEF_MAX_SEND;
141unsigned int sctp_path_rtx_max_default = SCTP_DEF_MAX_PATH_RTX;
142unsigned int sctp_nr_outgoing_streams_default = SCTP_OSTREAM_INITIAL;
143unsigned int sctp_add_more_threshold = SCTP_DEFAULT_ADD_MORE;
144
145uint32_t sctp_asoc_free_resc_limit = SCTP_DEF_ASOC_RESC_LIMIT;
146uint32_t sctp_system_free_resc_limit = SCTP_DEF_SYSTEM_RESC_LIMIT;
147
148int sctp_min_split_point = SCTP_DEFAULT_SPLIT_POINT_MIN;
149int sctp_pcbtblsize = SCTP_PCBHASHSIZE;
150int sctp_hashtblsize = SCTP_TCBHASHSIZE;
151int sctp_chunkscale = SCTP_CHUNKQUEUE_SCALE;
152
153unsigned int sctp_cmt_on_off = 0;
154unsigned int sctp_cmt_sockopt_on_off = 0;
155unsigned int sctp_cmt_use_dac = 0;
156unsigned int sctp_cmt_sockopt_use_dac = 0;
157
158int sctp_L2_abc_variable = 1;
159unsigned int sctp_early_fr = 0;
160unsigned int sctp_early_fr_msec = SCTP_MINFR_MSEC_TIMER;
161unsigned int sctp_use_rttvar_cc = 0;
162int sctp_says_check_for_deadlock = 0;
163unsigned int sctp_asconf_auth_nochk = 0;
164unsigned int sctp_auth_disable = 0;
165unsigned int sctp_auth_random_len = SCTP_AUTH_RANDOM_SIZE_DEFAULT;
166unsigned int sctp_auth_hmac_id_default = SCTP_AUTH_HMAC_ID_SHA1;
167struct sctpstat sctpstat;
168
169#ifdef SCTP_DEBUG
170extern uint32_t sctp_debug_on;
171
172#endif				/* SCTP_DEBUG */
173
174
175void
176sctp_init(void)
177{
178	/* Init the SCTP pcb in sctp_pcb.c */
179	u_long sb_max_adj;
180
181	sctp_pcb_init();
182
183	if ((nmbclusters / 8) > SCTP_ASOC_MAX_CHUNKS_ON_QUEUE)
184		sctp_max_chunks_on_queue = (nmbclusters / 8);
185	/*
186	 * Allow a user to take no more than 1/2 the number of clusters or
187	 * the SB_MAX whichever is smaller for the send window.
188	 */
189	sb_max_adj = (u_long)((u_quad_t) (SB_MAX) * MCLBYTES / (MSIZE + MCLBYTES));
190	sctp_sendspace = min((min(SB_MAX, sb_max_adj)),
191	    ((nmbclusters / 2) * SCTP_DEFAULT_MAXSEGMENT));
192	/*
193	 * Now for the recv window, should we take the same amount? or
194	 * should I do 1/2 the SB_MAX instead in the SB_MAX min above. For
195	 * now I will just copy.
196	 */
197	sctp_recvspace = sctp_sendspace;
198
199
200}
201
202
203#ifdef INET6
204void
205ip_2_ip6_hdr(struct ip6_hdr *ip6, struct ip *ip)
206{
207	bzero(ip6, sizeof(*ip6));
208
209	ip6->ip6_vfc = IPV6_VERSION;
210	ip6->ip6_plen = ip->ip_len;
211	ip6->ip6_nxt = ip->ip_p;
212	ip6->ip6_hlim = ip->ip_ttl;
213	ip6->ip6_src.s6_addr32[2] = ip6->ip6_dst.s6_addr32[2] =
214	    IPV6_ADDR_INT32_SMP;
215	ip6->ip6_src.s6_addr32[3] = ip->ip_src.s_addr;
216	ip6->ip6_dst.s6_addr32[3] = ip->ip_dst.s_addr;
217}
218
219#endif				/* INET6 */
220
221
222static void
223sctp_pathmtu_adustment(struct sctp_inpcb *inp,
224    struct sctp_tcb *stcb,
225    struct sctp_nets *net,
226    uint16_t nxtsz)
227{
228	struct sctp_tmit_chunk *chk;
229
230	/* Adjust that too */
231	stcb->asoc.smallest_mtu = nxtsz;
232	/* now off to subtract IP_DF flag if needed */
233
234	TAILQ_FOREACH(chk, &stcb->asoc.send_queue, sctp_next) {
235		if ((chk->send_size + IP_HDR_SIZE) > nxtsz) {
236			chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
237		}
238	}
239	TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
240		if ((chk->send_size + IP_HDR_SIZE) > nxtsz) {
241			/*
242			 * For this guy we also mark for immediate resend
243			 * since we sent to big of chunk
244			 */
245			chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
246			if (chk->sent != SCTP_DATAGRAM_RESEND) {
247				sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
248			}
249			chk->sent = SCTP_DATAGRAM_RESEND;
250			chk->rec.data.doing_fast_retransmit = 0;
251
252			/* Clear any time so NO RTT is being done */
253			chk->do_rtt = 0;
254			if (stcb->asoc.total_flight >= chk->book_size)
255				stcb->asoc.total_flight -= chk->book_size;
256			else
257				stcb->asoc.total_flight = 0;
258			if (stcb->asoc.total_flight_count > 0)
259				stcb->asoc.total_flight_count--;
260			if (net->flight_size >= chk->book_size)
261				net->flight_size -= chk->book_size;
262			else
263				net->flight_size = 0;
264		}
265	}
266}
267
268static void
269sctp_notify_mbuf(struct sctp_inpcb *inp,
270    struct sctp_tcb *stcb,
271    struct sctp_nets *net,
272    struct ip *ip,
273    struct sctphdr *sh)
274{
275	struct icmp *icmph;
276	int totsz, tmr_stopped = 0;
277	uint16_t nxtsz;
278
279	/* protection */
280	if ((inp == NULL) || (stcb == NULL) || (net == NULL) ||
281	    (ip == NULL) || (sh == NULL)) {
282		if (stcb != NULL)
283			SCTP_TCB_UNLOCK(stcb);
284		return;
285	}
286	/* First job is to verify the vtag matches what I would send */
287	if (ntohl(sh->v_tag) != (stcb->asoc.peer_vtag)) {
288		SCTP_TCB_UNLOCK(stcb);
289		return;
290	}
291	icmph = (struct icmp *)((caddr_t)ip - (sizeof(struct icmp) -
292	    sizeof(struct ip)));
293	if (icmph->icmp_type != ICMP_UNREACH) {
294		/* We only care about unreachable */
295		SCTP_TCB_UNLOCK(stcb);
296		return;
297	}
298	if (icmph->icmp_code != ICMP_UNREACH_NEEDFRAG) {
299		/* not a unreachable message due to frag. */
300		SCTP_TCB_UNLOCK(stcb);
301		return;
302	}
303	totsz = ip->ip_len;
304
305	nxtsz = ntohs(icmph->icmp_seq);
306	if (nxtsz == 0) {
307		/*
308		 * old type router that does not tell us what the next size
309		 * mtu is. Rats we will have to guess (in a educated fashion
310		 * of course)
311		 */
312		nxtsz = find_next_best_mtu(totsz);
313	}
314	/* Stop any PMTU timer */
315	if (callout_pending(&net->pmtu_timer.timer)) {
316		tmr_stopped = 1;
317		sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net);
318	}
319	/* Adjust destination size limit */
320	if (net->mtu > nxtsz) {
321		net->mtu = nxtsz;
322	}
323	/* now what about the ep? */
324	if (stcb->asoc.smallest_mtu > nxtsz) {
325		sctp_pathmtu_adustment(inp, stcb, net, nxtsz);
326	}
327	if (tmr_stopped)
328		sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net);
329
330	SCTP_TCB_UNLOCK(stcb);
331}
332
333
334void
335sctp_notify(struct sctp_inpcb *inp,
336    int errno,
337    struct sctphdr *sh,
338    struct sockaddr *to,
339    struct sctp_tcb *stcb,
340    struct sctp_nets *net)
341{
342	/* protection */
343	if ((inp == NULL) || (stcb == NULL) || (net == NULL) ||
344	    (sh == NULL) || (to == NULL)) {
345		return;
346	}
347	/* First job is to verify the vtag matches what I would send */
348	if (ntohl(sh->v_tag) != (stcb->asoc.peer_vtag)) {
349		return;
350	}
351	/* FIX ME FIX ME PROTOPT i.e. no SCTP should ALWAYS be an ABORT */
352
353	if ((errno == EHOSTUNREACH) ||	/* Host is not reachable */
354	    (errno == EHOSTDOWN) ||	/* Host is down */
355	    (errno == ECONNREFUSED) ||	/* Host refused the connection, (not
356					 * an abort?) */
357	    (errno == ENOPROTOOPT)	/* SCTP is not present on host */
358	    ) {
359		/*
360		 * Hmm reachablity problems we must examine closely. If its
361		 * not reachable, we may have lost a network. Or if there is
362		 * NO protocol at the other end named SCTP. well we consider
363		 * it a OOTB abort.
364		 */
365		if ((errno == EHOSTUNREACH) || (errno == EHOSTDOWN)) {
366			if (net->dest_state & SCTP_ADDR_REACHABLE) {
367				/* Ok that destination is NOT reachable */
368				net->dest_state &= ~SCTP_ADDR_REACHABLE;
369				net->dest_state |= SCTP_ADDR_NOT_REACHABLE;
370				net->error_count = net->failure_threshold + 1;
371				sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN,
372				    stcb, SCTP_FAILED_THRESHOLD,
373				    (void *)net);
374			}
375			if (stcb)
376				SCTP_TCB_UNLOCK(stcb);
377		} else {
378			/*
379			 * Here the peer is either playing tricks on us,
380			 * including an address that belongs to someone who
381			 * does not support SCTP OR was a userland
382			 * implementation that shutdown and now is dead. In
383			 * either case treat it like a OOTB abort with no
384			 * TCB
385			 */
386			sctp_abort_notification(stcb, SCTP_PEER_FAULTY);
387			sctp_free_assoc(inp, stcb, 0);
388			/* no need to unlock here, since the TCB is gone */
389		}
390	} else {
391		/* Send all others to the app */
392		if (stcb)
393			SCTP_TCB_UNLOCK(stcb);
394
395
396		if (inp->sctp_socket) {
397#ifdef SCTP_LOCK_LOGGING
398			sctp_log_lock(inp, stcb, SCTP_LOG_LOCK_SOCK);
399#endif
400			SOCK_LOCK(inp->sctp_socket);
401			inp->sctp_socket->so_error = errno;
402			sctp_sowwakeup(inp, inp->sctp_socket);
403			SOCK_UNLOCK(inp->sctp_socket);
404		}
405	}
406}
407
408void
409sctp_ctlinput(cmd, sa, vip)
410	int cmd;
411	struct sockaddr *sa;
412	void *vip;
413{
414	struct ip *ip = vip;
415	struct sctphdr *sh;
416	int s;
417
418
419	if (sa->sa_family != AF_INET ||
420	    ((struct sockaddr_in *)sa)->sin_addr.s_addr == INADDR_ANY) {
421		return;
422	}
423	if (PRC_IS_REDIRECT(cmd)) {
424		ip = 0;
425	} else if ((unsigned)cmd >= PRC_NCMDS || inetctlerrmap[cmd] == 0) {
426		return;
427	}
428	if (ip) {
429		struct sctp_inpcb *inp = NULL;
430		struct sctp_tcb *stcb = NULL;
431		struct sctp_nets *net = NULL;
432		struct sockaddr_in to, from;
433
434		sh = (struct sctphdr *)((caddr_t)ip + (ip->ip_hl << 2));
435		bzero(&to, sizeof(to));
436		bzero(&from, sizeof(from));
437		from.sin_family = to.sin_family = AF_INET;
438		from.sin_len = to.sin_len = sizeof(to);
439		from.sin_port = sh->src_port;
440		from.sin_addr = ip->ip_src;
441		to.sin_port = sh->dest_port;
442		to.sin_addr = ip->ip_dst;
443
444		/*
445		 * 'to' holds the dest of the packet that failed to be sent.
446		 * 'from' holds our local endpoint address. Thus we reverse
447		 * the to and the from in the lookup.
448		 */
449		s = splnet();
450		stcb = sctp_findassociation_addr_sa((struct sockaddr *)&from,
451		    (struct sockaddr *)&to,
452		    &inp, &net, 1);
453		if (stcb != NULL && inp && (inp->sctp_socket != NULL)) {
454			if (cmd != PRC_MSGSIZE) {
455				int cm;
456
457				if (cmd == PRC_HOSTDEAD) {
458					cm = EHOSTUNREACH;
459				} else {
460					cm = inetctlerrmap[cmd];
461				}
462				sctp_notify(inp, cm, sh,
463				    (struct sockaddr *)&to, stcb,
464				    net);
465			} else {
466				/* handle possible ICMP size messages */
467				sctp_notify_mbuf(inp, stcb, net, ip, sh);
468			}
469		} else {
470			if ((stcb == NULL) && (inp != NULL)) {
471				/* reduce ref-count */
472				SCTP_INP_WLOCK(inp);
473				SCTP_INP_DECR_REF(inp);
474				SCTP_INP_WUNLOCK(inp);
475			}
476		}
477		splx(s);
478	}
479	return;
480}
481
482static int
483sctp_getcred(SYSCTL_HANDLER_ARGS)
484{
485	struct sockaddr_in addrs[2];
486	struct sctp_inpcb *inp;
487	struct sctp_nets *net;
488	struct sctp_tcb *stcb;
489	int error, s;
490
491	error = suser(req->td);
492	if (error)
493		return (error);
494	error = SYSCTL_IN(req, addrs, sizeof(addrs));
495	if (error)
496		return (error);
497
498	s = splnet();
499	stcb = sctp_findassociation_addr_sa(sintosa(&addrs[0]),
500	    sintosa(&addrs[1]),
501	    &inp, &net, 1);
502	if (stcb == NULL || inp == NULL || inp->sctp_socket == NULL) {
503		if ((inp != NULL) && (stcb == NULL)) {
504			/* reduce ref-count */
505			SCTP_INP_WLOCK(inp);
506			SCTP_INP_DECR_REF(inp);
507			SCTP_INP_WUNLOCK(inp);
508		}
509		error = ENOENT;
510		goto out;
511	}
512	error = SYSCTL_OUT(req, inp->sctp_socket->so_cred, sizeof(struct ucred));
513	SCTP_TCB_UNLOCK(stcb);
514out:
515	splx(s);
516	return (error);
517}
518
519SYSCTL_PROC(_net_inet_sctp, OID_AUTO, getcred, CTLTYPE_OPAQUE | CTLFLAG_RW,
520    0, 0, sctp_getcred, "S,ucred", "Get the ucred of a SCTP connection");
521
522
523/*
524 * sysctl definitions
525 */
526
527SYSCTL_INT(_net_inet_sctp, OID_AUTO, sendspace, CTLFLAG_RW,
528    &sctp_sendspace, 0, "Maximum outgoing SCTP buffer size");
529
530SYSCTL_INT(_net_inet_sctp, OID_AUTO, recvspace, CTLFLAG_RW,
531    &sctp_recvspace, 0, "Maximum incoming SCTP buffer size");
532
533SYSCTL_INT(_net_inet_sctp, OID_AUTO, auto_asconf, CTLFLAG_RW,
534    &sctp_auto_asconf, 0, "Enable SCTP Auto-ASCONF");
535
536SYSCTL_INT(_net_inet_sctp, OID_AUTO, ecn_enable, CTLFLAG_RW,
537    &sctp_ecn_enable, 0, "Enable SCTP ECN");
538
539SYSCTL_INT(_net_inet_sctp, OID_AUTO, ecn_nonce, CTLFLAG_RW,
540    &sctp_ecn_nonce, 0, "Enable SCTP ECN Nonce");
541
542SYSCTL_INT(_net_inet_sctp, OID_AUTO, strict_sacks, CTLFLAG_RW,
543    &sctp_strict_sacks, 0, "Enable SCTP Strict SACK checking");
544
545SYSCTL_INT(_net_inet_sctp, OID_AUTO, loopback_nocsum, CTLFLAG_RW,
546    &sctp_no_csum_on_loopback, 0,
547    "Enable NO Csum on packets sent on loopback");
548
549SYSCTL_INT(_net_inet_sctp, OID_AUTO, strict_init, CTLFLAG_RW,
550    &sctp_strict_init, 0,
551    "Enable strict INIT/INIT-ACK singleton enforcement");
552
553SYSCTL_INT(_net_inet_sctp, OID_AUTO, peer_chkoh, CTLFLAG_RW,
554    &sctp_peer_chunk_oh, 0,
555    "Amount to debit peers rwnd per chunk sent");
556
557SYSCTL_INT(_net_inet_sctp, OID_AUTO, maxburst, CTLFLAG_RW,
558    &sctp_max_burst_default, 0,
559    "Default max burst for sctp endpoints");
560
561SYSCTL_INT(_net_inet_sctp, OID_AUTO, maxchunks, CTLFLAG_RW,
562    &sctp_max_chunks_on_queue, 0,
563    "Default max chunks on queue per asoc");
564
565SYSCTL_INT(_net_inet_sctp, OID_AUTO, tcbhashsize, CTLFLAG_RW,
566    &sctp_hashtblsize, 0,
567    "Tuneable for Hash table sizes");
568
569SYSCTL_INT(_net_inet_sctp, OID_AUTO, min_split_point, CTLFLAG_RW,
570    &sctp_min_split_point, 0,
571    "Minimum size when splitting a chunk");
572
573SYSCTL_INT(_net_inet_sctp, OID_AUTO, pcbhashsize, CTLFLAG_RW,
574    &sctp_pcbtblsize, 0,
575    "Tuneable for PCB Hash table sizes");
576
577SYSCTL_INT(_net_inet_sctp, OID_AUTO, sys_resource, CTLFLAG_RW,
578    &sctp_system_free_resc_limit, 0,
579    "Max number of cached resources in the system");
580
581SYSCTL_INT(_net_inet_sctp, OID_AUTO, asoc_resource, CTLFLAG_RW,
582    &sctp_asoc_free_resc_limit, 0,
583    "Max number of cached resources in an asoc");
584
585
586SYSCTL_INT(_net_inet_sctp, OID_AUTO, chunkscale, CTLFLAG_RW,
587    &sctp_chunkscale, 0,
588    "Tuneable for Scaling of number of chunks and messages");
589
590
591SYSCTL_UINT(_net_inet_sctp, OID_AUTO, delayed_sack_time, CTLFLAG_RW,
592    &sctp_delayed_sack_time_default, 0,
593    "Default delayed SACK timer in msec");
594
595SYSCTL_UINT(_net_inet_sctp, OID_AUTO, heartbeat_interval, CTLFLAG_RW,
596    &sctp_heartbeat_interval_default, 0,
597    "Default heartbeat interval in msec");
598
599SYSCTL_UINT(_net_inet_sctp, OID_AUTO, pmtu_raise_time, CTLFLAG_RW,
600    &sctp_pmtu_raise_time_default, 0,
601    "Default PMTU raise timer in sec");
602
603SYSCTL_UINT(_net_inet_sctp, OID_AUTO, shutdown_guard_time, CTLFLAG_RW,
604    &sctp_shutdown_guard_time_default, 0,
605    "Default shutdown guard timer in sec");
606
607SYSCTL_UINT(_net_inet_sctp, OID_AUTO, secret_lifetime, CTLFLAG_RW,
608    &sctp_secret_lifetime_default, 0,
609    "Default secret lifetime in sec");
610
611SYSCTL_UINT(_net_inet_sctp, OID_AUTO, rto_max, CTLFLAG_RW,
612    &sctp_rto_max_default, 0,
613    "Default maximum retransmission timeout in msec");
614
615SYSCTL_UINT(_net_inet_sctp, OID_AUTO, rto_min, CTLFLAG_RW,
616    &sctp_rto_min_default, 0,
617    "Default minimum retransmission timeout in msec");
618
619SYSCTL_UINT(_net_inet_sctp, OID_AUTO, rto_initial, CTLFLAG_RW,
620    &sctp_rto_initial_default, 0,
621    "Default initial retransmission timeout in msec");
622
623SYSCTL_UINT(_net_inet_sctp, OID_AUTO, init_rto_max, CTLFLAG_RW,
624    &sctp_init_rto_max_default, 0,
625    "Default maximum retransmission timeout during association setup in msec");
626
627SYSCTL_UINT(_net_inet_sctp, OID_AUTO, valid_cookie_life, CTLFLAG_RW,
628    &sctp_valid_cookie_life_default, 0,
629    "Default cookie lifetime in sec");
630
631SYSCTL_UINT(_net_inet_sctp, OID_AUTO, init_rtx_max, CTLFLAG_RW,
632    &sctp_init_rtx_max_default, 0,
633    "Default maximum number of retransmission for INIT chunks");
634
635SYSCTL_UINT(_net_inet_sctp, OID_AUTO, assoc_rtx_max, CTLFLAG_RW,
636    &sctp_assoc_rtx_max_default, 0,
637    "Default maximum number of retransmissions per association");
638
639SYSCTL_UINT(_net_inet_sctp, OID_AUTO, path_rtx_max, CTLFLAG_RW,
640    &sctp_path_rtx_max_default, 0,
641    "Default maximum of retransmissions per path");
642
643SYSCTL_UINT(_net_inet_sctp, OID_AUTO, add_more_on_output, CTLFLAG_RW,
644    &sctp_add_more_threshold, 0,
645    "When space wise is it worthwhile to try to add more to a socket send buffer");
646
647
648SYSCTL_UINT(_net_inet_sctp, OID_AUTO, nr_outgoing_streams, CTLFLAG_RW,
649    &sctp_nr_outgoing_streams_default, 0,
650    "Default number of outgoing streams");
651
652SYSCTL_UINT(_net_inet_sctp, OID_AUTO, cmt_on_off, CTLFLAG_RW,
653    &sctp_cmt_on_off, 0,
654    "CMT ON/OFF flag");
655
656SYSCTL_UINT(_net_inet_sctp, OID_AUTO, cwnd_maxburst, CTLFLAG_RW,
657    &sctp_use_cwnd_based_maxburst, 0,
658    "Use a CWND adjusting maxburst");
659
660SYSCTL_UINT(_net_inet_sctp, OID_AUTO, early_fast_retran, CTLFLAG_RW,
661    &sctp_early_fr, 0,
662    "Early Fast Retransmit with Timer");
663
664SYSCTL_UINT(_net_inet_sctp, OID_AUTO, use_rttvar_congctrl, CTLFLAG_RW,
665    &sctp_use_rttvar_cc, 0,
666    "Use congestion control via rtt variation");
667
668SYSCTL_UINT(_net_inet_sctp, OID_AUTO, deadlock_detect, CTLFLAG_RW,
669    &sctp_says_check_for_deadlock, 0,
670    "SMP Deadlock detection on/off");
671
672SYSCTL_UINT(_net_inet_sctp, OID_AUTO, early_fast_retran_msec, CTLFLAG_RW,
673    &sctp_early_fr_msec, 0,
674    "Early Fast Retransmit minimum timer value");
675
676SYSCTL_UINT(_net_inet_sctp, OID_AUTO, asconf_auth_nochk, CTLFLAG_RW,
677    &sctp_asconf_auth_nochk, 0,
678    "Disable SCTP ASCONF AUTH requirement");
679
680SYSCTL_UINT(_net_inet_sctp, OID_AUTO, auth_disable, CTLFLAG_RW,
681    &sctp_auth_disable, 0,
682    "Disable SCTP AUTH chunk requirement/function");
683
684SYSCTL_UINT(_net_inet_sctp, OID_AUTO, auth_random_len, CTLFLAG_RW,
685    &sctp_auth_random_len, 0,
686    "Length of AUTH RANDOMs");
687
688SYSCTL_UINT(_net_inet_sctp, OID_AUTO, auth_hmac_id, CTLFLAG_RW,
689    &sctp_auth_hmac_id_default, 0,
690    "Default HMAC Id for SCTP AUTHenthication");
691
692SYSCTL_INT(_net_inet_sctp, OID_AUTO, abc_l_var, CTLFLAG_RW,
693    &sctp_L2_abc_variable, 0,
694    "SCTP ABC max increase per SACK (L)");
695
696SYSCTL_INT(_net_inet_sctp, OID_AUTO, max_chained_mbufs, CTLFLAG_RW,
697    &sctp_mbuf_threshold_count, 0,
698    "Default max number of small mbufs on a chain");
699
700SYSCTL_UINT(_net_inet_sctp, OID_AUTO, cmt_use_dac, CTLFLAG_RW,
701    &sctp_cmt_use_dac, 0,
702    "CMT DAC ON/OFF flag");
703
704SYSCTL_INT(_net_inet_sctp, OID_AUTO, do_sctp_drain, CTLFLAG_RW,
705    &sctp_do_drain, 0,
706    "Should SCTP respond to the drain calls");
707
708SYSCTL_INT(_net_inet_sctp, OID_AUTO, warm_crc_table, CTLFLAG_RW,
709    &sctp_warm_the_crc32_table, 0,
710    "Should the CRC32c tables be warmed before checksum?");
711
712SYSCTL_INT(_net_inet_sctp, OID_AUTO, abort_at_limit, CTLFLAG_RW,
713    &sctp_abort_if_one_2_one_hits_limit, 0,
714    "When one-2-one hits qlimit abort");
715
716SYSCTL_INT(_net_inet_sctp, OID_AUTO, strict_data_order, CTLFLAG_RW,
717    &sctp_strict_data_order, 0,
718    "Enforce strict data ordering, abort if control inside data");
719
720SYSCTL_STRUCT(_net_inet_sctp, OID_AUTO, stats, CTLFLAG_RW,
721    &sctpstat, sctpstat,
722    "SCTP statistics (struct sctps_stat, netinet/sctp.h");
723#ifdef SCTP_DEBUG
724SYSCTL_INT(_net_inet_sctp, OID_AUTO, debug, CTLFLAG_RW,
725    &sctp_debug_on, 0, "Configure debug output");
726#endif				/* SCTP_DEBUG */
727
728static void
729sctp_abort(struct socket *so)
730{
731	struct sctp_inpcb *inp;
732	int s;
733	uint32_t flags;
734
735	inp = (struct sctp_inpcb *)so->so_pcb;
736	if (inp == 0)
737		return;
738
739	s = splnet();
740sctp_must_try_again:
741	flags = inp->sctp_flags;
742#ifdef SCTP_LOG_CLOSING
743	sctp_log_closing(inp, NULL, 17);
744#endif
745	if (((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
746	    (atomic_cmpset_int(&inp->sctp_flags, flags, (flags | SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_CLOSE_IP)))) {
747#ifdef SCTP_LOG_CLOSING
748		sctp_log_closing(inp, NULL, 16);
749#endif
750		sctp_inpcb_free(inp, 1, 0);
751		SOCK_LOCK(so);
752		so->so_snd.sb_cc = 0;
753		so->so_snd.sb_mb = NULL;
754		so->so_snd.sb_mbcnt = 0;
755
756		/*
757		 * same for the rcv ones, they are only here for the
758		 * accounting/select.
759		 */
760		so->so_rcv.sb_cc = 0;
761		so->so_rcv.sb_mb = NULL;
762		so->so_rcv.sb_mbcnt = 0;
763		/*
764		 * Now null out the reference, we are completely detached.
765		 */
766		so->so_pcb = NULL;
767		SOCK_UNLOCK(so);
768
769	} else {
770		flags = inp->sctp_flags;
771		if ((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) {
772			goto sctp_must_try_again;
773		}
774	}
775	splx(s);
776	return;
777}
778
779static int
780sctp_attach(struct socket *so, int proto, struct thread *p)
781{
782	struct sctp_inpcb *inp;
783	struct inpcb *ip_inp;
784	int s, error;
785
786#ifdef IPSEC
787	uint32_t flags;
788
789#endif
790	s = splnet();
791	inp = (struct sctp_inpcb *)so->so_pcb;
792	if (inp != 0) {
793		splx(s);
794		return EINVAL;
795	}
796	error = soreserve(so, sctp_sendspace, sctp_recvspace);
797	if (error) {
798		splx(s);
799		return error;
800	}
801	error = sctp_inpcb_alloc(so);
802	if (error) {
803		splx(s);
804		return error;
805	}
806	inp = (struct sctp_inpcb *)so->so_pcb;
807	SCTP_INP_WLOCK(inp);
808
809	inp->sctp_flags &= ~SCTP_PCB_FLAGS_BOUND_V6;	/* I'm not v6! */
810	ip_inp = &inp->ip_inp.inp;
811	ip_inp->inp_vflag |= INP_IPV4;
812	ip_inp->inp_ip_ttl = ip_defttl;
813
814#ifdef IPSEC
815	error = ipsec_init_pcbpolicy(so, &ip_inp->inp_sp);
816#ifdef SCTP_LOG_CLOSING
817	sctp_log_closing(inp, NULL, 17);
818#endif
819	if (error != 0) {
820		flags = inp->sctp_flags;
821		if (((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
822		    (atomic_cmpset_int(&inp->sctp_flags, flags, (flags | SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_CLOSE_IP)))) {
823#ifdef SCTP_LOG_CLOSING
824			sctp_log_closing(inp, NULL, 15);
825#endif
826			sctp_inpcb_free(inp, 1, 0);
827		}
828		return error;
829	}
830#endif				/* IPSEC */
831	SCTP_INP_WUNLOCK(inp);
832	splx(s);
833	return 0;
834}
835
836static int
837sctp_bind(struct socket *so, struct sockaddr *addr, struct thread *p)
838{
839	struct sctp_inpcb *inp;
840	int s, error;
841
842#ifdef INET6
843	if (addr && addr->sa_family != AF_INET)
844		/* must be a v4 address! */
845		return EINVAL;
846#endif				/* INET6 */
847
848	inp = (struct sctp_inpcb *)so->so_pcb;
849	if (inp == 0)
850		return EINVAL;
851
852	s = splnet();
853	error = sctp_inpcb_bind(so, addr, p);
854	splx(s);
855	return error;
856}
857
858static void
859sctp_close(struct socket *so)
860{
861	struct sctp_inpcb *inp;
862	uint32_t flags;
863
864	inp = (struct sctp_inpcb *)so->so_pcb;
865	if (inp == 0)
866		return;
867
868	/*
869	 * Inform all the lower layer assoc that we are done.
870	 */
871sctp_must_try_again:
872	flags = inp->sctp_flags;
873#ifdef SCTP_LOG_CLOSING
874	sctp_log_closing(inp, NULL, 17);
875#endif
876	if (((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
877	    (atomic_cmpset_int(&inp->sctp_flags, flags, (flags | SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_CLOSE_IP)))) {
878		if (((so->so_options & SO_LINGER) && (so->so_linger == 0)) ||
879		    (so->so_rcv.sb_cc > 0)) {
880#ifdef SCTP_LOG_CLOSING
881			sctp_log_closing(inp, NULL, 13);
882#endif
883			sctp_inpcb_free(inp, 1, 1);
884		} else {
885#ifdef SCTP_LOG_CLOSING
886			sctp_log_closing(inp, NULL, 14);
887#endif
888			sctp_inpcb_free(inp, 0, 1);
889		}
890		/*
891		 * The socket is now detached, no matter what the state of
892		 * the SCTP association.
893		 */
894		SOCK_LOCK(so);
895		so->so_snd.sb_cc = 0;
896		so->so_snd.sb_mb = NULL;
897		so->so_snd.sb_mbcnt = 0;
898
899		/*
900		 * same for the rcv ones, they are only here for the
901		 * accounting/select.
902		 */
903		so->so_rcv.sb_cc = 0;
904		so->so_rcv.sb_mb = NULL;
905		so->so_rcv.sb_mbcnt = 0;
906		/*
907		 * Now null out the reference, we are completely detached.
908		 */
909		so->so_pcb = NULL;
910		SOCK_UNLOCK(so);
911	} else {
912		flags = inp->sctp_flags;
913		if ((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) {
914			goto sctp_must_try_again;
915		}
916	}
917	return;
918}
919
920
921int
922sctp_sendm(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
923    struct mbuf *control, struct thread *p);
924
925
926int
927sctp_sendm(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
928    struct mbuf *control, struct thread *p)
929{
930	struct sctp_inpcb *inp;
931	int error;
932
933	inp = (struct sctp_inpcb *)so->so_pcb;
934	if (inp == 0) {
935		if (control) {
936			sctp_m_freem(control);
937			control = NULL;
938		}
939		sctp_m_freem(m);
940		return EINVAL;
941	}
942	/* Got to have an to address if we are NOT a connected socket */
943	if ((addr == NULL) &&
944	    ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) ||
945	    (inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE))
946	    ) {
947		goto connected_type;
948	} else if (addr == NULL) {
949		error = EDESTADDRREQ;
950		sctp_m_freem(m);
951		if (control) {
952			sctp_m_freem(control);
953			control = NULL;
954		}
955		return (error);
956	}
957#ifdef INET6
958	if (addr->sa_family != AF_INET) {
959		/* must be a v4 address! */
960		sctp_m_freem(m);
961		if (control) {
962			sctp_m_freem(control);
963			control = NULL;
964		}
965		error = EDESTADDRREQ;
966		return EINVAL;
967	}
968#endif				/* INET6 */
969connected_type:
970	/* now what about control */
971	if (control) {
972		if (inp->control) {
973			printf("huh? control set?\n");
974			sctp_m_freem(inp->control);
975			inp->control = NULL;
976		}
977		inp->control = control;
978	}
979	/* add it in possibly */
980	if ((inp->pkt) && (inp->pkt->m_flags & M_PKTHDR)) {
981		struct mbuf *x;
982		int c_len;
983
984		c_len = 0;
985		/* How big is it */
986		for (x = m; x; x = x->m_next) {
987			c_len += x->m_len;
988		}
989		inp->pkt->m_pkthdr.len += c_len;
990	}
991	/* Place the data */
992	if (inp->pkt) {
993		inp->pkt_last->m_next = m;
994		inp->pkt_last = m;
995	} else {
996		inp->pkt_last = inp->pkt = m;
997	}
998	if (
999	/* FreeBSD uses a flag passed */
1000	    ((flags & PRUS_MORETOCOME) == 0)
1001	    ) {
1002		/*
1003		 * note with the current version this code will only be used
1004		 * by OpenBSD-- NetBSD, FreeBSD, and MacOS have methods for
1005		 * re-defining sosend to use the sctp_sosend. One can
1006		 * optionally switch back to this code (by changing back the
1007		 * definitions) but this is not advisable. This code is used
1008		 * by FreeBSD when sending a file with sendfile() though.
1009		 */
1010		int ret;
1011
1012		ret = sctp_output(inp, inp->pkt, addr, inp->control, p, flags);
1013		inp->pkt = NULL;
1014		inp->control = NULL;
1015		return (ret);
1016	} else {
1017		return (0);
1018	}
1019}
1020
1021static int
1022sctp_disconnect(struct socket *so)
1023{
1024	struct sctp_inpcb *inp;
1025	int s;
1026
1027	s = splnet();
1028	inp = (struct sctp_inpcb *)so->so_pcb;
1029	if (inp == NULL) {
1030		splx(s);
1031		return (ENOTCONN);
1032	}
1033	SCTP_INP_RLOCK(inp);
1034	if (inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) {
1035		if (LIST_EMPTY(&inp->sctp_asoc_list)) {
1036			/* No connection */
1037			splx(s);
1038			SCTP_INP_RUNLOCK(inp);
1039			return (0);
1040		} else {
1041			struct sctp_association *asoc;
1042			struct sctp_tcb *stcb;
1043
1044			stcb = LIST_FIRST(&inp->sctp_asoc_list);
1045			if (stcb == NULL) {
1046				splx(s);
1047				SCTP_INP_RUNLOCK(inp);
1048				return (EINVAL);
1049			}
1050			SCTP_TCB_LOCK(stcb);
1051			asoc = &stcb->asoc;
1052			if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
1053				/* We are about to be freed, out of here */
1054				SCTP_TCB_UNLOCK(stcb);
1055				SCTP_INP_RUNLOCK(inp);
1056				return (0);
1057			}
1058			if (((so->so_options & SO_LINGER) &&
1059			    (so->so_linger == 0)) ||
1060			    (so->so_rcv.sb_cc > 0)) {
1061				if (SCTP_GET_STATE(asoc) !=
1062				    SCTP_STATE_COOKIE_WAIT) {
1063					/* Left with Data unread */
1064					struct mbuf *err;
1065
1066					err = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr), 0, M_DONTWAIT, 1, MT_DATA);
1067					if (err) {
1068						/*
1069						 * Fill in the user
1070						 * initiated abort
1071						 */
1072						struct sctp_paramhdr *ph;
1073
1074						ph = mtod(err, struct sctp_paramhdr *);
1075						err->m_len = sizeof(struct sctp_paramhdr);
1076						ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
1077						ph->param_length = htons(err->m_len);
1078					}
1079					sctp_send_abort_tcb(stcb, err);
1080					SCTP_STAT_INCR_COUNTER32(sctps_aborted);
1081				}
1082				SCTP_INP_RUNLOCK(inp);
1083				if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) ||
1084				    (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
1085					SCTP_STAT_DECR_GAUGE32(sctps_currestab);
1086				}
1087				sctp_free_assoc(inp, stcb, 0);
1088				/* No unlock tcb assoc is gone */
1089				splx(s);
1090				return (0);
1091			}
1092			if (TAILQ_EMPTY(&asoc->send_queue) &&
1093			    TAILQ_EMPTY(&asoc->sent_queue) &&
1094			    (asoc->stream_queue_cnt == 0)) {
1095				/* there is nothing queued to send, so done */
1096				if (asoc->locked_on_sending) {
1097					goto abort_anyway;
1098				}
1099				if ((SCTP_GET_STATE(asoc) !=
1100				    SCTP_STATE_SHUTDOWN_SENT) &&
1101				    (SCTP_GET_STATE(asoc) !=
1102				    SCTP_STATE_SHUTDOWN_ACK_SENT)) {
1103					/* only send SHUTDOWN 1st time thru */
1104					sctp_stop_timers_for_shutdown(stcb);
1105					sctp_send_shutdown(stcb,
1106					    stcb->asoc.primary_destination);
1107					sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3);
1108					asoc->state = SCTP_STATE_SHUTDOWN_SENT;
1109					SCTP_STAT_DECR_GAUGE32(sctps_currestab);
1110					sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
1111					    stcb->sctp_ep, stcb,
1112					    asoc->primary_destination);
1113					sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
1114					    stcb->sctp_ep, stcb,
1115					    asoc->primary_destination);
1116				}
1117			} else {
1118				/*
1119				 * we still got (or just got) data to send,
1120				 * so set SHUTDOWN_PENDING
1121				 */
1122				/*
1123				 * XXX sockets draft says that SCTP_EOF
1124				 * should be sent with no data. currently,
1125				 * we will allow user data to be sent first
1126				 * and move to SHUTDOWN-PENDING
1127				 */
1128				asoc->state |= SCTP_STATE_SHUTDOWN_PENDING;
1129				sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, stcb->sctp_ep, stcb,
1130				    asoc->primary_destination);
1131				if (asoc->locked_on_sending) {
1132					/* Locked to send out the data */
1133					struct sctp_stream_queue_pending *sp;
1134
1135					sp = TAILQ_LAST(&asoc->locked_on_sending->outqueue, sctp_streamhead);
1136					if (sp == NULL) {
1137						printf("Error, sp is NULL, locked on sending is non-null strm:%d\n",
1138						    asoc->locked_on_sending->stream_no);
1139					} else {
1140						if ((sp->length == 0) && (sp->msg_is_complete == 0))
1141							asoc->state |= SCTP_STATE_PARTIAL_MSG_LEFT;
1142					}
1143				}
1144				if (TAILQ_EMPTY(&asoc->send_queue) &&
1145				    TAILQ_EMPTY(&asoc->sent_queue) &&
1146				    (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT)) {
1147					struct mbuf *op_err;
1148
1149			abort_anyway:
1150					op_err = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
1151					    0, M_DONTWAIT, 1, MT_DATA);
1152					if (op_err) {
1153						/*
1154						 * Fill in the user
1155						 * initiated abort
1156						 */
1157						struct sctp_paramhdr *ph;
1158						uint32_t *ippp;
1159
1160						op_err->m_len =
1161						    (sizeof(struct sctp_paramhdr) + sizeof(uint32_t));
1162						ph = mtod(op_err,
1163						    struct sctp_paramhdr *);
1164						ph->param_type = htons(
1165						    SCTP_CAUSE_USER_INITIATED_ABT);
1166						ph->param_length = htons(op_err->m_len);
1167						ippp = (uint32_t *) (ph + 1);
1168						*ippp = htonl(0x30000007);
1169					}
1170					sctp_send_abort_tcb(stcb, op_err);
1171					SCTP_STAT_INCR_COUNTER32(sctps_aborted);
1172					if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) ||
1173					    (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
1174						SCTP_STAT_DECR_GAUGE32(sctps_currestab);
1175					}
1176					SCTP_INP_RUNLOCK(inp);
1177					sctp_free_assoc(inp, stcb, 0);
1178					splx(s);
1179					return (0);
1180				}
1181			}
1182			SCTP_TCB_UNLOCK(stcb);
1183			SCTP_INP_RUNLOCK(inp);
1184			splx(s);
1185			return (0);
1186		}
1187		/* not reached */
1188	} else {
1189		/* UDP model does not support this */
1190		SCTP_INP_RUNLOCK(inp);
1191		splx(s);
1192		return EOPNOTSUPP;
1193	}
1194}
1195
1196int
1197sctp_shutdown(struct socket *so)
1198{
1199	struct sctp_inpcb *inp;
1200	int s;
1201
1202	s = splnet();
1203	inp = (struct sctp_inpcb *)so->so_pcb;
1204	if (inp == 0) {
1205		splx(s);
1206		return EINVAL;
1207	}
1208	SCTP_INP_RLOCK(inp);
1209	/* For UDP model this is a invalid call */
1210	if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) {
1211		/* Restore the flags that the soshutdown took away. */
1212		so->so_rcv.sb_state &= ~SBS_CANTRCVMORE;
1213		/* This proc will wakeup for read and do nothing (I hope) */
1214		splx(s);
1215		SCTP_INP_RUNLOCK(inp);
1216		return (EOPNOTSUPP);
1217	}
1218	/*
1219	 * Ok if we reach here its the TCP model and it is either a SHUT_WR
1220	 * or SHUT_RDWR. This means we put the shutdown flag against it.
1221	 */
1222	{
1223		struct sctp_tcb *stcb;
1224		struct sctp_association *asoc;
1225
1226		socantsendmore(so);
1227
1228		stcb = LIST_FIRST(&inp->sctp_asoc_list);
1229		if (stcb == NULL) {
1230			/*
1231			 * Ok we hit the case that the shutdown call was
1232			 * made after an abort or something. Nothing to do
1233			 * now.
1234			 */
1235			splx(s);
1236			return (0);
1237		}
1238		SCTP_TCB_LOCK(stcb);
1239		asoc = &stcb->asoc;
1240		if (TAILQ_EMPTY(&asoc->send_queue) &&
1241		    TAILQ_EMPTY(&asoc->sent_queue) &&
1242		    (asoc->stream_queue_cnt == 0)) {
1243			if (asoc->locked_on_sending) {
1244				goto abort_anyway;
1245			}
1246			/* there is nothing queued to send, so I'm done... */
1247			if (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT) {
1248				/* only send SHUTDOWN the first time through */
1249				sctp_stop_timers_for_shutdown(stcb);
1250				sctp_send_shutdown(stcb,
1251				    stcb->asoc.primary_destination);
1252				sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3);
1253				asoc->state = SCTP_STATE_SHUTDOWN_SENT;
1254				SCTP_STAT_DECR_GAUGE32(sctps_currestab);
1255				sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
1256				    stcb->sctp_ep, stcb,
1257				    asoc->primary_destination);
1258				sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
1259				    stcb->sctp_ep, stcb,
1260				    asoc->primary_destination);
1261			}
1262		} else {
1263			/*
1264			 * we still got (or just got) data to send, so set
1265			 * SHUTDOWN_PENDING
1266			 */
1267			asoc->state |= SCTP_STATE_SHUTDOWN_PENDING;
1268			sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, stcb->sctp_ep, stcb,
1269			    asoc->primary_destination);
1270
1271			if (asoc->locked_on_sending) {
1272				/* Locked to send out the data */
1273				struct sctp_stream_queue_pending *sp;
1274
1275				sp = TAILQ_LAST(&asoc->locked_on_sending->outqueue, sctp_streamhead);
1276				if (sp == NULL) {
1277					printf("Error, sp is NULL, locked on sending is non-null strm:%d\n",
1278					    asoc->locked_on_sending->stream_no);
1279				} else {
1280					if ((sp->length == 0) && (sp->msg_is_complete == 0)) {
1281						asoc->state |= SCTP_STATE_PARTIAL_MSG_LEFT;
1282					}
1283				}
1284			}
1285			if (TAILQ_EMPTY(&asoc->send_queue) &&
1286			    TAILQ_EMPTY(&asoc->sent_queue) &&
1287			    (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT)) {
1288				struct mbuf *op_err;
1289
1290		abort_anyway:
1291				op_err = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
1292				    0, M_DONTWAIT, 1, MT_DATA);
1293				if (op_err) {
1294					/* Fill in the user initiated abort */
1295					struct sctp_paramhdr *ph;
1296					uint32_t *ippp;
1297
1298					op_err->m_len =
1299					    sizeof(struct sctp_paramhdr) + sizeof(uint32_t);
1300					ph = mtod(op_err,
1301					    struct sctp_paramhdr *);
1302					ph->param_type = htons(
1303					    SCTP_CAUSE_USER_INITIATED_ABT);
1304					ph->param_length = htons(op_err->m_len);
1305					ippp = (uint32_t *) (ph + 1);
1306					*ippp = htonl(0x30000008);
1307				}
1308				sctp_abort_an_association(stcb->sctp_ep, stcb,
1309				    SCTP_RESPONSE_TO_USER_REQ,
1310				    op_err);
1311				goto skip_unlock;
1312			}
1313		}
1314		SCTP_TCB_UNLOCK(stcb);
1315	}
1316skip_unlock:
1317	SCTP_INP_RUNLOCK(inp);
1318	splx(s);
1319	return 0;
1320}
1321
1322/*
1323 * copies a "user" presentable address and removes embedded scope, etc.
1324 * returns 0 on success, 1 on error
1325 */
1326static uint32_t
1327sctp_fill_user_address(struct sockaddr_storage *ss, struct sockaddr *sa)
1328{
1329	struct sockaddr_in6 lsa6;
1330
1331	sa = (struct sockaddr *)sctp_recover_scope((struct sockaddr_in6 *)sa,
1332	    &lsa6);
1333	memcpy(ss, sa, sa->sa_len);
1334	return (0);
1335}
1336
1337
1338
1339static int
1340sctp_fill_up_addresses(struct sctp_inpcb *inp,
1341    struct sctp_tcb *stcb,
1342    int limit,
1343    struct sockaddr_storage *sas)
1344{
1345	struct ifnet *ifn;
1346	struct ifaddr *ifa;
1347	int loopback_scope, ipv4_local_scope, local_scope, site_scope, actual;
1348	int ipv4_addr_legal, ipv6_addr_legal;
1349
1350	actual = 0;
1351	if (limit <= 0)
1352		return (actual);
1353
1354	if (stcb) {
1355		/* Turn on all the appropriate scope */
1356		loopback_scope = stcb->asoc.loopback_scope;
1357		ipv4_local_scope = stcb->asoc.ipv4_local_scope;
1358		local_scope = stcb->asoc.local_scope;
1359		site_scope = stcb->asoc.site_scope;
1360	} else {
1361		/* Turn on ALL scope, since we look at the EP */
1362		loopback_scope = ipv4_local_scope = local_scope =
1363		    site_scope = 1;
1364	}
1365	ipv4_addr_legal = ipv6_addr_legal = 0;
1366	if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
1367		ipv6_addr_legal = 1;
1368		if (
1369		    (((struct in6pcb *)inp)->inp_flags & IN6P_IPV6_V6ONLY)
1370		    == 0) {
1371			ipv4_addr_legal = 1;
1372		}
1373	} else {
1374		ipv4_addr_legal = 1;
1375	}
1376
1377	if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
1378		TAILQ_FOREACH(ifn, &ifnet, if_list) {
1379			if ((loopback_scope == 0) &&
1380			    (ifn->if_type == IFT_LOOP)) {
1381				/* Skip loopback if loopback_scope not set */
1382				continue;
1383			}
1384			TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
1385				if (stcb) {
1386					/*
1387					 * For the BOUND-ALL case, the list
1388					 * associated with a TCB is Always
1389					 * considered a reverse list.. i.e.
1390					 * it lists addresses that are NOT
1391					 * part of the association. If this
1392					 * is one of those we must skip it.
1393					 */
1394					if (sctp_is_addr_restricted(stcb,
1395					    ifa->ifa_addr)) {
1396						continue;
1397					}
1398				}
1399				if ((ifa->ifa_addr->sa_family == AF_INET) &&
1400				    (ipv4_addr_legal)) {
1401					struct sockaddr_in *sin;
1402
1403					sin = (struct sockaddr_in *)ifa->ifa_addr;
1404					if (sin->sin_addr.s_addr == 0) {
1405						/*
1406						 * we skip unspecifed
1407						 * addresses
1408						 */
1409						continue;
1410					}
1411					if ((ipv4_local_scope == 0) &&
1412					    (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
1413						continue;
1414					}
1415					if (inp->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) {
1416						in6_sin_2_v4mapsin6(sin, (struct sockaddr_in6 *)sas);
1417						((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport;
1418						sas = (struct sockaddr_storage *)((caddr_t)sas + sizeof(struct sockaddr_in6));
1419						actual += sizeof(sizeof(struct sockaddr_in6));
1420					} else {
1421						memcpy(sas, sin, sizeof(*sin));
1422						((struct sockaddr_in *)sas)->sin_port = inp->sctp_lport;
1423						sas = (struct sockaddr_storage *)((caddr_t)sas + sizeof(*sin));
1424						actual += sizeof(*sin);
1425					}
1426					if (actual >= limit) {
1427						return (actual);
1428					}
1429				} else if ((ifa->ifa_addr->sa_family == AF_INET6) &&
1430				    (ipv6_addr_legal)) {
1431					struct sockaddr_in6 *sin6;
1432
1433					sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
1434					if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
1435						/*
1436						 * we skip unspecifed
1437						 * addresses
1438						 */
1439						continue;
1440					}
1441					if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
1442						if (local_scope == 0)
1443							continue;
1444						if (sin6->sin6_scope_id == 0) {
1445							if (sa6_recoverscope(sin6) != 0)
1446								/*
1447								 * bad link
1448								 * local
1449								 * address
1450								 */
1451								continue;
1452						}
1453					}
1454					if ((site_scope == 0) &&
1455					    (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) {
1456						continue;
1457					}
1458					memcpy(sas, sin6, sizeof(*sin6));
1459					((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport;
1460					sas = (struct sockaddr_storage *)((caddr_t)sas + sizeof(*sin6));
1461					actual += sizeof(*sin6);
1462					if (actual >= limit) {
1463						return (actual);
1464					}
1465				}
1466			}
1467		}
1468	} else {
1469		struct sctp_laddr *laddr;
1470
1471		/*
1472		 * If we have a TCB and we do NOT support ASCONF (it's
1473		 * turned off or otherwise) then the list is always the true
1474		 * list of addresses (the else case below).  Otherwise the
1475		 * list on the association is a list of addresses that are
1476		 * NOT part of the association.
1477		 */
1478		if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_DO_ASCONF)) {
1479			/* The list is a NEGATIVE list */
1480			LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
1481				if (stcb) {
1482					if (sctp_is_addr_restricted(stcb, laddr->ifa->ifa_addr)) {
1483						continue;
1484					}
1485				}
1486				if (sctp_fill_user_address(sas, laddr->ifa->ifa_addr))
1487					continue;
1488
1489				((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport;
1490				sas = (struct sockaddr_storage *)((caddr_t)sas +
1491				    laddr->ifa->ifa_addr->sa_len);
1492				actual += laddr->ifa->ifa_addr->sa_len;
1493				if (actual >= limit) {
1494					return (actual);
1495				}
1496			}
1497		} else {
1498			/* The list is a positive list if present */
1499			if (stcb) {
1500				/* Must use the specific association list */
1501				LIST_FOREACH(laddr, &stcb->asoc.sctp_local_addr_list,
1502				    sctp_nxt_addr) {
1503					if (sctp_fill_user_address(sas,
1504					    laddr->ifa->ifa_addr))
1505						continue;
1506					((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport;
1507					sas = (struct sockaddr_storage *)((caddr_t)sas +
1508					    laddr->ifa->ifa_addr->sa_len);
1509					actual += laddr->ifa->ifa_addr->sa_len;
1510					if (actual >= limit) {
1511						return (actual);
1512					}
1513				}
1514			} else {
1515				/*
1516				 * No endpoint so use the endpoints
1517				 * individual list
1518				 */
1519				LIST_FOREACH(laddr, &inp->sctp_addr_list,
1520				    sctp_nxt_addr) {
1521					if (sctp_fill_user_address(sas,
1522					    laddr->ifa->ifa_addr))
1523						continue;
1524					((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport;
1525					sas = (struct sockaddr_storage *)((caddr_t)sas +
1526					    laddr->ifa->ifa_addr->sa_len);
1527					actual += laddr->ifa->ifa_addr->sa_len;
1528					if (actual >= limit) {
1529						return (actual);
1530					}
1531				}
1532			}
1533		}
1534	}
1535	return (actual);
1536}
1537
1538static int
1539sctp_count_max_addresses(struct sctp_inpcb *inp)
1540{
1541	int cnt = 0;
1542
1543	/*
1544	 * In both sub-set bound an bound_all cases we return the MAXIMUM
1545	 * number of addresses that you COULD get. In reality the sub-set
1546	 * bound may have an exclusion list for a given TCB OR in the
1547	 * bound-all case a TCB may NOT include the loopback or other
1548	 * addresses as well.
1549	 */
1550	if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
1551		struct ifnet *ifn;
1552		struct ifaddr *ifa;
1553
1554		TAILQ_FOREACH(ifn, &ifnet, if_list) {
1555			TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
1556				/* Count them if they are the right type */
1557				if (ifa->ifa_addr->sa_family == AF_INET) {
1558					if (inp->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)
1559						cnt += sizeof(struct sockaddr_in6);
1560					else
1561						cnt += sizeof(struct sockaddr_in);
1562
1563				} else if (ifa->ifa_addr->sa_family == AF_INET6)
1564					cnt += sizeof(struct sockaddr_in6);
1565			}
1566		}
1567	} else {
1568		struct sctp_laddr *laddr;
1569
1570		LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
1571			if (laddr->ifa->ifa_addr->sa_family == AF_INET) {
1572				if (inp->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)
1573					cnt += sizeof(struct sockaddr_in6);
1574				else
1575					cnt += sizeof(struct sockaddr_in);
1576
1577			} else if (laddr->ifa->ifa_addr->sa_family == AF_INET6)
1578				cnt += sizeof(struct sockaddr_in6);
1579		}
1580	}
1581	return (cnt);
1582}
1583
1584static int
1585sctp_do_connect_x(struct socket *so,
1586    struct sctp_inpcb *inp,
1587    struct mbuf *m,
1588    struct thread *p,
1589    int delay
1590)
1591{
1592	int s = splnet();
1593
1594	int error = 0;
1595	int creat_lock_on = 0;
1596	struct sctp_tcb *stcb = NULL;
1597	struct sockaddr *sa;
1598	int num_v6 = 0, num_v4 = 0, *totaddrp, totaddr, i, incr, at;
1599
1600#ifdef SCTP_DEBUG
1601	if (sctp_debug_on & SCTP_DEBUG_PCB1) {
1602		printf("Connectx called\n");
1603	}
1604#endif				/* SCTP_DEBUG */
1605
1606	if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
1607	    (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) {
1608		/* We are already connected AND the TCP model */
1609		splx(s);
1610		return (EADDRINUSE);
1611	}
1612	if (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) {
1613		splx(s);
1614		return (EINVAL);
1615	}
1616	if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
1617		SCTP_INP_RLOCK(inp);
1618		stcb = LIST_FIRST(&inp->sctp_asoc_list);
1619		SCTP_INP_RUNLOCK(inp);
1620	}
1621	if (stcb) {
1622		splx(s);
1623		return (EALREADY);
1624
1625	}
1626	SCTP_INP_INCR_REF(inp);
1627	SCTP_ASOC_CREATE_LOCK(inp);
1628	creat_lock_on = 1;
1629	if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
1630	    (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) {
1631		error = EFAULT;
1632		goto out_now;
1633	}
1634	totaddrp = mtod(m, int *);
1635	totaddr = *totaddrp;
1636	sa = (struct sockaddr *)(totaddrp + 1);
1637	at = incr = 0;
1638	/* account and validate addresses */
1639	for (i = 0; i < totaddr; i++) {
1640		if (sa->sa_family == AF_INET) {
1641			num_v4++;
1642			incr = sizeof(struct sockaddr_in);
1643		} else if (sa->sa_family == AF_INET6) {
1644			struct sockaddr_in6 *sin6;
1645
1646			sin6 = (struct sockaddr_in6 *)sa;
1647			if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
1648				/* Must be non-mapped for connectx */
1649				error = EINVAL;
1650				goto out_now;
1651			}
1652			num_v6++;
1653			incr = sizeof(struct sockaddr_in6);
1654		} else {
1655			totaddr = i;
1656			break;
1657		}
1658		stcb = sctp_findassociation_ep_addr(&inp, sa, NULL, NULL, NULL);
1659		if (stcb != NULL) {
1660			/* Already have or am bring up an association */
1661			SCTP_ASOC_CREATE_UNLOCK(inp);
1662			creat_lock_on = 0;
1663			SCTP_TCB_UNLOCK(stcb);
1664			error = EALREADY;
1665			goto out_now;
1666		}
1667		if ((at + incr) > m->m_len) {
1668			totaddr = i;
1669			break;
1670		}
1671		sa = (struct sockaddr *)((caddr_t)sa + incr);
1672	}
1673	sa = (struct sockaddr *)(totaddrp + 1);
1674#ifdef INET6
1675	if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) &&
1676	    (num_v6 > 0)) {
1677		splx(s);
1678		error = EINVAL;
1679		goto out_now;
1680	}
1681	if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
1682	    (num_v4 > 0)) {
1683		struct in6pcb *inp6;
1684
1685		inp6 = (struct in6pcb *)inp;
1686		if (
1687		    (inp6->inp_flags & IN6P_IPV6_V6ONLY)
1688		    ) {
1689			/*
1690			 * if IPV6_V6ONLY flag, ignore connections destined
1691			 * to a v4 addr or v4-mapped addr
1692			 */
1693			error = EINVAL;
1694			goto out_now;
1695		}
1696	}
1697#endif				/* INET6 */
1698	if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) ==
1699	    SCTP_PCB_FLAGS_UNBOUND) {
1700		/* Bind a ephemeral port */
1701		SCTP_INP_WUNLOCK(inp);
1702		error = sctp_inpcb_bind(so, NULL, p);
1703		if (error) {
1704			goto out_now;
1705		}
1706	} else {
1707		SCTP_INP_WUNLOCK(inp);
1708	}
1709
1710	/* We are GOOD to go */
1711	stcb = sctp_aloc_assoc(inp, sa, 1, &error, 0);
1712	if (stcb == NULL) {
1713		/* Gak! no memory */
1714		error = ENOMEM;
1715		goto out_now;
1716	}
1717	/* move to second address */
1718	if (sa->sa_family == AF_INET)
1719		sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in));
1720	else
1721		sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in6));
1722
1723	for (i = 1; i < totaddr; i++) {
1724		if (sa->sa_family == AF_INET) {
1725			incr = sizeof(struct sockaddr_in);
1726			if (sctp_add_remote_addr(stcb, sa, 0, 8)) {
1727				/* assoc gone no un-lock */
1728				sctp_free_assoc(inp, stcb, 0);
1729				error = ENOBUFS;
1730				goto out_now;
1731			}
1732		} else if (sa->sa_family == AF_INET6) {
1733			incr = sizeof(struct sockaddr_in6);
1734			if (sctp_add_remote_addr(stcb, sa, 0, 8)) {
1735				/* assoc gone no un-lock */
1736				sctp_free_assoc(inp, stcb, 0);
1737				error = ENOBUFS;
1738				goto out_now;
1739			}
1740		}
1741		sa = (struct sockaddr *)((caddr_t)sa + incr);
1742	}
1743	stcb->asoc.state = SCTP_STATE_COOKIE_WAIT;
1744
1745	/* initialize authentication parameters for the assoc */
1746	sctp_initialize_auth_params(inp, stcb);
1747
1748	if (delay) {
1749		/* doing delayed connection */
1750		stcb->asoc.delayed_connection = 1;
1751		sctp_timer_start(SCTP_TIMER_TYPE_INIT, inp, stcb, stcb->asoc.primary_destination);
1752	} else {
1753		SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered);
1754		sctp_send_initiate(inp, stcb);
1755	}
1756	SCTP_TCB_UNLOCK(stcb);
1757	if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) {
1758		stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED;
1759		/* Set the connected flag so we can queue data */
1760		soisconnecting(so);
1761	}
1762out_now:
1763	if (creat_lock_on)
1764		SCTP_ASOC_CREATE_UNLOCK(inp);
1765	SCTP_INP_DECR_REF(inp);
1766	splx(s);
1767	return error;
1768}
1769
1770
1771
1772static int
1773sctp_optsget(struct socket *so,
1774    int opt,
1775    struct mbuf **mp,
1776    struct thread *p
1777)
1778{
1779	struct sctp_inpcb *inp;
1780	struct mbuf *m;
1781	int error, optval = 0;
1782	struct sctp_tcb *stcb = NULL;
1783
1784	inp = (struct sctp_inpcb *)so->so_pcb;
1785	if (inp == 0)
1786		return EINVAL;
1787	error = 0;
1788
1789	if (mp == NULL) {
1790		return (EINVAL);
1791	}
1792	m = *mp;
1793	if (m == NULL) {
1794		/* Got to have a mbuf */
1795		return (EINVAL);
1796	}
1797	switch (opt) {
1798	case SCTP_NODELAY:
1799	case SCTP_AUTOCLOSE:
1800	case SCTP_EXPLICIT_EOR:
1801	case SCTP_AUTO_ASCONF:
1802	case SCTP_DISABLE_FRAGMENTS:
1803	case SCTP_I_WANT_MAPPED_V4_ADDR:
1804	case SCTP_USE_EXT_RCVINFO:
1805		SCTP_INP_RLOCK(inp);
1806		switch (opt) {
1807		case SCTP_DISABLE_FRAGMENTS:
1808			optval = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NO_FRAGMENT);
1809			break;
1810		case SCTP_I_WANT_MAPPED_V4_ADDR:
1811			optval = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4);
1812			break;
1813		case SCTP_AUTO_ASCONF:
1814			optval = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTO_ASCONF);
1815			break;
1816		case SCTP_EXPLICIT_EOR:
1817			optval = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXPLICIT_EOR);
1818			break;
1819		case SCTP_NODELAY:
1820			optval = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NODELAY);
1821			break;
1822		case SCTP_USE_EXT_RCVINFO:
1823			optval = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXT_RCVINFO);
1824			break;
1825		case SCTP_AUTOCLOSE:
1826			if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTOCLOSE))
1827				optval = TICKS_TO_SEC(inp->sctp_ep.auto_close_time);
1828			else
1829				optval = 0;
1830			break;
1831
1832		default:
1833			error = ENOPROTOOPT;
1834		}		/* end switch (sopt->sopt_name) */
1835		if (opt != SCTP_AUTOCLOSE) {
1836			/* make it an "on/off" value */
1837			optval = (optval != 0);
1838		}
1839		if ((size_t)m->m_len < sizeof(int)) {
1840			error = EINVAL;
1841		}
1842		SCTP_INP_RUNLOCK(inp);
1843		if (error == 0) {
1844			/* return the option value */
1845			*mtod(m, int *)= optval;
1846			m->m_len = sizeof(optval);
1847		}
1848		break;
1849	case SCTP_PARTIAL_DELIVERY_POINT:
1850		{
1851			if ((size_t)m->m_len < sizeof(unsigned int)) {
1852				error = EINVAL;
1853				break;
1854			}
1855			*mtod(m, unsigned int *)= inp->partial_delivery_point;
1856			m->m_len = sizeof(unsigned int);
1857		}
1858		break;
1859	case SCTP_FRAGMENT_INTERLEAVE:
1860		{
1861			if ((size_t)m->m_len < sizeof(unsigned int)) {
1862				error = EINVAL;
1863				break;
1864			}
1865			*mtod(m, unsigned int *)= sctp_is_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE);
1866			m->m_len = sizeof(unsigned int);
1867		}
1868		break;
1869	case SCTP_CMT_ON_OFF:
1870		{
1871			if ((size_t)m->m_len < sizeof(unsigned int)) {
1872				error = EINVAL;
1873				break;
1874			}
1875			*mtod(m, unsigned int *)= sctp_cmt_sockopt_on_off;
1876			m->m_len = sizeof(unsigned int);
1877		}
1878		break;
1879	case SCTP_CMT_USE_DAC:
1880		{
1881			*mtod(m, unsigned int *)= sctp_cmt_sockopt_use_dac;
1882			m->m_len = sizeof(unsigned int);
1883		}
1884		break;
1885	case SCTP_GET_ADDR_LEN:
1886		{
1887			struct sctp_assoc_value *av;
1888
1889			if ((size_t)m->m_len < sizeof(struct sctp_assoc_value)) {
1890				error = EINVAL;
1891				break;
1892			}
1893			av = mtod(m, struct sctp_assoc_value *);
1894			error = EINVAL;
1895#ifdef AF_INET
1896			if (av->assoc_value == AF_INET) {
1897				av->assoc_value = sizeof(struct sockaddr_in);
1898				error = 0;
1899			}
1900#endif
1901#ifdef AF_INET6
1902			if (av->assoc_value == AF_INET6) {
1903				av->assoc_value = sizeof(struct sockaddr_in6);
1904				error = 0;
1905			}
1906#endif
1907		}
1908		break;
1909	case SCTP_GET_ASOC_ID_LIST:
1910		{
1911			struct sctp_assoc_ids *ids;
1912			int cnt, at;
1913			uint16_t orig;
1914
1915			if ((size_t)m->m_len < sizeof(struct sctp_assoc_ids)) {
1916				error = EINVAL;
1917				break;
1918			}
1919			ids = mtod(m, struct sctp_assoc_ids *);
1920			cnt = 0;
1921			SCTP_INP_RLOCK(inp);
1922			stcb = LIST_FIRST(&inp->sctp_asoc_list);
1923			if (stcb == NULL) {
1924		none_out_now:
1925				ids->asls_numb_present = 0;
1926				ids->asls_more_to_get = 0;
1927				SCTP_INP_RUNLOCK(inp);
1928				break;
1929			}
1930			orig = ids->asls_assoc_start;
1931			stcb = LIST_FIRST(&inp->sctp_asoc_list);
1932			while (orig) {
1933				stcb = LIST_NEXT(stcb, sctp_tcblist);
1934				orig--;
1935				cnt--;
1936				if (stcb == NULL)
1937					goto none_out_now;
1938			}
1939			if (stcb == NULL)
1940				goto none_out_now;
1941
1942			at = 0;
1943			ids->asls_numb_present = 0;
1944			ids->asls_more_to_get = 1;
1945			while (at < MAX_ASOC_IDS_RET) {
1946				ids->asls_assoc_id[at] = sctp_get_associd(stcb);
1947				at++;
1948				ids->asls_numb_present++;
1949				stcb = LIST_NEXT(stcb, sctp_tcblist);
1950				if (stcb == NULL) {
1951					ids->asls_more_to_get = 0;
1952					break;
1953				}
1954			}
1955			SCTP_INP_RUNLOCK(inp);
1956		}
1957		break;
1958	case SCTP_CONTEXT:
1959		{
1960
1961			struct sctp_assoc_value *av;
1962
1963			if ((size_t)m->m_len < sizeof(struct sctp_assoc_value)) {
1964				error = EINVAL;
1965				break;
1966			}
1967			av = mtod(m, struct sctp_assoc_value *);
1968			if (av->assoc_id) {
1969				stcb = sctp_findassociation_ep_asocid(inp, av->assoc_id, 1);
1970				if (stcb == NULL) {
1971					error = ENOTCONN;
1972				} else {
1973					av->assoc_value = stcb->asoc.context;
1974					SCTP_TCB_UNLOCK(stcb);
1975				}
1976			} else {
1977				av->assoc_value = inp->sctp_context;
1978			}
1979		}
1980		break;
1981	case SCTP_GET_NONCE_VALUES:
1982		{
1983			struct sctp_get_nonce_values *gnv;
1984
1985			if ((size_t)m->m_len < sizeof(struct sctp_get_nonce_values)) {
1986				error = EINVAL;
1987				break;
1988			}
1989			gnv = mtod(m, struct sctp_get_nonce_values *);
1990			stcb = sctp_findassociation_ep_asocid(inp, gnv->gn_assoc_id, 1);
1991			if (stcb == NULL) {
1992				error = ENOTCONN;
1993			} else {
1994				gnv->gn_peers_tag = stcb->asoc.peer_vtag;
1995				gnv->gn_local_tag = stcb->asoc.my_vtag;
1996				SCTP_TCB_UNLOCK(stcb);
1997			}
1998
1999		}
2000		break;
2001	case SCTP_DELAYED_ACK_TIME:
2002		{
2003			struct sctp_assoc_value *tm;
2004
2005			if ((size_t)m->m_len < sizeof(struct sctp_assoc_value)) {
2006				error = EINVAL;
2007				break;
2008			}
2009			tm = mtod(m, struct sctp_assoc_value *);
2010
2011			if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2012				SCTP_INP_RLOCK(inp);
2013				stcb = LIST_FIRST(&inp->sctp_asoc_list);
2014				if (stcb) {
2015					SCTP_TCB_LOCK(stcb);
2016					tm->assoc_value = stcb->asoc.delayed_ack;
2017					SCTP_TCB_UNLOCK(stcb);
2018				} else {
2019					tm->assoc_value = TICKS_TO_MSEC(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV]);
2020				}
2021				SCTP_INP_RUNLOCK(inp);
2022			} else {
2023				stcb = sctp_findassociation_ep_asocid(inp, tm->assoc_id, 1);
2024				if (stcb == NULL) {
2025					error = ENOTCONN;
2026					tm->assoc_value = 0;
2027				} else {
2028					stcb->asoc.delayed_ack = tm->assoc_value;
2029					SCTP_TCB_UNLOCK(stcb);
2030				}
2031			}
2032		}
2033		break;
2034
2035	case SCTP_GET_SNDBUF_USE:
2036		if ((size_t)m->m_len < sizeof(struct sctp_sockstat)) {
2037			error = EINVAL;
2038		} else {
2039			struct sctp_sockstat *ss;
2040			struct sctp_tcb *stcb;
2041			struct sctp_association *asoc;
2042
2043			ss = mtod(m, struct sctp_sockstat *);
2044			stcb = sctp_findassociation_ep_asocid(inp, ss->ss_assoc_id, 1);
2045			if (stcb == NULL) {
2046				error = ENOTCONN;
2047			} else {
2048				asoc = &stcb->asoc;
2049				ss->ss_total_sndbuf = (uint32_t) asoc->total_output_queue_size;
2050				ss->ss_total_recv_buf = (uint32_t) (asoc->size_on_reasm_queue +
2051				    asoc->size_on_all_streams);
2052				SCTP_TCB_UNLOCK(stcb);
2053				error = 0;
2054				m->m_len = sizeof(struct sctp_sockstat);
2055			}
2056		}
2057		break;
2058	case SCTP_MAXBURST:
2059		{
2060			uint8_t *burst;
2061
2062			burst = mtod(m, uint8_t *);
2063			SCTP_INP_RLOCK(inp);
2064			*burst = inp->sctp_ep.max_burst;
2065			SCTP_INP_RUNLOCK(inp);
2066			m->m_len = sizeof(uint8_t);
2067		}
2068		break;
2069
2070	case SCTP_MAXSEG:
2071		{
2072			uint32_t *segsize;
2073			sctp_assoc_t *assoc_id;
2074			int ovh;
2075
2076			if ((size_t)m->m_len < sizeof(uint32_t)) {
2077				error = EINVAL;
2078				break;
2079			}
2080			if ((size_t)m->m_len < sizeof(sctp_assoc_t)) {
2081				error = EINVAL;
2082				break;
2083			}
2084			assoc_id = mtod(m, sctp_assoc_t *);
2085			segsize = mtod(m, uint32_t *);
2086			m->m_len = sizeof(uint32_t);
2087
2088			if (((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
2089			    (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) ||
2090			    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
2091				struct sctp_tcb *stcb;
2092
2093				SCTP_INP_RLOCK(inp);
2094				stcb = LIST_FIRST(&inp->sctp_asoc_list);
2095				if (stcb) {
2096					SCTP_TCB_LOCK(stcb);
2097					SCTP_INP_RUNLOCK(inp);
2098					*segsize = sctp_get_frag_point(stcb, &stcb->asoc);
2099					SCTP_TCB_UNLOCK(stcb);
2100				} else {
2101					SCTP_INP_RUNLOCK(inp);
2102					goto skipit;
2103				}
2104			} else {
2105				stcb = sctp_findassociation_ep_asocid(inp, *assoc_id, 1);
2106				if (stcb) {
2107					*segsize = sctp_get_frag_point(stcb, &stcb->asoc);
2108					SCTP_TCB_UNLOCK(stcb);
2109					break;
2110				}
2111		skipit:
2112				/*
2113				 * default is to get the max, if I can't
2114				 * calculate from an existing association.
2115				 */
2116				if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
2117					ovh = SCTP_MED_OVERHEAD;
2118				} else {
2119					ovh = SCTP_MED_V4_OVERHEAD;
2120				}
2121				*segsize = inp->sctp_frag_point - ovh;
2122			}
2123		}
2124		break;
2125
2126	case SCTP_SET_DEBUG_LEVEL:
2127#ifdef SCTP_DEBUG
2128		{
2129			uint32_t *level;
2130
2131			if ((size_t)m->m_len < sizeof(uint32_t)) {
2132				error = EINVAL;
2133				break;
2134			}
2135			level = mtod(m, uint32_t *);
2136			error = 0;
2137			*level = sctp_debug_on;
2138			m->m_len = sizeof(uint32_t);
2139			printf("Returning DEBUG LEVEL %x is set\n",
2140			    (uint32_t) sctp_debug_on);
2141		}
2142#else				/* SCTP_DEBUG */
2143		error = EOPNOTSUPP;
2144#endif
2145		break;
2146	case SCTP_GET_STAT_LOG:
2147#ifdef SCTP_STAT_LOGGING
2148		error = sctp_fill_stat_log(m);
2149#else				/* SCTP_DEBUG */
2150		error = EOPNOTSUPP;
2151#endif
2152		break;
2153	case SCTP_EVENTS:
2154		{
2155			struct sctp_event_subscribe *events;
2156
2157			if ((size_t)m->m_len < sizeof(struct sctp_event_subscribe)) {
2158				error = EINVAL;
2159				break;
2160			}
2161			events = mtod(m, struct sctp_event_subscribe *);
2162			memset(events, 0, sizeof(*events));
2163			SCTP_INP_RLOCK(inp);
2164			if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT))
2165				events->sctp_data_io_event = 1;
2166
2167			if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVASSOCEVNT))
2168				events->sctp_association_event = 1;
2169
2170			if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVPADDREVNT))
2171				events->sctp_address_event = 1;
2172
2173			if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVSENDFAILEVNT))
2174				events->sctp_send_failure_event = 1;
2175
2176			if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVPEERERR))
2177				events->sctp_peer_error_event = 1;
2178
2179			if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT))
2180				events->sctp_shutdown_event = 1;
2181
2182			if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PDAPIEVNT))
2183				events->sctp_partial_delivery_event = 1;
2184
2185			if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_ADAPTATIONEVNT))
2186				events->sctp_adaptation_layer_event = 1;
2187
2188			if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTHEVNT))
2189				events->sctp_authentication_event = 1;
2190
2191			if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_STREAM_RESETEVNT))
2192				events->sctp_stream_reset_events = 1;
2193			SCTP_INP_RUNLOCK(inp);
2194			m->m_len = sizeof(struct sctp_event_subscribe);
2195
2196		}
2197		break;
2198
2199	case SCTP_ADAPTATION_LAYER:
2200		if ((size_t)m->m_len < sizeof(int)) {
2201			error = EINVAL;
2202			break;
2203		}
2204		SCTP_INP_RLOCK(inp);
2205		*mtod(m, int *)= inp->sctp_ep.adaptation_layer_indicator;
2206		SCTP_INP_RUNLOCK(inp);
2207		m->m_len = sizeof(int);
2208		break;
2209	case SCTP_SET_INITIAL_DBG_SEQ:
2210		if ((size_t)m->m_len < sizeof(int)) {
2211			error = EINVAL;
2212			break;
2213		}
2214		SCTP_INP_RLOCK(inp);
2215		*mtod(m, int *)= inp->sctp_ep.initial_sequence_debug;
2216		SCTP_INP_RUNLOCK(inp);
2217		m->m_len = sizeof(int);
2218		break;
2219	case SCTP_GET_LOCAL_ADDR_SIZE:
2220		if ((size_t)m->m_len < sizeof(int)) {
2221			error = EINVAL;
2222			break;
2223		}
2224		SCTP_INP_RLOCK(inp);
2225		*mtod(m, int *)= sctp_count_max_addresses(inp);
2226		SCTP_INP_RUNLOCK(inp);
2227		m->m_len = sizeof(int);
2228		break;
2229	case SCTP_GET_REMOTE_ADDR_SIZE:
2230		{
2231			sctp_assoc_t *assoc_id;
2232			uint32_t *val, sz;
2233			struct sctp_nets *net;
2234
2235			if ((size_t)m->m_len < sizeof(sctp_assoc_t)) {
2236				error = EINVAL;
2237				break;
2238			}
2239			stcb = NULL;
2240			val = mtod(m, uint32_t *);
2241			if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2242				SCTP_INP_RLOCK(inp);
2243				stcb = LIST_FIRST(&inp->sctp_asoc_list);
2244				if (stcb)
2245					SCTP_TCB_LOCK(stcb);
2246				SCTP_INP_RUNLOCK(inp);
2247			}
2248			if (stcb == NULL) {
2249				assoc_id = mtod(m, sctp_assoc_t *);
2250				stcb = sctp_findassociation_ep_asocid(inp, *assoc_id, 1);
2251			}
2252			if (stcb == NULL) {
2253				error = EINVAL;
2254				break;
2255			}
2256			*val = 0;
2257			sz = 0;
2258			/* Count the sizes */
2259			TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
2260				if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) ||
2261				    (((struct sockaddr *)&net->ro._l_addr)->sa_family == AF_INET6)) {
2262					sz += sizeof(struct sockaddr_in6);
2263				} else if (((struct sockaddr *)&net->ro._l_addr)->sa_family == AF_INET) {
2264					sz += sizeof(struct sockaddr_in);
2265				} else {
2266					/* huh */
2267					break;
2268				}
2269			}
2270			SCTP_TCB_UNLOCK(stcb);
2271			*val = sz;
2272			m->m_len = sizeof(uint32_t);
2273		}
2274		break;
2275	case SCTP_GET_PEER_ADDRESSES:
2276		/*
2277		 * Get the address information, an array is passed in to
2278		 * fill up we pack it.
2279		 */
2280		{
2281			int cpsz, left;
2282			struct sockaddr_storage *sas;
2283			struct sctp_nets *net;
2284			struct sctp_getaddresses *saddr;
2285
2286			if ((size_t)m->m_len < sizeof(struct sctp_getaddresses)) {
2287				error = EINVAL;
2288				break;
2289			}
2290			left = m->m_len - sizeof(struct sctp_getaddresses);
2291			saddr = mtod(m, struct sctp_getaddresses *);
2292			if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2293				SCTP_INP_RLOCK(inp);
2294				stcb = LIST_FIRST(&inp->sctp_asoc_list);
2295				if (stcb)
2296					SCTP_TCB_LOCK(stcb);
2297				SCTP_INP_RUNLOCK(inp);
2298			} else
2299				stcb = sctp_findassociation_ep_asocid(inp,
2300				    saddr->sget_assoc_id, 1);
2301			if (stcb == NULL) {
2302				error = ENOENT;
2303				break;
2304			}
2305			m->m_len = sizeof(struct sctp_getaddresses);
2306			sas = (struct sockaddr_storage *)&saddr->addr[0];
2307
2308			TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
2309				if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) ||
2310				    (((struct sockaddr *)&net->ro._l_addr)->sa_family == AF_INET6)) {
2311					cpsz = sizeof(struct sockaddr_in6);
2312				} else if (((struct sockaddr *)&net->ro._l_addr)->sa_family == AF_INET) {
2313					cpsz = sizeof(struct sockaddr_in);
2314				} else {
2315					/* huh */
2316					break;
2317				}
2318				if (left < cpsz) {
2319					/* not enough room. */
2320					break;
2321				}
2322				if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
2323				    (((struct sockaddr *)&net->ro._l_addr)->sa_family == AF_INET)) {
2324					/* Must map the address */
2325					in6_sin_2_v4mapsin6((struct sockaddr_in *)&net->ro._l_addr,
2326					    (struct sockaddr_in6 *)sas);
2327				} else {
2328					memcpy(sas, &net->ro._l_addr, cpsz);
2329				}
2330				((struct sockaddr_in *)sas)->sin_port = stcb->rport;
2331
2332				sas = (struct sockaddr_storage *)((caddr_t)sas + cpsz);
2333				left -= cpsz;
2334				m->m_len += cpsz;
2335			}
2336			SCTP_TCB_UNLOCK(stcb);
2337		}
2338		break;
2339	case SCTP_GET_LOCAL_ADDRESSES:
2340		{
2341			int limit, actual;
2342			struct sockaddr_storage *sas;
2343			struct sctp_getaddresses *saddr;
2344
2345			if ((size_t)m->m_len < sizeof(struct sctp_getaddresses)) {
2346				error = EINVAL;
2347				break;
2348			}
2349			saddr = mtod(m, struct sctp_getaddresses *);
2350
2351			if (saddr->sget_assoc_id) {
2352				if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2353					SCTP_INP_RLOCK(inp);
2354					stcb = LIST_FIRST(&inp->sctp_asoc_list);
2355					if (stcb)
2356						SCTP_TCB_LOCK(stcb);
2357					SCTP_INP_RUNLOCK(inp);
2358				} else
2359					stcb = sctp_findassociation_ep_asocid(inp, saddr->sget_assoc_id, 1);
2360
2361			} else {
2362				stcb = NULL;
2363			}
2364			/*
2365			 * assure that the TCP model does not need a assoc
2366			 * id once connected.
2367			 */
2368			if ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) &&
2369			    (stcb == NULL)) {
2370				SCTP_INP_RLOCK(inp);
2371				stcb = LIST_FIRST(&inp->sctp_asoc_list);
2372				if (stcb)
2373					SCTP_TCB_LOCK(stcb);
2374				SCTP_INP_RUNLOCK(inp);
2375			}
2376			sas = (struct sockaddr_storage *)&saddr->addr[0];
2377			limit = m->m_len - sizeof(sctp_assoc_t);
2378			actual = sctp_fill_up_addresses(inp, stcb, limit, sas);
2379			if (stcb)
2380				SCTP_TCB_UNLOCK(stcb);
2381			m->m_len = sizeof(struct sockaddr_storage) + actual;
2382		}
2383		break;
2384	case SCTP_PEER_ADDR_PARAMS:
2385		{
2386			struct sctp_paddrparams *paddrp;
2387			struct sctp_nets *net;
2388
2389			if ((size_t)m->m_len < sizeof(struct sctp_paddrparams)) {
2390				error = EINVAL;
2391				break;
2392			}
2393			paddrp = mtod(m, struct sctp_paddrparams *);
2394
2395			net = NULL;
2396			if (paddrp->spp_assoc_id) {
2397				if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2398					SCTP_INP_RLOCK(inp);
2399					stcb = LIST_FIRST(&inp->sctp_asoc_list);
2400					if (stcb) {
2401						SCTP_TCB_LOCK(stcb);
2402						net = sctp_findnet(stcb, (struct sockaddr *)&paddrp->spp_address);
2403					}
2404					SCTP_INP_RLOCK(inp);
2405				} else {
2406					stcb = sctp_findassociation_ep_asocid(inp, paddrp->spp_assoc_id, 1);
2407				}
2408				if (stcb == NULL) {
2409					error = ENOENT;
2410					break;
2411				}
2412			}
2413			if ((stcb == NULL) &&
2414			    ((((struct sockaddr *)&paddrp->spp_address)->sa_family == AF_INET) ||
2415			    (((struct sockaddr *)&paddrp->spp_address)->sa_family == AF_INET6))) {
2416				/* Lookup via address */
2417				if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2418					SCTP_INP_RLOCK(inp);
2419					stcb = LIST_FIRST(&inp->sctp_asoc_list);
2420					if (stcb) {
2421						SCTP_TCB_LOCK(stcb);
2422						net = sctp_findnet(stcb, (struct sockaddr *)&paddrp->spp_address);
2423					}
2424					SCTP_INP_RUNLOCK(inp);
2425				} else {
2426					SCTP_INP_INCR_REF(inp);
2427					stcb = sctp_findassociation_ep_addr(&inp,
2428					    (struct sockaddr *)&paddrp->spp_address,
2429					    &net, NULL, NULL);
2430					if (stcb == NULL) {
2431						SCTP_INP_DECR_REF(inp);
2432					}
2433				}
2434
2435				if (stcb == NULL) {
2436					error = ENOENT;
2437					break;
2438				}
2439			}
2440			if (stcb) {
2441				/* Applys to the specific association */
2442				paddrp->spp_flags = 0;
2443				if (net) {
2444					paddrp->spp_pathmaxrxt = net->failure_threshold;
2445					paddrp->spp_pathmtu = net->mtu;
2446					/* get flags for HB */
2447					if (net->dest_state & SCTP_ADDR_NOHB)
2448						paddrp->spp_flags |= SPP_HB_DISABLE;
2449					else
2450						paddrp->spp_flags |= SPP_HB_ENABLE;
2451					/* get flags for PMTU */
2452					if (callout_pending(&net->pmtu_timer.timer)) {
2453						paddrp->spp_flags |= SPP_PMTUD_ENABLE;
2454					} else {
2455						paddrp->spp_flags |= SPP_PMTUD_DISABLE;
2456					}
2457#ifdef AF_INET
2458					if (net->ro._l_addr.sin.sin_family == AF_INET) {
2459						paddrp->spp_ipv4_tos = net->tos_flowlabel & 0x000000fc;
2460						paddrp->spp_flags |= SPP_IPV4_TOS;
2461					}
2462#endif
2463#ifdef AF_INET6
2464					if (net->ro._l_addr.sin6.sin6_family == AF_INET6) {
2465						paddrp->spp_ipv6_flowlabel = net->tos_flowlabel;
2466						paddrp->spp_flags |= SPP_IPV6_FLOWLABEL;
2467					}
2468#endif
2469				} else {
2470					/*
2471					 * No destination so return default
2472					 * value
2473					 */
2474					paddrp->spp_pathmaxrxt = stcb->asoc.def_net_failure;
2475					paddrp->spp_pathmtu = sctp_get_frag_point(stcb, &stcb->asoc);
2476#ifdef AF_INET
2477					paddrp->spp_ipv4_tos = stcb->asoc.default_tos & 0x000000fc;
2478					paddrp->spp_flags |= SPP_IPV4_TOS;
2479#endif
2480#ifdef AF_INET6
2481					paddrp->spp_ipv6_flowlabel = stcb->asoc.default_flowlabel;
2482					paddrp->spp_flags |= SPP_IPV6_FLOWLABEL;
2483#endif
2484					/* default settings should be these */
2485					if (sctp_is_hb_timer_running(stcb)) {
2486						paddrp->spp_flags |= SPP_HB_ENABLE;
2487					}
2488				}
2489				paddrp->spp_hbinterval = stcb->asoc.heart_beat_delay;
2490				paddrp->spp_sackdelay = stcb->asoc.delayed_ack;
2491				/*
2492				 * Currently we don't support no sack delay
2493				 * aka SPP_SACKDELAY_DISABLE.
2494				 */
2495				paddrp->spp_flags |= SPP_SACKDELAY_ENABLE;
2496				paddrp->spp_assoc_id = sctp_get_associd(stcb);
2497				SCTP_TCB_UNLOCK(stcb);
2498			} else {
2499				/* Use endpoint defaults */
2500				SCTP_INP_RLOCK(inp);
2501				paddrp->spp_pathmaxrxt = inp->sctp_ep.def_net_failure;
2502				paddrp->spp_hbinterval = TICKS_TO_MSEC(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]);
2503				paddrp->spp_sackdelay = TICKS_TO_MSEC(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV]);
2504				paddrp->spp_assoc_id = (sctp_assoc_t) 0;
2505				/* get inp's default */
2506#ifdef AF_INET
2507				paddrp->spp_ipv4_tos = inp->ip_inp.inp.inp_ip_tos;
2508				paddrp->spp_flags |= SPP_IPV4_TOS;
2509#endif
2510#ifdef AF_INET6
2511				if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
2512					paddrp->spp_ipv6_flowlabel = ((struct in6pcb *)inp)->in6p_flowinfo;
2513					paddrp->spp_flags |= SPP_IPV6_FLOWLABEL;
2514				}
2515#endif
2516				/* can't return this */
2517				paddrp->spp_pathmaxrxt = 0;
2518				paddrp->spp_pathmtu = 0;
2519				/* default behavior, no stcb */
2520				paddrp->spp_flags = SPP_HB_ENABLE | SPP_SACKDELAY_ENABLE | SPP_PMTUD_ENABLE;
2521
2522				SCTP_INP_RUNLOCK(inp);
2523			}
2524			m->m_len = sizeof(struct sctp_paddrparams);
2525		}
2526		break;
2527	case SCTP_GET_PEER_ADDR_INFO:
2528		{
2529			struct sctp_paddrinfo *paddri;
2530			struct sctp_nets *net;
2531
2532			if ((size_t)m->m_len < sizeof(struct sctp_paddrinfo)) {
2533				error = EINVAL;
2534				break;
2535			}
2536			paddri = mtod(m, struct sctp_paddrinfo *);
2537			net = NULL;
2538			if ((((struct sockaddr *)&paddri->spinfo_address)->sa_family == AF_INET) ||
2539			    (((struct sockaddr *)&paddri->spinfo_address)->sa_family == AF_INET6)) {
2540				/* Lookup via address */
2541				if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2542					SCTP_INP_RLOCK(inp);
2543					stcb = LIST_FIRST(&inp->sctp_asoc_list);
2544					if (stcb) {
2545						SCTP_TCB_LOCK(stcb);
2546						net = sctp_findnet(stcb,
2547						    (struct sockaddr *)&paddri->spinfo_address);
2548					}
2549					SCTP_INP_RUNLOCK(inp);
2550				} else {
2551					SCTP_INP_INCR_REF(inp);
2552					stcb = sctp_findassociation_ep_addr(&inp,
2553					    (struct sockaddr *)&paddri->spinfo_address,
2554					    &net, NULL, NULL);
2555					if (stcb == NULL) {
2556						SCTP_INP_DECR_REF(inp);
2557					}
2558				}
2559
2560			} else {
2561				stcb = NULL;
2562			}
2563			if ((stcb == NULL) || (net == NULL)) {
2564				if (stcb) {
2565					SCTP_TCB_UNLOCK(stcb);
2566				}
2567				error = ENOENT;
2568				break;
2569			}
2570			m->m_len = sizeof(struct sctp_paddrinfo);
2571			paddri->spinfo_state = net->dest_state & (SCTP_REACHABLE_MASK | SCTP_ADDR_NOHB);
2572			paddri->spinfo_cwnd = net->cwnd;
2573			paddri->spinfo_srtt = ((net->lastsa >> 2) + net->lastsv) >> 1;
2574			paddri->spinfo_rto = net->RTO;
2575			paddri->spinfo_assoc_id = sctp_get_associd(stcb);
2576			SCTP_TCB_UNLOCK(stcb);
2577		}
2578		break;
2579	case SCTP_PCB_STATUS:
2580		{
2581			struct sctp_pcbinfo *spcb;
2582
2583			if ((size_t)m->m_len < sizeof(struct sctp_pcbinfo)) {
2584				error = EINVAL;
2585				break;
2586			}
2587			spcb = mtod(m, struct sctp_pcbinfo *);
2588			sctp_fill_pcbinfo(spcb);
2589			m->m_len = sizeof(struct sctp_pcbinfo);
2590		}
2591		break;
2592	case SCTP_STATUS:
2593		{
2594			struct sctp_nets *net;
2595			struct sctp_status *sstat;
2596
2597			if ((size_t)m->m_len < sizeof(struct sctp_status)) {
2598				error = EINVAL;
2599				break;
2600			}
2601			sstat = mtod(m, struct sctp_status *);
2602
2603			if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2604				SCTP_INP_RLOCK(inp);
2605				stcb = LIST_FIRST(&inp->sctp_asoc_list);
2606				if (stcb)
2607					SCTP_TCB_LOCK(stcb);
2608				SCTP_INP_RUNLOCK(inp);
2609			} else
2610				stcb = sctp_findassociation_ep_asocid(inp, sstat->sstat_assoc_id, 1);
2611
2612			if (stcb == NULL) {
2613				error = EINVAL;
2614				break;
2615			}
2616			/*
2617			 * I think passing the state is fine since
2618			 * sctp_constants.h will be available to the user
2619			 * land.
2620			 */
2621			sstat->sstat_state = stcb->asoc.state;
2622			sstat->sstat_rwnd = stcb->asoc.peers_rwnd;
2623			sstat->sstat_unackdata = stcb->asoc.sent_queue_cnt;
2624			/*
2625			 * We can't include chunks that have been passed to
2626			 * the socket layer. Only things in queue.
2627			 */
2628			sstat->sstat_penddata = (stcb->asoc.cnt_on_reasm_queue +
2629			    stcb->asoc.cnt_on_all_streams);
2630
2631
2632			sstat->sstat_instrms = stcb->asoc.streamincnt;
2633			sstat->sstat_outstrms = stcb->asoc.streamoutcnt;
2634			sstat->sstat_fragmentation_point = sctp_get_frag_point(stcb, &stcb->asoc);
2635			memcpy(&sstat->sstat_primary.spinfo_address,
2636			    &stcb->asoc.primary_destination->ro._l_addr,
2637			    ((struct sockaddr *)(&stcb->asoc.primary_destination->ro._l_addr))->sa_len);
2638			net = stcb->asoc.primary_destination;
2639			((struct sockaddr_in *)&sstat->sstat_primary.spinfo_address)->sin_port = stcb->rport;
2640			/*
2641			 * Again the user can get info from sctp_constants.h
2642			 * for what the state of the network is.
2643			 */
2644			sstat->sstat_primary.spinfo_state = net->dest_state & SCTP_REACHABLE_MASK;
2645			sstat->sstat_primary.spinfo_cwnd = net->cwnd;
2646			sstat->sstat_primary.spinfo_srtt = net->lastsa;
2647			sstat->sstat_primary.spinfo_rto = net->RTO;
2648			sstat->sstat_primary.spinfo_mtu = net->mtu;
2649			sstat->sstat_primary.spinfo_assoc_id = sctp_get_associd(stcb);
2650			SCTP_TCB_UNLOCK(stcb);
2651			m->m_len = sizeof(*sstat);
2652		}
2653		break;
2654	case SCTP_RTOINFO:
2655		{
2656			struct sctp_rtoinfo *srto;
2657
2658			if ((size_t)m->m_len < sizeof(struct sctp_rtoinfo)) {
2659				error = EINVAL;
2660				break;
2661			}
2662			srto = mtod(m, struct sctp_rtoinfo *);
2663			if (srto->srto_assoc_id == 0) {
2664				/* Endpoint only please */
2665				SCTP_INP_RLOCK(inp);
2666				srto->srto_initial = inp->sctp_ep.initial_rto;
2667				srto->srto_max = inp->sctp_ep.sctp_maxrto;
2668				srto->srto_min = inp->sctp_ep.sctp_minrto;
2669				SCTP_INP_RUNLOCK(inp);
2670				break;
2671			}
2672			if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2673				SCTP_INP_RLOCK(inp);
2674				stcb = LIST_FIRST(&inp->sctp_asoc_list);
2675				if (stcb)
2676					SCTP_TCB_LOCK(stcb);
2677				SCTP_INP_RUNLOCK(inp);
2678			} else
2679				stcb = sctp_findassociation_ep_asocid(inp, srto->srto_assoc_id, 1);
2680
2681			if (stcb == NULL) {
2682				error = EINVAL;
2683				break;
2684			}
2685			srto->srto_initial = stcb->asoc.initial_rto;
2686			srto->srto_max = stcb->asoc.maxrto;
2687			srto->srto_min = stcb->asoc.minrto;
2688			SCTP_TCB_UNLOCK(stcb);
2689			m->m_len = sizeof(*srto);
2690		}
2691		break;
2692	case SCTP_ASSOCINFO:
2693		{
2694			struct sctp_assocparams *sasoc;
2695
2696			if ((size_t)m->m_len < sizeof(struct sctp_assocparams)) {
2697				error = EINVAL;
2698				break;
2699			}
2700			sasoc = mtod(m, struct sctp_assocparams *);
2701			stcb = NULL;
2702
2703			if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2704				SCTP_INP_RLOCK(inp);
2705				stcb = LIST_FIRST(&inp->sctp_asoc_list);
2706				if (stcb) {
2707
2708					SCTP_TCB_LOCK(stcb);
2709				}
2710				SCTP_INP_RUNLOCK(inp);
2711			} else if (sasoc->sasoc_assoc_id) {
2712				stcb = sctp_findassociation_ep_asocid(inp,
2713				    sasoc->sasoc_assoc_id, 1);
2714				if (stcb == NULL) {
2715					error = ENOENT;
2716					break;
2717				}
2718			} else {
2719				stcb = NULL;
2720			}
2721			if (stcb) {
2722				sasoc->sasoc_asocmaxrxt = stcb->asoc.max_send_times;
2723				sasoc->sasoc_number_peer_destinations = stcb->asoc.numnets;
2724				sasoc->sasoc_peer_rwnd = stcb->asoc.peers_rwnd;
2725				sasoc->sasoc_local_rwnd = stcb->asoc.my_rwnd;
2726				sasoc->sasoc_cookie_life = stcb->asoc.cookie_life;
2727				SCTP_TCB_UNLOCK(stcb);
2728			} else {
2729				SCTP_INP_RLOCK(inp);
2730				sasoc->sasoc_asocmaxrxt = inp->sctp_ep.max_send_times;
2731				sasoc->sasoc_number_peer_destinations = 0;
2732				sasoc->sasoc_peer_rwnd = 0;
2733				sasoc->sasoc_local_rwnd = sbspace(&inp->sctp_socket->so_rcv);
2734				sasoc->sasoc_cookie_life = inp->sctp_ep.def_cookie_life;
2735				SCTP_INP_RUNLOCK(inp);
2736			}
2737			m->m_len = sizeof(*sasoc);
2738		}
2739		break;
2740	case SCTP_DEFAULT_SEND_PARAM:
2741		{
2742			struct sctp_sndrcvinfo *s_info;
2743
2744			if (m->m_len != sizeof(struct sctp_sndrcvinfo)) {
2745				error = EINVAL;
2746				break;
2747			}
2748			s_info = mtod(m, struct sctp_sndrcvinfo *);
2749			if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2750				SCTP_INP_RLOCK(inp);
2751				stcb = LIST_FIRST(&inp->sctp_asoc_list);
2752				if (stcb)
2753					SCTP_TCB_LOCK(stcb);
2754				SCTP_INP_RUNLOCK(inp);
2755			} else
2756				stcb = sctp_findassociation_ep_asocid(inp, s_info->sinfo_assoc_id, 1);
2757
2758			if (stcb == NULL) {
2759				error = ENOENT;
2760				break;
2761			}
2762			/* Copy it out */
2763			*s_info = stcb->asoc.def_send;
2764			SCTP_TCB_UNLOCK(stcb);
2765			m->m_len = sizeof(*s_info);
2766		}
2767		break;
2768	case SCTP_INITMSG:
2769		{
2770			struct sctp_initmsg *sinit;
2771
2772			if ((size_t)m->m_len < sizeof(struct sctp_initmsg)) {
2773				error = EINVAL;
2774				break;
2775			}
2776			sinit = mtod(m, struct sctp_initmsg *);
2777			SCTP_INP_RLOCK(inp);
2778			sinit->sinit_num_ostreams = inp->sctp_ep.pre_open_stream_count;
2779			sinit->sinit_max_instreams = inp->sctp_ep.max_open_streams_intome;
2780			sinit->sinit_max_attempts = inp->sctp_ep.max_init_times;
2781			sinit->sinit_max_init_timeo = inp->sctp_ep.initial_init_rto_max;
2782			SCTP_INP_RUNLOCK(inp);
2783			m->m_len = sizeof(*sinit);
2784		}
2785		break;
2786	case SCTP_PRIMARY_ADDR:
2787		/* we allow a "get" operation on this */
2788		{
2789			struct sctp_setprim *ssp;
2790
2791			if ((size_t)m->m_len < sizeof(struct sctp_setprim)) {
2792				error = EINVAL;
2793				break;
2794			}
2795			ssp = mtod(m, struct sctp_setprim *);
2796			if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2797				SCTP_INP_RLOCK(inp);
2798				stcb = LIST_FIRST(&inp->sctp_asoc_list);
2799				if (stcb)
2800					SCTP_TCB_LOCK(stcb);
2801				SCTP_INP_RUNLOCK(inp);
2802			} else {
2803				stcb = sctp_findassociation_ep_asocid(inp, ssp->ssp_assoc_id, 1);
2804				if (stcb == NULL) {
2805					/*
2806					 * one last shot, try it by the
2807					 * address in
2808					 */
2809					struct sctp_nets *net;
2810
2811					SCTP_INP_INCR_REF(inp);
2812					stcb = sctp_findassociation_ep_addr(&inp,
2813					    (struct sockaddr *)&ssp->ssp_addr,
2814					    &net, NULL, NULL);
2815					if (stcb == NULL) {
2816						SCTP_INP_DECR_REF(inp);
2817					}
2818				}
2819				if (stcb == NULL) {
2820					error = EINVAL;
2821					break;
2822				}
2823			}
2824			/* simply copy out the sockaddr_storage... */
2825			memcpy(&ssp->ssp_addr,
2826			    &stcb->asoc.primary_destination->ro._l_addr,
2827			    ((struct sockaddr *)&stcb->asoc.primary_destination->ro._l_addr)->sa_len);
2828			SCTP_TCB_UNLOCK(stcb);
2829			m->m_len = sizeof(*ssp);
2830		}
2831		break;
2832
2833	case SCTP_HMAC_IDENT:
2834		{
2835			struct sctp_hmacalgo *shmac;
2836			sctp_hmaclist_t *hmaclist;
2837			uint32_t size;
2838			int i;
2839
2840			if ((size_t)(m->m_len) < sizeof(*shmac)) {
2841				error = EINVAL;
2842				break;
2843			}
2844			shmac = mtod(m, struct sctp_hmacalgo *);
2845			SCTP_INP_RLOCK(inp);
2846			hmaclist = inp->sctp_ep.local_hmacs;
2847			if (hmaclist == NULL) {
2848				/* no HMACs to return */
2849				m->m_len = sizeof(*shmac);
2850				break;
2851			}
2852			/* is there room for all of the hmac ids? */
2853			size = sizeof(*shmac) + (hmaclist->num_algo *
2854			    sizeof(shmac->shmac_idents[0]));
2855			if ((size_t)(m->m_len) < size) {
2856				error = EINVAL;
2857				SCTP_INP_RUNLOCK(inp);
2858				break;
2859			}
2860			/* copy in the list */
2861			for (i = 0; i < hmaclist->num_algo; i++)
2862				shmac->shmac_idents[i] = hmaclist->hmac[i];
2863			SCTP_INP_RUNLOCK(inp);
2864			m->m_len = size;
2865			break;
2866		}
2867	case SCTP_AUTH_ACTIVE_KEY:
2868		{
2869			struct sctp_authkeyid *scact;
2870
2871			if ((size_t)(m->m_len) < sizeof(*scact)) {
2872				error = EINVAL;
2873				break;
2874			}
2875			scact = mtod(m, struct sctp_authkeyid *);
2876			if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2877				/*
2878				 * if one-to-one, get from the connected
2879				 * assoc; else endpoint
2880				 */
2881				SCTP_INP_RLOCK(inp);
2882				stcb = LIST_FIRST(&inp->sctp_asoc_list);
2883				if (stcb)
2884					SCTP_TCB_LOCK(stcb);
2885				SCTP_INP_RUNLOCK(inp);
2886			} else if (scact->scact_assoc_id) {
2887				stcb = sctp_findassociation_ep_asocid(inp, scact->scact_assoc_id, 1);
2888				if (stcb == NULL) {
2889					error = ENOENT;
2890					break;
2891				}
2892			}
2893			if (stcb != NULL) {
2894				/* get the active key on the assoc */
2895				scact->scact_keynumber = stcb->asoc.authinfo.assoc_keyid;
2896				SCTP_TCB_UNLOCK(stcb);
2897			} else {
2898				/* get the endpoint active key */
2899				SCTP_INP_RLOCK(inp);
2900				scact->scact_keynumber = inp->sctp_ep.default_keyid;
2901				SCTP_INP_RUNLOCK(inp);
2902			}
2903			m->m_len = sizeof(*scact);
2904			break;
2905		}
2906	case SCTP_LOCAL_AUTH_CHUNKS:
2907		{
2908			struct sctp_authchunks *sac;
2909			sctp_auth_chklist_t *chklist = NULL;
2910			int size = 0;
2911
2912			if ((size_t)(m->m_len) < sizeof(*sac)) {
2913				error = EINVAL;
2914				break;
2915			}
2916			sac = mtod(m, struct sctp_authchunks *);
2917			if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2918				/*
2919				 * if one-to-one, get from the connected
2920				 * assoc; else endpoint
2921				 */
2922				SCTP_INP_RLOCK(inp);
2923				stcb = LIST_FIRST(&inp->sctp_asoc_list);
2924				if (stcb != NULL)
2925					SCTP_TCB_LOCK(stcb);
2926				SCTP_INP_RUNLOCK(inp);
2927			} else if (sac->gauth_assoc_id) {
2928				stcb = sctp_findassociation_ep_asocid(inp, sac->gauth_assoc_id, 1);
2929				if (stcb == NULL) {
2930					error = ENOENT;
2931					break;
2932				}
2933			}
2934			if (stcb != NULL) {
2935				/* get off the assoc */
2936				chklist = stcb->asoc.local_auth_chunks;
2937				if (chklist == NULL) {
2938					error = EINVAL;
2939					SCTP_TCB_UNLOCK(stcb);
2940					break;
2941				}
2942				/* is there enough space? */
2943				size = sctp_auth_get_chklist_size(chklist);
2944				if ((size_t)m->m_len < (sizeof(struct sctp_authchunks) + size)) {
2945					error = EINVAL;
2946					SCTP_TCB_UNLOCK(stcb);
2947					break;
2948				}
2949				/* copy in the chunks */
2950				sctp_serialize_auth_chunks(chklist, sac->gauth_chunks);
2951				SCTP_TCB_UNLOCK(stcb);
2952			} else {
2953				/* get off the endpoint */
2954				SCTP_INP_RLOCK(inp);
2955				chklist = inp->sctp_ep.local_auth_chunks;
2956				if (chklist == NULL) {
2957					error = EINVAL;
2958					SCTP_INP_RUNLOCK(inp);
2959					break;
2960				}
2961				/* is there enough space? */
2962				size = sctp_auth_get_chklist_size(chklist);
2963				if ((size_t)m->m_len < (sizeof(struct sctp_authchunks) + size)) {
2964					error = EINVAL;
2965					SCTP_INP_RUNLOCK(inp);
2966					break;
2967				}
2968				/* copy in the chunks */
2969				sctp_serialize_auth_chunks(chklist, sac->gauth_chunks);
2970				SCTP_INP_RUNLOCK(inp);
2971			}
2972			m->m_len = sizeof(struct sctp_authchunks) + size;
2973			break;
2974		}
2975	case SCTP_PEER_AUTH_CHUNKS:
2976		{
2977			struct sctp_authchunks *sac;
2978			sctp_auth_chklist_t *chklist = NULL;
2979			int size = 0;
2980
2981			if ((size_t)(m->m_len) < sizeof(*sac)) {
2982				error = EINVAL;
2983				break;
2984			}
2985			sac = mtod(m, struct sctp_authchunks *);
2986			if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2987				/*
2988				 * if one-to-one, get from the connected
2989				 * assoc, else endpoint
2990				 */
2991				SCTP_INP_RLOCK(inp);
2992				stcb = LIST_FIRST(&inp->sctp_asoc_list);
2993				if (stcb != NULL)
2994					SCTP_TCB_LOCK(stcb);
2995				SCTP_INP_RUNLOCK(inp);
2996			} else if (sac->gauth_assoc_id) {
2997				stcb = sctp_findassociation_ep_asocid(inp, sac->gauth_assoc_id, 1);
2998			}
2999			if (stcb == NULL) {
3000				error = ENOENT;
3001				break;
3002			}
3003			/* get off the assoc */
3004			chklist = stcb->asoc.peer_auth_chunks;
3005			if (chklist == NULL) {
3006				error = EINVAL;
3007				SCTP_TCB_UNLOCK(stcb);
3008				break;
3009			}
3010			/* is there enough space? */
3011			size = sctp_auth_get_chklist_size(chklist);
3012			if ((size_t)m->m_len < (sizeof(struct sctp_authchunks) + size)) {
3013				error = EINVAL;
3014				SCTP_TCB_UNLOCK(stcb);
3015				break;
3016			}
3017			/* copy in the chunks */
3018			sctp_serialize_auth_chunks(chklist, sac->gauth_chunks);
3019			SCTP_TCB_UNLOCK(stcb);
3020			m->m_len = sizeof(struct sctp_authchunks) + size;
3021			break;
3022		}
3023
3024
3025	default:
3026		error = ENOPROTOOPT;
3027		m->m_len = 0;
3028		break;
3029	}			/* end switch (sopt->sopt_name) */
3030	return (error);
3031}
3032
3033
3034static int
3035sctp_optsset(struct socket *so,
3036    int opt,
3037    struct mbuf **mp,
3038    struct thread *p
3039)
3040{
3041	int error, *mopt, set_opt, s;
3042	struct mbuf *m;
3043	struct sctp_tcb *stcb = NULL;
3044	struct sctp_inpcb *inp;
3045
3046	if (mp == NULL) {
3047		return (EINVAL);
3048	}
3049	m = *mp;
3050	if (m == NULL)
3051		return (EINVAL);
3052
3053	inp = (struct sctp_inpcb *)so->so_pcb;
3054	if (inp == 0)
3055		return EINVAL;
3056
3057	error = 0;
3058	switch (opt) {
3059	case SCTP_NODELAY:
3060	case SCTP_AUTOCLOSE:
3061	case SCTP_AUTO_ASCONF:
3062	case SCTP_EXPLICIT_EOR:
3063	case SCTP_DISABLE_FRAGMENTS:
3064	case SCTP_USE_EXT_RCVINFO:
3065	case SCTP_I_WANT_MAPPED_V4_ADDR:
3066		/* copy in the option value */
3067		if ((size_t)m->m_len < sizeof(int)) {
3068			error = EINVAL;
3069			break;
3070		}
3071		mopt = mtod(m, int *);
3072		set_opt = 0;
3073		if (error)
3074			break;
3075		switch (opt) {
3076		case SCTP_DISABLE_FRAGMENTS:
3077			set_opt = SCTP_PCB_FLAGS_NO_FRAGMENT;
3078			break;
3079		case SCTP_AUTO_ASCONF:
3080			set_opt = SCTP_PCB_FLAGS_AUTO_ASCONF;
3081			break;
3082		case SCTP_EXPLICIT_EOR:
3083			set_opt = SCTP_PCB_FLAGS_EXPLICIT_EOR;
3084			break;
3085		case SCTP_USE_EXT_RCVINFO:
3086			set_opt = SCTP_PCB_FLAGS_EXT_RCVINFO;
3087			break;
3088		case SCTP_I_WANT_MAPPED_V4_ADDR:
3089			if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
3090				set_opt = SCTP_PCB_FLAGS_NEEDS_MAPPED_V4;
3091			} else {
3092				return (EINVAL);
3093			}
3094			break;
3095		case SCTP_NODELAY:
3096			set_opt = SCTP_PCB_FLAGS_NODELAY;
3097			break;
3098		case SCTP_AUTOCLOSE:
3099			set_opt = SCTP_PCB_FLAGS_AUTOCLOSE;
3100			/*
3101			 * The value is in ticks. Note this does not effect
3102			 * old associations, only new ones.
3103			 */
3104			inp->sctp_ep.auto_close_time = SEC_TO_TICKS(*mopt);
3105			break;
3106		}
3107		SCTP_INP_WLOCK(inp);
3108		if (*mopt != 0) {
3109			sctp_feature_on(inp, set_opt);
3110		} else {
3111			sctp_feature_off(inp, set_opt);
3112		}
3113		SCTP_INP_WUNLOCK(inp);
3114		break;
3115	case SCTP_PARTIAL_DELIVERY_POINT:
3116		{
3117			if ((size_t)m->m_len < sizeof(unsigned int)) {
3118				error = EINVAL;
3119				break;
3120			}
3121			inp->partial_delivery_point = *mtod(m, unsigned int *);
3122			m->m_len = sizeof(unsigned int);
3123		}
3124		break;
3125	case SCTP_FRAGMENT_INTERLEAVE:
3126		/* not yet until we re-write sctp_recvmsg() */
3127		{
3128			int on_off;
3129
3130			if ((size_t)m->m_len < sizeof(int)) {
3131				error = EINVAL;
3132				break;
3133			}
3134			on_off = (mtod(m, int));
3135			if (on_off) {
3136				sctp_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE);
3137			} else {
3138				sctp_feature_off(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE);
3139			}
3140		}
3141		break;
3142	case SCTP_CMT_ON_OFF:
3143		{
3144			struct sctp_assoc_value *av;
3145
3146			if ((size_t)m->m_len < sizeof(struct sctp_assoc_value)) {
3147				error = EINVAL;
3148				break;
3149			}
3150			av = mtod(m, struct sctp_assoc_value *);
3151			stcb = sctp_findassociation_ep_asocid(inp, av->assoc_id, 1);
3152			if (stcb == NULL) {
3153				error = ENOTCONN;
3154			} else {
3155				if (sctp_cmt_on_off) {
3156					stcb->asoc.sctp_cmt_on_off = (uint8_t) av->assoc_value;
3157				} else {
3158					if ((stcb->asoc.sctp_cmt_on_off) && (av->assoc_value == 0)) {
3159						stcb->asoc.sctp_cmt_on_off = 0;
3160					} else {
3161						error = EACCES;
3162					}
3163				}
3164				SCTP_TCB_UNLOCK(stcb);
3165			}
3166		}
3167		break;
3168	case SCTP_CMT_USE_DAC:
3169		{
3170			if ((size_t)m->m_len < sizeof(unsigned int)) {
3171				error = EINVAL;
3172				break;
3173			}
3174			sctp_cmt_sockopt_use_dac = *mtod(m, unsigned int *);
3175			if (sctp_cmt_sockopt_use_dac != 0)
3176				sctp_cmt_sockopt_use_dac = 1;
3177		}
3178		break;
3179	case SCTP_CLR_STAT_LOG:
3180#ifdef SCTP_STAT_LOGGING
3181		sctp_clr_stat_log();
3182#else
3183		error = EOPNOTSUPP;
3184#endif
3185		break;
3186	case SCTP_CONTEXT:
3187		{
3188
3189			struct sctp_assoc_value *av;
3190
3191			if ((size_t)m->m_len < sizeof(struct sctp_assoc_value)) {
3192				error = EINVAL;
3193				break;
3194			}
3195			av = mtod(m, struct sctp_assoc_value *);
3196			if (av->assoc_id) {
3197				stcb = sctp_findassociation_ep_asocid(inp, av->assoc_id, 1);
3198				if (stcb == NULL) {
3199					error = ENOTCONN;
3200				} else {
3201					stcb->asoc.context = av->assoc_value;
3202					SCTP_TCB_UNLOCK(stcb);
3203				}
3204			} else {
3205				inp->sctp_context = av->assoc_value;
3206			}
3207		}
3208		break;
3209	case SCTP_DELAYED_ACK_TIME:
3210		{
3211			struct sctp_assoc_value *tm;
3212
3213			if ((size_t)m->m_len < sizeof(struct sctp_assoc_value)) {
3214				error = EINVAL;
3215				break;
3216			}
3217			tm = mtod(m, struct sctp_assoc_value *);
3218
3219			if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
3220				SCTP_INP_WLOCK(inp);
3221				stcb = LIST_FIRST(&inp->sctp_asoc_list);
3222				if (stcb) {
3223					SCTP_TCB_LOCK(stcb);
3224					stcb->asoc.delayed_ack = tm->assoc_value;
3225					SCTP_TCB_UNLOCK(stcb);
3226				} else {
3227					inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV] = MSEC_TO_TICKS(tm->assoc_value);
3228				}
3229				SCTP_INP_WUNLOCK(inp);
3230			} else {
3231				if (tm->assoc_id) {
3232					stcb = sctp_findassociation_ep_asocid(inp, tm->assoc_id, 1);
3233					if (stcb == NULL) {
3234						error = ENOTCONN;
3235					} else {
3236						stcb->asoc.delayed_ack = tm->assoc_value;
3237						SCTP_TCB_UNLOCK(stcb);
3238					}
3239				} else {
3240					SCTP_INP_WLOCK(inp);
3241					inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV] = MSEC_TO_TICKS(tm->assoc_value);
3242					SCTP_INP_WUNLOCK(inp);
3243				}
3244			}
3245		}
3246		break;
3247
3248	case SCTP_AUTH_CHUNK:
3249		{
3250			struct sctp_authchunk *sauth;
3251
3252			if ((size_t)m->m_len < sizeof(*sauth)) {
3253				error = EINVAL;
3254				break;
3255			}
3256			sauth = mtod(m, struct sctp_authchunk *);
3257			if (sctp_auth_add_chunk(sauth->sauth_chunk,
3258			    inp->sctp_ep.local_auth_chunks))
3259				error = EINVAL;
3260			break;
3261		}
3262	case SCTP_AUTH_KEY:
3263		{
3264			struct sctp_authkey *sca;
3265			struct sctp_keyhead *shared_keys;
3266			sctp_sharedkey_t *shared_key;
3267			sctp_key_t *key = NULL;
3268			int size;
3269
3270			size = m->m_len - sizeof(*sca);
3271			if (size < 0) {
3272				error = EINVAL;
3273				break;
3274			}
3275			sca = mtod(m, struct sctp_authkey *);
3276			if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
3277				/*
3278				 * if one-to-one, set it on the connected
3279				 * assoc; else endpoint
3280				 */
3281				SCTP_INP_RLOCK(inp);
3282				stcb = LIST_FIRST(&inp->sctp_asoc_list);
3283				if (stcb)
3284					SCTP_TCB_LOCK(stcb);
3285				SCTP_INP_RUNLOCK(inp);
3286			} else if (sca->sca_assoc_id) {
3287				stcb = sctp_findassociation_ep_asocid(inp, sca->sca_assoc_id, 1);
3288				if (stcb == NULL) {
3289					error = ENOENT;
3290					break;
3291				}
3292			}
3293			if (stcb != NULL) {
3294				/* set it on the assoc */
3295				shared_keys = &stcb->asoc.shared_keys;
3296				/* clear the cached keys for this key id */
3297				sctp_clear_cachedkeys(stcb, sca->sca_keynumber);
3298				/*
3299				 * create the new shared key and
3300				 * insert/replace it
3301				 */
3302				if (size > 0) {
3303					key = sctp_set_key(sca->sca_key, (uint32_t) size);
3304					if (key == NULL) {
3305						error = ENOMEM;
3306						SCTP_TCB_UNLOCK(stcb);
3307						break;
3308					}
3309				}
3310				shared_key = sctp_alloc_sharedkey();
3311				if (shared_key == NULL) {
3312					sctp_free_key(key);
3313					error = ENOMEM;
3314					SCTP_TCB_UNLOCK(stcb);
3315					break;
3316				}
3317				shared_key->key = key;
3318				shared_key->keyid = sca->sca_keynumber;
3319				sctp_insert_sharedkey(shared_keys, shared_key);
3320				SCTP_TCB_UNLOCK(stcb);
3321			} else {
3322				/* ste it on the endpoint */
3323				SCTP_INP_WLOCK(inp);
3324				shared_keys = &inp->sctp_ep.shared_keys;
3325				/*
3326				 * clear the cached keys on all assocs for
3327				 * this key id
3328				 */
3329				sctp_clear_cachedkeys_ep(inp, sca->sca_keynumber);
3330				/*
3331				 * create the new shared key and
3332				 * insert/replace it
3333				 */
3334				if (size > 0) {
3335					key = sctp_set_key(sca->sca_key, (uint32_t) size);
3336					if (key == NULL) {
3337						error = ENOMEM;
3338						SCTP_INP_WUNLOCK(inp);
3339						break;
3340					}
3341				}
3342				shared_key = sctp_alloc_sharedkey();
3343				if (shared_key == NULL) {
3344					sctp_free_key(key);
3345					error = ENOMEM;
3346					SCTP_INP_WUNLOCK(inp);
3347					break;
3348				}
3349				shared_key->key = key;
3350				shared_key->keyid = sca->sca_keynumber;
3351				sctp_insert_sharedkey(shared_keys, shared_key);
3352				SCTP_INP_WUNLOCK(inp);
3353			}
3354			break;
3355		}
3356	case SCTP_HMAC_IDENT:
3357		{
3358			struct sctp_hmacalgo *shmac;
3359			sctp_hmaclist_t *hmaclist;
3360			uint32_t hmacid;
3361			int size, i;
3362
3363			size = m->m_len - sizeof(*shmac);
3364			if (size < 0) {
3365				error = EINVAL;
3366				break;
3367			}
3368			shmac = mtod(m, struct sctp_hmacalgo *);
3369			size = size / sizeof(shmac->shmac_idents[0]);
3370			hmaclist = sctp_alloc_hmaclist(size);
3371			if (hmaclist == NULL) {
3372				error = ENOMEM;
3373				break;
3374			}
3375			for (i = 0; i < size; i++) {
3376				hmacid = shmac->shmac_idents[i];
3377				if (sctp_auth_add_hmacid(hmaclist, (uint16_t) hmacid)) {
3378					 /* invalid HMACs were found */ ;
3379					error = EINVAL;
3380					goto sctp_set_hmac_done;
3381				}
3382			}
3383			/* set it on the endpoint */
3384			SCTP_INP_WLOCK(inp);
3385			if (inp->sctp_ep.local_hmacs)
3386				sctp_free_hmaclist(inp->sctp_ep.local_hmacs);
3387			inp->sctp_ep.local_hmacs = hmaclist;
3388			SCTP_INP_WUNLOCK(inp);
3389	sctp_set_hmac_done:
3390			break;
3391		}
3392	case SCTP_AUTH_ACTIVE_KEY:
3393		{
3394			struct sctp_authkeyid *scact;
3395
3396			if ((size_t)m->m_len < sizeof(*scact)) {
3397				error = EINVAL;
3398				break;
3399			}
3400			scact = mtod(m, struct sctp_authkeyid *);
3401			if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
3402				/*
3403				 * if one-to-one, set it on the connected
3404				 * assoc; else endpoint
3405				 */
3406				SCTP_INP_RLOCK(inp);
3407				stcb = LIST_FIRST(&inp->sctp_asoc_list);
3408				if (stcb)
3409					SCTP_TCB_LOCK(stcb);
3410				SCTP_INP_RUNLOCK(inp);
3411			} else if (scact->scact_assoc_id) {
3412				stcb = sctp_findassociation_ep_asocid(inp, scact->scact_assoc_id, 1);
3413				if (stcb == NULL) {
3414					error = ENOENT;
3415					break;
3416				}
3417			}
3418			/* set the active key on the right place */
3419			if (stcb != NULL) {
3420				/* set the active key on the assoc */
3421				if (sctp_auth_setactivekey(stcb, scact->scact_keynumber))
3422					error = EINVAL;
3423				SCTP_TCB_UNLOCK(stcb);
3424			} else {
3425				/* set the active key on the endpoint */
3426				SCTP_INP_WLOCK(inp);
3427				if (sctp_auth_setactivekey_ep(inp, scact->scact_keynumber))
3428					error = EINVAL;
3429				SCTP_INP_WUNLOCK(inp);
3430			}
3431			break;
3432		}
3433	case SCTP_AUTH_DELETE_KEY:
3434		{
3435			struct sctp_authkeyid *scdel;
3436
3437			if ((size_t)m->m_len < sizeof(*scdel)) {
3438				error = EINVAL;
3439				break;
3440			}
3441			scdel = mtod(m, struct sctp_authkeyid *);
3442			if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
3443				/*
3444				 * if one-to-one, delete from the connected
3445				 * assoc; else endpoint
3446				 */
3447				SCTP_INP_RLOCK(inp);
3448				stcb = LIST_FIRST(&inp->sctp_asoc_list);
3449				if (stcb)
3450					SCTP_TCB_LOCK(stcb);
3451				SCTP_INP_RUNLOCK(inp);
3452			} else if (scdel->scact_assoc_id) {
3453				stcb = sctp_findassociation_ep_asocid(inp, scdel->scact_assoc_id, 1);
3454				if (stcb == NULL) {
3455					error = ENOENT;
3456					break;
3457				}
3458			}
3459			/* delete the key from the right place */
3460			if (stcb != NULL) {
3461				if (sctp_delete_sharedkey(stcb, scdel->scact_keynumber))
3462					error = EINVAL;
3463				SCTP_TCB_UNLOCK(stcb);
3464			} else {
3465				SCTP_INP_WLOCK(inp);
3466				if (sctp_delete_sharedkey_ep(inp, scdel->scact_keynumber))
3467					error = EINVAL;
3468				SCTP_INP_WUNLOCK(inp);
3469			}
3470			break;
3471		}
3472
3473	case SCTP_RESET_STREAMS:
3474		{
3475			struct sctp_stream_reset *strrst;
3476			uint8_t send_in = 0, send_tsn = 0, send_out = 0;
3477			int i;
3478
3479			if ((size_t)m->m_len < sizeof(struct sctp_stream_reset)) {
3480				error = EINVAL;
3481				break;
3482			}
3483			strrst = mtod(m, struct sctp_stream_reset *);
3484
3485			if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
3486				SCTP_INP_RLOCK(inp);
3487				stcb = LIST_FIRST(&inp->sctp_asoc_list);
3488				if (stcb)
3489					SCTP_TCB_LOCK(stcb);
3490				SCTP_INP_RUNLOCK(inp);
3491			} else
3492				stcb = sctp_findassociation_ep_asocid(inp, strrst->strrst_assoc_id, 1);
3493			if (stcb == NULL) {
3494				error = ENOENT;
3495				break;
3496			}
3497			if (stcb->asoc.peer_supports_strreset == 0) {
3498				/*
3499				 * Peer does not support it, we return
3500				 * protocol not supported since this is true
3501				 * for this feature and this peer, not the
3502				 * socket request in general.
3503				 */
3504				error = EPROTONOSUPPORT;
3505				SCTP_TCB_UNLOCK(stcb);
3506				break;
3507			}
3508			if (stcb->asoc.stream_reset_outstanding) {
3509				error = EALREADY;
3510				SCTP_TCB_UNLOCK(stcb);
3511				break;
3512			}
3513			if (strrst->strrst_flags == SCTP_RESET_LOCAL_RECV) {
3514				send_in = 1;
3515			} else if (strrst->strrst_flags == SCTP_RESET_LOCAL_SEND) {
3516				send_out = 1;
3517			} else if (strrst->strrst_flags == SCTP_RESET_BOTH) {
3518				send_in = 1;
3519				send_out = 1;
3520			} else if (strrst->strrst_flags == SCTP_RESET_TSN) {
3521				send_tsn = 1;
3522			} else {
3523				error = EINVAL;
3524				SCTP_TCB_UNLOCK(stcb);
3525				break;
3526			}
3527			for (i = 0; i < strrst->strrst_num_streams; i++) {
3528				if ((send_in) &&
3529
3530				    (strrst->strrst_list[i] > stcb->asoc.streamincnt)) {
3531					error = EINVAL;
3532					goto get_out;
3533				}
3534				if ((send_out) &&
3535				    (strrst->strrst_list[i] > stcb->asoc.streamoutcnt)) {
3536					error = EINVAL;
3537					goto get_out;
3538				}
3539			}
3540			if (error) {
3541		get_out:
3542				SCTP_TCB_UNLOCK(stcb);
3543				break;
3544			}
3545			error = sctp_send_str_reset_req(stcb, strrst->strrst_num_streams,
3546			    strrst->strrst_list,
3547			    send_out, (stcb->asoc.str_reset_seq_in - 3),
3548			    send_in, send_tsn);
3549
3550			s = splnet();
3551			sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_STRRST_REQ);
3552			SCTP_TCB_UNLOCK(stcb);
3553			splx(s);
3554
3555		}
3556		break;
3557	case SCTP_CONNECT_X:
3558		if ((size_t)m->m_len < (sizeof(int) + sizeof(struct sockaddr_in))) {
3559			error = EINVAL;
3560			break;
3561		}
3562		error = sctp_do_connect_x(so, inp, m, p, 0);
3563		break;
3564
3565	case SCTP_CONNECT_X_DELAYED:
3566		if ((size_t)m->m_len < (sizeof(int) + sizeof(struct sockaddr_in))) {
3567			error = EINVAL;
3568			break;
3569		}
3570		error = sctp_do_connect_x(so, inp, m, p, 1);
3571		break;
3572
3573	case SCTP_CONNECT_X_COMPLETE:
3574		{
3575			struct sockaddr *sa;
3576			struct sctp_nets *net;
3577
3578			if ((size_t)m->m_len < sizeof(struct sockaddr_in)) {
3579				error = EINVAL;
3580				break;
3581			}
3582			sa = mtod(m, struct sockaddr *);
3583			/* find tcb */
3584			if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
3585				SCTP_INP_RLOCK(inp);
3586				stcb = LIST_FIRST(&inp->sctp_asoc_list);
3587				if (stcb) {
3588					SCTP_TCB_LOCK(stcb);
3589					net = sctp_findnet(stcb, sa);
3590				}
3591				SCTP_INP_RUNLOCK(inp);
3592			} else {
3593				SCTP_INP_INCR_REF(inp);
3594				stcb = sctp_findassociation_ep_addr(&inp, sa, &net, NULL, NULL);
3595				if (stcb == NULL) {
3596					SCTP_INP_DECR_REF(inp);
3597				}
3598			}
3599
3600			if (stcb == NULL) {
3601				error = ENOENT;
3602				break;
3603			}
3604			if (stcb->asoc.delayed_connection == 1) {
3605				stcb->asoc.delayed_connection = 0;
3606				SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered);
3607				sctp_timer_stop(SCTP_TIMER_TYPE_INIT, inp, stcb, stcb->asoc.primary_destination);
3608				sctp_send_initiate(inp, stcb);
3609			} else {
3610				/*
3611				 * already expired or did not use delayed
3612				 * connectx
3613				 */
3614				error = EALREADY;
3615			}
3616			SCTP_TCB_UNLOCK(stcb);
3617		}
3618		break;
3619	case SCTP_MAXBURST:
3620		{
3621			uint8_t *burst;
3622
3623			SCTP_INP_WLOCK(inp);
3624			burst = mtod(m, uint8_t *);
3625			if (*burst) {
3626				inp->sctp_ep.max_burst = *burst;
3627			}
3628			SCTP_INP_WUNLOCK(inp);
3629		}
3630		break;
3631	case SCTP_MAXSEG:
3632		{
3633			uint32_t *segsize;
3634			int ovh;
3635
3636			if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
3637				ovh = SCTP_MED_OVERHEAD;
3638			} else {
3639				ovh = SCTP_MED_V4_OVERHEAD;
3640			}
3641			segsize = mtod(m, uint32_t *);
3642			if (*segsize < 1) {
3643				error = EINVAL;
3644				break;
3645			}
3646			SCTP_INP_WLOCK(inp);
3647			inp->sctp_frag_point = (*segsize + ovh);
3648			if (inp->sctp_frag_point < MHLEN) {
3649				inp->sctp_frag_point = MHLEN;
3650			}
3651			SCTP_INP_WUNLOCK(inp);
3652		}
3653		break;
3654	case SCTP_SET_DEBUG_LEVEL:
3655#ifdef SCTP_DEBUG
3656		{
3657			uint32_t *level;
3658
3659			if ((size_t)m->m_len < sizeof(uint32_t)) {
3660				error = EINVAL;
3661				break;
3662			}
3663			level = mtod(m, uint32_t *);
3664			error = 0;
3665			sctp_debug_on = (*level & (SCTP_DEBUG_ALL |
3666			    SCTP_DEBUG_NOISY));
3667			printf("SETTING DEBUG LEVEL to %x\n",
3668			    (uint32_t) sctp_debug_on);
3669
3670		}
3671#else
3672		error = EOPNOTSUPP;
3673#endif				/* SCTP_DEBUG */
3674		break;
3675	case SCTP_EVENTS:
3676		{
3677			struct sctp_event_subscribe *events;
3678
3679			if ((size_t)m->m_len < sizeof(struct sctp_event_subscribe)) {
3680				error = EINVAL;
3681				break;
3682			}
3683			SCTP_INP_WLOCK(inp);
3684			events = mtod(m, struct sctp_event_subscribe *);
3685			if (events->sctp_data_io_event) {
3686				sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT);
3687			} else {
3688				sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT);
3689			}
3690
3691			if (events->sctp_association_event) {
3692				sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVASSOCEVNT);
3693			} else {
3694				sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVASSOCEVNT);
3695			}
3696
3697			if (events->sctp_address_event) {
3698				sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVPADDREVNT);
3699			} else {
3700				sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVPADDREVNT);
3701			}
3702
3703			if (events->sctp_send_failure_event) {
3704				sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVSENDFAILEVNT);
3705			} else {
3706				sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVSENDFAILEVNT);
3707			}
3708
3709			if (events->sctp_peer_error_event) {
3710				sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVPEERERR);
3711			} else {
3712				sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVPEERERR);
3713			}
3714
3715			if (events->sctp_shutdown_event) {
3716				sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT);
3717			} else {
3718				sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT);
3719			}
3720
3721			if (events->sctp_partial_delivery_event) {
3722				sctp_feature_on(inp, SCTP_PCB_FLAGS_PDAPIEVNT);
3723			} else {
3724				sctp_feature_off(inp, SCTP_PCB_FLAGS_PDAPIEVNT);
3725			}
3726
3727			if (events->sctp_adaptation_layer_event) {
3728				sctp_feature_on(inp, SCTP_PCB_FLAGS_ADAPTATIONEVNT);
3729			} else {
3730				sctp_feature_off(inp, SCTP_PCB_FLAGS_ADAPTATIONEVNT);
3731			}
3732
3733			if (events->sctp_authentication_event) {
3734				sctp_feature_on(inp, SCTP_PCB_FLAGS_AUTHEVNT);
3735			} else {
3736				sctp_feature_off(inp, SCTP_PCB_FLAGS_AUTHEVNT);
3737			}
3738
3739			if (events->sctp_stream_reset_events) {
3740				sctp_feature_on(inp, SCTP_PCB_FLAGS_STREAM_RESETEVNT);
3741			} else {
3742				sctp_feature_off(inp, SCTP_PCB_FLAGS_STREAM_RESETEVNT);
3743			}
3744			SCTP_INP_WUNLOCK(inp);
3745		}
3746		break;
3747
3748	case SCTP_ADAPTATION_LAYER:
3749		{
3750			struct sctp_setadaptation *adap_bits;
3751
3752			if ((size_t)m->m_len < sizeof(struct sctp_setadaptation)) {
3753				error = EINVAL;
3754				break;
3755			}
3756			SCTP_INP_WLOCK(inp);
3757			adap_bits = mtod(m, struct sctp_setadaptation *);
3758			inp->sctp_ep.adaptation_layer_indicator = adap_bits->ssb_adaptation_ind;
3759			SCTP_INP_WUNLOCK(inp);
3760		}
3761		break;
3762	case SCTP_SET_INITIAL_DBG_SEQ:
3763		{
3764			uint32_t *vvv;
3765
3766			if ((size_t)m->m_len < sizeof(uint32_t)) {
3767				error = EINVAL;
3768				break;
3769			}
3770			SCTP_INP_WLOCK(inp);
3771			vvv = mtod(m, uint32_t *);
3772			inp->sctp_ep.initial_sequence_debug = *vvv;
3773			SCTP_INP_WUNLOCK(inp);
3774		}
3775		break;
3776	case SCTP_DEFAULT_SEND_PARAM:
3777		{
3778			struct sctp_sndrcvinfo *s_info;
3779
3780			if (m->m_len != sizeof(struct sctp_sndrcvinfo)) {
3781				error = EINVAL;
3782				break;
3783			}
3784			s_info = mtod(m, struct sctp_sndrcvinfo *);
3785
3786			if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
3787				SCTP_INP_RLOCK(inp);
3788				stcb = LIST_FIRST(&inp->sctp_asoc_list);
3789				if (stcb)
3790					SCTP_TCB_LOCK(stcb);
3791				SCTP_INP_RUNLOCK(inp);
3792			} else {
3793				if (s_info->sinfo_assoc_id) {
3794					stcb = sctp_findassociation_ep_asocid(inp, s_info->sinfo_assoc_id, 1);
3795				} else {
3796					stcb = NULL;
3797				}
3798			}
3799			if ((s_info->sinfo_assoc_id == 0) &&
3800			    (stcb == NULL)) {
3801				inp->def_send = *s_info;
3802			} else if (stcb == NULL) {
3803				error = ENOENT;
3804				break;
3805			}
3806			/* Validate things */
3807			if (s_info->sinfo_stream > stcb->asoc.streamoutcnt) {
3808				SCTP_TCB_UNLOCK(stcb);
3809				error = EINVAL;
3810				break;
3811			}
3812			/* Copy it in */
3813			stcb->asoc.def_send = *s_info;
3814			SCTP_TCB_UNLOCK(stcb);
3815		}
3816		break;
3817	case SCTP_PEER_ADDR_PARAMS:
3818		/* Applys to the specific association */
3819		{
3820			struct sctp_paddrparams *paddrp;
3821			struct sctp_nets *net;
3822
3823			if ((size_t)m->m_len < sizeof(struct sctp_paddrparams)) {
3824				error = EINVAL;
3825				break;
3826			}
3827			paddrp = mtod(m, struct sctp_paddrparams *);
3828			net = NULL;
3829			if (paddrp->spp_assoc_id) {
3830				if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
3831					SCTP_INP_RLOCK(inp);
3832					stcb = LIST_FIRST(&inp->sctp_asoc_list);
3833					if (stcb) {
3834						SCTP_TCB_LOCK(stcb);
3835						net = sctp_findnet(stcb, (struct sockaddr *)&paddrp->spp_address);
3836					}
3837					SCTP_INP_RUNLOCK(inp);
3838				} else {
3839					stcb = sctp_findassociation_ep_asocid(inp, paddrp->spp_assoc_id, 1);
3840				}
3841				if (stcb == NULL) {
3842					error = ENOENT;
3843					break;
3844				}
3845			}
3846			if ((stcb == NULL) &&
3847			    ((((struct sockaddr *)&paddrp->spp_address)->sa_family == AF_INET) ||
3848			    (((struct sockaddr *)&paddrp->spp_address)->sa_family == AF_INET6))) {
3849				/* Lookup via address */
3850				if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
3851					SCTP_INP_RLOCK(inp);
3852					stcb = LIST_FIRST(&inp->sctp_asoc_list);
3853					if (stcb) {
3854						SCTP_TCB_LOCK(stcb);
3855						net = sctp_findnet(stcb,
3856						    (struct sockaddr *)&paddrp->spp_address);
3857					}
3858					SCTP_INP_RUNLOCK(inp);
3859				} else {
3860					SCTP_INP_INCR_REF(inp);
3861					stcb = sctp_findassociation_ep_addr(&inp,
3862					    (struct sockaddr *)&paddrp->spp_address,
3863					    &net, NULL, NULL);
3864					if (stcb == NULL) {
3865						SCTP_INP_DECR_REF(inp);
3866					}
3867				}
3868			}
3869			if (stcb) {
3870				/************************TCB SPECIFIC SET ******************/
3871				/* sack delay first */
3872				if (paddrp->spp_flags & SPP_SACKDELAY_ENABLE) {
3873					/*
3874					 * we do NOT support turning it off
3875					 * (yet). only setting the delay.
3876					 */
3877					if (paddrp->spp_sackdelay >= SCTP_CLOCK_GRANULARITY)
3878						stcb->asoc.delayed_ack = paddrp->spp_sackdelay;
3879					else
3880						stcb->asoc.delayed_ack = SCTP_CLOCK_GRANULARITY;
3881
3882				} else if (paddrp->spp_flags & SPP_SACKDELAY_DISABLE) {
3883					stcb->asoc.delayed_ack = 0;
3884				}
3885				/*
3886				 * do we change the timer for HB, we run
3887				 * only one?
3888				 */
3889				if (paddrp->spp_hbinterval)
3890					stcb->asoc.heart_beat_delay = paddrp->spp_hbinterval;
3891				else if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO)
3892					stcb->asoc.heart_beat_delay = 0;
3893
3894				/* network sets ? */
3895				if (net) {
3896					/************************NET SPECIFIC SET ******************/
3897					if (paddrp->spp_flags & SPP_HB_DEMAND) {
3898						/* on demand HB */
3899						sctp_send_hb(stcb, 1, net);
3900					}
3901					if (paddrp->spp_flags & SPP_HB_DISABLE) {
3902						net->dest_state |= SCTP_ADDR_NOHB;
3903					}
3904					if (paddrp->spp_flags & SPP_HB_ENABLE) {
3905						net->dest_state &= ~SCTP_ADDR_NOHB;
3906					}
3907					if (paddrp->spp_flags & SPP_PMTUD_DISABLE) {
3908						if (callout_pending(&net->pmtu_timer.timer)) {
3909							sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net);
3910						}
3911						if (paddrp->spp_pathmtu > SCTP_DEFAULT_MINSEGMENT) {
3912							net->mtu = paddrp->spp_pathmtu;
3913							if (net->mtu < stcb->asoc.smallest_mtu)
3914								sctp_pathmtu_adustment(inp, stcb, net, net->mtu);
3915						}
3916					}
3917					if (paddrp->spp_flags & SPP_PMTUD_ENABLE) {
3918						if (callout_pending(&net->pmtu_timer.timer)) {
3919							sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net);
3920						}
3921					}
3922					if (paddrp->spp_pathmaxrxt)
3923						net->failure_threshold = paddrp->spp_pathmaxrxt;
3924#ifdef AF_INET
3925					if (paddrp->spp_flags & SPP_IPV4_TOS) {
3926						if (net->ro._l_addr.sin.sin_family == AF_INET) {
3927							net->tos_flowlabel = paddrp->spp_ipv4_tos & 0x000000fc;
3928						}
3929					}
3930#endif
3931#ifdef AF_INET6
3932					if (paddrp->spp_flags & SPP_IPV6_FLOWLABEL) {
3933						if (net->ro._l_addr.sin6.sin6_family == AF_INET6) {
3934							net->tos_flowlabel = paddrp->spp_ipv6_flowlabel;
3935						}
3936					}
3937#endif
3938				} else {
3939					/************************ASSOC ONLY -- NO NET SPECIFIC SET ******************/
3940					if (paddrp->spp_pathmaxrxt)
3941						stcb->asoc.def_net_failure = paddrp->spp_pathmaxrxt;
3942
3943					if (paddrp->spp_flags & SPP_HB_ENABLE) {
3944						/* Turn back on the timer */
3945						stcb->asoc.hb_is_disabled = 0;
3946						sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net);
3947					}
3948					if (paddrp->spp_flags & SPP_HB_DISABLE) {
3949						int cnt_of_unconf = 0;
3950						struct sctp_nets *lnet;
3951
3952						stcb->asoc.hb_is_disabled = 1;
3953						TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) {
3954							if (lnet->dest_state & SCTP_ADDR_UNCONFIRMED) {
3955								cnt_of_unconf++;
3956							}
3957						}
3958						/*
3959						 * stop the timer ONLY if we
3960						 * have no unconfirmed
3961						 * addresses
3962						 */
3963						if (cnt_of_unconf == 0) {
3964							sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net);
3965						}
3966					}
3967					if (paddrp->spp_flags & SPP_HB_ENABLE) {
3968						/* start up the timer. */
3969						sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net);
3970					}
3971#ifdef AF_INET
3972					if (paddrp->spp_flags & SPP_IPV4_TOS)
3973						stcb->asoc.default_tos = paddrp->spp_ipv4_tos & 0x000000fc;
3974#endif
3975#ifdef AF_INET6
3976					if (paddrp->spp_flags & SPP_IPV6_FLOWLABEL)
3977						stcb->asoc.default_flowlabel = paddrp->spp_ipv6_flowlabel;
3978#endif
3979
3980				}
3981				SCTP_TCB_UNLOCK(stcb);
3982			} else {
3983				/************************NO TCB, SET TO default stuff ******************/
3984				SCTP_INP_WLOCK(inp);
3985				/*
3986				 * For the TOS/FLOWLABEL stuff you set it
3987				 * with the options on the socket
3988				 */
3989				if (paddrp->spp_pathmaxrxt) {
3990					inp->sctp_ep.def_net_failure = paddrp->spp_pathmaxrxt;
3991				}
3992				if (paddrp->spp_flags & SPP_HB_ENABLE) {
3993					inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = MSEC_TO_TICKS(paddrp->spp_hbinterval);
3994					sctp_feature_off(inp, SCTP_PCB_FLAGS_DONOT_HEARTBEAT);
3995				} else if (paddrp->spp_flags & SPP_HB_DISABLE) {
3996					sctp_feature_on(inp, SCTP_PCB_FLAGS_DONOT_HEARTBEAT);
3997				}
3998				if (paddrp->spp_flags & SPP_SACKDELAY_ENABLE) {
3999					if (paddrp->spp_sackdelay > SCTP_CLOCK_GRANULARITY)
4000						inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV] = MSEC_TO_TICKS(paddrp->spp_sackdelay);
4001					else
4002						inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV] = MSEC_TO_TICKS(SCTP_CLOCK_GRANULARITY);
4003
4004				} else if (paddrp->spp_flags & SPP_SACKDELAY_DISABLE) {
4005					inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV] = 0;
4006				}
4007				SCTP_INP_WUNLOCK(inp);
4008			}
4009		}
4010		break;
4011	case SCTP_RTOINFO:
4012		{
4013			struct sctp_rtoinfo *srto;
4014
4015			if ((size_t)m->m_len < sizeof(struct sctp_rtoinfo)) {
4016				error = EINVAL;
4017				break;
4018			}
4019			srto = mtod(m, struct sctp_rtoinfo *);
4020			if (srto->srto_assoc_id == 0) {
4021				SCTP_INP_WLOCK(inp);
4022				/*
4023				 * If we have a null asoc, its default for
4024				 * the endpoint
4025				 */
4026				if (srto->srto_initial > 10)
4027					inp->sctp_ep.initial_rto = srto->srto_initial;
4028				if (srto->srto_max > 10)
4029					inp->sctp_ep.sctp_maxrto = srto->srto_max;
4030				if (srto->srto_min > 10)
4031					inp->sctp_ep.sctp_minrto = srto->srto_min;
4032				SCTP_INP_WUNLOCK(inp);
4033				break;
4034			}
4035			if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
4036				SCTP_INP_RLOCK(inp);
4037				stcb = LIST_FIRST(&inp->sctp_asoc_list);
4038				if (stcb)
4039					SCTP_TCB_LOCK(stcb);
4040				SCTP_INP_RUNLOCK(inp);
4041			} else
4042				stcb = sctp_findassociation_ep_asocid(inp, srto->srto_assoc_id, 1);
4043			if (stcb == NULL) {
4044				error = EINVAL;
4045				break;
4046			}
4047			/* Set in ms we hope :-) */
4048			if (srto->srto_initial > 10)
4049				stcb->asoc.initial_rto = srto->srto_initial;
4050			if (srto->srto_max > 10)
4051				stcb->asoc.maxrto = srto->srto_max;
4052			if (srto->srto_min > 10)
4053				stcb->asoc.minrto = srto->srto_min;
4054			SCTP_TCB_UNLOCK(stcb);
4055		}
4056		break;
4057	case SCTP_ASSOCINFO:
4058		{
4059			struct sctp_assocparams *sasoc;
4060
4061			if ((size_t)m->m_len < sizeof(struct sctp_assocparams)) {
4062				error = EINVAL;
4063				break;
4064			}
4065			sasoc = mtod(m, struct sctp_assocparams *);
4066			if (sasoc->sasoc_assoc_id) {
4067				if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
4068					SCTP_INP_RLOCK(inp);
4069					stcb = LIST_FIRST(&inp->sctp_asoc_list);
4070					if (stcb)
4071						SCTP_TCB_LOCK(stcb);
4072					SCTP_INP_RUNLOCK(inp);
4073				} else
4074					stcb = sctp_findassociation_ep_asocid(inp,
4075					    sasoc->sasoc_assoc_id, 1);
4076				if (stcb == NULL) {
4077					error = ENOENT;
4078					break;
4079				}
4080			} else {
4081				stcb = NULL;
4082			}
4083			if (stcb) {
4084				if (sasoc->sasoc_asocmaxrxt)
4085					stcb->asoc.max_send_times = sasoc->sasoc_asocmaxrxt;
4086				sasoc->sasoc_number_peer_destinations = stcb->asoc.numnets;
4087				sasoc->sasoc_peer_rwnd = 0;
4088				sasoc->sasoc_local_rwnd = 0;
4089				if (stcb->asoc.cookie_life)
4090					stcb->asoc.cookie_life = sasoc->sasoc_cookie_life;
4091				SCTP_TCB_UNLOCK(stcb);
4092			} else {
4093				SCTP_INP_WLOCK(inp);
4094				if (sasoc->sasoc_asocmaxrxt)
4095					inp->sctp_ep.max_send_times = sasoc->sasoc_asocmaxrxt;
4096				sasoc->sasoc_number_peer_destinations = 0;
4097				sasoc->sasoc_peer_rwnd = 0;
4098				sasoc->sasoc_local_rwnd = 0;
4099				if (sasoc->sasoc_cookie_life)
4100					inp->sctp_ep.def_cookie_life = sasoc->sasoc_cookie_life;
4101				SCTP_INP_WUNLOCK(inp);
4102			}
4103		}
4104		break;
4105	case SCTP_INITMSG:
4106		{
4107			struct sctp_initmsg *sinit;
4108
4109			if ((size_t)m->m_len < sizeof(struct sctp_initmsg)) {
4110				error = EINVAL;
4111				break;
4112			}
4113			sinit = mtod(m, struct sctp_initmsg *);
4114			SCTP_INP_WLOCK(inp);
4115			if (sinit->sinit_num_ostreams)
4116				inp->sctp_ep.pre_open_stream_count = sinit->sinit_num_ostreams;
4117
4118			if (sinit->sinit_max_instreams)
4119				inp->sctp_ep.max_open_streams_intome = sinit->sinit_max_instreams;
4120
4121			if (sinit->sinit_max_attempts)
4122				inp->sctp_ep.max_init_times = sinit->sinit_max_attempts;
4123
4124			if (sinit->sinit_max_init_timeo > 10)
4125				/*
4126				 * We must be at least a 100ms (we set in
4127				 * ticks)
4128				 */
4129				inp->sctp_ep.initial_init_rto_max = sinit->sinit_max_init_timeo;
4130			SCTP_INP_WUNLOCK(inp);
4131		}
4132		break;
4133	case SCTP_PRIMARY_ADDR:
4134		{
4135			struct sctp_setprim *spa;
4136			struct sctp_nets *net, *lnet;
4137
4138			if ((size_t)m->m_len < sizeof(struct sctp_setprim)) {
4139				error = EINVAL;
4140				break;
4141			}
4142			spa = mtod(m, struct sctp_setprim *);
4143
4144			if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
4145				SCTP_INP_RLOCK(inp);
4146				stcb = LIST_FIRST(&inp->sctp_asoc_list);
4147				if (stcb) {
4148					SCTP_TCB_LOCK(stcb);
4149				} else {
4150					error = EINVAL;
4151					break;
4152				}
4153				SCTP_INP_RUNLOCK(inp);
4154			} else
4155				stcb = sctp_findassociation_ep_asocid(inp, spa->ssp_assoc_id, 1);
4156			if (stcb == NULL) {
4157				/* One last shot */
4158				SCTP_INP_INCR_REF(inp);
4159				stcb = sctp_findassociation_ep_addr(&inp,
4160				    (struct sockaddr *)&spa->ssp_addr,
4161				    &net, NULL, NULL);
4162				if (stcb == NULL) {
4163					SCTP_INP_DECR_REF(inp);
4164					error = EINVAL;
4165					break;
4166				}
4167			} else {
4168				/*
4169				 * find the net, associd or connected lookup
4170				 * type
4171				 */
4172				net = sctp_findnet(stcb, (struct sockaddr *)&spa->ssp_addr);
4173				if (net == NULL) {
4174					SCTP_TCB_UNLOCK(stcb);
4175					error = EINVAL;
4176					break;
4177				}
4178			}
4179			if ((net != stcb->asoc.primary_destination) &&
4180			    (!(net->dest_state & SCTP_ADDR_UNCONFIRMED))) {
4181				/* Ok we need to set it */
4182				lnet = stcb->asoc.primary_destination;
4183				if (sctp_set_primary_addr(stcb,
4184				    (struct sockaddr *)NULL,
4185				    net) == 0) {
4186					if (net->dest_state & SCTP_ADDR_SWITCH_PRIMARY) {
4187						net->dest_state |= SCTP_ADDR_DOUBLE_SWITCH;
4188					}
4189					net->dest_state |= SCTP_ADDR_SWITCH_PRIMARY;
4190				}
4191			}
4192			SCTP_TCB_UNLOCK(stcb);
4193		}
4194		break;
4195
4196	case SCTP_SET_PEER_PRIMARY_ADDR:
4197		{
4198			struct sctp_setpeerprim *sspp;
4199
4200			if ((size_t)m->m_len < sizeof(struct sctp_setpeerprim)) {
4201				error = EINVAL;
4202				break;
4203			}
4204			sspp = mtod(m, struct sctp_setpeerprim *);
4205
4206
4207			if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
4208				SCTP_INP_RLOCK(inp);
4209				stcb = LIST_FIRST(&inp->sctp_asoc_list);
4210				if (stcb)
4211					SCTP_TCB_UNLOCK(stcb);
4212				SCTP_INP_RUNLOCK(inp);
4213			} else
4214				stcb = sctp_findassociation_ep_asocid(inp, sspp->sspp_assoc_id, 1);
4215			if (stcb == NULL) {
4216				error = EINVAL;
4217				break;
4218			}
4219			if (sctp_set_primary_ip_address_sa(stcb, (struct sockaddr *)&sspp->sspp_addr) != 0) {
4220				error = EINVAL;
4221			}
4222			SCTP_TCB_UNLOCK(stcb);
4223		}
4224		break;
4225	case SCTP_BINDX_ADD_ADDR:
4226		{
4227			struct sctp_getaddresses *addrs;
4228			struct sockaddr *addr_touse;
4229			struct sockaddr_in sin;
4230
4231			/* see if we're bound all already! */
4232			if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
4233				error = EINVAL;
4234				break;
4235			}
4236			if ((size_t)m->m_len < sizeof(struct sctp_getaddresses)) {
4237				error = EINVAL;
4238				break;
4239			}
4240			addrs = mtod(m, struct sctp_getaddresses *);
4241			addr_touse = addrs->addr;
4242			if (addrs->addr->sa_family == AF_INET6) {
4243				struct sockaddr_in6 *sin6;
4244
4245				sin6 = (struct sockaddr_in6 *)addr_touse;
4246				if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
4247					in6_sin6_2_sin(&sin, sin6);
4248					addr_touse = (struct sockaddr *)&sin;
4249				}
4250			}
4251			if (inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) {
4252				if (p == NULL) {
4253					/* Can't get proc for Net/Open BSD */
4254					error = EINVAL;
4255					break;
4256				}
4257				error = sctp_inpcb_bind(so, addr_touse, p);
4258				break;
4259			}
4260			/*
4261			 * No locks required here since bind and mgmt_ep_sa
4262			 * all do their own locking. If we do something for
4263			 * the FIX: below we may need to lock in that case.
4264			 */
4265			if (addrs->sget_assoc_id == 0) {
4266				/* add the address */
4267				struct sctp_inpcb *lep;
4268
4269				((struct sockaddr_in *)addr_touse)->sin_port = inp->sctp_lport;
4270				lep = sctp_pcb_findep(addr_touse, 1, 0);
4271				if (lep != NULL) {
4272					/*
4273					 * We must decrement the refcount
4274					 * since we have the ep already and
4275					 * are binding. No remove going on
4276					 * here.
4277					 */
4278					SCTP_INP_DECR_REF(inp);
4279				}
4280				if (lep == inp) {
4281					/* already bound to it.. ok */
4282					break;
4283				} else if (lep == NULL) {
4284					((struct sockaddr_in *)addr_touse)->sin_port = 0;
4285					error = sctp_addr_mgmt_ep_sa(inp, addr_touse,
4286					    SCTP_ADD_IP_ADDRESS);
4287				} else {
4288					error = EADDRNOTAVAIL;
4289				}
4290				if (error)
4291					break;
4292
4293			} else {
4294				/*
4295				 * FIX: decide whether we allow assoc based
4296				 * bindx
4297				 */
4298			}
4299		}
4300		break;
4301	case SCTP_BINDX_REM_ADDR:
4302		{
4303			struct sctp_getaddresses *addrs;
4304			struct sockaddr *addr_touse;
4305			struct sockaddr_in sin;
4306
4307			/* see if we're bound all already! */
4308			if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
4309				error = EINVAL;
4310				break;
4311			}
4312			if ((size_t)m->m_len < sizeof(struct sctp_getaddresses)) {
4313				error = EINVAL;
4314				break;
4315			}
4316			addrs = mtod(m, struct sctp_getaddresses *);
4317			addr_touse = addrs->addr;
4318			if (addrs->addr->sa_family == AF_INET6) {
4319				struct sockaddr_in6 *sin6;
4320
4321				sin6 = (struct sockaddr_in6 *)addr_touse;
4322				if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
4323					in6_sin6_2_sin(&sin, sin6);
4324					addr_touse = (struct sockaddr *)&sin;
4325				}
4326			}
4327			/*
4328			 * No lock required mgmt_ep_sa does its own locking.
4329			 * If the FIX: below is ever changed we may need to
4330			 * lock before calling association level binding.
4331			 */
4332			if (addrs->sget_assoc_id == 0) {
4333				/* delete the address */
4334				sctp_addr_mgmt_ep_sa(inp, addr_touse,
4335				    SCTP_DEL_IP_ADDRESS);
4336			} else {
4337				/*
4338				 * FIX: decide whether we allow assoc based
4339				 * bindx
4340				 */
4341			}
4342		}
4343		break;
4344	default:
4345		error = ENOPROTOOPT;
4346		break;
4347	}			/* end switch (opt) */
4348	return (error);
4349}
4350
4351
4352
4353extern int sctp_chatty_mbuf;
4354
4355int
4356sctp_ctloutput(struct socket *so, struct sockopt *sopt)
4357{
4358	struct mbuf *m = NULL;
4359	struct sctp_inpcb *inp;
4360	int s, error;
4361
4362	inp = (struct sctp_inpcb *)so->so_pcb;
4363	s = splnet();
4364	if (inp == 0) {
4365		splx(s);
4366		/* I made the same as TCP since we are not setup? */
4367		return (ECONNRESET);
4368	}
4369	if (sopt->sopt_level != IPPROTO_SCTP) {
4370		/* wrong proto level... send back up to IP */
4371#ifdef INET6
4372		if (INP_CHECK_SOCKAF(so, AF_INET6))
4373			error = ip6_ctloutput(so, sopt);
4374		else
4375#endif				/* INET6 */
4376			error = ip_ctloutput(so, sopt);
4377		splx(s);
4378		return (error);
4379	}
4380	if (sopt->sopt_valsize) {
4381		if (sopt->sopt_valsize < MLEN) {
4382			m = sctp_get_mbuf_for_msg(1, 0, M_WAIT, 1, MT_DATA);
4383		} else {
4384			m = sctp_get_mbuf_for_msg(sopt->sopt_valsize, 0, M_WAIT, 1, MT_DATA);
4385		}
4386		if (m == NULL) {
4387			sctp_m_freem(m);
4388			splx(s);
4389			return (ENOBUFS);
4390		}
4391		if (sopt->sopt_valsize > M_TRAILINGSPACE(m)) {
4392			/* Limit to actual size gotten */
4393			sopt->sopt_valsize = M_TRAILINGSPACE(m);
4394		}
4395		error = sooptcopyin(sopt, mtod(m, caddr_t), sopt->sopt_valsize,
4396		    sopt->sopt_valsize);
4397		if (error) {
4398			(void)sctp_m_free(m);
4399			goto out;
4400		}
4401		m->m_len = sopt->sopt_valsize;
4402	}
4403	if (sopt->sopt_dir == SOPT_SET) {
4404		error = sctp_optsset(so, sopt->sopt_name, &m, sopt->sopt_td);
4405	} else if (sopt->sopt_dir == SOPT_GET) {
4406		error = sctp_optsget(so, sopt->sopt_name, &m, sopt->sopt_td);
4407	} else {
4408		error = EINVAL;
4409	}
4410	if ((error == 0) && (m != NULL)) {
4411		error = sooptcopyout(sopt, mtod(m, caddr_t), m->m_len);
4412		sctp_m_freem(m);
4413	} else if (m != NULL) {
4414		sctp_m_freem(m);
4415	}
4416out:
4417	splx(s);
4418	return (error);
4419}
4420
4421
4422static int
4423sctp_connect(struct socket *so, struct sockaddr *addr, struct thread *p)
4424{
4425	int s = splnet();
4426
4427	int error = 0;
4428	int create_lock_on = 0;
4429	struct sctp_inpcb *inp;
4430	struct sctp_tcb *stcb = NULL;
4431
4432	inp = (struct sctp_inpcb *)so->so_pcb;
4433	if (inp == 0) {
4434		splx(s);
4435		/* I made the same as TCP since we are not setup? */
4436		return (ECONNRESET);
4437	}
4438	SCTP_ASOC_CREATE_LOCK(inp);
4439	create_lock_on = 1;
4440
4441	SCTP_INP_INCR_REF(inp);
4442	if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
4443	    (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) {
4444		/* Should I really unlock ? */
4445		error = EFAULT;
4446		goto out_now;
4447	}
4448#ifdef INET6
4449	if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) &&
4450	    (addr->sa_family == AF_INET6)) {
4451		error = EINVAL;
4452		goto out_now;
4453	}
4454#endif				/* INET6 */
4455	if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) ==
4456	    SCTP_PCB_FLAGS_UNBOUND) {
4457		/* Bind a ephemeral port */
4458		error = sctp_inpcb_bind(so, NULL, p);
4459		if (error) {
4460			goto out_now;
4461		}
4462	}
4463	/* Now do we connect? */
4464	if (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) {
4465		error = EINVAL;
4466		goto out_now;
4467	}
4468	if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
4469	    (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) {
4470		/* We are already connected AND the TCP model */
4471		error = EADDRINUSE;
4472		goto out_now;
4473	}
4474	if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
4475		SCTP_INP_RLOCK(inp);
4476		stcb = LIST_FIRST(&inp->sctp_asoc_list);
4477		if (stcb)
4478			SCTP_TCB_UNLOCK(stcb);
4479		SCTP_INP_RUNLOCK(inp);
4480	} else {
4481		/*
4482		 * Raise the count a second time, since on sucess
4483		 * f-a-ep_addr will decrement it.
4484		 */
4485		SCTP_INP_INCR_REF(inp);
4486		stcb = sctp_findassociation_ep_addr(&inp, addr, NULL, NULL, NULL);
4487		if (stcb == NULL) {
4488			SCTP_INP_DECR_REF(inp);
4489		}
4490	}
4491	if (stcb != NULL) {
4492		/* Already have or am bring up an association */
4493		error = EALREADY;
4494		goto out_now;
4495	}
4496	/* We are GOOD to go */
4497	stcb = sctp_aloc_assoc(inp, addr, 1, &error, 0);
4498	if (stcb == NULL) {
4499		/* Gak! no memory */
4500		splx(s);
4501		return (error);
4502	}
4503	if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) {
4504		stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED;
4505		/* Set the connected flag so we can queue data */
4506		soisconnecting(so);
4507	}
4508	stcb->asoc.state = SCTP_STATE_COOKIE_WAIT;
4509	SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered);
4510
4511	/* initialize authentication parameters for the assoc */
4512	sctp_initialize_auth_params(inp, stcb);
4513
4514	sctp_send_initiate(inp, stcb);
4515out_now:
4516	if (create_lock_on)
4517		SCTP_ASOC_CREATE_UNLOCK(inp);
4518
4519	if (stcb)
4520		SCTP_TCB_UNLOCK(stcb);
4521	SCTP_INP_DECR_REF(inp);
4522	splx(s);
4523	return error;
4524}
4525
4526int
4527sctp_listen(struct socket *so, int backlog, struct thread *p)
4528{
4529	/*
4530	 * Note this module depends on the protocol processing being called
4531	 * AFTER any socket level flags and backlog are applied to the
4532	 * socket. The traditional way that the socket flags are applied is
4533	 * AFTER protocol processing. We have made a change to the
4534	 * sys/kern/uipc_socket.c module to reverse this but this MUST be in
4535	 * place if the socket API for SCTP is to work properly.
4536	 */
4537	int s = splnet();
4538
4539	int error = 0;
4540	struct sctp_inpcb *inp;
4541
4542	inp = (struct sctp_inpcb *)so->so_pcb;
4543	if (inp == 0) {
4544		splx(s);
4545		/* I made the same as TCP since we are not setup? */
4546		return (ECONNRESET);
4547	}
4548	SCTP_INP_RLOCK(inp);
4549#ifdef SCTP_LOCK_LOGGING
4550	sctp_log_lock(inp, (struct sctp_tcb *)NULL, SCTP_LOG_LOCK_SOCK);
4551#endif
4552	SOCK_LOCK(so);
4553	error = solisten_proto_check(so);
4554	if (error) {
4555		SOCK_UNLOCK(so);
4556		return (error);
4557	}
4558	if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
4559	    (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) {
4560		/* We are already connected AND the TCP model */
4561		splx(s);
4562		SCTP_INP_RUNLOCK(inp);
4563		SOCK_UNLOCK(so);
4564		return (EADDRINUSE);
4565	}
4566	if (inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) {
4567		/* We must do a bind. */
4568		SCTP_INP_RUNLOCK(inp);
4569		if ((error = sctp_inpcb_bind(so, NULL, p))) {
4570			/* bind error, probably perm */
4571			SOCK_UNLOCK(so);
4572			splx(s);
4573			return (error);
4574		}
4575	} else {
4576		SCTP_INP_RUNLOCK(inp);
4577	}
4578	/* It appears for 7.0 and on, we must always call this. */
4579	solisten_proto(so, backlog);
4580
4581	if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) {
4582		/* remove the ACCEPTCONN flag for one-to-many sockets */
4583		so->so_options &= ~SO_ACCEPTCONN;
4584	}
4585	if (backlog == 0) {
4586		/* turning off listen */
4587		so->so_options &= ~SO_ACCEPTCONN;
4588	}
4589	SOCK_UNLOCK(so);
4590	splx(s);
4591	return (error);
4592}
4593
4594static int sctp_defered_wakeup_cnt = 0;
4595
4596int
4597sctp_accept(struct socket *so, struct sockaddr **addr)
4598{
4599	int s = splnet();
4600
4601	struct sctp_tcb *stcb;
4602	struct sctp_inpcb *inp;
4603	union sctp_sockstore store;
4604
4605	int error;
4606
4607
4608	inp = (struct sctp_inpcb *)so->so_pcb;
4609
4610	if (inp == 0) {
4611		splx(s);
4612		return (ECONNRESET);
4613	}
4614	SCTP_INP_RLOCK(inp);
4615	if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) {
4616		return (ENOTSUP);
4617	}
4618	if (so->so_state & SS_ISDISCONNECTED) {
4619		splx(s);
4620		SCTP_INP_RUNLOCK(inp);
4621		return (ECONNABORTED);
4622	}
4623	stcb = LIST_FIRST(&inp->sctp_asoc_list);
4624	if (stcb == NULL) {
4625		splx(s);
4626		SCTP_INP_RUNLOCK(inp);
4627		return (ECONNRESET);
4628	}
4629	SCTP_TCB_LOCK(stcb);
4630	SCTP_INP_RUNLOCK(inp);
4631	store = stcb->asoc.primary_destination->ro._l_addr;
4632	SCTP_TCB_UNLOCK(stcb);
4633	if (store.sa.sa_family == AF_INET) {
4634		struct sockaddr_in *sin;
4635
4636		SCTP_MALLOC_SONAME(sin, struct sockaddr_in *, sizeof *sin);
4637		sin->sin_family = AF_INET;
4638		sin->sin_len = sizeof(*sin);
4639		sin->sin_port = ((struct sockaddr_in *)&store)->sin_port;
4640		sin->sin_addr = ((struct sockaddr_in *)&store)->sin_addr;
4641		*addr = (struct sockaddr *)sin;
4642	} else {
4643		struct sockaddr_in6 *sin6;
4644
4645		SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof *sin6);
4646		sin6->sin6_family = AF_INET6;
4647		sin6->sin6_len = sizeof(*sin6);
4648		sin6->sin6_port = ((struct sockaddr_in6 *)&store)->sin6_port;
4649
4650		sin6->sin6_addr = ((struct sockaddr_in6 *)&store)->sin6_addr;
4651		if ((error = sa6_recoverscope(sin6)) != 0)
4652			return (error);
4653		*addr = (struct sockaddr *)sin6;
4654	}
4655	/* Wake any delayed sleep action */
4656	if (inp->sctp_flags & SCTP_PCB_FLAGS_DONT_WAKE) {
4657		inp->sctp_flags &= ~SCTP_PCB_FLAGS_DONT_WAKE;
4658		if (inp->sctp_flags & SCTP_PCB_FLAGS_WAKEOUTPUT) {
4659			inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEOUTPUT;
4660			SOCKBUF_LOCK(&inp->sctp_socket->so_snd);
4661			if (sowriteable(inp->sctp_socket)) {
4662				sowwakeup_locked(inp->sctp_socket);
4663			} else {
4664				SOCKBUF_UNLOCK(&inp->sctp_socket->so_snd);
4665			}
4666		}
4667		if (inp->sctp_flags & SCTP_PCB_FLAGS_WAKEINPUT) {
4668			inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEINPUT;
4669			SOCKBUF_LOCK(&inp->sctp_socket->so_rcv);
4670			if (soreadable(inp->sctp_socket)) {
4671				sctp_defered_wakeup_cnt++;
4672				sorwakeup_locked(inp->sctp_socket);
4673			} else {
4674				SOCKBUF_UNLOCK(&inp->sctp_socket->so_rcv);
4675			}
4676		}
4677	}
4678	splx(s);
4679	return (0);
4680}
4681
4682int
4683sctp_ingetaddr(struct socket *so, struct sockaddr **addr)
4684{
4685	struct sockaddr_in *sin;
4686
4687	int s;
4688	struct sctp_inpcb *inp;
4689
4690	/*
4691	 * Do the malloc first in case it blocks.
4692	 */
4693	SCTP_MALLOC_SONAME(sin, struct sockaddr_in *, sizeof *sin);
4694	sin->sin_family = AF_INET;
4695	sin->sin_len = sizeof(*sin);
4696	s = splnet();
4697	inp = (struct sctp_inpcb *)so->so_pcb;
4698	if (!inp) {
4699		splx(s);
4700		SCTP_FREE_SONAME(sin);
4701		return ECONNRESET;
4702	}
4703	SCTP_INP_RLOCK(inp);
4704	sin->sin_port = inp->sctp_lport;
4705	if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
4706		if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
4707			struct sctp_tcb *stcb;
4708			struct sockaddr_in *sin_a;
4709			struct sctp_nets *net;
4710			int fnd;
4711
4712			stcb = LIST_FIRST(&inp->sctp_asoc_list);
4713			if (stcb == NULL) {
4714				goto notConn;
4715			}
4716			fnd = 0;
4717			sin_a = NULL;
4718			SCTP_TCB_LOCK(stcb);
4719			TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
4720				sin_a = (struct sockaddr_in *)&net->ro._l_addr;
4721				if (sin_a->sin_family == AF_INET) {
4722					fnd = 1;
4723					break;
4724				}
4725			}
4726			if ((!fnd) || (sin_a == NULL)) {
4727				/* punt */
4728				SCTP_TCB_UNLOCK(stcb);
4729				goto notConn;
4730			}
4731			sin->sin_addr = sctp_ipv4_source_address_selection(inp,
4732			    stcb, (struct route *)&net->ro, net, 0);
4733			SCTP_TCB_UNLOCK(stcb);
4734		} else {
4735			/* For the bound all case you get back 0 */
4736	notConn:
4737			sin->sin_addr.s_addr = 0;
4738		}
4739
4740	} else {
4741		/* Take the first IPv4 address in the list */
4742		struct sctp_laddr *laddr;
4743		int fnd = 0;
4744
4745		LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
4746			if (laddr->ifa->ifa_addr->sa_family == AF_INET) {
4747				struct sockaddr_in *sin_a;
4748
4749				sin_a = (struct sockaddr_in *)laddr->ifa->ifa_addr;
4750				sin->sin_addr = sin_a->sin_addr;
4751				fnd = 1;
4752				break;
4753			}
4754		}
4755		if (!fnd) {
4756			splx(s);
4757			SCTP_FREE_SONAME(sin);
4758			SCTP_INP_RUNLOCK(inp);
4759			return ENOENT;
4760		}
4761	}
4762	SCTP_INP_RUNLOCK(inp);
4763	splx(s);
4764	(*addr) = (struct sockaddr *)sin;
4765	return (0);
4766}
4767
4768int
4769sctp_peeraddr(struct socket *so, struct sockaddr **addr)
4770{
4771	struct sockaddr_in *sin = (struct sockaddr_in *)*addr;
4772
4773	int s, fnd;
4774	struct sockaddr_in *sin_a;
4775	struct sctp_inpcb *inp;
4776	struct sctp_tcb *stcb;
4777	struct sctp_nets *net;
4778
4779
4780	/* Do the malloc first in case it blocks. */
4781	inp = (struct sctp_inpcb *)so->so_pcb;
4782	if ((inp == NULL) ||
4783	    ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)) {
4784		/* UDP type and listeners will drop out here */
4785		return (ENOTCONN);
4786	}
4787	s = splnet();
4788
4789	SCTP_MALLOC_SONAME(sin, struct sockaddr_in *, sizeof *sin);
4790	sin->sin_family = AF_INET;
4791	sin->sin_len = sizeof(*sin);
4792
4793	/* We must recapture incase we blocked */
4794	inp = (struct sctp_inpcb *)so->so_pcb;
4795	if (!inp) {
4796		splx(s);
4797		SCTP_FREE_SONAME(sin);
4798		return ECONNRESET;
4799	}
4800	SCTP_INP_RLOCK(inp);
4801	stcb = LIST_FIRST(&inp->sctp_asoc_list);
4802	if (stcb)
4803		SCTP_TCB_LOCK(stcb);
4804	SCTP_INP_RUNLOCK(inp);
4805	if (stcb == NULL) {
4806		splx(s);
4807		SCTP_FREE_SONAME(sin);
4808		return ECONNRESET;
4809	}
4810	fnd = 0;
4811	TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
4812		sin_a = (struct sockaddr_in *)&net->ro._l_addr;
4813		if (sin_a->sin_family == AF_INET) {
4814			fnd = 1;
4815			sin->sin_port = stcb->rport;
4816			sin->sin_addr = sin_a->sin_addr;
4817			break;
4818		}
4819	}
4820	SCTP_TCB_UNLOCK(stcb);
4821	if (!fnd) {
4822		/* No IPv4 address */
4823		splx(s);
4824		SCTP_FREE_SONAME(sin);
4825		return ENOENT;
4826	}
4827	splx(s);
4828	(*addr) = (struct sockaddr *)sin;
4829	return (0);
4830}
4831
4832struct pr_usrreqs sctp_usrreqs = {
4833	.pru_abort = sctp_abort,
4834	.pru_accept = sctp_accept,
4835	.pru_attach = sctp_attach,
4836	.pru_bind = sctp_bind,
4837	.pru_connect = sctp_connect,
4838	.pru_control = in_control,
4839	.pru_close = sctp_close,
4840	.pru_detach = sctp_close,
4841	.pru_sopoll = sopoll_generic,
4842	.pru_disconnect = sctp_disconnect,
4843	.pru_listen = sctp_listen,
4844	.pru_peeraddr = sctp_peeraddr,
4845	.pru_send = sctp_sendm,
4846	.pru_shutdown = sctp_shutdown,
4847	.pru_sockaddr = sctp_ingetaddr,
4848	.pru_sosend = sctp_sosend,
4849	.pru_soreceive = sctp_soreceive
4850};
4851