summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xcontrib/check_traceroute.pl210
1 files changed, 210 insertions, 0 deletions
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 @@
1#!/usr/bin/perl
2
3# $Id$
4
5# $Log$
6# Revision 1.1 2005/01/27 10:34:16 stanleyhopcroft
7# Jon Meek's check_traceroute for Mon hacked by YT for Nagios. Prob pretty weak
8#
9
10use strict ;
11
12use vars qw(%ERRORS $TIMEOUT) ;
13use utils qw(%ERRORS $TIMEOUT &print_revision &support &usage) ;
14
15sub print_help ();
16sub print_usage ();
17
18$ENV{'PATH'}='/bin:/usr/bin:/usr/sbin';
19
20my $PROGNAME = 'check_traceroute' ;
21 # delay units are millisecs.
22my $MAX_INTERHOP_DELAY = 200 ;
23my $MAX_HOPS = 30 ;
24
25use Getopt::Std;
26
27use vars qw($opt_H $opt_N $opt_r $opt_R $opt_T $opt_d $opt_h $opt_i $opt_v $opt_V) ;
28
29getopts('i:H:N:R:T:dhrvV');
30 # H, N, R, T, and i take parms, others are flags
31
32do { print_help ; exit $ERRORS{OK}; }
33 if $opt_h ;
34
35do { print_revision($PROGNAME, '$Revision$'); exit $ERRORS{OK}; }
36 if $opt_V ;
37
38do { print_help; exit $ERRORS{OK}; }
39 unless $opt_R || $opt_r ;
40
41do { print_help; exit $ERRORS{OK}; }
42 unless $opt_R =~ m|
43 (?:\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}-)+
44 \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}
45 |x
46 || $opt_r ;
47
48my $should_be = $opt_R ;
49 # Set default timeout in seconds
50my $TimeOut = $opt_T || $TIMEOUT;
51
52my $max_interhop_delay = $opt_i || $MAX_INTERHOP_DELAY ;
53my $max_hops = $opt_N || $MAX_HOPS ;
54
55my $TRACEROUTE = '/usr/sbin/traceroute';
56
57my $TargetHost = $opt_H ;
58
59print_help
60 unless $TargetHost ;
61
62my ($route, $pid, $rta_list) = ( '', '', '' );
63my %ResultString = () ;
64
65$SIG{ALRM} = sub { die "timeout" };
66
67eval {
68
69 alarm($TimeOut);
70 # XXXX Discarding STDERR _should_ reduce the risk
71 # of unexpected output but consequently, results for
72 # non existent hosts are stupid. However, why would you
73 # specify a route to a NX host, other than a typo ...
74
75 $pid = open(TR, "$TRACEROUTE -n $TargetHost 2>/dev/null |")
76 or do {
77 "Failed. Cannot fork \"$TRACEROUTE\": $!" ;
78 $ERRORS{UNKNOWN} ;
79 } ;
80
81 my $hops = 0 ;
82 while (<TR>) {
83
84 print $_
85 if $opt_d;
86
87 if ( m|#\*\s+\*\s+\*| ) {
88 # Get * * * then give up
89 $route .= '*';
90 # 13 = PIPE, prevents Broken Pipe Error, at least on Solaris
91 kill 13, $pid;
92 last;
93 }
94 # We will only pick up the first IP address listed on a line for now
95 # traceroute to csg.citec.com.au (203.9.184.12), 64 hops max, 44 byte packets
96 # 1 10.254.254.254 0.868 ms 0.728 ms 0.705 ms
97 # 2 192.168.9.1 1.240 ms 1.165 ms 1.191 ms
98
99 my ($ThisHopIP) = m|\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+|;
100 my ($max_rta) = m|\d{1,3}\.\d{1,3}\.\d{1,3}\s+ (\d+\.\d+) ms| ;
101
102 $route .= $ThisHopIP . '-';
103 $rta_list .= sprintf("%.1f", $max_rta) . '-' ;
104
105 if ( $opt_v ) {
106 chomp $_ ;
107 print $_, ' ' x (58 - length), $route, "\n";
108 }
109
110 $hops++ ;
111
112 if ( ($hops >= $max_hops) && ! $opt_r ) {
113 kill 13, $pid ;
114 print qq(Failed. Max hops ($max_hops) exceeeded: incomplete after $hops hops, "$route".\n) ;
115 exit $ERRORS{CRITICAL} ;
116 }
117 if ( ($hops %2 == 0) && ($hops >= 4) && ! $opt_r ) {
118
119 # Check for 2 cycles at end of path ie -(a-b)-(a-b)$
120 # where a and b are IP v4 addresses of IS (routers).
121
122 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})-$/ ;
123 if ( $route =~ /$last_2_is-$last_2_is-$/ ) {
124 kill 13, $pid ;
125 print qq(Failed. Last 2 routers ($last_2_is) repeated, "$route".\n) ;
126 exit $ERRORS{CRITICAL} ;
127 }
128
129 }
130
131 }
132};
133
134alarm(0);
135
136if ( $@ and $@ =~ /timeout/ ) {
137 $route .= '*';
138 # It was a traceroute timeout
139 kill 13, $pid;
140} elsif ( $@ and $@ !~ /timeout/ ) {
141 close TR ;
142 print "Failed. Somethings gone wrong with \"$TRACEROUTE\": $!" ;
143 exit $ERRORS{UNKNOWN} ;
144}
145
146close TR;
147 # Remove trailing '-'s
148# $route =~ s/\-$//;
149chop($route) ;
150chop($rta_list) ;
151
152print "$route\n"
153 if $opt_d;
154
155if ( $opt_r ) {
156 print qq(Ok. Traceroute to host "$TargetHost" via route "$route".\n) ;
157 exit $ERRORS{OK};
158}
159
160if ( &RouteEqual($should_be, $route) ) {
161 print qq(Ok. Traceroute to "$TargetHost" via expected route "$route" ($rta_list).\n) ;
162 exit $ERRORS{OK};
163} else {
164 print qq(Failed. Route "$route" ne expected "$should_be".\n) ;
165 exit $ERRORS{CRITICAL};
166}
167
168
169sub RouteEqual {
170 my ($current_route, $prev_route) = @_;
171 return $current_route eq $prev_route ;
172}
173
174sub print_usage () {
175 print "Usage: $PROGNAME [ -R <route_string>|-r ] [ -d -T timeout -v -h -i ] -H <host>\n";
176}
177
178sub print_help () {
179 print_revision($PROGNAME, '$Revision$') ;
180 print "Copyright (c) 2004 J Meek/Karl DeBisschop
181
182This plugin checks whether traceroute to the destination succeeds and if so that the route string option (-R) matches the list of routers
183returned by traceroute.
184
185";
186print_usage();
187 print "
188-d
189 Debug
190-h
191 Help
192-i
193 _TODO_
194 Max inter-hop delay (msec).
195-H
196 Host.
197-N
198 Max number of hops.
199-r
200 Record current route (and output to STDOUT). Useful for getting the value of -R option ...
201-v
202 Greater verbosity.
203-R
204 Mandatory route string ie r1-r2-... where ri is the ip address of the ith router.
205-T
206 Maximum time (seconds) to wait for the traceroute command to complete. Defaults to $TIMEOUT seconds.
207
208";
209 support();
210}