2014-08-31 4 views
1

저는 최근에 pf_ring/libpcap을 활용하는 데 관여했습니다. 나는 libpcap이나 pf_ring으로 개발 한 적이 없으므로, 바보 같은 질문 인 것처럼 보이는 것을 용서해주십시오. 네트워크 프로그래밍은 제게 새로운 것이기 때문에 ... 광범위하게 말하면,받은 패킷에 대해 if_index에 액세스하는 것입니다. 아래 그림과 같이 나는 현재 "C"사용 pf_ring로 만든 간단한 원시 패킷 스니퍼가 :pf_ring과 libpcap if_index가 돌아 오지 않습니다.

pkthdr->extended_hdr.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 구조체를 보면, 나는 다음을 수행 할 수 있어야한다

그러나 색인을 인쇄하려고하면 단지 0이 인쇄됩니다. if_index가 실제로 설정되어 있지 않다고 추측합니다. 실제로 색인을 얻으려면 pf_ring 함수를 호출 할 때 실제로 색인에 대한 값을받습니다. 지정된 기기 :

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

문제는 각 패킷에 대해 if_index를 보려고하기 때문에 콜백 함수 "processRingPacket"내에 일반적으로 장치를 지정할 방법이 없습니다. 패킷을 캡쳐하는 두 개의 인터페이스가 있기 때문에 일반적으로 여기서 말합니다. 내 신인 선수의 실수에 대한 아이디어는 없나요?

답변

2

PF_RING_LONG_HEADERpfring_open()의 플래그로 전달해야한다고 생각합니다. 따라서 pfring_open(device, MAXBYTES2CAPTURE, PF_RING_LONG_HEADER);

+0

나는이 체크 아웃이 작동하는지 알려 드리겠습니다. 팁 고마워. – matt32

+0

이것은 트릭을 만들었습니다. 그것이 단순해야만한다는 것을 알았습니다. 내가 이것을 보았다고 믿을 수 없어. 정말 고마워! – matt32

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

+0

thuovila : 우연히 두 장치에서 캡처하려고합니다. 따라서 이것이 ifindex를 일반적으로 각 패킷의 방향을 알 수 있도록 잡으려고합니다 (예 : ethA에 들어오는 패킷 또는 나가는 패킷입니다. on ethB). – matt32

+0

@ matt32 그런 경우 다른 스레드에서 pfring_loop()를 두 번 호출하고 있습니까? 아니면 다른 작업을 수행하고 있습니까? (pfring_open으로 무엇을 전달할 것입니까?) – nos

관련 문제