summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt5
-rw-r--r--mainwindow.cpp190
-rw-r--r--mainwindow.h9
-rw-r--r--mainwindow.ui93
-rw-r--r--packetstablewidget.cpp146
-rw-r--r--packetstablewidget.h47
-rw-r--r--pcapplusplus.cpp9
-rw-r--r--pcapplusplus.h4
8 files changed, 317 insertions, 186 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5e47b74..aab7a9f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -69,6 +69,9 @@ set(PROJECT_SOURCES
pcapplusplus.cpp
pcapplusplus.h
+ packetstablewidget.cpp
+ packetstablewidget.h
+
qhexedit2/src/chunks.cpp
qhexedit2/src/chunks.h
qhexedit2/src/commands.cpp
@@ -97,7 +100,7 @@ endif()
add_dependencies(pcap-editor PcapPlusPlus)
-target_include_directories(pcap-editor PRIVATE ${CMAKE_BINARY_DIR}/ppp-install/include/pcapplusplus)
+target_include_directories(pcap-editor PRIVATE ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR}/ppp-install/include/pcapplusplus)
target_link_libraries(pcap-editor PRIVATE Qt${QT_VERSION_MAJOR}::Widgets
${CMAKE_BINARY_DIR}/ppp-install/lib/libPcap++.a
${CMAKE_BINARY_DIR}/ppp-install/lib/libPacket++.a
diff --git a/mainwindow.cpp b/mainwindow.cpp
index 7391403..9b6534d 100644
--- a/mainwindow.cpp
+++ b/mainwindow.cpp
@@ -1,10 +1,10 @@
-#include "mainwindow.h"
-#include "ui_mainwindow.h"
-
#include <exception>
#include <qfiledialog.h>
#include <QMouseEvent>
+#include "mainwindow.h"
+#include "ui_mainwindow.h"
+
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, tableContextMenu()
@@ -42,25 +42,6 @@ MainWindow::MainWindow(QWidget *parent)
enableMenuButtons(this, false);
enableHexEditButtons(this, false);
- const auto& isEthernetSrcColumn = [this](const int& column) {
- return column == 6;
- };
- const auto& isEthernetDstColumn = [this](const int& column) {
- return column == 7;
- };
- const auto& isIpSrcColumn = [this](const int& column) {
- return column == 8;
- };
- const auto& isIpDstColumn = [this](const int& column) {
- return column == 9;
- };
- const auto& isPortSrcColumn = [this](const int& column) {
- return column == 10;
- };
- const auto& isPortDstColumn = [this](const int& column) {
- return column == 11;
- };
-
tableContextMenu.randomize.setText("Randomize");
tableContextMenu.menu.addAction(&tableContextMenu.randomize);
@@ -74,55 +55,31 @@ MainWindow::MainWindow(QWidget *parent)
myHexEdit.contextMenu.addAction(&myHexEdit.deleteBytes);
myHexEdit.contextMenu.addAction(&myHexEdit.deleteSelection);
- connect(&tableContextMenu.randomize, &QAction::triggered, this, [this, isEthernetSrcColumn, isEthernetDstColumn, isIpSrcColumn, isIpDstColumn, isPortSrcColumn, isPortDstColumn](bool checked __attribute__((unused))){
- if (!ppp)
- throw std::runtime_error("Can not randomize, no packets available");
+ connect(&tableContextMenu.randomize, &QAction::triggered, this, [this](bool checked __attribute__((unused))){
+ ui->tableWidget->randomizeLayerItem(ppp);
- const auto & y = ui->tableWidget->currentRow();
- const auto & col = ui->tableWidget->currentColumn() + 1;
-
- if (isEthernetSrcColumn(col) || isEthernetDstColumn(col)) {
- ppp->randomizeEth(y, isEthernetSrcColumn(col));
- } else if (isIpSrcColumn(col) || isIpDstColumn(col)) {
- ppp->randomizeIp(y, isIpSrcColumn(col));
- } else if (isPortSrcColumn(col) || isPortDstColumn(col)) {
- ppp->randomizePort(y, isPortSrcColumn(col));
- } else throw std::runtime_error("BUG: No supported column selected");
-
- if (!MainWindow::updateTableRow(y))
- throw std::runtime_error("BUG: Could not update table row");
+ const auto &rawPacket = ppp->getRawPacket(ui->tableWidget->currentRow());
+ myHexEdit.editor.setData(QByteArray::fromRawData(reinterpret_cast<const char *>(rawPacket.getRawData()), rawPacket.getRawDataLen()));
});
- connect(ui->tableWidget, &QTableWidget::itemChanged, this, [this, isEthernetSrcColumn, isEthernetDstColumn, isIpSrcColumn, isIpDstColumn, isPortSrcColumn, isPortDstColumn](QTableWidgetItem *item) {
- if (!item || !ppp)
- return;
+ connect(ui->tableWidget, &QTableWidget::itemChanged, this, [this](QTableWidgetItem *item) {
+ ui->tableWidget->setLayerItem(item, ppp, isProcessing);
- const auto & y = ui->tableWidget->currentRow();
- const auto & col = ui->tableWidget->currentColumn() + 1;
- const auto & text = item->text().toStdString();
-
- if (isEthernetSrcColumn(col) || isEthernetDstColumn(col)) {
- ppp->setEth(y, text, isEthernetSrcColumn(col));
- } else if (isIpSrcColumn(col) || isIpDstColumn(col)) {
- ppp->setIp(y, text, isIpSrcColumn(col));
- } else if (isPortSrcColumn(col) || isPortDstColumn(col)) {
- ppp->setPort(y, text, isPortSrcColumn(col));
+ if (!isProcessing) {
+ const auto &rawPacket = ppp->getRawPacket(item->row());
+ myHexEdit.editor.setData(QByteArray::fromRawData(reinterpret_cast<const char *>(rawPacket.getRawData()), rawPacket.getRawDataLen()));
}
-
- if (isProcessing)
- return;
- if (!MainWindow::updateTableRow(y))
- throw std::runtime_error("BUG: Could not update table row");
});
- connect(ui->tableWidget, &QTableWidget::customContextMenuRequested, this, [this, enableTableButtons, isEthernetSrcColumn, isEthernetDstColumn, isIpSrcColumn, isIpDstColumn, isPortSrcColumn, isPortDstColumn](const QPoint& pos){
+ connect(ui->tableWidget, &QTableWidget::customContextMenuRequested, this, [this, enableTableButtons](const QPoint& pos){
const auto & globalPos = ui->tableWidget->viewport()->mapToGlobal(pos);
const auto & col = ui->tableWidget->currentColumn() + 1;
+ const auto & table = ui->tableWidget;
if (ppp
- && (isEthernetSrcColumn(col) || isEthernetDstColumn(col)
- || isIpSrcColumn(col) || isIpDstColumn(col)
- || isPortSrcColumn(col) || isPortDstColumn(col)))
+ && (table->isEthernetSrcColumn(col) || table->isEthernetDstColumn(col)
+ || table->isIpSrcColumn(col) || table->isIpDstColumn(col)
+ || table->isPortSrcColumn(col) || table->isPortDstColumn(col)))
enableTableButtons(this, true);
else
enableTableButtons(this, false);
@@ -203,7 +160,7 @@ MainWindow::MainWindow(QWidget *parent)
if (fileName.length() > 0) {
ui->lineEdit->clear();
ui->tableWidget->clearSelection();
- ui->tableWidget->clear();
+ ui->tableWidget->clearContents();
ui->tableWidget->setRowCount(0);
myHexEdit.editor.data().data_ptr()->clear();
enableTableButtons(this, true);
@@ -231,7 +188,7 @@ MainWindow::MainWindow(QWidget *parent)
throw std::runtime_error("Reopen PCAP File to apply a BPF failed.");
if (!ppp->setFilter(ui->lineEdit->text()))
throw std::runtime_error("Could not re-apply a previously set filter.");
- ui->tableWidget->clear();
+ ui->tableWidget->clearContents();
ui->tableWidget->setRowCount(0);
emit processPcap();
}
@@ -285,14 +242,12 @@ MainWindow::MainWindow(QWidget *parent)
connect(this, &MainWindow::processPcap, this, [&](){
pcpp::Packet packet;
if (!ppp) throw std::runtime_error("PcapPlusPlus was not initialized.");
- firstPacketTs = 0;
isProcessing = true;
while (ppp->processPacket(packet)) {
- if (!firstPacketTs)
- firstPacketTs = packet.getRawPacket()->getPacketTimeStamp().tv_sec;
emit onPacketAvailable();
}
+ ui->tableWidget->clearSelection();
isProcessing = false;
pcpp::PcapFileReaderDevice::PcapStats stats;
@@ -304,17 +259,14 @@ MainWindow::MainWindow(QWidget *parent)
});
connect(this, &MainWindow::onPacketAvailable, this, [&]() {
- if (!addTableRow())
- throw std::runtime_error("Could not add row to table for packet");
+ emit ui->tableWidget->addRow(ppp);
});
- connect(ui->tableWidget, &QTableWidget::cellPressed, this, [&] {
- const auto &selected = ui->tableWidget->selectedItems();
- if (selected.empty())
- return;
-
- const auto &rawPacket = ppp->getRawPacket(selected.last()->row());
- myHexEdit.editor.setData(QByteArray::fromRawData(reinterpret_cast<const char *>(rawPacket.getRawData()), rawPacket.getRawDataLen()));
+ connect(ui->tableWidget, &QTableWidget::currentCellChanged, this, [&](int currentRow, int currentColumn, int previousRow, int previousColumn) {
+ if (!isProcessing && currentRow >= 0) {
+ const auto &rawPacket = ppp->getRawPacket(currentRow);
+ myHexEdit.editor.setData(QByteArray::fromRawData(reinterpret_cast<const char *>(rawPacket.getRawData()), rawPacket.getRawDataLen()));
+ }
});
connect(ui->tableWidget, &QTableWidget::itemSelectionChanged, this, [this, enableHexEditButtons]() {
@@ -363,96 +315,6 @@ pcpp::RawPacket* MainWindow::currentSelectedPacket()
return &ppp->getRawPacket(selected.last()->row());
}
-bool MainWindow::addTableRow()
-{
- QTableWidgetItem* itemRelativeTime = new QTableWidgetItem();
- QTableWidgetItem* itemFrameLength = new QTableWidgetItem();
- QTableWidgetItem* itemFirstLayerProtocol = new QTableWidgetItem();
- QTableWidgetItem* itemSecondLayerProtocol = new QTableWidgetItem();
- QTableWidgetItem* itemThirdLayerProtocol = new QTableWidgetItem();
- QTableWidgetItem* itemSrcMac = new QTableWidgetItem();
- QTableWidgetItem* itemDstMac = new QTableWidgetItem();
- QTableWidgetItem* itemSrcIp = new QTableWidgetItem();
- QTableWidgetItem* itemDstIp = new QTableWidgetItem();
- QTableWidgetItem* itemSrcPort = new QTableWidgetItem();
- QTableWidgetItem* itemDstPort = new QTableWidgetItem();
- QTableWidgetItem* itemDesc = new QTableWidgetItem();
-
- if (!itemRelativeTime || !itemFrameLength || !itemFirstLayerProtocol || !itemSecondLayerProtocol || !itemThirdLayerProtocol
- || !itemSrcMac || !itemDstMac || !itemSrcIp || !itemDstIp || !itemSrcPort || ! itemDstPort || !itemDesc)
- {
- delete itemRelativeTime;
- delete itemFrameLength;
- delete itemFirstLayerProtocol;
- delete itemSecondLayerProtocol;
- delete itemThirdLayerProtocol;
- delete itemSrcMac;
- delete itemDstMac;
- delete itemSrcIp;
- delete itemDstIp;
- delete itemSrcPort;
- delete itemDstPort;
- delete itemDesc;
-
- return false;
- }
-
- ui->tableWidget->insertRow(ui->tableWidget->rowCount());
- ui->tableWidget->setItem(ui->tableWidget->rowCount() - 1, 0, itemRelativeTime);
- ui->tableWidget->setItem(ui->tableWidget->rowCount() - 1, 1, itemFrameLength);
- ui->tableWidget->setItem(ui->tableWidget->rowCount() - 1, 2, itemFirstLayerProtocol);
- ui->tableWidget->setItem(ui->tableWidget->rowCount() - 1, 3, itemSecondLayerProtocol);
- ui->tableWidget->setItem(ui->tableWidget->rowCount() - 1, 4, itemThirdLayerProtocol);
- ui->tableWidget->setItem(ui->tableWidget->rowCount() - 1, 5, itemSrcMac);
- ui->tableWidget->setItem(ui->tableWidget->rowCount() - 1, 6, itemDstMac);
- ui->tableWidget->setItem(ui->tableWidget->rowCount() - 1, 7, itemSrcIp);
- ui->tableWidget->setItem(ui->tableWidget->rowCount() - 1, 8, itemDstIp);
- ui->tableWidget->setItem(ui->tableWidget->rowCount() - 1, 9, itemSrcPort);
- ui->tableWidget->setItem(ui->tableWidget->rowCount() - 1, 10, itemDstPort);
- ui->tableWidget->setItem(ui->tableWidget->rowCount() - 1, 11, itemDesc);
-
- ui->tableWidget->item(ui->tableWidget->rowCount() - 1, 0)->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemNeverHasChildren);
- ui->tableWidget->item(ui->tableWidget->rowCount() - 1, 1)->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemNeverHasChildren);
- ui->tableWidget->item(ui->tableWidget->rowCount() - 1, 2)->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemNeverHasChildren);
- ui->tableWidget->item(ui->tableWidget->rowCount() - 1, 3)->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemNeverHasChildren);
- ui->tableWidget->item(ui->tableWidget->rowCount() - 1, 4)->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemNeverHasChildren);
- ui->tableWidget->item(ui->tableWidget->rowCount() - 1, 11)->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemNeverHasChildren);
-
- return updateTableRow(ui->tableWidget->rowCount() - 1);
-}
-
-bool MainWindow::updateTableRow(size_t index)
-{
- if (!ppp)
- return false;
-
- auto parsedPacket = pcpp::Packet(&ppp->getRawPacket(index));
- const auto *firstLayer = PcapPlusPlus::getFirstLayer(parsedPacket);
- const auto *secondLayer = firstLayer ? firstLayer->getNextLayer() : nullptr;
- const auto *thirdLayer = secondLayer ? secondLayer->getNextLayer() : nullptr;
- const auto ethTuple = PcapPlusPlus::getEthTuple(parsedPacket);
- const auto ipTuple = PcapPlusPlus::getIpTuple(parsedPacket);
- const auto l4Tuple = PcapPlusPlus::getLayer4Tuple(parsedPacket);
-
- if (!firstLayer)
- return false;
-
- ui->tableWidget->item(index, 0)->setText(tr("%1").arg(parsedPacket.getRawPacket()->getPacketTimeStamp().tv_sec - firstPacketTs));
- ui->tableWidget->item(index, 1)->setText(tr("%1").arg(parsedPacket.getRawPacket()->getFrameLength()));
- ui->tableWidget->item(index, 2)->setText(tr("%1").arg(firstLayer ? PcapPlusPlus::getProtocolTypeAsString(firstLayer->getProtocol()) : ""));
- ui->tableWidget->item(index, 3)->setText(tr("%1").arg(secondLayer ? PcapPlusPlus::getProtocolTypeAsString(secondLayer->getProtocol()) : ""));
- ui->tableWidget->item(index, 4)->setText(tr("%1").arg(thirdLayer ? PcapPlusPlus::getProtocolTypeAsString(thirdLayer->getProtocol()) : ""));
- ui->tableWidget->item(index, 5)->setText(tr("%1").arg(std::get<0>(ethTuple)));
- ui->tableWidget->item(index, 6)->setText(tr("%1").arg(std::get<1>(ethTuple)));
- ui->tableWidget->item(index, 7)->setText(tr("%1").arg(std::get<0>(ipTuple)));
- ui->tableWidget->item(index, 8)->setText(tr("%1").arg(std::get<1>(ipTuple)));
- ui->tableWidget->item(index, 9)->setText(tr("%1").arg(std::get<0>(l4Tuple)));
- ui->tableWidget->item(index, 10)->setText(tr("%1").arg(std::get<1>(l4Tuple)));
- ui->tableWidget->item(index, 11)->setText(tr("%1").arg(QString::fromStdString(thirdLayer ? thirdLayer->toString() : (secondLayer ? secondLayer->toString() : (firstLayer ? firstLayer->toString() : "")))));
-
- return true;
-}
-
bool MainWindow::eventFilter(QObject *obj __attribute__((unused)), QEvent *event)
{
if (event->type() == QEvent::MouseMove)
diff --git a/mainwindow.h b/mainwindow.h
index a7d3a37..88b78c9 100644
--- a/mainwindow.h
+++ b/mainwindow.h
@@ -1,15 +1,15 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
-#include "bytewindow.h"
-#include "pcapplusplus.h"
-#include "qhexedit2/src/qhexedit.h"
-
#include <atomic>
#include <optional>
#include <QMainWindow>
#include <QMenu>
+#include "bytewindow.h"
+#include "pcapplusplus.h"
+#include "qhexedit2/src/qhexedit.h"
+
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
@@ -49,7 +49,6 @@ private:
int y;
} mouse;
- time_t firstPacketTs = 0;
Ui::MainWindow *ui = nullptr;
QString statusbarMessage;
PcapPlusPlus *ppp = nullptr;
diff --git a/mainwindow.ui b/mainwindow.ui
index fc0c8a6..70451e5 100644
--- a/mainwindow.ui
+++ b/mainwindow.ui
@@ -42,7 +42,7 @@
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0">
- <widget class="QTableWidget" name="tableWidget">
+ <widget class="PacketsTableWidget" name="tableWidget">
<property name="styleSheet">
<string notr="true">color: black;
background-color: white;
@@ -68,21 +68,81 @@ border-color: beige;</string>
<attribute name="horizontalHeaderCascadingSectionResizes">
<bool>false</bool>
</attribute>
+ <attribute name="horizontalHeaderMinimumSectionSize">
+ <number>120</number>
+ </attribute>
+ <attribute name="horizontalHeaderDefaultSectionSize">
+ <number>120</number>
+ </attribute>
+ <attribute name="horizontalHeaderHighlightSections">
+ <bool>false</bool>
+ </attribute>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
- <column/>
- <column/>
- <column/>
- <column/>
- <column/>
- <column/>
- <column/>
- <column/>
- <column/>
- <column/>
- <column/>
- <column/>
+ <attribute name="verticalHeaderVisible">
+ <bool>false</bool>
+ </attribute>
+ <column>
+ <property name="text">
+ <string>Timestamp</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Packet Size</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Layer 2</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Layer 3</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Layer 4</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Layer 2 Source</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Layer 2 Destination</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Layer 3 Source</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Layer 3 Destination</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Layer 4 Source</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Layer 4 Destination</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Additional Information</string>
+ </property>
+ </column>
</widget>
</item>
<item row="0" column="0">
@@ -128,6 +188,13 @@ border-color: beige;</string>
</property>
</action>
</widget>
+ <customwidgets>
+ <customwidget>
+ <class>PacketsTableWidget</class>
+ <extends>QTableWidget</extends>
+ <header>packetstablewidget.h</header>
+ </customwidget>
+ </customwidgets>
<resources/>
<connections/>
</ui>
diff --git a/packetstablewidget.cpp b/packetstablewidget.cpp
new file mode 100644
index 0000000..32a4a21
--- /dev/null
+++ b/packetstablewidget.cpp
@@ -0,0 +1,146 @@
+#include "packetstablewidget.h"
+
+PacketsTableWidget::PacketsTableWidget(QWidget *parent) : QTableWidget(parent)
+{
+ connect(this, &PacketsTableWidget::addRow, this, [&](PcapPlusPlus *ppp) {
+ if (!addTableRow(ppp))
+ throw std::runtime_error("Could not add row to table for packet");
+ });
+
+ connect(this, &PacketsTableWidget::updateRow, this, [&](size_t index, PcapPlusPlus *ppp) {
+ if (!updateTableRow(index, ppp))
+ throw std::runtime_error("Could not add row to table for packet");
+ });
+}
+
+void PacketsTableWidget::randomizeLayerItem(PcapPlusPlus *ppp)
+{
+ if (!ppp)
+ throw std::runtime_error("Can not randomize, no packets available");
+
+ const auto & y = currentRow();
+ const auto & col = currentColumn() + 1;
+
+ if (isEthernetSrcColumn(col) || isEthernetDstColumn(col)) {
+ ppp->randomizeEth(y, isEthernetSrcColumn(col));
+ } else if (isIpSrcColumn(col) || isIpDstColumn(col)) {
+ ppp->randomizeIp(y, isIpSrcColumn(col));
+ } else if (isPortSrcColumn(col) || isPortDstColumn(col)) {
+ ppp->randomizePort(y, isPortSrcColumn(col));
+ } else throw std::runtime_error("BUG: No supported column selected");
+
+ emit updateRow(y, ppp);
+}
+
+void PacketsTableWidget::setLayerItem(QTableWidgetItem *item, PcapPlusPlus *ppp, bool isProcessing)
+{
+ if (!item || !ppp)
+ return;
+
+ const auto & y = currentRow();
+ const auto & col = currentColumn() + 1;
+ const auto & text = item->text().toStdString();
+
+ if (isEthernetSrcColumn(col) || isEthernetDstColumn(col)) {
+ ppp->setEth(y, text, isEthernetSrcColumn(col));
+ } else if (isIpSrcColumn(col) || isIpDstColumn(col)) {
+ ppp->setIp(y, text, isIpSrcColumn(col));
+ } else if (isPortSrcColumn(col) || isPortDstColumn(col)) {
+ ppp->setPort(y, text, isPortSrcColumn(col));
+ }
+
+ if (isProcessing)
+ return;
+ emit updateRow(y, ppp);
+}
+
+bool PacketsTableWidget::addTableRow(PcapPlusPlus *ppp)
+{
+ QTableWidgetItem* itemRelativeTime = new QTableWidgetItem();
+ QTableWidgetItem* itemFrameLength = new QTableWidgetItem();
+ QTableWidgetItem* itemFirstLayerProtocol = new QTableWidgetItem();
+ QTableWidgetItem* itemSecondLayerProtocol = new QTableWidgetItem();
+ QTableWidgetItem* itemThirdLayerProtocol = new QTableWidgetItem();
+ QTableWidgetItem* itemSrcMac = new QTableWidgetItem();
+ QTableWidgetItem* itemDstMac = new QTableWidgetItem();
+ QTableWidgetItem* itemSrcIp = new QTableWidgetItem();
+ QTableWidgetItem* itemDstIp = new QTableWidgetItem();
+ QTableWidgetItem* itemSrcPort = new QTableWidgetItem();
+ QTableWidgetItem* itemDstPort = new QTableWidgetItem();
+ QTableWidgetItem* itemDesc = new QTableWidgetItem();
+
+ if (!itemRelativeTime || !itemFrameLength || !itemFirstLayerProtocol || !itemSecondLayerProtocol || !itemThirdLayerProtocol
+ || !itemSrcMac || !itemDstMac || !itemSrcIp || !itemDstIp || !itemSrcPort || ! itemDstPort || !itemDesc)
+ {
+ delete itemRelativeTime;
+ delete itemFrameLength;
+ delete itemFirstLayerProtocol;
+ delete itemSecondLayerProtocol;
+ delete itemThirdLayerProtocol;
+ delete itemSrcMac;
+ delete itemDstMac;
+ delete itemSrcIp;
+ delete itemDstIp;
+ delete itemSrcPort;
+ delete itemDstPort;
+ delete itemDesc;
+
+ return false;
+ }
+
+ insertRow(rowCount());
+ setItem(rowCount() - 1, 0, itemRelativeTime);
+ setItem(rowCount() - 1, 1, itemFrameLength);
+ setItem(rowCount() - 1, 2, itemFirstLayerProtocol);
+ setItem(rowCount() - 1, 3, itemSecondLayerProtocol);
+ setItem(rowCount() - 1, 4, itemThirdLayerProtocol);
+ setItem(rowCount() - 1, 5, itemSrcMac);
+ setItem(rowCount() - 1, 6, itemDstMac);
+ setItem(rowCount() - 1, 7, itemSrcIp);
+ setItem(rowCount() - 1, 8, itemDstIp);
+ setItem(rowCount() - 1, 9, itemSrcPort);
+ setItem(rowCount() - 1, 10, itemDstPort);
+ setItem(rowCount() - 1, 11, itemDesc);
+
+ item(rowCount() - 1, 0)->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemNeverHasChildren);
+ item(rowCount() - 1, 1)->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemNeverHasChildren);
+ item(rowCount() - 1, 2)->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemNeverHasChildren);
+ item(rowCount() - 1, 3)->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemNeverHasChildren);
+ item(rowCount() - 1, 4)->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemNeverHasChildren);
+ item(rowCount() - 1, 11)->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemNeverHasChildren);
+
+ emit updateRow(rowCount() - 1, ppp);
+ return true;
+}
+
+bool PacketsTableWidget::updateTableRow(size_t index, PcapPlusPlus *ppp)
+{
+ if (!ppp)
+ return false;
+
+ auto parsedPacket = pcpp::Packet(&ppp->getRawPacket(index));
+ const auto *firstLayer = PcapPlusPlus::getFirstLayer(parsedPacket);
+ const auto *secondLayer = firstLayer ? firstLayer->getNextLayer() : nullptr;
+ const auto *thirdLayer = secondLayer ? secondLayer->getNextLayer() : nullptr;
+ const auto ethTuple = PcapPlusPlus::getEthTuple(parsedPacket);
+ const auto ipTuple = PcapPlusPlus::getIpTuple(parsedPacket);
+ const auto l4Tuple = PcapPlusPlus::getLayer4Tuple(parsedPacket);
+
+ if (!firstLayer)
+ return false;
+
+ item(index, 0)->setText(tr("%1").arg(parsedPacket.getRawPacket()->getPacketTimeStamp().tv_sec - static_cast<unsigned long long int>(ppp->getFirstPacketTimestamp())));
+ item(index, 1)->setText(tr("%1").arg(parsedPacket.getRawPacket()->getFrameLength()));
+ item(index, 2)->setText(tr("%1").arg(firstLayer ? PcapPlusPlus::getProtocolTypeAsString(firstLayer->getProtocol()) : ""));
+ item(index, 3)->setText(tr("%1").arg(secondLayer ? PcapPlusPlus::getProtocolTypeAsString(secondLayer->getProtocol()) : ""));
+ item(index, 4)->setText(tr("%1").arg(thirdLayer ? PcapPlusPlus::getProtocolTypeAsString(thirdLayer->getProtocol()) : ""));
+ item(index, 5)->setText(tr("%1").arg(std::get<0>(ethTuple)));
+ item(index, 6)->setText(tr("%1").arg(std::get<1>(ethTuple)));
+ item(index, 7)->setText(tr("%1").arg(std::get<0>(ipTuple)));
+ item(index, 8)->setText(tr("%1").arg(std::get<1>(ipTuple)));
+ item(index, 9)->setText(tr("%1").arg(std::get<0>(l4Tuple)));
+ item(index, 10)->setText(tr("%1").arg(std::get<1>(l4Tuple)));
+ item(index, 11)->setText(tr("%1").arg(QString::fromStdString(thirdLayer ? thirdLayer->toString() : (secondLayer ? secondLayer->toString() : (firstLayer ? firstLayer->toString() : "")))));
+
+ return true;
+}
diff --git a/packetstablewidget.h b/packetstablewidget.h
new file mode 100644
index 0000000..0de46f9
--- /dev/null
+++ b/packetstablewidget.h
@@ -0,0 +1,47 @@
+#ifndef PACKETSTABLEWIDGET_H
+#define PACKETSTABLEWIDGET_H
+
+#include <QTableWidget>
+
+#include "pcapplusplus.h"
+
+class PacketsTableWidget : public QTableWidget
+{
+ Q_OBJECT
+
+public:
+ PacketsTableWidget(QWidget *parent = nullptr);
+
+ bool isEthernetSrcColumn(const int& column) {
+ return column == 6;
+ };
+ bool isEthernetDstColumn(const int& column) {
+ return column == 7;
+ };
+ bool isIpSrcColumn(const int& column) {
+ return column == 8;
+ };
+ bool isIpDstColumn(const int& column) {
+ return column == 9;
+ };
+ bool isPortSrcColumn(const int& column) {
+ return column == 10;
+ };
+ bool isPortDstColumn(const int& column) {
+ return column == 11;
+ };
+
+private:
+ bool addTableRow(PcapPlusPlus *ppp);
+ bool updateTableRow(size_t index, PcapPlusPlus *ppp);
+
+signals:
+ bool addRow(PcapPlusPlus *ppp);
+ bool updateRow(size_t index, PcapPlusPlus *ppp);
+
+public slots:
+ void randomizeLayerItem(PcapPlusPlus *ppp);
+ void setLayerItem(QTableWidgetItem *item, PcapPlusPlus *ppp, bool isProcessing);
+};
+
+#endif // PACKETSTABLEWIDGET_H
diff --git a/pcapplusplus.cpp b/pcapplusplus.cpp
index ea0acb7..0848401 100644
--- a/pcapplusplus.cpp
+++ b/pcapplusplus.cpp
@@ -1,5 +1,3 @@
-#include "pcapplusplus.h"
-
#include <chrono>
#include <EthLayer.h>
#include <exception>
@@ -12,6 +10,8 @@
#include <tuple>
#include <UdpLayer.h>
+#include "pcapplusplus.h"
+
PcapPlusPlus::PcapPlusPlus(std::string fileName) : rawPackets(), parsedPackets()
{
reader = pcpp::IFileReaderDevice::getReader(fileName);
@@ -69,6 +69,11 @@ bool PcapPlusPlus::processPacket(pcpp::Packet & packet)
return false;
if (reader->getNextPacket(rawPacket)) {
+ if (rawPackets.size() == 0) {
+ const auto & pktTs = rawPacket.getPacketTimeStamp();
+ firstPacketTs = pktTs.tv_sec;
+ firstPacketTs += pktTs.tv_nsec / 10e9f;
+ }
rawPackets.emplace_back(std::move(rawPacket));
pcpp::Packet parsedPacket(&rawPackets.back(), false);
diff --git a/pcapplusplus.h b/pcapplusplus.h
index e2ab070..c0f0eb6 100644
--- a/pcapplusplus.h
+++ b/pcapplusplus.h
@@ -28,6 +28,7 @@ public:
bool setIp(size_t index, const std::string & ip, bool isSourceIp);
bool setPort(size_t index, const std::string & port, bool isSourceIp);
bool getPcapStatistics(pcpp::IFileDevice::PcapStats & stats);
+ double getFirstPacketTimestamp() { return firstPacketTs; }
static const pcpp::Layer *getFirstLayer(const pcpp::Packet & packet);
static QString getProtocolTypeAsString(pcpp::ProtocolType protocolType);
@@ -36,7 +37,8 @@ public:
static std::tuple<uint16_t, uint16_t> getLayer4Tuple(const pcpp::Packet & packet);
private:
- pcpp::IFileReaderDevice *reader;
+ double firstPacketTs = 0;
+ pcpp::IFileReaderDevice *reader = nullptr;
std::vector<pcpp::RawPacket> rawPackets;
std::vector<pcpp::Packet> parsedPackets;
};