dnsmsg_parser/
ede.rs

1use hickory_proto::{
2    serialize::binary::{BinDecodable, BinDecoder, BinEncodable, BinEncoder},
3    ProtoError,
4};
5
6pub const EDE_OPTION_CODE: u16 = 15u16;
7
8#[derive(Debug, Clone)]
9pub struct EDE {
10    info_code: u16,
11    extra_text: Option<String>,
12}
13
14impl EDE {
15    pub fn new(info_code: u16, extra_text: Option<String>) -> Self {
16        Self {
17            info_code,
18            extra_text,
19        }
20    }
21
22    // https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#extended-dns-error-codes
23    pub fn purpose(&self) -> Option<&str> {
24        match self.info_code {
25            0 => Some("Other Error"),
26            1 => Some("Unsupported DNSKEY Algorithm"),
27            2 => Some("Unsupported DS Digest Type"),
28            3 => Some("Stale Answer"),
29            4 => Some("Forged Answer"),
30            5 => Some("DNSSEC Indeterminate"),
31            6 => Some("DNSSEC Bogus"),
32            7 => Some("Signature Expired"),
33            8 => Some("Signature Not Yet Valid"),
34            9 => Some("DNSKEY Missing"),
35            10 => Some("RRSIGs Missing"),
36            11 => Some("No Zone Key Bit Set"),
37            12 => Some("NSEC Missing"),
38            13 => Some("Cached Error"),
39            14 => Some("Not Ready"),
40            15 => Some("Blocked"),
41            16 => Some("Censored"),
42            17 => Some("Filtered"),
43            18 => Some("Prohibited"),
44            19 => Some("Stale NXDomain Answer"),
45            20 => Some("Not Authoritative"),
46            21 => Some("Not Supported"),
47            22 => Some("No Reachable Authority"),
48            23 => Some("Network Error"),
49            24 => Some("Invalid Data"),
50            25 => Some("Signature Expired before Valid"),
51            26 => Some("Too Early"),
52            27 => Some("Unsupported NSEC3 Iterations Value"),
53            28 => Some("Unable to conform to policy"),
54            29 => Some("Synthesized"),
55            30 => Some("Invalid Query Type"),
56            _ => None,
57        }
58    }
59
60    pub fn info_code(&self) -> u16 {
61        self.info_code
62    }
63
64    pub fn extra_text(&self) -> Option<String> {
65        self.extra_text.clone()
66    }
67}
68
69impl BinEncodable for EDE {
70    fn emit(&self, encoder: &mut BinEncoder<'_>) -> Result<(), ProtoError> {
71        encoder.emit_u16(self.info_code)?;
72        if let Some(extra_text) = &self.extra_text {
73            encoder.emit_vec(extra_text.as_bytes())?;
74        }
75        Ok(())
76    }
77}
78
79impl<'a> BinDecodable<'a> for EDE {
80    fn read(decoder: &mut BinDecoder<'a>) -> Result<Self, ProtoError> {
81        let info_code = decoder.read_u16()?.unverified();
82        let extra_text = if decoder.is_empty() {
83            None
84        } else {
85            Some(String::from_utf8(
86                decoder.read_vec(decoder.len())?.unverified(),
87            )?)
88        };
89        Ok(Self {
90            info_code,
91            extra_text,
92        })
93    }
94}