3

I want to check whether an active internet connection exists or not. For that I found out I can do that with the isReachable() method from the InetAddress class. Unfortunately (as the JavaDoc suggests and this post verifies), this only works with root privilegies, what is no solution to my problem.

When I run the following code, isReachable is always false:

InetAddress address = InetAddress.getByName("173.194.35.3"); //e.g. google
boolean isReachable = address.isReachable(2000); //ms

Therefore, I am searching for a good alternative to check for an active internet connection without the necessity of root privilegies.

Thank you!

Community
  • 1
  • 1
casaout
  • 1,819
  • 3
  • 24
  • 54

4 Answers4

2

Do you know the ICMP protocol? This is what ping uses internally i believe. Check out this example. (Allbeit this is is a solution for windows)

Additionally read this post for a high-level discussion on this topic!

Community
  • 1
  • 1
Nenad M
  • 3,055
  • 20
  • 26
  • Thank you for your comment. I also saw that one, but didn't try it because I have to buy JNIWrapper... So basically, I can chose to buy the Java Native Interface or run my program in root mode (to use theInetAddress.isReachable-code)? Or is there another possibility? – casaout Oct 21 '12 at 11:01
0

The Javadoc doesn't say that at all, and the post you linked doesn't 'verify' it either. What it actually says is "A typical implementation will use ICMP ECHO REQUESTs if the privilege can be obtained, otherwise it will try to establish a TCP connection on port 7 (Echo) of the destination host.".

In other words you don't need privileges to call this method at all. You only need privileges for the ICMP mode. If you don't have them (or you are on Windows as no ICMP implementation is used), it uses TCP to port 7. And note that it treats either a connection success or a connection refusal as 'reachable'.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • thanks for your post. My java program will run only on Windows machines (so TCP to port 7). Unfortunately, this didn't work on my (Windows-)machine. What should I do now? - Make a firewall exception for port 7 or something like that? Or can the program do something like this on its own? Thank you! – casaout Oct 22 '12 at 05:25
  • @casaout Try a different target address that does work. You need one that doesn't just drop port 7 requests on the floor. It has nothing to do with your local box. – user207421 Oct 22 '12 at 22:18
  • That sounds great. But I didn't find an address/ip that worked... Do you have a suggestion? (I also added the statement I run to the first post. thank you! – casaout Oct 23 '12 at 06:37
0

It can be old, but I had the same problem and after read those answers I found this amazing library icmp 4j and solved all my problems. You can download the source code here and use in your project something like this

// request
final IcmpPingRequest request = IcmpPingUtil.createIcmpPingRequest ();
request.setHost ("192.168.0.101");

// repeat a few times
for (int count = 1; count <= 4; count ++) {

// delegate
final IcmpPingResponse response = IcmpPingUtil.executePingRequest (request);

// log
final String formattedResponse = IcmpPingUtil.formatResponse (response);
System.out.println (formattedResponse);

// rest
Thread.sleep (1000);
}
0

InetAddress.isReachable() - can be run without root!

You simply need to assign the java executable the ability to send ICMP packets/etc.

You do this as follows; (run as root)

setcap cap_net_raw+eip $JAVA_HOME/bin/java

And there you have it... your java app can ping without being root!


If you get the following error;

./java: error while loading shared libraries: libjli.so: cannot open shared object file: No such file or directory

You can fix this with something like; (needs to be done as root, confirm /usr/lib64 is correct for you)

ln -s $JAVA_HOME/lib/amd64/jli/libjli.so /usr/lib64/libjli.so

Please note: unfortunately just doing export LD_LIBRARY_PATH=$JAVA_HOME/lib/amd64/jli doesn't work.

Glenn
  • 1
  • 1