From ac7e609b9f87d2f53b7dc77574ecd4c269f6d384 Mon Sep 17 00:00:00 2001 From: ruengeler Date: Thu, 19 Apr 2018 10:21:27 +0200 Subject: SCTP: INIT collision Change-Id: I283ce92048af39ff4cf54e5e401e714bf6ec308b Reviewed-on: https://code.wireshark.org/review/27023 Petri-Dish: Peter Wu Tested-by: Petri Dish Buildbot Reviewed-by: Peter Wu --- ui/qt/sctp_graph_dialog.cpp | 8 +--- ui/tap-sctp-analysis.c | 98 +++++++++++++++++++++++++++++++++++++++------ ui/tap-sctp-analysis.h | 27 +++++++------ 3 files changed, 101 insertions(+), 32 deletions(-) (limited to 'ui') diff --git a/ui/qt/sctp_graph_dialog.cpp b/ui/qt/sctp_graph_dialog.cpp index a5afe34738..840bf04c3d 100644 --- a/ui/qt/sctp_graph_dialog.cpp +++ b/ui/qt/sctp_graph_dialog.cpp @@ -304,7 +304,6 @@ void SCTPGraphDialog::drawTSNGraph() void SCTPGraphDialog::drawGraph(int which) { guint32 maxTSN, minTSN; - gint64 minBound; gIsSackChunkPresent = false; gIsNRSackChunkPresent = false; @@ -339,12 +338,7 @@ void SCTPGraphDialog::drawGraph(int which) connect(ui->sctpPlot, SIGNAL(plottableClick(QCPAbstractPlottable*,QMouseEvent*)), this, SLOT(graphClicked(QCPAbstractPlottable*, QMouseEvent*))); // set axes ranges, so we see all data: QCPRange myXRange(selected_assoc->min_secs, (selected_assoc->max_secs+1)); - if (maxTSN - minTSN < 5) { - minBound = 0; - } else { - minBound = minTSN; - } - QCPRange myYRange(minBound, maxTSN); + QCPRange myYRange(minTSN, maxTSN); ui->sctpPlot->xAxis->setRange(myXRange); ui->sctpPlot->yAxis->setRange(myYRange); ui->sctpPlot->replot(); diff --git a/ui/tap-sctp-analysis.c b/ui/tap-sctp-analysis.c index d714c0665e..c74d0a7116 100644 --- a/ui/tap-sctp-analysis.c +++ b/ui/tap-sctp-analysis.c @@ -142,6 +142,8 @@ reset(void *arg) g_slist_foreach(info->min_max, free_first, NULL); info->min_max = NULL; } + g_free(info->dir1); + g_free(info->dir2); g_free(list->data); list = g_list_next(list); @@ -389,6 +391,7 @@ packet(void *tapdata _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const voi info->init = FALSE; info->initack = FALSE; info->check_address = FALSE; + info->firstdata = TRUE; info->direction = sctp_info->direction; info = calc_checksum(sctp_info, info); info->n_packets = 1; @@ -421,6 +424,12 @@ packet(void *tapdata _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const voi info->sort_tsn2 = g_ptr_array_new(); info->sort_sack1 = g_ptr_array_new(); info->sort_sack2 = g_ptr_array_new(); + 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++) { @@ -514,6 +523,27 @@ packet(void *tapdata _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const voi 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 { @@ -559,8 +589,8 @@ packet(void *tapdata _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const voi } 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) @@ -802,7 +832,6 @@ packet(void *tapdata _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const voi ((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) @@ -851,6 +880,33 @@ packet(void *tapdata _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const voi 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->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->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->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->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; @@ -923,7 +979,7 @@ packet(void *tapdata _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const voi } tsn->tsns = g_list_append(tsn->tsns, t_s_n); - tsn_s = g_new(struct tsn_sort, 1); + 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; @@ -949,9 +1005,19 @@ packet(void *tapdata _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const voi if (info->direction == 1) { - if(tsnumber < info->min_tsn1) - info->min_tsn1 = tsnumber; - if ((info->init == TRUE || (info->initack == TRUE && info->initack_dir == 1))&& tsnumber >= info->min_tsn1 && tsnumber <= info->max_tsn1) + if (info->firstdata) { + info->firstdata = FALSE; + if (info->init_collision) { + if (tsnumber != info->min_tsn1) { + info->min_tsn1 = info->dir1->init_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) { @@ -989,11 +1055,20 @@ packet(void *tapdata _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const voi } 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; + } + } + } else { + if(tsnumber < info->min_tsn2) + info->min_tsn2 = tsnumber; + } - 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) + if ((info->initack && info->initack_dir == 2)&& tsnumber >= info->min_tsn2 && tsnumber <= info->max_tsn2) { if (datachunk) { @@ -1054,7 +1129,7 @@ packet(void *tapdata _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const voi 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 = 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; @@ -1092,7 +1167,6 @@ packet(void *tapdata _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const voi } else if (info->direction == 1) { - if(tsnumber < info->min_tsn2) info->min_tsn2 = tsnumber; if(tsnumber > info->max_tsn2) diff --git a/ui/tap-sctp-analysis.h b/ui/tap-sctp-analysis.h index 5d2f37a296..5bd5dbde74 100644 --- a/ui/tap-sctp-analysis.h +++ b/ui/tap-sctp-analysis.h @@ -159,17 +159,14 @@ typedef struct _sctp_tmp_info { guint32 n_tvbs; } sctp_tmp_info_t; -typedef struct _sctp_min_max { - guint32 tmp_min_secs; - guint32 tmp_min_usecs; - guint32 tmp_max_secs; - guint32 tmp_max_usecs; - guint32 tmp_min_tsn1; - guint32 tmp_min_tsn2; - guint32 tmp_max_tsn1; - guint32 tmp_max_tsn2; - gint tmp_secs; -} sctp_min_max_t; +typedef struct _sctp_init_collision { + guint32 init_vtag; /* initiate tag of the INIT chunk */ + guint32 initack_vtag; /* initiate tag of the INIT-ACK chunk */ + guint32 init_min_tsn; /* initial tsn of the INIT chunk */ + guint32 initack_min_tsn; /* initial tsn of the INIT-ACK chunk */ + gboolean init:1; + gboolean initack:1; +} sctp_init_collision_t; struct tsn_sort{ guint32 tsnumber; @@ -234,8 +231,10 @@ typedef struct _sctp_assoc_info { guint32 max_window2; guint32 arwnd1; guint32 arwnd2; - gboolean init; - gboolean initack; + gboolean init:1; + gboolean initack:1; + gboolean firstdata:1; + gboolean init_collision:1; guint16 initack_dir; guint16 direction; guint32 min_secs; @@ -248,6 +247,8 @@ typedef struct _sctp_assoc_info { guint32 max_tsn2; guint32 max_bytes1; guint32 max_bytes2; + sctp_init_collision_t *dir1; + sctp_init_collision_t *dir2; GSList *min_max; GList *frame_numbers; GList *tsn1; -- cgit v1.2.3