Getting mac address without internet connection in java - java

I have a chunk of code that returns the mac address of a PC very correctly, but that's only when there is an internet access, but I need it offline in a project I'm carrying out. If not possible, is there any other possible way of uniquely identifying a PC?

You certainly use an indirection based on the IP address, in your code snippet. This may explain why you do not get anything when Internet network access is down.
Here is a code snippet that does not depend on the network connection status.
It displays each MAC address of your PC. Note that a PC often has multiple MAC addresses. Each address will be displayed by this code snippet.
package com.stackoverflow;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;
public class GetHWAddresses {
public static void main(String[] args) throws SocketException {
final Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces();
while (e.hasMoreElements()) {
final byte [] mac = e.nextElement().getHardwareAddress();
if (mac != null) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < mac.length; i++)
sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : ""));
System.out.println(sb.toString());
}
}
}
}

Related

How to spoof NetworkInterface.getHardwareAddress() (Java)

I have a software running in OpenShift (Kubernetes) where the licence is based on the MAC address. When restarting the app, the MAC address of the container changes and I have to apply for a new licence file.
Since there are no static MAC-Adressess in k8s pods, I want to spoof the Java call to NetworkInterface.getHardwareAddress() to trick the software into thinking the MAC Address is still the same.
Enumeration enumeration = NetworkInterface.getNetworkInterfaces();
while (enumeration.hasMoreElements()) {
NetworkInterface networkInterface = (NetworkInterface) enumeration.nextElement();
if (networkInterface.isLoopback() || networkInterface.isPointToPoint() || networkInterface.isVirtual()) {
continue;
}
if (networkInterface.isUp()) {
byte[] arrayOfByte = networkInterface.getHardwareAddress();
if (arrayOfByte != null && arrayOfByte.length == 6) {
StringBuilder stringBuilder = new StringBuilder();
for (byte b = 0; b < arrayOfByte.length; b++) {
if (b != 0) {
stringBuilder.append(":");
}
stringBuilder.append(String.format("%02x", arrayOfByte[b]));
}
System.out.println(networkInterface.getName() + ": " + stringBuilder);
}
}
}
actual: eth0: 01:14:4d:ec:01:42
expected: eth0: ee:ee:ee:ee:ee:ee
Unfortunately, you cannot do this in Java.
The method NetworkInterface::getNetworkInterfaces() is implemented as native, which means it does not access any specific field to obtain its results. If it did, you might have luck hacking stuff with reflection, but as it stands, you have to manage it in your OS configuration instead.
EDIT: As for Kubernetes solutions, you might want to look here

How to find MAC address of another device in Java or Android

How can I find MAC address of another device (Cellphones, Printers, Computers) on LAN using Java or Android? I had read all the answer related to this there but most of them are finding MAC address of their own Device which is possible.
What I need is I put IP address of another device on my LAN and it will return the MAC address. The code which I am currently trying is mentioned below.
public static String findMACForIP(String IP) throws SocketException, UnknownHostException {
NetworkInterface network = NetworkInterface.getByInetAddress(InetAddress.getByName(IP));
if (network != null) {
byte[] mac = network.getHardwareAddress();
StringBuilder sb = new StringBuilder();
for (int x = 0; x < mac.length; x++) {
sb.append(String.format("%02X%s", mac[x], (x < mac.length - 1) ? "-" : ""));
}
Log.d(Config.TAG, "MAC:" + sb.toString());
return sb.toString();
}
return null;
}
The above code clear means that it is trying to find the interface to which the given IP is assigned, so in case of someone other computer/device it will be not able to find that interface as that exists on that device, not our so it will return null as a result I am receiving null.
But when I input my own device IP(android device IP) it is returning its MAC address since the above can find an interface with that IP.
What I want is someone another computer MAC. it is possible because there are many apps on google play store which actually get the MAC address of all the device on LAN.

What is the root cause of the "USB Host support is unavailable" message?

