ipv4.rs 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831
  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. // Total length may not be less than header length.
  420. if packet.total_len() < packet.header_len() as u16 { return Err(Error::Malformed) }
  421. // Since the packet is not fragmented, it must include the entire payload.
  422. let payload_len = packet.total_len() as usize - packet.header_len() as usize;
  423. if packet.payload().len() < payload_len { return Err(Error::Truncated) }
  424. // All DSCP values are acceptable, since they are of no concern to receiving endpoint.
  425. // All ECN values are acceptable, since ECN requires opt-in from both endpoints.
  426. // All TTL values are acceptable, since we do not perform routing.
  427. Ok(Repr {
  428. src_addr: packet.src_addr(),
  429. dst_addr: packet.dst_addr(),
  430. protocol: packet.protocol(),
  431. payload_len: payload_len,
  432. hop_limit: packet.hop_limit()
  433. })
  434. }
  435. /// Return the length of a header that will be emitted from this high-level representation.
  436. pub fn buffer_len(&self) -> usize {
  437. // We never emit any options.
  438. field::DST_ADDR.end
  439. }
  440. /// Emit a high-level representation into an Internet Protocol version 4 packet.
  441. pub fn emit<T: AsRef<[u8]> + AsMut<[u8]>>(&self, packet: &mut Packet<T>, checksum_caps: &ChecksumCapabilities) {
  442. packet.set_version(4);
  443. packet.set_header_len(field::DST_ADDR.end as u8);
  444. packet.set_dscp(0);
  445. packet.set_ecn(0);
  446. let total_len = packet.header_len() as u16 + self.payload_len as u16;
  447. packet.set_total_len(total_len);
  448. packet.set_ident(0);
  449. packet.clear_flags();
  450. packet.set_more_frags(false);
  451. packet.set_dont_frag(true);
  452. packet.set_frag_offset(0);
  453. packet.set_hop_limit(self.hop_limit);
  454. packet.set_protocol(self.protocol);
  455. packet.set_src_addr(self.src_addr);
  456. packet.set_dst_addr(self.dst_addr);
  457. if checksum_caps.ipv4.tx() {
  458. packet.fill_checksum();
  459. } else {
  460. // make sure we get a consistently zeroed checksum,
  461. // since implementations might rely on it
  462. packet.set_checksum(0);
  463. }
  464. }
  465. }
  466. impl<'a, T: AsRef<[u8]> + ?Sized> fmt::Display for Packet<&'a T> {
  467. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  468. match Repr::parse(self, &ChecksumCapabilities::ignored()) {
  469. Ok(repr) => write!(f, "{}", repr),
  470. Err(err) => {
  471. write!(f, "IPv4 ({})", err)?;
  472. write!(f, " src={} dst={} proto={} hop_limit={}",
  473. self.src_addr(), self.dst_addr(), self.protocol(), self.hop_limit())?;
  474. if self.version() != 4 {
  475. write!(f, " ver={}", self.version())?;
  476. }
  477. if self.header_len() != 20 {
  478. write!(f, " hlen={}", self.header_len())?;
  479. }
  480. if self.dscp() != 0 {
  481. write!(f, " dscp={}", self.dscp())?;
  482. }
  483. if self.ecn() != 0 {
  484. write!(f, " ecn={}", self.ecn())?;
  485. }
  486. write!(f, " tlen={}", self.total_len())?;
  487. if self.dont_frag() {
  488. write!(f, " df")?;
  489. }
  490. if self.more_frags() {
  491. write!(f, " mf")?;
  492. }
  493. if self.frag_offset() != 0 {
  494. write!(f, " off={}", self.frag_offset())?;
  495. }
  496. if self.more_frags() || self.frag_offset() != 0 {
  497. write!(f, " id={}", self.ident())?;
  498. }
  499. Ok(())
  500. }
  501. }
  502. }
  503. }
  504. impl fmt::Display for Repr {
  505. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  506. write!(f, "IPv4 src={} dst={} proto={}",
  507. self.src_addr, self.dst_addr, self.protocol)
  508. }
  509. }
  510. use super::pretty_print::{PrettyPrint, PrettyIndent};
  511. impl<T: AsRef<[u8]>> PrettyPrint for Packet<T> {
  512. fn pretty_print(buffer: &AsRef<[u8]>, f: &mut fmt::Formatter,
  513. indent: &mut PrettyIndent) -> fmt::Result {
  514. use wire::ip::checksum::format_checksum;
  515. let checksum_caps = ChecksumCapabilities::ignored();
  516. let (ip_repr, payload) = match Packet::new_checked(buffer) {
  517. Err(err) => return write!(f, "{}({})", indent, err),
  518. Ok(ip_packet) => {
  519. match Repr::parse(&ip_packet, &checksum_caps) {
  520. Err(_) => return Ok(()),
  521. Ok(ip_repr) => {
  522. write!(f, "{}{}", indent, ip_repr)?;
  523. format_checksum(f, ip_packet.verify_checksum())?;
  524. (ip_repr, ip_packet.payload())
  525. }
  526. }
  527. }
  528. };
  529. pretty_print_ip_payload(f, indent, ip_repr, payload)
  530. }
  531. }
  532. #[cfg(test)]
  533. mod test {
  534. use super::*;
  535. static PACKET_BYTES: [u8; 30] =
  536. [0x45, 0x00, 0x00, 0x1e,
  537. 0x01, 0x02, 0x62, 0x03,
  538. 0x1a, 0x01, 0xd5, 0x6e,
  539. 0x11, 0x12, 0x13, 0x14,
  540. 0x21, 0x22, 0x23, 0x24,
  541. 0xaa, 0x00, 0x00, 0x00,
  542. 0x00, 0x00, 0x00, 0x00,
  543. 0x00, 0xff];
  544. static PAYLOAD_BYTES: [u8; 10] =
  545. [0xaa, 0x00, 0x00, 0x00,
  546. 0x00, 0x00, 0x00, 0x00,
  547. 0x00, 0xff];
  548. #[test]
  549. fn test_deconstruct() {
  550. let packet = Packet::new(&PACKET_BYTES[..]);
  551. assert_eq!(packet.version(), 4);
  552. assert_eq!(packet.header_len(), 20);
  553. assert_eq!(packet.dscp(), 0);
  554. assert_eq!(packet.ecn(), 0);
  555. assert_eq!(packet.total_len(), 30);
  556. assert_eq!(packet.ident(), 0x102);
  557. assert_eq!(packet.more_frags(), true);
  558. assert_eq!(packet.dont_frag(), true);
  559. assert_eq!(packet.frag_offset(), 0x203 * 8);
  560. assert_eq!(packet.hop_limit(), 0x1a);
  561. assert_eq!(packet.protocol(), Protocol::Icmp);
  562. assert_eq!(packet.checksum(), 0xd56e);
  563. assert_eq!(packet.src_addr(), Address([0x11, 0x12, 0x13, 0x14]));
  564. assert_eq!(packet.dst_addr(), Address([0x21, 0x22, 0x23, 0x24]));
  565. assert_eq!(packet.verify_checksum(), true);
  566. assert_eq!(packet.payload(), &PAYLOAD_BYTES[..]);
  567. }
  568. #[test]
  569. fn test_construct() {
  570. let mut bytes = vec![0xa5; 30];
  571. let mut packet = Packet::new(&mut bytes);
  572. packet.set_version(4);
  573. packet.set_header_len(20);
  574. packet.clear_flags();
  575. packet.set_dscp(0);
  576. packet.set_ecn(0);
  577. packet.set_total_len(30);
  578. packet.set_ident(0x102);
  579. packet.set_more_frags(true);
  580. packet.set_dont_frag(true);
  581. packet.set_frag_offset(0x203 * 8);
  582. packet.set_hop_limit(0x1a);
  583. packet.set_protocol(Protocol::Icmp);
  584. packet.set_src_addr(Address([0x11, 0x12, 0x13, 0x14]));
  585. packet.set_dst_addr(Address([0x21, 0x22, 0x23, 0x24]));
  586. packet.fill_checksum();
  587. packet.payload_mut().copy_from_slice(&PAYLOAD_BYTES[..]);
  588. assert_eq!(&packet.into_inner()[..], &PACKET_BYTES[..]);
  589. }
  590. #[test]
  591. fn test_overlong() {
  592. let mut bytes = vec![];
  593. bytes.extend(&PACKET_BYTES[..]);
  594. bytes.push(0);
  595. assert_eq!(Packet::new(&bytes).payload().len(),
  596. PAYLOAD_BYTES.len());
  597. assert_eq!(Packet::new(&mut bytes).payload_mut().len(),
  598. PAYLOAD_BYTES.len());
  599. }
  600. #[test]
  601. fn test_total_len_overflow() {
  602. let mut bytes = vec![];
  603. bytes.extend(&PACKET_BYTES[..]);
  604. Packet::new(&mut bytes).set_total_len(128);
  605. assert_eq!(Packet::new_checked(&bytes).unwrap_err(),
  606. Error::Truncated);
  607. }
  608. static REPR_PACKET_BYTES: [u8; 24] =
  609. [0x45, 0x00, 0x00, 0x18,
  610. 0x00, 0x00, 0x40, 0x00,
  611. 0x40, 0x01, 0xd2, 0x79,
  612. 0x11, 0x12, 0x13, 0x14,
  613. 0x21, 0x22, 0x23, 0x24,
  614. 0xaa, 0x00, 0x00, 0xff];
  615. static REPR_PAYLOAD_BYTES: [u8; 4] =
  616. [0xaa, 0x00, 0x00, 0xff];
  617. fn packet_repr() -> Repr {
  618. Repr {
  619. src_addr: Address([0x11, 0x12, 0x13, 0x14]),
  620. dst_addr: Address([0x21, 0x22, 0x23, 0x24]),
  621. protocol: Protocol::Icmp,
  622. payload_len: 4,
  623. hop_limit: 64
  624. }
  625. }
  626. #[test]
  627. fn test_parse() {
  628. let packet = Packet::new(&REPR_PACKET_BYTES[..]);
  629. let repr = Repr::parse(&packet, &ChecksumCapabilities::default()).unwrap();
  630. assert_eq!(repr, packet_repr());
  631. }
  632. #[test]
  633. fn test_parse_bad_version() {
  634. let mut bytes = vec![0; 24];
  635. bytes.copy_from_slice(&REPR_PACKET_BYTES[..]);
  636. let mut packet = Packet::new(&mut bytes);
  637. packet.set_version(6);
  638. packet.fill_checksum();
  639. let packet = Packet::new(&*packet.into_inner());
  640. assert_eq!(Repr::parse(&packet, &ChecksumCapabilities::default()), Err(Error::Malformed));
  641. }
  642. #[test]
  643. fn test_parse_total_len_underflow() {
  644. let mut bytes = vec![0; 24];
  645. bytes.copy_from_slice(&REPR_PACKET_BYTES[..]);
  646. let mut packet = Packet::new(&mut bytes);
  647. packet.set_total_len(10);
  648. packet.fill_checksum();
  649. let packet = Packet::new(&*packet.into_inner());
  650. assert_eq!(Repr::parse(&packet, &ChecksumCapabilities::default()), Err(Error::Malformed));
  651. }
  652. #[test]
  653. fn test_parse_total_len_less_than_header_len() {
  654. let mut bytes = vec![0; 40];
  655. bytes[0] = 0x09;
  656. assert_eq!(Packet::new_checked(&mut bytes), Err(Error::Malformed));
  657. }
  658. #[test]
  659. fn test_emit() {
  660. let repr = packet_repr();
  661. let mut bytes = vec![0xa5; repr.buffer_len() + REPR_PAYLOAD_BYTES.len()];
  662. let mut packet = Packet::new(&mut bytes);
  663. repr.emit(&mut packet, &ChecksumCapabilities::default());
  664. packet.payload_mut().copy_from_slice(&REPR_PAYLOAD_BYTES);
  665. assert_eq!(&packet.into_inner()[..], &REPR_PACKET_BYTES[..]);
  666. }
  667. #[test]
  668. fn test_unspecified() {
  669. assert!(Address::UNSPECIFIED.is_unspecified());
  670. assert!(!Address::UNSPECIFIED.is_broadcast());
  671. assert!(!Address::UNSPECIFIED.is_multicast());
  672. assert!(!Address::UNSPECIFIED.is_link_local());
  673. assert!(!Address::UNSPECIFIED.is_loopback());
  674. }
  675. #[test]
  676. fn test_broadcast() {
  677. assert!(!Address::BROADCAST.is_unspecified());
  678. assert!(Address::BROADCAST.is_broadcast());
  679. assert!(!Address::BROADCAST.is_multicast());
  680. assert!(!Address::BROADCAST.is_link_local());
  681. assert!(!Address::BROADCAST.is_loopback());
  682. }
  683. #[test]
  684. fn test_cidr() {
  685. let cidr = Cidr::new(Address::new(192, 168, 1, 10), 24);
  686. let inside_subnet = [
  687. [192, 168, 1, 0], [192, 168, 1, 1],
  688. [192, 168, 1, 2], [192, 168, 1, 10],
  689. [192, 168, 1, 127], [192, 168, 1, 255],
  690. ];
  691. let outside_subnet = [
  692. [192, 168, 0, 0], [127, 0, 0, 1],
  693. [192, 168, 2, 0], [192, 168, 0, 255],
  694. [ 0, 0, 0, 0], [255, 255, 255, 255],
  695. ];
  696. let subnets = [
  697. ([192, 168, 1, 0], 32),
  698. ([192, 168, 1, 255], 24),
  699. ([192, 168, 1, 10], 30),
  700. ];
  701. let not_subnets = [
  702. ([192, 168, 1, 10], 23),
  703. ([127, 0, 0, 1], 8),
  704. ([192, 168, 1, 0], 0),
  705. ([192, 168, 0, 255], 32),
  706. ];
  707. for addr in inside_subnet.iter().map(|a| Address::from_bytes(a)) {
  708. assert!(cidr.contains_addr(&addr));
  709. }
  710. for addr in outside_subnet.iter().map(|a| Address::from_bytes(a)) {
  711. assert!(!cidr.contains_addr(&addr));
  712. }
  713. for subnet in subnets.iter().map(
  714. |&(a, p)| Cidr::new(Address::new(a[0], a[1], a[2], a[3]), p)) {
  715. assert!(cidr.contains_subnet(&subnet));
  716. }
  717. for subnet in not_subnets.iter().map(
  718. |&(a, p)| Cidr::new(Address::new(a[0], a[1], a[2], a[3]), p)) {
  719. assert!(!cidr.contains_subnet(&subnet));
  720. }
  721. let cidr_without_prefix = Cidr::new(cidr.address(), 0);
  722. assert!(cidr_without_prefix.contains_addr(&Address::new(127, 0, 0, 1)));
  723. }
  724. }