View Javadoc

    1   /*
    2    * Copyright 2012 The Netty Project
    3    *
    4    * The Netty Project licenses this file to you under the Apache License,
    5    * version 2.0 (the "License"); you may not use this file except in compliance
    6    * with the License. You may obtain a copy of the License at:
    7    *
    8    *   http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
    12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
    13   * License for the specific language governing permissions and limitations
    14   * under the License.
    15   */
    16  package org.jboss.netty.handler.ipfilter;
    17
    18  import java.net.Inet4Address;
    19  import java.net.Inet6Address;
    20  import java.net.InetAddress;
    21  import java.net.UnknownHostException;
    22
    23  /**
    24   */
    25  public class CIDR4 extends CIDR {
    26      /** The integer for the base address */
    27      private int addressInt;
    28
    29      /** The integer for the end address */
    30      private final int addressEndInt;
    31
    32      /**
    33       * @param newaddr
    34       * @param mask
    35       */
    36      protected CIDR4(Inet4Address newaddr, int mask) {
    37          cidrMask = mask;
    38          addressInt = ipv4AddressToInt(newaddr);
    39          int newmask = ipv4PrefixLengthToMask(mask);
    40          addressInt &= newmask;
    41          try {
    42              baseAddress = intToIPv4Address(addressInt);
    43          } catch (UnknownHostException e) {
    44              // this should never happen
    45          }
    46          addressEndInt = addressInt + ipv4PrefixLengthToLength(cidrMask) - 1;
    47      }
    48
    49      @Override
    50      public InetAddress getEndAddress() {
    51          try {
    52              return intToIPv4Address(addressEndInt);
    53          } catch (UnknownHostException e) {
    54              // this should never happen
    55              return null;
    56          }
    57      }
    58
    59      public int compareTo(CIDR arg) {
    60          if (arg instanceof CIDR6) {
    61              byte[] address = getIpV4FromIpV6((Inet6Address) arg.baseAddress);
    62              int net = ipv4AddressToInt(address);
    63              if (net == addressInt && arg.cidrMask == cidrMask) {
    64                  return 0;
    65              }
    66              if (net < addressInt) {
    67                  return 1;
    68              } else if (net > addressInt) {
    69                  return -1;
    70              } else if (arg.cidrMask < cidrMask) {
    71                  return -1;
    72              }
    73              return 1;
    74          }
    75          CIDR4 o = (CIDR4) arg;
    76          if (o.addressInt == addressInt && o.cidrMask == cidrMask) {
    77              return 0;
    78          }
    79          if (o.addressInt < addressInt) {
    80              return 1;
    81          } else if (o.addressInt > addressInt) {
    82              return -1;
    83          } else if (o.cidrMask < cidrMask) {
    84              // greater Mask means less IpAddresses so -1
    85              return -1;
    86          }
    87          return 1;
    88      }
    89
    90      @Override
    91      public boolean contains(InetAddress inetAddress) {
    92          int search = ipv4AddressToInt(inetAddress);
    93          return search >= addressInt && search <= addressEndInt;
    94      }
    95
    96      /**
    97       * Given an IPv4 baseAddress length, return the block length.  I.e., a
    98       * baseAddress length of 24 will return 256.
    99       */
    100     private static int ipv4PrefixLengthToLength(int prefix_length) {
    101         return 1 << 32 - prefix_length;
    102     }
    103
    104     /**
    105      * Given a baseAddress length, return a netmask.  I.e, a baseAddress length
    106      * of 24 will return 0xFFFFFF00.
    107      */
    108     private static int ipv4PrefixLengthToMask(int prefix_length) {
    109         return ~((1 << 32 - prefix_length) - 1);
    110     }
    111
    112     /**
    113      * Convert an integer into an (IPv4) InetAddress.
    114      *
    115      * @return the created InetAddress
    116      */
    117     private static InetAddress intToIPv4Address(int addr) throws UnknownHostException {
    118         byte[] a = new byte[4];
    119         a[0] = (byte) (addr >> 24 & 0xFF);
    120         a[1] = (byte) (addr >> 16 & 0xFF);
    121         a[2] = (byte) (addr >> 8 & 0xFF);
    122         a[3] = (byte) (addr & 0xFF);
    123         return InetAddress.getByAddress(a);
    124     }
    125
    126     /**
    127      * Given an IPv4 address, convert it into an integer.
    128      *
    129      * @return the integer representation of the InetAddress
    130      * @throws IllegalArgumentException if the address is really an
    131      *                                  IPv6 address.
    132      */
    133     private static int ipv4AddressToInt(InetAddress addr) {
    134         byte[] address = null;
    135         if (addr instanceof Inet6Address) {
    136             address = getIpV4FromIpV6((Inet6Address) addr);
    137         } else {
    138             address = addr.getAddress();
    139         }
    140         return ipv4AddressToInt(address);
    141     }
    142
    143     /**
    144      * Given an IPv4 address as array of bytes, convert it into an integer.
    145      *
    146      * @return the integer representation of the InetAddress
    147      * @throws IllegalArgumentException if the address is really an
    148      *                                  IPv6 address.
    149      */
    150     private static int ipv4AddressToInt(byte[] address) {
    151         int net = 0;
    152         for (byte addres : address) {
    153             net <<= 8;
    154             net |= addres & 0xFF;
    155         }
    156         return net;
    157     }
    158 }