Compare commits
4 Commits
data_drive
...
dns-body-m
Author | SHA1 | Date | |
---|---|---|---|
59556f6b3c | |||
d0e4bea3e8 | |||
46629d2aad | |||
ce12fddbe9 |
303
src/proto.rs
303
src/proto.rs
@ -140,10 +140,10 @@ pub struct DNSHeader {
|
||||
pub recursion_desired: bool,
|
||||
/// denotes whether recursive query support is available in the name server
|
||||
pub recursion_available: bool,
|
||||
/// TODO: add documuentation about this flag
|
||||
pub authentic_data: bool,
|
||||
/// TODO: add documuentation about this flag
|
||||
pub checking_disabled: bool,
|
||||
// no support of rfc4035 at the moment
|
||||
//pub authentic_data: bool,
|
||||
// no support of rfc4035 at the moment
|
||||
//pub checking_disabled: bool,
|
||||
pub response_code: DNSRCode,
|
||||
/// TODO: add documuentation about this count
|
||||
pub query_count: u16,
|
||||
@ -156,11 +156,47 @@ pub struct DNSHeader {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DNSQuery {
|
||||
pub hdr: DNSHeader,
|
||||
pub enum DNSClass {
|
||||
Internet = 1,
|
||||
Any = 255,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum DNSType {
|
||||
HostAddress = 1,
|
||||
NameServer = 2,
|
||||
CanonicalName = 5,
|
||||
StartOfZoneAuthority = 6,
|
||||
WellKnownServiceDescription = 11,
|
||||
DomainNamePointer = 12,
|
||||
HostInformation = 13,
|
||||
MailListInformation = 14,
|
||||
MailExchange = 15,
|
||||
TextStrings = 16,
|
||||
Any = 255,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DNSQuestion {
|
||||
pub name: String,
|
||||
pub qclass: u16,
|
||||
pub qtype: u16,
|
||||
pub r#type: DNSType,
|
||||
pub class: DNSClass,
|
||||
}
|
||||
|
||||
pub struct DNSResourceRecord {
|
||||
pub name: String,
|
||||
pub r#type: DNSType,
|
||||
pub class: DNSClass,
|
||||
pub ttl: u32,
|
||||
pub data: String,
|
||||
}
|
||||
|
||||
pub struct DNSMessage {
|
||||
pub header: DNSHeader,
|
||||
pub questions: Vec<DNSQuestion>,
|
||||
pub answers: Vec<DNSResourceRecord>,
|
||||
pub authorities: Vec<DNSResourceRecord>,
|
||||
pub additionals: Vec<DNSResourceRecord>,
|
||||
}
|
||||
|
||||
impl DNSHeader {
|
||||
@ -171,8 +207,9 @@ impl DNSHeader {
|
||||
const RD_MASK: u8 = 0b00000001;
|
||||
|
||||
const RA_MASK: u8 = 0b10000000;
|
||||
const AD_MASK: u8 = 0b00100000;
|
||||
const CD_MASK: u8 = 0b00010000;
|
||||
// no support of rfc4035 at the moment
|
||||
//const AD_MASK: u8 = 0b00100000;
|
||||
//const CD_MASK: u8 = 0b00010000;
|
||||
const RCODE_MASK: u8 = 0b00001111;
|
||||
|
||||
const OPCODE_OFFSET: u8 = 3;
|
||||
@ -186,15 +223,17 @@ impl DNSHeader {
|
||||
|
||||
let message_type = DNSMessageType::from(datagram[2] & Self::QR_MASK != 0);
|
||||
let opcode = DNSOpCode::try_from((datagram[2] & Self::OPCODE_MASK) >> Self::OPCODE_OFFSET)?;
|
||||
|
||||
let authorative_answer = (datagram[2] & Self::AA_MASK) != 0;
|
||||
let truncated = (datagram[2] & Self::TC_MASK) != 0;
|
||||
let recursion_desired = (datagram[2] & Self::RD_MASK) != 0;
|
||||
let recursion_available = (datagram[3] & Self::RA_MASK) != 0;
|
||||
|
||||
// no support for rfc4035 at the moment
|
||||
//let authentic_data = (datagram[2] & Self::AD_MASK) != 0;
|
||||
//let checking_disabled = (datagram[2] & Self::CD_MASK) != 0;
|
||||
|
||||
let recursion_available = (datagram[2] & Self::RA_MASK) != 0;
|
||||
let authentic_data = (datagram[2] & Self::AD_MASK) != 0;
|
||||
let checking_disabled = (datagram[2] & Self::CD_MASK) != 0;
|
||||
let response_code = DNSRCode::try_from(datagram[3] & Self::RCODE_MASK)?;
|
||||
|
||||
let query_count = u16::from_be_bytes((datagram[4..6]).try_into().unwrap());
|
||||
let answer_count = u16::from_be_bytes((datagram[6..8]).try_into().unwrap());
|
||||
let name_server_count = u16::from_be_bytes((datagram[8..10]).try_into().unwrap());
|
||||
@ -208,8 +247,8 @@ impl DNSHeader {
|
||||
truncated,
|
||||
recursion_desired,
|
||||
recursion_available,
|
||||
authentic_data,
|
||||
checking_disabled,
|
||||
//authentic_data, // no support of rfc4035 at the moment
|
||||
//checking_disabled, // no support of rfc4035 at the moment
|
||||
response_code,
|
||||
query_count,
|
||||
answer_count,
|
||||
@ -376,5 +415,237 @@ mod tests {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
mod query_count {
|
||||
use super::super::super::*;
|
||||
|
||||
#[test]
|
||||
fn zero() -> Result<(), DNSParseError> {
|
||||
let dns_query = [
|
||||
0xff, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
];
|
||||
let parse_result = DNSHeader::from_udp_datagram(&dns_query);
|
||||
assert_eq!(parse_result?.query_count, 0);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn one() -> Result<(), DNSParseError> {
|
||||
let dns_query = [
|
||||
0xff, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
];
|
||||
let parse_result = DNSHeader::from_udp_datagram(&dns_query);
|
||||
assert_eq!(parse_result?.query_count, 1);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn max_value() -> Result<(), DNSParseError> {
|
||||
let dns_query = [
|
||||
0xff, 0x00, 0x80, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
];
|
||||
let parse_result = DNSHeader::from_udp_datagram(&dns_query);
|
||||
assert_eq!(parse_result?.query_count, 65535);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
mod answer_count {
|
||||
use super::super::super::*;
|
||||
|
||||
#[test]
|
||||
fn zero() -> Result<(), DNSParseError> {
|
||||
let dns_query = [
|
||||
0xff, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
];
|
||||
let parse_result = DNSHeader::from_udp_datagram(&dns_query);
|
||||
assert_eq!(parse_result?.answer_count, 0);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn one() -> Result<(), DNSParseError> {
|
||||
let dns_query = [
|
||||
0xff, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
];
|
||||
let parse_result = DNSHeader::from_udp_datagram(&dns_query);
|
||||
assert_eq!(parse_result?.answer_count, 1);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn max_value() -> Result<(), DNSParseError> {
|
||||
let dns_query = [
|
||||
0xff, 0x00, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||
];
|
||||
let parse_result = DNSHeader::from_udp_datagram(&dns_query);
|
||||
assert_eq!(parse_result?.answer_count, 65535);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
mod name_server_count {
|
||||
use super::super::super::*;
|
||||
|
||||
#[test]
|
||||
fn zero() -> Result<(), DNSParseError> {
|
||||
let dns_query = [
|
||||
0xff, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
];
|
||||
let parse_result = DNSHeader::from_udp_datagram(&dns_query);
|
||||
assert_eq!(parse_result?.name_server_count, 0);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn one() -> Result<(), DNSParseError> {
|
||||
let dns_query = [
|
||||
0xff, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
|
||||
];
|
||||
let parse_result = DNSHeader::from_udp_datagram(&dns_query);
|
||||
assert_eq!(parse_result?.name_server_count, 1);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn max_value() -> Result<(), DNSParseError> {
|
||||
let dns_query = [
|
||||
0xff, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
|
||||
];
|
||||
let parse_result = DNSHeader::from_udp_datagram(&dns_query);
|
||||
assert_eq!(parse_result?.name_server_count, 65535);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
mod additional_count {
|
||||
use super::super::super::*;
|
||||
|
||||
#[test]
|
||||
fn zero() -> Result<(), DNSParseError> {
|
||||
let dns_query = [
|
||||
0xff, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
];
|
||||
let parse_result = DNSHeader::from_udp_datagram(&dns_query);
|
||||
assert_eq!(parse_result?.additional_count, 0);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn one() -> Result<(), DNSParseError> {
|
||||
let dns_query = [
|
||||
0xff, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
];
|
||||
let parse_result = DNSHeader::from_udp_datagram(&dns_query);
|
||||
assert_eq!(parse_result?.additional_count, 1);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn max_value() -> Result<(), DNSParseError> {
|
||||
let dns_query = [
|
||||
0xff, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
|
||||
];
|
||||
let parse_result = DNSHeader::from_udp_datagram(&dns_query);
|
||||
assert_eq!(parse_result?.additional_count, 65535);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
mod authorative_answer {
|
||||
use super::super::super::*;
|
||||
|
||||
#[test]
|
||||
fn yes() -> Result<(), DNSParseError> {
|
||||
let dns_query = [
|
||||
0xff, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
];
|
||||
let parse_result = DNSHeader::from_udp_datagram(&dns_query);
|
||||
assert_eq!(parse_result?.authorative_answer, true);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no() -> Result<(), DNSParseError> {
|
||||
let dns_query = [
|
||||
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
];
|
||||
let parse_result = DNSHeader::from_udp_datagram(&dns_query);
|
||||
assert_eq!(parse_result?.authorative_answer, false);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
mod truncated {
|
||||
use super::super::super::*;
|
||||
|
||||
#[test]
|
||||
fn yes() -> Result<(), DNSParseError> {
|
||||
let dns_query = [
|
||||
0xff, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
];
|
||||
let parse_result = DNSHeader::from_udp_datagram(&dns_query);
|
||||
assert_eq!(parse_result?.truncated, true);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no() -> Result<(), DNSParseError> {
|
||||
let dns_query = [
|
||||
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
];
|
||||
let parse_result = DNSHeader::from_udp_datagram(&dns_query);
|
||||
assert_eq!(parse_result?.truncated, false);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
mod recursion_desired {
|
||||
use super::super::super::*;
|
||||
|
||||
#[test]
|
||||
fn yes() -> Result<(), DNSParseError> {
|
||||
let dns_query = [
|
||||
0xff, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
];
|
||||
let parse_result = DNSHeader::from_udp_datagram(&dns_query);
|
||||
assert_eq!(parse_result?.recursion_desired, true);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no() -> Result<(), DNSParseError> {
|
||||
let dns_query = [
|
||||
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
];
|
||||
let parse_result = DNSHeader::from_udp_datagram(&dns_query);
|
||||
assert_eq!(parse_result?.recursion_desired, false);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
mod recursion_available {
|
||||
use super::super::super::*;
|
||||
|
||||
#[test]
|
||||
fn yes() -> Result<(), DNSParseError> {
|
||||
let dns_query = [
|
||||
0xff, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
];
|
||||
let parse_result = DNSHeader::from_udp_datagram(&dns_query);
|
||||
assert_eq!(parse_result?.recursion_available, true);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no() -> Result<(), DNSParseError> {
|
||||
let dns_query = [
|
||||
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
];
|
||||
let parse_result = DNSHeader::from_udp_datagram(&dns_query);
|
||||
assert_eq!(parse_result?.recursion_available, false);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user