mirror of
https://abf.rosa.ru/djam/dhcp.git
synced 2025-02-23 13:32:48 +00:00
253 lines
8.1 KiB
Perl
253 lines
8.1 KiB
Perl
#!/usr/bin/perl
|
|
|
|
my $path_to_leasefile = "/var/lib/dhcp/dhcpd.leases";
|
|
my $ping_ttl = .3;
|
|
my $date_format = "%m-%d-%Y %I:%M%p";
|
|
|
|
use strict;
|
|
use Net::Ping;
|
|
#To convert the UTC times to seconds since the epoch
|
|
use Time::Local;
|
|
#To format the output time
|
|
use POSIX ("strftime");
|
|
use Term::ANSIColor;
|
|
use Getopt::Long;
|
|
#use Getopt::Long (":config", "bundling");
|
|
use Term::ANSIColor (":constants");
|
|
$Term::ANSIColor::AUTORESET = 1;
|
|
|
|
#Populate all the command line variables
|
|
my ($showmac,$showatm,$showip,$showexpired,$help,$color);
|
|
GetOptions('mac|m' => \$showmac,'atm|a' => \$showatm,'ip|i=s' => \$showip,'expired|x' => \$showexpired,'help|h'=>\$help,'color|c'=>\$color);
|
|
|
|
$ENV{'REQUEST_METHOD'};
|
|
|
|
#Display the usage if they pass in --help or -h
|
|
if ($help) { die(&usage()); }
|
|
|
|
my @list;
|
|
my %hash;
|
|
my ($count,$expired_lease);
|
|
|
|
#Open the lease file to begin parsing it
|
|
open (INFILE,$path_to_leasefile);
|
|
|
|
#print "$< - $>\n";
|
|
|
|
$expired_lease=0;
|
|
while (<INFILE>) {
|
|
if ($_ =~ /lease (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/i) {
|
|
|
|
my $ip = $1;
|
|
my $hostname = undef;
|
|
my $remoteid = undef;
|
|
my $macaddr = undef;
|
|
my $lease_start = undef;
|
|
my $lease_end = undef;
|
|
# Go until you see a } which is the end of record char
|
|
while ($_ !~ /^}$/) {
|
|
$_ = <INFILE>;
|
|
if ($_ =~ /starts/) {
|
|
$lease_start = &leasegm_to_epoch($_);
|
|
}
|
|
elsif ($_ =~ /ends/) {
|
|
$lease_end = &leasegm_to_epoch($_);
|
|
}
|
|
elsif ($_ =~ /client-hostname \"(.*)\"/ ) {
|
|
$hostname = $1;
|
|
}
|
|
elsif ($_ =~ /option agent\.remote-id (.*);/ ) {
|
|
$remoteid = $1;
|
|
}
|
|
elsif ($_ =~ /hardware ethernet (.*);/ ) {
|
|
$macaddr = $1;
|
|
}
|
|
}
|
|
|
|
my $expired = &lease_expired($lease_end);
|
|
|
|
#If we're not searching for ONE IP and the lease isn't expired add it to the hash
|
|
if (!$showip && !$expired) {
|
|
# Put it in the hash no matter what, if showip isn't set because it will overwrite
|
|
$hash{$ip}={"hostname"=>$hostname,"remoteid"=>$remoteid,"mac"=>$macaddr,"lease_end"=>$lease_end};
|
|
}
|
|
elsif ($showip && $ip =~ /$showip/ && !$expired) {
|
|
# Only populate the hash if it matches the passed in request
|
|
$hash{$ip}={"hostname"=>$hostname,"remoteid"=>$remoteid,"mac"=>$macaddr,"lease_end"=>$lease_end};
|
|
}
|
|
elsif ($expired) {
|
|
#if ($showexpired) {
|
|
# my $ctime = strftime("%m-%d-%Y %I:%M%p",localtime($lease_end));
|
|
# print "Expired: $ip\t($ctime)\n";
|
|
#}
|
|
$expired_lease++;
|
|
}
|
|
|
|
$count++;
|
|
}
|
|
}
|
|
|
|
close INFILE;
|
|
|
|
if ($showip) {
|
|
print "Showing IPs that match \"$showip\"\n";
|
|
}
|
|
|
|
@list = sort(keys %hash);
|
|
my $total = scalar(@list) + 1;
|
|
|
|
my $maxlen;
|
|
#get the length of the longest IP
|
|
for my $ip(@list) {
|
|
if ($maxlen < length($ip)) { $maxlen = length($ip); }
|
|
}
|
|
|
|
my $output;
|
|
#$output .= "Content-Type: text/html\n\n";
|
|
#$output .= "Checking $total ($count dupes) leases for validity\n";
|
|
print "Checking $total leases ($expired_lease expired) for validity\n";
|
|
|
|
my $ping = Net::Ping->new("icmp");
|
|
my $count=0;
|
|
|
|
foreach my $ip (@list) {
|
|
my $result = $ping->ping($ip,$ping_ttl);
|
|
if ($result) {
|
|
$result = "Alive";
|
|
if ($color) { $result = GREEN $result; }
|
|
$count++;
|
|
}
|
|
else {
|
|
$result = "Dead";
|
|
if ($color) { $result = RED $result; }
|
|
}
|
|
|
|
# Get the hostname part
|
|
my $hostname;
|
|
$hostname = $hash{$ip}->{'hostname'};
|
|
if (!$hostname) {
|
|
$hostname = "*blank*";
|
|
if ($color) { $hostname = BOLD BLUE $hostname; }
|
|
}
|
|
|
|
my $lease_end;
|
|
#If we're showing when the leases expire
|
|
if ($showexpired) {
|
|
#If the year is great than 2020 (my way of representing "never") than it's a
|
|
#lease that doesn't expire
|
|
if (strftime("%Y",localtime($hash{$ip}->{lease_end})) > 2020) {
|
|
$lease_end = "Never";
|
|
if ($color) { $lease_end = BOLD WHITE $lease_end; }
|
|
$lease_end = &padtext($lease_end,length($lease_end)+2);
|
|
}
|
|
#Show the date in the date format
|
|
else {
|
|
$lease_end = strftime($date_format,localtime($hash{$ip}->{lease_end}));
|
|
$lease_end = padtext($lease_end,length($lease_end)+2);
|
|
}
|
|
}
|
|
else { $lease_end = ""; }
|
|
|
|
# Get the agentid
|
|
my $remoteid;
|
|
$remoteid = $hash{$ip}->{'remoteid'} or $remoteid = "none";
|
|
|
|
my $mac;
|
|
if ($showmac) { $mac = $hash{$ip}->{'mac'} or $mac = ""; }
|
|
my $atm;
|
|
if ($showatm) { $atm = $hash{$ip}->{'remoteid'} or $atm = ""; }
|
|
if ($showatm) { $atm = &getoption82($atm); }
|
|
|
|
$ip = padtext($ip,$maxlen + 2);
|
|
$mac = padtext($mac,19);
|
|
|
|
if (!$color) { $result = padtext($result,7); }
|
|
else { $result = padtext($result,16); }
|
|
|
|
$atm = padtext($atm,5);
|
|
$hostname = padtext("($hostname)",20);
|
|
|
|
my $outline = "$ip$result$mac$atm$lease_end$hostname\n";
|
|
print $outline;
|
|
}
|
|
|
|
my $percent;
|
|
if (!$total == 0) {
|
|
$percent = sprintf("%2.f%%", ($count/$total) * 100);
|
|
}
|
|
else {
|
|
$percent = "100%";
|
|
}
|
|
print "$count active leases ($percent)\n";
|
|
#$output .= "$count active leases ($percent)\n";
|
|
print $output;
|
|
|
|
sub getoption82 () {
|
|
my $data = shift;
|
|
if (!$data) { return -1; }
|
|
|
|
my @list = split(":",$data);
|
|
my $vpi = hex($list[9]);
|
|
my $vci = (hex($list[10]) * 16) + hex($list[11]);
|
|
return "$vpi-$vci";
|
|
}
|
|
|
|
sub padtext() {
|
|
my $str = shift;
|
|
my $len = shift;
|
|
if (!$str || !$len) { return $str; }
|
|
|
|
$str = sprintf("%-${len}s",$str);
|
|
return $str;
|
|
}
|
|
|
|
sub leasegm_to_epoch() {
|
|
my ($sec,$min,$hours,$mday,$mon,$year);
|
|
|
|
if (my @list = $_[0] =~ /(\w+)\s+(\d+)\s+(\d{4})\/(\d{1,2})\/(\d{1,2})\s+(\d{1,2}):(\d{1,2}):(\d{1,2})/) {
|
|
$sec = $list[7];
|
|
$min = $list[6];
|
|
$hours = $list[5];
|
|
$mday = $list[4];
|
|
$mon = $list[3] - 1;
|
|
$year = $list[2] - 1900;
|
|
}
|
|
elsif (my @list = $_[0] =~ /ends never/) {
|
|
$sec = 1;
|
|
$min = 1;
|
|
$hours = 1;
|
|
$mday = 1;
|
|
$mon = 1;
|
|
$year = 132;
|
|
}
|
|
else { die("Whoa that aint good!\n"); }
|
|
|
|
#print "$sec,$min,$hours,$mday,$mon,$year\n";
|
|
my $time_string = timegm($sec,$min,$hours,$mday,$mon,$year);
|
|
|
|
return $time_string;
|
|
}
|
|
|
|
# Check to see if the lease has expired
|
|
sub lease_expired() {
|
|
my $lease_time = shift;
|
|
#Make sure a lease time is passed in
|
|
if (!$lease_time) { return undef; }
|
|
|
|
my $time_now = time();
|
|
|
|
#If the lease is before right now, then the lease is still good
|
|
if ($lease_time < $time_now) { return 1; }
|
|
#Otherwise it has expired
|
|
else { return 0; }
|
|
}
|
|
|
|
sub usage() {
|
|
my $output .= "$0
|
|
-x --expired show lease expiration times
|
|
-m --mac show lease MAC address
|
|
-a --atm show lease ATM (Option 82) information
|
|
-i --IP=1.2.3.4 filter for ip 1.2.3.4 (regexp)
|
|
-c --color show output in color for readability
|
|
";
|
|
}
|