Network interface details with Java 6

Many times it is useful to be able to get programmatically information about the network interfaces present on a host. Java standard library include a number of classes designed to provide access to this information. The most important is java.net.NetworkInterface which suffered a major face lifting in Java 6.
Now it is possible to get a lot more information about every network interface in the system. Of special importance is the ability to get the MAC address of an interface.

This tutorial focuses on a sample application used to display detailed information about the network interfaces found on the host.

package com.littletutorials.netif;

import java.io.*;
import java.net.*;
import java.util.*;

public class NetIfInfo
{
    private static final String NL = System.getProperty("line.separator");
    private static final String NL_TAB = NL + "  ";
    private static final String IPV4 = "IPv4";
    private static final String IPV6 = "IPv6";

    private static class InterfaceInfo
    {
        public String displayName;
        public String name;
        public int mtu;
        public boolean isUp;
        public boolean isLoopback;
        public boolean isPointToPoint; // e.g. a PPP modem interface
        public boolean isVirtual;      // a sub-interface
        public boolean supportsMulticast;
        public byte[] macAddress;
        public List<IpAddressInfo> ipAddresses;
        public List<InterfaceInfo> subInterfaces;

        public String toString()
        {
            StringBuilder sb = new StringBuilder(NL);
            sb.append("*** Interface [" + name + "] ***").append(NL);

            sb.append(NL).append("display name  : " + displayName);
            sb.append(NL).append("MTU           : " + mtu);
            sb.append(NL).append("loopback      : " + isLoopback);
            sb.append(NL).append("point to point: " + isPointToPoint);
            sb.append(NL).append("up            : " + isUp);
            sb.append(NL).append("virtual       : " + isVirtual);
            sb.append(NL).append("multicast     : " + supportsMulticast);

            sb.append(NL).append("HW address    : ");
            if (macAddress != null)
            {
                for (byte b : macAddress)
                {
                    sb.append(String.format("%1$02X ", b));
                }
            }
            else
            {
                sb.append("n/a");
            }

            for (IpAddressInfo ipAddr: ipAddresses)
            {
                sb.append(ipAddr);
            }

            for (InterfaceInfo subInfo: subInterfaces)
            {
                sb.append(subInfo);
            }

            return sb.toString();
        }
    }

    private static class IpAddressInfo
    {
        public String ipAddress;
        public String ipVersion = "unknown";
        public String hostName;
        public String canonicalHostName;
        public boolean isLoopback;
        public boolean isSiteLocal; // private IP address
        public boolean isAnyLocal;  // wildcard address
        public boolean isLinkLocal;
        public boolean isMulticast;
        public boolean isReachable;

        public String toString()
        {
            StringBuilder sb = new StringBuilder();
            sb.append(NL).append("INET address ("+ ipVersion + "): " + ipAddress);
            sb.append(NL_TAB).append("host name           : " + hostName);
            sb.append(NL_TAB).append("canonical host name : " + canonicalHostName);
            sb.append(NL_TAB).append("loopback            : " + isLoopback);
            sb.append(NL_TAB).append("site local          : " + isSiteLocal);
            sb.append(NL_TAB).append("any local           : " + isAnyLocal);
            sb.append(NL_TAB).append("link local          : " + isLinkLocal);
            sb.append(NL_TAB).append("multicast           : " + isMulticast);
            sb.append(NL_TAB).append("reachable           : " + isReachable);

            return sb.toString();
        }
    }

    private static InterfaceInfo getInterfaceInfo(NetworkInterface nif) throws IOException
    {
        // get interface information
        InterfaceInfo info = new InterfaceInfo();
        info.displayName = nif.getDisplayName();
        info.name = nif.getName();
        info.mtu = nif.getMTU();
        info.isUp = nif.isUp();
        info.isLoopback = nif.isLoopback();
        info.isPointToPoint = nif.isPointToPoint();
        info.isVirtual = nif.isVirtual();
        info.supportsMulticast = nif.supportsMulticast();
        info.macAddress = nif.getHardwareAddress();
        info.ipAddresses = new ArrayList<IpAddressInfo>();
        info.subInterfaces = new ArrayList<InterfaceInfo>();

        // get IP address information
        Enumeration<InetAddress> inetAddresses = nif.getInetAddresses();
        while (inetAddresses.hasMoreElements())
        {
            InetAddress inetAddr = inetAddresses.nextElement();

            IpAddressInfo ipInfo = new IpAddressInfo();
            if (inetAddr instanceof Inet4Address)
            {
                ipInfo.ipVersion = IPV4;
            }
            else if (inetAddr instanceof Inet6Address)
            {
                ipInfo.ipVersion = IPV6;
            }
            ipInfo.ipAddress = inetAddr.getHostAddress();
            ipInfo.hostName = inetAddr.getHostName();
            ipInfo.canonicalHostName = inetAddr.getCanonicalHostName();
            ipInfo.isAnyLocal = inetAddr.isAnyLocalAddress();
            ipInfo.isLinkLocal = inetAddr.isLinkLocalAddress();
            ipInfo.isSiteLocal = inetAddr.isSiteLocalAddress();
            ipInfo.isLoopback = inetAddr.isLoopbackAddress();
            ipInfo.isMulticast = inetAddr.isMulticastAddress();
            ipInfo.isReachable = inetAddr.isReachable(5000);

            info.ipAddresses.add(ipInfo);
        }

        // get virtual interface information
        Enumeration<NetworkInterface> subIfs = nif.getSubInterfaces();
        while (subIfs.hasMoreElements())
        {
            NetworkInterface subIf = subIfs.nextElement();
            InterfaceInfo subInfo = getInterfaceInfo(subIf);
            info.subInterfaces.add(subInfo);
        }

        return info;
    }

    public static void main(String[] args) throws IOException
    {
        Enumeration<NetworkInterface> interfaces =
            NetworkInterface.getNetworkInterfaces();

        while (interfaces.hasMoreElements())
        {
            NetworkInterface nif = interfaces.nextElement();
            System.out.println(getInterfaceInfo(nif));
        }
    }
}

The output generated on a Linux system will look similar to this one:

*** Interface [eth0] ***

display name  : eth0
MTU           : 1500
loopback      : false
point to point: false
up            : true
virtual       : false
multicast     : true
HW address    : 00 13 D3 9F BB C1 
INET address (IPv6): fe80:0:0:0:213:d3ff:fe9f:bbc1%2
  host name           : fe80:0:0:0:213:d3ff:fe9f:bbc1%2
  canonical host name : fe80:0:0:0:213:d3ff:fe9f:bbc1%2
  loopback            : false
  site local          : false
  any local           : false
  link local          : true
  multicast           : false
  reachable           : true
INET address (IPv4): 192.168.0.99
  host name           : black.local
  canonical host name : black.local
  loopback            : false
  site local          : true
  any local           : false
  link local          : false
  multicast           : false
  reachable           : true

*** Interface [lo] ***

display name  : lo
MTU           : 16436
loopback      : true
point to point: false
up            : true
virtual       : false
multicast     : false
HW address    : n/a
INET address (IPv6): 0:0:0:0:0:0:0:1%1
  host name           : 0:0:0:0:0:0:0:1%1
  canonical host name : 0:0:0:0:0:0:0:1%1
  loopback            : true
  site local          : false
  any local           : false
  link local          : false
  multicast           : false
  reachable           : true
INET address (IPv4): 127.0.0.1
  host name           : localhost
  canonical host name : localhost
  loopback            : true
  site local          : false
  any local           : false
  link local          : false
  multicast           : false
  reachable           : true