Con todas las posibles soluciones que he encontrado aquí y otro responde, entonces voy a aportar mi solución. Debe especificar un parámetro con una cadena que contenga "ip" o "mac" dependiendo de lo que necesite verificar. Si la computadora no tiene interfaz, devolverá una Cadena que contenga nulo; de lo contrario, devolverá una Cadena que contenga lo que solicitó (la dirección IP o el mac).
Cómo se usa:
System.out.println("Ip: " + GetNetworkAddress.GetAddress("ip"));
System.out.println("Mac: " + GetNetworkAddress.GetAddress("mac"));
resultado (si el equipo tiene una tarjeta de red):
Ip: 192.168.0.10
Mac: 0D-73-ED-0A-27-44
resultado (si el equipo no tiene una tarjeta de red):
Ip: null
Mac: null
Aquí está el código:
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Enumeration;
public class GetNetworkAddress {
public static String GetAddress(String addressType) {
String address = "";
InetAddress lanIp = null;
try {
String ipAddress = null;
Enumeration<NetworkInterface> net = null;
net = NetworkInterface.getNetworkInterfaces();
while (net.hasMoreElements()) {
NetworkInterface element = net.nextElement();
Enumeration<InetAddress> addresses = element.getInetAddresses();
while (addresses.hasMoreElements() && element.getHardwareAddress().length > 0 && !isVMMac(element.getHardwareAddress())) {
InetAddress ip = addresses.nextElement();
if (ip instanceof Inet4Address) {
if (ip.isSiteLocalAddress()) {
ipAddress = ip.getHostAddress();
lanIp = InetAddress.getByName(ipAddress);
}
}
}
}
if (lanIp == null)
return null;
if (addressType.equals("ip")) {
address = lanIp.toString().replaceAll("^/+", "");
} else if (addressType.equals("mac")) {
address = getMacAddress(lanIp);
} else {
throw new Exception("Specify \"ip\" or \"mac\"");
}
} catch (UnknownHostException ex) {
ex.printStackTrace();
} catch (SocketException ex) {
ex.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
}
return address;
}
private static String getMacAddress(InetAddress ip) {
String address = null;
try {
NetworkInterface network = NetworkInterface.getByInetAddress(ip);
byte[] mac = network.getHardwareAddress();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < mac.length; i++) {
sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : ""));
}
address = sb.toString();
} catch (SocketException ex) {
ex.printStackTrace();
}
return address;
}
private static boolean isVMMac(byte[] mac) {
if(null == mac) return false;
byte invalidMacs[][] = {
{0x00, 0x05, 0x69}, //VMWare
{0x00, 0x1C, 0x14}, //VMWare
{0x00, 0x0C, 0x29}, //VMWare
{0x00, 0x50, 0x56}, //VMWare
{0x08, 0x00, 0x27}, //Virtualbox
{0x0A, 0x00, 0x27}, //Virtualbox
{0x00, 0x03, (byte)0xFF}, //Virtual-PC
{0x00, 0x15, 0x5D} //Hyper-V
};
for (byte[] invalid: invalidMacs){
if (invalid[0] == mac[0] && invalid[1] == mac[1] && invalid[2] == mac[2]) return true;
}
return false;
}
}
ACTUALIZADO 05/05/2017: Gracias a @mateuscb en la publicación How to Determine Internet Network Interface in Java que desafortunadamente no recibió ningún voto positivo anteriormente, pero ha contribuido a esta actualización.
El método ha sido mejorado para saltar las tarjetas de red de la máquina virtual (VM más popular de software)
Técnicamente, se debe tratar a una máquina fuera de línea, aunque no tiene la tarjeta de red de todos modos. ¿Cómo lidias con este último caso? –
¿Por qué su programa necesita esta información? ¿Qué beneficio le proporciona al usuario final? –
¿Y qué pasa si la máquina tiene más de una? ¿Y sabe que el usuario puede cambiar la dirección MAC?No hay nada que pueda hacer con una dirección MAC en Java, excepto tratar de usarla como un identificador de máquina, para lo cual no es adecuado. – EJP