NPCAP библиотека - этосуществоватьWindows
Библиотека для захвата и анализа сетевых пакетов на платформе.。этоWinPcap
филиал библиотеки,Зависит отNmap
Развитие команды разработчиков,И вNmap
используется в программном обеспечении。иWinPcap
Такой же,NPCAPБиблиотека предоставляет некоторыеAPI
,Позволяет разработчикам легко захватывать и обрабатывать сетевые пакеты в своих приложениях.。NPCAPДоступ к библиотеке можно получить черезWinPcap API
Программирование,Таким образом, существующие приложения WinPcap можно легко перенести в библиотеку NPCAP.
По сравнению с WinPcap,Библиотека NPCAP имеет лучшую производительность и надежность.,Поддерживает новейшие операционные системы и оборудование.。Он также обеспечивает802.11
Встроенная поддержка беспроводных сетей,и может пройтиWireshark
Подождите, пока будут использованы инструменты сетевого анализа.。 NPCAPБиблиотека находится вMIT
Опубликовано по лицензии,Поэтому его можно использовать как в бесплатном, так и в коммерческом программном обеспечении.
Набор инструментов разделен на две части: драйвер и набор инструментов SDK.,При использовании этой библиотеки для перехвата пакетов читателям необходимо самостоятельно установить соответствующую версию драйвера.,Версия, используемая здесь читателями:npcap-1.55.exe
После загрузки читатели могут нажать «Далее».,Когда установка будет завершена, вы увидите сообщение с подсказкой, как показано ниже;
Когда установка драйвера будет завершена,Читатели могут самостоятельно настроить инструментарий разработки в проекте.,Обычно достаточно удалитьinclude
иlib
Библиотеку можно настроить в проект,После настройки, как показано на рисунке ниже, вы можете применить и сохранить ее самостоятельно.
Затем давайте реализуем первую функцию,Перечислить информацию о сетевой карте, которую можно использовать на текущем хосте.,Реализация этой функции во многом зависит отpcap_findalldevs_ex()
функция,Эта функция используется для получения списка всех сетевых адаптеров, доступных в текущей системе.
Объявление прототипа функции выглядит следующим образом:
int pcap_findalldevs_ex(const char *source, struct pcap_rmtauth *auth,
pcap_if_t **alldevsp, char *errbuf);
Среди них значения параметров следующие:
pcap_rmtauth
Структура приходит Укажите удаленный IP и имя пользователя.Эта функция позволяет разработчикам получать сведения обо всех сетевых адаптерах через структуру. Позволяет указать фильтр,для соответствия определенным пользователем сетевым адаптерам и свойствам. также,pcap_findalldevs_ex()
Также предоставляет структуру для хранения информации об ошибках.,Чтобы предоставить информацию об ошибке в случае сбоя вызова функции.
В противном случае функция возвращает -1, чтобы указать на ошибку;,Возвращаемое значение 0 указывает, что операция прошла успешно.,и вернет все доступные сетевые адаптеры и их данные. Эти сведения включают имя адаптера, описание, MAC-адрес, IP-адрес, маску подсети и т. д.,как читательиспользоватьперечислятьфункция После окончаниянуждатьсясамоходныйвызовpcap_freealldevs
функция Освободите этот указатель, чтобы избежать утечек памяти.。
Ниже приведено объявление прототипа функции pcap_freealldevs:
void pcap_freealldevs(pcap_if_t *alldevs);
в,alldevs
Параметр указывает наpcap_if_t
Указатель на структуру типа,В структуру этого типа записывается подробная информация обо всех сетевых интерфейсах, доступных на текущем хосте.。pcap_freealldevs()
выпустит входящиеpcap_if_t
введите связанный список,И поставьте все элементы удалить.
вызовpcap_freealldevs()
функциячаснуждатьсяпрошло, прежде чем войтиpcap_findalldevs()
илиpcap_findalldevs_ex()
функцияполученныйориентированныйсвязанный списокструктурауказатель какпараметр。
Когда эти две функции используются в качестве условий, реализовать перечисление сетевых карт становится очень просто. Следующий код показывает конкретный процесс реализации использования этого набора инструментов для реализации перечисления. Читатели могут скомпилировать и протестировать его самостоятельно.
#include <iostream>
#include <winsock2.h>
#include <Windows.h>
#include <string>
#include <pcap.h>
#pragma comment(lib,"ws2_32.lib")
#pragma comment(lib, "packet.lib")
#pragma comment(lib, "wpcap.lib")
using namespace std;
// Выходные строки
void PrintLine(int x)
{
for (size_t i = 0; i < x; i++)
{
printf("-");
}
printf("\n");
}
// Перечислить текущие сетевые карты
int enumAdapters()
{
pcap_if_t *allAdapters; // Сохраните все устройства сетевых карт.
pcap_if_t *ptr; // указатель для обхода
int index = 0;
char errbuf[PCAP_ERRBUF_SIZE];
/* Получить список локальных машин и устройств */
if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &allAdapters, errbuf) != -1)
{
PrintLine(100);
printf("индекс \t Имя сетевой карты \n");
PrintLine(100);
/* Распечатать список информации о сетевой карте */
for (ptr = allAdapters; ptr != NULL; ptr = ptr->next)
{
++index;
if (ptr->description)
{
printf("[ %d ] \t [ %s ] \n", index - 1, ptr->description);
}
}
}
/* Список устройств больше не нужен, освободите его */
pcap_freealldevs(allAdapters);
return index;
}
int main(int argc, char* argv[])
{
enumAdapters();
system("pause");
return 0;
}
Скомпилируйте и запустите программу от имени администратора, читатель увидит выходные данные, как показано на рисунке ниже, где первый столбец — это индексный номер сетевой карты, а второй столбец — имя сетевой карты;
Как только номер сетевой карты станет доступен, считыватели смогут захватывать пакеты и анализировать конкретный номер.,Реализация функции захвата пакетов зависит отpcap_open()
функция,Эта функция используется для открытия указанного сетевого адаптера и начала перехвата сетевых пакетов.,Объявление прототипа функции выглядит следующим образом:
pcap_t *pcap_open(const char *source, int snaplen, int flags, int read_timeout,
struct pcap_rmtauth *auth, char *errbuf);
Смысл его параметров следующий:
pcap_open_live()
Имя, полученное от。promiscuous
режим контроллераили Нетpromiscuous
Снимать в режиме。pcap_rmtauth
структура,Укажите удаленный IP и имя пользователя.Долженфункциявозвращатьсяточкаpcap_t
указатель типа,Этот тип структуры обеспечивает интерфейс для связи с сетевым адаптером.,Может использоваться для захвата пакетов, отключения сетевых адаптеров и других операций.,читательсуществоватьвызовpcap_open()
функциячас,Необходимо указать имя сетевого адаптера для открытияsource
,Если вам нужно установить его в смешанный режим,Нужно установитьflags
ПараметрыPCAP_OPENFLAG_PROMISCUOUS
,такжеsnaplen
Параметр, используемый для установки размера перехваченных пакетов.,read_timeout
параметр Используется для установки блокировки чтения.функция的超часчас间,auth
Параметры используются для указания удаленногоIP
и имя пользователя,errbuf
Параметры, используемые для хранения информации об ошибках。нравитьсяфрукты Долженфункциявозвращаться空,Это означает, что указанный сетевой адаптер не был успешно открыт.
другойнуждатьсяосторожныйфункциядаpcap_next_ex()
Долженфункция Используется для чтения следующего сетевого пакета с указанного открытого сетевого адаптера.,Обычно этофункциянуждаться Сотрудничатьpcap_open()
используются вместе,Его прототип заявляет:
int pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header, const u_char **pkt_data);
Значения параметров следующие:
pcap_t
Указатель на структуру типа,Представляет открытый сетевой адаптер.pcap_pkthdr
указатель типа,Этот тип структуры содержит метаданные о текущем пакете.,Например, временная метка, Длина. пакета、Интерфейс сетевого адаптера и т. д., где были перехвачены пакеты.Он возвращает одно из следующих трех возвращаемых значений:
pkt_header
иpkt_data
ноориентированный Сопутствующая информация;errbuf
Найдите информацию об ошибке в параметрах。использоватьpcap_next_ex()
функциячас,нуждатьсяпоставлятьточкаpcap_t
Указатель на структуру типаp
Используется для определения того, с какого сетевого адаптера читать пакеты.。В случае успеха при чтении пакета,но Воля包的元数据存储существоватьпереходныйpcap_pkthdr
в указателе,Воляориентированный Хранилище указателей для захваченных пакетовсуществоватьpkt_data
в указателе。нравитьсяфруктысуществовать指定的час间内未捕获到任何数据包,Функция возвращает 0. Если при чтении пакета возникает какая-либо ошибка,Функция возвращает -1,И вerrbuf
Подробности об ошибке указаны в параметрах.。
Когда читатели поймут функции двух вышеупомянутых ключевых функций, они смогут реализовать функцию динамического захвата пакетов.,следующеекодвMonitorAdapter
функциянода抓包的实现,Эта функция требует передачи двух параметров.,параметр1Это сетевая карта, которая должна перехватывать пакеты.серийный номер,Здесь мы используем цифру 7,Второй параметр указывает тип пакета данных, который необходимо декодировать.,Здесь мы можем пройтиether
и т. д. для распаковки,Конечно, в этой функции еще не реализована функция анализа пакетов данных.,Реализация этих функций нуждается в дальнейшем совершенствовании.
#include <iostream>
#include <winsock2.h>
#include <Windows.h>
#include <string>
#include <pcap.h>
#pragma comment(lib,"ws2_32.lib")
#pragma comment(lib, "packet.lib")
#pragma comment(lib, "wpcap.lib")
using namespace std;
// Выберите сетевую карту и разберите пакеты по разным параметрам.
void MonitorAdapter(int nChoose, char *Type)
{
pcap_if_t *adapters;
char errbuf[PCAP_ERRBUF_SIZE];
if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &adapters, errbuf) != -1)
{
// Найти указанную сетевую карту
for (int x = 0; x < nChoose - 1; ++x)
adapters = adapters->next;
// PCAP_OPENFLAG_PROMISCUOUS = Сетевая карта переведена в беспорядочный режим
// 1000 => 1000 миллисекунд. Если данные не могут быть прочитаны, тайм-аут будет возвращен напрямую.
pcap_t * handle = pcap_open(adapters->name, 65534, 1, PCAP_OPENFLAG_PROMISCUOUS, 0, 0);
if (adapters == NULL)
return;
// printf("Начните слушать: % \n", adapters->description);
pcap_pkthdr *Packet_Header; // заголовок пакета
const u_char * Packet_Data; // сами данные
int retValue;
while ((retValue = pcap_next_ex(handle, &Packet_Header, &Packet_Data)) >= 0)
{
if (retValue == 0)
continue;
// printf("Продолжительность прослушивания: %d \n", Packet_Header->len);
if (strcmp(Type, "ether") == 0)
{
PrintEtherHeader(Packet_Data);
}
if (strcmp(Type, "ip") == 0)
{
PrintIPHeader(Packet_Data);
}
if (strcmp(Type, "tcp") == 0)
{
PrintTCPHeader(Packet_Data);
}
if (strcmp(Type, "udp") == 0)
{
PrintUDPHeader(Packet_Data);
}
if (strcmp(Type, "icmp") == 0)
{
PrintICMPHeader(Packet_Data);
}
if (strcmp(Type, "http") == 0)
{
PrintHttpHeader(Packet_Data);
}
if (strcmp(Type, "arp") == 0)
{
PrintArpHeader(Packet_Data);
}
}
}
}
int main(int argc, char* argv[])
{
MonitorAdapter(7,"ether");
system("pause");
return 0;
}
Когда читатель имеет вышеизложенноекодрамка,Затем следующим шагом будет его последовательная реализация.PrintEtherHeader
,PrintIPHeader
,PrintTCPHeader
,PrintUDPHeader
,PrintICMPHeader
,PrintHttpHeader
,PrintArpHeader
ждатьфункция,Этифункция Получить исходный пакетPacket_Data
тип,И конвертировать его в пакет данных соответствующего формата и выводить пользователю,Далее мы последовательно реализуем эти функции.
Пакеты Ethernet — это формат пакетов данных, отправляемых через Ethernet. Обычно он включает заголовок Ethernet и часть данных Ethernet. Вот введение в его различные части:
Пакеты Ethernet обычно используются для связи в локальных сетях. Отправляйте пакеты на все устройства в этой сети, используя кадры Ethernet в качестве формата пакета. Затем целевое устройство получает и обрабатывает эти кадры на основе целевого MAC-адреса, а другие устройства игнорируют эти кадры. В пакете Ethernet MAC-адрес назначения относится к уникальному MAC-адресу устройства, на которое пакет предназначен для отправки, а MAC-адрес источника относится к MAC-адресу устройства, отправляющего сообщение.
// Декодирование пакетов канала передачи данных Уровень канала передачи данных — это второй уровень, и во время декодирования необходимо инкапсулировать только один уровень заголовка Ethernet. пакета Вот и все.
#define hcons(A) (((WORD)(A)&0xFF00)>>8) | (((WORD)(A)&0x00FF)<<8)
void PrintEtherHeader(const u_char * packetData)
{
typedef struct ether_header
{
u_char ether_dhost[6]; // адрес назначения
u_char ether_shost[6]; // Исходный адрес
u_short ether_type; // Тип Ethernet
} ether_header;
struct ether_header * eth_protocol;
eth_protocol = (struct ether_header *)packetData;
u_short ether_type = ntohs(eth_protocol->ether_type); // Тип Ethernet
u_char *ether_src = eth_protocol->ether_shost; // Необработанный MAC-адрес Ethernet
u_char *ether_dst = eth_protocol->ether_dhost; // MAC-адрес назначения Ethernet
printf("Введите: 0x%x \t", ether_type);
printf("Исходный MAC-адрес: %02X:%02X:%02X:%02X:%02X:%02X \t",
ether_src[0], ether_src[1], ether_src[2], ether_src[3], ether_src[4], ether_src[5]);
printf("MAC-адрес назначения: %02X:%02X:%02X:%02X:%02X:%02X \n",
ether_dst[0], ether_dst[1], ether_dst[2], ether_dst[3], ether_dst[4], ether_dst[5]);
}
Поскольку Ethernet является слишком низкоуровневым, мы можем получить только некоторую базовую информацию о сетевой карте, анализируя Ethernet, как показано на рисунке ниже;
Пакеты данных IP (Интернет-протокол) представляют собой третий уровень стека протоколов TCP/IP (Протокол управления передачей/Интернет-протокол). Обычно он состоит из двух частей: IP-заголовка и части данных.
Заголовки IP обычно включают следующее:
Пакеты IP-данных передаются на сетевом уровне, и его основная функция — предоставлять услуги передачи пакетов между различными приложениями в Интернете. Он использует IP-адреса, чтобы определить, откуда приходят пакеты и куда их следует направить на устройство назначения.
При получении IP-пакета сетевое устройство сначала проверяет IP-адрес назначения в заголовке пакета, затем использует таблицу маршрутизации, чтобы найти следующий узел (следующий переход), необходимый для передачи пакета, и доставляет пакет этому узлу. Если маршрутизатор не может доставить пакет следующему узлу, пакет будет отброшен. Каждый узел проверяет значение TTL пакета и уменьшает его на единицу. Если значение TTL становится равным 0, пакет отбрасывается, чтобы предотвратить его зацикливание в сети.
// Декодирование IP-пакетов, уровень IP находится ниже уровня канала передачи данных, При декодировании требуется значение смещения +14. Пропустите уровень канала передачи данных.
void PrintIPHeader(const u_char * packetData)
{
typedef struct ip_header
{
char version : 4;
char headerlength : 4;
char cTOS;
unsigned short totla_length;
unsigned short identification;
unsigned short flags_offset;
char time_to_live;
char Protocol;
unsigned short check_sum;
unsigned int SrcAddr;
unsigned int DstAddr;
}ip_header;
struct ip_header *ip_protocol;
// +14 Пропустить уровень канала передачи данных
ip_protocol = (struct ip_header *)(packetData + 14);
SOCKADDR_IN Src_Addr, Dst_Addr = { 0 };
u_short check_sum = ntohs(ip_protocol->check_sum);
int ttl = ip_protocol->time_to_live;
int proto = ip_protocol->Protocol;
Src_Addr.sin_addr.s_addr = ip_protocol->SrcAddr;
Dst_Addr.sin_addr.s_addr = ip_protocol->DstAddr;
printf("Исходный адрес: %15s --> ", inet_ntoa(Src_Addr.sin_addr));
printf("адрес назначения: %15s --> ", inet_ntoa(Dst_Addr.sin_addr));
printf("Контрольная сумма: %5X --> TTL: %4d --> Тип соглашения: ", check_sum, ttl);
switch (ip_protocol->Protocol)
{
case 1: printf("ICMP \n"); break;
case 2: printf("IGMP \n"); break;
case 6: printf("TCP \n"); break;
case 17: printf("UDP \n"); break;
case 89: printf("OSPF \n"); break;
default: printf("None \n"); break;
}
}
Анализ пакетов уровня IP может быть более сложным.,потому чтоIP
В верхней части соглашения может содержатьсяICMP,IGMP,TCP,UDP,OSPF
Ожидание соглашения,После запуска программы читатели увидят конкретную информацию, как показано на рисунке ниже;
Пакет уровня TCP (протокол управления передачей) — это четвертый уровень в стеке протоколов TCP/IP (протокол управления передачей/протокол Интернета). Он состоит из двух частей: TCP-заголовка и части данных.
Заголовки TCP обычно включают следующее:
TCP — это протокол, ориентированный на соединение, поэтому перед отправкой данных TCP сначала устанавливает соединение между отправителем и получателем. Процесс установления соединения включает в себя трехэтапный процесс установления связи, при котором клиент инициирует запрос на соединение, сервер отправляет обратно подтверждение, а клиент отправляет подтверждение еще раз. После завершения соединения протокол TCP контролирует порядок передачи и достоверность пакетов данных (например, сообщений подтверждения и повторной передачи сообщений ACK) на основе номера подтверждения и порядкового номера для обеспечения эффективных услуг передачи данных.
Когда пакет TCP достигает целевого устройства, уровень TCP повторно соберет данные TCP на принимающей стороне, разделит сообщение TCP на более мелкие фрагменты данных, которые могут использоваться уровнем приложения, и отправит их целевому приложению. Если отправленный пакет данных протокола TCP не получен правильно, протокол TCP повторит попытку отправки потерянного пакета данных, чтобы обеспечить целостность и правильность данных.
//Декодируем TCP-пакеты,Нужно сначала добавить14Пропустить уровень канала передачи данных, Затем добавьте 20, чтобы пропустить уровень IP.
void PrintTCPHeader(const unsigned char * packetData)
{
typedef struct tcp_header
{
short SourPort; // Номер исходного порта 16 бит
short DestPort; // Номер порта назначения 16 бит.
unsigned int SequNum; // Серийный номер 32бит.
unsigned int AcknowledgeNum; // Номер подтверждения 32бит
unsigned char reserved : 4, offset : 4; // зарезервированное смещение
unsigned char flags; // логотип
short WindowSize; // Размер окна 16бит.
short CheckSum; // Контрольная сумма 16 бит
short surgentPointer; // Срочное смещение данных 16 бит
}tcp_header;
struct tcp_header *tcp_protocol;
// +14 Пропустить уровень канала передачи данных +20 Пропустить уровень IP
tcp_protocol = (struct tcp_header *)(packetData + 14 + 20);
u_short sport = ntohs(tcp_protocol->SourPort);
u_short dport = ntohs(tcp_protocol->DestPort);
int window = tcp_protocol->WindowSize;
int flags = tcp_protocol->flags;
printf("Исходный порт: %6d --> Порт назначения: %6d --> Размер окна: %7d --> логотип: (%d)",
sport, dport, window, flags);
if (flags & 0x08) printf("PSH Передача данных\n");
else if (flags & 0x10) printf("ACK Ответ\n");
else if (flags & 0x02) printf("SYN Установить соединение\n");
else if (flags & 0x20) printf("URG \n");
else if (flags & 0x01) printf("FIN Закройте соединение\n");
else if (flags & 0x04) printf("RST Сброс соединения\n");
else printf("None Неизвестно\n");
}
Анализ TCP также более сложен.,Это связано с тем, что протокол TCP имеет несколько значений состояния.,нравитьсяPSH、ACK、SYN、URG、FIN
иRST
ЭтоTCP
Используется в сегменте сообщениялоготипдругая информацияилистатуслоготип Кусочек。ЭтиTCPлоготип Кусочекзначениеследующее:
Установка и использование этих битов флага может помочь TCP надежно взаимодействовать между уровнем приложений и сетевым уровнем, гарантируя, что передача данных, а также установление и закрытие соединения могут быть выполнены правильно. Наш инструмент также может анализировать эти различные состояния битов флага, как показано ниже. показано на рисунке;
Пакет уровня UDP (протокол пользовательских дейтаграмм) — это четвертый уровень в стеке протоколов TCP/IP (протокол управления передачей/Интернет-протокол). Он проще, чем TCP, и не гарантирует местонахождение и достоверность пакетов данных, а также не устанавливает и не поддерживает соединение. Пакеты UDP содержат только заголовок UDP и части данных.
Заголовок UDP включает в себя следующее:
Преимуществами протокола UDP являются небольшие накладные расходы на передачу, высокая скорость и низкая задержка, поскольку он не выполняет проверку ошибок при высокой нагрузке, а также не устанавливает и не поддерживает соединение. Но это также означает, что передача пакетов данных ненадежна и целостность и правильность передачи данных не гарантируется. Если пакет UDP получен неправильно, попытка повторно отправить потерянный пакет предприниматься не будет. UDP часто используется для приложений, которым требуется быстрота, простота и низкая задержка, например онлайн-игры, потоковое видео и аудио и т. д.
// Уровень UDP точно такой же, как уровень TCP, за исключением небольшой разницы в определении и распаковке структуры.
void PrintUDPHeader(const unsigned char * packetData)
{
typedef struct udp_header
{
uint32_t sport; // исходный порт
uint32_t dport; // целевой порт
uint8_t zero; // Зарезервированный бит
uint8_t proto; // идентификатор протокола
uint16_t datalen; // Длина данных UDP
}udp_header;
struct udp_header *udp_protocol;
// +14 Пропустить уровень канала передачи данных +20 Пропустить уровень IP
udp_protocol = (struct udp_header *)(packetData + 14 + 20);
u_short sport = ntohs(udp_protocol->sport);
u_short dport = ntohs(udp_protocol->dport);
u_short datalen = ntohs(udp_protocol->datalen);
printf("Исходный порт: %5d --> Порт назначения: %5d --> размер: %5d \n", sport, dport, datalen);
}
Анализ протокола UDP становится очень простым. Поскольку UDP является протоколом без сохранения состояния, можно получить только порт источника и порт назначения. Результат анализа показан на рисунке ниже.
Пакеты уровня ICMP (Протокол управляющих сообщений Интернета) являются третьим уровнем в стеке протоколов TCP/IP. Это протокол управления, используемый для отчетов об ошибках и запроса состояния сети в сетевых коммуникациях. Пакеты ICMP обычно не несут никаких данных приложения или полезной нагрузки.
Пакеты ICMP обычно включают в себя следующие типы управляющей информации:
Пакеты ICMP также используются для других целей, таких как обнаружение прослушивателя многоадресной рассылки (MLD) и протокол обнаружения соседей (NDP), которые используются в многоадресной рассылке и сетевых соединениях IPv6.
Датаграммы ICMP обычно автоматически генерируются операционной системой или сетевым устройством и отправляются непосредственно в операционную систему или сетевое устройство. Затем их можно обнаружить и диагностировать с помощью инструментов сетевого анализа для выявления ошибок или сбоев в сети.
//Декодируем ICMP-пакеты,существовать解包дануждатьсятакой женуждаться Пропустить уровень канала передачи данныхиIPслой, Затем выполните анализ по номеру типа ICMP, Обычно используемый номер типа — `type 8`Он представляет собой временную метку отправки и получения пакетов.
void PrintICMPHeader(const unsigned char * packetData)
{
typedef struct icmp_header {
uint8_t type; // Тип ICMP
uint8_t code; // код
uint16_t checksum; // Контрольная сумма
uint16_t identification; // логотип
uint16_t sequence; // серийный номер
uint32_t init_time; // Временная метка начала
uint16_t recv_time; // принять временную метку
uint16_t send_time; // Временная метка передачи
}icmp_header;
struct icmp_header *icmp_protocol;
// +14 Пропустить уровень канала передачи данных +20 Пропустить уровень IP
icmp_protocol = (struct icmp_header *)(packetData + 14 + 20);
int type = icmp_protocol->type;
int init_time = icmp_protocol->init_time;
int send_time = icmp_protocol->send_time;
int recv_time = icmp_protocol->recv_time;
if (type == 8)
{
printf("Временная метка начала: %d --> Временная метка передачи: %d --> Получить временную метку: %d направление: ",
init_time, send_time, recv_time);
switch (type)
{
case 0: printf("Эхо-ответное сообщение \n"); break;
case 8: printf("Сообщение эхо-запроса \n"); break;
default:break;
}
}
}
Анализ протокола ICMP также очень прост. При перехвате пакетов мы можем получить только некоторую базовую информацию, такую как метка времени отправки, метка времени передачи, метка времени получения и направление сообщения. Здесь есть два направления: 0 представляет эхо-ответ. в то время как 8 представляет эхо-запрос. Конкретные выходные данные следующие:
Пакет уровня HTTP (протокол передачи гипертекста) — это седьмой уровень в стеке протоколов TCP/IP. Он в основном используется для передачи данных между клиентом и сервером в веб-приложениях. HTTP-пакеты обычно состоят из двух частей: HTTP-заголовка и части данных.
Заголовки HTTP обычно включают следующее:
Протокол HTTP работает следующим образом: клиент отправляет HTTP-запрос на сервер, а сервер возвращает результат запроса через HTTP-ответ. HTTP-запросы обычно используют методы HTTP, такие как GET, POST, PUT, DELETE и т. д., для управления типом и поведением операций HTTP. Ответы HTTP обычно содержат коды состояния HTTP, например 200, 404, 500 и т. д., чтобы указать состояние результатов запроса клиента.
В реальной сетевой связи формат и содержимое пакетов уровня HTTP обычно генерируются и анализируются приложениями или сетевыми устройствами, такими как веб-браузеры и веб-серверы.
// Декодируем HTTP-пакет,нуждаться Пропустить уровень канала передачи данных, Уровень IP и уровень TCP, Наконец, вы можете получить заголовок протокола HTTP-пакета.
void PrintHttpHeader(const unsigned char * packetData)
{
typedef struct tcp_port
{
unsigned short sport;
unsigned short dport;
}tcp_port;
typedef struct http_header
{
char url[512];
}http_header;
struct tcp_port *tcp_protocol;
struct http_header *http_protocol;
tcp_protocol = (struct tcp_port *)(packetData + 14 + 20);
int tcp_sport = ntohs(tcp_protocol->sport);
int tcp_dport = ntohs(tcp_protocol->dport);
if (tcp_sport == 80 || tcp_dport == 80)
{
// +14 Пропустить MAC-уровень +20 Пропустить уровень IP +20 Пропустить уровень TCP
http_protocol = (struct http_header *)(packetData + 14 + 20 + 20);
printf("%s \n", http_protocol->url);
}
}
Протокол HTTP также можно проанализировать, но поскольку протокол HTTP используется редко, этот код можно только продемонстрировать. В реальном бою обычно используется HTTPS. Ниже приведен пакет данных, перехваченный во время доступа по HTTP;
Пакеты уровня ARP (протокола разрешения адресов) являются вторым уровнем в стеке протоколов TCP/IP. Протокол ARP в основном используется для сопоставления адресов сетевого уровня (например, IP-адресов) с адресами канального уровня (например, MAC-адресами).
Пакеты ARP обычно включают в себя следующее:
Рабочий процесс протокола ARP выглядит следующим образом:
Основная задача протокола ARP — реализовать сопоставление адресов в локальной сети, что в основном включает в себя определение MAC-адреса какого устройства связан с конкретным IP-адресом и ответ на запросы сопоставления, которые преобразуют IP-адреса в соответствующие MAC-адреса. ARP обычно используется в сетях Ethernet и Wi-Fi для обеспечения связи устройств внутри локальной сети.
// Декодировать ARP-пакеты
void PrintArpHeader(const unsigned char * packetData)
{
typedef struct arp_header
{
uint16_t arp_hardware_type;
uint16_t arp_protocol_type;
uint8_t arp_hardware_length;
uint8_t arp_protocol_length;
uint16_t arp_operation_code;
uint8_t arp_source_ethernet_address[6];
uint8_t arp_source_ip_address[4];
uint8_t arp_destination_ethernet_address[6];
uint8_t arp_destination_ip_address[4];
}arp_header;
struct arp_header *arp_protocol;
arp_protocol = (struct arp_header *)(packetData + 14);
u_short hardware_type = ntohs(arp_protocol->arp_hardware_type);
u_short protocol_type = ntohs(arp_protocol->arp_protocol_type);
int arp_hardware_length = arp_protocol->arp_hardware_length;
int arp_protocol_length = arp_protocol->arp_protocol_length;
u_short operation_code = ntohs(arp_protocol->arp_operation_code);
// Определите, является ли это пакетом запроса ARP.
if (arp_hardware_length == 6 && arp_protocol_length == 4)
{
printf("Исходный MAC-адрес: ");
for (int x = 0; x < 6; x++)
printf("%x:", arp_protocol->arp_source_ethernet_address[x]);
printf(" --> ");
printf("MAC-адрес назначения: ");
for (int x = 0; x < 6; x++)
printf("%x:", arp_protocol->arp_destination_ethernet_address[x]);
printf(" --> ");
switch (operation_code)
{
case 1: printf("ARP просить \n"); break;
case 2: printf("ARP отвечать \n"); break;
case 3: printf("RARP просить \n"); break;
case 4: printf("RARP отвечать \n"); break;
default: break;
}
}
}
Также возможен анализ протокола ARP.,Протокол ARP также имеет несколько состояний.,в целом1-2
представлятьпроситьиотвечать,3-4
представлятьRARPобеспечить регресспроситьиотвечать,Из-за короткого периода срабатывания протокола ARP считыватели редко могут захватывать данные этого типа.,Как показано на рисунке ниже, считыватель фиксирует полный статус протокола ARP;
Автор статьи: Ван Жуй
Ссылка на эту статью: https://www.lyshark.com/post/526b8a6.html
Заявление об авторских правах: если не указано иное, все статьи в этом блоге лицензируются по лицензии BY-NC-SA. При перепечатке просьба указывать источник!