This repository has been archived on 2024-10-24. You can view files and clone it, but cannot push or open issues or pull requests.
NG_2024_PacketAnalyzer/packetanalyzer.cpp
Stanislav Mykhailenko d7a257af08
First version
2024-08-30 16:48:01 +03:00

338 lines
9.7 KiB
C++

#include "packetanalyzer.h"
#include "ui_packetanalyzer.h"
PacketAnalyzer::PacketAnalyzer(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::PacketAnalyzer)
{
ui->setupUi(this);
connect(ui->cb_interfaces, &QComboBox::currentTextChanged, this, &PacketAnalyzer::changeInterface);
connect(ui->b_refresh, &QPushButton::clicked, this, &PacketAnalyzer::refresh);
connect(ui->t_packets, &QTableWidget::itemSelectionChanged, this, &PacketAnalyzer::packetSelected);
connect(ui->b_start, &QPushButton::clicked, this, &PacketAnalyzer::start);
connect(ui->b_stop, &QPushButton::clicked, this, &PacketAnalyzer::stop);
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);
QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces();
for (QNetworkInterface &interface : interfaces)
ui->cb_interfaces->addItem(interface.name());
}
PacketAnalyzer::~PacketAnalyzer()
{
delete ui;
stop();
}
void PacketAnalyzer::changeInterface(QString)
{
stop();
clear();
m_packets.clear();
m_dev = pcpp::PcapLiveDeviceList::getInstance().getPcapLiveDeviceByName(ui->cb_interfaces->currentText().toStdString());
}
void PacketAnalyzer::clear()
{
ui->t_packets->setRowCount(0);
ui->e_selected->clear();
}
void PacketAnalyzer::refresh()
{
clear();
for (pcpp::RawPacketVector::ConstVectorIterator iter = m_packets.begin(); iter != m_packets.end(); iter++) {
pcpp::Packet parsedPacket(*iter);
ui->t_packets->insertRow( ui->t_packets->rowCount() );
for (pcpp::Layer* curLayer = parsedPacket.getFirstLayer(); curLayer != NULL; curLayer = curLayer->getNextLayer())
{
QTableWidgetItem* numberItem = new QTableWidgetItem();
numberItem->setData(Qt::DisplayRole, ui->t_packets->rowCount());
ui->t_packets->setItem( ui->t_packets->rowCount()-1,
0,
numberItem);
ui->t_packets->setItem( ui->t_packets->rowCount()-1,
3,
new QTableWidgetItem(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<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,
1,
new QTableWidgetItem(sourceIP));
ui->t_packets->setItem( ui->t_packets->rowCount()-1,
2,
new QTableWidgetItem(destinationIP));
}
}
}
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->b_llm->setEnabled(true);
}
void PacketAnalyzer::start()
{
if (!m_dev->open())
{
QMessageBox::critical(
this,
tr("Error"),
tr("Cannot open device.") );
return;
}
clear();
m_packets.clear();
m_dev->startCapture(m_packets);
ui->b_start->setEnabled(false);
ui->b_stop->setEnabled(true);
ui->b_save->setEnabled(false);
}
void PacketAnalyzer::stop()
{
if (m_dev == NULL || !m_dev->captureActive())
return;
m_dev->stopCapture();
ui->b_start->setEnabled(true);
ui->b_stop->setEnabled(false);
ui->b_save->setEnabled(true);
}
void PacketAnalyzer::save()
{
QString fileName = QFileDialog::getSaveFileName(this, "Select file", "", "pcap-ng files (*.pcapng)");
if (fileName.isEmpty())
return;
pcpp::PcapNgFileWriterDevice writer(fileName.toStdString());
if (!writer.open())
{
QMessageBox::critical(
this,
tr("Error"),
tr("Cannot open output file for writing.") );
return;
}
writer.writePackets(m_packets);
writer.close();
}
void PacketAnalyzer::load()
{
QString fileName = QFileDialog::getOpenFileName(this, "Select file", "", "pcap-ng files (*.pcapng)");
if (fileName.isEmpty())
return;
pcpp::PcapNgFileReaderDevice reader(fileName.toStdString());
if (!reader.open())
{
QMessageBox::critical(
this,
tr("Error"),
tr("Cannot open input file for reading.") );
return;
}
stop();
clear();
m_packets.clear();
reader.getNextPackets(m_packets);
reader.close();
refresh();
}
void PacketAnalyzer::llmRequest()
{
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"] = "Please analyze the following packet for anomalies.\n" + ui->e_selected->toPlainText();
json["stream"] = false;
m_manager->post(request, QJsonDocument(json).toJson());
ui->b_llm->setEnabled(false);
ui->b_load->setEnabled(false);
ui->b_refresh->setEnabled(false);
if (m_dev == NULL || !m_dev->captureActive())
ui->b_start->setEnabled(false);
else
ui->b_stop->setEnabled(false);
ui->cb_interfaces->setEnabled(false);
ui->t_packets->setSelectionMode(QAbstractItemView::NoSelection);
}
void PacketAnalyzer::llmResponse(QNetworkReply *reply)
{
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);
if (m_dev == NULL || !m_dev->captureActive())
ui->b_start->setEnabled(true);
else
ui->b_stop->setEnabled(true);
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";
}
}