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 }