chifflier / nfqueue-rs Goto Github PK
View Code? Open in Web Editor NEWNetfilter NFQUEUE high-level bindings (rust)
License: GNU General Public License v2.0
Netfilter NFQUEUE high-level bindings (rust)
License: GNU General Public License v2.0
The MAC address when pulled from the call to the C library does not include the first byte due to an indexing error (src/message.rs:218).
Program:
use nfqueue::{Queue, Verdict, Message};
fn callback(msg: &Message, d:&mut ()) {
println!(" -> msg: {}", msg);
msg.set_verdict(nfqueue::Verdict::Accept);
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut q = Queue::new(());
q.open();
q.create_queue(44, callback);
q.set_mode(nfqueue::CopyMode::CopyMeta, 0xffff);
//q.set_queuelen(1024); // linking fails with this
q.run_loop();
q.close();
Ok(())
}
Seems to be working in debug. But in release mode, it crashes:
#0 0x0000555555564850 in <nfqueue::message::Message as core::fmt::Display>::fmt ()
#1 0x00005555555840dc in core::fmt::write () at src/libcore/fmt/mod.rs:1028
#2 0x0000555555568981 in std::io::Write::write_fmt () at src/libstd/io/mod.rs:1412
#3 <std::io::stdio::Stdout as std::io::Write>::write_fmt () at src/libstd/io/stdio.rs:533
#4 0x00005555555691da in std::io::stdio::print_to::{{closure}} () at src/libstd/io/stdio.rs:786
#5 std::thread::local::LocalKey<T>::try_with () at src/libstd/thread/local.rs:262
#6 std::io::stdio::print_to () at src/libstd/io/stdio.rs:780
#7 std::io::stdio::_print () at src/libstd/io/stdio.rs:802
#8 0x00005555555644d8 in nfqnetsim::callback ()
#9 0x0000555555564249 in nfqueue::real_callback ()
#10 0x00007ffff7f5c3e9 in ?? () from /usr/lib/x86_64-linux-gnu/libnetfilter_queue.so.1
#11 0x00007ffff7b5573f in nfnl_handle_packet () from /usr/lib/x86_64-linux-gnu/libnfnetlink.so.0
#12 0x000055555556438f in nfqueue::Queue<T>::run_loop ()
#13 0x000055555556453b in nfqnetsim::main ()
#14 0x00005555555641f3 in std::rt::lang_start::{{closure}} ()
#15 0x000055555556dc93 in std::rt::lang_start_internal::{{closure}} () at src/libstd/rt.rs:48
#16 std::panicking::try::do_call () at src/libstd/panicking.rs:287
#17 0x000055555556f46a in __rust_maybe_catch_panic () at src/libpanic_unwind/lib.rs:78
#18 0x000055555556e6fd in std::panicking::try () at src/libstd/panicking.rs:265
#19 std::panic::catch_unwind () at src/libstd/panic.rs:396
#20 std::rt::lang_start_internal () at src/libstd/rt.rs:47
#21 0x0000555555564562 in main ()
Built with rustc 1.40.0-nightly (2477e2493 2019-11-04)
and libnetfilter-queue-dev=1.0.3-1
As the documentation says here, the target queue to put the packet into with the Queue verdict is encoded by putting it into the 16 high bits of the verdict. This is likely copied from the C version where it is reasonably possible to combine the value (VERDICT_QUEUE | (queue << 16)
). This is not possible in Rust ‒ doing that would create a non-existent variant of the Verdict
enum, which is UB in Rust (and one would likely need to use something like transmute to do that anyway).
MAC addresses that are displayed using println!() do not have the proper zero padding for bytes that are less than 0x10 (src/hwaddr.rs:21).
hi, i got some question:
libnetfilter-queue
shuld have one build script (build.rs
) ?libnetfilter-queue
.thx!
The run_loop
mode has two disadvantages.
• It is not possible to multiplex more than one queue on the same thread.
• There doesn't seem to be a clean way to terminate.
The C library supports other mode ‒ you can get the file descriptor, put it into epoll
(or something similar) and when it is ready, try recvmsg
on it. Then you call nfq_handle_packet
on it and it calls the callback internally. This is more flexible (though slightly more work). Would it be possible to expose this mode of API as well?
The current pnet version does not seem be able to get compiled, supposedly due to some mismatch with their tags:
warning: `nfqueue` (lib) generated 6 warnings
Compiling pnet_macros v0.33.0
Compiling pnet_packet v0.25.0
error[E0425]: cannot find function `register` in crate `pnet_macros`
--> /home/poiasd/.cargo/registry/src/github.com-1ecc6299db9ec823/pnet_packet-0.25.0/build.rs:27:30
|
27 | pnet_macros::register(&mut registry);
| ^^^^^^^^ not found in `pnet_macros`
For more information about this error, try `rustc --explain E0425`.
error: could not compile `pnet_packet` due to previous error
Related issue: libpnet/libpnet#524
See this email and the nf-queue.c example.
The current API has some drawbacks around the setting of verdict:
Is it possible to pass owned (not borrowed) message to the callback and consume it during verdicting? And maybe go so far as to panic (or at least warn) if the message is destroyed without getting a verdict?
If the problem is the buffer of data, it could be passed to the callback as two parameters ‒ one Message, that'd contain the metadata and the ability to verdict, and borrowed slice of bytes as the payload.
Hey there,
when trying your library I encountered failed assertions. The assertion in the examples let rc = q.bind(libc::AF_INET);
fails. If I remove it, the library fails with assertion failed: !self.qqh.is_null()', $HOME/.cargo/git/checkouts/nfqueue-rs-0ce1560e2a26a188/1ee3e07/src/lib.rs:258
.
Do you have any advise on how to solve this?
extern crate nfqueue;
extern crate libc;
struct State {
count: u32,
}
impl State {
pub fn new() -> State {
State{ count:0 }
}
}
fn queue_callback(msg: &nfqueue::Message, state:&mut State) {
...
}
fn main() {
let mut q = nfqueue::Queue::new(State::new());
q.open();
q.unbind(libc::AF_INET);
let rc = q.bind(libc::AF_INET);
// assert!(rc == 0);
q.create_queue(1, queue_callback);
q.run_loop();
q.close();
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.