c - 使用带超时的 Pcap 收听

标签 c linux pcap

我想在 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/

相关文章:

c - 如何创建类似 printf 变量参数的函数

c - 尝试打印菜单名称,使用结构,控制台被绞死,但打印结果?

c - pcap_next() 将地址返回到不可访问的内存区域

c++ - pcap_dump() 仅对用户降低权限

C:错误嵌套的 switch/case block 出人意料地有效

无法使用 MinGW 在 Windows 上编译 GTK+ 程序

PHP 将 Linux 子系统路径转换为 ​​Windows 路径

c - 销毁进程树并释放它分配的所有内存-Linux-C

c++ - 什么是关于国际化和本地化的良好介绍和教程?

networking - 转换 pcap <-> pcap-ng, pcap-ng 工具/库