2 * Copyright 2004, Irene Ruengeler <i.ruengeler [AT] fh-muenster.de>
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
32 #include "epan/packet_info.h"
34 #include "epan/address.h"
35 #include <epan/strutil.h>
37 #include "ui/simple_dialog.h"
39 #include "ui/gtk/dlg_utils.h"
40 #include "ui/gtk/sctp_stat.h"
41 #include "ui/gtk/main.h"
43 #define SCTP_ABORT_CHUNK_T_BIT 0x01
45 #define PARAMETER_TYPE_LENGTH 2
46 #define PARAMETER_LENGTH_LENGTH 2
47 #define PARAMETER_HEADER_LENGTH (PARAMETER_TYPE_LENGTH + PARAMETER_LENGTH_LENGTH)
49 #define PARAMETER_HEADER_OFFSET 0
50 #define PARAMETER_TYPE_OFFSET PARAMETER_HEADER_OFFSET
51 #define PARAMETER_LENGTH_OFFSET (PARAMETER_TYPE_OFFSET + PARAMETER_TYPE_LENGTH)
52 #define PARAMETER_VALUE_OFFSET (PARAMETER_LENGTH_OFFSET + PARAMETER_LENGTH_LENGTH)
54 #define IPV6_ADDRESS_LENGTH 16
55 #define IPV6_ADDRESS_OFFSET PARAMETER_VALUE_OFFSET
56 #define IPV4_ADDRESS_LENGTH 4
57 #define IPV4_ADDRESS_OFFSET PARAMETER_VALUE_OFFSET
58 #define IPV4ADDRESS_PARAMETER_ID 0x0005
59 #define IPV6ADDRESS_PARAMETER_ID 0x0006
61 #define SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH 4
62 #define SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET (CHUNK_VALUE_OFFSET + 0)
63 #define SACK_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH 4
64 #define SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET (SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET + \
65 SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH)
67 #define INIT_CHUNK_INITIAL_TSN_LENGTH 4
68 #define INIT_CHUNK_FIXED_PARAMTERS_LENGTH (INIT_CHUNK_INITIATE_TAG_LENGTH + \
69 INIT_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH + \
70 INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_LENGTH + \
71 INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_LENGTH + \
72 INIT_CHUNK_INITIAL_TSN_LENGTH)
73 #define CHUNK_HEADER_LENGTH (CHUNK_TYPE_LENGTH + \
74 CHUNK_FLAGS_LENGTH + \
76 #define INIT_CHUNK_VARIABLE_LENGTH_PARAMETER_OFFSET (INIT_CHUNK_INITIAL_TSN_OFFSET + \
77 INIT_CHUNK_INITIAL_TSN_LENGTH )
79 static const value_string chunk_type_values[] = {
80 { SCTP_DATA_CHUNK_ID, "DATA" },
81 { SCTP_INIT_CHUNK_ID, "INIT" },
82 { SCTP_INIT_ACK_CHUNK_ID, "INIT_ACK" },
83 { SCTP_SACK_CHUNK_ID, "SACK" },
84 { SCTP_HEARTBEAT_CHUNK_ID, "HEARTBEAT" },
85 { SCTP_HEARTBEAT_ACK_CHUNK_ID, "HEARTBEAT_ACK" },
86 { SCTP_ABORT_CHUNK_ID, "ABORT" },
87 { SCTP_SHUTDOWN_CHUNK_ID, "SHUTDOWN" },
88 { SCTP_SHUTDOWN_ACK_CHUNK_ID, "SHUTDOWN_ACK" },
89 { SCTP_ERROR_CHUNK_ID, "ERROR" },
90 { SCTP_COOKIE_ECHO_CHUNK_ID, "COOKIE_ECHO" },
91 { SCTP_COOKIE_ACK_CHUNK_ID, "COOKIE_ACK" },
92 { SCTP_ECNE_CHUNK_ID, "ECNE" },
93 { SCTP_CWR_CHUNK_ID, "CWR" },
94 { SCTP_SHUTDOWN_COMPLETE_CHUNK_ID, "SHUTDOWN_COMPLETE" },
95 { SCTP_FORWARD_TSN_CHUNK_ID, "FORWARD TSN" },
96 { SCTP_ASCONF_ACK_CHUNK_ID, "ASCONF_ACK" },
97 { SCTP_PKTDROP_CHUNK_ID, "PKTDROP" },
98 { SCTP_ASCONF_CHUNK_ID, "ASCONF" },
99 { SCTP_IETF_EXT, "IETF_EXTENSION" },
100 { SCTP_NR_SACK_CHUNK_ID, "NR_SACK" },
101 { SCTP_AUTH_CHUNK_ID, "AUTH" },
105 #define FORWARD_STREAM 0
106 #define BACKWARD_STREAM 1
107 #define FORWARD_ADD_FORWARD_VTAG 2
108 #define BACKWARD_ADD_FORWARD_VTAG 3
109 #define BACKWARD_ADD_BACKWARD_VTAG 4
110 #define ADDRESS_FORWARD_STREAM 5
111 #define ADDRESS_BACKWARD_STREAM 6
112 #define ADDRESS_FORWARD_ADD_FORWARD_VTAG 7
113 #define ADDRESS_BACKWARD_ADD_FORWARD_VTAG 8
114 #define ADDRESS_BACKWARD_ADD_BACKWARD_VTAG 9
115 #define ASSOC_NOT_FOUND 10
117 static sctp_allassocs_info_t sctp_tapinfo_struct = {0, NULL, FALSE, NULL};
120 void free_first(gpointer data, gpointer user_data _U_)
125 static void tsn_free(gpointer data, gpointer user_data _U_)
129 tsn = (tsn_t *) data;
130 if (tsn->tsns != NULL)
132 g_list_foreach(tsn->tsns, free_first, NULL);
133 g_list_free(tsn->tsns);
139 static void reset(void *arg)
141 sctp_allassocs_info_t *tapdata = arg;
143 sctp_assoc_info_t * info;
145 list = g_list_first(tapdata->assoc_info_list);
148 info = (sctp_assoc_info_t *) (list->data);
150 if (info->addr1 != NULL)
152 g_list_foreach(info->addr1, free_first, NULL);
153 g_list_free(info->addr1);
157 if (info->addr2 != NULL)
159 g_list_foreach(info->addr2,free_first, NULL);
160 g_list_free(info->addr2);
164 if (info->error_info_list != NULL)
166 g_list_foreach(info->error_info_list, free_first, NULL);
167 g_list_free(info->error_info_list);
168 info->error_info_list = NULL;
171 if (info->frame_numbers != NULL)
173 g_list_free(info->frame_numbers);
174 info->frame_numbers = NULL;
177 if (info->tsn1 != NULL)
179 g_list_foreach(info->tsn1, tsn_free, NULL);
180 g_list_free(info->tsn1);
184 if (info->tsn2 != NULL)
186 g_list_foreach(info->tsn2, tsn_free, NULL);
187 g_list_free(info->tsn2);
191 if (info->sack1 != NULL)
193 g_list_foreach(info->sack1, tsn_free, NULL);
194 g_list_free(info->sack1);
198 if (info->sack2 != NULL)
200 g_list_foreach(info->sack2, tsn_free, NULL);
201 g_list_free(info->sack2);
205 if (info->sort_tsn1 != NULL)
206 g_ptr_array_free(info->sort_tsn1, TRUE);
208 if (info->sort_tsn2 != NULL)
209 g_ptr_array_free(info->sort_tsn2, TRUE);
211 if (info->sort_sack1 != NULL)
212 g_ptr_array_free(info->sort_sack1, TRUE);
214 if (info->sort_sack2 != NULL)
215 g_ptr_array_free(info->sort_sack2, TRUE);
217 if (info->min_max != NULL)
219 g_slist_foreach(info->min_max, free_first, NULL);
220 info->min_max = NULL;
224 list = g_list_next(list);
226 g_list_free(tapdata->assoc_info_list);
227 tapdata->sum_tvbs = 0;
228 tapdata->assoc_info_list = NULL;
232 static sctp_assoc_info_t *calc_checksum(struct _sctp_info *check_data, sctp_assoc_info_t *data)
236 if (check_data->adler32_calculated)
238 data->n_adler32_calculated++;
239 if (check_data->adler32_correct)
240 data->n_adler32_correct++;
242 if (check_data->crc32c_calculated)
244 data->n_crc32c_calculated++;
245 if (check_data->crc32c_correct)
246 data->n_crc32c_correct++;
248 if (data->n_adler32_calculated > 0)
250 if ((float)(data->n_adler32_correct*1.0/data->n_adler32_calculated) > 0.5)
252 g_strlcpy(data->checksum_type,"ADLER32",8);
253 data->n_checksum_errors=(data->n_adler32_calculated-data->n_adler32_correct);
258 if (data->n_crc32c_calculated>0)
260 if ((float)(data->n_crc32c_correct*1.0/data->n_crc32c_calculated) > 0.5)
262 g_strlcpy(data->checksum_type,"CRC32C",8);
263 data->n_checksum_errors=data->n_crc32c_calculated-data->n_crc32c_correct;
270 g_strlcpy(data->checksum_type,"UNKNOWN",8);
271 data->n_checksum_errors=0;
279 /* XXX: Some versions of gcc warn about "breaking strict aliasing rules"
280 for 'a' in the following (given the way this function is called).
281 As a workaround we'll define the function parameters to match
282 how this function is actually called. */
284 static gint sctp_assoc_vtag_cmp(gconstpointer aa, gconstpointer bb)
286 const struct _sctp_assoc_info* a = aa;
287 const struct _sctp_assoc_info* b = bb;
289 return(FORWARD_STREAM);
292 static gint sctp_assoc_vtag_cmp(const sctp_tmp_info_t *a, const sctp_assoc_info_t *b)
295 if (a == NULL || b == NULL)
296 return(ASSOC_NOT_FOUND);
298 if ((a->port1 == b->port1) &&
299 (a->port2 == b->port2) &&
300 (a->verification_tag1 == b->verification_tag1) && a->verification_tag1==0 && a->initiate_tag != 0 &&
301 (a->initiate_tag != b->initiate_tag ))
302 return(ASSOC_NOT_FOUND); /* two INITs that belong to different assocs */
305 if ((a->port1 == b->port1) &&
306 (a->port2 == b->port2) &&
307 (a->verification_tag1 == b->verification_tag1) &&
308 ((a->verification_tag1 != 0 ||
309 (b->verification_tag2 != 0))))
310 return(FORWARD_STREAM);
312 /* ABORT, vtag reflected */
313 if ((a->port1 == b->port1) &&
314 (a->port2 == b->port2) &&
315 (a->verification_tag2 == b->verification_tag2) &&
316 (a->verification_tag1 == 0 && b->verification_tag1 != 0))
317 return(FORWARD_STREAM);
319 if ((a->port1 == b->port2) &&
320 (a->port2 == b->port1) &&
321 (a->verification_tag1 == b->verification_tag2) &&
322 (a->verification_tag1 != 0))
323 return(BACKWARD_STREAM);
325 if ((a->port1 == b->port2) &&
326 (a->port2 == b->port1) &&
327 (a->verification_tag2 == b->verification_tag1) &&
328 (a->verification_tag2 != 0))
329 return(BACKWARD_STREAM);
331 /* ABORT, vtag reflected */
332 if ((a->port1 == b->port2) &&
333 (a->port2 == b->port1) &&
334 (a->verification_tag2 == b->verification_tag1) &&
335 (a->verification_tag1 == 0 && b->verification_tag2 != 0))
336 return(BACKWARD_STREAM);
338 /*forward stream verifivation tag can be added*/
339 if ((a->port1 == b->port1) &&
340 (a->port2 == b->port2) &&
341 (a->verification_tag1 != 0) &&
342 (b->verification_tag1 == 0) &&
343 (b->verification_tag2 !=0))
344 return (FORWARD_ADD_FORWARD_VTAG);
346 if ((a->port1 == b->port2) &&
347 (a->port2 == b->port1) &&
348 (a->verification_tag1 == b->verification_tag2) &&
349 (b->verification_tag1 == 0))
350 return (BACKWARD_ADD_FORWARD_VTAG);
352 /*backward stream verification tag can be added */
353 if ((a->port1 == b->port2) &&
354 (a->port2 == b->port1) &&
355 (a->verification_tag1 !=0) &&
356 (b->verification_tag1 != 0) &&
357 (b->verification_tag2 == 0))
358 return(BACKWARD_ADD_BACKWARD_VTAG);
360 return(ASSOC_NOT_FOUND);
363 static sctp_assoc_info_t * find_assoc(sctp_tmp_info_t * needle)
365 sctp_allassocs_info_t *assoc_info;
366 sctp_assoc_info_t *info = NULL;
370 assoc_info = &sctp_tapinfo_struct;
371 if ((list = g_list_last(assoc_info->assoc_info_list))!=NULL)
375 cmp=sctp_assoc_vtag_cmp(needle, (sctp_assoc_info_t*)(list->data));
377 /*if (cmp==ASSOC_NOT_FOUND)
379 cmp=sctp_assoc_address_cmp(needle, (sctp_assoc_info_t*)(list->data));
384 info = (sctp_assoc_info_t*)(list->data);
387 case BACKWARD_STREAM:
388 info = (sctp_assoc_info_t*)(list->data);
391 case FORWARD_ADD_FORWARD_VTAG:
392 info = (sctp_assoc_info_t*)(list->data);
393 info->verification_tag1=needle->verification_tag1;
396 case BACKWARD_ADD_FORWARD_VTAG:
397 info = (sctp_assoc_info_t*)(list->data);
398 info->verification_tag1=needle->verification_tag1;
401 case BACKWARD_ADD_BACKWARD_VTAG:
402 info = (sctp_assoc_info_t*)(list->data);
403 info->verification_tag2=needle->verification_tag1;
406 case ADDRESS_FORWARD_STREAM:
407 info = (sctp_assoc_info_t*)(list->data);
409 info->check_address=TRUE;
411 case ADDRESS_BACKWARD_STREAM:
412 info = (sctp_assoc_info_t*)(list->data);
414 info->check_address=TRUE;
416 case ADDRESS_FORWARD_ADD_FORWARD_VTAG:
417 info = (sctp_assoc_info_t*)(list->data);
418 info->verification_tag1=needle->verification_tag1;
420 info->check_address=TRUE;
422 case ADDRESS_BACKWARD_ADD_FORWARD_VTAG:
423 info = (sctp_assoc_info_t*)(list->data);
424 info->verification_tag1=needle->verification_tag1;
426 info->check_address=TRUE;
428 case ADDRESS_BACKWARD_ADD_BACKWARD_VTAG:
429 info = (sctp_assoc_info_t*)(list->data);
430 info->verification_tag2=needle->verification_tag1;
432 info->check_address=TRUE;
436 list = g_list_previous(list);
442 static sctp_assoc_info_t * add_chunk_count(address * vadd, sctp_assoc_info_t * info, guint32 direction, guint32 type)
446 sctp_addr_chunk *ch=NULL;
450 list = g_list_first(info->addr_chunk_count);
454 ch = (sctp_addr_chunk *)(list->data);
455 if (ch->direction == direction)
457 v = (address *) (ch->addr);
458 if (ADDRESSES_EQUAL(vadd, v))
460 if (IS_SCTP_CHUNK_TYPE(type))
461 ch->addr_count[type]++;
463 ch->addr_count[OTHER_CHUNKS_INDEX]++;
468 list = g_list_next(list);
472 list = g_list_next(list);
474 ch = g_malloc(sizeof(sctp_addr_chunk));
475 ch->direction = direction;
476 ch->addr = g_malloc(sizeof(address));
477 ch->addr->type = vadd->type;
478 ch->addr->len = vadd->len;
479 dat = g_malloc(vadd->len);
480 memcpy(dat, vadd->data, vadd->len);
481 ch->addr->data = dat;
482 for (i=0; i < NUM_CHUNKS; i++)
483 ch->addr_count[i] = 0;
485 if (IS_SCTP_CHUNK_TYPE(type))
486 ch->addr_count[type]++;
488 ch->addr_count[OTHER_CHUNKS_INDEX]++;
490 info->addr_chunk_count = g_list_append(info->addr_chunk_count, ch);
494 static sctp_assoc_info_t * add_address(address * vadd, sctp_assoc_info_t *info, guint8 direction)
500 list = g_list_first(info->addr1);
502 list = g_list_first(info->addr2);
506 v = (address *) (list->data);
507 if (ADDRESSES_EQUAL(vadd, v)) {
511 list = g_list_next(list);
515 info->addr1 = g_list_append(info->addr1, vadd);
516 else if (direction==2)
517 info->addr2 = g_list_append(info->addr2, vadd);
523 packet(void *tapdata _U_, packet_info *pinfo , epan_dissect_t *edt _U_ , const void *data)
525 struct _sctp_info *sctp_info;
526 guint32 chunk_number = 0, tsnumber,framenumber;
527 sctp_tmp_info_t tmp_info;
528 sctp_assoc_info_t *info = NULL;
529 sctp_error_info_t *error = NULL;
530 guint16 type, length;
531 address *store = NULL;
534 guint8 *t_s_n = NULL;
535 gboolean sackchunk = FALSE;
536 gboolean datachunk = FALSE;
537 struct tsn_sort *tsn_s;
542 sctp_info = (struct _sctp_info *) data;
544 framenumber=pinfo->fd->num;
546 type = sctp_info->ip_src.type;
550 tmp_info.src.type = AT_IPv4;
551 tmp_info.src.len = 4;
553 else if (type == AT_IPv6)
555 tmp_info.src.type = AT_IPv6;
556 tmp_info.src.len = 16;
560 tmp_info.src.type = AT_NONE;
561 tmp_info.src.len = 0;
564 addr = g_malloc(tmp_info.src.len);
565 memcpy(addr, sctp_info->ip_src.data, tmp_info.src.len);
566 tmp_info.src.data = addr;
568 type = sctp_info->ip_dst.type;
572 tmp_info.dst.type = AT_IPv4;
573 tmp_info.dst.len = 4;
575 else if (type == AT_IPv6)
577 tmp_info.dst.type = AT_IPv6;
578 tmp_info.dst.len = 16;
582 tmp_info.dst.type = AT_NONE;
583 tmp_info.dst.len = 0;
586 addr = g_malloc(tmp_info.dst.len);
587 memcpy(addr, sctp_info->ip_dst.data, tmp_info.dst.len);
588 tmp_info.dst.data = addr;
590 tmp_info.port1 = sctp_info->sport;
591 tmp_info.port2 = sctp_info->dport;
593 if (sctp_info->vtag_reflected)
595 tmp_info.verification_tag2 = sctp_info->verification_tag;
596 tmp_info.verification_tag1 = 0;
600 tmp_info.verification_tag1 = sctp_info->verification_tag;
601 tmp_info.verification_tag2 = 0;
604 if (tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID)
606 tmp_info.initiate_tag = tvb_get_ntohl(sctp_info->tvb[0], 4);
610 tmp_info.initiate_tag = 0;
613 info = find_assoc(&tmp_info);
616 tmp_info.n_tvbs = sctp_info->number_of_tvbs;
617 sctp_tapinfo_struct.sum_tvbs+=sctp_info->number_of_tvbs;
619 if (sctp_info->number_of_tvbs > 0)
621 info = g_malloc(sizeof(sctp_assoc_info_t));
622 memset(info, 0, sizeof(sctp_assoc_info_t));
623 info->src.type = tmp_info.src.type;
624 info->src.len = tmp_info.src.len;
625 addr = g_malloc(tmp_info.dst.len);
626 memcpy(addr,(tmp_info.src.data), tmp_info.src.len);
627 info->src.data = addr;
628 info->dst.type = tmp_info.dst.type;
629 info->dst.len = tmp_info.dst.len;
630 addr = g_malloc(tmp_info.dst.len);
631 memcpy(addr, (tmp_info.dst.data), tmp_info.dst.len);
632 info->dst.data = addr;
633 info->port1 = tmp_info.port1;
634 info->port2 = tmp_info.port2;
635 info->verification_tag1 = tmp_info.verification_tag1;
636 info->verification_tag2 = tmp_info.verification_tag2;
637 info->initiate_tag = tmp_info.initiate_tag;
638 info->n_tvbs = tmp_info.n_tvbs;
640 info->initack = FALSE;
641 info->check_address = FALSE;
643 info = calc_checksum(sctp_info, info);
645 info->error_info_list = NULL;
646 info->min_secs = 0xffffffff;
647 info->min_usecs = 0xffffffff;
650 info->min_tsn2 = 0xFFFFFFFF;
651 info->min_tsn1 = 0xffffffff;
654 info->max_bytes1 = 0;
655 info->max_bytes2 = 0;
656 info->n_data_chunks = 0;
657 info->n_data_bytes = 0;
658 info->n_data_chunks_ep1 = 0;
659 info->n_data_bytes_ep1 = 0;
660 info->n_data_chunks_ep2 = 0;
661 info->n_data_bytes_ep2 = 0;
662 info->n_sack_chunks_ep1 = 0;
663 info->n_sack_chunks_ep2 = 0;
664 info->n_array_tsn1 = 0;
665 info->n_array_tsn2 = 0;
666 info->max_window1 = 0;
667 info->max_window2 = 0;
668 info->min_max = NULL;
669 info->sort_tsn1 = g_ptr_array_new();
670 info->sort_tsn2 = g_ptr_array_new();
671 info->sort_sack1 = g_ptr_array_new();
672 info->sort_sack2 = g_ptr_array_new();
673 for (i=0; i < NUM_CHUNKS; i++)
675 info->chunk_count[i] = 0;
676 info->ep1_chunk_count[i] = 0;
677 info->ep2_chunk_count[i] = 0;
679 info->addr_chunk_count = NULL;
681 if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID) ||
682 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID) ||
683 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) ||
684 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID) ||
685 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID))
687 tsn = g_malloc(sizeof(tsn_t));
688 sack = g_malloc(sizeof(tsn_t));
693 sack->src.type=tsn->src.type = tmp_info.src.type;
694 sack->src.len=tsn->src.len = tmp_info.src.len;
695 addr = g_malloc(tmp_info.src.len);
696 memcpy(addr, tmp_info.src.data, tmp_info.src.len);
697 tsn->src.data = addr;
698 addr = g_malloc(tmp_info.src.len);
699 memcpy(addr, tmp_info.src.data, tmp_info.src.len);
700 sack->src.data = addr;
701 sack->dst.type = tsn->dst.type = tmp_info.dst.type;
702 sack->dst.len =tsn->dst.len = tmp_info.dst.len;
703 addr = g_malloc(tmp_info.dst.len);
704 memcpy(addr, tmp_info.dst.data, tmp_info.dst.len);
705 tsn->dst.data = addr;
706 addr = g_malloc(tmp_info.dst.len);
707 memcpy(addr, tmp_info.dst.data, tmp_info.dst.len);
708 sack->dst.data = addr;
709 sack->secs=tsn->secs = (guint32)pinfo->fd->rel_ts.secs;
710 sack->usecs=tsn->usecs = (guint32)pinfo->fd->rel_ts.nsecs/1000;
711 if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) ||
712 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID) ||
713 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID))
715 if (tsn->secs < info->min_secs)
717 info->min_secs = tsn->secs;
718 info->min_usecs = tsn->usecs;
720 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
721 info->min_usecs = tsn->usecs;
723 if (tsn->secs > info->max_secs)
725 info->max_secs = tsn->secs;
726 info->max_usecs = tsn->usecs;
728 else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
729 info->max_usecs = tsn->usecs;
732 sack->frame_number = tsn->frame_number = pinfo->fd->num;
734 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))
736 info->min_tsn1 = tvb_get_ntohl(sctp_info->tvb[0],INIT_CHUNK_INITIAL_TSN_OFFSET);
737 info->verification_tag2 = tvb_get_ntohl(sctp_info->tvb[0], INIT_CHUNK_INITIATE_TAG_OFFSET);
738 info->instream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET);
739 info->outstream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET);
740 for (chunk_number = 1; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
742 type = tvb_get_ntohs(sctp_info->tvb[chunk_number],0);
743 if (type == IPV4ADDRESS_PARAMETER_ID)
745 store = g_malloc(sizeof (address));
746 store->type = AT_IPv4;
748 store->data = g_malloc(4);
749 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(store->data),IPV4_ADDRESS_OFFSET, 4);
750 info = add_address(store, info, 1);
752 else if (type == IPV6ADDRESS_PARAMETER_ID)
754 store = g_malloc(sizeof (address));
755 store->type = AT_IPv6;
757 store->data = g_malloc(16);
758 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(store->data),IPV6_ADDRESS_OFFSET, IPV6_ADDRESS_LENGTH);
759 info = add_address(store, info, 1);
763 if (tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID)
769 info->initack_dir = 1;
770 info->initack = TRUE;
773 idx = tvb_get_guint8(sctp_info->tvb[0],0);
774 if (!IS_SCTP_CHUNK_TYPE(idx))
775 idx = OTHER_CHUNKS_INDEX;
777 info->chunk_count[idx]++;
778 info->ep1_chunk_count[idx]++;
779 info = add_chunk_count(&tmp_info.src, info, 1, idx);
783 if (((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_INIT_CHUNK_ID) &&
784 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_INIT_ACK_CHUNK_ID) &&
785 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_DATA_CHUNK_ID) &&
786 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_SACK_CHUNK_ID) &&
787 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_NR_SACK_CHUNK_ID))
789 tsn = g_malloc(sizeof(tsn_t));
790 sack = g_malloc(sizeof(tsn_t));
796 for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
798 idx = tvb_get_guint8(sctp_info->tvb[0],0);
799 if (!IS_SCTP_CHUNK_TYPE(idx))
800 idx = OTHER_CHUNKS_INDEX;
802 info->chunk_count[idx]++;
803 info->ep1_chunk_count[idx]++;
804 info = add_chunk_count(&tmp_info.src, info, 1, idx);
806 if (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID)
808 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
809 info->n_data_chunks++;
810 info->n_data_bytes+=length;
811 info->outstream1 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
812 tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], DATA_CHUNK_TSN_OFFSET);
813 if (tsnumber < info->min_tsn1)
814 info->min_tsn1 = tsnumber;
815 if (tsnumber > info->max_tsn1)
817 length=tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
818 info->n_data_chunks_ep1++;
819 info->n_data_bytes_ep1+=length;
820 info->max_tsn1 = tsnumber;
822 if (tsn->first_tsn == 0)
823 tsn->first_tsn = tsnumber;
824 t_s_n = g_malloc(16);
825 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, 16);
826 tsn->tsns = g_list_append(tsn->tsns, t_s_n);
828 tsn_s = g_malloc(sizeof(struct tsn_sort));
829 tsn_s->tsnumber = tsnumber;
830 tsn_s->secs = tsn->secs = (guint32)pinfo->fd->rel_ts.secs;
831 tsn_s->usecs = tsn->usecs = (guint32)pinfo->fd->rel_ts.nsecs/1000;
833 tsn_s->framenumber = framenumber;
834 tsn_s->length = length-DATA_CHUNK_HEADER_LENGTH;
835 if (tsn->secs < info->min_secs)
837 info->min_secs = tsn->secs;
838 info->min_usecs = tsn->usecs;
840 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
841 info->min_usecs = tsn->usecs;
843 if (tsn->secs > info->max_secs)
845 info->max_secs = tsn->secs;
846 info->max_usecs = tsn->usecs;
848 else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
849 info->max_usecs = tsn->usecs;
850 g_ptr_array_add(info->sort_tsn1, tsn_s);
851 info->n_array_tsn1++;
853 if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_SACK_CHUNK_ID) ||
854 (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_NR_SACK_CHUNK_ID) )
856 tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET);
857 if (tsnumber < info->min_tsn2)
858 info->min_tsn2 = tsnumber;
859 if (tsnumber > info->max_tsn2)
860 info->max_tsn2 = tsnumber;
861 info->n_sack_chunks_ep2++;
862 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET);
863 if (sack->first_tsn == 0)
864 sack->first_tsn = tsnumber;
865 t_s_n = g_malloc(length);
866 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, length);
867 sack->tsns = g_list_append(sack->tsns, t_s_n);
869 tsn_s = g_malloc(sizeof(struct tsn_sort));
870 tsn_s->tsnumber = tsnumber;
871 tsn_s->secs = tsn->secs = (guint32)pinfo->fd->rel_ts.secs;
872 tsn_s->usecs = tsn->usecs = (guint32)pinfo->fd->rel_ts.nsecs/1000;
874 tsn_s->framenumber = framenumber;
875 tsn_s->length = tvb_get_ntohl(sctp_info->tvb[chunk_number], SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
876 if (tsn_s->length > info->max_window1)
877 info->max_window1 = tsn_s->length;
878 if (tsn->secs < info->min_secs)
880 info->min_secs = tsn->secs;
881 info->min_usecs = tsn->usecs;
883 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
884 info->min_usecs = tsn->usecs;
886 if (tsn->secs > info->max_secs)
888 info->max_secs = tsn->secs;
889 info->max_usecs = tsn->usecs;
891 else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
892 info->max_usecs = tsn->usecs;
893 g_ptr_array_add(info->sort_sack2, tsn_s);
894 info->n_sack_chunks_ep2++;
898 if (info->verification_tag1 != 0 || info->verification_tag2 != 0)
900 store = g_malloc(sizeof (address));
901 store->type = tmp_info.src.type;
902 store->len = tmp_info.src.len;
903 addr = g_malloc(tmp_info.src.len);
904 memcpy(addr,(tmp_info.src.data),tmp_info.src.len);
906 info = add_address(store, info, 1);
907 store = g_malloc(sizeof (address));
908 store->type = tmp_info.dst.type;
909 store->len = tmp_info.dst.len;
910 addr = g_malloc(tmp_info.dst.len);
911 memcpy(addr,(tmp_info.dst.data),tmp_info.dst.len);
913 info = add_address(store, info, 2);
914 info->frame_numbers=g_list_prepend(info->frame_numbers,&(pinfo->fd->num));
915 if (datachunk == TRUE)
916 info->tsn1 = g_list_prepend(info->tsn1, tsn);
917 if (sackchunk == TRUE)
918 info->sack2 = g_list_prepend(info->sack2, sack);
919 sctp_tapinfo_struct.assoc_info_list = g_list_append(sctp_tapinfo_struct.assoc_info_list, info);
923 error = g_malloc(sizeof(sctp_error_info_t));
924 error->frame_number = pinfo->fd->num;
925 error->chunk_info[0] = '\0';
926 if ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID)
927 g_strlcpy(error->chunk_info, val_to_str(tvb_get_guint8(sctp_info->tvb[0],0),chunk_type_values,"Reserved"), 200);
929 for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
930 g_strlcat(error->chunk_info, val_to_str(tvb_get_guint8(sctp_info->tvb[chunk_number],0),chunk_type_values,"Reserved"), 200);
931 error->info_text = "INFOS";
932 info->error_info_list = g_list_append(info->error_info_list, error);
935 } /* endif (!info) */
938 if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID) ||
939 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID) ||
940 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) ||
941 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID) ||
942 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID))
945 tsn = g_malloc(sizeof(tsn_t));
946 sack = g_malloc(sizeof(tsn_t));
951 sack->src.type = tsn->src.type = tmp_info.src.type;
952 sack->src.len = tsn->src.len = tmp_info.src.len;
953 addr = g_malloc(tmp_info.src.len);
954 memcpy(addr, tmp_info.src.data, tmp_info.src.len);
955 tsn->src.data = addr;
956 addr = g_malloc(tmp_info.src.len);
957 memcpy(addr, tmp_info.src.data, tmp_info.src.len);
958 sack->src.data = addr;
959 sack->dst.type = tsn->dst.type = tmp_info.dst.type;
960 sack->dst.len = tsn->dst.len = tmp_info.dst.len;
961 addr = g_malloc(tmp_info.dst.len);
962 memcpy(addr, tmp_info.dst.data, tmp_info.dst.len);
963 tsn->dst.data = addr;
964 addr = g_malloc(tmp_info.dst.len);
965 memcpy(addr, tmp_info.dst.data, tmp_info.dst.len);
966 sack->dst.data = addr;
967 sack->secs=tsn->secs = (guint32)pinfo->fd->rel_ts.secs;
968 sack->usecs=tsn->usecs = (guint32)pinfo->fd->rel_ts.nsecs/1000;
969 if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) ||
970 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID) ||
971 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID))
973 if (tsn->secs < info->min_secs)
975 info->min_secs = tsn->secs;
976 info->min_usecs = tsn->usecs;
978 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
979 info->min_usecs = tsn->usecs;
981 if (tsn->secs > info->max_secs)
983 info->max_secs = tsn->secs;
984 info->max_usecs = tsn->usecs;
986 else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
987 info->max_usecs = tsn->usecs;
989 sack->frame_number = tsn->frame_number = pinfo->fd->num;
991 info->frame_numbers = g_list_prepend(info->frame_numbers,&(pinfo->fd->num));
993 store = g_malloc(sizeof (address));
994 store->type = tmp_info.src.type;
995 store->len = tmp_info.src.len;
996 addr = g_malloc(tmp_info.src.len);
997 memcpy(addr,(tmp_info.src.data),tmp_info.src.len);
1000 if (info->direction == 1)
1001 info = add_address(store, info, 1);
1002 else if (info->direction == 2)
1003 info = add_address(store, info, 2);
1005 store = g_malloc(sizeof (address));
1006 store->type = tmp_info.dst.type;
1007 store->len = tmp_info.dst.len;
1008 addr = g_malloc(tmp_info.dst.len);
1009 memcpy(addr,(tmp_info.dst.data),tmp_info.dst.len);
1012 if (info->direction == 1)
1013 info = add_address(store, info, 2);
1014 else if (info->direction == 2)
1015 info = add_address(store, info, 1);
1017 if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID) ||
1018 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID))
1020 tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], INIT_CHUNK_INITIAL_TSN_OFFSET);
1022 if (info->direction == 2)
1024 if (tsnumber < info->min_tsn2)
1025 info->min_tsn2 = tsnumber;
1026 if (tsnumber > info->max_tsn2)
1027 info->max_tsn2 = tsnumber;
1028 info->instream2 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET);
1029 info->outstream2 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET);
1030 /*info->initack_dir=2;*/
1031 info->tsn2 = g_list_prepend(info->tsn2, tsn);
1033 else if (info->direction == 1)
1035 if (tsnumber < info->min_tsn1)
1036 info->min_tsn1 = tsnumber;
1037 if (tsnumber > info->max_tsn1)
1038 info->max_tsn1 = tsnumber;
1039 info->instream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET);
1040 info->outstream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET);
1041 /*info->initack_dir=1;*/
1042 info->tsn1 = g_list_prepend(info->tsn1, tsn);
1045 idx = tvb_get_guint8(sctp_info->tvb[0],0);
1046 if (!IS_SCTP_CHUNK_TYPE(idx))
1047 idx = OTHER_CHUNKS_INDEX;
1048 info->chunk_count[idx]++;
1049 if (info->direction == 1)
1050 info->ep1_chunk_count[idx]++;
1052 info->ep2_chunk_count[idx]++;
1053 info = add_chunk_count(&tmp_info.src, info, info->direction, idx);
1054 for (chunk_number = 1; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
1056 type = tvb_get_ntohs(sctp_info->tvb[chunk_number],0);
1057 if (type == IPV4ADDRESS_PARAMETER_ID)
1059 store = g_malloc(sizeof (address));
1060 store->type = AT_IPv4;
1062 store->data = g_malloc(4);
1063 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(store->data),IPV4_ADDRESS_OFFSET, 4);
1064 info = add_address(store, info, info->direction);
1066 else if (type == IPV6ADDRESS_PARAMETER_ID)
1068 store = g_malloc(sizeof (address));
1069 store->type = AT_IPv6;
1071 store->data = g_malloc(16);
1072 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(store->data),IPV6_ADDRESS_OFFSET, IPV6_ADDRESS_LENGTH);
1073 info = add_address(store, info, info->direction);
1076 if ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID)
1078 info->initack = TRUE;
1079 info->initack_dir = info->direction;
1082 if ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID)
1089 if (((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_INIT_ACK_CHUNK_ID) &&
1090 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_DATA_CHUNK_ID) &&
1091 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_SACK_CHUNK_ID) &&
1092 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_NR_SACK_CHUNK_ID))
1094 sack = g_malloc(sizeof(tsn_t));
1096 sack->first_tsn = 0;
1097 tsn = g_malloc(sizeof(tsn_t));
1101 for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
1103 idx = tvb_get_guint8(sctp_info->tvb[chunk_number],0);
1104 if (!IS_SCTP_CHUNK_TYPE(idx))
1105 idx = OTHER_CHUNKS_INDEX;
1107 info->chunk_count[idx]++;
1108 if (info->direction == 1)
1109 info->ep1_chunk_count[idx]++;
1111 info->ep2_chunk_count[idx]++;
1112 info = add_chunk_count(&tmp_info.src, info,info->direction, idx);
1114 if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0)) == SCTP_DATA_CHUNK_ID)
1116 tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], DATA_CHUNK_TSN_OFFSET);
1117 if (tsn->first_tsn == 0)
1118 tsn->first_tsn = tsnumber;
1119 t_s_n = g_malloc(16);
1120 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, 16);
1121 tsn->tsns = g_list_append(tsn->tsns, t_s_n);
1123 length=tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
1124 info->n_data_chunks++;
1125 info->n_data_bytes+=length;
1126 tsn_s = g_malloc(sizeof(struct tsn_sort));
1127 tsn_s->tsnumber = tsnumber;
1128 tsn_s->secs = tsn->secs = (guint32)pinfo->fd->rel_ts.secs;
1129 tsn_s->usecs = tsn->usecs = (guint32)pinfo->fd->rel_ts.nsecs/1000;
1131 tsn_s->framenumber = framenumber;
1132 tsn_s->length = length;
1134 if (tsn->secs < info->min_secs)
1136 info->min_secs = tsn->secs;
1137 info->min_usecs = tsn->usecs;
1139 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
1140 info->min_usecs = tsn->usecs;
1142 if (tsn->secs > info->max_secs)
1144 info->max_secs = tsn->secs;
1145 info->max_usecs = tsn->usecs;
1147 else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
1148 info->max_usecs = tsn->usecs;
1150 if (info->direction == 1)
1152 if(tsnumber < info->min_tsn1)
1153 info->min_tsn1 = tsnumber;
1154 if ((info->init == TRUE || (info->initack == TRUE && info->initack_dir == 1))&& tsnumber >= info->min_tsn1 && tsnumber <= info->max_tsn1)
1156 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
1157 info->n_data_chunks_ep1++;
1158 info->n_data_bytes_ep1 += length;
1160 if(tsnumber > info->max_tsn1)
1162 info->max_tsn1 = tsnumber;
1163 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
1164 info->n_data_chunks_ep1++;
1165 info->n_data_bytes_ep1 += length;
1167 if (info->init == FALSE)
1168 info->outstream1 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1169 if (info->initack == FALSE)
1170 info->instream2 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1172 g_ptr_array_add(info->sort_tsn1, tsn_s);
1173 info->n_array_tsn1++;
1175 else if (info->direction == 2)
1178 if(tsnumber < info->min_tsn2)
1179 info->min_tsn2 = tsnumber;
1181 if ((info->initack == TRUE && info->initack_dir == 2)&& tsnumber >= info->min_tsn2 && tsnumber <= info->max_tsn2)
1183 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
1184 info->n_data_chunks_ep2++;
1185 info->n_data_bytes_ep2+=length;
1187 if(tsnumber > info->max_tsn2)
1189 info->max_tsn2 = tsnumber;
1190 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
1191 info->n_data_chunks_ep2++;
1192 info->n_data_bytes_ep2+=length;
1194 if (info->init == FALSE)
1195 info->instream1 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1196 if (info->initack == FALSE)
1197 info->outstream2 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1199 g_ptr_array_add(info->sort_tsn2, tsn_s);
1200 info->n_array_tsn2++;
1203 else if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_SACK_CHUNK_ID) ||
1204 (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_NR_SACK_CHUNK_ID))
1206 tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET);
1207 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET);
1208 if (sack->first_tsn == 0)
1209 sack->first_tsn = tsnumber;
1210 t_s_n = g_malloc(length);
1211 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, length);
1212 sack->tsns = g_list_append(sack->tsns, t_s_n);
1214 tsn_s = g_malloc(sizeof(struct tsn_sort));
1215 tsn_s->tsnumber = tsnumber;
1216 tsn_s->secs = tsn->secs = (guint32)pinfo->fd->rel_ts.secs;
1217 tsn_s->usecs = tsn->usecs = (guint32)pinfo->fd->rel_ts.nsecs/1000;
1219 tsn_s->framenumber = framenumber;
1220 tsn_s->length = tvb_get_ntohl(sctp_info->tvb[chunk_number], SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
1222 if (tsn->secs < info->min_secs)
1224 info->min_secs = tsn->secs;
1225 info->min_usecs = tsn->usecs;
1227 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
1228 info->min_usecs = tsn->usecs;
1230 if (tsn->secs > info->max_secs)
1232 info->max_secs = tsn->secs;
1233 info->max_usecs = tsn->usecs;
1235 else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
1236 info->max_usecs = tsn->usecs;
1239 if (info->direction == 2)
1241 if(tsnumber < info->min_tsn1)
1242 info->min_tsn1 = tsnumber;
1243 if(tsnumber > info->max_tsn1)
1244 info->max_tsn1 = tsnumber;
1245 if (tsn_s->length > info->max_window1)
1246 info->max_window1 = tsn_s->length;
1247 g_ptr_array_add(info->sort_sack1, tsn_s);
1248 info->n_sack_chunks_ep1++;
1250 else if (info->direction == 1)
1253 if(tsnumber < info->min_tsn2)
1254 info->min_tsn2 = tsnumber;
1255 if(tsnumber > info->max_tsn2)
1256 info->max_tsn2 = tsnumber;
1257 if (tsn_s->length > info->max_window2)
1258 info->max_window2 = tsn_s->length;
1259 g_ptr_array_add(info->sort_sack2, tsn_s);
1260 info->n_sack_chunks_ep2++;
1267 if (datachunk == TRUE)
1269 if (info->direction == 1)
1270 info->tsn1 = g_list_prepend(info->tsn1, tsn);
1271 else if (info->direction == 2)
1272 info->tsn2 = g_list_prepend(info->tsn2, tsn);
1274 if (sackchunk == TRUE)
1276 if (info->direction == 1)
1277 info->sack2 = g_list_prepend(info->sack2, sack);
1278 else if(info->direction == 2)
1279 info->sack1 = g_list_prepend(info->sack1, sack);
1281 info->n_tvbs += sctp_info->number_of_tvbs;
1282 sctp_tapinfo_struct.sum_tvbs += sctp_info->number_of_tvbs;
1283 info = calc_checksum(sctp_info, info);
1290 /****************************************************************************/
1292 remove_tap_listener_sctp_stat(void)
1294 if (sctp_tapinfo_struct.is_registered) {
1295 remove_tap_listener(&sctp_tapinfo_struct);
1296 sctp_tapinfo_struct.is_registered = FALSE;
1301 void sctp_stat_scan(void)
1303 if (!sctp_tapinfo_struct.is_registered)
1304 register_tap_listener_sctp_stat();
1307 const sctp_allassocs_info_t* sctp_stat_get_info(void)
1309 return &sctp_tapinfo_struct;
1313 static void sctp_update(void *dummy _U_)
1315 if (get_stat_dlg()!=NULL)
1316 sctp_stat_dlg_update();
1320 register_tap_listener_sctp_stat(void)
1322 GString *error_string;
1324 if (!sctp_tapinfo_struct.is_registered)
1326 if ((error_string = register_tap_listener("sctp", &sctp_tapinfo_struct, NULL, 0, reset, packet, sctp_update))) {
1327 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", error_string->str);
1328 g_string_free(error_string, TRUE);
1331 sctp_tapinfo_struct.is_registered=TRUE;