File: check_soa

package info (click to toggle)
libnet-dns-perl 0.19-0.1
  • links: PTS
  • area: main
  • in suites: woody
  • size: 544 kB
  • ctags: 323
  • sloc: perl: 5,191; makefile: 54
file content (133 lines) | stat: -rwxr-xr-x 3,918 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#!/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<check_soa> I<domain>

=head1 DESCRIPTION

B<check_soa> 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<DNS and BIND> by Paul Albitz & Cricket Liu.

This Perl version was written by Michael Fuhr <mike@fuhr.org>.

=head1 SEE ALSO

L<perl(1)>, L<axfr>, L<check_zone>, L<mresolv>, L<mx>, L<perldig>, L<Net::DNS>

=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";
}