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