smoltcp/wire/
tcp.rs

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/// A TCP sequence number.
10///
11/// A sequence number is a monotonically advancing integer modulo 2<sup>32</sup>.
12/// Sequence numbers do not have a discontiguity when compared pairwise across a signed overflow.
13#[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/// A read/write wrapper around a Transmission Control Protocol packet buffer.
94#[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    /// Imbue a raw octet buffer with TCP packet structure.
140    pub const fn new_unchecked(buffer: T) -> Packet<T> {
141        Packet { buffer }
142    }
143
144    /// Shorthand for a combination of [new_unchecked] and [check_len].
145    ///
146    /// [new_unchecked]: #method.new_unchecked
147    /// [check_len]: #method.check_len
148    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    /// Ensure that no accessor method will panic if called.
155    /// Returns `Err(Error)` if the buffer is too short.
156    /// Returns `Err(Error)` if the header length field has a value smaller
157    /// than the minimal header length.
158    ///
159    /// The result of this check is invalidated by calling [set_header_len].
160    ///
161    /// [set_header_len]: #method.set_header_len
162    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    /// Consume the packet, returning the underlying buffer.
177    pub fn into_inner(self) -> T {
178        self.buffer
179    }
180
181    /// Return the source port field.
182    #[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    /// Return the destination port field.
189    #[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    /// Return the sequence number field.
196    #[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    /// Return the acknowledgement number field.
203    #[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    /// Return the FIN flag.
210    #[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    /// Return the SYN flag.
218    #[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    /// Return the RST flag.
226    #[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    /// Return the PSH flag.
234    #[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    /// Return the ACK flag.
242    #[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    /// Return the URG flag.
250    #[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    /// Return the ECE flag.
258    #[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    /// Return the CWR flag.
266    #[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    /// Return the NS flag.
274    #[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    /// Return the header length, in octets.
282    #[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    /// Return the window size field.
290    #[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    /// Return the checksum field.
297    #[inline]
298    pub fn checksum(&self) -> u16 {
299        let data = self.buffer.as_ref();
300        NetworkEndian::read_u16(&data[field::CHECKSUM])
301    }
302
303    /// Return the urgent pointer field.
304    #[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    /// Return the length of the segment, in terms of sequence space.
311    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    /// Returns whether the selective acknowledgement SYN flag is set or not.
324    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    /// Return the selective acknowledgement ranges, if any. If there are none in the packet, an
338    /// array of ``None`` values will be returned.
339    ///
340    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    /// Validate the packet checksum.
354    ///
355    /// # Panics
356    /// This function panics unless `src_addr` and `dst_addr` belong to the same family,
357    /// and that family is IPv4 or IPv6.
358    ///
359    /// # Fuzzing
360    /// This function always returns `true` when fuzzing.
361    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    /// Return a pointer to the options.
376    #[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    /// Return a pointer to the payload.
384    #[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    /// Set the source port field.
394    #[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    /// Set the destination port field.
401    #[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    /// Set the sequence number field.
408    #[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    /// Set the acknowledgement number field.
415    #[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    /// Clear the entire flags field.
422    #[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    /// Set the FIN flag.
431    #[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    /// Set the SYN flag.
444    #[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    /// Set the RST flag.
457    #[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    /// Set the PSH flag.
470    #[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    /// Set the ACK flag.
483    #[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    /// Set the URG flag.
496    #[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    /// Set the ECE flag.
509    #[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    /// Set the CWR flag.
522    #[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    /// Set the NS flag.
535    #[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    /// Set the header length, in octets.
548    #[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    /// Set the window size field.
557    #[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    /// Set the checksum field.
564    #[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    /// Set the urgent pointer field.
571    #[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    /// Compute and fill in the header checksum.
578    ///
579    /// # Panics
580    /// This function panics unless `src_addr` and `dst_addr` belong to the same family,
581    /// and that family is IPv4 or IPv6.
582    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    /// Return a pointer to the options.
595    #[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    /// Return a mutable pointer to the payload data.
603    #[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/// A representation of a single TCP option.
618#[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                            // It's possible for a remote to send 4 SACK blocks, but extremely rare.
661                            // Better to "lose" that 4th block and save the extra RAM and CPU
662                            // cycles in the vastly more common case.
663                            //
664                            // RFC 2018: SACK option that specifies n blocks will have a length of
665                            // 8*n+2 bytes, so the 40 bytes available for TCP options can specify a
666                            // maximum of 4 blocks.  It is expected that SACK will often be used in
667                            // conjunction with the Timestamp option used for RTTM [...] thus a
668                            // maximum of 3 SACK blocks will be allowed in this case.
669                            net_debug!("sACK with >3 blocks, truncating to 3");
670                        }
671                        let mut sack_ranges: [Option<(u32, u32)>; 3] = [None; 3];
672
673                        // RFC 2018: Each contiguous block of data queued at the data receiver is
674                        // defined in the SACK option by two 32-bit unsigned integers in network
675                        // byte order[...]
676                        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                // There may be padding space which also should be initialized.
715                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/// The possible control flags of a Transmission Control Protocol packet.
767#[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    /// Return the length of a control flag, in terms of sequence space.
780    pub const fn len(self) -> usize {
781        match self {
782            Control::Syn | Control::Fin => 1,
783            _ => 0,
784        }
785    }
786
787    /// Turn the PSH flag into no flag, and keep the rest as-is.
788    pub const fn quash_psh(self) -> Control {
789        match self {
790            Control::Psh => Control::None,
791            _ => self,
792        }
793    }
794}
795
796/// A high-level representation of a Transmission Control Protocol packet.
797#[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    /// Parse a Transmission Control Protocol packet and return a high-level representation.
814    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        // Source and destination ports must be present.
824        if packet.src_port() == 0 {
825            return Err(Error);
826        }
827        if packet.dst_port() == 0 {
828            return Err(Error);
829        }
830        // Valid checksum is expected.
831        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        // The PSH flag is ignored.
848        // The URG flag and the urgent field is ignored. This behavior is standards-compliant,
849        // however, most deployed systems (e.g. Linux) are *not* standards-compliant, and would
850        // cut the byte at the urgent pointer from the stream.
851
852        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                    // RFC 1323: Thus, the shift count must be limited to 14 (which allows windows
865                    // of 2**30 = 1 Gigabyte). If a Window Scale option is received with a shift.cnt
866                    // value exceeding 14, the TCP should log the error but use 14 instead of the
867                    // specified value.
868                    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    /// Return the length of a header that will be emitted from this high-level representation.
904    ///
905    /// This should be used for buffer space calculations.
906    /// The TCP header length is a multiple of 4.
907    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    /// Return the length of a packet that will be emitted from this high-level representation.
933    pub fn buffer_len(&self) -> usize {
934        self.header_len() + self.payload.len()
935    }
936
937    /// Emit a high-level representation into a Transmission Control Protocol packet.
938    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            // make sure we get a consistently zeroed checksum,
991            // since implementations might rely on it
992            packet.set_checksum(0);
993        }
994    }
995
996    /// Return the length of the segment, in terms of sequence space.
997    pub const fn segment_len(&self) -> usize {
998        self.payload.len() + self.control.len()
999    }
1000
1001    /// Return whether the segment has no flags set (except PSH) and no data.
1002    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        // Cannot use Repr::parse because we don't have the IP addresses.
1014        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:?}")?, // debug print conveniently includes the []s
1059                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); // This TCP Option needs 3 bytes.
1272        assert_eq!(repr.header_len() % 4, 0); // Should e.g. be 28 instead of 27.
1273    }
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}