Java finding network interface for default gateway - java

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.

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.

As far as I know, there will be no good way to do this, because such low level details are very difficult for Java to implement in a cross-platform way. java.net.NetworkInterface may help a little, but if the available methods aren't enough you might have to resort to something a little uglier.
Is this something that will run on a specified platform forever, or does it need to be more portable? At worst, you could try to exec a system command and parse the output, but this is not very portable or stable.
Some related topics:
Is it possible to get the default gateway IP and MAC addresses in java?
Finding SSID of a wireless network with Java

Related

how to set TOS flag using websockets in java

i want to use websockets in my java application, but have to specify the TOS flag. Is there a common way to do this properly? how do i configure socket settings typically?
thanks in advance!
This can be done with the setTrafficClass(int) method from the java.net.Socket class. The JavaDoc has a good description of the allowed parameter values and what it refers to:
For Internet Protocol v4 the value consists of an octet with precedence and TOS fields as detailed in RFC 1349. The TOS field is bitset created by bitwise-or'ing values such the following :-
• IPTOS_LOWCOST (0x02)
• IPTOS_RELIABILITY (0x04)
• IPTOS_THROUGHPUT (0x08)
• IPTOS_LOWDELAY (0x10)
The last low order bit is always ignored as this corresponds to the MBZ (must be zero) bit.

Match public IP addresses with user-supplied netmasks

Recently I was given a task at my company where I have to create a function like this:
boolean addrMatch(String IP, String netMask);
This has nothing to do with routing. We have a network service that will use this function. The IP parameter varies upon all requests, the netMask parameter is user-supplied. The function must tell that an actual IP address matches with the supplied netmask or not. This is something like the user tells our system to only serve requests on the public internet to a specific subset of IP addresses, not all of them.
My networking related knowledge is far from complete, so I did a deep search on the topic, but I didn't get very far.
What I know (or been told): all the two parameteres are valid IP addresses or netmasks in xxx.xxx.xxx.xxx notation. I have to do a bitwise AND on them (obviously after converting them into BitSet or at least byte[] array). But I guess this is not the complete algorithm.
So my question: what is the correct algorithm for matching an IP address with a netmask?
ps.: I'm working in Java, but I need the generic method.
A netmask is just a bitmask. Basically if address & netmask != 0 the address is in the subnet represented by the netmask. The implementation details you have to cope with are bytes instead of bits, and varying numbers of bytes depending on whether you have IPv4 or IPv6. But it's basically trivial.

Java Local IP range detect

I am working on a LAN based software, for which I require to detect the range in which systems in the network lies, using java. The function is required to be similar to "Detect local IP range" in netscan, a windows utility software. Any help in this regard will be highly appreciated.
If you are wanting the actual local subnet IP range, rather than a list of alive IP addresses in the local subnet, you can use the following code to get the subnet mask size:
InetAddress localHost = Inet4Address.getLocalHost();
NetworkInterface ni = NetworkInterface.getByInetAddress(localHost);
InterfaceAddress ia = ni.getInterfaceAddresses().get(0);
short mask = ia.getNetworkPrefixLength();
That will give you a short primitive with a value of 1-32, probably 24. Then you can use
byte[] b = ia.getAddress().getAddress();
Which will give you a byte[] which you will mask against the subnet mask to give you the local address range in some usable format.
Alternatively if you want a list of alive hosts on the local subnet, an arp-scan using JPCap is the method I would use.
You can try using "ping".
This post has some code on ping to start.
How to do a true Java ping from Windows?

Java / TCP Traffic classes

Well I notice in Java and presumably other languages there is a Socket option similar to
setTrafficClass(int tc)
I know the application I am using has a traffic class of 24, however despite googling I cannot find a list of what these classes correspond to, nor a list of valid ones.
Please enlighten me.
md_5
According to the specification for Socket.setTrafficClass, we see:
For Internet Protocol v4 the value consists of an integer, the least significant 8 bits of which represent the value of the TOS octet in IP packets sent by the socket. RFC 1349 defines the TOS values as follows:
IPTOS_LOWCOST (0x02)
IPTOS_RELIABILITY (0x04)
IPTOS_THROUGHPUT (0x08)
IPTOS_LOWDELAY (0x10)
The last low order bit is always ignored as this corresponds to the MBZ (must be zero) bit.
24 is 0x18 i.e. 0x10 | 0x08, which corresponds to IPTOS_THROUGHPUT and IPTOS_LOWDELAY being set.
As you can see, the TOS only serves as a hint; it requests high-throughput, low-delay routing... which may or may not be serviced!
You can read more on types of service in RFC 1349 and the relevant Wikipedia article here.
The Javadocs have some details. Essentially, you're setting the TOS (type of service) header of your packet. The routing network may choose to use that as a suggestion on how to process the packet (or it might ignore it completely). A lot of networks don't actually do anything meaningful with this field, so I wouldn't rely on it's behaviour.
Traffic class is ultimately a matter between you and your nearest router. The field has been through several mutations. It also varies between IPv4 and IPv6. The first definition for IPv4 was given in RFC 791-5; this was revised in RFC 1349, and redefined completely in RFC 2474 as 'Differentiated Services'. The whole business may well have been revised again since I researched it for my book in 2003 or so. For IPv6 see RFC 2460. The stuff in the Javadoc about the IPTOS_* values refers to RFC 1349, and was already several years out of date when it was written.

Good hash function for ip addresses and remote ports

I'm writing a peer to peer application and I need a hash function for storing IP/port pairs in a java hashset. Rather than re-invent the wheel I wondered if there are already solutions out there but google has not yielded much.
Can anyone recommend a hash function for IPv4 (bonus if it works for IPv6 as well!) and a remote port number?
The port number is likely to be the same unless the client is on the same host in which case it will be sequential.
The String.hashCode() is pretty reasonable. I would simply do this:
int hash = (ip + "/" + port).hashCode();
It is "random" enough for coding purposes, so much so that it is relied upon by much of the JDK API.
Remember this mantra... "less code is good"
ip^port is about as simple as you can get
this is pretty decent as the last few bits in the IP number are essentially random (assignment of ip from the ISP)
you can expand that with ip^port|port>>>16 to avoid the issue with ending on all 0 or 1 being avoided
for IPv6 you'll need to ipv6_1^ipv6_2^ipv6_3^ipv6_4^port (with ipv6_i being the ith 32bit part)
you can also do
int hash=17;
hash=hash*5+ip;
hash=hash*5+port;
return hash
or
int hash=17;
hash=hash*5+ipv6_1;
hash=hash*5+ipv6_2;
hash=hash*5+ipv6_3;
hash=hash*5+ipv6_4;
hash=hash*5+port;
return hash
as your standard hash function which is a bit better than the standard xor because it is not commutative and you can change the order around if you feel better about it

Categories

Resources