1use std::mem;
2
3extern crate errno;
4extern crate libc;
5
6use errno::Errno;
7use libc::{c_int, c_uint};
8
9use mnl::{Attr, AttrTbl, MsgVec, Result};
10
11#[repr(C)]
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
13pub enum Family {
14 Route = 0, Unused = 1, Usersock = 2, Firewall = 3, SockDiag = 4, Nflog = 5, Xfrm = 6, Selinux = 7, Iscsi = 8, Audit = 9, FibLookup = 10,
25 Connector = 11,
26 Netfilter = 12, Ip6Fw = 13,
28 Dnrtmsg = 14, KobjectUevent = 15, Generic = 16,
31
32 Scsitransport = 18, Ecryptfs = 19,
34 Rdma = 20,
35 Crypto = 21, Smc = 22, InetDiag, }
40
41impl Into<c_int> for Family {
42 fn into(self) -> c_int {
43 if self == Family::InetDiag {
44 return Family::SockDiag as c_int;
45 }
46 self as c_int
47 }
48}
49
50pub const MAX_LINKS: c_int = 32;
51
52#[repr(C)]
54#[derive(Debug, Clone, Copy)]
55pub struct SockaddrNl {
56 pub nl_family: u16,
57 nl_pad: u16,
58 pub nl_pid: u32,
59 pub nl_groups: u32,
60}
61
62impl Default for SockaddrNl {
63 fn default() -> SockaddrNl {
64 SockaddrNl {
65 nl_family: libc::AF_NETLINK as u16,
66 nl_pad: 0,
67 nl_pid: 0,
68 nl_groups: 0,
69 }
70 }
71}
72
73#[repr(C)]
74#[derive(Debug, Clone, Copy)]
75pub struct Nlmsghdr {
76 pub nlmsg_len: u32,
77 pub nlmsg_type: u16,
78 pub nlmsg_flags: u16,
79 pub nlmsg_seq: u32,
80 pub nlmsg_pid: u32,
81}
82
83pub 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;
96
97pub 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;
118pub const fn nlmsg_align(len: u32) -> u32 {
119 (len + NLMSG_ALIGNTO - 1) & !(NLMSG_ALIGNTO - 1)
120}
121pub const NLMSG_HDRLEN: u32 = nlmsg_align(mem::size_of::<Nlmsghdr>() as u32);
122pub const fn nlmsg_length(len: u32) -> u32 {
123 len + NLMSG_HDRLEN
124}
125pub const fn nlmsg_space(len: u32) -> u32 {
126 nlmsg_align(nlmsg_length(len))
127}
128pub unsafe fn nlmsg_data<T>(nlh: &mut Nlmsghdr) -> &mut T {
129 &mut *((nlh as *mut _ as *mut u8).offset(nlmsg_length(0) as isize) as *mut T)
130}
131pub unsafe fn nlmsg_next<'a>(nlh: &'a mut Nlmsghdr, len: &mut u32) -> &'a mut Nlmsghdr {
132 *len -= nlmsg_align(nlh.nlmsg_len);
133 &mut *((nlh as *mut _ as *mut u8).offset(nlmsg_align(nlh.nlmsg_len) as isize) as *mut Nlmsghdr)
134}
135pub fn nlmsg_ok(nlh: &Nlmsghdr, len: u32) -> bool {
136 len >= mem::size_of::<Nlmsghdr>() as u32
137 && nlh.nlmsg_len >= mem::size_of::<Nlmsghdr>() as u32
138 && nlh.nlmsg_len <= len
139}
140pub const fn nlmsg_payload(nlh: &Nlmsghdr, len: u32) -> u32 {
141 nlh.nlmsg_len - nlmsg_space(len)
142}
143
144#[derive(PartialEq, Eq, Hash)]
145pub enum MsgType {
146 Noop, Error, Done, Overrun, Other(u16),
151}
152pub const NLMSG_MIN_TYPE: u16 = 0x10; #[allow(clippy::from_over_into)]
155impl Into<u16> for MsgType {
156 fn into(self) -> u16 {
157 match self {
158 Self::Noop => 0x1,
159 Self::Error => 0x2,
160 Self::Done => 0x3,
161 Self::Overrun => 0x4,
162 Self::Other(v) => v,
163 }
164 }
165}
166
167impl std::convert::TryFrom<u16> for MsgType {
168 type Error = Errno;
169
170 fn try_from(v: u16) -> std::result::Result<Self, Errno> {
171 match v {
172 0x1 => Ok(Self::Noop),
173 0x2 => Ok(Self::Error),
174 0x3 => Ok(Self::Done),
175 0x4 => Ok(Self::Overrun),
176 n if n < NLMSG_MIN_TYPE => Err(Errno(libc::ERANGE)),
177 _ => Ok(Self::Other(v)),
178 }
179 }
180}
181
182#[repr(C)]
183#[derive(Debug, Clone, Copy)]
184pub struct Nlmsgerr {
185 pub error: c_int,
187 pub msg: Nlmsghdr, }
195
196#[repr(u16)]
207#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
208pub enum NlmsgerrAttrs {
209 Unused = 0,
210 Msg = 1,
211 Offs = 2,
212 Cookie = 3,
213 _MAX = 4,
214}
215
216pub const NETLINK_ADD_MEMBERSHIP: c_int = 1;
217pub const NETLINK_DROP_MEMBERSHIP: c_int = 2;
218pub const NETLINK_PKTINFO: c_int = 3;
219pub const NETLINK_BROADCAST_ERROR: c_int = 4;
220pub const NETLINK_NO_ENOBUFS: c_int = 5;
221pub const NETLINK_LISTEN_ALL_NSID: c_int = 8;
224pub const NETLINK_LIST_MEMBERSHIPS: c_int = 9;
225pub const NETLINK_CAP_ACK: c_int = 10;
226pub const NETLINK_EXT_ACK: c_int = 11;
227
228#[repr(C)]
229#[derive(Debug, Clone, Copy)]
230pub struct NlPktinfo {
231 group: u32,
232}
233
234pub const NET_MAJOR: c_uint = 36; pub const NETLINK_UNCONNECTED: u8 = 0;
238pub const NETLINK_CONNECTED: u8 = 1;
239
240#[repr(C)]
247#[derive(Debug, Clone, Copy)]
248pub struct Nlattr {
249 pub nla_len: u16,
250 pub nla_type: u16,
251}
252
253pub const NLA_F_NESTED: u16 = 1 << 15;
262pub const NLA_F_NET_BYTEORDER: u16 = 1 << 14;
263pub const NLA_TYPE_MASK: u16 = !(NLA_F_NESTED | NLA_F_NET_BYTEORDER);
264
265pub const NLA_ALIGNTO: u16 = 4;
266
267pub const fn nla_align(len: u16) -> u16 {
268 (len + NLA_ALIGNTO - 1) & !(NLA_ALIGNTO - 1)
269}
270
271pub const NLA_HDRLEN: u16 = nla_align(mem::size_of::<Nlattr>() as u16);
272
273#[repr(C)]
285#[derive(Debug, Clone, Copy)]
286pub struct NlaBitfield32 {
287 pub value: u32,
289 pub selector: u32,
290}
291
292#[repr(u32)]
321#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
322pub enum NetlinkAttrType {
323 Invalid,
325 Flag,
326 U8,
327 U16,
328 U32,
329 U64,
330 S8,
331 S16,
332 S32,
333 S64,
334 Binary,
335 String,
336 NulString,
337 Nested,
338 NestedArray,
339 Bitfield32,
340}
341pub const NL_ATTR_TYPE_INVALID: u32 = NetlinkAttrType::Invalid as u32;
342pub const NL_ATTR_TYPE_FLAG: u32 = NetlinkAttrType::Flag as u32;
343pub const NL_ATTR_TYPE_U8: u32 = NetlinkAttrType::U8 as u32;
344pub const NL_ATTR_TYPE_U16: u32 = NetlinkAttrType::U16 as u32;
345pub const NL_ATTR_TYPE_U32: u32 = NetlinkAttrType::U32 as u32;
346pub const NL_ATTR_TYPE_U64: u32 = NetlinkAttrType::U64 as u32;
347pub const NL_ATTR_TYPE_S8: u32 = NetlinkAttrType::S8 as u32;
348pub const NL_ATTR_TYPE_S16: u32 = NetlinkAttrType::S16 as u32;
349pub const NL_ATTR_TYPE_S32: u32 = NetlinkAttrType::S32 as u32;
350pub const NL_ATTR_TYPE_S64: u32 = NetlinkAttrType::S64 as u32;
351pub const NL_ATTR_TYPE_BINARY: u32 = NetlinkAttrType::Binary as u32;
352pub const NL_ATTR_TYPE_STRING: u32 = NetlinkAttrType::String as u32;
353pub const NL_ATTR_TYPE_NUL_STRING: u32 = NetlinkAttrType::NulString as u32;
354pub const NL_ATTR_TYPE_NESTED: u32 = NetlinkAttrType::Nested as u32;
355pub const NL_ATTR_TYPE_NESTED_ARRAY: u32 = NetlinkAttrType::NestedArray as u32;
356pub const NL_ATTR_TYPE_BITFIELD32: u32 = NetlinkAttrType::Bitfield32 as u32;
357
358#[repr(u16)]
384#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, NlaType)]
385#[tbname = "NetlinkPolicyTypeAttrTbl"]
386pub enum NetlinkPolicyTypeAttr {
387 Unspec,
389
390 #[nla_type(u32, atype)]
391 Type,
392
393 #[nla_type(i64, min_value_s)]
394 MinValueS,
395
396 #[nla_type(i64, max_value_s)]
397 MaxValueS,
398
399 #[nla_type(u64, min_value_u)]
400 MinValueU,
401
402 #[nla_type(u64, max_value_u)]
403 MaxValueU,
404
405 #[nla_type(u32, min_length)]
406 MinLength,
407
408 #[nla_type(u32, max_length)]
409 MaxLength,
410
411 #[nla_type(u32, policy_idx)]
412 PolicyIdx,
413
414 #[nla_type(u32, policy_max_type)]
415 PolicyMaxtype,
416
417 #[nla_type(u32, bitfield32_mask)]
418 Bitfield32Mask,
419
420 Pad,
421
422 _MAX,
424}