# Resolving Internet Addresses using Java

## Understanding how Internet addresses are formed and how to convert between symbolic names and IP Internet addresses and vice versa using Java

#### By

Summary: It is easier for us, humans, to remember symbolic names rather than a bunch of numbers, for example it is easier to memorize the string fundy.csd.unbsj.ca rather than 138.119.1.2. This article gives a brief introduction to Internet addressing and naming, then it shows how to translate symbolic names into Internet addresses and visa versa using Java. We conclude by implementing a utility that checks for the reachablity of a remote machine.

## Introduction to Internet Addressing/Naming

The Internet uses symbolic names for hostnames and networks, such as prep.ai.mit.edu or columbia.edu. These symbolic names are called domain names, and they are convenient for us, humans; however, these symbolic names have to be translated to Internet addresses (IP addresses, IP stands for Internet Protocol) before they can be used as communication identifiers. IP address are 32-bit numeric identifiers containing a network identifier and a host identifier that uniquely identify the network and a host on that particular network. The translation from symbolic names to IP identifiers is usually done by a name service. This service is known as the Domain Name System (DNS).

IP identifiers are used when a host is sending packets to other hosts on the same network or another network, or receiving packets from hosts on the same network or another network. If a host is sending packets to another host on the same network, only the host identifier is used to locate that host on the network. On the other hand, if a host is sending packets to a host on another network then both the host and network identifiers are used to locate that foreign host. The process of locating networks and hosts, and delivering packets to them is called routing. A router on a network contains an IP layer that implements a routing algorithm that moves packets to their destinations. It is the IP layer responsibility for moving packets from source to destination on the Internet. IP forwards each packet based on a four-byte destination address known as the IP number. Ranges (see below) of IP numbers are assigned by the Internet authorities, Network Information Center (NIC), to different organizations which in turn assign numbers to departments.

While data is being routed, the data can be lost in intermediate networks. Thus, it is the responsiblity of the underlying transmission protocol used to verify the correct delivery of data from source to destination. For example, TCP (Transfer Control Protocol) has support to detect errors or lost data and to re-transmit data until it is correctly received.

There are three classes of Internet addresses: A, B, and C. Also, there is another class known as "Multicast" which is implemented on some Internet hosts. These different classes of addresses meet the requirement of different organizations. For example, class A addresses are used for large networks that have more than 65,536 hosts. Class B addresses are used for intermediate size networks that have more than 255 but less than 65,536 hosts. Class C addresses are used for networks that have less than 256 hosts.

The decimal representation of the various classes of Internet Addresses is shown below:
Class A:

Network ID | Host ID

1 to 127 | 0 to 255 | 0 to 255 | 0 to 255

Class B:

Network ID | Host ID

128 to 191 | 0 to 255 | 0 to 255 | 0 to 255

Class C:

Network ID | Host ID

191 to 233 | 0 to 255 | 0 to 255 | 1 to 254

Multicast:

Multicast

234 to 255 | 0 to 255 | 0 to 255 | 1 to 254

The decimal numbers shown above represent the permissible range values for each class of addresses.

The numbers 0 and 255 have special meanings. The number 0 is reserved for machines that do not know their address. In certain cases (misconfiguration), it is possible for a machine not to know its own identifier or the identifier of the network it is running on. For example, a machine in class C with the number 0.0.0.42 would represent a machine that knew its number, 42, but didn't know the number of the network it is running on.

The number 255 is used for broadcasting. Broadcast is a message that when you send out you want it to be seen by every machine on the network.

Hopefully, the very brief introduction above has given you a basic understanding of Internet addresses and how they are constructed. Now, let's see how Java can help us in determining host name, IP addresses, and converting from symbolic names to IP addresses and vice versa.

Sometimes, you are interested in getting the IP address of the network you are running on, or some other hosts IP addresses. This can be done using the java.net.InetAddress class found in the java.net package. For example, if you want to get the IP address of the network you are running on then you would want to call the getLocalHost() and getAddress() methods of the class InetAddress in the package java.net. The method getLocalHost() returns an InetAddress object, and getAddress() returns a byte array of four bytes.

