use libc::{ c_int, c_uint, sockaddr_nl };
use std::mem::size_of;
pub const NETLINK_ROUTE: c_int = 0; pub const NETLINK_UNUSED: c_int = 1; pub const NETLINK_USERSOCK: c_int = 2; pub const NETLINK_FIREWALL: c_int = 3; pub const NETLINK_SOCK_DIAG: c_int = 4; pub const NETLINK_NFLOG: c_int = 5; pub const NETLINK_XFRM: c_int = 6; pub const NETLINK_SELINUX: c_int = 7; pub const NETLINK_ISCSI: c_int = 8; pub const NETLINK_AUDIT: c_int = 9; pub const NETLINK_FIB_LOOKUP: c_int = 10;
pub const NETLINK_CONNECTOR: c_int = 11;
pub const NETLINK_NETFILTER: c_int = 12; pub const NETLINK_IP6_FW: c_int = 13;
pub const NETLINK_DNRTMSG: c_int = 14; pub const NETLINK_KOBJECT_UEVENT: c_int = 15; pub const NETLINK_GENERIC: c_int = 16;
pub const NETLINK_SCSITRANSPORT: c_int = 18; pub const NETLINK_ECRYPTFS: c_int = 19;
pub const NETLINK_RDMA: c_int = 20;
pub const NETLINK_CRYPTO: c_int = 21; pub const NETLINK_SMC: c_int = 22;
pub const NETLINK_INET_DIAG: c_int = NETLINK_SOCK_DIAG;
pub const MAX_LINKS: c_int = 32;
#[allow(non_camel_case_types)]
pub enum Family {
ROUTE, UNUSED, USERSOCK, FIREWALL, SOCK_DIAG, NFLOG, XFRM, SELINUX, ISCSI, AUDIT, FIB_LOOKUP,
CONNECTOR,
NETFILTER, IP6_FW,
DNRTMSG, KOBJECT_UEVENT, GENERIC,
SCSITRANSPORT, ECRYPTFS,
RDMA,
CRYPTO,
INET_DIAG, }
impl Family {
pub fn c_int(self) -> c_int {
match self {
Family::ROUTE => NETLINK_ROUTE,
Family::UNUSED => NETLINK_UNUSED,
Family::USERSOCK => NETLINK_USERSOCK,
Family::FIREWALL => NETLINK_FIREWALL,
Family::SOCK_DIAG => NETLINK_SOCK_DIAG,
Family::NFLOG => NETLINK_NFLOG,
Family::XFRM => NETLINK_XFRM,
Family::SELINUX => NETLINK_SELINUX,
Family::ISCSI => NETLINK_ISCSI,
Family::AUDIT => NETLINK_AUDIT,
Family::FIB_LOOKUP => NETLINK_FIB_LOOKUP,
Family::CONNECTOR => NETLINK_CONNECTOR,
Family::NETFILTER => NETLINK_NETFILTER,
Family::IP6_FW => NETLINK_IP6_FW,
Family::DNRTMSG => NETLINK_DNRTMSG,
Family::KOBJECT_UEVENT => NETLINK_KOBJECT_UEVENT,
Family::GENERIC => NETLINK_GENERIC,
Family::SCSITRANSPORT => NETLINK_SCSITRANSPORT,
Family::ECRYPTFS => NETLINK_ECRYPTFS,
Family::RDMA => NETLINK_RDMA,
Family::CRYPTO => NETLINK_CRYPTO,
Family::INET_DIAG => NETLINK_INET_DIAG,
}
}
}
pub struct SockaddrNl { inner: sockaddr_nl }
#[repr(C)]
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_CAPPED: u16 = 0x100; pub const NLM_F_ACK_TLVS: u16 = 0x200;
pub const NLMSG_ALIGNTO: u32 = 4;
#[allow(non_snake_case)]
pub fn NLMSG_ALIGN(len: u32) -> u32 {
(len + NLMSG_ALIGNTO - 1) & !(NLMSG_ALIGNTO - 1)
}
#[allow(non_snake_case)]
pub fn NLMSG_HDRLEN() -> u32 {
NLMSG_ALIGN(size_of::<Nlmsghdr>() as u32)
}
#[allow(non_snake_case)]
pub fn NLMSG_LENGTH(len: u32) -> u32 {
len + NLMSG_HDRLEN()
}
#[allow(non_snake_case)]
pub fn NLMSG_SPACE(len: u32) -> u32 {
NLMSG_ALIGN(NLMSG_LENGTH(len))
}
#[allow(non_snake_case)]
pub fn NLMSG_DATA<T>(nlh: &mut Nlmsghdr) -> &mut T {
unsafe {
((nlh as *mut _ as *mut u8)
.offset(NLMSG_LENGTH(0) as isize) as *mut T)
.as_mut()
}.unwrap()
}
#[allow(non_snake_case)]
pub fn NLMSG_NEXT<'a>(nlh: &'a mut Nlmsghdr, len: &mut u32) -> &'a mut Nlmsghdr {
*len -= NLMSG_ALIGN(nlh.nlmsg_len);
unsafe {
((nlh as *mut _ as *mut u8)
.offset(NLMSG_ALIGN(nlh.nlmsg_len) as isize) as *mut Nlmsghdr)
.as_mut()
}.unwrap()
}
#[allow(non_snake_case)]
pub fn NLMSG_OK(nlh: &Nlmsghdr, len: u32) -> bool {
len >= size_of::<Nlmsghdr>() as u32 &&
nlh.nlmsg_len >= size_of::<Nlmsghdr>() as u32 &&
nlh.nlmsg_len <= len
}
#[allow(non_snake_case)]
pub fn NLMSG_PAYLOAD(nlh: &Nlmsghdr, len: u32) -> u32 {
nlh.nlmsg_len - NLMSG_SPACE((len))
}
pub const NLMSG_NOOP: u16 = 0x1; pub const NLMSG_ERROR: u16 = 0x2; pub const NLMSG_DONE: u16 = 0x3; pub const NLMSG_OVERRUN: u16 = 0x4;
pub const NLMSG_MIN_TYPE: u16 = 0x10;
#[repr(C)]
pub struct Nlmsgerr { pub error: c_int,
pub msg: Nlmsghdr,
}
#[allow(non_camel_case_types)]
#[repr(u16)]
pub enum NlmsgerrAttrs {
UNUSED = 0,
MSG = 1,
OFFS = 2,
COOKIE = 3,
MAX = 4,
}
pub const NLMSGERR_ATTR_UNUSED: u16 = NlmsgerrAttrs::UNUSED as u16;
pub const NLMSGERR_ATTR_MSG: u16 = NlmsgerrAttrs::MSG as u16;
pub const NLMSGERR_ATTR_OFFS: u16 = NlmsgerrAttrs::OFFS as u16;
pub const NLMSGERR_ATTR_COOKIE: u16 = NlmsgerrAttrs::COOKIE as u16;
pub const __NLMSGERR_ATTR_MAX: u16 = NlmsgerrAttrs::MAX as u16;
pub const MSGERR_ATTR_MAX: u16 = __NLMSGERR_ATTR_MAX - 1;
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)]
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)]
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;
#[allow(non_snake_case)]
pub fn NLA_ALIGN(len: u16) -> u16 {
(len + NLA_ALIGNTO - 1) & !(NLA_ALIGNTO - 1)
}
#[allow(non_snake_case)]
pub fn NLA_HDRLEN() -> u16 {
NLA_ALIGN(size_of::<Nlattr>() as u16)
}