simple_dns/dns/rdata/
ipseckey.rs1use super::RR;
2use crate::{
3 bytes_buffer::BytesBuffer,
4 dns::WireFormat,
5 lib::{Cow, Ipv4Addr, Ipv6Addr},
6 lib::Write,
7 Name,
8};
9
10#[derive(Debug, PartialEq, Eq, Hash, Clone)]
12pub struct IPSECKEY<'a> {
13 pub precedence: u8,
15 pub algorithm: u8,
17 pub gateway: Gateway<'a>,
19 pub public_key: Cow<'a, [u8]>,
21}
22
23#[derive(Debug, PartialEq, Eq, Hash, Clone)]
25pub enum Gateway<'a> {
26 None,
28 IPv4(Ipv4Addr),
30 IPv6(Ipv6Addr),
32 Domain(Name<'a>),
34}
35
36impl Gateway<'_> {
37 pub fn into_owned<'b>(self) -> Gateway<'b> {
39 match self {
40 Gateway::None => Gateway::None,
41 Gateway::IPv4(x) => Gateway::IPv4(x),
42 Gateway::IPv6(x) => Gateway::IPv6(x),
43 Gateway::Domain(x) => Gateway::Domain(x.into_owned()),
44 }
45 }
46}
47
48impl RR for IPSECKEY<'_> {
49 const TYPE_CODE: u16 = 45;
50}
51
52impl<'a> WireFormat<'a> for IPSECKEY<'a> {
53 const MINIMUM_LEN: usize = 5;
54
55 fn parse(data: &mut BytesBuffer<'a>) -> crate::Result<Self>
56 where
57 Self: Sized,
58 {
59 let precedence = data.get_u8()?;
60 let gateway_type = data.get_u8()?;
61 let algorithm = data.get_u8()?;
62 let gateway = match gateway_type {
63 0 => Gateway::None,
64 1 => Gateway::IPv4(data.get_u32()?.into()),
65 2 => Gateway::IPv6(data.get_u128()?.into()),
66 3 => Gateway::Domain(Name::parse(data)?),
67 _ => return Err(crate::SimpleDnsError::AttemptedInvalidOperation),
68 };
69 let public_key = data.get_remaining();
70 Ok(Self {
71 precedence,
72 algorithm,
73 gateway,
74 public_key: Cow::Borrowed(public_key),
75 })
76 }
77
78 fn write_to<T: Write>(&self, out: &mut T) -> crate::Result<()> {
79 match &self.gateway {
80 Gateway::None => {
81 out.write_all(&[self.precedence, 0, self.algorithm])?;
82 }
83 Gateway::IPv4(ipv4_addr) => {
84 out.write_all(&[self.precedence, 1, self.algorithm])?;
85 out.write_all(&ipv4_addr.octets())?
86 }
87 Gateway::IPv6(ipv6_addr) => {
88 out.write_all(&[self.precedence, 2, self.algorithm])?;
89 out.write_all(&ipv6_addr.octets())?
90 }
91 Gateway::Domain(name) => {
92 out.write_all(&[self.precedence, 3, self.algorithm])?;
93 name.write_to(out)?
94 }
95 };
96 out.write_all(&self.public_key)?;
97 Ok(())
98 }
99
100 fn len(&self) -> usize {
101 (match &self.gateway {
102 Gateway::None => 0,
103 Gateway::IPv4(_) => 4,
104 Gateway::IPv6(_) => 16,
105 Gateway::Domain(name) => name.len(),
106 }) + self.public_key.len()
107 + Self::MINIMUM_LEN
108 }
109}
110
111impl IPSECKEY<'_> {
112 pub fn into_owned<'b>(self) -> IPSECKEY<'b> {
114 IPSECKEY {
115 precedence: self.precedence,
116 algorithm: self.algorithm,
117 gateway: self.gateway.into_owned(),
118 public_key: self.public_key.into_owned().into(),
119 }
120 }
121}
122
123#[cfg(test)]
124mod tests {
125 use super::*;
126 use crate::lib::Vec;
127
128 #[test]
129 fn parse_and_write_ipseckey() {
130 let ipseckey = IPSECKEY {
131 precedence: 10,
132 algorithm: 2,
133 gateway: Gateway::IPv4(Ipv4Addr::new(192,0,2,38)),
134 public_key: Cow::Borrowed(b"\x01\x03\x51\x53\x79\x86\xed\x35\x53\x3b\x60\x64\x47\x8e\xee\xb2\x7b\x5b\xd7\x4d\xae\x14\x9b\x6e\x81\xba\x3a\x05\x21\xaf\x82\xab\x78\x01"),
135 };
136
137 let mut data = Vec::new();
138 ipseckey.write_to(&mut data).unwrap();
139
140 let ipseckey = IPSECKEY::parse(&mut (&data[..]).into()).unwrap();
141 assert_eq!(ipseckey.precedence, 10);
142 assert_eq!(ipseckey.algorithm, 2);
143 assert_eq!(
144 ipseckey.gateway,
145 Gateway::IPv4(Ipv4Addr::new(192, 0, 2, 38))
146 );
147 assert_eq!(*ipseckey.public_key, *b"\x01\x03\x51\x53\x79\x86\xed\x35\x53\x3b\x60\x64\x47\x8e\xee\xb2\x7b\x5b\xd7\x4d\xae\x14\x9b\x6e\x81\xba\x3a\x05\x21\xaf\x82\xab\x78\x01");
148 }
149
150 #[test]
151 #[cfg(feature = "std")]
152 fn parse_sample() -> Result<(), Box<dyn std::error::Error>> {
153 use crate::{rdata::RData, ResourceRecord};
154 let sample_file = std::fs::read("samples/zonefile/IPSECKEY.sample")?;
155
156 let sample_rdata = match ResourceRecord::parse(&mut (&sample_file[..]).into())?.rdata {
157 RData::IPSECKEY(rdata) => rdata,
158 _ => unreachable!(),
159 };
160
161 assert_eq!(sample_rdata.precedence, 10);
162 assert_eq!(sample_rdata.algorithm, 2);
163 assert_eq!(
164 sample_rdata.gateway,
165 Gateway::IPv4(Ipv4Addr::new(192, 0, 2, 38))
166 );
167 assert_eq!(*sample_rdata.public_key, *b"\x01\x03\x51\x53\x79\x86\xed\x35\x53\x3b\x60\x64\x47\x8e\xee\xb2\x7b\x5b\xd7\x4d\xae\x14\x9b\x6e\x81\xba\x3a\x05\x21\xaf\x82\xab\x78\x01");
168
169 Ok(())
170 }
171}