rsmnl-linux 0.1.0

linux headers for rsmnl
Documentation
use std::{
    env, process,
    time::{SystemTime, UNIX_EPOCH},
};

extern crate rsmnl as mnl;
use mnl::{MsgVec, Socket};

extern crate rsmnl_linux as linux;
use linux::{if_link::Ifla, rtnetlink::Ifinfomsg};

fn main() -> Result<(), String> {
    let args: Vec<_> = env::args().collect();
    if args.len() != 3 {
        println!("Usage: {} [ifname] [up|down]", args[0]);
        process::exit(libc::EXIT_FAILURE);
    }

    let mut change: u32 = 0;
    let mut flags: u32 = 0;
    match args[2].to_lowercase().as_ref() {
        "up" => {
            change |= libc::IFF_UP as u32;
            flags |= libc::IFF_UP as u32;
            Ok(())
        }
        "down" => {
            change |= libc::IFF_UP as u32;
            flags &= !libc::IFF_UP as u32;
            Ok(())
        }
        _ => Err(format!("{} is not neither `up' nor `down'", args[2])),
    }?;

    let mut nlv = MsgVec::new();
    let mut nlh = nlv.put_header();
    nlh.nlmsg_type = libc::RTM_NEWLINK;
    nlh.nlmsg_flags = (libc::NLM_F_REQUEST | libc::NLM_F_ACK) as u16;
    let seq = SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .unwrap()
        .as_secs() as u32;
    nlh.nlmsg_seq = seq;
    let ifm: &mut Ifinfomsg = nlv.put_extra_header().unwrap();
    ifm.ifi_family = libc::AF_UNSPEC as u8;
    ifm.ifi_change = change;
    ifm.ifi_flags = flags;

    Ifla::put_ifname(&mut nlv, &args[1]).unwrap();

    let mut nl = Socket::open(libc::NETLINK_ROUTE, 0)
        .map_err(|errno| format!("mnl_socket_open: {}", errno))?;

    nl.bind(0, mnl::SOCKET_AUTOPID)
        .map_err(|errno| format!("mnl_socket_bind: {}", errno))?;
    let portid = nl.portid();

    nl.sendto(&nlv)
        .map_err(|errno| format!("mnl_socket_sendto: {}", errno))?;

    let mut buf = mnl::default_buffer();
    let nrecv = nl
        .recvfrom(&mut buf)
        .map_err(|errno| format!("mnl_socket_recvfrom: {}", errno))?;

    mnl::cb_run(&buf[0..nrecv], seq, portid, mnl::NOCB)
        .map_err(|errno| format!("mnl_cb_run: {}", errno))?;

    Ok(())
}