summaryrefslogtreecommitdiffstats
path: root/ui/qt/sctp_graph_byte_dialog.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ui/qt/sctp_graph_byte_dialog.cpp')
-rw-r--r--ui/qt/sctp_graph_byte_dialog.cpp181
1 files changed, 181 insertions, 0 deletions
diff --git a/ui/qt/sctp_graph_byte_dialog.cpp b/ui/qt/sctp_graph_byte_dialog.cpp
new file mode 100644
index 0000000..bd91c08
--- /dev/null
+++ b/ui/qt/sctp_graph_byte_dialog.cpp
@@ -0,0 +1,181 @@
+/* sctp_graph_byte_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_graph_byte_dialog.h"
+#include <ui_sctp_graph_byte_dialog.h>
+
+#include <file.h>
+#include <math.h>
+#include <epan/dissectors/packet-sctp.h>
+#include "epan/packet.h"
+
+#include "ui/tap-sctp-analysis.h"
+
+#include <ui/qt/utils/qt_ui_utils.h>
+#include <ui/qt/widgets/qcustomplot.h>
+#include "sctp_graph_dialog.h"
+#include "sctp_assoc_analyse_dialog.h"
+
+SCTPGraphByteDialog::SCTPGraphByteDialog(QWidget *parent, const sctp_assoc_info_t *assoc,
+ capture_file *cf, int dir) :
+ QDialog(parent),
+ ui(new Ui::SCTPGraphByteDialog),
+ cap_file_(cf),
+ frame_num(0),
+ direction(dir)
+{
+ 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);
+ this->setWindowTitle(QString(tr("SCTP Data and Adv. Rec. Window over Time: %1 Port1 %2 Port2 %3"))
+ .arg(gchar_free_to_qstring(cf_get_display_name(cap_file_))).arg(assoc->port1).arg(assoc->port2));
+ if ((direction == 1 && assoc->n_array_tsn1 == 0) || (direction == 2 && assoc->n_array_tsn2 == 0)) {
+ QMessageBox msgBox;
+ msgBox.setText(tr("No Data Chunks sent"));
+ msgBox.exec();
+ return;
+ } else {
+ drawGraph();
+ }
+}
+
+SCTPGraphByteDialog::~SCTPGraphByteDialog()
+{
+ delete ui;
+}
+
+
+void SCTPGraphByteDialog::drawBytesGraph(const sctp_assoc_info_t *selected_assoc)
+{
+ GList *listTSN = Q_NULLPTR, *tlist = Q_NULLPTR;
+ tsn_t *tsn = Q_NULLPTR;
+ guint8 type;
+ guint32 maxBytes;
+ guint64 sumBytes = 0;
+
+ if (direction == 1) {
+ maxBytes = selected_assoc->n_data_bytes_ep1;
+ listTSN = g_list_last(selected_assoc->tsn1);
+ } else {
+ maxBytes = selected_assoc->n_data_bytes_ep2;
+ listTSN = g_list_last(selected_assoc->tsn2);
+ }
+
+
+ while (listTSN) {
+ tsn = gxx_list_data(tsn_t*, listTSN);
+ tlist = g_list_first(tsn->tsns);
+ guint16 length;
+ while (tlist)
+ {
+ type = gxx_list_data(struct chunk_header *, tlist)->type;
+ if (type == SCTP_DATA_CHUNK_ID || type == SCTP_I_DATA_CHUNK_ID) {
+ length = g_ntohs(gxx_list_data(struct data_chunk_header *, tlist)->length);
+ if (type == SCTP_DATA_CHUNK_ID)
+ length -= DATA_CHUNK_HEADER_LENGTH;
+ else
+ length -= I_DATA_CHUNK_HEADER_LENGTH;
+ sumBytes += length;
+ yb.append(sumBytes);
+ xb.append(tsn->secs + tsn->usecs/1000000.0);
+ fb.append(tsn->frame_number);
+ }
+ tlist = gxx_list_next(tlist);
+ }
+ listTSN = gxx_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(tr("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(tr("time [secs]"));
+ ui->sctpPlot->yAxis->setLabel(tr("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()
+{
+ const sctp_assoc_info_t* selected_assoc = SCTPAssocAnalyseDialog::findAssoc(this, selected_assoc_id);
+ if (!selected_assoc) return;
+
+ ui->sctpPlot->clearGraphs();
+ drawBytesGraph(selected_assoc);
+ ui->sctpPlot->setInteractions(QCP::iRangeZoom | QCP::iRangeDrag | QCP::iSelectPlottables);
+ connect(ui->sctpPlot, &QCustomPlot::plottableClick, this, &SCTPGraphByteDialog::graphClicked);
+ ui->sctpPlot->replot();
+}
+
+
+void SCTPGraphByteDialog::on_pushButton_4_clicked()
+{
+ const sctp_assoc_info_t* selected_assoc = SCTPAssocAnalyseDialog::findAssoc(this, selected_assoc_id);
+ if (!selected_assoc) return;
+
+ 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, int, QMouseEvent* event)
+{
+ if (plottable->name().contains(tr("Bytes"), Qt::CaseInsensitive)) {
+ double bytes = 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(tr("<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);
+}