If you are writing a network-based application, you may need to know the symbolic name (hostname) or the IP address of the machine the application is going to run on. If you are running the application on your machine and you know the symbolic or IP address of your machine then you could hard-code the machine name, for example: String localHost = "machine-name"; however, if your application is going to run on different machines then having the localHost hard-coded is not a good idea. You would rather want your program to be able to figure out the hostname of the machine it is running on automatically. The following snippet of code shows an example of how you could find the symbolic name of the machine you are working on:

    /*
     *  Program: GetName.java
     *  @author: Qusay H. Mahmoud
     * @version: Oct 29, 1996
     */

    import java.net.*;

    public class GetName {
        public static void main(String argv[]) throws Exception {
            InetAddress host = null;
            host = InetAddress.getLocalHost();
            System.out.println(host.getHostName());
        }
    }

InetAddress is a class in the java.net package. In the above code, we are saying that host is of type InetAddress; the assignment host = InetAddress.getLocalHost() returns an InetAddress. for example if your machine name is "tucker" and its IP number is "138.119.1.10" then the variable, host, would have the value: "tucker/138.119.1.10". However, since we are interested in the symbolic name only then we can use the method getHostname() to print the machine name, tucker.

Internet addresses are in digit formats, they are normally called IP addresses. The above program returns the machine name (hostname). But, if you want to return the IP number, i.e. "138.119.1.10" then we could modify the above program so that it would return the IP number of the local host we are working on, as follows:

    /*
     *  Program: GetAddress.java
     *  @author: Qusay H. Mahmoud
     * @version: Oct 29, 1996
     */

    import java.net.*;

    public class GetAddress {
        public static void main(String argv[]) throws Exception {
            InetAddress host = null;
            host = InetAddress.getLocalHost();
            byte ip[] = host.getAddress();
            for (int i=0; i<ip.length; i++) {
    	   if (i > 0) System.out.print(".");
               System.out.print(ip[i] & 0xff);
            }
            System.out.println();
        }
    }

The method, getAddress() returns a byte array of four bytes. For example, if your IP address is: 138.119.1.10 then the byte array ip defined above would have the following values:

    ip[0] = 138
    ip[1] = 119
    ip[2] = 1
    ip[3] = 10

As mentioned above, all computers on the Internet have addresses. Each computer has a unique IP address and name that identifies it. Why do we need addresses anyway? Addresses are important since they help us identify location of persistence resources, as well as to support routing.

There is a huge number of names and IP addresses on the Internet, thus a name services is needed to map each name to an IP address. This service is what is known as DNS (Domain Name System). An example of a naming service (a sophisticated DNS client is the nslookup utility found on UNIX systems). Using nslookup, one can find the hostname for an IP address or the IP address for a hostname. It is a very useful utility nevertheless. Let's write a utility that will allow us to find the IP address for any accessible hostname on the Internet.

    /*
     *  Program: nslookup.java
     *  @author: Qusay H. Mahmoud
     * @version: Oct 29, 1996
     */

    import java.net.*;
    public class nslookup {
        // Usage: java nslookup hostname
        public static void main(String argv[]) throws Exception {
            String host = argv[0];
            InetAddress address = null;
            try {
              address = InetAddress.getByName(host);
            } catch(UnknownHostException e) {
                 System.out.println("Unknown host");
                 System.exit(0);
            }
            byte[] ip = address.getAddress();
            for (int i=0; i<ip.length; i++) {
    	   if(i > 0) System.out.print(".");
               System.out.print((ip[i]) & 0xff);
            }
            System.out.println();
        }
    }

Writing a utility to convert IP addresses to symbolic names was not an easy task in JDK1.0.2 due to a bug in the method getHostName() in the InetAddress class. However, this bug has been fixed in JDK1.1beta, so the following code should work on JDK1.1.

    /*
     *   Program: GetIP.java
     *   @author: Qusay H. Mahmoud
     *  @version: Nov 2, 1996 (doesn't work with JDK1.0.2
     * @modified: Dec 9, 1996 (works with JDK1.1beta
     */

    import java.net.*;
    public class GetIP {
        public static void main(String argv[]) throws Exception {
            String host = argv[0];
            InetAddress address = null;
            try {
              address = InetAddress.getByName(host);
            } catch (UnknownHostException e) {
                System.out.println("invalid IP - malformed IP");
                System.exit(0);
            }
            System.out.println(address.getHostName());
        }
    }

Up to now, we have given an introduction to Internet addresses and how to convert symbolic names into IP address and vice versa using Java. Now, let's write a utility that will allow us to test for the reachability of destinations on the Internet.

Ping (which stands for Packet InterNet Groper) is a program found on UNIX systems. The purpose of this program is to check for reachability of remote hosts by sending them an ICMP (Internet Control Message Protocol) echo request and waiting for a reply. The ICMP (Internet Control Message Protocol), which was initially designed to allow routers to report the cause of delivery errors, allows routers and hosts to send error or control messages to other routers and hosts.

