NMS Nagios

http://nagios.org/
http://www.nagiosexchange.org/
http://www.nagioscommunity.org/blog/

Check Plugin: APC UPS Battery Status

#!/usr/bin/perl -w
use strict;
use Net::SNMP;
use Getopt::Long;
use Pod::Usage;

=head1 NAME

check_upsbatt.pl - APC UPS Battery Query

=head1 SYNOPSIS

	check_upsbatt.pl -H host [-p community] 
	
	host:      IP address of unit
	community: Community string for host (default is public)

=head1 DESCRIPTION
                                                                                
Uses SNMP query to get the battery status.

=head1 AUTHOR

Nigel Bruin

=cut

###############################################################################
#
# Variables & constants

my ( $host, $community );

my $OutputTag = "UPS:";

# Nagios return codes
my $NagiosOK       = 0;
my $NagiosWarning  = 1;
my $NagiosCritical = 2;
my $NagiosUnknown  = 3;

# SNMP Port
my $PORT = 161;

# APC OIDs
my $OIDAPC                = '.1.3.6.1.4.1.318.';
my $OIDhardware           = $OIDAPC.'1.1.';
my $OIDups                = $OIDhardware.'1.';
my $OIDident              = $OIDups.'1.';
my $OIDidentBasic         = $OIDident.'1.';
my $OIDidentBasicModel    = $OIDidentBasic.'1.0';
my $OIDidentBasicName     = $OIDidentBasic.'2.0';
my $OIDidentAdv           = $OIDident.'2.';
my $OIDidentAdvFW         = $OIDidentAdv.'1.0';
my $OIDidentAdvManuf      = $OIDidentAdv.'2.0';
my $OIDidentAdvSerial     = $OIDidentAdv.'3.0';
my $OIDbattery            = $OIDups.'2.';
my $OIDbatteryBasic       = $OIDbattery.'1.';
my $OIDbatteryBasicStatus = $OIDbatteryBasic.'1.0';
my $OIDbatteryBasicTime   = $OIDbatteryBasic.'2.0';
my $OIDbatteryBasicRepl   = $OIDbatteryBasic.'3.0';
my $OIDbatteryAdv         = $OIDbattery.'2.';
my $OIDbatteryAdvTemp     = $OIDbatteryAdv.'2.0';
my $OIDbatteryAdvRuntime  = $OIDbatteryAdv.'3.0';
my $OIDbatteryAdvReplace  = $OIDbatteryAdv.'4.0';

my $BATTERYREPLACE = '2';

my $TEMPCRIT = 55;
my $TEMPWARN = 50;

###############################################################################
#
# SNMP query sub routine
sub snmpQuery
  {
  my ($session, $result,$resultval,$query);
  ($session,$query) = @_;
  $result = $session->get_request( -varbindlist => [$query]);

  if (!defined($result)) { return "" };

  return $result->{$query};
  };

###############################################################################
#
# Main routine

GetOptions("H=s" => \$host,
	   "p=s" => \$community,
          );

# Enforce parameter defaults
if(!$community) { $community="public" };

# Do some command line options checking
if( !$host )
  { pod2usage("$OutputTag Not enough arguments.\n"); exit $NagiosUnknown; };

# Start the SNMP session
my ($session, $error) = Net::SNMP->session(
	    -hostname  => shift || $host,
            -community => shift || $community,
            -port      => shift || $PORT,
            -version   => 1,
            -timeout   => 2,
            -retries   => 1);

if (!defined($session))
  # Persistent failure - give up.
  { print "$OutputTag CRITICAL - No response from unit\n"; exit $NagiosCritical; };

my $batteryAdvTemp    = snmpQuery($session, $OIDbatteryAdvTemp    );
my $batteryAdvRuntime = snmpQuery($session, $OIDbatteryAdvRuntime );
my $batteryAdvReplace = snmpQuery($session, $OIDbatteryAdvReplace );

# Close SNMP session.
$session->close;

if ($batteryAdvRuntime eq '')
  { $batteryAdvRuntime = '?' }
else
  {
  # Tidy up the uptime string
  $batteryAdvRuntime =~ s/(\d*) hours, 0(\d*):(\d*).(\d*)/$1 hrs, $2 mins/;
  $batteryAdvRuntime =~ s/(\d*) hours, (\d*):(\d*).(\d*)/$1 hrs, $2 mins/;
  $batteryAdvRuntime =~ s/1 hour, 0(\d*):\d*.\d*/1 hr, $1 mins/;
  $batteryAdvRuntime =~ s/1 hour, (\d*):\d*.\d*/1 hr, $1 mins/;
  $batteryAdvRuntime =~ s/0(\d*):\d*.\d*/$1 mins/;
  $batteryAdvRuntime =~ s/(\d*):\d*.\d*/$1 mins/;
  };

if (($batteryAdvReplace ne '') && ($batteryAdvReplace eq $BATTERYREPLACE))
  { print "$OutputTag CRITICAL - Battery requires replacement\n"; exit $NagiosCritical; };

if    ($batteryAdvTemp eq '')
  { $batteryAdvTemp = '?' }
elsif ($batteryAdvTemp >= $TEMPCRIT)
  { print "$OutputTag CRITICAL - Battery hot\n"; exit $NagiosCritical; }
elsif ($batteryAdvTemp >= $TEMPWARN)
  { print "$OutputTag WARNING - Battery hot\n"; exit $NagiosWarning; };

print "$OutputTag OK - Run time=$batteryAdvRuntime, Temp=$batteryAdvTemp C\n";

exit $NagiosOK;

Check Plugin: APC UPS Input Voltage

Example services.cfg:

# Power Monitor: SNMP (Input Voltage) Service Definition
define service{
        use                             generic-service
        host_name                       Net_UPS4
        service_description             Voltage
        is_volatile                     0
        check_period                    24x7
        max_check_attempts              1
        normal_check_interval           1
        retry_check_interval            1
        contact_groups                  nagios-admins
        notification_interval           60
        notification_period             24x7
        notification_options            c,w,r
        check_command                   check_ups!-p public
        }

Perl code:

#!/usr/bin/perl -w
use strict;
use Net::SNMP;
use Getopt::Long;
use Pod::Usage;

=head1 NAME

check_ups.pl - APC UPS Query

=head1 SYNOPSIS

	check_ups.pl -H host [-p community] 
	
	host:      IP address of unit
	community: Community string for host (default is public)

=head1 DESCRIPTION
                                                                                
Uses SNMP query to get the input voltage values.

=head1 AUTHOR

Nigel Bruin

=cut

###############################################################################
#
# Variables & constants

my ( $host, $community, $volts, $volt, $iterations, $okay );

my $OutputTag = "UPS:";

# Nagios return codes
my $NagiosOK       = 0;
my $NagiosWarning  = 1;
my $NagiosCritical = 2;
my $NagiosUnknown  = 3;

# Constants
my $VOLTWARN = 210;
my $VOLTCRIT = 190;

# SNMP Port
my $PORT = 161;

# APC OID for input voltage
my $VoltageOID = '.1.3.6.1.4.1.318.1.1.1.3.2.1.0';

###############################################################################
#
# SNMP query sub routine
sub snmpQuery
  {
  my ($session, $result,$resultval,$query);
  ($session,$query) = @_;
  $result = $session->get_request( -varbindlist => [$query]);

  if (!defined($result)) { return "" };

  return $result->{$query};
  };

###############################################################################
#
# Main routine

GetOptions("H=s" => \$host,
	   "p=s" => \$community,
          );

# Enforce parameter defaults
if(!$community) { $community="public" };

# Do some command line options checking
if( !$host )
  { pod2usage("$OutputTag Not enough arguments.\n"); exit 3; };

