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