How to enumerate IP addresses of all enabled NIC cards from Java?
Asked Answered
G

5

47

Short of parsing the output of ipconfig, does anyone have a 100% pure java way of doing this?

Galore answered 30/1, 2009 at 4:13 Comment(0)
L
52

This is pretty easy:

try {
  InetAddress localhost = InetAddress.getLocalHost();
  LOG.info(" IP Addr: " + localhost.getHostAddress());
  // Just in case this host has multiple IP addresses....
  InetAddress[] allMyIps = InetAddress.getAllByName(localhost.getCanonicalHostName());
  if (allMyIps != null && allMyIps.length > 1) {
    LOG.info(" Full list of IP addresses:");
    for (int i = 0; i < allMyIps.length; i++) {
      LOG.info("    " + allMyIps[i]);
    }
  }
} catch (UnknownHostException e) {
  LOG.info(" (error retrieving server host name)");
}

try {
  LOG.info("Full list of Network Interfaces:");
  for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
    NetworkInterface intf = en.nextElement();
    LOG.info("    " + intf.getName() + " " + intf.getDisplayName());
    for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
      LOG.info("        " + enumIpAddr.nextElement().toString());
    }
  }
} catch (SocketException e) {
  LOG.info(" (error retrieving network interface list)");
}
Limelight answered 30/1, 2009 at 4:18 Comment(2)
Thanks for the example. There is a bug in it though(and in all other examples here), getNetworkInterfaces() can return null for some strange reason(please tell me why) if no network interfaces are found: 'Returns all the interfaces on this machine. Returns null if no network interfaces could be found on this machine. NOTE: can use getNetworkInterfaces()+getInetAddresses() to obtain all IP addresses for this node 'Reviewer
Version with LOG.infos replaced with System out calls and imports included here: gist.github.com/williamberg/5299998Derayne
O
25

Some of this will only work in JDK 1.6 and above (one of the methods was added in that release.)

List<InetAddress> addrList = new ArrayList<InetAddress>();
for(Enumeration<NetworkInterface> eni = NetworkInterface.getNetworkInterfaces(); eni.hasMoreElements(); ) {
   final NetworkInterface ifc = eni.nextElement();
   if(ifc.isUp()) {
      for(Enumeration<InetAddress> ena = ifc.getInetAddresses(); ena.hasMoreElements(); ) {
        addrList.add(ena.nextElement());
      }
   }
}

Prior to 1.6, it's a bit more difficult - isUp() isn't supported until then.

FWIW: The Javadocs note that this is the correct approach for getting all of the IP addresses for a node:

NOTE: can use getNetworkInterfaces()+getInetAddresses() to obtain all IP addresses for this node

Osithe answered 30/1, 2009 at 4:38 Comment(9)
According to the JavaDoc, NetworkInterface and its methods were added in 1.4. I've personally been using code similar to what I posted since Java 5, so I haven't tested my code with Java 1.4 or earlier.Limelight
Actually, please edit your post to remove the erroneous comment "Prior to 1.6, there is no way to do this 100% pure java....parsing Runtime results or JNI would be your only options." as only the ifUp() method you used was added in 1.6. The rest is present since 1.4.Limelight
The NetworkInterface class is present since 1.4, but the getInterfaceAddresses() and isUp() methods are both @since 1.6 (according to java.sun.com/javase/6/docs/api/java/net/NetworkInterface.html). 1.6 made the NetworkInterface class MUCH richer than it was in 1.5.Osithe
errr, I see what you're saying.... getInetAddresses() is @since 1.4 (at least)... Editted to reflect some doubt while I figure things out :).Osithe
But you are using only ifUp(). Your sample does not use getInterfaceAddresses(). Don't scare people off of using this code with Java 5 or Java 1.4! Yes, the Java 6 update added quite a lot to NetworkInterface.Limelight
Our comment electrons flew past each other in cyberspace :POsithe
I believe the other thing your code uses that is new to 1.6 is using an Enumeration with the Java 5 for/each loop. Sure makes it look cleaner!Limelight
This doesn't compile in JDK 1.7. getNetworkInterfaces returns an Enumeration which does not implement Iterable.Stylet
On JDK 1.7 turn the Enumeration into something iterable with Collections.list()Alight
T
8

