How to get subnet mask of local system using java? - java

How do you get the Subnet mask address of the local system using Java?

the netmask of the first address of the localhost interface:
InetAddress localHost = Inet4Address.getLocalHost();
NetworkInterface networkInterface = NetworkInterface.getByInetAddress(localHost);
networkInterface.getInterfaceAddresses().get(0).getNetworkPrefixLength();
a more complete approach:
InetAddress localHost = Inet4Address.getLocalHost();
NetworkInterface networkInterface = NetworkInterface.getByInetAddress(localHost);
for (InterfaceAddress address : networkInterface.getInterfaceAddresses()) {
System.out.println(address.getNetworkPrefixLength());
}
/24 means 255.255.255.

You can convert the obtained value into the standard textual format like this:
short prflen=...getNetworkPrefixLength();
int shft = 0xffffffff<<(32-prflen);
int oct1 = ((byte) ((shft&0xff000000)>>24)) & 0xff;
int oct2 = ((byte) ((shft&0x00ff0000)>>16)) & 0xff;
int oct3 = ((byte) ((shft&0x0000ff00)>>8)) & 0xff;
int oct4 = ((byte) (shft&0x000000ff)) & 0xff;
String submask = oct1+"."+oct2+"."+oct3+"."+oct4;

java.net.InterfaceAddress in SE6 has a getNetworkPrefixLength method that returns, as the name suggests, the network prefix length. You can calculate the subnet mask from this if you would rather have it in that format. java.net.InterfaceAddress supports both IPv4 and IPv6.
getSubnetMask() in several network application APIs returns subnet mask in java.net.InetAddress form for specified IP address (a local system may have many local IP addresses)

I found that:
NetworkInterface networkInterface = NetworkInterface.getByInetAddress(localHost);
To get subnetmask for ipv6 we can use:
networkInterface.getInterfaceAddresses().get(0).getNetworkPrefixLength();
To get subnetmask for ipv4 we can use:
networkInterface.getInterfaceAddresses().get(1).getNetworkPrefixLength();

I devised an IPv4 only solution that is simple enough. I needed that to generate netmask for subnetworks here in order to delegate those subnets correctly. I know I could have generated a table of the 32 possible masks, but I prefered to get it computed each time.
So here is my solution.
/*
* Get network mask for the IP address and network prefix specified...
* The network mask will be returned has an IP, thus you can
* print it out with .getHostAddress()...
*/
public static InetAddress getIPv4LocalNetMask(InetAddress ip, int netPrefix) {
try {
// Since this is for IPv4, it's 32 bits, so set the sign value of
// the int to "negative"...
int shiftby = (1<<31);
// For the number of bits of the prefix -1 (we already set the sign bit)
for (int i=netPrefix-1; i>0; i--) {
// Shift the sign right... Java makes the sign bit sticky on a shift...
// So no need to "set it back up"...
shiftby = (shiftby >> 1);
}
// Transform the resulting value in xxx.xxx.xxx.xxx format, like if
/// it was a standard address...
String maskString = Integer.toString((shiftby >> 24) & 255) + "." + Integer.toString((shiftby >> 16) & 255) + "." + Integer.toString((shiftby >> 8) & 255) + "." + Integer.toString(shiftby & 255);
// Return the address thus created...
return InetAddress.getByName(maskString);
}
catch(Exception e){e.printStackTrace();
}
// Something went wrong here...
return null;
}
You just call it with the IP and the prefix you want to use, it will generate the netmask for you.

I just finished working on an API for subnetting networks with Java.
https://launchpad.net/subnettingapi
it has that functionality and more.

Here is an answer, how to get a submask from WIFI connection: link
I adapted it for my needs, and here it is:
private static String intToIP(int ipAddress) {
String ret = String.format("%d.%d.%d.%d", (ipAddress & 0xff),
(ipAddress >> 8 & 0xff), (ipAddress >> 16 & 0xff),
(ipAddress >> 24 & 0xff));
return ret;
}
public static String GetSubnetMask_WIFI() {
WifiManager wifiManager = (WifiManager) Global.getMainActivity()
.getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
DhcpInfo dhcp = wifiManager.getDhcpInfo();
String mask = intToIP(dhcp.netmask);
return mask;
}

