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