Я пытаюсь сделать несколько простых захватов пакетов с помощью pcap, и поэтому я создал дескриптор для прослушивания через eth0. Моя проблема с pcap_loop(handle, 10, myCallback, NULL);
строка в конце моего кода. Я пытаюсь использовать pcap_loop
,
Ожидаемый результат должен быть:
eth0
Activated!
1
2
3
...
10
Done processing packets!
На токовом выходе отсутствуют приращения:
eth0
Activated!
Done processing packets!
В настоящее время он просто пропускает «Готово обрабатывать пакеты!» и я понятия не имею, почему. Даже если он не переходит к обратному вызову, он все равно должен ожидать пакетов, поскольку для параметра; count (см. Документацию по pcap_loop) установлено значение 10.
#include <iostream>
#include <pcap.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
void myCallback(u_char *useless, const struct pcap_pkthdr* hdr, const u_char*packet){
static int count = 1;
std::cout <<count<<std::endl;
count ++;
}
int main(){
char errbuf[PCAP_ERRBUF_SIZE];
char * devName;
char* net;
char* mask;
const u_char*packet;
struct in_addr addr;
struct pcap_pkthdr hdr;
bpf_u_int32 netp;
bpf_u_int32 maskp;
pcap_if_t *devs;
pcap_findalldevs(&devs, errbuf);
devName = pcap_lookupdev(errbuf);
std::cout <<devName<<std::endl;
int success = pcap_lookupnet(devName, &netp, &maskp, errbuf);
if(success<0){
exit(EXIT_FAILURE);
}
pcap_freealldevs(devs);
//Create a handle
pcap_t *handle = pcap_create(devName, errbuf);
pcap_set_promisc(handle, 1);
pcap_can_set_rfmon(handle);
//Activate the handle
if(pcap_activate(handle)){
std::cout <<"Activated!"<<std::endl;
}
else{
exit(EXIT_FAILURE);
}
pcap_loop(handle, 10, myCallback, NULL);
std::cout <<"Done processing packets!"<<std::endl;
//close handle
pcap_close(handle);
}
pcap_findalldevs(&devs, errbuf);
Этот звонок не делает ничего полезного, так как вы ничего не делаете с devs
кроме освобождения. (Вы также не проверяете, успешно ли это происходит или нет). Вы можете также удалить его, если у вас нет необходимости знать, что все устройства, на которых вы можете захватить.
pcap_can_set_rfmon(handle);
Это все не делает ничего полезного, так как вы не проверяете его возвращаемое значение. Если вы снимаете на устройстве Wi-Fi и хотите сделать снимок в режиме монитора, вы звоните pcap_set_rfmon()
— нет pcap_can_set_rfmon()
— на ручке после создания и перед активацией ручки.
//Activate the handle if(pcap_activate(handle)){ std::cout <<"Activated!"<<std::endl; } else{ exit(EXIT_FAILURE); }
Процитировать pcap_activate()
справочная страница:
RETURN VALUE
pcap_activate() returns 0 on success without warnings, PCAP_WARN-
ING_PROMISC_NOTSUP on success on a device that doesn't support promis-
cuous mode if promiscuous mode was requested, PCAP_WARNING on success
with any other warning, PCAP_ERROR_ACTIVATED if the handle has already
been activated, PCAP_ERROR_NO_SUCH_DEVICE if the capture source speci-
fied when the handle was created doesn't exist, PCAP_ERROR_PERM_DENIED
if the process doesn't have permission to open the capture source,
PCAP_ERROR_RFMON_NOTSUP if monitor mode was specified but the capture
source doesn't support monitor mode, PCAP_ERROR_IFACE_NOT_UP if the
capture source is not up, and PCAP_ERROR if another error occurred. If
PCAP_WARNING or PCAP_ERROR is returned, pcap_geterr() or pcap_perror()
may be called with p as an argument to fetch or display a message
describing the warning or error. If PCAP_WARNING_PROMISC_NOTSUP,
PCAP_ERROR_NO_SUCH_DEVICE, or PCAP_ERROR_PERM_DENIED is returned,
pcap_geterr() or pcap_perror() may be called with p as an argument to
fetch or display an message giving additional details about the problem
that might be useful for debugging the problem if it's unexpected.
Это означает, что приведенный выше код на 100% неверен — если pcap_activate()
возвращает ненулевое значение, может иметь не удалось, и если он возвращает 0, это удалось.
Если возвращаемое значение отрицательное, это значение ошибки, и оно не удалось. Если оно ненулевое, но положительное, это значение предупреждения; это удалось, но, например, возможно, он не включил случайный режим, так как ОС или устройство могут не разрешить устанавливать случайный режим.
Итак, что вы хотите, это:
//Activate the handle
int status;
status = pcap_activate(handle);
if(status >= 0){
if(status == PCAP_WARNING){
// warning
std:cout << "Activated, with warning: " << pcap_geterror(handle) << std::endl;
}
else if (status != 0){
// warning
std:cout << "Activated, with warning: " << pcap_statustostr(status) << std::endl;
}
else{
// no warning
std::cout <<"Activated!"<<std::endl;
}
}
else{
if(status == PCAP_ERROR){
std:cout << "Failed to activate: " << pcap_geterror(handle) << std::endl;
}
else{
std:cout << "Failed to activate: " << pcap_statustostr(status) << std::endl;
}
exit(EXIT_FAILURE);
}