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