Dead
[official-gcc.git] / gomp-20050608-branch / libjava / java / net / InetAddress.java
blob0a9831a4ab69b540a28507fc1ff776f6b7316c48
1 /* InetAddress.java -- Class to model an Internet address
2 Copyright (C) 1998, 1999, 2002, 2004, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 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 * byte 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] & 0xff) == 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.
202 // 10.0.0.0/8
203 if ((addr[0] & 0xff) == 0x0a)
204 return true;
206 // 172.16.0.0/12
207 if ((addr[0] & 0xff) == 0xac && (addr[1] & 0xf0) == 0x10)
208 return true;
210 // 192.168.0.0/16
211 if ((addr[0] & 0xff) == 0xc0 && (addr[1] & 0xff) == 0xa8)
212 return true;
214 // XXX: Do we need to check more addresses here ?
215 return false;
219 * Utility routine to check if InetAddress is a global multicast address
221 * @since 1.4
223 public boolean isMCGlobal()
225 // This is the IPv4 implementation.
226 // Any class derived from InetAddress should override this.
227 // XXX: This seems to not exist with IPv4 addresses
228 return false;
232 * Utility routine to check if InetAddress is a node local multicast address.
234 * @since 1.4
236 public boolean isMCNodeLocal()
238 // This is the IPv4 implementation.
239 // Any class derived from InetAddress should override this.
240 // XXX: This seems to not exist with IPv4 addresses
241 return false;
245 * Utility routine to check if InetAddress is a link local multicast address.
247 * @since 1.4
249 public boolean isMCLinkLocal()
251 // This is the IPv4 implementation.
252 // Any class derived from InetAddress should override this.
253 if (! isMulticastAddress())
254 return false;
256 return ((addr[0] & 0xff) == 0xe0
257 && (addr[1] & 0xff) == 0x00
258 && (addr[2] & 0xff) == 0x00);
262 * Utility routine to check if InetAddress is a site local multicast address.
264 * @since 1.4
266 public boolean isMCSiteLocal()
268 // This is the IPv4 implementation.
269 // Any class derived from InetAddress should override this.
270 // XXX: This seems to not exist with IPv4 addresses
271 return false;
275 * Utility routine to check if InetAddress is a organization local
276 * multicast address.
278 * @since 1.4
280 public boolean isMCOrgLocal()
282 // This is the IPv4 implementation.
283 // Any class derived from InetAddress should override this.
284 // XXX: This seems to not exist with IPv4 addresses
285 return false;
289 * Returns the hostname for this address. This will return the IP address
290 * as a String if there is no hostname available for this address
292 * @return The hostname for this address
294 public String getHostName()
296 if (hostName != null)
297 return hostName;
299 // Lookup hostname and set field.
300 lookup (null, this, false);
302 return hostName;
306 * Returns the canonical hostname represented by this InetAddress
308 * @since 1.4
310 public String getCanonicalHostName()
312 SecurityManager sm = System.getSecurityManager();
313 if (sm != null)
317 sm.checkConnect(hostName, -1);
319 catch (SecurityException e)
321 return getHostAddress();
325 // Try to find the FDQN now
326 InetAddress address;
327 byte[] ipaddr = getAddress();
329 if (ipaddr.length == 16)
330 address = new Inet6Address(getAddress(), null);
331 else
332 address = new Inet4Address(getAddress(), null);
334 return address.getHostName();
338 * Returns the IP address of this object as a byte array.
340 * @return IP address
342 public byte[] getAddress()
344 // An experiment shows that JDK1.2 returns a different byte array each
345 // time. This makes sense, in terms of security.
346 return (byte[]) addr.clone();
349 /* Helper function due to a CNI limitation. */
350 private static InetAddress[] allocArray (int count)
352 return new InetAddress [count];
355 /* Helper function due to a CNI limitation. */
356 private static SecurityException checkConnect (String hostname)
358 SecurityManager s = System.getSecurityManager();
360 if (s == null)
361 return null;
365 s.checkConnect (hostname, -1);
366 return null;
368 catch (SecurityException ex)
370 return ex;
375 * Returns the IP address of this object as a String. The address is in
376 * the dotted octet notation, for example, "127.0.0.1".
378 * @return The IP address of this object in String form
380 * @since 1.0.2
382 public String getHostAddress()
384 StringBuffer sb = new StringBuffer(40);
386 int len = addr.length;
387 int i = 0;
389 if (len == 16)
390 { // An IPv6 address.
391 for ( ; ; i += 2)
393 if (i >= 16)
394 return sb.toString();
396 int x = ((addr [i] & 0xFF) << 8) | (addr [i + 1] & 0xFF);
397 boolean empty = sb.length() == 0;
399 if (empty)
401 if (i == 10 && x == 0xFFFF)
402 { // IPv4-mapped IPv6 address.
403 sb.append (":FFFF:");
404 break; // Continue as IPv4 address;
406 else if (i == 12)
407 { // IPv4-compatible IPv6 address.
408 sb.append (':');
409 break; // Continue as IPv4 address.
411 else if (i > 0)
412 sb.append ("::");
414 else
415 sb.append (':');
417 if (x != 0 || i >= 14)
418 sb.append (Integer.toHexString (x).toUpperCase());
422 for ( ; ; )
424 sb.append(addr[i] & 0xff);
425 i++;
427 if (i == len)
428 break;
430 sb.append('.');
433 return sb.toString();
437 * Returns a hash value for this address. Useful for creating hash
438 * tables. Overrides Object.hashCode()
440 * @return A hash value for this address.
442 public int hashCode()
444 // There hashing algorithm is not specified, but a simple experiment
445 // shows that it is equal to the address, as a 32-bit big-endian integer.
446 int hash = 0;
447 int len = addr.length;
448 int i = len > 4 ? len - 4 : 0;
450 for (; i < len; i++)
451 hash = (hash << 8) | (addr[i] & 0xff);
453 return hash;
457 * Tests this address for equality against another InetAddress. The two
458 * addresses are considered equal if they contain the exact same octets.
459 * This implementation overrides Object.equals()
461 * @param obj The address to test for equality
463 * @return true if the passed in object's address is equal to this one's,
464 * false otherwise
466 public boolean equals(Object obj)
468 if (! (obj instanceof InetAddress))
469 return false;
471 // "The Java Class Libraries" 2nd edition says "If a machine has
472 // multiple names instances of InetAddress for different name of
473 // that same machine are not equal. This is because they have
474 // different host names." This violates the description in the
475 // JDK 1.2 API documentation. A little experimentation
476 // shows that the latter is correct.
477 byte[] addr2 = ((InetAddress) obj).addr;
479 if (addr.length != addr2.length)
480 return false;
482 for (int i = 0; i < addr.length; i++)
483 if (addr[i] != addr2[i])
484 return false;
486 return true;
490 * Converts this address to a String. This string contains the IP in
491 * dotted decimal form. For example: "127.0.0.1" This method is equivalent
492 * to getHostAddress() and overrides Object.toString()
494 * @return This address in String form
496 public String toString()
498 String addr = getHostAddress();
499 String host = (hostName != null) ? hostName : "";
500 return host + "/" + addr;
504 * Returns an InetAddress object given the raw IP address.
506 * The argument is in network byte order: the highest order byte of the
507 * address is in getAddress()[0].
509 * @param addr The IP address to create the InetAddress object from
511 * @exception UnknownHostException If IP address has illegal length
513 * @since 1.4
515 public static InetAddress getByAddress(byte[] addr)
516 throws UnknownHostException
518 return getByAddress(null, addr);
522 * Creates an InetAddress based on the provided host name and IP address.
523 * No name service is checked for the validity of the address.
525 * @param host The hostname of the InetAddress object to create
526 * @param addr The IP address to create the InetAddress object from
528 * @exception UnknownHostException If IP address is of illegal length
530 * @since 1.4
532 public static InetAddress getByAddress(String host, byte[] addr)
533 throws UnknownHostException
535 if (addr.length == 4)
536 return new Inet4Address(addr, host);
538 if (addr.length == 16)
539 return new Inet6Address(addr, host);
541 throw new UnknownHostException("IP address has illegal length");
545 * If hostname is a valid numeric IP address, return the numeric address.
546 * Otherwise, return null.
548 * @param hostname the name of the host
550 private static native byte[] aton(String hostname);
553 * Looks up all addresses of a given host.
555 * @param hostname the host to lookup
556 * @param ipaddr the IP address to lookup
557 * @param all return all known addresses for one host
559 * @return an array with all found addresses
561 private static native InetAddress[] lookup (String hostname,
562 InetAddress ipaddr, boolean all);
565 * Returns tha family type of an IP address.
567 * @param addr the IP address
569 * @return the family
571 private static native int getFamily (byte[] ipaddr);
574 * Returns an InetAddress object representing the IP address of the given
575 * hostname. This name can be either a hostname such as "www.urbanophile.com"
576 * or an IP address in dotted decimal format such as "127.0.0.1". If the
577 * hostname is null or "", the hostname of the local machine is supplied by
578 * default. This method is equivalent to returning the first element in
579 * the InetAddress array returned from GetAllByName.
581 * @param hostname The name of the desired host, or null for the local
582 * loopback address.
584 * @return The address of the host as an InetAddress object.
586 * @exception UnknownHostException If no IP address for the host could
587 * be found
588 * @exception SecurityException If a security manager exists and its
589 * checkConnect method doesn't allow the operation
591 public static InetAddress getByName(String hostname)
592 throws UnknownHostException
594 // If null or the empty string is supplied, the loopback address
595 // is returned. Note that this is permitted without a security check.
596 if (hostname == null || hostname.length() == 0)
597 return loopback;
599 SecurityManager s = System.getSecurityManager();
600 if (s != null)
601 s.checkConnect(hostname, -1);
603 // Assume that the host string is an IP address
604 byte[] address = aton(hostname);
605 if (address != null)
607 if (address.length == 4)
608 return new Inet4Address (address, null);
609 else if (address.length == 16)
611 if ((address [10] == 0xFF) && (address [11] == 0xFF))
613 byte[] ip4addr = new byte [4];
614 ip4addr [0] = address [12];
615 ip4addr [1] = address [13];
616 ip4addr [2] = address [14];
617 ip4addr [3] = address [15];
618 return new Inet4Address (ip4addr, null);
620 return new Inet6Address (address, null);
622 else
623 throw new UnknownHostException ("Address has invalid length");
626 // Try to resolve the host by DNS
627 InetAddress result = new InetAddress(null, null);
628 lookup (hostname, result, false);
629 return result;
633 * Returns an array of InetAddress objects representing all the host/ip
634 * addresses of a given host, given the host's name. This name can be
635 * either a hostname such as "www.urbanophile.com" or an IP address in
636 * dotted decimal format such as "127.0.0.1". If the value is null, the
637 * hostname of the local machine is supplied by default.
639 * @param hostname The name of the desired host, or null for the
640 * local loopback address.
642 * @return All addresses of the host as an array of InetAddress objects.
644 * @exception UnknownHostException If no IP address for the host could
645 * be found
646 * @exception SecurityException If a security manager exists and its
647 * checkConnect method doesn't allow the operation
649 public static InetAddress[] getAllByName(String hostname)
650 throws UnknownHostException
652 // If null or the empty string is supplied, the loopback address
653 // is returned. Note that this is permitted without a security check.
654 if (hostname == null || hostname.length() == 0)
655 return new InetAddress[] {loopback};
657 SecurityManager s = System.getSecurityManager();
658 if (s != null)
659 s.checkConnect(hostname, -1);
661 // Check if hostname is an IP address
662 byte[] address = aton (hostname);
663 if (address != null)
665 InetAddress[] result = new InetAddress [1];
666 result [0] = new InetAddress (address, null);
667 return result;
670 // Try to resolve the hostname by DNS
671 return lookup (hostname, null, true);
675 * This native method looks up the hostname of the local machine
676 * we are on. If the actual hostname cannot be determined, then the
677 * value "localhost" will be used. This native method wrappers the
678 * "gethostname" function.
680 * @return The local hostname.
682 private static native String getLocalHostname();
685 * Returns an InetAddress object representing the address of the current
686 * host.
688 * @return The local host's address
690 * @exception UnknownHostException If no IP address for the host could
691 * be found
693 public static InetAddress getLocalHost() throws UnknownHostException
695 SecurityManager s = System.getSecurityManager();
697 // Experimentation shows that JDK1.2 does cache the result.
698 // However, if there is a security manager, and the cached result
699 // is other than "localhost", we need to check again.
700 if (localhost == null
701 || (s != null && ! localhost.isLoopbackAddress()))
702 getLocalHost (s);
704 return localhost;
707 private static synchronized void getLocalHost (SecurityManager s)
708 throws UnknownHostException
710 // Check the localhost cache again, now that we've synchronized.
711 if (s == null && localhost != null)
712 return;
714 String hostname = getLocalHostname();
716 if (s != null)
718 // "The Java Class Libraries" suggests that if the security
719 // manager disallows getting the local host name, then
720 // we use the loopback host.
721 // However, the JDK 1.2 API claims to throw SecurityException,
722 // which seems to suggest SecurityException is *not* caught.
723 // In this case, experimentation shows that former is correct.
726 // This is wrong, if the name returned from getLocalHostname()
727 // is not a fully qualified name. FIXME.
728 s.checkConnect (hostname, -1);
730 catch (SecurityException ex)
732 hostname = null;
736 if (hostname != null && hostname.length() != 0)
740 localhost = new InetAddress (null, null);
741 lookup (hostname, localhost, false);
743 catch (Exception ex)
747 else
748 throw new UnknownHostException();
750 if (localhost == null)
751 localhost = new InetAddress (loopbackAddress, "localhost");
755 * Needed for serialization
757 private void readResolve() throws ObjectStreamException
759 // FIXME: implement this
762 private void readObject(ObjectInputStream ois)
763 throws IOException, ClassNotFoundException
765 ois.defaultReadObject();
766 addr = new byte[4];
767 addr[3] = (byte) address;
769 for (int i = 2; i >= 0; --i)
770 addr[i] = (byte) (address >>= 8);
772 // Ignore family from serialized data. Since the saved address is 32 bits
773 // the deserialized object will have an IPv4 address i.e. AF_INET family.
774 // FIXME: An alternative is to call the aton method on the deserialized
775 // hostname to get a new address. The Serialized Form doc is silent
776 // on how these fields are used.
777 family = getFamily (addr);
780 private void writeObject(ObjectOutputStream oos) throws IOException
782 // Build a 32 bit address from the last 4 bytes of a 4 byte IPv4 address
783 // or a 16 byte IPv6 address.
784 int len = addr.length;
785 int i = len - 4;
787 for (; i < len; i++)
788 address = address << 8 | (((int) addr[i]) & 0xFF);
790 oos.defaultWriteObject();