WinPcap没有捕获任何arp数据包

时间:2014-08-14 17:54:13

标签: c network-programming libpcap arp winpcap

我试图嗅闻所有的arp流量。这是我的代码:

void start(){
    pcap_if_t *alldevs;
    pcap_if_t *d;
    char errbuf[PCAP_ERRBUF_SIZE];
    int choice;
    pcap_t* pcap_handle;
    struct bpf_program filter;
    int i=0;
    if(pcap_findalldevs(&alldevs, errbuf)==-1){
        fatal("pcap_findalldevs", errbuf);
        return;
    }
    d = alldevs;
    for(d=alldevs; d; d=d->next){
        cout<<"#"<<i<<" "<<d->name<<endl;
        if (d->description)
            cout<<"description: "<<d->description<<(d->addresses==NULL?" invalid":" valid")<<endl;
        ++i;
    }
    if(i==0){
        cout<<"No interfaces!"<<endl;
    }
    while(true){
        cout<<"choose interface number: ";
        cin>>choice;
        if(choice<0 || choice>i-1){
            cout<<"choice is out of range!"<<endl;
            pcap_freealldevs(alldevs);
            return;
        }
        d=alldevs;
        for(int j=0;j<choice;++j){
            d=d->next;
        }
        if(d->addresses==NULL)
            cout<<"device is invalid!"<<endl;
        else
            break;
        if(i==1){
            return;
        }
    }
    cout<<"@@@\tGuarding device #"<<choice<<" "<<d->name<<endl;
    pcap_handle = pcap_open_live(d->name, 65535, 1, 0, errbuf);
    pcap_freealldevs(alldevs);
    if(pcap_handle == NULL){
        fatal("pcap_open_live", errbuf);
        return;
    }
    unsigned int netmask=((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr;
    if(pcap_compile(pcap_handle, &filter, "arp", 1, netmask)<0){
        fatal("pcap_compile", errbuf);
        return;
    }
    if(pcap_setfilter(pcap_handle, &filter)<0){
        fatal("pcap_setfilter", errbuf);
        return;
    }
    pcap_loop(pcap_handle, 5, packet_handler, NULL);
    pcap_close(pcap_handle);
}

不幸的是,没有捕获到arp数据包(wireshark告诉我有arp流量!)。如果我将过滤器更改为“ip”,则会捕获数据包..有任何想法吗?

问候

1 个答案:

答案 0 :(得分:1)

我会将pcap_open_live()调用更改为

pcap_handle = pcap_open_live(d->name, 65535, 1, 1000, errbuf);

在包括Windows在内的多个平台上,机制libpcap / WinPcap在通过过滤器时使用缓冲区数据包,并且只在缓冲区填满或超时到期时才将数据包传递给应用程序;这样做是为了在一个内核 - >用户转换中提供多个数据包,以减少大量流量的数据包捕获开销。

您提供的超时值为0;在几个平台上,包括Windows,这意味着&#34;没有超时&#34;,因此在缓冲区填满之前,数据包不会被传递。 ARP数据包很小,缓冲区足够大,可能需要很多ARP数据包来填充它; ARP数据包也相对较少,因此可能需要很长时间才能有足够的ARP数据包到达以填满它。 IP数据包更大,有时更大,更频繁,因此缓冲区可能不会花费太长时间来填充。

超时值1000是超时1秒,因此数据包应该在一秒钟内显示;这是tcpdump使用的超时值。您也可以使用较低的值。