ipv4.rs 34 KB

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