From 30d5c198fce3388b5b8a241feae346eee9d876a2 Mon Sep 17 00:00:00 2001
From: Stanley Hopcroft <stanleyhopcroft@users.sourceforge.net>
Date: Thu, 27 Jan 2005 10:34:16 +0000
Subject: Jon Meek's check_traceroute for Mon hacked by YT for Nagios. Prob
 pretty weak

git-svn-id: https://nagiosplug.svn.sourceforge.net/svnroot/nagiosplug/nagiosplug/trunk@1115 f882894a-f735-0410-b71e-b25c423dba1c

diff --git a/contrib/check_traceroute.pl b/contrib/check_traceroute.pl
new file mode 100755
index 0000000..c8d497b
--- /dev/null
+++ b/contrib/check_traceroute.pl
@@ -0,0 +1,210 @@
+#!/usr/bin/perl
+
+# $Id$
+
+# $Log$
+# Revision 1.1  2005/01/27 10:34:16  stanleyhopcroft
+# Jon Meek's check_traceroute for Mon hacked by YT for Nagios. Prob pretty weak
+#
+
+use strict ;
+
+use vars qw(%ERRORS $TIMEOUT) ;
+use utils qw(%ERRORS  $TIMEOUT &print_revision &support &usage) ;
+
+sub print_help ();
+sub print_usage ();
+
+$ENV{'PATH'}='/bin:/usr/bin:/usr/sbin';
+
+my $PROGNAME			= 'check_traceroute' ;
+										# delay units are millisecs.
+my $MAX_INTERHOP_DELAY	= 200 ;
+my $MAX_HOPS 			= 30 ;
+
+use Getopt::Std;
+
+use vars qw($opt_H $opt_N $opt_r $opt_R $opt_T $opt_d $opt_h $opt_i $opt_v $opt_V) ;
+
+getopts('i:H:N:R:T:dhrvV');
+										# H, N, R, T, and i take parms, others are flags
+
+do { print_help ; exit $ERRORS{OK}; }
+	if $opt_h ;
+
+do { print_revision($PROGNAME, '$Revision$'); exit $ERRORS{OK}; }
+	if $opt_V ;
+
+do { print_help; exit $ERRORS{OK}; }
+	unless $opt_R || $opt_r ;
+
+do { print_help; exit $ERRORS{OK}; }
+	unless $opt_R =~	m|
+							(?:\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}-)+
+							\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}
+						|x 
+	|| $opt_r ;
+
+my $should_be		= $opt_R ;
+										# Set default timeout in seconds
+my $TimeOut			= $opt_T || $TIMEOUT;
+
+my $max_interhop_delay	= $opt_i || $MAX_INTERHOP_DELAY ;
+my $max_hops 		= $opt_N || $MAX_HOPS ;
+
+my $TRACEROUTE		= '/usr/sbin/traceroute';
+
+my $TargetHost		= $opt_H ; 
+
+print_help 
+	unless $TargetHost ;
+
+my ($route, $pid, $rta_list) = ( '', '', '' );
+my %ResultString = () ;
+ 
+$SIG{ALRM} = sub { die "timeout" };
+
+eval {
+
+	alarm($TimeOut);
+										# XXXX Discarding STDERR _should_ reduce the risk
+										# of unexpected output but consequently, results for
+										# non existent hosts are stupid. However, why would you
+										# specify a route to a NX host, other than a typo ...
+
+	$pid = open(TR, "$TRACEROUTE -n $TargetHost 2>/dev/null |") 
+		or do	{
+					 "Failed. Cannot fork \"$TRACEROUTE\": $!" ;
+					 $ERRORS{UNKNOWN} ;
+				} ;
+
+	my $hops = 0 ;
+	while (<TR>) {
+
+		print $_
+			if $opt_d;
+
+		if ( m|#\*\s+\*\s+\*| ) {
+										# Get * * * then give up
+			$route .= '*';
+										# 13 = PIPE, prevents Broken Pipe Error, at least on Solaris
+			kill 13, $pid;
+			last;
+		}
+										# We will only pick up the first IP address listed on a line for now
+										# traceroute to csg.citec.com.au (203.9.184.12), 64 hops max, 44 byte packets
+										# 1  10.254.254.254  0.868 ms  0.728 ms  0.705 ms
+										# 2  192.168.9.1  1.240 ms  1.165 ms  1.191 ms
+
+		my ($ThisHopIP) = m|\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+|;
+		my ($max_rta)	= m|\d{1,3}\.\d{1,3}\.\d{1,3}\s+ (\d+\.\d+) ms| ; 
+
+		$route		.= $ThisHopIP . '-';
+		$rta_list	.= sprintf("%.1f", $max_rta) . '-' ; 
+
+		if ( $opt_v ) {
+			chomp $_ ;
+			print $_, ' ' x (58 - length), $route, "\n";
+		}
+
+		$hops++ ;
+
+		if ( ($hops >= $max_hops) && ! $opt_r ) {
+				kill 13, $pid ;
+				print qq(Failed. Max hops ($max_hops) exceeeded: incomplete after $hops hops, "$route".\n) ;
+				exit $ERRORS{CRITICAL} ;
+		}
+		if ( ($hops %2 == 0) && ($hops >= 4)  && ! $opt_r ) {
+
+										# Check for 2 cycles at end of path ie -(a-b)-(a-b)$
+										# where a and b are IP v4 addresses of IS (routers).
+
+			my ($last_2_is) = $route =~ /(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}-\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})-$/ ;
+			if ( $route =~ /$last_2_is-$last_2_is-$/ ) {
+				kill 13, $pid ;
+				print qq(Failed. Last 2 routers ($last_2_is) repeated, "$route".\n) ;
+				exit $ERRORS{CRITICAL} ;
+			}
+
+		} 
+
+	}
+};
+
+alarm(0);
+
+if ( $@ and $@ =~ /timeout/ ) {
+		$route .= '*';
+										# It was a traceroute timeout
+		kill 13, $pid;
+} elsif ( $@ and $@ !~ /timeout/ ) {
+		close TR ;
+		print "Failed. Somethings gone wrong with \"$TRACEROUTE\": $!" ;
+		exit $ERRORS{UNKNOWN} ;
+}
+
+close TR;
+										# Remove trailing '-'s
+# $route =~ s/\-$//;
+chop($route) ;
+chop($rta_list) ;
+
+print "$route\n"
+	if $opt_d;
+
+if ( $opt_r ) {
+	print qq(Ok. Traceroute to host "$TargetHost" via route "$route".\n) ;
+	exit $ERRORS{OK};
+}
+
+if ( &RouteEqual($should_be, $route) ) {
+	print qq(Ok. Traceroute to "$TargetHost" via expected route "$route" ($rta_list).\n) ;
+	exit $ERRORS{OK};
+} else {
+	print qq(Failed. Route "$route" ne expected "$should_be".\n) ;
+	exit $ERRORS{CRITICAL};
+}
+
+
+sub RouteEqual {
+	my ($current_route, $prev_route) = @_;
+	return $current_route eq $prev_route ; 
+}
+
+sub print_usage () {
+	print "Usage: $PROGNAME [ -R <route_string>|-r ] [ -d  -T timeout -v -h -i ] -H <host>\n";
+}
+
+sub print_help () {
+	print_revision($PROGNAME, '$Revision$') ;
+	print "Copyright (c) 2004 J Meek/Karl DeBisschop
+
+This plugin checks whether traceroute to the destination succeeds and if so that the route string option (-R) matches the list of routers
+returned by traceroute.
+
+";
+print_usage();
+	print "
+-d
+   Debug
+-h
+   Help
+-i
+   _TODO_
+   Max inter-hop delay (msec).
+-H
+   Host.
+-N
+   Max number of hops.
+-r
+   Record current route (and output to STDOUT). Useful for getting the value of -R option ...
+-v
+   Greater verbosity.
+-R
+   Mandatory route string ie r1-r2-... where ri is the ip address of the ith router.
+-T
+   Maximum time (seconds) to wait for the traceroute command to complete. Defaults to $TIMEOUT seconds.
+
+";
+	support();
+}
-- 
cgit v0.10-9-g596f

