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