Giter Club home page Giter Club logo

nfqueue-rs's People

Contributors

cactorium avatar chifflier avatar somedude232 avatar steven-joruk avatar vorner avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

nfqueue-rs's Issues

No way to specify the queue with Verdict::Queue

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).

Can't compile examples due to pnet

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

Suspicious crash in release mode.

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

MAC Address is missing first byte

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).

examples fail at assertion

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();
}

Setting of the verdict

The current API has some drawbacks around the setting of verdict:

  • It is possible to set the verdict multiple times on the same message.
  • On the other hand, it is not possible to delay setting the verdict outside of the callback. This is well supported by the C library ‒ they even go so far to promise it's OK to verdict packets out of order and inside another thread.

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.

Other modes of use than just run_loop

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?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.