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