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