View Javadoc
1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *  
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *  
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License. 
18   *  
19   */
20  package org.apache.directory.server.dhcp.store;
21  
22  
23  import java.net.InetAddress;
24  import java.net.UnknownHostException;
25  import java.util.Arrays;
26  
27  
28  /**
29   * The definition of a Subnet.
30   * 
31   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
32   */
33  public class Subnet extends DhcpConfigElement
34  {
35      /** the subnet's address */
36      private final InetAddress address;
37  
38      /** the subnet's netmask */
39      private final InetAddress netmask;
40  
41      /** the subnet's range: minimum address in range */
42      private InetAddress rangeMin;
43  
44      /** the subnet's range: maximum address in range */
45      private InetAddress rangeMax;
46  
47  
48      // This will suppress PMD.EmptyCatchBlock warnings in this method
49      @SuppressWarnings("PMD.EmptyCatchBlock")
50      public Subnet( InetAddress address, InetAddress netmask, InetAddress rangeMin, InetAddress rangeMax )
51      {
52          // mask address to match subnet
53          byte[] masked = netmask.getAddress();
54          byte[] addrBytes = netmask.getAddress();
55  
56          for ( int i = 0; i < addrBytes.length; i++ )
57          {
58              masked[i] &= addrBytes[i];
59          }
60  
61          if ( !Arrays.equals( masked, addrBytes ) )
62          {
63              try
64              {
65                  address = InetAddress.getByAddress( masked );
66              }
67              catch ( UnknownHostException e )
68              {
69                  // ignore - doesn't happen.
70              }
71          }
72  
73          this.address = address;
74          this.netmask = netmask;
75          this.rangeMin = rangeMin;
76          this.rangeMax = rangeMax;
77      }
78  
79  
80      public InetAddress getAddress()
81      {
82          return address;
83      }
84  
85  
86      public InetAddress getNetmask()
87      {
88          return netmask;
89      }
90  
91  
92      public InetAddress getRangeMax()
93      {
94          return rangeMax;
95      }
96  
97  
98      public void setRangeMax( InetAddress rangeMax )
99      {
100         this.rangeMax = rangeMax;
101     }
102 
103 
104     public InetAddress getRangeMin()
105     {
106         return rangeMin;
107     }
108 
109 
110     public void setRangeMin( InetAddress rangeMin )
111     {
112         this.rangeMin = rangeMin;
113     }
114 
115 
116     /**
117      * Check whether the given client address resides within this subnet and
118      * possibly range.
119      * 
120      * @param clientAddress
121      * @return boolean
122      */
123     public boolean contains( InetAddress clientAddress )
124     {
125         // check address type
126         if ( !clientAddress.getClass().equals( address.getClass() ) )
127         {
128             return false;
129         }
130 
131         byte[] client = clientAddress.getAddress();
132         byte[] masked = netmask.getAddress();
133 
134         for ( int i = 0; i < masked.length; i++ )
135         {
136             masked[i] &= client[i];
137         }
138 
139         return Arrays.equals( masked, address.getAddress() );
140     }
141 
142 
143     /**
144      * Check whether the specified address is within the range for this subnet.
145      * 
146      * @param clientAddress
147      * @return boolean
148      */
149     public boolean isInRange( InetAddress clientAddress )
150     {
151         byte[] client = clientAddress.getAddress();
152         byte[] masked = netmask.getAddress();
153 
154         for ( int i = 0; i < masked.length; i++ )
155         {
156             masked[i] &= client[i];
157         }
158 
159         if ( null != rangeMin && arrayComp( masked, rangeMin.getAddress() ) < 0 )
160         {
161             return false;
162         }
163 
164         return ( null == rangeMin || arrayComp( masked, rangeMax.getAddress() ) <= 0 );
165     }
166 
167 
168     private static int arrayComp( byte[] a1, byte[] a2 )
169     {
170         for ( int i = 0; i < a1.length && i < a2.length; i++ )
171         {
172             if ( a1[i] != a2[i] )
173             {
174                 return ( a1[i] & 0xff ) - ( a2[i] & 0xff );
175             }
176         }
177 
178         return a1.length - a2.length;
179     }
180 }