]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/netinet/sctp_usrreq.c
More 64 bit pointer fun.
[FreeBSD/FreeBSD.git] / sys / netinet / sctp_usrreq.c
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$");
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  */
104 int sctp_sendspace = (128 * 1024);
105 int sctp_recvspace = 128 * (1024 +
106 #ifdef INET6
107     sizeof(struct sockaddr_in6)
108 #else
109     sizeof(struct sockaddr_in)
110 #endif
111 );
112 int sctp_mbuf_threshold_count = SCTP_DEFAULT_MBUFS_IN_CHAIN;
113 int sctp_auto_asconf = SCTP_DEFAULT_AUTO_ASCONF;
114 int sctp_ecn_enable = 1;
115 int sctp_ecn_nonce = 0;
116 int sctp_strict_sacks = 0;
117 int sctp_no_csum_on_loopback = 1;
118 int sctp_strict_init = 1;
119 int sctp_abort_if_one_2_one_hits_limit = 0;
120 int sctp_strict_data_order = 0;
121
122 int sctp_peer_chunk_oh = sizeof(struct mbuf);
123 int sctp_max_burst_default = SCTP_DEF_MAX_BURST;
124 int sctp_use_cwnd_based_maxburst = 1;
125 int sctp_do_drain = 1;
126 int sctp_warm_the_crc32_table = 0;
127
128 unsigned int sctp_max_chunks_on_queue = SCTP_ASOC_MAX_CHUNKS_ON_QUEUE;
129 unsigned int sctp_delayed_sack_time_default = SCTP_RECV_MSEC;
130 unsigned int sctp_heartbeat_interval_default = SCTP_HB_DEFAULT_MSEC;
131 unsigned int sctp_pmtu_raise_time_default = SCTP_DEF_PMTU_RAISE_SEC;
132 unsigned int sctp_shutdown_guard_time_default = SCTP_DEF_MAX_SHUTDOWN_SEC;
133 unsigned int sctp_secret_lifetime_default = SCTP_DEFAULT_SECRET_LIFE_SEC;
134 unsigned int sctp_rto_max_default = SCTP_RTO_UPPER_BOUND;
135 unsigned int sctp_rto_min_default = SCTP_RTO_LOWER_BOUND;
136 unsigned int sctp_rto_initial_default = SCTP_RTO_INITIAL;
137 unsigned int sctp_init_rto_max_default = SCTP_RTO_UPPER_BOUND;
138 unsigned int sctp_valid_cookie_life_default = SCTP_DEFAULT_COOKIE_LIFE;
139 unsigned int sctp_init_rtx_max_default = SCTP_DEF_MAX_INIT;
140 unsigned int sctp_assoc_rtx_max_default = SCTP_DEF_MAX_SEND;
141 unsigned int sctp_path_rtx_max_default = SCTP_DEF_MAX_PATH_RTX;
142 unsigned int sctp_nr_outgoing_streams_default = SCTP_OSTREAM_INITIAL;
143 unsigned int sctp_add_more_threshold = SCTP_DEFAULT_ADD_MORE;
144
145 uint32_t sctp_asoc_free_resc_limit = SCTP_DEF_ASOC_RESC_LIMIT;
146 uint32_t sctp_system_free_resc_limit = SCTP_DEF_SYSTEM_RESC_LIMIT;
147
148 int sctp_min_split_point = SCTP_DEFAULT_SPLIT_POINT_MIN;
149 int sctp_pcbtblsize = SCTP_PCBHASHSIZE;
150 int sctp_hashtblsize = SCTP_TCBHASHSIZE;
151 int sctp_chunkscale = SCTP_CHUNKQUEUE_SCALE;
152
153 unsigned int sctp_cmt_on_off = 0;
154 unsigned int sctp_cmt_sockopt_on_off = 0;
155 unsigned int sctp_cmt_use_dac = 0;
156 unsigned int sctp_cmt_sockopt_use_dac = 0;
157
158 int sctp_L2_abc_variable = 1;
159 unsigned int sctp_early_fr = 0;
160 unsigned int sctp_early_fr_msec = SCTP_MINFR_MSEC_TIMER;
161 unsigned int sctp_use_rttvar_cc = 0;
162 int sctp_says_check_for_deadlock = 0;
163 unsigned int sctp_asconf_auth_nochk = 0;
164 unsigned int sctp_auth_disable = 0;
165 unsigned int sctp_auth_random_len = SCTP_AUTH_RANDOM_SIZE_DEFAULT;
166 unsigned int sctp_auth_hmac_id_default = SCTP_AUTH_HMAC_ID_SHA1;
167 struct sctpstat sctpstat;
168
169 #ifdef SCTP_DEBUG
170 extern uint32_t sctp_debug_on;
171
172 #endif                          /* SCTP_DEBUG */
173
174
175 void
176 sctp_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
204 void
205 ip_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
222 static void
223 sctp_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
268 static void
269 sctp_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
334 void
335 sctp_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
408 void
409 sctp_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
482 static int
483 sctp_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);
514 out:
515         splx(s);
516         return (error);
517 }
518
519 SYSCTL_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
527 SYSCTL_INT(_net_inet_sctp, OID_AUTO, sendspace, CTLFLAG_RW,
528     &sctp_sendspace, 0, "Maximum outgoing SCTP buffer size");
529
530 SYSCTL_INT(_net_inet_sctp, OID_AUTO, recvspace, CTLFLAG_RW,
531     &sctp_recvspace, 0, "Maximum incoming SCTP buffer size");
532
533 SYSCTL_INT(_net_inet_sctp, OID_AUTO, auto_asconf, CTLFLAG_RW,
534     &sctp_auto_asconf, 0, "Enable SCTP Auto-ASCONF");
535
536 SYSCTL_INT(_net_inet_sctp, OID_AUTO, ecn_enable, CTLFLAG_RW,
537     &sctp_ecn_enable, 0, "Enable SCTP ECN");
538
539 SYSCTL_INT(_net_inet_sctp, OID_AUTO, ecn_nonce, CTLFLAG_RW,
540     &sctp_ecn_nonce, 0, "Enable SCTP ECN Nonce");
541
542 SYSCTL_INT(_net_inet_sctp, OID_AUTO, strict_sacks, CTLFLAG_RW,
543     &sctp_strict_sacks, 0, "Enable SCTP Strict SACK checking");
544
545 SYSCTL_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
549 SYSCTL_INT(_net_inet_sctp, OID_AUTO, strict_init, CTLFLAG_RW,
550     &sctp_strict_init, 0,
551     "Enable strict INIT/INIT-ACK singleton enforcement");
552
553 SYSCTL_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
557 SYSCTL_INT(_net_inet_sctp, OID_AUTO, maxburst, CTLFLAG_RW,
558     &sctp_max_burst_default, 0,
559     "Default max burst for sctp endpoints");
560
561 SYSCTL_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
565 SYSCTL_INT(_net_inet_sctp, OID_AUTO, tcbhashsize, CTLFLAG_RW,
566     &sctp_hashtblsize, 0,
567     "Tuneable for Hash table sizes");
568
569 SYSCTL_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
573 SYSCTL_INT(_net_inet_sctp, OID_AUTO, pcbhashsize, CTLFLAG_RW,
574     &sctp_pcbtblsize, 0,
575     "Tuneable for PCB Hash table sizes");
576
577 SYSCTL_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
581 SYSCTL_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
586 SYSCTL_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
591 SYSCTL_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
595 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, heartbeat_interval, CTLFLAG_RW,
596     &sctp_heartbeat_interval_default, 0,
597     "Default heartbeat interval in msec");
598
599 SYSCTL_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
603 SYSCTL_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
607 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, secret_lifetime, CTLFLAG_RW,
608     &sctp_secret_lifetime_default, 0,
609     "Default secret lifetime in sec");
610
611 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, rto_max, CTLFLAG_RW,
612     &sctp_rto_max_default, 0,
613     "Default maximum retransmission timeout in msec");
614
615 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, rto_min, CTLFLAG_RW,
616     &sctp_rto_min_default, 0,
617     "Default minimum retransmission timeout in msec");
618
619 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, rto_initial, CTLFLAG_RW,
620     &sctp_rto_initial_default, 0,
621     "Default initial retransmission timeout in msec");
622
623 SYSCTL_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
627 SYSCTL_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
631 SYSCTL_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
635 SYSCTL_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
639 SYSCTL_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
643 SYSCTL_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
648 SYSCTL_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
652 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, cmt_on_off, CTLFLAG_RW,
653     &sctp_cmt_on_off, 0,
654     "CMT ON/OFF flag");
655
656 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, cwnd_maxburst, CTLFLAG_RW,
657     &sctp_use_cwnd_based_maxburst, 0,
658     "Use a CWND adjusting maxburst");
659
660 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, early_fast_retran, CTLFLAG_RW,
661     &sctp_early_fr, 0,
662     "Early Fast Retransmit with Timer");
663
664 SYSCTL_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
668 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, deadlock_detect, CTLFLAG_RW,
669     &sctp_says_check_for_deadlock, 0,
670     "SMP Deadlock detection on/off");
671
672 SYSCTL_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
676 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, asconf_auth_nochk, CTLFLAG_RW,
677     &sctp_asconf_auth_nochk, 0,
678     "Disable SCTP ASCONF AUTH requirement");
679
680 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, auth_disable, CTLFLAG_RW,
681     &sctp_auth_disable, 0,
682     "Disable SCTP AUTH chunk requirement/function");
683
684 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, auth_random_len, CTLFLAG_RW,
685     &sctp_auth_random_len, 0,
686     "Length of AUTH RANDOMs");
687
688 SYSCTL_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
692 SYSCTL_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
696 SYSCTL_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
700 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, cmt_use_dac, CTLFLAG_RW,
701     &sctp_cmt_use_dac, 0,
702     "CMT DAC ON/OFF flag");
703
704 SYSCTL_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
708 SYSCTL_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
712 SYSCTL_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
716 SYSCTL_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
720 SYSCTL_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
724 SYSCTL_INT(_net_inet_sctp, OID_AUTO, debug, CTLFLAG_RW,
725     &sctp_debug_on, 0, "Configure debug output");
726 #endif                          /* SCTP_DEBUG */
727
728 static void
729 sctp_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();
740 sctp_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
779 static int
780 sctp_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
836 static int
837 sctp_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
858 static void
859 sctp_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          */
871 sctp_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
921 int
922 sctp_sendm(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
923     struct mbuf *control, struct thread *p);
924
925
926 int
927 sctp_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 */
969 connected_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
1021 static int
1022 sctp_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
1196 int
1197 sctp_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         }
1316 skip_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  */
1326 static uint32_t
1327 sctp_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
1339 static int
1340 sctp_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
1538 static int
1539 sctp_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
1584 static int
1585 sctp_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         }
1762 out_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
1772 static int
1773 sctp_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
3034 static int
3035 sctp_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
4353 extern int sctp_chatty_mbuf;
4354
4355 int
4356 sctp_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         }
4416 out:
4417         splx(s);
4418         return (error);
4419 }
4420
4421
4422 static int
4423 sctp_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);
4515 out_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
4526 int
4527 sctp_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
4594 static int sctp_defered_wakeup_cnt = 0;
4595
4596 int
4597 sctp_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
4682 int
4683 sctp_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
4768 int
4769 sctp_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
4832 struct 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 };