#!/usr/bin/perl -w # $Id: check_soa,v 1.7 2000/11/10 16:01:21 mfuhr Exp mfuhr $ =head1 NAME check_soa - Check a domain's nameservers =head1 SYNOPSIS B I =head1 DESCRIPTION B queries each of a domain's nameservers for the Start of Authority (SOA) record and prints the serial number. Errors are printed for nameservers that couldn't be reached or didn't answer authoritatively. =head1 AUTHOR The original Bourne Shell and C versions were printed in I by Paul Albitz & Cricket Liu. This Perl version was written by Michael Fuhr . =head1 SEE ALSO L, L, L, L, L, L, L =cut use File::Basename; use Net::DNS::Resolver; use Net::DNS::RR; use strict; #------------------------------------------------------------------------------ # Get the domain from the command line. #------------------------------------------------------------------------------ die "Usage: ", basename($0), " domain\n" unless @ARGV == 1; my ($domain) = @ARGV; #------------------------------------------------------------------------------ # Find all the nameservers for the domain. #------------------------------------------------------------------------------ my $res = Net::DNS::Resolver->new; $res->defnames(0); $res->retry(2); my $ns_req = $res->query($domain, "NS"); die "No nameservers found for $domain: ", $res->errorstring, "\n" unless defined($ns_req) and ($ns_req->header->ancount > 0); #------------------------------------------------------------------------------ # Check the SOA record on each nameserver. #------------------------------------------------------------------------------ $res->recurse(0); $| = 1; foreach my $nsrr (grep {$_->type eq "NS" } $ns_req->answer) { #---------------------------------------------------------------------- # Set the resolver to query this nameserver. #---------------------------------------------------------------------- my $ns = $nsrr->nsdname; print "$ns "; unless ($res->nameservers($ns)) { warn ": can't find address: ", $res->errorstring, "\n"; next; } print "(", join(" ", $res->nameservers), ") "; #---------------------------------------------------------------------- # Get the SOA record. #---------------------------------------------------------------------- my $packet = Net::DNS::Packet->new($domain, "SOA", "IN"); my $soa_req = $res->send($packet); unless (defined($soa_req)) { warn ": ", $res->errorstring, "\n"; next; } #---------------------------------------------------------------------- # Is this nameserver authoritative for the domain? #---------------------------------------------------------------------- unless ($soa_req->header->aa) { print STDERR "isn't authoritative for $domain"; if ($soa_req->header->ancount >= 1 && ($soa_req->answer)[0]->type eq "SOA") { print STDERR " (has SOA, serial = ", ($soa_req->answer)[0]->serial, ")"; } print "\n"; next; } #---------------------------------------------------------------------- # We should have received exactly one answer. #---------------------------------------------------------------------- unless ($soa_req->header->ancount == 1) { warn ": expected 1 answer, got ", $soa_req->header->ancount, "\n"; next; } #---------------------------------------------------------------------- # Did we receive an SOA record? #---------------------------------------------------------------------- unless (($soa_req->answer)[0]->type eq "SOA") { warn ": expected SOA, got ", ($soa_req->answer)[0]->type, "\n"; next; } #---------------------------------------------------------------------- # Print the serial number. #---------------------------------------------------------------------- print "has serial number ", ($soa_req->answer)[0]->serial, "\n"; }