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