This code only works in Java 1.6 because of the added InterfaceAddress code.

  try
  {
     System.out.println("Output of Network Interrogation:");
     System.out.println("********************************\n");

     InetAddress theLocalhost = InetAddress.getLocalHost();
     System.out.println(" LOCALHOST INFO");
     if(theLocalhost != null)
     {
        System.out.println("          host: " + theLocalhost.getHostName());
        System.out.println("         class: " + theLocalhost.getClass().getSimpleName());
        System.out.println("            ip: " + theLocalhost.getHostAddress());
        System.out.println("         chost: " + theLocalhost.getCanonicalHostName());
        System.out.println("      byteaddr: " + toMACAddrString(theLocalhost.getAddress()));
        System.out.println("    sitelocal?: " + theLocalhost.isSiteLocalAddress());
        System.out.println("");
     }
     else
     {
        System.out.println(" localhost was null");
     }

     Enumeration<NetworkInterface> theIntfList = NetworkInterface.getNetworkInterfaces();
     List<InterfaceAddress> theAddrList = null;
     NetworkInterface theIntf = null;
     InetAddress theAddr = null;

     while(theIntfList.hasMoreElements())
     {
        theIntf = theIntfList.nextElement();

        System.out.println("--------------------");
        System.out.println(" " + theIntf.getDisplayName());
        System.out.println("          name: " + theIntf.getName());
        System.out.println("           mac: " + toMACAddrString(theIntf.getHardwareAddress()));
        System.out.println("           mtu: " + theIntf.getMTU());
        System.out.println("        mcast?: " + theIntf.supportsMulticast());
        System.out.println("     loopback?: " + theIntf.isLoopback());
        System.out.println("          ptp?: " + theIntf.isPointToPoint());
        System.out.println("      virtual?: " + theIntf.isVirtual());
        System.out.println("           up?: " + theIntf.isUp());

        theAddrList = theIntf.getInterfaceAddresses();
        System.out.println("     int addrs: " + theAddrList.size() + " total.");
        int addrindex = 0;
        for(InterfaceAddress intAddr : theAddrList)
        {
           addrindex++;
           theAddr = intAddr.getAddress();
           System.out.println("            " + addrindex + ").");
           System.out.println("            host: " + theAddr.getHostName());
           System.out.println("           class: " + theAddr.getClass().getSimpleName());
           System.out.println("              ip: " + theAddr.getHostAddress() + "/" + intAddr.getNetworkPrefixLength());
           System.out.println("           bcast: " + intAddr.getBroadcast().getHostAddress());
           int maskInt = Integer.MIN_VALUE >> (intAddr.getNetworkPrefixLength()-1);
           System.out.println("            mask: " + toIPAddrString(maskInt));
           System.out.println("           chost: " + theAddr.getCanonicalHostName());
           System.out.println("        byteaddr: " + toMACAddrString(theAddr.getAddress()));
           System.out.println("      sitelocal?: " + theAddr.isSiteLocalAddress());
           System.out.println("");
        }
     }
  }
  catch (SocketException e)
  {
     e.printStackTrace();
  }
  catch (UnknownHostException e)
  {
     e.printStackTrace();
  }

The "toMACAddrString" method looks like this:

public static String toMACAddrString(byte[] a)
{
  if (a == null)
  {
     return "null";
  }
  int iMax = a.length - 1;

  if (iMax == -1)
  {
     return "[]";
  }

  StringBuilder b = new StringBuilder();
  b.append('[');
  for (int i = 0;; i++)
  {
     b.append(String.format("%1$02x", a[i]));

     if (i == iMax)
     {
        return b.append(']').toString();
     }
     b.append(":");
  }
}

and the "toIPAddrString" method is here:

