2010-10-18 8 views
1

J'ai des difficultés à configurer une structure à partir de la bibliothèque pcap dans FFI.Conversion d'une structure C en FFI :: Struct

Struct:

struct pcap_if { 
struct pcap_if *next; 
char *name;   
char *description;  
struct pcap_addr *addresses; 
bpf_u_int32 flags;  
}; 

Le code correspondant Ruby

module Pcap 
extend FFI::Library 
ffi_lib 'pcap' 

attach_function :pcap_findalldevs,[:pointer,:string],:int 

class Pcap_if < FFI::Struct 
layout :next,:pointer, 
    :name,:string, 
    :description,:string, 
    :pcap_addr,:pointer, 
    :flags,:int 
end 
end 

Au-dessus de définition de la fonction attachée

int pcap_findalldevs(pcap_if_t **, char *) 

Le code de test (en tant que root)

tmp='' 
ptr = FFI::MemoryPointer.new :pointer 
res = Pcap.pcap_findalldevs ptr,tmp 
devs = Pcap::Pcap_if.new ptr 
puts res 
puts devs.offsets 
puts devs[:name] 

La sortie est

0 #pcap_findalldevs return success 
next 
0 
name 
4 
description 
8 
pcap_addr 
12 
flags 
16 
pcap.rb:29:in `[]': Memory access offset=4 size=4 is out of bounds (IndexError) 

Les décalages regarder à droite pour moi, mais mon C est très rouillé. Je m'attendais à 2 appareils: lo et eth0 comme noms.

Répondre

0

J'ai trouvé la solution. FFI ne peut pas traiter avec pcap_if_t **. J'ai écrit une fonction C pour retourner juste un tableau de structures.

pcap_if_t* find_devs() 
{ 
    pcap_if_t *devs; 
    char errbuf[PCAP_ERRBUF_SIZE]; 
    int res; 
    res=pcap_findalldevs(&devs, errbuf); 
    return devs; 
} 

Je dois toujours gérer les cas d'erreur, mais cela fonctionne.

1

post lent: Code devrait se présenter comme suit:

ptr = FFI::MemoryPointer.new Pcap::Pcap_if.size 
res = Pcap.pcap_findalldevs ptr,tmp 
devs = Pcap::Pcap_if.new ptr