C - pcap 在嗅探来自所有接口的数据包时不起作用("any")
C - pcap does not work when sniffing packets from all interfaces (with "any")
我正在尝试用 C 编写一个数据包嗅探器。这个程序应该从所有可用接口(eth0...等)捕获所有传入的 LLDP 数据包(lldp 对于这个问题并不重要)。当我在 dev 变量中指定一个接口时,该程序工作得很好,但当我试图一次从所有接口捕获时,该程序不起作用。 (程序没有显示任何内容,尽管我可以看到 Linux 中有一些使用 Tcpdump 命令的数据包)。
在 pcap_open_live ( https://www.tcpdump.org/manpages/pcap_open_live.3pcap.html ) 的手册页中,它确实说每当你想从所有接口捕获数据包时,你应该更改第一个NULL 或 "any" 的参数,所以我将 dev(带有接口名称的变量)更改为 "any “ 并期望该程序可以运行,但它没有..它没有给我任何错误,但它似乎无法捕获任何数据包...
我想我做错了什么,所以我会感谢任何帮助并提前致谢。
顺便说一句:提到的手册页指出 Linux 内核应该是 2.2 版或更高版本,我检查过这是真的(4.19 版)。
#include <pcap/pcap.h>
#include <stdlib.h>
void callback_func(u_char *args, const struct pcap_pkthdr* pkthdr, const u_char* packetData)
{
static int count = 1;
fprintf(stdout, "%3d, ", count);
fflush(stdout);
count++;
}
int main()
{
const char *dev = "any";
char errbuf[PCAP_ERRBUF_SIZE];
char lldp_filter_exp[] = "ether[12:2]=0x88cc";
pcap_t* descr;
const u_char *packetData;
struct pcap_pkthdr packetHeader;
struct bpf_program fp; /* hold compiled program */
/* open device for reading */
descr = pcap_open_live(dev, BUFSIZ, 0,-1, errbuf);
if(descr == NULL) {
fprintf(stderr, "Error calling pcap_open_live(): %s\n", errbuf);
exit(1);
}
pcap_setdirection(descr, PCAP_D_IN);
/* compile the filter expression*/
if(pcap_compile(descr, &fp, lldp_filter_exp, 0, PCAP_NETMASK_UNKNOWN) == PCAP_ERROR) {
fprintf(stderr, "Error calling pcap_compile\n");
exit(1);
}
/* set the filter */
if(pcap_setfilter(descr, &fp) == PCAP_ERROR) {
fprintf(stderr, "Error setting filter\n");
exit(1);
}
/* loop for callback function */
pcap_loop(descr, -1, callback_func, NULL);
return 0;
}
如果您过滤特定字节,过滤字符串应该是 "ether[12:2]==0x88cc"
。
然而,当你想过滤特定的以太类型时,我会使用 "ether proto 0x88cc"
。
这也适用于捕获设备“任何”。
我也很惊讶您的第一个过滤器字符串不适用于设备“任何”,因此我在特定设备以及设备“任何”上使用 wireshark 捕获了帧。
在设备“any”上捕获的帧使用不同的目标 MAC 地址,并且在以太网类型之前插入了两个零字节。这就是您的过滤器字符串不匹配的原因。
到目前为止,我没有在文档中找到针对设备“任何”捕获的特定帧格式的答案。
也许其他人可以阐明这一点。
帧特定设备:fc f8 ae 59 32 3d f0 c8 50 5b cc 3f 08 00 45 00
框架设备“任意”:00 00 00 01 00 06 f0 c8 50 5b cc 3f 00 00 08 00 45
我正在尝试用 C 编写一个数据包嗅探器。这个程序应该从所有可用接口(eth0...等)捕获所有传入的 LLDP 数据包(lldp 对于这个问题并不重要)。当我在 dev 变量中指定一个接口时,该程序工作得很好,但当我试图一次从所有接口捕获时,该程序不起作用。 (程序没有显示任何内容,尽管我可以看到 Linux 中有一些使用 Tcpdump 命令的数据包)。
在 pcap_open_live ( https://www.tcpdump.org/manpages/pcap_open_live.3pcap.html ) 的手册页中,它确实说每当你想从所有接口捕获数据包时,你应该更改第一个NULL 或 "any" 的参数,所以我将 dev(带有接口名称的变量)更改为 "any “ 并期望该程序可以运行,但它没有..它没有给我任何错误,但它似乎无法捕获任何数据包...
我想我做错了什么,所以我会感谢任何帮助并提前致谢。
顺便说一句:提到的手册页指出 Linux 内核应该是 2.2 版或更高版本,我检查过这是真的(4.19 版)。
#include <pcap/pcap.h>
#include <stdlib.h>
void callback_func(u_char *args, const struct pcap_pkthdr* pkthdr, const u_char* packetData)
{
static int count = 1;
fprintf(stdout, "%3d, ", count);
fflush(stdout);
count++;
}
int main()
{
const char *dev = "any";
char errbuf[PCAP_ERRBUF_SIZE];
char lldp_filter_exp[] = "ether[12:2]=0x88cc";
pcap_t* descr;
const u_char *packetData;
struct pcap_pkthdr packetHeader;
struct bpf_program fp; /* hold compiled program */
/* open device for reading */
descr = pcap_open_live(dev, BUFSIZ, 0,-1, errbuf);
if(descr == NULL) {
fprintf(stderr, "Error calling pcap_open_live(): %s\n", errbuf);
exit(1);
}
pcap_setdirection(descr, PCAP_D_IN);
/* compile the filter expression*/
if(pcap_compile(descr, &fp, lldp_filter_exp, 0, PCAP_NETMASK_UNKNOWN) == PCAP_ERROR) {
fprintf(stderr, "Error calling pcap_compile\n");
exit(1);
}
/* set the filter */
if(pcap_setfilter(descr, &fp) == PCAP_ERROR) {
fprintf(stderr, "Error setting filter\n");
exit(1);
}
/* loop for callback function */
pcap_loop(descr, -1, callback_func, NULL);
return 0;
}
如果您过滤特定字节,过滤字符串应该是 "ether[12:2]==0x88cc"
。
然而,当你想过滤特定的以太类型时,我会使用 "ether proto 0x88cc"
。
这也适用于捕获设备“任何”。
我也很惊讶您的第一个过滤器字符串不适用于设备“任何”,因此我在特定设备以及设备“任何”上使用 wireshark 捕获了帧。 在设备“any”上捕获的帧使用不同的目标 MAC 地址,并且在以太网类型之前插入了两个零字节。这就是您的过滤器字符串不匹配的原因。 到目前为止,我没有在文档中找到针对设备“任何”捕获的特定帧格式的答案。
也许其他人可以阐明这一点。
帧特定设备:fc f8 ae 59 32 3d f0 c8 50 5b cc 3f 08 00 45 00
框架设备“任意”:00 00 00 01 00 06 f0 c8 50 5b cc 3f 00 00 08 00 45