jtomschroeder/ether

/dev/bpf* doesn't exist, Error success

kpcyrd opened this issue · 1 comments

I ran into another issue:

let mut tap = tap::Tap::new("eth0").unwrap();

is failing with this error:

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error { repr: Os { code: 0, message: "Success" } }', src/libcore/result.rs:860

This is the code of open():

pub fn new(interface: &str) -> io::Result<Self> {
    fn open() -> io::Result<File> {
        // On macOS: bpf exposed as /dev/bpf###
        for entry in glob("/dev/bpf*").expect("Failed to read glob pattern") {
            if let Some(file) = entry
                   .ok()
                   .and_then(|path| {
                                 OpenOptions::new()
                                     .read(true)
                                     .write(true)
                                     .open(&path)
                                     .ok()
                             }) {
                return Ok(file);
            }
        }

        Err(io::Error::last_os_error())
    }

    let file = try!(open()); // this returns Err(io::Error::last_os_error())
    let config = Config::default();
    // [...]

It appears linux doesn't support berkley packet filter so it doesn't have /dev/bpf*, falls through the loop and returns last_os_error() which was unrelated and successful. :)

You might want to look into the pcap crate, I managed to dump traffic successfully using it, but I didn't feel like decoding ethernet, ip and tcp manually.

Yeah, on Linux, we would use an AF_PACKET socket. Also, the error handling and OS-specific gating could definitely be better. A wrapper around libpcap is viable option, but ether is meant to be a rustic replacement.

Tasks:

  • improve error handling (No unwraps!)
  • Narrow bpf module to macOS (BSD?)
  • implement Linux support for Tap via AF_PACKET