Fix LINT build.
[dragonfly.git] / sys / netinet / sctp_usrreq.c
1 /*      $KAME: sctp_usrreq.c,v 1.47 2005/03/06 16:04:18 itojun Exp $    */
2 /*      $DragonFly: src/sys/netinet/sctp_usrreq.c,v 1.14 2008/04/20 13:44:25 swildner Exp $     */
3
4 /*
5  * Copyright (c) 2001, 2002, 2003, 2004 Cisco Systems, Inc.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *      This product includes software developed by Cisco Systems, Inc.
19  * 4. Neither the name of the project nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY CISCO SYSTEMS AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL CISCO SYSTEMS OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  */
35 #if !(defined(__OpenBSD__) || defined(__APPLE__))
36 #include "opt_ipsec.h"
37 #endif
38 #if defined(__FreeBSD__) || defined(__DragonFly__)
39 #include "opt_inet6.h"
40 #include "opt_inet.h"
41 #endif
42 #if defined(__NetBSD__)
43 #include "opt_inet.h"
44 #endif
45
46 #ifdef __APPLE__
47 #include <sctp.h>
48 #elif !defined(__OpenBSD__)
49 #include "opt_sctp.h"
50 #endif
51
52 #include <sys/param.h>
53 #include <sys/systm.h>
54 #include <sys/kernel.h>
55 #include <sys/malloc.h>
56 #include <sys/mbuf.h>
57 #include <sys/domain.h>
58 #include <sys/proc.h>
59 #include <sys/priv.h>
60 #include <sys/protosw.h>
61 #include <sys/socket.h>
62 #include <sys/socketvar.h>
63 #include <sys/socketvar2.h>
64 #include <sys/sysctl.h>
65 #include <sys/syslog.h>
66 #include <sys/thread2.h>
67 #include <net/if.h>
68 #include <net/if_types.h>
69 #if defined(__FreeBSD__) || defined(__APPLE__) || defined(__DragonFly__)
70 #include <net/if_var.h>
71 #endif
72 #include <net/route.h>
73 #include <netinet/in.h>
74 #include <netinet/in_systm.h>
75 #include <netinet/ip.h>
76 #include <netinet/ip6.h>
77 #include <netinet/in_pcb.h>
78 #include <netinet/in_var.h>
79 #include <netinet/ip_var.h>
80 #include <netinet6/ip6_var.h>
81 #include <netinet6/in6_var.h>
82
83 #include <netinet/ip_icmp.h>
84 #include <netinet/icmp_var.h>
85 #include <netinet/sctp_pcb.h>
86 #include <netinet/sctp_header.h>
87 #include <netinet/sctp_var.h>
88 #include <netinet/sctp_output.h>
89 #include <netinet/sctp_uio.h>
90 #include <netinet/sctp_asconf.h>
91 #include <netinet/sctputil.h>
92 #include <netinet/sctp_indata.h>
93 #include <netinet/sctp_asconf.h>
94 #ifdef IPSEC
95 #ifndef __OpenBSD__
96 #include <netinet6/ipsec.h>
97 #include <netproto/key/key.h>
98 #else
99 #undef IPSEC
100 #endif
101 #endif /* IPSEC */
102
103 #include <net/net_osdep.h>
104
105 #if defined(HAVE_NRL_INPCB) || defined(__FreeBSD__) || defined(__DragonFly__)
106 #ifndef in6pcb
107 #define in6pcb          inpcb
108 #endif
109 #ifndef sotoin6pcb
110 #define sotoin6pcb      sotoinpcb
111 #endif
112 #endif
113
114 #ifdef SCTP_DEBUG
115 extern u_int32_t sctp_debug_on;
116 #endif /* SCTP_DEBUG */
117
118 /*
119  * sysctl tunable variables
120  */
121 int sctp_auto_asconf = SCTP_DEFAULT_AUTO_ASCONF;
122 int sctp_max_burst_default = SCTP_DEF_MAX_BURST;
123 int sctp_peer_chunk_oh = sizeof(struct mbuf);
124 int sctp_strict_init = 1;
125 int sctp_no_csum_on_loopback = 1;
126 unsigned int sctp_max_chunks_on_queue = SCTP_ASOC_MAX_CHUNKS_ON_QUEUE;
127 int sctp_sendspace = (128 * 1024);
128 int sctp_recvspace = 128 * (1024 +
129 #ifdef INET6
130                                 sizeof(struct sockaddr_in6)
131 #else
132                                 sizeof(struct sockaddr_in)
133 #endif
134         );
135 int sctp_strict_sacks = 0;
136 int sctp_ecn = 1;
137 int sctp_ecn_nonce = 0;
138
139 unsigned int sctp_delayed_sack_time_default = SCTP_RECV_MSEC;
140 unsigned int sctp_heartbeat_interval_default = SCTP_HB_DEFAULT_MSEC;
141 unsigned int sctp_pmtu_raise_time_default = SCTP_DEF_PMTU_RAISE_SEC;
142 unsigned int sctp_shutdown_guard_time_default = SCTP_DEF_MAX_SHUTDOWN_SEC;
143 unsigned int sctp_secret_lifetime_default = SCTP_DEFAULT_SECRET_LIFE_SEC;
144 unsigned int sctp_rto_max_default = SCTP_RTO_UPPER_BOUND;
145 unsigned int sctp_rto_min_default = SCTP_RTO_LOWER_BOUND;
146 unsigned int sctp_rto_initial_default = SCTP_RTO_INITIAL;
147 unsigned int sctp_init_rto_max_default = SCTP_RTO_UPPER_BOUND;
148 unsigned int sctp_valid_cookie_life_default = SCTP_DEFAULT_COOKIE_LIFE;
149 unsigned int sctp_init_rtx_max_default = SCTP_DEF_MAX_INIT;
150 unsigned int sctp_assoc_rtx_max_default = SCTP_DEF_MAX_SEND;
151 unsigned int sctp_path_rtx_max_default = SCTP_DEF_MAX_SEND/2;
152 unsigned int sctp_nr_outgoing_streams_default = SCTP_OSTREAM_INITIAL;
153
154 void
155 sctp_init(void)
156 {
157 #ifdef __OpenBSD__
158 #define nmbclusters     nmbclust
159 #endif
160         /* Init the SCTP pcb in sctp_pcb.c */
161         u_long sb_max_adj;
162
163         sctp_pcb_init();
164
165 #ifndef __OpenBSD__
166         if (nmbclusters > SCTP_ASOC_MAX_CHUNKS_ON_QUEUE)
167                 sctp_max_chunks_on_queue = nmbclusters;
168 #else
169 /*      if (nmbclust > SCTP_ASOC_MAX_CHUNKS_ON_QUEUE)
170         sctp_max_chunks_on_queue = nmbclust; FIX ME */
171         sctp_max_chunks_on_queue = nmbclust * 2;
172 #endif
173         /*
174          * Allow a user to take no more than 1/2 the number of clusters
175          * or the SB_MAX whichever is smaller for the send window.
176          */
177         sb_max_adj = (u_long)((u_quad_t)(SB_MAX) * MCLBYTES / (MSIZE + MCLBYTES));
178         sctp_sendspace = min((min(SB_MAX, sb_max_adj)),
179 #ifndef __OpenBSD__
180                              ((nmbclusters/2) * SCTP_DEFAULT_MAXSEGMENT));
181 #else
182                              ((nmbclust/2) * SCTP_DEFAULT_MAXSEGMENT));
183 #endif
184         /*
185          * Now for the recv window, should we take the same amount?
186          * or should I do 1/2 the SB_MAX instead in the SB_MAX min above.
187          * For now I will just copy.
188          */
189         sctp_recvspace = sctp_sendspace;
190 #ifdef __OpenBSD__
191 #undef nmbclusters
192 #endif
193 }
194
195 #ifdef INET6
196 void
197 ip_2_ip6_hdr(struct ip6_hdr *ip6, struct ip *ip)
198 {
199         bzero(ip6, sizeof(*ip6));
200
201         ip6->ip6_vfc = IPV6_VERSION;
202         ip6->ip6_plen = ip->ip_len;
203         ip6->ip6_nxt = ip->ip_p;
204         ip6->ip6_hlim = ip->ip_ttl;
205         ip6->ip6_src.s6_addr32[2] = ip6->ip6_dst.s6_addr32[2] =
206                 IPV6_ADDR_INT32_SMP;
207         ip6->ip6_src.s6_addr32[3] = ip->ip_src.s_addr;
208         ip6->ip6_dst.s6_addr32[3] = ip->ip_dst.s_addr;
209 }
210 #endif /* INET6 */
211
212 static void
213 sctp_split_chunks(struct sctp_association *asoc,
214                   struct sctp_stream_out *strm,
215                   struct sctp_tmit_chunk *chk)
216 {
217         struct sctp_tmit_chunk *new_chk;
218
219         /* First we need a chunk */
220         new_chk = (struct sctp_tmit_chunk *)SCTP_ZONE_GET(sctppcbinfo.ipi_zone_chunk);
221         if (new_chk == NULL) {
222                 chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
223                 return;
224         }
225         sctppcbinfo.ipi_count_chunk++;
226         sctppcbinfo.ipi_gencnt_chunk++;
227         /* Copy it all */
228         *new_chk = *chk;
229         /*  split the data */
230         new_chk->data = m_split(chk->data, (chk->send_size>>1), MB_DONTWAIT);
231         if (new_chk->data == NULL) {
232                 /* Can't split */
233                 chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
234                 SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_chunk, new_chk);
235                 sctppcbinfo.ipi_count_chunk--;
236                 if ((int)sctppcbinfo.ipi_count_chunk < 0) {
237                         panic("Chunk count is negative");
238                 }
239                 sctppcbinfo.ipi_gencnt_chunk++;
240                 return;
241
242         }
243         /* Data is now split adjust sizes */
244         chk->send_size >>= 1;
245         new_chk->send_size >>= 1;
246
247         chk->book_size >>= 1;
248         new_chk->book_size >>= 1;
249
250         /* now adjust the marks */
251         chk->rec.data.rcv_flags |= SCTP_DATA_FIRST_FRAG;
252         chk->rec.data.rcv_flags &= ~SCTP_DATA_LAST_FRAG;
253
254         new_chk->rec.data.rcv_flags &= ~SCTP_DATA_FIRST_FRAG;
255         new_chk->rec.data.rcv_flags |= SCTP_DATA_LAST_FRAG;
256
257         /* Increase ref count if dest is set */
258         if (chk->whoTo) {
259                 new_chk->whoTo->ref_count++;
260         }
261         /* now drop it on the end of the list*/
262         asoc->stream_queue_cnt++;
263         TAILQ_INSERT_AFTER(&strm->outqueue, chk, new_chk, sctp_next);
264 }
265
266 static void
267 sctp_notify_mbuf(struct sctp_inpcb *inp,
268                  struct sctp_tcb *stcb,
269                  struct sctp_nets *net,
270                  struct ip *ip,
271                  struct sctphdr *sh)
272
273 {
274         struct icmp *icmph;
275         int totsz;
276         uint16_t nxtsz;
277
278         /* protection */
279         if ((inp == NULL) || (stcb == NULL) || (net == NULL) ||
280             (ip == NULL) || (sh == NULL)) {
281                 if (stcb != NULL)
282                         SCTP_TCB_UNLOCK(stcb);
283                 return;
284         }
285         /* First job is to verify the vtag matches what I would send */
286         if (ntohl(sh->v_tag) != (stcb->asoc.peer_vtag)) {
287                 SCTP_TCB_UNLOCK(stcb);
288                 return;
289         }
290         icmph = (struct icmp *)((caddr_t)ip - (sizeof(struct icmp) -
291                                                sizeof(struct ip)));
292         if (icmph->icmp_type != ICMP_UNREACH) {
293                 /* We only care about unreachable */
294                 SCTP_TCB_UNLOCK(stcb);
295                 return;
296         }
297         if (icmph->icmp_code != ICMP_UNREACH_NEEDFRAG) {
298                 /* not a unreachable message due to frag. */
299                 SCTP_TCB_UNLOCK(stcb);
300                 return;
301         }
302         totsz = ip->ip_len;
303         nxtsz = ntohs(icmph->icmp_seq);
304         if (nxtsz == 0) {
305                 /*
306                  * old type router that does not tell us what the next size
307                  * mtu is. Rats we will have to guess (in a educated fashion
308                  * of course)
309                  */
310                 nxtsz = find_next_best_mtu(totsz);
311         }
312
313         /* Stop any PMTU timer */
314         sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, NULL);
315
316         /* Adjust destination size limit */
317         if (net->mtu > nxtsz) {
318                 net->mtu = nxtsz;
319         }
320         /* now what about the ep? */
321         if (stcb->asoc.smallest_mtu > nxtsz) {
322                 struct sctp_tmit_chunk *chk, *nchk;
323                 struct sctp_stream_out *strm;
324                 /* Adjust that too */
325                 stcb->asoc.smallest_mtu = nxtsz;
326                 /* now off to subtract IP_DF flag if needed */
327
328                 TAILQ_FOREACH(chk, &stcb->asoc.send_queue, sctp_next) {
329                         if ((chk->send_size+IP_HDR_SIZE) > nxtsz) {
330                                 chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
331                         }
332                 }
333                 TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
334                         if ((chk->send_size+IP_HDR_SIZE) > nxtsz) {
335                                 /*
336                                  * For this guy we also mark for immediate
337                                  * resend since we sent to big of chunk
338                                  */
339                                 chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
340                                 if (chk->sent != SCTP_DATAGRAM_RESEND) {
341                                         stcb->asoc.sent_queue_retran_cnt++;
342                                 }
343                                 chk->sent = SCTP_DATAGRAM_RESEND;
344                                 chk->rec.data.doing_fast_retransmit = 0;
345
346                                 /* Clear any time so NO RTT is being done */
347                                 chk->do_rtt = 0;
348                                 stcb->asoc.total_flight -= chk->book_size;
349                                 if (stcb->asoc.total_flight < 0) {
350                                         stcb->asoc.total_flight = 0;
351                                 }
352                                 stcb->asoc.total_flight_count--;
353                                 if (stcb->asoc.total_flight_count < 0) {
354                                         stcb->asoc.total_flight_count = 0;
355                                 }
356                                 net->flight_size -= chk->book_size;
357                                 if (net->flight_size < 0) {
358                                         net->flight_size = 0;
359                                 }
360                         }
361                 }
362                 TAILQ_FOREACH(strm, &stcb->asoc.out_wheel, next_spoke) {
363                         chk = TAILQ_FIRST(&strm->outqueue);
364                         while (chk) {
365                                 nchk = TAILQ_NEXT(chk, sctp_next);
366                                 if ((chk->send_size+SCTP_MED_OVERHEAD) > nxtsz) {
367                                         sctp_split_chunks(&stcb->asoc, strm, chk);
368                                 }
369                                 chk = nchk;
370                         }
371                 }
372         }
373         sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, NULL);
374         SCTP_TCB_UNLOCK(stcb);
375 }
376
377
378 void
379 sctp_notify(struct sctp_inpcb *inp,
380             int error,
381             struct sctphdr *sh,
382             struct sockaddr *to,
383             struct sctp_tcb *stcb,
384             struct sctp_nets *net)
385 {
386         /* protection */
387         if ((inp == NULL) || (stcb == NULL) || (net == NULL) ||
388             (sh == NULL) || (to == NULL)) {
389 #ifdef SCTP_DEBUG
390                 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
391                         kprintf("sctp-notify, bad call\n");
392                 }
393 #endif /* SCTP_DEBUG */
394                 return;
395         }
396         /* First job is to verify the vtag matches what I would send */
397         if (ntohl(sh->v_tag) != (stcb->asoc.peer_vtag)) {
398                 return;
399         }
400
401 /* FIX ME FIX ME PROTOPT i.e. no SCTP should ALWAYS be an ABORT */
402
403         if ((error == EHOSTUNREACH) ||  /* Host is not reachable */
404             (error == EHOSTDOWN) ||     /* Host is down */
405             (error == ECONNREFUSED) ||  /* Host refused the connection, (not an abort?) */
406             (error == ENOPROTOOPT)      /* SCTP is not present on host */
407                 ) {
408                 /*
409                  * Hmm reachablity problems we must examine closely.
410                  * If its not reachable, we may have lost a network.
411                  * Or if there is NO protocol at the other end named SCTP.
412                  * well we consider it a OOTB abort.
413                  */
414                 if ((error == EHOSTUNREACH) || (error == EHOSTDOWN)) {
415                         if (net->dest_state & SCTP_ADDR_REACHABLE) {
416                                 /* Ok that destination is NOT reachable */
417                                 net->dest_state &= ~SCTP_ADDR_REACHABLE;
418                                 net->dest_state |= SCTP_ADDR_NOT_REACHABLE;
419                                 net->error_count = net->failure_threshold + 1;
420                                 sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN,
421                                                 stcb, SCTP_FAILED_THRESHOLD,
422                                                 (void *)net);
423                         }
424                         if (stcb)
425                                 SCTP_TCB_UNLOCK(stcb);
426                 } else {
427                         /*
428                          * Here the peer is either playing tricks on us,
429                          * including an address that belongs to someone who
430                          * does not support SCTP OR was a userland
431                          * implementation that shutdown and now is dead. In
432                          * either case treat it like a OOTB abort with no TCB
433                          */
434                         sctp_abort_notification(stcb, SCTP_PEER_FAULTY);
435                         sctp_free_assoc(inp, stcb);
436                         /* no need to unlock here, since the TCB is gone */
437                 }
438         } else {
439                 /* Send all others to the app */
440                 if (inp->sctp_socket) {
441                         SOCK_LOCK(inp->sctp_socket);
442                         inp->sctp_socket->so_error = error;
443                         sctp_sowwakeup(inp, inp->sctp_socket);
444                         SOCK_UNLOCK(inp->sctp_socket);
445                 }
446                 if (stcb)
447                         SCTP_TCB_UNLOCK(stcb);
448         }
449 }
450
451 #if defined(__FreeBSD__) || defined(__APPLE__) || defined(__DragonFly__)
452 void
453 #else
454 void *
455 #endif
456 sctp_ctlinput(int cmd, struct sockaddr *sa, void *vip)
457 {
458         struct ip *ip = vip;
459         struct sctphdr *sh;
460
461
462         if (sa->sa_family != AF_INET ||
463             ((struct sockaddr_in *)sa)->sin_addr.s_addr == INADDR_ANY) {
464 #if defined(__FreeBSD__) || defined(__APPLE__) || defined(__DragonFly__)
465                 return;
466 #else
467                 return (NULL);
468 #endif
469         }
470
471         if (PRC_IS_REDIRECT(cmd)) {
472                 ip = 0;
473         } else if ((unsigned)cmd >= PRC_NCMDS || inetctlerrmap[cmd] == 0) {
474 #if defined(__FreeBSD__) || defined(__APPLE__) || defined(__DragonFly__)
475                 return;
476 #else
477                 return (NULL);
478 #endif
479         }
480         if (ip) {
481                 struct sctp_inpcb *inp;
482                 struct sctp_tcb *stcb;
483                 struct sctp_nets *net;
484                 struct sockaddr_in to, from;
485
486                 sh = (struct sctphdr *)((caddr_t)ip + (ip->ip_hl << 2));
487                 bzero(&to, sizeof(to));
488                 bzero(&from, sizeof(from));
489                 from.sin_family = to.sin_family = AF_INET;
490                 from.sin_len = to.sin_len = sizeof(to);
491                 from.sin_port = sh->src_port;
492                 from.sin_addr = ip->ip_src;
493                 to.sin_port = sh->dest_port;
494                 to.sin_addr = ip->ip_dst;
495
496                 /*
497                  * 'to' holds the dest of the packet that failed to be sent.
498                  * 'from' holds our local endpoint address.
499                  * Thus we reverse the to and the from in the lookup.
500                  */
501                 crit_enter();
502                 stcb = sctp_findassociation_addr_sa((struct sockaddr *)&from,
503                                                     (struct sockaddr *)&to,
504                                                     &inp, &net, 1);
505                 if (stcb != NULL && inp && (inp->sctp_socket != NULL)) {
506                         if (cmd != PRC_MSGSIZE) {
507                                 int cm;
508                                 if (cmd == PRC_HOSTDEAD) {
509                                         cm = EHOSTUNREACH;
510                                 } else {
511                                         cm = inetctlerrmap[cmd];
512                                 }
513                                 sctp_notify(inp, cm, sh,
514                                             (struct sockaddr *)&to, stcb,
515                                             net);
516                         } else {
517                                 /* handle possible ICMP size messages */
518                                 sctp_notify_mbuf(inp, stcb, net, ip, sh);
519                         }
520                 } else {
521 #if (defined(__FreeBSD__) && __FreeBSD_version < 500000) || defined(__DragonFly__)
522                         /* XXX must be fixed for 5.x and higher, leave for 4.x */
523                         if (PRC_IS_REDIRECT(cmd) && inp) {
524                                 in_rtchange((struct inpcb *)inp,
525                                             inetctlerrmap[cmd]);
526                         }
527 #endif
528                         if ((stcb == NULL) && (inp != NULL)) {
529                                 /* reduce ref-count */
530                                 SCTP_INP_WLOCK(inp);
531                                 SCTP_INP_DECR_REF(inp);
532                                 SCTP_INP_WUNLOCK(inp);
533                         }
534
535                 }
536                 crit_exit();
537         }
538 #if defined(__FreeBSD__) || defined(__APPLE__) || defined(__DragonFly__)
539         return;
540 #else
541         return (NULL);
542 #endif
543 }
544
545 #if defined(__FreeBSD__) || defined(__DragonFly__)
546 static int
547 sctp_getcred(SYSCTL_HANDLER_ARGS)
548 {
549         struct sockaddr_in addrs[2];
550         struct sctp_inpcb *inp;
551         struct sctp_nets *net;
552         struct sctp_tcb *stcb;
553         int error;
554
555 #if __FreeBSD_version >= 500000 || defined(__DragonFly__)
556         error = priv_check(req->td, PRIV_ROOT);
557 #else
558         error = suser(req->p);
559 #endif
560         if (error)
561                 return (error);
562         error = SYSCTL_IN(req, addrs, sizeof(addrs));
563         if (error)
564                 return (error);
565
566         crit_enter();
567         stcb = sctp_findassociation_addr_sa(sintosa(&addrs[0]),
568                                            sintosa(&addrs[1]),
569                                            &inp, &net, 1);
570         if (stcb == NULL || inp == NULL || inp->sctp_socket == NULL) {
571                 if ((inp != NULL) && (stcb == NULL)) {
572                         /* reduce ref-count */
573                         SCTP_INP_WLOCK(inp);
574                         SCTP_INP_DECR_REF(inp);
575                         SCTP_INP_WUNLOCK(inp);
576                 }
577                 error = ENOENT;
578                 goto out;
579         }
580         error = SYSCTL_OUT(req, inp->sctp_socket->so_cred, sizeof(struct ucred));
581         SCTP_TCB_UNLOCK(stcb);
582 out:
583         crit_exit();
584         return (error);
585 }
586
587 SYSCTL_PROC(_net_inet_sctp, OID_AUTO, getcred, CTLTYPE_OPAQUE|CTLFLAG_RW,
588             0, 0, sctp_getcred, "S,ucred", "Get the ucred of a SCTP connection");
589 #endif /* #if defined(__FreeBSD__) || defined(__DragonFly__) */
590
591 /*
592  * sysctl definitions
593  */
594 #if defined(__FreeBSD__) || defined (__APPLE__) || defined(__DragonFly__)
595
596 SYSCTL_DECL(_net_inet);
597
598 SYSCTL_NODE(_net_inet, OID_AUTO, sctp, CTLFLAG_RD, 0,
599         "sctp values");
600
601 SYSCTL_INT(_net_inet_sctp, OID_AUTO, maxdgram, CTLFLAG_RW,
602            &sctp_sendspace, 0, "Maximum outgoing SCTP buffer size");
603
604 SYSCTL_INT(_net_inet_sctp, OID_AUTO, recvspace, CTLFLAG_RW,
605            &sctp_recvspace, 0, "Maximum incoming SCTP buffer size");
606
607 SYSCTL_INT(_net_inet_sctp, OID_AUTO, auto_asconf, CTLFLAG_RW,
608            &sctp_auto_asconf, 0, "Enable SCTP Auto-ASCONF");
609
610 SYSCTL_INT(_net_inet_sctp, OID_AUTO, ecn_enable, CTLFLAG_RW,
611            &sctp_ecn, 0, "Enable SCTP ECN");
612
613 SYSCTL_INT(_net_inet_sctp, OID_AUTO, ecn_nonce, CTLFLAG_RW,
614            &sctp_ecn_nonce, 0, "Enable SCTP ECN Nonce");
615
616 SYSCTL_INT(_net_inet_sctp, OID_AUTO, strict_sacks, CTLFLAG_RW,
617            &sctp_strict_sacks, 0, "Enable SCTP Strict SACK checking");
618
619 SYSCTL_INT(_net_inet_sctp, OID_AUTO, loopback_nocsum, CTLFLAG_RW,
620            &sctp_no_csum_on_loopback, 0,
621            "Enable NO Csum on packets sent on loopback");
622
623 SYSCTL_INT(_net_inet_sctp, OID_AUTO, strict_init, CTLFLAG_RW,
624            &sctp_strict_init, 0,
625            "Enable strict INIT/INIT-ACK singleton enforcement");
626
627 SYSCTL_INT(_net_inet_sctp, OID_AUTO, peer_chkoh, CTLFLAG_RW,
628            &sctp_peer_chunk_oh, 0,
629            "Amount to debit peers rwnd per chunk sent");
630
631 SYSCTL_INT(_net_inet_sctp, OID_AUTO, maxburst, CTLFLAG_RW,
632            &sctp_max_burst_default, 0,
633            "Default max burst for sctp endpoints");
634
635 SYSCTL_INT(_net_inet_sctp, OID_AUTO, maxchunks, CTLFLAG_RW,
636            &sctp_max_chunks_on_queue, 0,
637            "Default max chunks on queue per asoc");
638
639 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, delayed_sack_time, CTLFLAG_RW,
640             &sctp_delayed_sack_time_default, 0,
641             "Default delayed SACK timer in msec");
642
643 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, heartbeat_interval, CTLFLAG_RW,
644             &sctp_heartbeat_interval_default, 0,
645             "Default heartbeat interval in msec");
646
647 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, pmtu_raise_time, CTLFLAG_RW,
648             &sctp_pmtu_raise_time_default, 0,
649             "Default PMTU raise timer in sec");
650
651 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, shutdown_guard_time, CTLFLAG_RW,
652             &sctp_shutdown_guard_time_default, 0,
653             "Default shutdown guard timer in sec");
654
655 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, secret_lifetime, CTLFLAG_RW,
656             &sctp_secret_lifetime_default, 0,
657             "Default secret lifetime in sec");
658
659 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, rto_max, CTLFLAG_RW,
660             &sctp_rto_max_default, 0,
661             "Default maximum retransmission timeout in msec");
662
663 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, rto_min, CTLFLAG_RW,
664             &sctp_rto_min_default, 0,
665             "Default minimum retransmission timeout in msec");
666
667 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, rto_initial, CTLFLAG_RW,
668             &sctp_rto_initial_default, 0,
669             "Default initial retransmission timeout in msec");
670
671 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, init_rto_max, CTLFLAG_RW,
672             &sctp_init_rto_max_default, 0,
673             "Default maximum retransmission timeout during association setup in msec");
674
675 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, valid_cookie_life, CTLFLAG_RW,
676             &sctp_valid_cookie_life_default, 0,
677             "Default cookie lifetime in sec");
678
679 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, init_rtx_max, CTLFLAG_RW,
680             &sctp_init_rtx_max_default, 0,
681             "Default maximum number of retransmission for INIT chunks");
682
683 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, assoc_rtx_max, CTLFLAG_RW,
684             &sctp_assoc_rtx_max_default, 0,
685             "Default maximum number of retransmissions per association");
686
687 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, path_rtx_max, CTLFLAG_RW,
688             &sctp_path_rtx_max_default, 0,
689             "Default maximum of retransmissions per path");
690
691 SYSCTL_UINT(_net_inet_sctp, OID_AUTO, nr_outgoing_streams, CTLFLAG_RW,
692             &sctp_nr_outgoing_streams_default, 0,
693             "Default number of outgoing streams");
694
695 #ifdef SCTP_DEBUG
696 SYSCTL_INT(_net_inet_sctp, OID_AUTO, debug, CTLFLAG_RW,
697            &sctp_debug_on, 0, "Configure debug output");
698 #endif /* SCTP_DEBUG */
699 #endif
700
701 /*
702  * NOTE: (so) is referenced from soabort*() and netmsg_pru_abort()
703  *       will sofree() it when we return.
704  */
705 static int
706 sctp_abort(struct socket *so)
707 {
708         struct sctp_inpcb *inp;
709         int error;
710
711         inp = (struct sctp_inpcb *)so->so_pcb;
712         if (inp) {
713                 sctp_inpcb_free(inp, 1);
714                 error = 0;
715         } else {
716                 error = EINVAL;
717         }
718         return error;
719 }
720
721 static int
722 #if defined(__FreeBSD__) && __FreeBSD_version >= 500000
723 sctp_attach(struct socket *so, int proto, struct thread *p)
724 #elif defined(__DragonFly__)
725 sctp_attach(struct socket *so, int proto, struct pru_attach_info *ai)
726 #else
727 sctp_attach(struct socket *so, int proto, struct proc *p)
728 #endif
729 {
730         struct sctp_inpcb *inp;
731         struct inpcb *ip_inp;
732         int error;
733
734         crit_enter();
735         inp = (struct sctp_inpcb *)so->so_pcb;
736         if (inp != 0) {
737                 crit_exit();
738                 return EINVAL;
739         }
740         error = soreserve(so, sctp_sendspace, sctp_recvspace, NULL);
741         if (error) {
742                 crit_exit();
743                 return error;
744         }
745         error = sctp_inpcb_alloc(so);
746         if (error) {
747                 crit_exit();
748                 return error;
749         }
750         inp = (struct sctp_inpcb *)so->so_pcb;
751         SCTP_INP_WLOCK(inp);
752
753         inp->sctp_flags &= ~SCTP_PCB_FLAGS_BOUND_V6;    /* I'm not v6! */
754         ip_inp = &inp->ip_inp.inp;
755 #if defined(__FreeBSD__) || defined(__APPLE__) || defined(__DragonFly__)
756         ip_inp->inp_vflag |= INP_IPV4;
757         ip_inp->inp_ip_ttl = ip_defttl;
758 #else
759         inp->inp_vflag |= INP_IPV4;
760         inp->inp_ip_ttl = ip_defttl;
761 #endif
762
763 #ifdef IPSEC
764 #if !(defined(__OpenBSD__) || defined(__APPLE__))
765         error = ipsec_init_policy(so, &ip_inp->inp_sp);
766         if (error != 0) {
767                 sctp_inpcb_free(inp, 1);
768                 return error;
769         }
770 #endif
771 #endif /*IPSEC*/
772         SCTP_INP_WUNLOCK(inp);
773 #if defined(__NetBSD__)
774         so->so_send = sctp_sosend;
775 #endif
776         crit_exit();
777         return 0;
778 }
779
780 static int
781 #if (defined(__FreeBSD__) && __FreeBSD_version >= 500000) || defined(__DragonFly__)
782 sctp_bind(struct socket *so, struct sockaddr *addr, struct thread *p)
783 {
784 #elif defined(__FreeBSD__) || defined(__APPLE__)
785 sctp_bind(struct socket *so, struct sockaddr *addr, struct proc *p)
786 {
787 #else
788 sctp_bind(struct socket *so, struct mbuf *nam, struct proc *p)
789 {
790         struct sockaddr *addr = nam ? mtod(nam, struct sockaddr *) : NULL;
791 #endif
792         struct sctp_inpcb *inp;
793         int error;
794
795 #ifdef INET6
796         if (addr && addr->sa_family != AF_INET)
797                 /* must be a v4 address! */
798                 return EINVAL;
799 #endif /* INET6 */
800
801         inp = (struct sctp_inpcb *)so->so_pcb;
802         if (inp == 0)
803                 return EINVAL;
804
805         crit_enter();
806         error = sctp_inpcb_bind(so, addr, p);
807         crit_exit();
808         return error;
809 }
810
811
812 static int
813 sctp_detach(struct socket *so)
814 {
815         struct sctp_inpcb *inp;
816
817         inp = (struct sctp_inpcb *)so->so_pcb;
818         if (inp == 0)
819                 return EINVAL;
820         crit_enter();
821         if (((so->so_options & SO_LINGER) && (so->so_linger == 0)) ||
822             (so->so_rcv.ssb_cc > 0)) {
823                 sctp_inpcb_free(inp, 1);
824         } else {
825                 sctp_inpcb_free(inp, 0);
826         }
827         crit_exit();
828         return 0;
829 }
830
831 int
832 #if (defined(__FreeBSD__) && __FreeBSD_version >= 500000) || defined(__DragonFly__)
833 sctp_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
834           struct mbuf *control, struct thread *p);
835 #else
836 sctp_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
837           struct mbuf *control, struct proc *p);
838 #endif
839
840 int
841 #if (defined(__FreeBSD__) && __FreeBSD_version >= 500000) || defined(__DragonFly__)
842 sctp_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
843           struct mbuf *control, struct thread *p)
844 {
845 #else
846 sctp_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
847           struct mbuf *control, struct proc *p)
848 {
849 #endif
850         struct sctp_inpcb *inp;
851         int error;
852         inp = (struct sctp_inpcb *)so->so_pcb;
853         if (inp == 0) {
854                 if (control) {
855                         sctp_m_freem(control);
856                         control = NULL;
857                 }
858                 sctp_m_freem(m);
859                 return EINVAL;
860         }
861         /* Got to have an to address if we are NOT a connected socket */
862         if ((addr == NULL) &&
863             ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) ||
864              (inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE))
865                 ) {
866                 goto connected_type;
867         } else if (addr == NULL) {
868                 error = EDESTADDRREQ;
869                 sctp_m_freem(m);
870                 if (control) {
871                         sctp_m_freem(control);
872                         control = NULL;
873                 }
874                 return (error);
875         }
876 #ifdef INET6
877         if (addr->sa_family != AF_INET) {
878                 /* must be a v4 address! */
879                 sctp_m_freem(m);
880                 if (control) {
881                         sctp_m_freem(control);
882                         control = NULL;
883                 }
884                 error = EDESTADDRREQ;
885                 return EINVAL;
886         }
887 #endif /* INET6 */
888  connected_type:
889         /* now what about control */
890         if (control) {
891                 if (inp->control) {
892                         kprintf("huh? control set?\n");
893                         sctp_m_freem(inp->control);
894                         inp->control = NULL;
895                 }
896                 inp->control = control;
897         }
898         /* add it in possibly */
899         if ((inp->pkt) && (inp->pkt->m_flags & M_PKTHDR)) {
900                 struct mbuf *x;
901                 int c_len;
902
903                 c_len = 0;
904                 /* How big is it */
905                 for (x=m;x;x = x->m_next) {
906                         c_len += x->m_len;
907                 }
908                 inp->pkt->m_pkthdr.len += c_len;
909         }
910         /* Place the data */
911         if (inp->pkt) {
912                 inp->pkt_last->m_next = m;
913                 inp->pkt_last = m;
914         } else {
915                 inp->pkt_last = inp->pkt = m;
916         }
917         if (
918 #if defined (__FreeBSD__) || defined(__APPLE__) || defined(__DragonFly__)
919             /* FreeBSD uses a flag passed */
920             ((flags & PRUS_MORETOCOME) == 0)
921 #elif defined( __NetBSD__)
922             /* NetBSD uses the so_state field */
923             ((so->so_state & SS_MORETOCOME) == 0)
924 #else
925             1   /* Open BSD does not have any "more to come" indication */
926 #endif
927             ) {
928                 /*
929                  * note with the current version this code will only be used
930                  * by OpenBSD-- NetBSD, FreeBSD, and MacOS have methods for
931                  * re-defining sosend to use the sctp_sosend. One can
932                  * optionally switch back to this code (by changing back the
933                  * definitions) but this is not advisable.
934              */
935                 int ret;
936                 ret = sctp_output(inp, inp->pkt, addr, inp->control, p, flags);
937                 inp->pkt = NULL;
938                 inp->control = NULL;
939                 return (ret);
940         } else {
941                 return (0);
942         }
943 }
944
945 static int
946 sctp_disconnect(struct socket *so)
947 {
948         struct sctp_inpcb *inp;
949
950         crit_enter();
951         inp = (struct sctp_inpcb *)so->so_pcb;
952         if (inp == NULL) {
953                 crit_exit();
954                 return (ENOTCONN);
955         }
956         SCTP_INP_RLOCK(inp);
957         if (inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) {
958                 if (LIST_EMPTY(&inp->sctp_asoc_list)) {
959                         /* No connection */
960                         crit_exit();
961                         SCTP_INP_RUNLOCK(inp);
962                         return (0);
963                 } else {
964                         int some_on_streamwheel = 0;
965                         struct sctp_association *asoc;
966                         struct sctp_tcb *stcb;
967
968                         stcb = LIST_FIRST(&inp->sctp_asoc_list);
969                         if (stcb == NULL) {
970                                 crit_exit();
971                                 SCTP_INP_RUNLOCK(inp);
972                                 return (EINVAL);
973                         }
974                         asoc = &stcb->asoc;
975                         SCTP_TCB_LOCK(stcb);
976                         if (((so->so_options & SO_LINGER) &&
977                              (so->so_linger == 0)) ||
978                             (so->so_rcv.ssb_cc > 0)) {
979                                 if (SCTP_GET_STATE(asoc) !=
980                                     SCTP_STATE_COOKIE_WAIT) {
981                                         /* Left with Data unread */
982                                         struct mbuf *err;
983                                         err = NULL;
984                                         MGET(err, MB_DONTWAIT, MT_DATA);
985                                         if (err) {
986                                                 /* Fill in the user initiated abort */
987                                                 struct sctp_paramhdr *ph;
988                                                 ph = mtod(err, struct sctp_paramhdr *);
989                                                 err->m_len = sizeof(struct sctp_paramhdr);
990                                                 ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
991                                                 ph->param_length = htons(err->m_len);
992                                         }
993                                         sctp_send_abort_tcb(stcb, err);
994                                 }
995                                 SCTP_INP_RUNLOCK(inp);
996                                 sctp_free_assoc(inp, stcb);
997                                 /* No unlock tcb assoc is gone */
998                                 crit_exit();
999                                 return (0);
1000                         }
1001                         if (!TAILQ_EMPTY(&asoc->out_wheel)) {
1002                                 /* Check to see if some data queued */
1003                                 struct sctp_stream_out *outs;
1004                                 TAILQ_FOREACH(outs, &asoc->out_wheel,
1005                                               next_spoke) {
1006                                         if (!TAILQ_EMPTY(&outs->outqueue)) {
1007                                                 some_on_streamwheel = 1;
1008                                                 break;
1009                                         }
1010                                 }
1011                         }
1012
1013                         if (TAILQ_EMPTY(&asoc->send_queue) &&
1014                             TAILQ_EMPTY(&asoc->sent_queue) &&
1015                             (some_on_streamwheel == 0)) {
1016                                 /* there is nothing queued to send, so done */
1017                                 if ((SCTP_GET_STATE(asoc) !=
1018                                      SCTP_STATE_SHUTDOWN_SENT) &&
1019                                     (SCTP_GET_STATE(asoc) !=
1020                                      SCTP_STATE_SHUTDOWN_ACK_SENT)) {
1021                                         /* only send SHUTDOWN 1st time thru */
1022 #ifdef SCTP_DEBUG
1023                                         if (sctp_debug_on & SCTP_DEBUG_OUTPUT4) {
1024                                                 kprintf("%s:%d sends a shutdown\n",
1025                                                        __FILE__,
1026                                                        __LINE__
1027                                                         );
1028                                         }
1029 #endif
1030                                         sctp_send_shutdown(stcb,
1031                                                            stcb->asoc.primary_destination);
1032                                         sctp_chunk_output(stcb->sctp_ep, stcb, 1);
1033                                         asoc->state = SCTP_STATE_SHUTDOWN_SENT;
1034                                         sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
1035                                                          stcb->sctp_ep, stcb,
1036                                                          asoc->primary_destination);
1037                                         sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
1038                                                          stcb->sctp_ep, stcb,
1039                                                          asoc->primary_destination);
1040                                 }
1041                         } else {
1042                                 /*
1043                                  * we still got (or just got) data to send,
1044                                  * so set SHUTDOWN_PENDING
1045                                  */
1046                                 /*
1047                                  * XXX sockets draft says that MSG_EOF should
1048                                  * be sent with no data.
1049                                  * currently, we will allow user data to be
1050                                  * sent first and move to SHUTDOWN-PENDING
1051                                  */
1052                                 asoc->state |= SCTP_STATE_SHUTDOWN_PENDING;
1053                         }
1054                         SCTP_TCB_UNLOCK(stcb);
1055                         SCTP_INP_RUNLOCK(inp);
1056                         crit_exit();
1057                         return (0);
1058                 }
1059                 /* not reached */
1060         } else {
1061                 /* UDP model does not support this */
1062                 SCTP_INP_RUNLOCK(inp);
1063                 crit_exit();
1064                 return EOPNOTSUPP;
1065         }
1066 }
1067
1068 int
1069 sctp_shutdown(struct socket *so)
1070 {
1071         struct sctp_inpcb *inp;
1072
1073         crit_enter();
1074         inp = (struct sctp_inpcb *)so->so_pcb;
1075         if (inp == 0) {
1076                 crit_exit();
1077                 return EINVAL;
1078         }
1079         SCTP_INP_RLOCK(inp);
1080         /* For UDP model this is a invalid call */
1081         if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) {
1082                 /* Restore the flags that the soshutdown took away. */
1083 #if defined(__FreeBSD__) && __FreeBSD_version >= 502115
1084                 so->so_rcv.sb_state &= ~SBS_CANTRCVMORE;
1085 #else
1086                 soclrstate(so, SS_CANTRCVMORE);
1087 #endif
1088                 /* This proc will wakeup for read and do nothing (I hope) */
1089                 crit_exit();
1090                 SCTP_INP_RUNLOCK(inp);
1091                 return (EOPNOTSUPP);
1092         }
1093         /*
1094          * Ok if we reach here its the TCP model and it is either a SHUT_WR
1095          * or SHUT_RDWR. This means we put the shutdown flag against it.
1096          */
1097         {
1098                 int some_on_streamwheel = 0;
1099                 struct sctp_tcb *stcb;
1100                 struct sctp_association *asoc;
1101                 socantsendmore(so);
1102
1103                 stcb = LIST_FIRST(&inp->sctp_asoc_list);
1104                 if (stcb == NULL) {
1105                         /*
1106                          * Ok we hit the case that the shutdown call was made
1107                          * after an abort or something. Nothing to do now.
1108                          */
1109                         crit_exit();
1110                         return (0);
1111                 }
1112                 SCTP_TCB_LOCK(stcb);
1113                 asoc = &stcb->asoc;
1114
1115                 if (!TAILQ_EMPTY(&asoc->out_wheel)) {
1116                         /* Check to see if some data queued */
1117                         struct sctp_stream_out *outs;
1118                         TAILQ_FOREACH(outs, &asoc->out_wheel, next_spoke) {
1119                                 if (!TAILQ_EMPTY(&outs->outqueue)) {
1120                                         some_on_streamwheel = 1;
1121                                         break;
1122                                 }
1123                         }
1124                 }
1125                 if (TAILQ_EMPTY(&asoc->send_queue) &&
1126                     TAILQ_EMPTY(&asoc->sent_queue) &&
1127                     (some_on_streamwheel == 0)) {
1128                         /* there is nothing queued to send, so I'm done... */
1129                         if (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT) {
1130                                 /* only send SHUTDOWN the first time through */
1131 #ifdef SCTP_DEBUG
1132                                 if (sctp_debug_on & SCTP_DEBUG_OUTPUT4) {
1133                                         kprintf("%s:%d sends a shutdown\n",
1134                                                __FILE__,
1135                                                __LINE__
1136                                                 );
1137                                 }
1138 #endif
1139                                 sctp_send_shutdown(stcb,
1140                                                    stcb->asoc.primary_destination);
1141                                 sctp_chunk_output(stcb->sctp_ep, stcb, 1);
1142                                 asoc->state = SCTP_STATE_SHUTDOWN_SENT;
1143                                 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
1144                                                  stcb->sctp_ep, stcb,
1145                                                  asoc->primary_destination);
1146                                 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
1147                                                  stcb->sctp_ep, stcb,
1148                                                  asoc->primary_destination);
1149                         }
1150                 } else {
1151                         /*
1152                          * we still got (or just got) data to send, so
1153                          * set SHUTDOWN_PENDING
1154                          */
1155                         asoc->state |= SCTP_STATE_SHUTDOWN_PENDING;
1156                 }
1157                 SCTP_TCB_UNLOCK(stcb);
1158         }
1159         SCTP_INP_RUNLOCK(inp);
1160         crit_exit();
1161         return 0;
1162 }
1163
1164 /*
1165  * copies a "user" presentable address and removes embedded scope, etc.
1166  * returns 0 on success, 1 on error
1167  */
1168 static uint32_t
1169 sctp_fill_user_address(struct sockaddr_storage *ss, struct sockaddr *sa)
1170 {
1171         struct sockaddr_in6 lsa6;
1172         sa = (struct sockaddr *)sctp_recover_scope((struct sockaddr_in6 *)sa,
1173                                                    &lsa6);
1174         memcpy(ss, sa, sa->sa_len);
1175         return (0);
1176 }
1177
1178
1179 #if defined(__NetBSD__) || defined(__OpenBSD__)
1180 /*
1181  * On NetBSD and OpenBSD in6_sin_2_v4mapsin6() not used and not exported,
1182  * so we have to export it here.
1183  */
1184 void    in6_sin_2_v4mapsin6(struct sockaddr_in *sin, struct sockaddr_in6 *sin6);
1185 #endif
1186
1187 static int
1188 sctp_fill_up_addresses(struct sctp_inpcb *inp,
1189                        struct sctp_tcb *stcb,
1190                        int limit,
1191                        struct sockaddr_storage *sas)
1192 {
1193         struct ifnet *ifn;
1194         int loopback_scope, ipv4_local_scope, local_scope, site_scope, actual;
1195         int ipv4_addr_legal, ipv6_addr_legal;
1196         actual = 0;
1197         if (limit <= 0)
1198                 return (actual);
1199
1200         if (stcb) {
1201                 /* Turn on all the appropriate scope */
1202                 loopback_scope = stcb->asoc.loopback_scope;
1203                 ipv4_local_scope = stcb->asoc.ipv4_local_scope;
1204                 local_scope = stcb->asoc.local_scope;
1205                 site_scope = stcb->asoc.site_scope;
1206         } else {
1207                 /* Turn on ALL scope, since we look at the EP */
1208                 loopback_scope = ipv4_local_scope = local_scope =
1209                         site_scope = 1;
1210         }
1211         ipv4_addr_legal = ipv6_addr_legal = 0;
1212         if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
1213                 ipv6_addr_legal = 1;
1214                 if (
1215 #if defined(__OpenBSD__)
1216                 (0) /* we always do dual bind */
1217 #elif defined (__NetBSD__)
1218                 (((struct in6pcb *)inp)->in6p_flags & IN6P_IPV6_V6ONLY)
1219 #else
1220                 (((struct in6pcb *)inp)->inp_flags & IN6P_IPV6_V6ONLY)
1221 #endif
1222                 == 0) {
1223                         ipv4_addr_legal = 1;
1224                 }
1225         } else {
1226                 ipv4_addr_legal = 1;
1227         }
1228
1229         if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
1230                 TAILQ_FOREACH(ifn, &ifnet, if_list) {
1231                         struct ifaddr_container *ifac;
1232
1233                         if ((loopback_scope == 0) &&
1234                             (ifn->if_type == IFT_LOOP)) {
1235                                 /* Skip loopback if loopback_scope not set */
1236                                 continue;
1237                         }
1238                         TAILQ_FOREACH(ifac, &ifn->if_addrheads[mycpuid],
1239                                       ifa_link) {
1240                                 struct ifaddr *ifa = ifac->ifa;
1241
1242                                 if (stcb) {
1243                                 /*
1244                                  * For the BOUND-ALL case, the list
1245                                  * associated with a TCB is Always
1246                                  * considered a reverse list.. i.e.
1247                                  * it lists addresses that are NOT
1248                                  * part of the association. If this
1249                                  * is one of those we must skip it.
1250                                  */
1251                                         if (sctp_is_addr_restricted(stcb,
1252                                                                     ifa->ifa_addr)) {
1253                                                 continue;
1254                                         }
1255                                 }
1256                                 if ((ifa->ifa_addr->sa_family == AF_INET) &&
1257                                     (ipv4_addr_legal)) {
1258                                         struct sockaddr_in *sin;
1259                                         sin = (struct sockaddr_in *)ifa->ifa_addr;
1260                                         if (sin->sin_addr.s_addr == 0) {
1261                                                 /* we skip unspecifed addresses */
1262                                                 continue;
1263                                         }
1264                                         if ((ipv4_local_scope == 0) &&
1265                                             (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
1266                                                 continue;
1267                                         }
1268                                         if (inp->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) {
1269                                                 in6_sin_2_v4mapsin6(sin, (struct sockaddr_in6 *)sas);
1270                                                 ((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport;
1271                                                 sas = (struct sockaddr_storage *)((caddr_t)sas + sizeof(struct sockaddr_in6));
1272                                                 actual += sizeof(sizeof(struct sockaddr_in6));
1273                                         } else {
1274                                                 memcpy(sas, sin, sizeof(*sin));
1275                                                 ((struct sockaddr_in *)sas)->sin_port = inp->sctp_lport;
1276                                                 sas = (struct sockaddr_storage *)((caddr_t)sas + sizeof(*sin));
1277                                                 actual += sizeof(*sin);
1278                                         }
1279                                         if (actual >= limit) {
1280                                                 return (actual);
1281                                         }
1282                                 } else if ((ifa->ifa_addr->sa_family == AF_INET6) &&
1283                                            (ipv6_addr_legal)) {
1284                                         struct sockaddr_in6 *sin6, lsa6;
1285                                         sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
1286                                         if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
1287                                                 /* we skip unspecifed addresses */
1288                                                 continue;
1289                                         }
1290                                         if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
1291                                                 if (local_scope == 0)
1292                                                         continue;
1293                                                 if (sin6->sin6_scope_id == 0) {
1294                                                         lsa6 = *sin6;
1295                                                         if (in6_recoverscope(&lsa6,
1296                                                                              &lsa6.sin6_addr,
1297                                                                              NULL))
1298                                                                 /* bad link local address */
1299                                                                 continue;
1300                                                         sin6 = &lsa6;
1301                                                 }
1302                                         }
1303                                         if ((site_scope == 0) &&
1304                                             (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) {
1305                                                 continue;
1306                                         }
1307                                         memcpy(sas, sin6, sizeof(*sin6));
1308                                         ((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport;
1309                                         sas = (struct sockaddr_storage *)((caddr_t)sas + sizeof(*sin6));
1310                                         actual += sizeof(*sin6);
1311                                         if (actual >= limit) {
1312                                                 return (actual);
1313                                         }
1314                                 }
1315                         }
1316                 }
1317         } else {
1318                 struct sctp_laddr *laddr;
1319                 /*
1320                  * If we have a TCB and we do NOT support ASCONF (it's
1321                  * turned off or otherwise) then the list is always the
1322                  * true list of addresses (the else case below).  Otherwise
1323                  * the list on the association is a list of addresses that
1324                  * are NOT part of the association.
1325                  */
1326                 if (inp->sctp_flags & SCTP_PCB_FLAGS_DO_ASCONF) {
1327                         /* The list is a NEGATIVE list */
1328                         LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
1329                                 if (stcb) {
1330                                         if (sctp_is_addr_restricted(stcb, laddr->ifa->ifa_addr)) {
1331                                                 continue;
1332                                         }
1333                                 }
1334                                 if (sctp_fill_user_address(sas, laddr->ifa->ifa_addr))
1335                                         continue;
1336
1337                                 ((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport;
1338                                 sas = (struct sockaddr_storage *)((caddr_t)sas +
1339                                                                   laddr->ifa->ifa_addr->sa_len);
1340                                 actual += laddr->ifa->ifa_addr->sa_len;
1341                                 if (actual >= limit) {
1342                                         return (actual);
1343                                 }
1344                         }
1345                 } else {
1346                         /* The list is a positive list if present */
1347                         if (stcb) {
1348                                 /* Must use the specific association list */
1349                                 LIST_FOREACH(laddr, &stcb->asoc.sctp_local_addr_list,
1350                                              sctp_nxt_addr) {
1351                                         if (sctp_fill_user_address(sas,
1352                                                                    laddr->ifa->ifa_addr))
1353                                                 continue;
1354                                         ((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport;
1355                                         sas = (struct sockaddr_storage *)((caddr_t)sas +
1356                                                                           laddr->ifa->ifa_addr->sa_len);
1357                                         actual += laddr->ifa->ifa_addr->sa_len;
1358                                         if (actual >= limit) {
1359                                                 return (actual);
1360                                         }
1361                                 }
1362                         } else {
1363                                 /* No endpoint so use the endpoints individual list */
1364                                 LIST_FOREACH(laddr, &inp->sctp_addr_list,
1365                                              sctp_nxt_addr) {
1366                                         if (sctp_fill_user_address(sas,
1367                                                                    laddr->ifa->ifa_addr))
1368                                                 continue;
1369                                         ((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport;
1370                                         sas = (struct sockaddr_storage *)((caddr_t)sas +
1371                                                                           laddr->ifa->ifa_addr->sa_len);
1372                                         actual += laddr->ifa->ifa_addr->sa_len;
1373                                         if (actual >= limit) {
1374                                                 return (actual);
1375                                         }
1376                                 }
1377                         }
1378                 }
1379         }
1380         return (actual);
1381 }
1382
1383 static int
1384 sctp_count_max_addresses(struct sctp_inpcb *inp)
1385 {
1386         int cnt = 0;
1387         /*
1388          * In both sub-set bound an bound_all cases we return the MAXIMUM
1389          * number of addresses that you COULD get. In reality the sub-set
1390          * bound may have an exclusion list for a given TCB OR in the
1391          * bound-all case a TCB may NOT include the loopback or other
1392          * addresses as well.
1393          */
1394         if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
1395                 struct ifnet *ifn;
1396
1397                 TAILQ_FOREACH(ifn, &ifnet, if_list) {
1398                         struct ifaddr_container *ifac;
1399
1400                         TAILQ_FOREACH(ifac, &ifn->if_addrheads[mycpuid], ifa_link) {
1401                                 struct ifaddr *ifa = ifac->ifa;
1402
1403                                 /* Count them if they are the right type */
1404                                 if (ifa->ifa_addr->sa_family == AF_INET) {
1405                                         if (inp->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)
1406                                                 cnt += sizeof(struct sockaddr_in6);
1407                                         else
1408                                                 cnt += sizeof(struct sockaddr_in);
1409
1410                                 } else if (ifa->ifa_addr->sa_family == AF_INET6)
1411                                         cnt += sizeof(struct sockaddr_in6);
1412                         }
1413                 }
1414         } else {
1415                 struct sctp_laddr *laddr;
1416                 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
1417                         if (laddr->ifa->ifa_addr->sa_family == AF_INET) {
1418                                 if (inp->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)
1419                                         cnt += sizeof(struct sockaddr_in6);
1420                                 else
1421                                         cnt += sizeof(struct sockaddr_in);
1422
1423                         } else if (laddr->ifa->ifa_addr->sa_family == AF_INET6)
1424                                 cnt += sizeof(struct sockaddr_in6);
1425                 }
1426         }
1427         return (cnt);
1428 }
1429
1430 static int
1431 sctp_do_connect_x(struct socket *so,
1432                   struct sctp_inpcb *inp,
1433                   struct mbuf *m,
1434 #if (defined(__FreeBSD__) && __FreeBSD_version >= 500000) || defined(__DragonFly__)
1435                   struct thread *p,
1436 #else
1437                   struct proc *p,
1438 #endif
1439                   int delay
1440         )
1441 {
1442         int error = 0;
1443         struct sctp_tcb *stcb = NULL;
1444         struct sockaddr *sa;
1445         int num_v6=0, num_v4=0, *totaddrp, totaddr, i, incr, at;
1446 #ifdef SCTP_DEBUG
1447         if (sctp_debug_on & SCTP_DEBUG_PCB1) {
1448                 kprintf("Connectx called\n");
1449         }
1450 #endif /* SCTP_DEBUG */
1451
1452         crit_enter();
1453         if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
1454             (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) {
1455                 /* We are already connected AND the TCP model */
1456                 crit_exit();
1457                 return (EADDRINUSE);
1458         }
1459         if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
1460                 SCTP_INP_RLOCK(inp);
1461                 stcb = LIST_FIRST(&inp->sctp_asoc_list);
1462                 SCTP_INP_RUNLOCK(inp);
1463         }
1464         if (stcb) {
1465                 crit_exit();
1466                 return (EALREADY);
1467
1468         }
1469         SCTP_ASOC_CREATE_LOCK(inp);
1470         if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
1471             (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) {
1472                 SCTP_ASOC_CREATE_UNLOCK(inp);
1473                 crit_exit();
1474                 return (EFAULT);
1475         }
1476
1477         totaddrp = mtod(m, int *);
1478         totaddr = *totaddrp;
1479         sa = (struct sockaddr *)(totaddrp + 1);
1480         at = incr = 0;
1481         /* account and validate addresses */
1482         SCTP_INP_WLOCK(inp);
1483         SCTP_INP_INCR_REF(inp);
1484         SCTP_INP_WUNLOCK(inp);
1485         for (i = 0; i < totaddr; i++) {
1486                 if (sa->sa_family == AF_INET) {
1487                         num_v4++;
1488                         incr = sizeof(struct sockaddr_in);
1489                 } else if (sa->sa_family == AF_INET6) {
1490                         struct sockaddr_in6 *sin6;
1491                         sin6 = (struct sockaddr_in6 *)sa;
1492                         if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
1493                                 /* Must be non-mapped for connectx */
1494                                 SCTP_ASOC_CREATE_UNLOCK(inp);
1495                                 crit_exit();
1496                                 return EINVAL;
1497                         }
1498                         num_v6++;
1499                         incr = sizeof(struct sockaddr_in6);
1500                 } else {
1501                         totaddr = i;
1502                         break;
1503                 }
1504                 stcb = sctp_findassociation_ep_addr(&inp, sa, NULL, NULL, NULL);
1505                 if (stcb != NULL) {
1506                         /* Already have or am bring up an association */
1507                         SCTP_ASOC_CREATE_UNLOCK(inp);
1508                         SCTP_TCB_UNLOCK(stcb);
1509                         crit_exit();
1510                         return (EALREADY);
1511                 }
1512                 if ((at + incr) > m->m_len) {
1513                         totaddr = i;
1514                         break;
1515                 }
1516                 sa = (struct sockaddr *)((caddr_t)sa + incr);
1517         }
1518         sa = (struct sockaddr *)(totaddrp + 1);
1519         SCTP_INP_WLOCK(inp);
1520         SCTP_INP_DECR_REF(inp);
1521         SCTP_INP_WUNLOCK(inp);
1522 #ifdef INET6
1523         if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) &&
1524             (num_v6 > 0)) {
1525                 crit_exit();
1526                 SCTP_INP_WUNLOCK(inp);
1527                 SCTP_ASOC_CREATE_UNLOCK(inp);
1528                 return (EINVAL);
1529         }
1530         if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
1531             (num_v4 > 0)) {
1532                 struct in6pcb *inp6;
1533                 inp6 = (struct in6pcb *)inp;
1534                 if (
1535 #if defined(__OpenBSD__)
1536                         (0) /* we always do dual bind */
1537 #elif defined (__NetBSD__)
1538                         (inp6->in6p_flags & IN6P_IPV6_V6ONLY)
1539 #else
1540                         (inp6->inp_flags & IN6P_IPV6_V6ONLY)
1541 #endif
1542                         ) {
1543                         /*
1544                          * if IPV6_V6ONLY flag, ignore connections
1545                          * destined to a v4 addr or v4-mapped addr
1546                          */
1547                         SCTP_INP_WUNLOCK(inp);
1548                         SCTP_ASOC_CREATE_UNLOCK(inp);
1549                         crit_exit();
1550                         return EINVAL;
1551                 }
1552         }
1553 #endif /* INET6 */
1554         if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) ==
1555             SCTP_PCB_FLAGS_UNBOUND) {
1556                 /* Bind a ephemeral port */
1557                 SCTP_INP_WUNLOCK(inp);
1558                 error = sctp_inpcb_bind(so, NULL, p);
1559                 if (error) {
1560                         SCTP_ASOC_CREATE_UNLOCK(inp);
1561                         crit_exit();
1562                         return (error);
1563                 }
1564         } else {
1565                 SCTP_INP_WUNLOCK(inp);
1566         }
1567         /* We are GOOD to go */
1568         stcb = sctp_aloc_assoc(inp, sa, 1, &error, 0);
1569         if (stcb == NULL) {
1570                 /* Gak! no memory */
1571                 SCTP_ASOC_CREATE_UNLOCK(inp);
1572                 crit_exit();
1573                 return (error);
1574         }
1575         /* move to second address */
1576         if (sa->sa_family == AF_INET)
1577                 sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in));
1578         else
1579                 sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in6));
1580
1581         for (i = 1; i < totaddr; i++) {
1582                 if (sa->sa_family == AF_INET) {
1583                         incr = sizeof(struct sockaddr_in);
1584                         if (sctp_add_remote_addr(stcb, sa, 0, 8)) {
1585                                 /* assoc gone no un-lock */
1586                                 sctp_free_assoc(inp, stcb);
1587                                 SCTP_ASOC_CREATE_UNLOCK(inp);
1588                                 crit_exit();
1589                                 return (ENOBUFS);
1590                         }
1591
1592                 } else if (sa->sa_family == AF_INET6) {
1593                         incr = sizeof(struct sockaddr_in6);
1594                         if (sctp_add_remote_addr(stcb, sa, 0, 8)) {
1595                                 /* assoc gone no un-lock */
1596                                 sctp_free_assoc(inp, stcb);
1597                                 SCTP_ASOC_CREATE_UNLOCK(inp);
1598                                 crit_exit();
1599                                 return (ENOBUFS);
1600                         }
1601                 }
1602                 sa = (struct sockaddr *)((caddr_t)sa + incr);
1603         }
1604         stcb->asoc.state = SCTP_STATE_COOKIE_WAIT;
1605         if (delay) {
1606                 /* doing delayed connection */
1607                 stcb->asoc.delayed_connection = 1;
1608                 sctp_timer_start(SCTP_TIMER_TYPE_INIT, inp, stcb, stcb->asoc.primary_destination);
1609         } else {
1610                 SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered);
1611                 sctp_send_initiate(inp, stcb);
1612         }
1613         SCTP_TCB_UNLOCK(stcb);
1614         if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) {
1615                 stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED;
1616                 /* Set the connected flag so we can queue data */
1617                 soisconnecting(so);
1618         }
1619         SCTP_ASOC_CREATE_UNLOCK(inp);
1620         crit_exit();
1621         return error;
1622 }
1623
1624
1625 static int
1626 sctp_optsget(struct socket *so,
1627              int opt,
1628              struct mbuf **mp,
1629 #if (defined(__FreeBSD__) && __FreeBSD_version >= 500000) || defined(__DragonFly__)
1630              struct thread *p
1631 #else
1632              struct proc *p
1633 #endif
1634         )
1635 {
1636         struct sctp_inpcb *inp;
1637         struct mbuf *m;
1638         int error, optval=0;
1639         struct sctp_tcb *stcb = NULL;
1640
1641         inp = (struct sctp_inpcb *)so->so_pcb;
1642         if (inp == 0)
1643                 return EINVAL;
1644         error = 0;
1645
1646         if (mp == NULL) {
1647 #ifdef SCTP_DEBUG
1648                 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
1649                         kprintf("optsget:MP is NULL EINVAL\n");
1650                 }
1651 #endif /* SCTP_DEBUG */
1652                 return (EINVAL);
1653         }
1654         m = *mp;
1655         if (m == NULL) {
1656                 /* Got to have a mbuf */
1657 #ifdef SCTP_DEBUG
1658                 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
1659                         kprintf("Huh no mbuf\n");
1660                 }
1661 #endif /* SCTP_DEBUG */
1662                 return (EINVAL);
1663         }
1664 #ifdef SCTP_DEBUG
1665         if (sctp_debug_on & SCTP_DEBUG_USRREQ2) {
1666                 kprintf("optsget opt:%lxx sz:%u\n", (unsigned long)opt,
1667                        m->m_len);
1668         }
1669 #endif /* SCTP_DEBUG */
1670
1671         switch (opt) {
1672         case SCTP_NODELAY:
1673         case SCTP_AUTOCLOSE:
1674         case SCTP_AUTO_ASCONF:
1675         case SCTP_DISABLE_FRAGMENTS:
1676         case SCTP_I_WANT_MAPPED_V4_ADDR:
1677 #ifdef SCTP_DEBUG
1678                 if (sctp_debug_on & SCTP_DEBUG_USRREQ2) {
1679                         kprintf("other stuff\n");
1680                 }
1681 #endif /* SCTP_DEBUG */
1682                 SCTP_INP_RLOCK(inp);
1683                 switch (opt) {
1684                 case SCTP_DISABLE_FRAGMENTS:
1685                         optval = inp->sctp_flags & SCTP_PCB_FLAGS_NO_FRAGMENT;
1686                         break;
1687                 case SCTP_I_WANT_MAPPED_V4_ADDR:
1688                         optval = inp->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4;
1689                         break;
1690                 case SCTP_AUTO_ASCONF:
1691                         optval = inp->sctp_flags & SCTP_PCB_FLAGS_AUTO_ASCONF;
1692                         break;
1693                 case SCTP_NODELAY:
1694                         optval = inp->sctp_flags & SCTP_PCB_FLAGS_NODELAY;
1695                         break;
1696                 case SCTP_AUTOCLOSE:
1697                         if ((inp->sctp_flags & SCTP_PCB_FLAGS_AUTOCLOSE) ==
1698                             SCTP_PCB_FLAGS_AUTOCLOSE)
1699                                 optval = inp->sctp_ep.auto_close_time;
1700                         else
1701                                 optval = 0;
1702                         break;
1703
1704                 default:
1705                         error = ENOPROTOOPT;
1706                 } /* end switch (sopt->sopt_name) */
1707                 if (opt != SCTP_AUTOCLOSE) {
1708                         /* make it an "on/off" value */
1709                         optval = (optval != 0);
1710                 }
1711                 if ((size_t)m->m_len < sizeof(int)) {
1712                         error = EINVAL;
1713                 }
1714                 SCTP_INP_RUNLOCK(inp);
1715                 if (error == 0) {
1716                         /* return the option value */
1717                         *mtod(m, int *) = optval;
1718                         m->m_len = sizeof(optval);
1719                 }
1720                 break;
1721         case SCTP_GET_ASOC_ID_LIST:
1722         {
1723                 struct sctp_assoc_ids *ids;
1724                 int cnt, at;
1725                 u_int16_t orig;
1726
1727                 if ((size_t)m->m_len < sizeof(struct sctp_assoc_ids)) {
1728                         error = EINVAL;
1729                         break;
1730                 }
1731                 ids = mtod(m, struct sctp_assoc_ids *);
1732                 cnt = 0;
1733                 SCTP_INP_RLOCK(inp);
1734                 stcb = LIST_FIRST(&inp->sctp_asoc_list);
1735                 if (stcb == NULL) {
1736                 none_out_now:
1737                         ids->asls_numb_present = 0;
1738                         ids->asls_more_to_get = 0;
1739                         SCTP_INP_RUNLOCK(inp);
1740                         break;
1741                 }
1742                 orig = ids->asls_assoc_start;
1743                 stcb = LIST_FIRST(&inp->sctp_asoc_list);
1744                 while( orig ) {
1745                         stcb = LIST_NEXT(stcb , sctp_tcblist);
1746                         orig--;
1747                         cnt--;
1748                 }
1749                 if ( stcb == NULL)
1750                         goto none_out_now;
1751
1752                 at = 0;
1753                 ids->asls_numb_present = 0;
1754                 ids->asls_more_to_get = 1;
1755                 while(at < MAX_ASOC_IDS_RET) {
1756                         ids->asls_assoc_id[at] = sctp_get_associd(stcb);
1757                         at++;
1758                         ids->asls_numb_present++;
1759                         stcb = LIST_NEXT(stcb , sctp_tcblist);
1760                         if (stcb == NULL) {
1761                                 ids->asls_more_to_get = 0;
1762                                 break;
1763                         }
1764                 }
1765                 SCTP_INP_RUNLOCK(inp);
1766         }
1767         break;
1768         case SCTP_GET_NONCE_VALUES:
1769         {
1770                 struct sctp_get_nonce_values *gnv;
1771                 if ((size_t)m->m_len < sizeof(struct sctp_get_nonce_values)) {
1772                         error = EINVAL;
1773                         break;
1774                 }
1775                 gnv = mtod(m, struct sctp_get_nonce_values *);
1776                 stcb = sctp_findassociation_ep_asocid(inp, gnv->gn_assoc_id);
1777                 if (stcb == NULL) {
1778                         error = ENOTCONN;
1779                 } else {
1780                         gnv->gn_peers_tag = stcb->asoc.peer_vtag;
1781                         gnv->gn_local_tag = stcb->asoc.my_vtag;
1782                         SCTP_TCB_UNLOCK(stcb);
1783                 }
1784
1785         }
1786         break;
1787         case SCTP_PEER_PUBLIC_KEY:
1788         case SCTP_MY_PUBLIC_KEY:
1789         case SCTP_SET_AUTH_CHUNKS:
1790         case SCTP_SET_AUTH_SECRET:
1791                 /* not supported yet and until we refine the draft */
1792                 error = EOPNOTSUPP;
1793                 break;
1794
1795         case SCTP_DELAYED_ACK_TIME:
1796         {
1797                 int32_t *tm;
1798                 if ((size_t)m->m_len < sizeof(int32_t)) {
1799                         error = EINVAL;
1800                         break;
1801                 }
1802                 tm = mtod(m, int32_t *);
1803
1804                 *tm = TICKS_TO_MSEC(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV]);
1805         }
1806         break;
1807
1808         case SCTP_GET_SNDBUF_USE:
1809                 if ((size_t)m->m_len < sizeof(struct sctp_sockstat)) {
1810                         error = EINVAL;
1811                 } else {
1812                         struct sctp_sockstat *ss;
1813                         struct sctp_tcb *stcb;
1814                         struct sctp_association *asoc;
1815                         ss = mtod(m, struct sctp_sockstat *);
1816                         stcb = sctp_findassociation_ep_asocid(inp, ss->ss_assoc_id);
1817                         if (stcb == NULL) {
1818                                 error = ENOTCONN;
1819                         } else {
1820                                 asoc = &stcb->asoc;
1821                                 ss->ss_total_sndbuf = (u_int32_t)asoc->total_output_queue_size;
1822                                 ss->ss_total_mbuf_sndbuf = (u_int32_t)asoc->total_output_mbuf_queue_size;
1823                                 ss->ss_total_recv_buf = (u_int32_t)(asoc->size_on_delivery_queue +
1824                                                                     asoc->size_on_reasm_queue +
1825                                                                     asoc->size_on_all_streams);
1826                                 SCTP_TCB_UNLOCK(stcb);
1827                                 error = 0;
1828                                 m->m_len = sizeof(struct sctp_sockstat);
1829                         }
1830                 }
1831                 break;
1832         case SCTP_MAXBURST:
1833         {
1834                 u_int8_t *burst;
1835                 burst = mtod(m, u_int8_t *);
1836                 SCTP_INP_RLOCK(inp);
1837                 *burst = inp->sctp_ep.max_burst;
1838                 SCTP_INP_RUNLOCK(inp);
1839                 m->m_len = sizeof(u_int8_t);
1840         }
1841         break;
1842         case SCTP_MAXSEG:
1843         {
1844                 u_int32_t *segsize;
1845                 sctp_assoc_t *assoc_id;
1846                 int ovh;
1847
1848                 if ((size_t)m->m_len < sizeof(u_int32_t)) {
1849                         error = EINVAL;
1850                         break;
1851                 }
1852                 if ((size_t)m->m_len < sizeof(sctp_assoc_t)) {
1853                         error = EINVAL;
1854                         break;
1855                 }
1856                 assoc_id = mtod(m, sctp_assoc_t *);
1857                 segsize = mtod(m, u_int32_t *);
1858                 m->m_len = sizeof(u_int32_t);
1859
1860                 if (((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
1861                      (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) ||
1862                     (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
1863                         struct sctp_tcb *stcb;
1864                         SCTP_INP_RLOCK(inp);
1865                         stcb = LIST_FIRST(&inp->sctp_asoc_list);
1866                         if (stcb) {
1867                                 SCTP_TCB_LOCK(stcb);
1868                                 SCTP_INP_RUNLOCK(inp);
1869                                 *segsize = sctp_get_frag_point(stcb, &stcb->asoc);
1870                                 SCTP_TCB_UNLOCK(stcb);
1871                         } else {
1872                                 SCTP_INP_RUNLOCK(inp);
1873                                 goto skipit;
1874                         }
1875                 } else {
1876                         stcb = sctp_findassociation_ep_asocid(inp, *assoc_id);
1877                         if (stcb) {
1878                                 *segsize = sctp_get_frag_point(stcb, &stcb->asoc);
1879                                 SCTP_TCB_UNLOCK(stcb);
1880                                 break;
1881                         }
1882                 skipit:
1883                         /* default is to get the max, if I
1884                          * can't calculate from an existing association.
1885                          */
1886                         if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
1887                                 ovh = SCTP_MED_OVERHEAD;
1888                         } else {
1889                                 ovh = SCTP_MED_V4_OVERHEAD;
1890                         }
1891                         *segsize = inp->sctp_frag_point - ovh;
1892                 }
1893         }
1894         break;
1895
1896         case SCTP_SET_DEBUG_LEVEL:
1897 #ifdef SCTP_DEBUG
1898         {
1899                 u_int32_t *level;
1900                 if ((size_t)m->m_len < sizeof(u_int32_t)) {
1901                         error = EINVAL;
1902                         break;
1903                 }
1904                 level = mtod(m, u_int32_t *);
1905                 error = 0;
1906                 *level = sctp_debug_on;
1907                 m->m_len = sizeof(u_int32_t);
1908                 kprintf("Returning DEBUG LEVEL %x is set\n",
1909                        (u_int)sctp_debug_on);
1910         }
1911 #else /* SCTP_DEBUG */
1912         error = EOPNOTSUPP;
1913 #endif
1914         break;
1915         case SCTP_GET_STAT_LOG:
1916 #ifdef SCTP_STAT_LOGGING
1917                 error = sctp_fill_stat_log(m);
1918 #else /* SCTP_DEBUG */
1919                 error = EOPNOTSUPP;
1920 #endif
1921                 break;
1922         case SCTP_GET_PEGS:
1923         {
1924                 u_int32_t *pt;
1925                 if ((size_t)m->m_len < sizeof(sctp_pegs)) {
1926                         error = EINVAL;
1927                         break;
1928                 }
1929                 pt = mtod(m, u_int32_t *);
1930                 memcpy(pt, sctp_pegs, sizeof(sctp_pegs));
1931                 m->m_len = sizeof(sctp_pegs);
1932         }
1933         break;
1934         case SCTP_EVENTS:
1935         {
1936                 struct sctp_event_subscribe *events;
1937 #ifdef SCTP_DEBUG
1938                 if (sctp_debug_on & SCTP_DEBUG_USRREQ2) {
1939                         kprintf("get events\n");
1940                 }
1941 #endif /* SCTP_DEBUG */
1942                 if ((size_t)m->m_len < sizeof(struct sctp_event_subscribe)) {
1943 #ifdef SCTP_DEBUG
1944                         if (sctp_debug_on & SCTP_DEBUG_USRREQ2) {
1945                                 kprintf("M->M_LEN is %d not %d\n",
1946                                        (int)m->m_len,
1947                                        (int)sizeof(struct sctp_event_subscribe));
1948                         }
1949 #endif /* SCTP_DEBUG */
1950                         error = EINVAL;
1951                         break;
1952                 }
1953                 events = mtod(m, struct sctp_event_subscribe *);
1954                 memset(events, 0, sizeof(events));
1955                 SCTP_INP_RLOCK(inp);
1956                 if (inp->sctp_flags & SCTP_PCB_FLAGS_RECVDATAIOEVNT)
1957                         events->sctp_data_io_event = 1;
1958
1959                 if (inp->sctp_flags & SCTP_PCB_FLAGS_RECVASSOCEVNT)
1960                         events->sctp_association_event = 1;
1961
1962                 if (inp->sctp_flags & SCTP_PCB_FLAGS_RECVPADDREVNT)
1963                         events->sctp_address_event = 1;
1964
1965                 if (inp->sctp_flags & SCTP_PCB_FLAGS_RECVSENDFAILEVNT)
1966                         events->sctp_send_failure_event = 1;
1967
1968                 if (inp->sctp_flags & SCTP_PCB_FLAGS_RECVPEERERR)
1969                         events->sctp_peer_error_event = 1;
1970
1971                 if (inp->sctp_flags & SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT)
1972                         events->sctp_shutdown_event = 1;
1973
1974                 if (inp->sctp_flags & SCTP_PCB_FLAGS_PDAPIEVNT)
1975                         events->sctp_partial_delivery_event = 1;
1976
1977                 if (inp->sctp_flags & SCTP_PCB_FLAGS_ADAPTIONEVNT)
1978                         events->sctp_adaption_layer_event = 1;
1979
1980                 if (inp->sctp_flags & SCTP_PCB_FLAGS_STREAM_RESETEVNT)
1981                         events->sctp_stream_reset_events = 1;
1982                 SCTP_INP_RUNLOCK(inp);
1983                 m->m_len = sizeof(struct sctp_event_subscribe);
1984
1985         }
1986         break;
1987
1988         case SCTP_ADAPTION_LAYER:
1989                 if ((size_t)m->m_len < sizeof(int)) {
1990                         error = EINVAL;
1991                         break;
1992                 }
1993 #ifdef SCTP_DEBUG
1994                 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
1995                         kprintf("getadaption ind\n");
1996                 }
1997 #endif /* SCTP_DEBUG */
1998                 SCTP_INP_RLOCK(inp);
1999                 *mtod(m, int *) = inp->sctp_ep.adaption_layer_indicator;
2000                 SCTP_INP_RUNLOCK(inp);
2001                 m->m_len = sizeof(int);
2002                 break;
2003         case SCTP_SET_INITIAL_DBG_SEQ:
2004                 if ((size_t)m->m_len < sizeof(int)) {
2005                         error = EINVAL;
2006                         break;
2007                 }
2008 #ifdef SCTP_DEBUG
2009                 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
2010                         kprintf("get initial dbg seq\n");
2011                 }
2012 #endif /* SCTP_DEBUG */
2013                 SCTP_INP_RLOCK(inp);
2014                 *mtod(m, int *) = inp->sctp_ep.initial_sequence_debug;
2015                 SCTP_INP_RUNLOCK(inp);
2016                 m->m_len = sizeof(int);
2017                 break;
2018         case SCTP_GET_LOCAL_ADDR_SIZE:
2019                 if ((size_t)m->m_len < sizeof(int)) {
2020                         error = EINVAL;
2021                         break;
2022                 }
2023 #ifdef SCTP_DEBUG
2024                 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
2025                         kprintf("get local sizes\n");
2026                 }
2027 #endif /* SCTP_DEBUG */
2028                 SCTP_INP_RLOCK(inp);
2029                 *mtod(m, int *) = sctp_count_max_addresses(inp);
2030                 SCTP_INP_RUNLOCK(inp);
2031                 m->m_len = sizeof(int);
2032                 break;
2033         case SCTP_GET_REMOTE_ADDR_SIZE:
2034         {
2035                 sctp_assoc_t *assoc_id;
2036                 u_int32_t *val, sz;
2037                 struct sctp_nets *net;
2038 #ifdef SCTP_DEBUG
2039                 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
2040                         kprintf("get remote size\n");
2041                 }
2042 #endif /* SCTP_DEBUG */
2043                 if ((size_t)m->m_len < sizeof(sctp_assoc_t)) {
2044 #ifdef SCTP_DEBUG
2045                         kprintf("m->m_len:%d not %d\n",
2046                                m->m_len, sizeof(sctp_assoc_t));
2047 #endif /* SCTP_DEBUG */
2048                         error = EINVAL;
2049                         break;
2050                 }
2051                 stcb = NULL;
2052                 val = mtod(m, u_int32_t *);
2053                 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2054                         SCTP_INP_RLOCK(inp);
2055                         stcb = LIST_FIRST(&inp->sctp_asoc_list);
2056                         if (stcb)
2057                                 SCTP_TCB_LOCK(stcb);
2058                         SCTP_INP_RUNLOCK(inp);
2059                 }
2060                 if (stcb == NULL) {
2061                         assoc_id = mtod(m, sctp_assoc_t *);
2062                         stcb = sctp_findassociation_ep_asocid(inp, *assoc_id);
2063                 }
2064
2065                 if (stcb == NULL) {
2066                         error = EINVAL;
2067                         break;
2068                 }
2069                 *val = 0;
2070                 sz = 0;
2071                 /* Count the sizes */
2072                 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
2073                         if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) ||
2074                             (((struct sockaddr *)&net->ro._l_addr)->sa_family == AF_INET6)) {
2075                                 sz += sizeof(struct sockaddr_in6);
2076                         } else if (((struct sockaddr *)&net->ro._l_addr)->sa_family == AF_INET) {
2077                                 sz += sizeof(struct sockaddr_in);
2078                         } else {
2079                                 /* huh */
2080                                 break;
2081                         }
2082                 }
2083                 SCTP_TCB_UNLOCK(stcb);
2084                 *val = sz;
2085                 m->m_len = sizeof(u_int32_t);
2086         }
2087         break;
2088         case SCTP_GET_PEER_ADDRESSES:
2089                 /*
2090                  * Get the address information, an array
2091                  * is passed in to fill up we pack it.
2092                  */
2093         {
2094                 int cpsz, left;
2095                 struct sockaddr_storage *sas;
2096                 struct sctp_nets *net;
2097                 struct sctp_getaddresses *saddr;
2098 #ifdef SCTP_DEBUG
2099                 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
2100                         kprintf("get peer addresses\n");
2101                 }
2102 #endif /* SCTP_DEBUG */
2103                 if ((size_t)m->m_len < sizeof(struct sctp_getaddresses)) {
2104                         error = EINVAL;
2105                         break;
2106                 }
2107                 left = m->m_len - sizeof(struct sctp_getaddresses);
2108                 saddr = mtod(m, struct sctp_getaddresses *);
2109                 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2110                         SCTP_INP_RLOCK(inp);
2111                         stcb = LIST_FIRST(&inp->sctp_asoc_list);
2112                         if (stcb)
2113                                 SCTP_TCB_LOCK(stcb);
2114                         SCTP_INP_RUNLOCK(inp);
2115                 } else
2116                         stcb = sctp_findassociation_ep_asocid(inp,
2117                                                               saddr->sget_assoc_id);
2118                 if (stcb == NULL) {
2119                         error = ENOENT;
2120                         break;
2121                 }
2122                 m->m_len = sizeof(struct sctp_getaddresses);
2123                 sas = (struct sockaddr_storage *)&saddr->addr[0];
2124
2125                 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
2126                         if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) ||
2127                             (((struct sockaddr *)&net->ro._l_addr)->sa_family == AF_INET6)) {
2128                                 cpsz = sizeof(struct sockaddr_in6);
2129                         } else if (((struct sockaddr *)&net->ro._l_addr)->sa_family == AF_INET) {
2130                                 cpsz = sizeof(struct sockaddr_in);
2131                         } else {
2132                                 /* huh */
2133                                 break;
2134                         }
2135                         if (left < cpsz) {
2136                                 /* not enough room. */
2137 #ifdef SCTP_DEBUG
2138                                 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
2139                                         kprintf("Out of room\n");
2140                                 }
2141 #endif /* SCTP_DEBUG */
2142                                 break;
2143                         }
2144                         if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
2145                             (((struct sockaddr *)&net->ro._l_addr)->sa_family == AF_INET)) {
2146                                 /* Must map the address */
2147                                 in6_sin_2_v4mapsin6((struct sockaddr_in *)&net->ro._l_addr,
2148                                                     (struct sockaddr_in6 *)sas);
2149                         } else {
2150                                 memcpy(sas, &net->ro._l_addr, cpsz);
2151                         }
2152                         ((struct sockaddr_in *)sas)->sin_port = stcb->rport;
2153
2154                         sas = (struct sockaddr_storage *)((caddr_t)sas + cpsz);
2155                         left -= cpsz;
2156                         m->m_len += cpsz;
2157 #ifdef SCTP_DEBUG
2158                         if (sctp_debug_on & SCTP_DEBUG_USRREQ2) {
2159                                 kprintf("left now:%d mlen:%d\n",
2160                                        left, m->m_len);
2161                         }
2162 #endif /* SCTP_DEBUG */
2163                 }
2164                 SCTP_TCB_UNLOCK(stcb);
2165         }
2166 #ifdef SCTP_DEBUG
2167         if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
2168                 kprintf("All done\n");
2169         }
2170 #endif /* SCTP_DEBUG */
2171         break;
2172         case SCTP_GET_LOCAL_ADDRESSES:
2173         {
2174                 int limit, actual;
2175                 struct sockaddr_storage *sas;
2176                 struct sctp_getaddresses *saddr;
2177 #ifdef SCTP_DEBUG
2178                 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
2179                         kprintf("get local addresses\n");
2180                 }
2181 #endif /* SCTP_DEBUG */
2182                 if ((size_t)m->m_len < sizeof(struct sctp_getaddresses)) {
2183                         error = EINVAL;
2184                         break;
2185                 }
2186                 saddr = mtod(m, struct sctp_getaddresses *);
2187
2188                 if (saddr->sget_assoc_id) {
2189                         if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2190                                 SCTP_INP_RLOCK(inp);
2191                                 stcb = LIST_FIRST(&inp->sctp_asoc_list);
2192                                 if (stcb)
2193                                         SCTP_TCB_LOCK(stcb);
2194                                 SCTP_INP_RUNLOCK(inp);
2195                         } else
2196                                 stcb = sctp_findassociation_ep_asocid(inp, saddr->sget_assoc_id);
2197
2198                 } else {
2199                         stcb = NULL;
2200                 }
2201                 /*
2202                  * assure that the TCP model does not need a assoc id
2203                  * once connected.
2204                  */
2205                 if ( (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) &&
2206                      (stcb == NULL) ) {
2207                         SCTP_INP_RLOCK(inp);
2208                         stcb = LIST_FIRST(&inp->sctp_asoc_list);
2209                         if (stcb)
2210                                 SCTP_TCB_LOCK(stcb);
2211                         SCTP_INP_RUNLOCK(inp);
2212                 }
2213                 sas = (struct sockaddr_storage *)&saddr->addr[0];
2214                 limit = m->m_len - sizeof(sctp_assoc_t);
2215                 actual = sctp_fill_up_addresses(inp, stcb, limit, sas);
2216                 SCTP_TCB_UNLOCK(stcb);
2217                 m->m_len = sizeof(struct sockaddr_storage) + actual;
2218         }
2219         break;
2220         case SCTP_PEER_ADDR_PARAMS:
2221         {
2222                 struct sctp_paddrparams *paddrp;
2223                 struct sctp_nets *net;
2224
2225 #ifdef SCTP_DEBUG
2226                 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
2227                         kprintf("Getting peer_addr_params\n");
2228                 }
2229 #endif /* SCTP_DEBUG */
2230                 if ((size_t)m->m_len < sizeof(struct sctp_paddrparams)) {
2231 #ifdef SCTP_DEBUG
2232                         if (sctp_debug_on & SCTP_DEBUG_USRREQ2) {
2233                                 kprintf("Hmm m->m_len:%d is to small\n",
2234                                        m->m_len);
2235                         }
2236 #endif /* SCTP_DEBUG */
2237                         error = EINVAL;
2238                         break;
2239                 }
2240                 paddrp = mtod(m, struct sctp_paddrparams *);
2241
2242                 net = NULL;
2243                 if (paddrp->spp_assoc_id) {
2244 #ifdef SCTP_DEBUG
2245                         if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
2246                                 kprintf("In spp_assoc_id find type\n");
2247                         }
2248 #endif /* SCTP_DEBUG */
2249                         if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2250                                 SCTP_INP_RLOCK(inp);
2251                                 stcb = LIST_FIRST(&inp->sctp_asoc_list);
2252                                 if (stcb) {
2253                                         SCTP_TCB_LOCK(stcb);
2254                                         net = sctp_findnet(stcb, (struct sockaddr *)&paddrp->spp_address);
2255                                 }
2256                                 SCTP_INP_RLOCK(inp);
2257                         } else {
2258                                 stcb = sctp_findassociation_ep_asocid(inp, paddrp->spp_assoc_id);
2259                         }
2260                         if (stcb == NULL) {
2261                                 error = ENOENT;
2262                                 break;
2263                         }
2264                 }
2265                 if (    (stcb == NULL) &&
2266                         ((((struct sockaddr *)&paddrp->spp_address)->sa_family == AF_INET) ||
2267                          (((struct sockaddr *)&paddrp->spp_address)->sa_family == AF_INET6))) {
2268                         /* Lookup via address */
2269 #ifdef SCTP_DEBUG
2270                         if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
2271                                 kprintf("Ok we need to lookup a param\n");
2272                         }
2273 #endif /* SCTP_DEBUG */
2274                         if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2275                                 SCTP_INP_RLOCK(inp);
2276                                 stcb = LIST_FIRST(&inp->sctp_asoc_list);
2277                                 if (stcb) {
2278                                         SCTP_TCB_LOCK(stcb);
2279                                         net = sctp_findnet(stcb, (struct sockaddr *)&paddrp->spp_address);
2280                                 }
2281                                 SCTP_INP_RUNLOCK(inp);
2282                         } else {
2283                                 SCTP_INP_WLOCK(inp);
2284                                 SCTP_INP_INCR_REF(inp);
2285                                 SCTP_INP_WUNLOCK(inp);
2286                                 stcb = sctp_findassociation_ep_addr(&inp,
2287                                                                     (struct sockaddr *)&paddrp->spp_address,
2288                                                                     &net, NULL, NULL);
2289                                 if (stcb == NULL) {
2290                                         SCTP_INP_WLOCK(inp);
2291                                         SCTP_INP_DECR_REF(inp);
2292                                         SCTP_INP_WUNLOCK(inp);
2293                                 }
2294                         }
2295
2296                         if (stcb == NULL) {
2297                                 error = ENOENT;
2298                                 break;
2299                         }
2300                 } else {
2301                         /* Effects the Endpoint */
2302 #ifdef SCTP_DEBUG
2303                         if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
2304                                 kprintf("User wants EP level info\n");
2305                         }
2306 #endif /* SCTP_DEBUG */
2307                         stcb = NULL;
2308                 }
2309                 if (stcb) {
2310                         /* Applys to the specific association */
2311 #ifdef SCTP_DEBUG
2312                         if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
2313                                 kprintf("In TCB side\n");
2314                         }
2315 #endif /* SCTP_DEBUG */
2316                         if (net) {
2317                                 paddrp->spp_pathmaxrxt = net->failure_threshold;
2318                         } else {
2319                                 /* No destination so return default value */
2320                                 paddrp->spp_pathmaxrxt = stcb->asoc.def_net_failure;
2321                         }
2322                         paddrp->spp_hbinterval = stcb->asoc.heart_beat_delay;
2323                         paddrp->spp_assoc_id = sctp_get_associd(stcb);
2324                         SCTP_TCB_UNLOCK(stcb);
2325                 } else {
2326                         /* Use endpoint defaults */
2327                         SCTP_INP_RLOCK(inp);
2328 #ifdef SCTP_DEBUG
2329                         if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
2330                                 kprintf("In EP level info\n");
2331                         }
2332 #endif /* SCTP_DEBUG */
2333                         paddrp->spp_pathmaxrxt = inp->sctp_ep.def_net_failure;
2334                         paddrp->spp_hbinterval = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT];
2335                         paddrp->spp_assoc_id = (sctp_assoc_t)0;
2336                         SCTP_INP_RUNLOCK(inp);
2337                 }
2338                 m->m_len = sizeof(struct sctp_paddrparams);
2339         }
2340         break;
2341         case SCTP_GET_PEER_ADDR_INFO:
2342         {
2343                 struct sctp_paddrinfo *paddri;
2344                 struct sctp_nets *net;
2345 #ifdef SCTP_DEBUG
2346                 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
2347                         kprintf("GetPEER ADDR_INFO\n");
2348                 }
2349 #endif /* SCTP_DEBUG */
2350                 if ((size_t)m->m_len < sizeof(struct sctp_paddrinfo)) {
2351                         error = EINVAL;
2352                         break;
2353                 }
2354                 paddri = mtod(m, struct sctp_paddrinfo *);
2355                 net = NULL;
2356                 if ((((struct sockaddr *)&paddri->spinfo_address)->sa_family == AF_INET) ||
2357                     (((struct sockaddr *)&paddri->spinfo_address)->sa_family == AF_INET6)) {
2358                         /* Lookup via address */
2359                         if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2360                                 SCTP_INP_RLOCK(inp);
2361                                 stcb = LIST_FIRST(&inp->sctp_asoc_list);
2362                                 if (stcb) {
2363                                         SCTP_TCB_LOCK(stcb);
2364                                         net = sctp_findnet(stcb,
2365                                                             (struct sockaddr *)&paddri->spinfo_address);
2366                                 }
2367                                 SCTP_INP_RUNLOCK(inp);
2368                         } else {
2369                                 SCTP_INP_WLOCK(inp);
2370                                 SCTP_INP_INCR_REF(inp);
2371                                 SCTP_INP_WUNLOCK(inp);
2372                                 stcb = sctp_findassociation_ep_addr(&inp,
2373                                     (struct sockaddr *)&paddri->spinfo_address,
2374                                     &net, NULL, NULL);
2375                                 if (stcb == NULL) {
2376                                         SCTP_INP_WLOCK(inp);
2377                                         SCTP_INP_DECR_REF(inp);
2378                                         SCTP_INP_WUNLOCK(inp);
2379                                 }
2380                         }
2381
2382                 } else {
2383                         stcb = NULL;
2384                 }
2385                 if ((stcb == NULL) || (net == NULL)) {
2386                         error = ENOENT;
2387                         break;
2388                 }
2389                 m->m_len = sizeof(struct sctp_paddrinfo);
2390                 paddri->spinfo_state = net->dest_state & (SCTP_REACHABLE_MASK|SCTP_ADDR_NOHB);
2391                 paddri->spinfo_cwnd = net->cwnd;
2392                 paddri->spinfo_srtt = ((net->lastsa >> 2) + net->lastsv) >> 1;
2393                 paddri->spinfo_rto = net->RTO;
2394                 paddri->spinfo_assoc_id = sctp_get_associd(stcb);
2395                 SCTP_TCB_UNLOCK(stcb);
2396         }
2397         break;
2398         case SCTP_PCB_STATUS:
2399         {
2400                 struct sctp_pcbinfo *spcb;
2401 #ifdef SCTP_DEBUG
2402                 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
2403                         kprintf("PCB status\n");
2404                 }
2405 #endif /* SCTP_DEBUG */
2406                 if ((size_t)m->m_len < sizeof(struct sctp_pcbinfo)) {
2407                         error = EINVAL;
2408                         break;
2409                 }
2410                 spcb = mtod(m, struct sctp_pcbinfo *);
2411                 sctp_fill_pcbinfo(spcb);
2412                 m->m_len = sizeof(struct sctp_pcbinfo);
2413         }
2414         break;
2415         case SCTP_STATUS:
2416         {
2417                 struct sctp_nets *net;
2418                 struct sctp_status *sstat;
2419 #ifdef SCTP_DEBUG
2420                 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
2421                         kprintf("SCTP status\n");
2422                 }
2423 #endif /* SCTP_DEBUG */
2424
2425                 if ((size_t)m->m_len < sizeof(struct sctp_status)) {
2426                         error = EINVAL;
2427                         break;
2428                 }
2429                 sstat = mtod(m, struct sctp_status *);
2430
2431                 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2432                         SCTP_INP_RLOCK(inp);
2433                         stcb = LIST_FIRST(&inp->sctp_asoc_list);
2434                         if (stcb)
2435                                 SCTP_TCB_LOCK(stcb);
2436                         SCTP_INP_RUNLOCK(inp);
2437                 } else
2438                         stcb = sctp_findassociation_ep_asocid(inp, sstat->sstat_assoc_id);
2439
2440                 if (stcb == NULL) {
2441                         error = EINVAL;
2442                         break;
2443                 }
2444                 /*
2445                  * I think passing the state is fine since
2446                  * sctp_constants.h will be available to the user
2447                  * land.
2448                  */
2449                 sstat->sstat_state = stcb->asoc.state;
2450                 sstat->sstat_rwnd = stcb->asoc.peers_rwnd;
2451                 sstat->sstat_unackdata = stcb->asoc.sent_queue_cnt;
2452                 /*
2453                  * We can't include chunks that have been passed
2454                  * to the socket layer. Only things in queue.
2455                  */
2456                 sstat->sstat_penddata = (stcb->asoc.cnt_on_delivery_queue +
2457                                          stcb->asoc.cnt_on_reasm_queue +
2458                                          stcb->asoc.cnt_on_all_streams);
2459
2460
2461                 sstat->sstat_instrms = stcb->asoc.streamincnt;
2462                 sstat->sstat_outstrms = stcb->asoc.streamoutcnt;
2463                 sstat->sstat_fragmentation_point = sctp_get_frag_point(stcb, &stcb->asoc);
2464                 memcpy(&sstat->sstat_primary.spinfo_address,
2465                        &stcb->asoc.primary_destination->ro._l_addr,
2466                        ((struct sockaddr *)(&stcb->asoc.primary_destination->ro._l_addr))->sa_len);
2467                 net = stcb->asoc.primary_destination;
2468                 ((struct sockaddr_in *)&sstat->sstat_primary.spinfo_address)->sin_port = stcb->rport;
2469                 /*
2470                  * Again the user can get info from sctp_constants.h
2471                  * for what the state of the network is.
2472                  */
2473                 sstat->sstat_primary.spinfo_state = net->dest_state & SCTP_REACHABLE_MASK;
2474                 sstat->sstat_primary.spinfo_cwnd = net->cwnd;
2475                 sstat->sstat_primary.spinfo_srtt = net->lastsa;
2476                 sstat->sstat_primary.spinfo_rto = net->RTO;
2477                 sstat->sstat_primary.spinfo_mtu = net->mtu;
2478                 sstat->sstat_primary.spinfo_assoc_id = sctp_get_associd(stcb);
2479                 SCTP_TCB_UNLOCK(stcb);
2480                 m->m_len = sizeof(*sstat);
2481         }
2482         break;
2483         case SCTP_RTOINFO:
2484         {
2485                 struct sctp_rtoinfo *srto;
2486 #ifdef SCTP_DEBUG
2487                 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
2488                         kprintf("RTO Info\n");
2489                 }
2490 #endif /* SCTP_DEBUG */
2491                 if ((size_t)m->m_len < sizeof(struct sctp_rtoinfo)) {
2492                         error = EINVAL;
2493                         break;
2494                 }
2495                 srto = mtod(m, struct sctp_rtoinfo *);
2496                 if (srto->srto_assoc_id == 0) {
2497                         /* Endpoint only please */
2498                         SCTP_INP_RLOCK(inp);
2499                         srto->srto_initial = inp->sctp_ep.initial_rto;
2500                         srto->srto_max = inp->sctp_ep.sctp_maxrto;
2501                         srto->srto_min = inp->sctp_ep.sctp_minrto;
2502                         SCTP_INP_RUNLOCK(inp);
2503                         break;
2504                 }
2505                 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2506                         SCTP_INP_RLOCK(inp);
2507                         stcb = LIST_FIRST(&inp->sctp_asoc_list);
2508                         if (stcb)
2509                                 SCTP_TCB_LOCK(stcb);
2510                         SCTP_INP_RUNLOCK(inp);
2511                 } else
2512                         stcb = sctp_findassociation_ep_asocid(inp, srto->srto_assoc_id);
2513
2514                 if (stcb == NULL) {
2515                         error = EINVAL;
2516                         break;
2517                 }
2518                 srto->srto_initial = stcb->asoc.initial_rto;
2519                 srto->srto_max = stcb->asoc.maxrto;
2520                 srto->srto_min = stcb->asoc.minrto;
2521                 SCTP_TCB_UNLOCK(stcb);
2522                 m->m_len = sizeof(*srto);
2523         }
2524         break;
2525         case SCTP_ASSOCINFO:
2526         {
2527                 struct sctp_assocparams *sasoc;
2528 #ifdef SCTP_DEBUG
2529                 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
2530                         kprintf("Associnfo\n");
2531                 }
2532 #endif /* SCTP_DEBUG */
2533                 if ((size_t)m->m_len < sizeof(struct sctp_assocparams)) {
2534                         error = EINVAL;
2535                         break;
2536                 }
2537                 sasoc = mtod(m, struct sctp_assocparams *);
2538                 stcb = NULL;
2539
2540                 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2541                         SCTP_INP_RLOCK(inp);
2542                         stcb = LIST_FIRST(&inp->sctp_asoc_list);
2543                         if (stcb)
2544                                 SCTP_TCB_LOCK(stcb);
2545                         SCTP_INP_RUNLOCK(inp);
2546                 }
2547                 if ((sasoc->sasoc_assoc_id) && (stcb == NULL)) {
2548                         stcb = sctp_findassociation_ep_asocid(inp,
2549                                                              sasoc->sasoc_assoc_id);
2550                         if (stcb == NULL) {
2551                                 error = ENOENT;
2552                                 break;
2553                         }
2554                 } else {
2555                         stcb = NULL;
2556                 }
2557
2558                 if (stcb) {
2559                         sasoc->sasoc_asocmaxrxt = stcb->asoc.max_send_times;
2560                         sasoc->sasoc_number_peer_destinations = stcb->asoc.numnets;
2561                         sasoc->sasoc_peer_rwnd = stcb->asoc.peers_rwnd;
2562                         sasoc->sasoc_local_rwnd = stcb->asoc.my_rwnd;
2563                         sasoc->sasoc_cookie_life = stcb->asoc.cookie_life;
2564                         SCTP_TCB_UNLOCK(stcb);
2565                 } else {
2566                         SCTP_INP_RLOCK(inp);
2567                         sasoc->sasoc_asocmaxrxt = inp->sctp_ep.max_send_times;
2568                         sasoc->sasoc_number_peer_destinations = 0;
2569                         sasoc->sasoc_peer_rwnd = 0;
2570                         sasoc->sasoc_local_rwnd = ssb_space(&inp->sctp_socket->so_rcv);
2571                         sasoc->sasoc_cookie_life = inp->sctp_ep.def_cookie_life;
2572                         SCTP_INP_RUNLOCK(inp);
2573                 }
2574                 m->m_len = sizeof(*sasoc);
2575         }
2576         break;
2577         case SCTP_DEFAULT_SEND_PARAM:
2578         {
2579                 struct sctp_sndrcvinfo *s_info;
2580
2581                 if (m->m_len != sizeof(struct sctp_sndrcvinfo)) {
2582                         error = EINVAL;
2583                         break;
2584                 }
2585                 s_info = mtod(m, struct sctp_sndrcvinfo *);
2586                 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2587                         SCTP_INP_RLOCK(inp);
2588                         stcb = LIST_FIRST(&inp->sctp_asoc_list);
2589                         if (stcb)
2590                                 SCTP_TCB_LOCK(stcb);
2591                         SCTP_INP_RUNLOCK(inp);
2592                 } else
2593                         stcb = sctp_findassociation_ep_asocid(inp, s_info->sinfo_assoc_id);
2594
2595                 if (stcb == NULL) {
2596                         error = ENOENT;
2597                         break;
2598                 }
2599                 /* Copy it out */
2600                 *s_info = stcb->asoc.def_send;
2601                 SCTP_TCB_UNLOCK(stcb);
2602                 m->m_len = sizeof(*s_info);
2603         }
2604         case SCTP_INITMSG:
2605         {
2606                 struct sctp_initmsg *sinit;
2607 #ifdef SCTP_DEBUG
2608                 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
2609                         kprintf("initmsg\n");
2610                 }
2611 #endif /* SCTP_DEBUG */
2612                 if ((size_t)m->m_len < sizeof(struct sctp_initmsg)) {
2613                         error = EINVAL;
2614                         break;
2615                 }
2616                 sinit = mtod(m, struct sctp_initmsg *);
2617                 SCTP_INP_RLOCK(inp);
2618                 sinit->sinit_num_ostreams = inp->sctp_ep.pre_open_stream_count;
2619                 sinit->sinit_max_instreams = inp->sctp_ep.max_open_streams_intome;
2620                 sinit->sinit_max_attempts = inp->sctp_ep.max_init_times;
2621                 sinit->sinit_max_init_timeo = inp->sctp_ep.initial_init_rto_max;
2622                 SCTP_INP_RUNLOCK(inp);
2623                 m->m_len = sizeof(*sinit);
2624         }
2625         break;
2626         case SCTP_PRIMARY_ADDR:
2627                 /* we allow a "get" operation on this */
2628         {
2629                 struct sctp_setprim *ssp;
2630
2631 #ifdef SCTP_DEBUG
2632                 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
2633                         kprintf("setprimary\n");
2634                 }
2635 #endif /* SCTP_DEBUG */
2636                 if ((size_t)m->m_len < sizeof(struct sctp_setprim)) {
2637                         error = EINVAL;
2638                         break;
2639                 }
2640                 ssp = mtod(m, struct sctp_setprim *);
2641                 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2642                         SCTP_INP_RLOCK(inp);
2643                         stcb = LIST_FIRST(&inp->sctp_asoc_list);
2644                         if (stcb)
2645                                 SCTP_TCB_LOCK(stcb);
2646                         SCTP_INP_RUNLOCK(inp);
2647                 } else {
2648                         stcb = sctp_findassociation_ep_asocid(inp, ssp->ssp_assoc_id);
2649                         if (stcb == NULL) {
2650                                 /* one last shot, try it by the address in */
2651                                 struct sctp_nets *net;
2652
2653                                 SCTP_INP_WLOCK(inp);
2654                                 SCTP_INP_INCR_REF(inp);
2655                                 SCTP_INP_WUNLOCK(inp);
2656                                 stcb = sctp_findassociation_ep_addr(&inp,
2657                                                             (struct sockaddr *)&ssp->ssp_addr,
2658                                                             &net, NULL, NULL);
2659                                 if (stcb == NULL) {
2660                                         SCTP_INP_WLOCK(inp);
2661                                         SCTP_INP_DECR_REF(inp);
2662                                         SCTP_INP_WUNLOCK(inp);
2663                                 }
2664                         }
2665                         if (stcb == NULL) {
2666                                 error = EINVAL;
2667                                 break;
2668                         }
2669                 }
2670                 /* simply copy out the sockaddr_storage... */
2671                 memcpy(&ssp->ssp_addr,
2672                        &stcb->asoc.primary_destination->ro._l_addr,
2673                        ((struct sockaddr *)&stcb->asoc.primary_destination->ro._l_addr)->sa_len);
2674                 SCTP_TCB_UNLOCK(stcb);
2675                 m->m_len = sizeof(*ssp);
2676         }
2677         break;
2678         default:
2679                 error = ENOPROTOOPT;
2680                 m->m_len = 0;
2681                 break;
2682         } /* end switch (sopt->sopt_name) */
2683         return (error);
2684 }
2685
2686 static int
2687 sctp_optsset(struct socket *so,
2688              int opt,
2689              struct mbuf **mp,
2690 #if (defined(__FreeBSD__) && __FreeBSD_version >= 500000) || defined(__DragonFly__)
2691              struct thread *p
2692 #else
2693              struct proc *p
2694 #endif
2695         )
2696 {
2697         int error, *mopt, set_opt;
2698         struct mbuf *m;
2699         struct sctp_tcb *stcb = NULL;
2700         struct sctp_inpcb *inp;
2701
2702         if (mp == NULL) {
2703 #ifdef SCTP_DEBUG
2704                 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
2705                         kprintf("optsset:MP is NULL EINVAL\n");
2706                 }
2707 #endif /* SCTP_DEBUG */
2708                 return (EINVAL);
2709         }
2710         m = *mp;
2711         if (m == NULL)
2712                 return (EINVAL);
2713
2714         inp = (struct sctp_inpcb *)so->so_pcb;
2715         if (inp == 0)
2716                 return EINVAL;
2717
2718         error = 0;
2719         switch (opt) {
2720         case SCTP_NODELAY:
2721         case SCTP_AUTOCLOSE:
2722         case SCTP_AUTO_ASCONF:
2723         case SCTP_DISABLE_FRAGMENTS:
2724         case SCTP_I_WANT_MAPPED_V4_ADDR:
2725                 /* copy in the option value */
2726                 if ((size_t)m->m_len < sizeof(int)) {
2727                         error = EINVAL;
2728                         break;
2729                 }
2730                 mopt = mtod(m, int *);
2731                 set_opt = 0;
2732                 if (error)
2733                         break;
2734                 switch (opt) {
2735                 case SCTP_DISABLE_FRAGMENTS:
2736                         set_opt = SCTP_PCB_FLAGS_NO_FRAGMENT;
2737                         break;
2738                 case SCTP_AUTO_ASCONF:
2739                         set_opt = SCTP_PCB_FLAGS_AUTO_ASCONF;
2740                         break;
2741
2742                 case SCTP_I_WANT_MAPPED_V4_ADDR:
2743                         if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
2744                                 set_opt = SCTP_PCB_FLAGS_NEEDS_MAPPED_V4;
2745                         } else {
2746                                 return (EINVAL);
2747                         }
2748                         break;
2749                 case SCTP_NODELAY:
2750                         set_opt = SCTP_PCB_FLAGS_NODELAY;
2751                         break;
2752                 case SCTP_AUTOCLOSE:
2753                         set_opt = SCTP_PCB_FLAGS_AUTOCLOSE;
2754                         /*
2755                          * The value is in ticks.
2756                          * Note this does not effect old associations, only
2757                          * new ones.
2758                          */
2759                         inp->sctp_ep.auto_close_time = (*mopt * hz);
2760                         break;
2761                 }
2762                 SCTP_INP_WLOCK(inp);
2763                 if (*mopt != 0) {
2764                         inp->sctp_flags |= set_opt;
2765                 } else {
2766                         inp->sctp_flags &= ~set_opt;
2767                 }
2768                 SCTP_INP_WUNLOCK(inp);
2769                 break;
2770         case SCTP_MY_PUBLIC_KEY:    /* set my public key */
2771         case SCTP_SET_AUTH_CHUNKS:  /* set the authenticated chunks required */
2772         case SCTP_SET_AUTH_SECRET:  /* set the actual secret for the endpoint */
2773                 /* not supported yet and until we refine the draft */
2774                 error = EOPNOTSUPP;
2775                 break;
2776
2777         case SCTP_CLR_STAT_LOG:
2778 #ifdef SCTP_STAT_LOGGING
2779                 sctp_clr_stat_log();
2780 #else
2781                 error = EOPNOTSUPP;
2782 #endif
2783                 break;
2784         case SCTP_DELAYED_ACK_TIME:
2785         {
2786                 int32_t *tm;
2787                 if ((size_t)m->m_len < sizeof(int32_t)) {
2788                         error = EINVAL;
2789                         break;
2790                 }
2791                 tm = mtod(m, int32_t *);
2792
2793                 if ((*tm < 10) || (*tm > 500)) {
2794                         /* can't be smaller than 10ms */
2795                         /* MUST NOT be larger than 500ms */
2796                         error = EINVAL;
2797                         break;
2798                 }
2799                 inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV] = MSEC_TO_TICKS(*tm);
2800         }
2801                 break;
2802         case SCTP_RESET_STREAMS:
2803         {
2804                 struct sctp_stream_reset *strrst;
2805                 uint8_t two_way, not_peer;
2806
2807                 if ((size_t)m->m_len < sizeof(struct sctp_stream_reset)) {
2808                         error = EINVAL;
2809                         break;
2810                 }
2811                 strrst = mtod(m, struct sctp_stream_reset *);
2812
2813                 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2814                         SCTP_INP_RLOCK(inp);
2815                         stcb = LIST_FIRST(&inp->sctp_asoc_list);
2816                         if (stcb)
2817                                 SCTP_TCB_LOCK(stcb);
2818                         SCTP_INP_RUNLOCK(inp);
2819                 } else
2820                         stcb = sctp_findassociation_ep_asocid(inp, strrst->strrst_assoc_id);
2821                 if (stcb == NULL) {
2822                         error = ENOENT;
2823                         break;
2824                 }
2825                 if (stcb->asoc.peer_supports_strreset == 0) {
2826                         /* Peer does not support it,
2827                          * we return protocol not supported since
2828                          * this is true for this feature and this
2829                          * peer, not the socket request in general.
2830                          */
2831                         error = EPROTONOSUPPORT;
2832                         SCTP_TCB_UNLOCK(stcb);
2833                         break;
2834                 }
2835
2836 /* Having re-thought this code I added as I write the I-D there
2837  * is NO need for it. The peer, if we are requesting a stream-reset
2838  * will send a request to us but will itself do what we do, take
2839  * and copy off the "reset information" we send and queue TSN's
2840  * larger than the send-next in our response message. Thus they
2841  * will handle it.
2842  */
2843 /*              if (stcb->asoc.sending_seq != (stcb->asoc.last_acked_seq + 1)) {*/
2844                 /* Must have all sending data ack'd before we
2845                  * start this procedure. This is a bit restrictive
2846                  * and we SHOULD work on changing this so ONLY the
2847                  * streams being RESET get held up. So, a reset-all
2848                  * would require this.. but a reset specific just
2849                  * needs to be sure that the ones being reset have
2850                  * nothing on the send_queue. For now we will
2851                  * skip this more detailed method and do a course
2852                  * way.. i.e. nothing pending ... for future FIX ME!
2853                  */
2854 /*                      error = EBUSY;*/
2855 /*                      break;*/
2856 /*              }*/
2857
2858                 if (stcb->asoc.stream_reset_outstanding) {
2859                         error = EALREADY;
2860                         SCTP_TCB_UNLOCK(stcb);
2861                         break;
2862                 }
2863                 if (strrst->strrst_flags == SCTP_RESET_LOCAL_RECV) {
2864                         two_way = 0;
2865                         not_peer = 0;
2866                 } else if (strrst->strrst_flags == SCTP_RESET_LOCAL_SEND) {
2867                         two_way = 1;
2868                         not_peer = 1;
2869                 } else if (strrst->strrst_flags == SCTP_RESET_BOTH) {
2870                         two_way = 1;
2871                         not_peer = 0;
2872                 } else {
2873                         error = EINVAL;
2874                         SCTP_TCB_UNLOCK(stcb);
2875                         break;
2876                 }
2877                 sctp_send_str_reset_req(stcb, strrst->strrst_num_streams,
2878                                         strrst->strrst_list, two_way, not_peer);
2879                 crit_enter();
2880                 sctp_chunk_output(inp, stcb, 12);
2881                 SCTP_TCB_UNLOCK(stcb);
2882                 crit_exit();
2883
2884         }
2885         break;
2886         case SCTP_RESET_PEGS:
2887                 memset(sctp_pegs, 0, sizeof(sctp_pegs));
2888                 error = 0;
2889                 break;
2890         case SCTP_CONNECT_X:
2891                 if ((size_t)m->m_len < (sizeof(int) + sizeof(struct sockaddr_in))) {
2892                         error = EINVAL;
2893                         break;
2894                 }
2895                 error = sctp_do_connect_x(so, inp, m, p, 0);
2896                 break;
2897
2898         case SCTP_CONNECT_X_DELAYED:
2899                 if ((size_t)m->m_len < (sizeof(int) + sizeof(struct sockaddr_in))) {
2900                         error = EINVAL;
2901                         break;
2902                 }
2903                 error = sctp_do_connect_x(so, inp, m, p, 1);
2904                 break;
2905
2906         case SCTP_CONNECT_X_COMPLETE:
2907         {
2908                 struct sockaddr *sa;
2909                 struct sctp_nets *net;
2910                 if ((size_t)m->m_len < sizeof(struct sockaddr_in)) {
2911                         error = EINVAL;
2912                         break;
2913                 }
2914                 sa = mtod(m, struct sockaddr *);
2915                 /* find tcb */
2916                 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2917                         SCTP_INP_RLOCK(inp);
2918                         stcb = LIST_FIRST(&inp->sctp_asoc_list);
2919                         if (stcb) {
2920                                 SCTP_TCB_LOCK(stcb);
2921                                 net = sctp_findnet(stcb, sa);
2922                         }
2923                         SCTP_INP_RUNLOCK(inp);
2924                 } else {
2925                         SCTP_INP_WLOCK(inp);
2926                         SCTP_INP_INCR_REF(inp);
2927                         SCTP_INP_WUNLOCK(inp);
2928                         stcb = sctp_findassociation_ep_addr(&inp, sa, &net, NULL, NULL);
2929                         if (stcb == NULL) {
2930                                 SCTP_INP_WLOCK(inp);
2931                                 SCTP_INP_DECR_REF(inp);
2932                                 SCTP_INP_WUNLOCK(inp);
2933                         }
2934                 }
2935
2936                 if (stcb == NULL) {
2937                         error = ENOENT;
2938                         break;
2939                 }
2940                 if (stcb->asoc.delayed_connection == 1) {
2941                         stcb->asoc.delayed_connection = 0;
2942                         SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered);
2943                         sctp_timer_stop(SCTP_TIMER_TYPE_INIT, inp, stcb, stcb->asoc.primary_destination);
2944                         sctp_send_initiate(inp, stcb);
2945                 } else {
2946                         /* already expired or did not use delayed connectx */
2947                         error = EALREADY;
2948                 }
2949                 SCTP_TCB_UNLOCK(stcb);
2950         }
2951         break;
2952         case SCTP_MAXBURST:
2953         {
2954                 u_int8_t *burst;
2955                 SCTP_INP_WLOCK(inp);
2956                 burst = mtod(m, u_int8_t *);
2957                 if (*burst) {
2958                         inp->sctp_ep.max_burst = *burst;
2959                 }
2960                 SCTP_INP_WUNLOCK(inp);
2961         }
2962         break;
2963         case SCTP_MAXSEG:
2964         {
2965                 u_int32_t *segsize;
2966                 int ovh;
2967                 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
2968                         ovh = SCTP_MED_OVERHEAD;
2969                 } else {
2970                         ovh = SCTP_MED_V4_OVERHEAD;
2971                 }
2972                 segsize = mtod(m, u_int32_t *);
2973                 if (*segsize < 1) {
2974                         error = EINVAL;
2975                         break;
2976                 }
2977                 SCTP_INP_WLOCK(inp);
2978                 inp->sctp_frag_point = (*segsize+ovh);
2979                 if (inp->sctp_frag_point < MHLEN) {
2980                         inp->sctp_frag_point = MHLEN;
2981                 }
2982                 SCTP_INP_WUNLOCK(inp);
2983         }
2984         break;
2985         case SCTP_SET_DEBUG_LEVEL:
2986 #ifdef SCTP_DEBUG
2987         {
2988                 u_int32_t *level;
2989                 if ((size_t)m->m_len < sizeof(u_int32_t)) {
2990                         error = EINVAL;
2991                         break;
2992                 }
2993                 level = mtod(m, u_int32_t *);
2994                 error = 0;
2995                 sctp_debug_on = (*level & (SCTP_DEBUG_ALL |
2996                                            SCTP_DEBUG_NOISY));
2997                 kprintf("SETTING DEBUG LEVEL to %x\n",
2998                        (u_int)sctp_debug_on);
2999
3000         }
3001 #else
3002         error = EOPNOTSUPP;
3003 #endif /* SCTP_DEBUG */
3004         break;
3005         case SCTP_EVENTS:
3006         {
3007                 struct sctp_event_subscribe *events;
3008                 if ((size_t)m->m_len < sizeof(struct sctp_event_subscribe)) {
3009                         error = EINVAL;
3010                         break;
3011                 }
3012                 SCTP_INP_WLOCK(inp);
3013                 events = mtod(m, struct sctp_event_subscribe *);
3014                 if (events->sctp_data_io_event) {
3015                         inp->sctp_flags |= SCTP_PCB_FLAGS_RECVDATAIOEVNT;
3016                 } else {
3017                         inp->sctp_flags &= ~SCTP_PCB_FLAGS_RECVDATAIOEVNT;
3018                 }
3019
3020                 if (events->sctp_association_event) {
3021                         inp->sctp_flags |= SCTP_PCB_FLAGS_RECVASSOCEVNT;
3022                 } else {
3023                         inp->sctp_flags &= ~SCTP_PCB_FLAGS_RECVASSOCEVNT;
3024                 }
3025
3026                 if (events->sctp_address_event) {
3027                         inp->sctp_flags |= SCTP_PCB_FLAGS_RECVPADDREVNT;
3028                 } else {
3029                         inp->sctp_flags &= ~SCTP_PCB_FLAGS_RECVPADDREVNT;
3030                 }
3031
3032                 if (events->sctp_send_failure_event) {
3033                         inp->sctp_flags |= SCTP_PCB_FLAGS_RECVSENDFAILEVNT;
3034                 } else {
3035                         inp->sctp_flags &= ~SCTP_PCB_FLAGS_RECVSENDFAILEVNT;
3036                 }
3037
3038                 if (events->sctp_peer_error_event) {
3039                         inp->sctp_flags |= SCTP_PCB_FLAGS_RECVPEERERR;
3040                 } else {
3041                         inp->sctp_flags &= ~SCTP_PCB_FLAGS_RECVPEERERR;
3042                 }
3043
3044                 if (events->sctp_shutdown_event) {
3045                         inp->sctp_flags |= SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT;
3046                 } else {
3047                         inp->sctp_flags &= ~SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT;
3048                 }
3049
3050                 if (events->sctp_partial_delivery_event) {
3051                         inp->sctp_flags |= SCTP_PCB_FLAGS_PDAPIEVNT;
3052                 } else {
3053                         inp->sctp_flags &= ~SCTP_PCB_FLAGS_PDAPIEVNT;
3054                 }
3055
3056                 if (events->sctp_adaption_layer_event) {
3057                         inp->sctp_flags |= SCTP_PCB_FLAGS_ADAPTIONEVNT;
3058                 } else {
3059                         inp->sctp_flags &= ~SCTP_PCB_FLAGS_ADAPTIONEVNT;
3060                 }
3061
3062                 if (events->sctp_stream_reset_events) {
3063                         inp->sctp_flags |= SCTP_PCB_FLAGS_STREAM_RESETEVNT;
3064                 } else {
3065                         inp->sctp_flags &= ~SCTP_PCB_FLAGS_STREAM_RESETEVNT;
3066                 }
3067                 SCTP_INP_WUNLOCK(inp);
3068         }
3069         break;
3070
3071         case SCTP_ADAPTION_LAYER:
3072         {
3073                 struct sctp_setadaption *adap_bits;
3074                 if ((size_t)m->m_len < sizeof(struct sctp_setadaption)) {
3075                         error = EINVAL;
3076                         break;
3077                 }
3078                 SCTP_INP_WLOCK(inp);
3079                 adap_bits = mtod(m, struct sctp_setadaption *);
3080                 inp->sctp_ep.adaption_layer_indicator = adap_bits->ssb_adaption_ind;
3081                 SCTP_INP_WUNLOCK(inp);
3082         }
3083         break;
3084         case SCTP_SET_INITIAL_DBG_SEQ:
3085         {
3086                 u_int32_t *vvv;
3087                 if ((size_t)m->m_len < sizeof(u_int32_t)) {
3088                         error = EINVAL;
3089                         break;
3090                 }
3091                 SCTP_INP_WLOCK(inp);
3092                 vvv = mtod(m, u_int32_t *);
3093                 inp->sctp_ep.initial_sequence_debug = *vvv;
3094                 SCTP_INP_WUNLOCK(inp);
3095         }
3096         break;
3097         case SCTP_DEFAULT_SEND_PARAM:
3098         {
3099                 struct sctp_sndrcvinfo *s_info;
3100
3101                 if (m->m_len != sizeof(struct sctp_sndrcvinfo)) {
3102                         error = EINVAL;
3103                         break;
3104                 }
3105                 s_info = mtod(m, struct sctp_sndrcvinfo *);
3106
3107                 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
3108                         SCTP_INP_RLOCK(inp);
3109                         stcb = LIST_FIRST(&inp->sctp_asoc_list);
3110                         if (stcb)
3111                                 SCTP_TCB_LOCK(stcb);
3112                         SCTP_INP_RUNLOCK(inp);
3113                 } else
3114                         stcb = sctp_findassociation_ep_asocid(inp, s_info->sinfo_assoc_id);
3115
3116                 if (stcb == NULL) {
3117                         error = ENOENT;
3118                         break;
3119                 }
3120                 /* Validate things */
3121                 if (s_info->sinfo_stream > stcb->asoc.streamoutcnt) {
3122                         SCTP_TCB_UNLOCK(stcb);
3123                         error = EINVAL;
3124                         break;
3125                 }
3126                 /* Mask off the flags that are allowed */
3127                 s_info->sinfo_flags = (s_info->sinfo_flags &
3128                                        (MSG_UNORDERED | MSG_ADDR_OVER |
3129                                         MSG_PR_SCTP_TTL | MSG_PR_SCTP_BUF));
3130                 /* Copy it in */
3131                 stcb->asoc.def_send = *s_info;
3132                 SCTP_TCB_UNLOCK(stcb);
3133         }
3134         break;
3135         case SCTP_PEER_ADDR_PARAMS:
3136         {
3137                 struct sctp_paddrparams *paddrp;
3138                 struct sctp_nets *net;
3139                 if ((size_t)m->m_len < sizeof(struct sctp_paddrparams)) {
3140                         error = EINVAL;
3141                         break;
3142                 }
3143                 paddrp = mtod(m, struct sctp_paddrparams *);
3144                 net = NULL;
3145                 if (paddrp->spp_assoc_id) {
3146                         if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
3147                                 SCTP_INP_RLOCK(inp);
3148                                 stcb = LIST_FIRST(&inp->sctp_asoc_list);
3149                                 if (stcb) {
3150                                         SCTP_TCB_LOCK(stcb);
3151                                         net = sctp_findnet(stcb, (struct sockaddr *)&paddrp->spp_address);
3152                                 }
3153                                 SCTP_INP_RUNLOCK(inp);
3154                         } else
3155                                 stcb = sctp_findassociation_ep_asocid(inp, paddrp->spp_assoc_id);
3156                         if (stcb == NULL) {
3157                                 error = ENOENT;
3158                                 break;
3159                         }
3160
3161                 }
3162                 if ((stcb == NULL) &&
3163                     ((((struct sockaddr *)&paddrp->spp_address)->sa_family == AF_INET) ||
3164                      (((struct sockaddr *)&paddrp->spp_address)->sa_family == AF_INET6))) {
3165                         /* Lookup via address */
3166                         if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
3167                                 SCTP_INP_RLOCK(inp);
3168                                 stcb = LIST_FIRST(&inp->sctp_asoc_list);
3169                                 if (stcb) {
3170                                         SCTP_TCB_LOCK(stcb);
3171                                         net = sctp_findnet(stcb,
3172                                                            (struct sockaddr *)&paddrp->spp_address);
3173                                 }
3174                                 SCTP_INP_RUNLOCK(inp);
3175                         } else {
3176                                 SCTP_INP_WLOCK(inp);
3177                                 SCTP_INP_INCR_REF(inp);
3178                                 SCTP_INP_WUNLOCK(inp);
3179                                 stcb = sctp_findassociation_ep_addr(&inp,
3180                                                                     (struct sockaddr *)&paddrp->spp_address,
3181                                                                     &net, NULL, NULL);
3182                                 if (stcb == NULL) {
3183                                         SCTP_INP_WLOCK(inp);
3184                                         SCTP_INP_DECR_REF(inp);
3185                                         SCTP_INP_WUNLOCK(inp);
3186                                 }
3187                         }
3188                 } else {
3189                         /* Effects the Endpoint */
3190                         stcb = NULL;
3191                 }
3192                 if (stcb) {
3193                         /* Applies to the specific association */
3194                         if (paddrp->spp_pathmaxrxt) {
3195                                 if (net) {
3196                                         if (paddrp->spp_pathmaxrxt)
3197                                                 net->failure_threshold = paddrp->spp_pathmaxrxt;
3198                                 } else {
3199                                         if (paddrp->spp_pathmaxrxt)
3200                                                 stcb->asoc.def_net_failure = paddrp->spp_pathmaxrxt;
3201                                 }
3202                         }
3203                         if ((paddrp->spp_hbinterval != 0) && (paddrp->spp_hbinterval != 0xffffffff)) {
3204                                 /* Just a set */
3205                                 int old;
3206                                 if (net) {
3207                                         net->dest_state &= ~SCTP_ADDR_NOHB;
3208                                 } else {
3209                                         old = stcb->asoc.heart_beat_delay;
3210                                         stcb->asoc.heart_beat_delay = paddrp->spp_hbinterval;
3211                                         if (old == 0) {
3212                                                 /* Turn back on the timer */
3213                                                 sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net);
3214                                         }
3215                                 }
3216                         } else if (paddrp->spp_hbinterval == 0xffffffff) {
3217                                 /* on demand HB */
3218                                 sctp_send_hb(stcb, 1, net);
3219                         } else {
3220                                 if (net == NULL) {
3221                                         /* off on association */
3222                                         if (stcb->asoc.heart_beat_delay) {
3223                                                 int cnt_of_unconf = 0;
3224                                                 struct sctp_nets *lnet;
3225                                                 TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) {
3226                                                         if (lnet->dest_state & SCTP_ADDR_UNCONFIRMED) {
3227                                                                 cnt_of_unconf++;
3228                                                         }
3229                                                 }
3230                                                 /* stop the timer ONLY if we have no unconfirmed addresses
3231                                                  */
3232                                                 if (cnt_of_unconf == 0)
3233                                                         sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net);
3234                                         }
3235                                         stcb->asoc.heart_beat_delay = 0;
3236                                 } else {
3237                                         net->dest_state |= SCTP_ADDR_NOHB;
3238                                 }
3239                         }
3240                         SCTP_TCB_UNLOCK(stcb);
3241                 } else {
3242                         /* Use endpoint defaults */
3243                         SCTP_INP_WLOCK(inp);
3244                         if (paddrp->spp_pathmaxrxt)
3245                                 inp->sctp_ep.def_net_failure = paddrp->spp_pathmaxrxt;
3246                         if (paddrp->spp_hbinterval != SCTP_ISSUE_HB)
3247                                 inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = paddrp->spp_hbinterval;
3248                         SCTP_INP_WUNLOCK(inp);
3249                 }
3250         }
3251         break;
3252         case SCTP_RTOINFO:
3253         {
3254                 struct sctp_rtoinfo *srto;
3255                 if ((size_t)m->m_len < sizeof(struct sctp_rtoinfo)) {
3256                         error = EINVAL;
3257                         break;
3258                 }
3259                 srto = mtod(m, struct sctp_rtoinfo *);
3260                 if (srto->srto_assoc_id == 0) {
3261                         SCTP_INP_WLOCK(inp);
3262                         /* If we have a null asoc, its default for the endpoint */
3263                         if (srto->srto_initial > 10)
3264                                 inp->sctp_ep.initial_rto = srto->srto_initial;
3265                         if (srto->srto_max > 10)
3266                                 inp->sctp_ep.sctp_maxrto = srto->srto_max;
3267                         if (srto->srto_min > 10)
3268                                 inp->sctp_ep.sctp_minrto = srto->srto_min;
3269                         SCTP_INP_WUNLOCK(inp);
3270                         break;
3271                 }
3272                 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
3273                         SCTP_INP_RLOCK(inp);
3274                         stcb = LIST_FIRST(&inp->sctp_asoc_list);
3275                         if (stcb)
3276                                 SCTP_TCB_LOCK(stcb);
3277                         SCTP_INP_RUNLOCK(inp);
3278                 } else
3279                         stcb = sctp_findassociation_ep_asocid(inp, srto->srto_assoc_id);
3280                 if (stcb == NULL) {
3281                         error = EINVAL;
3282                         break;
3283                 }
3284                 /* Set in ms we hope :-) */
3285                 if (srto->srto_initial > 10)
3286                         stcb->asoc.initial_rto = srto->srto_initial;
3287                 if (srto->srto_max > 10)
3288                         stcb->asoc.maxrto = srto->srto_max;
3289                 if (srto->srto_min > 10)
3290                         stcb->asoc.minrto = srto->srto_min;
3291                 SCTP_TCB_UNLOCK(stcb);
3292         }
3293         break;
3294         case SCTP_ASSOCINFO:
3295         {
3296                 struct sctp_assocparams *sasoc;
3297
3298                 if ((size_t)m->m_len < sizeof(struct sctp_assocparams)) {
3299                         error = EINVAL;
3300                         break;
3301                 }
3302                 sasoc = mtod(m, struct sctp_assocparams *);
3303                 if (sasoc->sasoc_assoc_id) {
3304                         if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
3305                                 SCTP_INP_RLOCK(inp);
3306                                 stcb = LIST_FIRST(&inp->sctp_asoc_list);
3307                                 if (stcb)
3308                                         SCTP_TCB_LOCK(stcb);
3309                                 SCTP_INP_RUNLOCK(inp);
3310                         } else
3311                                 stcb = sctp_findassociation_ep_asocid(inp,
3312                                                                       sasoc->sasoc_assoc_id);
3313                         if (stcb == NULL) {
3314                                 error = ENOENT;
3315                                 break;
3316                         }
3317
3318                 } else {
3319                         stcb = NULL;
3320                 }
3321                 if (stcb) {
3322                         if (sasoc->sasoc_asocmaxrxt)
3323                                 stcb->asoc.max_send_times = sasoc->sasoc_asocmaxrxt;
3324                         sasoc->sasoc_number_peer_destinations = stcb->asoc.numnets;
3325                         sasoc->sasoc_peer_rwnd = 0;
3326                         sasoc->sasoc_local_rwnd = 0;
3327                         if (stcb->asoc.cookie_life)
3328                                 stcb->asoc.cookie_life = sasoc->sasoc_cookie_life;
3329                         SCTP_TCB_UNLOCK(stcb);
3330                 } else {
3331                         SCTP_INP_WLOCK(inp);
3332                         if (sasoc->sasoc_asocmaxrxt)
3333                                 inp->sctp_ep.max_send_times = sasoc->sasoc_asocmaxrxt;
3334                         sasoc->sasoc_number_peer_destinations = 0;
3335                         sasoc->sasoc_peer_rwnd = 0;
3336                         sasoc->sasoc_local_rwnd = 0;
3337                         if (sasoc->sasoc_cookie_life)
3338                                 inp->sctp_ep.def_cookie_life = sasoc->sasoc_cookie_life;
3339                         SCTP_INP_WUNLOCK(inp);
3340                 }
3341         }
3342         break;
3343         case SCTP_INITMSG:
3344         {
3345                 struct sctp_initmsg *sinit;
3346
3347                 if ((size_t)m->m_len < sizeof(struct sctp_initmsg)) {
3348                         error = EINVAL;
3349                         break;
3350                 }
3351                 sinit = mtod(m, struct sctp_initmsg *);
3352                 SCTP_INP_WLOCK(inp);
3353                 if (sinit->sinit_num_ostreams)
3354                         inp->sctp_ep.pre_open_stream_count = sinit->sinit_num_ostreams;
3355
3356                 if (sinit->sinit_max_instreams)
3357                         inp->sctp_ep.max_open_streams_intome = sinit->sinit_max_instreams;
3358
3359                 if (sinit->sinit_max_attempts)
3360                         inp->sctp_ep.max_init_times = sinit->sinit_max_attempts;
3361
3362                 if (sinit->sinit_max_init_timeo > 10)
3363                         /* We must be at least a 100ms (we set in ticks) */
3364                         inp->sctp_ep.initial_init_rto_max = sinit->sinit_max_init_timeo;
3365                 SCTP_INP_WUNLOCK(inp);
3366         }
3367         break;
3368         case SCTP_PRIMARY_ADDR:
3369         {
3370                 struct sctp_setprim *spa;
3371                 struct sctp_nets *net, *lnet;
3372                 if ((size_t)m->m_len < sizeof(struct sctp_setprim)) {
3373                         error = EINVAL;
3374                         break;
3375                 }
3376                 spa = mtod(m, struct sctp_setprim *);
3377
3378                 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
3379                         SCTP_INP_RLOCK(inp);
3380                         stcb = LIST_FIRST(&inp->sctp_asoc_list);
3381                         if (stcb) {
3382                                 SCTP_TCB_LOCK(stcb);
3383                         } else {
3384                                 error = EINVAL;
3385                                 break;
3386                         }
3387                         SCTP_INP_RUNLOCK(inp);
3388                 } else
3389                         stcb = sctp_findassociation_ep_asocid(inp, spa->ssp_assoc_id);
3390                 if (stcb == NULL) {
3391                         /* One last shot */
3392                         SCTP_INP_WLOCK(inp);
3393                         SCTP_INP_INCR_REF(inp);
3394                         SCTP_INP_WUNLOCK(inp);
3395                         stcb = sctp_findassociation_ep_addr(&inp,
3396                                                             (struct sockaddr *)&spa->ssp_addr,
3397                                                             &net, NULL, NULL);
3398                         if (stcb == NULL) {
3399                                 SCTP_INP_WLOCK(inp);
3400                                 SCTP_INP_DECR_REF(inp);
3401                                 SCTP_INP_WUNLOCK(inp);
3402                                 error = EINVAL;
3403                                 break;
3404                         }
3405                 } else {
3406                         /* find the net, associd or connected lookup type */
3407                         net = sctp_findnet(stcb, (struct sockaddr *)&spa->ssp_addr);
3408                         if (net == NULL) {
3409                                 SCTP_TCB_UNLOCK(stcb);
3410                                 error = EINVAL;
3411                                 break;
3412                         }
3413                 }
3414                 if ((net != stcb->asoc.primary_destination) &&
3415                     (!(net->dest_state & SCTP_ADDR_UNCONFIRMED))) {
3416                         /* Ok we need to set it */
3417                         lnet = stcb->asoc.primary_destination;
3418                         lnet->next_tsn_at_change = net->next_tsn_at_change = stcb->asoc.sending_seq;
3419                         if (sctp_set_primary_addr(stcb,
3420                                                   NULL,
3421                                                   net) == 0) {
3422                                 if (net->dest_state & SCTP_ADDR_SWITCH_PRIMARY) {
3423                                         net->dest_state |= SCTP_ADDR_DOUBLE_SWITCH;
3424                                 }
3425                                 net->dest_state |= SCTP_ADDR_SWITCH_PRIMARY;
3426                         }
3427                 }
3428                 SCTP_TCB_UNLOCK(stcb);
3429         }
3430         break;
3431
3432         case SCTP_SET_PEER_PRIMARY_ADDR:
3433         {
3434                 struct sctp_setpeerprim *sspp;
3435                 if ((size_t)m->m_len < sizeof(struct sctp_setpeerprim)) {
3436                         error = EINVAL;
3437                         break;
3438                 }
3439                 sspp = mtod(m, struct sctp_setpeerprim *);
3440
3441
3442                 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
3443                         SCTP_INP_RLOCK(inp);
3444                         stcb = LIST_FIRST(&inp->sctp_asoc_list);
3445                         if (stcb)
3446                                 SCTP_TCB_UNLOCK(stcb);
3447                         SCTP_INP_RUNLOCK(inp);
3448                 } else
3449                         stcb = sctp_findassociation_ep_asocid(inp, sspp->sspp_assoc_id);
3450                 if (stcb == NULL) {
3451                         error = EINVAL;
3452                         break;
3453                 }
3454                 if (sctp_set_primary_ip_address_sa(stcb, (struct sockaddr *)&sspp->sspp_addr) != 0) {
3455                         error = EINVAL;
3456                 }
3457                 SCTP_TCB_UNLOCK(stcb);
3458         }
3459         break;
3460         case SCTP_BINDX_ADD_ADDR:
3461         {
3462                 struct sctp_getaddresses *addrs;
3463                 struct sockaddr *addr_touse;
3464                 struct sockaddr_in sin;
3465                 /* see if we're bound all already! */
3466                 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
3467                         error = EINVAL;
3468                         break;
3469                 }
3470                 if ((size_t)m->m_len < sizeof(struct sctp_getaddresses)) {
3471                         error = EINVAL;
3472                         break;
3473                 }
3474                 addrs = mtod(m, struct sctp_getaddresses *);
3475                 addr_touse = addrs->addr;
3476                 if (addrs->addr->sa_family == AF_INET6) {
3477                         struct sockaddr_in6 *sin6;
3478                         sin6 = (struct sockaddr_in6 *)addr_touse;
3479                         if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
3480                                 in6_sin6_2_sin(&sin, sin6);
3481                                 addr_touse = (struct sockaddr *)&sin;
3482                         }
3483                 }
3484                 if (inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) {
3485                         if (p == NULL) {
3486                                 /* Can't get proc for Net/Open BSD */
3487                                 error = EINVAL;
3488                                 break;
3489                         }
3490                         error = sctp_inpcb_bind(so, addr_touse, p);
3491                         break;
3492                 }
3493                 /* No locks requ