Retrieving a MAC address from a PING sweep - java

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)

Related

Ping code java not working

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

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));
}
}

Finding string to address serial port dynamically

I have an application developed in Java, and a second under development in Ruby on Rails, which require connecting to Arduino by serial communication. While I can input a string based on my own computer to address the correct serial port, the string changes depending even on which USB port I use, which makes me think it would be better for the user to be able to select a valid serial port from one that is scanned from a list on their own computers, not one predefined by me. Does anyone have a strategy I can use for allowing the user to scan their computer for all serial ports and select the correct one out of an array/list, either in Java or Ruby on Rails?
From List the ports:
import java.util.Enumeration;
import javax.comm.CommPortIdentifier;
/**
* List the ports.
*
* #author Ian F. Darwin, http://www.darwinsys.com/
* #version $Id: CommPortLister.java,v 1.4 2004/02/09 03:33:51 ian Exp $
*/
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.
Enumeration pList = CommPortIdentifier.getPortIdentifiers();
// Process the list.
while (pList.hasMoreElements()) {
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);
}
}
}
}

how to get the ip address of the connected interface

the way how we get Ip address using java code is clear and many questions about this subject were answered.
but assuming that you have Vmware or VirtualBox on your machine,so you will have extra virtual network cards each one have its own Ip Address.
when executing a little program the result was like 192.168.x.x which belongs to one of my virtual network adapters.
but using "What Is My IP" the result was like 197.x.x.x
so how can i get the ip adress of the connected interface ?
this should do the trick:
import java.io.*;
import java.util.*;
public class ExecTest {
public static void main(String[] args) throws IOException {
Process result = Runtime.getRuntime().exec("traceroute -m 1 www.amazon.com");
BufferedReader output = new BufferedReader(new InputStreamReader(result.getInputStream()));
String thisLine = output.readLine();
StringTokenizer st = new StringTokenizer(thisLine);
st.nextToken();
String gateway = st.nextToken();
System.out.printf("The gateway is %s\n", gateway);
}
}
Courtesy of Chris Bunch from: How can I determine the IP of my router/gateway in Java?
Greets!
Your interface IP 192.168.x.x is your local adapter interface. The prefix 192.168 indicates that this is a private non-routable address that is valid only behind a NAT firewall.
The IP returned by WhatIsMyIP is the external address of the firewall/gateway through which you access the Internet. Unless your computer is connected directly to the Internet these two addresses will never be the same.

How do you tell whether a string is an IP or a hostname

So you have a String that is retrieved from an admin web UI (so it is definitely a String). How can you find out whether this string is an IP address or a hostname in Java?
Update: I think I didn't make myself clear, I was more asking if there is anything in the Java SDK that I can use to distinguish between IPs and hostnames? Sorry for the confusion and thanks for everybody who took/will take the time to answer this.
You can use a regular expression with this pattern:
\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b
That will tell you if it's an IPv4 address.
Do we get to make the assumption that it is one or the other, and not something completely different? If so, I'd probably use a regex to see if it matched the "dotted quad" format.
You can see if the string matches the number.number.number.number format, for example:
\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b
will match anything from 0 - 999.
Anything else you can have it default to hostname.
URI validator = new URI(yourString);
That code will validate the IP address or Hostname. (It throws a malformed URI Exception if the string is invalid)
If you are trying to distinguish the two..then I miss read your question.
You can use a security manager with the InetAddress.getByName(addr) call.
If the addr is not a dotted quad, getByName will attempt to perform a connect to do the name lookup, which the security manager can capture as a checkConnect(addr, -1) call, resulting in a thrown SecurityException that you can catch.
You can use System.setSecurityManager() if you're running fully privileged to insert your custom security manager before the getByName call is made.
It is not as simple as it may appear, there are some ambiguities around characters like hyphens, underscore, and square brackets '-', '_', '[]'.
The Java SDK is has some limitations in this area. When using InetAddress.getByName it will go out onto the network to do a DNS name resolution and resolve the address, which is expensive and unnecessary if all you want is to detect host vs address. Also, if an address is written in a slightly different but valid format (common in IPv6) doing a string comparison on the results of InetAddress.getByName will not work.
The IPAddress Java library will do it. The javadoc is available at the link. Disclaimer: I am the project manager.
static void check(HostName host) {
try {
host.validate();
if(host.isAddress()) {
System.out.println("address: " + host.asAddress());
} else {
System.out.println("host name: " + host);
}
} catch(HostNameException e) {
System.out.println(e.getMessage());
}
}
public static void main(String[] args) {
HostName host = new HostName("1.2.3.4");
check(host);
host = new HostName("1.2.a.4");
check(host);
host = new HostName("::1");
check(host);
host = new HostName("[::1]");
check(host);
host = new HostName("1.2.?.4");
check(host);
}
Output:
address: 1.2.3.4
host name: 1.2.a.4
address: ::1
address: ::1
1.2.?.4 Host error: invalid character at index 4
Couldn't you just to a regexp match on it?
Use InetAddress#getAllByName(String hostOrIp) - if hostOrIp is an IP-address the result is an array with single InetAddress and it's .getHostAddress() returns the same string as hostOrIp.
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
public class IPvsHostTest {
private static final org.slf4j.Logger LOG = org.slf4j.LoggerFactory.getLogger(IPvsHostTest.class);
#org.junit.Test
public void checkHostValidity() {
Arrays.asList("10.10.10.10", "google.com").forEach( hostname -> isHost(hostname));
}
private void isHost(String ip){
try {
InetAddress[] ips = InetAddress.getAllByName(ip);
LOG.info("IP-addresses for {}", ip);
Arrays.asList(ips).forEach( ia -> {
LOG.info(ia.getHostAddress());
});
} catch (UnknownHostException e) {
LOG.error("Invalid hostname", e);
}
}
}
The output:
IP-addresses for 10.10.10.10
10.10.10.10
IP-addresses for google.com
64.233.164.100
64.233.164.138
64.233.164.139
64.233.164.113
64.233.164.102
64.233.164.101
This code still performs the DNS lookup if a host name is specified, but at least it skips the reverse lookup that may be performed with other approaches:
...
isDottedQuad("1.2.3.4");
isDottedQuad("google.com");
...
boolean isDottedQuad(String hostOrIP) throws UnknownHostException {
InetAddress inet = InetAddress.getByName(hostOrIP);
boolean b = inet.toString().startsWith("/");
System.out.println("Is " + hostOrIP + " dotted quad? " + b + " (" + inet.toString() + ")");
return b;
}
It generates this output:
Is 1.2.3.4 dotted quad? true (/1.2.3.4)
Is google.com dotted quad? false (google.com/172.217.12.238)
Do you think we can expect the toString() behavior to change anytime soon?

Categories