Ping code java not working - java

I use the following code
InetAddress localhost = InetAddress.getLocalHost();
// this code assumes IPv4 is used
byte[] ip = localhost.getAddress();
for (int i = 1; i <= 254; i++)
{
ip[3] = (byte)i;
InetAddress address = InetAddress.getByAddress(ip);
if (address.isReachable(1000))
{
System.out.println(address + " machine is turned on and can be pinged");
}
else if (!address.getHostAddress().equals(address.getHostName()))
{
System.out.println(address + " machine is known in a DNS lookup");
}
else
{
System.out.println(address + " the host address and host name " +
"are equal, meaning the host name could not be resolved");
}
}
To try and find all online devices on my wifi network.
However, two problems arise.
All 253 tested IPs come back positive
My computer is the only one that has a device name, and the ip is off.
Any help solving this dilemma?

I tried a similar code with oracle jdk 1.8.0_51 and works fine; but when i test it on oracle jre 1.8.0_91 all the ip's of the network segment come back positive.
Maybe is a Bug with InetAddress.isReachable(1000) on the current jre version, a similar bug was reported on openjdk https://bugs.openjdk.java.net/browse/JDK-8145011

Related

Why does HttpServletRequest.getRemoteAddr() with IPv6 address return extra characters

In my Tomcat-hosted web app, the first two lines in a doGet(...) method are:
String ip = request.getRemoteAddr();
System.out.println("ip = " + ip);
With an IPv6 address on our local network, it outputs:
ip = fe80:0:0:0:ac40:98cb:ca2e:c03c%4
The %4 at the end seems extraneous. It is causing requests to our geolocation service to fail. Is this %4 supposed to be there? If so, what does it signify? Is there a reliable way to get a IPv6 address from an HttpServletRequest instance that does NOT have the %4?
It's the scope ID. Using native APIs, your best bet to get rid of it would be as below with help of java.net.InetAddress and Inet6Address#getScopeId():
String ip = request.getRemoteAddr();
InetAddress inetAddress = InetAddress.getByName(ip);
if (inetAddress instanceof Inet6Address) {
Inet6Address inet6Address = (Inet6Address) inetAddress;
int scopeId = inet6Address.getScopeId();
if (scopeId > 0) {
ip = inet6Address.getHostName().replaceAll("%" + scopeId + "$", "");
}
}
This clumsiness is because the standard java.net.Inet6Address API doesn't have any method which returns the bare hostname without scope ID.
On the other hand, I'd wonder if the geolocation service in question should in turn not already be taking that into account. If the support for IPv6 scopes is even not explicitly excluded in their API documentation, then I'd file an issue at their issue tracker.

Get the name and IP of devices on a Wifi network

I know this question has been asked here but it didn't get answered.
I'm writing a simple Java Swing application in which I want to show the name and IP address of each and every device that is connected to my wireless network.
I want to show this list in a JFrame. I searched a lot on the web but couldn't find a way to achieve this. Please help me out Java masters!
Thanks in advance!
I found this code after looking a little bit. It works, but it is slow, and probably not the best way to do it, but it works.
import java.io.IOException;
import java.net.InetAddress;
public class NetworkPing {
/**
* JavaProgrammingForums.com
*/
public static void main(String[] args) throws IOException {
InetAddress localhost = InetAddress.getLocalHost();
// this code assumes IPv4 is used
byte[] ip = localhost.getAddress();
for (int i = 1; i <= 254; i++)
{
ip[3] = (byte)i;
InetAddress address = InetAddress.getByAddress(ip);
if (address.isReachable(1000))
{
System.out.println(address + " machine is turned on and can be pinged");
}
else if (!address.getHostAddress().equals(address.getHostName()))
{
System.out.println(address + " machine is known in a DNS lookup");
}
else
{
System.out.println(address + " the host address and host name are equal, meaning the host name could not be resolved");
}
}
}
}
Couple things to note, address.getHostAddress() returns the 192.168.0.xxx
and address.getHostName() returns the name of the device like "Kevins-PC"
It's a pretty simple piece of code, but I'll walk through it real fast.
It starts off by getting your localhost IP address (which on a normal household network would be 192.168.0.xxx) and it stores that in a byte[] so it looks something like {192, 168, 0, xxx}.
Then it creates a for loop starting at 1 and going to 254 (because this code assumes a /24 subnet mask (255.255.255.0) but if its running a different subnet mask then it might not be 1-254).
Then in the for loop it sets the third index of the ip to i.
It then creates an InetAddress from that address.
Then it tries to reach it in 1000 milliseconds (1 second), and if it succeeds then it prints the address and says its reachable.
Else if the machine host address (the 192.168.0.xxx) does not equal the host name (like the name of your computer like Kevins-PC), then it says that the machine is known in a DNS lookup meaning it is found in a DNS lookup but it wasnt reachable (so its probably off or not connected, but it has been before), DNS is Domain Name Service. The DNS basically stores the information (your router probably does this).
Finally, else it just says it couldn't be resolved which means it wasnt reachable nor was it found looking in the DNS.
I found this code here and here
UPDATE
So if you run this and you just keep getting something like "192.168.0.5/192.168.0.5 the host address and host name are equal, meaning the host name could not be resolved"
That means that your router (your local DNS) just isn't storing the information OR those devices just choose not to submit their host name to the router, and that is why you will continually get that message. As far as I am aware, there isn't a way around this because those device names literally aren't stored
Try this :)
import java.io.IOException;
import java.net.*;
import java.util.Vector;
public class search {
public static void main(String args[]) throws UnknownHostException{
Vector<String> Available_Devices=new Vector<>();
String myip=InetAddress.getLocalHost().getHostAddress();
String mynetworkips=new String();
for(int i=myip.length();i>0;--i) {
if(myip.charAt(i-1)=='.'){ mynetworkips=myip.substring(0,i); break; }
}
System.out.println("My Device IP: " + myip+"\n");
System.out.println("Search log:");
for(int i=1;i<=254;++i){
try {
InetAddress addr=InetAddress.getByName(mynetworkips + new Integer(i).toString());
if (addr.isReachable(1000)){
System.out.println("Available: " + addr.getHostAddress());
Available_Devices.add(addr.getHostAddress());
}
else System.out.println("Not available: "+ addr.getHostAddress());
}catch (IOException ioex){}
}
System.out.println("\nAll Connected devices(" + Available_Devices.size() +"):");
for(int i=0;i<Available_Devices.size();++i) System.out.println(Available_Devices.get(i));
}
}

