netlink_packet_sock_diag/unix/request.rs
1// SPDX-License-Identifier: MIT
2
3use std::convert::TryFrom;
4
5use netlink_packet_utils::{
6 buffer,
7 traits::{Emitable, Parseable},
8 DecodeError,
9};
10
11use crate::constants::*;
12
13pub const UNIX_REQUEST_LEN: usize = 24;
14
15buffer!(UnixRequestBuffer(UNIX_REQUEST_LEN) {
16 // The address family; it should be set to `AF_UNIX`
17 family: (u8, 0),
18 // This field should be set to `0`
19 protocol: (u8, 1),
20 // This field should be set to `0`
21 pad: (u16, 2..4),
22 // This is a bit mask that defines a filter of sockets
23 // states. Only those sockets whose states are in this mask will
24 // be reported. Ignored when querying for an individual
25 // socket. Supported values are:
26 //
27 // ```no_rust
28 // 1 << UNIX_ESTABLISHED
29 // 1 << UNIX_LISTEN
30 // ```
31 state_flags: (u32, 4..8),
32 // This is an inode number when querying for an individual
33 // socket. Ignored when querying for a list of sockets.
34 inode: (u32, 8..12),
35 // This is a set of flags defining what kind of information to
36 // report. Supported values are the `UDIAG_SHOW_*` constants.
37 show_flags: (u32, 12..16),
38 // This is an array of opaque identifiers that could be used
39 // along with udiag_ino to specify an individual socket. It is
40 // ignored when querying for a list of sockets, as well as when
41 // all its elements are set to `0xff`.
42 cookie: (slice, 16..UNIX_REQUEST_LEN),
43});
44
45/// The request for UNIX domain sockets
46#[derive(Debug, PartialEq, Eq, Clone)]
47pub struct UnixRequest {
48 /// This is a bit mask that defines a filter of sockets states.
49 ///
50 /// Only those sockets whose states are in this mask will be reported.
51 /// Ignored when querying for an individual socket.
52 pub state_flags: StateFlags,
53 /// This is an inode number when querying for an individual socket.
54 ///
55 /// Ignored when querying for a list of sockets.
56 pub inode: u32,
57 /// This is a set of flags defining what kind of information to report.
58 ///
59 /// Each requested kind of information is reported back as a netlink
60 /// attribute
61 pub show_flags: ShowFlags,
62 /// This is an opaque identifiers that could be used to specify an
63 /// individual socket.
64 pub cookie: [u8; 8],
65}
66
67bitflags! {
68 /// Bitmask that defines a filter of UNIX socket states
69 pub struct StateFlags: u32 {
70 const ESTABLISHED = 1 << TCP_ESTABLISHED;
71 const LISTEN = 1 << TCP_LISTEN;
72 }
73}
74
75bitflags! {
76 /// Bitmask that defines what kind of information to
77 /// report. Supported values are the `UDIAG_SHOW_*` constants.
78 pub struct ShowFlags: u32 {
79 const NAME = UDIAG_SHOW_NAME;
80 const VFS = UDIAG_SHOW_VFS;
81 const PEER = UDIAG_SHOW_PEER;
82 const ICONS = UDIAG_SHOW_ICONS;
83 const RQLEN = UDIAG_SHOW_RQLEN;
84 const MEMINFO = UDIAG_SHOW_MEMINFO;
85 }
86}
87
88impl<'a, T: AsRef<[u8]> + 'a> Parseable<UnixRequestBuffer<&'a T>>
89 for UnixRequest
90{
91 fn parse(buf: &UnixRequestBuffer<&'a T>) -> Result<Self, DecodeError> {
92 Ok(Self {
93 state_flags: StateFlags::from_bits_truncate(buf.state_flags()),
94 inode: buf.inode(),
95 show_flags: ShowFlags::from_bits_truncate(buf.show_flags()),
96 // Unwrapping is safe because UnixRequestBuffer::cookie()
97 // returns a slice of exactly 8 bytes.
98 cookie: TryFrom::try_from(buf.cookie()).unwrap(),
99 })
100 }
101}
102
103impl Emitable for UnixRequest {
104 fn buffer_len(&self) -> usize {
105 UNIX_REQUEST_LEN
106 }
107
108 fn emit(&self, buf: &mut [u8]) {
109 let mut buffer = UnixRequestBuffer::new(buf);
110 buffer.set_family(AF_UNIX);
111 buffer.set_protocol(0);
112 buffer.set_state_flags(self.state_flags.bits());
113 buffer.set_inode(self.inode);
114 buffer.set_pad(0);
115 buffer.set_show_flags(self.show_flags.bits());
116 buffer.cookie_mut().copy_from_slice(&self.cookie[..]);
117 }
118}