netlink_packet_sock_diag/inet/
request.rs1use anyhow::Context;
4use netlink_packet_utils::nla::{DefaultNla, Nla, NlaBuffer, NlasIterator};
5use netlink_packet_utils::traits::{Emitable, Parseable};
6use netlink_packet_utils::{DecodeError, ParseableParametrized, buffer};
7use smallvec::SmallVec;
8
9use crate::constants::*;
10use crate::inet::{SocketId, SocketIdBuffer};
11
12pub const REQUEST_LEN: usize = 56;
13
14buffer!(InetRequestBuffer(REQUEST_LEN) {
15 family: (u8, 0),
16 protocol: (u8, 1),
17 extensions: (u8, 2),
18 pad: (u8, 3),
19 states: (u32, 4..8),
20 socket_id: (slice, 8..56),
21 payload: (slice, REQUEST_LEN..),
22});
23
24#[derive(Debug, PartialEq, Eq, Clone)]
25pub enum RequestNla {
26 Bytecode(Vec<u8>),
29 Other(DefaultNla),
30}
31
32impl Nla for RequestNla {
33 fn value_len(&self) -> usize {
34 match self {
35 Self::Bytecode(v) => v.len(),
36 Self::Other(attr) => attr.value_len(),
37 }
38 }
39
40 fn kind(&self) -> u16 {
41 match self {
42 Self::Bytecode(_) => INET_DIAG_REQ_BYTECODE,
43 Self::Other(attr) => attr.kind(),
44 }
45 }
46
47 fn emit_value(&self, buffer: &mut [u8]) {
48 match self {
49 Self::Bytecode(v) => buffer[..v.len()].copy_from_slice(&v[..]),
50 Self::Other(attr) => attr.emit_value(buffer),
51 }
52 }
53}
54
55impl<'a, T: AsRef<[u8]> + ?Sized> InetRequestBuffer<&'a T> {
56 pub fn nlas(&self) -> impl Iterator<Item = Result<NlaBuffer<&'a [u8]>, DecodeError>> {
57 NlasIterator::new(self.payload()).map(|res| res.map_err(Into::into))
58 }
59}
60
61impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for RequestNla {
62 type Error = DecodeError;
63 fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
64 let payload = buf.value();
65 Ok(match buf.kind() {
66 INET_DIAG_REQ_BYTECODE => Self::Bytecode(payload.to_vec()),
67 kind => {
68 Self::Other(DefaultNla::parse(buf).context(format!("unknown NLA type {kind}"))?)
69 }
70 })
71 }
72}
73
74#[derive(Debug, PartialEq, Eq, Clone)]
76pub struct InetRequest {
77 pub family: u8,
79 pub protocol: u8,
82 pub extensions: ExtensionFlags,
86 pub states: StateFlags,
88 pub socket_id: SocketId,
95 pub nlas: SmallVec<[RequestNla; 4]>,
96}
97
98bitflags! {
99 #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)]
101 pub struct StateFlags: u32 {
102 const ESTABLISHED = 1 << TCP_ESTABLISHED ;
106 const SYN_SENT = 1 <<TCP_SYN_SENT ;
109 const SYN_RECV = 1 << TCP_SYN_RECV ;
113 const FIN_WAIT1 = 1 << TCP_FIN_WAIT1 ;
118 const FIN_WAIT2 = 1 << TCP_FIN_WAIT2 ;
121 const TIME_WAIT = 1 << TCP_TIME_WAIT ;
125 const CLOSE = 1 << TCP_CLOSE ;
128 const CLOSE_WAIT = 1 << TCP_CLOSE_WAIT ;
131 const LAST_ACK = 1 << TCP_LAST_ACK ;
136 const LISTEN = 1 << TCP_LISTEN ;
139 const CLOSING = 1 << TCP_CLOSING ;
143 }
144}
145
146bitflags! {
147 #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)]
150 pub struct ExtensionFlags: u8 {
151 const MEMINFO = 1 << (INET_DIAG_MEMINFO - 1);
152 const INFO = 1 << (INET_DIAG_INFO - 1);
153 const VEGASINFO = 1 << (INET_DIAG_VEGASINFO - 1);
154 const CONG = 1 << (INET_DIAG_CONG - 1);
155 const TOS = 1 << (INET_DIAG_TOS - 1);
156 const TCLASS = 1 << (INET_DIAG_TCLASS - 1);
157 const SKMEMINFO = 1 << (INET_DIAG_SKMEMINFO - 1);
158 const SHUTDOWN = 1 << (INET_DIAG_SHUTDOWN - 1);
159 }
160}
161
162impl<'a, T: AsRef<[u8]> + ?Sized + 'a> Parseable<InetRequestBuffer<&'a T>> for InetRequest {
163 type Error = DecodeError;
164 fn parse(buf: &InetRequestBuffer<&'a T>) -> Result<Self, DecodeError> {
165 let err = "invalid socket_id value";
166 let socket_id = SocketId::parse_with_param(
167 &SocketIdBuffer::new(&buf.socket_id()).context(err)?,
168 buf.family(),
169 )
170 .context(err)?;
171
172 let mut nlas = SmallVec::new();
173 for nla_buf in buf.nlas() {
174 nlas.push(RequestNla::parse(&nla_buf?)?);
175 }
176
177 Ok(Self {
178 family: buf.family(),
179 protocol: buf.protocol(),
180 extensions: ExtensionFlags::from_bits_truncate(buf.extensions()),
181 states: StateFlags::from_bits_truncate(buf.states()),
182 socket_id,
183 nlas,
184 })
185 }
186}
187
188impl Emitable for InetRequest {
189 fn buffer_len(&self) -> usize {
190 REQUEST_LEN + self.nlas.as_slice().buffer_len()
191 }
192
193 fn emit(&self, buf: &mut [u8]) {
194 let mut buf = InetRequestBuffer::new_unchecked(buf);
195 buf.set_family(self.family);
196 buf.set_protocol(self.protocol);
197 buf.set_extensions(self.extensions.bits());
198 buf.set_pad(0);
199 buf.set_states(self.states.bits());
200 self.socket_id.emit(buf.socket_id_mut());
201 self.nlas.as_slice().emit(&mut buf.payload_mut());
202 }
203}