summaryrefslogtreecommitdiffstats
path: root/ui/qt/sctp_chunk_statistics_dialog.cpp
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 20:34:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 20:34:10 +0000
commite4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc (patch)
tree68cb5ef9081156392f1dd62a00c6ccc1451b93df /ui/qt/sctp_chunk_statistics_dialog.cpp
parentInitial commit. (diff)
downloadwireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.tar.xz
wireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.zip
Adding upstream version 4.2.2.upstream/4.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ui/qt/sctp_chunk_statistics_dialog.cpp')
-rw-r--r--ui/qt/sctp_chunk_statistics_dialog.cpp330
1 files changed, 330 insertions, 0 deletions
diff --git a/ui/qt/sctp_chunk_statistics_dialog.cpp b/ui/qt/sctp_chunk_statistics_dialog.cpp
new file mode 100644
index 0000000..f77c2ed
--- /dev/null
+++ b/ui/qt/sctp_chunk_statistics_dialog.cpp
@@ -0,0 +1,330 @@
+/* sctp_chunk_statistics_dialog.cpp
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "sctp_chunk_statistics_dialog.h"
+#include "sctp_assoc_analyse_dialog.h"
+#include <ui_sctp_chunk_statistics_dialog.h>
+#include "uat_dialog.h"
+
+#include <wsutil/strtoi.h>
+#include <wsutil/wslog.h>
+
+#include "ui/tap-sctp-analysis.h"
+#include <ui/qt/utils/qt_ui_utils.h>
+
+SCTPChunkStatisticsDialog::SCTPChunkStatisticsDialog(QWidget *parent, const sctp_assoc_info_t *assoc,
+ capture_file *cf) :
+ QDialog(parent),
+ ui(new Ui::SCTPChunkStatisticsDialog),
+ cap_file_(cf)
+{
+ Q_ASSERT(assoc);
+ selected_assoc_id = assoc->assoc_id;
+
+ ui->setupUi(this);
+ Qt::WindowFlags flags = Qt::Window | Qt::WindowSystemMenuHint
+ | Qt::WindowMinimizeButtonHint
+ | Qt::WindowMaximizeButtonHint
+ | Qt::WindowCloseButtonHint;
+ this->setWindowFlags(flags);
+ ui->tableWidget->verticalHeader()->setSectionsClickable(true);
+ ui->tableWidget->verticalHeader()->setSectionsMovable(true);
+
+
+ ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
+ ui->tableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
+
+ ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
+
+ this->setWindowTitle(QString(tr("SCTP Chunk Statistics: %1 Port1 %2 Port2 %3"))
+ .arg(gchar_free_to_qstring(cf_get_display_name(cap_file_)))
+ .arg(assoc->port1).arg(assoc->port2));
+// connect(ui->tableWidget->verticalHeader(), &QHeaderView::sectionMoved, this, &SCTPChunkStatisticsDialog::on_sectionMoved);
+
+ ctx_menu_.addAction(ui->actionHideChunkType);
+ ctx_menu_.addAction(ui->actionChunkTypePreferences);
+ ctx_menu_.addAction(ui->actionShowAllChunkTypes);
+ initializeChunkMap();
+ fillTable(false, assoc);
+}
+
+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;
+ snprintf(buf, sizeof buf, "%d", i);
+ (void) g_strlcpy(temp.name, val_to_str_const(i, chunk_type_values, "NA"), sizeof temp.name);
+ if (strcmp(temp.name, "NA") == 0) {
+ temp.hide = 1;
+ (void) g_strlcpy(temp.name, buf, sizeof temp.name);
+ } else {
+ temp.hide = 0;
+ }
+ chunks.insert(i, temp);
+ }
+}
+
+void SCTPChunkStatisticsDialog::fillTable(bool all, const sctp_assoc_info_t *selected_assoc)
+{
+ if (!selected_assoc) {
+ selected_assoc = SCTPAssocAnalyseDialog::findAssoc(this, selected_assoc_id);
+ if (!selected_assoc) return;
+ }
+
+ FILE* fp = NULL;
+
+ pref_t *pref = prefs_find_preference(prefs_find_module("sctp"),"statistics_chunk_types");
+ if (!pref) {
+ ws_log(LOG_DOMAIN_QTUI, LOG_LEVEL_ERROR, "Can't find preference sctp/statistics_chunk_types");
+ return;
+ }
+ uat_t *uat = prefs_get_uat_value(pref);
+ gchar* fname = uat_get_actual_filename(uat,TRUE);
+ bool init = false;
+
+ if (!fname) {
+ init = true;
+ } else {
+ fp = ws_fopen(fname,"r");
+
+ if (!fp) {
+ if (errno == ENOENT) {
+ init = true;
+ } else {
+ ws_log(LOG_DOMAIN_QTUI, LOG_LEVEL_ERROR, "Can't open %s: %s", fname, g_strerror(errno));
+ return;
+ }
+ }
+ }
+ g_free (fname);
+
+ if (init || all) {
+ int i, j = 0;
+
+ for (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 (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[100];
+ char *token, id[5];
+ int i = 0, j = 0;
+ struct chunkTypes temp;
+
+ while (fgets(line, (int)sizeof line, fp)) {
+ if (line[0] == '#')
+ continue;
+ token = strtok(line, ",");
+ if (!token)
+ continue;
+ /* Get rid of the quotation marks */
+ QString ch = QString(token).mid(1, (int)strlen(token)-2);
+ (void) g_strlcpy(id, qPrintable(ch), sizeof id);
+ if (!ws_strtoi32(id, NULL, &temp.id))
+ continue;
+ temp.hide = 0;
+ temp.name[0] = '\0';
+ 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 ch2 = QString(token).mid(1, (int)strlen(token)-2);
+ (void) g_strlcpy(temp.name, qPrintable(ch2), sizeof temp.name);
+ }
+ }
+ }
+ 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 (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++;
+ }
+ }
+ }
+ if (fp)
+ 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) {
+ ctx_menu_.popup(event->globalPos());
+ }
+}
+
+
+
+void SCTPChunkStatisticsDialog::on_pushButton_clicked()
+{
+ FILE* fp;
+
+ pref_t *pref = prefs_find_preference(prefs_find_module("sctp"),"statistics_chunk_types");
+ if (!pref) {
+ ws_log(LOG_DOMAIN_QTUI, LOG_LEVEL_ERROR, "Can't find preference sctp/statistics_chunk_types");
+ return;
+ }
+
+ uat_t *uat = prefs_get_uat_value(pref);
+
+ gchar* fname = uat_get_actual_filename(uat,TRUE);
+
+ if (!fname) {
+ return;
+ }
+ fp = ws_fopen(fname,"w");
+
+ if (!fp && errno == ENOENT) {
+ gchar *pf_dir_path = NULL;
+ if (create_persconffile_dir(&pf_dir_path) != 0) {
+ g_free (pf_dir_path);
+ return;
+ }
+ fp = ws_fopen(fname,"w");
+ }
+
+ if (!fp) {
+ return;
+ }
+
+ g_free (fname);
+
+ fprintf(fp,"# This file is automatically generated, DO NOT MODIFY.\n");
+ char str[40];
+ struct chunkTypes tempChunk;
+
+ for (int i = 0; i < chunks.size(); i++) {
+ tempChunk = chunks.value(i);
+ snprintf(str, sizeof str, "\"%d\",\"%s\",\"%s\"\n", tempChunk.id, tempChunk.name, tempChunk.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)
+{
+}*/
+
+void SCTPChunkStatisticsDialog::on_actionHideChunkType_triggered()
+{
+ int row;
+
+ QTableWidgetItem *itemPoint = ui->tableWidget->itemAt(selected_point.x(), selected_point.y()-60);
+ if (itemPoint) {
+ row = itemPoint->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()
+{
+ gchar* err = NULL;
+
+ pref_t *pref = prefs_find_preference(prefs_find_module("sctp"),"statistics_chunk_types");
+ if (!pref) {
+ ws_log(LOG_DOMAIN_QTUI, LOG_LEVEL_ERROR, "Can't find preference sctp/statistics_chunk_types");
+ return;
+ }
+
+ uat_t *uat = prefs_get_uat_value(pref);
+ uat_clear(uat);
+
+ if (!uat_load(uat, NULL, &err)) {
+ /* XXX - report this through the GUI */
+ ws_log(LOG_DOMAIN_QTUI, LOG_LEVEL_WARNING, "Error loading table '%s': %s", uat->name, err);
+ g_free(err);
+ }
+
+ UatDialog *uatdialog = new UatDialog(this, uat);
+ uatdialog->exec();
+ // Emitting PacketDissectionChanged directly from a QDialog can cause
+ // problems on macOS.
+ mainApp->flushAppSignals();
+
+ ui->tableWidget->clear();
+ ui->tableWidget->setRowCount(0);
+ ui->tableWidget->setHorizontalHeaderItem(0, new QTableWidgetItem(QString(tr("Association"))));
+ ui->tableWidget->setHorizontalHeaderItem(1, new QTableWidgetItem(QString(tr("Endpoint 1"))));
+ ui->tableWidget->setHorizontalHeaderItem(2, new QTableWidgetItem(QString(tr("Endpoint 2"))));
+ fillTable();
+}
+
+void SCTPChunkStatisticsDialog::on_actionShowAllChunkTypes_triggered()
+{
+ ui->tableWidget->clear();
+ ui->tableWidget->setRowCount(0);
+ ui->tableWidget->setHorizontalHeaderItem(0, new QTableWidgetItem(QString(tr("Association"))));
+ ui->tableWidget->setHorizontalHeaderItem(1, new QTableWidgetItem(QString(tr("Endpoint 1"))));
+ ui->tableWidget->setHorizontalHeaderItem(2, new QTableWidgetItem(QString(tr("Endpoint 2"))));
+ initializeChunkMap();
+ fillTable(true);
+}