DNS Lookups with Perl Net::DNS::Resolver
Sometimes when parsing logs or files you need to know what the IP resolves to. This Perl script uses Net::DNS::Resolver to Automate DNS Lookups.
The advantage of using Net::DNS::Resolver over other methods is the ability to get more information from the DNS servers, and specify which DNS servers to use.
#!/usr/bin/perl
# takes list of DATA and does dns lookup
# gethostbyaddr uses whatever is confiogured on said client
# Net DNS Resolver allows you to specify lookup servers in script
#usage: perl resolver.pl > hosts.csv
$|++;
use warnings;
use strict;
use Socket;
use Net::DNS::Resolver;
my %ips; # will hold deduped list of ips addresses
# process the data handle and load up the hash
while (<data>) {
my $ip = $_;
chomp $ip;
$ips{$ip}++;
}
# get counts
my $ips = %ips;
my $count = 0;
print "FOUND $ips IPs\n";
# deduped, now proceed by looping over hash keys
foreach my $ip (keys %ips) {
$count++; # real count of found ips, different than input ips
# if you want to see status on a large list (sometimes it takes hours to process large lists)
#warn "$count -> $ip\n";
# very crude, use real regex module if you care
# if your input isn't tested, you need to fix this
if($ip =~ /^\d+.\d+.\d+.\d+$/) {
# NET::DNS::Resolver way:
# create new Resolver Object, YMMV
my $res = new Net::DNS::Resolver(
nameservers => [ '192.168.1.1', '208.67.222.222', '208.67.220.220' ],
#debug => 1 # spews entire DNS query results
recurse => 1,
# 1 = recursive, accurate, keeps asking anyone, even poisoned caches until it thinks answer is right
# 0 = iterative, final answer, no verification from others
#iterative is probably how security should be handled.
);
# even with timeout of 5 this can take hours on a large list
$res->tcp_timeout(5);
# change IP from 192.168.1.15 to 15.1.168.192.in-addr.arpa for searching
my $target_IP = join('.', reverse split(/\./, $ip)).".in-addr.arpa";
# query DNS
my $query = $res->query("$target_IP", "PTR");
# if a result is found
if ($query){
print("'$ip,'");
# for every result, print the IP address
foreach my $rr ($query->answer){
# show all unless the type is PTR (pointer to a canonical name)
next unless $rr->type eq "PTR";
# remove the period at the end
printf(substr($rr->rdatastr, 0, -1));
print "'\n";
}
} else {
print "'$ip','UNKNOWN'\n";
}
} else {
print " Expected: <host>, got <$ip>\n";
}
}
__DATA__
1.1.1.1
10.10.0.10
192.192.192.192
8.8.8.8