'pcap_loop' 没有记录数据包,甚至没有 运行

'pcap_loop' is not recording packets and isn't even running

我正在尝试使用 pcap 进行一些简单的数据包捕获,因此我创建了一个句柄来通过 eth0 进行侦听。我的问题是代码末尾附近的 pcap_loop(handle, 10, myCallback, NULL); 行。我正在尝试使用 pcap_loop。 预期输出应该是:

eth0
Activated!
1
2
3
...
10
Done processing packets!

当前输出缺少增量:

eth0
Activated!
Done processing packets!

目前它只是直接跳到 "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);

That call isn't doing anything useful, as you're not doing anything with devs other than freeing it. (You also aren't checking whether it succeeds or fails.) You might as well remove it unless you have some need to know what all the devices on which you can capture are.

pcap_can_set_rfmon(handle);

That all isn't doing anything useful, as you're not checking its return value. If you are capturing on a Wi-Fi device, and you want to capture in monitor mode, you call pcap_set_rfmon() - not pcap_can_set_rfmon() - on the handle after creating and before activating the handle.

//Activate the handle
if(pcap_activate(handle)){
    std::cout <<"Activated!"<<std::endl;
}
else{
    exit(EXIT_FAILURE);
}

To quote the pcap_activate() man page:

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.

This means that the code above is 100% wrong - if pcap_activate() returns a non-zero value, it may have failed, and if it returns 0, it succeeded.

If the return value is negative, it's an error value, and it has failed. If it's non-zero but positive, it's a warning value; it has succeeded, but, for example, it might not have turned promiscuous mode on, as the OS or device might not let promiscuous mode be set.

So what you want is, instead:

//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);
}