I need to determine if given IP address is from some special network in order to authenticate automatically.
Once you have your IP addresses as plain int s you can do some bit arithmetic to perform the check: int subnet = 0x0A010100; // 10.1. 1.0/24 int bits = 24; int ip = 0x0A010163; // 10.1. 1.99 // Create bitmask to clear out irrelevant bits.
The most common subnet you will see is 255.255. 255.0. So if two addresses match in the first three sections (reading left to right), and the subnet is 255.255. 255.0 for both addresses, they are in the same subnet.
How do I identify an unknown device on my network? To see all of the devices connected to your network, type arp -a in a Command Prompt window. This will show you the allocated IP addresses and the MAC addresses of all connected devices.
Use spring-security-web
's IpAddressMatcher. Unlike Apache Commons Net, it supports both ipv4 and ipv6.
import org.springframework.security.web.util.matcher.IpAddressMatcher; ... private void checkIpMatch() { matches("192.168.2.1", "192.168.2.1"); // true matches("192.168.2.1", "192.168.2.0/32"); // false matches("192.168.2.5", "192.168.2.0/24"); // true matches("92.168.2.1", "fe80:0:0:0:0:0:c0a8:1/120"); // false matches("fe80:0:0:0:0:0:c0a8:11", "fe80:0:0:0:0:0:c0a8:1/120"); // true matches("fe80:0:0:0:0:0:c0a8:11", "fe80:0:0:0:0:0:c0a8:1/128"); // false matches("fe80:0:0:0:0:0:c0a8:11", "192.168.2.0/32"); // false } private boolean matches(String ip, String subnet) { IpAddressMatcher ipAddressMatcher = new IpAddressMatcher(subnet); return ipAddressMatcher.matches(ip); }
The code in previous part works perfectly fine but it needs spring-security-web
to be included.
If you are not willing to include Spring framework in your project, you may use this class which is a slightly modified version of the original class from Spring, so that it has no non-JRE dependencies.
/* * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import java.net.InetAddress; import java.net.UnknownHostException; /** * Matches a request based on IP Address or subnet mask matching against the remote * address. * <p> * Both IPv6 and IPv4 addresses are supported, but a matcher which is configured with an * IPv4 address will never match a request which returns an IPv6 address, and vice-versa. * * @author Luke Taylor * @since 3.0.2 * * Slightly modified by omidzk to have zero dependency to any frameworks other than the JRE. */ public final class IpAddressMatcher { private final int nMaskBits; private final InetAddress requiredAddress; /** * Takes a specific IP address or a range specified using the IP/Netmask (e.g. * 192.168.1.0/24 or 202.24.0.0/14). * * @param ipAddress the address or range of addresses from which the request must * come. */ public IpAddressMatcher(String ipAddress) { if (ipAddress.indexOf('/') > 0) { String[] addressAndMask = ipAddress.split("/"); ipAddress = addressAndMask[0]; nMaskBits = Integer.parseInt(addressAndMask[1]); } else { nMaskBits = -1; } requiredAddress = parseAddress(ipAddress); assert (requiredAddress.getAddress().length * 8 >= nMaskBits) : String.format("IP address %s is too short for bitmask of length %d", ipAddress, nMaskBits); } public boolean matches(String address) { InetAddress remoteAddress = parseAddress(address); if (!requiredAddress.getClass().equals(remoteAddress.getClass())) { return false; } if (nMaskBits < 0) { return remoteAddress.equals(requiredAddress); } byte[] remAddr = remoteAddress.getAddress(); byte[] reqAddr = requiredAddress.getAddress(); int nMaskFullBytes = nMaskBits / 8; byte finalByte = (byte) (0xFF00 >> (nMaskBits & 0x07)); // System.out.println("Mask is " + new sun.misc.HexDumpEncoder().encode(mask)); for (int i = 0; i < nMaskFullBytes; i++) { if (remAddr[i] != reqAddr[i]) { return false; } } if (finalByte != 0) { return (remAddr[nMaskFullBytes] & finalByte) == (reqAddr[nMaskFullBytes] & finalByte); } return true; } private InetAddress parseAddress(String address) { try { return InetAddress.getByName(address); } catch (UnknownHostException e) { throw new IllegalArgumentException("Failed to parse address" + address, e); } } }
NOTICE: Notice that for using this option, it's your responsibility to carefully examine the license to make sure by using this code, you are not in violation of any terms mandated by the aforementioned license. (Of course publishing this code to Stackoverflow.com by me is not a violation.)
Apache Commons Net has org.apache.commons.net.util.SubnetUtils
that appears to satisfy your needs. It looks like you do something like this:
SubnetInfo subnet = (new SubnetUtils("10.10.10.0", "255.255.255.128")).getInfo(); boolean test = subnet.isInRange("10.10.10.10");
Note, as carson points out, that Apache Commons Net has a bug that prevents it from giving the correct answer in some cases. Carson suggests using the SVN version to avoid this bug.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With