#!/usr/bin/perl -w 

# verify that a DHCP server is operating.
#
# usage: dhcp.monitor [host ...]
#
# Uses Net::DHCP::Watch to send a DHCP inform message to each of the servers
# listed on the command line, and then waits up to 30 seconds for a response.
#
# The script will determine your mon server's mac address and IP by parsing the
# output of 'ifconfig eth0'.  You may need to modify that logic for your
# operating system.
#
# Depending on your OS, you may need to have your mon server *not* be using DHCP
# for its own interface management, as some DHCP implementations will bind the
# DHCP port and refuse to allow Net::DHCP:Watch to generate and receive its own
# requests.


# Copyright (c) 2002 Carnegie Mellon University. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
#    this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
#    this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
#
# 3. The name "Carnegie Mellon University" must not be used to endorse or
#    promote products derived from this software without prior written
#    permission. For permission or any legal details, please contact:
#      Office of Technology Transfer
#      Carnegie Mellon University
#      5000 Forbes Avenue
#      Pittsburgh, PA 15213-3890
#      (412) 268-4387, fax: (412) 268-7395
#      tech-transfer@andrew.cmu.edu
#
# 4. Redistributions of any form whatsoever must retain the following
#    acknowledgment: "This product includes software developed by Computing
#    Services at Carnegie Mellon University (http://www.cmu.edu/computing/)."
#
# CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
# SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
# IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE FOR ANY SPECIAL,
# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.



use Net::DHCP::Watch;

$Client = qx[ /sbin/ifconfig eth0 | /bin/sed 's/:/ /' | /bin/grep "inet addr" | /bin/awk '{print \$3}' ];
chomp($Client);
$Ether  = qx[ /sbin/ifconfig eth0 | /bin/grep HWaddr | /bin/awk '{print \$5}'];
chomp($Ether);


foreach $host (@ARGV) {

    eval {
	my $dhcpw = new Net::DHCP::Watch({
					  client => $Client,
					  server => $host,
					  ether  => $Ether,
					  timeout => 30,
					 });
	my $success = 0;
	foreach (1..3) {
	    $dhcpw->watch();

	    my $s = $dhcpw->status();

	    if ($s->{Ok}) {
		$success = 1;
		last;
	    }

	    $dhcpw->unwatch();
	}

	if (!$success) {
	    push @failures, $host;
	    push @longerr, "$host: DHCP INFORM request failed";
	}
    };

    if ($EVAL_ERROR && ($EVAL_ERROR =~ /Timeout/ )) {
	push @failures, $host;
	push @longerr, "$host: Request timed out.";
    } elsif ($EVAL_ERROR) {
	push @longerr, "$host: $EVAL_ERROR";
	push @failures, $host;
    }
}

if (!@failures) {
    exit 0;
}

print join(" ", @failures),"\n";
print join("\n", @longerr), "\n";
exit scalar @failures;



