#!/usr/bin/perl use POSIX; use strict; use lib "/usr/local/nagios/libexec"; use utils qw($TIMEOUT %ERRORS &print_revision &support); use Getopt::Long; &Getopt::Long::config('bundling'); use SNMP::Info; my $PROGNAME = "check_cdpneighbour"; my $Version='1.0'; my $timeout; my $status; my $state = "UNKNOWN"; my $answer = ""; my $o_community = "public"; my $o_host; my $o_port = 161; # port my $o_help= undef; # wan't some help ? my $o_verb= undef; # verbose mode my $o_version= undef; # print version my $o_version2 =undef; # Version 2 my $o_login= undef; # Login for snmpv3 my $o_passwd= undef; # Pass for snmpv3 my $o_timeout= 5; # Default 5s Timeout my $o_debug=0; my $o_neigh=undef; # Neighbour name my $o_neighint=undef; # Neighbourg interface my $o_interface=undef; # Local interface to see the neighbour on my $o_cneigh=undef; my $o_nodomain=undef; sub p_version { print "$PROGNAME version : $Version\n"; } sub print_help { print "\nSNMP CDP/FDP Monitor for Nagios version ",$Version,"\n"; print "(c)2009 - Sebastien Barbereau\n\n"; print "This plugins checks for the existence of a specific neighbour for a networking device by looking up the CDP or FDP table.\n"; print "Requires : libsnmp-info from http://snmp-info.sourceforge.net/\n"; print "Requires : SNMP mib file being located in proper directories"; print_usage(); print < -C [-2] [-p ] [-t ] [-V] [--nodomain] [-n | -c \$o_verb, 'verbose' => \$o_verb, 'h' => \$o_help, 'help' => \$o_help, 'd' => \$o_debug, 'debug' => \$o_debug, 'H:s' => \$o_host, 'hostname:s' => \$o_host, 'P:i' => \$o_port, 'port:i' => \$o_port, 'C:s' => \$o_community, 'community:s' => \$o_community, '2' => \$o_version2, 'v2c' => \$o_version2, 't:i' => \$o_timeout, 'timeout:i' => \$o_timeout, 'V' => \$o_version, 'version' => \$o_version, 'nodomain' => \$o_nodomain, 'n:s' => \$o_neigh, 'neighbour:s' => \$o_neigh, 'i:s' => \$o_neighint, 'interface:s' => \$o_neighint, 'c:i' => \$o_cneigh, 'count:i' => \$o_cneigh, 'l' => \$o_interface, 'perfparse' => \$o_interface ); if (defined ($o_help) ) { print_help(); exit $ERRORS{"UNKNOWN"}}; if (defined($o_version)) { p_version(); exit $ERRORS{"UNKNOWN"}}; if ( ! defined($o_host) ) # check host and filter { print_usage(); exit $ERRORS{"UNKNOWN"}} # check snmp information if ( !defined($o_community) && (!defined($o_login) || !defined($o_passwd)) ) { print "Put snmp login info!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} if ((defined($o_login) || defined($o_passwd)) && (defined($o_community) || defined($o_version2)) ) { print "Can't mix snmp v1,2c,3 protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} # check options #if ( (!defined($o_neigh))) # check neighbour host if ( (!defined($o_neigh)) && (!defined($o_cneigh))) # check neighbour host { print "missing option.\n";print_usage(); exit $ERRORS{"UNKNOWN"}} $o_neigh = lc($o_neigh); if (defined($o_version2)) { $o_version2=2; } $o_neigh=stripdomain($o_neigh); # if (defined($o_nodomain)) { # verb("Domain stripped, got: $o_neigh"); # } } ################### MAIN ####################### check_options(); # Check gobal timeout if snmp screws up if (defined($TIMEOUT)) { verb("Alarm at $TIMEOUT"); alarm($TIMEOUT); } else { verb("no timeout defined : $o_timeout + 10"); alarm ($o_timeout+10); } if ($o_debug) { print "Debug => $o_debug\n"; print "DestHost => $o_host\n"; print "Community => $o_community\n"; print "Version => $o_version2\n"; print "Looking for => $o_neigh\n" if (defined($o_neigh)); print "Counting for => $o_cneigh\n" if (defined($o_cneigh)); } verb("Connecting to $o_host community $o_community using version $o_version2."); my $device = new SNMP::Info( # Auto Discover more specific Device Class AutoSpecify => 1, Debug => $o_debug, # The rest is passed to SNMP::Session DestHost => $o_host, Community => $o_community, Version => $o_version2 ) or die "Can't connect to device.\n"; my $err = $device->error(); if (defined($err)) { printf("ERROR opening session (SNMP community or version probably wrong): %s.\n", $err); exit $ERRORS{"UNKNOWN"}; } if (not $device->cdp_run()) { printf("ERROR retrieving CDP state (is CDP running)?!\n"); exit $ERRORS{"UNKNOWN"}; } my $name = $device->name(); verb("Device name: $name"); #$x = $device->c_id(); #print "cdp $x\n"; my $c_ip = $device->c_ip(); my $interfaces = $device->interfaces(); my $c_if = $device->c_if(); my $c_port = $device->c_port(); my $c_id = $device->c_id(); $state='CRITICAL'; my $count=0; my $i_id; $o_neigh='XXXXXXXXXXXXXXX' if ( ! defined($o_neigh)); foreach my $cdp_key (keys %$c_ip){ my $iid = $c_if->{$cdp_key}; my $port = $interfaces->{$iid}; my $neighbor = $c_ip->{$cdp_key}; my $neighbor_port = $c_port->{$cdp_key}; my $id = $c_id->{$cdp_key}; $id=lc($id); verb( "Port : $port connected to $neighbor($id) / $neighbor_port "); $count=$count+1; $i_id=stripdomain($id); if ($o_neigh eq $i_id) { $state="OK"; if ($answer ne "") {$answer .= ",";} $answer .= " $name/$port connected to $id/$neighbor_port"; verb("Found $i_id $o_neigh"); } } if (defined($o_cneigh) && ($count==$o_cneigh)) { $answer="Found $count neighbours to $name."; $state="OK"; } if (defined($o_cneigh) && ($count!=$o_cneigh)) { $answer="Found $count from $o_cneigh neighbours to $name."; $state="CRITICAL"; } if ($answer eq "") { $answer="$o_neigh is not a neighbor of $name"; } print $answer."\n"; exit $ERRORS{$state};