Split LLM, packet classification and packet capturing in different classes

This commit is contained in:
Stanislav Mykhailenko 2024-08-31 09:37:52 +03:00
parent d7a257af08
commit 6fc5c1f19f
GPG key ID: 1E95E66A9C9D6A36
7 changed files with 269 additions and 159 deletions

View file

@ -9,11 +9,15 @@ CONFIG += c++17
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \ SOURCES += \
llmmanager.cpp \
main.cpp \ main.cpp \
packetanalyzer.cpp packetanalyzer.cpp \
packetmanager.cpp
HEADERS += \ HEADERS += \
packetanalyzer.h llmmanager.h \
packetanalyzer.h \
packetmanager.h
FORMS += \ FORMS += \
packetanalyzer.ui packetanalyzer.ui

31
llmmanager.cpp Normal file
View file

@ -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();
}
}

27
llmmanager.h Normal file
View file

@ -0,0 +1,27 @@
#ifndef LLMMANAGER_H
#define LLMMANAGER_H
#include <QJsonDocument>
#include <QJsonObject>
#include <QNetworkReply>
#include <QObject>
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

View file

@ -15,7 +15,9 @@ PacketAnalyzer::PacketAnalyzer(QWidget *parent)
connect(ui->b_save, &QPushButton::clicked, this, &PacketAnalyzer::save); connect(ui->b_save, &QPushButton::clicked, this, &PacketAnalyzer::save);
connect(ui->b_load, &QPushButton::clicked, this, &PacketAnalyzer::load); connect(ui->b_load, &QPushButton::clicked, this, &PacketAnalyzer::load);
connect(ui->b_llm, &QPushButton::clicked, this, &PacketAnalyzer::llmRequest); 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<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces(); QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces();
@ -60,34 +62,19 @@ void PacketAnalyzer::refresh()
numberItem); numberItem);
ui->t_packets->setItem( ui->t_packets->rowCount()-1, ui->t_packets->setItem( ui->t_packets->rowCount()-1,
3, 3,
new QTableWidgetItem(getProtocolTypeAsString(curLayer->getProtocol()))); new QTableWidgetItem(PacketManager::getProtocolTypeAsString(curLayer->getProtocol())));
ui->t_packets->setItem( ui->t_packets->rowCount()-1, ui->t_packets->setItem( ui->t_packets->rowCount()-1,
4, 4,
new QTableWidgetItem(QString::number((int)curLayer->getDataLen()))); new QTableWidgetItem(QString::number((int)curLayer->getDataLen())));
QString sourceIP = "Unknown"; QStringList sourceAndDestination = PacketManager::getPacketSourceAndDestination(&parsedPacket);
QString destinationIP = "Unknown";
pcpp::IPv4Layer* ipv4Layer = parsedPacket.getLayerOfType<pcpp::IPv4Layer>();
if (ipv4Layer != NULL)
{
sourceIP = QString::fromStdString(ipv4Layer->getSrcIPAddress().toString());
destinationIP = QString::fromStdString(ipv4Layer->getSrcIPAddress().toString());
}
pcpp::IPv6Layer* ipv6Layer = parsedPacket.getLayerOfType<pcpp::IPv6Layer>();
if (ipv6Layer != NULL)
{
sourceIP = QString::fromStdString(ipv6Layer->getSrcIPAddress().toString());
destinationIP = QString::fromStdString(ipv6Layer->getSrcIPAddress().toString());
}
ui->t_packets->setItem( ui->t_packets->rowCount()-1, ui->t_packets->setItem( ui->t_packets->rowCount()-1,
1, 1,
new QTableWidgetItem(sourceIP)); new QTableWidgetItem(sourceAndDestination[0]));
ui->t_packets->setItem( ui->t_packets->rowCount()-1, ui->t_packets->setItem( ui->t_packets->rowCount()-1,
2, 2,
new QTableWidgetItem(destinationIP)); new QTableWidgetItem(sourceAndDestination[1]));
} }
} }
} }
@ -96,7 +83,7 @@ void PacketAnalyzer::packetSelected()
{ {
int packetId = ui->t_packets->selectedItems()[0]->text().toInt(); int packetId = ui->t_packets->selectedItems()[0]->text().toInt();
pcpp::RawPacket* packet = m_packets.at(packetId-1); 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); ui->b_llm->setEnabled(true);
} }
@ -182,16 +169,31 @@ void PacketAnalyzer::load()
void PacketAnalyzer::llmRequest() void PacketAnalyzer::llmRequest()
{ {
QNetworkRequest request(QUrl("http://127.0.0.1:11434/api/generate")); uiLock();
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); m_llm->llmRequest("Please analyze the following packet for anomalies.\n" + ui->e_selected->toPlainText());
}
QJsonObject json; void PacketAnalyzer::llmResponse(QString responseText)
json["model"] = "llama3.1:8b"; {
json["prompt"] = "Please analyze the following packet for anomalies.\n" + ui->e_selected->toPlainText(); uiUnlock();
json["stream"] = false; 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_llm->setEnabled(false);
ui->b_load->setEnabled(false); ui->b_load->setEnabled(false);
ui->b_refresh->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_llm->setEnabled(true);
ui->b_load->setEnabled(true); ui->b_load->setEnabled(true);
ui->b_refresh->setEnabled(true); ui->b_refresh->setEnabled(true);
@ -229,110 +218,3 @@ void PacketAnalyzer::llmResponse(QNetworkReply *reply)
ui->cb_interfaces->setEnabled(true); ui->cb_interfaces->setEnabled(true);
ui->t_packets->setSelectionMode(QAbstractItemView::SingleSelection); 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";
}
}

