1use byteorder::{ByteOrder, NetworkEndian};
2use core::{cmp, fmt, i32, 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}
135
136pub const HEADER_LEN: usize = field::URGENT.end;
137
138impl<T: AsRef<[u8]>> Packet<T> {
139 pub const fn new_unchecked(buffer: T) -> Packet<T> {
141 Packet { buffer }
142 }
143
144 pub fn new_checked(buffer: T) -> Result<Packet<T>> {
149 let packet = Self::new_unchecked(buffer);
150 packet.check_len()?;
151 Ok(packet)
152 }
153
154 pub fn check_len(&self) -> Result<()> {
163 let len = self.buffer.as_ref().len();
164 if len < field::URGENT.end {
165 Err(Error)
166 } else {
167 let header_len = self.header_len() as usize;
168 if len < header_len || header_len < field::URGENT.end {
169 Err(Error)
170 } else {
171 Ok(())
172 }
173 }
174 }
175
176 pub fn into_inner(self) -> T {
178 self.buffer
179 }
180
181 #[inline]
183 pub fn src_port(&self) -> u16 {
184 let data = self.buffer.as_ref();
185 NetworkEndian::read_u16(&data[field::SRC_PORT])
186 }
187
188 #[inline]
190 pub fn dst_port(&self) -> u16 {
191 let data = self.buffer.as_ref();
192 NetworkEndian::read_u16(&data[field::DST_PORT])
193 }
194
195 #[inline]
197 pub fn seq_number(&self) -> SeqNumber {
198 let data = self.buffer.as_ref();
199 SeqNumber(NetworkEndian::read_i32(&data[field::SEQ_NUM]))
200 }
201
202 #[inline]
204 pub fn ack_number(&self) -> SeqNumber {
205 let data = self.buffer.as_ref();
206 SeqNumber(NetworkEndian::read_i32(&data[field::ACK_NUM]))
207 }
208
209 #[inline]
211 pub fn fin(&self) -> bool {
212 let data = self.buffer.as_ref();
213 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
214 raw & field::FLG_FIN != 0
215 }
216
217 #[inline]
219 pub fn syn(&self) -> bool {
220 let data = self.buffer.as_ref();
221 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
222 raw & field::FLG_SYN != 0
223 }
224
225 #[inline]
227 pub fn rst(&self) -> bool {
228 let data = self.buffer.as_ref();
229 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
230 raw & field::FLG_RST != 0
231 }
232
233 #[inline]
235 pub fn psh(&self) -> bool {
236 let data = self.buffer.as_ref();
237 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
238 raw & field::FLG_PSH != 0
239 }
240
241 #[inline]
243 pub fn ack(&self) -> bool {
244 let data = self.buffer.as_ref();
245 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
246 raw & field::FLG_ACK != 0
247 }
248
249 #[inline]
251 pub fn urg(&self) -> bool {
252 let data = self.buffer.as_ref();
253 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
254 raw & field::FLG_URG != 0
255 }
256
257 #[inline]
259 pub fn ece(&self) -> bool {
260 let data = self.buffer.as_ref();
261 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
262 raw & field::FLG_ECE != 0
263 }
264
265 #[inline]
267 pub fn cwr(&self) -> bool {
268 let data = self.buffer.as_ref();
269 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
270 raw & field::FLG_CWR != 0
271 }
272
273 #[inline]
275 pub fn ns(&self) -> bool {
276 let data = self.buffer.as_ref();
277 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
278 raw & field::FLG_NS != 0
279 }
280
281 #[inline]
283 pub fn header_len(&self) -> u8 {
284 let data = self.buffer.as_ref();
285 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
286 ((raw >> 12) * 4) as u8
287 }
288
289 #[inline]
291 pub fn window_len(&self) -> u16 {
292 let data = self.buffer.as_ref();
293 NetworkEndian::read_u16(&data[field::WIN_SIZE])
294 }
295
296 #[inline]
298 pub fn checksum(&self) -> u16 {
299 let data = self.buffer.as_ref();
300 NetworkEndian::read_u16(&data[field::CHECKSUM])
301 }
302
303 #[inline]
305 pub fn urgent_at(&self) -> u16 {
306 let data = self.buffer.as_ref();
307 NetworkEndian::read_u16(&data[field::URGENT])
308 }
309
310 pub fn segment_len(&self) -> usize {
312 let data = self.buffer.as_ref();
313 let mut length = data.len() - self.header_len() as usize;
314 if self.syn() {
315 length += 1
316 }
317 if self.fin() {
318 length += 1
319 }
320 length
321 }
322
323 pub fn selective_ack_permitted(&self) -> Result<bool> {
325 let data = self.buffer.as_ref();
326 let mut options = &data[field::OPTIONS(self.header_len())];
327 while !options.is_empty() {
328 let (next_options, option) = TcpOption::parse(options)?;
329 if option == TcpOption::SackPermitted {
330 return Ok(true);
331 }
332 options = next_options;
333 }
334 Ok(false)
335 }
336
337 pub fn selective_ack_ranges(&self) -> Result<[Option<(u32, u32)>; 3]> {
341 let data = self.buffer.as_ref();
342 let mut options = &data[field::OPTIONS(self.header_len())];
343 while !options.is_empty() {
344 let (next_options, option) = TcpOption::parse(options)?;
345 if let TcpOption::SackRange(slice) = option {
346 return Ok(slice);
347 }
348 options = next_options;
349 }
350 Ok([None, None, None])
351 }
352
353 pub fn verify_checksum(&self, src_addr: &IpAddress, dst_addr: &IpAddress) -> bool {
362 if cfg!(fuzzing) {
363 return true;
364 }
365
366 let data = self.buffer.as_ref();
367 checksum::combine(&[
368 checksum::pseudo_header(src_addr, dst_addr, IpProtocol::Tcp, data.len() as u32),
369 checksum::data(data),
370 ]) == !0
371 }
372}
373
374impl<'a, T: AsRef<[u8]> + ?Sized> Packet<&'a T> {
375 #[inline]
377 pub fn options(&self) -> &'a [u8] {
378 let header_len = self.header_len();
379 let data = self.buffer.as_ref();
380 &data[field::OPTIONS(header_len)]
381 }
382
383 #[inline]
385 pub fn payload(&self) -> &'a [u8] {
386 let header_len = self.header_len() as usize;
387 let data = self.buffer.as_ref();
388 &data[header_len..]
389 }
390}
391
392impl<T: AsRef<[u8]> + AsMut<[u8]>> Packet<T> {
393 #[inline]
395 pub fn set_src_port(&mut self, value: u16) {
396 let data = self.buffer.as_mut();
397 NetworkEndian::write_u16(&mut data[field::SRC_PORT], value)
398 }
399
400 #[inline]
402 pub fn set_dst_port(&mut self, value: u16) {
403 let data = self.buffer.as_mut();
404 NetworkEndian::write_u16(&mut data[field::DST_PORT], value)
405 }
406
407 #[inline]
409 pub fn set_seq_number(&mut self, value: SeqNumber) {
410 let data = self.buffer.as_mut();
411 NetworkEndian::write_i32(&mut data[field::SEQ_NUM], value.0)
412 }
413
414 #[inline]
416 pub fn set_ack_number(&mut self, value: SeqNumber) {
417 let data = self.buffer.as_mut();
418 NetworkEndian::write_i32(&mut data[field::ACK_NUM], value.0)
419 }
420
421 #[inline]
423 pub fn clear_flags(&mut self) {
424 let data = self.buffer.as_mut();
425 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
426 let raw = raw & !0x0fff;
427 NetworkEndian::write_u16(&mut data[field::FLAGS], raw)
428 }
429
430 #[inline]
432 pub fn set_fin(&mut self, value: bool) {
433 let data = self.buffer.as_mut();
434 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
435 let raw = if value {
436 raw | field::FLG_FIN
437 } else {
438 raw & !field::FLG_FIN
439 };
440 NetworkEndian::write_u16(&mut data[field::FLAGS], raw)
441 }
442
443 #[inline]
445 pub fn set_syn(&mut self, value: bool) {
446 let data = self.buffer.as_mut();
447 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
448 let raw = if value {
449 raw | field::FLG_SYN
450 } else {
451 raw & !field::FLG_SYN
452 };
453 NetworkEndian::write_u16(&mut data[field::FLAGS], raw)
454 }
455
456 #[inline]
458 pub fn set_rst(&mut self, value: bool) {
459 let data = self.buffer.as_mut();
460 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
461 let raw = if value {
462 raw | field::FLG_RST
463 } else {
464 raw & !field::FLG_RST
465 };
466 NetworkEndian::write_u16(&mut data[field::FLAGS], raw)
467 }
468
469 #[inline]
471 pub fn set_psh(&mut self, value: bool) {
472 let data = self.buffer.as_mut();
473 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
474 let raw = if value {
475 raw | field::FLG_PSH
476 } else {
477 raw & !field::FLG_PSH
478 };
479 NetworkEndian::write_u16(&mut data[field::FLAGS], raw)
480 }
481
482 #[inline]
484 pub fn set_ack(&mut self, value: bool) {
485 let data = self.buffer.as_mut();
486 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
487 let raw = if value {
488 raw | field::FLG_ACK
489 } else {
490 raw & !field::FLG_ACK
491 };
492 NetworkEndian::write_u16(&mut data[field::FLAGS], raw)
493 }
494
495 #[inline]
497 pub fn set_urg(&mut self, value: bool) {
498 let data = self.buffer.as_mut();
499 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
500 let raw = if value {
501 raw | field::FLG_URG
502 } else {
503 raw & !field::FLG_URG
504 };
505 NetworkEndian::write_u16(&mut data[field::FLAGS], raw)
506 }
507
508 #[inline]
510 pub fn set_ece(&mut self, value: bool) {
511 let data = self.buffer.as_mut();
512 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
513 let raw = if value {
514 raw | field::FLG_ECE
515 } else {
516 raw & !field::FLG_ECE
517 };
518 NetworkEndian::write_u16(&mut data[field::FLAGS], raw)
519 }
520
521 #[inline]
523 pub fn set_cwr(&mut self, value: bool) {
524 let data = self.buffer.as_mut();
525 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
526 let raw = if value {
527 raw | field::FLG_CWR
528 } else {
529 raw & !field::FLG_CWR
530 };
531 NetworkEndian::write_u16(&mut data[field::FLAGS], raw)
532 }
533
534 #[inline]
536 pub fn set_ns(&mut self, value: bool) {
537 let data = self.buffer.as_mut();
538 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
539 let raw = if value {
540 raw | field::FLG_NS
541 } else {
542 raw & !field::FLG_NS
543 };
544 NetworkEndian::write_u16(&mut data[field::FLAGS], raw)
545 }
546
547 #[inline]
549 pub fn set_header_len(&mut self, value: u8) {
550 let data = self.buffer.as_mut();
551 let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
552 let raw = (raw & !0xf000) | ((value as u16) / 4) << 12;
553 NetworkEndian::write_u16(&mut data[field::FLAGS], raw)
554 }
555
556 #[inline]
558 pub fn set_window_len(&mut self, value: u16) {
559 let data = self.buffer.as_mut();
560 NetworkEndian::write_u16(&mut data[field::WIN_SIZE], value)
561 }
562
563 #[inline]
565 pub fn set_checksum(&mut self, value: u16) {
566 let data = self.buffer.as_mut();
567 NetworkEndian::write_u16(&mut data[field::CHECKSUM], value)
568 }
569
570 #[inline]
572 pub fn set_urgent_at(&mut self, value: u16) {
573 let data = self.buffer.as_mut();
574 NetworkEndian::write_u16(&mut data[field::URGENT], value)
575 }
576
577 pub fn fill_checksum(&mut self, src_addr: &IpAddress, dst_addr: &IpAddress) {
583 self.set_checksum(0);
584 let checksum = {
585 let data = self.buffer.as_ref();
586 !checksum::combine(&[
587 checksum::pseudo_header(src_addr, dst_addr, IpProtocol::Tcp, data.len() as u32),
588 checksum::data(data),
589 ])
590 };
591 self.set_checksum(checksum)
592 }
593
594 #[inline]
596 pub fn options_mut(&mut self) -> &mut [u8] {
597 let header_len = self.header_len();
598 let data = self.buffer.as_mut();
599 &mut data[field::OPTIONS(header_len)]
600 }
601
602 #[inline]
604 pub fn payload_mut(&mut self) -> &mut [u8] {
605 let header_len = self.header_len() as usize;
606 let data = self.buffer.as_mut();
607 &mut data[header_len..]
608 }
609}
610
611impl<T: AsRef<[u8]>> AsRef<[u8]> for Packet<T> {
612 fn as_ref(&self) -> &[u8] {
613 self.buffer.as_ref()
614 }
615}
616
617#[derive(Debug, PartialEq, Eq, Clone, Copy)]
619#[cfg_attr(feature = "defmt", derive(defmt::Format))]
620pub enum TcpOption<'a> {
621 EndOfList,
622 NoOperation,
623 MaxSegmentSize(u16),
624 WindowScale(u8),
625 SackPermitted,
626 SackRange([Option<(u32, u32)>; 3]),
627 Unknown { kind: u8, data: &'a [u8] },
628}
629
630impl<'a> TcpOption<'a> {
631 pub fn parse(buffer: &'a [u8]) -> Result<(&'a [u8], TcpOption<'a>)> {
632 let (length, option);
633 match *buffer.first().ok_or(Error)? {
634 field::OPT_END => {
635 length = 1;
636 option = TcpOption::EndOfList;
637 }
638 field::OPT_NOP => {
639 length = 1;
640 option = TcpOption::NoOperation;
641 }
642 kind => {
643 length = *buffer.get(1).ok_or(Error)? as usize;
644 let data = buffer.get(2..length).ok_or(Error)?;
645 match (kind, length) {
646 (field::OPT_END, _) | (field::OPT_NOP, _) => unreachable!(),
647 (field::OPT_MSS, 4) => {
648 option = TcpOption::MaxSegmentSize(NetworkEndian::read_u16(data))
649 }
650 (field::OPT_MSS, _) => return Err(Error),
651 (field::OPT_WS, 3) => option = TcpOption::WindowScale(data[0]),
652 (field::OPT_WS, _) => return Err(Error),
653 (field::OPT_SACKPERM, 2) => option = TcpOption::SackPermitted,
654 (field::OPT_SACKPERM, _) => return Err(Error),
655 (field::OPT_SACKRNG, n) => {
656 if n < 10 || (n - 2) % 8 != 0 {
657 return Err(Error);
658 }
659 if n > 26 {
660 net_debug!("sACK with >3 blocks, truncating to 3");
670 }
671 let mut sack_ranges: [Option<(u32, u32)>; 3] = [None; 3];
672
673 sack_ranges.iter_mut().enumerate().for_each(|(i, nmut)| {
677 let left = i * 8;
678 *nmut = if left < data.len() {
679 let mid = left + 4;
680 let right = mid + 4;
681 let range_left = NetworkEndian::read_u32(&data[left..mid]);
682 let range_right = NetworkEndian::read_u32(&data[mid..right]);
683 Some((range_left, range_right))
684 } else {
685 None
686 };
687 });
688 option = TcpOption::SackRange(sack_ranges);
689 }
690 (_, _) => option = TcpOption::Unknown { kind, data },
691 }
692 }
693 }
694 Ok((&buffer[length..], option))
695 }
696
697 pub fn buffer_len(&self) -> usize {
698 match *self {
699 TcpOption::EndOfList => 1,
700 TcpOption::NoOperation => 1,
701 TcpOption::MaxSegmentSize(_) => 4,
702 TcpOption::WindowScale(_) => 3,
703 TcpOption::SackPermitted => 2,
704 TcpOption::SackRange(s) => s.iter().filter(|s| s.is_some()).count() * 8 + 2,
705 TcpOption::Unknown { data, .. } => 2 + data.len(),
706 }
707 }
708
709 pub fn emit<'b>(&self, buffer: &'b mut [u8]) -> &'b mut [u8] {
710 let length;
711 match *self {
712 TcpOption::EndOfList => {
713 length = 1;
714 for p in buffer.iter_mut() {
716 *p = field::OPT_END;
717 }
718 }
719 TcpOption::NoOperation => {
720 length = 1;
721 buffer[0] = field::OPT_NOP;
722 }
723 _ => {
724 length = self.buffer_len();
725 buffer[1] = length as u8;
726 match self {
727 &TcpOption::EndOfList | &TcpOption::NoOperation => unreachable!(),
728 &TcpOption::MaxSegmentSize(value) => {
729 buffer[0] = field::OPT_MSS;
730 NetworkEndian::write_u16(&mut buffer[2..], value)
731 }
732 &TcpOption::WindowScale(value) => {
733 buffer[0] = field::OPT_WS;
734 buffer[2] = value;
735 }
736 &TcpOption::SackPermitted => {
737 buffer[0] = field::OPT_SACKPERM;
738 }
739 &TcpOption::SackRange(slice) => {
740 buffer[0] = field::OPT_SACKRNG;
741 slice
742 .iter()
743 .filter(|s| s.is_some())
744 .enumerate()
745 .for_each(|(i, s)| {
746 let (first, second) = *s.as_ref().unwrap();
747 let pos = i * 8 + 2;
748 NetworkEndian::write_u32(&mut buffer[pos..], first);
749 NetworkEndian::write_u32(&mut buffer[pos + 4..], second);
750 });
751 }
752 &TcpOption::Unknown {
753 kind,
754 data: provided,
755 } => {
756 buffer[0] = kind;
757 buffer[2..].copy_from_slice(provided)
758 }
759 }
760 }
761 }
762 &mut buffer[length..]
763 }
764}
765
766#[derive(Debug, PartialEq, Eq, Clone, Copy)]
768#[cfg_attr(feature = "defmt", derive(defmt::Format))]
769pub enum Control {
770 None,
771 Psh,
772 Syn,
773 Fin,
774 Rst,
775}
776
777#[allow(clippy::len_without_is_empty)]
778impl Control {
779 pub const fn len(self) -> usize {
781 match self {
782 Control::Syn | Control::Fin => 1,
783 _ => 0,
784 }
785 }
786
787 pub const fn quash_psh(self) -> Control {
789 match self {
790 Control::Psh => Control::None,
791 _ => self,
792 }
793 }
794}
795
796#[derive(Debug, PartialEq, Eq, Clone, Copy)]
798pub struct Repr<'a> {
799 pub src_port: u16,
800 pub dst_port: u16,
801 pub control: Control,
802 pub seq_number: SeqNumber,
803 pub ack_number: Option<SeqNumber>,
804 pub window_len: u16,
805 pub window_scale: Option<u8>,
806 pub max_seg_size: Option<u16>,
807 pub sack_permitted: bool,
808 pub sack_ranges: [Option<(u32, u32)>; 3],
809 pub payload: &'a [u8],
810}
811
812impl<'a> Repr<'a> {
813 pub fn parse<T>(
815 packet: &Packet<&'a T>,
816 src_addr: &IpAddress,
817 dst_addr: &IpAddress,
818 checksum_caps: &ChecksumCapabilities,
819 ) -> Result<Repr<'a>>
820 where
821 T: AsRef<[u8]> + ?Sized,
822 {
823 if packet.src_port() == 0 {
825 return Err(Error);
826 }
827 if packet.dst_port() == 0 {
828 return Err(Error);
829 }
830 if checksum_caps.tcp.rx() && !packet.verify_checksum(src_addr, dst_addr) {
832 return Err(Error);
833 }
834
835 let control = match (packet.syn(), packet.fin(), packet.rst(), packet.psh()) {
836 (false, false, false, false) => Control::None,
837 (false, false, false, true) => Control::Psh,
838 (true, false, false, _) => Control::Syn,
839 (false, true, false, _) => Control::Fin,
840 (false, false, true, _) => Control::Rst,
841 _ => return Err(Error),
842 };
843 let ack_number = match packet.ack() {
844 true => Some(packet.ack_number()),
845 false => None,
846 };
847 let mut max_seg_size = None;
853 let mut window_scale = None;
854 let mut options = packet.options();
855 let mut sack_permitted = false;
856 let mut sack_ranges = [None, None, None];
857 while !options.is_empty() {
858 let (next_options, option) = TcpOption::parse(options)?;
859 match option {
860 TcpOption::EndOfList => break,
861 TcpOption::NoOperation => (),
862 TcpOption::MaxSegmentSize(value) => max_seg_size = Some(value),
863 TcpOption::WindowScale(value) => {
864 window_scale = if value > 14 {
869 net_debug!(
870 "{}:{}:{}:{}: parsed window scaling factor >14, setting to 14",
871 src_addr,
872 packet.src_port(),
873 dst_addr,
874 packet.dst_port()
875 );
876 Some(14)
877 } else {
878 Some(value)
879 };
880 }
881 TcpOption::SackPermitted => sack_permitted = true,
882 TcpOption::SackRange(slice) => sack_ranges = slice,
883 _ => (),
884 }
885 options = next_options;
886 }
887
888 Ok(Repr {
889 src_port: packet.src_port(),
890 dst_port: packet.dst_port(),
891 control: control,
892 seq_number: packet.seq_number(),
893 ack_number: ack_number,
894 window_len: packet.window_len(),
895 window_scale: window_scale,
896 max_seg_size: max_seg_size,
897 sack_permitted: sack_permitted,
898 sack_ranges: sack_ranges,
899 payload: packet.payload(),
900 })
901 }
902
903 pub fn header_len(&self) -> usize {
908 let mut length = field::URGENT.end;
909 if self.max_seg_size.is_some() {
910 length += 4
911 }
912 if self.window_scale.is_some() {
913 length += 3
914 }
915 if self.sack_permitted {
916 length += 2;
917 }
918 let sack_range_len: usize = self
919 .sack_ranges
920 .iter()
921 .map(|o| o.map(|_| 8).unwrap_or(0))
922 .sum();
923 if sack_range_len > 0 {
924 length += sack_range_len + 2;
925 }
926 if length % 4 != 0 {
927 length += 4 - length % 4;
928 }
929 length
930 }
931
932 pub fn buffer_len(&self) -> usize {
934 self.header_len() + self.payload.len()
935 }
936
937 pub fn emit<T>(
939 &self,
940 packet: &mut Packet<&mut T>,
941 src_addr: &IpAddress,
942 dst_addr: &IpAddress,
943 checksum_caps: &ChecksumCapabilities,
944 ) where
945 T: AsRef<[u8]> + AsMut<[u8]> + ?Sized,
946 {
947 packet.set_src_port(self.src_port);
948 packet.set_dst_port(self.dst_port);
949 packet.set_seq_number(self.seq_number);
950 packet.set_ack_number(self.ack_number.unwrap_or(SeqNumber(0)));
951 packet.set_window_len(self.window_len);
952 packet.set_header_len(self.header_len() as u8);
953 packet.clear_flags();
954 match self.control {
955 Control::None => (),
956 Control::Psh => packet.set_psh(true),
957 Control::Syn => packet.set_syn(true),
958 Control::Fin => packet.set_fin(true),
959 Control::Rst => packet.set_rst(true),
960 }
961 packet.set_ack(self.ack_number.is_some());
962 {
963 let mut options = packet.options_mut();
964 if let Some(value) = self.max_seg_size {
965 let tmp = options;
966 options = TcpOption::MaxSegmentSize(value).emit(tmp);
967 }
968 if let Some(value) = self.window_scale {
969 let tmp = options;
970 options = TcpOption::WindowScale(value).emit(tmp);
971 }
972 if self.sack_permitted {
973 let tmp = options;
974 options = TcpOption::SackPermitted.emit(tmp);
975 } else if self.ack_number.is_some() && self.sack_ranges.iter().any(|s| s.is_some()) {
976 let tmp = options;
977 options = TcpOption::SackRange(self.sack_ranges).emit(tmp);
978 }
979
980 if !options.is_empty() {
981 TcpOption::EndOfList.emit(options);
982 }
983 }
984 packet.set_urgent_at(0);
985 packet.payload_mut()[..self.payload.len()].copy_from_slice(self.payload);
986
987 if checksum_caps.tcp.tx() {
988 packet.fill_checksum(src_addr, dst_addr)
989 } else {
990 packet.set_checksum(0);
993 }
994 }
995
996 pub const fn segment_len(&self) -> usize {
998 self.payload.len() + self.control.len()
999 }
1000
1001 pub const fn is_empty(&self) -> bool {
1003 match self.control {
1004 _ if !self.payload.is_empty() => false,
1005 Control::Syn | Control::Fin | Control::Rst => false,
1006 Control::None | Control::Psh => true,
1007 }
1008 }
1009}
1010
1011impl<'a, T: AsRef<[u8]> + ?Sized> fmt::Display for Packet<&'a T> {
1012 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1013 write!(f, "TCP src={} dst={}", self.src_port(), self.dst_port())?;
1015 if self.syn() {
1016 write!(f, " syn")?
1017 }
1018 if self.fin() {
1019 write!(f, " fin")?
1020 }
1021 if self.rst() {
1022 write!(f, " rst")?
1023 }
1024 if self.psh() {
1025 write!(f, " psh")?
1026 }
1027 if self.ece() {
1028 write!(f, " ece")?
1029 }
1030 if self.cwr() {
1031 write!(f, " cwr")?
1032 }
1033 if self.ns() {
1034 write!(f, " ns")?
1035 }
1036 write!(f, " seq={}", self.seq_number())?;
1037 if self.ack() {
1038 write!(f, " ack={}", self.ack_number())?;
1039 }
1040 write!(f, " win={}", self.window_len())?;
1041 if self.urg() {
1042 write!(f, " urg={}", self.urgent_at())?;
1043 }
1044 write!(f, " len={}", self.payload().len())?;
1045
1046 let mut options = self.options();
1047 while !options.is_empty() {
1048 let (next_options, option) = match TcpOption::parse(options) {
1049 Ok(res) => res,
1050 Err(err) => return write!(f, " ({err})"),
1051 };
1052 match option {
1053 TcpOption::EndOfList => break,
1054 TcpOption::NoOperation => (),
1055 TcpOption::MaxSegmentSize(value) => write!(f, " mss={value}")?,
1056 TcpOption::WindowScale(value) => write!(f, " ws={value}")?,
1057 TcpOption::SackPermitted => write!(f, " sACK")?,
1058 TcpOption::SackRange(slice) => write!(f, " sACKr{slice:?}")?, TcpOption::Unknown { kind, .. } => write!(f, " opt({kind})")?,
1060 }
1061 options = next_options;
1062 }
1063 Ok(())
1064 }
1065}
1066
1067impl<'a> fmt::Display for Repr<'a> {
1068 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1069 write!(f, "TCP src={} dst={}", self.src_port, self.dst_port)?;
1070 match self.control {
1071 Control::Syn => write!(f, " syn")?,
1072 Control::Fin => write!(f, " fin")?,
1073 Control::Rst => write!(f, " rst")?,
1074 Control::Psh => write!(f, " psh")?,
1075 Control::None => (),
1076 }
1077 write!(f, " seq={}", self.seq_number)?;
1078 if let Some(ack_number) = self.ack_number {
1079 write!(f, " ack={ack_number}")?;
1080 }
1081 write!(f, " win={}", self.window_len)?;
1082 write!(f, " len={}", self.payload.len())?;
1083 if let Some(max_seg_size) = self.max_seg_size {
1084 write!(f, " mss={max_seg_size}")?;
1085 }
1086 Ok(())
1087 }
1088}
1089
1090#[cfg(feature = "defmt")]
1091impl<'a> defmt::Format for Repr<'a> {
1092 fn format(&self, fmt: defmt::Formatter) {
1093 defmt::write!(fmt, "TCP src={} dst={}", self.src_port, self.dst_port);
1094 match self.control {
1095 Control::Syn => defmt::write!(fmt, " syn"),
1096 Control::Fin => defmt::write!(fmt, " fin"),
1097 Control::Rst => defmt::write!(fmt, " rst"),
1098 Control::Psh => defmt::write!(fmt, " psh"),
1099 Control::None => (),
1100 }
1101 defmt::write!(fmt, " seq={}", self.seq_number);
1102 if let Some(ack_number) = self.ack_number {
1103 defmt::write!(fmt, " ack={}", ack_number);
1104 }
1105 defmt::write!(fmt, " win={}", self.window_len);
1106 defmt::write!(fmt, " len={}", self.payload.len());
1107 if let Some(max_seg_size) = self.max_seg_size {
1108 defmt::write!(fmt, " mss={}", max_seg_size);
1109 }
1110 }
1111}
1112
1113use crate::wire::pretty_print::{PrettyIndent, PrettyPrint};
1114
1115impl<T: AsRef<[u8]>> PrettyPrint for Packet<T> {
1116 fn pretty_print(
1117 buffer: &dyn AsRef<[u8]>,
1118 f: &mut fmt::Formatter,
1119 indent: &mut PrettyIndent,
1120 ) -> fmt::Result {
1121 match Packet::new_checked(buffer) {
1122 Err(err) => write!(f, "{indent}({err})"),
1123 Ok(packet) => write!(f, "{indent}{packet}"),
1124 }
1125 }
1126}
1127
1128#[cfg(test)]
1129mod test {
1130 use super::*;
1131 #[cfg(feature = "proto-ipv4")]
1132 use crate::wire::Ipv4Address;
1133
1134 #[cfg(feature = "proto-ipv4")]
1135 const SRC_ADDR: Ipv4Address = Ipv4Address([192, 168, 1, 1]);
1136 #[cfg(feature = "proto-ipv4")]
1137 const DST_ADDR: Ipv4Address = Ipv4Address([192, 168, 1, 2]);
1138
1139 #[cfg(feature = "proto-ipv4")]
1140 static PACKET_BYTES: [u8; 28] = [
1141 0xbf, 0x00, 0x00, 0x50, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x60, 0x35, 0x01,
1142 0x23, 0x01, 0xb6, 0x02, 0x01, 0x03, 0x03, 0x0c, 0x01, 0xaa, 0x00, 0x00, 0xff,
1143 ];
1144
1145 #[cfg(feature = "proto-ipv4")]
1146 static OPTION_BYTES: [u8; 4] = [0x03, 0x03, 0x0c, 0x01];
1147
1148 #[cfg(feature = "proto-ipv4")]
1149 static PAYLOAD_BYTES: [u8; 4] = [0xaa, 0x00, 0x00, 0xff];
1150
1151 #[test]
1152 #[cfg(feature = "proto-ipv4")]
1153 fn test_deconstruct() {
1154 let packet = Packet::new_unchecked(&PACKET_BYTES[..]);
1155 assert_eq!(packet.src_port(), 48896);
1156 assert_eq!(packet.dst_port(), 80);
1157 assert_eq!(packet.seq_number(), SeqNumber(0x01234567));
1158 assert_eq!(packet.ack_number(), SeqNumber(0x89abcdefu32 as i32));
1159 assert_eq!(packet.header_len(), 24);
1160 assert!(packet.fin());
1161 assert!(!packet.syn());
1162 assert!(packet.rst());
1163 assert!(!packet.psh());
1164 assert!(packet.ack());
1165 assert!(packet.urg());
1166 assert_eq!(packet.window_len(), 0x0123);
1167 assert_eq!(packet.urgent_at(), 0x0201);
1168 assert_eq!(packet.checksum(), 0x01b6);
1169 assert_eq!(packet.options(), &OPTION_BYTES[..]);
1170 assert_eq!(packet.payload(), &PAYLOAD_BYTES[..]);
1171 assert!(packet.verify_checksum(&SRC_ADDR.into(), &DST_ADDR.into()));
1172 }
1173
1174 #[test]
1175 #[cfg(feature = "proto-ipv4")]
1176 fn test_construct() {
1177 let mut bytes = vec![0xa5; PACKET_BYTES.len()];
1178 let mut packet = Packet::new_unchecked(&mut bytes);
1179 packet.set_src_port(48896);
1180 packet.set_dst_port(80);
1181 packet.set_seq_number(SeqNumber(0x01234567));
1182 packet.set_ack_number(SeqNumber(0x89abcdefu32 as i32));
1183 packet.set_header_len(24);
1184 packet.clear_flags();
1185 packet.set_fin(true);
1186 packet.set_syn(false);
1187 packet.set_rst(true);
1188 packet.set_psh(false);
1189 packet.set_ack(true);
1190 packet.set_urg(true);
1191 packet.set_window_len(0x0123);
1192 packet.set_urgent_at(0x0201);
1193 packet.set_checksum(0xEEEE);
1194 packet.options_mut().copy_from_slice(&OPTION_BYTES[..]);
1195 packet.payload_mut().copy_from_slice(&PAYLOAD_BYTES[..]);
1196 packet.fill_checksum(&SRC_ADDR.into(), &DST_ADDR.into());
1197 assert_eq!(&*packet.into_inner(), &PACKET_BYTES[..]);
1198 }
1199
1200 #[test]
1201 #[cfg(feature = "proto-ipv4")]
1202 fn test_truncated() {
1203 let packet = Packet::new_unchecked(&PACKET_BYTES[..23]);
1204 assert_eq!(packet.check_len(), Err(Error));
1205 }
1206
1207 #[test]
1208 fn test_impossible_len() {
1209 let mut bytes = vec![0; 20];
1210 let mut packet = Packet::new_unchecked(&mut bytes);
1211 packet.set_header_len(10);
1212 assert_eq!(packet.check_len(), Err(Error));
1213 }
1214
1215 #[cfg(feature = "proto-ipv4")]
1216 static SYN_PACKET_BYTES: [u8; 24] = [
1217 0xbf, 0x00, 0x00, 0x50, 0x01, 0x23, 0x45, 0x67, 0x00, 0x00, 0x00, 0x00, 0x50, 0x02, 0x01,
1218 0x23, 0x7a, 0x8d, 0x00, 0x00, 0xaa, 0x00, 0x00, 0xff,
1219 ];
1220
1221 #[cfg(feature = "proto-ipv4")]
1222 fn packet_repr() -> Repr<'static> {
1223 Repr {
1224 src_port: 48896,
1225 dst_port: 80,
1226 seq_number: SeqNumber(0x01234567),
1227 ack_number: None,
1228 window_len: 0x0123,
1229 window_scale: None,
1230 control: Control::Syn,
1231 max_seg_size: None,
1232 sack_permitted: false,
1233 sack_ranges: [None, None, None],
1234 payload: &PAYLOAD_BYTES,
1235 }
1236 }
1237
1238 #[test]
1239 #[cfg(feature = "proto-ipv4")]
1240 fn test_parse() {
1241 let packet = Packet::new_unchecked(&SYN_PACKET_BYTES[..]);
1242 let repr = Repr::parse(
1243 &packet,
1244 &SRC_ADDR.into(),
1245 &DST_ADDR.into(),
1246 &ChecksumCapabilities::default(),
1247 )
1248 .unwrap();
1249 assert_eq!(repr, packet_repr());
1250 }
1251
1252 #[test]
1253 #[cfg(feature = "proto-ipv4")]
1254 fn test_emit() {
1255 let repr = packet_repr();
1256 let mut bytes = vec![0xa5; repr.buffer_len()];
1257 let mut packet = Packet::new_unchecked(&mut bytes);
1258 repr.emit(
1259 &mut packet,
1260 &SRC_ADDR.into(),
1261 &DST_ADDR.into(),
1262 &ChecksumCapabilities::default(),
1263 );
1264 assert_eq!(&*packet.into_inner(), &SYN_PACKET_BYTES[..]);
1265 }
1266
1267 #[test]
1268 #[cfg(feature = "proto-ipv4")]
1269 fn test_header_len_multiple_of_4() {
1270 let mut repr = packet_repr();
1271 repr.window_scale = Some(0); assert_eq!(repr.header_len() % 4, 0); }
1274
1275 macro_rules! assert_option_parses {
1276 ($opt:expr, $data:expr) => {{
1277 assert_eq!(TcpOption::parse($data), Ok((&[][..], $opt)));
1278 let buffer = &mut [0; 40][..$opt.buffer_len()];
1279 assert_eq!($opt.emit(buffer), &mut []);
1280 assert_eq!(&*buffer, $data);
1281 }};
1282 }
1283
1284 #[test]
1285 fn test_tcp_options() {
1286 assert_option_parses!(TcpOption::EndOfList, &[0x00]);
1287 assert_option_parses!(TcpOption::NoOperation, &[0x01]);
1288 assert_option_parses!(TcpOption::MaxSegmentSize(1500), &[0x02, 0x04, 0x05, 0xdc]);
1289 assert_option_parses!(TcpOption::WindowScale(12), &[0x03, 0x03, 0x0c]);
1290 assert_option_parses!(TcpOption::SackPermitted, &[0x4, 0x02]);
1291 assert_option_parses!(
1292 TcpOption::SackRange([Some((500, 1500)), None, None]),
1293 &[0x05, 0x0a, 0x00, 0x00, 0x01, 0xf4, 0x00, 0x00, 0x05, 0xdc]
1294 );
1295 assert_option_parses!(
1296 TcpOption::SackRange([Some((875, 1225)), Some((1500, 2500)), None]),
1297 &[
1298 0x05, 0x12, 0x00, 0x00, 0x03, 0x6b, 0x00, 0x00, 0x04, 0xc9, 0x00, 0x00, 0x05, 0xdc,
1299 0x00, 0x00, 0x09, 0xc4
1300 ]
1301 );
1302 assert_option_parses!(
1303 TcpOption::SackRange([
1304 Some((875000, 1225000)),
1305 Some((1500000, 2500000)),
1306 Some((876543210, 876654320))
1307 ]),
1308 &[
1309 0x05, 0x1a, 0x00, 0x0d, 0x59, 0xf8, 0x00, 0x12, 0xb1, 0x28, 0x00, 0x16, 0xe3, 0x60,
1310 0x00, 0x26, 0x25, 0xa0, 0x34, 0x3e, 0xfc, 0xea, 0x34, 0x40, 0xae, 0xf0
1311 ]
1312 );
1313 assert_option_parses!(
1314 TcpOption::Unknown {
1315 kind: 12,
1316 data: &[1, 2, 3][..]
1317 },
1318 &[0x0c, 0x05, 0x01, 0x02, 0x03]
1319 )
1320 }
1321
1322 #[test]
1323 fn test_malformed_tcp_options() {
1324 assert_eq!(TcpOption::parse(&[]), Err(Error));
1325 assert_eq!(TcpOption::parse(&[0xc]), Err(Error));
1326 assert_eq!(TcpOption::parse(&[0xc, 0x05, 0x01, 0x02]), Err(Error));
1327 assert_eq!(TcpOption::parse(&[0xc, 0x01]), Err(Error));
1328 assert_eq!(TcpOption::parse(&[0x2, 0x02]), Err(Error));
1329 assert_eq!(TcpOption::parse(&[0x3, 0x02]), Err(Error));
1330 }
1331}