aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIrene RĂ¼ngeler <I.Ruengeler@fh-muenster.de>2013-12-13 07:25:30 +0000
committerIrene RĂ¼ngeler <I.Ruengeler@fh-muenster.de>2013-12-13 07:25:30 +0000
commit796bf409b0c286dd76e6ecd5c61d0d947d54b479 (patch)
tree42d21c7d8b1175adf0f155f5c0fb9f53feb795d5
parent28e6aa4e8a06299895d7924508a32a895a5454ab (diff)
Add dialogs and graphs to analyse SCTP behavior similar to the GTK version.
svn path=/trunk/; revision=54026
-rw-r--r--epan/dissectors/packet-sctp.c7
-rw-r--r--epan/value_string.h9
-rw-r--r--ui/gtk/Makefile.common1
-rw-r--r--ui/qt/CMakeLists.txt18
-rw-r--r--ui/qt/Makefile.common24
-rw-r--r--ui/qt/QtShark.pro24
-rw-r--r--ui/qt/main_window.h5
-rw-r--r--ui/qt/main_window.ui18
-rw-r--r--ui/qt/main_window_slots.cpp56
-rw-r--r--ui/qt/packet_list.cpp20
-rw-r--r--ui/qt/sctp_all_assocs_dialog.cpp144
-rw-r--r--ui/qt/sctp_all_assocs_dialog.h52
-rw-r--r--ui/qt/sctp_all_assocs_dialog.ui433
-rw-r--r--ui/qt/sctp_assoc_analyse_dialog.cpp292
-rw-r--r--ui/qt/sctp_assoc_analyse_dialog.h66
-rw-r--r--ui/qt/sctp_assoc_analyse_dialog.ui607
-rw-r--r--ui/qt/sctp_chunk_statistics_dialog.cpp288
-rw-r--r--ui/qt/sctp_chunk_statistics_dialog.h75
-rw-r--r--ui/qt/sctp_chunk_statistics_dialog.ui160
-rw-r--r--ui/qt/sctp_graph_arwnd_dialog.cpp141
-rw-r--r--ui/qt/sctp_graph_arwnd_dialog.h57
-rw-r--r--ui/qt/sctp_graph_arwnd_dialog.ui129
-rw-r--r--ui/qt/sctp_graph_byte_dialog.cpp145
-rw-r--r--ui/qt/sctp_graph_byte_dialog.h55
-rw-r--r--ui/qt/sctp_graph_byte_dialog.ui129
-rw-r--r--ui/qt/sctp_graph_dialog.cpp399
-rw-r--r--ui/qt/sctp_graph_dialog.h114
-rw-r--r--ui/qt/sctp_graph_dialog.ui177
-rw-r--r--ui/tap-sctp-analysis.c216
-rw-r--r--ui/tap-sctp-analysis.h52
30 files changed, 3698 insertions, 215 deletions
diff --git a/epan/dissectors/packet-sctp.c b/epan/dissectors/packet-sctp.c
index edfa689660..717d132f8c 100644
--- a/epan/dissectors/packet-sctp.c
+++ b/epan/dissectors/packet-sctp.c
@@ -4671,11 +4671,11 @@ proto_register_sctp(void)
UAT_FLD_VS(type_fields, type_enable, "Visibility", chunk_enabled, "Hide or show the type in the chunk statistics"),
UAT_END_FIELDS
};
-
+
module_t *sctp_module;
expert_module_t* expert_sctp;
uat_t* chunk_types_uat;
-
+
chunk_types_uat = uat_new("Chunk types for the statistics dialog",
sizeof(type_field_t),
"statistics_chunk_types",
@@ -4689,8 +4689,7 @@ proto_register_sctp(void)
sctp_chunk_type_free_cb,
NULL,
custom_types_uat_fields
- );
-
+);
/* Register the protocol name and description */
proto_sctp = proto_register_protocol("Stream Control Transmission Protocol", "SCTP", "sctp");
diff --git a/epan/value_string.h b/epan/value_string.h
index d5326a2776..c83aa73b24 100644
--- a/epan/value_string.h
+++ b/epan/value_string.h
@@ -25,6 +25,10 @@
#ifndef __VALUE_STRING_H__
#define __VALUE_STRING_H__
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
#include <glib.h>
#include "ws_symbol_export.h"
@@ -250,8 +254,11 @@ WS_DLL_LOCAL
const gchar *
value_string_ext_match_type_str(const value_string_ext *vse);
-#endif /* __VALUE_STRING_H__ */
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __VALUE_STRING_H__ */
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
diff --git a/ui/gtk/Makefile.common b/ui/gtk/Makefile.common
index 0012d17885..aa41da4518 100644
--- a/ui/gtk/Makefile.common
+++ b/ui/gtk/Makefile.common
@@ -220,6 +220,7 @@ WIRESHARK_TAP_SRC = \
sctp_assoc_analyse.c \
sctp_chunk_stat.c \
sctp_chunk_stat_dlg.c \
+ sctp_stat.c \
sctp_stat_dlg.c \
sip_stat.c \
smb_stat.c \
diff --git a/ui/qt/CMakeLists.txt b/ui/qt/CMakeLists.txt
index 7a3686fe34..807f7b775c 100644
--- a/ui/qt/CMakeLists.txt
+++ b/ui/qt/CMakeLists.txt
@@ -70,6 +70,12 @@ set(WIRESHARK_QT_HEADERS
proto_tree.h
qcustomplot.h
recent_file_status.h
+ sctp_all_assocs_dialog.h
+ sctp_assoc_analyse_dialog.h
+ sctp_chunk_statistics_dialog.h
+ sctp_graph_dialog.h
+ sctp_graph_arwnd_dialog.h
+ sctp_graph_byte_dialog.h
search_frame.h
sequence_diagram.h
sequence_dialog.h
@@ -141,6 +147,12 @@ set(WIRESHARK_QT_SRC
qt_ui_utils.cpp
recent_file_status.cpp
related_packet_delegate.cpp
+ sctp_all_assocs_dialog.cpp
+ sctp_assoc_analyse_dialog.cpp
+ sctp_chunk_statistics_dialog.cpp
+ sctp_graph_dialog.cpp
+ sctp_graph_arwnd_dialog.cpp
+ sctp_graph_byte_dialog.cpp
search_frame.cpp
sequence_diagram.cpp
sequence_dialog.cpp
@@ -190,6 +202,12 @@ set(WIRESHARK_QT_UI
preferences_dialog.ui
print_dialog.ui
profile_dialog.ui
+ sctp_all_assocs_dialog.ui
+ sctp_assoc_analyse_dialog.ui
+ sctp_chunk_statistics_dialog.ui
+ sctp_graph_dialog.ui
+ sctp_graph_arwnd_dialog.ui
+ sctp_graph_byte_dialog.ui
search_frame.ui
sequence_dialog.ui
splash_overlay.ui
diff --git a/ui/qt/Makefile.common b/ui/qt/Makefile.common
index 340f2feba6..0c2ed5d740 100644
--- a/ui/qt/Makefile.common
+++ b/ui/qt/Makefile.common
@@ -52,6 +52,12 @@ NODIST_GENERATED_HEADER_FILES = \
ui_preferences_dialog.h \
ui_print_dialog.h \
ui_profile_dialog.h \
+ ui_sctp_all_assocs_dialog.h \
+ ui_sctp_assoc_analyse_dialog.h \
+ ui_sctp_chunk_statistics_dialog.h \
+ ui_sctp_graph_dialog.h \
+ ui_sctp_graph_arwnd_dialog.h \
+ ui_sctp_graph_byte_dialog.h \
ui_stats_tree_dialog.h \
ui_search_frame.h \
ui_sequence_dialog.h \
@@ -143,6 +149,12 @@ MOC_HDRS = \
recent_file_status.h \
related_packet_delegate.h \
search_frame.h \
+ sctp_all_assocs_dialog.h \
+ sctp_assoc_analyse_dialog.h \
+ sctp_chunk_statistics_dialog.h \
+ sctp_graph_dialog.h \
+ sctp_graph_arwnd_dialog.h \
+ sctp_graph_byte_dialog.h \
sequence_diagram.h \
sequence_dialog.h \
simple_dialog_qt.h \
@@ -182,6 +194,12 @@ UI_FILES = \
preferences_dialog.ui \
print_dialog.ui \
profile_dialog.ui \
+ sctp_all_assocs_dialog.ui \
+ sctp_assoc_analyse_dialog.ui \
+ sctp_chunk_statistics_dialog.ui \
+ sctp_graph_dialog.ui \
+ sctp_graph_arwnd_dialog.ui \
+ sctp_graph_byte_dialog.ui \
search_frame.ui \
sequence_dialog.ui \
splash_overlay.ui \
@@ -291,6 +309,12 @@ WIRESHARK_QT_SRC = \
qt_ui_utils.cpp \
recent_file_status.cpp \
related_packet_delegate.cpp \
+ sctp_all_assocs_dialog.cpp \
+ sctp_assoc_analyse_dialog.cpp \
+ sctp_chunk_statistics_dialog.cpp \
+ sctp_graph_dialog.cpp \
+ sctp_graph_arwnd_dialog.cpp \
+ sctp_graph_byte_dialog.cpp \
search_frame.cpp \
sequence_diagram.cpp \
sequence_dialog.cpp \
diff --git a/ui/qt/QtShark.pro b/ui/qt/QtShark.pro
index 5fc5f92492..fa4c05ee2d 100644
--- a/ui/qt/QtShark.pro
+++ b/ui/qt/QtShark.pro
@@ -242,6 +242,12 @@ FORMS += \
preferences_dialog.ui \
print_dialog.ui \
profile_dialog.ui \
+ sctp_all_assocs_dialog.ui \
+ sctp_assoc_analyse_dialog.ui \
+ sctp_chunk_statistics_dialog.ui \
+ sctp_graph_dialog.ui \
+ sctp_graph_arwnd_dialog.ui \
+ sctp_graph_byte_dialog.ui \
search_frame.ui \
sequence_dialog.ui \
splash_overlay.ui \
@@ -272,6 +278,12 @@ HEADERS += $$HEADERS_WS_C \
preferences_dialog.h \
print_dialog.h \
profile_dialog.h \
+ sctp_all_assocs_dialog.h \
+ sctp_assoc_analyse_dialog.h \
+ sctp_chunk_statistics_dialog.h \
+ sctp_graph_dialog.h \
+ sctp_graph_arwnd_dialog.h \
+ sctp_graph_byte_dialog.h \
search_frame.h \
splash_overlay.h \
stats_tree_dialog.h \
@@ -529,6 +541,12 @@ HEADERS += \
qcustomplot.h \
recent_file_status.h \
related_packet_delegate.h \
+ sctp_all_assocs_dialog.h \
+ sctp_assoc_analyse_dialog.h \
+ sctp_chunk_statistics_dialog.h \
+ sctp_graph_dialog.h \
+ sctp_graph_arwnd_dialog.h \
+ sctp_graph_byte_dialog.h \
sequence_diagram.h \
sequence_dialog.h \
simple_dialog_qt.h \
@@ -590,6 +608,12 @@ SOURCES += \
qt_ui_utils.cpp \
recent_file_status.cpp \
related_packet_delegate.cpp \
+ sctp_all_assocs_dialog.cpp \
+ sctp_assoc_analyse_dialog.cpp \
+ sctp_chunk_statistics_dialog.cpp \
+ sctp_graph_dialog.cpp \
+ sctp_graph_arwnd_dialog.cpp \
+ sctp_graph_byte_dialog.cpp \
search_frame.cpp \
sequence_diagram.cpp \
sequence_dialog.cpp \
diff --git a/ui/qt/main_window.h b/ui/qt/main_window.h
index 2ecc38b3eb..448a592cb9 100644
--- a/ui/qt/main_window.h
+++ b/ui/qt/main_window.h
@@ -326,6 +326,9 @@ private slots:
void on_actionStatisticsTcpStreamThroughput_triggered();
void on_actionStatisticsTcpStreamRoundTripTime_triggered();
void on_actionStatisticsTcpStreamWindowScaling_triggered();
+ void openSCTPAllAssocsDialog();
+ void on_actionSCTPShowAllAssociations_triggered();
+ void on_actionSCTPAnalyseThisAssociation_triggered();
#ifdef HAVE_LIBPCAP
void on_actionCaptureInterfaces_triggered();
@@ -349,9 +352,7 @@ private slots:
void on_actionTelephonyRTSPPacketCounter_triggered();
void on_actionTelephonySMPPOperations_triggered();
void on_actionTelephonyUCPMessages_triggered();
-
};
-
#endif // MAINWINDOW_H
/*
diff --git a/ui/qt/main_window.ui b/ui/qt/main_window.ui
index c6fcb5cb38..3f190a76e7 100644
--- a/ui/qt/main_window.ui
+++ b/ui/qt/main_window.ui
@@ -302,6 +302,13 @@
<addaction name="actionAnalyzePAFAndNotSelected"/>
<addaction name="actionAnalyzePAFOrNotSelected"/>
</widget>
+ <widget class="QMenu" name="menuSCTP">
+ <property name="title">
+ <string>SCTP</string>
+ </property>
+ <addaction name="actionSCTPAnalyseThisAssociation"/>
+ <addaction name="actionSCTPShowAllAssociations"/>
+ </widget>
<addaction name="actionDisplayFilters"/>
<addaction name="actionDisplayFilterMacros"/>
<addaction name="separator"/>
@@ -311,6 +318,7 @@
<addaction name="separator"/>
<addaction name="actionAnalyzeDecodeAs"/>
<addaction name="separator"/>
+ <addaction name="menuSCTP"/>
<addaction name="actionAnalyzeFollowTCPStream"/>
<addaction name="actionAnalyzeFollowUDPStream"/>
<addaction name="actionAnalyzeFollowSSLStream"/>
@@ -1360,6 +1368,16 @@
<string>TCP time sequence graph (tcptrace)</string>
</property>
</action>
+ <action name="actionSCTPAnalyseThisAssociation">
+ <property name="text">
+ <string>Analyse this Association</string>
+ </property>
+ </action>
+ <action name="actionSCTPShowAllAssociations">
+ <property name="text">
+ <string>Show All Associations</string>
+ </property>
+ </action>
<action name="actionStatisticsFlowGraph">
<property name="text">
<string>Flow Graph</string>
diff --git a/ui/qt/main_window_slots.cpp b/ui/qt/main_window_slots.cpp
index 9ece59cfbc..e352033769 100644
--- a/ui/qt/main_window_slots.cpp
+++ b/ui/qt/main_window_slots.cpp
@@ -77,6 +77,9 @@
#include "print_dialog.h"
#include "profile_dialog.h"
#include "qt_ui_utils.h"
+#include "sctp_all_assocs_dialog.h"
+#include "sctp_assoc_analyse_dialog.h"
+#include "sctp_graph_dialog.h"
#include "sequence_dialog.h"
#include "stats_tree_dialog.h"
#include "tcp_stream_dialog.h"
@@ -729,7 +732,7 @@ void MainWindow::setMenusForSelectedPacket()
#if 0
gboolean is_ip = FALSE, is_tcp = FALSE, is_udp = FALSE, is_sctp = FALSE;
#else
- gboolean is_tcp = FALSE;
+ gboolean is_tcp = FALSE, is_sctp = FALSE;;
#endif
// /* Making the menu context-sensitive allows for easier selection of the
@@ -773,7 +776,7 @@ void MainWindow::setMenusForSelectedPacket()
if (cap_file_->edt)
{
- proto_get_frame_protocols(cap_file_->edt->pi.layers, NULL, &is_tcp, NULL, NULL);
+ proto_get_frame_protocols(cap_file_->edt->pi.layers, NULL, &is_tcp, NULL, &is_sctp);
}
}
// if (cfile.edt && cfile.edt->tree) {
@@ -922,6 +925,9 @@ void MainWindow::setMenusForSelectedPacket()
// set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/ToolsMenu/FirewallACLRules",
// frame_selected);
main_ui_->menuTcpStreamGraphs->setEnabled(is_tcp);
+ main_ui_->menuSCTP->setEnabled(is_sctp);
+ main_ui_->actionSCTPAnalyseThisAssociation->setEnabled(is_sctp);
+ main_ui_->actionSCTPShowAllAssociations->setEnabled(is_sctp);
// while (list_entry != NULL) {
// dissector_filter_t *filter_entry;
@@ -1743,6 +1749,52 @@ void MainWindow::on_actionAnalyzeFollowSSLStream_triggered()
openFollowStreamDialog(FOLLOW_SSL);
}
+void MainWindow::openSCTPAllAssocsDialog()
+{
+ SCTPAllAssocsDialog *sctp_dialog = new SCTPAllAssocsDialog(this, cap_file_);
+ connect(sctp_dialog, SIGNAL(filterPackets(QString&,bool)),
+ this, SLOT(filterPackets(QString&,bool)));
+ connect(this, SIGNAL(setCaptureFile(capture_file*)),
+ sctp_dialog, SLOT(setCaptureFile(capture_file*)));
+ sctp_dialog->fillTable();
+
+ if (sctp_dialog->isMinimized() == true)
+ {
+ sctp_dialog->showNormal();
+ }
+ else
+ {
+ sctp_dialog->show();
+ }
+
+ sctp_dialog->raise();
+ sctp_dialog->activateWindow();
+}
+
+void MainWindow::on_actionSCTPShowAllAssociations_triggered()
+{
+ openSCTPAllAssocsDialog();
+}
+
+void MainWindow::on_actionSCTPAnalyseThisAssociation_triggered()
+{
+ SCTPAssocAnalyseDialog *sctp_analyse = new SCTPAssocAnalyseDialog(this, NULL, cap_file_);
+ connect(sctp_analyse, SIGNAL(filterPackets(QString&,bool)),
+ this, SLOT(filterPackets(QString&,bool)));
+
+ if (sctp_analyse->isMinimized() == true)
+ {
+ sctp_analyse->showNormal();
+ }
+ else
+ {
+ sctp_analyse->show();
+ }
+
+ sctp_analyse->raise();
+ sctp_analyse->activateWindow();
+}
+
// Next / previous / first / last slots in packet_list
// Statistics Menu
diff --git a/ui/qt/packet_list.cpp b/ui/qt/packet_list.cpp
index b98ebb31d4..987fdd294a 100644
--- a/ui/qt/packet_list.cpp
+++ b/ui/qt/packet_list.cpp
@@ -35,6 +35,7 @@
#include "packet_list.h"
#include "proto_tree.h"
#include "wireshark_application.h"
+#include "epan/ipproto.h"
#include "qt_ui_utils.h"
@@ -258,7 +259,12 @@ PacketList::PacketList(QWidget *parent) :
// " <menuitem name='FollowTCPStream' action='/Follow TCP Stream'/>\n"
// " <menuitem name='FollowUDPStream' action='/Follow UDP Stream'/>\n"
// " <menuitem name='FollowSSLStream' action='/Follow SSL Stream'/>\n"
-
+ submenu = new QMenu(tr("SCTP"));
+ ctx_menu_.addMenu(submenu);
+ submenu->addAction(window()->findChild<QAction *>("actionSCTPAnalyseThisAssociation"));
+ submenu->addAction(window()->findChild<QAction *>("actionSCTPShowAllAssociations"));
+ submenu->addAction(window()->findChild<QAction *>("actionSCTPChunkCounter"));
+ filter_actions_ << submenu->actions();
ctx_menu_.addSeparator();
// " <menuitem name='ManuallyResolveAddress' action='/ManuallyResolveAddress'/>\n"
ctx_menu_.addSeparator();
@@ -473,6 +479,18 @@ void PacketList::contextMenuEvent(QContextMenuEvent *event)
{
act->setEnabled(true);
+ // check SCTP
+ if (act->objectName().contains("SCTP"))
+ {
+ if (cap_file_->edt->pi.ipproto == IP_PROTO_SCTP)
+ {
+ act->setEnabled(true);
+ }
+ else
+ {
+ act->setEnabled(false);
+ }
+ }
// check follow stream
if (act->text().contains("TCP"))
diff --git a/ui/qt/sctp_all_assocs_dialog.cpp b/ui/qt/sctp_all_assocs_dialog.cpp
new file mode 100644
index 0000000000..d51522c4fd
--- /dev/null
+++ b/ui/qt/sctp_all_assocs_dialog.cpp
@@ -0,0 +1,144 @@
+#include "sctp_all_assocs_dialog.h"
+#include "ui_sctp_all_assocs_dialog.h"
+#include "sctp_assoc_analyse_dialog.h"
+
+#include "qt_ui_utils.h"
+//#include "wireshark_application.h"
+#include "file.h"
+#include "ui/qt/main_window.h"
+
+#include <QWidget>
+#include <QDir>
+#include <QFileDialog>
+#include <QIcon>
+#include <QPushButton>
+
+//#include <QDebug>
+
+SCTPAllAssocsDialog::SCTPAllAssocsDialog(QWidget *parent, capture_file *cf) :
+ QDialog(parent),
+ ui(new Ui::SCTPAllAssocsDialog),
+ cap_file_(cf)
+{
+ ui->setupUi(this);
+ sctp_assocs = (sctp_allassocs_info_t *)g_malloc(sizeof(sctp_allassocs_info_t));
+ fillTable();
+}
+
+SCTPAllAssocsDialog::~SCTPAllAssocsDialog()
+{
+ delete ui;
+}
+
+void SCTPAllAssocsDialog::fillTable()
+{
+ QString output;
+ GList *list;
+ sctp_assoc_info_t* assinfo;
+ int numAssocs;
+
+ ui->assocList->setColumnHidden(0, true);
+ ui->assocList->setColumnWidth(1, 85);
+ ui->assocList->setColumnWidth(2, 85);
+ ui->assocList->setColumnWidth(3, 150);
+ ui->assocList->setColumnWidth(4, 150);
+
+ sctp_assocs = (sctp_allassocs_info_t*)sctp_stat_get_info();
+ if (sctp_stat_get_info()->is_registered == FALSE) {
+ register_tap_listener_sctp_stat();
+ }
+ /* (redissect all packets) */
+ cf_retap_packets(cap_file_);
+ numAssocs = 0;
+ ui->assocList->setRowCount(g_list_length(sctp_assocs->assoc_info_list));
+
+ list = g_list_first(sctp_assocs->assoc_info_list);
+
+ while (list) {
+ assinfo = (sctp_assoc_info_t*)(list->data);
+ ui->assocList->setItem(numAssocs, 0, new QTableWidgetItem(QString("%1").arg(assinfo->assoc_id)));
+ ui->assocList->setItem(numAssocs, 1, new QTableWidgetItem(QString("%1").arg(assinfo->port1)));
+ ui->assocList->setItem(numAssocs, 2, new QTableWidgetItem(QString("%1").arg(assinfo->port2)));
+ ui->assocList->setItem(numAssocs, 3, new QTableWidgetItem(QString("%1").arg(assinfo->n_packets)));
+ ui->assocList->setItem(numAssocs, 4, new QTableWidgetItem(QString("%1").arg(assinfo->n_data_chunks)));
+ ui->assocList->setItem(numAssocs, 5, new QTableWidgetItem(QString("%1").arg(assinfo->n_data_bytes)));
+ list = g_list_next(list);
+ numAssocs++;
+ }
+ ui->analyseButton->setEnabled(false);
+ ui->setFilterButton->setEnabled(false);
+ connect(ui->assocList, SIGNAL(itemSelectionChanged()), this, SLOT(getSelectedItem()));
+ }
+
+sctp_assoc_info_t* SCTPAllAssocsDialog::findSelectedAssoc()
+{
+ QTableWidgetItem *selection;
+ GList *list;
+ sctp_assoc_info_t* assinfo;
+ int row, id;
+
+ selection = ui->assocList->selectedItems()[0];
+ row = selection->row();
+ selection = ui->assocList->item(row, 0);
+ id = (selection->data(0)).toInt();
+ list = g_list_first(sctp_assocs->assoc_info_list);
+
+ while (list) {
+ assinfo = (sctp_assoc_info_t*)(list->data);
+ if (assinfo->assoc_id == id) {
+ return assinfo;
+ }
+ list = g_list_next(list);
+ }
+ return NULL;
+}
+
+void SCTPAllAssocsDialog::getSelectedItem()
+{
+ ui->analyseButton->setEnabled(true);
+ ui->setFilterButton->setEnabled(true);
+ ui->analyseButton->setFocus(Qt::OtherFocusReason);
+ selected_assoc = findSelectedAssoc();
+ printf("selection changed assoc now %p with id %d\n",
+ selected_assoc, selected_assoc->assoc_id);
+}
+
+void SCTPAllAssocsDialog::on_analyseButton_clicked()
+{
+
+ if (!selected_assoc) {
+ selected_assoc = findSelectedAssoc();
+ printf("on_analyseButton_clicked found assoc %p with id %d\n",
+ selected_assoc, selected_assoc->assoc_id);
+ }
+
+ SCTPAssocAnalyseDialog *sctp_analyse = new SCTPAssocAnalyseDialog(this, selected_assoc, cap_file_, this);
+ connect(sctp_analyse, SIGNAL(filterPackets(QString&,bool)),
+ parent(), SLOT(filterPackets(QString&,bool)));
+
+ if (sctp_analyse->isMinimized() == true)
+ {
+ sctp_analyse->showNormal();
+ }
+ else
+ {
+ sctp_analyse->show();
+ }
+
+ sctp_analyse->raise();
+ sctp_analyse->activateWindow();
+}
+
+void SCTPAllAssocsDialog::on_setFilterButton_clicked()
+{
+
+ if (!selected_assoc){
+ selected_assoc = findSelectedAssoc();
+ printf("on_setFilterButton_clicked found assoc %p with id %d\n",
+ selected_assoc, selected_assoc->assoc_id);
+ }
+
+ QString newFilter = QString("sctp.assoc_index==%1").arg(selected_assoc->assoc_id);
+ selected_assoc = NULL;
+ emit filterPackets(newFilter, false);
+}
diff --git a/ui/qt/sctp_all_assocs_dialog.h b/ui/qt/sctp_all_assocs_dialog.h
new file mode 100644
index 0000000000..68650e1506
--- /dev/null
+++ b/ui/qt/sctp_all_assocs_dialog.h
@@ -0,0 +1,52 @@
+#ifndef SCTP_ALL_ASSOCS_DIALOG_H
+#define SCTP_ALL_ASSOCS_DIALOG_H
+
+#include "config.h"
+
+#include <glib.h>
+
+#include <file.h>
+
+#include <epan/dissectors/packet-sctp.h>
+
+#include "ui/tap-sctp-analysis.h"
+
+#include <QDialog>
+#include <QObject>
+
+namespace Ui {
+class SCTPAllAssocsDialog;
+}
+
+class SCTPAllAssocsDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit SCTPAllAssocsDialog(QWidget *parent = 0, capture_file *cf = NULL);
+ ~SCTPAllAssocsDialog();
+
+ void fillTable();
+ sctp_assoc_info_t* getSelectedAssoc() { return selected_assoc; };
+ sctp_assoc_info_t* findSelectedAssoc();
+
+public slots:
+ void setCaptureFile(capture_file *cf) { cap_file_ = cf; }
+
+private slots:
+ void on_analyseButton_clicked();
+ void on_setFilterButton_clicked();
+ void getSelectedItem();
+
+private:
+ Ui::SCTPAllAssocsDialog *ui;
+ capture_file *cap_file_;
+ sctp_allassocs_info_t *sctp_assocs;
+ sctp_assoc_info_t *selected_assoc;
+
+
+signals:
+ void filterPackets(QString& new_filter, bool force);
+};
+
+#endif // SCTP_ALL_ASSOCS_DIALOG_H
diff --git a/ui/qt/sctp_all_assocs_dialog.ui b/ui/qt/sctp_all_assocs_dialog.ui
new file mode 100644
index 0000000000..d72c96ae00
--- /dev/null
+++ b/ui/qt/sctp_all_assocs_dialog.ui
@@ -0,0 +1,433 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>SCTPAllAssocsDialog</class>
+ <widget class="QDialog" name="SCTPAllAssocsDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>685</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Wireshark - SCTP Associations</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QTableWidget" name="assocList">
+ <property name="editTriggers">
+ <set>QAbstractItemView::NoEditTriggers</set>
+ </property>
+ <property name="showDropIndicator" stdset="0">
+ <bool>false</bool>
+ </property>
+ <property name="dragDropOverwriteMode">
+ <bool>false</bool>
+ </property>
+ <property name="alternatingRowColors">
+ <bool>true</bool>
+ </property>
+ <property name="selectionMode">
+ <enum>QAbstractItemView::SingleSelection</enum>
+ </property>
+ <property name="selectionBehavior">
+ <enum>QAbstractItemView::SelectRows</enum>
+ </property>
+ <property name="sortingEnabled">
+ <bool>true</bool>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ <property name="rowCount">
+ <number>2</number>
+ </property>
+ <property name="columnCount">
+ <number>6</number>
+ </property>
+ <attribute name="horizontalHeaderDefaultSectionSize">
+ <number>120</number>
+ </attribute>
+ <attribute name="horizontalHeaderMinimumSectionSize">
+ <number>50</number>
+ </attribute>
+ <attribute name="horizontalHeaderStretchLastSection">
+ <bool>true</bool>
+ </attribute>
+ <row/>
+ <row/>
+ <column>
+ <property name="text">
+ <string>ID</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Port 1</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Port 2</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Number of Packets</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Number of DATA Chunks</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Number of Bytes</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout"/>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QPushButton" name="setFilterButton">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::ClickFocus</enum>
+ </property>
+ <property name="text">
+ <string>Filter Selected Association</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="analyseButton">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::ClickFocus</enum>
+ </property>
+ <property name="text">
+ <string>Analyze</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>10</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Close</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ <action name="actionReset">
+ <property name="text">
+ <string>Reset Graph</string>
+ </property>
+ <property name="toolTip">
+ <string>Reset the graph to its initial state.</string>
+ </property>
+ <property name="shortcut">
+ <string>0</string>
+ </property>
+ </action>
+ <action name="actionZoomIn">
+ <property name="text">
+ <string>Zoom In</string>
+ </property>
+ <property name="toolTip">
+ <string>Zoom in</string>
+ </property>
+ <property name="shortcut">
+ <string>+</string>
+ </property>
+ </action>
+ <action name="actionZoomOut">
+ <property name="text">
+ <string>Zoom Out</string>
+ </property>
+ <property name="toolTip">
+ <string>Zoom out</string>
+ </property>
+ <property name="shortcut">
+ <string>-</string>
+ </property>
+ </action>
+ <action name="actionMoveUp10">
+ <property name="text">
+ <string>Move Up 10 Pixels</string>
+ </property>
+ <property name="toolTip">
+ <string>Move up 10 pixels</string>
+ </property>
+ <property name="shortcut">
+ <string>Up</string>
+ </property>
+ </action>
+ <action name="actionMoveLeft10">
+ <property name="text">
+ <string>Move Left 10 Pixels</string>
+ </property>
+ <property name="toolTip">
+ <string>Move left 10 pixels</string>
+ </property>
+ <property name="shortcut">
+ <string>Left</string>
+ </property>
+ </action>
+ <action name="actionMoveRight10">
+ <property name="text">
+ <string>Move Right 10 Pixels</string>
+ </property>
+ <property name="toolTip">
+ <string>Move right 10 pixels</string>
+ </property>
+ <property name="shortcut">
+ <string>Right</string>
+ </property>
+ </action>
+ <action name="actionMoveDown10">
+ <property name="text">
+ <string>Move Down 10 Pixels</string>
+ </property>
+ <property name="toolTip">
+ <string>Move down 10 pixels</string>
+ </property>
+ <property name="shortcut">
+ <string>Down</string>
+ </property>
+ </action>
+ <action name="actionMoveUp1">
+ <property name="text">
+ <string>Move Up 1 Pixel</string>
+ </property>
+ <property name="toolTip">
+ <string>Move up 1 pixel</string>
+ </property>
+ <property name="shortcut">
+ <string>Shift+Up</string>
+ </property>
+ </action>
+ <action name="actionMoveLeft1">
+ <property name="text">
+ <string>Move Left 1 Pixel</string>
+ </property>
+ <property name="toolTip">
+ <string>Move left 1 pixel</string>
+ </property>
+ <property name="shortcut">
+ <string>Shift+Left</string>
+ </property>
+ </action>
+ <action name="actionMoveRight1">
+ <property name="text">
+ <string>Move Right 1 Pixel</string>
+ </property>
+ <property name="toolTip">
+ <string>Move right 1 pixel</string>
+ </property>
+ <property name="shortcut">
+ <string>Shift+Right</string>
+ </property>
+ </action>
+ <action name="actionMoveDown1">
+ <property name="text">
+ <string>Move Down 1 Pixel</string>
+ </property>
+ <property name="toolTip">
+ <string>Move down 1 pixel</string>
+ </property>
+ <property name="shortcut">
+ <string>Shift+Down</string>
+ </property>
+ </action>
+ <action name="actionNextStream">
+ <property name="text">
+ <string>Next Stream</string>
+ </property>
+ <property name="toolTip">
+ <string>Go to the next stream in the capture</string>
+ </property>
+ <property name="shortcut">
+ <string>PgUp</string>
+ </property>
+ </action>
+ <action name="actionPreviousStream">
+ <property name="text">
+ <string>Previous Stream</string>
+ </property>
+ <property name="toolTip">
+ <string>Go to the previous stream in the capture</string>
+ </property>
+ <property name="shortcut">
+ <string>PgDown</string>
+ </property>
+ </action>
+ <action name="actionSwitchDirection">
+ <property name="text">
+ <string>Switch Direction</string>
+ </property>
+ <property name="toolTip">
+ <string>Switch direction (swap TCP endpoints)</string>
+ </property>
+ <property name="shortcut">
+ <string>D</string>
+ </property>
+ </action>
+ <action name="actionGoToPacket">
+ <property name="text">
+ <string>Go To Packet Under Cursor</string>
+ </property>
+ <property name="toolTip">
+ <string>Go to packet currently under the cursor</string>
+ </property>
+ <property name="shortcut">
+ <string>G</string>
+ </property>
+ </action>
+ <action name="actionDragZoom">
+ <property name="text">
+ <string>Drag / Zoom</string>
+ </property>
+ <property name="toolTip">
+ <string>Toggle mouse drag / zoom behavior</string>
+ </property>
+ <property name="shortcut">
+ <string>Z</string>
+ </property>
+ </action>
+ <action name="actionToggleSequenceNumbers">
+ <property name="text">
+ <string>Relative / Absolute Sequence Numbers</string>
+ </property>
+ <property name="toolTip">
+ <string>Toggle relative / absolute sequence numbers</string>
+ </property>
+ <property name="shortcut">
+ <string>S</string>
+ </property>
+ </action>
+ <action name="actionToggleTimeOrigin">
+ <property name="text">
+ <string>Capture / Session Time Origin</string>
+ </property>
+ <property name="toolTip">
+ <string>Toggle capture / session time origin</string>
+ </property>
+ <property name="shortcut">
+ <string>T</string>
+ </property>
+ </action>
+ <action name="actionCrosshairs">
+ <property name="text">
+ <string>Crosshairs</string>
+ </property>
+ <property name="toolTip">
+ <string>Toggle crosshairs</string>
+ </property>
+ <property name="shortcut">
+ <string>Space</string>
+ </property>
+ </action>
+ <action name="actionRoundTripTime">
+ <property name="text">
+ <string>Round Trip Time</string>
+ </property>
+ <property name="toolTip">
+ <string>Switch to the Round Trip Time graph</string>
+ </property>
+ <property name="shortcut">
+ <string>1</string>
+ </property>
+ </action>
+ <action name="actionThroughput">
+ <property name="text">
+ <string>Throughput</string>
+ </property>
+ <property name="toolTip">
+ <string>Switch to the Throughput graph</string>
+ </property>
+ <property name="shortcut">
+ <string>2</string>
+ </property>
+ </action>
+ <action name="actionStevens">
+ <property name="text">
+ <string>Time / Sequence (Stevens)</string>
+ </property>
+ <property name="toolTip">
+ <string>Switch to the Stevens-style Time / Sequence graph</string>
+ </property>
+ <property name="shortcut">
+ <string>3</string>
+ </property>
+ </action>
+ <action name="actionWindowScaling">
+ <property name="text">
+ <string>Window Scaling</string>
+ </property>
+ <property name="toolTip">
+ <string>Switch to the Window Scaling graph</string>
+ </property>
+ <property name="shortcut">
+ <string>5</string>
+ </property>
+ </action>
+ <action name="actionTcptrace">
+ <property name="text">
+ <string>Time / Sequence (tcptrace)</string>
+ </property>
+ <property name="toolTip">
+ <string>Switch to the tcptrace-style Time / Sequence graph</string>
+ </property>
+ <property name="shortcut">
+ <string>4</string>
+ </property>
+ </action>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>clicked(QAbstractButton*)</signal>
+ <receiver>SCTPAllAssocsDialog</receiver>
+ <slot>close()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>644</x>
+ <y>274</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>659</x>
+ <y>322</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/ui/qt/sctp_assoc_analyse_dialog.cpp b/ui/qt/sctp_assoc_analyse_dialog.cpp
new file mode 100644
index 0000000000..d27ec2ac48
--- /dev/null
+++ b/ui/qt/sctp_assoc_analyse_dialog.cpp
@@ -0,0 +1,292 @@
+#include "sctp_assoc_analyse_dialog.h"
+#include "ui_sctp_assoc_analyse_dialog.h"
+#include "sctp_graph_dialog.h"
+#include "sctp_graph_arwnd_dialog.h"
+#include "sctp_graph_byte_dialog.h"
+#include "sctp_chunk_statistics_dialog.h"
+
+
+SCTPAssocAnalyseDialog::SCTPAssocAnalyseDialog(QWidget *parent, sctp_assoc_info_t *assoc, capture_file *cf, SCTPAllAssocsDialog* caller) :
+ QDialog(parent),
+ ui(new Ui::SCTPAssocAnalyseDialog),
+ selected_assoc(assoc),
+ cap_file_(cf),
+ caller_(caller)
+{
+ ui->setupUi(this);
+ ui->SCTPAssocAnalyseTab->setCurrentWidget(ui->Statistics);
+ if (!selected_assoc) {
+ if (sctp_stat_get_info()->is_registered == FALSE) {
+ register_tap_listener_sctp_stat();
+ }
+ /* (redissect all packets) */
+ cf_retap_packets(cap_file_);
+ findAssocForPacket();
+ }
+ this->setWindowTitle(QString("SCTP Analyse Association: %1 Port1 %2 Port2 %3").arg(cf_get_display_name(cap_file_)).arg(selected_assoc->port1).arg(selected_assoc->port2));
+ fillTabs();
+}
+
+SCTPAssocAnalyseDialog::~SCTPAssocAnalyseDialog()
+{
+ delete ui;
+}
+
+void SCTPAssocAnalyseDialog::findAssocForPacket()
+{
+ frame_data *fdata;
+ GList *list, *framelist;
+ sctp_assoc_info_t *assoc;
+ bool frame_found = false;
+ printf("findAssocForPacket\n");
+ fdata = cap_file_->current_frame;
+ list = g_list_first(sctp_stat_get_info()->assoc_info_list);
+
+ while (list) {
+ assoc = (sctp_assoc_info_t*)(list->data);
+
+ framelist = g_list_first(assoc->frame_numbers);
+ while (framelist) {
+ guint32 *fn;
+ fn = (guint32 *)framelist->data;
+ if (*fn == fdata->num) {
+ frame_found = TRUE;
+ break;
+ }
+ framelist = g_list_next(framelist);
+ }
+ if (frame_found) {
+ selected_assoc = assoc;
+ printf("assoc_id =%d\n", selected_assoc->assoc_id);
+ return;
+ } else {
+ list = g_list_next(list);
+ }
+ }
+
+ if (!frame_found) {
+ QMessageBox msgBox;
+ msgBox.setText("No Association found for this packet.");
+ msgBox.exec();
+ }
+}
+
+void SCTPAssocAnalyseDialog::fillTabs()
+{
+ /* Statistics Tab */
+
+ ui->checksumLabel->setText(selected_assoc->checksum_type);
+ ui->data12Label->setText(QString("%1").arg(selected_assoc->n_data_chunks_ep1));
+ ui->bytes12Label->setText(QString("%1").arg(selected_assoc->n_data_bytes_ep1));
+ ui->data21Label->setText(QString("%1").arg(selected_assoc->n_data_chunks_ep2));
+ ui->bytes21Label->setText(QString("%1").arg(selected_assoc->n_data_bytes_ep2));
+
+ /* Tab Endpoint 1 */
+
+ if (selected_assoc->init == TRUE)
+ ui->labelEP1->setText(QString("Complete list of IP-Addresses as provided in the INIT-Chunk"));
+ else if ((selected_assoc->initack == TRUE) && (selected_assoc->initack_dir == 1))
+ ui->labelEP1->setText(QString("Complete list of IP-Addresses as provided in the INITACK-Chunk"));
+ else
+ ui->labelEP1->setText(QString("List of used IP-Addresses"));
+
+ if (selected_assoc->addr1 != NULL) {
+ GList *list;
+
+ list = g_list_first(selected_assoc->addr1);
+ while (list) {
+ address *store;
+
+ store = (address *)(list->data);
+ if (store->type != AT_NONE) {
+ if (store->type == AT_IPv4) {
+ ui->listWidgetEP1->addItem(QString("%1").arg(ip_to_str((const guint8 *)(store->data))));
+ } else if (store->type == AT_IPv6) {
+ ui->listWidgetEP1->addItem(QString("%1").arg(ip6_to_str((const struct e_in6_addr *)(store->data))));
+ }
+ }
+ list = g_list_next(list);
+ }
+ } else {
+ return;
+ }
+
+ ui->label_221->setText(QString("%1").arg(selected_assoc->port1));
+ ui->label_222->setText(QString("0x%1").arg(selected_assoc->verification_tag1, 0, 16));
+
+ if ((selected_assoc->init == TRUE) ||
+ ((selected_assoc->initack == TRUE) && (selected_assoc->initack_dir == 1))) {
+ ui->label_213->setText(QString("Requested Number of Inbound Streams:"));
+ ui->label_223->setText(QString("%1").arg(selected_assoc->instream1));
+ ui->label_214->setText(QString("Minimum Number of Inbound Streams:"));
+ ui->label_224->setText(QString("%1").arg(((selected_assoc->instream1 > selected_assoc->outstream2) ?
+ selected_assoc->outstream2 : selected_assoc->instream1)));
+ ui->label_215->setText(QString("Provided Number of Outbound Streams:"));
+ ui->label_225->setText(QString("%1").arg(selected_assoc->outstream1));
+ ui->label_216->setText(QString("Minimum Number of Outbound Streams:"));
+ ui->label_226->setText(QString("%1").arg(((selected_assoc->outstream1 > selected_assoc->instream2) ?
+ selected_assoc->instream2 : selected_assoc->outstream1)));
+ } else {
+ ui->label_213->setText(QString("Used Number of Inbound Streams:"));
+ ui->label_223->setText(QString("%1").arg(selected_assoc->instream1));
+ ui->label_214->setText(QString("Used Number of Outbound Streams:"));
+ ui->label_224->setText(QString("%1").arg(selected_assoc->outstream1));
+ ui->label_215->setText(QString(""));
+ ui->label_225->setText(QString(""));
+ ui->label_216->setText(QString(""));
+ ui->label_226->setText(QString(""));
+ }
+
+ /* Tab Endpoint 2 */
+
+ if ((selected_assoc->initack == TRUE) && (selected_assoc->initack_dir == 2))
+ ui->labelEP2->setText(QString("Complete list of IP-Addresses as provided in the INITACK-Chunk"));
+ else
+ ui->labelEP2->setText(QString("List of used IP-Addresses"));
+
+ if (selected_assoc->addr2 != NULL) {
+ GList *list;
+
+ list = g_list_first(selected_assoc->addr2);
+ while (list) {
+ address *store;
+
+ store = (address *)(list->data);
+ if (store->type != AT_NONE) {
+ if (store->type == AT_IPv4) {
+ ui->listWidgetEP2->addItem(QString("%1").arg(ip_to_str((const guint8 *)(store->data))));
+ } else if (store->type == AT_IPv6) {
+ ui->listWidgetEP2->addItem(QString("%1").arg(ip6_to_str((const struct e_in6_addr *)(store->data))));
+ }
+ }
+ list = g_list_next(list);
+ }
+ } else {
+ return;
+ }
+
+ ui->label_321->setText(QString("%1").arg(selected_assoc->port2));
+ ui->label_322->setText(QString("0x%1").arg(selected_assoc->verification_tag2, 0, 16));
+
+ if (selected_assoc->initack == TRUE) {
+ ui->label_313->setText(QString("Requested Number of Inbound Streams:"));
+ ui->label_323->setText(QString("%1").arg(selected_assoc->instream2));
+ ui->label_314->setText(QString("Minimum Number of Inbound Streams:"));
+ ui->label_324->setText(QString("%1").arg(((selected_assoc->instream2 > selected_assoc->outstream1) ?
+ selected_assoc->outstream1 : selected_assoc->instream2)));
+ ui->label_315->setText(QString("Provided Number of Outbound Streams:"));
+ ui->label_325->setText(QString("%1").arg(selected_assoc->outstream2));
+ ui->label_316->setText(QString("Minimum Number of Outbound Streams:"));
+ ui->label_326->setText(QString("%1").arg(((selected_assoc->outstream2 > selected_assoc->instream1) ?
+ selected_assoc->instream1 : selected_assoc->outstream2)));
+ } else {
+ ui->label_313->setText(QString("Used Number of Inbound Streams:"));
+ ui->label_323->setText(QString("%1").arg(selected_assoc->instream2));
+ ui->label_314->setText(QString("Used Number of Outbound Streams:"));
+ ui->label_324->setText(QString("%1").arg(selected_assoc->outstream2));
+ ui->label_315->setText(QString(""));
+ ui->label_325->setText(QString(""));
+ ui->label_316->setText(QString(""));
+ ui->label_326->setText(QString(""));
+ }
+}
+
+void SCTPAssocAnalyseDialog::openGraphDialog(int direction)
+{
+ SCTPGraphDialog *sctp_dialog = new SCTPGraphDialog(this, selected_assoc, cap_file_, direction);
+
+ if (sctp_dialog->isMinimized() == true) {
+ sctp_dialog->showNormal();
+ } else {
+ sctp_dialog->show();
+ }
+
+ sctp_dialog->raise();
+ sctp_dialog->activateWindow();
+}
+
+void SCTPAssocAnalyseDialog::on_GraphTSN_2_clicked()
+{
+ openGraphDialog(2);
+
+
+}
+
+void SCTPAssocAnalyseDialog::on_GraphTSN_1_clicked()
+{
+ openGraphDialog(1);
+}
+
+void SCTPAssocAnalyseDialog::on_chunkStatisticsButton_clicked()
+{
+ if (caller_ && !selected_assoc) {
+ selected_assoc = caller_->findSelectedAssoc();
+ } else if (!caller_ && !selected_assoc) {
+ findAssocForPacket();
+ }
+ SCTPChunkStatisticsDialog *sctp_dialog = new SCTPChunkStatisticsDialog(this, selected_assoc, cap_file_);
+
+ if (sctp_dialog->isMinimized() == true) {
+ sctp_dialog->showNormal();
+ } else {
+ sctp_dialog->show();
+ }
+
+ sctp_dialog->raise();
+ sctp_dialog->activateWindow();
+}
+
+void SCTPAssocAnalyseDialog::on_setFilterButton_clicked()
+{
+ QString newFilter = QString("sctp.assoc_index==%1").arg(selected_assoc->assoc_id);
+ selected_assoc = NULL;
+ emit filterPackets(newFilter, false);
+}
+
+void SCTPAssocAnalyseDialog::openGraphByteDialog(int direction)
+{
+ SCTPGraphByteDialog *sctp_dialog = new SCTPGraphByteDialog(this, selected_assoc, cap_file_, direction);
+
+ if (sctp_dialog->isMinimized() == true) {
+ sctp_dialog->showNormal();
+ } else {
+ sctp_dialog->show();
+ }
+
+ sctp_dialog->raise();
+ sctp_dialog->activateWindow();
+}
+
+void SCTPAssocAnalyseDialog::on_GraphBytes_1_clicked()
+{
+ openGraphByteDialog(1);
+}
+
+void SCTPAssocAnalyseDialog::on_GraphBytes_2_clicked()
+{
+ openGraphByteDialog(2);
+}
+
+void SCTPAssocAnalyseDialog::openGraphArwndDialog(int direction)
+{
+ SCTPGraphArwndDialog *sctp_dialog = new SCTPGraphArwndDialog(this, selected_assoc, cap_file_, direction);
+
+ if (sctp_dialog->isMinimized() == true) {
+ sctp_dialog->showNormal();
+ } else {
+ sctp_dialog->show();
+ }
+
+ sctp_dialog->raise();
+ sctp_dialog->activateWindow();
+}
+
+void SCTPAssocAnalyseDialog::on_GraphArwnd_1_clicked()
+{
+ openGraphArwndDialog(1);
+}
+
+void SCTPAssocAnalyseDialog::on_GraphArwnd_2_clicked()
+{
+ openGraphArwndDialog(2);
+}
diff --git a/ui/qt/sctp_assoc_analyse_dialog.h b/ui/qt/sctp_assoc_analyse_dialog.h
new file mode 100644
index 0000000000..31cd273e25
--- /dev/null
+++ b/ui/qt/sctp_assoc_analyse_dialog.h
@@ -0,0 +1,66 @@
+#ifndef SCTP_ASSOC_ANALYSE_DIALOG_H
+#define SCTP_ASSOC_ANALYSE_DIALOG_H
+
+#include "config.h"
+
+#include <glib.h>
+
+#include <file.h>
+
+#include <epan/dissectors/packet-sctp.h>
+
+#include "ui/tap-sctp-analysis.h"
+#include "sctp_all_assocs_dialog.h"
+
+#include <QDialog>
+#include <QTabWidget>
+#include <QObject>
+#include <QGridLayout>
+#include <QMessageBox>
+
+
+namespace Ui {
+class SCTPAssocAnalyseDialog;
+}
+
+class SCTPAssocAnalyseDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit SCTPAssocAnalyseDialog(QWidget *parent = 0, sctp_assoc_info_t *assoc = NULL, capture_file *cf = NULL, SCTPAllAssocsDialog *caller = NULL);
+ ~SCTPAssocAnalyseDialog();
+
+ void fillTabs();
+
+public slots:
+ void setCaptureFile(capture_file *cf) { cap_file_ = cf; }
+
+private slots:
+ void on_GraphTSN_2_clicked();
+ void on_GraphTSN_1_clicked();
+ void on_chunkStatisticsButton_clicked();
+ void on_setFilterButton_clicked();
+
+ void on_GraphBytes_1_clicked();
+ void on_GraphBytes_2_clicked();
+
+ void on_GraphArwnd_1_clicked();
+ void on_GraphArwnd_2_clicked();
+
+private:
+ Ui::SCTPAssocAnalyseDialog *ui;
+ sctp_assoc_info_t *selected_assoc;
+ capture_file *cap_file_;
+ SCTPAllAssocsDialog *caller_;
+ void findAssocForPacket();
+ void openGraphDialog(int direction);
+ void openGraphByteDialog(int direction);
+ void openGraphArwndDialog(int direction);
+
+
+signals:
+ void filterPackets(QString& new_filter, bool force);
+};
+
+#endif // SCTP_ASSOC_ANALYSE_DIALOG_H
diff --git a/ui/qt/sctp_assoc_analyse_dialog.ui b/ui/qt/sctp_assoc_analyse_dialog.ui
new file mode 100644
index 0000000000..b74af737d7
--- /dev/null
+++ b/ui/qt/sctp_assoc_analyse_dialog.ui
@@ -0,0 +1,607 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>SCTPAssocAnalyseDialog</class>
+ <widget class="QDialog" name="SCTPAssocAnalyseDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>537</width>
+ <height>385</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>Wireshark - Analyse Association</string>
+ </property>
+ <property name="windowIcon">
+ <iconset resource="../../image/toolbar.qrc">
+ <normaloff>:/menu/help/wsicon16.png</normaloff>:/menu/help/wsicon16.png</iconset>
+ </property>
+ <property name="locale">
+ <locale language="English" country="UnitedStates"/>
+ </property>
+ <widget class="QTabWidget" name="SCTPAssocAnalyseTab">
+ <property name="geometry">
+ <rect>
+ <x>5</x>
+ <y>10</y>
+ <width>529</width>
+ <height>371</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>TabWidget</string>
+ </property>
+ <property name="currentIndex">
+ <number>2</number>
+ </property>
+ <widget class="QWidget" name="Statistics">
+ <property name="focusPolicy">
+ <enum>Qt::NoFocus</enum>
+ </property>
+ <attribute name="title">
+ <string>Statistics</string>
+ </attribute>
+ <widget class="QPushButton" name="chunkStatisticsButton">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>310</y>
+ <width>131</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::NoFocus</enum>
+ </property>
+ <property name="text">
+ <string>Chunk Statistics</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="setFilterButton">
+ <property name="geometry">
+ <rect>
+ <x>130</x>
+ <y>310</y>
+ <width>141</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::NoFocus</enum>
+ </property>
+ <property name="text">
+ <string>Filter Association</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="pushButton">
+ <property name="geometry">
+ <rect>
+ <x>390</x>
+ <y>310</y>
+ <width>114</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::NoFocus</enum>
+ </property>
+ <property name="text">
+ <string>SchlieĂŸen</string>
+ </property>
+ </widget>
+ <widget class="QWidget" name="gridLayoutWidget_3">
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>40</y>
+ <width>481</width>
+ <height>201</height>
+ </rect>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_3">
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_17">
+ <property name="text">
+ <string>Number of Data Chunks from EP2 to EP1: </string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_15">
+ <property name="text">
+ <string>Checksum Type:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_16">
+ <property name="text">
+ <string>Number of Data Chunks from EP1 to EP2: </string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_13">
+ <property name="text">
+ <string>Number of Data Bytes from EP1 to EP2:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="label_18">
+ <property name="text">
+ <string>Number of Data Bytes from EP2 to EP1: </string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="data12Label">
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="checksumLabel">
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLabel" name="bytes12Label">
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QLabel" name="data21Label">
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QLabel" name="bytes21Label">
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ <widget class="QWidget" name="Endpoint_1">
+ <attribute name="title">
+ <string>Endpoint 1</string>
+ </attribute>
+ <widget class="QPushButton" name="GraphTSN_1">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>310</y>
+ <width>114</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::NoFocus</enum>
+ </property>
+ <property name="text">
+ <string>Graph TSN</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="GraphBytes_1">
+ <property name="geometry">
+ <rect>
+ <x>110</x>
+ <y>310</y>
+ <width>114</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::NoFocus</enum>
+ </property>
+ <property name="text">
+ <string>Graph Bytes</string>
+ </property>
+ </widget>
+ <widget class="QLabel" name="labelEP1">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>10</y>
+ <width>441</width>
+ <height>16</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Complete list of IP Addresses as provided in the INIT Chunk</string>
+ </property>
+ </widget>
+ <widget class="QWidget" name="gridLayoutWidget">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>170</y>
+ <width>520</width>
+ <height>138</height>
+ </rect>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_213">
+ <property name="text">
+ <string>Requested Number of Inbound Streams:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_211">
+ <property name="text">
+ <string>Port:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="label_222">
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_212">
+ <property name="text">
+ <string>Sent Verification Tag:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QLabel" name="label_224">
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_214">
+ <property name="text">
+ <string>Minimum Number of Inbound Streams:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="label_221">
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="label_215">
+ <property name="text">
+ <string>Minimum Number of Outbound Streams:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLabel" name="label_223">
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QLabel" name="label_225">
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="label_216">
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1">
+ <widget class="QLabel" name="label_226">
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QPushButton" name="pushButton_2">
+ <property name="geometry">
+ <rect>
+ <x>390</x>
+ <y>310</y>
+ <width>114</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::NoFocus</enum>
+ </property>
+ <property name="text">
+ <string>SchlieĂŸen</string>
+ </property>
+ </widget>
+ <widget class="QListWidget" name="listWidgetEP1">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>30</y>
+ <width>501</width>
+ <height>131</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="GraphArwnd_1">
+ <property name="geometry">
+ <rect>
+ <x>220</x>
+ <y>310</y>
+ <width>114</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Graph Arwnd</string>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QWidget" name="Endpoint_2">
+ <attribute name="title">
+ <string>Endpoint 2</string>
+ </attribute>
+ <widget class="QPushButton" name="GraphTSN_2">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>310</y>
+ <width>114</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::NoFocus</enum>
+ </property>
+ <property name="text">
+ <string>Graph TSN</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="GraphBytes_2">
+ <property name="geometry">
+ <rect>
+ <x>110</x>
+ <y>310</y>
+ <width>114</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::NoFocus</enum>
+ </property>
+ <property name="text">
+ <string>Graph Bytes</string>
+ </property>
+ </widget>
+ <widget class="QWidget" name="gridLayoutWidget_2">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>170</y>
+ <width>511</width>
+ <height>141</height>
+ </rect>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_313">
+ <property name="text">
+ <string>Requested Number of Inbound Streams:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QLabel" name="label_324">
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="label_321">
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_312">
+ <property name="text">
+ <string>Sent Verification Tag:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="label_316">
+ <property name="text">
+ <string>Minimum Number of Outbound Streams:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_311">
+ <property name="text">
+ <string>Port:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_314">
+ <property name="text">
+ <string>Minimum Number of Inbound Streams:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="label_322">
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLabel" name="label_323">
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1">
+ <widget class="QLabel" name="label_326">
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="label_315">
+ <property name="text">
+ <string>Provided Number of Outbound Streams:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QLabel" name="label_325">
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QLabel" name="labelEP2">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>10</y>
+ <width>441</width>
+ <height>16</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Complete list of IP Addresses as provided in the INIT-ACK Chunk</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="pushButton_3">
+ <property name="geometry">
+ <rect>
+ <x>390</x>
+ <y>310</y>
+ <width>114</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::NoFocus</enum>
+ </property>
+ <property name="text">
+ <string>SchlieĂŸen</string>
+ </property>
+ </widget>
+ <widget class="QListWidget" name="listWidgetEP2">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>30</y>
+ <width>501</width>
+ <height>131</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="GraphArwnd_2">
+ <property name="geometry">
+ <rect>
+ <x>220</x>
+ <y>310</y>
+ <width>121</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Graph a_rwnd</string>
+ </property>
+ </widget>
+ </widget>
+ </widget>
+ </widget>
+ <resources>
+ <include location="../../image/toolbar.qrc"/>
+ </resources>
+ <connections>
+ <connection>
+ <sender>pushButton_2</sender>
+ <signal>clicked()</signal>
+ <receiver>SCTPAssocAnalyseDialog</receiver>
+ <slot>close()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>471</x>
+ <y>365</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>475</x>
+ <y>384</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>pushButton</sender>
+ <signal>clicked()</signal>
+ <receiver>SCTPAssocAnalyseDialog</receiver>
+ <slot>close()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>494</x>
+ <y>361</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>523</x>
+ <y>433</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>pushButton_3</sender>
+ <signal>clicked()</signal>
+ <receiver>SCTPAssocAnalyseDialog</receiver>
+ <slot>close()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>502</x>
+ <y>362</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>520</x>
+ <y>459</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/ui/qt/sctp_chunk_statistics_dialog.cpp b/ui/qt/sctp_chunk_statistics_dialog.cpp
new file mode 100644
index 0000000000..b4a70f6d75
--- /dev/null
+++ b/ui/qt/sctp_chunk_statistics_dialog.cpp
@@ -0,0 +1,288 @@
+#include "sctp_chunk_statistics_dialog.h"
+#include "ui_sctp_chunk_statistics_dialog.h"
+#include "uat_dialog.h"
+
+#include <string>
+
+
+SCTPChunkStatisticsDialog::SCTPChunkStatisticsDialog(QWidget *parent, sctp_assoc_info_t *assoc, capture_file *cf) :
+ QDialog(parent),
+ ui(new Ui::SCTPChunkStatisticsDialog),
+ selected_assoc(assoc),
+ cap_file_(cf)
+{
+ ui->setupUi(this);
+ printf("selected_assoc id=%d\n", selected_assoc->assoc_id);
+ ui->tableWidget->verticalHeader()->setSectionsClickable(true);
+ ui->tableWidget->verticalHeader()->setSectionsMovable(true);
+
+ ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
+ ui->tableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
+
+#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
+ ui->tableWidget->horizontalHeader()->setResizeMode(QHeaderView::ResizeToContents);
+#else
+ ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
+#endif
+
+ this->setWindowTitle(QString("SCTP Chunk Statistics: %1 Port1 %2 Port2 %3").arg(cf_get_display_name(cap_file_)).arg(selected_assoc->port1).arg(selected_assoc->port2));
+ // connect(ui->tableWidget->verticalHeader(), SIGNAL(sectionClicked(int)), this, SLOT(on_sectionClicked(int)));
+ connect(ui->tableWidget->verticalHeader(), SIGNAL(sectionMoved(int,int,int)), this, SLOT(on_sectionMoved(int, int, int)));
+
+ ctx_menu_.addAction(ui->actionHideChunkType);
+ ctx_menu_.addAction(ui->actionChunkTypePreferences);
+ ctx_menu_.addAction(ui->actionShowAllChunkTypes);
+ initializeChunkMap();
+ fillTable();
+}
+
+SCTPChunkStatisticsDialog::~SCTPChunkStatisticsDialog()
+{
+ delete ui;
+}
+
+void SCTPChunkStatisticsDialog::initializeChunkMap()
+{
+ struct chunkTypes temp;
+ gchar buf[16];
+
+ for (int i = 0; i < 256; i++) {
+ temp.id = i;
+ temp.row = i;
+ sprintf(buf, "%d", i);
+ strcpy(temp.name, val_to_str_const(i, chunk_type_values, "NA"));
+ if (strcmp(temp.name, "NA") == 0) {
+ temp.hide = 1;
+ strcpy(temp.name, buf);
+ } else {
+ temp.hide = 0;
+ }
+ chunks.insert(i, temp);
+ }
+}
+
+void SCTPChunkStatisticsDialog::fillTable(bool all)
+{
+ FILE* fp;
+
+ pref_t *pref = prefs_find_preference(prefs_find_module("sctp"),"statistics_chunk_types");
+ uat_t *uat = pref->varp.uat;
+ gchar* fname = uat_get_actual_filename(uat,TRUE);
+ bool init = false;
+
+ if (!fname ) {
+ printf("no filename\n");
+ init = true;
+ } else {
+ fp = ws_fopen(fname,"r");
+
+ if (!fp && errno == ENOENT) {
+ init = true;
+ }
+ }
+ g_free (fname);
+
+ if (init || all) {
+ int j = 0;
+ printf("init set\n");
+ for (int i = 0; i < chunks.size(); i++) {
+ if (!chunks.value(i).hide) {
+ ui->tableWidget->setRowCount(ui->tableWidget->rowCount()+1);
+ ui->tableWidget->setVerticalHeaderItem(j, new QTableWidgetItem(QString("%1").arg(chunks.value(i).name)));
+ ui->tableWidget->setItem(j,0, new QTableWidgetItem(QString("%1").arg(selected_assoc->chunk_count[chunks.value(i).id])));
+ ui->tableWidget->setItem(j,1, new QTableWidgetItem(QString("%1").arg(selected_assoc->ep1_chunk_count[chunks.value(i).id])));
+ ui->tableWidget->setItem(j,2, new QTableWidgetItem(QString("%1").arg(selected_assoc->ep2_chunk_count[chunks.value(i).id])));
+ j++;
+ }
+ }
+ for (int i = 0; i < chunks.size(); i++) {
+ if (chunks.value(i).hide) {
+ ui->tableWidget->setRowCount(ui->tableWidget->rowCount()+1);
+ /* ui->tableWidget->setVerticalHeaderItem(j, new QTableWidgetItem(QString("%1").arg(chunks.value(i).name)));
+ ui->tableWidget->setItem(j,0, new QTableWidgetItem(QString("%1").arg(selected_assoc->chunk_count[chunks.value(i).id])));
+ ui->tableWidget->setItem(j,1, new QTableWidgetItem(QString("%1").arg(selected_assoc->ep1_chunk_count[chunks.value(i).id])));
+ ui->tableWidget->setItem(j,2, new QTableWidgetItem(QString("%1").arg(selected_assoc->ep2_chunk_count[chunks.value(i).id])));*/
+ ui->tableWidget->hideRow(j);
+ j++;
+ }
+ }
+ } else {
+ char* line = NULL;
+ size_t cap = 0;
+ ssize_t len;
+ char *token, id[5];
+ int i = 0, j = 0;
+ struct chunkTypes temp;
+
+ getline(&line, &cap, fp);
+ while ((len = getline(&line, &cap, fp)) > 0 ) {
+ token = strtok(line, ",");
+ /* Get rid of the quotation marks */
+ QString ch = QString(token).mid(1, (int)strlen(token)-2);
+ strcpy(id, qPrintable(ch));
+ temp.id = atoi(id);
+ while(token != NULL) {
+ token = strtok(NULL, ",");
+ if (token) {
+ if ((strstr(token, "Hide"))) {
+ temp.hide = 1;
+ } else if ((strstr(token, "Show"))) {
+ temp.hide = 0;
+ } else {
+ QString ch = QString(token).mid(1, (int)strlen(token)-2);
+ strcpy(temp.name, qPrintable(ch));
+ }
+ }
+ }
+ if (!temp.hide) {
+ ui->tableWidget->setRowCount(ui->tableWidget->rowCount()+1);
+ ui->tableWidget->setVerticalHeaderItem(j, new QTableWidgetItem(QString("%1").arg(temp.name)));
+ ui->tableWidget->setItem(j,0, new QTableWidgetItem(QString("%1").arg(selected_assoc->chunk_count[temp.id])));
+ ui->tableWidget->setItem(j,1, new QTableWidgetItem(QString("%1").arg(selected_assoc->ep1_chunk_count[temp.id])));
+ ui->tableWidget->setItem(j,2, new QTableWidgetItem(QString("%1").arg(selected_assoc->ep2_chunk_count[temp.id])));
+ j++;
+ }
+ chunks.insert(i, temp);
+ i++;
+ }
+ j = ui->tableWidget->rowCount();
+ for (int i = 0; i < chunks.size(); i++) {
+ if (chunks.value(i).hide) {
+ ui->tableWidget->setRowCount(ui->tableWidget->rowCount()+1);
+ /* ui->tableWidget->setVerticalHeaderItem(j, new QTableWidgetItem(QString("%1").arg(chunks.value(i).name)));
+ ui->tableWidget->setItem(j,0, new QTableWidgetItem(QString("%1").arg(selected_assoc->chunk_count[chunks.value(i).id])));
+ ui->tableWidget->setItem(j,1, new QTableWidgetItem(QString("%1").arg(selected_assoc->ep1_chunk_count[chunks.value(i).id])));
+ ui->tableWidget->setItem(j,2, new QTableWidgetItem(QString("%1").arg(selected_assoc->ep2_chunk_count[chunks.value(i).id])));*/
+ ui->tableWidget->hideRow(j);
+ j++;
+ }
+ }
+ fclose(fp);
+ }
+}
+
+void SCTPChunkStatisticsDialog::contextMenuEvent( QContextMenuEvent * event)
+{
+ selected_point = event->pos();
+ QTableWidgetItem *item = ui->tableWidget->itemAt(selected_point.x(), selected_point.y()-60);
+ if (item) {
+ printf("clicked on row %d\n", item->row());
+ printf("Inhalt von %d: %s\n", item->row(), ui->tableWidget->verticalHeaderItem(item->row())->text().toUtf8().constData());
+ ctx_menu_.exec(event->globalPos());
+ }
+ else
+ printf("nichts da\n");
+
+}
+
+
+
+void SCTPChunkStatisticsDialog::on_pushButton_clicked()
+{
+ FILE* fp;
+
+ pref_t *pref = prefs_find_preference(prefs_find_module("sctp"),"statistics_chunk_types");
+
+ uat_t *uat = pref->varp.uat;
+
+ gchar* fname = uat_get_actual_filename(uat,TRUE);
+
+ if (!fname ) {
+ printf("no filename\n");
+ return;
+ }
+ fp = ws_fopen(fname,"w");
+
+ if (!fp && errno == ENOENT) {
+ gchar *pf_dir_path = NULL;
+ if (create_persconffile_dir(&pf_dir_path) != 0) {
+ printf("on_pushButton_clicked: error creating '%s'", pf_dir_path);
+ g_free (pf_dir_path);
+ return;
+ }
+ fp = ws_fopen(fname,"w");
+ }
+
+ if (!fp) {
+ printf("on_pushButton_clicked: error opening '%s': %s",fname,g_strerror(errno));
+ return;
+ }
+
+ g_free (fname);
+
+ fprintf(fp,"# This file is automatically generated, DO NOT MODIFY.\n");
+ char str[40];
+
+ for (int i = 0; i < chunks.size(); i++) {
+ sprintf(str, "\"%d\",\"%s\",\"%s\"\n", chunks.value(i).id, chunks.value(i).name, (chunks.value(i).hide==0?"Show":"Hide"));
+ fputs(str, fp);
+ void *rec = g_malloc0(uat->record_size);
+ uat_add_record(uat, rec, TRUE);
+ if (uat->free_cb) {
+ uat->free_cb(rec);
+ }
+ g_free(rec);
+ }
+
+ fclose(fp);
+}
+
+void SCTPChunkStatisticsDialog::on_sectionMoved(int logicalIndex, int oldVisualIndex, int newVisualIndex)
+{
+ printf("logicalIndex=%d, oldVisualIndex=%d, newVisualIndex=%d\n", logicalIndex, oldVisualIndex, newVisualIndex);
+}
+
+void SCTPChunkStatisticsDialog::on_actionHideChunkType_triggered()
+{
+ int row;
+
+ QTableWidgetItem *item = ui->tableWidget->itemAt(selected_point.x(), selected_point.y()-60);
+ if (item) {
+ row = item->row();
+ ui->tableWidget->hideRow(row);
+ QTableWidgetItem *item = ui->tableWidget->verticalHeaderItem(row);
+ QMap<int, struct chunkTypes>::iterator iter;
+ for (iter = chunks.begin(); iter != chunks.end(); ++iter) {
+ if (strcmp(iter.value().name, item->text().toUtf8().constData()) == 0) {
+ iter.value().hide = true;
+ break;
+ }
+ }
+ }
+
+}
+
+void SCTPChunkStatisticsDialog::on_actionChunkTypePreferences_triggered()
+{
+ const gchar* err = NULL;
+
+ pref_t *pref = prefs_find_preference(prefs_find_module("sctp"),"statistics_chunk_types");
+ uat_t *uat = pref->varp.uat;
+ uat_clear(uat);
+
+ uat_load(pref->varp.uat, &err);
+ if (err) {
+ printf("Error loading table '%s': %s",pref->varp.uat->name,err);
+ }
+
+ UatDialog *uatdialog = new UatDialog(this, pref->varp.uat);
+ uatdialog->exec();
+ ui->tableWidget->clear();
+ ui->tableWidget->setRowCount(0);
+ ui->tableWidget->setHorizontalHeaderItem(0, new QTableWidgetItem(QString("Association")));
+ ui->tableWidget->setHorizontalHeaderItem(1, new QTableWidgetItem(QString("Endpoint 1")));
+ ui->tableWidget->setHorizontalHeaderItem(2, new QTableWidgetItem(QString("Endpoint 2")));
+ fillTable();
+}
+
+void SCTPChunkStatisticsDialog::on_actionShowAllChunkTypes_triggered()
+{
+ ui->tableWidget->clear();
+ ui->tableWidget->setRowCount(0);
+ ui->tableWidget->setHorizontalHeaderItem(0, new QTableWidgetItem(QString("Association")));
+ ui->tableWidget->setHorizontalHeaderItem(1, new QTableWidgetItem(QString("Endpoint 1")));
+ ui->tableWidget->setHorizontalHeaderItem(2, new QTableWidgetItem(QString("Endpoint 2")));
+ printf ("on_actionShowAllChunkTypes_triggered: assoc=%d\n", selected_assoc->assoc_id);
+ initializeChunkMap();
+ fillTable(true);
+}
diff --git a/ui/qt/sctp_chunk_statistics_dialog.h b/ui/qt/sctp_chunk_statistics_dialog.h
new file mode 100644
index 0000000000..0392b8e8bc
--- /dev/null
+++ b/ui/qt/sctp_chunk_statistics_dialog.h
@@ -0,0 +1,75 @@
+#ifndef SCTP_CHUNK_STATISTICS_DIALOG_H
+#define SCTP_CHUNK_STATISTICS_DIALOG_H
+
+#include "config.h"
+#include <glib.h>
+
+#include <file.h>
+#include <wsutil/file_util.h>
+#include <epan/dissectors/packet-sctp.h>
+#include "epan/packet.h"
+#include "epan/value_string.h"
+#include <epan/prefs.h>
+#include <epan/uat-int.h>
+#include <epan/prefs-int.h>
+#include <wsutil/filesystem.h>
+#include "wireshark_application.h"
+
+#include "ui/tap-sctp-analysis.h"
+
+#include <QTableWidgetItem>
+#include <QDialog>
+#include <QtGui>
+#include <QMenu>
+#include <QContextMenuEvent>
+
+namespace Ui {
+class SCTPChunkStatisticsDialog;
+}
+
+class SCTPChunkStatisticsDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit SCTPChunkStatisticsDialog(QWidget *parent = 0, sctp_assoc_info_t *assoc = NULL, capture_file *cf = NULL);
+ ~SCTPChunkStatisticsDialog();
+
+public slots:
+ void setCaptureFile(capture_file *cf) { cap_file_ = cf; }
+
+private slots:
+ // void on_sectionClicked(int row);
+ void on_sectionMoved(int logicalIndex, int oldVisualIndex, int newVisualIndex);
+ void on_pushButton_clicked();
+ void on_actionHideChunkType_triggered();
+ void on_actionChunkTypePreferences_triggered();
+ void contextMenuEvent(QContextMenuEvent * event);
+
+ void on_actionShowAllChunkTypes_triggered();
+
+signals:
+ // void sectionClicked(int);
+ void sectionMoved(int, int, int);
+
+private:
+ Ui::SCTPChunkStatisticsDialog *ui;
+ sctp_assoc_info_t *selected_assoc;
+ capture_file *cap_file_;
+ QMenu ctx_menu_;
+ QPoint selected_point;
+
+ struct chunkTypes {
+ int row;
+ int id;
+ int hide;
+ char name[30];
+ };
+
+ QMap<int, struct chunkTypes> chunks, tempChunks;
+
+ void initializeChunkMap();
+ void fillTable(bool all = false);
+};
+
+#endif // SCTP_CHUNK_STATISTICS_DIALOG_H
diff --git a/ui/qt/sctp_chunk_statistics_dialog.ui b/ui/qt/sctp_chunk_statistics_dialog.ui
new file mode 100644
index 0000000000..4165edc5ff
--- /dev/null
+++ b/ui/qt/sctp_chunk_statistics_dialog.ui
@@ -0,0 +1,160 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>SCTPChunkStatisticsDialog</class>
+ <widget class="QDialog" name="SCTPChunkStatisticsDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>519</width>
+ <height>504</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>Dialog</string>
+ </property>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="geometry">
+ <rect>
+ <x>310</x>
+ <y>470</y>
+ <width>191</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Close</set>
+ </property>
+ </widget>
+ <widget class="QTableWidget" name="tableWidget">
+ <property name="geometry">
+ <rect>
+ <x>30</x>
+ <y>30</y>
+ <width>471</width>
+ <height>431</height>
+ </rect>
+ </property>
+ <property name="editTriggers">
+ <set>QAbstractItemView::NoEditTriggers</set>
+ </property>
+ <property name="alternatingRowColors">
+ <bool>true</bool>
+ </property>
+ <property name="selectionMode">
+ <enum>QAbstractItemView::SingleSelection</enum>
+ </property>
+ <property name="selectionBehavior">
+ <enum>QAbstractItemView::SelectRows</enum>
+ </property>
+ <property name="rowCount">
+ <number>0</number>
+ </property>
+ <attribute name="horizontalHeaderCascadingSectionResizes">
+ <bool>false</bool>
+ </attribute>
+ <attribute name="horizontalHeaderStretchLastSection">
+ <bool>true</bool>
+ </attribute>
+ <attribute name="verticalHeaderCascadingSectionResizes">
+ <bool>false</bool>
+ </attribute>
+ <column>
+ <property name="text">
+ <string>Association</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Endpoint 1</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Endpoint 2</string>
+ </property>
+ </column>
+ </widget>
+ <widget class="QPushButton" name="pushButton">
+ <property name="geometry">
+ <rect>
+ <x>130</x>
+ <y>470</y>
+ <width>181</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Save Chunk Type Order</string>
+ </property>
+ </widget>
+ <action name="actionHideChunkType">
+ <property name="text">
+ <string>Hide Chunk Type</string>
+ </property>
+ <property name="toolTip">
+ <string>Remove the chunk type from the table</string>
+ </property>
+ </action>
+ <action name="actionChunkTypePreferences">
+ <property name="text">
+ <string>Chunk Type Preferences</string>
+ </property>
+ <property name="toolTip">
+ <string>Go to the chunk type preferences dialog to show or hide other chunk types</string>
+ </property>
+ </action>
+ <action name="actionShowAllChunkTypes">
+ <property name="text">
+ <string>Show All Registered Chunk Types</string>
+ </property>
+ <property name="toolTip">
+ <string>Show all chunk types with defined names</string>
+ </property>
+ </action>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>clicked(QAbstractButton*)</signal>
+ <receiver>SCTPChunkStatisticsDialog</receiver>
+ <slot>close()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>456</x>
+ <y>483</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>445</x>
+ <y>563</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>clicked(QAbstractButton*)</signal>
+ <receiver>SCTPChunkStatisticsDialog</receiver>
+ <slot>close()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>357</x>
+ <y>486</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>355</x>
+ <y>542</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/ui/qt/sctp_graph_arwnd_dialog.cpp b/ui/qt/sctp_graph_arwnd_dialog.cpp
new file mode 100644
index 0000000000..238b58e2d6
--- /dev/null
+++ b/ui/qt/sctp_graph_arwnd_dialog.cpp
@@ -0,0 +1,141 @@
+#include "sctp_graph_arwnd_dialog.h"
+#include "ui_sctp_graph_arwnd_dialog.h"
+
+#include "sctp_graph_dialog.h"
+
+SCTPGraphArwndDialog::SCTPGraphArwndDialog(QWidget *parent, sctp_assoc_info_t *assoc, capture_file *cf, int dir) :
+ QDialog(parent),
+ ui(new Ui::SCTPGraphArwndDialog),
+ selected_assoc(assoc),
+ cap_file_(cf),
+ direction(dir)
+{
+ ui->setupUi(this);
+ this->setWindowTitle(QString("SCTP Data and Adv. Rec. Window over Time: %1 Port1 %2 Port2 %3").arg(cf_get_display_name(cap_file_)).arg(selected_assoc->port1).arg(selected_assoc->port2));
+ if ((direction == 1 && selected_assoc->n_array_tsn1 == 0) || (direction == 2 && selected_assoc->n_array_tsn2 == 0)) {
+ QMessageBox msgBox;
+ msgBox.setText("No Data Chunks sent");
+ msgBox.exec();
+ return;
+ } else {
+ drawGraph();
+ }
+}
+
+SCTPGraphArwndDialog::~SCTPGraphArwndDialog()
+{
+ delete ui;
+}
+
+void SCTPGraphArwndDialog::drawArwndGraph()
+{
+ GList *listSACK = NULL, *tlist;
+ struct sack_chunk_header *sack_header;
+ struct nr_sack_chunk_header *nr_sack_header;
+ tsn_t *tsn;
+ guint8 type;
+ guint32 arwnd=0;
+
+ if (direction == 1) {
+ listSACK = g_list_last(selected_assoc->sack1);
+ startArwnd = selected_assoc->arwnd1;
+ } else {
+ listSACK = g_list_last(selected_assoc->sack2);
+ startArwnd = selected_assoc->arwnd2;
+ }
+ while (listSACK) {
+ tsn = (tsn_t*) (listSACK->data);
+ tlist = g_list_first(tsn->tsns);
+ while (tlist) {
+ type = ((struct chunk_header *)tlist->data)->type;
+ if (type == SCTP_SACK_CHUNK_ID) {
+ sack_header =(struct sack_chunk_header *)tlist->data;
+ arwnd = g_ntohl(sack_header->a_rwnd);
+ } else if (type == SCTP_NR_SACK_CHUNK_ID) {
+ nr_sack_header =(struct nr_sack_chunk_header *)tlist->data;
+ arwnd = g_ntohl(nr_sack_header->a_rwnd);
+ }
+ // printf("frame %d arwnd=%d\n", tsn->frame_number, arwnd);
+ ya.append(arwnd);
+ xa.append(tsn->secs + tsn->usecs/1000000.0);
+ fa.append(tsn->frame_number);
+ tlist = g_list_next(tlist);
+ }
+ listSACK = g_list_previous(listSACK);
+ }
+
+ QCPScatterStyle myScatter;
+ myScatter.setShape(QCPScatterStyle::ssCircle);
+ myScatter.setSize(3);
+
+ // create graph and assign data to it:
+
+ // Add Arwnd graph
+ if (xa.size() > 0) {
+ QCPGraph *gr = ui->sctpPlot->addGraph(ui->sctpPlot->xAxis, ui->sctpPlot->yAxis);
+ gr->setName(QString("Arwnd"));
+ myScatter.setPen(QPen(Qt::red));
+ myScatter.setBrush(Qt::red);
+ ui->sctpPlot->graph(0)->setScatterStyle(myScatter);
+ ui->sctpPlot->graph(0)->setLineStyle(QCPGraph::lsNone);
+ ui->sctpPlot->graph(0)->setData(xa, ya);
+ }
+
+ ui->sctpPlot->xAxis->setLabel("time [secs]");
+ ui->sctpPlot->yAxis->setLabel("Advertised Receiver Window [Bytes]");
+
+ // set axes ranges, so we see all data:
+ QCPRange myXArwndRange(0, (selected_assoc->max_secs+1));
+ // QCPRange myXArwndRange(0, 1);
+ QCPRange myYArwndRange(0, startArwnd);
+ ui->sctpPlot->xAxis->setRange(myXArwndRange);
+ ui->sctpPlot->yAxis->setRange(myYArwndRange);
+}
+
+
+void SCTPGraphArwndDialog::drawGraph()
+{
+ ui->sctpPlot->clearGraphs();
+ drawArwndGraph();
+ ui->sctpPlot->setInteractions(QCP::iRangeZoom | QCP::iRangeDrag | QCP::iSelectPlottables);
+ ui->sctpPlot->axisRect(0)->setRangeZoomAxes(ui->sctpPlot->xAxis, ui->sctpPlot->yAxis);
+ ui->sctpPlot->axisRect(0)->setRangeZoom(Qt::Horizontal);
+ connect(ui->sctpPlot, SIGNAL(plottableClick(QCPAbstractPlottable*,QMouseEvent*)), this, SLOT(graphClicked(QCPAbstractPlottable*, QMouseEvent*)));
+ ui->sctpPlot->replot();
+}
+
+
+void SCTPGraphArwndDialog::on_pushButton_4_clicked()
+{
+ ui->sctpPlot->xAxis->setRange(selected_assoc->min_secs+selected_assoc->min_usecs/1000000.0, selected_assoc->max_secs+selected_assoc->max_usecs/1000000.0);
+ ui->sctpPlot->yAxis->setRange(0, startArwnd);
+ ui->sctpPlot->replot();
+}
+
+void SCTPGraphArwndDialog::graphClicked(QCPAbstractPlottable* plottable, QMouseEvent* event)
+{
+ if (plottable->name().contains("Arwnd", Qt::CaseInsensitive)) {
+ double times = ui->sctpPlot->xAxis->pixelToCoord(event->pos().x());
+ int i=0;
+ for (i = 0; i < xa.size(); i++) {
+ if (times <= xa.value(i)) {
+ frame_num = fa.at(i);
+ break;
+ }
+ }
+ if (cap_file_ && frame_num > 0) {
+ cf_goto_frame(cap_file_, frame_num);
+ }
+
+ ui->hintLabel->setText(QString("<small><i>Graph %1: arwnd=%2 Time=%3 secs </i></small>")
+ .arg(plottable->name())
+ .arg(ya.value(i))
+ .arg(xa.value(i)));
+ }
+}
+
+
+void SCTPGraphArwndDialog::on_saveButton_clicked()
+{
+ SCTPGraphDialog::save_graph(this, ui->sctpPlot);
+}
diff --git a/ui/qt/sctp_graph_arwnd_dialog.h b/ui/qt/sctp_graph_arwnd_dialog.h
new file mode 100644
index 0000000000..8be8c34b58
--- /dev/null
+++ b/ui/qt/sctp_graph_arwnd_dialog.h
@@ -0,0 +1,57 @@
+#ifndef SCTP_GRAPH_ARWND_DIALOG_H
+#define SCTP_GRAPH_ARWND_DIALOG_H
+
+#include "config.h"
+#include "qcustomplot.h"
+#include <glib.h>
+
+#include <file.h>
+#include <math.h>
+#include <epan/dissectors/packet-sctp.h>
+#include "epan/packet.h"
+
+#include "ui/tap-sctp-analysis.h"
+
+#include <QDialog>
+#include <QObject>
+#include <QMessageBox>
+
+namespace Ui {
+class SCTPGraphArwndDialog;
+}
+
+
+class SCTPGraphArwndDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit SCTPGraphArwndDialog(QWidget *parent = 0, sctp_assoc_info_t *assoc = NULL, capture_file *cf = NULL, int dir = 0);
+ ~SCTPGraphArwndDialog();
+
+public slots:
+ void setCaptureFile(capture_file *cf) { cap_file_ = cf; }
+
+private slots:
+ void on_pushButton_4_clicked();
+
+ void graphClicked(QCPAbstractPlottable* plottable, QMouseEvent* event);
+
+ void on_saveButton_clicked();
+
+private:
+ Ui::SCTPGraphArwndDialog *ui;
+ sctp_assoc_info_t *selected_assoc;
+ capture_file *cap_file_;
+ int frame_num;
+ int direction;
+ int startArwnd;
+ QVector<double> xa, ya;
+ QVector<guint32> fa;
+ // QVector<QString> typeStrings;
+
+ void drawGraph();
+ void drawArwndGraph();
+};
+
+#endif // SCTP_GRAPH_DIALOG_H
diff --git a/ui/qt/sctp_graph_arwnd_dialog.ui b/ui/qt/sctp_graph_arwnd_dialog.ui
new file mode 100644
index 0000000000..3ae71cbe84
--- /dev/null
+++ b/ui/qt/sctp_graph_arwnd_dialog.ui
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>SCTPGraphArwndDialog</class>
+ <widget class="QDialog" name="SCTPGraphArwndDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>800</width>
+ <height>546</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>SCTP Graph</string>
+ </property>
+ <widget class="QCustomPlot" name="sctpPlot" native="true">
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>30</y>
+ <width>761</width>
+ <height>451</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>1</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="pushButton_4">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>510</y>
+ <width>131</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::NoFocus</enum>
+ </property>
+ <property name="text">
+ <string>Reset to full size</string>
+ </property>
+ </widget>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="geometry">
+ <rect>
+ <x>680</x>
+ <y>510</y>
+ <width>120</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::NoFocus</enum>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Close</set>
+ </property>
+ </widget>
+ <widget class="QLabel" name="hintLabel">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>490</y>
+ <width>655</width>
+ <height>12</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="saveButton">
+ <property name="geometry">
+ <rect>
+ <x>140</x>
+ <y>510</y>
+ <width>114</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Save Graph</string>
+ </property>
+ </widget>
+ <action name="actionGoToPacket">
+ <property name="text">
+ <string>goToPacket</string>
+ </property>
+ <property name="toolTip">
+ <string>Go to Packet</string>
+ </property>
+ </action>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>QCustomPlot</class>
+ <extends>QWidget</extends>
+ <header>qcustomplot.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>clicked(QAbstractButton*)</signal>
+ <receiver>SCTPGraphArwndDialog</receiver>
+ <slot>close()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>706</x>
+ <y>530</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>703</x>
+ <y>574</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/ui/qt/sctp_graph_byte_dialog.cpp b/ui/qt/sctp_graph_byte_dialog.cpp
new file mode 100644
index 0000000000..0574150010
--- /dev/null
+++ b/ui/qt/sctp_graph_byte_dialog.cpp
@@ -0,0 +1,145 @@
+#include "sctp_graph_byte_dialog.h"
+#include "ui_sctp_graph_byte_dialog.h"
+
+#include "sctp_graph_dialog.h"
+
+SCTPGraphByteDialog::SCTPGraphByteDialog(QWidget *parent, sctp_assoc_info_t *assoc, capture_file *cf, int dir) :
+ QDialog(parent),
+ ui(new Ui::SCTPGraphByteDialog),
+ selected_assoc(assoc),
+ cap_file_(cf),
+ direction(dir)
+{
+ ui->setupUi(this);
+ this->setWindowTitle(QString("SCTP Data and Adv. Rec. Window over Time: %1 Port1 %2 Port2 %3").arg(cf_get_display_name(cap_file_)).arg(selected_assoc->port1).arg(selected_assoc->port2));
+ if ((direction == 1 && selected_assoc->n_array_tsn1 == 0) || (direction == 2 && selected_assoc->n_array_tsn2 == 0)) {
+ QMessageBox msgBox;
+ msgBox.setText("No Data Chunks sent");
+ msgBox.exec();
+ return;
+ } else {
+ drawGraph();
+ }
+}
+
+SCTPGraphByteDialog::~SCTPGraphByteDialog()
+{
+ delete ui;
+}
+
+
+void SCTPGraphByteDialog::drawBytesGraph()
+{
+ GList *listTSN = NULL,*tlist;
+ tsn_t *tsn;
+ guint8 type;
+ guint32 minBytes, maxBytes;
+ long sumBytes = 0;
+ // printf("drawBytesGraph\n");
+ if (direction == 1) {
+ minBytes = 0; //selected_assoc->min_tsn1;
+ maxBytes = selected_assoc->n_data_bytes_ep1;
+ listTSN = g_list_last(selected_assoc->tsn1);
+ } else {
+ minBytes = 0; //selected_assoc->min_tsn2;
+ maxBytes = selected_assoc->n_data_bytes_ep2;
+ listTSN = g_list_last(selected_assoc->tsn2);
+ }
+
+
+ while (listTSN) {
+ tsn = (tsn_t*) (listTSN->data);
+ tlist = g_list_first(tsn->tsns);
+ guint16 length;
+ while (tlist)
+ {
+ type = ((struct chunk_header *)tlist->data)->type;
+ if (type == SCTP_DATA_CHUNK_ID) {
+ length = g_ntohs(((struct data_chunk_header *)tlist->data)->length);
+ sumBytes += length;
+ yb.append(sumBytes);
+ xb.append(tsn->secs + tsn->usecs/1000000.0);
+ // printf("x=%f y=%ld\n", tsn->secs + tsn->usecs/1000000.0, sumBytes);
+ fb.append(tsn->frame_number);
+ }
+ tlist = g_list_next(tlist);
+ }
+ listTSN = g_list_previous(listTSN);
+ }
+
+
+ QCPScatterStyle myScatter;
+ myScatter.setShape(QCPScatterStyle::ssCircle);
+ myScatter.setSize(3);
+
+ // create graph and assign data to it:
+
+ // Add Bytes graph
+ if (xb.size() > 0) {
+ QCPGraph *gr = ui->sctpPlot->addGraph(ui->sctpPlot->xAxis, ui->sctpPlot->yAxis);
+ gr->setName(QString("Bytes"));
+ myScatter.setPen(QPen(Qt::red));
+ myScatter.setBrush(Qt::red);
+ ui->sctpPlot->graph(0)->setScatterStyle(myScatter);
+ ui->sctpPlot->graph(0)->setLineStyle(QCPGraph::lsNone);
+ ui->sctpPlot->graph(0)->setData(xb, yb);
+ }
+ ui->sctpPlot->xAxis->setLabel("time [secs]");
+ ui->sctpPlot->yAxis->setLabel("Received Bytes");
+
+ // set axes ranges, so we see all data:
+ QCPRange myXByteRange(0, (selected_assoc->max_secs+1));
+ QCPRange myYByteRange(0, maxBytes);
+ ui->sctpPlot->xAxis->setRange(myXByteRange);
+ ui->sctpPlot->yAxis->setRange(myYByteRange);
+}
+
+
+void SCTPGraphByteDialog::drawGraph()
+{
+ ui->sctpPlot->clearGraphs();
+ drawBytesGraph();
+ ui->sctpPlot->setInteractions(QCP::iRangeZoom | QCP::iRangeDrag | QCP::iSelectPlottables);
+ connect(ui->sctpPlot, SIGNAL(plottableClick(QCPAbstractPlottable*,QMouseEvent*)), this, SLOT(graphClicked(QCPAbstractPlottable*, QMouseEvent*)));
+ ui->sctpPlot->replot();
+}
+
+
+void SCTPGraphByteDialog::on_pushButton_4_clicked()
+{
+ ui->sctpPlot->xAxis->setRange(selected_assoc->min_secs+selected_assoc->min_usecs/1000000.0, selected_assoc->max_secs+selected_assoc->max_usecs/1000000.0);
+ if (direction == 1) {
+ ui->sctpPlot->yAxis->setRange(0, selected_assoc->n_data_bytes_ep1);
+ } else {
+ ui->sctpPlot->yAxis->setRange(0, selected_assoc->n_data_bytes_ep2);
+ }
+ ui->sctpPlot->replot();
+}
+
+void SCTPGraphByteDialog::graphClicked(QCPAbstractPlottable* plottable, QMouseEvent* event)
+{
+ if (plottable->name().contains("Bytes", Qt::CaseInsensitive)) {
+ double bytes = round(ui->sctpPlot->yAxis->pixelToCoord(event->pos().y()));
+ int i;
+ for (i = 0; i < yb.size(); i++) {
+ if (bytes <= yb.value(i)) {
+ frame_num = fb.at(i);
+ break;
+ }
+ }
+ if (cap_file_ && frame_num > 0) {
+ cf_goto_frame(cap_file_, frame_num);
+ }
+
+ ui->hintLabel->setText(QString("<small><i>Graph %1: Received bytes=%2 Time=%3 secs </i></small>")
+ .arg(plottable->name())
+ .arg(yb.value(i))
+ .arg(xb.value(i)));
+ }
+}
+
+
+void SCTPGraphByteDialog::on_saveButton_clicked()
+{
+ SCTPGraphDialog::save_graph(this, ui->sctpPlot);
+}
diff --git a/ui/qt/sctp_graph_byte_dialog.h b/ui/qt/sctp_graph_byte_dialog.h
new file mode 100644
index 0000000000..4a8fa5d595
--- /dev/null
+++ b/ui/qt/sctp_graph_byte_dialog.h
@@ -0,0 +1,55 @@
+#ifndef SCTP_GRAPH_BYTE_DIALOG_H
+#define SCTP_GRAPH_BYTE_DIALOG_H
+
+#include "config.h"
+#include "qcustomplot.h"
+#include <glib.h>
+
+#include <file.h>
+#include <math.h>
+#include <epan/dissectors/packet-sctp.h>
+#include "epan/packet.h"
+
+#include "ui/tap-sctp-analysis.h"
+
+#include <QDialog>
+#include <QObject>
+#include <QMessageBox>
+
+namespace Ui {
+class SCTPGraphByteDialog;
+}
+
+
+class SCTPGraphByteDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit SCTPGraphByteDialog(QWidget *parent = 0, sctp_assoc_info_t *assoc = NULL, capture_file *cf = NULL, int dir = 0);
+ ~SCTPGraphByteDialog();
+
+public slots:
+ void setCaptureFile(capture_file *cf) { cap_file_ = cf; }
+
+private slots:
+ void on_pushButton_4_clicked();
+
+ void graphClicked(QCPAbstractPlottable* plottable, QMouseEvent* event);
+
+ void on_saveButton_clicked();
+
+private:
+ Ui::SCTPGraphByteDialog *ui;
+ sctp_assoc_info_t *selected_assoc;
+ capture_file *cap_file_;
+ int frame_num;
+ int direction;
+ QVector<double> xb, yb;
+ QVector<guint32> fb;
+
+ void drawGraph();
+ void drawBytesGraph();
+};
+
+#endif // SCTP_GRAPH_DIALOG_H
diff --git a/ui/qt/sctp_graph_byte_dialog.ui b/ui/qt/sctp_graph_byte_dialog.ui
new file mode 100644
index 0000000000..984397f93e
--- /dev/null
+++ b/ui/qt/sctp_graph_byte_dialog.ui
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>SCTPGraphByteDialog</class>
+ <widget class="QDialog" name="SCTPGraphByteDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>800</width>
+ <height>546</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>SCTP Graph</string>
+ </property>
+ <widget class="QCustomPlot" name="sctpPlot" native="true">
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>30</y>
+ <width>761</width>
+ <height>451</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>1</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="pushButton_4">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>510</y>
+ <width>131</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::NoFocus</enum>
+ </property>
+ <property name="text">
+ <string>Reset to full size</string>
+ </property>
+ </widget>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="geometry">
+ <rect>
+ <x>680</x>
+ <y>510</y>
+ <width>120</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::NoFocus</enum>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Close</set>
+ </property>
+ </widget>
+ <widget class="QLabel" name="hintLabel">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>490</y>
+ <width>655</width>
+ <height>12</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="saveButton">
+ <property name="geometry">
+ <rect>
+ <x>140</x>
+ <y>510</y>
+ <width>114</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Save Graph</string>
+ </property>
+ </widget>
+ <action name="actionGoToPacket">
+ <property name="text">
+ <string>goToPacket</string>
+ </property>
+ <property name="toolTip">
+ <string>Go to Packet</string>
+ </property>
+ </action>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>QCustomPlot</class>
+ <extends>QWidget</extends>
+ <header>qcustomplot.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>clicked(QAbstractButton*)</signal>
+ <receiver>SCTPGraphByteDialog</receiver>
+ <slot>close()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>706</x>
+ <y>530</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>703</x>
+ <y>574</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/ui/qt/sctp_graph_dialog.cpp b/ui/qt/sctp_graph_dialog.cpp
new file mode 100644
index 0000000000..83c7ff907e
--- /dev/null
+++ b/ui/qt/sctp_graph_dialog.cpp
@@ -0,0 +1,399 @@
+#include "sctp_graph_dialog.h"
+#include "ui_sctp_graph_dialog.h"
+
+#include "wireshark_application.h"
+
+SCTPGraphDialog::SCTPGraphDialog(QWidget *parent, sctp_assoc_info_t *assoc, capture_file *cf, int dir) :
+ QDialog(parent),
+ ui(new Ui::SCTPGraphDialog),
+ selected_assoc(assoc),
+ cap_file_(cf),
+ direction(dir)
+{
+ ui->setupUi(this);
+ this->setWindowTitle(QString("SCTP TSNs and SACKs over Time: %1 Port1 %2 Port2 %3").arg(cf_get_display_name(cap_file_)).arg(selected_assoc->port1).arg(selected_assoc->port2));
+ if ((direction == 1 && selected_assoc->n_array_tsn1 == 0) || (direction == 2 && selected_assoc->n_array_tsn2 == 0)) {
+ QMessageBox msgBox;
+ msgBox.setText("No Data Chunks sent");
+ msgBox.exec();
+ return;
+ } else {
+ drawGraph(3);
+ }
+}
+
+SCTPGraphDialog::~SCTPGraphDialog()
+{
+ delete ui;
+}
+
+void SCTPGraphDialog::drawNRSACKGraph()
+{
+ tsn_t *sack;
+ GList *list=NULL, *tlist;
+ guint16 gap_start=0, gap_end=0, i, numberOf_gaps, numberOf_nr_gaps;
+ guint8 type;
+ guint32 tsnumber, j, min_tsn;
+ struct nr_sack_chunk_header *nr_sack_header;
+ struct gaps *nr_gap;
+ /* This holds the sum of gap acks and nr gap acks */
+ guint16 total_gaps = 0;
+
+ if (direction == 1) {
+ list = g_list_last(selected_assoc->sack1);
+ min_tsn = selected_assoc->min_tsn1;
+ } else {
+ list = g_list_last(selected_assoc->sack1);
+ min_tsn = selected_assoc->min_tsn1;
+ }
+ while (list) {
+ sack = (tsn_t*) (list->data);
+ tlist = g_list_first(sack->tsns);
+ while (tlist) {
+ type = ((struct chunk_header *)tlist->data)->type;
+ if (type == SCTP_NR_SACK_CHUNK_ID) {
+ gIsNRSackChunkPresent = 1;
+ nr_sack_header =(struct nr_sack_chunk_header *)tlist->data;
+ numberOf_nr_gaps=g_ntohs(nr_sack_header->nr_of_nr_gaps);
+ numberOf_gaps=g_ntohs(nr_sack_header->nr_of_gaps);
+ tsnumber = g_ntohl(nr_sack_header->cum_tsn_ack);
+ total_gaps = numberOf_gaps + numberOf_nr_gaps;
+ /* If the number of nr_gaps is greater than 0 */
+ if ( total_gaps > 0 ) {
+ nr_gap = &nr_sack_header->gaps[0];
+ for (i = 0; i < total_gaps; i++) {
+ gap_start = g_ntohs(nr_gap->start);
+ gap_end = g_ntohs(nr_gap->end);
+ for ( j = gap_start; j <= gap_end; j++) {
+ if (i >= numberOf_gaps) {
+ yn.append(j + tsnumber);
+ xn.append(sack->secs + sack->usecs/1000000.0);
+ fn.append(sack->frame_number);
+ } else {
+ yg.append(j + tsnumber);
+ xg.append(sack->secs + sack->usecs/1000000.0);
+ fg.append(sack->frame_number);
+ }
+ }
+ if (i < total_gaps-1)
+ nr_gap++;
+ }
+
+ if (tsnumber>=min_tsn) {
+ ys.append(j + tsnumber);
+ xs.append(sack->secs + sack->usecs/1000000.0);
+ fs.append(sack->frame_number);
+ }
+ }
+ }
+ tlist = g_list_next(tlist);
+ }
+ list = g_list_previous(list);
+ }
+}
+
+void SCTPGraphDialog::drawSACKGraph()
+{
+ GList *listSACK = NULL, *tlist;
+ guint16 gap_start=0, gap_end=0, nr, dup_nr;
+ struct sack_chunk_header *sack_header;
+ struct gaps *gap;
+ tsn_t *tsn;
+ guint8 type;
+ guint32 tsnumber=0;
+ guint32 minTSN;
+ guint32 *dup_list;
+ int i, j;
+
+ if (direction == 1) {
+ minTSN = selected_assoc->min_tsn1;
+ listSACK = g_list_last(selected_assoc->sack1);
+ } else {
+ minTSN = selected_assoc->min_tsn2;
+ listSACK = g_list_last(selected_assoc->sack2);
+ }
+ while (listSACK) {
+ tsn = (tsn_t*) (listSACK->data);
+ tlist = g_list_first(tsn->tsns);
+ while (tlist) {
+ type = ((struct chunk_header *)tlist->data)->type;
+ if (type == SCTP_SACK_CHUNK_ID) {
+ gIsSackChunkPresent = 1;
+ sack_header =(struct sack_chunk_header *)tlist->data;
+ nr=g_ntohs(sack_header->nr_of_gaps);
+ tsnumber = g_ntohl(sack_header->cum_tsn_ack);
+ dup_nr=g_ntohs(sack_header->nr_of_dups);
+ if (nr>0) { // Gap Reports green
+ gap = &sack_header->gaps[0];
+ for(i=0;i<nr; i++) {
+ gap_start=g_ntohs(gap->start);
+ gap_end = g_ntohs(gap->end);
+ for (j=gap_start; j<=gap_end; j++) {
+ yg.append(j+tsnumber);
+ xg.append(tsn->secs + tsn->usecs/1000000.0);
+ fg.append(tsn->frame_number);
+ }
+ if (i < nr-1)
+ gap++;
+ }
+ }
+ if (tsnumber>=minTSN) { // CumTSNAck red
+ ys.append(tsnumber);
+ xs.append(tsn->secs + tsn->usecs/1000000.0);
+ fs.append(tsn->frame_number);
+ }
+ if (dup_nr > 0) { // Duplicates cyan
+ dup_list = &sack_header->a_rwnd + 2 + nr;
+ for (i = 0; i < dup_nr; i++) {
+ tsnumber = g_ntohl(dup_list[i]);
+ if (tsnumber >= minTSN) {
+ yd.append(tsnumber);
+ xd.append(tsn->secs + tsn->usecs/1000000.0);
+ fd.append(tsn->frame_number);
+ }
+ }
+ }
+ }
+ tlist = g_list_next(tlist);
+ }
+ listSACK = g_list_previous(listSACK);
+ }
+
+ QCPScatterStyle myScatter;
+ myScatter.setShape(QCPScatterStyle::ssCircle);
+ myScatter.setSize(3);
+
+ int graphcount = ui->sctpPlot->graphCount();
+ // create graph and assign data to it:
+
+ // Add SACK graph
+ if (xs.size() > 0) {
+ ui->sctpPlot->addGraph();
+ myScatter.setPen(QPen(Qt::red));
+ myScatter.setBrush(Qt::red);
+ ui->sctpPlot->graph(graphcount)->setScatterStyle(myScatter);
+ ui->sctpPlot->graph(graphcount)->setLineStyle(QCPGraph::lsNone);
+ ui->sctpPlot->graph(graphcount)->setData(xs, ys);
+ typeStrings.insert(graphcount, QString("CumTSNAck"));
+ graphcount++;
+ }
+
+ // Add Gap Acks
+ if (xg.size() > 0) {
+ ui->sctpPlot->addGraph();
+ myScatter.setPen(QPen(Qt::green));
+ myScatter.setBrush(Qt::green);
+ ui->sctpPlot->graph(graphcount)->setScatterStyle(myScatter);
+ ui->sctpPlot->graph(graphcount)->setLineStyle(QCPGraph::lsNone);
+ ui->sctpPlot->graph(graphcount)->setData(xg, yg);
+ typeStrings.insert(graphcount, QString("Gap Ack"));
+ graphcount++;
+ }
+
+ // Add NR Gap Acks
+ if (xn.size() > 0) {
+ ui->sctpPlot->addGraph();
+ myScatter.setPen(QPen(Qt::blue));
+ myScatter.setBrush(Qt::blue);
+ ui->sctpPlot->graph(graphcount)->setScatterStyle(myScatter);
+ ui->sctpPlot->graph(graphcount)->setLineStyle(QCPGraph::lsNone);
+ ui->sctpPlot->graph(graphcount)->setData(xg, yg);
+ typeStrings.insert(graphcount, QString("NR Gap Ack"));
+ graphcount++;
+ }
+
+ // Add Duplicates
+ if (xd.size() > 0) {
+ ui->sctpPlot->addGraph();
+ myScatter.setPen(QPen(Qt::cyan));
+ myScatter.setBrush(Qt::cyan);
+ ui->sctpPlot->graph(graphcount)->setScatterStyle(myScatter);
+ ui->sctpPlot->graph(graphcount)->setLineStyle(QCPGraph::lsNone);
+ ui->sctpPlot->graph(graphcount)->setData(xd, yd);
+ typeStrings.insert(graphcount, QString("Duplicate Ack"));
+ }
+}
+
+void SCTPGraphDialog::drawTSNGraph()
+{
+ GList *listTSN = NULL,*tlist;
+ tsn_t *tsn;
+ guint8 type;
+ guint32 tsnumber=0;
+ guint32 minTSN;
+
+ if (direction == 1) {
+ minTSN = selected_assoc->min_tsn1;
+ listTSN = g_list_last(selected_assoc->tsn1);
+ } else {
+ minTSN = selected_assoc->min_tsn2;
+ listTSN = g_list_last(selected_assoc->tsn2);
+ }
+
+
+ while (listTSN) {
+ tsn = (tsn_t*) (listTSN->data);
+ tlist = g_list_first(tsn->tsns);
+ while (tlist)
+ {
+ type = ((struct chunk_header *)tlist->data)->type;
+ if (type == SCTP_DATA_CHUNK_ID || type == SCTP_FORWARD_TSN_CHUNK_ID) {
+ tsnumber = g_ntohl(((struct data_chunk_header *)tlist->data)->tsn);
+ yt.append(tsnumber);
+ xt.append(tsn->secs + tsn->usecs/1000000.0);
+ ft.append(tsn->frame_number);
+ }
+ tlist = g_list_next(tlist);
+ }
+ listTSN = g_list_previous(listTSN);
+ }
+
+ QCPScatterStyle myScatter;
+ myScatter.setShape(QCPScatterStyle::ssCircle);
+ myScatter.setSize(3);
+
+ int graphcount = ui->sctpPlot->graphCount();
+ // create graph and assign data to it:
+
+ // Add TSN graph
+ if (xt.size() > 0) {
+ ui->sctpPlot->addGraph();
+ myScatter.setPen(QPen(Qt::black));
+ myScatter.setBrush(Qt::black);
+ ui->sctpPlot->graph(graphcount)->setScatterStyle(myScatter);
+ ui->sctpPlot->graph(graphcount)->setLineStyle(QCPGraph::lsNone);
+ ui->sctpPlot->graph(graphcount)->setData(xt, yt);
+ typeStrings.insert(graphcount, QString("TSN"));
+ }
+}
+
+void SCTPGraphDialog::drawGraph(int which)
+{
+ guint32 minTSN, maxTSN;
+
+ gIsSackChunkPresent = false;
+ gIsNRSackChunkPresent = false;
+
+ if (direction == 1) {
+ minTSN = selected_assoc->min_tsn1;
+ maxTSN = selected_assoc->max_tsn1;
+ } else {
+ minTSN = selected_assoc->min_tsn2;
+ maxTSN = selected_assoc->max_tsn2;
+ }
+
+ switch (which) {
+ case 1: drawSACKGraph();
+ drawNRSACKGraph();
+ break;
+ case 2: drawTSNGraph();
+ break;
+ case 3: drawTSNGraph();
+ drawSACKGraph();
+ drawNRSACKGraph();
+ break;
+ default: drawTSNGraph();
+ drawSACKGraph();
+ drawNRSACKGraph();
+ }
+
+ // give the axes some labels:
+ ui->sctpPlot->xAxis->setLabel("time [secs]");
+ ui->sctpPlot->yAxis->setLabel("TSNs");
+ ui->sctpPlot->setInteractions(QCP::iRangeZoom | QCP::iRangeDrag | QCP::iSelectPlottables);
+ connect(ui->sctpPlot, SIGNAL(plottableClick(QCPAbstractPlottable*,QMouseEvent*)), this, SLOT(graphClicked(QCPAbstractPlottable*, QMouseEvent*)));
+ // set axes ranges, so we see all data:
+ QCPRange myXRange(0, (selected_assoc->max_secs+1));
+ QCPRange myYRange(0, maxTSN);
+ ui->sctpPlot->xAxis->setRange(myXRange);
+ ui->sctpPlot->yAxis->setRange(myYRange);
+ ui->sctpPlot->replot();
+}
+
+void SCTPGraphDialog::on_pushButton_clicked()
+{
+ drawGraph(1);
+}
+
+void SCTPGraphDialog::on_pushButton_2_clicked()
+{
+ drawGraph(2);
+}
+
+void SCTPGraphDialog::on_pushButton_3_clicked()
+{
+ drawGraph(3);
+}
+
+void SCTPGraphDialog::on_pushButton_4_clicked()
+{
+ ui->sctpPlot->xAxis->setRange(selected_assoc->min_secs+selected_assoc->min_usecs/1000000.0, selected_assoc->max_secs+selected_assoc->max_usecs/1000000.0);
+ if (direction == 1) {
+ ui->sctpPlot->yAxis->setRange(selected_assoc->min_tsn1, selected_assoc->max_tsn1);
+ } else {
+ ui->sctpPlot->yAxis->setRange(selected_assoc->min_tsn2, selected_assoc->max_tsn2);
+ }
+ ui->sctpPlot->replot();
+}
+
+void SCTPGraphDialog::graphClicked(QCPAbstractPlottable* plottable, QMouseEvent* event)
+{
+ if (plottable->name().contains("Graph", Qt::CaseInsensitive)) {
+ // double tsn = round(ui->sctpPlot->yAxis->pixelToCoord(event->pos().y()));
+ int index = yt.indexOf(round(ui->sctpPlot->yAxis->pixelToCoord(event->pos().y())));
+ // double time = xt.at(index);
+ frame_num = ft.at(index);
+ if (cap_file_ && frame_num > 0) {
+ cf_goto_frame(cap_file_, frame_num);
+ }
+ }
+ int num = plottable->name().remove("Graph ",Qt::CaseInsensitive).toInt();
+ ui->hintLabel->setText(QString("<small><i>%1: %2: %3 Time: %4 secs </i></small>")
+ .arg(plottable->name())
+ .arg(typeStrings[num-1])
+ .arg(round(ui->sctpPlot->yAxis->pixelToCoord(event->pos().y())))
+ .arg(ui->sctpPlot->xAxis->pixelToCoord(event->pos().x())));
+}
+
+void SCTPGraphDialog::save_graph(QDialog *dlg, QCustomPlot *plot)
+{
+ QString file_name, extension;
+ QDir path(wsApp->lastOpenDir());
+ QString pdf_filter = tr("Portable Document Format (*.pdf)");
+ QString png_filter = tr("Portable Network Graphics (*.png)");
+ QString bmp_filter = tr("Windows Bitmap (*.bmp)");
+ // Gaze upon my beautiful graph with lossy artifacts!
+ QString jpeg_filter = tr("JPEG File Interchange Format (*.jpeg *.jpg)");
+ QString filter = QString("%1;;%2;;%3;;%4")
+ .arg(pdf_filter)
+ .arg(png_filter)
+ .arg(bmp_filter)
+ .arg(jpeg_filter);
+
+ file_name = QFileDialog::getSaveFileName(dlg, tr("Wireshark: Save Graph As..."),
+ path.canonicalPath(), filter, &extension);
+
+ if (file_name.length() > 0) {
+ bool save_ok = false;
+ if (extension.compare(pdf_filter) == 0) {
+ save_ok = plot->savePdf(file_name);
+ } else if (extension.compare(png_filter) == 0) {
+ save_ok = plot->savePng(file_name);
+ } else if (extension.compare(bmp_filter) == 0) {
+ save_ok = plot->saveBmp(file_name);
+ } else if (extension.compare(jpeg_filter) == 0) {
+ save_ok = plot->saveJpg(file_name);
+ }
+ // else error dialog?
+ if (save_ok) {
+ path = QDir(file_name);
+ wsApp->setLastOpenDir(path.canonicalPath().toUtf8().constData());
+ }
+ }
+}
+
+
+void SCTPGraphDialog::on_saveButton_clicked()
+{
+ save_graph(this, ui->sctpPlot);
+}
diff --git a/ui/qt/sctp_graph_dialog.h b/ui/qt/sctp_graph_dialog.h
new file mode 100644
index 0000000000..29f7c0a089
--- /dev/null
+++ b/ui/qt/sctp_graph_dialog.h
@@ -0,0 +1,114 @@
+#ifndef SCTP_GRAPH_DIALOG_H
+#define SCTP_GRAPH_DIALOG_H
+
+#include "config.h"
+#include "qcustomplot.h"
+#include <glib.h>
+
+#include <file.h>
+#include <math.h>
+#include <epan/dissectors/packet-sctp.h>
+#include "epan/packet.h"
+
+#include "ui/tap-sctp-analysis.h"
+
+#include <QDialog>
+#include <QObject>
+#include <QMessageBox>
+#include <QDir>
+#include <QFileDialog>
+
+namespace Ui {
+class SCTPGraphDialog;
+}
+
+struct chunk_header {
+ guint8 type;
+ guint8 flags;
+ guint16 length;
+};
+
+struct data_chunk_header {
+ guint8 type;
+ guint8 flags;
+ guint16 length;
+ guint32 tsn;
+ guint16 sid;
+ guint16 ssn;
+ guint32 ppi;
+};
+
+struct gaps {
+ guint16 start;
+ guint16 end;
+};
+
+struct sack_chunk_header {
+ guint8 type;
+ guint8 flags;
+ guint16 length;
+ guint32 cum_tsn_ack;
+ guint32 a_rwnd;
+ guint16 nr_of_gaps;
+ guint16 nr_of_dups;
+ struct gaps gaps[1];
+};
+
+struct nr_sack_chunk_header {
+ guint8 type;
+ guint8 flags;
+ guint16 length;
+ guint32 cum_tsn_ack;
+ guint32 a_rwnd;
+ guint16 nr_of_gaps;
+ guint16 nr_of_nr_gaps;
+ guint16 nr_of_dups;
+ guint16 reserved;
+ struct gaps gaps[1];
+};
+
+
+class SCTPGraphDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit SCTPGraphDialog(QWidget *parent = 0, sctp_assoc_info_t *assoc = NULL, capture_file *cf = NULL, int dir = 0);
+ ~SCTPGraphDialog();
+ static void save_graph(QDialog *dlg, QCustomPlot *plot);
+
+public slots:
+ void setCaptureFile(capture_file *cf) { cap_file_ = cf; }
+
+private slots:
+ void on_pushButton_clicked();
+
+ void on_pushButton_2_clicked();
+
+ void on_pushButton_3_clicked();
+
+ void on_pushButton_4_clicked();
+
+ void graphClicked(QCPAbstractPlottable* plottable, QMouseEvent* event);
+
+ void on_saveButton_clicked();
+
+private:
+ Ui::SCTPGraphDialog *ui;
+ sctp_assoc_info_t *selected_assoc;
+ capture_file *cap_file_;
+ int frame_num;
+ int direction;
+ QVector<double> xt, yt, xs, ys, xg, yg, xd, yd, xn, yn;
+ QVector<guint32> ft, fs, fg, fd, fn;
+ QVector<QString> typeStrings;
+ bool gIsSackChunkPresent;
+ bool gIsNRSackChunkPresent;
+
+ void drawGraph(int which);
+ void drawTSNGraph();
+ void drawSACKGraph();
+ void drawNRSACKGraph();
+};
+
+#endif // SCTP_GRAPH_DIALOG_H
diff --git a/ui/qt/sctp_graph_dialog.ui b/ui/qt/sctp_graph_dialog.ui
new file mode 100644
index 0000000000..2a5a847bd6
--- /dev/null
+++ b/ui/qt/sctp_graph_dialog.ui
@@ -0,0 +1,177 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>SCTPGraphDialog</class>
+ <widget class="QDialog" name="SCTPGraphDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>800</width>
+ <height>546</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>SCTP Graph</string>
+ </property>
+ <widget class="QCustomPlot" name="sctpPlot" native="true">
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>30</y>
+ <width>761</width>
+ <height>451</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>1</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="pushButton">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>510</y>
+ <width>120</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::NoFocus</enum>
+ </property>
+ <property name="text">
+ <string>Only SACKs</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="pushButton_2">
+ <property name="geometry">
+ <rect>
+ <x>120</x>
+ <y>510</y>
+ <width>120</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::NoFocus</enum>
+ </property>
+ <property name="text">
+ <string>Only TSNs</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="pushButton_3">
+ <property name="geometry">
+ <rect>
+ <x>240</x>
+ <y>510</y>
+ <width>120</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::NoFocus</enum>
+ </property>
+ <property name="text">
+ <string>Show both</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="pushButton_4">
+ <property name="geometry">
+ <rect>
+ <x>360</x>
+ <y>510</y>
+ <width>131</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::NoFocus</enum>
+ </property>
+ <property name="text">
+ <string>Reset to full size</string>
+ </property>
+ </widget>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="geometry">
+ <rect>
+ <x>680</x>
+ <y>510</y>
+ <width>120</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::NoFocus</enum>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Close</set>
+ </property>
+ </widget>
+ <widget class="QLabel" name="hintLabel">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>490</y>
+ <width>655</width>
+ <height>12</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="saveButton">
+ <property name="geometry">
+ <rect>
+ <x>490</x>
+ <y>510</y>
+ <width>114</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Save Graph</string>
+ </property>
+ </widget>
+ <action name="actionGoToPacket">
+ <property name="text">
+ <string>goToPacket</string>
+ </property>
+ <property name="toolTip">
+ <string>Go to Packet</string>
+ </property>
+ </action>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>QCustomPlot</class>
+ <extends>QWidget</extends>
+ <header>qcustomplot.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>clicked(QAbstractButton*)</signal>
+ <receiver>SCTPGraphDialog</receiver>
+ <slot>close()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>706</x>
+ <y>530</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>703</x>
+ <y>574</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/ui/tap-sctp-analysis.c b/ui/tap-sctp-analysis.c
index 77a64e615e..8344bce1cd 100644
--- a/ui/tap-sctp-analysis.c
+++ b/ui/tap-sctp-analysis.c
@@ -36,68 +36,6 @@
#include "ui/simple_dialog.h"
-#define SCTP_ABORT_CHUNK_T_BIT 0x01
-
-#define PARAMETER_TYPE_LENGTH 2
-#define PARAMETER_LENGTH_LENGTH 2
-#define PARAMETER_HEADER_LENGTH (PARAMETER_TYPE_LENGTH + PARAMETER_LENGTH_LENGTH)
-
-#define PARAMETER_HEADER_OFFSET 0
-#define PARAMETER_TYPE_OFFSET PARAMETER_HEADER_OFFSET
-#define PARAMETER_LENGTH_OFFSET (PARAMETER_TYPE_OFFSET + PARAMETER_TYPE_LENGTH)
-#define PARAMETER_VALUE_OFFSET (PARAMETER_LENGTH_OFFSET + PARAMETER_LENGTH_LENGTH)
-
-#define IPV6_ADDRESS_LENGTH 16
-#define IPV6_ADDRESS_OFFSET PARAMETER_VALUE_OFFSET
-#define IPV4_ADDRESS_LENGTH 4
-#define IPV4_ADDRESS_OFFSET PARAMETER_VALUE_OFFSET
-#define IPV4ADDRESS_PARAMETER_ID 0x0005
-#define IPV6ADDRESS_PARAMETER_ID 0x0006
-
-#define SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH 4
-#define SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET (CHUNK_VALUE_OFFSET + 0)
-#define SACK_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH 4
-#define SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET (SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET + \
- SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH)
-
-#define INIT_CHUNK_INITIAL_TSN_LENGTH 4
-#define INIT_CHUNK_FIXED_PARAMTERS_LENGTH (INIT_CHUNK_INITIATE_TAG_LENGTH + \
- 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)
-#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 )
-
-static const value_string chunk_type_values[] = {
- { SCTP_DATA_CHUNK_ID, "DATA" },
- { SCTP_INIT_CHUNK_ID, "INIT" },
- { SCTP_INIT_ACK_CHUNK_ID, "INIT_ACK" },
- { SCTP_SACK_CHUNK_ID, "SACK" },
- { SCTP_HEARTBEAT_CHUNK_ID, "HEARTBEAT" },
- { SCTP_HEARTBEAT_ACK_CHUNK_ID, "HEARTBEAT_ACK" },
- { SCTP_ABORT_CHUNK_ID, "ABORT" },
- { SCTP_SHUTDOWN_CHUNK_ID, "SHUTDOWN" },
- { SCTP_SHUTDOWN_ACK_CHUNK_ID, "SHUTDOWN_ACK" },
- { SCTP_ERROR_CHUNK_ID, "ERROR" },
- { SCTP_COOKIE_ECHO_CHUNK_ID, "COOKIE_ECHO" },
- { SCTP_COOKIE_ACK_CHUNK_ID, "COOKIE_ACK" },
- { SCTP_ECNE_CHUNK_ID, "ECNE" },
- { SCTP_CWR_CHUNK_ID, "CWR" },
- { SCTP_SHUTDOWN_COMPLETE_CHUNK_ID, "SHUTDOWN_COMPLETE" },
- { SCTP_FORWARD_TSN_CHUNK_ID, "FORWARD TSN" },
- { SCTP_ASCONF_ACK_CHUNK_ID, "ASCONF_ACK" },
- { 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 } };
-
-
#define FORWARD_STREAM 0
#define BACKWARD_STREAM 1
#define FORWARD_ADD_FORWARD_VTAG 2
@@ -272,145 +210,20 @@ static sctp_assoc_info_t *calc_checksum(struct _sctp_info *check_data, sctp_asso
}
-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);
-
- if ((a->port1 == b->port1) &&
- (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); /* 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 ||
- (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) &&
- (a->verification_tag1 != 0) &&
- (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) &&
- (a->verification_tag1 !=0) &&
- (b->verification_tag1 != 0) &&
- (b->verification_tag2 == 0))
- return(BACKWARD_ADD_BACKWARD_VTAG);
-
- return(ASSOC_NOT_FOUND);
-}
-
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;
- guint8 cmp;
assoc_info = &sctp_tapinfo_struct;
if ((list = g_list_last(assoc_info->assoc_info_list))!=NULL)
{
while (list)
{
- cmp=sctp_assoc_vtag_cmp(needle, (sctp_assoc_info_t*)(list->data));
-
- switch (cmp)
- {
- case FORWARD_STREAM:
- info = (sctp_assoc_info_t*)(list->data);
- info->direction = 1;
- return info;
- case BACKWARD_STREAM:
- info = (sctp_assoc_info_t*)(list->data);
- info->direction = 2;
- return info;
- case FORWARD_ADD_FORWARD_VTAG:
- info = (sctp_assoc_info_t*)(list->data);
- info->verification_tag1=needle->verification_tag1;
- info->direction = 1;
- return info;
- case BACKWARD_ADD_FORWARD_VTAG:
- info = (sctp_assoc_info_t*)(list->data);
- info->verification_tag1=needle->verification_tag1;
- info->direction = 2;
- return info;
- case BACKWARD_ADD_BACKWARD_VTAG:
- info = (sctp_assoc_info_t*)(list->data);
- info->verification_tag2=needle->verification_tag1;
- info->direction = 2;
- return info;
- case ADDRESS_FORWARD_STREAM:
- info = (sctp_assoc_info_t*)(list->data);
- info->direction = 1;
- info->check_address=TRUE;
- return info;
- case ADDRESS_BACKWARD_STREAM:
- info = (sctp_assoc_info_t*)(list->data);
- info->direction = 2;
- info->check_address=TRUE;
- return info;
- case ADDRESS_FORWARD_ADD_FORWARD_VTAG:
- info = (sctp_assoc_info_t*)(list->data);
- info->verification_tag1=needle->verification_tag1;
- info->direction = 1;
- info->check_address=TRUE;
- return info;
- case ADDRESS_BACKWARD_ADD_FORWARD_VTAG:
- info = (sctp_assoc_info_t*)(list->data);
- info->verification_tag1=needle->verification_tag1;
- info->direction = 2;
- info->check_address=TRUE;
- return info;
- case ADDRESS_BACKWARD_ADD_BACKWARD_VTAG:
- info = (sctp_assoc_info_t*)(list->data);
- info->verification_tag2=needle->verification_tag1;
- info->direction = 2;
- info->check_address=TRUE;
- return info;
- }
+ info = (sctp_assoc_info_t*)(list->data);
+ if (needle->assoc_id == info->assoc_id)
+ return info;
list = g_list_previous(list);
}
@@ -590,6 +403,8 @@ packet(void *tapdata _U_, packet_info *pinfo , epan_dissect_t *edt _U_ , const v
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)
{
@@ -600,6 +415,7 @@ packet(void *tapdata _U_, packet_info *pinfo , epan_dissect_t *edt _U_ , const v
{
info = (sctp_assoc_info_t *)g_malloc(sizeof(sctp_assoc_info_t));
memset(info, 0, sizeof(sctp_assoc_info_t));
+ info->assoc_id = sctp_info->assoc_index;
info->src.type = tmp_info.src.type;
info->src.len = tmp_info.src.len;
addr = (guint8 *)g_malloc(tmp_info.dst.len);
@@ -651,6 +467,7 @@ packet(void *tapdata _U_, packet_info *pinfo , epan_dissect_t *edt _U_ , const v
info->sort_tsn2 = g_ptr_array_new();
info->sort_sack1 = g_ptr_array_new();
info->sort_sack2 = g_ptr_array_new();
+
for (i=0; i < NUM_CHUNKS; i++)
{
info->chunk_count[i] = 0;
@@ -720,6 +537,7 @@ packet(void *tapdata _U_, packet_info *pinfo , epan_dissect_t *edt _U_ , const v
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);
@@ -943,6 +761,13 @@ packet(void *tapdata _U_, packet_info *pinfo , epan_dissect_t *edt _U_ , const v
} /* endif (!info) */
else
{
+ 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) ||
@@ -1037,7 +862,7 @@ packet(void *tapdata _U_, packet_info *pinfo , epan_dissect_t *edt _U_ , const v
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->initack_dir=2;*/
+ info->arwnd2 = tvb_get_ntohl(sctp_info->tvb[0],INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
info->tsn2 = g_list_prepend(info->tsn2, tsn);
}
else if (info->direction == 1)
@@ -1048,7 +873,7 @@ packet(void *tapdata _U_, packet_info *pinfo , epan_dissect_t *edt _U_ , const v
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->initack_dir=1;*/
+ info->arwnd1 = tvb_get_ntohl(sctp_info->tvb[0],INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
info->tsn1 = g_list_prepend(info->tsn1, tsn);
}
@@ -1367,13 +1192,6 @@ const sctp_allassocs_info_t* sctp_stat_get_info(void)
}
-/*static void
-sctp_update(void *dummy _U_)
-{
- if (get_stat_dlg()!=NULL)
- sctp_stat_dlg_update();
-}*/
-
void
register_tap_listener_sctp_stat(void)
{
diff --git a/ui/tap-sctp-analysis.h b/ui/tap-sctp-analysis.h
index 5efc4c416e..2200bb8f4a 100644
--- a/ui/tap-sctp-analysis.h
+++ b/ui/tap-sctp-analysis.h
@@ -25,6 +25,10 @@
#ifndef __TAP_SCTP_ANALYSIS_H__
#define __TAP_SCTP_ANALYSIS_H__
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
#include <epan/dissectors/packet-sctp.h>
#include <epan/address.h>
#ifndef _WIN32
@@ -54,11 +58,13 @@
#define SCTP_SHUTDOWN_COMPLETE_CHUNK_ID 14
#define SCTP_AUTH_CHUNK_ID 15
#define SCTP_NR_SACK_CHUNK_ID 16
-#define SCTP_FORWARD_TSN_CHUNK_ID 0xc0
#define SCTP_ASCONF_ACK_CHUNK_ID 0x80
#define SCTP_PKTDROP_CHUNK_ID 0x81
-#define SCTP_ASCONF_CHUNK_ID 0xc1
-#define SCTP_IETF_EXT 255
+#define SCTP_RE_CONFIG_CHUNK_ID 0x82
+#define SCTP_PAD_CHUNK_ID 0x84
+#define SCTP_FORWARD_TSN_CHUNK_ID 0xC0
+#define SCTP_ASCONF_CHUNK_ID 0xC1
+#define SCTP_IETF_EXT 0xFF
#define IS_SCTP_CHUNK_TYPE(t) \
(((t) <= 16) || ((t) == 0xC0) || ((t) == 0xC1) || ((t) == 0x80) || ((t) == 0x81))
@@ -138,8 +144,35 @@
#define INIT_CHUNK_VARIABLE_LENGTH_PARAMETER_OFFSET (INIT_CHUNK_INITIAL_TSN_OFFSET + \
INIT_CHUNK_INITIAL_TSN_LENGTH )
-/* The below value is 256 */
-#define NUM_CHUNKS 0xff
+static const value_string chunk_type_values[] = {
+ { SCTP_DATA_CHUNK_ID, "DATA" },
+ { SCTP_INIT_CHUNK_ID, "INIT" },
+ { SCTP_INIT_ACK_CHUNK_ID, "INIT_ACK" },
+ { SCTP_SACK_CHUNK_ID, "SACK" },
+ { SCTP_HEARTBEAT_CHUNK_ID, "HEARTBEAT" },
+ { SCTP_HEARTBEAT_ACK_CHUNK_ID, "HEARTBEAT_ACK" },
+ { SCTP_ABORT_CHUNK_ID, "ABORT" },
+ { SCTP_SHUTDOWN_CHUNK_ID, "SHUTDOWN" },
+ { SCTP_SHUTDOWN_ACK_CHUNK_ID, "SHUTDOWN_ACK" },
+ { SCTP_ERROR_CHUNK_ID, "ERROR" },
+ { SCTP_COOKIE_ECHO_CHUNK_ID, "COOKIE_ECHO" },
+ { SCTP_COOKIE_ACK_CHUNK_ID, "COOKIE_ACK" },
+ { SCTP_ECNE_CHUNK_ID, "ECNE" },
+ { SCTP_CWR_CHUNK_ID, "CWR" },
+ { SCTP_SHUTDOWN_COMPLETE_CHUNK_ID, "SHUTDOWN_COMPLETE" },
+ { SCTP_AUTH_CHUNK_ID, "AUTH" },
+ { SCTP_NR_SACK_CHUNK_ID, "NR-SACK" },
+ { SCTP_ASCONF_ACK_CHUNK_ID, "ASCONF_ACK" },
+ { SCTP_PKTDROP_CHUNK_ID, "PKTDROP" },
+ { SCTP_RE_CONFIG_CHUNK_ID, "RE_CONFIG" },
+ { SCTP_PAD_CHUNK_ID, "PAD" },
+ { SCTP_FORWARD_TSN_CHUNK_ID, "FORWARD_TSN" },
+ { SCTP_ASCONF_CHUNK_ID, "ASCONF" },
+ { SCTP_IETF_EXT, "IETF_EXTENSION" },
+ { 0, NULL } };
+
+/* The below value is 255 */
+#define NUM_CHUNKS 0x100
/* This variable is used as an index into arrays
* which store the cumulative information corresponding
@@ -165,6 +198,8 @@ typedef struct _tsn {
} tsn_t;
typedef struct _sctp_tmp_info {
+ guint16 assoc_id;
+ guint16 direction;
address src;
address dst;
guint16 port1;
@@ -207,6 +242,7 @@ typedef struct _sctp_addr_chunk {
} sctp_addr_chunk;
typedef struct _sctp_assoc_info {
+ guint16 assoc_id;
address src;
address dst;
guint16 port1;
@@ -247,6 +283,8 @@ typedef struct _sctp_assoc_info {
guint32 n_array_tsn2;
guint32 max_window1;
guint32 max_window2;
+ guint32 arwnd1;
+ guint32 arwnd2;
gboolean init;
gboolean initack;
guint8 initack_dir;
@@ -310,7 +348,9 @@ void remove_tap_listener_sctp_stat(void);
const sctp_assoc_info_t* get_selected_assoc(void);
-
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
#endif /* __TAP_SCTP_ANALYSIS_H__ */