#!/usr/bin/perl -wT # # check_nt_service.pl $Revision: 0.2 $ # # Uses the NT SNMP service to find out whether a particular # NT service is running. # # Copyright (C) 2001 Tim Deegan (tjd@chiark.greenend.org.uk) # # Based upon supclient 1.0, another SNMP client for http://www.uptimes.net/ # Copyright (C) 2000 Matthew Dainty (madmatt@bits.bris.ac.uk) # and the netsaint monitor scripts # # 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. # # 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. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # $Id: check_ntservice,v 0.2 2001/03/14 10:47:11 tdeegan Exp $ BEGIN { if ($0 =~ m/^(.*?)[\/\\]([^\/\\]+)$/) { $runtimedir = $1; $PROGNAME = $2; } } use strict; use lib $main::runtimedir; use vars qw( $host $port $community $oid $service $session $error $verbose $opt_V $opt_h $response $runtimedit $PROGNAME $exval ); use Getopt::Long; use Net::SNMP qw( snmp_event_loop ); use utils qw($TIMEOUT %ERRORS &print_revision &support &usage); sub print_help (); sub print_usage (); $port = '161'; $oid = '1.3.6.1.4.1.77.1.2.3.1.3'; # LanMan II MIB entry lanmgr-2.server.svSvcTable.svSvcEntry.svSvcOperatingState # Values for each available service are: # 1 - active # 2 - continue-pending # 3 - pause-pending # 4 - paused $ENV{'PATH'}=''; $ENV{'BASH_ENV'}=''; $ENV{'ENV'}=''; Getopt::Long::Configure('bundling'); GetOptions ("V" => \$opt_V, "version" => \$opt_V, "h" => \$opt_h, "help" => \$opt_h, "v" => \$verbose, "verbose" => \$verbose, "H=s" => \$host, "host=s" => \$host, "p:i" => \$port, "port:i" => \$port, "s=s" => \$service, "service=s" => \$service, "c=s" => \$community, "community=s" => \$community); # # Parse the standard options. # if ($opt_V) { print_revision($PROGNAME,' $Revision: 0.2 $ '); #' exit $ERRORS{'OK'}; } if ($opt_h) { print_help(); exit $ERRORS{'OK'}; } $host = shift unless ($host); if (!defined $host || !defined $service || !defined $community) { &print_usage(); exit 1; } # # Install the signal handler. # $SIG{ INT } = \&handler; # # Make an SNMP client object. # print "Connecting to $community\@$host:$port\n" if ($verbose); ( $session, $error ) = Net::SNMP->session( -hostname => $host, -community => $community, -port => $port, -nonblocking => 0x1, -translate => [ -timeticks => 0x0 ] ); if( ! defined( $session ) ) { print STDERR "Error establishing SNMP connection to $host, aborting\n"; exit 1; } # # Use it to get the service table. # print "Requesting $oid\n" if ($verbose); $session->get_table( -baseoid => $oid, -callback => [\&list_callback, $session] ); $response = 0; # Default is CRITICAL: The service isn't listed. snmp_event_loop(); # Here it may get softened as we parse the reply. # Deal with out-of-bounds answers. if (($response < 0) || ($response > 4)) { $response = 5; } print "NTSERVICE " . ("CRITICAL: $service not listed", "OK: $service state is ACTIVE", "WARNING: $service state is CONTINUE-PENDING", "WARNING: $service state is PAUSE-PENDING", "WARNING: $service state is PAUSED", "CRITICAL: $service listed in undefined state", )[$response] . "\n"; $exval = (2,0,1,1,1,2)[$response]; exit $exval; # Callback used to parse the table once Perl::SNMP has done the hard # work of getting it for us. sub list_callback { my ( $this, $session ) = @_; if( defined( $this->var_bind_list() ) ) { # Extract the response. my $key = ''; my $hashref = $this->var_bind_list(); print "Got a reply.\n" if ($verbose); foreach $key (keys %$hashref) { # We want to extract some data from the oid: # This is only reasonable for tablewalking this # particular OID, where we know that # the values will be ($oid).(number).(svcname) my ($name, $asciiname) = ($key, ''); $name =~ s/^$oid\.[0-9]+//; while ($name =~ s/^\.([0-9]+)//) { $asciiname .= chr ($1); } if ($asciiname eq $service) { $response = $hashref->{$key}; } print "$asciiname : " . ("ACTIVE", "CONTINUE-PENDING", "PAUSE-PENDING", "PAUSED") [$hashref->{$key} - 1] . "\n" if ($verbose); } } $this->error_status(); } # Signal handler, probably nearly always triggered by SIGINT. sub handler { $session->close(); die "Received signal SIG".( shift ); } # User-friendliness, such as it is. sub print_usage () { print "Usage: $PROGNAME -H hostname -p port -s service -c community [--verbose] $PROGNAME --help $PROGNAME --version "; } sub print_help () { print_revision($PROGNAME,'$Revision: 0.2 $ '); print "Copyright (c) 2001 Tim Deegan Check NT service list for a particular service, by SNMP "; print_usage(); print " -H --host=HOST Choose host to query -p --port=PORT Pick a port number (default is 161) -s --service=SERVICE Which NT service to check for -c --community=COMMUNITY SNMP community string -v, --verbose Print some extra debugging information (not advised for normal operation) -V, --version Show version and license information -h, --help Show this help screen "; support(); }