smoltcp/wire/
tcp.rs

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/// 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    pub const OPT_TSTAMP: u8 = 0x08;
135}
136
137pub const HEADER_LEN: usize = field::URGENT.end;
138
139impl<T: AsRef<[u8]>> Packet<T> {
140    /// Imbue a raw octet buffer with TCP packet structure.
141    pub const fn new_unchecked(buffer: T) -> Packet<T> {
142        Packet { buffer }
143    }
144
145    /// Shorthand for a combination of [new_unchecked] and [check_len].
146    ///
147    /// [new_unchecked]: #method.new_unchecked
148    /// [check_len]: #method.check_len
149    pub fn new_checked(buffer: T) -> Result<Packet<T>> {
150        let packet = Self::new_unchecked(buffer);
151        packet.check_len()?;
152        Ok(packet)
153    }
154
155    /// Ensure that no accessor method will panic if called.
156    /// Returns `Err(Error)` if the buffer is too short.
157    /// Returns `Err(Error)` if the header length field has a value smaller
158    /// than the minimal header length.
159    ///
160    /// The result of this check is invalidated by calling [set_header_len].
161    ///
162    /// [set_header_len]: #method.set_header_len
163    pub fn check_len(&self) -> Result<()> {
164        let len = self.buffer.as_ref().len();
165        if len < field::URGENT.end {
166            Err(Error)
167        } else {
168            let header_len = self.header_len() as usize;
169            if len < header_len || header_len < field::URGENT.end {
170                Err(Error)
171            } else {
172                Ok(())
173            }
174        }
175    }
176
177    /// Consume the packet, returning the underlying buffer.
178    pub fn into_inner(self) -> T {
179        self.buffer
180    }
181
182    /// Return the source port field.
183    #[inline]
184    pub fn src_port(&self) -> u16 {
185        let data = self.buffer.as_ref();
186        NetworkEndian::read_u16(&data[field::SRC_PORT])
187    }
188
189    /// Return the destination port field.
190    #[inline]
191    pub fn dst_port(&self) -> u16 {
192        let data = self.buffer.as_ref();
193        NetworkEndian::read_u16(&data[field::DST_PORT])
194    }
195
196    /// Return the sequence number field.
197    #[inline]
198    pub fn seq_number(&self) -> SeqNumber {
199        let data = self.buffer.as_ref();
200        SeqNumber(NetworkEndian::read_i32(&data[field::SEQ_NUM]))
201    }
202
203    /// Return the acknowledgement number field.
204    #[inline]
205    pub fn ack_number(&self) -> SeqNumber {
206        let data = self.buffer.as_ref();
207        SeqNumber(NetworkEndian::read_i32(&data[field::ACK_NUM]))
208    }
209
210    /// Return the FIN flag.
211    #[inline]
212    pub fn fin(&self) -> bool {
213        let data = self.buffer.as_ref();
214        let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
215        raw & field::FLG_FIN != 0
216    }
217
218    /// Return the SYN flag.
219    #[inline]
220    pub fn syn(&self) -> bool {
221        let data = self.buffer.as_ref();
222        let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
223        raw & field::FLG_SYN != 0
224    }
225
226    /// Return the RST flag.
227    #[inline]
228    pub fn rst(&self) -> bool {
229        let data = self.buffer.as_ref();
230        let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
231        raw & field::FLG_RST != 0
232    }
233
234    /// Return the PSH flag.
235    #[inline]
236    pub fn psh(&self) -> bool {
237        let data = self.buffer.as_ref();
238        let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
239        raw & field::FLG_PSH != 0
240    }
241
242    /// Return the ACK flag.
243    #[inline]
244    pub fn ack(&self) -> bool {
245        let data = self.buffer.as_ref();
246        let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
247        raw & field::FLG_ACK != 0
248    }
249
250    /// Return the URG flag.
251    #[inline]
252    pub fn urg(&self) -> bool {
253        let data = self.buffer.as_ref();
254        let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
255        raw & field::FLG_URG != 0
256    }
257
258    /// Return the ECE flag.
259    #[inline]
260    pub fn ece(&self) -> bool {
261        let data = self.buffer.as_ref();
262        let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
263        raw & field::FLG_ECE != 0
264    }
265
266    /// Return the CWR flag.
267    #[inline]
268    pub fn cwr(&self) -> bool {
269        let data = self.buffer.as_ref();
270        let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
271        raw & field::FLG_CWR != 0
272    }
273
274    /// Return the NS flag.
275    #[inline]
276    pub fn ns(&self) -> bool {
277        let data = self.buffer.as_ref();
278        let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
279        raw & field::FLG_NS != 0
280    }
281
282    /// Return the header length, in octets.
283    #[inline]
284    pub fn header_len(&self) -> u8 {
285        let data = self.buffer.as_ref();
286        let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
287        ((raw >> 12) * 4) as u8
288    }
289
290    /// Return the window size field.
291    #[inline]
292    pub fn window_len(&self) -> u16 {
293        let data = self.buffer.as_ref();
294        NetworkEndian::read_u16(&data[field::WIN_SIZE])
295    }
296
297    /// Return the checksum field.
298    #[inline]
299    pub fn checksum(&self) -> u16 {
300        let data = self.buffer.as_ref();
301        NetworkEndian::read_u16(&data[field::CHECKSUM])
302    }
303
304    /// Return the urgent pointer field.
305    #[inline]
306    pub fn urgent_at(&self) -> u16 {
307        let data = self.buffer.as_ref();
308        NetworkEndian::read_u16(&data[field::URGENT])
309    }
310
311    /// Return the length of the segment, in terms of sequence space.
312    pub fn segment_len(&self) -> usize {
313        let data = self.buffer.as_ref();
314        let mut length = data.len() - self.header_len() as usize;
315        if self.syn() {
316            length += 1
317        }
318        if self.fin() {
319            length += 1
320        }
321        length
322    }
323
324    /// Returns whether the selective acknowledgement SYN flag is set or not.
325    pub fn selective_ack_permitted(&self) -> Result<bool> {
326        let data = self.buffer.as_ref();
327        let mut options = &data[field::OPTIONS(self.header_len())];
328        while !options.is_empty() {
329            let (next_options, option) = TcpOption::parse(options)?;
330            if option == TcpOption::SackPermitted {
331                return Ok(true);
332            }
333            options = next_options;
334        }
335        Ok(false)
336    }
337
338    /// Return the selective acknowledgement ranges, if any. If there are none in the packet, an
339    /// array of ``None`` values will be returned.
340    ///
341    pub fn selective_ack_ranges(&self) -> Result<[Option<(u32, u32)>; 3]> {
342        let data = self.buffer.as_ref();
343        let mut options = &data[field::OPTIONS(self.header_len())];
344        while !options.is_empty() {
345            let (next_options, option) = TcpOption::parse(options)?;
346            if let TcpOption::SackRange(slice) = option {
347                return Ok(slice);
348            }
349            options = next_options;
350        }
351        Ok([None, None, None])
352    }
353
354    /// Validate the packet checksum.
355    ///
356    /// # Panics
357    /// This function panics unless `src_addr` and `dst_addr` belong to the same family,
358    /// and that family is IPv4 or IPv6.
359    ///
360    /// # Fuzzing
361    /// This function always returns `true` when fuzzing.
362    pub fn verify_checksum(&self, src_addr: &IpAddress, dst_addr: &IpAddress) -> bool {
363        if cfg!(fuzzing) {
364            return true;
365        }
366
367        let data = self.buffer.as_ref();
368        checksum::combine(&[
369            checksum::pseudo_header(src_addr, dst_addr, IpProtocol::Tcp, data.len() as u32),
370            checksum::data(data),
371        ]) == !0
372    }
373}
374
375impl<'a, T: AsRef<[u8]> + ?Sized> Packet<&'a T> {
376    /// Return a pointer to the options.
377    #[inline]
378    pub fn options(&self) -> &'a [u8] {
379        let header_len = self.header_len();
380        let data = self.buffer.as_ref();
381        &data[field::OPTIONS(header_len)]
382    }
383
384    /// Return a pointer to the payload.
385    #[inline]
386    pub fn payload(&self) -> &'a [u8] {
387        let header_len = self.header_len() as usize;
388        let data = self.buffer.as_ref();
389        &data[header_len..]
390    }
391}
392
393impl<T: AsRef<[u8]> + AsMut<[u8]>> Packet<T> {
394    /// Set the source port field.
395    #[inline]
396    pub fn set_src_port(&mut self, value: u16) {
397        let data = self.buffer.as_mut();
398        NetworkEndian::write_u16(&mut data[field::SRC_PORT], value)
399    }
400
401    /// Set the destination port field.
402    #[inline]
403    pub fn set_dst_port(&mut self, value: u16) {
404        let data = self.buffer.as_mut();
405        NetworkEndian::write_u16(&mut data[field::DST_PORT], value)
406    }
407
408    /// Set the sequence number field.
409    #[inline]
410    pub fn set_seq_number(&mut self, value: SeqNumber) {
411        let data = self.buffer.as_mut();
412        NetworkEndian::write_i32(&mut data[field::SEQ_NUM], value.0)
413    }
414
415    /// Set the acknowledgement number field.
416    #[inline]
417    pub fn set_ack_number(&mut self, value: SeqNumber) {
418        let data = self.buffer.as_mut();
419        NetworkEndian::write_i32(&mut data[field::ACK_NUM], value.0)
420    }
421
422    /// Clear the entire flags field.
423    #[inline]
424    pub fn clear_flags(&mut self) {
425        let data = self.buffer.as_mut();
426        let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
427        let raw = raw & !0x0fff;
428        NetworkEndian::write_u16(&mut data[field::FLAGS], raw)
429    }
430
431    /// Set the FIN flag.
432    #[inline]
433    pub fn set_fin(&mut self, value: bool) {
434        let data = self.buffer.as_mut();
435        let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
436        let raw = if value {
437            raw | field::FLG_FIN
438        } else {
439            raw & !field::FLG_FIN
440        };
441        NetworkEndian::write_u16(&mut data[field::FLAGS], raw)
442    }
443
444    /// Set the SYN flag.
445    #[inline]
446    pub fn set_syn(&mut self, value: bool) {
447        let data = self.buffer.as_mut();
448        let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
449        let raw = if value {
450            raw | field::FLG_SYN
451        } else {
452            raw & !field::FLG_SYN
453        };
454        NetworkEndian::write_u16(&mut data[field::FLAGS], raw)
455    }
456
457    /// Set the RST flag.
458    #[inline]
459    pub fn set_rst(&mut self, value: bool) {
460        let data = self.buffer.as_mut();
461        let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
462        let raw = if value {
463            raw | field::FLG_RST
464        } else {
465            raw & !field::FLG_RST
466        };
467        NetworkEndian::write_u16(&mut data[field::FLAGS], raw)
468    }
469
470    /// Set the PSH flag.
471    #[inline]
472    pub fn set_psh(&mut self, value: bool) {
473        let data = self.buffer.as_mut();
474        let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
475        let raw = if value {
476            raw | field::FLG_PSH
477        } else {
478            raw & !field::FLG_PSH
479        };
480        NetworkEndian::write_u16(&mut data[field::FLAGS], raw)
481    }
482
483    /// Set the ACK flag.
484    #[inline]
485    pub fn set_ack(&mut self, value: bool) {
486        let data = self.buffer.as_mut();
487        let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
488        let raw = if value {
489            raw | field::FLG_ACK
490        } else {
491            raw & !field::FLG_ACK
492        };
493        NetworkEndian::write_u16(&mut data[field::FLAGS], raw)
494    }
495
496    /// Set the URG flag.
497    #[inline]
498    pub fn set_urg(&mut self, value: bool) {
499        let data = self.buffer.as_mut();
500        let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
501        let raw = if value {
502            raw | field::FLG_URG
503        } else {
504            raw & !field::FLG_URG
505        };
506        NetworkEndian::write_u16(&mut data[field::FLAGS], raw)
507    }
508
509    /// Set the ECE flag.
510    #[inline]
511    pub fn set_ece(&mut self, value: bool) {
512        let data = self.buffer.as_mut();
513        let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
514        let raw = if value {
515            raw | field::FLG_ECE
516        } else {
517            raw & !field::FLG_ECE
518        };
519        NetworkEndian::write_u16(&mut data[field::FLAGS], raw)
520    }
521
522    /// Set the CWR flag.
523    #[inline]
524    pub fn set_cwr(&mut self, value: bool) {
525        let data = self.buffer.as_mut();
526        let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
527        let raw = if value {
528            raw | field::FLG_CWR
529        } else {
530            raw & !field::FLG_CWR
531        };
532        NetworkEndian::write_u16(&mut data[field::FLAGS], raw)
533    }
534
535    /// Set the NS flag.
536    #[inline]
537    pub fn set_ns(&mut self, value: bool) {
538        let data = self.buffer.as_mut();
539        let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
540        let raw = if value {
541            raw | field::FLG_NS
542        } else {
543            raw & !field::FLG_NS
544        };
545        NetworkEndian::write_u16(&mut data[field::FLAGS], raw)
546    }
547
548    /// Set the header length, in octets.
549    #[inline]
550    pub fn set_header_len(&mut self, value: u8) {
551        let data = self.buffer.as_mut();
552        let raw = NetworkEndian::read_u16(&data[field::FLAGS]);
553        let raw = (raw & !0xf000) | ((value as u16) / 4) << 12;
554        NetworkEndian::write_u16(&mut data[field::FLAGS], raw)
555    }
556
557    /// Set the window size field.
558    #[inline]
559    pub fn set_window_len(&mut self, value: u16) {
560        let data = self.buffer.as_mut();
561        NetworkEndian::write_u16(&mut data[field::WIN_SIZE], value)
562    }
563
564    /// Set the checksum field.
565    #[inline]
566    pub fn set_checksum(&mut self, value: u16) {
567        let data = self.buffer.as_mut();
568        NetworkEndian::write_u16(&mut data[field::CHECKSUM], value)
569    }
570
571    /// Set the urgent pointer field.
572    #[inline]
573    pub fn set_urgent_at(&mut self, value: u16) {
574        let data = self.buffer.as_mut();
575        NetworkEndian::write_u16(&mut data[field::URGENT], value)
576    }
577
578    /// Compute and fill in the header checksum.
579    ///
580    /// # Panics
581    /// This function panics unless `src_addr` and `dst_addr` belong to the same family,
582    /// and that family is IPv4 or IPv6.
583    pub fn fill_checksum(&mut self, src_addr: &IpAddress, dst_addr: &IpAddress) {
584        self.set_checksum(0);
585        let checksum = {
586            let data = self.buffer.as_ref();
587            !checksum::combine(&[
588                checksum::pseudo_header(src_addr, dst_addr, IpProtocol::Tcp, data.len() as u32),
589                checksum::data(data),
590            ])
591        };
592        self.set_checksum(checksum)
593    }
594
595    /// Return a pointer to the options.
596    #[inline]
597    pub fn options_mut(&mut self) -> &mut [u8] {
598        let header_len = self.header_len();
599        let data = self.buffer.as_mut();
600        &mut data[field::OPTIONS(header_len)]
601    }
602
603    /// Return a mutable pointer to the payload data.
604    #[inline]
605    pub fn payload_mut(&mut self) -> &mut [u8] {
606        let header_len = self.header_len() as usize;
607        let data = self.buffer.as_mut();
608        &mut data[header_len..]
609    }
610}
611
612impl<T: AsRef<[u8]>> AsRef<[u8]> for Packet<T> {
613    fn as_ref(&self) -> &[u8] {
614        self.buffer.as_ref()
615    }
616}
617
618/// A representation of a single TCP option.
619#[derive(Debug, PartialEq, Eq, Clone, Copy)]
620#[cfg_attr(feature = "defmt", derive(defmt::Format))]
621pub enum TcpOption<'a> {
622    EndOfList,
623    NoOperation,
624    MaxSegmentSize(u16),
625    WindowScale(u8),
626    SackPermitted,
627    SackRange([Option<(u32, u32)>; 3]),
628    TimeStamp { tsval: u32, tsecr: u32 },
629    Unknown { kind: u8, data: &'a [u8] },
630}
631
632impl<'a> TcpOption<'a> {
633    pub fn parse(buffer: &'a [u8]) -> Result<(&'a [u8], TcpOption<'a>)> {
634        let (length, option);
635        match *buffer.first().ok_or(Error)? {
636            field::OPT_END => {
637                length = 1;
638                option = TcpOption::EndOfList;
639            }
640            field::OPT_NOP => {
641                length = 1;
642                option = TcpOption::NoOperation;
643            }
644            kind => {
645                length = *buffer.get(1).ok_or(Error)? as usize;
646                let data = buffer.get(2..length).ok_or(Error)?;
647                match (kind, length) {
648                    (field::OPT_END, _) | (field::OPT_NOP, _) => unreachable!(),
649                    (field::OPT_MSS, 4) => {
650                        option = TcpOption::MaxSegmentSize(NetworkEndian::read_u16(data))
651                    }
652                    (field::OPT_MSS, _) => return Err(Error),
653                    (field::OPT_WS, 3) => option = TcpOption::WindowScale(data[0]),
654                    (field::OPT_WS, _) => return Err(Error),
655                    (field::OPT_SACKPERM, 2) => option = TcpOption::SackPermitted,
656                    (field::OPT_SACKPERM, _) => return Err(Error),
657                    (field::OPT_SACKRNG, n) => {
658                        if n < 10 || (n - 2) % 8 != 0 {
659                            return Err(Error);
660                        }
661                        if n > 26 {
662                            // It's possible for a remote to send 4 SACK blocks, but extremely rare.
663                            // Better to "lose" that 4th block and save the extra RAM and CPU
664                            // cycles in the vastly more common case.
665                            //
666                            // RFC 2018: SACK option that specifies n blocks will have a length of
667                            // 8*n+2 bytes, so the 40 bytes available for TCP options can specify a
668                            // maximum of 4 blocks.  It is expected that SACK will often be used in
669                            // conjunction with the Timestamp option used for RTTM [...] thus a
670                            // maximum of 3 SACK blocks will be allowed in this case.
671                            net_debug!("sACK with >3 blocks, truncating to 3");
672                        }
673                        let mut sack_ranges: [Option<(u32, u32)>; 3] = [None; 3];
674
675                        // RFC 2018: Each contiguous block of data queued at the data receiver is
676                        // defined in the SACK option by two 32-bit unsigned integers in network
677                        // byte order[...]
678                        sack_ranges.iter_mut().enumerate().for_each(|(i, nmut)| {
679                            let left = i * 8;
680                            *nmut = if left < data.len() {
681                                let mid = left + 4;
682                                let right = mid + 4;
683                                let range_left = NetworkEndian::read_u32(&data[left..mid]);
684                                let range_right = NetworkEndian::read_u32(&data[mid..right]);
685                                Some((range_left, range_right))
686                            } else {
687                                None
688                            };
689                        });
690                        option = TcpOption::SackRange(sack_ranges);
691                    }
692                    (field::OPT_TSTAMP, 10) => {
693                        let tsval = NetworkEndian::read_u32(&data[0..4]);
694                        let tsecr = NetworkEndian::read_u32(&data[4..8]);
695                        option = TcpOption::TimeStamp { tsval, tsecr };
696                    }
697                    (_, _) => option = TcpOption::Unknown { kind, data },
698                }
699            }
700        }
701        Ok((&buffer[length..], option))
702    }
703
704    pub fn buffer_len(&self) -> usize {
705        match *self {
706            TcpOption::EndOfList => 1,
707            TcpOption::NoOperation => 1,
708            TcpOption::MaxSegmentSize(_) => 4,
709            TcpOption::WindowScale(_) => 3,
710            TcpOption::SackPermitted => 2,
711            TcpOption::SackRange(s) => s.iter().filter(|s| s.is_some()).count() * 8 + 2,
712            TcpOption::TimeStamp { tsval: _, tsecr: _ } => 10,
713            TcpOption::Unknown { data, .. } => 2 + data.len(),
714        }
715    }
716
717    pub fn emit<'b>(&self, buffer: &'b mut [u8]) -> &'b mut [u8] {
718        let length;
719        match *self {
720            TcpOption::EndOfList => {
721                length = 1;
722                // There may be padding space which also should be initialized.
723                for p in buffer.iter_mut() {
724                    *p = field::OPT_END;
725                }
726            }
727            TcpOption::NoOperation => {
728                length = 1;
729                buffer[0] = field::OPT_NOP;
730            }
731            _ => {
732                length = self.buffer_len();
733                buffer[1] = length as u8;
734                match self {
735                    &TcpOption::EndOfList | &TcpOption::NoOperation => unreachable!(),
736                    &TcpOption::MaxSegmentSize(value) => {
737                        buffer[0] = field::OPT_MSS;
738                        NetworkEndian::write_u16(&mut buffer[2..], value)
739                    }
740                    &TcpOption::WindowScale(value) => {
741                        buffer[0] = field::OPT_WS;
742                        buffer[2] = value;
743                    }
744                    &TcpOption::SackPermitted => {
745                        buffer[0] = field::OPT_SACKPERM;
746                    }
747                    &TcpOption::SackRange(slice) => {
748                        buffer[0] = field::OPT_SACKRNG;
749                        slice
750                            .iter()
751                            .filter(|s| s.is_some())
752                            .enumerate()
753                            .for_each(|(i, s)| {
754                                let (first, second) = *s.as_ref().unwrap();
755                                let pos = i * 8 + 2;
756                                NetworkEndian::write_u32(&mut buffer[pos..], first);
757                                NetworkEndian::write_u32(&mut buffer[pos + 4..], second);
758                            });
759                    }
760                    &TcpOption::TimeStamp { tsval, tsecr } => {
761                        buffer[0] = field::OPT_TSTAMP;
762                        NetworkEndian::write_u32(&mut buffer[2..], tsval);
763                        NetworkEndian::write_u32(&mut buffer[6..], tsecr);
764                    }
765                    &TcpOption::Unknown {
766                        kind,
767                        data: provided,
768                    } => {
769                        buffer[0] = kind;
770                        buffer[2..].copy_from_slice(provided)
771                    }
772                }
773            }
774        }
775        &mut buffer[length..]
776    }
777}
778
779/// The possible control flags of a Transmission Control Protocol packet.
780#[derive(Debug, PartialEq, Eq, Clone, Copy)]
781#[cfg_attr(feature = "defmt", derive(defmt::Format))]
782pub enum Control {
783    None,
784    Psh,
785    Syn,
786    Fin,
787    Rst,
788}
789
790#[allow(clippy::len_without_is_empty)]
791impl Control {
792    /// Return the length of a control flag, in terms of sequence space.
793    pub const fn len(self) -> usize {
794        match self {
795            Control::Syn | Control::Fin => 1,
796            _ => 0,
797        }
798    }
799
800    /// Turn the PSH flag into no flag, and keep the rest as-is.
801    pub const fn quash_psh(self) -> Control {
802        match self {
803            Control::Psh => Control::None,
804            _ => self,
805        }
806    }
807}
808
809/// A high-level representation of a Transmission Control Protocol packet.
810#[derive(Debug, PartialEq, Eq, Clone, Copy)]
811pub struct Repr<'a> {
812    pub src_port: u16,
813    pub dst_port: u16,
814    pub control: Control,
815    pub seq_number: SeqNumber,
816    pub ack_number: Option<SeqNumber>,
817    pub window_len: u16,
818    pub window_scale: Option<u8>,
819    pub max_seg_size: Option<u16>,
820    pub sack_permitted: bool,
821    pub sack_ranges: [Option<(u32, u32)>; 3],
822    pub timestamp: Option<TcpTimestampRepr>,
823    pub payload: &'a [u8],
824}
825
826pub type TcpTimestampGenerator = fn() -> u32;
827
828#[derive(Debug, PartialEq, Eq, Clone, Copy)]
829pub struct TcpTimestampRepr {
830    pub tsval: u32,
831    pub tsecr: u32,
832}
833
834impl TcpTimestampRepr {
835    pub fn new(tsval: u32, tsecr: u32) -> Self {
836        Self { tsval, tsecr }
837    }
838
839    pub fn generate_reply(&self, generator: Option<TcpTimestampGenerator>) -> Option<Self> {
840        Self::generate_reply_with_tsval(generator, self.tsval)
841    }
842
843    pub fn generate_reply_with_tsval(
844        generator: Option<TcpTimestampGenerator>,
845        tsval: u32,
846    ) -> Option<Self> {
847        Some(Self::new(generator?(), tsval))
848    }
849}
850
851impl<'a> Repr<'a> {
852    /// Parse a Transmission Control Protocol packet and return a high-level representation.
853    pub fn parse<T>(
854        packet: &Packet<&'a T>,
855        src_addr: &IpAddress,
856        dst_addr: &IpAddress,
857        checksum_caps: &ChecksumCapabilities,
858    ) -> Result<Repr<'a>>
859    where
860        T: AsRef<[u8]> + ?Sized,
861    {
862        packet.check_len()?;
863
864        // Source and destination ports must be present.
865        if packet.src_port() == 0 {
866            return Err(Error);
867        }
868        if packet.dst_port() == 0 {
869            return Err(Error);
870        }
871        // Valid checksum is expected.
872        if checksum_caps.tcp.rx() && !packet.verify_checksum(src_addr, dst_addr) {
873            return Err(Error);
874        }
875
876        let control = match (packet.syn(), packet.fin(), packet.rst(), packet.psh()) {
877            (false, false, false, false) => Control::None,
878            (false, false, false, true) => Control::Psh,
879            (true, false, false, _) => Control::Syn,
880            (false, true, false, _) => Control::Fin,
881            (false, false, true, _) => Control::Rst,
882            _ => return Err(Error),
883        };
884        let ack_number = match packet.ack() {
885            true => Some(packet.ack_number()),
886            false => None,
887        };
888        // The PSH flag is ignored.
889        // The URG flag and the urgent field is ignored. This behavior is standards-compliant,
890        // however, most deployed systems (e.g. Linux) are *not* standards-compliant, and would
891        // cut the byte at the urgent pointer from the stream.
892
893        let mut max_seg_size = None;
894        let mut window_scale = None;
895        let mut options = packet.options();
896        let mut sack_permitted = false;
897        let mut sack_ranges = [None, None, None];
898        let mut timestamp = None;
899        while !options.is_empty() {
900            let (next_options, option) = TcpOption::parse(options)?;
901            match option {
902                TcpOption::EndOfList => break,
903                TcpOption::NoOperation => (),
904                TcpOption::MaxSegmentSize(value) => max_seg_size = Some(value),
905                TcpOption::WindowScale(value) => {
906                    // RFC 1323: Thus, the shift count must be limited to 14 (which allows windows
907                    // of 2**30 = 1 Gigabyte). If a Window Scale option is received with a shift.cnt
908                    // value exceeding 14, the TCP should log the error but use 14 instead of the
909                    // specified value.
910                    window_scale = if value > 14 {
911                        net_debug!(
912                            "{}:{}:{}:{}: parsed window scaling factor >14, setting to 14",
913                            src_addr,
914                            packet.src_port(),
915                            dst_addr,
916                            packet.dst_port()
917                        );
918                        Some(14)
919                    } else {
920                        Some(value)
921                    };
922                }
923                TcpOption::SackPermitted => sack_permitted = true,
924                TcpOption::SackRange(slice) => sack_ranges = slice,
925                TcpOption::TimeStamp { tsval, tsecr } => {
926                    timestamp = Some(TcpTimestampRepr::new(tsval, tsecr));
927                }
928                _ => (),
929            }
930            options = next_options;
931        }
932
933        Ok(Repr {
934            src_port: packet.src_port(),
935            dst_port: packet.dst_port(),
936            control: control,
937            seq_number: packet.seq_number(),
938            ack_number: ack_number,
939            window_len: packet.window_len(),
940            window_scale: window_scale,
941            max_seg_size: max_seg_size,
942            sack_permitted: sack_permitted,
943            sack_ranges: sack_ranges,
944            timestamp: timestamp,
945            payload: packet.payload(),
946        })
947    }
948
949    /// Return the length of a header that will be emitted from this high-level representation.
950    ///
951    /// This should be used for buffer space calculations.
952    /// The TCP header length is a multiple of 4.
953    pub fn header_len(&self) -> usize {
954        let mut length = field::URGENT.end;
955        if self.max_seg_size.is_some() {
956            length += 4
957        }
958        if self.window_scale.is_some() {
959            length += 3
960        }
961        if self.sack_permitted {
962            length += 2;
963        }
964        if self.timestamp.is_some() {
965            length += 10;
966        }
967        let sack_range_len: usize = self
968            .sack_ranges
969            .iter()
970            .map(|o| o.map(|_| 8).unwrap_or(0))
971            .sum();
972        if sack_range_len > 0 {
973            length += sack_range_len + 2;
974        }
975        if length % 4 != 0 {
976            length += 4 - length % 4;
977        }
978        length
979    }
980
981    /// Return the length of a packet that will be emitted from this high-level representation.
982    pub fn buffer_len(&self) -> usize {
983        self.header_len() + self.payload.len()
984    }
985
986    /// Emit a high-level representation into a Transmission Control Protocol packet.
987    pub fn emit<T>(
988        &self,
989        packet: &mut Packet<&mut T>,
990        src_addr: &IpAddress,
991        dst_addr: &IpAddress,
992        checksum_caps: &ChecksumCapabilities,
993    ) where
994        T: AsRef<[u8]> + AsMut<[u8]> + ?Sized,
995    {
996        packet.set_src_port(self.src_port);
997        packet.set_dst_port(self.dst_port);
998        packet.set_seq_number(self.seq_number);
999        packet.set_ack_number(self.ack_number.unwrap_or(SeqNumber(0)));
1000        packet.set_window_len(self.window_len);
1001        packet.set_header_len(self.header_len() as u8);
1002        packet.clear_flags();
1003        match self.control {
1004            Control::None => (),
1005            Control::Psh => packet.set_psh(true),
1006            Control::Syn => packet.set_syn(true),
1007            Control::Fin => packet.set_fin(true),
1008            Control::Rst => packet.set_rst(true),
1009        }
1010        packet.set_ack(self.ack_number.is_some());
1011        {
1012            let mut options = packet.options_mut();
1013            if let Some(value) = self.max_seg_size {
1014                let tmp = options;
1015                options = TcpOption::MaxSegmentSize(value).emit(tmp);
1016            }
1017            if let Some(value) = self.window_scale {
1018                let tmp = options;
1019                options = TcpOption::WindowScale(value).emit(tmp);
1020            }
1021            if self.sack_permitted {
1022                let tmp = options;
1023                options = TcpOption::SackPermitted.emit(tmp);
1024            } else if self.ack_number.is_some() && self.sack_ranges.iter().any(|s| s.is_some()) {
1025                let tmp = options;
1026                options = TcpOption::SackRange(self.sack_ranges).emit(tmp);
1027            }
1028            if let Some(timestamp) = self.timestamp {
1029                let tmp = options;
1030                options = TcpOption::TimeStamp {
1031                    tsval: timestamp.tsval,
1032                    tsecr: timestamp.tsecr,
1033                }
1034                .emit(tmp);
1035            }
1036
1037            if !options.is_empty() {
1038                TcpOption::EndOfList.emit(options);
1039            }
1040        }
1041        packet.set_urgent_at(0);
1042        packet.payload_mut()[..self.payload.len()].copy_from_slice(self.payload);
1043
1044        if checksum_caps.tcp.tx() {
1045            packet.fill_checksum(src_addr, dst_addr)
1046        } else {
1047            // make sure we get a consistently zeroed checksum,
1048            // since implementations might rely on it
1049            packet.set_checksum(0);
1050        }
1051    }
1052
1053    /// Return the length of the segment, in terms of sequence space.
1054    pub const fn segment_len(&self) -> usize {
1055        self.payload.len() + self.control.len()
1056    }
1057
1058    /// Return whether the segment has no flags set (except PSH) and no data.
1059    pub const fn is_empty(&self) -> bool {
1060        match self.control {
1061            _ if !self.payload.is_empty() => false,
1062            Control::Syn | Control::Fin | Control::Rst => false,
1063            Control::None | Control::Psh => true,
1064        }
1065    }
1066}
1067
1068impl<'a, T: AsRef<[u8]> + ?Sized> fmt::Display for Packet<&'a T> {
1069    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1070        // Cannot use Repr::parse because we don't have the IP addresses.
1071        write!(f, "TCP src={} dst={}", self.src_port(), self.dst_port())?;
1072        if self.syn() {
1073            write!(f, " syn")?
1074        }
1075        if self.fin() {
1076            write!(f, " fin")?
1077        }
1078        if self.rst() {
1079            write!(f, " rst")?
1080        }
1081        if self.psh() {
1082            write!(f, " psh")?
1083        }
1084        if self.ece() {
1085            write!(f, " ece")?
1086        }
1087        if self.cwr() {
1088            write!(f, " cwr")?
1089        }
1090        if self.ns() {
1091            write!(f, " ns")?
1092        }
1093        write!(f, " seq={}", self.seq_number())?;
1094        if self.ack() {
1095            write!(f, " ack={}", self.ack_number())?;
1096        }
1097        write!(f, " win={}", self.window_len())?;
1098        if self.urg() {
1099            write!(f, " urg={}", self.urgent_at())?;
1100        }
1101        write!(f, " len={}", self.payload().len())?;
1102
1103        let mut options = self.options();
1104        while !options.is_empty() {
1105            let (next_options, option) = match TcpOption::parse(options) {
1106                Ok(res) => res,
1107                Err(err) => return write!(f, " ({err})"),
1108            };
1109            match option {
1110                TcpOption::EndOfList => break,
1111                TcpOption::NoOperation => (),
1112                TcpOption::MaxSegmentSize(value) => write!(f, " mss={value}")?,
1113                TcpOption::WindowScale(value) => write!(f, " ws={value}")?,
1114                TcpOption::SackPermitted => write!(f, " sACK")?,
1115                TcpOption::SackRange(slice) => write!(f, " sACKr{slice:?}")?, // debug print conveniently includes the []s
1116                TcpOption::TimeStamp { tsval, tsecr } => {
1117                    write!(f, " tsval {tsval:08x} tsecr {tsecr:08x}")?
1118                }
1119                TcpOption::Unknown { kind, .. } => write!(f, " opt({kind})")?,
1120            }
1121            options = next_options;
1122        }
1123        Ok(())
1124    }
1125}
1126
1127impl<'a> fmt::Display for Repr<'a> {
1128    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1129        write!(f, "TCP src={} dst={}", self.src_port, self.dst_port)?;
1130        match self.control {
1131            Control::Syn => write!(f, " syn")?,
1132            Control::Fin => write!(f, " fin")?,
1133            Control::Rst => write!(f, " rst")?,
1134            Control::Psh => write!(f, " psh")?,
1135            Control::None => (),
1136        }
1137        write!(f, " seq={}", self.seq_number)?;
1138        if let Some(ack_number) = self.ack_number {
1139            write!(f, " ack={ack_number}")?;
1140        }
1141        write!(f, " win={}", self.window_len)?;
1142        write!(f, " len={}", self.payload.len())?;
1143        if let Some(max_seg_size) = self.max_seg_size {
1144            write!(f, " mss={max_seg_size}")?;
1145        }
1146        Ok(())
1147    }
1148}
1149
1150#[cfg(feature = "defmt")]
1151impl<'a> defmt::Format for Repr<'a> {
1152    fn format(&self, fmt: defmt::Formatter) {
1153        defmt::write!(fmt, "TCP src={} dst={}", self.src_port, self.dst_port);
1154        match self.control {
1155            Control::Syn => defmt::write!(fmt, " syn"),
1156            Control::Fin => defmt::write!(fmt, " fin"),
1157            Control::Rst => defmt::write!(fmt, " rst"),
1158            Control::Psh => defmt::write!(fmt, " psh"),
1159            Control::None => (),
1160        }
1161        defmt::write!(fmt, " seq={}", self.seq_number);
1162        if let Some(ack_number) = self.ack_number {
1163            defmt::write!(fmt, " ack={}", ack_number);
1164        }
1165        defmt::write!(fmt, " win={}", self.window_len);
1166        defmt::write!(fmt, " len={}", self.payload.len());
1167        if let Some(max_seg_size) = self.max_seg_size {
1168            defmt::write!(fmt, " mss={}", max_seg_size);
1169        }
1170    }
1171}
1172
1173use crate::wire::pretty_print::{PrettyIndent, PrettyPrint};
1174
1175impl<T: AsRef<[u8]>> PrettyPrint for Packet<T> {
1176    fn pretty_print(
1177        buffer: &dyn AsRef<[u8]>,
1178        f: &mut fmt::Formatter,
1179        indent: &mut PrettyIndent,
1180    ) -> fmt::Result {
1181        match Packet::new_checked(buffer) {
1182            Err(err) => write!(f, "{indent}({err})"),
1183            Ok(packet) => write!(f, "{indent}{packet}"),
1184        }
1185    }
1186}
1187
1188#[cfg(test)]
1189mod test {
1190    use super::*;
1191    #[cfg(feature = "proto-ipv4")]
1192    use crate::wire::Ipv4Address;
1193
1194    #[cfg(feature = "proto-ipv4")]
1195    const SRC_ADDR: Ipv4Address = Ipv4Address::new(192, 168, 1, 1);
1196    #[cfg(feature = "proto-ipv4")]
1197    const DST_ADDR: Ipv4Address = Ipv4Address::new(192, 168, 1, 2);
1198
1199    #[cfg(feature = "proto-ipv4")]
1200    static PACKET_BYTES: [u8; 28] = [
1201        0xbf, 0x00, 0x00, 0x50, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x60, 0x35, 0x01,
1202        0x23, 0x01, 0xb6, 0x02, 0x01, 0x03, 0x03, 0x0c, 0x01, 0xaa, 0x00, 0x00, 0xff,
1203    ];
1204
1205    #[cfg(feature = "proto-ipv4")]
1206    static OPTION_BYTES: [u8; 4] = [0x03, 0x03, 0x0c, 0x01];
1207
1208    #[cfg(feature = "proto-ipv4")]
1209    static PAYLOAD_BYTES: [u8; 4] = [0xaa, 0x00, 0x00, 0xff];
1210
1211    #[test]
1212    #[cfg(feature = "proto-ipv4")]
1213    fn test_deconstruct() {
1214        let packet = Packet::new_unchecked(&PACKET_BYTES[..]);
1215        assert_eq!(packet.src_port(), 48896);
1216        assert_eq!(packet.dst_port(), 80);
1217        assert_eq!(packet.seq_number(), SeqNumber(0x01234567));
1218        assert_eq!(packet.ack_number(), SeqNumber(0x89abcdefu32 as i32));
1219        assert_eq!(packet.header_len(), 24);
1220        assert!(packet.fin());
1221        assert!(!packet.syn());
1222        assert!(packet.rst());
1223        assert!(!packet.psh());
1224        assert!(packet.ack());
1225        assert!(packet.urg());
1226        assert_eq!(packet.window_len(), 0x0123);
1227        assert_eq!(packet.urgent_at(), 0x0201);
1228        assert_eq!(packet.checksum(), 0x01b6);
1229        assert_eq!(packet.options(), &OPTION_BYTES[..]);
1230        assert_eq!(packet.payload(), &PAYLOAD_BYTES[..]);
1231        assert!(packet.verify_checksum(&SRC_ADDR.into(), &DST_ADDR.into()));
1232    }
1233
1234    #[test]
1235    #[cfg(feature = "proto-ipv4")]
1236    fn test_construct() {
1237        let mut bytes = vec![0xa5; PACKET_BYTES.len()];
1238        let mut packet = Packet::new_unchecked(&mut bytes);
1239        packet.set_src_port(48896);
1240        packet.set_dst_port(80);
1241        packet.set_seq_number(SeqNumber(0x01234567));
1242        packet.set_ack_number(SeqNumber(0x89abcdefu32 as i32));
1243        packet.set_header_len(24);
1244        packet.clear_flags();
1245        packet.set_fin(true);
1246        packet.set_syn(false);
1247        packet.set_rst(true);
1248        packet.set_psh(false);
1249        packet.set_ack(true);
1250        packet.set_urg(true);
1251        packet.set_window_len(0x0123);
1252        packet.set_urgent_at(0x0201);
1253        packet.set_checksum(0xEEEE);
1254        packet.options_mut().copy_from_slice(&OPTION_BYTES[..]);
1255        packet.payload_mut().copy_from_slice(&PAYLOAD_BYTES[..]);
1256        packet.fill_checksum(&SRC_ADDR.into(), &DST_ADDR.into());
1257        assert_eq!(&*packet.into_inner(), &PACKET_BYTES[..]);
1258    }
1259
1260    #[test]
1261    #[cfg(feature = "proto-ipv4")]
1262    fn test_truncated() {
1263        let packet = Packet::new_unchecked(&PACKET_BYTES[..23]);
1264        assert_eq!(packet.check_len(), Err(Error));
1265    }
1266
1267    #[test]
1268    fn test_impossible_len() {
1269        let mut bytes = vec![0; 20];
1270        let mut packet = Packet::new_unchecked(&mut bytes);
1271        packet.set_header_len(10);
1272        assert_eq!(packet.check_len(), Err(Error));
1273    }
1274
1275    #[cfg(feature = "proto-ipv4")]
1276    static SYN_PACKET_BYTES: [u8; 24] = [
1277        0xbf, 0x00, 0x00, 0x50, 0x01, 0x23, 0x45, 0x67, 0x00, 0x00, 0x00, 0x00, 0x50, 0x02, 0x01,
1278        0x23, 0x7a, 0x8d, 0x00, 0x00, 0xaa, 0x00, 0x00, 0xff,
1279    ];
1280
1281    #[cfg(feature = "proto-ipv4")]
1282    fn packet_repr() -> Repr<'static> {
1283        Repr {
1284            src_port: 48896,
1285            dst_port: 80,
1286            seq_number: SeqNumber(0x01234567),
1287            ack_number: None,
1288            window_len: 0x0123,
1289            window_scale: None,
1290            control: Control::Syn,
1291            max_seg_size: None,
1292            sack_permitted: false,
1293            sack_ranges: [None, None, None],
1294            timestamp: None,
1295            payload: &PAYLOAD_BYTES,
1296        }
1297    }
1298
1299    #[test]
1300    #[cfg(feature = "proto-ipv4")]
1301    fn test_parse() {
1302        let packet = Packet::new_unchecked(&SYN_PACKET_BYTES[..]);
1303        let repr = Repr::parse(
1304            &packet,
1305            &SRC_ADDR.into(),
1306            &DST_ADDR.into(),
1307            &ChecksumCapabilities::default(),
1308        )
1309        .unwrap();
1310        assert_eq!(repr, packet_repr());
1311    }
1312
1313    #[test]
1314    #[cfg(feature = "proto-ipv4")]
1315    fn test_emit() {
1316        let repr = packet_repr();
1317        let mut bytes = vec![0xa5; repr.buffer_len()];
1318        let mut packet = Packet::new_unchecked(&mut bytes);
1319        repr.emit(
1320            &mut packet,
1321            &SRC_ADDR.into(),
1322            &DST_ADDR.into(),
1323            &ChecksumCapabilities::default(),
1324        );
1325        assert_eq!(&*packet.into_inner(), &SYN_PACKET_BYTES[..]);
1326    }
1327
1328    #[test]
1329    #[cfg(feature = "proto-ipv4")]
1330    fn test_header_len_multiple_of_4() {
1331        let mut repr = packet_repr();
1332        repr.window_scale = Some(0); // This TCP Option needs 3 bytes.
1333        assert_eq!(repr.header_len() % 4, 0); // Should e.g. be 28 instead of 27.
1334    }
1335
1336    macro_rules! assert_option_parses {
1337        ($opt:expr, $data:expr) => {{
1338            assert_eq!(TcpOption::parse($data), Ok((&[][..], $opt)));
1339            let buffer = &mut [0; 40][..$opt.buffer_len()];
1340            assert_eq!($opt.emit(buffer), &mut []);
1341            assert_eq!(&*buffer, $data);
1342        }};
1343    }
1344
1345    #[test]
1346    fn test_tcp_options() {
1347        assert_option_parses!(TcpOption::EndOfList, &[0x00]);
1348        assert_option_parses!(TcpOption::NoOperation, &[0x01]);
1349        assert_option_parses!(TcpOption::MaxSegmentSize(1500), &[0x02, 0x04, 0x05, 0xdc]);
1350        assert_option_parses!(TcpOption::WindowScale(12), &[0x03, 0x03, 0x0c]);
1351        assert_option_parses!(TcpOption::SackPermitted, &[0x4, 0x02]);
1352        assert_option_parses!(
1353            TcpOption::SackRange([Some((500, 1500)), None, None]),
1354            &[0x05, 0x0a, 0x00, 0x00, 0x01, 0xf4, 0x00, 0x00, 0x05, 0xdc]
1355        );
1356        assert_option_parses!(
1357            TcpOption::SackRange([Some((875, 1225)), Some((1500, 2500)), None]),
1358            &[
1359                0x05, 0x12, 0x00, 0x00, 0x03, 0x6b, 0x00, 0x00, 0x04, 0xc9, 0x00, 0x00, 0x05, 0xdc,
1360                0x00, 0x00, 0x09, 0xc4
1361            ]
1362        );
1363        assert_option_parses!(
1364            TcpOption::SackRange([
1365                Some((875000, 1225000)),
1366                Some((1500000, 2500000)),
1367                Some((876543210, 876654320))
1368            ]),
1369            &[
1370                0x05, 0x1a, 0x00, 0x0d, 0x59, 0xf8, 0x00, 0x12, 0xb1, 0x28, 0x00, 0x16, 0xe3, 0x60,
1371                0x00, 0x26, 0x25, 0xa0, 0x34, 0x3e, 0xfc, 0xea, 0x34, 0x40, 0xae, 0xf0
1372            ]
1373        );
1374        assert_option_parses!(
1375            TcpOption::TimeStamp {
1376                tsval: 5000000,
1377                tsecr: 7000000
1378            },
1379            &[
1380                0x08, // data length
1381                0x0a, // type
1382                0x00, 0x4c, 0x4b, 0x40, //tsval
1383                0x00, 0x6a, 0xcf, 0xc0 //tsecr
1384            ]
1385        );
1386        assert_option_parses!(
1387            TcpOption::Unknown {
1388                kind: 12,
1389                data: &[1, 2, 3][..]
1390            },
1391            &[0x0c, 0x05, 0x01, 0x02, 0x03]
1392        )
1393    }
1394
1395    #[test]
1396    fn test_malformed_tcp_options() {
1397        assert_eq!(TcpOption::parse(&[]), Err(Error));
1398        assert_eq!(TcpOption::parse(&[0xc]), Err(Error));
1399        assert_eq!(TcpOption::parse(&[0xc, 0x05, 0x01, 0x02]), Err(Error));
1400        assert_eq!(TcpOption::parse(&[0xc, 0x01]), Err(Error));
1401        assert_eq!(TcpOption::parse(&[0x2, 0x02]), Err(Error));
1402        assert_eq!(TcpOption::parse(&[0x3, 0x02]), Err(Error));
1403    }
1404}