1 /*
2  * Copyright 2004-2013, Irene Ruengeler <i.ruengeler [AT] fh-muenster.de>
3  *
4  * Wireshark - Network traffic analyzer
5  * By Gerald Combs <gerald@wireshark.org>
6  * Copyright 1998 Gerald Combs
7  *
8  * SPDX-License-Identifier: GPL-2.0-or-later
9  */
10 
11 #include "config.h"
12 
13 #include <string.h>
14 #include <math.h>
15 
16 #include <glib.h>
17 
18 #include "epan/packet_info.h"
19 #include "epan/tap.h"
20 #include "epan/value_string.h"
21 
22 #include "ui/tap-sctp-analysis.h"
23 
24 #include "ui/simple_dialog.h"
25 
26 #define FORWARD_STREAM                     0
27 #define BACKWARD_STREAM                    1
28 #define FORWARD_ADD_FORWARD_VTAG           2
29 #define BACKWARD_ADD_FORWARD_VTAG          3
30 #define BACKWARD_ADD_BACKWARD_VTAG         4
31 #define ADDRESS_FORWARD_STREAM             5
32 #define ADDRESS_BACKWARD_STREAM            6
33 #define ADDRESS_FORWARD_ADD_FORWARD_VTAG   7
34 #define ADDRESS_BACKWARD_ADD_FORWARD_VTAG  8
35 #define ADDRESS_BACKWARD_ADD_BACKWARD_VTAG 9
36 #define ASSOC_NOT_FOUND                    10
37 
38 static sctp_allassocs_info_t sctp_tapinfo_struct = {0, NULL, FALSE, NULL};
39 
40 static void
free_first(gpointer data,gpointer user_data _U_)41 free_first(gpointer data, gpointer user_data _U_)
42 {
43     g_free(data);
44 }
45 
46 static void
tsn_free(gpointer data)47 tsn_free(gpointer data)
48 {
49     tsn_t *tsn;
50 
51     tsn = (tsn_t *) data;
52     if (tsn->tsns != NULL)
53     {
54         g_list_free_full(tsn->tsns, g_free);
55     }
56     free_address(&tsn->src);
57     free_address(&tsn->dst);
58     g_free(tsn);
59 }
60 
61 static void
chunk_free(gpointer data)62 chunk_free(gpointer data)
63 {
64     sctp_addr_chunk *chunk = (sctp_addr_chunk *) data;
65 
66     free_address(&chunk->addr);
67     g_free(chunk);
68 }
69 
70 static void
store_free(gpointer data)71 store_free(gpointer data)
72 {
73     address *addr = (address *) data;
74 
75     free_address(addr);
76     g_free(addr);
77 }
78 
79 static void
reset(void * arg)80 reset(void *arg)
81 {
82     sctp_allassocs_info_t *tapdata = (sctp_allassocs_info_t *)arg;
83     GList* list;
84     sctp_assoc_info_t * info;
85 
86     list = g_list_first(tapdata->assoc_info_list);
87     while (list)
88     {
89         info = (sctp_assoc_info_t *) (list->data);
90 
91         if (info->addr1 != NULL)
92         {
93             g_list_free_full(info->addr1, store_free);
94             info->addr1 = NULL;
95         }
96 
97         if (info->addr2 != NULL)
98         {
99             g_list_free_full(info->addr2, store_free);
100             info->addr2 = NULL;
101         }
102 
103         if (info->error_info_list != NULL)
104         {
105             g_list_free_full(info->error_info_list, g_free);
106             info->error_info_list = NULL;
107         }
108 
109         if (info->frame_numbers != NULL)
110         {
111             g_list_free(info->frame_numbers);
112             info->frame_numbers = NULL;
113         }
114 
115         if (info->tsn1 != NULL)
116         {
117             g_list_free_full(info->tsn1, tsn_free);
118             info->tsn1 = NULL;
119         }
120 
121         if (info->tsn2 != NULL)
122         {
123             g_list_free_full(info->tsn2, tsn_free);
124             info->tsn2 = NULL;
125         }
126 
127         if (info->sack1 != NULL)
128         {
129             g_list_free_full(info->sack1, tsn_free);
130             info->sack1 = NULL;
131         }
132 
133         if (info->sack2 != NULL)
134         {
135             g_list_free_full(info->sack2, tsn_free);
136             info->sack2 = NULL;
137         }
138 
139         if (info->sort_tsn1 != NULL)
140             g_ptr_array_free(info->sort_tsn1, TRUE);
141 
142         if (info->sort_tsn2 != NULL)
143             g_ptr_array_free(info->sort_tsn2, TRUE);
144 
145         if (info->sort_sack1 != NULL)
146             g_ptr_array_free(info->sort_sack1, TRUE);
147 
148         if (info->sort_sack2 != NULL)
149             g_ptr_array_free(info->sort_sack2, TRUE);
150 
151         if (info->min_max != NULL)
152         {
153             g_slist_foreach(info->min_max, free_first, NULL);
154             info->min_max = NULL;
155         }
156 
157         if (info->addr_chunk_count) {
158             g_list_free_full(info->addr_chunk_count, chunk_free);
159         }
160 
161         g_free(info->dir1);
162         g_free(info->dir2);
163         free_address(&info->src);
164         free_address(&info->dst);
165 
166         g_free(list->data);
167         list = g_list_next(list);
168     }
169     g_list_free(tapdata->assoc_info_list);
170     tapdata->sum_tvbs = 0;
171     tapdata->assoc_info_list = NULL;
172 }
173 
174 
175 static sctp_assoc_info_t *
calc_checksum(const struct _sctp_info * check_data,sctp_assoc_info_t * data)176 calc_checksum(const struct _sctp_info *check_data, sctp_assoc_info_t *data)
177 {
178     gboolean ok = FALSE;
179 
180     if (check_data->adler32_calculated)
181     {
182         data->n_adler32_calculated++;
183         if (check_data->adler32_correct)
184             data->n_adler32_correct++;
185     }
186     if (check_data->crc32c_calculated)
187     {
188         data->n_crc32c_calculated++;
189         if (check_data->crc32c_correct)
190             data->n_crc32c_correct++;
191     }
192     if (data->n_adler32_calculated > 0)
193     {
194         if ((float)(data->n_adler32_correct*1.0/data->n_adler32_calculated) > 0.5)
195         {
196             char str[] = "ADLER32";
197             (void) g_strlcpy(data->checksum_type, str, strlen(str));
198             data->n_checksum_errors=(data->n_adler32_calculated-data->n_adler32_correct);
199             ok = TRUE;
200         }
201     }
202 
203     if (data->n_crc32c_calculated>0)
204     {
205         if ((float)(data->n_crc32c_correct*1.0/data->n_crc32c_calculated) > 0.5)
206         {
207             char str[] = "CRC32C";
208             (void) g_strlcpy(data->checksum_type, str, strlen(str));
209             data->n_checksum_errors=data->n_crc32c_calculated-data->n_crc32c_correct;
210             ok = TRUE;
211         }
212     }
213 
214     if (!ok)
215     {
216         char str[] = "UNKNOWN";
217         (void) g_strlcpy(data->checksum_type, str, strlen(str));
218         data->n_checksum_errors=0;
219     }
220 
221     return(data);
222 
223 }
224 
225 
226 static sctp_assoc_info_t *
find_assoc(sctp_tmp_info_t * needle)227 find_assoc(sctp_tmp_info_t *needle)
228 {
229     sctp_allassocs_info_t *assoc_info;
230     sctp_assoc_info_t *info = NULL;
231     GList* list;
232 
233     assoc_info = &sctp_tapinfo_struct;
234     if ((list = g_list_last(assoc_info->assoc_info_list))!=NULL)
235     {
236         while (list)
237         {
238             info = (sctp_assoc_info_t*)(list->data);
239             if (needle->assoc_id == info->assoc_id)
240                 return info;
241 
242             list = g_list_previous(list);
243         }
244     }
245     return NULL;
246 }
247 
248 static sctp_assoc_info_t *
add_chunk_count(address * vadd,sctp_assoc_info_t * info,guint32 direction,guint32 type)249 add_chunk_count(address *vadd, sctp_assoc_info_t *info, guint32 direction, guint32 type)
250 {
251     GList *list;
252     sctp_addr_chunk *ch=NULL;
253     int i;
254 
255     list = g_list_first(info->addr_chunk_count);
256 
257     while (list)
258     {
259         ch = (sctp_addr_chunk *)(list->data);
260         if (ch->direction == direction)
261         {
262             if (addresses_equal(vadd, &ch->addr))
263             {
264                 if (IS_SCTP_CHUNK_TYPE(type))
265                     ch->addr_count[type]++;
266                 else
267                     ch->addr_count[OTHER_CHUNKS_INDEX]++;
268                 return info;
269             }
270             else
271             {
272                 list = g_list_next(list);
273             }
274         }
275         else
276             list = g_list_next(list);
277     }
278     ch = g_new(sctp_addr_chunk, 1);
279     ch->direction = direction;
280     copy_address(&ch->addr, vadd);
281     for (i=0; i < NUM_CHUNKS; i++)
282         ch->addr_count[i] = 0;
283 
284     if (IS_SCTP_CHUNK_TYPE(type))
285         ch->addr_count[type]++;
286     else
287         ch->addr_count[OTHER_CHUNKS_INDEX]++;
288 
289     info->addr_chunk_count = g_list_append(info->addr_chunk_count, ch);
290     return info;
291 }
292 
293 static sctp_assoc_info_t *
add_address(address * vadd,sctp_assoc_info_t * info,guint16 direction)294 add_address(address *vadd, sctp_assoc_info_t *info, guint16 direction)
295 {
296     GList *list;
297     address *v=NULL;
298 
299     if (direction == 1)
300         list = g_list_first(info->addr1);
301     else
302         list = g_list_first(info->addr2);
303 
304     while (list)
305     {
306         v = (address *) (list->data);
307         if (addresses_equal(vadd, v)) {
308             free_address(vadd);
309             g_free(vadd);
310             return info;
311         }
312         list = g_list_next(list);
313     }
314 
315     if (direction == 1)
316         info->addr1 = g_list_append(info->addr1, vadd);
317     else if (direction==2)
318         info->addr2 = g_list_append(info->addr2, vadd);
319 
320     return info;
321 }
322 
323 static tap_packet_status
packet(void * tapdata _U_,packet_info * pinfo,epan_dissect_t * edt _U_,const void * data)324 packet(void *tapdata _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *data)
325 {
326     const struct _sctp_info *sctp_info = (const struct _sctp_info *)data;
327     guint32 chunk_number = 0, tsnumber, framenumber;
328     sctp_tmp_info_t tmp_info;
329     sctp_assoc_info_t *info = NULL;
330     sctp_error_info_t *error = NULL;
331     guint16 type, length = 0;
332     address *store = NULL;
333     tsn_t *tsn = NULL;
334     tsn_t *sack = NULL;
335     guint8 *t_s_n = NULL;
336     gboolean sackchunk = FALSE;
337     gboolean datachunk = FALSE;
338     gboolean forwardchunk = FALSE;
339     struct tsn_sort *tsn_s;
340     int i;
341     guint8 idx = 0;
342     gboolean tsn_used = FALSE;
343     gboolean sack_used = FALSE;
344 
345     framenumber = pinfo->num;
346 
347     type = sctp_info->ip_src.type;
348 
349     if (type == AT_IPv4 || type == AT_IPv6)
350         copy_address(&tmp_info.src, &sctp_info->ip_src);
351     else
352         set_address(&tmp_info.src, AT_NONE, 0, NULL);
353 
354     type = sctp_info->ip_dst.type;
355 
356     if (type == AT_IPv4 || type == AT_IPv6)
357         copy_address(&tmp_info.dst, &sctp_info->ip_dst);
358     else
359         set_address(&tmp_info.dst, AT_NONE, 0, NULL);
360 
361     tmp_info.port1 = sctp_info->sport;
362     tmp_info.port2 = sctp_info->dport;
363 
364     if (sctp_info->vtag_reflected)
365     {
366         tmp_info.verification_tag2 = sctp_info->verification_tag;
367         tmp_info.verification_tag1 = 0;
368     }
369     else
370     {
371         tmp_info.verification_tag1 = sctp_info->verification_tag;
372         tmp_info.verification_tag2 = 0;
373     }
374     tmp_info.n_tvbs = 0;
375     if (tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID)
376     {
377         tmp_info.initiate_tag = tvb_get_ntohl(sctp_info->tvb[0], 4);
378     }
379     else
380     {
381         tmp_info.initiate_tag = 0;
382     }
383 
384     tmp_info.direction = sctp_info->direction;
385     tmp_info.assoc_id = sctp_info->assoc_index;
386     info = find_assoc(&tmp_info);
387     if (!info)
388     {
389         tmp_info.n_tvbs = sctp_info->number_of_tvbs;
390         sctp_tapinfo_struct.sum_tvbs+=sctp_info->number_of_tvbs;
391 
392         if (sctp_info->number_of_tvbs > 0)
393         {
394             info = g_new0(sctp_assoc_info_t, 1);
395             info->assoc_id = sctp_info->assoc_index;
396             copy_address(&info->src, &tmp_info.src);
397             copy_address(&info->dst, &tmp_info.dst);
398             info->port1 = tmp_info.port1;
399             info->port2 = tmp_info.port2;
400             info->verification_tag1 = tmp_info.verification_tag1;
401             info->verification_tag2 = tmp_info.verification_tag2;
402             info->initiate_tag      = tmp_info.initiate_tag;
403             info->n_tvbs            = tmp_info.n_tvbs;
404             info->init              = FALSE;
405             info->initack           = FALSE;
406             info->check_address     = FALSE;
407             info->firstdata         = TRUE;
408             info->direction         = sctp_info->direction;
409             info->instream1         = 0;
410             info->outstream1        = 0;
411             info->instream2         = 0;
412             info->outstream2        = 0;
413             info                    = calc_checksum(sctp_info, info);
414             info->n_packets         = 1;
415             info->error_info_list   = NULL;
416             info->min_secs          = 0xffffffff;
417             info->min_usecs         = 0xffffffff;
418             info->max_secs          = 0;
419             info->max_usecs         = 0;
420             info->min_tsn2          = 0xFFFFFFFF;
421             info->min_tsn1          = 0xffffffff;
422             info->max_tsn1          = 0;
423             info->max_tsn2          = 0;
424             info->max_bytes1        = 0;
425             info->max_bytes2        = 0;
426             info->n_data_chunks     = 0;
427             info->n_data_bytes      = 0;
428             info->n_data_chunks_ep1 = 0;
429             info->n_data_bytes_ep1  = 0;
430             info->n_data_chunks_ep2 = 0;
431             info->n_data_bytes_ep2  = 0;
432             info->n_sack_chunks_ep1 = 0;
433             info->n_sack_chunks_ep2 = 0;
434             info->n_array_tsn1      = 0;
435             info->n_array_tsn2      = 0;
436             info->n_forward_chunks  = 0;
437             info->max_window1       = 0;
438             info->max_window2       = 0;
439             info->min_max           = NULL;
440             info->sort_tsn1         = g_ptr_array_new_with_free_func(g_free);
441             info->sort_tsn2         = g_ptr_array_new_with_free_func(g_free);
442             info->sort_sack1        = g_ptr_array_new_with_free_func(g_free);
443             info->sort_sack2        = g_ptr_array_new_with_free_func(g_free);
444             info->dir1              = g_new0(sctp_init_collision_t, 1);
445             info->dir1->init_min_tsn = 0xffffffff;
446             info->dir1->initack_min_tsn = 0xffffffff;
447             info->dir2              = g_new0(sctp_init_collision_t, 1);
448             info->dir2->init_min_tsn = 0xffffffff;
449             info->dir2->initack_min_tsn = 0xffffffff;
450 
451             for (i=0; i < NUM_CHUNKS; i++)
452             {
453                 info->chunk_count[i] = 0;
454                 info->ep1_chunk_count[i] = 0;
455                 info->ep2_chunk_count[i] = 0;
456             }
457             info->addr_chunk_count = NULL;
458 
459             if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID) ||
460                     ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID) ||
461                     ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) ||
462                     ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_I_DATA_CHUNK_ID) ||
463                     ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID) ||
464                     ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID) ||
465                     ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_FORWARD_TSN_CHUNK_ID))
466             {
467                 tsn = g_new0(tsn_t, 1);
468                 copy_address(&tsn->src, &tmp_info.src);
469                 copy_address(&tsn->dst, &tmp_info.dst);
470 
471                 sack = g_new0(tsn_t, 1);
472                 copy_address(&sack->src, &tmp_info.src);
473                 copy_address(&sack->dst, &tmp_info.dst);
474                 sack->secs=tsn->secs   = (guint32)pinfo->rel_ts.secs;
475                 sack->usecs=tsn->usecs = (guint32)pinfo->rel_ts.nsecs/1000;
476 
477                 if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) ||
478                         ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_I_DATA_CHUNK_ID) ||
479                         ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID) ||
480                         ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID) ||
481                         ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_FORWARD_TSN_CHUNK_ID))
482                 {
483                     if (tsn->secs < info->min_secs)
484                     {
485                         info->min_secs  = tsn->secs;
486                         info->min_usecs = tsn->usecs;
487                     }
488                     else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
489                         info->min_usecs = tsn->usecs;
490 
491                     if (tsn->secs > info->max_secs)
492                     {
493                         info->max_secs  = tsn->secs;
494                         info->max_usecs = tsn->usecs;
495                     }
496                     else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
497                         info->max_usecs = tsn->usecs;
498                 }
499 
500                 sack->frame_number = tsn->frame_number = pinfo->num;
501             }
502             if ((tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID) || (tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_ACK_CHUNK_ID))
503             {
504                 info->min_tsn1 = tvb_get_ntohl(sctp_info->tvb[0],INIT_CHUNK_INITIAL_TSN_OFFSET);
505                 info->verification_tag2 = tvb_get_ntohl(sctp_info->tvb[0], INIT_CHUNK_INITIATE_TAG_OFFSET);
506                 info->instream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET);
507                 info->outstream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET);
508                 info->arwnd1 = tvb_get_ntohl(sctp_info->tvb[0], INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
509                 for (chunk_number = 1; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
510                 {
511                     type = tvb_get_ntohs(sctp_info->tvb[chunk_number],0);
512                     if (type == IPV4ADDRESS_PARAMETER_ID)
513                     {
514                         store = g_new(address, 1);
515                         alloc_address_tvb(NULL, store, AT_IPv4, 4, sctp_info->tvb[chunk_number], IPV4_ADDRESS_OFFSET);
516                         info = add_address(store, info, info->direction);
517                     }
518                     else if (type == IPV6ADDRESS_PARAMETER_ID)
519                     {
520                         store = g_new(address, 1);
521                         alloc_address_tvb(NULL, store, AT_IPv6, 16, sctp_info->tvb[chunk_number], IPV6_ADDRESS_OFFSET);
522                         info = add_address(store, info, info->direction);
523                     }
524                 }
525 
526                 if (tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID)
527                 {
528                     info->init = TRUE;
529                 }
530                 else
531                 {
532                     info->initack_dir = 1;
533                     info->initack     = TRUE;
534                 }
535 
536                 idx = tvb_get_guint8(sctp_info->tvb[0],0);
537                 if (!IS_SCTP_CHUNK_TYPE(idx))
538                     idx = OTHER_CHUNKS_INDEX;
539 
540                 info->chunk_count[idx]++;
541                 info->ep1_chunk_count[idx]++;
542                 info = add_chunk_count(&tmp_info.src, info, 1, idx);
543                 if (info->direction == 1) {
544                     if (tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID) {
545                         info->dir1->init = TRUE;
546                         info->dir1->init_min_tsn = info->min_tsn1;
547                         info->dir1->init_vtag = info->verification_tag2;
548                     } else if (tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_ACK_CHUNK_ID) {
549                         info->dir1->initack = TRUE;
550                         info->dir1->initack_min_tsn = info->min_tsn1;
551                         info->dir1->initack_vtag = info->verification_tag2;
552                     }
553                 } else {
554                     if (tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID) {
555                         info->dir2->init = TRUE;
556                         info->dir2->init_min_tsn = info->min_tsn1;
557                         info->dir2->init_vtag = info->verification_tag2;
558                     } else if (tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_ACK_CHUNK_ID) {
559                         info->dir2->initack = TRUE;
560                         info->dir2->initack_min_tsn = info->min_tsn1;
561                         info->dir2->initack_vtag = info->verification_tag2;
562                     }
563                 }
564             }
565             else
566             {
567                 if (((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_INIT_CHUNK_ID) &&
568                         ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_INIT_ACK_CHUNK_ID) &&
569                         ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_DATA_CHUNK_ID) &&
570                         ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_I_DATA_CHUNK_ID) &&
571                         ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_SACK_CHUNK_ID) &&
572                         ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_NR_SACK_CHUNK_ID) &&
573                         ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_FORWARD_TSN_CHUNK_ID))
574                 {
575                     tsn = g_new0(tsn_t, 1);
576                     sack = g_new0(tsn_t, 1);
577                 }
578                 for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
579                 {
580                     idx = tvb_get_guint8(sctp_info->tvb[0],0);
581                     if (!IS_SCTP_CHUNK_TYPE(idx))
582                         idx = OTHER_CHUNKS_INDEX;
583 
584                     info->chunk_count[idx]++;
585                     info->ep1_chunk_count[idx]++;
586                     info = add_chunk_count(&tmp_info.src, info, 1, idx);
587 
588                     if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID) ||
589                             (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_I_DATA_CHUNK_ID))
590                     {
591                         datachunk = TRUE;
592                         if (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID) {
593                             length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET) - DATA_CHUNK_HEADER_LENGTH;
594                         } else {
595                             length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET) - I_DATA_CHUNK_HEADER_LENGTH;
596                         }
597                         info->n_data_chunks++;
598                         info->n_data_bytes+=length;
599                         info->outstream1 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
600                     }
601                     if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_FORWARD_TSN_CHUNK_ID))
602                     {
603                         forwardchunk = TRUE;
604                         length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET);
605                         info->n_forward_chunks++;
606                     }
607                     if (datachunk || forwardchunk)
608                     {
609                         tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], DATA_CHUNK_TSN_OFFSET);
610                         info->firstdata = FALSE;
611                         if (tsnumber < info->min_tsn1)
612                             info->min_tsn1 = tsnumber;
613                         if (tsnumber > info->max_tsn1)
614                         {
615                             if (datachunk)
616                             {
617                                 info->n_data_chunks_ep1++;
618                                 info->n_data_bytes_ep1+=length;
619                             }
620                             else
621                                 info->n_forward_chunks_ep1++;
622                             info->max_tsn1 = tsnumber;
623                         }
624                         if (tsn->first_tsn == 0)
625                             tsn->first_tsn = tsnumber;
626                         if (datachunk)
627                         {
628                             t_s_n = (guint8 *)g_malloc(16);
629                             tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, 16);
630                         }
631                         else
632                         {
633                             t_s_n = (guint8 *)g_malloc(length);
634                             tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, length);
635                         }
636                         tsn->tsns = g_list_append(tsn->tsns, t_s_n);
637                         tsn_s = g_new(struct tsn_sort, 1);
638                         tsn_s->tsnumber = tsnumber;
639                         tsn_s->secs     = tsn->secs = (guint32)pinfo->rel_ts.secs;
640                         tsn_s->usecs    = tsn->usecs = (guint32)pinfo->rel_ts.nsecs/1000;
641                         tsn_s->offset   = 0;
642                         tsn_s->framenumber = framenumber;
643                         if (datachunk)
644                             if (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID) {
645                                 tsn_s->length   = length - DATA_CHUNK_HEADER_LENGTH;
646                             } else {
647                                 tsn_s->length   = length - I_DATA_CHUNK_HEADER_LENGTH;
648                             }
649                             else
650                                 tsn_s->length   = length;
651                         if (tsn->secs < info->min_secs)
652                         {
653                             info->min_secs  = tsn->secs;
654                             info->min_usecs = tsn->usecs;
655                         }
656                         else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
657                             info->min_usecs = tsn->usecs;
658 
659                         if (tsn->secs > info->max_secs)
660                         {
661                             info->max_secs  = tsn->secs;
662                             info->max_usecs = tsn->usecs;
663                         }
664                         else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
665                             info->max_usecs = tsn->usecs;
666                         g_ptr_array_add(info->sort_tsn1, tsn_s);
667                         info->n_array_tsn1++;
668                     }
669                     if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_SACK_CHUNK_ID) ||
670                             (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_NR_SACK_CHUNK_ID) )
671                     {
672                         tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET);
673                         if (tsnumber < info->min_tsn2)
674                             info->min_tsn2 = tsnumber;
675                         if (tsnumber > info->max_tsn2)
676                             info->max_tsn2 = tsnumber;
677                         length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET);
678                         if (sack->first_tsn == 0)
679                             sack->first_tsn = tsnumber;
680                         t_s_n = (guint8 *)g_malloc(length);
681                         tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, length);
682                         sack->tsns = g_list_append(sack->tsns, t_s_n);
683                         sackchunk = TRUE;
684                         tsn_s = g_new(struct tsn_sort, 1);
685                         tsn_s->tsnumber = tsnumber;
686                         tsn_s->secs     = tsn->secs = (guint32)pinfo->rel_ts.secs;
687                         tsn_s->usecs    = tsn->usecs = (guint32)pinfo->rel_ts.nsecs/1000;
688                         tsn_s->offset   = 0;
689                         tsn_s->framenumber = framenumber;
690                         tsn_s->length   =  tvb_get_ntohl(sctp_info->tvb[chunk_number], SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
691                         if (tsn_s->length > info->max_window1)
692                             info->max_window1 = tsn_s->length;
693                         if (tsn->secs < info->min_secs)
694                         {
695                             info->min_secs  = tsn->secs;
696                             info->min_usecs = tsn->usecs;
697                         }
698                         else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
699                             info->min_usecs = tsn->usecs;
700 
701                         if (tsn->secs > info->max_secs)
702                         {
703                             info->max_secs  = tsn->secs;
704                             info->max_usecs = tsn->usecs;
705                         }
706                         else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
707                             info->max_usecs = tsn->usecs;
708                         g_ptr_array_add(info->sort_sack2, tsn_s);
709                         info->n_sack_chunks_ep2++;
710                     }
711                 }
712             }
713             if (info->verification_tag1 != 0 || info->verification_tag2 != 0)
714             {
715                 guint32 number;
716                 store = g_new(address, 1);
717                 copy_address(store, &tmp_info.src);
718                 info  = add_address(store, info, info->direction);
719                 store = g_new(address, 1);
720                 copy_address(store, &tmp_info.dst);
721                 if (info->direction == 1)
722                     info = add_address(store, info, 2);
723                 else
724                     info = add_address(store, info, 1);
725                 number = pinfo->num;
726                 info->frame_numbers=g_list_prepend(info->frame_numbers, GUINT_TO_POINTER(number));
727                 if (datachunk || forwardchunk) {
728                     info->tsn1 = g_list_prepend(info->tsn1, tsn);
729                     tsn_used = TRUE;
730                 }
731                 if (sackchunk == TRUE) {
732                     info->sack2 = g_list_prepend(info->sack2, sack);
733                     sack_used = TRUE;
734                 }
735                 sctp_tapinfo_struct.assoc_info_list = g_list_append(sctp_tapinfo_struct.assoc_info_list, info);
736             }
737             else
738             {
739                 gchar* tmp_str;
740                 error = g_new(sctp_error_info_t, 1);
741                 error->frame_number = pinfo->num;
742                 error->chunk_info[0] = '\0';
743                 if ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID)
744                 {
745                     tmp_str = val_to_str_wmem(NULL, tvb_get_guint8(sctp_info->tvb[0],0),chunk_type_values,"Reserved (%d)");
746                     (void) g_strlcpy(error->chunk_info, tmp_str, 200);
747                     wmem_free(NULL, tmp_str);
748                 }
749                 else
750                 {
751                     for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
752                     {
753                         tmp_str = val_to_str_wmem(NULL, tvb_get_guint8(sctp_info->tvb[chunk_number],0),chunk_type_values,"Reserved (%d)");
754                         (void) g_strlcat(error->chunk_info, tmp_str, 200);
755                         wmem_free(NULL, tmp_str);
756                     }
757                 }
758                 error->info_text = "INFOS";
759                 info->error_info_list = g_list_append(info->error_info_list, error);
760             }
761         }
762     } /* endif (!info) */
763     else
764     {
765         guint32 number;
766         info->direction = sctp_info->direction;
767 
768         if (info->verification_tag1 == 0 && info->verification_tag2 != sctp_info->verification_tag) {
769             info->verification_tag1 = sctp_info->verification_tag;
770         } else if (info->verification_tag2 == 0 && info->verification_tag1 != sctp_info->verification_tag) {
771             info->verification_tag2 = sctp_info->verification_tag;
772         }
773         if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID) ||
774                 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID) ||
775                 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) ||
776                 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_I_DATA_CHUNK_ID) ||
777                 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID) ||
778                 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID) ||
779                 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_FORWARD_TSN_CHUNK_ID))
780         {
781 
782             tsn = g_new0(tsn_t, 1);
783             copy_address(&tsn->src, &tmp_info.src);
784             copy_address(&tsn->dst, &tmp_info.dst);
785 
786             sack = g_new0(tsn_t, 1);
787             copy_address(&sack->src, &tmp_info.src);
788             copy_address(&sack->dst, &tmp_info.dst);
789             sack->secs=tsn->secs = (guint32)pinfo->rel_ts.secs;
790             sack->usecs=tsn->usecs = (guint32)pinfo->rel_ts.nsecs/1000;
791 
792             if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) ||
793                     ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_I_DATA_CHUNK_ID) ||
794                     ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID) ||
795                     ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID) ||
796                     ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_FORWARD_TSN_CHUNK_ID))
797             {
798                 if (tsn->secs < info->min_secs)
799                 {
800                     info->min_secs  = tsn->secs;
801                     info->min_usecs = tsn->usecs;
802                 }
803                 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
804                     info->min_usecs = tsn->usecs;
805 
806                 if (tsn->secs > info->max_secs)
807                 {
808                     info->max_secs  = tsn->secs;
809                     info->max_usecs = tsn->usecs;
810                 }
811                 else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
812                     info->max_usecs = tsn->usecs;
813             }
814             sack->frame_number = tsn->frame_number = pinfo->num;
815         }
816         number = pinfo->num;
817         info->frame_numbers=g_list_prepend(info->frame_numbers, GUINT_TO_POINTER(number));
818 
819         store = g_new(address, 1);
820         copy_address(store, &tmp_info.src);
821 
822         switch (info->direction) {
823             case 1:
824                 info = add_address(store, info, 1);
825                 break;
826             case 2:
827                 info = add_address(store, info, 2);
828                 break;
829             default:
830                 g_free(store);
831                 break;
832         }
833 
834         store = g_new(address, 1);
835         copy_address(store, &tmp_info.dst);
836 
837         switch (info->direction) {
838             case 1:
839                 info = add_address(store, info, 2);
840                 break;
841             case 2:
842                 info = add_address(store, info, 1);
843                 break;
844             default:
845                 g_free(store);
846                 break;
847         }
848 
849         if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID) ||
850                 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID))
851         {
852             tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], INIT_CHUNK_INITIAL_TSN_OFFSET);
853             if (info->direction == 2)
854             {
855                 if (tsnumber < info->min_tsn2)
856                     info->min_tsn2 = tsnumber;
857                 if (tsnumber > info->max_tsn2)
858                     info->max_tsn2 = tsnumber;
859                 info->instream2 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET);
860                 info->outstream2 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET);
861                 info->arwnd2 = tvb_get_ntohl(sctp_info->tvb[0],INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
862                 info->tsn2 = g_list_prepend(info->tsn2, tsn);
863                 tsn_used = TRUE;
864             }
865             else if (info->direction == 1)
866             {
867                 if (tsnumber < info->min_tsn1)
868                     info->min_tsn1 = tsnumber;
869                 if (tsnumber > info->max_tsn1)
870                     info->max_tsn1 = tsnumber;
871                 info->instream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET);
872                 info->outstream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET);
873                 info->arwnd1 = tvb_get_ntohl(sctp_info->tvb[0],INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
874                 info->tsn1 = g_list_prepend(info->tsn1, tsn);
875                 tsn_used = TRUE;
876             }
877 
878             idx = tvb_get_guint8(sctp_info->tvb[0],0);
879             if (!IS_SCTP_CHUNK_TYPE(idx))
880                 idx = OTHER_CHUNKS_INDEX;
881             info->chunk_count[idx]++;
882             if (info->direction == 1)
883                 info->ep1_chunk_count[idx]++;
884             else
885                 info->ep2_chunk_count[idx]++;
886             info = add_chunk_count(&tmp_info.src, info, info->direction, idx);
887             for (chunk_number = 1; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
888             {
889                 type = tvb_get_ntohs(sctp_info->tvb[chunk_number],0);
890                 if (type == IPV4ADDRESS_PARAMETER_ID)
891                 {
892                     store = g_new(address, 1);
893                     alloc_address_tvb(NULL, store, AT_IPv4, 4, sctp_info->tvb[chunk_number], IPV4_ADDRESS_OFFSET);
894                     info = add_address(store, info, info->direction);
895                 }
896                 else if (type == IPV6ADDRESS_PARAMETER_ID)
897                 {
898                     store = g_new(address, 1);
899                     alloc_address_tvb(NULL, store, AT_IPv6, 16, sctp_info->tvb[chunk_number], IPV6_ADDRESS_OFFSET);
900                     info = add_address(store, info, info->direction);
901                 }
902             }
903             if (info->direction == 1) {
904                 if (info->dir1->init || info->dir1->initack) {
905                     info->init_collision = TRUE;
906                 }
907                 if (tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID) {
908                     info->dir1->init = TRUE;
909                     info->dir1->init_min_tsn = tvb_get_ntohl((sctp_info->tvb)[0], INIT_CHUNK_INITIAL_TSN_OFFSET);
910                     info->min_tsn1 = info->dir1->init_min_tsn;
911                     info->dir1->init_vtag = tvb_get_ntohl(sctp_info->tvb[0], INIT_CHUNK_INITIATE_TAG_OFFSET);
912                 } else if (tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_ACK_CHUNK_ID) {
913                     info->dir1->initack = TRUE;
914                     info->dir1->initack_min_tsn = tvb_get_ntohl((sctp_info->tvb)[0], INIT_CHUNK_INITIAL_TSN_OFFSET);
915                     info->min_tsn1 = info->dir1->initack_min_tsn;
916                     info->dir1->initack_vtag = tvb_get_ntohl(sctp_info->tvb[0], INIT_CHUNK_INITIATE_TAG_OFFSET);
917                 }
918             } else {
919                 if (info->dir2->init || info->dir2->initack) {
920                     info->init_collision = TRUE;
921                 }
922                 if (tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID) {
923                     info->dir2->init = TRUE;
924                     info->dir2->init_min_tsn = tvb_get_ntohl((sctp_info->tvb)[0], INIT_CHUNK_INITIAL_TSN_OFFSET);
925                     info->min_tsn2 = info->dir2->init_min_tsn;
926                     info->dir2->init_vtag = tvb_get_ntohl(sctp_info->tvb[0], INIT_CHUNK_INITIATE_TAG_OFFSET);
927                 } else if (tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_ACK_CHUNK_ID) {
928                     info->dir2->initack = TRUE;
929                     info->dir2->initack_min_tsn = tvb_get_ntohl((sctp_info->tvb)[0], INIT_CHUNK_INITIAL_TSN_OFFSET);
930                     info->min_tsn2 = info->dir2->initack_min_tsn;
931                     info->dir2->initack_vtag = tvb_get_ntohl(sctp_info->tvb[0], INIT_CHUNK_INITIATE_TAG_OFFSET);
932                 }
933             }
934             if ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID)
935             {
936                 info->initack = TRUE;
937                 info->initack_dir = info->direction;
938             }
939             else if ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID)
940             {
941                 info->init = TRUE;
942             }
943         }
944         else
945         {
946             if (((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_INIT_ACK_CHUNK_ID) &&
947                     ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_DATA_CHUNK_ID) &&
948                     ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_I_DATA_CHUNK_ID) &&
949                     ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_SACK_CHUNK_ID) &&
950                     ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_NR_SACK_CHUNK_ID) &&
951                     ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_FORWARD_TSN_CHUNK_ID))
952             {
953                 if (!sack)
954                     sack = g_new0(tsn_t, 1);
955                 sack->tsns = NULL;
956                 sack->first_tsn = 0;
957                 if (!tsn)
958                     tsn = g_new0(tsn_t, 1);
959                 tsn->tsns = NULL;
960                 tsn->first_tsn = 0;
961             }
962             for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
963             {
964                 idx = tvb_get_guint8(sctp_info->tvb[chunk_number],0);
965                 if (!IS_SCTP_CHUNK_TYPE(idx))
966                     idx = OTHER_CHUNKS_INDEX;
967 
968                 info->chunk_count[idx]++;
969                 if (info->direction == 1)
970                     info->ep1_chunk_count[idx]++;
971                 else
972                     info->ep2_chunk_count[idx]++;
973                 info = add_chunk_count(&tmp_info.src, info,info->direction, idx);
974 
975                 if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID) ||
976                         (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_I_DATA_CHUNK_ID))
977                     datachunk = TRUE;
978                 if (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_FORWARD_TSN_CHUNK_ID)
979                     forwardchunk = TRUE;
980                 if ((datachunk || forwardchunk) && tsn != NULL)
981                 {
982                     tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], DATA_CHUNK_TSN_OFFSET);
983                     if (tsn->first_tsn == 0)
984                         tsn->first_tsn = tsnumber;
985                     if (datachunk)
986                     {
987                         t_s_n = (guint8 *)g_malloc(16);
988                         tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, 16);
989                         if (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID) {
990                             length=tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
991                         } else {
992                             length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET) - I_DATA_CHUNK_HEADER_LENGTH;
993                         }
994                         info->n_data_chunks++;
995                         info->n_data_bytes+=length;
996                     }
997                     else
998                     {
999                         length=tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET);
1000                         t_s_n = (guint8 *)g_malloc(length);
1001                         tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, length);
1002                         info->n_forward_chunks++;
1003                     }
1004                     tsn->tsns = g_list_append(tsn->tsns, t_s_n);
1005 
1006                     tsn_s = g_new0(struct tsn_sort, 1);
1007                     tsn_s->tsnumber = tsnumber;
1008                     tsn_s->secs  = tsn->secs = (guint32)pinfo->rel_ts.secs;
1009                     tsn_s->usecs = tsn->usecs = (guint32)pinfo->rel_ts.nsecs/1000;
1010                     tsn_s->offset = 0;
1011                     tsn_s->framenumber = framenumber;
1012                     tsn_s->length = length;
1013 
1014                     if (tsn->secs < info->min_secs)
1015                     {
1016                         info->min_secs  = tsn->secs;
1017                         info->min_usecs = tsn->usecs;
1018                     }
1019                     else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
1020                         info->min_usecs = tsn->usecs;
1021 
1022                     if (tsn->secs > info->max_secs)
1023                     {
1024                         info->max_secs  = tsn->secs;
1025                         info->max_usecs = tsn->usecs;
1026                     }
1027                     else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
1028                         info->max_usecs = tsn->usecs;
1029 
1030                     if (info->direction == 1)
1031                     {
1032                         if (info->firstdata) {
1033                             info->firstdata = FALSE;
1034                             if (info->init_collision) {
1035                                 if (tsnumber != info->min_tsn1) {
1036                                     info->min_tsn1 = info->dir1->init_min_tsn;
1037                                 }
1038                                 info->min_tsn2 = info->dir2->initack_min_tsn;
1039                             }
1040                         } else {
1041                             if(tsnumber < info->min_tsn1) {
1042                                 info->min_tsn1 = tsnumber;
1043                             }
1044                         }
1045                         if ((info->init || (info->initack && info->initack_dir == 1))&& tsnumber >= info->min_tsn1 && tsnumber <= info->max_tsn1)
1046                         {
1047                             if (datachunk)
1048                             {
1049                                 info->n_data_chunks_ep1++;
1050                                 info->n_data_bytes_ep1 += length;
1051                             }
1052                             else if (forwardchunk)
1053                             {
1054                                 info->n_forward_chunks_ep1++;
1055                             }
1056                         }
1057                         if(tsnumber > info->max_tsn1)
1058                         {
1059                             info->max_tsn1 = tsnumber;
1060                             if (datachunk)
1061                             {
1062                                 info->n_data_chunks_ep1++;
1063                                 info->n_data_bytes_ep1 += length;
1064                             }
1065                             else if (forwardchunk)
1066                             {
1067                                 info->n_forward_chunks_ep1++;
1068                             }
1069                         }
1070                         if (datachunk)
1071                         {
1072                             if (info->init == FALSE) {
1073                                 guint16 tmp = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1074                                 if (info->outstream1 < tmp) info->outstream1 = tmp;
1075                             }
1076                             if (info->initack == FALSE) {
1077                                 guint16 tmp = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1078                                 if (info->instream2 < tmp) info->instream2 = tmp;
1079                             }
1080                         }
1081 
1082                         g_ptr_array_add(info->sort_tsn1, tsn_s);
1083                         info->n_array_tsn1++;
1084                     }
1085                     else if (info->direction == 2)
1086                     {
1087                         if (info->firstdata) {
1088                             info->firstdata = FALSE;
1089                             if (info->init_collision) {
1090                                 if (tsnumber != info->min_tsn2) {
1091                                     info->min_tsn2 = info->dir2->init_min_tsn;
1092                                     info->initack_dir = 2;
1093                                 }
1094                                 info->min_tsn1 = info->dir1->initack_min_tsn;
1095                             }
1096                         } else {
1097                             if(tsnumber < info->min_tsn2)
1098                                 info->min_tsn2 = tsnumber;
1099                         }
1100 
1101                         if ((info->initack && info->initack_dir == 2)&& tsnumber >= info->min_tsn2 && tsnumber <= info->max_tsn2)
1102                         {
1103                             if (datachunk)
1104                             {
1105                                 if (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID) {
1106                                     length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET) - DATA_CHUNK_HEADER_LENGTH;
1107                                 } else {
1108                                     length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET) - I_DATA_CHUNK_HEADER_LENGTH;
1109                                 }
1110                                 info->n_data_chunks_ep2++;
1111                                 info->n_data_bytes_ep2+=length;
1112                             }
1113                             else if (forwardchunk)
1114                             {
1115                                 info->n_forward_chunks_ep2++;
1116                             }
1117                         }
1118                         if (tsnumber > info->max_tsn2)
1119                         {
1120                             info->max_tsn2 = tsnumber;
1121                             if (datachunk)
1122                             {
1123                                 if (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID) {
1124                                     length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET) - DATA_CHUNK_HEADER_LENGTH;
1125                                 } else {
1126                                     length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET) - I_DATA_CHUNK_HEADER_LENGTH;
1127                                 }
1128                                 info->n_data_chunks_ep2++;
1129                                 info->n_data_bytes_ep2+=length;
1130                             }
1131                             else if (forwardchunk)
1132                             {
1133                                 info->n_forward_chunks_ep2++;
1134                             }
1135                         }
1136                         if (datachunk)
1137                         {
1138                             if (info->init == FALSE) {
1139                                 guint16 tmp = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1140                                 if (info->instream1 < tmp) info->instream1 = tmp;
1141                             }
1142                             if (info->initack == FALSE) {
1143                                 guint16 tmp = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1144                                 if (info->outstream2 < tmp) info->outstream2 = tmp;
1145                             }
1146                         }
1147 
1148                         g_ptr_array_add(info->sort_tsn2, tsn_s);
1149                         info->n_array_tsn2++;
1150                     }
1151                 }
1152                 else if (((tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_SACK_CHUNK_ID) ||
1153                             (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_NR_SACK_CHUNK_ID)) &&
1154                         sack != NULL)
1155                 {
1156                     tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET);
1157                     length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET);
1158 
1159                     if (sack->first_tsn == 0)
1160                         sack->first_tsn = tsnumber;
1161 
1162                     t_s_n = (guint8 *)g_malloc(length);
1163                     tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, length);
1164                     sack->tsns = g_list_append(sack->tsns, t_s_n);
1165                     sackchunk = TRUE;
1166                     tsn_s = g_new0(struct tsn_sort, 1);
1167                     tsn_s->tsnumber = tsnumber;
1168                     tsn_s->secs   = tsn->secs = (guint32)pinfo->rel_ts.secs;
1169                     tsn_s->usecs  = tsn->usecs = (guint32)pinfo->rel_ts.nsecs/1000;
1170                     tsn_s->offset = 0;
1171                     tsn_s->framenumber = framenumber;
1172                     tsn_s->length = tvb_get_ntohl(sctp_info->tvb[chunk_number], SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
1173 
1174                     if (tsn->secs < info->min_secs)
1175                     {
1176                         info->min_secs  = tsn->secs;
1177                         info->min_usecs = tsn->usecs;
1178                     }
1179                     else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
1180                         info->min_usecs = tsn->usecs;
1181 
1182                     if (tsn->secs > info->max_secs)
1183                     {
1184                         info->max_secs  = tsn->secs;
1185                         info->max_usecs = tsn->usecs;
1186                     }
1187                     else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
1188                         info->max_usecs = tsn->usecs;
1189 
1190 
1191                     if (info->direction == 2)
1192                     {
1193                         if(tsnumber < info->min_tsn1)
1194                             info->min_tsn1 = tsnumber;
1195                         if(tsnumber > info->max_tsn1)
1196                             info->max_tsn1 = tsnumber;
1197                         if (tsn_s->length > info->max_window1)
1198                             info->max_window1 = tsn_s->length;
1199                         g_ptr_array_add(info->sort_sack1, tsn_s);
1200                         info->n_sack_chunks_ep1++;
1201                     }
1202                     else if (info->direction == 1)
1203                     {
1204                         if(tsnumber < info->min_tsn2)
1205                             info->min_tsn2 = tsnumber;
1206                         if(tsnumber > info->max_tsn2)
1207                             info->max_tsn2 = tsnumber;
1208                         if (tsn_s->length > info->max_window2)
1209                             info->max_window2 = tsn_s->length;
1210                         g_ptr_array_add(info->sort_sack2, tsn_s);
1211                         info->n_sack_chunks_ep2++;
1212                     }
1213                 }
1214             }
1215         }
1216 
1217         if (datachunk || forwardchunk)
1218         {
1219             if (info->direction == 1)
1220                 info->tsn1 = g_list_prepend(info->tsn1, tsn);
1221             else if (info->direction == 2)
1222                 info->tsn2 = g_list_prepend(info->tsn2, tsn);
1223             tsn_used = TRUE;
1224         }
1225         if (sackchunk == TRUE)
1226         {
1227             if (info->direction == 1)
1228                 info->sack2 = g_list_prepend(info->sack2, sack);
1229             else if(info->direction == 2)
1230                 info->sack1 = g_list_prepend(info->sack1, sack);
1231             sack_used = TRUE;
1232         }
1233         info->n_tvbs += sctp_info->number_of_tvbs;
1234         sctp_tapinfo_struct.sum_tvbs += sctp_info->number_of_tvbs;
1235         info = calc_checksum(sctp_info, info);
1236         info->n_packets++;
1237     }
1238     if (tsn && !tsn_used)
1239         tsn_free(tsn);
1240     if (sack && !sack_used)
1241         tsn_free(sack);
1242     free_address(&tmp_info.src);
1243     free_address(&tmp_info.dst);
1244     return TAP_PACKET_REDRAW;
1245 }
1246 
1247 
1248 /****************************************************************************/
1249 void
remove_tap_listener_sctp_stat(void)1250 remove_tap_listener_sctp_stat(void)
1251 {
1252     if (sctp_tapinfo_struct.is_registered) {
1253         remove_tap_listener(&sctp_tapinfo_struct);
1254         sctp_tapinfo_struct.is_registered = FALSE;
1255     }
1256 }
1257 
1258 
1259 void
sctp_stat_scan(void)1260 sctp_stat_scan(void)
1261 {
1262     if (!sctp_tapinfo_struct.is_registered) {
1263         register_tap_listener_sctp_stat();
1264     }
1265 }
1266 
1267 const sctp_allassocs_info_t *
sctp_stat_get_info(void)1268 sctp_stat_get_info(void)
1269 {
1270     return &sctp_tapinfo_struct;
1271 }
1272 
1273 const sctp_assoc_info_t *
get_sctp_assoc_info(guint16 assoc_id)1274 get_sctp_assoc_info(guint16 assoc_id)
1275 {
1276     sctp_tmp_info_t needle = { .assoc_id = assoc_id };
1277     return find_assoc(&needle);
1278 }
1279 
1280 void
register_tap_listener_sctp_stat(void)1281 register_tap_listener_sctp_stat(void)
1282 {
1283     GString *error_string;
1284 
1285     if (!sctp_tapinfo_struct.is_registered)
1286     {
1287         if ((error_string = register_tap_listener("sctp", &sctp_tapinfo_struct, NULL, 0, reset, packet, NULL, NULL))) {
1288             simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", error_string->str);
1289             g_string_free(error_string, TRUE);
1290             return;
1291         }
1292         sctp_tapinfo_struct.is_registered=TRUE;
1293     }
1294 }
1295