#![allow(dead_code)]
extern crate errno;
extern crate libc;
use errno::Errno;
mod attr;
mod callback;
mod msgvec;
mod nlmsg;
mod socket;
pub use attr::Attr;
pub use attr::AttrTbl;
pub use attr::NestAttr;
pub use callback::run as cb_run;
pub use callback::run2 as cb_run2;
pub use callback::NOCB;
pub use msgvec::MsgVec;
pub use nlmsg::Msghdr;
pub use socket::Socket;
#[derive(Debug, Copy, Clone)]
pub enum AttrDataType {
UNSPEC,
U8,
U16,
U32,
U64,
String,
Flag,
MSecs,
Nested,
NestedCompat,
NulString,
Binary,
}
#[derive(Debug, PartialEq)]
pub enum CbStatus {
Ok,
Stop,
}
pub const ALIGNTO: usize = 4;
pub const SOCKET_AUTOPID: u32 = 0;
pub type Result<T> = std::result::Result<T, Errno>;
pub type GenError = Box<dyn std::error::Error>;
#[macro_export]
macro_rules! gen_errno {
($e: expr) => {
Err(crate::GenError::from(Errno($e)))
};
}
pub type CbResult = std::result::Result<CbStatus, GenError>;
#[inline]
pub fn align(len: usize) -> usize {
(len + ALIGNTO - 1) & !(ALIGNTO - 1)
}
pub fn socket_buffer_size() -> usize {
let pagesize = unsafe { libc::sysconf(libc::_SC_PAGESIZE) as usize };
assert!(pagesize > Msghdr::HDRLEN);
if pagesize < 8192 {
pagesize
} else {
8192
}
}
pub fn default_buffer() -> Vec<u8> {
vec![0u8; socket_buffer_size()]
}
pub const SOCKET_DUMP_SIZE: usize = 32768;
pub fn dump_buffer() -> [u8; SOCKET_DUMP_SIZE] {
[0u8; SOCKET_DUMP_SIZE]
}
pub fn parse_payload<T: FnMut(&Attr) -> CbResult>(payload: &[u8], mut cb: T) -> CbResult {
let mut ret: CbResult = gen_errno!(libc::ENOENT);
let mut attr: &Attr = unsafe { &*(payload.as_ptr() as *const _ as *const Attr) };
while attr.ok(
payload.as_ptr() as *const _ as isize + payload.len() as isize - attr as *const _ as isize,
) {
ret = cb(attr);
match ret {
Ok(CbStatus::Ok) => {}
_ => return ret,
}
unsafe { attr = attr.next() };
}
ret
}