1. /*
  2. * @(#)NetworkInterface.java 1.17 04/05/05
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.net;
  8. import java.net.SocketException;
  9. import java.util.Enumeration;
  10. import java.util.NoSuchElementException;
  11. import sun.security.action.*;
  12. import java.security.AccessController;
  13. /**
  14. * This class represents a Network Interface made up of a name,
  15. * and a list of IP addresses assigned to this interface.
  16. * It is used to identify the local interface on which a multicast group
  17. * is joined.
  18. *
  19. * Interfaces are normally known by names such as "le0".
  20. *
  21. * @since 1.4
  22. */
  23. public final class NetworkInterface {
  24. private String name;
  25. private String displayName;
  26. private int index;
  27. private InetAddress addrs[];
  28. static {
  29. AccessController.doPrivileged(new LoadLibraryAction("net"));
  30. init();
  31. }
  32. /**
  33. * Returns an NetworkInterface object with index set to 0 and name to null.
  34. * Setting such an interface on a MulticastSocket will cause the
  35. * kernel to choose one interface for sending multicast packets.
  36. *
  37. */
  38. NetworkInterface() {
  39. }
  40. NetworkInterface(String name, int index, InetAddress[] addrs) {
  41. this.name = name;
  42. this.index = index;
  43. this.addrs = addrs;
  44. }
  45. /**
  46. * Get the name of this network interface.
  47. *
  48. * @return the name of this network interface
  49. */
  50. public String getName() {
  51. return name;
  52. }
  53. /**
  54. * Convenience method to return an Enumeration with all or a
  55. * subset of the InetAddresses bound to this network interface.
  56. * <p>
  57. * If there is a security manager, its <code>checkConnect</code>
  58. * method is called for each InetAddress. Only InetAddresses where
  59. * the <code>checkConnect</code> doesn't throw a SecurityException
  60. * will be returned in the Enumeration.
  61. * @return an Enumeration object with all or a subset of the InetAddresses
  62. * bound to this network interface
  63. */
  64. public Enumeration<InetAddress> getInetAddresses() {
  65. class checkedAddresses implements Enumeration<InetAddress> {
  66. private int i=0, count=0;
  67. private InetAddress local_addrs[];
  68. checkedAddresses() {
  69. local_addrs = new InetAddress[addrs.length];
  70. SecurityManager sec = System.getSecurityManager();
  71. for (int j=0; j<addrs.length; j++) {
  72. try {
  73. if (sec != null) {
  74. sec.checkConnect(addrs[j].getHostAddress(), -1);
  75. }
  76. local_addrs[count++] = addrs[j];
  77. } catch (SecurityException e) { }
  78. }
  79. }
  80. public InetAddress nextElement() {
  81. if (i < count) {
  82. return local_addrs[i++];
  83. } else {
  84. throw new NoSuchElementException();
  85. }
  86. }
  87. public boolean hasMoreElements() {
  88. return (i < count);
  89. }
  90. }
  91. return new checkedAddresses();
  92. }
  93. /**
  94. * Get the index of this network interface.
  95. *
  96. * @return the index of this network interface
  97. */
  98. int getIndex() {
  99. return index;
  100. }
  101. /**
  102. * Get the display name of this network interface.
  103. * A display name is a human readable String describing the network
  104. * device.
  105. *
  106. * @return the display name of this network interface,
  107. * or null if no display name is available.
  108. */
  109. public String getDisplayName() {
  110. return displayName;
  111. }
  112. /**
  113. * Searches for the network interface with the specified name.
  114. *
  115. * @param name
  116. * The name of the network interface.
  117. *
  118. * @return A <tt>NetworkInterface</tt> with the specified name,
  119. * or <tt>null</tt> if there is no network interface
  120. * with the specified name.
  121. *
  122. * @throws SocketException
  123. * If an I/O error occurs.
  124. *
  125. * @throws NullPointerException
  126. * If the specified name is <tt>null</tt>.
  127. */
  128. public static NetworkInterface getByName(String name) throws SocketException {
  129. if (name == null)
  130. throw new NullPointerException();
  131. return getByName0(name);
  132. }
  133. /**
  134. * Get a network interface given its index.
  135. *
  136. * @param index an integer, the index of the interface
  137. * @return the NetworkInterface obtained from its index
  138. * @exception SocketException if an I/O error occurs.
  139. */
  140. native static NetworkInterface getByIndex(int index)
  141. throws SocketException;
  142. /**
  143. * Convenience method to search for a network interface that
  144. * has the specified Internet Protocol (IP) address bound to
  145. * it.
  146. * <p>
  147. * If the specified IP address is bound to multiple network
  148. * interfaces it is not defined which network interface is
  149. * returned.
  150. *
  151. * @param addr
  152. * The <tt>InetAddress</tt> to search with.
  153. *
  154. * @return A <tt>NetworkInterface</tt>
  155. * or <tt>null</tt> if there is no network interface
  156. * with the specified IP address.
  157. *
  158. * @throws SocketException
  159. * If an I/O error occurs.
  160. *
  161. * @throws NullPointerException
  162. * If the specified address is <tt>null</tt>.
  163. */
  164. public static NetworkInterface getByInetAddress(InetAddress addr) throws SocketException {
  165. if (addr == null)
  166. throw new NullPointerException();
  167. return getByInetAddress0(addr);
  168. }
  169. /**
  170. * Returns all the interfaces on this machine. Returns null if no
  171. * network interfaces could be found on this machine.
  172. *
  173. * NOTE: can use getNetworkInterfaces()+getInetAddresses()
  174. * to obtain all IP addresses for this node
  175. *
  176. * @return an Enumeration of NetworkInterfaces found on this machine
  177. * @exception SocketException if an I/O error occurs.
  178. */
  179. public static Enumeration<NetworkInterface> getNetworkInterfaces()
  180. throws SocketException {
  181. final NetworkInterface[] netifs = getAll();
  182. // specified to return null if no network interfaces
  183. if (netifs == null)
  184. return null;
  185. return new Enumeration<NetworkInterface>() {
  186. private int i = 0;
  187. public NetworkInterface nextElement() {
  188. if (netifs != null && i < netifs.length) {
  189. NetworkInterface netif = netifs[i++];
  190. return netif;
  191. } else {
  192. throw new NoSuchElementException();
  193. }
  194. }
  195. public boolean hasMoreElements() {
  196. return (netifs != null && i < netifs.length);
  197. }
  198. };
  199. }
  200. private native static NetworkInterface[] getAll()
  201. throws SocketException;
  202. private native static NetworkInterface getByName0(String name)
  203. throws SocketException;
  204. private native static NetworkInterface getByInetAddress0(InetAddress addr)
  205. throws SocketException;
  206. /**
  207. * Compares this object against the specified object.
  208. * The result is <code>true</code> if and only if the argument is
  209. * not <code>null</code> and it represents the same NetworkInterface
  210. * as this object.
  211. * <p>
  212. * Two instances of <code>NetworkInterface</code> represent the same
  213. * NetworkInterface if both name and addrs are the same for both.
  214. *
  215. * @param obj the object to compare against.
  216. * @return <code>true</code> if the objects are the same;
  217. * <code>false</code> otherwise.
  218. * @see java.net.InetAddress#getAddress()
  219. */
  220. public boolean equals(Object obj) {
  221. if ((obj == null) || !(obj instanceof NetworkInterface)) {
  222. return false;
  223. }
  224. NetworkInterface netIF = (NetworkInterface)obj;
  225. if (name != null ) {
  226. if (netIF.getName() != null) {
  227. if (!name.equals(netIF.getName())) {
  228. return false;
  229. }
  230. } else {
  231. return false;
  232. }
  233. } else {
  234. if (netIF.getName() != null) {
  235. return false;
  236. }
  237. }
  238. Enumeration newAddrs = netIF.getInetAddresses();
  239. int i = 0;
  240. for (i = 0; newAddrs.hasMoreElements();newAddrs.nextElement(), i++);
  241. if (addrs == null) {
  242. if (i != 0) {
  243. return false;
  244. }
  245. } else {
  246. /*
  247. * Compare number of addresses (in the checked subset)
  248. */
  249. int count = 0;
  250. Enumeration e = getInetAddresses();
  251. for (; e.hasMoreElements(); count++) {
  252. e.nextElement();
  253. }
  254. if (i != count) {
  255. return false;
  256. }
  257. }
  258. newAddrs = netIF.getInetAddresses();
  259. for (; newAddrs.hasMoreElements();) {
  260. boolean equal = false;
  261. Enumeration thisAddrs = getInetAddresses();
  262. InetAddress newAddr = (InetAddress)newAddrs.nextElement();
  263. for (; thisAddrs.hasMoreElements();) {
  264. InetAddress thisAddr = (InetAddress)thisAddrs.nextElement();
  265. if (thisAddr.equals(newAddr)) {
  266. equal = true;
  267. }
  268. }
  269. if (!equal) {
  270. return false;
  271. }
  272. }
  273. return true;
  274. }
  275. public int hashCode() {
  276. int count = 0;
  277. if (addrs != null) {
  278. for (int i = 0; i < addrs.length; i++) {
  279. count += addrs[i].hashCode();
  280. }
  281. }
  282. return count;
  283. }
  284. public String toString() {
  285. String result = "name:";
  286. result += name == null? "null": name;
  287. if (displayName != null) {
  288. result += " (" + displayName + ")";
  289. }
  290. result += " index: "+index+" addresses:\n";
  291. for (Enumeration e = getInetAddresses(); e.hasMoreElements(); ) {
  292. InetAddress addr = (InetAddress)e.nextElement();
  293. result += addr+";\n";
  294. }
  295. return result;
  296. }
  297. private static native void init();
  298. }