szymonwieloch / rust-rawsock

Rust library for obtaining and sending raw network packets from interfaces.
MIT License
64 stars 16 forks source link

Implement filter. #8

Closed spacemeowx2 closed 4 years ago

spacemeowx2 commented 4 years ago
spacemeowx2 commented 4 years ago

I can't make pfring work.

sudo ./target/debug/examples/filter
Opening packet capturing library
Library opened, version is pfring 7.5.0
Opening the lo interface
Interface opened, data link: ethernet
./target/debug/examples/filter: symbol lookup error: /usr/local/lib/libpfring.so.1: undefined symbol: pcap_open_dead

Seems that libpfring doesn't dynamic link with libpcap.

ldd -r /usr/local/lib/libpfring.so.1
        linux-vdso.so.1 (0x00007ffeca397000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fd96b223000)
        librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fd96b01b000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fd96ae17000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd96aa26000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fd96b6de000)
undefined symbol: pcap_compile_nopcap   (/usr/local/lib/libpfring.so.1)
undefined symbol: pcap_close    (/usr/local/lib/libpfring.so.1)
undefined symbol: pcap_open_dead        (/usr/local/lib/libpfring.so.1)
undefined symbol: pcap_compile  (/usr/local/lib/libpfring.so.1)
undefined symbol: pcap_freecode (/usr/local/lib/libpfring.so.1)
undefined symbol: bpf_filter    (/usr/local/lib/libpfring.so.1)

Finally I find out I can make it work with this command:

LD_PRELOAD=/usr/local/lib/libpcap.so.1.8.1 ./target/debug/examples/filter

I think we need to load libpcap before set_filter. How can we load libpcap by code?

szymonwieloch commented 4 years ago

@spacemeowx2 Hi! Thank you for your contribution. I am dead tired today because I had 2 hours of training. I will review your changes tomorrow, when I have more time. Cheers!

szymonwieloch commented 4 years ago

@spacemeowx2 When it comes to loading a pcap library, I think it should be delayed as long as possible. Many users may not need to perform filtering and it is pointless to use to much resources when not needed. You are right - the best place to do it is probably in the set_filter() function. My guess would be that you need to add it to the Library instance:

pcap: Mutex<Option<dlopen::raw::Library>>

and add a prefetch_pcap() function :

pub (crate) fn prefetch_pcap(&self){}

Then call prefetch_pcap() from set_filter()

I haven't tested it though and I am curious if it is possible to load pcap library in this way...

spacemeowx2 commented 4 years ago

Ok, I'll fix it by myself.

spacemeowx2 commented 4 years ago

@szymonwieloch After many attempts, I found that calling dlopen with RTLD_GLOBAL | RTLD_LAZY or RTLD_LOCAL | RTLD_NOW allows pcap to be loaded and used by pfring. However, dlopen crate uses the flag RTLD_LOCAL | RTLD_LAZY and cannot be changed at runtime.

I guess I will leave this problem to you to solve.

tan-wei commented 4 years ago

It seems that set_filter not support in version 0.3.0, maybe the new interface is not merged in the release crate?