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