我试图嗅闻所有的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”,则会捕获数据包..有任何想法吗?
问候
答案 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使用的超时值。您也可以使用较低的值。