2

Using Java I tried to find my PCs local IP address. However, the result hasn't been correct. To be specific, I need the Wireless LAN Adapter WiFi IPv4 address from the ipconfig command. I looked at many different questions such as this excellent answer but it didn't become clear how to do this in Java. InetAddress.getLocalHost() returns the wrong IP ('Ethernet-Adapter VirtualBox Host-Only Network').

I tried the following code:

public static List<String> getLocalIPAddresses() throws Exception
{
    val networkInterfaces = NetworkInterface.getNetworkInterfaces();
    val localIPAddresses = new ArrayList<String>();

    while (networkInterfaces.hasMoreElements())
    {
        for (val interfaceAddress : networkInterfaces.nextElement().getInterfaceAddresses())
        {
            val address = interfaceAddress.getAddress();

            // Find the local IP addresses
            if (address.isSiteLocalAddress())
            {
                val localIPAddress = interfaceAddress.getAddress().toString().replace("/", "");
                localIPAddresses.add(localIPAddress);
            }
        }
    }

    if (localIPAddresses.isEmpty())
    {
        throw new IllegalStateException("Expected the computer's local IP address but didn't get one!");
    }

    return localIPAddresses;
}

Note:
val is from Lombok.

On my machine this returns a list of 2 IP addresses:

192.168.56.1
192.168.2.103

The 'Ethernet-Adapter VirtualBox Host-Only Network' one and the correct 'Wireless LAN Adapter WiFi' one. What can I do to always guarantee the latter? Apparently checking for isSiteLocalAddress() (a.k.a local IP addresses) is not enough. What else can be done code-wise? Filtering out 'VirtualBox' is not a foolproof-solution especially since network interface names are language-dependent:

public static List<String> getLocalIPAddresses() throws Exception
{
    val networkInterfaces = NetworkInterface.getNetworkInterfaces();
    val localIPAddresses = new ArrayList<String>();

    while (networkInterfaces.hasMoreElements())
    {
        val networkInterface = networkInterfaces.nextElement();
        val displayName = networkInterface.getDisplayName();

        if (!displayName.contains("VirtualBox"))
        {
            for (val interfaceAddress : networkInterface.getInterfaceAddresses())
            {
                val address = interfaceAddress.getAddress();

                // Find the local IP addresses
                if (address.isSiteLocalAddress())
                {
                    val localIPAddress = interfaceAddress.getAddress().toString().replace("/", "");
                    localIPAddresses.add(localIPAddress);
                }
            }
        }
    }

    if (localIPAddresses.isEmpty())
    {
        throw new IllegalStateException("Expected the computer's local IP address but didn't get one!");
    }

    return localIPAddresses;
}

I need a platform independent solution. I'm on Windows though.

user207421
  • 305,947
  • 44
  • 307
  • 483
BullyWiiPlaza
  • 17,329
  • 10
  • 113
  • 185
  • Are both IPs found on the same networkInterface? If not, can you distinguish the interface with boolean tests such as networkIntreface.isVirtual()? – Michael McKay Dec 02 '17 at 14:04
  • @MichaelMcKay: Even after including the `isVirtual()` check the code still returns the 2 IPs. They are on different network interfaces each. – BullyWiiPlaza Dec 02 '17 at 20:31
  • If "InetAddress.getLocalHost() returns the wrong IP", can you use that to filter it out in your for loop? – Michael McKay Dec 02 '17 at 22:40
  • @MichaelMcKay: No because for another machine it could be the right one... – BullyWiiPlaza Dec 02 '17 at 23:00
  • The only other thing I could suggest would be to use the getName() method and select the first one that starts with "wlan". In the end though, both IP addresses are valid answers to the question "Whats my IP address?" - not false positives. There is a possibility that you could use the host file in windows to specify which one was selected as the default but this file may not exist on many computers. You could also look at the naming services. – Michael McKay Dec 03 '17 at 14:23

1 Answers1

0

Why don't you use isVirtual() method.

static List<String> getLocalIpAddress() throws SocketException {
    Enumeration<NetworkInterface> networkInterfaces = null;
    List<String> localIpAddress = new ArrayList<String>();

    networkInterfaces = NetworkInterface.getNetworkInterfaces();

    while (networkInterfaces.hasMoreElements()) {
        NetworkInterface ni = networkInterfaces.nextElement();
        System.out.println("=== <" + ni.getDisplayName() + "> ===");

        if (!ni.isUp()) {
            for (InterfaceAddress addr : ni.getInterfaceAddresses()) {
                System.out.println("not up : " + addr.getAddress().getHostAddress());
            }
            continue;
        }
        if (ni.isLoopback()) {
            for (InterfaceAddress addr : ni.getInterfaceAddresses()) {
                System.out.println("loopback : " + addr.getAddress().getHostAddress());
            }
            continue;
        }
        if (ni.isVirtual()) {
            for (InterfaceAddress addr : ni.getInterfaceAddresses()) {
                System.out.println("virtual : " + addr.getAddress().getHostAddress());
            }
            continue;
        }

        if (!ni.isPointToPoint()) {
            for (InterfaceAddress addr : ni.getInterfaceAddresses()) {
                System.out.println("not ppp : " + addr.getAddress().getHostAddress());
            }
            continue;
        }

        for (InterfaceAddress addr : ni.getInterfaceAddresses()) {
            InetAddress address = addr.getAddress();
            if (address.isLinkLocalAddress()) {
                System.out.println("link local address: " + address.getHostName() + address.getHostAddress());
                continue;
            }
            if (address.isSiteLocalAddress()) {
                System.out.println("site local address: " + address.getHostName() + address.getHostAddress());
                continue;
            }

            System.out.println("getHostName: " + address.getHostName());
            System.out.println("getHostAddress : " + address.getHostAddress());
            System.out.println("------separator-------");

            localIpAddress.add(address.getHostAddress());
        }
    }

    return localIpAddress;
}
kayjay
  • 56
  • 4