Blame demo/check_soa

Packit e6c8bb
#!/usr/local/bin/perl -w
Packit e6c8bb
# $Id: check_soa 264 2005-04-06 09:16:15Z olaf $
Packit e6c8bb
Packit e6c8bb
=head1 NAME
Packit e6c8bb
Packit e6c8bb
check_soa - Check a domain's nameservers
Packit e6c8bb
Packit e6c8bb
=head1 SYNOPSIS
Packit e6c8bb
Packit e6c8bb
B<check_soa> I<domain>
Packit e6c8bb
Packit e6c8bb
=head1 DESCRIPTION
Packit e6c8bb
Packit e6c8bb
B<check_soa> queries each of a domain's nameservers for the Start
Packit e6c8bb
of Authority (SOA) record and prints the serial number.  Errors
Packit e6c8bb
are printed for nameservers that couldn't be reached or didn't
Packit e6c8bb
answer authoritatively.
Packit e6c8bb
Packit e6c8bb
=head1 AUTHOR
Packit e6c8bb
Packit e6c8bb
The original Bourne Shell and C versions were printed in
Packit e6c8bb
I<DNS and BIND> by Paul Albitz & Cricket Liu.
Packit e6c8bb
Packit e6c8bb
This Perl version was written by Michael Fuhr <mike@fuhr.org>.
Packit e6c8bb
Packit e6c8bb
=head1 SEE ALSO
Packit e6c8bb
Packit e6c8bb
L<perl(1)>, L<axfr>, L<check_zone>, L<mresolv>, L<mx>, L<perldig>, L<Net::DNS>
Packit e6c8bb
Packit e6c8bb
=cut
Packit e6c8bb
Packit e6c8bb
use File::Basename;
Packit e6c8bb
use Net::DNS;
Packit e6c8bb
use strict;
Packit e6c8bb
Packit e6c8bb
#------------------------------------------------------------------------------
Packit e6c8bb
# Get the domain from the command line.
Packit e6c8bb
#------------------------------------------------------------------------------
Packit e6c8bb
Packit e6c8bb
die "Usage: ", basename($0), " domain\n" unless @ARGV == 1;
Packit e6c8bb
Packit e6c8bb
my ($domain) = @ARGV;
Packit e6c8bb
Packit e6c8bb
#------------------------------------------------------------------------------
Packit e6c8bb
# Find all the nameservers for the domain.
Packit e6c8bb
#------------------------------------------------------------------------------
Packit e6c8bb
Packit e6c8bb
my $res = Net::DNS::Resolver->new();
Packit e6c8bb
Packit e6c8bb
$res->defnames(0);
Packit e6c8bb
$res->retry(2);
Packit e6c8bb
Packit e6c8bb
my $ns_req = $res->query($domain, "NS");
Packit e6c8bb
die "No nameservers found for $domain: ", $res->errorstring, "\n"
Packit e6c8bb
	unless defined($ns_req) and ($ns_req->header->ancount > 0);
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
# Send out non-recursive queries
Packit e6c8bb
$res->recurse(0);
Packit e6c8bb
# Do not buffer standard out
Packit e6c8bb
$| = 1;
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
#------------------------------------------------------------------------------
Packit e6c8bb
# Check the SOA record on each nameserver.
Packit e6c8bb
#------------------------------------------------------------------------------
Packit e6c8bb
Packit e6c8bb
foreach my $nsrr (grep {$_->type eq "NS" } $ns_req->answer) {
Packit e6c8bb
	
Packit e6c8bb
	#----------------------------------------------------------------------
Packit e6c8bb
	# Set the resolver to query this nameserver.
Packit e6c8bb
	#----------------------------------------------------------------------
Packit e6c8bb
	my $ns = $nsrr->nsdname;
Packit e6c8bb
	
Packit e6c8bb
	# In order to lookup the IP(s) of the nameserver, we need a Resolver
Packit e6c8bb
	# object that is set to our local, recursive nameserver.  So we create
Packit e6c8bb
	# a new object just to do that.
Packit e6c8bb
	
Packit e6c8bb
	my $local_res = Net::DNS::Resolver->new();
Packit e6c8bb
	
Packit e6c8bb
	my $a_req = $local_res->query($ns, 'A');
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
	unless ($a_req) {
Packit e6c8bb
		warn "Can not find address for $ns: ", $res->errorstring, "\n";
Packit e6c8bb
		next;
Packit e6c8bb
	}
Packit e6c8bb
	
Packit e6c8bb
	foreach my $ip (map { $_->address } grep { $_->type eq 'A' } $a_req->answer) {
Packit e6c8bb
		#----------------------------------------------------------------------
Packit e6c8bb
		# Ask this IP.
Packit e6c8bb
		#----------------------------------------------------------------------
Packit e6c8bb
		$res->nameservers($ip);	
Packit e6c8bb
	
Packit e6c8bb
		print "$ns ($ip): ";
Packit e6c8bb
Packit e6c8bb
		#----------------------------------------------------------------------
Packit e6c8bb
		# Get the SOA record.
Packit e6c8bb
		#----------------------------------------------------------------------
Packit e6c8bb
	
Packit e6c8bb
		my $soa_req = $res->send($domain, 'SOA', 'IN');
Packit e6c8bb
		
Packit e6c8bb
		unless (defined($soa_req)) {
Packit e6c8bb
			warn $res->errorstring, "\n";
Packit e6c8bb
			next;
Packit e6c8bb
		}
Packit e6c8bb
Packit e6c8bb
		#----------------------------------------------------------------------
Packit e6c8bb
		# Is this nameserver authoritative for the domain?
Packit e6c8bb
		#----------------------------------------------------------------------
Packit e6c8bb
Packit e6c8bb
		unless ($soa_req->header->aa) {
Packit e6c8bb
			warn "isn't authoritative for $domain\n";
Packit e6c8bb
			next;
Packit e6c8bb
		}
Packit e6c8bb
Packit e6c8bb
		#----------------------------------------------------------------------
Packit e6c8bb
		# We should have received exactly one answer.
Packit e6c8bb
		#----------------------------------------------------------------------
Packit e6c8bb
Packit e6c8bb
		unless ($soa_req->header->ancount == 1) {
Packit e6c8bb
			warn "expected 1 answer, got ", $soa_req->header->ancount, "\n";
Packit e6c8bb
			next;
Packit e6c8bb
		}
Packit e6c8bb
		
Packit e6c8bb
		#----------------------------------------------------------------------
Packit e6c8bb
		# Did we receive an SOA record?
Packit e6c8bb
		#----------------------------------------------------------------------
Packit e6c8bb
	
Packit e6c8bb
		unless (($soa_req->answer)[0]->type eq "SOA") {
Packit e6c8bb
			warn "expected SOA, got ", ($soa_req->answer)[0]->type, "\n";
Packit e6c8bb
			next;
Packit e6c8bb
		}
Packit e6c8bb
		
Packit e6c8bb
		#----------------------------------------------------------------------
Packit e6c8bb
		# Print the serial number.
Packit e6c8bb
		#----------------------------------------------------------------------
Packit e6c8bb
Packit e6c8bb
		print "has serial number ", ($soa_req->answer)[0]->serial, "\n";
Packit e6c8bb
	}
Packit e6c8bb
}
Packit e6c8bb
Packit e6c8bb
0;