-/*
+/*
* Copyright 2004, Irene Ruengeler <i.ruengeler [AT] fh-muenster.de>
*
* $Id$
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-
+
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
-
#include <stdio.h>
-#include <gtk/gtk.h>
-#include "simple_dialog.h" /* Both is used for error handling */
-#include "globals.h"
-#include "epan/packet_info.h" /* Needed for packet_info */
-#include <epan/tap.h> /* Needed for register_tap_listener */
-#include "dlg_utils.h"
-#include "compat_macros.h"
-#include "register.h"
#include <string.h>
-#include "sctp_stat.h"
#include <math.h>
+
+#include <gtk/gtk.h>
+
+#include "epan/packet_info.h"
+#include <epan/tap.h>
#include "epan/address.h"
+#include <epan/strutil.h>
+
+#include "../simple_dialog.h"
-#define SCTP_HEARTBEAT_CHUNK_ID 4
-#define SCTP_HEARTBEAT_ACK_CHUNK_ID 5
-#define SCTP_ABORT_CHUNK_ID 6
-#define SCTP_SHUTDOWN_CHUNK_ID 7
-#define SCTP_SHUTDOWN_ACK_CHUNK_ID 8
-#define SCTP_ERROR_CHUNK_ID 9
-#define SCTP_COOKIE_ECHO_CHUNK_ID 10
-#define SCTP_COOKIE_ACK_CHUNK_ID 11
-#define SCTP_ECNE_CHUNK_ID 12
-#define SCTP_CWR_CHUNK_ID 13
-#define SCTP_SHUTDOWN_COMPLETE_CHUNK_ID 14
-#define SCTP_FORWARD_TSN_CHUNK_ID 192
-#define SCTP_ASCONF_ACK_CHUNK_ID 0x80
-#define SCTP_PKTDROP_CHUNK_ID 0X81
-#define SCTP_ASCONF_CHUNK_ID 0XC1
-#define SCTP_IETF_EXT 255
+#include "gtk/dlg_utils.h"
+#include "gtk/sctp_stat.h"
+#include "gtk/main.h"
#define SCTP_ABORT_CHUNK_T_BIT 0x01
INIT_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH + \
INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_LENGTH + \
INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_LENGTH + \
- INIT_CHUNK_INITIAL_TSN_LENGTH)
+ INIT_CHUNK_INITIAL_TSN_LENGTH)
#define CHUNK_HEADER_LENGTH (CHUNK_TYPE_LENGTH + \
CHUNK_FLAGS_LENGTH + \
CHUNK_LENGTH_LENGTH)
#define INIT_CHUNK_VARIABLE_LENGTH_PARAMETER_OFFSET (INIT_CHUNK_INITIAL_TSN_OFFSET + \
- INIT_CHUNK_INITIAL_TSN_LENGTH )
+ INIT_CHUNK_INITIAL_TSN_LENGTH )
static const value_string chunk_type_values[] = {
{ SCTP_DATA_CHUNK_ID, "DATA" },
{ SCTP_PKTDROP_CHUNK_ID, "PKTDROP" },
{ SCTP_ASCONF_CHUNK_ID, "ASCONF" },
{ SCTP_IETF_EXT, "IETF_EXTENSION" },
+ { SCTP_NR_SACK_CHUNK_ID, "NR_SACK" },
+ { SCTP_AUTH_CHUNK_ID, "AUTH" },
{ 0, NULL } };
}
}
-static void
-reset(void *arg)
+
+static void reset(void *arg)
{
sctp_allassocs_info_t *tapdata = arg;
GList* list;
{
if ((float)(data->n_adler32_correct*1.0/data->n_adler32_calculated) > 0.5)
{
- strcpy(data->checksum_type,"ADLER32");
+ g_strlcpy(data->checksum_type,"ADLER32",8);
data->n_checksum_errors=(data->n_adler32_calculated-data->n_adler32_correct);
ok = TRUE;
}
{
if ((float)(data->n_crc32c_correct*1.0/data->n_crc32c_calculated) > 0.5)
{
- strcpy(data->checksum_type,"CRC32C");
+ g_strlcpy(data->checksum_type,"CRC32C",8);
data->n_checksum_errors=data->n_crc32c_calculated-data->n_crc32c_correct;
ok = TRUE;
}
if (!ok)
{
- strcpy(data->checksum_type,"UNKNOWN");
+ g_strlcpy(data->checksum_type,"UNKNOWN",8);
data->n_checksum_errors=0;
}
}
+/* XXX: Some versions of gcc warn about "breaking strict aliasing rules"
+ for 'a' in the following (given the way this function is called).
+ As a workaround we'll define the function parameters to match
+ how this function is actually called. */
+/*******
static gint sctp_assoc_vtag_cmp(gconstpointer aa, gconstpointer bb)
{
-
const struct _sctp_assoc_info* a = aa;
const struct _sctp_assoc_info* b = bb;
-
if (a == b)
return(FORWARD_STREAM);
+********/
+
+static gint sctp_assoc_vtag_cmp(const sctp_tmp_info_t *a, const sctp_assoc_info_t *b)
+{
if (a == NULL || b == NULL)
return(ASSOC_NOT_FOUND);
(a->port2 == b->port2) &&
(a->verification_tag1 == b->verification_tag1) && a->verification_tag1==0 && a->initiate_tag != 0 &&
(a->initiate_tag != b->initiate_tag ))
- return(ASSOC_NOT_FOUND);
+ return(ASSOC_NOT_FOUND); /* two INITs that belong to different assocs */
/* assoc known*/
if ((a->port1 == b->port1) &&
(a->port2 == b->port2) &&
(a->verification_tag1 == b->verification_tag1) &&
- ((a->verification_tag1 != 0 ||
+ ((a->verification_tag1 != 0 ||
(b->verification_tag2 != 0))))
return(FORWARD_STREAM);
+ /* ABORT, vtag reflected */
+ if ((a->port1 == b->port1) &&
+ (a->port2 == b->port2) &&
+ (a->verification_tag2 == b->verification_tag2) &&
+ (a->verification_tag1 == 0 && b->verification_tag1 != 0))
+ return(FORWARD_STREAM);
+
if ((a->port1 == b->port2) &&
(a->port2 == b->port1) &&
(a->verification_tag1 == b->verification_tag2) &&
(a->verification_tag1 != 0))
return(BACKWARD_STREAM);
-
+
if ((a->port1 == b->port2) &&
(a->port2 == b->port1) &&
(a->verification_tag2 == b->verification_tag1) &&
(a->verification_tag2 != 0))
return(BACKWARD_STREAM);
+ /* ABORT, vtag reflected */
+ if ((a->port1 == b->port2) &&
+ (a->port2 == b->port1) &&
+ (a->verification_tag2 == b->verification_tag1) &&
+ (a->verification_tag1 == 0 && b->verification_tag2 != 0))
+ return(BACKWARD_STREAM);
+
/*forward stream verifivation tag can be added*/
if ((a->port1 == b->port1) &&
(a->port2 == b->port2) &&
(b->verification_tag1 == 0) &&
(b->verification_tag2 !=0))
return (FORWARD_ADD_FORWARD_VTAG);
-
+
if ((a->port1 == b->port2) &&
(a->port2 == b->port1) &&
(a->verification_tag1 == b->verification_tag2) &&
(b->verification_tag1 == 0))
return (BACKWARD_ADD_FORWARD_VTAG);
-
+
/*backward stream verification tag can be added */
if ((a->port1 == b->port2) &&
(a->port2 == b->port1) &&
info->verification_tag2=needle->verification_tag1;
info->direction = 2;
return info;
- case ADDRESS_FORWARD_STREAM:
+ case ADDRESS_FORWARD_STREAM:
info = (sctp_assoc_info_t*)(list->data);
info->direction = 1;
info->check_address=TRUE;
guint8 * dat;
int i;
- list = g_list_first(info->addr_chunk_count);
-
+ list = g_list_first(info->addr_chunk_count);
+
while (list)
{
ch = (sctp_addr_chunk *)(list->data);
if (ch->direction == direction)
{
v = (address *) (ch->addr);
- if (*(vadd->data)==*(v->data))
+ if (ADDRESSES_EQUAL(vadd, v))
{
- ch->addr_count[type]++;
+ if (IS_SCTP_CHUNK_TYPE(type))
+ ch->addr_count[type]++;
+ else
+ ch->addr_count[OTHER_CHUNKS_INDEX]++;
return info;
}
else
}
ch = g_malloc(sizeof(sctp_addr_chunk));
ch->direction = direction;
- ch->addr = g_malloc(sizeof(address));
+ ch->addr = g_malloc(sizeof(address));
ch->addr->type = vadd->type;
ch->addr->len = vadd->len;
dat = g_malloc(vadd->len);
memcpy(dat, vadd->data, vadd->len);
ch->addr->data = dat;
- for (i=0; i<13; i++)
+ for (i=0; i < NUM_CHUNKS; i++)
ch->addr_count[i] = 0;
- ch->addr_count[type]++;
+
+ 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;
}
{
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 (v->type == AT_IPv4 && vadd->type == AT_IPv4)
- {
- if (*vadd->data!=*v->data)
- {
- list = g_list_next(list);
- }
- else
- {
- g_free(vadd);
- return info;
- }
- }
- else if (v->type == AT_IPv6 && vadd->type == AT_IPv6)
- {
- if (strcmp(ip6_to_str((const struct e_in6_addr *)(vadd->data)), ip6_to_str((const struct e_in6_addr *)v->data)))
- {
- list = g_list_next(list);
- }
- else
- {
- g_free(vadd);
- return info;
- }
- }
- else
- {
- list = g_list_next(list);
+ if (ADDRESSES_EQUAL(vadd, v)) {
+ 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);
+ info->addr2 = g_list_append(info->addr2, vadd);
return info;
}
packet(void *tapdata _U_, packet_info *pinfo , epan_dissect_t *edt _U_ , const void *data)
{
struct _sctp_info *sctp_info;
- guint32 chunk_number = 0, tsnumber;
+ guint32 chunk_number = 0, tsnumber,framenumber;
sctp_tmp_info_t tmp_info;
sctp_assoc_info_t *info = NULL;
sctp_error_info_t *error = NULL;
struct tsn_sort *tsn_s;
guint8* addr = NULL;
int i;
+ guint8 idx = 0;
sctp_allassocs_info_t *assoc_info=NULL;
assoc_info = &sctp_tapinfo_struct;
sctp_info = (struct _sctp_info *) data;
max =0xFFFFFFFF;
+ framenumber=pinfo->fd->num;
+
type = sctp_info->ip_src.type;
if (type == AT_IPv4)
tmp_info.src.type = AT_IPv6;
tmp_info.src.len = 16;
}
-
+ else
+ {
+ tmp_info.src.type = AT_NONE;
+ tmp_info.src.len = 0;
+ }
+
addr = g_malloc(tmp_info.src.len);
memcpy(addr, sctp_info->ip_src.data, tmp_info.src.len);
tmp_info.src.data = addr;
tmp_info.dst.type = AT_IPv6;
tmp_info.dst.len = 16;
}
-
+ else
+ {
+ tmp_info.dst.type = AT_NONE;
+ tmp_info.dst.len = 0;
+ }
+
addr = g_malloc(tmp_info.dst.len);
memcpy(addr, sctp_info->ip_dst.data, tmp_info.dst.len);
tmp_info.dst.data = addr;
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_SACK_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))
{
tsn = g_malloc(sizeof(tsn_t));
sack = g_malloc(sizeof(tsn_t));
tsn->tsns = NULL;
+ tsn->first_tsn = 0;
sack->tsns = NULL;
+ sack->first_tsn = 0;
sack->src.type=tsn->src.type = tmp_info.src.type;
sack->src.len=tsn->src.len = tmp_info.src.len;
addr = g_malloc(tmp_info.src.len);
sack->secs=tsn->secs = (guint32)pinfo->fd->rel_ts.secs;
sack->usecs=tsn->usecs = (guint32)pinfo->fd->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_SACK_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))
{
if (tsn->secs < info->min_secs)
{
store->type = AT_IPv6;;
store->len = 16;
store->data = g_malloc(16);
- tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(store->data),IPV6_ADDRESS_OFFSET, IPV6_ADDRESS_LENGTH);
+ tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(store->data),IPV6_ADDRESS_OFFSET, IPV6_ADDRESS_LENGTH);
info = add_address(store, info, 1);
}
}
-
+
if (tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID)
{
info->init = TRUE;
info->initack_dir = 1;
info->initack = TRUE;
}
- info->chunk_count[tvb_get_guint8(sctp_info->tvb[0],0)]++;
- info->ep1_chunk_count[tvb_get_guint8(sctp_info->tvb[0],0)]++;
- info = add_chunk_count(&tmp_info.src, info, 1, tvb_get_guint8(sctp_info->tvb[0],0));
+
+ 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);
}
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_SACK_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))
{
tsn = g_malloc(sizeof(tsn_t));
sack = g_malloc(sizeof(tsn_t));
tsn->tsns = NULL;
sack->tsns = NULL;
+ tsn->first_tsn = 0;
+ sack->first_tsn = 0;
}
for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
{
- if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0)) < 12)
- {
- info->chunk_count[tvb_get_guint8(sctp_info->tvb[0],0)]++;
- info->ep1_chunk_count[tvb_get_guint8(sctp_info->tvb[0],0)]++;
- info = add_chunk_count(&tmp_info.src, info, 1, tvb_get_guint8(sctp_info->tvb[0],0));
- }
- else
- {
- info->chunk_count[12]++;
- info->ep1_chunk_count[12]++;
- info = add_chunk_count(&tmp_info.src, info, 1, 12);
- }
+ 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)
{
length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
info->n_data_bytes_ep1+=length;
info->max_tsn1 = tsnumber;
}
+ if (tsn->first_tsn == 0)
+ tsn->first_tsn = tsnumber;
t_s_n = g_malloc(16);
tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, 16);
tsn->tsns = g_list_append(tsn->tsns, t_s_n);
datachunk = TRUE;
tsn_s = g_malloc(sizeof(struct tsn_sort));
tsn_s->tsnumber = tsnumber;
- tsn_s->secs = tsn->secs;
- tsn_s->usecs = tsn->usecs;
+ tsn_s->secs = tsn->secs = (guint32)pinfo->fd->rel_ts.secs;
+ tsn_s->usecs = tsn->usecs = (guint32)pinfo->fd->rel_ts.nsecs/1000;
tsn_s->offset = 0;
+ tsn_s->framenumber = framenumber;
tsn_s->length = length-DATA_CHUNK_HEADER_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)
+ 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->max_tsn2 = tsnumber;
info->n_sack_chunks_ep2++;
length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET);
+ if (sack->first_tsn == 0)
+ sack->first_tsn = tsnumber;
t_s_n = 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_malloc(sizeof(struct tsn_sort));
tsn_s->tsnumber = tsnumber;
- tsn_s->secs = tsn->secs;
- tsn_s->usecs = tsn->usecs;
+ tsn_s->secs = tsn->secs = (guint32)pinfo->fd->rel_ts.secs;
+ tsn_s->usecs = tsn->usecs = (guint32)pinfo->fd->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++;
}
{
error = g_malloc(sizeof(sctp_error_info_t));
error->frame_number = pinfo->fd->num;
- strcpy(str,"");
- strcpy(error->chunk_info,"");
+ str[0] = '\0';
+ error->chunk_info[0] = '\0';
if ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID)
- strcpy(error->chunk_info, val_to_str(tvb_get_guint8(sctp_info->tvb[0],0),chunk_type_values,"Reserved"));
+ g_strlcpy(error->chunk_info, val_to_str(tvb_get_guint8(sctp_info->tvb[0],0),chunk_type_values,"Reserved"), 200);
else
for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
- strcat(error->chunk_info, val_to_str(tvb_get_guint8(sctp_info->tvb[chunk_number],0),chunk_type_values,"Reserved"));
+ g_strlcat(error->chunk_info, val_to_str(tvb_get_guint8(sctp_info->tvb[chunk_number],0),chunk_type_values,"Reserved"), 200);
error->info_text = "INFOS";
info->error_info_list = g_list_append(info->error_info_list, error);
}
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_SACK_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))
{
tsn = g_malloc(sizeof(tsn_t));
sack = g_malloc(sizeof(tsn_t));
tsn->tsns = NULL;
+ tsn->first_tsn = 0;
sack->tsns = NULL;
+ sack->first_tsn = 0;
sack->src.type = tsn->src.type = tmp_info.src.type;
sack->src.len = tsn->src.len = tmp_info.src.len;
addr = g_malloc(tmp_info.src.len);
sack->dst.len = tsn->dst.len = tmp_info.dst.len;
addr = g_malloc(tmp_info.dst.len);
memcpy(addr, tmp_info.dst.data, tmp_info.dst.len);
- tsn->dst.data = addr;
+ tsn->dst.data = addr;
addr = g_malloc(tmp_info.dst.len);
memcpy(addr, tmp_info.dst.data, tmp_info.dst.len);
sack->dst.data = addr;
sack->secs=tsn->secs = (guint32)pinfo->fd->rel_ts.secs;
sack->usecs=tsn->usecs = (guint32)pinfo->fd->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_SACK_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))
{
if (tsn->secs < info->min_secs)
{
addr = g_malloc(tmp_info.src.len);
memcpy(addr,(tmp_info.src.data),tmp_info.src.len);
store->data = addr;
-
+
if (info->direction == 1)
info = add_address(store, info, 1);
else if (info->direction == 2)
info = add_address(store, info, 2);
-
+
store = g_malloc(sizeof (address));
store->type = tmp_info.dst.type;
store->len = tmp_info.dst.len;
addr = g_malloc(tmp_info.dst.len);
memcpy(addr,(tmp_info.dst.data),tmp_info.dst.len);
store->data = addr;
-
+
if (info->direction == 1)
info = add_address(store, info, 2);
else if (info->direction == 2)
/*info->initack_dir=1;*/
info->tsn1 = g_list_prepend(info->tsn1, tsn);
}
- info->chunk_count[tvb_get_guint8(sctp_info->tvb[0],0)]++;
+
+ 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[tvb_get_guint8(sctp_info->tvb[0],0)]++;
+ info->ep1_chunk_count[idx]++;
else
- info->ep2_chunk_count[tvb_get_guint8(sctp_info->tvb[0],0)]++;
- info = add_chunk_count(&tmp_info.src, info, info->direction, tvb_get_guint8(sctp_info->tvb[0],0));
+ 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 (((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_SACK_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))
{
sack = g_malloc(sizeof(tsn_t));
sack->tsns = NULL;
+ sack->first_tsn = 0;
tsn = g_malloc(sizeof(tsn_t));
tsn->tsns = NULL;
+ tsn->first_tsn = 0;
}
for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
{
- if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0)) < 12)
- {
- info->chunk_count[tvb_get_guint8(sctp_info->tvb[chunk_number],0)]++;
- if (info->direction == 1)
- info->ep1_chunk_count[tvb_get_guint8(sctp_info->tvb[chunk_number],0)]++;
- else
- info->ep2_chunk_count[tvb_get_guint8(sctp_info->tvb[chunk_number],0)]++;
- info = add_chunk_count(&tmp_info.src, info,info->direction, tvb_get_guint8(sctp_info->tvb[chunk_number],0));
- }
+ 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->chunk_count[12]++;
- if (info->direction == 1)
- info->ep1_chunk_count[12]++;
- else
- info->ep2_chunk_count[12]++;
- info = add_chunk_count(&tmp_info.src, info, info->direction,12);
- }
+ 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)
{
tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], DATA_CHUNK_TSN_OFFSET);
+ if (tsn->first_tsn == 0)
+ tsn->first_tsn = tsnumber;
t_s_n = g_malloc(16);
tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, 16);
tsn->tsns = g_list_append(tsn->tsns, t_s_n);
info->n_data_bytes+=length;
tsn_s = g_malloc(sizeof(struct tsn_sort));
tsn_s->tsnumber = tsnumber;
- tsn_s->secs = tsn->secs;
- tsn_s->usecs = tsn->usecs;
+ tsn_s->secs = tsn->secs = (guint32)pinfo->fd->rel_ts.secs;
+ tsn_s->usecs = tsn->usecs = (guint32)pinfo->fd->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(tsnumber < info->min_tsn1)
info->outstream1 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
if (info->initack == FALSE)
info->instream2 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
-
+
g_ptr_array_add(info->sort_tsn1, tsn_s);
info->n_array_tsn1++;
}
else if (info->direction == 2)
{
-
+
if(tsnumber < info->min_tsn2)
info->min_tsn2 = tsnumber;
-
+
if ((info->initack == TRUE && info->initack_dir == 2)&& tsnumber >= info->min_tsn2 && tsnumber <= info->max_tsn2)
{
length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
info->instream1 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
if (info->initack == FALSE)
info->outstream2 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
-
+
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)
+ 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))
{
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 = 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_malloc(sizeof(struct tsn_sort));
tsn_s->tsnumber = tsnumber;
- tsn_s->secs = tsn->secs;
- tsn_s->usecs = tsn->usecs;
+ tsn_s->secs = tsn->secs = (guint32)pinfo->fd->rel_ts.secs;
+ tsn_s->usecs = tsn->usecs = (guint32)pinfo->fd->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)
}
else if (info->direction == 1)
{
-
+
if(tsnumber < info->min_tsn2)
info->min_tsn2 = tsnumber;
if(tsnumber > info->max_tsn2)
g_ptr_array_add(info->sort_sack2, tsn_s);
info->n_sack_chunks_ep2++;
}
-
+
}
}
}
-/* XXX just copied from gtk/rpc_stat.c */
-void protect_thread_critical_region(void);
-void unprotect_thread_critical_region(void);
-
/****************************************************************************/
void
remove_tap_listener_sctp_stat(void)
if (!sctp_tapinfo_struct.is_registered)
{
- if ((error_string = register_tap_listener("sctp", &sctp_tapinfo_struct, NULL, reset, packet, sctp_update))) {
- simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, error_string->str);
+ if ((error_string = register_tap_listener("sctp", &sctp_tapinfo_struct, NULL, 0, reset, packet, sctp_update))) {
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", error_string->str);
g_string_free(error_string, TRUE);
return;
}