From e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 10 Apr 2024 22:34:10 +0200 Subject: Adding upstream version 4.2.2. Signed-off-by: Daniel Baumann --- ui/tap-sctp-analysis.c | 1294 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1294 insertions(+) create mode 100644 ui/tap-sctp-analysis.c (limited to 'ui/tap-sctp-analysis.c') diff --git a/ui/tap-sctp-analysis.c b/ui/tap-sctp-analysis.c new file mode 100644 index 0000000..9a4427a --- /dev/null +++ b/ui/tap-sctp-analysis.c @@ -0,0 +1,1294 @@ +/* + * Copyright 2004-2013, Irene Ruengeler + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "config.h" + +#include +#include + +#include + +#include "epan/packet_info.h" +#include "epan/tap.h" +#include "epan/value_string.h" + +#include "ui/tap-sctp-analysis.h" + +#include "ui/simple_dialog.h" + +#define FORWARD_STREAM 0 +#define BACKWARD_STREAM 1 +#define FORWARD_ADD_FORWARD_VTAG 2 +#define BACKWARD_ADD_FORWARD_VTAG 3 +#define BACKWARD_ADD_BACKWARD_VTAG 4 +#define ADDRESS_FORWARD_STREAM 5 +#define ADDRESS_BACKWARD_STREAM 6 +#define ADDRESS_FORWARD_ADD_FORWARD_VTAG 7 +#define ADDRESS_BACKWARD_ADD_FORWARD_VTAG 8 +#define ADDRESS_BACKWARD_ADD_BACKWARD_VTAG 9 +#define ASSOC_NOT_FOUND 10 + +static sctp_allassocs_info_t sctp_tapinfo_struct = {0, NULL, FALSE, NULL}; + +static void +free_first(gpointer data, gpointer user_data _U_) +{ + g_free(data); +} + +static void +tsn_free(gpointer data) +{ + tsn_t *tsn; + + tsn = (tsn_t *) data; + if (tsn->tsns != NULL) + { + g_list_free_full(tsn->tsns, g_free); + } + free_address(&tsn->src); + free_address(&tsn->dst); + g_free(tsn); +} + +static void +chunk_free(gpointer data) +{ + sctp_addr_chunk *chunk = (sctp_addr_chunk *) data; + + free_address(&chunk->addr); + g_free(chunk); +} + +static void +store_free(gpointer data) +{ + address *addr = (address *) data; + + free_address(addr); + g_free(addr); +} + +static void +reset(void *arg) +{ + sctp_allassocs_info_t *tapdata = (sctp_allassocs_info_t *)arg; + GList* list; + sctp_assoc_info_t * info; + + list = g_list_first(tapdata->assoc_info_list); + while (list) + { + info = (sctp_assoc_info_t *) (list->data); + + if (info->addr1 != NULL) + { + g_list_free_full(info->addr1, store_free); + info->addr1 = NULL; + } + + if (info->addr2 != NULL) + { + g_list_free_full(info->addr2, store_free); + info->addr2 = NULL; + } + + if (info->error_info_list != NULL) + { + g_list_free_full(info->error_info_list, g_free); + info->error_info_list = NULL; + } + + if (info->frame_numbers != NULL) + { + g_list_free(info->frame_numbers); + info->frame_numbers = NULL; + } + + if (info->tsn1 != NULL) + { + g_list_free_full(info->tsn1, tsn_free); + info->tsn1 = NULL; + } + + if (info->tsn2 != NULL) + { + g_list_free_full(info->tsn2, tsn_free); + info->tsn2 = NULL; + } + + if (info->sack1 != NULL) + { + g_list_free_full(info->sack1, tsn_free); + info->sack1 = NULL; + } + + if (info->sack2 != NULL) + { + g_list_free_full(info->sack2, tsn_free); + info->sack2 = NULL; + } + + if (info->sort_tsn1 != NULL) + g_ptr_array_free(info->sort_tsn1, TRUE); + + if (info->sort_tsn2 != NULL) + g_ptr_array_free(info->sort_tsn2, TRUE); + + if (info->sort_sack1 != NULL) + g_ptr_array_free(info->sort_sack1, TRUE); + + if (info->sort_sack2 != NULL) + g_ptr_array_free(info->sort_sack2, TRUE); + + if (info->min_max != NULL) + { + g_slist_foreach(info->min_max, free_first, NULL); + info->min_max = NULL; + } + + if (info->addr_chunk_count) { + g_list_free_full(info->addr_chunk_count, chunk_free); + } + + g_free(info->dir1); + g_free(info->dir2); + free_address(&info->src); + free_address(&info->dst); + + g_free(list->data); + list = g_list_next(list); + } + g_list_free(tapdata->assoc_info_list); + tapdata->sum_tvbs = 0; + tapdata->assoc_info_list = NULL; +} + + +static sctp_assoc_info_t * +calc_checksum(const struct _sctp_info *check_data, sctp_assoc_info_t *data) +{ + gboolean ok = FALSE; + + if (check_data->adler32_calculated) + { + data->n_adler32_calculated++; + if (check_data->adler32_correct) + data->n_adler32_correct++; + } + if (check_data->crc32c_calculated) + { + data->n_crc32c_calculated++; + if (check_data->crc32c_correct) + data->n_crc32c_correct++; + } + if (data->n_adler32_calculated > 0) + { + if ((float)(data->n_adler32_correct*1.0/data->n_adler32_calculated) > 0.5) + { + char str[] = "ADLER32"; + (void) g_strlcpy(data->checksum_type, str, 8); + data->n_checksum_errors=(data->n_adler32_calculated-data->n_adler32_correct); + ok = TRUE; + } + } + + if (data->n_crc32c_calculated>0) + { + if ((float)(data->n_crc32c_correct*1.0/data->n_crc32c_calculated) > 0.5) + { + char str[] = "CRC32C"; + (void) g_strlcpy(data->checksum_type, str, 8); + data->n_checksum_errors=data->n_crc32c_calculated-data->n_crc32c_correct; + ok = TRUE; + } + } + + if (!ok) + { + char str[] = "UNKNOWN"; + (void) g_strlcpy(data->checksum_type, str, 8); + data->n_checksum_errors=0; + } + + return(data); + +} + + +static sctp_assoc_info_t * +find_assoc(sctp_tmp_info_t *needle) +{ + sctp_allassocs_info_t *assoc_info; + sctp_assoc_info_t *info = NULL; + GList* list; + + assoc_info = &sctp_tapinfo_struct; + if ((list = g_list_last(assoc_info->assoc_info_list))!=NULL) + { + while (list) + { + info = (sctp_assoc_info_t*)(list->data); + if (needle->assoc_id == info->assoc_id) + return info; + + list = g_list_previous(list); + } + } + return NULL; +} + +static sctp_assoc_info_t * +add_chunk_count(address *vadd, sctp_assoc_info_t *info, guint32 direction, guint32 type) +{ + GList *list; + sctp_addr_chunk *ch=NULL; + int i; + + list = g_list_first(info->addr_chunk_count); + + while (list) + { + ch = (sctp_addr_chunk *)(list->data); + if (ch->direction == direction) + { + if (addresses_equal(vadd, &ch->addr)) + { + if (IS_SCTP_CHUNK_TYPE(type)) + ch->addr_count[type]++; + else + ch->addr_count[OTHER_CHUNKS_INDEX]++; + return info; + } + else + { + list = g_list_next(list); + } + } + else + list = g_list_next(list); + } + ch = g_new(sctp_addr_chunk, 1); + ch->direction = direction; + copy_address(&ch->addr, vadd); + for (i=0; i < NUM_CHUNKS; i++) + ch->addr_count[i] = 0; + + if (IS_SCTP_CHUNK_TYPE(type)) + ch->addr_count[type]++; + else + ch->addr_count[OTHER_CHUNKS_INDEX]++; + + info->addr_chunk_count = g_list_append(info->addr_chunk_count, ch); + return info; +} + +static sctp_assoc_info_t * +add_address(address *vadd, sctp_assoc_info_t *info, guint16 direction) +{ + GList *list; + address *v=NULL; + + if (direction == 1) + list = g_list_first(info->addr1); + else + list = g_list_first(info->addr2); + + while (list) + { + v = (address *) (list->data); + if (addresses_equal(vadd, v)) { + free_address(vadd); + g_free(vadd); + return info; + } + list = g_list_next(list); + } + + if (direction == 1) + info->addr1 = g_list_append(info->addr1, vadd); + else if (direction==2) + info->addr2 = g_list_append(info->addr2, vadd); + + return info; +} + +static tap_packet_status +packet(void *tapdata _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *data, tap_flags_t flags _U_) +{ + const struct _sctp_info *sctp_info = (const struct _sctp_info *)data; + guint32 chunk_number = 0, tsnumber, framenumber; + sctp_tmp_info_t tmp_info; + sctp_assoc_info_t *info = NULL; + sctp_error_info_t *error = NULL; + guint16 type, length = 0; + address *store = NULL; + tsn_t *tsn = NULL; + tsn_t *sack = NULL; + guint8 *t_s_n = NULL; + gboolean sackchunk = FALSE; + gboolean datachunk = FALSE; + gboolean forwardchunk = FALSE; + struct tsn_sort *tsn_s; + int i; + guint8 idx = 0; + gboolean tsn_used = FALSE; + gboolean sack_used = FALSE; + + framenumber = pinfo->num; + + type = sctp_info->ip_src.type; + + if (type == AT_IPv4 || type == AT_IPv6) + copy_address(&tmp_info.src, &sctp_info->ip_src); + else + set_address(&tmp_info.src, AT_NONE, 0, NULL); + + type = sctp_info->ip_dst.type; + + if (type == AT_IPv4 || type == AT_IPv6) + copy_address(&tmp_info.dst, &sctp_info->ip_dst); + else + set_address(&tmp_info.dst, AT_NONE, 0, NULL); + + tmp_info.port1 = sctp_info->sport; + tmp_info.port2 = sctp_info->dport; + + if (sctp_info->vtag_reflected) + { + tmp_info.verification_tag2 = sctp_info->verification_tag; + tmp_info.verification_tag1 = 0; + } + else + { + tmp_info.verification_tag1 = sctp_info->verification_tag; + tmp_info.verification_tag2 = 0; + } + tmp_info.n_tvbs = 0; + if (tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID) + { + tmp_info.initiate_tag = tvb_get_ntohl(sctp_info->tvb[0], 4); + } + else + { + tmp_info.initiate_tag = 0; + } + + tmp_info.direction = sctp_info->direction; + tmp_info.assoc_id = sctp_info->assoc_index; + info = find_assoc(&tmp_info); + if (!info) + { + tmp_info.n_tvbs = sctp_info->number_of_tvbs; + sctp_tapinfo_struct.sum_tvbs+=sctp_info->number_of_tvbs; + + if (sctp_info->number_of_tvbs > 0) + { + info = g_new0(sctp_assoc_info_t, 1); + info->assoc_id = sctp_info->assoc_index; + copy_address(&info->src, &tmp_info.src); + copy_address(&info->dst, &tmp_info.dst); + info->port1 = tmp_info.port1; + info->port2 = tmp_info.port2; + info->verification_tag1 = tmp_info.verification_tag1; + info->verification_tag2 = tmp_info.verification_tag2; + info->initiate_tag = tmp_info.initiate_tag; + info->n_tvbs = tmp_info.n_tvbs; + info->init = FALSE; + info->initack = FALSE; + info->check_address = FALSE; + info->firstdata = TRUE; + info->direction = sctp_info->direction; + info->instream1 = 0; + info->outstream1 = 0; + info->instream2 = 0; + info->outstream2 = 0; + info = calc_checksum(sctp_info, info); + info->n_packets = 1; + info->error_info_list = NULL; + info->min_secs = 0xffffffff; + info->min_usecs = 0xffffffff; + info->max_secs = 0; + info->max_usecs = 0; + info->min_tsn2 = 0xFFFFFFFF; + info->min_tsn1 = 0xffffffff; + info->max_tsn1 = 0; + info->max_tsn2 = 0; + info->max_bytes1 = 0; + info->max_bytes2 = 0; + info->n_data_chunks = 0; + info->n_data_bytes = 0; + info->n_data_chunks_ep1 = 0; + info->n_data_bytes_ep1 = 0; + info->n_data_chunks_ep2 = 0; + info->n_data_bytes_ep2 = 0; + info->n_sack_chunks_ep1 = 0; + info->n_sack_chunks_ep2 = 0; + info->n_array_tsn1 = 0; + info->n_array_tsn2 = 0; + info->n_forward_chunks = 0; + info->max_window1 = 0; + info->max_window2 = 0; + info->min_max = NULL; + info->sort_tsn1 = g_ptr_array_new_with_free_func(g_free); + info->sort_tsn2 = g_ptr_array_new_with_free_func(g_free); + info->sort_sack1 = g_ptr_array_new_with_free_func(g_free); + info->sort_sack2 = g_ptr_array_new_with_free_func(g_free); + info->dir1 = g_new0(sctp_init_collision_t, 1); + info->dir1->init_min_tsn = 0xffffffff; + info->dir1->initack_min_tsn = 0xffffffff; + info->dir2 = g_new0(sctp_init_collision_t, 1); + info->dir2->init_min_tsn = 0xffffffff; + info->dir2->initack_min_tsn = 0xffffffff; + + for (i=0; i < NUM_CHUNKS; i++) + { + info->chunk_count[i] = 0; + info->ep1_chunk_count[i] = 0; + info->ep2_chunk_count[i] = 0; + } + info->addr_chunk_count = NULL; + + 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) || + ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) || + ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_I_DATA_CHUNK_ID) || + ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID) || + ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID) || + ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_FORWARD_TSN_CHUNK_ID)) + { + tsn = g_new0(tsn_t, 1); + copy_address(&tsn->src, &tmp_info.src); + copy_address(&tsn->dst, &tmp_info.dst); + + sack = g_new0(tsn_t, 1); + copy_address(&sack->src, &tmp_info.src); + copy_address(&sack->dst, &tmp_info.dst); + sack->secs=tsn->secs = (guint32)pinfo->rel_ts.secs; + sack->usecs=tsn->usecs = (guint32)pinfo->rel_ts.nsecs/1000; + + if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) || + ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_I_DATA_CHUNK_ID) || + ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID) || + ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID) || + ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_FORWARD_TSN_CHUNK_ID)) + { + if (tsn->secs < info->min_secs) + { + info->min_secs = tsn->secs; + info->min_usecs = tsn->usecs; + } + else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs) + info->min_usecs = tsn->usecs; + + if (tsn->secs > info->max_secs) + { + info->max_secs = tsn->secs; + info->max_usecs = tsn->usecs; + } + else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs) + info->max_usecs = tsn->usecs; + } + + sack->frame_number = tsn->frame_number = pinfo->num; + } + 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)) + { + info->min_tsn1 = tvb_get_ntohl(sctp_info->tvb[0],INIT_CHUNK_INITIAL_TSN_OFFSET); + info->verification_tag2 = tvb_get_ntohl(sctp_info->tvb[0], INIT_CHUNK_INITIATE_TAG_OFFSET); + info->instream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET); + info->outstream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET); + info->arwnd1 = tvb_get_ntohl(sctp_info->tvb[0], INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET); + for (chunk_number = 1; chunk_number < sctp_info->number_of_tvbs; chunk_number++) + { + type = tvb_get_ntohs(sctp_info->tvb[chunk_number],0); + if (type == IPV4ADDRESS_PARAMETER_ID) + { + store = g_new(address, 1); + alloc_address_tvb(NULL, store, AT_IPv4, 4, sctp_info->tvb[chunk_number], IPV4_ADDRESS_OFFSET); + info = add_address(store, info, info->direction); + } + else if (type == IPV6ADDRESS_PARAMETER_ID) + { + store = g_new(address, 1); + alloc_address_tvb(NULL, store, AT_IPv6, 16, sctp_info->tvb[chunk_number], IPV6_ADDRESS_OFFSET); + info = add_address(store, info, info->direction); + } + } + + if (tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID) + { + info->init = TRUE; + } + else + { + info->initack_dir = 1; + info->initack = TRUE; + } + + idx = tvb_get_guint8(sctp_info->tvb[0],0); + if (!IS_SCTP_CHUNK_TYPE(idx)) + idx = OTHER_CHUNKS_INDEX; + + info->chunk_count[idx]++; + info->ep1_chunk_count[idx]++; + info = add_chunk_count(&tmp_info.src, info, 1, idx); + if (info->direction == 1) { + if (tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID) { + info->dir1->init = TRUE; + info->dir1->init_min_tsn = info->min_tsn1; + info->dir1->init_vtag = info->verification_tag2; + } else if (tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_ACK_CHUNK_ID) { + info->dir1->initack = TRUE; + info->dir1->initack_min_tsn = info->min_tsn1; + info->dir1->initack_vtag = info->verification_tag2; + } + } else { + if (tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID) { + info->dir2->init = TRUE; + info->dir2->init_min_tsn = info->min_tsn1; + info->dir2->init_vtag = info->verification_tag2; + } else if (tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_ACK_CHUNK_ID) { + info->dir2->initack = TRUE; + info->dir2->initack_min_tsn = info->min_tsn1; + info->dir2->initack_vtag = info->verification_tag2; + } + } + } + else + { + 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) && + ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_DATA_CHUNK_ID) && + ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_I_DATA_CHUNK_ID) && + ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_SACK_CHUNK_ID) && + ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_NR_SACK_CHUNK_ID) && + ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_FORWARD_TSN_CHUNK_ID)) + { + tsn = g_new0(tsn_t, 1); + sack = g_new0(tsn_t, 1); + } + for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++) + { + idx = tvb_get_guint8(sctp_info->tvb[0],0); + if (!IS_SCTP_CHUNK_TYPE(idx)) + idx = OTHER_CHUNKS_INDEX; + + info->chunk_count[idx]++; + info->ep1_chunk_count[idx]++; + info = add_chunk_count(&tmp_info.src, info, 1, idx); + + if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID) || + (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_I_DATA_CHUNK_ID)) + { + datachunk = TRUE; + if (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID) { + length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET) - DATA_CHUNK_HEADER_LENGTH; + } else { + length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET) - I_DATA_CHUNK_HEADER_LENGTH; + } + info->n_data_chunks++; + info->n_data_bytes+=length; + info->outstream1 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1; + } + if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_FORWARD_TSN_CHUNK_ID)) + { + forwardchunk = TRUE; + length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET); + info->n_forward_chunks++; + } + if (datachunk || forwardchunk) + { + tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], DATA_CHUNK_TSN_OFFSET); + info->firstdata = FALSE; + if (tsnumber < info->min_tsn1) + info->min_tsn1 = tsnumber; + if (tsnumber > info->max_tsn1) + { + if (datachunk) + { + info->n_data_chunks_ep1++; + info->n_data_bytes_ep1+=length; + } + else + info->n_forward_chunks_ep1++; + info->max_tsn1 = tsnumber; + } + if (tsn->first_tsn == 0) + tsn->first_tsn = tsnumber; + if (datachunk) + { + t_s_n = (guint8 *)g_malloc(16); + tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, 16); + } + else + { + t_s_n = (guint8 *)g_malloc(length); + tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, length); + } + tsn->tsns = g_list_append(tsn->tsns, t_s_n); + tsn_s = g_new(struct tsn_sort, 1); + tsn_s->tsnumber = tsnumber; + tsn_s->secs = tsn->secs = (guint32)pinfo->rel_ts.secs; + tsn_s->usecs = tsn->usecs = (guint32)pinfo->rel_ts.nsecs/1000; + tsn_s->offset = 0; + tsn_s->framenumber = framenumber; + if (datachunk) + if (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID) { + tsn_s->length = length - DATA_CHUNK_HEADER_LENGTH; + } else { + tsn_s->length = length - I_DATA_CHUNK_HEADER_LENGTH; + } + else + tsn_s->length = length; + if (tsn->secs < info->min_secs) + { + info->min_secs = tsn->secs; + info->min_usecs = tsn->usecs; + } + else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs) + info->min_usecs = tsn->usecs; + + if (tsn->secs > info->max_secs) + { + info->max_secs = tsn->secs; + info->max_usecs = tsn->usecs; + } + else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs) + info->max_usecs = tsn->usecs; + g_ptr_array_add(info->sort_tsn1, tsn_s); + info->n_array_tsn1++; + } + if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_SACK_CHUNK_ID) || + (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_NR_SACK_CHUNK_ID) ) + { + tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET); + if (tsnumber < info->min_tsn2) + info->min_tsn2 = tsnumber; + if (tsnumber > info->max_tsn2) + info->max_tsn2 = tsnumber; + length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET); + if (sack->first_tsn == 0) + sack->first_tsn = tsnumber; + t_s_n = (guint8 *)g_malloc(length); + tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, length); + sack->tsns = g_list_append(sack->tsns, t_s_n); + sackchunk = TRUE; + tsn_s = g_new(struct tsn_sort, 1); + tsn_s->tsnumber = tsnumber; + tsn_s->secs = tsn->secs = (guint32)pinfo->rel_ts.secs; + tsn_s->usecs = tsn->usecs = (guint32)pinfo->rel_ts.nsecs/1000; + tsn_s->offset = 0; + tsn_s->framenumber = framenumber; + tsn_s->length = tvb_get_ntohl(sctp_info->tvb[chunk_number], SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET); + if (tsn_s->length > info->max_window1) + info->max_window1 = tsn_s->length; + if (tsn->secs < info->min_secs) + { + info->min_secs = tsn->secs; + info->min_usecs = tsn->usecs; + } + else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs) + info->min_usecs = tsn->usecs; + + if (tsn->secs > info->max_secs) + { + info->max_secs = tsn->secs; + info->max_usecs = tsn->usecs; + } + else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs) + info->max_usecs = tsn->usecs; + g_ptr_array_add(info->sort_sack2, tsn_s); + info->n_sack_chunks_ep2++; + } + } + } + if (info->verification_tag1 != 0 || info->verification_tag2 != 0) + { + guint32 number; + store = g_new(address, 1); + copy_address(store, &tmp_info.src); + info = add_address(store, info, info->direction); + store = g_new(address, 1); + copy_address(store, &tmp_info.dst); + if (info->direction == 1) + info = add_address(store, info, 2); + else + info = add_address(store, info, 1); + number = pinfo->num; + info->frame_numbers=g_list_prepend(info->frame_numbers, GUINT_TO_POINTER(number)); + if (datachunk || forwardchunk) { + info->tsn1 = g_list_prepend(info->tsn1, tsn); + tsn_used = TRUE; + } + if (sackchunk == TRUE) { + info->sack2 = g_list_prepend(info->sack2, sack); + sack_used = TRUE; + } + sctp_tapinfo_struct.assoc_info_list = g_list_append(sctp_tapinfo_struct.assoc_info_list, info); + } + else + { + gchar* tmp_str; + error = g_new(sctp_error_info_t, 1); + error->frame_number = pinfo->num; + error->chunk_info[0] = '\0'; + if ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID) + { + tmp_str = val_to_str_wmem(NULL, tvb_get_guint8(sctp_info->tvb[0],0),chunk_type_values,"Reserved (%d)"); + (void) g_strlcpy(error->chunk_info, tmp_str, 200); + wmem_free(NULL, tmp_str); + } + else + { + for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++) + { + tmp_str = val_to_str_wmem(NULL, tvb_get_guint8(sctp_info->tvb[chunk_number],0),chunk_type_values,"Reserved (%d)"); + (void) g_strlcat(error->chunk_info, tmp_str, 200); + wmem_free(NULL, tmp_str); + } + } + error->info_text = "INFOS"; + info->error_info_list = g_list_append(info->error_info_list, error); + } + } + } /* endif (!info) */ + else + { + guint32 number; + info->direction = sctp_info->direction; + + if (info->verification_tag1 == 0 && info->verification_tag2 != sctp_info->verification_tag) { + info->verification_tag1 = sctp_info->verification_tag; + } else if (info->verification_tag2 == 0 && info->verification_tag1 != sctp_info->verification_tag) { + info->verification_tag2 = sctp_info->verification_tag; + } + 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) || + ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) || + ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_I_DATA_CHUNK_ID) || + ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID) || + ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID) || + ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_FORWARD_TSN_CHUNK_ID)) + { + + tsn = g_new0(tsn_t, 1); + copy_address(&tsn->src, &tmp_info.src); + copy_address(&tsn->dst, &tmp_info.dst); + + sack = g_new0(tsn_t, 1); + copy_address(&sack->src, &tmp_info.src); + copy_address(&sack->dst, &tmp_info.dst); + sack->secs=tsn->secs = (guint32)pinfo->rel_ts.secs; + sack->usecs=tsn->usecs = (guint32)pinfo->rel_ts.nsecs/1000; + + if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) || + ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_I_DATA_CHUNK_ID) || + ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID) || + ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID) || + ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_FORWARD_TSN_CHUNK_ID)) + { + if (tsn->secs < info->min_secs) + { + info->min_secs = tsn->secs; + info->min_usecs = tsn->usecs; + } + else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs) + info->min_usecs = tsn->usecs; + + if (tsn->secs > info->max_secs) + { + info->max_secs = tsn->secs; + info->max_usecs = tsn->usecs; + } + else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs) + info->max_usecs = tsn->usecs; + } + sack->frame_number = tsn->frame_number = pinfo->num; + } + number = pinfo->num; + info->frame_numbers=g_list_prepend(info->frame_numbers, GUINT_TO_POINTER(number)); + + store = g_new(address, 1); + copy_address(store, &tmp_info.src); + + switch (info->direction) { + case 1: + info = add_address(store, info, 1); + break; + case 2: + info = add_address(store, info, 2); + break; + default: + g_free(store); + break; + } + + store = g_new(address, 1); + copy_address(store, &tmp_info.dst); + + switch (info->direction) { + case 1: + info = add_address(store, info, 2); + break; + case 2: + info = add_address(store, info, 1); + break; + default: + g_free(store); + break; + } + + if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID) || + ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID)) + { + tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], INIT_CHUNK_INITIAL_TSN_OFFSET); + if (info->direction == 2) + { + if (tsnumber < info->min_tsn2) + info->min_tsn2 = tsnumber; + if (tsnumber > info->max_tsn2) + info->max_tsn2 = tsnumber; + info->instream2 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET); + info->outstream2 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET); + info->arwnd2 = tvb_get_ntohl(sctp_info->tvb[0],INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET); + info->tsn2 = g_list_prepend(info->tsn2, tsn); + tsn_used = TRUE; + } + else if (info->direction == 1) + { + if (tsnumber < info->min_tsn1) + info->min_tsn1 = tsnumber; + if (tsnumber > info->max_tsn1) + info->max_tsn1 = tsnumber; + info->instream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET); + info->outstream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET); + info->arwnd1 = tvb_get_ntohl(sctp_info->tvb[0],INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET); + info->tsn1 = g_list_prepend(info->tsn1, tsn); + tsn_used = TRUE; + } + + idx = tvb_get_guint8(sctp_info->tvb[0],0); + if (!IS_SCTP_CHUNK_TYPE(idx)) + idx = OTHER_CHUNKS_INDEX; + info->chunk_count[idx]++; + if (info->direction == 1) + info->ep1_chunk_count[idx]++; + else + info->ep2_chunk_count[idx]++; + info = add_chunk_count(&tmp_info.src, info, info->direction, idx); + for (chunk_number = 1; chunk_number < sctp_info->number_of_tvbs; chunk_number++) + { + type = tvb_get_ntohs(sctp_info->tvb[chunk_number],0); + if (type == IPV4ADDRESS_PARAMETER_ID) + { + store = g_new(address, 1); + alloc_address_tvb(NULL, store, AT_IPv4, 4, sctp_info->tvb[chunk_number], IPV4_ADDRESS_OFFSET); + info = add_address(store, info, info->direction); + } + else if (type == IPV6ADDRESS_PARAMETER_ID) + { + store = g_new(address, 1); + alloc_address_tvb(NULL, store, AT_IPv6, 16, sctp_info->tvb[chunk_number], IPV6_ADDRESS_OFFSET); + info = add_address(store, info, info->direction); + } + } + if (info->direction == 1) { + if (info->dir1->init || info->dir1->initack) { + info->init_collision = TRUE; + } + if (tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID) { + info->dir1->init = TRUE; + info->dir1->init_min_tsn = tvb_get_ntohl((sctp_info->tvb)[0], INIT_CHUNK_INITIAL_TSN_OFFSET); + info->min_tsn1 = info->dir1->init_min_tsn; + info->dir1->init_vtag = tvb_get_ntohl(sctp_info->tvb[0], INIT_CHUNK_INITIATE_TAG_OFFSET); + } else if (tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_ACK_CHUNK_ID) { + info->dir1->initack = TRUE; + info->dir1->initack_min_tsn = tvb_get_ntohl((sctp_info->tvb)[0], INIT_CHUNK_INITIAL_TSN_OFFSET); + info->min_tsn1 = info->dir1->initack_min_tsn; + info->dir1->initack_vtag = tvb_get_ntohl(sctp_info->tvb[0], INIT_CHUNK_INITIATE_TAG_OFFSET); + } + } else { + if (info->dir2->init || info->dir2->initack) { + info->init_collision = TRUE; + } + if (tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID) { + info->dir2->init = TRUE; + info->dir2->init_min_tsn = tvb_get_ntohl((sctp_info->tvb)[0], INIT_CHUNK_INITIAL_TSN_OFFSET); + info->min_tsn2 = info->dir2->init_min_tsn; + info->dir2->init_vtag = tvb_get_ntohl(sctp_info->tvb[0], INIT_CHUNK_INITIATE_TAG_OFFSET); + } else if (tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_ACK_CHUNK_ID) { + info->dir2->initack = TRUE; + info->dir2->initack_min_tsn = tvb_get_ntohl((sctp_info->tvb)[0], INIT_CHUNK_INITIAL_TSN_OFFSET); + info->min_tsn2 = info->dir2->initack_min_tsn; + info->dir2->initack_vtag = tvb_get_ntohl(sctp_info->tvb[0], INIT_CHUNK_INITIATE_TAG_OFFSET); + } + } + if ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID) + { + info->initack = TRUE; + info->initack_dir = info->direction; + } + else if ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID) + { + info->init = TRUE; + } + } + else + { + if (((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_INIT_ACK_CHUNK_ID) && + ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_DATA_CHUNK_ID) && + ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_I_DATA_CHUNK_ID) && + ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_SACK_CHUNK_ID) && + ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_NR_SACK_CHUNK_ID) && + ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_FORWARD_TSN_CHUNK_ID)) + { + if (!sack) + sack = g_new0(tsn_t, 1); + sack->tsns = NULL; + sack->first_tsn = 0; + if (!tsn) + tsn = g_new0(tsn_t, 1); + tsn->tsns = NULL; + tsn->first_tsn = 0; + } + for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++) + { + idx = tvb_get_guint8(sctp_info->tvb[chunk_number],0); + if (!IS_SCTP_CHUNK_TYPE(idx)) + idx = OTHER_CHUNKS_INDEX; + + info->chunk_count[idx]++; + if (info->direction == 1) + info->ep1_chunk_count[idx]++; + else + info->ep2_chunk_count[idx]++; + info = add_chunk_count(&tmp_info.src, info,info->direction, idx); + + if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID) || + (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_I_DATA_CHUNK_ID)) + datachunk = TRUE; + if (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_FORWARD_TSN_CHUNK_ID) + forwardchunk = TRUE; + if ((datachunk || forwardchunk) && tsn != NULL) + { + tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], DATA_CHUNK_TSN_OFFSET); + if (tsn->first_tsn == 0) + tsn->first_tsn = tsnumber; + if (datachunk) + { + t_s_n = (guint8 *)g_malloc(16); + tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, 16); + if (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID) { + length=tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH; + } else { + length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET) - I_DATA_CHUNK_HEADER_LENGTH; + } + info->n_data_chunks++; + info->n_data_bytes+=length; + } + else + { + length=tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET); + t_s_n = (guint8 *)g_malloc(length); + tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, length); + info->n_forward_chunks++; + } + tsn->tsns = g_list_append(tsn->tsns, t_s_n); + + tsn_s = g_new0(struct tsn_sort, 1); + tsn_s->tsnumber = tsnumber; + tsn_s->secs = tsn->secs = (guint32)pinfo->rel_ts.secs; + tsn_s->usecs = tsn->usecs = (guint32)pinfo->rel_ts.nsecs/1000; + tsn_s->offset = 0; + tsn_s->framenumber = framenumber; + tsn_s->length = length; + + if (tsn->secs < info->min_secs) + { + info->min_secs = tsn->secs; + info->min_usecs = tsn->usecs; + } + else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs) + info->min_usecs = tsn->usecs; + + if (tsn->secs > info->max_secs) + { + info->max_secs = tsn->secs; + info->max_usecs = tsn->usecs; + } + else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs) + info->max_usecs = tsn->usecs; + + if (info->direction == 1) + { + if (info->firstdata) { + info->firstdata = FALSE; + if (info->init_collision) { + if (tsnumber != info->min_tsn1) { + info->min_tsn1 = info->dir1->init_min_tsn; + } + info->min_tsn2 = info->dir2->initack_min_tsn; + } + } else { + if(tsnumber < info->min_tsn1) { + info->min_tsn1 = tsnumber; + } + } + if ((info->init || (info->initack && info->initack_dir == 1))&& tsnumber >= info->min_tsn1 && tsnumber <= info->max_tsn1) + { + if (datachunk) + { + info->n_data_chunks_ep1++; + info->n_data_bytes_ep1 += length; + } + else if (forwardchunk) + { + info->n_forward_chunks_ep1++; + } + } + if(tsnumber > info->max_tsn1) + { + info->max_tsn1 = tsnumber; + if (datachunk) + { + info->n_data_chunks_ep1++; + info->n_data_bytes_ep1 += length; + } + else if (forwardchunk) + { + info->n_forward_chunks_ep1++; + } + } + if (datachunk) + { + if (info->init == FALSE) { + guint16 tmp = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1; + if (info->outstream1 < tmp) info->outstream1 = tmp; + } + if (info->initack == FALSE) { + guint16 tmp = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1; + if (info->instream2 < tmp) info->instream2 = tmp; + } + } + + g_ptr_array_add(info->sort_tsn1, tsn_s); + info->n_array_tsn1++; + } + else if (info->direction == 2) + { + if (info->firstdata) { + info->firstdata = FALSE; + if (info->init_collision) { + if (tsnumber != info->min_tsn2) { + info->min_tsn2 = info->dir2->init_min_tsn; + info->initack_dir = 2; + } + info->min_tsn1 = info->dir1->initack_min_tsn; + } + } else { + if(tsnumber < info->min_tsn2) + info->min_tsn2 = tsnumber; + } + + if ((info->initack && info->initack_dir == 2)&& tsnumber >= info->min_tsn2 && tsnumber <= info->max_tsn2) + { + if (datachunk) + { + if (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID) { + length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET) - DATA_CHUNK_HEADER_LENGTH; + } else { + length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET) - I_DATA_CHUNK_HEADER_LENGTH; + } + info->n_data_chunks_ep2++; + info->n_data_bytes_ep2+=length; + } + else if (forwardchunk) + { + info->n_forward_chunks_ep2++; + } + } + if (tsnumber > info->max_tsn2) + { + info->max_tsn2 = tsnumber; + if (datachunk) + { + if (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID) { + length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET) - DATA_CHUNK_HEADER_LENGTH; + } else { + length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET) - I_DATA_CHUNK_HEADER_LENGTH; + } + info->n_data_chunks_ep2++; + info->n_data_bytes_ep2+=length; + } + else if (forwardchunk) + { + info->n_forward_chunks_ep2++; + } + } + if (datachunk) + { + if (info->init == FALSE) { + guint16 tmp = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1; + if (info->instream1 < tmp) info->instream1 = tmp; + } + if (info->initack == FALSE) { + guint16 tmp = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1; + if (info->outstream2 < tmp) info->outstream2 = tmp; + } + } + + g_ptr_array_add(info->sort_tsn2, tsn_s); + info->n_array_tsn2++; + } + } + else if (((tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_SACK_CHUNK_ID) || + (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_NR_SACK_CHUNK_ID)) && + sack != NULL) + { + tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET); + length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET); + + if (sack->first_tsn == 0) + sack->first_tsn = tsnumber; + + t_s_n = (guint8 *)g_malloc(length); + tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, length); + sack->tsns = g_list_append(sack->tsns, t_s_n); + sackchunk = TRUE; + tsn_s = g_new0(struct tsn_sort, 1); + tsn_s->tsnumber = tsnumber; + tsn_s->secs = tsn->secs = (guint32)pinfo->rel_ts.secs; + tsn_s->usecs = tsn->usecs = (guint32)pinfo->rel_ts.nsecs/1000; + tsn_s->offset = 0; + tsn_s->framenumber = framenumber; + tsn_s->length = tvb_get_ntohl(sctp_info->tvb[chunk_number], SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET); + + if (tsn->secs < info->min_secs) + { + info->min_secs = tsn->secs; + info->min_usecs = tsn->usecs; + } + else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs) + info->min_usecs = tsn->usecs; + + if (tsn->secs > info->max_secs) + { + info->max_secs = tsn->secs; + info->max_usecs = tsn->usecs; + } + else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs) + info->max_usecs = tsn->usecs; + + + if (info->direction == 2) + { + if(tsnumber < info->min_tsn1) + info->min_tsn1 = tsnumber; + if(tsnumber > info->max_tsn1) + info->max_tsn1 = tsnumber; + if (tsn_s->length > info->max_window1) + info->max_window1 = tsn_s->length; + g_ptr_array_add(info->sort_sack1, tsn_s); + info->n_sack_chunks_ep1++; + } + else if (info->direction == 1) + { + if(tsnumber < info->min_tsn2) + info->min_tsn2 = tsnumber; + if(tsnumber > info->max_tsn2) + info->max_tsn2 = tsnumber; + if (tsn_s->length > info->max_window2) + info->max_window2 = tsn_s->length; + g_ptr_array_add(info->sort_sack2, tsn_s); + info->n_sack_chunks_ep2++; + } + } + } + } + + if (datachunk || forwardchunk) + { + if (info->direction == 1) + info->tsn1 = g_list_prepend(info->tsn1, tsn); + else if (info->direction == 2) + info->tsn2 = g_list_prepend(info->tsn2, tsn); + tsn_used = TRUE; + } + if (sackchunk == TRUE) + { + if (info->direction == 1) + info->sack2 = g_list_prepend(info->sack2, sack); + else if(info->direction == 2) + info->sack1 = g_list_prepend(info->sack1, sack); + sack_used = TRUE; + } + info->n_tvbs += sctp_info->number_of_tvbs; + sctp_tapinfo_struct.sum_tvbs += sctp_info->number_of_tvbs; + info = calc_checksum(sctp_info, info); + info->n_packets++; + } + if (tsn && !tsn_used) + tsn_free(tsn); + if (sack && !sack_used) + tsn_free(sack); + free_address(&tmp_info.src); + free_address(&tmp_info.dst); + return TAP_PACKET_REDRAW; +} + + +/****************************************************************************/ +void +remove_tap_listener_sctp_stat(void) +{ + if (sctp_tapinfo_struct.is_registered) { + remove_tap_listener(&sctp_tapinfo_struct); + sctp_tapinfo_struct.is_registered = FALSE; + } +} + + +void +sctp_stat_scan(void) +{ + if (!sctp_tapinfo_struct.is_registered) { + register_tap_listener_sctp_stat(); + } +} + +const sctp_allassocs_info_t * +sctp_stat_get_info(void) +{ + return &sctp_tapinfo_struct; +} + +const sctp_assoc_info_t * +get_sctp_assoc_info(guint16 assoc_id) +{ + sctp_tmp_info_t needle = { .assoc_id = assoc_id }; + return find_assoc(&needle); +} + +void +register_tap_listener_sctp_stat(void) +{ + GString *error_string; + + if (!sctp_tapinfo_struct.is_registered) + { + if ((error_string = register_tap_listener("sctp", &sctp_tapinfo_struct, NULL, 0, reset, packet, NULL, NULL))) { + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", error_string->str); + g_string_free(error_string, TRUE); + return; + } + sctp_tapinfo_struct.is_registered=TRUE; + } +} -- cgit v1.2.3