Retrieving a MAC address from a PING sweep

i have developed a code which enables me to ping a range of IP addresses. The results from my ping sweep identifies what local machines are reachable, if reachable there hostname and also if they are not reachable.
I am having trouble at the moment retrieving the MAC address of the reachable IP addresses. Has anyone got a solution for this?
package networkping;
import java.io.IOException;
import java.net.InetAddress;
/**
*
* #author Learner
*/
public class Networkping {
public static void main(String[] args) throws IOException {
InetAddress localhost = InetAddress.getLocalHost();
// this code assumes IPv4 is used
byte[] ip = localhost.getAddress();
for (int i = 1; i <= 254; i++)
{
ip[3] = (byte)i;
InetAddress address = InetAddress.getByAddress(ip);
if (address.isReachable(1000))
{
System.out.println(address + " Address is reachable" );
}
else if (!address.getHostAddress().equals(address.getHostName()))
{
System.out.println(address + " Address is known in a DNS lookup and is reachable ");
}
else
{
System.out.println(address + " Address is unreachable");
}
}
}
Thanks
You cannot do this just using java.
There are two options:
Execute another process through java and communicate through standard output with your original java application. Such a process is ARP for example.
use JNI as suggested in the comments.
Have a look also at the following resources/answers:
https://stackoverflow.com/a/14650693
https://stackoverflow.com/a/14857412/1688441
The second resource even has an implemented method calling ARP named private String getMac(String ip)

Android IP address with java

I'm writing an Android video game that supports multiplayer. There is a dedicated server running which the androids connect to when the multiplayer button is clicked by opening a socket(this works fine). The server basically just acts as a matchmaking system.
When a client hosts a game, the server adds that client to the list of hosts. Other clients may choose to view this list and then subsequently connect to that host. This is where the problem is. The server is supposed to keep track of the ip/port of hosts, and then other clients are supposed to use this information to open a socket with the host and then the game starts. I'm trying to get the host to send its own IP address to server for other clients to use later.
I have tried many methods so far. One is:
try {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress()) {
return inetAddress.getHostAddress().toString();
}
}
}
} catch (SocketException ex) {
}
This returns 10.0.2.15, which is obviously useless for other clients.
The other method I've tried is this:
String hostName = InetAddress.getLocalHost().getHostName();
InetAddress addrs[] = InetAddress.getAllByName(hostName);
for (InetAddress addr: addrs) {
System.out.println ("addr.getHostAddress() = " + addr.getHostAddress());
System.out.println ("addr.getHostName() = " + addr.getHostName());
System.out.println ("addr.isAnyLocalAddress() = " + addr.isAnyLocalAddress());
System.out.println ("addr.isLinkLocalAddress() = " + addr.isLinkLocalAddress());
System.out.println ("addr.isLoopbackAddress() = " + addr.isLoopbackAddress());
System.out.println ("addr.isMulticastAddress() = " + addr.isMulticastAddress());
System.out.println ("addr.isSiteLocalAddress() = " + addr.isSiteLocalAddress());
System.out.println ("");
if (!addr.isLoopbackAddress()){// && addr.isSiteLocalAddress()) {
myIP = addr.getHostAddress();
}
This returns the ip address that I'm looking for when I run it as a java application, but when I run it as an android application, it doesn't work. The last if condition is somehow not satisfied and myIP ends up being null. Note that I have included the permissions: android.permission.INTERNET, android.permission.ACCESS_WIFI_STATE, android.permission.ACCESS_COARSE_LOCATION, android.permission.ACCESS_NETWORK_STATE.
Can anybody help me?
If you just need the IP for the Wifi connection you can retrieve the IP as a 32 bit integer:
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
int ip = wifiInfo.getIpAddress();
Then, in order to construct the IP in dot-decimal notation; bit-shift and mask the result:
String ipString = String.format(
"%d.%d.%d.%d",
(ip & 0xff),
(ip >> 8 & 0xff),
(ip >> 16 & 0xff),
(ip >> 24 & 0xff));
android.permission.ACCESS_WIFI_STATE permission will be required in the manifest.
Do you have to rely on the host to figure out its own IP address and provide this to the server? If the host opens a connection and sends a message to the server announcing that it is hosting a game, then could the server use the IP address that the connection and message came from? This would avoid the problem altogether.
try this
WifiManager wim= (WifiManager) getSystemService(WIFI_SERVICE) ;
List<WifiConfiguration> l= wim.getConfiguredNetworks();
WifiConfiguration wc=l.get(0);
textview.append( "\n"+ Formatter.formatIpAddress(wim.getConnectionInfo().getIpAddress()));

Client computer name in java

I want to find client computer name in java. My applciation runs in intranet. so i am using below code
public String findClientComputerName(HttpServletRequest request) {
String computerName = null;
String remoteAddress = request.getRemoteAddr();
System.out.println("remoteAddress: " + remoteAddress);
try {
InetAddress inetAddress = InetAddress.getByName(remoteAddress);
System.out.println("inetAddress: " + inetAddress);
computerName = inetAddress.getHostName();
System.out.println("computerName: " + computerName);
if (computerName.equalsIgnoreCase("localhost")) {
computerName = java.net.InetAddress.getLocalHost().getCanonicalHostName();
}
} catch (UnknownHostException e) {
log.error("UnknownHostException detected in StartAction. ", e);
}
if(StringUtils.trim(computerName).length()>0) computerName = computerName.toUpperCase();
System.out.println("computerName: " + computerName);
return computerName;
}
but sometimes i am getting host name properly but some time not. I am getting Correct IP. What may be the reason for this? Why inetAddress.getHostName(); is failing to give host name some time? Your help is very appriciated.
private String getHostName (InetAddress inaHost) throws UnknownHostException
{
try
{
Class clazz = Class.forName("java.net.InetAddress");
Constructor[] constructors = clazz.getDeclaredConstructors();
constructors[0].setAccessible(true);
InetAddress ina = (InetAddress) constructors[0].newInstance();
Field[] fields = ina.getClass().getDeclaredFields();
for (Field field: fields)
{
if (field.getName().equals("nameService"))
{
field.setAccessible(true);
Method[] methods = field.get(null).getClass().getDeclaredMethods();
for (Method method: methods)
{
if (method.getName().equals("getHostByAddr"))
{
method.setAccessible(true);
return (String) method.invoke(field.get (null), inaHost.getAddress());
}
}
}
}
} catch (ClassNotFoundException cnfe) {
} catch (IllegalAccessException iae) {
} catch (InstantiationException ie) {
} catch (InvocationTargetException ite) {
throw (UnknownHostException) ite.getCause();
}
return null;
}
above function returning host name correctly in Intranet. for local it will return localhost.
To get the name for local host we use computerName = java.net.InetAddress.getLocalHost().getCanonicalHostName();
HttpServletRequest will return the IP address (either v4 or v6) of whoever is hitting your servlet. That address may or may not resolve to a valid hostname. InetAddress.getHostName() does a reverse DNS resolution of the IP address. It is not required that each IP address allocated maps back to a valid DNS entry. There are, in fact, a large percent of IP addresses in the world that will not resolve to a hostname.
You can see the same thing using the 'host' command on a linux box to look up the reverse DNS entry (if any) for a given IP address.
The InetAddress.getHostName() function will return the host name if the InetAddress object was initialized with a host name. Otherwise, it'll do a reverse DNS lookup to get the host name.
To get this reverse DNS lookup to work, you'll need to make sure all of the clients on your intranet are configured with host names and that your DNS provider (e.g. your router) properly matches up the host names with its records. (Some routers can do this automatically.)
In order to get the hostname of windows machines, you will need to perform a reverse NetBIOS lookup on the IP address. Windows uses a system called WINS to provide hostnames to its computers. This system is based off NetBIOS.
If you don't want to try to find a specification of the protocol and implement it yourself, then you will want to execute the command nbtstat -A [ip address] if you are on Windows, or nmblookup -A [ip address] if you are on a Linux machine. If you are on a Linux machine, the Samba package will have to be installed as the nmblookup executable is installed on all Linux machines. You will then have to parse the output of that command to get the host name.
The alternative is, as stated before, try to find a specification of the protocol, and implement the part that you need to implement.

Categories