pf_ring и libpcap if_index не возвращаются

Недавно я столкнулся с необходимостью использовать pf_ring / libpcap. Я никогда не разрабатывал с помощью libpcap или pf_ring, поэтому, пожалуйста, простите за глупый вопрос, поскольку сетевое программирование для меня почти новое... В общих чертах, я пытаюсь получить доступ к if_index для полученных пакетов. В настоящее время у меня есть простой сниффер необработанных пакетов, созданный с помощью «C» с использованием pf_ring, как показано ниже:

#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;
}

Глядя на структуру pfring_pkthdr в API pf_ring, я должен сделать следующее:

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» нет способа указать устройство в общем. Я говорю здесь в общем, потому что будет два интерфейса, перехватывающих пакеты. Любые идеи о том, что моя ошибка новичка может быть?


person matt32    schedule 31.08.2014    source источник


Ответы (2)


Я думаю, вам нужно передать PF_RING_LONG_HEADER в качестве флага для pfring_open(). Так и получается, pfring_open(device, MAXBYTES2CAPTURE, PF_RING_LONG_HEADER);

person thuovila    schedule 01.09.2014
comment
Я проверю это и дам вам знать, если это сработает. Спасибо за чаевые. - person matt32; 02.09.2014
comment
Это помогло. Подумал, что должно быть что-то простое. Не могу поверить, что просмотрел это. Спасибо большое! - person matt32; 02.09.2014

Если 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.
person nos    schedule 01.09.2014
comment
Это здорово, если вы захватываете только один интерфейс или можете отслеживать, какие обратные вызовы предназначены для каких интерфейсов. Тем не менее, я должен предположить, что было бы немного более общим, чтобы прочитать номер интерфейса из расширенных заголовков захваченных пакетов. - person thuovila; 01.09.2014
comment
thuovila: По совпадению, я пытаюсь захватить на двух устройствах, поэтому я пытаюсь захватить ifindex в общем, чтобы иметь возможность указать направление каждого пакета (например, пакет приходит на ethA или он уходит на этБ). - person matt32; 02.09.2014
comment
@matt32 в этом случае вы вызываете pfring_loop() дважды (например, в разных потоках) или делаете что-то еще? (Что вы передаете в качестве устройства pfring_open?) - person nos; 03.09.2014
comment
@nos pfring_loop вызывается один раз. Переданные устройства будут выглядеть примерно так: eth0, eth1. - person matt32; 04.09.2014