Skip to main content

mdns_proto/wire/record/
a.rs

1//! A record (IPv4 address, RFC 1035 §3.4.1).
2
3use core::net::Ipv4Addr;
4
5use crate::error::{BufferTooShortDetail, ParseError};
6
7/// Parsed A record rdata.
8#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
9pub struct A {
10  addr: Ipv4Addr,
11}
12
13impl A {
14  /// Parses a 4-byte IPv4 address from rdata.
15  ///
16  /// `rdata` MUST be exactly 4 bytes (RFC 1035 §3.4.1).  A
17  /// shorter slice yields `BufferTooShort`; an oversize slice would
18  /// previously have been silently truncated, which is wire-level
19  /// undefined behaviour and could mask a protocol error from the
20  /// caller.
21  pub fn try_from_rdata(rdata: &[u8]) -> Result<Self, ParseError> {
22    if rdata.len() != 4 {
23      return Err(ParseError::BufferTooShort(BufferTooShortDetail::new(
24        4,
25        0,
26        rdata.len(),
27      )));
28    }
29    let arr: &[u8; 4] = rdata
30      .first_chunk::<4>()
31      .ok_or_else(|| ParseError::BufferTooShort(BufferTooShortDetail::new(4, 0, rdata.len())))?;
32    Ok(Self {
33      addr: Ipv4Addr::from(*arr),
34    })
35  }
36
37  /// Returns the parsed IPv4 address.
38  #[inline(always)]
39  pub const fn addr(&self) -> Ipv4Addr {
40    self.addr
41  }
42}
43
44#[cfg(test)]
45#[allow(clippy::unwrap_used)]
46mod tests;