1. /*
  2. * @(#)Inet6Address.java 1.25 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.security.AccessController;
  9. import java.io.ObjectInputStream;
  10. import java.io.IOException;
  11. import java.io.ObjectStreamException;
  12. import java.io.InvalidObjectException;
  13. import sun.security.action.*;
  14. /**
  15. * This class represents an Internet Protocol version 6 (IPv6) address.
  16. * Defined by <a href="http://www.ietf.org/rfc/rfc2373.txt">
  17. * <i>RFC 2373: IP Version 6 Addressing Architecture</i></a>.
  18. *
  19. * <h4> <A NAME="format">Textual representation of IP addresses<a> </h4>
  20. *
  21. * Textual representation of IPv6 address used as input to methods
  22. * takes one of the following forms:
  23. *
  24. * <ol>
  25. * <li><p> <A NAME="lform">The preferred form<a> is x:x:x:x:x:x:x:x, where the 'x's are
  26. * the hexadecimal values of the eight 16-bit pieces of the
  27. * address. This is the full form. For example,
  28. *
  29. * <blockquote><table cellpadding=0 cellspacing=0 summary="layout">
  30. * <tr><td><tt>1080:0:0:0:8:800:200C:417A</tt><td></tr>
  31. * </table></blockquote>
  32. *
  33. * <p> Note that it is not necessary to write the leading zeros in
  34. * an individual field. However, there must be at least one numeral
  35. * in every field, except as described below.</li>
  36. *
  37. * <li><p> Due to some methods of allocating certain styles of IPv6
  38. * addresses, it will be common for addresses to contain long
  39. * strings of zero bits. In order to make writing addresses
  40. * containing zero bits easier, a special syntax is available to
  41. * compress the zeros. The use of "::" indicates multiple groups
  42. * of 16-bits of zeros. The "::" can only appear once in an address.
  43. * The "::" can also be used to compress the leading and/or trailing
  44. * zeros in an address. For example,
  45. *
  46. * <blockquote><table cellpadding=0 cellspacing=0 summary="layout">
  47. * <tr><td><tt>1080::8:800:200C:417A</tt><td></tr>
  48. * </table></blockquote>
  49. *
  50. * <li><p> An alternative form that is sometimes more convenient
  51. * when dealing with a mixed environment of IPv4 and IPv6 nodes is
  52. * x:x:x:x:x:x:d.d.d.d, where the 'x's are the hexadecimal values
  53. * of the six high-order 16-bit pieces of the address, and the 'd's
  54. * are the decimal values of the four low-order 8-bit pieces of the
  55. * standard IPv4 representation address, for example,
  56. *
  57. * <blockquote><table cellpadding=0 cellspacing=0 summary="layout">
  58. * <tr><td><tt>::FFFF:129.144.52.38</tt><td></tr>
  59. * <tr><td><tt>::129.144.52.38</tt><td></tr>
  60. * </table></blockquote>
  61. *
  62. * <p> where "::FFFF:d.d.d.d" and "::d.d.d.d" are, respectively, the
  63. * general forms of an IPv4-mapped IPv6 address and an
  64. * IPv4-compatible IPv6 address. Note that the IPv4 portion must be
  65. * in the "d.d.d.d" form. The following forms are invalid:
  66. *
  67. * <blockquote><table cellpadding=0 cellspacing=0 summary="layout">
  68. * <tr><td><tt>::FFFF:d.d.d</tt><td></tr>
  69. * <tr><td><tt>::FFFF:d.d</tt><td></tr>
  70. * <tr><td><tt>::d.d.d</tt><td></tr>
  71. * <tr><td><tt>::d.d</tt><td></tr>
  72. * </table></blockquote>
  73. *
  74. * <p> The following form:
  75. *
  76. * <blockquote><table cellpadding=0 cellspacing=0 summary="layout">
  77. * <tr><td><tt>::FFFF:d</tt><td></tr>
  78. * </table></blockquote>
  79. *
  80. * <p> is valid, however it is an unconventional representation of
  81. * the IPv4-compatible IPv6 address,
  82. *
  83. * <blockquote><table cellpadding=0 cellspacing=0 summary="layout">
  84. * <tr><td><tt>::255.255.0.d</tt><td></tr>
  85. * </table></blockquote>
  86. *
  87. * <p> while "::d" corresponds to the general IPv6 address
  88. * "0:0:0:0:0:0:0:d".</li>
  89. * </ol>
  90. *
  91. * <p> For methods that return a textual representation as output
  92. * value, the full form is used. Inet6Address will return the full
  93. * form because it is unambiguous when used in combination with other
  94. * textual data.
  95. *
  96. * <h4> Special IPv6 address </h4>
  97. *
  98. * <blockquote>
  99. * <table cellspacing=2 summary="Description of IPv4-mapped address"> <tr><th valign=top><i>IPv4-mapped address</i></th>
  100. * <td>Of the form::ffff:w.x.y.z, this IPv6 address is used to
  101. * represent an IPv4 address. It allows the native program to
  102. * use the same address data structure and also the same
  103. * socket when communicating with both IPv4 and IPv6 nodes.
  104. *
  105. * <p>In InetAddress and Inet6Address, it is used for internal
  106. * representation; it has no functional role. Java will never
  107. * return an IPv4-mapped address. These classes can take an
  108. * IPv4-mapped address as input, both in byte array and text
  109. * representation. However, it will be converted into an IPv4
  110. * address.</td></tr>
  111. * </table></blockquote>
  112. */
  113. public final
  114. class Inet6Address extends InetAddress {
  115. final static int INADDRSZ = 16;
  116. /*
  117. * cached scope_id - for link-local address use only.
  118. */
  119. private transient int cached_scope_id = 0;
  120. /**
  121. * Holds a 128-bit (16 bytes) IPv6 address.
  122. *
  123. * @serial
  124. */
  125. byte[] ipaddress;
  126. private static final long serialVersionUID = 6880410070516793377L;
  127. /*
  128. * Perform initializations.
  129. */
  130. static {
  131. init();
  132. }
  133. Inet6Address() {
  134. super();
  135. hostName = null;
  136. ipaddress = new byte[INADDRSZ];
  137. family = IPv6;
  138. }
  139. Inet6Address(String hostName, byte addr[]) {
  140. this.hostName = hostName;
  141. if (addr.length == INADDRSZ) { // normal IPv6 address
  142. family = IPv6;
  143. ipaddress = (byte[])addr.clone();
  144. }
  145. }
  146. private void readObject(ObjectInputStream s)
  147. throws IOException, ClassNotFoundException {
  148. s.defaultReadObject();
  149. ipaddress = (byte[])ipaddress.clone();
  150. // Check that our invariants are satisfied
  151. if (ipaddress.length != INADDRSZ) {
  152. throw new InvalidObjectException("invalid address length: "+
  153. ipaddress.length);
  154. }
  155. if (family != IPv6) {
  156. throw new InvalidObjectException("invalid address family type");
  157. }
  158. }
  159. /**
  160. * Utility routine to check if the InetAddress is an IP multicast
  161. * address. 11111111 at the start of the address identifies the
  162. * address as being a multicast address.
  163. *
  164. * @return a <code>boolean</code> indicating if the InetAddress is
  165. * an IP multicast address
  166. * @since JDK1.1
  167. */
  168. public boolean isMulticastAddress() {
  169. return ((ipaddress[0] & 0xff) == 0xff);
  170. }
  171. /**
  172. * Utility routine to check if the InetAddress in a wildcard address.
  173. * @return a <code>boolean</code> indicating if the Inetaddress is
  174. * a wildcard address.
  175. * @since 1.4
  176. */
  177. public boolean isAnyLocalAddress() {
  178. byte test = 0x00;
  179. for (int i = 0; i < INADDRSZ; i++) {
  180. test |= ipaddress[i];
  181. }
  182. return (test == 0x00);
  183. }
  184. /**
  185. * Utility routine to check if the InetAddress is a loopback address.
  186. *
  187. * @return a <code>boolean</code> indicating if the InetAddress is
  188. * a loopback address; or false otherwise.
  189. * @since 1.4
  190. */
  191. public boolean isLoopbackAddress() {
  192. byte test = 0x00;
  193. for (int i = 0; i < 15; i++) {
  194. test |= ipaddress[i];
  195. }
  196. return (test == 0x00) && (ipaddress[15] == 0x01);
  197. }
  198. /**
  199. * Utility routine to check if the InetAddress is an link local address.
  200. *
  201. * @return a <code>boolean</code> indicating if the InetAddress is
  202. * a link local address; or false if address is not a link local unicast address.
  203. * @since 1.4
  204. */
  205. public boolean isLinkLocalAddress() {
  206. return ((ipaddress[0] & 0xff) == 0xfe
  207. && (ipaddress[1] & 0xc0) == 0x80);
  208. }
  209. /**
  210. * Utility routine to check if the InetAddress is a site local address.
  211. *
  212. * @return a <code>boolean</code> indicating if the InetAddress is
  213. * a site local address; or false if address is not a site local unicast address.
  214. * @since 1.4
  215. */
  216. public boolean isSiteLocalAddress() {
  217. return ((ipaddress[0] & 0xff) == 0xfe
  218. && (ipaddress[1] & 0xc0) == 0xc0);
  219. }
  220. /**
  221. * Utility routine to check if the multicast address has global scope.
  222. *
  223. * @return a <code>boolean</code> indicating if the address has
  224. * is a multicast address of global scope, false if it is not
  225. * of global scope or it is not a multicast address
  226. * @since 1.4
  227. */
  228. public boolean isMCGlobal() {
  229. return ((ipaddress[0] & 0xff) == 0xff
  230. && (ipaddress[1] & 0x0f) == 0x0e);
  231. }
  232. /**
  233. * Utility routine to check if the multicast address has node scope.
  234. *
  235. * @return a <code>boolean</code> indicating if the address has
  236. * is a multicast address of node-local scope, false if it is not
  237. * of node-local scope or it is not a multicast address
  238. * @since 1.4
  239. */
  240. public boolean isMCNodeLocal() {
  241. return ((ipaddress[0] & 0xff) == 0xff
  242. && (ipaddress[1] & 0x0f) == 0x01);
  243. }
  244. /**
  245. * Utility routine to check if the multicast address has link scope.
  246. *
  247. * @return a <code>boolean</code> indicating if the address has
  248. * is a multicast address of link-local scope, false if it is not
  249. * of link-local scope or it is not a multicast address
  250. * @since 1.4
  251. */
  252. public boolean isMCLinkLocal() {
  253. return ((ipaddress[0] & 0xff) == 0xff
  254. && (ipaddress[1] & 0x0f) == 0x02);
  255. }
  256. /**
  257. * Utility routine to check if the multicast address has site scope.
  258. *
  259. * @return a <code>boolean</code> indicating if the address has
  260. * is a multicast address of site-local scope, false if it is not
  261. * of site-local scope or it is not a multicast address
  262. * @since 1.4
  263. */
  264. public boolean isMCSiteLocal() {
  265. return ((ipaddress[0] & 0xff) == 0xff
  266. && (ipaddress[1] & 0x0f) == 0x05);
  267. }
  268. /**
  269. * Utility routine to check if the multicast address has organization scope.
  270. *
  271. * @return a <code>boolean</code> indicating if the address has
  272. * is a multicast address of organization-local scope,
  273. * false if it is not of organization-local scope
  274. * or it is not a multicast address
  275. * @since 1.4
  276. */
  277. public boolean isMCOrgLocal() {
  278. return ((ipaddress[0] & 0xff) == 0xff
  279. && (ipaddress[1] & 0x0f) == 0x08);
  280. }
  281. /**
  282. * Returns the raw IP address of this <code>InetAddress</code>
  283. * object. The result is in network byte order: the highest order
  284. * byte of the address is in <code>getAddress()[0]</code>.
  285. *
  286. * @return the raw IP address of this object.
  287. */
  288. public byte[] getAddress() {
  289. return (byte[])ipaddress.clone();
  290. }
  291. /**
  292. * Returns the IP address string in textual presentation.
  293. *
  294. * @return the raw IP address in a string format.
  295. */
  296. public String getHostAddress() {
  297. return numericToTextFormat(ipaddress);
  298. }
  299. /**
  300. * Returns a hashcode for this IP address.
  301. *
  302. * @return a hash code value for this IP address.
  303. */
  304. public int hashCode() {
  305. if (ipaddress != null) {
  306. int hash = 0;
  307. int i=0;
  308. while (i<INADDRSZ) {
  309. int j=0;
  310. int component=0;
  311. while (j<4 && i<INADDRSZ) {
  312. component = (component << 8) + ipaddress[i];
  313. j++;
  314. i++;
  315. }
  316. hash += component;
  317. }
  318. return hash;
  319. } else {
  320. return 0;
  321. }
  322. }
  323. /**
  324. * Compares this object against the specified object.
  325. * The result is <code>true</code> if and only if the argument is
  326. * not <code>null</code> and it represents the same IP address as
  327. * this object.
  328. * <p>
  329. * Two instances of <code>InetAddress</code> represent the same IP
  330. * address if the length of the byte arrays returned by
  331. * <code>getAddress</code> is the same for both, and each of the
  332. * array components is the same for the byte arrays.
  333. *
  334. * @param obj the object to compare against.
  335. * @return <code>true</code> if the objects are the same;
  336. * <code>false</code> otherwise.
  337. * @see java.net.InetAddress#getAddress()
  338. */
  339. public boolean equals(Object obj) {
  340. if (obj == null ||
  341. !(obj instanceof Inet6Address))
  342. return false;
  343. Inet6Address inetAddr = (Inet6Address)obj;
  344. for (int i = 0; i < INADDRSZ; i++) {
  345. if (ipaddress[i] != inetAddr.ipaddress[i])
  346. return false;
  347. }
  348. return true;
  349. }
  350. /**
  351. * Utility routine to check if the InetAddress is an
  352. * IPv4 mapped IPv6 address.
  353. *
  354. * @return a <code>boolean</code> indicating if the InetAddress is
  355. * an IPv4 mapped IPv6 address; or false if address is IPv4 address.
  356. */
  357. static boolean isIPv4MappedAddress(byte[] addr) {
  358. if (addr.length < INADDRSZ) {
  359. return false;
  360. }
  361. if ((addr[0] == 0x00) && (addr[1] == 0x00) &&
  362. (addr[2] == 0x00) && (addr[3] == 0x00) &&
  363. (addr[4] == 0x00) && (addr[5] == 0x00) &&
  364. (addr[6] == 0x00) && (addr[7] == 0x00) &&
  365. (addr[8] == 0x00) && (addr[9] == 0x00) &&
  366. (addr[10] == (byte)0xff) &&
  367. (addr[11] == (byte)0xff)) {
  368. return true;
  369. }
  370. return false;
  371. }
  372. static byte[] convertFromIPv4MappedAddress(byte[] addr) {
  373. if (isIPv4MappedAddress(addr)) {
  374. byte[] newAddr = new byte[Inet4Address.INADDRSZ];
  375. System.arraycopy(addr, 12, newAddr, 0, Inet4Address.INADDRSZ);
  376. return newAddr;
  377. }
  378. return null;
  379. }
  380. /**
  381. * Utility routine to check if the InetAddress is an
  382. * IPv4 compatible IPv6 address.
  383. *
  384. * @return a <code>boolean</code> indicating if the InetAddress is
  385. * an IPv4 compatible IPv6 address; or false if address is IPv4 address.
  386. * @since 1.4
  387. */
  388. public boolean isIPv4CompatibleAddress() {
  389. if ((ipaddress[0] == 0x00) && (ipaddress[1] == 0x00) &&
  390. (ipaddress[2] == 0x00) && (ipaddress[3] == 0x00) &&
  391. (ipaddress[4] == 0x00) && (ipaddress[5] == 0x00) &&
  392. (ipaddress[6] == 0x00) && (ipaddress[7] == 0x00) &&
  393. (ipaddress[8] == 0x00) && (ipaddress[9] == 0x00) &&
  394. (ipaddress[10] == 0x00) && (ipaddress[11] == 0x00)) {
  395. return true;
  396. }
  397. return false;
  398. }
  399. // Utilities
  400. private final static int INT16SZ = 2;
  401. /*
  402. * Convert IPv6 binary address into presentation (printable) format.
  403. *
  404. * @param src a byte array representing the IPv6 numeric address
  405. * @return a String representing an IPv6 address in
  406. * textual representation format
  407. * @since 1.4
  408. */
  409. static String numericToTextFormat(byte[] src)
  410. {
  411. StringBuffer sb = new StringBuffer(39);
  412. for (int i = 0; i < (INADDRSZ / INT16SZ); i++) {
  413. sb.append(Integer.toHexString(((src[i<<1]<<8) & 0xff00)
  414. | (src[(i<<1)+1] & 0xff)));
  415. if (i < (INADDRSZ / INT16SZ) -1 ) {
  416. sb.append(":");
  417. }
  418. }
  419. return sb.toString();
  420. }
  421. /*
  422. * Convert IPv6 presentation level address to network order binary form.
  423. * credit:
  424. * Converted from C code from Solaris 8 (inet_pton)
  425. *
  426. * @param src a String representing an IPv6 address in textual format
  427. * @return a byte array representing the IPv6 numeric address
  428. * @since 1.4
  429. */
  430. static byte[] textToNumericFormat(String src)
  431. {
  432. if (src.length() == 0) {
  433. return null;
  434. }
  435. int colonp;
  436. char ch;
  437. boolean saw_xdigit;
  438. int val;
  439. char[] srcb = src.toCharArray();
  440. byte[] dst = new byte[INADDRSZ];
  441. colonp = -1;
  442. int i = 0, j = 0;
  443. /* Leading :: requires some special handling. */
  444. if (srcb[i] == ':')
  445. if (srcb[++i] != ':')
  446. return null;
  447. int curtok = i;
  448. saw_xdigit = false;
  449. val = 0;
  450. while (i < srcb.length) {
  451. ch = srcb[i++];
  452. int chval = Character.digit(ch, 16);
  453. if (chval != -1) {
  454. val <<= 4;
  455. val |= chval;
  456. if (val > 0xffff)
  457. return null;
  458. saw_xdigit = true;
  459. continue;
  460. }
  461. if (ch == ':') {
  462. curtok = i;
  463. if (!saw_xdigit) {
  464. if (colonp != -1)
  465. return null;
  466. colonp = j;
  467. continue;
  468. } else if (i == srcb.length) {
  469. return null;
  470. }
  471. if (j + INT16SZ > INADDRSZ)
  472. return null;
  473. dst[j++] = (byte) ((val >> 8) & 0xff);
  474. dst[j++] = (byte) (val & 0xff);
  475. saw_xdigit = false;
  476. val = 0;
  477. continue;
  478. }
  479. if (ch == '.' && ((j + Inet4Address.INADDRSZ) <= INADDRSZ)) {
  480. byte[] v4addr = Inet4Address.textToNumericFormat(src.substring(curtok));
  481. if (v4addr == null) {
  482. return null;
  483. }
  484. for (int k = 0; k < Inet4Address.INADDRSZ; k++) {
  485. dst[j++] = v4addr[k];
  486. }
  487. saw_xdigit = false;
  488. break; /* '\0' was seen by inet_pton4(). */
  489. }
  490. return null;
  491. }
  492. if (saw_xdigit) {
  493. if (j + INT16SZ > INADDRSZ)
  494. return null;
  495. dst[j++] = (byte) ((val >> 8) & 0xff);
  496. dst[j++] = (byte) (val & 0xff);
  497. }
  498. if (colonp != -1) {
  499. int n = j - colonp;
  500. if (j == INADDRSZ)
  501. return null;
  502. for (i = 1; i <= n; i++) {
  503. dst[INADDRSZ - i] = dst[colonp + n - i];
  504. dst[colonp + n - i] = 0;
  505. }
  506. j = INADDRSZ;
  507. }
  508. if (j != INADDRSZ)
  509. return null;
  510. byte[] newdst = convertFromIPv4MappedAddress(dst);
  511. if (newdst != null) {
  512. return newdst;
  513. } else {
  514. return dst;
  515. }
  516. }
  517. /**
  518. * Perform class load-time initializations.
  519. */
  520. private static native void init();
  521. }