I am working on a LAN based software, for which I require to detect the range in which systems in the network lies, using java. The function is required to be similar to "Detect local IP range" in netscan, a windows utility software. Any help in this regard will be highly appreciated.
If you are wanting the actual local subnet IP range, rather than a list of alive IP addresses in the local subnet, you can use the following code to get the subnet mask size:
InetAddress localHost = Inet4Address.getLocalHost();
NetworkInterface ni = NetworkInterface.getByInetAddress(localHost);
InterfaceAddress ia = ni.getInterfaceAddresses().get(0);
short mask = ia.getNetworkPrefixLength();
That will give you a short primitive with a value of 1-32, probably 24. Then you can use
byte[] b = ia.getAddress().getAddress();
Which will give you a byte[] which you will mask against the subnet mask to give you the local address range in some usable format.
Alternatively if you want a list of alive hosts on the local subnet, an arp-scan using JPCap is the method I would use.
You can try using "ping".
This post has some code on ping to start.
How to do a true Java ping from Windows?
Related
This question already has answers here:
Converting CIDR address to subnet mask and network address
(11 answers)
Closed 8 years ago.
How can I convert cidr to ip range in java ? I have used apache SubnetUtils but its ignoring first and last value of the range.
e.g
for CIDR 192.168.1.0/16 output should be 192.168.0.0 to 192.168.255.255.
but I am getting 192.168.0.1 to 192.168.255.254.
Please help
The SubnetUtils class by default excludes the zeroth and last address from the range of usable "host" addresses because they are (or were, in the case of the zeroth address) used as the network broadcast address.
You need to invoke the .setInclusiveHostCount(true) method on your SubnetUtils instance to tell it to include those addresses within the returned range.
Actually,first and last value will be ignored beacuse of the specialitty which it carries.Theses are not general purpose IP-Addresses.The Class C IP Addresses range will be this only.You need to read more about "Subnetting and Addressing in Class C Type IP-Addresses".
192.168.0.0--->By convention, network routers and other gateways use 192.168.0.0 to reference a private network generically!Being private, 192.168.0.0 and all other addresses within this network cannot be used on the Internet.It's not like a general IP-Address.It is the host's IP Address(by default),you can't change it!
192.168.255.255--->Broadcasting Address in the network,again not a general IP Address as it is used to broadcast the data to all other computers on the network!
What data type is recommended to store range of IP addresses?
For eg,
"IP1":["12.21.31.0/24"],
"IP2":["13.96.210.122/28","12.33.116.17/21"]
The data is in JSON format. I have a java object that is parsing this JSON information. I am just not sure what data type to go ahead with in the Java class. Please suggest.
The InetAddress class would be the ideal type store IP addresses. It is a lot more than you've asked for here. But would be useful for getting IP from name/address or the other way round.
Since you are using CIDR masks not supported by INetAddress you'll need other types
Code sample using Apache SubnetUtils
String subnet = "12.21.31.0/24";
SubnetUtils utils = new SubnetUtils(subnet);
utils.getInfo().isInRange(address);
Code sample using CIDRUtils
CIDRUtils cidrUtils = new CIDRUtils("10.21.31.0/24");
String networkAddress = cidrUtils.getNetworkAddress();
String broadcastAddress = cidrUtils.getBroadcastAddress();
IP addresses can be represented as 32-bit integers (128-bit for IPv6). So, you could simply treat ranges as ranges of integers. You could then consider a TreeSet, a bit mask, or some other data structure, depending on how you query. Alternately, perhaps a RangeSet of either integers or a IP address wrapper class you write that implements Comparable would be a good solution.
Is there any JAVA or LINUX way to extract decimal formatted IPV6 ip address.
Or
Is there any JAVA or LINUX way to covert IPV6 ip to IPV4 format.
Thanks.
Dnyanesh.
Is there any JAVA or LINUX way to extract decimal formatted IPV6 ip address.
No. IPv6 addresses are always presented in hexadecimal.
Or Is there any JAVA or LINUX way to covert IPV6 ip to IPV4 format.
No. They're completely different address types.
Well, IPv6 addresses are just 16 bytes (and a netmask), in the same way IPv4 addresses are 4 bytes. So, printing them in decimal is certainly possible. The question is, though, why you'd want to do that, given that everybody writes these addresses in hex.
While there is a specific address range within IPv6 for embedding IPv4 addresses (and you're free to create new ones in your own infrastructure), this is obviously not generically possible.
If your real question is "how do I talk to an IPv6 host if I only have IPv4", then the answer is more complicated and involves tunneling IPv6 traffic within IPv4.
http://www.networkworld.com/news/2010/050610-ipv6-tunnel-basics.html has a comprehensive overview about the options available. The TLDR summary: you probably should use Teredo for ad-hoc access to IPv6 (Linux client: http://www.remlab.net/miredo/). If you want to connect a server and can't get IPv6 service from your provider, the best answer used to be 6to4 (in my experience), but these days it's more useful to tell your provider to get their act together. Or change providers.
Depends on what you mean by extract.
The IPAddress Java library will do some or all of what you ask. The javadoc is available at the link. Disclaimer: I am the project manager.
The library parses IPv4 and IPv6. It allows you to produce various strings of different formats, and you could call the toNormalizedString(IPStringOptions) method to produce an IPv6 string with a decimal format, even though IPv6 is generally hexadecimal.
The library allows you to extract an IPv4 address from an IPv6 address using IPAddress.getEmbeddedIPv4Address(), as shown:
String str = "1::1";//ipv6 address
IPAddressString addrString = new IPAddressString(str);
try {
IPAddress addr = addrString.toAddress();//parse the ipv6 address
IPAddress addr2 = addr.getEmbeddedIPv4Address()//extract the ipv4 address 0.0.0.1 from the terminating bytes
...
} catch(AddressStringException e) {
//e.getMessage provides validation issue
}
Recently I was given a task at my company where I have to create a function like this:
boolean addrMatch(String IP, String netMask);
This has nothing to do with routing. We have a network service that will use this function. The IP parameter varies upon all requests, the netMask parameter is user-supplied. The function must tell that an actual IP address matches with the supplied netmask or not. This is something like the user tells our system to only serve requests on the public internet to a specific subset of IP addresses, not all of them.
My networking related knowledge is far from complete, so I did a deep search on the topic, but I didn't get very far.
What I know (or been told): all the two parameteres are valid IP addresses or netmasks in xxx.xxx.xxx.xxx notation. I have to do a bitwise AND on them (obviously after converting them into BitSet or at least byte[] array). But I guess this is not the complete algorithm.
So my question: what is the correct algorithm for matching an IP address with a netmask?
ps.: I'm working in Java, but I need the generic method.
A netmask is just a bitmask. Basically if address & netmask != 0 the address is in the subnet represented by the netmask. The implementation details you have to cope with are bytes instead of bits, and varying numbers of bytes depending on whether you have IPv4 or IPv6. But it's basically trivial.
In Java, I'd like to find the java.net.NetworkInterface corresponding with the interface used reach the default gateway. The names of the interfaces, etc, are not know ahead of time.
In other-words, if the following was my routing table, I would want the interface corresponding with "bond0":
$ netstat -r
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
10.10.10.0 * 255.255.255.0 U 0 0 0 bond0
10.10.11.0 * 255.255.255.0 U 0 0 0 eth2
10.10.11.0 * 255.255.255.0 U 0 0 0 eth3
10.10.12.0 * 255.255.255.0 U 0 0 0 eth4
10.10.13.0 * 255.255.255.0 U 0 0 0 eth5
default mygateway 0.0.0.0 UG 0 0 0 bond0
After doing some google searching, I still haven't found any answer.
edit:
The java runtime must "know" how to get this information (not to say that it's exposed). When joining a java.net.MulticastSocket to a multicast group using the join(InetAddress grpAddr) call (which does not specify an interface), the apparent behavior seems to be to join on the "default" interface (as define above). This works even when the default intf is not the first interface listed in the routing table. However, the underlying POSIX call that joins an mcast group requires this information!:
struct ip_mreqn group;
group.imr_multiaddr = ...
group.imr_address = **address of the interface!**
setsockopty(sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &group, sizeof(group));
The point: by providing a method to join a multicast group that doesn't require the intf, the java platform, implicitly, must know how to determine the appropriate intf on each platform.
My way is:
try(DatagramSocket s=new DatagramSocket())
{
s.connect(InetAddress.getByAddress(new byte[]{1,1,1,1}), 0);
return NetworkInterface.getByInetAddress(s.getLocalAddress()).getHardwareAddress();
}
Because of using datagram (UDP), it isn't connecting anywhere, so port number may be meaningless and remote address (1.1.1.1) needn't be reachable, just routable.
As far as I know, there will be no good way to do this, because such low level details are very difficult for Java to implement in a cross-platform way. java.net.NetworkInterface may help a little, but if the available methods aren't enough you might have to resort to something a little uglier.
Is this something that will run on a specified platform forever, or does it need to be more portable? At worst, you could try to exec a system command and parse the output, but this is not very portable or stable.
Some related topics:
Is it possible to get the default gateway IP and MAC addresses in java?
Finding SSID of a wireless network with Java