diff --git a/dns/GNUmakefile b/dns/GNUmakefile index 9ab40c2..1148a56 100644 --- a/dns/GNUmakefile +++ b/dns/GNUmakefile @@ -1,11 +1,12 @@ include GNUmakevars -all: gethostbyname fqdn +all: gethostbyname fqdn query install: \ - $(BINDIR)/gethostbyname \ $(BINDIR)/axfr \ $(BINDIR)/fqdn \ + $(BINDIR)/gethostbyname \ $(BINDIR)/minnet \ + $(BINDIR)/query \ clean: diff --git a/dns/check.pl b/dns/check.pl new file mode 100644 index 0000000..72dfd41 --- /dev/null +++ b/dns/check.pl @@ -0,0 +1,97 @@ +#!/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]); diff --git a/dns/query b/dns/query new file mode 100755 index 0000000..42e43eb --- /dev/null +++ b/dns/query @@ -0,0 +1,19 @@ +#!/usr/bin/perl -w +use strict; +use Net::DNS; + +sub usage { + print STDERR "Usage: $0 domainname type nameserver\n" unless (@ARGV == 2); + exit(1); +} + +usage() unless (@ARGV == 3); + +my $res = new Net::DNS::Resolver; +$res->nameservers($ARGV[2]); +my $answer = $res->query($ARGV[0], $ARGV[1]); +if ($answer) { + $answer->print; +} else { + print STDERR "query failed: ", $res->errorstring, "\n"; +}