#!/usr/bin/perl -w #******************************************************* # Programmer: Sean L. Ryle # Program: dhcpleases.pl (ls dhcp leases) # Date: 03.19.2001 # Purpose: To search for and sort the DHCP lease # file. # Modification Log # Ini Date Notes # --- ---------- -------------------- # SLR 03.19.2001 Creation of this script # SLR 03.21.2001 added Date::Manip usage # SLR 04.20.2001 added Getopt::Std usage # #******************************************************* use Date::Manip; use Getopt::Std; #lease file, will need to be modified when put #in production to reflect the correct path $LEASE_FILE = "dhcp.leases"; #get command line args getopts('adlthsu', \%opts); #if help is requested, print help & go no further if($opts{'h'}) { print_help(); exit 0; } $ip_re = qr(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}); # Matches an IP # $date_re = qr(\d\d\d\d/\d\d/\d\d \d\d:\d\d:\d\d); # Matches a date and time $Hbyte_re= qr([\da-f][\da-f]); # Matches two hex digits $mac_re = qr((?:$Hbyte_re:){5}$Hbyte_re); # Matches a MAC address $regex = qr( ^ lease \s ($ip_re) \s {\n # Match 'lease' & save IP \s* starts \s \d \s ($date_re);\n # Match and save start date \s* ends \s \d \s ($date_re);\n # Match and save end date (?:\s* (abandoned);\n)? # Match abandoned (?:\s* hardware\sethernet \s ($mac_re);\n)? # Match and save 1st MAC (?:\s* uid \s (\d\d:$mac_re);\n)? # Match and save uid (?:\s* client-hostname \s "([^"]+)";\n)? # Match and save name }$)x; #open the file for reading open(LF, $LEASE_FILE) || die "Error: $!\n$LEASE_FILE could not be opened.\n"; local $/ = "}\n"; while($record = ) { #print "$record\n"; #used for debugging unless(($ip, $start, $end, $abd, $mac, $uid, $name) = $record =~ m/$regex/) { #save the bad record in case retrieeval is requested $bad{$.} = $record; next; } if(defined($abd)) { $aban{$ip} = $record; } else { $d=&DateCalc($start,$end); if($d eq "+0:0:0:0:2:0:0") { $laptop{$ip} = $record; } else { $desktop{$ip} = $record; } } } #close the file close(LF); #process command like args foreach my $parm(keys(%opts)) { if($opts{'a'}) { sort_ips(\%aban); }elsif($opts{'d'}) { sort_ips(\%desktop); }elsif($opts{'l'}) { sort_ips(\%laptop); }elsif($opts{'t'}) { print_abd_records(); }elsif($opts{'s'}) { lease_summary(); }elsif($opts{'u'}) { print_bad_records(); }elsif($opts{'h'}) { print_help(); }else{ print_help(); } } exit; sub print_info() { print "IP:\t$ip\n"; print "Start:\t$start\n"; print "End:\t$end\n"; print "MAC1:\t$mac\n"; print "UID:\t$uid\n"; print "Name:\t$name\n"; print "Aban:\t$abd\n"; print "---------------\n"; } sub print_bad_records() { print "Bad Record Detail\n"; print "-----------------\n"; foreach my $element(keys(%bad)) { print "Record #$element:\n$bad{$element}"; } print "\n"; } sub print_abd_records() { print "Abandonded Record Detail\n"; print "------------------------\n"; foreach my $element(keys(%aban)) { print "IP Address: $element\n$aban{$element}"; } print "\n"; } sub lease_summary() { print "DHCP Lease Summary\n"; print "------------------\n"; print "Unparsable:\t".keys(%bad)."\n"; print "Abandonded:\t".keys(%aban)."\n"; print "Desktop:\t".keys(%desktop)."\n"; print "Laptop:\t\t".keys(%laptop)."\n"; print "\n"; } sub sort_ips() { my %counts; my $hash_ref = shift; print "Subnet\t\tCount\n"; foreach my $ip(keys(%$hash_ref)) { my $subnet = pack 'C3', split /\./, $ip; $counts{$subnet}++; } foreach my $subnet(sort keys(%counts)) { print join '.', unpack 'C3', $subnet; print ":\t$counts{$subnet}"; print "\n"; } print "\n"; } sub print_help() { print "lsdl [-a][-d][-l][-t][-h][-s][-u]\n"; print "-a\tDisplay a summary of abandonded leases sorted by subnet.\n"; print "-d\tDisplay a summary of deesktop leases sorted by subnet.\n"; print "-l\tDisplay a summary of laptop leases sorted by subnet.\n"; print "-t\tDisplay a detail of abandonded leases sorted by subnet.\n"; print "-h\tDisplay this help.\n"; print "-s\tDisplay a summary of the entire lease file.\n"; print "-u\tDisplay a detail of unreadable records from the lease file.\n"; } # here is a sample file __END__ lease 10.178.72.57 { starts 1 2001/03/19 18:47:27; ends 0 2001/03/25 18:47:27; hardware ethernet 00:00:d0:c0:75:5e; uid 01:00:00:d0:c0:75:5e; client-hostname "SUUUUD01"; } lease 10.178.72.51 { starts 1 2001/03/19 18:47:25; ends 0 2001/03/25 18:47:25; hardware ethernet 00:00:d0:c0:75:70; uid 01:00:00:d0:c0:75:70; client-hostname "SVVVVD01"; } lease 10.178.72.45 { starts 1 2001/03/19 23:47:24; ends 0 2001/03/20 01:47:24; hardware ethernet 00:00:d0:c0:75:1f; uid 01:00:00:d0:c0:75:1f; client-hostname "SWWWWD01"; } lease 10.178.72.45 { ends 0 2001/03/25 18:47:24; hardware ethernet 00:00:d0:c0:75:1f; uid 01:00:00:d0:c0:75:1f; client-hostname "SXXXXD01"; } lease 10.4.120.102 { starts 2 1999/08/17 22:48:42; ends 2 2038/01/19 03:14:07; abandoned; client-hostname "PreinstalledCom"; } lease 10.4.120.103 { starts 2 1999/08/17 22:48:42; ends 2 2038/01/19 03:14:07; abandoned; client-hostname "PreinstalledCom"; } lease 10.4.120.104 { starts 2 1999/08/17 22:48:42; ends 2 2038/01/19 03:14:07; abandoned; client-hostname "PreinstalledCom"; }