1. /*
  2. * @(#)InetAddress.java 1.99 03/01/23
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.net;
  8. import java.util.HashMap;
  9. import java.util.LinkedHashMap;
  10. import java.util.Random;
  11. import java.util.Iterator;
  12. import java.util.LinkedList;
  13. import java.security.AccessController;
  14. import java.io.ObjectStreamException;
  15. import sun.security.action.*;
  16. import sun.net.InetAddressCachePolicy;
  17. import sun.misc.Service;
  18. import sun.net.spi.nameservice.*;
  19. /**
  20. * This class represents an Internet Protocol (IP) address.
  21. *
  22. * <p> An IP address is either a 32-bit or 128-bit unsigned number
  23. * used by IP, a lower-level protocol on which protocols like UDP and
  24. * TCP are built. The IP address architecture is defined by <a
  25. * href="http://www.ietf.org/rfc/rfc790.txt"><i>RFC 790:
  26. * Assigned Numbers</i></a>, <a
  27. * href="http://www.ietf.org/rfc/rfc1918.txt"> <i>RFC 1918:
  28. * Address Allocation for Private Internets</i></a>, <a
  29. * href="http://www.ietf.org/rfc/rfc2365.txt"><i>RFC 2365:
  30. * Administratively Scoped IP Multicast</i></a>, and <a
  31. * href="http://www.ietf.org/rfc/rfc2373.txt"><i>RFC 2373: IP
  32. * Version 6 Addressing Architecture</i></a>. An instance of an
  33. * InetAddress consists of an IP address and possibly its
  34. * corresponding host name (depending on whether it is constructed
  35. * with a host name or whether it has already done reverse host name
  36. * resolution).
  37. *
  38. * <h4> Address types </h4>
  39. *
  40. * <blockquote><table cellspacing=2 summary="Description of unicast and multicast address types">
  41. * <tr><th valign=top><i>unicast</i></th>
  42. * <td>An identifier for a single interface. A packet sent to
  43. * a unicast address is delivered to the interface identified by
  44. * that address.
  45. *
  46. * <p> The Unspecified Address -- Also called anylocal or wildcard
  47. * address. It must never be assigned to any node. It indicates the
  48. * absence of an address. One example of its use is as the target of
  49. * bind, which allows a server to accept a client connection on any
  50. * interface, in case the server host has multiple interfaces.
  51. *
  52. * <p> The <i>unspecified</i> address must not be used as
  53. * the destination address of an IP packet.
  54. *
  55. * <p> The <i>Loopback</i> Addresses -- This is the address
  56. * assigned to the loopback interface. Anything sent to this
  57. * IP address loops around and becomes IP input on the local
  58. * host. This address is often used when testing a
  59. * client.</td></tr>
  60. * <tr><th valign=top><i>multicast</i></th>
  61. * <td>An identifier for a set of interfaces (typically belonging
  62. * to different nodes). A packet sent to a multicast address is
  63. * delivered to all interfaces identified by that address.</td></tr>
  64. * </table></blockquote>
  65. *
  66. * <h4> IP address scope </h4>
  67. *
  68. * <p> <i>Link-local</i> addresses are designed to be used for addressing
  69. * on a single link for purposes such as auto-address configuration,
  70. * neighbor discovery, or when no routers are present.
  71. *
  72. * <p> <i>Site-local</i> addresses are designed to be used for addressing
  73. * inside of a site without the need for a global prefix.
  74. *
  75. * <p> <i>Global</i> addresses are unique across the internet.
  76. *
  77. * <h4> Textual representation of IP addresses </h4>
  78. *
  79. * The textual representation of an IP address is address family specific.
  80. *
  81. * <p>
  82. *
  83. * For IPv4 address format, please refer to <A
  84. * HREF="Inet4Address.html#format">Inet4Address#format</A> For IPv6
  85. * address format, please refer to <A
  86. * HREF="Inet6Address.html#format">Inet6Address#format</A>.
  87. *
  88. * <h4> Host Name Resolution </h4>
  89. *
  90. * Host name-to-IP address <i>resolution</i> is accomplished through
  91. * the use of a combination of local machine configuration information
  92. * and network naming services such as the Domain Name System (DNS)
  93. * and Network Information Service(NIS). The particular naming
  94. * services(s) being used is by default the local machine configured
  95. * one. For any host name, its corresponding IP address is returned.
  96. *
  97. * <p> <i>Reverse name resolution</i> means that for any IP address,
  98. * the host associated with the IP address is returned.
  99. *
  100. * <p> The InetAddress class provides methods to resolve host names to
  101. * their IP addresses and vise versa.
  102. *
  103. * <h4> InetAddress Caching </h4>
  104. *
  105. * The InetAddress class has a cache to store successful as well as
  106. * unsuccessful host name resolutions. The positive caching is there
  107. * to guard against DNS spoofing attacks; while the negative caching
  108. * is used to improve performance.
  109. *
  110. * <p> By default, the result of positive host name resolutions are
  111. * cached forever, because there is no general rule to decide when it
  112. * is safe to remove cache entries. The result of unsuccessful host
  113. * name resolution is cached for a very short period of time (10
  114. * seconds) to improve performance.
  115. *
  116. * <p> Under certain circumstances where it can be determined that DNS
  117. * spoofing attacks are not possible, a Java security property can be
  118. * set to a different Time-to-live (TTL) value for positive
  119. * caching. Likewise, a system admin can configure a different
  120. * negative caching TTL value when needed.
  121. *
  122. * <p> Two Java security properties control the TTL values used for
  123. * positive and negative host name resolution caching:
  124. *
  125. * <blockquote>
  126. * <dl>
  127. * <dt><b>networkaddress.cache.ttl</b> (default: -1)</dt>
  128. * <dd>Indicates the caching policy for successful name lookups from
  129. * the name service. The value is specified as as integer to indicate
  130. * the number of seconds to cache the successful lookup.
  131. * <p>
  132. * A value of -1 indicates "cache forever".
  133. * </dt><p>
  134. * <p>
  135. * <dt><b>networkaddress.cache.negative.ttl</b> (default: 10)</dt>
  136. * <dd>Indicates the caching policy for un-successful name lookups
  137. * from the name service. The value is specified as as integer to
  138. * indicate the number of seconds to cache the failure for
  139. * un-successful lookups.
  140. * <p>
  141. * A value of 0 indicates "never cache".
  142. * A value of -1 indicates "cache forever".
  143. * </dd>
  144. * </dl>
  145. * </blockquote>
  146. *
  147. * @author Chris Warth
  148. * @version 1.99, 01/23/03
  149. * @see java.net.InetAddress#getByAddress(byte[])
  150. * @see java.net.InetAddress#getByAddress(java.lang.String, byte[])
  151. * @see java.net.InetAddress#getAllByName(java.lang.String)
  152. * @see java.net.InetAddress#getByName(java.lang.String)
  153. * @see java.net.InetAddress#getLocalHost()
  154. * @since JDK1.0
  155. */
  156. public
  157. class InetAddress implements java.io.Serializable {
  158. /**
  159. * Specify the address family: Internet Protocol, Version 4
  160. * @since 1.4
  161. */
  162. static final int IPv4 = 1;
  163. /**
  164. * Specify the address family: Internet Protocol, Version 6
  165. * @since 1.4
  166. */
  167. static final int IPv6 = 2;
  168. /* Specify address family preference */
  169. static transient boolean preferIPv6Address = false;
  170. /**
  171. * @serial
  172. */
  173. String hostName;
  174. /**
  175. * Holds a 32-bit IPv4 address.
  176. *
  177. * @serial
  178. */
  179. int address;
  180. /**
  181. * Specifies the address family type, for instance, '1' for IPv4
  182. * addresses, and '2' for IPv6 addresses.
  183. *
  184. * @serial
  185. */
  186. int family;
  187. /* Used to store the name service provider */
  188. private static NameService nameService = null;
  189. /* Used to store the best available hostname */
  190. private transient String canonicalHostName = null;
  191. /** use serialVersionUID from JDK 1.0.2 for interoperability */
  192. private static final long serialVersionUID = 3286316764910316507L;
  193. /*
  194. * Load net library into runtime, and perform initializations.
  195. */
  196. static {
  197. preferIPv6Address =
  198. ((Boolean)java.security.AccessController.doPrivileged(
  199. new GetBooleanAction("java.net.preferIPv6Addresses"))).booleanValue();
  200. AccessController.doPrivileged(new LoadLibraryAction("net"));
  201. init();
  202. }
  203. /**
  204. * Constructor for the Socket.accept() method.
  205. * This creates an empty InetAddress, which is filled in by
  206. * the accept() method. This InetAddress, however, is not
  207. * put in the address cache, since it is not created by name.
  208. */
  209. InetAddress() {
  210. }
  211. /**
  212. * Replaces the de-serialized object with an Inet4Address object.
  213. *
  214. * @return the alternate object to the de-serialized object.
  215. *
  216. * @throws ObjectStreamException if a new object replacing this
  217. * object could not be created
  218. */
  219. private Object readResolve() throws ObjectStreamException {
  220. // will replace the deserialized 'this' object
  221. return new Inet4Address(this.hostName, this.address);
  222. }
  223. /**
  224. * Utility routine to check if the InetAddress is an
  225. * IP multicast address.
  226. * @return a <code>boolean</code> indicating if the InetAddress is
  227. * an IP multicast address
  228. * @since JDK1.1
  229. */
  230. public boolean isMulticastAddress() {
  231. return false;
  232. }
  233. /**
  234. * Utility routine to check if the InetAddress in a wildcard address.
  235. * @return a <code>boolean</code> indicating if the Inetaddress is
  236. * a wildcard address.
  237. * @since 1.4
  238. */
  239. public boolean isAnyLocalAddress() {
  240. return false;
  241. }
  242. /**
  243. * Utility routine to check if the InetAddress is a loopback address.
  244. *
  245. * @return a <code>boolean</code> indicating if the InetAddress is
  246. * a loopback address; or false otherwise.
  247. * @since 1.4
  248. */
  249. public boolean isLoopbackAddress() {
  250. return false;
  251. }
  252. /**
  253. * Utility routine to check if the InetAddress is an link local address.
  254. *
  255. * @return a <code>boolean</code> indicating if the InetAddress is
  256. * a link local address; or false if address is not a link local unicast address.
  257. * @since 1.4
  258. */
  259. public boolean isLinkLocalAddress() {
  260. return false;
  261. }
  262. /**
  263. * Utility routine to check if the InetAddress is a site local address.
  264. *
  265. * @return a <code>boolean</code> indicating if the InetAddress is
  266. * a site local address; or false if address is not a site local unicast address.
  267. * @since 1.4
  268. */
  269. public boolean isSiteLocalAddress() {
  270. return false;
  271. }
  272. /**
  273. * Utility routine to check if the multicast address has global scope.
  274. *
  275. * @return a <code>boolean</code> indicating if the address has
  276. * is a multicast address of global scope, false if it is not
  277. * of global scope or it is not a multicast address
  278. * @since 1.4
  279. */
  280. public boolean isMCGlobal() {
  281. return false;
  282. }
  283. /**
  284. * Utility routine to check if the multicast address has node scope.
  285. *
  286. * @return a <code>boolean</code> indicating if the address has
  287. * is a multicast address of node-local scope, false if it is not
  288. * of node-local scope or it is not a multicast address
  289. * @since 1.4
  290. */
  291. public boolean isMCNodeLocal() {
  292. return false;
  293. }
  294. /**
  295. * Utility routine to check if the multicast address has link scope.
  296. *
  297. * @return a <code>boolean</code> indicating if the address has
  298. * is a multicast address of link-local scope, false if it is not
  299. * of link-local scope or it is not a multicast address
  300. * @since 1.4
  301. */
  302. public boolean isMCLinkLocal() {
  303. return false;
  304. }
  305. /**
  306. * Utility routine to check if the multicast address has site scope.
  307. *
  308. * @return a <code>boolean</code> indicating if the address has
  309. * is a multicast address of site-local scope, false if it is not
  310. * of site-local scope or it is not a multicast address
  311. * @since 1.4
  312. */
  313. public boolean isMCSiteLocal() {
  314. return false;
  315. }
  316. /**
  317. * Utility routine to check if the multicast address has organization scope.
  318. *
  319. * @return a <code>boolean</code> indicating if the address has
  320. * is a multicast address of organization-local scope,
  321. * false if it is not of organization-local scope
  322. * or it is not a multicast address
  323. * @since 1.4
  324. */
  325. public boolean isMCOrgLocal() {
  326. return false;
  327. }
  328. /**
  329. * Gets the host name for this IP address.
  330. *
  331. * <p>If this InetAddress was created with a host name,
  332. * this host name will be remembered and returned;
  333. * otherwise, a reverse name lookup will be performed
  334. * and the result will be returned based on the system
  335. * configured name lookup service. If a lookup of the name service
  336. * is required, call
  337. * {@link #getCanonicalHostName() getCanonicalHostName}.
  338. *
  339. * <p>If there is a security manager, its
  340. * <code>checkConnect</code> method is first called
  341. * with the hostname and <code>-1</code>
  342. * as its arguments to see if the operation is allowed.
  343. * If the operation is not allowed, it will return
  344. * the textual representation of the IP address.
  345. *
  346. * @return the host name for this IP address, or if the operation
  347. * is not allowed by the security check, the textual
  348. * representation of the IP address.
  349. *
  350. * @see InetAddress#getCanonicalHostName
  351. * @see SecurityManager#checkConnect
  352. */
  353. public String getHostName() {
  354. return getHostName(true);
  355. }
  356. /**
  357. * Returns the hostname for this address.
  358. * If the host is equal to null, then this address refers to any
  359. * of the local machine's available network addresses.
  360. * this is package private so SocketPermission can make calls into
  361. * here without a security check.
  362. *
  363. * <p>If there is a security manager, this method first
  364. * calls its <code>checkConnect</code> method
  365. * with the hostname and <code>-1</code>
  366. * as its arguments to see if the calling code is allowed to know
  367. * the hostname for this IP address, i.e., to connect to the host.
  368. * If the operation is not allowed, it will return
  369. * the textual representation of the IP address.
  370. *
  371. * @return the host name for this IP address, or if the operation
  372. * is not allowed by the security check, the textual
  373. * representation of the IP address.
  374. *
  375. * @param check make security check if true
  376. *
  377. * @see SecurityManager#checkConnect
  378. */
  379. String getHostName(boolean check) {
  380. if (hostName == null) {
  381. hostName = InetAddress.getHostFromNameService(this, check);
  382. }
  383. return hostName;
  384. }
  385. /**
  386. * Gets the fully qualified domain name for this IP address.
  387. * Best effort method, meaning we may not be able to return
  388. * the FQDN depending on the underlying system configuration.
  389. *
  390. * <p>If there is a security manager, this method first
  391. * calls its <code>checkConnect</code> method
  392. * with the hostname and <code>-1</code>
  393. * as its arguments to see if the calling code is allowed to know
  394. * the hostname for this IP address, i.e., to connect to the host.
  395. * If the operation is not allowed, it will return
  396. * the textual representation of the IP address.
  397. *
  398. * @return the fully qualified domain name for this IP address,
  399. * or if the operation is not allowed by the security check,
  400. * the textual representation of the IP address.
  401. *
  402. * @see SecurityManager#checkConnect
  403. *
  404. * @since 1.4
  405. */
  406. public String getCanonicalHostName() {
  407. if (canonicalHostName == null) {
  408. canonicalHostName =
  409. InetAddress.getHostFromNameService(this, true);
  410. }
  411. return canonicalHostName;
  412. }
  413. /**
  414. * Returns the hostname for this address.
  415. *
  416. * <p>If there is a security manager, this method first
  417. * calls its <code>checkConnect</code> method
  418. * with the hostname and <code>-1</code>
  419. * as its arguments to see if the calling code is allowed to know
  420. * the hostname for this IP address, i.e., to connect to the host.
  421. * If the operation is not allowed, it will return
  422. * the textual representation of the IP address.
  423. *
  424. * @return the host name for this IP address, or if the operation
  425. * is not allowed by the security check, the textual
  426. * representation of the IP address.
  427. *
  428. * @param check make security check if true
  429. *
  430. * @see SecurityManager#checkConnect
  431. */
  432. private static String getHostFromNameService(InetAddress addr, boolean check) {
  433. String host;
  434. try {
  435. // first lookup the hostname
  436. host = nameService.getHostByAddr(addr.getAddress());
  437. /* check to see if calling code is allowed to know
  438. * the hostname for this IP address, ie, connect to the host
  439. */
  440. if (check) {
  441. SecurityManager sec = System.getSecurityManager();
  442. if (sec != null) {
  443. sec.checkConnect(host, -1);
  444. }
  445. }
  446. /* now get all the IP addresses for this hostname,
  447. * and make sure one of them matches the original IP
  448. * address. We do this to try and prevent spoofing.
  449. */
  450. InetAddress[] arr = InetAddress.getAllByName0(host, check);
  451. boolean ok = false;
  452. if(arr != null) {
  453. for(int i = 0; !ok && i < arr.length; i++) {
  454. ok = addr.equals(arr[i]);
  455. }
  456. }
  457. //XXX: if it looks a spoof just return the address?
  458. if (!ok) {
  459. host = addr.getHostAddress();
  460. return host;
  461. }
  462. } catch (SecurityException e) {
  463. host = addr.getHostAddress();
  464. } catch (UnknownHostException e) {
  465. host = addr.getHostAddress();
  466. }
  467. return host;
  468. }
  469. /**
  470. * Returns the raw IP address of this <code>InetAddress</code>
  471. * object. The result is in network byte order: the highest order
  472. * byte of the address is in <code>getAddress()[0]</code>.
  473. *
  474. * @return the raw IP address of this object.
  475. */
  476. public byte[] getAddress() {
  477. return null;
  478. }
  479. /**
  480. * Returns the IP address string in textual presentation.
  481. *
  482. * @return the raw IP address in a string format.
  483. * @since JDK1.0.2
  484. */
  485. public String getHostAddress() {
  486. return null;
  487. }
  488. /**
  489. * Returns a hashcode for this IP address.
  490. *
  491. * @return a hash code value for this IP address.
  492. */
  493. public int hashCode() {
  494. return -1;
  495. }
  496. /**
  497. * Compares this object against the specified object.
  498. * The result is <code>true</code> if and only if the argument is
  499. * not <code>null</code> and it represents the same IP address as
  500. * this object.
  501. * <p>
  502. * Two instances of <code>InetAddress</code> represent the same IP
  503. * address if the length of the byte arrays returned by
  504. * <code>getAddress</code> is the same for both, and each of the
  505. * array components is the same for the byte arrays.
  506. *
  507. * @param obj the object to compare against.
  508. * @return <code>true</code> if the objects are the same;
  509. * <code>false</code> otherwise.
  510. * @see java.net.InetAddress#getAddress()
  511. */
  512. public boolean equals(Object obj) {
  513. return false;
  514. }
  515. /**
  516. * Converts this IP address to a <code>String</code>. The
  517. * string returned is of the form: hostname / literal IP
  518. * address.
  519. *
  520. * If the host name is unresolved, no reverse name service loopup
  521. * is performed. The hostname part will be represented by an empty string.
  522. *
  523. * @return a string representation of this IP address.
  524. */
  525. public String toString() {
  526. return ((hostName != null) ? hostName : "")
  527. + "/" + getHostAddress();
  528. }
  529. /*
  530. * Cached addresses - our own litle nis, not!
  531. */
  532. private static Cache addressCache =
  533. new Cache(InetAddressCachePolicy.get());
  534. private static Cache negativeCache =
  535. new Cache(InetAddressCachePolicy.getNegative());
  536. private static boolean addressCacheInit = false;
  537. static InetAddress[] unknown_array; // put THIS in cache
  538. static InetAddressImpl impl;
  539. private static HashMap lookupTable = new HashMap();
  540. /**
  541. * Represents a cache entry
  542. */
  543. static final class CacheEntry {
  544. CacheEntry(Object address, long expiration) {
  545. this.address = address;
  546. this.expiration = expiration;
  547. }
  548. Object address;
  549. long expiration;
  550. }
  551. /**
  552. * A cache that manages entries based on a policy specified
  553. * at creation time.
  554. */
  555. static final class Cache {
  556. private int policy;
  557. private LinkedHashMap cache;
  558. /**
  559. * Create cache with specific policy
  560. */
  561. public Cache(int policy) {
  562. this.policy = policy;
  563. cache = new LinkedHashMap();
  564. }
  565. /**
  566. * Add an entry to the cache. If there's already an
  567. * entry then for this host then the entry will be
  568. * replaced.
  569. */
  570. public Cache put(String host, Object address) {
  571. if (policy == InetAddressCachePolicy.NEVER) {
  572. return this;
  573. }
  574. // purge any expired entries
  575. if (policy != InetAddressCachePolicy.FOREVER) {
  576. // As we iterate in insertion order we can
  577. // terminate when a non-expired entry is found.
  578. LinkedList expired = new LinkedList();
  579. Iterator i = cache.keySet().iterator();
  580. long now = System.currentTimeMillis();
  581. while (i.hasNext()) {
  582. String key = (String)i.next();
  583. CacheEntry entry = (CacheEntry)cache.get(key);
  584. if (entry.expiration >= 0 && entry.expiration < now) {
  585. expired.add(key);
  586. } else {
  587. break;
  588. }
  589. }
  590. i = expired.iterator();
  591. while (i.hasNext()) {
  592. cache.remove(i.next());
  593. }
  594. }
  595. // create new entry and add it to the cache
  596. // -- as a HashMap replaces existing entries we
  597. // don't need to explicitly check if there is
  598. // already an entry for this host.
  599. long expiration;
  600. if (policy == InetAddressCachePolicy.FOREVER) {
  601. expiration = -1;
  602. } else {
  603. expiration = System.currentTimeMillis() + (policy * 1000);
  604. }
  605. CacheEntry entry = new CacheEntry(address, expiration);
  606. cache.put(host, entry);
  607. return this;
  608. }
  609. /**
  610. * Query the cache for the specific host. If found then
  611. * return its CacheEntry, or null if not found.
  612. */
  613. public CacheEntry get(String host) {
  614. if (policy == InetAddressCachePolicy.NEVER) {
  615. return null;
  616. }
  617. CacheEntry entry = (CacheEntry)cache.get(host);
  618. // check if entry has expired
  619. if (entry != null && policy != InetAddressCachePolicy.FOREVER) {
  620. if (entry.expiration >= 0 &&
  621. entry.expiration < System.currentTimeMillis()) {
  622. cache.remove(host);
  623. entry = null;
  624. }
  625. }
  626. return entry;
  627. }
  628. }
  629. /*
  630. * Initialize cache and insert anyLocalAddress into the
  631. * unknown array with no expiry.
  632. */
  633. private static void cacheInitIfNeeded() {
  634. assert Thread.holdsLock(addressCache);
  635. if (addressCacheInit) {
  636. return;
  637. }
  638. unknown_array = new InetAddress[1];
  639. unknown_array[0] = impl.anyLocalAddress();
  640. addressCache.put(impl.anyLocalAddress().getHostName(),
  641. unknown_array);
  642. addressCacheInit = true;
  643. }
  644. /*
  645. * Cache the given hostname and address.
  646. */
  647. private static void cacheAddress(String hostname, Object address,
  648. boolean success) {
  649. synchronized (addressCache) {
  650. cacheInitIfNeeded();
  651. if (success) {
  652. addressCache.put(hostname, address);
  653. } else {
  654. negativeCache.put(hostname, address);
  655. }
  656. }
  657. }
  658. /*
  659. * Lookup hostname in cache (positive & negative cache). If
  660. * found return address, null if not found.
  661. */
  662. private static Object getCachedAddress(String hostname) {
  663. hostname = hostname.toLowerCase();
  664. // search both positive & negative caches
  665. synchronized (addressCache) {
  666. CacheEntry entry;
  667. cacheInitIfNeeded();
  668. entry = (CacheEntry)addressCache.get(hostname);
  669. if (entry == null) {
  670. entry = (CacheEntry)negativeCache.get(hostname);
  671. }
  672. if (entry != null) {
  673. return entry.address;
  674. }
  675. }
  676. // not found
  677. return null;
  678. }
  679. static {
  680. // create the impl
  681. impl = (new InetAddressImplFactory()).create();
  682. // get name service if provided and requested
  683. String provider = null;;
  684. String propPrefix = "sun.net.spi.nameservice.provider.";
  685. int n = 1;
  686. while (nameService == null) {
  687. provider
  688. = (String)AccessController.doPrivileged(
  689. new GetPropertyAction(propPrefix+n, "default"));
  690. n++;
  691. if (provider.equals("default")) {
  692. // initialize the default name service
  693. nameService = new NameService() {
  694. public byte[][] lookupAllHostAddr(String host)
  695. throws UnknownHostException {
  696. return impl.lookupAllHostAddr(host);
  697. }
  698. public String getHostByAddr(byte[] addr)
  699. throws UnknownHostException {
  700. return impl.getHostByAddr(addr);
  701. }
  702. };
  703. break;
  704. }
  705. final String providerName = provider;
  706. try {
  707. java.security.AccessController.doPrivileged(
  708. new java.security.PrivilegedExceptionAction() {
  709. public Object run() {
  710. Iterator itr
  711. = Service.providers(NameServiceDescriptor.class);
  712. while (itr.hasNext()) {
  713. NameServiceDescriptor nsd
  714. = (NameServiceDescriptor)itr.next();
  715. if (providerName.
  716. equalsIgnoreCase(nsd.getType()+","
  717. +nsd.getProviderName())) {
  718. try {
  719. nameService = nsd.createNameService();
  720. break;
  721. } catch (Exception e) {
  722. e.printStackTrace();
  723. System.err.println(
  724. "Cannot create name service:"
  725. +providerName+": " + e);
  726. }
  727. }
  728. } /* while */
  729. return null;
  730. }
  731. });
  732. } catch (java.security.PrivilegedActionException e) {
  733. }
  734. }
  735. }
  736. /**
  737. * Create an InetAddress based on the provided host name and IP address
  738. * No name service is checked for the validity of the address.
  739. *
  740. * <p> The host name can either be a machine name, such as
  741. * "<code>java.sun.com</code>", or a textual representation of its IP
  742. * address.
  743. *
  744. * <p> For <code>host</code> specified in literal IPv6 address,
  745. * either the form defined in RFC 2732 or the literal IPv6 address
  746. * format defined in RFC 2373 is accepted.
  747. *
  748. * <p> If addr specifies an IPv4 address an instance of Inet4Address
  749. * will be returned; otherwise, an instance of Inet6Address
  750. * will be returned.
  751. *
  752. * <p> IPv4 address byte array must be 4 bytes long and IPv6 byte array
  753. * must be 16 bytes long
  754. *
  755. * @param host the specified host
  756. * @param addr the raw IP address in network byte order
  757. * @return an InetAddress object created from the raw IP address.
  758. * @exception UnknownHostException if IP address is of illegal length
  759. * @since 1.4
  760. */
  761. public static InetAddress getByAddress(String host, byte[] addr)
  762. throws UnknownHostException {
  763. if (host != null && host.length() > 0 && host.charAt(0) == '[') {
  764. if (host.charAt(host.length()-1) == ']') {
  765. host = host.substring(1, host.length() -1);
  766. }
  767. }
  768. if (addr != null) {
  769. if (addr.length == Inet4Address.INADDRSZ) {
  770. return new Inet4Address(host, addr);
  771. } else if (addr.length == Inet6Address.INADDRSZ) {
  772. byte[] newAddr
  773. = Inet6Address.convertFromIPv4MappedAddress(addr);
  774. if (newAddr != null) {
  775. return new Inet4Address(host, newAddr);
  776. } else {
  777. return new Inet6Address(host, addr);
  778. }
  779. }
  780. }
  781. throw new UnknownHostException("addr is of illegal length");
  782. }
  783. /**
  784. * Determines the IP address of a host, given the host's name.
  785. *
  786. * <p> The host name can either be a machine name, such as
  787. * "<code>java.sun.com</code>", or a textual representation of its
  788. * IP address. If a literal IP address is supplied, only the
  789. * validity of the address format is checked.
  790. *
  791. * <p> For <code>host</code> specified in literal IPv6 address,
  792. * either the form defined in RFC 2732 or the literal IPv6 address
  793. * format defined in RFC 2373 is accepted.
  794. *
  795. * <p> If the host is <tt>null</tt> then an <tt>InetAddress</tt>
  796. * representing an address of the loopback interface is returned.
  797. * See <a href="http://www.ietf.org/rfc/rfc3330.txt">RFC 3330</a>
  798. * section 2 and <a href="http://www.ietf.org/rfc/rfc2373.txt">RFC 2373</a>
  799. * section 2.5.3. </p>
  800. *
  801. * @param host the specified host, or <code>null</code>.
  802. * @return an IP address for the given host name.
  803. * @exception UnknownHostException if no IP address for the
  804. * <code>host</code> could be found.
  805. * @exception SecurityException if a security manager exists
  806. * and its checkConnect method doesn't allow the operation
  807. */
  808. public static InetAddress getByName(String host)
  809. throws UnknownHostException {
  810. return InetAddress.getAllByName(host)[0];
  811. }
  812. /**
  813. * Given the name of a host, returns an array of its IP addresses,
  814. * based on the configured name service on the system.
  815. *
  816. * <p> The host name can either be a machine name, such as
  817. * "<code>java.sun.com</code>", or a textual representation of its IP
  818. * address. If a literal IP address is supplied, only the
  819. * validity of the address format is checked.
  820. *
  821. * <p> For <code>host</code> specified in literal IPv6 address,
  822. * either the form defined in RFC 2732 or the literal IPv6 address
  823. * format defined in RFC 2373 is accepted.
  824. *
  825. * <p> If the host is <tt>null</tt> then an <tt>InetAddress</tt>
  826. * representing an address of the loopback interface is returned.
  827. * See <a href="http://www.ietf.org/rfc/rfc3330.txt">RFC 3330</a>
  828. * section 2 and <a href="http://www.ietf.org/rfc/rfc2373.txt">RFC 2373</a>
  829. * section 2.5.3. </p>
  830. *
  831. * <p> If there is a security manager and <code>host</code> is not
  832. * null and <code>host.length() </code> is not equal to zero, the
  833. * security manager's
  834. * <code>checkConnect</code> method is called
  835. * with the hostname and <code>-1</code>
  836. * as its arguments to see if the operation is allowed.
  837. *
  838. * @param host the name of the host, or <code>null</code>.
  839. * @return an array of all the IP addresses for a given host name.
  840. *
  841. * @exception UnknownHostException if no IP address for the
  842. * <code>host</code> could be found.
  843. * @exception SecurityException if a security manager exists and its
  844. * <code>checkConnect</code> method doesn't allow the operation.
  845. *
  846. * @see SecurityManager#checkConnect
  847. */
  848. public static InetAddress[] getAllByName(String host)
  849. throws UnknownHostException {
  850. if (host == null || host.length() == 0) {
  851. InetAddress[] ret = new InetAddress[1];
  852. ret[0] = impl.loopbackAddress();
  853. return ret;
  854. }
  855. boolean ipv6Expected = false;
  856. if (host.charAt(0) == '[') {
  857. // This is supposed to be an IPv6 litteral
  858. if (host.length() > 2 && host.charAt(host.length()-1) == ']') {
  859. host = host.substring(1, host.length() -1);
  860. ipv6Expected = true;
  861. } else {
  862. // This was supposed to be a IPv6 address, but it's not!
  863. throw new UnknownHostException(host);
  864. }
  865. }
  866. // if host is an IP address, we won't do further lookup
  867. if (Character.digit(host.charAt(0), 16) != -1
  868. || (host.charAt(0) == ':')) {
  869. byte[] addr = null;
  870. // see if it is IPv4 address
  871. addr = Inet4Address.textToNumericFormat(host);
  872. if (addr == null) {
  873. // see if it is IPv6 address
  874. addr = Inet6Address.textToNumericFormat(host);
  875. } else if (ipv6Expected) {
  876. // Means an IPv4 litteral between brackets!
  877. throw new UnknownHostException("["+host+"]");
  878. }
  879. InetAddress[] ret = new InetAddress[1];
  880. if(addr != null) {
  881. if (addr.length == Inet4Address.INADDRSZ) {
  882. ret[0] = new Inet4Address(null, addr);
  883. } else {
  884. ret[0] = new Inet6Address(null, addr);
  885. }
  886. return ret;
  887. }
  888. } else if (ipv6Expected) {
  889. // We were expecting an IPv6 Litteral, but got something else
  890. throw new UnknownHostException("["+host+"]");
  891. }
  892. return getAllByName0(host);
  893. }
  894. private static InetAddress[] getAllByName0 (String host)
  895. throws UnknownHostException
  896. {
  897. return getAllByName0(host, true);
  898. }
  899. /**
  900. * package private so SocketPermission can call it
  901. */
  902. static InetAddress[] getAllByName0 (String host, boolean check)
  903. throws UnknownHostException {
  904. /* If it gets here it is presumed to be a hostname */
  905. /* Cache.get can return: null, unknownAddress, or InetAddress[] */
  906. Object obj = null;
  907. Object objcopy = null;
  908. /* make sure the connection to the host is allowed, before we
  909. * give out a hostname
  910. */
  911. if (check) {
  912. SecurityManager security = System.getSecurityManager();
  913. if (security != null) {
  914. security.checkConnect(host, -1);
  915. }
  916. }
  917. obj = getCachedAddress(host);
  918. /* If no entry in cache, then do the host lookup */
  919. if (obj == null) {
  920. try {
  921. obj = getAddressFromNameService(host);
  922. } catch (UnknownHostException uhe) {
  923. throw new UnknownHostException(host + ": " + uhe.getMessage());
  924. }
  925. }
  926. if (obj == unknown_array)
  927. throw new UnknownHostException(host);
  928. /* Make a copy of the InetAddress array */
  929. objcopy = ((InetAddress [])obj).clone();
  930. return (InetAddress [])objcopy;
  931. }
  932. private static Object getAddressFromNameService(String host)
  933. throws UnknownHostException
  934. {
  935. Object obj = null;
  936. boolean success = false;
  937. // Check whether the host is in the lookupTable.
  938. // 1) If the host isn't in the lookupTable when
  939. // checkLookupTable() is called, checkLookupTable()
  940. // would add the host in the lookupTable and
  941. // return null. So we will do the lookup.
  942. // 2) If the host is in the lookupTable when
  943. // checkLookupTable() is called, the current thread
  944. // would be blocked until the host is removed
  945. // from the lookupTable. Then this thread
  946. // should try to look up the addressCache.
  947. // i) if it found the address in the
  948. // addressCache, checkLookupTable() would
  949. // return the address.
  950. // ii) if it didn't find the address in the
  951. // addressCache for any reason,
  952. // it should add the host in the
  953. // lookupTable and return null so the
  954. // following code would do a lookup itself.
  955. if ((obj = checkLookupTable(host)) == null) {
  956. // This is the first thread which looks up the address
  957. // this host or the cache entry for this host has been
  958. // expired so this thread should do the lookup.
  959. try {
  960. /*
  961. * Do not put the call to lookup() inside the
  962. * constructor. if you do you will still be
  963. * allocating space when the lookup fails.
  964. */
  965. byte[][] byte_array;
  966. byte_array = nameService.lookupAllHostAddr(host);
  967. InetAddress[] addr_array =
  968. new InetAddress[byte_array.length];
  969. for (int i = 0; i < byte_array.length; i++) {
  970. byte addr[] = byte_array[i];
  971. if (addr.length == Inet4Address.INADDRSZ) {
  972. addr_array[i] = new Inet4Address(host, addr);
  973. } else {
  974. addr_array[i] = new Inet6Address(host, addr);
  975. }
  976. }
  977. obj = addr_array;
  978. success = true;
  979. } catch (UnknownHostException uhe) {
  980. obj = unknown_array;
  981. success = false;
  982. throw uhe;
  983. } finally {
  984. // Cache the address.
  985. cacheAddress(host, obj, success);
  986. // Delete the host from the lookupTable, and
  987. // notify all threads waiting for the monitor
  988. // for lookupTable.
  989. updateLookupTable(host);
  990. }
  991. }
  992. return obj;
  993. }
  994. private static Object checkLookupTable(String host) {
  995. // make sure obj is null.
  996. Object obj = null;
  997. synchronized (lookupTable) {
  998. // If the host isn't in the lookupTable, add it in the
  999. // lookuptable and return null. The caller should do
  1000. // the lookup.
  1001. if (lookupTable.containsKey(host) == false) {
  1002. lookupTable.put(host, null);
  1003. return obj;
  1004. }
  1005. // If the host is in the lookupTable, it means that another
  1006. // thread is trying to look up the address of this host.
  1007. // This thread should wait.
  1008. while (lookupTable.containsKey(host)) {
  1009. try {
  1010. lookupTable.wait();
  1011. } catch (InterruptedException e) {
  1012. }
  1013. }
  1014. }
  1015. // The other thread has finished looking up the address of
  1016. // the host. This thread should retry to get the address
  1017. // from the addressCache. If it doesn't get the address from
  1018. // the cache, it will try to look up the address itself.
  1019. obj = getCachedAddress(host);
  1020. if (obj == null) {
  1021. synchronized (lookupTable) {
  1022. lookupTable.put(host, null);
  1023. }
  1024. }
  1025. return obj;
  1026. }
  1027. private static void updateLookupTable(String host) {
  1028. synchronized (lookupTable) {
  1029. lookupTable.remove(host);
  1030. lookupTable.notifyAll();
  1031. }
  1032. }
  1033. /**
  1034. * Returns an <code>InetAddress</code> object given the raw IP address .
  1035. * The argument is in network byte order: the highest order
  1036. * byte of the address is in <code>getAddress()[0]</code>.
  1037. *
  1038. * <p> This method doesn't block, i.e. no reverse name service lookup
  1039. * is performed.
  1040. *
  1041. * <p> IPv4 address byte array must be 4 bytes long and IPv6 byte array
  1042. * must be 16 bytes long
  1043. *
  1044. * @param addr the raw IP address in network byte order
  1045. * @return an InetAddress object created from the raw IP address.
  1046. * @exception UnknownHostException if IP address is of illegal length
  1047. * @since 1.4
  1048. */
  1049. public static InetAddress getByAddress(byte[] addr)
  1050. throws UnknownHostException {
  1051. return getByAddress(null, addr);
  1052. }
  1053. /**
  1054. * Returns the local host.
  1055. *
  1056. * <p>If there is a security manager, its
  1057. * <code>checkConnect</code> method is called
  1058. * with the local host name and <code>-1</code>
  1059. * as its arguments to see if the operation is allowed.
  1060. * If the operation is not allowed, an InetAddress representing
  1061. * the loopback address is returned.
  1062. *
  1063. * @return the IP address of the local host.
  1064. *
  1065. * @exception UnknownHostException if no IP address for the
  1066. * <code>host</code> could be found.
  1067. *
  1068. * @see SecurityManager#checkConnect
  1069. */
  1070. public static InetAddress getLocalHost() throws UnknownHostException {
  1071. SecurityManager security = System.getSecurityManager();
  1072. try {
  1073. String local = impl.getLocalHostName();
  1074. if (security != null) {
  1075. security.checkConnect(local, -1);
  1076. }
  1077. // we are calling getAddressFromNameService directly
  1078. // to avoid getting localHost from cache
  1079. InetAddress[] localAddrs;
  1080. try {
  1081. localAddrs =
  1082. (InetAddress[]) InetAddress.getAddressFromNameService(local);
  1083. } catch (UnknownHostException uhe) {
  1084. throw new UnknownHostException(local + ": " + uhe.getMessage());
  1085. }
  1086. return localAddrs[0];
  1087. } catch (java.lang.SecurityException e) {
  1088. return impl.loopbackAddress();
  1089. }
  1090. }
  1091. /**
  1092. * Perform class load-time initializations.
  1093. */
  1094. private static native void init();
  1095. /*
  1096. * Returns the InetAddress representing anyLocalAddress
  1097. * (typically 0.0.0.0 or ::0)
  1098. */
  1099. static InetAddress anyLocalAddress() {
  1100. return impl.anyLocalAddress();
  1101. }
  1102. /*
  1103. * Load and instantiate an underlying impl class
  1104. */
  1105. static Object loadImpl(String implName) {
  1106. Object impl;
  1107. /*
  1108. * Property "impl.prefix" will be prepended to the classname
  1109. * of the implementation object we instantiate, to which we
  1110. * delegate the real work (like native methods). This
  1111. * property can vary across implementations of the java.
  1112. * classes. The default is an empty String "".
  1113. */
  1114. String prefix = (String)AccessController.doPrivileged(
  1115. new GetPropertyAction("impl.prefix", ""));
  1116. impl = null;
  1117. try {
  1118. impl = Class.forName("java.net." + prefix + implName).newInstance();
  1119. } catch (ClassNotFoundException e) {
  1120. System.err.println("Class not found: java.net." + prefix +
  1121. implName + ":\ncheck impl.prefix property " +
  1122. "in your properties file.");
  1123. } catch (InstantiationException e) {
  1124. System.err.println("Could not instantiate: java.net." + prefix +
  1125. implName + ":\ncheck impl.prefix property " +
  1126. "in your properties file.");
  1127. } catch (IllegalAccessException e) {
  1128. System.err.println("Cannot access class: java.net." + prefix +
  1129. implName + ":\ncheck impl.prefix property " +
  1130. "in your properties file.");
  1131. }
  1132. if (impl == null) {
  1133. try {
  1134. impl = Class.forName(implName).newInstance();
  1135. } catch (Exception e) {
  1136. throw new Error("System property impl.prefix incorrect");
  1137. }
  1138. }
  1139. return impl;
  1140. }
  1141. }
  1142. /*
  1143. * Simple factory to create the impl
  1144. */
  1145. class InetAddressImplFactory {
  1146. static InetAddressImpl create() {
  1147. Object o;
  1148. if (isIPv6Supported()) {
  1149. o = InetAddress.loadImpl("Inet6AddressImpl");
  1150. } else {
  1151. o = InetAddress.loadImpl("Inet4AddressImpl");
  1152. }
  1153. return (InetAddressImpl)o;
  1154. }
  1155. private static native boolean isIPv6Supported();
  1156. }