simple_dns/dns/rdata/
eui.rs1use crate::{bytes_buffer::BytesBuffer, dns::WireFormat};
2
3use super::RR;
4
5#[derive(Debug, PartialEq, Eq, Hash, Clone)]
7pub struct EUI48 {
8 pub address: [u8; 6],
10}
11
12#[derive(Debug, PartialEq, Eq, Hash, Clone)]
14pub struct EUI64 {
15 pub address: [u8; 8],
17}
18
19impl RR for EUI48 {
20 const TYPE_CODE: u16 = 108;
21}
22
23impl RR for EUI64 {
24 const TYPE_CODE: u16 = 109;
25}
26
27impl WireFormat<'_> for EUI48 {
28 const MINIMUM_LEN: usize = 6;
29
30 fn parse(data: &mut BytesBuffer) -> crate::Result<Self>
31 where
32 Self: Sized,
33 {
34 let address = data.get_array()?;
35 Ok(Self { address })
36 }
37
38 fn write_to<T: std::io::Write>(&self, out: &mut T) -> crate::Result<()> {
39 out.write_all(&self.address)
40 .map_err(crate::SimpleDnsError::from)
41 }
42}
43
44impl WireFormat<'_> for EUI64 {
45 const MINIMUM_LEN: usize = 8;
46
47 fn parse(data: &mut BytesBuffer) -> crate::Result<Self>
48 where
49 Self: Sized,
50 {
51 let address = data.get_array()?;
52 Ok(Self { address })
53 }
54
55 fn write_to<T: std::io::Write>(&self, out: &mut T) -> crate::Result<()> {
56 out.write_all(&self.address)
57 .map_err(crate::SimpleDnsError::from)
58 }
59}
60
61impl EUI48 {
62 pub fn into_owned(self) -> Self {
64 self
65 }
66}
67
68impl EUI64 {
69 pub fn into_owned(self) -> Self {
71 self
72 }
73}
74
75impl From<EUI48> for [u8; 6] {
76 fn from(value: EUI48) -> Self {
77 value.address
78 }
79}
80
81impl From<EUI64> for [u8; 8] {
82 fn from(value: EUI64) -> Self {
83 value.address
84 }
85}
86
87#[cfg(test)]
88mod tests {
89 use crate::{rdata::RData, ResourceRecord};
90
91 use super::*;
92
93 #[test]
94 fn parse_and_write_eui48() {
95 let mac = [0, 0, 0, 0, 0, 0];
96 let rdata = EUI48 { address: mac };
97 let mut writer = Vec::new();
98 rdata.write_to(&mut writer).unwrap();
99 let rdata = EUI48::parse(&mut BytesBuffer::new(&writer)).unwrap();
100 assert_eq!(rdata.address, mac);
101 }
102
103 #[test]
104 fn parse_and_write_eui64() {
105 let mac = [0, 0, 0, 0, 0, 0, 0, 0];
106 let rdata = EUI64 { address: mac };
107 let mut writer = Vec::new();
108 rdata.write_to(&mut writer).unwrap();
109 let rdata = EUI64::parse(&mut (&writer[..]).into()).unwrap();
110 assert_eq!(rdata.address, mac);
111 }
112
113 #[test]
114 fn parse_sample_eui48() -> Result<(), Box<dyn std::error::Error>> {
115 let sample_file = std::fs::read("samples/zonefile/EUI48.sample")?;
116
117 let sample_rdata = match ResourceRecord::parse(&mut (&sample_file[..]).into())?.rdata {
118 RData::EUI48(rdata) => rdata,
119 _ => unreachable!(),
120 };
121
122 assert_eq!(sample_rdata.address, [0x00, 0x00, 0x5e, 0x00, 0x53, 0x2a]);
123
124 Ok(())
125 }
126
127 #[test]
128 fn parse_sample_eui64() -> Result<(), Box<dyn std::error::Error>> {
129 let sample_file = std::fs::read("samples/zonefile/EUI64.sample")?;
130
131 let sample_rdata = match ResourceRecord::parse(&mut (&sample_file[..]).into())?.rdata {
132 RData::EUI64(rdata) => rdata,
133 _ => unreachable!(),
134 };
135
136 assert_eq!(
137 sample_rdata.address,
138 [0x00, 0x00, 0x5e, 0xef, 0x10, 0x00, 0x00, 0x2a]
139 );
140
141 Ok(())
142 }
143}