【问题标题】:'pcap_loop' is not recording packets and isn't even running'pcap_loop' 没有记录数据包,甚至没有运行
【发布时间】:2015-06-28 03:03:59
【问题描述】:

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

【问题讨论】:

    标签: c++ pcap packet-sniffers winpcap sniffing


    【解决方案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,它成功 em>。

    如果返回值为负,则为错误值,失败。如果它非零但为正,则为警告值;它已经成功,但是,例如,它可能没有打开混杂模式,因为操作系统或设备可能不允许设置混杂模式。

    所以你想要的是:

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

    【讨论】:

    • 我应该更加关注文档。在检查 pcap_activate 的成功时,这是一个很大的错误。谢谢
    猜你喜欢
    • 2021-05-20
    • 1970-01-01
    • 2021-07-23
    • 2016-03-02
    • 2014-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多