001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020package org.apache.directory.server.dhcp.store; 021 022 023import java.net.InetAddress; 024import java.net.UnknownHostException; 025import java.util.Arrays; 026 027 028/** 029 * The definition of a Subnet. 030 * 031 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 032 */ 033public class Subnet extends DhcpConfigElement 034{ 035 /** the subnet's address */ 036 private final InetAddress address; 037 038 /** the subnet's netmask */ 039 private final InetAddress netmask; 040 041 /** the subnet's range: minimum address in range */ 042 private InetAddress rangeMin; 043 044 /** the subnet's range: maximum address in range */ 045 private InetAddress rangeMax; 046 047 048 // This will suppress PMD.EmptyCatchBlock warnings in this method 049 @SuppressWarnings("PMD.EmptyCatchBlock") 050 public Subnet( InetAddress address, InetAddress netmask, InetAddress rangeMin, InetAddress rangeMax ) 051 { 052 // mask address to match subnet 053 byte[] masked = netmask.getAddress(); 054 byte[] addrBytes = netmask.getAddress(); 055 056 for ( int i = 0; i < addrBytes.length; i++ ) 057 { 058 masked[i] &= addrBytes[i]; 059 } 060 061 if ( !Arrays.equals( masked, addrBytes ) ) 062 { 063 try 064 { 065 address = InetAddress.getByAddress( masked ); 066 } 067 catch ( UnknownHostException e ) 068 { 069 // ignore - doesn't happen. 070 } 071 } 072 073 this.address = address; 074 this.netmask = netmask; 075 this.rangeMin = rangeMin; 076 this.rangeMax = rangeMax; 077 } 078 079 080 public InetAddress getAddress() 081 { 082 return address; 083 } 084 085 086 public InetAddress getNetmask() 087 { 088 return netmask; 089 } 090 091 092 public InetAddress getRangeMax() 093 { 094 return rangeMax; 095 } 096 097 098 public void setRangeMax( InetAddress rangeMax ) 099 { 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}