001: /*
002: * @(#)NetworkInterface.java 1.18 06/10/10
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package java.net;
028:
029: import java.net.SocketException;
030: import java.util.Enumeration;
031: import java.util.NoSuchElementException;
032: import sun.security.action.*;
033: import java.security.AccessController;
034:
035: /**
036: * This class represents a Network Interface made up of a name,
037: * and a list of IP addresses assigned to this interface.
038: * It is used to identify the local interface on which a multicast group
039: * is joined.
040: *
041: * Interfaces are normally known by names such as "le0".
042: *
043: * @since 1.4
044: */
045: public final class NetworkInterface {
046: private String name;
047: private String displayName;
048: private int index;
049: private InetAddress addrs[];
050:
051: static {
052: AccessController.doPrivileged(new LoadLibraryAction("net"));
053: init();
054: }
055:
056: /**
057: * Returns an NetworkInterface object with index set to 0 and name to null.
058: * Setting such an interface on a MulticastSocket will cause the
059: * kernel to choose one interface for sending multicast packets.
060: *
061: */
062: NetworkInterface() {
063: }
064:
065: NetworkInterface(String name, int index, InetAddress[] addrs) {
066: this .name = name;
067: this .index = index;
068: this .addrs = addrs;
069: }
070:
071: /**
072: * Get the name of this network interface.
073: *
074: * @return the name of this network interface
075: */
076: public String getName() {
077: return name;
078: }
079:
080: /**
081: * Convenience method to return an Enumeration with all or a
082: * subset of the InetAddresses bound to this network interface.
083: * <p>
084: * If there is a security manager, its <code>checkConnect</code>
085: * method is called for each InetAddress. Only InetAddresses where
086: * the <code>checkConnect</code> doesn't throw a SecurityException
087: * will be returned in the Enumeration.
088: * @return an Enumeration object with all or a subset of the InetAddresses
089: * bound to this network interface
090: */
091: public Enumeration getInetAddresses() {
092:
093: class checkedAddresses implements Enumeration {
094:
095: private int i = 0, count = 0;
096: private Object local_addrs[];
097:
098: checkedAddresses() {
099: local_addrs = new Object[addrs.length];
100:
101: SecurityManager sec = System.getSecurityManager();
102: for (int j = 0; j < addrs.length; j++) {
103: try {
104: if (sec != null) {
105: sec.checkConnect(addrs[j].getHostAddress(),
106: -1);
107: }
108: local_addrs[count++] = addrs[j];
109: } catch (SecurityException e) {
110: }
111: }
112:
113: }
114:
115: public Object nextElement() {
116: if (i < count) {
117: return local_addrs[i++];
118: } else {
119: throw new NoSuchElementException();
120: }
121: }
122:
123: public boolean hasMoreElements() {
124: return (i < count);
125: }
126: }
127: return new checkedAddresses();
128:
129: }
130:
131: /**
132: * Get the index of this network interface.
133: *
134: * @return the index of this network interface
135: */
136: int getIndex() {
137: return index;
138: }
139:
140: /**
141: * Get the display name of this network interface.
142: * A display name is a human readable String describing the network
143: * device.
144: *
145: * @return the display name of this network interface,
146: * or null if no display name is available.
147: */
148: public String getDisplayName() {
149: return displayName;
150: }
151:
152: /**
153: * Searches for the network interface with the specified name.
154: *
155: * @param name
156: * The name of the network interface.
157: *
158: * @return A <tt>NetworkInterface</tt> with the specified name,
159: * or <tt>null</tt> if there is no network interface
160: * with the specified name.
161: *
162: * @throws SocketException
163: * If an I/O error occurs.
164: *
165: * @throws NullPointerException
166: * If the specified name is <tt>null</tt>.
167: */
168: public static NetworkInterface getByName(String name)
169: throws SocketException {
170: if (name == null)
171: throw new NullPointerException();
172: return getByName0(name);
173: }
174:
175: /**
176: * Get a network interface given its index.
177: *
178: * @param index an integer, the index of the interface
179: * @return the NetworkInterface obtained from its index
180: * @exception SocketException if an I/O error occurs.
181: */
182: native static NetworkInterface getByIndex(int index)
183: throws SocketException;
184:
185: /**
186: * Convenience method to search for a network interface that
187: * has the specified Internet Protocol (IP) address bound to
188: * it.
189: * <p>
190: * If the specified IP address is bound to multiple network
191: * interfaces it is not defined which network interface is
192: * returned.
193: *
194: * @param addr
195: * The <tt>InetAddress</tt> to search with.
196: *
197: * @return A <tt>NetworkInterface</tt>
198: * or <tt>null</tt> if there is no network interface
199: * with the specified IP address.
200: *
201: * @throws SocketException
202: * If an I/O error occurs.
203: *
204: * @throws NullPointerException
205: * If the specified address is <tt>null</tt>.
206: */
207: public static NetworkInterface getByInetAddress(InetAddress addr)
208: throws SocketException {
209: if (addr == null)
210: throw new NullPointerException();
211: return getByInetAddress0(addr);
212: }
213:
214: /**
215: * Returns all the interfaces on this machine. Returns null if no
216: * network interfaces could be found on this machine.
217: *
218: * NOTE: can use getNetworkInterfaces()+getInetAddresses()
219: * to obtain all IP addresses for this node
220: *
221: * @return an Enumeration of NetworkInterfaces found on this machine
222: * @exception SocketException if an I/O error occurs.
223: */
224:
225: public static Enumeration getNetworkInterfaces()
226: throws SocketException {
227: final NetworkInterface[] netifs = getAll();
228:
229: // specified to return null if no network interfaces
230: if (netifs == null)
231: return null;
232:
233: return new Enumeration() {
234: private int i = 0;
235:
236: public Object nextElement() {
237: if (netifs != null && i < netifs.length) {
238: NetworkInterface netif = netifs[i++];
239: return netif;
240: } else {
241: throw new NoSuchElementException();
242: }
243: }
244:
245: public boolean hasMoreElements() {
246: return (netifs != null && i < netifs.length);
247: }
248: };
249: }
250:
251: private native static NetworkInterface[] getAll()
252: throws SocketException;
253:
254: private native static NetworkInterface getByName0(String name)
255: throws SocketException;
256:
257: private native static NetworkInterface getByInetAddress0(
258: InetAddress addr) throws SocketException;
259:
260: /**
261: * Compares this object against the specified object.
262: * The result is <code>true</code> if and only if the argument is
263: * not <code>null</code> and it represents the same NetworkInterface
264: * as this object.
265: * <p>
266: * Two instances of <code>NetworkInterface</code> represent the same
267: * NetworkInterface if both name and addrs are the same for both.
268: *
269: * @param obj the object to compare against.
270: * @return <code>true</code> if the objects are the same;
271: * <code>false</code> otherwise.
272: * @see java.net.InetAddress#getAddress()
273: */
274: public boolean equals(Object obj) {
275: if ((obj == null) || !(obj instanceof NetworkInterface)) {
276: return false;
277: }
278: NetworkInterface netIF = (NetworkInterface) obj;
279: if (name != null) {
280: if (netIF.getName() != null) {
281: if (!name.equals(netIF.getName())) {
282: return false;
283: }
284: } else {
285: return false;
286: }
287: } else {
288: if (netIF.getName() != null) {
289: return false;
290: }
291: }
292: Enumeration newAddrs = netIF.getInetAddresses();
293: int i = 0;
294: for (i = 0; newAddrs.hasMoreElements(); newAddrs.nextElement(), i++)
295: ;
296: if (addrs == null) {
297: if (i != 0) {
298: return false;
299: }
300: } else {
301: /*
302: * Compare number of addresses (in the checked subset)
303: */
304: int count = 0;
305: Enumeration e = getInetAddresses();
306: for (; e.hasMoreElements(); count++) {
307: e.nextElement();
308: }
309: if (i != count) {
310: return false;
311: }
312: }
313: newAddrs = netIF.getInetAddresses();
314: for (; newAddrs.hasMoreElements();) {
315: boolean equal = false;
316: Enumeration this Addrs = getInetAddresses();
317: InetAddress newAddr = (InetAddress) newAddrs.nextElement();
318: for (; this Addrs.hasMoreElements();) {
319: InetAddress this Addr = (InetAddress) this Addrs
320: .nextElement();
321: if (this Addr.equals(newAddr)) {
322: equal = true;
323: }
324: }
325: if (!equal) {
326: return false;
327: }
328: }
329: return true;
330: }
331:
332: public int hashCode() {
333: int count = 0;
334: if (addrs != null) {
335: for (int i = 0; i < addrs.length; i++) {
336: count += addrs[i].hashCode();
337: }
338: }
339: return count;
340: }
341:
342: public String toString() {
343: String result = "name:";
344: result += name == null ? "null" : name;
345: if (displayName != null) {
346: result += " (" + displayName + ")";
347: }
348: result += " index: " + index + " addresses:\n";
349: for (Enumeration e = getInetAddresses(); e.hasMoreElements();) {
350: InetAddress addr = (InetAddress) e.nextElement();
351: result += addr + ";\n";
352: }
353: return result;
354: }
355:
356: private static native void init();
357:
358: }
|