App-DNS-Zonewalk
view release on metacpan or search on metacpan
bin/zonewalk view on Meta::CPAN
use App::DNS::Zonewalk qw();
use Getopt::Long qw(GetOptions);
use Pod::Usage qw(pod2usage);
our $VERSION = '0.05';
our $debug;
our $v4;
our $v6;
our $long_listing;
our $server;
our $start_zone;
handle_options();
my $rec_zone_listing = run_raxfr($start_zone);
print_rec_zone($rec_zone_listing);
exit;
###############################################################
# end of main
###############################################################
#
# check cmdline flags and args
#
sub handle_options {
GetOptions(
'debug|d' => \$debug,
'4' => \$v4,
'6' => \$v6,
'long|l' => \$long_listing,
'server|s=s' => \$server,
)
or pod2usage(
-exitval => 2,
-verbose => 1,
);
# get the start zone from cmdline
$start_zone = lc shift @ARGV
or pod2usage(
-exitval => 2,
-verbose => 1,
-message => 'missing zone',
);
# #####################
# convenience function
# #####################
#
# check for IPv4 address as start zone, build reverse zone
if ( Net::DNS::Resolver::Base::_ip_is_ipv4($start_zone) ) {
my @octets = split( /\./, $start_zone );
$start_zone = join( '.', reverse @octets );
$start_zone .= '.in-addr.arpa';
}
# check for IPv6 address as start zone, build reverse zone
elsif ( Net::DNS::Resolver::Base::_ip_is_ipv6($start_zone) ) {
# this simple algo works only for fully expanded IPv6 addresses
$start_zone =~ s/://g;
my @octets = split( //, $start_zone );
$start_zone = join( '.', reverse @octets );
$start_zone .= '.ip6.arpa';
}
return 1;
}
#
# create a Net::DNS::Resolver object and do a raxfr() fro start zone
# return an array-ref of Net::DNS::RR objects from zone walk
#
sub run_raxfr {
my $zone = shift;
my $resolver = App::DNS::Zonewalk->new(
retrans => 1,
retry => 1,
tcp_timeout => 3,
debug => $debug,
$server ? ( nameservers => [$server] ) : (),
);
my $rec_zone_listing = $resolver->raxfr($zone);
unless (@$rec_zone_listing) {
warn "Cannot fetch '$zone': ", $resolver->errorstring, "\n";
exit 1;
}
return $rec_zone_listing;
}
#
# print A, AAAA or PTR records as default
# only when requested (-l) do a full RR listing
#
sub print_rec_zone {
my ($zone) = @_;
foreach my $rr (@$zone) {
if ($long_listing) {
$rr->print;
next;
}
# was this a reverse_zone walk, just print the PTR records
if ( $start_zone =~ m/ .* \.in-addr\.arpa $ | .* \.ip6\.arpa $/ix )
{
printf "%-30s %s\n", $rr->name, $rr->ptrdname
if $rr->type eq 'PTR';
next;
}
given ( $rr->type ) {
when ('A') {
printf "%-15s %s\n", $rr->address, $rr->name unless $v6;
}
( run in 1.819 second using v1.01-cache-2.11-cpan-a9496e3eb41 )