DHCP Scope Monitor Perl Script

Ken darkdantae at aol.com
Sun Nov 28 17:49:36 UTC 2004


*****This is information based only*****

I was looking for a script to poll my windows 2000 dhcp server and
print out I nice chart.I didn't find any on the web, so, after I built
one I thought I would give post it on the groupsthat I always take
from but have never contributed to. Please realize I really don't know
anything about perl and scripting, most of my limited programming
comes from c++. I kinda see what other people do and learn from
examples on the fly.

This script prints out a html chart with the following columns: DHCP
server, the scope, how many ip's are in use, how many ips are free,
total ip, percent in use, and estimated class c's. You might want to
get rid of that last column if you have scopes that have less than a
full class C. If a scope is found with a higher percentage than the
threshold (90 in my case) the font is colored red, to grab your
attention. You could have it do other things if you felt like
scripting it, e.g. e-mail you. Finally it gives you stats on: how many
subnets there are, how many total ips are in use, how many total ips
are free, how many total ips there are, and the total percetage of ips
being used. I have over a hundred scopes on two different servers, and
the script only takes about 20-30 seconds.

my configurations.
-This is perl, v5.8.3 built for i386-linux-thread-multi
-fedora core 2


Assumptions
-You are attempting to get a microsoft 2000 dhcp server stats
-snmp is allowed to the server you are running this from, of course I
suggest locking snmp to only allow access from polling server
-perl is located @ /usr/bin/perl, for many it will in fact be
/usr/bin/local/perl
-you have perl modules Net::SNMP, and Time::Duration, not sure if it
comes with fedora or not, because someone else had already used those
modules and I didn't have to make any changes myself
-you have only class A or B, otherwise you could use regular
expressions to check if it returns an IP or other, but I didn't do it
that way
-both boxes are snmp version 2 capable, otherwise change v2c to v1
-dhcp_update and dhcp-scop-monitor are excutable by the person using
it, or cron

cronjob
00      1       *       *       *       root           
/usr/scripts/dhcp_update


the file /usr/scripts/dhcp_update
/var/www/html/cgi-bin/dhcp-scope-monitor > /var/www/html/dhcp.htm
#put your file locations


the perl script dhcp-scope-monitor
#!/usr/bin/perl
use Net::SNMP;
use Time::Duration;

############################################################
# written by Ken C, darkdantae at aol.com, don't laugh it     #
# is from high school like 10 years ago, but it still works#
############################################################

@server = ("DHCP-01","DHCP-02");  #list your dhcp servers here, by ip
or dns name
$rosnmp = "ROstring";   #this is your read-only snmp community string
$percentthreshold = "90";  #the threshold that you want to flag
$evalip = "172.16.";   #what to evaluate
$sprintf = "%.7s";    #how many digits to evaluate

##########################################################
#That should be the only configurations you need to make #
##########################################################

print "<html><body bgcolor=#345d98 link=black vlink=black><br>\n";
print "<center><h1>DHCP Scope Monitor</h1>\n";

   open(DATE, "date|");  
         $theDate = <DATE>;
   close DATE;
   
print "<center><b>Statistics as of $theDate<br>\n";
print "<table border=1 cellpadding=8><tr>\n";
print "<th><b>DHCP Server</th><th><center><b>Subnet</th><th><b>IP's in
use</th>\n";
print "<th><b>IP's Free</th><th><b>Total
IP's</th><th><b><center>Percentage in use</th></center>\n";
print "<th><b>Estimated Class C's</th></tr><br>\n";


