Network Names and Services


 
Network Programming with Perl
By Lincoln  D.  Stein
Slots : 1
Table of Contents
Chapter  3.   Introduction to Berkeley Sockets

    Content

Network Names and Services

The example in the last section used the remote host's dotted -quad IP address and numeric port and protocol numbers to construct the socket. Usually, however, you'll want to use symbolic names instead of numbers . Not only does this make it easier to write the program, but it makes it easier for end users to use it, allowing them to enter the host address as wuarchive.wustl.edu rather than 128.252.120.8.

The domain name system (DNS) is an Internet-wide database that translates hostnames into dotted IP addresses and back again. Various local database services translate from service names into numbers. This section introduces the functions that allow you to translate names into numbers, and vice versa.

Translating Hostnames into IP Addresses

Perl's gethostbyname() and gethostbyaddr() functions translate a symbolic hostname into a packed IP address, and vice versa. They are front ends to system library calls of the same name. Depending on your system's name-resolution setup, the call will consult one or more static text files such as /etc/ hosts , local area network databases such as NIS, or the Internet-wide DNS.

($name,$aliases,$type,$len,$packed_addr) = gethostbyname($name);

$packed_addr = gethostbyname($name);

If the hostname doesn't exist, gethostbyname() returns undef . Otherwise, in a scalar context it returns the IP address of the host in packed binary form, while in a list context it returns a five-element list.

The first element, $name , is the canonical hostname ”the official name ”for the requested host. This is followed by a list of hostname aliases, the address type and address length, usually AF_INET and 4, and the address itself in packed form. The aliases field is a space-delimited list of alternative names for the host. If there are no alternative names, the list is empty.

You can pass the packed address returned by gethostbyname() directly to the socket functions, or translate it back a human-readable dotted-quad form using inet_ntoa() . If you pass gethostbyname() a dotted-quad IP address, it will detect that fact and return the packed version of the address, just as inet_aton() does.

$name = gethostbyaddr($packed_addr,$family);

($name,$aliases,$type,$len,$packed_addr) = gethostbyaddr($packed_addr, $family);

The gethostbyaddr() call performs the reverse lookup, taking a packed IP address and returning the hostname corresponding to it.

gethostbyaddr() takes two arguments, the packed address and the address family (usually AF_INET ). In a scalar context, it returns the hostname of the indicated address. In a list context, it returns a five-element list consisting of the canonical hostname, a list of aliases, the address type, address length, and packed address. This is the same list returned by gethostbyname(literal) .

If the call is unsuccessful in looking up the address, it returns undef or an empty list.

The inet_aton() function can also translate hostnames into packed IP addresses. In general, you can replace scalar context calls to gethostbyname() with calls to inet_aton() :

 $packed_address = inet_aton($host); $packed_address = gethostbyname($host); 

Which of these two functions you use is a matter of taste, but be aware that gethostbyname() is built into Perl, but inet_aton() is available only after you load the socket module. I prefer inet_aton() because, unlike gethostbyname() , it isn't sensitive to list context.

Hostname Translation Examples

Using these functions, we can write a simple program to translate a list of hostnames into dotted-quad IP addresses (Figure 3.5). Given a file of hostnames stored in hostnames.txt, the script's output looks like this:

Figure 3.5. Translating hostnames into IP addresses

graphics/03fig05.gif

 % ip_trans.pl < hostnames.txt pesto.cshl.org => 143.48.7.220 w3.org => 18.23.0.20 foo.bar.com => ? ntp.css.gov => 140.162.3 

Figure 3.6 shows a short program for performing the reverse operation, translating a list of dotted-quad IP addresses into hostnames. For each line of input, the program checks that it looks like a valid IP address (line 6) and, if so, packs the address using inet_aton(). The packed address is then passed to gethostbyaddr(), specifying AF_INET for the address family (line 7). If successful, the translated hostname is printed out.

Figure 3.6. Translating IP addresses into hostnames

graphics/03fig06.gif

Getting Information about Protocols and Services

In the same way that gethostbyname() and gethostbyaddr() interconvert hostnames and IP addresses, Perl provides functions to translate the symbolic names of protocols and services into protocol and port numbers.

$number = getprotobyname ($protocol)

($name,$aliases,$number) = getprotobyname($protocol)

getprotobyname() takes a symbolic protocol name, such as "udp", and converts it into its corresponding numeric value. In a scalar context, just the protocol number is returned. In a list context, the function returns the protocol name, a list of aliases, and the number. Multiple aliases are separated by spaces. If the named protocol is unknown, the function returns undef or an empty list.

