Bulk domain name resolver with perl
I was in the need of getting the ip address from a long list of domain names, the domains were stored in a MySQL db, so I quickly turned into perl for making a script that got the list and then use an external command to resolve the domain.
At first I was going to use the dig command, but that would have taken to much effort, then I thought about using the ping command, but again to much effort, instead I’ve decided to leverage the IO::Socket::INET module, trying to open a socket to a domain name, will resolve the name and I could use that.
My implementation was very simple and it worked well, here is the relevant part:
#include the module use IO::Socket::INET;#create a socket to uncommon udp port, because tcp is likely to be firewalled my $sock = IO::Socket::INET->new( PeerAddr=> "$domain", PeerPort =>40125, Proto=>'udp');#if we can create a socket, then we have an ip if (defined $sock) { $result = $sock->peerhost; logOut("Success!"); } else { logOut("Failed trying to connect to $domain"); return;}
This was Pretty simple no?, here is the complete script, which gathers all the rows with no ip address and then it will try to get the ip, update the row and continue.
#!/usr/bin/perl use strict; use DBI; use IO::Socket::INET;####Global Variables### our %db = ('host' => 'localhost','name' => 'domains','user' => 'ivan','pass' => '1234','port' => '3306'); our $dsn; our $dbh;#log function sub logOut { my ($msg) = @_; print $msg . "\n";}#db connection sub initialize { logOut("Connecting to db server on $db{'host'}"); $dsn = "DBI:mysql:database=$db{'name'};host=$db{'host'};port=$db{'port'}"; $dbh = DBI->connect($dsn, $db{'user'}, $db{'pass'}) or die('failed to connect');}#function to gather the ip fo a domain sub getIpAddress { my ($domain) = @_; logOut("Trying to connect to: $domain..."); my $result; my $sock = IO::Socket::INET->new( PeerAddr=> "$domain", PeerPort =>40125, Proto=>'udp'); if (defined $sock) { $result = $sock->peerhost; logOut("Success!"); } else { logOut("Failed trying to connect to $domain"); return;} return $result;}##This function# gets all domains from domains table sub getDomains { logOut("Fetching db for domains..."); my $result = $dbh->selectall_hashref("SELECT domain_name FROM domains WHERE ip_address IS NULL", 'domain_name'); logOut(keys( %$result ) . " domains returned."); my $updatedDomains = 0; my $noIpDomains = 0; foreach my $id (keys %$result) { my $ip = getIpAddress($result->{$id}->{domain_name}); if ($ip) { logOut("Ip found $ip for $result->{$id}->{domain_name}"); my @values = ($ip, $result->{$id}->{domain_name}); my $re = $dbh->do("UPDATE domains SET ip_address=? WHERE domain_name=?",undef, @values); if ($re == 1) { $updatedDomains++;} } else { logOut("no ip for $result->{$id}->{domain_name}"); $noIpDomains++;}} logOut("Updated Domains: $updatedDomains"); logOut("Domains with no Ip found: $noIpDomains");}#script starts here initialize(); getDomains();
Maybe there are more efficient methods but as I said, this worked pretty well, it didn’t consume a lot of results and it performs fast enough for my needs.