Match public IP addresses with user-supplied netmasks - java

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.

Related

Converting CIDR notation to IP range in java [duplicate]

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!

Datatype to store range of IP addresses in Java

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.

Decimal formatted IPV6 ip address or extract IPV4 from IPV6

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
}

Java Local IP range detect

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?

Good hash function for ip addresses and remote ports

I'm writing a peer to peer application and I need a hash function for storing IP/port pairs in a java hashset. Rather than re-invent the wheel I wondered if there are already solutions out there but google has not yielded much.
Can anyone recommend a hash function for IPv4 (bonus if it works for IPv6 as well!) and a remote port number?
The port number is likely to be the same unless the client is on the same host in which case it will be sequential.
The String.hashCode() is pretty reasonable. I would simply do this:
int hash = (ip + "/" + port).hashCode();
It is "random" enough for coding purposes, so much so that it is relied upon by much of the JDK API.
Remember this mantra... "less code is good"
ip^port is about as simple as you can get
this is pretty decent as the last few bits in the IP number are essentially random (assignment of ip from the ISP)
you can expand that with ip^port|port>>>16 to avoid the issue with ending on all 0 or 1 being avoided
for IPv6 you'll need to ipv6_1^ipv6_2^ipv6_3^ipv6_4^port (with ipv6_i being the ith 32bit part)
you can also do
int hash=17;
hash=hash*5+ip;
hash=hash*5+port;
return hash
or
int hash=17;
hash=hash*5+ipv6_1;
hash=hash*5+ipv6_2;
hash=hash*5+ipv6_3;
hash=hash*5+ipv6_4;
hash=hash*5+port;
return hash
as your standard hash function which is a bit better than the standard xor because it is not commutative and you can change the order around if you feel better about it

Categories

Resources