use std::mem;
extern crate errno;
extern crate libc;
use errno::Errno;
use libc::{c_int, c_uint};
use mnl::{Attr, AttrTbl, MsgVec, Result};
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Family {
Route = 0, Unused = 1, Usersock = 2, Firewall = 3, SockDiag = 4, Nflog = 5, Xfrm = 6, Selinux = 7, Iscsi = 8, Audit = 9, FibLookup = 10,
Connector = 11,
Netfilter = 12, Ip6Fw = 13,
Dnrtmsg = 14, KobjectUevent = 15, Generic = 16,
Scsitransport = 18, Ecryptfs = 19,
Rdma = 20,
Crypto = 21, Smc = 22,
InetDiag, }
impl Into<c_int> for Family {
fn into(self) -> c_int {
if self == Family::InetDiag {
return Family::SockDiag as c_int;
}
self as c_int
}
}
pub const MAX_LINKS: c_int = 32;
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct SockaddrNl {
pub nl_family: u16,
nl_pad: u16,
pub nl_pid: u32,
pub nl_groups: u32,
}
impl Default for SockaddrNl {
fn default() -> SockaddrNl {
SockaddrNl {
nl_family: libc::AF_NETLINK as u16,
nl_pad: 0,
nl_pid: 0,
nl_groups: 0,
}
}
}
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct Nlmsghdr {
pub nlmsg_len: u32,
pub nlmsg_type: u16,
pub nlmsg_flags: u16,
pub nlmsg_seq: u32,
pub nlmsg_pid: u32,
}
pub const NLM_F_REQUEST: u16 = 0x01; pub const NLM_F_MULTI: u16 = 0x02; pub const NLM_F_ACK: u16 = 0x04; pub const NLM_F_ECHO: u16 = 0x08; pub const NLM_F_DUMP_INTR: u16 = 0x10; pub const NLM_F_DUMP_FILTERED: u16 = 0x20;
pub const NLM_F_ROOT: u16 = 0x100; pub const NLM_F_MATCH: u16 = 0x200; pub const NLM_F_ATOMIC: u16 = 0x400; pub const NLM_F_DUMP: u16 = NLM_F_ROOT | NLM_F_MATCH;
pub const NLM_F_REPLACE: u16 = 0x100; pub const NLM_F_EXCL: u16 = 0x200; pub const NLM_F_CREATE: u16 = 0x400; pub const NLM_F_APPEND: u16 = 0x800;
pub const NLM_F_NONREC: u16 = 0x100;
pub const NLM_F_CAPPED: u16 = 0x100; pub const NLM_F_ACK_TLVS: u16 = 0x200;
pub const NLMSG_ALIGNTO: u32 = 4;
pub const fn nlmsg_align(len: u32) -> u32 {
(len + NLMSG_ALIGNTO - 1) & !(NLMSG_ALIGNTO - 1)
}
pub const NLMSG_HDRLEN: u32 = nlmsg_align(mem::size_of::<Nlmsghdr>() as u32);
pub const fn nlmsg_length(len: u32) -> u32 {
len + NLMSG_HDRLEN
}
pub const fn nlmsg_space(len: u32) -> u32 {
nlmsg_align(nlmsg_length(len))
}
pub unsafe fn nlmsg_data<T>(nlh: &mut Nlmsghdr) -> &mut T {
&mut *((nlh as *mut _ as *mut u8).offset(nlmsg_length(0) as isize) as *mut T)
}
pub unsafe fn nlmsg_next<'a>(nlh: &'a mut Nlmsghdr, len: &mut u32) -> &'a mut Nlmsghdr {
*len -= nlmsg_align(nlh.nlmsg_len);
&mut *((nlh as *mut _ as *mut u8).offset(nlmsg_align(nlh.nlmsg_len) as isize) as *mut Nlmsghdr)
}
pub fn nlmsg_ok(nlh: &Nlmsghdr, len: u32) -> bool {
len >= mem::size_of::<Nlmsghdr>() as u32
&& nlh.nlmsg_len >= mem::size_of::<Nlmsghdr>() as u32
&& nlh.nlmsg_len <= len
}
pub const fn nlmsg_payload(nlh: &Nlmsghdr, len: u32) -> u32 {
nlh.nlmsg_len - nlmsg_space(len)
}
#[derive(PartialEq, Eq, Hash)]
pub enum MsgType {
Noop, Error, Done, Overrun, Other(u16),
}
pub const NLMSG_MIN_TYPE: u16 = 0x10;
#[allow(clippy::from_over_into)]
impl Into<u16> for MsgType {
fn into(self) -> u16 {
match self {
Self::Noop => 0x1,
Self::Error => 0x2,
Self::Done => 0x3,
Self::Overrun => 0x4,
Self::Other(v) => v,
}
}
}
impl std::convert::TryFrom<u16> for MsgType {
type Error = Errno;
fn try_from(v: u16) -> std::result::Result<Self, Errno> {
match v {
0x1 => Ok(Self::Noop),
0x2 => Ok(Self::Error),
0x3 => Ok(Self::Done),
0x4 => Ok(Self::Overrun),
n if n < NLMSG_MIN_TYPE => Err(Errno(libc::ERANGE)),
_ => Ok(Self::Other(v)),
}
}
}
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct Nlmsgerr {
pub error: c_int,
pub msg: Nlmsghdr,
}
#[repr(u16)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum NlmsgerrAttrs {
Unused = 0,
Msg = 1,
Offs = 2,
Cookie = 3,
_MAX = 4,
}
pub const NETLINK_ADD_MEMBERSHIP: c_int = 1;
pub const NETLINK_DROP_MEMBERSHIP: c_int = 2;
pub const NETLINK_PKTINFO: c_int = 3;
pub const NETLINK_BROADCAST_ERROR: c_int = 4;
pub const NETLINK_NO_ENOBUFS: c_int = 5;
pub const NETLINK_LISTEN_ALL_NSID: c_int = 8;
pub const NETLINK_LIST_MEMBERSHIPS: c_int = 9;
pub const NETLINK_CAP_ACK: c_int = 10;
pub const NETLINK_EXT_ACK: c_int = 11;
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct NlPktinfo {
group: u32,
}
pub const NET_MAJOR: c_uint = 36;
pub const NETLINK_UNCONNECTED: u8 = 0;
pub const NETLINK_CONNECTED: u8 = 1;
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct Nlattr {
pub nla_len: u16,
pub nla_type: u16,
}
pub const NLA_F_NESTED: u16 = 1 << 15;
pub const NLA_F_NET_BYTEORDER: u16 = 1 << 14;
pub const NLA_TYPE_MASK: u16 = !(NLA_F_NESTED | NLA_F_NET_BYTEORDER);
pub const NLA_ALIGNTO: u16 = 4;
pub const fn nla_align(len: u16) -> u16 {
(len + NLA_ALIGNTO - 1) & !(NLA_ALIGNTO - 1)
}
pub const NLA_HDRLEN: u16 = nla_align(mem::size_of::<Nlattr>() as u16);
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct NlaBitfield32 {
pub value: u32,
pub selector: u32,
}
#[repr(u32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum NetlinkAttrType {
Invalid,
Flag,
U8,
U16,
U32,
U64,
S8,
S16,
S32,
S64,
Binary,
String,
NulString,
Nested,
NestedArray,
Bitfield32,
}
pub const NL_ATTR_TYPE_INVALID: u32 = NetlinkAttrType::Invalid as u32;
pub const NL_ATTR_TYPE_FLAG: u32 = NetlinkAttrType::Flag as u32;
pub const NL_ATTR_TYPE_U8: u32 = NetlinkAttrType::U8 as u32;
pub const NL_ATTR_TYPE_U16: u32 = NetlinkAttrType::U16 as u32;
pub const NL_ATTR_TYPE_U32: u32 = NetlinkAttrType::U32 as u32;
pub const NL_ATTR_TYPE_U64: u32 = NetlinkAttrType::U64 as u32;
pub const NL_ATTR_TYPE_S8: u32 = NetlinkAttrType::S8 as u32;
pub const NL_ATTR_TYPE_S16: u32 = NetlinkAttrType::S16 as u32;
pub const NL_ATTR_TYPE_S32: u32 = NetlinkAttrType::S32 as u32;
pub const NL_ATTR_TYPE_S64: u32 = NetlinkAttrType::S64 as u32;
pub const NL_ATTR_TYPE_BINARY: u32 = NetlinkAttrType::Binary as u32;
pub const NL_ATTR_TYPE_STRING: u32 = NetlinkAttrType::String as u32;
pub const NL_ATTR_TYPE_NUL_STRING: u32 = NetlinkAttrType::NulString as u32;
pub const NL_ATTR_TYPE_NESTED: u32 = NetlinkAttrType::Nested as u32;
pub const NL_ATTR_TYPE_NESTED_ARRAY: u32 = NetlinkAttrType::NestedArray as u32;
pub const NL_ATTR_TYPE_BITFIELD32: u32 = NetlinkAttrType::Bitfield32 as u32;
#[repr(u16)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, NlaType)]
#[tbname = "NetlinkPolicyTypeAttrTbl"]
pub enum NetlinkPolicyTypeAttr {
Unspec,
#[nla_type(u32, atype)]
Type,
#[nla_type(i64, min_value_s)]
MinValueS,
#[nla_type(i64, max_value_s)]
MaxValueS,
#[nla_type(u64, min_value_u)]
MinValueU,
#[nla_type(u64, max_value_u)]
MaxValueU,
#[nla_type(u32, min_length)]
MinLength,
#[nla_type(u32, max_length)]
MaxLength,
#[nla_type(u32, policy_idx)]
PolicyIdx,
#[nla_type(u32, policy_max_type)]
PolicyMaxtype,
#[nla_type(u32, bitfield32_mask)]
Bitfield32Mask,
Pad,
_MAX,
}