/*
* Copyright 2011 Future Systems
*
* 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 org.krakenapps.dhcp.server;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.List;
import org.krakenapps.dhcp.DhcpMessage;
import org.krakenapps.dhcp.DhcpServer;
import org.krakenapps.dhcp.MacAddress;
import org.krakenapps.dhcp.model.DhcpIpGroup;
import org.krakenapps.dhcp.model.DhcpIpLease;
import org.krakenapps.dhcp.model.DhcpIpReservation;
import org.krakenapps.dhcp.model.DhcpOptionConfig;
import org.krakenapps.dhcp.options.ByteConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class DhcpDiscoverHandler {
private final Logger logger = LoggerFactory.getLogger(DhcpDiscoverHandler.class.getName());
private DhcpServer server;
private DhcpServerContext c;
public DhcpDiscoverHandler(DhcpServer server, DhcpServerContext c) {
this.server = server;
this.c = c;
}
public void handle(DhcpMessage msg) throws IOException {
// check if blocked
if (c.blockFilters.containsKey(msg.getClientMac())) {
logger.warn("kraken dhcp: client [{}] discover ignored by block list", msg.getClientMac());
return;
}
// determine ip address
String hostName = DhcpOptions.getHostName(msg);
InetAddress yourAddress = determineIp(msg.getClientMac(), hostName);
if (yourAddress == null) {
logger.warn("kraken dhcp: address cannot be allocated");
return;
}
// send offer
DhcpIpGroup group = server.getIpGroup(yourAddress);
List<DhcpOptionConfig> configs = server.getGroupOptions(group.getName());
DhcpMessage m = DhcpMessageBuilder.newOffer(msg, configs, yourAddress);
c.send(m);
}
private InetAddress determineIp(MacAddress mac, String hostName) {
DhcpIpReservation r = c.reserveMap.get(mac);
if (r != null)
return r.getIp();
List<DhcpIpGroup> groups = DhcpDatabase.getIpGroups(c.conn);
for (DhcpIpGroup group : groups) {
long from = ByteConverter.toInteger(group.getFrom().getAddress()) & 0xffffffffl;
long to = ByteConverter.toInteger(group.getTo().getAddress()) & 0xffffffffl;
for (long target = from + 1; from <= to; target++) {
try {
InetAddress t = InetAddress.getByAddress(ByteConverter.convert((int) target));
if (c.offerMap.containsKey(t))
continue;
List<DhcpOptionConfig> options = DhcpDatabase.getGroupConfigs(group.getName());
int leaseDuration = DhcpDatabase.getLeaseDuration(options);
DhcpIpLease lease = new DhcpIpLease(group.getName(), t, mac, hostName, leaseDuration);
DhcpIpLease old = c.leaseMap.get(t);
if (old == null) {
c.offerMap.put(t, lease);
return t;
} else {
// exists but expired
if (old.getExpire().before(new Date())) {
c.offerMap.put(t, lease);
return t;
}
}
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
return null;
}
}