2014-08-31 85 views
1

我最近一直在参与必须使用pf_ring/libpcap。我从来没有用libpcap或pf_ring开发过,所以请原谅什么似乎是一个愚蠢的问题,因为网络编程对我而言是半新的......广义地说,我试图做的是访问接收到的数据包的if_index。我目前有“C”使用PF_RING创建了一个简单的原始数据包嗅探器,如下图所示:pf_ring和libpcap if_index不返回

#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函数来获取设备如果索引,我实际上收到一个值指定设备:

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

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

回答

2

我认为您需要将PF_RING_LONG_HEADER作为标志传递给pfring_open()。所以它变成pfring_open(device, MAXBYTES2CAPTURE, PF_RING_LONG_HEADER);

+0

我检查了这一点,让你知道,如果这个工程。谢谢你的提示。 – matt32 2014-09-02 14:58:43

+0

这个伎俩。认为它必须是简单的东西。我不敢相信我看过这个。非常感谢! – matt32 2014-09-02 15:51:36

1

如果在回调函数中没有设置pkthdr->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. 
+0

这很好,如果你只从一个接口捕获,或者可以跟踪哪些回调针对哪个接口。但是,我必须建议从捕获的数据包扩展头中读取接口号,这会更通用一些。 – thuovila 2014-09-01 13:47:17

+0

thuovila:巧合的是我试图捕获两个设备,因此这就是为什么我试图抓住ifindex一般来说,能够告诉每个数据包的方向(例如数据包是在ethA上发送还是将发送出去在ethB上)。 – matt32 2014-09-02 14:57:25

+0

@ matt32在这种情况下,你是否调用了pfring_loop()两次(例如,在不同的线程中),或者你在做其他事情? (你作为pfring_open的设备传入了什么?) – nos 2014-09-03 07:08:56