public static String toIPAddrString(int ipa)
{
   StringBuilder b = new StringBuilder();
   b.append(Integer.toString(0x000000ff & (ipa >> 24)));
   b.append(".");
   b.append(Integer.toString(0x000000ff & (ipa >> 16)));
   b.append(".");
   b.append(Integer.toString(0x000000ff & (ipa >> 8)));
   b.append(".");
   b.append(Integer.toString(0x000000ff & (ipa)));
   return b.toString();
}

I have that first set of code in the try/catch above in a method called dump() in class called IPConfig. Then I just put a main method in IPConfig to call new IPConfig().dump() so that when I'm trying to figure out some wacky network problem, I can see Java thinks is going on. I figured out that my Fedora box reports different information than Windows for the LocalHost information and it was causing my Java programs some issues.

I realize its similiar to the other answers but it prints out nearly everything interesting that you can get from the interface and ipaddress apis.

Tacklind answered 30/1, 2009 at 13:51 Comment(4)
I've got very similar code in the startup procedure for my application. For some reason, RedHat and related linuxes really like to misconfigure the loopback address - I've had inumerable problems caused by 127.0.0.1 being mapped to the hostname rather than localhost on Redhat boxes.Osithe
That's exactly what kept getting me down too. I ended up putting in code that chooses the first non-localhost interface with an IPv4 address and asking that for the hostname, or allowing the user to set a system property that picks the interface by name and set java.net.preferIPv4Tacklind
It didn't solve the hostname problem necessarily, but it meant that I didn't have to depend on the hostname anymore.Tacklind
InterfaceAddress.getBroadcast() may return null.Longevous
O
4

Update to fix Jared's answer for JDK 1.7.

// Get list of IP addresses from all local network interfaces. (JDK1.7)
// -----------------------------------------------------------
public List<InetAddress> getListOfIPsFromNIs(){
    List<InetAddress> addrList           = new ArrayList<InetAddress>();
    Enumeration<NetworkInterface> enumNI = NetworkInterface.getNetworkInterfaces();
    while ( enumNI.hasMoreElements() ){
        NetworkInterface ifc             = enumNI.nextElement();
        if( ifc.isUp() ){
            Enumeration<InetAddress> enumAdds     = ifc.getInetAddresses();
            while ( enumAdds.hasMoreElements() ){
                InetAddress addr                  = enumAdds.nextElement();
                addrList.add(addr);
                System.out.println(addr.getHostAddress());   //<---print IP
            }
        }
    }
    return addrList;
}

As highlighted by Sam Skuce comment:

This doesn't compile in JDK 1.7. getNetworkInterfaces returns an Enumeration which does not implement Iterable. – Sam Skuce Jul 11 '12 at 19:58

Output Example:

fe80:0:0:0:800:aaaa:aaaa:0%8
192.168.56.1
fe80:0:0:0:227:aaa:aaaa:6b5%2
123.123.123.123
0:0:0:0:0:0:0:1%1
127.0.0.1
Otiliaotina answered 26/3, 2013 at 15:28 Comment(0)
B
1
import java.net.*;
import java.util.*;

public class NIC {

public static void main(String args[]) throws Exception {

    List<InetAddress> addrList = new ArrayList<InetAddress>();
    Enumeration<NetworkInterface> interfaces = null;
    try {
        interfaces = NetworkInterface.getNetworkInterfaces();
    } catch (SocketException e) {
        e.printStackTrace();
    }

    InetAddress localhost = null;

    try {
        localhost = InetAddress.getByName("127.0.0.1");
    } catch (UnknownHostException e) {
        e.printStackTrace();
    }

    while (interfaces.hasMoreElements()) {
        NetworkInterface ifc = interfaces.nextElement();
        Enumeration<InetAddress> addressesOfAnInterface = ifc.getInetAddresses();

        while (addressesOfAnInterface.hasMoreElements()) {
            InetAddress address = addressesOfAnInterface.nextElement();

            if (!address.equals(localhost) && !address.toString().contains(":")) {
                addrList.add(address);
                System.out.println("FOUND ADDRESS ON NIC: " + address.getHostAddress());
            }
        }
    }

}
}
Breana answered 14/4, 2011 at 9:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.