$count=0;
foreach $server (@server)
    {

    $address = "1.3.6.1.4.1.311.1.3.2.1.1.1";
    $getsubnet = "snmpgetnext -v2c -c $rosnmp -Oqv $server  $address
|";
    
    open(SUBNET, "$getsubnet");
    $subnet = <SUBNET>;
    close SUBNET;

    $evalsubnet = sprintf($sprintf, $subnet);
    while ($evalsubnet eq $evalip)
    { 
        $inuse= "1.3.6.1.4.1.311.1.3.2.1.1.2";
        $free = "1.3.6.1.4.1.311.1.3.2.1.1.3";
   
        $address = "1.3.6.1.4.1.311.1.3.2.1.1.1";
        $address =join ".", $address,$subnet;
        $inuse=join ".", $inuse,$subnet;
	  $free=join ".", $free,$subnet;

        $getinuse = "snmpget -v2c -c $rosnmp -Oqv $server  $inuse |";
        $getfree = "snmpget -v2c -c  $rosnmp -Oqv $server  $free |";


        open(INUSE, "$getinuse");
        $inuseresponse = <INUSE>;
        close INUSE;

        open(FREE, "$getfree");
        $freeresponse = <FREE>;
        close FREE;


        $totalip = ($inuseresponse + $freeresponse);
        if ($totalip == 0)
        {
           $percentuse = "not active";
        }
        else
        {
            $percentuse =  $inuseresponse / $totalip;
            $percentuse = $percentuse * 100;
            $percentuse = sprintf ("%.0f%",$percentuse);
        }
	
        if ($totalip < 255)
	    {
            $estip = "1";
        }
    	elsif ($totalip > 255 and $totalip < 510)
	    { 
            $estip = 2;
        }
    	else
	    { 
            $estip = 4
        }

        if ($percentuse >= $percentthreshold)
        {
            $fontstyle = "<b><font color = RED>"
        }
        else
        {
            $fontstyle = "<font color = BLACK>"
        }

    	print "<tr><td><center>$fontstyle$server</td>\n";
    	print "<td><center>$fontstyle$subnet</td>\n";
    	print "<td><center>$fontstyle$inuseresponse</td>\n";
    	print "<td><center>$fontstyle$freeresponse</td>\n";
    	print "<td><center>$fontstyle$totalip</td>\n";
    	print "<td><center>$fontstyle$percentuse</td>\n";
    	print "<td><center>$fontstyle$estip</td></tr>\n";

    	$getsubnet = "snmpgetnext -v2c -c $rosnmp  -Oqv $server $address
|";
    
    	open(SUBNET, "$getsubnet");
	    $subnet = <SUBNET>;
    	close SUBNET;
    
    	$evalsubnet = sprintf($sprintf, $subnet);
        if ($inuseresponse >= 1)
        {
            $count++;
            $totalinuse = ($totalinuse + $inuseresponse);
            $totalfree = ($totalfree + $freeresponse);
        }    
        }
    }
$alltotal = ($totalfree + $totalinuse);
$allpercentuse =  $totalinuse / $alltotal;
$allpercentuse = $allpercentuse * 100;
$allpercentuse = sprintf ("%.0f%",$allpercentuse);
print "</table><br>\n";
print "<table border=0 cellpadding=4 width=35%>\n";
print "<tr><td><center><b>Note: scopes with 0 IP's in use are not
taken into consideration ";
print "for stats as they are considered to be not in use</td></tr>\n";
print "<tr><td><center><b>Percentage threshold is. . .
$percentthreshold</td></tr>\n";
print "<tr><td><center><b>Total Subnets. . . $count</td></tr>\n";
print "<tr><td><center><b>Total Inuse IP's. . .
$totalinuse</td></tr>\n";
print "<tr><td><center><b>Total Free IP's. . .
$totalfree</td></tr>\n";
print "<tr><td><center><b>Total IP's. . . $alltotal</td></tr>\n";
print "<tr><td><center><b>Total Percentage in use. . .
$allpercentuse</td></tr></table>\n";





###########################################################
# End of script, if you have any suggestions on how       #
# too improve the script please post them, I really       #
# have no clue at what I am doing. Also if anyone can     #
# tell me how to create an update button that will        #
# automatically run the script again, it would be greatly #
# appreciated                                             #
###########################################################



More information about the bind-users mailing list