netlink_packet_sock_diag/inet/
request.rs

1// SPDX-License-Identifier: MIT
2
3use anyhow::Context;
4use netlink_packet_utils::traits::{Emitable, Parseable, ParseableParametrized};
5use netlink_packet_utils::{DecodeError, buffer};
6
7use crate::constants::*;
8use crate::inet::{SocketId, SocketIdBuffer};
9
10pub const REQUEST_LEN: usize = 56;
11
12buffer!(InetRequestBuffer(REQUEST_LEN) {
13    family: (u8, 0),
14    protocol: (u8, 1),
15    extensions: (u8, 2),
16    pad: (u8, 3),
17    states: (u32, 4..8),
18    socket_id: (slice, 8..56),
19});
20
21/// A request for Ipv4 and Ipv6 sockets
22#[derive(Debug, PartialEq, Eq, Clone)]
23pub struct InetRequest {
24    /// The address family, either `AF_INET` or `AF_INET6`
25    pub family: u8,
26    /// The IP protocol. This field should be set to one of the
27    /// `IPPROTO_*` constants
28    pub protocol: u8,
29    /// Set of flags defining what kind of extended information to
30    /// report. Each requested kind of information is reported back as
31    /// a netlink attribute.
32    pub extensions: ExtensionFlags,
33    /// Bitmask that defines a filter of TCP socket states
34    pub states: StateFlags,
35    /// A socket ID object that is used in dump requests, in queries
36    /// about individual sockets, and is reported back in each
37    /// response.
38    ///
39    /// Unlike UNIX domain sockets, IPv4 and IPv6 sockets are
40    /// identified using addresses and ports.
41    pub socket_id: SocketId,
42}
43
44bitflags! {
45    /// Bitmask that defines a filter of TCP socket states
46    #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)]
47    pub struct StateFlags: u32 {
48        /// (server and client) represents an open connection,
49        /// data received can be delivered to the user. The normal
50        /// state for the data transfer phase of the connection.
51        const ESTABLISHED = 1 << TCP_ESTABLISHED ;
52        /// (client) represents waiting for a matching connection
53        /// request after having sent a connection request.
54        const SYN_SENT = 1 <<TCP_SYN_SENT ;
55        /// (server) represents waiting for a confirming connection
56        /// request acknowledgment after having both received and sent
57        /// a connection request.
58        const SYN_RECV = 1 << TCP_SYN_RECV ;
59        /// (both server and client) represents waiting for a
60        /// connection termination request from the remote TCP, or an
61        /// acknowledgment of the connection termination request
62        /// previously sent.
63        const FIN_WAIT1 = 1 << TCP_FIN_WAIT1 ;
64        /// (both server and client) represents waiting for a
65        /// connection termination request from the remote TCP.
66        const FIN_WAIT2 = 1 << TCP_FIN_WAIT2 ;
67        /// (either server or client) represents waiting for enough
68        /// time to pass to be sure the remote TCP received the
69        /// acknowledgment of its connection termination request.
70        const TIME_WAIT = 1 << TCP_TIME_WAIT ;
71        /// (both server and client) represents no connection state at
72        /// all.
73        const CLOSE = 1 << TCP_CLOSE ;
74        /// (both server and client) represents waiting for a
75        /// connection termination request from the local user.
76        const CLOSE_WAIT = 1 << TCP_CLOSE_WAIT ;
77        /// (both server and client) represents waiting for an
78        /// acknowledgment of the connection termination request
79        /// previously sent to the remote TCP (which includes an
80        /// acknowledgment of its connection termination request).
81        const LAST_ACK = 1 << TCP_LAST_ACK ;
82        /// (server) represents waiting for a connection request from
83        /// any remote TCP and port.
84        const LISTEN = 1 << TCP_LISTEN ;
85        /// (both server and client) represents waiting for a
86        /// connection termination request acknowledgment from the
87        /// remote TCP.
88        const CLOSING = 1 << TCP_CLOSING ;
89    }
90}
91
92bitflags! {
93    /// This is a set of flags defining what kind of extended
94    /// information to report.
95    #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)]
96    pub struct ExtensionFlags: u8 {
97        const MEMINFO = 1 << (INET_DIAG_MEMINFO - 1);
98        const INFO = 1 << (INET_DIAG_INFO - 1);
99        const VEGASINFO = 1 << (INET_DIAG_VEGASINFO - 1);
100        const CONG = 1 << (INET_DIAG_CONG - 1);
101        const TOS = 1 << (INET_DIAG_TOS - 1);
102        const TCLASS = 1 << (INET_DIAG_TCLASS - 1);
103        const SKMEMINFO = 1 << (INET_DIAG_SKMEMINFO - 1);
104        const SHUTDOWN = 1 << (INET_DIAG_SHUTDOWN - 1);
105    }
106}
107
108impl<'a, T: AsRef<[u8]> + ?Sized + 'a> Parseable<InetRequestBuffer<&'a T>> for InetRequest {
109    type Error = DecodeError;
110    fn parse(buf: &InetRequestBuffer<&'a T>) -> Result<Self, DecodeError> {
111        let err = "invalid socket_id value";
112        let socket_id = SocketId::parse_with_param(
113            &SocketIdBuffer::new(&buf.socket_id()).context(err)?,
114            buf.family(),
115        )
116        .context(err)?;
117
118        Ok(Self {
119            family: buf.family(),
120            protocol: buf.protocol(),
121            extensions: ExtensionFlags::from_bits_truncate(buf.extensions()),
122            states: StateFlags::from_bits_truncate(buf.states()),
123            socket_id,
124        })
125    }
126}
127
128impl Emitable for InetRequest {
129    fn buffer_len(&self) -> usize {
130        REQUEST_LEN
131    }
132
133    fn emit(&self, buf: &mut [u8]) {
134        let mut buf = InetRequestBuffer::new_unchecked(buf);
135        buf.set_family(self.family);
136        buf.set_protocol(self.protocol);
137        buf.set_extensions(self.extensions.bits());
138        buf.set_pad(0);
139        buf.set_states(self.states.bits());
140        self.socket_id.emit(buf.socket_id_mut())
141    }
142}