1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
|
use std::{env, error::Error};
#[cfg(feature = "async")]
use tokio::runtime::Runtime;
#[cfg(feature = "async")]
use neli::router::asynchronous::NlRouter;
#[cfg(not(feature = "async"))]
use neli::router::synchronous::NlRouter;
use neli::{
attr::Attribute,
consts::{genl::*, nl::*, socket::*},
genl::{Genlmsghdr, GenlmsghdrBuilder},
nl::NlPayload,
types::{Buffer, GenlBuffer},
utils::Groups,
};
const GENL_VERSION: u8 = 2;
// This example attempts to mimic the "genl ctrl list" command. For simplicity, it only outputs
// the name and identifier of each generic netlink family.
#[cfg(feature = "async")]
fn main() -> Result<(), Box<dyn Error>> {
env_logger::init();
let num_reps = env::args()
.nth(1)
.ok_or("Number of loop repetitions required")?
.parse::<usize>()?;
Runtime::new()?.block_on(async {
for _ in 0..num_reps {
let (socket, _) = NlRouter::connect(NlFamily::Generic, None, Groups::empty()).await?;
let mut recv = socket
.send::<_, _, NlTypeWrapper, Genlmsghdr<CtrlCmd, CtrlAttr>>(
GenlId::Ctrl,
NlmF::DUMP,
NlPayload::Payload(
GenlmsghdrBuilder::default()
.cmd(CtrlCmd::Getfamily)
.version(GENL_VERSION)
.attrs(GenlBuffer::<u16, Buffer>::new())
.build()?,
),
)
.await?;
while let Some(response_result) = recv
.next::<NlTypeWrapper, Genlmsghdr<CtrlCmd, CtrlAttr>>()
.await
{
let response = response_result?;
if let Some(p) = response.get_payload() {
let handle = p.attrs().get_attr_handle();
for attr in handle.iter() {
match attr.nla_type().nla_type() {
CtrlAttr::FamilyName => {
println!("{}", attr.get_payload_as_with_len::<String>()?);
}
CtrlAttr::FamilyId => {
println!("\tID: 0x{:x}", attr.get_payload_as::<u16>()?);
}
_ => (),
}
}
}
}
}
Result::<_, Box<dyn Error>>::Ok(())
})?;
Ok(())
}
#[cfg(not(feature = "async"))]
fn main() -> Result<(), Box<dyn Error>> {
env_logger::init();
let num_reps = env::args()
.nth(1)
.ok_or_else(|| "Number of loop repetitions required")?
.parse::<usize>()?;
for _ in 0..num_reps {
let (socket, _) = NlRouter::connect(NlFamily::Generic, None, Groups::empty())?;
let recv = socket.send::<_, _, NlTypeWrapper, Genlmsghdr<CtrlCmd, CtrlAttr>>(
GenlId::Ctrl,
NlmF::DUMP,
NlPayload::Payload(
GenlmsghdrBuilder::default()
.cmd(CtrlCmd::Getfamily)
.version(GENL_VERSION)
.attrs(GenlBuffer::<u16, Buffer>::new())
.build()?,
),
)?;
for response_result in recv {
let response = response_result?;
if let Some(p) = response.get_payload() {
let handle = p.attrs().get_attr_handle();
for attr in handle.iter() {
match attr.nla_type().nla_type() {
CtrlAttr::FamilyName => {
println!("{}", attr.get_payload_as_with_len::<String>()?);
}
CtrlAttr::FamilyId => {
println!("\tID: 0x{:x}", attr.get_payload_as::<u16>()?);
}
_ => (),
}
}
}
}
}
Ok(())
}
|