Skip to content

Commit

Permalink
NFLOG MVP support
Browse files Browse the repository at this point in the history
Support receiving packets from the kernel over nflog. Some parts are not
yet implemented ‒ conntrack integration, hardware headers...

Closes #38.
  • Loading branch information
vorner committed Oct 12, 2019
1 parent f182835 commit 851d1c1
Show file tree
Hide file tree
Showing 7 changed files with 465 additions and 3 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## Unreleased

### Additions
* NFLOG support, in the `netfilter` module.

## 0.4.3
### Breaking changes
* Change `Nlattr.add_nested_attribute()` to take a reference
Expand Down
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

58 changes: 58 additions & 0 deletions examples/nflog.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//! This example connects to the netfilter logging facility, group 10 (arbitrarily chosen number),
//! on INET (IPv4).
//!
//! If you want to see it work, log some packets, for example by adding this into the iptables:
//!
//! ```sh
//! iptables -I INPUT -j NFLOG --nflog-group 10 --nflog-prefix "A packet"
//! ```
//!
//! Both this example and the above command needs to be run as root.
extern crate neli;

use neli::consts::{NlFamily, NlmF};
use neli::consts::netfilter::{LogCmd, LogCopyMode, NetfilterMsg, NfLogCfg};
use neli::netfilter::{LogConfigMode, LogConfigReq, LogPacket};
use neli::nlattr::Nlattr;
use neli::nl::Nlmsghdr;
use neli::socket::NlSocket;

fn main() -> Result<(), Box<dyn std::error::Error>> {
// First, let's create a socket to the netfilter.
let mut socket = NlSocket::connect(NlFamily::Netfilter, None, None, false)?;

// Then, ask the kernel to send the relevant packets into it. Unfortunately, the documentation
// of the functionality is kind of sparse, so there are some unknowns, like why do we have to
// do the PfUnbind first (every other example out there on the Internet does that and doesn't
// explain it).
let cmds = vec![
Nlattr::new(None, NfLogCfg::Cmd, LogCmd::PfUnbind)?,
// This one says we are interested in the first 50 bytes of each packet. If not included,
// it'll send us the whole packets.
Nlattr::new(None, NfLogCfg::Mode, LogConfigMode {
copy_mode: LogCopyMode::Packet,
copy_range: 50,
})?,
Nlattr::new(None, NfLogCfg::Cmd, LogCmd::PfBind)?,
Nlattr::new(None, NfLogCfg::Cmd, LogCmd::Bind)?,
];
let req = LogConfigReq::new(libc::AF_INET, 10, cmds);
let flags = vec![NlmF::Request, NlmF::Ack];
let msg = Nlmsghdr::new(None, NetfilterMsg::LogConfig, flags, None, None, req);
// Send the request to the kernel
socket.send_nl(msg)?;
// And check it succeeds.
socket.recv_ack()?;

// Now, let's start getting the packets. A real world application would do something more
// useful with them then just print them, but hey, this is an example.
for pkt in socket.iter::<NetfilterMsg, LogPacket>() {
let pkt = pkt?;
match pkt.nl_type {
NetfilterMsg::LogPacket => println!("{:?}", pkt.nl_payload),
// TODO: Does anyone have any idea what these messages are and why we get them?
_ => println!("Some other message received"),
}
}
Ok(())
}
1 change: 1 addition & 0 deletions src/consts/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ mod macros;
/// Constants related to generic netlink
pub mod genl;
pub use crate::consts::genl::*;
pub mod netfilter;
/// Constants related to generic netlink attributes
pub mod nlattr;
pub use crate::consts::nlattr::*;
Expand Down
79 changes: 79 additions & 0 deletions src/consts/netfilter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
//! Constants for netfilter related protocols
//!
//! Note that this doesn't cover everything yet, both the list of types and variants in enums will
//! be added over time.

use super::{NlAttrType, NlType};

impl_var_trait! {
/// Attributes inside a netfilter log packet message.
///
/// These are send by the kernel and describe a logged packet.
NfLogAttr, u16, NlAttrType,
PacketHdr => 1,
Mark => 2,
Timestamp => 3,
IfindexIndev => 4,
IfindexOutdev => 5,
IfindexPhyindev => 6,
IfindexPhyoutdev => 7,
Hwaddr => 8,
Payload => 9,
Prefix => 10,
Uid => 11,
Seq => 12,
SeqGlobal => 13,
Gid => 14,
Hwtype => 15,
Hwheader => 16,
Hwlen => 17,
Ct => 18,
CtInfo => 19
}

impl_var_trait! {
/// Configuration attributes for netfilter logging.
///
/// See [LogConfigReq][crate::netfilter::LogConfigReq]
NfLogCfg, u16, NlAttrType,
Cmd => 1,
Mode => 2,
NlBufSize => 3,
Timeout => 4,
QThresh => 5,
Flags => 6
}

impl_var_trait! {
/// Messages related to the netfilter netlink protocols.
///
/// These appear on the [NlFamily::Netfilter][super::NlFamily::Netfilter] sockets.
NetfilterMsg, u16, NlType,
// TODO: Docs here /// A logged packet, going from kernel to userspace.
LogPacket => 0x0400,
// TODO: Docs here /// A logging configuration request, going from userspace to kernel.
LogConfig => 0x0401
}

impl_trait! {
/// Parameters for the [NfLogCfg::Cmd].
LogCfgCmd, u8
}

impl_var_trait! {
/// Command value for the [NfLogCfg::Cmd].
LogCmd, u8, LogCfgCmd,
Bind => 1,
Unbind => 2,
PfBind => 3,
PfUnbind => 4
}

impl_var! {
/// Copy mode of the logged packets.
LogCopyMode, u8,
None => 0,
Meta => 1,
Packet => 2
}

2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
//! code.
//! * `genl` - This code provides parsing for the generic netlink subsystem of the netlink
//! protocol.
//! * `netfilter` - Netfilter related protocols (NFLOG, NFQUEUE, CONNTRACK).
//! * `nlattr` - This code provides more granular parsing methods for the generic netlink
//! attributes in the context of generic netlink requests and responses.
//! * `nl` - This is the top level netlink header code that handles the header that all netlink
Expand Down Expand Up @@ -68,6 +69,7 @@ pub mod consts;
pub mod err;
/// Genetlink (generic netlink) header and attribute helpers
pub mod genl;
pub mod netfilter;
/// Top-level netlink header
pub mod nl;
/// Netlink attribute handler
Expand Down
Loading

0 comments on commit 851d1c1

Please sign in to comment.