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