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