Tuesday, September 2, 2014

IPv6 - InetAddress and scope_id

Ever wondered whats the scope_id which comes after IPv6 address prefixed with "%" in Java InetAddress.getAllByName() or InetAddress.getByName() method.

The Javadoc is as below

The IPv6-address is a literal IPv6 address as described above. The scope_id refers to an interface on the local system, and it can be specified in two ways.
  1. As a numeric identifier. This must be a positive integer that identifies the particular interface and scope as understood by the system. Usually, the numeric values can be determined through administration tools on the system. Each interface may have multiple values, one for each scope. If the scope is unspecified, then the default value used is zero.

  2. As a string. This must be the exact string that is returned by NetworkInterface.getName() for the particular interface in question. When an Inet6Address is created in this way, the numeric scope-id is determined at the time the object is created by querying the relevant NetworkInterface.
Note also, that the numeric scope_id can be retrieved from Inet6Address instances returned from the NetworkInterface class. This can be used to find out the current scope ids configured on the system. 

But to me the above explanation is not very clear.

After digging up little bit, I have found out how this scope_id is fetched. This is the integer id assigned to the network interfaces available in the system. This interface id can be found using "ip addr" or "ip link" command.



I have written the following program for analysis purpose.

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;

public class networkinterfacetest1 {
  public static void main(String...args) {
    Enumeration<NetworkInterface> networkInterfaces;
    try {
      networkInterfaces = NetworkInterface.getNetworkInterfaces();
      Integer notIncludedMatch = null;
      Integer match = null;
      while (networkInterfaces.hasMoreElements()) {
        Enumeration<InetAddress> inetAddresses = networkInterfaces.nextElement().getInetAddresses();
        while (inetAddresses.hasMoreElements()) {
        InetAddress addr = inetAddresses.nextElement();
        System.out.println("ip all:" + addr);
        }
      }
    } catch (SocketException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
}


I have a system where the ip addr output is as below.

[user@BGL-351L tch]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
  link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  inet 127.0.0.1/8 scope host lo
   inet6 ::1/128 scope host
   valid_lft forever preferred_lft forever
2: wlan0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
  link/ether 08:11:96:09:04:04 brd ff:ff:ff:ff:ff:ff
3: em1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
  link/ether 5c:26:0a:77:e4:fd brd ff:ff:ff:ff:ff:ff
  inet 10.10.64.86/22 brd 10.10.67.255 scope global em1
  inet6 fcff:3:10:64:5e26:aff:fe77:e4fd/64 scope global dynamic
   valid_lft 2591601sec preferred_lft 604401sec
  inet6 fe80::5e26:aff:fe77:e4fd/64 scope link
   valid_lft forever preferred_lft forever


In the same machine If I runthe above program, I have got the output as

ip all:BGL-351L/10.10.64.86
ip all:BGL-351L/fe80:0:0:0:5e26:aff:fe77:e4fd%3
ip all:BGL-351L/fcff:3:10:64:5e26:aff:fe77:e4fd%3


And in another machine the "ip addr" and program output are as below as

[user@BGL-341L]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
  link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  inet 127.0.0.1/8 scope host lo
  inet6 ::1/128 scope host
   valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
  link/ether 00:0c:29:64:61:4a brd ff:ff:ff:ff:ff:ff
  inet 10.10.68.24/22 brd 10.10.71.255 scope global eth0
  inet6 3002::20c:29ff:fe64:614a/64 scope global dynamic
   valid_lft 2591981sec preferred_lft 604781sec
  inet6 fe80::20c:29ff:fe64:614a/64 scope link
   valid_lft forever preferred_lft forever
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN
  link/ether 9a:ee:72:78:fc:cc brd ff:ff:ff:ff:ff:ff
  inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0


Program output:

ip all:BGL-341L/fe80:0:0:0:20c:29ff:fe64:614a%2
ip all:BGL-341L/3002:0:0:0:20c:29ff:fe64:614a%2
ip all:BGL-341L/10.10.68.24


So, In both the above cases, the id assigned to em1 or eth0 came as scope_id along with ipv6 address in java program output.