【问题标题】:How to capture traffic from multiple interfaces using pcap如何使用 pcap 从多个接口捕获流量
【发布时间】:2011-12-16 13:13:15
【问题描述】:

为了使用 pcap 从多个接口中嗅探,我会执行以下操作(在伪代码中):

foreach interface:
    open a file descriptor using pcap_open_live()
    set the file descriptor to non-blocking

while true:
    check for a ready file descriptor using select() or an equivalent I/O multiplexer
    read data from every ready file descriptor using pcap_dispatch()
    handle EndOfStream or Errors and break out of loop if needed

这是否足够或有一些特别的注意事项需要考虑?

【问题讨论】:

    标签: c linux interface pcap


    【解决方案1】:

    我在尝试使用 pcap 从特定接口捕获时遇到了一些问题,并在此处询问。似乎很少有人熟悉 pcap。我的问题以及我最终得到的答案指出了非常有用的细节,可以在下面的链接中找到,您可能会发现它很有用:

    Confused by libcap (pcap) and wireless

    【讨论】:

    • 这并没有解决同时从一组接口进行嗅探的问题,但是 select() (正如你提到的)应该像往常一样处理。
    【解决方案2】:

    要从多个网络接口捕获数据包,您需要调用fork() new child process,然后调用pcap_lookupnet(),然后调用pcap_open_live()

    注意:您不能使用线程代替为每个网络接口创建子进程。

    【讨论】:

      【解决方案3】:

      这是一个小 C 程序 sn-p 使用 PCAP 库在网络中以混杂(隐身)模式捕获(嗅探)网络数据包。

      #include <stdio.h>
      #include <stdlib.h>
      #include <pcap.h>  /* GIMME a libpcap plz! */
      #include <errno.h>
      #include <sys/socket.h>
      #include <netinet/in.h>
      #include <arpa/inet.h>  
      
      void callback(u_char *useless,const struct pcap_pkthdr* pkthdr,const u_char* packet)
      {
        static int count = 1;
        printf("\nPacket number [%d], length of this packet is: %d\n", count++, pkthdr->len);
      }
      
      void pktinit(char *dev) /*function: for individual interface packet capturing*/
      {
          char errbuf[PCAP_ERRBUF_SIZE];
          pcap_t* descr;
          struct bpf_program fp;        /* to hold compiled program */
          bpf_u_int32 pMask;            /* subnet mask */
          bpf_u_int32 pNet;             /* ip address*/
          pcap_if_t *alldevs, *d;
          char dev_buff[64] = {0};
          int i =0;
          pcap_lookupnet(dev, &pNet, &pMask, errbuf);
          descr = pcap_open_live(dev, BUFSIZ, 0,-1, errbuf);
          if(descr == NULL)
          {
              printf("pcap_open_live() failed due to [%s]\n", errbuf);
              return -1;
          }
          return 0;
      }
      
      int main(int argc, char **argv)
      {
          int pid,i;
          if(argc < 2) /*command <eth0> [eth1]...*/
          {
              fprintf(strerr,"command needs ethernet name")
              return 0;
          }
          for(i = 1; i < argc; i++)
          {
              if((pid=fork()) != -1)
              {
                  pktinit(argv[i])
              }
              else
              {
                  fprintf(stderr,"pacp failed for: %s\n", argv[i]);
              }
          }
          return 0;
      }
      

      gcc 文件.c -lpcap

      ./file eth0 eth1 wlan0

      【讨论】:

        【解决方案4】:

        pcap_open_live(3) 的手册页说:

        pcap_open_live()用于获取抓包句柄查看 网络上的数据包。 device 是一个指定网络的字符串 打开装置;在具有 2.2 或更高版本内核的 Linux 系统上,设备 "any" 或 NULL 参数可用于捕获来自所有 接口。

        答案在最后一行。

        因此,在pcap_open_live() 调用的device 参数中使用"any"NULL 以从所有接口进行捕获。

        【讨论】:

        • 我认为问题在于从网络接口的子集中捕获。至少这是我阅读这个问题的情况。除非您也可以使用“en0|utun2”,否则 "any"/"null" 很遗憾没有帮助。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-10-29
        • 1970-01-01
        • 2011-01-31
        • 2012-12-14
        • 2020-02-23
        • 2020-10-03
        相关资源
        最近更新 更多