In summary, a method to obtain the mask would be like this:
public String mascara() throws SocketException{
try{
InetAddress localHost = Inet4Address.getLocalHost();
NetworkInterface networkInterface = NetworkInterface.getByInetAddress(localHost);
prefijo =
""+networkInterface.getInterfaceAddresses().get(0).getNetworkPrefixLength();
int shft = 0xffffffff<<(32-
networkInterface.getInterfaceAddresses().get(0).getNetworkPrefixLength());
int oct1 = ((byte) ((shft&0xff000000)>>24)) & 0xff;
int oct2 = ((byte) ((shft&0x00ff0000)>>16)) & 0xff;
int oct3 = ((byte) ((shft&0x0000ff00)>>8)) & 0xff;
int oct4 = ((byte) (shft&0x000000ff)) & 0xff;
mascara = oct1+"."+oct2+"."+oct3+"."+oct4;
// System.out.println(""+mascara);
}catch(UnknownHostException e){
System.out.println("Error: "+e);
}
return mascara;
}

FWIW, in the past I'd tried using InterfaceAddress.getNetworkPrefixLength() and InterfaceAddress.getBroadcast(), but they don't return accurate info (this is on Windows, with Sun JDK 1.6.0 update 10). The network prefix length is 128 (not 24, which it is on my network), and the broadcast address returned is 255.255.255.255 (not 192.168.1.255, which it is on my network).
James
Update: I just found the solution posted here:
http://forums.sun.com/thread.jspa?threadID=5277744
You need to prevent Java from using IPv6, so that it isn't getting to IPv4 via IPv6.
Adding -Djava.net.preferIPv4Stack=true to the command line fixes the results from InterfaceAddress.getNetworkPrefixLength() and InterfaceAddress.getBroadcast() for me.

Related

Trying to port scan only on local subnet

Currently I've got a working port scanner but I want to limit it to only scanning IP address on the local subnet.
The only solution i've found when digging is this:
Does anyone know a java component to check if IP address is from particular network/netmask? however I dont full understand
What is the difference between a subnet and a netmask? I thought they were the same thing?
Secondly, how can i find the values for subnet and netmask for localHost?
So far this is what I have
NetworkInterface network = NetworkInterface.getByInetAddress(localHost);
short subnetMask =
network.getInterfaceAddresses().get(1).getNetworkPrefixLength();
But is this the netmask or the subnet? And how do I get the other value?
The subnetMask you determined is the number of bits in the network. The network address is found by setting all bits in the address that are after the bits in the mask to zero. This code should print the mask and network address in the usual form.
NetworkInterface network = NetworkInterface.getByInetAddress(localhost);
short subnetMask
= network.getInterfaceAddresses().get(1).getNetworkPrefixLength();
int address_int = ByteBuffer.wrap(localhost.getAddress()).getInt();
int mask_int = 0;
for(int i = 0; i < subnetMask-1; i++) {
mask_int = mask_int | (1<<31);
mask_int = mask_int >> 1;
}
byte mask_bytes[] = ByteBuffer.allocate(4).putInt(mask_int).array();
InetAddress mask_address = InetAddress.getByAddress(mask_bytes);
System.out.println("mask_address = " + mask_address);
int network_int = mask_int & address_int;
byte network_bytes[] = ByteBuffer.allocate(4).putInt(network_int).array();
InetAddress network_address = InetAddress.getByAddress(network_bytes);
System.out.println("network_address = " + network_address);
You can test if any address is on this network by using the bitwise and of the address in integer form with the network_mask integer. If it is on the network this should produce the address_int.

How to put in an entry into dnsjava cache to override DNS lookup

