Saturday, May 24, 2008

Simple Perl Script To Demonstrate DNS Lookups In Linux

Hey There,

This weekend post is somewhat of a look-back at a previous post on we did on simple IP and hostname resolution with Perl.

The script we're putting out today is only about half as good as some of the standard hostname/IP checkers out there, and it was specifically written only to accept hostnames and not IP's. If there's a request for it, we could write out the other half, but it's probably best to check out our Perl IP/hostname resolution post and do it for yourself. It's pretty much already written, you just have to reverse the logic (or invert it) somewhat ;)

This Perl script should run on any flavour of Linux, Unix and probably even Windows , assuming you have some sort of Cygwin or MKS *nix-on-Windows setup - or want to go through and manually edit the script to switch the backslashes to forward slashes, etc, so you can use ActivePerl for Windows - Note that, of these three options, only MKS isn't freeware, so if you're working on the cheap, stick with Cygwin or ActivePerl. No offense meant to MKS; it's a fine product but starts out at around 4 or 500 dollars to buy a single developer license.

The script only takes one argument of a hostname, like so:

host # ./double.pl www.google.com

The script is basically meant to reinforce Perl's basic network lookup functions that we went over a post or so ago, and provide a relatively lame means of double-checking a lookup to determine if it's bogus.

The skeleton of the script (logically) is this:

1. Lookup the IP of the hostname supplied.
2. Lookup the hostname using the IP we got in step 1.
3. Determine if the hostname's gotten in steps 1 and 2 match.
4. If they do, then we quit; assuming everything's okay.
5. If they don't match, we lookup the IP of the second hostname we received.
6. Lookup the IP of the second hostname (that we got in step 2)
7. Determine if the IP's (gotten in steps 1 and 6) match.
8. If they do, then we quit; assuming all is well.
9. If they don't, we still quit; we just complain about it ;)

This script should also aid in examining the opposite of a double-reverse-lookup (The double-reverse-lookup being IP to Name to IP mapping, with this being Name to IP to Name mapping). Some sites use Double Reverse Lookups as a security measure, but whether or not the process protects anything at all, or is just a waste of resources, is debatable. Just do a search for it online and you'll be inundated with polemic for as long as you can stand to read.

For our purposes, this is just another way to learn more about how things work with Perl's networking functions and how you can better work with them :)

This is what you can expect to see from this script (approximately):

host # ./double.pl www.google.com

Hostname: www.google.com = IP: 64.233.167.99

IP: 64.233.167.99 = Hostname: py-in-f99.google.com

www.google.com and py-in-f99.google.com Do Not Match
Checking Reverse...

64.233.167.99 and 64.233.167.99 match
Everything is probably ok!


Here's hoping this helps you out, and best of luck if you decide to write the opposite (which would be the "real" Double Reverse Lookup :)

Cheers,


Creative Commons License


This work is licensed under a
Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License

#!/usr/bin/perl

#
# double.pl - Double Check That Hostnames Match The IP's They're Advertising
#
# 2008 - Mike Golvach - eggi@comcast.net
#
# Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License
#

use Socket;

if ( $#ARGV != 0 ) {
print "Usage: $0 hostname\n";
exit(1);
}

$entry = $ARGV[0];

$hostname1 = $entry;
$ip1 = gethostbyname($hostname1) || die "error - gethostbyname: $!\n\n";
$hostip1 = inet_ntoa($ip1) || die "error - inet_ntoa: $!\n\n";
print "\nHostname: $hostname1 = IP: $hostip1\n\n";
$hostname2 = gethostbyaddr(inet_aton($hostip1),AF_INET) || die "error - inet_aton: $!\n\n";
print "IP: $hostip1 = Hostname: $hostname2\n\n";
if ( $hostname1 eq $hostname2 ) {
print "$hostname1 and $hostname2 Match!\n";
print "Good Deal!\n\n";
exit(0);
} else {
print "$hostname1 and $hostname2 Do Not Match\n";
print "Checking Reverse...\n\n";
$ip2 = gethostbyname($hostname2) || die "error - gethostbyname: $!\n\n";
$hostip2 = inet_ntoa($ip2) || die "error - inet_ntoa: $!\n\n";
if ( $hostip1 eq $hostip2 ) {
print "$hostip1 and $hostip2 match\n";
print "Everything is probably ok!\n\n";
exit(0);
} else {
print "$hostip1 and $hostip2 don't match\n";
print "This DNS may be bogus or setup incorrectly!\n\n";
exit(0);
}
}


, Mike