ipv4.rs 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819
  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. ///
  158. /// The result of this check is invalidated by calling [set_header_len]
  159. /// and [set_total_len].
  160. ///
  161. /// [set_header_len]: #method.set_header_len
  162. /// [set_total_len]: #method.set_total_len
  163. pub fn check_len(&self) -> Result<()> {
  164. let len = self.buffer.as_ref().len();
  165. if len < field::DST_ADDR.end {
  166. Err(Error::Truncated)
  167. } else if len < self.header_len() as usize {
  168. Err(Error::Truncated)
  169. } else if len < self.total_len() as usize {
  170. Err(Error::Truncated)
  171. } else {
  172. Ok(())
  173. }
  174. }
  175. /// Consume the packet, returning the underlying buffer.
  176. pub fn into_inner(self) -> T {
  177. self.buffer
  178. }
  179. /// Return the version field.
  180. #[inline]
  181. pub fn version(&self) -> u8 {
  182. let data = self.buffer.as_ref();
  183. data[field::VER_IHL] >> 4
  184. }
  185. /// Return the header length, in octets.
  186. #[inline]
  187. pub fn header_len(&self) -> u8 {
  188. let data = self.buffer.as_ref();
  189. (data[field::VER_IHL] & 0x0f) * 4
  190. }
  191. /// Return the Differential Services Code Point field.
  192. pub fn dscp(&self) -> u8 {
  193. let data = self.buffer.as_ref();
  194. data[field::DSCP_ECN] >> 2
  195. }
  196. /// Return the Explicit Congestion Notification field.
  197. pub fn ecn(&self) -> u8 {
  198. let data = self.buffer.as_ref();
  199. data[field::DSCP_ECN] & 0x03
  200. }
  201. /// Return the total length field.
  202. #[inline]
  203. pub fn total_len(&self) -> u16 {
  204. let data = self.buffer.as_ref();
  205. NetworkEndian::read_u16(&data[field::LENGTH])
  206. }
  207. /// Return the fragment identification field.
  208. #[inline]
  209. pub fn ident(&self) -> u16 {
  210. let data = self.buffer.as_ref();
  211. NetworkEndian::read_u16(&data[field::IDENT])
  212. }
  213. /// Return the "don't fragment" flag.
  214. #[inline]
  215. pub fn dont_frag(&self) -> bool {
  216. let data = self.buffer.as_ref();
  217. NetworkEndian::read_u16(&data[field::FLG_OFF]) & 0x4000 != 0
  218. }
  219. /// Return the "more fragments" flag.
  220. #[inline]
  221. pub fn more_frags(&self) -> bool {
  222. let data = self.buffer.as_ref();
  223. NetworkEndian::read_u16(&data[field::FLG_OFF]) & 0x2000 != 0
  224. }
  225. /// Return the fragment offset, in octets.
  226. #[inline]
  227. pub fn frag_offset(&self) -> u16 {
  228. let data = self.buffer.as_ref();
  229. NetworkEndian::read_u16(&data[field::FLG_OFF]) << 3
  230. }
  231. /// Return the time to live field.
  232. #[inline]
  233. pub fn hop_limit(&self) -> u8 {
  234. let data = self.buffer.as_ref();
  235. data[field::TTL]
  236. }
  237. /// Return the protocol field.
  238. #[inline]
  239. pub fn protocol(&self) -> Protocol {
  240. let data = self.buffer.as_ref();
  241. Protocol::from(data[field::PROTOCOL])
  242. }
  243. /// Return the header checksum field.
  244. #[inline]
  245. pub fn checksum(&self) -> u16 {
  246. let data = self.buffer.as_ref();
  247. NetworkEndian::read_u16(&data[field::CHECKSUM])
  248. }
  249. /// Return the source address field.
  250. #[inline]
  251. pub fn src_addr(&self) -> Address {
  252. let data = self.buffer.as_ref();
  253. Address::from_bytes(&data[field::SRC_ADDR])
  254. }
  255. /// Return the destination address field.
  256. #[inline]
  257. pub fn dst_addr(&self) -> Address {
  258. let data = self.buffer.as_ref();
  259. Address::from_bytes(&data[field::DST_ADDR])
  260. }
  261. /// Validate the header checksum.
  262. ///
  263. /// # Fuzzing
  264. /// This function always returns `true` when fuzzing.
  265. pub fn verify_checksum(&self) -> bool {
  266. if cfg!(fuzzing) { return true }
  267. let data = self.buffer.as_ref();
  268. checksum::data(&data[..self.header_len() as usize]) == !0
  269. }
  270. }
  271. impl<'a, T: AsRef<[u8]> + ?Sized> Packet<&'a T> {
  272. /// Return a pointer to the payload.
  273. #[inline]
  274. pub fn payload(&self) -> &'a [u8] {
  275. let range = self.header_len() as usize..self.total_len() as usize;
  276. let data = self.buffer.as_ref();
  277. &data[range]
  278. }
  279. }
  280. impl<T: AsRef<[u8]> + AsMut<[u8]>> Packet<T> {
  281. /// Set the version field.
  282. #[inline]
  283. pub fn set_version(&mut self, value: u8) {
  284. let data = self.buffer.as_mut();
  285. data[field::VER_IHL] = (data[field::VER_IHL] & !0xf0) | (value << 4);
  286. }
  287. /// Set the header length, in octets.
  288. #[inline]
  289. pub fn set_header_len(&mut self, value: u8) {
  290. let data = self.buffer.as_mut();
  291. data[field::VER_IHL] = (data[field::VER_IHL] & !0x0f) | ((value / 4) & 0x0f);
  292. }
  293. /// Set the Differential Services Code Point field.
  294. pub fn set_dscp(&mut self, value: u8) {
  295. let data = self.buffer.as_mut();
  296. data[field::DSCP_ECN] = (data[field::DSCP_ECN] & !0xfc) | (value << 2)
  297. }
  298. /// Set the Explicit Congestion Notification field.
  299. pub fn set_ecn(&mut self, value: u8) {
  300. let data = self.buffer.as_mut();
  301. data[field::DSCP_ECN] = (data[field::DSCP_ECN] & !0x03) | (value & 0x03)
  302. }
  303. /// Set the total length field.
  304. #[inline]
  305. pub fn set_total_len(&mut self, value: u16) {
  306. let data = self.buffer.as_mut();
  307. NetworkEndian::write_u16(&mut data[field::LENGTH], value)
  308. }
  309. /// Set the fragment identification field.
  310. #[inline]
  311. pub fn set_ident(&mut self, value: u16) {
  312. let data = self.buffer.as_mut();
  313. NetworkEndian::write_u16(&mut data[field::IDENT], value)
  314. }
  315. /// Clear the entire flags field.
  316. #[inline]
  317. pub fn clear_flags(&mut self) {
  318. let data = self.buffer.as_mut();
  319. let raw = NetworkEndian::read_u16(&data[field::FLG_OFF]);
  320. let raw = raw & !0xe000;
  321. NetworkEndian::write_u16(&mut data[field::FLG_OFF], raw);
  322. }
  323. /// Set the "don't fragment" flag.
  324. #[inline]
  325. pub fn set_dont_frag(&mut self, value: bool) {
  326. let data = self.buffer.as_mut();
  327. let raw = NetworkEndian::read_u16(&data[field::FLG_OFF]);
  328. let raw = if value { raw | 0x4000 } else { raw & !0x4000 };
  329. NetworkEndian::write_u16(&mut data[field::FLG_OFF], raw);
  330. }
  331. /// Set the "more fragments" flag.
  332. #[inline]
  333. pub fn set_more_frags(&mut self, value: bool) {
  334. let data = self.buffer.as_mut();
  335. let raw = NetworkEndian::read_u16(&data[field::FLG_OFF]);
  336. let raw = if value { raw | 0x2000 } else { raw & !0x2000 };
  337. NetworkEndian::write_u16(&mut data[field::FLG_OFF], raw);
  338. }
  339. /// Set the fragment offset, in octets.
  340. #[inline]
  341. pub fn set_frag_offset(&mut self, value: u16) {
  342. let data = self.buffer.as_mut();
  343. let raw = NetworkEndian::read_u16(&data[field::FLG_OFF]);
  344. let raw = (raw & 0xe000) | (value >> 3);
  345. NetworkEndian::write_u16(&mut data[field::FLG_OFF], raw);
  346. }
  347. /// Set the time to live field.
  348. #[inline]
  349. pub fn set_hop_limit(&mut self, value: u8) {
  350. let data = self.buffer.as_mut();
  351. data[field::TTL] = value
  352. }
  353. /// Set the protocol field.
  354. #[inline]
  355. pub fn set_protocol(&mut self, value: Protocol) {
  356. let data = self.buffer.as_mut();
  357. data[field::PROTOCOL] = value.into()
  358. }
  359. /// Set the header checksum field.
  360. #[inline]
  361. pub fn set_checksum(&mut self, value: u16) {
  362. let data = self.buffer.as_mut();
  363. NetworkEndian::write_u16(&mut data[field::CHECKSUM], value)
  364. }
  365. /// Set the source address field.
  366. #[inline]
  367. pub fn set_src_addr(&mut self, value: Address) {
  368. let data = self.buffer.as_mut();
  369. data[field::SRC_ADDR].copy_from_slice(value.as_bytes())
  370. }
  371. /// Set the destination address field.
  372. #[inline]
  373. pub fn set_dst_addr(&mut self, value: Address) {
  374. let data = self.buffer.as_mut();
  375. data[field::DST_ADDR].copy_from_slice(value.as_bytes())
  376. }
  377. /// Compute and fill in the header checksum.
  378. pub fn fill_checksum(&mut self) {
  379. self.set_checksum(0);
  380. let checksum = {
  381. let data = self.buffer.as_ref();
  382. !checksum::data(&data[..self.header_len() as usize])
  383. };
  384. self.set_checksum(checksum)
  385. }
  386. }
  387. impl<'a, T: AsRef<[u8]> + AsMut<[u8]> + ?Sized> Packet<&'a mut T> {
  388. /// Return a mutable pointer to the payload.
  389. #[inline]
  390. pub fn payload_mut(&mut self) -> &mut [u8] {
  391. let range = self.header_len() as usize..self.total_len() as usize;
  392. let data = self.buffer.as_mut();
  393. &mut data[range]
  394. }
  395. }
  396. /// A high-level representation of an Internet Protocol version 4 packet header.
  397. #[derive(Debug, PartialEq, Eq, Clone, Copy)]
  398. pub struct Repr {
  399. pub src_addr: Address,
  400. pub dst_addr: Address,
  401. pub protocol: Protocol,
  402. pub payload_len: usize,
  403. pub hop_limit: u8
  404. }
  405. impl Repr {
  406. /// Parse an Internet Protocol version 4 packet and return a high-level representation.
  407. pub fn parse<T: AsRef<[u8]> + ?Sized>(packet: &Packet<&T>,
  408. checksum_caps: &ChecksumCapabilities) -> Result<Repr> {
  409. // Version 4 is expected.
  410. if packet.version() != 4 { return Err(Error::Malformed) }
  411. // Valid checksum is expected.
  412. if checksum_caps.ipv4.rx() && !packet.verify_checksum() { return Err(Error::Checksum) }
  413. // We do not support fragmentation.
  414. if packet.more_frags() || packet.frag_offset() != 0 { return Err(Error::Fragmented) }
  415. // Total length may not be less than header length.
  416. if packet.total_len() < packet.header_len() as u16 { return Err(Error::Malformed) }
  417. // Since the packet is not fragmented, it must include the entire payload.
  418. let payload_len = packet.total_len() as usize - packet.header_len() as usize;
  419. if packet.payload().len() < payload_len { return Err(Error::Truncated) }
  420. // All DSCP values are acceptable, since they are of no concern to receiving endpoint.
  421. // All ECN values are acceptable, since ECN requires opt-in from both endpoints.
  422. // All TTL values are acceptable, since we do not perform routing.
  423. Ok(Repr {
  424. src_addr: packet.src_addr(),
  425. dst_addr: packet.dst_addr(),
  426. protocol: packet.protocol(),
  427. payload_len: payload_len,
  428. hop_limit: packet.hop_limit()
  429. })
  430. }
  431. /// Return the length of a header that will be emitted from this high-level representation.
  432. pub fn buffer_len(&self) -> usize {
  433. // We never emit any options.
  434. field::DST_ADDR.end
  435. }
  436. /// Emit a high-level representation into an Internet Protocol version 4 packet.
  437. pub fn emit<T: AsRef<[u8]> + AsMut<[u8]>>(&self, packet: &mut Packet<T>, checksum_caps: &ChecksumCapabilities) {
  438. packet.set_version(4);
  439. packet.set_header_len(field::DST_ADDR.end as u8);
  440. packet.set_dscp(0);
  441. packet.set_ecn(0);
  442. let total_len = packet.header_len() as u16 + self.payload_len as u16;
  443. packet.set_total_len(total_len);
  444. packet.set_ident(0);
  445. packet.clear_flags();
  446. packet.set_more_frags(false);
  447. packet.set_dont_frag(true);
  448. packet.set_frag_offset(0);
  449. packet.set_hop_limit(self.hop_limit);
  450. packet.set_protocol(self.protocol);
  451. packet.set_src_addr(self.src_addr);
  452. packet.set_dst_addr(self.dst_addr);
  453. if checksum_caps.ipv4.tx() {
  454. packet.fill_checksum();
  455. } else {
  456. // make sure we get a consistently zeroed checksum, since implementations might rely on it
  457. packet.set_checksum(0);
  458. }
  459. }
  460. }
  461. impl<'a, T: AsRef<[u8]> + ?Sized> fmt::Display for Packet<&'a T> {
  462. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  463. match Repr::parse(self, &ChecksumCapabilities::ignored()) {
  464. Ok(repr) => write!(f, "{}", repr),
  465. Err(err) => {
  466. write!(f, "IPv4 ({})", err)?;
  467. write!(f, " src={} dst={} proto={} hop_limit={}",
  468. self.src_addr(), self.dst_addr(), self.protocol(), self.hop_limit())?;
  469. if self.version() != 4 {
  470. write!(f, " ver={}", self.version())?;
  471. }
  472. if self.header_len() != 20 {
  473. write!(f, " hlen={}", self.header_len())?;
  474. }
  475. if self.dscp() != 0 {
  476. write!(f, " dscp={}", self.dscp())?;
  477. }
  478. if self.ecn() != 0 {
  479. write!(f, " ecn={}", self.ecn())?;
  480. }
  481. write!(f, " tlen={}", self.total_len())?;
  482. if self.dont_frag() {
  483. write!(f, " df")?;
  484. }
  485. if self.more_frags() {
  486. write!(f, " mf")?;
  487. }
  488. if self.frag_offset() != 0 {
  489. write!(f, " off={}", self.frag_offset())?;
  490. }
  491. if self.more_frags() || self.frag_offset() != 0 {
  492. write!(f, " id={}", self.ident())?;
  493. }
  494. Ok(())
  495. }
  496. }
  497. }
  498. }
  499. impl fmt::Display for Repr {
  500. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  501. write!(f, "IPv4 src={} dst={} proto={}",
  502. self.src_addr, self.dst_addr, self.protocol)
  503. }
  504. }
  505. use super::pretty_print::{PrettyPrint, PrettyIndent};
  506. impl<T: AsRef<[u8]>> PrettyPrint for Packet<T> {
  507. fn pretty_print(buffer: &AsRef<[u8]>, f: &mut fmt::Formatter,
  508. indent: &mut PrettyIndent) -> fmt::Result {
  509. use wire::ip::checksum::format_checksum;
  510. let checksum_caps = ChecksumCapabilities::ignored();
  511. let (ip_repr, payload) = match Packet::new_checked(buffer) {
  512. Err(err) => return write!(f, "{}({})", indent, err),
  513. Ok(ip_packet) => {
  514. match Repr::parse(&ip_packet, &checksum_caps) {
  515. Err(_) => return Ok(()),
  516. Ok(ip_repr) => {
  517. write!(f, "{}{}", indent, ip_repr)?;
  518. format_checksum(f, ip_packet.verify_checksum())?;
  519. (ip_repr, ip_packet.payload())
  520. }
  521. }
  522. }
  523. };
  524. pretty_print_ip_payload(f, indent, ip_repr, payload)
  525. }
  526. }
  527. #[cfg(test)]
  528. mod test {
  529. use super::*;
  530. static PACKET_BYTES: [u8; 30] =
  531. [0x45, 0x00, 0x00, 0x1e,
  532. 0x01, 0x02, 0x62, 0x03,
  533. 0x1a, 0x01, 0xd5, 0x6e,
  534. 0x11, 0x12, 0x13, 0x14,
  535. 0x21, 0x22, 0x23, 0x24,
  536. 0xaa, 0x00, 0x00, 0x00,
  537. 0x00, 0x00, 0x00, 0x00,
  538. 0x00, 0xff];
  539. static PAYLOAD_BYTES: [u8; 10] =
  540. [0xaa, 0x00, 0x00, 0x00,
  541. 0x00, 0x00, 0x00, 0x00,
  542. 0x00, 0xff];
  543. #[test]
  544. fn test_deconstruct() {
  545. let packet = Packet::new(&PACKET_BYTES[..]);
  546. assert_eq!(packet.version(), 4);
  547. assert_eq!(packet.header_len(), 20);
  548. assert_eq!(packet.dscp(), 0);
  549. assert_eq!(packet.ecn(), 0);
  550. assert_eq!(packet.total_len(), 30);
  551. assert_eq!(packet.ident(), 0x102);
  552. assert_eq!(packet.more_frags(), true);
  553. assert_eq!(packet.dont_frag(), true);
  554. assert_eq!(packet.frag_offset(), 0x203 * 8);
  555. assert_eq!(packet.hop_limit(), 0x1a);
  556. assert_eq!(packet.protocol(), Protocol::Icmp);
  557. assert_eq!(packet.checksum(), 0xd56e);
  558. assert_eq!(packet.src_addr(), Address([0x11, 0x12, 0x13, 0x14]));
  559. assert_eq!(packet.dst_addr(), Address([0x21, 0x22, 0x23, 0x24]));
  560. assert_eq!(packet.verify_checksum(), true);
  561. assert_eq!(packet.payload(), &PAYLOAD_BYTES[..]);
  562. }
  563. #[test]
  564. fn test_construct() {
  565. let mut bytes = vec![0xa5; 30];
  566. let mut packet = Packet::new(&mut bytes);
  567. packet.set_version(4);
  568. packet.set_header_len(20);
  569. packet.clear_flags();
  570. packet.set_dscp(0);
  571. packet.set_ecn(0);
  572. packet.set_total_len(30);
  573. packet.set_ident(0x102);
  574. packet.set_more_frags(true);
  575. packet.set_dont_frag(true);
  576. packet.set_frag_offset(0x203 * 8);
  577. packet.set_hop_limit(0x1a);
  578. packet.set_protocol(Protocol::Icmp);
  579. packet.set_src_addr(Address([0x11, 0x12, 0x13, 0x14]));
  580. packet.set_dst_addr(Address([0x21, 0x22, 0x23, 0x24]));
  581. packet.fill_checksum();
  582. packet.payload_mut().copy_from_slice(&PAYLOAD_BYTES[..]);
  583. assert_eq!(&packet.into_inner()[..], &PACKET_BYTES[..]);
  584. }
  585. #[test]
  586. fn test_overlong() {
  587. let mut bytes = vec![];
  588. bytes.extend(&PACKET_BYTES[..]);
  589. bytes.push(0);
  590. assert_eq!(Packet::new(&bytes).payload().len(),
  591. PAYLOAD_BYTES.len());
  592. assert_eq!(Packet::new(&mut bytes).payload_mut().len(),
  593. PAYLOAD_BYTES.len());
  594. }
  595. #[test]
  596. fn test_total_len_overflow() {
  597. let mut bytes = vec![];
  598. bytes.extend(&PACKET_BYTES[..]);
  599. Packet::new(&mut bytes).set_total_len(128);
  600. assert_eq!(Packet::new_checked(&bytes).unwrap_err(),
  601. Error::Truncated);
  602. }
  603. static REPR_PACKET_BYTES: [u8; 24] =
  604. [0x45, 0x00, 0x00, 0x18,
  605. 0x00, 0x00, 0x40, 0x00,
  606. 0x40, 0x01, 0xd2, 0x79,
  607. 0x11, 0x12, 0x13, 0x14,
  608. 0x21, 0x22, 0x23, 0x24,
  609. 0xaa, 0x00, 0x00, 0xff];
  610. static REPR_PAYLOAD_BYTES: [u8; 4] =
  611. [0xaa, 0x00, 0x00, 0xff];
  612. fn packet_repr() -> Repr {
  613. Repr {
  614. src_addr: Address([0x11, 0x12, 0x13, 0x14]),
  615. dst_addr: Address([0x21, 0x22, 0x23, 0x24]),
  616. protocol: Protocol::Icmp,
  617. payload_len: 4,
  618. hop_limit: 64
  619. }
  620. }
  621. #[test]
  622. fn test_parse() {
  623. let packet = Packet::new(&REPR_PACKET_BYTES[..]);
  624. let repr = Repr::parse(&packet, &ChecksumCapabilities::default()).unwrap();
  625. assert_eq!(repr, packet_repr());
  626. }
  627. #[test]
  628. fn test_parse_bad_version() {
  629. let mut bytes = vec![0; 24];
  630. bytes.copy_from_slice(&REPR_PACKET_BYTES[..]);
  631. let mut packet = Packet::new(&mut bytes);
  632. packet.set_version(6);
  633. packet.fill_checksum();
  634. let packet = Packet::new(&*packet.into_inner());
  635. assert_eq!(Repr::parse(&packet, &ChecksumCapabilities::default()), Err(Error::Malformed));
  636. }
  637. #[test]
  638. fn test_parse_total_len_underflow() {
  639. let mut bytes = vec![0; 24];
  640. bytes.copy_from_slice(&REPR_PACKET_BYTES[..]);
  641. let mut packet = Packet::new(&mut bytes);
  642. packet.set_total_len(10);
  643. packet.fill_checksum();
  644. let packet = Packet::new(&*packet.into_inner());
  645. assert_eq!(Repr::parse(&packet, &ChecksumCapabilities::default()), Err(Error::Malformed));
  646. }
  647. #[test]
  648. fn test_emit() {
  649. let repr = packet_repr();
  650. let mut bytes = vec![0xa5; repr.buffer_len() + REPR_PAYLOAD_BYTES.len()];
  651. let mut packet = Packet::new(&mut bytes);
  652. repr.emit(&mut packet, &ChecksumCapabilities::default());
  653. packet.payload_mut().copy_from_slice(&REPR_PAYLOAD_BYTES);
  654. assert_eq!(&packet.into_inner()[..], &REPR_PACKET_BYTES[..]);
  655. }
  656. #[test]
  657. fn test_unspecified() {
  658. assert!(Address::UNSPECIFIED.is_unspecified());
  659. assert!(!Address::UNSPECIFIED.is_broadcast());
  660. assert!(!Address::UNSPECIFIED.is_multicast());
  661. assert!(!Address::UNSPECIFIED.is_link_local());
  662. assert!(!Address::UNSPECIFIED.is_loopback());
  663. }
  664. #[test]
  665. fn test_broadcast() {
  666. assert!(!Address::BROADCAST.is_unspecified());
  667. assert!(Address::BROADCAST.is_broadcast());
  668. assert!(!Address::BROADCAST.is_multicast());
  669. assert!(!Address::BROADCAST.is_link_local());
  670. assert!(!Address::BROADCAST.is_loopback());
  671. }
  672. #[test]
  673. fn test_cidr() {
  674. let cidr = Cidr::new(Address::new(192, 168, 1, 10), 24);
  675. let inside_subnet = [
  676. [192, 168, 1, 0], [192, 168, 1, 1],
  677. [192, 168, 1, 2], [192, 168, 1, 10],
  678. [192, 168, 1, 127], [192, 168, 1, 255],
  679. ];
  680. let outside_subnet = [
  681. [192, 168, 0, 0], [127, 0, 0, 1],
  682. [192, 168, 2, 0], [192, 168, 0, 255],
  683. [ 0, 0, 0, 0], [255, 255, 255, 255],
  684. ];
  685. let subnets = [
  686. ([192, 168, 1, 0], 32),
  687. ([192, 168, 1, 255], 24),
  688. ([192, 168, 1, 10], 30),
  689. ];
  690. let not_subnets = [
  691. ([192, 168, 1, 10], 23),
  692. ([127, 0, 0, 1], 8),
  693. ([192, 168, 1, 0], 0),
  694. ([192, 168, 0, 255], 32),
  695. ];
  696. for addr in inside_subnet.iter().map(|a| Address::from_bytes(a)) {
  697. assert!(cidr.contains_addr(&addr));
  698. }
  699. for addr in outside_subnet.iter().map(|a| Address::from_bytes(a)) {
  700. assert!(!cidr.contains_addr(&addr));
  701. }
  702. for subnet in subnets.iter().map(
  703. |&(a, p)| Cidr::new(Address::new(a[0], a[1], a[2], a[3]), p)) {
  704. assert!(cidr.contains_subnet(&subnet));
  705. }
  706. for subnet in not_subnets.iter().map(
  707. |&(a, p)| Cidr::new(Address::new(a[0], a[1], a[2], a[3]), p)) {
  708. assert!(!cidr.contains_subnet(&subnet));
  709. }
  710. let cidr_without_prefix = Cidr::new(cidr.address(), 0);
  711. assert!(cidr_without_prefix.contains_addr(&Address::new(127, 0, 0, 1)));
  712. }
  713. }