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