Back to index

nagios-plugins  1.4.16
check_real.c
Go to the documentation of this file.
00001 /*****************************************************************************
00002 * 
00003 * Nagios check_real plugin
00004 * 
00005 * License: GPL
00006 * Copyright (c) 2000-2007 Nagios Plugins Development Team
00007 * 
00008 * Description:
00009 * 
00010 * This file contains the check_real plugin
00011 * 
00012 * This plugin tests the REAL service on the specified host.
00013 * 
00014 * 
00015 * This program is free software: you can redistribute it and/or modify
00016 * it under the terms of the GNU General Public License as published by
00017 * the Free Software Foundation, either version 3 of the License, or
00018 * (at your option) any later version.
00019 * 
00020 * This program is distributed in the hope that it will be useful,
00021 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023 * GNU General Public License for more details.
00024 * 
00025 * You should have received a copy of the GNU General Public License
00026 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00027 * 
00028 * 
00029 *****************************************************************************/
00030 
00031 const char *progname = "check_real";
00032 const char *copyright = "2000-2007";
00033 const char *email = "nagiosplug-devel@lists.sourceforge.net";
00034 
00035 #include "common.h"
00036 #include "netutils.h"
00037 #include "utils.h"
00038 
00039 enum {
00040        PORT   = 554
00041 };
00042 
00043 #define EXPECT       "RTSP/1."
00044 #define URL   ""
00045 
00046 int process_arguments (int, char **);
00047 int validate_arguments (void);
00048 void print_help (void);
00049 void print_usage (void);
00050 
00051 int server_port = PORT;
00052 char *server_address;
00053 char *host_name;
00054 char *server_url = NULL;
00055 char *server_expect;
00056 int warning_time = 0;
00057 int check_warning_time = FALSE;
00058 int critical_time = 0;
00059 int check_critical_time = FALSE;
00060 int verbose = FALSE;
00061 
00062 
00063 
00064 int
00065 main (int argc, char **argv)
00066 {
00067        int sd;
00068        int result = STATE_UNKNOWN;
00069        char buffer[MAX_INPUT_BUFFER];
00070        char *status_line = NULL;
00071 
00072        setlocale (LC_ALL, "");
00073        bindtextdomain (PACKAGE, LOCALEDIR);
00074        textdomain (PACKAGE);
00075 
00076        /* Parse extra opts if any */
00077        argv=np_extra_opts (&argc, argv, progname);
00078 
00079        if (process_arguments (argc, argv) == ERROR)
00080               usage4 (_("Could not parse arguments"));
00081 
00082        /* initialize alarm signal handling */
00083        signal (SIGALRM, socket_timeout_alarm_handler);
00084 
00085        /* set socket timeout */
00086        alarm (socket_timeout);
00087        time (&start_time);
00088 
00089        /* try to connect to the host at the given port number */
00090        if (my_tcp_connect (server_address, server_port, &sd) != STATE_OK)
00091               die (STATE_CRITICAL, _("Unable to connect to %s on port %d\n"),
00092                                                   server_address, server_port);
00093 
00094        /* Part I - Server Check */
00095 
00096        /* send the OPTIONS request */
00097        sprintf (buffer, "OPTIONS rtsp://%s:%d RTSP/1.0\r\n", host_name, server_port);
00098        result = send (sd, buffer, strlen (buffer), 0);
00099 
00100        /* send the header sync */
00101        sprintf (buffer, "CSeq: 1\r\n");
00102        result = send (sd, buffer, strlen (buffer), 0);
00103 
00104        /* send a newline so the server knows we're done with the request */
00105        sprintf (buffer, "\r\n");
00106        result = send (sd, buffer, strlen (buffer), 0);
00107 
00108        /* watch for the REAL connection string */
00109        result = recv (sd, buffer, MAX_INPUT_BUFFER - 1, 0);
00110 
00111        /* return a CRITICAL status if we couldn't read any data */
00112        if (result == -1)
00113               die (STATE_CRITICAL, _("No data received from %s\n"), host_name);
00114 
00115        /* make sure we find the response we are looking for */
00116        if (!strstr (buffer, server_expect)) {
00117               if (server_port == PORT)
00118                      printf ("%s\n", _("Invalid REAL response received from host"));
00119               else
00120                      printf (_("Invalid REAL response received from host on port %d\n"),
00121                                                  server_port);
00122        }
00123        else {
00124               /* else we got the REAL string, so check the return code */
00125 
00126               time (&end_time);
00127 
00128               result = STATE_OK;
00129 
00130               status_line = (char *) strtok (buffer, "\n");
00131 
00132               if (strstr (status_line, "200"))
00133                      result = STATE_OK;
00134 
00135               /* client errors result in a warning state */
00136               else if (strstr (status_line, "400"))
00137                      result = STATE_WARNING;
00138               else if (strstr (status_line, "401"))
00139                      result = STATE_WARNING;
00140               else if (strstr (status_line, "402"))
00141                      result = STATE_WARNING;
00142               else if (strstr (status_line, "403"))
00143                      result = STATE_WARNING;
00144               else if (strstr (status_line, "404"))
00145                      result = STATE_WARNING;
00146 
00147               /* server errors result in a critical state */
00148               else if (strstr (status_line, "500"))
00149                      result = STATE_CRITICAL;
00150               else if (strstr (status_line, "501"))
00151                      result = STATE_CRITICAL;
00152               else if (strstr (status_line, "502"))
00153                      result = STATE_CRITICAL;
00154               else if (strstr (status_line, "503"))
00155                      result = STATE_CRITICAL;
00156 
00157               else
00158                      result = STATE_UNKNOWN;
00159        }
00160 
00161        /* Part II - Check stream exists and is ok */
00162        if ((result == STATE_OK )&& (server_url != NULL) ) {
00163 
00164               /* Part I - Server Check */
00165 
00166               /* send the OPTIONS request */
00167               sprintf (buffer, "DESCRIBE rtsp://%s:%d%s RTSP/1.0\n", host_name,
00168                                            server_port, server_url);
00169               result = send (sd, buffer, strlen (buffer), 0);
00170 
00171               /* send the header sync */
00172               sprintf (buffer, "CSeq: 2\n");
00173               result = send (sd, buffer, strlen (buffer), 0);
00174 
00175               /* send a newline so the server knows we're done with the request */
00176               sprintf (buffer, "\n");
00177               result = send (sd, buffer, strlen (buffer), 0);
00178 
00179               /* watch for the REAL connection string */
00180               result = recv (sd, buffer, MAX_INPUT_BUFFER - 1, 0);
00181 
00182               /* return a CRITICAL status if we couldn't read any data */
00183               if (result == -1) {
00184                      printf (_("No data received from host\n"));
00185                      result = STATE_CRITICAL;
00186               }
00187               else {
00188                      /* make sure we find the response we are looking for */
00189                      if (!strstr (buffer, server_expect)) {
00190                             if (server_port == PORT)
00191                                    printf ("%s\n", _("Invalid REAL response received from host"));
00192                             else
00193                                    printf (_("Invalid REAL response received from host on port %d\n"),
00194                                                                server_port);
00195                      }
00196                      else {
00197 
00198                             /* else we got the REAL string, so check the return code */
00199 
00200                             time (&end_time);
00201 
00202                             result = STATE_OK;
00203 
00204                             status_line = (char *) strtok (buffer, "\n");
00205 
00206                             if (strstr (status_line, "200"))
00207                                    result = STATE_OK;
00208 
00209                             /* client errors result in a warning state */
00210                             else if (strstr (status_line, "400"))
00211                                    result = STATE_WARNING;
00212                             else if (strstr (status_line, "401"))
00213                                    result = STATE_WARNING;
00214                             else if (strstr (status_line, "402"))
00215                                    result = STATE_WARNING;
00216                             else if (strstr (status_line, "403"))
00217                                    result = STATE_WARNING;
00218                             else if (strstr (status_line, "404"))
00219                                    result = STATE_WARNING;
00220 
00221                             /* server errors result in a critical state */
00222                             else if (strstr (status_line, "500"))
00223                                    result = STATE_CRITICAL;
00224                             else if (strstr (status_line, "501"))
00225                                    result = STATE_CRITICAL;
00226                             else if (strstr (status_line, "502"))
00227                                    result = STATE_CRITICAL;
00228                             else if (strstr (status_line, "503"))
00229                                    result = STATE_CRITICAL;
00230 
00231                             else
00232                                    result = STATE_UNKNOWN;
00233                      }
00234               }
00235        }
00236 
00237        /* Return results */
00238        if (result == STATE_OK) {
00239 
00240               if (check_critical_time == TRUE
00241                             && (end_time - start_time) > critical_time) result = STATE_CRITICAL;
00242               else if (check_warning_time == TRUE
00243                                            && (end_time - start_time) > warning_time) result =
00244                             STATE_WARNING;
00245 
00246               /* Put some HTML in here to create a dynamic link */
00247               printf (_("REAL %s - %d second response time\n"),
00248                                           state_text (result),
00249                                           (int) (end_time - start_time));
00250        }
00251        else
00252               printf ("%s\n", status_line);
00253 
00254        /* close the connection */
00255        close (sd);
00256 
00257        /* reset the alarm */
00258        alarm (0);
00259 
00260        return result;
00261 }
00262 
00263 
00264 
00265 /* process command-line arguments */
00266 int
00267 process_arguments (int argc, char **argv)
00268 {
00269        int c;
00270 
00271        int option = 0;
00272        static struct option longopts[] = {
00273               {"hostname", required_argument, 0, 'H'},
00274               {"IPaddress", required_argument, 0, 'I'},
00275               {"expect", required_argument, 0, 'e'},
00276               {"url", required_argument, 0, 'u'},
00277               {"port", required_argument, 0, 'p'},
00278               {"critical", required_argument, 0, 'c'},
00279               {"warning", required_argument, 0, 'w'},
00280               {"timeout", required_argument, 0, 't'},
00281               {"verbose", no_argument, 0, 'v'},
00282               {"version", no_argument, 0, 'V'},
00283               {"help", no_argument, 0, 'h'},
00284               {0, 0, 0, 0}
00285        };
00286 
00287        if (argc < 2)
00288               return ERROR;
00289 
00290        for (c = 1; c < argc; c++) {
00291               if (strcmp ("-to", argv[c]) == 0)
00292                      strcpy (argv[c], "-t");
00293               else if (strcmp ("-wt", argv[c]) == 0)
00294                      strcpy (argv[c], "-w");
00295               else if (strcmp ("-ct", argv[c]) == 0)
00296                      strcpy (argv[c], "-c");
00297        }
00298 
00299        while (1) {
00300               c = getopt_long (argc, argv, "+hvVI:H:e:u:p:w:c:t:", longopts,
00301                                                                 &option);
00302 
00303               if (c == -1 || c == EOF)
00304                      break;
00305 
00306               switch (c) {
00307               case 'I':                                                             /* hostname */
00308               case 'H':                                                             /* hostname */
00309                      if (server_address)
00310                             break;
00311                      else if (is_host (optarg))
00312                             server_address = optarg;
00313                      else
00314                             usage2 (_("Invalid hostname/address"), optarg);
00315                      break;
00316               case 'e':                                                             /* string to expect in response header */
00317                      server_expect = optarg;
00318                      break;
00319               case 'u':                                                             /* server URL */
00320                      server_url = optarg;
00321                      break;
00322               case 'p':                                                             /* port */
00323                      if (is_intpos (optarg)) {
00324                             server_port = atoi (optarg);
00325                      }
00326                      else {
00327                             usage4 (_("Port must be a positive integer"));
00328                      }
00329                      break;
00330               case 'w':                                                             /* warning time threshold */
00331                      if (is_intnonneg (optarg)) {
00332                             warning_time = atoi (optarg);
00333                             check_warning_time = TRUE;
00334                      }
00335                      else {
00336                             usage4 (_("Warning time must be a positive integer"));
00337                      }
00338                      break;
00339               case 'c':                                                             /* critical time threshold */
00340                      if (is_intnonneg (optarg)) {
00341                             critical_time = atoi (optarg);
00342                             check_critical_time = TRUE;
00343                      }
00344                      else {
00345                             usage4 (_("Critical time must be a positive integer"));
00346                      }
00347                      break;
00348               case 'v':                                                             /* verbose */
00349                      verbose = TRUE;
00350                      break;
00351               case 't':                                                             /* timeout */
00352                      if (is_intnonneg (optarg)) {
00353                             socket_timeout = atoi (optarg);
00354                      }
00355                      else {
00356                             usage4 (_("Timeout interval must be a positive integer"));
00357                      }
00358                      break;
00359               case 'V':                                                             /* version */
00360                      print_revision (progname, NP_VERSION);
00361                      exit (STATE_OK);
00362               case 'h':                                                             /* help */
00363                      print_help ();
00364                      exit (STATE_OK);
00365               case '?':                                                             /* usage */
00366                      usage5 ();
00367               }
00368        }
00369 
00370        c = optind;
00371        if (server_address==NULL && argc>c) {
00372               if (is_host (argv[c])) {
00373                      server_address = argv[c++];
00374               }
00375               else {
00376                      usage2 (_("Invalid hostname/address"), argv[c]);
00377               }
00378        }
00379 
00380        if (server_address==NULL)
00381               usage4 (_("You must provide a server to check"));
00382 
00383        if (host_name==NULL)
00384               host_name = strdup (server_address);
00385 
00386        if (server_expect == NULL)
00387               server_expect = strdup(EXPECT);
00388 
00389        return validate_arguments ();
00390 }
00391 
00392 
00393 
00394 int
00395 validate_arguments (void)
00396 {
00397        return OK;
00398 }
00399 
00400 
00401 
00402 void
00403 print_help (void)
00404 {
00405        char *myport;
00406        asprintf (&myport, "%d", PORT);
00407 
00408        print_revision (progname, NP_VERSION);
00409 
00410        printf ("Copyright (c) 1999 Pedro Leite <leite@cic.ua.pt>\n");
00411        printf (COPYRIGHT, copyright, email);
00412 
00413        printf ("%s\n", _("This plugin tests the REAL service on the specified host."));
00414 
00415   printf ("\n\n");
00416 
00417        print_usage ();
00418 
00419        printf (UT_HELP_VRSN);
00420        printf (UT_EXTRA_OPTS);
00421 
00422        printf (UT_HOST_PORT, 'p', myport);
00423 
00424        printf (" %s\n", "-u, --url=STRING");
00425   printf ("    %s\n", _("Connect to this url"));
00426   printf (" %s\n", "-e, --expect=STRING");
00427   printf (_("String to expect in first line of server response (default: %s)\n"),
00428               EXPECT);
00429 
00430        printf (UT_WARN_CRIT);
00431 
00432        printf (UT_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
00433 
00434        printf (UT_VERBOSE);
00435 
00436   printf ("\n");
00437        printf ("%s\n", _("This plugin will attempt to open an RTSP connection with the host."));
00438   printf ("%s\n", _("Successul connects return STATE_OK, refusals and timeouts return"));
00439   printf ("%s\n", _("STATE_CRITICAL, other errors return STATE_UNKNOWN.  Successful connects,"));
00440   printf ("%s\n", _("but incorrect reponse messages from the host result in STATE_WARNING return"));
00441   printf ("%s\n", _("values."));
00442 
00443        printf (UT_SUPPORT);
00444 }
00445 
00446 
00447 
00448 void
00449 print_usage (void)
00450 {
00451   printf ("%s\n", _("Usage:"));
00452        printf ("%s -H host [-e expect] [-p port] [-w warn] [-c crit] [-t timeout] [-v]\n", progname);
00453 }