Merge from mainline (gomp-merge-2005-02-26).
[official-gcc.git] / libjava / java / net / InetAddress.java
blob5a3ec474cf9e6d9816f36e6d227bc587e73415a0
1 /* InetAddress.java -- Class to model an Internet address
2 Copyright (C) 1998, 1999, 2002, 2004 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package java.net;
41 import gnu.classpath.Configuration;
43 import java.io.IOException;
44 import java.io.ObjectInputStream;
45 import java.io.ObjectOutputStream;
46 import java.io.ObjectStreamException;
47 import java.io.Serializable;
49 /**
50 * This class models an Internet address. It does not have a public
51 * constructor. Instead, new instances of this objects are created
52 * using the static methods getLocalHost(), getByName(), and
53 * getAllByName().
55 * <p>This class fulfills the function of the C style functions gethostname(),
56 * gethostbyname(), and gethostbyaddr(). It resolves Internet DNS names
57 * into their corresponding numeric addresses and vice versa.</p>
59 * @author Aaron M. Renn (arenn@urbanophile.com)
60 * @author Per Bothner
62 * @specnote This class is not final since JK 1.4
64 public class InetAddress implements Serializable
66 private static final long serialVersionUID = 3286316764910316507L;
68 /**
69 * Dummy InetAddress, used to bind socket to any (all) network interfaces.
71 static InetAddress ANY_IF;
73 private static final byte[] loopbackAddress = { 127, 0, 0, 1 };
75 private static final InetAddress loopback
76 = new Inet4Address(loopbackAddress, "localhost");
78 private static InetAddress localhost = null;
80 static
82 // load the shared library needed for name resolution
83 if (Configuration.INIT_LOAD_LIBRARY)
84 System.loadLibrary("javanet");
86 byte[] zeros = { 0, 0, 0, 0 };
87 ANY_IF = new Inet4Address(zeros, "0.0.0.0");
90 /**
91 * The Serialized Form specifies that an int 'address' is saved/restored.
92 * This class uses a byte array internally so we'll just do the conversion
93 * at serialization time and leave the rest of the algorithm as is.
95 private int address;
97 /**
98 * An array of octets representing an IP address.
100 transient byte[] addr;
103 * The name of the host for this address.
105 String hostName;
108 * The field 'family' seems to be the AF_ value.
109 * FIXME: Much of the code in the other java.net classes does not make
110 * use of this family field. A better implementation would be to make
111 * use of getaddrinfo() and have other methods just check the family
112 * field rather than examining the length of the address each time.
114 int family;
117 * Initializes this object's addr instance variable from the passed in
118 * int array. Note that this constructor is protected and is called
119 * only by static methods in this class.
121 * @param ipaddr The IP number of this address as an array of bytes
122 * @param hostname The hostname of this IP address.
124 InetAddress(byte[] ipaddr, String hostname)
126 addr = (null == ipaddr) ? null : (byte[]) ipaddr.clone();
127 hostName = hostname;
129 if (ipaddr != null)
130 family = getFamily(ipaddr);
134 * Returns true if this address is a multicast address, false otherwise.
135 * An address is multicast if the high four bits are "1110". These are
136 * also known as "Class D" addresses.
138 * @return true if mulitcast, false if not
140 * @since 1.1
142 public boolean isMulticastAddress()
144 // Mask against high order bits of 1110
145 if (addr.length == 4)
146 return (addr[0] & 0xF0) == 0xE0;
148 // Mask against high order bits of 11111111
149 if (addr.length == 16)
150 return addr [0] == (byte) 0xFF;
152 return false;
156 * Utility routine to check if the InetAddress in a wildcard address
158 * @since 1.4
160 public boolean isAnyLocalAddress()
162 // This is the IPv4 implementation.
163 // Any class derived from InetAddress should override this.
164 return equals(ANY_IF);
168 * Utility routine to check if the InetAddress is a loopback address
170 * @since 1.4
172 public boolean isLoopbackAddress()
174 // This is the IPv4 implementation.
175 // Any class derived from InetAddress should override this.
176 return addr[0] == 0x7F;
180 * Utility routine to check if InetAddress is a link local address
182 * @since 1.4
184 public boolean isLinkLocalAddress()
186 // This is the IPv4 implementation.
187 // Any class derived from InetAddress should override this.
188 // XXX: This seems to not exist with IPv4 addresses
189 return false;
193 * Utility routine to check if InetAddress is a site local address
195 * @since 1.4
197 public boolean isSiteLocalAddress()
199 // This is the IPv4 implementation.
200 // Any class derived from InetAddress should override this.
201 // 10.0.0.0/8
202 if (addr[0] == 0x0A)
203 return true;
205 // XXX: Suns JDK 1.4.1 (on Linux) seems to have a bug here:
206 // it says 172.16.0.0 - 172.255.255.255 are site local addresses
207 // 172.16.0.0/12
208 if (addr[0] == 0xAC && (addr[1] & 0xF0) == 0x01)
209 return true;
211 // 192.168.0.0/16
212 if (addr[0] == 0xC0 && addr[1] == 0xA8)
213 return true;
215 // XXX: Do we need to check more addresses here ?
216 return false;
220 * Utility routine to check if InetAddress is a global multicast address
222 * @since 1.4
224 public boolean isMCGlobal()
226 // This is the IPv4 implementation.
227 // Any class derived from InetAddress should override this.
228 // XXX: This seems to not exist with IPv4 addresses
229 return false;
233 * Utility reoutine to check if InetAddress is a node local multicast address
235 * @since 1.4
237 public boolean isMCNodeLocal()
239 // This is the IPv4 implementation.
240 // Any class derived from InetAddress should override this.
241 // XXX: This seems to not exist with IPv4 addresses
242 return false;
246 * Utility reoutine to check if InetAddress is a link local multicast address
248 * @since 1.4
250 public boolean isMCLinkLocal()
252 // This is the IPv4 implementation.
253 // Any class derived from InetAddress should override this.
254 if (! isMulticastAddress())
255 return false;
257 return (addr[0] == 0xE0 && addr[1] == 0x00 && addr[2] == 0x00);
261 * Utility routine to check if InetAddress is a site local multicast address
263 * @since 1.4
265 public boolean isMCSiteLocal()
267 // This is the IPv4 implementation.
268 // Any class derived from InetAddress should override this.
269 // XXX: This seems to not exist with IPv4 addresses
270 return false;
274 * Utility reoutine to check if InetAddress is a organization local
275 * multicast address
277 * @since 1.4
279 public boolean isMCOrgLocal()
281 // This is the IPv4 implementation.
282 // Any class derived from InetAddress should override this.
283 // XXX: This seems to not exist with IPv4 addresses
284 return false;
288 * Returns the hostname for this address. This will return the IP address
289 * as a String if there is no hostname available for this address
291 * @return The hostname for this address
293 public String getHostName()
295 if (hostName != null)
296 return hostName;
298 // Lookup hostname and set field.
299 lookup (null, this, false);
301 return hostName;
305 * Returns the canonical hostname represented by this InetAddress
307 * @since 1.4
309 public String getCanonicalHostName()
311 SecurityManager sm = System.getSecurityManager();
312 if (sm != null)
316 sm.checkConnect(hostName, -1);
318 catch (SecurityException e)
320 return getHostAddress();
324 // Try to find the FDQN now
325 InetAddress address;
326 byte[] ipaddr = getAddress();
328 if (ipaddr.length == 16)
329 address = new Inet6Address(getAddress(), null);
330 else
331 address = new Inet4Address(getAddress(), null);
333 return address.getHostName();
337 * Returns the IP address of this object as a byte array.
339 * @return IP address
341 public byte[] getAddress()
343 // An experiment shows that JDK1.2 returns a different byte array each
344 // time. This makes sense, in terms of security.
345 return (byte[]) addr.clone();
348 /* Helper function due to a CNI limitation. */
349 private static InetAddress[] allocArray (int count)
351 return new InetAddress [count];
354 /* Helper function due to a CNI limitation. */
355 private static SecurityException checkConnect (String hostname)
357 SecurityManager s = System.getSecurityManager();
359 if (s == null)
360 return null;
364 s.checkConnect (hostname, -1);
365 return null;
367 catch (SecurityException ex)
369 return ex;
374 * Returns the IP address of this object as a String. The address is in
375 * the dotted octet notation, for example, "127.0.0.1".
377 * @return The IP address of this object in String form
379 * @since 1.0.2
381 public String getHostAddress()
383 StringBuffer sb = new StringBuffer(40);
385 int len = addr.length;
386 int i = 0;
388 if (len == 16)
389 { // An IPv6 address.
390 for ( ; ; i += 2)
392 if (i >= 16)
393 return sb.toString();
395 int x = ((addr [i] & 0xFF) << 8) | (addr [i + 1] & 0xFF);
396 boolean empty = sb.length() == 0;
398 if (empty)
400 if (i == 10 && x == 0xFFFF)
401 { // IPv4-mapped IPv6 address.
402 sb.append (":FFFF:");
403 break; // Continue as IPv4 address;
405 else if (i == 12)
406 { // IPv4-compatible IPv6 address.
407 sb.append (':');
408 break; // Continue as IPv4 address.
410 else if (i > 0)
411 sb.append ("::");
413 else
414 sb.append (':');
416 if (x != 0 || i >= 14)
417 sb.append (Integer.toHexString (x).toUpperCase());
421 for ( ; ; )
423 sb.append(addr[i] & 0xff);
424 i++;
426 if (i == len)
427 break;
429 sb.append('.');
432 return sb.toString();
436 * Returns a hash value for this address. Useful for creating hash
437 * tables. Overrides Object.hashCode()
439 * @return A hash value for this address.
441 public int hashCode()
443 // There hashing algorithm is not specified, but a simple experiment
444 // shows that it is equal to the address, as a 32-bit big-endian integer.
445 int hash = 0;
446 int len = addr.length;
447 int i = len > 4 ? len - 4 : 0;
449 for (; i < len; i++)
450 hash = (hash << 8) | (addr[i] & 0xFF);
452 return hash;
456 * Tests this address for equality against another InetAddress. The two
457 * addresses are considered equal if they contain the exact same octets.
458 * This implementation overrides Object.equals()
460 * @param obj The address to test for equality
462 * @return true if the passed in object's address is equal to this one's,
463 * false otherwise
465 public boolean equals(Object obj)
467 if (! (obj instanceof InetAddress))
468 return false;
470 // "The Java Class Libraries" 2nd edition says "If a machine has
471 // multiple names instances of InetAddress for different name of
472 // that same machine are not equal. This is because they have
473 // different host names." This violates the description in the
474 // JDK 1.2 API documentation. A little experimentation
475 // shows that the latter is correct.
476 byte[] addr2 = ((InetAddress) obj).addr;
478 if (addr.length != addr2.length)
479 return false;
481 for (int i = 0; i < addr.length; i++)
482 if (addr[i] != addr2[i])
483 return false;
485 return true;
489 * Converts this address to a String. This string contains the IP in
490 * dotted decimal form. For example: "127.0.0.1" This method is equivalent
491 * to getHostAddress() and overrides Object.toString()
493 * @return This address in String form
495 public String toString()
497 String addr = getHostAddress();
498 String host = (hostName != null) ? hostName : addr;
499 return host + "/" + addr;
503 * Returns an InetAddress object given the raw IP address.
505 * The argument is in network byte order: the highest order byte of the
506 * address is in getAddress()[0].
508 * @param addr The IP address to create the InetAddress object from
510 * @exception UnknownHostException If IP address has illegal length
512 * @since 1.4
514 public static InetAddress getByAddress(byte[] addr)
515 throws UnknownHostException
517 return getByAddress(null, addr);
521 * Creates an InetAddress based on the provided host name and IP address.
522 * No name service is checked for the validity of the address.
524 * @param host The hostname of the InetAddress object to create
525 * @param addr The IP address to create the InetAddress object from
527 * @exception UnknownHostException If IP address is of illegal length
529 * @since 1.4
531 public static InetAddress getByAddress(String host, byte[] addr)
532 throws UnknownHostException
534 if (addr.length == 4)
535 return new Inet4Address(addr, host);
537 if (addr.length == 16)
538 return new Inet6Address(addr, host);
540 throw new UnknownHostException("IP address has illegal length");
544 * If host is a valid numeric IP address, return the numeric address.
545 * Otherwise, return null.
547 private static native byte[] aton (String host);
549 private static native InetAddress[] lookup (String hostname,
550 InetAddress addr, boolean all);
552 private static native int getFamily (byte[] address);
555 * Returns an InetAddress object representing the IP address of the given
556 * hostname. This name can be either a hostname such as "www.urbanophile.com"
557 * or an IP address in dotted decimal format such as "127.0.0.1". If the
558 * hostname is null or "", the hostname of the local machine is supplied by
559 * default. This method is equivalent to returning the first element in
560 * the InetAddress array returned from GetAllByName.
562 * @param hostname The name of the desired host, or null for the local
563 * loopback address.
565 * @return The address of the host as an InetAddress object.
567 * @exception UnknownHostException If no IP address for the host could
568 * be found
569 * @exception SecurityException If a security manager exists and its
570 * checkConnect method doesn't allow the operation
572 public static InetAddress getByName(String hostname)
573 throws UnknownHostException
575 // If null or the empty string is supplied, the loopback address
576 // is returned. Note that this is permitted without a security check.
577 if (hostname == null || hostname.length() == 0)
578 return loopback;
580 SecurityManager s = System.getSecurityManager();
581 if (s != null)
582 s.checkConnect(hostname, -1);
584 // Assume that the host string is an IP address
585 byte[] address = aton(hostname);
586 if (address != null)
588 if (address.length == 4)
589 return new Inet4Address (address, null);
590 else if (address.length == 16)
592 if ((address [10] == 0xFF) && (address [11] == 0xFF))
594 byte[] ip4addr = new byte [4];
595 ip4addr [0] = address [12];
596 ip4addr [1] = address [13];
597 ip4addr [2] = address [14];
598 ip4addr [3] = address [15];
599 return new Inet4Address (ip4addr, null);
601 return new Inet6Address (address, null);
603 else
604 throw new UnknownHostException ("Address has invalid length");
607 // Try to resolve the host by DNS
608 InetAddress result = new InetAddress(null, null);
609 lookup (hostname, result, false);
610 return result;
614 * Returns an array of InetAddress objects representing all the host/ip
615 * addresses of a given host, given the host's name. This name can be
616 * either a hostname such as "www.urbanophile.com" or an IP address in
617 * dotted decimal format such as "127.0.0.1". If the value is null, the
618 * hostname of the local machine is supplied by default.
620 * @param hostname The name of the desired host, or null for the
621 * local loopback address.
623 * @return All addresses of the host as an array of InetAddress objects.
625 * @exception UnknownHostException If no IP address for the host could
626 * be found
627 * @exception SecurityException If a security manager exists and its
628 * checkConnect method doesn't allow the operation
630 public static InetAddress[] getAllByName(String hostname)
631 throws UnknownHostException
633 // If null or the empty string is supplied, the loopback address
634 // is returned. Note that this is permitted without a security check.
635 if (hostname == null || hostname.length() == 0)
636 return new InetAddress[] {loopback};
638 SecurityManager s = System.getSecurityManager();
639 if (s != null)
640 s.checkConnect(hostname, -1);
642 // Check if hostname is an IP address
643 byte[] address = aton (hostname);
644 if (address != null)
646 InetAddress[] result = new InetAddress [1];
647 result [0] = new InetAddress (address, null);
648 return result;
651 // Try to resolve the hostname by DNS
652 return lookup (hostname, null, true);
656 * This native method looks up the hostname of the local machine
657 * we are on. If the actual hostname cannot be determined, then the
658 * value "localhost" will be used. This native method wrappers the
659 * "gethostname" function.
661 * @return The local hostname.
663 private static native String getLocalHostname();
666 * Returns an InetAddress object representing the address of the current
667 * host.
669 * @return The local host's address
671 * @exception UnknownHostException If no IP address for the host could
672 * be found
674 public static InetAddress getLocalHost() throws UnknownHostException
676 SecurityManager s = System.getSecurityManager();
678 // Experimentation shows that JDK1.2 does cache the result.
679 // However, if there is a security manager, and the cached result
680 // is other than "localhost", we need to check again.
681 if (localhost == null
682 || (s != null && ! localhost.isLoopbackAddress()))
683 getLocalHost (s);
685 return localhost;
688 private static synchronized void getLocalHost (SecurityManager s)
689 throws UnknownHostException
691 // Check the localhost cache again, now that we've synchronized.
692 if (s == null && localhost != null)
693 return;
695 String hostname = getLocalHostname();
697 if (s != null)
699 // "The Java Class Libraries" suggests that if the security
700 // manager disallows getting the local host name, then
701 // we use the loopback host.
702 // However, the JDK 1.2 API claims to throw SecurityException,
703 // which seems to suggest SecurityException is *not* caught.
704 // In this case, experimentation shows that former is correct.
707 // This is wrong, if the name returned from getLocalHostname()
708 // is not a fully qualified name. FIXME.
709 s.checkConnect (hostname, -1);
711 catch (SecurityException ex)
713 hostname = null;
717 if (hostname != null && hostname.length() != 0)
721 localhost = new InetAddress (null, null);
722 lookup (hostname, localhost, false);
724 catch (Exception ex)
728 else
729 throw new UnknownHostException();
731 if (localhost == null)
732 localhost = new InetAddress (loopbackAddress, "localhost");
736 * Needed for serialization
738 private void readResolve() throws ObjectStreamException
740 // FIXME: implement this
743 private void readObject(ObjectInputStream ois)
744 throws IOException, ClassNotFoundException
746 ois.defaultReadObject();
747 addr = new byte[4];
748 addr[3] = (byte) address;
750 for (int i = 2; i >= 0; --i)
751 addr[i] = (byte) (address >>= 8);
753 // Ignore family from serialized data. Since the saved address is 32 bits
754 // the deserialized object will have an IPv4 address i.e. AF_INET family.
755 // FIXME: An alternative is to call the aton method on the deserialized
756 // hostname to get a new address. The Serialized Form doc is silent
757 // on how these fields are used.
758 family = getFamily (addr);
761 private void writeObject(ObjectOutputStream oos) throws IOException
763 // Build a 32 bit address from the last 4 bytes of a 4 byte IPv4 address
764 // or a 16 byte IPv6 address.
765 int len = addr.length;
766 int i = len - 4;
768 for (; i < len; i++)
769 address = address << 8 | (((int) addr[i]) & 0xFF);
771 oos.defaultWriteObject();