1use super::flags::TcpFlags;
4use crate::error::ParseError;
5
6pub(super) const HEADER_LENGTH: usize = 20;
7
8#[derive(Clone, Copy, Debug, Eq, PartialEq)]
10pub struct TcpSegment<'a> {
11 bytes: &'a [u8],
12}
13
14impl<'a> TcpSegment<'a> {
15 #[inline]
17 pub fn parse(bytes: &'a [u8]) -> Result<Self, ParseError> {
18 validate(bytes)?;
19 Ok(Self { bytes })
20 }
21
22 #[inline]
24 pub fn source_port(&self) -> u16 {
25 u16::from_be_bytes([self.bytes[0], self.bytes[1]])
26 }
27
28 #[inline]
30 pub fn destination_port(&self) -> u16 {
31 u16::from_be_bytes([self.bytes[2], self.bytes[3]])
32 }
33
34 #[inline]
36 pub fn sequence_number(&self) -> u32 {
37 u32::from_be_bytes(self.bytes[4..8].try_into().expect("validated TCP header"))
38 }
39
40 #[inline]
42 pub fn acknowledgment_number(&self) -> u32 {
43 u32::from_be_bytes(self.bytes[8..12].try_into().expect("validated TCP header"))
44 }
45
46 #[inline]
48 pub fn data_offset(&self) -> u8 {
49 self.bytes[12] >> 4
50 }
51
52 #[inline]
54 pub fn header_length(&self) -> usize {
55 usize::from(self.data_offset()) * 4
56 }
57
58 #[inline]
60 pub fn reserved(&self) -> u8 {
61 self.bytes[12] & 0x0f
62 }
63
64 #[inline]
66 pub fn flags(&self) -> TcpFlags {
67 TcpFlags::new(self.bytes[13])
68 }
69
70 #[inline]
72 pub fn window_size(&self) -> u16 {
73 u16::from_be_bytes([self.bytes[14], self.bytes[15]])
74 }
75
76 #[inline]
78 pub fn checksum(&self) -> u16 {
79 u16::from_be_bytes([self.bytes[16], self.bytes[17]])
80 }
81
82 #[inline]
84 pub fn urgent_pointer(&self) -> u16 {
85 u16::from_be_bytes([self.bytes[18], self.bytes[19]])
86 }
87
88 #[inline]
90 pub fn options(&self) -> &'a [u8] {
91 &self.bytes[HEADER_LENGTH..self.header_length()]
92 }
93
94 #[inline]
96 pub fn payload(&self) -> &'a [u8] {
97 &self.bytes[self.header_length()..]
98 }
99
100 #[inline]
102 pub fn as_bytes(&self) -> &'a [u8] {
103 self.bytes
104 }
105}
106
107#[derive(Debug, Eq, PartialEq)]
109pub struct TcpSegmentMut<'a> {
110 bytes: &'a mut [u8],
111}
112
113impl<'a> TcpSegmentMut<'a> {
114 #[inline]
116 pub fn parse(bytes: &'a mut [u8]) -> Result<Self, ParseError> {
117 validate(bytes)?;
118 Ok(Self { bytes })
119 }
120
121 pub(crate) fn from_validated(bytes: &'a mut [u8]) -> Self {
122 Self { bytes }
123 }
124
125 #[inline]
127 pub fn source_port(&self) -> u16 {
128 u16::from_be_bytes([self.bytes[0], self.bytes[1]])
129 }
130
131 #[inline]
133 pub fn destination_port(&self) -> u16 {
134 u16::from_be_bytes([self.bytes[2], self.bytes[3]])
135 }
136
137 #[inline]
139 pub fn sequence_number(&self) -> u32 {
140 u32::from_be_bytes(self.bytes[4..8].try_into().expect("validated TCP header"))
141 }
142
143 #[inline]
145 pub fn acknowledgment_number(&self) -> u32 {
146 u32::from_be_bytes(self.bytes[8..12].try_into().expect("validated TCP header"))
147 }
148
149 #[inline]
151 pub fn data_offset(&self) -> u8 {
152 self.bytes[12] >> 4
153 }
154
155 #[inline]
157 pub fn header_length(&self) -> usize {
158 usize::from(self.data_offset()) * 4
159 }
160
161 #[inline]
163 pub fn reserved(&self) -> u8 {
164 self.bytes[12] & 0x0f
165 }
166
167 #[inline]
169 pub fn flags(&self) -> TcpFlags {
170 TcpFlags::new(self.bytes[13])
171 }
172
173 #[inline]
175 pub fn window_size(&self) -> u16 {
176 u16::from_be_bytes([self.bytes[14], self.bytes[15]])
177 }
178
179 #[inline]
181 pub fn checksum(&self) -> u16 {
182 u16::from_be_bytes([self.bytes[16], self.bytes[17]])
183 }
184
185 #[inline]
187 pub fn urgent_pointer(&self) -> u16 {
188 u16::from_be_bytes([self.bytes[18], self.bytes[19]])
189 }
190
191 #[inline]
193 pub fn options(&self) -> &[u8] {
194 &self.bytes[HEADER_LENGTH..self.header_length()]
195 }
196
197 #[inline]
199 pub fn options_mut(&mut self) -> &mut [u8] {
200 let header_length = self.header_length();
201 &mut self.bytes[HEADER_LENGTH..header_length]
202 }
203
204 #[inline]
206 pub fn payload(&self) -> &[u8] {
207 &self.bytes[self.header_length()..]
208 }
209
210 #[inline]
212 pub fn payload_mut(&mut self) -> &mut [u8] {
213 let header_length = self.header_length();
214 &mut self.bytes[header_length..]
215 }
216
217 #[inline]
219 pub fn as_bytes(&self) -> &[u8] {
220 self.bytes
221 }
222
223 #[inline]
225 pub fn as_bytes_mut(&mut self) -> &mut [u8] {
226 self.bytes
227 }
228
229 #[inline]
231 pub fn set_source_port(&mut self, value: u16) {
232 self.bytes[0..2].copy_from_slice(&value.to_be_bytes());
233 }
234
235 #[inline]
237 pub fn set_destination_port(&mut self, value: u16) {
238 self.bytes[2..4].copy_from_slice(&value.to_be_bytes());
239 }
240
241 #[inline]
243 pub fn set_sequence_number(&mut self, value: u32) {
244 self.bytes[4..8].copy_from_slice(&value.to_be_bytes());
245 }
246
247 #[inline]
249 pub fn set_acknowledgment_number(&mut self, value: u32) {
250 self.bytes[8..12].copy_from_slice(&value.to_be_bytes());
251 }
252
253 #[inline]
255 pub fn set_flags(&mut self, value: TcpFlags) {
256 self.bytes[13] = value.raw();
257 }
258
259 #[inline]
261 pub fn set_window_size(&mut self, value: u16) {
262 self.bytes[14..16].copy_from_slice(&value.to_be_bytes());
263 }
264
265 #[inline]
267 pub fn set_checksum(&mut self, value: u16) {
268 self.bytes[16..18].copy_from_slice(&value.to_be_bytes());
269 }
270
271 #[inline]
273 pub fn set_urgent_pointer(&mut self, value: u16) {
274 self.bytes[18..20].copy_from_slice(&value.to_be_bytes());
275 }
276}
277
278fn validate(bytes: &[u8]) -> Result<(), ParseError> {
279 if bytes.len() < HEADER_LENGTH {
280 return Err(ParseError::Truncated {
281 minimum: HEADER_LENGTH,
282 available: bytes.len(),
283 });
284 }
285 let header_length = usize::from(bytes[12] >> 4) * 4;
286 if header_length < HEADER_LENGTH {
287 return Err(ParseError::InvalidHeaderLength {
288 minimum: HEADER_LENGTH,
289 actual: header_length,
290 });
291 }
292 if bytes.len() < header_length {
293 return Err(ParseError::Truncated {
294 minimum: header_length,
295 available: bytes.len(),
296 });
297 }
298 Ok(())
299}