如何使用 pcap 从多个接口捕获流量

发布于 2024-12-12 16:49:09 字数 441 浏览 5 评论 0原文

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

这是否足够或者是否需要考虑一些特定的警告?

In order to sniff from multiple interfaces using pcap, I would do the following (in pseudocode):

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

Is this enough or are there some particular caveats to take into account ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

长发绾君心 2024-12-19 16:49:10

这是一个小的 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

Here is small C-Program snippet to use PCAP library to capture (sniff) network packets in promiscus (stealth) mode in the network.

#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

慢慢从新开始 2024-12-19 16:49:10

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

对 libcap (pcap) 和无线感到困惑

I ran into some issues trying to capture from particular interfaces with pcap and asked about it here. It seemed few were familiar with pcap. My issues, and an answer I finally got pointing out very helpful details, can be found here in the below link which you might find useful:

Confused by libcap (pcap) and wireless

吃不饱 2024-12-19 16:49:10

pcap_open_live(3) 的手册页显示:

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

答案在最后一行。

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

Man page of pcap_open_live(3) says:

pcap_open_live() is used to obtain a packet capture handle to look at
packets on the network. device is a string that specifies the network
device to open; on Linux systems with 2.2 or later kernels, a device
argument of "any" or NULL can be used to capture packets from all
interfaces.

The answer is in the last line.

So, use "any" or NULL in device parameter of pcap_open_live() call to capture from all interfaces.

暮年 2024-12-19 16:49:10

要从多个网络接口捕获数据包,您需要调用 fork() 新子进程,然后执行 pcap_lookupnet()pcap_open_live()

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

To capture packets from multiple network interfaces you need to call fork() new child process and then do pcap_lookupnet() and then pcap_open_live().

Note: You cannot use thread instead of create child process for each network interface.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文