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

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

本文关键字:运行 数据包 pcap 记录 loop      更新时间:2023-10-16

我正在尝试用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);
}