$name = getprotobynumber($protocol_number)

($name,$aliases,$number) = getprotobyname($protocol_number)

The rarely used getprotobynumber() function reverses the previous operation, translating a protocol number into a protocol name. In a scalar context, it returns the protocol number's name as a string. In a list context, it returns the same list as getprotobyname() . If passed an invalid protocol number, this function returns undef or an empty list.

$port = getservbyname($service,$protocol)

($name,$aliases,$port,$protocol) = getservbyname($service,$protocol)

The getservbyname() function converts a symbolic service name, such as "echo," into a port number suitable for passing to sockaddr_in() . The function takes two arguments corresponding to the service name and the desired protocol. The reason for the additional protocol argument is that some services, echo included, come in both UDP and TCP versions, and there's no guarantee that the two versions of the service use the same port number, although this is almost always the case.

In a scalar context, getservbyname() returns the port number of the service, or undef if unknown. In a list context, the function returns a four-element list consisting of the canonical name for the service, a space-delimited list of aliases, if any, the port number, and the protocol number. If the service is unknown, the function returns an empty list.

$name = getservbyport ($port,$protocol)

($name,$aliases,$port,$protocol) = getservbyport($port,$protocol)

The getservbyport() function reverses the previous operation by translating a port number into the corresponding service name. Its behavior in scalar and list contexts is exactly the same as getservbyname() .

Daytime Client, Revisited

We now have the tools to eliminate the hard-coded port and protocol numbers from the daytime client that we developed earlier. In addition, we can make the program more user friendly by accepting the name of the daytime host as either a DNS name or a dotted-IP address. Figure 3.7 gives the code for the revised client. The differences from the earlier version are as follows :

Figure 3.7. Daytime client, using symbolic hostnames and service names

graphics/03fig07.gif

Line 5: Look up IP address of the daytime host We call gethostbyname() to translate the hostname given on the command line into a packed IP address. If no command-line argument is given, we default to using the loopback address. If the user provided a dotted-IP address instead of a hostname, then gethostbyname() simply packs it in the manner of inet_aton() . If gethostbyname() fails because the provided hostname is invalid, it returns undef and we exit with an error message.

Line 6: Look up the TCP protocol number We call getprotobyname() to retrieve the value of the TCP protocol number, rather than hard coding it as before.

Line 7: Look up the daytime service port number Instead of hard coding the port number for the daytime service, we call getservbyname() to look it up in the system service database. If for some reason this doesn't work, we exit with an error message.

Lines 8 “11: Connect and read data The remainder of the program is as before, with the exception that we use the TCP protocol number retrieved from getprotobyname() in the call to socket() .

You can test the script on the host http://www.modperl.com/

Other Sources of Network Information

In addition to gethostbyname() and its brethren, specialized add-on modules offer direct access to a number of other common databases of network information. I won't cover them in detail here, but you should know that they exist if you need them. All the modules can be obtained from CPAN.

Net::DNS

This module offers you much greater control over how hostnames are resolved using the domain name system. In addition to the functionality offered by gethostbyname() and gethostbyaddr() , Net::DNS allows you to fetch and iterate over all hosts in a domain; get the e-mail address of the network administrator responsible for the domain; and look up the machine responsible for accepting e-mail for a domain (the "mail exchanger ," or MX).

Net::NIS

Many traditional UNIX networks use Sun's Network Information System (NIS) to distribute such things as hostnames, IP addresses, usernames, passwords, automount tables, and cryptographic keys. This allows a user to have the same login username, password, and home directories on all the machines on the network. Perl's built-in network information access functions, such as gethostbyname() and getpwnam() , provide transparent access to much, but not all, of NIS's functionality. The Net::NIS module provides access to more esoteric information, such as automount tables.

Net::LDAP

NIS is slowly being displaced by the Lightweight Directory Access Protocol (LDAP), which provides greater flexibility and scalability. In addition to the types of information stored by NIS, LDAP is often used to store users' e-mail addresses, telephone numbers, and other "white pages" “type information. Net::LDAP gives you access to these databases.

Win32::NetResource

On Windows networks, the NT domain controller provides directory information on hosts, printers, shared file systems, and other network information. Win32::NetResources provides functions for reading and writing this information.


   
Top


Network Programming with Perl
Network Programming with Perl
ISBN: 0201615711
EAN: 2147483647
Year: 2000
Pages: 173

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net