#!/usr/pkg/bin/perl
#
# $Header: /home/vikas/src/nocol/perlnocol/RCS/bpmon,v 1.5 1999/11/01 05:49:02 vikas Exp $
#
# 	bpmon - perl bootp service monitor
#
# Date: September 21, 1993
# Programmer: John Wobus, jmwobus@mailbox.syr.edu
#  Modifications:
#	Cleaned up for using 'nocollib.pl'	-vikas@navya.com
#	Added 'bootpquery' support.		-meyer@phloem.uoregon.edu
#  
#
#    (c) Syracuse University Computing & Network Services 1993
#
# No warranty is expressed or implied.  Permission to copy and use is
# extended to all.  Permission to redistribute is granted under the
# following conditions: it is not sold for profit; this copyright
# notice remains intact; the same permissions extend to the recipient;
# and if any changes are made, a notice is added so stating.
#
# Command Format:
#
#  bpmon
#
#    Automatically kills old process and forks a new one, reading
#    the configuration file in the process.
#
# What it does:
#
#    This program is used to monitor a bootp daemon. It uses the
#    'bootpquery' (or 'bootptest') program to send out a bootp query 
#    to the server, and reports whether it received an answer (in 
#    NOCOL format).
#     Example report of problem:
#
#    Site      Address      Time   +-Variable-+ +-Value-+  Condition
#   butler  144.1.8.2       13:38  bootp status        1    Critical
#
#    This reports that a bootp server called "butler" with IP number
#    144.1.8.2 went down at 13:38.
#
##### Output of 'bootpquery'
#	sentinel.syr.edu# bootpquery -h
#	Usage: bootpquery haddr [htype] [-i ipaddr] [-s server]
#                        [-b bootfile] [-v vendor]
#	sentinel.syr.edu# bootpquery 0800200846b7 -s 128.230.12.5 
#	Received BOOTREPLY from lurch.cns.syr.EDU (128.230.12.5)
#
#	Hardware Address:       08:00:20:08:46:b7
#	Hardware Type:          ethernet
#	IP Address:             128.230.4.7
#	Boot file:              /tftpboot/mx1500.sys
#
#	RFC 1048 Vendor Information:
#  	   Time Offset:          18000 seconds
#  	   Subnet Mask:          255.255.255.0
#  	   Gateway:              128.230.4.1
#  	   Domain Name Servers:  128.230.1.49, 128.230.12.5
#  	   Log Server            128.230.12.5
#  	   LPR Server:           128.230.12.5
#	sentinel.syr.edu#
#
##### Output of 'bootptest'
# Sending to 128.223.3.5 (request) htype:0 hlen:0 C:128.223.32.35 vend-rfc1395
# Recvd from 128.223.3.5 (reply) htype:0 hlen:0 C:128.223.32.35 
# S:128.223.3.5 sname:"phloem" vend-rfc1395 SM:255.255.254.0 GW:128.223.32.1 
# DNS:128.223.3.5,128.223.8.9,128.223.21.104,128.223.32.29,192.220.250.1 
# TS:128.223.32.35
#

######
# Files used:
#
#   bootpquery/bootptest	a Unix command that queries a bootp
#				server. 'bootptest' is available from CMU
#   bpmon-confg                 configuration file.
#   bpmon-output		created by this program in the NOCOL data dir.
#
# Nocol event elements used:
#   sender                     "bpmon"
#   mon, day, hour, min        time at which entity went up or down
#   severity                   up: 4; down: 3,2,1; test & down: 2;
#   nocop                      up, down, unknown
#   site
#    name                      the server name
#    addr                      the server's IP number
#   var                       
#    name                      "bootp status"
#    value                     1=up, 0=down
#    threshold                 always 2
#    units                     always "entry"
#
# To install this:
#   (1) Make sure bootpquery (or bootptest) is installed and set the
#	'rprog' variable below.
#   (2) Create your bpmon-confg file in NOCOL/etc/
#   (3) Install in NOCOL/bin/
#   (6) Add to 'keepalive_monitors' to startup program.
#
# Configuration file format:
#    #<text>                                   Comment line.
#    haddr=<enet addr>                         Ethernet address of host
#                                               that is running bpmon.
#    broadcast                                 Check queries that are
#                                               broadcast.
#    <name> <ip number>                        Name and number of bootp
#                                               server.
#
# Sample configuration file:
#    # bpmon configuration
#    haddr=080020011234
#    butler 144.1.8.2
#
## 
##
#
#
############################
## Variables customization #  overrides values in the nocollib.pl library
############################
$rprog="./bootpquery";		# Path for bootpquery/bootptest program
				# Set it to 'bootptest' if using that.
$varname="Bootp_Server";
$varunits="Status";
$sleepint=60*5;       		# Seconds to sleep between tries.
############################
$debug = 0;			# set to 1 for debugging output
$libdebug = 0;			# set to 1 for nocollib.pl debugging

require  "nocollib.pl" ;

-x $rprog || die("Could not find executable $rprog, exiting");

$maxseverity = $E_ERROR ;		# max severity of events

##
# Read the config file. Use '\t' as a separator
sub readconf {
    open(CONFIG,"<$cfile")||die("Couldn't find $cfile, exiting");
    while(<CONFIG>) {
	chop;
	if(/^\s*#/) {next;}	# skip comments
	if(/^\s*$/) {next;}   # skip blank lines

	if (/^\s*haddr=(\S+)(\s.*)?$/) {$haddr=$1;}
	elsif (/^\s*broadcast(\s.*)?$/) {push(@items,"255.255.255.255\tbroadcast");}
	elsif (/^\s*(\S+)\s+(\S+)(\s.*)?$/) {push(@items,"$2\t$1");}
    }
    close(CONFIG);
    
    if(0>$#items){die("Nothing to monitor in $cfile, exiting")};
}

## This sends a bootpquery to the server. Note handling of broadcast query.
#  Returns 0 if server works, 1 if it doesn't. 
sub dotest {
    local($server)=@_;
    local($command,$works,$goodresp);

    if ($rprog =~ /bootptest/)	# using bootptest
    {
	$command="$rprog $server";
	$goodresp="Recvd from $server \\(reply\\)";
    }
    else			# using 'bootpquery', not 'bootptest'
    {	
	if ($server eq "255.255.255.255") {$command = "$rprog $haddr";}
	else {$command="$rprog $haddr -s $server"; }

	$goodresp="Received\s+BOOTREPLY";
    }

    $works=0;
    open(STDERR, ">&STDOUT")          || die "Can't dup stdout";
    open(COMMAND, "$command |") || die "Can't open $command $!";
    while (<COMMAND>) {
        if (/$goodresp/) {
	    $works=1;
	    break;
	}
    }
    close(COMMAND);

    return($works);
}


###
### Main program:
###

# Fork and get rid of old process.
&nocol_startup;

&readconf;

# $item is an index into the arrays
foreach $item (@items) {
    local($number,$name)=split(/\t/,$item);
    &init_event("$name", "$number", $item);
}

while (1) {
    foreach $item (@items)
    {
	local ($status) = &dotest($siteaddr{$item}) ;
	
	&update_event($item, $status, $status, $maxseverity);
    }
    
    ## Note: we want to write the file quickly.
    open(OEVENTS,">$datafile");
    foreach $item (@items)  { &writeevent(OEVENTS, $item) } ;
    close(OEVENTS);
    sleep($sleepint);
    
} # end while(forever)

