1use crate::Packet;
12use crate::PrimitiveValues;
13use crate::ip::IpNextHeaderProtocols;
14
15use alloc::{vec, vec::Vec};
16
17use pnet_macros::packet;
18use pnet_macros_support::types::*;
19
20use pnet_base::core_net::Ipv4Addr;
21use pnet_base::core_net::Ipv6Addr;
22use crate::util::{self, Octets};
23
24#[allow(non_snake_case)]
26#[allow(non_upper_case_globals)]
27pub mod TcpFlags {
28 pub const CWR: u8 = 0b10000000;
32 pub const ECE: u8 = 0b01000000;
39 pub const URG: u8 = 0b00100000;
41 pub const ACK: u8 = 0b00010000;
44 pub const PSH: u8 = 0b00001000;
46 pub const RST: u8 = 0b00000100;
48 pub const SYN: u8 = 0b00000010;
51 pub const FIN: u8 = 0b00000001;
53}
54
55#[packet]
57pub struct Tcp {
58 pub source: u16be,
59 pub destination: u16be,
60 pub sequence: u32be,
61 pub acknowledgement: u32be,
62 pub data_offset: u4,
63 pub reserved: u4,
64 pub flags: u8,
65 pub window: u16be,
66 pub checksum: u16be,
67 pub urgent_ptr: u16be,
68 #[length_fn = "tcp_options_length"]
69 pub options: Vec<TcpOption>,
70 #[payload]
71 pub payload: Vec<u8>,
72}
73
74#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
76pub struct TcpOptionNumber(pub u8);
77
78#[allow(non_snake_case)]
80#[allow(non_upper_case_globals)]
81pub mod TcpOptionNumbers {
82 use super::TcpOptionNumber;
83
84 pub const EOL: TcpOptionNumber = TcpOptionNumber(0);
86
87 pub const NOP: TcpOptionNumber = TcpOptionNumber(1);
89
90 pub const MSS: TcpOptionNumber = TcpOptionNumber(2);
92
93 pub const WSCALE: TcpOptionNumber = TcpOptionNumber(3);
95
96 pub const SACK_PERMITTED: TcpOptionNumber = TcpOptionNumber(4);
98
99 pub const SACK: TcpOptionNumber = TcpOptionNumber(5);
101
102 pub const TIMESTAMPS: TcpOptionNumber = TcpOptionNumber(8);
104}
105
106#[packet]
108pub struct TcpOption {
109 #[construct_with(u8)]
110 pub number: TcpOptionNumber,
111 #[length_fn = "tcp_option_length"]
112 pub length: Vec<u8>,
114 #[length_fn = "tcp_option_payload_length"]
115 #[payload]
116 pub data: Vec<u8>,
117}
118
119impl TcpOption {
120 pub fn nop() -> Self {
122 TcpOption {
123 number: TcpOptionNumbers::NOP,
124 length: vec![],
125 data: vec![],
126 }
127 }
128
129 pub fn timestamp(my: u32, their: u32) -> Self {
133 let mut data = vec![];
134 data.extend_from_slice(&my.octets()[..]);
135 data.extend_from_slice(&their.octets()[..]);
136
137 TcpOption {
138 number: TcpOptionNumbers::TIMESTAMPS,
139 length: vec![10],
140 data: data,
141 }
142 }
143
144 pub fn mss(val: u16) -> Self {
147 let mut data = vec![];
148 data.extend_from_slice(&val.octets()[..]);
149
150 TcpOption {
151 number: TcpOptionNumbers::MSS,
152 length: vec![4],
153 data: data,
154 }
155 }
156
157 pub fn wscale(val: u8) -> Self {
160 TcpOption {
161 number: TcpOptionNumbers::WSCALE,
162 length: vec![3],
163 data: vec![val],
164 }
165 }
166
167 pub fn sack_perm() -> Self {
171 TcpOption {
172 number: TcpOptionNumbers::SACK_PERMITTED,
173 length: vec![2],
174 data: vec![],
175 }
176 }
177
178 pub fn selective_ack(acks: &[u32]) -> Self {
183 let mut data = vec![];
184 for ack in acks {
185 data.extend_from_slice(&ack.octets()[..]);
186 }
187 TcpOption {
188 number: TcpOptionNumbers::SACK,
189 length: vec![1 + 1 + data.len() as u8],
190 data: data,
191 }
192 }
193}
194
195#[inline]
199fn tcp_option_length(option: &TcpOptionPacket) -> usize {
200 match option.get_number() {
201 TcpOptionNumbers::EOL => 0,
202 TcpOptionNumbers::NOP => 0,
203 _ => 1,
204 }
205}
206
207fn tcp_option_payload_length(ipv4_option: &TcpOptionPacket) -> usize {
208 match ipv4_option.get_length_raw().first() {
209 Some(len) if *len >= 2 => *len as usize - 2,
210 _ => 0,
211 }
212}
213
214impl TcpOptionNumber {
215 pub fn new(value: u8) -> TcpOptionNumber {
217 TcpOptionNumber(value)
218 }
219}
220
221impl PrimitiveValues for TcpOptionNumber {
222 type T = (u8,);
223 fn to_primitive_values(&self) -> (u8,) {
224 (self.0,)
225 }
226}
227
228#[inline]
229fn tcp_options_length(tcp: &TcpPacket) -> usize {
230 let data_offset = tcp.get_data_offset();
231
232 if data_offset > 5 {
233 data_offset as usize * 4 - 20
234 } else {
235 0
236 }
237}
238
239pub fn ipv4_checksum(packet: &TcpPacket, source: &Ipv4Addr, destination: &Ipv4Addr) -> u16 {
241 ipv4_checksum_adv(packet, &[], source, destination)
242}
243
244pub fn ipv4_checksum_adv(packet: &TcpPacket,
252 extra_data: &[u8],
253 source: &Ipv4Addr,
254 destination: &Ipv4Addr)
255 -> u16 {
256 util::ipv4_checksum(packet.packet(),
257 8,
258 extra_data,
259 source,
260 destination,
261 IpNextHeaderProtocols::Tcp)
262}
263
264pub fn ipv6_checksum(packet: &TcpPacket, source: &Ipv6Addr, destination: &Ipv6Addr) -> u16 {
266 ipv6_checksum_adv(packet, &[], source, destination)
267}
268
269pub fn ipv6_checksum_adv(packet: &TcpPacket,
277 extra_data: &[u8],
278 source: &Ipv6Addr,
279 destination: &Ipv6Addr)
280 -> u16 {
281 util::ipv6_checksum(packet.packet(),
282 8,
283 extra_data,
284 source,
285 destination,
286 IpNextHeaderProtocols::Tcp)
287}
288
289#[test]
290fn tcp_header_ipv4_test() {
291 use crate::ip::IpNextHeaderProtocols;
292 use crate::ipv4::MutableIpv4Packet;
293
294 const IPV4_HEADER_LEN: usize = 20;
295 const TCP_HEADER_LEN: usize = 32;
296 const TEST_DATA_LEN: usize = 4;
297
298 let mut packet = [0u8; IPV4_HEADER_LEN + TCP_HEADER_LEN + TEST_DATA_LEN];
299 let ipv4_source = Ipv4Addr::new(192, 168, 2, 1);
300 let ipv4_destination = Ipv4Addr::new(192, 168, 111, 51);
301 {
302 let mut ip_header = MutableIpv4Packet::new(&mut packet[..]).unwrap();
303 ip_header.set_next_level_protocol(IpNextHeaderProtocols::Tcp);
304 ip_header.set_source(ipv4_source);
305 ip_header.set_destination(ipv4_destination);
306 }
307
308 packet[IPV4_HEADER_LEN + TCP_HEADER_LEN] = 't' as u8;
310 packet[IPV4_HEADER_LEN + TCP_HEADER_LEN + 1] = 'e' as u8;
311 packet[IPV4_HEADER_LEN + TCP_HEADER_LEN + 2] = 's' as u8;
312 packet[IPV4_HEADER_LEN + TCP_HEADER_LEN + 3] = 't' as u8;
313
314 {
315 let mut tcp_header = MutableTcpPacket::new(&mut packet[IPV4_HEADER_LEN..]).unwrap();
316 tcp_header.set_source(49511);
317 assert_eq!(tcp_header.get_source(), 49511);
318
319 tcp_header.set_destination(9000);
320 assert_eq!(tcp_header.get_destination(), 9000);
321
322 tcp_header.set_sequence(0x9037d2b8);
323 assert_eq!(tcp_header.get_sequence(), 0x9037d2b8);
324
325 tcp_header.set_acknowledgement(0x944bb276);
326 assert_eq!(tcp_header.get_acknowledgement(), 0x944bb276);
327
328 tcp_header.set_flags(TcpFlags::PSH | TcpFlags::ACK);
329 assert_eq!(tcp_header.get_flags(), TcpFlags::PSH | TcpFlags::ACK);
330
331 tcp_header.set_window(4015);
332 assert_eq!(tcp_header.get_window(), 4015);
333
334 tcp_header.set_data_offset(8);
335 assert_eq!(tcp_header.get_data_offset(), 8);
336
337 let ts = TcpOption::timestamp(743951781, 44056978);
338 tcp_header.set_options(&vec![TcpOption::nop(), TcpOption::nop(), ts]);
339
340 let checksum = ipv4_checksum(&tcp_header.to_immutable(), &ipv4_source, &ipv4_destination);
341 tcp_header.set_checksum(checksum);
342 assert_eq!(tcp_header.get_checksum(), 0xc031);
343 }
344 let ref_packet = [0xc1, 0x67, 0x23, 0x28, 0x90, 0x37, 0xd2, 0xb8, 0x94, 0x4b, 0xb2, 0x76, 0x80, 0x18, 0x0f, 0xaf, 0xc0, 0x31, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0x2c, 0x57,
353 0xcd, 0xa5, 0x02, 0xa0,
354 0x41, 0x92, 0x74, 0x65, 0x73, 0x74 ];
357 assert_eq!(&ref_packet[..], &packet[20..]);
358}
359
360#[test]
361fn tcp_test_options_invalid_offset() {
362 let mut buf = [0; 20]; {
364 if let Some(mut tcp) = MutableTcpPacket::new(&mut buf[..]) {
365 tcp.set_data_offset(10); }
367 }
368
369 if let Some(tcp) = TcpPacket::new(&buf[..]) {
370 let _options = tcp.get_options_iter(); }
372}
373
374#[test]
375fn tcp_test_options_vec_invalid_offset() {
376 let mut buf = [0; 20]; {
378 if let Some(mut tcp) = MutableTcpPacket::new(&mut buf[..]) {
379 tcp.set_data_offset(10); }
381 }
382
383 if let Some(tcp) = TcpPacket::new(&buf[..]) {
384 let _options = tcp.get_options(); }
386}
387
388#[test]
389fn tcp_test_options_slice_invalid_offset() {
390 let mut buf = [0; 20]; {
392 if let Some(mut tcp) = MutableTcpPacket::new(&mut buf[..]) {
393 tcp.set_data_offset(10); }
395 }
396
397 if let Some(tcp) = TcpPacket::new(&buf[..]) {
398 let _options = tcp.get_options_raw(); }
400}
401
402#[test]
403fn tcp_test_option_invalid_len() {
404 use std::println;
405 let mut buf = [0; 24];
406 {
407 if let Some(mut tcp) = MutableTcpPacket::new(&mut buf[..]) {
408 tcp.set_data_offset(6);
409 }
410 buf[20] = 2; buf[21] = 8; }
413
414 if let Some(tcp) = TcpPacket::new(&buf[..]) {
415 let options = tcp.get_options_iter();
416 for opt in options {
417 println!("{:?}", opt);
418 }
419 }
420}
421
422#[test]
423fn tcp_test_payload_slice_invalid_offset() {
424 let mut buf = [0; 20];
425 {
426 if let Some(mut tcp) = MutableTcpPacket::new(&mut buf[..]) {
427 tcp.set_data_offset(10); }
429 }
430
431 if let Some(tcp) = TcpPacket::new(&buf[..]) {
432 assert_eq!(tcp.payload().len(), 0);
433 }
434}