1use byteorder::{ByteOrder, NetworkEndian};
2use core::{cmp, fmt, ops};
3
4use super::{Error, Result};
5use crate::phy::ChecksumCapabilities;
6use crate::wire::ip::checksum;
7use crate::wire::{IpAddress, IpProtocol};
8
9#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
14pub struct SeqNumber(pub i32);
15
16impl SeqNumber {
17 pub fn max(self, rhs: Self) -> Self {
18 if self > rhs {
19 self
20 } else {
21 rhs
22 }
23 }
24
25 pub fn min(self, rhs: Self) -> Self {
26 if self < rhs {
27 self
28 } else {
29 rhs
30 }
31 }
32}
33
34impl fmt::Display for SeqNumber {
35 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
36 write!(f, "{}", self.0 as u32)
37 }
38}
39
40#[cfg(feature = "defmt")]
41impl defmt::Format for SeqNumber {
42 fn format(&self, fmt: defmt::Formatter) {
43 defmt::write!(fmt, "{}", self.0 as u32);
44 }
45}
46
47impl ops::Add<usize> for SeqNumber {
48 type Output = SeqNumber;
49
50 fn add(self, rhs: usize) -> SeqNumber {
51 if rhs > i32::MAX as usize {
52 panic!("attempt to add to sequence number with unsigned overflow")
53 }
54 SeqNumber(self.0.wrapping_add(rhs as i32))
55 }
56}
57
58impl ops::Sub<usize> for SeqNumber {
59 type Output = SeqNumber;
60
61 fn sub(self, rhs: usize) -> SeqNumber {
62 if rhs > i32::MAX as usize {
63 panic!("attempt to subtract to sequence number with unsigned overflow")
64 }
65 SeqNumber(self.0.wrapping_sub(rhs as i32))
66 }
67}
68
69impl ops::AddAssign<usize> for SeqNumber {
70 fn add_assign(&mut self, rhs: usize) {
71 *self = *self + rhs;
72 }
73}
74
75impl ops::Sub for SeqNumber {
76 type Output = usize;
77
78 fn sub(self, rhs: SeqNumber) -> usize {
79 let result = self.0.wrapping_sub(rhs.0);
80 if result < 0 {
81 panic!("attempt to subtract sequence numbers with underflow")
82 }
83 result as usize
84 }
85}
86
87impl cmp::PartialOrd for SeqNumber {
88 fn partial_cmp(&self, other: &SeqNumber) -> Option<cmp::Ordering> {
89 self.0.wrapping_sub(other.0).partial_cmp(&0)
90 }
91}
92
93#[derive(Debug, PartialEq, Eq, Clone)]
95#[cfg_attr(feature = "defmt", derive(defmt::Format))]
96pub struct Packet<T: AsRef<[u8]>> {
97 buffer: T,
98}
99
100mod field {
101 #![allow(non_snake_case)]
102
103 use crate::wire::field::*;
104
105 pub const SRC_PORT: Field = 0..2;
106 pub const DST_PORT: Field = 2..4;
107 pub const SEQ_NUM: Field = 4..8;
108 pub const ACK_NUM: Field = 8..12;
109 pub const FLAGS: Field = 12..14;
110 pub const WIN_SIZE: Field = 14..16;
111 pub const CHECKSUM: Field = 16..18;
112 pub const URGENT: Field = 18..20;
113
114 pub const fn OPTIONS(length: u8) -> Field {
115 URGENT.end..(length as usize)
116 }
117
118 pub const FLG_FIN: u16 = 0x001;
119 pub const FLG_SYN: u16 = 0x002;
120 pub const FLG_RST: u16 = 0x004;
121 pub const FLG_PSH: u16 = 0x008;
122 pub const FLG_ACK: u16 = 0x010;
123 pub const FLG_URG: u16 = 0x020;
124 pub const FLG_ECE: u16 = 0x040;
125 pub const FLG_CWR: u16 = 0x080;
126 pub const FLG_NS: u16 = 0x100;
127
128 pub const OPT_END: u8 = 0x00;
129 pub const OPT_NOP: u8 = 0x01;
130 pub const OPT_MSS: u8 = 0x02;
131 pub const OPT_WS: u8 = 0x03;
132 pub const OPT_SACKPERM: u8 = 0x04;
133 pub const OPT_SACKRNG: u8 = 0x05;
134 pub const OPT_TSTAMP: u8 = 0x08;
135}
136
137pub const HEADER_LEN: usize = field::URGENT.end;
138
139impl<T: AsRef<[u8]>> Packet<T> {
140 pub const fn new_unchecked(buffer: T) -> Packet<T> {
142 Packet { buffer }
143 }
144
145 pub fn new_checked(buffer: T) -> Result<Packet<T>> {
150 let packet = Self::new_unchecked(buffer);
151 packet.check_len()?;
152 Ok(packet)
153 }
154
155 pub fn check_len(&self) -> Result<()> {
164 let len = self.buffer.as_ref().len();
165 if len < field::URGENT.end {
166 Err(Error)
167 } else {
168 let header_len = self.header_len() as usize;
169 if len < header_len || header_len < field::URGENT.end {
170 Err(Error)
171 } else {
172 Ok(())
173 }
174 }
175 }
176
177 pub fn into_inner(self) -> T {
179 self.buffer
180 }
181
182 #[inline]
184 pub fn src_port(&self) -> u16 {
185 let data = self.buffer.as_ref();
186 NetworkEndian::read_u16(&data[field::SRC_PORT])
187 }
188
189 #[inline]
191 pub fn dst_port(&self) -> u16 {
192 let data = self.buffer.as_ref();
193 NetworkEndian::read_u16(&data[field::DST_PORT])
194 }
195
196 #[inline]
198 pub fn seq_number(&self) -> SeqNumber {
199 let data = self.buffer.as_ref();
200 SeqNumber(NetworkEndian::read_i32(&data[field::SEQ_NUM]))
201 }
202
203 #[inline]
205 pub fn ack_number(&self) -> SeqNumber {
206 let data = self.buffer.as_ref();
207 SeqNumber(NetworkEndian::read_i32(&data[field::ACK_NUM]))
208 }
209
210 #[inline]
212 pub fn fin(&self) -> bool {
213 let data = self.buffer.as_ref();
214 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
215 raw & field::FLG_FIN != 0
216 }
217
218 #[inline]
220 pub fn syn(&self) -> bool {
221 let data = self.buffer.as_ref();
222 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
223 raw & field::FLG_SYN != 0
224 }
225
226 #[inline]
228 pub fn rst(&self) -> bool {
229 let data = self.buffer.as_ref();
230 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
231 raw & field::FLG_RST != 0
232 }
233
234 #[inline]
236 pub fn psh(&self) -> bool {
237 let data = self.buffer.as_ref();
238 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
239 raw & field::FLG_PSH != 0
240 }
241
242 #[inline]
244 pub fn ack(&self) -> bool {
245 let data = self.buffer.as_ref();
246 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
247 raw & field::FLG_ACK != 0
248 }
249
250 #[inline]
252 pub fn urg(&self) -> bool {
253 let data = self.buffer.as_ref();
254 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
255 raw & field::FLG_URG != 0
256 }
257
258 #[inline]
260 pub fn ece(&self) -> bool {
261 let data = self.buffer.as_ref();
262 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
263 raw & field::FLG_ECE != 0
264 }
265
266 #[inline]
268 pub fn cwr(&self) -> bool {
269 let data = self.buffer.as_ref();
270 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
271 raw & field::FLG_CWR != 0
272 }
273
274 #[inline]
276 pub fn ns(&self) -> bool {
277 let data = self.buffer.as_ref();
278 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
279 raw & field::FLG_NS != 0
280 }
281
282 #[inline]
284 pub fn header_len(&self) -> u8 {
285 let data = self.buffer.as_ref();
286 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
287 ((raw >> 12) * 4) as u8
288 }
289
290 #[inline]
292 pub fn window_len(&self) -> u16 {
293 let data = self.buffer.as_ref();
294 NetworkEndian::read_u16(&data[field::WIN_SIZE])
295 }
296
297 #[inline]
299 pub fn checksum(&self) -> u16 {
300 let data = self.buffer.as_ref();
301 NetworkEndian::read_u16(&data[field::CHECKSUM])
302 }
303
304 #[inline]
306 pub fn urgent_at(&self) -> u16 {
307 let data = self.buffer.as_ref();
308 NetworkEndian::read_u16(&data[field::URGENT])
309 }
310
311 pub fn segment_len(&self) -> usize {
313 let data = self.buffer.as_ref();
314 let mut length = data.len() - self.header_len() as usize;
315 if self.syn() {
316 length += 1
317 }
318 if self.fin() {
319 length += 1
320 }
321 length
322 }
323
324 pub fn selective_ack_permitted(&self) -> Result<bool> {
326 let data = self.buffer.as_ref();
327 let mut options = &data[field::OPTIONS(self.header_len())];
328 while !options.is_empty() {
329 let (next_options, option) = TcpOption::parse(options)?;
330 if option == TcpOption::SackPermitted {
331 return Ok(true);
332 }
333 options = next_options;
334 }
335 Ok(false)
336 }
337
338 pub fn selective_ack_ranges(&self) -> Result<[Option<(u32, u32)>; 3]> {
342 let data = self.buffer.as_ref();
343 let mut options = &data[field::OPTIONS(self.header_len())];
344 while !options.is_empty() {
345 let (next_options, option) = TcpOption::parse(options)?;
346 if let TcpOption::SackRange(slice) = option {
347 return Ok(slice);
348 }
349 options = next_options;
350 }
351 Ok([None, None, None])
352 }
353
354 pub fn verify_checksum(&self, src_addr: &IpAddress, dst_addr: &IpAddress) -> bool {
363 if cfg!(fuzzing) {
364 return true;
365 }
366
367 let data = self.buffer.as_ref();
368 checksum::combine(&[
369 checksum::pseudo_header(src_addr, dst_addr, IpProtocol::Tcp, data.len() as u32),
370 checksum::data(data),
371 ]) == !0
372 }
373}
374
375impl<'a, T: AsRef<[u8]> + ?Sized> Packet<&'a T> {
376 #[inline]
378 pub fn options(&self) -> &'a [u8] {
379 let header_len = self.header_len();
380 let data = self.buffer.as_ref();
381 &data[field::OPTIONS(header_len)]
382 }
383
384 #[inline]
386 pub fn payload(&self) -> &'a [u8] {
387 let header_len = self.header_len() as usize;
388 let data = self.buffer.as_ref();
389 &data[header_len..]
390 }
391}
392
393impl<T: AsRef<[u8]> + AsMut<[u8]>> Packet<T> {
394 #[inline]
396 pub fn set_src_port(&mut self, value: u16) {
397 let data = self.buffer.as_mut();
398 NetworkEndian::write_u16(&mut data[field::SRC_PORT], value)
399 }
400
401 #[inline]
403 pub fn set_dst_port(&mut self, value: u16) {
404 let data = self.buffer.as_mut();
405 NetworkEndian::write_u16(&mut data[field::DST_PORT], value)
406 }
407
408 #[inline]
410 pub fn set_seq_number(&mut self, value: SeqNumber) {
411 let data = self.buffer.as_mut();
412 NetworkEndian::write_i32(&mut data[field::SEQ_NUM], value.0)
413 }
414
415 #[inline]
417 pub fn set_ack_number(&mut self, value: SeqNumber) {
418 let data = self.buffer.as_mut();
419 NetworkEndian::write_i32(&mut data[field::ACK_NUM], value.0)
420 }
421
422 #[inline]
424 pub fn clear_flags(&mut self) {
425 let data = self.buffer.as_mut();
426 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
427 let raw = raw & !0x0fff;
428 NetworkEndian::write_u16(&mut data[field::FLAGS], raw)
429 }
430
431 #[inline]
433 pub fn set_fin(&mut self, value: bool) {
434 let data = self.buffer.as_mut();
435 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
436 let raw = if value {
437 raw | field::FLG_FIN
438 } else {
439 raw & !field::FLG_FIN
440 };
441 NetworkEndian::write_u16(&mut data[field::FLAGS], raw)
442 }
443
444 #[inline]
446 pub fn set_syn(&mut self, value: bool) {
447 let data = self.buffer.as_mut();
448 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
449 let raw = if value {
450 raw | field::FLG_SYN
451 } else {
452 raw & !field::FLG_SYN
453 };
454 NetworkEndian::write_u16(&mut data[field::FLAGS], raw)
455 }
456
457 #[inline]
459 pub fn set_rst(&mut self, value: bool) {
460 let data = self.buffer.as_mut();
461 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
462 let raw = if value {
463 raw | field::FLG_RST
464 } else {
465 raw & !field::FLG_RST
466 };
467 NetworkEndian::write_u16(&mut data[field::FLAGS], raw)
468 }
469
470 #[inline]
472 pub fn set_psh(&mut self, value: bool) {
473 let data = self.buffer.as_mut();
474 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
475 let raw = if value {
476 raw | field::FLG_PSH
477 } else {
478 raw & !field::FLG_PSH
479 };
480 NetworkEndian::write_u16(&mut data[field::FLAGS], raw)
481 }
482
483 #[inline]
485 pub fn set_ack(&mut self, value: bool) {
486 let data = self.buffer.as_mut();
487 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
488 let raw = if value {
489 raw | field::FLG_ACK
490 } else {
491 raw & !field::FLG_ACK
492 };
493 NetworkEndian::write_u16(&mut data[field::FLAGS], raw)
494 }
495
496 #[inline]
498 pub fn set_urg(&mut self, value: bool) {
499 let data = self.buffer.as_mut();
500 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
501 let raw = if value {
502 raw | field::FLG_URG
503 } else {
504 raw & !field::FLG_URG
505 };
506 NetworkEndian::write_u16(&mut data[field::FLAGS], raw)
507 }
508
509 #[inline]
511 pub fn set_ece(&mut self, value: bool) {
512 let data = self.buffer.as_mut();
513 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
514 let raw = if value {
515 raw | field::FLG_ECE
516 } else {
517 raw & !field::FLG_ECE
518 };
519 NetworkEndian::write_u16(&mut data[field::FLAGS], raw)
520 }
521
522 #[inline]
524 pub fn set_cwr(&mut self, value: bool) {
525 let data = self.buffer.as_mut();
526 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
527 let raw = if value {
528 raw | field::FLG_CWR
529 } else {
530 raw & !field::FLG_CWR
531 };
532 NetworkEndian::write_u16(&mut data[field::FLAGS], raw)
533 }
534
535 #[inline]
537 pub fn set_ns(&mut self, value: bool) {
538 let data = self.buffer.as_mut();
539 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
540 let raw = if value {
541 raw | field::FLG_NS
542 } else {
543 raw & !field::FLG_NS
544 };
545 NetworkEndian::write_u16(&mut data[field::FLAGS], raw)
546 }
547
548 #[inline]
550 pub fn set_header_len(&mut self, value: u8) {
551 let data = self.buffer.as_mut();
552 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
553 let raw = (raw & !0xf000) | ((value as u16) / 4) << 12;
554 NetworkEndian::write_u16(&mut data[field::FLAGS], raw)
555 }
556
557 #[inline]
559 pub fn set_window_len(&mut self, value: u16) {
560 let data = self.buffer.as_mut();
561 NetworkEndian::write_u16(&mut data[field::WIN_SIZE], value)
562 }
563
564 #[inline]
566 pub fn set_checksum(&mut self, value: u16) {
567 let data = self.buffer.as_mut();
568 NetworkEndian::write_u16(&mut data[field::CHECKSUM], value)
569 }
570
571 #[inline]
573 pub fn set_urgent_at(&mut self, value: u16) {
574 let data = self.buffer.as_mut();
575 NetworkEndian::write_u16(&mut data[field::URGENT], value)
576 }
577
578 pub fn fill_checksum(&mut self, src_addr: &IpAddress, dst_addr: &IpAddress) {
584 self.set_checksum(0);
585 let checksum = {
586 let data = self.buffer.as_ref();
587 !checksum::combine(&[
588 checksum::pseudo_header(src_addr, dst_addr, IpProtocol::Tcp, data.len() as u32),
589 checksum::data(data),
590 ])
591 };
592 self.set_checksum(checksum)
593 }
594
595 #[inline]
597 pub fn options_mut(&mut self) -> &mut [u8] {
598 let header_len = self.header_len();
599 let data = self.buffer.as_mut();
600 &mut data[field::OPTIONS(header_len)]
601 }
602
603 #[inline]
605 pub fn payload_mut(&mut self) -> &mut [u8] {
606 let header_len = self.header_len() as usize;
607 let data = self.buffer.as_mut();
608 &mut data[header_len..]
609 }
610}
611
612impl<T: AsRef<[u8]>> AsRef<[u8]> for Packet<T> {
613 fn as_ref(&self) -> &[u8] {
614 self.buffer.as_ref()
615 }
616}
617
618#[derive(Debug, PartialEq, Eq, Clone, Copy)]
620#[cfg_attr(feature = "defmt", derive(defmt::Format))]
621pub enum TcpOption<'a> {
622 EndOfList,
623 NoOperation,
624 MaxSegmentSize(u16),
625 WindowScale(u8),
626 SackPermitted,
627 SackRange([Option<(u32, u32)>; 3]),
628 TimeStamp { tsval: u32, tsecr: u32 },
629 Unknown { kind: u8, data: &'a [u8] },
630}
631
632impl<'a> TcpOption<'a> {
633 pub fn parse(buffer: &'a [u8]) -> Result<(&'a [u8], TcpOption<'a>)> {
634 let (length, option);
635 match *buffer.first().ok_or(Error)? {
636 field::OPT_END => {
637 length = 1;
638 option = TcpOption::EndOfList;
639 }
640 field::OPT_NOP => {
641 length = 1;
642 option = TcpOption::NoOperation;
643 }
644 kind => {
645 length = *buffer.get(1).ok_or(Error)? as usize;
646 let data = buffer.get(2..length).ok_or(Error)?;
647 match (kind, length) {
648 (field::OPT_END, _) | (field::OPT_NOP, _) => unreachable!(),
649 (field::OPT_MSS, 4) => {
650 option = TcpOption::MaxSegmentSize(NetworkEndian::read_u16(data))
651 }
652 (field::OPT_MSS, _) => return Err(Error),
653 (field::OPT_WS, 3) => option = TcpOption::WindowScale(data[0]),
654 (field::OPT_WS, _) => return Err(Error),
655 (field::OPT_SACKPERM, 2) => option = TcpOption::SackPermitted,
656 (field::OPT_SACKPERM, _) => return Err(Error),
657 (field::OPT_SACKRNG, n) => {
658 if n < 10 || (n - 2) % 8 != 0 {
659 return Err(Error);
660 }
661 if n > 26 {
662 net_debug!("sACK with >3 blocks, truncating to 3");
672 }
673 let mut sack_ranges: [Option<(u32, u32)>; 3] = [None; 3];
674
675 sack_ranges.iter_mut().enumerate().for_each(|(i, nmut)| {
679 let left = i * 8;
680 *nmut = if left < data.len() {
681 let mid = left + 4;
682 let right = mid + 4;
683 let range_left = NetworkEndian::read_u32(&data[left..mid]);
684 let range_right = NetworkEndian::read_u32(&data[mid..right]);
685 Some((range_left, range_right))
686 } else {
687 None
688 };
689 });
690 option = TcpOption::SackRange(sack_ranges);
691 }
692 (field::OPT_TSTAMP, 10) => {
693 let tsval = NetworkEndian::read_u32(&data[0..4]);
694 let tsecr = NetworkEndian::read_u32(&data[4..8]);
695 option = TcpOption::TimeStamp { tsval, tsecr };
696 }
697 (_, _) => option = TcpOption::Unknown { kind, data },
698 }
699 }
700 }
701 Ok((&buffer[length..], option))
702 }
703
704 pub fn buffer_len(&self) -> usize {
705 match *self {
706 TcpOption::EndOfList => 1,
707 TcpOption::NoOperation => 1,
708 TcpOption::MaxSegmentSize(_) => 4,
709 TcpOption::WindowScale(_) => 3,
710 TcpOption::SackPermitted => 2,
711 TcpOption::SackRange(s) => s.iter().filter(|s| s.is_some()).count() * 8 + 2,
712 TcpOption::TimeStamp { tsval: _, tsecr: _ } => 10,
713 TcpOption::Unknown { data, .. } => 2 + data.len(),
714 }
715 }
716
717 pub fn emit<'b>(&self, buffer: &'b mut [u8]) -> &'b mut [u8] {
718 let length;
719 match *self {
720 TcpOption::EndOfList => {
721 length = 1;
722 for p in buffer.iter_mut() {
724 *p = field::OPT_END;
725 }
726 }
727 TcpOption::NoOperation => {
728 length = 1;
729 buffer[0] = field::OPT_NOP;
730 }
731 _ => {
732 length = self.buffer_len();
733 buffer[1] = length as u8;
734 match self {
735 &TcpOption::EndOfList | &TcpOption::NoOperation => unreachable!(),
736 &TcpOption::MaxSegmentSize(value) => {
737 buffer[0] = field::OPT_MSS;
738 NetworkEndian::write_u16(&mut buffer[2..], value)
739 }
740 &TcpOption::WindowScale(value) => {
741 buffer[0] = field::OPT_WS;
742 buffer[2] = value;
743 }
744 &TcpOption::SackPermitted => {
745 buffer[0] = field::OPT_SACKPERM;
746 }
747 &TcpOption::SackRange(slice) => {
748 buffer[0] = field::OPT_SACKRNG;
749 slice
750 .iter()
751 .filter(|s| s.is_some())
752 .enumerate()
753 .for_each(|(i, s)| {
754 let (first, second) = *s.as_ref().unwrap();
755 let pos = i * 8 + 2;
756 NetworkEndian::write_u32(&mut buffer[pos..], first);
757 NetworkEndian::write_u32(&mut buffer[pos + 4..], second);
758 });
759 }
760 &TcpOption::TimeStamp { tsval, tsecr } => {
761 buffer[0] = field::OPT_TSTAMP;
762 NetworkEndian::write_u32(&mut buffer[2..], tsval);
763 NetworkEndian::write_u32(&mut buffer[6..], tsecr);
764 }
765 &TcpOption::Unknown {
766 kind,
767 data: provided,
768 } => {
769 buffer[0] = kind;
770 buffer[2..].copy_from_slice(provided)
771 }
772 }
773 }
774 }
775 &mut buffer[length..]
776 }
777}
778
779#[derive(Debug, PartialEq, Eq, Clone, Copy)]
781#[cfg_attr(feature = "defmt", derive(defmt::Format))]
782pub enum Control {
783 None,
784 Psh,
785 Syn,
786 Fin,
787 Rst,
788}
789
790#[allow(clippy::len_without_is_empty)]
791impl Control {
792 pub const fn len(self) -> usize {
794 match self {
795 Control::Syn | Control::Fin => 1,
796 _ => 0,
797 }
798 }
799
800 pub const fn quash_psh(self) -> Control {
802 match self {
803 Control::Psh => Control::None,
804 _ => self,
805 }
806 }
807}
808
809#[derive(Debug, PartialEq, Eq, Clone, Copy)]
811pub struct Repr<'a> {
812 pub src_port: u16,
813 pub dst_port: u16,
814 pub control: Control,
815 pub seq_number: SeqNumber,
816 pub ack_number: Option<SeqNumber>,
817 pub window_len: u16,
818 pub window_scale: Option<u8>,
819 pub max_seg_size: Option<u16>,
820 pub sack_permitted: bool,
821 pub sack_ranges: [Option<(u32, u32)>; 3],
822 pub timestamp: Option<TcpTimestampRepr>,
823 pub payload: &'a [u8],
824}
825
826pub type TcpTimestampGenerator = fn() -> u32;
827
828#[derive(Debug, PartialEq, Eq, Clone, Copy)]
829pub struct TcpTimestampRepr {
830 pub tsval: u32,
831 pub tsecr: u32,
832}
833
834impl TcpTimestampRepr {
835 pub fn new(tsval: u32, tsecr: u32) -> Self {
836 Self { tsval, tsecr }
837 }
838
839 pub fn generate_reply(&self, generator: Option<TcpTimestampGenerator>) -> Option<Self> {
840 Self::generate_reply_with_tsval(generator, self.tsval)
841 }
842
843 pub fn generate_reply_with_tsval(
844 generator: Option<TcpTimestampGenerator>,
845 tsval: u32,
846 ) -> Option<Self> {
847 Some(Self::new(generator?(), tsval))
848 }
849}
850
851impl<'a> Repr<'a> {
852 pub fn parse<T>(
854 packet: &Packet<&'a T>,
855 src_addr: &IpAddress,
856 dst_addr: &IpAddress,
857 checksum_caps: &ChecksumCapabilities,
858 ) -> Result<Repr<'a>>
859 where
860 T: AsRef<[u8]> + ?Sized,
861 {
862 packet.check_len()?;
863
864 if packet.src_port() == 0 {
866 return Err(Error);
867 }
868 if packet.dst_port() == 0 {
869 return Err(Error);
870 }
871 if checksum_caps.tcp.rx() && !packet.verify_checksum(src_addr, dst_addr) {
873 return Err(Error);
874 }
875
876 let control = match (packet.syn(), packet.fin(), packet.rst(), packet.psh()) {
877 (false, false, false, false) => Control::None,
878 (false, false, false, true) => Control::Psh,
879 (true, false, false, _) => Control::Syn,
880 (false, true, false, _) => Control::Fin,
881 (false, false, true, _) => Control::Rst,
882 _ => return Err(Error),
883 };
884 let ack_number = match packet.ack() {
885 true => Some(packet.ack_number()),
886 false => None,
887 };
888 let mut max_seg_size = None;
894 let mut window_scale = None;
895 let mut options = packet.options();
896 let mut sack_permitted = false;
897 let mut sack_ranges = [None, None, None];
898 let mut timestamp = None;
899 while !options.is_empty() {
900 let (next_options, option) = TcpOption::parse(options)?;
901 match option {
902 TcpOption::EndOfList => break,
903 TcpOption::NoOperation => (),
904 TcpOption::MaxSegmentSize(value) => max_seg_size = Some(value),
905 TcpOption::WindowScale(value) => {
906 window_scale = if value > 14 {
911 net_debug!(
912 "{}:{}:{}:{}: parsed window scaling factor >14, setting to 14",
913 src_addr,
914 packet.src_port(),
915 dst_addr,
916 packet.dst_port()
917 );
918 Some(14)
919 } else {
920 Some(value)
921 };
922 }
923 TcpOption::SackPermitted => sack_permitted = true,
924 TcpOption::SackRange(slice) => sack_ranges = slice,
925 TcpOption::TimeStamp { tsval, tsecr } => {
926 timestamp = Some(TcpTimestampRepr::new(tsval, tsecr));
927 }
928 _ => (),
929 }
930 options = next_options;
931 }
932
933 Ok(Repr {
934 src_port: packet.src_port(),
935 dst_port: packet.dst_port(),
936 control: control,
937 seq_number: packet.seq_number(),
938 ack_number: ack_number,
939 window_len: packet.window_len(),
940 window_scale: window_scale,
941 max_seg_size: max_seg_size,
942 sack_permitted: sack_permitted,
943 sack_ranges: sack_ranges,
944 timestamp: timestamp,
945 payload: packet.payload(),
946 })
947 }
948
949 pub fn header_len(&self) -> usize {
954 let mut length = field::URGENT.end;
955 if self.max_seg_size.is_some() {
956 length += 4
957 }
958 if self.window_scale.is_some() {
959 length += 3
960 }
961 if self.sack_permitted {
962 length += 2;
963 }
964 if self.timestamp.is_some() {
965 length += 10;
966 }
967 let sack_range_len: usize = self
968 .sack_ranges
969 .iter()
970 .map(|o| o.map(|_| 8).unwrap_or(0))
971 .sum();
972 if sack_range_len > 0 {
973 length += sack_range_len + 2;
974 }
975 if length % 4 != 0 {
976 length += 4 - length % 4;
977 }
978 length
979 }
980
981 pub fn buffer_len(&self) -> usize {
983 self.header_len() + self.payload.len()
984 }
985
986 pub fn emit<T>(
988 &self,
989 packet: &mut Packet<&mut T>,
990 src_addr: &IpAddress,
991 dst_addr: &IpAddress,
992 checksum_caps: &ChecksumCapabilities,
993 ) where
994 T: AsRef<[u8]> + AsMut<[u8]> + ?Sized,
995 {
996 packet.set_src_port(self.src_port);
997 packet.set_dst_port(self.dst_port);
998 packet.set_seq_number(self.seq_number);
999 packet.set_ack_number(self.ack_number.unwrap_or(SeqNumber(0)));
1000 packet.set_window_len(self.window_len);
1001 packet.set_header_len(self.header_len() as u8);
1002 packet.clear_flags();
1003 match self.control {
1004 Control::None => (),
1005 Control::Psh => packet.set_psh(true),
1006 Control::Syn => packet.set_syn(true),
1007 Control::Fin => packet.set_fin(true),
1008 Control::Rst => packet.set_rst(true),
1009 }
1010 packet.set_ack(self.ack_number.is_some());
1011 {
1012 let mut options = packet.options_mut();
1013 if let Some(value) = self.max_seg_size {
1014 let tmp = options;
1015 options = TcpOption::MaxSegmentSize(value).emit(tmp);
1016 }
1017 if let Some(value) = self.window_scale {
1018 let tmp = options;
1019 options = TcpOption::WindowScale(value).emit(tmp);
1020 }
1021 if self.sack_permitted {
1022 let tmp = options;
1023 options = TcpOption::SackPermitted.emit(tmp);
1024 } else if self.ack_number.is_some() && self.sack_ranges.iter().any(|s| s.is_some()) {
1025 let tmp = options;
1026 options = TcpOption::SackRange(self.sack_ranges).emit(tmp);
1027 }
1028 if let Some(timestamp) = self.timestamp {
1029 let tmp = options;
1030 options = TcpOption::TimeStamp {
1031 tsval: timestamp.tsval,
1032 tsecr: timestamp.tsecr,
1033 }
1034 .emit(tmp);
1035 }
1036
1037 if !options.is_empty() {
1038 TcpOption::EndOfList.emit(options);
1039 }
1040 }
1041 packet.set_urgent_at(0);
1042 packet.payload_mut()[..self.payload.len()].copy_from_slice(self.payload);
1043
1044 if checksum_caps.tcp.tx() {
1045 packet.fill_checksum(src_addr, dst_addr)
1046 } else {
1047 packet.set_checksum(0);
1050 }
1051 }
1052
1053 pub const fn segment_len(&self) -> usize {
1055 self.payload.len() + self.control.len()
1056 }
1057
1058 pub const fn is_empty(&self) -> bool {
1060 match self.control {
1061 _ if !self.payload.is_empty() => false,
1062 Control::Syn | Control::Fin | Control::Rst => false,
1063 Control::None | Control::Psh => true,
1064 }
1065 }
1066}
1067
1068impl<'a, T: AsRef<[u8]> + ?Sized> fmt::Display for Packet<&'a T> {
1069 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1070 write!(f, "TCP src={} dst={}", self.src_port(), self.dst_port())?;
1072 if self.syn() {
1073 write!(f, " syn")?
1074 }
1075 if self.fin() {
1076 write!(f, " fin")?
1077 }
1078 if self.rst() {
1079 write!(f, " rst")?
1080 }
1081 if self.psh() {
1082 write!(f, " psh")?
1083 }
1084 if self.ece() {
1085 write!(f, " ece")?
1086 }
1087 if self.cwr() {
1088 write!(f, " cwr")?
1089 }
1090 if self.ns() {
1091 write!(f, " ns")?
1092 }
1093 write!(f, " seq={}", self.seq_number())?;
1094 if self.ack() {
1095 write!(f, " ack={}", self.ack_number())?;
1096 }
1097 write!(f, " win={}", self.window_len())?;
1098 if self.urg() {
1099 write!(f, " urg={}", self.urgent_at())?;
1100 }
1101 write!(f, " len={}", self.payload().len())?;
1102
1103 let mut options = self.options();
1104 while !options.is_empty() {
1105 let (next_options, option) = match TcpOption::parse(options) {
1106 Ok(res) => res,
1107 Err(err) => return write!(f, " ({err})"),
1108 };
1109 match option {
1110 TcpOption::EndOfList => break,
1111 TcpOption::NoOperation => (),
1112 TcpOption::MaxSegmentSize(value) => write!(f, " mss={value}")?,
1113 TcpOption::WindowScale(value) => write!(f, " ws={value}")?,
1114 TcpOption::SackPermitted => write!(f, " sACK")?,
1115 TcpOption::SackRange(slice) => write!(f, " sACKr{slice:?}")?, TcpOption::TimeStamp { tsval, tsecr } => {
1117 write!(f, " tsval {tsval:08x} tsecr {tsecr:08x}")?
1118 }
1119 TcpOption::Unknown { kind, .. } => write!(f, " opt({kind})")?,
1120 }
1121 options = next_options;
1122 }
1123 Ok(())
1124 }
1125}
1126
1127impl<'a> fmt::Display for Repr<'a> {
1128 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1129 write!(f, "TCP src={} dst={}", self.src_port, self.dst_port)?;
1130 match self.control {
1131 Control::Syn => write!(f, " syn")?,
1132 Control::Fin => write!(f, " fin")?,
1133 Control::Rst => write!(f, " rst")?,
1134 Control::Psh => write!(f, " psh")?,
1135 Control::None => (),
1136 }
1137 write!(f, " seq={}", self.seq_number)?;
1138 if let Some(ack_number) = self.ack_number {
1139 write!(f, " ack={ack_number}")?;
1140 }
1141 write!(f, " win={}", self.window_len)?;
1142 write!(f, " len={}", self.payload.len())?;
1143 if let Some(max_seg_size) = self.max_seg_size {
1144 write!(f, " mss={max_seg_size}")?;
1145 }
1146 Ok(())
1147 }
1148}
1149
1150#[cfg(feature = "defmt")]
1151impl<'a> defmt::Format for Repr<'a> {
1152 fn format(&self, fmt: defmt::Formatter) {
1153 defmt::write!(fmt, "TCP src={} dst={}", self.src_port, self.dst_port);
1154 match self.control {
1155 Control::Syn => defmt::write!(fmt, " syn"),
1156 Control::Fin => defmt::write!(fmt, " fin"),
1157 Control::Rst => defmt::write!(fmt, " rst"),
1158 Control::Psh => defmt::write!(fmt, " psh"),
1159 Control::None => (),
1160 }
1161 defmt::write!(fmt, " seq={}", self.seq_number);
1162 if let Some(ack_number) = self.ack_number {
1163 defmt::write!(fmt, " ack={}", ack_number);
1164 }
1165 defmt::write!(fmt, " win={}", self.window_len);
1166 defmt::write!(fmt, " len={}", self.payload.len());
1167 if let Some(max_seg_size) = self.max_seg_size {
1168 defmt::write!(fmt, " mss={}", max_seg_size);
1169 }
1170 }
1171}
1172
1173use crate::wire::pretty_print::{PrettyIndent, PrettyPrint};
1174
1175impl<T: AsRef<[u8]>> PrettyPrint for Packet<T> {
1176 fn pretty_print(
1177 buffer: &dyn AsRef<[u8]>,
1178 f: &mut fmt::Formatter,
1179 indent: &mut PrettyIndent,
1180 ) -> fmt::Result {
1181 match Packet::new_checked(buffer) {
1182 Err(err) => write!(f, "{indent}({err})"),
1183 Ok(packet) => write!(f, "{indent}{packet}"),
1184 }
1185 }
1186}
1187
1188#[cfg(test)]
1189mod test {
1190 use super::*;
1191 #[cfg(feature = "proto-ipv4")]
1192 use crate::wire::Ipv4Address;
1193
1194 #[cfg(feature = "proto-ipv4")]
1195 const SRC_ADDR: Ipv4Address = Ipv4Address::new(192, 168, 1, 1);
1196 #[cfg(feature = "proto-ipv4")]
1197 const DST_ADDR: Ipv4Address = Ipv4Address::new(192, 168, 1, 2);
1198
1199 #[cfg(feature = "proto-ipv4")]
1200 static PACKET_BYTES: [u8; 28] = [
1201 0xbf, 0x00, 0x00, 0x50, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x60, 0x35, 0x01,
1202 0x23, 0x01, 0xb6, 0x02, 0x01, 0x03, 0x03, 0x0c, 0x01, 0xaa, 0x00, 0x00, 0xff,
1203 ];
1204
1205 #[cfg(feature = "proto-ipv4")]
1206 static OPTION_BYTES: [u8; 4] = [0x03, 0x03, 0x0c, 0x01];
1207
1208 #[cfg(feature = "proto-ipv4")]
1209 static PAYLOAD_BYTES: [u8; 4] = [0xaa, 0x00, 0x00, 0xff];
1210
1211 #[test]
1212 #[cfg(feature = "proto-ipv4")]
1213 fn test_deconstruct() {
1214 let packet = Packet::new_unchecked(&PACKET_BYTES[..]);
1215 assert_eq!(packet.src_port(), 48896);
1216 assert_eq!(packet.dst_port(), 80);
1217 assert_eq!(packet.seq_number(), SeqNumber(0x01234567));
1218 assert_eq!(packet.ack_number(), SeqNumber(0x89abcdefu32 as i32));
1219 assert_eq!(packet.header_len(), 24);
1220 assert!(packet.fin());
1221 assert!(!packet.syn());
1222 assert!(packet.rst());
1223 assert!(!packet.psh());
1224 assert!(packet.ack());
1225 assert!(packet.urg());
1226 assert_eq!(packet.window_len(), 0x0123);
1227 assert_eq!(packet.urgent_at(), 0x0201);
1228 assert_eq!(packet.checksum(), 0x01b6);
1229 assert_eq!(packet.options(), &OPTION_BYTES[..]);
1230 assert_eq!(packet.payload(), &PAYLOAD_BYTES[..]);
1231 assert!(packet.verify_checksum(&SRC_ADDR.into(), &DST_ADDR.into()));
1232 }
1233
1234 #[test]
1235 #[cfg(feature = "proto-ipv4")]
1236 fn test_construct() {
1237 let mut bytes = vec![0xa5; PACKET_BYTES.len()];
1238 let mut packet = Packet::new_unchecked(&mut bytes);
1239 packet.set_src_port(48896);
1240 packet.set_dst_port(80);
1241 packet.set_seq_number(SeqNumber(0x01234567));
1242 packet.set_ack_number(SeqNumber(0x89abcdefu32 as i32));
1243 packet.set_header_len(24);
1244 packet.clear_flags();
1245 packet.set_fin(true);
1246 packet.set_syn(false);
1247 packet.set_rst(true);
1248 packet.set_psh(false);
1249 packet.set_ack(true);
1250 packet.set_urg(true);
1251 packet.set_window_len(0x0123);
1252 packet.set_urgent_at(0x0201);
1253 packet.set_checksum(0xEEEE);
1254 packet.options_mut().copy_from_slice(&OPTION_BYTES[..]);
1255 packet.payload_mut().copy_from_slice(&PAYLOAD_BYTES[..]);
1256 packet.fill_checksum(&SRC_ADDR.into(), &DST_ADDR.into());
1257 assert_eq!(&*packet.into_inner(), &PACKET_BYTES[..]);
1258 }
1259
1260 #[test]
1261 #[cfg(feature = "proto-ipv4")]
1262 fn test_truncated() {
1263 let packet = Packet::new_unchecked(&PACKET_BYTES[..23]);
1264 assert_eq!(packet.check_len(), Err(Error));
1265 }
1266
1267 #[test]
1268 fn test_impossible_len() {
1269 let mut bytes = vec![0; 20];
1270 let mut packet = Packet::new_unchecked(&mut bytes);
1271 packet.set_header_len(10);
1272 assert_eq!(packet.check_len(), Err(Error));
1273 }
1274
1275 #[cfg(feature = "proto-ipv4")]
1276 static SYN_PACKET_BYTES: [u8; 24] = [
1277 0xbf, 0x00, 0x00, 0x50, 0x01, 0x23, 0x45, 0x67, 0x00, 0x00, 0x00, 0x00, 0x50, 0x02, 0x01,
1278 0x23, 0x7a, 0x8d, 0x00, 0x00, 0xaa, 0x00, 0x00, 0xff,
1279 ];
1280
1281 #[cfg(feature = "proto-ipv4")]
1282 fn packet_repr() -> Repr<'static> {
1283 Repr {
1284 src_port: 48896,
1285 dst_port: 80,
1286 seq_number: SeqNumber(0x01234567),
1287 ack_number: None,
1288 window_len: 0x0123,
1289 window_scale: None,
1290 control: Control::Syn,
1291 max_seg_size: None,
1292 sack_permitted: false,
1293 sack_ranges: [None, None, None],
1294 timestamp: None,
1295 payload: &PAYLOAD_BYTES,
1296 }
1297 }
1298
1299 #[test]
1300 #[cfg(feature = "proto-ipv4")]
1301 fn test_parse() {
1302 let packet = Packet::new_unchecked(&SYN_PACKET_BYTES[..]);
1303 let repr = Repr::parse(
1304 &packet,
1305 &SRC_ADDR.into(),
1306 &DST_ADDR.into(),
1307 &ChecksumCapabilities::default(),
1308 )
1309 .unwrap();
1310 assert_eq!(repr, packet_repr());
1311 }
1312
1313 #[test]
1314 #[cfg(feature = "proto-ipv4")]
1315 fn test_emit() {
1316 let repr = packet_repr();
1317 let mut bytes = vec![0xa5; repr.buffer_len()];
1318 let mut packet = Packet::new_unchecked(&mut bytes);
1319 repr.emit(
1320 &mut packet,
1321 &SRC_ADDR.into(),
1322 &DST_ADDR.into(),
1323 &ChecksumCapabilities::default(),
1324 );
1325 assert_eq!(&*packet.into_inner(), &SYN_PACKET_BYTES[..]);
1326 }
1327
1328 #[test]
1329 #[cfg(feature = "proto-ipv4")]
1330 fn test_header_len_multiple_of_4() {
1331 let mut repr = packet_repr();
1332 repr.window_scale = Some(0); assert_eq!(repr.header_len() % 4, 0); }
1335
1336 macro_rules! assert_option_parses {
1337 ($opt:expr, $data:expr) => {{
1338 assert_eq!(TcpOption::parse($data), Ok((&[][..], $opt)));
1339 let buffer = &mut [0; 40][..$opt.buffer_len()];
1340 assert_eq!($opt.emit(buffer), &mut []);
1341 assert_eq!(&*buffer, $data);
1342 }};
1343 }
1344
1345 #[test]
1346 fn test_tcp_options() {
1347 assert_option_parses!(TcpOption::EndOfList, &[0x00]);
1348 assert_option_parses!(TcpOption::NoOperation, &[0x01]);
1349 assert_option_parses!(TcpOption::MaxSegmentSize(1500), &[0x02, 0x04, 0x05, 0xdc]);
1350 assert_option_parses!(TcpOption::WindowScale(12), &[0x03, 0x03, 0x0c]);
1351 assert_option_parses!(TcpOption::SackPermitted, &[0x4, 0x02]);
1352 assert_option_parses!(
1353 TcpOption::SackRange([Some((500, 1500)), None, None]),
1354 &[0x05, 0x0a, 0x00, 0x00, 0x01, 0xf4, 0x00, 0x00, 0x05, 0xdc]
1355 );
1356 assert_option_parses!(
1357 TcpOption::SackRange([Some((875, 1225)), Some((1500, 2500)), None]),
1358 &[
1359 0x05, 0x12, 0x00, 0x00, 0x03, 0x6b, 0x00, 0x00, 0x04, 0xc9, 0x00, 0x00, 0x05, 0xdc,
1360 0x00, 0x00, 0x09, 0xc4
1361 ]
1362 );
1363 assert_option_parses!(
1364 TcpOption::SackRange([
1365 Some((875000, 1225000)),
1366 Some((1500000, 2500000)),
1367 Some((876543210, 876654320))
1368 ]),
1369 &[
1370 0x05, 0x1a, 0x00, 0x0d, 0x59, 0xf8, 0x00, 0x12, 0xb1, 0x28, 0x00, 0x16, 0xe3, 0x60,
1371 0x00, 0x26, 0x25, 0xa0, 0x34, 0x3e, 0xfc, 0xea, 0x34, 0x40, 0xae, 0xf0
1372 ]
1373 );
1374 assert_option_parses!(
1375 TcpOption::TimeStamp {
1376 tsval: 5000000,
1377 tsecr: 7000000
1378 },
1379 &[
1380 0x08, 0x0a, 0x00, 0x4c, 0x4b, 0x40, 0x00, 0x6a, 0xcf, 0xc0 ]
1385 );
1386 assert_option_parses!(
1387 TcpOption::Unknown {
1388 kind: 12,
1389 data: &[1, 2, 3][..]
1390 },
1391 &[0x0c, 0x05, 0x01, 0x02, 0x03]
1392 )
1393 }
1394
1395 #[test]
1396 fn test_malformed_tcp_options() {
1397 assert_eq!(TcpOption::parse(&[]), Err(Error));
1398 assert_eq!(TcpOption::parse(&[0xc]), Err(Error));
1399 assert_eq!(TcpOption::parse(&[0xc, 0x05, 0x01, 0x02]), Err(Error));
1400 assert_eq!(TcpOption::parse(&[0xc, 0x01]), Err(Error));
1401 assert_eq!(TcpOption::parse(&[0x2, 0x02]), Err(Error));
1402 assert_eq!(TcpOption::parse(&[0x3, 0x02]), Err(Error));
1403 }
1404}