如何使用pcap捕获来自多个接口的流量

5
为了使用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

这个足够了,还是有一些特别的注意事项需要考虑吗?
4个回答

2
这是一个小的C程序片段,使用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 file.c -lpcap

./file eth0 eth1 wlan0


1

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

混淆于libcap(pcap)和无线


这并未针对同时从某一组接口进行嗅探,但是像你所提到的那样,select() 应该和往常一样处理它。 - gnometorule

0

pcap_open_live(3)的手册中写道:

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

答案在最后一行。

因此,在调用pcap_open_live()时,使用"any"NULL作为device参数即可从所有接口捕获数据。


我认为这个问题是关于从网络接口的子集中捕获的。至少在我阅读这个问题时是这样的。 "any" / "null" 不幸的是没有帮助,除非你也可以使用 "en0 | utun2"。 - Adrian Maire

-1
为了从多个网络接口捕获数据包,您需要调用fork()创建新的子进程,然后执行pcap_lookupnet()pcap_open_live()注意:您不能使用线程代替为每个网络接口创建子进程。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接