From 2a7b8433f58db7cd6fdf332ae9bcbda52a9fc720 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20B=C3=BChler?= Date: Thu, 27 Aug 2020 12:40:51 +0200 Subject: [PATCH] fix APL and add (new) APL test from powerdns --- Cargo.lock | 6 +- lib/dnsbox-base/Cargo.toml | 2 +- .../src/records/tests/powerdns_tests.rs | 99 +++++++++++++++++++ lib/dnsbox-base/src/records/weird_structs.rs | 8 +- 4 files changed, 109 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0a25a16..4dd282b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -112,7 +112,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "cidr" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitstring 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -204,7 +204,7 @@ version = "0.1.0" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "cidr 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cidr 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "dnsbox-derive 0.1.0", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -950,7 +950,7 @@ dependencies = [ "checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" "checksum cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "39f75544d7bbaf57560d2168f28fd649ff9c76153874db88bdbdfd839b1a7e7d" "checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33" -"checksum cidr 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2da1cf0f275bb8dc1867a7f40cdb3b746951db73a183048e6e37fa89ed81bd01" +"checksum cidr 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c6316c62053228eddd526a5e6deb6344c80bf2bc1e9786e7f90b3083e73197c1" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" "checksum crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b18cd2e169ad86297e6bc0ad9aa679aee9daa4f19e8163860faf7c164e4f5a71" "checksum crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "04c9e3102cc2d69cd681412141b390abd55a362afc1540965dad0ad4d34280b4" diff --git a/lib/dnsbox-base/Cargo.toml b/lib/dnsbox-base/Cargo.toml index 711f8ab..38838bd 100644 --- a/lib/dnsbox-base/Cargo.toml +++ b/lib/dnsbox-base/Cargo.toml @@ -7,7 +7,7 @@ edition = "2018" [dependencies] byteorder = "1.1.0" bytes = "0.4" -cidr = "0.1.0" +cidr = "0.1.1" data-encoding = "2.1.0" dnsbox-derive = { path = "../dnsbox-derive" } failure = "0.1.5" diff --git a/lib/dnsbox-base/src/records/tests/powerdns_tests.rs b/lib/dnsbox-base/src/records/tests/powerdns_tests.rs index 66b6be1..edf48bd 100644 --- a/lib/dnsbox-base/src/records/tests/powerdns_tests.rs +++ b/lib/dnsbox-base/src/records/tests/powerdns_tests.rs @@ -500,6 +500,105 @@ fn test_CERT() { ); } +#[test] +fn test_APL() { + check(types::APL, + "1:10.0.0.0/32", + None, + b"\x00\x01\x20\x01\x0a", + ); + check(types::APL, + "1:10.1.1.1/32", + None, + b"\x00\x01\x20\x04\x0a\x01\x01\x01", + ); + check(types::APL, + "1:10.1.1.0/24", + None, + b"\x00\x01\x18\x03\x0a\x01\x01", + ); + check(types::APL, + "1:60.0.0.0/8", + None, + b"\x00\x01\x08\x01\x3c", + ); + check(types::APL, + "1:10.1.1.1/32", + None, + b"\x00\x01\x20\x04\x0a\x01\x01\x01", + ); + check(types::APL, + "!1:10.1.1.1/32", + None, + b"\x00\x01\x20\x84\x0a\x01\x01\x01", + ); + check(types::APL, + "1:255.255.255.255/32", + None, + b"\x00\x01\x20\x04\xff\xff\xff\xff", + ); + check(types::APL, + "2:100::/8", + None, + b"\x00\x02\x08\x01\x01", + ); + check(types::APL, + "2:20::/16", + None, + b"\x00\x02\x10\x02\x00\x20", + ); + check(types::APL, + "2:2000::/8", + None, + b"\x00\x02\x08\x01\x20", + ); + check(types::APL, + "2:fe00::/8", + None, + b"\x00\x02\x08\x01\xfe", + ); + check(types::APL, + "2:fe80::/16", + None, + b"\x00\x02\x10\x02\xfe\x80", + ); + check(types::APL, + "2:2001::1/128", + None, + b"\x00\x02\x80\x10\x20\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", + ); + check(types::APL, + "!2:2001::1/128", + None, + b"\x00\x02\x80\x90\x20\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", + ); + check(types::APL, + "2:fe80:1234:5678:9910:8bc:3359:b2e8:720e/128", + None, + b"\x00\x02\x80\x10\xfe\x80\x12\x34\x56\x78\x99\x10\x08\xbc\x33\x59\xb2\xe8\x72\x0e", + ); + check(types::APL, + "2:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128", + None, + b"\x00\x02\x80\x10\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff", + ); + check(types::APL, + "", + None, + b"", + ); + check(types::APL, + "1:10.0.0.0/32 1:10.1.1.1/32", + None, + b"\x00\x01\x20\x01\x0a\x00\x01\x20\x04\x0a\x01\x01\x01", + ); + check(types::APL, + "1:10.0.0.0/32 2:100::/8", + None, + b"\x00\x01\x20\x01\x0a\x00\x02\x08\x01\x01", + ); +} + // missing test_A6 // missing test_DNAME diff --git a/lib/dnsbox-base/src/records/weird_structs.rs b/lib/dnsbox-base/src/records/weird_structs.rs index fea32c3..779b83c 100644 --- a/lib/dnsbox-base/src/records/weird_structs.rs +++ b/lib/dnsbox-base/src/records/weird_structs.rs @@ -489,7 +489,7 @@ impl DnsPacketData for APL { packet.put_u16_be(if item.prefix.is_ipv4() { 1 } else { 2 }); packet.put_u8(item.prefix.network_length()); let negation_flag = if item.negation { 0x80 } else { 0x00 }; - let mut l = (item.prefix.network_length() + 7) / 4; + let mut l = (item.prefix.network_length() + 7) / 8; match &item.prefix { cidr::IpCidr::V4(p) => { let addr = p.first_address().octets(); @@ -527,6 +527,10 @@ impl DnsTextData for APL { None => failure::bail!("no colon in APL item: {:?}", item), }; let afi = afi.parse::()?; + if content.find('/').is_none() { + // prefix is mandatory, even if it is /32 for IPv4 or /128 for IPv6. + failure::bail!("no '/' in APL item: {:?}", item); + } let prefix = match afi { 1 => prefix.parse::()?.into(), 2 => prefix.parse::()?.into(), @@ -543,7 +547,7 @@ impl DnsTextData for APL { f.next_field()?; let family = if item.prefix.is_ipv4() { 1 } else { 2 }; let negation = if item.negation { "!" } else { "" }; - write!(f, "{}{}:{}", negation, family, item.prefix)?; + write!(f, "{}{}:{:#}", negation, family, item.prefix)?; } Ok(()) }