All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.jradius.handler.dhcp.AddressPoolImpl Maven / Gradle / Ivy

The newest version!
/**
 * JRadius - A RADIUS Server Java Adapter
 * Copyright (c) 2006-2008 David Bird 
 *
 * 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.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.io.Serializable;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;

import net.jradius.util.RadiusRandom;
import net.jradius.util.RadiusUtils;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheException;
import net.sf.ehcache.Ehcache;
import net.sf.ehcache.Element;
import net.sf.ehcache.event.CacheEventListener;

public class AddressPoolImpl implements AddressPool, CacheEventListener
{
    protected String leaseFile = "/tmp/leases.dhcp";
    protected InetAddress network;
    protected InetAddress netmask;
    protected InetAddress router;
    protected InetAddress[] dns;
    protected byte next = RadiusRandom.getBytes(1)[0];
    protected int fudge = 10;
    protected int leaseTime;
    protected AddressPoolListener listener;
    protected Cache leases;
    
    class MACKey implements Serializable
    {
        private static final long serialVersionUID = 0L;
        byte[] mac;
     
        public MACKey(byte[] b) { mac = b; }
        public byte[] getMAC() { return mac; }
        
        public boolean equals(Object o)
        {
            if (!(o instanceof MACKey))
                return false;
            
            if (this == o)
                return true;
            
            byte[] omac = ((MACKey) o).getMAC();
            
            if (mac.length != omac.length)
                return false;

            for (int i = 0; i < mac.length; i++)
            {
                if (mac[i] != omac[i])
                    return false;
            }
            
            return true;
        }
        
        public int hashCode()
        {
            return Arrays.hashCode(mac);
        }
    }

    public AddressPoolImpl()
    {
    }
    
    public AddressPoolImpl(InetAddress network, InetAddress netmask, InetAddress router, int leaseTime)
    {
        this.network = network;
        this.netmask = netmask;
        this.router = router;
        this.leaseTime = leaseTime;
    }
    
    public boolean contains(InetAddress ip) 
    {
        if (getNetwork() == null || getNetmask() == null)  
        	throw new RuntimeException("network/netmask requierd");

        byte[] networkBytes = getNetwork().getAddress();
        byte[] netmaskBytes = getNetmask().getAddress();
        byte[] ipBytes = ip.getAddress();
        
        if (networkBytes.length != netmaskBytes.length || netmaskBytes.length != ipBytes.length)
        {
            return false;
        }
        
        for (int i=0; i < netmaskBytes.length; i++) 
        {
            int mask = netmaskBytes[i] & 0xff;
            if ((networkBytes[i] & mask) != (ipBytes[i] & mask)) 
            {
                return false;
            }
        }
        
        return true;
    }

    public InetAddress nextIP() throws UnknownHostException
    {
        if (getNetwork() == null || getNetmask() == null)  
        	throw new RuntimeException("network/netmask requierd");

        InetAddress nextAddress = null;

        do
        {
            byte b[] = getNetwork().getAddress();
            b[b.length-1] = next++;
            nextAddress = InetAddress.getByAddress(b);
        }
        while(leases.get(nextAddress) != null ||
             (router != null && nextAddress.equals(router)));
        
        return nextAddress;
    }
    
    private static InetAddress anyIPAddress;

    static {
        try { anyIPAddress = InetAddress.getByAddress(new byte[] { 0, 0, 0, 0 }); }
        catch (Exception e) { }
    }
    
    public InetAddress getIP(byte[] hwa, InetAddress requested, boolean forceNew) throws UnknownHostException
    {
        if (leases == null) throw new RuntimeException("leases not set");

        MACKey hwKey = new MACKey(hwa);
        Element eHW = leases.get(hwKey);
        Element eIP = leases.get(requested);
        
        if (anyIPAddress.equals(requested))
            requested = null;
        
        if (eHW == null)
        {
            /**
             *   Client does not yet have a leased IP address
             */
            
            if (requested != null) 
            {
                /**
                 *   Client is requesting an IP
                 */

                if (!contains(requested))
                {
                    /**
                     *  IP address not in our range!
                     */

                    return null;
                }

                if (eIP != null && hwKey.equals(eIP.getValue()))
                {
                    /**
                     *  We owned the lease, so let's go ahead and update the IP
                     */
                    
                    leases.remove(eIP.getKey());
                }
                else
                {
                    /**
                     *  IP address is already leased
                     */

                    return null;
                }

                eHW = new Element(hwKey, requested);
            }
            else
            {
                eHW = new Element(hwKey, nextIP());
            }
        }
        else
        {
            /**
             *  Client already has a leased IP
             */

            if (forceNew)
            {
                if (eIP != null && hwKey.equals(eIP.getValue()))
                {
                    /**
                     *  We owned the lease, so let's go ahead and update the IP
                     */

                    leases.remove(eIP.getKey());
                }

                eHW = new Element(hwKey, nextIP());
            }
            else if (requested != null) 
            {
                if (!requested.equals(eHW.getValue()))
                {
                    /**
                     *  Requested IP address does not match leased IP
                     */

                    if (eIP != null && hwKey.equals(eIP.getValue()))
                    {
                        /**
                         *  We owned the lease, so let's go ahead and update the IP
                         */

                        leases.remove(eIP.getKey());
                    }
                    else
                    {
                        return null;
                    }
                }
            }
        }

        eIP = new Element(eHW.getValue(), eHW.getKey());

        leases.put(eHW);
        leases.put(eIP);
        
        writeLeaseFile();
        
        return (InetAddress) eHW.getValue();
    }

    public void writeLeaseFile()
    {
        if (getLeaseFile() == null) return;
        try
        {
            File file = new File(getLeaseFile());
            PrintWriter writer = new PrintWriter(new FileWriter(file));
            
            for (Object o : leases.getKeys())
            {
                if (o instanceof MACKey)
                {
                    InetAddress inet = (InetAddress)leases.get(o).getValue();
                    MACKey macKey = (MACKey)o;

                    writer.print(inet.getHostAddress());
                    writer.print(" ");
                    writer.println(RadiusUtils.byteArrayToHexString(macKey.getMAC()));
                }
            }
            
            writer.close();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
    
    public void notifyElementEvicted(Ehcache cache, Element e)
    {
    }

    public void notifyElementExpired(Ehcache cache, Element e)
    {
    }

    public void notifyElementPut(Ehcache cache, Element e) throws CacheException
    {
    }

    public void notifyElementRemoved(Ehcache cache, Element e) throws CacheException
    {
    }

    public void notifyElementUpdated(Ehcache cache, Element e) throws CacheException
    {
    }

    public void notifyRemoveAll(Ehcache cache)
    {
    }

    public Object clone() throws CloneNotSupportedException
    {
        return super.clone();
    }

    public void dispose()
    {
    }

    public void setFudge(int fudge)
    {
        this.fudge = fudge;
    }

    public void setLeaseFile(String leaseFile)
    {
        this.leaseFile = leaseFile;
    }

    public void setLeases(Cache leases)
    {
        this.leases = leases;
    }

    public void setLeaseTime(int leaseTime)
    {
        this.leaseTime = leaseTime;
    }

    public void setNetmask(InetAddress netmask)
    {
        this.netmask = netmask;
    }

    public void setNetwork(InetAddress network)
    {
        this.network = network;
    }

    public void setRouter(InetAddress router)
    {
        this.router = router;
    }

    public String getLeaseFile()
    {
        return leaseFile;
    }

    public Ehcache getLeases()
    {
        return leases;
    }

    public int getLeaseTime()
    {
        return leaseTime;
    }

    public InetAddress getNetmask()
    {
        return netmask;
    }

    public InetAddress getNetwork()
    {
        return network;
    }

    public InetAddress getRouter()
    {
        return router;
    }

    public InetAddress[] getDns()
    {
        return dns;
    }

    public void setDns(InetAddress[] dns)
    {
        this.dns = dns;
    }

    public AddressPoolListener getListener()
    {
        return listener;
    }

    public void setListener(AddressPoolListener listener)
    {
        this.listener = listener;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy