DNS checking using perl and Net::DNS

旧时模样 提交于 2020-01-04 03:45:20

问题


So, in the otter book, there is a small script(see page 173) whose purpose is to iteratively check DNS servers to see if they are returning the same address for a given hostname. However, the solution given in the book works only when the host has a static IP address. How would I write this script if I wanted it to work with hosts that have multiple addresses associated with them?

Here is the code:

#!/usr/bin/perl
use Data::Dumper;
use Net::DNS;

my $hostname = $ARGV[0];
# servers to check
my @servers = qw(8.8.8.8 208.67.220.220 8.8.4.4);

my %results;
foreach my $server (@servers) {
    $results{$server} 
        = lookup( $hostname, $server );
}

my %inv = reverse %results; # invert results - it should have one key if all
                           # are the same
if (scalar keys %inv > 1) { # if it has more than one key
    print "The results are different:\n";
    print Data::Dumper->Dump( [ \%results ], ['results'] ), "\n";
}

sub lookup {
    my ( $hostname, $server ) = @_;

    my $res = new Net::DNS::Resolver;
    $res->nameservers($server);
    my $packet = $res->query($hostname);

    if ( !$packet ) {
        warn "$server not returning any data for $hostname!\n";
        return;
    }
    my (@results);
    foreach my $rr ( $packet->answer ) {
        push ( @results, $rr->address );
    }
    return join( ', ', sort @results );
}

回答1:


The problem I had was that I was getting this error calling the code on a hostname that returned multiple addresses, such as www.google.com:

***  WARNING!!!  The program has attempted to call the method
***  "address" for the following RR object:
***
***  www.google.com.    86399   IN  CNAME   www.l.google.com.
***
***  This object does not have a method "address".  THIS IS A BUG
***  IN THE CALLING SOFTWARE, which has incorrectly assumed that
***  the object would be of a particular type.  The calling
***  software should check the type of each RR object before
***  calling any of its methods.
***
***  Net::DNS has returned undef to the caller.

This error meant that I was trying to call the address method on an rr object of type CNAME. I want to call the address method only on rr objects of type 'A'. In the code above, I have no checks to make sure I'm calling address on objects of type 'A'. I added this line of code(the next unless one), and it works:

my (@results);
foreach my $rr ( $packet->answer ) {
    next unless $rr->type eq "A";
    push ( @results, $rr->address );
}

This line of code skips to the next address gotten from $packet->answer unless the rr object's type is "A".



来源:https://stackoverflow.com/questions/9244843/dns-checking-using-perl-and-netdns

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!