net.jradius.handler.dhcp.DHCPPoolHandler.java Source code

Java tutorial

Introduction

Here is the source code for net.jradius.handler.dhcp.DHCPPoolHandler.java

Source

/**
 * JRadius - A RADIUS Server Java Adapter
 * Copyright (c) 2006-2008 David Bird <david@coova.com>
 *
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or (at
 * your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
 * License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 */

package net.jradius.handler.dhcp;

import java.net.InetAddress;

import org.springframework.beans.factory.InitializingBean;

import net.jradius.dictionary.vsa_dhcp.Attr_DHCPClientHardwareAddress;
import net.jradius.dictionary.vsa_dhcp.Attr_DHCPClientIPAddress;
import net.jradius.dictionary.vsa_dhcp.Attr_DHCPDHCPServerIdentifier;
import net.jradius.dictionary.vsa_dhcp.Attr_DHCPDomainNameServer;
import net.jradius.dictionary.vsa_dhcp.Attr_DHCPIPAddressLeaseTime;
import net.jradius.dictionary.vsa_dhcp.Attr_DHCPMessageType;
import net.jradius.dictionary.vsa_dhcp.Attr_DHCPRequestedIPAddress;
import net.jradius.dictionary.vsa_dhcp.Attr_DHCPRouterAddress;
import net.jradius.dictionary.vsa_dhcp.Attr_DHCPSubnetMask;
import net.jradius.dictionary.vsa_dhcp.Attr_DHCPYourIPAddress;
import net.jradius.handler.PacketHandlerChain;
import net.jradius.packet.DHCPAck;
import net.jradius.packet.DHCPDecline;
import net.jradius.packet.DHCPDiscover;
import net.jradius.packet.DHCPInform;
import net.jradius.packet.DHCPNack;
import net.jradius.packet.DHCPOffer;
import net.jradius.packet.DHCPRelease;
import net.jradius.packet.DHCPRequest;
import net.jradius.packet.RadiusPacket;
import net.jradius.packet.attribute.AttributeList;
import net.jradius.server.JRadiusRequest;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;

/**
 * Simple DHCP IP Pool Handler for FreeRADIUS. 
 * 
 * @author David Bird
 */
public class DHCPPoolHandler extends PacketHandlerChain implements InitializingBean {
    private CacheManager cacheManager;
    private Cache cache;

    public DHCPPoolHandler() {
    }

    private AddressPoolImpl _pool;

    private AddressPool getDefaultPool() {
        if (_pool != null)
            return _pool;

        try {
            InetAddress[] dns = new InetAddress[1];
            dns[0] = InetAddress.getByName("10.1.0.1");

            _pool = new AddressPoolImpl();
            _pool.setNetwork(InetAddress.getByName("10.1.0.0"));
            _pool.setNetmask(InetAddress.getByName("255.255.0.0"));
            _pool.setRouter(InetAddress.getByName("10.1.0.1"));
            _pool.setLeaseTime(900);
            _pool.setDns(dns);

            if (cache == null) {
                cache = new Cache("ippool", 10000, true, false, _pool.getLeaseTime() + 60,
                        _pool.getLeaseTime() + 30);
                cacheManager.addCache(cache);
            }

            _pool.setLeases(cache);

            //pool.addOption(Attr_DHCPProxyAutoDiscovery.VSA_TYPE, wpadURL);
            return _pool;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    public boolean handle(JRadiusRequest request) throws Exception {
        RadiusPacket req = request.getRequestPacket();

        if (req.getCode() < 1024)
            return false;

        byte[] hwAddress = (byte[]) req.getAttributeValue(Attr_DHCPClientHardwareAddress.TYPE);
        if (hwAddress == null)
            throw new DHCPException("no hardware address");

        return handle(request, hwAddress, getDefaultPool());
    }

    public boolean handle(JRadiusRequest request, byte[] hwAddress, AddressPool pool) throws Exception {
        RadiusPacket req = request.getRequestPacket();
        RadiusPacket rep = request.getReplyPacket();
        //AttributeList ci = request.getConfigItems();

        InetAddress requested = (InetAddress) req.getAttributeValue(Attr_DHCPRequestedIPAddress.TYPE);
        if (requested == null)
            requested = (InetAddress) req.getAttributeValue(Attr_DHCPClientIPAddress.TYPE);

        boolean forceRenew = req.getCode() == DHCPDecline.CODE;

        InetAddress ipAddress = pool.getIP(hwAddress, requested, forceRenew);

        // Get the reply attributes before overwriting the reply
        // with the correct response, based on code.
        AttributeList attributes = rep.getAttributes();

        switch (req.getCode()) {
        case DHCPDiscover.CODE:
            if (ipAddress == null && requested != null) {
                // Try to get a new IP if we did not like the request IP
                ipAddress = pool.getIP(hwAddress, null, true);
            }

            rep = (ipAddress == null) ? new DHCPNack() : new DHCPOffer();
            break;

        case DHCPRequest.CODE:
            rep = (ipAddress == null) ? new DHCPNack() : new DHCPAck();
            break;

        case DHCPDecline.CODE:
            rep = (ipAddress == null) ? new DHCPNack() : new DHCPOffer();
            break;

        case DHCPInform.CODE:
            rep = new DHCPAck();
            break;

        case DHCPRelease.CODE:
            rep = new DHCPAck();
            break;

        default:
            return true;
        }

        attributes.add(new Attr_DHCPMessageType(rep.getCode() - 1024));

        if (ipAddress != null) {
            switch (req.getCode()) {
            case DHCPDiscover.CODE:
            case DHCPRequest.CODE:
                attributes.add(new Attr_DHCPYourIPAddress(ipAddress));
                attributes.add(new Attr_DHCPIPAddressLeaseTime(pool.getLeaseTime()));
                attributes.add(new Attr_DHCPDHCPServerIdentifier(pool.getRouter()));

                InetAddress[] dns = pool.getDns();
                if (dns != null) {
                    for (int i = 0; i < dns.length; i++) {
                        attributes.add(new Attr_DHCPDomainNameServer(dns[i]), false);
                    }
                }

                attributes.add(new Attr_DHCPSubnetMask(pool.getNetmask()));
                attributes.add(new Attr_DHCPRouterAddress(pool.getRouter()));
                /* drop through */

            case DHCPInform.CODE:
                //attributes.add(new Attr_DHCPProxyAutoDiscovery(wpadURL));
                break;

            default:
                break;
            }

            //attributes.add(new Attr_DHCPWWWServerAddress("coova.org"));
        }

        rep.getAttributes().add(attributes);
        request.setReplyPacket(rep);

        return true; // do not continue in chain!
    }

    public void afterPropertiesSet() throws Exception {
        if (cacheManager == null) {
            throw new RuntimeException("cacheManager required");
        }
    }

    public void setCacheManager(CacheManager cacheManager) {
        this.cacheManager = cacheManager;
    }

    public void setCache(Cache cache) {
        this.cache = cache;
    }
}