44#include < ctime>
55#include < winsock2.h>
66#include < ws2tcpip.h>
7+ #include < iphlpapi.h>
78#include < QDateTime>
89#include < QMetaType>
910#include < QThread>
1011#include < QDebug>
1112#include < functional>
1213#include < thread>
1314
14- #pragma comment(lib, "Ws2_32.lib")
15-
1615struct ip_hdr {
1716 unsigned char ip_hl : 4 ;
1817 unsigned char ip_v : 4 ;
@@ -136,6 +135,19 @@ void PacketHandler::processPacket(u_char *userData, const struct pcap_pkthdr *pk
136135
137136 qDebug () << " IP пакет:" << sourceIP << " ->" << destIP << " Протокол:" << (int )ipHeader->ip_p ;
138137
138+ // Проверяем, является ли IP-адрес источника или назначения локальным
139+ bool isSourceLocal = false ;
140+ bool isDestLocal = false ;
141+
142+ for (const auto & localIP : handler->localIPAddresses ) {
143+ if (localIP == sourceIP) {
144+ isSourceLocal = true ;
145+ }
146+ if (localIP == destIP) {
147+ isDestLocal = true ;
148+ }
149+ }
150+
139151 // Определяем тип пакета
140152 QString packetType;
141153 QString details;
@@ -174,7 +186,11 @@ void PacketHandler::processPacket(u_char *userData, const struct pcap_pkthdr *pk
174186
175187 // Проверяем на возможное сканирование портов
176188 // Сканирование портов обычно направлено на привилегированные порты (< 1024)
177- if (destPort < 1024 ) {
189+ // Теперь проверяем как внешние, так и внутренние сканирования
190+ if (destPort < 1024 && isDestLocal && !isSourceLocal) {
191+ details = " (Порт " + QString::number (sourcePort) + " -> " + QString::number (destPort) + " ) Возможное сканирование портов с внешнего IP" ;
192+ isPotentialThreat = true ;
193+ } else if (destPort < 1024 ) {
178194 details = " (Порт " + QString::number (sourcePort) + " -> " + QString::number (destPort) + " ) Возможное сканирование портов" ;
179195 isPotentialThreat = true ;
180196 } else {
@@ -208,7 +224,11 @@ void PacketHandler::processPacket(u_char *userData, const struct pcap_pkthdr *pk
208224
209225 // Если это попытка подключения (SYN) к известному порту
210226 if (tcpHeader->flags & 0x02 && !(tcpHeader->flags & 0x10 )) {
211- details += " (Попытка подключения к потенциально уязвимому сервису)" ;
227+ if (!isSourceLocal && isDestLocal) {
228+ details += " (Попытка подключения к потенциально уязвимому сервису с внешнего IP)" ;
229+ } else {
230+ details += " (Попытка подключения к потенциально уязвимому сервису)" ;
231+ }
212232 isPotentialThreat = true ;
213233 }
214234 }
@@ -240,6 +260,11 @@ void PacketHandler::processPacket(u_char *userData, const struct pcap_pkthdr *pk
240260 destPort == 1900 || // UPnP
241261 destPort == 5353 ) { // mDNS
242262
263+ // Если пакет направлен на локальный компьютер с внешнего IP
264+ if (!isSourceLocal && isDestLocal) {
265+ details += " (Возможный UDP флуд с внешнего IP)" ;
266+ isPotentialThreat = true ;
267+ }
243268 // Здесь можно добавить логику для отслеживания частоты UDP пакетов
244269 // на эти порты для обнаружения UDP флуда
245270 }
@@ -250,10 +275,17 @@ void PacketHandler::processPacket(u_char *userData, const struct pcap_pkthdr *pk
250275 qDebug () << " ICMP пакет:" << sourceIP << " ->" << destIP;
251276
252277 packetType = " ICMP" ;
253- details = " (ping)" ;
254278
255- // Здесь можно добавить логику для отслеживания частоты ICMP пакетов
256- // для обнаружения ping flood
279+ // Если пакет направлен на локальный компьютер с внешнего IP
280+ if (!isSourceLocal && isDestLocal) {
281+ details = " (ping с внешнего IP)" ;
282+
283+ // С некоторой вероятностью помечаем как потенциальную угрозу
284+ // Здесь можно добавить логику для отслеживания частоты ICMP пакетов
285+ // для обнаружения ping flood
286+ } else {
287+ details = " (ping)" ;
288+ }
257289
258290 break ;
259291 }
@@ -282,6 +314,84 @@ void PacketHandler::processPacket(u_char *userData, const struct pcap_pkthdr *pk
282314 }
283315}
284316
317+ std::vector<std::string> PacketHandler::getLocalIPAddresses () {
318+ std::vector<std::string> ipAddresses;
319+
320+ // Инициализируем Winsock
321+ WSADATA wsaData;
322+ if (WSAStartup (MAKEWORD (2 , 2 ), &wsaData) != 0 ) {
323+ qDebug () << " Ошибка при инициализации Winsock" ;
324+ return ipAddresses;
325+ }
326+
327+ // Получаем информацию об адаптерах
328+ ULONG bufferSize = 15000 ;
329+ PIP_ADAPTER_ADDRESSES pAddresses = (IP_ADAPTER_ADDRESSES*)malloc (bufferSize);
330+
331+ if (pAddresses == nullptr ) {
332+ qDebug () << " Ошибка выделения памяти для IP_ADAPTER_ADDRESSES" ;
333+ WSACleanup ();
334+ return ipAddresses;
335+ }
336+
337+ DWORD result = GetAdaptersAddresses (AF_INET, 0 , nullptr , pAddresses, &bufferSize);
338+
339+ if (result == ERROR_BUFFER_OVERFLOW) {
340+ free (pAddresses);
341+ pAddresses = (IP_ADAPTER_ADDRESSES*)malloc (bufferSize);
342+
343+ if (pAddresses == nullptr ) {
344+ qDebug () << " Ошибка выделения памяти для IP_ADAPTER_ADDRESSES после переполнения буфера" ;
345+ WSACleanup ();
346+ return ipAddresses;
347+ }
348+
349+ result = GetAdaptersAddresses (AF_INET, 0 , nullptr , pAddresses, &bufferSize);
350+ }
351+
352+ if (result != NO_ERROR) {
353+ qDebug () << " Ошибка при получении информации об адаптерах:" << result;
354+ free (pAddresses);
355+ WSACleanup ();
356+ return ipAddresses;
357+ }
358+
359+ // Перебираем все адаптеры и их IP-адреса
360+ for (PIP_ADAPTER_ADDRESSES pCurrAddresses = pAddresses; pCurrAddresses != nullptr ; pCurrAddresses = pCurrAddresses->Next ) {
361+ // Пропускаем отключенные адаптеры
362+ if (pCurrAddresses->OperStatus != IfOperStatusUp) {
363+ continue ;
364+ }
365+
366+ // Получаем IP-адреса для текущего адаптера
367+ PIP_ADAPTER_UNICAST_ADDRESS pUnicast = pCurrAddresses->FirstUnicastAddress ;
368+ while (pUnicast != nullptr ) {
369+ // Проверяем, что это IPv4 адрес
370+ if (pUnicast->Address .lpSockaddr ->sa_family == AF_INET) {
371+ sockaddr_in* sockaddr = reinterpret_cast <sockaddr_in*>(pUnicast->Address .lpSockaddr );
372+ char ipStr[INET_ADDRSTRLEN];
373+ inet_ntop (AF_INET, &(sockaddr->sin_addr ), ipStr, INET_ADDRSTRLEN);
374+
375+ // Добавляем IP-адрес в список
376+ ipAddresses.push_back (ipStr);
377+ qDebug () << " Найден локальный IP-адрес:" << ipStr;
378+ }
379+
380+ pUnicast = pUnicast->Next ;
381+ }
382+ }
383+
384+ // Добавляем localhost
385+ ipAddresses.push_back (" 127.0.0.1" );
386+ qDebug () << " Добавлен localhost: 127.0.0.1" ;
387+
388+ // Освобождаем ресурсы
389+ free (pAddresses);
390+ WSACleanup ();
391+
392+ return ipAddresses;
393+ }
394+
285395bool PacketHandler::startCapture (const std::string& deviceName, QString* errorMessage) {
286396 try {
287397 if (isRunning) {
@@ -291,6 +401,9 @@ bool PacketHandler::startCapture(const std::string& deviceName, QString* errorMe
291401 return false ;
292402 }
293403
404+ // Получаем локальные IP-адреса
405+ localIPAddresses = getLocalIPAddresses ();
406+
294407 char errorBuffer[PCAP_ERRBUF_SIZE];
295408
296409 // Проверяем, существует ли устройство
@@ -323,6 +436,7 @@ bool PacketHandler::startCapture(const std::string& deviceName, QString* errorMe
323436 qDebug () << " Открываем устройство:" << QString::fromStdString (deviceName);
324437
325438 // Открываем устройство для захвата пакетов в режиме promiscuous
439+ // Устанавливаем режим promiscuous (1), чтобы захватывать все пакеты в сети
326440 handle = pcap_open_live (deviceName.c_str (), BUFSIZ, 1 , 100 , errorBuffer);
327441
328442 if (handle == nullptr ) {
@@ -342,9 +456,12 @@ bool PacketHandler::startCapture(const std::string& deviceName, QString* errorMe
342456 qDebug () << " Предупреждение: устройство не использует Ethernet. Захват может работать некорректно." ;
343457 }
344458
345- // Устанавливаем пустой фильтр, чтобы захватывать все пакеты
459+ // Устанавливаем фильтр для захвата всех пакетов в сети
346460 struct bpf_program fp;
347- if (pcap_compile (handle, &fp, " " , 0 , PCAP_NETMASK_UNKNOWN) == -1 ) {
461+ // Пустой фильтр для захвата всех пакетов
462+ const char * filter = " " ;
463+
464+ if (pcap_compile (handle, &fp, filter, 0 , PCAP_NETMASK_UNKNOWN) == -1 ) {
348465 if (errorMessage) {
349466 *errorMessage = QString (" Ошибка при компиляции фильтра: %1" ).arg (pcap_geterr (handle));
350467 }
0 commit comments