我正在尝试用 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
未设置任何值,因此它包含未知值。 如果那个值恰好指向内存中的一个位置,这样ifpcap_compile()
、pcap_setfilter()
和pcap_loop()
不会碰巧崩溃,然后它会看起来好像程序正在运行 - 但它不是。
所以你应该检查
pcap_open_live()
是否成功,如上例所示 - and 你应该检查 pcap_compile()
、pcap_setfilter()
和 pcap_loop()
是否也成功。
你应该注意到你调用的函数
pcap_open_live
的第一个参数是你的Linux的网络接口。所以你应该确保你的 Linux 有名为 eth3 的网络接口。你可以通过ifconfig -a
命令检查你的Linux的网络接口,如果你发现存在no接口名为eth3,那么它可能是问题所在。