netlink_packet_sock_diag/inet/
response.rs1use std::time::Duration;
4
5use anyhow::Context;
6use netlink_packet_utils::nla::{NlaBuffer, NlasIterator};
7use netlink_packet_utils::traits::{Emitable, Parseable, ParseableParametrized};
8use netlink_packet_utils::{DecodeError, buffer};
9use smallvec::SmallVec;
10
11use crate::inet::nlas::Nla;
12use crate::inet::{SocketId, SocketIdBuffer};
13
14#[derive(Debug, PartialEq, Eq, Clone)]
16pub enum Timer {
17 Retransmit(Duration, u8),
19 KeepAlive(Duration),
21 TimeWait,
23 Probe(Duration),
25}
26
27pub const RESPONSE_LEN: usize = 72;
28
29buffer!(InetResponseBuffer(RESPONSE_LEN) {
30 family: (u8, 0),
31 state: (u8, 1),
32 timer: (u8, 2),
33 retransmits: (u8, 3),
34 socket_id: (slice, 4..52),
35 expires: (u32, 52..56),
36 recv_queue: (u32, 56..60),
37 send_queue: (u32, 60..64),
38 uid: (u32, 64..68),
39 inode: (u32, 68..72),
40 payload: (slice, RESPONSE_LEN..),
41});
42
43#[derive(Debug, PartialEq, Eq, Clone)]
45pub struct InetResponseHeader {
46 pub family: u8,
49
50 pub state: u8,
52
53 pub timer: Option<Timer>,
56
57 pub socket_id: SocketId,
59
60 pub recv_queue: u32,
63
64 pub send_queue: u32,
67
68 pub uid: u32,
70
71 pub inode: u32,
73}
74
75impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<InetResponseBuffer<&'a T>> for InetResponseHeader {
76 type Error = DecodeError;
77 fn parse(buf: &InetResponseBuffer<&'a T>) -> Result<Self, DecodeError> {
78 let err = "invalid socket_id value";
79 let socket_id = SocketId::parse_with_param(
80 &SocketIdBuffer::new(&buf.socket_id()).context(err)?,
81 buf.family(),
82 )
83 .context(err)?;
84
85 let timer = match buf.timer() {
86 1 => {
87 let expires = Duration::from_millis(buf.expires() as u64);
88 let retransmits = buf.retransmits();
89 Some(Timer::Retransmit(expires, retransmits))
90 }
91 2 => {
92 let expires = Duration::from_millis(buf.expires() as u64);
93 Some(Timer::KeepAlive(expires))
94 }
95 3 => Some(Timer::TimeWait),
96 4 => {
97 let expires = Duration::from_millis(buf.expires() as u64);
98 Some(Timer::Probe(expires))
99 }
100 _ => None,
101 };
102
103 Ok(Self {
104 family: buf.family(),
105 state: buf.state(),
106 timer,
107 socket_id,
108 recv_queue: buf.recv_queue(),
109 send_queue: buf.send_queue(),
110 uid: buf.uid(),
111 inode: buf.inode(),
112 })
113 }
114}
115
116impl Emitable for InetResponseHeader {
117 fn buffer_len(&self) -> usize {
118 RESPONSE_LEN
119 }
120
121 fn emit(&self, buf: &mut [u8]) {
122 let mut buf = InetResponseBuffer::new_unchecked(buf);
123 buf.set_family(self.family);
124 buf.set_state(self.state);
125 match self.timer {
126 Some(Timer::Retransmit(expires, retransmits)) => {
127 buf.set_timer(1);
128 buf.set_expires((expires.as_millis() & 0xffff_ffff) as u32);
129 buf.set_retransmits(retransmits);
130 }
131 Some(Timer::KeepAlive(expires)) => {
132 buf.set_timer(2);
133 buf.set_expires((expires.as_millis() & 0xffff_ffff) as u32);
134 buf.set_retransmits(0);
135 }
136 Some(Timer::TimeWait) => {
137 buf.set_timer(3);
138 buf.set_expires(0);
139 buf.set_retransmits(0);
140 }
141 Some(Timer::Probe(expires)) => {
142 buf.set_timer(4);
143 buf.set_expires((expires.as_millis() & 0xffff_ffff) as u32);
144 buf.set_retransmits(0);
145 }
146 None => {
147 buf.set_timer(0);
148 buf.set_expires(0);
149 buf.set_retransmits(0);
150 }
151 }
152 buf.set_recv_queue(self.recv_queue);
153 buf.set_send_queue(self.send_queue);
154 buf.set_uid(self.uid);
155 buf.set_inode(self.inode);
156 self.socket_id.emit(buf.socket_id_mut())
157 }
158}
159
160#[derive(Debug, PartialEq, Eq, Clone)]
161pub struct InetResponse {
162 pub header: InetResponseHeader,
163 pub nlas: SmallVec<[Nla; 8]>,
164}
165
166impl<'a, T: AsRef<[u8]> + ?Sized> InetResponseBuffer<&'a T> {
167 pub fn nlas(&self) -> impl Iterator<Item = Result<NlaBuffer<&'a [u8]>, DecodeError>> {
168 NlasIterator::new(self.payload()).map(|res| res.map_err(Into::into))
169 }
170}
171
172impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<InetResponseBuffer<&'a T>> for SmallVec<[Nla; 8]> {
173 type Error = DecodeError;
174 fn parse(buf: &InetResponseBuffer<&'a T>) -> Result<Self, DecodeError> {
175 let mut nlas = smallvec![];
176 for nla_buf in buf.nlas() {
177 nlas.push(Nla::parse(&nla_buf?)?);
178 }
179 Ok(nlas)
180 }
181}
182
183impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<InetResponseBuffer<&'a T>> for InetResponse {
184 type Error = DecodeError;
185 fn parse(buf: &InetResponseBuffer<&'a T>) -> Result<Self, DecodeError> {
186 let header =
187 InetResponseHeader::parse(buf).context("failed to parse inet response header")?;
188 let nlas =
189 SmallVec::<[Nla; 8]>::parse(buf).context("failed to parse inet response NLAs")?;
190 Ok(InetResponse { header, nlas })
191 }
192}
193
194impl Emitable for InetResponse {
195 fn buffer_len(&self) -> usize {
196 self.header.buffer_len() + self.nlas.as_slice().buffer_len()
197 }
198
199 fn emit(&self, buffer: &mut [u8]) {
200 self.header.emit(buffer);
201 self.nlas.as_slice().emit(&mut buffer[self.header.buffer_len()..]);
202 }
203}