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