simple/dns/check.pl

98 lines
2.2 KiB
Perl

#!/usr/bin/perl -w
use strict;
use Net::DNS;
sub usage {
print STDERR "Usage: $0 domainname-or-ip-address\n";
exit(1);
}
usage() unless (@ARGV == 1);
my $res = new Net::DNS::Resolver;
if ($ARGV[0] =~ m/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/) {
check_ptr($ARGV[0]);
} else {
check_a($ARGV[0]);
# check_ns($ARGV[0]);
}
exit 0;
my %addr_to_name;
my %name_to_addr;
sub check_ptr {
my ($addr, $name) = @_;
my @names;
if (defined $addr_to_name{$addr}) {
@names = @{ $addr_to_name{$addr} };
} else {
# XXX - ipv6?
my $q = join('.', reverse (split(/\./, $addr)), "in-addr", "arpa");
my $reply = $res->send($q, 'PTR');
for my $ans ($reply->answer) {
if ($ans->type eq 'PTR') {
push @names, $ans->ptrdname;
} else {
die "cannot happen";
}
}
if (@names == 0) {
print "[$addr] $q has no PTR record\n";
}
$addr_to_name{$addr} = \@names;
}
if ($name) {
unless (grep { $_ eq $name } @names) {
print "$name not found in PTR records of [$addr]\n";
}
return;
}
for my $name (@names) {
check_a($name, $addr);
}
}
sub check_a {
my ($name, $addr) = @_;
my @addrs;
if (defined $name_to_addr{$name}) {
@addrs = @{ $name_to_addr{$name} };
} else {
my $reply = $res->send($name, 'A');
for my $ans ($reply->answer) {
if ($ans->type eq 'A') {
push @addrs, $ans->address;
} else {
print "unexpected response to A query for $name\n";
$ans->print;
}
}
if (@addrs == 0) {
print "$name has no A record\n";
}
$name_to_addr{$name} = \@addrs;
}
if ($addr) {
unless (grep { $_ eq $addr } @addrs) {
print "[$addr] not found in A records of $name\n";
}
return;
}
for my $addr (@addrs) {
check_ptr($addr, $name);
}
}
my $answer = $res->query($ARGV[0], $ARGV[1]);
if ($answer) {
$answer->print;
} else {
print STDERR "query failed: ", $res->errorstring, "\n";
}
# $res->nameservers($ARGV[2]);