#!/usr/bin/perl
getopts(
"r"
);
die
"Usage: "
, basename($0),
" [ -r ] domain [ class ]\n"
unless
(
@ARGV
>= 1) && (
@ARGV
<= 2);
check_domain(
@ARGV
);
exit
;
sub
check_domain {
my
(
$domain
,
$class
) =
@_
;
$class
||=
"IN"
;
print
"-"
x 70,
"\n"
;
print
"$domain (class $class)\n"
;
print
"\n"
;
my
$res
= Net::DNS::Resolver->new;
$res
->defnames(0);
$res
->retry(2);
my
$nspack
=
$res
->query(
$domain
,
"NS"
,
$class
);
unless
(
defined
(
$nspack
)) {
warn
"Couldn't find nameservers for $domain: "
,
$res
->errorstring,
"\n"
;
return
;
}
print
"nameservers (will request zone from first available):\n"
;
my
$ns
;
foreach
my
$ns
(
grep
{
$_
->type eq
"NS"
}
$nspack
->answer) {
print
"\t"
,
$ns
->nsdname,
"\n"
;
}
print
"\n"
;
$res
->nameservers(
map
{
$_
->nsdname }
grep
{
$_
->type eq
"NS"
}
$nspack
->answer);
my
@zone
=
$res
->axfr(
$domain
,
$class
);
unless
(
@zone
) {
warn
"Zone transfer failed: "
,
$res
->errorstring,
"\n"
;
return
;
}
print
"checking PTR records\n"
;
check_ptr(
$domain
,
$class
,
@zone
);
print
"\n"
;
print
"checking NS records\n"
;
check_ns(
$domain
,
$class
,
@zone
);
print
"\n"
;
print
"checking MX records\n"
;
check_mx(
$domain
,
$class
,
@zone
);
print
"\n"
;
print
"checking CNAME records\n"
;
check_cname(
$domain
,
$class
,
@zone
);
print
"\n"
;
if
(
$opt_r
) {
print
"checking subdomains\n\n"
;
my
%subdomains
;
foreach
(
grep
{
$_
->type eq
"NS"
and
$_
->name ne
$domain
}
@zone
) {
$subdomains
{
$_
->name} = 1;
}
foreach
(
sort
keys
%subdomains
) {
check_domain(
$_
,
$class
);
}
}
return
;
}
sub
check_ptr {
my
(
$domain
,
$class
,
@zone
) =
@_
;
my
$res
= Net::DNS::Resolver->new;
my
$rr
;
foreach
my
$rr
(
grep
{
$_
->type eq
"A"
}
@zone
) {
my
$host
=
$rr
->name;
my
$addr
=
$rr
->address;
my
$ans
=
$res
->
send
(
$addr
,
"A"
,
$class
);
print
"\t$host ($addr) has no PTR record\n"
if
(
$ans
->header->ancount < 1);
}
return
;
}
sub
check_ns {
my
(
$domain
,
$class
,
@zone
) =
@_
;
my
$res
= Net::DNS::Resolver->new;
my
$rr
;
foreach
my
$rr
(
grep
{
$_
->type eq
"NS"
}
@zone
) {
my
$ans
=
$res
->
send
(
$rr
->nsdname,
"A"
,
$class
);
print
"\t"
,
$rr
->nsdname,
" has no A record\n"
if
(
$ans
->header->ancount < 1);
}
return
;
}
sub
check_mx {
my
(
$domain
,
$class
,
@zone
) =
@_
;
my
$res
= Net::DNS::Resolver->new;
my
$rr
;
foreach
my
$rr
(
grep
{
$_
->type eq
"MX"
}
@zone
) {
my
$ans
=
$res
->
send
(
$rr
->exchange,
"A"
,
$class
);
print
"\t"
,
$rr
->exchange,
" has no A record\n"
if
(
$ans
->header->ancount < 1);
}
return
;
}
sub
check_cname {
my
(
$domain
,
$class
,
@zone
) =
@_
;
my
$res
= Net::DNS::Resolver->new;
my
$rr
;
foreach
my
$rr
(
grep
{
$_
->type eq
"CNAME"
}
@zone
) {
my
$ans
=
$res
->
send
(
$rr
->cname,
"A"
,
$class
);
print
"\t"
,
$rr
->cname,
" has no A record\n"
if
(
$ans
->header->ancount < 1);
}
return
;
}