最近在开发someip 的测试工具,手动测试的时候通过wireshark 来抓取网络中的数据,在工具的自动化测试中希望可以保存网卡中的数据来进行分析使用。
QT中使用Npcap lib 需要下载sdk 包和npcap 安装包。
Npcap: Windows Packet Capture Library & Driver
安装包直接下载后安装好就可以,相关的dll 会安装在系统文件夹下面
SDK 文件夹是里面我们会用到lib 和include 两个文件夹中的内容
现在我们需要在自己的QT Project 中添加相关的头文件和lib:
我在自己的工程文件下有一个include /npcap 文件夹,把lib和include copy到里面 然后在QT的 .pro
文件中添加头文件和lib的路径。
INCLUDEPATH += $$PWD/include/npcap/Include \
$$PWD/include/npcap/Include/pcap
LIBS += -L$$PWD/include/npcap/Lib/x64/ -lwpcap -lPacket
LIBS += -lws2_32
然后我们可以按照example 中的例子来使用相关的API 函数实现自己的功能。
首先需要设置dll 的路径
bool npcap::LoadNpcapDlls()
{
_TCHAR npcap_dir[512];
u_int len;
len = GetSystemDirectory(npcap_dir, 480);
if (!len) {
LOG(ERROR)<<"Error in GetSystemDirectory: %x", GetLastError();
return FALSE;
}
_tcscat_s(npcap_dir,_T("\\Npcap"));
if (SetDllDirectory(npcap_dir) == 0) {
LOG(ERROR)<<"Error in SetDllDirectory: %x", GetLastError();
return FALSE;
}
return true;
}
然后去。查找本机上的网卡:
/* Retrieve the device list from the local machine */
if (pcap_findalldevs(&alldevs, errbuf) == -1)
{
// fprintf(stderr, "Error in pcap_findalldevs_ex: %s\n", errbuf);
LOG(ERROR)<<"Error in pcap_findalldevs_ex: %s\n", errbuf;
return false;
}
/* Print the list */
i=0;
for (d = alldevs; d != NULL; d = d->next)
{
printf("%d. %s", ++i, d->name);
// std::cout<<d->name;
if (d->description)
{
printf(" (%s)\n", d->description);
LOG(INFO)<<d->name <<" "<<d->description;
}
else
printf(" (No description available)\n");
}
if (i == 0)
{
LOG(ERROR)<<"No interfaces found! Make sure Npcap is installed.";
return false;
}
LOG(INFO)<<"EVERTHING IS OK";
log中显示的设备如下:
1. \Device\NPF_{6D1563EB-50E0-4120-8037-CCE642522B73} (Microsoft)
2. \Device\NPF_{9A940057-B2C2-4980-9170-886634C36850} (Microsoft)
3. \Device\NPF_{F95E1AB6-8332-4E32-84A3-814F0059022E} (TAP-Windows Adapter V9)
4. \Device\NPF_{DBDA1639-0D88-4DC4-A7AA-7DC7DCE89ABA} (Microsoft)
5. \Device\NPF_{081972C6-8EEF-4867-9D7B-EDC7D7403648} (Realtek PCIe GbE Family Controller)
6. \Device\NPF_{215630E1-4D9D-45B7-B69F-99E76F815248} (Microsoft)
再就是打开设备:
/* Open the adapter */
if ((adhandle= pcap_open_live(d->name, // name of the device
65536, // portion of the packet to capture.
// 65536 grants that the whole packet will be captured on all the MACs.
1, // promiscuous mode (nonzero means promiscuous)
1000, // read timeout
errbuf // error buffer
)) == NULL)
{
fprintf(stderr,"\nUnable to open the adapter. %s is not supported by Npcap\n", d->name);
/* Free the device list */
pcap_freealldevs(alldevs);
return false;
}
可以将抓取的数据保存到相关的文件中:
/* Open the dump file */
dumpfile = pcap_dump_open(adhandle, logFolder);
if(dumpfile==NULL)
{
fprintf(stderr,"\nError opening output file\n");
return false;
}
然后开始抓取数据:
/* start the capture */
pcap_loop(adhandle, 0, packet_handler, (unsigned char *)dumpfile);
停止抓取:
pcap_breakloop(adhandle);
pcap_dump_close(dumpfile);
pcap_close(adhandle);
以上就是使用npcap的一个简单过程,一些其它的用法可以参考sdk 里面的范例。