simple_dns/dns/rdata/
naptr.rs1use crate::{
2 bytes_buffer::BytesBuffer,
3 dns::{CharacterString, Name, WireFormat},
4};
5
6use super::RR;
7
8#[derive(Debug, PartialEq, Eq, Hash, Clone)]
13pub struct NAPTR<'a> {
14 pub order: u16,
16 pub preference: u16,
18 pub flags: CharacterString<'a>,
20 pub services: CharacterString<'a>,
22 pub regexp: CharacterString<'a>,
24 pub replacement: Name<'a>,
26}
27
28impl RR for NAPTR<'_> {
29 const TYPE_CODE: u16 = 35;
30}
31
32impl NAPTR<'_> {
33 pub fn into_owned<'b>(self) -> NAPTR<'b> {
35 NAPTR {
36 order: self.order,
37 preference: self.preference,
38 flags: self.flags.into_owned(),
39 services: self.services.into_owned(),
40 regexp: self.regexp.into_owned(),
41 replacement: self.replacement.into_owned(),
42 }
43 }
44}
45
46impl<'a> WireFormat<'a> for NAPTR<'a> {
47 const MINIMUM_LEN: usize = 4;
48
49 fn parse(data: &mut BytesBuffer<'a>) -> crate::Result<Self>
50 where
51 Self: Sized,
52 {
53 let order = data.get_u16()?;
54 let preference = data.get_u16()?;
55 let flags = CharacterString::parse(data)?;
56 let services = CharacterString::parse(data)?;
57 let regexp = CharacterString::parse(data)?;
58 let replacement = Name::parse(data)?;
59
60 Ok(Self {
61 order,
62 preference,
63 flags,
64 services,
65 regexp,
66 replacement,
67 })
68 }
69
70 fn write_to<T: std::io::Write>(&self, out: &mut T) -> crate::Result<()> {
71 out.write_all(&self.order.to_be_bytes())?;
72 out.write_all(&self.preference.to_be_bytes())?;
73 self.flags.write_to(out)?;
74 self.services.write_to(out)?;
75 self.regexp.write_to(out)?;
76 self.replacement.write_to(out)
77 }
78
79 fn len(&self) -> usize {
80 self.flags.len()
81 + self.services.len()
82 + self.regexp.len()
83 + self.replacement.len()
84 + Self::MINIMUM_LEN
85 }
86}
87
88#[cfg(test)]
89mod tests {
90 use super::*;
91
92 #[test]
93 fn parse_and_write_naptr() {
94 let naptr = NAPTR {
95 order: 0,
96 preference: 1,
97 flags: CharacterString::new(b"123abc").unwrap(),
98 services: CharacterString::new(b"test").unwrap(),
99 regexp: CharacterString::new(b"@\\w+\\.\\w{2,3}(\\.\\w{2,3})?").unwrap(),
100 replacement: Name::new("e.exchange.com").unwrap(),
101 };
102
103 let mut data = Vec::new();
104 assert!(naptr.write_to(&mut data).is_ok());
105
106 let naptr = NAPTR::parse(&mut data[..].into());
107 assert!(naptr.is_ok());
108 let naptr = naptr.unwrap();
109
110 assert_eq!(data.len(), naptr.len());
111 assert_eq!(0, naptr.order);
112 assert_eq!(1, naptr.preference);
113 assert_eq!("123abc", naptr.flags.to_string());
114 assert_eq!("test", naptr.services.to_string());
115 assert_eq!("@\\w+\\.\\w{2,3}(\\.\\w{2,3})?", naptr.regexp.to_string());
116 assert_eq!("e.exchange.com", naptr.replacement.to_string());
117 }
118}