001    /* InetAddress.java -- Class to model an Internet address
002       Copyright (C) 1998, 1999, 2002, 2004, 2005, 2006
003       Free Software Foundation, Inc.
004    
005    This file is part of GNU Classpath.
006    
007    GNU Classpath is free software; you can redistribute it and/or modify
008    it under the terms of the GNU General Public License as published by
009    the Free Software Foundation; either version 2, or (at your option)
010    any later version.
011    
012    GNU Classpath is distributed in the hope that it will be useful, but
013    WITHOUT ANY WARRANTY; without even the implied warranty of
014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015    General Public License for more details.
016    
017    You should have received a copy of the GNU General Public License
018    along with GNU Classpath; see the file COPYING.  If not, write to the
019    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
020    02110-1301 USA.
021    
022    Linking this library statically or dynamically with other modules is
023    making a combined work based on this library.  Thus, the terms and
024    conditions of the GNU General Public License cover the whole
025    combination.
026    
027    As a special exception, the copyright holders of this library give you
028    permission to link this library with independent modules to produce an
029    executable, regardless of the license terms of these independent
030    modules, and to copy and distribute the resulting executable under
031    terms of your choice, provided that you also meet, for each linked
032    independent module, the terms and conditions of the license of that
033    module.  An independent module is a module which is not derived from
034    or based on this library.  If you modify this library, you may extend
035    this exception to your version of the library, but you are not
036    obligated to do so.  If you do not wish to do so, delete this
037    exception statement from your version. */
038    
039    
040    package java.net;
041    
042    import java.io.IOException;
043    import java.io.ObjectInputStream;
044    import java.io.ObjectOutputStream;
045    import java.io.ObjectStreamException;
046    import java.io.Serializable;
047    
048    /**
049     * This class models an Internet address.  It does not have a public
050     * constructor.  Instead, new instances of this objects are created
051     * using the static methods getLocalHost(), getByName(), and
052     * getAllByName().
053     *
054     * <p>This class fulfills the function of the C style functions gethostname(),
055     * gethostbyname(), and gethostbyaddr().  It resolves Internet DNS names
056     * into their corresponding numeric addresses and vice versa.</p>
057     *
058     * @author Aaron M. Renn (arenn@urbanophile.com)
059     * @author Per Bothner
060     * @author Gary Benson (gbenson@redhat.com)
061     *
062     * @specnote This class is not final since JDK 1.4
063     */
064    public class InetAddress implements Serializable
065    {
066      private static final long serialVersionUID = 3286316764910316507L;
067    
068      /**
069       * Dummy InetAddress, used to bind socket to any (all) network interfaces.
070       */
071      static InetAddress ANY_IF;
072      static
073      {
074        byte[] addr;
075        try
076          {
077            addr = VMInetAddress.lookupInaddrAny();
078          }
079        catch (UnknownHostException e)
080          {
081            // Make one up and hope it works.
082            addr = new byte[] {0, 0, 0, 0};
083          }
084        try
085          {
086            ANY_IF = getByAddress(addr);
087          }
088        catch (UnknownHostException e)
089          {
090            throw (InternalError) new InternalError().initCause(e);
091          }
092        ANY_IF.hostName = ANY_IF.getHostName();
093      }
094    
095      /**
096       * Stores static localhost address object.
097       */
098      static InetAddress LOCALHOST;
099      static
100      {
101        try
102          {
103            LOCALHOST = getByAddress("localhost", new byte[] {127, 0, 0, 1});
104          }
105        catch (UnknownHostException e)
106          {
107            throw (InternalError) new InternalError().initCause(e);
108          }
109      }
110    
111      /**
112       * The Serialized Form specifies that an int 'address' is saved/restored.
113       * This class uses a byte array internally so we'll just do the conversion
114       * at serialization time and leave the rest of the algorithm as is.
115       */
116      private int address;
117    
118      /**
119       * An array of octets representing an IP address.
120       */
121      transient byte[] addr;
122    
123      /**
124       * The name of the host for this address.
125       */
126      String hostName;
127    
128      /**
129       * Needed for serialization.
130       */
131      private int family;
132    
133      /**
134       * Constructor.  Prior to the introduction of IPv6 support in 1.4,
135       * methods such as InetAddress.getByName() would return InetAddress
136       * objects.  From 1.4 such methods returned either Inet4Address or
137       * Inet6Address objects, but for compatibility Inet4Address objects
138       * are serialized as InetAddresses.  As such, there are only two
139       * places where it is appropriate to invoke this constructor: within
140       * subclasses constructors and within Inet4Address.writeReplace().
141       *
142       * @param ipaddr The IP number of this address as an array of bytes
143       * @param hostname The hostname of this IP address.
144       * @param family The address family of this IP address.
145       */
146      InetAddress(byte[] ipaddr, String hostname, int family)
147      {
148        addr = (null == ipaddr) ? null : (byte[]) ipaddr.clone();
149        hostName = hostname;
150        this.family = family;
151      }
152    
153      /**
154       * Returns true if this address is a multicast address, false otherwise.
155       * An address is multicast if the high four bits are "1110".  These are
156       * also known as "Class D" addresses.
157       *
158       * <p>This method cannot be abstract for backward compatibility reasons. By
159       * default it always throws {@link UnsupportedOperationException} unless
160       * overridden.</p>
161       *
162       * @return true if mulitcast, false if not
163       *
164       * @since 1.1
165       */
166      public boolean isMulticastAddress()
167      {
168        throw new UnsupportedOperationException();
169      }
170    
171      /**
172       * Utility routine to check if the InetAddress in a wildcard address
173       *
174       * <p>This method cannot be abstract for backward compatibility reasons. By
175       * default it always throws {@link UnsupportedOperationException} unless
176       * overridden.</p>
177       *
178       * @since 1.4
179       */
180      public boolean isAnyLocalAddress()
181      {
182        throw new UnsupportedOperationException();
183      }
184    
185      /**
186       * Utility routine to check if the InetAddress is a loopback address
187       *
188       * <p>This method cannot be abstract for backward compatibility reasons. By
189       * default it always throws {@link UnsupportedOperationException} unless
190       * overridden.</p>
191       *
192       * @since 1.4
193       */
194      public boolean isLoopbackAddress()
195      {
196        throw new UnsupportedOperationException();
197      }
198    
199      /**
200       * Utility routine to check if InetAddress is a link local address
201       *
202       * <p>This method cannot be abstract for backward compatibility reasons. By
203       * default it always throws {@link UnsupportedOperationException} unless
204       * overridden.</p>
205       *
206       * @since 1.4
207       */
208      public boolean isLinkLocalAddress()
209      {
210        throw new UnsupportedOperationException();
211      }
212    
213      /**
214       * Utility routine to check if InetAddress is a site local address
215       *
216       * <p>This method cannot be abstract for backward compatibility reasons. By
217       * default it always throws {@link UnsupportedOperationException} unless
218       * overridden.</p>
219       *
220       * @since 1.4
221       */
222      public boolean isSiteLocalAddress()
223      {
224        throw new UnsupportedOperationException();
225      }
226    
227      /**
228       * Utility routine to check if InetAddress is a global multicast address
229       *
230       * <p>This method cannot be abstract for backward compatibility reasons. By
231       * default it always throws {@link UnsupportedOperationException} unless
232       * overridden.</p>
233       *
234       * @since 1.4
235       */
236      public boolean isMCGlobal()
237      {
238        throw new UnsupportedOperationException();
239      }
240    
241      /**
242       * Utility routine to check if InetAddress is a node local multicast address.
243       *
244       * <p>This method cannot be abstract for backward compatibility reasons. By
245       * default it always throws {@link UnsupportedOperationException} unless
246       * overridden.</p>
247       *
248       * @since 1.4
249       */
250      public boolean isMCNodeLocal()
251      {
252        throw new UnsupportedOperationException();
253      }
254    
255      /**
256       * Utility routine to check if InetAddress is a link local multicast address.
257       *
258       * <p>This method cannot be abstract for backward compatibility reasons. By
259       * default it always throws {@link UnsupportedOperationException} unless
260       * overridden.</p>
261       *
262       * @since 1.4
263       */
264      public boolean isMCLinkLocal()
265      {
266        throw new UnsupportedOperationException();
267      }
268    
269      /**
270       * Utility routine to check if InetAddress is a site local multicast address.
271       *
272       * <p>This method cannot be abstract for backward compatibility reasons. By
273       * default it always throws {@link UnsupportedOperationException} unless
274       * overridden.</p>
275       *
276       * @since 1.4
277       */
278      public boolean isMCSiteLocal()
279      {
280        throw new UnsupportedOperationException();
281      }
282    
283      /**
284       * Utility routine to check if InetAddress is a organization local
285       * multicast address.
286       *
287       * <p>This method cannot be abstract for backward compatibility reasons. By
288       * default it always throws {@link UnsupportedOperationException} unless
289       * overridden.</p>
290       *
291       * @since 1.4
292       */
293      public boolean isMCOrgLocal()
294      {
295        throw new UnsupportedOperationException();
296      }
297    
298      /**
299       * Returns the hostname for this address.  This will return the IP address
300       * as a String if there is no hostname available for this address
301       *
302       * @return The hostname for this address
303       */
304      public String getHostName()
305      {
306        if (hostName == null)
307          hostName = getCanonicalHostName();
308    
309        return hostName;
310      }
311    
312      /**
313       * Returns the canonical hostname represented by this InetAddress
314       */
315      String internalGetCanonicalHostName()
316      {
317        try
318          {
319            return ResolverCache.getHostByAddr(addr);
320          }
321        catch (UnknownHostException e)
322          {
323            return getHostAddress();
324          }
325      }
326    
327      /**
328       * Returns the canonical hostname represented by this InetAddress
329       *
330       * @since 1.4
331       */
332      public String getCanonicalHostName()
333      {
334        String hostname = internalGetCanonicalHostName();
335    
336        SecurityManager sm = System.getSecurityManager();
337        if (sm != null)
338          {
339            try
340              {
341                sm.checkConnect(hostname, -1);
342              }
343            catch (SecurityException e)
344              {
345                return getHostAddress();
346              }
347          }
348    
349        return hostname;
350      }
351    
352      /**
353       * Returns the IP address of this object as a byte array.
354       *
355       * @return IP address
356       */
357      public byte[] getAddress()
358      {
359        // An experiment shows that JDK1.2 returns a different byte array each
360        // time.  This makes sense, in terms of security.
361        return (byte[]) addr.clone();
362      }
363    
364      /**
365       * Returns the IP address of this object as a String.
366       *
367       * <p>This method cannot be abstract for backward compatibility reasons. By
368       * default it always throws {@link UnsupportedOperationException} unless
369       * overridden.</p>
370       *
371       * @return The IP address of this object in String form
372       *
373       * @since 1.0.2
374       */
375      public String getHostAddress()
376      {
377        throw new UnsupportedOperationException();
378      }
379    
380      /**
381       * Returns a hash value for this address.  Useful for creating hash
382       * tables.  Overrides Object.hashCode()
383       *
384       * @return A hash value for this address.
385       */
386      public int hashCode()
387      {
388        // There hashing algorithm is not specified, but a simple experiment
389        // shows that it is equal to the address, as a 32-bit big-endian integer.
390        int hash = 0;
391        int len = addr.length;
392        int i = len > 4 ? len - 4 : 0;
393    
394        for (; i < len; i++)
395          hash = (hash << 8) | (addr[i] & 0xff);
396    
397        return hash;
398      }
399    
400      /**
401       * Tests this address for equality against another InetAddress.  The two
402       * addresses are considered equal if they contain the exact same octets.
403       * This implementation overrides Object.equals()
404       *
405       * @param obj The address to test for equality
406       *
407       * @return true if the passed in object's address is equal to this one's,
408       * false otherwise
409       */
410      public boolean equals(Object obj)
411      {
412        if (! (obj instanceof InetAddress))
413          return false;
414    
415        // "The Java Class Libraries" 2nd edition says "If a machine has
416        // multiple names instances of InetAddress for different name of
417        // that same machine are not equal.  This is because they have
418        // different host names."  This violates the description in the
419        // JDK 1.2 API documentation.  A little experimentation
420        // shows that the latter is correct.
421        byte[] addr2 = ((InetAddress) obj).addr;
422    
423        if (addr.length != addr2.length)
424          return false;
425    
426        for (int i = 0; i < addr.length; i++)
427          if (addr[i] != addr2[i])
428            return false;
429    
430        return true;
431      }
432    
433      /**
434       * Converts this address to a String.  This string contains the IP in
435       * dotted decimal form. For example: "127.0.0.1"  This method is equivalent
436       * to getHostAddress() and overrides Object.toString()
437       *
438       * @return This address in String form
439       */
440      public String toString()
441      {
442        String addr = getHostAddress();
443        String host = (hostName != null) ? hostName : "";
444        return host + "/" + addr;
445      }
446    
447      /**
448       * Returns an InetAddress object given the raw IP address.
449       *
450       * The argument is in network byte order: the highest order byte of the
451       * address is in getAddress()[0].
452       *
453       * @param addr The IP address to create the InetAddress object from
454       *
455       * @exception UnknownHostException If IP address has illegal length
456       *
457       * @since 1.4
458       */
459      public static InetAddress getByAddress(byte[] addr)
460        throws UnknownHostException
461      {
462        return getByAddress(null, addr);
463      }
464    
465      /**
466       * Creates an InetAddress based on the provided host name and IP address.
467       * No name service is checked for the validity of the address.
468       *
469       * @param host The hostname of the InetAddress object to create
470       * @param addr The IP address to create the InetAddress object from
471       *
472       * @exception UnknownHostException If IP address is of illegal length
473       *
474       * @since 1.4
475       */
476      public static InetAddress getByAddress(String host, byte[] addr)
477        throws UnknownHostException
478      {
479        if (addr.length == 4)
480          return new Inet4Address(addr, host);
481    
482        if (addr.length == 16)
483          {
484            for (int i = 0; i < 12; i++)
485              {
486                if (addr[i] != (i < 10 ? 0 : (byte) 0xFF))
487                  return new Inet6Address(addr, host);
488              }
489    
490            byte[] ip4addr = new byte[4];
491            ip4addr[0] = addr[12];
492            ip4addr[1] = addr[13];
493            ip4addr[2] = addr[14];
494            ip4addr[3] = addr[15];
495            return new Inet4Address(ip4addr, host);
496          }
497    
498        throw new UnknownHostException("IP address has illegal length");
499      }
500    
501      /**
502       * Returns an InetAddress object representing the IP address of
503       * the given literal IP address in dotted decimal format such as
504       * "127.0.0.1".  This is used by SocketPermission.setHostPort()
505       * to parse literal IP addresses without performing a DNS lookup.
506       *
507       * @param literal The literal IP address to create the InetAddress
508       * object from
509       *
510       * @return The address of the host as an InetAddress object, or
511       * null if the IP address is invalid.
512       */
513      static InetAddress getByLiteral(String literal)
514      {
515        byte[] address = VMInetAddress.aton(literal);
516        if (address == null)
517          return null;
518    
519        try
520          {
521            return getByAddress(address);
522          }
523        catch (UnknownHostException e)
524          {
525            throw (InternalError) new InternalError().initCause(e);
526          }
527      }
528    
529      /**
530       * Returns an InetAddress object representing the IP address of the given
531       * hostname.  This name can be either a hostname such as "www.urbanophile.com"
532       * or an IP address in dotted decimal format such as "127.0.0.1".  If the
533       * hostname is null or "", the hostname of the local machine is supplied by
534       * default.  This method is equivalent to returning the first element in
535       * the InetAddress array returned from GetAllByName.
536       *
537       * @param hostname The name of the desired host, or null for the local
538       * loopback address.
539       *
540       * @return The address of the host as an InetAddress object.
541       *
542       * @exception UnknownHostException If no IP address for the host could
543       * be found
544       * @exception SecurityException If a security manager exists and its
545       * checkConnect method doesn't allow the operation
546       */
547      public static InetAddress getByName(String hostname)
548        throws UnknownHostException
549      {
550        InetAddress[] addresses = getAllByName(hostname);
551        return addresses[0];
552      }
553    
554      /**
555       * Returns an array of InetAddress objects representing all the host/ip
556       * addresses of a given host, given the host's name.  This name can be
557       * either a hostname such as "www.urbanophile.com" or an IP address in
558       * dotted decimal format such as "127.0.0.1".  If the value is null, the
559       * hostname of the local machine is supplied by default.
560       *
561       * @param hostname The name of the desired host, or null for the
562       * local loopback address.
563       *
564       * @return All addresses of the host as an array of InetAddress objects.
565       *
566       * @exception UnknownHostException If no IP address for the host could
567       * be found
568       * @exception SecurityException If a security manager exists and its
569       * checkConnect method doesn't allow the operation
570       */
571      public static InetAddress[] getAllByName(String hostname)
572        throws UnknownHostException
573      {
574        // If null or the empty string is supplied, the loopback address
575        // is returned.
576        if (hostname == null || hostname.length() == 0)
577          return new InetAddress[] {LOCALHOST};
578    
579        // Check if hostname is an IP address
580        InetAddress address = getByLiteral(hostname);
581        if (address != null)
582          return new InetAddress[] {address};
583    
584        // Perform security check before resolving
585        SecurityManager sm = System.getSecurityManager();
586        if (sm != null)
587          sm.checkConnect(hostname, -1);
588    
589        // Resolve the hostname
590        byte[][] iplist = ResolverCache.getHostByName(hostname);
591        if (iplist.length == 0)
592          throw new UnknownHostException(hostname);
593    
594        InetAddress[] addresses = new InetAddress[iplist.length];
595        for (int i = 0; i < iplist.length; i++)
596          addresses[i] = getByAddress(hostname, iplist[i]);
597    
598        return addresses;
599      }
600    
601      /**
602       * Returns an InetAddress object representing the address of the current
603       * host.
604       *
605       * @return The local host's address
606       *
607       * @exception UnknownHostException If no IP address for the host could
608       * be found
609       */
610      public static InetAddress getLocalHost() throws UnknownHostException
611      {
612        String hostname = VMInetAddress.getLocalHostname();
613        try
614          {
615            return getByName(hostname);
616          }
617        catch (SecurityException e)
618          {
619            return LOCALHOST;
620          }
621      }
622    
623      /**
624       * Inet4Address objects are serialized as InetAddress objects.
625       * This deserializes them back into Inet4Address objects.
626       */
627      private Object readResolve() throws ObjectStreamException
628      {
629        return new Inet4Address(addr, hostName);
630      }
631    
632      private void readObject(ObjectInputStream ois)
633        throws IOException, ClassNotFoundException
634      {
635        ois.defaultReadObject();
636        addr = new byte[4];
637        addr[3] = (byte) address;
638    
639        for (int i = 2; i >= 0; --i)
640          addr[i] = (byte) (address >>= 8);
641      }
642    
643      private void writeObject(ObjectOutputStream oos) throws IOException
644      {
645        // Build a 32 bit address from the last 4 bytes of a 4 byte IPv4 address
646        // or a 16 byte IPv6 address.
647        int len = addr.length;
648        int i = len - 4;
649    
650        for (; i < len; i++)
651          address = address << 8 | (addr[i] & 0xff);
652    
653        oos.defaultWriteObject();
654      }
655    }