Line # Revision Author
1 51 dpavlin #!/usr/bin/perl -w
2
3 use Net::DNS;
4 use Algorithm::Diff qw(traverse_sequences);
5 use Data::Dumper;
6
7 my $verbose = 1;
8 my $debug = 0;
9
10 my $res;
11
12 sub check {
13 my $arg = shift || die "no arg?";
14
15 print "## $arg\n" if ($debug);
16
17 my ($domain,$type,$what,$server) = split(/\s+/,$arg) or die "can't split $arg into domain, type, what, server";
18
19 $res->{$server} ||= Net::DNS::Resolver->new(
20 nameservers => [ $server ],
21 recurse => 0,
22 debug => $debug,
23 );
24
25 my $query = $res->{$server}->query($domain, $type) || die "can't find $type $domain on $server\n";
26
27 my @out;
28
29 if ($query) {
30 foreach my $ans ($query->answer) {
31 push @out, $ans->$what;
32 }
33 } else {
34 print "query $type $domain failed: ", $res->errorstring, "\n";
35 }
36
37 print "# out: ",join(",",(sort @out)),"\n" if ($debug);
38
39 return @out;
40 }
41
42 my $domain = shift @ARGV || die "usage: $0 my.domain.com [primary.dns.com]\n";
43 my $master = shift @ARGV || '127.0.0.1';
44
45 my ($serial) = check("$domain SOA serial $master");
46 my @ns = check("$domain NS nsdname $master");
47 @ns = sort @ns;
48 foreach $ns ( @ns ) {
49 print "# testing $ns $domain\n" if ($verbose);
50
51 my ($s) = check("$domain SOA serial $ns");
52 if ($s != $serial) {
53 print STDERR "ERROR\t$ns: serial $s != $serial\n";
54 } else {
55 print "ok\t$ns: serial $s\n" if ($verbose);
56 }
57
58 my @ns_this = check("$domain NS nsdname $ns");
59 @ns_this = sort @ns_this;
60
61 print "### ns: ",join(",",@ns),"\n" if ($debug);
62 print "### ns_this: ",join(",",@ns_this),"\n" if ($debug);
63
64 traverse_sequences(\@ns, \@ns_this, {
65 MATCH => sub { print "ok\t$ns: $domain NS ",$ns[$_[0]],"\n" if ($verbose); },
66 DISCARD_A => sub { print "ERROR\t$ns: $domain NS missing: ",$ns[$_[0]],"\n"; },
67 DISCARD_B => sub { print "ERROR\t$ns: $domain NS added: ", $ns_this[$_[1]],"\n"; },
68 });
69
70 }
71