Test with Java if two IPs are in the same network
Asked Answered
C

3

9

How can I test if two IPs are in the same network according to the subnet mask?

For example I have the IPs 1.2.3.4 and 1.2.4.3: Both are in the same network if the mask is 255.0.0.0 or 255.255.0.0 or even 255.255.248.0 but not if the mask is 255.255.255.0..

Chacon answered 19/12, 2011 at 0:0 Comment(0)
P
15

Try this method:

public static boolean sameNetwork(String ip1, String ip2, String mask) 
throws Exception {

    byte[] a1 = InetAddress.getByName(ip1).getAddress();
    byte[] a2 = InetAddress.getByName(ip2).getAddress();
    byte[] m = InetAddress.getByName(mask).getAddress();

    for (int i = 0; i < a1.length; i++)
        if ((a1[i] & m[i]) != (a2[i] & m[i]))
            return false;

    return true;

}

And use it like this:

sameNetwork("1.2.3.4", "1.2.4.3", "255.255.255.0")
> false

EDIT :

If you already have the IPs as InetAddress objects:

public static boolean sameNetwork(InetAddress ip1, InetAddress ip2, String mask) 
throws Exception {

    byte[] a1 = ip1.getAddress();
    byte[] a2 = ip2.getAddress();
    byte[] m = InetAddress.getByName(mask).getAddress();

    for (int i = 0; i < a1.length; i++)
        if ((a1[i] & m[i]) != (a2[i] & m[i]))
            return false;

    return true;

}
Parentage answered 19/12, 2011 at 0:15 Comment(3)
Nice solution - avoids having to parse the string yourself.Saphead
I have the IPs itself already as InetAddresses, so at most I have to parse the mask.Chacon
@Chacon I edited my answer to match your last comment. Notice that if the mask is the same for all comparisons, it'd be better to compute its byte[] address only once and reuse itCopulation
S
5

Simple enough: mask & ip1 == mask & ip2 - you have to interpret the IPs all as a single number for that but that should be obvious.

Saphead answered 19/12, 2011 at 0:4 Comment(5)
@Chacon The mask is your subnet mask. And sure it will work for IPv6 just as fine - just a different notation when compared to IPv4. But in the end you just use the subnet mask to mask the network part of the IP and then compare those with each other.Saphead
But how to get the subnet mask from the program itself?Chacon
@Chacon Sorry I don't understand your question. Do you want the most specific subnet mask so that 2 IPs are in the same net? In any other case without the subnet mask you can't answer the question whether 2 IPs are in the same net after all (that depends on the mask after all).Saphead
And there is no way to determine the subnet mask without asking the user?Chacon
@Chacon I don't think InetAddress stores that information, but even if it did - where would it get the information itself? One way or another you need to get that information from the user (well her configuration - you may read the information from the OS if its a local process) no way around that.Saphead
X
0

this solution will work with IPv4/IPv6 also.

static boolean sameNetwork(final byte[] x, final byte[] y, final int mask) {
    if(x == y) return true;
    if(x == null || y == null) return false;
    if(x.length != y.length) return false;
    final int bits  = mask &   7;
    final int bytes = mask >>> 3;
    for(int i=0;i<bytes;i++)  if(x[i] != y[i]) return false;
    final int shift = 8 - bits;
    if(bits != 0 && x[bytes]>>>shift != y[bytes]>>>shift) return false;
    return true;
}
static boolean sameNetwork(final InetAddress a, final InetAddress b, final int mask) {
    return sameNetwork(a.getAddress(), b.getAddress(), mask);
}
Xanthic answered 7/4, 2015 at 23:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.