a.rs 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. use std::net::Ipv4Addr;
  2. use log::*;
  3. use crate::wire::*;
  4. /// An **A** record type, which contains an `Ipv4Address`.
  5. ///
  6. /// # References
  7. ///
  8. /// - [RFC 1035 §3.4.1](https://tools.ietf.org/html/rfc1035) — Domain Names,
  9. /// Implementation and Specification (November 1987)
  10. #[derive(PartialEq, Debug, Copy, Clone)]
  11. pub struct A {
  12. /// The IPv4 address contained in the packet.
  13. pub address: Ipv4Addr,
  14. }
  15. impl Wire for A {
  16. const NAME: &'static str = "A";
  17. const RR_TYPE: u16 = 1;
  18. #[cfg_attr(feature = "with_mutagen", ::mutagen::mutate)]
  19. fn read(stated_length: u16, c: &mut Cursor<&[u8]>) -> Result<Self, WireError> {
  20. if stated_length != 4 {
  21. warn!("Length is incorrect (record length {:?}, but should be four)", stated_length);
  22. let mandated_length = MandatedLength::Exactly(4);
  23. return Err(WireError::WrongRecordLength { stated_length, mandated_length });
  24. }
  25. let mut buf = [0_u8; 4];
  26. c.read_exact(&mut buf)?;
  27. let address = Ipv4Addr::from(buf);
  28. trace!("Parsed IPv4 address -> {:?}", address);
  29. Ok(Self { address })
  30. }
  31. }
  32. #[cfg(test)]
  33. mod test {
  34. use super::*;
  35. use pretty_assertions::assert_eq;
  36. #[test]
  37. fn parses() {
  38. let buf = &[
  39. 0x7F, 0x00, 0x00, 0x01, // IPv4 address
  40. ];
  41. assert_eq!(A::read(buf.len() as _, &mut Cursor::new(buf)).unwrap(),
  42. A { address: Ipv4Addr::new(127, 0, 0, 1) });
  43. }
  44. #[test]
  45. fn record_too_short() {
  46. let buf = &[
  47. 0x7F, 0x00, 0x00, // Too short IPv4 address
  48. ];
  49. assert_eq!(A::read(buf.len() as _, &mut Cursor::new(buf)),
  50. Err(WireError::WrongRecordLength { stated_length: 3, mandated_length: MandatedLength::Exactly(4) }));
  51. }
  52. #[test]
  53. fn record_too_long() {
  54. let buf = &[
  55. 0x7F, 0x00, 0x00, 0x00, // IPv4 address
  56. 0x01, // Unexpected extra byte
  57. ];
  58. assert_eq!(A::read(buf.len() as _, &mut Cursor::new(buf)),
  59. Err(WireError::WrongRecordLength { stated_length: 5, mandated_length: MandatedLength::Exactly(4) }));
  60. }
  61. #[test]
  62. fn record_empty() {
  63. assert_eq!(A::read(0, &mut Cursor::new(&[])),
  64. Err(WireError::WrongRecordLength { stated_length: 0, mandated_length: MandatedLength::Exactly(4) }));
  65. }
  66. #[test]
  67. fn buffer_ends_abruptly() {
  68. let buf = &[
  69. 0x7F, 0x00, // Half an IPv4 address
  70. ];
  71. assert_eq!(A::read(4, &mut Cursor::new(buf)),
  72. Err(WireError::IO));
  73. }
  74. }