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