1 /* lbm_stream_dialog.cpp
3 * Copyright (c) 2005-2014 Informatica Corporation. All Rights Reserved.
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
12 // Adapted from stats_tree_packet.cpp
14 #include "lbm_stream_dialog.h"
15 #include <ui_lbm_stream_dialog.h>
19 #include <ui/qt/utils/qt_ui_utils.h>
20 #include "main_application.h"
23 #include <QMessageBox>
24 #include <QTreeWidget>
25 #include <QTreeWidgetItemIterator>
26 #include <epan/packet_info.h>
27 #include <epan/to_str.h>
29 #include <epan/dissectors/packet-lbm.h>
35 static const int Stream_Column
= 0;
36 static const int EndpointA_Column
= 1;
37 static const int EndpointB_Column
= 2;
38 static const int Messages_Column
= 3;
39 static const int Bytes_Column
= 4;
40 static const int FirstFrame_Column
= 5;
41 static const int LastFrame_Column
= 6;
44 class LBMSubstreamEntry
47 LBMSubstreamEntry(uint64_t channel
, uint32_t substream_id
, const address
* source_address
, uint16_t source_port
, const address
* destination_address
, uint16_t destination_port
);
48 ~LBMSubstreamEntry(void);
49 void processPacket(uint32_t frame
, uint32_t bytes
);
50 void setItem(QTreeWidgetItem
* item
);
51 QTreeWidgetItem
* getItem(void)
57 void fillItem(bool update_only
= true);
59 uint32_t m_substream_id
;
62 uint32_t m_first_frame
;
63 uint32_t m_flast_frame
;
66 QTreeWidgetItem
* m_item
;
69 LBMSubstreamEntry::LBMSubstreamEntry(uint64_t channel
, uint32_t substream_id
, const address
* source_address
, uint16_t source_port
, const address
* destination_address
, uint16_t destination_port
) :
71 m_substream_id(substream_id
),
72 m_first_frame((uint32_t)(~0)),
78 m_endpoint_a
= QStringLiteral("%1:%2")
79 .arg(address_to_qstring(source_address
))
81 m_endpoint_b
= QStringLiteral("%1:%2")
82 .arg(address_to_qstring(destination_address
))
83 .arg(destination_port
);
86 LBMSubstreamEntry::~LBMSubstreamEntry(void)
90 void LBMSubstreamEntry::processPacket(uint32_t frame
, uint32_t bytes
)
92 if (m_first_frame
> frame
)
94 m_first_frame
= frame
;
96 if (m_flast_frame
< frame
)
98 m_flast_frame
= frame
;
105 void LBMSubstreamEntry::setItem(QTreeWidgetItem
* item
)
111 void LBMSubstreamEntry::fillItem(bool update_only
)
113 if (update_only
== false)
115 m_item
->setText(Stream_Column
, QStringLiteral("%1.%2").arg(m_channel
).arg(m_substream_id
));
116 m_item
->setText(EndpointA_Column
, m_endpoint_a
);
117 m_item
->setText(EndpointB_Column
, m_endpoint_b
);
119 m_item
->setText(Messages_Column
, QStringLiteral("%1").arg(m_messages
));
120 m_item
->setText(Bytes_Column
, QStringLiteral("%1").arg(m_bytes
));
121 m_item
->setText(FirstFrame_Column
, QStringLiteral("%1").arg(m_first_frame
));
122 m_item
->setText(LastFrame_Column
, QStringLiteral("%1").arg(m_flast_frame
));
125 typedef QMap
<uint32_t, LBMSubstreamEntry
*> LBMSubstreamMap
;
126 typedef QMap
<uint32_t, LBMSubstreamEntry
*>::iterator LBMSubstreamMapIterator
;
131 LBMStreamEntry(const packet_info
* pinfo
, uint64_t channel
, const lbm_uim_stream_endpoint_t
* endpoint_a
, const lbm_uim_stream_endpoint_t
* endpoint_b
);
132 ~LBMStreamEntry(void);
133 void processPacket(const packet_info
* pinfo
, const lbm_uim_stream_tap_info_t
* stream_info
);
134 void setItem(QTreeWidgetItem
* item
);
135 QTreeWidgetItem
* getItem(void)
141 void fillItem(bool update_only
= true);
142 QString
formatEndpoint(const packet_info
* pinfo
, const lbm_uim_stream_endpoint_t
* endpoint
);
144 QString m_endpoint_a
;
145 QString m_endpoint_b
;
146 uint32_t m_first_frame
;
147 uint32_t m_flast_frame
;
150 QTreeWidgetItem
* m_item
;
151 LBMSubstreamMap m_substreams
;
154 LBMStreamEntry::LBMStreamEntry(const packet_info
* pinfo
, uint64_t channel
, const lbm_uim_stream_endpoint_t
* endpoint_a
, const lbm_uim_stream_endpoint_t
* endpoint_b
) :
156 m_first_frame((uint32_t)(~0)),
163 m_endpoint_a
= formatEndpoint(pinfo
, endpoint_a
);
164 m_endpoint_b
= formatEndpoint(pinfo
, endpoint_b
);
167 LBMStreamEntry::~LBMStreamEntry(void)
169 LBMSubstreamMapIterator it
;
171 for (it
= m_substreams
.begin(); it
!= m_substreams
.end(); ++it
)
175 m_substreams
.clear();
178 QString
LBMStreamEntry::formatEndpoint(const packet_info
* pinfo
, const lbm_uim_stream_endpoint_t
* endpoint
)
180 if (endpoint
->type
== lbm_uim_instance_stream
)
182 return QString(bytes_to_str(pinfo
->pool
, endpoint
->stream_info
.ctxinst
.ctxinst
, sizeof(endpoint
->stream_info
.ctxinst
.ctxinst
)));
186 return QStringLiteral("%1:%2:%3")
187 .arg(endpoint
->stream_info
.dest
.domain
)
188 .arg(address_to_str(pinfo
->pool
, &(endpoint
->stream_info
.dest
.addr
)))
189 .arg(endpoint
->stream_info
.dest
.port
);
193 void LBMStreamEntry::processPacket(const packet_info
* pinfo
, const lbm_uim_stream_tap_info_t
* stream_info
)
195 LBMSubstreamEntry
* substream
= NULL
;
196 LBMSubstreamMapIterator it
;
198 if (m_first_frame
> pinfo
->num
)
200 m_first_frame
= pinfo
->num
;
202 if (m_flast_frame
< pinfo
->num
)
204 m_flast_frame
= pinfo
->num
;
206 m_bytes
+= stream_info
->bytes
;
208 it
= m_substreams
.find(stream_info
->substream_id
);
209 if (m_substreams
.end() == it
)
211 QTreeWidgetItem
* item
= NULL
;
213 substream
= new LBMSubstreamEntry(m_channel
, stream_info
->substream_id
, &(pinfo
->src
), pinfo
->srcport
, &(pinfo
->dst
), pinfo
->destport
);
214 m_substreams
.insert(stream_info
->substream_id
, substream
);
215 item
= new QTreeWidgetItem();
216 substream
->setItem(item
);
217 m_item
->addChild(item
);
218 m_item
->sortChildren(Stream_Column
, Qt::AscendingOrder
);
222 substream
= it
.value();
225 substream
->processPacket(pinfo
->num
, stream_info
->bytes
);
228 void LBMStreamEntry::setItem(QTreeWidgetItem
* item
)
234 void LBMStreamEntry::fillItem(bool update_only
)
236 if (update_only
== false)
238 m_item
->setData(Stream_Column
, Qt::DisplayRole
, QVariant((qulonglong
)m_channel
));
239 m_item
->setText(EndpointA_Column
, m_endpoint_a
);
240 m_item
->setText(EndpointB_Column
, m_endpoint_b
);
242 m_item
->setText(Messages_Column
, QStringLiteral("%1").arg(m_messages
));
243 m_item
->setText(Bytes_Column
, QStringLiteral("%1").arg(m_bytes
));
244 m_item
->setText(FirstFrame_Column
, QStringLiteral("%1").arg(m_first_frame
));
245 m_item
->setText(LastFrame_Column
, QStringLiteral("%1").arg(m_flast_frame
));
248 typedef QMap
<uint64_t, LBMStreamEntry
*> LBMStreamMap
;
249 typedef QMap
<uint64_t, LBMStreamEntry
*>::iterator LBMStreamMapIterator
;
251 class LBMStreamDialogInfo
254 LBMStreamDialogInfo(void);
255 ~LBMStreamDialogInfo(void);
256 void setDialog(LBMStreamDialog
* dialog
);
257 LBMStreamDialog
* getDialog(void);
258 void processPacket(const packet_info
* pinfo
, const lbm_uim_stream_tap_info_t
* stream_info
);
259 void resetStreams(void);
262 LBMStreamDialog
* m_dialog
;
263 LBMStreamMap m_streams
;
266 LBMStreamDialogInfo::LBMStreamDialogInfo(void) :
272 LBMStreamDialogInfo::~LBMStreamDialogInfo(void)
277 void LBMStreamDialogInfo::setDialog(LBMStreamDialog
* dialog
)
282 LBMStreamDialog
* LBMStreamDialogInfo::getDialog(void)
287 void LBMStreamDialogInfo::processPacket(const packet_info
* pinfo
, const lbm_uim_stream_tap_info_t
* stream_info
)
289 LBMStreamEntry
* stream
= NULL
;
290 LBMStreamMapIterator it
;
292 it
= m_streams
.find(stream_info
->channel
);
293 if (m_streams
.end() == it
)
295 QTreeWidgetItem
* item
= NULL
;
296 QTreeWidgetItem
* parent
= NULL
;
297 Ui::LBMStreamDialog
* ui
= NULL
;
299 stream
= new LBMStreamEntry(pinfo
, stream_info
->channel
, &(stream_info
->endpoint_a
), &(stream_info
->endpoint_b
));
300 it
= m_streams
.insert(stream_info
->channel
, stream
);
301 item
= new QTreeWidgetItem();
302 stream
->setItem(item
);
303 ui
= m_dialog
->getUI();
304 ui
->lbm_stream_TreeWidget
->addTopLevelItem(item
);
305 parent
= ui
->lbm_stream_TreeWidget
->invisibleRootItem();
306 parent
->sortChildren(Stream_Column
, Qt::AscendingOrder
);
312 stream
->processPacket(pinfo
, stream_info
);
315 void LBMStreamDialogInfo::resetStreams(void)
317 LBMStreamMapIterator it
= m_streams
.begin();
319 while (it
!= m_streams
.end())
327 LBMStreamDialog::LBMStreamDialog(QWidget
* parent
, capture_file
* cfile
) :
329 m_ui(new Ui::LBMStreamDialog
),
331 m_capture_file(cfile
)
334 m_dialog_info
= new LBMStreamDialogInfo();
335 setAttribute(Qt::WA_DeleteOnClose
, true);
339 LBMStreamDialog::~LBMStreamDialog(void)
342 if (m_dialog_info
!= NULL
)
344 delete m_dialog_info
;
348 void LBMStreamDialog::setCaptureFile(capture_file
* cfile
)
350 if (cfile
== NULL
) // We only want to know when the file closes.
352 m_capture_file
= NULL
;
353 m_ui
->displayFilterLineEdit
->setEnabled(false);
354 m_ui
->applyFilterButton
->setEnabled(false);
358 void LBMStreamDialog::fillTree(void)
360 GString
* error_string
;
362 if (m_capture_file
== NULL
)
366 m_dialog_info
->setDialog(this);
368 error_string
= register_tap_listener("lbm_stream",
369 (void *)m_dialog_info
,
370 m_ui
->displayFilterLineEdit
->text().toUtf8().constData(),
378 QMessageBox::critical(this, tr("LBM Stream failed to attach to tap"),
380 g_string_free(error_string
, TRUE
);
384 cf_retap_packets(m_capture_file
);
385 drawTreeItems(&m_dialog_info
);
386 remove_tap_listener((void *)m_dialog_info
);
389 void LBMStreamDialog::resetTap(void * tap_data
)
391 LBMStreamDialogInfo
* info
= (LBMStreamDialogInfo
*)tap_data
;
392 LBMStreamDialog
* dialog
= info
->getDialog();
397 info
->resetStreams();
398 dialog
->m_ui
->lbm_stream_TreeWidget
->clear();
401 tap_packet_status
LBMStreamDialog::tapPacket(void * tap_data
, packet_info
* pinfo
, epan_dissect_t
*, const void * stream_info
, tap_flags_t
)
403 if (pinfo
->fd
->passed_dfilter
== 1)
405 const lbm_uim_stream_tap_info_t
* tapinfo
= (const lbm_uim_stream_tap_info_t
*)stream_info
;
406 LBMStreamDialogInfo
* info
= (LBMStreamDialogInfo
*)tap_data
;
408 info
->processPacket(pinfo
, tapinfo
);
410 return (TAP_PACKET_REDRAW
);
413 void LBMStreamDialog::drawTreeItems(void *)
417 void LBMStreamDialog::on_applyFilterButton_clicked(void)