clamav-devel/contrib/clamavmon/clamavmon
a209be97
 #!/usr/bin/perl -w
 
 #   Copyright (C) 2004 Nigel Horne <njh@bandsman.co.uk>
eb07d47f
 #
a209be97
 #   This program is free software; you can redistribute it and/or modify
 #   it under the terms of the GNU General Public License as published by
 #   the Free Software Foundation; either version 2 of the License, or
 #   (at your option) any later version.
eb07d47f
 #
a209be97
 #   This program is distributed in the hope that it will be useful,
 #   but WITHOUT ANY WARRANTY; without even the implied warranty of
 #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 #   GNU General Public License for more details.
eb07d47f
 #
a209be97
 #   You should have received a copy of the GNU General Public License
 #   along with this program; if not, write to the Free Software
48b7b4a7
 #   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 #   MA 02110-1301, USA.
a209be97
 
 #	clamavmon - monitor a network for virus intrusion
5297fcaf
 # Usage "clamavmon [machines...]" where machines is an optional list of machine
 # running clamd. These will turn from green to red if clamd dies. Clicking on
 # the machine name gives the version of clamd running there.
267027d7
 
 # TODO: clicking should give the data base information and date of last
ad821338
 #	freshclam, and then allow remote update
267027d7
 # TODO:	Resizing the program should resize the text area
a209be97
 
eb07d47f
 eval 'exec /usr/bin/perl -w -S $0 ${1+"$@"}' if 0;
a209be97
 
 use strict;
 use IO::Socket::INET;
 use Tk;
 use Tk::Dialog;
 
 my $mw = MainWindow->new;
 
eb07d47f
 # $mw->bind('<Alt-F4>' => \&exit);
5297fcaf
 
 my $top = $mw->Frame();
 my $middle = $mw->Frame();
 my $bottom = $mw->Frame();
 
 $top->pack();
 
 my $text = $middle->Scrolled('Text', -width => 50, -scrollbars => 'ow')->pack;
 
 $middle->pack();
a209be97
 
5297fcaf
 my $b1 = $bottom->Button(-text => 'About', -command => \&about)->pack(-side => 'left');
 my $b2 = $bottom->Button(-text => 'Quit', -command => \&exit)->pack(-side => 'left');
a209be97
 
5297fcaf
 $bottom->pack();
 
eb07d47f
 my @machines;
5297fcaf
 
 if(@ARGV) {
eb07d47f
 	my $offset = 0;
 	foreach(@ARGV) {
 		$machines[$offset++] = $top->Button(-text => $_, -command => [ \&drill, $_ ])->pack(-side => 'left');
 	}
 	# Every minute check each of the clamd servers are still up
 	&pinger;
 	$mw->repeat(60000, \&pinger);
5297fcaf
 }
 
 # $t->detach();
a209be97
 
5297fcaf
 my $history = "";
 
eb07d47f
 my $sock = IO::Socket::INET->new(
 	LocalPort => 3310,
 	Proto => 'udp',
 	Type => SOCK_DGRAM) or die "$0: socket: $!\n";
a209be97
 
267027d7
 $sock->shutdown(SHUT_WR);
eb07d47f
 $mw->fileevent($sock, 'readable', [ \&packet_ready, $sock ]);
a209be97
 
eb07d47f
 MainLoop;
a209be97
 
eb07d47f
 sub packet_ready {
267027d7
 	# print "packet_ready\n";
eb07d47f
 	my $sock = shift;
5297fcaf
 
267027d7
 	# my $mess = <$sock>;
eb07d47f
 	my $mess;
 	$sock->recv($mess, 128);
a209be97
 
eb07d47f
 	my $peeraddr = $sock->peerhost;
a209be97
 
267027d7
 	# print "From $peeraddr $mess\n";
eb07d47f
 	$text->insert('end', "From $peeraddr: $mess\n");
5297fcaf
 }
 
 sub pinger {
267027d7
 	# print "pinger\n";
eb07d47f
 	foreach(@machines) {
 		my $machine = $_->cget('-text');
 		my $sock = IO::Socket::INET->new(
 			PeerPort => 3310,
 			PeerAddr => $machine,
 			Proto => 'tcp',
 			Timeout => 5,
 			Type => SOCK_STREAM);
5297fcaf
 
eb07d47f
 		if($sock) {
267027d7
 			$mw->fileevent($sock, 'readable', [ \&pinger_ready, $_, $sock ]);
eb07d47f
 			print $sock "PING\n";
5297fcaf
 
267027d7
 			$sock->shutdown(SHUT_WR);
5297fcaf
 
267027d7
 			$mw->update;
 		} else {
 			my $background = $_->cget('-background');
5297fcaf
 
eb07d47f
 			if($background ne 'red') {
 				$_->configure(-background => 'red');
 			}
5297fcaf
 		}
a209be97
 	}
 }
 
267027d7
 sub pinger_ready {
 	# print "pinger_ready\n";
 	my $machine = shift;
 	my $sock = shift;
 
 	# my $mess = <$sock>;
 	my $mess;
 	$sock->recv($mess, 6);
 
 	my $peeraddr = $sock->peerhost;
 
 	close $sock;
 
 	my $background = $machine->cget('-background');
 
 	if($mess && ($mess ne "PONG\n")) {
 		# print "$machine is down\n";
 		if($background ne 'red') {
 			$machine->configure(-background => 'red');
 		}
 	} else {
 		# print "$machine is up\n";
 		if($background ne 'green') {
 			$machine->configure(-background => 'green');
 		}
 	}
 }
a209be97
 
5297fcaf
 # TODO: this should be modeless
a209be97
 sub about {
 	my $about = $mw->DialogBox(
 		-title=>"About clamAVmon",
 		-buttons=>["OK"]
 	);
 
 	$about->add('Label',
 		-anchor => 'w',
 		-justify => 'left',
 		-text => "clamAVmon\n" .
 			"Copyright (C) 2004 Nigel Horne njh\@bandsman.co.uk\n" .
 			"The GPL Licence will appear here")->pack;
 
 	$about->Show();
 }
5297fcaf
 
 sub drill {
 	my $machine = shift;
 
 	my $sock = IO::Socket::INET->new(
 		PeerPort => 3310,
 		PeerAddr => $machine,
 		Proto => 'tcp',
eb07d47f
 		Timeout => 5,
5297fcaf
 		Type => SOCK_STREAM) or die "$0: socket: $!\n";
 
 	print $sock "VERSION\n";
 
 	my $mess = <$sock>;
 
 	close $sock;
 
 	print $mess;
 
 	my $state = $mw->DialogBox(
267027d7
 		-title => $machine,
 		-buttons => ["OK"]
5297fcaf
 	);
 
 	$state->add('Label',
 		-anchor => 'w',
 		-justify => 'left',
 		-text => $mess)->pack;
 
 	$state->Show();
 }