mirror of https://github.com/stjepang/smol
example: netlink crate
This commit is contained in:
parent
23d9f94264
commit
9f3fc1958b
|
@ -12,6 +12,9 @@ uds_windows = "0.1.4"
|
|||
inotify = { version = "0.8.2", default-features = false }
|
||||
nix = "0.17.0"
|
||||
timerfd = "1.1.1"
|
||||
netlink-sys = "0.2"
|
||||
netlink-packet-core = "0.1"
|
||||
netlink-packet-route = "0.2"
|
||||
|
||||
[dev-dependencies]
|
||||
anyhow = "1.0.28"
|
||||
|
@ -38,6 +41,10 @@ tokio = { version = "0.2.18", default-features = false }
|
|||
tungstenite = "0.10.1"
|
||||
url = "2.1.1"
|
||||
|
||||
[[example]]
|
||||
name = "netlink-route"
|
||||
path = "netlink-route.rs"
|
||||
|
||||
[[example]]
|
||||
name = "async-h1-client"
|
||||
path = "async-h1-client.rs"
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
use std::io;
|
||||
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
fn main() {
|
||||
println!("This example works only on Linux!");
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn main() -> io::Result<()> {
|
||||
use netlink_packet_core::{NetlinkHeader, NetlinkMessage, NLM_F_DUMP, NLM_F_REQUEST};
|
||||
use netlink_packet_route::{rtnl::link::nlas::Nla, LinkMessage, NetlinkPayload, RtnlMessage};
|
||||
use netlink_sys::{Protocol, Socket, SocketAddr};
|
||||
use smol::Async;
|
||||
use std::process;
|
||||
|
||||
fn align(len: usize) -> usize {
|
||||
const RTA_ALIGNTO: usize = 4;
|
||||
|
||||
((len)+RTA_ALIGNTO-1) & !(RTA_ALIGNTO-1)
|
||||
}
|
||||
|
||||
smol::run(async {
|
||||
let mut socket = Socket::new(Protocol::Route)?;
|
||||
socket.bind(&SocketAddr::new(process::id(), 1))?;
|
||||
let mut socket = Async::new(socket)?;
|
||||
|
||||
let mut packet = NetlinkMessage {
|
||||
header: NetlinkHeader {
|
||||
sequence_number: 1,
|
||||
flags: NLM_F_DUMP | NLM_F_REQUEST,
|
||||
..Default::default()
|
||||
},
|
||||
payload: RtnlMessage::GetLink(LinkMessage::default()).into(),
|
||||
};
|
||||
packet.finalize();
|
||||
|
||||
let mut buf = vec![0; packet.header.length as usize];
|
||||
packet.serialize(&mut buf[..]);
|
||||
socket.write_with_mut(|sock| sock.send(&buf, 0)).await?;
|
||||
|
||||
'out: loop {
|
||||
let mut buf = [0; 4096];
|
||||
let mut cursor = 0;
|
||||
|
||||
let (count, _) = socket
|
||||
.read_with_mut(|sock| sock.recv_from(&mut buf, 0))
|
||||
.await?;
|
||||
loop {
|
||||
if cursor >= count {
|
||||
break;
|
||||
}
|
||||
let msg_len = {
|
||||
let mut len_buf = [0; 4];
|
||||
len_buf.copy_from_slice(&buf[cursor..cursor + 4]);
|
||||
u32::from_ne_bytes(len_buf) as usize
|
||||
};
|
||||
let msg_len = align(msg_len);
|
||||
let reply = NetlinkMessage::<RtnlMessage>::deserialize(&buf[cursor..cursor + msg_len])
|
||||
.expect("Failed to deserialize message");
|
||||
match reply.payload {
|
||||
NetlinkPayload::InnerMessage(RtnlMessage::NewLink(link)) => {
|
||||
let name = link
|
||||
.nlas
|
||||
.iter()
|
||||
.filter_map(|nla| match nla {
|
||||
Nla::IfName(name) => Some(name.clone()),
|
||||
_ => None,
|
||||
})
|
||||
.next()
|
||||
.unwrap();
|
||||
println!("{}: {}", link.header.index, name);
|
||||
}
|
||||
_ => {
|
||||
break 'out;
|
||||
}
|
||||
}
|
||||
cursor += msg_len;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
})
|
||||
}
|
Loading…
Reference in New Issue