使用Pcap监听超时

xyz*_*yzt 2 c linux pcap

我想在Linux上使用C语言编写一个小应用程序.

目前,它开始嗅探并等待数据包.但这不是我真正需要的.我希望它等待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);
}
Run Code Online (Sandbox Code Playgroud)

lem*_*eze 6

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);
}
Run Code Online (Sandbox Code Playgroud)

注意:至于使用libpcap的读取超时来执行此操作,它将不会也无法工作,man pcap明确警告它:

读取超时不能用于使读取数据包的调用在有限的时间内返回[...]这意味着不应使用读取超时,例如,在交互式应用程序中允许数据包捕获循环定期轮询用户输入,因为即使没有数据包到达,也无法保证在超时到期后呼叫读取数据包将返回.