SCTP: INIT collision

Change-Id: I283ce92048af39ff4cf54e5e401e714bf6ec308b
Reviewed-on: https://code.wireshark.org/review/27023
Petri-Dish: Peter Wu <peter@lekensteyn.nl>
Tested-by: Petri Dish Buildbot
Reviewed-by: Peter Wu <peter@lekensteyn.nl>
This commit is contained in:
ruengeler 2018-04-19 10:21:27 +02:00 committed by Peter Wu
parent e96c3d008e
commit ac7e609b9f
4 changed files with 104 additions and 33 deletions

View File

@ -699,7 +699,9 @@ find_assoc_index(assoc_info_t* tmpinfo, gboolean visited)
inf.direction = info->direction;
return inf;
} else if ((tmpinfo->verification_tag1 != 0 && tmpinfo->verification_tag1 == info->verification_tag2) ||
(tmpinfo->verification_tag2 != 0 && tmpinfo->verification_tag2 == info->verification_tag1)) {
(tmpinfo->verification_tag2 != 0 && tmpinfo->verification_tag2 == info->verification_tag1) ||
(tmpinfo->verification_tag1 == 0 && tmpinfo->initiate_tag != 0 &&
tmpinfo->initiate_tag == info->verification_tag1)) {
inf.assoc_index = info->assoc_index;
if (info->direction == 1)
inf.direction = 2;

View File

@ -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();

View File

@ -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)

View File

@ -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;