iris_core/protocols/packet/
tcp.rs1use crate::memory::mbuf::Mbuf;
4use crate::protocols::packet::{Packet, PacketHeader, PacketParseError};
5use crate::utils::types::*;
6
7pub const TCP_PROTOCOL: usize = 6;
9
10pub const CWR: u8 = 0b1000_0000;
12pub const ECE: u8 = 0b0100_0000;
13pub const URG: u8 = 0b0010_0000;
14pub const ACK: u8 = 0b0001_0000;
15pub const PSH: u8 = 0b0000_1000;
16pub const RST: u8 = 0b0000_0100;
17pub const SYN: u8 = 0b0000_0010;
18pub const FIN: u8 = 0b0000_0001;
19
20#[derive(Debug)]
24pub struct Tcp<'a> {
25 header: TcpHeader,
27 offset: usize,
29 mbuf: &'a Mbuf,
31}
32
33impl Tcp<'_> {
34 #[inline]
36 pub fn src_port(&self) -> u16 {
37 self.header.src_port.into()
38 }
39
40 #[inline]
42 pub fn dst_port(&self) -> u16 {
43 self.header.dst_port.into()
44 }
45
46 #[inline]
48 pub fn seq_no(&self) -> u32 {
49 self.header.seq_no.into()
50 }
51
52 #[inline]
54 pub fn ack_no(&self) -> u32 {
55 self.header.ack_no.into()
56 }
57
58 #[inline]
60 pub fn data_offset(&self) -> u8 {
61 (self.header.data_offset_to_ns & 0xf0) >> 4
62 }
63
64 #[inline]
66 pub fn reserved(&self) -> u8 {
67 self.header.data_offset_to_ns & 0x0f
68 }
69
70 #[inline]
72 pub fn data_offset_to_ns(&self) -> u8 {
73 self.header.data_offset_to_ns
74 }
75
76 #[inline]
78 pub fn flags(&self) -> u8 {
79 self.header.flags
80 }
81
82 #[inline]
84 pub fn window(&self) -> u16 {
85 self.header.window.into()
86 }
87
88 #[inline]
90 pub fn checksum(&self) -> u16 {
91 self.header.checksum.into()
92 }
93
94 #[inline]
96 pub fn urgent_pointer(&self) -> u16 {
97 self.header.urgent_pointer.into()
98 }
99
100 #[inline]
104 pub fn ns(&self) -> u8 {
105 ((self.header.data_offset_to_ns & 0x01) != 0) as u8
106 }
107
108 #[inline]
110 pub fn cwr(&self) -> u8 {
111 ((self.flags() & CWR) != 0) as u8
112 }
113
114 #[inline]
116 pub fn ece(&self) -> u8 {
117 ((self.flags() & ECE) != 0) as u8
118 }
119
120 #[inline]
122 pub fn urg(&self) -> u8 {
123 ((self.flags() & URG) != 0) as u8
124 }
125
126 #[inline]
128 pub fn ack(&self) -> u8 {
129 ((self.flags() & ACK) != 0) as u8
130 }
131
132 #[inline]
134 pub fn psh(&self) -> u8 {
135 ((self.flags() & PSH) != 0) as u8
136 }
137
138 #[inline]
140 pub fn rst(&self) -> u8 {
141 ((self.flags() & RST) != 0) as u8
142 }
143
144 #[inline]
146 pub fn syn(&self) -> u8 {
147 ((self.flags() & SYN) != 0) as u8
148 }
149
150 #[inline]
152 pub fn fin(&self) -> u8 {
153 ((self.flags() & FIN) != 0) as u8
154 }
155
156 #[inline]
158 pub fn synack(&self) -> u8 {
159 ((self.flags() & (ACK | SYN)) != 0) as u8
160 }
161}
162
163impl<'a> Packet<'a> for Tcp<'a> {
164 fn mbuf(&self) -> &Mbuf {
165 self.mbuf
166 }
167
168 fn header_len(&self) -> usize {
169 self.header.length()
170 }
171
172 fn next_header_offset(&self) -> usize {
173 self.offset + self.header_len()
174 }
175
176 fn next_header(&self) -> Option<usize> {
177 None
178 }
179
180 fn parse_from(outer: &'a impl Packet<'a>) -> Result<Self, PacketParseError>
181 where
182 Self: Sized,
183 {
184 let offset = outer.next_header_offset();
185 if let Ok(header) = outer.mbuf().get_data(offset) {
186 match outer.next_header() {
187 Some(TCP_PROTOCOL) => Ok(Tcp {
188 header: unsafe { *header },
189 offset,
190 mbuf: outer.mbuf(),
191 }),
192 _ => Err(PacketParseError::InvalidProtocol),
193 }
194 } else {
195 Err(PacketParseError::InvalidRead)
196 }
197 }
198}
199
200#[derive(Debug, Clone, Copy)]
202#[repr(C, packed)]
203struct TcpHeader {
204 src_port: u16be,
205 dst_port: u16be,
206 seq_no: u32be,
207 ack_no: u32be,
208 data_offset_to_ns: u8,
209 flags: u8,
210 window: u16be,
211 checksum: u16be,
212 urgent_pointer: u16be,
213}
214
215impl PacketHeader for TcpHeader {
216 fn length(&self) -> usize {
221 ((self.data_offset_to_ns & 0xf0) >> 2).into()
222 }
223}