summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plugins/check_snmp.c84
-rwxr-xr-xplugins/tests/check_snmp.t12
2 files changed, 70 insertions, 26 deletions
diff --git a/plugins/check_snmp.c b/plugins/check_snmp.c
index 2601ccd8..d407609f 100644
--- a/plugins/check_snmp.c
+++ b/plugins/check_snmp.c
@@ -1,31 +1,31 @@
1/***************************************************************************** 1/*****************************************************************************
2* 2*
3* Monitoring check_snmp plugin 3* Monitoring check_snmp plugin
4* 4*
5* License: GPL 5* License: GPL
6* Copyright (c) 1999-2007 Monitoring Plugins Development Team 6* Copyright (c) 1999-2007 Monitoring Plugins Development Team
7* 7*
8* Description: 8* Description:
9* 9*
10* This file contains the check_snmp plugin 10* This file contains the check_snmp plugin
11* 11*
12* Check status of remote machines and obtain system information via SNMP 12* Check status of remote machines and obtain system information via SNMP
13* 13*
14* 14*
15* This program is free software: you can redistribute it and/or modify 15* This program is free software: you can redistribute it and/or modify
16* it under the terms of the GNU General Public License as published by 16* it under the terms of the GNU General Public License as published by
17* the Free Software Foundation, either version 3 of the License, or 17* the Free Software Foundation, either version 3 of the License, or
18* (at your option) any later version. 18* (at your option) any later version.
19* 19*
20* This program is distributed in the hope that it will be useful, 20* This program is distributed in the hope that it will be useful,
21* but WITHOUT ANY WARRANTY; without even the implied warranty of 21* but WITHOUT ANY WARRANTY; without even the implied warranty of
22* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23* GNU General Public License for more details. 23* GNU General Public License for more details.
24* 24*
25* You should have received a copy of the GNU General Public License 25* You should have received a copy of the GNU General Public License
26* along with this program. If not, see <http://www.gnu.org/licenses/>. 26* along with this program. If not, see <http://www.gnu.org/licenses/>.
27* 27*
28* 28*
29*****************************************************************************/ 29*****************************************************************************/
30 30
31const char *progname = "check_snmp"; 31const char *progname = "check_snmp";
@@ -90,6 +90,7 @@ char *thisarg (char *str);
90char *nextarg (char *str); 90char *nextarg (char *str);
91void print_usage (void); 91void print_usage (void);
92void print_help (void); 92void print_help (void);
93char *multiply (char *str);
93 94
94#include "regex.h" 95#include "regex.h"
95char regex_expect[MAX_INPUT_BUFFER] = ""; 96char regex_expect[MAX_INPUT_BUFFER] = "";
@@ -154,6 +155,8 @@ double *previous_value;
154size_t previous_size = OID_COUNT_STEP; 155size_t previous_size = OID_COUNT_STEP;
155int perf_labels = 1; 156int perf_labels = 1;
156char* ip_version = ""; 157char* ip_version = "";
158double multiplier = 1.0;
159char *fmtstr = "";
157 160
158static char *fix_snmp_range(char *th) 161static char *fix_snmp_range(char *th)
159{ 162{
@@ -316,7 +319,7 @@ main (int argc, char **argv)
316 for (i = 0; i < numcontext; i++) { 319 for (i = 0; i < numcontext; i++) {
317 command_line[10 + i] = contextargs[i]; 320 command_line[10 + i] = contextargs[i];
318 } 321 }
319 322
320 for (i = 0; i < numauthpriv; i++) { 323 for (i = 0; i < numauthpriv; i++) {
321 command_line[10 + numcontext + i] = authpriv[i]; 324 command_line[10 + numcontext + i] = authpriv[i];
322 } 325 }
@@ -330,7 +333,7 @@ main (int argc, char **argv)
330 333
331 for (i = 0; i < numoids; i++) { 334 for (i = 0; i < numoids; i++) {
332 command_line[10 + numcontext + numauthpriv + 1 + i] = oids[i]; 335 command_line[10 + numcontext + numauthpriv + 1 + i] = oids[i];
333 xasprintf(&cl_hidden_auth, "%s %s", cl_hidden_auth, oids[i]); 336 xasprintf(&cl_hidden_auth, "%s %s", cl_hidden_auth, oids[i]);
334 } 337 }
335 338
336 command_line[10 + numcontext + numauthpriv + 1 + numoids] = NULL; 339 command_line[10 + numcontext + numauthpriv + 1 + numoids] = NULL;
@@ -398,15 +401,15 @@ main (int argc, char **argv)
398 is_counter=0; 401 is_counter=0;
399 /* We strip out the datatype indicator for PHBs */ 402 /* We strip out the datatype indicator for PHBs */
400 if (strstr (response, "Gauge: ")) { 403 if (strstr (response, "Gauge: ")) {
401 show = strstr (response, "Gauge: ") + 7; 404 show = multiply (strstr (response, "Gauge: ") + 7);
402 } 405 }
403 else if (strstr (response, "Gauge32: ")) { 406 else if (strstr (response, "Gauge32: ")) {
404 show = strstr (response, "Gauge32: ") + 9; 407 show = multiply (strstr (response, "Gauge32: ") + 9);
405 } 408 }
406 else if (strstr (response, "Counter32: ")) { 409 else if (strstr (response, "Counter32: ")) {
407 show = strstr (response, "Counter32: ") + 11; 410 show = strstr (response, "Counter32: ") + 11;
408 is_counter=1; 411 is_counter=1;
409 if(!calculate_rate) 412 if(!calculate_rate)
410 strcpy(type, "c"); 413 strcpy(type, "c");
411 } 414 }
412 else if (strstr (response, "Counter64: ")) { 415 else if (strstr (response, "Counter64: ")) {
@@ -416,7 +419,10 @@ main (int argc, char **argv)
416 strcpy(type, "c"); 419 strcpy(type, "c");
417 } 420 }
418 else if (strstr (response, "INTEGER: ")) { 421 else if (strstr (response, "INTEGER: ")) {
419 show = strstr (response, "INTEGER: ") + 9; 422 show = multiply (strstr (response, "INTEGER: ") + 9);
423 if (fmtstr != "") {
424 conv = fmtstr;
425 }
420 } 426 }
421 else if (strstr (response, "OID: ")) { 427 else if (strstr (response, "OID: ")) {
422 show = strstr (response, "OID: ") + 5; 428 show = strstr (response, "OID: ") + 5;
@@ -616,7 +622,7 @@ main (int argc, char **argv)
616 state_string=malloc(string_length); 622 state_string=malloc(string_length);
617 if(state_string==NULL) 623 if(state_string==NULL)
618 die(STATE_UNKNOWN, _("Cannot malloc")); 624 die(STATE_UNKNOWN, _("Cannot malloc"));
619 625
620 current_length=0; 626 current_length=0;
621 for(i=0; i<total_oids; i++) { 627 for(i=0; i<total_oids; i++) {
622 xasprintf(&temp_string,"%.0f",response_value[i]); 628 xasprintf(&temp_string,"%.0f",response_value[i]);
@@ -638,7 +644,7 @@ main (int argc, char **argv)
638 state_string[--current_length]='\0'; 644 state_string[--current_length]='\0';
639 if (verbose > 2) 645 if (verbose > 2)
640 printf("State string=%s\n",state_string); 646 printf("State string=%s\n",state_string);
641 647
642 /* This is not strictly the same as time now, but any subtle variations will cancel out */ 648 /* This is not strictly the same as time now, but any subtle variations will cancel out */
643 np_state_write_string(current_time, state_string ); 649 np_state_write_string(current_time, state_string );
644 if(previous_state==NULL) { 650 if(previous_state==NULL) {
@@ -698,6 +704,8 @@ process_arguments (int argc, char **argv)
698 {"perf-oids", no_argument, 0, 'O'}, 704 {"perf-oids", no_argument, 0, 'O'},
699 {"ipv4", no_argument, 0, '4'}, 705 {"ipv4", no_argument, 0, '4'},
700 {"ipv6", no_argument, 0, '6'}, 706 {"ipv6", no_argument, 0, '6'},
707 {"multiplier", required_argument, 0, 'M'},
708 {"fmtstr", required_argument, 0, 'f'},
701 {0, 0, 0, 0} 709 {0, 0, 0, 0}
702 }; 710 };
703 711
@@ -715,7 +723,7 @@ process_arguments (int argc, char **argv)
715 } 723 }
716 724
717 while (1) { 725 while (1) {
718 c = getopt_long (argc, argv, "nhvVO46t:c:w:H:C:o:e:E:d:D:s:t:R:r:l:u:p:m:P:N:L:U:a:x:A:X:z:", 726 c = getopt_long (argc, argv, "nhvVO46t:c:w:H:C:o:e:E:d:D:s:t:R:r:l:u:p:m:P:N:L:U:a:x:A:X:M:f:z:",
719 longopts, &option); 727 longopts, &option);
720 728
721 if (c == -1 || c == EOF) 729 if (c == -1 || c == EOF)
@@ -953,6 +961,16 @@ process_arguments (int argc, char **argv)
953 if(verbose>2) 961 if(verbose>2)
954 printf("IPv6 detected! Will pass \"udp6:\" to snmpget.\n"); 962 printf("IPv6 detected! Will pass \"udp6:\" to snmpget.\n");
955 break; 963 break;
964 case 'M':
965 if ( strspn( optarg, "0123456789.," ) == strlen( optarg ) ) {
966 multiplier=strtod(optarg,NULL);
967 }
968 break;
969 case 'f':
970 if (multiplier != 1.0) {
971 fmtstr=optarg;
972 }
973 break;
956 } 974 }
957 } 975 }
958 976
@@ -1022,7 +1040,7 @@ validate_arguments ()
1022 contextargs[0] = strdup ("-n"); 1040 contextargs[0] = strdup ("-n");
1023 contextargs[1] = strdup (context); 1041 contextargs[1] = strdup (context);
1024 } 1042 }
1025 1043
1026 if (seclevel == NULL) 1044 if (seclevel == NULL)
1027 xasprintf(&seclevel, "noAuthNoPriv"); 1045 xasprintf(&seclevel, "noAuthNoPriv");
1028 1046
@@ -1143,6 +1161,21 @@ nextarg (char *str)
1143 1161
1144 1162
1145 1163
1164/* multiply result (values 0 < n < 1 work as divider) */
1165char *
1166multiply (char *str)
1167{
1168 double val = strtod (str, NULL);
1169 val *= multiplier;
1170 if (val == (int)val) {
1171 sprintf(str, "%.0f", val);
1172 } else {
1173 sprintf(str, "%f", val);
1174 }
1175 return str;
1176}
1177
1178
1146void 1179void
1147print_help (void) 1180print_help (void)
1148{ 1181{
@@ -1235,6 +1268,10 @@ print_help (void)
1235 printf (" %s\n", _("Units label(s) for output data (e.g., 'sec.').")); 1268 printf (" %s\n", _("Units label(s) for output data (e.g., 'sec.')."));
1236 printf (" %s\n", "-D, --output-delimiter=STRING"); 1269 printf (" %s\n", "-D, --output-delimiter=STRING");
1237 printf (" %s\n", _("Separates output on multiple OID requests")); 1270 printf (" %s\n", _("Separates output on multiple OID requests"));
1271 printf (" %s\n", "-M, --multiplier=FLOAT");
1272 printf (" %s\n", _("Multiplies current value, 0 < n < 1 works as divider, defaults to 1"));
1273 printf (" %s\n", "-f, --fmtstr=STRING");
1274 printf (" %s\n", _("C-style format string for float values (see option -M)"));
1238 1275
1239 printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); 1276 printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
1240 printf (" %s\n", _("NOTE the final timeout value is calculated using this formula: timeout_interval * retries + 5")); 1277 printf (" %s\n", _("NOTE the final timeout value is calculated using this formula: timeout_interval * retries + 5"));
@@ -1287,4 +1324,5 @@ print_usage (void)
1287 printf ("[-l label] [-u units] [-p port-number] [-d delimiter] [-D output-delimiter]\n"); 1324 printf ("[-l label] [-u units] [-p port-number] [-d delimiter] [-D output-delimiter]\n");
1288 printf ("[-m miblist] [-P snmp version] [-N context] [-L seclevel] [-U secname]\n"); 1325 printf ("[-m miblist] [-P snmp version] [-N context] [-L seclevel] [-U secname]\n");
1289 printf ("[-a authproto] [-A authpasswd] [-x privproto] [-X privpasswd] [-4|6]\n"); 1326 printf ("[-a authproto] [-A authpasswd] [-x privproto] [-X privpasswd] [-4|6]\n");
1327 printf ("[-M multiplier [-f format]]\n");
1290} 1328}
diff --git a/plugins/tests/check_snmp.t b/plugins/tests/check_snmp.t
index 0a77fa8a..e9cc0213 100755
--- a/plugins/tests/check_snmp.t
+++ b/plugins/tests/check_snmp.t
@@ -9,7 +9,7 @@ use NPTest;
9use FindBin qw($Bin); 9use FindBin qw($Bin);
10use POSIX qw/strftime/; 10use POSIX qw/strftime/;
11 11
12my $tests = 73; 12my $tests = 75;
13# Check that all dependent modules are available 13# Check that all dependent modules are available
14eval { 14eval {
15 require NetSNMP::OID; 15 require NetSNMP::OID;
@@ -57,9 +57,9 @@ if ($pid) {
57 exec("snmpd -c tests/conf/snmpd.conf -C -f -r udp:$port_snmp"); 57 exec("snmpd -c tests/conf/snmpd.conf -C -f -r udp:$port_snmp");
58} 58}
59 59
60END { 60END {
61 foreach my $pid (@pids) { 61 foreach my $pid (@pids) {
62 if ($pid) { print "Killing $pid\n"; kill "INT", $pid } 62 if ($pid) { print "Killing $pid\n"; kill "INT", $pid }
63 } 63 }
64}; 64};
65 65
@@ -268,3 +268,9 @@ like($res->output, '/SNMP WARNING - \d+ \*-4\* | iso.3.6.1.4.1.8072.3.2.67.10=\d
268$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10,.1.3.6.1.4.1.8072.3.2.67.17 -w 1,2 -c 1" ); 268$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10,.1.3.6.1.4.1.8072.3.2.67.17 -w 1,2 -c 1" );
269is($res->return_code, 2, "Multiple OIDs with some thresholds" ); 269is($res->return_code, 2, "Multiple OIDs with some thresholds" );
270like($res->output, '/SNMP CRITICAL - \*\d+\* \*-4\* | iso.3.6.1.4.1.8072.3.2.67.10=\d+c;1;2 iso.3.6.1.4.1.8072.3.2.67.17=-4;;/', "Multiple OIDs with thresholds output" ); 270like($res->output, '/SNMP CRITICAL - \*\d+\* \*-4\* | iso.3.6.1.4.1.8072.3.2.67.10=\d+c;1;2 iso.3.6.1.4.1.8072.3.2.67.17=-4;;/', "Multiple OIDs with thresholds output" );
271
272$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.2.1.25.2.2.0 -M .125 ");
273is($res->return_code, 0, "Multiply OK" );
274
275$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.2.1.25.2.2.0 --multiplier=.0009765625 -f '%.3f' ");
276is($res->return_code, 0, "Multiply format OK" );