| FxChiP ( @ 2009-05-06 01:56:00 |
| Current mood: | |
| Current music: | Eric Johnson - Cliffs of Dover |
Feature creep?
WARNING: Technobabble! You may not understand a lot of this! (If you do, though, so much the better)
Recently I had need of a script or tool that would reverse DNS a bunch of IPs, and then do a forward lookup on the results of the rDNS to ensure that the hostnames given would, indeed, point back to the IPs originally looked up to begin with. Something like this would, of course, be done to verify proper DNS operation of a host; essentially to make sure everything is pointing to the right place.
Take a look at the output and capabilities of it thus far:
fxchip@Leviathan:~/Code$ ./double-lookup.pl 66.249.66.244-66.249.67.15 IP Hostname Back to IP 66.249.66.244 crawl-66-249-66-244.googlebot.com 66.249.66.244 66.249.66.245 N/A - couldn't lookup N/A 66.249.66.246 N/A - couldn't lookup N/A 66.249.66.247 N/A - couldn't lookup N/A 66.249.66.248 N/A - couldn't lookup N/A 66.249.66.249 N/A - couldn't lookup N/A 66.249.66.250 N/A - couldn't lookup N/A 66.249.66.251 N/A - couldn't lookup N/A 66.249.66.252 N/A - couldn't lookup N/A 66.249.66.253 N/A - couldn't lookup N/A 66.249.66.254 N/A - couldn't lookup N/A 66.249.66.255 N/A - couldn't lookup N/A 66.249.67.1 crawl-66-249-67-1.googlebot.com 66.249.67.1 66.249.67.2 crawl-66-249-67-2.googlebot.com 66.249.67.2 66.249.67.3 crawl-66-249-67-3.googlebot.com 66.249.67.3 66.249.67.4 crawl-66-249-67-4.googlebot.com 66.249.67.4 66.249.67.5 crawl-66-249-67-5.googlebot.com 66.249.67.5 66.249.67.6 crawl-66-249-67-6.googlebot.com 66.249.67.6 66.249.67.7 crawl-66-249-67-7.googlebot.com 66.249.67.7 66.249.67.8 crawl-66-249-67-8.googlebot.com 66.249.67.8 66.249.67.9 crawl-66-249-67-9.googlebot.com 66.249.67.9 66.249.67.10 crawl-66-249-67-10.googlebot.com 66.249.67.10 66.249.67.11 crawl-66-249-67-11.googlebot.com 66.249.67.11 66.249.67.12 crawl-66-249-67-12.googlebot.com 66.249.67.12 66.249.67.13 crawl-66-249-67-13.googlebot.com 66.249.67.13 66.249.67.14 crawl-66-249-67-14.googlebot.com 66.249.67.14 66.249.67.15 crawl-66-249-67-15.googlebot.com 66.249.67.15
I use a chunk of the Googlebot subnet as it's publicly available and I don't think Google would mind me hammering their rDNS too much in the name of getting things working. They probably deal with worse on a daily basis. I don't get into changing the second octet, because I don't really have forever to wait for my script to go through 65,535+ hosts, and that would almost certainly get me into trouble -- but the capability is there (or so I hope) in case someone really wants to play with it.
This thing is pretty good; you can pass it a single IP or a range (x.x.x.x-y.y.y.y) and it will cycle through the IP addresses in the range given, getting their hostnames and getting the IP address attached to the hostname (not always the same as the IP given to it!). But see, here's the thing: this is where my ambition grows and threatens to take over and deny me sleep tonight.
Because I want to add more.
I want to make the IPs you can pass to it capable of being comma-delimited; that is, you can pass a range and three individual IPs, or you can pass four ranges, an individual IP, and then another range. Basically I want to make this versatile as hell, so you only have to use it once from the command line and get all the information you want with regards to what it is.
Technically, it's as simple as throwing a split() function in there and iterating through the resultant array of that; applying my regex and routines to each member of that array, which results in the ability to query for a bunch of different machines at once, rather than just one range or just one machine.
The problem, of course, is that it's 1:50 AM (again... I planned on sleeping earlier but I'm a perfectionist), and I quite honestly don't have the time to pursue this further. Besides, it's complete enough for what I need to use it for, and that's the important bit, because now it's like, ten times easier to do the task I have to do. But that comes tomorrow. :)
However, for anyone who's interested in my ugly-ass Perl code, it's all behind the cut.
#!/usr/bin/perl
#
# Double-lookup -- takes an IP (or range), performs a reverse lookup, then performs a lookup
# on the result of the reverse, and outputs the results in a table.
#
use strict;
use warnings;
use Socket;
sub usage() {
print "Usage: $0 <IP/range>\n";
print "Reverse lookups an IP or range and lookups the result and outputs it all.\n\n";
}
if (scalar(@ARGV) < 1) { usage(); exit; }
my $fight = $ARGV[0];
my @octets = ($fight =~ /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3} )(?:\-(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.( \d{1,3}))?$/);
#if (scalar(@octets) < 4) {
# print "WARN: $fight seems to not have 4 but " . scalar(@octets) . " octets!\n";
#} else {
# my $start = "$octets[0].$octets[1].$octets[2].$octet s[3]";
# my $finish = "$octets[4].$octets[5].$octets[6].$octet s[7]" if (defined $octets[4]);
# if (defined $octets[4] && ($octets[0] > $octets[4] || $octets[1] > $octets[5] || $octets[2] > $octets[6] || $octets[3] > $octets[7])) {
# my $tmp = $start;
# $start = $finish;
# $finish = $tmp;
# }
# print "First set of octets is $start\n";
# print "Second set of octets is $finish\n" if (defined $octets[4]);
# print "(There is no second set of octets)\n" if (!defined $octets[4]);
# print "\nDEBUG: the above are the acquired octets and there appear to be " . scalar(@octets) . " of them.";
#}
sub lookup_one_ip($) {
my ($IP_lookup) = @_; # Slight TODO: update this to take IP ranges
# print "DBG:lookup_one_ip:look up $IP_lookup for me please\n";
my ($host) = gethostbyaddr(inet_aton($IP_lookup), AF_INET);
return ($IP_lookup, "N/A - couldn't lookup", "N/A") if (!defined $host);
my ($no,$no2,$no3,$no4,($backtrack)) = gethostbyname($host);
return ($IP_lookup, $host, "N/A - couldn't go back!") if (!defined $backtrack);
$backtrack = inet_ntoa($backtrack);
my @results = ($IP_lookup, $host, $backtrack);
# print "DBG:lookup_one_ip:returning $IP_lookup, $host, $backtrack for results\n";
return @results;
}
sub pick_bigger($) {
my ($one, $two) = @_;
return ($one > $two) ? $one : $two;
}
sub pick_smaller($) {
my ($one, $two) = @_;
return ($one < $two) ? $one : $two;
}
my @love = ();
if (defined $octets[4]) {
# operating in range mode
# print "WARN: operating in range mode\n";
my @start = ();
my @end = ();
if ($octets[0] > $octets[4] && $octets[1] > $octets[5] && $octets[2] > $octets[6] && $octets[3] > $octets[7]) {
# IP #1 is further along than IP #2
@start = ($octets[4], $octets[5], $octets[6], $octets[7]);
@end = ($octets[0], $octets[1], $octets[2], $octets[3]);
# print "PREFILTER: " . join('.', @start) . " later than " . join('.', @end) . "\n";
} else {
# IP 2 further than IP 1 (how things should be)
@start = ($octets[0], $octets[1], $octets[2], $octets[3]);
@end = ($octets[4], $octets[5], $octets[6], $octets[7]);
# print "PREFILTER: " . join('.', @start) . " earlier than " . join('.', @end) . "\n";
}
# Roll the numbers up, starting with the right and encasing them.
OCTET1: while ($start[0] <= 255) {
# print "BIGLOOP:octet1 at $start[1] w/ octet2 @ $start[2]\n";
OCTET2: while ($start[1] <= 255) {
# print "BIGLOOP:octet2 at $start[1] w/ octet3 @ $start[2]\n";
OCTET3: while ($start[2] <= 255) {
# print "BIGLOOP:octet3 at $start[2] w/ octet4 @ $start[3] to $end[3]\n";
OCTET4: while ($start[3] <= 255) {
# Lookup this IP
push(@love, [ lookup_one_ip("$start[0].$start[1].$star t[2].$start[3]") ]);
$start[3]++;
# print "BIGLOOP:octet4 at $start[3] to $end[3]\n";
last OCTET1 if ($start[3] > $end[3] && $start[2] >= $end[2] && $start[1] >= $end[1] && $start[0] >= $end[0]);
}
$start[3] = 1 if ($start[3] >= 255);
$start[2]++;
last OCTET1 if ($start[2] > $end[2] && $start[1] >= $end[1] && $start[0] >= $end[0]);
}
$start[2] = 1 if ($start[2] >= 255);
$start[1]++;
last OCTET1 if ($start[1] > $end[1] && $start[0] >= $end[0]);
}
$start[1] = 1 if ($start[1] >= 255);
$start[0]++;
last OCTET1 if ($start[0] > $end[0]);
}
} else {
# print "WARN: operating in singular mode\n";
# print "DBG: fight is $fight\n";
@love = [ lookup_one_ip($fight) ];
}
#print "\nTODO: add range support\n"; # Done
print "IP\t\tHostname\t\tBack to IP\n";
#print "$IP_lookup\t$host\t$backtrack\n";
#print "\n\n";
foreach my $ohlol (@love) {
my @thx = @$ohlol;
print "$thx[0]\t$thx[1]\t$thx[2]\n";
}
print "\n";
Caveat: the column formatting used in this script is fairly atrocious (although to be fair, the script itself ain't exactly aesthetic... or commented). The output won't be pretty, but it should be separated enough so that you can see all three columns distinctly and it won't be too hard transcribing it into something else, if need be.
Oh, it's also not commented and fairly messy. Watch your step.
So as Stan Lee might have used to say, farewell for now, true believers!