diff options
| -rwxr-xr-x | contrib/check_lotus.pl | 261 |
1 files changed, 261 insertions, 0 deletions
diff --git a/contrib/check_lotus.pl b/contrib/check_lotus.pl new file mode 100755 index 00000000..c94e6c2d --- /dev/null +++ b/contrib/check_lotus.pl | |||
| @@ -0,0 +1,261 @@ | |||
| 1 | #!/usr/bin/perl -w | ||
| 2 | |||
| 3 | # $Id$ | ||
| 4 | |||
| 5 | # $Log$ | ||
| 6 | # Revision 1.1 2005/01/25 09:04:26 stanleyhopcroft | ||
| 7 | # New plugin to check responsiveness of Louts Notes (v5 at least) servers | ||
| 8 | # | ||
| 9 | # Revision 1.10 2005-01-25 15:44:07+11 anwsmh | ||
| 10 | # 1 use packet_utils instead of hard coding subroutines (pdump and tethereal) | ||
| 11 | # 2 redo indentation using tabs (set at 4 spaces) | ||
| 12 | # | ||
| 13 | |||
| 14 | use strict ; | ||
| 15 | |||
| 16 | use IO::Socket; | ||
| 17 | use Getopt::Long ; | ||
| 18 | |||
| 19 | my ($timeout, $debug, $lotus_host, $server, $indiv_dn, $packet_debug) ; | ||
| 20 | |||
| 21 | use lib qw(/usr/local/nagios/libexec) ; | ||
| 22 | use utils qw($TIMEOUT %ERRORS &print_revision &support &usage) ; | ||
| 23 | use packet_utils qw(pdump &tethereal) ; | ||
| 24 | |||
| 25 | my $PROGNAME = 'check_lotus_notes' ; | ||
| 26 | |||
| 27 | sub print_help (); | ||
| 28 | sub print_usage (); | ||
| 29 | sub help (); | ||
| 30 | sub version (); | ||
| 31 | |||
| 32 | my $TEST_COUNT = 2 ; | ||
| 33 | # Number of Lotus client hellos sent without reply | ||
| 34 | my $BUFFER_SIZE = 1500 ; | ||
| 35 | # buffer size used for 'recv' calls. | ||
| 36 | my $LOTUS_PORT = 1352 ; | ||
| 37 | |||
| 38 | Getopt::Long::Configure('no_ignore_case'); | ||
| 39 | GetOptions | ||
| 40 | ("V|version" => \&version, | ||
| 41 | "h|help" => \&help, | ||
| 42 | "v|debug" => \$debug, | ||
| 43 | "vv|i_packet_debug" => \$packet_debug, | ||
| 44 | "H|lotus_host=s"=> \$lotus_host, | ||
| 45 | # "I|indivual_dn:s" => \$indiv_dn, | ||
| 46 | "S|server:s" => \$server, | ||
| 47 | "T|t_timeout:i" => \$timeout, | ||
| 48 | ) ; | ||
| 49 | |||
| 50 | usage("You must provide the DNS name or IP (v4) address of the Lotus server to be checked.\n") | ||
| 51 | unless $lotus_host and ( | ||
| 52 | $lotus_host =~ m#^\d+\.\d+\.\d+\.\d+$# or | ||
| 53 | $lotus_host =~ m#^[\w\._-]+$# | ||
| 54 | ) ; | ||
| 55 | |||
| 56 | $server ||= $lotus_host | ||
| 57 | if $lotus_host =~ m#^[\w-]+$# ; | ||
| 58 | |||
| 59 | usage("You must provide a server option unless the lotus_host option looks like an unqualified host name.\n") | ||
| 60 | unless $server ; | ||
| 61 | |||
| 62 | $timeout ||= $TIMEOUT ; | ||
| 63 | $debug = 1 | ||
| 64 | if $packet_debug ; | ||
| 65 | |||
| 66 | my $server_dn = "CN=\U$server" . '(?:/\w+=[\w -]+)*' ; | ||
| 67 | |||
| 68 | # Definitions of query strings. Change at your own risk :) | ||
| 69 | # This info was gathered with tcpdump while using a Lotus Notes 5 client, | ||
| 70 | # so I'm not sure of what each value is. | ||
| 71 | |||
| 72 | my $lotus_client_hello = &tethereal(<<'End_of_Tethereal_trace', '82') ; | ||
| 73 | 0030 ff ff dc c5 00 00 82 00 00 00 77 00 00 00 02 00 ..........w..... | ||
| 74 | 0040 00 40 02 0f 00 07 00 39 05 9e 45 54 ad ad 03 00 .@.....9..ET.... | ||
| 75 | 0050 00 00 00 02 00 2f 00 00 00 00 00 00 00 00 00 40 ...../.........@ | ||
| 76 | 0060 1f a0 af 19 d8 92 da 37 78 c9 ce 60 5e 35 b8 f7 .......7x..`^5.. | ||
| 77 | 0070 4e 05 00 10 00 0d 00 00 00 00 00 00 00 00 00 00 N............... | ||
| 78 | 0080 00 00 00 00 00 02 00 08 00 9c dc 22 00 7c 6f 25 ...........".|o% | ||
| 79 | 0090 4a 08 00 10 00 00 00 00 00 00 00 00 00 00 00 00 J............... | ||
| 80 | 00a0 00 00 00 00 00 04 00 10 00 ba ac 8c 49 67 ee a1 ............Ig.. | ||
| 81 | 00b0 22 6f 63 bb 04 b4 75 0b 8f 00 "oc...u... | ||
| 82 | End_of_Tethereal_trace | ||
| 83 | |||
| 84 | # XXXX | ||
| 85 | # Notes 5 accepts this | ||
| 86 | # _wrongly_ encoded DN | ||
| 87 | # but in general the | ||
| 88 | # server will reset | ||
| 89 | # the connection if | ||
| 90 | # it receives malformed | ||
| 91 | # packets. | ||
| 92 | |||
| 93 | my $lotus_client_m1 = &tethereal(<<'End_of_Tethereal_trace', 'de') ; | ||
| 94 | 0000 de 00 00 00 d4 00 00 00 13 00 00 40 01 00 9e 45 ...........@...E | ||
| 95 | 0010 54 ad ad 03 00 00 00 00 02 00 29 13 23 00 b9 68 T.........).#..h | ||
| 96 | 0020 25 00 9f 87 27 00 8f f4 25 00 00 00 88 00 24 00 %...'...%.....$. | ||
| 97 | 0030 28 00 00 00 42 56 04 00 31 2e 30 00 42 43 01 00 (...BV..1.0.BC.. | ||
| 98 | 0040 03 42 41 01 00 30 42 4c 02 00 76 02 4e 4e 50 00 .BA..0BL..v.NNP. | ||
| 99 | 0050 cf ee 9d 19 99 ca e0 bf 97 d3 59 a1 c5 78 16 82 ..........Y..x.. | ||
| 100 | 0060 76 09 8c 2c 96 ae 5a c1 15 bd 4e e9 b7 0f a9 d4 v..,..Z...N..... | ||
| 101 | 0070 5a 03 d9 0d bc e4 7d 4f e0 f2 79 89 cf cd 23 19 Z.....}O..y...#. | ||
| 102 | 0080 40 55 98 81 98 be d9 17 8d 69 8e 09 de c8 e8 92 @U.......i...... | ||
| 103 | 0090 24 86 6f 5a 09 81 1f 71 be 29 b7 47 78 8c 2e 00 $.oZ...q.).Gx... | ||
| 104 | 00a0 45 4e 04 00 95 63 00 00 4d 41 08 00 64 a1 b4 b3 EN...c..MA..d... | ||
| 105 | 00b0 a1 01 45 c2 80 00 50 55 52 53 41 46 22 00 43 4e ..E...PURSAF".CN | ||
| 106 | 00c0 3d 4d 72 20 46 6f 6f 2f 4f 55 3d 42 61 72 20 68 =Mr Foo/OU=Bar h | ||
| 107 | 00d0 6f 74 65 6c 2f 4f 3d 42 61 7a 20 4a 75 6e 63 74 otel/O=Baz Junct | ||
| 108 | 00e0 69 6f 6e ion | ||
| 109 | End_of_Tethereal_trace | ||
| 110 | |||
| 111 | my $buff = ''; | ||
| 112 | |||
| 113 | my $valid_resp_cr = sub { | ||
| 114 | my ($resp, $dn, $err_ind_sr) = @_ ; | ||
| 115 | if ( $resp =~ /($dn)/ ) { | ||
| 116 | return $1 | ||
| 117 | } else { | ||
| 118 | ($$err_ind_sr) = $resp =~ m#(CN=[\w -]+(?:/\w+=[\w -]+)*)# ; | ||
| 119 | return 0 ; | ||
| 120 | } | ||
| 121 | } ; | ||
| 122 | |||
| 123 | my @send = ( | ||
| 124 | { Msg => 'Helo', Send => $lotus_client_hello, Ok => $valid_resp_cr }, | ||
| 125 | { Msg => 'm1', Send => $lotus_client_m1, Ok => $valid_resp_cr }, | ||
| 126 | ) ; | ||
| 127 | |||
| 128 | my $tcp ; | ||
| 129 | |||
| 130 | eval { | ||
| 131 | |||
| 132 | $tcp = IO::Socket::INET->new(Proto => 'tcp', PeerAddr => $lotus_host, PeerPort => $LOTUS_PORT, Timeout => $timeout) | ||
| 133 | # Some versions (eg 1.1603) croak on a connect failure .. | ||
| 134 | } ; | ||
| 135 | |||
| 136 | &outahere("Connect to $lotus_host:$LOTUS_PORT failed:", $@) | ||
| 137 | if $@ || ! defined($tcp) ; | ||
| 138 | |||
| 139 | my $found = '' ; | ||
| 140 | |||
| 141 | foreach (@send) { | ||
| 142 | |||
| 143 | print STDERR "Sending Lotus client $_->{Msg} to $lotus_host.\n" | ||
| 144 | if $debug ; | ||
| 145 | |||
| 146 | &pdump($_->{Send}) | ||
| 147 | if $packet_debug ; | ||
| 148 | |||
| 149 | eval { | ||
| 150 | |||
| 151 | local $SIG{"ALRM"} = sub { die 'Alarm clock restart' } ; | ||
| 152 | |||
| 153 | alarm($timeout) ; | ||
| 154 | |||
| 155 | $tcp->send($_->{Send}, 0) || | ||
| 156 | &outahere("Send to $lotus_host failed: $!") ; | ||
| 157 | |||
| 158 | defined( $tcp->recv($buff, $BUFFER_SIZE, 0 ) ) || | ||
| 159 | &outahere("Recv from $lotus_host failed: $!") | ||
| 160 | |||
| 161 | } ; | ||
| 162 | |||
| 163 | alarm(0) ; | ||
| 164 | |||
| 165 | &outahere('Unexpected exception raised by eval:', $@) | ||
| 166 | if $@ and $@ !~ /Alarm clock restart/ ; | ||
| 167 | |||
| 168 | &outahere("Timeout after $timeout secs - no response from $lotus_host") | ||
| 169 | if $@ and $@ =~ /Alarm clock restart/ ; | ||
| 170 | |||
| 171 | &outahere("Lotus server $lotus_host reset connection - client protocol (malformed packet sent) error", $@) | ||
| 172 | if $@ and $@ =~ /reset/ ; | ||
| 173 | |||
| 174 | &outahere("Empty recv buff after sending client $_->{Msg} and waiting $timeout secs. NB _no_ timeout exception.") | ||
| 175 | unless $buff ; | ||
| 176 | |||
| 177 | &pdump($buff) | ||
| 178 | if $packet_debug ; | ||
| 179 | |||
| 180 | my $err = '' ; | ||
| 181 | |||
| 182 | &outahere(qq(Response from $lotus_host failed to match CN=$server/.. got "$err") ) | ||
| 183 | unless $found = $_->{Ok}->($buff, $server_dn, \$err) ; | ||
| 184 | |||
| 185 | print STDERR "Received Ok reply from $lotus_host - found DN $found in response.\n" | ||
| 186 | if $debug ; | ||
| 187 | |||
| 188 | } | ||
| 189 | |||
| 190 | close $tcp; | ||
| 191 | |||
| 192 | print "Ok. Lotus server $lotus_host responded with $found after ", scalar @send, " packet dialogue.\n" ; | ||
| 193 | exit $ERRORS{OK} ; | ||
| 194 | |||
| 195 | =begin comment | ||
| 196 | |||
| 197 | Normal response from Lotus Notes 5 server | ||
| 198 | |||
| 199 | 0000 74 00 00 00 69 00 00 00 03 00 00 40 02 0f 00 05 t...i......@.... | ||
| 200 | 0010 00 3d 05 60 f0 3a 38 03 03 00 00 00 00 02 00 2f .=.`.:8......../ | ||
| 201 | 0020 00 26 00 00 00 00 00 00 00 40 1f 3d 73 76 0e 57 .&.......@.=sv.W | ||
| 202 | 0030 e0 d7 67 cd a3 50 10 e0 99 24 b4 43 4e 3d 43 42 ..g..P...$.CN=CB | ||
| 203 | 0040 52 4e 4f 54 45 53 30 31 2f 4f 55 3d 53 45 52 56 RNOTES01/OU=SERV | ||
| 204 | 0050 45 52 53 2f 4f 3d 49 50 41 75 73 74 72 61 6c 69 ERS/O=IPAustrali | ||
| 205 | 0060 61 05 00 10 00 09 00 00 00 00 00 00 00 00 00 00 a............... | ||
| 206 | 0070 00 00 00 00 00 00 | ||
| 207 | |||
| 208 | =end comment | ||
| 209 | |||
| 210 | =cut | ||
| 211 | |||
| 212 | sub outahere { | ||
| 213 | print "Failed. @_.\n" ; | ||
| 214 | exit $ERRORS{CRITICAL} ; | ||
| 215 | } | ||
| 216 | |||
| 217 | sub print_usage () { | ||
| 218 | print "Usage: $PROGNAME -H <lotus_host (name _or_ address)>..) [-S <lotus_server name> -T <timeout> -v ]\n"; | ||
| 219 | } | ||
| 220 | |||
| 221 | sub print_help () { | ||
| 222 | print_revision($PROGNAME,'$Revision$ '); | ||
| 223 | print "Copyright (c) 2004 Ed Rolison/S Hopcroft | ||
| 224 | |||
| 225 | Perl Check Lotus Notes plugin for Nagios. | ||
| 226 | |||
| 227 | Returns OK if the named server responds with its name. | ||
| 228 | |||
| 229 | "; | ||
| 230 | print_usage(); | ||
| 231 | print ' | ||
| 232 | -H, --lotus_host:STRING | ||
| 233 | Name or IP Address of Lotus server to be checked. | ||
| 234 | -I, --individual_dn:NOT IMPLEMENTED | ||
| 235 | String of form CN=\w+(?:/OU=\w+)?/O=\w+ | ||
| 236 | -S, --server:STRING | ||
| 237 | Alpha numeric string specifying the Lotus server name (the CN by which the server is known by | ||
| 238 | in the Domino directory). Defaults to host name if the host name does not look like an IP address. | ||
| 239 | -T, --packet-timeout:INTEGER | ||
| 240 | Time to wait for TCP dialogue to complete = send + rcv times (default Nagios timeout [$TIMEOUT sec]). | ||
| 241 | -v, --debug | ||
| 242 | Debugging output. | ||
| 243 | -vv, --packet_debug | ||
| 244 | Packet dump. Please post to Nag users in the event of trouble with this plugin. | ||
| 245 | -h, --help | ||
| 246 | This stuff. | ||
| 247 | |||
| 248 | '; | ||
| 249 | support(); | ||
| 250 | } | ||
| 251 | |||
| 252 | sub version () { | ||
| 253 | print_revision($PROGNAME,'$Revision$ '); | ||
| 254 | exit $ERRORS{'OK'}; | ||
| 255 | } | ||
| 256 | |||
| 257 | sub help () { | ||
| 258 | print_help(); | ||
| 259 | exit $ERRORS{'OK'}; | ||
| 260 | } | ||
| 261 | |||
