network with what is in DNS. Hosts that are answering pings but are not in DNS may be unauthorized, and addresses in DNS which are not answering may be able to be reclaimed. Hawk monitors all hosts on the networks you specify and lets you view them via a web page. Hawk consists of a backend written in Perl that monitors hosts by ICMP pings and writes the status to a mysql database. The frontend is in PHP and lets you select which network to view, and how to view it. This version has several enhancements to the original; including cleaner Perl code, a user-definable string to designate unused addresses that are in DNS, testing that the forward and reverse hostnames match, and the daemon forks one process pre subnet. WWW: http://sourceforge.net/projects/iphawk/
217 lines
6.5 KiB
Text
217 lines
6.5 KiB
Text
--- daemon/hawk.orig 2002-01-12 01:10:52.000000000 +0000
|
|
+++ daemon/hawk 2012-02-05 12:31:38.000000000 +0000
|
|
@@ -1,8 +1,9 @@
|
|
-#!/usr/bin/perl
|
|
+#!%%PREFIX%%/bin/perl -w
|
|
|
|
# hawk version 0.60
|
|
# Greg Heim <gregheim@mindspring.com>
|
|
|
|
+use strict;
|
|
|
|
use Socket;
|
|
use Net::Netmask;
|
|
@@ -10,12 +11,14 @@
|
|
use File::Basename;
|
|
use DBI;
|
|
|
|
+# Variables defined in the config file
|
|
+our (@networks, @gateways, $frequency, $pingtimeout, $debuglevel, $logfile,
|
|
+ $dbuser, $dbpass, $dbhost, $dbname, $pidfile);
|
|
|
|
############################################################################
|
|
# create pid file and process config file
|
|
############################################################################
|
|
-$configfile = dirname($0) . "/hawk.conf";
|
|
-readConfigs($configfile);
|
|
+readConfigs("%%PREFIX%%/etc/hawk/daemon.conf");
|
|
|
|
createPidFile($pidfile);
|
|
|
|
@@ -34,13 +37,24 @@
|
|
# main loop
|
|
##########################################################################
|
|
LOOP: while () {
|
|
+ my ($block, @children, $netblock, $gateway, @ips, $ip, $pingtime, $hostname);
|
|
|
|
- $loopstarttime = time();
|
|
+ my $loopstarttime = time();
|
|
|
|
|
|
BLOCK: foreach $block (@networks) {
|
|
+
|
|
+ my $pid = fork();
|
|
+ if ($pid) {
|
|
+ # parent
|
|
+ push (@children, $pid);
|
|
+ } elsif ($pid == 0) {
|
|
+ # child
|
|
+
|
|
$netblock = new Net::Netmask ($block);
|
|
|
|
+ logMsg (2, "Forked a child process for $netblock");
|
|
+
|
|
# check here that gateway is up
|
|
if (@gateways) {
|
|
foreach $gateway (@gateways) {
|
|
@@ -51,7 +65,7 @@
|
|
|
|
if (!ping($gateway, $pingtimeout)) {
|
|
logMsg (1, "No response from gateway $gateway, skipping network $block");
|
|
- next BLOCK;
|
|
+ exit (0);
|
|
}
|
|
else {
|
|
logMsg (1, "Gateway $gateway responded. $block ok so far.");
|
|
@@ -90,15 +104,37 @@
|
|
$hostname = gethostbyaddr (inet_aton($ip), AF_INET);
|
|
$hostname = "" unless $hostname;
|
|
|
|
+ my $for_rev_match='0';
|
|
+ if ($hostname) {
|
|
+ my $packed_host_ip = gethostbyname("$hostname");
|
|
+ if (defined $packed_host_ip) {
|
|
+ if (inet_ntoa($packed_host_ip) =~ /^$ip$/) {
|
|
+ $for_rev_match='1';
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
# check if it's already in the database
|
|
# if pingtime is zero, that field isn't updated
|
|
if (ipExists($ip)) {
|
|
- updateRecord($ip, $hostname, $pingtime);
|
|
+ updateRecord($ip, $hostname, $pingtime, $for_rev_match);
|
|
}
|
|
else {
|
|
- insertRecord($ip, $hostname, $pingtime);
|
|
+ insertRecord($ip, $hostname, $pingtime, $for_rev_match);
|
|
}
|
|
}
|
|
+
|
|
+ logMsg (2, "Child process for $netblock exiting");
|
|
+ exit (0);
|
|
+
|
|
+ } else {
|
|
+ die "Couldn't fork: $!\n";
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
+ foreach (@children) {
|
|
+ waitpid($_, 0);
|
|
}
|
|
|
|
# sleep until it's time for another run
|
|
@@ -121,8 +157,9 @@
|
|
##########################################################################
|
|
sub ipExists {
|
|
|
|
- ($ip) = @_;
|
|
+ my ($ip) = @_;
|
|
my $qip; # ip from query
|
|
+ my ($dbh, %attr, $sth);
|
|
|
|
logMsg (2, "Checking database for $ip");
|
|
|
|
@@ -148,12 +185,13 @@
|
|
##########################################################################
|
|
sub insertRecord{
|
|
|
|
- ($ip, $hostname, $pingtime) = @_;
|
|
+ my ($ip, $hostname, $pingtime, $for_rev_match) = @_;
|
|
+ my ($dbh, %attr, $sth);
|
|
|
|
- logMsg (2, "Inserting record: IP: $ip, Hostname: $hostname, Pingtime: $pingtime");
|
|
+ logMsg (2, "Inserting record: IP: $ip, Hostname: $hostname, Pingtime: $pingtime, Match: $for_rev_match");
|
|
|
|
$dbh = DBI->connect('dbi:mysql:' . $dbname . ';host='. $dbhost, $dbuser, $dbpass, \%attr) or die "Couldn't connect to database: " . DBI->errstr;
|
|
- $sth = $dbh -> prepare("insert into hawk.ip (ip, hostname, lastping) values ('$ip', '$hostname', '$pingtime')");
|
|
+ $sth = $dbh -> prepare("insert into hawk.ip (ip, hostname, lastping, for_rev_match) values ('$ip', '$hostname', '$pingtime', '$for_rev_match')");
|
|
$sth -> execute or logMsg (0, "Couldn't update record!" . DBI -> errstr);
|
|
|
|
}
|
|
@@ -164,15 +202,16 @@
|
|
##########################################################################
|
|
sub updateRecord{
|
|
|
|
- ($ip, $hostname, $pingtime) = @_;
|
|
+ my ($ip, $hostname, $pingtime, $for_rev_match) = @_;
|
|
+ my ($query, $dbh, %attr, $sth);
|
|
|
|
- logMsg (2, "Updating record: IP: $ip, Hostname: $hostname, Pingtime: $pingtime");
|
|
+ logMsg (2, "Updating record: IP: $ip, Hostname: $hostname, Pingtime: $pingtime, Match: $for_rev_match");
|
|
|
|
if ($pingtime) {
|
|
- $query = "update hawk.ip set hostname = '$hostname', lastping = '$pingtime' where ip = '$ip'";
|
|
+ $query = "update hawk.ip set hostname = '$hostname', lastping = '$pingtime', for_rev_match = '$for_rev_match' where ip = '$ip'";
|
|
}
|
|
else {
|
|
- $query = "update hawk.ip set hostname = '$hostname' where ip = '$ip'";
|
|
+ $query = "update hawk.ip set hostname = '$hostname', for_rev_match = '$for_rev_match' where ip = '$ip'";
|
|
}
|
|
|
|
$dbh = DBI->connect('dbi:mysql:' . $dbname . ';host='. $dbhost, $dbuser, $dbpass, \%attr) or die "Couldn't connect to database: " . DBI->errstr;
|
|
@@ -188,14 +227,15 @@
|
|
sub ping {
|
|
|
|
my ($ip, $timeout) = @_;
|
|
+ my ($p, $return);
|
|
|
|
logMsg(2, "Pinging $ip");
|
|
|
|
- $p = Net::Ping->new(icmp);
|
|
+ $p = Net::Ping->new('icmp');
|
|
$return = $p->ping($ip, $timeout);
|
|
$p->close;
|
|
|
|
- logMsg(2, "Ping returned $return");
|
|
+ logMsg(2, "Ping $ip returned $return");
|
|
|
|
return $return;
|
|
}
|
|
@@ -208,7 +248,7 @@
|
|
|
|
sub createPidFile {
|
|
|
|
- ($pidfile) = @_;
|
|
+ my ($pidfile) = @_;
|
|
|
|
logMsg (2, "Creating pid file $pidfile");
|
|
|
|
@@ -219,7 +259,7 @@
|
|
|
|
# found pid file. signalling existing process
|
|
logMsg (1, "Pid file $pidfile exists. Attempting to signal existing process.");
|
|
- $kstatus = kill 0, $pid;
|
|
+ my $kstatus = kill 0, $pid;
|
|
|
|
# see if we killed anything
|
|
if ($kstatus) {
|
|
@@ -305,9 +345,8 @@
|
|
|
|
sub readConfigs {
|
|
|
|
- ($file) = @_;
|
|
+ my ($file) = @_;
|
|
|
|
- logMsg(1, "Reading config file");
|
|
do $file;
|
|
|
|
}
|
|
@@ -317,12 +356,12 @@
|
|
##########################################################################
|
|
# write debug messages
|
|
##########################################################################
|
|
-sub logMsg () {
|
|
+sub logMsg {
|
|
|
|
- ($level, $message) = @_;
|
|
+ my ($level, $message) = @_;
|
|
if ($debuglevel >= $level) {
|
|
|
|
- $time = localtime(time);
|
|
+ my $time = localtime(time);
|
|
open LOGFILE, ">> $logfile" || die "Couldn't open logfile: $!\n";
|
|
print LOGFILE "$time: $message\n";
|
|
close LOGFILE;
|