In trying to avoid having a hostname looked up from the public DNS for testing purposes, I need to essentially set /etc/hosts file, but I don't always know what hostnames I'll need to override the IP address for, so I'm trying to use dnsjava since the default Java DNS resolving doesn't allow for inserting directly into the cache.
Basically, you need to grab the correct DNS Type cache for dnsjava (A, AAAA, etc). Most likely A (for IPv4) or AAAA (for IPv6) is what you should use, although all of the other DNS entry types are also supported. You'll need to create a Name instance, and from that an ARecord which will be inserted into the Cache. Example is as below:
public void addHostToCacheAs(String hostname, String ipAddress) throws UnknownHostException, TextParseException {
//add an ending period assuming the hostname is truly an absolute hostname
Name host = new Name(hostname + ".");
//putting in a good long TTL, and using an A record, but AAAA might be desired as well for IPv6
Record aRec = new ARecord(host, Type.A, 9999999, getInetAddressFromString(ipAddress));
Lookup.getDefaultCache(Type.A).addRecord(aRec, Credibility.NORMAL,this);
}
public InetAddress getInetAddressFromString(String ip) throws UnknownHostException {
//Assume we are using IPv4
byte[] bytes = new byte[4];
String[] ipParts = ip.split("\\.");
InetAddress addr = null;
//if we only have one part, it must actually be a hostname, rather than a real IP
if (ipParts.length <= 1) {
addr = InetAddress.getByName(ip);
} else {
for (int i = 0; i < ipParts.length; i++) {
bytes[i] = Byte.parseByte(ipParts[i]);
}
addr = InetAddress.getByAddress(bytes);
}
return addr
}

How to get Public IP address of the device?

Is it possible to get the public IP address of the device using some Java code in Android?
Can I use curl with php to remote server to know the public IP? But I don't know how to use curl in Java.
I need the code for user's country based on the public IP address.
I Only need the code for public ip of the user later see the country
public String getIpAddr() {
WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
nt ip = wifiInfo.getIpAddress();
String ipString = String.format(
"%d.%d.%d.%d",
(ip & 0xff),
(ip >> 8 & 0xff),
(ip >> 16 & 0xff),
(ip >> 24 & 0xff));
return ipString;
}
Please Note: You need to add android.permission.INTERNET and android.permission.ACCESS_WIFI_STATE in your AndroidManifest.xml as to access the code.
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
via Detect wifi IP address on Android? , user Tanmay Mandal

Is there any method to find the ip address of nearest access point in my wifi network?

I use inssider and kismac for checking the wifi indoor and outdoor accesspoints in my network. But both these tools doesn't provide any info on the ip of the access point currently connected. Its seen that netstumbler in windows had an option to display ip address and subnet but, though they have the fields, it doesn't display anything. I don't find any app that fulfills this requirement.
Is there any method to find the ip address of the nearest accesspoint in my wifi network? programmatically or is there any app?
is there any method in python , objective c , java where a request for ip-address of an ap returns it.
I use osx 10.9
use following way to achieve
public String getIpAddr() {
WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
int ip = wifiInfo.getIpAddress();
String ipString = String.format(
"%d.%d.%d.%d",
(ip & 0xff),
(ip >> 8 & 0xff),
(ip >> 16 & 0xff),
(ip >> 24 & 0xff));
return ipString;
}
Please Note: You need to add android.permission.INTERNET and android.permission.ACCESS_WIFI_STATE in your AndroidManifest.xml as to access the code.
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
for google play similar type of app look at https://play.google.com/store/apps/details?id=com.roamingsoft.manager&hl=en
You cant get ip of AP without connecting to it.
You can get ip of connected AP by following
DhcpInfo dhcp;
WifiManager wifii;
wifii = (WifiManager) getSystemService(Context.WIFI_SERVICE);
dhcp = wifii.getDhcpInfo();
s_dns1 = "DNS 1: " + String.valueOf(dhcp.dns1);
s_dns2 = "DNS 2: " + String.valueOf(dhcp.dns2);
s_gateway = "Default Gateway: " + String.valueOf(dhcp.gateway);
s_ipAddress = "IP Address: " + String.valueOf(dhcp.ipAddress);
s_leaseDuration = "Lease Time: " + String.valueOf(dhcp.leaseDuration);
s_netmask = "Subnet Mask: " + String.valueOf(dhcp.netmask);
s_serverAddress = "Server IP: " + String.valueOf(dhcp.serverAddress);

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

Categories