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 }