tun-tap 0.1.4

TUN/TAP interface wrapper
Documentation
//! An example of reading from tun
//!
//! It creates a tun device, sets it up (using shell commands) for local use and then prints the
//! raw data of the packets that arrive.
//!
//! You really do want better error handling than all these unwraps.
extern crate tun_tap;

use std::process::Command;

use tun_tap::{Iface, Mode};

/// Run a shell command. Panic if it fails in any way.
fn cmd(cmd: &str, args: &[&str]) {
    let ecode = Command::new("ip")
        .args(args)
        .spawn()
        .unwrap()
        .wait()
        .unwrap();
    assert!(ecode.success(), "Failed to execte {}", cmd);
}

fn main() {
    // Create the tun interface.
    let iface = Iface::new("testtun%d", Mode::Tun).unwrap();
    eprintln!("Iface: {:?}", iface);
    // Configure the „local“ (kernel) endpoint.
    cmd("ip", &["addr", "add", "dev", iface.name(), "10.107.1.2/24"]);
    cmd("ip", &["link", "set", "up", "dev", iface.name()]);
    println!("Created interface {}. Send some packets into it and see they're printed here",
             iface.name());
    println!("You can for example ping 10.107.1.3 (it won't answer)");
    // That 1500 is a guess for the IFace's MTU (we probably could configure it explicitly). 4 more
    // for TUN's „header“.
    let mut buffer = vec![0; 1504];
    loop {
        // Every read is one packet. If the buffer is too small, bad luck, it gets truncated.
        let size = iface.recv(&mut buffer).unwrap();
        assert!(size >= 4);
        println!("Packet: {:?}", &buffer[4..size]);
    }
}