View file

@ -2,19 +2,16 @@
#define PACKETANALYZER_H #define PACKETANALYZER_H
#include <QFileDialog> #include <QFileDialog>
#include <QJsonDocument>
#include <QJsonObject>
#include <QMainWindow> #include <QMainWindow>
#include <QMessageBox> #include <QMessageBox>
#include <QNetworkInterface> #include <QNetworkInterface>
#include <QNetworkReply>
#include <QTableWidgetItem> #include <QTableWidgetItem>
#include <GeneralUtils.h>
#include <IPv4Layer.h> #include <IPv4Layer.h>
#include <IPv6Layer.h> #include <IPv6Layer.h>
#include <PcapFileDevice.h> #include <PcapFileDevice.h>
#include <PcapLiveDeviceList.h> #include <PcapLiveDeviceList.h>
#include <SystemUtils.h> #include "llmmanager.h"
#include "packetmanager.h"
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
namespace Ui { namespace Ui {
@ -39,14 +36,17 @@ private slots:
void save(); void save();
void load(); void load();
void llmRequest(); void llmRequest();
void llmResponse(QNetworkReply *); void llmResponse(QString);
void llmError();
private: private:
Ui::PacketAnalyzer *ui; Ui::PacketAnalyzer *ui;
pcpp::PcapLiveDevice* m_dev = nullptr; pcpp::PcapLiveDevice* m_dev = nullptr;
pcpp::RawPacketVector m_packets; pcpp::RawPacketVector m_packets;
QNetworkAccessManager *m_manager = new QNetworkAccessManager(); LlmManager *m_llm = new LlmManager();
QString getProtocolTypeAsString(pcpp::ProtocolType);
void clear(); void clear();
void uiLock();
void uiUnlock();
}; };
#endif // PACKETANALYZER_H #endif // PACKETANALYZER_H

144
packetmanager.cpp Normal file
View file

@ -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<pcpp::IPv4Layer>();
if (ipv4Layer != NULL)
{
sourceIP = QString::fromStdString(ipv4Layer->getSrcIPAddress().toString());
destinationIP = QString::fromStdString(ipv4Layer->getSrcIPAddress().toString());
}
pcpp::IPv6Layer* ipv6Layer = packet->getLayerOfType<pcpp::IPv6Layer>();
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()));
}

22
packetmanager.h Normal file
View file

@ -0,0 +1,22 @@
#ifndef PACKETMANAGER_H
#define PACKETMANAGER_H
#include <QObject>
#include <GeneralUtils.h>
#include <IPv4Layer.h>
#include <IPv6Layer.h>
#include <Packet.h>
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