# Start the SNMP session
my ($session, $error) = Net::SNMP->session(
	    -hostname  => shift || $host,
            -community => shift || $community,
            -port      => shift || $PORT,
            -version   => 1,
            -timeout   => 2,
            -retries   => 0);

if (!defined($session))
  # Persistent failure - give up.
  { print "$OutputTag CRITICAL - No response from unit\n"; exit 2; };

# We loop obsessively until we get PASS values.
$volt = 0;
$iterations = 0;
do
  {
  $iterations++;
  $volts = snmpQuery($session, $VoltageOID);
  if (defined($volts) && ($volts ne '')) {
    if ($volts > $volt) { $volt = $volts }
    };
  } 
  while ( ($iterations < 5) && ($volt <= $VOLTWARN) );

# Close SNMP session.
$session->close;

# Generate response text for Nagios
if ($volt <= $VOLTCRIT)
  { print "$OutputTag CRITICAL - $volt" . "V \n"; exit 2; };

if ($volt <= $VOLTWARN)
  { print "$OutputTag WARNING - $volt" . "V \n"; exit 1; };

print "$OutputTag OK - $volt" . "V \n";
exit $NagiosOK;

Check Plugin: Avaya AP2000 Access Point

Example services.cfg:

# Access Point SNMP (SSIDs) Service Definition
define service{
        use                             generic-service
        host_name                       APIckford1,APIckford2
        service_description             SSID
        is_volatile                     0
        check_period                    24x7
        max_check_attempts              3
        normal_check_interval           5
        retry_check_interval            1
        contact_groups                  nagios-admins
        notification_interval           60
        notification_period             24x7
        notification_options            c,r
        check_command                   check_ap2000!public
        }

Perl code:

#!/usr/bin/perl -w
use strict;
use Net::SNMP;
use Getopt::Long;
use Pod::Usage;

=head1 NAME

check_ap2000.pl - Show Proxim AP2000 radio SSIDs 

=head1 SYNOPSIS

	check_ap2000.pl -H host [-p community]
	
	host:      IP address of the access point
	community: Community string for host (default: public)

=head1 DESCRIPTION
                                                                                
Uses SNMP query to get the access point's SSIDs.

=head1 AUTHOR

Nigel Bruin. 2005

=cut

###############################################################################
#
# Constants and global variables

my $OutputTag = 'SSIDs:';

# SNMP Port
my $PORT = 161;

# OIDs for Proxim radio parameters
my $OID_IndexA = '1.3.6.1.4.1.11898.2.1.2.1.2.1.1.3';
my $OID_IndexB = '1.3.6.1.4.1.11898.2.1.2.1.2.1.1.4';

my $OID_RadioA = '1.3.6.1.4.1.11898.2.1.2.1.3.1.2.3.1';
my $OID_RadioB = '1.3.6.1.4.1.11898.2.1.2.1.3.1.2.4.1';

# Nagios return codes
my $NagiosOK       = 0;
my $NagiosWarning  = 1;
my $NagiosCritical = 2;
my $NagiosUnknown  = 3;

my ( $host, $community, $oid );

###############################################################################
#
# The actual query control, depending on the type.
sub snmpQuery {
    my ( $session, $result, $resultval, $query );
    ( $session, $query ) = @_;
    $result = $session->get_request( -varbindlist => [$query]);

    if (!defined($result)) {
      return;
      }
    $resultval = $result->{$query};
    return $resultval;
};

###############################################################################
#
# Main routine

GetOptions(
	"H=s" => \$host,
	"p=s" => \$community
);

# Enforce parameter defaults
if(!$community) { $community = 'public' };

# Do some command line options checking
if ( !$host ){
	pod2usage("$OutputTag Not enough arguments.\n");
	exit $NagiosUnknown;
	}

# Start the SNMP session
my ($session, $error) = Net::SNMP->session(
	    -hostname  => shift || $host,
            -community => shift || $community,
            -port      => shift || $PORT,
            -version   => 1,
            -timeout   => 2,
            -retries   => 2);

my $numSSID = 0;

if (!defined($session))
  # Persistent failure - give up.
  { print "$OutputTag CRITICAL - No response from $host \n"; exit $NagiosCritical; };

my $radioAssid = '';
my $idx = snmpQuery($session, $OID_IndexA);
if (defined($idx))
  {
  my $ssid = snmpQuery($session, $OID_RadioA);
  if (defined($ssid))
    { $radioAssid = '"'.$radioAssid.$ssid.'"'; $numSSID++ };
  };

my $radioBssid = '';
$idx = snmpQuery($session, $OID_IndexB);
if (defined($idx))
  {
  my $ssid = snmpQuery($session, $OID_RadioB);
  if (defined($ssid))
    { $radioBssid = '"'.$radioBssid.$ssid.'"'; $numSSID++ }
  };

# Generate answer
if ($numSSID == 0)
  { print "$OutputTag CRITICAL - No response from $host \n"; exit $NagiosCritical };

print "$OutputTag OK - $radioAssid  $radioBssid\n";
exit $NagiosOK;

Check Plugin: Orthogon Gemini Link Loss

Example services.cfg:

# Orthogon: Link Loss Service Definition
define service{
        use                             generic-service
        host_name                       Net_WRM-ICK2
        service_description             Link-Loss
        is_volatile                     0
        check_period                    24x7
        max_check_attempts              3
        normal_check_interval           2
        retry_check_interval            1
        contact_groups                  nagios-admins 
        notification_interval           120
        notification_period             24x7
        notification_options            c,w,r
        check_command                   check_geminiloss!-p public -w 150 -c 160
        }

Perl code:

#!/usr/bin/perl -w
use strict;
use Net::SNMP;
use Getopt::Long;
use Pod::Usage;

=head1 NAME

check_geminiloss.pl - Orthogon Gemini Link Loss Query

=head1 SYNOPSIS

	check_geminiloss.pl -H host [-p community] [-o oid] -w wlevel -c clevel
	
	host:      The Gemini radio
	community: Community string for host (default: public)
	oid:	   MIB object id to query    (default: 1.3.6.1.4.1.17713.1.12.5.0)
	wlevel:    Warning treshhold         (default: 160)
	clevel:    Critical treshhold        (default: 170)

=head1 DESCRIPTION
                                                                                
Uses SNMP query to get the radio's current link loss and compares
it against warning & critical levels.

=head1 AUTHOR

Nigel Bruin. 2005

=cut

###############################################################################
#
# Constants and global variables

my $OutputTag = "Link Loss:";

# SNMP Port
my $PORT = 161;

# Loss NIL value
my $NILLOSS = '100000000';

# Nagios return codes
my $NagiosOK       = 0;
my $NagiosWarning  = 1;
my $NagiosCritical = 2;
my $NagiosUnknown  = 3;

my ( $host, $community, $oid, $wlevel, $clevel );

###############################################################################
#
# The actual query control, depending on the type.
sub snmpQuery {
    my ( $session, $result, $resultval, $query );
    ( $session, $query ) = @_;
    $result = $session->get_request( -varbindlist => [$query]);

    if (!defined($result)) {
      return;
      }
    $resultval = $result->{$query};
    return $resultval;
};

###############################################################################
#
# Main routine
#
# We fetch the radio parameters twice and use the better RSSI and LQ values

GetOptions(
	"H=s" => \$host,
	"p=s" => \$community,
	"o=s" => \$oid,
	"w=i" => \$wlevel,
	"c=i" => \$clevel
);

# Enforce parameter defaults
if(!$community) { $community = "public"                     };
if(!$oid      ) { $oid       = "1.3.6.1.4.1.17713.1.12.5.0" };
if(!$clevel   ) { $clevel    = "170"                        };
if(!$wlevel   ) { $wlevel    = "160"                        };

