Feature Request: Used/Free Dynamic Leases

In the DHCP Configuration page, it would be nice if the page showed us how many Leases are in use out of how many available. I have one firewall that has a lot of leases in use and it would be nice to see at a glance if I am getting close to using up all available leases. Right now, I copy all the leases to a spreadsheet and use the rows filled to determine how many leases are in use.

For the DHCP server all IPs handed out sometimes are ‘in use’.
Even if the lease time has expired, the relation IP <—> MAC is retained. If a device, identified by the MAC, without an IP sends a request it gets the IP defined by this ‘old’ lease relation.
It is possible to count the defined dynamic leases and give an information
<#of possible IPs>,<#of expired leases>,<#of active leases>
Is this the feature you think of?

Yes. Something like:

Total Addresses: 150
In Use: 104 (69%)
Available: 46 (31%)

Looking at the sources ( dhcp.cgi ) shows it isn’t such easy as it sounds.
dhcp.cgi is one of the ‘odd’ programs of IPFire. The printing of the dynamic leases is a separate function in /var/ipfire/header.pl which just reads the info from dhcpd’s leases file, without knowing the configuration.
Your feature would request a reorganisation of these sources.

Okay, thank you for checking. I do believe it could be a useful feature in environments where DHCP usage is high. Perhaps the feature could be put on a list for future consideration.

Searching on the internet, I found a cgi/perl program called dhcpstatus, however, it was written in 2000 and would most like have to be re-written, because dhcpd.conf and dhcpd.leases files probably have a different format.

But it shouldn’t be that hard to take the difference between the end and start address of the dhcp to get the total, then count how many current leases and generate all the numbers from there (% available, how many IPs available, etc)

I remember an add-on called “Who’s online?
Can this be of any help?

Not really. It just shows what DHCP server shows, but adds a button that says whether that system is offline or online. What I’m looking for is similar to what I’ve seen in other consumer routers and in Windows Server’s DHCP page:
Total DHCP Leases
Used DHCP Leases
Unused DHCP Leases

When dealing with 200+ leases, this is very valuable to see at a glance whether you are approaching capacity. Right now IPFire just shows a long list of leases in use. It may look like all or most leases are in use, but until you actually count them, you won’t know. This is where I have to copy the leases, paste them into a spreadsheet, and use the rows field to see how many are in use.

I’ll touch back on this, as I have to go on an service call and be out for much of the day, but it shouldn’t be that hard considering 80% of the info is already called to the page.

One thing I don’t understand is the leases with the strike through mark and we should be able to control this behaviour as maybe 48 hrs after a lease expired might be handy for some while others wouldn’t care about past expired leases.

The basic behaviour of the DHCP server is ( ignoring the fixed leases, which have a set of IPS outside the dynamic set { start_addr … end_addr } ):

  • start: free_set={start_addr, …, end_addr}, old_leases={}, active_leases{}
  • loop:
  • request for IP by device(MAC)
  • search for MAC in active_leases, if found select IP from tuple, update element to (MAC, IP, new lease_time), goto send
  • search in old_lease for MAC, if found select IP from (MAC,IP,last_request_time) tuple and delete the tuple in old_leases, goto send
  • chose an element of free_leases; if free_leases=={}, chose oldest element of old_leases; delete element IP from free_leases or old_leases.
  • send: answer with (IP, lease_time), add (IP, MAC, lease_time) to active_leases
  • goto loop
  • timer tasks:
    • if lease_time of (IP,MAC) is expired move (MAC, IP, lease_time) from active_leases to old_leases

Okay, a bit complicated.
But this means there are three sets

  • dynamic_pool={ IP | start_addr<=IP<=end_addr}
  • active_pool={ IP | current_time < expiration_time(IP) }
  • expired_pool={ IP | current_time >= expiration_time(IP) }

The numbers are

  • Total leases = || dynamic_pool ||
  • Used leases = || active_pool ||
  • Unused leases = || dynamic_pool - active_pool - expired_pool ||
  • Available leases = || dynamic_pool - active_pool ||

So far the theory, which can be easily implemented. But as stated before the source isn’t prepared for such analysis. It demands some reorganisation of the subroutines. Eeach change bears the danger of unwanted side-effects.

IMHO, the effort ( including checks of dependencies ) is much higher than the gain.
If there are no IPs available anymore there are error messages.
If your dynamic pool has a size of 200 IPs there is not much room in a usual /24 net. A /24 net includes 254 addresses, 256 numbers - network IP - broadcast IP.
A change in the network definition demands much more than just some DHCP settings.

This page just needs just need refinements, even though half of the issue of the Current Lease section is the expired leases not getting deleted in the .leases file so you end up with this big grey blob area with a bunch of ip addresses with a strike through. Which I find that to be a broken part of the page.

current dynamic leases should only list the current dynamic leases and why is the .leases file not auto deleting when it expires but instead is deactivated and no controls to delete the entry in the file. So, how long does it take to reach 4GB since it doesn’t purge old records?

Ok, Its not hard to write this page guys. Even if it wasn’t using any perl::ip tools.

Thank you, for doing it. :wink:

Well I guess, since that is part of open source community.

In Perl, just like C++. to calculate the difference between two 32 bit words in 8 bit BCD value segments (the structure of ip adresses), one just simply converts the ip number into its integer value, then subtract the two, leaving how many addresses or numbers between the two.

The green and blue DHCP parameters are rendered by the same subroutine. So you would just use what they already loaded into variables for filling the blanks in the start and end address part of the form.

There are several ways to convert the ip number to an integer, I use the bit shift operation as that is much faster than most other methods.

my ($start_bytes, $end_bytes)= map { [split /\./, $_] }($dhcpsettings{"START_ADDR_${itf}"},$dhcpsettings{"END_ADDR_${itf}"});
my $dhcp_pool_int= ( ($end_bytes->[0] << 24) + ($end_bytes->[1] << 16) + ($end_bytes->[2] << 8) + $end_bytes->[3] ) -  ( ($start_bytes->[0] << 24) + ($start_bytes->[1] << 16) + ($start_bytes->[2] << 8) + $start_bytes->[3] );
print $dhcp_pool_int;


Other stuff is just as easy. But I have no time this morning to elaborate.