'pcap_loop' не записывает пакеты и даже не работает

Я пытаюсь сделать простой захват пакетов с помощью 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);
    }

person Jon Tan    schedule 28.06.2015    source источник


Ответы (1)


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);
}
person Community    schedule 28.06.2015
comment
Я должен был уделять больше внимания документации. Это было довольно большой ошибкой при проверке успеха pcap_activate. Спасибо - person Jon Tan; 28.06.2015