Home | History | Annotate | Line # | Download | only in netinet
sctputil.c revision 1.15
      1   1.1       rjs /*	$KAME: sctputil.c,v 1.39 2005/06/16 20:54:06 jinmei Exp $	*/
      2  1.15       rjs /*	$NetBSD: sctputil.c,v 1.15 2019/08/13 19:55:40 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.15       rjs __KERNEL_RCSID(0, "$NetBSD: sctputil.c,v 1.15 2019/08/13 19:55:40 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.13  riastrad 	asoc->my_rwnd = uimax(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 u_int32_t
   1576   1.1       rjs sctp_calculate_len(struct mbuf *m)
   1577   1.1       rjs {
   1578   1.1       rjs 	u_int32_t tlen=0;
   1579   1.1       rjs 	struct mbuf *at;
   1580   1.1       rjs 	at = m;
   1581   1.1       rjs 	while (at) {
   1582   1.1       rjs 		tlen += at->m_len;
   1583   1.1       rjs 		at = at->m_next;
   1584   1.1       rjs 	}
   1585   1.1       rjs 	return (tlen);
   1586   1.1       rjs }
   1587   1.1       rjs 
   1588   1.1       rjs uint32_t
   1589   1.1       rjs sctp_calculate_sum(struct mbuf *m, int32_t *pktlen, uint32_t offset)
   1590   1.1       rjs {
   1591   1.1       rjs 	/*
   1592   1.1       rjs 	 * given a mbuf chain with a packetheader offset by 'offset'
   1593   1.1       rjs 	 * pointing at a sctphdr (with csum set to 0) go through
   1594   1.1       rjs 	 * the chain of m_next's and calculate the SCTP checksum.
   1595  1.15       rjs 	 * This is CRC32c.
   1596  1.15       rjs 	 * Also has a side bonus calculate the total length
   1597   1.1       rjs 	 * of the mbuf chain.
   1598   1.1       rjs 	 * Note: if offset is greater than the total mbuf length,
   1599   1.1       rjs 	 * checksum=1, pktlen=0 is returned (ie. no real error code)
   1600   1.1       rjs 	 */
   1601   1.1       rjs 	int32_t tlen=0;
   1602   1.1       rjs 	uint32_t base = 0xffffffff;
   1603   1.1       rjs 	struct mbuf *at;
   1604   1.1       rjs 	at = m;
   1605   1.1       rjs 	/* find the correct mbuf and offset into mbuf */
   1606   1.1       rjs 	while ((at != NULL) && (offset > (uint32_t)at->m_len)) {
   1607   1.1       rjs 		offset -= at->m_len;	/* update remaining offset left */
   1608   1.1       rjs 		at = at->m_next;
   1609   1.1       rjs 	}
   1610   1.1       rjs 
   1611   1.1       rjs 	while (at != NULL) {
   1612   1.1       rjs 		base = update_crc32(base, at->m_data + offset,
   1613   1.1       rjs 		    at->m_len - offset);
   1614   1.1       rjs 		tlen += at->m_len - offset;
   1615   1.1       rjs 		/* we only offset once into the first mbuf */
   1616   1.1       rjs 		if (offset) {
   1617   1.1       rjs 			offset = 0;
   1618   1.1       rjs 		}
   1619   1.1       rjs 		at = at->m_next;
   1620   1.1       rjs 	}
   1621   1.1       rjs 	if (pktlen != NULL) {
   1622   1.1       rjs 		*pktlen = tlen;
   1623   1.1       rjs 	}
   1624   1.1       rjs 	/* CRC-32c */
   1625   1.1       rjs 	base = sctp_csum_finalize(base);
   1626   1.1       rjs 	return (base);
   1627   1.1       rjs }
   1628   1.1       rjs 
   1629   1.1       rjs void
   1630   1.1       rjs sctp_mtu_size_reset(struct sctp_inpcb *inp,
   1631   1.1       rjs 		    struct sctp_association *asoc, u_long mtu)
   1632   1.1       rjs {
   1633   1.1       rjs 	/*
   1634   1.1       rjs 	 * Reset the P-MTU size on this association, this involves changing
   1635   1.1       rjs 	 * the asoc MTU, going through ANY chunk+overhead larger than mtu
   1636   1.1       rjs 	 * to allow the DF flag to be cleared.
   1637   1.1       rjs 	 */
   1638   1.1       rjs 	struct sctp_tmit_chunk *chk;
   1639   1.1       rjs 	struct sctp_stream_out *strm;
   1640   1.1       rjs 	unsigned int eff_mtu, ovh;
   1641   1.1       rjs 	asoc->smallest_mtu = mtu;
   1642   1.1       rjs 	if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
   1643   1.1       rjs 		ovh = SCTP_MIN_OVERHEAD;
   1644   1.1       rjs 	} else {
   1645   1.1       rjs 		ovh = SCTP_MIN_V4_OVERHEAD;
   1646   1.1       rjs 	}
   1647   1.1       rjs 	eff_mtu = mtu - ovh;
   1648   1.1       rjs 	/* Now mark any chunks that need to let IP fragment */
   1649   1.1       rjs 	TAILQ_FOREACH(strm, &asoc->out_wheel, next_spoke) {
   1650   1.1       rjs 		TAILQ_FOREACH(chk, &strm->outqueue, sctp_next) {
   1651   1.1       rjs 			if (chk->send_size > eff_mtu) {
   1652   1.1       rjs 				chk->flags &= SCTP_DONT_FRAGMENT;
   1653   1.1       rjs 				chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
   1654   1.1       rjs 			}
   1655   1.1       rjs 		}
   1656   1.1       rjs 	}
   1657   1.1       rjs 	TAILQ_FOREACH(chk, &asoc->send_queue, sctp_next) {
   1658   1.1       rjs 		if (chk->send_size > eff_mtu) {
   1659   1.1       rjs 			chk->flags &= SCTP_DONT_FRAGMENT;
   1660   1.1       rjs 			chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
   1661   1.1       rjs 		}
   1662   1.1       rjs 	}
   1663   1.1       rjs 	TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) {
   1664   1.1       rjs 		if (chk->send_size > eff_mtu) {
   1665   1.1       rjs 			chk->flags &= SCTP_DONT_FRAGMENT;
   1666   1.1       rjs 			chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
   1667   1.1       rjs 		}
   1668   1.1       rjs 	}
   1669   1.1       rjs }
   1670   1.1       rjs 
   1671   1.1       rjs 
   1672   1.1       rjs /*
   1673   1.1       rjs  * given an association and starting time of the current RTT period
   1674   1.1       rjs  * return RTO in number of usecs
   1675   1.1       rjs  * net should point to the current network
   1676   1.1       rjs  */
   1677   1.1       rjs u_int32_t
   1678   1.1       rjs sctp_calculate_rto(struct sctp_tcb *stcb,
   1679   1.1       rjs 		   struct sctp_association *asoc,
   1680   1.1       rjs 		   struct sctp_nets *net,
   1681   1.1       rjs 		   struct timeval *old)
   1682   1.1       rjs {
   1683   1.1       rjs 	/*
   1684   1.1       rjs 	 * given an association and the starting time of the current RTT
   1685   1.1       rjs 	 * period (in value1/value2) return RTO in number of usecs.
   1686   1.1       rjs 	 */
   1687   1.1       rjs 	int calc_time = 0;
   1688   1.1       rjs 	unsigned int new_rto = 0;
   1689   1.1       rjs 	int first_measure = 0;
   1690   1.1       rjs 	struct timeval now;
   1691   1.1       rjs 
   1692   1.1       rjs 	/************************/
   1693   1.1       rjs 	/* 1. calculate new RTT */
   1694   1.1       rjs 	/************************/
   1695   1.1       rjs 	/* get the current time */
   1696   1.1       rjs 	SCTP_GETTIME_TIMEVAL(&now);
   1697   1.1       rjs 	/* compute the RTT value */
   1698   1.1       rjs 	if ((u_long)now.tv_sec > (u_long)old->tv_sec) {
   1699   1.1       rjs 		calc_time = ((u_long)now.tv_sec - (u_long)old->tv_sec) * 1000;
   1700   1.1       rjs 		if ((u_long)now.tv_usec > (u_long)old->tv_usec) {
   1701   1.1       rjs 			calc_time += (((u_long)now.tv_usec -
   1702   1.1       rjs 				       (u_long)old->tv_usec)/1000);
   1703   1.1       rjs 		} else if ((u_long)now.tv_usec < (u_long)old->tv_usec) {
   1704   1.1       rjs 			/* Borrow 1,000ms from current calculation */
   1705   1.1       rjs 			calc_time -= 1000;
   1706   1.1       rjs 			/* Add in the slop over */
   1707   1.1       rjs 			calc_time += ((int)now.tv_usec/1000);
   1708   1.1       rjs 			/* Add in the pre-second ms's */
   1709   1.1       rjs 			calc_time += (((int)1000000 - (int)old->tv_usec)/1000);
   1710   1.1       rjs 		}
   1711   1.1       rjs 	} else if ((u_long)now.tv_sec == (u_long)old->tv_sec) {
   1712   1.1       rjs 		if ((u_long)now.tv_usec > (u_long)old->tv_usec) {
   1713   1.1       rjs 			calc_time = ((u_long)now.tv_usec -
   1714   1.1       rjs 				     (u_long)old->tv_usec)/1000;
   1715   1.1       rjs 		} else if ((u_long)now.tv_usec < (u_long)old->tv_usec) {
   1716   1.1       rjs 			/* impossible .. garbage in nothing out */
   1717   1.1       rjs 			return (((net->lastsa >> 2) + net->lastsv) >> 1);
   1718   1.1       rjs 		} else {
   1719   1.1       rjs 			/* impossible .. garbage in nothing out */
   1720   1.1       rjs 			return (((net->lastsa >> 2) + net->lastsv) >> 1);
   1721   1.1       rjs 		}
   1722   1.1       rjs 	} else {
   1723   1.1       rjs 		/* Clock wrapped? */
   1724   1.1       rjs 		return (((net->lastsa >> 2) + net->lastsv) >> 1);
   1725   1.1       rjs 	}
   1726   1.1       rjs 	/***************************/
   1727   1.1       rjs 	/* 2. update RTTVAR & SRTT */
   1728   1.1       rjs 	/***************************/
   1729   1.1       rjs #if 0
   1730   1.1       rjs 	/*	if (net->lastsv || net->lastsa) {*/
   1731   1.1       rjs 	/* per Section 5.3.1 C3 in SCTP */
   1732   1.1       rjs 	/*		net->lastsv = (int) 	*//* RTTVAR */
   1733   1.1       rjs 	/*			(((double)(1.0 - 0.25) * (double)net->lastsv) +
   1734   1.1       rjs 				(double)(0.25 * (double)abs(net->lastsa - calc_time)));
   1735   1.1       rjs 				net->lastsa = (int) */	/* SRTT */
   1736   1.1       rjs 	/*(((double)(1.0 - 0.125) * (double)net->lastsa) +
   1737   1.1       rjs 	  (double)(0.125 * (double)calc_time));
   1738   1.1       rjs 	  } else {
   1739   1.1       rjs 	*//* the first RTT calculation, per C2 Section 5.3.1 */
   1740   1.1       rjs 	/*		net->lastsa = calc_time;	*//* SRTT */
   1741   1.1       rjs 	/*		net->lastsv = calc_time / 2;	*//* RTTVAR */
   1742   1.1       rjs 	/*	}*/
   1743   1.1       rjs 	/* if RTTVAR goes to 0 you set to clock grainularity */
   1744   1.1       rjs 	/*	if (net->lastsv == 0) {
   1745   1.1       rjs 		net->lastsv = SCTP_CLOCK_GRANULARITY;
   1746   1.1       rjs 		}
   1747   1.1       rjs 		new_rto = net->lastsa + 4 * net->lastsv;
   1748   1.1       rjs 	*/
   1749   1.1       rjs #endif
   1750   1.1       rjs 	/* this is Van Jacobson's integer version */
   1751   1.1       rjs 	if (net->RTO) {
   1752   1.1       rjs 		calc_time -= (net->lastsa >> 3);
   1753   1.1       rjs 		net->lastsa += calc_time;
   1754   1.1       rjs 		if (calc_time < 0) {
   1755   1.1       rjs 			calc_time = -calc_time;
   1756   1.1       rjs 		}
   1757   1.1       rjs 		calc_time -= (net->lastsv >> 2);
   1758   1.1       rjs 		net->lastsv += calc_time;
   1759   1.1       rjs 		if (net->lastsv == 0) {
   1760   1.1       rjs 			net->lastsv = SCTP_CLOCK_GRANULARITY;
   1761   1.1       rjs 		}
   1762   1.1       rjs 	} else {
   1763   1.1       rjs 		/* First RTO measurment */
   1764   1.1       rjs 		net->lastsa = calc_time;
   1765   1.1       rjs 		net->lastsv = calc_time >> 1;
   1766   1.1       rjs 		first_measure = 1;
   1767   1.1       rjs 	}
   1768   1.1       rjs 	new_rto = ((net->lastsa >> 2) + net->lastsv) >> 1;
   1769   1.1       rjs 	if ((new_rto > SCTP_SAT_NETWORK_MIN) &&
   1770   1.1       rjs 	    (stcb->asoc.sat_network_lockout == 0)) {
   1771   1.1       rjs 		stcb->asoc.sat_network = 1;
   1772   1.1       rjs 	} else 	if ((!first_measure) && stcb->asoc.sat_network) {
   1773   1.1       rjs 		stcb->asoc.sat_network = 0;
   1774   1.1       rjs 		stcb->asoc.sat_network_lockout = 1;
   1775   1.1       rjs 	}
   1776   1.1       rjs 	/* bound it, per C6/C7 in Section 5.3.1 */
   1777   1.1       rjs 	if (new_rto < stcb->asoc.minrto) {
   1778   1.1       rjs 		new_rto = stcb->asoc.minrto;
   1779   1.1       rjs 	}
   1780   1.1       rjs 	if (new_rto > stcb->asoc.maxrto) {
   1781   1.1       rjs 		new_rto = stcb->asoc.maxrto;
   1782   1.1       rjs 	}
   1783   1.1       rjs 	/* we are now returning the RTT Smoothed */
   1784   1.1       rjs 	return ((u_int32_t)new_rto);
   1785   1.1       rjs }
   1786   1.1       rjs 
   1787   1.1       rjs 
   1788   1.1       rjs /*
   1789   1.1       rjs  * return a pointer to a contiguous piece of data from the given
   1790   1.1       rjs  * mbuf chain starting at 'off' for 'len' bytes.  If the desired
   1791   1.1       rjs  * piece spans more than one mbuf, a copy is made at 'ptr'.
   1792   1.1       rjs  * caller must ensure that the buffer size is >= 'len'
   1793   1.1       rjs  * returns NULL if there there isn't 'len' bytes in the chain.
   1794   1.1       rjs  */
   1795   1.1       rjs void *
   1796   1.1       rjs sctp_m_getptr(struct mbuf *m, int off, int len, u_int8_t *in_ptr)
   1797   1.1       rjs {
   1798   1.1       rjs 	uint32_t count;
   1799   1.1       rjs 	uint8_t *ptr;
   1800   1.1       rjs 	ptr = in_ptr;
   1801   1.1       rjs 	if ((off < 0) || (len <= 0))
   1802   1.1       rjs 		return (NULL);
   1803   1.1       rjs 
   1804   1.1       rjs 	/* find the desired start location */
   1805   1.1       rjs 	while ((m != NULL) && (off > 0)) {
   1806   1.1       rjs 		if (off < m->m_len)
   1807   1.1       rjs 			break;
   1808   1.1       rjs 		off -= m->m_len;
   1809   1.1       rjs 		m = m->m_next;
   1810   1.1       rjs 	}
   1811   1.1       rjs 	if (m == NULL)
   1812   1.1       rjs 		return (NULL);
   1813   1.1       rjs 
   1814   1.1       rjs 	/* is the current mbuf large enough (eg. contiguous)? */
   1815   1.1       rjs 	if ((m->m_len - off) >= len) {
   1816   1.1       rjs 		return ((void *)(mtod(m, vaddr_t) + off));
   1817   1.1       rjs 	} else {
   1818   1.1       rjs 		/* else, it spans more than one mbuf, so save a temp copy... */
   1819   1.1       rjs 		while ((m != NULL) && (len > 0)) {
   1820  1.13  riastrad 			count = uimin(m->m_len - off, len);
   1821   1.1       rjs 			memcpy(ptr, (void *)(mtod(m, vaddr_t) + off), count);
   1822   1.1       rjs 			len -= count;
   1823   1.1       rjs 			ptr += count;
   1824   1.1       rjs 			off = 0;
   1825   1.1       rjs 			m = m->m_next;
   1826   1.1       rjs 		}
   1827   1.1       rjs 		if ((m == NULL) && (len > 0))
   1828   1.1       rjs 			return (NULL);
   1829   1.1       rjs 		else
   1830   1.1       rjs 			return ((void *)in_ptr);
   1831   1.1       rjs 	}
   1832   1.1       rjs }
   1833   1.1       rjs 
   1834   1.1       rjs 
   1835   1.1       rjs struct sctp_paramhdr *
   1836   1.1       rjs sctp_get_next_param(struct mbuf *m,
   1837   1.1       rjs 		    int offset,
   1838   1.1       rjs 		    struct sctp_paramhdr *pull,
   1839   1.1       rjs 		    int pull_limit)
   1840   1.1       rjs {
   1841   1.1       rjs 	/* This just provides a typed signature to Peter's Pull routine */
   1842   1.1       rjs 	return ((struct sctp_paramhdr *)sctp_m_getptr(m, offset, pull_limit,
   1843   1.1       rjs     	    (u_int8_t *)pull));
   1844   1.1       rjs }
   1845   1.1       rjs 
   1846   1.1       rjs 
   1847   1.1       rjs int
   1848   1.1       rjs sctp_add_pad_tombuf(struct mbuf *m, int padlen)
   1849   1.1       rjs {
   1850   1.1       rjs 	/*
   1851   1.1       rjs 	 * add padlen bytes of 0 filled padding to the end of the mbuf.
   1852   1.1       rjs 	 * If padlen is > 3 this routine will fail.
   1853   1.1       rjs 	 */
   1854   1.1       rjs 	u_int8_t *dp;
   1855   1.1       rjs 	int i;
   1856   1.1       rjs 	if (padlen > 3) {
   1857   1.1       rjs 		return (ENOBUFS);
   1858   1.1       rjs 	}
   1859   1.1       rjs 	if (M_TRAILINGSPACE(m)) {
   1860   1.1       rjs 		/*
   1861   1.1       rjs 		 * The easy way.
   1862   1.1       rjs 		 * We hope the majority of the time we hit here :)
   1863   1.1       rjs 		 */
   1864   1.1       rjs 		dp = (u_int8_t *)(mtod(m, vaddr_t) + m->m_len);
   1865   1.1       rjs 		m->m_len += padlen;
   1866   1.1       rjs 	} else {
   1867   1.1       rjs 		/* Hard way we must grow the mbuf */
   1868   1.1       rjs 		struct mbuf *tmp;
   1869   1.1       rjs 		MGET(tmp, M_DONTWAIT, MT_DATA);
   1870   1.1       rjs 		if (tmp == NULL) {
   1871   1.1       rjs 			/* Out of space GAK! we are in big trouble. */
   1872   1.1       rjs 			return (ENOSPC);
   1873   1.1       rjs 		}
   1874   1.1       rjs 		/* setup and insert in middle */
   1875   1.1       rjs 		tmp->m_next = m->m_next;
   1876   1.1       rjs 		tmp->m_len = padlen;
   1877   1.1       rjs 		m->m_next = tmp;
   1878   1.1       rjs 		dp = mtod(tmp, u_int8_t *);
   1879   1.1       rjs 	}
   1880   1.1       rjs 	/* zero out the pad */
   1881   1.1       rjs 	for (i=  0; i < padlen; i++) {
   1882   1.1       rjs 		*dp = 0;
   1883   1.1       rjs 		dp++;
   1884   1.1       rjs 	}
   1885   1.1       rjs 	return (0);
   1886   1.1       rjs }
   1887   1.1       rjs 
   1888   1.1       rjs int
   1889   1.1       rjs sctp_pad_lastmbuf(struct mbuf *m, int padval)
   1890   1.1       rjs {
   1891   1.1       rjs 	/* find the last mbuf in chain and pad it */
   1892   1.1       rjs 	struct mbuf *m_at;
   1893   1.1       rjs 	m_at = m;
   1894   1.1       rjs 	while (m_at) {
   1895   1.1       rjs 		if (m_at->m_next == NULL) {
   1896   1.1       rjs 			return (sctp_add_pad_tombuf(m_at, padval));
   1897   1.1       rjs 		}
   1898   1.1       rjs 		m_at = m_at->m_next;
   1899   1.1       rjs 	}
   1900   1.1       rjs 	return (EFAULT);
   1901   1.1       rjs }
   1902   1.1       rjs 
   1903   1.1       rjs static void
   1904   1.1       rjs sctp_notify_assoc_change(u_int32_t event, struct sctp_tcb *stcb,
   1905   1.1       rjs     u_int32_t error)
   1906   1.1       rjs {
   1907   1.1       rjs 	struct mbuf *m_notify;
   1908   1.1       rjs 	struct sctp_assoc_change *sac;
   1909   1.1       rjs 	const struct sockaddr *to;
   1910   1.1       rjs 	struct sockaddr_in6 sin6, lsa6;
   1911   1.1       rjs 
   1912   1.1       rjs #ifdef SCTP_DEBUG
   1913   1.1       rjs 	printf("notify: %d\n", event);
   1914   1.1       rjs #endif
   1915   1.1       rjs 	/*
   1916  1.14   msaitoh 	 * First if we are going down dump everything we
   1917   1.1       rjs 	 * can to the socket rcv queue.
   1918   1.1       rjs 	 */
   1919   1.1       rjs 	if ((event == SCTP_SHUTDOWN_COMP) || (event == SCTP_COMM_LOST)) {
   1920   1.1       rjs 		sctp_deliver_data(stcb, &stcb->asoc, NULL, 0);
   1921   1.1       rjs 	}
   1922   1.1       rjs 
   1923   1.1       rjs 	/*
   1924   1.1       rjs 	 * For TCP model AND UDP connected sockets we will send
   1925   1.1       rjs 	 * an error up when an ABORT comes in.
   1926   1.1       rjs 	 */
   1927   1.1       rjs 	if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   1928   1.1       rjs 	     (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) &&
   1929   1.1       rjs 	    (event == SCTP_COMM_LOST)) {
   1930   1.1       rjs 		stcb->sctp_socket->so_error = ECONNRESET;
   1931   1.1       rjs 		/* Wake ANY sleepers */
   1932   1.1       rjs 		sowwakeup(stcb->sctp_socket);
   1933   1.1       rjs 		sorwakeup(stcb->sctp_socket);
   1934   1.1       rjs 	}
   1935   1.1       rjs #if 0
   1936   1.1       rjs 	if ((event == SCTP_COMM_UP) &&
   1937   1.1       rjs 	    (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
   1938   1.1       rjs  	    (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) {
   1939   1.1       rjs 		 soisconnected(stcb->sctp_socket);
   1940   1.1       rjs 	}
   1941   1.1       rjs #endif
   1942   1.1       rjs 	if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_RECVASSOCEVNT)) {
   1943   1.1       rjs 		/* event not enabled */
   1944   1.1       rjs 		return;
   1945   1.1       rjs 	}
   1946   1.1       rjs 	MGETHDR(m_notify, M_DONTWAIT, MT_DATA);
   1947   1.1       rjs 	if (m_notify == NULL)
   1948   1.1       rjs 		/* no space left */
   1949   1.1       rjs 		return;
   1950   1.1       rjs 	m_notify->m_len = 0;
   1951   1.1       rjs 
   1952   1.1       rjs 	sac = mtod(m_notify, struct sctp_assoc_change *);
   1953   1.1       rjs 	sac->sac_type = SCTP_ASSOC_CHANGE;
   1954   1.1       rjs 	sac->sac_flags = 0;
   1955   1.1       rjs 	sac->sac_length = sizeof(struct sctp_assoc_change);
   1956   1.1       rjs 	sac->sac_state = event;
   1957   1.1       rjs 	sac->sac_error = error;
   1958   1.1       rjs 	/* XXX verify these stream counts */
   1959   1.1       rjs 	sac->sac_outbound_streams = stcb->asoc.streamoutcnt;
   1960   1.1       rjs 	sac->sac_inbound_streams = stcb->asoc.streamincnt;
   1961   1.1       rjs 	sac->sac_assoc_id = sctp_get_associd(stcb);
   1962   1.1       rjs 
   1963   1.1       rjs 	m_notify->m_flags |= M_EOR | M_NOTIFICATION;
   1964   1.1       rjs 	m_notify->m_pkthdr.len = sizeof(struct sctp_assoc_change);
   1965   1.9     ozaki 	m_reset_rcvif(m_notify);
   1966   1.1       rjs 	m_notify->m_len = sizeof(struct sctp_assoc_change);
   1967   1.1       rjs 	m_notify->m_next = NULL;
   1968   1.1       rjs 
   1969   1.1       rjs 	/* append to socket */
   1970   1.1       rjs 	to = rtcache_getdst(&stcb->asoc.primary_destination->ro);
   1971   1.1       rjs 	if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
   1972   1.1       rjs 	    to->sa_family == AF_INET) {
   1973   1.1       rjs 		const struct sockaddr_in *sin;
   1974   1.1       rjs 
   1975   1.1       rjs 		sin = (const struct sockaddr_in *)to;
   1976   1.2       rtr 		in6_sin_2_v4mapsin6(sin, &sin6);
   1977   1.1       rjs 		to = (struct sockaddr *)&sin6;
   1978   1.1       rjs 	}
   1979   1.1       rjs 	/* check and strip embedded scope junk */
   1980   1.1       rjs 	to = (const struct sockaddr *)sctp_recover_scope((const struct sockaddr_in6 *)to,
   1981   1.1       rjs 						   &lsa6);
   1982   1.1       rjs 	/*
   1983   1.1       rjs 	 * We need to always notify comm changes.
   1984   1.1       rjs 	 * if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) {
   1985   1.1       rjs 	 * 	sctp_m_freem(m_notify);
   1986   1.1       rjs 	 *	return;
   1987   1.1       rjs 	 * }
   1988   1.1       rjs 	*/
   1989   1.1       rjs 	SCTP_TCB_UNLOCK(stcb);
   1990   1.1       rjs 	SCTP_INP_WLOCK(stcb->sctp_ep);
   1991   1.1       rjs 	SCTP_TCB_LOCK(stcb);
   1992   1.1       rjs 	if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv,
   1993   1.1       rjs 	    to, m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) {
   1994   1.1       rjs 		/* not enough room */
   1995   1.1       rjs 		sctp_m_freem(m_notify);
   1996   1.1       rjs 		SCTP_INP_WUNLOCK(stcb->sctp_ep);
   1997   1.1       rjs 		return;
   1998   1.1       rjs 	}
   1999   1.1       rjs 	if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) &&
   2000   1.1       rjs 	   ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){
   2001   1.1       rjs 		if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) {
   2002   1.1       rjs 			stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
   2003   1.1       rjs 		}
   2004   1.1       rjs 	} else {
   2005   1.1       rjs 		stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
   2006   1.1       rjs 	}
   2007   1.1       rjs 	SCTP_INP_WUNLOCK(stcb->sctp_ep);
   2008   1.1       rjs 	/* Wake up any sleeper */
   2009   1.1       rjs 	sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
   2010   1.1       rjs 	sctp_sowwakeup(stcb->sctp_ep, stcb->sctp_socket);
   2011   1.1       rjs }
   2012   1.1       rjs 
   2013   1.1       rjs static void
   2014   1.1       rjs sctp_notify_peer_addr_change(struct sctp_tcb *stcb, uint32_t state,
   2015   1.1       rjs     const struct sockaddr *sa, uint32_t error)
   2016   1.1       rjs {
   2017   1.1       rjs 	struct mbuf *m_notify;
   2018   1.1       rjs 	struct sctp_paddr_change *spc;
   2019   1.1       rjs 	const struct sockaddr *to;
   2020   1.1       rjs 	struct sockaddr_in6 sin6, lsa6;
   2021   1.1       rjs 
   2022   1.1       rjs 	if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_RECVPADDREVNT))
   2023   1.1       rjs 		/* event not enabled */
   2024   1.1       rjs 		return;
   2025   1.1       rjs 
   2026   1.1       rjs 	MGETHDR(m_notify, M_DONTWAIT, MT_DATA);
   2027   1.1       rjs 	if (m_notify == NULL)
   2028   1.1       rjs 		return;
   2029   1.1       rjs 	m_notify->m_len = 0;
   2030   1.1       rjs 
   2031   1.1       rjs 	MCLGET(m_notify, M_DONTWAIT);
   2032   1.1       rjs 	if ((m_notify->m_flags & M_EXT) != M_EXT) {
   2033   1.1       rjs 		sctp_m_freem(m_notify);
   2034   1.1       rjs 		return;
   2035   1.1       rjs 	}
   2036   1.1       rjs 
   2037   1.1       rjs 	spc = mtod(m_notify, struct sctp_paddr_change *);
   2038   1.1       rjs 	spc->spc_type = SCTP_PEER_ADDR_CHANGE;
   2039   1.1       rjs 	spc->spc_flags = 0;
   2040   1.1       rjs 	spc->spc_length = sizeof(struct sctp_paddr_change);
   2041   1.1       rjs 	if (sa->sa_family == AF_INET) {
   2042   1.1       rjs 		memcpy(&spc->spc_aaddr, sa, sizeof(struct sockaddr_in));
   2043   1.1       rjs 	} else {
   2044   1.1       rjs 		memcpy(&spc->spc_aaddr, sa, sizeof(struct sockaddr_in6));
   2045   1.1       rjs 	}
   2046   1.1       rjs 	spc->spc_state = state;
   2047   1.1       rjs 	spc->spc_error = error;
   2048   1.1       rjs 	spc->spc_assoc_id = sctp_get_associd(stcb);
   2049   1.1       rjs 
   2050   1.1       rjs 	m_notify->m_flags |= M_EOR | M_NOTIFICATION;
   2051   1.1       rjs 	m_notify->m_pkthdr.len = sizeof(struct sctp_paddr_change);
   2052   1.9     ozaki 	m_reset_rcvif(m_notify);
   2053   1.1       rjs 	m_notify->m_len = sizeof(struct sctp_paddr_change);
   2054   1.1       rjs 	m_notify->m_next = NULL;
   2055   1.1       rjs 
   2056   1.1       rjs 	to = rtcache_getdst(&stcb->asoc.primary_destination->ro);
   2057   1.1       rjs 	if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
   2058   1.1       rjs 	    to->sa_family == AF_INET) {
   2059   1.1       rjs 		const struct sockaddr_in *sin;
   2060   1.1       rjs 
   2061   1.1       rjs 		sin = (const struct sockaddr_in *)to;
   2062   1.2       rtr 		in6_sin_2_v4mapsin6(sin, &sin6);
   2063   1.1       rjs 		to = (struct sockaddr *)&sin6;
   2064   1.1       rjs 	}
   2065   1.1       rjs 	/* check and strip embedded scope junk */
   2066   1.1       rjs 	to = (const struct sockaddr *)sctp_recover_scope((const struct sockaddr_in6 *)to,
   2067   1.1       rjs 	    &lsa6);
   2068   1.1       rjs 
   2069   1.1       rjs 	if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) {
   2070   1.1       rjs 		sctp_m_freem(m_notify);
   2071   1.1       rjs 		return;
   2072   1.1       rjs 	}
   2073   1.1       rjs 	/* append to socket */
   2074   1.1       rjs 	SCTP_TCB_UNLOCK(stcb);
   2075   1.1       rjs 	SCTP_INP_WLOCK(stcb->sctp_ep);
   2076   1.1       rjs 	SCTP_TCB_LOCK(stcb);
   2077   1.1       rjs 	if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv, to,
   2078   1.1       rjs 	    m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) {
   2079   1.1       rjs 		/* not enough room */
   2080   1.1       rjs 		sctp_m_freem(m_notify);
   2081   1.1       rjs 		SCTP_INP_WUNLOCK(stcb->sctp_ep);
   2082   1.1       rjs 		return;
   2083   1.1       rjs 	}
   2084   1.1       rjs 	if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) &&
   2085   1.1       rjs 	   ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){
   2086   1.1       rjs 		if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) {
   2087   1.1       rjs 			stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
   2088   1.1       rjs 		}
   2089   1.1       rjs 	} else {
   2090   1.1       rjs 		stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
   2091   1.1       rjs 	}
   2092   1.1       rjs 	SCTP_INP_WUNLOCK(stcb->sctp_ep);
   2093   1.1       rjs 	sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
   2094   1.1       rjs }
   2095   1.1       rjs 
   2096   1.1       rjs 
   2097   1.1       rjs static void
   2098   1.1       rjs sctp_notify_send_failed(struct sctp_tcb *stcb, u_int32_t error,
   2099   1.1       rjs 			struct sctp_tmit_chunk *chk)
   2100   1.1       rjs {
   2101   1.1       rjs 	struct mbuf *m_notify;
   2102   1.1       rjs 	struct sctp_send_failed *ssf;
   2103   1.1       rjs 	struct sockaddr_in6 sin6, lsa6;
   2104   1.1       rjs 	const struct sockaddr *to;
   2105   1.1       rjs 	int length;
   2106   1.1       rjs 
   2107   1.1       rjs 	if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_RECVSENDFAILEVNT))
   2108   1.1       rjs 		/* event not enabled */
   2109   1.1       rjs 		return;
   2110   1.1       rjs 
   2111   1.1       rjs 	length = sizeof(struct sctp_send_failed) + chk->send_size;
   2112   1.1       rjs 	MGETHDR(m_notify, M_DONTWAIT, MT_DATA);
   2113   1.1       rjs 	if (m_notify == NULL)
   2114   1.1       rjs 		/* no space left */
   2115   1.1       rjs 		return;
   2116   1.1       rjs 	m_notify->m_len = 0;
   2117   1.1       rjs 	ssf = mtod(m_notify, struct sctp_send_failed *);
   2118   1.1       rjs 	ssf->ssf_type = SCTP_SEND_FAILED;
   2119   1.1       rjs 	if (error == SCTP_NOTIFY_DATAGRAM_UNSENT)
   2120   1.1       rjs 		ssf->ssf_flags = SCTP_DATA_UNSENT;
   2121   1.1       rjs 	else
   2122   1.1       rjs 		ssf->ssf_flags = SCTP_DATA_SENT;
   2123   1.1       rjs 	ssf->ssf_length = length;
   2124   1.1       rjs 	ssf->ssf_error = error;
   2125   1.1       rjs 	/* not exactly what the user sent in, but should be close :) */
   2126   1.1       rjs 	ssf->ssf_info.sinfo_stream = chk->rec.data.stream_number;
   2127   1.1       rjs 	ssf->ssf_info.sinfo_ssn = chk->rec.data.stream_seq;
   2128   1.1       rjs 	ssf->ssf_info.sinfo_flags = chk->rec.data.rcv_flags;
   2129   1.1       rjs 	ssf->ssf_info.sinfo_ppid = chk->rec.data.payloadtype;
   2130   1.1       rjs 	ssf->ssf_info.sinfo_context = chk->rec.data.context;
   2131   1.1       rjs 	ssf->ssf_info.sinfo_assoc_id = sctp_get_associd(stcb);
   2132   1.1       rjs 	ssf->ssf_assoc_id = sctp_get_associd(stcb);
   2133   1.1       rjs 	m_notify->m_next = chk->data;
   2134   1.1       rjs 	if (m_notify->m_next == NULL)
   2135   1.1       rjs 		m_notify->m_flags |= M_EOR | M_NOTIFICATION;
   2136   1.1       rjs 	else {
   2137   1.1       rjs 		struct mbuf *m;
   2138   1.1       rjs 		m_notify->m_flags |= M_NOTIFICATION;
   2139   1.1       rjs 		m = m_notify;
   2140   1.1       rjs 		while (m->m_next != NULL)
   2141   1.1       rjs 			m = m->m_next;
   2142   1.1       rjs 		m->m_flags |= M_EOR;
   2143   1.1       rjs 	}
   2144   1.1       rjs 	m_notify->m_pkthdr.len = length;
   2145   1.9     ozaki 	m_reset_rcvif(m_notify);
   2146   1.1       rjs 	m_notify->m_len = sizeof(struct sctp_send_failed);
   2147   1.1       rjs 
   2148   1.1       rjs 	/* Steal off the mbuf */
   2149   1.1       rjs 	chk->data = NULL;
   2150   1.1       rjs 	to = rtcache_getdst(&stcb->asoc.primary_destination->ro);
   2151   1.1       rjs 	if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
   2152   1.1       rjs 	    to->sa_family == AF_INET) {
   2153   1.1       rjs 		const struct sockaddr_in *sin;
   2154   1.1       rjs 
   2155   1.1       rjs 		sin = satocsin(to);
   2156   1.2       rtr 		in6_sin_2_v4mapsin6(sin, &sin6);
   2157   1.1       rjs 		to = (struct sockaddr *)&sin6;
   2158   1.1       rjs 	}
   2159   1.1       rjs 	/* check and strip embedded scope junk */
   2160   1.1       rjs 	to = (const struct sockaddr *)sctp_recover_scope((const struct sockaddr_in6 *)to,
   2161   1.1       rjs 						   &lsa6);
   2162   1.1       rjs 
   2163   1.1       rjs 	if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) {
   2164   1.1       rjs 		sctp_m_freem(m_notify);
   2165   1.1       rjs 		return;
   2166   1.1       rjs 	}
   2167   1.1       rjs 
   2168   1.1       rjs 	/* append to socket */
   2169   1.1       rjs 	SCTP_TCB_UNLOCK(stcb);
   2170   1.1       rjs 	SCTP_INP_WLOCK(stcb->sctp_ep);
   2171   1.1       rjs 	SCTP_TCB_LOCK(stcb);
   2172   1.1       rjs 	if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv, to,
   2173   1.1       rjs 	    m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) {
   2174   1.1       rjs 		/* not enough room */
   2175   1.1       rjs 		sctp_m_freem(m_notify);
   2176   1.1       rjs 		SCTP_INP_WUNLOCK(stcb->sctp_ep);
   2177   1.1       rjs 		return;
   2178   1.1       rjs 	}
   2179   1.1       rjs 	if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) &&
   2180   1.1       rjs 	   ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){
   2181   1.1       rjs 		if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) {
   2182   1.1       rjs 			stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
   2183   1.1       rjs 		}
   2184   1.1       rjs 	} else {
   2185   1.1       rjs 		stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
   2186   1.1       rjs 	}
   2187   1.1       rjs 	SCTP_INP_WUNLOCK(stcb->sctp_ep);
   2188   1.1       rjs 	sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
   2189   1.1       rjs }
   2190   1.1       rjs 
   2191   1.1       rjs static void
   2192   1.1       rjs sctp_notify_adaption_layer(struct sctp_tcb *stcb,
   2193   1.1       rjs 			   u_int32_t error)
   2194   1.1       rjs {
   2195   1.1       rjs 	struct mbuf *m_notify;
   2196   1.1       rjs 	struct sctp_adaption_event *sai;
   2197   1.1       rjs 	struct sockaddr_in6 sin6, lsa6;
   2198   1.1       rjs 	const struct sockaddr *to;
   2199   1.1       rjs 
   2200   1.1       rjs 	if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_ADAPTIONEVNT))
   2201   1.1       rjs 		/* event not enabled */
   2202   1.1       rjs 		return;
   2203   1.1       rjs 
   2204   1.1       rjs 	MGETHDR(m_notify, M_DONTWAIT, MT_DATA);
   2205   1.1       rjs 	if (m_notify == NULL)
   2206   1.1       rjs 		/* no space left */
   2207   1.1       rjs 		return;
   2208   1.1       rjs 	m_notify->m_len = 0;
   2209   1.1       rjs 	sai = mtod(m_notify, struct sctp_adaption_event *);
   2210   1.1       rjs 	sai->sai_type = SCTP_ADAPTION_INDICATION;
   2211   1.1       rjs 	sai->sai_flags = 0;
   2212   1.1       rjs 	sai->sai_length = sizeof(struct sctp_adaption_event);
   2213   1.1       rjs 	sai->sai_adaption_ind = error;
   2214   1.1       rjs 	sai->sai_assoc_id = sctp_get_associd(stcb);
   2215   1.1       rjs 
   2216   1.1       rjs 	m_notify->m_flags |= M_EOR | M_NOTIFICATION;
   2217   1.1       rjs 	m_notify->m_pkthdr.len = sizeof(struct sctp_adaption_event);
   2218   1.9     ozaki 	m_reset_rcvif(m_notify);
   2219   1.1       rjs 	m_notify->m_len = sizeof(struct sctp_adaption_event);
   2220   1.1       rjs 	m_notify->m_next = NULL;
   2221   1.1       rjs 
   2222   1.1       rjs 	to = rtcache_getdst(&stcb->asoc.primary_destination->ro);
   2223   1.1       rjs 	if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
   2224   1.1       rjs 	    (to->sa_family == AF_INET)) {
   2225   1.1       rjs 		const struct sockaddr_in *sin;
   2226   1.1       rjs 
   2227   1.1       rjs 		sin = satocsin(to);
   2228   1.2       rtr 		in6_sin_2_v4mapsin6(sin, &sin6);
   2229   1.1       rjs 		to = (struct sockaddr *)&sin6;
   2230   1.1       rjs 	}
   2231   1.1       rjs 	/* check and strip embedded scope junk */
   2232   1.1       rjs 	to = (const struct sockaddr *)sctp_recover_scope((const struct sockaddr_in6 *)to,
   2233   1.1       rjs 						   &lsa6);
   2234   1.1       rjs 	if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) {
   2235   1.1       rjs 		sctp_m_freem(m_notify);
   2236   1.1       rjs 		return;
   2237   1.1       rjs 	}
   2238   1.1       rjs 	/* append to socket */
   2239   1.1       rjs 	SCTP_TCB_UNLOCK(stcb);
   2240   1.1       rjs 	SCTP_INP_WLOCK(stcb->sctp_ep);
   2241   1.1       rjs 	SCTP_TCB_LOCK(stcb);
   2242   1.1       rjs 	if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv, to,
   2243   1.1       rjs 	    m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) {
   2244   1.1       rjs 		/* not enough room */
   2245   1.1       rjs 		sctp_m_freem(m_notify);
   2246   1.1       rjs 		SCTP_INP_WUNLOCK(stcb->sctp_ep);
   2247   1.1       rjs 		return;
   2248   1.1       rjs 	}
   2249   1.1       rjs 	if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) &&
   2250   1.1       rjs 	   ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){
   2251   1.1       rjs 		if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) {
   2252   1.1       rjs 			stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
   2253   1.1       rjs 		}
   2254   1.1       rjs 	} else {
   2255   1.1       rjs 		stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
   2256   1.1       rjs 	}
   2257   1.1       rjs 	SCTP_INP_WUNLOCK(stcb->sctp_ep);
   2258   1.1       rjs 	sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
   2259   1.1       rjs }
   2260   1.1       rjs 
   2261   1.1       rjs static void
   2262   1.1       rjs sctp_notify_partial_delivery_indication(struct sctp_tcb *stcb,
   2263   1.1       rjs 					u_int32_t error)
   2264   1.1       rjs {
   2265   1.1       rjs 	struct mbuf *m_notify;
   2266   1.1       rjs 	struct sctp_pdapi_event *pdapi;
   2267   1.1       rjs 	struct sockaddr_in6 sin6, lsa6;
   2268   1.1       rjs 	const struct sockaddr *to;
   2269   1.1       rjs 
   2270   1.1       rjs 	if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_PDAPIEVNT))
   2271   1.1       rjs 		/* event not enabled */
   2272   1.1       rjs 		return;
   2273   1.1       rjs 
   2274   1.1       rjs 	MGETHDR(m_notify, M_DONTWAIT, MT_DATA);
   2275   1.1       rjs 	if (m_notify == NULL)
   2276   1.1       rjs 		/* no space left */
   2277   1.1       rjs 		return;
   2278   1.1       rjs 	m_notify->m_len = 0;
   2279   1.1       rjs 	pdapi = mtod(m_notify, struct sctp_pdapi_event *);
   2280   1.1       rjs 	pdapi->pdapi_type = SCTP_PARTIAL_DELIVERY_EVENT;
   2281   1.1       rjs 	pdapi->pdapi_flags = 0;
   2282   1.1       rjs 	pdapi->pdapi_length = sizeof(struct sctp_pdapi_event);
   2283   1.1       rjs 	pdapi->pdapi_indication = error;
   2284   1.1       rjs 	pdapi->pdapi_assoc_id = sctp_get_associd(stcb);
   2285   1.1       rjs 
   2286   1.1       rjs 	m_notify->m_flags |= M_EOR | M_NOTIFICATION;
   2287   1.1       rjs 	m_notify->m_pkthdr.len = sizeof(struct sctp_pdapi_event);
   2288   1.9     ozaki 	m_reset_rcvif(m_notify);
   2289   1.1       rjs 	m_notify->m_len = sizeof(struct sctp_pdapi_event);
   2290   1.1       rjs 	m_notify->m_next = NULL;
   2291   1.1       rjs 
   2292   1.1       rjs 	to = rtcache_getdst(&stcb->asoc.primary_destination->ro);
   2293   1.1       rjs 	if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
   2294   1.1       rjs 	    (to->sa_family == AF_INET)) {
   2295   1.1       rjs 		const struct sockaddr_in *sin;
   2296   1.1       rjs 
   2297   1.1       rjs 		sin = satocsin(to);
   2298   1.2       rtr 		in6_sin_2_v4mapsin6(sin, &sin6);
   2299   1.1       rjs 		to = (struct sockaddr *)&sin6;
   2300   1.1       rjs 	}
   2301   1.1       rjs 	/* check and strip embedded scope junk */
   2302   1.1       rjs 	to = (const struct sockaddr *)sctp_recover_scope((const struct sockaddr_in6 *)to,
   2303   1.1       rjs 						   &lsa6);
   2304   1.1       rjs 	if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) {
   2305   1.1       rjs 		sctp_m_freem(m_notify);
   2306   1.1       rjs 		return;
   2307   1.1       rjs 	}
   2308   1.1       rjs 	/* append to socket */
   2309   1.1       rjs 	SCTP_TCB_UNLOCK(stcb);
   2310   1.1       rjs 	SCTP_INP_WLOCK(stcb->sctp_ep);
   2311   1.1       rjs 	SCTP_TCB_LOCK(stcb);
   2312   1.1       rjs 	if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv, to,
   2313   1.1       rjs 	    m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) {
   2314   1.1       rjs 		/* not enough room */
   2315   1.1       rjs 		sctp_m_freem(m_notify);
   2316   1.1       rjs 		SCTP_INP_WUNLOCK(stcb->sctp_ep);
   2317   1.1       rjs 		return;
   2318   1.1       rjs 	}
   2319   1.1       rjs 	if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) &&
   2320   1.1       rjs 	   ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){
   2321   1.1       rjs 		if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) {
   2322   1.1       rjs 			stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
   2323   1.1       rjs 		}
   2324   1.1       rjs 	} else {
   2325   1.1       rjs 		stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
   2326   1.1       rjs 	}
   2327   1.1       rjs 	SCTP_INP_WUNLOCK(stcb->sctp_ep);
   2328   1.1       rjs 	sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
   2329   1.1       rjs }
   2330   1.1       rjs 
   2331   1.1       rjs static void
   2332   1.1       rjs sctp_notify_shutdown_event(struct sctp_tcb *stcb)
   2333   1.1       rjs {
   2334   1.1       rjs 	struct mbuf *m_notify;
   2335   1.1       rjs 	struct sctp_shutdown_event *sse;
   2336   1.1       rjs 	struct sockaddr_in6 sin6, lsa6;
   2337   1.1       rjs 	const struct sockaddr *to;
   2338   1.1       rjs 
   2339   1.1       rjs 	/*
   2340   1.1       rjs 	 * For TCP model AND UDP connected sockets we will send
   2341   1.1       rjs 	 * an error up when an SHUTDOWN completes
   2342   1.1       rjs 	 */
   2343   1.1       rjs 	if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   2344   1.1       rjs 	    (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
   2345   1.1       rjs 		/* mark socket closed for read/write and wakeup! */
   2346   1.1       rjs 		socantrcvmore(stcb->sctp_socket);
   2347   1.1       rjs 		socantsendmore(stcb->sctp_socket);
   2348   1.1       rjs 	}
   2349   1.1       rjs 
   2350   1.1       rjs 	if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT))
   2351   1.1       rjs 		/* event not enabled */
   2352   1.1       rjs 		return;
   2353   1.1       rjs 
   2354   1.1       rjs 	MGETHDR(m_notify, M_DONTWAIT, MT_DATA);
   2355   1.1       rjs 	if (m_notify == NULL)
   2356   1.1       rjs 		/* no space left */
   2357   1.1       rjs 		return;
   2358   1.1       rjs 	m_notify->m_len = 0;
   2359   1.1       rjs 	sse = mtod(m_notify, struct sctp_shutdown_event *);
   2360   1.1       rjs 	sse->sse_type = SCTP_SHUTDOWN_EVENT;
   2361   1.1       rjs 	sse->sse_flags = 0;
   2362   1.1       rjs 	sse->sse_length = sizeof(struct sctp_shutdown_event);
   2363   1.1       rjs 	sse->sse_assoc_id = sctp_get_associd(stcb);
   2364   1.1       rjs 
   2365   1.1       rjs 	m_notify->m_flags |= M_EOR | M_NOTIFICATION;
   2366   1.1       rjs 	m_notify->m_pkthdr.len = sizeof(struct sctp_shutdown_event);
   2367   1.9     ozaki 	m_reset_rcvif(m_notify);
   2368   1.1       rjs 	m_notify->m_len = sizeof(struct sctp_shutdown_event);
   2369   1.1       rjs 	m_notify->m_next = NULL;
   2370   1.1       rjs 
   2371   1.1       rjs 	to = rtcache_getdst(&stcb->asoc.primary_destination->ro);
   2372   1.1       rjs 	if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
   2373   1.1       rjs 	    to->sa_family == AF_INET) {
   2374   1.1       rjs 		const struct sockaddr_in *sin;
   2375   1.1       rjs 
   2376   1.1       rjs 		sin = satocsin(to);
   2377   1.2       rtr 		in6_sin_2_v4mapsin6(sin, &sin6);
   2378   1.1       rjs 		to = (struct sockaddr *)&sin6;
   2379   1.1       rjs 	}
   2380   1.1       rjs 	/* check and strip embedded scope junk */
   2381   1.1       rjs 	to = (const struct sockaddr *)sctp_recover_scope((const struct sockaddr_in6 *)to,
   2382   1.1       rjs 	    &lsa6);
   2383   1.1       rjs 	if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) {
   2384   1.1       rjs 		sctp_m_freem(m_notify);
   2385   1.1       rjs 		return;
   2386   1.1       rjs 	}
   2387   1.1       rjs 	/* append to socket */
   2388   1.1       rjs 	SCTP_TCB_UNLOCK(stcb);
   2389   1.1       rjs 	SCTP_INP_WLOCK(stcb->sctp_ep);
   2390   1.1       rjs 	SCTP_TCB_LOCK(stcb);
   2391   1.1       rjs 	if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv, to,
   2392   1.1       rjs 	    m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) {
   2393   1.1       rjs 		/* not enough room */
   2394   1.1       rjs 		sctp_m_freem(m_notify);
   2395   1.1       rjs 		SCTP_INP_WUNLOCK(stcb->sctp_ep);
   2396   1.1       rjs 		return;
   2397   1.1       rjs 	}
   2398   1.1       rjs 	if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) &&
   2399   1.1       rjs 	   ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){
   2400   1.1       rjs 		if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) {
   2401   1.1       rjs 			stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
   2402   1.1       rjs 		}
   2403   1.1       rjs 	} else {
   2404   1.1       rjs 		stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
   2405   1.1       rjs 	}
   2406   1.1       rjs 	SCTP_INP_WUNLOCK(stcb->sctp_ep);
   2407   1.1       rjs 	sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
   2408   1.1       rjs }
   2409   1.1       rjs 
   2410   1.1       rjs static void
   2411   1.1       rjs sctp_notify_stream_reset(struct sctp_tcb *stcb,
   2412   1.1       rjs     int number_entries, uint16_t *list, int flag)
   2413   1.1       rjs {
   2414   1.1       rjs 	struct mbuf *m_notify;
   2415   1.1       rjs 	struct sctp_stream_reset_event *strreset;
   2416   1.1       rjs 	struct sockaddr_in6 sin6, lsa6;
   2417   1.1       rjs 	const struct sockaddr *to;
   2418   1.1       rjs 	int len;
   2419   1.1       rjs 
   2420   1.1       rjs 	if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_STREAM_RESETEVNT))
   2421   1.1       rjs 		/* event not enabled */
   2422   1.1       rjs 		return;
   2423   1.1       rjs 
   2424   1.1       rjs 	MGETHDR(m_notify, M_DONTWAIT, MT_DATA);
   2425   1.1       rjs 	if (m_notify == NULL)
   2426   1.1       rjs 		/* no space left */
   2427   1.1       rjs 		return;
   2428   1.1       rjs 	m_notify->m_len = 0;
   2429   1.1       rjs 	len = sizeof(struct sctp_stream_reset_event) + (number_entries * sizeof(uint16_t));
   2430   1.1       rjs 	if (len > M_TRAILINGSPACE(m_notify)) {
   2431   1.1       rjs 		MCLGET(m_notify, M_WAIT);
   2432   1.1       rjs 	}
   2433   1.1       rjs 	if (m_notify == NULL)
   2434   1.1       rjs 		/* no clusters */
   2435   1.1       rjs 		return;
   2436   1.1       rjs 
   2437   1.1       rjs 	if (len > M_TRAILINGSPACE(m_notify)) {
   2438   1.1       rjs 		/* never enough room */
   2439   1.1       rjs 		m_freem(m_notify);
   2440   1.1       rjs 		return;
   2441   1.1       rjs 	}
   2442   1.1       rjs 	strreset = mtod(m_notify, struct sctp_stream_reset_event *);
   2443   1.1       rjs 	strreset->strreset_type = SCTP_STREAM_RESET_EVENT;
   2444   1.1       rjs 	if (number_entries == 0) {
   2445   1.1       rjs 		strreset->strreset_flags = flag | SCTP_STRRESET_ALL_STREAMS;
   2446   1.1       rjs 	} else {
   2447   1.1       rjs 		strreset->strreset_flags = flag | SCTP_STRRESET_STREAM_LIST;
   2448   1.1       rjs 	}
   2449   1.1       rjs 	strreset->strreset_length = len;
   2450   1.1       rjs 	strreset->strreset_assoc_id = sctp_get_associd(stcb);
   2451   1.1       rjs 	if (number_entries) {
   2452   1.1       rjs 		int i;
   2453   1.1       rjs 		for (i=0; i<number_entries; i++) {
   2454   1.1       rjs 			strreset->strreset_list[i] = list[i];
   2455   1.1       rjs 		}
   2456   1.1       rjs 	}
   2457   1.1       rjs 	m_notify->m_flags |= M_EOR | M_NOTIFICATION;
   2458   1.1       rjs 	m_notify->m_pkthdr.len = len;
   2459   1.9     ozaki 	m_reset_rcvif(m_notify);
   2460   1.1       rjs 	m_notify->m_len = len;
   2461   1.1       rjs 	m_notify->m_next = NULL;
   2462   1.1       rjs 	if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) {
   2463   1.1       rjs 		/* no space */
   2464   1.1       rjs 		sctp_m_freem(m_notify);
   2465   1.1       rjs 		return;
   2466   1.1       rjs 	}
   2467   1.1       rjs 	to = rtcache_getdst(&stcb->asoc.primary_destination->ro);
   2468   1.1       rjs 	if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
   2469   1.1       rjs 	    to->sa_family == AF_INET) {
   2470   1.1       rjs 		const struct sockaddr_in *sin;
   2471   1.1       rjs 
   2472   1.1       rjs 		sin = satocsin(to);
   2473   1.2       rtr 		in6_sin_2_v4mapsin6(sin, &sin6);
   2474   1.1       rjs 		to = (struct sockaddr *)&sin6;
   2475   1.1       rjs 	}
   2476   1.1       rjs 	/* check and strip embedded scope junk */
   2477   1.1       rjs 	to = (const struct sockaddr *) sctp_recover_scope((const struct sockaddr_in6 *)to,
   2478   1.1       rjs 	    &lsa6);
   2479   1.1       rjs 	/* append to socket */
   2480   1.1       rjs 	SCTP_TCB_UNLOCK(stcb);
   2481   1.1       rjs 	SCTP_INP_WLOCK(stcb->sctp_ep);
   2482   1.1       rjs 	SCTP_TCB_LOCK(stcb);
   2483   1.1       rjs 	if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv, to,
   2484   1.1       rjs 	    m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) {
   2485   1.1       rjs 		/* not enough room */
   2486   1.1       rjs 		sctp_m_freem(m_notify);
   2487   1.1       rjs 		SCTP_INP_WUNLOCK(stcb->sctp_ep);
   2488   1.1       rjs 		return;
   2489   1.1       rjs 	}
   2490   1.1       rjs 	if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) &&
   2491   1.1       rjs 	   ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){
   2492   1.1       rjs 		if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) {
   2493   1.1       rjs 			stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
   2494   1.1       rjs 		}
   2495   1.1       rjs 	} else {
   2496   1.1       rjs 		stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
   2497   1.1       rjs 	}
   2498   1.1       rjs 	SCTP_INP_WUNLOCK(stcb->sctp_ep);
   2499   1.1       rjs 	sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
   2500   1.1       rjs }
   2501   1.1       rjs 
   2502   1.1       rjs 
   2503   1.1       rjs void
   2504   1.1       rjs sctp_ulp_notify(u_int32_t notification, struct sctp_tcb *stcb,
   2505   1.1       rjs 		u_int32_t error, void *data)
   2506   1.1       rjs {
   2507   1.1       rjs 	if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
   2508   1.1       rjs 		/* No notifications up when we are in a no socket state */
   2509   1.1       rjs 		return;
   2510   1.1       rjs 	}
   2511   1.1       rjs 	if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
   2512   1.1       rjs 		/* Can't send up to a closed socket any notifications */
   2513   1.1       rjs 		return;
   2514   1.1       rjs 	}
   2515   1.1       rjs 	switch (notification) {
   2516   1.1       rjs 	case SCTP_NOTIFY_ASSOC_UP:
   2517   1.1       rjs 		sctp_notify_assoc_change(SCTP_COMM_UP, stcb, error);
   2518   1.1       rjs 		break;
   2519   1.1       rjs 	case SCTP_NOTIFY_ASSOC_DOWN:
   2520   1.1       rjs 		sctp_notify_assoc_change(SCTP_SHUTDOWN_COMP, stcb, error);
   2521   1.1       rjs 		break;
   2522   1.1       rjs 	case SCTP_NOTIFY_INTERFACE_DOWN:
   2523   1.1       rjs 	{
   2524   1.1       rjs 		struct sctp_nets *net;
   2525   1.1       rjs 		net = (struct sctp_nets *)data;
   2526   1.1       rjs 		sctp_notify_peer_addr_change(stcb, SCTP_ADDR_UNREACHABLE,
   2527   1.1       rjs 		    rtcache_getdst(&net->ro), error);
   2528   1.1       rjs 		break;
   2529   1.1       rjs 	}
   2530   1.1       rjs 	case SCTP_NOTIFY_INTERFACE_UP:
   2531   1.1       rjs 	{
   2532   1.1       rjs 		struct sctp_nets *net;
   2533   1.1       rjs 		net = (struct sctp_nets *)data;
   2534   1.1       rjs 		sctp_notify_peer_addr_change(stcb, SCTP_ADDR_AVAILABLE,
   2535   1.1       rjs 		    rtcache_getdst(&net->ro), error);
   2536   1.1       rjs 		break;
   2537   1.1       rjs 	}
   2538   1.1       rjs 	case SCTP_NOTIFY_INTERFACE_CONFIRMED:
   2539   1.1       rjs 	{
   2540   1.1       rjs 		struct sctp_nets *net;
   2541   1.1       rjs 		net = (struct sctp_nets *)data;
   2542   1.1       rjs 		sctp_notify_peer_addr_change(stcb, SCTP_ADDR_CONFIRMED,
   2543   1.1       rjs 		    rtcache_getdst(&net->ro), error);
   2544   1.1       rjs 		break;
   2545   1.1       rjs 	}
   2546   1.1       rjs 	case SCTP_NOTIFY_DG_FAIL:
   2547   1.1       rjs 		sctp_notify_send_failed(stcb, error,
   2548   1.1       rjs 		    (struct sctp_tmit_chunk *)data);
   2549   1.1       rjs 		break;
   2550   1.1       rjs 	case SCTP_NOTIFY_ADAPTION_INDICATION:
   2551   1.1       rjs 		/* Here the error is the adaption indication */
   2552   1.1       rjs 		sctp_notify_adaption_layer(stcb, error);
   2553   1.1       rjs 		break;
   2554   1.1       rjs 	case SCTP_NOTIFY_PARTIAL_DELVIERY_INDICATION:
   2555   1.1       rjs 		sctp_notify_partial_delivery_indication(stcb, error);
   2556   1.1       rjs 		break;
   2557   1.1       rjs 	case SCTP_NOTIFY_STRDATA_ERR:
   2558   1.1       rjs 		break;
   2559   1.1       rjs 	case SCTP_NOTIFY_ASSOC_ABORTED:
   2560   1.1       rjs 		sctp_notify_assoc_change(SCTP_COMM_LOST, stcb, error);
   2561   1.1       rjs 		break;
   2562   1.1       rjs 	case SCTP_NOTIFY_PEER_OPENED_STREAM:
   2563   1.1       rjs 		break;
   2564   1.1       rjs 	case SCTP_NOTIFY_STREAM_OPENED_OK:
   2565   1.1       rjs 		break;
   2566   1.1       rjs 	case SCTP_NOTIFY_ASSOC_RESTART:
   2567   1.1       rjs 		sctp_notify_assoc_change(SCTP_RESTART, stcb, error);
   2568   1.1       rjs 		break;
   2569   1.1       rjs 	case SCTP_NOTIFY_HB_RESP:
   2570   1.1       rjs 		break;
   2571   1.1       rjs 	case SCTP_NOTIFY_STR_RESET_SEND:
   2572   1.1       rjs 		sctp_notify_stream_reset(stcb, error, ((uint16_t *)data), SCTP_STRRESET_OUTBOUND_STR);
   2573   1.1       rjs 		break;
   2574   1.1       rjs 	case SCTP_NOTIFY_STR_RESET_RECV:
   2575   1.1       rjs 		sctp_notify_stream_reset(stcb, error, ((uint16_t *)data), SCTP_STRRESET_INBOUND_STR);
   2576   1.1       rjs 		break;
   2577   1.1       rjs 	case SCTP_NOTIFY_ASCONF_ADD_IP:
   2578   1.1       rjs 		sctp_notify_peer_addr_change(stcb, SCTP_ADDR_ADDED, data,
   2579   1.1       rjs 		    error);
   2580   1.1       rjs 		break;
   2581   1.1       rjs 	case SCTP_NOTIFY_ASCONF_DELETE_IP:
   2582   1.1       rjs 		sctp_notify_peer_addr_change(stcb, SCTP_ADDR_REMOVED, data,
   2583   1.1       rjs 		    error);
   2584   1.1       rjs 		break;
   2585   1.1       rjs 	case SCTP_NOTIFY_ASCONF_SET_PRIMARY:
   2586   1.1       rjs 		sctp_notify_peer_addr_change(stcb, SCTP_ADDR_MADE_PRIM, data,
   2587   1.1       rjs 		    error);
   2588   1.1       rjs 		break;
   2589   1.1       rjs 	case SCTP_NOTIFY_ASCONF_SUCCESS:
   2590   1.1       rjs 		break;
   2591   1.1       rjs 	case SCTP_NOTIFY_ASCONF_FAILED:
   2592   1.1       rjs 		break;
   2593   1.1       rjs 	case SCTP_NOTIFY_PEER_SHUTDOWN:
   2594   1.1       rjs 		sctp_notify_shutdown_event(stcb);
   2595   1.1       rjs 		break;
   2596   1.1       rjs 	default:
   2597   1.1       rjs #ifdef SCTP_DEBUG
   2598   1.1       rjs 		if (sctp_debug_on & SCTP_DEBUG_UTIL1) {
   2599   1.1       rjs 			printf("NOTIFY: unknown notification %xh (%u)\n",
   2600   1.1       rjs 			    notification, notification);
   2601   1.1       rjs 		}
   2602   1.1       rjs #endif /* SCTP_DEBUG */
   2603   1.1       rjs 		break;
   2604   1.1       rjs 	} /* end switch */
   2605   1.1       rjs }
   2606   1.1       rjs 
   2607   1.1       rjs void
   2608   1.1       rjs sctp_report_all_outbound(struct sctp_tcb *stcb)
   2609   1.1       rjs {
   2610   1.1       rjs 	struct sctp_association *asoc;
   2611   1.1       rjs 	struct sctp_stream_out *outs;
   2612   1.1       rjs 	struct sctp_tmit_chunk *chk;
   2613   1.1       rjs 
   2614   1.1       rjs 	asoc = &stcb->asoc;
   2615   1.1       rjs 
   2616   1.1       rjs 	if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
   2617   1.1       rjs 		return;
   2618   1.1       rjs 	}
   2619   1.1       rjs 	/* now through all the gunk freeing chunks */
   2620   1.1       rjs 	TAILQ_FOREACH(outs, &asoc->out_wheel, next_spoke) {
   2621   1.1       rjs 		/* now clean up any chunks here */
   2622   1.1       rjs 		chk = TAILQ_FIRST(&outs->outqueue);
   2623   1.1       rjs 		while (chk) {
   2624   1.1       rjs 			stcb->asoc.stream_queue_cnt--;
   2625   1.1       rjs 			TAILQ_REMOVE(&outs->outqueue, chk, sctp_next);
   2626   1.1       rjs 			sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb,
   2627   1.1       rjs 			    SCTP_NOTIFY_DATAGRAM_UNSENT, chk);
   2628   1.1       rjs 			if (chk->data) {
   2629   1.1       rjs 				sctp_m_freem(chk->data);
   2630   1.1       rjs 				chk->data = NULL;
   2631   1.1       rjs 			}
   2632   1.1       rjs 			if (chk->whoTo)
   2633   1.1       rjs 				sctp_free_remote_addr(chk->whoTo);
   2634   1.1       rjs 			chk->whoTo = NULL;
   2635   1.1       rjs 			chk->asoc = NULL;
   2636   1.1       rjs 			/* Free the chunk */
   2637   1.1       rjs 			SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_chunk, chk);
   2638   1.1       rjs 			sctppcbinfo.ipi_count_chunk--;
   2639   1.1       rjs 			if ((int)sctppcbinfo.ipi_count_chunk < 0) {
   2640   1.1       rjs 				panic("Chunk count is negative");
   2641   1.1       rjs 			}
   2642   1.1       rjs 			sctppcbinfo.ipi_gencnt_chunk++;
   2643   1.1       rjs 			chk = TAILQ_FIRST(&outs->outqueue);
   2644   1.1       rjs 		}
   2645   1.1       rjs 	}
   2646   1.1       rjs 	/* pending send queue SHOULD be empty */
   2647   1.1       rjs 	if (!TAILQ_EMPTY(&asoc->send_queue)) {
   2648   1.1       rjs 		chk = TAILQ_FIRST(&asoc->send_queue);
   2649   1.1       rjs 		while (chk) {
   2650   1.1       rjs 			TAILQ_REMOVE(&asoc->send_queue, chk, sctp_next);
   2651   1.1       rjs 			sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb, SCTP_NOTIFY_DATAGRAM_UNSENT, chk);
   2652   1.1       rjs 			if (chk->data) {
   2653   1.1       rjs 				sctp_m_freem(chk->data);
   2654   1.1       rjs 				chk->data = NULL;
   2655   1.1       rjs 			}
   2656   1.1       rjs 			if (chk->whoTo)
   2657   1.1       rjs 				sctp_free_remote_addr(chk->whoTo);
   2658   1.1       rjs 			chk->whoTo = NULL;
   2659   1.1       rjs 			SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_chunk, chk);
   2660   1.1       rjs 			sctppcbinfo.ipi_count_chunk--;
   2661   1.1       rjs 			if ((int)sctppcbinfo.ipi_count_chunk < 0) {
   2662   1.1       rjs 				panic("Chunk count is negative");
   2663   1.1       rjs 			}
   2664   1.1       rjs 			sctppcbinfo.ipi_gencnt_chunk++;
   2665   1.1       rjs 			chk = TAILQ_FIRST(&asoc->send_queue);
   2666   1.1       rjs 		}
   2667   1.1       rjs 	}
   2668   1.1       rjs 	/* sent queue SHOULD be empty */
   2669   1.1       rjs 	if (!TAILQ_EMPTY(&asoc->sent_queue)) {
   2670   1.1       rjs 		chk = TAILQ_FIRST(&asoc->sent_queue);
   2671   1.1       rjs 		while (chk) {
   2672   1.1       rjs 			TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next);
   2673   1.1       rjs 			sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb,
   2674   1.1       rjs 			    SCTP_NOTIFY_DATAGRAM_SENT, chk);
   2675   1.1       rjs 			if (chk->data) {
   2676   1.1       rjs 				sctp_m_freem(chk->data);
   2677   1.1       rjs 				chk->data = NULL;
   2678   1.1       rjs 			}
   2679   1.1       rjs 			if (chk->whoTo)
   2680   1.1       rjs 				sctp_free_remote_addr(chk->whoTo);
   2681   1.1       rjs 			chk->whoTo = NULL;
   2682   1.1       rjs 			SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_chunk, chk);
   2683   1.1       rjs 			sctppcbinfo.ipi_count_chunk--;
   2684   1.1       rjs 			if ((int)sctppcbinfo.ipi_count_chunk < 0) {
   2685   1.1       rjs 				panic("Chunk count is negative");
   2686   1.1       rjs 			}
   2687   1.1       rjs 			sctppcbinfo.ipi_gencnt_chunk++;
   2688   1.1       rjs 			chk = TAILQ_FIRST(&asoc->sent_queue);
   2689   1.1       rjs 		}
   2690   1.1       rjs 	}
   2691   1.1       rjs }
   2692   1.1       rjs 
   2693   1.1       rjs void
   2694   1.1       rjs sctp_abort_notification(struct sctp_tcb *stcb, int error)
   2695   1.1       rjs {
   2696   1.1       rjs 
   2697   1.1       rjs 	if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
   2698   1.1       rjs 		return;
   2699   1.1       rjs 	}
   2700   1.1       rjs 	/* Tell them we lost the asoc */
   2701   1.1       rjs 	sctp_report_all_outbound(stcb);
   2702   1.1       rjs 	sctp_ulp_notify(SCTP_NOTIFY_ASSOC_ABORTED, stcb, error, NULL);
   2703   1.1       rjs }
   2704   1.1       rjs 
   2705   1.1       rjs void
   2706   1.1       rjs sctp_abort_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
   2707   1.1       rjs     struct mbuf *m, int iphlen, struct sctphdr *sh, struct mbuf *op_err)
   2708   1.1       rjs {
   2709   1.1       rjs 	u_int32_t vtag;
   2710   1.1       rjs 
   2711   1.1       rjs 	vtag = 0;
   2712   1.1       rjs 	if (stcb != NULL) {
   2713   1.1       rjs 		/* We have a TCB to abort, send notification too */
   2714   1.1       rjs 		vtag = stcb->asoc.peer_vtag;
   2715   1.1       rjs 		sctp_abort_notification(stcb, 0);
   2716   1.1       rjs 	}
   2717   1.1       rjs 	sctp_send_abort(m, iphlen, sh, vtag, op_err);
   2718   1.1       rjs 	if (stcb != NULL) {
   2719   1.1       rjs 		/* Ok, now lets free it */
   2720   1.1       rjs 		sctp_free_assoc(inp, stcb);
   2721   1.1       rjs 	} else {
   2722   1.1       rjs 		if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
   2723   1.1       rjs 			if (LIST_FIRST(&inp->sctp_asoc_list) == NULL) {
   2724   1.1       rjs 				sctp_inpcb_free(inp, 1);
   2725   1.1       rjs 			}
   2726   1.1       rjs 		}
   2727   1.1       rjs 	}
   2728   1.1       rjs }
   2729   1.1       rjs 
   2730   1.1       rjs void
   2731   1.1       rjs sctp_abort_an_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
   2732   1.1       rjs     int error, struct mbuf *op_err)
   2733   1.1       rjs {
   2734   1.1       rjs 
   2735   1.1       rjs 	if (stcb == NULL) {
   2736   1.1       rjs 		/* Got to have a TCB */
   2737   1.1       rjs 		if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
   2738   1.1       rjs 			if (LIST_FIRST(&inp->sctp_asoc_list) == NULL) {
   2739   1.1       rjs 				sctp_inpcb_free(inp, 1);
   2740   1.1       rjs 			}
   2741   1.1       rjs 		}
   2742   1.1       rjs 		return;
   2743   1.1       rjs 	}
   2744   1.1       rjs 	/* notify the ulp */
   2745   1.1       rjs 	if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0)
   2746   1.1       rjs 		sctp_abort_notification(stcb, error);
   2747   1.1       rjs 	/* notify the peer */
   2748   1.1       rjs 	sctp_send_abort_tcb(stcb, op_err);
   2749   1.1       rjs 	/* now free the asoc */
   2750   1.1       rjs 	sctp_free_assoc(inp, stcb);
   2751   1.1       rjs }
   2752   1.1       rjs 
   2753   1.1       rjs void
   2754   1.1       rjs sctp_handle_ootb(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
   2755   1.1       rjs     struct sctp_inpcb *inp, struct mbuf *op_err)
   2756   1.1       rjs {
   2757   1.1       rjs 	struct sctp_chunkhdr *ch, chunk_buf;
   2758   1.1       rjs 	unsigned int chk_length;
   2759   1.1       rjs 
   2760   1.1       rjs 	/* Generate a TO address for future reference */
   2761   1.1       rjs 	if (inp && (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) {
   2762   1.1       rjs 		if (LIST_FIRST(&inp->sctp_asoc_list) == NULL) {
   2763   1.1       rjs 			sctp_inpcb_free(inp, 1);
   2764   1.1       rjs 		}
   2765   1.1       rjs 	}
   2766   1.1       rjs 	ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset,
   2767   1.1       rjs 	    sizeof(*ch), (u_int8_t *)&chunk_buf);
   2768   1.1       rjs 	while (ch != NULL) {
   2769   1.1       rjs 		chk_length = ntohs(ch->chunk_length);
   2770   1.1       rjs 		if (chk_length < sizeof(*ch)) {
   2771   1.1       rjs 			/* break to abort land */
   2772   1.1       rjs 			break;
   2773   1.1       rjs 		}
   2774   1.1       rjs 		switch (ch->chunk_type) {
   2775   1.1       rjs 		case SCTP_PACKET_DROPPED:
   2776   1.1       rjs 			/* we don't respond to pkt-dropped */
   2777   1.1       rjs 			return;
   2778   1.1       rjs 		case SCTP_ABORT_ASSOCIATION:
   2779   1.1       rjs 			/* we don't respond with an ABORT to an ABORT */
   2780   1.1       rjs 			return;
   2781   1.1       rjs 		case SCTP_SHUTDOWN_COMPLETE:
   2782   1.1       rjs 			/*
   2783   1.1       rjs 			 * we ignore it since we are not waiting for it
   2784   1.1       rjs 			 * and peer is gone
   2785   1.1       rjs 			 */
   2786   1.1       rjs 			return;
   2787   1.1       rjs 		case SCTP_SHUTDOWN_ACK:
   2788   1.1       rjs 			sctp_send_shutdown_complete2(m, iphlen, sh);
   2789   1.1       rjs 			return;
   2790   1.1       rjs 		default:
   2791   1.1       rjs 			break;
   2792   1.1       rjs 		}
   2793   1.1       rjs 		offset += SCTP_SIZE32(chk_length);
   2794   1.1       rjs 		ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset,
   2795   1.1       rjs 		    sizeof(*ch), (u_int8_t *)&chunk_buf);
   2796   1.1       rjs 	}
   2797   1.1       rjs 	sctp_send_abort(m, iphlen, sh, 0, op_err);
   2798   1.1       rjs }
   2799   1.1       rjs 
   2800   1.1       rjs /*
   2801   1.1       rjs  * check the inbound datagram to make sure there is not an abort
   2802   1.1       rjs  * inside it, if there is return 1, else return 0.
   2803   1.1       rjs  */
   2804   1.1       rjs int
   2805   1.1       rjs sctp_is_there_an_abort_here(struct mbuf *m, int iphlen, int *vtagfill)
   2806   1.1       rjs {
   2807   1.1       rjs 	struct sctp_chunkhdr *ch;
   2808   1.1       rjs 	struct sctp_init_chunk *init_chk, chunk_buf;
   2809   1.1       rjs 	int offset;
   2810   1.1       rjs 	unsigned int chk_length;
   2811   1.1       rjs 
   2812   1.1       rjs 	offset = iphlen + sizeof(struct sctphdr);
   2813   1.1       rjs 	ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset, sizeof(*ch),
   2814   1.1       rjs 	    (u_int8_t *)&chunk_buf);
   2815   1.1       rjs 	while (ch != NULL) {
   2816   1.1       rjs 		chk_length = ntohs(ch->chunk_length);
   2817   1.1       rjs 		if (chk_length < sizeof(*ch)) {
   2818   1.1       rjs 			/* packet is probably corrupt */
   2819   1.1       rjs 			break;
   2820   1.1       rjs 		}
   2821   1.1       rjs 		/* we seem to be ok, is it an abort? */
   2822   1.1       rjs 		if (ch->chunk_type == SCTP_ABORT_ASSOCIATION) {
   2823   1.1       rjs 			/* yep, tell them */
   2824   1.1       rjs 			return (1);
   2825   1.1       rjs 		}
   2826   1.1       rjs 		if (ch->chunk_type == SCTP_INITIATION) {
   2827   1.1       rjs 			/* need to update the Vtag */
   2828   1.1       rjs 			init_chk = (struct sctp_init_chunk *)sctp_m_getptr(m,
   2829   1.1       rjs 			    offset, sizeof(*init_chk), (u_int8_t *)&chunk_buf);
   2830   1.1       rjs 			if (init_chk != NULL) {
   2831   1.1       rjs 				*vtagfill = ntohl(init_chk->init.initiate_tag);
   2832   1.1       rjs 			}
   2833   1.1       rjs 		}
   2834   1.1       rjs 		/* Nope, move to the next chunk */
   2835   1.1       rjs 		offset += SCTP_SIZE32(chk_length);
   2836   1.1       rjs 		ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset,
   2837   1.1       rjs 		    sizeof(*ch), (u_int8_t *)&chunk_buf);
   2838   1.1       rjs 	}
   2839   1.1       rjs 	return (0);
   2840   1.1       rjs }
   2841   1.1       rjs 
   2842   1.1       rjs /*
   2843   1.1       rjs  * currently (2/02), ifa_addr embeds scope_id's and don't
   2844   1.1       rjs  * have sin6_scope_id set (i.e. it's 0)
   2845   1.1       rjs  * so, create this function to compare link local scopes
   2846   1.1       rjs  */
   2847   1.1       rjs uint32_t
   2848   1.8       rjs sctp_is_same_scope(const struct sockaddr_in6 *addr1, const struct sockaddr_in6 *addr2)
   2849   1.1       rjs {
   2850   1.1       rjs 	struct sockaddr_in6 a, b;
   2851   1.1       rjs 
   2852   1.1       rjs 	/* save copies */
   2853   1.1       rjs 	a = *addr1;
   2854   1.1       rjs 	b = *addr2;
   2855   1.1       rjs 
   2856   1.1       rjs 	if (a.sin6_scope_id == 0)
   2857   1.1       rjs 		if (sa6_recoverscope(&a)) {
   2858   1.1       rjs 			/* can't get scope, so can't match */
   2859   1.1       rjs 			return (0);
   2860   1.1       rjs 		}
   2861   1.1       rjs 	if (b.sin6_scope_id == 0)
   2862   1.1       rjs 		if (sa6_recoverscope(&b)) {
   2863   1.1       rjs 			/* can't get scope, so can't match */
   2864   1.1       rjs 			return (0);
   2865   1.1       rjs 		}
   2866   1.1       rjs 	if (a.sin6_scope_id != b.sin6_scope_id)
   2867   1.1       rjs 		return (0);
   2868   1.1       rjs 
   2869   1.1       rjs 	return (1);
   2870   1.1       rjs }
   2871   1.1       rjs 
   2872   1.1       rjs /*
   2873   1.1       rjs  * returns a sockaddr_in6 with embedded scope recovered and removed
   2874   1.1       rjs  */
   2875   1.1       rjs const struct sockaddr_in6 *
   2876   1.1       rjs sctp_recover_scope(const struct sockaddr_in6 *addr, struct sockaddr_in6 *store)
   2877   1.1       rjs {
   2878   1.1       rjs 	const struct sockaddr_in6 *newaddr;
   2879   1.1       rjs 
   2880   1.1       rjs 	newaddr = addr;
   2881   1.1       rjs 	/* check and strip embedded scope junk */
   2882   1.1       rjs 	if (addr->sin6_family == AF_INET6) {
   2883   1.1       rjs 		if (IN6_IS_SCOPE_LINKLOCAL(&addr->sin6_addr)) {
   2884   1.1       rjs 			if (addr->sin6_scope_id == 0) {
   2885   1.1       rjs 				*store = *addr;
   2886   1.1       rjs 				if (sa6_recoverscope(store) == 0) {
   2887   1.1       rjs 					/* use the recovered scope */
   2888   1.1       rjs 					newaddr = store;
   2889   1.1       rjs 				}
   2890   1.1       rjs 				/* else, return the original "to" addr */
   2891   1.1       rjs 			}
   2892   1.1       rjs 		}
   2893   1.1       rjs 	}
   2894   1.1       rjs 	return (newaddr);
   2895   1.1       rjs }
   2896   1.1       rjs 
   2897   1.1       rjs /*
   2898   1.1       rjs  * are the two addresses the same?  currently a "scopeless" check
   2899   1.1       rjs  * returns: 1 if same, 0 if not
   2900   1.1       rjs  */
   2901   1.1       rjs int
   2902   1.1       rjs sctp_cmpaddr(const struct sockaddr *sa1, const struct sockaddr *sa2)
   2903   1.1       rjs {
   2904   1.1       rjs 
   2905   1.1       rjs 	/* must be valid */
   2906   1.1       rjs 	if (sa1 == NULL || sa2 == NULL)
   2907   1.1       rjs 		return (0);
   2908   1.1       rjs 
   2909   1.1       rjs 	/* must be the same family */
   2910   1.1       rjs 	if (sa1->sa_family != sa2->sa_family)
   2911   1.1       rjs 		return (0);
   2912   1.1       rjs 
   2913   1.1       rjs 	if (sa1->sa_family == AF_INET6) {
   2914   1.1       rjs 		/* IPv6 addresses */
   2915   1.1       rjs 		const struct sockaddr_in6 *sin6_1, *sin6_2;
   2916   1.1       rjs 
   2917   1.1       rjs 		sin6_1 = (const struct sockaddr_in6 *)sa1;
   2918   1.1       rjs 		sin6_2 = (const struct sockaddr_in6 *)sa2;
   2919   1.1       rjs 		return (SCTP6_ARE_ADDR_EQUAL(&sin6_1->sin6_addr,
   2920   1.1       rjs 		    &sin6_2->sin6_addr));
   2921   1.1       rjs 	} else if (sa1->sa_family == AF_INET) {
   2922   1.1       rjs 		/* IPv4 addresses */
   2923   1.1       rjs 		const struct sockaddr_in *sin_1, *sin_2;
   2924   1.1       rjs 
   2925   1.1       rjs 		sin_1 = (const struct sockaddr_in *)sa1;
   2926   1.1       rjs 		sin_2 = (const struct sockaddr_in *)sa2;
   2927   1.1       rjs 		return (sin_1->sin_addr.s_addr == sin_2->sin_addr.s_addr);
   2928   1.1       rjs 	} else {
   2929   1.1       rjs 		/* we don't do these... */
   2930   1.1       rjs 		return (0);
   2931   1.1       rjs 	}
   2932   1.1       rjs }
   2933   1.1       rjs 
   2934   1.1       rjs void
   2935   1.1       rjs sctp_print_address(const struct sockaddr *sa)
   2936   1.1       rjs {
   2937  1.11       ryo 	char ip6buf[INET6_ADDRSTRLEN];
   2938   1.1       rjs 
   2939   1.1       rjs 	if (sa->sa_family == AF_INET6) {
   2940   1.1       rjs 		const struct sockaddr_in6 *sin6;
   2941   1.1       rjs 		sin6 = (const struct sockaddr_in6 *)sa;
   2942   1.1       rjs 		printf("IPv6 address: %s:%d scope:%u\n",
   2943  1.12  christos 		    IN6_PRINT(ip6buf, &sin6->sin6_addr), ntohs(sin6->sin6_port),
   2944   1.1       rjs 		    sin6->sin6_scope_id);
   2945   1.1       rjs 	} else if (sa->sa_family == AF_INET) {
   2946   1.1       rjs 		const struct sockaddr_in *sin;
   2947   1.1       rjs 		sin = (const struct sockaddr_in *)sa;
   2948   1.1       rjs 		printf("IPv4 address: %s:%d\n", inet_ntoa(sin->sin_addr),
   2949   1.1       rjs 		    ntohs(sin->sin_port));
   2950   1.1       rjs 	} else {
   2951   1.1       rjs 		printf("?\n");
   2952   1.1       rjs 	}
   2953   1.1       rjs }
   2954   1.1       rjs 
   2955   1.1       rjs void
   2956   1.1       rjs sctp_print_address_pkt(struct ip *iph, struct sctphdr *sh)
   2957   1.1       rjs {
   2958   1.1       rjs 	if (iph->ip_v == IPVERSION) {
   2959   1.1       rjs 		struct sockaddr_in lsa, fsa;
   2960   1.1       rjs 
   2961   1.1       rjs 		memset(&lsa, 0, sizeof(lsa));
   2962   1.1       rjs 		lsa.sin_len = sizeof(lsa);
   2963   1.1       rjs 		lsa.sin_family = AF_INET;
   2964   1.1       rjs 		lsa.sin_addr = iph->ip_src;
   2965   1.1       rjs 		lsa.sin_port = sh->src_port;
   2966   1.1       rjs 		memset(&fsa, 0, sizeof(fsa));
   2967   1.1       rjs 		fsa.sin_len = sizeof(fsa);
   2968   1.1       rjs 		fsa.sin_family = AF_INET;
   2969   1.1       rjs 		fsa.sin_addr = iph->ip_dst;
   2970   1.1       rjs 		fsa.sin_port = sh->dest_port;
   2971   1.1       rjs 		printf("src: ");
   2972   1.1       rjs 		sctp_print_address((struct sockaddr *)&lsa);
   2973   1.1       rjs 		printf("dest: ");
   2974   1.1       rjs 		sctp_print_address((struct sockaddr *)&fsa);
   2975   1.1       rjs 	} else if (iph->ip_v == (IPV6_VERSION >> 4)) {
   2976   1.1       rjs 		struct ip6_hdr *ip6;
   2977   1.1       rjs 		struct sockaddr_in6 lsa6, fsa6;
   2978   1.1       rjs 
   2979   1.1       rjs 		ip6 = (struct ip6_hdr *)iph;
   2980   1.1       rjs 		memset(&lsa6, 0, sizeof(lsa6));
   2981   1.1       rjs 		lsa6.sin6_len = sizeof(lsa6);
   2982   1.1       rjs 		lsa6.sin6_family = AF_INET6;
   2983   1.1       rjs 		lsa6.sin6_addr = ip6->ip6_src;
   2984   1.1       rjs 		lsa6.sin6_port = sh->src_port;
   2985   1.1       rjs 		memset(&fsa6, 0, sizeof(fsa6));
   2986   1.1       rjs 		fsa6.sin6_len = sizeof(fsa6);
   2987   1.1       rjs 		fsa6.sin6_family = AF_INET6;
   2988   1.1       rjs 		fsa6.sin6_addr = ip6->ip6_dst;
   2989   1.1       rjs 		fsa6.sin6_port = sh->dest_port;
   2990   1.1       rjs 		printf("src: ");
   2991   1.1       rjs 		sctp_print_address((struct sockaddr *)&lsa6);
   2992   1.1       rjs 		printf("dest: ");
   2993   1.1       rjs 		sctp_print_address((struct sockaddr *)&fsa6);
   2994   1.1       rjs 	}
   2995   1.1       rjs }
   2996   1.1       rjs 
   2997   1.1       rjs #if defined(__FreeBSD__) || defined(__APPLE__)
   2998   1.1       rjs 
   2999   1.1       rjs /* cloned from uipc_socket.c */
   3000   1.1       rjs 
   3001   1.1       rjs #define SCTP_SBLINKRECORD(sb, m0) do {					\
   3002   1.1       rjs 	if ((sb)->sb_lastrecord != NULL)				\
   3003   1.1       rjs 		(sb)->sb_lastrecord->m_nextpkt = (m0);			\
   3004   1.1       rjs 	else								\
   3005   1.1       rjs 		(sb)->sb_mb = (m0);					\
   3006   1.1       rjs 	(sb)->sb_lastrecord = (m0);					\
   3007   1.1       rjs } while (/*CONSTCOND*/0)
   3008   1.1       rjs #endif
   3009   1.1       rjs 
   3010   1.1       rjs 
   3011   1.1       rjs int
   3012   1.1       rjs sbappendaddr_nocheck(struct sockbuf *sb, const struct sockaddr *asa,
   3013   1.1       rjs 	struct mbuf *m0, struct mbuf *control,
   3014   1.1       rjs 	u_int32_t tag, struct sctp_inpcb *inp)
   3015   1.1       rjs {
   3016   1.1       rjs #ifdef __NetBSD__
   3017   1.1       rjs 	struct mbuf *m, *n;
   3018   1.1       rjs 
   3019   1.1       rjs 	if (m0 && (m0->m_flags & M_PKTHDR) == 0)
   3020   1.1       rjs 		panic("sbappendaddr_nocheck");
   3021   1.1       rjs 
   3022   1.1       rjs 	m0->m_pkthdr.csum_data = (int)tag;
   3023   1.1       rjs 
   3024   1.1       rjs 	for (n = control; n; n = n->m_next) {
   3025   1.1       rjs 		if (n->m_next == 0)	/* keep pointer to last control buf */
   3026   1.1       rjs 			break;
   3027   1.1       rjs 	}
   3028   1.1       rjs 	if (((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) == 0) ||
   3029   1.1       rjs 	    ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)== 0)) {
   3030   1.1       rjs 		MGETHDR(m, M_DONTWAIT, MT_SONAME);
   3031   1.1       rjs 		if (m == 0)
   3032   1.1       rjs 			return (0);
   3033   1.1       rjs 
   3034   1.1       rjs 		m->m_len = asa->sa_len;
   3035   1.1       rjs 		memcpy(mtod(m, void *), (const void *)asa, asa->sa_len);
   3036   1.1       rjs 	} else {
   3037   1.1       rjs 		m = NULL;
   3038   1.1       rjs 	}
   3039   1.1       rjs 	if (n) {
   3040   1.1       rjs 		n->m_next = m0;		/* concatenate data to control */
   3041   1.1       rjs 	}else {
   3042   1.1       rjs 		control = m0;
   3043   1.1       rjs 	}
   3044   1.1       rjs 	if (m)
   3045   1.1       rjs 		m->m_next = control;
   3046   1.1       rjs 	else
   3047   1.1       rjs 		m = control;
   3048   1.1       rjs 	m->m_pkthdr.csum_data = tag;
   3049   1.1       rjs 
   3050   1.1       rjs 	for (n = m; n; n = n->m_next)
   3051   1.1       rjs 		sballoc(sb, n);
   3052   1.1       rjs 	if ((n = sb->sb_mb) != NULL) {
   3053   1.1       rjs 		if ((n->m_nextpkt != inp->sb_last_mpkt) && (n->m_nextpkt == NULL)) {
   3054   1.1       rjs 			inp->sb_last_mpkt = NULL;
   3055   1.1       rjs 		}
   3056   1.1       rjs 		if (inp->sb_last_mpkt)
   3057   1.1       rjs 			inp->sb_last_mpkt->m_nextpkt = m;
   3058   1.1       rjs  		else {
   3059   1.1       rjs 			while (n->m_nextpkt) {
   3060   1.1       rjs 				n = n->m_nextpkt;
   3061   1.1       rjs 			}
   3062   1.1       rjs 			n->m_nextpkt = m;
   3063   1.1       rjs 		}
   3064   1.1       rjs 		inp->sb_last_mpkt = m;
   3065   1.1       rjs 	} else {
   3066   1.1       rjs 		inp->sb_last_mpkt = sb->sb_mb = m;
   3067   1.1       rjs 		inp->sctp_vtag_first = tag;
   3068   1.1       rjs 	}
   3069   1.1       rjs 	return (1);
   3070   1.1       rjs #endif
   3071   1.1       rjs #if defined(__FreeBSD__) || defined(__APPLE__)
   3072   1.1       rjs 	struct mbuf *m, *n, *nlast;
   3073   1.1       rjs 	int cnt=0;
   3074   1.1       rjs 
   3075   1.1       rjs 	if (m0 && (m0->m_flags & M_PKTHDR) == 0)
   3076   1.1       rjs 		panic("sbappendaddr_nocheck");
   3077   1.1       rjs 
   3078   1.1       rjs 	for (n = control; n; n = n->m_next) {
   3079   1.1       rjs 		if (n->m_next == 0)	/* get pointer to last control buf */
   3080   1.1       rjs 			break;
   3081   1.1       rjs 	}
   3082   1.1       rjs 	if (((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) == 0) ||
   3083   1.1       rjs 	    ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)== 0)) {
   3084   1.1       rjs 		if (asa->sa_len > MHLEN)
   3085   1.1       rjs 			return (0);
   3086   1.1       rjs  try_again:
   3087   1.1       rjs 		MGETHDR(m, M_DONTWAIT, MT_SONAME);
   3088   1.1       rjs 		if (m == 0)
   3089   1.1       rjs 			return (0);
   3090   1.1       rjs 		m->m_len = 0;
   3091   1.1       rjs 		/* safety */
   3092   1.1       rjs 		if (m == m0) {
   3093   1.1       rjs 			printf("Duplicate mbuf allocated %p in and mget returned %p?\n",
   3094   1.1       rjs 			       m0, m);
   3095   1.1       rjs 			if (cnt) {
   3096   1.1       rjs 				panic("more than once");
   3097   1.1       rjs 			}
   3098   1.1       rjs 			cnt++;
   3099   1.1       rjs 			goto try_again;
   3100   1.1       rjs 		}
   3101   1.1       rjs 		m->m_len = asa->sa_len;
   3102   1.1       rjs 		bcopy((void *)asa, mtod(m, void *), asa->sa_len);
   3103   1.1       rjs 	}
   3104   1.1       rjs 	else {
   3105   1.1       rjs 		m = NULL;
   3106   1.1       rjs 	}
   3107   1.1       rjs 	if (n)
   3108   1.1       rjs 		n->m_next = m0;		/* concatenate data to control */
   3109   1.1       rjs 	else
   3110   1.1       rjs 		control = m0;
   3111   1.1       rjs 	if (m)
   3112   1.1       rjs 		m->m_next = control;
   3113   1.1       rjs 	else
   3114   1.1       rjs 		m = control;
   3115   1.1       rjs 	m->m_pkthdr.csum_data = (int)tag;
   3116   1.1       rjs 
   3117   1.1       rjs 	for (n = m; n; n = n->m_next)
   3118   1.1       rjs 		sballoc(sb, n);
   3119   1.1       rjs 	nlast = n;
   3120   1.1       rjs 	if (sb->sb_mb == NULL) {
   3121   1.1       rjs 		inp->sctp_vtag_first = tag;
   3122   1.1       rjs 	}
   3123   1.1       rjs 
   3124   1.1       rjs #ifdef __FREEBSD__
   3125   1.1       rjs 	if (sb->sb_mb == NULL)
   3126   1.1       rjs 		inp->sctp_vtag_first = tag;
   3127   1.1       rjs 	SCTP_SBLINKRECORD(sb, m);
   3128   1.1       rjs 	sb->sb_mbtail = nlast;
   3129   1.1       rjs #else
   3130   1.1       rjs 	if ((n = sb->sb_mb) != NULL) {
   3131   1.1       rjs 		if ((n->m_nextpkt != inp->sb_last_mpkt) && (n->m_nextpkt == NULL)) {
   3132   1.1       rjs 			inp->sb_last_mpkt = NULL;
   3133   1.1       rjs 		}
   3134   1.1       rjs 		if (inp->sb_last_mpkt)
   3135   1.1       rjs 			inp->sb_last_mpkt->m_nextpkt = m;
   3136   1.1       rjs  		else {
   3137   1.1       rjs 			while (n->m_nextpkt) {
   3138   1.1       rjs 				n = n->m_nextpkt;
   3139   1.1       rjs 			}
   3140   1.1       rjs 			n->m_nextpkt = m;
   3141   1.1       rjs 		}
   3142   1.1       rjs 		inp->sb_last_mpkt = m;
   3143   1.1       rjs 	} else {
   3144   1.1       rjs 		inp->sb_last_mpkt = sb->sb_mb = m;
   3145   1.1       rjs 		inp->sctp_vtag_first = tag;
   3146   1.1       rjs 	}
   3147   1.1       rjs #endif
   3148   1.1       rjs 	return (1);
   3149   1.1       rjs #endif
   3150   1.1       rjs #ifdef __OpenBSD__
   3151   1.1       rjs 	struct mbuf *m, *n;
   3152   1.1       rjs 
   3153   1.1       rjs 	if (m0 && (m0->m_flags & M_PKTHDR) == 0)
   3154   1.1       rjs 		panic("sbappendaddr_nocheck");
   3155   1.1       rjs 	m0->m_pkthdr.csum = (int)tag;
   3156   1.1       rjs 	for (n = control; n; n = n->m_next) {
   3157   1.1       rjs 		if (n->m_next == 0)	/* keep pointer to last control buf */
   3158   1.1       rjs 			break;
   3159   1.1       rjs 	}
   3160   1.1       rjs 	if (((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) == 0) ||
   3161   1.1       rjs 	    ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)== 0)) {
   3162   1.1       rjs 		if (asa->sa_len > MHLEN)
   3163   1.1       rjs 			return (0);
   3164   1.1       rjs 		MGETHDR(m, M_DONTWAIT, MT_SONAME);
   3165   1.1       rjs 		if (m == 0)
   3166   1.1       rjs 			return (0);
   3167   1.1       rjs 		m->m_len = asa->sa_len;
   3168   1.1       rjs 		bcopy((void *)asa, mtod(m, void *), asa->sa_len);
   3169   1.1       rjs 	} else {
   3170   1.1       rjs 		m = NULL;
   3171   1.1       rjs 	}
   3172   1.1       rjs 	if (n)
   3173   1.1       rjs 		n->m_next = m0;		/* concatenate data to control */
   3174   1.1       rjs 	else
   3175   1.1       rjs 		control = m0;
   3176   1.1       rjs 
   3177   1.1       rjs 	m->m_pkthdr.csum = (int)tag;
   3178   1.1       rjs 	m->m_next = control;
   3179   1.1       rjs 	for (n = m; n; n = n->m_next)
   3180   1.1       rjs 		sballoc(sb, n);
   3181   1.1       rjs 	if ((n = sb->sb_mb) != NULL) {
   3182   1.1       rjs 		if ((n->m_nextpkt != inp->sb_last_mpkt) && (n->m_nextpkt == NULL)) {
   3183   1.1       rjs 			inp->sb_last_mpkt = NULL;
   3184   1.1       rjs 		}
   3185   1.1       rjs 		if (inp->sb_last_mpkt)
   3186   1.1       rjs 			inp->sb_last_mpkt->m_nextpkt = m;
   3187   1.1       rjs  		else {
   3188   1.1       rjs 			while (n->m_nextpkt) {
   3189   1.1       rjs 				n = n->m_nextpkt;
   3190   1.1       rjs 			}
   3191   1.1       rjs 			n->m_nextpkt = m;
   3192   1.1       rjs 		}
   3193   1.1       rjs 		inp->sb_last_mpkt = m;
   3194   1.1       rjs 	} else {
   3195   1.1       rjs 		inp->sb_last_mpkt = sb->sb_mb = m;
   3196   1.1       rjs 		inp->sctp_vtag_first = tag;
   3197   1.1       rjs 	}
   3198   1.1       rjs 	return (1);
   3199   1.1       rjs #endif
   3200   1.1       rjs }
   3201   1.1       rjs 
   3202   1.1       rjs /*************HOLD THIS COMMENT FOR PATCH FILE OF
   3203   1.1       rjs  *************ALTERNATE ROUTING CODE
   3204   1.1       rjs  */
   3205   1.1       rjs 
   3206   1.1       rjs /*************HOLD THIS COMMENT FOR END OF PATCH FILE OF
   3207   1.1       rjs  *************ALTERNATE ROUTING CODE
   3208   1.1       rjs  */
   3209   1.1       rjs 
   3210   1.1       rjs struct mbuf *
   3211   1.1       rjs sctp_generate_invmanparam(int err)
   3212   1.1       rjs {
   3213   1.1       rjs 	/* Return a MBUF with a invalid mandatory parameter */
   3214   1.1       rjs 	struct mbuf *m;
   3215   1.1       rjs 
   3216   1.1       rjs 	MGET(m, M_DONTWAIT, MT_DATA);
   3217   1.1       rjs 	if (m) {
   3218   1.1       rjs 		struct sctp_paramhdr *ph;
   3219   1.1       rjs 		m->m_len = sizeof(struct sctp_paramhdr);
   3220   1.1       rjs 		ph = mtod(m, struct sctp_paramhdr *);
   3221   1.1       rjs 		ph->param_length = htons(sizeof(struct sctp_paramhdr));
   3222   1.1       rjs 		ph->param_type = htons(err);
   3223   1.1       rjs 	}
   3224   1.1       rjs 	return (m);
   3225   1.1       rjs }
   3226   1.1       rjs 
   3227   1.1       rjs static int
   3228   1.1       rjs sctp_should_be_moved(struct mbuf *this, struct sctp_association *asoc)
   3229   1.1       rjs {
   3230   1.1       rjs 	struct mbuf *m;
   3231   1.1       rjs 	/*
   3232   1.1       rjs 	 * given a mbuf chain, look through it finding
   3233   1.1       rjs 	 * the M_PKTHDR and return 1 if it belongs to
   3234   1.1       rjs 	 * the association given. We tell this by
   3235   1.1       rjs 	 * a kludge where we stuff the my_vtag of the asoc
   3236   1.1       rjs 	 * into the m->m_pkthdr.csum_data/csum field.
   3237   1.1       rjs 	 */
   3238   1.1       rjs 	m = this;
   3239   1.1       rjs 	while (m) {
   3240   1.1       rjs 		if (m->m_flags & M_PKTHDR) {
   3241   1.1       rjs 			/* check it */
   3242   1.1       rjs #if defined(__OpenBSD__)
   3243   1.1       rjs 			if ((u_int32_t)m->m_pkthdr.csum == asoc->my_vtag)
   3244   1.1       rjs #else
   3245   1.1       rjs 			if ((u_int32_t)m->m_pkthdr.csum_data == asoc->my_vtag)
   3246   1.1       rjs #endif
   3247   1.1       rjs 			{
   3248   1.1       rjs 				/* Yep */
   3249   1.1       rjs 				return (1);
   3250   1.1       rjs 			}
   3251   1.1       rjs 		}
   3252   1.1       rjs 		m = m->m_next;
   3253   1.1       rjs 	}
   3254   1.1       rjs 	return (0);
   3255   1.1       rjs }
   3256   1.1       rjs 
   3257   1.1       rjs u_int32_t
   3258   1.1       rjs sctp_get_first_vtag_from_sb(struct socket *so)
   3259   1.1       rjs {
   3260   1.1       rjs 	struct mbuf *this, *at;
   3261   1.1       rjs 	u_int32_t retval;
   3262   1.1       rjs 
   3263   1.1       rjs 	retval = 0;
   3264   1.1       rjs 	if (so->so_rcv.sb_mb) {
   3265   1.1       rjs 		/* grubbing time */
   3266   1.1       rjs 		this = so->so_rcv.sb_mb;
   3267   1.1       rjs 		while (this) {
   3268   1.1       rjs 			at = this;
   3269   1.1       rjs 			/* get to the m_pkthdr */
   3270   1.1       rjs 			while (at) {
   3271   1.1       rjs 				if (at->m_flags & M_PKTHDR)
   3272   1.1       rjs 					break;
   3273   1.1       rjs 				else {
   3274   1.1       rjs 					at = at->m_next;
   3275   1.1       rjs 				}
   3276   1.1       rjs 			}
   3277   1.1       rjs 			/* now do we have a m_pkthdr */
   3278   1.1       rjs 			if (at && (at->m_flags & M_PKTHDR)) {
   3279   1.1       rjs 				/* check it */
   3280   1.1       rjs #if defined(__OpenBSD__)
   3281   1.1       rjs 				if ((u_int32_t)at->m_pkthdr.csum != 0)
   3282   1.1       rjs #else
   3283   1.1       rjs 				if ((u_int32_t)at->m_pkthdr.csum_data != 0)
   3284   1.1       rjs #endif
   3285   1.1       rjs 				{
   3286   1.1       rjs 					/* its the one */
   3287   1.1       rjs #if defined(__OpenBSD__)
   3288   1.1       rjs 					retval = (u_int32_t)at->m_pkthdr.csum;
   3289   1.1       rjs #else
   3290   1.1       rjs 					retval =
   3291   1.1       rjs 					    (u_int32_t)at->m_pkthdr.csum_data;
   3292   1.1       rjs #endif
   3293   1.1       rjs 					break;
   3294   1.1       rjs 				}
   3295   1.1       rjs 			}
   3296   1.1       rjs 			this = this->m_nextpkt;
   3297   1.1       rjs 		}
   3298   1.1       rjs 
   3299   1.1       rjs 	}
   3300   1.1       rjs 	return (retval);
   3301   1.1       rjs 
   3302   1.1       rjs }
   3303   1.1       rjs void
   3304   1.1       rjs sctp_grub_through_socket_buffer(struct sctp_inpcb *inp, struct socket *old,
   3305   1.1       rjs     struct socket *new, struct sctp_tcb *stcb)
   3306   1.1       rjs {
   3307   1.1       rjs 	struct mbuf **put, **take, *next, *this;
   3308   1.1       rjs 	struct sockbuf *old_sb, *new_sb;
   3309   1.1       rjs 	struct sctp_association *asoc;
   3310   1.1       rjs 	int moved_top = 0;
   3311   1.1       rjs 
   3312   1.1       rjs 	asoc = &stcb->asoc;
   3313   1.1       rjs 	old_sb = &old->so_rcv;
   3314   1.1       rjs 	new_sb = &new->so_rcv;
   3315   1.1       rjs 	if (old_sb->sb_mb == NULL) {
   3316   1.1       rjs 		/* Nothing to move */
   3317   1.1       rjs 		return;
   3318   1.1       rjs 	}
   3319   1.1       rjs 
   3320   1.1       rjs 	if (inp->sctp_vtag_first == asoc->my_vtag) {
   3321   1.1       rjs 		/* First one must be moved */
   3322   1.1       rjs 		struct mbuf *mm;
   3323   1.1       rjs 		for (mm = old_sb->sb_mb; mm; mm = mm->m_next) {
   3324   1.1       rjs 			/*
   3325   1.1       rjs 			 * Go down the chain and fix
   3326   1.1       rjs 			 * the space allocation of the
   3327   1.1       rjs 			 * two sockets.
   3328   1.1       rjs 			 */
   3329   1.1       rjs 			sbfree(old_sb, mm);
   3330   1.1       rjs 			sballoc(new_sb, mm);
   3331   1.1       rjs 		}
   3332   1.1       rjs 		new_sb->sb_mb = old_sb->sb_mb;
   3333   1.1       rjs 		old_sb->sb_mb = new_sb->sb_mb->m_nextpkt;
   3334   1.1       rjs 		new_sb->sb_mb->m_nextpkt = NULL;
   3335   1.1       rjs 		put = &new_sb->sb_mb->m_nextpkt;
   3336   1.1       rjs 		moved_top = 1;
   3337   1.1       rjs 	} else {
   3338   1.1       rjs 		put = &new_sb->sb_mb;
   3339   1.1       rjs 	}
   3340   1.1       rjs 
   3341   1.1       rjs 	take = &old_sb->sb_mb;
   3342   1.1       rjs 	next = old_sb->sb_mb;
   3343   1.1       rjs 	while (next) {
   3344   1.1       rjs 		this = next;
   3345   1.1       rjs 		/* postion for next one */
   3346   1.1       rjs 		next = this->m_nextpkt;
   3347   1.1       rjs 		/* check the tag of this packet */
   3348   1.1       rjs 		if (sctp_should_be_moved(this, asoc)) {
   3349   1.1       rjs 			/* yes this needs to be moved */
   3350   1.1       rjs 			struct mbuf *mm;
   3351   1.1       rjs 			*take = this->m_nextpkt;
   3352   1.1       rjs 			this->m_nextpkt = NULL;
   3353   1.1       rjs 			*put = this;
   3354   1.1       rjs 			for (mm = this; mm; mm = mm->m_next) {
   3355   1.1       rjs 				/*
   3356   1.1       rjs 				 * Go down the chain and fix
   3357   1.1       rjs 				 * the space allocation of the
   3358   1.1       rjs 				 * two sockets.
   3359   1.1       rjs 				 */
   3360   1.1       rjs 				sbfree(old_sb, mm);
   3361   1.1       rjs 				sballoc(new_sb, mm);
   3362   1.1       rjs 			}
   3363   1.1       rjs 			put = &this->m_nextpkt;
   3364   1.1       rjs 
   3365   1.1       rjs 		} else {
   3366   1.1       rjs 			/* no advance our take point. */
   3367   1.1       rjs 			take = &this->m_nextpkt;
   3368   1.1       rjs 		}
   3369   1.1       rjs 	}
   3370   1.1       rjs 	if (moved_top) {
   3371   1.1       rjs 		/*
   3372   1.1       rjs 		 * Ok so now we must re-postion vtag_first to
   3373   1.1       rjs 		 * match the new first one since we moved the
   3374   1.1       rjs 		 * mbuf at the top.
   3375   1.1       rjs 		 */
   3376   1.1       rjs 		inp->sctp_vtag_first = sctp_get_first_vtag_from_sb(old);
   3377   1.1       rjs 	}
   3378   1.1       rjs }
   3379   1.1       rjs 
   3380   1.1       rjs void
   3381   1.1       rjs sctp_free_bufspace(struct sctp_tcb *stcb, struct sctp_association *asoc,
   3382   1.1       rjs     struct sctp_tmit_chunk *tp1)
   3383   1.1       rjs {
   3384   1.1       rjs 	if (tp1->data == NULL) {
   3385   1.1       rjs 		return;
   3386   1.1       rjs 	}
   3387   1.1       rjs #ifdef SCTP_MBCNT_LOGGING
   3388   1.1       rjs 	sctp_log_mbcnt(SCTP_LOG_MBCNT_DECREASE,
   3389   1.1       rjs 		       asoc->total_output_queue_size,
   3390   1.1       rjs 		       tp1->book_size,
   3391   1.1       rjs 		       asoc->total_output_mbuf_queue_size,
   3392   1.1       rjs 		       tp1->mbcnt);
   3393   1.1       rjs #endif
   3394   1.1       rjs 	if (asoc->total_output_queue_size >= tp1->book_size) {
   3395   1.1       rjs 		asoc->total_output_queue_size -= tp1->book_size;
   3396   1.1       rjs 	} else {
   3397   1.1       rjs 		asoc->total_output_queue_size = 0;
   3398   1.1       rjs 	}
   3399   1.1       rjs 
   3400   1.1       rjs 	/* Now free the mbuf */
   3401   1.1       rjs 	if (asoc->total_output_mbuf_queue_size >= tp1->mbcnt) {
   3402   1.1       rjs 		asoc->total_output_mbuf_queue_size -= tp1->mbcnt;
   3403   1.1       rjs 	} else {
   3404   1.1       rjs 		asoc->total_output_mbuf_queue_size = 0;
   3405   1.1       rjs 	}
   3406   1.1       rjs 	if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
   3407   1.1       rjs 	    (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
   3408   1.1       rjs 		if (stcb->sctp_socket->so_snd.sb_cc >= tp1->book_size) {
   3409   1.1       rjs 			stcb->sctp_socket->so_snd.sb_cc -= tp1->book_size;
   3410   1.1       rjs 		} else {
   3411   1.1       rjs 			stcb->sctp_socket->so_snd.sb_cc = 0;
   3412   1.1       rjs 
   3413   1.1       rjs 		}
   3414   1.1       rjs 		if (stcb->sctp_socket->so_snd.sb_mbcnt >= tp1->mbcnt) {
   3415   1.1       rjs 			stcb->sctp_socket->so_snd.sb_mbcnt -= tp1->mbcnt;
   3416   1.1       rjs 		} else {
   3417   1.1       rjs 			stcb->sctp_socket->so_snd.sb_mbcnt = 0;
   3418   1.1       rjs 		}
   3419   1.1       rjs 	}
   3420   1.1       rjs }
   3421   1.1       rjs 
   3422   1.1       rjs int
   3423   1.1       rjs sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1,
   3424   1.1       rjs     int reason, struct sctpchunk_listhead *queue)
   3425   1.1       rjs {
   3426   1.1       rjs 	int ret_sz = 0;
   3427   1.1       rjs 	int notdone;
   3428   1.1       rjs 	uint8_t foundeom = 0;
   3429   1.1       rjs 
   3430   1.1       rjs 	do {
   3431   1.1       rjs 		ret_sz += tp1->book_size;
   3432   1.1       rjs 		tp1->sent = SCTP_FORWARD_TSN_SKIP;
   3433   1.1       rjs 		if (tp1->data) {
   3434   1.1       rjs 			sctp_free_bufspace(stcb, &stcb->asoc, tp1);
   3435   1.1       rjs 			sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb, reason, tp1);
   3436   1.1       rjs 			sctp_m_freem(tp1->data);
   3437   1.1       rjs 			tp1->data = NULL;
   3438   1.1       rjs 			sctp_sowwakeup(stcb->sctp_ep, stcb->sctp_socket);
   3439   1.1       rjs 		}
   3440   1.1       rjs 		if (tp1->flags & SCTP_PR_SCTP_BUFFER) {
   3441   1.1       rjs 			stcb->asoc.sent_queue_cnt_removeable--;
   3442   1.1       rjs 		}
   3443   1.1       rjs 		if (queue == &stcb->asoc.send_queue) {
   3444   1.1       rjs 			TAILQ_REMOVE(&stcb->asoc.send_queue, tp1, sctp_next);
   3445   1.1       rjs 			/* on to the sent queue */
   3446   1.1       rjs 			TAILQ_INSERT_TAIL(&stcb->asoc.sent_queue, tp1,
   3447   1.1       rjs 			    sctp_next);
   3448   1.1       rjs 			stcb->asoc.sent_queue_cnt++;
   3449   1.1       rjs 		}
   3450   1.1       rjs 		if ((tp1->rec.data.rcv_flags & SCTP_DATA_NOT_FRAG) ==
   3451   1.1       rjs 		    SCTP_DATA_NOT_FRAG) {
   3452   1.1       rjs 			/* not frag'ed we ae done   */
   3453   1.1       rjs 			notdone = 0;
   3454   1.1       rjs 			foundeom = 1;
   3455   1.1       rjs 		} else if (tp1->rec.data.rcv_flags & SCTP_DATA_LAST_FRAG) {
   3456   1.1       rjs 			/* end of frag, we are done */
   3457   1.1       rjs 			notdone = 0;
   3458   1.1       rjs 			foundeom = 1;
   3459   1.1       rjs 		} else {
   3460   1.1       rjs 			/* Its a begin or middle piece, we must mark all of it */
   3461   1.1       rjs 			notdone = 1;
   3462   1.1       rjs 			tp1 = TAILQ_NEXT(tp1, sctp_next);
   3463   1.1       rjs 		}
   3464   1.1       rjs 	} while (tp1 && notdone);
   3465   1.1       rjs 	if ((foundeom == 0) && (queue == &stcb->asoc.sent_queue)) {
   3466   1.1       rjs 		/*
   3467   1.1       rjs 		 * The multi-part message was scattered
   3468   1.1       rjs 		 * across the send and sent queue.
   3469   1.1       rjs 		 */
   3470   1.1       rjs 		tp1 = TAILQ_FIRST(&stcb->asoc.send_queue);
   3471   1.1       rjs 		/*
   3472   1.1       rjs 		 * recurse throught the send_queue too, starting at the
   3473   1.1       rjs 		 * beginning.
   3474   1.1       rjs 		 */
   3475   1.1       rjs 		if (tp1) {
   3476   1.1       rjs 			ret_sz += sctp_release_pr_sctp_chunk(stcb, tp1, reason,
   3477   1.1       rjs 			    &stcb->asoc.send_queue);
   3478   1.1       rjs 		} else {
   3479   1.1       rjs 			printf("hmm, nothing on the send queue and no EOM?\n");
   3480   1.1       rjs 		}
   3481   1.1       rjs 	}
   3482   1.1       rjs 	return (ret_sz);
   3483   1.1       rjs }
   3484   1.1       rjs 
   3485   1.1       rjs /*
   3486   1.1       rjs  * checks to see if the given address, sa, is one that is currently
   3487   1.1       rjs  * known by the kernel
   3488   1.1       rjs  * note: can't distinguish the same address on multiple interfaces and
   3489   1.1       rjs  *       doesn't handle multiple addresses with different zone/scope id's
   3490   1.1       rjs  * note: ifa_ifwithaddr() compares the entire sockaddr struct
   3491   1.1       rjs  */
   3492   1.1       rjs struct ifaddr *
   3493   1.1       rjs sctp_find_ifa_by_addr(struct sockaddr *sa)
   3494   1.1       rjs {
   3495   1.1       rjs 	struct ifnet *ifn;
   3496   1.1       rjs 	struct ifaddr *ifa;
   3497   1.7     ozaki 	int s;
   3498   1.1       rjs 
   3499   1.1       rjs 	/* go through all our known interfaces */
   3500   1.7     ozaki 	s = pserialize_read_enter();
   3501   1.7     ozaki 	IFNET_READER_FOREACH(ifn) {
   3502   1.1       rjs 		/* go through each interface addresses */
   3503  1.10     ozaki 		IFADDR_READER_FOREACH(ifa, ifn) {
   3504   1.1       rjs 			/* correct family? */
   3505   1.1       rjs 			if (ifa->ifa_addr->sa_family != sa->sa_family)
   3506   1.1       rjs 				continue;
   3507   1.1       rjs 
   3508   1.1       rjs #ifdef INET6
   3509   1.1       rjs 			if (ifa->ifa_addr->sa_family == AF_INET6) {
   3510   1.1       rjs 				/* IPv6 address */
   3511   1.1       rjs 				struct sockaddr_in6 *sin1, *sin2, sin6_tmp;
   3512   1.1       rjs 				sin1 = (struct sockaddr_in6 *)ifa->ifa_addr;
   3513   1.1       rjs 				if (IN6_IS_SCOPE_LINKLOCAL(&sin1->sin6_addr)) {
   3514   1.1       rjs 					/* create a copy and clear scope */
   3515   1.1       rjs 					memcpy(&sin6_tmp, sin1,
   3516   1.1       rjs 					    sizeof(struct sockaddr_in6));
   3517   1.1       rjs 					sin1 = &sin6_tmp;
   3518   1.1       rjs 					in6_clearscope(&sin1->sin6_addr);
   3519   1.1       rjs 				}
   3520   1.1       rjs 				sin2 = (struct sockaddr_in6 *)sa;
   3521   1.1       rjs 				if (memcmp(&sin1->sin6_addr, &sin2->sin6_addr,
   3522   1.1       rjs 					   sizeof(struct in6_addr)) == 0) {
   3523   1.1       rjs 					/* found it */
   3524   1.7     ozaki 					pserialize_read_exit(s);
   3525   1.1       rjs 					return (ifa);
   3526   1.1       rjs 				}
   3527   1.1       rjs 			} else
   3528   1.1       rjs #endif
   3529   1.1       rjs 			if (ifa->ifa_addr->sa_family == AF_INET) {
   3530   1.1       rjs 				/* IPv4 address */
   3531   1.1       rjs 				struct sockaddr_in *sin1, *sin2;
   3532   1.1       rjs 				sin1 = (struct sockaddr_in *)ifa->ifa_addr;
   3533   1.1       rjs 				sin2 = (struct sockaddr_in *)sa;
   3534   1.1       rjs 				if (sin1->sin_addr.s_addr ==
   3535   1.1       rjs 				    sin2->sin_addr.s_addr) {
   3536   1.1       rjs 					/* found it */
   3537   1.7     ozaki 					pserialize_read_exit(s);
   3538   1.1       rjs 					return (ifa);
   3539   1.1       rjs 				}
   3540   1.1       rjs 			}
   3541   1.1       rjs 			/* else, not AF_INET or AF_INET6, so skip */
   3542   1.1       rjs 		} /* end foreach ifa */
   3543   1.1       rjs 	} /* end foreach ifn */
   3544   1.7     ozaki 	pserialize_read_exit(s);
   3545   1.7     ozaki 
   3546   1.1       rjs 	/* not found! */
   3547   1.1       rjs 	return (NULL);
   3548   1.1       rjs }
   3549   1.1       rjs 
   3550   1.1       rjs 
   3551   1.1       rjs #ifdef __APPLE__
   3552   1.1       rjs /*
   3553   1.1       rjs  * here we hack in a fix for Apple's m_copym for the case where the first mbuf
   3554   1.1       rjs  * in the chain is a M_PKTHDR and the length is zero
   3555   1.1       rjs  */
   3556   1.1       rjs static void
   3557   1.1       rjs sctp_pkthdr_fix(struct mbuf *m)
   3558   1.1       rjs {
   3559   1.1       rjs 	struct mbuf *m_nxt;
   3560   1.1       rjs 
   3561   1.1       rjs 	if ((m->m_flags & M_PKTHDR) == 0) {
   3562   1.1       rjs 		/* not a PKTHDR */
   3563   1.1       rjs 		return;
   3564   1.1       rjs 	}
   3565   1.1       rjs 
   3566   1.1       rjs 	if (m->m_len != 0) {
   3567   1.1       rjs 		/* not a zero length PKTHDR mbuf */
   3568   1.1       rjs 		return;
   3569   1.1       rjs 	}
   3570   1.1       rjs 
   3571   1.1       rjs 	/* let's move in a word into the first mbuf... yes, ugly! */
   3572   1.1       rjs 	m_nxt = m->m_next;
   3573   1.1       rjs 	if (m_nxt == NULL) {
   3574   1.1       rjs 		/* umm... not a very useful mbuf chain... */
   3575   1.1       rjs 		return;
   3576   1.1       rjs 	}
   3577   1.1       rjs 	if ((size_t)m_nxt->m_len > sizeof(long)) {
   3578   1.1       rjs 		/* move over a long */
   3579   1.1       rjs 		bcopy(mtod(m_nxt, void *), mtod(m, void *), sizeof(long));
   3580   1.1       rjs 		/* update mbuf data pointers and lengths */
   3581   1.1       rjs 		m->m_len += sizeof(long);
   3582   1.1       rjs 		m_nxt->m_data += sizeof(long);
   3583   1.1       rjs 		m_nxt->m_len -= sizeof(long);
   3584   1.1       rjs 	}
   3585   1.1       rjs }
   3586   1.1       rjs 
   3587   1.1       rjs inline struct mbuf *
   3588   1.1       rjs sctp_m_copym(struct mbuf *m, int off, int len, int wait)
   3589   1.1       rjs {
   3590   1.1       rjs 	sctp_pkthdr_fix(m);
   3591   1.1       rjs 	return (m_copym(m, off, len, wait));
   3592   1.1       rjs }
   3593   1.1       rjs #endif /* __APPLE__ */
   3594