OSDN Git Service

2006-09-20 Gary Benson <gbenson@redhat.com>
[pf3gnuchains/gcc-fork.git] / libjava / classpath / java / net / InetAddress.java
1 /* InetAddress.java -- Class to model an Internet address
2    Copyright (C) 1998, 1999, 2002, 2004, 2005, 2006
3    Free Software Foundation, Inc.
4
5 This file is part of GNU Classpath.
6
7 GNU Classpath is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU Classpath is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU Classpath; see the file COPYING.  If not, write to the
19 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301 USA.
21
22 Linking this library statically or dynamically with other modules is
23 making a combined work based on this library.  Thus, the terms and
24 conditions of the GNU General Public License cover the whole
25 combination.
26
27 As a special exception, the copyright holders of this library give you
28 permission to link this library with independent modules to produce an
29 executable, regardless of the license terms of these independent
30 modules, and to copy and distribute the resulting executable under
31 terms of your choice, provided that you also meet, for each linked
32 independent module, the terms and conditions of the license of that
33 module.  An independent module is a module which is not derived from
34 or based on this library.  If you modify this library, you may extend
35 this exception to your version of the library, but you are not
36 obligated to do so.  If you do not wish to do so, delete this
37 exception statement from your version. */
38
39
40 package java.net;
41
42 import java.io.IOException;
43 import java.io.ObjectInputStream;
44 import java.io.ObjectOutputStream;
45 import java.io.ObjectStreamException;
46 import java.io.Serializable;
47
48 /**
49  * This class models an Internet address.  It does not have a public
50  * constructor.  Instead, new instances of this objects are created
51  * using the static methods getLocalHost(), getByName(), and
52  * getAllByName().
53  *
54  * <p>This class fulfills the function of the C style functions gethostname(),
55  * gethostbyname(), and gethostbyaddr().  It resolves Internet DNS names
56  * into their corresponding numeric addresses and vice versa.</p>
57  *
58  * @author Aaron M. Renn (arenn@urbanophile.com)
59  * @author Per Bothner
60  * @author Gary Benson (gbenson@redhat.com)
61  *
62  * @specnote This class is not final since JK 1.4
63  */
64 public class InetAddress implements Serializable
65 {
66   private static final long serialVersionUID = 3286316764910316507L;
67
68   /**
69    * Dummy InetAddress, used to bind socket to any (all) network interfaces.
70    */
71   static InetAddress ANY_IF;
72   static
73   {
74     byte[] addr;
75     try
76       {
77         addr = VMInetAddress.lookupInaddrAny();
78       }
79     catch (UnknownHostException e)
80       {
81         // Make one up and hope it works.
82         addr = new byte[] {0, 0, 0, 0};
83       }
84     try
85       {
86         ANY_IF = getByAddress(addr);
87       }
88     catch (UnknownHostException e)
89       {
90         throw new RuntimeException("should never happen", e);
91       }
92     ANY_IF.hostName = ANY_IF.getHostName();
93   }
94   
95   /**
96    * Stores static localhost address object.
97    */
98   static InetAddress LOCALHOST;
99   static
100   {
101     try
102       {
103         LOCALHOST = getByAddress("localhost", new byte[] {127, 0, 0, 1});
104       }
105     catch (UnknownHostException e)
106       {
107         throw new RuntimeException("should never happen", 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 new RuntimeException("should never happen", 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 }