【问题标题】:pf_ring and libpcap if_index not returningpf_ring 和 libpcap if_index 没有返回
【发布时间】:2014-08-31 09:23:12
【问题描述】:

我最近一直在使用 pf_ring / libpcap。我从来没有使用 libpcap 或 pf_ring 开发过,所以请原谅这似乎是一个愚蠢的问题,因为网络编程对我来说是半新的......从广义上讲,我想要做的是访问 if_index 接收的数据包。我目前使用 pf_ring 使用“C”创建了一个简单的原始数据包嗅探器,如下所示:

#include <pcap.h>
#include <pfring.h>
#include <string.h>
#include <stdlib.h>

#define MAXBYTES2CAPTURE 2048


void processRingPacket(const struct pfring_pkthdr* pkthdr, const u_char* packet, const u_char *arg)
{
        int i=0, *counter = (int*)arg;

        printf("Packet Count: %d ", ++(*counter));
        printf("Received Packet Size: %d ", pkthdr->len);
        printf("ifIndex: %d ", pkthdr->extended_hdr.if_index);
        printf("Payload:\n");

        for(i=0; i < pkthdr->len; i++)
        {
            if(isprint(packet[i]))
            {
                    printf("%c ", packet[i]);
            }

            else
            {
                    printf(". ");
            }

            if((i % 16 == 0) && (i != 0) || (i == pkthdr->len-1))
            {
                    printf("\n");
            }
    }

    return;

}

int main()
{
    int count = 0;
    char *device = "eth0";  

    printf("Opening Device: %s\n", device); 

    pfring* ring = pfring_open(device, MAXBYTES2CAPTURE, 0);
    pfring_enable_ring(ring);

    pfring_loop(ring, processRingPacket, (u_char*)&count, 1);   

    return 0;
}

查看 pf_ring API 中的 pfring_pkthdr 结构,我应该能够执行以下操作:

pkthdr->extended_hdr.if_index

但是,当我尝试打印索引时,它只打印 0。我猜 if_index 实际上并没有被设置,因为当我实际调用 pf_ring 函数来获取设备 if 索引时,我实际上收到了一个值指定设备:

pfring_get_device_ifindex (pfring *ring, char *device_name, int *if_index)

问题是我正在尝试查看每个数据包的 if_index,因此在回调函数“processRingPacket”中无法通用地指定设备。我在这里笼统地说是因为会有两个接口捕获数据包。关于我的菜鸟错误可能是什么的任何想法?

【问题讨论】:

    标签: c sockets network-programming libpcap pf-ring


    【解决方案1】:

    我认为您需要将PF_RING_LONG_HEADER 作为标志传递给pfring_open()。于是就变成了pfring_open(device, MAXBYTES2CAPTURE, PF_RING_LONG_HEADER);

    【讨论】:

    • 我会检查一下并让您知道这是否有效。感谢您的提示。
    • 这成功了。认为它必须是一些简单的东西。不敢相信我看过这个。非常感谢!
    【解决方案2】:

    如果pkthdr-&gt;extended_hdr.if_index 未在回调函数中设置,您始终可以在arg 参数中将其传递给您的回调函数。

    struct Dev {
       int count;
       int if_index;
    };
    

    ...

    char *device = "eth0";  
    struct Dev dev;
    dev.count = 0;
    dev.if_index = if_nametoindex(device); //from #include <net/in.h>
    
    printf("Opening Device: %s\n", device); 
    
    pfring* ring = pfring_open(device, MAXBYTES2CAPTURE, 0);
    pfring_enable_ring(ring);
    
    pfring_loop(ring, processRingPacket, (u_char*)&dev, 1);   
    

    并在回调函数中恢复:

    void processRingPacket(const struct pfring_pkthdr* pkthdr, const u_char* packet, const u_char *arg)
    {
        struct Dev *dev = (struct Dev*)arg;    
        int i=0, *counter = (int*)&dev->count;
       //and use dev->if_index; whenever you need to.
    

    【讨论】:

    • 如果您只从一个接口捕获或者可以跟踪哪些回调用于哪些接口,那就太好了。但是,我不得不建议从捕获的数据包扩展标头中读取接口号会更通用一些。
    • thuovila:巧合的是,我正试图在两个设备上捕获,因此这就是为什么我试图抓住 ifindex 以便能够分辨每个数据包的方向(例如,数据包进来在 ethA 上还是在 ethB 上出去)。
    • @matt32 在这种情况下您是两次调用 pfring_loop() (例如在不同的线程中),还是在做其他事情? (您将什么作为设备传递给 pfring_open ?)
    • @nos pfring_loop 被调用一次。传入的设备类似于“eth0,eth1”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-20
    • 1970-01-01
    • 2010-10-24
    • 1970-01-01
    • 1970-01-01
    • 2015-12-10
    • 1970-01-01
    相关资源
    最近更新 更多