# Do some command line options checking
if ( !$host ){
	pod2usage("$OutputTag Not enough arguments.\n");
	exit $NagiosUnknown;
	}
if ( $wlevel > $clevel ){
	pod2usage("$OutputTag wlevel is less than clevel\n");
	exit $NagiosUnknown;
	}

# Start the SNMP session
my ($session, $error) = Net::SNMP->session(
	    -hostname  => shift || $host,
            -community => shift || $community,
            -port      => shift || $PORT,
            -version   => 1,
            -timeout   => 2,
            -retries   => 0);

if (!defined($session))
  # Persistent failure - give up.
  { print "$OutputTag CRITICAL - No response from unit\n"; exit $NagiosCritical; };

# We take an optimistic view.  Loop several times, getting the
# unit's link loss and use the best of the values returned.
my $loss = $NILLOSS;
for ( my $loop = 1 ; $loop < 5 ; $loop++ )
  {
  my $losstemp = snmpQuery($session, $oid);
  if (defined($losstemp)) {
    if ($losstemp < $loss) { $loss = $losstemp };
    sleep(1);
    }
  };

# Generate answer
if ($loss == $NILLOSS)
  { print "$OutputTag CRITICAL - No response from unit\n"; exit $NagiosCritical };

my $lossint = int($loss / 10);

if ($lossint gt $clevel)
  { print "$OutputTag CRITICAL - $lossint dB\n"; exit $NagiosCritical };

if ($lossint ge $wlevel)
  { print "$OutputTag WARNING - $lossint dB\n"; exit $NagiosWarning };

print "$OutputTag OK - $lossint dB\n";
exit $NagiosOK;

Check Plugin: Orthogon Gemini Modulation Mode

#!/usr/bin/perl -w
use strict;
use Net::SNMP;
use Getopt::Long;
use Pod::Usage;

=head1 NAME

check_geminimod.pl - Orthogon Gemini Modulation Mode Query

=head1 SYNOPSIS

	check_geminimod.pl -H host [-p community] [-o oid] [ -w wlevel ] [ -c clevel ]
	
	host:      The Gemini radio
	community: Community string for host (default: public)
	oid:	   MIB object id to query    (default: 1.3.6.1.4.1.17713.1.12.8.0)
	wlevel:    Warning treshhold         (default: 1)
	clevel:    Critical treshhold        (default: 0)

=head1 DESCRIPTION
                                                                                
Uses SNMP query to get the radio's current modulation mode and compares
it against warning & critical levels.

=head1 AUTHOR

Nigel Bruin. 2005

=cut

###############################################################################
#
# Constants and global variables

my $OutputTag = "Modulation:";

# SNMP Port
my $PORT = 161;

# Nagios return codes
my $NagiosOK       = 0;
my $NagiosWarning  = 1;
my $NagiosCritical = 2;
my $NagiosUnknown  = 3;

my ( $host, $community, $oid, $wlevel, $clevel );

###############################################################################
#
# The actual query control, depending on the type.
sub snmpQuery {
    my ($session, $result,$resultval,$query);
    ($session,$query) = @_;
    $result = $session->get_request( -varbindlist => [$query]);

    if (!defined($result)) {
      return;
      }
    $resultval = $result->{$query};
    return $resultval;
};

###############################################################################
#
# Main routine
#
# We fetch the radio parameters twice and use the better RSSI and LQ values

GetOptions(
	"H=s" => \$host,
	"p=s" => \$community,
	"o=s" => \$oid,
	"w=i" => \$wlevel,
	"c=i" => \$clevel
);

# Enforce parameter defaults
if(!$community) { $community = "public"                     };
if(!$oid      ) { $oid       = "1.3.6.1.4.1.17713.1.12.8.0" };
if(!$clevel   ) { $clevel    = "0"                          };
if(!$wlevel   ) { $wlevel    = "1"                          };

# Do some command line options checking
if( !$host ){
	pod2usage("$OutputTag Not enough arguments.\n");
	exit $NagiosUnknown;
}
if($wlevel<=$clevel){
	pod2usage("$OutputTag wlevel is greater clevel\n");
	exit $NagiosUnknown;
}

# Start the SNMP session
my ($session, $error) = Net::SNMP->session(
	    -hostname  => shift || $host,
            -community => shift || $community,
            -port      => shift || $PORT,
            -version   => 1,
            -timeout   => 2,
            -retries   => 0);

if (!defined($session))
  # Persistent failure - give up.
  { print "$OutputTag CRITICAL - No response from unit\n"; exit $NagiosCritical };

# We take an optimistic view.  Loop several times, getting the
# unit's modulation and use the highest of the values returned.
my $mod = "0";
for ( my $loop = 1 ; $loop < 6 ; $loop++ )
  {
  my $modtemp = snmpQuery($session, $oid);
  if (defined($modtemp)) {
    if ($modtemp gt $mod) { $mod = $modtemp };
    sleep(1);
    }
  };

# Convert integer coding to a human readable string
my $MOD = "UNKNOWN";
if ($mod eq "0") { $MOD = "0-[........] Link Aquisition (zeroMbps)" };
if ($mod eq "1") { $MOD = "1-[*.......] BPSK-1-2 (1.6Mbps)"         };
if ($mod eq "2") { $MOD = "2-[**......] QPSK-1-2 (3.8Mbps)"         };
if ($mod eq "3") { $MOD = "3-[***.....] QPSK-2-3 (5.0Mbps)"         };
if ($mod eq "4") { $MOD = "4-[****....] 16QAM-1-2 (7.5Mbps)"        };
if ($mod eq "5") { $MOD = "5-[*****...] 16QAM-3-4 (11.3Mbps)"       };
if ($mod eq "6") { $MOD = "6-[******..] 64QAM-2-3 (15.1Mbps)"       };
if ($mod eq "7") { $MOD = "7-[*******.] 64QAM-3-4 (16.9Mbps)"       };
if ($mod eq "8") { $MOD = "8-[********] 64QAM-7-8 (19.8Mbps)"       };

# Generate answer
if ($mod le $clevel)
  { print "$OutputTag CRITICAL - $MOD\n"; exit $NagiosCritical };

if ($mod le $wlevel)
  { print "$OutputTag WARNING - $MOD\n"; exit $NagiosWarning };

print "$OutputTag OK - $MOD\n";
exit $NagiosOK;

Check Plugin: SmartBridges AirBridge CPE

Example services.cfg:

# airBridge CPE SNMP-based Service definitions
define service{
        use                             generic-service
        hostgroup_name                  ickford1
        service_description             SNMP
        is_volatile                     0
        check_period                    24x7
        max_check_attempts              2
        normal_check_interval           10
        retry_check_interval            2
        contact_groups                  nagios-admins
        notification_interval           1440    ; 1 day reminders only
        notification_period             24x7
        notification_options            c,r
        check_command                   check_airbridge         ; Shouldn't need -p password option
        }

Perl code:

#!/usr/bin/perl -w
use strict;
use Net::SNMP;
use Getopt::Long;
use Pod::Usage;

=head1 NAME

check_airbridge.pl - SmartBridges AirBridge Query

=head1 SYNOPSIS

	check_airbridge.pl -H host [-p community] [-wr rw%] [-cr rc%] [-wl wl%] [-cl cl%]
	
	host:      IP address of the airBridge
	community: Community string for host    (default: public)
	wr%:       RSSI warning threshold (%)   (default: 35)
	cl%:       RSSI critical threshold (%)  (default; 25)
	wl%:       LQ warning threshold (%)     (default; 40)
	cl%:       LQ critical threshold (%)    (default: 25)

=head1 DESCRIPTION
                                                                                
