diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 20:34:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 20:34:10 +0000 |
commit | e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc (patch) | |
tree | 68cb5ef9081156392f1dd62a00c6ccc1451b93df /ui/qt/lbm_stream_dialog.cpp | |
parent | Initial commit. (diff) | |
download | wireshark-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/lbm_stream_dialog.cpp')
-rw-r--r-- | ui/qt/lbm_stream_dialog.cpp | 420 |
1 files changed, 420 insertions, 0 deletions
diff --git a/ui/qt/lbm_stream_dialog.cpp b/ui/qt/lbm_stream_dialog.cpp new file mode 100644 index 00000000..65ddcc47 --- /dev/null +++ b/ui/qt/lbm_stream_dialog.cpp @@ -0,0 +1,420 @@ +/* lbm_stream_dialog.cpp + * + * Copyright (c) 2005-2014 Informatica Corporation. All Rights Reserved. + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +// Adapted from stats_tree_packet.cpp + +#include "lbm_stream_dialog.h" +#include <ui_lbm_stream_dialog.h> + +#include "file.h" + +#include <ui/qt/utils/qt_ui_utils.h> +#include "main_application.h" + +#include <QClipboard> +#include <QMessageBox> +#include <QTreeWidget> +#include <QTreeWidgetItemIterator> +#include <epan/packet_info.h> +#include <epan/to_str.h> +#include <epan/tap.h> +#include <epan/dissectors/packet-lbm.h> + +#include <QDebug> + +namespace +{ + static const int Stream_Column = 0; + static const int EndpointA_Column = 1; + static const int EndpointB_Column = 2; + static const int Messages_Column = 3; + static const int Bytes_Column = 4; + static const int FirstFrame_Column = 5; + static const int LastFrame_Column = 6; +} + +class LBMSubstreamEntry +{ + public: + LBMSubstreamEntry(guint64 channel, guint32 substream_id, const address * source_address, guint16 source_port, const address * destination_address, guint16 destination_port); + ~LBMSubstreamEntry(void); + void processPacket(guint32 frame, guint32 bytes); + void setItem(QTreeWidgetItem * item); + QTreeWidgetItem * getItem(void) + { + return (m_item); + } + + private: + void fillItem(gboolean update_only = TRUE); + guint64 m_channel; + guint32 m_substream_id; + QString m_endpoint_a; + QString m_endpoint_b; + guint32 m_first_frame; + guint32 m_flast_frame; + guint32 m_messages; + guint32 m_bytes; + QTreeWidgetItem * m_item; +}; + +LBMSubstreamEntry::LBMSubstreamEntry(guint64 channel, guint32 substream_id, const address * source_address, guint16 source_port, const address * destination_address, guint16 destination_port) : + m_channel(channel), + m_substream_id(substream_id), + m_first_frame((guint32)(~0)), + m_flast_frame(0), + m_messages(0), + m_bytes(0), + m_item(NULL) +{ + m_endpoint_a = QString("%1:%2") + .arg(address_to_qstring(source_address)) + .arg(source_port); + m_endpoint_b = QString("%1:%2") + .arg(address_to_qstring(destination_address)) + .arg(destination_port); +} + +LBMSubstreamEntry::~LBMSubstreamEntry(void) +{ +} + +void LBMSubstreamEntry::processPacket(guint32 frame, guint32 bytes) +{ + if (m_first_frame > frame) + { + m_first_frame = frame; + } + if (m_flast_frame < frame) + { + m_flast_frame = frame; + } + m_bytes += bytes; + m_messages++; + fillItem(); +} + +void LBMSubstreamEntry::setItem(QTreeWidgetItem * item) +{ + m_item = item; + fillItem(FALSE); +} + +void LBMSubstreamEntry::fillItem(gboolean update_only) +{ + if (update_only == FALSE) + { + m_item->setText(Stream_Column, QString("%1.%2").arg(m_channel).arg(m_substream_id)); + m_item->setText(EndpointA_Column, m_endpoint_a); + m_item->setText(EndpointB_Column, m_endpoint_b); + } + m_item->setText(Messages_Column, QString("%1").arg(m_messages)); + m_item->setText(Bytes_Column, QString("%1").arg(m_bytes)); + m_item->setText(FirstFrame_Column, QString("%1").arg(m_first_frame)); + m_item->setText(LastFrame_Column, QString("%1").arg(m_flast_frame)); +} + +typedef QMap<guint32, LBMSubstreamEntry *> LBMSubstreamMap; +typedef QMap<guint32, LBMSubstreamEntry *>::iterator LBMSubstreamMapIterator; + +class LBMStreamEntry +{ + public: + LBMStreamEntry(const packet_info * pinfo, guint64 channel, const lbm_uim_stream_endpoint_t * endpoint_a, const lbm_uim_stream_endpoint_t * endpoint_b); + ~LBMStreamEntry(void); + void processPacket(const packet_info * pinfo, const lbm_uim_stream_tap_info_t * stream_info); + void setItem(QTreeWidgetItem * item); + QTreeWidgetItem * getItem(void) + { + return (m_item); + } + + private: + void fillItem(gboolean update_only = TRUE); + QString formatEndpoint(const packet_info * pinfo, const lbm_uim_stream_endpoint_t * endpoint); + guint64 m_channel; + QString m_endpoint_a; + QString m_endpoint_b; + guint32 m_first_frame; + guint32 m_flast_frame; + guint32 m_messages; + guint32 m_bytes; + QTreeWidgetItem * m_item; + LBMSubstreamMap m_substreams; +}; + +LBMStreamEntry::LBMStreamEntry(const packet_info * pinfo, guint64 channel, const lbm_uim_stream_endpoint_t * endpoint_a, const lbm_uim_stream_endpoint_t * endpoint_b) : + m_channel(channel), + m_first_frame((guint32)(~0)), + m_flast_frame(0), + m_messages(0), + m_bytes(0), + m_item(NULL), + m_substreams() +{ + m_endpoint_a = formatEndpoint(pinfo, endpoint_a); + m_endpoint_b = formatEndpoint(pinfo, endpoint_b); +} + +LBMStreamEntry::~LBMStreamEntry(void) +{ + LBMSubstreamMapIterator it; + + for (it = m_substreams.begin(); it != m_substreams.end(); ++it) + { + delete *it; + } + m_substreams.clear(); +} + +QString LBMStreamEntry::formatEndpoint(const packet_info * pinfo, const lbm_uim_stream_endpoint_t * endpoint) +{ + if (endpoint->type == lbm_uim_instance_stream) + { + return QString(bytes_to_str(pinfo->pool, endpoint->stream_info.ctxinst.ctxinst, sizeof(endpoint->stream_info.ctxinst.ctxinst))); + } + else + { + return QString("%1:%2:%3") + .arg(endpoint->stream_info.dest.domain) + .arg(address_to_str(pinfo->pool, &(endpoint->stream_info.dest.addr))) + .arg(endpoint->stream_info.dest.port); + } +} + +void LBMStreamEntry::processPacket(const packet_info * pinfo, const lbm_uim_stream_tap_info_t * stream_info) +{ + LBMSubstreamEntry * substream = NULL; + LBMSubstreamMapIterator it; + + if (m_first_frame > pinfo->num) + { + m_first_frame = pinfo->num; + } + if (m_flast_frame < pinfo->num) + { + m_flast_frame = pinfo->num; + } + m_bytes += stream_info->bytes; + m_messages++; + it = m_substreams.find(stream_info->substream_id); + if (m_substreams.end() == it) + { + QTreeWidgetItem * item = NULL; + + substream = new LBMSubstreamEntry(m_channel, stream_info->substream_id, &(pinfo->src), pinfo->srcport, &(pinfo->dst), pinfo->destport); + m_substreams.insert(stream_info->substream_id, substream); + item = new QTreeWidgetItem(); + substream->setItem(item); + m_item->addChild(item); + m_item->sortChildren(Stream_Column, Qt::AscendingOrder); + } + else + { + substream = it.value(); + } + fillItem(); + substream->processPacket(pinfo->num, stream_info->bytes); +} + +void LBMStreamEntry::setItem(QTreeWidgetItem * item) +{ + m_item = item; + fillItem(FALSE); +} + +void LBMStreamEntry::fillItem(gboolean update_only) +{ + if (update_only == FALSE) + { + m_item->setData(Stream_Column, Qt::DisplayRole, QVariant((qulonglong)m_channel)); + m_item->setText(EndpointA_Column, m_endpoint_a); + m_item->setText(EndpointB_Column, m_endpoint_b); + } + m_item->setText(Messages_Column, QString("%1").arg(m_messages)); + m_item->setText(Bytes_Column, QString("%1").arg(m_bytes)); + m_item->setText(FirstFrame_Column, QString("%1").arg(m_first_frame)); + m_item->setText(LastFrame_Column, QString("%1").arg(m_flast_frame)); +} + +typedef QMap<guint64, LBMStreamEntry *> LBMStreamMap; +typedef QMap<guint64, LBMStreamEntry *>::iterator LBMStreamMapIterator; + +class LBMStreamDialogInfo +{ + public: + LBMStreamDialogInfo(void); + ~LBMStreamDialogInfo(void); + void setDialog(LBMStreamDialog * dialog); + LBMStreamDialog * getDialog(void); + void processPacket(const packet_info * pinfo, const lbm_uim_stream_tap_info_t * stream_info); + void resetStreams(void); + + private: + LBMStreamDialog * m_dialog; + LBMStreamMap m_streams; +}; + +LBMStreamDialogInfo::LBMStreamDialogInfo(void) : + m_dialog(NULL), + m_streams() +{ +} + +LBMStreamDialogInfo::~LBMStreamDialogInfo(void) +{ + resetStreams(); +} + +void LBMStreamDialogInfo::setDialog(LBMStreamDialog * dialog) +{ + m_dialog = dialog; +} + +LBMStreamDialog * LBMStreamDialogInfo::getDialog(void) +{ + return (m_dialog); +} + +void LBMStreamDialogInfo::processPacket(const packet_info * pinfo, const lbm_uim_stream_tap_info_t * stream_info) +{ + LBMStreamEntry * stream = NULL; + LBMStreamMapIterator it; + + it = m_streams.find(stream_info->channel); + if (m_streams.end() == it) + { + QTreeWidgetItem * item = NULL; + QTreeWidgetItem * parent = NULL; + Ui::LBMStreamDialog * ui = NULL; + + stream = new LBMStreamEntry(pinfo, stream_info->channel, &(stream_info->endpoint_a), &(stream_info->endpoint_b)); + it = m_streams.insert(stream_info->channel, stream); + item = new QTreeWidgetItem(); + stream->setItem(item); + ui = m_dialog->getUI(); + ui->lbm_stream_TreeWidget->addTopLevelItem(item); + parent = ui->lbm_stream_TreeWidget->invisibleRootItem(); + parent->sortChildren(Stream_Column, Qt::AscendingOrder); + } + else + { + stream = it.value(); + } + stream->processPacket(pinfo, stream_info); +} + +void LBMStreamDialogInfo::resetStreams(void) +{ + LBMStreamMapIterator it = m_streams.begin(); + + while (it != m_streams.end()) + { + delete *it; + ++it; + } + m_streams.clear(); +} + +LBMStreamDialog::LBMStreamDialog(QWidget * parent, capture_file * cfile) : + QDialog(parent), + m_ui(new Ui::LBMStreamDialog), + m_dialog_info(NULL), + m_capture_file(cfile) +{ + m_ui->setupUi(this); + m_dialog_info = new LBMStreamDialogInfo(); + setAttribute(Qt::WA_DeleteOnClose, true); + fillTree(); +} + +LBMStreamDialog::~LBMStreamDialog(void) +{ + delete m_ui; + if (m_dialog_info != NULL) + { + delete m_dialog_info; + } +} + +void LBMStreamDialog::setCaptureFile(capture_file * cfile) +{ + if (cfile == NULL) // We only want to know when the file closes. + { + m_capture_file = NULL; + m_ui->displayFilterLineEdit->setEnabled(false); + m_ui->applyFilterButton->setEnabled(false); + } +} + +void LBMStreamDialog::fillTree(void) +{ + GString * error_string; + + if (m_capture_file == NULL) + { + return; + } + m_dialog_info->setDialog(this); + + error_string = register_tap_listener("lbm_stream", + (void *)m_dialog_info, + m_ui->displayFilterLineEdit->text().toUtf8().constData(), + TL_REQUIRES_COLUMNS, + resetTap, + tapPacket, + drawTreeItems, + NULL); + if (error_string) + { + QMessageBox::critical(this, tr("LBM Stream failed to attach to tap"), + error_string->str); + g_string_free(error_string, TRUE); + reject(); + } + + cf_retap_packets(m_capture_file); + drawTreeItems(&m_dialog_info); + remove_tap_listener((void *)m_dialog_info); +} + +void LBMStreamDialog::resetTap(void * tap_data) +{ + LBMStreamDialogInfo * info = (LBMStreamDialogInfo *)tap_data; + LBMStreamDialog * dialog = info->getDialog(); + if (dialog == NULL) + { + return; + } + info->resetStreams(); + dialog->m_ui->lbm_stream_TreeWidget->clear(); +} + +tap_packet_status LBMStreamDialog::tapPacket(void * tap_data, packet_info * pinfo, epan_dissect_t *, const void * stream_info, tap_flags_t) +{ + if (pinfo->fd->passed_dfilter == 1) + { + const lbm_uim_stream_tap_info_t * tapinfo = (const lbm_uim_stream_tap_info_t *)stream_info; + LBMStreamDialogInfo * info = (LBMStreamDialogInfo *)tap_data; + + info->processPacket(pinfo, tapinfo); + } + return (TAP_PACKET_REDRAW); +} + +void LBMStreamDialog::drawTreeItems(void *) +{ +} + +void LBMStreamDialog::on_applyFilterButton_clicked(void) +{ + fillTree(); +} |