use
5.014002;
use
version;
our
$VERSION
= version->declare(
"v1.0.8"
);
sub
all {
my
(
$class
,
$zone
) =
@_
;
my
@results
;
push
@results
,
$class
->address01(
$zone
)
if
Zonemaster::Engine::Util::should_run_test(
q{address01}
);
push
@results
,
$class
->address02(
$zone
)
if
Zonemaster::Engine::Util::should_run_test(
q{address02}
);
if
( any {
$_
->tag eq
q{NAMESERVERS_IP_WITH_REVERSE}
}
@results
) {
push
@results
,
$class
->address03(
$zone
)
if
Zonemaster::Engine::Util::should_run_test(
q{address03}
);
}
return
@results
;
}
sub
metadata {
my
(
$class
) =
@_
;
return
{
address01
=> [
qw(
NAMESERVER_IP_PRIVATE_NETWORK
NO_IP_PRIVATE_NETWORK
TEST_CASE_END
TEST_CASE_START
)
],
address02
=> [
qw(
NAMESERVER_IP_WITHOUT_REVERSE
NAMESERVERS_IP_WITH_REVERSE
NO_RESPONSE_PTR_QUERY
TEST_CASE_END
TEST_CASE_START
)
],
address03
=> [
qw(
NAMESERVER_IP_WITHOUT_REVERSE
NAMESERVER_IP_PTR_MISMATCH
NAMESERVER_IP_PTR_MATCH
NO_RESPONSE_PTR_QUERY
TEST_CASE_END
TEST_CASE_START
)
],
};
}
Readonly
my
%TAG_DESCRIPTIONS
=> (
NAMESERVER_IP_WITHOUT_REVERSE
=>
sub
{
__x
'Nameserver {nsname} has an IP address ({ns_ip}) without PTR configured.'
,
@_
;
},
NAMESERVER_IP_PTR_MISMATCH
=>
sub
{
__x
'Nameserver {nsname} has an IP address ({ns_ip}) with mismatched PTR result ({names}).'
,
@_
;
},
NAMESERVER_IP_PRIVATE_NETWORK
=>
sub
{
__x
'Nameserver {nsname} has an IP address ({ns_ip}) '
.
'with prefix {prefix} referenced in {reference} as a \'{name}\'.'
,
@_
;
},
NO_IP_PRIVATE_NETWORK
=>
sub
{
__x
'All Nameserver addresses are in the routable public addressing space.'
,
@_
;
},
NAMESERVERS_IP_WITH_REVERSE
=>
sub
{
__x
"Reverse DNS entry exists for each Nameserver IP address."
,
@_
;
},
NAMESERVER_IP_PTR_MATCH
=>
sub
{
__x
"Every reverse DNS entry matches name server name."
,
@_
;
},
NO_RESPONSE_PTR_QUERY
=>
sub
{
__x
'No response from nameserver(s) on PTR query ({domain}).'
,
@_
;
},
TEST_CASE_END
=>
sub
{
__x
'TEST_CASE_END {testcase}.'
,
@_
;
},
TEST_CASE_START
=>
sub
{
__x
'TEST_CASE_START {testcase}.'
,
@_
;
},
);
sub
tag_descriptions {
return
\
%TAG_DESCRIPTIONS
;
}
sub
version {
return
"$Zonemaster::Engine::Test::Address::VERSION"
;
}
sub
find_special_address {
my
(
$class
,
$ip
) =
@_
;
my
@special_addresses
;
if
(
$ip
->version ==
$IP_VERSION_4
) {
@special_addresses
=
@IPV4_SPECIAL_ADDRESSES
;
}
elsif
(
$ip
->version ==
$IP_VERSION_6
) {
@special_addresses
=
@IPV6_SPECIAL_ADDRESSES
;
}
foreach
my
$ip_details
(
@special_addresses
) {
if
(
$ip
->overlaps( ${
$ip_details
}{ip} ) ) {
return
$ip_details
;
}
}
return
;
}
sub
address01 {
my
(
$class
,
$zone
) =
@_
;
push
my
@results
, info(
TEST_CASE_START
=> {
testcase
=> (
split
/::/, (
caller
(0))[3])[-1] } );
my
%ips
;
foreach
my
$local_ns
( @{ Zonemaster::Engine::TestMethods->method4(
$zone
) }, @{ Zonemaster::Engine::TestMethods->method5(
$zone
) } )
{
next
if
$ips
{
$local_ns
->address->short };
my
$ip_details_ref
=
$class
->find_special_address(
$local_ns
->address );
if
(
$ip_details_ref
) {
push
@results
,
info(
NAMESERVER_IP_PRIVATE_NETWORK
=> {
nsname
=>
$local_ns
->name->string,
ns_ip
=>
$local_ns
->address->short,
prefix
=> ${
$ip_details_ref
}{ip}->
print
,
name
=> ${
$ip_details_ref
}{name},
reference
=> ${
$ip_details_ref
}{reference},
}
);
}
$ips
{
$local_ns
->address->short }++;
}
if
(
scalar
keys
%ips
and not
grep
{
$_
->tag ne
q{TEST_CASE_START}
}
@results
) {
push
@results
, info(
NO_IP_PRIVATE_NETWORK
=> {} );
}
return
(
@results
, info(
TEST_CASE_END
=> {
testcase
=> (
split
/::/, (
caller
(0))[3])[-1] } ) );
}
sub
address02 {
my
(
$class
,
$zone
) =
@_
;
push
my
@results
, info(
TEST_CASE_START
=> {
testcase
=> (
split
/::/, (
caller
(0))[3])[-1] } );
my
%ips
;
my
$ptr_query
;
foreach
my
$local_ns
( @{ Zonemaster::Engine::TestMethods->method4(
$zone
) }, @{ Zonemaster::Engine::TestMethods->method5(
$zone
) } )
{
next
if
$ips
{
$local_ns
->address->short };
my
$reverse_ip_query
=
$local_ns
->address->reverse_ip;
$ptr_query
=
$reverse_ip_query
;
my
$p
= Zonemaster::Engine::Recursor->recurse(
$ptr_query
,
q{PTR}
);
if
(
$p
and
$p
->rcode eq
q{NOERROR}
and
$p
->get_records(
q{CNAME}
,
q{answer}
) ) {
my
(
$cname
) =
$p
->get_records(
q{CNAME}
,
q{answer}
);
$ptr_query
=
$cname
->cname;
$p
= Zonemaster::Engine::Recursor->recurse(
$ptr_query
,
q{PTR}
);
}
if
(
$p
) {
if
(
$p
->rcode ne
q{NOERROR}
or not
$p
->get_records(
q{PTR}
,
q{answer}
) ) {
push
@results
,
info(
NAMESERVER_IP_WITHOUT_REVERSE
=> {
nsname
=>
$local_ns
->name->string,
ns_ip
=>
$local_ns
->address->short,
}
);
}
}
else
{
push
@results
,
info(
NO_RESPONSE_PTR_QUERY
=> {
domain
=>
$ptr_query
,
}
);
}
$ips
{
$local_ns
->address->short }++;
}
if
(
scalar
keys
%ips
and not
grep
{
$_
->tag ne
q{TEST_CASE_START}
}
@results
) {
push
@results
, info(
NAMESERVERS_IP_WITH_REVERSE
=> {} );
}
return
(
@results
, info(
TEST_CASE_END
=> {
testcase
=> (
split
/::/, (
caller
(0))[3])[-1] } ) );
}
sub
address03 {
my
(
$class
,
$zone
) =
@_
;
push
my
@results
, info(
TEST_CASE_START
=> {
testcase
=> (
split
/::/, (
caller
(0))[3])[-1] } );
my
$ptr_query
;
my
%ips
;
foreach
my
$local_ns
( @{ Zonemaster::Engine::TestMethods->method5(
$zone
) } ) {
next
if
$ips
{
$local_ns
->address->short };
my
$reverse_ip_query
=
$local_ns
->address->reverse_ip;
$ptr_query
=
$reverse_ip_query
;
my
$p
= Zonemaster::Engine::Recursor->recurse(
$ptr_query
,
q{PTR}
);
if
(
$p
and
$p
->rcode eq
q{NOERROR}
and
$p
->get_records(
q{CNAME}
,
q{answer}
) ) {
my
(
$cname
) =
$p
->get_records(
q{CNAME}
,
q{answer}
);
$ptr_query
=
$cname
->cname;
$p
= Zonemaster::Engine::Recursor->recurse(
$ptr_query
,
q{PTR}
);
}
if
(
$p
) {
my
@ptr
=
$p
->get_records_for_name(
q{PTR}
,
$ptr_query
);
if
(
$p
->rcode eq
q{NOERROR}
and
scalar
@ptr
) {
if
( none { name(
$_
->ptrdname ) eq
$local_ns
->name->string .
q{.}
}
@ptr
) {
push
@results
,
info(
NAMESERVER_IP_PTR_MISMATCH
=> {
nsname
=>
$local_ns
->name->string,
ns_ip
=>
$local_ns
->address->short,
names
=>
join
(
q{/}
,
map
{
$_
->ptrdname }
@ptr
),
}
);
}
}
else
{
push
@results
,
info(
NAMESERVER_IP_WITHOUT_REVERSE
=> {
nsname
=>
$local_ns
->name->string,
ns_ip
=>
$local_ns
->address->short,
}
);
}
}
else
{
push
@results
,
info(
NO_RESPONSE_PTR_QUERY
=> {
domain
=>
$ptr_query
,
}
);
}
$ips
{
$local_ns
->address->short }++;
}
if
(
scalar
keys
%ips
and not
grep
{
$_
->tag ne
q{TEST_CASE_START}
}
@results
) {
push
@results
, info(
NAMESERVER_IP_PTR_MATCH
=> {} );
}
return
(
@results
, info(
TEST_CASE_END
=> {
testcase
=> (
split
/::/, (
caller
(0))[3])[-1] } ) );
}
1;