Uses an SNMP query to get the RSSI and Link Quality values from the airBridge.
These are filtered for rogue values and compared against warning & critical levels.
Output is Nagios compliant in format and return code.

=head1 AUTHOR

Nigel Bruin

=cut

###############################################################################
#
# Constants

# Text printed at beginning of script output.
my $OutputTag = "airBridge:";

# SNMP Port
my $PORT = 161;

# airBridge SNMP OID for radio parameters
my $MediaOID = '1.3.6.1.4.1.410.1.2.8.1.0';

# Atmel radio parameters maximum
my $MAX_RSSI = 40.0;

# Number of times to check a radio before giving up
my $MAXITERATIONS = 3;
my $CHECKINTERVAL = 10;

# Nagios return codes
my $NagiosOK       = 0;
my $NagiosWarning  = 1;
my $NagiosCritical = 2;
my $NagiosUnknown  = 3;

###############################################################################
#
# Global variables

my ( $host, $community, $rssiWarn, $rssiCrit, $linkWarn, $linkCrit );
my ( $RBytes, $link1, $rssi1, $okay );

###############################################################################
#
# SNMP query sub routine
sub snmpQuery {
    my ($session, $result,$resultval,$query);
    ($session,$query) = @_;
    $result = $session->get_request( -varbindlist => [$query]);
    if (!defined($result)) { return "" };

    return $result->{$query};
};

###############################################################################
#
# Main routine

GetOptions("H=s"  => \$host,
	   "p=s"  => \$community,
	   "cr=i" => \$rssiCrit,
	   "cl=i" => \$linkCrit,
	   "wr=i" => \$rssiWarn,
	   "wl=i" => \$linkWarn,
          );

# Enforce parameter defaults
if(!$community) { $community = "public" };
if(!$rssiCrit ) { $rssiCrit  = 25       };
if(!$linkCrit ) { $linkCrit  = 25       };
if(!$rssiWarn ) { $rssiWarn  = 35       };
if(!$linkWarn ) { $linkWarn  = 40       };

# Command line options checking
if ( !$host )
  { pod2usage("$OutputTag Not enough arguments.\n"); exit $NagiosUnknown };
if ( ($rssiCrit > 100) || ($linkCrit > 100) || ($rssiWarn > 100) || ($linkWarn > 100) )
  { pod2usage("$OutputTag Parameter error.\n"); exit $NagiosUnknown };
if ( $linkCrit >= $linkWarn )
  { pod2usage("$OutputTag LQ Critical must be less than LQ warning.\n"); exit $NagiosUnknown };
if ( $rssiCrit >= $rssiWarn )
  { pod2usage("$OutputTag RSSI Critical must be less than RSSi warning.\n"); exit $NagiosUnknown };

# Start the SNMP session
my ($session, $error) = Net::SNMP->session(
	    -hostname  => shift || $host,
            -community => shift || $community,
            -port      => $PORT,
            -version   => 1,
            -timeout   => 2,
            -retries   => 1);

if (!defined($session))
  # Cannot continue - give up.
  { print "$OutputTag CRITICAL - No response from $host \n"; exit $NagiosCritical };

# We loop obsessively until we get PASS values.
my $link = 0;
my $rssi = 0;
my $iterations = 0;
do
  {
  # Get the airBridge radio parameters
  $RBytes = snmpQuery($session, $MediaOID);
  if ($RBytes)
    {
    # Extract RSSI and SNR values from Atmel MIB structure.
    $rssi1 = hex(substr($RBytes, 22, 2));
    $link1 = hex(substr($RBytes, 30, 2));

    # The MAX_RSSI for smartBridges radios is 40. This is a baseband processor
    # default, and is used for calculation of the Roaming threshold and
    # other parameters in the operaion of the channel. The different values
    # are also used for RSSI in a relative manner for other functions. For
    # the purpose of representation, the MAX_RSSI is scaled as per the Radio
    # to show a percentage value. In dBm, the same would range from -95 dBm
    # to -10 dBm. In the next few lines we just convert the RSSI value to a
    # percentage.
    if ($rssi1 > $MAX_RSSI) { $rssi1 = $MAX_RSSI };
    if ($link1 > $MAX_RSSI) { $link1 = 0 };
    $link1 = int (( ($MAX_RSSI - $link1) / $MAX_RSSI ) * 100);
    $rssi1 = int (( $rssi1 / $MAX_RSSI ) * 100);

    # Use the best values which represents a optimistc atitude.
    if ($rssi1 > $rssi) { $rssi = $rssi1 };
    if ($link1 > $link) { $link = $link1 };
    };

  $okay = (($rssi > $rssiWarn) && ($link > $linkWarn));

  # Wait if we haven't got OK values yet, but only if we got a valid response
  # from the unit so we don't wait for a unit that is unresponsive or absent. 
  #if (!$okay && ($RBytes)) { sleep($CHECKINTERVAL) };
  if (!$okay) { sleep($CHECKINTERVAL) };
  } 
  # Keep looping until either the values will pass as OK, or we are taking too long
  while ( ($iterations++ < $MAXITERATIONS) && (!$okay) );

# Close SNMP session.
$session->close;

# Generate response text for Nagios
if (($rssi == 0) && ($link == 0))
  { print "$OutputTag CRITICAL - No response from $host \n"; exit $NagiosCritical };

if ($rssi < $rssiCrit)
  { print "$OutputTag CRITICAL - *RSSI=$rssi%, LQ=$link%\n"; exit $NagiosCritical };

if ($link < $linkCrit)
  { print "$OutputTag CRITICAL - RSSI=$rssi%, *LQ=$link%\n"; exit $NagiosCritical };

if ($rssi < $rssiWarn)
  { print "$OutputTag WARNING - *RSSI=$rssi%, LQ=$link%\n"; exit $NagiosWarning };

if ($link < $linkWarn)
  { print "$OutputTag WARNING - RSSI=$rssi%, *LQ=$link%\n"; exit $NagiosWarning };

print "$OutputTag OK - RSSI=$rssi%, LQ=$link%\n";
exit $NagiosOK;
  

Check Plugin: Trango TrangoLINK10

Example services.cfg:

# Trango Master: SNMP RSSI Service Definition
define service{                         
        use                             generic-service
        host_name                       Net_WRM-WRN
        service_description             RSSI
        is_volatile                     0
        check_period                    24x7
        max_check_attempts              2
        normal_check_interval           2
        retry_check_interval            1
        contact_groups                  nagios-admins
        notification_interval           0
        notification_period             24x7
        notification_options            c,r
        check_command                   check_trangorssi! -w 83 -c 88 -p public -o 1.3.6.1.4.1.5454.1.22.2.1.0
        }

# Trango Slave: SNMP RSSI Service Definition
define service{                         
        use                             generic-service
        host_name                       Net_WRN-WRM
        service_description             RSSI
        is_volatile                     0
        check_period                    24x7
        max_check_attempts              2
        normal_check_interval           2
        retry_check_interval            1
        contact_groups                  nagios-admins
        notification_interval           0
        notification_period             24x7
        notification_options            c,r
        check_command                   check_trangorssi! -w 83 -c 88 -p public -o 1.3.6.1.4.1.5454.1.24.2.1.0
        }

Perl code:

#!/usr/bin/perl -w

use strict;
use Net::DNS;
use Getopt::Long;
use Pod::Usage;

=head1 NAME

check_trangorssi.pl - TrangoLink10 RSSI Query

