1. /*
  2. * @(#)Inet4Address.java 1.24 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.ObjectStreamException;
  10. import sun.security.action.*;
  11. /**
  12. * This class represents an Internet Protocol version 4 (IPv4) address.
  13. * Defined by <a href="http://www.ietf.org/rfc/rfc790.txt">
  14. * <i>RFC 790: Assigned Numbers</i></a>,
  15. * <a href="http://www.ietf.org/rfc/rfc1918.txt">
  16. * <i>RFC 1918: Address Allocation for Private Internets</i></a>,
  17. * and <a href="http://www.ietf.org/rfc/rfc2365.txt"><i>RFC 2365:
  18. * Administratively Scoped IP Multicast</i></a>
  19. *
  20. * <h4> <A NAME="format">Textual representation of IP addresses<a> </h4>
  21. *
  22. * Textual representation of IPv4 address used as input to methods
  23. * takes one of the following forms:
  24. *
  25. * <blockquote><table cellpadding=0 cellspacing=0 summary="layout">
  26. * <tr><td><tt>d.d.d.d</tt><td></tr>
  27. * <tr><td><tt>d.d.d</tt><td></tr>
  28. * <tr><td><tt>d.d</td></tr>
  29. * <tr><td><tt>d</td></tr>
  30. * </table></blockquote>
  31. *
  32. * <p> When four parts are specified, each is interpreted as a byte of
  33. * data and assigned, from left to right, to the four bytes of an IPv4
  34. * address.
  35. * <p> When a three part address is specified, the last part is
  36. * interpreted as a 16-bit quantity and placed in the right most two
  37. * bytes of the network address. This makes the three part address
  38. * format convenient for specifying Class B net- work addresses as
  39. * 128.net.host.
  40. *
  41. * <p> When a two part address is supplied, the last part is
  42. * interpreted as a 24-bit quantity and placed in the right most three
  43. * bytes of the network address. This makes the two part address
  44. * format convenient for specifying Class A network addresses as
  45. * net.host.
  46. *
  47. * <p> When only one part is given, the value is stored directly in
  48. * the network address without any byte rearrangement.
  49. *
  50. * <p> For methods that return a textual representation as output
  51. * value, the first form, i.e. a dotted-quad string, is used.
  52. *
  53. * <h4> The Scope of a Multicast Address </h4>
  54. *
  55. * Historically the IPv4 TTL field in the IP header has doubled as a
  56. * multicast scope field: a TTL of 0 means node-local, 1 means
  57. * link-local, up through 32 means site-local, up through 64 means
  58. * region-local, up through 128 means continent-local, and up through
  59. * 255 are global. However, the administrative scoping is preferred.
  60. * Please refer to <a href="http://www.ietf.org/rfc/rfc2365.txt">
  61. * <i>RFC 2365: Administratively Scoped IP Multicast</i></a>
  62. */
  63. public final
  64. class Inet4Address extends InetAddress {
  65. final static int INADDRSZ = 4;
  66. /** use serialVersionUID from InetAddress, but Inet4Address instance
  67. * is always replaced by an InetAddress instance before being
  68. * serialized */
  69. private static final long serialVersionUID = 3286316764910316507L;
  70. /*
  71. * Perform initializations.
  72. */
  73. static {
  74. init();
  75. }
  76. Inet4Address() {
  77. super();
  78. hostName = null;
  79. address = 0;
  80. family = IPv4;
  81. }
  82. Inet4Address(String hostName, byte addr[]) {
  83. this.hostName = hostName;
  84. this.family = IPv4;
  85. if (addr != null) {
  86. if (addr.length == INADDRSZ) {
  87. address = addr[3] & 0xFF;
  88. address |= ((addr[2] << 8) & 0xFF00);
  89. address |= ((addr[1] << 16) & 0xFF0000);
  90. address |= ((addr[0] << 24) & 0xFF000000);
  91. }
  92. }
  93. }
  94. Inet4Address(String hostName, int address) {
  95. this.hostName = hostName;
  96. this.family = IPv4;
  97. this.address = address;
  98. }
  99. /**
  100. * Replaces the object to be serialized with an InetAddress object.
  101. *
  102. * @return the alternate object to be serialized.
  103. *
  104. * @throws ObjectStreamException if a new object replacing this
  105. * object could not be created
  106. */
  107. private Object writeReplace() throws ObjectStreamException {
  108. // will replace the to be serialized 'this' object
  109. InetAddress inet = new InetAddress();
  110. inet.hostName = this.hostName;
  111. inet.address = this.address;
  112. /**
  113. * Prior to 1.4 an InetAddress was created with a family
  114. * based on the platform AF_INET value (usually 2).
  115. * For compatibility reasons we must therefore write the
  116. * the InetAddress with this family.
  117. */
  118. inet.family = 2;
  119. return inet;
  120. }
  121. /**
  122. * Utility routine to check if the InetAddress is an
  123. * IP multicast address. IP multicast address is a Class D
  124. * address i.e first four bits of the address are 1110.
  125. * @return a <code>boolean</code> indicating if the InetAddress is
  126. * an IP multicast address
  127. * @since JDK1.1
  128. */
  129. public boolean isMulticastAddress() {
  130. return ((address & 0xf0000000) == 0xe0000000);
  131. }
  132. /**
  133. * Utility routine to check if the InetAddress in a wildcard address.
  134. * @return a <code>boolean</code> indicating if the Inetaddress is
  135. * a wildcard address.
  136. * @since 1.4
  137. */
  138. public boolean isAnyLocalAddress() {
  139. return address == 0;
  140. }
  141. /**
  142. * Utility routine to check if the InetAddress is a loopback address.
  143. *
  144. * @return a <code>boolean</code> indicating if the InetAddress is
  145. * a loopback address; or false otherwise.
  146. * @since 1.4
  147. */
  148. private static final int loopback = 2130706433; /* 127.0.0.1 */
  149. public boolean isLoopbackAddress() {
  150. /* 127.x.x.x */
  151. byte[] byteAddr = getAddress();
  152. return byteAddr[0] == 127;
  153. }
  154. /**
  155. * Utility routine to check if the InetAddress is an link local address.
  156. *
  157. * @return a <code>boolean</code> indicating if the InetAddress is
  158. * a link local address; or false if address is not a link local unicast address.
  159. * @since 1.4
  160. */
  161. public boolean isLinkLocalAddress() {
  162. // link-local unicast in IPv4 (169.254.0.0/16)
  163. // defined in "Documenting Special Use IPv4 Address Blocks
  164. // that have been Registered with IANA" by Bill Manning
  165. // draft-manning-dsua-06.txt
  166. return (((address >>> 24) & 0xFF) == 169)
  167. && (((address >>> 16) & 0xFF) == 254);
  168. }
  169. /**
  170. * Utility routine to check if the InetAddress is a site local address.
  171. *
  172. * @return a <code>boolean</code> indicating if the InetAddress is
  173. * a site local address; or false if address is not a site local unicast address.
  174. * @since 1.4
  175. */
  176. public boolean isSiteLocalAddress() {
  177. // refer to RFC 1918
  178. // 10/8 prefix
  179. // 172.16/12 prefix
  180. // 192.168/16 prefix
  181. return (((address >>> 24) & 0xFF) == 10)
  182. || ((((address >>> 24) & 0xFF) == 172)
  183. && (((address >>> 16) & 0xF0) == 16))
  184. || ((((address >>> 24) & 0xFF) == 192)
  185. && (((address >>> 16) & 0xFF) == 168));
  186. }
  187. /**
  188. * Utility routine to check if the multicast address has global scope.
  189. *
  190. * @return a <code>boolean</code> indicating if the address has
  191. * is a multicast address of global scope, false if it is not
  192. * of global scope or it is not a multicast address
  193. * @since 1.4
  194. */
  195. public boolean isMCGlobal() {
  196. // 224.0.1.0 to 238.255.255.255
  197. byte[] byteAddr = getAddress();
  198. return ((byteAddr[0] & 0xff) >= 224 && (byteAddr[0] & 0xff) <= 238 ) &&
  199. !((byteAddr[0] & 0xff) == 224 && byteAddr[1] == 0 &&
  200. byteAddr[2] == 0);
  201. }
  202. /**
  203. * Utility routine to check if the multicast address has node scope.
  204. *
  205. * @return a <code>boolean</code> indicating if the address has
  206. * is a multicast address of node-local scope, false if it is not
  207. * of node-local scope or it is not a multicast address
  208. * @since 1.4
  209. */
  210. public boolean isMCNodeLocal() {
  211. // unless ttl == 0
  212. return false;
  213. }
  214. /**
  215. * Utility routine to check if the multicast address has link scope.
  216. *
  217. * @return a <code>boolean</code> indicating if the address has
  218. * is a multicast address of link-local scope, false if it is not
  219. * of link-local scope or it is not a multicast address
  220. * @since 1.4
  221. */
  222. public boolean isMCLinkLocal() {
  223. // 224.0.0/24 prefix and ttl == 1
  224. return (((address >>> 24) & 0xFF) == 224)
  225. && (((address >>> 16) & 0xFF) == 0)
  226. && (((address >>> 8) & 0xFF) == 0);
  227. }
  228. /**
  229. * Utility routine to check if the multicast address has site scope.
  230. *
  231. * @return a <code>boolean</code> indicating if the address has
  232. * is a multicast address of site-local scope, false if it is not
  233. * of site-local scope or it is not a multicast address
  234. * @since 1.4
  235. */
  236. public boolean isMCSiteLocal() {
  237. // 239.255/16 prefix or ttl < 32
  238. return (((address >>> 24) & 0xFF) == 239)
  239. && (((address >>> 16) & 0xFF) == 255);
  240. }
  241. /**
  242. * Utility routine to check if the multicast address has organization scope.
  243. *
  244. * @return a <code>boolean</code> indicating if the address has
  245. * is a multicast address of organization-local scope,
  246. * false if it is not of organization-local scope
  247. * or it is not a multicast address
  248. * @since 1.4
  249. */
  250. public boolean isMCOrgLocal() {
  251. // 239.192 - 239.195
  252. return (((address >>> 24) & 0xFF) == 239)
  253. && (((address >>> 16) & 0xFF) >= 192)
  254. && (((address >>> 16) & 0xFF) <= 195);
  255. }
  256. /**
  257. * Returns the raw IP address of this <code>InetAddress</code>
  258. * object. The result is in network byte order: the highest order
  259. * byte of the address is in <code>getAddress()[0]</code>.
  260. *
  261. * @return the raw IP address of this object.
  262. */
  263. public byte[] getAddress() {
  264. byte[] addr = new byte[INADDRSZ];
  265. addr[0] = (byte) ((address >>> 24) & 0xFF);
  266. addr[1] = (byte) ((address >>> 16) & 0xFF);
  267. addr[2] = (byte) ((address >>> 8) & 0xFF);
  268. addr[3] = (byte) (address & 0xFF);
  269. return addr;
  270. }
  271. /**
  272. * Returns the IP address string in textual presentation form.
  273. *
  274. * @return the raw IP address in a string format.
  275. * @since JDK1.0.2
  276. */
  277. public String getHostAddress() {
  278. return numericToTextFormat(getAddress());
  279. }
  280. /**
  281. * Returns a hashcode for this IP address.
  282. *
  283. * @return a hash code value for this IP address.
  284. */
  285. public int hashCode() {
  286. return address;
  287. }
  288. /**
  289. * Compares this object against the specified object.
  290. * The result is <code>true</code> if and only if the argument is
  291. * not <code>null</code> and it represents the same IP address as
  292. * this object.
  293. * <p>
  294. * Two instances of <code>InetAddress</code> represent the same IP
  295. * address if the length of the byte arrays returned by
  296. * <code>getAddress</code> is the same for both, and each of the
  297. * array components is the same for the byte arrays.
  298. *
  299. * @param obj the object to compare against.
  300. * @return <code>true</code> if the objects are the same;
  301. * <code>false</code> otherwise.
  302. * @see java.net.InetAddress#getAddress()
  303. */
  304. public boolean equals(Object obj) {
  305. return (obj != null) && (obj instanceof Inet4Address) &&
  306. (((InetAddress)obj).address == address);
  307. }
  308. // Utilities
  309. /*
  310. * Converts IPv4 binary address into a string suitable for presentation.
  311. *
  312. * @param src a byte array representing an IPv4 numeric address
  313. * @return a String representing the IPv4 address in
  314. * textual representation format
  315. * @since 1.4
  316. */
  317. static String numericToTextFormat(byte[] src)
  318. {
  319. return (src[0] & 0xff) + "." + (src[1] & 0xff) + "." + (src[2] & 0xff) + "." + (src[3] & 0xff);
  320. }
  321. /*
  322. * Converts IPv4 address in its textual presentation form
  323. * into its numeric binary form.
  324. *
  325. * @param src a String representing an IPv4 address in standard format
  326. * @return a byte array representing the IPv4 numeric address
  327. * @since 1.4
  328. */
  329. static byte[] textToNumericFormat(String src)
  330. {
  331. if (src.length() == 0) {
  332. return null;
  333. }
  334. int octets;
  335. char ch;
  336. byte[] dst = new byte[INADDRSZ];
  337. char[] srcb = src.toCharArray();
  338. boolean saw_digit = false;
  339. octets = 0;
  340. int i = 0;
  341. int cur = 0;
  342. while (i < srcb.length) {
  343. ch = srcb[i++];
  344. if (Character.isDigit(ch)) {
  345. // note that Java byte is signed, so need to convert to int
  346. int sum = (dst[cur] & 0xff)*10
  347. + (Character.digit(ch, 10) & 0xff);
  348. if (sum > 255)
  349. return null;
  350. dst[cur] = (byte)(sum & 0xff);
  351. if (! saw_digit) {
  352. if (++octets > INADDRSZ)
  353. return null;
  354. saw_digit = true;
  355. }
  356. } else if (ch == '.' && saw_digit) {
  357. if (octets == INADDRSZ)
  358. return null;
  359. cur++;
  360. dst[cur] = 0;
  361. saw_digit = false;
  362. } else
  363. return null;
  364. }
  365. if (octets < INADDRSZ)
  366. return null;
  367. return dst;
  368. }
  369. /**
  370. * Perform class load-time initializations.
  371. */
  372. private static native void init();
  373. }