all write_to functions implemented...
This commit is contained in:
parent
9ad645564d
commit
382701ea1e
@ -101,28 +101,22 @@ mod tests {
|
||||
use super::*;
|
||||
use super::super::util::tests::{test_parse_data_set, test_write_data_set_to};
|
||||
|
||||
#[test]
|
||||
fn parse() {
|
||||
let data: Vec<(Vec<u8>, Name)> = vec![
|
||||
(vec![0], Name{ labels: vec![] }), // base case, only the root
|
||||
(vec![1,b'a',0], Name{ labels: vec!["a".to_string()] }), // a single 'a' label
|
||||
(vec![1,b'a',2,b'b',b'c',0], Name{ labels: vec!["a".to_string(), "bc".to_string()] }), // two labels, 'a.bc'
|
||||
(vec![1,b'a',3,0xE2,0x99,0xA5,0], Name{ labels: vec!["a".to_string(), "♥".to_string()] }), // two labels utf8, 'a.♥'
|
||||
(vec![1,b'A',0], Name { labels: vec!["a".to_string()] }), // a single 'a' label, lowercased
|
||||
];
|
||||
|
||||
test_parse_data_set(data, |b| Name::parse(b));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn write_to() {
|
||||
let data: Vec<(Name, Vec<u8>)> = vec![
|
||||
fn get_data() -> Vec<(Name, Vec<u8>)> {
|
||||
vec![
|
||||
(Name { labels: vec![] }, vec![0]), // base case, only the root
|
||||
(Name { labels: vec!["a".to_string()] }, vec![1,b'a',0]), // a single 'a' label
|
||||
(Name { labels: vec!["a".to_string(), "bc".to_string()] }, vec![1,b'a',2,b'b',b'c',0]), // two labels, 'a.bc'
|
||||
(Name { labels: vec!["a".to_string(), "♥".to_string()] }, vec![1,b'a',3,0xE2,0x99,0xA5,0]), // two labels utf8, 'a.♥'
|
||||
];
|
||||
]
|
||||
}
|
||||
|
||||
test_write_data_set_to(data, |b, n| n.write_to(b));
|
||||
#[test]
|
||||
fn parse() {
|
||||
test_parse_data_set(get_data(), |b| Name::parse(b));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn write_to() {
|
||||
test_write_data_set_to(get_data(), |b, n| n.write_to(b));
|
||||
}
|
||||
}
|
||||
|
@ -28,29 +28,47 @@ pub fn parse(data: &mut Vec<u8>) -> RData {
|
||||
RData::A{ address: Ipv4Addr::new(data.pop().unwrap(), data.pop().unwrap(), data.pop().unwrap(), data.pop().unwrap()) }
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
use std::net::Ipv4Addr;
|
||||
pub fn write_to(a: &RData, buf: &mut Vec<u8>) {
|
||||
if let RData::A { address } = *a {
|
||||
let segments = address.octets();
|
||||
|
||||
let data: Vec<(Vec<u8>, Ipv4Addr)> = vec![
|
||||
(vec![0,0,0,0], Ipv4Addr::from_str("0.0.0.0").unwrap()), // base case
|
||||
(vec![1,0,0,0], Ipv4Addr::from_str("1.0.0.0").unwrap()),
|
||||
(vec![0,1,0,0], Ipv4Addr::from_str("0.1.0.0").unwrap()),
|
||||
(vec![0,0,1,0], Ipv4Addr::from_str("0.0.1.0").unwrap()),
|
||||
(vec![0,0,0,1], Ipv4Addr::from_str("0.0.0.1").unwrap()),
|
||||
(vec![127,0,0,1], Ipv4Addr::from_str("127.0.0.1").unwrap()),
|
||||
(vec![192,168,64,32], Ipv4Addr::from_str("192.168.64.32").unwrap()),
|
||||
];
|
||||
|
||||
let mut test_num = 0;
|
||||
for (mut binary, expect) in data {
|
||||
test_num += 1;
|
||||
println!("test: {}", test_num);
|
||||
binary.reverse();
|
||||
if let RData::A{address} = parse(&mut binary) {
|
||||
assert_eq!(address, expect);
|
||||
} else {
|
||||
panic!();
|
||||
}
|
||||
buf.push(segments[0]);
|
||||
buf.push(segments[1]);
|
||||
buf.push(segments[2]);
|
||||
buf.push(segments[3]);
|
||||
} else {
|
||||
panic!("wrong type here {:?}", a)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::net::Ipv4Addr;
|
||||
use std::str::FromStr;
|
||||
|
||||
use super::*;
|
||||
use super::super::super::record_data::RData;
|
||||
use super::super::super::util::tests::{test_parse_data_set, test_write_data_set_to};
|
||||
|
||||
fn get_data() -> Vec<(RData, Vec<u8>)> {
|
||||
vec![
|
||||
(RData::A{ address: Ipv4Addr::from_str("0.0.0.0").unwrap()}, vec![0,0,0,0]), // base case
|
||||
(RData::A{ address: Ipv4Addr::from_str("1.0.0.0").unwrap()}, vec![1,0,0,0]),
|
||||
(RData::A{ address: Ipv4Addr::from_str("0.1.0.0").unwrap()}, vec![0,1,0,0]),
|
||||
(RData::A{ address: Ipv4Addr::from_str("0.0.1.0").unwrap()}, vec![0,0,1,0]),
|
||||
(RData::A{ address: Ipv4Addr::from_str("0.0.0.1").unwrap()}, vec![0,0,0,1]),
|
||||
(RData::A{ address: Ipv4Addr::from_str("127.0.0.1").unwrap()}, vec![127,0,0,1]),
|
||||
(RData::A{ address: Ipv4Addr::from_str("192.168.64.32").unwrap()}, vec![192,168,64,32]),
|
||||
]
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
test_parse_data_set(get_data(), |b| parse(b));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_write_to() {
|
||||
test_write_data_set_to(get_data(), |b,d| write_to(&d,b));
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
use std::net::Ipv6Addr;
|
||||
use std::str::FromStr;
|
||||
|
||||
use super::super::record_data::RData;
|
||||
use super::super::util;
|
||||
@ -37,38 +36,43 @@ pub fn write_to(aaaa: &RData, buf: &mut Vec<u8>) {
|
||||
util::write_u16_to(buf, segments[6]);
|
||||
util::write_u16_to(buf, segments[7]);
|
||||
} else {
|
||||
assert!(false)
|
||||
panic!("wrong type here {:?}", aaaa)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::net::Ipv6Addr;
|
||||
use std::str::FromStr;
|
||||
|
||||
let data: Vec<(Vec<u8>, Ipv6Addr)> = vec![
|
||||
(vec![0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0], Ipv6Addr::from_str("::").unwrap()), // base case
|
||||
(vec![0,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0], Ipv6Addr::from_str("1::").unwrap()),
|
||||
(vec![0,0,0,1,0,0,0,0, 0,0,0,0,0,0,0,0], Ipv6Addr::from_str("0:1::").unwrap()),
|
||||
(vec![0,0,0,0,0,1,0,0, 0,0,0,0,0,0,0,0], Ipv6Addr::from_str("0:0:1::").unwrap()),
|
||||
(vec![0,0,0,0,0,0,0,1, 0,0,0,0,0,0,0,0], Ipv6Addr::from_str("0:0:0:1::").unwrap()),
|
||||
(vec![0,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0], Ipv6Addr::from_str("::1:0:0:0").unwrap()),
|
||||
(vec![0,0,0,0,0,0,0,0, 0,0,0,1,0,0,0,0], Ipv6Addr::from_str("::1:0:0").unwrap()),
|
||||
(vec![0,0,0,0,0,0,0,0, 0,0,0,0,0,1,0,0], Ipv6Addr::from_str("::1:0").unwrap()),
|
||||
(vec![0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,1], Ipv6Addr::from_str("::1").unwrap()),
|
||||
(vec![0,0,0,0,0,0,0,0, 0,0,0,0,127,0,0,1], Ipv6Addr::from_str("::127.0.0.1").unwrap()),
|
||||
(vec![255,0,0,0,0,0,0,0, 0,0,0,0,192,168,64,32], Ipv6Addr::from_str("FF00::192.168.64.32").unwrap()),
|
||||
];
|
||||
use super::*;
|
||||
use super::super::super::record_data::RData;
|
||||
use super::super::super::util::tests::{test_parse_data_set, test_write_data_set_to};
|
||||
|
||||
let mut test_num = 0;
|
||||
for (mut binary, expect) in data {
|
||||
test_num += 1;
|
||||
println!("test: {}", test_num);
|
||||
binary.reverse();
|
||||
if let RData::AAAA{address} = parse(&mut binary) {
|
||||
assert_eq!(address, expect);
|
||||
} else {
|
||||
panic!();
|
||||
}
|
||||
fn get_data() -> Vec<(RData, Vec<u8>)> {
|
||||
vec![
|
||||
(RData::AAAA{ address: Ipv6Addr::from_str("::").unwrap()}, vec![0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0]), // base case
|
||||
(RData::AAAA{ address: Ipv6Addr::from_str("1::").unwrap()}, vec![0,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0]),
|
||||
(RData::AAAA{ address: Ipv6Addr::from_str("0:1::").unwrap()}, vec![0,0,0,1,0,0,0,0, 0,0,0,0,0,0,0,0]),
|
||||
(RData::AAAA{ address: Ipv6Addr::from_str("0:0:1::").unwrap()}, vec![0,0,0,0,0,1,0,0, 0,0,0,0,0,0,0,0]),
|
||||
(RData::AAAA{ address: Ipv6Addr::from_str("0:0:0:1::").unwrap()}, vec![0,0,0,0,0,0,0,1, 0,0,0,0,0,0,0,0]),
|
||||
(RData::AAAA{ address: Ipv6Addr::from_str("::1:0:0:0").unwrap()}, vec![0,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0]),
|
||||
(RData::AAAA{ address: Ipv6Addr::from_str("::1:0:0").unwrap()}, vec![0,0,0,0,0,0,0,0, 0,0,0,1,0,0,0,0]),
|
||||
(RData::AAAA{ address: Ipv6Addr::from_str("::1:0").unwrap()}, vec![0,0,0,0,0,0,0,0, 0,0,0,0,0,1,0,0]),
|
||||
(RData::AAAA{ address: Ipv6Addr::from_str("::1").unwrap()}, vec![0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,1]),
|
||||
(RData::AAAA{ address: Ipv6Addr::from_str("::127.0.0.1").unwrap()}, vec![0,0,0,0,0,0,0,0, 0,0,0,0,127,0,0,1]),
|
||||
(RData::AAAA{ address: Ipv6Addr::from_str("FF00::192.168.64.32").unwrap()}, vec![255,0,0,0,0,0,0,0, 0,0,0,0,192,168,64,32]),
|
||||
]
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
test_parse_data_set(get_data(), |b| parse(b));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_write_to() {
|
||||
test_write_data_set_to(get_data(), |b,d| write_to(&d,b));
|
||||
}
|
||||
}
|
||||
|
@ -22,17 +22,12 @@ pub fn parse(data: &mut Vec<u8>) -> RData {
|
||||
RData::CNAME{ cname: Name::parse(data) }
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let mut data: Vec<u8> = vec![3,b'w',b'w',b'w',7,b'e',b'x',b'a',b'm',b'p',b'l',b'e',3,b'c',b'o',b'm',0];
|
||||
data.reverse();
|
||||
if let RData::CNAME { cname } = parse(&mut data) {
|
||||
let expect = vec!["www","example","com"];
|
||||
assert_eq!(cname[0], expect[0]);
|
||||
assert_eq!(cname[1], expect[1]);
|
||||
assert_eq!(cname[2], expect[2]);
|
||||
pub fn write_to(cname_data: &RData, buf: &mut Vec<u8>) {
|
||||
if let RData::CNAME { ref cname } = *cname_data {
|
||||
cname.write_to(buf);
|
||||
} else {
|
||||
panic!();
|
||||
panic!("wrong type: {:?}", cname_data)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// #[test] is performed at the record_data module, the inner name in domain::Name
|
||||
|
@ -29,15 +29,13 @@ pub fn parse(data: &mut Vec<u8>) -> RData {
|
||||
RData::MX { preference: util::parse_u16(data), exchange: Name::parse(data) }
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let mut data: Vec<u8> = vec![1,0,1,b'n',0];
|
||||
data.reverse();
|
||||
|
||||
if let RData::MX{ preference, exchange } = parse(&mut data) {
|
||||
assert_eq!(preference, 256);
|
||||
assert_eq!(exchange[0], "n".to_string());
|
||||
pub fn write_to(mx: &RData, buf: &mut Vec<u8>) {
|
||||
if let RData::MX { ref preference, ref exchange } = *mx {
|
||||
util::write_u16_to(buf, *preference);
|
||||
exchange.write_to(buf);
|
||||
} else {
|
||||
panic!();
|
||||
}
|
||||
}
|
||||
|
||||
// #[test] is performed at the record_data module, the inner name in domain::Name
|
||||
|
@ -29,16 +29,10 @@ pub fn parse(data: &mut Vec<u8>) -> RData {
|
||||
RData::NS{ nsdname: Name::parse(data) }
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let mut data: Vec<u8> = vec![3,b'w',b'w',b'w',7,b'e',b'x',b'a',b'm',b'p',b'l',b'e',3,b'c',b'o',b'm',0];
|
||||
data.reverse();
|
||||
if let RData::NS { nsdname } = parse(&mut data) {
|
||||
let expect = vec!["www","example","com"];
|
||||
assert_eq!(nsdname[0], expect[0]);
|
||||
assert_eq!(nsdname[1], expect[1]);
|
||||
assert_eq!(nsdname[2], expect[2]);
|
||||
pub fn write_to(ns: &RData, buf: &mut Vec<u8>) {
|
||||
if let RData::NS{ ref nsdname } = *ns {
|
||||
nsdname.write_to(buf);
|
||||
} else {
|
||||
panic!();
|
||||
panic!()
|
||||
}
|
||||
}
|
||||
|
@ -23,16 +23,10 @@ pub fn parse(data: &mut Vec<u8>) -> RData {
|
||||
RData::PTR{ ptrdname: Name::parse(data) }
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let mut data: Vec<u8> = vec![3,b'w',b'w',b'w',7,b'e',b'x',b'a',b'm',b'p',b'l',b'e',3,b'c',b'o',b'm',0];
|
||||
data.reverse();
|
||||
if let RData::PTR { ptrdname } = parse(&mut data) {
|
||||
let expect = vec!["www","example","com"];
|
||||
assert_eq!(ptrdname[0], expect[0]);
|
||||
assert_eq!(ptrdname[1], expect[1]);
|
||||
assert_eq!(ptrdname[2], expect[2]);
|
||||
pub fn write_to(ptr: &RData, buf: &mut Vec<u8>) {
|
||||
if let RData::PTR { ref ptrdname } = *ptr {
|
||||
ptrdname.write_to(buf);
|
||||
} else {
|
||||
panic!();
|
||||
panic!()
|
||||
}
|
||||
}
|
||||
|
@ -80,28 +80,16 @@ pub fn parse(data: &mut Vec<u8>) -> RData {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let mut data: Vec<u8> = vec![3,b'w',b'w',b'w',7,b'e',b'x',b'a',b'm',b'p',b'l',b'e',3,b'c',b'o',b'm',0,
|
||||
3,b'x',b'x',b'x',7,b'e',b'x',b'a',b'm',b'p',b'l',b'e',3,b'c',b'o',b'm',0,
|
||||
0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF];
|
||||
data.reverse();
|
||||
if let RData::SOA { mname, rname, serial, refresh, retry, expire, minimum } = parse(&mut data) {
|
||||
let expect1 = vec!["www","example","com"];
|
||||
let expect2 = vec!["xxx","example","com"];
|
||||
|
||||
assert_eq!(mname[0], expect1[0]);
|
||||
assert_eq!(rname[0], expect2[0]);
|
||||
assert_eq!(serial, u32::max_value());
|
||||
assert_eq!(refresh, -1 as i32);
|
||||
assert_eq!(retry, -1 as i32);
|
||||
assert_eq!(expire, -1 as i32);
|
||||
assert_eq!(minimum, u32::max_value());
|
||||
pub fn write_to(soa: &RData, buf: &mut Vec<u8>) {
|
||||
if let RData::SOA { ref mname, ref rname, ref serial, ref refresh, ref retry, ref expire, ref minimum} = *soa {
|
||||
mname.write_to(buf);
|
||||
rname.write_to(buf);
|
||||
util::write_u32_to(buf, *serial);
|
||||
util::write_i32_to(buf, *refresh);
|
||||
util::write_i32_to(buf, *retry);
|
||||
util::write_i32_to(buf, *expire);
|
||||
util::write_u32_to(buf, *minimum);
|
||||
} else {
|
||||
panic!();
|
||||
panic!()
|
||||
}
|
||||
}
|
||||
|
@ -27,20 +27,12 @@ pub fn parse(data: &mut Vec<u8>, count: u16) -> RData {
|
||||
RData::TXT{ txt_data: strings }
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let mut data = vec![6,b'a',b'b',b'c',b'd',b'e',b'f',
|
||||
3,b'g',b'h',b'i',
|
||||
0,
|
||||
1,b'j'];
|
||||
data.reverse();
|
||||
|
||||
if let RData::TXT{ txt_data } = parse(&mut data, 14) {
|
||||
assert_eq!(txt_data[0], "abcdef".to_string());
|
||||
assert_eq!(txt_data[1], "ghi".to_string());
|
||||
assert_eq!(txt_data[2], "".to_string());
|
||||
assert_eq!(txt_data[3], "j".to_string());
|
||||
pub fn write_to(txt: &RData, buf: &mut Vec<u8>) {
|
||||
if let RData::TXT { ref txt_data } = *txt {
|
||||
for s in txt_data {
|
||||
util::write_character_data_to(buf, s);
|
||||
}
|
||||
} else {
|
||||
panic!();
|
||||
panic!()
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
use std::net::{Ipv4Addr, Ipv6Addr};
|
||||
use std::convert::From;
|
||||
|
||||
use super::domain::Name;
|
||||
use super::record_type::RecordType;
|
||||
@ -18,6 +19,7 @@ use super::rdata;
|
||||
// is treated as binary information, and can be up to 256 characters in
|
||||
// length (including the length octet).
|
||||
//
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum RData {
|
||||
//-- RFC 1035 -- Domain Implementation and Specification November 1987
|
||||
|
||||
@ -309,8 +311,8 @@ pub enum RData {
|
||||
}
|
||||
|
||||
impl RData {
|
||||
pub fn parse(data: &mut Vec<u8>, rtype: &RecordType, rd_length: u16) -> Self {
|
||||
match *rtype {
|
||||
pub fn parse(data: &mut Vec<u8>, rtype: RecordType, rd_length: u16) -> Self {
|
||||
match rtype {
|
||||
RecordType::CNAME => rdata::cname::parse(data),
|
||||
RecordType::MX => rdata::mx::parse(data),
|
||||
RecordType::NS => rdata::ns::parse(data),
|
||||
@ -324,17 +326,85 @@ impl RData {
|
||||
}
|
||||
|
||||
pub fn write_to(&self, buf: &mut Vec<u8>) {
|
||||
match self {
|
||||
// CNAME => rdata::cname::write_to(self, buf),
|
||||
// MX => rdata::mx::write_to(self, buf),
|
||||
// NULL => rdata::null::write_to(self, buf),
|
||||
// NS => rdata::null::write_to(self, buf),
|
||||
// PTR => rdata::ptr::write_to(self, buf),
|
||||
// SOA => rdata::soa::write_to(self, buf),
|
||||
// TXT => rdata::txt::write_to(self, buf),
|
||||
// A => rdata::a::write_to(self, buf),
|
||||
AAAA => rdata::aaaa::write_to(self, buf),
|
||||
// _ => unimplemented!()
|
||||
match *self {
|
||||
RData::CNAME{ref cname} => rdata::cname::write_to(self, buf),
|
||||
RData::MX{ref preference,ref exchange} => rdata::mx::write_to(self, buf),
|
||||
// RData::NULL => rdata::null::write_to(self, buf),
|
||||
RData::NS{ref nsdname} => rdata::ns::write_to(self, buf),
|
||||
RData::PTR{ref ptrdname} => rdata::ptr::write_to(self, buf),
|
||||
RData::SOA{ref mname, ref rname, ref serial, ref refresh, ref retry, ref expire, ref minimum} => rdata::soa::write_to(self, buf),
|
||||
RData::TXT{ ref txt_data } => rdata::txt::write_to(self, buf),
|
||||
RData::A{ ref address } => rdata::a::write_to(self, buf),
|
||||
RData::AAAA{ ref address } => rdata::aaaa::write_to(self, buf),
|
||||
_ => unimplemented!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a RData> for RecordType {
|
||||
fn from(rdata: &'a RData) -> Self {
|
||||
match *rdata {
|
||||
RData::CNAME{ref cname} => RecordType::CNAME,
|
||||
RData::MX{ref preference,ref exchange} => RecordType::MX,
|
||||
RData::NS{ref nsdname} => RecordType::NS,
|
||||
RData::PTR{ref ptrdname} => RecordType::PTR,
|
||||
RData::SOA{ref mname, ref rname, ref serial, ref refresh, ref retry, ref expire, ref minimum} => RecordType::SOA,
|
||||
RData::TXT{ref txt_data } => RecordType::TXT,
|
||||
RData::A{ref address } => RecordType::A,
|
||||
RData::AAAA{ref address } => RecordType::AAAA,
|
||||
_ => unimplemented!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::fmt::Debug;
|
||||
use std::net::Ipv6Addr;
|
||||
use std::net::Ipv4Addr;
|
||||
use std::str::FromStr;
|
||||
|
||||
use super::*;
|
||||
use super::super::util::tests::test_write_data_set_to;
|
||||
use super::super::domain::Name;
|
||||
|
||||
fn get_data() -> Vec<(RData, Vec<u8>)> {
|
||||
vec![
|
||||
(RData::CNAME{cname: Name::with_labels(vec!["www".to_string(),"example".to_string(),"com".to_string()])}, vec![3,b'w',b'w',b'w',7,b'e',b'x',b'a',b'm',b'p',b'l',b'e',3,b'c',b'o',b'm',0]),
|
||||
(RData::MX{preference: 256, exchange: Name::with_labels(vec!["n".to_string()])}, vec![1,0,1,b'n',0]),
|
||||
(RData::NS{nsdname: Name::with_labels(vec!["www".to_string(),"example".to_string(),"com".to_string()])}, vec![3,b'w',b'w',b'w',7,b'e',b'x',b'a',b'm',b'p',b'l',b'e',3,b'c',b'o',b'm',0]),
|
||||
(RData::PTR{ptrdname: Name::with_labels(vec!["www".to_string(),"example".to_string(),"com".to_string()])}, vec![3,b'w',b'w',b'w',7,b'e',b'x',b'a',b'm',b'p',b'l',b'e',3,b'c',b'o',b'm',0]),
|
||||
(RData::SOA{mname: Name::with_labels(vec!["www".to_string(),"example".to_string(),"com".to_string()]),
|
||||
rname: Name::with_labels(vec!["xxx".to_string(),"example".to_string(),"com".to_string()]),
|
||||
serial: u32::max_value(), refresh: -1 as i32, retry: -1 as i32, expire: -1 as i32, minimum: u32::max_value()},
|
||||
vec![3,b'w',b'w',b'w',7,b'e',b'x',b'a',b'm',b'p',b'l',b'e',3,b'c',b'o',b'm',0,
|
||||
3,b'x',b'x',b'x',7,b'e',b'x',b'a',b'm',b'p',b'l',b'e',3,b'c',b'o',b'm',0,
|
||||
0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF]),
|
||||
(RData::TXT{txt_data: vec!["abcdef".to_string(), "ghi".to_string(), "".to_string(), "j".to_string()]},
|
||||
vec![6,b'a',b'b',b'c',b'd',b'e',b'f', 3,b'g',b'h',b'i', 0, 1,b'j']),
|
||||
(RData::A{ address: Ipv4Addr::from_str("0.0.0.0").unwrap()}, vec![0,0,0,0]),
|
||||
(RData::AAAA{ address: Ipv6Addr::from_str("::").unwrap()}, vec![0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0])
|
||||
]
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let mut test_pass = 0;
|
||||
for (expect, mut binary) in get_data() {
|
||||
test_pass += 1;
|
||||
println!("test {}: {:?}", test_pass, binary);
|
||||
binary.reverse();
|
||||
let length = binary.len() as u16; // pre exclusive borrow
|
||||
assert_eq!(RData::parse(&mut binary, super::super::record_type::RecordType::from(&expect), length), expect);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_write_to() {
|
||||
test_write_data_set_to(get_data(), |b,d| RData::write_to(&d,b));
|
||||
}
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ impl Record {
|
||||
// RDATA a variable length string of octets that describes the
|
||||
// resource. The format of this information varies
|
||||
// according to the TYPE and CLASS of the resource record.
|
||||
let rdata = RData::parse(data, &record_type, rd_length);
|
||||
let rdata = RData::parse(data, record_type, rd_length);
|
||||
|
||||
Ok(Record{ name_labels: name_labels, rr_type: record_type, dns_class: class, ttl: ttl, rdata: rdata })
|
||||
}
|
||||
|
122
src/rr/util.rs
122
src/rr/util.rs
@ -133,81 +133,46 @@ pub fn write_u32_to(buf: &mut Vec<u8>, data: u32) {
|
||||
pub mod tests {
|
||||
use std::fmt::Debug;
|
||||
|
||||
fn get_character_data() -> Vec<(String, Vec<u8>)> {
|
||||
vec![
|
||||
("".to_string(), vec![0]), // base case, only the root
|
||||
("a".to_string(), vec![1,b'a']), // a single 'a' label
|
||||
("bc".to_string(), vec![2,b'b',b'c']), // two labels, 'a.bc'
|
||||
("♥".to_string(), vec![3,0xE2,0x99,0xA5]), // two labels utf8, 'a.♥'
|
||||
]
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_character_data() {
|
||||
let data: Vec<(Vec<u8>, String)> = vec![
|
||||
(vec![0], "".to_string()), // base case, only the root
|
||||
(vec![1,b'a'], "a".to_string()), // a single 'a' label
|
||||
(vec![2,b'b',b'c'], "bc".to_string()), // two labels, 'a.bc'
|
||||
(vec![3,0xE2,0x99,0xA5], "♥".to_string()), // two labels utf8, 'a.♥'
|
||||
(vec![1,b'A'], "a".to_string()), // a single 'a' label, lowercased
|
||||
];
|
||||
|
||||
test_parse_data_set(data, |b| super::parse_character_data(b));
|
||||
test_parse_data_set(get_character_data(), |b| super::parse_character_data(b));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn write_character_data() {
|
||||
let data: Vec<(&'static str, Vec<u8>)> = vec![
|
||||
("", vec![0]), // base case, only the root
|
||||
("a", vec![1,b'a']), // a single 'a' label
|
||||
("bc", vec![2,b'b',b'c']), // two labels, 'a.bc'
|
||||
("♥", vec![3,0xE2,0x99,0xA5]), // two labels utf8, 'a.♥'
|
||||
];
|
||||
|
||||
let mut test_num = 0;
|
||||
for (data, expect) in data {
|
||||
test_num += 1;
|
||||
println!("test {}: {:?}", test_num, data);
|
||||
let mut buf: Vec<u8> = Vec::with_capacity(expect.len());
|
||||
super::write_character_data_to(&mut buf, data);
|
||||
assert_eq!(buf, expect);
|
||||
}
|
||||
test_write_data_set_to(get_character_data(), |b, d| super::write_character_data_to(b,&d));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_u16() {
|
||||
let data: Vec<(Vec<u8>, u16)> = vec![
|
||||
(vec![0x00,0x00], 0),
|
||||
(vec![0x00,0x01], 1),
|
||||
(vec![0x01,0x00], 256),
|
||||
(vec![0xFF,0xFF], u16::max_value()),
|
||||
];
|
||||
|
||||
test_parse_data_set(data, |b| super::parse_u16(b));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn write_u16() {
|
||||
let data: Vec<(u16, Vec<u8>)> = vec![
|
||||
fn get_u16_data() -> Vec<(u16, Vec<u8>)> {
|
||||
vec![
|
||||
(0, vec![0x00,0x00]),
|
||||
(1, vec![0x00,0x01]),
|
||||
(256, vec![0x01,0x00]),
|
||||
(u16::max_value(), vec![0xFF,0xFF]),
|
||||
];
|
||||
|
||||
test_write_data_set_to(data, |b, d| super::write_u16_to(b,d));
|
||||
]
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_i32() {
|
||||
let data: Vec<(Vec<u8>, i32)> = vec![
|
||||
(vec![0x00,0x00,0x00,0x00], 0),
|
||||
(vec![0x00,0x00,0x00,0x01], 1),
|
||||
(vec![0x00,0x00,0x01,0x00], 256),
|
||||
(vec![0x00,0x01,0x00,0x00], 256*256),
|
||||
(vec![0x01,0x00,0x00,0x00], 256*256*256),
|
||||
(vec![0xFF,0xFF,0xFF,0xFF], -1),
|
||||
(vec![0x80,0x00,0x00,0x00], i32::min_value()),
|
||||
(vec![0x7F,0xFF,0xFF,0xFF], i32::max_value()),
|
||||
];
|
||||
|
||||
test_parse_data_set(data, |b| super::parse_i32(b));
|
||||
fn parse_u16() {
|
||||
test_parse_data_set(get_u16_data(), |b| super::parse_u16(b));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn write_i32() {
|
||||
let data: Vec<(i32, Vec<u8>)> = vec![
|
||||
fn write_u16() {
|
||||
test_write_data_set_to(get_u16_data(), |b, d| super::write_u16_to(b,d));
|
||||
}
|
||||
|
||||
fn get_i32_data() -> Vec<(i32, Vec<u8>)> {
|
||||
vec![
|
||||
(0, vec![0x00,0x00,0x00,0x00]),
|
||||
(1, vec![0x00,0x00,0x00,0x01]),
|
||||
(256, vec![0x00,0x00,0x01,0x00]),
|
||||
@ -216,30 +181,21 @@ pub mod tests {
|
||||
(-1, vec![0xFF,0xFF,0xFF,0xFF]),
|
||||
(i32::min_value(), vec![0x80,0x00,0x00,0x00]),
|
||||
(i32::max_value(), vec![0x7F,0xFF,0xFF,0xFF]),
|
||||
];
|
||||
|
||||
test_write_data_set_to(data, |b, d| super::write_i32_to(b,d));
|
||||
]
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_u32() {
|
||||
let data: Vec<(Vec<u8>, u32)> = vec![
|
||||
(vec![0x00,0x00,0x00,0x00], 0),
|
||||
(vec![0x00,0x00,0x00,0x01], 1),
|
||||
(vec![0x00,0x00,0x01,0x00], 256),
|
||||
(vec![0x00,0x01,0x00,0x00], 256*256),
|
||||
(vec![0x01,0x00,0x00,0x00], 256*256*256),
|
||||
(vec![0xFF,0xFF,0xFF,0xFF], u32::max_value()),
|
||||
(vec![0x80,0x00,0x00,0x00], 2147483648),
|
||||
(vec![0x7F,0xFF,0xFF,0xFF], i32::max_value() as u32),
|
||||
];
|
||||
|
||||
test_parse_data_set(data, |b| super::parse_u32(b));
|
||||
fn parse_i32() {
|
||||
test_parse_data_set(get_i32_data(), |b| super::parse_i32(b));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn write_u32() {
|
||||
let data: Vec<(u32, Vec<u8>)> = vec![
|
||||
fn write_i32() {
|
||||
test_write_data_set_to(get_i32_data(), |b, d| super::write_i32_to(b,d));
|
||||
}
|
||||
|
||||
fn get_u32_data() -> Vec<(u32, Vec<u8>)> {
|
||||
vec![
|
||||
(0, vec![0x00,0x00,0x00,0x00]),
|
||||
(1, vec![0x00,0x00,0x00,0x01]),
|
||||
(256, vec![0x00,0x00,0x01,0x00]),
|
||||
@ -248,16 +204,24 @@ pub mod tests {
|
||||
(u32::max_value(), vec![0xFF,0xFF,0xFF,0xFF]),
|
||||
(2147483648, vec![0x80,0x00,0x00,0x00]),
|
||||
(i32::max_value() as u32, vec![0x7F,0xFF,0xFF,0xFF]),
|
||||
];
|
||||
]
|
||||
}
|
||||
|
||||
test_write_data_set_to(data, |b, d| super::write_u32_to(b,d));
|
||||
#[test]
|
||||
fn parse_u32() {
|
||||
test_parse_data_set(get_u32_data(), |b| super::parse_u32(b));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn write_u32() {
|
||||
test_write_data_set_to(get_u32_data(), |b, d| super::write_u32_to(b,d));
|
||||
}
|
||||
|
||||
|
||||
pub fn test_parse_data_set<E, F>(data_set: Vec<(Vec<u8>, E)>, parse_func: F)
|
||||
pub fn test_parse_data_set<E, F>(data_set: Vec<(E, Vec<u8>)>, parse_func: F)
|
||||
where E: PartialEq<E> + Debug, F: Fn(&mut Vec<u8>) -> E {
|
||||
let mut test_pass = 0;
|
||||
for (mut binary, expect) in data_set {
|
||||
for (expect, mut binary) in data_set {
|
||||
test_pass += 1;
|
||||
println!("test {}: {:?}", test_pass, binary);
|
||||
binary.reverse();
|
||||
|
Loading…
Reference in New Issue
Block a user