blob: 8b2899c48d950df8cf5bd4602b92a6f47771b694 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package java.net;
27
28import java.net.SocketException;
29import java.util.Enumeration;
30import java.util.NoSuchElementException;
31import sun.security.action.*;
32import java.security.AccessController;
33
34/**
35 * This class represents a Network Interface made up of a name,
36 * and a list of IP addresses assigned to this interface.
37 * It is used to identify the local interface on which a multicast group
38 * is joined.
39 *
40 * Interfaces are normally known by names such as "le0".
41 *
42 * @since 1.4
43 */
44public final class NetworkInterface {
45 private String name;
46 private String displayName;
47 private int index;
48 private InetAddress addrs[];
49 private InterfaceAddress bindings[];
50 private NetworkInterface childs[];
51 private NetworkInterface parent = null;
52 private boolean virtual = false;
53
54 static {
55 AccessController.doPrivileged(new LoadLibraryAction("net"));
56 init();
57 }
58
59 /**
60 * Returns an NetworkInterface object with index set to 0 and name to null.
61 * Setting such an interface on a MulticastSocket will cause the
62 * kernel to choose one interface for sending multicast packets.
63 *
64 */
65 NetworkInterface() {
66 }
67
68 NetworkInterface(String name, int index, InetAddress[] addrs) {
69 this.name = name;
70 this.index = index;
71 this.addrs = addrs;
72 }
73
74 /**
75 * Get the name of this network interface.
76 *
77 * @return the name of this network interface
78 */
79 public String getName() {
80 return name;
81 }
82
83 /**
84 * Convenience method to return an Enumeration with all or a
85 * subset of the InetAddresses bound to this network interface.
86 * <p>
87 * If there is a security manager, its <code>checkConnect</code>
88 * method is called for each InetAddress. Only InetAddresses where
89 * the <code>checkConnect</code> doesn't throw a SecurityException
90 * will be returned in the Enumeration.
91 * @return an Enumeration object with all or a subset of the InetAddresses
92 * bound to this network interface
93 */
94 public Enumeration<InetAddress> getInetAddresses() {
95
96 class checkedAddresses implements Enumeration<InetAddress> {
97
98 private int i=0, count=0;
99 private InetAddress local_addrs[];
100
101 checkedAddresses() {
102 local_addrs = new InetAddress[addrs.length];
103
104 SecurityManager sec = System.getSecurityManager();
105 for (int j=0; j<addrs.length; j++) {
106 try {
107 if (sec != null) {
108 sec.checkConnect(addrs[j].getHostAddress(), -1);
109 }
110 local_addrs[count++] = addrs[j];
111 } catch (SecurityException e) { }
112 }
113
114 }
115
116 public InetAddress nextElement() {
117 if (i < count) {
118 return local_addrs[i++];
119 } else {
120 throw new NoSuchElementException();
121 }
122 }
123
124 public boolean hasMoreElements() {
125 return (i < count);
126 }
127 }
128 return new checkedAddresses();
129
130 }
131
132 /**
133 * Get a List of all or a subset of the <code>InterfaceAddresses</code>
134 * of this network interface.
135 * <p>
136 * If there is a security manager, its <code>checkConnect</code>
137 * method is called with the InetAddress for each InterfaceAddress.
138 * Only InterfaceAddresses where the <code>checkConnect</code> doesn't throw
139 * a SecurityException will be returned in the List.
140 *
141 * @return a <code>List</code> object with all or a subset of the
142 * InterfaceAddresss of this network interface
143 * @since 1.6
144 */
145 public java.util.List<InterfaceAddress> getInterfaceAddresses() {
146 java.util.List<InterfaceAddress> lst = new java.util.ArrayList<InterfaceAddress>(1);
147 SecurityManager sec = System.getSecurityManager();
148 for (int j=0; j<bindings.length; j++) {
149 try {
150 if (sec != null) {
151 sec.checkConnect(bindings[j].getAddress().getHostAddress(), -1);
152 }
153 lst.add(bindings[j]);
154 } catch (SecurityException e) { }
155 }
156 return lst;
157 }
158
159 /**
160 * Get an Enumeration with all the subinterfaces (also known as virtual
161 * interfaces) attached to this network interface.
162 * <p>
163 * For instance eth0:1 will be a subinterface to eth0.
164 *
165 * @return an Enumeration object with all of the subinterfaces
166 * of this network interface
167 * @since 1.6
168 */
169 public Enumeration<NetworkInterface> getSubInterfaces() {
170 class subIFs implements Enumeration<NetworkInterface> {
171
172 private int i=0;
173
174 subIFs() {
175 }
176
177 public NetworkInterface nextElement() {
178 if (i < childs.length) {
179 return childs[i++];
180 } else {
181 throw new NoSuchElementException();
182 }
183 }
184
185 public boolean hasMoreElements() {
186 return (i < childs.length);
187 }
188 }
189 return new subIFs();
190
191 }
192
193 /**
194 * Returns the parent NetworkInterface of this interface if this is
195 * a subinterface, or <code>null</code> if it is a physical
196 * (non virtual) interface or has no parent.
197 *
198 * @return The <code>NetworkInterface</code> this interface is attached to.
199 * @since 1.6
200 */
201 public NetworkInterface getParent() {
202 return parent;
203 }
204
205 /**
206 * Get the index of this network interface.
207 *
208 * @return the index of this network interface
209 */
210 int getIndex() {
211 return index;
212 }
213
214 /**
215 * Get the display name of this network interface.
216 * A display name is a human readable String describing the network
217 * device.
218 *
219 * @return the display name of this network interface,
220 * or null if no display name is available.
221 */
222 public String getDisplayName() {
223 return displayName;
224 }
225
226 /**
227 * Searches for the network interface with the specified name.
228 *
229 * @param name
230 * The name of the network interface.
231 *
232 * @return A <tt>NetworkInterface</tt> with the specified name,
233 * or <tt>null</tt> if there is no network interface
234 * with the specified name.
235 *
236 * @throws SocketException
237 * If an I/O error occurs.
238 *
239 * @throws NullPointerException
240 * If the specified name is <tt>null</tt>.
241 */
242 public static NetworkInterface getByName(String name) throws SocketException {
243 if (name == null)
244 throw new NullPointerException();
245 return getByName0(name);
246 }
247
248 /**
249 * Get a network interface given its index.
250 *
251 * @param index an integer, the index of the interface
252 * @return the NetworkInterface obtained from its index
253 * @exception SocketException if an I/O error occurs.
254 */
255 native static NetworkInterface getByIndex(int index)
256 throws SocketException;
257
258 /**
259 * Convenience method to search for a network interface that
260 * has the specified Internet Protocol (IP) address bound to
261 * it.
262 * <p>
263 * If the specified IP address is bound to multiple network
264 * interfaces it is not defined which network interface is
265 * returned.
266 *
267 * @param addr
268 * The <tt>InetAddress</tt> to search with.
269 *
270 * @return A <tt>NetworkInterface</tt>
271 * or <tt>null</tt> if there is no network interface
272 * with the specified IP address.
273 *
274 * @throws SocketException
275 * If an I/O error occurs.
276 *
277 * @throws NullPointerException
278 * If the specified address is <tt>null</tt>.
279 */
280 public static NetworkInterface getByInetAddress(InetAddress addr) throws SocketException {
281 if (addr == null)
282 throw new NullPointerException();
283 return getByInetAddress0(addr);
284 }
285
286 /**
287 * Returns all the interfaces on this machine. Returns null if no
288 * network interfaces could be found on this machine.
289 *
290 * NOTE: can use getNetworkInterfaces()+getInetAddresses()
291 * to obtain all IP addresses for this node
292 *
293 * @return an Enumeration of NetworkInterfaces found on this machine
294 * @exception SocketException if an I/O error occurs.
295 */
296
297 public static Enumeration<NetworkInterface> getNetworkInterfaces()
298 throws SocketException {
299 final NetworkInterface[] netifs = getAll();
300
301 // specified to return null if no network interfaces
302 if (netifs == null)
303 return null;
304
305 return new Enumeration<NetworkInterface>() {
306 private int i = 0;
307 public NetworkInterface nextElement() {
308 if (netifs != null && i < netifs.length) {
309 NetworkInterface netif = netifs[i++];
310 return netif;
311 } else {
312 throw new NoSuchElementException();
313 }
314 }
315
316 public boolean hasMoreElements() {
317 return (netifs != null && i < netifs.length);
318 }
319 };
320 }
321
322 private native static NetworkInterface[] getAll()
323 throws SocketException;
324
325 private native static NetworkInterface getByName0(String name)
326 throws SocketException;
327
328 private native static NetworkInterface getByInetAddress0(InetAddress addr)
329 throws SocketException;
330
331 /**
332 * Returns whether a network interface is up and running.
333 *
334 * @return <code>true</code> if the interface is up and running.
335 * @exception SocketException if an I/O error occurs.
336 * @since 1.6
337 */
338
339 public boolean isUp() throws SocketException {
340 return isUp0(name, index);
341 }
342
343 /**
344 * Returns whether a network interface is a loopback interface.
345 *
346 * @return <code>true</code> if the interface is a loopback interface.
347 * @exception SocketException if an I/O error occurs.
348 * @since 1.6
349 */
350
351 public boolean isLoopback() throws SocketException {
352 return isLoopback0(name, index);
353 }
354
355 /**
356 * Returns whether a network interface is a point to point interface.
357 * A typical point to point interface would be a PPP connection through
358 * a modem.
359 *
360 * @return <code>true</code> if the interface is a point to point
361 * interface.
362 * @exception SocketException if an I/O error occurs.
363 * @since 1.6
364 */
365
366 public boolean isPointToPoint() throws SocketException {
367 return isP2P0(name, index);
368 }
369
370 /**
371 * Returns whether a network interface supports multicasting or not.
372 *
373 * @return <code>true</code> if the interface supports Multicasting.
374 * @exception SocketException if an I/O error occurs.
375 * @since 1.6
376 */
377
378 public boolean supportsMulticast() throws SocketException {
379 return supportsMulticast0(name, index);
380 }
381
382 /**
383 * Returns the hardware address (usually MAC) of the interface if it
384 * has one and if it can be accessed given the current privileges.
385 *
386 * @return a byte array containing the address or <code>null</code> if
387 * the address doesn't exist or is not accessible.
388 * @exception SocketException if an I/O error occurs.
389 * @since 1.6
390 */
391 public byte[] getHardwareAddress() throws SocketException {
392 for (InetAddress addr : addrs) {
393 if (addr instanceof Inet4Address) {
394 return getMacAddr0(((Inet4Address)addr).getAddress(), name, index);
395 }
396 }
397 return getMacAddr0(null, name, index);
398 }
399
400 /**
401 * Returns the Maximum Transmission Unit (MTU) of this interface.
402 *
403 * @return the value of the MTU for that interface.
404 * @exception SocketException if an I/O error occurs.
405 * @since 1.6
406 */
407 public int getMTU() throws SocketException {
408 return getMTU0(name, index);
409 }
410
411 /**
412 * Returns whether this interface is a virtual interface (also called
413 * subinterface).
414 * Virtual interfaces are, on some systems, interfaces created as a child
415 * of a physical interface and given different settings (like address or
416 * MTU). Usually the name of the interface will the name of the parent
417 * followed by a colon (:) and a number identifying the child since there
418 * can be several virtual interfaces attached to a single physical
419 * interface.
420 *
421 * @return <code>true</code> if this interface is a virtual interface.
422 * @since 1.6
423 */
424 public boolean isVirtual() {
425 return virtual;
426 }
427
428 private native static long getSubnet0(String name, int ind) throws SocketException;
429 private native static Inet4Address getBroadcast0(String name, int ind) throws SocketException;
430 private native static boolean isUp0(String name, int ind) throws SocketException;
431 private native static boolean isLoopback0(String name, int ind) throws SocketException;
432 private native static boolean supportsMulticast0(String name, int ind) throws SocketException;
433 private native static boolean isP2P0(String name, int ind) throws SocketException;
434 private native static byte[] getMacAddr0(byte[] inAddr, String name, int ind) throws SocketException;
435 private native static int getMTU0(String name, int ind) throws SocketException;
436
437 /**
438 * Compares this object against the specified object.
439 * The result is <code>true</code> if and only if the argument is
440 * not <code>null</code> and it represents the same NetworkInterface
441 * as this object.
442 * <p>
443 * Two instances of <code>NetworkInterface</code> represent the same
444 * NetworkInterface if both name and addrs are the same for both.
445 *
446 * @param obj the object to compare against.
447 * @return <code>true</code> if the objects are the same;
448 * <code>false</code> otherwise.
449 * @see java.net.InetAddress#getAddress()
450 */
451 public boolean equals(Object obj) {
452 if ((obj == null) || !(obj instanceof NetworkInterface)) {
453 return false;
454 }
455 NetworkInterface netIF = (NetworkInterface)obj;
456 if (name != null ) {
457 if (netIF.getName() != null) {
458 if (!name.equals(netIF.getName())) {
459 return false;
460 }
461 } else {
462 return false;
463 }
464 } else {
465 if (netIF.getName() != null) {
466 return false;
467 }
468 }
469 Enumeration newAddrs = netIF.getInetAddresses();
470 int i = 0;
471 for (i = 0; newAddrs.hasMoreElements();newAddrs.nextElement(), i++);
472 if (addrs == null) {
473 if (i != 0) {
474 return false;
475 }
476 } else {
477 /*
478 * Compare number of addresses (in the checked subset)
479 */
480 int count = 0;
481 Enumeration e = getInetAddresses();
482 for (; e.hasMoreElements(); count++) {
483 e.nextElement();
484 }
485 if (i != count) {
486 return false;
487 }
488 }
489 newAddrs = netIF.getInetAddresses();
490 for (; newAddrs.hasMoreElements();) {
491 boolean equal = false;
492 Enumeration thisAddrs = getInetAddresses();
493 InetAddress newAddr = (InetAddress)newAddrs.nextElement();
494 for (; thisAddrs.hasMoreElements();) {
495 InetAddress thisAddr = (InetAddress)thisAddrs.nextElement();
496 if (thisAddr.equals(newAddr)) {
497 equal = true;
498 }
499 }
500 if (!equal) {
501 return false;
502 }
503 }
504 return true;
505 }
506
507 public int hashCode() {
508 int count = 0;
509 if (addrs != null) {
510 for (int i = 0; i < addrs.length; i++) {
511 count += addrs[i].hashCode();
512 }
513 }
514 return count;
515 }
516
517 public String toString() {
518 String result = "name:";
519 result += name == null? "null": name;
520 if (displayName != null) {
521 result += " (" + displayName + ")";
522 }
523 result += " index: "+index+" addresses:\n";
524 for (Enumeration e = getInetAddresses(); e.hasMoreElements(); ) {
525 InetAddress addr = (InetAddress)e.nextElement();
526 result += addr+";\n";
527 }
528 return result;
529 }
530 private static native void init();
531
532}