=head1 SYNOPSIS

	check_hosts.pl -H host [-p community] [-o oid] -w wlevel -c clevel
	
	host:      The Trango radio (master
	community: Community string for host (default is public)
	oid:       MIB object ID to query (default is 1.3.6.1.4.1.5454.1.22.2.1.0).
	wlevel:    Warning treshhold (dBm)
	clevel:    Critical treshhold (dBm)

=head1 DESCRIPTION
                                                                                
Uses SNMP query to get the RSSI and filter for rogue values and compare
against warning & critical levels.

=head1 AUTHOR

Nigel Bruin

=cut
1
###############################################################################
#
# Constants

# Text printed at beginning of script output.
my $OutputTag = "RSSI:";

# Nagios return codes
my $NagiosOK       = 0;
my $NagiosWarning  = 1;
my $NagiosCritical = 2;
my $NagiosUnknown  = 3;

###############################################################################
#
# Variables

my ( $host, $community, $oid, $wlevel, $clevel, $cmd);
my $lowerthres = "-96";

GetOptions(
	"H=s" => \$host,
	"p=s" => \$community,
	"o=s" => \$oid,
	"w=i" => \$wlevel,
	"c=i" => \$clevel
);

# Enforce parameter defaults
if(!$community) { $community = "public"                };
if(!$oid      ) { $oid = "1.3.6.1.4.1.5454.1.22.2.1.0" };

# Do some command line options checking
if( !$host || !$wlevel || !$clevel){
	pod2usage("$0: Not enough arguments.\n");
	exit $NagiosUnknown;
	};
if($wlevel>=$clevel){
	pod2usage("$0: wlevel is greater clevel\n");
	exit $NagiosUnknown;
	};

# The SNMPGET & sleep commands we are going to use
my $snmpget = "/usr/bin/snmpget -v 1 -c $community -Oqvn -r 2 -t 1 $host $oid";
my $sleep   = "/bin/sleep 5";

$cmd = `$snmpget`;
if ($?) { print "$OutputTag CRITICAL - Invalid response\n"; exit 2; };

chomp ($cmd);
if ($cmd < $lowerthres)
  {
  # Possible rogue reply -- retry after a short delay to settle the radio
  $cmd = `$sleep; $snmpget`;
  if ($?) { print "$OutputTag CRITICAL - Invalid response\n"; exit 2; };
  chomp ($cmd);
  };

# Generate answer
if ($cmd < $lowerthres)
  { print "$OutputTag CRITICAL - Invalid response\n"; exit 2; };

if ($cmd<"-$clevel")
  { print "$OutputTag CRITICAL - $cmd dBm\n"; exit 2; };

if ($cmd<"-$wlevel")
  { print "$OutputTag WARNING - $cmd dBm\n"; exit 1; };

print "$OutputTag OK - $cmd dBm\n";
exit 0; # Nagios: OK

Check Plugin: Uptime

Example services.cfg:

define service{
        use                             generic-service
        host_name                       Net_Cyclone
        service_description             Uptime
        is_volatile                     0
        check_period                    24x7
        max_check_attempts              3
        normal_check_interval           15
        retry_check_interval            1
        contact_groups                  nagios-admins
        notification_interval           0
        notification_period             24x7
        notification_options            n
#       System uptime.                  
        check_command                   check_uptime!public
        }

Perl code:

#!/usr/bin/perl -w
use strict;
use Net::SNMP;
use Getopt::Long;
use Pod::Usage;

=head1 NAME

check_uptime.pl - Get standard Uptime value

=head1 SYNOPSIS

	check_uptime.pl -H host [-p community] [-o oid] 
	
	host:      The host's IP address
	community: Community string for host (default: public)
	oid:	   MIB object id to query    (default: 1.3.6.1.2.1.1.3.0)

=head1 DESCRIPTION
                                                                                
Uses SNMP query to get the unit uptime.

=head1 AUTHOR

Nigel Bruin. 2005

=cut

###############################################################################
#
# Constants and global variables

my $OutputTag = 'Uptime:';

# SNMP Port
my $PORT = 161;

# Nagios return codes
my $NagiosOK       = 0;
my $NagiosWarning  = 1;
my $NagiosCritical = 2;
my $NagiosUnknown  = 3;

my ( $host, $community, $oid );

###############################################################################
#
# The actual query control, depending on the type.
sub snmpQuery {
    my ( $session, $result, $resultval, $query );
    ( $session, $query ) = @_;
    $result = $session->get_request( -varbindlist => [$query]);

    if (!defined($result)) {
      return;
      }
    $resultval = $result->{$query};
    return $resultval;
};

###############################################################################
#
# Main routine

GetOptions(
	"H=s" => \$host,
	"p=s" => \$community,
	"o=s" => \$oid
);

# Enforce parameter defaults
if(!$community) { $community = 'public'            };
if(!$oid      ) { $oid       = '1.3.6.1.2.1.1.3.0' };

# Do some command line options checking
if ( !$host ){
	pod2usage("$OutputTag Not enough arguments.\n");
	exit $NagiosUnknown;
	}

# Start the SNMP session
my ($session, $error) = Net::SNMP->session(
	    -hostname  => shift || $host,
            -community => shift || $community,
            -port      => shift || $PORT,
            -version   => 1,
            -timeout   => 2,
            -retries   => 2);

if (!defined($session))
  { print "$OutputTag CRITICAL - No response from $host \n"; exit $NagiosCritical };

my $uptime = snmpQuery($session, $oid);

if (!defined($uptime))
  { print "$OutputTag CRITICAL - No response from $host \n"; exit $NagiosCritical };

# Generate answer
print "$OutputTag OK - $uptime\n";
exit $NagiosOK;

Config: MacOS launchd

Using launchd to automatically run nagios.

/System/Library/LaunchDaemons/com.wisp.nagios.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Label</key>
	<string>nagios</string>
	<key>OnDemand</key>
	<false/>
	<key>ProgramArguments</key>
	<array>
		<string>/usr/local/nagios/bin/nagios</string>
		<string>/usr/local/nagios/etc/nagios.cfg</string>
	</array>
	<key>RunAtLoad</key>
	<true/>
</dict>
</plist>

Config: checkcommands.cfg

################################################################################
# WISP Broadband object config file for Nagios 
#
################################################################################

################################################################################
# COMMAND DEFINITIONS
#
# SYNTAX:
#
#	define command{
#               template      
#		name          
#               command_name  
#               command_line  
#               }
# WHERE:
#
#  = object name of another command definition that should be
#                  used as a template for this definition (optional)
#    = object name of command definition, referenced by other
#                  command definitions that use it as a template (optional)
#   = name of the command, as recognized/used by Nagios
#   = command line
#
################################################################################

################################################################################
#
# SERVICE CHECK COMMANDS
#
################################################################################

# 'check_tcp' command definition
define command{
	command_name	check_tcp
	command_line	$USER1$/check_tcp -H $HOSTADDRESS$ -p $ARG1$
	}

# 'check_udp' command definition
define command{
	command_name	check_udp
	command_line	$USER1$/check_udp -H $HOSTADDRESS$ -p $ARG1$
	}

# 'check_ssh' command definition
define command{
	command_name	check_ssh
	command_line	$USER1$/check_ssh -H $HOSTADDRESS$
	}

# 'check_ftp' command definition
define command{
	command_name	check_ftp
	command_line	$USER1$/check_ftp -H $HOSTADDRESS$
	}

# 'check_pop' command definition
define command{
	command_name	check_pop
	command_line	$USER1$/check_pop -H $HOSTADDRESS$
	}

# 'check_snmp' command definition
define command{
	command_name	check_snmp
	command_line	$USER1$/check_snmp -H $HOSTADDRESS$ $ARG1$
	}

# 'check_smtp' command definition
define command{
	command_name	check_smtp
	command_line	$USER1$/check_smtp -H $HOSTADDRESS$ $ARG1$
	}

# 'check_nntp' command definition
define command{
	command_name	check_nntp
	command_line	$USER1$/check_nntp -H $HOSTADDRESS$ $ARG1$
	}

# 'check_http' command definition
define command{
	command_name	check_http
	command_line	$USER1$/check_http -H $HOSTADDRESS$ $ARG1$
	}

# 'check_telnet' command definition
define command{
	command_name	check_telnet
	command_line	$USER1$/check_tcp -H $HOSTADDRESS$ -p 23
	}

# 'check_ping' command definition
define command{
	command_name	check_ping
	command_line	$USER1$/check_ping -H $HOSTADDRESS$ -w $ARG1$ -c $ARG2$ $ARG3$
	}

# 'check_icmp' command definition
define command{
	command_name	check_icmp
	command_line	$USER1$/check_icmp -H $HOSTADDRESS$ -w $ARG1$ -c $ARG2$ 
	}

# 'check_keepalive' command definition
define command{
	command_name	check_keepalive
	command_line	$USER1$/check_keepalive.pl
	}

# 'check_dns' command definition
define command{
	command_name	check_dns
# Changed to use dig as chek_dns seemed to give too many false alarms
#	command_line	$USER1$/check_dns -H www.yahoo.com -s $HOSTADDRESS$ 
	command_line	$USER1$/check_dig -H $HOSTADDRESS$ -l www.yahoo.com -t 20
	}

# 'check_dig' command definition
define command{
	command_name	check_dig
	command_line	$USER1$/check_dig -H $HOSTADDRESS$ $ARG1$
	}

# 'check_host' command definition
define command{
	command_name	check_host
	command_line	$USER1$/check_dns.pl $ARG1$
	}

# 'check_hosts' command definition
define command{
	command_name	check_hosts
	command_line	$USER1$/check_hosts.pl -H $HOSTADDRESS$ $ARG1$
	}

# 'check_trangorssi' command definition
define command{
	command_name	check_trangorssi
	command_line	$USER1$/check_trangorssi.pl -H $HOSTADDRESS$ $ARG1$
	}

# 'check_geminimod' command definition
define command{
	command_name	check_geminimod
	command_line	$USER1$/check_geminimod.pl -H $HOSTADDRESS$ $ARG1$
	}

# 'check_geminiloss' command definition
define command{
	command_name	check_geminiloss
	command_line	$USER1$/check_geminiloss.pl -H $HOSTADDRESS$ $ARG1$
	}

# 'check_airbridge' command definition
define command{
	command_name	check_airbridge
	command_line	$USER1$/check_airbridge.pl -H $HOSTADDRESS$ $ARG1$
	}

# 'check_ups' command definition
define command{
	command_name	check_ups
	command_line	$USER1$/check_ups.pl -H $HOSTADDRESS$ $ARG1$
	}

# 'check_upsbatt' command definition
define command{
	command_name	check_upsbatt
	command_line	$USER1$/check_upsbatt.pl -H $HOSTADDRESS$ $ARG1$
	}

# 'check_multiups' command definition
define command{
	command_name	check_multiups
	command_line	$USER1$/check_multiups.pl $ARG1$
	}

# 'check_bonding' command definition
define command{
	command_name	check_bonding
	command_line	$USER1$/check_bonding.pl -H $HOSTADDRESS$ $ARG1$
	}

# 'check_multilinkppp' command definition
define command{
	command_name	check_multilinkppp
	command_line	$USER1$/check_multilinkppp.pl -H $HOSTADDRESS$ $ARG1$
	}

# 'check_wicadsl' command definition
define command{
	command_name	check_wicadsl
	command_line	$USER1$/check_wicadsl.pl -H $HOSTADDRESS$ $ARG1$
	}

# 'check_atm' command definition
define command{
	command_name	check_atm
	command_line	$USER1$/check_atm.pl -H $HOSTADDRESS$ $ARG1$
	}

# 'check_ap2000' command definition
define command{
	command_name	check_ap2000
	command_line	$USER1$/check_ap2000.pl -H $HOSTADDRESS$ -p $ARG1$
	}

# 'check_hpjd' command definition
define command{
	command_name	check_hpjd
	command_line	$USER1$/check_hpjd -H $HOSTADDRESS$ -C public
	}

# 'check_local_disk' command definition
define command{
	command_name	check_local_disk
	command_line	$USER1$/check_disk -w $ARG1$ -c $ARG2$ -p $ARG3$
	}

# 'check_local_users' command definition
define command{
	command_name	check_local_users
	command_line	$USER1$/check_users -w $ARG1$ -c $ARG2$
	}

# 'check_local_procs' command definition
define command{
	command_name	check_local_procs
	command_line	$USER1$/check_procs -w $ARG1$ -c $ARG2$ -s $ARG3$
	}

# 'check_local_load' command definition
define command{
	command_name	check_local_load
	command_line	$USER1$/check_load -w $ARG1$ -c $ARG2$
	}

# 'check_uptime' command definition
define command{
	command_name	check_uptime
#	command_line	$USER1$/check_snmp -H $HOSTADDRESS$ -o .1.3.6.1.2.1.1.3.0 -C $ARG1$ -t 5 -m : 
	command_line	$USER1$/check_uptime.pl -H $HOSTADDRESS$ -p $ARG1$ 
	}

################################################################################
#
# HOST CHECK COMMANDS
#
################################################################################

# This command checks to see if a host is "alive" by pinging it
# The check must result in a 100% packet loss or 5 second (5000ms) round trip 
# average time to produce a critical error.
# Note: Only one ICMP echo packet is sent (determined by the '-p 1' argument)

# 'check-host-alive' command definition
define command{
        command_name    check-host-alive
	command_line    $USER1$/check_ping -H $HOSTADDRESS$ -w 3000.0,80% -c 5000.0,100% -p 2 -t 6
#	command_line    $USER1$/check_updown.pl -H $HOSTADDRESS$ 
        }

# 'check-host-updown' command definition
define command{
        command_name    check-host-updown
        command_line    $USER1$/check_updown.pl -H $HOSTADDRESS$ 
        }

# 'check_nil' command definition
define command{
	command_name	check_nil
	command_line	$USER1$/check_nil.pl
	}

# 'check_dummy' command definition
define command{
	command_name	check_dummy
	command_line	$USER1$/check_dummy $ARG1$
	}

# 'check_ifoperstatus' command definition
define command{
	command_name	check_ifoperstatus
	command_line	$USER1$/check_ifoperstatus -H $HOSTADDRESS$ $ARG1$
	}

# 'check_log' command definition
define command{
	command_name	check_log
	command_line	$USER1$/check_log -F $ARG1$ -O $ARG2$ -q $ARG3$
	}

# 'check_log2' command definition
define command{
	command_name	check_log2
	command_line	$USER1$/check_log2 -l $ARG1$ -s $ARG2$ -p $ARG3$
	}

# 'check_logs' command definition
define command{
	command_name	check_logs
	command_line	$USER1$/check_logs.pl -l $ARG1$ -s $ARG2$ -p $ARG3$
	}

# 'check_tcpsmtp' command definition: checks TCP port 25
define command{
	command_name	check_tcpsmtp
	command_line	$USER1$/check_tcp -H $HOSTADDRESS$ -p 25
	}

Config: hosts.cfg

################################################################################
#
# WISP Broadband object config file for Nagios 
#
################################################################################

################################################################################
#
# HOST TEMPLATES
#
################################################################################

# Generic host definition template
define host{
	name				generic-host	; Template name, referenced in other host definitions
	notifications_enabled		1	; Host notifications are enabled
	event_handler_enabled		1	; Host event handler is enabled
	flap_detection_enabled		1	; Flap detection is enabled
	process_perf_data		1	; Process performance data
	retain_status_information	1	; Retain status information across program restarts
	retain_nonstatus_information	1	; Retain non-status information across program restarts
#	active_checks_enabled		0
#	passive_checks_enabled		0
	register			0	; Don't register, just a template
	}

# Dummy host definition template
define host{
	name				dummy-host
	notifications_enabled		1	; Host notifications are enabled
	event_handler_enabled		1	; Host event handler is enabled
	flap_detection_enabled		1	; Flap detection is enabled
	process_perf_data		1	; Process performance data
	retain_status_information	1	; Retain status information across program restarts
	retain_nonstatus_information	1	; Retain non-status information across program restarts
	check_command			check_nil
	max_check_attempts		1
	contact_groups			nagios-admins
	notification_interval		120
	notification_period		24x7
	notification_options		n
#	active_checks_enabled		0
#	passive_checks_enabled		0
	register			0	; Just a template
	}

# AP host definition template
define host{
	name				ap-host
	notifications_enabled		1	; Host notifications are enabled
	event_handler_enabled		1	; Host event handler is enabled
	flap_detection_enabled		1	; Flap detection is enabled
	process_perf_data		1	; Process performance data
	retain_status_information	1	; Retain status information across program restarts
	retain_nonstatus_information	1	; Retain non-status information across program restarts
	check_command			check-host-alive
	max_check_attempts		2
	contact_groups			nagios-admins
	notification_interval		120
	notification_period		24x7
	notification_options		d,u,r
#	active_checks_enabled		0
#	passive_checks_enabled		0
	register			0	; Just a template
	}

# CPE host definition template
define host{
	name				cpe-host
	notifications_enabled		1	; Host notifications are enabled
	event_handler_enabled		1	; Host event handler is enabled
	flap_detection_enabled		1	; Flap detection is enabled
	process_perf_data		1	; Process performance data
	retain_status_information	1	; Retain status information across program restarts
	retain_nonstatus_information	1	; Retain non-status information across program restarts
	check_command			check-host-alive
	max_check_attempts		1
	contact_groups			nagios-admins
	notification_interval		1440	; 24 hours
	notification_period		24x7
	notification_options		d,u,r
#	active_checks_enabled		0
#	passive_checks_enabled		0
	register			0	; Just a template
	}

################################################################################
#
# HOST DEFINITIONS
#

# Internet: ISP router definition
define host{
	use			generic-host
	host_name		ISP_Router
	alias			ISP Edge Router
#	address			195.72.164.155
	address			195.72.163.164
	parents			Net_Cyclone
	check_command		check-host-alive
	max_check_attempts	2
	contact_groups			nagios-admins
	notification_interval	120
	notification_period	24x7
	notification_options	d,r
	}

# Internet: Nildram DNS server definition
define host{
	use			generic-host
	host_name		Community_DNS
	alias			Nildram DNS
	address			195.72.171.39
        parents			ISP_Router
	check_command		check-host-alive
	max_check_attempts	2
	contact_groups		nagios-admins
	notification_interval	120
	notification_period	24x7
	notification_options	d,r
	}

# Network Hub host definition
define host{
	use			dummy-host
	host_name		Net_ICK1_Hub
	alias			Ickford1 Hub
	parents			NMS
	}

# NMS host definition
define host{
	use			generic-host
	host_name		NMS
	alias			Network Manager PC (NMS)
	address			10.0.0.2
	check_command		check-host-alive
	max_check_attempts	1
	contact_groups		nagios-admins
	notification_interval	120
	notification_period	24x7
	notification_options	d,r
	}

# UPS Management Card host definition
define host{
	use			generic-host
	host_name		Net_UPS4
	alias			Ickford1 UPS-4
	address			10.0.0.46
	parents			Net_ICK1_Hub
	check_command		check-host-alive
	max_check_attempts	1
	contact_groups			nagios-admins
	notification_interval	120
	notification_period	24x7
	notification_options	d,r
	}

# UPS Management Card host definition
define host{
	use			generic-host
	host_name		Net_UPS5
	alias			Ickford bearcave UPS-5
	address			10.0.0.44
	parents			CPE_Bruin
	check_command		check-host-alive
	max_check_attempts	1
	contact_groups			nagios-admins
	notification_interval	120
	notification_period	24x7
	notification_options	d,r
	register		0
	}

# Gemini radio host definition
define host{
	use			generic-host
	host_name		Net_WRM-ICK2
	alias			Gemini-Slave
	address			10.0.0.5
	parents			Net_ICK2-WRM
	check_command		check-host-alive
	max_check_attempts	3
	contact_groups			nagios-admins
	notification_interval	120
	notification_period	24x7
	notification_options	d,u,r
	}

# Gemini radio host definition
define host{
	use			generic-host
	host_name		Net_ICK2-WRM
	alias			Gemini-Master
	address			10.0.0.4
	parents			Net_ICK2_Hub
	check_command		check-host-alive
	max_check_attempts	3
	contact_groups			nagios-admins
	notification_interval	120
	notification_period	24x7
	notification_options	d,u,r
	}

# Cyclone host definition
define host{
	use			generic-host
	host_name		Net_Cyclone
	alias			Cyclone C1000 Router
	address			10.0.0.1
	parents			Net_ICK1_Hub
	check_command		check-host-alive
	max_check_attempts	3
	contact_groups			nagios-admins
	notification_interval	60
	notification_period	24x7
	notification_options	d,u,r
	}

# Trango radio host definition
define host{
	use			generic-host
	host_name		Net_WRM-WRN
	alias			Trango-Master
	address			10.0.0.6
	parents			Net_ICK1_Hub
	check_command		check-host-alive
	max_check_attempts	3
	contact_groups		nagios-admins
	notification_interval	120
	notification_period	24x7
	notification_options	d,u,r
	}

# Trango radio host definition
define host{
	use			generic-host
	host_name		Net_WRN-WRM
	alias			Trango-Slave
	address			10.0.0.7
	parents			Net_WRM-WRN
#	check_command		check-host-alive
	check_command		check_nil
	max_check_attempts	3
	contact_groups		nagios-admins
	notification_interval	120
	notification_period	24x7
	notification_options	d,u,r
	}

# Ad-hoc ICMP device host definition
define host{
	use			generic-host
	host_name		Net_ICK2_Power
	alias			Ickford 2 Site Power Monitor
	address			10.0.0.45
	parents			Net_ICK2_Hub
	check_command		check-host-alive
	max_check_attempts	2
	contact_groups		nagios-admins
	notification_interval	60
	notification_period	24x7
	notification_options	d,r
	}

# Ad-hoc ICMP device host definition
define host{
	use			generic-host
	host_name		Net_WRN_Power
	alias			Wornal Site Power Monitor
	address			10.0.0.40
	parents			Net_WRN_Hub
	check_command		check-host-alive
	max_check_attempts	2
	contact_groups		nagios-admins
	notification_interval	60
	notification_period	24x7
	notification_options	d,r
	register		0
	}

###########################################################################
#
# AP DEFINITIONS
#

###########################################################################
#
# Network Hub host definition
define host{
	use			dummy-host
	host_name		Net_ICK2_Hub
	alias			ICK2 Hub
	parents			APIckford2
	}

# AP host definition
define host{
	use			ap-host
	host_name		APIckford2
	alias			Ickford #2
	address			10.0.0.14
	parents			Ant_ICK1-ICK2
	}

# APIckford2 Antenna host definition
define host{
        use                     dummy-host
        host_name               Ant_ICK2-ICK1
        alias                   ICK2-ICK1
	address			10.0.0.14
        parents                 APIckford2
        }

###########################################################################
#
# AP host definition
define host{
	use			generic-host
	host_name		Net_ICK1-ICK2
	alias			ICK1-ICK2
	address			10.0.0.9
	parents			APIckford2
	check_command		check-host-alive
	max_check_attempts	2
	contact_groups			nagios-admins
	notification_interval	120
	notification_period	24x7
	notification_options	d,u,r
	register		0
	}

###########################################################################
#
# AP host definition
define host{
	use			ap-host
	host_name		APIckford1
	alias			Ickford #1
	address			10.0.0.13
	parents			Net_ICK1_Hub
	}

# APIckford1 Antenna host definition
define host{
        use                     dummy-host
        host_name               Ant_ICK1-AP
        alias                   ICK2-AP
	address			10.0.0.13
        parents                 APIckford1
        }

# APIckford1 Antenna host definition
define host{
        use                     dummy-host
        host_name               Ant_ICK1-ICK2
        alias                   ICK1-ICK2
	address			10.0.0.13
        parents                 APIckford1
        }

###########################################################################
#
# CPE DEFINITIONS
#
# CPE host definition
define host{
	use			cpe-host
	host_name		CPE_xxxx
	alias			(redacted)
	address			10.0.0.50
	parents			Ant_ICK1-AP
	}

###########################################################################

Script: nagiosnotify.pl

There's a bug somewhere in here to do with the difference between hosts and services but it was never annoying enough to track down.

You will see it formats the nagios alert and then adds some log entries and then creates an RSS entry for the alarm feed.

Example misccommands.cfg:

# 'email' command definition
define command{
	command_name	email
	command_line	/usr/local/nagios/bin/nagiosnotify.pl -h "$HOSTNAME$" -m "$CONTACTEMAIL$" -n "$CONTACTNAME$" -a "$HOSTADDRESS$" -t $NOTIFICATIONTYPE$ -h $HOSTNAME$ -o "$HOSTOUTPUT$" -d "$SERVICEDESC$" -s "$HOSTSTATE$" -w "$LONGDATETIME$"
	}

Perl code:

#!/usr/bin/perl -w
use strict;
use Getopt::Long;
use Mail::Sendmail;
use XML::RSS;

=head1 SYNOPSIS

nagiosnotify.pl -h $HOSTNAME$ -m "$CONTACTEMAIL$" -n "$CONTACTNAME$" -a $HOSTADDRESS$ //
                -t "$NOTIFICATIONTYPE$" -h "$HOSTNAME$" -o $HOSTOUTPUT$ //
                -d "$SERVICEDESC$" -s $HOSTSTATE$ -w $LONGDATETIME$

=head1 DESCRIPTION
                                                                                
Nagios notify script.  Uses SENDMAIL to send an e-mail and the
RSS library to add an item to the RSS feed.

=head1 AUTHOR

Nigel Bruin 2006

=cut

###############################################################################
#
# Constants & variables

# Fixed TO: and FROM: e-mail addresses
my $to   = 'WISP Network ';
my $from = 'Nagios Server ';

# Path to external command "tail"
my $cmd_tail     = '/usr/bin/tail';

# Filenames for logs files
my $fn_syslogs   = '/var/log/system.log';
my $fn_nagioslog = '/usr/local/nagios/var/nagios.log';

# Filename for RSS feed
my $fn_rss   = '/Library/WebServer/rss/nagios.rdf';
my $size_rss = 30;

# Link to NMS
my $urlNMSint = 'http://10.0.0.2/cgi-bin/nms.cgi';
#my $urlNMSext = 'http://84.12.108.100/cgi-bin/nms.cgi';
my $urlNMSext = 'http://195.72.186.183/cgi-bin/nms.cgi';
my $urlRSS    = 'http://10.0.0.2/rss/nagios.rdf';

my $sep = '- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -';

my ($hostname, $hostaddress, $datetime, $contactemail, $notificationtype, 
    $servicedesc, $servicestate, $servicecomment, $serviceoutput );

###############################################################################
#
# Main routine

# notify -m "$CONTACTEMAIL$" -p "$CONTACTPAGER$" -u "$CONTACTNAME$" -t "$NOTIFICATIONTYPE$" HOSTNAME="$HOSTNAME$" SERVICEDESC="$SERVICEDESC$"
GetOptions("h=s" => \$hostname,
           "a=s" => \$hostaddress,
           "w=s" => \$datetime,
           "m=s" => \$contactemail,
           "t=s" => \$notificationtype,
           "d=s" => \$servicedesc,
           "s=s" => \$servicestate,
           "c=s" => \$servicecomment,
           "o=s" => \$serviceoutput,
           );

# Enforce suitable parameter defaults to avoid script crashes
if(!$hostname        ) { $hostname         = '?'   };
if(!$hostaddress     ) { $hostaddress      = '?'   };
if(!$datetime        ) { $datetime         = '?'   };
if(!$contactemail    ) { $contactemail     = '?'   };
if(!$notificationtype) { $notificationtype = '?'   };
if(!$servicedesc     ) { $servicedesc      = ''    };
if(!$servicestate    ) { $servicestate     = 'n/a' };
if(!$servicecomment  ) { $servicecomment   = 'n/a' };
if(!$serviceoutput   ) { $serviceoutput    = 'n/a' };

###############################################################################
#
# Wisp Broadband Nagios notification script.
#
#### Form up Body Text

# Nagios event details
my $problemdesc = "$datetime  |  Notification Type: $notificationtype\n\n";
if ($servicedesc ne '')
  { $problemdesc .= "Service: $servicedesc  |  " };
$problemdesc .= "Host: $hostname  |  IP Address: $hostaddress  |  State: $servicestate\n\n";
  
my $body = $problemdesc;
if ($notificationtype eq 'ACKNOWLEDGEMENT')
  { $body .= "Comment: $servicecomment\n\n" }
else 
  { $body .= "Output: $serviceoutput\n\n" };

# Useful links
$body .= "NMS (int): $urlNMSint\nNMS: (ext): $urlNMSext\nRSS: $urlRSS\n$sep\n";

# System logs
my $syslogs    = `$cmd_tail -n 10 $fn_syslogs`;
$body .= "Last few System logs:\n\n$syslogs\n"; 

# Nagios logs
my $nagioslogs = `$cmd_tail -n 10 $fn_nagioslog`;
# Convert log timestamps from UTC to a readbable format
# e.g.:  [Sat Dec 31 10:00:48 2005]
$nagioslogs =~ s/\[(\d+)\]/"[".localtime($1)."]"/eg;
    
# Use this to delete just the year:
#$nagioslogs =~ s/\[(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)]/$1 $2 $3 $4/g;
        
#Use this to delete day, date and year, leaving just the time:
$nagioslogs =~ s/\[(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)]/$4/g;
$body .= "$sep\nLast few Nagios logs:\n\n$nagioslogs\n$sep\n";

$body .= "$0\nNigel Bruin 2006\n";

#### Form up Subject:     
my $subject = "$notificationtype alert: $hostname";
if ($servicedesc ne '')
  { $subject .= '('.$servicedesc.')' };
$subject .= ' is '.$servicestate;

###############################################################################
# Send e-mail
my %mail = ( To      => $to,
             From    => $from,
             Subject => 'WISP Alarm: '.$subject,
             Message => $body
           );
sendmail(%mail);

###############################################################################
# Write a new item to the RSS feed 
my $rss = new XML::RSS (version  => '0.91', 
                        encoding => 'ISO-8859-1'
                       );

$rss->parsefile($fn_rss);
pop(@{$rss->{'items'}}) if (@{$rss->{'items'}} == $size_rss);
$rss->add_item(title => $subject,
               link  => $urlNMSint,
               mode  => 'insert',
               description => $problemdesc
               );
                    
$rss->save($fn_rss);

exit;