ipv4.rs 27 KB

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