Kerberos: add kerberos_inject_longterm_key() helper function
[wireshark-sm.git] / ui / tap-sctp-analysis.c
bloba4077befabff0d09a80653159e6ba2db167445bf
1 /*
2 * Copyright 2004-2013, Irene Ruengeler <i.ruengeler [AT] fh-muenster.de>
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
11 #include "config.h"
13 #include <string.h>
14 #include <math.h>
16 #include <glib.h>
18 #include "epan/packet_info.h"
19 #include "epan/tap.h"
20 #include "epan/value_string.h"
22 #include "ui/tap-sctp-analysis.h"
24 #include "ui/simple_dialog.h"
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
38 static sctp_allassocs_info_t sctp_tapinfo_struct;
40 static void
41 free_first(void *data, void *user_data _U_)
43 g_free(data);
46 static void
47 tsn_free(void *data)
49 tsn_t *tsn;
51 tsn = (tsn_t *) data;
52 if (tsn->tsns != NULL)
54 g_list_free_full(tsn->tsns, g_free);
56 free_address(&tsn->src);
57 free_address(&tsn->dst);
58 g_free(tsn);
61 static void
62 chunk_free(void *data)
64 sctp_addr_chunk *chunk = (sctp_addr_chunk *) data;
66 free_address(&chunk->addr);
67 g_free(chunk);
70 static void
71 store_free(void *data)
73 address *addr = (address *) data;
75 free_address(addr);
76 g_free(addr);
79 static void
80 reset(void *arg)
82 sctp_allassocs_info_t *tapdata = (sctp_allassocs_info_t *)arg;
83 GList* list;
84 sctp_assoc_info_t * info;
86 list = g_list_first(tapdata->assoc_info_list);
87 while (list)
89 info = (sctp_assoc_info_t *) (list->data);
91 if (info->addr1 != NULL)
93 g_list_free_full(info->addr1, store_free);
94 info->addr1 = NULL;
97 if (info->addr2 != NULL)
99 g_list_free_full(info->addr2, store_free);
100 info->addr2 = NULL;
103 if (info->error_info_list != NULL)
105 g_list_free_full(info->error_info_list, g_free);
106 info->error_info_list = NULL;
109 if (info->frame_numbers != NULL)
111 g_list_free(info->frame_numbers);
112 info->frame_numbers = NULL;
115 if (info->tsn1 != NULL)
117 g_list_free_full(info->tsn1, tsn_free);
118 info->tsn1 = NULL;
121 if (info->tsn2 != NULL)
123 g_list_free_full(info->tsn2, tsn_free);
124 info->tsn2 = NULL;
127 if (info->sack1 != NULL)
129 g_list_free_full(info->sack1, tsn_free);
130 info->sack1 = NULL;
133 if (info->sack2 != NULL)
135 g_list_free_full(info->sack2, tsn_free);
136 info->sack2 = NULL;
139 if (info->sort_tsn1 != NULL)
140 g_ptr_array_free(info->sort_tsn1, true);
142 if (info->sort_tsn2 != NULL)
143 g_ptr_array_free(info->sort_tsn2, true);
145 if (info->sort_sack1 != NULL)
146 g_ptr_array_free(info->sort_sack1, true);
148 if (info->sort_sack2 != NULL)
149 g_ptr_array_free(info->sort_sack2, true);
151 if (info->min_max != NULL)
153 g_slist_foreach(info->min_max, free_first, NULL);
154 info->min_max = NULL;
157 if (info->addr_chunk_count) {
158 g_list_free_full(info->addr_chunk_count, chunk_free);
161 g_free(info->dir1);
162 g_free(info->dir2);
163 free_address(&info->src);
164 free_address(&info->dst);
166 g_free(list->data);
167 list = g_list_next(list);
169 g_list_free(tapdata->assoc_info_list);
170 tapdata->sum_tvbs = 0;
171 tapdata->assoc_info_list = NULL;
175 static sctp_assoc_info_t *
176 calc_checksum(const struct _sctp_info *check_data, sctp_assoc_info_t *data)
178 bool ok = false;
180 if (check_data->adler32_calculated)
182 data->n_adler32_calculated++;
183 if (check_data->adler32_correct)
184 data->n_adler32_correct++;
186 if (check_data->crc32c_calculated)
188 data->n_crc32c_calculated++;
189 if (check_data->crc32c_correct)
190 data->n_crc32c_correct++;
192 if (data->n_adler32_calculated > 0)
194 if ((float)(data->n_adler32_correct*1.0/data->n_adler32_calculated) > 0.5)
196 char str[] = "ADLER32";
197 (void) g_strlcpy(data->checksum_type, str, 8);
198 data->n_checksum_errors=(data->n_adler32_calculated-data->n_adler32_correct);
199 ok = true;
203 if (data->n_crc32c_calculated>0)
205 if ((float)(data->n_crc32c_correct*1.0/data->n_crc32c_calculated) > 0.5)
207 char str[] = "CRC32C";
208 (void) g_strlcpy(data->checksum_type, str, 8);
209 data->n_checksum_errors=data->n_crc32c_calculated-data->n_crc32c_correct;
210 ok = true;
214 if (!ok)
216 char str[] = "UNKNOWN";
217 (void) g_strlcpy(data->checksum_type, str, 8);
218 data->n_checksum_errors=0;
221 return(data);
226 static sctp_assoc_info_t *
227 find_assoc(sctp_tmp_info_t *needle)
229 sctp_allassocs_info_t *assoc_info;
230 sctp_assoc_info_t *info = NULL;
231 GList* list;
233 assoc_info = &sctp_tapinfo_struct;
234 if ((list = g_list_last(assoc_info->assoc_info_list))!=NULL)
236 while (list)
238 info = (sctp_assoc_info_t*)(list->data);
239 if (needle->assoc_id == info->assoc_id)
240 return info;
242 list = g_list_previous(list);
245 return NULL;
248 static sctp_assoc_info_t *
249 add_chunk_count(address *vadd, sctp_assoc_info_t *info, uint32_t direction, uint32_t type)
251 GList *list;
252 sctp_addr_chunk *ch=NULL;
253 int i;
255 list = g_list_first(info->addr_chunk_count);
257 while (list)
259 ch = (sctp_addr_chunk *)(list->data);
260 if (ch->direction == direction)
262 if (addresses_equal(vadd, &ch->addr))
264 if (IS_SCTP_CHUNK_TYPE(type))
265 ch->addr_count[type]++;
266 else
267 ch->addr_count[OTHER_CHUNKS_INDEX]++;
268 return info;
270 else
272 list = g_list_next(list);
275 else
276 list = g_list_next(list);
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;
284 if (IS_SCTP_CHUNK_TYPE(type))
285 ch->addr_count[type]++;
286 else
287 ch->addr_count[OTHER_CHUNKS_INDEX]++;
289 info->addr_chunk_count = g_list_append(info->addr_chunk_count, ch);
290 return info;
293 static sctp_assoc_info_t *
294 add_address(address *vadd, sctp_assoc_info_t *info, uint16_t direction)
296 GList *list;
297 address *v=NULL;
299 if (direction == 1)
300 list = g_list_first(info->addr1);
301 else
302 list = g_list_first(info->addr2);
304 while (list)
306 v = (address *) (list->data);
307 if (addresses_equal(vadd, v)) {
308 free_address(vadd);
309 g_free(vadd);
310 return info;
312 list = g_list_next(list);
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);
320 return info;
323 static tap_packet_status
324 packet(void *tapdata _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *data, tap_flags_t flags _U_)
326 const struct _sctp_info *sctp_info = (const struct _sctp_info *)data;
327 uint32_t 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 uint16_t type, length = 0;
332 address *store = NULL;
333 tsn_t *tsn = NULL;
334 tsn_t *sack = NULL;
335 uint8_t *t_s_n = NULL;
336 bool sackchunk = false;
337 bool datachunk = false;
338 bool forwardchunk = false;
339 struct tsn_sort *tsn_s;
340 int i;
341 uint8_t idx = 0;
342 bool tsn_used = false;
343 bool sack_used = false;
345 framenumber = pinfo->num;
347 type = sctp_info->ip_src.type;
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);
354 type = sctp_info->ip_dst.type;
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);
361 tmp_info.port1 = sctp_info->sport;
362 tmp_info.port2 = sctp_info->dport;
364 if (sctp_info->vtag_reflected)
366 tmp_info.verification_tag2 = sctp_info->verification_tag;
367 tmp_info.verification_tag1 = 0;
369 else
371 tmp_info.verification_tag1 = sctp_info->verification_tag;
372 tmp_info.verification_tag2 = 0;
374 tmp_info.n_tvbs = 0;
375 if (tvb_get_uint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID)
377 tmp_info.initiate_tag = tvb_get_ntohl(sctp_info->tvb[0], 4);
379 else
381 tmp_info.initiate_tag = 0;
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)
389 tmp_info.n_tvbs = sctp_info->number_of_tvbs;
390 sctp_tapinfo_struct.sum_tvbs+=sctp_info->number_of_tvbs;
392 if (sctp_info->number_of_tvbs > 0)
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;
451 for (i=0; i < NUM_CHUNKS; i++)
453 info->chunk_count[i] = 0;
454 info->ep1_chunk_count[i] = 0;
455 info->ep2_chunk_count[i] = 0;
457 info->addr_chunk_count = NULL;
459 if (((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID) ||
460 ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID) ||
461 ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) ||
462 ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_I_DATA_CHUNK_ID) ||
463 ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID) ||
464 ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID) ||
465 ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_FORWARD_TSN_CHUNK_ID))
467 tsn = g_new0(tsn_t, 1);
468 copy_address(&tsn->src, &tmp_info.src);
469 copy_address(&tsn->dst, &tmp_info.dst);
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 = (uint32_t)pinfo->rel_ts.secs;
475 sack->usecs=tsn->usecs = (uint32_t)pinfo->rel_ts.nsecs/1000;
477 if (((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) ||
478 ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_I_DATA_CHUNK_ID) ||
479 ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID) ||
480 ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID) ||
481 ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_FORWARD_TSN_CHUNK_ID))
483 if (tsn->secs < info->min_secs)
485 info->min_secs = tsn->secs;
486 info->min_usecs = tsn->usecs;
488 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
489 info->min_usecs = tsn->usecs;
491 if (tsn->secs > info->max_secs)
493 info->max_secs = tsn->secs;
494 info->max_usecs = tsn->usecs;
496 else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
497 info->max_usecs = tsn->usecs;
500 sack->frame_number = tsn->frame_number = pinfo->num;
502 if ((tvb_get_uint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID) || (tvb_get_uint8(sctp_info->tvb[0],0) == SCTP_INIT_ACK_CHUNK_ID))
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++)
511 type = tvb_get_ntohs(sctp_info->tvb[chunk_number],0);
512 if (type == IPV4ADDRESS_PARAMETER_ID)
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);
518 else if (type == IPV6ADDRESS_PARAMETER_ID)
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);
526 if (tvb_get_uint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID)
528 info->init = true;
530 else
532 info->initack_dir = 1;
533 info->initack = true;
536 idx = tvb_get_uint8(sctp_info->tvb[0],0);
537 if (!IS_SCTP_CHUNK_TYPE(idx))
538 idx = OTHER_CHUNKS_INDEX;
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_uint8(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_uint8(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;
553 } else {
554 if (tvb_get_uint8(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_uint8(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;
565 else
567 if (((tvb_get_uint8(sctp_info->tvb[0],0)) != SCTP_INIT_CHUNK_ID) &&
568 ((tvb_get_uint8(sctp_info->tvb[0],0)) != SCTP_INIT_ACK_CHUNK_ID) &&
569 ((tvb_get_uint8(sctp_info->tvb[0],0)) != SCTP_DATA_CHUNK_ID) &&
570 ((tvb_get_uint8(sctp_info->tvb[0],0)) != SCTP_I_DATA_CHUNK_ID) &&
571 ((tvb_get_uint8(sctp_info->tvb[0],0)) != SCTP_SACK_CHUNK_ID) &&
572 ((tvb_get_uint8(sctp_info->tvb[0],0)) != SCTP_NR_SACK_CHUNK_ID) &&
573 ((tvb_get_uint8(sctp_info->tvb[0],0)) != SCTP_FORWARD_TSN_CHUNK_ID))
575 tsn = g_new0(tsn_t, 1);
576 sack = g_new0(tsn_t, 1);
578 for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
580 idx = tvb_get_uint8(sctp_info->tvb[0],0);
581 if (!IS_SCTP_CHUNK_TYPE(idx))
582 idx = OTHER_CHUNKS_INDEX;
584 info->chunk_count[idx]++;
585 info->ep1_chunk_count[idx]++;
586 info = add_chunk_count(&tmp_info.src, info, 1, idx);
588 if ((tvb_get_uint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID) ||
589 (tvb_get_uint8(sctp_info->tvb[chunk_number],0) == SCTP_I_DATA_CHUNK_ID))
591 datachunk = true;
592 if (tvb_get_uint8(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;
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;
601 if ((tvb_get_uint8(sctp_info->tvb[chunk_number],0) == SCTP_FORWARD_TSN_CHUNK_ID))
603 forwardchunk = true;
604 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET);
605 info->n_forward_chunks++;
607 if (datachunk || forwardchunk)
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)
615 if (datachunk)
617 info->n_data_chunks_ep1++;
618 info->n_data_bytes_ep1+=length;
620 else
621 info->n_forward_chunks_ep1++;
622 info->max_tsn1 = tsnumber;
624 if (tsn->first_tsn == 0)
625 tsn->first_tsn = tsnumber;
626 if (datachunk)
628 t_s_n = (uint8_t *)g_malloc(16);
629 tvb_memcpy(sctp_info->tvb[chunk_number], (uint8_t *)(t_s_n),0, 16);
631 else
633 t_s_n = (uint8_t *)g_malloc(length);
634 tvb_memcpy(sctp_info->tvb[chunk_number], (uint8_t *)(t_s_n),0, length);
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 = (uint32_t)pinfo->rel_ts.secs;
640 tsn_s->usecs = tsn->usecs = (uint32_t)pinfo->rel_ts.nsecs/1000;
641 tsn_s->offset = 0;
642 tsn_s->framenumber = framenumber;
643 if (datachunk)
644 if (tvb_get_uint8(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;
649 else
650 tsn_s->length = length;
651 if (tsn->secs < info->min_secs)
653 info->min_secs = tsn->secs;
654 info->min_usecs = tsn->usecs;
656 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
657 info->min_usecs = tsn->usecs;
659 if (tsn->secs > info->max_secs)
661 info->max_secs = tsn->secs;
662 info->max_usecs = tsn->usecs;
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++;
669 if ((tvb_get_uint8(sctp_info->tvb[chunk_number],0) == SCTP_SACK_CHUNK_ID) ||
670 (tvb_get_uint8(sctp_info->tvb[chunk_number],0) == SCTP_NR_SACK_CHUNK_ID) )
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 = (uint8_t *)g_malloc(length);
681 tvb_memcpy(sctp_info->tvb[chunk_number], (uint8_t *)(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 = (uint32_t)pinfo->rel_ts.secs;
687 tsn_s->usecs = tsn->usecs = (uint32_t)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)
695 info->min_secs = tsn->secs;
696 info->min_usecs = tsn->usecs;
698 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
699 info->min_usecs = tsn->usecs;
701 if (tsn->secs > info->max_secs)
703 info->max_secs = tsn->secs;
704 info->max_usecs = tsn->usecs;
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++;
713 if (info->verification_tag1 != 0 || info->verification_tag2 != 0)
715 uint32_t 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;
731 if (sackchunk == true) {
732 info->sack2 = g_list_prepend(info->sack2, sack);
733 sack_used = true;
735 sctp_tapinfo_struct.assoc_info_list = g_list_append(sctp_tapinfo_struct.assoc_info_list, info);
737 else
739 char* 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_uint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID)
745 tmp_str = val_to_str_wmem(NULL, tvb_get_uint8(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);
749 else
751 for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
753 tmp_str = val_to_str_wmem(NULL, tvb_get_uint8(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);
758 error->info_text = "INFOS";
759 info->error_info_list = g_list_append(info->error_info_list, error);
762 } /* endif (!info) */
763 else
765 uint32_t number;
766 info->direction = sctp_info->direction;
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;
773 if (((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID) ||
774 ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID) ||
775 ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) ||
776 ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_I_DATA_CHUNK_ID) ||
777 ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID) ||
778 ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID) ||
779 ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_FORWARD_TSN_CHUNK_ID))
782 tsn = g_new0(tsn_t, 1);
783 copy_address(&tsn->src, &tmp_info.src);
784 copy_address(&tsn->dst, &tmp_info.dst);
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 = (uint32_t)pinfo->rel_ts.secs;
790 sack->usecs=tsn->usecs = (uint32_t)pinfo->rel_ts.nsecs/1000;
792 if (((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) ||
793 ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_I_DATA_CHUNK_ID) ||
794 ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID) ||
795 ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID) ||
796 ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_FORWARD_TSN_CHUNK_ID))
798 if (tsn->secs < info->min_secs)
800 info->min_secs = tsn->secs;
801 info->min_usecs = tsn->usecs;
803 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
804 info->min_usecs = tsn->usecs;
806 if (tsn->secs > info->max_secs)
808 info->max_secs = tsn->secs;
809 info->max_usecs = tsn->usecs;
811 else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
812 info->max_usecs = tsn->usecs;
814 sack->frame_number = tsn->frame_number = pinfo->num;
816 number = pinfo->num;
817 info->frame_numbers=g_list_prepend(info->frame_numbers, GUINT_TO_POINTER(number));
819 store = g_new(address, 1);
820 copy_address(store, &tmp_info.src);
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;
834 store = g_new(address, 1);
835 copy_address(store, &tmp_info.dst);
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;
849 if (((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID) ||
850 ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID))
852 tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], INIT_CHUNK_INITIAL_TSN_OFFSET);
853 if (info->direction == 2)
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;
865 else if (info->direction == 1)
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;
878 idx = tvb_get_uint8(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++)
889 type = tvb_get_ntohs(sctp_info->tvb[chunk_number],0);
890 if (type == IPV4ADDRESS_PARAMETER_ID)
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);
896 else if (type == IPV6ADDRESS_PARAMETER_ID)
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);
903 if (info->direction == 1) {
904 if (info->dir1->init || info->dir1->initack) {
905 info->init_collision = true;
907 if (tvb_get_uint8(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_uint8(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);
918 } else {
919 if (info->dir2->init || info->dir2->initack) {
920 info->init_collision = true;
922 if (tvb_get_uint8(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_uint8(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);
934 if ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID)
936 info->initack = true;
937 info->initack_dir = info->direction;
939 else if ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID)
941 info->init = true;
944 else
946 if (((tvb_get_uint8(sctp_info->tvb[0],0)) != SCTP_INIT_ACK_CHUNK_ID) &&
947 ((tvb_get_uint8(sctp_info->tvb[0],0)) != SCTP_DATA_CHUNK_ID) &&
948 ((tvb_get_uint8(sctp_info->tvb[0],0)) != SCTP_I_DATA_CHUNK_ID) &&
949 ((tvb_get_uint8(sctp_info->tvb[0],0)) != SCTP_SACK_CHUNK_ID) &&
950 ((tvb_get_uint8(sctp_info->tvb[0],0)) != SCTP_NR_SACK_CHUNK_ID) &&
951 ((tvb_get_uint8(sctp_info->tvb[0],0)) != SCTP_FORWARD_TSN_CHUNK_ID))
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;
962 for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
964 idx = tvb_get_uint8(sctp_info->tvb[chunk_number],0);
965 if (!IS_SCTP_CHUNK_TYPE(idx))
966 idx = OTHER_CHUNKS_INDEX;
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);
975 if ((tvb_get_uint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID) ||
976 (tvb_get_uint8(sctp_info->tvb[chunk_number],0) == SCTP_I_DATA_CHUNK_ID))
977 datachunk = true;
978 if (tvb_get_uint8(sctp_info->tvb[chunk_number],0) == SCTP_FORWARD_TSN_CHUNK_ID)
979 forwardchunk = true;
980 if ((datachunk || forwardchunk) && tsn != NULL)
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)
987 t_s_n = (uint8_t *)g_malloc(16);
988 tvb_memcpy(sctp_info->tvb[chunk_number], (uint8_t *)(t_s_n),0, 16);
989 if (tvb_get_uint8(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;
994 info->n_data_chunks++;
995 info->n_data_bytes+=length;
997 else
999 length=tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET);
1000 t_s_n = (uint8_t *)g_malloc(length);
1001 tvb_memcpy(sctp_info->tvb[chunk_number], (uint8_t *)(t_s_n),0, length);
1002 info->n_forward_chunks++;
1004 tsn->tsns = g_list_append(tsn->tsns, t_s_n);
1006 tsn_s = g_new0(struct tsn_sort, 1);
1007 tsn_s->tsnumber = tsnumber;
1008 tsn_s->secs = tsn->secs = (uint32_t)pinfo->rel_ts.secs;
1009 tsn_s->usecs = tsn->usecs = (uint32_t)pinfo->rel_ts.nsecs/1000;
1010 tsn_s->offset = 0;
1011 tsn_s->framenumber = framenumber;
1012 tsn_s->length = length;
1014 if (tsn->secs < info->min_secs)
1016 info->min_secs = tsn->secs;
1017 info->min_usecs = tsn->usecs;
1019 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
1020 info->min_usecs = tsn->usecs;
1022 if (tsn->secs > info->max_secs)
1024 info->max_secs = tsn->secs;
1025 info->max_usecs = tsn->usecs;
1027 else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
1028 info->max_usecs = tsn->usecs;
1030 if (info->direction == 1)
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;
1038 info->min_tsn2 = info->dir2->initack_min_tsn;
1040 } else {
1041 if(tsnumber < info->min_tsn1) {
1042 info->min_tsn1 = tsnumber;
1045 if ((info->init || (info->initack && info->initack_dir == 1))&& tsnumber >= info->min_tsn1 && tsnumber <= info->max_tsn1)
1047 if (datachunk)
1049 info->n_data_chunks_ep1++;
1050 info->n_data_bytes_ep1 += length;
1052 else if (forwardchunk)
1054 info->n_forward_chunks_ep1++;
1057 if(tsnumber > info->max_tsn1)
1059 info->max_tsn1 = tsnumber;
1060 if (datachunk)
1062 info->n_data_chunks_ep1++;
1063 info->n_data_bytes_ep1 += length;
1065 else if (forwardchunk)
1067 info->n_forward_chunks_ep1++;
1070 if (datachunk)
1072 if (info->init == false) {
1073 uint16_t tmp = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1074 if (info->outstream1 < tmp) info->outstream1 = tmp;
1076 if (info->initack == false) {
1077 uint16_t tmp = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1078 if (info->instream2 < tmp) info->instream2 = tmp;
1082 g_ptr_array_add(info->sort_tsn1, tsn_s);
1083 info->n_array_tsn1++;
1085 else if (info->direction == 2)
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;
1094 info->min_tsn1 = info->dir1->initack_min_tsn;
1096 } else {
1097 if(tsnumber < info->min_tsn2)
1098 info->min_tsn2 = tsnumber;
1101 if ((info->initack && info->initack_dir == 2)&& tsnumber >= info->min_tsn2 && tsnumber <= info->max_tsn2)
1103 if (datachunk)
1105 if (tvb_get_uint8(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;
1110 info->n_data_chunks_ep2++;
1111 info->n_data_bytes_ep2+=length;
1113 else if (forwardchunk)
1115 info->n_forward_chunks_ep2++;
1118 if (tsnumber > info->max_tsn2)
1120 info->max_tsn2 = tsnumber;
1121 if (datachunk)
1123 if (tvb_get_uint8(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;
1128 info->n_data_chunks_ep2++;
1129 info->n_data_bytes_ep2+=length;
1131 else if (forwardchunk)
1133 info->n_forward_chunks_ep2++;
1136 if (datachunk)
1138 if (info->init == false) {
1139 uint16_t tmp = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1140 if (info->instream1 < tmp) info->instream1 = tmp;
1142 if (info->initack == false) {
1143 uint16_t tmp = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1144 if (info->outstream2 < tmp) info->outstream2 = tmp;
1148 g_ptr_array_add(info->sort_tsn2, tsn_s);
1149 info->n_array_tsn2++;
1152 else if (((tvb_get_uint8(sctp_info->tvb[chunk_number],0) == SCTP_SACK_CHUNK_ID) ||
1153 (tvb_get_uint8(sctp_info->tvb[chunk_number],0) == SCTP_NR_SACK_CHUNK_ID)) &&
1154 sack != NULL)
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);
1159 if (sack->first_tsn == 0)
1160 sack->first_tsn = tsnumber;
1162 t_s_n = (uint8_t *)g_malloc(length);
1163 tvb_memcpy(sctp_info->tvb[chunk_number], (uint8_t *)(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 = (uint32_t)pinfo->rel_ts.secs;
1169 tsn_s->usecs = tsn->usecs = (uint32_t)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);
1174 if (tsn->secs < info->min_secs)
1176 info->min_secs = tsn->secs;
1177 info->min_usecs = tsn->usecs;
1179 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
1180 info->min_usecs = tsn->usecs;
1182 if (tsn->secs > info->max_secs)
1184 info->max_secs = tsn->secs;
1185 info->max_usecs = tsn->usecs;
1187 else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
1188 info->max_usecs = tsn->usecs;
1191 if (info->direction == 2)
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++;
1202 else if (info->direction == 1)
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++;
1217 if (datachunk || forwardchunk)
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;
1225 if (sackchunk == true)
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;
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++;
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;
1248 /****************************************************************************/
1249 void
1250 remove_tap_listener_sctp_stat(void)
1252 if (sctp_tapinfo_struct.is_registered) {
1253 remove_tap_listener(&sctp_tapinfo_struct);
1254 sctp_tapinfo_struct.is_registered = false;
1259 void
1260 sctp_stat_scan(void)
1262 if (!sctp_tapinfo_struct.is_registered) {
1263 register_tap_listener_sctp_stat();
1267 const sctp_allassocs_info_t *
1268 sctp_stat_get_info(void)
1270 return &sctp_tapinfo_struct;
1273 const sctp_assoc_info_t *
1274 get_sctp_assoc_info(uint16_t assoc_id)
1276 sctp_tmp_info_t needle = { .assoc_id = assoc_id };
1277 return find_assoc(&needle);
1280 void
1281 register_tap_listener_sctp_stat(void)
1283 GString *error_string;
1285 if (!sctp_tapinfo_struct.is_registered)
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;
1292 sctp_tapinfo_struct.is_registered=true;