Click Here!
home account info subscribe login search My ITKnowledge FAQ/help site map contact us


 
Brief Full
 Advanced
      Search
 Search Tips
To access the contents, click the chapter and section titles.

Perl CGl Programming: No experience required.
(Publisher: Sybex, Inc.)
Author(s): Erik Strom
ISBN: 0782121578
Publication Date: 11/01/97

Bookmark It

Search this book:
 
Previous Table of Contents Next


Resolving Internet Addresses with Perl

You’ve probably found yourself in situations where you had a domain name and needed to look up its address or vice versa. Here’s a Perl program that will allow you to resolve Internet addresses from the command line:

   #!/perl/bin/perl
   # lookup.pl
   # A little Internet domain name and IP address resolver.
   # To be run from the command line.

       $AF_INET = 2;        # Always this value.

   # Get name of address to resolve from the command line.

       $Address = $ARGV[0];

   # Treat the command line argument as an IP address by attempting
   # to turn whatever it is into a four-byte numeric value.

       @IP = split (/\./, $Address);
       $IPAddress = pack ("C4", @IP);

   # Try gethostbyaddr() first.

       ($name, $aliases, $type, $length, $addr)
           = gethostbyaddr ($IPAddress, $AF_INET);

   # If $name comes back blank, it's a good indication that
   # gethostbyaddr() failed. Try gethostbyname() with the
   # original command line argument.

       if ($name eq "")
           {
           ($name, $aliases, $type, $length, $addr)
               = gethostbyname ($Address);
           }

   # Turn the value in $addr into a string IP address.

       @Addrs = unpack ("C4", $addr);
       $StringIP = join (".", @Addrs);

   # If the name is still empty, or if gethostbyname() has returned
   # a name that is the same as the unpacked $addr, the lookup probably
   # failed. Otherwise, print the name and IP address.

       if (($name eq "") || ($name eq $StringIP))
           {
           print "Unable to resolve $Address\n";
           }
      else
           {
           print "$name\n";
           print "$StringIP\n";
           }

   #                    End lookup.pl

Save the script as lookup.pl and run it from the command line with either a domain name or an IP address as an argument. You’ll get back something similar to the display in Figure 12.7.


Figure 12.7:  Looking up names and addresses on the Internet

Dissecting the Lookup Script

Two of the Perl networking functions are the key to how lookup.pl works: gethostbyaddr and gethostbyname.

If they succeed, both of these functions return a list of information about the address you pass to them.

  name The primary domain name
  aliases Any aliases to the primary domain name
  address type An Internet protocol identification that is always equal to 2 in this application
  length The length in bytes of the IP address
  address A list of IP addresses in numeric form

The specification for gethostbyname looks like this:

   gethostbyname (ADDRESS);

where ADDRESS is a domain name. One more parameter goes to gethostbyaddr:

   gethostbyaddr (ADDRESS, TYPE);

where ADDRESS is a numeric IP address and TYPE is the same as address type.

The logic used in lookup.pl is that no domain name can be turned into a valid numeric IP address, so the first thing the program does is attempt to pack the command line argument into a four-byte number.

   @IP = split (/\./, $Address);
   $IPAddress = pack ("C4", @IP);

This code first uses split to break $Address up into pieces separated by periods. In the case of a human-readable IP address, this operation will yield four numbers. If $Address is a domain name, it’ll be broken up into as many strings as there are periods in the name; once pack is through with it, the chances are very good that it won’t even faintly resemble a valid Internet address.

Recall from Table 7.1 that the pack format C designates an unsigned character, which is a byte. We’re using C4 in lookup.pl, so pack will attempt to extract four bytes from the list in @IP and put them in $IPAddress. This operation will fail miserably if @IP contains a split-up domain name, but that’s good. The first Perl networking function called in the script is gethostbyaddr and we want the function to fail on a domain name so we can go on to get the proper information from gethostbyname.

The call to gethostbyaddr fills four variables if it succeeds in finding the address you’ve given it:

   ($name, $aliases, $type, $length, $addr)
       = gethostbyaddr ($IPAddress, $AF_INET);

These are the values that are explained in the list at the beginning of this section. However, if gethostbyaddr can’t resolve $IPAddress, $name will turn up empty, which is what the next conditional expression tests.

   if ($name eq "")
       {
      ($name, $aliases, $type, $length, $addr)
          = gethostbyname ($Address);
      }

See the assumption that is being made here? If the name comes back blank from gethostbyaddr, there must be a domain name on the command line, so try to resolve the address with gethostbyname.

What happens if both the name and address functions fail? If gethostbyaddr is given a valid IP address that simply doesn’t exist anywhere, the string IP address on the command line will be passed to gethostbyname, which will either fail completely or, in some versions of Perl, turn it into a numeric IP in $addr and place the string in $name. Either case is easy to find once $addr is turned into a string IP address:

   @Addrs = unpack ("C4", $addr);
   $StringIP = join (".", @Addrs);

   if (($name eq "") || ($name eq $StringIP))
       {
       print "Unable to resolve $Address\n";
       }
   else
       {
       print "$name\n";
       print "$StringIP\n";
       }


Previous Table of Contents Next


Products |  Contact Us |  About Us |  Privacy  |  Ad Info  |  Home

Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited.