2014-08-31 18 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