From 6fc5c1f19fc2dee0dfea10962259b167483b559c Mon Sep 17 00:00:00 2001 From: Stanislav Mykhailenko Date: Sat, 31 Aug 2024 09:37:52 +0300 Subject: [PATCH] Split LLM, packet classification and packet capturing in different classes --- NG_2024_PacketAnalyzer.pro | 8 +- llmmanager.cpp | 31 +++++++ llmmanager.h | 27 ++++++ packetanalyzer.cpp | 180 +++++++------------------------------ packetanalyzer.h | 16 ++-- packetmanager.cpp | 144 +++++++++++++++++++++++++++++ packetmanager.h | 22 +++++ 7 files changed, 269 insertions(+), 159 deletions(-) create mode 100644 llmmanager.cpp create mode 100644 llmmanager.h create mode 100644 packetmanager.cpp create mode 100644 packetmanager.h diff --git a/NG_2024_PacketAnalyzer.pro b/NG_2024_PacketAnalyzer.pro index d6a0986..e137263 100644 --- a/NG_2024_PacketAnalyzer.pro +++ b/NG_2024_PacketAnalyzer.pro @@ -9,11 +9,15 @@ CONFIG += c++17 #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ + llmmanager.cpp \ main.cpp \ - packetanalyzer.cpp + packetanalyzer.cpp \ + packetmanager.cpp HEADERS += \ - packetanalyzer.h + llmmanager.h \ + packetanalyzer.h \ + packetmanager.h FORMS += \ packetanalyzer.ui diff --git a/llmmanager.cpp b/llmmanager.cpp new file mode 100644 index 0000000..82f48a2 --- /dev/null +++ b/llmmanager.cpp @@ -0,0 +1,31 @@ +#include "llmmanager.h" + +LlmManager::LlmManager(QObject *parent) + : QObject{parent} +{ + connect (m_manager, &QNetworkAccessManager::finished, this, &LlmManager::llmResponse); +} + +void LlmManager::llmRequest(QString prompt) +{ + QNetworkRequest request(QUrl("http://127.0.0.1:11434/api/generate")); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + + QJsonObject json; + json["model"] = "llama3.1:8b"; + json["prompt"] = prompt; + json["stream"] = false; + + m_manager->post(request, QJsonDocument(json).toJson()); +} + +void LlmManager::llmResponse(QNetworkReply *reply) +{ + if (reply->error() == QNetworkReply::NoError) { + QByteArray textReply = reply->readAll(); + QString responseText = QJsonDocument::fromJson(textReply).object().value("response").toString(); + emit responseReceived(responseText); + } else { + emit errorReceived(); + } +} diff --git a/llmmanager.h b/llmmanager.h new file mode 100644 index 0000000..2b6f0fa --- /dev/null +++ b/llmmanager.h @@ -0,0 +1,27 @@ +#ifndef LLMMANAGER_H +#define LLMMANAGER_H + +#include +#include +#include +#include + +class LlmManager : public QObject +{ + Q_OBJECT +public: + explicit LlmManager(QObject *parent = nullptr); + void llmRequest(QString); + +signals: + void responseReceived(QString); + void errorReceived(); + +private slots: + void llmResponse(QNetworkReply *); + +private: + QNetworkAccessManager *m_manager = new QNetworkAccessManager(); +}; + +#endif // LLMMANAGER_H diff --git a/packetanalyzer.cpp b/packetanalyzer.cpp index e413557..8282648 100644 --- a/packetanalyzer.cpp +++ b/packetanalyzer.cpp @@ -15,7 +15,9 @@ PacketAnalyzer::PacketAnalyzer(QWidget *parent) connect(ui->b_save, &QPushButton::clicked, this, &PacketAnalyzer::save); connect(ui->b_load, &QPushButton::clicked, this, &PacketAnalyzer::load); connect(ui->b_llm, &QPushButton::clicked, this, &PacketAnalyzer::llmRequest); - connect (m_manager, &QNetworkAccessManager::finished, this, &PacketAnalyzer::llmResponse); + + connect(m_llm, &LlmManager::responseReceived, this, &PacketAnalyzer::llmResponse); + connect(m_llm, &LlmManager::errorReceived, this, &PacketAnalyzer::llmError); QList interfaces = QNetworkInterface::allInterfaces(); @@ -60,34 +62,19 @@ void PacketAnalyzer::refresh() numberItem); ui->t_packets->setItem( ui->t_packets->rowCount()-1, 3, - new QTableWidgetItem(getProtocolTypeAsString(curLayer->getProtocol()))); + new QTableWidgetItem(PacketManager::getProtocolTypeAsString(curLayer->getProtocol()))); ui->t_packets->setItem( ui->t_packets->rowCount()-1, 4, new QTableWidgetItem(QString::number((int)curLayer->getDataLen()))); - QString sourceIP = "Unknown"; - QString destinationIP = "Unknown"; - - pcpp::IPv4Layer* ipv4Layer = parsedPacket.getLayerOfType(); - if (ipv4Layer != NULL) - { - sourceIP = QString::fromStdString(ipv4Layer->getSrcIPAddress().toString()); - destinationIP = QString::fromStdString(ipv4Layer->getSrcIPAddress().toString()); - } - - pcpp::IPv6Layer* ipv6Layer = parsedPacket.getLayerOfType(); - if (ipv6Layer != NULL) - { - sourceIP = QString::fromStdString(ipv6Layer->getSrcIPAddress().toString()); - destinationIP = QString::fromStdString(ipv6Layer->getSrcIPAddress().toString()); - } + QStringList sourceAndDestination = PacketManager::getPacketSourceAndDestination(&parsedPacket); ui->t_packets->setItem( ui->t_packets->rowCount()-1, 1, - new QTableWidgetItem(sourceIP)); + new QTableWidgetItem(sourceAndDestination[0])); ui->t_packets->setItem( ui->t_packets->rowCount()-1, 2, - new QTableWidgetItem(destinationIP)); + new QTableWidgetItem(sourceAndDestination[1])); } } } @@ -96,7 +83,7 @@ void PacketAnalyzer::packetSelected() { int packetId = ui->t_packets->selectedItems()[0]->text().toInt(); pcpp::RawPacket* packet = m_packets.at(packetId-1); - ui->e_selected->setText(QString::fromStdString(pcpp::byteArrayToHexString(packet->getRawData(), packet->getRawDataLen()))); + ui->e_selected->setText(PacketManager::getPacketData(packet)); ui->b_llm->setEnabled(true); } @@ -182,16 +169,31 @@ void PacketAnalyzer::load() void PacketAnalyzer::llmRequest() { - QNetworkRequest request(QUrl("http://127.0.0.1:11434/api/generate")); - request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + uiLock(); + m_llm->llmRequest("Please analyze the following packet for anomalies.\n" + ui->e_selected->toPlainText()); +} - QJsonObject json; - json["model"] = "llama3.1:8b"; - json["prompt"] = "Please analyze the following packet for anomalies.\n" + ui->e_selected->toPlainText(); - json["stream"] = false; +void PacketAnalyzer::llmResponse(QString responseText) +{ + uiUnlock(); + QMessageBox::information( + this, + tr("LLM response"), + responseText ); +} - m_manager->post(request, QJsonDocument(json).toJson()); +void PacketAnalyzer::llmError() +{ + uiUnlock(); + QMessageBox::critical( + this, + tr("Error"), + tr("Could not connect to LLM.") ); +} + +void PacketAnalyzer::uiLock() +{ ui->b_llm->setEnabled(false); ui->b_load->setEnabled(false); ui->b_refresh->setEnabled(false); @@ -204,21 +206,8 @@ void PacketAnalyzer::llmRequest() } -void PacketAnalyzer::llmResponse(QNetworkReply *reply) +void PacketAnalyzer::uiUnlock() { - if (reply->error() == QNetworkReply::NoError) { - QByteArray textReply = reply->readAll(); - QString responseText = QJsonDocument::fromJson(textReply).object().value("response").toString(); - QMessageBox::information( - this, - tr("LLM response"), - responseText ); - } else { - QMessageBox::critical( - this, - tr("Error"), - tr("Could not connect to LLM.") ); - } ui->b_llm->setEnabled(true); ui->b_load->setEnabled(true); ui->b_refresh->setEnabled(true); @@ -229,110 +218,3 @@ void PacketAnalyzer::llmResponse(QNetworkReply *reply) ui->cb_interfaces->setEnabled(true); ui->t_packets->setSelectionMode(QAbstractItemView::SingleSelection); } - -QString PacketAnalyzer::getProtocolTypeAsString(pcpp::ProtocolType protocolType) -{ - switch (protocolType) - { - case pcpp::Ethernet: - return "Ethernet"; - case pcpp::IPv4: - return "IPv4"; - case pcpp::IPv6: - return "IPv6"; - case pcpp::TCP: - return "TCP"; - case pcpp::UDP: - return "UDP"; - case pcpp::HTTPRequest: - case pcpp::HTTPResponse: - return "HTTP"; - case pcpp::ARP: - return "ARP"; - case pcpp::VLAN: - return "VLAN"; - case pcpp::ICMP: - return "ICMP"; - case pcpp::PPPoESession: - case pcpp::PPPoEDiscovery: - return "PPPoE"; - case pcpp::DNS: - return "DNS"; - case pcpp::MPLS: - return "MPLS"; - case pcpp::GREv0: - case pcpp::GREv1: - return "GRE"; - case pcpp::PPP_PPTP: - return "PPP_PPTP"; - case pcpp::SSL: - return "SSL"; - case pcpp::SLL: - return "SLL"; - case pcpp::DHCP: - return "DHCP"; - case pcpp::NULL_LOOPBACK: - return "NULL_LOOPBACK"; - case pcpp::IGMPv1: - case pcpp::IGMPv2: - case pcpp::IGMPv3: - return "IGMP"; - case pcpp::GenericPayload: - return "GenericPayload"; - case pcpp::VXLAN: - return "VXLAN"; - case pcpp::SIPRequest: - case pcpp::SIPResponse: - return "SIP"; - case pcpp::SDP: - return "SDP"; - case pcpp::PacketTrailer: - return "PacketTrailer"; - case pcpp::Radius: - return "Radius"; - case pcpp::GTPv1: - return "GTP"; - case pcpp::EthernetDot3: - return "EthernetDot3"; - case pcpp::BGP: - return "BGP"; - case pcpp::SSH: - return "SSH"; - case pcpp::AuthenticationHeader: - case pcpp::ESP: - return "IPsec"; - case pcpp::DHCPv6: - return "DHCPv6"; - case pcpp::NTP: - return "NTP"; - case pcpp::Telnet: - return "Telnet"; - case pcpp::FTP: - return "FTP"; - case pcpp::ICMPv6: - return "ICMPv6"; - case pcpp::STP: - return "STP"; - case pcpp::LLC: - return "LLC"; - case pcpp::SomeIP: - return "SomeIP"; - case pcpp::WakeOnLan: - return "WakeOnLan"; - case pcpp::NFLOG: - return "NFLOG"; - case pcpp::TPKT: - return "TPKT"; - case pcpp::VRRPv2: - case pcpp::VRRPv3: - return "VRRP"; - case pcpp::COTP: - return "COTP"; - case pcpp::SLL2: - return "SLL2"; - case pcpp::S7COMM: - return "S7COMM"; - default: - return "Unknown"; - } -} diff --git a/packetanalyzer.h b/packetanalyzer.h index 9caeac2..ba8f620 100644 --- a/packetanalyzer.h +++ b/packetanalyzer.h @@ -2,19 +2,16 @@ #define PACKETANALYZER_H #include -#include -#include #include #include #include -#include #include -#include #include #include #include #include -#include +#include "llmmanager.h" +#include "packetmanager.h" QT_BEGIN_NAMESPACE namespace Ui { @@ -39,14 +36,17 @@ private slots: void save(); void load(); void llmRequest(); - void llmResponse(QNetworkReply *); + void llmResponse(QString); + void llmError(); private: Ui::PacketAnalyzer *ui; pcpp::PcapLiveDevice* m_dev = nullptr; pcpp::RawPacketVector m_packets; - QNetworkAccessManager *m_manager = new QNetworkAccessManager(); - QString getProtocolTypeAsString(pcpp::ProtocolType); + LlmManager *m_llm = new LlmManager(); + void clear(); + void uiLock(); + void uiUnlock(); }; #endif // PACKETANALYZER_H diff --git a/packetmanager.cpp b/packetmanager.cpp new file mode 100644 index 0000000..7b924d0 --- /dev/null +++ b/packetmanager.cpp @@ -0,0 +1,144 @@ +#include "packetmanager.h" + +PacketManager::PacketManager(QObject *parent) + : QObject{parent} +{} + +QString PacketManager::getProtocolTypeAsString(pcpp::ProtocolType protocolType) +{ + switch (protocolType) + { + case pcpp::Ethernet: + return "Ethernet"; + case pcpp::IPv4: + return "IPv4"; + case pcpp::IPv6: + return "IPv6"; + case pcpp::TCP: + return "TCP"; + case pcpp::UDP: + return "UDP"; + case pcpp::HTTPRequest: + case pcpp::HTTPResponse: + return "HTTP"; + case pcpp::ARP: + return "ARP"; + case pcpp::VLAN: + return "VLAN"; + case pcpp::ICMP: + return "ICMP"; + case pcpp::PPPoESession: + case pcpp::PPPoEDiscovery: + return "PPPoE"; + case pcpp::DNS: + return "DNS"; + case pcpp::MPLS: + return "MPLS"; + case pcpp::GREv0: + case pcpp::GREv1: + return "GRE"; + case pcpp::PPP_PPTP: + return "PPP_PPTP"; + case pcpp::SSL: + return "SSL"; + case pcpp::SLL: + return "SLL"; + case pcpp::DHCP: + return "DHCP"; + case pcpp::NULL_LOOPBACK: + return "NULL_LOOPBACK"; + case pcpp::IGMPv1: + case pcpp::IGMPv2: + case pcpp::IGMPv3: + return "IGMP"; + case pcpp::GenericPayload: + return "GenericPayload"; + case pcpp::VXLAN: + return "VXLAN"; + case pcpp::SIPRequest: + case pcpp::SIPResponse: + return "SIP"; + case pcpp::SDP: + return "SDP"; + case pcpp::PacketTrailer: + return "PacketTrailer"; + case pcpp::Radius: + return "Radius"; + case pcpp::GTPv1: + return "GTP"; + case pcpp::EthernetDot3: + return "EthernetDot3"; + case pcpp::BGP: + return "BGP"; + case pcpp::SSH: + return "SSH"; + case pcpp::AuthenticationHeader: + case pcpp::ESP: + return "IPsec"; + case pcpp::DHCPv6: + return "DHCPv6"; + case pcpp::NTP: + return "NTP"; + case pcpp::Telnet: + return "Telnet"; + case pcpp::FTP: + return "FTP"; + case pcpp::ICMPv6: + return "ICMPv6"; + case pcpp::STP: + return "STP"; + case pcpp::LLC: + return "LLC"; + case pcpp::SomeIP: + return "SomeIP"; + case pcpp::WakeOnLan: + return "WakeOnLan"; + case pcpp::NFLOG: + return "NFLOG"; + case pcpp::TPKT: + return "TPKT"; + case pcpp::VRRPv2: + case pcpp::VRRPv3: + return "VRRP"; + case pcpp::COTP: + return "COTP"; + case pcpp::SLL2: + return "SLL2"; + case pcpp::S7COMM: + return "S7COMM"; + default: + return "Unknown"; + } +} + +QStringList PacketManager::getPacketSourceAndDestination(pcpp::Packet* packet) +{ + QString sourceIP = "Unknown"; + QString destinationIP = "Unknown"; + + pcpp::IPv4Layer* ipv4Layer = packet->getLayerOfType(); + if (ipv4Layer != NULL) + { + sourceIP = QString::fromStdString(ipv4Layer->getSrcIPAddress().toString()); + destinationIP = QString::fromStdString(ipv4Layer->getSrcIPAddress().toString()); + } + + pcpp::IPv6Layer* ipv6Layer = packet->getLayerOfType(); + if (ipv6Layer != NULL) + { + sourceIP = QString::fromStdString(ipv6Layer->getSrcIPAddress().toString()); + destinationIP = QString::fromStdString(ipv6Layer->getSrcIPAddress().toString()); + } + + QStringList sourceAndDestination; + + sourceAndDestination.append(sourceIP); + sourceAndDestination.append(destinationIP); + + return sourceAndDestination; +} + +QString PacketManager::getPacketData(pcpp::RawPacket *rawPacket) +{ + return QString::fromStdString(pcpp::byteArrayToHexString(rawPacket->getRawData(), rawPacket->getRawDataLen())); +} diff --git a/packetmanager.h b/packetmanager.h new file mode 100644 index 0000000..74e44e4 --- /dev/null +++ b/packetmanager.h @@ -0,0 +1,22 @@ +#ifndef PACKETMANAGER_H +#define PACKETMANAGER_H + +#include +#include +#include +#include +#include + +class PacketManager : public QObject +{ + Q_OBJECT +public: + explicit PacketManager(QObject *parent = nullptr); + static QString getProtocolTypeAsString(pcpp::ProtocolType); + static QStringList getPacketSourceAndDestination(pcpp::Packet*); + static QString getPacketData(pcpp::RawPacket*); + +signals: +}; + +#endif // PACKETMANAGER_H