diff options
Diffstat (limited to 'contrib/check_ica_master_browser.pl')
| -rwxr-xr-x | contrib/check_ica_master_browser.pl | 228 |
1 files changed, 0 insertions, 228 deletions
diff --git a/contrib/check_ica_master_browser.pl b/contrib/check_ica_master_browser.pl deleted file mode 100755 index 922e7187..00000000 --- a/contrib/check_ica_master_browser.pl +++ /dev/null | |||
| @@ -1,228 +0,0 @@ | |||
| 1 | #!/usr/bin/perl -w | ||
| 2 | |||
| 3 | # $Id: check_ica_master_browser.pl 1099 2005-01-25 09:09:33Z stanleyhopcroft $ | ||
| 4 | |||
| 5 | # Revision 1.1 2005/01/25 09:09:33 stanleyhopcroft | ||
| 6 | # New plugin - checks that ICA master browser is what it should be (important for firewalled dialup) | ||
| 7 | # | ||
| 8 | |||
| 9 | use strict ; | ||
| 10 | |||
| 11 | use IO::Socket; | ||
| 12 | use IO::Select; | ||
| 13 | use Getopt::Long ; | ||
| 14 | |||
| 15 | use lib qw(/usr/local/nagios/libexec) ; | ||
| 16 | use utils qw(%ERRORS &print_revision &support &usage); | ||
| 17 | use packet_utils qw(&pdump &tethereal) ; | ||
| 18 | |||
| 19 | my $PROGNAME = 'check_ica_master_browser' ; | ||
| 20 | |||
| 21 | # You might have to change this... | ||
| 22 | |||
| 23 | my $PACKET_TIMEOUT = 1; | ||
| 24 | # Number of seconds to wait for further UDP packets | ||
| 25 | my $TEST_COUNT = 2; | ||
| 26 | # Number of datagrams sent without reply | ||
| 27 | my $BUFFER_SIZE = 1500; | ||
| 28 | # buffer size used for 'recv' calls. | ||
| 29 | my $ICA_PORT = 1604; | ||
| 30 | # what port ICA runs on. Unlikely to change. | ||
| 31 | |||
| 32 | # End user config. | ||
| 33 | |||
| 34 | my ($debug, $preferred_master, $bcast_addr, $ica_browser, $timeout) ; | ||
| 35 | |||
| 36 | Getopt::Long::Configure('bundling', 'no_ignore_case'); | ||
| 37 | GetOptions | ||
| 38 | ("V|version" => \&version, | ||
| 39 | "h|help" => \&help, | ||
| 40 | "v|verbose" => \$debug, | ||
| 41 | "B|broadcast_addr:s" => \$bcast_addr, | ||
| 42 | "I|ica_browser:s" => \$ica_browser, | ||
| 43 | "P|preferred_master:s" => \$preferred_master, | ||
| 44 | "T|Packet_timeout:i" => \$timeout, | ||
| 45 | ) ; | ||
| 46 | |||
| 47 | |||
| 48 | my $broadcast_addr = $1 if $bcast_addr and $bcast_addr =~ m#(\d+\.\d+\.\d+\.\d+)# ; | ||
| 49 | usage("Invalid broadcast address: $bcast_addr") | ||
| 50 | if $bcast_addr and not defined($broadcast_addr) ; | ||
| 51 | |||
| 52 | usage("You must provide either the name of an ICA browser or the broadcast address of the subnet containing them\n") | ||
| 53 | unless ($ica_browser or $broadcast_addr) ; | ||
| 54 | |||
| 55 | usage("You must provide the name or address of a preferred ICA master browser\n") | ||
| 56 | unless ($preferred_master) ; | ||
| 57 | |||
| 58 | my $preferred_master_n = $preferred_master =~ m#(\d+\.\d+\.\d+\.\d+)# | ||
| 59 | ? $preferred_master | ||
| 60 | : inet_ntoa(scalar gethostbyname($preferred_master)) ; | ||
| 61 | |||
| 62 | my $Timeout = $timeout || $PACKET_TIMEOUT ; | ||
| 63 | |||
| 64 | # Definitions of query strings. Change at your own risk :) | ||
| 65 | # this info was gathered with tcpdump whilst trying to use an ICA client, | ||
| 66 | # so I'm not 100% sure of what each value is. | ||
| 67 | |||
| 68 | my $bcast_helo = &tethereal(<<'End_of_Tethereal_trace', '1e') ; | ||
| 69 | 0020 ff ff 04 d6 06 44 00 26 4a 76 1e 00 01 30 02 fd .....D.&Jv...0.. | ||
| 70 | 0030 a8 e3 00 02 f5 95 9f f5 30 07 00 00 00 00 00 00 ........0....... | ||
| 71 | 0040 00 00 00 00 00 00 01 00 ........ | ||
| 72 | End_of_Tethereal_trace | ||
| 73 | |||
| 74 | my $direct_helo = &tethereal(<<'End_of_Tethereal_trace', '20') ; | ||
| 75 | 0020 64 17 05 0f 06 44 00 28 ab b5 20 00 01 30 02 fd d....D.(.. ..0.. | ||
| 76 | 0030 a8 e3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ | ||
| 77 | 0040 00 00 00 00 00 00 00 00 00 00 ........ | ||
| 78 | End_of_Tethereal_trace | ||
| 79 | |||
| 80 | my $Udp = IO::Socket::INET->new( Proto => 'udp' ) | ||
| 81 | || die "Socket failure: $!"; | ||
| 82 | |||
| 83 | # select is here to allow us to set timeouts on the connections. Otherwise they | ||
| 84 | # just 'stop' until a server appears. | ||
| 85 | |||
| 86 | my $select = IO::Select->new($Udp) | ||
| 87 | || die "Select failure: $!"; | ||
| 88 | |||
| 89 | $Udp->sockopt(SO_BROADCAST, 1 ); | ||
| 90 | |||
| 91 | my ($remote_host, $buff, $destination, $raddr, $rport, $rhost, @remote_response); | ||
| 92 | my ($query_message, $send_addr, $this_test) ; | ||
| 93 | |||
| 94 | $buff = ''; | ||
| 95 | $this_test = 0; | ||
| 96 | |||
| 97 | # If there is no response to the first helo packet it will be resent | ||
| 98 | # up to $TEST_COUNT (see at the top). | ||
| 99 | |||
| 100 | $query_message = $broadcast_addr ? $bcast_helo : $direct_helo ; | ||
| 101 | $destination = $broadcast_addr ? $broadcast_addr: $ica_browser ; | ||
| 102 | $send_addr = sockaddr_in($ICA_PORT, inet_aton($destination) ) ; | ||
| 103 | |||
| 104 | while ( ++$this_test <= $TEST_COUNT && !$buff ) { | ||
| 105 | |||
| 106 | print "Sending helo datagram. datagram number: ", $this_test, "\n" | ||
| 107 | if $debug ; | ||
| 108 | |||
| 109 | print "Querying $destination for master browser\n" | ||
| 110 | if $debug ; | ||
| 111 | &pdump($query_message) | ||
| 112 | if $debug ; | ||
| 113 | $Udp->send($query_message, 0, $send_addr ); | ||
| 114 | if ( $select->can_read($Timeout) ) { | ||
| 115 | $remote_host = $Udp->recv($buff, $BUFFER_SIZE, 0 ); | ||
| 116 | } | ||
| 117 | |||
| 118 | last | ||
| 119 | if $buff ; | ||
| 120 | sleep 1 ; | ||
| 121 | |||
| 122 | } | ||
| 123 | |||
| 124 | # Ok we've looped several times, looking for a response. If we don't have one | ||
| 125 | # yet, we simply mark the whole lot as being unavailable. | ||
| 126 | |||
| 127 | unless ( $buff ) { | ||
| 128 | print "Failed. No response to helo datagram (master browser query) from $destination.\n" ; | ||
| 129 | exit $ERRORS{CRITICAL} ; | ||
| 130 | } | ||
| 131 | |||
| 132 | ($rport, $raddr) = sockaddr_in( $remote_host ); | ||
| 133 | $rhost = gethostbyaddr( $raddr, AF_INET ); | ||
| 134 | my @tmpbuf = unpack('C*', $buff ); | ||
| 135 | if ( $debug ) { | ||
| 136 | print "$rhost:$rport responded with: ",length($buff), " bytes\n"; | ||
| 137 | &pdump($buff) ; | ||
| 138 | } | ||
| 139 | |||
| 140 | # Now we have a response, then we need to figure out the master browser, and | ||
| 141 | # query it for published applications... | ||
| 142 | |||
| 143 | my $master_browser = join '.', @tmpbuf[32..35] ; | ||
| 144 | my ($master_browser_a) = gethostbyaddr(inet_aton($master_browser), AF_INET) =~ /^(\w+?)\./ ; | ||
| 145 | |||
| 146 | # Ok should probably error check this, because it's remotely possible | ||
| 147 | # that a server response might be completely wrong... | ||
| 148 | |||
| 149 | print "Master browser = $master_browser_a/$master_browser\n" | ||
| 150 | if $debug ; | ||
| 151 | |||
| 152 | $send_addr = sockaddr_in($ICA_PORT, inet_aton($master_browser)); | ||
| 153 | |||
| 154 | my $subject_clause = $bcast_addr ? "of the \"$destination\" subnet" : "known to ICA server \"$destination\"" ; | ||
| 155 | |||
| 156 | if ( $master_browser eq $preferred_master_n ) { | ||
| 157 | print "Preferred master browser \"$preferred_master\" __is__ the master browser (\"$master_browser_a/$master_browser\") $subject_clause.\n" ; | ||
| 158 | exit $ERRORS{OK} ; | ||
| 159 | } else { | ||
| 160 | print "\"\u$preferred_master\" is __not__ the master browser (\"$master_browser_a/$master_browser\") $subject_clause: remote clients (dialup) may not find Published applications from Master Browser.\n" ; | ||
| 161 | exit $ERRORS{CRITICAL} ; | ||
| 162 | } | ||
| 163 | |||
| 164 | close $Udp; | ||
| 165 | |||
| 166 | |||
| 167 | sub print_usage () { | ||
| 168 | print "Usage: $PROGNAME (-B <broadcast_address>| -I <citrix_server>) - P <preferred_master_browser>" ; | ||
| 169 | } | ||
| 170 | |||
| 171 | sub print_help () { | ||
| 172 | print_revision($PROGNAME,'$Revision: 1099 $ '); | ||
| 173 | print "Copyright (c) 2002 Ed Rolison/Tom De Blende/S Hopcroft | ||
| 174 | |||
| 175 | Perl Check Citrix Master Browser plugin for Nagios. | ||
| 176 | |||
| 177 | Returns OK if the Citrix master browser is that given by the -P option. | ||
| 178 | |||
| 179 | The plugin works by | ||
| 180 | If the -B option is specified, sends a broadcast helo to find the address of the Citrix master browser in the specified subnet. | ||
| 181 | return critical if there is no reply; | ||
| 182 | Else if the -I option is specified | ||
| 183 | send a direct helo to the specified server until there is a response (containing the address of the Citrix master browser) | ||
| 184 | |||
| 185 | |||
| 186 | return Critical if the response does not contain the address of the 'preferred master browser' (-P option). | ||
| 187 | return OK | ||
| 188 | |||
| 189 | How ICA Clients Use the Master ICA Browser. | ||
| 190 | |||
| 191 | Citrix ICA Clients must locate the master browser to get the address of a server or published application. | ||
| 192 | |||
| 193 | The Citrix ICA Client can locate the master browser by sending out broadcast packets, or, | ||
| 194 | if the address of a Citrix server is specified in the Citrix ICA Client or in an ICA file, | ||
| 195 | the ICA Client locates the master browser by sending directed packets to the specified address. | ||
| 196 | The ICA Client requests the address of the ICA master browser from the Citrix server. | ||
| 197 | |||
| 198 | "; | ||
| 199 | print_usage(); | ||
| 200 | print ' | ||
| 201 | -B, --broadcast_address:STRING | ||
| 202 | The broadcast address that should contain Citrix master browser. This option takes precedence over -I. | ||
| 203 | -I, --ica_browser:STRING | ||
| 204 | Optional name or address of an ICA server that could be the master browser (used when broadcast not possible). | ||
| 205 | -P, --preferred_master:STRING | ||
| 206 | Name or address of the ICA server that _should_ be the master browser. | ||
| 207 | Required. | ||
| 208 | -T, --packet-timeout:INTEGER | ||
| 209 | Time to wait for UDP packets (default 1 sec). | ||
| 210 | -v, --verbose | ||
| 211 | Debugging output. | ||
| 212 | -h, --help | ||
| 213 | This stuff. | ||
| 214 | |||
| 215 | '; | ||
| 216 | support(); | ||
| 217 | } | ||
| 218 | |||
| 219 | sub version () { | ||
| 220 | print_revision($PROGNAME,'$Revision: 1099 $ '); | ||
| 221 | exit $ERRORS{'OK'}; | ||
| 222 | } | ||
| 223 | |||
| 224 | sub help () { | ||
| 225 | print_help(); | ||
| 226 | exit $ERRORS{'OK'}; | ||
| 227 | } | ||
| 228 | |||
