parse EDE info from dig's output
This commit is contained in:
parent
166863bcc4
commit
dc19776107
@ -141,6 +141,7 @@ impl DigSettings {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct DigOutput {
|
pub struct DigOutput {
|
||||||
|
pub ede: Option<ExtendedDnsError>,
|
||||||
pub flags: DigFlags,
|
pub flags: DigFlags,
|
||||||
pub status: DigStatus,
|
pub status: DigStatus,
|
||||||
pub answer: Vec<Record>,
|
pub answer: Vec<Record>,
|
||||||
@ -154,6 +155,7 @@ impl FromStr for DigOutput {
|
|||||||
fn from_str(input: &str) -> Result<Self> {
|
fn from_str(input: &str) -> Result<Self> {
|
||||||
const FLAGS_PREFIX: &str = ";; flags: ";
|
const FLAGS_PREFIX: &str = ";; flags: ";
|
||||||
const STATUS_PREFIX: &str = ";; ->>HEADER<<- opcode: QUERY, status: ";
|
const STATUS_PREFIX: &str = ";; ->>HEADER<<- opcode: QUERY, status: ";
|
||||||
|
const EDE_PREFIX: &str = "; EDE: ";
|
||||||
const ANSWER_HEADER: &str = ";; ANSWER SECTION:";
|
const ANSWER_HEADER: &str = ";; ANSWER SECTION:";
|
||||||
const AUTHORITY_HEADER: &str = ";; AUTHORITY SECTION:";
|
const AUTHORITY_HEADER: &str = ";; AUTHORITY SECTION:";
|
||||||
|
|
||||||
@ -173,6 +175,7 @@ impl FromStr for DigOutput {
|
|||||||
let mut status = None;
|
let mut status = None;
|
||||||
let mut answer = None;
|
let mut answer = None;
|
||||||
let mut authority = None;
|
let mut authority = None;
|
||||||
|
let mut ede = None;
|
||||||
|
|
||||||
let mut lines = input.lines();
|
let mut lines = input.lines();
|
||||||
while let Some(line) = lines.next() {
|
while let Some(line) = lines.next() {
|
||||||
@ -196,6 +199,17 @@ impl FromStr for DigOutput {
|
|||||||
}
|
}
|
||||||
|
|
||||||
status = Some(status_text.parse()?);
|
status = Some(status_text.parse()?);
|
||||||
|
} else if let Some(unprefixed) = line.strip_prefix(EDE_PREFIX) {
|
||||||
|
let code = unprefixed
|
||||||
|
.split_once(' ')
|
||||||
|
.map(|(code, _rest)| code)
|
||||||
|
.unwrap_or(unprefixed);
|
||||||
|
|
||||||
|
if ede.is_some() {
|
||||||
|
return Err(more_than_once(EDE_PREFIX).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
ede = Some(code.parse()?);
|
||||||
} else if line.starts_with(ANSWER_HEADER) {
|
} else if line.starts_with(ANSWER_HEADER) {
|
||||||
if answer.is_some() {
|
if answer.is_some() {
|
||||||
return Err(more_than_once(ANSWER_HEADER).into());
|
return Err(more_than_once(ANSWER_HEADER).into());
|
||||||
@ -230,14 +244,37 @@ impl FromStr for DigOutput {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
flags: flags.ok_or_else(|| not_found(FLAGS_PREFIX))?,
|
|
||||||
status: status.ok_or_else(|| not_found(STATUS_PREFIX))?,
|
|
||||||
answer: answer.unwrap_or_default(),
|
answer: answer.unwrap_or_default(),
|
||||||
authority: authority.unwrap_or_default(),
|
authority: authority.unwrap_or_default(),
|
||||||
|
ede,
|
||||||
|
flags: flags.ok_or_else(|| not_found(FLAGS_PREFIX))?,
|
||||||
|
status: status.ok_or_else(|| not_found(STATUS_PREFIX))?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
pub enum ExtendedDnsError {
|
||||||
|
DnssecBogus,
|
||||||
|
DnskeyMissing,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for ExtendedDnsError {
|
||||||
|
type Err = Error;
|
||||||
|
|
||||||
|
fn from_str(input: &str) -> std::prelude::v1::Result<Self, Self::Err> {
|
||||||
|
let code: u16 = input.parse()?;
|
||||||
|
|
||||||
|
let code = match code {
|
||||||
|
6 => Self::DnssecBogus,
|
||||||
|
9 => Self::DnskeyMissing,
|
||||||
|
_ => todo!("EDE {code} has not yet been implemented"),
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(code)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, PartialEq)]
|
#[derive(Debug, Default, PartialEq)]
|
||||||
pub struct DigFlags {
|
pub struct DigFlags {
|
||||||
pub authenticated_data: bool,
|
pub authenticated_data: bool,
|
||||||
@ -398,4 +435,32 @@ mod tests {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn ede() -> Result<()> {
|
||||||
|
let input = "; <<>> DiG 9.18.24-1-Debian <<>> +recurse +nodnssec +adflag +nocdflag @192.168.176.5 A example.nameservers.com.
|
||||||
|
; (1 server found)
|
||||||
|
;; global options: +cmd
|
||||||
|
;; Got answer:
|
||||||
|
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 49801
|
||||||
|
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
|
||||||
|
|
||||||
|
;; OPT PSEUDOSECTION:
|
||||||
|
; EDNS: version: 0, flags:; udp: 1232
|
||||||
|
; EDE: 9 (DNSKEY Missing)
|
||||||
|
;; QUESTION SECTION:
|
||||||
|
;example.nameservers.com. IN A
|
||||||
|
|
||||||
|
;; Query time: 26 msec
|
||||||
|
;; SERVER: 192.168.176.5#53(192.168.176.5) (UDP)
|
||||||
|
;; WHEN: Tue Mar 05 17:45:29 UTC 2024
|
||||||
|
;; MSG SIZE rcvd: 58
|
||||||
|
";
|
||||||
|
|
||||||
|
let output: DigOutput = input.parse()?;
|
||||||
|
|
||||||
|
assert_eq!(Some(ExtendedDnsError::DnskeyMissing), output.ede);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user