Re: Citrix plugin
"Tom DE BLENDE" <[email protected]>
| Newsgroups | gmane.network.netsaint.user |
|---|---|
| Organization | DHL GCC |
| Message-ID | <[email protected]> |
Dear Jens, Did this solve your issue (either using single or double quotes in your service definition)? Please advise, Tom "Bishop, Dean" wrote: > > you need to guard your arument (APPLICATION ONE) with some form of > quotes...probably doubles will do the trick > > -----Original Message----- > From: Jens Kruse [mailto:[email protected]] > Sent: Monday, October 07, 2002 12:03 PM > To: Tom DE BLENDE > Cc: [email protected] > Subject: Re: [netsaint] Citrix plugin > > Hi Tom, > > thanks for this nice plug-in! > > One question so far: > > - Calling './check_cit -C SERVER -P 'APPLICATION ONE' works > > - When I implement it in our netsaint environment, I receive the > following error code: > Failed. "'APPLICATION" not found in list of published applications > "APPLICATION ONE,APPLICATION TWO,APPLICATION THREE" from master browser > "10.10.10.99". > > The command.cfg-statement looks like this: > command[check_cit]=/usr/lib/netsaint/plugins/check_cit -C $HOSTADDRESS$ > -P '$ARG1$' > service[SERVER]=Published Application APPLICATION > ONE;0;24x7;3;5;1;nt-admins;360;24x7;1;1;1;;check_cit!APPLICATION ONE > > any idea what might be wrong? > > TIA, Jens > > Tom DE BLENDE wrote: > > Dear all, > > > > Thanks to the great efforts made by Ed Rolison who created the > > original plugin for Big Brother, and Stanley Hopcroft who cleaned up > > the Netsaint port I've made, I am now able to release a beta version > > of the check_cit plugin. > > > > Help can be obtained by running "./check_cit --help". Basicly this > > plugin checks for the availability of published applications in a > > Citrix environment. It does this either by means of a broadcast, or by > > using a query to a specific server. > > > > I would like to ask those of you who have a Citrix environment to try > > out the plugin, and see if it works OK. Any comments are welcome. > > > > Kind regards, > > Tom De Blende > > > > > > ------------------------------------------------------------------------ > > > > #!/usr/bin/perl -w > > > > # $Id: check_cit,v 1.6 2002-10-03 16:16:44+10 anwsmh Exp anwsmh $ > > > > # $Log: check_cit,v $ > > # Revision 1.6 2002-10-03 16:16:44+10 anwsmh > > # Contributions from Mr Bas Rijniersce > > # 1 Decode unicode in application list if it looks as if the app list > contains unicode > > # 2 Only stop receiving packets from the browser after the socket times > out > > # (formerly would only read 2 packets and this was useless for more > than 20 apps) > > # if -L option. > > # 3 Change meaning of -T and default value. Now this is the UDP packet > timeout > > # value and is set to be 1 second. > > # > > # Revision 1.5 2002-10-01 19:26:07+10 anwsmh > > # Provide -L option to deal with long lists of published apps (use -T > probably indicated also). > > # > > # Revision 1.4 2002-10-01 16:53:56+10 anwsmh > > # Roll version to accomodate > > # . -P no longer mandatory (either -P or -W will do) > > # . remove some redundant pack and unpacks after getting the > > # app list from the browser. > > # > > > > # Ed Rolison 15/06/02 > > # [email protected] > > # If it doesn't work, please let me know, I've only had access to my > > # environment so I'm not 100% sure. > > # > > # If you want to mess around with this script, then please feel free > > # to do so. > > # However, if you add anything 'funky' then I'd really appreciate > > # hearing about it. > > # > > # Oh, and if you do ever make huge amounts of money out of it, cut me > > # in :) > > > > use strict ; > > > > use IO::Socket; > > use IO::Select; > > use FileHandle; > > use Getopt::Long ; > > > > use vars qw($opt_H $opt_B $opt_W $opt_T $debug @citrix_servers > $crit_pub_apps $warn_pub_apps $long_list); > > use utils qw(%ERRORS &print_revision &support &usage); > > > > my $PROGNAME = 'check_citrix' ; > > > > sub print_help (); > > sub print_usage (); > > sub help (); > > sub version (); > > > > delete @ENV{'PATH', 'IFS', 'CDPATH', 'ENV', 'BASH_ENV'}; > > > > # You might have to change this... > > > > use constant PACKET_TIMEOUT => 1; > > # Number of seconds to wait for further UDP > packets > > use constant TEST_COUNT => 2; > > # Number of datagrams sent without reply > > use constant BUFFER_SIZE => 1500; > > # buffer size used for 'recv' calls. > > use constant LONG_LIST => 0 ; > > # this is for if you have many published > applications. > > # if you set it, it won't do any harm, but > may slow the test > > # down a little. (Since it does a 'recv' > twice instead of > > # once and therefore may have to wait for a > timeout). > > use constant ICA_PORT => 1604; > > # what port ICA runs on. Unlikely to change. > > > > # End user config. > > > > Getopt::Long::Configure('bundling', 'no_ignore_case'); > > GetOptions > > ("V|version" => \&version, > > "h|help" => \&help, > > "d|debug" => \$debug, > > "B|broadcast_addr:s" => \$opt_B, > > "C|citrix_servers:s" => \@citrix_servers, > > "L|long_list" => \$long_list, > > "P|crit_pub_apps:s" => \$crit_pub_apps, > > "T|Packet_timeout:i" => \$opt_T, > > "W|warn_pub_apps:s" => \$warn_pub_apps, > > ) ; > > > > # configuration section > > > > my $broadcast_addr = $1 if $opt_B and $opt_B =~ m#(\d+\.\d+\.\d+\.\d+)# ; > > usage("Invalid broadcast address: $opt_B\n") if $opt_B and not > defined($broadcast_addr) ; > > > > usage("You must provide either the names of citrix servers or the > broadcast address of the subnet containing them\n") > > unless (@citrix_servers or $broadcast_addr) ; > > > > my @target = defined $broadcast_addr ? ($broadcast_addr) : @citrix_servers > ; > > > > usage("You must provide the names of the published applications that the > Citrix browser should be advertising\n") > > unless $crit_pub_apps or $warn_pub_apps ; > > > > my $Timeout = $opt_T if defined $opt_T ; > > $Timeout = PACKET_TIMEOUT unless defined $Timeout ; > > $long_list = LONG_LIST unless defined $long_list ; > > > > my @crit_pub_apps = $crit_pub_apps ? split(/,/, $crit_pub_apps) : () ; > > my @warn_pub_apps = $warn_pub_apps ? split(/,/, $warn_pub_apps) : () ; > > > > # definitions of query strings. Change at your own risk :) > > # this info was gathered with tcpdump whilst trying to use an ICA client, > > # so I'm not 100% sure of what each value is. > > > > my @bcast_helo = &tethereal2list(<<'End_of_Tethereal_trace', '1e') ; > > 0020 ff ff 04 d6 06 44 00 26 4a 76 1e 00 01 30 02 fd .....D.&Jv...0.. > > 0030 a8 e3 00 02 f5 95 9f f5 30 07 00 00 00 00 00 00 ........0....... > > 0040 00 00 00 00 00 00 01 00 > > End_of_Tethereal_trace > > > > my @bcast_query_app = &tethereal2list(<<'End_of_Tethereal_trace', '24') ; > > 0020 64 17 04 50 06 44 00 2c 85 6a 24 00 01 32 02 fd d..P.D.,.j$..2.. > > 0030 a8 e3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ > > 0040 00 00 00 00 00 00 21 00 02 00 00 00 00 00 ......!...... > > End_of_Tethereal_trace > > > > my @direct_helo = &tethereal2list(<<'End_of_Tethereal_trace', '20') ; > > 0020 64 17 05 0f 06 44 00 28 ab b5 20 00 01 30 02 fd d....D.(.. ..0.. > > 0030 a8 e3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ > > 0040 00 00 00 00 00 00 00 00 00 00 > > End_of_Tethereal_trace > > > > my @direct_query_app = &tethereal2list(<<'End_of_Tethereal_trace', '2c') ; > > 0020 64 17 05 10 06 44 00 34 7a 9a 2c 00 02 32 02 fd d....D.4z.,..2.. > > 0030 a8 e3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ > > 0040 00 00 00 00 00 00 21 00 02 00 01 00 00 00 00 00 ......!......... > > 0050 00 00 00 00 00 00 > > End_of_Tethereal_trace > > > > my $Udp = IO::Socket::INET->new( Proto => 'udp' ) || die "Socket failure: > $!"; > > > > # select is here to allow us to set timeouts on the connections. > Otherwise they > > # just 'stop' until a server appears. > > > > my $select = IO::Select->new($Udp) || die "Select failure: $!"; > > > > # helo needs to be broadcast, but query does not. > > > > $Udp->sockopt(SO_BROADCAST, 1 ); > > $Udp->autoflush(1); > > > > my ($remote_host, $buff, $buff2, $raddr, $rport, $rhost, > @remote_response); > > my (@query_message, $send_addr, $this_test) ; > > > > $buff = $buff2 = ''; > > $this_test = 0; > > > > # If there is no response to the first helo packet it will be resent > > # up to TEST_COUNT (see at the top). > > > > while ( ++$this_test <= TEST_COUNT && !$buff ) { > > > > print "Sending helo datagram. datagram number: ", $this_test, "\n" if > $debug ; > > > > # if we have multiple targets, we probe each of them until we get a > > # response... > > > > foreach my $destination (@target) { > > @query_message = ( $broadcast_addr ? @bcast_helo : @direct_helo) ; > > print "Querying $destination for master browser\n" if $debug ; > > $send_addr = sockaddr_in(ICA_PORT, inet_aton($destination) ); > > &dump(pack('C*', @query_message)) if $debug ; > > $Udp->send( pack('C*', @query_message), 0, $send_addr ); > > if ( $select->can_read($Timeout) ) { > > $remote_host = $Udp->recv($buff, BUFFER_SIZE, 0 ); > > } > > > > last if $buff ; > > sleep 1 ; > > > > } # foreach destination > > } # while loop > > > > # ok we've looped several times, looking for a response. If we don't have > one > > # yet, we simply mark the whole lot as being unavailable. > > > > unless ( $buff ) { > > print "Failed. No response to helo datagram (master browser query) from > ", $broadcast_addr ? $broadcast_addr : "@citrix_servers", ".\n" ; > > exit $ERRORS{CRITICAL} ; > > } > > > > ($rport, $raddr) = sockaddr_in( $remote_host ); > > $rhost = gethostbyaddr( $raddr, AF_INET ); > > my @tmpbuf = unpack('C*', $buff ); > > if ( $debug ) { > > print "$rhost:$rport responded with: ",length($buff), " bytes\n"; > > &dump($buff) ; > > } #if debug > > > > # now we have a response, then we need to figure out the master browser, > and > > # query it for published applications... > > > > my $master_browser = join '.', @tmpbuf[32..35] ; > > > > # ok should probably error check this, because it's remotely possible > > # that a server response might be completely wrong... > > > > print "Master browser = $master_browser\n" if $debug ; > > > > $send_addr = sockaddr_in(ICA_PORT, inet_aton($master_browser)); > > > > if ( $broadcast_addr ) { > > print "using broadcast query\n" if $debug ; > > @query_message = @bcast_query_app; > > } else { > > print "using directed query\n" if $debug ; > > @query_message = @direct_query_app; > > } > > > > # now we send the appropriate query string, to the master browser we've > found. > > > > $buff = ''; > > $this_test = 0 ; > > > > print "Querying master browser for published application list\n" if > $debug ; > > > > while ( ++$this_test <= TEST_COUNT && !$buff ) { > > print "Sending application query datagram. datagram number: ", > $this_test, "\n" if $debug ; > > &dump(pack('C*', @query_message)) if $debug ; > > $Udp->send( pack ('C*', @query_message), 0, $send_addr ); > > > > if ( $select->can_read($Timeout) ) { > > $remote_host = $Udp->recv($buff, BUFFER_SIZE, 0 ); > > # $buff = substr($buff, 32) ; > > # Hope that ICA preamble is > first 32 bytes > > } > > > > # long application lists are delivered in multiple packets > > > > my $buff2 = '' ; > > while ( $long_list && $select->can_read($Timeout) ) { > > $remote_host = $Udp->recv($buff2, BUFFER_SIZE, 0 ); > > $buff .= $buff2 if $buff2 ; > > # $buff .= substr($buff2, 32) if $buff2 ; > > # Hope that ICA preamble is > first 32 bytes > > } > > > > last if $buff ; > > sleep 1 ; > > > > } # while test_count > > > > unless ( $buff ) { > > print "Failed. No response to application query datagram from ", > $master_browser, ".\n" ; > > exit $ERRORS{CRITICAL} ; > > } > > > > # we got a response from a couple of retries of the app query > > > > ($rport, $raddr) = sockaddr_in ( $remote_host ); > > $rhost = gethostbyaddr ( $raddr, AF_INET ); > > if ( $debug ) { > > print "$rhost:$rport responded to app query with: ",length($buff), " > bytes\n"; > > &dump($buff) ; > > } #debug > > > > my $app_list = $buff ; > > # delete nulls in unicode > > # but only if there is > unicode (usually from > > # broadcast query) > > > > $app_list =~ s/(?:(\w| |-)\x00)/$1/g > > if $app_list =~ /(?:(?:(?:\w| |-)\x00){3,})/ ; > > # FIXME an application name > is > > # 3 or more unicoded > characters > > > > # FIXME locale > > # extract null terminated > strings > > > > my (@clean_app_list, $clean_app_list) ; > > $clean_app_list = join(',', @clean_app_list = $app_list =~ m#([A-Z](?:\w| > |-)+?(?=\x00))#g ) ; > > > > # FIXME everyones apps don't > start with caps > > > > print qq(Received list of applications: "$clean_app_list".\n) if $debug ; > > > > if ( scalar @crit_pub_apps and my @missing = > &simple_diff(\@clean_app_list, \@crit_pub_apps) ) { > > print qq(Failed. "@missing" not found in list of published > applications), > > qq( "$clean_app_list" from master browser "$master_browser".\n) ; > > exit $ERRORS{CRITICAL} ; > > } > > > > if ( my @missing = &simple_diff(\@clean_app_list, \@warn_pub_apps) ) { > > print qq(Warning. "@missing" not found in list of published > applications), > > qq( "$clean_app_list" from master browser "$master_browser".\n) ; > > exit $ERRORS{WARNING} ; > > } > > > > my @x = (@crit_pub_apps, @warn_pub_apps) ; > > my $blah = ( scalar(@x) == 1 ? 'the published application "' . join(',', > @x) . '" is available' : > > 'the published applications "' . join(',', > @x) . '" are available' ) ; > > > > print qq(Ok. Citrix master browser "$master_browser" reported that > $blah.\n) ; > > exit $ERRORS{OK} ; > > > > # sleep $Timeout; > > # because otherwise we can > get responses from > > # the WRONG servers. DOH > > close $Udp; > > > > > > sub print_usage () { > > print "Usage: $PROGNAME (-B <broadcast_address>| -C > <citrix_server>..) -W <pub_app1,pub_app2..> -P <pub_app1,pub_app2,>\n"; > > } > > > > sub print_help () { > > print_revision($PROGNAME,'$Revision: 1.6 $ '); > > print "Copyright (c) 2002 Ed Rolison/Tom De Blende > > > > Perl Check Citrix plugin for NetSaint. > > > > Returns OK if the Citrix master browser returns a 'published application' > list that contain names specified by the -W or -P options > > > > The plugin works by > > If the -B option is specified, sending a broadcast helo to find the > address of the Citrix master browser in the specified subnet. > > return critical if there is no reply; > > Else if the -C option is specified > > send a direct helo to the specified server until there is a response > (containing the address of the Citrix master browser) > > > > Query the master browser (using a 'broadcast published applications > query ' if -B) and compare the published applications returned > > to those specified by -W and -P options > > > > return Critical if the published applications specified by -P is not a > subset of the query responses; > > return Warning if the published applications specified by -W is not a > subset of the query responses; > > return OK > > > > "; > > print_usage(); > > print ' > > -B, --broadcast_address=STRING > > The broadcast address that should contain Citrix master browser. This > option takes precedence over -C. > > -C, --citrix_server:STRING > > Optional __name(s)__ of Citrix servers that could be the master browser > (used when broadcast not possible). > > -L, --long_list > > Set this if you have heaps of published applications (ie more than will > fit in _one_ UDP packet) > > -P, --crit_published_app=STRING > > Optional comma separated list of published application that must be in > the response from the master browser. > > Check returns critical otherwise. > > -T, --packet-timeout:INTEGER > > Time to wait for UDP packets (default 1 sec). > > -W, --warn_published_app=STRING > > Optional comma separated list of published application that should be > in the response from the master browser. > > Check returns warning otherwise. > > -d, --debug > > Debugging output. > > -h, --help > > This stuff. > > > > '; > > support(); > > } > > > > sub version () { > > print_revision($PROGNAME,'$Revision: 1.6 $ '); > > exit $ERRORS{'OK'}; > > } > > > > sub help () { > > print_help(); > > exit $ERRORS{'OK'}; > > } > > > > sub dump { > > my ($x) = shift @_ ; > > my (@x, @y, $y, $i, $rowcount) ; > > my ($nr, $j, $number_in_row, $number_of_bytes) ; > > my $dump ; > > > > $number_in_row = 16 ; > > $number_of_bytes = length $x ; > > $nr = 0 ; > > > > # styled on tethereal. > > > > foreach $j (1 .. int( $number_of_bytes / $number_in_row) ) { > > $y = substr($x, ($j - 1)*$number_in_row, $number_in_row) ; > > @y = unpack("C*", $y) ; > > $y =~ tr /\x00-\x19/./ ; > > $rowcount = sprintf("%4.4x", ($j - 1) * 0x10 ) ; > > $dump .= sprintf "%s %s %s\n", $rowcount, join(" ", map { sprintf > "%2.2x", $_} @y), $y ; > > $nr++ ; > > } > > > > if ( $number_of_bytes % $number_in_row > 0 ) { > > my $spaces_to_text = $number_in_row * 3 - 1 + 3 ; > > $rowcount = sprintf("%4.4x", $nr * 0x10 ) ; > > $y = substr($x, $nr * $number_in_row ) ; > > @y = unpack("C*", $y) ; > > my $bytes = join(" ", map { sprintf "%2.2x", $_} @y) ; > > my $spaces = ' ' x ($spaces_to_text - length($bytes)) ; > > $dump .= sprintf "%s %s%s%s\n", $rowcount, $bytes, $spaces, $y ; > > } > > > > print $dump, "\n" ; > > > > } > > > > sub tethereal2list { > > my ($tethereal_dump, $start_byte) = @_ ; > > > > # return an array containing qw(0xef 0xab 0x00 ...) from a tethereal > trace. > > # skip all stuff until the first byte given by $start_byte. > > > > return undef unless $tethereal_dump =~ /\d\d\d\d \S\S(?: \S\S){1,15}/ ; > > > > my $hex_start_byte = hex($start_byte) ; > > my @x = $tethereal_dump =~ m#(.+)#g ; > > my @y = map unpack("x6 a47", $_), @x ; > > my @z = map { my $y = $_; $y =~ s/(\S\S)/hex($1)/eg; my @a = split(' ', > $y); @a } @y ; > > shift @z, while $z[0] ne $hex_start_byte ; > > > > @z ; > > > > } > > > > sub simple_diff { > > > > my ( $a_list, $b_list) = @_ ; > > > > # simple set difference 'Recipe 4.7 Perl Cookbook', Christiansen and > Torkington > > > > my (%seen, @missing) ; > > > > @seen{@$a_list} = () ; > > > > foreach my $item (@$b_list) { > > push @missing, $item unless exists $seen{$item} ; > > } > > > > @missing ; > > } > > > > > > > > -- > Mit freundlichen Grüßen > > Jens Kruse > Linux Systemadministrator > > MobilCom AG > Hollerstraße 126 > 24782 Büdelsdorf > Telefon: +49 (0)4331/ 447 - 2168 > Telefax: +49 (0)4331/ 434 - 4010 > [email protected] > > Besucher: > Am Friedrichsbrunnen > > ------------------------------------------------------- > This sf.net email is sponsored by:ThinkGeek > Welcome to geek heaven. > http://thinkgeek.com/sf > _______________________________________________ > Netsaint-users mailing list > [email protected] > https://lists.sourceforge.net/lists/listinfo/netsaint-users -- Tom De Blende Senior NT Infrastructure Analyst (Frango) DHL Global Coordination Center - IT Department Tel +32 2 713 42 62 Fax +32 2 713 52 00 ------------------------------------------------------- This sf.net email is sponsored by:ThinkGeek Welcome to geek heaven. http://thinkgeek.com/sf