use sawp::error::Result;
use sawp::parser::{Direction, Parse};
use sawp::probe::Probe;
use sawp::protocol::Protocol;
use sawp_flags::{BitFlags, Flag, Flags};
#[cfg(feature = "ffi")]
mod ffi;
#[cfg(feature = "ffi")]
use sawp_ffi::GenerateFFI;
pub mod answer;
use answer::*;
pub mod edns;
pub mod enums;
use enums::*;
pub mod header;
use header::*;
pub mod name;
use name::*;
pub mod question;
use question::*;
pub mod rdata;
use nom::error::ErrorKind;
type IResult<'a, O> = nom::IResult<&'a [u8], O, sawp::error::NomError<&'a [u8]>>;
fn custom_many0<O, F>(mut func: F) -> impl FnMut(&[u8]) -> IResult<Vec<O>>
where
F: FnMut(&[u8]) -> IResult<O>,
{
move |mut input| {
let mut acc = Vec::with_capacity(1);
loop {
match func(input) {
Err(nom::Err::Error((_, nom::error::ErrorKind::LengthValue))) => {
return Ok((input, acc))
}
Ok((rem, out)) => {
if rem == input {
return Err(nom::Err::Error((input, ErrorKind::Many0)));
}
input = rem;
acc.push(out);
}
Err(e) => {
return Err(e);
}
}
}
}
}
pub fn custom_count<O, F>(
mut func: F,
count: usize,
) -> impl for<'a> FnMut(&'a [u8], &'a [u8]) -> IResult<'a, Vec<O>>
where
F: for<'a> FnMut(&'a [u8], &'a [u8]) -> IResult<'a, O>,
{
move |i, reference| {
let mut input = i;
let mut res = Vec::with_capacity(count);
for _ in 0..count {
let input_ = input;
match func(input_, reference) {
Ok((rem, out)) => {
res.push(out);
input = rem;
}
Err(nom::Err::Error((input, nom::error::ErrorKind::Count))) => {
return Ok((input, res));
}
Err(e) => {
return Err(e);
}
}
}
Ok((input, res))
}
}
#[allow(clippy::upper_case_acronyms)]
#[repr(u16)]
#[derive(Clone, Copy, Debug, PartialEq, BitFlags)]
pub enum ErrorFlags {
ExtraOptRr = 0b0000_0000_0000_0001,
UnknownOpcode = 0b0000_0000_0000_0010,
UnknownRcode = 0b0000_0000_0000_0100,
UnknownRclass = 0b0000_0000_0000_1000,
UnknownRtype = 0b0000_0000_0001_0000,
EdnsParseFail = 0b0000_0000_0010_0000,
DnsLabelExceedsMaxLen = 0b0000_0000_0100_0000,
DnsNameExceedsMaxLen = 0b0000_0000_1000_0000,
DnsNameInvalidCompression = 0b0000_0001_0000_0000,
}
#[cfg_attr(feature = "ffi", derive(GenerateFFI))]
#[cfg_attr(feature = "ffi", sawp_ffi(prefix = "sawp_dns"))]
#[derive(Debug, PartialEq)]
pub struct Message {
pub header: Header,
pub queries: Vec<Question>,
pub answers: Vec<Answer>,
pub nameservers: Vec<Answer>,
pub additional: Vec<Answer>,
#[cfg_attr(feature = "ffi", sawp_ffi(flag = "u16"))]
pub error_flags: Flags<ErrorFlags>,
}
impl Message {}
#[derive(Debug)]
pub struct Dns {}
impl<'a> Protocol<'a> for Dns {
type Message = Message;
fn name() -> &'static str {
"dns"
}
}
impl<'a> Probe<'a> for Dns {}
impl<'a> Parse<'a> for Dns {
fn parse(
&self,
input: &'a [u8],
_direction: Direction,
) -> Result<(&'a [u8], Option<Self::Message>)> {
let reference_bytes = input; let mut message = Message {
header: Header {
transaction_id: 0,
flags: 0,
query_response: QueryResponse::Response,
opcode: OpCode::QUERY,
authoritative: false,
truncated: false,
recursion_desired: false,
recursion_available: false,
zflag: false,
authenticated_data: false,
check_disabled: false,
rcode: ResponseCode::NOERROR,
qdcount: 0,
ancount: 0,
nscount: 0,
arcount: 0,
},
queries: vec![],
answers: vec![],
nameservers: vec![],
additional: vec![],
error_flags: ErrorFlags::none(),
};
let (input, (header, error_flags)) = Header::parse(input)?;
message.header = header;
message.error_flags |= error_flags;
let (input, (questions, error_flags)) =
Question::parse_questions(input, reference_bytes, message.header.qdcount.into())?;
message.queries = questions;
message.error_flags |= error_flags;
let (input, (answers, error_flags)) =
Answer::parse_answers(input, reference_bytes, message.header.ancount.into())?;
message.answers = answers;
message.error_flags |= error_flags;
let (input, (nameservers, error_flags)) =
Answer::parse_answers(input, reference_bytes, message.header.nscount.into())?;
message.nameservers = nameservers;
message.error_flags |= error_flags;
let (input, (additionals, error_flags)) =
Answer::parse_additionals(input, reference_bytes, message.header.arcount.into())?;
message.additional = additionals;
message.error_flags |= error_flags;
Ok((input, Some(message)))
}
}
#[cfg(test)]
mod test {
#![allow(clippy::type_complexity)]
use crate::enums::*;
use crate::rdata::*;
use crate::{
Answer, Dns, ErrorFlags, Header, Message, OpCode, Parse, QueryResponse, Question,
RecordClass, RecordType, ResponseCode,
};
use rstest::rstest;
use sawp::error::{Error, Result};
use sawp::parser::Direction;
use sawp_flags::Flag;
#[rstest(
input,
expected,
case::parse_too_long_name(
&[
0x31, 0x21, // Transaction ID: 0x3121
0x81, 0x00, // Flags: response, recursion desired
0x00, 0x01, // QDCOUNT: 1
0x00, 0x01, // ANCOUNT: 1
0x00, 0x00, // NSCOUNT: 0
0x00, 0x00, // ARCOUNT: 0
0x08, 0x73, 0x74, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x67, 0x08, 0x66, 0x72, 0x65, 0x65,
0x6e, 0x6f, 0x64, 0x65, 0x03, 0x6e, 0x65, 0x74, 0x08, 0x73, 0x74, 0x65, 0x72, 0x6c,
0x69, 0x6e, 0x67, 0x08, 0x66, 0x72, 0x65, 0x65, 0x6e, 0x6f, 0x64, 0x65, 0x03, 0x6e,
0x65, 0x74, 0x08, 0x73, 0x74, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x67, 0x08, 0x66, 0x72,
0x65, 0x65, 0x6e, 0x6f, 0x64, 0x65, 0x03, 0x6e, 0x65, 0x74, 0x08, 0x73, 0x74, 0x65,
0x72, 0x6c, 0x69, 0x6e, 0x67, 0x08, 0x66, 0x72, 0x65, 0x65, 0x6e, 0x6f, 0x64, 0x65,
0x03, 0x6e, 0x65, 0x74, 0x08, 0x73, 0x74, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x67, 0x08,
0x66, 0x72, 0x65, 0x65, 0x6e, 0x6f, 0x64, 0x65, 0x03, 0x6e, 0x65, 0x74, 0x08, 0x73,
0x74, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x67, 0x08, 0x66, 0x72, 0x65, 0x65, 0x6e, 0x6f,
0x64, 0x65, 0x03, 0x6e, 0x65, 0x74, 0x08, 0x73, 0x74, 0x65, 0x72, 0x6c, 0x69, 0x6e,
0x67, 0x08, 0x66, 0x72, 0x65, 0x65, 0x6e, 0x6f, 0x64, 0x65, 0x03, 0x6e, 0x65, 0x74,
0x08, 0x73, 0x74, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x67, 0x08, 0x66, 0x72, 0x65, 0x65,
0x6e, 0x6f, 0x64, 0x65, 0x03, 0x6e, 0x65, 0x74, 0x08, 0x73, 0x74, 0x65, 0x72, 0x6c,
0x69, 0x6e, 0x67, 0x08, 0x66, 0x72, 0x65, 0x65, 0x6e, 0x6f, 0x64, 0x65, 0x03, 0x6e,
0x65, 0x74, 0x08, 0x73, 0x74, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x67, 0x08, 0x66, 0x72,
0x65, 0x65, 0x6e, 0x6f, 0x64, 0x65, 0x03, 0x6e, 0x65, 0x74, 0x08, 0x73, 0x74, 0x65,
0x72, 0x6c, 0x69, 0x6e, 0x67, 0x08, 0x66, 0x72, 0x65, 0x65, 0x6e, 0x6f, 0x64, 0x65,
0x03, 0x6e, 0x65, 0x74, 0x08, 0x73, 0x74, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x67, 0x08,
0x66, 0x72, 0x65, 0x65, 0x6e, 0x6f, 0x64, 0x65, 0x03, 0x6e, 0x65, 0x74, 0x08, 0x73,
0x74, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x67, 0x08, 0x66, 0x72, 0x65, 0x65, 0x6e, 0x6f,
0x64, 0x65, 0x03, 0x6e, 0x65, 0x74, 0x08, 0x73, 0x74, 0x65, 0x72, 0x6c, 0x69, 0x6e,
0x67, 0x08, 0x66, 0x72, 0x65, 0x65, 0x6e, 0x6f, 0x64, 0x65, 0x03, 0x6e, 0x65, 0x74,
0x08, 0x73, 0x74, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x67, 0x08, 0x66, 0x72, 0x65, 0x65,
0x6e, 0x6f, 0x64, 0x65, 0x03, 0x6e, 0x65, 0x74, 0x08, 0x73, 0x74, 0x65, 0x72, 0x6c,
0x69, 0x6e, 0x67, 0x08, 0x66, 0x72, 0x65, 0x65, 0x6e, 0x6f, 0x64, 0x65, 0x03, 0x6e,
0x65, 0x74, 0x00, // question: sterling.freenode.net (repeated for length)
0x00, 0x01, // RType: A
0x00, 0x01, // RClass: IN
0xc0, 0x0c, // answer: sterling.freenode.net
0x00, 0x01, // RType: A
0x00, 0x01, // RClass: IN
0x00, 0x00, 0x27, 0x10, // TTL: 10000
0x00, 0x04, // Data length: 4
0xd4, 0xcc, 0xd6, 0x72, // 212.204.214.114
],
Ok((
0,
Some(
Message {
header: Header {
transaction_id: 0x3121,
flags: 0b1000_0001_0000_0000,
query_response: QueryResponse::Response,
opcode: OpCode::QUERY,
authoritative: false,
truncated: false,
recursion_desired: true,
recursion_available: false,
zflag: false,
authenticated_data: false,
check_disabled: false,
rcode: ResponseCode::NOERROR,
qdcount: 1,
ancount: 1,
nscount: 0,
arcount: 0,
},
queries: vec ! [
Question {
name:
"sterling.freenode.net\
.sterling.freenode.net\
.sterling.freenode.net\
.sterling.freenode.net\
.sterling.freenode.net\
.sterling.freenode.net\
.sterling.freenode.net\
.sterling.freenode.net\
.sterling.freenode.net\
.sterling.freenode.net\
.sterling.freenode.net\
.sterling.free".as_bytes().to_vec(),
record_type: RecordType::A,
record_type_raw: 1,
record_class: RecordClass::IN,
record_class_raw: 1,
}
],
nameservers: vec ! [],
answers: vec ! [
Answer {
name:
"sterling.freenode.net\
.sterling.freenode.net\
.sterling.freenode.net\
.sterling.freenode.net\
.sterling.freenode.net\
.sterling.freenode.net\
.sterling.freenode.net\
.sterling.freenode.net\
.sterling.freenode.net\
.sterling.freenode.net\
.sterling.freenode.net\
.sterling.free".as_bytes().to_vec(),
rtype: RecordType::A,
rtype_raw: 1,
rclass: RecordClass::IN,
rclass_raw: 1,
ttl: 10000,
data: RDataType::A(vec![212, 204, 214, 114]),
}
],
additional: vec ! [],
error_flags: ErrorFlags::DnsNameExceedsMaxLen.into(),
}
)))
),
case::parse_too_long_label(
&[
0x31, 0x21, // Transaction ID: 0x3121
0x81, 0x00, // Flags: response, recursion desired
0x00, 0x01, // QDCOUNT: 1
0x00, 0x01, // ANCOUNT: 1
0x00, 0x00, // NSCOUNT: 0
0x00, 0x00, // ARCOUNT: 0
0x64, // too long
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x00, // question: AAA....
0x00, 0x01, // RType: A
0x00, 0x01, // RClass: IN
0xc0, 0x0c, // answer: AAA.....
0x00, 0x01, // RType: A
0x00, 0x01, // RClass: IN
0x00, 0x00, 0x27, 0x10, // TTL: 10000
0x00, 0x04, // Data length: 4
0xd4, 0xcc, 0xd6, 0x72, // 212.204.214.114
],
Ok((
0,
Some(
Message {
header: Header {
transaction_id: 12577,
flags: 0b1000_0001_0000_0000,
query_response: QueryResponse::Response,
opcode: OpCode::QUERY,
authoritative: false,
truncated: false,
recursion_desired: true,
recursion_available: false,
zflag: false,
authenticated_data: false,
check_disabled: false,
rcode: ResponseCode::NOERROR,
qdcount: 1,
ancount: 1,
nscount: 0,
arcount: 0,
},
queries: vec![
Question {
name: vec![
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
],
record_type: RecordType::A,
record_type_raw: 1,
record_class: RecordClass::IN,
record_class_raw: 1,
}
],
answers: vec![
Answer {
name: vec![
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
],
rtype: RecordType::A,
rtype_raw: 1,
rclass: RecordClass::IN,
rclass_raw: 1,
ttl: 10000,
data: RDataType::A(vec![212, 204, 214, 114]),
}
],
nameservers: vec![],
additional: vec![],
error_flags: ErrorFlags::DnsLabelExceedsMaxLen.into(),
})))
),
case::parse_name_invalid_ptr(
&[
0x31, 0x21, // Transaction ID: 0x3121
0x81, 0x00, // Flags: response, recursion desired
0x00, 0x01, // QDCOUNT: 1
0x00, 0x01, // ANCOUNT: 1
0x00, 0x00, // NSCOUNT: 0
0x00, 0x00, // ARCOUNT: 0
0x08, 0x73, 0x74, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x67, 0x08, 0x66, 0x72, 0x65, 0x65,
0x6e, 0x6f, 0x64, 0x65, 0x03, 0x6e, 0x65, 0x74,
0x00, // question: sterling.freenode.net
0x00, 0x01, // RType: A
0x00, 0x01, // RClass: IN
0xc0, 0xfc, // answer: invalid ptr
0x00, 0x01, // RType: A
0x00, 0x01, // RClass: IN
0x00, 0x00, 0x27, 0x10, // TTL: 10000
0x00, 0x04, // Data length: 4
0xd4, 0xcc, 0xd6, 0x72, // 212.204.214.114
],
Ok((
0,
Some(
Message {
header: Header {
transaction_id: 0x3121,
flags: 0b1000_0001_0000_0000,
query_response: QueryResponse::Response,
opcode: OpCode::QUERY,
authoritative: false,
truncated: false,
recursion_desired: true,
recursion_available: false,
zflag: false,
authenticated_data: false,
check_disabled: false,
rcode: ResponseCode::NOERROR,
qdcount: 1,
ancount: 1,
nscount: 0,
arcount: 0,
},
queries: vec![
Question {
name: "sterling.freenode.net".as_bytes().to_vec(),
record_type: RecordType::A,
record_type_raw: 1,
record_class: RecordClass::IN,
record_class_raw: 1,
}
],
nameservers: vec![],
answers: vec![
Answer {
name: vec![],
rtype: RecordType::A,
rtype_raw: 1,
rclass: RecordClass::IN,
rclass_raw: 1,
ttl: 10000,
data: RDataType::A(vec![212, 204, 214, 114]),
}
],
additional: vec![],
error_flags: ErrorFlags::DnsNameInvalidCompression.into(),
}
)))
),
case::parse_bad_record_type(
&[
0x31, 0x21, // Transaction ID: 0x3121
0x81, 0x00, // Flags: response, recursion desired
0x00, 0x01, // QDCOUNT: 1
0x00, 0x01, // ANCOUNT: 1
0x00, 0x00, // NSCOUNT: 0
0x00, 0x00, // ARCOUNT: 0
0x08, 0x73, 0x74, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x67, 0x08, 0x66, 0x72, 0x65, 0x65,
0x6e, 0x6f, 0x64, 0x65, 0x03, 0x6e, 0x65, 0x74,
0x00, // question: sterling.freenode.net
0x01, 0x05, // RType: UNKNOWN
0x00, 0x01, // RClass: IN
0xc0, 0x0c, // answer: sterling.freenode.net
0x00, 0x01, // RType: A
0x00, 0x01, // RClass: IN
0x00, 0x00, 0x27, 0x10, // TTL: 10000
0x00, 0x04, // Data length: 4
0xd4, 0xcc, 0xd6, 0x72, // 212.204.214.114
],
Ok((
0,
Some(
Message {
header: Header {
transaction_id: 0x3121,
flags: 0b1000_0001_0000_0000,
query_response: QueryResponse::Response,
opcode: OpCode::QUERY,
authoritative: false,
truncated: false,
recursion_desired: true,
recursion_available: false,
zflag: false,
authenticated_data: false,
check_disabled: false,
rcode: ResponseCode::NOERROR,
qdcount: 1,
ancount: 1,
nscount: 0,
arcount: 0,
},
queries: vec![
Question {
name: "sterling.freenode.net".as_bytes().to_vec(),
record_type: RecordType::UNKNOWN,
record_type_raw: 261,
record_class: RecordClass::IN,
record_class_raw: 1,
}
],
nameservers: vec![],
answers: vec![
Answer {
name: "sterling.freenode.net".as_bytes().to_vec(),
rtype: RecordType::A,
rtype_raw: 1,
rclass: RecordClass::IN,
rclass_raw: 1,
ttl: 10000,
data: (RDataType::A(vec![212, 204, 214, 114])),
}
],
additional: vec![],
error_flags: ErrorFlags::UnknownRtype.into(),
}
)))
),
case::parse_bad_record_class(
&[
0x31, 0x21, // Transaction ID: 0x3121
0x81, 0x00, // Flags: response, recursion desired
0x00, 0x01, // QDCOUNT: 1
0x00, 0x01, // ANCOUNT: 1
0x00, 0x00, // NSCOUNT: 0
0x00, 0x00, // ARCOUNT: 0
0x08, 0x73, 0x74, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x67, 0x08, 0x66, 0x72, 0x65, 0x65,
0x6e, 0x6f, 0x64, 0x65, 0x03, 0x6e, 0x65, 0x74,
0x00, // question: sterling.freenode.net
0x00, 0x01, // RType: A
0x00, 0x20, // RClass: UNKNOWN
0xc0, 0x0c, // answer: sterling.freenode.net
0x00, 0x01, // RType: A
0x00, 0x60, // RClass: UNKNOWN
0x00, 0x00, 0x27, 0x10, // TTL: 10000
0x00, 0x04, // Data length: 4
0xd4, 0xcc, 0xd6, 0x72, // 212.204.214.114
],
Ok((
0,
Some(
Message {
header: Header {
transaction_id: 0x3121,
flags: 0b1000_0001_0000_0000,
query_response: QueryResponse::Response,
opcode: OpCode::QUERY,
authoritative: false,
truncated: false,
recursion_desired: true,
recursion_available: false,
zflag: false,
authenticated_data: false,
check_disabled: false,
rcode: ResponseCode::NOERROR,
qdcount: 1,
ancount: 1,
nscount: 0,
arcount: 0,
},
queries: vec![
Question {
name: "sterling.freenode.net".as_bytes().to_vec(),
record_type: RecordType::A,
record_type_raw: 1,
record_class: RecordClass::UNKNOWN,
record_class_raw: 32,
}
],
nameservers: vec![],
answers: vec![
Answer {
name: "sterling.freenode.net".as_bytes().to_vec(),
rtype: RecordType::A,
rtype_raw: 1,
rclass: RecordClass::UNKNOWN,
rclass_raw: 96,
ttl: 10000,
data: (RDataType::A(vec![212, 204, 214, 114])),
}
],
additional: vec![],
error_flags: ErrorFlags::UnknownRclass.into(),
}
)))
),
case::parse_a_response(
&[
0x31, 0x21, // Transaction ID: 0x3121
0x81, 0x00, // Flags: response, recursion desired
0x00, 0x01, // QDCOUNT: 1
0x00, 0x01, // ANCOUNT: 1
0x00, 0x00, // NSCOUNT: 0
0x00, 0x00, // ARCOUNT: 0
0x08, 0x73, 0x74, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x67, 0x08, 0x66, 0x72, 0x65, 0x65,
0x6e, 0x6f, 0x64, 0x65, 0x03, 0x6e, 0x65, 0x74,
0x00, // question: sterling.freenode.net
0x00, 0x01, // RType: A
0x00, 0x01, // RClass: IN
0xc0, 0x0c, // answer: sterling.freenode.net
0x00, 0x01, // RType: A
0x00, 0x01, // RClass: IN
0x00, 0x00, 0x27, 0x10, // TTL: 10000
0x00, 0x04, // Data length: 4
0xd4, 0xcc, 0xd6, 0x72, // 212.204.214.114
],
Ok((
0,
Some(
Message {
header: Header {
transaction_id: 0x3121,
flags: 0b1000_0001_0000_0000,
query_response: QueryResponse::Response,
opcode: OpCode::QUERY,
authoritative: false,
truncated: false,
recursion_desired: true,
recursion_available: false,
zflag: false,
authenticated_data: false,
check_disabled: false,
rcode: ResponseCode::NOERROR,
qdcount: 1,
ancount: 1,
nscount: 0,
arcount: 0,
},
queries: vec![
Question {
name: "sterling.freenode.net".as_bytes().to_vec(),
record_type: RecordType::A,
record_type_raw: 1,
record_class: RecordClass::IN,
record_class_raw: 1,
}
],
nameservers: vec![],
answers: vec![
Answer {
name: "sterling.freenode.net".as_bytes().to_vec(),
rtype: RecordType::A,
rtype_raw: 1,
rclass: RecordClass::IN,
rclass_raw: 1,
ttl: 10000,
data: (RDataType::A(vec![212, 204, 214, 114])),
}
],
additional: vec![],
error_flags: ErrorFlags::none(),
}
)))
),
case::parse_txt_response(
&[
0x10, 0x32, // Transaction ID: 0x1032
0x81, 0x80, // Flags: response, recursion desired, recursion available
0x00, 0x01, // QDCOUNT: 1
0x00, 0x01, // ANCOUNT: 1
0x00, 0x00, // NSCOUNT: 0
0x00, 0x00, // ARCOUNT: 0
0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00,
// question: google.com
0x00, 0x10, // RType: TXT
0x00, 0x01, // RCLASS: IN
0xc0, 0x0c, // answer: google.com
0x00, 0x10, // RType: TXT
0x00, 0x01, // RCLASS: IN
0x00, 0x00, 0x01, 0x0e, // TTL: 270
0x00, 0x10, // Data length: 15
0x0f, 0x76, 0x3d, 0x73, 0x70, 0x66, 0x31, 0x20, 0x70, 0x74, 0x72, 0x20, 0x3f, 0x61,
0x6c, 0x6c, // v=spf1 ptr ?all
],
Ok((
0,
Some(
Message {
header: Header {
transaction_id: 0x1032,
flags: 0b1000_0001_1000_0000,
query_response: QueryResponse::Response,
opcode: OpCode::QUERY,
authoritative: false,
truncated: false,
recursion_desired: true,
recursion_available: true,
zflag: false,
authenticated_data: false,
check_disabled: false,
rcode: ResponseCode::NOERROR,
qdcount: 1,
ancount: 1,
nscount: 0,
arcount: 0,
},
queries: vec![
Question {
name: "google.com".as_bytes().to_vec(),
record_type: RecordType::TXT,
record_type_raw: 16,
record_class: RecordClass::IN,
record_class_raw: 1,
}
],
answers: vec![
Answer {
name: "google.com".as_bytes().to_vec(),
rtype: RecordType::TXT,
rtype_raw: 16,
rclass: RecordClass::IN,
rclass_raw: 1,
ttl: 270,
data: (RDataType::TXT("v=spf1 ptr ?all".as_bytes().to_vec())),
}
],
nameservers: vec![],
additional: vec![],
error_flags: ErrorFlags::none(),
}
)))
),
case::parse_mx_response_with_additional_records(
&[
0xf7, 0x6f, // Transaction ID: 0xf76f
0x81, 0x80, // Flags: response, recursion desired, recursion available
0x00, 0x01, // QDCOUNT: 1
0x00, 0x06, // ANCOUNT: 6
0x00, 0x00, // NSCOUNT: 0
0x00, 0x06, // ARCOUNT: 0
0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00,
// question: google.com
0x00, 0x0f, // RType: MX
0x00, 0x01, // RClass: IN
0xc0, 0x0c, // answer: google.com
0x00, 0x0f, // RType: MX
0x00, 0x01, // RClass: IN
0x00, 0x00, 0x02, 0x28, // TTL: 552
0x00, 0x0a, // Data length: 10
0x00, 0x28, // Preference: 40
0x05, 0x73, 0x6d, 0x74, 0x70, 0x34, 0xc0, 0x0c, // MX: smtp4.google.com
0xc0, 0x0c, // answer: google.com
0x00, 0x0f, // RType: MX
0x00, 0x01, // RClass: IN
0x00, 0x00, 0x02, 0x28, // TTL: 552
0x00, 0x0a, // Data length: 10
0x00, 0x0a, // Preference: 10
0x05, 0x73, 0x6d, 0x74, 0x70, 0x35, 0xc0, 0x0c, // MX: smtp5.google.com
0xc0, 0x0c, // answer: google.com
0x00, 0x0f, // RType: MX
0x00, 0x01, // RClass: IN
0x00, 0x00, 0x02, 0x28, // TTL: 552
0x00, 0x0a, // Data length: 10
0x00, 0x0a, // Preference: 10
0x05, 0x73, 0x6d, 0x74, 0x70, 0x36, 0xc0, 0x0c, // MX: smtp6.google.com
0xc0, 0x0c, // answer: google.com
0x00, 0x0f, // RType: MX
0x00, 0x01, // RClass: IN
0x00, 0x00, 0x02, 0x28, // TTL: 552
0x00, 0x0a, // Data length: 10
0x00, 0x0a, // Preference: 10
0x05, 0x73, 0x6d, 0x74, 0x70, 0x31, 0xc0, 0x0c, // MX: smtp1.google.com
0xc0, 0x0c, // answer: google.com
0x00, 0x0f, // RType: MX
0x00, 0x01, // RClass: IN
0x00, 0x00, 0x02, 0x28, // TTL: 552
0x00, 0x0a, // Data length: 10
0x00, 0x0a, // Preference: 10
0x05, 0x73, 0x6d, 0x74, 0x70, 0x32, 0xc0, 0x0c, // MX: smtp2.google.com
0xc0, 0x0c, // answer: google.com
0x00, 0x0f, // RType: MX
0x00, 0x01, // RClass: IN
0x00, 0x00, 0x02, 0x28, // TTL: 552
0x00, 0x0a, // Data length: 10
0x00, 0x28, // Preference: 10
0x05, 0x73, 0x6d, 0x74, 0x70, 0x33, 0xc0, 0x0c, // MX: smtp3.google.com
0xc0, 0x2a, // additional: smtp4.google.com
0x00, 0x01, // RType: A
0x00, 0x01, // RClass: IN
0x00, 0x00, 0x02, 0x58, // TTL: 600
0x00, 0x04, // Data length: 4
0xd8, 0xef, 0x25, 0x1a, // 216.239.37.26
0xc0, 0x40, // additional: smtp5.google.com
0x00, 0x01, // RType: A
0x00, 0x01, // RClass: IN
0x00, 0x00, 0x02, 0x58, // TTL: 600
0x00, 0x04, // Data length: 4
0x40, 0xe9, 0xa7, 0x19, // 64.233.167.25
0xc0, 0x56, // additional: smtp6.google.com
0x00, 0x01, // RType: A
0x00, 0x01, // RClass: IN
0x00, 0x00, 0x02, 0x58, // TTL: 600
0x00, 0x04, // Data length: 4
0x42, 0x66, 0x09, 0x19, // 66.102.9.25
0xc0, 0x6c, // additional: smtp1.google.com
0x00, 0x01, // RType: A
0x00, 0x01, // RClass: IN
0x00, 0x00, 0x02, 0x58, // TTL: 600
0x00, 0x04, // Data length: 4
0xd8, 0xef, 0x39, 0x19, // 216.239.57.25
0xc0, 0x82, // additional: smtp2.google.com
0x00, 0x01, // RType: A
0x00, 0x01, // RClass: IN
0x00, 0x00, 0x02, 0x58, // TTL: 600
0x00, 0x04, // Data length: 4
0xd8, 0xef, 0x25, 0x19, // 216.239.37.25
0xc0, 0x98, // additional: smtp2.google.com
0x00, 0x01, // RType: A
0x00, 0x01, // RClass: IN
0x00, 0x00, 0x02, 0x58, // TTL: 600
0x00, 0x04, // Data length: 4
0xd8, 0xef, 0x39, 0x1a, // 216.239.57.26
],
Ok((
0,
Some(
Message {
header: Header {
transaction_id: 0xf76f,
flags: 0b1000_0001_1000_0000,
query_response: QueryResponse::Response,
opcode: OpCode::QUERY,
authoritative: false,
truncated: false,
recursion_desired: true,
recursion_available: true,
zflag: false,
authenticated_data: false,
check_disabled: false,
rcode: ResponseCode::NOERROR,
qdcount: 1,
ancount: 6,
nscount: 0,
arcount: 6,
},
queries: vec![
Question {
name: "google.com".as_bytes().to_vec(),
record_type: RecordType::MX,
record_type_raw: 15,
record_class: RecordClass::IN,
record_class_raw: 1,
}
],
answers: vec![
Answer {
name: "google.com".as_bytes().to_vec(),
rtype: RecordType::MX,
rtype_raw: 15,
rclass: RecordClass::IN,
rclass_raw: 1,
ttl: 552,
data: (RDataType::MX("smtp4.google.com".as_bytes().to_vec())),
},
Answer {
name: "google.com".as_bytes().to_vec(),
rtype: RecordType::MX,
rtype_raw: 15,
rclass: RecordClass::IN,
rclass_raw: 1,
ttl: 552,
data: (RDataType::MX("smtp5.google.com".as_bytes().to_vec())),
},
Answer {
name: "google.com".as_bytes().to_vec(),
rtype: RecordType::MX,
rtype_raw: 15,
rclass: RecordClass::IN,
rclass_raw: 1,
ttl: 552,
data: (RDataType::MX("smtp6.google.com".as_bytes().to_vec())),
},
Answer {
name: "google.com".as_bytes().to_vec(),
rtype: RecordType::MX,
rtype_raw: 15,
rclass: RecordClass::IN,
rclass_raw: 1,
ttl: 552,
data: (RDataType::MX("smtp1.google.com".as_bytes().to_vec())),
},
Answer {
name: "google.com".as_bytes().to_vec(),
rtype: RecordType::MX,
rtype_raw: 15,
rclass: RecordClass::IN,
rclass_raw: 1,
ttl: 552,
data: (RDataType::MX("smtp2.google.com".as_bytes().to_vec())),
},
Answer {
name: "google.com".as_bytes().to_vec(),
rtype: RecordType::MX,
rtype_raw: 15,
rclass: RecordClass::IN,
rclass_raw: 1,
ttl: 552,
data: (RDataType::MX("smtp3.google.com".as_bytes().to_vec())),
},
],
nameservers: vec![],
additional: vec![
Answer {
name: "smtp4.google.com".as_bytes().to_vec(),
rtype: RecordType::A,
rtype_raw: 1,
rclass: RecordClass::IN,
rclass_raw: 1,
ttl: 600,
data: (RDataType::A(vec![216, 239, 37, 26])),
},
Answer {
name: "smtp5.google.com".as_bytes().to_vec(),
rtype: RecordType::A,
rtype_raw: 1,
rclass: RecordClass::IN,
rclass_raw: 1,
ttl: 600,
data: (RDataType::A(vec![64, 233, 167, 25])),
},
Answer {
name: "smtp6.google.com".as_bytes().to_vec(),
rtype: RecordType::A,
rtype_raw: 1,
rclass: RecordClass::IN,
rclass_raw: 1,
ttl: 600,
data: (RDataType::A(vec![66, 102, 9, 25])),
},
Answer {
name: "smtp1.google.com".as_bytes().to_vec(),
rtype: RecordType::A,
rtype_raw: 1,
rclass: RecordClass::IN,
rclass_raw: 1,
ttl: 600,
data: (RDataType::A(vec![216, 239, 57, 25])),
},
Answer {
name: "smtp2.google.com".as_bytes().to_vec(),
rtype: RecordType::A,
rtype_raw: 1,
rclass: RecordClass::IN,
rclass_raw: 1,
ttl: 600,
data: (RDataType::A(vec![216, 239, 37, 25])),
},
Answer {
name: "smtp3.google.com".as_bytes().to_vec(),
rtype: RecordType::A,
rtype_raw: 1,
rclass: RecordClass::IN,
rclass_raw: 1,
ttl: 600,
data: (RDataType::A(vec![216, 239, 57, 26])),
},
],
error_flags: ErrorFlags::none(),
}
)))
),
case::parse_loc_response(
&[
0x49, 0xa1, 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00,
0x00, 0x1d, 0x00, 0x01, ],
Ok((
0,
Some(
Message {
header: Header {
transaction_id: 0x49a1,
flags: 0b1000_0001_1000_0000,
query_response: QueryResponse::Response,
opcode: OpCode::QUERY,
authoritative: false,
truncated: false,
recursion_desired: true,
recursion_available: true,
zflag: false,
authenticated_data: false,
check_disabled: false,
rcode: ResponseCode::NOERROR,
qdcount: 1,
ancount: 0,
nscount: 0,
arcount: 0,
},
queries: vec![
Question {
name: "google.com".as_bytes().to_vec(),
record_type: RecordType::LOC,
record_type_raw: 29,
record_class: RecordClass::IN,
record_class_raw: 1,
}
],
answers: vec![],
nameservers: vec![],
additional: vec![],
error_flags: ErrorFlags::none(),
}
)))
),
case::parse_ptr_response(
&[
0x9b, 0xbb, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0x31, 0x30, 0x34, 0x01, 0x39, 0x03, 0x31, 0x39, 0x32, 0x02, 0x36, 0x36, 0x07,
0x69, 0x6e, 0x2d, 0x61, 0x64, 0x64, 0x72, 0x04, 0x61, 0x72, 0x70, 0x61, 0x00,
0x00, 0x0c, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x01, 0x51, 0x25, 0x00, 0x20, 0x0c, 0x36, 0x36, 0x2d, 0x31, 0x39, 0x32, 0x2d, 0x39, 0x2d, 0x31, 0x30, 0x34, 0x03, 0x67, 0x65,
0x6e, 0x09, 0x74, 0x77, 0x74, 0x65, 0x6c, 0x65, 0x63, 0x6f, 0x6d, 0x03, 0x6e, 0x65,
0x74, 0x00, ],
Ok((
0,
Some(
Message {
header: Header {
transaction_id: 0x9bbb,
flags: 0b1000_0001_1000_0000,
query_response: QueryResponse::Response,
opcode: OpCode::QUERY,
authoritative: false,
truncated: false,
recursion_desired: true,
recursion_available: true,
zflag: false,
authenticated_data: false,
check_disabled: false,
rcode: ResponseCode::NOERROR,
qdcount: 1,
ancount: 1,
nscount: 0,
arcount: 0,
},
queries: vec![
Question {
name: "104.9.192.66.in-addr.arpa".as_bytes().to_vec(),
record_type: RecordType::PTR,
record_type_raw: 12,
record_class: RecordClass::IN,
record_class_raw: 1,
}
],
answers: vec![
Answer {
name: "104.9.192.66.in-addr.arpa".as_bytes().to_vec(),
rtype: RecordType::PTR,
rtype_raw: 12,
rclass: RecordClass::IN,
rclass_raw: 1,
ttl: 86309,
data: (RDataType::PTR("66-192-9-104.gen.twtelecom.net".as_bytes().to_vec())),
}
],
nameservers: vec![],
additional: vec![],
error_flags: ErrorFlags::none(),
}
)))
),
case::parse_aaaa_response(
&[
0xf0, 0xd4, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0x77, 0x77, 0x77, 0x06, 0x6e, 0x65, 0x74, 0x62, 0x73, 0x64, 0x03, 0x6f, 0x72,
0x67, 0x00, 0x00, 0x1c, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x1c, 0x00, 0x01, 0x00, 0x01, 0x51, 0x80, 0x00, 0x10, 0x20, 0x01, 0x04, 0xf8, 0x00, 0x04, 0x00, 0x07, 0x02, 0xe0, 0x81, 0xff, 0xfe, 0x52,
0x9a, 0x6b, ],
Ok((
0,
Some(
Message {
header: Header {
transaction_id: 0xf0d4,
flags: 0b1000_0001_1000_0000,
query_response: QueryResponse::Response,
opcode: OpCode::QUERY,
authoritative: false,
truncated: false,
recursion_desired: true,
recursion_available: true,
zflag: false,
authenticated_data: false,
check_disabled: false,
rcode: ResponseCode::NOERROR,
qdcount: 1,
ancount: 1,
nscount: 0,
arcount: 0,
},
queries: vec![
Question {
name: "www.netbsd.org".as_bytes().to_vec(),
record_type: RecordType::AAAA,
record_type_raw: 28,
record_class: RecordClass::IN,
record_class_raw: 1,
}],
answers: vec![
Answer {
name: "www.netbsd.org".as_bytes().to_vec(),
rtype: RecordType::AAAA,
rtype_raw: 28,
rclass: RecordClass::IN,
rclass_raw: 1,
ttl: 86400,
data: (RDataType::AAAA(vec![
0x20, 0x01, 0x04, 0xf8, 0x00, 0x04, 0x00, 0x07, 0x02, 0xe0, 0x81, 0xff, 0xfe,
0x52, 0x9a, 0x6b,
])),
}],
nameservers: vec![],
additional: vec![],
error_flags: ErrorFlags::none(),
}
)))
),
case::parse_cname_response(
&[
0x8d, 0xb3, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0x77, 0x77, 0x77, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f,
0x6d, 0x00, 0x00, 0x1c, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x02, 0x79, 0x00, 0x08, 0x03, 0x77, 0x77, 0x77, 0x01, 0x6c, 0xc0, 0x10, ],
Ok((
0,
Some(
Message {
header: Header {
transaction_id: 0x8db3,
flags: 0b1000_0001_1000_0000,
query_response: QueryResponse::Response,
opcode: OpCode::QUERY,
authoritative: false,
truncated: false,
recursion_desired: true,
recursion_available: true,
zflag: false,
authenticated_data: false,
check_disabled: false,
rcode: ResponseCode::NOERROR,
qdcount: 1,
ancount: 1,
nscount: 0,
arcount: 0,
},
queries: vec![
Question {
name: "www.google.com".as_bytes().to_vec(),
record_type: RecordType::AAAA,
record_type_raw: 28,
record_class: RecordClass::IN,
record_class_raw: 1,
}
],
answers: vec![
Answer {
name: "www.google.com".as_bytes().to_vec(),
rtype: RecordType::CNAME,
rtype_raw: 5,
rclass: RecordClass::IN,
rclass_raw: 1,
ttl: 633,
data: (RDataType::CNAME("www.l.google.com".as_bytes().to_vec())),
}
],
nameservers: vec![],
additional: vec![],
error_flags: ErrorFlags::none(),
}
)))
),
case::parse_error_response_no_such_name(
&[
0x26, 0x6d, 0x85,
0x83, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x77, 0x77, 0x77, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x07, 0x6e,
0x6f, 0x74, 0x67, 0x69, 0x6e, 0x68, 0x00, 0x00, 0x1c, 0x00, 0x01, ],
Ok((
0,
Some(
Message {
header: Header {
transaction_id: 0x266d,
flags: 0b1000_0101_1000_0011,
query_response: QueryResponse::Response,
opcode: OpCode::QUERY,
authoritative: true,
truncated: false,
recursion_desired: true,
recursion_available: true,
zflag: false,
authenticated_data: false,
check_disabled: false,
rcode: ResponseCode::NAMEERROR,
qdcount: 1,
ancount: 0,
nscount: 0,
arcount: 0,
},
queries: vec![
Question {
name: "www.example.notginh".as_bytes().to_vec(),
record_type: RecordType::AAAA,
record_type_raw: 28,
record_class: RecordClass::IN,
record_class_raw: 1,
}
],
answers: vec![],
nameservers: vec![],
additional: vec![],
error_flags: ErrorFlags::none(),
}
)))
),
case::parse_any_response(
&[
0xfe, 0xe3, 0x81, 0x80, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x77, 0x77, 0x77, 0x03, 0x69, 0x73, 0x63, 0x03, 0x6f, 0x72, 0x67, 0x00,
0x00, 0xff, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x1c, 0x00, 0x01, 0x00, 0x00, 0x02, 0x58, 0x00, 0x10, 0x20, 0x01, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0d, 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x02, 0x58, 0x00, 0x04, 0xcc, 0x98, 0xb8, 0x58, ],
Ok((
0,
Some(
Message {
header: Header {
transaction_id: 0xfee3,
flags: 0b1000_0001_1000_0000,
query_response: QueryResponse::Response,
opcode: OpCode::QUERY,
authoritative: false,
truncated: false,
recursion_desired: true,
recursion_available: true,
zflag: false,
authenticated_data: false,
check_disabled: false,
rcode: ResponseCode::NOERROR,
qdcount: 1,
ancount: 2,
nscount: 0,
arcount: 0,
},
queries: vec![
Question {
name: "www.isc.org".as_bytes().to_vec(),
record_type: RecordType::ANY,
record_type_raw: 255,
record_class: RecordClass::IN,
record_class_raw: 1,
}
],
answers: vec![
Answer {
name: "www.isc.org".as_bytes().to_vec(),
rtype: RecordType::AAAA,
rtype_raw: 28,
rclass: RecordClass::IN,
rclass_raw: 1,
ttl: 600,
data: (RDataType::AAAA(vec![
0x20, 0x01, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0d,
])),
},
Answer {
name: "www.isc.org".as_bytes().to_vec(),
rtype: RecordType::A,
rtype_raw: 1,
rclass: RecordClass::IN,
rclass_raw: 1,
ttl: 600,
data: (RDataType::A(vec![0xcc, 0x98, 0xb8, 0x58])),
},
],
nameservers: vec![],
additional: vec![],
error_flags: ErrorFlags::none(),
}
)))
),
case::parse_ns_response(
&[
0x20, 0x8a, 0x81, 0x80, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x69, 0x73, 0x63, 0x03, 0x6f, 0x72, 0x67, 0x00, 0x00, 0x02, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0x00, 0x0e, 0x06, 0x6e, 0x73, 0x2d, 0x65, 0x78, 0x74, 0x04, 0x6e, 0x72, 0x74, 0x31, 0xc0, 0x0c,
0xc0, 0x0c, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0x00, 0x0e, 0x06, 0x6e, 0x73, 0x2d, 0x65, 0x78, 0x74, 0x04, 0x73, 0x74, 0x68, 0x31, 0xc0, 0x0c,
0xc0, 0x0c, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0x00, 0x09, 0x06, 0x6e, 0x73, 0x2d, 0x65, 0x78, 0x74, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0x00, 0x0e, 0x06, 0x6e, 0x73, 0x2d, 0x65, 0x78, 0x74, 0x04, 0x6c, 0x67, 0x61, 0x31, 0xc0,
0x0c, ],
Ok((
0,
Some(
Message {
header: Header {
transaction_id: 0x208a,
flags: 0b1000_0001_1000_0000,
query_response: QueryResponse::Response,
opcode: OpCode::QUERY,
authoritative: false,
truncated: false,
recursion_desired: true,
recursion_available: true,
zflag: false,
authenticated_data: false,
check_disabled: false,
rcode: ResponseCode::NOERROR,
qdcount: 1,
ancount: 4,
nscount: 0,
arcount: 0,
},
queries: vec![
Question {
name: "isc.org".as_bytes().to_vec(),
record_type: RecordType::NS,
record_type_raw: 2,
record_class: RecordClass::IN,
record_class_raw: 1,
}
],
answers: vec![
Answer {
name: "isc.org".as_bytes().to_vec(),
rtype: RecordType::NS,
rtype_raw: 2,
rclass: RecordClass::IN,
rclass_raw: 1,
ttl: 3600,
data: (RDataType::NS("ns-ext.nrt1.isc.org".as_bytes().to_vec())),
},
Answer {
name: "isc.org".as_bytes().to_vec(),
rtype: RecordType::NS,
rtype_raw: 2,
rclass: RecordClass::IN,
rclass_raw: 1,
ttl: 3600,
data: (RDataType::NS("ns-ext.sth1.isc.org".as_bytes().to_vec())),
},
Answer {
name: "isc.org".as_bytes().to_vec(),
rtype: RecordType::NS,
rtype_raw: 2,
rclass: RecordClass::IN,
rclass_raw: 1,
ttl: 3600,
data: (RDataType::NS("ns-ext.isc.org".as_bytes().to_vec())),
},
Answer {
name: "isc.org".as_bytes().to_vec(),
rtype: RecordType::NS,
rtype_raw: 2,
rclass: RecordClass::IN,
rclass_raw: 1,
ttl: 3600,
data: (RDataType::NS("ns-ext.lga1.isc.org".as_bytes().to_vec())),
},
],
nameservers: vec![],
additional: vec![],
error_flags: ErrorFlags::none(),
}
)))
),
case::parse_large_txt_response(
&[
0xd3, 0x88, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x6d, 0x69, 0x6d, 0x69, 0x6b, 0x61, 0x74, 0x7a, 0x02, 0x32, 0x31, 0x0b, 0x70,
0x61, 0x63, 0x6b, 0x65, 0x74, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x03, 0x63, 0x6f, 0x6d,
0x00, 0x00, 0x10, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3b, 0x04, 0x25, 0xfa, 0x78, 0x68, 0x44, 0x68, 0x73, 0x48, 0x50, 0x45, 0x6a, 0x31, 0x71, 0x44, 0x72, 0x50,
0x62, 0x47, 0x63, 0x70, 0x54, 0x35, 0x63, 0x6e, 0x66, 0x2f, 0x41, 0x64, 0x55, 0x68,
0x4d, 0x59, 0x49, 0x43, 0x2f, 0x44, 0x43, 0x43, 0x41, 0x76, 0x67, 0x43, 0x41, 0x51,
0x45, 0x77, 0x67, 0x5a, 0x4d, 0x77, 0x66, 0x6a, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47,
0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, 0x43, 0x55, 0x45, 0x77, 0x78, 0x49, 0x6a,
0x41, 0x67, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x54, 0x47, 0x56, 0x56, 0x75,
0x61, 0x58, 0x70, 0x6c, 0x64, 0x47, 0x38, 0x67, 0x56, 0x47, 0x56, 0x6a, 0x61, 0x47,
0x35, 0x76, 0x62, 0x47, 0x39, 0x6e, 0x61, 0x57, 0x56, 0x7a, 0x49, 0x46, 0x4d, 0x75,
0x51, 0x53, 0x34, 0x78, 0x4a, 0x7a, 0x41, 0x6c, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41,
0x73, 0x54, 0x48, 0x6b, 0x4e, 0x6c, 0x63, 0x6e, 0x52, 0x31, 0x62, 0x53, 0x42, 0x44,
0x5a, 0x58, 0x4a, 0x30, 0x61, 0x57, 0x5a, 0x70, 0x59, 0x32, 0x46, 0x30, 0x61, 0x57,
0x39, 0x75, 0x49, 0x45, 0x46, 0x31, 0x64, 0x47, 0x68, 0x76, 0x63, 0x6d, 0x6c, 0x30,
0x65, 0x54, 0x45, 0x69, 0x4d, 0x43, 0x41, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78,
0x4d, 0x5a, 0x51, 0x32, 0x56, 0x79, 0x64, 0x48, 0x56, 0x74, 0x49, 0x46, 0x52, 0x79,
0x64, 0x58, 0x4e, 0x30, 0x5a, 0x57, 0x51, 0x67, 0x54, 0x6d, 0x56, 0x30, 0x64, 0x32,
0x39, 0x79, 0x61, 0x79, 0x42, 0x44, 0x51, 0x51, 0x49, 0x52, 0x41, 0x50, 0x35, 0x6e,
0x35, 0x50, 0x46, 0x61, 0x4a, 0x4f, 0x50, 0x47, 0x44, 0x56, 0x52, 0x38, 0x6f, 0x43,
0x44, 0x43, 0x64, 0x6e, 0x41, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x59, 0x49, 0xfa, 0x5a, 0x49, 0x41, 0x57, 0x55, 0x44, 0x42, 0x41, 0x49, 0x42, 0x42, 0x51, 0x43, 0x67,
0x67, 0x67, 0x45, 0x35, 0x4d, 0x42, 0x6f, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49,
0x62, 0x33, 0x44, 0x51, 0x45, 0x4a, 0x41, 0x7a, 0x45, 0x4e, 0x42, 0x67, 0x73, 0x71,
0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x43, 0x52, 0x41, 0x42, 0x42, 0x44,
0x41, 0x63, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42,
0x43, 0x51, 0x55, 0x78, 0x44, 0x78, 0x63, 0x4e, 0x4d, 0x54, 0x6b, 0x77, 0x4e, 0x7a,
0x45, 0x77, 0x4d, 0x6a, 0x45, 0x78, 0x4d, 0x54, 0x45, 0x7a, 0x57, 0x6a, 0x41, 0x76,
0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x43, 0x51,
0x51, 0x78, 0x49, 0x67, 0x51, 0x67, 0x52, 0x55, 0x44, 0x4c, 0x4e, 0x54, 0x6f, 0x68,
0x36, 0x2b, 0x74, 0x6a, 0x2f, 0x6b, 0x39, 0x7a, 0x47, 0x54, 0x6d, 0x44, 0x39, 0x76,
0x65, 0x65, 0x32, 0x6a, 0x43, 0x38, 0x78, 0x6b, 0x5a, 0x53, 0x68, 0x31, 0x4a, 0x64,
0x43, 0x39, 0x47, 0x6a, 0x53, 0x61, 0x49, 0x77, 0x67, 0x63, 0x73, 0x47, 0x43, 0x79,
0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x4a, 0x45, 0x41, 0x49, 0x4d,
0x4d, 0x59, 0x47, 0x37, 0x4d, 0x49, 0x47, 0x34, 0x4d, 0x49, 0x47, 0x31, 0x4d, 0x49,
0x47, 0x79, 0x42, 0x42, 0x52, 0x50, 0x6a, 0x55, 0x78, 0x49, 0x42, 0x6b, 0x6c, 0x43,
0x61, 0x75, 0x2b, 0x4c, 0x68, 0x74, 0x54, 0x56, 0x2f, 0x48, 0x6b, 0x79, 0x35, 0x78,
0x51, 0x74, 0x68, 0x54, 0x43, 0x42, 0x6d, 0x54, 0x43, 0x42, 0x67, 0x36, 0x53, 0x42,
0x67, 0x44, 0x42, 0x2b, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0xfa, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x51, 0x54, 0x44, 0x45, 0x69, 0x4d, 0x43,
0x41, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4d, 0x5a, 0x56, 0x57, 0x35, 0x70,
0x65, 0x6d, 0x56, 0x30, 0x62, 0x79, 0x42, 0x55, 0x5a, 0x57, 0x4e, 0x6f, 0x62, 0x6d,
0x39, 0x73, 0x62, 0x32, 0x64, 0x70, 0x5a, 0x58, 0x4d, 0x67, 0x55, 0x79, 0x35, 0x42,
0x4c, 0x6a, 0x45, 0x6e, 0x4d, 0x43, 0x55, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x78,
0x4d, 0x65, 0x51, 0x32, 0x56, 0x79, 0x64, 0x48, 0x56, 0x74, 0x49, 0x45, 0x4e, 0x6c,
0x63, 0x6e, 0x52, 0x70, 0x5a, 0x6d, 0x6c, 0x6a, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32,
0x34, 0x67, 0x51, 0x58, 0x56, 0x30, 0x61, 0x47, 0x39, 0x79, 0x61, 0x58, 0x52, 0x35,
0x4d, 0x53, 0x49, 0x77, 0x49, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78,
0x6c, 0x44, 0x5a, 0x58, 0x4a, 0x30, 0x64, 0x57, 0x30, 0x67, 0x56, 0x48, 0x4a, 0x31,
0x63, 0x33, 0x52, 0x6c, 0x5a, 0x43, 0x42, 0x4f, 0x5a, 0x58, 0x52, 0x33, 0x62, 0x33,
0x4a, 0x72, 0x49, 0x45, 0x4e, 0x42, 0x41, 0x68, 0x45, 0x41, 0x2f, 0x6d, 0x66, 0x6b,
0x38, 0x56, 0x6f, 0x6b, 0x34, 0x38, 0x59, 0x4e, 0x56, 0x48, 0x79, 0x67, 0x49, 0x4d,
0x4a, 0x32, 0x63, 0x44, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47,
0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x53, 0x43, 0x41, 0x51,
0x41, 0x77, 0x33, 0x56, 0x52, 0x77, 0x6a, 0x78, 0x4b, 0x31, 0x44, 0x45, 0x33, 0x52,
0x43, 0x38, 0x51, 0x58, 0x44, 0x61, 0x76, 0x33, 0x57, 0x63, 0x6c, 0x45, 0x5a, 0x56,
0x67, 0x7a, 0x56, 0x7a, 0x59, 0x7a, 0x45, 0x59, 0x53, 0x4f, 0x6e, 0x4c, 0xfa, 0x48, 0x54, 0x4f, 0x4b, 0x49, 0x44, 0x75, 0x2b, 0x4e, 0x51, 0x6a, 0x6e, 0x55, 0x66,
0x36, 0x4d, 0x68, 0x61, 0x51, 0x51, 0x2f, 0x67, 0x50, 0x4d, 0x52, 0x73, 0x75, 0x55,
0x6c, 0x35, 0x41, 0x6a, 0x68, 0x64, 0x4a, 0x6a, 0x6f, 0x66, 0x54, 0x6c, 0x46, 0x78,
0x62, 0x68, 0x66, 0x61, 0x47, 0x4a, 0x4e, 0x47, 0x6f, 0x52, 0x50, 0x4a, 0x55, 0x5a,
0x53, 0x6a, 0x53, 0x33, 0x53, 0x46, 0x58, 0x63, 0x63, 0x33, 0x6a, 0x48, 0x6d, 0x6e,
0x35, 0x4e, 0x56, 0x2b, 0x2f, 0x58, 0x69, 0x70, 0x54, 0x33, 0x61, 0x55, 0x2f, 0x48,
0x56, 0x64, 0x2b, 0x49, 0x41, 0x31, 0x42, 0x55, 0x6c, 0x68, 0x63, 0x43, 0x74, 0x43,
0x71, 0x4d, 0x53, 0x68, 0x59, 0x2b, 0x56, 0x36, 0x65, 0x31, 0x5a, 0x5a, 0x39, 0x4f,
0x72, 0x34, 0x4c, 0x5a, 0x79, 0x6b, 0x33, 0x70, 0x6c, 0x65, 0x39, 0x52, 0x7a, 0x6f,
0x6d, 0x30, 0x42, 0x63, 0x44, 0x32, 0x4f, 0x6e, 0x4c, 0x4f, 0x70, 0x45, 0x7a, 0x51,
0x72, 0x75, 0x62, 0x44, 0x46, 0x72, 0x36, 0x78, 0x4b, 0x41, 0x45, 0x2f, 0x6d, 0x51,
0x66, 0x74, 0x41, 0x6e, 0x75, 0x51, 0x36, 0x77, 0x73, 0x71, 0x50, 0x42, 0x58, 0x49,
0x2f, 0x79, 0x46, 0x36, 0x42, 0x31, 0x62, 0x59, 0x44, 0x36, 0x38, 0x79, 0x41, 0x4e,
0x6f, 0x64, 0x6a, 0x38, 0x78, 0x71, 0x6d, 0x55, 0x73, 0x33, 0x33, 0x4e, 0x76, 0x4e,
0x4d, 0x62, 0x2b, 0x32, 0x6f, 0x4e, 0x49, 0x67, 0x4c, 0x71, 0x54, 0x34, 0x65, 0x31,
0x46, 0x64, 0x4d, 0x6d, 0x72, 0x4f, 0x54, 0x31, 0x41, 0x53, 0x50, 0x76, 0x2f, 0x52,
0x6a, 0x31, 0x44, 0x54, 0x79, 0x78, 0x64, 0x41, 0x30, 0x4a, 0x44, 0x70, 0x41, 0x45,
0x46, 0x59, 0x48, 0x6d, 0x35, 0x78, 0x57, 0x4b, 0x33, 0x36, 0x72, 0x38, 0x38, 0x35, 0x78, 0x54, 0x63, 0x62, 0x4b, 0x34, 0x48, 0x69, 0x37, 0x54, 0x33, 0x4f, 0x39,
0x55, 0x76, 0x50, 0x43, 0x72, 0x69, 0x68, 0x70, 0x44, 0x4a, 0x65, 0x70, 0x63, 0x6f,
0x46, 0x4e, 0x42, 0x69, 0x62, 0x46, 0x6c, 0x59, 0x4f, 0x46, 0x66, 0x6c, 0x6c, 0x59,
0x57, 0x36, 0x38, 0x58, 0x31, 0x66, 0x72, 0x57, 0x53, 0x6a, 0x41, 0x41, 0x41,
0x41,
],
Ok((
0,
Some(
Message {
header: Header {
transaction_id: 0xd388,
flags: 0b1000_0001_1000_0000,
query_response: QueryResponse::Response,
opcode: OpCode::QUERY,
authoritative: false,
truncated: false,
recursion_desired: true,
recursion_available: true,
zflag: false,
authenticated_data: false,
check_disabled: false,
rcode: ResponseCode::NOERROR,
qdcount: 1,
ancount: 1,
nscount: 0,
arcount: 0,
},
queries: vec![
Question {
name: "mimikatz.21.packetclass.com".as_bytes().to_vec(),
record_type: RecordType::TXT,
record_type_raw: 16,
record_class: RecordClass::IN,
record_class_raw: 1,
}
],
answers: vec![
Answer {
name: "mimikatz.21.packetclass.com".as_bytes().to_vec(),
rtype: RecordType::TXT,
rtype_raw: 16,
rclass: RecordClass::IN,
rclass_raw: 1,
ttl: 59,
data: (RDataType::TXT(
"xhDhsHPEj1qDrPbGcpT5cnf/AdUhMYIC/DCCAvgCAQEwgZMwfjELMAk\
GA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFM\
uQS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml\
0eTEiMCAGA1UEAxMZQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQQIRAP5\
n5PFaJOPGDVR8oCDCdnAwDQYJYIZIAWUDBAIBBQCgggE5MBoGCSqGSIb\
3DQEJAzENBgsqhkiG9w0BCRABBDAcBgkqhkiG9w0BCQUxDxcNMTkwNzE\
wMjExMTEzWjAvBgkqhkiG9w0BCQQxIgQgRUDLNToh6+tj/k9zGTmD9ve\
e2jC8xkZSh1JdC9GjSaIwgcsGCyqGSIb3DQEJEAIMMYG7MIG4MIG1MIG\
yBBRPjUxIBklCau+LhtTV/Hky5xQthTCBmTCBg6SBgDB+MQswCQYDVQQ\
GEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjE\
nMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSI\
wIAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBAhEA/mfk8Vo\
k48YNVHygIMJ2cDANBgkqhkiG9w0BAQEFAASCAQAw3VRwjxK1DE3RC8Q\
XDav3WclEZVgzVzYzEYSOnLHTOKIDu+NQjnUf6MhaQQ/gPMRsuUl5Ajh\
dJjofTlFxbhfaGJNGoRPJUZSjS3SFXcc3jHmn5NV+/XipT3aU/HVd+IA\
1BUlhcCtCqMShY+V6e1ZZ9Or4LZyk3ple9Rzom0BcD2OnLOpEzQrubDF\
r6xKAE/mQftAnuQ6wsqPBXI/yF6B1bYD68yANodj8xqmUs33NvNMb+2o\
NIgLqT4e1FdMmrOT1ASPv/Rj1DTyxdA0JDpAEFYHm5xWK36r85xTcbK4\
Hi7T3O9UvPCrihpDJepcoFNBibFlYOFfllYW68X1frWSjAAAA"
.as_bytes()
.to_vec(),
)),
}
],
nameservers: vec![],
additional: vec![],
error_flags: ErrorFlags::none(),
}
)))
),
case::parse_soa_response_with_opt_ar(
&[
0x82, 0x95, 0x81, 0x83, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x03, 0x64, 0x6e, 0x65, 0x04, 0x6f, 0x69, 0x73, 0x66, 0x03, 0x6e, 0x65, 0x74, 0x00,
0x00, 0x01, 0x00, 0x01, 0xc0, 0x10, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x03, 0x83, 0x00, 0x45, 0x06, 0x6e, 0x73, 0x2d, 0x31, 0x31, 0x30, 0x09, 0x61, 0x77, 0x73, 0x64, 0x6e, 0x73,
0x2d, 0x31, 0x33, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x11, 0x61, 0x77, 0x73, 0x64, 0x6e, 0x73, 0x2d, 0x68, 0x6f, 0x73, 0x74, 0x6d, 0x61,
0x73, 0x74, 0x65, 0x72, 0x06, 0x61, 0x6d, 0x61, 0x7a, 0x6f, 0x6e, 0xc0, 0x3b,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1c, 0x20, 0x00, 0x00, 0x03, 0x84, 0x00, 0x12, 0x75, 0x00, 0x00, 0x01, 0x51, 0x80, 0x00, 0x00, 0x29, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ],
Ok((
0,
Some(
Message {
header: Header {
transaction_id: 0x8295,
flags: 0b1000_0001_1000_0011,
query_response: QueryResponse::Response,
opcode: OpCode::QUERY,
authoritative: false,
truncated: false,
recursion_desired: true,
recursion_available: true,
zflag: false,
authenticated_data: false,
check_disabled: false,
rcode: ResponseCode::NAMEERROR,
qdcount: 1,
ancount: 0,
nscount: 1,
arcount: 1,
},
queries: vec![
Question {
name: "dne.oisf.net".as_bytes().to_vec(),
record_type: RecordType::A,
record_type_raw: 1,
record_class: RecordClass::IN,
record_class_raw: 1,
}
],
answers: vec![],
nameservers: vec![
Answer {
name: "oisf.net".as_bytes().to_vec(),
rtype: RecordType::SOA,
rtype_raw: 6,
rclass: RecordClass::IN,
rclass_raw: 1,
ttl: 899,
data: (RDataType::SOA(RDataSoa {
mname: "ns-110.awsdns-13.com".as_bytes().to_vec(),
rname: "awsdns-hostmaster.amazon.com".as_bytes().to_vec(),
serial: 1,
refresh: 7200,
retry: 900,
expire: 1209600,
minimum: 86400,
})),
}
],
additional: vec![
Answer {
name: vec![0x00],
rtype: RecordType::OPT,
rtype_raw: 41,
rclass: RecordClass::NONE,
rclass_raw: 254,
ttl: 0,
data: (RDataType::OPT(RDataOPT {
udp_payload_size: 512,
extended_rcode: 0x00,
version: 0,
flags: 0,
data: vec![],
})),
}
],
error_flags: ErrorFlags::none(),
}
)))
),
case::multiple_opt_responses(
&[
0x82, 0x95, 0x81, 0x83, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x64, 0x6e, 0x65, 0x04, 0x6f, 0x69, 0x73, 0x66, 0x03, 0x6e, 0x65, 0x74, 0x00,
0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x29, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ],
Ok((
0,
Some(
Message {
header: Header {
transaction_id: 0x8295,
flags: 0b1000_0001_1000_0011,
query_response: QueryResponse::Response,
opcode: OpCode::QUERY,
authoritative: false,
truncated: false,
recursion_desired: true,
recursion_available: true,
zflag: false,
authenticated_data: false,
check_disabled: false,
rcode: ResponseCode::NAMEERROR,
qdcount: 1,
ancount: 0,
nscount: 0,
arcount: 2,
},
queries: vec![
Question {
name: vec![100, 110, 101, 46, 111, 105, 115, 102, 46, 110, 101, 116],
record_type: RecordType::A,
record_type_raw: 1,
record_class: RecordClass::IN,
record_class_raw: 1,
}
],
answers: vec![],
nameservers: vec![],
additional: vec![
Answer {
name: vec![0x00],
rtype: RecordType::OPT,
rtype_raw: 41,
rclass: RecordClass::NONE,
rclass_raw: 254,
ttl: 0,
data: (RDataType::OPT(RDataOPT {
udp_payload_size: 512,
extended_rcode: 0x00,
version: 0,
flags: 0,
data: vec![],
})),
},
Answer {
name: vec![0x00],
rtype: RecordType::OPT,
rtype_raw: 41,
rclass: RecordClass::NONE,
rclass_raw: 254,
ttl: 0,
data: (RDataType::OPT(RDataOPT {
udp_payload_size: 512,
extended_rcode: 0x00,
version: 0,
flags: 0,
data: vec![],
})),
},
],
error_flags: ErrorFlags::ExtraOptRr.into(),
}
)))
),
case::parse_opt_ar_not_enough_data(
&[
0x82, 0x95, 0x81, 0x83, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x03, 0x64, 0x6e, 0x65, 0x04, 0x6f, 0x69, 0x73, 0x66, 0x03, 0x6e, 0x65, 0x74, 0x00,
0x00, 0x01, 0x00, 0x01, 0xc0, 0x10, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x03, 0x83, 0x00, 0x45, 0x06, 0x6e, 0x73, 0x2d, 0x31, 0x31, 0x30, 0x09, 0x61, 0x77, 0x73, 0x64, 0x6e, 0x73,
0x2d, 0x31, 0x33, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x11, 0x61, 0x77, 0x73, 0x64, 0x6e, 0x73, 0x2d, 0x68, 0x6f, 0x73, 0x74, 0x6d, 0x61,
0x73, 0x74, 0x65, 0x72, 0x06, 0x61, 0x6d, 0x61, 0x7a, 0x6f, 0x6e, 0xc0, 0x3b,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1c, 0x20, 0x00, 0x00, 0x03, 0x84, 0x00, 0x12, 0x75, 0x00, 0x00, 0x01, 0x51, 0x80, 0x00, 0x00, 0x29, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, ],
Err(Error::incomplete_needed(2))
),
case::parse_srv_response(
&[
0xc4, 0xdb, 0x85, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, 0x6b, 0x65, 0x72, 0x62, 0x65, 0x72, 0x6f, 0x73, 0x04, 0x5f, 0x74, 0x63,
0x70, 0x05, 0x53, 0x41, 0x4d, 0x42, 0x41, 0x07, 0x45, 0x58, 0x41, 0x4d, 0x50, 0x4c,
0x45, 0x03, 0x43, 0x4f, 0x4d, 0x00, 0x00, 0x21, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x03, 0x84, 0x00, 0x21, 0x00, 0x00, 0x00, 0x64, 0x00, 0x58, 0x07, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x64, 0x63, 0x05, 0x73, 0x61, 0x6d, 0x62, 0x61,
0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d,
0x00, ],
Ok((
0,
Some(
Message {
header: Header {
transaction_id: 0xc4db,
flags: 0b1000_0101_1000_0000,
query_response: QueryResponse::Response,
opcode: OpCode::QUERY,
authoritative: true,
truncated: false,
recursion_desired: true,
recursion_available: true,
zflag: false,
authenticated_data: false,
check_disabled: false,
rcode: ResponseCode::NOERROR,
qdcount: 1,
ancount: 1,
nscount: 0,
arcount: 0
},
queries: vec![
Question {
name: "_kerberos._tcp.SAMBA.EXAMPLE.COM".as_bytes().to_vec(),
record_type: RecordType::SRV,
record_type_raw: 33,
record_class: RecordClass::IN,
record_class_raw: 1,
}
],
answers: vec![
Answer {
name: "_kerberos._tcp.SAMBA.EXAMPLE.COM".as_bytes().to_vec(),
rtype: RecordType::SRV,
rtype_raw: 33,
rclass: RecordClass::IN,
rclass_raw: 1,
ttl: 900,
data: RDataType::SRV(RDataSRV {
priority: 0,
weight: 100,
port: 88,
target: "localdc.samba.example.com".as_bytes().to_vec()
})
}
],
nameservers: vec![],
additional: vec![],
error_flags: ErrorFlags::none()
}
)))
),
case::parse_sshfp_response(
&[
0x70, 0x31, 0x81,
0xa0, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x08, 0x6d, 0x61, 0x6e, 0x79, 0x2d, 0x72, 0x72, 0x73, 0x08, 0x77, 0x65, 0x62, 0x65,
0x72, 0x64, 0x6e, 0x73, 0x02, 0x64, 0x65, 0x00, 0x00, 0x2c, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x2c, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0x00, 0x22, 0x03, 0x02, 0xf2, 0xb4, 0xee, 0x8f, 0x42, 0x0f, 0x05, 0x56, 0x2b, 0x23, 0x49, 0x7d, 0x41, 0x0e,
0xea, 0x8d, 0xfa, 0xe6, 0x01, 0x7d, 0xba, 0x82, 0x51, 0xc2, 0x63, 0x36, 0x8a, 0x57,
0x94, 0xb5, 0xd7, 0x43,
0xc0, 0x0c, 0x00, 0x2c, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0x00, 0x16, 0x04, 0x01, 0xe9, 0xd7, 0x62, 0xca, 0x6b, 0x63, 0x93, 0x1a, 0x92, 0xde, 0x1c, 0x69, 0x7d, 0xe3,
0x25, 0x76, 0xb8, 0xf6, 0x88, 0xf7,
0xc0, 0x0c, 0x00, 0x2c, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0x00, 0x22, 0x02, 0x02, 0x23, 0xfb, 0x15, 0x47, 0x76, 0x9a, 0x83, 0x1b, 0x44, 0x21, 0x30, 0x0e, 0x69, 0xbd,
0xff, 0xcd, 0xd1, 0x65, 0x00, 0x10, 0x0a, 0x3c, 0xd5, 0xb9, 0xce, 0xd7, 0xc6, 0x89,
0xde, 0xbb, 0x09, 0xe7,
0xc0, 0x0c, 0x00, 0x2c, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0x00, 0x22, 0x01, 0x02, 0x49, 0x00, 0xa9, 0x38, 0xd3, 0xd6, 0x67, 0x80, 0x28, 0x2b, 0xd1, 0x1e, 0xd0, 0xb1,
0xad, 0xd1, 0x85, 0xb8, 0x40, 0xa5, 0xe5, 0x35, 0x93, 0xc7, 0xe3, 0xb6, 0x1f, 0x05,
0xb6, 0x38, 0x09, 0x57,
0xc0, 0x0c, 0x00, 0x2c, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0x00, 0x16, 0x01, 0x01, 0x3e, 0xef, 0xea, 0x71, 0xca, 0x65, 0xfb, 0x5d, 0x8f, 0x45, 0xf4, 0x33, 0x0b, 0x72,
0x68, 0xb4, 0xa4, 0x1d, 0x14, 0xa5,
0xc0, 0x0c, 0x00, 0x2c, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0x00, 0x16, 0x03, 0x01, 0x1f, 0x2d, 0x63, 0x72, 0x57, 0x10, 0xd1, 0x5c, 0x14, 0xfd, 0x88, 0xab, 0xf4, 0xec,
0x9c, 0xab, 0x05, 0x54, 0xc6, 0x33,
0xc0, 0x0c, 0x00, 0x2c, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0x00, 0x22, 0x04, 0x02, 0x94, 0x92, 0x2e, 0xc5, 0xb5, 0xdb, 0x59, 0xe4, 0x81, 0xad, 0x9d, 0x92, 0xaf, 0x3d,
0x8a, 0x51, 0x0b, 0x1a, 0x64, 0x6c, 0x14, 0xa4, 0x96, 0x32, 0x43, 0x9b, 0x58, 0x7b,
0x16, 0xf8, 0xf7, 0xbe,
0xc0, 0x0c, 0x00, 0x2c, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0x00, 0x16, 0x02, 0x01, 0x5d, 0xed, 0xb2, 0x7f, 0x44, 0x8e, 0x1f, 0x5c, 0xbc, 0x67, 0x73, 0xbb, 0xc6, 0xc5,
0x0e, 0x51, 0xdf, 0xc1, 0xe1, 0x8d,
0x00, 0x00, 0x29, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ],
Ok((
0,
Some(
Message {
header: Header {
transaction_id: 0x7031,
flags: 0b1000_0001_1010_0000,
query_response: QueryResponse::Response,
opcode: OpCode::QUERY,
authoritative: false,
truncated: false,
recursion_desired: true,
recursion_available: true,
zflag: false,
authenticated_data: true,
check_disabled: false,
rcode: ResponseCode::NOERROR,
qdcount: 1,
ancount: 8,
nscount: 0,
arcount: 1
},
queries: vec![
Question {
name: "many-rrs.weberdns.de".as_bytes().to_vec(),
record_type: RecordType::SSHFP,
record_type_raw: 44,
record_class: RecordClass::IN,
record_class_raw: 1,
}
],
answers: vec![
Answer {
name: "many-rrs.weberdns.de".as_bytes().to_vec(),
rtype: RecordType::SSHFP,
rtype_raw: 44,
rclass: RecordClass::IN,
rclass_raw: 1,
ttl: 3600,
data: (RDataType::SSHFP(RDataSSHFP {
algorithm: SshfpAlgorithm::ECDSA,
fingerprint_type: SshfpFingerprint::SHA256,
fingerprint: vec![
0xf2, 0xb4, 0xee, 0x8f, 0x42, 0x0f, 0x05, 0x56, 0x2b, 0x23, 0x49,
0x7d, 0x41, 0x0e, 0xea, 0x8d, 0xfa, 0xe6, 0x01, 0x7d, 0xba, 0x82,
0x51, 0xc2, 0x63, 0x36, 0x8a, 0x57, 0x94, 0xb5, 0xd7, 0x43,
]
}))
},
Answer {
name: "many-rrs.weberdns.de".as_bytes().to_vec(),
rtype: RecordType::SSHFP,
rtype_raw: 44,
rclass: RecordClass::IN,
rclass_raw: 1,
ttl: 3600,
data: (RDataType::SSHFP(RDataSSHFP {
algorithm: SshfpAlgorithm::Ed25519,
fingerprint_type: SshfpFingerprint::SHA1,
fingerprint: vec![
0xe9, 0xd7, 0x62, 0xca, 0x6b, 0x63, 0x93, 0x1a, 0x92, 0xde, 0x1c,
0x69, 0x7d, 0xe3, 0x25, 0x76, 0xb8, 0xf6, 0x88, 0xf7,
]
}))
},
Answer {
name: "many-rrs.weberdns.de".as_bytes().to_vec(),
rtype: RecordType::SSHFP,
rtype_raw: 44,
rclass: RecordClass::IN,
rclass_raw: 1,
ttl: 3600,
data: (RDataType::SSHFP(RDataSSHFP {
algorithm: SshfpAlgorithm::DSA,
fingerprint_type: SshfpFingerprint::SHA256,
fingerprint: vec![
0x23, 0xfb, 0x15, 0x47, 0x76, 0x9a, 0x83, 0x1b, 0x44, 0x21, 0x30,
0x0e, 0x69, 0xbd, 0xff, 0xcd, 0xd1, 0x65, 0x00, 0x10, 0x0a, 0x3c,
0xd5, 0xb9, 0xce, 0xd7, 0xc6, 0x89, 0xde, 0xbb, 0x09, 0xe7,
]
}))
},
Answer {
name: "many-rrs.weberdns.de".as_bytes().to_vec(),
rtype: RecordType::SSHFP,
rtype_raw: 44,
rclass: RecordClass::IN,
rclass_raw: 1,
ttl: 3600,
data: (RDataType::SSHFP(RDataSSHFP {
algorithm: SshfpAlgorithm::RSA,
fingerprint_type: SshfpFingerprint::SHA256,
fingerprint: vec![
0x49, 0x00, 0xa9, 0x38, 0xd3, 0xd6, 0x67, 0x80, 0x28, 0x2b, 0xd1,
0x1e, 0xd0, 0xb1, 0xad, 0xd1, 0x85, 0xb8, 0x40, 0xa5, 0xe5, 0x35,
0x93, 0xc7, 0xe3, 0xb6, 0x1f, 0x05, 0xb6, 0x38, 0x09, 0x57,
]
}))
},
Answer {
name: "many-rrs.weberdns.de".as_bytes().to_vec(),
rtype: RecordType::SSHFP,
rtype_raw: 44,
rclass: RecordClass::IN,
rclass_raw: 1,
ttl: 3600,
data: (RDataType::SSHFP(RDataSSHFP {
algorithm: SshfpAlgorithm::RSA,
fingerprint_type: SshfpFingerprint::SHA1,
fingerprint: vec![
0x3e, 0xef, 0xea, 0x71, 0xca, 0x65, 0xfb, 0x5d, 0x8f, 0x45, 0xf4,
0x33, 0x0b, 0x72, 0x68, 0xb4, 0xa4, 0x1d, 0x14, 0xa5,
]
}))
},
Answer {
name: "many-rrs.weberdns.de".as_bytes().to_vec(),
rtype: RecordType::SSHFP,
rtype_raw: 44,
rclass: RecordClass::IN,
rclass_raw: 1,
ttl: 3600,
data: (RDataType::SSHFP(RDataSSHFP {
algorithm: SshfpAlgorithm::ECDSA,
fingerprint_type: SshfpFingerprint::SHA1,
fingerprint: vec![
0x1f, 0x2d, 0x63, 0x72, 0x57, 0x10, 0xd1, 0x5c, 0x14, 0xfd, 0x88,
0xab, 0xf4, 0xec, 0x9c, 0xab, 0x05, 0x54, 0xc6, 0x33,
]
}))
},
Answer {
name: "many-rrs.weberdns.de".as_bytes().to_vec(),
rtype: RecordType::SSHFP,
rtype_raw: 44,
rclass: RecordClass::IN,
rclass_raw: 1,
ttl: 3600,
data: (RDataType::SSHFP(RDataSSHFP {
algorithm: SshfpAlgorithm::Ed25519,
fingerprint_type: SshfpFingerprint::SHA256,
fingerprint: vec![
0x94, 0x92, 0x2e, 0xc5, 0xb5, 0xdb, 0x59, 0xe4, 0x81, 0xad, 0x9d,
0x92, 0xaf, 0x3d, 0x8a, 0x51, 0x0b, 0x1a, 0x64, 0x6c, 0x14, 0xa4,
0x96, 0x32, 0x43, 0x9b, 0x58, 0x7b, 0x16, 0xf8, 0xf7, 0xbe,
]
}))
},
Answer {
name: "many-rrs.weberdns.de".as_bytes().to_vec(),
rtype: RecordType::SSHFP,
rtype_raw: 44,
rclass: RecordClass::IN,
rclass_raw: 1,
ttl: 3600,
data: (RDataType::SSHFP(RDataSSHFP {
algorithm: SshfpAlgorithm::DSA,
fingerprint_type: SshfpFingerprint::SHA1,
fingerprint: vec![
0x5d, 0xed, 0xb2, 0x7f, 0x44, 0x8e, 0x1f, 0x5c, 0xbc, 0x67, 0x73,
0xbb, 0xc6, 0xc5, 0x0e, 0x51, 0xdf, 0xc1, 0xe1, 0x8d,
]
}))
},
],
nameservers: vec![],
additional: vec![Answer {
name: vec![0],
rtype: RecordType::OPT,
rtype_raw: 41,
rclass: RecordClass::NONE,
rclass_raw: 254,
ttl: 0,
data: RDataType::OPT(RDataOPT {
udp_payload_size: 4096,
extended_rcode: 0,
version: 0,
flags: 0,
data: vec![]
})
}],
error_flags: ErrorFlags::none()
}
)))
),
case::parse_tkey_tsig_response(
&[
0x02, 0x34, 0x80, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0a, 0x33, 0x32, 0x35, 0x39, 0x33, 0x36, 0x35, 0x39, 0x35, 0x34, 0x13, 0x73, 0x69,
0x67, 0x2d, 0x77, 0x69, 0x6e, 0x2d, 0x73, 0x74, 0x37, 0x62, 0x6f, 0x30, 0x30, 0x33,
0x73, 0x70, 0x6f, 0x08, 0x68, 0x6f, 0x6d, 0x65, 0x74, 0x65, 0x73, 0x74, 0x03, 0x6c,
0x61, 0x6e, 0x00, 0x00, 0xf9, 0x00, 0xff, 0x0a, 0x33, 0x32, 0x35, 0x39, 0x33, 0x36, 0x35, 0x39, 0x35, 0x34, 0x13, 0x73, 0x69,
0x67, 0x2d, 0x77, 0x69, 0x6e, 0x2d, 0x73, 0x74, 0x37, 0x62, 0x6f, 0x30, 0x30, 0x33,
0x73, 0x70, 0x6f, 0x08, 0x68, 0x6f, 0x6d, 0x65, 0x74, 0x65, 0x73, 0x74, 0x03, 0x6c,
0x61, 0x6e, 0x00, 0x00, 0xf9, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x08, 0x67, 0x73, 0x73, 0x2d, 0x74, 0x73, 0x69, 0x67,
0x00, 0x50, 0xf8, 0xcf, 0xbb,
0x50, 0xfa, 0x21, 0x3b,
0x00, 0x03, 0x00, 0x00, 0x00, 0xba, 0xa1, 0x81, 0xb7, 0x30, 0x81, 0xb4, 0xa0, 0x03, 0x0a, 0x01, 0x00, 0xa1, 0x0b, 0x06,
0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, 0xa2, 0x81, 0x9f, 0x04,
0x81, 0x9c, 0x60, 0x81, 0x99, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01,
0x02, 0x02, 0x02, 0x00, 0x6f, 0x81, 0x89, 0x30, 0x81, 0x86, 0xa0, 0x03, 0x02, 0x01,
0x05, 0xa1, 0x03, 0x02, 0x01, 0x0f, 0xa2, 0x7a, 0x30, 0x78, 0xa0, 0x03, 0x02, 0x01,
0x12, 0xa2, 0x71, 0x04, 0x6f, 0x32, 0x94, 0x40, 0xf8, 0xae, 0xaa, 0xbd, 0xa2, 0x9e,
0x7e, 0x78, 0x1d, 0x0f, 0xf0, 0x9b, 0xae, 0x14, 0x5c, 0x99, 0xc1, 0xdc, 0xb6, 0xc7,
0xa0, 0xbd, 0x7a, 0x83, 0xed, 0x18, 0x0b, 0xf9, 0xea, 0xa0, 0x29, 0x1f, 0x0e, 0x82,
0xd8, 0x2f, 0x1d, 0x59, 0xb9, 0xda, 0x97, 0x41, 0xf2, 0x7b, 0xab, 0xa2, 0xdb, 0x38,
0xe9, 0xcd, 0xfe, 0x27, 0xb3, 0xbf, 0x13, 0x0a, 0xeb, 0xde, 0xa7, 0x7e, 0x55, 0x1a,
0x6c, 0xff, 0x2d, 0x64, 0xfb, 0xfc, 0x56, 0x52, 0xb5, 0xc8, 0x28, 0x07, 0x17, 0x6c,
0xe7, 0x57, 0xe5, 0xf5, 0xaa, 0xd5, 0x84, 0x18, 0x80, 0x21, 0xa1, 0xd9, 0xdd, 0x03,
0x82, 0xf1, 0xcf, 0x1b, 0xe6, 0x17, 0x97, 0xee, 0x2b, 0xdd, 0x27, 0x80, 0xea, 0x42,
0xde, 0xc8, 0x57, 0x8a,
0x00, 0x00, 0x0a, 0x33, 0x32, 0x35, 0x39, 0x33, 0x36, 0x35, 0x39, 0x35, 0x34, 0x13, 0x73, 0x69,
0x67, 0x2d, 0x77, 0x69, 0x6e, 0x2d, 0x73, 0x74, 0x37, 0x62, 0x6f, 0x30, 0x30, 0x33,
0x73, 0x70, 0x6f, 0x08, 0x68, 0x6f, 0x6d, 0x65, 0x74, 0x65, 0x73, 0x74, 0x03, 0x6c,
0x61, 0x6e, 0x00, 0x00, 0xfa, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x08, 0x67, 0x73, 0x73, 0x2d, 0x74, 0x73, 0x69, 0x67,
0x00, 0x00, 0x00, 0x50, 0xf8, 0xcf, 0xbb,
0x8c, 0xa0, 0x00, 0x1c, 0x04, 0x04, 0x05, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x73, 0x28,
0x5d, 0x0a, 0x2d, 0xf4, 0xa3, 0x34, 0x2f, 0xcf, 0x01, 0x6f, 0x3c, 0x9f, 0x76, 0x82,
0x02, 0x34, 0x00, 0x00, 0x00, 0x00, ],
Ok((
0,
Some(
Message {
header: Header {
transaction_id: 0x0234,
flags: 0b1000_0000_0000_0000,
query_response: QueryResponse::Response,
opcode: OpCode::QUERY,
authoritative: false,
truncated: false,
recursion_desired: false,
recursion_available: false,
zflag: false,
authenticated_data: false,
check_disabled: false,
rcode: ResponseCode::NOERROR,
qdcount: 1,
ancount: 1,
nscount: 0,
arcount: 1
},
queries: vec![
Question {
name: "3259365954.sig-win-st7bo003spo.hometest.lan"
.as_bytes()
.to_vec(),
record_type: RecordType::TKEY,
record_type_raw: 249,
record_class: RecordClass::ANY,
record_class_raw: 255,
}
],
answers: vec![
Answer {
name: "3259365954.sig-win-st7bo003spo.hometest.lan"
.as_bytes()
.to_vec(),
rtype: RecordType::TKEY,
rtype_raw: 249,
rclass: RecordClass::ANY,
rclass_raw: 255,
ttl: 0,
data: RDataType::TKEY(RDataTKEY {
algorithm: "gss-tsig".as_bytes().to_vec(),
inception: 1358483387,
expiration: 1358569787,
mode: TkeyMode::GssApiNegotiation,
error: TSigResponseCode::NOERROR,
key_data: vec![
0xa1, 0x81, 0xb7, 0x30, 0x81, 0xb4, 0xa0, 0x03, 0x0a, 0x01, 0x00, 0xa1,
0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02,
0xa2, 0x81, 0x9f, 0x04, 0x81, 0x9c, 0x60, 0x81, 0x99, 0x06, 0x09, 0x2a,
0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, 0x02, 0x00, 0x6f, 0x81,
0x89, 0x30, 0x81, 0x86, 0xa0, 0x03, 0x02, 0x01, 0x05, 0xa1, 0x03, 0x02,
0x01, 0x0f, 0xa2, 0x7a, 0x30, 0x78, 0xa0, 0x03, 0x02, 0x01, 0x12, 0xa2,
0x71, 0x04, 0x6f, 0x32, 0x94, 0x40, 0xf8, 0xae, 0xaa, 0xbd, 0xa2, 0x9e,
0x7e, 0x78, 0x1d, 0x0f, 0xf0, 0x9b, 0xae, 0x14, 0x5c, 0x99, 0xc1, 0xdc,
0xb6, 0xc7, 0xa0, 0xbd, 0x7a, 0x83, 0xed, 0x18, 0x0b, 0xf9, 0xea, 0xa0,
0x29, 0x1f, 0x0e, 0x82, 0xd8, 0x2f, 0x1d, 0x59, 0xb9, 0xda, 0x97, 0x41,
0xf2, 0x7b, 0xab, 0xa2, 0xdb, 0x38, 0xe9, 0xcd, 0xfe, 0x27, 0xb3, 0xbf,
0x13, 0x0a, 0xeb, 0xde, 0xa7, 0x7e, 0x55, 0x1a, 0x6c, 0xff, 0x2d, 0x64,
0xfb, 0xfc, 0x56, 0x52, 0xb5, 0xc8, 0x28, 0x07, 0x17, 0x6c, 0xe7, 0x57,
0xe5, 0xf5, 0xaa, 0xd5, 0x84, 0x18, 0x80, 0x21, 0xa1, 0xd9, 0xdd, 0x03,
0x82, 0xf1, 0xcf, 0x1b, 0xe6, 0x17, 0x97, 0xee, 0x2b, 0xdd, 0x27, 0x80,
0xea, 0x42, 0xde, 0xc8, 0x57, 0x8a,
],
other_data: vec![]
})
}
],
nameservers: vec![],
additional: vec![
Answer {
name: "3259365954.sig-win-st7bo003spo.hometest.lan"
.as_bytes()
.to_vec(),
rtype: RecordType::TSIG,
rtype_raw: 250,
rclass: RecordClass::ANY,
rclass_raw: 255,
ttl: 0,
data: RDataType::TSIG(RDataTSIG {
algorithm_name: "gss-tsig".as_bytes().to_vec(),
time_signed: 1358483387,
fudge: 36000,
mac: vec![
0x04, 0x04, 0x05, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
0x73, 0x28, 0x5d, 0x0a, 0x2d, 0xf4, 0xa3, 0x34, 0x2f, 0xcf, 0x01, 0x6f,
0x3c, 0x9f, 0x76, 0x82
],
original_id: 564,
error: TSigResponseCode::NOERROR,
other_data: vec![]
})
}
],
error_flags: ErrorFlags::none()
}
)))
),
case::parse_caa_response(
&[
0x35, 0x5e, 0x81,
0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00,
0x01, 0x01, 0x00, 0x01, 0xc0, 0x0c, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x54, 0x49, 0x00, 0x13, 0x00, 0x05, 0x69, 0x73, 0x73, 0x75, 0x65, 0x73, 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63, 0x2e, 0x63, 0x6f,
0x6d,
],
Ok((
0,
Some(
Message {
header: Header {
transaction_id: 0x355e,
flags: 0b1000_0001_1000_0000,
query_response: QueryResponse::Response,
opcode: OpCode::QUERY,
authoritative: false,
truncated: false,
recursion_desired: true,
recursion_available: true,
zflag: false,
authenticated_data: false,
check_disabled: false,
rcode: ResponseCode::NOERROR,
qdcount: 1,
ancount: 1,
nscount: 0,
arcount: 0
},
queries: vec![Question {
name: "google.com".as_bytes().to_vec(),
record_type: RecordType::CAA,
record_type_raw: 257,
record_class: RecordClass::IN,
record_class_raw: 1,
}],
answers: vec![Answer {
name: "google.com".as_bytes().to_vec(),
rtype: RecordType::CAA,
rtype_raw: 257,
rclass: RecordClass::IN,
rclass_raw: 1,
ttl: 21577,
data: RDataType::CAA(RDataCAA {
flags: 0,
tag: "issue".as_bytes().to_vec(),
value: "symantec.com".as_bytes().to_vec()
})
}],
nameservers: vec![],
additional: vec![],
error_flags: ErrorFlags::none()
}
)))
),
)]
fn dns(input: &[u8], expected: Result<(usize, Option<Message>)>) {
let dns = Dns {};
assert_eq!(
dns.parse(input, Direction::Unknown)
.map(|(rem, msg)| (rem.len(), msg)),
expected
);
}
}