Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java finding network interface for default gateway

In Java, I'd like to find the java.net.NetworkInterface corresponding with the interface used reach the default gateway. The names of the interfaces, etc, are not know ahead of time.

In other-words, if the following was my routing table, I would want the interface corresponding with "bond0":

$ netstat -r
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
10.10.10.0     *               255.255.255.0   U         0 0          0 bond0
10.10.11.0     *               255.255.255.0   U         0 0          0 eth2
10.10.11.0     *               255.255.255.0   U         0 0          0 eth3
10.10.12.0     *               255.255.255.0   U         0 0          0 eth4
10.10.13.0     *               255.255.255.0   U         0 0          0 eth5
default         mygateway      0.0.0.0         UG        0 0          0 bond0

After doing some google searching, I still haven't found any answer.

edit:
The java runtime must "know" how to get this information (not to say that it's exposed). When joining a java.net.MulticastSocket to a multicast group using the join(InetAddress grpAddr) call (which does not specify an interface), the apparent behavior seems to be to join on the "default" interface (as define above). This works even when the default intf is not the first interface listed in the routing table. However, the underlying POSIX call that joins an mcast group requires this information!:

struct ip_mreqn group;
group.imr_multiaddr = ...
group.imr_address = **address of the interface!**
setsockopty(sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &group, sizeof(group));

The point: by providing a method to join a multicast group that doesn't require the intf, the java platform, implicitly, must know how to determine the appropriate intf on each platform.

like image 388
Josh Avatar asked Aug 03 '12 14:08

Josh


1 Answers

My way is:

try(DatagramSocket s=new DatagramSocket())
{
    s.connect(InetAddress.getByAddress(new byte[]{1,1,1,1}), 0);
    return NetworkInterface.getByInetAddress(s.getLocalAddress()).getHardwareAddress();
}

Because of using datagram (UDP), it isn't connecting anywhere, so port number may be meaningless and remote address (1.1.1.1) needn't be reachable, just routable.

like image 97
motas Avatar answered Sep 29 '22 23:09

motas