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