Linux Kernel AF_PACKET bindings for Rust
02 May 2018
I’ve finally gotten my Linux kernel AF_PACKET bindings in Rust working properly – this should allow people to start developing network sniffers, monitoring tools, and security-related software using Rust. There’s a lot of clean-up ahead and I want to make the interface more controllable, but for now, it’s still pretty simple to use. I need to write a bunch of documentation as well.
The Linux kernel will balance flows based on a tupled hash so you shouldn’t need to do any cross-thread communication to reassemble flows.
The project is on GitLab and and packages are available on crates.io. I’ve pasted a dead-simple example below.
extern crate af_packet;
extern crate num_cpus;
use std::env;
use std::thread;
fn main() {
let args: Vec<String> = env::args().collect();
for _ in 0..num_cpus::get() {
let interface = args[1].clone();
thread::spawn(move || {
let mut ring = af_packet::Ring::from_if_name(&interface).unwrap();
loop {
println!(
"Ring {} on {} has received {} packets and dropped {}",
ring.fd, ring.if_name, ring.packets, ring.drops
);
let mut block = ring.get_block(); //THIS WILL BLOCK
for _packet in block.get_raw_packets() {
//do something
}
block.mark_as_consumed();
}
});
}
loop {
thread::sleep_ms(1000);
}
}