summaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/Makefile.am99
-rw-r--r--plugins/check_apt.c12
-rw-r--r--plugins/check_dig.c2
-rw-r--r--plugins/check_disk.c37
-rw-r--r--plugins/check_dns.c2
-rw-r--r--plugins/check_fping.c78
-rw-r--r--plugins/check_http.c185
-rw-r--r--plugins/check_ide_smart.c109
-rw-r--r--plugins/check_mysql.c154
-rw-r--r--plugins/check_nagios.c16
-rw-r--r--plugins/check_nt.c16
-rw-r--r--plugins/check_ntp_peer.c32
-rw-r--r--plugins/check_pgsql.c236
-rw-r--r--plugins/check_procs.c77
-rw-r--r--plugins/check_smtp.c26
-rw-r--r--plugins/check_snmp.c53
-rw-r--r--plugins/check_tcp.c25
-rw-r--r--plugins/check_users.c45
-rw-r--r--plugins/common.h10
-rw-r--r--plugins/netutils.h2
-rw-r--r--plugins/runcmd.c2
-rw-r--r--plugins/runcmd.h2
-rw-r--r--plugins/sslutils.c13
-rw-r--r--plugins/t/check_apt.t4
-rw-r--r--plugins/t/check_http.t32
-rw-r--r--plugins/t/check_procs.t6
-rw-r--r--plugins/t/check_snmp.t293
-rw-r--r--plugins/t/check_tcp.t6
-rwxr-xr-xplugins/tests/check_http.t13
29 files changed, 1192 insertions, 395 deletions
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 0eb0255..031dd25 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -39,15 +39,19 @@ EXTRA_PROGRAMS = check_mysql check_radius check_pgsql check_snmp check_hpjd \
39 check_nagios check_by_ssh check_dns check_nt check_ide_smart \ 39 check_nagios check_by_ssh check_dns check_nt check_ide_smart \
40 check_procs check_mysql_query check_apt check_dbi 40 check_procs check_mysql_query check_apt check_dbi
41 41
42EXTRA_DIST = t tests utils.c netutils.c sslutils.c popen.c utils.h netutils.h \ 42EXTRA_DIST = t tests
43 popen.h common.h runcmd.c runcmd.h
44 43
45PLUGINHDRS = common.h 44PLUGINHDRS = common.h
46 45
47BASEOBJS = utils.o ../lib/libnagiosplug.a ../gl/libgnu.a 46noinst_LIBRARIES = libnpcommon.a
48NETOBJS = netutils.o $(BASEOBJS) $(EXTRA_NETOBJS) 47
49SSLOBJS = sslutils.o 48libnpcommon_a_SOURCES = utils.c netutils.c sslutils.c runcmd.c \
49 popen.c utils.h netutils.h popen.h common.h runcmd.c runcmd.h
50
51BASEOBJS = libnpcommon.a ../lib/libnagiosplug.a ../gl/libgnu.a
52NETOBJS = $(BASEOBJS) $(EXTRA_NETOBLS)
50NETLIBS = $(NETOBJS) $(SOCKETLIBS) 53NETLIBS = $(NETOBJS) $(SOCKETLIBS)
54SSLOBJS = $(BASEOBJS) $(NETLIBS) $(SSLLIBS)
51 55
52TESTS_ENVIRONMENT = perl -I $(top_builddir) -I $(top_srcdir) 56TESTS_ENVIRONMENT = perl -I $(top_builddir) -I $(top_srcdir)
53 57
@@ -62,19 +66,19 @@ test-debug:
62############################################################################## 66##############################################################################
63# the actual targets 67# the actual targets
64 68
65check_apt_LDADD = $(BASEOBJS) runcmd.o 69check_apt_LDADD = $(BASEOBJS)
66check_cluster_LDADD = $(BASEOBJS) 70check_cluster_LDADD = $(BASEOBJS)
67check_dbi_LDADD = $(NETLIBS) $(DBILIBS) 71check_dbi_LDADD = $(NETLIBS) $(DBILIBS)
68check_dig_LDADD = $(NETLIBS) runcmd.o 72check_dig_LDADD = $(NETLIBS)
69check_disk_LDADD = $(BASEOBJS) popen.o 73check_disk_LDADD = $(BASEOBJS)
70check_dns_LDADD = $(NETLIBS) runcmd.o 74check_dns_LDADD = $(NETLIBS)
71check_dummy_LDADD = $(BASEOBJS) 75check_dummy_LDADD = $(BASEOBJS)
72check_fping_LDADD = $(NETLIBS) popen.o 76check_fping_LDADD = $(NETLIBS)
73check_game_LDADD = $(BASEOBJS) runcmd.o 77check_game_LDADD = $(BASEOBJS)
74check_http_LDADD = $(SSLOBJS) $(NETLIBS) $(SSLLIBS) 78check_http_LDADD = $(SSLOBJS)
75check_hpjd_LDADD = $(NETLIBS) popen.o 79check_hpjd_LDADD = $(NETLIBS)
76check_ldap_LDADD = $(NETLIBS) $(LDAPLIBS) 80check_ldap_LDADD = $(NETLIBS) $(LDAPLIBS)
77check_load_LDADD = $(BASEOBJS) popen.o 81check_load_LDADD = $(BASEOBJS)
78check_mrtg_LDADD = $(BASEOBJS) 82check_mrtg_LDADD = $(BASEOBJS)
79check_mrtgtraf_LDADD = $(BASEOBJS) 83check_mrtgtraf_LDADD = $(BASEOBJS)
80check_mysql_CFLAGS = $(MYSQLCFLAGS) -DNP_VERSION='"$(NP_VERSION)"' 84check_mysql_CFLAGS = $(MYSQLCFLAGS) -DNP_VERSION='"$(NP_VERSION)"'
@@ -83,22 +87,22 @@ check_mysql_LDADD = $(NETLIBS) $(MYSQLLIBS)
83check_mysql_query_CFLAGS = $(MYSQLCFLAGS) -DNP_VERSION='"$(NP_VERSION)"' 87check_mysql_query_CFLAGS = $(MYSQLCFLAGS) -DNP_VERSION='"$(NP_VERSION)"'
84check_mysql_query_CPPFLAGS = $(MYSQLINCLUDE) 88check_mysql_query_CPPFLAGS = $(MYSQLINCLUDE)
85check_mysql_query_LDADD = $(NETLIBS) $(MYSQLLIBS) 89check_mysql_query_LDADD = $(NETLIBS) $(MYSQLLIBS)
86check_nagios_LDADD = $(BASEOBJS) runcmd.o 90check_nagios_LDADD = $(BASEOBJS)
87check_nt_LDADD = $(NETLIBS) 91check_nt_LDADD = $(NETLIBS)
88check_ntp_LDADD = $(NETLIBS) $(MATHLIBS) 92check_ntp_LDADD = $(NETLIBS) $(MATHLIBS)
89check_ntp_peer_LDADD = $(NETLIBS) $(MATHLIBS) 93check_ntp_peer_LDADD = $(NETLIBS) $(MATHLIBS)
90check_nwstat_LDADD = $(NETLIBS) 94check_nwstat_LDADD = $(NETLIBS)
91check_overcr_LDADD = $(NETLIBS) 95check_overcr_LDADD = $(NETLIBS)
92check_pgsql_LDADD = $(NETLIBS) $(PGLIBS) 96check_pgsql_LDADD = $(NETLIBS) $(PGLIBS)
93check_ping_LDADD = $(NETLIBS) popen.o 97check_ping_LDADD = $(NETLIBS)
94check_procs_LDADD = $(BASEOBJS) 98check_procs_LDADD = $(BASEOBJS)
95check_radius_LDADD = $(NETLIBS) $(RADIUSLIBS) 99check_radius_LDADD = $(NETLIBS) $(RADIUSLIBS)
96check_real_LDADD = $(NETLIBS) 100check_real_LDADD = $(NETLIBS)
97check_snmp_LDADD = $(BASEOBJS) 101check_snmp_LDADD = $(BASEOBJS)
98check_smtp_LDADD = $(SSLOBJS) $(NETLIBS) $(SSLLIBS) 102check_smtp_LDADD = $(SSLOBJS)
99check_ssh_LDADD = $(NETLIBS) 103check_ssh_LDADD = $(NETLIBS)
100check_swap_LDADD = $(MATHLIBS) $(BASEOBJS) popen.o 104check_swap_LDADD = $(MATHLIBS) $(BASEOBJS)
101check_tcp_LDADD = $(SSLOBJS) $(NETLIBS) $(SSLLIBS) 105check_tcp_LDADD = $(SSLOBJS)
102check_time_LDADD = $(NETLIBS) 106check_time_LDADD = $(NETLIBS)
103check_ntp_time_LDADD = $(NETLIBS) $(MATHLIBS) 107check_ntp_time_LDADD = $(NETLIBS) $(MATHLIBS)
104check_ups_LDADD = $(NETLIBS) 108check_ups_LDADD = $(NETLIBS)
@@ -106,62 +110,15 @@ check_users_LDADD = $(BASEOBJS)
106check_by_ssh_LDADD = $(NETLIBS) 110check_by_ssh_LDADD = $(NETLIBS)
107check_ide_smart_LDADD = $(BASEOBJS) 111check_ide_smart_LDADD = $(BASEOBJS)
108negate_LDADD = $(BASEOBJS) 112negate_LDADD = $(BASEOBJS)
109urlize_LDADD = $(BASEOBJS) popen.o 113urlize_LDADD = $(BASEOBJS)
110 114
111check_apt_DEPENDENCIES = check_apt.c $(BASEOBJS) runcmd.o $(DEPLIBS) 115if !HAVE_UTMPX
112check_cluster_DEPENDENCIES = check_cluster.c $(BASEOBJS) $(DEPLIBS) 116check_users_LDADD += popen.o
113check_dbi_DEPENDENCIES = check_dbi.c $(NETOBJS) $(DEPLIBS) 117endif
114check_dig_DEPENDENCIES = check_dig.c $(NETOBJS) runcmd.o $(DEPLIBS)
115check_disk_DEPENDENCIES = check_disk.c $(BASEOBJS) popen.o $(DEPLIBS)
116check_dns_DEPENDENCIES = check_dns.c $(NETOBJS) runcmd.o $(DEPLIBS)
117check_dummy_DEPENDENCIES = check_dummy.c $(DEPLIBS)
118check_fping_DEPENDENCIES = check_fping.c $(NETOBJS) popen.o $(DEPLIBS)
119check_game_DEPENDENCIES = check_game.c $(DEPLIBS) runcmd.o
120check_http_DEPENDENCIES = check_http.c $(SSLOBJS) $(NETOBJS) $(DEPLIBS)
121check_hpjd_DEPENDENCIES = check_hpjd.c $(NETOBJS) popen.o $(DEPLIBS)
122check_ide_smart_DEPENDENCIES = check_ide_smart.c $(BASEOBJS) $(DEPLIBS)
123check_ldap_DEPENDENCIES = check_ldap.c $(NETOBJS) $(DEPLIBS)
124check_load_DEPENDENCIES = check_load.c $(BASEOBJS) popen.o $(DEPLIBS)
125check_mrtg_DEPENDENCIES = check_mrtg.c $(DEPLIBS)
126check_mrtgtraf_DEPENDENCIES = check_mrtgtraf.c $(DEPLIBS)
127check_mysql_DEPENDENCIES = check_mysql.c $(NETOBJS) $(DEPLIBS)
128check_mysql_query_DEPENDENCIES = check_mysql_query.c $(NETOBJS) $(DEPLIBS)
129check_nagios_DEPENDENCIES = check_nagios.c $(BASEOBJS) runcmd.o $(DEPLIBS)
130check_nt_DEPENDENCIES = check_nt.c $(NETOBJS) $(DEPLIBS)
131check_ntp_DEPENDENCIES = check_ntp.c $(NETOBJS) $(DEPLIBS)
132check_ntp_peer_DEPENDENCIES = check_ntp_peer.c $(NETOBJS) $(DEPLIBS)
133check_nwstat_DEPENDENCIES = check_nwstat.c $(NETOBJS) $(DEPLIBS)
134check_overcr_DEPENDENCIES = check_overcr.c $(NETOBJS) $(DEPLIBS)
135check_pgsql_DEPENDENCIES = check_pgsql.c $(NETOBJS) $(DEPLIBS)
136check_ping_DEPENDENCIES = check_ping.c $(NETOBJS) popen.o $(DEPLIBS)
137check_procs_DEPENDENCIES = check_procs.c $(BASEOBJS) popen.o $(DEPLIBS)
138check_radius_DEPENDENCIES = check_radius.c $(NETOBJS) $(DEPLIBS)
139check_real_DEPENDENCIES = check_real.c $(NETOBJS) $(DEPLIBS)
140check_snmp_DEPENDENCIES = check_snmp.c $(BASEOBJS) $(DEPLIBS)
141check_smtp_DEPENDENCIES = check_smtp.c $(SSLOBJS) $(NETOBJS) $(DEPLIBS)
142check_ssh_DEPENDENCIES = check_ssh.c $(NETOBJS) $(DEPLIBS)
143check_swap_DEPENDENCIES = check_swap.c $(BASEOBJS) popen.o $(DEPLIBS)
144check_tcp_DEPENDENCIES = check_tcp.c $(SSLOBJS) $(NETOBJS) $(DEPLIBS)
145check_time_DEPENDENCIES = check_time.c $(NETOBJS) $(DEPLIBS)
146check_ntp_time_DEPENDENCIES = check_ntp_time.c $(NETOBJS) $(DEPLIBS)
147check_ups_DEPENDENCIES = check_ups.c $(NETOBJS) $(DEPLIBS)
148check_users_DEPENDENCIES = check_users.c $(BASEOBJS) popen.o $(DEPLIBS)
149check_by_ssh_DEPENDENCIES = check_by_ssh.c $(NETOBJS) $(DEPLIBS)
150negate_DEPENDENCIES = negate.c $(BASEOBJS) $(DEPLIBS)
151urlize_DEPENDENCIES = urlize.c $(BASEOBJS) popen.o $(DEPLIBS)
152 118
153############################################################################## 119##############################################################################
154# secondary dependencies 120# secondary dependencies
155 121
156popen.o: popen.c popen.h $(PLUGINHDRS)
157
158runcmd.o: runcmd.c runcmd.h $(PLUGINHDRS)
159
160utils.o: utils.c utils.h $(PLUGINHDRS)
161
162netutils.o: netutils.c netutils.h $(PLUGINHDRS)
163sslutils.o: sslutils.c netutils.h $(PLUGINHDRS)
164
165all-local: $(check_tcp_programs) 122all-local: $(check_tcp_programs)
166 123
167$(check_tcp_programs): check_tcp 124$(check_tcp_programs): check_tcp
diff --git a/plugins/check_apt.c b/plugins/check_apt.c
index cf18661..daeb757 100644
--- a/plugins/check_apt.c
+++ b/plugins/check_apt.c
@@ -112,11 +112,11 @@ int main (int argc, char **argv) {
112 result = max_state(result, STATE_CRITICAL); 112 result = max_state(result, STATE_CRITICAL);
113 } else if(packages_available > 0){ 113 } else if(packages_available > 0){
114 result = max_state(result, STATE_WARNING); 114 result = max_state(result, STATE_WARNING);
115 } else { 115 } else if(result > STATE_UNKNOWN){
116 result = max_state(result, STATE_OK); 116 result = STATE_UNKNOWN;
117 } 117 }
118 118
119 printf(_("APT %s: %d packages available for %s (%d critical updates). %s%s%s%s\n"), 119 printf(_("APT %s: %d packages available for %s (%d critical updates). %s%s%s%s|available_upgrades=%d;;;0 critical_updates=%d;;;0\n"),
120 state_text(result), 120 state_text(result),
121 packages_available, 121 packages_available,
122 (upgrade==DIST_UPGRADE)?"dist-upgrade":"upgrade", 122 (upgrade==DIST_UPGRADE)?"dist-upgrade":"upgrade",
@@ -124,7 +124,9 @@ int main (int argc, char **argv) {
124 (stderr_warning)?" warnings detected":"", 124 (stderr_warning)?" warnings detected":"",
125 (stderr_warning && exec_warning)?",":"", 125 (stderr_warning && exec_warning)?",":"",
126 (exec_warning)?" errors detected":"", 126 (exec_warning)?" errors detected":"",
127 (stderr_warning||exec_warning)?". run with -v for information.":"" 127 (stderr_warning||exec_warning)?". run with -v for information.":"",
128 packages_available,
129 sec_count
128 ); 130 );
129 131
130 return result; 132 return result;
@@ -444,7 +446,7 @@ print_help (void)
444 printf (" %s\n", _("Do not run the upgrade. Probably not useful (without -u at least).")); 446 printf (" %s\n", _("Do not run the upgrade. Probably not useful (without -u at least)."));
445 printf (" %s\n", "-i, --include=REGEXP"); 447 printf (" %s\n", "-i, --include=REGEXP");
446 printf (" %s\n", _("Include only packages matching REGEXP. Can be specified multiple times")); 448 printf (" %s\n", _("Include only packages matching REGEXP. Can be specified multiple times"));
447 printf (" %s\n", _("the values will be combined together. Any patches matching this list")); 449 printf (" %s\n", _("the values will be combined together. Any packages matching this list"));
448 printf (" %s\n", _("cause the plugin to return WARNING status. Others will be ignored.")); 450 printf (" %s\n", _("cause the plugin to return WARNING status. Others will be ignored."));
449 printf (" %s\n", _("Default is to include all packages.")); 451 printf (" %s\n", _("Default is to include all packages."));
450 printf (" %s\n", "-e, --exclude=REGEXP"); 452 printf (" %s\n", "-e, --exclude=REGEXP");
diff --git a/plugins/check_dig.c b/plugins/check_dig.c
index 3c80cb7..c113d87 100644
--- a/plugins/check_dig.c
+++ b/plugins/check_dig.c
@@ -78,7 +78,7 @@ main (int argc, char **argv)
78 textdomain (PACKAGE); 78 textdomain (PACKAGE);
79 79
80 /* Set signal handling and alarm */ 80 /* Set signal handling and alarm */
81 if (signal (SIGALRM, popen_timeout_alarm_handler) == SIG_ERR) 81 if (signal (SIGALRM, runcmd_timeout_alarm_handler) == SIG_ERR)
82 usage_va(_("Cannot catch SIGALRM")); 82 usage_va(_("Cannot catch SIGALRM"));
83 83
84 /* Parse extra opts if any */ 84 /* Parse extra opts if any */
diff --git a/plugins/check_disk.c b/plugins/check_disk.c
index 6ba7bdf..47dc0ad 100644
--- a/plugins/check_disk.c
+++ b/plugins/check_disk.c
@@ -91,9 +91,12 @@ static int stat_remote_fs = 0;
91 91
92/* Linked list of filesystem types to omit. 92/* Linked list of filesystem types to omit.
93 If the list is empty, don't exclude any types. */ 93 If the list is empty, don't exclude any types. */
94
95static struct name_list *fs_exclude_list; 94static struct name_list *fs_exclude_list;
96 95
96/* Linked list of filesystem types to check.
97 If the list is empty, include all types. */
98static struct name_list *fs_include_list;
99
97static struct name_list *dp_exclude_list; 100static struct name_list *dp_exclude_list;
98 101
99static struct parameter_list *path_select_list = NULL; 102static struct parameter_list *path_select_list = NULL;
@@ -135,6 +138,7 @@ int verbose = 0;
135int erronly = FALSE; 138int erronly = FALSE;
136int display_mntp = FALSE; 139int display_mntp = FALSE;
137int exact_match = FALSE; 140int exact_match = FALSE;
141int freespace_ignore_reserved = FALSE;
138char *warn_freespace_units = NULL; 142char *warn_freespace_units = NULL;
139char *crit_freespace_units = NULL; 143char *crit_freespace_units = NULL;
140char *warn_freespace_percent = NULL; 144char *warn_freespace_percent = NULL;
@@ -255,6 +259,9 @@ main (int argc, char **argv)
255 (np_find_name (dp_exclude_list, me->me_devname) || 259 (np_find_name (dp_exclude_list, me->me_devname) ||
256 np_find_name (dp_exclude_list, me->me_mountdir))) { 260 np_find_name (dp_exclude_list, me->me_mountdir))) {
257 continue; 261 continue;
262 /* Skip not included fstypes */
263 } else if (fs_include_list && !np_find_name (fs_include_list, me->me_type)) {
264 continue;
258 } 265 }
259 266
260 stat_path(path); 267 stat_path(path);
@@ -419,11 +426,13 @@ process_arguments (int argc, char **argv)
419 {"partition", required_argument, 0, 'p'}, 426 {"partition", required_argument, 0, 'p'},
420 {"exclude_device", required_argument, 0, 'x'}, 427 {"exclude_device", required_argument, 0, 'x'},
421 {"exclude-type", required_argument, 0, 'X'}, 428 {"exclude-type", required_argument, 0, 'X'},
429 {"include-type", required_argument, 0, 'N'},
422 {"group", required_argument, 0, 'g'}, 430 {"group", required_argument, 0, 'g'},
423 {"eregi-path", required_argument, 0, 'R'}, 431 {"eregi-path", required_argument, 0, 'R'},
424 {"eregi-partition", required_argument, 0, 'R'}, 432 {"eregi-partition", required_argument, 0, 'R'},
425 {"ereg-path", required_argument, 0, 'r'}, 433 {"ereg-path", required_argument, 0, 'r'},
426 {"ereg-partition", required_argument, 0, 'r'}, 434 {"ereg-partition", required_argument, 0, 'r'},
435 {"freespace-ignore-reserved", no_argument, 0, 'f'},
427 {"ignore-ereg-path", required_argument, 0, 'i'}, 436 {"ignore-ereg-path", required_argument, 0, 'i'},
428 {"ignore-ereg-partition", required_argument, 0, 'i'}, 437 {"ignore-ereg-partition", required_argument, 0, 'i'},
429 {"ignore-eregi-path", required_argument, 0, 'I'}, 438 {"ignore-eregi-path", required_argument, 0, 'I'},
@@ -452,7 +461,7 @@ process_arguments (int argc, char **argv)
452 strcpy (argv[c], "-t"); 461 strcpy (argv[c], "-t");
453 462
454 while (1) { 463 while (1) {
455 c = getopt_long (argc, argv, "+?VqhveCt:c:w:K:W:u:p:x:X:mklLg:R:r:i:I:MEA", longopts, &option); 464 c = getopt_long (argc, argv, "+?VqhvefCt:c:w:K:W:u:p:x:X:N:mklLg:R:r:i:I:MEA", longopts, &option);
456 465
457 if (c == -1 || c == EOF) 466 if (c == -1 || c == EOF)
458 break; 467 break;
@@ -591,6 +600,9 @@ process_arguments (int argc, char **argv)
591 case 'X': /* exclude file system type */ 600 case 'X': /* exclude file system type */
592 np_add_name(&fs_exclude_list, optarg); 601 np_add_name(&fs_exclude_list, optarg);
593 break; 602 break;
603 case 'N': /* include file system type */
604 np_add_name(&fs_include_list, optarg);
605 break;
594 case 'v': /* verbose */ 606 case 'v': /* verbose */
595 verbose++; 607 verbose++;
596 break; 608 break;
@@ -606,6 +618,9 @@ process_arguments (int argc, char **argv)
606 die (STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), _("Must set -E before selecting paths\n")); 618 die (STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), _("Must set -E before selecting paths\n"));
607 exact_match = TRUE; 619 exact_match = TRUE;
608 break; 620 break;
621 case 'f':
622 freespace_ignore_reserved = TRUE;
623 break;
609 case 'g': 624 case 'g':
610 if (path_selected) 625 if (path_selected)
611 die (STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), _("Must set group value before selecting paths\n")); 626 die (STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), _("Must set group value before selecting paths\n"));
@@ -871,6 +886,8 @@ print_help (void)
871 printf (" %s\n", _("For paths or partitions specified with -p, only check for exact paths")); 886 printf (" %s\n", _("For paths or partitions specified with -p, only check for exact paths"));
872 printf (" %s\n", "-e, --errors-only"); 887 printf (" %s\n", "-e, --errors-only");
873 printf (" %s\n", _("Display only devices/mountpoints with errors")); 888 printf (" %s\n", _("Display only devices/mountpoints with errors"));
889 printf (" %s\n", "-f, --freespace-ignore-reserved");
890 printf (" %s\n", _("Don't account root-reserved blocks into freespace in perfdata"));
874 printf (" %s\n", "-g, --group=NAME"); 891 printf (" %s\n", "-g, --group=NAME");
875 printf (" %s\n", _("Group paths. Thresholds apply to (free-)space of all partitions together")); 892 printf (" %s\n", _("Group paths. Thresholds apply to (free-)space of all partitions together"));
876 printf (" %s\n", "-k, --kilobytes"); 893 printf (" %s\n", "-k, --kilobytes");
@@ -900,6 +917,8 @@ print_help (void)
900 printf (UT_VERBOSE); 917 printf (UT_VERBOSE);
901 printf (" %s\n", "-X, --exclude-type=TYPE"); 918 printf (" %s\n", "-X, --exclude-type=TYPE");
902 printf (" %s\n", _("Ignore all filesystems of indicated type (may be repeated)")); 919 printf (" %s\n", _("Ignore all filesystems of indicated type (may be repeated)"));
920 printf (" %s\n", "-N, --include-type=TYPE");
921 printf (" %s\n", _("Check only filesystems of indicated type (may be repeated)"));
903 922
904 printf ("\n"); 923 printf ("\n");
905 printf ("%s\n", _("Examples:")); 924 printf ("%s\n", _("Examples:"));
@@ -921,8 +940,8 @@ print_usage (void)
921{ 940{
922 printf ("%s\n", _("Usage:")); 941 printf ("%s\n", _("Usage:"));
923 printf (" %s -w limit -c limit [-W limit] [-K limit] {-p path | -x device}\n", progname); 942 printf (" %s -w limit -c limit [-W limit] [-K limit] {-p path | -x device}\n", progname);
924 printf ("[-C] [-E] [-e] [-g group ] [-k] [-l] [-M] [-m] [-R path ] [-r path ]\n"); 943 printf ("[-C] [-E] [-e] [-f] [-g group ] [-k] [-l] [-M] [-m] [-R path ] [-r path ]\n");
925 printf ("[-t timeout] [-u unit] [-v] [-X type]\n"); 944 printf ("[-t timeout] [-u unit] [-v] [-X type] [-N type]\n");
926} 945}
927 946
928void 947void
@@ -994,13 +1013,19 @@ get_stats (struct parameter_list *p, struct fs_usage *fsp) {
994 1013
995void 1014void
996get_path_stats (struct parameter_list *p, struct fs_usage *fsp) { 1015get_path_stats (struct parameter_list *p, struct fs_usage *fsp) {
997 p->total = fsp->fsu_blocks;
998 /* 2007-12-08 - Workaround for Gnulib reporting insanely high available 1016 /* 2007-12-08 - Workaround for Gnulib reporting insanely high available
999 * space on BSD (the actual value should be negative but fsp->fsu_bavail 1017 * space on BSD (the actual value should be negative but fsp->fsu_bavail
1000 * is unsigned) */ 1018 * is unsigned) */
1001 p->available = fsp->fsu_bavail > fsp->fsu_bfree ? 0 : fsp->fsu_bavail; 1019 p->available = fsp->fsu_bavail > fsp->fsu_bfree ? 0 : fsp->fsu_bavail;
1002 p->available_to_root = fsp->fsu_bfree; 1020 p->available_to_root = fsp->fsu_bfree;
1003 p->used = p->total - p->available_to_root; 1021 p->used = fsp->fsu_blocks - fsp->fsu_bfree;
1022 if (freespace_ignore_reserved) {
1023 /* option activated : we substract the root-reserved space from the total */
1024 p->total = fsp->fsu_blocks - p->available_to_root + p->available;
1025 } else {
1026 /* default behaviour : take all the blocks into account */
1027 p->total = fsp->fsu_blocks;
1028 }
1004 1029
1005 p->dused_units = p->used*fsp->fsu_blocksize/mult; 1030 p->dused_units = p->used*fsp->fsu_blocksize/mult;
1006 p->dfree_units = p->available*fsp->fsu_blocksize/mult; 1031 p->dfree_units = p->available*fsp->fsu_blocksize/mult;
diff --git a/plugins/check_dns.c b/plugins/check_dns.c
index 91af730..ac6cfc3 100644
--- a/plugins/check_dns.c
+++ b/plugins/check_dns.c
@@ -91,7 +91,7 @@ main (int argc, char **argv)
91 textdomain (PACKAGE); 91 textdomain (PACKAGE);
92 92
93 /* Set signal handling and alarm */ 93 /* Set signal handling and alarm */
94 if (signal (SIGALRM, popen_timeout_alarm_handler) == SIG_ERR) { 94 if (signal (SIGALRM, runcmd_timeout_alarm_handler) == SIG_ERR) {
95 usage_va(_("Cannot catch SIGALRM")); 95 usage_va(_("Cannot catch SIGALRM"));
96 } 96 }
97 97
diff --git a/plugins/check_fping.c b/plugins/check_fping.c
index 675a547..c7cce97 100644
--- a/plugins/check_fping.c
+++ b/plugins/check_fping.c
@@ -52,6 +52,8 @@ void print_help (void);
52void print_usage (void); 52void print_usage (void);
53 53
54char *server_name = NULL; 54char *server_name = NULL;
55char *sourceip = NULL;
56char *sourceif = NULL;
55int packet_size = PACKET_SIZE; 57int packet_size = PACKET_SIZE;
56int packet_count = PACKET_COUNT; 58int packet_count = PACKET_COUNT;
57int target_timeout = 0; 59int target_timeout = 0;
@@ -72,6 +74,8 @@ main (int argc, char **argv)
72/* normaly should be int result = STATE_UNKNOWN; */ 74/* normaly should be int result = STATE_UNKNOWN; */
73 75
74 int status = STATE_UNKNOWN; 76 int status = STATE_UNKNOWN;
77 int result = 0;
78 char *fping_prog = NULL;
75 char *server = NULL; 79 char *server = NULL;
76 char *command_line = NULL; 80 char *command_line = NULL;
77 char *input_buffer = NULL; 81 char *input_buffer = NULL;
@@ -95,8 +99,21 @@ main (int argc, char **argv)
95 xasprintf(&option_string, "%s-t %d ", option_string, target_timeout); 99 xasprintf(&option_string, "%s-t %d ", option_string, target_timeout);
96 if (packet_interval) 100 if (packet_interval)
97 xasprintf(&option_string, "%s-p %d ", option_string, packet_interval); 101 xasprintf(&option_string, "%s-p %d ", option_string, packet_interval);
98 102 if (sourceip)
99 xasprintf (&command_line, "%s %s-b %d -c %d %s", PATH_TO_FPING, 103 xasprintf(&option_string, "%s-S %s ", option_string, sourceip);
104 if (sourceif)
105 xasprintf(&option_string, "%s-I %s ", option_string, sourceif);
106
107#ifdef PATH_TO_FPING6
108 if (address_family == AF_INET6)
109 fping_prog = strdup(PATH_TO_FPING6);
110 else
111 fping_prog = strdup(PATH_TO_FPING);
112#else
113 fping_prog = strdup(PATH_TO_FPING);
114#endif
115
116 xasprintf (&command_line, "%s %s-b %d -c %d %s", fping_prog,
100 option_string, packet_size, packet_count, server); 117 option_string, packet_size, packet_count, server);
101 118
102 if (verbose) 119 if (verbose)
@@ -130,10 +147,24 @@ main (int argc, char **argv)
130 (void) fclose (child_stderr); 147 (void) fclose (child_stderr);
131 148
132 /* close the pipe */ 149 /* close the pipe */
133 if (spclose (child_process)) 150 if (result = spclose (child_process))
134 /* need to use max_state not max */ 151 /* need to use max_state not max */
135 status = max_state (status, STATE_WARNING); 152 status = max_state (status, STATE_WARNING);
136 153
154 if (result > 1 ) {
155 status = max_state (status, STATE_UNKNOWN);
156 if (result == 2) {
157 die (STATE_UNKNOWN, _("FPING UNKNOWN - IP address not found\n"));
158 }
159 if (result == 3) {
160 die (STATE_UNKNOWN, _("FPING UNKNOWN - invalid commandline argument\n"));
161 }
162 if (result == 4) {
163 die (STATE_UNKNOWN, _("FPING UNKNOWN - failed system call\n"));
164 }
165
166 }
167
137 printf ("FPING %s - %s\n", state_text (status), server_name); 168 printf ("FPING %s - %s\n", state_text (status), server_name);
138 169
139 return status; 170 return status;
@@ -159,6 +190,10 @@ textscan (char *buf)
159 "host"); 190 "host");
160 191
161 } 192 }
193 else if (strstr (buf, "Operation not permitted") || strstr (buf, "No such device") ) {
194 die (STATE_UNKNOWN, _("FPING UNKNOWN - %s parameter error\n"),
195 "host");
196 }
162 else if (strstr (buf, "is down")) { 197 else if (strstr (buf, "is down")) {
163 die (STATE_CRITICAL, _("FPING CRITICAL - %s is down\n"), server_name); 198 die (STATE_CRITICAL, _("FPING CRITICAL - %s is down\n"), server_name);
164 199
@@ -232,6 +267,8 @@ process_arguments (int argc, char **argv)
232 int option = 0; 267 int option = 0;
233 static struct option longopts[] = { 268 static struct option longopts[] = {
234 {"hostname", required_argument, 0, 'H'}, 269 {"hostname", required_argument, 0, 'H'},
270 {"sourceip", required_argument, 0, 'S'},
271 {"sourceif", required_argument, 0, 'I'},
235 {"critical", required_argument, 0, 'c'}, 272 {"critical", required_argument, 0, 'c'},
236 {"warning", required_argument, 0, 'w'}, 273 {"warning", required_argument, 0, 'w'},
237 {"bytes", required_argument, 0, 'b'}, 274 {"bytes", required_argument, 0, 'b'},
@@ -241,6 +278,8 @@ process_arguments (int argc, char **argv)
241 {"verbose", no_argument, 0, 'v'}, 278 {"verbose", no_argument, 0, 'v'},
242 {"version", no_argument, 0, 'V'}, 279 {"version", no_argument, 0, 'V'},
243 {"help", no_argument, 0, 'h'}, 280 {"help", no_argument, 0, 'h'},
281 {"use-ipv4", no_argument, 0, '4'},
282 {"use-ipv6", no_argument, 0, '6'},
244 {0, 0, 0, 0} 283 {0, 0, 0, 0}
245 }; 284 };
246 285
@@ -258,7 +297,7 @@ process_arguments (int argc, char **argv)
258 } 297 }
259 298
260 while (1) { 299 while (1) {
261 c = getopt_long (argc, argv, "+hVvH:c:w:b:n:T:i:", longopts, &option); 300 c = getopt_long (argc, argv, "+hVvH:S:c:w:b:n:T:i:I:46", longopts, &option);
262 301
263 if (c == -1 || c == EOF || c == 1) 302 if (c == -1 || c == EOF || c == 1)
264 break; 303 break;
@@ -281,6 +320,24 @@ process_arguments (int argc, char **argv)
281 } 320 }
282 server_name = strscpy (server_name, optarg); 321 server_name = strscpy (server_name, optarg);
283 break; 322 break;
323 case 'S': /* sourceip */
324 if (is_host (optarg) == FALSE) {
325 usage2 (_("Invalid hostname/address"), optarg);
326 }
327 sourceip = strscpy (sourceip, optarg);
328 break;
329 case 'I': /* sourceip */
330 sourceif = strscpy (sourceif, optarg);
331 case '4': /* IPv4 only */
332 address_family = AF_INET;
333 break;
334 case '6': /* IPv6 only */
335#ifdef USE_IPV6
336 address_family = AF_INET6;
337#else
338 usage (_("IPv6 support not available\n"));
339#endif
340 break;
284 case 'c': 341 case 'c':
285 get_threshold (optarg, rv); 342 get_threshold (optarg, rv);
286 if (rv[RTA]) { 343 if (rv[RTA]) {
@@ -402,6 +459,8 @@ print_help (void)
402 printf (UT_HELP_VRSN); 459 printf (UT_HELP_VRSN);
403 printf (UT_EXTRA_OPTS); 460 printf (UT_EXTRA_OPTS);
404 461
462 printf (UT_IPv46);
463
405 printf (" %s\n", "-H, --hostname=HOST"); 464 printf (" %s\n", "-H, --hostname=HOST");
406 printf (" %s\n", _("name or IP Address of host to ping (IP Address bypasses name lookup, reducing system load)")); 465 printf (" %s\n", _("name or IP Address of host to ping (IP Address bypasses name lookup, reducing system load)"));
407 printf (" %s\n", "-w, --warning=THRESHOLD"); 466 printf (" %s\n", "-w, --warning=THRESHOLD");
@@ -413,15 +472,22 @@ print_help (void)
413 printf (" %s\n", "-n, --number=INTEGER"); 472 printf (" %s\n", "-n, --number=INTEGER");
414 printf (" %s (default: %d)\n", _("number of ICMP packets to send"),PACKET_COUNT); 473 printf (" %s (default: %d)\n", _("number of ICMP packets to send"),PACKET_COUNT);
415 printf (" %s\n", "-T, --target-timeout=INTEGER"); 474 printf (" %s\n", "-T, --target-timeout=INTEGER");
416 printf (" %s (default: fping's default for -t)\n", _("Target timeout (ms)"),PACKET_COUNT); 475 printf (" %s (default: fping's default for -t)\n", _("Target timeout (ms)"));
417 printf (" %s\n", "-i, --interval=INTEGER"); 476 printf (" %s\n", "-i, --interval=INTEGER");
418 printf (" %s (default: fping's default for -p)\n", _("Interval (ms) between sending packets"),PACKET_COUNT); 477 printf (" %s (default: fping's default for -p)\n", _("Interval (ms) between sending packets"));
478 printf (" %s\n", "-S, --sourceip=HOST");
479 printf (" %s\n", _("name or IP Address of sourceip"));
480 printf (" %s\n", "-I, --sourceif=IF");
481 printf (" %s\n", _("source interface name"));
419 printf (UT_VERBOSE); 482 printf (UT_VERBOSE);
420 printf ("\n"); 483 printf ("\n");
421 printf (" %s\n", _("THRESHOLD is <rta>,<pl>%% where <rta> is the round trip average travel time (ms)")); 484 printf (" %s\n", _("THRESHOLD is <rta>,<pl>%% where <rta> is the round trip average travel time (ms)"));
422 printf (" %s\n", _("which triggers a WARNING or CRITICAL state, and <pl> is the percentage of")); 485 printf (" %s\n", _("which triggers a WARNING or CRITICAL state, and <pl> is the percentage of"));
423 printf (" %s\n", _("packet loss to trigger an alarm state.")); 486 printf (" %s\n", _("packet loss to trigger an alarm state."));
424 487
488 printf ("\n");
489 printf (" %s\n", _("IPv4 is used by default. Specify -6 to use IPv6."));
490
425 printf (UT_SUPPORT); 491 printf (UT_SUPPORT);
426} 492}
427 493
diff --git a/plugins/check_http.c b/plugins/check_http.c
index 9231a55..1576601 100644
--- a/plugins/check_http.c
+++ b/plugins/check_http.c
@@ -1,40 +1,40 @@
1/***************************************************************************** 1/*****************************************************************************
2* 2*
3* Nagios check_http plugin 3* Nagios check_http plugin
4* 4*
5* License: GPL 5* License: GPL
6* Copyright (c) 1999-2008 Nagios Plugins Development Team 6* Copyright (c) 1999-2013 Nagios Plugins Development Team
7* 7*
8* Description: 8* Description:
9* 9*
10* This file contains the check_http plugin 10* This file contains the check_http plugin
11* 11*
12* This plugin tests the HTTP service on the specified host. It can test 12* This plugin tests the HTTP service on the specified host. It can test
13* normal (http) and secure (https) servers, follow redirects, search for 13* normal (http) and secure (https) servers, follow redirects, search for
14* strings and regular expressions, check connection times, and report on 14* strings and regular expressions, check connection times, and report on
15* certificate expiration times. 15* certificate expiration times.
16* 16*
17* 17*
18* This program is free software: you can redistribute it and/or modify 18* This program is free software: you can redistribute it and/or modify
19* it under the terms of the GNU General Public License as published by 19* it under the terms of the GNU General Public License as published by
20* the Free Software Foundation, either version 3 of the License, or 20* the Free Software Foundation, either version 3 of the License, or
21* (at your option) any later version. 21* (at your option) any later version.
22* 22*
23* This program is distributed in the hope that it will be useful, 23* This program is distributed in the hope that it will be useful,
24* but WITHOUT ANY WARRANTY; without even the implied warranty of 24* but WITHOUT ANY WARRANTY; without even the implied warranty of
25* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26* GNU General Public License for more details. 26* GNU General Public License for more details.
27* 27*
28* You should have received a copy of the GNU General Public License 28* You should have received a copy of the GNU General Public License
29* along with this program. If not, see <http://www.gnu.org/licenses/>. 29* along with this program. If not, see <http://www.gnu.org/licenses/>.
30* 30*
31* 31*
32*****************************************************************************/ 32*****************************************************************************/
33 33
34/* splint -I. -I../../plugins -I../../lib/ -I/usr/kerberos/include/ ../../plugins/check_http.c */ 34/* splint -I. -I../../plugins -I../../lib/ -I/usr/kerberos/include/ ../../plugins/check_http.c */
35 35
36const char *progname = "check_http"; 36const char *progname = "check_http";
37const char *copyright = "1999-2011"; 37const char *copyright = "1999-2013";
38const char *email = "nagiosplug-devel@lists.sourceforge.net"; 38const char *email = "nagiosplug-devel@lists.sourceforge.net";
39 39
40#include "common.h" 40#include "common.h"
@@ -43,7 +43,6 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net";
43#include "base64.h" 43#include "base64.h"
44#include <ctype.h> 44#include <ctype.h>
45 45
46#define INPUT_DELIMITER ";"
47#define STICKY_NONE 0 46#define STICKY_NONE 0
48#define STICKY_HOST 1 47#define STICKY_HOST 1
49#define STICKY_PORT 2 48#define STICKY_PORT 2
@@ -85,6 +84,7 @@ int errcode;
85int invert_regex = 0; 84int invert_regex = 0;
86 85
87struct timeval tv; 86struct timeval tv;
87struct timeval tv_temp;
88 88
89#define HTTP_URL "/" 89#define HTTP_URL "/"
90#define CRLF "\r\n" 90#define CRLF "\r\n"
@@ -100,7 +100,9 @@ char *user_agent;
100int server_url_length; 100int server_url_length;
101int server_expect_yn = 0; 101int server_expect_yn = 0;
102char server_expect[MAX_INPUT_BUFFER] = HTTP_EXPECT; 102char server_expect[MAX_INPUT_BUFFER] = HTTP_EXPECT;
103char header_expect[MAX_INPUT_BUFFER] = "";
103char string_expect[MAX_INPUT_BUFFER] = ""; 104char string_expect[MAX_INPUT_BUFFER] = "";
105char output_header_search[30] = "";
104char output_string_search[30] = ""; 106char output_string_search[30] = "";
105char *warning_thresholds = NULL; 107char *warning_thresholds = NULL;
106char *critical_thresholds = NULL; 108char *critical_thresholds = NULL;
@@ -115,6 +117,7 @@ int followsticky = STICKY_NONE;
115int use_ssl = FALSE; 117int use_ssl = FALSE;
116int use_sni = FALSE; 118int use_sni = FALSE;
117int verbose = FALSE; 119int verbose = FALSE;
120int show_extended_perfdata = FALSE;
118int sd; 121int sd;
119int min_page_len = 0; 122int min_page_len = 0;
120int max_page_len = 0; 123int max_page_len = 0;
@@ -124,6 +127,8 @@ char *http_method;
124char *http_post_data; 127char *http_post_data;
125char *http_content_type; 128char *http_content_type;
126char buffer[MAX_INPUT_BUFFER]; 129char buffer[MAX_INPUT_BUFFER];
130char *client_cert = NULL;
131char *client_privkey = NULL;
127 132
128int process_arguments (int, char **); 133int process_arguments (int, char **);
129int check_http (void); 134int check_http (void);
@@ -131,6 +136,11 @@ void redir (char *pos, char *status_line);
131int server_type_check(const char *type); 136int server_type_check(const char *type);
132int server_port_check(int ssl_flag); 137int server_port_check(int ssl_flag);
133char *perfd_time (double microsec); 138char *perfd_time (double microsec);
139char *perfd_time_connect (double microsec);
140char *perfd_time_ssl (double microsec);
141char *perfd_time_firstbyte (double microsec);
142char *perfd_time_headers (double microsec);
143char *perfd_time_transfer (double microsec);
134char *perfd_size (int page_len); 144char *perfd_size (int page_len);
135void print_help (void); 145void print_help (void);
136void print_usage (void); 146void print_usage (void);
@@ -170,7 +180,14 @@ main (int argc, char **argv)
170 return result; 180 return result;
171} 181}
172 182
173 183/* check whether a file exists */
184void
185test_file (char *path)
186{
187 if (access(path, R_OK) == 0)
188 return;
189 usage2 (_("file does not exist or is not readable"), path);
190}
174 191
175/* process command-line arguments */ 192/* process command-line arguments */
176int 193int
@@ -199,6 +216,7 @@ process_arguments (int argc, char **argv)
199 {"port", required_argument, 0, 'p'}, 216 {"port", required_argument, 0, 'p'},
200 {"authorization", required_argument, 0, 'a'}, 217 {"authorization", required_argument, 0, 'a'},
201 {"proxy_authorization", required_argument, 0, 'b'}, 218 {"proxy_authorization", required_argument, 0, 'b'},
219 {"header-string", required_argument, 0, 'd'},
202 {"string", required_argument, 0, 's'}, 220 {"string", required_argument, 0, 's'},
203 {"expect", required_argument, 0, 'e'}, 221 {"expect", required_argument, 0, 'e'},
204 {"regex", required_argument, 0, 'r'}, 222 {"regex", required_argument, 0, 'r'},
@@ -207,6 +225,8 @@ process_arguments (int argc, char **argv)
207 {"linespan", no_argument, 0, 'l'}, 225 {"linespan", no_argument, 0, 'l'},
208 {"onredirect", required_argument, 0, 'f'}, 226 {"onredirect", required_argument, 0, 'f'},
209 {"certificate", required_argument, 0, 'C'}, 227 {"certificate", required_argument, 0, 'C'},
228 {"client-cert", required_argument, 0, 'J'},
229 {"private-key", required_argument, 0, 'K'},
210 {"useragent", required_argument, 0, 'A'}, 230 {"useragent", required_argument, 0, 'A'},
211 {"header", required_argument, 0, 'k'}, 231 {"header", required_argument, 0, 'k'},
212 {"no-body", no_argument, 0, 'N'}, 232 {"no-body", no_argument, 0, 'N'},
@@ -216,6 +236,7 @@ process_arguments (int argc, char **argv)
216 {"invert-regex", no_argument, NULL, INVERT_REGEX}, 236 {"invert-regex", no_argument, NULL, INVERT_REGEX},
217 {"use-ipv4", no_argument, 0, '4'}, 237 {"use-ipv4", no_argument, 0, '4'},
218 {"use-ipv6", no_argument, 0, '6'}, 238 {"use-ipv6", no_argument, 0, '6'},
239 {"extended-perfdata", no_argument, 0, 'E'},
219 {0, 0, 0, 0} 240 {0, 0, 0, 0}
220 }; 241 };
221 242
@@ -236,7 +257,7 @@ process_arguments (int argc, char **argv)
236 } 257 }
237 258
238 while (1) { 259 while (1) {
239 c = getopt_long (argc, argv, "Vvh46t:c:w:A:k:H:P:j:T:I:a:b:e:p:s:R:r:u:f:C:nlLS::m:M:N", longopts, &option); 260 c = getopt_long (argc, argv, "Vvh46t:c:w:A:k:H:P:j:T:I:a:b:d:e:p:s:R:r:u:f:C:J:K:nlLS::m:M:N:E", longopts, &option);
240 if (c == -1 || c == EOF) 261 if (c == -1 || c == EOF)
241 break; 262 break;
242 263
@@ -301,10 +322,23 @@ process_arguments (int argc, char **argv)
301 days_till_exp_warn = atoi (optarg); 322 days_till_exp_warn = atoi (optarg);
302 } 323 }
303 check_cert = TRUE; 324 check_cert = TRUE;
304 /* Fall through to -S option */ 325 goto enable_ssl;
326#endif
327 case 'J': /* use client certificate */
328#ifdef HAVE_SSL
329 test_file(optarg);
330 client_cert = optarg;
331 goto enable_ssl;
332#endif
333 case 'K': /* use client private key */
334#ifdef HAVE_SSL
335 test_file(optarg);
336 client_privkey = optarg;
337 goto enable_ssl;
305#endif 338#endif
306 case 'S': /* use SSL */ 339 case 'S': /* use SSL */
307#ifdef HAVE_SSL 340#ifdef HAVE_SSL
341 enable_ssl:
308 use_ssl = TRUE; 342 use_ssl = TRUE;
309 if (optarg == NULL || c != 'S') 343 if (optarg == NULL || c != 'S')
310 ssl_version = 0; 344 ssl_version = 0;
@@ -316,6 +350,7 @@ process_arguments (int argc, char **argv)
316 if (specify_port == FALSE) 350 if (specify_port == FALSE)
317 server_port = HTTPS_PORT; 351 server_port = HTTPS_PORT;
318#else 352#else
353 /* -C -J and -K fall through to here without SSL */
319 usage4 (_("Invalid option - SSL is not available")); 354 usage4 (_("Invalid option - SSL is not available"));
320#endif 355#endif
321 break; 356 break;
@@ -385,6 +420,10 @@ process_arguments (int argc, char **argv)
385 free(http_method); 420 free(http_method);
386 http_method = strdup (optarg); 421 http_method = strdup (optarg);
387 break; 422 break;
423 case 'd': /* string or substring */
424 strncpy (header_expect, optarg, MAX_INPUT_BUFFER - 1);
425 header_expect[MAX_INPUT_BUFFER - 1] = 0;
426 break;
388 case 's': /* string or substring */ 427 case 's': /* string or substring */
389 strncpy (string_expect, optarg, MAX_INPUT_BUFFER - 1); 428 strncpy (string_expect, optarg, MAX_INPUT_BUFFER - 1);
390 string_expect[MAX_INPUT_BUFFER - 1] = 0; 429 string_expect[MAX_INPUT_BUFFER - 1] = 0;
@@ -471,6 +510,9 @@ process_arguments (int argc, char **argv)
471 } 510 }
472 } 511 }
473 break; 512 break;
513 case 'E': /* show extended perfdata */
514 show_extended_perfdata = TRUE;
515 break;
474 } 516 }
475 } 517 }
476 518
@@ -497,6 +539,9 @@ process_arguments (int argc, char **argv)
497 if (http_method == NULL) 539 if (http_method == NULL)
498 http_method = strdup ("GET"); 540 http_method = strdup ("GET");
499 541
542 if (client_cert && !client_privkey)
543 usage4 (_("If you use a client certificate you must also specify a private key file"));
544
500 return TRUE; 545 return TRUE;
501} 546}
502 547
@@ -812,17 +857,33 @@ check_http (void)
812 char *pos; 857 char *pos;
813 long microsec; 858 long microsec;
814 double elapsed_time; 859 double elapsed_time;
860 long microsec_connect;
861 double elapsed_time_connect;
862 long microsec_ssl;
863 double elapsed_time_ssl;
864 long microsec_firstbyte;
865 double elapsed_time_firstbyte;
866 long microsec_headers;
867 double elapsed_time_headers;
868 long microsec_transfer;
869 double elapsed_time_transfer;
815 int page_len = 0; 870 int page_len = 0;
816 int result = STATE_OK; 871 int result = STATE_OK;
817 872
818 /* try to connect to the host at the given port number */ 873 /* try to connect to the host at the given port number */
874 gettimeofday (&tv_temp, NULL);
819 if (my_tcp_connect (server_address, server_port, &sd) != STATE_OK) 875 if (my_tcp_connect (server_address, server_port, &sd) != STATE_OK)
820 die (STATE_CRITICAL, _("HTTP CRITICAL - Unable to open TCP socket\n")); 876 die (STATE_CRITICAL, _("HTTP CRITICAL - Unable to open TCP socket\n"));
877 microsec_connect = deltime (tv_temp);
821#ifdef HAVE_SSL 878#ifdef HAVE_SSL
879 elapsed_time_connect = (double)microsec_connect / 1.0e6;
822 if (use_ssl == TRUE) { 880 if (use_ssl == TRUE) {
823 result = np_net_ssl_init_with_hostname_and_version(sd, (use_sni ? host_name : NULL), ssl_version); 881 gettimeofday (&tv_temp, NULL);
882 result = np_net_ssl_init_with_hostname_version_and_cert(sd, (use_sni ? host_name : NULL), ssl_version, client_cert, client_privkey);
824 if (result != STATE_OK) 883 if (result != STATE_OK)
825 return result; 884 return result;
885 microsec_ssl = deltime (tv_temp);
886 elapsed_time_ssl = (double)microsec_ssl / 1.0e6;
826 if (check_cert == TRUE) { 887 if (check_cert == TRUE) {
827 result = np_net_ssl_check_cert(days_till_exp_warn, days_till_exp_crit); 888 result = np_net_ssl_check_cert(days_till_exp_warn, days_till_exp_crit);
828 np_net_ssl_cleanup(); 889 np_net_ssl_cleanup();
@@ -854,8 +915,7 @@ check_http (void)
854 /* optionally send any other header tag */ 915 /* optionally send any other header tag */
855 if (http_opt_headers_count) { 916 if (http_opt_headers_count) {
856 for (i = 0; i < http_opt_headers_count ; i++) { 917 for (i = 0; i < http_opt_headers_count ; i++) {
857 for ((pos = strtok(http_opt_headers[i], INPUT_DELIMITER)); pos; (pos = strtok(NULL, INPUT_DELIMITER))) 918 xasprintf (&buf, "%s%s\r\n", buf, http_opt_headers[i]);
858 xasprintf (&buf, "%s%s\r\n", buf, pos);
859 } 919 }
860 /* This cannot be free'd here because a redirection will then try to access this and segfault */ 920 /* This cannot be free'd here because a redirection will then try to access this and segfault */
861 /* Covered in a testcase in tests/check_http.t */ 921 /* Covered in a testcase in tests/check_http.t */
@@ -891,11 +951,19 @@ check_http (void)
891 } 951 }
892 952
893 if (verbose) printf ("%s\n", buf); 953 if (verbose) printf ("%s\n", buf);
954 gettimeofday (&tv_temp, NULL);
894 my_send (buf, strlen (buf)); 955 my_send (buf, strlen (buf));
956 microsec_headers = deltime (tv_temp);
957 elapsed_time_headers = (double)microsec_headers / 1.0e6;
895 958
896 /* fetch the page */ 959 /* fetch the page */
897 full_page = strdup(""); 960 full_page = strdup("");
961 gettimeofday (&tv_temp, NULL);
898 while ((i = my_recv (buffer, MAX_INPUT_BUFFER-1)) > 0) { 962 while ((i = my_recv (buffer, MAX_INPUT_BUFFER-1)) > 0) {
963 if ((i >= 1) && (elapsed_time_firstbyte <= 0.000001)) {
964 microsec_firstbyte = deltime (tv_temp);
965 elapsed_time_firstbyte = (double)microsec_firstbyte / 1.0e6;
966 }
899 buffer[i] = '\0'; 967 buffer[i] = '\0';
900 xasprintf (&full_page_new, "%s%s", full_page, buffer); 968 xasprintf (&full_page_new, "%s%s", full_page, buffer);
901 free (full_page); 969 free (full_page);
@@ -907,6 +975,8 @@ check_http (void)
907 break; 975 break;
908 } 976 }
909 } 977 }
978 microsec_transfer = deltime (tv_temp);
979 elapsed_time_transfer = (double)microsec_transfer / 1.0e6;
910 980
911 if (i < 0 && errno != ECONNRESET) { 981 if (i < 0 && errno != ECONNRESET) {
912#ifdef HAVE_SSL 982#ifdef HAVE_SSL
@@ -1050,6 +1120,17 @@ check_http (void)
1050 } 1120 }
1051 1121
1052 /* Page and Header content checks go here */ 1122 /* Page and Header content checks go here */
1123 if (strlen (header_expect)) {
1124 if (!strstr (header, header_expect)) {
1125 strncpy(&output_header_search[0],header_expect,sizeof(output_header_search));
1126 if(output_header_search[sizeof(output_header_search)-1]!='\0') {
1127 bcopy("...",&output_header_search[sizeof(output_header_search)-4],4);
1128 }
1129 xasprintf (&msg, _("%sheader '%s' not found on '%s://%s:%d%s', "), msg, output_header_search, use_ssl ? "https" : "http", host_name ? host_name : server_address, server_port, server_url);
1130 result = STATE_CRITICAL;
1131 }
1132 }
1133
1053 1134
1054 if (strlen (string_expect)) { 1135 if (strlen (string_expect)) {
1055 if (!strstr (page, string_expect)) { 1136 if (!strstr (page, string_expect)) {
@@ -1108,11 +1189,25 @@ check_http (void)
1108 msg[strlen(msg)-3] = '\0'; 1189 msg[strlen(msg)-3] = '\0';
1109 1190
1110 /* check elapsed time */ 1191 /* check elapsed time */
1111 xasprintf (&msg, 1192 if (show_extended_perfdata)
1112 _("%s - %d bytes in %.3f second response time %s|%s %s"), 1193 xasprintf (&msg,
1113 msg, page_len, elapsed_time, 1194 _("%s - %d bytes in %.3f second response time %s|%s %s %s %s %s %s %s"),
1114 (display_html ? "</A>" : ""), 1195 msg, page_len, elapsed_time,
1115 perfd_time (elapsed_time), perfd_size (page_len)); 1196 (display_html ? "</A>" : ""),
1197 perfd_time (elapsed_time),
1198 perfd_size (page_len),
1199 perfd_time_connect (elapsed_time_connect),
1200 use_ssl == TRUE ? perfd_time_ssl (elapsed_time_ssl) : "",
1201 perfd_time_headers (elapsed_time_headers),
1202 perfd_time_firstbyte (elapsed_time_firstbyte),
1203 perfd_time_transfer (elapsed_time_transfer));
1204 else
1205 xasprintf (&msg,
1206 _("%s - %d bytes in %.3f second response time %s|%s %s"),
1207 msg, page_len, elapsed_time,
1208 (display_html ? "</A>" : ""),
1209 perfd_time (elapsed_time),
1210 perfd_size (page_len));
1116 1211
1117 result = max_state_alt(get_status(elapsed_time, thlds), result); 1212 result = max_state_alt(get_status(elapsed_time, thlds), result);
1118 1213
@@ -1301,7 +1396,30 @@ char *perfd_time (double elapsed_time)
1301 TRUE, 0, FALSE, 0); 1396 TRUE, 0, FALSE, 0);
1302} 1397}
1303 1398
1399char *perfd_time_connect (double elapsed_time_connect)
1400{
1401 return fperfdata ("time_connect", elapsed_time_connect, "s", FALSE, 0, FALSE, 0, FALSE, 0, FALSE, 0);
1402}
1403
1404char *perfd_time_ssl (double elapsed_time_ssl)
1405{
1406 return fperfdata ("time_ssl", elapsed_time_ssl, "s", FALSE, 0, FALSE, 0, FALSE, 0, FALSE, 0);
1407}
1408
1409char *perfd_time_headers (double elapsed_time_headers)
1410{
1411 return fperfdata ("time_headers", elapsed_time_headers, "s", FALSE, 0, FALSE, 0, FALSE, 0, FALSE, 0);
1412}
1413
1414char *perfd_time_firstbyte (double elapsed_time_firstbyte)
1415{
1416 return fperfdata ("time_firstbyte", elapsed_time_firstbyte, "s", FALSE, 0, FALSE, 0, FALSE, 0, FALSE, 0);
1417}
1304 1418
1419char *perfd_time_transfer (double elapsed_time_transfer)
1420{
1421 return fperfdata ("time_transfer", elapsed_time_transfer, "s", FALSE, 0, FALSE, 0, FALSE, 0, FALSE, 0);
1422}
1305 1423
1306char *perfd_size (int page_len) 1424char *perfd_size (int page_len)
1307{ 1425{
@@ -1354,7 +1472,13 @@ print_help (void)
1354 printf (" %s\n", _("Enable SSL/TLS hostname extension support (SNI)")); 1472 printf (" %s\n", _("Enable SSL/TLS hostname extension support (SNI)"));
1355 printf (" %s\n", "-C, --certificate=INTEGER[,INTEGER]"); 1473 printf (" %s\n", "-C, --certificate=INTEGER[,INTEGER]");
1356 printf (" %s\n", _("Minimum number of days a certificate has to be valid. Port defaults to 443")); 1474 printf (" %s\n", _("Minimum number of days a certificate has to be valid. Port defaults to 443"));
1357 printf (" %s\n", _("(when this option is used the URL is not checked.)\n")); 1475 printf (" %s\n", _("(when this option is used the URL is not checked.)"));
1476 printf (" %s\n", "-J, --client-cert=FILE");
1477 printf (" %s\n", _("Name of file that contains the client certificate (PEM format)"));
1478 printf (" %s\n", _("to be used in establishing the SSL session"));
1479 printf (" %s\n", "-K, --private-key=FILE");
1480 printf (" %s\n", _("Name of file containing the private key (PEM format)"));
1481 printf (" %s\n", _("matching the client certificate"));
1358#endif 1482#endif
1359 1483
1360 printf (" %s\n", "-e, --expect=STRING"); 1484 printf (" %s\n", "-e, --expect=STRING");
@@ -1362,6 +1486,8 @@ print_help (void)
1362 printf (" %s", _("the first (status) line of the server response (default: ")); 1486 printf (" %s", _("the first (status) line of the server response (default: "));
1363 printf ("%s)\n", HTTP_EXPECT); 1487 printf ("%s)\n", HTTP_EXPECT);
1364 printf (" %s\n", _("If specified skips all other status line logic (ex: 3xx, 4xx, 5xx processing)")); 1488 printf (" %s\n", _("If specified skips all other status line logic (ex: 3xx, 4xx, 5xx processing)"));
1489 printf (" %s\n", "-d, --header-string=STRING");
1490 printf (" %s\n", _("String to expect in the response headers"));
1365 printf (" %s\n", "-s, --string=STRING"); 1491 printf (" %s\n", "-s, --string=STRING");
1366 printf (" %s\n", _("String to expect in the content")); 1492 printf (" %s\n", _("String to expect in the content"));
1367 printf (" %s\n", "-u, --url=PATH"); 1493 printf (" %s\n", "-u, --url=PATH");
@@ -1396,6 +1522,8 @@ print_help (void)
1396 printf (" %s\n", _("String to be sent in http header as \"User Agent\"")); 1522 printf (" %s\n", _("String to be sent in http header as \"User Agent\""));
1397 printf (" %s\n", "-k, --header=STRING"); 1523 printf (" %s\n", "-k, --header=STRING");
1398 printf (" %s\n", _("Any other tags to be sent in http header. Use multiple times for additional headers")); 1524 printf (" %s\n", _("Any other tags to be sent in http header. Use multiple times for additional headers"));
1525 printf (" %s\n", "-E, --extended-perfdata");
1526 printf (" %s\n", _("Print additional performance data"));
1399 printf (" %s\n", "-L, --link"); 1527 printf (" %s\n", "-L, --link");
1400 printf (" %s\n", _("Wrap output in HTML link (obsoleted by urlize)")); 1528 printf (" %s\n", _("Wrap output in HTML link (obsoleted by urlize)"));
1401 printf (" %s\n", "-f, --onredirect=<ok|warning|critical|follow|sticky|stickyport>"); 1529 printf (" %s\n", "-f, --onredirect=<ok|warning|critical|follow|sticky|stickyport>");
@@ -1461,9 +1589,10 @@ print_usage (void)
1461{ 1589{
1462 printf ("%s\n", _("Usage:")); 1590 printf ("%s\n", _("Usage:"));
1463 printf (" %s -H <vhost> | -I <IP-address> [-u <uri>] [-p <port>]\n",progname); 1591 printf (" %s -H <vhost> | -I <IP-address> [-u <uri>] [-p <port>]\n",progname);
1464 printf (" [-w <warn time>] [-c <critical time>] [-t <timeout>] [-L] [-a auth]\n"); 1592 printf (" [-J <client certificate file>] [-K <private key>]\n");
1593 printf (" [-w <warn time>] [-c <critical time>] [-t <timeout>] [-L] [-E] [-a auth]\n");
1465 printf (" [-b proxy_auth] [-f <ok|warning|critcal|follow|sticky|stickyport>]\n"); 1594 printf (" [-b proxy_auth] [-f <ok|warning|critcal|follow|sticky|stickyport>]\n");
1466 printf (" [-e <expect>] [-s string] [-l] [-r <regex> | -R <case-insensitive regex>]\n"); 1595 printf (" [-e <expect>] [-d string] [-s string] [-l] [-r <regex> | -R <case-insensitive regex>]\n");
1467 printf (" [-P string] [-m <min_pg_size>:<max_pg_size>] [-4|-6] [-N] [-M <age>]\n"); 1596 printf (" [-P string] [-m <min_pg_size>:<max_pg_size>] [-4|-6] [-N] [-M <age>]\n");
1468 printf (" [-A string] [-k string] [-S <version>] [--sni] [-C <warn_age>[,<crit_age>]]\n"); 1597 printf (" [-A string] [-k string] [-S <version>] [--sni] [-C <warn_age>[,<crit_age>]]\n");
1469 printf (" [-T <content-type>] [-j method]\n"); 1598 printf (" [-T <content-type>] [-j method]\n");
diff --git a/plugins/check_ide_smart.c b/plugins/check_ide_smart.c
index b942461..ee6bf7b 100644
--- a/plugins/check_ide_smart.c
+++ b/plugins/check_ide_smart.c
@@ -46,8 +46,29 @@ void print_usage (void);
46#include <sys/stat.h> 46#include <sys/stat.h>
47#include <sys/ioctl.h> 47#include <sys/ioctl.h>
48#include <fcntl.h> 48#include <fcntl.h>
49#ifdef __linux__
49#include <linux/hdreg.h> 50#include <linux/hdreg.h>
50#include <linux/types.h> 51#include <linux/types.h>
52
53#define OPEN_MODE O_RDONLY
54#endif /* __linux__ */
55#ifdef __NetBSD__
56#include <sys/device.h>
57#include <sys/param.h>
58#include <sys/sysctl.h>
59#include <sys/videoio.h> /* for __u8 and friends */
60#include <sys/scsiio.h>
61#include <sys/ataio.h>
62#include <dev/ata/atareg.h>
63#include <dev/ic/wdcreg.h>
64
65#define SMART_ENABLE WDSM_ENABLE_OPS
66#define SMART_DISABLE WDSM_DISABLE_OPS
67#define SMART_IMMEDIATE_OFFLINE WDSM_EXEC_OFFL_IMM
68#define SMART_AUTO_OFFLINE 0xdb /* undefined in NetBSD headers */
69
70#define OPEN_MODE O_RDWR
71#endif /* __NetBSD__ */
51#include <errno.h> 72#include <errno.h>
52 73
53#define NR_ATTRIBUTES 30 74#define NR_ATTRIBUTES 30
@@ -223,7 +244,7 @@ main (int argc, char *argv[])
223 return STATE_OK; 244 return STATE_OK;
224 } 245 }
225 246
226 fd = open (device, O_RDONLY); 247 fd = open (device, OPEN_MODE);
227 248
228 if (fd < 0) { 249 if (fd < 0) {
229 printf (_("CRITICAL - Couldn't open device %s: %s\n"), device, strerror (errno)); 250 printf (_("CRITICAL - Couldn't open device %s: %s\n"), device, strerror (errno));
@@ -284,6 +305,7 @@ get_offline_text (int status)
284int 305int
285smart_read_values (int fd, values_t * values) 306smart_read_values (int fd, values_t * values)
286{ 307{
308#ifdef __linux__
287 int e; 309 int e;
288 __u8 args[4 + 512]; 310 __u8 args[4 + 512];
289 args[0] = WIN_SMART; 311 args[0] = WIN_SMART;
@@ -296,6 +318,35 @@ smart_read_values (int fd, values_t * values)
296 return e; 318 return e;
297 } 319 }
298 memcpy (values, args + 4, 512); 320 memcpy (values, args + 4, 512);
321#endif /* __linux__ */
322#ifdef __NetBSD__
323 struct atareq req;
324 unsigned char inbuf[DEV_BSIZE];
325
326 memset(&req, 0, sizeof(req));
327 req.timeout = 1000;
328 memset(&inbuf, 0, sizeof(inbuf));
329
330 req.flags = ATACMD_READ;
331 req.features = WDSM_RD_DATA;
332 req.command = WDCC_SMART;
333 req.databuf = (char *)inbuf;
334 req.datalen = sizeof(inbuf);
335 req.cylinder = WDSMART_CYL;
336
337 if (ioctl(fd, ATAIOCCOMMAND, &req) == 0) {
338 if (req.retsts != ATACMD_OK)
339 errno = ENODEV;
340 }
341
342 if (errno != 0) {
343 int e = errno;
344 printf (_("CRITICAL - SMART_READ_VALUES: %s\n"), strerror (errno));
345 return e;
346 }
347
348 (void)memcpy(values, inbuf, 512);
349#endif /* __NetBSD__ */
299 return 0; 350 return 0;
300} 351}
301 352
@@ -439,6 +490,7 @@ int
439smart_cmd_simple (int fd, enum SmartCommand command, __u8 val0, char show_error) 490smart_cmd_simple (int fd, enum SmartCommand command, __u8 val0, char show_error)
440{ 491{
441 int e = 0; 492 int e = 0;
493#ifdef __linux__
442 __u8 args[4]; 494 __u8 args[4];
443 args[0] = WIN_SMART; 495 args[0] = WIN_SMART;
444 args[1] = val0; 496 args[1] = val0;
@@ -450,6 +502,31 @@ smart_cmd_simple (int fd, enum SmartCommand command, __u8 val0, char show_error)
450 printf (_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror (errno)); 502 printf (_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror (errno));
451 } 503 }
452 } 504 }
505#endif /* __linux__ */
506#ifdef __NetBSD__
507 struct atareq req;
508
509 memset(&req, 0, sizeof(req));
510 req.timeout = 1000;
511 req.flags = ATACMD_READREG;
512 req.features = smart_command[command].value;
513 req.command = WDCC_SMART;
514 req.cylinder = WDSMART_CYL;
515 req.sec_count = val0;
516
517 if (ioctl(fd, ATAIOCCOMMAND, &req) == 0) {
518 if (req.retsts != ATACMD_OK)
519 errno = ENODEV;
520 if (req.cylinder != WDSMART_CYL)
521 errno = ENODEV;
522 }
523
524 if (errno != 0) {
525 e = errno;
526 printf (_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror (errno));
527 return e;
528 }
529#endif /* __NetBSD__ */
453 return e; 530 return e;
454} 531}
455 532
@@ -458,6 +535,7 @@ smart_cmd_simple (int fd, enum SmartCommand command, __u8 val0, char show_error)
458int 535int
459smart_read_thresholds (int fd, thresholds_t * thresholds) 536smart_read_thresholds (int fd, thresholds_t * thresholds)
460{ 537{
538#ifdef __linux__
461 int e; 539 int e;
462 __u8 args[4 + 512]; 540 __u8 args[4 + 512];
463 args[0] = WIN_SMART; 541 args[0] = WIN_SMART;
@@ -470,6 +548,35 @@ smart_read_thresholds (int fd, thresholds_t * thresholds)
470 return e; 548 return e;
471 } 549 }
472 memcpy (thresholds, args + 4, 512); 550 memcpy (thresholds, args + 4, 512);
551#endif /* __linux__ */
552#ifdef __NetBSD__
553 struct atareq req;
554 unsigned char inbuf[DEV_BSIZE];
555
556 memset(&req, 0, sizeof(req));
557 req.timeout = 1000;
558 memset(&inbuf, 0, sizeof(inbuf));
559
560 req.flags = ATACMD_READ;
561 req.features = WDSM_RD_THRESHOLDS;
562 req.command = WDCC_SMART;
563 req.databuf = (char *)inbuf;
564 req.datalen = sizeof(inbuf);
565 req.cylinder = WDSMART_CYL;
566
567 if (ioctl(fd, ATAIOCCOMMAND, &req) == 0) {
568 if (req.retsts != ATACMD_OK)
569 errno = ENODEV;
570 }
571
572 if (errno != 0) {
573 int e = errno;
574 printf (_("CRITICAL - SMART_READ_THRESHOLDS: %s\n"), strerror (errno));
575 return e;
576 }
577
578 (void)memcpy(thresholds, inbuf, 512);
579#endif /* __NetBSD__ */
473 return 0; 580 return 0;
474} 581}
475 582
diff --git a/plugins/check_mysql.c b/plugins/check_mysql.c
index 51579c2..db670e2 100644
--- a/plugins/check_mysql.c
+++ b/plugins/check_mysql.c
@@ -49,10 +49,44 @@ char *db_host = NULL;
49char *db_socket = NULL; 49char *db_socket = NULL;
50char *db_pass = NULL; 50char *db_pass = NULL;
51char *db = NULL; 51char *db = NULL;
52char *ca_cert = NULL;
53char *ca_dir = NULL;
54char *cert = NULL;
55char *key = NULL;
56char *ciphers = NULL;
57bool ssl = false;
58char *opt_file = NULL;
59char *opt_group = NULL;
52unsigned int db_port = MYSQL_PORT; 60unsigned int db_port = MYSQL_PORT;
53int check_slave = 0, warn_sec = 0, crit_sec = 0; 61int check_slave = 0, warn_sec = 0, crit_sec = 0;
54int verbose = 0; 62int verbose = 0;
55 63
64static double warning_time = 0;
65static double critical_time = 0;
66
67#define LENGTH_METRIC_UNIT 6
68static const char *metric_unit[LENGTH_METRIC_UNIT] = {
69 "Open_files",
70 "Open_tables",
71 "Qcache_free_memory",
72 "Qcache_queries_in_cache",
73 "Threads_connected",
74 "Threads_running"
75};
76
77#define LENGTH_METRIC_COUNTER 9
78static const char *metric_counter[LENGTH_METRIC_COUNTER] = {
79 "Connections",
80 "Qcache_hits",
81 "Qcache_inserts",
82 "Qcache_lowmem_prunes",
83 "Qcache_not_cached",
84 "Queries",
85 "Questions",
86 "Table_locks_waited",
87 "Uptime"
88};
89
56thresholds *my_threshold = NULL; 90thresholds *my_threshold = NULL;
57 91
58int process_arguments (int, char **); 92int process_arguments (int, char **);
@@ -73,6 +107,9 @@ main (int argc, char **argv)
73 char *result = NULL; 107 char *result = NULL;
74 char *error = NULL; 108 char *error = NULL;
75 char slaveresult[SLAVERESULTSIZE]; 109 char slaveresult[SLAVERESULTSIZE];
110 char* perf;
111
112 perf = strdup ("");
76 113
77 setlocale (LC_ALL, ""); 114 setlocale (LC_ALL, "");
78 bindtextdomain (PACKAGE, LOCALEDIR); 115 bindtextdomain (PACKAGE, LOCALEDIR);
@@ -86,9 +123,17 @@ main (int argc, char **argv)
86 123
87 /* initialize mysql */ 124 /* initialize mysql */
88 mysql_init (&mysql); 125 mysql_init (&mysql);
126
127 if (opt_file != NULL)
128 mysql_options(&mysql,MYSQL_READ_DEFAULT_FILE,opt_file);
89 129
90 mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"client"); 130 if (opt_group != NULL)
131 mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,opt_group);
132 else
133 mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"client");
91 134
135 if (ssl)
136 mysql_ssl_set(&mysql,key,cert,ca_cert,ca_dir,ciphers);
92 /* establish a connection to the server and error checking */ 137 /* establish a connection to the server and error checking */
93 if (!mysql_real_connect(&mysql,db_host,db_user,db_pass,db,db_port,db_socket,0)) { 138 if (!mysql_real_connect(&mysql,db_host,db_user,db_pass,db,db_port,db_socket,0)) {
94 if (mysql_errno (&mysql) == CR_UNKNOWN_HOST) 139 if (mysql_errno (&mysql) == CR_UNKNOWN_HOST)
@@ -118,6 +163,37 @@ main (int argc, char **argv)
118 die (STATE_CRITICAL, "%s\n", mysql_error (&mysql)); 163 die (STATE_CRITICAL, "%s\n", mysql_error (&mysql));
119 } 164 }
120 165
166 /* try to fetch some perf data */
167 if (mysql_query (&mysql, "show global status") == 0) {
168 if ( (res = mysql_store_result (&mysql)) == NULL) {
169 error = strdup(mysql_error(&mysql));
170 mysql_close (&mysql);
171 die (STATE_CRITICAL, _("status store_result error: %s\n"), error);
172 }
173
174 while ( (row = mysql_fetch_row (res)) != NULL) {
175 int i;
176
177 for(i = 0; i < LENGTH_METRIC_UNIT; i++) {
178 if (strcmp(row[0], metric_unit[i]) == 0) {
179 xasprintf(&perf, "%s%s ", perf, perfdata(metric_unit[i],
180 atol(row[1]), "", FALSE, 0, FALSE, 0, FALSE, 0, FALSE, 0));
181 continue;
182 }
183 }
184 for(i = 0; i < LENGTH_METRIC_COUNTER; i++) {
185 if (strcmp(row[0], metric_counter[i]) == 0) {
186 xasprintf(&perf, "%s%s ", perf, perfdata(metric_counter[i],
187 atol(row[1]), "c", FALSE, 0, FALSE, 0, FALSE, 0, FALSE, 0));
188 continue;
189 }
190 }
191 }
192 /* remove trailing space */
193 if (strlen(perf) > 0)
194 perf[strlen(perf) - 1] = '\0';
195 }
196
121 if(check_slave) { 197 if(check_slave) {
122 /* check the slave status */ 198 /* check the slave status */
123 if (mysql_query (&mysql, "show slave status") != 0) { 199 if (mysql_query (&mysql, "show slave status") != 0) {
@@ -210,11 +286,17 @@ main (int argc, char **argv)
210 286
211 status = get_status(value, my_threshold); 287 status = get_status(value, my_threshold);
212 288
289 xasprintf (&perf, "%s %s", perf, fperfdata ("seconds behind master", value, "s",
290 TRUE, (double) warning_time,
291 TRUE, (double) critical_time,
292 FALSE, 0,
293 FALSE, 0));
294
213 if (status == STATE_WARNING) { 295 if (status == STATE_WARNING) {
214 printf("SLOW_SLAVE %s: %s\n", _("WARNING"), slaveresult); 296 printf("SLOW_SLAVE %s: %s|%s\n", _("WARNING"), slaveresult, perf);
215 exit(STATE_WARNING); 297 exit(STATE_WARNING);
216 } else if (status == STATE_CRITICAL) { 298 } else if (status == STATE_CRITICAL) {
217 printf("SLOW_SLAVE %s: %s\n", _("CRITICAL"), slaveresult); 299 printf("SLOW_SLAVE %s: %s|%s\n", _("CRITICAL"), slaveresult, perf);
218 exit(STATE_CRITICAL); 300 exit(STATE_CRITICAL);
219 } 301 }
220 } 302 }
@@ -229,9 +311,9 @@ main (int argc, char **argv)
229 311
230 /* print out the result of stats */ 312 /* print out the result of stats */
231 if (check_slave) { 313 if (check_slave) {
232 printf ("%s %s\n", result, slaveresult); 314 printf ("%s %s|%s\n", result, slaveresult, perf);
233 } else { 315 } else {
234 printf ("%s\n", result); 316 printf ("%s|%s\n", result, perf);
235 } 317 }
236 318
237 return STATE_OK; 319 return STATE_OK;
@@ -253,6 +335,8 @@ process_arguments (int argc, char **argv)
253 {"database", required_argument, 0, 'd'}, 335 {"database", required_argument, 0, 'd'},
254 {"username", required_argument, 0, 'u'}, 336 {"username", required_argument, 0, 'u'},
255 {"password", required_argument, 0, 'p'}, 337 {"password", required_argument, 0, 'p'},
338 {"file", required_argument, 0, 'f'},
339 {"group", required_argument, 0, 'g'},
256 {"port", required_argument, 0, 'P'}, 340 {"port", required_argument, 0, 'P'},
257 {"critical", required_argument, 0, 'c'}, 341 {"critical", required_argument, 0, 'c'},
258 {"warning", required_argument, 0, 'w'}, 342 {"warning", required_argument, 0, 'w'},
@@ -260,6 +344,12 @@ process_arguments (int argc, char **argv)
260 {"verbose", no_argument, 0, 'v'}, 344 {"verbose", no_argument, 0, 'v'},
261 {"version", no_argument, 0, 'V'}, 345 {"version", no_argument, 0, 'V'},
262 {"help", no_argument, 0, 'h'}, 346 {"help", no_argument, 0, 'h'},
347 {"ssl", no_argument, 0, 'l'},
348 {"ca-cert", optional_argument, 0, 'C'},
349 {"key", required_argument,0,'k'},
350 {"cert", required_argument,0,'a'},
351 {"ca-dir", required_argument, 0, 'D'},
352 {"ciphers", required_argument, 0, 'L'},
263 {0, 0, 0, 0} 353 {0, 0, 0, 0}
264 }; 354 };
265 355
@@ -267,7 +357,7 @@ process_arguments (int argc, char **argv)
267 return ERROR; 357 return ERROR;
268 358
269 while (1) { 359 while (1) {
270 c = getopt_long (argc, argv, "hvVSP:p:u:d:H:s:c:w:", longopts, &option); 360 c = getopt_long (argc, argv, "hlvVSP:p:u:d:H:s:c:w:a:k:C:D:L:f:g:", longopts, &option);
271 361
272 if (c == -1 || c == EOF) 362 if (c == -1 || c == EOF)
273 break; 363 break;
@@ -287,6 +377,24 @@ process_arguments (int argc, char **argv)
287 case 'd': /* database */ 377 case 'd': /* database */
288 db = optarg; 378 db = optarg;
289 break; 379 break;
380 case 'l':
381 ssl = true;
382 break;
383 case 'C':
384 ca_cert = optarg;
385 break;
386 case 'a':
387 cert = optarg;
388 break;
389 case 'k':
390 key = optarg;
391 break;
392 case 'D':
393 ca_dir = optarg;
394 break;
395 case 'L':
396 ciphers = optarg;
397 break;
290 case 'u': /* username */ 398 case 'u': /* username */
291 db_user = optarg; 399 db_user = optarg;
292 break; 400 break;
@@ -299,6 +407,12 @@ process_arguments (int argc, char **argv)
299 optarg++; 407 optarg++;
300 } 408 }
301 break; 409 break;
410 case 'f': /* client options file */
411 opt_file = optarg;
412 break;
413 case 'g': /* client options group */
414 opt_group = optarg;
415 break;
302 case 'P': /* critical time threshold */ 416 case 'P': /* critical time threshold */
303 db_port = atoi (optarg); 417 db_port = atoi (optarg);
304 break; 418 break;
@@ -307,9 +421,11 @@ process_arguments (int argc, char **argv)
307 break; 421 break;
308 case 'w': 422 case 'w':
309 warning = optarg; 423 warning = optarg;
424 warning_time = strtod (warning, NULL);
310 break; 425 break;
311 case 'c': 426 case 'c':
312 critical = optarg; 427 critical = optarg;
428 critical_time = strtod (critical, NULL);
313 break; 429 break;
314 case 'V': /* version */ 430 case 'V': /* version */
315 print_revision (progname, NP_VERSION); 431 print_revision (progname, NP_VERSION);
@@ -360,6 +476,12 @@ validate_arguments (void)
360 if (db_user == NULL) 476 if (db_user == NULL)
361 db_user = strdup(""); 477 db_user = strdup("");
362 478
479 if (opt_file == NULL)
480 opt_file = strdup("");
481
482 if (opt_group == NULL)
483 opt_group = strdup("");
484
363 if (db_host == NULL) 485 if (db_host == NULL)
364 db_host = strdup(""); 486 db_host = strdup("");
365 487
@@ -395,6 +517,10 @@ print_help (void)
395 517
396 printf (" %s\n", "-d, --database=STRING"); 518 printf (" %s\n", "-d, --database=STRING");
397 printf (" %s\n", _("Check database with indicated name")); 519 printf (" %s\n", _("Check database with indicated name"));
520 printf (" %s\n", "-f, --file=STRING");
521 printf (" %s\n", _("Read from the specified client options file"));
522 printf (" %s\n", "-g, --group=STRING");
523 printf (" %s\n", _("Use a client options group"));
398 printf (" %s\n", "-u, --username=STRING"); 524 printf (" %s\n", "-u, --username=STRING");
399 printf (" %s\n", _("Connect using the indicated username")); 525 printf (" %s\n", _("Connect using the indicated username"));
400 printf (" %s\n", "-p, --password=STRING"); 526 printf (" %s\n", "-p, --password=STRING");
@@ -409,6 +535,19 @@ print_help (void)
409 printf (" %s\n", "-c, --critical"); 535 printf (" %s\n", "-c, --critical");
410 printf (" %s\n", _("Exit with CRITICAL status if slave server is more then INTEGER seconds")); 536 printf (" %s\n", _("Exit with CRITICAL status if slave server is more then INTEGER seconds"));
411 printf (" %s\n", _("behind master")); 537 printf (" %s\n", _("behind master"));
538 printf (" %s\n", "-l, --ssl");
539 printf (" %s\n", _("Use ssl encryptation"));
540 printf (" %s\n", "-C, --ca-cert=STRING");
541 printf (" %s\n", _("Path to CA signing the cert"));
542 printf (" %s\n", "-a, --cert=STRING");
543 printf (" %s\n", _("Path to SSL certificate"));
544 printf (" %s\n", "-k, --key=STRING");
545 printf (" %s\n", _("Path to private SSL key"));
546 printf (" %s\n", "-D, --ca-dir=STRING");
547 printf (" %s\n", _("Path to CA directory"));
548 printf (" %s\n", "-L, --ciphers=STRING");
549 printf (" %s\n", _("List of valid SSL ciphers"));
550
412 551
413 printf ("\n"); 552 printf ("\n");
414 printf (" %s\n", _("There are no required arguments. By default, the local database is checked")); 553 printf (" %s\n", _("There are no required arguments. By default, the local database is checked"));
@@ -429,5 +568,6 @@ print_usage (void)
429{ 568{
430 printf ("%s\n", _("Usage:")); 569 printf ("%s\n", _("Usage:"));
431 printf (" %s [-d database] [-H host] [-P port] [-s socket]\n",progname); 570 printf (" %s [-d database] [-H host] [-P port] [-s socket]\n",progname);
432 printf (" [-u user] [-p password] [-S]\n"); 571 printf (" [-u user] [-p password] [-S] [-l] [-a cert] [-k key]\n");
572 printf (" [-C ca-cert] [-D ca-dir] [-L ciphers] [-f optfile] [-g group]\n");
433} 573}
diff --git a/plugins/check_nagios.c b/plugins/check_nagios.c
index c8cdbc0..4fd6342 100644
--- a/plugins/check_nagios.c
+++ b/plugins/check_nagios.c
@@ -205,6 +205,7 @@ process_arguments (int argc, char **argv)
205 {"filename", required_argument, 0, 'F'}, 205 {"filename", required_argument, 0, 'F'},
206 {"expires", required_argument, 0, 'e'}, 206 {"expires", required_argument, 0, 'e'},
207 {"command", required_argument, 0, 'C'}, 207 {"command", required_argument, 0, 'C'},
208 {"timeout", optional_argument, 0, 't'},
208 {"version", no_argument, 0, 'V'}, 209 {"version", no_argument, 0, 'V'},
209 {"help", no_argument, 0, 'h'}, 210 {"help", no_argument, 0, 'h'},
210 {"verbose", no_argument, 0, 'v'}, 211 {"verbose", no_argument, 0, 'v'},
@@ -226,7 +227,7 @@ process_arguments (int argc, char **argv)
226 } 227 }
227 228
228 while (1) { 229 while (1) {
229 c = getopt_long (argc, argv, "+hVvF:C:e:", longopts, &option); 230 c = getopt_long (argc, argv, "+hVvF:C:e:t:", longopts, &option);
230 231
231 if (c == -1 || c == EOF || c == 1) 232 if (c == -1 || c == EOF || c == 1)
232 break; 233 break;
@@ -251,6 +252,13 @@ process_arguments (int argc, char **argv)
251 die (STATE_UNKNOWN, 252 die (STATE_UNKNOWN,
252 _("Expiration time must be an integer (seconds)\n")); 253 _("Expiration time must be an integer (seconds)\n"));
253 break; 254 break;
255 case 't': /* timeout */
256 if (is_intnonneg (optarg))
257 timeout_interval = atoi (optarg);
258 else
259 die (STATE_UNKNOWN,
260 _("Timeout must be an integer (seconds)\n"));
261 break;
254 case 'v': 262 case 'v':
255 verbose++; 263 verbose++;
256 break; 264 break;
@@ -296,11 +304,13 @@ print_help (void)
296 printf (" %s\n", _("Minutes aging after which logfile is considered stale")); 304 printf (" %s\n", _("Minutes aging after which logfile is considered stale"));
297 printf (" %s\n", "-C, --command=STRING"); 305 printf (" %s\n", "-C, --command=STRING");
298 printf (" %s\n", _("Substring to search for in process arguments")); 306 printf (" %s\n", _("Substring to search for in process arguments"));
307 printf (" %s\n", "-t, --timeout=INTEGER");
308 printf (" %s\n", _("Timeout for the plugin in seconds"));
299 printf (UT_VERBOSE); 309 printf (UT_VERBOSE);
300 310
301 printf ("\n"); 311 printf ("\n");
302 printf ("%s\n", _("Examples:")); 312 printf ("%s\n", _("Examples:"));
303 printf (" %s\n", "check_nagios -e 5 -F /usr/local/nagios/var/status.log -C /usr/local/nagios/bin/nagios"); 313 printf (" %s\n", "check_nagios -t 20 -e 5 -F /usr/local/nagios/var/status.log -C /usr/local/nagios/bin/nagios");
304 314
305 printf (UT_SUPPORT); 315 printf (UT_SUPPORT);
306} 316}
@@ -311,5 +321,5 @@ void
311print_usage (void) 321print_usage (void)
312{ 322{
313 printf ("%s\n", _("Usage:")); 323 printf ("%s\n", _("Usage:"));
314 printf ("%s -F <status log file> -e <expire_minutes> -C <process_string>\n", progname); 324 printf ("%s -F <status log file> -t <timeout_seconds> -e <expire_minutes> -C <process_string>\n", progname);
315} 325}
diff --git a/plugins/check_nt.c b/plugins/check_nt.c
index 89c4d8d..52bbd1c 100644
--- a/plugins/check_nt.c
+++ b/plugins/check_nt.c
@@ -94,6 +94,7 @@ int main(int argc, char **argv){
94 char *description=NULL,*counter_unit = NULL; 94 char *description=NULL,*counter_unit = NULL;
95 char *minval = NULL, *maxval = NULL, *errcvt = NULL; 95 char *minval = NULL, *maxval = NULL, *errcvt = NULL;
96 char *fds=NULL, *tds=NULL; 96 char *fds=NULL, *tds=NULL;
97 char *numstr;
97 98
98 double total_disk_space=0; 99 double total_disk_space=0;
99 double free_disk_space=0; 100 double free_disk_space=0;
@@ -265,7 +266,10 @@ int main(int argc, char **argv){
265 xasprintf(&send_buffer,"%s&%u&%s&%s", req_password,(vars_to_check==CHECK_SERVICESTATE)?5:6, 266 xasprintf(&send_buffer,"%s&%u&%s&%s", req_password,(vars_to_check==CHECK_SERVICESTATE)?5:6,
266 (show_all==TRUE) ? "ShowAll" : "ShowFail",value_list); 267 (show_all==TRUE) ? "ShowAll" : "ShowFail",value_list);
267 fetch_data (server_address, server_port, send_buffer); 268 fetch_data (server_address, server_port, send_buffer);
268 return_code=atoi(strtok(recv_buffer,"&")); 269 numstr = strtok(recv_buffer,"&");
270 if (numstr == NULL)
271 die(STATE_UNKNOWN, _("could not fetch information from server\n"));
272 return_code=atoi(numstr);
269 temp_string=strtok(NULL,"&"); 273 temp_string=strtok(NULL,"&");
270 output_message = strdup (temp_string); 274 output_message = strdup (temp_string);
271 } 275 }
@@ -275,8 +279,14 @@ int main(int argc, char **argv){
275 279
276 xasprintf(&send_buffer,"%s&7", req_password); 280 xasprintf(&send_buffer,"%s&7", req_password);
277 fetch_data (server_address, server_port, send_buffer); 281 fetch_data (server_address, server_port, send_buffer);
278 mem_commitLimit=atof(strtok(recv_buffer,"&")); 282 numstr = strtok(recv_buffer,"&");
279 mem_commitByte=atof(strtok(NULL,"&")); 283 if (numstr == NULL)
284 die(STATE_UNKNOWN, _("could not fetch information from server\n"));
285 mem_commitLimit=atof(numstr);
286 numstr = strtok(NULL,"&");
287 if (numstr == NULL)
288 die(STATE_UNKNOWN, _("could not fetch information from server\n"));
289 mem_commitByte=atof(numstr);
280 percent_used_space = (mem_commitByte / mem_commitLimit) * 100; 290 percent_used_space = (mem_commitByte / mem_commitLimit) * 100;
281 warning_used_space = ((float)warning_value / 100) * mem_commitLimit; 291 warning_used_space = ((float)warning_value / 100) * mem_commitLimit;
282 critical_used_space = ((float)critical_value / 100) * mem_commitLimit; 292 critical_used_space = ((float)critical_value / 100) * mem_commitLimit;
diff --git a/plugins/check_ntp_peer.c b/plugins/check_ntp_peer.c
index b59c056..76152e1 100644
--- a/plugins/check_ntp_peer.c
+++ b/plugins/check_ntp_peer.c
@@ -241,15 +241,19 @@ int ntp_request(const char *host, double *offset, int *offset_result, double *ji
241 DBG(printf("sending READSTAT request")); 241 DBG(printf("sending READSTAT request"));
242 write(conn, &req, SIZEOF_NTPCM(req)); 242 write(conn, &req, SIZEOF_NTPCM(req));
243 DBG(print_ntp_control_message(&req)); 243 DBG(print_ntp_control_message(&req));
244 /* Attempt to read the largest size packet possible */ 244
245 req.count=htons(MAX_CM_SIZE); 245 do {
246 DBG(printf("recieving READSTAT response")) 246 /* Attempt to read the largest size packet possible */
247 if(read(conn, &req, SIZEOF_NTPCM(req)) == -1) 247 req.count=htons(MAX_CM_SIZE);
248 die(STATE_CRITICAL, "NTP CRITICAL: No response from NTP server\n"); 248 DBG(printf("recieving READSTAT response"))
249 DBG(print_ntp_control_message(&req)); 249 if(read(conn, &req, SIZEOF_NTPCM(req)) == -1)
250 /* discard obviously invalid packets */ 250 die(STATE_CRITICAL, "NTP CRITICAL: No response from NTP server\n");
251 if (ntohs(req.count) > MAX_CM_SIZE) 251 DBG(print_ntp_control_message(&req));
252 die(STATE_CRITICAL, "NTP CRITICAL: Invalid packet received from NTP server\n"); 252 /* discard obviously invalid packets */
253 if (ntohs(req.count) > MAX_CM_SIZE)
254 die(STATE_CRITICAL, "NTP CRITICAL: Invalid packet received from NTP server\n");
255 } while (!(req.op&OP_READSTAT && ntohs(req.seq) == 1));
256
253 if (LI(req.flags) == LI_ALARM) li_alarm = 1; 257 if (LI(req.flags) == LI_ALARM) li_alarm = 1;
254 /* Each peer identifier is 4 bytes in the data section, which 258 /* Each peer identifier is 4 bytes in the data section, which
255 * we represent as a ntp_assoc_status_pair datatype. 259 * we represent as a ntp_assoc_status_pair datatype.
@@ -312,10 +316,12 @@ int ntp_request(const char *host, double *offset, int *offset_result, double *ji
312 write(conn, &req, SIZEOF_NTPCM(req)); 316 write(conn, &req, SIZEOF_NTPCM(req));
313 DBG(print_ntp_control_message(&req)); 317 DBG(print_ntp_control_message(&req));
314 318
315 req.count = htons(MAX_CM_SIZE); 319 do {
316 DBG(printf("receiving READVAR response...\n")); 320 req.count = htons(MAX_CM_SIZE);
317 read(conn, &req, SIZEOF_NTPCM(req)); 321 DBG(printf("receiving READVAR response...\n"));
318 DBG(print_ntp_control_message(&req)); 322 read(conn, &req, SIZEOF_NTPCM(req));
323 DBG(print_ntp_control_message(&req));
324 } while (!(req.op&OP_READVAR && ntohs(req.seq) == 2));
319 325
320 if(!(req.op&REM_ERROR)) 326 if(!(req.op&REM_ERROR))
321 xasprintf(&data, "%s%s", data, req.data); 327 xasprintf(&data, "%s%s", data, req.data);
diff --git a/plugins/check_pgsql.c b/plugins/check_pgsql.c
index 8b0769f..8d60701 100644
--- a/plugins/check_pgsql.c
+++ b/plugins/check_pgsql.c
@@ -3,7 +3,7 @@
3* Nagios check_pgsql plugin 3* Nagios check_pgsql plugin
4* 4*
5* License: GPL 5* License: GPL
6* Copyright (c) 1999-2007 Nagios Plugins Development Team 6* Copyright (c) 1999-2011 Nagios Plugins Development Team
7* 7*
8* Description: 8* Description:
9* 9*
@@ -29,7 +29,7 @@
29*****************************************************************************/ 29*****************************************************************************/
30 30
31const char *progname = "check_pgsql"; 31const char *progname = "check_pgsql";
32const char *copyright = "1999-2007"; 32const char *copyright = "1999-2011";
33const char *email = "nagiosplug-devel@lists.sourceforge.net"; 33const char *email = "nagiosplug-devel@lists.sourceforge.net";
34 34
35#include "common.h" 35#include "common.h"
@@ -42,6 +42,20 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net";
42#define DEFAULT_DB "template1" 42#define DEFAULT_DB "template1"
43#define DEFAULT_HOST "127.0.0.1" 43#define DEFAULT_HOST "127.0.0.1"
44 44
45/* return the PSQL server version as a 3-tuple */
46#define PSQL_SERVER_VERSION3(server_version) \
47 (server_version) / 10000, \
48 (server_version) / 100 - (int)((server_version) / 10000) * 100, \
49 (server_version) - (int)((server_version) / 100) * 100
50/* return true if the given host is a UNIX domain socket */
51#define PSQL_IS_UNIX_DOMAIN_SOCKET(host) \
52 ((NULL == (host)) || ('\0' == *(host)) || ('/' == *(host)))
53/* return a 3-tuple identifying a host/port independent of the socket type */
54#define PSQL_SOCKET3(host, port) \
55 ((NULL == (host)) || ('\0' == *(host))) ? DEFAULT_PGSOCKET_DIR : host, \
56 PSQL_IS_UNIX_DOMAIN_SOCKET (host) ? "/.s.PGSQL." : ":", \
57 port
58
45enum { 59enum {
46 DEFAULT_PORT = 5432, 60 DEFAULT_PORT = 5432,
47 DEFAULT_WARN = 2, 61 DEFAULT_WARN = 2,
@@ -56,6 +70,7 @@ void print_usage (void);
56void print_help (void); 70void print_help (void);
57int is_pg_dbname (char *); 71int is_pg_dbname (char *);
58int is_pg_logname (char *); 72int is_pg_logname (char *);
73int do_query (PGconn *, char *);
59 74
60char *pghost = NULL; /* host name of the backend server */ 75char *pghost = NULL; /* host name of the backend server */
61char *pgport = NULL; /* port of the backend server */ 76char *pgport = NULL; /* port of the backend server */
@@ -65,14 +80,15 @@ char *pgtty = NULL;
65char dbName[NAMEDATALEN] = DEFAULT_DB; 80char dbName[NAMEDATALEN] = DEFAULT_DB;
66char *pguser = NULL; 81char *pguser = NULL;
67char *pgpasswd = NULL; 82char *pgpasswd = NULL;
83char *pgparams = NULL;
68double twarn = (double)DEFAULT_WARN; 84double twarn = (double)DEFAULT_WARN;
69double tcrit = (double)DEFAULT_CRIT; 85double tcrit = (double)DEFAULT_CRIT;
86char *pgquery = NULL;
87char *query_warning = NULL;
88char *query_critical = NULL;
89thresholds *qthresholds = NULL;
70int verbose = 0; 90int verbose = 0;
71 91
72PGconn *conn;
73/*PGresult *res;*/
74
75
76/****************************************************************************** 92/******************************************************************************
77 93
78The (psuedo?)literate programming XML is contained within \@\@\- <XML> \-\@\@ 94The (psuedo?)literate programming XML is contained within \@\@\- <XML> \-\@\@
@@ -115,10 +131,6 @@ Please note that all tags must be lowercase to use the DocBook XML DTD.
115<sect2> 131<sect2>
116<title>Future Enhancements</title> 132<title>Future Enhancements</title>
117<para>ToDo List</para> 133<para>ToDo List</para>
118<itemizedlist>
119<listitem>Add option to get password from a secured file rather than the command line</listitem>
120<listitem>Add option to specify the query to execute</listitem>
121</itemizedlist>
122</sect2> 134</sect2>
123 135
124 136
@@ -132,8 +144,14 @@ Please note that all tags must be lowercase to use the DocBook XML DTD.
132int 144int
133main (int argc, char **argv) 145main (int argc, char **argv)
134{ 146{
135 int elapsed_time; 147 PGconn *conn;
148 char *conninfo = NULL;
149
150 struct timeval start_timeval;
151 struct timeval end_timeval;
152 double elapsed_time;
136 int status = STATE_UNKNOWN; 153 int status = STATE_UNKNOWN;
154 int query_status = STATE_UNKNOWN;
137 155
138 /* begin, by setting the parameters for a backend connection if the 156 /* begin, by setting the parameters for a backend connection if the
139 * parameters are null, then the system will try to use reasonable 157 * parameters are null, then the system will try to use reasonable
@@ -161,20 +179,41 @@ main (int argc, char **argv)
161 } 179 }
162 alarm (timeout_interval); 180 alarm (timeout_interval);
163 181
164 if (verbose) 182 if (pgparams)
165 printf("Connecting to database:\n DB: %s\n User: %s\n Host: %s\n Port: %d\n", dbName, 183 asprintf (&conninfo, "%s ", pgparams);
166 (pguser != NULL) ? pguser : "unspecified", 184
167 (pghost != NULL) ? pghost : "unspecified", 185 asprintf (&conninfo, "%sdbname = '%s'", conninfo ? conninfo : "", dbName);
168 (pgport != NULL) ? atoi(pgport) : DEFAULT_PORT); 186 if (pghost)
187 asprintf (&conninfo, "%s host = '%s'", conninfo, pghost);
188 if (pgport)
189 asprintf (&conninfo, "%s port = '%s'", conninfo, pgport);
190 if (pgoptions)
191 asprintf (&conninfo, "%s options = '%s'", conninfo, pgoptions);
192 /* if (pgtty) -- ignored by PQconnectdb */
193 if (pguser)
194 asprintf (&conninfo, "%s user = '%s'", conninfo, pguser);
195
196 if (verbose) /* do not include password (see right below) in output */
197 printf ("Connecting to PostgreSQL using conninfo: %s%s\n", conninfo,
198 pgpasswd ? " password = <hidden>" : "");
199
200 if (pgpasswd)
201 asprintf (&conninfo, "%s password = '%s'", conninfo, pgpasswd);
169 202
170 /* make a connection to the database */ 203 /* make a connection to the database */
171 time (&start_time); 204 gettimeofday (&start_timeval, NULL);
172 conn = 205 conn = PQconnectdb (conninfo);
173 PQsetdbLogin (pghost, pgport, pgoptions, pgtty, dbName, pguser, pgpasswd); 206 gettimeofday (&end_timeval, NULL);
174 time (&end_time); 207
175 elapsed_time = (int) (end_time - start_time); 208 while (start_timeval.tv_usec > end_timeval.tv_usec) {
209 --end_timeval.tv_sec;
210 end_timeval.tv_usec += 1000000;
211 }
212 elapsed_time = (double)(end_timeval.tv_sec - start_timeval.tv_sec)
213 + (double)(end_timeval.tv_usec - start_timeval.tv_usec) / 1000000.0;
214
176 if (verbose) 215 if (verbose)
177 printf("Time elapsed: %d\n", elapsed_time); 216 printf("Time elapsed: %f\n", elapsed_time);
178 217
179 /* check to see that the backend connection was successfully made */ 218 /* check to see that the backend connection was successfully made */
180 if (verbose) 219 if (verbose)
@@ -194,14 +233,32 @@ main (int argc, char **argv)
194 else { 233 else {
195 status = STATE_OK; 234 status = STATE_OK;
196 } 235 }
236
237 if (verbose) {
238 char *server_host = PQhost (conn);
239 int server_version = PQserverVersion (conn);
240
241 printf ("Successfully connected to database %s (user %s) "
242 "at server %s%s%s (server version: %d.%d.%d, "
243 "protocol version: %d, pid: %d)\n",
244 PQdb (conn), PQuser (conn),
245 PSQL_SOCKET3 (server_host, PQport (conn)),
246 PSQL_SERVER_VERSION3 (server_version),
247 PQprotocolVersion (conn), PQbackendPID (conn));
248 }
249
250 printf (_(" %s - database %s (%f sec.)|%s\n"),
251 state_text(status), dbName, elapsed_time,
252 fperfdata("time", elapsed_time, "s",
253 !!(twarn > 0.0), twarn, !!(tcrit > 0.0), tcrit, TRUE, 0, FALSE,0));
254
255 if (pgquery)
256 query_status = do_query (conn, pgquery);
257
197 if (verbose) 258 if (verbose)
198 printf("Closing connection\n"); 259 printf("Closing connection\n");
199 PQfinish (conn); 260 PQfinish (conn);
200 printf (_(" %s - database %s (%d sec.)|%s\n"), 261 return (query_status > status) ? query_status : status;
201 state_text(status), dbName, elapsed_time,
202 fperfdata("time", elapsed_time, "s",
203 (int)twarn, twarn, (int)tcrit, tcrit, TRUE, 0, FALSE,0));
204 return status;
205} 262}
206 263
207 264
@@ -225,12 +282,16 @@ process_arguments (int argc, char **argv)
225 {"authorization", required_argument, 0, 'a'}, 282 {"authorization", required_argument, 0, 'a'},
226 {"port", required_argument, 0, 'P'}, 283 {"port", required_argument, 0, 'P'},
227 {"database", required_argument, 0, 'd'}, 284 {"database", required_argument, 0, 'd'},
285 {"option", required_argument, 0, 'o'},
286 {"query", required_argument, 0, 'q'},
287 {"query_critical", required_argument, 0, 'C'},
288 {"query_warning", required_argument, 0, 'W'},
228 {"verbose", no_argument, 0, 'v'}, 289 {"verbose", no_argument, 0, 'v'},
229 {0, 0, 0, 0} 290 {0, 0, 0, 0}
230 }; 291 };
231 292
232 while (1) { 293 while (1) {
233 c = getopt_long (argc, argv, "hVt:c:w:H:P:d:l:p:a:v", 294 c = getopt_long (argc, argv, "hVt:c:w:H:P:d:l:p:a:o:q:C:W:v",
234 longopts, &option); 295 longopts, &option);
235 296
236 if (c == EOF) 297 if (c == EOF)
@@ -263,8 +324,14 @@ process_arguments (int argc, char **argv)
263 else 324 else
264 twarn = strtod (optarg, NULL); 325 twarn = strtod (optarg, NULL);
265 break; 326 break;
327 case 'C': /* critical query threshold */
328 query_critical = optarg;
329 break;
330 case 'W': /* warning query threshold */
331 query_warning = optarg;
332 break;
266 case 'H': /* host */ 333 case 'H': /* host */
267 if (!is_host (optarg)) 334 if ((*optarg != '/') && (!is_host (optarg)))
268 usage2 (_("Invalid hostname/address"), optarg); 335 usage2 (_("Invalid hostname/address"), optarg);
269 else 336 else
270 pghost = optarg; 337 pghost = optarg;
@@ -291,12 +358,23 @@ process_arguments (int argc, char **argv)
291 case 'a': 358 case 'a':
292 pgpasswd = optarg; 359 pgpasswd = optarg;
293 break; 360 break;
361 case 'o':
362 if (pgparams)
363 asprintf (&pgparams, "%s %s", pgparams, optarg);
364 else
365 asprintf (&pgparams, "%s", optarg);
366 break;
367 case 'q':
368 pgquery = optarg;
369 break;
294 case 'v': 370 case 'v':
295 verbose++; 371 verbose++;
296 break; 372 break;
297 } 373 }
298 } 374 }
299 375
376 set_thresholds (&qthresholds, query_warning, query_critical);
377
300 return validate_arguments (); 378 return validate_arguments ();
301} 379}
302 380
@@ -434,8 +512,6 @@ print_help (void)
434 512
435 printf (UT_HOST_PORT, 'P', myport); 513 printf (UT_HOST_PORT, 'P', myport);
436 514
437 printf (UT_IPv46);
438
439 printf (" %s\n", "-d, --database=STRING"); 515 printf (" %s\n", "-d, --database=STRING");
440 printf (" %s", _("Database to check ")); 516 printf (" %s", _("Database to check "));
441 printf (_("(default: %s)"), DEFAULT_DB); 517 printf (_("(default: %s)"), DEFAULT_DB);
@@ -443,11 +519,20 @@ print_help (void)
443 printf (" %s\n", _("Login name of user")); 519 printf (" %s\n", _("Login name of user"));
444 printf (" %s\n", "-p, --password = STRING"); 520 printf (" %s\n", "-p, --password = STRING");
445 printf (" %s\n", _("Password (BIG SECURITY ISSUE)")); 521 printf (" %s\n", _("Password (BIG SECURITY ISSUE)"));
522 printf (" %s\n", "-o, --option = STRING");
523 printf (" %s\n", _("Connection parameters (keyword = value), see below"));
446 524
447 printf (UT_WARN_CRIT); 525 printf (UT_WARN_CRIT);
448 526
449 printf (UT_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); 527 printf (UT_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
450 528
529 printf (" %s\n", "-q, --query=STRING");
530 printf (" %s\n", _("SQL query to run. Only first column in first row will be read"));
531 printf (" %s\n", "-W, --query-warning=RANGE");
532 printf (" %s\n", _("SQL query value to result in warning status (double)"));
533 printf (" %s\n", "-C, --query-critical=RANGE");
534 printf (" %s\n", _("SQL query value to result in critical status (double)"));
535
451 printf (UT_VERBOSE); 536 printf (UT_VERBOSE);
452 537
453 printf ("\n"); 538 printf ("\n");
@@ -458,6 +543,22 @@ print_help (void)
458 printf (" %s\n", _("connects to the template1 database, which is present in every functioning")); 543 printf (" %s\n", _("connects to the template1 database, which is present in every functioning"));
459 printf (" %s\n\n", _("PostgreSQL DBMS.")); 544 printf (" %s\n\n", _("PostgreSQL DBMS."));
460 545
546 printf (" %s\n", _("If a query is specified using the -q option, it will be executed after"));
547 printf (" %s\n", _("connecting to the server. The result from the query has to be numeric."));
548 printf (" %s\n", _("Multiple SQL commands, separated by semicolon, are allowed but the result "));
549 printf (" %s\n", _("of the last command is taken into account only. The value of the first"));
550 printf (" %s\n\n", _("column in the first row is used as the check result."));
551
552 printf (" %s\n", _("See the chapter \"Monitoring Database Activity\" of the PostgreSQL manual"));
553 printf (" %s\n\n", _("for details about how to access internal statistics of the database server."));
554
555 printf (" %s\n", _("For a list of available connection parameters which may be used with the -o"));
556 printf (" %s\n", _("command line option, see the documentation for PQconnectdb() in the chapter"));
557 printf (" %s\n", _("\"libpq - C Library\" of the PostgreSQL manual. For example, this may be"));
558 printf (" %s\n", _("used to specify a service name in pg_service.conf to be used for additional"));
559 printf (" %s\n", _("connection parameters: -o 'service=<name>' or to specify the SSL mode:"));
560 printf (" %s\n\n", _("-o 'sslmode=require'."));
561
461 printf (" %s\n", _("The plugin will connect to a local postmaster if no host is specified. To")); 562 printf (" %s\n", _("The plugin will connect to a local postmaster if no host is specified. To"));
462 printf (" %s\n", _("connect to a remote host, be sure that the remote postmaster accepts TCP/IP")); 563 printf (" %s\n", _("connect to a remote host, be sure that the remote postmaster accepts TCP/IP"));
463 printf (" %s\n\n", _("connections (start the postmaster with the -i option).")); 564 printf (" %s\n\n", _("connections (start the postmaster with the -i option)."));
@@ -475,6 +576,75 @@ void
475print_usage (void) 576print_usage (void)
476{ 577{
477 printf ("%s\n", _("Usage:")); 578 printf ("%s\n", _("Usage:"));
478 printf ("%s [-H <host>] [-4|-6] [-P <port>] [-c <critical time>] [-w <warning time>]\n", progname); 579 printf ("%s [-H <host>] [-P <port>] [-c <critical time>] [-w <warning time>]\n", progname);
479 printf (" [-t <timeout>] [-d <database>] [-l <logname>] [-p <password>]\n"); 580 printf (" [-t <timeout>] [-d <database>] [-l <logname>] [-p <password>]\n"
581 "[-q <query>] [-C <critical query range>] [-W <warning query range>]\n");
480} 582}
583
584int
585do_query (PGconn *conn, char *query)
586{
587 PGresult *res;
588
589 char *val_str;
590 double value;
591
592 char *endptr = NULL;
593
594 int my_status = STATE_UNKNOWN;
595
596 if (verbose)
597 printf ("Executing SQL query \"%s\".\n", query);
598 res = PQexec (conn, query);
599
600 if (PGRES_TUPLES_OK != PQresultStatus (res)) {
601 printf (_("QUERY %s - %s: %s.\n"), _("CRITICAL"), _("Error with query"),
602 PQerrorMessage (conn));
603 return STATE_CRITICAL;
604 }
605
606 if (PQntuples (res) < 1) {
607 printf ("QUERY %s - %s.\n", _("WARNING"), _("No rows returned"));
608 return STATE_WARNING;
609 }
610
611 if (PQnfields (res) < 1) {
612 printf ("QUERY %s - %s.\n", _("WARNING"), _("No columns returned"));
613 return STATE_WARNING;
614 }
615
616 val_str = PQgetvalue (res, 0, 0);
617 if (! val_str) {
618 printf ("QUERY %s - %s.\n", _("CRITICAL"), _("No data returned"));
619 return STATE_CRITICAL;
620 }
621
622 value = strtod (val_str, &endptr);
623 if (verbose)
624 printf ("Query result: %f\n", value);
625
626 if (endptr == val_str) {
627 printf ("QUERY %s - %s: %s\n", _("CRITICAL"), _("Is not a numeric"), val_str);
628 return STATE_CRITICAL;
629 }
630 else if ((endptr != NULL) && (*endptr != '\0')) {
631 if (verbose)
632 printf ("Garbage after value: %s.\n", endptr);
633 }
634
635 my_status = get_status (value, qthresholds);
636 printf ("QUERY %s - ",
637 (my_status == STATE_OK)
638 ? _("OK")
639 : (my_status == STATE_WARNING)
640 ? _("WARNING")
641 : (my_status == STATE_CRITICAL)
642 ? _("CRITICAL")
643 : _("UNKNOWN"));
644 printf (_("'%s' returned %f"), query, value);
645 printf ("|query=%f;%s;%s;;\n", value,
646 query_warning ? query_warning : "",
647 query_critical ? query_critical : "");
648 return my_status;
649}
650
diff --git a/plugins/check_procs.c b/plugins/check_procs.c
index 00b032a..d09bd8b 100644
--- a/plugins/check_procs.c
+++ b/plugins/check_procs.c
@@ -42,6 +42,11 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net";
42#include "regex.h" 42#include "regex.h"
43 43
44#include <pwd.h> 44#include <pwd.h>
45#include <errno.h>
46
47#ifdef HAVE_SYS_STAT_H
48#include <sys/stat.h>
49#endif
45 50
46int process_arguments (int, char **); 51int process_arguments (int, char **);
47int validate_arguments (void); 52int validate_arguments (void);
@@ -65,6 +70,10 @@ int options = 0; /* bitmask of filter criteria to test against */
65#define PCPU 256 70#define PCPU 256
66#define ELAPSED 512 71#define ELAPSED 512
67#define EREG_ARGS 1024 72#define EREG_ARGS 1024
73
74#define KTHREAD_PARENT "kthreadd" /* the parent process of kernel threads:
75 ppid of procs are compared to pid of this proc*/
76
68/* Different metrics */ 77/* Different metrics */
69char *metric_name; 78char *metric_name;
70enum metric { 79enum metric {
@@ -90,9 +99,21 @@ regex_t re_args;
90char *fmt; 99char *fmt;
91char *fails; 100char *fails;
92char tmp[MAX_INPUT_BUFFER]; 101char tmp[MAX_INPUT_BUFFER];
102int kthread_filter = 0;
103int usepid = 0; /* whether to test for pid or /proc/pid/exe */
93 104
94FILE *ps_input = NULL; 105FILE *ps_input = NULL;
95 106
107static int
108stat_exe (const pid_t pid, struct stat *buf) {
109 char *path;
110 int ret;
111 xasprintf(&path, "/proc/%d/exe", pid);
112 ret = stat(path, buf);
113 free(path);
114 return ret;
115}
116
96 117
97int 118int
98main (int argc, char **argv) 119main (int argc, char **argv)
@@ -102,9 +123,13 @@ main (int argc, char **argv)
102 char *procprog; 123 char *procprog;
103 124
104 pid_t mypid = 0; 125 pid_t mypid = 0;
126 struct stat statbuf;
127 dev_t mydev = 0;
128 ino_t myino = 0;
105 int procuid = 0; 129 int procuid = 0;
106 pid_t procpid = 0; 130 pid_t procpid = 0;
107 pid_t procppid = 0; 131 pid_t procppid = 0;
132 pid_t kthread_ppid = 0;
108 int procvsz = 0; 133 int procvsz = 0;
109 int procrss = 0; 134 int procrss = 0;
110 int procseconds = 0; 135 int procseconds = 0;
@@ -125,6 +150,7 @@ main (int argc, char **argv)
125 int crit = 0; /* number of processes in crit state */ 150 int crit = 0; /* number of processes in crit state */
126 int i = 0, j = 0; 151 int i = 0, j = 0;
127 int result = STATE_UNKNOWN; 152 int result = STATE_UNKNOWN;
153 int ret;
128 output chld_out, chld_err; 154 output chld_out, chld_err;
129 155
130 setlocale (LC_ALL, ""); 156 setlocale (LC_ALL, "");
@@ -144,8 +170,16 @@ main (int argc, char **argv)
144 if (process_arguments (argc, argv) == ERROR) 170 if (process_arguments (argc, argv) == ERROR)
145 usage4 (_("Could not parse arguments")); 171 usage4 (_("Could not parse arguments"));
146 172
147 /* get our pid */ 173 /* find ourself */
148 mypid = getpid(); 174 mypid = getpid();
175 if (usepid || stat_exe(mypid, &statbuf) == -1) {
176 /* usepid might have been set by -T */
177 usepid = 1;
178 } else {
179 usepid = 0;
180 mydev = statbuf.st_dev;
181 myino = statbuf.st_ino;
182 }
149 183
150 /* Set signal handling and alarm timeout */ 184 /* Set signal handling and alarm timeout */
151 if (signal (SIGALRM, timeout_alarm_handler) == SIG_ERR) { 185 if (signal (SIGALRM, timeout_alarm_handler) == SIG_ERR) {
@@ -200,7 +234,28 @@ main (int argc, char **argv)
200 procetime, procprog, procargs); 234 procetime, procprog, procargs);
201 235
202 /* Ignore self */ 236 /* Ignore self */
203 if (mypid == procpid) continue; 237 if ((usepid && mypid == procpid) ||
238 (!usepid && ((ret = stat_exe(procpid, &statbuf) != -1) && statbuf.st_dev == mydev && statbuf.st_ino == myino) ||
239 (ret == -1 && errno == ENOENT))) {
240 if (verbose >= 3)
241 printf("not considering - is myself or gone\n");
242 continue;
243 }
244
245 /* filter kernel threads (childs of KTHREAD_PARENT)*/
246 /* TODO adapt for other OSes than GNU/Linux
247 sorry for not doing that, but I've no other OSes to test :-( */
248 if (kthread_filter == 1) {
249 /* get pid KTHREAD_PARENT */
250 if (kthread_ppid == 0 && !strcmp(procprog, KTHREAD_PARENT) )
251 kthread_ppid = procpid;
252
253 if (kthread_ppid == procppid) {
254 if (verbose >= 2)
255 printf ("Ignore kernel thread: pid=%d ppid=%d prog=%s args=%s\n", procpid, procppid, procprog, procargs);
256 continue;
257 }
258 }
204 259
205 if ((options & STAT) && (strstr (statopts, procstat))) 260 if ((options & STAT) && (strstr (statopts, procstat)))
206 resultsum |= STAT; 261 resultsum |= STAT;
@@ -332,6 +387,7 @@ process_arguments (int argc, char **argv)
332 {"timeout", required_argument, 0, 't'}, 387 {"timeout", required_argument, 0, 't'},
333 {"status", required_argument, 0, 's'}, 388 {"status", required_argument, 0, 's'},
334 {"ppid", required_argument, 0, 'p'}, 389 {"ppid", required_argument, 0, 'p'},
390 {"user", required_argument, 0, 'u'},
335 {"command", required_argument, 0, 'C'}, 391 {"command", required_argument, 0, 'C'},
336 {"vsz", required_argument, 0, 'z'}, 392 {"vsz", required_argument, 0, 'z'},
337 {"rss", required_argument, 0, 'r'}, 393 {"rss", required_argument, 0, 'r'},
@@ -343,6 +399,8 @@ process_arguments (int argc, char **argv)
343 {"verbose", no_argument, 0, 'v'}, 399 {"verbose", no_argument, 0, 'v'},
344 {"ereg-argument-array", required_argument, 0, CHAR_MAX+1}, 400 {"ereg-argument-array", required_argument, 0, CHAR_MAX+1},
345 {"input-file", required_argument, 0, CHAR_MAX+2}, 401 {"input-file", required_argument, 0, CHAR_MAX+2},
402 {"no-kthreads", required_argument, 0, 'k'},
403 {"traditional-filter", no_argument, 0, 'T'},
346 {0, 0, 0, 0} 404 {0, 0, 0, 0}
347 }; 405 };
348 406
@@ -351,7 +409,7 @@ process_arguments (int argc, char **argv)
351 strcpy (argv[c], "-t"); 409 strcpy (argv[c], "-t");
352 410
353 while (1) { 411 while (1) {
354 c = getopt_long (argc, argv, "Vvht:c:w:p:s:u:C:a:z:r:m:P:", 412 c = getopt_long (argc, argv, "Vvhkt:c:w:p:s:u:C:a:z:r:m:P:T",
355 longopts, &option); 413 longopts, &option);
356 414
357 if (c == -1 || c == EOF) 415 if (c == -1 || c == EOF)
@@ -495,9 +553,15 @@ process_arguments (int argc, char **argv)
495 } 553 }
496 554
497 usage4 (_("Metric must be one of PROCS, VSZ, RSS, CPU, ELAPSED!")); 555 usage4 (_("Metric must be one of PROCS, VSZ, RSS, CPU, ELAPSED!"));
556 case 'k': /* linux kernel thread filter */
557 kthread_filter = 1;
558 break;
498 case 'v': /* command */ 559 case 'v': /* command */
499 verbose++; 560 verbose++;
500 break; 561 break;
562 case 'T':
563 usepid = 1;
564 break;
501 case CHAR_MAX+2: 565 case CHAR_MAX+2:
502 input_filename = optarg; 566 input_filename = optarg;
503 break; 567 break;
@@ -648,6 +712,9 @@ print_help (void)
648 printf (" %s\n", "-v, --verbose"); 712 printf (" %s\n", "-v, --verbose");
649 printf (" %s\n", _("Extra information. Up to 3 verbosity levels")); 713 printf (" %s\n", _("Extra information. Up to 3 verbosity levels"));
650 714
715 printf (" %s\n", "-T, --traditional");
716 printf (" %s\n", _("Filter own process the traditional way by PID instead of /proc/pid/exe"));
717
651 printf ("\n"); 718 printf ("\n");
652 printf ("%s\n", "Filters:"); 719 printf ("%s\n", "Filters:");
653 printf (" %s\n", "-s, --state=STATUSFLAGS"); 720 printf (" %s\n", "-s, --state=STATUSFLAGS");
@@ -670,6 +737,8 @@ print_help (void)
670 printf (" %s\n", _("Only scan for processes with args that contain the regex STRING.")); 737 printf (" %s\n", _("Only scan for processes with args that contain the regex STRING."));
671 printf (" %s\n", "-C, --command=COMMAND"); 738 printf (" %s\n", "-C, --command=COMMAND");
672 printf (" %s\n", _("Only scan for exact matches of COMMAND (without path).")); 739 printf (" %s\n", _("Only scan for exact matches of COMMAND (without path)."));
740 printf (" %s\n", "-k, --no-kthreads");
741 printf (" %s\n", _("Only scan for non kernel threads (works on Linux only)."));
673 742
674 printf(_("\n\ 743 printf(_("\n\
675RANGEs are specified 'min:max' or 'min:' or ':max' (or 'max'). If\n\ 744RANGEs are specified 'min:max' or 'min:' or ':max' (or 'max'). If\n\
@@ -704,5 +773,5 @@ print_usage (void)
704 printf ("%s\n", _("Usage:")); 773 printf ("%s\n", _("Usage:"));
705 printf ("%s -w <range> -c <range> [-m metric] [-s state] [-p ppid]\n", progname); 774 printf ("%s -w <range> -c <range> [-m metric] [-s state] [-p ppid]\n", progname);
706 printf (" [-u user] [-r rss] [-z vsz] [-P %%cpu] [-a argument-array]\n"); 775 printf (" [-u user] [-r rss] [-z vsz] [-P %%cpu] [-a argument-array]\n");
707 printf (" [-C command] [-t timeout] [-v]\n"); 776 printf (" [-C command] [-k] [-t timeout] [-v]\n");
708} 777}
diff --git a/plugins/check_smtp.c b/plugins/check_smtp.c
index 79fa482..d477a51 100644
--- a/plugins/check_smtp.c
+++ b/plugins/check_smtp.c
@@ -99,9 +99,9 @@ char **responses = NULL;
99char *authtype = NULL; 99char *authtype = NULL;
100char *authuser = NULL; 100char *authuser = NULL;
101char *authpass = NULL; 101char *authpass = NULL;
102int warning_time = 0; 102double warning_time = 0;
103int check_warning_time = FALSE; 103int check_warning_time = FALSE;
104int critical_time = 0; 104double critical_time = 0;
105int check_critical_time = FALSE; 105int check_critical_time = FALSE;
106int verbose = 0; 106int verbose = 0;
107int use_ssl = FALSE; 107int use_ssl = FALSE;
@@ -417,9 +417,9 @@ main (int argc, char **argv)
417 elapsed_time = (double)microsec / 1.0e6; 417 elapsed_time = (double)microsec / 1.0e6;
418 418
419 if (result == STATE_OK) { 419 if (result == STATE_OK) {
420 if (check_critical_time && elapsed_time > (double) critical_time) 420 if (check_critical_time && elapsed_time > critical_time)
421 result = STATE_CRITICAL; 421 result = STATE_CRITICAL;
422 else if (check_warning_time && elapsed_time > (double) warning_time) 422 else if (check_warning_time && elapsed_time > warning_time)
423 result = STATE_WARNING; 423 result = STATE_WARNING;
424 } 424 }
425 425
@@ -552,21 +552,19 @@ process_arguments (int argc, char **argv)
552 nresponses++; 552 nresponses++;
553 break; 553 break;
554 case 'c': /* critical time threshold */ 554 case 'c': /* critical time threshold */
555 if (is_intnonneg (optarg)) { 555 if (!is_nonnegative (optarg))
556 critical_time = atoi (optarg); 556 usage4 (_("Critical time must be a positive"));
557 check_critical_time = TRUE;
558 }
559 else { 557 else {
560 usage4 (_("Critical time must be a positive integer")); 558 critical_time = strtod (optarg, NULL);
559 check_critical_time = TRUE;
561 } 560 }
562 break; 561 break;
563 case 'w': /* warning time threshold */ 562 case 'w': /* warning time threshold */
564 if (is_intnonneg (optarg)) { 563 if (!is_nonnegative (optarg))
565 warning_time = atoi (optarg); 564 usage4 (_("Warning time must be a positive"));
566 check_warning_time = TRUE;
567 }
568 else { 565 else {
569 usage4 (_("Warning time must be a positive integer")); 566 warning_time = strtod (optarg, NULL);
567 check_warning_time = TRUE;
570 } 568 }
571 break; 569 break;
572 case 'v': /* verbose */ 570 case 'v': /* verbose */
diff --git a/plugins/check_snmp.c b/plugins/check_snmp.c
index c73562b..9ca845d 100644
--- a/plugins/check_snmp.c
+++ b/plugins/check_snmp.c
@@ -63,6 +63,7 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net";
63#define L_CALCULATE_RATE CHAR_MAX+1 63#define L_CALCULATE_RATE CHAR_MAX+1
64#define L_RATE_MULTIPLIER CHAR_MAX+2 64#define L_RATE_MULTIPLIER CHAR_MAX+2
65#define L_INVERT_SEARCH CHAR_MAX+3 65#define L_INVERT_SEARCH CHAR_MAX+3
66#define L_OFFSET CHAR_MAX+4
66 67
67/* Gobble to string - stop incrementing c when c[0] match one of the 68/* Gobble to string - stop incrementing c when c[0] match one of the
68 * characters in s */ 69 * characters in s */
@@ -142,6 +143,7 @@ char *output_delim;
142char *miblist = NULL; 143char *miblist = NULL;
143int needmibs = FALSE; 144int needmibs = FALSE;
144int calculate_rate = 0; 145int calculate_rate = 0;
146double offset = 0.0;
145int rate_multiplier = 1; 147int rate_multiplier = 1;
146state_data *previous_state; 148state_data *previous_state;
147double *previous_value; 149double *previous_value;
@@ -153,16 +155,18 @@ static char *fix_snmp_range(char *th)
153{ 155{
154 double left, right; 156 double left, right;
155 char *colon, *ret; 157 char *colon, *ret;
156 if (!(colon = strchr(th, ':'))) 158
159 if ((colon = strchr(th, ':')) == NULL || *(colon + 1) == '\0')
157 return th; 160 return th;
158 *colon = 0;
159 161
160 left = strtod(th, NULL); 162 left = strtod(th, NULL);
161 right = strtod(colon + 1, NULL); 163 right = strtod(colon + 1, NULL);
162 if (right >= left) { 164 if (right >= left)
163 return th; 165 return th;
164 } 166
165 ret = malloc(strlen(th) + strlen(colon + 1) + 2); 167 if ((ret = malloc(strlen(th) + 2)) == NULL)
168 die(STATE_UNKNOWN, _("Cannot malloc"));
169 *colon = '\0';
166 sprintf(ret, "@%s:%s", colon + 1, th); 170 sprintf(ret, "@%s:%s", colon + 1, th);
167 free(th); 171 free(th);
168 return ret; 172 return ret;
@@ -292,35 +296,36 @@ main (int argc, char **argv)
292 snmpcmd = strdup (PATH_TO_SNMPGET); 296 snmpcmd = strdup (PATH_TO_SNMPGET);
293 } 297 }
294 298
295 /* 9 arguments to pass before authpriv options + 1 for host and numoids. Add one for terminating NULL */ 299 /* 10 arguments to pass before authpriv options + 1 for host and numoids. Add one for terminating NULL */
296 command_line = calloc (9 + numauthpriv + 1 + numoids + 1, sizeof (char *)); 300 command_line = calloc (10 + numauthpriv + 1 + numoids + 1, sizeof (char *));
297 command_line[0] = snmpcmd; 301 command_line[0] = snmpcmd;
298 command_line[1] = strdup ("-t"); 302 command_line[1] = strdup ("-Le");
299 xasprintf (&command_line[2], "%d", timeout_interval); 303 command_line[2] = strdup ("-t");
300 command_line[3] = strdup ("-r"); 304 xasprintf (&command_line[3], "%d", timeout_interval);
301 xasprintf (&command_line[4], "%d", retries); 305 command_line[4] = strdup ("-r");
302 command_line[5] = strdup ("-m"); 306 xasprintf (&command_line[5], "%d", retries);
303 command_line[6] = strdup (miblist); 307 command_line[6] = strdup ("-m");
304 command_line[7] = "-v"; 308 command_line[7] = strdup (miblist);
305 command_line[8] = strdup (proto); 309 command_line[8] = "-v";
310 command_line[9] = strdup (proto);
306 311
307 for (i = 0; i < numauthpriv; i++) { 312 for (i = 0; i < numauthpriv; i++) {
308 command_line[9 + i] = authpriv[i]; 313 command_line[10 + i] = authpriv[i];
309 } 314 }
310 315
311 xasprintf (&command_line[9 + numauthpriv], "%s:%s", server_address, port); 316 xasprintf (&command_line[10 + numauthpriv], "%s:%s", server_address, port);
312 317
313 /* This is just for display purposes, so it can remain a string */ 318 /* This is just for display purposes, so it can remain a string */
314 xasprintf(&cl_hidden_auth, "%s -t %d -r %d -m %s -v %s %s %s:%s", 319 xasprintf(&cl_hidden_auth, "%s -Le -t %d -r %d -m %s -v %s %s %s:%s",
315 snmpcmd, timeout_interval, retries, strlen(miblist) ? miblist : "''", proto, "[authpriv]", 320 snmpcmd, timeout_interval, retries, strlen(miblist) ? miblist : "''", proto, "[authpriv]",
316 server_address, port); 321 server_address, port);
317 322
318 for (i = 0; i < numoids; i++) { 323 for (i = 0; i < numoids; i++) {
319 command_line[9 + numauthpriv + 1 + i] = oids[i]; 324 command_line[10 + numauthpriv + 1 + i] = oids[i];
320 xasprintf(&cl_hidden_auth, "%s %s", cl_hidden_auth, oids[i]); 325 xasprintf(&cl_hidden_auth, "%s %s", cl_hidden_auth, oids[i]);
321 } 326 }
322 327
323 command_line[9 + numauthpriv + 1 + numoids] = NULL; 328 command_line[10 + numauthpriv + 1 + numoids] = NULL;
324 329
325 if (verbose) 330 if (verbose)
326 printf ("%s\n", cl_hidden_auth); 331 printf ("%s\n", cl_hidden_auth);
@@ -451,7 +456,7 @@ main (int argc, char **argv)
451 response_size += OID_COUNT_STEP; 456 response_size += OID_COUNT_STEP;
452 response_value = realloc(response_value, response_size * sizeof(*response_value)); 457 response_value = realloc(response_value, response_size * sizeof(*response_value));
453 } 458 }
454 response_value[i] = strtod (ptr, NULL); 459 response_value[i] = strtod (ptr, NULL) + offset;
455 460
456 if(calculate_rate) { 461 if(calculate_rate) {
457 if (previous_state!=NULL) { 462 if (previous_state!=NULL) {
@@ -640,6 +645,7 @@ process_arguments (int argc, char **argv)
640 {"next", no_argument, 0, 'n'}, 645 {"next", no_argument, 0, 'n'},
641 {"rate", no_argument, 0, L_CALCULATE_RATE}, 646 {"rate", no_argument, 0, L_CALCULATE_RATE},
642 {"rate-multiplier", required_argument, 0, L_RATE_MULTIPLIER}, 647 {"rate-multiplier", required_argument, 0, L_RATE_MULTIPLIER},
648 {"offset", required_argument, 0, L_OFFSET},
643 {"invert-search", no_argument, 0, L_INVERT_SEARCH}, 649 {"invert-search", no_argument, 0, L_INVERT_SEARCH},
644 {"perf-oids", no_argument, 0, 'O'}, 650 {"perf-oids", no_argument, 0, 'O'},
645 {0, 0, 0, 0} 651 {0, 0, 0, 0}
@@ -872,6 +878,9 @@ process_arguments (int argc, char **argv)
872 if(!is_integer(optarg)||((rate_multiplier=atoi(optarg))<=0)) 878 if(!is_integer(optarg)||((rate_multiplier=atoi(optarg))<=0))
873 usage2(_("Rate multiplier must be a positive integer"),optarg); 879 usage2(_("Rate multiplier must be a positive integer"),optarg);
874 break; 880 break;
881 case L_OFFSET:
882 offset=strtod(optarg,NULL);
883 break;
875 case L_INVERT_SEARCH: 884 case L_INVERT_SEARCH:
876 invert_search=1; 885 invert_search=1;
877 break; 886 break;
@@ -1120,6 +1129,8 @@ print_help (void)
1120 printf (" %s\n", _("Enable rate calculation. See 'Rate Calculation' below")); 1129 printf (" %s\n", _("Enable rate calculation. See 'Rate Calculation' below"));
1121 printf (" %s\n", "--rate-multiplier"); 1130 printf (" %s\n", "--rate-multiplier");
1122 printf (" %s\n", _("Converts rate per second. For example, set to 60 to convert to per minute")); 1131 printf (" %s\n", _("Converts rate per second. For example, set to 60 to convert to per minute"));
1132 printf (" %s\n", "--offset=OFFSET");
1133 printf (" %s\n", _("Add/substract the specified OFFSET to numeric sensor data"));
1123 1134
1124 /* Tests Against Strings */ 1135 /* Tests Against Strings */
1125 printf (" %s\n", "-s, --string=STRING"); 1136 printf (" %s\n", "-s, --string=STRING");
diff --git a/plugins/check_tcp.c b/plugins/check_tcp.c
index af3ae24..ce966c3 100644
--- a/plugins/check_tcp.c
+++ b/plugins/check_tcp.c
@@ -1,30 +1,30 @@
1/***************************************************************************** 1/*****************************************************************************
2* 2*
3* Nagios check_tcp plugin 3* Nagios check_tcp plugin
4* 4*
5* License: GPL 5* License: GPL
6* Copyright (c) 1999-2008 Nagios Plugins Development Team 6* Copyright (c) 1999-2008 Nagios Plugins Development Team
7* 7*
8* Description: 8* Description:
9* 9*
10* This file contains the check_tcp plugin 10* This file contains the check_tcp plugin
11* 11*
12* 12*
13* This program is free software: you can redistribute it and/or modify 13* This program is free software: you can redistribute it and/or modify
14* it under the terms of the GNU General Public License as published by 14* it under the terms of the GNU General Public License as published by
15* the Free Software Foundation, either version 3 of the License, or 15* the Free Software Foundation, either version 3 of the License, or
16* (at your option) any later version. 16* (at your option) any later version.
17* 17*
18* This program is distributed in the hope that it will be useful, 18* This program is distributed in the hope that it will be useful,
19* but WITHOUT ANY WARRANTY; without even the implied warranty of 19* but WITHOUT ANY WARRANTY; without even the implied warranty of
20* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21* GNU General Public License for more details. 21* GNU General Public License for more details.
22* 22*
23* You should have received a copy of the GNU General Public License 23* You should have received a copy of the GNU General Public License
24* along with this program. If not, see <http://www.gnu.org/licenses/>. 24* along with this program. If not, see <http://www.gnu.org/licenses/>.
25* 25*
26* $Id$ 26* $Id$
27* 27*
28*****************************************************************************/ 28*****************************************************************************/
29 29
30/* progname "check_tcp" changes depending on symlink called */ 30/* progname "check_tcp" changes depending on symlink called */
@@ -61,6 +61,7 @@ static int PORT = 0;
61 61
62static int server_port = 0; 62static int server_port = 0;
63static char *server_address = NULL; 63static char *server_address = NULL;
64static int host_specified = FALSE;
64static char *server_send = NULL; 65static char *server_send = NULL;
65static char *server_quit = NULL; 66static char *server_quit = NULL;
66static char **server_expect; 67static char **server_expect;
@@ -462,6 +463,7 @@ process_arguments (int argc, char **argv)
462#endif 463#endif
463 break; 464 break;
464 case 'H': /* hostname */ 465 case 'H': /* hostname */
466 host_specified = TRUE;
465 server_address = optarg; 467 server_address = optarg;
466 break; 468 break;
467 case 'c': /* critical */ 469 case 'c': /* critical */
@@ -588,6 +590,10 @@ process_arguments (int argc, char **argv)
588 } 590 }
589 } 591 }
590 592
593 c = optind;
594 if(host_specified == FALSE && c < argc)
595 server_address = strdup (argv[c++]);
596
591 if (server_address == NULL) 597 if (server_address == NULL)
592 usage4 (_("You must provide a server address")); 598 usage4 (_("You must provide a server address"));
593 else if (server_address[0] != '/' && is_host (server_address) == FALSE) 599 else if (server_address[0] != '/' && is_host (server_address) == FALSE)
@@ -666,4 +672,3 @@ print_usage (void)
666 printf ("[-t <timeout seconds>] [-r <refuse state>] [-M <mismatch state>] [-v] [-4|-6] [-j]\n"); 672 printf ("[-t <timeout seconds>] [-r <refuse state>] [-M <mismatch state>] [-v] [-4|-6] [-j]\n");
667 printf ("[-D <warn days cert expire>[,<crit days cert expire>]] [-S <use SSL>] [-E]\n"); 673 printf ("[-D <warn days cert expire>[,<crit days cert expire>]] [-S <use SSL>] [-E]\n");
668} 674}
669
diff --git a/plugins/check_users.c b/plugins/check_users.c
index c581fb2..ff2aedd 100644
--- a/plugins/check_users.c
+++ b/plugins/check_users.c
@@ -36,7 +36,12 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net";
36 36
37#include "common.h" 37#include "common.h"
38#include "utils.h" 38#include "utils.h"
39#include <utmpx.h> 39
40#if HAVE_UTMPX_H
41# include <utmpx.h>
42#else
43# include "popen.h"
44#endif
40 45
41#define possibly_set(a,b) ((a) == 0 ? (b) : 0) 46#define possibly_set(a,b) ((a) == 0 ? (b) : 0)
42 47
@@ -53,7 +58,11 @@ main (int argc, char **argv)
53 int users = -1; 58 int users = -1;
54 int result = STATE_UNKNOWN; 59 int result = STATE_UNKNOWN;
55 char *perf; 60 char *perf;
61#if HAVE_UTMPX_H
56 struct utmpx *putmpx; 62 struct utmpx *putmpx;
63#else
64 char input_buffer[MAX_INPUT_BUFFER];
65#endif
57 66
58 setlocale (LC_ALL, ""); 67 setlocale (LC_ALL, "");
59 bindtextdomain (PACKAGE, LOCALEDIR); 68 bindtextdomain (PACKAGE, LOCALEDIR);
@@ -69,6 +78,7 @@ main (int argc, char **argv)
69 78
70 users = 0; 79 users = 0;
71 80
81#if HAVE_UTMPX_H
72 /* get currently logged users from utmpx */ 82 /* get currently logged users from utmpx */
73 setutxent (); 83 setutxent ();
74 84
@@ -77,6 +87,39 @@ main (int argc, char **argv)
77 users++; 87 users++;
78 88
79 endutxent (); 89 endutxent ();
90#else
91 /* run the command */
92 child_process = spopen (WHO_COMMAND);
93 if (child_process == NULL) {
94 printf (_("Could not open pipe: %s\n"), WHO_COMMAND);
95 return STATE_UNKNOWN;
96 }
97
98 child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r");
99 if (child_stderr == NULL)
100 printf (_("Could not open stderr for %s\n"), WHO_COMMAND);
101
102 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) {
103 /* increment 'users' on all lines except total user count */
104 if (input_buffer[0] != '#') {
105 users++;
106 continue;
107 }
108
109 /* get total logged in users */
110 if (sscanf (input_buffer, _("# users=%d"), &users) == 1)
111 break;
112 }
113
114 /* check STDERR */
115 if (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr))
116 result = possibly_set (result, STATE_UNKNOWN);
117 (void) fclose (child_stderr);
118
119 /* close the pipe */
120 if (spclose (child_process))
121 result = possibly_set (result, STATE_UNKNOWN);
122#endif
80 123
81 /* check the user count against warning and critical thresholds */ 124 /* check the user count against warning and critical thresholds */
82 if (users > cusers) 125 if (users > cusers)
diff --git a/plugins/common.h b/plugins/common.h
index f024b2a..b49ad94 100644
--- a/plugins/common.h
+++ b/plugins/common.h
@@ -82,10 +82,12 @@
82 getting that data 82 getting that data
83 Will return -1 if cannot get data 83 Will return -1 if cannot get data
84*/ 84*/
85#ifdef HAVE_SYSCONF__SC_NPROCESSORS_CONF 85#if defined(HAVE_SYSCONF__SC_NPROCESSORS_ONLN)
86#define GET_NUMBER_OF_CPUS() sysconf(_SC_NPROCESSORS_CONF) 86# define GET_NUMBER_OF_CPUS() sysconf(_SC_NPROCESSORS_ONLN)
87#elif defined (HAVE_SYSCONF__SC_NPROCESSORS_CONF)
88# define GET_NUMBER_OF_CPUS() sysconf(_SC_NPROCESSORS_CONF)
87#else 89#else
88#define GET_NUMBER_OF_CPUS() -1 90# define GET_NUMBER_OF_CPUS() -1
89#endif 91#endif
90 92
91#ifdef TIME_WITH_SYS_TIME 93#ifdef TIME_WITH_SYS_TIME
@@ -115,9 +117,7 @@
115#include <getopt.h> 117#include <getopt.h>
116#include "dirname.h" 118#include "dirname.h"
117 119
118#ifdef HAVE_LOCALE_H
119#include <locale.h> 120#include <locale.h>
120#endif
121 121
122#ifdef HAVE_SYS_POLL_H 122#ifdef HAVE_SYS_POLL_H
123# include "sys/poll.h" 123# include "sys/poll.h"
diff --git a/plugins/netutils.h b/plugins/netutils.h
index 21017f1..5a495c9 100644
--- a/plugins/netutils.h
+++ b/plugins/netutils.h
@@ -100,6 +100,8 @@ extern int address_family;
100/* maybe this could be merged with the above np_net_connect, via some flags */ 100/* maybe this could be merged with the above np_net_connect, via some flags */
101int np_net_ssl_init(int sd); 101int np_net_ssl_init(int sd);
102int np_net_ssl_init_with_hostname(int sd, char *host_name); 102int np_net_ssl_init_with_hostname(int sd, char *host_name);
103int np_net_ssl_init_with_hostname_and_version(int sd, char *host_name, int version);
104int np_net_ssl_init_with_hostname_version_and_cert(int sd, char *host_name, int version, char *cert, char *privkey);
103void np_net_ssl_cleanup(); 105void np_net_ssl_cleanup();
104int np_net_ssl_write(const void *buf, int num); 106int np_net_ssl_write(const void *buf, int num);
105int np_net_ssl_read(void *buf, int num); 107int np_net_ssl_read(void *buf, int num);
diff --git a/plugins/runcmd.c b/plugins/runcmd.c
index 7574b12..8aba1e3 100644
--- a/plugins/runcmd.c
+++ b/plugins/runcmd.c
@@ -256,7 +256,7 @@ np_runcmd_close(int fd)
256 256
257 257
258void 258void
259popen_timeout_alarm_handler (int signo) 259runcmd_timeout_alarm_handler (int signo)
260{ 260{
261 size_t i; 261 size_t i;
262 262
diff --git a/plugins/runcmd.h b/plugins/runcmd.h
index 211dee2..5957562 100644
--- a/plugins/runcmd.h
+++ b/plugins/runcmd.h
@@ -39,7 +39,7 @@ typedef struct output output;
39 39
40/** prototypes **/ 40/** prototypes **/
41int np_runcmd(const char *, output *, output *, int); 41int np_runcmd(const char *, output *, output *, int);
42void popen_timeout_alarm_handler(int) 42void runcmd_timeout_alarm_handler(int)
43 __attribute__((__noreturn__)); 43 __attribute__((__noreturn__));
44 44
45/* only multi-threaded plugins need to bother with this */ 45/* only multi-threaded plugins need to bother with this */
diff --git a/plugins/sslutils.c b/plugins/sslutils.c
index a1ce560..818f799 100644
--- a/plugins/sslutils.c
+++ b/plugins/sslutils.c
@@ -45,6 +45,10 @@ int np_net_ssl_init_with_hostname(int sd, char *host_name) {
45} 45}
46 46
47int np_net_ssl_init_with_hostname_and_version(int sd, char *host_name, int version) { 47int np_net_ssl_init_with_hostname_and_version(int sd, char *host_name, int version) {
48 return np_net_ssl_init_with_hostname_version_and_cert(sd, host_name, version, NULL, NULL);
49}
50
51int np_net_ssl_init_with_hostname_version_and_cert(int sd, char *host_name, int version, char *cert, char *privkey) {
48 const SSL_METHOD *method = NULL; 52 const SSL_METHOD *method = NULL;
49 53
50 switch (version) { 54 switch (version) {
@@ -80,9 +84,18 @@ int np_net_ssl_init_with_hostname_and_version(int sd, char *host_name, int versi
80 printf("%s\n", _("CRITICAL - Cannot create SSL context.")); 84 printf("%s\n", _("CRITICAL - Cannot create SSL context."));
81 return STATE_CRITICAL; 85 return STATE_CRITICAL;
82 } 86 }
87 if (cert && privkey) {
88 SSL_CTX_use_certificate_file(c, cert, SSL_FILETYPE_PEM);
89 SSL_CTX_use_PrivateKey_file(c, privkey, SSL_FILETYPE_PEM);
90 if (!SSL_CTX_check_private_key(c)) {
91 printf ("%s\n", _("CRITICAL - Private key does not seem to match certificate!\n"));
92 return STATE_CRITICAL;
93 }
94 }
83#ifdef SSL_OP_NO_TICKET 95#ifdef SSL_OP_NO_TICKET
84 SSL_CTX_set_options(c, SSL_OP_NO_TICKET); 96 SSL_CTX_set_options(c, SSL_OP_NO_TICKET);
85#endif 97#endif
98 SSL_CTX_set_mode(c, SSL_MODE_AUTO_RETRY);
86 if ((s = SSL_new(c)) != NULL) { 99 if ((s = SSL_new(c)) != NULL) {
87#ifdef SSL_set_tlsext_host_name 100#ifdef SSL_set_tlsext_host_name
88 if (host_name != NULL) 101 if (host_name != NULL)
diff --git a/plugins/t/check_apt.t b/plugins/t/check_apt.t
index 7123097..9ba0ff8 100644
--- a/plugins/t/check_apt.t
+++ b/plugins/t/check_apt.t
@@ -18,8 +18,8 @@ sub make_result_regexp {
18 } else { 18 } else {
19 $status = "CRITICAL"; 19 $status = "CRITICAL";
20 } 20 }
21 return sprintf('/^APT %s: %d packages available for upgrade \(%d critical updates\).\s*$/', 21 return sprintf('/^APT %s: %d packages available for upgrade \(%d critical updates\)\. |available_upgrades=%d;;;0 critical_updates=%d;;;0$/',
22 $status, $warning, $critical); 22 $status, $warning, $critical, $warning, $critical);
23} 23}
24 24
25if (-x "./check_apt") { 25if (-x "./check_apt") {
diff --git a/plugins/t/check_http.t b/plugins/t/check_http.t
index 0a25c77..9948c53 100644
--- a/plugins/t/check_http.t
+++ b/plugins/t/check_http.t
@@ -8,22 +8,22 @@ use strict;
8use Test::More; 8use Test::More;
9use NPTest; 9use NPTest;
10 10
11plan tests => 28; 11plan tests => 30;
12 12
13my $successOutput = '/OK.*HTTP.*second/'; 13my $successOutput = '/OK.*HTTP.*second/';
14 14
15my $res; 15my $res;
16 16
17my $host_tcp_http = getTestParameter( "NP_HOST_TCP_HTTP", 17my $host_tcp_http = getTestParameter( "NP_HOST_TCP_HTTP",
18 "A host providing the HTTP Service (a web server)", 18 "A host providing the HTTP Service (a web server)",
19 "localhost" ); 19 "localhost" );
20 20
21my $host_nonresponsive = getTestParameter( "NP_HOST_NONRESPONSIVE", 21my $host_nonresponsive = getTestParameter( "NP_HOST_NONRESPONSIVE",
22 "The hostname of system not responsive to network requests", 22 "The hostname of system not responsive to network requests",
23 "10.0.0.1" ); 23 "10.0.0.1" );
24 24
25my $hostname_invalid = getTestParameter( "NP_HOSTNAME_INVALID", 25my $hostname_invalid = getTestParameter( "NP_HOSTNAME_INVALID",
26 "An invalid (not known to DNS) hostname", 26 "An invalid (not known to DNS) hostname",
27 "nosuchhost"); 27 "nosuchhost");
28 28
29my $internet_access = getTestParameter( "NP_INTERNET_ACCESS", 29my $internet_access = getTestParameter( "NP_INTERNET_ACCESS",
@@ -32,8 +32,8 @@ my $internet_access = getTestParameter( "NP_INTERNET_ACCESS",
32 32
33my $host_tcp_http2; 33my $host_tcp_http2;
34if ($internet_access eq "no") { 34if ($internet_access eq "no") {
35 $host_tcp_http2 = getTestParameter( "NP_HOST_TCP_HTTP2", 35 $host_tcp_http2 = getTestParameter( "NP_HOST_TCP_HTTP2",
36 "A host providing an index page containing the string 'nagios'", 36 "A host providing an index page containing the string 'nagios'",
37 "www.nagios.com" ); 37 "www.nagios.com" );
38} 38}
39 39
@@ -45,14 +45,9 @@ cmp_ok( $res->return_code, '==', 0, "Webserver $host_tcp_http responded" );
45like( $res->output, $successOutput, "Output OK" ); 45like( $res->output, $successOutput, "Output OK" );
46 46
47$res = NPTest->testCmd( 47$res = NPTest->testCmd(
48 "./check_http $host_tcp_http -wt 300 -ct 600 -v -v -v -k 'bob:there;fred:here'" 48 "./check_http $host_tcp_http -wt 300 -ct 600 -v -v -v -k 'bob:there' -k 'carl:frown'"
49 ); 49 );
50like( $res->output, '/bob:there\r\nfred:here\r\n/', "Got headers, delimited with ';'" ); 50like( $res->output, '/bob:there\r\ncarl:frown\r\n/', "Got headers with multiple -k options" );
51
52$res = NPTest->testCmd(
53 "./check_http $host_tcp_http -wt 300 -ct 600 -v -v -v -k 'bob:there;fred:here' -k 'carl:frown'"
54 );
55like( $res->output, '/bob:there\r\nfred:here\r\ncarl:frown\r\n/', "Got headers with multiple -k options" );
56 51
57$res = NPTest->testCmd( 52$res = NPTest->testCmd(
58 "./check_http $host_nonresponsive -wt 1 -ct 2" 53 "./check_http $host_nonresponsive -wt 1 -ct 2"
@@ -123,6 +118,10 @@ SKIP: {
123 $res = NPTest->testCmd( "./check_http www.verisign.com -C 1" ); 118 $res = NPTest->testCmd( "./check_http www.verisign.com -C 1" );
124 cmp_ok( $res->output, 'eq', $saved_cert_output, "Old syntax for cert checking still works"); 119 cmp_ok( $res->output, 'eq', $saved_cert_output, "Old syntax for cert checking still works");
125 120
121 $res = NPTest->testCmd( "./check_http --ssl www.verisign.com -E" );
122 like ( $res->output, '/time_connect=[\d\.]+/', 'Extended Performance Data Output OK' );
123 like ( $res->output, '/time_ssl=[\d\.]+/', 'Extended Performance Data SSL Output OK' );
124
126 $res = NPTest->testCmd( 125 $res = NPTest->testCmd(
127 "./check_http --ssl www.e-paycobalt.com" 126 "./check_http --ssl www.e-paycobalt.com"
128 ); 127 );
@@ -131,4 +130,7 @@ SKIP: {
131 130
132 $res = NPTest->testCmd( "./check_http -H www.mozilla.com -u /firefox -f follow" ); 131 $res = NPTest->testCmd( "./check_http -H www.mozilla.com -u /firefox -f follow" );
133 is( $res->return_code, 0, "Redirection based on location is okay"); 132 is( $res->return_code, 0, "Redirection based on location is okay");
133
134 $res = NPTest->testCmd( "./check_http -H www.mozilla.com --extended-perfdata" );
135 like ( $res->output, '/time_connect=[\d\.]+/', 'Extended Performance Data Output OK' );
134} 136}
diff --git a/plugins/t/check_procs.t b/plugins/t/check_procs.t
index 30f0248..a1a2883 100644
--- a/plugins/t/check_procs.t
+++ b/plugins/t/check_procs.t
@@ -20,7 +20,7 @@ my $result;
20 20
21$result = NPTest->testCmd( "./check_procs -w 100000 -c 100000" ); 21$result = NPTest->testCmd( "./check_procs -w 100000 -c 100000" );
22is( $result->return_code, 0, "Checking less than 10000 processes" ); 22is( $result->return_code, 0, "Checking less than 10000 processes" );
23like( $result->output, '/^PROCS OK: [0-9]+ process(es)?$/', "Output correct" ); 23like( $result->output, '/^PROCS OK: [0-9]+ process(es)? | procs=[0-9]+;100000;100000;0;$/', "Output correct" );
24 24
25$result = NPTest->testCmd( "./check_procs -w 100000 -c 100000 -s Z" ); 25$result = NPTest->testCmd( "./check_procs -w 100000 -c 100000 -s Z" );
26is( $result->return_code, 0, "Checking less than 100000 zombie processes" ); 26is( $result->return_code, 0, "Checking less than 100000 zombie processes" );
@@ -28,11 +28,11 @@ like( $result->output, '/^PROCS OK: [0-9]+ process(es)? with /', "Output correct
28 28
29$result = NPTest->testCmd( "./check_procs -w 0 -c 100000" ); 29$result = NPTest->testCmd( "./check_procs -w 0 -c 100000" );
30is( $result->return_code, 1, "Checking warning if processes > 0" ); 30is( $result->return_code, 1, "Checking warning if processes > 0" );
31like( $result->output, '/^PROCS WARNING: [0-9]+ process(es)?$/', "Output correct" ); 31like( $result->output, '/^PROCS WARNING: [0-9]+ process(es)? | procs=[0-9]+;0;100000;0;$/', "Output correct" );
32 32
33$result = NPTest->testCmd( "./check_procs -w 0 -c 0" ); 33$result = NPTest->testCmd( "./check_procs -w 0 -c 0" );
34is( $result->return_code, 2, "Checking critical if processes > 0" ); 34is( $result->return_code, 2, "Checking critical if processes > 0" );
35like( $result->output, '/^PROCS CRITICAL: [0-9]+ process(es)?$/', "Output correct" ); 35like( $result->output, '/^PROCS CRITICAL: [0-9]+ process(es)? | procs=[0-9]+;0;0;0;$/', "Output correct" );
36 36
37$result = NPTest->testCmd( "./check_procs -w 0 -c 0 -s S" ); 37$result = NPTest->testCmd( "./check_procs -w 0 -c 0 -s S" );
38is( $result->return_code, 2, "Checking critical if sleeping processes" ); 38is( $result->return_code, 2, "Checking critical if sleeping processes" );
diff --git a/plugins/t/check_snmp.t b/plugins/t/check_snmp.t
index 04bf500..6de5f29 100644
--- a/plugins/t/check_snmp.t
+++ b/plugins/t/check_snmp.t
@@ -8,145 +8,164 @@ use strict;
8use Test::More; 8use Test::More;
9use NPTest; 9use NPTest;
10 10
11my $tests = 8+42+2+2; 11BEGIN {
12plan tests => $tests; 12 plan skip_all => 'check_snmp is not compiled' unless -x "./check_snmp";
13 plan tests => 60;
14}
15
13my $res; 16my $res;
14 17
18my $host_snmp = getTestParameter( "host_snmp", "NP_HOST_SNMP", "localhost",
19 "A host providing an SNMP Service");
20
21my $snmp_community = getTestParameter( "snmp_community", "NP_SNMP_COMMUNITY", "public",
22 "The SNMP Community string for SNMP Testing (assumes snmp v1)" );
23
24my $host_nonresponsive = getTestParameter( "host_nonresponsive", "NP_HOST_NONRESPONSIVE", "10.0.0.1",
25 "The hostname of system not responsive to network requests" );
26
27my $hostname_invalid = getTestParameter( "hostname_invalid", "NP_HOSTNAME_INVALID", "nosuchhost",
28 "An invalid (not known to DNS) hostname" );
29
30$res = NPTest->testCmd( "./check_snmp -t 1" );
31is( $res->return_code, 3, "No host name" );
32is( $res->output, "No host specified" );
33
34$res = NPTest->testCmd( "./check_snmp -H fakehostname" );
35is( $res->return_code, 3, "No OIDs specified" );
36is( $res->output, "No OIDs specified" );
37
38$res = NPTest->testCmd( "./check_snmp -H fakehost -o oids -P 3 --seclevel=rubbish" );
39is( $res->return_code, 3, "Invalid seclevel" );
40like( $res->output, "/check_snmp: Invalid seclevel - rubbish/" );
41
42$res = NPTest->testCmd( "./check_snmp -H fakehost -o oids -P 3c" );
43is( $res->return_code, 3, "Invalid protocol" );
44like( $res->output, "/check_snmp: Invalid SNMP version - 3c/" );
45
46SKIP: {
47 skip "no snmp host defined", 38 if ( ! $host_snmp );
48
49 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o system.sysUpTime.0 -w 1: -c 1:");
50 cmp_ok( $res->return_code, '==', 0, "Exit OK when querying uptime" );
51 like($res->output, '/^SNMP OK - (\d+)/', "String contains SNMP OK");
52 $res->output =~ /^SNMP OK - (\d+)/;
53 my $value = $1;
54 cmp_ok( $value, ">", 0, "Got a time value" );
55 like($res->perf_output, "/sysUpTime.*$1/", "Got perfdata with value '$1' in it");
56
57
58 # some more threshold tests
59 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o system.sysUpTime.0 -c 1");
60 cmp_ok( $res->return_code, '==', 2, "Threshold test -c 1" );
61
62 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o system.sysUpTime.0 -c 1:");
63 cmp_ok( $res->return_code, '==', 0, "Threshold test -c 1:" );
64
65 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o system.sysUpTime.0 -c ~:1");
66 cmp_ok( $res->return_code, '==', 2, "Threshold test -c ~:1" );
67
68 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o system.sysUpTime.0 -c 1:10");
69 cmp_ok( $res->return_code, '==', 2, "Threshold test -c 1:10" );
70
71 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o system.sysUpTime.0 -c \@1:10");
72 cmp_ok( $res->return_code, '==', 0, "Threshold test -c \@1:10" );
73
74 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o system.sysUpTime.0 -c 10:1");
75 cmp_ok( $res->return_code, '==', 0, "Threshold test -c 10:1" );
76
77
78 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o .1.3.6.1.2.1.1.3.0 -w 1: -c 1:");
79 cmp_ok( $res->return_code, '==', 0, "Test with numeric OID (no mibs loaded)" );
80 like($res->output, '/^SNMP OK - \d+/', "String contains SNMP OK");
81
82 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o system.sysDescr.0");
83 cmp_ok( $res->return_code, '==', 0, "Exit OK when querying sysDescr" );
84 unlike($res->perf_output, '/sysDescr/', "Perfdata doesn't contain string values");
85
86 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o system.sysDescr.0,system.sysDescr.0");
87 cmp_ok( $res->return_code, '==', 0, "Exit OK when querying two string OIDs, comma-separated" );
88 like($res->output, '/^SNMP OK - /', "String contains SNMP OK");
89
90 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o system.sysDescr.0 -o system.sysDescr.0");
91 cmp_ok( $res->return_code, '==', 0, "Exit OK when querying two string OIDs, repeated option" );
92 like($res->output, '/^SNMP OK - /', "String contains SNMP OK");
93
94 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w 1:1 -c 1:1");
95 cmp_ok( $res->return_code, '==', 0, "Exit OK when querying hrSWRunIndex.1" );
96 like($res->output, '/^SNMP OK - 1\s.*$/', "String fits SNMP OK and output format");
97
98 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w 0 -c 1:");
99 cmp_ok( $res->return_code, '==', 1, "Exit WARNING when querying hrSWRunIndex.1 and warn-th doesn't apply " );
100 like($res->output, '/^SNMP WARNING - \*1\*\s.*$/', "String matches SNMP WARNING and output format");
101
102 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w :0 -c 0");
103 cmp_ok( $res->return_code, '==', 2, "Exit CRITICAL when querying hrSWRunIndex.1 and crit-th doesn't apply" );
104 like($res->output, '/^SNMP CRITICAL - \*1\*\s.*$/', "String matches SNMP CRITICAL and output format");
105
106 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o ifIndex.2,ifIndex.1 -w 1:2 -c 1:2");
107 cmp_ok( $res->return_code, '==', 0, "Checking two OIDs at once" );
108 like($res->output, "/^SNMP OK - 2 1/", "Got two values back" );
109 like( $res->perf_output, "/ifIndex.2=2/", "Got 1st perf data" );
110 like( $res->perf_output, "/ifIndex.1=1/", "Got 2nd perf data" );
111
112 $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");
113 cmp_ok( $res->return_code, '==', 2, "Checking critical threshold is passed if any one value crosses" );
114 like($res->output, "/^SNMP CRITICAL - 2 *1*/", "Got two values back" );
115 like( $res->perf_output, "/ifIndex.2=2/", "Got 1st perf data" );
116 like( $res->perf_output, "/ifIndex.1=1/", "Got 2nd perf data" );
117
118 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o host.hrStorage.hrMemorySize.0,host.hrSystem.hrSystemProcesses.0 -w 1:,1: -c 1:,1:");
119 cmp_ok( $res->return_code, '==', 0, "Exit OK when querying hrMemorySize and hrSystemProcesses");
120 like($res->output, '/^SNMP OK - \d+ \d+/', "String contains hrMemorySize and hrSystemProcesses");
121
122 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w \@:0 -c \@0");
123 cmp_ok( $res->return_code, '==', 0, "Exit OK with inside-range thresholds");
124 like($res->output, '/^SNMP OK - 1\s.*$/', "String matches SNMP OK and output format");
125
126 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o enterprises.ucdavis.laTable.laEntry.laLoad.3");
127 $res->output =~ m/^SNMP OK - (\d+\.\d{2})\s.*$/;
128 my $lower = $1 - 0.05;
129 my $higher = $1 + 0.05;
130 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o enterprises.ucdavis.laTable.laEntry.laLoad.3 -w $lower -c $higher");
131 cmp_ok( $res->return_code, '==', 1, "Exit WARNING with fractionnal arguments");
132
133 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o system.sysUpTime.0,host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w ,:0 -c ,:2");
134 cmp_ok( $res->return_code, '==', 1, "Exit WARNING on 2nd threshold");
135 like($res->output, '/^SNMP WARNING - Timeticks:\s\(\d+\)\s+(?:\d+ days?,\s+)?\d+:\d+:\d+\.\d+\s+\*1\*\s.*$/', "First OID returned as string, 2nd checked for thresholds");
136
137 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w '' -c ''");
138 cmp_ok( $res->return_code, '==', 0, "Empty thresholds doesn't crash");
139
140 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o host.hrStorage.hrMemorySize.0,host.hrSystem.hrSystemProcesses.0 -w ,,1 -c ,,2");
141 cmp_ok( $res->return_code, '==', 0, "Skipping first two thresholds on 2 OID check");
142 like($res->output, '/^SNMP OK - \d+ \w+ \d+\s.*$/', "Skipping first two thresholds, result printed rather than parsed");
143
144 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o host.hrStorage.hrMemorySize.0,host.hrSystem.hrSystemProcesses.0 -w ,, -c ,,");
145 cmp_ok( $res->return_code, '==', 0, "Skipping all thresholds");
146 like($res->output, '/^SNMP OK - \d+ \w+ \d+\s.*$/', "Skipping all thresholds, result printed rather than parsed");
147
148 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o system.sysUpTime.0 -c 1000000000000: -u '1/100 sec'");
149 cmp_ok( $res->return_code, '==', 2, "Timetick used as a threshold");
150 like($res->output, '/^SNMP CRITICAL - \*\d+\* 1\/100 sec.*$/', "Timetick used as a threshold, parsed as numeric");
151
152 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o system.sysUpTime.0");
153 cmp_ok( $res->return_code, '==', 0, "Timetick used as a string");
154 like($res->output, '/^SNMP OK - Timeticks:\s\(\d+\)\s+(?:\d+ days?,\s+)?\d+:\d+:\d+\.\d+\s.*$/', "Timetick used as a string, result printed rather than parsed");
155}
156
157# These checks need a complete command line. An invalid community is used so
158# the tests can run on hosts w/o snmp host/community in NPTest.cache. Execution will fail anyway
15SKIP: { 159SKIP: {
16 skip "check_snmp is not compiled", $tests if ( ! -x "./check_snmp" ); 160 skip "no non responsive host defined", 2 if ( ! $host_nonresponsive );
17 161 $res = NPTest->testCmd( "./check_snmp -H $host_nonresponsive -C np_foobar -o system.sysUpTime.0 -w 1: -c 1:");
18 my $host_snmp = getTestParameter( "host_snmp", "NP_HOST_SNMP", "localhost", 162 cmp_ok( $res->return_code, '==', 3, "Exit UNKNOWN with non responsive host" );
19 "A host providing an SNMP Service"); 163 like($res->output, '/External command error: Timeout: No Response from /', "String matches timeout problem");
20 164}
21 my $snmp_community = getTestParameter( "snmp_community", "NP_SNMP_COMMUNITY", "public",
22 "The SNMP Community string for SNMP Testing (assumes snmp v1)" );
23
24 my $host_nonresponsive = getTestParameter( "host_nonresponsive", "NP_HOST_NONRESPONSIVE", "10.0.0.1",
25 "The hostname of system not responsive to network requests" );
26
27 my $hostname_invalid = getTestParameter( "hostname_invalid", "NP_HOSTNAME_INVALID", "nosuchhost",
28 "An invalid (not known to DNS) hostname" );
29
30 $res = NPTest->testCmd( "./check_snmp -t 1" );
31 is( $res->return_code, 3, "No host name" );
32 is( $res->output, "No host specified" );
33
34 $res = NPTest->testCmd( "./check_snmp -H fakehostname" );
35 is( $res->return_code, 3, "No OIDs specified" );
36 is( $res->output, "No OIDs specified" );
37
38 $res = NPTest->testCmd( "./check_snmp -H fakehost -o oids -P 3 --seclevel=rubbish" );
39 is( $res->return_code, 3, "Invalid seclevel" );
40 like( $res->output, "/check_snmp: Invalid seclevel - rubbish/" );
41
42 $res = NPTest->testCmd( "./check_snmp -H fakehost -o oids -P 3c" );
43 is( $res->return_code, 3, "Invalid protocol" );
44 like( $res->output, "/check_snmp: Invalid SNMP version - 3c/" );
45
46 SKIP: {
47 skip "no snmp host defined", 38 if ( ! $host_snmp );
48
49 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o system.sysUpTime.0 -w 1: -c 1:");
50 cmp_ok( $res->return_code, '==', 0, "Exit OK when querying uptime" );
51 like($res->output, '/^SNMP OK - (\d+)/', "String contains SNMP OK");
52 $res->output =~ /^SNMP OK - (\d+)/;
53 my $value = $1;
54 cmp_ok( $value, ">", 0, "Got a time value" );
55 like($res->perf_output, "/sysUpTime.*$1/", "Got perfdata with value '$1' in it");
56
57 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o .1.3.6.1.2.1.1.3.0 -w 1: -c 1:");
58 cmp_ok( $res->return_code, '==', 0, "Test with numeric OID (no mibs loaded)" );
59 like($res->output, '/^SNMP OK - \d+/', "String contains SNMP OK");
60
61 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o system.sysDescr.0");
62 cmp_ok( $res->return_code, '==', 0, "Exit OK when querying sysDescr" );
63 unlike($res->perf_output, '/sysDescr/', "Perfdata doesn't contain string values");
64
65 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o system.sysDescr.0,system.sysDescr.0");
66 cmp_ok( $res->return_code, '==', 0, "Exit OK when querying two string OIDs, comma-separated" );
67 like($res->output, '/^SNMP OK - /', "String contains SNMP OK");
68
69 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o system.sysDescr.0 -o system.sysDescr.0");
70 cmp_ok( $res->return_code, '==', 0, "Exit OK when querying two string OIDs, repeated option" );
71 like($res->output, '/^SNMP OK - /', "String contains SNMP OK");
72
73 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w 1:1 -c 1:1");
74 cmp_ok( $res->return_code, '==', 0, "Exit OK when querying hrSWRunIndex.1" );
75 like($res->output, '/^SNMP OK - 1\s.*$/', "String fits SNMP OK and output format");
76
77 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w 0 -c 1:");
78 cmp_ok( $res->return_code, '==', 1, "Exit WARNING when querying hrSWRunIndex.1 and warn-th doesn't apply " );
79 like($res->output, '/^SNMP WARNING - \*1\*\s.*$/', "String matches SNMP WARNING and output format");
80
81 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w :0 -c 0");
82 cmp_ok( $res->return_code, '==', 2, "Exit CRITICAL when querying hrSWRunIndex.1 and crit-th doesn't apply" );
83 like($res->output, '/^SNMP CRITICAL - \*1\*\s.*$/', "String matches SNMP CRITICAL and output format");
84
85 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o ifIndex.2,ifIndex.1 -w 1:2 -c 1:2");
86 cmp_ok( $res->return_code, '==', 0, "Checking two OIDs at once" );
87 like($res->output, "/^SNMP OK - 2 1/", "Got two values back" );
88 like( $res->perf_output, "/ifIndex.2=2/", "Got 1st perf data" );
89 like( $res->perf_output, "/ifIndex.1=1/", "Got 2nd perf data" );
90
91 $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");
92 cmp_ok( $res->return_code, '==', 2, "Checking critical threshold is passed if any one value crosses" );
93 like($res->output, "/^SNMP CRITICAL - 2 *1*/", "Got two values back" );
94 like( $res->perf_output, "/ifIndex.2=2/", "Got 1st perf data" );
95 like( $res->perf_output, "/ifIndex.1=1/", "Got 2nd perf data" );
96
97 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o host.hrStorage.hrMemorySize.0,host.hrSystem.hrSystemProcesses.0 -w 1:,1: -c 1:,1:");
98 cmp_ok( $res->return_code, '==', 0, "Exit OK when querying hrMemorySize and hrSystemProcesses");
99 like($res->output, '/^SNMP OK - \d+ \d+/', "String contains hrMemorySize and hrSystemProcesses");
100
101 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w \@:0 -c \@0");
102 cmp_ok( $res->return_code, '==', 0, "Exit OK with inside-range thresholds");
103 like($res->output, '/^SNMP OK - 1\s.*$/', "String matches SNMP OK and output format");
104
105 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o enterprises.ucdavis.laTable.laEntry.laLoad.3");
106 $res->output =~ m/^SNMP OK - (\d+\.\d{2})\s.*$/;
107 my $lower = $1 - 0.05;
108 my $higher = $1 + 0.05;
109 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o enterprises.ucdavis.laTable.laEntry.laLoad.3 -w $lower -c $higher");
110 cmp_ok( $res->return_code, '==', 1, "Exit WARNING with fractionnal arguments");
111
112 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o system.sysUpTime.0,host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w ,:0 -c ,:2");
113 cmp_ok( $res->return_code, '==', 1, "Exit WARNING on 2nd threshold");
114 like($res->output, '/^SNMP WARNING - Timeticks:\s\(\d+\)\s+(?:\d+ days?,\s+)?\d+:\d+:\d+\.\d+\s+\*1\*\s.*$/', "First OID returned as string, 2nd checked for thresholds");
115
116 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w '' -c ''");
117 cmp_ok( $res->return_code, '==', 0, "Empty thresholds doesn't crash");
118
119 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o host.hrStorage.hrMemorySize.0,host.hrSystem.hrSystemProcesses.0 -w ,,1 -c ,,2");
120 cmp_ok( $res->return_code, '==', 0, "Skipping first two thresholds on 2 OID check");
121 like($res->output, '/^SNMP OK - \d+ \w+ \d+\s.*$/', "Skipping first two thresholds, result printed rather than parsed");
122
123 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o host.hrStorage.hrMemorySize.0,host.hrSystem.hrSystemProcesses.0 -w ,, -c ,,");
124 cmp_ok( $res->return_code, '==', 0, "Skipping all thresholds");
125 like($res->output, '/^SNMP OK - \d+ \w+ \d+\s.*$/', "Skipping all thresholds, result printed rather than parsed");
126
127 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o system.sysUpTime.0 -c 1000000000000: -u '1/100 sec'");
128 cmp_ok( $res->return_code, '==', 2, "Timetick used as a threshold");
129 like($res->output, '/^SNMP CRITICAL - \*\d+\* 1\/100 sec.*$/', "Timetick used as a threshold, parsed as numeric");
130
131 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o system.sysUpTime.0");
132 cmp_ok( $res->return_code, '==', 0, "Timetick used as a string");
133 like($res->output, '/^SNMP OK - Timeticks:\s\(\d+\)\s+(?:\d+ days?,\s+)?\d+:\d+:\d+\.\d+\s.*$/', "Timetick used as a string, result printed rather than parsed");
134 }
135
136 # These checks need a complete command line. An invalid community is used so
137 # the tests can run on hosts w/o snmp host/community in NPTest.cache. Execution will fail anyway
138 SKIP: {
139 skip "no non responsive host defined", 2 if ( ! $host_nonresponsive );
140 $res = NPTest->testCmd( "./check_snmp -H $host_nonresponsive -C np_foobar -o system.sysUpTime.0 -w 1: -c 1:");
141 cmp_ok( $res->return_code, '==', 3, "Exit UNKNOWN with non responsive host" );
142 like($res->output, '/External command error: Timeout: No Response from /', "String matches timeout problem");
143 }
144
145 SKIP: {
146 skip "no non invalid host defined", 2 if ( ! $hostname_invalid );
147 $res = NPTest->testCmd( "./check_snmp -H $hostname_invalid -C np_foobar -o system.sysUpTime.0 -w 1: -c 1:");
148 cmp_ok( $res->return_code, '==', 3, "Exit UNKNOWN with non responsive host" );
149 like($res->output, '/External command error: .*(nosuchhost|Name or service not known|Unknown host)/', "String matches invalid host");
150 }
151 165
166SKIP: {
167 skip "no non invalid host defined", 2 if ( ! $hostname_invalid );
168 $res = NPTest->testCmd( "./check_snmp -H $hostname_invalid -C np_foobar -o system.sysUpTime.0 -w 1: -c 1:");
169 cmp_ok( $res->return_code, '==', 3, "Exit UNKNOWN with non responsive host" );
170 like($res->output, '/External command error: .*(nosuchhost|Name or service not known|Unknown host)/', "String matches invalid host");
152} 171}
diff --git a/plugins/t/check_tcp.t b/plugins/t/check_tcp.t
index 75c1e5f..c100cad 100644
--- a/plugins/t/check_tcp.t
+++ b/plugins/t/check_tcp.t
@@ -9,7 +9,7 @@ use Test;
9use NPTest; 9use NPTest;
10 10
11use vars qw($tests); 11use vars qw($tests);
12BEGIN {$tests = 7; plan tests => $tests} 12BEGIN {$tests = 14; plan tests => $tests}
13 13
14my $host_tcp_http = getTestParameter( "host_tcp_http", "NP_HOST_TCP_HTTP", "localhost", 14my $host_tcp_http = getTestParameter( "host_tcp_http", "NP_HOST_TCP_HTTP", "localhost",
15 "A host providing the HTTP Service (a web server)" ); 15 "A host providing the HTTP Service (a web server)" );
@@ -27,13 +27,15 @@ my $failedExpect = '/^TCP WARNING\s-\sUnexpected response from host/socket on po
27my $t; 27my $t;
28 28
29$t += checkCmd( "./check_tcp $host_tcp_http -p 80 -wt 300 -ct 600", 0, $successOutput ); 29$t += checkCmd( "./check_tcp $host_tcp_http -p 80 -wt 300 -ct 600", 0, $successOutput );
30$t += checkCmd( "./check_tcp $host_tcp_http -p 80 -wt 300 -ct 600 -6 ", 0, $successOutput );
30$t += checkCmd( "./check_tcp $host_tcp_http -p 81 -wt 0 -ct 0 -to 1", 2 ); # use invalid port for this test 31$t += checkCmd( "./check_tcp $host_tcp_http -p 81 -wt 0 -ct 0 -to 1", 2 ); # use invalid port for this test
31$t += checkCmd( "./check_tcp $host_nonresponsive -p 80 -wt 0 -ct 0 -to 1", 2 ); 32$t += checkCmd( "./check_tcp $host_nonresponsive -p 80 -wt 0 -ct 0 -to 1", 2 );
32$t += checkCmd( "./check_tcp $hostname_invalid -p 80 -wt 0 -ct 0 -to 1", 2 ); 33$t += checkCmd( "./check_tcp $hostname_invalid -p 80 -wt 0 -ct 0 -to 1", 2 );
33$t += checkCmd( "./check_tcp -S -D 1 -H www.verisign.com -p 443", 0 ); 34$t += checkCmd( "./check_tcp -S -D 1 -H www.verisign.com -p 443", 0 );
34$t += checkCmd( "./check_tcp -S -D 9000,1 -H www.verisign.com -p 443", 0 ); 35$t += checkCmd( "./check_tcp -S -D 9000,1 -H www.verisign.com -p 443", 1 );
35$t += checkCmd( "./check_tcp -S -D 9000 -H www.verisign.com -p 443", 1 ); 36$t += checkCmd( "./check_tcp -S -D 9000 -H www.verisign.com -p 443", 1 );
36$t += checkCmd( "./check_tcp -S -D 9000,8999 -H www.verisign.com -p 443", 2 ); 37$t += checkCmd( "./check_tcp -S -D 9000,8999 -H www.verisign.com -p 443", 2 );
38$t += checkCmd( "./check_tcp -6 -p 80 www.heise.de", 0 );
37 39
38# Need the \r\n to make it more standards compliant with web servers. Need the various quotes 40# Need the \r\n to make it more standards compliant with web servers. Need the various quotes
39# so that perl doesn't interpret the \r\n and is passed onto command line correctly 41# so that perl doesn't interpret the \r\n and is passed onto command line correctly
diff --git a/plugins/tests/check_http.t b/plugins/tests/check_http.t
index 9f97abd..c3085e1 100755
--- a/plugins/tests/check_http.t
+++ b/plugins/tests/check_http.t
@@ -17,7 +17,7 @@ use Test::More;
17use NPTest; 17use NPTest;
18use FindBin qw($Bin); 18use FindBin qw($Bin);
19 19
20my $common_tests = 66; 20my $common_tests = 70;
21my $ssl_only_tests = 8; 21my $ssl_only_tests = 8;
22# Check that all dependent modules are available 22# Check that all dependent modules are available
23eval { 23eval {
@@ -151,6 +151,10 @@ sub run_server {
151 unshift @persist, $c; 151 unshift @persist, $c;
152 delete($persist[1000]); 152 delete($persist[1000]);
153 next MAINLOOP; 153 next MAINLOOP;
154 } elsif ($r->url->path eq "/header_check") {
155 $c->send_basic_header;
156 $c->send_header('foo');
157 $c->send_crlf;
154 } else { 158 } else {
155 $c->send_error(HTTP::Status->RC_FORBIDDEN); 159 $c->send_error(HTTP::Status->RC_FORBIDDEN);
156 } 160 }
@@ -223,6 +227,13 @@ sub run_common_tests {
223 is( $result->return_code, 2, "Missing string check"); 227 is( $result->return_code, 2, "Missing string check");
224 like( $result->output, qr%HTTP CRITICAL: HTTP/1\.1 200 OK - string 'NonRootWithOver30charsAndM...' not found on 'https?://127\.0\.0\.1:\d+/file/root'%, "Shows search string and location"); 228 like( $result->output, qr%HTTP CRITICAL: HTTP/1\.1 200 OK - string 'NonRootWithOver30charsAndM...' not found on 'https?://127\.0\.0\.1:\d+/file/root'%, "Shows search string and location");
225 229
230 $result = NPTest->testCmd( "$command -u /header_check -d foo" );
231 is( $result->return_code, 0, "header_check search for string");
232 like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - 96 bytes in [\d\.]+ second/', "Output correct" );
233
234 $result = NPTest->testCmd( "$command -u /header_check -d bar" );
235 is( $result->return_code, 2, "Missing header string check");
236 like( $result->output, qr%^HTTP CRITICAL: HTTP/1\.1 200 OK - header 'bar' not found on 'https?://127\.0\.0\.1:\d+/header_check'%, "Shows search string and location");
226 237
227 my $cmd; 238 my $cmd;
228 $cmd = "$command -u /slow"; 239 $cmd = "$command -u /slow";