Code

Fixed passing of quotes in OID for check_snmp (#1985230 - Jan Wagner, patch by John...
authorTon Voon <tonvoon@macbook.local>
Sat, 14 Mar 2009 01:17:50 +0000 (01:17 +0000)
committerTon Voon <tonvoon@macbook.local>
Sat, 14 Mar 2009 01:17:50 +0000 (01:17 +0000)
NEWS
THANKS.in
plugins/Makefile.am
plugins/check_snmp.c
plugins/t/check_snmp.t

diff --git a/NEWS b/NEWS
index 60ecb87d5481f7013990ddfd19fedbaace786aff..5272d4f6ae14bc02137553b51f058dabf36934ba 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -22,6 +22,7 @@ This file documents the major additions and syntax changes between releases.
        Fixed check_http behaviour: all check are now performed as long as a valid response is returned (sf.net #1460312)
        check_http --onredirect=sticky follows using the same IP address (sf.net #2550208)
        Fixed coredump from check_nt when invalid drive is specified (#2179754 - Olli Hauer)
+       Fixed passing of quotes in OID for check_snmp (#1985230 - Jan Wagner, patch by John Barbuto)
 
 1.4.13 25th Sept 2008
        Fix Debian bug #460097: check_http --max-age broken (Hilko Bengen)
index 36fd74f24af0bc68fe5791103099bffa74d8a9ce..7737e17ddfdc96f6333c23a1afa4a9240f9064f9 100644 (file)
--- a/THANKS.in
+++ b/THANKS.in
@@ -247,3 +247,4 @@ Erik Welch
 Nik Soggia
 Olli Hauer
 Richard Edward Horner
+John Barbuto
index f5272e178de1ab4d6d6dac2e02ad866a88643d4e..4e1f21016d2ff7f8071f57da250c22e5aa5bb603 100644 (file)
@@ -93,7 +93,7 @@ check_ping_LDADD = $(NETLIBS) popen.o
 check_procs_LDADD = $(BASEOBJS)
 check_radius_LDADD = $(NETLIBS) $(RADIUSLIBS)
 check_real_LDADD = $(NETLIBS)
-check_snmp_LDADD = $(BASEOBJS) popen.o
+check_snmp_LDADD = $(BASEOBJS)
 check_smtp_LDADD = $(SSLOBJS) $(NETLIBS) $(SSLLIBS)
 check_ssh_LDADD = $(NETLIBS)
 check_swap_LDADD = $(MATHLIBS) $(BASEOBJS) popen.o
@@ -135,7 +135,7 @@ check_ping_DEPENDENCIES = check_ping.c $(NETOBJS) popen.o $(DEPLIBS)
 check_procs_DEPENDENCIES = check_procs.c $(BASEOBJS) popen.o $(DEPLIBS)
 check_radius_DEPENDENCIES = check_radius.c $(NETOBJS)  $(DEPLIBS)
 check_real_DEPENDENCIES = check_real.c $(NETOBJS) $(DEPLIBS)
-check_snmp_DEPENDENCIES = check_snmp.c $(BASEOBJS) popen.o $(DEPLIBS)
+check_snmp_DEPENDENCIES = check_snmp.c $(BASEOBJS) $(DEPLIBS)
 check_smtp_DEPENDENCIES = check_smtp.c $(SSLOBJS) $(NETOBJS) $(DEPLIBS)
 check_ssh_DEPENDENCIES = check_ssh.c $(NETOBJS) $(DEPLIBS)
 check_swap_DEPENDENCIES = check_swap.c $(BASEOBJS) popen.o $(DEPLIBS)
index a8e08fa1ecbc3221894a79f299cf4e5065628dd3..1b1eb2e85f075c6ba699799e667c1a19c0d93a11 100644 (file)
@@ -34,7 +34,7 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net";
 
 #include "common.h"
 #include "utils.h"
-#include "popen.h"
+#include "utils_cmd.h"
 
 #define DEFAULT_COMMUNITY "public"
 #define DEFAULT_PORT "161"
@@ -91,14 +91,14 @@ regex_t preg;
 regmatch_t pmatch[10];
 char timestamp[10] = "";
 char errbuf[MAX_INPUT_BUFFER] = "";
-char perfstr[MAX_INPUT_BUFFER] = "";
+char perfstr[MAX_INPUT_BUFFER] = "";
 int cflags = REG_EXTENDED | REG_NOSUB | REG_NEWLINE;
 int eflags = 0;
 int errcode, excode;
 
 char *server_address = NULL;
 char *community = NULL;
-char *authpriv = NULL;
+char **authpriv = NULL;
 char *proto = NULL;
 char *seclevel = NULL;
 char *secname = NULL;
@@ -106,10 +106,11 @@ char *authproto = NULL;
 char *privproto = NULL;
 char *authpasswd = NULL;
 char *privpasswd = NULL;
-char *oid;
+char **oids = NULL; 
 char *label;
 char *units;
 char *port;
+char *snmpcmd;
 char string_value[MAX_INPUT_BUFFER] = "";
 char **labels = NULL;
 char **unitv = NULL;
@@ -117,6 +118,8 @@ size_t nlabels = 0;
 size_t labels_size = 8;
 size_t nunits = 0;
 size_t unitv_size = 8;
+int numoids = 0;
+int numauthpriv = 0;
 int verbose = FALSE;
 int usesnmpgetnext = FALSE;
 unsigned long long lower_warn_lim[MAX_OIDS];
@@ -139,18 +142,16 @@ main (int argc, char **argv)
 {
        int i = 0;
        int iresult = STATE_UNKNOWN;
-       int found = 0;
-       int result = STATE_DEPENDENT;
-       char input_buffer[MAX_INPUT_BUFFER];
-       char *command_line = NULL;
+       int result = STATE_UNKNOWN;
+       char **command_line = NULL;
        char *cl_hidden_auth = NULL;
+       char *oidname = NULL;
        char *response = NULL;
        char *outbuff;
-       char *output;
        char *ptr = NULL;
-       char *p2 = NULL;
        char *show = NULL;
        char type[8] = "";
+       output chld_out, chld_err;
 
        setlocale (LC_ALL, "");
        bindtextdomain (PACKAGE, LOCALEDIR);
@@ -162,12 +163,10 @@ main (int argc, char **argv)
                eval_method[i] = CHECK_UNDEF;
        i = 0;
 
-       oid = strdup ("");
        label = strdup ("SNMP");
        units = strdup ("");
        port = strdup (DEFAULT_PORT);
        outbuff = strdup ("");
-       output = strdup ("");
        delimiter = strdup (" = ");
        output_delim = strdup (DEFAULT_OUTPUT_DELIMITER);
        /* miblist = strdup (DEFAULT_MIBLIST); */
@@ -180,91 +179,73 @@ main (int argc, char **argv)
        if (process_arguments (argc, argv) == ERROR)
                usage4 (_("Could not parse arguments"));
 
-       /* create the command line to execute */
-               if(usesnmpgetnext == TRUE) {
-               asprintf(&command_line, "%s -t %d -r %d -m %s -v %s %s %s:%s %s",
-                       PATH_TO_SNMPGETNEXT, timeout_interval, retries, miblist, proto,
-                       authpriv, server_address, port, oid);
-               asprintf(&cl_hidden_auth, "%s -t %d -r %d -m %s -v %s %s %s:%s %s",
-                       PATH_TO_SNMPGETNEXT, timeout_interval, retries, miblist, proto,
-                       "[authpriv]", server_address, port, oid);
+       /* Create the command array to execute */
+       if(usesnmpgetnext == TRUE) {
+               snmpcmd = strdup (PATH_TO_SNMPGETNEXT);
        }else{
-
-               asprintf (&command_line, "%s -t %d -r %d -m %s -v %s %s %s:%s %s",
-                       PATH_TO_SNMPGET, timeout_interval, retries, miblist, proto,
-                       authpriv, server_address, port, oid);
-               asprintf(&cl_hidden_auth, "%s -t %d -r %d -m %s -v %s %s %s:%s %s",
-                       PATH_TO_SNMPGET, timeout_interval, retries, miblist, proto,
-                       "[authpriv]", server_address, port, oid);
+               snmpcmd = strdup (PATH_TO_SNMPGET);
+       } 
+       
+        /* 9 arguments to pass before authpriv options + 1 for host and numoids. Add one for terminating NULL */
+       command_line = calloc (9 + numauthpriv + 1 + numoids + 1, sizeof (char *));
+       command_line[0] = snmpcmd;
+       command_line[1] = strdup ("-t");
+       asprintf (&command_line[2], "%d", timeout_interval);
+       command_line[3] = strdup ("-r");
+       asprintf (&command_line[4], "%d", retries);
+       command_line[5] = strdup ("-m");
+       command_line[6] = strdup (miblist);
+       command_line[7] = "-v";
+       command_line[8] = strdup (proto);
+
+       for (i = 0; i < numauthpriv; i++) {
+               command_line[9 + i] = authpriv[i];
        }
 
-       if (verbose)
-               printf ("%s\n", command_line);
-
+       asprintf (&command_line[9 + numauthpriv], "%s:%s", server_address, port);
 
-       /* run the command */
-       child_process = spopen (command_line);
-       if (child_process == NULL) {
-               printf (_("Could not open pipe: %s\n"), cl_hidden_auth);
-               exit (STATE_UNKNOWN);
-       }
+        /* This is just for display purposes, so it can remain a string */
+       asprintf(&cl_hidden_auth, "%s -t %d -r %d -m %s -v %s %s %s:%s",
+               snmpcmd, timeout_interval, retries, miblist, proto, "[authpriv]",
+               server_address, port);
 
-#if 0          /* Removed May 29, 2007 */
-       child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r");
-       if (child_stderr == NULL) {
-               printf (_("Could not open stderr for %s\n"), cl_hidden_auth);
+       for (i = 0; i < numoids; i++) {
+               command_line[9 + numauthpriv + 1 + i] = oids[i];
+               asprintf(&cl_hidden_auth, "%s %s", cl_hidden_auth, oids[i]);    
        }
-#endif
 
-       while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process))
-               asprintf (&output, "%s%s", output, input_buffer);
+       command_line[9 + numauthpriv + 1 + numoids] = NULL;
 
        if (verbose)
-               printf ("%s\n", output);
+               printf ("%s\n", cl_hidden_auth);
 
-       ptr = output;
+       /* Run the command */
+       result = cmd_run_array (command_line, &chld_out, &chld_err, 0);
 
-       strncat(perfstr, "| ", sizeof(perfstr)-strlen(perfstr)-1);
-       while (ptr) {
-               char *foo, *ptr2;
-               unsigned int copylen;
-
-               foo = strstr (ptr, delimiter);
-               copylen = foo-ptr;
-               if (copylen > sizeof(perfstr)-strlen(perfstr)-1)
-                       copylen = sizeof(perfstr)-strlen(perfstr)-1;
-               ptr2 = ptr;
-               ptr = foo;
-
-               if (ptr == NULL)
-                       break;
-
-               ptr += strlen (delimiter);
-               ptr += strspn (ptr, " ");
+       if (chld_err.lines > 0) {
+               printf (_("External command error: %s\n"), chld_err.line[0]);
+               for (i = 1; i < chld_err.lines; i++) {
+                       printf ("%s\n", chld_err.line[i]);
+               }
+               exit (STATE_UNKNOWN);
+       }
 
-               found++;
+       /* Return UNKNOWN or worse if no output is returned */
+       if (chld_out.lines == 0)
+               die (max_state_alt (result, STATE_UNKNOWN), _("%s problem - No data received from host\nCMD: %s\n"),
+                                                               label,
+                                                               cl_hidden_auth);
 
-               if (ptr[0] == '"') {
-                       ptr++;
-                       response = strpcpy (response, ptr, "\"");
-                       ptr = strpbrk (ptr, "\"");
-                       ptr += strspn (ptr, "\"\n");
-               }
-               else {
-                       response = strpcpy (response, ptr, "\n");
-                       ptr = strpbrk (ptr, "\n");
-                       ptr += strspn (ptr, "\n");
-                       while
-                               (strstr (ptr, delimiter) &&
-                                strstr (ptr, "\n") && strstr (ptr, "\n") < strstr (ptr, delimiter)) {
-                               response = strpcat (response, ptr, "\n");
-                               ptr = strpbrk (ptr, "\n");
-                       }
-                       if (ptr && strstr (ptr, delimiter) == NULL) {
-                               asprintf (&response, "%s%s", response, ptr);
-                               ptr = NULL;
-                       }
+       if (verbose) {
+               for (i = 0; i < chld_out.lines; i++) {
+                       printf ("%s\n", chld_out.line[i]);
                }
+       }
+
+       for (i = 0; i < chld_out.lines; i++) {
+               ptr = chld_out.line[i];
+               oidname = strpcpy (oidname, ptr, delimiter); 
+               response = strstr (ptr, delimiter);
 
                /* We strip out the datatype indicator for PHBs */
 
@@ -289,7 +270,6 @@ main (int argc, char **argv)
                        show = strstr (response, "STRING: ") + 8;
                else
                        show = response;
-               p2 = show;
 
                iresult = STATE_DEPENDENT;
 
@@ -306,10 +286,10 @@ main (int argc, char **argv)
                    eval_method[i] & WARN_LE ||
                    eval_method[i] & WARN_EQ ||
                    eval_method[i] & WARN_NE) {
-                       p2 = strpbrk (p2, "0123456789");
-                       if (p2 == NULL)
+                       ptr = strpbrk (show, "0123456789");
+                       if (ptr == NULL)
                                die (STATE_UNKNOWN,_("No valid data returned"));
-                       response_value[i] = strtoul (p2, NULL, 10);
+                       response_value[i] = strtoul (ptr, NULL, 10);
                        iresult = check_num (i);
                        asprintf (&show, "%llu", response_value[i]);
                }
@@ -364,10 +344,8 @@ main (int argc, char **argv)
                if (nunits > (size_t)0 && (size_t)i < nunits && unitv[i] != NULL)
                        asprintf (&outbuff, "%s %s", outbuff, unitv[i]);
 
-               i++;
-
                if (is_numeric(show)) {
-                       strncat(perfstr, ptr2, copylen);
+                       strncat(perfstr, oidname, sizeof(perfstr)-strlen(perfstr)-1);
                        strncat(perfstr, "=", sizeof(perfstr)-strlen(perfstr)-1);
                        strncat(perfstr, show, sizeof(perfstr)-strlen(perfstr)-1);
 
@@ -375,29 +353,6 @@ main (int argc, char **argv)
                                strncat(perfstr, type, sizeof(perfstr)-strlen(perfstr)-1);
                        strncat(perfstr, " ", sizeof(perfstr)-strlen(perfstr)-1);
                }
-
-       }       /* end while (ptr) */
-
-       if (found == 0)
-               die (STATE_UNKNOWN,
-                       _("%s problem - No data received from host\nCMD: %s\n"),
-                       label,
-                       cl_hidden_auth);
-
-#if 0          /* Removed May 29, 2007 */
-       /* WARNING if output found on stderr */
-       if (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr))
-               result = max_state (result, STATE_WARNING);
-
-       /* close stderr */
-       (void) fclose (child_stderr);
-#endif
-
-       /* close the pipe */
-       if (spclose (child_process)) {
-               if (result == STATE_OK)
-                       result = STATE_UNKNOWN;
-               asprintf (&outbuff, "%s (%s)", outbuff, _("snmpget returned an error status"));
        }
 
 /*     if (nunits == 1 || i == 1) */
@@ -563,12 +518,12 @@ process_arguments (int argc, char **argv)
                                         */
                                        needmibs = TRUE;
                        }
-
-                       for (ptr = optarg; (ptr = index (ptr, ',')); ptr++)
-                               ptr[0] = ' '; /* relpace comma with space */
-                       for (ptr = optarg; (ptr = index (ptr, ' ')); ptr++)
-                               j++; /* count OIDs */
-                       asprintf (&oid, "%s %s", (oid?oid:""), optarg);
+                       oids = calloc(MAX_OIDS, sizeof (char *));
+                       for (ptr = strtok(optarg, ", "); ptr != NULL; ptr = strtok(NULL, ", ")) {
+                               oids[j] = strdup(ptr);
+                               j++;
+                       }
+                       numoids = j;
                        if (c == 'E' || c == 'e') {
                                jj++;
                                ii++;
@@ -675,8 +630,6 @@ process_arguments (int argc, char **argv)
        if (community == NULL)
                community = strdup (DEFAULT_COMMUNITY);
 
-
-
        return validate_arguments ();
 }
 
@@ -713,47 +666,79 @@ validate_arguments ()
                }
        }
 
+       /* Check server_address is given */
+       if (server_address == NULL)
+               die(STATE_UNKNOWN, _("No host specified\n"));
 
-       /* Need better checks to verify seclevel and authproto choices */
-
-       if (seclevel == NULL)
-               asprintf (&seclevel, "noAuthNoPriv");
-
-
-       if (authproto == NULL )
-               asprintf(&authproto, DEFAULT_AUTH_PROTOCOL);
-
-       if (privproto == NULL )
-               asprintf(&privproto, DEFAULT_PRIV_PROTOCOL);
+       /* Check oid is given */
+       if (numoids == 0)
+               die(STATE_UNKNOWN, _("No OIDs specified\n"));
 
-       if (proto == NULL || (strcmp(proto,DEFAULT_PROTOCOL) == 0) ) {  /* default protocol version */
+       if (proto == NULL)
                asprintf(&proto, DEFAULT_PROTOCOL);
-               asprintf(&authpriv, "%s%s", "-c ", community);
-       }
-       else if ( strcmp (proto, "2c") == 0 ) {         /* snmpv2c args */
-               asprintf(&authpriv, "%s%s", "-c ", community);
+
+       if ((strcmp(proto,"1") == 0) || (strcmp(proto, "2c")==0)) {     /* snmpv1 or snmpv2c */
+               numauthpriv = 2;
+               authpriv = calloc (numauthpriv, sizeof (char *));
+               authpriv[0] = strdup ("-c");
+               authpriv[1] = strdup (community);
        }
        else if ( strcmp (proto, "3") == 0 ) {          /* snmpv3 args */
-               asprintf(&proto, "%s", "3");
-
-               if ( (strcmp(seclevel, "noAuthNoPriv") == 0) || seclevel == NULL ) {
-                       asprintf(&authpriv, "%s", "-l noAuthNoPriv" );
-               }
-               else if ( strcmp(seclevel, "authNoPriv") == 0 ) {
-                       if ( secname == NULL || authpasswd == NULL) {
-                               printf (_("Missing secname (%s) or authpassword (%s) ! \n"),secname, authpasswd );
-                               print_usage ();
-                               exit (STATE_UNKNOWN);
+               if (seclevel == NULL)
+                       asprintf(&seclevel, "noAuthNoPriv");
+
+               if (strcmp(seclevel, "noAuthNoPriv") == 0) {
+                       numauthpriv = 2;
+                       authpriv = calloc (numauthpriv, sizeof (char *));
+                       authpriv[0] = strdup ("-l");
+                       authpriv[1] = strdup ("noAuthNoPriv");
+               } else {
+                       if (! ( (strcmp(seclevel, "authNoPriv")==0) || (strcmp(seclevel, "authPriv")==0) ) ) {
+                               usage2 (_("Invalid seclevel"), seclevel);
                        }
-                       asprintf(&authpriv, "-l authNoPriv -a %s -u %s -A %s ", authproto, secname, authpasswd);
-               }
-               else if ( strcmp(seclevel, "authPriv") == 0 ) {
-                       if ( secname == NULL || authpasswd == NULL || privpasswd == NULL ) {
-                               printf (_("Missing secname (%s), authpassword (%s), or privpasswd (%s)! \n"),secname, authpasswd,privpasswd );
-                               print_usage ();
-                               exit (STATE_UNKNOWN);
+
+                       if (authproto == NULL )
+                               asprintf(&authproto, DEFAULT_AUTH_PROTOCOL);
+
+                       if (secname == NULL)
+                               die(STATE_UNKNOWN, _("Required parameter: %s\n"), "secname");
+
+                       if (authpasswd == NULL)
+                               die(STATE_UNKNOWN, _("Required parameter: %s\n"), "authpasswd");
+
+                       if ( strcmp(seclevel, "authNoPriv") == 0 ) {
+                               numauthpriv = 8;
+                               authpriv = calloc (numauthpriv, sizeof (char *));
+                               authpriv[0] = strdup ("-l");
+                               authpriv[1] = strdup ("authNoPriv");
+                               authpriv[2] = strdup ("-a");
+                               authpriv[3] = strdup (authproto);
+                               authpriv[4] = strdup ("-u");
+                               authpriv[5] = strdup (secname);
+                               authpriv[6] = strdup ("-A");
+                               authpriv[7] = strdup (authpasswd);
+                       } else if ( strcmp(seclevel, "authPriv") == 0 ) {
+                               if (privproto == NULL )
+                                       asprintf(&privproto, DEFAULT_PRIV_PROTOCOL);
+
+                               if (privpasswd == NULL)
+                                       die(STATE_UNKNOWN, _("Required parameter: %s\n"), "privpasswd");
+
+                               numauthpriv = 12;
+                               authpriv = calloc (numauthpriv, sizeof (char *));
+                               authpriv[0] = strdup ("-l");
+                               authpriv[1] = strdup ("authPriv");
+                               authpriv[2] = strdup ("-a");
+                               authpriv[3] = strdup (authproto);
+                               authpriv[4] = strdup ("-u");
+                               authpriv[5] = strdup (secname);
+                               authpriv[6] = strdup ("-A");
+                               authpriv[7] = strdup (authpasswd);
+                               authpriv[8] = strdup ("-x");
+                               authpriv[9] = strdup (privproto);
+                               authpriv[10] = strdup ("-X");
+                               authpriv[11] = strdup (privpasswd);
                        }
-                       asprintf(&authpriv, "-l authPriv -a %s -u %s -A %s -x %s -X %s ", authproto, secname, authpasswd, privproto, privpasswd);
                }
 
        }
index 369314ec6e6265d01a7a19723956a86be993f6de..4820aace81a698300a40031a7deabeaf40871f89 100644 (file)
@@ -8,9 +8,8 @@ use strict;
 use Test::More;
 use NPTest;
 
-use vars qw($tests);
-BEGIN {$tests = 14; plan tests => $tests}
-
+my $tests = 32;
+plan tests => $tests;
 my $res;
 
 SKIP: {
@@ -20,7 +19,7 @@ SKIP: {
                                           "A host providing an SNMP Service");
 
        my $snmp_community = getTestParameter( "snmp_community",     "NP_SNMP_COMMUNITY", "public",
-                                           "The SNMP Community string for SNMP Testing" );
+                                           "The SNMP Community string for SNMP Testing (assumes snmp v1)" );
 
        my $host_nonresponsive = getTestParameter( "host_nonresponsive", "NP_HOST_NONRESPONSIVE", "10.0.0.1",
                                                   "The hostname of system not responsive to network requests" );
@@ -28,12 +27,32 @@ SKIP: {
        my $hostname_invalid   = getTestParameter( "hostname_invalid",   "NP_HOSTNAME_INVALID",   "nosuchhost",
                                                   "An invalid (not known to DNS) hostname" );
 
+       $res = NPTest->testCmd( "./check_snmp -t 1" );
+       is( $res->return_code, 3, "No host name" );
+       is( $res->output, "No host specified" );
+       
+       $res = NPTest->testCmd( "./check_snmp -H fakehostname" );
+       is( $res->return_code, 3, "No OIDs specified" );
+       is( $res->output, "No OIDs specified" );
+
+       $res = NPTest->testCmd( "./check_snmp -H fakehost -o oids -P 3 --seclevel=rubbish" );
+       is( $res->return_code, 3, "Invalid seclevel" );
+       like( $res->output, "/check_snmp: Invalid seclevel - rubbish/" );
+
+       $res = NPTest->testCmd( "./check_snmp -H fakehost -o oids -P 3c" );
+       is( $res->return_code, 3, "Invalid protocol" );
+       like( $res->output, "/check_snmp: Invalid SNMP version - 3c/" );
+
        SKIP: {
-               skip "no snmp host defined", 10 if ( ! $host_snmp );
+               skip "no snmp host defined", 20 if ( ! $host_snmp );
 
                $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o system.sysUpTime.0 -w 1: -c 1:");
                cmp_ok( $res->return_code, '==', 0, "Exit OK when querying uptime" ); 
-               like($res->output, '/^SNMP OK - \d+/', "String contains SNMP OK");
+               like($res->output, '/^SNMP OK - (\d+)/', "String contains SNMP OK");
+               $res->output =~ /^SNMP OK - (\d+)/;
+               my $value = $1;
+               cmp_ok( $value, ">", 0, "Got a time value" );
+               like($res->perf_output, "/sysUpTime.*$1/", "Got perfdata with value '$1' in it");
 
                $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o system.sysDescr.0");
                cmp_ok( $res->return_code, '==', 0, "Exit OK when querying sysDescr" ); 
@@ -49,21 +68,33 @@ SKIP: {
 
                $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w  :0 -c 0");
                cmp_ok( $res->return_code, '==', 2, "Exit CRITICAL when querying hrSWRunIndex.1 and crit-th doesn't apply" ); 
-               like($res->output, '/^SNMP CRITICAL - \*1\*\s.*$/', "String matches SNMP CRITICAL and ouput format");
+               like($res->output, '/^SNMP CRITICAL - \*1\*\s.*$/', "String matches SNMP CRITICAL and output format");
+
+               $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o ifIndex.2,ifIndex.1 -w 1:2 -c 1:2");
+               cmp_ok( $res->return_code, '==', 0, "Checking two OIDs at once" );
+               like($res->output, "/^SNMP OK - 2 1/", "Got two values back" );
+               like( $res->perf_output, "/ifIndex.2=2/", "Got 1st perf data" );
+               like( $res->perf_output, "/ifIndex.1=1/", "Got 2nd perf data" );
+
+               $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o ifIndex.2,ifIndex.1 -w 1:2,1:2 -c 2:2,2:2");
+               cmp_ok( $res->return_code, '==', 2, "Checking critical threshold is passed if any one value crosses" );
+               like($res->output, "/^SNMP CRITICAL - 2 *1*/", "Got two values back" );
+               like( $res->perf_output, "/ifIndex.2=2/", "Got 1st perf data" );
+               like( $res->perf_output, "/ifIndex.1=1/", "Got 2nd perf data" );
        }
 
        SKIP: {
                skip "no non responsive host defined", 2 if ( ! $host_nonresponsive );
                $res = NPTest->testCmd( "./check_snmp -H $host_nonresponsive -C $snmp_community -o system.sysUpTime.0 -w 1: -c 1:");
                cmp_ok( $res->return_code, '==', 3, "Exit UNKNOWN with non responsive host" ); 
-               like($res->output, '/SNMP problem - /', "String matches SNMP Problem");
+               like($res->output, '/External command error: Timeout: No Response from /', "String matches timeout problem");
        }
 
        SKIP: {
                skip "no non invalid host defined", 2 if ( ! $hostname_invalid );
                $res = NPTest->testCmd( "./check_snmp -H $hostname_invalid   -C $snmp_community -o system.sysUpTime.0 -w 1: -c 1:");
                cmp_ok( $res->return_code, '==', 3, "Exit UNKNOWN with non responsive host" ); 
-               like($res->output, '/SNMP problem - /', "String matches SNMP Problem");
+               like($res->output, '/External command error: .*nosuchhost/', "String matches invalid host");
        }
 
 }