use crate::dns::parser::{DnsPacket, DnsQuestionIter, DnsRecordIter};
#[derive(Debug, Clone)]
pub struct LlmnrPacket<'a> {
dns: DnsPacket<'a>,
}
impl<'a> LlmnrPacket<'a> {
pub fn new(buf: &'a [u8]) -> Option<Self> {
DnsPacket::new(buf).map(|dns| Self { dns })
}
pub fn is_query(&self) -> bool { !self.dns.qr() }
pub fn is_response(&self) -> bool { self.dns.qr() }
pub fn is_valid_query(&self) -> bool {
!self.dns.qr() && self.dns.questions_count() == 1
}
pub fn has_conflict(&self) -> bool {
self.dns.qr() && (self.dns.flags() & 0x0040) != 0
}
pub fn questions(&self) -> DnsQuestionIter<'a> { self.dns.questions() }
pub fn answers(&self) -> DnsRecordIter<'a> { self.dns.answers() }
}
#[cfg(test)]
mod tests {
use super::*;
use crate::dns::builder::DnsPacketBuilder;
use crate::dns::types::{DnsClass, DnsType};
#[test]
fn parse_llmnr_query() {
let q = DnsPacketBuilder::query()
.add_question("wpad", DnsType::A, DnsClass::IN)
.build();
let p = LlmnrPacket::new(&q).unwrap();
assert!(p.is_query());
assert!(p.is_valid_query());
}
#[test]
fn parse_llmnr_response() {
let r = DnsPacketBuilder::response()
.add_raw_answer("wpad", DnsType::A, 30, &[10, 0, 0, 1])
.build();
assert!(LlmnrPacket::new(&r).unwrap().is_response());
}
}