Tests whether the ip Address is within the address space defined by the ip Address With Net mask. - Java Network

Java examples for Network:IP Address

Description

Tests whether the ip Address is within the address space defined by the ip Address With Net mask.

Demo Code

/*/* www.j a  v  a 2  s . c om*/
 * Copyright (c) 2011-2012 ICM Uniwersytet Warszawski All rights reserved.
 * See LICENCE file for licensing information.
 *
 * Derived from the code copyrighted and licensed as follows:
 * 
 * Copyright (c) Members of the EGEE Collaboration. 2004.
 * See http://www.eu-egee.org/partners/ for details on the copyright
 * holders.
 * 
 * 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
 * 
 *    http://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.
 */
//package com.java2s;

public class Main {
    public static void main(String[] argv) throws Exception {
        byte[] ipBytes = new byte[] { 34, 35, 36, 37, 37, 37, 67, 68, 69 };
        byte[] ipAddressWithNetmask = new byte[] { 34, 35, 36, 37, 37, 37,
                67, 68, 69 };
        System.out.println(isWithinAddressSpace(ipBytes,
                ipAddressWithNetmask));
    }

    private static final int IPv4_FULL_MASK = 32;
    private static final int IPv6_FULL_MASK = 128;
    private static final int IPv6_HALF_MASK = 64;

    /**
     * Tests whether the ipAddress is within the address space defined by
     * the ipAddressWithNetmask.
     * 
     * @param ipBytes
     *                The IP address bytes to compare against the address
     *                space.
     * @param ipAddressWithNetmask
     *                The 8 (IPv4) or 32 (IPv6) byte array containing in the
     *                first half the base IP address bytes and in the second
     *                half the netmask bytes.
     * @return true if ip matches subnet.
     */
    public static boolean isWithinAddressSpace(byte[] ipBytes,
            byte[] ipAddressWithNetmask) {

        if (!(ipAddressWithNetmask.length == 8 && ipBytes.length == 4)
                && !(ipAddressWithNetmask.length == 32 && ipBytes.length == 16)) {
            throw new IllegalArgumentException(
                    "IP address and IP address-netmask length mismatch, should be either (4 and 8) or (16 and 32), actual lengths were: "
                            + ipBytes.length
                            + " and "
                            + ipAddressWithNetmask.length + ".");
        }

        if (ipBytes.length == 4) {

            int mask = getCidrNetmask(4, ipAddressWithNetmask, 4);
            /*
             * IPv4 can be represented as a 32 bit ints.
             */
            int ipAsInt = getInt(ipBytes, 0);
            int netAsInt = getInt(ipAddressWithNetmask, 0);

            return (ipAsInt ^ netAsInt) >> (IPv4_FULL_MASK - mask) == 0;
        }

        /**
         * IPv6 can be represented as two 64 bit longs.
         * 
         * We evaluate second long only if bitmask bigger than 64. The
         * second longs are created only if needed as it turned to be
         * the slowest part.
         */
        long ipAsLong0 = getLong(ipBytes, 0);
        long netAsLong0 = getLong(ipAddressWithNetmask, 0);
        int mask = getCidrNetmask(16, ipAddressWithNetmask, 16);

        if (mask > 64) {
            long ipAsLong1 = getLong(ipBytes, 8);
            long netAsLong1 = getLong(ipAddressWithNetmask, 8);

            return (ipAsLong0 == netAsLong0)
                    & (ipAsLong1 ^ netAsLong1) >> (IPv6_FULL_MASK - mask) == 0;
        }
        return (ipAsLong0 ^ netAsLong0) >> (IPv6_HALF_MASK - mask) == 0;
    }

    private static int getCidrNetmask(int size, byte[] netmask, int offset) {
        int ret = 0;
        for (int i = 0; i < size; i++) {
            if (netmask[i + offset] != -1) //-1 == 255 unsigned
            {
                int maskByteReversed = (~(netmask[i + offset])) & 0xff;
                int bitPfx = Integer.numberOfLeadingZeros(maskByteReversed) - 24;
                return ret + bitPfx;
            } else
                ret += 8;
        }
        return ret;
    }

    /**
     * Returns the big-endian {@code int} value whose byte representation is
     * the 4 bytes of <code>bytes</code> staring <code>offset</code>.
     * 
     * @param bytes
     * @param offset
     * @return int value
     */
    private static int getInt(byte[] bytes, int offset) {
        return (bytes[offset + 0] & 0xFF) << 24
                | (bytes[offset + 1] & 0xFF) << 16
                | (bytes[offset + 2] & 0xFF) << 8
                | (bytes[offset + 3] & 0xFF);
    }

    /**
     * Returns the big-endian {@code long} value whose byte representation
     * is the 8 bytes of <code>bytes</code> staring <code>offset</code>.
     * 
     * @param bytes
     * @param offset
     * @return long value
     */
    private static long getLong(byte[] bytes, int offset) {
        return (bytes[offset] & 0xFFL) << 56
                | (bytes[offset + 1] & 0xFFL) << 48
                | (bytes[offset + 2] & 0xFFL) << 40
                | (bytes[offset + 3] & 0xFFL) << 32
                | (bytes[offset + 4] & 0xFFL) << 24
                | (bytes[offset + 5] & 0xFFL) << 16
                | (bytes[offset + 6] & 0xFFL) << 8
                | (bytes[offset + 7] & 0xFFL);
    }
}

Related Tutorials