Is there a parser in Perl out there for dhcpd.leases?

Steve van der Burg steve.vanderburg at LHSC.ON.CA
Wed Nov 3 12:49:05 UTC 2010


> I scan dhcpd.leases at regular intervals using a Perl script
> to extract statistics for display using MRTG.  So far, instead
> of parsing the file properly, I take advantage of its apparent
> line-oriented layout.
> 
> I currently need to enhance the script, and am minded to 'fix'
> the parsing, probably using the Parse::RecDescent module from
> CPAN.
> 
> If someone else has already done (some of, or something like)
> this, I'ld be happy to avoid repeating the effort.

I have been using the code that follows for a couple of years now.  I thought about going down the Parse::RecDescent road as well, but managed to avoid it in the end.

...Steve

- - - cut here - - -

#!/usr/bin/perl
#
# Parse the ISC dhcpd leases file, put it into a perl data structure and write it to disk.
#
# Sep 25/08 - Steve van der Burg - Created
#

use Date::Parse;
use Data::Dumper;
use strict;

my $pl = make_lease_list((-e "/etc/dhcpd.i.am.secondary" ? "dhcp2" : "dhcp1"),"/etc/dhcpd.leases");

my $flpf = "/opt/local/check/parsed-leases.txt";

if ( $pl && open(FLPF,">$flpf.working") ) {
   $Data::Dumper::Indent = 1;
   print FLPF Dumper($pl);
   close FLPF;
   rename "$flpf.working",$flpf;
}

#--------------------------------------------------

sub make_lease_list {
   my ($sname,$lfile) = @_;

   local *LF;
   local $/ = "}\n";

   my %ll;

   return unless open(LF,$lfile);
   print STDERR "$0: ",(scalar localtime)," in make_lease_list, parsing $lfile\n";

   while (<LF>) {
      next unless /^lease\s+(\S+)\s+/m;
      my $IP = $1;
      next if /binding state backup/;
      delete $ll{$IP} if exists $ll{$IP} && $ll{$IP}->{server} eq $sname;
      $ll{$IP}->{type}   = "dynamic";
      $ll{$IP}->{state}  = $1  if /binding state\s+([^\;]+)/;
      $ll{$IP}->{MAC}    = $1  if /hardware ethernet\s+([^\;]+)/;
      $ll{$IP}->{uid}    = $1  if /uid\s+([^\;]+)/;
      $ll{$IP}->{chname} = $1  if /client-hostname\s+([^\;]+)/;
      foreach my $time ( qw / starts ends / ) {
         if ( /$time\s+([^\;]+)/ ) {
            my $utm = substr($1,-19);
            $ll{$IP}->{$time} = str2time($utm,"UTC");
         }
      }
      $ll{$IP}->{server} = $sname;
   }
   close LF;

   # Remove all but active leases from the list:
   #
   foreach my $lk ( keys %ll ) {
      delete $ll{$lk}, next unless $ll{$lk}->{state} eq 'active';
   }

   print STDERR "$0: ",(scalar localtime)," in make_lease_list, finished parsing lease files\n";

   return \%ll;
}

- - - cut here - - -


 --------------------------------------------------------------------------------
This information is directed in confidence solely to the person named above and may contain confidential and/or privileged material. This information may not otherwise be distributed, copied or disclosed. If you have received this e-mail in error, please notify the sender immediately via a return e-mail and destroy original message. Thank you for your cooperation.



More information about the dhcp-users mailing list