nell 0.0.1

Linux netlink API access
Documentation
// Copyright (C) 2018 - Will Glozer. All rights reserved.

use std::mem::size_of;
use ffi::*;
use ffi::netlink_family::*;
use sys::*;

#[derive(Debug)]
pub struct Link {
    pub index: u32,
    pub name:  String,
    pub flags: u32,
}

pub fn links() -> Result<Vec<Link>, Error> {
    let sock = Socket::new(NETLINK_ROUTE)?;

    #[repr(C)]
    #[derive(Default, Debug)]
    struct Request {
        hdr: nlmsghdr,
        req: rtgenmsg,
    }

    let mut req = Request::default();
    req.hdr.nlmsg_len    = nlmsg_length(size_of::<rtgenmsg>() as u32);
    req.hdr.nlmsg_type   = RTM_GETLINK;
    req.hdr.nlmsg_flags  = NLM_F_REQUEST | NLM_F_DUMP;
    req.req.rtgen_family = AF_UNSPEC;

    sock.send(&mut [as_iovec(&mut req)])?;
    sock.recv(|data: &ifinfomsg, mut tail: Attrs| {
        let mut link = Link {
            index: data.ifi_index as u32,
            name:  String::new(),
            flags: data.ifi_flags as u32,
        };

        // FIXME: cleanup
        while let Some((head, data)) = tail.next::<rtattr>() {
            println!("got attr {:?}: {:?}", head, data);
            match head.rta_type {
                IFLA_IFNAME  => link.name = data.string(),
                IFLA_STATS64 => {
                    let stats: &rtnl_link_stats64 = data.cast();
                    println!("stats {:#?}", stats);
                },
                IFLA_XDP     => {
                    let mut attrs = data.attrs();
                    while let Some((head, data)) = attrs.next::<nlattr>() {
                        match head.nla_type {
                            IFLA_XDP_FD       => println!("{}: XDP FD {:?}", link.index, data.cast::<u32>()),
                            IFLA_XDP_ATTACHED => println!("{}: XDP ATTACHED {:?}", link.index, data.cast::<bool>()),
                            IFLA_XDP_PROG_ID  => println!("{}: XDP PROG ID {:?}", link.index, data.cast::<u32>()),
                            n  => println!("{}: XDP (UNKNOWN {}) {:?}", link.index, n, data),
                        }
                    }
                },
                _           => (),
            }
        }

        Ok(link)
    })
}