ipv4.rs 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829
  1. use core::fmt;
  2. use byteorder::{ByteOrder, NetworkEndian};
  3. use {Error, Result};
  4. use phy::ChecksumCapabilities;
  5. use super::ip::{checksum, pretty_print_ip_payload};
  6. pub use super::IpProtocol as Protocol;
  7. /// Minimum MTU required of all links supporting IPv4. See [RFC 791 § 3.1].
  8. ///
  9. /// [RFC 791 § 3.1]: https://tools.ietf.org/html/rfc791#section-3.1
  10. // RFC 791 states the following:
  11. //
  12. // > Every internet module must be able to forward a datagram of 68
  13. // > octets without further fragmentation... Every internet destination
  14. // > must be able to receive a datagram of 576 octets either in one piece
  15. // > or in fragments to be reassembled.
  16. //
  17. // As a result, we can assume that every host we send packets to can
  18. // accept a packet of the following size.
  19. pub const MIN_MTU: usize = 576;
  20. /// A four-octet IPv4 address.
  21. #[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default)]
  22. pub struct Address(pub [u8; 4]);
  23. impl Address {
  24. /// An unspecified address.
  25. pub const UNSPECIFIED: Address = Address([0x00; 4]);
  26. /// The broadcast address.
  27. pub const BROADCAST: Address = Address([0xff; 4]);
  28. /// Construct an IPv4 address from parts.
  29. pub fn new(a0: u8, a1: u8, a2: u8, a3: u8) -> Address {
  30. Address([a0, a1, a2, a3])
  31. }
  32. /// Construct an IPv4 address from a sequence of octets, in big-endian.
  33. ///
  34. /// # Panics
  35. /// The function panics if `data` is not four octets long.
  36. pub fn from_bytes(data: &[u8]) -> Address {
  37. let mut bytes = [0; 4];
  38. bytes.copy_from_slice(data);
  39. Address(bytes)
  40. }
  41. /// Return an IPv4 address as a sequence of octets, in big-endian.
  42. pub fn as_bytes(&self) -> &[u8] {
  43. &self.0
  44. }
  45. /// Query whether the address is an unicast address.
  46. pub fn is_unicast(&self) -> bool {
  47. !(self.is_broadcast() ||
  48. self.is_multicast() ||
  49. self.is_unspecified())
  50. }
  51. /// Query whether the address is the broadcast address.
  52. pub fn is_broadcast(&self) -> bool {
  53. self.0[0..4] == [255; 4]
  54. }
  55. /// Query whether the address is a multicast address.
  56. pub fn is_multicast(&self) -> bool {
  57. self.0[0] & 0xf0 == 224
  58. }
  59. /// Query whether the address falls into the "unspecified" range.
  60. pub fn is_unspecified(&self) -> bool {
  61. self.0[0] == 0
  62. }
  63. /// Query whether the address falls into the "link-local" range.
  64. pub fn is_link_local(&self) -> bool {
  65. self.0[0..2] == [169, 254]
  66. }
  67. /// Query whether the address falls into the "loopback" range.
  68. pub fn is_loopback(&self) -> bool {
  69. self.0[0] == 127
  70. }
  71. }
  72. impl fmt::Display for Address {
  73. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  74. let bytes = self.0;
  75. write!(f, "{}.{}.{}.{}", bytes[0], bytes[1], bytes[2], bytes[3])
  76. }
  77. }
  78. /// A specification of an IPv4 CIDR block, containing an address and a variable-length
  79. /// subnet masking prefix length.
  80. #[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default)]
  81. pub struct Cidr {
  82. address: Address,
  83. prefix_len: u8,
  84. }
  85. impl Cidr {
  86. /// Create an IPv4 CIDR block from the given address and prefix length.
  87. ///
  88. /// # Panics
  89. /// This function panics if the prefix length is larger than 32.
  90. pub fn new(address: Address, prefix_len: u8) -> Cidr {
  91. assert!(prefix_len <= 32);
  92. Cidr { address, prefix_len }
  93. }
  94. /// Return the address of this IPv4 CIDR block.
  95. pub fn address(&self) -> Address {
  96. self.address
  97. }
  98. /// Return the prefix length of this IPv4 CIDR block.
  99. pub fn prefix_len(&self) -> u8 {
  100. self.prefix_len
  101. }
  102. /// Query whether the subnetwork described by this IPv4 CIDR block contains
  103. /// the given address.
  104. pub fn contains_addr(&self, addr: &Address) -> bool {
  105. // right shift by 32 is not legal
  106. if self.prefix_len == 0 { return true }
  107. let shift = 32 - self.prefix_len;
  108. let self_prefix = NetworkEndian::read_u32(self.address.as_bytes()) >> shift;
  109. let addr_prefix = NetworkEndian::read_u32(addr.as_bytes()) >> shift;
  110. self_prefix == addr_prefix
  111. }
  112. /// Query whether the subnetwork described by this IPv4 CIDR block contains
  113. /// the subnetwork described by the given IPv4 CIDR block.
  114. pub fn contains_subnet(&self, subnet: &Cidr) -> bool {
  115. self.prefix_len <= subnet.prefix_len && self.contains_addr(&subnet.address)
  116. }
  117. }
  118. impl fmt::Display for Cidr {
  119. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  120. write!(f, "{}/{}", self.address, self.prefix_len)
  121. }
  122. }
  123. /// A read/write wrapper around an Internet Protocol version 4 packet buffer.
  124. #[derive(Debug, PartialEq)]
  125. pub struct Packet<T: AsRef<[u8]>> {
  126. buffer: T
  127. }
  128. mod field {
  129. use wire::field::*;
  130. pub const VER_IHL: usize = 0;
  131. pub const DSCP_ECN: usize = 1;
  132. pub const LENGTH: Field = 2..4;
  133. pub const IDENT: Field = 4..6;
  134. pub const FLG_OFF: Field = 6..8;
  135. pub const TTL: usize = 8;
  136. pub const PROTOCOL: usize = 9;
  137. pub const CHECKSUM: Field = 10..12;
  138. pub const SRC_ADDR: Field = 12..16;
  139. pub const DST_ADDR: Field = 16..20;
  140. }
  141. impl<T: AsRef<[u8]>> Packet<T> {
  142. /// Imbue a raw octet buffer with IPv4 packet structure.
  143. pub fn new(buffer: T) -> Packet<T> {
  144. Packet { buffer }
  145. }
  146. /// Shorthand for a combination of [new] and [check_len].
  147. ///
  148. /// [new]: #method.new
  149. /// [check_len]: #method.check_len
  150. pub fn new_checked(buffer: T) -> Result<Packet<T>> {
  151. let packet = Self::new(buffer);
  152. packet.check_len()?;
  153. Ok(packet)
  154. }
  155. /// Ensure that no accessor method will panic if called.
  156. /// Returns `Err(Error::Truncated)` if the buffer is too short.
  157. /// Returns `Err(Error::Malformed)` if the header length is greater
  158. /// than total length.
  159. ///
  160. /// The result of this check is invalidated by calling [set_header_len]
  161. /// and [set_total_len].
  162. ///
  163. /// [set_header_len]: #method.set_header_len
  164. /// [set_total_len]: #method.set_total_len
  165. pub fn check_len(&self) -> Result<()> {
  166. let len = self.buffer.as_ref().len();
  167. if len < field::DST_ADDR.end {
  168. Err(Error::Truncated)
  169. } else if len < self.header_len() as usize {
  170. Err(Error::Truncated)
  171. } else if self.header_len() as u16 > self.total_len() {
  172. Err(Error::Malformed)
  173. } else if len < self.total_len() as usize {
  174. Err(Error::Truncated)
  175. } else {
  176. Ok(())
  177. }
  178. }
  179. /// Consume the packet, returning the underlying buffer.
  180. pub fn into_inner(self) -> T {
  181. self.buffer
  182. }
  183. /// Return the version field.
  184. #[inline]
  185. pub fn version(&self) -> u8 {
  186. let data = self.buffer.as_ref();
  187. data[field::VER_IHL] >> 4
  188. }
  189. /// Return the header length, in octets.
  190. #[inline]
  191. pub fn header_len(&self) -> u8 {
  192. let data = self.buffer.as_ref();
  193. (data[field::VER_IHL] & 0x0f) * 4
  194. }
  195. /// Return the Differential Services Code Point field.
  196. pub fn dscp(&self) -> u8 {
  197. let data = self.buffer.as_ref();
  198. data[field::DSCP_ECN] >> 2
  199. }
  200. /// Return the Explicit Congestion Notification field.
  201. pub fn ecn(&self) -> u8 {
  202. let data = self.buffer.as_ref();
  203. data[field::DSCP_ECN] & 0x03
  204. }
  205. /// Return the total length field.
  206. #[inline]
  207. pub fn total_len(&self) -> u16 {
  208. let data = self.buffer.as_ref();
  209. NetworkEndian::read_u16(&data[field::LENGTH])
  210. }
  211. /// Return the fragment identification field.
  212. #[inline]
  213. pub fn ident(&self) -> u16 {
  214. let data = self.buffer.as_ref();
  215. NetworkEndian::read_u16(&data[field::IDENT])
  216. }
  217. /// Return the "don't fragment" flag.
  218. #[inline]
  219. pub fn dont_frag(&self) -> bool {
  220. let data = self.buffer.as_ref();
  221. NetworkEndian::read_u16(&data[field::FLG_OFF]) & 0x4000 != 0
  222. }
  223. /// Return the "more fragments" flag.
  224. #[inline]
  225. pub fn more_frags(&self) -> bool {
  226. let data = self.buffer.as_ref();
  227. NetworkEndian::read_u16(&data[field::FLG_OFF]) & 0x2000 != 0
  228. }
  229. /// Return the fragment offset, in octets.
  230. #[inline]
  231. pub fn frag_offset(&self) -> u16 {
  232. let data = self.buffer.as_ref();
  233. NetworkEndian::read_u16(&data[field::FLG_OFF]) << 3
  234. }
  235. /// Return the time to live field.
  236. #[inline]
  237. pub fn hop_limit(&self) -> u8 {
  238. let data = self.buffer.as_ref();
  239. data[field::TTL]
  240. }
  241. /// Return the protocol field.
  242. #[inline]
  243. pub fn protocol(&self) -> Protocol {
  244. let data = self.buffer.as_ref();
  245. Protocol::from(data[field::PROTOCOL])
  246. }
  247. /// Return the header checksum field.
  248. #[inline]
  249. pub fn checksum(&self) -> u16 {
  250. let data = self.buffer.as_ref();
  251. NetworkEndian::read_u16(&data[field::CHECKSUM])
  252. }
  253. /// Return the source address field.
  254. #[inline]
  255. pub fn src_addr(&self) -> Address {
  256. let data = self.buffer.as_ref();
  257. Address::from_bytes(&data[field::SRC_ADDR])
  258. }
  259. /// Return the destination address field.
  260. #[inline]
  261. pub fn dst_addr(&self) -> Address {
  262. let data = self.buffer.as_ref();
  263. Address::from_bytes(&data[field::DST_ADDR])
  264. }
  265. /// Validate the header checksum.
  266. ///
  267. /// # Fuzzing
  268. /// This function always returns `true` when fuzzing.
  269. pub fn verify_checksum(&self) -> bool {
  270. if cfg!(fuzzing) { return true }
  271. let data = self.buffer.as_ref();
  272. checksum::data(&data[..self.header_len() as usize]) == !0
  273. }
  274. }
  275. impl<'a, T: AsRef<[u8]> + ?Sized> Packet<&'a T> {
  276. /// Return a pointer to the payload.
  277. #[inline]
  278. pub fn payload(&self) -> &'a [u8] {
  279. let range = self.header_len() as usize..self.total_len() as usize;
  280. let data = self.buffer.as_ref();
  281. &data[range]
  282. }
  283. }
  284. impl<T: AsRef<[u8]> + AsMut<[u8]>> Packet<T> {
  285. /// Set the version field.
  286. #[inline]
  287. pub fn set_version(&mut self, value: u8) {
  288. let data = self.buffer.as_mut();
  289. data[field::VER_IHL] = (data[field::VER_IHL] & !0xf0) | (value << 4);
  290. }
  291. /// Set the header length, in octets.
  292. #[inline]
  293. pub fn set_header_len(&mut self, value: u8) {
  294. let data = self.buffer.as_mut();
  295. data[field::VER_IHL] = (data[field::VER_IHL] & !0x0f) | ((value / 4) & 0x0f);
  296. }
  297. /// Set the Differential Services Code Point field.
  298. pub fn set_dscp(&mut self, value: u8) {
  299. let data = self.buffer.as_mut();
  300. data[field::DSCP_ECN] = (data[field::DSCP_ECN] & !0xfc) | (value << 2)
  301. }
  302. /// Set the Explicit Congestion Notification field.
  303. pub fn set_ecn(&mut self, value: u8) {
  304. let data = self.buffer.as_mut();
  305. data[field::DSCP_ECN] = (data[field::DSCP_ECN] & !0x03) | (value & 0x03)
  306. }
  307. /// Set the total length field.
  308. #[inline]
  309. pub fn set_total_len(&mut self, value: u16) {
  310. let data = self.buffer.as_mut();
  311. NetworkEndian::write_u16(&mut data[field::LENGTH], value)
  312. }
  313. /// Set the fragment identification field.
  314. #[inline]
  315. pub fn set_ident(&mut self, value: u16) {
  316. let data = self.buffer.as_mut();
  317. NetworkEndian::write_u16(&mut data[field::IDENT], value)
  318. }
  319. /// Clear the entire flags field.
  320. #[inline]
  321. pub fn clear_flags(&mut self) {
  322. let data = self.buffer.as_mut();
  323. let raw = NetworkEndian::read_u16(&data[field::FLG_OFF]);
  324. let raw = raw & !0xe000;
  325. NetworkEndian::write_u16(&mut data[field::FLG_OFF], raw);
  326. }
  327. /// Set the "don't fragment" flag.
  328. #[inline]
  329. pub fn set_dont_frag(&mut self, value: bool) {
  330. let data = self.buffer.as_mut();
  331. let raw = NetworkEndian::read_u16(&data[field::FLG_OFF]);
  332. let raw = if value { raw | 0x4000 } else { raw & !0x4000 };
  333. NetworkEndian::write_u16(&mut data[field::FLG_OFF], raw);
  334. }
  335. /// Set the "more fragments" flag.
  336. #[inline]
  337. pub fn set_more_frags(&mut self, value: bool) {
  338. let data = self.buffer.as_mut();
  339. let raw = NetworkEndian::read_u16(&data[field::FLG_OFF]);
  340. let raw = if value { raw | 0x2000 } else { raw & !0x2000 };
  341. NetworkEndian::write_u16(&mut data[field::FLG_OFF], raw);
  342. }
  343. /// Set the fragment offset, in octets.
  344. #[inline]
  345. pub fn set_frag_offset(&mut self, value: u16) {
  346. let data = self.buffer.as_mut();
  347. let raw = NetworkEndian::read_u16(&data[field::FLG_OFF]);
  348. let raw = (raw & 0xe000) | (value >> 3);
  349. NetworkEndian::write_u16(&mut data[field::FLG_OFF], raw);
  350. }
  351. /// Set the time to live field.
  352. #[inline]
  353. pub fn set_hop_limit(&mut self, value: u8) {
  354. let data = self.buffer.as_mut();
  355. data[field::TTL] = value
  356. }
  357. /// Set the protocol field.
  358. #[inline]
  359. pub fn set_protocol(&mut self, value: Protocol) {
  360. let data = self.buffer.as_mut();
  361. data[field::PROTOCOL] = value.into()
  362. }
  363. /// Set the header checksum field.
  364. #[inline]
  365. pub fn set_checksum(&mut self, value: u16) {
  366. let data = self.buffer.as_mut();
  367. NetworkEndian::write_u16(&mut data[field::CHECKSUM], value)
  368. }
  369. /// Set the source address field.
  370. #[inline]
  371. pub fn set_src_addr(&mut self, value: Address) {
  372. let data = self.buffer.as_mut();
  373. data[field::SRC_ADDR].copy_from_slice(value.as_bytes())
  374. }
  375. /// Set the destination address field.
  376. #[inline]
  377. pub fn set_dst_addr(&mut self, value: Address) {
  378. let data = self.buffer.as_mut();
  379. data[field::DST_ADDR].copy_from_slice(value.as_bytes())
  380. }
  381. /// Compute and fill in the header checksum.
  382. pub fn fill_checksum(&mut self) {
  383. self.set_checksum(0);
  384. let checksum = {
  385. let data = self.buffer.as_ref();
  386. !checksum::data(&data[..self.header_len() as usize])
  387. };
  388. self.set_checksum(checksum)
  389. }
  390. }
  391. impl<'a, T: AsRef<[u8]> + AsMut<[u8]> + ?Sized> Packet<&'a mut T> {
  392. /// Return a mutable pointer to the payload.
  393. #[inline]
  394. pub fn payload_mut(&mut self) -> &mut [u8] {
  395. let range = self.header_len() as usize..self.total_len() as usize;
  396. let data = self.buffer.as_mut();
  397. &mut data[range]
  398. }
  399. }
  400. /// A high-level representation of an Internet Protocol version 4 packet header.
  401. #[derive(Debug, PartialEq, Eq, Clone, Copy)]
  402. pub struct Repr {
  403. pub src_addr: Address,
  404. pub dst_addr: Address,
  405. pub protocol: Protocol,
  406. pub payload_len: usize,
  407. pub hop_limit: u8
  408. }
  409. impl Repr {
  410. /// Parse an Internet Protocol version 4 packet and return a high-level representation.
  411. pub fn parse<T: AsRef<[u8]> + ?Sized>(packet: &Packet<&T>,
  412. checksum_caps: &ChecksumCapabilities) -> Result<Repr> {
  413. // Version 4 is expected.
  414. if packet.version() != 4 { return Err(Error::Malformed) }
  415. // Valid checksum is expected.
  416. if checksum_caps.ipv4.rx() && !packet.verify_checksum() { return Err(Error::Checksum) }
  417. // We do not support fragmentation.
  418. if packet.more_frags() || packet.frag_offset() != 0 { return Err(Error::Fragmented) }
  419. // Since the packet is not fragmented, it must include the entire payload.
  420. let payload_len = packet.total_len() as usize - packet.header_len() as usize;
  421. if packet.payload().len() < payload_len { return Err(Error::Truncated) }
  422. // All DSCP values are acceptable, since they are of no concern to receiving endpoint.
  423. // All ECN values are acceptable, since ECN requires opt-in from both endpoints.
  424. // All TTL values are acceptable, since we do not perform routing.
  425. Ok(Repr {
  426. src_addr: packet.src_addr(),
  427. dst_addr: packet.dst_addr(),
  428. protocol: packet.protocol(),
  429. payload_len: payload_len,
  430. hop_limit: packet.hop_limit()
  431. })
  432. }
  433. /// Return the length of a header that will be emitted from this high-level representation.
  434. pub fn buffer_len(&self) -> usize {
  435. // We never emit any options.
  436. field::DST_ADDR.end
  437. }
  438. /// Emit a high-level representation into an Internet Protocol version 4 packet.
  439. pub fn emit<T: AsRef<[u8]> + AsMut<[u8]>>(&self, packet: &mut Packet<T>, checksum_caps: &ChecksumCapabilities) {
  440. packet.set_version(4);
  441. packet.set_header_len(field::DST_ADDR.end as u8);
  442. packet.set_dscp(0);
  443. packet.set_ecn(0);
  444. let total_len = packet.header_len() as u16 + self.payload_len as u16;
  445. packet.set_total_len(total_len);
  446. packet.set_ident(0);
  447. packet.clear_flags();
  448. packet.set_more_frags(false);
  449. packet.set_dont_frag(true);
  450. packet.set_frag_offset(0);
  451. packet.set_hop_limit(self.hop_limit);
  452. packet.set_protocol(self.protocol);
  453. packet.set_src_addr(self.src_addr);
  454. packet.set_dst_addr(self.dst_addr);
  455. if checksum_caps.ipv4.tx() {
  456. packet.fill_checksum();
  457. } else {
  458. // make sure we get a consistently zeroed checksum,
  459. // since implementations might rely on it
  460. packet.set_checksum(0);
  461. }
  462. }
  463. }
  464. impl<'a, T: AsRef<[u8]> + ?Sized> fmt::Display for Packet<&'a T> {
  465. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  466. match Repr::parse(self, &ChecksumCapabilities::ignored()) {
  467. Ok(repr) => write!(f, "{}", repr),
  468. Err(err) => {
  469. write!(f, "IPv4 ({})", err)?;
  470. write!(f, " src={} dst={} proto={} hop_limit={}",
  471. self.src_addr(), self.dst_addr(), self.protocol(), self.hop_limit())?;
  472. if self.version() != 4 {
  473. write!(f, " ver={}", self.version())?;
  474. }
  475. if self.header_len() != 20 {
  476. write!(f, " hlen={}", self.header_len())?;
  477. }
  478. if self.dscp() != 0 {
  479. write!(f, " dscp={}", self.dscp())?;
  480. }
  481. if self.ecn() != 0 {
  482. write!(f, " ecn={}", self.ecn())?;
  483. }
  484. write!(f, " tlen={}", self.total_len())?;
  485. if self.dont_frag() {
  486. write!(f, " df")?;
  487. }
  488. if self.more_frags() {
  489. write!(f, " mf")?;
  490. }
  491. if self.frag_offset() != 0 {
  492. write!(f, " off={}", self.frag_offset())?;
  493. }
  494. if self.more_frags() || self.frag_offset() != 0 {
  495. write!(f, " id={}", self.ident())?;
  496. }
  497. Ok(())
  498. }
  499. }
  500. }
  501. }
  502. impl fmt::Display for Repr {
  503. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  504. write!(f, "IPv4 src={} dst={} proto={}",
  505. self.src_addr, self.dst_addr, self.protocol)
  506. }
  507. }
  508. use super::pretty_print::{PrettyPrint, PrettyIndent};
  509. impl<T: AsRef<[u8]>> PrettyPrint for Packet<T> {
  510. fn pretty_print(buffer: &AsRef<[u8]>, f: &mut fmt::Formatter,
  511. indent: &mut PrettyIndent) -> fmt::Result {
  512. use wire::ip::checksum::format_checksum;
  513. let checksum_caps = ChecksumCapabilities::ignored();
  514. let (ip_repr, payload) = match Packet::new_checked(buffer) {
  515. Err(err) => return write!(f, "{}({})", indent, err),
  516. Ok(ip_packet) => {
  517. match Repr::parse(&ip_packet, &checksum_caps) {
  518. Err(_) => return Ok(()),
  519. Ok(ip_repr) => {
  520. write!(f, "{}{}", indent, ip_repr)?;
  521. format_checksum(f, ip_packet.verify_checksum())?;
  522. (ip_repr, ip_packet.payload())
  523. }
  524. }
  525. }
  526. };
  527. pretty_print_ip_payload(f, indent, ip_repr, payload)
  528. }
  529. }
  530. #[cfg(test)]
  531. mod test {
  532. use super::*;
  533. static PACKET_BYTES: [u8; 30] =
  534. [0x45, 0x00, 0x00, 0x1e,
  535. 0x01, 0x02, 0x62, 0x03,
  536. 0x1a, 0x01, 0xd5, 0x6e,
  537. 0x11, 0x12, 0x13, 0x14,
  538. 0x21, 0x22, 0x23, 0x24,
  539. 0xaa, 0x00, 0x00, 0x00,
  540. 0x00, 0x00, 0x00, 0x00,
  541. 0x00, 0xff];
  542. static PAYLOAD_BYTES: [u8; 10] =
  543. [0xaa, 0x00, 0x00, 0x00,
  544. 0x00, 0x00, 0x00, 0x00,
  545. 0x00, 0xff];
  546. #[test]
  547. fn test_deconstruct() {
  548. let packet = Packet::new(&PACKET_BYTES[..]);
  549. assert_eq!(packet.version(), 4);
  550. assert_eq!(packet.header_len(), 20);
  551. assert_eq!(packet.dscp(), 0);
  552. assert_eq!(packet.ecn(), 0);
  553. assert_eq!(packet.total_len(), 30);
  554. assert_eq!(packet.ident(), 0x102);
  555. assert_eq!(packet.more_frags(), true);
  556. assert_eq!(packet.dont_frag(), true);
  557. assert_eq!(packet.frag_offset(), 0x203 * 8);
  558. assert_eq!(packet.hop_limit(), 0x1a);
  559. assert_eq!(packet.protocol(), Protocol::Icmp);
  560. assert_eq!(packet.checksum(), 0xd56e);
  561. assert_eq!(packet.src_addr(), Address([0x11, 0x12, 0x13, 0x14]));
  562. assert_eq!(packet.dst_addr(), Address([0x21, 0x22, 0x23, 0x24]));
  563. assert_eq!(packet.verify_checksum(), true);
  564. assert_eq!(packet.payload(), &PAYLOAD_BYTES[..]);
  565. }
  566. #[test]
  567. fn test_construct() {
  568. let mut bytes = vec![0xa5; 30];
  569. let mut packet = Packet::new(&mut bytes);
  570. packet.set_version(4);
  571. packet.set_header_len(20);
  572. packet.clear_flags();
  573. packet.set_dscp(0);
  574. packet.set_ecn(0);
  575. packet.set_total_len(30);
  576. packet.set_ident(0x102);
  577. packet.set_more_frags(true);
  578. packet.set_dont_frag(true);
  579. packet.set_frag_offset(0x203 * 8);
  580. packet.set_hop_limit(0x1a);
  581. packet.set_protocol(Protocol::Icmp);
  582. packet.set_src_addr(Address([0x11, 0x12, 0x13, 0x14]));
  583. packet.set_dst_addr(Address([0x21, 0x22, 0x23, 0x24]));
  584. packet.fill_checksum();
  585. packet.payload_mut().copy_from_slice(&PAYLOAD_BYTES[..]);
  586. assert_eq!(&packet.into_inner()[..], &PACKET_BYTES[..]);
  587. }
  588. #[test]
  589. fn test_overlong() {
  590. let mut bytes = vec![];
  591. bytes.extend(&PACKET_BYTES[..]);
  592. bytes.push(0);
  593. assert_eq!(Packet::new(&bytes).payload().len(),
  594. PAYLOAD_BYTES.len());
  595. assert_eq!(Packet::new(&mut bytes).payload_mut().len(),
  596. PAYLOAD_BYTES.len());
  597. }
  598. #[test]
  599. fn test_total_len_overflow() {
  600. let mut bytes = vec![];
  601. bytes.extend(&PACKET_BYTES[..]);
  602. Packet::new(&mut bytes).set_total_len(128);
  603. assert_eq!(Packet::new_checked(&bytes).unwrap_err(),
  604. Error::Truncated);
  605. }
  606. static REPR_PACKET_BYTES: [u8; 24] =
  607. [0x45, 0x00, 0x00, 0x18,
  608. 0x00, 0x00, 0x40, 0x00,
  609. 0x40, 0x01, 0xd2, 0x79,
  610. 0x11, 0x12, 0x13, 0x14,
  611. 0x21, 0x22, 0x23, 0x24,
  612. 0xaa, 0x00, 0x00, 0xff];
  613. static REPR_PAYLOAD_BYTES: [u8; 4] =
  614. [0xaa, 0x00, 0x00, 0xff];
  615. fn packet_repr() -> Repr {
  616. Repr {
  617. src_addr: Address([0x11, 0x12, 0x13, 0x14]),
  618. dst_addr: Address([0x21, 0x22, 0x23, 0x24]),
  619. protocol: Protocol::Icmp,
  620. payload_len: 4,
  621. hop_limit: 64
  622. }
  623. }
  624. #[test]
  625. fn test_parse() {
  626. let packet = Packet::new(&REPR_PACKET_BYTES[..]);
  627. let repr = Repr::parse(&packet, &ChecksumCapabilities::default()).unwrap();
  628. assert_eq!(repr, packet_repr());
  629. }
  630. #[test]
  631. fn test_parse_bad_version() {
  632. let mut bytes = vec![0; 24];
  633. bytes.copy_from_slice(&REPR_PACKET_BYTES[..]);
  634. let mut packet = Packet::new(&mut bytes);
  635. packet.set_version(6);
  636. packet.fill_checksum();
  637. let packet = Packet::new(&*packet.into_inner());
  638. assert_eq!(Repr::parse(&packet, &ChecksumCapabilities::default()), Err(Error::Malformed));
  639. }
  640. #[test]
  641. fn test_parse_total_len_underflow() {
  642. let mut bytes = vec![0; 24];
  643. bytes.copy_from_slice(&REPR_PACKET_BYTES[..]);
  644. let mut packet = Packet::new(&mut bytes);
  645. packet.set_total_len(10);
  646. packet.fill_checksum();
  647. let packet = Packet::new(&*packet.into_inner());
  648. assert_eq!(Repr::parse(&packet, &ChecksumCapabilities::default()), Err(Error::Malformed));
  649. }
  650. #[test]
  651. fn test_parse_total_len_less_than_header_len() {
  652. let mut bytes = vec![0; 40];
  653. bytes[0] = 0x09;
  654. assert_eq!(Packet::new_checked(&mut bytes), Err(Error::Malformed));
  655. }
  656. #[test]
  657. fn test_emit() {
  658. let repr = packet_repr();
  659. let mut bytes = vec![0xa5; repr.buffer_len() + REPR_PAYLOAD_BYTES.len()];
  660. let mut packet = Packet::new(&mut bytes);
  661. repr.emit(&mut packet, &ChecksumCapabilities::default());
  662. packet.payload_mut().copy_from_slice(&REPR_PAYLOAD_BYTES);
  663. assert_eq!(&packet.into_inner()[..], &REPR_PACKET_BYTES[..]);
  664. }
  665. #[test]
  666. fn test_unspecified() {
  667. assert!(Address::UNSPECIFIED.is_unspecified());
  668. assert!(!Address::UNSPECIFIED.is_broadcast());
  669. assert!(!Address::UNSPECIFIED.is_multicast());
  670. assert!(!Address::UNSPECIFIED.is_link_local());
  671. assert!(!Address::UNSPECIFIED.is_loopback());
  672. }
  673. #[test]
  674. fn test_broadcast() {
  675. assert!(!Address::BROADCAST.is_unspecified());
  676. assert!(Address::BROADCAST.is_broadcast());
  677. assert!(!Address::BROADCAST.is_multicast());
  678. assert!(!Address::BROADCAST.is_link_local());
  679. assert!(!Address::BROADCAST.is_loopback());
  680. }
  681. #[test]
  682. fn test_cidr() {
  683. let cidr = Cidr::new(Address::new(192, 168, 1, 10), 24);
  684. let inside_subnet = [
  685. [192, 168, 1, 0], [192, 168, 1, 1],
  686. [192, 168, 1, 2], [192, 168, 1, 10],
  687. [192, 168, 1, 127], [192, 168, 1, 255],
  688. ];
  689. let outside_subnet = [
  690. [192, 168, 0, 0], [127, 0, 0, 1],
  691. [192, 168, 2, 0], [192, 168, 0, 255],
  692. [ 0, 0, 0, 0], [255, 255, 255, 255],
  693. ];
  694. let subnets = [
  695. ([192, 168, 1, 0], 32),
  696. ([192, 168, 1, 255], 24),
  697. ([192, 168, 1, 10], 30),
  698. ];
  699. let not_subnets = [
  700. ([192, 168, 1, 10], 23),
  701. ([127, 0, 0, 1], 8),
  702. ([192, 168, 1, 0], 0),
  703. ([192, 168, 0, 255], 32),
  704. ];
  705. for addr in inside_subnet.iter().map(|a| Address::from_bytes(a)) {
  706. assert!(cidr.contains_addr(&addr));
  707. }
  708. for addr in outside_subnet.iter().map(|a| Address::from_bytes(a)) {
  709. assert!(!cidr.contains_addr(&addr));
  710. }
  711. for subnet in subnets.iter().map(
  712. |&(a, p)| Cidr::new(Address::new(a[0], a[1], a[2], a[3]), p)) {
  713. assert!(cidr.contains_subnet(&subnet));
  714. }
  715. for subnet in not_subnets.iter().map(
  716. |&(a, p)| Cidr::new(Address::new(a[0], a[1], a[2], a[3]), p)) {
  717. assert!(!cidr.contains_subnet(&subnet));
  718. }
  719. let cidr_without_prefix = Cidr::new(cidr.address(), 0);
  720. assert!(cidr_without_prefix.contains_addr(&Address::new(127, 0, 0, 1)));
  721. }
  722. }