Sniffing a LAN : Jpcap java program only seems to catch my packets - java

I have to create a program that sniff a local network for school. I chose to work with Java and found out that you can capture packets with jpcap.
So I wanted to follow one of the example provided in jpcap's github and it seems like I can only find my own packets.
Like I said, I've looked at the code and chose my wifi interface. The program is capturing packets and I put all the source ip addresses in a text file to run some tests. I have also created a hashmap the ip addresses I've finded when I did a arp -a. From what I've read online, this command shows you ip addresses in your network.I created a boolean set to false and I then proceeded to run a loop that goes through the textfile and looked if the ip address was in the hashMap : if one of the addresses appeared in the hashmap, the boolean would be change to true and it would mean that I've managed to catch something.
After running the test, the boolean came out false.
Here's the example code
``public class PacketCaptor {
private static final int INFINITE = -1;
private static final int PACKET_COUNT = INFINITE;
/*
private static final String HOST = "203.239.110.20";
private static final String FILTER =
"host " + HOST + " and proto TCP and port 23";
*/
private static final String FILTER =
// "port 23";
"";
public static void main(String[] args) {
try {
if(args.length == 1){
PacketCaptor sniffer = new PacketCaptor(args[0]);
} else {
System.out.println("Usage: java Sniffer [device name]");
System.out.println("Available network devices on your machine:");
String[] devs = PacketCapture.lookupDevices();
for(int i = 0; i < devs.length ; i++)
System.out.println("\t" + devs[i]);
}
} catch(Exception e) {
e.printStackTrace();
}
}
public PacketCaptor(String device) throws Exception {
// Initialize jpcap
PacketCapture pcap = new PacketCapture();
System.out.println("Using device '" + device + "'");
pcap.open(device, true);
//pcap.setFilter(FILTER, true);
pcap.addPacketListener(new PacketHandler());
System.out.println("Capturing packets...");
pcap.capture(PACKET_COUNT);
}
}
class PacketHandler implements PacketListener
{
WritingClass writing = new WritingClass();
public void packetArrived(Packet packet) {
try {
// only handle TCP packets
if(packet instanceof TCPPacket) {
TCPPacket tcpPacket = (TCPPacket)packet;
byte[] data = tcpPacket.getTCPData();
String srcHost = tcpPacket.getSourceAddress();
String dstHost = tcpPacket.getDestinationAddress();
String isoData = new String(data, "ISO-8859-1");
System.out.println(srcHost+" -> " + dstHost + ": " + isoData);
String datas = srcHost+"|"+dstHost+"|";
writing.write(datas, this.writing.getFileName());
}
} catch( Exception e ) {
e.printStackTrace();
}
}
Can anyone help me figure out why It doesn't work ?
Thank you so much for your help

The reason why you aren't able to capture more packets is because you need an interface in promisc or raw mode, I advice you to use a proper sniffer like wireshark to check if other packets that aren't addressed to you can be captured. If not, means you need apply a mitm method because you are in a commuted network. For use that code on wifi should be enough an interface in monitor mode (check aircrack-ng suite).
In GNU/Linux Debian based systems may use the command iw dev wlan0 interface add mon0 type monitor (from package wireless-tools)

Related

Don't list all ip lan [duplicate]

InetAddress byName = InetAddress.getByName("173.39.161.140");
System.out.println(byName);
System.out.println(byName.isReachable(1000));
Why does isReachable return false? I can ping the IP.
The "isReachable" method has not been worthy of using for me in many cases. You can scroll to the bottom to see my alternative for simply testing if you're online and capable of resolving external hosts (i.e. google.com) ... Which generally seems to work on *NIX machines.
The issue
There is alot of chatter about this :
Here are other, similar questions :
Detect internet Connection using Java
How do I test the availability of the internet in Java?
And even a reported bug on this same matter :
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4921816
Part 1 : A reproducible example of the problem
Note that in this case, it fails.
//also, this fails for an invalid address, like "www.sjdosgoogle.com1234sd"
InetAddress[] addresses = InetAddress.getAllByName("www.google.com");
for (InetAddress address : addresses) {
if (address.isReachable(10000))
{
System.out.println("Connected "+ address);
}
else
{
System.out.println("Failed "+address);
}
}
//output:*Failed www.google.com/74.125.227.114*
Part 2 : A Hackish Workaround
As an alternative, you can do this :
// in case of Linux change the 'n' to 'c'
Process p1 = java.lang.Runtime.getRuntime().exec("ping -n 1 www.google.com");
int returnVal = p1.waitFor();
boolean reachable = (returnVal==0);
The -c option of ping will allow ping to simply try to reach the server once(as opposed to the infinite ping which we're used to using at the terminal).
This will return 0 if the host is reachable. Otherwise, you will get "2" as a return value.
Much simpler - but of course it is platform specific.
And there may be certain privilege caveats to using this command - but I find it works on my machines.
PLEASE Note that :
1) This solution is not production quality. Its a bit of a hack. If google is down, or your internet is temporarily slow, or maybe even if there is some funniness in your privileges/system settings, if could return false negatives (i.e. it could fail even though the input address is reachable).
2) The isReachable failure is an outstanding issue. Again - there are several online resources indicating that there is no "perfect" way of doing this at the time of this writing, due to the way the JVM tries to reach hosts - I guess it is an intrinsically platform specific task which, although simple, hasn't yet been abstracted sufficiently by the JVM.
I came here to get an answer for this same question, but I was unsatisfied by any of the answers because I was looking for a platform independent solution. Here is the code which I wrote and is platform independent, but requires information about any open port on the other machine (which we have most of the time).
private static boolean isReachable(String addr, int openPort, int timeOutMillis) {
// Any Open port on other machine
// openPort = 22 - ssh, 80 or 443 - webserver, 25 - mailserver etc.
try {
try (Socket soc = new Socket()) {
soc.connect(new InetSocketAddress(addr, openPort), timeOutMillis);
}
return true;
} catch (IOException ex) {
return false;
}
}
Update: Based on a recent comment to this answer, here is a succinct version of the above code:
private static boolean isReachable(String addr, int openPort, int timeOutMillis) {
// Any Open port on other machine
// openPort = 22 - ssh, 80 or 443 - webserver, 25 - mailserver etc.
try (Socket soc = new Socket()) {
soc.connect(new InetSocketAddress(addr, openPort), timeOutMillis);
return true;
} catch (IOException ex) {
return false;
}
}
If you only want to check if it is connected to internet use this method , It returns true if internet is connected, Its preferable if you use the address of the site you are trying to connect through the program.
public static boolean isInternetReachable()
{
try {
//make a URL to a known source
URL url = new URL("http://www.google.com");
//open a connection to that source
HttpURLConnection urlConnect = (HttpURLConnection)url.openConnection();
//trying to retrieve data from the source. If there
//is no connection, this line will fail
Object objData = urlConnect.getContent();
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
Just mentioning it explicitly since the other answers don't. The ping part of isReachable() requires root access on Unix. And as pointed out by bestsss in 4779367:
And if you ask why ping from bash doesn't, actually it does need as well. Do that ls -l /bin/ping.
Since using root was not an option in my case the solution was to allow access to port 7 in the firewall to the specific server I was interested in.
I am not sure what was the state when the original question was asked back in 2012.
As it stands now, ping will be executed as a root. Through the ping executable's authorization you will see the +s flag, and the process belonging to root, meaning it will run as root. run ls -liat on where the ping is located and you should see it.
So, if you run InetAddress.getByName("www.google.com").isReacheable(5000) as root, it should return true.
you need proper authorizations for the raw socket, which is used by ICMP (the protocol used by ping)
InetAddress.getByName is as reliable as ping, but you need proper permissions on the process to have it running properly.
Since you can ping the computer, your Java process should run with sufficient privileges to perform the check. Probably due to use of ports in the lower range. If you run your java program with sudo/superuser, I'll bet it works.
I would suggest that the ONLY reliable way to test an internet connection is to actually connect AND download a file, OR to parse the output of an OS ping call via exec(). You cannot rely on the exit code for ping and isReachable() is crap.
You cannot rely on a ping exit code as it returns 0 if the ping command executes correctly. Unfortunately, ping executes correctly if it can't reach the target host but gets a "Destination host unreachable" from your home ADSL router. This is kind of a reply that gets treated as a successfull hit, thus exit code = 0. Have to add though that this is on a Windows system. Not checked *nixes.
private boolean isReachable(int nping, int wping, String ipping) throws Exception {
int nReceived = 0;
int nLost = 0;
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec("ping -n " + nping + " -w " + wping + " " + ipping);
Scanner scanner = new Scanner(process.getInputStream());
process.waitFor();
ArrayList<String> strings = new ArrayList<>();
String data = "";
//
while (scanner.hasNextLine()) {
String string = scanner.nextLine();
data = data + string + "\n";
strings.add(string);
}
if (data.contains("IP address must be specified.")
|| (data.contains("Ping request could not find host " + ipping + ".")
|| data.contains("Please check the name and try again."))) {
throw new Exception(data);
} else if (nping > strings.size()) {
throw new Exception(data);
}
int index = 2;
for (int i = index; i < nping + index; i++) {
String string = strings.get(i);
if (string.contains("Destination host unreachable.")) {
nLost++;
} else if (string.contains("Request timed out.")) {
nLost++;
} else if (string.contains("bytes") && string.contains("time") && string.contains("TTL")) {
nReceived++;
} else {
}
}
return nReceived > 0;
}
nping is number of try to ping ip(packets), if you have busy network or systems choose biger nping numbers.
wping is time waiting for pong from ip, you can set it 2000ms
for using this method u can write this:
isReachable(5, 2000, "192.168.7.93");
Or using this way:
public static boolean exists(final String host)
{
try
{
InetAddress.getByName(host);
return true;
}
catch (final UnknownHostException exception)
{
exception.printStackTrace();
// Handler
}
return false;
}
InetAddress.isReachable is flappy, and sometimes returns unreachable for addresses which we can ping.
I tried the following:
ping -c 1 <fqdn> and check the exit status.
Works for all the cases i had tried where InetAddress.isReachable doesn't work.
To Check Internet
public boolean isInternetAvailable() {
try {
InetAddress ipAddr = InetAddress.getByName("google.com");
//You can replace it with your name
return !ipAddr.equals("");
} catch (Exception e1) {
try {
Process p1 = java.lang.Runtime.getRuntime().exec("/system/bin/ping -W 1 -c 1 www.google.com");
int returnVal = 0;
returnVal = p1.waitFor();
boolean reachable = (returnVal==0);
return reachable;
} catch (Exception e2) {
e2.printStackTrace();
return false;
}
}
}
To check network connectivity
private boolean isNetworkConnected() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
return cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isConnected();
}
Because isReachable is using the TCP protocol(by WireShark) The Ping command is using ICMP protocol,if you want to return true you need to open the 7 port

Parallel Port communication Rxtx or javax.comm

Currently I am trying to communicate with a Parallel port via Java, but this has proven to be troublesome. I am currently doing a brain research using EEG and I want to send simple "event markers" to the EEG system, which must happen via Parallel Port. I have used both javax.comm and RXTX but for some reason I cannot manage to write output to the port. The test-code is as follows:
import gnu.io.*; // RXTX
// import javax.comm.*; // javax.comm
public class PrlCom {
private String msg= "1";
private OutputStream outputStream;
private InputStream inputStream;
private ParallelPort parallelPort; // can be both Rxtx or javax.comm
private CommPortIdentifier port;
// CONSTANTS
public final String PARALLEL_PORT = "LPT1";
public final String[] PORT_TYPE = { "Serial Port", "Parallel Port" };
public static void main(String[] args) {
new PrlCom();
}
public PrlCom(){
openParPort();
}
public void openParPort() {
try {
// get the parallel port connected to the EEG-system (used to be printer)
port = CommPortIdentifier.getPortIdentifier(PARALLEL_PORT);
System.out.println("\nport.portType = " + port.getPortType());
System.out.println("port type = " + PORT_TYPE[port.getPortType() - 1]);
System.out.println("port.name = " + port.getName());
// open the parallel port -- open(App name, timeout)
parallelPort = (ParallelPort) port.open("CommTest", 50);
outputStream = parallelPort.getOutputStream();
inputStream = parallelPort.getInputStream();
System.out.println("Write...");
outputStream.write(toBytes(msg.toCharArray()));
System.out.println("Flush...");
outputStream.flush();
} catch (NoSuchPortException nspe) {
System.out.println("\nPrinter Port LPT1 not found : " + "NoSuchPortException.\nException:\n" + nspe + "\n");
} catch (PortInUseException piue) {
System.out.println("\nPrinter Port LPT1 is in use : " + "PortInUseException.\nException:\n" + piue + "\n");
} catch (IOException ioe) {
System.out.println("\nPrinter Port LPT1 failed to write : " + "IOException.\nException:\n" + ioe + "\n");
} catch (Exception e) {
System.out.println("\nFailed to open Printer Port LPT1 with exeception : " + e + "\n");
} finally {
if (port != null && port.isCurrentlyOwned()) {
parallelPort.close();
}
System.out.println("Closed all resources.\n");
}
}
I got the toBytes() function from Converting char[] to byte[] . I also directly tried spam.getBytes(), which made no difference.
After running this code with the javax.comm package, the parallel port is not recognized. If I run the code with RXTX(gnu.io), I get an IOException. The entire printed output is then as follows
Stable Library
=========================================
Native lib Version = RXTX-2.1-7
Java lib Version = RXTX-2.1-7
port.portType = 2
port type = Parallel Port
port.name = LPT1
Output stream opened
Write...
Printer Port LPT1 failed to write : IOException.
Exception:
java.io.IOException: The device is not connected.
in writeByte
Closed all resources.
With Rxtx, the code can make a connection with the Parallel Port thus. However, it is unable to write a byte to the output stream. Can someone please tell me how to resolve this?
I have read in many of the other topics how outdated a parallel port is and that I should use USB. However, I am working with an EEG-system (BioSemi ActiveTwo with ActiView software) to measure brain activity and, sadly, I don't have the possibility to change this. A Parallel port-USB converter is also no option. (Odd though, that something so technologically advanced uses such outdated hardware).
Thank you so much!
I have accepted that Rxtx and javax.comm do not work anymore. Instead, I found a workaround via Python. For the answer, see
Parallel Port Communication with jnpout32pkg / jnpout32reg

To scan for ports and to list the services running on each port

I am trying to build a port scanner which not only scans for port numbers but, also list the services running on the respective port .I am new to java-programming and As you can see i have the code for scanning the status of ports on the local machine. I don't know where to start when it comes to list services running on each port. I would appreciate if anyone can suggest me any code/links to list those services. Thanks for the help.....
public class port {
public static void main(String[] args) throws Exception {
String host = "localhost";
InetAddress inetAddress = InetAddress.getByName(host);
String hostName = inetAddress.getHostName();
for (int port = 0; port <= 200; port++) {
try {
Socket socket = new Socket(hostName, port);
String text = hostName + " is listening on port " + port;
System.out.println(text);
socket.close();
}
catch (IOException e)
{
String s = hostName + " is not listening on port " + port;
System.out.println(s);
}
}
}
}
The code seems fine if you want to check for open ports, but identifying services... well, that's tricky.
It's a bit like identifying the type of file by reading the first few bytes. An easy solution is to compare the port number with the list of well known ports. So if port 80 is open, you just assume it's HTTP and move on.
This method assumes that services actually listen on their assigned ports. This is like assuming that a file that ends with "zip" is always a zip file. It's correct most of the time, but only because it's a convention. Not because it has to be this way. If you want to actually fingerprint services - determine the type of service by "talking to it", then it's a serious undertaking, not something that can be explained in a few lines. I suggest you take a look at Nmap, as it's an existing tool that does just that. You might be able to use it instead of writing your own.
So, you are looking for something like Nmap?
Your code seems good to me, although I would do something like
public class PortScanner {
public static void main(String[] args) throws Exception {
final String host = "localhost";
final InetAddress inetAddress = InetAddress.getByName(host);
final String hostName = inetAddress.getHostName();
final List<int> openPorts = new ArrayList();
// we begin at port 1 because port 0 is never used
for (int port = 1; port <= 200; port++) {
try {
Socket socket = new Socket(hostName, port);
openPorts.add(port);
} catch (IOException) {
} finally {
socket.close();
}
}
}
}
You cannot easily know what service is running on the port, you can only simply assume what service is running on that port using this list. But beware, a web server can use custom ports instead of default ones.
If you do have the requirement to know exactly what service is running on what port, I suggest you use Nmap and make a bash script out of it which in turn outputs it's findings in a .txt file. That .txt file can then be read by Java. This approach saves tons of work.

how to count Usb port using java?

I want to detect list of USB Ports which are free (not occupied) in system to while I checked with CommPortIdentifier.getPortIdentifiers() while this returns me Enumeration with 0 elements
I'd add librxtxcomm.jar too in classpath.
This should return each Port detail
Enumeration pList = CommPortIdentifier.getPortIdentifiers();
System.out.println(pList.hasMoreElements());
this returns 0 mean no List/Enumeration.
Rest Code :
public class CommPortLister{
/** Simple test program. */
public static void main(String[] ap) {
new CommPortLister().list();
}
/** Ask the Java Communications API * what ports it thinks it has. */
protected void list() {
// get list of ports available on this particular computer, by calling static method in CommPortIdentifier.
System.out.println("");
Enumeration pList = CommPortIdentifier.getPortIdentifiers();
System.out.println("Before While");
// CommPortIdentifier.getPortIdentifiers();
// Process the list.
System.out.println(pList.hasMoreElements());
while (pList.hasMoreElements()) {
System.out.println("While Loop");
CommPortIdentifier cpi = (CommPortIdentifier) pList.nextElement();
System.out.print("Port " + cpi.getName() + " ");
if (cpi.getPortType() == CommPortIdentifier.PORT_SERIAL) {
System.out.println("is a Serial Port: " + cpi);
} else if (cpi.getPortType() == CommPortIdentifier.PORT_PARALLEL) {
System.out.println("is a Parallel Port: " + cpi);
} else {
System.out.println("is an Unknown Port: " + cpi);
}
}
System.out.println("After While");
}
}
Code to detect USB port while i am unable to detect USB Port
Please try using ServerSocket(portNo). If there is an service running in the port, it will error so catch the exception and try the next port.
A port number is a 16-bit unsigned integer, thus ranging from 1 to 65535.
If you need to know which ports are occupied, you may call the system command "netstat" from java.
================Edited===========================
The above information is for transport layer logical ports.If you are looking for hardware ports for peripheral devices, then you need to check the COM ports. I found the following tutorial, maybe you can give it a try, so find another tutorial that suits your need.
http://www.java-samples.com/showtutorial.php?tutorialid=11
You will need javax.comm api for this. You can grab it from http://www.java2s.com/Code/Jar/c/Downloadcomm20jar.htm or http://www.oracle.com/technetwork/java/index-jsp-141752.html
Well here the thing using that u can have available ports u can scan it.
public class GettingAvaliable {
public static void main(String args[]) {
int startPortRange = 0;
int stopPortRange = 65365;
int usedport = 0;
int unusedports = 0;
for (int i = startPortRange; i <= stopPortRange; i++) {
try {
Socket ServerSok = new Socket("127.0.0.1", i);
System.out.println("Port in use: " + i);
usedport++;
ServerSok.close();
} catch (Exception e) {
//e.printStackTrace();
}
System.out.println("Port not in use: " + i);
unusedports++;
if (i == stopPortRange) {
System.out.println("Number of Used Ports In Your Machine: "+usedport);
System.out.println("Number of Unused Ports In Your Machine: "+unusedports);
}
}
}
}

isReachable() method for ping measurements returns wrong value [duplicate]

InetAddress byName = InetAddress.getByName("173.39.161.140");
System.out.println(byName);
System.out.println(byName.isReachable(1000));
Why does isReachable return false? I can ping the IP.
The "isReachable" method has not been worthy of using for me in many cases. You can scroll to the bottom to see my alternative for simply testing if you're online and capable of resolving external hosts (i.e. google.com) ... Which generally seems to work on *NIX machines.
The issue
There is alot of chatter about this :
Here are other, similar questions :
Detect internet Connection using Java
How do I test the availability of the internet in Java?
And even a reported bug on this same matter :
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4921816
Part 1 : A reproducible example of the problem
Note that in this case, it fails.
//also, this fails for an invalid address, like "www.sjdosgoogle.com1234sd"
InetAddress[] addresses = InetAddress.getAllByName("www.google.com");
for (InetAddress address : addresses) {
if (address.isReachable(10000))
{
System.out.println("Connected "+ address);
}
else
{
System.out.println("Failed "+address);
}
}
//output:*Failed www.google.com/74.125.227.114*
Part 2 : A Hackish Workaround
As an alternative, you can do this :
// in case of Linux change the 'n' to 'c'
Process p1 = java.lang.Runtime.getRuntime().exec("ping -n 1 www.google.com");
int returnVal = p1.waitFor();
boolean reachable = (returnVal==0);
The -c option of ping will allow ping to simply try to reach the server once(as opposed to the infinite ping which we're used to using at the terminal).
This will return 0 if the host is reachable. Otherwise, you will get "2" as a return value.
Much simpler - but of course it is platform specific.
And there may be certain privilege caveats to using this command - but I find it works on my machines.
PLEASE Note that :
1) This solution is not production quality. Its a bit of a hack. If google is down, or your internet is temporarily slow, or maybe even if there is some funniness in your privileges/system settings, if could return false negatives (i.e. it could fail even though the input address is reachable).
2) The isReachable failure is an outstanding issue. Again - there are several online resources indicating that there is no "perfect" way of doing this at the time of this writing, due to the way the JVM tries to reach hosts - I guess it is an intrinsically platform specific task which, although simple, hasn't yet been abstracted sufficiently by the JVM.
I came here to get an answer for this same question, but I was unsatisfied by any of the answers because I was looking for a platform independent solution. Here is the code which I wrote and is platform independent, but requires information about any open port on the other machine (which we have most of the time).
private static boolean isReachable(String addr, int openPort, int timeOutMillis) {
// Any Open port on other machine
// openPort = 22 - ssh, 80 or 443 - webserver, 25 - mailserver etc.
try {
try (Socket soc = new Socket()) {
soc.connect(new InetSocketAddress(addr, openPort), timeOutMillis);
}
return true;
} catch (IOException ex) {
return false;
}
}
Update: Based on a recent comment to this answer, here is a succinct version of the above code:
private static boolean isReachable(String addr, int openPort, int timeOutMillis) {
// Any Open port on other machine
// openPort = 22 - ssh, 80 or 443 - webserver, 25 - mailserver etc.
try (Socket soc = new Socket()) {
soc.connect(new InetSocketAddress(addr, openPort), timeOutMillis);
return true;
} catch (IOException ex) {
return false;
}
}
If you only want to check if it is connected to internet use this method , It returns true if internet is connected, Its preferable if you use the address of the site you are trying to connect through the program.
public static boolean isInternetReachable()
{
try {
//make a URL to a known source
URL url = new URL("http://www.google.com");
//open a connection to that source
HttpURLConnection urlConnect = (HttpURLConnection)url.openConnection();
//trying to retrieve data from the source. If there
//is no connection, this line will fail
Object objData = urlConnect.getContent();
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
Just mentioning it explicitly since the other answers don't. The ping part of isReachable() requires root access on Unix. And as pointed out by bestsss in 4779367:
And if you ask why ping from bash doesn't, actually it does need as well. Do that ls -l /bin/ping.
Since using root was not an option in my case the solution was to allow access to port 7 in the firewall to the specific server I was interested in.
I am not sure what was the state when the original question was asked back in 2012.
As it stands now, ping will be executed as a root. Through the ping executable's authorization you will see the +s flag, and the process belonging to root, meaning it will run as root. run ls -liat on where the ping is located and you should see it.
So, if you run InetAddress.getByName("www.google.com").isReacheable(5000) as root, it should return true.
you need proper authorizations for the raw socket, which is used by ICMP (the protocol used by ping)
InetAddress.getByName is as reliable as ping, but you need proper permissions on the process to have it running properly.
Since you can ping the computer, your Java process should run with sufficient privileges to perform the check. Probably due to use of ports in the lower range. If you run your java program with sudo/superuser, I'll bet it works.
I would suggest that the ONLY reliable way to test an internet connection is to actually connect AND download a file, OR to parse the output of an OS ping call via exec(). You cannot rely on the exit code for ping and isReachable() is crap.
You cannot rely on a ping exit code as it returns 0 if the ping command executes correctly. Unfortunately, ping executes correctly if it can't reach the target host but gets a "Destination host unreachable" from your home ADSL router. This is kind of a reply that gets treated as a successfull hit, thus exit code = 0. Have to add though that this is on a Windows system. Not checked *nixes.
private boolean isReachable(int nping, int wping, String ipping) throws Exception {
int nReceived = 0;
int nLost = 0;
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec("ping -n " + nping + " -w " + wping + " " + ipping);
Scanner scanner = new Scanner(process.getInputStream());
process.waitFor();
ArrayList<String> strings = new ArrayList<>();
String data = "";
//
while (scanner.hasNextLine()) {
String string = scanner.nextLine();
data = data + string + "\n";
strings.add(string);
}
if (data.contains("IP address must be specified.")
|| (data.contains("Ping request could not find host " + ipping + ".")
|| data.contains("Please check the name and try again."))) {
throw new Exception(data);
} else if (nping > strings.size()) {
throw new Exception(data);
}
int index = 2;
for (int i = index; i < nping + index; i++) {
String string = strings.get(i);
if (string.contains("Destination host unreachable.")) {
nLost++;
} else if (string.contains("Request timed out.")) {
nLost++;
} else if (string.contains("bytes") && string.contains("time") && string.contains("TTL")) {
nReceived++;
} else {
}
}
return nReceived > 0;
}
nping is number of try to ping ip(packets), if you have busy network or systems choose biger nping numbers.
wping is time waiting for pong from ip, you can set it 2000ms
for using this method u can write this:
isReachable(5, 2000, "192.168.7.93");
Or using this way:
public static boolean exists(final String host)
{
try
{
InetAddress.getByName(host);
return true;
}
catch (final UnknownHostException exception)
{
exception.printStackTrace();
// Handler
}
return false;
}
InetAddress.isReachable is flappy, and sometimes returns unreachable for addresses which we can ping.
I tried the following:
ping -c 1 <fqdn> and check the exit status.
Works for all the cases i had tried where InetAddress.isReachable doesn't work.
To Check Internet
public boolean isInternetAvailable() {
try {
InetAddress ipAddr = InetAddress.getByName("google.com");
//You can replace it with your name
return !ipAddr.equals("");
} catch (Exception e1) {
try {
Process p1 = java.lang.Runtime.getRuntime().exec("/system/bin/ping -W 1 -c 1 www.google.com");
int returnVal = 0;
returnVal = p1.waitFor();
boolean reachable = (returnVal==0);
return reachable;
} catch (Exception e2) {
e2.printStackTrace();
return false;
}
}
}
To check network connectivity
private boolean isNetworkConnected() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
return cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isConnected();
}
Because isReachable is using the TCP protocol(by WireShark) The Ping command is using ICMP protocol,if you want to return true you need to open the 7 port

Categories

Resources