tcp.rs 43 KB

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