/* * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package java.net; import java.util.Arrays; import java.util.Enumeration; import java.util.NoSuchElementException; import java.util.Objects; import java.util.Spliterator; import java.util.Spliterators; import java.util.stream.Stream; import java.util.stream.StreamSupport; /** * This class represents a Network Interface. *
* A Network Interface is an abstraction encapsulating * the characteristics of a Network Interface Controller, or * Virtual Network adapter, which is a system hardware/software * component connecting a computer, or host system, to a computer * network. A Network Interface can be physical or virtual. * A Network Interface has a name, zero or more assigned * {@linkplain InetAddress IP addresses}, zero or more {@linkplain * InterfaceAddress MAC Addresses}, and may have an index. * The name is highly platform specific but a name such as "le0" * is typical; it may not be unique. The index is a highly platform * specific number that identifies the interface. The network * configuration may change during the lifetime of the JVM. * For example, the set of IP addresses assigned to a network * interface can be transient and dynamically allocated, and may * change at any time. *
* When obtaining a {@code NetworkInterface} instance, part of its * configuration (such as its name and the list of assigned IP addresses), * is reflective of its configuration at creation time. * Obtaining an updated view of the network configuration may require * looking up a network interface again in order to obtain a new instance. *
* Network interface instances are typically used to identify the local
* interface on which a multicast group is joined.
*
* @apiNote Several static methods in this class are
* factory methods, returning a new instance of a {@code NetworkInterface},
* reflecting the configuration at the time of instantiation.
* The network configuration may change at any time, and as such,
* these methods may need to be invoked again in order to obtain
* a more up-to-date view of the network interfaces.
* In particular, there is no guarantee that the same interface will be
* found at the same index, or that the same network addresses will be
* bound to the interface, if the network configuration of the system
* has changed.
*
* @since 1.4
*/
public final class NetworkInterface {
private String name;
private String displayName;
private int index;
private InetAddress addrs[];
private InterfaceAddress bindings[];
private NetworkInterface childs[];
private NetworkInterface parent = null;
private boolean virtual = false;
private static final NetworkInterface defaultInterface;
static {
jdk.internal.loader.BootLoader.loadLibrary("net");
init();
defaultInterface = DefaultInterface.getDefault();
}
/**
* Returns an NetworkInterface object with index set to 0 and name to null.
* Setting such an interface on a MulticastSocket will cause the
* kernel to choose one interface for sending multicast packets.
*
*/
NetworkInterface() {
}
NetworkInterface(String name, int index, InetAddress[] addrs) {
this.name = name;
this.index = index;
this.addrs = addrs;
}
/**
* Get the name of this network interface.
*
* @return the name of this network interface
*/
public String getName() {
return name;
}
/**
* Get an Enumeration with all, or a subset, of the InetAddresses bound to
* this network interface.
*
* @implNote
* The returned enumeration contains all, or a subset, of the InetAddresses that were
* bound to the interface at the time the {@linkplain #getNetworkInterfaces()
* interface configuration was read}
*
* @return an Enumeration object with all, or a subset, of the InetAddresses
* bound to this network interface
* @see #inetAddresses()
*/
public Enumeration
* If the specified IP address is bound to multiple network
* interfaces it is not defined which network interface is
* returned.
*
* @apiNote
* The returned interface instance may reflect a snapshot of the
* configuration taken at the time the instance is created.
* See the general discussion of {@linkplain NetworkInterface##lookup
* snapshots and configuration} for the semantics of the returned interface.
*
* @param addr
* The {@code InetAddress} to search with.
*
* @return A {@code NetworkInterface}
* or {@code null} if there is no network interface
* with the specified IP address.
*
* @throws SocketException
* If an I/O error occurs.
*
* @throws NullPointerException
* If the specified address is {@code null}.
*/
public static NetworkInterface getByInetAddress(InetAddress addr) throws SocketException {
if (addr == null) {
throw new NullPointerException();
}
if (addr.holder.family == InetAddress.IPv4) {
if (!(addr instanceof Inet4Address)) {
throw new IllegalArgumentException("invalid family type: "
+ addr.holder.family);
}
} else if (addr.holder.family == InetAddress.IPv6) {
if (!(addr instanceof Inet6Address)) {
throw new IllegalArgumentException("invalid family type: "
+ addr.holder.family);
}
} else {
throw new IllegalArgumentException("invalid address type: " + addr);
}
return getByInetAddress0(addr);
}
/**
* Returns an {@code Enumeration} of all the interfaces on this machine. The
* {@code Enumeration} contains at least one element, possibly representing
* a loopback interface that only supports communication between entities on
* this machine.
*
* @apiNote
* This method can be used in combination with
* {@link #getInetAddresses()} to obtain all IP addresses for this node.
*
* The returned interface instances may reflect a snapshot of the
* configuration taken at the time the instance is created.
* See the general discussion of {@linkplain NetworkInterface##lookup
* snapshots and configuration} for the semantics of the returned interface.
*
* @return an Enumeration of NetworkInterfaces found on this machine
* @throws SocketException if an I/O error occurs,
* or if the platform does not have at least one configured
* network interface.
* @see #networkInterfaces()
*/
public static Enumeration
* The returned interface instances may reflect a snapshot of the
* configuration taken at the time the instance is created.
* See the general discussion of {@linkplain NetworkInterface##lookup
* snapshots and configuration} for the semantics of the returned interface.
*
* @return a Stream of NetworkInterfaces found on this machine
* @throws SocketException if an I/O error occurs,
* or if the platform does not have at least one configured
* network interface.
* @since 9
*/
public static Stream
* Two instances of {@code NetworkInterface} represent the same
* NetworkInterface if both the name and the set of {@code InetAddress}es
* bound to the interfaces are equal.
*
* @apiNote two {@code NetworkInterface} objects referring to the same
* underlying interface may not compare equal if the addresses
* of the underlying interface are being dynamically updated by
* the system.
*
* @param obj the object to compare against.
* @return {@code true} if the objects are the same;
* {@code false} otherwise.
* @see java.net.InetAddress#getAddress()
*/
@Override
public boolean equals(Object obj) {
if (!(obj instanceof NetworkInterface that)) {
return false;
}
if (!Objects.equals(this.name, that.name)) {
return false;
}
if (this.addrs == null) {
return that.addrs == null;
} else if (that.addrs == null) {
return false;
}
/* Both addrs not null. Compare number of addresses */
if (this.addrs.length != that.addrs.length) {
return false;
}
for (InetAddress thisAddr : this.addrs) {
boolean found = false;
for (InetAddress thatAddr : that.addrs) {
if (thisAddr.equals(thatAddr)) {
found = true;
break;
}
}
if (!found) {
return false;
}
}
return true;
}
@Override
public int hashCode() {
return Objects.hashCode(name);
}
public String toString() {
String result = "name:";
result += name == null? "null": name;
if (displayName != null) {
result += " (" + displayName + ")";
}
return result;
}
private static native void init();
/**
* Returns the default network interface of this system
*
* @return the default interface
*/
static NetworkInterface getDefault() {
return defaultInterface;
}
}
{@code
* Stream
*