我正在尝试用 C 语言编写一个数据包嗅探程序,当我在成功编译后尝试运行该程序时,遇到了段错误。我试图通过注释掉一些代码并重新编译程序,然后重新运行程序的较小版本来确定导致程序出现段错误的确切代码行。这是我的代码。
void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet)
{
printf("Got a packet\n");
}
int main()
{
pcap_t *handle;
char errbuf[PCAP_ERRBUF_SIZE];
struct bpf_program fp;
char filter_exp[] = "ip proto icmp";
bpf_u_int32 net;
// Step 1: Open live pcap session on NIC with name eth3
handle = pcap_open_live("eth3", BUFSIZ, 1, 1000, errbuf);
// Step 2: Compile filter_exp into BPF psuedo-code
pcap_compile(handle, &fp, filter_exp, 0, net);
pcap_setfilter(handle, &fp);
// Step 3: Capture packets
pcap_loop(handle, -1, got_packet, NULL);
pcap_close(handle); //Close the handle
return 0;
}
注释掉代码并重新编译程序并重新运行程序后,我发现段错误发生在pcap_compile
行:
pcap_compile(handle, &fp, filter_exp, 0, net);
当我编译并运行一个程序,并将 handle
(第 1 步)行之后的所有内容都注释掉时,该程序运行时不会出现段错误,并且不会发生任何情况。一旦我通过使其在程序中处于事件状态来包含 pcap_compile
语句,程序就会出现段错误。有谁知道可能是什么问题,无论是 pcap_compile
调用还是其他问题?
最佳答案
Steffen Ullrich 在这里 100% 正确。
如果您要调用任何返回 pcap_t *
的例程,例如 pcap_open_live()
,您必须通过检查是否成功来检查是否成功它是否返回空指针:
handle = pcap_open_live("eth3", BUFSIZ, 1, 1000, errbuf);
if (handle != NULL) {
fprintf(stderr, "Can't open eth3: %s\n", errbuf);
exit(1);
}
如果它失败并返回一个空指针,那么当您将该空指针作为第一个参数传递给它时,pcap_compile()
- 和其他 libpcap 例程 - 将崩溃。
如果注释掉对 pcap_open_live()
的调用,则 handle
未设置为任何内容,因此它包含未知值。 如果该值碰巧指向内存中的某个位置,if pcap_compile()
, pcap_setfilter ()
和 pcap_loop()
不会发生崩溃,那么就会看起来程序正在运行 -但事实并非如此。
因此,您应该检查 pcap_open_live()
是否成功,如上面的示例 - 并且您应该检查 pcap_compile()
是否成功,pcap_setfilter()
和 pcap_loop()
也成功。
关于c - 使用 pcap 段错误进行数据包嗅探,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59943064/