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