Ping is implemented on UNIX systems by sending an ICMP echo request to a remote host and waiting for a reply; if the reply contains exactly the same data that was sent in the request then the remote host is reachable. On the other hand, if the router gateway can not deliver the echo request then it send an unreachable message (with an error code) back to the host. The error code can be one of the following integer values:

            Value                   What it means
            0                       Network Unreachable
            1                       Host Unreachable
            2                       Protocol Unreachable
            3                       Port Unreachable
            4                       Fragmentation Needed (fragment: dividing a datagram into packets)
            5                       Source Route Failed

Unfortunately, Java does not have support for ICMP packets. ICMP packets can be created via a socket with the SOCK_RAW type, but Java only supports SOCK_STREAM (TCP) and SOCK_DGRAM (UDP) sockets. Also, it is important to note that the ICMP protocol requires all programs using it to be run as root or be setuid to root; however, the TCP and UDP protocols do not require that special privilege.

All hope is not lost.....we still would like to develop a ping utility that will help us to test for the reachability of remote destinations. The utility can be developed using either the TCP or UDP protocol. If ping was to be developed using UDP then one could approach it by sending a packet to the remote host's echo port (port 7), and if echo reply contains the same data that was sent in the sending packet then the host is considered reachable. Note that UDP is not a reliable protocol, and thus the packet you send/receive may not be received/sent in the same order they were sent/received; however, one advantage of using UDP is that it is a connectionless protocol and thus it is unlike TCP where a connection must be opened and closed, i.e. there is no communication overhead when using UDP.

I prefer using TCP, so we will develop the ping program using the TCP protocol. Using TCP, the ping utility can be developed as follows: we attempt to establish a connection to the remote host's port number (again, port 7), if the connection is successfully established then the remote host is considered reachable. We then close the connection. Note that we do not need to send any data to the echo server!

    /*
     *  Program: ping.java
     *  @author: Qusay H. Mahmoud
     * @version: Nov 2, 1996
     */

    import java.io.*;
    import java.net.*;

    public class ping {
        public final static int ECHO_PORT = 7;
        public static void main(String argv[]) {
            if (argv.length != 1) {
              System.out.println("Usage: java ping hostname");
              System.exit(0);
            }
            if (alive(argv[0])) {
              System.out.println(argv[0] + " is alive");
            } else {
             System.out.println("No response from " + argv[0] +". Host is down or does not exist");
            }
        }

        public static boolean alive(String host) {
            Socket pingSocket = null;
            try {
                pingSocket = new Socket(host, ECHO_PORT);
            } catch (UnknownHostException e) {
                System.err.println("UnknownHostException: " +e);
            } catch (IOException io) {
                System.out.println("IOException: " + io);
            }
            if (pingSocket != null) {
               try {
                  pingSocket.close();
               } catch (IOException e) {
                    System.err.println("IOException: " + e);
               }
               return true;
            } else {
               return false;
            }
        }
    }

Conclusion:
Internet addresses, actually, refer to communication paths rather than computer names. They help TCP/IP applications to hide physical network details. Thus, the Internet appears as a single uniform virtual network. Each host on the Internet consists of a 32-bit Internet address that is used as a communication identifier.
Java provides, through the class java.net.InetAddress, a nice way to represent Internet addresses. The class has some useful methods that you can use in your network applications.

About the author:
Qusay H. Mahmoud is a graduate student in Computer Science at the University of New Brunswick, Saint John, Canada. This term he is teaching a course on Multimedia and the Information Highway at the university. As part of his thesis, he is developing a distributed computing system over the Web using Java. You can reach him at: k3is@fundy.csd.unbsj.ca

Resources:

- The java.net package in JDK1.1: http://www.javasoft.com:80/products/JDK/1.1/docs/api/Package-java.net.html
- Book: Internetworking with TCP/IP, Principles, Protocols, and Architecture. By Douglas Comer. Prentice Hall.

``
[Home] [Collection] [Tools] [Reference] [Events] [Language] [Links]

Java and all Java-based trademarks and logos are trademarks or registered
trademarks of Sun Microsystems, Inc. in the U.S. and other countries.
Copyright Notice: © 1996 Digital Cat,LLC

953 Industrial Ave., Suite 125 - Palo Alto, California 94303
Tel: 415.555.1212 - Fax: 415.555.1212
webmaster@javacats.com