simple_dns/dns/rdata/
zonemd.rs1use crate::{
2 bytes_buffer::BytesBuffer,
3 dns::WireFormat,
4 lib::{Cow, Write},
5};
6
7use super::RR;
8
9#[derive(Debug, PartialEq, Eq, Hash, Clone)]
11pub struct ZONEMD<'a> {
12 pub serial: u32,
14 pub scheme: u8,
16 pub algorithm: u8,
18 pub digest: Cow<'a, [u8]>,
20}
21
22impl RR for ZONEMD<'_> {
23 const TYPE_CODE: u16 = 63;
24}
25
26impl<'a> WireFormat<'a> for ZONEMD<'a> {
27 const MINIMUM_LEN: usize = 6;
28
29 fn parse(data: &mut BytesBuffer<'a>) -> crate::Result<Self>
30 where
31 Self: Sized,
32 {
33 let serial = data.get_u32()?;
34 let scheme = data.get_u8()?;
35 let algorithm = data.get_u8()?;
36 let digest = Cow::Borrowed(data.get_remaining());
37
38 Ok(Self {
39 serial,
40 scheme,
41 algorithm,
42 digest,
43 })
44 }
45
46 fn write_to<T: Write>(&self, out: &mut T) -> crate::Result<()> {
47 out.write_all(&self.serial.to_be_bytes())?;
48 out.write_all(&[self.scheme])?;
49 out.write_all(&[self.algorithm])?;
50 out.write_all(&self.digest)?;
51
52 Ok(())
53 }
54
55 fn len(&self) -> usize {
56 self.digest.len() + Self::MINIMUM_LEN
57 }
58}
59
60impl ZONEMD<'_> {
61 pub fn into_owned<'b>(self) -> ZONEMD<'b> {
63 ZONEMD {
64 scheme: self.scheme,
65 serial: self.serial,
66 algorithm: self.algorithm,
67 digest: self.digest.into_owned().into(),
68 }
69 }
70}
71
72#[cfg(test)]
73mod tests {
74 use crate::lib::Vec;
75 use crate::rdata::ZONEMD;
76
77 use super::*;
78
79 #[test]
80 fn parse_and_write_srv() {
81 let zonemd = ZONEMD {
82 serial: 1,
83 scheme: 2,
84 algorithm: 3,
85 digest: Cow::Borrowed(&[4, 5, 6]),
86 };
87
88 let mut bytes = Vec::new();
89 assert!(zonemd.write_to(&mut bytes).is_ok());
90
91 let zonemd = ZONEMD::parse(&mut bytes[..].into());
92 assert!(zonemd.is_ok());
93 let zonemd = zonemd.unwrap();
94
95 assert_eq!(zonemd.serial, 1);
96 assert_eq!(zonemd.scheme, 2);
97 assert_eq!(zonemd.algorithm, 3);
98 assert_eq!(*zonemd.digest, *b"\x04\x05\x06");
99 }
100
101 #[test]
102 #[cfg(feature = "std")]
103 fn parse_sample() -> Result<(), crate::lib::Box<dyn crate::lib::Error>> {
104 use crate::{rdata::RData, ResourceRecord};
105
106 let sample_file = std::fs::read("samples/zonefile/ZONEMD.sample")?;
107
108 let sample_rdata = match ResourceRecord::parse(&mut sample_file[..].into())?.rdata {
109 RData::ZONEMD(rdata) => rdata,
110 _ => unreachable!(),
111 };
112
113 assert_eq!(sample_rdata.serial, 2018031500);
114 assert_eq!(sample_rdata.scheme, 1);
115 assert_eq!(sample_rdata.algorithm, 1);
116 assert_eq!(*sample_rdata.digest, *b"\xFE\xBE\x3D\x4C\xE2\xEC\x2F\xFA\x4B\xA9\x9D\x46\xCD\x69\xD6\xD2\x97\x11\xE5\x52\x17\x05\x7B\xEE\x7E\xB1\xA7\xB6\x41\xA4\x7B\xA7\xFE\xD2\xDD\x5B\x97\xAE\x49\x9F\xAF\xA4\xF2\x2C\x6B\xD6\x47\xDE");
117
118 Ok(())
119 }
120}