我想在 Linux 上使用 C 中的 Libpcap 编写一个小型应用程序。
目前,它开始嗅探并等待数据包。但这并不是我真正需要的。我希望它等待 N 秒然后停止收听。
我怎样才能做到这一点?
这是我的代码:
void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet)
{
printf("got packet\n);
}
int main()
{
int ret = 0;
char *dev = NULL; /* capture device name */
char errbuf[PCAP_ERRBUF_SIZE]; /* error buffer */
pcap_t *handle; /* packet capture handle */
char filter_exp[] = "udp dst port 1500"; /* filter expression */
struct bpf_program fp; /* compiled filter program (expression) */
bpf_u_int32 mask; /* subnet mask */
bpf_u_int32 net; /* ip */
int num_packets = 10; /* number of packets to capture */
/* get network number and mask associated with capture device */
if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) {
fprintf(stderr, "Couldn't get netmask for device %s: %s\n",
dev, errbuf);
net = 0;
mask = 0;
}
/* print capture info */
printf("Device: %s\n", dev);
printf("Number of packets: %d\n", num_packets);
printf("Filter expression: %s\n", filter_exp);
/* open capture device */
handle = pcap_open_live(dev, SNAP_LEN, 1, 1000, errbuf);
if (handle == NULL) {
fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
exit(EXIT_FAILURE);
}
/* compile the filter expression */
if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) {
fprintf(stderr, "Couldn't parse filter %s: %s\n",
filter_exp, pcap_geterr(handle));
exit(EXIT_FAILURE);
}
/* apply the compiled filter */
if (pcap_setfilter(handle, &fp) == -1) {
fprintf(stderr, "Couldn't install filter %s: %s\n",
filter_exp, pcap_geterr(handle));
exit(EXIT_FAILURE);
}
/* now we can set our callback function */
pcap_loop(handle, num_packets, got_packet, NULL);
/* cleanup */
pcap_freecode(&fp);
pcap_close(handle);
}
最佳答案
当你想停止监听时,你应该调用 pcap_breakloop()
。所以一种方法是:
- 设置在 N 秒内触发的警报,
- 为
SIGALRM
信号安装一个信号处理器, - 在处理程序中调用
pcap_breakloop()
使pcap_loop()
返回。
代码:
void alarm_handler(int sig)
{
pcap_breakloop(handle);
}
int main()
{
...
alarm(N);
signal(SIGALRM, alarm_handler);
/* now we can set our callback function */
pcap_loop(handle, num_packets, got_packet, NULL);
/* cleanup */
pcap_freecode(&fp);
pcap_close(handle);
}
注意:至于使用 libpcap 的读取超时来执行此操作,它不会也不能工作,man pcap 明确警告不要这样做:
The read timeout cannot be used to cause calls that read packets to return within a limited period of time [...] This means that the read timeout should NOT be used, for example, in an interactive application to allow the packet capture loop to poll for user input periodically, as there's no guarantee that a call reading packets will return after the timeout expires even if no packets have arrived.
关于c - 使用带超时的 Pcap 收听,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4583386/