ipv4.rs 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137
  1. use byteorder::{ByteOrder, NetworkEndian};
  2. use core::fmt;
  3. use crate::phy::ChecksumCapabilities;
  4. use crate::wire::ip::{checksum, pretty_print_ip_payload};
  5. use crate::{Error, Result};
  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. /// All multicast-capable nodes
  29. pub const MULTICAST_ALL_SYSTEMS: Address = Address([224, 0, 0, 1]);
  30. /// All multicast-capable routers
  31. pub const MULTICAST_ALL_ROUTERS: Address = Address([224, 0, 0, 2]);
  32. /// Construct an IPv4 address from parts.
  33. pub const fn new(a0: u8, a1: u8, a2: u8, a3: u8) -> Address {
  34. Address([a0, a1, a2, a3])
  35. }
  36. /// Construct an IPv4 address from a sequence of octets, in big-endian.
  37. ///
  38. /// # Panics
  39. /// The function panics if `data` is not four octets long.
  40. pub fn from_bytes(data: &[u8]) -> Address {
  41. let mut bytes = [0; 4];
  42. bytes.copy_from_slice(data);
  43. Address(bytes)
  44. }
  45. /// Return an IPv4 address as a sequence of octets, in big-endian.
  46. pub fn as_bytes(&self) -> &[u8] {
  47. &self.0
  48. }
  49. /// Query whether the address is an unicast address.
  50. pub fn is_unicast(&self) -> bool {
  51. !(self.is_broadcast() || self.is_multicast() || self.is_unspecified())
  52. }
  53. /// Query whether the address is the broadcast address.
  54. pub fn is_broadcast(&self) -> bool {
  55. self.0[0..4] == [255; 4]
  56. }
  57. /// Query whether the address is a multicast address.
  58. pub const fn is_multicast(&self) -> bool {
  59. self.0[0] & 0xf0 == 224
  60. }
  61. /// Query whether the address falls into the "unspecified" range.
  62. pub const fn is_unspecified(&self) -> bool {
  63. self.0[0] == 0
  64. }
  65. /// Query whether the address falls into the "link-local" range.
  66. pub fn is_link_local(&self) -> bool {
  67. self.0[0..2] == [169, 254]
  68. }
  69. /// Query whether the address falls into the "loopback" range.
  70. pub const fn is_loopback(&self) -> bool {
  71. self.0[0] == 127
  72. }
  73. }
  74. #[cfg(feature = "std")]
  75. impl From<::std::net::Ipv4Addr> for Address {
  76. fn from(x: ::std::net::Ipv4Addr) -> Address {
  77. Address(x.octets())
  78. }
  79. }
  80. #[cfg(feature = "std")]
  81. impl From<Address> for ::std::net::Ipv4Addr {
  82. fn from(Address(x): Address) -> ::std::net::Ipv4Addr {
  83. x.into()
  84. }
  85. }
  86. impl fmt::Display for Address {
  87. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  88. let bytes = self.0;
  89. write!(f, "{}.{}.{}.{}", bytes[0], bytes[1], bytes[2], bytes[3])
  90. }
  91. }
  92. #[cfg(feature = "defmt")]
  93. impl defmt::Format for Address {
  94. fn format(&self, f: defmt::Formatter) {
  95. defmt::write!(
  96. f,
  97. "{=u8}.{=u8}.{=u8}.{=u8}",
  98. self.0[0],
  99. self.0[1],
  100. self.0[2],
  101. self.0[3]
  102. )
  103. }
  104. }
  105. /// A specification of an IPv4 CIDR block, containing an address and a variable-length
  106. /// subnet masking prefix length.
  107. #[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default)]
  108. pub struct Cidr {
  109. address: Address,
  110. prefix_len: u8,
  111. }
  112. impl Cidr {
  113. /// Create an IPv4 CIDR block from the given address and prefix length.
  114. ///
  115. /// # Panics
  116. /// This function panics if the prefix length is larger than 32.
  117. #[allow(clippy::no_effect)]
  118. pub const fn new(address: Address, prefix_len: u8) -> Cidr {
  119. // Replace with const panic (or assert) when stabilized
  120. // see: https://github.com/rust-lang/rust/issues/51999
  121. ["Prefix length should be <= 32"][(prefix_len > 32) as usize];
  122. Cidr {
  123. address,
  124. prefix_len,
  125. }
  126. }
  127. /// Create an IPv4 CIDR block from the given address and network mask.
  128. pub fn from_netmask(addr: Address, netmask: Address) -> Result<Cidr> {
  129. let netmask = NetworkEndian::read_u32(&netmask.0[..]);
  130. if netmask.leading_zeros() == 0 && netmask.trailing_zeros() == netmask.count_zeros() {
  131. Ok(Cidr {
  132. address: addr,
  133. prefix_len: netmask.count_ones() as u8,
  134. })
  135. } else {
  136. Err(Error::Illegal)
  137. }
  138. }
  139. /// Return the address of this IPv4 CIDR block.
  140. pub const fn address(&self) -> Address {
  141. self.address
  142. }
  143. /// Return the prefix length of this IPv4 CIDR block.
  144. pub const fn prefix_len(&self) -> u8 {
  145. self.prefix_len
  146. }
  147. /// Return the network mask of this IPv4 CIDR.
  148. pub fn netmask(&self) -> Address {
  149. if self.prefix_len == 0 {
  150. return Address([0, 0, 0, 0]);
  151. }
  152. let number = 0xffffffffu32 << (32 - self.prefix_len);
  153. let data = [
  154. ((number >> 24) & 0xff) as u8,
  155. ((number >> 16) & 0xff) as u8,
  156. ((number >> 8) & 0xff) as u8,
  157. ((number >> 0) & 0xff) as u8,
  158. ];
  159. Address(data)
  160. }
  161. /// Return the broadcast address of this IPv4 CIDR.
  162. pub fn broadcast(&self) -> Option<Address> {
  163. let network = self.network();
  164. if network.prefix_len == 31 || network.prefix_len == 32 {
  165. return None;
  166. }
  167. let network_number = NetworkEndian::read_u32(&network.address.0[..]);
  168. let number = network_number | 0xffffffffu32 >> network.prefix_len;
  169. let data = [
  170. ((number >> 24) & 0xff) as u8,
  171. ((number >> 16) & 0xff) as u8,
  172. ((number >> 8) & 0xff) as u8,
  173. ((number >> 0) & 0xff) as u8,
  174. ];
  175. Some(Address(data))
  176. }
  177. /// Return the network block of this IPv4 CIDR.
  178. pub fn network(&self) -> Cidr {
  179. let mask = self.netmask().0;
  180. let network = [
  181. self.address.0[0] & mask[0],
  182. self.address.0[1] & mask[1],
  183. self.address.0[2] & mask[2],
  184. self.address.0[3] & mask[3],
  185. ];
  186. Cidr {
  187. address: Address(network),
  188. prefix_len: self.prefix_len,
  189. }
  190. }
  191. /// Query whether the subnetwork described by this IPv4 CIDR block contains
  192. /// the given address.
  193. pub fn contains_addr(&self, addr: &Address) -> bool {
  194. // right shift by 32 is not legal
  195. if self.prefix_len == 0 {
  196. return true;
  197. }
  198. let shift = 32 - self.prefix_len;
  199. let self_prefix = NetworkEndian::read_u32(self.address.as_bytes()) >> shift;
  200. let addr_prefix = NetworkEndian::read_u32(addr.as_bytes()) >> shift;
  201. self_prefix == addr_prefix
  202. }
  203. /// Query whether the subnetwork described by this IPv4 CIDR block contains
  204. /// the subnetwork described by the given IPv4 CIDR block.
  205. pub fn contains_subnet(&self, subnet: &Cidr) -> bool {
  206. self.prefix_len <= subnet.prefix_len && self.contains_addr(&subnet.address)
  207. }
  208. }
  209. impl fmt::Display for Cidr {
  210. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  211. write!(f, "{}/{}", self.address, self.prefix_len)
  212. }
  213. }
  214. #[cfg(feature = "defmt")]
  215. impl defmt::Format for Cidr {
  216. fn format(&self, f: defmt::Formatter) {
  217. defmt::write!(f, "{:?}/{=u8}", self.address, self.prefix_len);
  218. }
  219. }
  220. /// A read/write wrapper around an Internet Protocol version 4 packet buffer.
  221. #[derive(Debug, PartialEq, Clone)]
  222. #[cfg_attr(feature = "defmt", derive(defmt::Format))]
  223. pub struct Packet<T: AsRef<[u8]>> {
  224. buffer: T,
  225. }
  226. mod field {
  227. use crate::wire::field::*;
  228. pub const VER_IHL: usize = 0;
  229. pub const DSCP_ECN: usize = 1;
  230. pub const LENGTH: Field = 2..4;
  231. pub const IDENT: Field = 4..6;
  232. pub const FLG_OFF: Field = 6..8;
  233. pub const TTL: usize = 8;
  234. pub const PROTOCOL: usize = 9;
  235. pub const CHECKSUM: Field = 10..12;
  236. pub const SRC_ADDR: Field = 12..16;
  237. pub const DST_ADDR: Field = 16..20;
  238. }
  239. pub const HEADER_LEN: usize = field::DST_ADDR.end;
  240. impl<T: AsRef<[u8]>> Packet<T> {
  241. /// Imbue a raw octet buffer with IPv4 packet structure.
  242. pub fn new_unchecked(buffer: T) -> Packet<T> {
  243. Packet { buffer }
  244. }
  245. /// Shorthand for a combination of [new_unchecked] and [check_len].
  246. ///
  247. /// [new_unchecked]: #method.new_unchecked
  248. /// [check_len]: #method.check_len
  249. pub fn new_checked(buffer: T) -> Result<Packet<T>> {
  250. let packet = Self::new_unchecked(buffer);
  251. packet.check_len()?;
  252. Ok(packet)
  253. }
  254. /// Ensure that no accessor method will panic if called.
  255. /// Returns `Err(Error::Truncated)` if the buffer is too short.
  256. /// Returns `Err(Error::Malformed)` if the header length is greater
  257. /// than total length.
  258. ///
  259. /// The result of this check is invalidated by calling [set_header_len]
  260. /// and [set_total_len].
  261. ///
  262. /// [set_header_len]: #method.set_header_len
  263. /// [set_total_len]: #method.set_total_len
  264. #[allow(clippy::if_same_then_else)]
  265. pub fn check_len(&self) -> Result<()> {
  266. let len = self.buffer.as_ref().len();
  267. if len < field::DST_ADDR.end {
  268. Err(Error::Truncated)
  269. } else if len < self.header_len() as usize {
  270. Err(Error::Truncated)
  271. } else if self.header_len() as u16 > self.total_len() {
  272. Err(Error::Malformed)
  273. } else if len < self.total_len() as usize {
  274. Err(Error::Truncated)
  275. } else {
  276. Ok(())
  277. }
  278. }
  279. /// Consume the packet, returning the underlying buffer.
  280. pub fn into_inner(self) -> T {
  281. self.buffer
  282. }
  283. /// Return the version field.
  284. #[inline]
  285. pub fn version(&self) -> u8 {
  286. let data = self.buffer.as_ref();
  287. data[field::VER_IHL] >> 4
  288. }
  289. /// Return the header length, in octets.
  290. #[inline]
  291. pub fn header_len(&self) -> u8 {
  292. let data = self.buffer.as_ref();
  293. (data[field::VER_IHL] & 0x0f) * 4
  294. }
  295. /// Return the Differential Services Code Point field.
  296. pub fn dscp(&self) -> u8 {
  297. let data = self.buffer.as_ref();
  298. data[field::DSCP_ECN] >> 2
  299. }
  300. /// Return the Explicit Congestion Notification field.
  301. pub fn ecn(&self) -> u8 {
  302. let data = self.buffer.as_ref();
  303. data[field::DSCP_ECN] & 0x03
  304. }
  305. /// Return the total length field.
  306. #[inline]
  307. pub fn total_len(&self) -> u16 {
  308. let data = self.buffer.as_ref();
  309. NetworkEndian::read_u16(&data[field::LENGTH])
  310. }
  311. /// Return the fragment identification field.
  312. #[inline]
  313. pub fn ident(&self) -> u16 {
  314. let data = self.buffer.as_ref();
  315. NetworkEndian::read_u16(&data[field::IDENT])
  316. }
  317. /// Return the "don't fragment" flag.
  318. #[inline]
  319. pub fn dont_frag(&self) -> bool {
  320. let data = self.buffer.as_ref();
  321. NetworkEndian::read_u16(&data[field::FLG_OFF]) & 0x4000 != 0
  322. }
  323. /// Return the "more fragments" flag.
  324. #[inline]
  325. pub fn more_frags(&self) -> bool {
  326. let data = self.buffer.as_ref();
  327. NetworkEndian::read_u16(&data[field::FLG_OFF]) & 0x2000 != 0
  328. }
  329. /// Return the fragment offset, in octets.
  330. #[inline]
  331. pub fn frag_offset(&self) -> u16 {
  332. let data = self.buffer.as_ref();
  333. NetworkEndian::read_u16(&data[field::FLG_OFF]) << 3
  334. }
  335. /// Return the time to live field.
  336. #[inline]
  337. pub fn hop_limit(&self) -> u8 {
  338. let data = self.buffer.as_ref();
  339. data[field::TTL]
  340. }
  341. /// Return the next_header (protocol) field.
  342. #[inline]
  343. pub fn next_header(&self) -> Protocol {
  344. let data = self.buffer.as_ref();
  345. Protocol::from(data[field::PROTOCOL])
  346. }
  347. /// Return the header checksum field.
  348. #[inline]
  349. pub fn checksum(&self) -> u16 {
  350. let data = self.buffer.as_ref();
  351. NetworkEndian::read_u16(&data[field::CHECKSUM])
  352. }
  353. /// Return the source address field.
  354. #[inline]
  355. pub fn src_addr(&self) -> Address {
  356. let data = self.buffer.as_ref();
  357. Address::from_bytes(&data[field::SRC_ADDR])
  358. }
  359. /// Return the destination address field.
  360. #[inline]
  361. pub fn dst_addr(&self) -> Address {
  362. let data = self.buffer.as_ref();
  363. Address::from_bytes(&data[field::DST_ADDR])
  364. }
  365. /// Validate the header checksum.
  366. ///
  367. /// # Fuzzing
  368. /// This function always returns `true` when fuzzing.
  369. pub fn verify_checksum(&self) -> bool {
  370. if cfg!(fuzzing) {
  371. return true;
  372. }
  373. let data = self.buffer.as_ref();
  374. checksum::data(&data[..self.header_len() as usize]) == !0
  375. }
  376. }
  377. impl<'a, T: AsRef<[u8]> + ?Sized> Packet<&'a T> {
  378. /// Return a pointer to the payload.
  379. #[inline]
  380. pub fn payload(&self) -> &'a [u8] {
  381. let range = self.header_len() as usize..self.total_len() as usize;
  382. let data = self.buffer.as_ref();
  383. &data[range]
  384. }
  385. }
  386. impl<T: AsRef<[u8]> + AsMut<[u8]>> Packet<T> {
  387. /// Set the version field.
  388. #[inline]
  389. pub fn set_version(&mut self, value: u8) {
  390. let data = self.buffer.as_mut();
  391. data[field::VER_IHL] = (data[field::VER_IHL] & !0xf0) | (value << 4);
  392. }
  393. /// Set the header length, in octets.
  394. #[inline]
  395. pub fn set_header_len(&mut self, value: u8) {
  396. let data = self.buffer.as_mut();
  397. data[field::VER_IHL] = (data[field::VER_IHL] & !0x0f) | ((value / 4) & 0x0f);
  398. }
  399. /// Set the Differential Services Code Point field.
  400. pub fn set_dscp(&mut self, value: u8) {
  401. let data = self.buffer.as_mut();
  402. data[field::DSCP_ECN] = (data[field::DSCP_ECN] & !0xfc) | (value << 2)
  403. }
  404. /// Set the Explicit Congestion Notification field.
  405. pub fn set_ecn(&mut self, value: u8) {
  406. let data = self.buffer.as_mut();
  407. data[field::DSCP_ECN] = (data[field::DSCP_ECN] & !0x03) | (value & 0x03)
  408. }
  409. /// Set the total length field.
  410. #[inline]
  411. pub fn set_total_len(&mut self, value: u16) {
  412. let data = self.buffer.as_mut();
  413. NetworkEndian::write_u16(&mut data[field::LENGTH], value)
  414. }
  415. /// Set the fragment identification field.
  416. #[inline]
  417. pub fn set_ident(&mut self, value: u16) {
  418. let data = self.buffer.as_mut();
  419. NetworkEndian::write_u16(&mut data[field::IDENT], value)
  420. }
  421. /// Clear the entire flags field.
  422. #[inline]
  423. pub fn clear_flags(&mut self) {
  424. let data = self.buffer.as_mut();
  425. let raw = NetworkEndian::read_u16(&data[field::FLG_OFF]);
  426. let raw = raw & !0xe000;
  427. NetworkEndian::write_u16(&mut data[field::FLG_OFF], raw);
  428. }
  429. /// Set the "don't fragment" flag.
  430. #[inline]
  431. pub fn set_dont_frag(&mut self, value: bool) {
  432. let data = self.buffer.as_mut();
  433. let raw = NetworkEndian::read_u16(&data[field::FLG_OFF]);
  434. let raw = if value { raw | 0x4000 } else { raw & !0x4000 };
  435. NetworkEndian::write_u16(&mut data[field::FLG_OFF], raw);
  436. }
  437. /// Set the "more fragments" flag.
  438. #[inline]
  439. pub fn set_more_frags(&mut self, value: bool) {
  440. let data = self.buffer.as_mut();
  441. let raw = NetworkEndian::read_u16(&data[field::FLG_OFF]);
  442. let raw = if value { raw | 0x2000 } else { raw & !0x2000 };
  443. NetworkEndian::write_u16(&mut data[field::FLG_OFF], raw);
  444. }
  445. /// Set the fragment offset, in octets.
  446. #[inline]
  447. pub fn set_frag_offset(&mut self, value: u16) {
  448. let data = self.buffer.as_mut();
  449. let raw = NetworkEndian::read_u16(&data[field::FLG_OFF]);
  450. let raw = (raw & 0xe000) | (value >> 3);
  451. NetworkEndian::write_u16(&mut data[field::FLG_OFF], raw);
  452. }
  453. /// Set the time to live field.
  454. #[inline]
  455. pub fn set_hop_limit(&mut self, value: u8) {
  456. let data = self.buffer.as_mut();
  457. data[field::TTL] = value
  458. }
  459. /// Set the next header (protocol) field.
  460. #[inline]
  461. pub fn set_next_header(&mut self, value: Protocol) {
  462. let data = self.buffer.as_mut();
  463. data[field::PROTOCOL] = value.into()
  464. }
  465. /// Set the header checksum field.
  466. #[inline]
  467. pub fn set_checksum(&mut self, value: u16) {
  468. let data = self.buffer.as_mut();
  469. NetworkEndian::write_u16(&mut data[field::CHECKSUM], value)
  470. }
  471. /// Set the source address field.
  472. #[inline]
  473. pub fn set_src_addr(&mut self, value: Address) {
  474. let data = self.buffer.as_mut();
  475. data[field::SRC_ADDR].copy_from_slice(value.as_bytes())
  476. }
  477. /// Set the destination address field.
  478. #[inline]
  479. pub fn set_dst_addr(&mut self, value: Address) {
  480. let data = self.buffer.as_mut();
  481. data[field::DST_ADDR].copy_from_slice(value.as_bytes())
  482. }
  483. /// Compute and fill in the header checksum.
  484. pub fn fill_checksum(&mut self) {
  485. self.set_checksum(0);
  486. let checksum = {
  487. let data = self.buffer.as_ref();
  488. !checksum::data(&data[..self.header_len() as usize])
  489. };
  490. self.set_checksum(checksum)
  491. }
  492. /// Return a mutable pointer to the payload.
  493. #[inline]
  494. pub fn payload_mut(&mut self) -> &mut [u8] {
  495. let range = self.header_len() as usize..self.total_len() as usize;
  496. let data = self.buffer.as_mut();
  497. &mut data[range]
  498. }
  499. }
  500. impl<T: AsRef<[u8]>> AsRef<[u8]> for Packet<T> {
  501. fn as_ref(&self) -> &[u8] {
  502. self.buffer.as_ref()
  503. }
  504. }
  505. /// A high-level representation of an Internet Protocol version 4 packet header.
  506. #[derive(Debug, PartialEq, Eq, Clone, Copy)]
  507. #[cfg_attr(feature = "defmt", derive(defmt::Format))]
  508. pub struct Repr {
  509. pub src_addr: Address,
  510. pub dst_addr: Address,
  511. pub next_header: Protocol,
  512. pub payload_len: usize,
  513. pub hop_limit: u8,
  514. }
  515. impl Repr {
  516. /// Parse an Internet Protocol version 4 packet and return a high-level representation.
  517. pub fn parse<T: AsRef<[u8]> + ?Sized>(
  518. packet: &Packet<&T>,
  519. checksum_caps: &ChecksumCapabilities,
  520. ) -> Result<Repr> {
  521. // Version 4 is expected.
  522. if packet.version() != 4 {
  523. return Err(Error::Malformed);
  524. }
  525. // Valid checksum is expected.
  526. if checksum_caps.ipv4.rx() && !packet.verify_checksum() {
  527. return Err(Error::Checksum);
  528. }
  529. // We do not support fragmentation.
  530. if packet.more_frags() || packet.frag_offset() != 0 {
  531. return Err(Error::Fragmented);
  532. }
  533. // Since the packet is not fragmented, it must include the entire payload.
  534. let payload_len = packet.total_len() as usize - packet.header_len() as usize;
  535. if packet.payload().len() < payload_len {
  536. return Err(Error::Truncated);
  537. }
  538. // All DSCP values are acceptable, since they are of no concern to receiving endpoint.
  539. // All ECN values are acceptable, since ECN requires opt-in from both endpoints.
  540. // All TTL values are acceptable, since we do not perform routing.
  541. Ok(Repr {
  542. src_addr: packet.src_addr(),
  543. dst_addr: packet.dst_addr(),
  544. next_header: packet.next_header(),
  545. payload_len: payload_len,
  546. hop_limit: packet.hop_limit(),
  547. })
  548. }
  549. /// Return the length of a header that will be emitted from this high-level representation.
  550. pub fn buffer_len(&self) -> usize {
  551. // We never emit any options.
  552. field::DST_ADDR.end
  553. }
  554. /// Emit a high-level representation into an Internet Protocol version 4 packet.
  555. pub fn emit<T: AsRef<[u8]> + AsMut<[u8]>>(
  556. &self,
  557. packet: &mut Packet<T>,
  558. checksum_caps: &ChecksumCapabilities,
  559. ) {
  560. packet.set_version(4);
  561. packet.set_header_len(field::DST_ADDR.end as u8);
  562. packet.set_dscp(0);
  563. packet.set_ecn(0);
  564. let total_len = packet.header_len() as u16 + self.payload_len as u16;
  565. packet.set_total_len(total_len);
  566. packet.set_ident(0);
  567. packet.clear_flags();
  568. packet.set_more_frags(false);
  569. packet.set_dont_frag(true);
  570. packet.set_frag_offset(0);
  571. packet.set_hop_limit(self.hop_limit);
  572. packet.set_next_header(self.next_header);
  573. packet.set_src_addr(self.src_addr);
  574. packet.set_dst_addr(self.dst_addr);
  575. if checksum_caps.ipv4.tx() {
  576. packet.fill_checksum();
  577. } else {
  578. // make sure we get a consistently zeroed checksum,
  579. // since implementations might rely on it
  580. packet.set_checksum(0);
  581. }
  582. }
  583. }
  584. impl<'a, T: AsRef<[u8]> + ?Sized> fmt::Display for Packet<&'a T> {
  585. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  586. match Repr::parse(self, &ChecksumCapabilities::ignored()) {
  587. Ok(repr) => write!(f, "{}", repr),
  588. Err(err) => {
  589. write!(f, "IPv4 ({})", err)?;
  590. write!(
  591. f,
  592. " src={} dst={} proto={} hop_limit={}",
  593. self.src_addr(),
  594. self.dst_addr(),
  595. self.next_header(),
  596. self.hop_limit()
  597. )?;
  598. if self.version() != 4 {
  599. write!(f, " ver={}", self.version())?;
  600. }
  601. if self.header_len() != 20 {
  602. write!(f, " hlen={}", self.header_len())?;
  603. }
  604. if self.dscp() != 0 {
  605. write!(f, " dscp={}", self.dscp())?;
  606. }
  607. if self.ecn() != 0 {
  608. write!(f, " ecn={}", self.ecn())?;
  609. }
  610. write!(f, " tlen={}", self.total_len())?;
  611. if self.dont_frag() {
  612. write!(f, " df")?;
  613. }
  614. if self.more_frags() {
  615. write!(f, " mf")?;
  616. }
  617. if self.frag_offset() != 0 {
  618. write!(f, " off={}", self.frag_offset())?;
  619. }
  620. if self.more_frags() || self.frag_offset() != 0 {
  621. write!(f, " id={}", self.ident())?;
  622. }
  623. Ok(())
  624. }
  625. }
  626. }
  627. }
  628. impl fmt::Display for Repr {
  629. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  630. write!(
  631. f,
  632. "IPv4 src={} dst={} proto={}",
  633. self.src_addr, self.dst_addr, self.next_header
  634. )
  635. }
  636. }
  637. use crate::wire::pretty_print::{PrettyIndent, PrettyPrint};
  638. impl<T: AsRef<[u8]>> PrettyPrint for Packet<T> {
  639. fn pretty_print(
  640. buffer: &dyn AsRef<[u8]>,
  641. f: &mut fmt::Formatter,
  642. indent: &mut PrettyIndent,
  643. ) -> fmt::Result {
  644. use crate::wire::ip::checksum::format_checksum;
  645. let checksum_caps = ChecksumCapabilities::ignored();
  646. let (ip_repr, payload) = match Packet::new_checked(buffer) {
  647. Err(err) => return write!(f, "{}({})", indent, err),
  648. Ok(ip_packet) => match Repr::parse(&ip_packet, &checksum_caps) {
  649. Err(_) => return Ok(()),
  650. Ok(ip_repr) => {
  651. write!(f, "{}{}", indent, ip_repr)?;
  652. format_checksum(f, ip_packet.verify_checksum())?;
  653. (ip_repr, ip_packet.payload())
  654. }
  655. },
  656. };
  657. pretty_print_ip_payload(f, indent, ip_repr, payload)
  658. }
  659. }
  660. #[cfg(test)]
  661. mod test {
  662. use super::*;
  663. static PACKET_BYTES: [u8; 30] = [
  664. 0x45, 0x00, 0x00, 0x1e, 0x01, 0x02, 0x62, 0x03, 0x1a, 0x01, 0xd5, 0x6e, 0x11, 0x12, 0x13,
  665. 0x14, 0x21, 0x22, 0x23, 0x24, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
  666. ];
  667. static PAYLOAD_BYTES: [u8; 10] = [0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff];
  668. #[test]
  669. fn test_deconstruct() {
  670. let packet = Packet::new_unchecked(&PACKET_BYTES[..]);
  671. assert_eq!(packet.version(), 4);
  672. assert_eq!(packet.header_len(), 20);
  673. assert_eq!(packet.dscp(), 0);
  674. assert_eq!(packet.ecn(), 0);
  675. assert_eq!(packet.total_len(), 30);
  676. assert_eq!(packet.ident(), 0x102);
  677. assert!(packet.more_frags());
  678. assert!(packet.dont_frag());
  679. assert_eq!(packet.frag_offset(), 0x203 * 8);
  680. assert_eq!(packet.hop_limit(), 0x1a);
  681. assert_eq!(packet.next_header(), Protocol::Icmp);
  682. assert_eq!(packet.checksum(), 0xd56e);
  683. assert_eq!(packet.src_addr(), Address([0x11, 0x12, 0x13, 0x14]));
  684. assert_eq!(packet.dst_addr(), Address([0x21, 0x22, 0x23, 0x24]));
  685. assert!(packet.verify_checksum());
  686. assert_eq!(packet.payload(), &PAYLOAD_BYTES[..]);
  687. }
  688. #[test]
  689. fn test_construct() {
  690. let mut bytes = vec![0xa5; 30];
  691. let mut packet = Packet::new_unchecked(&mut bytes);
  692. packet.set_version(4);
  693. packet.set_header_len(20);
  694. packet.clear_flags();
  695. packet.set_dscp(0);
  696. packet.set_ecn(0);
  697. packet.set_total_len(30);
  698. packet.set_ident(0x102);
  699. packet.set_more_frags(true);
  700. packet.set_dont_frag(true);
  701. packet.set_frag_offset(0x203 * 8);
  702. packet.set_hop_limit(0x1a);
  703. packet.set_next_header(Protocol::Icmp);
  704. packet.set_src_addr(Address([0x11, 0x12, 0x13, 0x14]));
  705. packet.set_dst_addr(Address([0x21, 0x22, 0x23, 0x24]));
  706. packet.fill_checksum();
  707. packet.payload_mut().copy_from_slice(&PAYLOAD_BYTES[..]);
  708. assert_eq!(&packet.into_inner()[..], &PACKET_BYTES[..]);
  709. }
  710. #[test]
  711. fn test_overlong() {
  712. let mut bytes = vec![];
  713. bytes.extend(&PACKET_BYTES[..]);
  714. bytes.push(0);
  715. assert_eq!(
  716. Packet::new_unchecked(&bytes).payload().len(),
  717. PAYLOAD_BYTES.len()
  718. );
  719. assert_eq!(
  720. Packet::new_unchecked(&mut bytes).payload_mut().len(),
  721. PAYLOAD_BYTES.len()
  722. );
  723. }
  724. #[test]
  725. fn test_total_len_overflow() {
  726. let mut bytes = vec![];
  727. bytes.extend(&PACKET_BYTES[..]);
  728. Packet::new_unchecked(&mut bytes).set_total_len(128);
  729. assert_eq!(Packet::new_checked(&bytes).unwrap_err(), Error::Truncated);
  730. }
  731. static REPR_PACKET_BYTES: [u8; 24] = [
  732. 0x45, 0x00, 0x00, 0x18, 0x00, 0x00, 0x40, 0x00, 0x40, 0x01, 0xd2, 0x79, 0x11, 0x12, 0x13,
  733. 0x14, 0x21, 0x22, 0x23, 0x24, 0xaa, 0x00, 0x00, 0xff,
  734. ];
  735. static REPR_PAYLOAD_BYTES: [u8; 4] = [0xaa, 0x00, 0x00, 0xff];
  736. fn packet_repr() -> Repr {
  737. Repr {
  738. src_addr: Address([0x11, 0x12, 0x13, 0x14]),
  739. dst_addr: Address([0x21, 0x22, 0x23, 0x24]),
  740. next_header: Protocol::Icmp,
  741. payload_len: 4,
  742. hop_limit: 64,
  743. }
  744. }
  745. #[test]
  746. fn test_parse() {
  747. let packet = Packet::new_unchecked(&REPR_PACKET_BYTES[..]);
  748. let repr = Repr::parse(&packet, &ChecksumCapabilities::default()).unwrap();
  749. assert_eq!(repr, packet_repr());
  750. }
  751. #[test]
  752. fn test_parse_bad_version() {
  753. let mut bytes = vec![0; 24];
  754. bytes.copy_from_slice(&REPR_PACKET_BYTES[..]);
  755. let mut packet = Packet::new_unchecked(&mut bytes);
  756. packet.set_version(6);
  757. packet.fill_checksum();
  758. let packet = Packet::new_unchecked(&*packet.into_inner());
  759. assert_eq!(
  760. Repr::parse(&packet, &ChecksumCapabilities::default()),
  761. Err(Error::Malformed)
  762. );
  763. }
  764. #[test]
  765. fn test_parse_total_len_less_than_header_len() {
  766. let mut bytes = vec![0; 40];
  767. bytes[0] = 0x09;
  768. assert_eq!(Packet::new_checked(&mut bytes), Err(Error::Malformed));
  769. }
  770. #[test]
  771. fn test_emit() {
  772. let repr = packet_repr();
  773. let mut bytes = vec![0xa5; repr.buffer_len() + REPR_PAYLOAD_BYTES.len()];
  774. let mut packet = Packet::new_unchecked(&mut bytes);
  775. repr.emit(&mut packet, &ChecksumCapabilities::default());
  776. packet.payload_mut().copy_from_slice(&REPR_PAYLOAD_BYTES);
  777. assert_eq!(&packet.into_inner()[..], &REPR_PACKET_BYTES[..]);
  778. }
  779. #[test]
  780. fn test_unspecified() {
  781. assert!(Address::UNSPECIFIED.is_unspecified());
  782. assert!(!Address::UNSPECIFIED.is_broadcast());
  783. assert!(!Address::UNSPECIFIED.is_multicast());
  784. assert!(!Address::UNSPECIFIED.is_link_local());
  785. assert!(!Address::UNSPECIFIED.is_loopback());
  786. }
  787. #[test]
  788. fn test_broadcast() {
  789. assert!(!Address::BROADCAST.is_unspecified());
  790. assert!(Address::BROADCAST.is_broadcast());
  791. assert!(!Address::BROADCAST.is_multicast());
  792. assert!(!Address::BROADCAST.is_link_local());
  793. assert!(!Address::BROADCAST.is_loopback());
  794. }
  795. #[test]
  796. fn test_cidr() {
  797. let cidr = Cidr::new(Address::new(192, 168, 1, 10), 24);
  798. let inside_subnet = [
  799. [192, 168, 1, 0],
  800. [192, 168, 1, 1],
  801. [192, 168, 1, 2],
  802. [192, 168, 1, 10],
  803. [192, 168, 1, 127],
  804. [192, 168, 1, 255],
  805. ];
  806. let outside_subnet = [
  807. [192, 168, 0, 0],
  808. [127, 0, 0, 1],
  809. [192, 168, 2, 0],
  810. [192, 168, 0, 255],
  811. [0, 0, 0, 0],
  812. [255, 255, 255, 255],
  813. ];
  814. let subnets = [
  815. ([192, 168, 1, 0], 32),
  816. ([192, 168, 1, 255], 24),
  817. ([192, 168, 1, 10], 30),
  818. ];
  819. let not_subnets = [
  820. ([192, 168, 1, 10], 23),
  821. ([127, 0, 0, 1], 8),
  822. ([192, 168, 1, 0], 0),
  823. ([192, 168, 0, 255], 32),
  824. ];
  825. for addr in inside_subnet.iter().map(|a| Address::from_bytes(a)) {
  826. assert!(cidr.contains_addr(&addr));
  827. }
  828. for addr in outside_subnet.iter().map(|a| Address::from_bytes(a)) {
  829. assert!(!cidr.contains_addr(&addr));
  830. }
  831. for subnet in subnets
  832. .iter()
  833. .map(|&(a, p)| Cidr::new(Address::new(a[0], a[1], a[2], a[3]), p))
  834. {
  835. assert!(cidr.contains_subnet(&subnet));
  836. }
  837. for subnet in not_subnets
  838. .iter()
  839. .map(|&(a, p)| Cidr::new(Address::new(a[0], a[1], a[2], a[3]), p))
  840. {
  841. assert!(!cidr.contains_subnet(&subnet));
  842. }
  843. let cidr_without_prefix = Cidr::new(cidr.address(), 0);
  844. assert!(cidr_without_prefix.contains_addr(&Address::new(127, 0, 0, 1)));
  845. }
  846. #[test]
  847. fn test_cidr_from_netmask() {
  848. assert!(Cidr::from_netmask(Address([0, 0, 0, 0]), Address([1, 0, 2, 0])).is_err());
  849. assert!(Cidr::from_netmask(Address([0, 0, 0, 0]), Address([0, 0, 0, 0])).is_err());
  850. assert_eq!(
  851. Cidr::from_netmask(Address([0, 0, 0, 1]), Address([255, 255, 255, 0])).unwrap(),
  852. Cidr::new(Address([0, 0, 0, 1]), 24)
  853. );
  854. assert_eq!(
  855. Cidr::from_netmask(Address([192, 168, 0, 1]), Address([255, 255, 0, 0])).unwrap(),
  856. Cidr::new(Address([192, 168, 0, 1]), 16)
  857. );
  858. assert_eq!(
  859. Cidr::from_netmask(Address([172, 16, 0, 1]), Address([255, 240, 0, 0])).unwrap(),
  860. Cidr::new(Address([172, 16, 0, 1]), 12)
  861. );
  862. assert_eq!(
  863. Cidr::from_netmask(Address([255, 255, 255, 1]), Address([255, 255, 255, 0])).unwrap(),
  864. Cidr::new(Address([255, 255, 255, 1]), 24)
  865. );
  866. assert_eq!(
  867. Cidr::from_netmask(Address([255, 255, 255, 255]), Address([255, 255, 255, 255]))
  868. .unwrap(),
  869. Cidr::new(Address([255, 255, 255, 255]), 32)
  870. );
  871. }
  872. #[test]
  873. fn test_cidr_netmask() {
  874. assert_eq!(
  875. Cidr::new(Address([0, 0, 0, 0]), 0).netmask(),
  876. Address([0, 0, 0, 0])
  877. );
  878. assert_eq!(
  879. Cidr::new(Address([0, 0, 0, 1]), 24).netmask(),
  880. Address([255, 255, 255, 0])
  881. );
  882. assert_eq!(
  883. Cidr::new(Address([0, 0, 0, 0]), 32).netmask(),
  884. Address([255, 255, 255, 255])
  885. );
  886. assert_eq!(
  887. Cidr::new(Address([127, 0, 0, 0]), 8).netmask(),
  888. Address([255, 0, 0, 0])
  889. );
  890. assert_eq!(
  891. Cidr::new(Address([192, 168, 0, 0]), 16).netmask(),
  892. Address([255, 255, 0, 0])
  893. );
  894. assert_eq!(
  895. Cidr::new(Address([192, 168, 1, 1]), 16).netmask(),
  896. Address([255, 255, 0, 0])
  897. );
  898. assert_eq!(
  899. Cidr::new(Address([192, 168, 1, 1]), 17).netmask(),
  900. Address([255, 255, 128, 0])
  901. );
  902. assert_eq!(
  903. Cidr::new(Address([172, 16, 0, 0]), 12).netmask(),
  904. Address([255, 240, 0, 0])
  905. );
  906. assert_eq!(
  907. Cidr::new(Address([255, 255, 255, 1]), 24).netmask(),
  908. Address([255, 255, 255, 0])
  909. );
  910. assert_eq!(
  911. Cidr::new(Address([255, 255, 255, 255]), 32).netmask(),
  912. Address([255, 255, 255, 255])
  913. );
  914. }
  915. #[test]
  916. fn test_cidr_broadcast() {
  917. assert_eq!(
  918. Cidr::new(Address([0, 0, 0, 0]), 0).broadcast().unwrap(),
  919. Address([255, 255, 255, 255])
  920. );
  921. assert_eq!(
  922. Cidr::new(Address([0, 0, 0, 1]), 24).broadcast().unwrap(),
  923. Address([0, 0, 0, 255])
  924. );
  925. assert_eq!(Cidr::new(Address([0, 0, 0, 0]), 32).broadcast(), None);
  926. assert_eq!(
  927. Cidr::new(Address([127, 0, 0, 0]), 8).broadcast().unwrap(),
  928. Address([127, 255, 255, 255])
  929. );
  930. assert_eq!(
  931. Cidr::new(Address([192, 168, 0, 0]), 16)
  932. .broadcast()
  933. .unwrap(),
  934. Address([192, 168, 255, 255])
  935. );
  936. assert_eq!(
  937. Cidr::new(Address([192, 168, 1, 1]), 16)
  938. .broadcast()
  939. .unwrap(),
  940. Address([192, 168, 255, 255])
  941. );
  942. assert_eq!(
  943. Cidr::new(Address([192, 168, 1, 1]), 17)
  944. .broadcast()
  945. .unwrap(),
  946. Address([192, 168, 127, 255])
  947. );
  948. assert_eq!(
  949. Cidr::new(Address([172, 16, 0, 1]), 12).broadcast().unwrap(),
  950. Address([172, 31, 255, 255])
  951. );
  952. assert_eq!(
  953. Cidr::new(Address([255, 255, 255, 1]), 24)
  954. .broadcast()
  955. .unwrap(),
  956. Address([255, 255, 255, 255])
  957. );
  958. assert_eq!(
  959. Cidr::new(Address([255, 255, 255, 254]), 31).broadcast(),
  960. None
  961. );
  962. assert_eq!(
  963. Cidr::new(Address([255, 255, 255, 255]), 32).broadcast(),
  964. None
  965. );
  966. }
  967. #[test]
  968. fn test_cidr_network() {
  969. assert_eq!(
  970. Cidr::new(Address([0, 0, 0, 0]), 0).network(),
  971. Cidr::new(Address([0, 0, 0, 0]), 0)
  972. );
  973. assert_eq!(
  974. Cidr::new(Address([0, 0, 0, 1]), 24).network(),
  975. Cidr::new(Address([0, 0, 0, 0]), 24)
  976. );
  977. assert_eq!(
  978. Cidr::new(Address([0, 0, 0, 0]), 32).network(),
  979. Cidr::new(Address([0, 0, 0, 0]), 32)
  980. );
  981. assert_eq!(
  982. Cidr::new(Address([127, 0, 0, 0]), 8).network(),
  983. Cidr::new(Address([127, 0, 0, 0]), 8)
  984. );
  985. assert_eq!(
  986. Cidr::new(Address([192, 168, 0, 0]), 16).network(),
  987. Cidr::new(Address([192, 168, 0, 0]), 16)
  988. );
  989. assert_eq!(
  990. Cidr::new(Address([192, 168, 1, 1]), 16).network(),
  991. Cidr::new(Address([192, 168, 0, 0]), 16)
  992. );
  993. assert_eq!(
  994. Cidr::new(Address([192, 168, 1, 1]), 17).network(),
  995. Cidr::new(Address([192, 168, 0, 0]), 17)
  996. );
  997. assert_eq!(
  998. Cidr::new(Address([172, 16, 0, 1]), 12).network(),
  999. Cidr::new(Address([172, 16, 0, 0]), 12)
  1000. );
  1001. assert_eq!(
  1002. Cidr::new(Address([255, 255, 255, 1]), 24).network(),
  1003. Cidr::new(Address([255, 255, 255, 0]), 24)
  1004. );
  1005. assert_eq!(
  1006. Cidr::new(Address([255, 255, 255, 255]), 32).network(),
  1007. Cidr::new(Address([255, 255, 255, 255]), 32)
  1008. );
  1009. }
  1010. }