Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nflog support MVP #48

Merged
merged 1 commit into from
Oct 30, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
62 changes: 62 additions & 0 deletions examples/nflog.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
//! 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::netfilter::{LogCmd, LogCopyMode, NetfilterMsg, NfLogCfg};
use neli::consts::{NlFamily, NlmF};
use neli::netfilter::{LogConfigMode, LogConfigReq, LogPacket};
use neli::nl::Nlmsghdr;
use neli::nlattr::Nlattr;
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
78 changes: 78 additions & 0 deletions src/consts/netfilter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
//! 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,
jbaublitz marked this conversation as resolved.
Show resolved Hide resolved
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