#!/usr/local/bin/perl -w use strict; use Net::SNMP; use Getopt::Long; my $Version='0.2'; use lib "/usr/local/nagios/libexec"; my $TIMEOUT=10; my %ERRORS=('OK'=>0,'WARNING'=>1,'CRITICAL'=>2,'UNKNOWN'=>3,'DEPENDENT'=>4); my $o_host = undef; # hostname my $o_community = undef; # community my $o_version2 =undef; # Version 2 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_timeout= undef; # Default 5s Timeout my $o_warn= undef; # Warning for connections my $o_crit= undef; # Crit for connections my $o_svn= undef; # Check for SVN status my $o_fw= undef; # Check for FW status my $o_ha= undef; # Check for HA status my $o_mgmt= undef; # Check for management status my $o_policy= undef; # Check for policy name my $o_conn= undef; # Check for connexions my $o_perf= undef; # Performance data output # SNMPv3 specific my $o_login= undef; # Login for snmpv3 my $o_passwd= undef; # Pass for snmpv3 my $v3protocols=undef; # V3 protocol list. my $o_authproto='md5'; # Auth protocol my $o_privproto='des'; # Priv protocol my $o_privpass= undef; # priv password # functions sub p_version { print "check_tunnel.pl version : $Version\n"; } sub print_usage { print "Usage: $0 [-v] -H -C [-2] | (-l login -x passwd [-X pass -L ,]) [-p ] [-t ] [-V]\n"; } sub isnnum { # Return true if arg is not a number my $num = shift; if ( $num =~ /^(\d+\.?\d*)|(^\.\d+)$/ ) { return 0 ;} return 1; } sub help { print "\nSNMP Checkpoint FW-1 Tunnel Monitor for Nagios version ",$Version,"\n"; print_usage(); print <, : Authentication protocol (md5|sha : default md5) : Priv protocole (des|aes : default des) -p, --port=PORT SNMP port (Default 161) -t, --timeout=INTEGER timeout for SNMP (Default: Nagios default) -V, --version prints version number EOT } # For verbose output sub verb { my $t=shift; print $t,"\n" if defined($o_verb) ; } sub check_options { Getopt::Long::Configure ("bundling"); GetOptions( 'v' => \$o_verb, 'verbose' => \$o_verb, 'h' => \$o_help, 'help' => \$o_help, '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, 'l:s' => \$o_login, 'login:s' => \$o_login, 'x:s' => \$o_passwd, 'passwd:s' => \$o_passwd, 'X:s' => \$o_privpass, 'privpass:s' => \$o_privpass, 'L:s' => \$v3protocols, 'protocols:s' => \$v3protocols, 't:i' => \$o_timeout, 'timeout:i' => \$o_timeout, 'V' => \$o_version, 'version' => \$o_version, ); if (defined ($o_help) ) { 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"}} if (defined ($v3protocols)) { if (!defined($o_login)) { print "Put snmp V3 login info with protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} my @v3proto=split(/,/,$v3protocols); if ((defined ($v3proto[0])) && ($v3proto[0] ne "")) {$o_authproto=$v3proto[0]; } # Auth protocol if (defined ($v3proto[1])) {$o_privproto=$v3proto[1]; } # Priv protocol if ((defined ($v3proto[1])) && (!defined($o_privpass))) { print "Put snmp V3 priv login info with priv protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} } } ########## MAIN ####### check_options(); # Check gobal timeout if snmp screws up if (defined($o_timeout)) { verb("Alarm at $o_timeout +2sec"); alarm($o_timeout+2); } else { verb("timeout not defined : $TIMEOUT +2sec"); alarm ($TIMEOUT+2); } $SIG{'ALRM'} = sub { print "No answer from host\n"; exit $ERRORS{"UNKNOWN"}; }; # Connect to host my ($session,$error); if ( defined($o_login) && defined($o_passwd)) { # SNMPv3 login verb("SNMPv3 login"); if (!defined ($o_privpass)) { verb("SNMPv3 AuthNoPriv login : $o_login, $o_authproto"); ($session, $error) = Net::SNMP->session( -hostname => $o_host, -version => '3', -username => $o_login, -port => $o_port, -authpassword => $o_passwd, -authprotocol => $o_authproto, -timeout => $o_timeout ); } else { verb("SNMPv3 AuthPriv login : $o_login, $o_authproto, $o_privproto"); ($session, $error) = Net::SNMP->session( -hostname => $o_host, -version => '3', -username => $o_login, -port => $o_port, -authpassword => $o_passwd, -authprotocol => $o_authproto, -privpassword => $o_privpass, -privprotocol => $o_privproto, -timeout => $o_timeout ); } } else { if (defined ($o_version2)) { # SNMPv2 Login verb("SNMP v2c login"); ($session, $error) = Net::SNMP->session( -hostname => $o_host, -version => 2, -community => $o_community, -port => $o_port, -timeout => $o_timeout ); } else { # SNMPV1 login verb("SNMP v1 login"); ($session, $error) = Net::SNMP->session( -hostname => $o_host, -community => $o_community, -port => $o_port, -timeout => $o_timeout || '5', -retries => '2' ); verb("Login to $o_host, port $o_port with Comm $o_community"); } } if (!defined($session)) { printf("ERROR opening session: %s.\n", $error); exit $ERRORS{"UNKNOWN"}; } else { verb ("SNMP Session opened successfully."); } ########### Global checks ################# my ($resultat,$key)=(undef,undef); my $ES=0; my $peerIP="1.1.1.1"; my $numTunnels=0; my $numTunnelsBad=0; my $numTunnelsGood=0; my $tunnelName=""; my $tunnelStatus=""; my $tunnelCommunity=""; my $tunnelStatusLong=""; my $LINE1=""; my $LINE2=""; my $LINE3=""; my $ops="green"; my $term="normal"; my $previous="1.2.3.4"; my $OID="1.3.6.1.4.1.2620.500.9002.1.1"; my $OID1="1.3.6.1.2.1.1.5.0"; my $OID2="1.3.6.1.2.1.1.3.0"; my $OID3="1.3.6.1.4.1.2620.500.9002.1.1"; my @OID_all=($OID, $OID1); while ( $ops =~ /green/ ) { $resultat = $session->get_next_request( Varbindlist => \@OID_all ); if (!defined($resultat) ) { if ( $numTunnels == 0 ) { verb ("No tunnels found!"); print "No tunnels configured"; exit 1 } verb("shit no SNMP $session->error"); print "Table $OID not found. Check CP SNMP agent!"; exit 2; } my @names = $session->var_bind_names; if ( $names[0] =~ /1.3.6.1.4.1.2620.500.9002.1.2/ ) { $ops="done"; } $peerIP=$$resultat{$names[0]}; verb ("___________________________________________________________\nNext IP is $peerIP (source is OID $names[0]"); if ( $peerIP =~ /^0$/ ) { $ops="done"; } if ($ops eq "green") { # get tunnel status and details verb ("obtaining tunnel details..."); $numTunnels++; if ( $numTunnels > 100 ) { # probably somthing is wrong!! e.g. SNMP loop? $ops="red"; verb("ATTENTION: max number tunnels exceeded!"); $term="max_tunnel_reached"; } $OID1="1.3.6.1.4.1.2620.500.9002.1.2.${peerIP}.0"; $OID2="1.3.6.1.4.1.2620.500.9002.1.3.${peerIP}.0"; $OID3="1.3.6.1.4.1.2620.500.9002.1.4.${peerIP}.0"; @OID_all=($OID1,$OID2,$OID3); verb ("checking OIDs:\n T_Name $OID1\n T_Stat $OID2\n T_Comm $OID3"); $resultat = $session->get_request( Varbindlist => \@OID_all ); if (!defined($resultat) ) { verb ("SNMP keine ahnung"); } #$error=$session->error; #verb ("SNMP error: $error"); $tunnelName=$$resultat{$OID1}; if (! defined($tunnelName) ) { $tunnelName="no name"; } $tunnelStatus=$$resultat{$OID2}; if (! defined($tunnelStatus) ) { $tunnelStatus="-1"; } $tunnelCommunity=$$resultat{$OID3}; if (! defined($tunnelCommunity) ) { $tunnelCommunity="no community"; } if ( length($tunnelCommunity) < 2) { $tunnelCommunity = "T:" . $tunnelName; } verb("Tunnel $tunnelName in status $tunnelStatus, Comm: $tunnelCommunity|"); if ( $tunnelStatus == 3) { $tunnelStatusLong="active"; } if ( $tunnelStatus == 4) { $tunnelStatusLong="destroy"; } if ( $tunnelStatus == 129) { $tunnelStatusLong="idle"; } if ( $tunnelStatus == 130) { $tunnelStatusLong="phase1"; } if ( $tunnelStatus == 131) { $tunnelStatusLong="down"; } if ( $tunnelStatus == 132) { $tunnelStatusLong="init"; } if ( ($tunnelStatus ne 3) && ($tunnelStatus ne 130) ) { $LINE1=$LINE1." Tunnel ".$tunnelCommunity." (".$tunnelName.") is ".$tunnelStatusLong; $numTunnelsBad++; $ES=2; $term="tunnel_down"; verb ("Bad tunnel: $tunnelCommunity, $tunnelName, $tunnelStatusLong"); } else { $LINE2=$LINE2." ". $tunnelCommunity .","; $numTunnelsGood++; verb ("Good Tunnnel: $tunnelCommunity, $tunnelName, $tunnelStatusLong"); } verb ("Tunnel Count: good/bad $numTunnelsGood / $numTunnelsBad "); verb ("LINE1 (bad) = $LINE1"); verb ("LINE2 (good) = $LINE2"); # prepare for next run $OID="1.3.6.1.4.1.2620.500.9002.1.1.$peerIP.0"; @OID_all=($OID); if ($previous eq $peerIP) { $ops="red"; verb("ATTENTION: SNMP loop detected!"); $term="SNMP_loop_detected"; } $previous=$peerIP; # sleep 1; } } # while $session->close; verb ("Closing SNMP session"); ########## print results and exit if ( $LINE1 eq "" ) { $LINE1=$LINE2; } # somethings was wrong: e.g. max number reached? or loop? flag as warning # if ( $ops ne "done" ) { $ES=1; } if ($numTunnels == 0) { $ES=1; } # truncate lengthy output verb("Full output: $LINE1"); $OID=length($LINE1); # if ($OID > 180) { $LINE1=substr($LINE1,1,177) . "..."; } print "$LINE3$numTunnelsGood/$numTunnels tunnels active:$LINE1|Tunnels=$numTunnels; Termination=$term\n"; exit $ES;