I am trying to send data over a USB to serial cable using the jUSB library. I'm coding in the NetBeans IDE on Windows.
What is the problem behind the message: "USB Host support is unavailable" in the following code:
package usb.core;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import usb.core.*;
public class Main {
public static void main(String[] args) throws IOException {
try {
// Bootstrap by getting the USB Host from the HostFactory.
Host host = HostFactory.getHost();
// Obtain a list of the USB buses available on the Host.
Bus[] bus = host.getBusses();
int total_bus = bus.length;
System.out.println(total_bus);
// Traverse through all the USB buses.
for (int i = 0; i < total_bus; i++) {
// Access the root hub on the USB bus and obtain the
// number of USB ports available on the root hub.
Device root = bus[i].getRootHub();
int total_port = root.getNumPorts();
// Traverse through all the USB ports available on the
// root hub. It should be mentioned that the numbering
// starts from 1, not 0.
for (int j = 1; j <= total_port; j++) {
// Obtain the Device connected to the port.
Device device = root.getChild(j);
if (device != null) {
// USB device available, do something here.
// Obtain the current Configuration of the device
// and the number of interfaces available under the
// current Configuration.
Configuration config = device.getConfiguration();
int total_interface = config.getNumInterfaces();
// Traverse through the Interfaces
for (int k = 0; k < total_interface; k++) {
// Access the current Interface and obtain the
// number of endpoints available on the Interface
Interface itf = config.getInterface(k, 0);
int total_ep = itf.getNumEndpoints();
// Traverse through all the endpoints.
for (int l = 0; l < total_ep; l++) {
// Access the endpoint and
// obtain its I/O type
Endpoint ep = itf.getEndpoint(l);
String io_type = ep.getType();
boolean input = ep.isInput();
// If the endpoint is an input endpoint,
// obtain its InputStream and read in data.
if (input) {
InputStream in;
in = ep.getInputStream();
// Read in data here
in.close();
}
else {
// If the Endpoint is an output Endpoint,
// obtain its OutputStream and
// write out data.
OutputStream out;
out = ep.getOutputStream();
// Write out data here.
out.close();
}
}
}
}
}
}
}
catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
I Googled that error message and I found:
A forum post from 2005 that said that on Linux this can be due to something else having grabbed exclusive use of the USB controller: http://bytes.com/topic/java/answers/16736-jusb
An online copy of the source code, which indicates that this happens if getHost's attempt to create a (platform specific) HostFactory fails. Unfortunately, the code eats unexpected exceptions (*), so it you'll need to use a Java debugger to figure out what the real code is.
(* The code catches Exception in maybeGetHost and other places and throws away the diagnostics! This is a major no-no, and a big red flag on overall code quality of the library. If I were you, I'd be looking for a better quality library to use.)

How can I get the actual IP in a linux machine from Java

I am trying to get the local IP address from a Linux machine BUT NOT get the loopback.
To do that I am using the following code (I am not sure if what I am doing is correct):
NetworkInterface ni = NetworkInterface.getByName("eth0");
Enumeration<InetAddress> inetAddresses = ni.getInetAddresses();
while(inetAddresses.hasMoreElements()) {
InetAddress ia = inetAddresses.nextElement();
if(!ia.isLinkLocalAddress()) {
//this is not loopback
}
}
When I run this I get 2 IPs (I was interested only in one of these) which when I do an ifconfig I see one (the one I want to get) is
in the entry for eth0 while the other is in the entry for eth0:54.
I don't even know what is eth0:54.
How can I get the IP I want?
Linux machines can have more than one IP address including loopback. There is no concept of uniqueness for IP addresses.
What you might be looking for is the hostname (and its IP address) You can get this by reading /etc/hostname and looking up its IP address. Note: its possible it doesn't have an IP address if the machine is not setup in a normal manner.
Any modern computer have multiple IP-numbers, 127.0.0.1 being one of them. The actual configuration does not always get correctly reported up to the Java layer (in my experience).
You may simply want to execute /sbin/ifconfig -a on a scheduled basis (or at startup time) and log the complete output.
I had the same question but using PHP instead of Java:
Simply find the ip address of server
The best answer was that its not generally possible without serious back flips which doesn't really have to do with the language you are using and more to do with the underlying system.
Try this,
import java.io.*;
import java.net.*;
import java.util.*;
import static java.lang.System.out;
public class ListNets {
public static void main(String args[]) throws SocketException, UnknownHostException {
System.out.println(System.getProperty("os.name"));
Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();
for (NetworkInterface netint : Collections.list(nets))
if (netint.getName().equals("wlan0") || netint.getName().equals("en0")) {
displayInterfaceInformation(netint);
}
}
static void displayInterfaceInformation(NetworkInterface netint) throws SocketException {
out.printf("Display name: %s\n", netint.getDisplayName());
out.printf("Name: %s\n", netint.getName());
Enumeration<InetAddress> inetAddresses = netint.getInetAddresses();
for (InetAddress inetAddress : Collections.list(inetAddresses)) {
out.printf("InetAddress: %s\n", inetAddress);
}
out.printf("\n");
}
}

How to use multicast on a multi-homed system (Java, Linux)

This is in Java, but I can always revert to C via JNI if needed.
I have a system with two NICs, each connected to a distinct subnet. I want to use multicast (in particular, SDP) to discover other hosts on both networks.
One network is easy: create a MulticastSocket on the specified port, joinGroup it, and I get packets. Simplicity.
Two networks: so far impossible. I've tried:
1) creating two sockets, binding to the same port and using setInterface() or setNetworkInterface() to "connect" to the right interface. No luck, even after various permutations of setReuseAddress().
2) create a single socket, and then attempt to join twice, with two calls to joinGroup(SocketAddress mcastaddr, NetworkInterface netIf). The second join call fails.
Solutions outside of Java would be great. In particular, if I could set up multicast routes that would effectively 'combine' the two interfaces (I could then look at each packet to determine which network) that would be fine. As I mentioned before, any amount of native code is usable in this environment (Linux, with the Apache "luni" java infrastructure).
Thanks!
Coincidentally, I was working on a similar problem recently.
Here's some Java code which does what you want -- it picks up SDP packets on several interfaces. joinGroup is used to "attach" to the specified interfaces.
/**
* Demonstrate multi-homed multicast listening
*
* usage: java Multihome eth0 eth1 lo <etc>
*/
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.MulticastSocket;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
public class Multihome {
// SDP constants
public static final String MULTICAST_ADDRESS = "239.255.255.250";
public static final int MULTICAST_PORT = 1900;
// args: each arg is the name of an interface.
public void doMain(Set<String> args)
throws Exception
{
InetSocketAddress socketAddress =
new InetSocketAddress(MULTICAST_ADDRESS, MULTICAST_PORT);
MulticastSocket socket = new MulticastSocket(MULTICAST_PORT);
Enumeration<NetworkInterface> ifs =
NetworkInterface.getNetworkInterfaces();
while (ifs.hasMoreElements()) {
NetworkInterface xface = ifs.nextElement();
Enumeration<InetAddress> addrs = xface.getInetAddresses();
String name = xface.getName();
while (addrs.hasMoreElements()) {
InetAddress addr = addrs.nextElement();
System.out.println(name + " ... has addr " + addr);
}
if (args.contains(name)) {
System.out.println("Adding " + name + " to our interface set");
socket.joinGroup(socketAddress, xface);
}
}
byte[] buffer = new byte[1500];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
while (true) {
try {
packet.setData(buffer, 0, buffer.length);
socket.receive(packet);
System.out.println("Received pkt from " + packet.getAddress() +
" of length " + packet.getLength());
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
public static void main(String[] args)
throws Exception
{
Set<String> argSet = new HashSet<String>();
Multihome multi = new Multihome();
for (String arg : args) {
argSet.add(arg);
}
multi.doMain(argSet);
}
}
I'd recommend using JGroups, which abstracts everything you're trying to do, if I understand your needs correctly. it's an elegant and well-made framework for multicast (and multicast-like semantics, emulated when necessary).
I have no reasonable setup to try this here, but receiving multicast messages should not require the MulticastSocket to be bound to the port number from the multicast address and setNetworkInterface is used to set the interface used for outbound messages.
What I would try to create two different MulticastSockets (on any free port) and then use joinGroup(SocketAddress mcastaddr, NetworkInterface netIf) on each of them using the same multicast address, but different network interfaces.
Have you considered using ZeroConf for this?
The jmdns project has a pure java implementation which should work very well.

Categories

Resources