The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/netinet/sctputil.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $KAME: sctputil.c,v 1.39 2005/06/16 20:54:06 jinmei Exp $       */
    2 /*      $NetBSD: sctputil.c,v 1.19 2022/04/08 10:27:04 andvar 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 
   36 #include <sys/cdefs.h>
   37 __KERNEL_RCSID(0, "$NetBSD: sctputil.c,v 1.19 2022/04/08 10:27:04 andvar Exp $");
   38 
   39 #ifdef _KERNEL_OPT
   40 #include "opt_inet.h"
   41 #include "opt_ipsec.h"
   42 #include "opt_sctp.h"
   43 #endif /* _KERNEL_OPT */
   44 
   45 #include <sys/param.h>
   46 #include <sys/systm.h>
   47 #include <sys/malloc.h>
   48 #include <sys/mbuf.h>
   49 #include <sys/domain.h>
   50 #include <sys/protosw.h>
   51 #include <sys/socket.h>
   52 #include <sys/socketvar.h>
   53 #include <sys/mutex.h>
   54 #include <sys/proc.h>
   55 #include <sys/kernel.h>
   56 #include <sys/sysctl.h>
   57 #include <sys/cprng.h>
   58 
   59 #include <sys/callout.h>
   60 
   61 #include <net/route.h>
   62 
   63 #ifdef INET6
   64 #include <sys/domain.h>
   65 #endif
   66 
   67 #include <machine/limits.h>
   68 
   69 #include <net/if.h>
   70 #include <net/if_types.h>
   71 #include <net/route.h>
   72 
   73 #include <netinet/in.h>
   74 #include <netinet/in_systm.h>
   75 #include <netinet/ip.h>
   76 #include <netinet/in_pcb.h>
   77 #include <netinet/in_var.h>
   78 #include <netinet/ip_var.h>
   79 
   80 #ifdef INET6
   81 #include <netinet/ip6.h>
   82 #include <netinet6/ip6_var.h>
   83 #include <netinet6/scope6_var.h>
   84 #include <netinet6/in6_pcb.h>
   85 
   86 #endif /* INET6 */
   87 
   88 #include <netinet/sctp_pcb.h>
   89 
   90 #ifdef IPSEC
   91 #include <netipsec/ipsec.h>
   92 #include <netipsec/key.h>
   93 #endif /* IPSEC */
   94 
   95 #include <netinet/sctputil.h>
   96 #include <netinet/sctp_var.h>
   97 #ifdef INET6
   98 #include <netinet6/sctp6_var.h>
   99 #endif
  100 #include <netinet/sctp_header.h>
  101 #include <netinet/sctp_output.h>
  102 #include <netinet/sctp_hashdriver.h>
  103 #include <netinet/sctp_uio.h>
  104 #include <netinet/sctp_timer.h>
  105 #include <netinet/sctp_crc32.h>
  106 #include <netinet/sctp_indata.h>        /* for sctp_deliver_data() */
  107 #define NUMBER_OF_MTU_SIZES 18
  108 
  109 #ifdef SCTP_DEBUG
  110 extern u_int32_t sctp_debug_on;
  111 #endif
  112 
  113 #ifdef SCTP_STAT_LOGGING
  114 int sctp_cwnd_log_at=0;
  115 int sctp_cwnd_log_rolled=0;
  116 struct sctp_cwnd_log sctp_clog[SCTP_STAT_LOG_SIZE];
  117 
  118 void sctp_clr_stat_log(void)
  119 {
  120         sctp_cwnd_log_at=0;
  121         sctp_cwnd_log_rolled=0;
  122 }
  123 
  124 void
  125 sctp_log_strm_del_alt(u_int32_t tsn, u_int16_t sseq, int from)
  126 {
  127 
  128         sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
  129         sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_STRM;
  130         sctp_clog[sctp_cwnd_log_at].x.strlog.n_tsn = tsn;
  131         sctp_clog[sctp_cwnd_log_at].x.strlog.n_sseq = sseq;
  132         sctp_clog[sctp_cwnd_log_at].x.strlog.e_tsn = 0;
  133         sctp_clog[sctp_cwnd_log_at].x.strlog.e_sseq = 0;
  134         sctp_cwnd_log_at++;
  135         if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
  136                 sctp_cwnd_log_at = 0;
  137                 sctp_cwnd_log_rolled = 1;
  138         }
  139 
  140 }
  141 
  142 void
  143 sctp_log_map(uint32_t map, uint32_t cum, uint32_t high, int from)
  144 {
  145 
  146         sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
  147         sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_MAP;
  148         sctp_clog[sctp_cwnd_log_at].x.map.base = map;
  149         sctp_clog[sctp_cwnd_log_at].x.map.cum = cum;
  150         sctp_clog[sctp_cwnd_log_at].x.map.high = high;
  151         sctp_cwnd_log_at++;
  152         if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
  153                 sctp_cwnd_log_at = 0;
  154                 sctp_cwnd_log_rolled = 1;
  155         }
  156 }
  157 
  158 void
  159 sctp_log_fr(uint32_t biggest_tsn, uint32_t biggest_new_tsn, uint32_t tsn,
  160     int from)
  161 {
  162 
  163         sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
  164         sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_FR;
  165         sctp_clog[sctp_cwnd_log_at].x.fr.largest_tsn = biggest_tsn;
  166         sctp_clog[sctp_cwnd_log_at].x.fr.largest_new_tsn = biggest_new_tsn;
  167         sctp_clog[sctp_cwnd_log_at].x.fr.tsn = tsn;
  168         sctp_cwnd_log_at++;
  169         if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
  170                 sctp_cwnd_log_at = 0;
  171                 sctp_cwnd_log_rolled = 1;
  172         }
  173 }
  174 
  175 void
  176 sctp_log_strm_del(struct sctp_tmit_chunk *chk, struct sctp_tmit_chunk *poschk,
  177     int from)
  178 {
  179 
  180         if (chk == NULL) {
  181                 printf("Gak log of NULL?\n");
  182                 return;
  183         }
  184         sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
  185         sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_STRM;
  186         sctp_clog[sctp_cwnd_log_at].x.strlog.n_tsn = chk->rec.data.TSN_seq;
  187         sctp_clog[sctp_cwnd_log_at].x.strlog.n_sseq = chk->rec.data.stream_seq;
  188         if (poschk != NULL) {
  189                 sctp_clog[sctp_cwnd_log_at].x.strlog.e_tsn =
  190                     poschk->rec.data.TSN_seq;
  191                 sctp_clog[sctp_cwnd_log_at].x.strlog.e_sseq =
  192                     poschk->rec.data.stream_seq;
  193         } else {
  194                 sctp_clog[sctp_cwnd_log_at].x.strlog.e_tsn = 0;
  195                 sctp_clog[sctp_cwnd_log_at].x.strlog.e_sseq = 0;
  196         }
  197         sctp_cwnd_log_at++;
  198         if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
  199                 sctp_cwnd_log_at = 0;
  200                 sctp_cwnd_log_rolled = 1;
  201         }
  202 }
  203 
  204 void
  205 sctp_log_cwnd(struct sctp_nets *net, int augment, uint8_t from)
  206 {
  207 
  208         sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
  209         sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_CWND;
  210         sctp_clog[sctp_cwnd_log_at].x.cwnd.net = net;
  211         sctp_clog[sctp_cwnd_log_at].x.cwnd.cwnd_new_value = net->cwnd;
  212         sctp_clog[sctp_cwnd_log_at].x.cwnd.inflight = net->flight_size;
  213         sctp_clog[sctp_cwnd_log_at].x.cwnd.cwnd_augment = augment;
  214         sctp_cwnd_log_at++;
  215         if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
  216                 sctp_cwnd_log_at = 0;
  217                 sctp_cwnd_log_rolled = 1;
  218         }
  219 }
  220 
  221 void
  222 sctp_log_maxburst(struct sctp_nets *net, int error, int burst, uint8_t from)
  223 {
  224         sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
  225         sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_MAXBURST;
  226         sctp_clog[sctp_cwnd_log_at].x.cwnd.net = net;
  227         sctp_clog[sctp_cwnd_log_at].x.cwnd.cwnd_new_value = error;
  228         sctp_clog[sctp_cwnd_log_at].x.cwnd.inflight = net->flight_size;
  229         sctp_clog[sctp_cwnd_log_at].x.cwnd.cwnd_augment = burst;
  230         sctp_cwnd_log_at++;
  231         if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
  232                 sctp_cwnd_log_at = 0;
  233                 sctp_cwnd_log_rolled = 1;
  234         }
  235 }
  236 
  237 void
  238 sctp_log_rwnd(uint8_t from, u_int32_t peers_rwnd , u_int32_t snd_size, u_int32_t overhead)
  239 {
  240         sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
  241         sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_RWND;
  242         sctp_clog[sctp_cwnd_log_at].x.rwnd.rwnd = peers_rwnd;
  243         sctp_clog[sctp_cwnd_log_at].x.rwnd.send_size = snd_size;
  244         sctp_clog[sctp_cwnd_log_at].x.rwnd.overhead = overhead;
  245         sctp_clog[sctp_cwnd_log_at].x.rwnd.new_rwnd = 0;
  246         sctp_cwnd_log_at++;
  247         if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
  248                 sctp_cwnd_log_at = 0;
  249                 sctp_cwnd_log_rolled = 1;
  250         }
  251 }
  252 
  253 void
  254 sctp_log_rwnd_set(uint8_t from, u_int32_t peers_rwnd , u_int32_t flight_size, u_int32_t overhead, u_int32_t a_rwndval)
  255 {
  256         sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
  257         sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_RWND;
  258         sctp_clog[sctp_cwnd_log_at].x.rwnd.rwnd = peers_rwnd;
  259         sctp_clog[sctp_cwnd_log_at].x.rwnd.send_size = flight_size;
  260         sctp_clog[sctp_cwnd_log_at].x.rwnd.overhead = overhead;
  261         sctp_clog[sctp_cwnd_log_at].x.rwnd.new_rwnd = a_rwndval;
  262         sctp_cwnd_log_at++;
  263         if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
  264                 sctp_cwnd_log_at = 0;
  265                 sctp_cwnd_log_rolled = 1;
  266         }
  267 }
  268 
  269 void
  270 sctp_log_mbcnt(uint8_t from, u_int32_t total_oq , u_int32_t book, u_int32_t total_mbcnt_q, u_int32_t mbcnt)
  271 {
  272         sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
  273         sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_MBCNT;
  274         sctp_clog[sctp_cwnd_log_at].x.mbcnt.total_queue_size = total_oq;
  275         sctp_clog[sctp_cwnd_log_at].x.mbcnt.size_change  = book;
  276         sctp_clog[sctp_cwnd_log_at].x.mbcnt.total_queue_mb_size = total_mbcnt_q;
  277         sctp_clog[sctp_cwnd_log_at].x.mbcnt.mbcnt_change = mbcnt;
  278         sctp_cwnd_log_at++;
  279         if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
  280                 sctp_cwnd_log_at = 0;
  281                 sctp_cwnd_log_rolled = 1;
  282         }
  283 }
  284 
  285 void
  286 sctp_log_block(uint8_t from, struct socket *so, struct sctp_association *asoc)
  287 {
  288 
  289         sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
  290         sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_BLOCK;
  291         sctp_clog[sctp_cwnd_log_at].x.blk.maxmb = (u_int16_t)(so->so_snd.sb_mbmax/1024);
  292         sctp_clog[sctp_cwnd_log_at].x.blk.onmb = asoc->total_output_mbuf_queue_size;
  293         sctp_clog[sctp_cwnd_log_at].x.blk.maxsb = (u_int16_t)(so->so_snd.sb_hiwat/1024);
  294         sctp_clog[sctp_cwnd_log_at].x.blk.onsb = asoc->total_output_queue_size;
  295         sctp_clog[sctp_cwnd_log_at].x.blk.send_sent_qcnt = (u_int16_t)(asoc->send_queue_cnt + asoc->sent_queue_cnt);
  296         sctp_clog[sctp_cwnd_log_at].x.blk.stream_qcnt = (u_int16_t)asoc->stream_queue_cnt;
  297         sctp_cwnd_log_at++;
  298         if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
  299                 sctp_cwnd_log_at = 0;
  300                 sctp_cwnd_log_rolled = 1;
  301         }
  302 }
  303 
  304 int
  305 sctp_fill_stat_log(struct mbuf *m)
  306 {
  307         struct sctp_cwnd_log_req *req;
  308         int size_limit, num, i, at, cnt_out=0;
  309 
  310         if (m == NULL)
  311                 return (EINVAL);
  312 
  313         size_limit = (m->m_len - sizeof(struct sctp_cwnd_log_req));
  314         if (size_limit < sizeof(struct sctp_cwnd_log)) {
  315                 return (EINVAL);
  316         }
  317         req = mtod(m, struct sctp_cwnd_log_req *);
  318         num = size_limit/sizeof(struct sctp_cwnd_log);
  319         if (sctp_cwnd_log_rolled) {
  320                 req->num_in_log = SCTP_STAT_LOG_SIZE;
  321         } else {
  322                 req->num_in_log = sctp_cwnd_log_at;
  323                 /* if the log has not rolled, we don't
  324                  * let you have old data.
  325                  */
  326                 if (req->end_at > sctp_cwnd_log_at) {
  327                         req->end_at = sctp_cwnd_log_at;
  328                 }
  329         }
  330         if ((num < SCTP_STAT_LOG_SIZE) &&
  331             ((sctp_cwnd_log_rolled) || (sctp_cwnd_log_at > num))) {
  332                 /* we can't return all of it */
  333                 if (((req->start_at == 0) && (req->end_at == 0)) ||
  334                     (req->start_at >= SCTP_STAT_LOG_SIZE) ||
  335                     (req->end_at >= SCTP_STAT_LOG_SIZE)) {
  336                         /* No user request or user is wacked. */
  337                         req->num_ret = num;
  338                         req->end_at = sctp_cwnd_log_at - 1;
  339                         if ((sctp_cwnd_log_at - num) < 0) {
  340                                 int cc;
  341                                 cc = num - sctp_cwnd_log_at;
  342                                 req->start_at = SCTP_STAT_LOG_SIZE - cc;
  343                         } else {
  344                                 req->start_at = sctp_cwnd_log_at - num;
  345                         }
  346                 } else {
  347                         /* a user request */
  348                         int cc;
  349                         if (req->start_at > req->end_at) {
  350                                 cc = (SCTP_STAT_LOG_SIZE - req->start_at) +
  351                                     (req->end_at + 1);
  352                         } else {
  353 
  354                                 cc = req->end_at - req->start_at;
  355                         }
  356                         if (cc < num) {
  357                                 num = cc;
  358                         }
  359                         req->num_ret = num;
  360                 }
  361         } else {
  362                 /* We can return all  of it */
  363                 req->start_at = 0;
  364                 req->end_at = sctp_cwnd_log_at - 1;
  365                 req->num_ret = sctp_cwnd_log_at;
  366         }
  367         for (i = 0, at = req->start_at; i < req->num_ret; i++) {
  368                 req->log[i] = sctp_clog[at];
  369                 cnt_out++;
  370                 at++;
  371                 if (at >= SCTP_STAT_LOG_SIZE)
  372                         at = 0;
  373         }
  374         m->m_len = (cnt_out * sizeof(struct sctp_cwnd_log_req)) + sizeof(struct sctp_cwnd_log_req);
  375         return (0);
  376 }
  377 
  378 #endif
  379 
  380 #ifdef SCTP_AUDITING_ENABLED
  381 u_int8_t sctp_audit_data[SCTP_AUDIT_SIZE][2];
  382 static int sctp_audit_indx = 0;
  383 
  384 static
  385 void sctp_print_audit_report(void)
  386 {
  387         int i;
  388         int cnt;
  389         cnt = 0;
  390         for (i=sctp_audit_indx;i<SCTP_AUDIT_SIZE;i++) {
  391                 if ((sctp_audit_data[i][0] == 0xe0) &&
  392                     (sctp_audit_data[i][1] == 0x01)) {
  393                         cnt = 0;
  394                         printf("\n");
  395                 } else if (sctp_audit_data[i][0] == 0xf0) {
  396                         cnt = 0;
  397                         printf("\n");
  398                 } else if ((sctp_audit_data[i][0] == 0xc0) &&
  399                     (sctp_audit_data[i][1] == 0x01)) {
  400                         printf("\n");
  401                         cnt = 0;
  402                 }
  403                 printf("%2.2x%2.2x ", (uint32_t)sctp_audit_data[i][0],
  404                     (uint32_t)sctp_audit_data[i][1]);
  405                 cnt++;
  406                 if ((cnt % 14) == 0)
  407                         printf("\n");
  408         }
  409         for (i=0;i<sctp_audit_indx;i++) {
  410                 if ((sctp_audit_data[i][0] == 0xe0) &&
  411                     (sctp_audit_data[i][1] == 0x01)) {
  412                         cnt = 0;
  413                         printf("\n");
  414                 } else if (sctp_audit_data[i][0] == 0xf0) {
  415                         cnt = 0;
  416                         printf("\n");
  417                 } else if ((sctp_audit_data[i][0] == 0xc0) &&
  418                          (sctp_audit_data[i][1] == 0x01)) {
  419                         printf("\n");
  420                         cnt = 0;
  421                 }
  422                 printf("%2.2x%2.2x ", (uint32_t)sctp_audit_data[i][0],
  423                     (uint32_t)sctp_audit_data[i][1]);
  424                 cnt++;
  425                 if ((cnt % 14) == 0)
  426                         printf("\n");
  427         }
  428         printf("\n");
  429 }
  430 
  431 void sctp_auditing(int from, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
  432     struct sctp_nets *net)
  433 {
  434         int resend_cnt, tot_out, rep, tot_book_cnt;
  435         struct sctp_nets *lnet;
  436         struct sctp_tmit_chunk *chk;
  437 
  438         sctp_audit_data[sctp_audit_indx][0] = 0xAA;
  439         sctp_audit_data[sctp_audit_indx][1] = 0x000000ff & from;
  440         sctp_audit_indx++;
  441         if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
  442                 sctp_audit_indx = 0;
  443         }
  444         if (inp == NULL) {
  445                 sctp_audit_data[sctp_audit_indx][0] = 0xAF;
  446                 sctp_audit_data[sctp_audit_indx][1] = 0x01;
  447                 sctp_audit_indx++;
  448                 if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
  449                         sctp_audit_indx = 0;
  450                 }
  451                 return;
  452         }
  453         if (stcb == NULL) {
  454                 sctp_audit_data[sctp_audit_indx][0] = 0xAF;
  455                 sctp_audit_data[sctp_audit_indx][1] = 0x02;
  456                 sctp_audit_indx++;
  457                 if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
  458                         sctp_audit_indx = 0;
  459                 }
  460                 return;
  461         }
  462         sctp_audit_data[sctp_audit_indx][0] = 0xA1;
  463         sctp_audit_data[sctp_audit_indx][1] =
  464             (0x000000ff & stcb->asoc.sent_queue_retran_cnt);
  465         sctp_audit_indx++;
  466         if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
  467                 sctp_audit_indx = 0;
  468         }
  469         rep = 0;
  470         tot_book_cnt = 0;
  471         resend_cnt = tot_out = 0;
  472         TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
  473                 if (chk->sent == SCTP_DATAGRAM_RESEND) {
  474                         resend_cnt++;
  475                 } else if (chk->sent < SCTP_DATAGRAM_RESEND) {
  476                         tot_out += chk->book_size;
  477                         tot_book_cnt++;
  478                 }
  479         }
  480         if (resend_cnt != stcb->asoc.sent_queue_retran_cnt) {
  481                 sctp_audit_data[sctp_audit_indx][0] = 0xAF;
  482                 sctp_audit_data[sctp_audit_indx][1] = 0xA1;
  483                 sctp_audit_indx++;
  484                 if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
  485                         sctp_audit_indx = 0;
  486                 }
  487                 printf("resend_cnt:%d asoc-tot:%d\n",
  488                     resend_cnt, stcb->asoc.sent_queue_retran_cnt);
  489                 rep = 1;
  490                 stcb->asoc.sent_queue_retran_cnt = resend_cnt;
  491                 sctp_audit_data[sctp_audit_indx][0] = 0xA2;
  492                 sctp_audit_data[sctp_audit_indx][1] =
  493                     (0x000000ff & stcb->asoc.sent_queue_retran_cnt);
  494                 sctp_audit_indx++;
  495                 if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
  496                         sctp_audit_indx = 0;
  497                 }
  498         }
  499         if (tot_out != stcb->asoc.total_flight) {
  500                 sctp_audit_data[sctp_audit_indx][0] = 0xAF;
  501                 sctp_audit_data[sctp_audit_indx][1] = 0xA2;
  502                 sctp_audit_indx++;
  503                 if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
  504                         sctp_audit_indx = 0;
  505                 }
  506                 rep = 1;
  507                 printf("tot_flt:%d asoc_tot:%d\n", tot_out,
  508                     (int)stcb->asoc.total_flight);
  509                 stcb->asoc.total_flight = tot_out;
  510         }
  511         if (tot_book_cnt != stcb->asoc.total_flight_count) {
  512                 sctp_audit_data[sctp_audit_indx][0] = 0xAF;
  513                 sctp_audit_data[sctp_audit_indx][1] = 0xA5;
  514                 sctp_audit_indx++;
  515                 if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
  516                         sctp_audit_indx = 0;
  517                 }
  518                 rep = 1;
  519                 printf("tot_flt_book:%d\n", tot_book);
  520 
  521                 stcb->asoc.total_flight_count = tot_book_cnt;
  522         }
  523         tot_out = 0;
  524         TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) {
  525                 tot_out += lnet->flight_size;
  526         }
  527         if (tot_out != stcb->asoc.total_flight) {
  528                 sctp_audit_data[sctp_audit_indx][0] = 0xAF;
  529                 sctp_audit_data[sctp_audit_indx][1] = 0xA3;
  530                 sctp_audit_indx++;
  531                 if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
  532                         sctp_audit_indx = 0;
  533                 }
  534                 rep = 1;
  535                 printf("real flight:%d net total was %d\n",
  536                     stcb->asoc.total_flight, tot_out);
  537                 /* now corrective action */
  538                 TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) {
  539                         tot_out = 0;
  540                         TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
  541                                 if ((chk->whoTo == lnet) &&
  542                                     (chk->sent < SCTP_DATAGRAM_RESEND)) {
  543                                         tot_out += chk->book_size;
  544                                 }
  545                         }
  546                         if (lnet->flight_size != tot_out) {
  547                                 printf("net:%x flight was %d corrected to %d\n",
  548                                     (uint32_t)lnet, lnet->flight_size, tot_out);
  549                                 lnet->flight_size = tot_out;
  550                         }
  551 
  552                 }
  553         }
  554 
  555         if (rep) {
  556                 sctp_print_audit_report();
  557         }
  558 }
  559 
  560 void
  561 sctp_audit_log(u_int8_t ev, u_int8_t fd)
  562 {
  563         sctp_audit_data[sctp_audit_indx][0] = ev;
  564         sctp_audit_data[sctp_audit_indx][1] = fd;
  565         sctp_audit_indx++;
  566         if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
  567                 sctp_audit_indx = 0;
  568         }
  569 }
  570 
  571 #endif
  572 
  573 /*
  574  * a list of sizes based on typical mtu's, used only if next hop
  575  * size not returned.
  576  */
  577 static int sctp_mtu_sizes[] = {
  578         68,
  579         296,
  580         508,
  581         512,
  582         544,
  583         576,
  584         1006,
  585         1492,
  586         1500,
  587         1536,
  588         2002,
  589         2048,
  590         4352,
  591         4464,
  592         8166,
  593         17914,
  594         32000,
  595         65535
  596 };
  597 
  598 int
  599 find_next_best_mtu(int totsz)
  600 {
  601         int i, perfer;
  602         /*
  603          * if we are in here we must find the next best fit based on the
  604          * size of the dg that failed to be sent.
  605          */
  606         perfer = 0;
  607         for (i = 0; i < NUMBER_OF_MTU_SIZES; i++) {
  608                 if (totsz < sctp_mtu_sizes[i]) {
  609                         perfer = i - 1;
  610                         if (perfer < 0)
  611                                 perfer = 0;
  612                         break;
  613                 }
  614         }
  615         return (sctp_mtu_sizes[perfer]);
  616 }
  617 
  618 uint32_t
  619 sctp_select_initial_TSN(struct sctp_pcb *m)
  620 {
  621         return cprng_strong32();
  622 }
  623 
  624 u_int32_t sctp_select_a_tag(struct sctp_inpcb *m)
  625 {
  626         u_long x, not_done;
  627         struct timeval now;
  628 
  629         SCTP_GETTIME_TIMEVAL(&now);
  630         not_done = 1;
  631         while (not_done) {
  632                 x = sctp_select_initial_TSN(&m->sctp_ep);
  633                 if (x == 0) {
  634                         /* we never use 0 */
  635                         continue;
  636                 }
  637                 if (sctp_is_vtag_good(m, x, &now)) {
  638                         not_done = 0;
  639                 }
  640         }
  641         return (x);
  642 }
  643 
  644 
  645 int
  646 sctp_init_asoc(struct sctp_inpcb *m, struct sctp_association *asoc,
  647                int for_a_init, uint32_t override_tag )
  648 {
  649         /*
  650          * Anything set to zero is taken care of by the allocation
  651          * routine's bzero
  652          */
  653 
  654         /*
  655          * Up front select what scoping to apply on addresses I tell my peer
  656          * Not sure what to do with these right now, we will need to come up
  657          * with a way to set them. We may need to pass them through from the
  658          * caller in the sctp_aloc_assoc() function.
  659          */
  660         int i;
  661         /* init all variables to a known value.*/
  662         asoc->state = SCTP_STATE_INUSE;
  663         asoc->max_burst = m->sctp_ep.max_burst;
  664         asoc->heart_beat_delay = m->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT];
  665         asoc->cookie_life = m->sctp_ep.def_cookie_life;
  666 
  667         if (override_tag) {
  668                 asoc->my_vtag = override_tag;
  669         } else {
  670                 asoc->my_vtag = sctp_select_a_tag(m);
  671         }
  672         asoc->asconf_seq_out = asoc->str_reset_seq_out = asoc->init_seq_number = asoc->sending_seq =
  673                 sctp_select_initial_TSN(&m->sctp_ep);
  674         asoc->t3timeout_highest_marked = asoc->asconf_seq_out;
  675         /* we are opptimisitic here */
  676         asoc->peer_supports_asconf = 1;
  677         asoc->peer_supports_asconf_setprim = 1;
  678         asoc->peer_supports_pktdrop = 1;
  679 
  680         asoc->sent_queue_retran_cnt = 0;
  681         /* This will need to be adjusted */
  682         asoc->last_cwr_tsn = asoc->init_seq_number - 1;
  683         asoc->last_acked_seq = asoc->init_seq_number - 1;
  684         asoc->advanced_peer_ack_point = asoc->last_acked_seq;
  685         asoc->asconf_seq_in = asoc->last_acked_seq;
  686 
  687         /* here we are different, we hold the next one we expect */
  688         asoc->str_reset_seq_in = asoc->last_acked_seq + 1;
  689 
  690         asoc->initial_init_rto_max = m->sctp_ep.initial_init_rto_max;
  691         asoc->initial_rto = m->sctp_ep.initial_rto;
  692 
  693         asoc->max_init_times = m->sctp_ep.max_init_times;
  694         asoc->max_send_times = m->sctp_ep.max_send_times;
  695         asoc->def_net_failure = m->sctp_ep.def_net_failure;
  696 
  697         /* ECN Nonce initialization */
  698         asoc->ecn_nonce_allowed = 0;
  699         asoc->receiver_nonce_sum = 1;
  700         asoc->nonce_sum_expect_base = 1;
  701         asoc->nonce_sum_check = 1;
  702         asoc->nonce_resync_tsn = 0;
  703         asoc->nonce_wait_for_ecne = 0;
  704         asoc->nonce_wait_tsn = 0;
  705 
  706         if (m->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
  707                 struct in6pcb *inp6;
  708 
  709 
  710                 /* Its a V6 socket */
  711                 inp6 = (struct in6pcb *)m;
  712                 asoc->ipv6_addr_legal = 1;
  713                 /* Now look at the binding flag to see if V4 will be legal */
  714         if (
  715 #if defined(__OpenBSD__)
  716                 (0) /* we always do dual bind */
  717 #elif defined (__NetBSD__)
  718                 (inp6->in6p_flags & IN6P_IPV6_V6ONLY)
  719 #else
  720                 (inp6->inp_flags & IN6P_IPV6_V6ONLY)
  721 #endif
  722              == 0) {
  723                         asoc->ipv4_addr_legal = 1;
  724                 } else {
  725                         /* V4 addresses are NOT legal on the association */
  726                         asoc->ipv4_addr_legal = 0;
  727                 }
  728         } else {
  729                 /* Its a V4 socket, no - V6 */
  730                 asoc->ipv4_addr_legal = 1;
  731                 asoc->ipv6_addr_legal = 0;
  732         }
  733 
  734 
  735         asoc->my_rwnd = uimax(m->sctp_socket->so_rcv.sb_hiwat, SCTP_MINIMAL_RWND);
  736         asoc->peers_rwnd = m->sctp_socket->so_rcv.sb_hiwat;
  737 
  738         asoc->smallest_mtu = m->sctp_frag_point;
  739         asoc->minrto = m->sctp_ep.sctp_minrto;
  740         asoc->maxrto = m->sctp_ep.sctp_maxrto;
  741 
  742         LIST_INIT(&asoc->sctp_local_addr_list);
  743         TAILQ_INIT(&asoc->nets);
  744         TAILQ_INIT(&asoc->pending_reply_queue);
  745         asoc->last_asconf_ack_sent = NULL;
  746         /* Setup to fill the hb random cache at first HB */
  747         asoc->hb_random_idx = 4;
  748 
  749         asoc->sctp_autoclose_ticks = m->sctp_ep.auto_close_time;
  750 
  751         /*
  752          * Now the stream parameters, here we allocate space for all
  753          * streams that we request by default.
  754          */
  755         asoc->streamoutcnt = asoc->pre_open_streams =
  756             m->sctp_ep.pre_open_stream_count;
  757         asoc->strmout = malloc(asoc->streamoutcnt *
  758             sizeof(struct sctp_stream_out), M_PCB, M_NOWAIT);
  759         if (asoc->strmout == NULL) {
  760                 /* big trouble no memory */
  761                 return (ENOMEM);
  762         }
  763         for (i = 0; i < asoc->streamoutcnt; i++) {
  764                 /*
  765                  * inbound side must be set to 0xffff,
  766                  * also NOTE when we get the INIT-ACK back (for INIT sender)
  767                  * we MUST reduce the count (streamoutcnt) but first check
  768                  * if we sent to any of the upper streams that were dropped
  769                  * (if some were). Those that were dropped must be notified
  770                  * to the upper layer as failed to send.
  771                  */
  772                 asoc->strmout[i].next_sequence_sent = 0x0;
  773                 TAILQ_INIT(&asoc->strmout[i].outqueue);
  774                 asoc->strmout[i].stream_no = i;
  775                 asoc->strmout[i].next_spoke.tqe_next = 0;
  776                 asoc->strmout[i].next_spoke.tqe_prev = 0;
  777         }
  778         /* Now the mapping array */
  779         asoc->mapping_array_size = SCTP_INITIAL_MAPPING_ARRAY;
  780         asoc->mapping_array = malloc(asoc->mapping_array_size,
  781                M_PCB, M_NOWAIT);
  782         if (asoc->mapping_array == NULL) {
  783                 free(asoc->strmout, M_PCB);
  784                 return (ENOMEM);
  785         }
  786         memset(asoc->mapping_array, 0, asoc->mapping_array_size);
  787         /* Now the init of the other outqueues */
  788         TAILQ_INIT(&asoc->out_wheel);
  789         TAILQ_INIT(&asoc->control_send_queue);
  790         TAILQ_INIT(&asoc->send_queue);
  791         TAILQ_INIT(&asoc->sent_queue);
  792         TAILQ_INIT(&asoc->reasmqueue);
  793         TAILQ_INIT(&asoc->delivery_queue);
  794         asoc->max_inbound_streams = m->sctp_ep.max_open_streams_intome;
  795 
  796         TAILQ_INIT(&asoc->asconf_queue);
  797         return (0);
  798 }
  799 
  800 int
  801 sctp_expand_mapping_array(struct sctp_association *asoc)
  802 {
  803         /* mapping array needs to grow */
  804         u_int8_t *new_array;
  805         uint16_t new_size, old_size;
  806 
  807         old_size = asoc->mapping_array_size;
  808         new_size = old_size + SCTP_MAPPING_ARRAY_INCR;
  809         new_array = malloc(new_size, M_PCB, M_NOWAIT);
  810         if (new_array == NULL) {
  811                 /* can't get more, forget it */
  812                 printf("No memory for expansion of SCTP mapping array %d\n",
  813                        new_size);
  814                 return (-1);
  815         }
  816         memcpy(new_array, asoc->mapping_array, old_size);
  817         memset(new_array + old_size, 0, SCTP_MAPPING_ARRAY_INCR);
  818         free(asoc->mapping_array, M_PCB);
  819         asoc->mapping_array = new_array;
  820         asoc->mapping_array_size = new_size;
  821         return (0);
  822 }
  823 
  824 static void
  825 sctp_timeout_handler(void *t)
  826 {
  827         struct sctp_inpcb *inp;
  828         struct sctp_tcb *stcb;
  829         struct sctp_nets *net;
  830         struct sctp_timer *tmr;
  831         int did_output;
  832 
  833         mutex_enter(softnet_lock);
  834         tmr = (struct sctp_timer *)t;
  835         inp = (struct sctp_inpcb *)tmr->ep;
  836         stcb = (struct sctp_tcb *)tmr->tcb;
  837         net = (struct sctp_nets *)tmr->net;
  838         did_output = 1;
  839 
  840 #ifdef SCTP_AUDITING_ENABLED
  841         sctp_audit_log(0xF0, (u_int8_t)tmr->type);
  842         sctp_auditing(3, inp, stcb, net);
  843 #endif
  844         sctp_pegs[SCTP_TIMERS_EXP]++;
  845 
  846         if (inp == NULL) {
  847                 return;
  848         }
  849 
  850         SCTP_INP_WLOCK(inp);
  851         if (inp->sctp_socket == 0) {
  852                 mutex_exit(softnet_lock);
  853                 SCTP_INP_WUNLOCK(inp);
  854                 return;
  855         }
  856         if (stcb) {
  857                 if (stcb->asoc.state == 0) {
  858                         mutex_exit(softnet_lock);
  859                         SCTP_INP_WUNLOCK(inp);
  860                         return;
  861                 }
  862         }
  863 #ifdef SCTP_DEBUG
  864         if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
  865                 printf("Timer type %d goes off\n", tmr->type);
  866         }
  867 #endif /* SCTP_DEBUG */
  868 #ifndef __NetBSD__
  869         if (!callout_active(&tmr->timer)) {
  870                 SCTP_INP_WUNLOCK(inp);
  871                 return;
  872         }
  873 #endif
  874         if (stcb) {
  875                 SCTP_TCB_LOCK(stcb);
  876         }
  877         SCTP_INP_INCR_REF(inp);
  878         SCTP_INP_WUNLOCK(inp);
  879 
  880         switch (tmr->type) {
  881         case SCTP_TIMER_TYPE_ITERATOR:
  882         {
  883                 struct sctp_iterator *it;
  884                 it = (struct sctp_iterator *)inp;
  885                 sctp_iterator_timer(it);
  886         }
  887         break;
  888         /* call the handler for the appropriate timer type */
  889         case SCTP_TIMER_TYPE_SEND:
  890                 sctp_pegs[SCTP_TMIT_TIMER]++;
  891                 stcb->asoc.num_send_timers_up--;
  892                 if (stcb->asoc.num_send_timers_up < 0) {
  893                         stcb->asoc.num_send_timers_up = 0;
  894                 }
  895                 if (sctp_t3rxt_timer(inp, stcb, net)) {
  896                         /* no need to unlock on tcb its gone */
  897 
  898                         goto out_decr;
  899                 }
  900 #ifdef SCTP_AUDITING_ENABLED
  901                 sctp_auditing(4, inp, stcb, net);
  902 #endif
  903                 sctp_chunk_output(inp, stcb, 1);
  904                 if ((stcb->asoc.num_send_timers_up == 0) &&
  905                     (stcb->asoc.sent_queue_cnt > 0)
  906                         ) {
  907                         struct sctp_tmit_chunk *chk;
  908                         /*
  909                          * safeguard. If there on some on the sent queue
  910                          * somewhere but no timers running something is
  911                          * wrong... so we start a timer on the first chunk
  912                          * on the send queue on whatever net it is sent to.
  913                          */
  914                         sctp_pegs[SCTP_T3_SAFEGRD]++;
  915                         chk = TAILQ_FIRST(&stcb->asoc.sent_queue);
  916                         sctp_timer_start(SCTP_TIMER_TYPE_SEND, inp, stcb,
  917                                          chk->whoTo);
  918                 }
  919                 break;
  920         case SCTP_TIMER_TYPE_INIT:
  921                 if (sctp_t1init_timer(inp, stcb, net)) {
  922                         /* no need to unlock on tcb its gone */
  923                         goto out_decr;
  924                 }
  925                 /* We do output but not here */
  926                 did_output = 0;
  927                 break;
  928         case SCTP_TIMER_TYPE_RECV:
  929                 sctp_pegs[SCTP_RECV_TIMER]++;
  930                 sctp_send_sack(stcb);
  931 #ifdef SCTP_AUDITING_ENABLED
  932                 sctp_auditing(4, inp, stcb, net);
  933 #endif
  934                 sctp_chunk_output(inp, stcb, 4);
  935                 break;
  936         case SCTP_TIMER_TYPE_SHUTDOWN:
  937                 if (sctp_shutdown_timer(inp, stcb, net) ) {
  938                         /* no need to unlock on tcb its gone */
  939                         goto out_decr;
  940                 }
  941 #ifdef SCTP_AUDITING_ENABLED
  942                 sctp_auditing(4, inp, stcb, net);
  943 #endif
  944                 sctp_chunk_output(inp, stcb, 5);
  945                 break;
  946         case SCTP_TIMER_TYPE_HEARTBEAT:
  947                 if (sctp_heartbeat_timer(inp, stcb, net)) {
  948                         /* no need to unlock on tcb its gone */
  949                         goto out_decr;
  950                 }
  951 #ifdef SCTP_AUDITING_ENABLED
  952                 sctp_auditing(4, inp, stcb, net);
  953 #endif
  954                 sctp_chunk_output(inp, stcb, 6);
  955                 break;
  956         case SCTP_TIMER_TYPE_COOKIE:
  957                 if (sctp_cookie_timer(inp, stcb, net)) {
  958                         /* no need to unlock on tcb its gone */
  959                         goto out_decr;
  960                 }
  961 #ifdef SCTP_AUDITING_ENABLED
  962                 sctp_auditing(4, inp, stcb, net);
  963 #endif
  964                 sctp_chunk_output(inp, stcb, 1);
  965                 break;
  966         case SCTP_TIMER_TYPE_NEWCOOKIE:
  967         {
  968                 struct timeval tv;
  969                 int i, secret;
  970                 SCTP_GETTIME_TIMEVAL(&tv);
  971                 SCTP_INP_WLOCK(inp);
  972                 inp->sctp_ep.time_of_secret_change = tv.tv_sec;
  973                 inp->sctp_ep.last_secret_number =
  974                         inp->sctp_ep.current_secret_number;
  975                 inp->sctp_ep.current_secret_number++;
  976                 if (inp->sctp_ep.current_secret_number >=
  977                     SCTP_HOW_MANY_SECRETS) {
  978                         inp->sctp_ep.current_secret_number = 0;
  979                 }
  980                 secret = (int)inp->sctp_ep.current_secret_number;
  981                 for (i = 0; i < SCTP_NUMBER_OF_SECRETS; i++) {
  982                         inp->sctp_ep.secret_key[secret][i] =
  983                                 sctp_select_initial_TSN(&inp->sctp_ep);
  984                 }
  985                 SCTP_INP_WUNLOCK(inp);
  986                 sctp_timer_start(SCTP_TIMER_TYPE_NEWCOOKIE, inp, stcb, net);
  987         }
  988         did_output = 0;
  989         break;
  990         case SCTP_TIMER_TYPE_PATHMTURAISE:
  991                 sctp_pathmtu_timer(inp, stcb, net);
  992                 did_output = 0;
  993                 break;
  994         case SCTP_TIMER_TYPE_SHUTDOWNACK:
  995                 if (sctp_shutdownack_timer(inp, stcb, net)) {
  996                         /* no need to unlock on tcb its gone */
  997                         goto out_decr;
  998                 }
  999 #ifdef SCTP_AUDITING_ENABLED
 1000                 sctp_auditing(4, inp, stcb, net);
 1001 #endif
 1002                 sctp_chunk_output(inp, stcb, 7);
 1003                 break;
 1004         case SCTP_TIMER_TYPE_SHUTDOWNGUARD:
 1005                 sctp_abort_an_association(inp, stcb,
 1006                                           SCTP_SHUTDOWN_GUARD_EXPIRES, NULL);
 1007                 /* no need to unlock on tcb its gone */
 1008                 goto out_decr;
 1009                 break;
 1010 
 1011         case SCTP_TIMER_TYPE_STRRESET:
 1012                 if (sctp_strreset_timer(inp, stcb, net)) {
 1013                         /* no need to unlock on tcb its gone */
 1014                         goto out_decr;
 1015                 }
 1016                 sctp_chunk_output(inp, stcb, 9);
 1017                 break;
 1018 
 1019         case SCTP_TIMER_TYPE_ASCONF:
 1020                 if (sctp_asconf_timer(inp, stcb, net)) {
 1021                         /* no need to unlock on tcb its gone */
 1022                         goto out_decr;
 1023                 }
 1024 #ifdef SCTP_AUDITING_ENABLED
 1025                 sctp_auditing(4, inp, stcb, net);
 1026 #endif
 1027                 sctp_chunk_output(inp, stcb, 8);
 1028                 break;
 1029 
 1030         case SCTP_TIMER_TYPE_AUTOCLOSE:
 1031                 sctp_autoclose_timer(inp, stcb, net);
 1032                 sctp_chunk_output(inp, stcb, 10);
 1033                 did_output = 0;
 1034                 break;
 1035         case SCTP_TIMER_TYPE_INPKILL:
 1036                 /* special case, take away our
 1037                  * increment since WE are the killer
 1038                  */
 1039                 SCTP_INP_WLOCK(inp);
 1040                 SCTP_INP_DECR_REF(inp);
 1041                 SCTP_INP_WUNLOCK(inp);
 1042                 sctp_timer_stop(SCTP_TIMER_TYPE_INPKILL, inp, NULL, NULL);
 1043                 sctp_inpcb_free(inp, 1);
 1044                 goto out_no_decr;
 1045                 break;
 1046         default:
 1047 #ifdef SCTP_DEBUG
 1048                 if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
 1049                         printf("sctp_timeout_handler:unknown timer %d\n",
 1050                                tmr->type);
 1051                 }
 1052 #endif /* SCTP_DEBUG */
 1053                 break;
 1054         };
 1055 #ifdef SCTP_AUDITING_ENABLED
 1056         sctp_audit_log(0xF1, (u_int8_t)tmr->type);
 1057         sctp_auditing(5, inp, stcb, net);
 1058 #endif
 1059         if (did_output) {
 1060                 /*
 1061                  * Now we need to clean up the control chunk chain if an
 1062                  * ECNE is on it. It must be marked as UNSENT again so next
 1063                  * call will continue to send it until such time that we get
 1064                  * a CWR, to remove it. It is, however, less likely that we
 1065                  * will find a ecn echo on the chain though.
 1066                  */
 1067                 sctp_fix_ecn_echo(&stcb->asoc);
 1068         }
 1069         if (stcb) {
 1070                 SCTP_TCB_UNLOCK(stcb);
 1071         }
 1072  out_decr:
 1073         SCTP_INP_WLOCK(inp);
 1074         SCTP_INP_DECR_REF(inp);
 1075         SCTP_INP_WUNLOCK(inp);
 1076 
 1077  out_no_decr:
 1078 
 1079         mutex_exit(softnet_lock);
 1080 }
 1081 
 1082 int
 1083 sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
 1084     struct sctp_nets *net)
 1085 {
 1086         int to_ticks;
 1087         struct sctp_timer *tmr;
 1088 
 1089         if (inp == NULL)
 1090                 return (EFAULT);
 1091 
 1092         to_ticks = 0;
 1093 
 1094         tmr = NULL;
 1095         switch (t_type) {
 1096         case SCTP_TIMER_TYPE_ITERATOR:
 1097         {
 1098                 struct sctp_iterator *it;
 1099                 it = (struct sctp_iterator *)inp;
 1100                 tmr = &it->tmr;
 1101                 to_ticks = SCTP_ITERATOR_TICKS;
 1102         }
 1103         break;
 1104         case SCTP_TIMER_TYPE_SEND:
 1105                 /* Here we use the RTO timer */
 1106         {
 1107                 int rto_val;
 1108                 if ((stcb == NULL) || (net == NULL)) {
 1109                         return (EFAULT);
 1110                 }
 1111                 tmr = &net->rxt_timer;
 1112                 if (net->RTO == 0) {
 1113                         rto_val = stcb->asoc.initial_rto;
 1114                 } else {
 1115                         rto_val = net->RTO;
 1116                 }
 1117                 to_ticks = MSEC_TO_TICKS(rto_val);
 1118         }
 1119         break;
 1120         case SCTP_TIMER_TYPE_INIT:
 1121                 /*
 1122                  * Here we use the INIT timer default
 1123                  * usually about 1 minute.
 1124                  */
 1125                 if ((stcb == NULL) || (net == NULL)) {
 1126                         return (EFAULT);
 1127                 }
 1128                 tmr = &net->rxt_timer;
 1129                 if (net->RTO == 0) {
 1130                         to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
 1131                 } else {
 1132                         to_ticks = MSEC_TO_TICKS(net->RTO);
 1133                 }
 1134                 break;
 1135         case SCTP_TIMER_TYPE_RECV:
 1136                 /*
 1137                  * Here we use the Delayed-Ack timer value from the inp
 1138                  * ususually about 200ms.
 1139                  */
 1140                 if (stcb == NULL) {
 1141                         return (EFAULT);
 1142                 }
 1143                 tmr = &stcb->asoc.dack_timer;
 1144                 to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV];
 1145                 break;
 1146         case SCTP_TIMER_TYPE_SHUTDOWN:
 1147                 /* Here we use the RTO of the destination. */
 1148                 if ((stcb == NULL) || (net == NULL)) {
 1149                         return (EFAULT);
 1150                 }
 1151 
 1152                 if (net->RTO == 0) {
 1153                         to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
 1154                 } else {
 1155                         to_ticks = MSEC_TO_TICKS(net->RTO);
 1156                 }
 1157                 tmr = &net->rxt_timer;
 1158                 break;
 1159         case SCTP_TIMER_TYPE_HEARTBEAT:
 1160                 /*
 1161                  * the net is used here so that we can add in the RTO.
 1162                  * Even though we use a different timer. We also add the
 1163                  * HB timer PLUS a random jitter.
 1164                  */
 1165                 if (stcb == NULL) {
 1166                         return (EFAULT);
 1167                 }
 1168                 {
 1169                         uint32_t rndval;
 1170                         uint8_t this_random;
 1171                         int cnt_of_unconf=0;
 1172                         struct sctp_nets *lnet;
 1173 
 1174                         TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) {
 1175                                 if (lnet->dest_state & SCTP_ADDR_UNCONFIRMED) {
 1176                                         cnt_of_unconf++;
 1177                                 }
 1178                         }
 1179 #ifdef SCTP_DEBUG
 1180                         if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
 1181                                 printf("HB timer to start unconfirmed:%d hb_delay:%d\n",
 1182                                        cnt_of_unconf, stcb->asoc.heart_beat_delay);
 1183                         }
 1184 #endif
 1185                         if (stcb->asoc.hb_random_idx > 3) {
 1186                                 rndval = sctp_select_initial_TSN(&inp->sctp_ep);
 1187                                 memcpy(stcb->asoc.hb_random_values, &rndval,
 1188                                        sizeof(stcb->asoc.hb_random_values));
 1189                                 this_random = stcb->asoc.hb_random_values[0];
 1190                                 stcb->asoc.hb_random_idx = 0;
 1191                                 stcb->asoc.hb_ect_randombit = 0;
 1192                         } else {
 1193                                 this_random = stcb->asoc.hb_random_values[stcb->asoc.hb_random_idx];
 1194                                 stcb->asoc.hb_random_idx++;
 1195                                 stcb->asoc.hb_ect_randombit = 0;
 1196                         }
 1197                         /*
 1198                          * this_random will be 0 - 256 ms
 1199                          * RTO is in ms.
 1200                          */
 1201                         if ((stcb->asoc.heart_beat_delay == 0) &&
 1202                             (cnt_of_unconf == 0)) {
 1203                                 /* no HB on this inp after confirmations */
 1204                                 return (0);
 1205                         }
 1206                         if (net) {
 1207                                 int delay;
 1208                                 delay = stcb->asoc.heart_beat_delay;
 1209                                 TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) {
 1210                                         if ((lnet->dest_state & SCTP_ADDR_UNCONFIRMED) &&
 1211                                             ((lnet->dest_state & SCTP_ADDR_OUT_OF_SCOPE) == 0) &&
 1212                                             (lnet->dest_state & SCTP_ADDR_REACHABLE)) {
 1213                                             delay = 0;
 1214                                         }
 1215                                 }
 1216                                 if (net->RTO == 0) {
 1217                                         /* Never been checked */
 1218                                         to_ticks = this_random + stcb->asoc.initial_rto + delay;
 1219                                 } else {
 1220                                         /* set rto_val to the ms */
 1221                                         to_ticks = delay + net->RTO + this_random;
 1222                                 }
 1223                         } else {
 1224                                 if (cnt_of_unconf) {
 1225                                         to_ticks = this_random + stcb->asoc.initial_rto;
 1226                                 } else {
 1227                                         to_ticks = stcb->asoc.heart_beat_delay + this_random + stcb->asoc.initial_rto;
 1228                                 }
 1229                         }
 1230                         /*
 1231                          * Now we must convert the to_ticks that are now in
 1232                          * ms to ticks.
 1233                          */
 1234                         to_ticks *= hz;
 1235                         to_ticks /= 1000;
 1236 #ifdef SCTP_DEBUG
 1237                         if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
 1238                                 printf("Timer to expire in %d ticks\n", to_ticks);
 1239                         }
 1240 #endif
 1241                         tmr = &stcb->asoc.hb_timer;
 1242                 }
 1243                 break;
 1244         case SCTP_TIMER_TYPE_COOKIE:
 1245                 /*
 1246                  * Here we can use the RTO timer from the network since
 1247                  * one RTT was compelete. If a retran happened then we will
 1248                  * be using the RTO initial value.
 1249                  */
 1250                 if ((stcb == NULL) || (net == NULL)) {
 1251                         return (EFAULT);
 1252                 }
 1253                 if (net->RTO == 0) {
 1254                         to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
 1255                 } else {
 1256                         to_ticks = MSEC_TO_TICKS(net->RTO);
 1257                 }
 1258                 tmr = &net->rxt_timer;
 1259                 break;
 1260         case SCTP_TIMER_TYPE_NEWCOOKIE:
 1261                 /*
 1262                  * nothing needed but the endpoint here
 1263                  * ususually about 60 minutes.
 1264                  */
 1265                 tmr = &inp->sctp_ep.signature_change;
 1266                 to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_SIGNATURE];
 1267                 break;
 1268         case SCTP_TIMER_TYPE_INPKILL:
 1269                 /*
 1270                  * The inp is setup to die. We re-use the
 1271                  * signature_change timer since that has
 1272                  * stopped and we are in the GONE state.
 1273                  */
 1274                 tmr = &inp->sctp_ep.signature_change;
 1275                 to_ticks = (SCTP_INP_KILL_TIMEOUT * hz) / 1000;
 1276                 break;
 1277         case SCTP_TIMER_TYPE_PATHMTURAISE:
 1278                 /*
 1279                  * Here we use the value found in the EP for PMTU
 1280                  * ususually about 10 minutes.
 1281                  */
 1282                 if (stcb == NULL) {
 1283                         return (EFAULT);
 1284                 }
 1285                 if (net == NULL) {
 1286                         return (EFAULT);
 1287                 }
 1288                 to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_PMTU];
 1289                 tmr = &net->pmtu_timer;
 1290                 break;
 1291         case SCTP_TIMER_TYPE_SHUTDOWNACK:
 1292                 /* Here we use the RTO of the destination */
 1293                 if ((stcb == NULL) || (net == NULL)) {
 1294                         return (EFAULT);
 1295                 }
 1296                 if (net->RTO == 0) {
 1297                         to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
 1298                 } else {
 1299                         to_ticks = MSEC_TO_TICKS(net->RTO);
 1300                 }
 1301                 tmr = &net->rxt_timer;
 1302                 break;
 1303         case SCTP_TIMER_TYPE_SHUTDOWNGUARD:
 1304                 /*
 1305                  * Here we use the endpoints shutdown guard timer
 1306                  * usually about 3 minutes.
 1307                  */
 1308                 if (stcb == NULL) {
 1309                         return (EFAULT);
 1310                 }
 1311                 to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_MAXSHUTDOWN];
 1312                 tmr = &stcb->asoc.shut_guard_timer;
 1313                 break;
 1314         case SCTP_TIMER_TYPE_STRRESET:
 1315                 /*
 1316                  * Here the timer comes from the inp
 1317                  * but its value is from the RTO.
 1318                  */
 1319                 if ((stcb == NULL) || (net == NULL)) {
 1320                         return (EFAULT);
 1321                 }
 1322                 if (net->RTO == 0) {
 1323                         to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
 1324                 } else {
 1325                         to_ticks = MSEC_TO_TICKS(net->RTO);
 1326                 }
 1327                 tmr = &stcb->asoc.strreset_timer;
 1328                 break;
 1329 
 1330         case SCTP_TIMER_TYPE_ASCONF:
 1331                 /*
 1332                  * Here the timer comes from the inp
 1333                  * but its value is from the RTO.
 1334                  */
 1335                 if ((stcb == NULL) || (net == NULL)) {
 1336                         return (EFAULT);
 1337                 }
 1338                 if (net->RTO == 0) {
 1339                         to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
 1340                 } else {
 1341                         to_ticks = MSEC_TO_TICKS(net->RTO);
 1342                 }
 1343                 tmr = &stcb->asoc.asconf_timer;
 1344                 break;
 1345         case SCTP_TIMER_TYPE_AUTOCLOSE:
 1346                 if (stcb == NULL) {
 1347                         return (EFAULT);
 1348                 }
 1349                 if (stcb->asoc.sctp_autoclose_ticks == 0) {
 1350                         /* Really an error since stcb is NOT set to autoclose */
 1351                         return (0);
 1352                 }
 1353                 to_ticks = stcb->asoc.sctp_autoclose_ticks;
 1354                 tmr = &stcb->asoc.autoclose_timer;
 1355                 break;
 1356         default:
 1357 #ifdef SCTP_DEBUG
 1358                 if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
 1359                         printf("sctp_timer_start:Unknown timer type %d\n",
 1360                                t_type);
 1361                 }
 1362 #endif /* SCTP_DEBUG */
 1363                 return (EFAULT);
 1364                 break;
 1365         };
 1366         if ((to_ticks <= 0) || (tmr == NULL)) {
 1367 #ifdef SCTP_DEBUG
 1368                 if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
 1369                         printf("sctp_timer_start:%d:software error to_ticks:%d tmr:%p not set ??\n",
 1370                                t_type, to_ticks, tmr);
 1371                 }
 1372 #endif /* SCTP_DEBUG */
 1373                 return (EFAULT);
 1374         }
 1375         if (callout_pending(&tmr->timer)) {
 1376                 /*
 1377                  * we do NOT allow you to have it already running.
 1378                  * if it is we leave the current one up unchanged
 1379                  */
 1380                 return (EALREADY);
 1381         }
 1382         /* At this point we can proceed */
 1383         if (t_type == SCTP_TIMER_TYPE_SEND) {
 1384                 stcb->asoc.num_send_timers_up++;
 1385         }
 1386         tmr->type = t_type;
 1387         tmr->ep = (void *)inp;
 1388         tmr->tcb = (void *)stcb;
 1389         tmr->net = (void *)net;
 1390         callout_reset(&tmr->timer, to_ticks, sctp_timeout_handler, tmr);
 1391         return (0);
 1392 }
 1393 
 1394 int
 1395 sctp_timer_stop(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
 1396                 struct sctp_nets *net)
 1397 {
 1398         struct sctp_timer *tmr;
 1399 
 1400         if (inp == NULL)
 1401                 return (EFAULT);
 1402 
 1403         tmr = NULL;
 1404         switch (t_type) {
 1405         case SCTP_TIMER_TYPE_ITERATOR:
 1406         {
 1407                 struct sctp_iterator *it;
 1408                 it = (struct sctp_iterator *)inp;
 1409                 tmr = &it->tmr;
 1410         }
 1411         break;
 1412         case SCTP_TIMER_TYPE_SEND:
 1413                 if ((stcb == NULL) || (net == NULL)) {
 1414                         return (EFAULT);
 1415                 }
 1416                 tmr = &net->rxt_timer;
 1417                 break;
 1418         case SCTP_TIMER_TYPE_INIT:
 1419                 if ((stcb == NULL) || (net == NULL)) {
 1420                         return (EFAULT);
 1421                 }
 1422                 tmr = &net->rxt_timer;
 1423                 break;
 1424         case SCTP_TIMER_TYPE_RECV:
 1425                 if (stcb == NULL) {
 1426                         return (EFAULT);
 1427                 }
 1428                 tmr = &stcb->asoc.dack_timer;
 1429                 break;
 1430         case SCTP_TIMER_TYPE_SHUTDOWN:
 1431                 if ((stcb == NULL) || (net == NULL)) {
 1432                         return (EFAULT);
 1433                 }
 1434                 tmr = &net->rxt_timer;
 1435                 break;
 1436         case SCTP_TIMER_TYPE_HEARTBEAT:
 1437                 if (stcb == NULL) {
 1438                         return (EFAULT);
 1439                 }
 1440                 tmr = &stcb->asoc.hb_timer;
 1441                 break;
 1442         case SCTP_TIMER_TYPE_COOKIE:
 1443                 if ((stcb == NULL) || (net == NULL)) {
 1444                         return (EFAULT);
 1445                 }
 1446                 tmr = &net->rxt_timer;
 1447                 break;
 1448         case SCTP_TIMER_TYPE_NEWCOOKIE:
 1449                 /* nothing needed but the endpoint here */
 1450                 tmr = &inp->sctp_ep.signature_change;
 1451                 /* We re-use the newcookie timer for
 1452                  * the INP kill timer. We must assure
 1453                  * that we do not kill it by accident.
 1454                  */
 1455                 break;
 1456         case SCTP_TIMER_TYPE_INPKILL:
 1457                 /*
 1458                  * The inp is setup to die. We re-use the
 1459                  * signature_change timer since that has
 1460                  * stopped and we are in the GONE state.
 1461                  */
 1462                 tmr = &inp->sctp_ep.signature_change;
 1463                 break;
 1464         case SCTP_TIMER_TYPE_PATHMTURAISE:
 1465                 if (stcb == NULL) {
 1466                         return (EFAULT);
 1467                 }
 1468                 if (net == NULL) {
 1469                         return (EFAULT);
 1470                 }
 1471                 tmr = &net->pmtu_timer;
 1472                 break;
 1473         case SCTP_TIMER_TYPE_SHUTDOWNACK:
 1474                 if ((stcb == NULL) || (net == NULL)) {
 1475                         return (EFAULT);
 1476                 }
 1477                 tmr = &net->rxt_timer;
 1478                 break;
 1479         case SCTP_TIMER_TYPE_SHUTDOWNGUARD:
 1480                 if (stcb == NULL) {
 1481                         return (EFAULT);
 1482                 }
 1483                 tmr = &stcb->asoc.shut_guard_timer;
 1484                 break;
 1485         case SCTP_TIMER_TYPE_STRRESET:
 1486                 if (stcb == NULL) {
 1487                         return (EFAULT);
 1488                 }
 1489                 tmr = &stcb->asoc.strreset_timer;
 1490                 break;
 1491         case SCTP_TIMER_TYPE_ASCONF:
 1492                 if (stcb == NULL) {
 1493                         return (EFAULT);
 1494                 }
 1495                 tmr = &stcb->asoc.asconf_timer;
 1496                 break;
 1497         case SCTP_TIMER_TYPE_AUTOCLOSE:
 1498                 if (stcb == NULL) {
 1499                         return (EFAULT);
 1500                 }
 1501                 tmr = &stcb->asoc.autoclose_timer;
 1502                 break;
 1503         default:
 1504 #ifdef SCTP_DEBUG
 1505                 if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
 1506                         printf("sctp_timer_stop:Unknown timer type %d\n",
 1507                                t_type);
 1508                 }
 1509 #endif /* SCTP_DEBUG */
 1510                 break;
 1511         };
 1512         if (tmr == NULL)
 1513                 return (EFAULT);
 1514 
 1515         if ((tmr->type != t_type) && tmr->type) {
 1516                 /*
 1517                  * Ok we have a timer that is under joint use. Cookie timer
 1518                  * per chance with the SEND timer. We therefore are NOT
 1519                  * running the timer that the caller wants stopped.  So just
 1520                  * return.
 1521                  */
 1522                 return (0);
 1523         }
 1524         if (t_type == SCTP_TIMER_TYPE_SEND) {
 1525                 stcb->asoc.num_send_timers_up--;
 1526                 if (stcb->asoc.num_send_timers_up < 0) {
 1527                         stcb->asoc.num_send_timers_up = 0;
 1528                 }
 1529         }
 1530         callout_stop(&tmr->timer);
 1531         return (0);
 1532 }
 1533 
 1534 u_int32_t
 1535 sctp_calculate_len(struct mbuf *m)
 1536 {
 1537         u_int32_t tlen=0;
 1538         struct mbuf *at;
 1539         at = m;
 1540         while (at) {
 1541                 tlen += at->m_len;
 1542                 at = at->m_next;
 1543         }
 1544         return (tlen);
 1545 }
 1546 
 1547 uint32_t
 1548 sctp_calculate_sum(struct mbuf *m, int32_t *pktlen, uint32_t offset)
 1549 {
 1550         /*
 1551          * given a mbuf chain with a packetheader offset by 'offset'
 1552          * pointing at a sctphdr (with csum set to 0) go through
 1553          * the chain of m_next's and calculate the SCTP checksum.
 1554          * This is CRC32c.
 1555          * Also has a side bonus calculate the total length
 1556          * of the mbuf chain.
 1557          * Note: if offset is greater than the total mbuf length,
 1558          * checksum=1, pktlen=0 is returned (ie. no real error code)
 1559          */
 1560         int32_t tlen=0;
 1561         uint32_t base = 0xffffffff;
 1562         struct mbuf *at;
 1563         at = m;
 1564         /* find the correct mbuf and offset into mbuf */
 1565         while ((at != NULL) && (offset > (uint32_t)at->m_len)) {
 1566                 offset -= at->m_len;    /* update remaining offset left */
 1567                 at = at->m_next;
 1568         }
 1569 
 1570         while (at != NULL) {
 1571                 base = update_crc32(base, at->m_data + offset,
 1572                     at->m_len - offset);
 1573                 tlen += at->m_len - offset;
 1574                 /* we only offset once into the first mbuf */
 1575                 if (offset) {
 1576                         offset = 0;
 1577                 }
 1578                 at = at->m_next;
 1579         }
 1580         if (pktlen != NULL) {
 1581                 *pktlen = tlen;
 1582         }
 1583         /* CRC-32c */
 1584         base = sctp_csum_finalize(base);
 1585         return (base);
 1586 }
 1587 
 1588 void
 1589 sctp_mtu_size_reset(struct sctp_inpcb *inp,
 1590                     struct sctp_association *asoc, u_long mtu)
 1591 {
 1592         /*
 1593          * Reset the P-MTU size on this association, this involves changing
 1594          * the asoc MTU, going through ANY chunk+overhead larger than mtu
 1595          * to allow the DF flag to be cleared.
 1596          */
 1597         struct sctp_tmit_chunk *chk;
 1598         struct sctp_stream_out *strm;
 1599         unsigned int eff_mtu, ovh;
 1600         asoc->smallest_mtu = mtu;
 1601         if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
 1602                 ovh = SCTP_MIN_OVERHEAD;
 1603         } else {
 1604                 ovh = SCTP_MIN_V4_OVERHEAD;
 1605         }
 1606         eff_mtu = mtu - ovh;
 1607         /* Now mark any chunks that need to let IP fragment */
 1608         TAILQ_FOREACH(strm, &asoc->out_wheel, next_spoke) {
 1609                 TAILQ_FOREACH(chk, &strm->outqueue, sctp_next) {
 1610                         if (chk->send_size > eff_mtu) {
 1611                                 chk->flags &= SCTP_DONT_FRAGMENT;
 1612                                 chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
 1613                         }
 1614                 }
 1615         }
 1616         TAILQ_FOREACH(chk, &asoc->send_queue, sctp_next) {
 1617                 if (chk->send_size > eff_mtu) {
 1618                         chk->flags &= SCTP_DONT_FRAGMENT;
 1619                         chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
 1620                 }
 1621         }
 1622         TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) {
 1623                 if (chk->send_size > eff_mtu) {
 1624                         chk->flags &= SCTP_DONT_FRAGMENT;
 1625                         chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
 1626                 }
 1627         }
 1628 }
 1629 
 1630 
 1631 /*
 1632  * given an association and starting time of the current RTT period
 1633  * return RTO in number of usecs
 1634  * net should point to the current network
 1635  */
 1636 u_int32_t
 1637 sctp_calculate_rto(struct sctp_tcb *stcb,
 1638                    struct sctp_association *asoc,
 1639                    struct sctp_nets *net,
 1640                    struct timeval *old)
 1641 {
 1642         /*
 1643          * given an association and the starting time of the current RTT
 1644          * period (in value1/value2) return RTO in number of usecs.
 1645          */
 1646         int calc_time = 0;
 1647         unsigned int new_rto = 0;
 1648         int first_measure = 0;
 1649         struct timeval now;
 1650 
 1651         /************************/
 1652         /* 1. calculate new RTT */
 1653         /************************/
 1654         /* get the current time */
 1655         SCTP_GETTIME_TIMEVAL(&now);
 1656         /* compute the RTT value */
 1657         if ((u_long)now.tv_sec > (u_long)old->tv_sec) {
 1658                 calc_time = ((u_long)now.tv_sec - (u_long)old->tv_sec) * 1000;
 1659                 if ((u_long)now.tv_usec > (u_long)old->tv_usec) {
 1660                         calc_time += (((u_long)now.tv_usec -
 1661                                        (u_long)old->tv_usec)/1000);
 1662                 } else if ((u_long)now.tv_usec < (u_long)old->tv_usec) {
 1663                         /* Borrow 1,000ms from current calculation */
 1664                         calc_time -= 1000;
 1665                         /* Add in the slop over */
 1666                         calc_time += ((int)now.tv_usec/1000);
 1667                         /* Add in the pre-second ms's */
 1668                         calc_time += (((int)1000000 - (int)old->tv_usec)/1000);
 1669                 }
 1670         } else if ((u_long)now.tv_sec == (u_long)old->tv_sec) {
 1671                 if ((u_long)now.tv_usec > (u_long)old->tv_usec) {
 1672                         calc_time = ((u_long)now.tv_usec -
 1673                                      (u_long)old->tv_usec)/1000;
 1674                 } else if ((u_long)now.tv_usec < (u_long)old->tv_usec) {
 1675                         /* impossible .. garbage in nothing out */
 1676                         return (((net->lastsa >> 2) + net->lastsv) >> 1);
 1677                 } else {
 1678                         /* impossible .. garbage in nothing out */
 1679                         return (((net->lastsa >> 2) + net->lastsv) >> 1);
 1680                 }
 1681         } else {
 1682                 /* Clock wrapped? */
 1683                 return (((net->lastsa >> 2) + net->lastsv) >> 1);
 1684         }
 1685         /***************************/
 1686         /* 2. update RTTVAR & SRTT */
 1687         /***************************/
 1688 #if 0
 1689         /*      if (net->lastsv || net->lastsa) {*/
 1690         /* per Section 5.3.1 C3 in SCTP */
 1691         /*              net->lastsv = (int)     *//* RTTVAR */
 1692         /*                      (((double)(1.0 - 0.25) * (double)net->lastsv) +
 1693                                 (double)(0.25 * (double)abs(net->lastsa - calc_time)));
 1694                                 net->lastsa = (int) */  /* SRTT */
 1695         /*(((double)(1.0 - 0.125) * (double)net->lastsa) +
 1696           (double)(0.125 * (double)calc_time));
 1697           } else {
 1698         *//* the first RTT calculation, per C2 Section 5.3.1 */
 1699         /*              net->lastsa = calc_time;        *//* SRTT */
 1700         /*              net->lastsv = calc_time / 2;    *//* RTTVAR */
 1701         /*      }*/
 1702         /* if RTTVAR goes to 0 you set to clock grainularity */
 1703         /*      if (net->lastsv == 0) {
 1704                 net->lastsv = SCTP_CLOCK_GRANULARITY;
 1705                 }
 1706                 new_rto = net->lastsa + 4 * net->lastsv;
 1707         */
 1708 #endif
 1709         /* this is Van Jacobson's integer version */
 1710         if (net->RTO) {
 1711                 calc_time -= (net->lastsa >> 3);
 1712                 net->lastsa += calc_time;
 1713                 if (calc_time < 0) {
 1714                         calc_time = -calc_time;
 1715                 }
 1716                 calc_time -= (net->lastsv >> 2);
 1717                 net->lastsv += calc_time;
 1718                 if (net->lastsv == 0) {
 1719                         net->lastsv = SCTP_CLOCK_GRANULARITY;
 1720                 }
 1721         } else {
 1722                 /* First RTO measurement */
 1723                 net->lastsa = calc_time;
 1724                 net->lastsv = calc_time >> 1;
 1725                 first_measure = 1;
 1726         }
 1727         new_rto = ((net->lastsa >> 2) + net->lastsv) >> 1;
 1728         if ((new_rto > SCTP_SAT_NETWORK_MIN) &&
 1729             (stcb->asoc.sat_network_lockout == 0)) {
 1730                 stcb->asoc.sat_network = 1;
 1731         } else  if ((!first_measure) && stcb->asoc.sat_network) {
 1732                 stcb->asoc.sat_network = 0;
 1733                 stcb->asoc.sat_network_lockout = 1;
 1734         }
 1735         /* bound it, per C6/C7 in Section 5.3.1 */
 1736         if (new_rto < stcb->asoc.minrto) {
 1737                 new_rto = stcb->asoc.minrto;
 1738         }
 1739         if (new_rto > stcb->asoc.maxrto) {
 1740                 new_rto = stcb->asoc.maxrto;
 1741         }
 1742         /* we are now returning the RTT Smoothed */
 1743         return ((u_int32_t)new_rto);
 1744 }
 1745 
 1746 
 1747 /*
 1748  * return a pointer to a contiguous piece of data from the given
 1749  * mbuf chain starting at 'off' for 'len' bytes.  If the desired
 1750  * piece spans more than one mbuf, a copy is made at 'ptr'.
 1751  * caller must ensure that the buffer size is >= 'len'
 1752  * returns NULL if there there isn't 'len' bytes in the chain.
 1753  */
 1754 void *
 1755 sctp_m_getptr(struct mbuf *m, int off, int len, u_int8_t *in_ptr)
 1756 {
 1757         uint32_t count;
 1758         uint8_t *ptr;
 1759         ptr = in_ptr;
 1760         if ((off < 0) || (len <= 0))
 1761                 return (NULL);
 1762 
 1763         /* find the desired start location */
 1764         while ((m != NULL) && (off > 0)) {
 1765                 if (off < m->m_len)
 1766                         break;
 1767                 off -= m->m_len;
 1768                 m = m->m_next;
 1769         }
 1770         if (m == NULL)
 1771                 return (NULL);
 1772 
 1773         /* is the current mbuf large enough (eg. contiguous)? */
 1774         if ((m->m_len - off) >= len) {
 1775                 return ((void *)(mtod(m, vaddr_t) + off));
 1776         } else {
 1777                 /* else, it spans more than one mbuf, so save a temp copy... */
 1778                 while ((m != NULL) && (len > 0)) {
 1779                         count = uimin(m->m_len - off, len);
 1780                         memcpy(ptr, (void *)(mtod(m, vaddr_t) + off), count);
 1781                         len -= count;
 1782                         ptr += count;
 1783                         off = 0;
 1784                         m = m->m_next;
 1785                 }
 1786                 if ((m == NULL) && (len > 0))
 1787                         return (NULL);
 1788                 else
 1789                         return ((void *)in_ptr);
 1790         }
 1791 }
 1792 
 1793 
 1794 struct sctp_paramhdr *
 1795 sctp_get_next_param(struct mbuf *m,
 1796                     int offset,
 1797                     struct sctp_paramhdr *pull,
 1798                     int pull_limit)
 1799 {
 1800         /* This just provides a typed signature to Peter's Pull routine */
 1801         return ((struct sctp_paramhdr *)sctp_m_getptr(m, offset, pull_limit,
 1802             (u_int8_t *)pull));
 1803 }
 1804 
 1805 
 1806 int
 1807 sctp_add_pad_tombuf(struct mbuf *m, int padlen)
 1808 {
 1809         /*
 1810          * add padlen bytes of 0 filled padding to the end of the mbuf.
 1811          * If padlen is > 3 this routine will fail.
 1812          */
 1813         u_int8_t *dp;
 1814         int i;
 1815         if (padlen > 3) {
 1816                 return (ENOBUFS);
 1817         }
 1818         if (M_TRAILINGSPACE(m)) {
 1819                 /*
 1820                  * The easy way.
 1821                  * We hope the majority of the time we hit here :)
 1822                  */
 1823                 dp = (u_int8_t *)(mtod(m, vaddr_t) + m->m_len);
 1824                 m->m_len += padlen;
 1825         } else {
 1826                 /* Hard way we must grow the mbuf */
 1827                 struct mbuf *tmp;
 1828                 MGET(tmp, M_DONTWAIT, MT_DATA);
 1829                 if (tmp == NULL) {
 1830                         /* Out of space GAK! we are in big trouble. */
 1831                         return (ENOSPC);
 1832                 }
 1833                 /* setup and insert in middle */
 1834                 tmp->m_next = m->m_next;
 1835                 tmp->m_len = padlen;
 1836                 m->m_next = tmp;
 1837                 dp = mtod(tmp, u_int8_t *);
 1838         }
 1839         /* zero out the pad */
 1840         for (i=  0; i < padlen; i++) {
 1841                 *dp = 0;
 1842                 dp++;
 1843         }
 1844         return (0);
 1845 }
 1846 
 1847 int
 1848 sctp_pad_lastmbuf(struct mbuf *m, int padval)
 1849 {
 1850         /* find the last mbuf in chain and pad it */
 1851         struct mbuf *m_at;
 1852         m_at = m;
 1853         while (m_at) {
 1854                 if (m_at->m_next == NULL) {
 1855                         return (sctp_add_pad_tombuf(m_at, padval));
 1856                 }
 1857                 m_at = m_at->m_next;
 1858         }
 1859         return (EFAULT);
 1860 }
 1861 
 1862 static void
 1863 sctp_notify_assoc_change(u_int32_t event, struct sctp_tcb *stcb,
 1864     u_int32_t error)
 1865 {
 1866         struct mbuf *m_notify;
 1867         struct sctp_assoc_change *sac;
 1868         const struct sockaddr *to;
 1869         struct sockaddr_in6 sin6, lsa6;
 1870 
 1871 #ifdef SCTP_DEBUG
 1872         printf("notify: %d\n", event);
 1873 #endif
 1874         /*
 1875          * First if we are going down dump everything we
 1876          * can to the socket rcv queue.
 1877          */
 1878         if ((event == SCTP_SHUTDOWN_COMP) || (event == SCTP_COMM_LOST)) {
 1879                 sctp_deliver_data(stcb, &stcb->asoc, NULL, 0);
 1880         }
 1881 
 1882         /*
 1883          * For TCP model AND UDP connected sockets we will send
 1884          * an error up when an ABORT comes in.
 1885          */
 1886         if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
 1887              (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) &&
 1888             (event == SCTP_COMM_LOST)) {
 1889                 stcb->sctp_socket->so_error = ECONNRESET;
 1890                 /* Wake ANY sleepers */
 1891                 sowwakeup(stcb->sctp_socket);
 1892                 sorwakeup(stcb->sctp_socket);
 1893         }
 1894 #if 0
 1895         if ((event == SCTP_COMM_UP) &&
 1896             (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
 1897             (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) {
 1898                  soisconnected(stcb->sctp_socket);
 1899         }
 1900 #endif
 1901         if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_RECVASSOCEVNT)) {
 1902                 /* event not enabled */
 1903                 return;
 1904         }
 1905         MGETHDR(m_notify, M_DONTWAIT, MT_DATA);
 1906         if (m_notify == NULL)
 1907                 /* no space left */
 1908                 return;
 1909         m_notify->m_len = 0;
 1910 
 1911         sac = mtod(m_notify, struct sctp_assoc_change *);
 1912         sac->sac_type = SCTP_ASSOC_CHANGE;
 1913         sac->sac_flags = 0;
 1914         sac->sac_length = sizeof(struct sctp_assoc_change);
 1915         sac->sac_state = event;
 1916         sac->sac_error = error;
 1917         /* XXX verify these stream counts */
 1918         sac->sac_outbound_streams = stcb->asoc.streamoutcnt;
 1919         sac->sac_inbound_streams = stcb->asoc.streamincnt;
 1920         sac->sac_assoc_id = sctp_get_associd(stcb);
 1921 
 1922         m_notify->m_flags |= M_EOR | M_NOTIFICATION;
 1923         m_notify->m_pkthdr.len = sizeof(struct sctp_assoc_change);
 1924         m_reset_rcvif(m_notify);
 1925         m_notify->m_len = sizeof(struct sctp_assoc_change);
 1926         m_notify->m_next = NULL;
 1927 
 1928         /* append to socket */
 1929         to = rtcache_getdst(&stcb->asoc.primary_destination->ro);
 1930         if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
 1931             to->sa_family == AF_INET) {
 1932                 const struct sockaddr_in *sin;
 1933 
 1934                 sin = (const struct sockaddr_in *)to;
 1935                 in6_sin_2_v4mapsin6(sin, &sin6);
 1936                 to = (struct sockaddr *)&sin6;
 1937         }
 1938         /* check and strip embedded scope junk */
 1939         to = (const struct sockaddr *)sctp_recover_scope((const struct sockaddr_in6 *)to,
 1940                                                    &lsa6);
 1941         /*
 1942          * We need to always notify comm changes.
 1943          * if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) {
 1944          *      sctp_m_freem(m_notify);
 1945          *      return;
 1946          * }
 1947         */
 1948         SCTP_TCB_UNLOCK(stcb);
 1949         SCTP_INP_WLOCK(stcb->sctp_ep);
 1950         SCTP_TCB_LOCK(stcb);
 1951         if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv,
 1952             to, m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) {
 1953                 /* not enough room */
 1954                 sctp_m_freem(m_notify);
 1955                 SCTP_INP_WUNLOCK(stcb->sctp_ep);
 1956                 return;
 1957         }
 1958         if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) &&
 1959            ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){
 1960                 if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) {
 1961                         stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
 1962                 }
 1963         } else {
 1964                 stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
 1965         }
 1966         SCTP_INP_WUNLOCK(stcb->sctp_ep);
 1967         /* Wake up any sleeper */
 1968         sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
 1969         sctp_sowwakeup(stcb->sctp_ep, stcb->sctp_socket);
 1970 }
 1971 
 1972 static void
 1973 sctp_notify_peer_addr_change(struct sctp_tcb *stcb, uint32_t state,
 1974     const struct sockaddr *sa, uint32_t error)
 1975 {
 1976         struct mbuf *m_notify;
 1977         struct sctp_paddr_change *spc;
 1978         const struct sockaddr *to;
 1979         struct sockaddr_in6 sin6, lsa6;
 1980 
 1981         if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_RECVPADDREVNT))
 1982                 /* event not enabled */
 1983                 return;
 1984 
 1985         MGETHDR(m_notify, M_DONTWAIT, MT_DATA);
 1986         if (m_notify == NULL)
 1987                 return;
 1988         m_notify->m_len = 0;
 1989 
 1990         MCLGET(m_notify, M_DONTWAIT);
 1991         if ((m_notify->m_flags & M_EXT) != M_EXT) {
 1992                 sctp_m_freem(m_notify);
 1993                 return;
 1994         }
 1995 
 1996         spc = mtod(m_notify, struct sctp_paddr_change *);
 1997         spc->spc_type = SCTP_PEER_ADDR_CHANGE;
 1998         spc->spc_flags = 0;
 1999         spc->spc_length = sizeof(struct sctp_paddr_change);
 2000         if (sa->sa_family == AF_INET) {
 2001                 memcpy(&spc->spc_aaddr, sa, sizeof(struct sockaddr_in));
 2002         } else {
 2003                 memcpy(&spc->spc_aaddr, sa, sizeof(struct sockaddr_in6));
 2004         }
 2005         spc->spc_state = state;
 2006         spc->spc_error = error;
 2007         spc->spc_assoc_id = sctp_get_associd(stcb);
 2008 
 2009         m_notify->m_flags |= M_EOR | M_NOTIFICATION;
 2010         m_notify->m_pkthdr.len = sizeof(struct sctp_paddr_change);
 2011         m_reset_rcvif(m_notify);
 2012         m_notify->m_len = sizeof(struct sctp_paddr_change);
 2013         m_notify->m_next = NULL;
 2014 
 2015         to = rtcache_getdst(&stcb->asoc.primary_destination->ro);
 2016         if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
 2017             to->sa_family == AF_INET) {
 2018                 const struct sockaddr_in *sin;
 2019 
 2020                 sin = (const struct sockaddr_in *)to;
 2021                 in6_sin_2_v4mapsin6(sin, &sin6);
 2022                 to = (struct sockaddr *)&sin6;
 2023         }
 2024         /* check and strip embedded scope junk */
 2025         to = (const struct sockaddr *)sctp_recover_scope((const struct sockaddr_in6 *)to,
 2026             &lsa6);
 2027 
 2028         if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) {
 2029                 sctp_m_freem(m_notify);
 2030                 return;
 2031         }
 2032         /* append to socket */
 2033         SCTP_TCB_UNLOCK(stcb);
 2034         SCTP_INP_WLOCK(stcb->sctp_ep);
 2035         SCTP_TCB_LOCK(stcb);
 2036         if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv, to,
 2037             m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) {
 2038                 /* not enough room */
 2039                 sctp_m_freem(m_notify);
 2040                 SCTP_INP_WUNLOCK(stcb->sctp_ep);
 2041                 return;
 2042         }
 2043         if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) &&
 2044            ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){
 2045                 if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) {
 2046                         stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
 2047                 }
 2048         } else {
 2049                 stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
 2050         }
 2051         SCTP_INP_WUNLOCK(stcb->sctp_ep);
 2052         sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
 2053 }
 2054 
 2055 
 2056 static void
 2057 sctp_notify_send_failed(struct sctp_tcb *stcb, u_int32_t error,
 2058                         struct sctp_tmit_chunk *chk)
 2059 {
 2060         struct mbuf *m_notify;
 2061         struct sctp_send_failed *ssf;
 2062         struct sockaddr_in6 sin6, lsa6;
 2063         const struct sockaddr *to;
 2064         int length;
 2065 
 2066         if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_RECVSENDFAILEVNT))
 2067                 /* event not enabled */
 2068                 return;
 2069 
 2070         length = sizeof(struct sctp_send_failed) + chk->send_size;
 2071         MGETHDR(m_notify, M_DONTWAIT, MT_DATA);
 2072         if (m_notify == NULL)
 2073                 /* no space left */
 2074                 return;
 2075         m_notify->m_len = 0;
 2076         ssf = mtod(m_notify, struct sctp_send_failed *);
 2077         ssf->ssf_type = SCTP_SEND_FAILED;
 2078         if (error == SCTP_NOTIFY_DATAGRAM_UNSENT)
 2079                 ssf->ssf_flags = SCTP_DATA_UNSENT;
 2080         else
 2081                 ssf->ssf_flags = SCTP_DATA_SENT;
 2082         ssf->ssf_length = length;
 2083         ssf->ssf_error = error;
 2084         /* not exactly what the user sent in, but should be close :) */
 2085         ssf->ssf_info.sinfo_stream = chk->rec.data.stream_number;
 2086         ssf->ssf_info.sinfo_ssn = chk->rec.data.stream_seq;
 2087         ssf->ssf_info.sinfo_flags = chk->rec.data.rcv_flags;
 2088         ssf->ssf_info.sinfo_ppid = chk->rec.data.payloadtype;
 2089         ssf->ssf_info.sinfo_context = chk->rec.data.context;
 2090         ssf->ssf_info.sinfo_assoc_id = sctp_get_associd(stcb);
 2091         ssf->ssf_assoc_id = sctp_get_associd(stcb);
 2092         m_notify->m_next = chk->data;
 2093         if (m_notify->m_next == NULL)
 2094                 m_notify->m_flags |= M_EOR | M_NOTIFICATION;
 2095         else {
 2096                 struct mbuf *m;
 2097                 m_notify->m_flags |= M_NOTIFICATION;
 2098                 m = m_notify;
 2099                 while (m->m_next != NULL)
 2100                         m = m->m_next;
 2101                 m->m_flags |= M_EOR;
 2102         }
 2103         m_notify->m_pkthdr.len = length;
 2104         m_reset_rcvif(m_notify);
 2105         m_notify->m_len = sizeof(struct sctp_send_failed);
 2106 
 2107         /* Steal off the mbuf */
 2108         chk->data = NULL;
 2109         to = rtcache_getdst(&stcb->asoc.primary_destination->ro);
 2110         if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
 2111             to->sa_family == AF_INET) {
 2112                 const struct sockaddr_in *sin;
 2113 
 2114                 sin = satocsin(to);
 2115                 in6_sin_2_v4mapsin6(sin, &sin6);
 2116                 to = (struct sockaddr *)&sin6;
 2117         }
 2118         /* check and strip embedded scope junk */
 2119         to = (const struct sockaddr *)sctp_recover_scope((const struct sockaddr_in6 *)to,
 2120                                                    &lsa6);
 2121 
 2122         if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) {
 2123                 sctp_m_freem(m_notify);
 2124                 return;
 2125         }
 2126 
 2127         /* append to socket */
 2128         SCTP_TCB_UNLOCK(stcb);
 2129         SCTP_INP_WLOCK(stcb->sctp_ep);
 2130         SCTP_TCB_LOCK(stcb);
 2131         if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv, to,
 2132             m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) {
 2133                 /* not enough room */
 2134                 sctp_m_freem(m_notify);
 2135                 SCTP_INP_WUNLOCK(stcb->sctp_ep);
 2136                 return;
 2137         }
 2138         if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) &&
 2139            ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){
 2140                 if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) {
 2141                         stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
 2142                 }
 2143         } else {
 2144                 stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
 2145         }
 2146         SCTP_INP_WUNLOCK(stcb->sctp_ep);
 2147         sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
 2148 }
 2149 
 2150 static void
 2151 sctp_notify_adaption_layer(struct sctp_tcb *stcb,
 2152                            u_int32_t error)
 2153 {
 2154         struct mbuf *m_notify;
 2155         struct sctp_adaption_event *sai;
 2156         struct sockaddr_in6 sin6, lsa6;
 2157         const struct sockaddr *to;
 2158 
 2159         if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_ADAPTIONEVNT))
 2160                 /* event not enabled */
 2161                 return;
 2162 
 2163         MGETHDR(m_notify, M_DONTWAIT, MT_DATA);
 2164         if (m_notify == NULL)
 2165                 /* no space left */
 2166                 return;
 2167         m_notify->m_len = 0;
 2168         sai = mtod(m_notify, struct sctp_adaption_event *);
 2169         sai->sai_type = SCTP_ADAPTION_INDICATION;
 2170         sai->sai_flags = 0;
 2171         sai->sai_length = sizeof(struct sctp_adaption_event);
 2172         sai->sai_adaption_ind = error;
 2173         sai->sai_assoc_id = sctp_get_associd(stcb);
 2174 
 2175         m_notify->m_flags |= M_EOR | M_NOTIFICATION;
 2176         m_notify->m_pkthdr.len = sizeof(struct sctp_adaption_event);
 2177         m_reset_rcvif(m_notify);
 2178         m_notify->m_len = sizeof(struct sctp_adaption_event);
 2179         m_notify->m_next = NULL;
 2180 
 2181         to = rtcache_getdst(&stcb->asoc.primary_destination->ro);
 2182         if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
 2183             (to->sa_family == AF_INET)) {
 2184                 const struct sockaddr_in *sin;
 2185 
 2186                 sin = satocsin(to);
 2187                 in6_sin_2_v4mapsin6(sin, &sin6);
 2188                 to = (struct sockaddr *)&sin6;
 2189         }
 2190         /* check and strip embedded scope junk */
 2191         to = (const struct sockaddr *)sctp_recover_scope((const struct sockaddr_in6 *)to,
 2192                                                    &lsa6);
 2193         if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) {
 2194                 sctp_m_freem(m_notify);
 2195                 return;
 2196         }
 2197         /* append to socket */
 2198         SCTP_TCB_UNLOCK(stcb);
 2199         SCTP_INP_WLOCK(stcb->sctp_ep);
 2200         SCTP_TCB_LOCK(stcb);
 2201         if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv, to,
 2202             m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) {
 2203                 /* not enough room */
 2204                 sctp_m_freem(m_notify);
 2205                 SCTP_INP_WUNLOCK(stcb->sctp_ep);
 2206                 return;
 2207         }
 2208         if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) &&
 2209            ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){
 2210                 if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) {
 2211                         stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
 2212                 }
 2213         } else {
 2214                 stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
 2215         }
 2216         SCTP_INP_WUNLOCK(stcb->sctp_ep);
 2217         sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
 2218 }
 2219 
 2220 static void
 2221 sctp_notify_partial_delivery_indication(struct sctp_tcb *stcb,
 2222                                         u_int32_t error)
 2223 {
 2224         struct mbuf *m_notify;
 2225         struct sctp_pdapi_event *pdapi;
 2226         struct sockaddr_in6 sin6, lsa6;
 2227         const struct sockaddr *to;
 2228 
 2229         if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_PDAPIEVNT))
 2230                 /* event not enabled */
 2231                 return;
 2232 
 2233         MGETHDR(m_notify, M_DONTWAIT, MT_DATA);
 2234         if (m_notify == NULL)
 2235                 /* no space left */
 2236                 return;
 2237         m_notify->m_len = 0;
 2238         pdapi = mtod(m_notify, struct sctp_pdapi_event *);
 2239         pdapi->pdapi_type = SCTP_PARTIAL_DELIVERY_EVENT;
 2240         pdapi->pdapi_flags = 0;
 2241         pdapi->pdapi_length = sizeof(struct sctp_pdapi_event);
 2242         pdapi->pdapi_indication = error;
 2243         pdapi->pdapi_assoc_id = sctp_get_associd(stcb);
 2244 
 2245         m_notify->m_flags |= M_EOR | M_NOTIFICATION;
 2246         m_notify->m_pkthdr.len = sizeof(struct sctp_pdapi_event);
 2247         m_reset_rcvif(m_notify);
 2248         m_notify->m_len = sizeof(struct sctp_pdapi_event);
 2249         m_notify->m_next = NULL;
 2250 
 2251         to = rtcache_getdst(&stcb->asoc.primary_destination->ro);
 2252         if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
 2253             (to->sa_family == AF_INET)) {
 2254                 const struct sockaddr_in *sin;
 2255 
 2256                 sin = satocsin(to);
 2257                 in6_sin_2_v4mapsin6(sin, &sin6);
 2258                 to = (struct sockaddr *)&sin6;
 2259         }
 2260         /* check and strip embedded scope junk */
 2261         to = (const struct sockaddr *)sctp_recover_scope((const struct sockaddr_in6 *)to,
 2262                                                    &lsa6);
 2263         if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) {
 2264                 sctp_m_freem(m_notify);
 2265                 return;
 2266         }
 2267         /* append to socket */
 2268         SCTP_TCB_UNLOCK(stcb);
 2269         SCTP_INP_WLOCK(stcb->sctp_ep);
 2270         SCTP_TCB_LOCK(stcb);
 2271         if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv, to,
 2272             m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) {
 2273                 /* not enough room */
 2274                 sctp_m_freem(m_notify);
 2275                 SCTP_INP_WUNLOCK(stcb->sctp_ep);
 2276                 return;
 2277         }
 2278         if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) &&
 2279            ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){
 2280                 if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) {
 2281                         stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
 2282                 }
 2283         } else {
 2284                 stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
 2285         }
 2286         SCTP_INP_WUNLOCK(stcb->sctp_ep);
 2287         sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
 2288 }
 2289 
 2290 static void
 2291 sctp_notify_shutdown_event(struct sctp_tcb *stcb)
 2292 {
 2293         struct mbuf *m_notify;
 2294         struct sctp_shutdown_event *sse;
 2295         struct sockaddr_in6 sin6, lsa6;
 2296         const struct sockaddr *to;
 2297 
 2298         /*
 2299          * For TCP model AND UDP connected sockets we will send
 2300          * an error up when an SHUTDOWN completes
 2301          */
 2302         if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
 2303             (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
 2304                 /* mark socket closed for read/write and wakeup! */
 2305                 socantrcvmore(stcb->sctp_socket);
 2306                 socantsendmore(stcb->sctp_socket);
 2307         }
 2308 
 2309         if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT))
 2310                 /* event not enabled */
 2311                 return;
 2312 
 2313         MGETHDR(m_notify, M_DONTWAIT, MT_DATA);
 2314         if (m_notify == NULL)
 2315                 /* no space left */
 2316                 return;
 2317         m_notify->m_len = 0;
 2318         sse = mtod(m_notify, struct sctp_shutdown_event *);
 2319         sse->sse_type = SCTP_SHUTDOWN_EVENT;
 2320         sse->sse_flags = 0;
 2321         sse->sse_length = sizeof(struct sctp_shutdown_event);
 2322         sse->sse_assoc_id = sctp_get_associd(stcb);
 2323 
 2324         m_notify->m_flags |= M_EOR | M_NOTIFICATION;
 2325         m_notify->m_pkthdr.len = sizeof(struct sctp_shutdown_event);
 2326         m_reset_rcvif(m_notify);
 2327         m_notify->m_len = sizeof(struct sctp_shutdown_event);
 2328         m_notify->m_next = NULL;
 2329 
 2330         to = rtcache_getdst(&stcb->asoc.primary_destination->ro);
 2331         if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
 2332             to->sa_family == AF_INET) {
 2333                 const struct sockaddr_in *sin;
 2334 
 2335                 sin = satocsin(to);
 2336                 in6_sin_2_v4mapsin6(sin, &sin6);
 2337                 to = (struct sockaddr *)&sin6;
 2338         }
 2339         /* check and strip embedded scope junk */
 2340         to = (const struct sockaddr *)sctp_recover_scope((const struct sockaddr_in6 *)to,
 2341             &lsa6);
 2342         if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) {
 2343                 sctp_m_freem(m_notify);
 2344                 return;
 2345         }
 2346         /* append to socket */
 2347         SCTP_TCB_UNLOCK(stcb);
 2348         SCTP_INP_WLOCK(stcb->sctp_ep);
 2349         SCTP_TCB_LOCK(stcb);
 2350         if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv, to,
 2351             m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) {
 2352                 /* not enough room */
 2353                 sctp_m_freem(m_notify);
 2354                 SCTP_INP_WUNLOCK(stcb->sctp_ep);
 2355                 return;
 2356         }
 2357         if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) &&
 2358            ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){
 2359                 if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) {
 2360                         stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
 2361                 }
 2362         } else {
 2363                 stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
 2364         }
 2365         SCTP_INP_WUNLOCK(stcb->sctp_ep);
 2366         sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
 2367 }
 2368 
 2369 static void
 2370 sctp_notify_stream_reset(struct sctp_tcb *stcb,
 2371     int number_entries, uint16_t *list, int flag)
 2372 {
 2373         struct mbuf *m_notify;
 2374         struct sctp_stream_reset_event *strreset;
 2375         struct sockaddr_in6 sin6, lsa6;
 2376         const struct sockaddr *to;
 2377         int len;
 2378 
 2379         if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_STREAM_RESETEVNT))
 2380                 /* event not enabled */
 2381                 return;
 2382 
 2383         MGETHDR(m_notify, M_DONTWAIT, MT_DATA);
 2384         if (m_notify == NULL)
 2385                 /* no space left */
 2386                 return;
 2387         m_notify->m_len = 0;
 2388         len = sizeof(struct sctp_stream_reset_event) + (number_entries * sizeof(uint16_t));
 2389         if (len > M_TRAILINGSPACE(m_notify)) {
 2390                 MCLGET(m_notify, M_WAIT);
 2391         }
 2392         if (m_notify == NULL)
 2393                 /* no clusters */
 2394                 return;
 2395 
 2396         if (len > M_TRAILINGSPACE(m_notify)) {
 2397                 /* never enough room */
 2398                 m_freem(m_notify);
 2399                 return;
 2400         }
 2401         strreset = mtod(m_notify, struct sctp_stream_reset_event *);
 2402         strreset->strreset_type = SCTP_STREAM_RESET_EVENT;
 2403         if (number_entries == 0) {
 2404                 strreset->strreset_flags = flag | SCTP_STRRESET_ALL_STREAMS;
 2405         } else {
 2406                 strreset->strreset_flags = flag | SCTP_STRRESET_STREAM_LIST;
 2407         }
 2408         strreset->strreset_length = len;
 2409         strreset->strreset_assoc_id = sctp_get_associd(stcb);
 2410         if (number_entries) {
 2411                 int i;
 2412                 for (i=0; i<number_entries; i++) {
 2413                         strreset->strreset_list[i] = list[i];
 2414                 }
 2415         }
 2416         m_notify->m_flags |= M_EOR | M_NOTIFICATION;
 2417         m_notify->m_pkthdr.len = len;
 2418         m_reset_rcvif(m_notify);
 2419         m_notify->m_len = len;
 2420         m_notify->m_next = NULL;
 2421         if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) {
 2422                 /* no space */
 2423                 sctp_m_freem(m_notify);
 2424                 return;
 2425         }
 2426         to = rtcache_getdst(&stcb->asoc.primary_destination->ro);
 2427         if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
 2428             to->sa_family == AF_INET) {
 2429                 const struct sockaddr_in *sin;
 2430 
 2431                 sin = satocsin(to);
 2432                 in6_sin_2_v4mapsin6(sin, &sin6);
 2433                 to = (struct sockaddr *)&sin6;
 2434         }
 2435         /* check and strip embedded scope junk */
 2436         to = (const struct sockaddr *) sctp_recover_scope((const struct sockaddr_in6 *)to,
 2437             &lsa6);
 2438         /* append to socket */
 2439         SCTP_TCB_UNLOCK(stcb);
 2440         SCTP_INP_WLOCK(stcb->sctp_ep);
 2441         SCTP_TCB_LOCK(stcb);
 2442         if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv, to,
 2443             m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) {
 2444                 /* not enough room */
 2445                 sctp_m_freem(m_notify);
 2446                 SCTP_INP_WUNLOCK(stcb->sctp_ep);
 2447                 return;
 2448         }
 2449         if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) &&
 2450            ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){
 2451                 if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) {
 2452                         stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
 2453                 }
 2454         } else {
 2455                 stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
 2456         }
 2457         SCTP_INP_WUNLOCK(stcb->sctp_ep);
 2458         sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
 2459 }
 2460 
 2461 
 2462 void
 2463 sctp_ulp_notify(u_int32_t notification, struct sctp_tcb *stcb,
 2464                 u_int32_t error, void *data)
 2465 {
 2466         if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
 2467                 /* No notifications up when we are in a no socket state */
 2468                 return;
 2469         }
 2470         if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
 2471                 /* Can't send up to a closed socket any notifications */
 2472                 return;
 2473         }
 2474         switch (notification) {
 2475         case SCTP_NOTIFY_ASSOC_UP:
 2476                 sctp_notify_assoc_change(SCTP_COMM_UP, stcb, error);
 2477                 break;
 2478         case SCTP_NOTIFY_ASSOC_DOWN:
 2479                 sctp_notify_assoc_change(SCTP_SHUTDOWN_COMP, stcb, error);
 2480                 break;
 2481         case SCTP_NOTIFY_INTERFACE_DOWN:
 2482         {
 2483                 struct sctp_nets *net;
 2484                 net = (struct sctp_nets *)data;
 2485                 sctp_notify_peer_addr_change(stcb, SCTP_ADDR_UNREACHABLE,
 2486                     rtcache_getdst(&net->ro), error);
 2487                 break;
 2488         }
 2489         case SCTP_NOTIFY_INTERFACE_UP:
 2490         {
 2491                 struct sctp_nets *net;
 2492                 net = (struct sctp_nets *)data;
 2493                 sctp_notify_peer_addr_change(stcb, SCTP_ADDR_AVAILABLE,
 2494                     rtcache_getdst(&net->ro), error);
 2495                 break;
 2496         }
 2497         case SCTP_NOTIFY_INTERFACE_CONFIRMED:
 2498         {
 2499                 struct sctp_nets *net;
 2500                 net = (struct sctp_nets *)data;
 2501                 sctp_notify_peer_addr_change(stcb, SCTP_ADDR_CONFIRMED,
 2502                     rtcache_getdst(&net->ro), error);
 2503                 break;
 2504         }
 2505         case SCTP_NOTIFY_DG_FAIL:
 2506                 sctp_notify_send_failed(stcb, error,
 2507                     (struct sctp_tmit_chunk *)data);
 2508                 break;
 2509         case SCTP_NOTIFY_ADAPTION_INDICATION:
 2510                 /* Here the error is the adaption indication */
 2511                 sctp_notify_adaption_layer(stcb, error);
 2512                 break;
 2513         case SCTP_NOTIFY_PARTIAL_DELVIERY_INDICATION:
 2514                 sctp_notify_partial_delivery_indication(stcb, error);
 2515                 break;
 2516         case SCTP_NOTIFY_STRDATA_ERR:
 2517                 break;
 2518         case SCTP_NOTIFY_ASSOC_ABORTED:
 2519                 sctp_notify_assoc_change(SCTP_COMM_LOST, stcb, error);
 2520                 break;
 2521         case SCTP_NOTIFY_PEER_OPENED_STREAM:
 2522                 break;
 2523         case SCTP_NOTIFY_STREAM_OPENED_OK:
 2524                 break;
 2525         case SCTP_NOTIFY_ASSOC_RESTART:
 2526                 sctp_notify_assoc_change(SCTP_RESTART, stcb, error);
 2527                 break;
 2528         case SCTP_NOTIFY_HB_RESP:
 2529                 break;
 2530         case SCTP_NOTIFY_STR_RESET_SEND:
 2531                 sctp_notify_stream_reset(stcb, error, ((uint16_t *)data), SCTP_STRRESET_OUTBOUND_STR);
 2532                 break;
 2533         case SCTP_NOTIFY_STR_RESET_RECV:
 2534                 sctp_notify_stream_reset(stcb, error, ((uint16_t *)data), SCTP_STRRESET_INBOUND_STR);
 2535                 break;
 2536         case SCTP_NOTIFY_ASCONF_ADD_IP:
 2537                 sctp_notify_peer_addr_change(stcb, SCTP_ADDR_ADDED, data,
 2538                     error);
 2539                 break;
 2540         case SCTP_NOTIFY_ASCONF_DELETE_IP:
 2541                 sctp_notify_peer_addr_change(stcb, SCTP_ADDR_REMOVED, data,
 2542                     error);
 2543                 break;
 2544         case SCTP_NOTIFY_ASCONF_SET_PRIMARY:
 2545                 sctp_notify_peer_addr_change(stcb, SCTP_ADDR_MADE_PRIM, data,
 2546                     error);
 2547                 break;
 2548         case SCTP_NOTIFY_ASCONF_SUCCESS:
 2549                 break;
 2550         case SCTP_NOTIFY_ASCONF_FAILED:
 2551                 break;
 2552         case SCTP_NOTIFY_PEER_SHUTDOWN:
 2553                 sctp_notify_shutdown_event(stcb);
 2554                 break;
 2555         default:
 2556 #ifdef SCTP_DEBUG
 2557                 if (sctp_debug_on & SCTP_DEBUG_UTIL1) {
 2558                         printf("NOTIFY: unknown notification %xh (%u)\n",
 2559                             notification, notification);
 2560                 }
 2561 #endif /* SCTP_DEBUG */
 2562                 break;
 2563         } /* end switch */
 2564 }
 2565 
 2566 void
 2567 sctp_report_all_outbound(struct sctp_tcb *stcb)
 2568 {
 2569         struct sctp_association *asoc;
 2570         struct sctp_stream_out *outs;
 2571         struct sctp_tmit_chunk *chk;
 2572 
 2573         asoc = &stcb->asoc;
 2574 
 2575         if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
 2576                 return;
 2577         }
 2578         /* now through all the gunk freeing chunks */
 2579         TAILQ_FOREACH(outs, &asoc->out_wheel, next_spoke) {
 2580                 /* now clean up any chunks here */
 2581                 chk = TAILQ_FIRST(&outs->outqueue);
 2582                 while (chk) {
 2583                         stcb->asoc.stream_queue_cnt--;
 2584                         TAILQ_REMOVE(&outs->outqueue, chk, sctp_next);
 2585                         sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb,
 2586                             SCTP_NOTIFY_DATAGRAM_UNSENT, chk);
 2587                         if (chk->data) {
 2588                                 sctp_m_freem(chk->data);
 2589                                 chk->data = NULL;
 2590                         }
 2591                         if (chk->whoTo)
 2592                                 sctp_free_remote_addr(chk->whoTo);
 2593                         chk->whoTo = NULL;
 2594                         chk->asoc = NULL;
 2595                         /* Free the chunk */
 2596                         SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_chunk, chk);
 2597                         sctppcbinfo.ipi_count_chunk--;
 2598                         if ((int)sctppcbinfo.ipi_count_chunk < 0) {
 2599                                 panic("Chunk count is negative");
 2600                         }
 2601                         sctppcbinfo.ipi_gencnt_chunk++;
 2602                         chk = TAILQ_FIRST(&outs->outqueue);
 2603                 }
 2604         }
 2605         /* pending send queue SHOULD be empty */
 2606         if (!TAILQ_EMPTY(&asoc->send_queue)) {
 2607                 chk = TAILQ_FIRST(&asoc->send_queue);
 2608                 while (chk) {
 2609                         TAILQ_REMOVE(&asoc->send_queue, chk, sctp_next);
 2610                         sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb, SCTP_NOTIFY_DATAGRAM_UNSENT, chk);
 2611                         if (chk->data) {
 2612                                 sctp_m_freem(chk->data);
 2613                                 chk->data = NULL;
 2614                         }
 2615                         if (chk->whoTo)
 2616                                 sctp_free_remote_addr(chk->whoTo);
 2617                         chk->whoTo = NULL;
 2618                         SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_chunk, chk);
 2619                         sctppcbinfo.ipi_count_chunk--;
 2620                         if ((int)sctppcbinfo.ipi_count_chunk < 0) {
 2621                                 panic("Chunk count is negative");
 2622                         }
 2623                         sctppcbinfo.ipi_gencnt_chunk++;
 2624                         chk = TAILQ_FIRST(&asoc->send_queue);
 2625                 }
 2626         }
 2627         /* sent queue SHOULD be empty */
 2628         if (!TAILQ_EMPTY(&asoc->sent_queue)) {
 2629                 chk = TAILQ_FIRST(&asoc->sent_queue);
 2630                 while (chk) {
 2631                         TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next);
 2632                         sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb,
 2633                             SCTP_NOTIFY_DATAGRAM_SENT, chk);
 2634                         if (chk->data) {
 2635                                 sctp_m_freem(chk->data);
 2636                                 chk->data = NULL;
 2637                         }
 2638                         if (chk->whoTo)
 2639                                 sctp_free_remote_addr(chk->whoTo);
 2640                         chk->whoTo = NULL;
 2641                         SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_chunk, chk);
 2642                         sctppcbinfo.ipi_count_chunk--;
 2643                         if ((int)sctppcbinfo.ipi_count_chunk < 0) {
 2644                                 panic("Chunk count is negative");
 2645                         }
 2646                         sctppcbinfo.ipi_gencnt_chunk++;
 2647                         chk = TAILQ_FIRST(&asoc->sent_queue);
 2648                 }
 2649         }
 2650 }
 2651 
 2652 void
 2653 sctp_abort_notification(struct sctp_tcb *stcb, int error)
 2654 {
 2655 
 2656         if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
 2657                 return;
 2658         }
 2659         /* Tell them we lost the asoc */
 2660         sctp_report_all_outbound(stcb);
 2661         sctp_ulp_notify(SCTP_NOTIFY_ASSOC_ABORTED, stcb, error, NULL);
 2662 }
 2663 
 2664 void
 2665 sctp_abort_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
 2666     struct mbuf *m, int iphlen, struct sctphdr *sh, struct mbuf *op_err)
 2667 {
 2668         u_int32_t vtag;
 2669 
 2670         vtag = 0;
 2671         if (stcb != NULL) {
 2672                 /* We have a TCB to abort, send notification too */
 2673                 vtag = stcb->asoc.peer_vtag;
 2674                 sctp_abort_notification(stcb, 0);
 2675         }
 2676         sctp_send_abort(m, iphlen, sh, vtag, op_err);
 2677         if (stcb != NULL) {
 2678                 /* Ok, now lets free it */
 2679                 sctp_free_assoc(inp, stcb);
 2680         } else {
 2681                 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
 2682                         if (LIST_FIRST(&inp->sctp_asoc_list) == NULL) {
 2683                                 sctp_inpcb_free(inp, 1);
 2684                         }
 2685                 }
 2686         }
 2687 }
 2688 
 2689 void
 2690 sctp_abort_an_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
 2691     int error, struct mbuf *op_err)
 2692 {
 2693 
 2694         if (stcb == NULL) {
 2695                 /* Got to have a TCB */
 2696                 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
 2697                         if (LIST_FIRST(&inp->sctp_asoc_list) == NULL) {
 2698                                 sctp_inpcb_free(inp, 1);
 2699                         }
 2700                 }
 2701                 return;
 2702         }
 2703         /* notify the ulp */
 2704         if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0)
 2705                 sctp_abort_notification(stcb, error);
 2706         /* notify the peer */
 2707         sctp_send_abort_tcb(stcb, op_err);
 2708         /* now free the asoc */
 2709         sctp_free_assoc(inp, stcb);
 2710 }
 2711 
 2712 void
 2713 sctp_handle_ootb(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
 2714     struct sctp_inpcb *inp, struct mbuf *op_err)
 2715 {
 2716         struct sctp_chunkhdr *ch, chunk_buf;
 2717         unsigned int chk_length;
 2718 
 2719         /* Generate a TO address for future reference */
 2720         if (inp && (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) {
 2721                 if (LIST_FIRST(&inp->sctp_asoc_list) == NULL) {
 2722                         sctp_inpcb_free(inp, 1);
 2723                 }
 2724         }
 2725         ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset,
 2726             sizeof(*ch), (u_int8_t *)&chunk_buf);
 2727         while (ch != NULL) {
 2728                 chk_length = ntohs(ch->chunk_length);
 2729                 if (chk_length < sizeof(*ch)) {
 2730                         /* break to abort land */
 2731                         break;
 2732                 }
 2733                 switch (ch->chunk_type) {
 2734                 case SCTP_PACKET_DROPPED:
 2735                         /* we don't respond to pkt-dropped */
 2736                         return;
 2737                 case SCTP_ABORT_ASSOCIATION:
 2738                         /* we don't respond with an ABORT to an ABORT */
 2739                         return;
 2740                 case SCTP_SHUTDOWN_COMPLETE:
 2741                         /*
 2742                          * we ignore it since we are not waiting for it
 2743                          * and peer is gone
 2744                          */
 2745                         return;
 2746                 case SCTP_SHUTDOWN_ACK:
 2747                         sctp_send_shutdown_complete2(m, iphlen, sh);
 2748                         return;
 2749                 default:
 2750                         break;
 2751                 }
 2752                 offset += SCTP_SIZE32(chk_length);
 2753                 ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset,
 2754                     sizeof(*ch), (u_int8_t *)&chunk_buf);
 2755         }
 2756         sctp_send_abort(m, iphlen, sh, 0, op_err);
 2757 }
 2758 
 2759 /*
 2760  * check the inbound datagram to make sure there is not an abort
 2761  * inside it, if there is return 1, else return 0.
 2762  */
 2763 int
 2764 sctp_is_there_an_abort_here(struct mbuf *m, int iphlen, int *vtagfill)
 2765 {
 2766         struct sctp_chunkhdr *ch;
 2767         struct sctp_init_chunk *init_chk, chunk_buf;
 2768         int offset;
 2769         unsigned int chk_length;
 2770 
 2771         offset = iphlen + sizeof(struct sctphdr);
 2772         ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset, sizeof(*ch),
 2773             (u_int8_t *)&chunk_buf);
 2774         while (ch != NULL) {
 2775                 chk_length = ntohs(ch->chunk_length);
 2776                 if (chk_length < sizeof(*ch)) {
 2777                         /* packet is probably corrupt */
 2778                         break;
 2779                 }
 2780                 /* we seem to be ok, is it an abort? */
 2781                 if (ch->chunk_type == SCTP_ABORT_ASSOCIATION) {
 2782                         /* yep, tell them */
 2783                         return (1);
 2784                 }
 2785                 if (ch->chunk_type == SCTP_INITIATION) {
 2786                         /* need to update the Vtag */
 2787                         init_chk = (struct sctp_init_chunk *)sctp_m_getptr(m,
 2788                             offset, sizeof(*init_chk), (u_int8_t *)&chunk_buf);
 2789                         if (init_chk != NULL) {
 2790                                 *vtagfill = ntohl(init_chk->init.initiate_tag);
 2791                         }
 2792                 }
 2793                 /* Nope, move to the next chunk */
 2794                 offset += SCTP_SIZE32(chk_length);
 2795                 ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset,
 2796                     sizeof(*ch), (u_int8_t *)&chunk_buf);
 2797         }
 2798         return (0);
 2799 }
 2800 
 2801 /*
 2802  * currently (2/02), ifa_addr embeds scope_id's and don't
 2803  * have sin6_scope_id set (i.e. it's 0)
 2804  * so, create this function to compare link local scopes
 2805  */
 2806 uint32_t
 2807 sctp_is_same_scope(const struct sockaddr_in6 *addr1, const struct sockaddr_in6 *addr2)
 2808 {
 2809         struct sockaddr_in6 a, b;
 2810 
 2811         /* save copies */
 2812         a = *addr1;
 2813         b = *addr2;
 2814 
 2815         if (a.sin6_scope_id == 0)
 2816                 if (sa6_recoverscope(&a)) {
 2817                         /* can't get scope, so can't match */
 2818                         return (0);
 2819                 }
 2820         if (b.sin6_scope_id == 0)
 2821                 if (sa6_recoverscope(&b)) {
 2822                         /* can't get scope, so can't match */
 2823                         return (0);
 2824                 }
 2825         if (a.sin6_scope_id != b.sin6_scope_id)
 2826                 return (0);
 2827 
 2828         return (1);
 2829 }
 2830 
 2831 /*
 2832  * returns a sockaddr_in6 with embedded scope recovered and removed
 2833  */
 2834 const struct sockaddr_in6 *
 2835 sctp_recover_scope(const struct sockaddr_in6 *addr, struct sockaddr_in6 *store)
 2836 {
 2837         const struct sockaddr_in6 *newaddr;
 2838 
 2839         newaddr = addr;
 2840         /* check and strip embedded scope junk */
 2841         if (addr->sin6_family == AF_INET6) {
 2842                 if (IN6_IS_SCOPE_LINKLOCAL(&addr->sin6_addr)) {
 2843                         if (addr->sin6_scope_id == 0) {
 2844                                 *store = *addr;
 2845                                 if (sa6_recoverscope(store) == 0) { 
 2846                                         /* use the recovered scope */
 2847                                         newaddr = store;
 2848                                 }
 2849                                 /* else, return the original "to" addr */
 2850                         }
 2851                 }
 2852         }
 2853         return (newaddr);
 2854 }
 2855 
 2856 /*
 2857  * are the two addresses the same?  currently a "scopeless" check
 2858  * returns: 1 if same, 0 if not
 2859  */
 2860 int
 2861 sctp_cmpaddr(const struct sockaddr *sa1, const struct sockaddr *sa2)
 2862 {
 2863 
 2864         /* must be valid */
 2865         if (sa1 == NULL || sa2 == NULL)
 2866                 return (0);
 2867 
 2868         /* must be the same family */
 2869         if (sa1->sa_family != sa2->sa_family)
 2870                 return (0);
 2871 
 2872         if (sa1->sa_family == AF_INET6) {
 2873                 /* IPv6 addresses */
 2874                 const struct sockaddr_in6 *sin6_1, *sin6_2;
 2875 
 2876                 sin6_1 = (const struct sockaddr_in6 *)sa1;
 2877                 sin6_2 = (const struct sockaddr_in6 *)sa2;
 2878                 return (SCTP6_ARE_ADDR_EQUAL(&sin6_1->sin6_addr,
 2879                     &sin6_2->sin6_addr));
 2880         } else if (sa1->sa_family == AF_INET) {
 2881                 /* IPv4 addresses */
 2882                 const struct sockaddr_in *sin_1, *sin_2;
 2883 
 2884                 sin_1 = (const struct sockaddr_in *)sa1;
 2885                 sin_2 = (const struct sockaddr_in *)sa2;
 2886                 return (sin_1->sin_addr.s_addr == sin_2->sin_addr.s_addr);
 2887         } else {
 2888                 /* we don't do these... */
 2889                 return (0);
 2890         }
 2891 }
 2892 
 2893 void
 2894 sctp_print_address(const struct sockaddr *sa)
 2895 {
 2896         char ip6buf[INET6_ADDRSTRLEN];
 2897 
 2898         if (sa->sa_family == AF_INET6) {
 2899                 const struct sockaddr_in6 *sin6;
 2900                 sin6 = (const struct sockaddr_in6 *)sa;
 2901                 printf("IPv6 address: %s:%d scope:%u\n",
 2902                     IN6_PRINT(ip6buf, &sin6->sin6_addr), ntohs(sin6->sin6_port),
 2903                     sin6->sin6_scope_id);
 2904         } else if (sa->sa_family == AF_INET) {
 2905                 const struct sockaddr_in *sin;
 2906                 sin = (const struct sockaddr_in *)sa;
 2907                 printf("IPv4 address: %s:%d\n", inet_ntoa(sin->sin_addr),
 2908                     ntohs(sin->sin_port));
 2909         } else {
 2910                 printf("?\n");
 2911         }
 2912 }
 2913 
 2914 void
 2915 sctp_print_address_pkt(struct ip *iph, struct sctphdr *sh)
 2916 {
 2917         if (iph->ip_v == IPVERSION) {
 2918                 struct sockaddr_in lsa, fsa;
 2919 
 2920                 memset(&lsa, 0, sizeof(lsa));
 2921                 lsa.sin_len = sizeof(lsa);
 2922                 lsa.sin_family = AF_INET;
 2923                 lsa.sin_addr = iph->ip_src;
 2924                 lsa.sin_port = sh->src_port;
 2925                 memset(&fsa, 0, sizeof(fsa));
 2926                 fsa.sin_len = sizeof(fsa);
 2927                 fsa.sin_family = AF_INET;
 2928                 fsa.sin_addr = iph->ip_dst;
 2929                 fsa.sin_port = sh->dest_port;
 2930                 printf("src: ");
 2931                 sctp_print_address((struct sockaddr *)&lsa);
 2932                 printf("dest: ");
 2933                 sctp_print_address((struct sockaddr *)&fsa);
 2934         } else if (iph->ip_v == (IPV6_VERSION >> 4)) {
 2935                 struct ip6_hdr *ip6;
 2936                 struct sockaddr_in6 lsa6, fsa6;
 2937 
 2938                 ip6 = (struct ip6_hdr *)iph;
 2939                 memset(&lsa6, 0, sizeof(lsa6));
 2940                 lsa6.sin6_len = sizeof(lsa6);
 2941                 lsa6.sin6_family = AF_INET6;
 2942                 lsa6.sin6_addr = ip6->ip6_src;
 2943                 lsa6.sin6_port = sh->src_port;
 2944                 memset(&fsa6, 0, sizeof(fsa6));
 2945                 fsa6.sin6_len = sizeof(fsa6);
 2946                 fsa6.sin6_family = AF_INET6;
 2947                 fsa6.sin6_addr = ip6->ip6_dst;
 2948                 fsa6.sin6_port = sh->dest_port;
 2949                 printf("src: ");
 2950                 sctp_print_address((struct sockaddr *)&lsa6);
 2951                 printf("dest: ");
 2952                 sctp_print_address((struct sockaddr *)&fsa6);
 2953         }
 2954 }
 2955 
 2956 #if defined(__FreeBSD__) || defined(__APPLE__)
 2957 
 2958 /* cloned from uipc_socket.c */
 2959 
 2960 #define SCTP_SBLINKRECORD(sb, m0) do {                                  \
 2961         if ((sb)->sb_lastrecord != NULL)                                \
 2962                 (sb)->sb_lastrecord->m_nextpkt = (m0);                  \
 2963         else                                                            \
 2964                 (sb)->sb_mb = (m0);                                     \
 2965         (sb)->sb_lastrecord = (m0);                                     \
 2966 } while (/*CONSTCOND*/0)
 2967 #endif
 2968 
 2969 
 2970 int
 2971 sbappendaddr_nocheck(struct sockbuf *sb, const struct sockaddr *asa,
 2972         struct mbuf *m0, struct mbuf *control,
 2973         u_int32_t tag, struct sctp_inpcb *inp)
 2974 {
 2975 #ifdef __NetBSD__
 2976         struct mbuf *m, *n;
 2977 
 2978         if (m0 && (m0->m_flags & M_PKTHDR) == 0)
 2979                 panic("sbappendaddr_nocheck");
 2980 
 2981         m0->m_pkthdr.csum_data = (int)tag;
 2982 
 2983         for (n = control; n; n = n->m_next) {
 2984                 if (n->m_next == 0)     /* keep pointer to last control buf */
 2985                         break;
 2986         }
 2987         if (((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) == 0) ||
 2988             ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)== 0)) {
 2989                 MGETHDR(m, M_DONTWAIT, MT_SONAME);
 2990                 if (m == 0)
 2991                         return (0);
 2992 
 2993                 m->m_len = asa->sa_len;
 2994                 memcpy(mtod(m, void *), (const void *)asa, asa->sa_len);
 2995         } else {
 2996                 m = NULL;
 2997         }
 2998         if (n) {
 2999                 n->m_next = m0;         /* concatenate data to control */
 3000         }else {
 3001                 control = m0;
 3002         }
 3003         if (m)
 3004                 m->m_next = control;
 3005         else
 3006                 m = control;
 3007         m->m_pkthdr.csum_data = tag;
 3008 
 3009         for (n = m; n; n = n->m_next)
 3010                 sballoc(sb, n);
 3011         if ((n = sb->sb_mb) != NULL) {
 3012                 if ((n->m_nextpkt != inp->sb_last_mpkt) && (n->m_nextpkt == NULL)) {
 3013                         inp->sb_last_mpkt = NULL;
 3014                 }
 3015                 if (inp->sb_last_mpkt)
 3016                         inp->sb_last_mpkt->m_nextpkt = m;
 3017                 else {
 3018                         while (n->m_nextpkt) {
 3019                                 n = n->m_nextpkt;
 3020                         }
 3021                         n->m_nextpkt = m;
 3022                 }
 3023                 inp->sb_last_mpkt = m;
 3024         } else {
 3025                 inp->sb_last_mpkt = sb->sb_mb = m;
 3026                 inp->sctp_vtag_first = tag;
 3027         }
 3028         return (1);
 3029 #endif
 3030 #if defined(__FreeBSD__) || defined(__APPLE__)
 3031         struct mbuf *m, *n, *nlast;
 3032         int cnt=0;
 3033 
 3034         if (m0 && (m0->m_flags & M_PKTHDR) == 0)
 3035                 panic("sbappendaddr_nocheck");
 3036 
 3037         for (n = control; n; n = n->m_next) {
 3038                 if (n->m_next == 0)     /* get pointer to last control buf */
 3039                         break;
 3040         }
 3041         if (((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) == 0) ||
 3042             ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)== 0)) {
 3043                 if (asa->sa_len > MHLEN)
 3044                         return (0);
 3045  try_again:
 3046                 MGETHDR(m, M_DONTWAIT, MT_SONAME);
 3047                 if (m == 0)
 3048                         return (0);
 3049                 m->m_len = 0;
 3050                 /* safety */
 3051                 if (m == m0) {
 3052                         printf("Duplicate mbuf allocated %p in and mget returned %p?\n",
 3053                                m0, m);
 3054                         if (cnt) {
 3055                                 panic("more than once");
 3056                         }
 3057                         cnt++;
 3058                         goto try_again;
 3059                 }
 3060                 m->m_len = asa->sa_len;
 3061                 bcopy((void *)asa, mtod(m, void *), asa->sa_len);
 3062         }
 3063         else {
 3064                 m = NULL;
 3065         }
 3066         if (n)
 3067                 n->m_next = m0;         /* concatenate data to control */
 3068         else
 3069                 control = m0;
 3070         if (m)
 3071                 m->m_next = control;
 3072         else
 3073                 m = control;
 3074         m->m_pkthdr.csum_data = (int)tag;
 3075 
 3076         for (n = m; n; n = n->m_next)
 3077                 sballoc(sb, n);
 3078         nlast = n;
 3079         if (sb->sb_mb == NULL) {
 3080                 inp->sctp_vtag_first = tag;
 3081         }
 3082 
 3083 #ifdef __FREEBSD__
 3084         if (sb->sb_mb == NULL)
 3085                 inp->sctp_vtag_first = tag;
 3086         SCTP_SBLINKRECORD(sb, m);
 3087         sb->sb_mbtail = nlast;
 3088 #else
 3089         if ((n = sb->sb_mb) != NULL) {
 3090                 if ((n->m_nextpkt != inp->sb_last_mpkt) && (n->m_nextpkt == NULL)) {
 3091                         inp->sb_last_mpkt = NULL;
 3092                 }
 3093                 if (inp->sb_last_mpkt)
 3094                         inp->sb_last_mpkt->m_nextpkt = m;
 3095                 else {
 3096                         while (n->m_nextpkt) {
 3097                                 n = n->m_nextpkt;
 3098                         }
 3099                         n->m_nextpkt = m;
 3100                 }
 3101                 inp->sb_last_mpkt = m;
 3102         } else {
 3103                 inp->sb_last_mpkt = sb->sb_mb = m;
 3104                 inp->sctp_vtag_first = tag;
 3105         }
 3106 #endif
 3107         return (1);
 3108 #endif
 3109 #ifdef __OpenBSD__
 3110         struct mbuf *m, *n;
 3111 
 3112         if (m0 && (m0->m_flags & M_PKTHDR) == 0)
 3113                 panic("sbappendaddr_nocheck");
 3114         m0->m_pkthdr.csum = (int)tag;
 3115         for (n = control; n; n = n->m_next) {
 3116                 if (n->m_next == 0)     /* keep pointer to last control buf */
 3117                         break;
 3118         }
 3119         if (((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) == 0) ||
 3120             ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)== 0)) {
 3121                 if (asa->sa_len > MHLEN)
 3122                         return (0);
 3123                 MGETHDR(m, M_DONTWAIT, MT_SONAME);
 3124                 if (m == 0)
 3125                         return (0);
 3126                 m->m_len = asa->sa_len;
 3127                 bcopy((void *)asa, mtod(m, void *), asa->sa_len);
 3128         } else {
 3129                 m = NULL;
 3130         }
 3131         if (n)
 3132                 n->m_next = m0;         /* concatenate data to control */
 3133         else
 3134                 control = m0;
 3135 
 3136         m->m_pkthdr.csum = (int)tag;
 3137         m->m_next = control;
 3138         for (n = m; n; n = n->m_next)
 3139                 sballoc(sb, n);
 3140         if ((n = sb->sb_mb) != NULL) {
 3141                 if ((n->m_nextpkt != inp->sb_last_mpkt) && (n->m_nextpkt == NULL)) {
 3142                         inp->sb_last_mpkt = NULL;
 3143                 }
 3144                 if (inp->sb_last_mpkt)
 3145                         inp->sb_last_mpkt->m_nextpkt = m;
 3146                 else {
 3147                         while (n->m_nextpkt) {
 3148                                 n = n->m_nextpkt;
 3149                         }
 3150                         n->m_nextpkt = m;
 3151                 }
 3152                 inp->sb_last_mpkt = m;
 3153         } else {
 3154                 inp->sb_last_mpkt = sb->sb_mb = m;
 3155                 inp->sctp_vtag_first = tag;
 3156         }
 3157         return (1);
 3158 #endif
 3159 }
 3160 
 3161 /*************HOLD THIS COMMENT FOR PATCH FILE OF
 3162  *************ALTERNATE ROUTING CODE
 3163  */
 3164 
 3165 /*************HOLD THIS COMMENT FOR END OF PATCH FILE OF
 3166  *************ALTERNATE ROUTING CODE
 3167  */
 3168 
 3169 struct mbuf *
 3170 sctp_generate_invmanparam(int err)
 3171 {
 3172         /* Return a MBUF with a invalid mandatory parameter */
 3173         struct mbuf *m;
 3174 
 3175         MGET(m, M_DONTWAIT, MT_DATA);
 3176         if (m) {
 3177                 struct sctp_paramhdr *ph;
 3178                 m->m_len = sizeof(struct sctp_paramhdr);
 3179                 ph = mtod(m, struct sctp_paramhdr *);
 3180                 ph->param_length = htons(sizeof(struct sctp_paramhdr));
 3181                 ph->param_type = htons(err);
 3182         }
 3183         return (m);
 3184 }
 3185 
 3186 static int
 3187 sctp_should_be_moved(struct mbuf *this, struct sctp_association *asoc)
 3188 {
 3189         struct mbuf *m;
 3190         /*
 3191          * given a mbuf chain, look through it finding
 3192          * the M_PKTHDR and return 1 if it belongs to
 3193          * the association given. We tell this by
 3194          * a kludge where we stuff the my_vtag of the asoc
 3195          * into the m->m_pkthdr.csum_data/csum field.
 3196          */
 3197         m = this;
 3198         while (m) {
 3199                 if (m->m_flags & M_PKTHDR) {
 3200                         /* check it */
 3201 #if defined(__OpenBSD__)
 3202                         if ((u_int32_t)m->m_pkthdr.csum == asoc->my_vtag)
 3203 #else
 3204                         if ((u_int32_t)m->m_pkthdr.csum_data == asoc->my_vtag)
 3205 #endif
 3206                         {
 3207                                 /* Yep */
 3208                                 return (1);
 3209                         }
 3210                 }
 3211                 m = m->m_next;
 3212         }
 3213         return (0);
 3214 }
 3215 
 3216 u_int32_t
 3217 sctp_get_first_vtag_from_sb(struct socket *so)
 3218 {
 3219         struct mbuf *this, *at;
 3220         u_int32_t retval;
 3221 
 3222         retval = 0;
 3223         if (so->so_rcv.sb_mb) {
 3224                 /* grubbing time */
 3225                 this = so->so_rcv.sb_mb;
 3226                 while (this) {
 3227                         at = this;
 3228                         /* get to the m_pkthdr */
 3229                         while (at) {
 3230                                 if (at->m_flags & M_PKTHDR)
 3231                                         break;
 3232                                 else {
 3233                                         at = at->m_next;
 3234                                 }
 3235                         }
 3236                         /* now do we have a m_pkthdr */
 3237                         if (at && (at->m_flags & M_PKTHDR)) {
 3238                                 /* check it */
 3239 #if defined(__OpenBSD__)
 3240                                 if ((u_int32_t)at->m_pkthdr.csum != 0)
 3241 #else
 3242                                 if ((u_int32_t)at->m_pkthdr.csum_data != 0)
 3243 #endif
 3244                                 {
 3245                                         /* its the one */
 3246 #if defined(__OpenBSD__)
 3247                                         retval = (u_int32_t)at->m_pkthdr.csum;
 3248 #else
 3249                                         retval =
 3250                                             (u_int32_t)at->m_pkthdr.csum_data;
 3251 #endif
 3252                                         break;
 3253                                 }
 3254                         }
 3255                         this = this->m_nextpkt;
 3256                 }
 3257 
 3258         }
 3259         return (retval);
 3260 
 3261 }
 3262 void
 3263 sctp_grub_through_socket_buffer(struct sctp_inpcb *inp, struct socket *old,
 3264     struct socket *new, struct sctp_tcb *stcb)
 3265 {
 3266         struct mbuf **put, **take, *next, *this;
 3267         struct sockbuf *old_sb, *new_sb;
 3268         struct sctp_association *asoc;
 3269         int moved_top = 0;
 3270 
 3271         asoc = &stcb->asoc;
 3272         old_sb = &old->so_rcv;
 3273         new_sb = &new->so_rcv;
 3274         if (old_sb->sb_mb == NULL) {
 3275                 /* Nothing to move */
 3276                 return;
 3277         }
 3278 
 3279         if (inp->sctp_vtag_first == asoc->my_vtag) {
 3280                 /* First one must be moved */
 3281                 struct mbuf *mm;
 3282                 for (mm = old_sb->sb_mb; mm; mm = mm->m_next) {
 3283                         /*
 3284                          * Go down the chain and fix
 3285                          * the space allocation of the
 3286                          * two sockets.
 3287                          */
 3288                         sbfree(old_sb, mm);
 3289                         sballoc(new_sb, mm);
 3290                 }
 3291                 new_sb->sb_mb = old_sb->sb_mb;
 3292                 old_sb->sb_mb = new_sb->sb_mb->m_nextpkt;
 3293                 new_sb->sb_mb->m_nextpkt = NULL;
 3294                 put = &new_sb->sb_mb->m_nextpkt;
 3295                 moved_top = 1;
 3296         } else {
 3297                 put = &new_sb->sb_mb;
 3298         }
 3299 
 3300         take = &old_sb->sb_mb;
 3301         next = old_sb->sb_mb;
 3302         while (next) {
 3303                 this = next;
 3304                 /* position for next one */
 3305                 next = this->m_nextpkt;
 3306                 /* check the tag of this packet */
 3307                 if (sctp_should_be_moved(this, asoc)) {
 3308                         /* yes this needs to be moved */
 3309                         struct mbuf *mm;
 3310                         *take = this->m_nextpkt;
 3311                         this->m_nextpkt = NULL;
 3312                         *put = this;
 3313                         for (mm = this; mm; mm = mm->m_next) {
 3314                                 /*
 3315                                  * Go down the chain and fix
 3316                                  * the space allocation of the
 3317                                  * two sockets.
 3318                                  */
 3319                                 sbfree(old_sb, mm);
 3320                                 sballoc(new_sb, mm);
 3321                         }
 3322                         put = &this->m_nextpkt;
 3323 
 3324                 } else {
 3325                         /* no advance our take point. */
 3326                         take = &this->m_nextpkt;
 3327                 }
 3328         }
 3329         if (moved_top) {
 3330                 /*
 3331                  * Ok so now we must re-position vtag_first to
 3332                  * match the new first one since we moved the
 3333                  * mbuf at the top.
 3334                  */
 3335                 inp->sctp_vtag_first = sctp_get_first_vtag_from_sb(old);
 3336         }
 3337 }
 3338 
 3339 void
 3340 sctp_free_bufspace(struct sctp_tcb *stcb, struct sctp_association *asoc,
 3341     struct sctp_tmit_chunk *tp1)
 3342 {
 3343         if (tp1->data == NULL) {
 3344                 return;
 3345         }
 3346 #ifdef SCTP_MBCNT_LOGGING
 3347         sctp_log_mbcnt(SCTP_LOG_MBCNT_DECREASE,
 3348                        asoc->total_output_queue_size,
 3349                        tp1->book_size,
 3350                        asoc->total_output_mbuf_queue_size,
 3351                        tp1->mbcnt);
 3352 #endif
 3353         if (asoc->total_output_queue_size >= tp1->book_size) {
 3354                 asoc->total_output_queue_size -= tp1->book_size;
 3355         } else {
 3356                 asoc->total_output_queue_size = 0;
 3357         }
 3358 
 3359         /* Now free the mbuf */
 3360         if (asoc->total_output_mbuf_queue_size >= tp1->mbcnt) {
 3361                 asoc->total_output_mbuf_queue_size -= tp1->mbcnt;
 3362         } else {
 3363                 asoc->total_output_mbuf_queue_size = 0;
 3364         }
 3365         if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
 3366             (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
 3367                 if (stcb->sctp_socket->so_snd.sb_cc >= tp1->book_size) {
 3368                         stcb->sctp_socket->so_snd.sb_cc -= tp1->book_size;
 3369                 } else {
 3370                         stcb->sctp_socket->so_snd.sb_cc = 0;
 3371 
 3372                 }
 3373                 if (stcb->sctp_socket->so_snd.sb_mbcnt >= tp1->mbcnt) {
 3374                         stcb->sctp_socket->so_snd.sb_mbcnt -= tp1->mbcnt;
 3375                 } else {
 3376                         stcb->sctp_socket->so_snd.sb_mbcnt = 0;
 3377                 }
 3378         }
 3379 }
 3380 
 3381 int
 3382 sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1,
 3383     int reason, struct sctpchunk_listhead *queue)
 3384 {
 3385         int ret_sz = 0;
 3386         int notdone;
 3387         uint8_t foundeom = 0;
 3388 
 3389         do {
 3390                 ret_sz += tp1->book_size;
 3391                 tp1->sent = SCTP_FORWARD_TSN_SKIP;
 3392                 if (tp1->data) {
 3393                         sctp_free_bufspace(stcb, &stcb->asoc, tp1);
 3394                         sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb, reason, tp1);
 3395                         sctp_m_freem(tp1->data);
 3396                         tp1->data = NULL;
 3397                         sctp_sowwakeup(stcb->sctp_ep, stcb->sctp_socket);
 3398                 }
 3399                 if (tp1->flags & SCTP_PR_SCTP_BUFFER) {
 3400                         stcb->asoc.sent_queue_cnt_removeable--;
 3401                 }
 3402                 if (queue == &stcb->asoc.send_queue) {
 3403                         TAILQ_REMOVE(&stcb->asoc.send_queue, tp1, sctp_next);
 3404                         /* on to the sent queue */
 3405                         TAILQ_INSERT_TAIL(&stcb->asoc.sent_queue, tp1,
 3406                             sctp_next);
 3407                         stcb->asoc.sent_queue_cnt++;
 3408                 }
 3409                 if ((tp1->rec.data.rcv_flags & SCTP_DATA_NOT_FRAG) ==
 3410                     SCTP_DATA_NOT_FRAG) {
 3411                         /* not frag'ed we ae done   */
 3412                         notdone = 0;
 3413                         foundeom = 1;
 3414                 } else if (tp1->rec.data.rcv_flags & SCTP_DATA_LAST_FRAG) {
 3415                         /* end of frag, we are done */
 3416                         notdone = 0;
 3417                         foundeom = 1;
 3418                 } else {
 3419                         /* Its a begin or middle piece, we must mark all of it */
 3420                         notdone = 1;
 3421                         tp1 = TAILQ_NEXT(tp1, sctp_next);
 3422                 }
 3423         } while (tp1 && notdone);
 3424         if ((foundeom == 0) && (queue == &stcb->asoc.sent_queue)) {
 3425                 /*
 3426                  * The multi-part message was scattered
 3427                  * across the send and sent queue.
 3428                  */
 3429                 tp1 = TAILQ_FIRST(&stcb->asoc.send_queue);
 3430                 /*
 3431                  * recurse throught the send_queue too, starting at the
 3432                  * beginning.
 3433                  */
 3434                 if (tp1) {
 3435                         ret_sz += sctp_release_pr_sctp_chunk(stcb, tp1, reason,
 3436                             &stcb->asoc.send_queue);
 3437                 } else {
 3438                         printf("hmm, nothing on the send queue and no EOM?\n");
 3439                 }
 3440         }
 3441         return (ret_sz);
 3442 }
 3443 
 3444 /*
 3445  * checks to see if the given address, sa, is one that is currently
 3446  * known by the kernel
 3447  * note: can't distinguish the same address on multiple interfaces and
 3448  *       doesn't handle multiple addresses with different zone/scope id's
 3449  * note: ifa_ifwithaddr() compares the entire sockaddr struct
 3450  */
 3451 struct ifaddr *
 3452 sctp_find_ifa_by_addr(struct sockaddr *sa)
 3453 {
 3454         struct ifnet *ifn;
 3455         struct ifaddr *ifa;
 3456         int s;
 3457 
 3458         /* go through all our known interfaces */
 3459         s = pserialize_read_enter();
 3460         IFNET_READER_FOREACH(ifn) {
 3461                 /* go through each interface addresses */
 3462                 IFADDR_READER_FOREACH(ifa, ifn) {
 3463                         /* correct family? */
 3464                         if (ifa->ifa_addr->sa_family != sa->sa_family)
 3465                                 continue;
 3466 
 3467 #ifdef INET6
 3468                         if (ifa->ifa_addr->sa_family == AF_INET6) {
 3469                                 /* IPv6 address */
 3470                                 struct sockaddr_in6 *sin1, *sin2, sin6_tmp;
 3471                                 sin1 = (struct sockaddr_in6 *)ifa->ifa_addr;
 3472                                 if (IN6_IS_SCOPE_LINKLOCAL(&sin1->sin6_addr)) {
 3473                                         /* create a copy and clear scope */
 3474                                         memcpy(&sin6_tmp, sin1,
 3475                                             sizeof(struct sockaddr_in6));
 3476                                         sin1 = &sin6_tmp;
 3477                                         in6_clearscope(&sin1->sin6_addr);
 3478                                 }
 3479                                 sin2 = (struct sockaddr_in6 *)sa;
 3480                                 if (memcmp(&sin1->sin6_addr, &sin2->sin6_addr,
 3481                                            sizeof(struct in6_addr)) == 0) {
 3482                                         /* found it */
 3483                                         pserialize_read_exit(s);
 3484                                         return (ifa);
 3485                                 }
 3486                         } else
 3487 #endif
 3488                         if (ifa->ifa_addr->sa_family == AF_INET) {
 3489                                 /* IPv4 address */
 3490                                 struct sockaddr_in *sin1, *sin2;
 3491                                 sin1 = (struct sockaddr_in *)ifa->ifa_addr;
 3492                                 sin2 = (struct sockaddr_in *)sa;
 3493                                 if (sin1->sin_addr.s_addr ==
 3494                                     sin2->sin_addr.s_addr) {
 3495                                         /* found it */
 3496                                         pserialize_read_exit(s);
 3497                                         return (ifa);
 3498                                 }
 3499                         }
 3500                         /* else, not AF_INET or AF_INET6, so skip */
 3501                 } /* end foreach ifa */
 3502         } /* end foreach ifn */
 3503         pserialize_read_exit(s);
 3504 
 3505         /* not found! */
 3506         return (NULL);
 3507 }
 3508 
 3509 
 3510 #ifdef __APPLE__
 3511 /*
 3512  * here we hack in a fix for Apple's m_copym for the case where the first mbuf
 3513  * in the chain is a M_PKTHDR and the length is zero
 3514  */
 3515 static void
 3516 sctp_pkthdr_fix(struct mbuf *m)
 3517 {
 3518         struct mbuf *m_nxt;
 3519 
 3520         if ((m->m_flags & M_PKTHDR) == 0) {
 3521                 /* not a PKTHDR */
 3522                 return;
 3523         }
 3524 
 3525         if (m->m_len != 0) {
 3526                 /* not a zero length PKTHDR mbuf */
 3527                 return;
 3528         }
 3529 
 3530         /* let's move in a word into the first mbuf... yes, ugly! */
 3531         m_nxt = m->m_next;
 3532         if (m_nxt == NULL) {
 3533                 /* umm... not a very useful mbuf chain... */
 3534                 return;
 3535         }
 3536         if ((size_t)m_nxt->m_len > sizeof(long)) {
 3537                 /* move over a long */
 3538                 bcopy(mtod(m_nxt, void *), mtod(m, void *), sizeof(long));
 3539                 /* update mbuf data pointers and lengths */
 3540                 m->m_len += sizeof(long);
 3541                 m_nxt->m_data += sizeof(long);
 3542                 m_nxt->m_len -= sizeof(long);
 3543         }
 3544 }
 3545 
 3546 inline struct mbuf *
 3547 sctp_m_copym(struct mbuf *m, int off, int len, int wait)
 3548 {
 3549         sctp_pkthdr_fix(m);
 3550         return (m_copym(m, off, len, wait));
 3551 }
 3552 #endif /* __APPLE__ */

Cache object: c8da8388c6122cf7aff7ffb407ded39e


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.