mirror of
https://github.com/monitoring-plugins/monitoring-plugins.git
synced 2026-05-28 04:35:40 -04:00
Merge branch 'master' into refactor/check_tcp
This commit is contained in:
commit
54a099ed6d
75 changed files with 6240 additions and 4935 deletions
4
.github/NPTest.cache
vendored
4
.github/NPTest.cache
vendored
|
|
@ -38,8 +38,8 @@
|
|||
'NP_MYSQL_LOGIN_DETAILS' => '-u root -d test',
|
||||
'NP_MYSQL_SERVER' => 'localhost',
|
||||
'NP_MYSQL_SOCKET' => '/var/run/mysqld/mysqld.sock',
|
||||
'NP_MYSQL_WITH_SLAVE' => '',
|
||||
'NP_MYSQL_WITH_SLAVE_LOGIN' => '',
|
||||
'NP_MYSQL_WITH_REPLICA' => '',
|
||||
'NP_MYSQL_WITH_REPLICA_LOGIN' => '',
|
||||
'NP_NO_NTP_SERVICE' => 'localhost',
|
||||
'NP_PORT_TCP_PROXY' => '3128',
|
||||
'NP_SMB_SHARE' => '',
|
||||
|
|
|
|||
14
.github/monitoring-plugins.spec
vendored
14
.github/monitoring-plugins.spec
vendored
|
|
@ -193,7 +193,6 @@ Requires: %{name}-ntp_peer
|
|||
Requires: %{name}-ntp_time
|
||||
Requires: %{name}-nwstat
|
||||
Requires: %{name}-oracle
|
||||
Requires: %{name}-overcr
|
||||
Requires: %{name}-pgsql
|
||||
Requires: %{name}-ping
|
||||
Requires: %{name}-procs
|
||||
|
|
@ -729,19 +728,6 @@ Provides check_oracle of the Monitoring Plugins.
|
|||
|
||||
|
||||
|
||||
# check_overcr
|
||||
%package overcr
|
||||
Summary: Monitoring Plugins - check_overcr
|
||||
Requires: %{name} = %{version}-%{release}
|
||||
|
||||
%description overcr
|
||||
Provides check_overcr of the Monitoring Plugins.
|
||||
|
||||
%files overcr
|
||||
%{plugindir}/check_overcr
|
||||
|
||||
|
||||
|
||||
# check_pgsql
|
||||
%package pgsql
|
||||
Summary: Monitoring Plugins - check_pgsql
|
||||
|
|
|
|||
1
.github/prepare_debian.sh
vendored
1
.github/prepare_debian.sh
vendored
|
|
@ -59,6 +59,7 @@ apt-get -y install perl \
|
|||
mariadb-server \
|
||||
mariadb-client \
|
||||
libmariadb-dev \
|
||||
libmariadb-dev-compat \
|
||||
cron \
|
||||
iputils-ping \
|
||||
iproute2 \
|
||||
|
|
|
|||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -178,7 +178,6 @@ NP-VERSION-FILE
|
|||
/plugins/check_ntp_peer
|
||||
/plugins/check_ntp_time
|
||||
/plugins/check_nwstat
|
||||
/plugins/check_overcr
|
||||
/plugins/check_pgsql
|
||||
/plugins/check_ping
|
||||
/plugins/check_pop
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ use warnings;
|
|||
use Cwd;
|
||||
use File::Basename;
|
||||
|
||||
use JSON;
|
||||
|
||||
use IO::File;
|
||||
use Data::Dumper;
|
||||
|
||||
|
|
@ -617,6 +619,8 @@ sub testCmd {
|
|||
chomp $output;
|
||||
$object->output($output);
|
||||
|
||||
eval { $object->{'mp_test_result'} = decode_json($output) };
|
||||
|
||||
alarm(0);
|
||||
|
||||
my ($pkg, $file, $line) = caller(0);
|
||||
|
|
|
|||
12
lib/output.c
12
lib/output.c
|
|
@ -11,6 +11,9 @@
|
|||
#include "perfdata.h"
|
||||
#include "states.h"
|
||||
|
||||
// == Global variables
|
||||
static mp_output_format output_format = MP_FORMAT_DEFAULT;
|
||||
|
||||
// == Prototypes ==
|
||||
static char *fmt_subcheck_output(mp_output_format output_format, mp_subcheck check, unsigned int indentation);
|
||||
static inline cJSON *json_serialize_subcheck(mp_subcheck subcheck);
|
||||
|
|
@ -55,7 +58,6 @@ static inline char *fmt_subcheck_perfdata(mp_subcheck check) {
|
|||
*/
|
||||
mp_check mp_check_init(void) {
|
||||
mp_check check = {0};
|
||||
check.format = MP_FORMAT_DEFAULT;
|
||||
return check;
|
||||
}
|
||||
|
||||
|
|
@ -234,7 +236,7 @@ mp_state_enum mp_compute_check_state(const mp_check check) {
|
|||
char *mp_fmt_output(mp_check check) {
|
||||
char *result = NULL;
|
||||
|
||||
switch (check.format) {
|
||||
switch (output_format) {
|
||||
case MP_FORMAT_MULTI_LINE: {
|
||||
if (check.summary == NULL) {
|
||||
check.summary = get_subcheck_summary(check);
|
||||
|
|
@ -482,7 +484,7 @@ void mp_print_output(mp_check check) { puts(mp_fmt_output(check)); }
|
|||
*/
|
||||
void mp_exit(mp_check check) {
|
||||
mp_print_output(check);
|
||||
if (check.format == MP_FORMAT_TEST_JSON) {
|
||||
if (output_format == MP_FORMAT_TEST_JSON) {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
|
@ -533,3 +535,7 @@ parsed_output_format mp_parse_output_format(char *format_string) {
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
void mp_set_format(mp_output_format format) { output_format = format; }
|
||||
|
||||
mp_output_format mp_get_format(void) { return output_format; }
|
||||
|
|
|
|||
|
|
@ -35,6 +35,12 @@ typedef enum output_format {
|
|||
|
||||
#define MP_FORMAT_DEFAULT MP_FORMAT_MULTI_LINE
|
||||
|
||||
/*
|
||||
* Format related functions
|
||||
*/
|
||||
void mp_set_format(mp_output_format format);
|
||||
mp_output_format mp_get_format(void);
|
||||
|
||||
/*
|
||||
* The main state object of a plugin. Exists only ONCE per plugin.
|
||||
* This is the "root" of a tree of singular checks.
|
||||
|
|
@ -42,7 +48,6 @@ typedef enum output_format {
|
|||
* in the first layer of subchecks
|
||||
*/
|
||||
typedef struct {
|
||||
mp_output_format format; // The output format
|
||||
char *summary; // Overall summary, if not set a summary will be automatically generated
|
||||
mp_subcheck_list *subchecks;
|
||||
} mp_check;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ MATHLIBS = @MATHLIBS@
|
|||
#AM_CFLAGS = -Wall
|
||||
|
||||
libexec_PROGRAMS = check_apt check_cluster check_disk check_dummy check_http check_load \
|
||||
check_mrtg check_mrtgtraf check_ntp check_ntp_peer check_nwstat check_overcr check_ping \
|
||||
check_mrtg check_mrtgtraf check_ntp check_ntp_peer check_nwstat check_ping \
|
||||
check_real check_smtp check_ssh check_tcp check_time check_ntp_time \
|
||||
check_ups check_users negate \
|
||||
urlize @EXTRAS@
|
||||
|
|
@ -46,7 +46,37 @@ SUBDIRS = picohttpparser
|
|||
|
||||
np_test_scripts = tests/test_check_swap.t
|
||||
|
||||
EXTRA_DIST = t tests $(np_test_scripts) check_swap.d
|
||||
EXTRA_DIST = t \
|
||||
tests \
|
||||
$(np_test_scripts) \
|
||||
negate.d \
|
||||
check_swap.d \
|
||||
check_ldap.d \
|
||||
check_hpjd.d \
|
||||
check_game.d \
|
||||
check_radius.d \
|
||||
check_time.d \
|
||||
check_nagios.d \
|
||||
check_dbi.d \
|
||||
check_real.d \
|
||||
check_ssh.d \
|
||||
check_nt.d \
|
||||
check_dns.d \
|
||||
check_mrtgtraf.d \
|
||||
check_mysql_query.d \
|
||||
check_mrtg.d \
|
||||
check_ntp_peer.d \
|
||||
check_apt.d \
|
||||
check_pgsql.d \
|
||||
check_ping.d \
|
||||
check_by_ssh.d \
|
||||
check_smtp.d \
|
||||
check_mysql.d \
|
||||
check_ntp_time.d \
|
||||
check_dig.d \
|
||||
check_cluster.d \
|
||||
check_ups.d \
|
||||
check_fping.d
|
||||
|
||||
PLUGINHDRS = common.h
|
||||
|
||||
|
|
@ -109,7 +139,6 @@ check_nt_LDADD = $(NETLIBS)
|
|||
check_ntp_LDADD = $(NETLIBS) $(MATHLIBS)
|
||||
check_ntp_peer_LDADD = $(NETLIBS) $(MATHLIBS)
|
||||
check_nwstat_LDADD = $(NETLIBS)
|
||||
check_overcr_LDADD = $(NETLIBS)
|
||||
check_pgsql_LDADD = $(NETLIBS) $(PGLIBS)
|
||||
check_ping_LDADD = $(NETLIBS)
|
||||
check_procs_LDADD = $(BASEOBJS)
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "states.h"
|
||||
const char *progname = "check_apt";
|
||||
const char *copyright = "2006-2024";
|
||||
const char *email = "devel@monitoring-plugins.org";
|
||||
|
|
@ -37,13 +38,7 @@ const char *email = "devel@monitoring-plugins.org";
|
|||
#include "runcmd.h"
|
||||
#include "utils.h"
|
||||
#include "regex.h"
|
||||
|
||||
/* some constants */
|
||||
typedef enum {
|
||||
UPGRADE,
|
||||
DIST_UPGRADE,
|
||||
NO_UPGRADE
|
||||
} upgrade_type;
|
||||
#include "check_apt.d/config.h"
|
||||
|
||||
/* Character for hidden input file option (for testing). */
|
||||
#define INPUT_FILE_OPT CHAR_MAX + 1
|
||||
|
|
@ -61,14 +56,18 @@ typedef enum {
|
|||
#define SECURITY_RE "^[^\\(]*\\(.* (Debian-Security:|Ubuntu:[^/]*/[^-]*-security)"
|
||||
|
||||
/* some standard functions */
|
||||
static int process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
typedef struct {
|
||||
int errorcode;
|
||||
check_apt_config config;
|
||||
} check_apt_config_wrapper;
|
||||
static check_apt_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
static void print_help(void);
|
||||
void print_usage(void);
|
||||
|
||||
/* construct the appropriate apt-get cmdline */
|
||||
static char *construct_cmdline(upgrade_type u, const char *opts);
|
||||
static char *construct_cmdline(upgrade_type /*u*/, const char * /*opts*/);
|
||||
/* run an apt-get update */
|
||||
static int run_update(void);
|
||||
static int run_update(char * /*update_opts*/);
|
||||
|
||||
typedef struct {
|
||||
int errorcode;
|
||||
|
|
@ -79,42 +78,35 @@ typedef struct {
|
|||
} run_upgrade_result;
|
||||
|
||||
/* run an apt-get upgrade */
|
||||
static run_upgrade_result run_upgrade(void);
|
||||
run_upgrade_result run_upgrade(upgrade_type upgrade, const char *do_include, const char *do_exclude, const char *do_critical,
|
||||
const char *upgrade_opts, const char *input_filename);
|
||||
|
||||
/* add another clause to a regexp */
|
||||
static char *add_to_regexp(char *expr, const char *next);
|
||||
static char *add_to_regexp(char * /*expr*/, const char * /*next*/);
|
||||
/* extract package name from Inst line */
|
||||
static char *pkg_name(char *line);
|
||||
static char *pkg_name(char * /*line*/);
|
||||
/* string comparison function for qsort */
|
||||
static int cmpstringp(const void *p1, const void *p2);
|
||||
static int cmpstringp(const void * /*p1*/, const void * /*p2*/);
|
||||
|
||||
/* configuration variables */
|
||||
static int verbose = 0; /* -v */
|
||||
static bool list = false; /* list packages available for upgrade */
|
||||
static bool do_update = false; /* whether to call apt-get update */
|
||||
static bool only_critical = false; /* whether to warn about non-critical updates */
|
||||
static upgrade_type upgrade = UPGRADE; /* which type of upgrade to do */
|
||||
static char *upgrade_opts = NULL; /* options to override defaults for upgrade */
|
||||
static char *update_opts = NULL; /* options to override defaults for update */
|
||||
static char *do_include = NULL; /* regexp to only include certain packages */
|
||||
static char *do_exclude = NULL; /* regexp to only exclude certain packages */
|
||||
static char *do_critical = NULL; /* regexp specifying critical packages */
|
||||
static char *input_filename = NULL; /* input filename for testing */
|
||||
/* number of packages available for upgrade to return WARNING status */
|
||||
static int packages_warning = 1;
|
||||
static int verbose = 0; /* -v */
|
||||
|
||||
/* other global variables */
|
||||
static int stderr_warning = 0; /* if a cmd issued output on stderr */
|
||||
static int exec_warning = 0; /* if a cmd exited non-zero */
|
||||
static bool stderr_warning = false; /* if a cmd issued output on stderr */
|
||||
static bool exec_warning = false; /* if a cmd exited non-zero */
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
/* Parse extra opts if any */
|
||||
argv = np_extra_opts(&argc, argv, progname);
|
||||
|
||||
if (process_arguments(argc, argv) == ERROR) {
|
||||
check_apt_config_wrapper tmp_config = process_arguments(argc, argv);
|
||||
|
||||
if (tmp_config.errorcode == ERROR) {
|
||||
usage_va(_("Could not parse arguments"));
|
||||
}
|
||||
|
||||
const check_apt_config config = tmp_config.config;
|
||||
|
||||
/* Set signal handling and alarm timeout */
|
||||
if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) {
|
||||
usage_va(_("Cannot catch SIGALRM"));
|
||||
|
|
@ -123,14 +115,15 @@ int main(int argc, char **argv) {
|
|||
/* handle timeouts gracefully... */
|
||||
alarm(timeout_interval);
|
||||
|
||||
int result = STATE_UNKNOWN;
|
||||
mp_state_enum result = STATE_UNKNOWN;
|
||||
/* if they want to run apt-get update first... */
|
||||
if (do_update) {
|
||||
result = run_update();
|
||||
if (config.do_update) {
|
||||
result = run_update(config.update_opts);
|
||||
}
|
||||
|
||||
/* apt-get upgrade */
|
||||
run_upgrade_result upgrad_res = run_upgrade();
|
||||
run_upgrade_result upgrad_res =
|
||||
run_upgrade(config.upgrade, config.do_include, config.do_exclude, config.do_critical, config.upgrade_opts, config.input_filename);
|
||||
|
||||
result = max_state(result, upgrad_res.errorcode);
|
||||
int packages_available = upgrad_res.package_count;
|
||||
|
|
@ -140,18 +133,18 @@ int main(int argc, char **argv) {
|
|||
|
||||
if (sec_count > 0) {
|
||||
result = max_state(result, STATE_CRITICAL);
|
||||
} else if (packages_available >= packages_warning && only_critical == false) {
|
||||
} else if (packages_available >= config.packages_warning && !config.only_critical) {
|
||||
result = max_state(result, STATE_WARNING);
|
||||
} else if (result > STATE_UNKNOWN) {
|
||||
result = STATE_UNKNOWN;
|
||||
}
|
||||
|
||||
printf(_("APT %s: %d packages available for %s (%d critical updates). %s%s%s%s|available_upgrades=%d;;;0 critical_updates=%d;;;0\n"),
|
||||
state_text(result), packages_available, (upgrade == DIST_UPGRADE) ? "dist-upgrade" : "upgrade", sec_count,
|
||||
state_text(result), packages_available, (config.upgrade == DIST_UPGRADE) ? "dist-upgrade" : "upgrade", sec_count,
|
||||
(stderr_warning) ? " warnings detected" : "", (stderr_warning && exec_warning) ? "," : "",
|
||||
(exec_warning) ? " errors detected" : "", (stderr_warning || exec_warning) ? "." : "", packages_available, sec_count);
|
||||
|
||||
if (list) {
|
||||
if (config.list) {
|
||||
qsort(secpackages_list, sec_count, sizeof(char *), cmpstringp);
|
||||
qsort(packages_list, packages_available - sec_count, sizeof(char *), cmpstringp);
|
||||
|
||||
|
|
@ -159,7 +152,7 @@ int main(int argc, char **argv) {
|
|||
printf("%s (security)\n", secpackages_list[i]);
|
||||
}
|
||||
|
||||
if (only_critical == false) {
|
||||
if (!config.only_critical) {
|
||||
for (int i = 0; i < packages_available - sec_count; i++) {
|
||||
printf("%s\n", packages_list[i]);
|
||||
}
|
||||
|
|
@ -170,7 +163,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
/* process command-line arguments */
|
||||
int process_arguments(int argc, char **argv) {
|
||||
check_apt_config_wrapper process_arguments(int argc, char **argv) {
|
||||
static struct option longopts[] = {{"version", no_argument, 0, 'V'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
|
|
@ -179,7 +172,7 @@ int process_arguments(int argc, char **argv) {
|
|||
{"upgrade", optional_argument, 0, 'U'},
|
||||
{"no-upgrade", no_argument, 0, 'n'},
|
||||
{"dist-upgrade", optional_argument, 0, 'd'},
|
||||
{"list", no_argument, false, 'l'},
|
||||
{"list", no_argument, 0, 'l'},
|
||||
{"include", required_argument, 0, 'i'},
|
||||
{"exclude", required_argument, 0, 'e'},
|
||||
{"critical", required_argument, 0, 'c'},
|
||||
|
|
@ -188,6 +181,11 @@ int process_arguments(int argc, char **argv) {
|
|||
{"packages-warning", required_argument, 0, 'w'},
|
||||
{0, 0, 0, 0}};
|
||||
|
||||
check_apt_config_wrapper result = {
|
||||
.errorcode = OK,
|
||||
.config = check_apt_config_init(),
|
||||
};
|
||||
|
||||
while (true) {
|
||||
int option_char = getopt_long(argc, argv, "hVvt:u::U::d::nli:e:c:ow:", longopts, NULL);
|
||||
|
||||
|
|
@ -209,55 +207,55 @@ int process_arguments(int argc, char **argv) {
|
|||
timeout_interval = atoi(optarg);
|
||||
break;
|
||||
case 'd':
|
||||
upgrade = DIST_UPGRADE;
|
||||
result.config.upgrade = DIST_UPGRADE;
|
||||
if (optarg != NULL) {
|
||||
upgrade_opts = strdup(optarg);
|
||||
if (upgrade_opts == NULL) {
|
||||
result.config.upgrade_opts = strdup(optarg);
|
||||
if (result.config.upgrade_opts == NULL) {
|
||||
die(STATE_UNKNOWN, "strdup failed");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'U':
|
||||
upgrade = UPGRADE;
|
||||
result.config.upgrade = UPGRADE;
|
||||
if (optarg != NULL) {
|
||||
upgrade_opts = strdup(optarg);
|
||||
if (upgrade_opts == NULL) {
|
||||
result.config.upgrade_opts = strdup(optarg);
|
||||
if (result.config.upgrade_opts == NULL) {
|
||||
die(STATE_UNKNOWN, "strdup failed");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'n':
|
||||
upgrade = NO_UPGRADE;
|
||||
result.config.upgrade = NO_UPGRADE;
|
||||
break;
|
||||
case 'u':
|
||||
do_update = true;
|
||||
result.config.do_update = true;
|
||||
if (optarg != NULL) {
|
||||
update_opts = strdup(optarg);
|
||||
if (update_opts == NULL) {
|
||||
result.config.update_opts = strdup(optarg);
|
||||
if (result.config.update_opts == NULL) {
|
||||
die(STATE_UNKNOWN, "strdup failed");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'l':
|
||||
list = true;
|
||||
result.config.list = true;
|
||||
break;
|
||||
case 'i':
|
||||
do_include = add_to_regexp(do_include, optarg);
|
||||
result.config.do_include = add_to_regexp(result.config.do_include, optarg);
|
||||
break;
|
||||
case 'e':
|
||||
do_exclude = add_to_regexp(do_exclude, optarg);
|
||||
result.config.do_exclude = add_to_regexp(result.config.do_exclude, optarg);
|
||||
break;
|
||||
case 'c':
|
||||
do_critical = add_to_regexp(do_critical, optarg);
|
||||
result.config.do_critical = add_to_regexp(result.config.do_critical, optarg);
|
||||
break;
|
||||
case 'o':
|
||||
only_critical = true;
|
||||
result.config.only_critical = true;
|
||||
break;
|
||||
case INPUT_FILE_OPT:
|
||||
input_filename = optarg;
|
||||
result.config.input_filename = optarg;
|
||||
break;
|
||||
case 'w':
|
||||
packages_warning = atoi(optarg);
|
||||
result.config.packages_warning = atoi(optarg);
|
||||
break;
|
||||
default:
|
||||
/* print short usage statement if args not parsable */
|
||||
|
|
@ -265,11 +263,12 @@ int process_arguments(int argc, char **argv) {
|
|||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* run an apt-get upgrade */
|
||||
run_upgrade_result run_upgrade(void) {
|
||||
run_upgrade_result run_upgrade(const upgrade_type upgrade, const char *do_include, const char *do_exclude, const char *do_critical,
|
||||
const char *upgrade_opts, const char *input_filename) {
|
||||
regex_t ereg;
|
||||
/* initialize ereg as it is possible it is printed while uninitialized */
|
||||
memset(&ereg, '\0', sizeof(ereg.buffer));
|
||||
|
|
@ -332,7 +331,7 @@ run_upgrade_result run_upgrade(void) {
|
|||
fprintf(stderr, _("'%s' exited with non-zero status.\n"), cmdline);
|
||||
}
|
||||
|
||||
char **pkglist = malloc(sizeof(char *) * chld_out.lines);
|
||||
char **pkglist = malloc(sizeof(char *) * chld_out.lines);
|
||||
if (!pkglist) {
|
||||
die(STATE_UNKNOWN, "malloc failed!\n");
|
||||
}
|
||||
|
|
@ -385,7 +384,7 @@ run_upgrade_result run_upgrade(void) {
|
|||
|
||||
/* If we get anything on stderr, at least set warning */
|
||||
if (input_filename == NULL && chld_err.buflen) {
|
||||
stderr_warning = 1;
|
||||
stderr_warning = true;
|
||||
result.errorcode = max_state(result.errorcode, STATE_WARNING);
|
||||
if (verbose) {
|
||||
for (size_t i = 0; i < chld_err.lines; i++) {
|
||||
|
|
@ -405,7 +404,7 @@ run_upgrade_result run_upgrade(void) {
|
|||
}
|
||||
|
||||
/* run an apt-get update (needs root) */
|
||||
int run_update(void) {
|
||||
int run_update(char *update_opts) {
|
||||
int result = STATE_UNKNOWN;
|
||||
char *cmdline;
|
||||
/* run the update */
|
||||
|
|
@ -418,7 +417,7 @@ int run_update(void) {
|
|||
* since we were explicitly asked to do so, this is treated as
|
||||
* a critical error. */
|
||||
if (result != 0) {
|
||||
exec_warning = 1;
|
||||
exec_warning = true;
|
||||
result = STATE_CRITICAL;
|
||||
fprintf(stderr, _("'%s' exited with non-zero status.\n"), cmdline);
|
||||
}
|
||||
|
|
@ -446,7 +445,7 @@ int run_update(void) {
|
|||
char *pkg_name(char *line) {
|
||||
char *start = line + strlen(PKGINST_PREFIX);
|
||||
|
||||
int len = strlen(start);
|
||||
size_t len = strlen(start);
|
||||
|
||||
char *space = index(start, ' ');
|
||||
if (space != NULL) {
|
||||
|
|
@ -464,35 +463,37 @@ char *pkg_name(char *line) {
|
|||
return pkg;
|
||||
}
|
||||
|
||||
int cmpstringp(const void *p1, const void *p2) { return strcmp(*(char *const *)p1, *(char *const *)p2); }
|
||||
int cmpstringp(const void *left_string, const void *right_string) {
|
||||
return strcmp(*(char *const *)left_string, *(char *const *)right_string);
|
||||
}
|
||||
|
||||
char *add_to_regexp(char *expr, const char *next) {
|
||||
char *re = NULL;
|
||||
char *regex_string = NULL;
|
||||
|
||||
if (expr == NULL) {
|
||||
re = malloc(sizeof(char) * (strlen("()") + strlen(next) + 1));
|
||||
if (!re) {
|
||||
regex_string = malloc(sizeof(char) * (strlen("()") + strlen(next) + 1));
|
||||
if (!regex_string) {
|
||||
die(STATE_UNKNOWN, "malloc failed!\n");
|
||||
}
|
||||
sprintf(re, "(%s)", next);
|
||||
sprintf(regex_string, "(%s)", next);
|
||||
} else {
|
||||
/* resize it, adding an extra char for the new '|' separator */
|
||||
re = realloc(expr, sizeof(char) * (strlen(expr) + 1 + strlen(next) + 1));
|
||||
if (!re) {
|
||||
regex_string = realloc(expr, sizeof(char) * (strlen(expr) + 1 + strlen(next) + 1));
|
||||
if (!regex_string) {
|
||||
die(STATE_UNKNOWN, "realloc failed!\n");
|
||||
}
|
||||
/* append it starting at ')' in the old re */
|
||||
sprintf((char *)(re + strlen(re) - 1), "|%s)", next);
|
||||
sprintf((char *)(regex_string + strlen(regex_string) - 1), "|%s)", next);
|
||||
}
|
||||
|
||||
return re;
|
||||
return regex_string;
|
||||
}
|
||||
|
||||
char *construct_cmdline(upgrade_type u, const char *opts) {
|
||||
char *construct_cmdline(upgrade_type upgrade, const char *opts) {
|
||||
const char *opts_ptr = NULL;
|
||||
const char *aptcmd = NULL;
|
||||
|
||||
switch (u) {
|
||||
switch (upgrade) {
|
||||
case UPGRADE:
|
||||
if (opts == NULL) {
|
||||
opts_ptr = UPGRADE_DEFAULT_OPTS;
|
||||
|
|
|
|||
41
plugins/check_apt.d/config.h
Normal file
41
plugins/check_apt.d/config.h
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../config.h"
|
||||
#include <stddef.h>
|
||||
|
||||
/* some constants */
|
||||
typedef enum {
|
||||
UPGRADE,
|
||||
DIST_UPGRADE,
|
||||
NO_UPGRADE
|
||||
} upgrade_type;
|
||||
|
||||
typedef struct {
|
||||
bool do_update; /* whether to call apt-get update */
|
||||
upgrade_type upgrade; /* which type of upgrade to do */
|
||||
bool only_critical; /* whether to warn about non-critical updates */
|
||||
bool list; /* list packages available for upgrade */
|
||||
/* number of packages available for upgrade to return WARNING status */
|
||||
int packages_warning;
|
||||
|
||||
char *upgrade_opts; /* options to override defaults for upgrade */
|
||||
char *update_opts; /* options to override defaults for update */
|
||||
char *do_include; /* regexp to only include certain packages */
|
||||
char *do_exclude; /* regexp to only exclude certain packages */
|
||||
char *do_critical; /* regexp specifying critical packages */
|
||||
char *input_filename; /* input filename for testing */
|
||||
} check_apt_config;
|
||||
|
||||
check_apt_config check_apt_config_init() {
|
||||
check_apt_config tmp = {.do_update = false,
|
||||
.upgrade = UPGRADE,
|
||||
.only_critical = false,
|
||||
.list = false,
|
||||
.packages_warning = 1,
|
||||
.update_opts = NULL,
|
||||
.do_include = NULL,
|
||||
.do_exclude = NULL,
|
||||
.do_critical = NULL,
|
||||
.input_filename = NULL};
|
||||
return tmp;
|
||||
}
|
||||
|
|
@ -32,48 +32,28 @@ const char *email = "devel@monitoring-plugins.org";
|
|||
|
||||
#include "common.h"
|
||||
#include "utils.h"
|
||||
#include "netutils.h"
|
||||
#include "utils_cmd.h"
|
||||
#include "check_by_ssh.d/config.h"
|
||||
#include "states.h"
|
||||
|
||||
#ifndef NP_MAXARGS
|
||||
# define NP_MAXARGS 1024
|
||||
#endif
|
||||
|
||||
static int process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
static int validate_arguments(void);
|
||||
static void comm_append(const char * /*str*/);
|
||||
typedef struct {
|
||||
int errorcode;
|
||||
check_by_ssh_config config;
|
||||
} check_by_ssh_config_wrapper;
|
||||
static check_by_ssh_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
static check_by_ssh_config_wrapper validate_arguments(check_by_ssh_config_wrapper /*config_wrapper*/);
|
||||
|
||||
static command_construct comm_append(command_construct /*cmd*/, const char * /*str*/);
|
||||
static void print_help(void);
|
||||
void print_usage(void);
|
||||
|
||||
static unsigned int commands = 0;
|
||||
static unsigned int services = 0;
|
||||
static int skip_stdout = 0;
|
||||
static int skip_stderr = 0;
|
||||
static int warn_on_stderr = 0;
|
||||
static bool unknown_timeout = false;
|
||||
static char *remotecmd = NULL;
|
||||
static char **commargv = NULL;
|
||||
static int commargc = 0;
|
||||
static char *hostname = NULL;
|
||||
static char *outputfile = NULL;
|
||||
static char *host_shortname = NULL;
|
||||
static char **service;
|
||||
static bool passive = false;
|
||||
static bool verbose = false;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
char *status_text;
|
||||
int cresult;
|
||||
int result = STATE_UNKNOWN;
|
||||
time_t local_time;
|
||||
FILE *file_pointer = NULL;
|
||||
output chld_out;
|
||||
output chld_err;
|
||||
|
||||
remotecmd = "";
|
||||
comm_append(SSH_COMMAND);
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
textdomain(PACKAGE);
|
||||
|
|
@ -81,11 +61,15 @@ int main(int argc, char **argv) {
|
|||
/* Parse extra opts if any */
|
||||
argv = np_extra_opts(&argc, argv, progname);
|
||||
|
||||
check_by_ssh_config_wrapper tmp_config = process_arguments(argc, argv);
|
||||
|
||||
/* process arguments */
|
||||
if (process_arguments(argc, argv) == ERROR) {
|
||||
if (tmp_config.errorcode == ERROR) {
|
||||
usage_va(_("Could not parse arguments"));
|
||||
}
|
||||
|
||||
const check_by_ssh_config config = tmp_config.config;
|
||||
|
||||
/* Set signal handling and alarm timeout */
|
||||
if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) {
|
||||
usage_va(_("Cannot catch SIGALRM"));
|
||||
|
|
@ -94,16 +78,18 @@ int main(int argc, char **argv) {
|
|||
|
||||
/* run the command */
|
||||
if (verbose) {
|
||||
printf("Command: %s\n", commargv[0]);
|
||||
for (int i = 1; i < commargc; i++) {
|
||||
printf("Argument %i: %s\n", i, commargv[i]);
|
||||
printf("Command: %s\n", config.cmd.commargv[0]);
|
||||
for (int i = 1; i < config.cmd.commargc; i++) {
|
||||
printf("Argument %i: %s\n", i, config.cmd.commargv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
result = cmd_run_array(commargv, &chld_out, &chld_err, 0);
|
||||
output chld_out;
|
||||
output chld_err;
|
||||
mp_state_enum result = cmd_run_array(config.cmd.commargv, &chld_out, &chld_err, 0);
|
||||
|
||||
/* SSH returns 255 if connection attempt fails; include the first line of error output */
|
||||
if (result == 255 && unknown_timeout) {
|
||||
if (result == 255 && config.unknown_timeout) {
|
||||
printf(_("SSH connection failed: %s\n"), chld_err.lines > 0 ? chld_err.line[0] : "(no error output)");
|
||||
return STATE_UNKNOWN;
|
||||
}
|
||||
|
|
@ -117,17 +103,24 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
}
|
||||
|
||||
if (skip_stdout == -1) { /* --skip-stdout specified without argument */
|
||||
size_t skip_stdout = 0;
|
||||
if (config.skip_stdout == -1) { /* --skip-stdout specified without argument */
|
||||
skip_stdout = chld_out.lines;
|
||||
} else {
|
||||
skip_stdout = config.skip_stdout;
|
||||
}
|
||||
if (skip_stderr == -1) { /* --skip-stderr specified without argument */
|
||||
|
||||
size_t skip_stderr = 0;
|
||||
if (config.skip_stderr == -1) { /* --skip-stderr specified without argument */
|
||||
skip_stderr = chld_err.lines;
|
||||
} else {
|
||||
skip_stderr = config.skip_stderr;
|
||||
}
|
||||
|
||||
/* UNKNOWN or worse if (non-skipped) output found on stderr */
|
||||
if (chld_err.lines > (size_t)skip_stderr) {
|
||||
printf(_("Remote command execution failed: %s\n"), chld_err.line[skip_stderr]);
|
||||
if (warn_on_stderr) {
|
||||
if (config.warn_on_stderr) {
|
||||
return max_state_alt(result, STATE_WARNING);
|
||||
}
|
||||
return max_state_alt(result, STATE_UNKNOWN);
|
||||
|
|
@ -135,13 +128,13 @@ int main(int argc, char **argv) {
|
|||
|
||||
/* this is simple if we're not supposed to be passive.
|
||||
* Wrap up quickly and keep the tricks below */
|
||||
if (!passive) {
|
||||
if (!config.passive) {
|
||||
if (chld_out.lines > (size_t)skip_stdout) {
|
||||
for (size_t i = skip_stdout; i < chld_out.lines; i++) {
|
||||
puts(chld_out.line[i]);
|
||||
}
|
||||
} else {
|
||||
printf(_("%s - check_by_ssh: Remote command '%s' returned status %d\n"), state_text(result), remotecmd, result);
|
||||
printf(_("%s - check_by_ssh: Remote command '%s' returned status %d\n"), state_text(result), config.remotecmd, result);
|
||||
}
|
||||
return result; /* return error status from remote command */
|
||||
}
|
||||
|
|
@ -151,36 +144,34 @@ int main(int argc, char **argv) {
|
|||
*/
|
||||
|
||||
/* process output */
|
||||
if (!(file_pointer = fopen(outputfile, "a"))) {
|
||||
printf(_("SSH WARNING: could not open %s\n"), outputfile);
|
||||
FILE *file_pointer = NULL;
|
||||
if (!(file_pointer = fopen(config.outputfile, "a"))) {
|
||||
printf(_("SSH WARNING: could not open %s\n"), config.outputfile);
|
||||
exit(STATE_UNKNOWN);
|
||||
}
|
||||
|
||||
local_time = time(NULL);
|
||||
commands = 0;
|
||||
time_t local_time = time(NULL);
|
||||
unsigned int commands = 0;
|
||||
char *status_text;
|
||||
int cresult;
|
||||
for (size_t i = skip_stdout; i < chld_out.lines; i++) {
|
||||
status_text = chld_out.line[i++];
|
||||
if (i == chld_out.lines || strstr(chld_out.line[i], "STATUS CODE: ") == NULL) {
|
||||
die(STATE_UNKNOWN, _("%s: Error parsing output\n"), progname);
|
||||
}
|
||||
|
||||
if (service[commands] && status_text && sscanf(chld_out.line[i], "STATUS CODE: %d", &cresult) == 1) {
|
||||
fprintf(file_pointer, "[%d] PROCESS_SERVICE_CHECK_RESULT;%s;%s;%d;%s\n", (int)local_time, host_shortname, service[commands++],
|
||||
cresult, status_text);
|
||||
if (config.service[commands] && status_text && sscanf(chld_out.line[i], "STATUS CODE: %d", &cresult) == 1) {
|
||||
fprintf(file_pointer, "[%d] PROCESS_SERVICE_CHECK_RESULT;%s;%s;%d;%s\n", (int)local_time, config.host_shortname,
|
||||
config.service[commands++], cresult, status_text);
|
||||
}
|
||||
}
|
||||
|
||||
/* Multiple commands and passive checking should always return OK */
|
||||
return result;
|
||||
exit(result);
|
||||
}
|
||||
|
||||
/* process command-line arguments */
|
||||
int process_arguments(int argc, char **argv) {
|
||||
int c;
|
||||
char *p1;
|
||||
char *p2;
|
||||
|
||||
int option = 0;
|
||||
check_by_ssh_config_wrapper process_arguments(int argc, char **argv) {
|
||||
static struct option longopts[] = {{"version", no_argument, 0, 'V'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
|
|
@ -210,24 +201,33 @@ int process_arguments(int argc, char **argv) {
|
|||
{"configfile", optional_argument, 0, 'F'},
|
||||
{0, 0, 0, 0}};
|
||||
|
||||
check_by_ssh_config_wrapper result = {
|
||||
.errorcode = OK,
|
||||
.config = check_by_ssh_config_init(),
|
||||
};
|
||||
|
||||
if (argc < 2) {
|
||||
return ERROR;
|
||||
result.errorcode = ERROR;
|
||||
return result;
|
||||
}
|
||||
|
||||
for (c = 1; c < argc; c++) {
|
||||
if (strcmp("-to", argv[c]) == 0) {
|
||||
strcpy(argv[c], "-t");
|
||||
for (int index = 1; index < argc; index++) {
|
||||
if (strcmp("-to", argv[index]) == 0) {
|
||||
strcpy(argv[index], "-t");
|
||||
}
|
||||
}
|
||||
|
||||
while (1) {
|
||||
c = getopt_long(argc, argv, "Vvh1246fqt:UH:O:p:i:u:l:C:S::E::n:s:o:F:", longopts, &option);
|
||||
result.config.cmd = comm_append(result.config.cmd, SSH_COMMAND);
|
||||
|
||||
if (c == -1 || c == EOF) {
|
||||
int option = 0;
|
||||
while (true) {
|
||||
int opt_index = getopt_long(argc, argv, "Vvh1246fqt:UH:O:p:i:u:l:C:S::E::n:s:o:F:", longopts, &option);
|
||||
|
||||
if (opt_index == -1 || opt_index == EOF) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (c) {
|
||||
switch (opt_index) {
|
||||
case 'V': /* version */
|
||||
print_revision(progname, NP_VERSION);
|
||||
exit(STATE_UNKNOWN);
|
||||
|
|
@ -245,169 +245,182 @@ int process_arguments(int argc, char **argv) {
|
|||
}
|
||||
break;
|
||||
case 'U':
|
||||
unknown_timeout = true;
|
||||
result.config.unknown_timeout = true;
|
||||
break;
|
||||
case 'H': /* host */
|
||||
hostname = optarg;
|
||||
result.config.hostname = optarg;
|
||||
break;
|
||||
case 'p': /* port number */
|
||||
if (!is_integer(optarg)) {
|
||||
usage_va(_("Port must be a positive integer"));
|
||||
}
|
||||
comm_append("-p");
|
||||
comm_append(optarg);
|
||||
result.config.cmd = comm_append(result.config.cmd, "-p");
|
||||
result.config.cmd = comm_append(result.config.cmd, optarg);
|
||||
break;
|
||||
case 'O': /* output file */
|
||||
outputfile = optarg;
|
||||
passive = true;
|
||||
result.config.outputfile = optarg;
|
||||
result.config.passive = true;
|
||||
break;
|
||||
case 's': /* description of service to check */
|
||||
case 's': /* description of service to check */ {
|
||||
char *p1;
|
||||
char *p2;
|
||||
|
||||
p1 = optarg;
|
||||
service = realloc(service, (++services) * sizeof(char *));
|
||||
result.config.service = realloc(result.config.service, (++result.config.number_of_services) * sizeof(char *));
|
||||
while ((p2 = index(p1, ':'))) {
|
||||
*p2 = '\0';
|
||||
service[services - 1] = p1;
|
||||
service = realloc(service, (++services) * sizeof(char *));
|
||||
result.config.service[result.config.number_of_services - 1] = p1;
|
||||
result.config.service = realloc(result.config.service, (++result.config.number_of_services) * sizeof(char *));
|
||||
p1 = p2 + 1;
|
||||
}
|
||||
service[services - 1] = p1;
|
||||
result.config.service[result.config.number_of_services - 1] = p1;
|
||||
break;
|
||||
case 'n': /* short name of host in the monitoring configuration */
|
||||
host_shortname = optarg;
|
||||
break;
|
||||
|
||||
result.config.host_shortname = optarg;
|
||||
} break;
|
||||
case 'u':
|
||||
comm_append("-l");
|
||||
comm_append(optarg);
|
||||
result.config.cmd = comm_append(result.config.cmd, "-l");
|
||||
result.config.cmd = comm_append(result.config.cmd, optarg);
|
||||
break;
|
||||
case 'l': /* login name */
|
||||
comm_append("-l");
|
||||
comm_append(optarg);
|
||||
result.config.cmd = comm_append(result.config.cmd, "-l");
|
||||
result.config.cmd = comm_append(result.config.cmd, optarg);
|
||||
break;
|
||||
case 'i': /* identity */
|
||||
comm_append("-i");
|
||||
comm_append(optarg);
|
||||
result.config.cmd = comm_append(result.config.cmd, "-i");
|
||||
result.config.cmd = comm_append(result.config.cmd, optarg);
|
||||
break;
|
||||
|
||||
case '1': /* Pass these switches directly to ssh */
|
||||
comm_append("-1");
|
||||
result.config.cmd = comm_append(result.config.cmd, "-1");
|
||||
break;
|
||||
case '2': /* 1 to force version 1, 2 to force version 2 */
|
||||
comm_append("-2");
|
||||
result.config.cmd = comm_append(result.config.cmd, "-2");
|
||||
break;
|
||||
case '4': /* -4 for IPv4 */
|
||||
comm_append("-4");
|
||||
result.config.cmd = comm_append(result.config.cmd, "-4");
|
||||
break;
|
||||
case '6': /* -6 for IPv6 */
|
||||
comm_append("-6");
|
||||
result.config.cmd = comm_append(result.config.cmd, "-6");
|
||||
break;
|
||||
case 'f': /* fork to background */
|
||||
comm_append("-f");
|
||||
result.config.cmd = comm_append(result.config.cmd, "-f");
|
||||
break;
|
||||
case 'C': /* Command for remote machine */
|
||||
commands++;
|
||||
if (commands > 1) {
|
||||
xasprintf(&remotecmd, "%s;echo STATUS CODE: $?;", remotecmd);
|
||||
result.config.commands++;
|
||||
if (result.config.commands > 1) {
|
||||
xasprintf(&result.config.remotecmd, "%s;echo STATUS CODE: $?;", result.config.remotecmd);
|
||||
}
|
||||
xasprintf(&remotecmd, "%s%s", remotecmd, optarg);
|
||||
xasprintf(&result.config.remotecmd, "%s%s", result.config.remotecmd, optarg);
|
||||
break;
|
||||
case 'S': /* skip n (or all) lines on stdout */
|
||||
if (optarg == NULL) {
|
||||
skip_stdout = -1; /* skip all output on stdout */
|
||||
result.config.skip_stdout = -1; /* skip all output on stdout */
|
||||
} else if (!is_integer(optarg)) {
|
||||
usage_va(_("skip-stdout argument must be an integer"));
|
||||
} else {
|
||||
skip_stdout = atoi(optarg);
|
||||
result.config.skip_stdout = atoi(optarg);
|
||||
}
|
||||
break;
|
||||
case 'E': /* skip n (or all) lines on stderr */
|
||||
if (optarg == NULL) {
|
||||
skip_stderr = -1; /* skip all output on stderr */
|
||||
result.config.skip_stderr = -1; /* skip all output on stderr */
|
||||
} else if (!is_integer(optarg)) {
|
||||
usage_va(_("skip-stderr argument must be an integer"));
|
||||
} else {
|
||||
skip_stderr = atoi(optarg);
|
||||
result.config.skip_stderr = atoi(optarg);
|
||||
}
|
||||
break;
|
||||
case 'W': /* exit with warning if there is an output on stderr */
|
||||
warn_on_stderr = 1;
|
||||
result.config.warn_on_stderr = true;
|
||||
break;
|
||||
case 'o': /* Extra options for the ssh command */
|
||||
comm_append("-o");
|
||||
comm_append(optarg);
|
||||
result.config.cmd = comm_append(result.config.cmd, "-o");
|
||||
result.config.cmd = comm_append(result.config.cmd, optarg);
|
||||
break;
|
||||
case 'q': /* Tell the ssh command to be quiet */
|
||||
comm_append("-q");
|
||||
result.config.cmd = comm_append(result.config.cmd, "-q");
|
||||
break;
|
||||
case 'F': /* ssh configfile */
|
||||
comm_append("-F");
|
||||
comm_append(optarg);
|
||||
result.config.cmd = comm_append(result.config.cmd, "-F");
|
||||
result.config.cmd = comm_append(result.config.cmd, optarg);
|
||||
break;
|
||||
default: /* help */
|
||||
usage5();
|
||||
}
|
||||
}
|
||||
|
||||
c = optind;
|
||||
if (hostname == NULL) {
|
||||
int c = optind;
|
||||
if (result.config.hostname == NULL) {
|
||||
if (c <= argc) {
|
||||
die(STATE_UNKNOWN, _("%s: You must provide a host name\n"), progname);
|
||||
}
|
||||
hostname = argv[c++];
|
||||
result.config.hostname = argv[c++];
|
||||
}
|
||||
|
||||
if (strlen(remotecmd) == 0) {
|
||||
if (strlen(result.config.remotecmd) == 0) {
|
||||
for (; c < argc; c++) {
|
||||
if (strlen(remotecmd) > 0) {
|
||||
xasprintf(&remotecmd, "%s %s", remotecmd, argv[c]);
|
||||
if (strlen(result.config.remotecmd) > 0) {
|
||||
xasprintf(&result.config.remotecmd, "%s %s", result.config.remotecmd, argv[c]);
|
||||
} else {
|
||||
xasprintf(&remotecmd, "%s", argv[c]);
|
||||
xasprintf(&result.config.remotecmd, "%s", argv[c]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (commands > 1 || passive) {
|
||||
xasprintf(&remotecmd, "%s;echo STATUS CODE: $?;", remotecmd);
|
||||
if (result.config.commands > 1 || result.config.passive) {
|
||||
xasprintf(&result.config.remotecmd, "%s;echo STATUS CODE: $?;", result.config.remotecmd);
|
||||
}
|
||||
|
||||
if (remotecmd == NULL || strlen(remotecmd) <= 1) {
|
||||
if (result.config.remotecmd == NULL || strlen(result.config.remotecmd) <= 1) {
|
||||
usage_va(_("No remotecmd"));
|
||||
}
|
||||
|
||||
comm_append(hostname);
|
||||
comm_append(remotecmd);
|
||||
result.config.cmd = comm_append(result.config.cmd, result.config.hostname);
|
||||
result.config.cmd = comm_append(result.config.cmd, result.config.remotecmd);
|
||||
|
||||
return validate_arguments();
|
||||
return validate_arguments(result);
|
||||
}
|
||||
|
||||
void comm_append(const char *str) {
|
||||
command_construct comm_append(command_construct cmd, const char *str) {
|
||||
|
||||
if (++commargc > NP_MAXARGS) {
|
||||
if (verbose) {
|
||||
for (int i = 0; i < cmd.commargc; i++) {
|
||||
printf("Current command: [%i] %s\n", i, cmd.commargv[i]);
|
||||
}
|
||||
|
||||
printf("Appending: %s\n", str);
|
||||
}
|
||||
|
||||
if (++cmd.commargc > NP_MAXARGS) {
|
||||
die(STATE_UNKNOWN, _("%s: Argument limit of %d exceeded\n"), progname, NP_MAXARGS);
|
||||
}
|
||||
|
||||
if ((commargv = (char **)realloc(commargv, (commargc + 1) * sizeof(char *))) == NULL) {
|
||||
if ((cmd.commargv = (char **)realloc(cmd.commargv, (cmd.commargc + 1) * sizeof(char *))) == NULL) {
|
||||
die(STATE_UNKNOWN, _("Can not (re)allocate 'commargv' buffer\n"));
|
||||
}
|
||||
|
||||
commargv[commargc - 1] = strdup(str);
|
||||
commargv[commargc] = NULL;
|
||||
cmd.commargv[cmd.commargc - 1] = strdup(str);
|
||||
cmd.commargv[cmd.commargc] = NULL;
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
int validate_arguments(void) {
|
||||
if (remotecmd == NULL || hostname == NULL) {
|
||||
return ERROR;
|
||||
check_by_ssh_config_wrapper validate_arguments(check_by_ssh_config_wrapper config_wrapper) {
|
||||
if (config_wrapper.config.remotecmd == NULL || config_wrapper.config.hostname == NULL) {
|
||||
config_wrapper.errorcode = ERROR;
|
||||
return config_wrapper;
|
||||
}
|
||||
|
||||
if (passive && commands != services) {
|
||||
if (config_wrapper.config.passive && config_wrapper.config.commands != config_wrapper.config.number_of_services) {
|
||||
die(STATE_UNKNOWN, _("%s: In passive mode, you must provide a service name for each command.\n"), progname);
|
||||
}
|
||||
|
||||
if (passive && host_shortname == NULL) {
|
||||
if (config_wrapper.config.passive && config_wrapper.config.host_shortname == NULL) {
|
||||
die(STATE_UNKNOWN, _("%s: In passive mode, you must provide the host short name from the monitoring configs.\n"), progname);
|
||||
}
|
||||
|
||||
return OK;
|
||||
return config_wrapper;
|
||||
}
|
||||
|
||||
void print_help(void) {
|
||||
|
|
|
|||
56
plugins/check_by_ssh.d/config.h
Normal file
56
plugins/check_by_ssh.d/config.h
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../config.h"
|
||||
#include <stddef.h>
|
||||
|
||||
typedef struct {
|
||||
int commargc;
|
||||
char **commargv;
|
||||
} command_construct;
|
||||
|
||||
typedef struct {
|
||||
char *hostname;
|
||||
char *host_shortname;
|
||||
|
||||
char **service;
|
||||
unsigned int number_of_services;
|
||||
|
||||
unsigned int commands; // Not needed during actual test run
|
||||
char *remotecmd;
|
||||
|
||||
command_construct cmd;
|
||||
|
||||
bool unknown_timeout;
|
||||
bool warn_on_stderr;
|
||||
int skip_stdout;
|
||||
int skip_stderr;
|
||||
bool passive;
|
||||
char *outputfile;
|
||||
} check_by_ssh_config;
|
||||
|
||||
check_by_ssh_config check_by_ssh_config_init() {
|
||||
check_by_ssh_config tmp = {
|
||||
.hostname = NULL,
|
||||
.host_shortname = NULL,
|
||||
|
||||
.service = NULL,
|
||||
.number_of_services = 0,
|
||||
|
||||
.commands = 0,
|
||||
.remotecmd = "",
|
||||
|
||||
.cmd =
|
||||
{
|
||||
.commargc = 0,
|
||||
.commargv = NULL,
|
||||
},
|
||||
|
||||
.unknown_timeout = false,
|
||||
.warn_on_stderr = false,
|
||||
.skip_stderr = 0,
|
||||
.skip_stdout = 0,
|
||||
.passive = false,
|
||||
.outputfile = NULL,
|
||||
};
|
||||
return tmp;
|
||||
}
|
||||
|
|
@ -29,42 +29,20 @@ const char *email = "devel@monitoring-plugins.org";
|
|||
#include "common.h"
|
||||
#include "utils.h"
|
||||
#include "utils_base.h"
|
||||
|
||||
enum {
|
||||
CHECK_SERVICES = 1,
|
||||
CHECK_HOSTS = 2
|
||||
};
|
||||
#include "check_cluster.d/config.h"
|
||||
|
||||
static void print_help(void);
|
||||
void print_usage(void);
|
||||
|
||||
static int total_services_ok = 0;
|
||||
static int total_services_warning = 0;
|
||||
static int total_services_unknown = 0;
|
||||
static int total_services_critical = 0;
|
||||
|
||||
static int total_hosts_up = 0;
|
||||
static int total_hosts_down = 0;
|
||||
static int total_hosts_unreachable = 0;
|
||||
|
||||
static char *warn_threshold;
|
||||
static char *crit_threshold;
|
||||
|
||||
static int check_type = CHECK_SERVICES;
|
||||
|
||||
static char *data_vals = NULL;
|
||||
static char *label = NULL;
|
||||
|
||||
static int verbose = 0;
|
||||
|
||||
static int process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
typedef struct {
|
||||
int errorcode;
|
||||
check_cluster_config config;
|
||||
} check_cluster_config_wrapper;
|
||||
static check_cluster_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
char *ptr;
|
||||
int data_val;
|
||||
int return_code = STATE_OK;
|
||||
thresholds *thresholds = NULL;
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
textdomain(PACKAGE);
|
||||
|
|
@ -72,20 +50,32 @@ int main(int argc, char **argv) {
|
|||
/* Parse extra opts if any */
|
||||
argv = np_extra_opts(&argc, argv, progname);
|
||||
|
||||
if (process_arguments(argc, argv) == ERROR)
|
||||
check_cluster_config_wrapper tmp_config = process_arguments(argc, argv);
|
||||
if (tmp_config.errorcode == ERROR) {
|
||||
usage(_("Could not parse arguments"));
|
||||
}
|
||||
|
||||
const check_cluster_config config = tmp_config.config;
|
||||
|
||||
/* Initialize the thresholds */
|
||||
set_thresholds(&thresholds, warn_threshold, crit_threshold);
|
||||
if (verbose)
|
||||
print_thresholds("check_cluster", thresholds);
|
||||
if (verbose) {
|
||||
print_thresholds("check_cluster", config.thresholds);
|
||||
}
|
||||
|
||||
int data_val;
|
||||
int total_services_ok = 0;
|
||||
int total_services_warning = 0;
|
||||
int total_services_unknown = 0;
|
||||
int total_services_critical = 0;
|
||||
int total_hosts_up = 0;
|
||||
int total_hosts_down = 0;
|
||||
int total_hosts_unreachable = 0;
|
||||
/* check the data values */
|
||||
for (ptr = strtok(data_vals, ","); ptr != NULL; ptr = strtok(NULL, ",")) {
|
||||
for (char *ptr = strtok(config.data_vals, ","); ptr != NULL; ptr = strtok(NULL, ",")) {
|
||||
|
||||
data_val = atoi(ptr);
|
||||
|
||||
if (check_type == CHECK_SERVICES) {
|
||||
if (config.check_type == CHECK_SERVICES) {
|
||||
switch (data_val) {
|
||||
case 0:
|
||||
total_services_ok++;
|
||||
|
|
@ -119,101 +109,108 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
}
|
||||
|
||||
int return_code = STATE_OK;
|
||||
/* return the status of the cluster */
|
||||
if (check_type == CHECK_SERVICES) {
|
||||
return_code = get_status(total_services_warning + total_services_unknown + total_services_critical, thresholds);
|
||||
if (config.check_type == CHECK_SERVICES) {
|
||||
return_code = get_status(total_services_warning + total_services_unknown + total_services_critical, config.thresholds);
|
||||
printf("CLUSTER %s: %s: %d ok, %d warning, %d unknown, %d critical\n", state_text(return_code),
|
||||
(label == NULL) ? "Service cluster" : label, total_services_ok, total_services_warning, total_services_unknown,
|
||||
(config.label == NULL) ? "Service cluster" : config.label, total_services_ok, total_services_warning, total_services_unknown,
|
||||
total_services_critical);
|
||||
} else {
|
||||
return_code = get_status(total_hosts_down + total_hosts_unreachable, thresholds);
|
||||
printf("CLUSTER %s: %s: %d up, %d down, %d unreachable\n", state_text(return_code), (label == NULL) ? "Host cluster" : label,
|
||||
total_hosts_up, total_hosts_down, total_hosts_unreachable);
|
||||
return_code = get_status(total_hosts_down + total_hosts_unreachable, config.thresholds);
|
||||
printf("CLUSTER %s: %s: %d up, %d down, %d unreachable\n", state_text(return_code),
|
||||
(config.label == NULL) ? "Host cluster" : config.label, total_hosts_up, total_hosts_down, total_hosts_unreachable);
|
||||
}
|
||||
|
||||
return return_code;
|
||||
exit(return_code);
|
||||
}
|
||||
|
||||
int process_arguments(int argc, char **argv) {
|
||||
int c;
|
||||
char *ptr;
|
||||
int option = 0;
|
||||
check_cluster_config_wrapper process_arguments(int argc, char **argv) {
|
||||
static struct option longopts[] = {{"data", required_argument, 0, 'd'}, {"warning", required_argument, 0, 'w'},
|
||||
{"critical", required_argument, 0, 'c'}, {"label", required_argument, 0, 'l'},
|
||||
{"host", no_argument, 0, 'h'}, {"service", no_argument, 0, 's'},
|
||||
{"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'},
|
||||
{"help", no_argument, 0, 'H'}, {0, 0, 0, 0}};
|
||||
|
||||
check_cluster_config_wrapper result = {
|
||||
.errorcode = OK,
|
||||
.config = check_cluster_config_init(),
|
||||
};
|
||||
|
||||
/* no options were supplied */
|
||||
if (argc < 2)
|
||||
return ERROR;
|
||||
if (argc < 2) {
|
||||
result.errorcode = ERROR;
|
||||
return result;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
int option = 0;
|
||||
char *warn_threshold = NULL;
|
||||
char *crit_threshold = NULL;
|
||||
while (true) {
|
||||
int option_index = getopt_long(argc, argv, "hHsvVw:c:d:l:", longopts, &option);
|
||||
|
||||
c = getopt_long(argc, argv, "hHsvVw:c:d:l:", longopts, &option);
|
||||
|
||||
if (c == -1 || c == EOF || c == 1)
|
||||
if (option_index == -1 || option_index == EOF || option_index == 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (c) {
|
||||
|
||||
switch (option_index) {
|
||||
case 'h': /* host cluster */
|
||||
check_type = CHECK_HOSTS;
|
||||
result.config.check_type = CHECK_HOSTS;
|
||||
break;
|
||||
|
||||
case 's': /* service cluster */
|
||||
check_type = CHECK_SERVICES;
|
||||
result.config.check_type = CHECK_SERVICES;
|
||||
break;
|
||||
|
||||
case 'w': /* warning threshold */
|
||||
warn_threshold = strdup(optarg);
|
||||
break;
|
||||
|
||||
case 'c': /* warning threshold */
|
||||
crit_threshold = strdup(optarg);
|
||||
break;
|
||||
|
||||
case 'd': /* data values */
|
||||
data_vals = (char *)strdup(optarg);
|
||||
result.config.data_vals = strdup(optarg);
|
||||
/* validate data */
|
||||
for (ptr = data_vals; ptr != NULL; ptr += 2) {
|
||||
if (ptr[0] < '0' || ptr[0] > '3')
|
||||
return ERROR;
|
||||
if (ptr[1] == '\0')
|
||||
for (char *ptr = result.config.data_vals; ptr != NULL; ptr += 2) {
|
||||
if (ptr[0] < '0' || ptr[0] > '3') {
|
||||
result.errorcode = ERROR;
|
||||
return result;
|
||||
}
|
||||
if (ptr[1] == '\0') {
|
||||
break;
|
||||
if (ptr[1] != ',')
|
||||
return ERROR;
|
||||
}
|
||||
if (ptr[1] != ',') {
|
||||
result.errorcode = ERROR;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'l': /* text label */
|
||||
label = (char *)strdup(optarg);
|
||||
result.config.label = strdup(optarg);
|
||||
break;
|
||||
|
||||
case 'v': /* verbose */
|
||||
verbose++;
|
||||
break;
|
||||
|
||||
case 'V': /* version */
|
||||
print_revision(progname, NP_VERSION);
|
||||
exit(STATE_UNKNOWN);
|
||||
break;
|
||||
|
||||
case 'H': /* help */
|
||||
print_help();
|
||||
exit(STATE_UNKNOWN);
|
||||
break;
|
||||
|
||||
default:
|
||||
return ERROR;
|
||||
result.errorcode = ERROR;
|
||||
return result;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (data_vals == NULL)
|
||||
return ERROR;
|
||||
if (result.config.data_vals == NULL) {
|
||||
result.errorcode = ERROR;
|
||||
return result;
|
||||
}
|
||||
|
||||
return OK;
|
||||
set_thresholds(&result.config.thresholds, warn_threshold, crit_threshold);
|
||||
return result;
|
||||
}
|
||||
|
||||
void print_help(void) {
|
||||
|
|
|
|||
27
plugins/check_cluster.d/config.h
Normal file
27
plugins/check_cluster.d/config.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../config.h"
|
||||
#include "../../lib/thresholds.h"
|
||||
#include <stddef.h>
|
||||
|
||||
enum {
|
||||
CHECK_SERVICES = 1,
|
||||
CHECK_HOSTS = 2
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
char *data_vals;
|
||||
thresholds *thresholds;
|
||||
int check_type;
|
||||
char *label;
|
||||
} check_cluster_config;
|
||||
|
||||
check_cluster_config check_cluster_config_init() {
|
||||
check_cluster_config tmp = {
|
||||
.data_vals = NULL,
|
||||
.thresholds = NULL,
|
||||
.check_type = CHECK_SERVICES,
|
||||
.label = NULL,
|
||||
};
|
||||
return tmp;
|
||||
}
|
||||
|
|
@ -33,6 +33,8 @@ const char *progname = "check_dbi";
|
|||
const char *copyright = "2011-2024";
|
||||
const char *email = "devel@monitoring-plugins.org";
|
||||
|
||||
#include "../lib/monitoringplug.h"
|
||||
#include "check_dbi.d/config.h"
|
||||
#include "common.h"
|
||||
#include "utils.h"
|
||||
#include "utils_cmd.h"
|
||||
|
|
@ -53,55 +55,24 @@ const char *email = "devel@monitoring-plugins.org";
|
|||
|
||||
#include <stdarg.h>
|
||||
|
||||
typedef enum {
|
||||
METRIC_CONN_TIME,
|
||||
METRIC_SERVER_VERSION,
|
||||
METRIC_QUERY_RESULT,
|
||||
METRIC_QUERY_TIME,
|
||||
} np_dbi_metric_t;
|
||||
|
||||
typedef enum {
|
||||
TYPE_NUMERIC,
|
||||
TYPE_STRING,
|
||||
} np_dbi_type_t;
|
||||
|
||||
typedef struct {
|
||||
char *key;
|
||||
char *value;
|
||||
} driver_option_t;
|
||||
|
||||
static char *host = NULL;
|
||||
static int verbose = 0;
|
||||
|
||||
static char *warning_range = NULL;
|
||||
static char *critical_range = NULL;
|
||||
static thresholds *dbi_thresholds = NULL;
|
||||
typedef struct {
|
||||
int errorcode;
|
||||
check_dbi_config config;
|
||||
} check_dbi_config_wrapper;
|
||||
|
||||
static char *expect = NULL;
|
||||
|
||||
static regex_t expect_re;
|
||||
static char *expect_re_str = NULL;
|
||||
static int expect_re_cflags = 0;
|
||||
|
||||
static np_dbi_metric_t metric = METRIC_QUERY_RESULT;
|
||||
static np_dbi_type_t type = TYPE_NUMERIC;
|
||||
|
||||
static char *np_dbi_driver = NULL;
|
||||
static driver_option_t *np_dbi_options = NULL;
|
||||
static int np_dbi_options_num = 0;
|
||||
static char *np_dbi_database = NULL;
|
||||
static char *np_dbi_query = NULL;
|
||||
|
||||
static int process_arguments(int, char **);
|
||||
static int validate_arguments(void);
|
||||
static check_dbi_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
static check_dbi_config_wrapper validate_arguments(check_dbi_config_wrapper /*config_wrapper*/);
|
||||
void print_usage(void);
|
||||
static void print_help(void);
|
||||
|
||||
static double timediff(struct timeval, struct timeval);
|
||||
static double timediff(struct timeval /*start*/, struct timeval /*end*/);
|
||||
|
||||
static void np_dbi_print_error(dbi_conn, char *, ...);
|
||||
static void np_dbi_print_error(dbi_conn /*conn*/, char * /*fmt*/, ...);
|
||||
|
||||
static int do_query(dbi_conn, const char **, double *, double *);
|
||||
static mp_state_enum do_query(dbi_conn /*conn*/, const char ** /*res_val_str*/, double * /*res_val*/, double * /*res_time*/, mp_dbi_metric /*metric*/,
|
||||
mp_dbi_type /*type*/, char * /*np_dbi_query*/);
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int status = STATE_UNKNOWN;
|
||||
|
|
@ -119,8 +90,6 @@ int main(int argc, char **argv) {
|
|||
const char *query_val_str = NULL;
|
||||
double query_val = 0.0;
|
||||
|
||||
int i;
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
textdomain(PACKAGE);
|
||||
|
|
@ -128,8 +97,13 @@ int main(int argc, char **argv) {
|
|||
/* Parse extra opts if any */
|
||||
argv = np_extra_opts(&argc, argv, progname);
|
||||
|
||||
if (process_arguments(argc, argv) == ERROR)
|
||||
check_dbi_config_wrapper tmp = process_arguments(argc, argv);
|
||||
|
||||
if (tmp.errorcode == ERROR) {
|
||||
usage4(_("Could not parse arguments"));
|
||||
}
|
||||
|
||||
const check_dbi_config config = tmp.config;
|
||||
|
||||
/* Set signal handling and alarm */
|
||||
if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) {
|
||||
|
|
@ -137,8 +111,9 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
alarm(timeout_interval);
|
||||
|
||||
if (verbose > 2)
|
||||
if (verbose > 2) {
|
||||
printf("Initializing DBI\n");
|
||||
}
|
||||
|
||||
dbi_inst *instance_p = {0};
|
||||
|
||||
|
|
@ -152,12 +127,13 @@ int main(int argc, char **argv) {
|
|||
return STATE_UNKNOWN;
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
printf("Opening DBI driver '%s'\n", np_dbi_driver);
|
||||
if (verbose) {
|
||||
printf("Opening DBI driver '%s'\n", config.dbi_driver);
|
||||
}
|
||||
|
||||
driver = dbi_driver_open_r(np_dbi_driver, instance_p);
|
||||
driver = dbi_driver_open_r(config.dbi_driver, instance_p);
|
||||
if (!driver) {
|
||||
printf("UNKNOWN - failed to open DBI driver '%s'; possibly it's not installed.\n", np_dbi_driver);
|
||||
printf("UNKNOWN - failed to open DBI driver '%s'; possibly it's not installed.\n", config.dbi_driver);
|
||||
|
||||
printf("Known drivers:\n");
|
||||
for (driver = dbi_driver_list_r(NULL, instance_p); driver; driver = dbi_driver_list_r(driver, instance_p)) {
|
||||
|
|
@ -176,17 +152,19 @@ int main(int argc, char **argv) {
|
|||
return STATE_UNKNOWN;
|
||||
}
|
||||
|
||||
for (i = 0; i < np_dbi_options_num; ++i) {
|
||||
for (size_t i = 0; i < config.dbi_options_num; ++i) {
|
||||
const char *opt;
|
||||
|
||||
if (verbose > 1)
|
||||
printf("Setting DBI driver option '%s' to '%s'\n", np_dbi_options[i].key, np_dbi_options[i].value);
|
||||
if (verbose > 1) {
|
||||
printf("Setting DBI driver option '%s' to '%s'\n", config.dbi_options[i].key, config.dbi_options[i].value);
|
||||
}
|
||||
|
||||
if (!dbi_conn_set_option(conn, np_dbi_options[i].key, np_dbi_options[i].value))
|
||||
if (!dbi_conn_set_option(conn, config.dbi_options[i].key, config.dbi_options[i].value)) {
|
||||
continue;
|
||||
}
|
||||
/* else: status != 0 */
|
||||
|
||||
np_dbi_print_error(conn, "UNKNOWN - failed to set option '%s' to '%s'", np_dbi_options[i].key, np_dbi_options[i].value);
|
||||
np_dbi_print_error(conn, "UNKNOWN - failed to set option '%s' to '%s'", config.dbi_options[i].key, config.dbi_options[i].value);
|
||||
printf("Known driver options:\n");
|
||||
|
||||
for (opt = dbi_conn_get_option_list(conn, NULL); opt; opt = dbi_conn_get_option_list(conn, opt)) {
|
||||
|
|
@ -196,10 +174,11 @@ int main(int argc, char **argv) {
|
|||
return STATE_UNKNOWN;
|
||||
}
|
||||
|
||||
if (host) {
|
||||
if (verbose > 1)
|
||||
printf("Setting DBI driver option 'host' to '%s'\n", host);
|
||||
dbi_conn_set_option(conn, "host", host);
|
||||
if (config.host) {
|
||||
if (verbose > 1) {
|
||||
printf("Setting DBI driver option 'host' to '%s'\n", config.host);
|
||||
}
|
||||
dbi_conn_set_option(conn, "host", config.host);
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
|
|
@ -209,10 +188,12 @@ int main(int argc, char **argv) {
|
|||
dbname = dbi_conn_get_option(conn, "dbname");
|
||||
host = dbi_conn_get_option(conn, "host");
|
||||
|
||||
if (!dbname)
|
||||
if (!dbname) {
|
||||
dbname = "<unspecified>";
|
||||
if (!host)
|
||||
}
|
||||
if (!host) {
|
||||
host = "<unspecified>";
|
||||
}
|
||||
|
||||
printf("Connecting to database '%s' at host '%s'\n", dbname, host);
|
||||
}
|
||||
|
|
@ -226,109 +207,122 @@ int main(int argc, char **argv) {
|
|||
conn_time = timediff(start_timeval, end_timeval);
|
||||
|
||||
server_version = dbi_conn_get_engine_version(conn);
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
printf("Connected to server version %u\n", server_version);
|
||||
}
|
||||
|
||||
if (metric == METRIC_SERVER_VERSION)
|
||||
status = get_status(server_version, dbi_thresholds);
|
||||
if (config.metric == METRIC_SERVER_VERSION) {
|
||||
status = get_status(server_version, config.dbi_thresholds);
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
printf("Time elapsed: %f\n", conn_time);
|
||||
}
|
||||
|
||||
if (metric == METRIC_CONN_TIME)
|
||||
status = get_status(conn_time, dbi_thresholds);
|
||||
if (config.metric == METRIC_CONN_TIME) {
|
||||
status = get_status(conn_time, config.dbi_thresholds);
|
||||
}
|
||||
|
||||
/* select a database */
|
||||
if (np_dbi_database) {
|
||||
if (verbose > 1)
|
||||
printf("Selecting database '%s'\n", np_dbi_database);
|
||||
if (config.dbi_database) {
|
||||
if (verbose > 1) {
|
||||
printf("Selecting database '%s'\n", config.dbi_database);
|
||||
}
|
||||
|
||||
if (dbi_conn_select_db(conn, np_dbi_database)) {
|
||||
np_dbi_print_error(conn, "UNKNOWN - failed to select database '%s'", np_dbi_database);
|
||||
if (dbi_conn_select_db(conn, config.dbi_database)) {
|
||||
np_dbi_print_error(conn, "UNKNOWN - failed to select database '%s'", config.dbi_database);
|
||||
return STATE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
if (np_dbi_query) {
|
||||
if (config.dbi_query) {
|
||||
/* execute query */
|
||||
status = do_query(conn, &query_val_str, &query_val, &query_time);
|
||||
if (status != STATE_OK)
|
||||
status = do_query(conn, &query_val_str, &query_val, &query_time, config.metric, config.type, config.dbi_query);
|
||||
if (status != STATE_OK) {
|
||||
/* do_query prints an error message in this case */
|
||||
return status;
|
||||
}
|
||||
|
||||
if (metric == METRIC_QUERY_RESULT) {
|
||||
if (expect) {
|
||||
if ((!query_val_str) || strcmp(query_val_str, expect))
|
||||
if (config.metric == METRIC_QUERY_RESULT) {
|
||||
if (config.expect) {
|
||||
if ((!query_val_str) || strcmp(query_val_str, config.expect)) {
|
||||
status = STATE_CRITICAL;
|
||||
else
|
||||
} else {
|
||||
status = STATE_OK;
|
||||
} else if (expect_re_str) {
|
||||
}
|
||||
} else if (config.expect_re_str) {
|
||||
int err;
|
||||
|
||||
regex_t expect_re = {};
|
||||
err = regexec(&expect_re, query_val_str, 0, NULL, /* flags = */ 0);
|
||||
if (!err)
|
||||
if (!err) {
|
||||
status = STATE_OK;
|
||||
else if (err == REG_NOMATCH)
|
||||
} else if (err == REG_NOMATCH) {
|
||||
status = STATE_CRITICAL;
|
||||
else {
|
||||
} else {
|
||||
char errmsg[1024];
|
||||
regerror(err, &expect_re, errmsg, sizeof(errmsg));
|
||||
printf("ERROR - failed to execute regular expression: %s\n", errmsg);
|
||||
status = STATE_CRITICAL;
|
||||
}
|
||||
} else
|
||||
status = get_status(query_val, dbi_thresholds);
|
||||
} else if (metric == METRIC_QUERY_TIME)
|
||||
status = get_status(query_time, dbi_thresholds);
|
||||
} else {
|
||||
status = get_status(query_val, config.dbi_thresholds);
|
||||
}
|
||||
} else if (config.metric == METRIC_QUERY_TIME) {
|
||||
status = get_status(query_time, config.dbi_thresholds);
|
||||
}
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
printf("Closing connection\n");
|
||||
}
|
||||
dbi_conn_close(conn);
|
||||
|
||||
/* In case of METRIC_QUERY_RESULT, isnan(query_val) indicates an error
|
||||
* which should have been reported and handled (abort) before
|
||||
* ... unless we expected a string to be returned */
|
||||
assert((metric != METRIC_QUERY_RESULT) || (!isnan(query_val)) || (type == TYPE_STRING));
|
||||
assert((config.metric != METRIC_QUERY_RESULT) || (!isnan(query_val)) || (config.type == TYPE_STRING));
|
||||
|
||||
assert((type != TYPE_STRING) || (expect || expect_re_str));
|
||||
assert((config.type != TYPE_STRING) || (config.expect || config.expect_re_str));
|
||||
|
||||
printf("%s - connection time: %fs", state_text(status), conn_time);
|
||||
if (np_dbi_query) {
|
||||
if (type == TYPE_STRING) {
|
||||
assert(expect || expect_re_str);
|
||||
printf(", '%s' returned '%s' in %fs", np_dbi_query, query_val_str ? query_val_str : "<nothing>", query_time);
|
||||
if (config.dbi_query) {
|
||||
if (config.type == TYPE_STRING) {
|
||||
assert(config.expect || config.expect_re_str);
|
||||
printf(", '%s' returned '%s' in %fs", config.dbi_query, query_val_str ? query_val_str : "<nothing>", query_time);
|
||||
if (status != STATE_OK) {
|
||||
if (expect)
|
||||
printf(" (expected '%s')", expect);
|
||||
else if (expect_re_str)
|
||||
printf(" (expected regex /%s/%s)", expect_re_str, ((expect_re_cflags & REG_ICASE) ? "i" : ""));
|
||||
if (config.expect) {
|
||||
printf(" (expected '%s')", config.expect);
|
||||
} else if (config.expect_re_str) {
|
||||
printf(" (expected regex /%s/%s)", config.expect_re_str, ((config.expect_re_cflags & REG_ICASE) ? "i" : ""));
|
||||
}
|
||||
}
|
||||
} else if (isnan(query_val))
|
||||
printf(", '%s' query execution time: %fs", np_dbi_query, query_time);
|
||||
else
|
||||
printf(", '%s' returned %f in %fs", np_dbi_query, query_val, query_time);
|
||||
} else if (isnan(query_val)) {
|
||||
printf(", '%s' query execution time: %fs", config.dbi_query, query_time);
|
||||
} else {
|
||||
printf(", '%s' returned %f in %fs", config.dbi_query, query_val, query_time);
|
||||
}
|
||||
}
|
||||
|
||||
printf(" | conntime=%fs;%s;%s;0; server_version=%u;%s;%s;0;", conn_time,
|
||||
((metric == METRIC_CONN_TIME) && warning_range) ? warning_range : "",
|
||||
((metric == METRIC_CONN_TIME) && critical_range) ? critical_range : "", server_version,
|
||||
((metric == METRIC_SERVER_VERSION) && warning_range) ? warning_range : "",
|
||||
((metric == METRIC_SERVER_VERSION) && critical_range) ? critical_range : "");
|
||||
if (np_dbi_query) {
|
||||
if (!isnan(query_val)) /* this is also true when -e is used */
|
||||
printf(" query=%f;%s;%s;;", query_val, ((metric == METRIC_QUERY_RESULT) && warning_range) ? warning_range : "",
|
||||
((metric == METRIC_QUERY_RESULT) && critical_range) ? critical_range : "");
|
||||
printf(" querytime=%fs;%s;%s;0;", query_time, ((metric == METRIC_QUERY_TIME) && warning_range) ? warning_range : "",
|
||||
((metric == METRIC_QUERY_TIME) && critical_range) ? critical_range : "");
|
||||
((config.metric == METRIC_CONN_TIME) && config.warning_range) ? config.warning_range : "",
|
||||
((config.metric == METRIC_CONN_TIME) && config.critical_range) ? config.critical_range : "", server_version,
|
||||
((config.metric == METRIC_SERVER_VERSION) && config.warning_range) ? config.warning_range : "",
|
||||
((config.metric == METRIC_SERVER_VERSION) && config.critical_range) ? config.critical_range : "");
|
||||
if (config.dbi_query) {
|
||||
if (!isnan(query_val)) { /* this is also true when -e is used */
|
||||
printf(" query=%f;%s;%s;;", query_val, ((config.metric == METRIC_QUERY_RESULT) && config.warning_range) ? config.warning_range : "",
|
||||
((config.metric == METRIC_QUERY_RESULT) && config.critical_range) ? config.critical_range : "");
|
||||
}
|
||||
printf(" querytime=%fs;%s;%s;0;", query_time, ((config.metric == METRIC_QUERY_TIME) && config.warning_range) ? config.warning_range : "",
|
||||
((config.metric == METRIC_QUERY_TIME) && config.critical_range) ? config.critical_range : "");
|
||||
}
|
||||
printf("\n");
|
||||
return status;
|
||||
}
|
||||
|
||||
/* process command-line arguments */
|
||||
int process_arguments(int argc, char **argv) {
|
||||
int c;
|
||||
check_dbi_config_wrapper process_arguments(int argc, char **argv) {
|
||||
|
||||
int option = 0;
|
||||
static struct option longopts[] = {STD_LONG_OPTS,
|
||||
|
|
@ -343,13 +337,19 @@ int process_arguments(int argc, char **argv) {
|
|||
{"database", required_argument, 0, 'D'},
|
||||
{0, 0, 0, 0}};
|
||||
|
||||
while (1) {
|
||||
c = getopt_long(argc, argv, "Vvht:c:w:e:r:R:m:H:d:o:q:D:", longopts, &option);
|
||||
check_dbi_config_wrapper result = {
|
||||
.config = check_dbi_config_init(),
|
||||
.errorcode = OK,
|
||||
};
|
||||
int option_char;
|
||||
while (true) {
|
||||
option_char = getopt_long(argc, argv, "Vvht:c:w:e:r:R:m:H:d:o:q:D:", longopts, &option);
|
||||
|
||||
if (c == EOF)
|
||||
if (option_char == EOF) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (c) {
|
||||
switch (option_char) {
|
||||
case '?': /* usage */
|
||||
usage5();
|
||||
case 'h': /* help */
|
||||
|
|
@ -360,135 +360,148 @@ int process_arguments(int argc, char **argv) {
|
|||
exit(STATE_UNKNOWN);
|
||||
|
||||
case 'c': /* critical range */
|
||||
critical_range = optarg;
|
||||
type = TYPE_NUMERIC;
|
||||
result.config.critical_range = optarg;
|
||||
result.config.type = TYPE_NUMERIC;
|
||||
break;
|
||||
case 'w': /* warning range */
|
||||
warning_range = optarg;
|
||||
type = TYPE_NUMERIC;
|
||||
result.config.warning_range = optarg;
|
||||
result.config.type = TYPE_NUMERIC;
|
||||
break;
|
||||
case 'e':
|
||||
expect = optarg;
|
||||
type = TYPE_STRING;
|
||||
result.config.expect = optarg;
|
||||
result.config.type = TYPE_STRING;
|
||||
break;
|
||||
case 'R':
|
||||
expect_re_cflags = REG_ICASE;
|
||||
result.config.expect_re_cflags = REG_ICASE;
|
||||
/* fall through */
|
||||
case 'r': {
|
||||
int err;
|
||||
|
||||
expect_re_cflags |= REG_EXTENDED | REG_NOSUB | REG_NEWLINE;
|
||||
expect_re_str = optarg;
|
||||
type = TYPE_STRING;
|
||||
result.config.expect_re_cflags |= REG_EXTENDED | REG_NOSUB | REG_NEWLINE;
|
||||
result.config.expect_re_str = optarg;
|
||||
result.config.type = TYPE_STRING;
|
||||
|
||||
err = regcomp(&expect_re, expect_re_str, expect_re_cflags);
|
||||
regex_t expect_re = {};
|
||||
err = regcomp(&expect_re, result.config.expect_re_str, result.config.expect_re_cflags);
|
||||
if (err) {
|
||||
char errmsg[1024];
|
||||
regerror(err, &expect_re, errmsg, sizeof(errmsg));
|
||||
printf("ERROR - failed to compile regular expression: %s\n", errmsg);
|
||||
return ERROR;
|
||||
|
||||
result.errorcode = ERROR;
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'm':
|
||||
if (!strcasecmp(optarg, "CONN_TIME"))
|
||||
metric = METRIC_CONN_TIME;
|
||||
else if (!strcasecmp(optarg, "SERVER_VERSION"))
|
||||
metric = METRIC_SERVER_VERSION;
|
||||
else if (!strcasecmp(optarg, "QUERY_RESULT"))
|
||||
metric = METRIC_QUERY_RESULT;
|
||||
else if (!strcasecmp(optarg, "QUERY_TIME"))
|
||||
metric = METRIC_QUERY_TIME;
|
||||
else
|
||||
if (!strcasecmp(optarg, "CONN_TIME")) {
|
||||
result.config.metric = METRIC_CONN_TIME;
|
||||
} else if (!strcasecmp(optarg, "SERVER_VERSION")) {
|
||||
result.config.metric = METRIC_SERVER_VERSION;
|
||||
} else if (!strcasecmp(optarg, "QUERY_RESULT")) {
|
||||
result.config.metric = METRIC_QUERY_RESULT;
|
||||
} else if (!strcasecmp(optarg, "QUERY_TIME")) {
|
||||
result.config.metric = METRIC_QUERY_TIME;
|
||||
} else {
|
||||
usage2(_("Invalid metric"), optarg);
|
||||
}
|
||||
break;
|
||||
case 't': /* timeout */
|
||||
if (!is_intnonneg(optarg))
|
||||
if (!is_intnonneg(optarg)) {
|
||||
usage2(_("Timeout interval must be a positive integer"), optarg);
|
||||
else
|
||||
} else {
|
||||
timeout_interval = atoi(optarg);
|
||||
}
|
||||
|
||||
break;
|
||||
case 'H': /* host */
|
||||
if (!is_host(optarg))
|
||||
if (!is_host(optarg)) {
|
||||
usage2(_("Invalid hostname/address"), optarg);
|
||||
else
|
||||
host = optarg;
|
||||
} else {
|
||||
result.config.host = optarg;
|
||||
}
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
np_dbi_driver = optarg;
|
||||
result.config.dbi_driver = optarg;
|
||||
break;
|
||||
case 'o': {
|
||||
driver_option_t *new;
|
||||
driver_option_t *new = NULL;
|
||||
|
||||
char *k;
|
||||
char *v;
|
||||
char *key = optarg;
|
||||
char *value = strchr(key, '=');
|
||||
|
||||
k = optarg;
|
||||
v = strchr(k, (int)'=');
|
||||
|
||||
if (!v)
|
||||
if (!value) {
|
||||
usage2(_("Option must be '<key>=<value>'"), optarg);
|
||||
}
|
||||
|
||||
*v = '\0';
|
||||
++v;
|
||||
*value = '\0';
|
||||
++value;
|
||||
|
||||
new = realloc(np_dbi_options, (np_dbi_options_num + 1) * sizeof(*new));
|
||||
new = realloc(result.config.dbi_options, (result.config.dbi_options_num + 1) * sizeof(*new));
|
||||
if (!new) {
|
||||
printf("UNKNOWN - failed to reallocate memory\n");
|
||||
exit(STATE_UNKNOWN);
|
||||
}
|
||||
|
||||
np_dbi_options = new;
|
||||
new = np_dbi_options + np_dbi_options_num;
|
||||
++np_dbi_options_num;
|
||||
result.config.dbi_options = new;
|
||||
new = result.config.dbi_options + result.config.dbi_options_num;
|
||||
result.config.dbi_options_num++;
|
||||
|
||||
new->key = k;
|
||||
new->value = v;
|
||||
new->key = key;
|
||||
new->value = value;
|
||||
} break;
|
||||
case 'q':
|
||||
np_dbi_query = optarg;
|
||||
result.config.dbi_query = optarg;
|
||||
break;
|
||||
case 'D':
|
||||
np_dbi_database = optarg;
|
||||
result.config.dbi_database = optarg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
set_thresholds(&dbi_thresholds, warning_range, critical_range);
|
||||
set_thresholds(&result.config.dbi_thresholds, result.config.warning_range, result.config.critical_range);
|
||||
|
||||
return validate_arguments();
|
||||
return validate_arguments(result);
|
||||
}
|
||||
|
||||
int validate_arguments(void) {
|
||||
if (!np_dbi_driver)
|
||||
check_dbi_config_wrapper validate_arguments(check_dbi_config_wrapper config_wrapper) {
|
||||
if (!config_wrapper.config.dbi_driver) {
|
||||
usage("Must specify a DBI driver");
|
||||
}
|
||||
|
||||
if (((metric == METRIC_QUERY_RESULT) || (metric == METRIC_QUERY_TIME)) && (!np_dbi_query))
|
||||
if (((config_wrapper.config.metric == METRIC_QUERY_RESULT) || (config_wrapper.config.metric == METRIC_QUERY_TIME)) &&
|
||||
(!config_wrapper.config.dbi_query)) {
|
||||
usage("Must specify a query to execute (metric == QUERY_RESULT)");
|
||||
}
|
||||
|
||||
if ((metric != METRIC_CONN_TIME) && (metric != METRIC_SERVER_VERSION) && (metric != METRIC_QUERY_RESULT) &&
|
||||
(metric != METRIC_QUERY_TIME))
|
||||
if ((config_wrapper.config.metric != METRIC_CONN_TIME) && (config_wrapper.config.metric != METRIC_SERVER_VERSION) &&
|
||||
(config_wrapper.config.metric != METRIC_QUERY_RESULT) && (config_wrapper.config.metric != METRIC_QUERY_TIME)) {
|
||||
usage("Invalid metric specified");
|
||||
}
|
||||
|
||||
if (expect && (warning_range || critical_range || expect_re_str))
|
||||
if (config_wrapper.config.expect && (config_wrapper.config.warning_range || config_wrapper.config.critical_range || config_wrapper.config.expect_re_str)) {
|
||||
usage("Do not mix -e and -w/-c/-r/-R");
|
||||
}
|
||||
|
||||
if (expect_re_str && (warning_range || critical_range || expect))
|
||||
if (config_wrapper.config.expect_re_str && (config_wrapper.config.warning_range || config_wrapper.config.critical_range || config_wrapper.config.expect)) {
|
||||
usage("Do not mix -r/-R and -w/-c/-e");
|
||||
}
|
||||
|
||||
if (expect && (metric != METRIC_QUERY_RESULT))
|
||||
if (config_wrapper.config.expect && (config_wrapper.config.metric != METRIC_QUERY_RESULT)) {
|
||||
usage("Option -e requires metric QUERY_RESULT");
|
||||
}
|
||||
|
||||
if (expect_re_str && (metric != METRIC_QUERY_RESULT))
|
||||
if (config_wrapper.config.expect_re_str && (config_wrapper.config.metric != METRIC_QUERY_RESULT)) {
|
||||
usage("Options -r/-R require metric QUERY_RESULT");
|
||||
}
|
||||
|
||||
return OK;
|
||||
config_wrapper.errorcode = OK;
|
||||
return config_wrapper;
|
||||
}
|
||||
|
||||
void print_help(void) {
|
||||
|
|
@ -518,6 +531,8 @@ void print_help(void) {
|
|||
printf(" %s\n", _("DBI driver options"));
|
||||
printf(" %s\n", "-q, --query=STRING");
|
||||
printf(" %s\n", _("query to execute"));
|
||||
printf(" %s\n", "-H STRING");
|
||||
printf(" %s\n", _("target database host"));
|
||||
printf("\n");
|
||||
|
||||
printf(UT_WARN_CRIT_RANGE);
|
||||
|
|
@ -592,13 +607,7 @@ void print_usage(void) {
|
|||
printf(" [-e <string>] [-r|-R <regex>]\n");
|
||||
}
|
||||
|
||||
#define CHECK_IGNORE_ERROR(s) \
|
||||
do { \
|
||||
if (metric != METRIC_QUERY_RESULT) \
|
||||
return (s); \
|
||||
} while (0)
|
||||
|
||||
const char *get_field_str(dbi_conn conn, dbi_result res, unsigned short field_type) {
|
||||
const char *get_field_str(dbi_conn conn, dbi_result res, unsigned short field_type, mp_dbi_metric metric, mp_dbi_type type) {
|
||||
const char *str;
|
||||
|
||||
if (field_type != DBI_TYPE_STRING) {
|
||||
|
|
@ -608,17 +617,20 @@ const char *get_field_str(dbi_conn conn, dbi_result res, unsigned short field_ty
|
|||
|
||||
str = dbi_result_get_string_idx(res, 1);
|
||||
if ((!str) || (strcmp(str, "ERROR") == 0)) {
|
||||
CHECK_IGNORE_ERROR(NULL);
|
||||
if (metric != METRIC_QUERY_RESULT) {
|
||||
return NULL;
|
||||
}
|
||||
np_dbi_print_error(conn, "CRITICAL - failed to fetch string value");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((verbose && (type == TYPE_STRING)) || (verbose > 2))
|
||||
if ((verbose && (type == TYPE_STRING)) || (verbose > 2)) {
|
||||
printf("Query returned string '%s'\n", str);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
double get_field(dbi_conn conn, dbi_result res, unsigned short *field_type) {
|
||||
double get_field(dbi_conn conn, dbi_result res, unsigned short *field_type, mp_dbi_metric metric, mp_dbi_type type) {
|
||||
double val = NAN;
|
||||
|
||||
if (*field_type == DBI_TYPE_INTEGER) {
|
||||
|
|
@ -629,26 +641,33 @@ double get_field(dbi_conn conn, dbi_result res, unsigned short *field_type) {
|
|||
const char *val_str;
|
||||
char *endptr = NULL;
|
||||
|
||||
val_str = get_field_str(conn, res, *field_type);
|
||||
val_str = get_field_str(conn, res, *field_type, metric, type);
|
||||
if (!val_str) {
|
||||
CHECK_IGNORE_ERROR(NAN);
|
||||
if (metric != METRIC_QUERY_RESULT) {
|
||||
return NAN;
|
||||
}
|
||||
*field_type = DBI_TYPE_ERROR;
|
||||
return NAN;
|
||||
}
|
||||
|
||||
val = strtod(val_str, &endptr);
|
||||
if (endptr == val_str) {
|
||||
CHECK_IGNORE_ERROR(NAN);
|
||||
if (metric != METRIC_QUERY_RESULT) {
|
||||
return NAN;
|
||||
}
|
||||
printf("CRITICAL - result value is not a numeric: %s\n", val_str);
|
||||
*field_type = DBI_TYPE_ERROR;
|
||||
return NAN;
|
||||
}
|
||||
if ((endptr != NULL) && (*endptr != '\0')) {
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
printf("Garbage after value: %s\n", endptr);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
CHECK_IGNORE_ERROR(NAN);
|
||||
if (metric != METRIC_QUERY_RESULT) {
|
||||
return NAN;
|
||||
}
|
||||
printf("CRITICAL - cannot parse value of type %s (%i)\n",
|
||||
(*field_type == DBI_TYPE_BINARY) ? "BINARY"
|
||||
: (*field_type == DBI_TYPE_DATETIME) ? "DATETIME"
|
||||
|
|
@ -660,53 +679,66 @@ double get_field(dbi_conn conn, dbi_result res, unsigned short *field_type) {
|
|||
return val;
|
||||
}
|
||||
|
||||
double get_query_result(dbi_conn conn, dbi_result res, const char **res_val_str, double *res_val) {
|
||||
mp_state_enum get_query_result(dbi_conn conn, dbi_result res, const char **res_val_str, double *res_val, mp_dbi_metric metric, mp_dbi_type type) {
|
||||
unsigned short field_type;
|
||||
double val = NAN;
|
||||
|
||||
if (dbi_result_get_numrows(res) == DBI_ROW_ERROR) {
|
||||
CHECK_IGNORE_ERROR(STATE_OK);
|
||||
if (metric != METRIC_QUERY_RESULT) {
|
||||
return STATE_OK;
|
||||
}
|
||||
np_dbi_print_error(conn, "CRITICAL - failed to fetch rows");
|
||||
return STATE_CRITICAL;
|
||||
}
|
||||
|
||||
if (dbi_result_get_numrows(res) < 1) {
|
||||
CHECK_IGNORE_ERROR(STATE_OK);
|
||||
if (metric != METRIC_QUERY_RESULT) {
|
||||
return STATE_OK;
|
||||
}
|
||||
printf("WARNING - no rows returned\n");
|
||||
return STATE_WARNING;
|
||||
}
|
||||
|
||||
if (dbi_result_get_numfields(res) == DBI_FIELD_ERROR) {
|
||||
CHECK_IGNORE_ERROR(STATE_OK);
|
||||
if (metric != METRIC_QUERY_RESULT) {
|
||||
return STATE_OK;
|
||||
}
|
||||
np_dbi_print_error(conn, "CRITICAL - failed to fetch fields");
|
||||
return STATE_CRITICAL;
|
||||
}
|
||||
|
||||
if (dbi_result_get_numfields(res) < 1) {
|
||||
CHECK_IGNORE_ERROR(STATE_OK);
|
||||
if (metric != METRIC_QUERY_RESULT) {
|
||||
return STATE_OK;
|
||||
}
|
||||
printf("WARNING - no fields returned\n");
|
||||
return STATE_WARNING;
|
||||
}
|
||||
|
||||
if (dbi_result_first_row(res) != 1) {
|
||||
CHECK_IGNORE_ERROR(STATE_OK);
|
||||
if (metric != METRIC_QUERY_RESULT) {
|
||||
return STATE_OK;
|
||||
}
|
||||
np_dbi_print_error(conn, "CRITICAL - failed to fetch first row");
|
||||
return STATE_CRITICAL;
|
||||
}
|
||||
|
||||
field_type = dbi_result_get_field_type_idx(res, 1);
|
||||
if (field_type != DBI_TYPE_ERROR) {
|
||||
if (type == TYPE_STRING)
|
||||
if (type == TYPE_STRING) {
|
||||
/* the value will be freed in dbi_result_free */
|
||||
*res_val_str = strdup(get_field_str(conn, res, field_type));
|
||||
else
|
||||
val = get_field(conn, res, &field_type);
|
||||
*res_val_str = strdup(get_field_str(conn, res, field_type, metric, type));
|
||||
} else {
|
||||
val = get_field(conn, res, &field_type, metric, type);
|
||||
}
|
||||
}
|
||||
|
||||
*res_val = val;
|
||||
|
||||
if (field_type == DBI_TYPE_ERROR) {
|
||||
CHECK_IGNORE_ERROR(STATE_OK);
|
||||
if (metric != METRIC_QUERY_RESULT) {
|
||||
return STATE_OK;
|
||||
}
|
||||
np_dbi_print_error(conn, "CRITICAL - failed to fetch data");
|
||||
return STATE_CRITICAL;
|
||||
}
|
||||
|
|
@ -715,19 +747,19 @@ double get_query_result(dbi_conn conn, dbi_result res, const char **res_val_str,
|
|||
return STATE_OK;
|
||||
}
|
||||
|
||||
#undef CHECK_IGNORE_ERROR
|
||||
|
||||
int do_query(dbi_conn conn, const char **res_val_str, double *res_val, double *res_time) {
|
||||
mp_state_enum do_query(dbi_conn conn, const char **res_val_str, double *res_val, double *res_time, mp_dbi_metric metric, mp_dbi_type type,
|
||||
char *np_dbi_query) {
|
||||
dbi_result res;
|
||||
|
||||
struct timeval timeval_start;
|
||||
struct timeval timeval_end;
|
||||
int status = STATE_OK;
|
||||
mp_state_enum status = STATE_OK;
|
||||
|
||||
assert(np_dbi_query);
|
||||
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
printf("Executing query '%s'\n", np_dbi_query);
|
||||
}
|
||||
|
||||
gettimeofday(&timeval_start, NULL);
|
||||
|
||||
|
|
@ -737,13 +769,14 @@ int do_query(dbi_conn conn, const char **res_val_str, double *res_val, double *r
|
|||
return STATE_CRITICAL;
|
||||
}
|
||||
|
||||
status = get_query_result(conn, res, res_val_str, res_val);
|
||||
status = get_query_result(conn, res, res_val_str, res_val, metric, type);
|
||||
|
||||
gettimeofday(&timeval_end, NULL);
|
||||
*res_time = timediff(timeval_start, timeval_end);
|
||||
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
printf("Time elapsed: %f\n", *res_time);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
|
|
|||
63
plugins/check_dbi.d/config.h
Normal file
63
plugins/check_dbi.d/config.h
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../config.h"
|
||||
#include <stddef.h>
|
||||
#include "../../lib/monitoringplug.h"
|
||||
|
||||
typedef enum {
|
||||
METRIC_CONN_TIME,
|
||||
METRIC_SERVER_VERSION,
|
||||
METRIC_QUERY_RESULT,
|
||||
METRIC_QUERY_TIME,
|
||||
} mp_dbi_metric;
|
||||
|
||||
typedef enum {
|
||||
TYPE_NUMERIC,
|
||||
TYPE_STRING,
|
||||
} mp_dbi_type;
|
||||
|
||||
typedef struct {
|
||||
char *key;
|
||||
char *value;
|
||||
} driver_option_t;
|
||||
|
||||
typedef struct {
|
||||
char *dbi_driver;
|
||||
char *host;
|
||||
driver_option_t *dbi_options;
|
||||
size_t dbi_options_num;
|
||||
char *dbi_database;
|
||||
char *dbi_query;
|
||||
|
||||
char *expect;
|
||||
char *expect_re_str;
|
||||
int expect_re_cflags;
|
||||
mp_dbi_metric metric;
|
||||
mp_dbi_type type;
|
||||
char *warning_range;
|
||||
char *critical_range;
|
||||
thresholds *dbi_thresholds;
|
||||
|
||||
} check_dbi_config;
|
||||
|
||||
check_dbi_config check_dbi_config_init() {
|
||||
check_dbi_config tmp = {
|
||||
.dbi_driver = NULL,
|
||||
.host = NULL,
|
||||
.dbi_options = NULL,
|
||||
.dbi_options_num = 0,
|
||||
.dbi_database = NULL,
|
||||
.dbi_query = NULL,
|
||||
|
||||
.expect = NULL,
|
||||
.expect_re_str = NULL,
|
||||
.expect_re_cflags = 0,
|
||||
.metric = METRIC_QUERY_RESULT,
|
||||
.type = TYPE_NUMERIC,
|
||||
|
||||
.warning_range = NULL,
|
||||
.critical_range = NULL,
|
||||
.dbi_thresholds = NULL,
|
||||
};
|
||||
return tmp;
|
||||
}
|
||||
|
|
@ -41,97 +41,93 @@ const char *email = "devel@monitoring-plugins.org";
|
|||
#include "utils.h"
|
||||
#include "runcmd.h"
|
||||
|
||||
static int process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
static int validate_arguments(void);
|
||||
#include "check_dig.d/config.h"
|
||||
#include "states.h"
|
||||
|
||||
typedef struct {
|
||||
int errorcode;
|
||||
check_dig_config config;
|
||||
} check_dig_config_wrapper;
|
||||
static check_dig_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
static check_dig_config_wrapper validate_arguments(check_dig_config_wrapper /*config_wrapper*/);
|
||||
|
||||
static void print_help(void);
|
||||
void print_usage(void);
|
||||
|
||||
#define UNDEFINED 0
|
||||
#define DEFAULT_PORT 53
|
||||
#define DEFAULT_TRIES 2
|
||||
|
||||
static char *query_address = NULL;
|
||||
static char *record_type = "A";
|
||||
static char *expected_address = NULL;
|
||||
static char *dns_server = NULL;
|
||||
static char *dig_args = "";
|
||||
static char *query_transport = "";
|
||||
static bool verbose = false;
|
||||
static int server_port = DEFAULT_PORT;
|
||||
static int number_tries = DEFAULT_TRIES;
|
||||
static double warning_interval = UNDEFINED;
|
||||
static double critical_interval = UNDEFINED;
|
||||
static struct timeval tv;
|
||||
static int verbose = 0;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
char *command_line;
|
||||
output chld_out;
|
||||
output chld_err;
|
||||
char *msg = NULL;
|
||||
size_t i;
|
||||
char *t;
|
||||
long microsec;
|
||||
double elapsed_time;
|
||||
int result = STATE_UNKNOWN;
|
||||
int timeout_interval_dig;
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
textdomain(PACKAGE);
|
||||
|
||||
/* Set signal handling and alarm */
|
||||
if (signal(SIGALRM, runcmd_timeout_alarm_handler) == SIG_ERR)
|
||||
if (signal(SIGALRM, runcmd_timeout_alarm_handler) == SIG_ERR) {
|
||||
usage_va(_("Cannot catch SIGALRM"));
|
||||
}
|
||||
|
||||
/* Parse extra opts if any */
|
||||
argv = np_extra_opts(&argc, argv, progname);
|
||||
|
||||
if (process_arguments(argc, argv) == ERROR)
|
||||
check_dig_config_wrapper tmp_config = process_arguments(argc, argv);
|
||||
if (tmp_config.errorcode == ERROR) {
|
||||
usage_va(_("Could not parse arguments"));
|
||||
}
|
||||
|
||||
const check_dig_config config = tmp_config.config;
|
||||
|
||||
/* dig applies the timeout to each try, so we need to work around this */
|
||||
timeout_interval_dig = timeout_interval / number_tries + number_tries;
|
||||
int timeout_interval_dig = ((int)timeout_interval / config.number_tries) + config.number_tries;
|
||||
|
||||
char *command_line;
|
||||
/* get the command to run */
|
||||
xasprintf(&command_line, "%s %s %s -p %d @%s %s %s +retry=%d +time=%d", PATH_TO_DIG, dig_args, query_transport, server_port, dns_server,
|
||||
query_address, record_type, number_tries, timeout_interval_dig);
|
||||
xasprintf(&command_line, "%s %s %s -p %d @%s %s %s +retry=%d +time=%d", PATH_TO_DIG, config.dig_args, config.query_transport,
|
||||
config.server_port, config.dns_server, config.query_address, config.record_type, config.number_tries, timeout_interval_dig);
|
||||
|
||||
alarm(timeout_interval);
|
||||
gettimeofday(&tv, NULL);
|
||||
struct timeval start_time;
|
||||
gettimeofday(&start_time, NULL);
|
||||
|
||||
if (verbose) {
|
||||
printf("%s\n", command_line);
|
||||
if (expected_address != NULL) {
|
||||
printf(_("Looking for: '%s'\n"), expected_address);
|
||||
if (config.expected_address != NULL) {
|
||||
printf(_("Looking for: '%s'\n"), config.expected_address);
|
||||
} else {
|
||||
printf(_("Looking for: '%s'\n"), query_address);
|
||||
printf(_("Looking for: '%s'\n"), config.query_address);
|
||||
}
|
||||
}
|
||||
|
||||
output chld_out;
|
||||
output chld_err;
|
||||
char *msg = NULL;
|
||||
mp_state_enum result = STATE_UNKNOWN;
|
||||
/* run the command */
|
||||
if (np_runcmd(command_line, &chld_out, &chld_err, 0) != 0) {
|
||||
result = STATE_WARNING;
|
||||
msg = (char *)_("dig returned an error status");
|
||||
}
|
||||
|
||||
for (i = 0; i < chld_out.lines; i++) {
|
||||
for (size_t i = 0; i < chld_out.lines; i++) {
|
||||
/* the server is responding, we just got the host name... */
|
||||
if (strstr(chld_out.line[i], ";; ANSWER SECTION:")) {
|
||||
|
||||
/* loop through the whole 'ANSWER SECTION' */
|
||||
for (; i < chld_out.lines; i++) {
|
||||
/* get the host address */
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
printf("%s\n", chld_out.line[i]);
|
||||
}
|
||||
|
||||
if (strcasestr(chld_out.line[i], (expected_address == NULL ? query_address : expected_address)) != NULL) {
|
||||
if (strcasestr(chld_out.line[i], (config.expected_address == NULL ? config.query_address : config.expected_address)) !=
|
||||
NULL) {
|
||||
msg = chld_out.line[i];
|
||||
result = STATE_OK;
|
||||
|
||||
/* Translate output TAB -> SPACE */
|
||||
t = msg;
|
||||
while ((t = strchr(t, '\t')) != NULL)
|
||||
*t = ' ';
|
||||
char *temp = msg;
|
||||
while ((temp = strchr(temp, '\t')) != NULL) {
|
||||
*temp = ' ';
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -154,37 +150,37 @@ int main(int argc, char **argv) {
|
|||
/* If we get anything on STDERR, at least set warning */
|
||||
if (chld_err.buflen > 0) {
|
||||
result = max_state(result, STATE_WARNING);
|
||||
if (!msg)
|
||||
for (i = 0; i < chld_err.lines; i++) {
|
||||
if (!msg) {
|
||||
for (size_t i = 0; i < chld_err.lines; i++) {
|
||||
msg = strchr(chld_err.line[0], ':');
|
||||
if (msg) {
|
||||
msg++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
microsec = deltime(tv);
|
||||
elapsed_time = (double)microsec / 1.0e6;
|
||||
long microsec = deltime(start_time);
|
||||
double elapsed_time = (double)microsec / 1.0e6;
|
||||
|
||||
if (critical_interval > UNDEFINED && elapsed_time > critical_interval)
|
||||
if (config.critical_interval > UNDEFINED && elapsed_time > config.critical_interval) {
|
||||
result = STATE_CRITICAL;
|
||||
}
|
||||
|
||||
else if (warning_interval > UNDEFINED && elapsed_time > warning_interval)
|
||||
else if (config.warning_interval > UNDEFINED && elapsed_time > config.warning_interval) {
|
||||
result = STATE_WARNING;
|
||||
}
|
||||
|
||||
printf("DNS %s - %.3f seconds response time (%s)|%s\n", state_text(result), elapsed_time,
|
||||
msg ? msg : _("Probably a non-existent host/domain"),
|
||||
fperfdata("time", elapsed_time, "s", (warning_interval > UNDEFINED ? true : false), warning_interval,
|
||||
(critical_interval > UNDEFINED ? true : false), critical_interval, true, 0, false, 0));
|
||||
return result;
|
||||
fperfdata("time", elapsed_time, "s", (config.warning_interval > UNDEFINED), config.warning_interval,
|
||||
(config.critical_interval > UNDEFINED), config.critical_interval, true, 0, false, 0));
|
||||
exit(result);
|
||||
}
|
||||
|
||||
/* process command-line arguments */
|
||||
int process_arguments(int argc, char **argv) {
|
||||
int c;
|
||||
|
||||
int option = 0;
|
||||
check_dig_config_wrapper process_arguments(int argc, char **argv) {
|
||||
static struct option longopts[] = {{"hostname", required_argument, 0, 'H'},
|
||||
{"query_address", required_argument, 0, 'l'},
|
||||
{"warning", required_argument, 0, 'w'},
|
||||
|
|
@ -201,16 +197,25 @@ int process_arguments(int argc, char **argv) {
|
|||
{"use-ipv6", no_argument, 0, '6'},
|
||||
{0, 0, 0, 0}};
|
||||
|
||||
if (argc < 2)
|
||||
return ERROR;
|
||||
check_dig_config_wrapper result = {
|
||||
.errorcode = OK,
|
||||
.config = check_dig_config_init(),
|
||||
};
|
||||
|
||||
while (1) {
|
||||
c = getopt_long(argc, argv, "hVvt:l:H:w:c:T:p:a:A:46", longopts, &option);
|
||||
if (argc < 2) {
|
||||
result.errorcode = ERROR;
|
||||
return result;
|
||||
}
|
||||
|
||||
if (c == -1 || c == EOF)
|
||||
int option = 0;
|
||||
while (true) {
|
||||
int option_index = getopt_long(argc, argv, "hVvt:l:H:w:c:T:p:a:A:46", longopts, &option);
|
||||
|
||||
if (option_index == -1 || option_index == EOF) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (c) {
|
||||
switch (option_index) {
|
||||
case 'h': /* help */
|
||||
print_help();
|
||||
exit(STATE_UNKNOWN);
|
||||
|
|
@ -219,28 +224,28 @@ int process_arguments(int argc, char **argv) {
|
|||
exit(STATE_UNKNOWN);
|
||||
case 'H': /* hostname */
|
||||
host_or_die(optarg);
|
||||
dns_server = optarg;
|
||||
result.config.dns_server = optarg;
|
||||
break;
|
||||
case 'p': /* server port */
|
||||
if (is_intpos(optarg)) {
|
||||
server_port = atoi(optarg);
|
||||
result.config.server_port = atoi(optarg);
|
||||
} else {
|
||||
usage_va(_("Port must be a positive integer - %s"), optarg);
|
||||
}
|
||||
break;
|
||||
case 'l': /* address to lookup */
|
||||
query_address = optarg;
|
||||
result.config.query_address = optarg;
|
||||
break;
|
||||
case 'w': /* warning */
|
||||
if (is_nonnegative(optarg)) {
|
||||
warning_interval = strtod(optarg, NULL);
|
||||
result.config.warning_interval = strtod(optarg, NULL);
|
||||
} else {
|
||||
usage_va(_("Warning interval must be a positive integer - %s"), optarg);
|
||||
}
|
||||
break;
|
||||
case 'c': /* critical */
|
||||
if (is_nonnegative(optarg)) {
|
||||
critical_interval = strtod(optarg, NULL);
|
||||
result.config.critical_interval = strtod(optarg, NULL);
|
||||
} else {
|
||||
usage_va(_("Critical interval must be a positive integer - %s"), optarg);
|
||||
}
|
||||
|
|
@ -253,48 +258,50 @@ int process_arguments(int argc, char **argv) {
|
|||
}
|
||||
break;
|
||||
case 'A': /* dig arguments */
|
||||
dig_args = strdup(optarg);
|
||||
result.config.dig_args = strdup(optarg);
|
||||
break;
|
||||
case 'v': /* verbose */
|
||||
verbose = true;
|
||||
verbose++;
|
||||
break;
|
||||
case 'T':
|
||||
record_type = optarg;
|
||||
result.config.record_type = optarg;
|
||||
break;
|
||||
case 'a':
|
||||
expected_address = optarg;
|
||||
result.config.expected_address = optarg;
|
||||
break;
|
||||
case '4':
|
||||
query_transport = "-4";
|
||||
result.config.query_transport = "-4";
|
||||
break;
|
||||
case '6':
|
||||
query_transport = "-6";
|
||||
result.config.query_transport = "-6";
|
||||
break;
|
||||
default: /* usage5 */
|
||||
usage5();
|
||||
}
|
||||
}
|
||||
|
||||
c = optind;
|
||||
if (dns_server == NULL) {
|
||||
if (c < argc) {
|
||||
host_or_die(argv[c]);
|
||||
dns_server = argv[c];
|
||||
int index = optind;
|
||||
if (result.config.dns_server == NULL) {
|
||||
if (index < argc) {
|
||||
host_or_die(argv[index]);
|
||||
result.config.dns_server = argv[index];
|
||||
} else {
|
||||
if (strcmp(query_transport, "-6") == 0)
|
||||
dns_server = strdup("::1");
|
||||
else
|
||||
dns_server = strdup("127.0.0.1");
|
||||
if (strcmp(result.config.query_transport, "-6") == 0) {
|
||||
result.config.dns_server = strdup("::1");
|
||||
} else {
|
||||
result.config.dns_server = strdup("127.0.0.1");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return validate_arguments();
|
||||
return validate_arguments(result);
|
||||
}
|
||||
|
||||
int validate_arguments(void) {
|
||||
if (query_address != NULL)
|
||||
return OK;
|
||||
return ERROR;
|
||||
check_dig_config_wrapper validate_arguments(check_dig_config_wrapper config_wrapper) {
|
||||
if (config_wrapper.config.query_address == NULL) {
|
||||
config_wrapper.errorcode = ERROR;
|
||||
}
|
||||
return config_wrapper;
|
||||
}
|
||||
|
||||
void print_help(void) {
|
||||
|
|
|
|||
40
plugins/check_dig.d/config.h
Normal file
40
plugins/check_dig.d/config.h
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../config.h"
|
||||
#include <stddef.h>
|
||||
|
||||
#define UNDEFINED 0
|
||||
#define DEFAULT_PORT 53
|
||||
#define DEFAULT_TRIES 2
|
||||
|
||||
typedef struct {
|
||||
char *query_address;
|
||||
char *record_type;
|
||||
char *expected_address;
|
||||
char *dns_server;
|
||||
char *query_transport;
|
||||
int server_port;
|
||||
char *dig_args;
|
||||
int number_tries;
|
||||
|
||||
double warning_interval;
|
||||
double critical_interval;
|
||||
} check_dig_config;
|
||||
|
||||
check_dig_config check_dig_config_init() {
|
||||
check_dig_config tmp = {
|
||||
.query_address = NULL,
|
||||
.record_type = "A",
|
||||
.expected_address = NULL,
|
||||
.dns_server = NULL,
|
||||
.query_transport = "",
|
||||
.server_port = DEFAULT_PORT,
|
||||
.dig_args = "",
|
||||
.number_tries = DEFAULT_TRIES,
|
||||
|
||||
.warning_interval = UNDEFINED,
|
||||
.critical_interval = UNDEFINED,
|
||||
|
||||
};
|
||||
return tmp;
|
||||
}
|
||||
|
|
@ -39,26 +39,22 @@ const char *email = "devel@monitoring-plugins.org";
|
|||
#include "netutils.h"
|
||||
#include "runcmd.h"
|
||||
|
||||
static int process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
static int validate_arguments(void);
|
||||
static int error_scan(char * /*input_buffer*/, bool *);
|
||||
#include "states.h"
|
||||
#include "check_dns.d/config.h"
|
||||
|
||||
typedef struct {
|
||||
int errorcode;
|
||||
check_dns_config config;
|
||||
} check_dns_config_wrapper;
|
||||
static check_dns_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
static check_dns_config_wrapper validate_arguments(check_dns_config_wrapper /*config_wrapper*/);
|
||||
static mp_state_enum error_scan(char * /*input_buffer*/, bool * /*is_nxdomain*/, const char /*dns_server*/[ADDRESS_LENGTH]);
|
||||
static bool ip_match_cidr(const char * /*addr*/, const char * /*cidr_ro*/);
|
||||
static unsigned long ip2long(const char * /*src*/);
|
||||
static void print_help(void);
|
||||
void print_usage(void);
|
||||
|
||||
#define ADDRESS_LENGTH 256
|
||||
static char query_address[ADDRESS_LENGTH] = "";
|
||||
static char dns_server[ADDRESS_LENGTH] = "";
|
||||
static char ptr_server[ADDRESS_LENGTH] = "";
|
||||
static bool verbose = false;
|
||||
static char **expected_address = NULL;
|
||||
static int expected_address_cnt = 0;
|
||||
static bool expect_nxdomain = false;
|
||||
|
||||
static bool expect_authority = false;
|
||||
static bool all_match = false;
|
||||
static thresholds *time_thresholds = NULL;
|
||||
|
||||
static int qstrcmp(const void *p1, const void *p2) {
|
||||
/* The actual arguments to this function are "pointers to
|
||||
|
|
@ -68,23 +64,6 @@ static int qstrcmp(const void *p1, const void *p2) {
|
|||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
char *command_line = NULL;
|
||||
char input_buffer[MAX_INPUT_BUFFER];
|
||||
char *address = NULL; /* comma separated str with addrs/ptrs (sorted) */
|
||||
char **addresses = NULL;
|
||||
int n_addresses = 0;
|
||||
char *msg = NULL;
|
||||
char *temp_buffer = NULL;
|
||||
bool non_authoritative = false;
|
||||
int result = STATE_UNKNOWN;
|
||||
double elapsed_time;
|
||||
long microsec;
|
||||
struct timeval tv;
|
||||
bool parse_address = false; /* This flag scans for Address: but only after Name: */
|
||||
output chld_out;
|
||||
output chld_err;
|
||||
bool is_nxdomain = false;
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
textdomain(PACKAGE);
|
||||
|
|
@ -97,39 +76,65 @@ int main(int argc, char **argv) {
|
|||
/* Parse extra opts if any */
|
||||
argv = np_extra_opts(&argc, argv, progname);
|
||||
|
||||
if (process_arguments(argc, argv) == ERROR) {
|
||||
check_dns_config_wrapper tmp = process_arguments(argc, argv);
|
||||
|
||||
if (tmp.errorcode == ERROR) {
|
||||
usage_va(_("Could not parse arguments"));
|
||||
}
|
||||
|
||||
/* get the command to run */
|
||||
xasprintf(&command_line, "%s %s %s", NSLOOKUP_COMMAND, query_address, dns_server);
|
||||
const check_dns_config config = tmp.config;
|
||||
|
||||
char *command_line = NULL;
|
||||
/* get the command to run */
|
||||
xasprintf(&command_line, "%s %s %s", NSLOOKUP_COMMAND, config.query_address, config.dns_server);
|
||||
|
||||
struct timeval tv;
|
||||
alarm(timeout_interval);
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
printf("%s\n", command_line);
|
||||
}
|
||||
|
||||
output chld_out;
|
||||
output chld_err;
|
||||
char *msg = NULL;
|
||||
mp_state_enum result = STATE_UNKNOWN;
|
||||
/* run the command */
|
||||
if ((np_runcmd(command_line, &chld_out, &chld_err, 0)) != 0) {
|
||||
msg = (char *)_("nslookup returned an error status");
|
||||
result = STATE_WARNING;
|
||||
}
|
||||
|
||||
/* scan stdout */
|
||||
/* =====
|
||||
* scan stdout, main results get retrieved here
|
||||
* =====
|
||||
*/
|
||||
char *address = NULL; /* comma separated str with addrs/ptrs (sorted) */
|
||||
char **addresses = NULL; // All addresses parsed from stdout
|
||||
size_t n_addresses = 0; // counter for retrieved addresses
|
||||
bool non_authoritative = false;
|
||||
bool is_nxdomain = false;
|
||||
bool parse_address = false; /* This flag scans for Address: but only after Name: */
|
||||
for (size_t i = 0; i < chld_out.lines; i++) {
|
||||
if (addresses == NULL)
|
||||
if (addresses == NULL) {
|
||||
addresses = malloc(sizeof(*addresses) * 10);
|
||||
else if (!(n_addresses % 10))
|
||||
} else if (!(n_addresses % 10)) {
|
||||
addresses = realloc(addresses, sizeof(*addresses) * (n_addresses + 10));
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
puts(chld_out.line[i]);
|
||||
}
|
||||
|
||||
if (strcasestr(chld_out.line[i], ".in-addr.arpa") || strcasestr(chld_out.line[i], ".ip6.arpa")) {
|
||||
if ((temp_buffer = strstr(chld_out.line[i], "name = ")))
|
||||
if ((strstr(chld_out.line[i], "canonical name = ") != NULL)) {
|
||||
continue;
|
||||
}
|
||||
char *temp_buffer = NULL;
|
||||
if ((temp_buffer = strstr(chld_out.line[i], "name = "))) {
|
||||
addresses[n_addresses++] = strdup(temp_buffer + 7);
|
||||
else {
|
||||
} else {
|
||||
msg = (char *)_("Warning plugin error");
|
||||
result = STATE_WARNING;
|
||||
}
|
||||
|
|
@ -137,37 +142,47 @@ int main(int argc, char **argv) {
|
|||
|
||||
/* bug ID: 2946553 - Older versions of bind will use all available dns
|
||||
servers, we have to match the one specified */
|
||||
if (strstr(chld_out.line[i], "Server:") && strlen(dns_server) > 0) {
|
||||
temp_buffer = strchr(chld_out.line[i], ':');
|
||||
if (strstr(chld_out.line[i], "Server:") && strlen(config.dns_server) > 0) {
|
||||
char *temp_buffer = strchr(chld_out.line[i], ':');
|
||||
if (temp_buffer == NULL) {
|
||||
die(STATE_UNKNOWN, _("'%s' returned a weirdly formatted Server line\n"), NSLOOKUP_COMMAND);
|
||||
}
|
||||
|
||||
temp_buffer++;
|
||||
|
||||
/* Strip leading tabs */
|
||||
for (; *temp_buffer != '\0' && *temp_buffer == '\t'; temp_buffer++)
|
||||
for (; *temp_buffer != '\0' && *temp_buffer == '\t'; temp_buffer++) {
|
||||
/* NOOP */;
|
||||
}
|
||||
|
||||
strip(temp_buffer);
|
||||
if (temp_buffer == NULL || strlen(temp_buffer) == 0) {
|
||||
if (strlen(temp_buffer) == 0) {
|
||||
die(STATE_CRITICAL, _("DNS CRITICAL - '%s' returned empty server string\n"), NSLOOKUP_COMMAND);
|
||||
}
|
||||
|
||||
if (strcmp(temp_buffer, dns_server) != 0) {
|
||||
die(STATE_CRITICAL, _("DNS CRITICAL - No response from DNS %s\n"), dns_server);
|
||||
if (strcmp(temp_buffer, config.dns_server) != 0) {
|
||||
die(STATE_CRITICAL, _("DNS CRITICAL - No response from DNS %s\n"), config.dns_server);
|
||||
}
|
||||
}
|
||||
|
||||
/* the server is responding, we just got the host name... */
|
||||
if (strstr(chld_out.line[i], "Name:"))
|
||||
if (strstr(chld_out.line[i], "Name:")) {
|
||||
parse_address = true;
|
||||
else if (parse_address && (strstr(chld_out.line[i], "Address:") || strstr(chld_out.line[i], "Addresses:"))) {
|
||||
temp_buffer = index(chld_out.line[i], ':');
|
||||
} else if (parse_address && (strstr(chld_out.line[i], "Address:") || strstr(chld_out.line[i], "Addresses:"))) {
|
||||
char *temp_buffer = strchr(chld_out.line[i], ':');
|
||||
if (temp_buffer == NULL) {
|
||||
die(STATE_UNKNOWN, _("'%s' returned a weirdly formatted Address line\n"), NSLOOKUP_COMMAND);
|
||||
}
|
||||
|
||||
temp_buffer++;
|
||||
|
||||
/* Strip leading spaces */
|
||||
while (*temp_buffer == ' ')
|
||||
while (*temp_buffer == ' ') {
|
||||
temp_buffer++;
|
||||
}
|
||||
|
||||
strip(temp_buffer);
|
||||
if (temp_buffer == NULL || strlen(temp_buffer) == 0) {
|
||||
if (strlen(temp_buffer) == 0) {
|
||||
die(STATE_CRITICAL, _("DNS CRITICAL - '%s' returned empty host name string\n"), NSLOOKUP_COMMAND);
|
||||
}
|
||||
|
||||
|
|
@ -176,65 +191,71 @@ int main(int argc, char **argv) {
|
|||
non_authoritative = true;
|
||||
}
|
||||
|
||||
result = error_scan(chld_out.line[i], &is_nxdomain);
|
||||
result = error_scan(chld_out.line[i], &is_nxdomain, config.dns_server);
|
||||
if (result != STATE_OK) {
|
||||
msg = strchr(chld_out.line[i], ':');
|
||||
if (msg)
|
||||
if (msg) {
|
||||
msg++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
char input_buffer[MAX_INPUT_BUFFER];
|
||||
/* scan stderr */
|
||||
for (size_t i = 0; i < chld_err.lines; i++) {
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
puts(chld_err.line[i]);
|
||||
}
|
||||
|
||||
if (error_scan(chld_err.line[i], &is_nxdomain) != STATE_OK) {
|
||||
result = max_state(result, error_scan(chld_err.line[i], &is_nxdomain));
|
||||
if (error_scan(chld_err.line[i], &is_nxdomain, config.dns_server) != STATE_OK) {
|
||||
result = max_state(result, error_scan(chld_err.line[i], &is_nxdomain, config.dns_server));
|
||||
msg = strchr(input_buffer, ':');
|
||||
if (msg)
|
||||
if (msg) {
|
||||
msg++;
|
||||
else
|
||||
} else {
|
||||
msg = input_buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_nxdomain && !expect_nxdomain) {
|
||||
die(STATE_CRITICAL, _("Domain '%s' was not found by the server\n"), query_address);
|
||||
if (is_nxdomain && !config.expect_nxdomain) {
|
||||
die(STATE_CRITICAL, _("Domain '%s' was not found by the server\n"), config.query_address);
|
||||
}
|
||||
|
||||
if (addresses) {
|
||||
int i;
|
||||
int slen;
|
||||
char *adrp;
|
||||
size_t slen = 1;
|
||||
char *adrp = NULL;
|
||||
qsort(addresses, n_addresses, sizeof(*addresses), qstrcmp);
|
||||
for (i = 0, slen = 1; i < n_addresses; i++) {
|
||||
for (size_t i = 0; i < n_addresses; i++) {
|
||||
slen += strlen(addresses[i]) + 1;
|
||||
}
|
||||
|
||||
// Temporary pointer adrp gets moved, address stays on the beginning
|
||||
adrp = address = malloc(slen);
|
||||
for (i = 0; i < n_addresses; i++) {
|
||||
if (i)
|
||||
for (size_t i = 0; i < n_addresses; i++) {
|
||||
if (i) {
|
||||
*adrp++ = ',';
|
||||
}
|
||||
strcpy(adrp, addresses[i]);
|
||||
adrp += strlen(addresses[i]);
|
||||
}
|
||||
*adrp = 0;
|
||||
} else
|
||||
} else {
|
||||
die(STATE_CRITICAL, _("DNS CRITICAL - '%s' msg parsing exited with no address\n"), NSLOOKUP_COMMAND);
|
||||
}
|
||||
|
||||
/* compare to expected address */
|
||||
if (result == STATE_OK && expected_address_cnt > 0) {
|
||||
if (result == STATE_OK && config.expected_address_cnt > 0) {
|
||||
result = STATE_CRITICAL;
|
||||
temp_buffer = "";
|
||||
unsigned long expect_match = (1 << expected_address_cnt) - 1;
|
||||
char *temp_buffer = "";
|
||||
unsigned long expect_match = (1 << config.expected_address_cnt) - 1;
|
||||
unsigned long addr_match = (1 << n_addresses) - 1;
|
||||
|
||||
for (int i = 0; i < expected_address_cnt; i++) {
|
||||
int j;
|
||||
for (size_t i = 0; i < config.expected_address_cnt; i++) {
|
||||
/* check if we get a match on 'raw' ip or cidr */
|
||||
for (j = 0; j < n_addresses; j++) {
|
||||
if (strcmp(addresses[j], expected_address[i]) == 0 || ip_match_cidr(addresses[j], expected_address[i])) {
|
||||
for (size_t j = 0; j < n_addresses; j++) {
|
||||
if (strcmp(addresses[j], config.expected_address[i]) == 0 || ip_match_cidr(addresses[j], config.expected_address[i])) {
|
||||
result = STATE_OK;
|
||||
addr_match &= ~(1 << j);
|
||||
expect_match &= ~(1 << i);
|
||||
|
|
@ -242,11 +263,12 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
/* prepare an error string */
|
||||
xasprintf(&temp_buffer, "%s%s; ", temp_buffer, expected_address[i]);
|
||||
xasprintf(&temp_buffer, "%s%s; ", temp_buffer, config.expected_address[i]);
|
||||
}
|
||||
/* check if expected_address must cover all in addresses and none may be missing */
|
||||
if (all_match && (expect_match != 0 || addr_match != 0))
|
||||
if (config.all_match && (expect_match != 0 || addr_match != 0)) {
|
||||
result = STATE_CRITICAL;
|
||||
}
|
||||
if (result == STATE_CRITICAL) {
|
||||
/* Strip off last semicolon... */
|
||||
temp_buffer[strlen(temp_buffer) - 2] = '\0';
|
||||
|
|
@ -254,28 +276,29 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
}
|
||||
|
||||
if (expect_nxdomain) {
|
||||
if (config.expect_nxdomain) {
|
||||
if (!is_nxdomain) {
|
||||
result = STATE_CRITICAL;
|
||||
xasprintf(&msg, _("Domain '%s' was found by the server: '%s'\n"), query_address, address);
|
||||
xasprintf(&msg, _("Domain '%s' was found by the server: '%s'\n"), config.query_address, address);
|
||||
} else {
|
||||
if (address != NULL)
|
||||
if (address != NULL) {
|
||||
free(address);
|
||||
}
|
||||
address = "NXDOMAIN";
|
||||
}
|
||||
}
|
||||
|
||||
/* check if authoritative */
|
||||
if (result == STATE_OK && expect_authority && non_authoritative) {
|
||||
if (result == STATE_OK && config.expect_authority && non_authoritative) {
|
||||
result = STATE_CRITICAL;
|
||||
xasprintf(&msg, _("server %s is not authoritative for %s"), dns_server, query_address);
|
||||
xasprintf(&msg, _("server %s is not authoritative for %s"), config.dns_server, config.query_address);
|
||||
}
|
||||
|
||||
microsec = deltime(tv);
|
||||
elapsed_time = (double)microsec / 1.0e6;
|
||||
long microsec = deltime(tv);
|
||||
double elapsed_time = (double)microsec / 1.0e6;
|
||||
|
||||
if (result == STATE_OK) {
|
||||
result = get_status(elapsed_time, time_thresholds);
|
||||
result = get_status(elapsed_time, config.time_thresholds);
|
||||
if (result == STATE_OK) {
|
||||
printf("DNS %s: ", _("OK"));
|
||||
} else if (result == STATE_WARNING) {
|
||||
|
|
@ -284,24 +307,26 @@ int main(int argc, char **argv) {
|
|||
printf("DNS %s: ", _("CRITICAL"));
|
||||
}
|
||||
printf(ngettext("%.3f second response time", "%.3f seconds response time", elapsed_time), elapsed_time);
|
||||
printf(_(". %s returns %s"), query_address, address);
|
||||
if ((time_thresholds->warning != NULL) && (time_thresholds->critical != NULL)) {
|
||||
printf("|%s\n", fperfdata("time", elapsed_time, "s", true, time_thresholds->warning->end, true, time_thresholds->critical->end,
|
||||
true, 0, false, 0));
|
||||
} else if ((time_thresholds->warning == NULL) && (time_thresholds->critical != NULL)) {
|
||||
printf("|%s\n", fperfdata("time", elapsed_time, "s", false, 0, true, time_thresholds->critical->end, true, 0, false, 0));
|
||||
} else if ((time_thresholds->warning != NULL) && (time_thresholds->critical == NULL)) {
|
||||
printf("|%s\n", fperfdata("time", elapsed_time, "s", true, time_thresholds->warning->end, false, 0, true, 0, false, 0));
|
||||
} else
|
||||
printf(_(". %s returns %s"), config.query_address, address);
|
||||
if ((config.time_thresholds->warning != NULL) && (config.time_thresholds->critical != NULL)) {
|
||||
printf("|%s\n", fperfdata("time", elapsed_time, "s", true, config.time_thresholds->warning->end, true,
|
||||
config.time_thresholds->critical->end, true, 0, false, 0));
|
||||
} else if ((config.time_thresholds->warning == NULL) && (config.time_thresholds->critical != NULL)) {
|
||||
printf("|%s\n", fperfdata("time", elapsed_time, "s", false, 0, true, config.time_thresholds->critical->end, true, 0, false, 0));
|
||||
} else if ((config.time_thresholds->warning != NULL) && (config.time_thresholds->critical == NULL)) {
|
||||
printf("|%s\n", fperfdata("time", elapsed_time, "s", true, config.time_thresholds->warning->end, false, 0, true, 0, false, 0));
|
||||
} else {
|
||||
printf("|%s\n", fperfdata("time", elapsed_time, "s", false, 0, false, 0, true, 0, false, 0));
|
||||
} else if (result == STATE_WARNING)
|
||||
}
|
||||
} else if (result == STATE_WARNING) {
|
||||
printf(_("DNS WARNING - %s\n"), !strcmp(msg, "") ? _(" Probably a non-existent host/domain") : msg);
|
||||
else if (result == STATE_CRITICAL)
|
||||
} else if (result == STATE_CRITICAL) {
|
||||
printf(_("DNS CRITICAL - %s\n"), !strcmp(msg, "") ? _(" Probably a non-existent host/domain") : msg);
|
||||
else
|
||||
} else {
|
||||
printf(_("DNS UNKNOWN - %s\n"), !strcmp(msg, "") ? _(" Probably a non-existent host/domain") : msg);
|
||||
}
|
||||
|
||||
return result;
|
||||
exit(result);
|
||||
}
|
||||
|
||||
bool ip_match_cidr(const char *addr, const char *cidr_ro) {
|
||||
|
|
@ -329,64 +354,69 @@ unsigned long ip2long(const char *src) {
|
|||
: 0;
|
||||
}
|
||||
|
||||
int error_scan(char *input_buffer, bool *is_nxdomain) {
|
||||
mp_state_enum error_scan(char *input_buffer, bool *is_nxdomain, const char dns_server[ADDRESS_LENGTH]) {
|
||||
|
||||
const int nxdomain = strstr(input_buffer, "Non-existent") || strstr(input_buffer, "** server can't find") ||
|
||||
strstr(input_buffer, "** Can't find") || strstr(input_buffer, "NXDOMAIN");
|
||||
if (nxdomain)
|
||||
if (nxdomain) {
|
||||
*is_nxdomain = true;
|
||||
}
|
||||
|
||||
/* the DNS lookup timed out */
|
||||
if (strstr(input_buffer, _("Note: nslookup is deprecated and may be removed from future releases.")) ||
|
||||
strstr(input_buffer, _("Consider using the `dig' or `host' programs instead. Run nslookup with")) ||
|
||||
strstr(input_buffer, _("the `-sil[ent]' option to prevent this message from appearing.")))
|
||||
strstr(input_buffer, _("the `-sil[ent]' option to prevent this message from appearing."))) {
|
||||
return STATE_OK;
|
||||
}
|
||||
|
||||
/* DNS server is not running... */
|
||||
else if (strstr(input_buffer, "No response from server"))
|
||||
else if (strstr(input_buffer, "No response from server")) {
|
||||
die(STATE_CRITICAL, _("No response from DNS %s\n"), dns_server);
|
||||
else if (strstr(input_buffer, "no servers could be reached"))
|
||||
} else if (strstr(input_buffer, "no servers could be reached")) {
|
||||
die(STATE_CRITICAL, _("No response from DNS %s\n"), dns_server);
|
||||
}
|
||||
|
||||
/* Host name is valid, but server doesn't have records... */
|
||||
else if (strstr(input_buffer, "No records"))
|
||||
else if (strstr(input_buffer, "No records")) {
|
||||
die(STATE_CRITICAL, _("DNS %s has no records\n"), dns_server);
|
||||
}
|
||||
|
||||
/* Connection was refused */
|
||||
else if (strstr(input_buffer, "Connection refused") || strstr(input_buffer, "Couldn't find server") ||
|
||||
strstr(input_buffer, "Refused") || (strstr(input_buffer, "** server can't find") && strstr(input_buffer, ": REFUSED")))
|
||||
strstr(input_buffer, "Refused") || (strstr(input_buffer, "** server can't find") && strstr(input_buffer, ": REFUSED"))) {
|
||||
die(STATE_CRITICAL, _("Connection to DNS %s was refused\n"), dns_server);
|
||||
}
|
||||
|
||||
/* Query refused (usually by an ACL in the namserver) */
|
||||
else if (strstr(input_buffer, "Query refused"))
|
||||
else if (strstr(input_buffer, "Query refused")) {
|
||||
die(STATE_CRITICAL, _("Query was refused by DNS server at %s\n"), dns_server);
|
||||
}
|
||||
|
||||
/* No information (e.g. nameserver IP has two PTR records) */
|
||||
else if (strstr(input_buffer, "No information"))
|
||||
else if (strstr(input_buffer, "No information")) {
|
||||
die(STATE_CRITICAL, _("No information returned by DNS server at %s\n"), dns_server);
|
||||
}
|
||||
|
||||
/* Network is unreachable */
|
||||
else if (strstr(input_buffer, "Network is unreachable"))
|
||||
else if (strstr(input_buffer, "Network is unreachable")) {
|
||||
die(STATE_CRITICAL, _("Network is unreachable\n"));
|
||||
}
|
||||
|
||||
/* Internal server failure */
|
||||
else if (strstr(input_buffer, "Server failure"))
|
||||
else if (strstr(input_buffer, "Server failure")) {
|
||||
die(STATE_CRITICAL, _("DNS failure for %s\n"), dns_server);
|
||||
}
|
||||
|
||||
/* Request error or the DNS lookup timed out */
|
||||
else if (strstr(input_buffer, "Format error") || strstr(input_buffer, "Timed out"))
|
||||
else if (strstr(input_buffer, "Format error") || strstr(input_buffer, "Timed out")) {
|
||||
return STATE_WARNING;
|
||||
}
|
||||
|
||||
return STATE_OK;
|
||||
}
|
||||
|
||||
/* process command-line arguments */
|
||||
int process_arguments(int argc, char **argv) {
|
||||
int c;
|
||||
char *warning = NULL;
|
||||
char *critical = NULL;
|
||||
|
||||
int opt_index = 0;
|
||||
check_dns_config_wrapper process_arguments(int argc, char **argv) {
|
||||
static struct option long_opts[] = {{"help", no_argument, 0, 'h'},
|
||||
{"version", no_argument, 0, 'V'},
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
|
|
@ -402,20 +432,34 @@ int process_arguments(int argc, char **argv) {
|
|||
{"critical", required_argument, 0, 'c'},
|
||||
{0, 0, 0, 0}};
|
||||
|
||||
if (argc < 2)
|
||||
return ERROR;
|
||||
check_dns_config_wrapper result = {
|
||||
.config = check_dns_config_init(),
|
||||
.errorcode = OK,
|
||||
};
|
||||
|
||||
for (c = 1; c < argc; c++)
|
||||
if (strcmp("-to", argv[c]) == 0)
|
||||
strcpy(argv[c], "-t");
|
||||
if (argc < 2) {
|
||||
result.errorcode = ERROR;
|
||||
return result;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
c = getopt_long(argc, argv, "hVvALnt:H:s:r:a:w:c:", long_opts, &opt_index);
|
||||
for (int index = 1; index < argc; index++) {
|
||||
if (strcmp("-to", argv[index]) == 0) {
|
||||
strcpy(argv[index], "-t");
|
||||
}
|
||||
}
|
||||
|
||||
if (c == -1 || c == EOF)
|
||||
char *warning = NULL;
|
||||
char *critical = NULL;
|
||||
int opt_index = 0;
|
||||
int index = 0;
|
||||
while (true) {
|
||||
index = getopt_long(argc, argv, "hVvALnt:H:s:r:a:w:c:", long_opts, &opt_index);
|
||||
|
||||
if (index == -1 || index == EOF) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (c) {
|
||||
switch (index) {
|
||||
case 'h': /* help */
|
||||
print_help();
|
||||
exit(STATE_UNKNOWN);
|
||||
|
|
@ -429,54 +473,63 @@ int process_arguments(int argc, char **argv) {
|
|||
timeout_interval = atoi(optarg);
|
||||
break;
|
||||
case 'H': /* hostname */
|
||||
if (strlen(optarg) >= ADDRESS_LENGTH)
|
||||
if (strlen(optarg) >= ADDRESS_LENGTH) {
|
||||
die(STATE_UNKNOWN, _("Input buffer overflow\n"));
|
||||
strcpy(query_address, optarg);
|
||||
}
|
||||
strcpy(result.config.query_address, optarg);
|
||||
break;
|
||||
case 's': /* server name */
|
||||
/* TODO: this host_or_die check is probably unnecessary.
|
||||
* Better to confirm nslookup response matches */
|
||||
host_or_die(optarg);
|
||||
if (strlen(optarg) >= ADDRESS_LENGTH)
|
||||
if (strlen(optarg) >= ADDRESS_LENGTH) {
|
||||
die(STATE_UNKNOWN, _("Input buffer overflow\n"));
|
||||
strcpy(dns_server, optarg);
|
||||
}
|
||||
strcpy(result.config.dns_server, optarg);
|
||||
break;
|
||||
case 'r': /* reverse server name */
|
||||
/* TODO: Is this host_or_die necessary? */
|
||||
// TODO This does not do anything!!! 2025-03-08 rincewind
|
||||
host_or_die(optarg);
|
||||
if (strlen(optarg) >= ADDRESS_LENGTH)
|
||||
if (strlen(optarg) >= ADDRESS_LENGTH) {
|
||||
die(STATE_UNKNOWN, _("Input buffer overflow\n"));
|
||||
}
|
||||
static char ptr_server[ADDRESS_LENGTH] = "";
|
||||
strcpy(ptr_server, optarg);
|
||||
break;
|
||||
case 'a': /* expected address */
|
||||
if (strlen(optarg) >= ADDRESS_LENGTH)
|
||||
if (strlen(optarg) >= ADDRESS_LENGTH) {
|
||||
die(STATE_UNKNOWN, _("Input buffer overflow\n"));
|
||||
}
|
||||
if (strchr(optarg, ',') != NULL) {
|
||||
char *comma = strchr(optarg, ',');
|
||||
while (comma != NULL) {
|
||||
expected_address = (char **)realloc(expected_address, (expected_address_cnt + 1) * sizeof(char **));
|
||||
expected_address[expected_address_cnt] = strndup(optarg, comma - optarg);
|
||||
expected_address_cnt++;
|
||||
result.config.expected_address =
|
||||
(char **)realloc(result.config.expected_address, (result.config.expected_address_cnt + 1) * sizeof(char **));
|
||||
result.config.expected_address[result.config.expected_address_cnt] = strndup(optarg, comma - optarg);
|
||||
result.config.expected_address_cnt++;
|
||||
optarg = comma + 1;
|
||||
comma = strchr(optarg, ',');
|
||||
}
|
||||
expected_address = (char **)realloc(expected_address, (expected_address_cnt + 1) * sizeof(char **));
|
||||
expected_address[expected_address_cnt] = strdup(optarg);
|
||||
expected_address_cnt++;
|
||||
result.config.expected_address =
|
||||
(char **)realloc(result.config.expected_address, (result.config.expected_address_cnt + 1) * sizeof(char **));
|
||||
result.config.expected_address[result.config.expected_address_cnt] = strdup(optarg);
|
||||
result.config.expected_address_cnt++;
|
||||
} else {
|
||||
expected_address = (char **)realloc(expected_address, (expected_address_cnt + 1) * sizeof(char **));
|
||||
expected_address[expected_address_cnt] = strdup(optarg);
|
||||
expected_address_cnt++;
|
||||
result.config.expected_address =
|
||||
(char **)realloc(result.config.expected_address, (result.config.expected_address_cnt + 1) * sizeof(char **));
|
||||
result.config.expected_address[result.config.expected_address_cnt] = strdup(optarg);
|
||||
result.config.expected_address_cnt++;
|
||||
}
|
||||
break;
|
||||
case 'n': /* expect NXDOMAIN */
|
||||
expect_nxdomain = true;
|
||||
result.config.expect_nxdomain = true;
|
||||
break;
|
||||
case 'A': /* expect authority */
|
||||
expect_authority = true;
|
||||
result.config.expect_authority = true;
|
||||
break;
|
||||
case 'L': /* all must match */
|
||||
all_match = true;
|
||||
result.config.all_match = true;
|
||||
break;
|
||||
case 'w':
|
||||
warning = optarg;
|
||||
|
|
@ -489,38 +542,42 @@ int process_arguments(int argc, char **argv) {
|
|||
}
|
||||
}
|
||||
|
||||
c = optind;
|
||||
if (strlen(query_address) == 0 && c < argc) {
|
||||
if (strlen(argv[c]) >= ADDRESS_LENGTH)
|
||||
index = optind;
|
||||
if (strlen(result.config.query_address) == 0 && index < argc) {
|
||||
if (strlen(argv[index]) >= ADDRESS_LENGTH) {
|
||||
die(STATE_UNKNOWN, _("Input buffer overflow\n"));
|
||||
strcpy(query_address, argv[c++]);
|
||||
}
|
||||
strcpy(result.config.query_address, argv[index++]);
|
||||
}
|
||||
|
||||
if (strlen(dns_server) == 0 && c < argc) {
|
||||
if (strlen(result.config.dns_server) == 0 && index < argc) {
|
||||
/* TODO: See -s option */
|
||||
host_or_die(argv[c]);
|
||||
if (strlen(argv[c]) >= ADDRESS_LENGTH)
|
||||
host_or_die(argv[index]);
|
||||
if (strlen(argv[index]) >= ADDRESS_LENGTH) {
|
||||
die(STATE_UNKNOWN, _("Input buffer overflow\n"));
|
||||
strcpy(dns_server, argv[c++]);
|
||||
}
|
||||
strcpy(result.config.dns_server, argv[index++]);
|
||||
}
|
||||
|
||||
set_thresholds(&time_thresholds, warning, critical);
|
||||
set_thresholds(&result.config.time_thresholds, warning, critical);
|
||||
|
||||
return validate_arguments();
|
||||
return validate_arguments(result);
|
||||
}
|
||||
|
||||
int validate_arguments(void) {
|
||||
if (query_address[0] == 0) {
|
||||
check_dns_config_wrapper validate_arguments(check_dns_config_wrapper config_wrapper) {
|
||||
if (config_wrapper.config.query_address[0] == 0) {
|
||||
printf("missing --host argument\n");
|
||||
return ERROR;
|
||||
config_wrapper.errorcode = ERROR;
|
||||
return config_wrapper;
|
||||
}
|
||||
|
||||
if (expected_address_cnt > 0 && expect_nxdomain) {
|
||||
if (config_wrapper.config.expected_address_cnt > 0 && config_wrapper.config.expect_nxdomain) {
|
||||
printf("--expected-address and --expect-nxdomain cannot be combined\n");
|
||||
return ERROR;
|
||||
config_wrapper.errorcode = ERROR;
|
||||
return config_wrapper;
|
||||
}
|
||||
|
||||
return OK;
|
||||
return config_wrapper;
|
||||
}
|
||||
|
||||
void print_help(void) {
|
||||
|
|
|
|||
34
plugins/check_dns.d/config.h
Normal file
34
plugins/check_dns.d/config.h
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../config.h"
|
||||
#include "thresholds.h"
|
||||
#include <stddef.h>
|
||||
|
||||
#define ADDRESS_LENGTH 256
|
||||
|
||||
typedef struct {
|
||||
bool all_match;
|
||||
char dns_server[ADDRESS_LENGTH];
|
||||
char query_address[ADDRESS_LENGTH];
|
||||
bool expect_nxdomain;
|
||||
bool expect_authority;
|
||||
char **expected_address;
|
||||
size_t expected_address_cnt;
|
||||
|
||||
thresholds *time_thresholds;
|
||||
} check_dns_config;
|
||||
|
||||
check_dns_config check_dns_config_init() {
|
||||
check_dns_config tmp = {
|
||||
.all_match = false,
|
||||
.dns_server = "",
|
||||
.query_address = "",
|
||||
.expect_nxdomain = false,
|
||||
.expect_authority = false,
|
||||
.expected_address = NULL,
|
||||
.expected_address_cnt = 0,
|
||||
|
||||
.time_thresholds = NULL,
|
||||
};
|
||||
return tmp;
|
||||
}
|
||||
|
|
@ -38,52 +38,29 @@ const char *email = "devel@monitoring-plugins.org";
|
|||
#include "netutils.h"
|
||||
#include "utils.h"
|
||||
#include <stdbool.h>
|
||||
#include "check_fping.d/config.h"
|
||||
#include "states.h"
|
||||
|
||||
enum {
|
||||
PACKET_COUNT = 1,
|
||||
PACKET_SIZE = 56,
|
||||
PL = 0,
|
||||
RTA = 1
|
||||
};
|
||||
|
||||
static int textscan(char *buf);
|
||||
static int process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
static mp_state_enum textscan(char *buf, const char * /*server_name*/, bool /*crta_p*/, double /*crta*/, bool /*wrta_p*/, double /*wrta*/,
|
||||
bool /*cpl_p*/, int /*cpl*/, bool /*wpl_p*/, int /*wpl*/, bool /*alive_p*/);
|
||||
|
||||
typedef struct {
|
||||
int errorcode;
|
||||
check_fping_config config;
|
||||
} check_fping_config_wrapper;
|
||||
static check_fping_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
static int get_threshold(char *arg, char *rv[2]);
|
||||
static void print_help(void);
|
||||
void print_usage(void);
|
||||
|
||||
static char *server_name = NULL;
|
||||
static char *sourceip = NULL;
|
||||
static char *sourceif = NULL;
|
||||
static int packet_size = PACKET_SIZE;
|
||||
static int packet_count = PACKET_COUNT;
|
||||
static int target_timeout = 0;
|
||||
static int packet_interval = 0;
|
||||
static bool verbose = false;
|
||||
static bool dontfrag = false;
|
||||
static bool randomize_packet_data = false;
|
||||
static int cpl;
|
||||
static int wpl;
|
||||
static double crta;
|
||||
static double wrta;
|
||||
static bool cpl_p = false;
|
||||
static bool wpl_p = false;
|
||||
static bool alive_p = false;
|
||||
static bool crta_p = false;
|
||||
static bool wrta_p = false;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
/* normally should be int result = STATE_UNKNOWN; */
|
||||
|
||||
int status = STATE_UNKNOWN;
|
||||
int result = 0;
|
||||
char *fping_prog = NULL;
|
||||
char *server = NULL;
|
||||
char *command_line = NULL;
|
||||
char *input_buffer = NULL;
|
||||
char *option_string = "";
|
||||
input_buffer = malloc(MAX_INPUT_BUFFER);
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
textdomain(PACKAGE);
|
||||
|
|
@ -91,39 +68,54 @@ int main(int argc, char **argv) {
|
|||
/* Parse extra opts if any */
|
||||
argv = np_extra_opts(&argc, argv, progname);
|
||||
|
||||
if (process_arguments(argc, argv) == ERROR)
|
||||
check_fping_config_wrapper tmp_config = process_arguments(argc, argv);
|
||||
if (tmp_config.errorcode == ERROR) {
|
||||
usage4(_("Could not parse arguments"));
|
||||
}
|
||||
|
||||
server = strscpy(server, server_name);
|
||||
const check_fping_config config = tmp_config.config;
|
||||
|
||||
char *server = NULL;
|
||||
server = strscpy(server, config.server_name);
|
||||
|
||||
char *option_string = "";
|
||||
/* compose the command */
|
||||
if (target_timeout)
|
||||
xasprintf(&option_string, "%s-t %d ", option_string, target_timeout);
|
||||
if (packet_interval)
|
||||
xasprintf(&option_string, "%s-p %d ", option_string, packet_interval);
|
||||
if (sourceip)
|
||||
xasprintf(&option_string, "%s-S %s ", option_string, sourceip);
|
||||
if (sourceif)
|
||||
xasprintf(&option_string, "%s-I %s ", option_string, sourceif);
|
||||
if (dontfrag)
|
||||
if (config.target_timeout) {
|
||||
xasprintf(&option_string, "%s-t %d ", option_string, config.target_timeout);
|
||||
}
|
||||
if (config.packet_interval) {
|
||||
xasprintf(&option_string, "%s-p %d ", option_string, config.packet_interval);
|
||||
}
|
||||
if (config.sourceip) {
|
||||
xasprintf(&option_string, "%s-S %s ", option_string, config.sourceip);
|
||||
}
|
||||
if (config.sourceif) {
|
||||
xasprintf(&option_string, "%s-I %s ", option_string, config.sourceif);
|
||||
}
|
||||
if (config.dontfrag) {
|
||||
xasprintf(&option_string, "%s-M ", option_string);
|
||||
if (randomize_packet_data)
|
||||
}
|
||||
if (config.randomize_packet_data) {
|
||||
xasprintf(&option_string, "%s-R ", option_string);
|
||||
}
|
||||
|
||||
|
||||
char *fping_prog = NULL;
|
||||
#ifdef PATH_TO_FPING6
|
||||
if (address_family != AF_INET && is_inet6_addr(server))
|
||||
if (address_family != AF_INET && is_inet6_addr(server)) {
|
||||
fping_prog = strdup(PATH_TO_FPING6);
|
||||
else
|
||||
} else {
|
||||
fping_prog = strdup(PATH_TO_FPING);
|
||||
}
|
||||
#else
|
||||
fping_prog = strdup(PATH_TO_FPING);
|
||||
#endif
|
||||
|
||||
xasprintf(&command_line, "%s %s-b %d -c %d %s", fping_prog, option_string, packet_size, packet_count, server);
|
||||
char *command_line = NULL;
|
||||
xasprintf(&command_line, "%s %s-b %d -c %d %s", fping_prog, option_string, config.packet_size, config.packet_count, server);
|
||||
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
printf("%s\n", command_line);
|
||||
}
|
||||
|
||||
/* run the command */
|
||||
child_process = spopen(command_line);
|
||||
|
|
@ -137,23 +129,29 @@ int main(int argc, char **argv) {
|
|||
printf(_("Could not open stderr for %s\n"), command_line);
|
||||
}
|
||||
|
||||
char *input_buffer = malloc(MAX_INPUT_BUFFER);
|
||||
mp_state_enum status = STATE_UNKNOWN;
|
||||
while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_process)) {
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
printf("%s", input_buffer);
|
||||
status = max_state(status, textscan(input_buffer));
|
||||
}
|
||||
status = max_state(status, textscan(input_buffer, config.server_name, config.crta_p, config.crta, config.wrta_p, config.wrta,
|
||||
config.cpl_p, config.cpl, config.wpl_p, config.wpl, config.alive_p));
|
||||
}
|
||||
|
||||
/* If we get anything on STDERR, at least set warning */
|
||||
while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) {
|
||||
status = max_state(status, STATE_WARNING);
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
printf("%s", input_buffer);
|
||||
status = max_state(status, textscan(input_buffer));
|
||||
}
|
||||
status = max_state(status, textscan(input_buffer, config.server_name, config.crta_p, config.crta, config.wrta_p, config.wrta,
|
||||
config.cpl_p, config.cpl, config.wpl_p, config.wpl, config.alive_p));
|
||||
}
|
||||
(void)fclose(child_stderr);
|
||||
|
||||
/* close the pipe */
|
||||
result = spclose(child_process);
|
||||
int result = spclose(child_process);
|
||||
if (result) {
|
||||
/* need to use max_state not max */
|
||||
status = max_state(status, STATE_WARNING);
|
||||
|
|
@ -172,21 +170,17 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
}
|
||||
|
||||
printf("FPING %s - %s\n", state_text(status), server_name);
|
||||
printf("FPING %s - %s\n", state_text(status), config.server_name);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int textscan(char *buf) {
|
||||
char *rtastr = NULL;
|
||||
char *losstr = NULL;
|
||||
char *xmtstr = NULL;
|
||||
double loss;
|
||||
double rta;
|
||||
double xmt;
|
||||
int status = STATE_UNKNOWN;
|
||||
|
||||
mp_state_enum textscan(char *buf, const char *server_name, bool crta_p, double crta, bool wrta_p, double wrta, bool cpl_p, int cpl,
|
||||
bool wpl_p, int wpl, bool alive_p) {
|
||||
/* stops testing after the first successful reply. */
|
||||
double rta;
|
||||
double loss;
|
||||
char *rtastr = NULL;
|
||||
if (alive_p && strstr(buf, "avg, 0% loss)")) {
|
||||
rtastr = strstr(buf, "ms (");
|
||||
rtastr = 1 + index(rtastr, '(');
|
||||
|
|
@ -198,6 +192,10 @@ int textscan(char *buf) {
|
|||
fperfdata("rta", rta / 1.0e3, "s", wrta_p, wrta / 1.0e3, crta_p, crta / 1.0e3, true, 0, false, 0));
|
||||
}
|
||||
|
||||
mp_state_enum status = STATE_UNKNOWN;
|
||||
char *xmtstr = NULL;
|
||||
double xmt;
|
||||
char *losstr = NULL;
|
||||
if (strstr(buf, "not found")) {
|
||||
die(STATE_CRITICAL, _("FPING UNKNOWN - %s not found\n"), server_name);
|
||||
|
||||
|
|
@ -221,18 +219,19 @@ int textscan(char *buf) {
|
|||
rtastr = 1 + index(rtastr, '/');
|
||||
loss = strtod(losstr, NULL);
|
||||
rta = strtod(rtastr, NULL);
|
||||
if (cpl_p && loss > cpl)
|
||||
if (cpl_p && loss > cpl) {
|
||||
status = STATE_CRITICAL;
|
||||
else if (crta_p && rta > crta)
|
||||
} else if (crta_p && rta > crta) {
|
||||
status = STATE_CRITICAL;
|
||||
else if (wpl_p && loss > wpl)
|
||||
} else if (wpl_p && loss > wpl) {
|
||||
status = STATE_WARNING;
|
||||
else if (wrta_p && rta > wrta)
|
||||
} else if (wrta_p && rta > wrta) {
|
||||
status = STATE_WARNING;
|
||||
else
|
||||
} else {
|
||||
status = STATE_OK;
|
||||
}
|
||||
die(status, _("FPING %s - %s (loss=%.0f%%, rta=%f ms)|%s %s\n"), state_text(status), server_name, loss, rta,
|
||||
perfdata("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, true, 0, true, 100),
|
||||
perfdata("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, false, 0, false, 0),
|
||||
fperfdata("rta", rta / 1.0e3, "s", wrta_p, wrta / 1.0e3, crta_p, crta / 1.0e3, true, 0, false, 0));
|
||||
|
||||
} else if (strstr(buf, "xmt/rcv/%loss")) {
|
||||
|
|
@ -241,22 +240,24 @@ int textscan(char *buf) {
|
|||
losstr = strstr(buf, "=");
|
||||
xmtstr = 1 + losstr;
|
||||
xmt = strtod(xmtstr, NULL);
|
||||
if (xmt == 0)
|
||||
if (xmt == 0) {
|
||||
die(STATE_CRITICAL, _("FPING CRITICAL - %s is down\n"), server_name);
|
||||
}
|
||||
losstr = 1 + strstr(losstr, "/");
|
||||
losstr = 1 + strstr(losstr, "/");
|
||||
loss = strtod(losstr, NULL);
|
||||
if (atoi(losstr) == 100)
|
||||
if (atoi(losstr) == 100) {
|
||||
status = STATE_CRITICAL;
|
||||
else if (cpl_p && loss > cpl)
|
||||
} else if (cpl_p && loss > cpl) {
|
||||
status = STATE_CRITICAL;
|
||||
else if (wpl_p && loss > wpl)
|
||||
} else if (wpl_p && loss > wpl) {
|
||||
status = STATE_WARNING;
|
||||
else
|
||||
} else {
|
||||
status = STATE_OK;
|
||||
}
|
||||
/* loss=%.0f%%;%d;%d;0;100 */
|
||||
die(status, _("FPING %s - %s (loss=%.0f%% )|%s\n"), state_text(status), server_name, loss,
|
||||
perfdata("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, true, 0, true, 100));
|
||||
perfdata("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, false, 0, false, 0));
|
||||
|
||||
} else {
|
||||
status = max_state(status, STATE_WARNING);
|
||||
|
|
@ -266,54 +267,50 @@ int textscan(char *buf) {
|
|||
}
|
||||
|
||||
/* process command-line arguments */
|
||||
int process_arguments(int argc, char **argv) {
|
||||
int c;
|
||||
check_fping_config_wrapper process_arguments(int argc, char **argv) {
|
||||
static struct option longopts[] = {
|
||||
{"hostname", required_argument, 0, 'H'}, {"sourceip", required_argument, 0, 'S'}, {"sourceif", required_argument, 0, 'I'},
|
||||
{"critical", required_argument, 0, 'c'}, {"warning", required_argument, 0, 'w'}, {"alive", no_argument, 0, 'a'},
|
||||
{"bytes", required_argument, 0, 'b'}, {"number", required_argument, 0, 'n'}, {"target-timeout", required_argument, 0, 'T'},
|
||||
{"interval", required_argument, 0, 'i'}, {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'},
|
||||
{"help", no_argument, 0, 'h'}, {"use-ipv4", no_argument, 0, '4'}, {"use-ipv6", no_argument, 0, '6'},
|
||||
{"dontfrag", no_argument, 0, 'M'}, {"random", no_argument, 0, 'R'}, {0, 0, 0, 0}};
|
||||
|
||||
char *rv[2];
|
||||
|
||||
int option = 0;
|
||||
static struct option longopts[] = {{"hostname", required_argument, 0, 'H'},
|
||||
{"sourceip", required_argument, 0, 'S'},
|
||||
{"sourceif", required_argument, 0, 'I'},
|
||||
{"critical", required_argument, 0, 'c'},
|
||||
{"warning", required_argument, 0, 'w'},
|
||||
{"alive", no_argument, 0, 'a'},
|
||||
{"bytes", required_argument, 0, 'b'},
|
||||
{"number", required_argument, 0, 'n'},
|
||||
{"target-timeout", required_argument, 0, 'T'},
|
||||
{"interval", required_argument, 0, 'i'},
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
{"version", no_argument, 0, 'V'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"use-ipv4", no_argument, 0, '4'},
|
||||
{"use-ipv6", no_argument, 0, '6'},
|
||||
{"dontfrag", no_argument, 0, 'M'},
|
||||
{"random", no_argument, 0, 'R'},
|
||||
{0, 0, 0, 0}};
|
||||
|
||||
rv[PL] = NULL;
|
||||
rv[RTA] = NULL;
|
||||
|
||||
if (argc < 2)
|
||||
return ERROR;
|
||||
int option = 0;
|
||||
|
||||
check_fping_config_wrapper result = {
|
||||
.errorcode = OK,
|
||||
.config = check_fping_config_init(),
|
||||
};
|
||||
|
||||
if (argc < 2) {
|
||||
result.errorcode = ERROR;
|
||||
return result;
|
||||
}
|
||||
|
||||
if (!is_option(argv[1])) {
|
||||
server_name = argv[1];
|
||||
result.config.server_name = argv[1];
|
||||
argv[1] = argv[0];
|
||||
argv = &argv[1];
|
||||
argc--;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
c = getopt_long(argc, argv, "+hVvaH:S:c:w:b:n:T:i:I:M:R:46", longopts, &option);
|
||||
int option_index = getopt_long(argc, argv, "+hVvaH:S:c:w:b:n:T:i:I:M:R:46", longopts, &option);
|
||||
|
||||
if (c == -1 || c == EOF || c == 1)
|
||||
if (option_index == -1 || option_index == EOF || option_index == 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (c) {
|
||||
switch (option_index) {
|
||||
case '?': /* print short usage statement if args not parsable */
|
||||
usage5();
|
||||
case 'a': /* host alive mode */
|
||||
alive_p = true;
|
||||
result.config.alive_p = true;
|
||||
break;
|
||||
case 'h': /* help */
|
||||
print_help();
|
||||
|
|
@ -325,19 +322,19 @@ int process_arguments(int argc, char **argv) {
|
|||
verbose = true;
|
||||
break;
|
||||
case 'H': /* hostname */
|
||||
if (is_host(optarg) == false) {
|
||||
if (!is_host(optarg)) {
|
||||
usage2(_("Invalid hostname/address"), optarg);
|
||||
}
|
||||
server_name = strscpy(server_name, optarg);
|
||||
result.config.server_name = optarg;
|
||||
break;
|
||||
case 'S': /* sourceip */
|
||||
if (is_host(optarg) == false) {
|
||||
if (!is_host(optarg)) {
|
||||
usage2(_("Invalid hostname/address"), optarg);
|
||||
}
|
||||
sourceip = strscpy(sourceip, optarg);
|
||||
result.config.sourceip = optarg;
|
||||
break;
|
||||
case 'I': /* sourceip */
|
||||
sourceif = strscpy(sourceif, optarg);
|
||||
result.config.sourceif = optarg;
|
||||
break;
|
||||
case '4': /* IPv4 only */
|
||||
address_family = AF_INET;
|
||||
|
|
@ -352,82 +349,89 @@ int process_arguments(int argc, char **argv) {
|
|||
case 'c':
|
||||
get_threshold(optarg, rv);
|
||||
if (rv[RTA]) {
|
||||
crta = strtod(rv[RTA], NULL);
|
||||
crta_p = true;
|
||||
result.config.crta = strtod(rv[RTA], NULL);
|
||||
result.config.crta_p = true;
|
||||
rv[RTA] = NULL;
|
||||
}
|
||||
if (rv[PL]) {
|
||||
cpl = atoi(rv[PL]);
|
||||
cpl_p = true;
|
||||
result.config.cpl = atoi(rv[PL]);
|
||||
result.config.cpl_p = true;
|
||||
rv[PL] = NULL;
|
||||
}
|
||||
break;
|
||||
case 'w':
|
||||
get_threshold(optarg, rv);
|
||||
if (rv[RTA]) {
|
||||
wrta = strtod(rv[RTA], NULL);
|
||||
wrta_p = true;
|
||||
result.config.wrta = strtod(rv[RTA], NULL);
|
||||
result.config.wrta_p = true;
|
||||
rv[RTA] = NULL;
|
||||
}
|
||||
if (rv[PL]) {
|
||||
wpl = atoi(rv[PL]);
|
||||
wpl_p = true;
|
||||
result.config.wpl = atoi(rv[PL]);
|
||||
result.config.wpl_p = true;
|
||||
rv[PL] = NULL;
|
||||
}
|
||||
break;
|
||||
case 'b': /* bytes per packet */
|
||||
if (is_intpos(optarg))
|
||||
packet_size = atoi(optarg);
|
||||
else
|
||||
if (is_intpos(optarg)) {
|
||||
result.config.packet_size = atoi(optarg);
|
||||
} else {
|
||||
usage(_("Packet size must be a positive integer"));
|
||||
}
|
||||
break;
|
||||
case 'n': /* number of packets */
|
||||
if (is_intpos(optarg))
|
||||
packet_count = atoi(optarg);
|
||||
else
|
||||
if (is_intpos(optarg)) {
|
||||
result.config.packet_count = atoi(optarg);
|
||||
} else {
|
||||
usage(_("Packet count must be a positive integer"));
|
||||
}
|
||||
break;
|
||||
case 'T': /* timeout in msec */
|
||||
if (is_intpos(optarg))
|
||||
target_timeout = atoi(optarg);
|
||||
else
|
||||
if (is_intpos(optarg)) {
|
||||
result.config.target_timeout = atoi(optarg);
|
||||
} else {
|
||||
usage(_("Target timeout must be a positive integer"));
|
||||
}
|
||||
break;
|
||||
case 'i': /* interval in msec */
|
||||
if (is_intpos(optarg))
|
||||
packet_interval = atoi(optarg);
|
||||
else
|
||||
if (is_intpos(optarg)) {
|
||||
result.config.packet_interval = atoi(optarg);
|
||||
} else {
|
||||
usage(_("Interval must be a positive integer"));
|
||||
}
|
||||
break;
|
||||
case 'R':
|
||||
randomize_packet_data = true;
|
||||
result.config.randomize_packet_data = true;
|
||||
break;
|
||||
case 'M':
|
||||
dontfrag = true;
|
||||
result.config.dontfrag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (server_name == NULL)
|
||||
if (result.config.server_name == NULL) {
|
||||
usage4(_("Hostname was not supplied"));
|
||||
}
|
||||
|
||||
return OK;
|
||||
return result;
|
||||
}
|
||||
|
||||
int get_threshold(char *arg, char *rv[2]) {
|
||||
char *arg1 = NULL;
|
||||
char *arg2 = NULL;
|
||||
|
||||
arg1 = strscpy(arg1, arg);
|
||||
if (strpbrk(arg1, ",:"))
|
||||
char *arg1 = strdup(arg);
|
||||
if (strpbrk(arg1, ",:")) {
|
||||
arg2 = 1 + strpbrk(arg1, ",:");
|
||||
}
|
||||
|
||||
if (arg2) {
|
||||
arg1[strcspn(arg1, ",:")] = 0;
|
||||
if (strstr(arg1, "%") && strstr(arg2, "%"))
|
||||
if (strstr(arg1, "%") && strstr(arg2, "%")) {
|
||||
die(STATE_UNKNOWN, _("%s: Only one threshold may be packet loss (%s)\n"), progname, arg);
|
||||
if (!strstr(arg1, "%") && !strstr(arg2, "%"))
|
||||
}
|
||||
if (!strstr(arg1, "%") && !strstr(arg2, "%")) {
|
||||
die(STATE_UNKNOWN, _("%s: Only one threshold must be packet loss (%s)\n"), progname, arg);
|
||||
}
|
||||
}
|
||||
|
||||
if (arg2 && strstr(arg2, "%")) {
|
||||
|
|
|
|||
58
plugins/check_fping.d/config.h
Normal file
58
plugins/check_fping.d/config.h
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../config.h"
|
||||
#include <stddef.h>
|
||||
|
||||
enum {
|
||||
PACKET_SIZE = 56,
|
||||
PACKET_COUNT = 1,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
char *server_name;
|
||||
char *sourceip;
|
||||
char *sourceif;
|
||||
int packet_size;
|
||||
int packet_count;
|
||||
int target_timeout;
|
||||
int packet_interval;
|
||||
bool randomize_packet_data;
|
||||
bool dontfrag;
|
||||
bool alive_p;
|
||||
|
||||
double crta;
|
||||
bool crta_p;
|
||||
double wrta;
|
||||
bool wrta_p;
|
||||
|
||||
int cpl;
|
||||
bool cpl_p;
|
||||
int wpl;
|
||||
bool wpl_p;
|
||||
} check_fping_config;
|
||||
|
||||
check_fping_config check_fping_config_init() {
|
||||
check_fping_config tmp = {
|
||||
.server_name = NULL,
|
||||
.sourceip = NULL,
|
||||
.sourceif = NULL,
|
||||
.packet_size = PACKET_SIZE,
|
||||
.packet_count = PACKET_COUNT,
|
||||
.target_timeout = 0,
|
||||
.packet_interval = 0,
|
||||
.randomize_packet_data = false,
|
||||
.dontfrag = false,
|
||||
.alive_p = false,
|
||||
|
||||
.crta = 0,
|
||||
.crta_p = false,
|
||||
.wrta = 0,
|
||||
.wrta_p = false,
|
||||
|
||||
.cpl = 0,
|
||||
.cpl_p = false,
|
||||
.wpl = 0,
|
||||
.wpl_p = false,
|
||||
};
|
||||
return tmp;
|
||||
}
|
||||
|
|
@ -36,9 +36,15 @@ const char *email = "devel@monitoring-plugins.org";
|
|||
#include "common.h"
|
||||
#include "utils.h"
|
||||
#include "runcmd.h"
|
||||
#include "check_game.d/config.h"
|
||||
#include "../lib/monitoringplug.h"
|
||||
|
||||
static int process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
static int validate_arguments(void);
|
||||
typedef struct {
|
||||
int errorcode;
|
||||
check_game_config config;
|
||||
} check_game_config_wrapper;
|
||||
|
||||
static check_game_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
static void print_help(void);
|
||||
void print_usage(void);
|
||||
|
||||
|
|
@ -49,26 +55,9 @@ void print_usage(void);
|
|||
#define QSTAT_HOST_TIMEOUT "TIMEOUT"
|
||||
#define QSTAT_MAX_RETURN_ARGS 12
|
||||
|
||||
static char *server_ip;
|
||||
static char *game_type;
|
||||
static int port = 0;
|
||||
|
||||
static bool verbose = false;
|
||||
|
||||
static int qstat_game_players_max = -1;
|
||||
static int qstat_game_players = -1;
|
||||
static int qstat_game_field = -1;
|
||||
static int qstat_map_field = -1;
|
||||
static int qstat_ping_field = -1;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
char *command_line;
|
||||
int result = STATE_UNKNOWN;
|
||||
char *p;
|
||||
char *ret[QSTAT_MAX_RETURN_ARGS];
|
||||
size_t i = 0;
|
||||
output chld_out;
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
textdomain(PACKAGE);
|
||||
|
|
@ -76,22 +65,31 @@ int main(int argc, char **argv) {
|
|||
/* Parse extra opts if any */
|
||||
argv = np_extra_opts(&argc, argv, progname);
|
||||
|
||||
if (process_arguments(argc, argv) == ERROR)
|
||||
usage_va(_("Could not parse arguments"));
|
||||
check_game_config_wrapper tmp = process_arguments(argc, argv);
|
||||
|
||||
result = STATE_OK;
|
||||
if (tmp.errorcode == ERROR) {
|
||||
usage_va(_("Could not parse arguments"));
|
||||
}
|
||||
|
||||
check_game_config config = tmp.config;
|
||||
|
||||
mp_state_enum result = STATE_OK;
|
||||
|
||||
/* create the command line to execute */
|
||||
xasprintf(&command_line, "%s -raw %s -%s %s", PATH_TO_QSTAT, QSTAT_DATA_DELIMITER, game_type, server_ip);
|
||||
char *command_line = NULL;
|
||||
xasprintf(&command_line, "%s -raw %s -%s %s", PATH_TO_QSTAT, QSTAT_DATA_DELIMITER, config.game_type, config.server_ip);
|
||||
|
||||
if (port)
|
||||
xasprintf(&command_line, "%s:%-d", command_line, port);
|
||||
if (config.port) {
|
||||
xasprintf(&command_line, "%s:%-d", command_line, config.port);
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
printf("%s\n", command_line);
|
||||
}
|
||||
|
||||
/* run the command. historically, this plugin ignores output on stderr,
|
||||
* as well as return status of the qstat program */
|
||||
output chld_out = {};
|
||||
(void)np_runcmd(command_line, &chld_out, NULL, 0);
|
||||
|
||||
/* sanity check */
|
||||
|
|
@ -104,19 +102,22 @@ int main(int argc, char **argv) {
|
|||
In the end, I figured I'd simply let an error occur & then trap it
|
||||
*/
|
||||
|
||||
if (!strncmp(chld_out.line[0], "unknown option", 14)) {
|
||||
if (!strncmp(chld_out.line[0], "unknown option", strlen("unknown option"))) {
|
||||
printf(_("CRITICAL - Host type parameter incorrect!\n"));
|
||||
result = STATE_CRITICAL;
|
||||
return result;
|
||||
exit(result);
|
||||
}
|
||||
|
||||
p = (char *)strtok(chld_out.line[0], QSTAT_DATA_DELIMITER);
|
||||
while (p != NULL) {
|
||||
ret[i] = p;
|
||||
p = (char *)strtok(NULL, QSTAT_DATA_DELIMITER);
|
||||
char *ret[QSTAT_MAX_RETURN_ARGS];
|
||||
size_t i = 0;
|
||||
char *sequence = strtok(chld_out.line[0], QSTAT_DATA_DELIMITER);
|
||||
while (sequence != NULL) {
|
||||
ret[i] = sequence;
|
||||
sequence = strtok(NULL, QSTAT_DATA_DELIMITER);
|
||||
i++;
|
||||
if (i >= QSTAT_MAX_RETURN_ARGS)
|
||||
if (i >= QSTAT_MAX_RETURN_ARGS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (strstr(ret[2], QSTAT_HOST_ERROR)) {
|
||||
|
|
@ -129,19 +130,20 @@ int main(int argc, char **argv) {
|
|||
printf(_("CRITICAL - Game server timeout\n"));
|
||||
result = STATE_CRITICAL;
|
||||
} else {
|
||||
printf("OK: %s/%s %s (%s), Ping: %s ms|%s %s\n", ret[qstat_game_players], ret[qstat_game_players_max], ret[qstat_game_field],
|
||||
ret[qstat_map_field], ret[qstat_ping_field],
|
||||
perfdata("players", atol(ret[qstat_game_players]), "", false, 0, false, 0, true, 0, true, atol(ret[qstat_game_players_max])),
|
||||
fperfdata("ping", strtod(ret[qstat_ping_field], NULL), "", false, 0, false, 0, true, 0, false, 0));
|
||||
printf("OK: %s/%s %s (%s), Ping: %s ms|%s %s\n", ret[config.qstat_game_players], ret[config.qstat_game_players_max],
|
||||
ret[config.qstat_game_field], ret[config.qstat_map_field], ret[config.qstat_ping_field],
|
||||
perfdata("players", atol(ret[config.qstat_game_players]), "", false, 0, false, 0, true, 0, true,
|
||||
atol(ret[config.qstat_game_players_max])),
|
||||
fperfdata("ping", strtod(ret[config.qstat_ping_field], NULL), "", false, 0, false, 0, true, 0, false, 0));
|
||||
}
|
||||
|
||||
return result;
|
||||
exit(result);
|
||||
}
|
||||
|
||||
int process_arguments(int argc, char **argv) {
|
||||
int c;
|
||||
#define players_field_index 129
|
||||
#define max_players_field_index 130
|
||||
|
||||
int opt_index = 0;
|
||||
check_game_config_wrapper process_arguments(int argc, char **argv) {
|
||||
static struct option long_opts[] = {{"help", no_argument, 0, 'h'},
|
||||
{"version", no_argument, 0, 'V'},
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
|
|
@ -152,29 +154,39 @@ int process_arguments(int argc, char **argv) {
|
|||
{"map-field", required_argument, 0, 'm'},
|
||||
{"ping-field", required_argument, 0, 'p'},
|
||||
{"game-field", required_argument, 0, 'g'},
|
||||
{"players-field", required_argument, 0, 129},
|
||||
{"max-players-field", required_argument, 0, 130},
|
||||
{"players-field", required_argument, 0, players_field_index},
|
||||
{"max-players-field", required_argument, 0, max_players_field_index},
|
||||
{0, 0, 0, 0}};
|
||||
|
||||
if (argc < 2)
|
||||
return ERROR;
|
||||
check_game_config_wrapper result = {
|
||||
.config = check_game_config_init(),
|
||||
.errorcode = OK,
|
||||
};
|
||||
|
||||
for (c = 1; c < argc; c++) {
|
||||
if (strcmp("-mf", argv[c]) == 0)
|
||||
strcpy(argv[c], "-m");
|
||||
else if (strcmp("-pf", argv[c]) == 0)
|
||||
strcpy(argv[c], "-p");
|
||||
else if (strcmp("-gf", argv[c]) == 0)
|
||||
strcpy(argv[c], "-g");
|
||||
if (argc < 2) {
|
||||
result.errorcode = ERROR;
|
||||
return result;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
c = getopt_long(argc, argv, "hVvt:H:P:G:g:p:m:", long_opts, &opt_index);
|
||||
for (int option_counter = 1; option_counter < argc; option_counter++) {
|
||||
if (strcmp("-mf", argv[option_counter]) == 0) {
|
||||
strcpy(argv[option_counter], "-m");
|
||||
} else if (strcmp("-pf", argv[option_counter]) == 0) {
|
||||
strcpy(argv[option_counter], "-p");
|
||||
} else if (strcmp("-gf", argv[option_counter]) == 0) {
|
||||
strcpy(argv[option_counter], "-g");
|
||||
}
|
||||
}
|
||||
|
||||
if (c == -1 || c == EOF)
|
||||
int opt_index = 0;
|
||||
while (true) {
|
||||
int option_index = getopt_long(argc, argv, "hVvt:H:P:G:g:p:m:", long_opts, &opt_index);
|
||||
|
||||
if (option_index == -1 || option_index == EOF) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (c) {
|
||||
switch (option_index) {
|
||||
case 'h': /* help */
|
||||
print_help();
|
||||
exit(STATE_UNKNOWN);
|
||||
|
|
@ -188,79 +200,75 @@ int process_arguments(int argc, char **argv) {
|
|||
timeout_interval = atoi(optarg);
|
||||
break;
|
||||
case 'H': /* hostname */
|
||||
if (strlen(optarg) >= MAX_HOST_ADDRESS_LENGTH)
|
||||
if (strlen(optarg) >= MAX_HOST_ADDRESS_LENGTH) {
|
||||
die(STATE_UNKNOWN, _("Input buffer overflow\n"));
|
||||
server_ip = optarg;
|
||||
}
|
||||
result.config.server_ip = optarg;
|
||||
break;
|
||||
case 'P': /* port */
|
||||
port = atoi(optarg);
|
||||
result.config.port = atoi(optarg);
|
||||
break;
|
||||
case 'G': /* hostname */
|
||||
if (strlen(optarg) >= MAX_INPUT_BUFFER)
|
||||
if (strlen(optarg) >= MAX_INPUT_BUFFER) {
|
||||
die(STATE_UNKNOWN, _("Input buffer overflow\n"));
|
||||
game_type = optarg;
|
||||
}
|
||||
result.config.game_type = optarg;
|
||||
break;
|
||||
case 'p': /* index of ping field */
|
||||
qstat_ping_field = atoi(optarg);
|
||||
if (qstat_ping_field < 0 || qstat_ping_field > QSTAT_MAX_RETURN_ARGS)
|
||||
return ERROR;
|
||||
result.config.qstat_ping_field = atoi(optarg);
|
||||
if (result.config.qstat_ping_field < 0 || result.config.qstat_ping_field > QSTAT_MAX_RETURN_ARGS) {
|
||||
result.errorcode = ERROR;
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
case 'm': /* index on map field */
|
||||
qstat_map_field = atoi(optarg);
|
||||
if (qstat_map_field < 0 || qstat_map_field > QSTAT_MAX_RETURN_ARGS)
|
||||
return ERROR;
|
||||
result.config.qstat_map_field = atoi(optarg);
|
||||
if (result.config.qstat_map_field < 0 || result.config.qstat_map_field > QSTAT_MAX_RETURN_ARGS) {
|
||||
result.errorcode = ERROR;
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
case 'g': /* index of game field */
|
||||
qstat_game_field = atoi(optarg);
|
||||
if (qstat_game_field < 0 || qstat_game_field > QSTAT_MAX_RETURN_ARGS)
|
||||
return ERROR;
|
||||
result.config.qstat_game_field = atoi(optarg);
|
||||
if (result.config.qstat_game_field < 0 || result.config.qstat_game_field > QSTAT_MAX_RETURN_ARGS) {
|
||||
result.errorcode = ERROR;
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
case 129: /* index of player count field */
|
||||
qstat_game_players = atoi(optarg);
|
||||
if (qstat_game_players_max == 0)
|
||||
qstat_game_players_max = qstat_game_players - 1;
|
||||
if (qstat_game_players < 0 || qstat_game_players > QSTAT_MAX_RETURN_ARGS)
|
||||
return ERROR;
|
||||
case players_field_index: /* index of player count field */
|
||||
result.config.qstat_game_players = atoi(optarg);
|
||||
if (result.config.qstat_game_players_max == 0) {
|
||||
result.config.qstat_game_players_max = result.config.qstat_game_players - 1;
|
||||
}
|
||||
if (result.config.qstat_game_players < 0 || result.config.qstat_game_players > QSTAT_MAX_RETURN_ARGS) {
|
||||
result.errorcode = ERROR;
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
case 130: /* index of max players field */
|
||||
qstat_game_players_max = atoi(optarg);
|
||||
if (qstat_game_players_max < 0 || qstat_game_players_max > QSTAT_MAX_RETURN_ARGS)
|
||||
return ERROR;
|
||||
case max_players_field_index: /* index of max players field */
|
||||
result.config.qstat_game_players_max = atoi(optarg);
|
||||
if (result.config.qstat_game_players_max < 0 || result.config.qstat_game_players_max > QSTAT_MAX_RETURN_ARGS) {
|
||||
result.errorcode = ERROR;
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
default: /* args not parsable */
|
||||
usage5();
|
||||
}
|
||||
}
|
||||
|
||||
c = optind;
|
||||
int option_counter = optind;
|
||||
/* first option is the game type */
|
||||
if (!game_type && c < argc)
|
||||
game_type = strdup(argv[c++]);
|
||||
if (!result.config.game_type && option_counter < argc) {
|
||||
result.config.game_type = strdup(argv[option_counter++]);
|
||||
}
|
||||
|
||||
/* Second option is the server name */
|
||||
if (!server_ip && c < argc)
|
||||
server_ip = strdup(argv[c++]);
|
||||
if (!result.config.server_ip && option_counter < argc) {
|
||||
result.config.server_ip = strdup(argv[option_counter++]);
|
||||
}
|
||||
|
||||
return validate_arguments();
|
||||
}
|
||||
|
||||
int validate_arguments(void) {
|
||||
if (qstat_game_players_max < 0)
|
||||
qstat_game_players_max = 4;
|
||||
|
||||
if (qstat_game_players < 0)
|
||||
qstat_game_players = 5;
|
||||
|
||||
if (qstat_game_field < 0)
|
||||
qstat_game_field = 2;
|
||||
|
||||
if (qstat_map_field < 0)
|
||||
qstat_map_field = 3;
|
||||
|
||||
if (qstat_ping_field < 0)
|
||||
qstat_ping_field = 5;
|
||||
|
||||
return OK;
|
||||
return result;
|
||||
}
|
||||
|
||||
void print_help(void) {
|
||||
|
|
@ -277,14 +285,15 @@ void print_help(void) {
|
|||
|
||||
printf(UT_HELP_VRSN);
|
||||
printf(UT_EXTRA_OPTS);
|
||||
|
||||
printf(" %s\n", "-p");
|
||||
printf(" %s\n", _("Optional port of which to connect"));
|
||||
printf(" %s\n", "gf");
|
||||
printf(" -H, --hostname=ADDRESS\n"
|
||||
" Host name, IP Address, or unix socket (must be an absolute path)\n");
|
||||
printf(" %s\n", "-P");
|
||||
printf(" %s\n", _("Optional port to connect to"));
|
||||
printf(" %s\n", "-g");
|
||||
printf(" %s\n", _("Field number in raw qstat output that contains game name"));
|
||||
printf(" %s\n", "-mf");
|
||||
printf(" %s\n", "-m");
|
||||
printf(" %s\n", _("Field number in raw qstat output that contains map name"));
|
||||
printf(" %s\n", "-pf");
|
||||
printf(" %s\n", "-p");
|
||||
printf(" %s\n", _("Field number in raw qstat output that contains ping time"));
|
||||
|
||||
printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
|
||||
|
|
|
|||
30
plugins/check_game.d/config.h
Normal file
30
plugins/check_game.d/config.h
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#pragma once
|
||||
#include "../../config.h"
|
||||
#include <stddef.h>
|
||||
|
||||
typedef struct {
|
||||
char *server_ip;
|
||||
char *game_type;
|
||||
int port;
|
||||
|
||||
int qstat_game_players_max;
|
||||
int qstat_game_players;
|
||||
int qstat_game_field;
|
||||
int qstat_map_field;
|
||||
int qstat_ping_field;
|
||||
} check_game_config;
|
||||
|
||||
check_game_config check_game_config_init() {
|
||||
check_game_config tmp = {
|
||||
.server_ip = NULL,
|
||||
.game_type = NULL,
|
||||
.port = 0,
|
||||
|
||||
.qstat_game_players_max = 4,
|
||||
.qstat_game_players = 5,
|
||||
.qstat_map_field = 3,
|
||||
.qstat_game_field = 2,
|
||||
.qstat_ping_field = 5,
|
||||
};
|
||||
return tmp;
|
||||
}
|
||||
|
|
@ -37,9 +37,10 @@ const char *email = "devel@monitoring-plugins.org";
|
|||
#include "popen.h"
|
||||
#include "utils.h"
|
||||
#include "netutils.h"
|
||||
#include "states.h"
|
||||
#include "check_hpjd.d/config.h"
|
||||
|
||||
#define DEFAULT_COMMUNITY "public"
|
||||
#define DEFAULT_PORT "161"
|
||||
|
||||
#define HPJD_LINE_STATUS ".1.3.6.1.4.1.11.2.3.9.1.1.2.1"
|
||||
#define HPJD_PAPER_STATUS ".1.3.6.1.4.1.11.2.3.9.1.1.2.2"
|
||||
|
|
@ -57,39 +58,15 @@ const char *email = "devel@monitoring-plugins.org";
|
|||
#define ONLINE 0
|
||||
#define OFFLINE 1
|
||||
|
||||
static int process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
static int validate_arguments(void);
|
||||
typedef struct {
|
||||
int errorcode;
|
||||
check_hpjd_config config;
|
||||
} check_hpjd_config_wrapper;
|
||||
static check_hpjd_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
static void print_help(void);
|
||||
void print_usage(void);
|
||||
|
||||
static char *community = NULL;
|
||||
static char *address = NULL;
|
||||
static unsigned int port = 0;
|
||||
static int check_paper_out = 1;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
char command_line[1024];
|
||||
int result = STATE_UNKNOWN;
|
||||
int line;
|
||||
char input_buffer[MAX_INPUT_BUFFER];
|
||||
char query_string[512];
|
||||
char *errmsg;
|
||||
char *temp_buffer;
|
||||
int line_status = ONLINE;
|
||||
int paper_status = 0;
|
||||
int intervention_required = 0;
|
||||
int peripheral_error = 0;
|
||||
int paper_jam = 0;
|
||||
int paper_out = 0;
|
||||
int toner_low = 0;
|
||||
int page_punt = 0;
|
||||
int memory_out = 0;
|
||||
int door_open = 0;
|
||||
int paper_output = 0;
|
||||
char display_message[MAX_INPUT_BUFFER];
|
||||
|
||||
errmsg = malloc(MAX_INPUT_BUFFER);
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
textdomain(PACKAGE);
|
||||
|
|
@ -97,9 +74,15 @@ int main(int argc, char **argv) {
|
|||
/* Parse extra opts if any */
|
||||
argv = np_extra_opts(&argc, argv, progname);
|
||||
|
||||
if (process_arguments(argc, argv) == ERROR)
|
||||
usage4(_("Could not parse arguments"));
|
||||
check_hpjd_config_wrapper tmp_config = process_arguments(argc, argv);
|
||||
|
||||
if (tmp_config.errorcode == ERROR) {
|
||||
usage4(_("Could not parse arguments"));
|
||||
}
|
||||
|
||||
const check_hpjd_config config = tmp_config.config;
|
||||
|
||||
char query_string[512];
|
||||
/* removed ' 2>1' at end of command 10/27/1999 - EG */
|
||||
/* create the query string */
|
||||
sprintf(query_string, "%s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0", HPJD_LINE_STATUS, HPJD_PAPER_STATUS,
|
||||
|
|
@ -107,7 +90,8 @@ int main(int argc, char **argv) {
|
|||
HPJD_GD_PAGE_PUNT, HPJD_GD_MEMORY_OUT, HPJD_GD_DOOR_OPEN, HPJD_GD_PAPER_OUTPUT, HPJD_GD_STATUS_DISPLAY);
|
||||
|
||||
/* get the command to run */
|
||||
sprintf(command_line, "%s -OQa -m : -v 1 -c %s %s:%u %s", PATH_TO_SNMPGET, community, address, port, query_string);
|
||||
char command_line[1024];
|
||||
sprintf(command_line, "%s -OQa -m : -v 1 -c %s %s:%u %s", PATH_TO_SNMPGET, config.community, config.address, config.port, query_string);
|
||||
|
||||
/* run the command */
|
||||
child_process = spopen(command_line);
|
||||
|
|
@ -121,29 +105,41 @@ int main(int argc, char **argv) {
|
|||
printf(_("Could not open stderr for %s\n"), command_line);
|
||||
}
|
||||
|
||||
result = STATE_OK;
|
||||
mp_state_enum result = STATE_OK;
|
||||
|
||||
int line_status = ONLINE;
|
||||
int paper_status = 0;
|
||||
int intervention_required = 0;
|
||||
int peripheral_error = 0;
|
||||
int paper_jam = 0;
|
||||
int paper_out = 0;
|
||||
int toner_low = 0;
|
||||
int page_punt = 0;
|
||||
int memory_out = 0;
|
||||
int door_open = 0;
|
||||
int paper_output = 0;
|
||||
char display_message[MAX_INPUT_BUFFER];
|
||||
|
||||
char input_buffer[MAX_INPUT_BUFFER];
|
||||
char *errmsg = malloc(MAX_INPUT_BUFFER);
|
||||
int line = 0;
|
||||
|
||||
line = 0;
|
||||
while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_process)) {
|
||||
|
||||
/* strip the newline character from the end of the input */
|
||||
if (input_buffer[strlen(input_buffer) - 1] == '\n')
|
||||
if (input_buffer[strlen(input_buffer) - 1] == '\n') {
|
||||
input_buffer[strlen(input_buffer) - 1] = 0;
|
||||
}
|
||||
|
||||
line++;
|
||||
|
||||
temp_buffer = strtok(input_buffer, "=");
|
||||
char *temp_buffer = strtok(input_buffer, "=");
|
||||
temp_buffer = strtok(NULL, "=");
|
||||
|
||||
if (temp_buffer == NULL && line < 13) {
|
||||
|
||||
result = STATE_UNKNOWN;
|
||||
strcpy(errmsg, input_buffer);
|
||||
|
||||
} else {
|
||||
|
||||
switch (line) {
|
||||
|
||||
case 1: /* 1st line should contain the line status */
|
||||
line_status = atoi(temp_buffer);
|
||||
break;
|
||||
|
|
@ -186,16 +182,18 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
/* break out of the read loop if we encounter an error */
|
||||
if (result != STATE_OK)
|
||||
if (result != STATE_OK) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* WARNING if output found on stderr */
|
||||
if (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) {
|
||||
result = max_state(result, STATE_WARNING);
|
||||
/* remove CRLF */
|
||||
if (input_buffer[strlen(input_buffer) - 1] == '\n')
|
||||
if (input_buffer[strlen(input_buffer) - 1] == '\n') {
|
||||
input_buffer[strlen(input_buffer) - 1] = 0;
|
||||
}
|
||||
sprintf(errmsg, "%s", input_buffer);
|
||||
}
|
||||
|
||||
|
|
@ -203,15 +201,15 @@ int main(int argc, char **argv) {
|
|||
(void)fclose(child_stderr);
|
||||
|
||||
/* close the pipe */
|
||||
if (spclose(child_process))
|
||||
if (spclose(child_process)) {
|
||||
result = max_state(result, STATE_WARNING);
|
||||
}
|
||||
|
||||
/* if there wasn't any output, display an error */
|
||||
if (line == 0) {
|
||||
|
||||
/* might not be the problem, but most likely is. */
|
||||
result = STATE_UNKNOWN;
|
||||
xasprintf(&errmsg, "%s : Timeout from host %s\n", errmsg, address);
|
||||
xasprintf(&errmsg, "%s : Timeout from host %s\n", errmsg, config.address);
|
||||
}
|
||||
|
||||
/* if we had no read errors, check the printer status results... */
|
||||
|
|
@ -221,8 +219,9 @@ int main(int argc, char **argv) {
|
|||
result = STATE_WARNING;
|
||||
strcpy(errmsg, _("Paper Jam"));
|
||||
} else if (paper_out) {
|
||||
if (check_paper_out)
|
||||
if (config.check_paper_out) {
|
||||
result = STATE_WARNING;
|
||||
}
|
||||
strcpy(errmsg, _("Out of Paper"));
|
||||
} else if (line_status == OFFLINE) {
|
||||
if (strcmp(errmsg, "POWERSAVE ON") != 0) {
|
||||
|
|
@ -256,29 +255,23 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
}
|
||||
|
||||
if (result == STATE_OK)
|
||||
if (result == STATE_OK) {
|
||||
printf(_("Printer ok - (%s)\n"), display_message);
|
||||
|
||||
else if (result == STATE_UNKNOWN) {
|
||||
|
||||
} else if (result == STATE_UNKNOWN) {
|
||||
printf("%s\n", errmsg);
|
||||
|
||||
/* if printer could not be reached, escalate to critical */
|
||||
if (strstr(errmsg, "Timeout"))
|
||||
if (strstr(errmsg, "Timeout")) {
|
||||
result = STATE_CRITICAL;
|
||||
}
|
||||
} else if (result == STATE_WARNING) {
|
||||
printf("%s (%s)\n", errmsg, display_message);
|
||||
}
|
||||
|
||||
else if (result == STATE_WARNING)
|
||||
printf("%s (%s)\n", errmsg, display_message);
|
||||
|
||||
return result;
|
||||
exit(result);
|
||||
}
|
||||
|
||||
/* process command-line arguments */
|
||||
int process_arguments(int argc, char **argv) {
|
||||
int c;
|
||||
|
||||
int option = 0;
|
||||
check_hpjd_config_wrapper process_arguments(int argc, char **argv) {
|
||||
static struct option longopts[] = {{"hostname", required_argument, 0, 'H'},
|
||||
{"community", required_argument, 0, 'C'},
|
||||
/* {"critical", required_argument,0,'c'}, */
|
||||
|
|
@ -288,34 +281,44 @@ int process_arguments(int argc, char **argv) {
|
|||
{"help", no_argument, 0, 'h'},
|
||||
{0, 0, 0, 0}};
|
||||
|
||||
if (argc < 2)
|
||||
return ERROR;
|
||||
check_hpjd_config_wrapper result = {
|
||||
.errorcode = OK,
|
||||
.config = check_hpjd_config_init(),
|
||||
};
|
||||
|
||||
while (1) {
|
||||
c = getopt_long(argc, argv, "+hVH:C:p:D", longopts, &option);
|
||||
if (argc < 2) {
|
||||
result.errorcode = ERROR;
|
||||
return result;
|
||||
}
|
||||
|
||||
if (c == -1 || c == EOF || c == 1)
|
||||
int option = 0;
|
||||
while (true) {
|
||||
int option_index = getopt_long(argc, argv, "+hVH:C:p:D", longopts, &option);
|
||||
|
||||
if (option_index == -1 || option_index == EOF || option_index == 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (c) {
|
||||
switch (option_index) {
|
||||
case 'H': /* hostname */
|
||||
if (is_host(optarg)) {
|
||||
address = strscpy(address, optarg);
|
||||
result.config.address = strscpy(result.config.address, optarg);
|
||||
} else {
|
||||
usage2(_("Invalid hostname/address"), optarg);
|
||||
}
|
||||
break;
|
||||
case 'C': /* community */
|
||||
community = strscpy(community, optarg);
|
||||
result.config.community = strscpy(result.config.community, optarg);
|
||||
break;
|
||||
case 'p':
|
||||
if (!is_intpos(optarg))
|
||||
if (!is_intpos(optarg)) {
|
||||
usage2(_("Port must be a positive short integer"), optarg);
|
||||
else
|
||||
port = atoi(optarg);
|
||||
} else {
|
||||
result.config.port = atoi(optarg);
|
||||
}
|
||||
break;
|
||||
case 'D': /* disable paper out check*/
|
||||
check_paper_out = 0;
|
||||
result.config.check_paper_out = false;
|
||||
break;
|
||||
case 'V': /* version */
|
||||
print_revision(progname, NP_VERSION);
|
||||
|
|
@ -328,31 +331,26 @@ int process_arguments(int argc, char **argv) {
|
|||
}
|
||||
}
|
||||
|
||||
c = optind;
|
||||
if (address == NULL) {
|
||||
int c = optind;
|
||||
if (result.config.address == NULL) {
|
||||
if (is_host(argv[c])) {
|
||||
address = argv[c++];
|
||||
result.config.address = argv[c++];
|
||||
} else {
|
||||
usage2(_("Invalid hostname/address"), argv[c]);
|
||||
}
|
||||
}
|
||||
|
||||
if (community == NULL) {
|
||||
if (argv[c] != NULL)
|
||||
community = argv[c];
|
||||
else
|
||||
community = strdup(DEFAULT_COMMUNITY);
|
||||
if (result.config.community == NULL) {
|
||||
if (argv[c] != NULL) {
|
||||
result.config.community = argv[c];
|
||||
} else {
|
||||
result.config.community = strdup(DEFAULT_COMMUNITY);
|
||||
}
|
||||
}
|
||||
|
||||
if (port == 0) {
|
||||
port = atoi(DEFAULT_PORT);
|
||||
}
|
||||
|
||||
return validate_arguments();
|
||||
return result;
|
||||
}
|
||||
|
||||
int validate_arguments(void) { return OK; }
|
||||
|
||||
void print_help(void) {
|
||||
print_revision(progname, NP_VERSION);
|
||||
|
||||
|
|
|
|||
25
plugins/check_hpjd.d/config.h
Normal file
25
plugins/check_hpjd.d/config.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../config.h"
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define DEFAULT_PORT "161"
|
||||
|
||||
typedef struct {
|
||||
char *address;
|
||||
char *community;
|
||||
unsigned int port;
|
||||
bool check_paper_out;
|
||||
|
||||
} check_hpjd_config;
|
||||
|
||||
check_hpjd_config check_hpjd_config_init() {
|
||||
check_hpjd_config tmp = {
|
||||
.address = NULL,
|
||||
.community = NULL,
|
||||
.port = (unsigned int)atoi(DEFAULT_PORT),
|
||||
.check_paper_out = true,
|
||||
};
|
||||
return tmp;
|
||||
}
|
||||
|
|
@ -1,30 +1,30 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* Monitoring check_ldap plugin
|
||||
*
|
||||
* License: GPL
|
||||
* Copyright (c) 2000-2024 Monitoring Plugins Development Team
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* This file contains the check_ldap plugin
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*****************************************************************************/
|
||||
*
|
||||
* Monitoring check_ldap plugin
|
||||
*
|
||||
* License: GPL
|
||||
* Copyright (c) 2000-2024 Monitoring Plugins Development Team
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* This file contains the check_ldap plugin
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* progname may be check_ldaps */
|
||||
char *progname = "check_ldap";
|
||||
|
|
@ -34,209 +34,178 @@ const char *email = "devel@monitoring-plugins.org";
|
|||
#include "common.h"
|
||||
#include "netutils.h"
|
||||
#include "utils.h"
|
||||
#include "check_ldap.d/config.h"
|
||||
|
||||
#include "states.h"
|
||||
#include <lber.h>
|
||||
#define LDAP_DEPRECATED 1
|
||||
#include <ldap.h>
|
||||
|
||||
enum {
|
||||
UNDEFINED = 0,
|
||||
#ifdef HAVE_LDAP_SET_OPTION
|
||||
DEFAULT_PROTOCOL = 2,
|
||||
#endif
|
||||
DEFAULT_PORT = 389
|
||||
};
|
||||
|
||||
static int process_arguments (int, char **);
|
||||
static int validate_arguments (void);
|
||||
static void print_help (void);
|
||||
void print_usage (void);
|
||||
typedef struct {
|
||||
int errorcode;
|
||||
check_ldap_config config;
|
||||
} check_ldap_config_wrapper;
|
||||
static check_ldap_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
static check_ldap_config_wrapper validate_arguments(check_ldap_config_wrapper /*config_wrapper*/);
|
||||
|
||||
static void print_help(void);
|
||||
void print_usage(void);
|
||||
|
||||
static char ld_defattr[] = "(objectclass=*)";
|
||||
static char *ld_attr = ld_defattr;
|
||||
static char *ld_host = NULL;
|
||||
static char *ld_base = NULL;
|
||||
static char *ld_passwd = NULL;
|
||||
static char *ld_binddn = NULL;
|
||||
static int ld_port = -1;
|
||||
#ifdef HAVE_LDAP_SET_OPTION
|
||||
static int ld_protocol = DEFAULT_PROTOCOL;
|
||||
#endif
|
||||
#ifndef LDAP_OPT_SUCCESS
|
||||
# define LDAP_OPT_SUCCESS LDAP_SUCCESS
|
||||
# define LDAP_OPT_SUCCESS LDAP_SUCCESS
|
||||
#endif
|
||||
static double warn_time = UNDEFINED;
|
||||
static double crit_time = UNDEFINED;
|
||||
static thresholds *entries_thresholds = NULL;
|
||||
static struct timeval tv;
|
||||
static char* warn_entries = NULL;
|
||||
static char* crit_entries = NULL;
|
||||
static bool starttls = false;
|
||||
static bool ssl_on_connect = false;
|
||||
static bool verbose = false;
|
||||
static int verbose = 0;
|
||||
|
||||
/* for ldap tls */
|
||||
int main(int argc, char *argv[]) {
|
||||
setlocale(LC_ALL, "");
|
||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
textdomain(PACKAGE);
|
||||
|
||||
static char *SERVICE = "LDAP";
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
|
||||
LDAP *ld;
|
||||
LDAPMessage *result;
|
||||
|
||||
/* should be int result = STATE_UNKNOWN; */
|
||||
|
||||
int status = STATE_UNKNOWN;
|
||||
long microsec;
|
||||
double elapsed_time;
|
||||
|
||||
/* for ldap tls */
|
||||
|
||||
int tls;
|
||||
int version=3;
|
||||
|
||||
int status_entries = STATE_OK;
|
||||
int num_entries = 0;
|
||||
|
||||
setlocale (LC_ALL, "");
|
||||
bindtextdomain (PACKAGE, LOCALEDIR);
|
||||
textdomain (PACKAGE);
|
||||
|
||||
if (strstr(argv[0],"check_ldaps")) {
|
||||
xasprintf (&progname, "check_ldaps");
|
||||
}
|
||||
if (strstr(argv[0], "check_ldaps")) {
|
||||
xasprintf(&progname, "check_ldaps");
|
||||
}
|
||||
|
||||
/* Parse extra opts if any */
|
||||
argv=np_extra_opts (&argc, argv, progname);
|
||||
argv = np_extra_opts(&argc, argv, progname);
|
||||
|
||||
if (process_arguments (argc, argv) == ERROR)
|
||||
usage4 (_("Could not parse arguments"));
|
||||
check_ldap_config_wrapper tmp_config = process_arguments(argc, argv);
|
||||
if (tmp_config.errorcode == ERROR) {
|
||||
usage4(_("Could not parse arguments"));
|
||||
}
|
||||
|
||||
if (strstr(argv[0],"check_ldaps") && ! starttls && ! ssl_on_connect)
|
||||
starttls = true;
|
||||
const check_ldap_config config = tmp_config.config;
|
||||
|
||||
/* initialize alarm signal handling */
|
||||
signal (SIGALRM, socket_timeout_alarm_handler);
|
||||
signal(SIGALRM, socket_timeout_alarm_handler);
|
||||
|
||||
/* set socket timeout */
|
||||
alarm (socket_timeout);
|
||||
alarm(socket_timeout);
|
||||
|
||||
/* get the start time */
|
||||
gettimeofday (&tv, NULL);
|
||||
struct timeval start_time;
|
||||
gettimeofday(&start_time, NULL);
|
||||
|
||||
LDAP *ldap_connection;
|
||||
/* initialize ldap */
|
||||
#ifdef HAVE_LDAP_INIT
|
||||
if (!(ld = ldap_init (ld_host, ld_port))) {
|
||||
printf ("Could not connect to the server at port %i\n", ld_port);
|
||||
if (!(ldap_connection = ldap_init(config.ld_host, config.ld_port))) {
|
||||
printf("Could not connect to the server at port %i\n", config.ld_port);
|
||||
return STATE_CRITICAL;
|
||||
}
|
||||
#else
|
||||
if (!(ld = ldap_open (ld_host, ld_port))) {
|
||||
if (verbose)
|
||||
ldap_perror(ld, "ldap_open");
|
||||
printf (_("Could not connect to the server at port %i\n"), ld_port);
|
||||
if (!(ld = ldap_open(config.ld_host, config.ld_port))) {
|
||||
if (verbose) {
|
||||
ldap_perror(ldap_connection, "ldap_open");
|
||||
}
|
||||
printf(_("Could not connect to the server at port %i\n"), config.ld_port);
|
||||
return STATE_CRITICAL;
|
||||
}
|
||||
#endif /* HAVE_LDAP_INIT */
|
||||
|
||||
#ifdef HAVE_LDAP_SET_OPTION
|
||||
/* set ldap options */
|
||||
if (ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, &ld_protocol) !=
|
||||
LDAP_OPT_SUCCESS ) {
|
||||
printf(_("Could not set protocol version %d\n"), ld_protocol);
|
||||
if (ldap_set_option(ldap_connection, LDAP_OPT_PROTOCOL_VERSION, &config.ld_protocol) != LDAP_OPT_SUCCESS) {
|
||||
printf(_("Could not set protocol version %d\n"), config.ld_protocol);
|
||||
return STATE_CRITICAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ld_port == LDAPS_PORT || ssl_on_connect) {
|
||||
xasprintf (&SERVICE, "LDAPS");
|
||||
int version = 3;
|
||||
int tls;
|
||||
if (config.ld_port == LDAPS_PORT || config.ssl_on_connect) {
|
||||
#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_X_TLS)
|
||||
/* ldaps: set option tls */
|
||||
tls = LDAP_OPT_X_TLS_HARD;
|
||||
|
||||
if (ldap_set_option (ld, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS)
|
||||
{
|
||||
if (verbose)
|
||||
ldap_perror(ld, "ldaps_option");
|
||||
printf (_("Could not init TLS at port %i!\n"), ld_port);
|
||||
if (ldap_set_option(ldap_connection, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS) {
|
||||
if (verbose) {
|
||||
ldap_perror(ldap_connection, "ldaps_option");
|
||||
}
|
||||
printf(_("Could not init TLS at port %i!\n"), config.ld_port);
|
||||
return STATE_CRITICAL;
|
||||
}
|
||||
#else
|
||||
printf (_("TLS not supported by the libraries!\n"));
|
||||
printf(_("TLS not supported by the libraries!\n"));
|
||||
return STATE_CRITICAL;
|
||||
#endif /* LDAP_OPT_X_TLS */
|
||||
} else if (starttls) {
|
||||
xasprintf (&SERVICE, "LDAP-TLS");
|
||||
} else if (config.starttls) {
|
||||
#if defined(HAVE_LDAP_SET_OPTION) && defined(HAVE_LDAP_START_TLS_S)
|
||||
/* ldap with startTLS: set option version */
|
||||
if (ldap_get_option(ld,LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS )
|
||||
{
|
||||
if (version < LDAP_VERSION3)
|
||||
{
|
||||
if (ldap_get_option(ldap_connection, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS) {
|
||||
if (version < LDAP_VERSION3) {
|
||||
version = LDAP_VERSION3;
|
||||
ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version);
|
||||
ldap_set_option(ldap_connection, LDAP_OPT_PROTOCOL_VERSION, &version);
|
||||
}
|
||||
}
|
||||
/* call start_tls */
|
||||
if (ldap_start_tls_s(ld, NULL, NULL) != LDAP_SUCCESS)
|
||||
{
|
||||
if (verbose)
|
||||
ldap_perror(ld, "ldap_start_tls");
|
||||
printf (_("Could not init startTLS at port %i!\n"), ld_port);
|
||||
if (ldap_start_tls_s(ldap_connection, NULL, NULL) != LDAP_SUCCESS) {
|
||||
if (verbose) {
|
||||
ldap_perror(ldap_connection, "ldap_start_tls");
|
||||
}
|
||||
printf(_("Could not init startTLS at port %i!\n"), config.ld_port);
|
||||
return STATE_CRITICAL;
|
||||
}
|
||||
#else
|
||||
printf (_("startTLS not supported by the library, needs LDAPv3!\n"));
|
||||
printf(_("startTLS not supported by the library, needs LDAPv3!\n"));
|
||||
return STATE_CRITICAL;
|
||||
#endif /* HAVE_LDAP_START_TLS_S */
|
||||
}
|
||||
|
||||
/* bind to the ldap server */
|
||||
if (ldap_bind_s (ld, ld_binddn, ld_passwd, LDAP_AUTH_SIMPLE) !=
|
||||
LDAP_SUCCESS) {
|
||||
if (verbose)
|
||||
ldap_perror(ld, "ldap_bind");
|
||||
printf (_("Could not bind to the LDAP server\n"));
|
||||
if (ldap_bind_s(ldap_connection, config.ld_binddn, config.ld_passwd, LDAP_AUTH_SIMPLE) != LDAP_SUCCESS) {
|
||||
if (verbose) {
|
||||
ldap_perror(ldap_connection, "ldap_bind");
|
||||
}
|
||||
printf(_("Could not bind to the LDAP server\n"));
|
||||
return STATE_CRITICAL;
|
||||
}
|
||||
|
||||
LDAPMessage *result;
|
||||
int num_entries = 0;
|
||||
/* do a search of all objectclasses in the base dn */
|
||||
if (ldap_search_s (ld, ld_base, (crit_entries!=NULL || warn_entries!=NULL) ? LDAP_SCOPE_SUBTREE : LDAP_SCOPE_BASE, ld_attr, NULL, 0, &result)
|
||||
!= LDAP_SUCCESS) {
|
||||
if (verbose)
|
||||
ldap_perror(ld, "ldap_search");
|
||||
printf (_("Could not search/find objectclasses in %s\n"), ld_base);
|
||||
if (ldap_search_s(ldap_connection, config.ld_base,
|
||||
(config.crit_entries != NULL || config.warn_entries != NULL) ? LDAP_SCOPE_SUBTREE : LDAP_SCOPE_BASE, config.ld_attr,
|
||||
NULL, 0, &result) != LDAP_SUCCESS) {
|
||||
if (verbose) {
|
||||
ldap_perror(ldap_connection, "ldap_search");
|
||||
}
|
||||
printf(_("Could not search/find objectclasses in %s\n"), config.ld_base);
|
||||
return STATE_CRITICAL;
|
||||
} else if (crit_entries!=NULL || warn_entries!=NULL) {
|
||||
num_entries = ldap_count_entries(ld, result);
|
||||
}
|
||||
|
||||
if (config.crit_entries != NULL || config.warn_entries != NULL) {
|
||||
num_entries = ldap_count_entries(ldap_connection, result);
|
||||
}
|
||||
|
||||
/* unbind from the ldap server */
|
||||
ldap_unbind (ld);
|
||||
ldap_unbind(ldap_connection);
|
||||
|
||||
/* reset the alarm handler */
|
||||
alarm (0);
|
||||
alarm(0);
|
||||
|
||||
/* calculate the elapsed time and compare to thresholds */
|
||||
|
||||
microsec = deltime (tv);
|
||||
elapsed_time = (double)microsec / 1.0e6;
|
||||
|
||||
if (crit_time!=UNDEFINED && elapsed_time>crit_time)
|
||||
long microsec = deltime(start_time);
|
||||
double elapsed_time = (double)microsec / 1.0e6;
|
||||
mp_state_enum status = STATE_UNKNOWN;
|
||||
if (config.crit_time_set && elapsed_time > config.crit_time) {
|
||||
status = STATE_CRITICAL;
|
||||
else if (warn_time!=UNDEFINED && elapsed_time>warn_time)
|
||||
} else if (config.warn_time_set && elapsed_time > config.warn_time) {
|
||||
status = STATE_WARNING;
|
||||
else
|
||||
} else {
|
||||
status = STATE_OK;
|
||||
}
|
||||
|
||||
if(entries_thresholds != NULL) {
|
||||
if (config.entries_thresholds != NULL) {
|
||||
if (verbose) {
|
||||
printf ("entries found: %d\n", num_entries);
|
||||
print_thresholds("entry thresholds", entries_thresholds);
|
||||
printf("entries found: %d\n", num_entries);
|
||||
print_thresholds("entry thresholds", config.entries_thresholds);
|
||||
}
|
||||
status_entries = get_status(num_entries, entries_thresholds);
|
||||
mp_state_enum status_entries = get_status(num_entries, config.entries_thresholds);
|
||||
if (status_entries == STATE_CRITICAL) {
|
||||
status = STATE_CRITICAL;
|
||||
} else if (status != STATE_CRITICAL) {
|
||||
|
|
@ -245,273 +214,272 @@ main (int argc, char *argv[])
|
|||
}
|
||||
|
||||
/* print out the result */
|
||||
if (crit_entries!=NULL || warn_entries!=NULL) {
|
||||
printf (_("LDAP %s - found %d entries in %.3f seconds|%s %s\n"),
|
||||
state_text (status),
|
||||
num_entries,
|
||||
elapsed_time,
|
||||
fperfdata ("time", elapsed_time, "s",
|
||||
(int)warn_time, warn_time,
|
||||
(int)crit_time, crit_time,
|
||||
true, 0, false, 0),
|
||||
sperfdata ("entries", (double)num_entries, "",
|
||||
warn_entries,
|
||||
crit_entries,
|
||||
true, 0.0, false, 0.0));
|
||||
if (config.crit_entries != NULL || config.warn_entries != NULL) {
|
||||
printf(_("LDAP %s - found %d entries in %.3f seconds|%s %s\n"), state_text(status), num_entries, elapsed_time,
|
||||
fperfdata("time", elapsed_time, "s", config.warn_time_set, config.warn_time, config.crit_time_set, config.crit_time, true, 0,
|
||||
false, 0),
|
||||
sperfdata("entries", (double)num_entries, "", config.warn_entries, config.crit_entries, true, 0.0, false, 0.0));
|
||||
} else {
|
||||
printf (_("LDAP %s - %.3f seconds response time|%s\n"),
|
||||
state_text (status),
|
||||
elapsed_time,
|
||||
fperfdata ("time", elapsed_time, "s",
|
||||
(int)warn_time, warn_time,
|
||||
(int)crit_time, crit_time,
|
||||
true, 0, false, 0));
|
||||
printf(_("LDAP %s - %.3f seconds response time|%s\n"), state_text(status), elapsed_time,
|
||||
fperfdata("time", elapsed_time, "s", config.warn_time_set, config.warn_time, config.crit_time_set, config.crit_time, true, 0,
|
||||
false, 0));
|
||||
}
|
||||
|
||||
return status;
|
||||
exit(status);
|
||||
}
|
||||
|
||||
/* process command-line arguments */
|
||||
int
|
||||
process_arguments (int argc, char **argv)
|
||||
{
|
||||
int c;
|
||||
|
||||
int option = 0;
|
||||
check_ldap_config_wrapper process_arguments(int argc, char **argv) {
|
||||
/* initialize the long option struct */
|
||||
static struct option longopts[] = {
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"version", no_argument, 0, 'V'},
|
||||
{"timeout", required_argument, 0, 't'},
|
||||
{"hostname", required_argument, 0, 'H'},
|
||||
{"base", required_argument, 0, 'b'},
|
||||
{"attr", required_argument, 0, 'a'},
|
||||
{"bind", required_argument, 0, 'D'},
|
||||
{"pass", required_argument, 0, 'P'},
|
||||
static struct option longopts[] = {{"help", no_argument, 0, 'h'},
|
||||
{"version", no_argument, 0, 'V'},
|
||||
{"timeout", required_argument, 0, 't'},
|
||||
{"hostname", required_argument, 0, 'H'},
|
||||
{"base", required_argument, 0, 'b'},
|
||||
{"attr", required_argument, 0, 'a'},
|
||||
{"bind", required_argument, 0, 'D'},
|
||||
{"pass", required_argument, 0, 'P'},
|
||||
#ifdef HAVE_LDAP_SET_OPTION
|
||||
{"ver2", no_argument, 0, '2'},
|
||||
{"ver3", no_argument, 0, '3'},
|
||||
{"ver2", no_argument, 0, '2'},
|
||||
{"ver3", no_argument, 0, '3'},
|
||||
#endif
|
||||
{"starttls", no_argument, 0, 'T'},
|
||||
{"ssl", no_argument, 0, 'S'},
|
||||
{"use-ipv4", no_argument, 0, '4'},
|
||||
{"use-ipv6", no_argument, 0, '6'},
|
||||
{"port", required_argument, 0, 'p'},
|
||||
{"warn", required_argument, 0, 'w'},
|
||||
{"crit", required_argument, 0, 'c'},
|
||||
{"warn-entries", required_argument, 0, 'W'},
|
||||
{"crit-entries", required_argument, 0, 'C'},
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
{0, 0, 0, 0}
|
||||
{"starttls", no_argument, 0, 'T'},
|
||||
{"ssl", no_argument, 0, 'S'},
|
||||
{"use-ipv4", no_argument, 0, '4'},
|
||||
{"use-ipv6", no_argument, 0, '6'},
|
||||
{"port", required_argument, 0, 'p'},
|
||||
{"warn", required_argument, 0, 'w'},
|
||||
{"crit", required_argument, 0, 'c'},
|
||||
{"warn-entries", required_argument, 0, 'W'},
|
||||
{"crit-entries", required_argument, 0, 'C'},
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
{0, 0, 0, 0}};
|
||||
|
||||
check_ldap_config_wrapper result = {
|
||||
.errorcode = OK,
|
||||
.config = check_ldap_config_init(),
|
||||
};
|
||||
|
||||
if (argc < 2)
|
||||
return ERROR;
|
||||
|
||||
for (c = 1; c < argc; c++) {
|
||||
if (strcmp ("-to", argv[c]) == 0)
|
||||
strcpy (argv[c], "-t");
|
||||
if (argc < 2) {
|
||||
result.errorcode = ERROR;
|
||||
return result;
|
||||
}
|
||||
|
||||
for (int index = 1; index < argc; index++) {
|
||||
if (strcmp("-to", argv[index]) == 0) {
|
||||
strcpy(argv[index], "-t");
|
||||
}
|
||||
}
|
||||
|
||||
int option = 0;
|
||||
while (true) {
|
||||
c = getopt_long (argc, argv, "hvV234TS6t:c:w:H:b:p:a:D:P:C:W:", longopts, &option);
|
||||
int option_index = getopt_long(argc, argv, "hvV234TS6t:c:w:H:b:p:a:D:P:C:W:", longopts, &option);
|
||||
|
||||
if (c == -1 || c == EOF)
|
||||
if (option_index == -1 || option_index == EOF) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (c) {
|
||||
case 'h': /* help */
|
||||
print_help ();
|
||||
exit (STATE_UNKNOWN);
|
||||
case 'V': /* version */
|
||||
print_revision (progname, NP_VERSION);
|
||||
exit (STATE_UNKNOWN);
|
||||
case 't': /* timeout period */
|
||||
if (!is_intnonneg (optarg))
|
||||
usage2 (_("Timeout interval must be a positive integer"), optarg);
|
||||
else
|
||||
socket_timeout = atoi (optarg);
|
||||
switch (option_index) {
|
||||
case 'h': /* help */
|
||||
print_help();
|
||||
exit(STATE_UNKNOWN);
|
||||
case 'V': /* version */
|
||||
print_revision(progname, NP_VERSION);
|
||||
exit(STATE_UNKNOWN);
|
||||
case 't': /* timeout period */
|
||||
if (!is_intnonneg(optarg)) {
|
||||
usage2(_("Timeout interval must be a positive integer"), optarg);
|
||||
} else {
|
||||
socket_timeout = atoi(optarg);
|
||||
}
|
||||
break;
|
||||
case 'H':
|
||||
ld_host = optarg;
|
||||
result.config.ld_host = optarg;
|
||||
break;
|
||||
case 'b':
|
||||
ld_base = optarg;
|
||||
result.config.ld_base = optarg;
|
||||
break;
|
||||
case 'p':
|
||||
ld_port = atoi (optarg);
|
||||
result.config.ld_port = atoi(optarg);
|
||||
break;
|
||||
case 'a':
|
||||
ld_attr = optarg;
|
||||
result.config.ld_attr = optarg;
|
||||
break;
|
||||
case 'D':
|
||||
ld_binddn = optarg;
|
||||
result.config.ld_binddn = optarg;
|
||||
break;
|
||||
case 'P':
|
||||
ld_passwd = optarg;
|
||||
result.config.ld_passwd = optarg;
|
||||
break;
|
||||
case 'w':
|
||||
warn_time = strtod (optarg, NULL);
|
||||
result.config.warn_time_set = true;
|
||||
result.config.warn_time = strtod(optarg, NULL);
|
||||
break;
|
||||
case 'c':
|
||||
crit_time = strtod (optarg, NULL);
|
||||
result.config.crit_time_set = true;
|
||||
result.config.crit_time = strtod(optarg, NULL);
|
||||
break;
|
||||
case 'W':
|
||||
warn_entries = optarg;
|
||||
result.config.warn_entries = optarg;
|
||||
break;
|
||||
case 'C':
|
||||
crit_entries = optarg;
|
||||
result.config.crit_entries = optarg;
|
||||
break;
|
||||
#ifdef HAVE_LDAP_SET_OPTION
|
||||
case '2':
|
||||
ld_protocol = 2;
|
||||
result.config.ld_protocol = 2;
|
||||
break;
|
||||
case '3':
|
||||
ld_protocol = 3;
|
||||
result.config.ld_protocol = 3;
|
||||
break;
|
||||
#endif
|
||||
#endif // HAVE_LDAP_SET_OPTION
|
||||
case '4':
|
||||
address_family = AF_INET;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = true;
|
||||
verbose++;
|
||||
break;
|
||||
case 'T':
|
||||
if (! ssl_on_connect)
|
||||
starttls = true;
|
||||
else
|
||||
if (!result.config.ssl_on_connect) {
|
||||
result.config.starttls = true;
|
||||
} else {
|
||||
usage_va(_("%s cannot be combined with %s"), "-T/--starttls", "-S/--ssl");
|
||||
}
|
||||
break;
|
||||
case 'S':
|
||||
if (! starttls) {
|
||||
ssl_on_connect = true;
|
||||
if (ld_port == -1)
|
||||
ld_port = LDAPS_PORT;
|
||||
} else
|
||||
if (!result.config.starttls) {
|
||||
result.config.ssl_on_connect = true;
|
||||
if (result.config.ld_port == -1) {
|
||||
result.config.ld_port = LDAPS_PORT;
|
||||
}
|
||||
} else {
|
||||
usage_va(_("%s cannot be combined with %s"), "-S/--ssl", "-T/--starttls");
|
||||
}
|
||||
break;
|
||||
case '6':
|
||||
#ifdef USE_IPV6
|
||||
address_family = AF_INET6;
|
||||
#else
|
||||
usage (_("IPv6 support not available\n"));
|
||||
usage(_("IPv6 support not available\n"));
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
usage5 ();
|
||||
usage5();
|
||||
}
|
||||
}
|
||||
|
||||
c = optind;
|
||||
if (ld_host == NULL && is_host(argv[c]))
|
||||
ld_host = strdup (argv[c++]);
|
||||
|
||||
if (ld_base == NULL && argv[c])
|
||||
ld_base = strdup (argv[c++]);
|
||||
|
||||
if (ld_port == -1)
|
||||
ld_port = DEFAULT_PORT;
|
||||
|
||||
return validate_arguments ();
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
validate_arguments ()
|
||||
{
|
||||
if (ld_host==NULL || strlen(ld_host)==0)
|
||||
usage4 (_("Please specify the host name\n"));
|
||||
|
||||
if (ld_base==NULL)
|
||||
usage4 (_("Please specify the LDAP base\n"));
|
||||
|
||||
if (crit_entries!=NULL || warn_entries!=NULL) {
|
||||
set_thresholds(&entries_thresholds,
|
||||
warn_entries, crit_entries);
|
||||
int index = optind;
|
||||
if ((result.config.ld_host == NULL) && is_host(argv[index])) {
|
||||
result.config.ld_host = strdup(argv[index++]);
|
||||
}
|
||||
if (ld_passwd==NULL)
|
||||
ld_passwd = getenv("LDAP_PASSWORD");
|
||||
|
||||
return OK;
|
||||
if ((result.config.ld_base == NULL) && argv[index]) {
|
||||
result.config.ld_base = strdup(argv[index++]);
|
||||
}
|
||||
|
||||
if (result.config.ld_port == -1) {
|
||||
result.config.ld_port = DEFAULT_PORT;
|
||||
}
|
||||
|
||||
if (strstr(argv[0], "check_ldaps") && !result.config.starttls && !result.config.ssl_on_connect) {
|
||||
result.config.starttls = true;
|
||||
}
|
||||
|
||||
return validate_arguments(result);
|
||||
}
|
||||
|
||||
check_ldap_config_wrapper validate_arguments(check_ldap_config_wrapper config_wrapper) {
|
||||
if (config_wrapper.config.ld_host == NULL || strlen(config_wrapper.config.ld_host) == 0) {
|
||||
usage4(_("Please specify the host name\n"));
|
||||
}
|
||||
|
||||
void
|
||||
print_help (void)
|
||||
{
|
||||
if (config_wrapper.config.ld_base == NULL) {
|
||||
usage4(_("Please specify the LDAP base\n"));
|
||||
}
|
||||
|
||||
if (config_wrapper.config.crit_entries != NULL || config_wrapper.config.warn_entries != NULL) {
|
||||
set_thresholds(&config_wrapper.config.entries_thresholds, config_wrapper.config.warn_entries, config_wrapper.config.crit_entries);
|
||||
}
|
||||
|
||||
if (config_wrapper.config.ld_passwd == NULL) {
|
||||
config_wrapper.config.ld_passwd = getenv("LDAP_PASSWORD");
|
||||
}
|
||||
|
||||
return config_wrapper;
|
||||
}
|
||||
|
||||
void print_help(void) {
|
||||
char *myport;
|
||||
xasprintf (&myport, "%d", DEFAULT_PORT);
|
||||
xasprintf(&myport, "%d", DEFAULT_PORT);
|
||||
|
||||
print_revision (progname, NP_VERSION);
|
||||
print_revision(progname, NP_VERSION);
|
||||
|
||||
printf ("Copyright (c) 1999 Didi Rieder (adrieder@sbox.tu-graz.ac.at)\n");
|
||||
printf (COPYRIGHT, copyright, email);
|
||||
printf("Copyright (c) 1999 Didi Rieder (adrieder@sbox.tu-graz.ac.at)\n");
|
||||
printf(COPYRIGHT, copyright, email);
|
||||
|
||||
printf ("\n\n");
|
||||
printf("\n\n");
|
||||
|
||||
print_usage ();
|
||||
print_usage();
|
||||
|
||||
printf (UT_HELP_VRSN);
|
||||
printf (UT_EXTRA_OPTS);
|
||||
printf(UT_HELP_VRSN);
|
||||
printf(UT_EXTRA_OPTS);
|
||||
|
||||
printf (UT_HOST_PORT, 'p', myport);
|
||||
printf(UT_HOST_PORT, 'p', myport);
|
||||
|
||||
printf (UT_IPv46);
|
||||
printf(UT_IPv46);
|
||||
|
||||
printf (" %s\n", "-a [--attr]");
|
||||
printf (" %s\n", _("ldap attribute to search (default: \"(objectclass=*)\""));
|
||||
printf (" %s\n", "-b [--base]");
|
||||
printf (" %s\n", _("ldap base (eg. ou=my unit, o=my org, c=at"));
|
||||
printf (" %s\n", "-D [--bind]");
|
||||
printf (" %s\n", _("ldap bind DN (if required)"));
|
||||
printf (" %s\n", "-P [--pass]");
|
||||
printf (" %s\n", _("ldap password (if required, or set the password through environment variable 'LDAP_PASSWORD')"));
|
||||
printf (" %s\n", "-T [--starttls]");
|
||||
printf (" %s\n", _("use starttls mechanism introduced in protocol version 3"));
|
||||
printf (" %s\n", "-S [--ssl]");
|
||||
printf (" %s %i\n", _("use ldaps (ldap v2 ssl method). this also sets the default port to"), LDAPS_PORT);
|
||||
printf(" %s\n", "-a [--attr]");
|
||||
printf(" %s\n", _("ldap attribute to search (default: \"(objectclass=*)\""));
|
||||
printf(" %s\n", "-b [--base]");
|
||||
printf(" %s\n", _("ldap base (eg. ou=my unit, o=my org, c=at"));
|
||||
printf(" %s\n", "-D [--bind]");
|
||||
printf(" %s\n", _("ldap bind DN (if required)"));
|
||||
printf(" %s\n", "-P [--pass]");
|
||||
printf(" %s\n", _("ldap password (if required, or set the password through environment variable 'LDAP_PASSWORD')"));
|
||||
printf(" %s\n", "-T [--starttls]");
|
||||
printf(" %s\n", _("use starttls mechanism introduced in protocol version 3"));
|
||||
printf(" %s\n", "-S [--ssl]");
|
||||
printf(" %s %i\n", _("use ldaps (ldap v2 ssl method). this also sets the default port to"), LDAPS_PORT);
|
||||
|
||||
#ifdef HAVE_LDAP_SET_OPTION
|
||||
printf (" %s\n", "-2 [--ver2]");
|
||||
printf (" %s\n", _("use ldap protocol version 2"));
|
||||
printf (" %s\n", "-3 [--ver3]");
|
||||
printf (" %s\n", _("use ldap protocol version 3"));
|
||||
printf (" (%s %d)\n", _("default protocol version:"), DEFAULT_PROTOCOL);
|
||||
printf(" %s\n", "-2 [--ver2]");
|
||||
printf(" %s\n", _("use ldap protocol version 2"));
|
||||
printf(" %s\n", "-3 [--ver3]");
|
||||
printf(" %s\n", _("use ldap protocol version 3"));
|
||||
printf(" (%s %d)\n", _("default protocol version:"), DEFAULT_PROTOCOL);
|
||||
#endif
|
||||
|
||||
printf (UT_WARN_CRIT);
|
||||
printf(UT_WARN_CRIT);
|
||||
|
||||
printf (" %s\n", "-W [--warn-entries]");
|
||||
printf (" %s\n", _("Number of found entries to result in warning status"));
|
||||
printf (" %s\n", "-C [--crit-entries]");
|
||||
printf (" %s\n", _("Number of found entries to result in critical status"));
|
||||
printf(" %s\n", "-W [--warn-entries]");
|
||||
printf(" %s\n", _("Number of found entries to result in warning status"));
|
||||
printf(" %s\n", "-C [--crit-entries]");
|
||||
printf(" %s\n", _("Number of found entries to result in critical status"));
|
||||
|
||||
printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
|
||||
printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
|
||||
|
||||
printf (UT_VERBOSE);
|
||||
printf(UT_VERBOSE);
|
||||
|
||||
printf ("\n");
|
||||
printf ("%s\n", _("Notes:"));
|
||||
printf (" %s\n", _("If this plugin is called via 'check_ldaps', method 'STARTTLS' will be"));
|
||||
printf (_(" implied (using default port %i) unless --port=636 is specified. In that case\n"), DEFAULT_PORT);
|
||||
printf (" %s\n", _("'SSL on connect' will be used no matter how the plugin was called."));
|
||||
printf (" %s\n", _("This detection is deprecated, please use 'check_ldap' with the '--starttls' or '--ssl' flags"));
|
||||
printf (" %s\n", _("to define the behaviour explicitly instead."));
|
||||
printf (" %s\n", _("The parameters --warn-entries and --crit-entries are optional."));
|
||||
printf("\n");
|
||||
printf("%s\n", _("Notes:"));
|
||||
printf(" %s\n", _("If this plugin is called via 'check_ldaps', method 'STARTTLS' will be"));
|
||||
printf(_(" implied (using default port %i) unless --port=636 is specified. In that case\n"), DEFAULT_PORT);
|
||||
printf(" %s\n", _("'SSL on connect' will be used no matter how the plugin was called."));
|
||||
printf(" %s\n", _("This detection is deprecated, please use 'check_ldap' with the '--starttls' or '--ssl' flags"));
|
||||
printf(" %s\n", _("to define the behaviour explicitly instead."));
|
||||
printf(" %s\n", _("The parameters --warn-entries and --crit-entries are optional."));
|
||||
|
||||
printf (UT_SUPPORT);
|
||||
printf(UT_SUPPORT);
|
||||
}
|
||||
|
||||
void
|
||||
print_usage (void)
|
||||
{
|
||||
printf ("%s\n", _("Usage:"));
|
||||
printf (" %s -H <host> -b <base_dn> [-p <port>] [-a <attr>] [-D <binddn>]",progname);
|
||||
printf ("\n [-P <password>] [-w <warn_time>] [-c <crit_time>] [-t timeout]%s\n",
|
||||
void print_usage(void) {
|
||||
printf("%s\n", _("Usage:"));
|
||||
printf(" %s -H <host> -b <base_dn> [-p <port>] [-a <attr>] [-D <binddn>]", progname);
|
||||
printf("\n [-P <password>] [-w <warn_time>] [-c <crit_time>] [-t timeout]%s\n",
|
||||
#ifdef HAVE_LDAP_SET_OPTION
|
||||
"\n [-2|-3] [-4|-6]"
|
||||
"\n [-2|-3] [-4|-6]"
|
||||
#else
|
||||
""
|
||||
""
|
||||
#endif
|
||||
);
|
||||
);
|
||||
}
|
||||
|
|
|
|||
60
plugins/check_ldap.d/config.h
Normal file
60
plugins/check_ldap.d/config.h
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../config.h"
|
||||
#include "thresholds.h"
|
||||
#include <stddef.h>
|
||||
|
||||
static char ld_defattr[] = "(objectclass=*)";
|
||||
|
||||
enum {
|
||||
#ifdef HAVE_LDAP_SET_OPTION
|
||||
DEFAULT_PROTOCOL = 2,
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
char *ld_host;
|
||||
char *ld_base;
|
||||
char *ld_passwd;
|
||||
char *ld_binddn;
|
||||
char *ld_attr;
|
||||
int ld_port;
|
||||
bool starttls;
|
||||
bool ssl_on_connect;
|
||||
#ifdef HAVE_LDAP_SET_OPTION
|
||||
int ld_protocol;
|
||||
#endif
|
||||
|
||||
char *warn_entries;
|
||||
char *crit_entries;
|
||||
thresholds *entries_thresholds;
|
||||
bool warn_time_set;
|
||||
double warn_time;
|
||||
bool crit_time_set;
|
||||
double crit_time;
|
||||
} check_ldap_config;
|
||||
|
||||
check_ldap_config check_ldap_config_init() {
|
||||
check_ldap_config tmp = {
|
||||
.ld_host = NULL,
|
||||
.ld_base = NULL,
|
||||
.ld_passwd = NULL,
|
||||
.ld_binddn = NULL,
|
||||
.ld_attr = ld_defattr,
|
||||
.ld_port = -1,
|
||||
.starttls = false,
|
||||
.ssl_on_connect = false,
|
||||
#ifdef HAVE_LDAP_SET_OPTION
|
||||
.ld_protocol = DEFAULT_PROTOCOL,
|
||||
#endif
|
||||
|
||||
.warn_entries = NULL,
|
||||
.crit_entries = NULL,
|
||||
.entries_thresholds = NULL,
|
||||
.warn_time_set = false,
|
||||
.warn_time = 0,
|
||||
.crit_time_set = false,
|
||||
.crit_time = 0,
|
||||
};
|
||||
return tmp;
|
||||
}
|
||||
|
|
@ -35,21 +35,18 @@ const char *email = "devel@monitoring-plugins.org";
|
|||
|
||||
#include "common.h"
|
||||
#include "utils.h"
|
||||
#include "check_mrtg.d/config.h"
|
||||
|
||||
typedef struct {
|
||||
int errorcode;
|
||||
check_mrtg_config config;
|
||||
} check_mrtg_config_wrapper;
|
||||
static check_mrtg_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
static check_mrtg_config_wrapper validate_arguments(check_mrtg_config_wrapper /*config_wrapper*/);
|
||||
|
||||
static int process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
static int validate_arguments(void);
|
||||
static void print_help(void);
|
||||
void print_usage(void);
|
||||
|
||||
static char *log_file = NULL;
|
||||
static int expire_minutes = 0;
|
||||
static bool use_average = true;
|
||||
static int variable_number = -1;
|
||||
static unsigned long value_warning_threshold = 0L;
|
||||
static unsigned long value_critical_threshold = 0L;
|
||||
static char *label;
|
||||
static char *units;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
setlocale(LC_ALL, "");
|
||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
|
|
@ -58,32 +55,37 @@ int main(int argc, char **argv) {
|
|||
/* Parse extra opts if any */
|
||||
argv = np_extra_opts(&argc, argv, progname);
|
||||
|
||||
if (process_arguments(argc, argv) == ERROR)
|
||||
check_mrtg_config_wrapper tmp_config = process_arguments(argc, argv);
|
||||
if (tmp_config.errorcode == ERROR) {
|
||||
usage4(_("Could not parse arguments\n"));
|
||||
}
|
||||
|
||||
const check_mrtg_config config = tmp_config.config;
|
||||
|
||||
/* open the MRTG log file for reading */
|
||||
FILE *mtrg_log_file = fopen(log_file, "r");
|
||||
FILE *mtrg_log_file = fopen(config.log_file, "r");
|
||||
if (mtrg_log_file == NULL) {
|
||||
printf(_("Unable to open MRTG log file\n"));
|
||||
return STATE_UNKNOWN;
|
||||
}
|
||||
|
||||
time_t timestamp = 0L;
|
||||
unsigned long average_value_rate = 0L;
|
||||
unsigned long maximum_value_rate = 0L;
|
||||
time_t timestamp = 0;
|
||||
unsigned long average_value_rate = 0;
|
||||
unsigned long maximum_value_rate = 0;
|
||||
char input_buffer[MAX_INPUT_BUFFER];
|
||||
int line = 0;
|
||||
while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, mtrg_log_file)) {
|
||||
|
||||
line++;
|
||||
|
||||
/* skip the first line of the log file */
|
||||
if (line == 1)
|
||||
if (line == 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* break out of read loop if we've passed the number of entries we want to read */
|
||||
if (line > 2)
|
||||
if (line > 2) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* grab the timestamp */
|
||||
char *temp_buffer = strtok(input_buffer, " ");
|
||||
|
|
@ -91,23 +93,27 @@ int main(int argc, char **argv) {
|
|||
|
||||
/* grab the average value 1 rate */
|
||||
temp_buffer = strtok(NULL, " ");
|
||||
if (variable_number == 1)
|
||||
if (config.variable_number == 1) {
|
||||
average_value_rate = strtoul(temp_buffer, NULL, 10);
|
||||
}
|
||||
|
||||
/* grab the average value 2 rate */
|
||||
temp_buffer = strtok(NULL, " ");
|
||||
if (variable_number == 2)
|
||||
if (config.variable_number == 2) {
|
||||
average_value_rate = strtoul(temp_buffer, NULL, 10);
|
||||
}
|
||||
|
||||
/* grab the maximum value 1 rate */
|
||||
temp_buffer = strtok(NULL, " ");
|
||||
if (variable_number == 1)
|
||||
if (config.variable_number == 1) {
|
||||
maximum_value_rate = strtoul(temp_buffer, NULL, 10);
|
||||
}
|
||||
|
||||
/* grab the maximum value 2 rate */
|
||||
temp_buffer = strtok(NULL, " ");
|
||||
if (variable_number == 2)
|
||||
if (config.variable_number == 2) {
|
||||
maximum_value_rate = strtoul(temp_buffer, NULL, 10);
|
||||
}
|
||||
}
|
||||
|
||||
/* close the log file */
|
||||
|
|
@ -122,49 +128,59 @@ int main(int argc, char **argv) {
|
|||
/* make sure the MRTG data isn't too old */
|
||||
time_t current_time;
|
||||
time(¤t_time);
|
||||
if (expire_minutes > 0 && (current_time - timestamp) > (expire_minutes * 60)) {
|
||||
if (config.expire_minutes > 0 && (current_time - timestamp) > (config.expire_minutes * 60)) {
|
||||
printf(_("MRTG data has expired (%d minutes old)\n"), (int)((current_time - timestamp) / 60));
|
||||
return STATE_WARNING;
|
||||
}
|
||||
|
||||
unsigned long rate = 0L;
|
||||
/* else check the incoming/outgoing rates */
|
||||
if (use_average)
|
||||
if (config.use_average) {
|
||||
rate = average_value_rate;
|
||||
else
|
||||
} else {
|
||||
rate = maximum_value_rate;
|
||||
}
|
||||
|
||||
int result = STATE_OK;
|
||||
if (rate > value_critical_threshold)
|
||||
if (config.value_critical_threshold_set && rate > config.value_critical_threshold) {
|
||||
result = STATE_CRITICAL;
|
||||
else if (rate > value_warning_threshold)
|
||||
} else if (config.value_warning_threshold_set && rate > config.value_warning_threshold) {
|
||||
result = STATE_WARNING;
|
||||
}
|
||||
|
||||
printf("%s. %s = %lu %s|%s\n", (use_average) ? _("Avg") : _("Max"), label, rate, units,
|
||||
perfdata(label, (long)rate, units, (int)value_warning_threshold, (long)value_warning_threshold, (int)value_critical_threshold,
|
||||
(long)value_critical_threshold, 0, 0, 0, 0));
|
||||
printf("%s. %s = %lu %s|%s\n", (config.use_average) ? _("Avg") : _("Max"), config.label, rate, config.units,
|
||||
perfdata(config.label, (long)rate, config.units, config.value_warning_threshold_set, (long)config.value_warning_threshold,
|
||||
config.value_critical_threshold_set, (long)config.value_critical_threshold, 0, 0, 0, 0));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* process command-line arguments */
|
||||
int process_arguments(int argc, char **argv) {
|
||||
check_mrtg_config_wrapper process_arguments(int argc, char **argv) {
|
||||
static struct option longopts[] = {
|
||||
{"logfile", required_argument, 0, 'F'}, {"expires", required_argument, 0, 'e'}, {"aggregation", required_argument, 0, 'a'},
|
||||
{"variable", required_argument, 0, 'v'}, {"critical", required_argument, 0, 'c'}, {"warning", required_argument, 0, 'w'},
|
||||
{"label", required_argument, 0, 'l'}, {"units", required_argument, 0, 'u'}, {"variable", required_argument, 0, 'v'},
|
||||
{"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}};
|
||||
|
||||
if (argc < 2)
|
||||
return ERROR;
|
||||
check_mrtg_config_wrapper result = {
|
||||
.errorcode = OK,
|
||||
.config = check_mrtg_config_init(),
|
||||
};
|
||||
|
||||
if (argc < 2) {
|
||||
result.errorcode = ERROR;
|
||||
return result;
|
||||
}
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (strcmp("-to", argv[i]) == 0)
|
||||
if (strcmp("-to", argv[i]) == 0) {
|
||||
strcpy(argv[i], "-t");
|
||||
else if (strcmp("-wt", argv[i]) == 0)
|
||||
} else if (strcmp("-wt", argv[i]) == 0) {
|
||||
strcpy(argv[i], "-w");
|
||||
else if (strcmp("-ct", argv[i]) == 0)
|
||||
} else if (strcmp("-ct", argv[i]) == 0) {
|
||||
strcpy(argv[i], "-c");
|
||||
}
|
||||
}
|
||||
|
||||
int option_char;
|
||||
|
|
@ -172,38 +188,39 @@ int process_arguments(int argc, char **argv) {
|
|||
while (1) {
|
||||
option_char = getopt_long(argc, argv, "hVF:e:a:v:c:w:l:u:", longopts, &option);
|
||||
|
||||
if (option_char == -1 || option_char == EOF)
|
||||
if (option_char == -1 || option_char == EOF) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (option_char) {
|
||||
case 'F': /* input file */
|
||||
log_file = optarg;
|
||||
result.config.log_file = optarg;
|
||||
break;
|
||||
case 'e': /* ups name */
|
||||
expire_minutes = atoi(optarg);
|
||||
result.config.expire_minutes = atoi(optarg);
|
||||
break;
|
||||
case 'a': /* port */
|
||||
if (!strcmp(optarg, "MAX"))
|
||||
use_average = false;
|
||||
else
|
||||
use_average = true;
|
||||
result.config.use_average = (bool)(strcmp(optarg, "MAX"));
|
||||
break;
|
||||
case 'v':
|
||||
variable_number = atoi(optarg);
|
||||
if (variable_number < 1 || variable_number > 2)
|
||||
result.config.variable_number = atoi(optarg);
|
||||
if (result.config.variable_number < 1 || result.config.variable_number > 2) {
|
||||
usage4(_("Invalid variable number"));
|
||||
}
|
||||
break;
|
||||
case 'w': /* critical time threshold */
|
||||
value_warning_threshold = strtoul(optarg, NULL, 10);
|
||||
result.config.value_warning_threshold_set = true;
|
||||
result.config.value_warning_threshold = strtoul(optarg, NULL, 10);
|
||||
break;
|
||||
case 'c': /* warning time threshold */
|
||||
value_critical_threshold = strtoul(optarg, NULL, 10);
|
||||
result.config.value_critical_threshold_set = true;
|
||||
result.config.value_critical_threshold = strtoul(optarg, NULL, 10);
|
||||
break;
|
||||
case 'l': /* label */
|
||||
label = optarg;
|
||||
result.config.label = optarg;
|
||||
break;
|
||||
case 'u': /* timeout */
|
||||
units = optarg;
|
||||
result.config.units = optarg;
|
||||
break;
|
||||
case 'V': /* version */
|
||||
print_revision(progname, NP_VERSION);
|
||||
|
|
@ -217,63 +234,69 @@ int process_arguments(int argc, char **argv) {
|
|||
}
|
||||
|
||||
option_char = optind;
|
||||
if (log_file == NULL && argc > option_char) {
|
||||
log_file = argv[option_char++];
|
||||
if (result.config.log_file == NULL && argc > option_char) {
|
||||
result.config.log_file = argv[option_char++];
|
||||
}
|
||||
|
||||
if (expire_minutes <= 0 && argc > option_char) {
|
||||
if (is_intpos(argv[option_char]))
|
||||
expire_minutes = atoi(argv[option_char++]);
|
||||
else
|
||||
if (result.config.expire_minutes <= 0 && argc > option_char) {
|
||||
if (is_intpos(argv[option_char])) {
|
||||
result.config.expire_minutes = atoi(argv[option_char++]);
|
||||
} else {
|
||||
die(STATE_UNKNOWN, _("%s is not a valid expiration time\nUse '%s -h' for additional help\n"), argv[option_char], progname);
|
||||
}
|
||||
}
|
||||
|
||||
if (argc > option_char && strcmp(argv[option_char], "MAX") == 0) {
|
||||
use_average = false;
|
||||
result.config.use_average = false;
|
||||
option_char++;
|
||||
} else if (argc > option_char && strcmp(argv[option_char], "AVG") == 0) {
|
||||
use_average = true;
|
||||
result.config.use_average = true;
|
||||
option_char++;
|
||||
}
|
||||
|
||||
if (argc > option_char && variable_number == -1) {
|
||||
variable_number = atoi(argv[option_char++]);
|
||||
if (variable_number < 1 || variable_number > 2) {
|
||||
if (argc > option_char && result.config.variable_number == -1) {
|
||||
result.config.variable_number = atoi(argv[option_char++]);
|
||||
if (result.config.variable_number < 1 || result.config.variable_number > 2) {
|
||||
printf("%s :", argv[option_char]);
|
||||
usage(_("Invalid variable number\n"));
|
||||
}
|
||||
}
|
||||
|
||||
if (argc > option_char && value_warning_threshold == 0) {
|
||||
value_warning_threshold = strtoul(argv[option_char++], NULL, 10);
|
||||
if (argc > option_char && !result.config.value_warning_threshold_set) {
|
||||
result.config.value_warning_threshold_set = true;
|
||||
result.config.value_warning_threshold = strtoul(argv[option_char++], NULL, 10);
|
||||
}
|
||||
|
||||
if (argc > option_char && value_critical_threshold == 0) {
|
||||
value_critical_threshold = strtoul(argv[option_char++], NULL, 10);
|
||||
if (argc > option_char && !result.config.value_critical_threshold_set) {
|
||||
result.config.value_critical_threshold_set = true;
|
||||
result.config.value_critical_threshold = strtoul(argv[option_char++], NULL, 10);
|
||||
}
|
||||
|
||||
if (argc > option_char && strlen(label) == 0) {
|
||||
label = argv[option_char++];
|
||||
if (argc > option_char && strlen(result.config.label) == 0) {
|
||||
result.config.label = argv[option_char++];
|
||||
}
|
||||
|
||||
if (argc > option_char && strlen(units) == 0) {
|
||||
units = argv[option_char++];
|
||||
if (argc > option_char && strlen(result.config.units) == 0) {
|
||||
result.config.units = argv[option_char++];
|
||||
}
|
||||
|
||||
return validate_arguments();
|
||||
return validate_arguments(result);
|
||||
}
|
||||
|
||||
int validate_arguments(void) {
|
||||
if (variable_number == -1)
|
||||
check_mrtg_config_wrapper validate_arguments(check_mrtg_config_wrapper config_wrapper) {
|
||||
if (config_wrapper.config.variable_number == -1) {
|
||||
usage4(_("You must supply the variable number"));
|
||||
}
|
||||
|
||||
if (label == NULL)
|
||||
label = strdup("value");
|
||||
if (config_wrapper.config.label == NULL) {
|
||||
config_wrapper.config.label = strdup("value");
|
||||
}
|
||||
|
||||
if (units == NULL)
|
||||
units = strdup("");
|
||||
if (config_wrapper.config.units == NULL) {
|
||||
config_wrapper.config.units = strdup("");
|
||||
}
|
||||
|
||||
return OK;
|
||||
return config_wrapper;
|
||||
}
|
||||
|
||||
void print_help(void) {
|
||||
|
|
|
|||
36
plugins/check_mrtg.d/config.h
Normal file
36
plugins/check_mrtg.d/config.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../config.h"
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct {
|
||||
bool use_average;
|
||||
int variable_number;
|
||||
int expire_minutes;
|
||||
char *label;
|
||||
char *units;
|
||||
char *log_file;
|
||||
|
||||
bool value_warning_threshold_set;
|
||||
unsigned long value_warning_threshold;
|
||||
bool value_critical_threshold_set;
|
||||
unsigned long value_critical_threshold;
|
||||
} check_mrtg_config;
|
||||
|
||||
check_mrtg_config check_mrtg_config_init() {
|
||||
check_mrtg_config tmp = {
|
||||
.use_average = true,
|
||||
.variable_number = -1,
|
||||
.expire_minutes = 0,
|
||||
.label = NULL,
|
||||
.units = NULL,
|
||||
.log_file = NULL,
|
||||
|
||||
.value_warning_threshold_set = false,
|
||||
.value_warning_threshold = 0,
|
||||
.value_critical_threshold_set = false,
|
||||
.value_critical_threshold = 0,
|
||||
};
|
||||
return tmp;
|
||||
}
|
||||
|
|
@ -29,25 +29,23 @@
|
|||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "common.h"
|
||||
#include "utils.h"
|
||||
|
||||
const char *progname = "check_mrtgtraf";
|
||||
const char *copyright = "1999-2024";
|
||||
const char *email = "devel@monitoring-plugins.org";
|
||||
|
||||
static int process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
#include "check_mrtgtraf.d/config.h"
|
||||
#include "common.h"
|
||||
#include "utils.h"
|
||||
|
||||
typedef struct {
|
||||
int errorcode;
|
||||
check_mrtgtraf_config config;
|
||||
} check_mrtgtraf_config_wrapper;
|
||||
|
||||
static check_mrtgtraf_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
static void print_help(void);
|
||||
void print_usage(void);
|
||||
|
||||
static char *log_file = NULL;
|
||||
static int expire_minutes = -1;
|
||||
static bool use_average = true;
|
||||
static unsigned long incoming_warning_threshold = 0L;
|
||||
static unsigned long incoming_critical_threshold = 0L;
|
||||
static unsigned long outgoing_warning_threshold = 0L;
|
||||
static unsigned long outgoing_critical_threshold = 0L;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
setlocale(LC_ALL, "");
|
||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
|
|
@ -56,13 +54,18 @@ int main(int argc, char **argv) {
|
|||
/* Parse extra opts if any */
|
||||
argv = np_extra_opts(&argc, argv, progname);
|
||||
|
||||
if (process_arguments(argc, argv) == ERROR)
|
||||
check_mrtgtraf_config_wrapper tmp_config = process_arguments(argc, argv);
|
||||
if (tmp_config.errorcode == ERROR) {
|
||||
usage4(_("Could not parse arguments"));
|
||||
}
|
||||
|
||||
const check_mrtgtraf_config config = tmp_config.config;
|
||||
|
||||
/* open the MRTG log file for reading */
|
||||
FILE *mrtg_log_file_ptr = fopen(log_file, "r");
|
||||
if (mrtg_log_file_ptr == NULL)
|
||||
FILE *mrtg_log_file_ptr = fopen(config.log_file, "r");
|
||||
if (mrtg_log_file_ptr == NULL) {
|
||||
usage4(_("Unable to open MRTG log file"));
|
||||
}
|
||||
|
||||
time_t timestamp = 0L;
|
||||
char input_buffer[MAX_INPUT_BUFFER];
|
||||
|
|
@ -76,13 +79,15 @@ int main(int argc, char **argv) {
|
|||
line++;
|
||||
|
||||
/* skip the first line of the log file */
|
||||
if (line == 1)
|
||||
if (line == 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* break out of read loop */
|
||||
/* if we've passed the number of entries we want to read */
|
||||
if (line > 2)
|
||||
if (line > 2) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* grab the timestamp */
|
||||
char *temp_buffer = strtok(input_buffer, " ");
|
||||
|
|
@ -109,19 +114,21 @@ int main(int argc, char **argv) {
|
|||
fclose(mrtg_log_file_ptr);
|
||||
|
||||
/* if we couldn't read enough data, return an unknown error */
|
||||
if (line <= 2)
|
||||
if (line <= 2) {
|
||||
usage4(_("Unable to process MRTG log file"));
|
||||
}
|
||||
|
||||
/* make sure the MRTG data isn't too old */
|
||||
time_t current_time;
|
||||
time(¤t_time);
|
||||
if ((expire_minutes > 0) && (current_time - timestamp) > (expire_minutes * 60))
|
||||
if ((config.expire_minutes > 0) && (current_time - timestamp) > (config.expire_minutes * 60)) {
|
||||
die(STATE_WARNING, _("MRTG data has expired (%d minutes old)\n"), (int)((current_time - timestamp) / 60));
|
||||
}
|
||||
|
||||
unsigned long incoming_rate = 0L;
|
||||
unsigned long outgoing_rate = 0L;
|
||||
/* else check the incoming/outgoing rates */
|
||||
if (use_average) {
|
||||
if (config.use_average) {
|
||||
incoming_rate = average_incoming_rate;
|
||||
outgoing_rate = average_outgoing_rate;
|
||||
} else {
|
||||
|
|
@ -166,24 +173,26 @@ int main(int argc, char **argv) {
|
|||
/* report outgoing traffic in MBytes/sec */
|
||||
else {
|
||||
strcpy(outgoing_speed_rating, "MB");
|
||||
adjusted_outgoing_rate = (double)(outgoing_rate / 1024.0 / 1024.0);
|
||||
adjusted_outgoing_rate = (outgoing_rate / 1024.0 / 1024.0);
|
||||
}
|
||||
|
||||
int result = STATE_OK;
|
||||
if (incoming_rate > incoming_critical_threshold || outgoing_rate > outgoing_critical_threshold) {
|
||||
if (incoming_rate > config.incoming_critical_threshold || outgoing_rate > config.outgoing_critical_threshold) {
|
||||
result = STATE_CRITICAL;
|
||||
} else if (incoming_rate > incoming_warning_threshold || outgoing_rate > outgoing_warning_threshold) {
|
||||
} else if (incoming_rate > config.incoming_warning_threshold || outgoing_rate > config.outgoing_warning_threshold) {
|
||||
result = STATE_WARNING;
|
||||
}
|
||||
|
||||
char *error_message;
|
||||
xasprintf(&error_message, _("%s. In = %0.1f %s/s, %s. Out = %0.1f %s/s|%s %s\n"), (use_average) ? _("Avg") : _("Max"),
|
||||
adjusted_incoming_rate, incoming_speed_rating, (use_average) ? _("Avg") : _("Max"), adjusted_outgoing_rate,
|
||||
xasprintf(&error_message, _("%s. In = %0.1f %s/s, %s. Out = %0.1f %s/s|%s %s\n"), (config.use_average) ? _("Avg") : _("Max"),
|
||||
adjusted_incoming_rate, incoming_speed_rating, (config.use_average) ? _("Avg") : _("Max"), adjusted_outgoing_rate,
|
||||
outgoing_speed_rating,
|
||||
fperfdata("in", adjusted_incoming_rate, incoming_speed_rating, (int)incoming_warning_threshold, incoming_warning_threshold,
|
||||
(int)incoming_critical_threshold, incoming_critical_threshold, true, 0, false, 0),
|
||||
fperfdata("out", adjusted_outgoing_rate, outgoing_speed_rating, (int)outgoing_warning_threshold, outgoing_warning_threshold,
|
||||
(int)outgoing_critical_threshold, outgoing_critical_threshold, true, 0, false, 0));
|
||||
fperfdata("in", adjusted_incoming_rate, incoming_speed_rating, (int)config.incoming_warning_threshold,
|
||||
config.incoming_warning_threshold, (int)config.incoming_critical_threshold, config.incoming_critical_threshold,
|
||||
true, 0, false, 0),
|
||||
fperfdata("out", adjusted_outgoing_rate, outgoing_speed_rating, (int)config.outgoing_warning_threshold,
|
||||
config.outgoing_warning_threshold, (int)config.outgoing_critical_threshold, config.outgoing_critical_threshold,
|
||||
true, 0, false, 0));
|
||||
|
||||
printf(_("Traffic %s - %s\n"), state_text(result), error_message);
|
||||
|
||||
|
|
@ -191,7 +200,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
/* process command-line arguments */
|
||||
int process_arguments(int argc, char **argv) {
|
||||
check_mrtgtraf_config_wrapper process_arguments(int argc, char **argv) {
|
||||
static struct option longopts[] = {{"filename", required_argument, 0, 'F'},
|
||||
{"expires", required_argument, 0, 'e'},
|
||||
{"aggregation", required_argument, 0, 'a'},
|
||||
|
|
@ -201,44 +210,49 @@ int process_arguments(int argc, char **argv) {
|
|||
{"help", no_argument, 0, 'h'},
|
||||
{0, 0, 0, 0}};
|
||||
|
||||
if (argc < 2)
|
||||
return ERROR;
|
||||
check_mrtgtraf_config_wrapper result = {
|
||||
.errorcode = OK,
|
||||
.config = check_mrtgtraf_config_init(),
|
||||
};
|
||||
if (argc < 2) {
|
||||
result.errorcode = ERROR;
|
||||
return result;
|
||||
}
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (strcmp("-to", argv[i]) == 0)
|
||||
if (strcmp("-to", argv[i]) == 0) {
|
||||
strcpy(argv[i], "-t");
|
||||
else if (strcmp("-wt", argv[i]) == 0)
|
||||
} else if (strcmp("-wt", argv[i]) == 0) {
|
||||
strcpy(argv[i], "-w");
|
||||
else if (strcmp("-ct", argv[i]) == 0)
|
||||
} else if (strcmp("-ct", argv[i]) == 0) {
|
||||
strcpy(argv[i], "-c");
|
||||
}
|
||||
}
|
||||
|
||||
int option_char;
|
||||
int option = 0;
|
||||
while (1) {
|
||||
while (true) {
|
||||
option_char = getopt_long(argc, argv, "hVF:e:a:c:w:", longopts, &option);
|
||||
|
||||
if (option_char == -1 || option_char == EOF)
|
||||
if (option_char == -1 || option_char == EOF) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (option_char) {
|
||||
case 'F': /* input file */
|
||||
log_file = optarg;
|
||||
result.config.log_file = optarg;
|
||||
break;
|
||||
case 'e': /* expiration time */
|
||||
expire_minutes = atoi(optarg);
|
||||
result.config.expire_minutes = atoi(optarg);
|
||||
break;
|
||||
case 'a': /* aggregation (AVE or MAX) */
|
||||
if (!strcmp(optarg, "MAX"))
|
||||
use_average = false;
|
||||
else
|
||||
use_average = true;
|
||||
result.config.use_average = (bool)(strcmp(optarg, "MAX"));
|
||||
break;
|
||||
case 'c': /* warning threshold */
|
||||
sscanf(optarg, "%lu,%lu", &incoming_critical_threshold, &outgoing_critical_threshold);
|
||||
sscanf(optarg, "%lu,%lu", &result.config.incoming_critical_threshold, &result.config.outgoing_critical_threshold);
|
||||
break;
|
||||
case 'w': /* critical threshold */
|
||||
sscanf(optarg, "%lu,%lu", &incoming_warning_threshold, &outgoing_warning_threshold);
|
||||
sscanf(optarg, "%lu,%lu", &result.config.incoming_warning_threshold, &result.config.outgoing_warning_threshold);
|
||||
break;
|
||||
case 'V': /* version */
|
||||
print_revision(progname, NP_VERSION);
|
||||
|
|
@ -252,39 +266,39 @@ int process_arguments(int argc, char **argv) {
|
|||
}
|
||||
|
||||
option_char = optind;
|
||||
if (argc > option_char && log_file == NULL) {
|
||||
log_file = argv[option_char++];
|
||||
if (argc > option_char && result.config.log_file == NULL) {
|
||||
result.config.log_file = argv[option_char++];
|
||||
}
|
||||
|
||||
if (argc > option_char && expire_minutes == -1) {
|
||||
expire_minutes = atoi(argv[option_char++]);
|
||||
if (argc > option_char && result.config.expire_minutes == -1) {
|
||||
result.config.expire_minutes = atoi(argv[option_char++]);
|
||||
}
|
||||
|
||||
if (argc > option_char && strcmp(argv[option_char], "MAX") == 0) {
|
||||
use_average = false;
|
||||
result.config.use_average = false;
|
||||
option_char++;
|
||||
} else if (argc > option_char && strcmp(argv[option_char], "AVG") == 0) {
|
||||
use_average = true;
|
||||
result.config.use_average = true;
|
||||
option_char++;
|
||||
}
|
||||
|
||||
if (argc > option_char && incoming_warning_threshold == 0) {
|
||||
incoming_warning_threshold = strtoul(argv[option_char++], NULL, 10);
|
||||
if (argc > option_char && result.config.incoming_warning_threshold == 0) {
|
||||
result.config.incoming_warning_threshold = strtoul(argv[option_char++], NULL, 10);
|
||||
}
|
||||
|
||||
if (argc > option_char && incoming_critical_threshold == 0) {
|
||||
incoming_critical_threshold = strtoul(argv[option_char++], NULL, 10);
|
||||
if (argc > option_char && result.config.incoming_critical_threshold == 0) {
|
||||
result.config.incoming_critical_threshold = strtoul(argv[option_char++], NULL, 10);
|
||||
}
|
||||
|
||||
if (argc > option_char && outgoing_warning_threshold == 0) {
|
||||
outgoing_warning_threshold = strtoul(argv[option_char++], NULL, 10);
|
||||
if (argc > option_char && result.config.outgoing_warning_threshold == 0) {
|
||||
result.config.outgoing_warning_threshold = strtoul(argv[option_char++], NULL, 10);
|
||||
}
|
||||
|
||||
if (argc > option_char && outgoing_critical_threshold == 0) {
|
||||
outgoing_critical_threshold = strtoul(argv[option_char++], NULL, 10);
|
||||
if (argc > option_char && result.config.outgoing_critical_threshold == 0) {
|
||||
result.config.outgoing_critical_threshold = strtoul(argv[option_char++], NULL, 10);
|
||||
}
|
||||
|
||||
return OK;
|
||||
return result;
|
||||
}
|
||||
|
||||
void print_help(void) {
|
||||
|
|
|
|||
30
plugins/check_mrtgtraf.d/config.h
Normal file
30
plugins/check_mrtgtraf.d/config.h
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../config.h"
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct {
|
||||
char *log_file;
|
||||
int expire_minutes;
|
||||
bool use_average;
|
||||
unsigned long incoming_warning_threshold;
|
||||
unsigned long incoming_critical_threshold;
|
||||
unsigned long outgoing_warning_threshold;
|
||||
unsigned long outgoing_critical_threshold;
|
||||
|
||||
} check_mrtgtraf_config;
|
||||
|
||||
check_mrtgtraf_config check_mrtgtraf_config_init() {
|
||||
check_mrtgtraf_config tmp = {
|
||||
.log_file = NULL,
|
||||
.expire_minutes = -1,
|
||||
.use_average = true,
|
||||
|
||||
.incoming_warning_threshold = 0,
|
||||
.incoming_critical_threshold = 0,
|
||||
.outgoing_warning_threshold = 0,
|
||||
.outgoing_critical_threshold = 0,
|
||||
};
|
||||
return tmp;
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
58
plugins/check_mysql.d/config.h
Normal file
58
plugins/check_mysql.d/config.h
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../config.h"
|
||||
#include "thresholds.h"
|
||||
#include <stddef.h>
|
||||
#include <mysql.h>
|
||||
|
||||
typedef struct {
|
||||
char *db_host;
|
||||
unsigned int db_port;
|
||||
char *db_user;
|
||||
char *db_socket;
|
||||
char *db_pass;
|
||||
char *db;
|
||||
char *ca_cert;
|
||||
char *ca_dir;
|
||||
char *cert;
|
||||
char *key;
|
||||
char *ciphers;
|
||||
bool ssl;
|
||||
char *opt_file;
|
||||
char *opt_group;
|
||||
|
||||
bool check_replica;
|
||||
bool ignore_auth;
|
||||
|
||||
double warning_time;
|
||||
double critical_time;
|
||||
thresholds *my_threshold;
|
||||
|
||||
} check_mysql_config;
|
||||
|
||||
check_mysql_config check_mysql_config_init() {
|
||||
check_mysql_config tmp = {
|
||||
.db_host = NULL,
|
||||
.db_port = MYSQL_PORT,
|
||||
.db = NULL,
|
||||
.db_pass = NULL,
|
||||
.db_socket = NULL,
|
||||
.db_user = NULL,
|
||||
.ca_cert = NULL,
|
||||
.ca_dir = NULL,
|
||||
.cert = NULL,
|
||||
.key = NULL,
|
||||
.ciphers = NULL,
|
||||
.ssl = false,
|
||||
.opt_file = NULL,
|
||||
.opt_group = NULL,
|
||||
|
||||
.check_replica = false,
|
||||
.ignore_auth = false,
|
||||
|
||||
.warning_time = 0,
|
||||
.critical_time = 0,
|
||||
.my_threshold = NULL,
|
||||
};
|
||||
return tmp;
|
||||
}
|
||||
|
|
@ -37,27 +37,21 @@ const char *email = "devel@monitoring-plugins.org";
|
|||
#include "utils.h"
|
||||
#include "utils_base.h"
|
||||
#include "netutils.h"
|
||||
#include "check_mysql_query.d/config.h"
|
||||
|
||||
#include <mysql.h>
|
||||
#include <errmsg.h>
|
||||
|
||||
static char *db_user = NULL;
|
||||
static char *db_host = NULL;
|
||||
static char *db_socket = NULL;
|
||||
static char *db_pass = NULL;
|
||||
static char *db = NULL;
|
||||
static char *opt_file = NULL;
|
||||
static char *opt_group = NULL;
|
||||
static unsigned int db_port = MYSQL_PORT;
|
||||
|
||||
static int process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
static int validate_arguments(void);
|
||||
typedef struct {
|
||||
int errorcode;
|
||||
check_mysql_query_config config;
|
||||
} check_mysql_query_config_wrapper;
|
||||
static check_mysql_query_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
static check_mysql_query_config_wrapper validate_arguments(check_mysql_query_config_wrapper /*config_wrapper*/);
|
||||
static void print_help(void);
|
||||
void print_usage(void);
|
||||
|
||||
static char *sql_query = NULL;
|
||||
static int verbose = 0;
|
||||
static thresholds *my_thresholds = NULL;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
setlocale(LC_ALL, "");
|
||||
|
|
@ -67,39 +61,46 @@ int main(int argc, char **argv) {
|
|||
/* Parse extra opts if any */
|
||||
argv = np_extra_opts(&argc, argv, progname);
|
||||
|
||||
if (process_arguments(argc, argv) == ERROR)
|
||||
check_mysql_query_config_wrapper tmp_config = process_arguments(argc, argv);
|
||||
if (tmp_config.errorcode == ERROR) {
|
||||
usage4(_("Could not parse arguments"));
|
||||
}
|
||||
|
||||
const check_mysql_query_config config = tmp_config.config;
|
||||
|
||||
MYSQL mysql;
|
||||
/* initialize mysql */
|
||||
mysql_init(&mysql);
|
||||
|
||||
if (opt_file != NULL)
|
||||
mysql_options(&mysql, MYSQL_READ_DEFAULT_FILE, opt_file);
|
||||
if (config.opt_file != NULL) {
|
||||
mysql_options(&mysql, MYSQL_READ_DEFAULT_FILE, config.opt_file);
|
||||
}
|
||||
|
||||
if (opt_group != NULL)
|
||||
mysql_options(&mysql, MYSQL_READ_DEFAULT_GROUP, opt_group);
|
||||
else
|
||||
if (config.opt_group != NULL) {
|
||||
mysql_options(&mysql, MYSQL_READ_DEFAULT_GROUP, config.opt_group);
|
||||
} else {
|
||||
mysql_options(&mysql, MYSQL_READ_DEFAULT_GROUP, "client");
|
||||
}
|
||||
|
||||
/* establish a connection to the server and error checking */
|
||||
if (!mysql_real_connect(&mysql, db_host, db_user, db_pass, db, db_port, db_socket, 0)) {
|
||||
if (mysql_errno(&mysql) == CR_UNKNOWN_HOST)
|
||||
if (!mysql_real_connect(&mysql, config.db_host, config.db_user, config.db_pass, config.db, config.db_port, config.db_socket, 0)) {
|
||||
if (mysql_errno(&mysql) == CR_UNKNOWN_HOST) {
|
||||
die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error(&mysql));
|
||||
else if (mysql_errno(&mysql) == CR_VERSION_ERROR)
|
||||
} else if (mysql_errno(&mysql) == CR_VERSION_ERROR) {
|
||||
die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error(&mysql));
|
||||
else if (mysql_errno(&mysql) == CR_OUT_OF_MEMORY)
|
||||
} else if (mysql_errno(&mysql) == CR_OUT_OF_MEMORY) {
|
||||
die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error(&mysql));
|
||||
else if (mysql_errno(&mysql) == CR_IPSOCK_ERROR)
|
||||
} else if (mysql_errno(&mysql) == CR_IPSOCK_ERROR) {
|
||||
die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error(&mysql));
|
||||
else if (mysql_errno(&mysql) == CR_SOCKET_CREATE_ERROR)
|
||||
} else if (mysql_errno(&mysql) == CR_SOCKET_CREATE_ERROR) {
|
||||
die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error(&mysql));
|
||||
else
|
||||
} else {
|
||||
die(STATE_CRITICAL, "QUERY %s: %s\n", _("CRITICAL"), mysql_error(&mysql));
|
||||
}
|
||||
}
|
||||
|
||||
char *error = NULL;
|
||||
if (mysql_query(&mysql, sql_query) != 0) {
|
||||
if (mysql_query(&mysql, config.sql_query) != 0) {
|
||||
error = strdup(mysql_error(&mysql));
|
||||
mysql_close(&mysql);
|
||||
die(STATE_CRITICAL, "QUERY %s: %s - %s\n", _("CRITICAL"), _("Error with query"), error);
|
||||
|
|
@ -140,10 +141,11 @@ int main(int argc, char **argv) {
|
|||
/* close the connection */
|
||||
mysql_close(&mysql);
|
||||
|
||||
if (verbose >= 3)
|
||||
if (verbose >= 3) {
|
||||
printf("mysql result: %f\n", value);
|
||||
}
|
||||
|
||||
int status = get_status(value, my_thresholds);
|
||||
int status = get_status(value, config.my_thresholds);
|
||||
|
||||
if (status == STATE_OK) {
|
||||
printf("QUERY %s: ", _("OK"));
|
||||
|
|
@ -152,17 +154,16 @@ int main(int argc, char **argv) {
|
|||
} else if (status == STATE_CRITICAL) {
|
||||
printf("QUERY %s: ", _("CRITICAL"));
|
||||
}
|
||||
printf(_("'%s' returned %f | %s"), sql_query, value,
|
||||
fperfdata("result", value, "", my_thresholds->warning ? true : false, my_thresholds->warning ? my_thresholds->warning->end : 0,
|
||||
my_thresholds->critical ? true : false, my_thresholds->critical ? my_thresholds->critical->end : 0, false, 0, false,
|
||||
0));
|
||||
printf(_("'%s' returned %f | %s"), config.sql_query, value,
|
||||
fperfdata("result", value, "", config.my_thresholds->warning, config.my_thresholds->warning ? config.my_thresholds->warning->end : 0,
|
||||
config.my_thresholds->critical, config.my_thresholds->critical ? config.my_thresholds->critical->end : 0, false, 0, false, 0));
|
||||
printf("\n");
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* process command-line arguments */
|
||||
int process_arguments(int argc, char **argv) {
|
||||
check_mysql_query_config_wrapper process_arguments(int argc, char **argv) {
|
||||
static struct option longopts[] = {
|
||||
{"hostname", required_argument, 0, 'H'}, {"socket", required_argument, 0, 's'}, {"database", required_argument, 0, 'd'},
|
||||
{"username", required_argument, 0, 'u'}, {"password", required_argument, 0, 'p'}, {"file", required_argument, 0, 'f'},
|
||||
|
|
@ -170,8 +171,15 @@ int process_arguments(int argc, char **argv) {
|
|||
{"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, {"query", required_argument, 0, 'q'},
|
||||
{"warning", required_argument, 0, 'w'}, {"critical", required_argument, 0, 'c'}, {0, 0, 0, 0}};
|
||||
|
||||
if (argc < 1)
|
||||
return ERROR;
|
||||
check_mysql_query_config_wrapper result = {
|
||||
.errorcode = OK,
|
||||
.config = check_mysql_query_config_init(),
|
||||
};
|
||||
|
||||
if (argc < 1) {
|
||||
result.errorcode = ERROR;
|
||||
return result;
|
||||
}
|
||||
|
||||
char *warning = NULL;
|
||||
char *critical = NULL;
|
||||
|
|
@ -180,28 +188,29 @@ int process_arguments(int argc, char **argv) {
|
|||
int option = 0;
|
||||
int option_char = getopt_long(argc, argv, "hvVP:p:u:d:H:s:q:w:c:f:g:", longopts, &option);
|
||||
|
||||
if (option_char == -1 || option_char == EOF)
|
||||
if (option_char == -1 || option_char == EOF) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (option_char) {
|
||||
case 'H': /* hostname */
|
||||
if (is_host(optarg)) {
|
||||
db_host = optarg;
|
||||
result.config.db_host = optarg;
|
||||
} else {
|
||||
usage2(_("Invalid hostname/address"), optarg);
|
||||
}
|
||||
break;
|
||||
case 's': /* socket */
|
||||
db_socket = optarg;
|
||||
result.config.db_socket = optarg;
|
||||
break;
|
||||
case 'd': /* database */
|
||||
db = optarg;
|
||||
result.config.db = optarg;
|
||||
break;
|
||||
case 'u': /* username */
|
||||
db_user = optarg;
|
||||
result.config.db_user = optarg;
|
||||
break;
|
||||
case 'p': /* authentication information: password */
|
||||
db_pass = strdup(optarg);
|
||||
result.config.db_pass = strdup(optarg);
|
||||
|
||||
/* Delete the password from process list */
|
||||
while (*optarg != '\0') {
|
||||
|
|
@ -210,13 +219,13 @@ int process_arguments(int argc, char **argv) {
|
|||
}
|
||||
break;
|
||||
case 'f': /* client options file */
|
||||
opt_file = optarg;
|
||||
result.config.opt_file = optarg;
|
||||
break;
|
||||
case 'g': /* client options group */
|
||||
opt_group = optarg;
|
||||
result.config.opt_group = optarg;
|
||||
break;
|
||||
case 'P': /* critical time threshold */
|
||||
db_port = atoi(optarg);
|
||||
result.config.db_port = atoi(optarg);
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
|
|
@ -228,7 +237,7 @@ int process_arguments(int argc, char **argv) {
|
|||
print_help();
|
||||
exit(STATE_UNKNOWN);
|
||||
case 'q':
|
||||
xasprintf(&sql_query, "%s", optarg);
|
||||
xasprintf(&result.config.sql_query, "%s", optarg);
|
||||
break;
|
||||
case 'w':
|
||||
warning = optarg;
|
||||
|
|
@ -241,25 +250,29 @@ int process_arguments(int argc, char **argv) {
|
|||
}
|
||||
}
|
||||
|
||||
set_thresholds(&my_thresholds, warning, critical);
|
||||
set_thresholds(&result.config.my_thresholds, warning, critical);
|
||||
|
||||
return validate_arguments();
|
||||
return validate_arguments(result);
|
||||
}
|
||||
|
||||
int validate_arguments(void) {
|
||||
if (sql_query == NULL)
|
||||
check_mysql_query_config_wrapper validate_arguments(check_mysql_query_config_wrapper config_wrapper) {
|
||||
if (config_wrapper.config.sql_query == NULL) {
|
||||
usage("Must specify a SQL query to run");
|
||||
}
|
||||
|
||||
if (db_user == NULL)
|
||||
db_user = strdup("");
|
||||
if (config_wrapper.config.db_user == NULL) {
|
||||
config_wrapper.config.db_user = strdup("");
|
||||
}
|
||||
|
||||
if (db_host == NULL)
|
||||
db_host = strdup("");
|
||||
if (config_wrapper.config.db_host == NULL) {
|
||||
config_wrapper.config.db_host = strdup("");
|
||||
}
|
||||
|
||||
if (db == NULL)
|
||||
db = strdup("");
|
||||
if (config_wrapper.config.db == NULL) {
|
||||
config_wrapper.config.db = strdup("");
|
||||
}
|
||||
|
||||
return OK;
|
||||
return config_wrapper;
|
||||
}
|
||||
|
||||
void print_help(void) {
|
||||
|
|
|
|||
36
plugins/check_mysql_query.d/config.h
Normal file
36
plugins/check_mysql_query.d/config.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../config.h"
|
||||
#include "thresholds.h"
|
||||
#include <mysql.h>
|
||||
|
||||
typedef struct {
|
||||
char *db_host;
|
||||
char *db_socket;
|
||||
char *db;
|
||||
char *db_user;
|
||||
char *db_pass;
|
||||
char *opt_file;
|
||||
char *opt_group;
|
||||
unsigned int db_port;
|
||||
|
||||
char *sql_query;
|
||||
thresholds *my_thresholds;
|
||||
} check_mysql_query_config;
|
||||
|
||||
check_mysql_query_config check_mysql_query_config_init() {
|
||||
check_mysql_query_config tmp = {
|
||||
.db_host = NULL,
|
||||
.db_socket = NULL,
|
||||
.db = NULL,
|
||||
.db_user = NULL,
|
||||
.db_pass = NULL,
|
||||
.opt_file = NULL,
|
||||
.opt_group = NULL,
|
||||
.db_port = MYSQL_PORT,
|
||||
|
||||
.sql_query = NULL,
|
||||
.my_thresholds = NULL,
|
||||
};
|
||||
return tmp;
|
||||
}
|
||||
|
|
@ -39,47 +39,20 @@ const char *email = "devel@monitoring-plugins.org";
|
|||
#include "common.h"
|
||||
#include "runcmd.h"
|
||||
#include "utils.h"
|
||||
#include "states.h"
|
||||
#include "check_nagios.d/config.h"
|
||||
|
||||
static int process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
typedef struct {
|
||||
int errorcode;
|
||||
check_nagios_config config;
|
||||
} check_nagios_config_wrapper;
|
||||
static check_nagios_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
static void print_help(void);
|
||||
void print_usage(void);
|
||||
|
||||
static char *status_log = NULL;
|
||||
static char *process_string = NULL;
|
||||
static int expire_minutes = 0;
|
||||
|
||||
static int verbose = 0;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int result = STATE_UNKNOWN;
|
||||
char input_buffer[MAX_INPUT_BUFFER];
|
||||
unsigned long latest_entry_time = 0L;
|
||||
unsigned long temp_entry_time = 0L;
|
||||
int proc_entries = 0;
|
||||
time_t current_time;
|
||||
char *temp_ptr;
|
||||
FILE *fp;
|
||||
int procuid = 0;
|
||||
int procpid = 0;
|
||||
int procppid = 0;
|
||||
int procvsz = 0;
|
||||
int procrss = 0;
|
||||
float procpcpu = 0;
|
||||
char procstat[8];
|
||||
#ifdef PS_USES_PROCETIME
|
||||
char procetime[MAX_INPUT_BUFFER];
|
||||
#endif /* PS_USES_PROCETIME */
|
||||
char procprog[MAX_INPUT_BUFFER];
|
||||
char *procargs;
|
||||
int pos;
|
||||
int cols;
|
||||
int expected_cols = PS_COLS - 1;
|
||||
const char *zombie = "Z";
|
||||
char *temp_string;
|
||||
output chld_out;
|
||||
output chld_err;
|
||||
size_t i;
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
textdomain(PACKAGE);
|
||||
|
|
@ -87,8 +60,13 @@ int main(int argc, char **argv) {
|
|||
/* Parse extra opts if any */
|
||||
argv = np_extra_opts(&argc, argv, progname);
|
||||
|
||||
if (process_arguments(argc, argv) == ERROR)
|
||||
check_nagios_config_wrapper tmp_config = process_arguments(argc, argv);
|
||||
|
||||
if (tmp_config.errorcode == ERROR) {
|
||||
usage_va(_("Could not parse arguments"));
|
||||
}
|
||||
|
||||
const check_nagios_config config = tmp_config.config;
|
||||
|
||||
/* Set signal handling and alarm timeout */
|
||||
if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) {
|
||||
|
|
@ -99,13 +77,17 @@ int main(int argc, char **argv) {
|
|||
alarm(timeout_interval);
|
||||
|
||||
/* open the status log */
|
||||
fp = fopen(status_log, "r");
|
||||
if (fp == NULL) {
|
||||
FILE *log_file = fopen(config.status_log, "r");
|
||||
if (log_file == NULL) {
|
||||
die(STATE_CRITICAL, "NAGIOS %s: %s\n", _("CRITICAL"), _("Cannot open status log for reading!"));
|
||||
}
|
||||
|
||||
unsigned long latest_entry_time = 0L;
|
||||
unsigned long temp_entry_time = 0L;
|
||||
char input_buffer[MAX_INPUT_BUFFER];
|
||||
char *temp_ptr;
|
||||
/* get the date/time of the last item updated in the log */
|
||||
while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, fp)) {
|
||||
while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, log_file)) {
|
||||
if ((temp_ptr = strstr(input_buffer, "created=")) != NULL) {
|
||||
temp_entry_time = strtoul(temp_ptr + 8, NULL, 10);
|
||||
latest_entry_time = temp_entry_time;
|
||||
|
|
@ -113,22 +95,44 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
if ((temp_ptr = strtok(input_buffer, "]")) != NULL) {
|
||||
temp_entry_time = strtoul(temp_ptr + 1, NULL, 10);
|
||||
if (temp_entry_time > latest_entry_time)
|
||||
if (temp_entry_time > latest_entry_time) {
|
||||
latest_entry_time = temp_entry_time;
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
fclose(log_file);
|
||||
|
||||
if (verbose >= 2)
|
||||
if (verbose >= 2) {
|
||||
printf("command: %s\n", PS_COMMAND);
|
||||
}
|
||||
|
||||
/* run the command to check for the Nagios process.. */
|
||||
if ((result = np_runcmd(PS_COMMAND, &chld_out, &chld_err, 0)) != 0)
|
||||
mp_state_enum result = STATE_UNKNOWN;
|
||||
output chld_out;
|
||||
output chld_err;
|
||||
if ((result = np_runcmd(PS_COMMAND, &chld_out, &chld_err, 0)) != 0) {
|
||||
result = STATE_WARNING;
|
||||
}
|
||||
|
||||
int procuid = 0;
|
||||
int procpid = 0;
|
||||
int procppid = 0;
|
||||
int procvsz = 0;
|
||||
int procrss = 0;
|
||||
int proc_entries = 0;
|
||||
float procpcpu = 0;
|
||||
char procstat[8];
|
||||
char procprog[MAX_INPUT_BUFFER];
|
||||
char *procargs;
|
||||
#ifdef PS_USES_PROCETIME
|
||||
char procetime[MAX_INPUT_BUFFER];
|
||||
#endif /* PS_USES_PROCETIME */
|
||||
int pos;
|
||||
int expected_cols = PS_COLS - 1;
|
||||
const char *zombie = "Z";
|
||||
/* count the number of matching Nagios processes... */
|
||||
for (i = 0; i < chld_out.lines; i++) {
|
||||
cols = sscanf(chld_out.line[i], PS_FORMAT, PS_VARLIST);
|
||||
for (size_t i = 0; i < chld_out.lines; i++) {
|
||||
int cols = sscanf(chld_out.line[i], PS_FORMAT, PS_VARLIST);
|
||||
/* Zombie processes do not give a procprog command */
|
||||
if (cols == (expected_cols - 1) && strstr(procstat, zombie)) {
|
||||
cols = expected_cols;
|
||||
|
|
@ -142,14 +146,14 @@ int main(int argc, char **argv) {
|
|||
strip(procargs);
|
||||
|
||||
/* Some ps return full pathname for command. This removes path */
|
||||
temp_string = strtok((char *)procprog, "/");
|
||||
char *temp_string = strtok((char *)procprog, "/");
|
||||
while (temp_string) {
|
||||
strcpy(procprog, temp_string);
|
||||
temp_string = strtok(NULL, "/");
|
||||
}
|
||||
|
||||
/* May get empty procargs */
|
||||
if (!strstr(procargs, argv[0]) && strstr(procargs, process_string) && strcmp(procargs, "")) {
|
||||
if (!strstr(procargs, argv[0]) && strstr(procargs, config.process_string) && strcmp(procargs, "")) {
|
||||
proc_entries++;
|
||||
if (verbose >= 2) {
|
||||
printf(_("Found process: %s %s\n"), procprog, procargs);
|
||||
|
|
@ -159,8 +163,9 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
/* If we get anything on stderr, at least set warning */
|
||||
if (chld_err.buflen)
|
||||
if (chld_err.buflen) {
|
||||
result = max_state(result, STATE_WARNING);
|
||||
}
|
||||
|
||||
/* reset the alarm handler */
|
||||
alarm(0);
|
||||
|
|
@ -173,8 +178,9 @@ int main(int argc, char **argv) {
|
|||
die(STATE_CRITICAL, "NAGIOS %s: %s\n", _("CRITICAL"), _("Cannot parse Nagios log file for valid time"));
|
||||
}
|
||||
|
||||
time_t current_time;
|
||||
time(¤t_time);
|
||||
if ((int)(current_time - latest_entry_time) > (expire_minutes * 60)) {
|
||||
if ((int)(current_time - latest_entry_time) > (config.expire_minutes * 60)) {
|
||||
result = STATE_WARNING;
|
||||
} else {
|
||||
result = STATE_OK;
|
||||
|
|
@ -187,39 +193,45 @@ int main(int argc, char **argv) {
|
|||
(int)(current_time - latest_entry_time));
|
||||
printf("\n");
|
||||
|
||||
return result;
|
||||
exit(result);
|
||||
}
|
||||
|
||||
/* process command-line arguments */
|
||||
int process_arguments(int argc, char **argv) {
|
||||
int c;
|
||||
|
||||
int option = 0;
|
||||
check_nagios_config_wrapper process_arguments(int argc, char **argv) {
|
||||
static struct option longopts[] = {{"filename", required_argument, 0, 'F'}, {"expires", required_argument, 0, 'e'},
|
||||
{"command", required_argument, 0, 'C'}, {"timeout", optional_argument, 0, 't'},
|
||||
{"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'},
|
||||
{"verbose", no_argument, 0, 'v'}, {0, 0, 0, 0}};
|
||||
|
||||
if (argc < 2)
|
||||
return ERROR;
|
||||
|
||||
if (!is_option(argv[1])) {
|
||||
status_log = argv[1];
|
||||
if (is_intnonneg(argv[2]))
|
||||
expire_minutes = atoi(argv[2]);
|
||||
else
|
||||
die(STATE_UNKNOWN, _("Expiration time must be an integer (seconds)\n"));
|
||||
process_string = argv[3];
|
||||
return OK;
|
||||
check_nagios_config_wrapper result = {
|
||||
.errorcode = OK,
|
||||
.config = check_nagios_config_init(),
|
||||
};
|
||||
if (argc < 2) {
|
||||
result.errorcode = ERROR;
|
||||
return result;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
c = getopt_long(argc, argv, "+hVvF:C:e:t:", longopts, &option);
|
||||
if (!is_option(argv[1])) {
|
||||
result.config.status_log = argv[1];
|
||||
if (is_intnonneg(argv[2])) {
|
||||
result.config.expire_minutes = atoi(argv[2]);
|
||||
} else {
|
||||
die(STATE_UNKNOWN, _("Expiration time must be an integer (seconds)\n"));
|
||||
}
|
||||
result.config.process_string = argv[3];
|
||||
return result;
|
||||
}
|
||||
|
||||
if (c == -1 || c == EOF || c == 1)
|
||||
int option = 0;
|
||||
while (true) {
|
||||
int option_index = getopt_long(argc, argv, "+hVvF:C:e:t:", longopts, &option);
|
||||
|
||||
if (option_index == -1 || option_index == EOF || option_index == 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (c) {
|
||||
switch (option_index) {
|
||||
case 'h': /* help */
|
||||
print_help();
|
||||
exit(STATE_UNKNOWN);
|
||||
|
|
@ -227,22 +239,24 @@ int process_arguments(int argc, char **argv) {
|
|||
print_revision(progname, NP_VERSION);
|
||||
exit(STATE_UNKNOWN);
|
||||
case 'F': /* status log */
|
||||
status_log = optarg;
|
||||
result.config.status_log = optarg;
|
||||
break;
|
||||
case 'C': /* command */
|
||||
process_string = optarg;
|
||||
result.config.process_string = optarg;
|
||||
break;
|
||||
case 'e': /* expiry time */
|
||||
if (is_intnonneg(optarg))
|
||||
expire_minutes = atoi(optarg);
|
||||
else
|
||||
if (is_intnonneg(optarg)) {
|
||||
result.config.expire_minutes = atoi(optarg);
|
||||
} else {
|
||||
die(STATE_UNKNOWN, _("Expiration time must be an integer (seconds)\n"));
|
||||
}
|
||||
break;
|
||||
case 't': /* timeout */
|
||||
if (is_intnonneg(optarg))
|
||||
if (is_intnonneg(optarg)) {
|
||||
timeout_interval = atoi(optarg);
|
||||
else
|
||||
} else {
|
||||
die(STATE_UNKNOWN, _("Timeout must be an integer (seconds)\n"));
|
||||
}
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
|
|
@ -252,13 +266,15 @@ int process_arguments(int argc, char **argv) {
|
|||
}
|
||||
}
|
||||
|
||||
if (status_log == NULL)
|
||||
if (result.config.status_log == NULL) {
|
||||
die(STATE_UNKNOWN, _("You must provide the status_log\n"));
|
||||
}
|
||||
|
||||
if (process_string == NULL)
|
||||
if (result.config.process_string == NULL) {
|
||||
die(STATE_UNKNOWN, _("You must provide a process string\n"));
|
||||
}
|
||||
|
||||
return OK;
|
||||
return result;
|
||||
}
|
||||
|
||||
void print_help(void) {
|
||||
|
|
|
|||
19
plugins/check_nagios.d/config.h
Normal file
19
plugins/check_nagios.d/config.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../config.h"
|
||||
#include <stddef.h>
|
||||
|
||||
typedef struct {
|
||||
char *status_log;
|
||||
char *process_string;
|
||||
int expire_minutes;
|
||||
} check_nagios_config;
|
||||
|
||||
check_nagios_config check_nagios_config_init() {
|
||||
check_nagios_config tmp = {
|
||||
.status_log = NULL,
|
||||
.process_string = NULL,
|
||||
.expire_minutes = 0,
|
||||
};
|
||||
return tmp;
|
||||
}
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
* This plugin collects data from the NSClient service running on a
|
||||
* Windows NT/2000/XP/2003 server.
|
||||
* This plugin requires NSClient software to run on NT
|
||||
* (http://nsclient.ready2run.nl/)
|
||||
* (https://nsclient.org/)
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
|
|
@ -39,82 +39,28 @@ const char *email = "devel@monitoring-plugins.org";
|
|||
#include "common.h"
|
||||
#include "netutils.h"
|
||||
#include "utils.h"
|
||||
|
||||
enum checkvars {
|
||||
CHECK_NONE,
|
||||
CHECK_CLIENTVERSION,
|
||||
CHECK_CPULOAD,
|
||||
CHECK_UPTIME,
|
||||
CHECK_USEDDISKSPACE,
|
||||
CHECK_SERVICESTATE,
|
||||
CHECK_PROCSTATE,
|
||||
CHECK_MEMUSE,
|
||||
CHECK_COUNTER,
|
||||
CHECK_FILEAGE,
|
||||
CHECK_INSTANCES
|
||||
};
|
||||
#include "check_nt.d/config.h"
|
||||
|
||||
enum {
|
||||
MAX_VALUE_LIST = 30,
|
||||
PORT = 1248
|
||||
};
|
||||
|
||||
static char *server_address = NULL;
|
||||
static int server_port = PORT;
|
||||
static char *value_list = NULL;
|
||||
static char *req_password = NULL;
|
||||
static unsigned long lvalue_list[MAX_VALUE_LIST];
|
||||
static unsigned long warning_value = 0L;
|
||||
static unsigned long critical_value = 0L;
|
||||
static bool check_warning_value = false;
|
||||
static bool check_critical_value = false;
|
||||
static enum checkvars vars_to_check = CHECK_NONE;
|
||||
static bool show_all = false;
|
||||
|
||||
static char recv_buffer[MAX_INPUT_BUFFER];
|
||||
|
||||
static void fetch_data(const char *address, int port, const char *sendb);
|
||||
static int process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
|
||||
typedef struct {
|
||||
int errorcode;
|
||||
check_nt_config config;
|
||||
} check_nt_config_wrapper;
|
||||
static check_nt_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
|
||||
static void preparelist(char *string);
|
||||
static bool strtoularray(unsigned long *array, char *string, const char *delim);
|
||||
static void print_help(void);
|
||||
void print_usage(void);
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
/* should be int result = STATE_UNKNOWN; */
|
||||
|
||||
int return_code = STATE_UNKNOWN;
|
||||
char *send_buffer = NULL;
|
||||
char *output_message = NULL;
|
||||
char *perfdata = NULL;
|
||||
char *temp_string = NULL;
|
||||
char *temp_string_perf = NULL;
|
||||
char *description = NULL, *counter_unit = NULL;
|
||||
char *minval = NULL, *maxval = NULL, *errcvt = NULL;
|
||||
char *fds = NULL, *tds = NULL;
|
||||
char *numstr;
|
||||
|
||||
double total_disk_space = 0;
|
||||
double free_disk_space = 0;
|
||||
double percent_used_space = 0;
|
||||
double warning_used_space = 0;
|
||||
double critical_used_space = 0;
|
||||
double mem_commitLimit = 0;
|
||||
double mem_commitByte = 0;
|
||||
double fminval = 0, fmaxval = 0;
|
||||
unsigned long utilization;
|
||||
unsigned long uptime;
|
||||
unsigned long age_in_minutes;
|
||||
double counter_value = 0.0;
|
||||
int offset = 0;
|
||||
int updays = 0;
|
||||
int uphours = 0;
|
||||
int upminutes = 0;
|
||||
|
||||
bool isPercent = false;
|
||||
bool allRight = false;
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
textdomain(PACKAGE);
|
||||
|
|
@ -122,8 +68,12 @@ int main(int argc, char **argv) {
|
|||
/* Parse extra opts if any */
|
||||
argv = np_extra_opts(&argc, argv, progname);
|
||||
|
||||
if (process_arguments(argc, argv) == ERROR)
|
||||
check_nt_config_wrapper tmp_config = process_arguments(argc, argv);
|
||||
if (tmp_config.errorcode == ERROR) {
|
||||
usage4(_("Could not parse arguments"));
|
||||
}
|
||||
|
||||
const check_nt_config config = tmp_config.config;
|
||||
|
||||
/* initialize alarm signal handling */
|
||||
signal(SIGALRM, socket_timeout_alarm_handler);
|
||||
|
|
@ -131,49 +81,57 @@ int main(int argc, char **argv) {
|
|||
/* set socket timeout */
|
||||
alarm(socket_timeout);
|
||||
|
||||
switch (vars_to_check) {
|
||||
|
||||
int return_code = STATE_UNKNOWN;
|
||||
char *send_buffer = NULL;
|
||||
char *output_message = NULL;
|
||||
char *perfdata = NULL;
|
||||
char *temp_string = NULL;
|
||||
char *temp_string_perf = NULL;
|
||||
char *description = NULL;
|
||||
char *counter_unit = NULL;
|
||||
char *errcvt = NULL;
|
||||
unsigned long lvalue_list[MAX_VALUE_LIST];
|
||||
switch (config.vars_to_check) {
|
||||
case CHECK_CLIENTVERSION:
|
||||
|
||||
xasprintf(&send_buffer, "%s&1", req_password);
|
||||
fetch_data(server_address, server_port, send_buffer);
|
||||
if (value_list != NULL && strcmp(recv_buffer, value_list) != 0) {
|
||||
xasprintf(&output_message, _("Wrong client version - running: %s, required: %s"), recv_buffer, value_list);
|
||||
xasprintf(&send_buffer, "%s&1", config.req_password);
|
||||
fetch_data(config.server_address, config.server_port, send_buffer);
|
||||
if (config.value_list != NULL && strcmp(recv_buffer, config.value_list) != 0) {
|
||||
xasprintf(&output_message, _("Wrong client version - running: %s, required: %s"), recv_buffer, config.value_list);
|
||||
return_code = STATE_WARNING;
|
||||
} else {
|
||||
xasprintf(&output_message, "%s", recv_buffer);
|
||||
return_code = STATE_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case CHECK_CPULOAD:
|
||||
|
||||
if (value_list == NULL)
|
||||
if (config.value_list == NULL) {
|
||||
output_message = strdup(_("missing -l parameters"));
|
||||
else if (!strtoularray(lvalue_list, value_list, ","))
|
||||
} else if (!strtoularray(lvalue_list, config.value_list, ",")) {
|
||||
output_message = strdup(_("wrong -l parameter."));
|
||||
else {
|
||||
} else {
|
||||
/* -l parameters is present with only integers */
|
||||
return_code = STATE_OK;
|
||||
temp_string = strdup(_("CPU Load"));
|
||||
temp_string_perf = strdup(" ");
|
||||
|
||||
/* loop until one of the parameters is wrong or not present */
|
||||
int offset = 0;
|
||||
while (lvalue_list[0 + offset] > (unsigned long)0 && lvalue_list[0 + offset] <= (unsigned long)17280 &&
|
||||
lvalue_list[1 + offset] > (unsigned long)0 && lvalue_list[1 + offset] <= (unsigned long)100 &&
|
||||
lvalue_list[2 + offset] > (unsigned long)0 && lvalue_list[2 + offset] <= (unsigned long)100) {
|
||||
|
||||
/* Send request and retrieve data */
|
||||
xasprintf(&send_buffer, "%s&2&%lu", req_password, lvalue_list[0 + offset]);
|
||||
fetch_data(server_address, server_port, send_buffer);
|
||||
xasprintf(&send_buffer, "%s&2&%lu", config.req_password, lvalue_list[0 + offset]);
|
||||
fetch_data(config.server_address, config.server_port, send_buffer);
|
||||
|
||||
utilization = strtoul(recv_buffer, NULL, 10);
|
||||
unsigned long utilization = strtoul(recv_buffer, NULL, 10);
|
||||
|
||||
/* Check if any of the request is in a warning or critical state */
|
||||
if (utilization >= lvalue_list[2 + offset])
|
||||
if (utilization >= lvalue_list[2 + offset]) {
|
||||
return_code = STATE_CRITICAL;
|
||||
else if (utilization >= lvalue_list[1 + offset] && return_code < STATE_WARNING)
|
||||
} else if (utilization >= lvalue_list[1 + offset] && return_code < STATE_WARNING) {
|
||||
return_code = STATE_WARNING;
|
||||
}
|
||||
|
||||
xasprintf(&output_message, _(" %lu%% (%lu min average)"), utilization, lvalue_list[0 + offset]);
|
||||
xasprintf(&temp_string, "%s%s", temp_string, output_message);
|
||||
|
|
@ -186,82 +144,87 @@ int main(int argc, char **argv) {
|
|||
if (strlen(temp_string) > 10) { /* we had at least one loop */
|
||||
output_message = strdup(temp_string);
|
||||
perfdata = temp_string_perf;
|
||||
} else
|
||||
} else {
|
||||
output_message = strdup(_("not enough values for -l parameters"));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CHECK_UPTIME:
|
||||
|
||||
if (value_list == NULL) {
|
||||
value_list = "minutes";
|
||||
case CHECK_UPTIME: {
|
||||
char *tmp_value_list = config.value_list;
|
||||
if (config.value_list == NULL) {
|
||||
tmp_value_list = "minutes";
|
||||
}
|
||||
if (strncmp(value_list, "seconds", strlen("seconds") + 1) && strncmp(value_list, "minutes", strlen("minutes") + 1) &&
|
||||
strncmp(value_list, "hours", strlen("hours") + 1) && strncmp(value_list, "days", strlen("days") + 1)) {
|
||||
if (strncmp(tmp_value_list, "seconds", strlen("seconds") + 1) && strncmp(tmp_value_list, "minutes", strlen("minutes") + 1) &&
|
||||
strncmp(config.value_list, "hours", strlen("hours") + 1) && strncmp(tmp_value_list, "days", strlen("days") + 1)) {
|
||||
|
||||
output_message = strdup(_("wrong -l argument"));
|
||||
} else {
|
||||
xasprintf(&send_buffer, "%s&3", req_password);
|
||||
fetch_data(server_address, server_port, send_buffer);
|
||||
uptime = strtoul(recv_buffer, NULL, 10);
|
||||
updays = uptime / 86400;
|
||||
uphours = (uptime % 86400) / 3600;
|
||||
upminutes = ((uptime % 86400) % 3600) / 60;
|
||||
xasprintf(&send_buffer, "%s&3", config.req_password);
|
||||
fetch_data(config.server_address, config.server_port, send_buffer);
|
||||
unsigned long uptime = strtoul(recv_buffer, NULL, 10);
|
||||
int updays = uptime / 86400;
|
||||
int uphours = (uptime % 86400) / 3600;
|
||||
int upminutes = ((uptime % 86400) % 3600) / 60;
|
||||
|
||||
if (!strncmp(value_list, "minutes", strlen("minutes")))
|
||||
if (!strncmp(tmp_value_list, "minutes", strlen("minutes"))) {
|
||||
uptime = uptime / 60;
|
||||
else if (!strncmp(value_list, "hours", strlen("hours")))
|
||||
} else if (!strncmp(tmp_value_list, "hours", strlen("hours"))) {
|
||||
uptime = uptime / 3600;
|
||||
else if (!strncmp(value_list, "days", strlen("days")))
|
||||
} else if (!strncmp(tmp_value_list, "days", strlen("days"))) {
|
||||
uptime = uptime / 86400;
|
||||
}
|
||||
/* else uptime in seconds, nothing to do */
|
||||
|
||||
xasprintf(&output_message, _("System Uptime - %u day(s) %u hour(s) %u minute(s) |uptime=%lu"), updays, uphours, upminutes,
|
||||
uptime);
|
||||
|
||||
if (check_critical_value && uptime <= critical_value)
|
||||
if (config.check_critical_value && uptime <= config.critical_value) {
|
||||
return_code = STATE_CRITICAL;
|
||||
else if (check_warning_value && uptime <= warning_value)
|
||||
} else if (config.check_warning_value && uptime <= config.warning_value) {
|
||||
return_code = STATE_WARNING;
|
||||
else
|
||||
} else {
|
||||
return_code = STATE_OK;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
} break;
|
||||
case CHECK_USEDDISKSPACE:
|
||||
|
||||
if (value_list == NULL)
|
||||
if (config.value_list == NULL) {
|
||||
output_message = strdup(_("missing -l parameters"));
|
||||
else if (strlen(value_list) != 1)
|
||||
} else if (strlen(config.value_list) != 1) {
|
||||
output_message = strdup(_("wrong -l argument"));
|
||||
else {
|
||||
xasprintf(&send_buffer, "%s&4&%s", req_password, value_list);
|
||||
fetch_data(server_address, server_port, send_buffer);
|
||||
fds = strtok(recv_buffer, "&");
|
||||
tds = strtok(NULL, "&");
|
||||
if (fds != NULL)
|
||||
} else {
|
||||
xasprintf(&send_buffer, "%s&4&%s", config.req_password, config.value_list);
|
||||
fetch_data(config.server_address, config.server_port, send_buffer);
|
||||
char *fds = strtok(recv_buffer, "&");
|
||||
char *tds = strtok(NULL, "&");
|
||||
double total_disk_space = 0;
|
||||
double free_disk_space = 0;
|
||||
if (fds != NULL) {
|
||||
free_disk_space = atof(fds);
|
||||
if (tds != NULL)
|
||||
}
|
||||
if (tds != NULL) {
|
||||
total_disk_space = atof(tds);
|
||||
}
|
||||
|
||||
if (total_disk_space > 0 && free_disk_space >= 0) {
|
||||
percent_used_space = ((total_disk_space - free_disk_space) / total_disk_space) * 100;
|
||||
warning_used_space = ((float)warning_value / 100) * total_disk_space;
|
||||
critical_used_space = ((float)critical_value / 100) * total_disk_space;
|
||||
double percent_used_space = ((total_disk_space - free_disk_space) / total_disk_space) * 100;
|
||||
double warning_used_space = ((float)config.warning_value / 100) * total_disk_space;
|
||||
double critical_used_space = ((float)config.critical_value / 100) * total_disk_space;
|
||||
|
||||
xasprintf(&temp_string, _("%s:\\ - total: %.2f Gb - used: %.2f Gb (%.0f%%) - free %.2f Gb (%.0f%%)"), value_list,
|
||||
xasprintf(&temp_string, _("%s:\\ - total: %.2f Gb - used: %.2f Gb (%.0f%%) - free %.2f Gb (%.0f%%)"), config.value_list,
|
||||
total_disk_space / 1073741824, (total_disk_space - free_disk_space) / 1073741824, percent_used_space,
|
||||
free_disk_space / 1073741824, (free_disk_space / total_disk_space) * 100);
|
||||
xasprintf(&temp_string_perf, _("'%s:\\ Used Space'=%.2fGb;%.2f;%.2f;0.00;%.2f"), value_list,
|
||||
xasprintf(&temp_string_perf, _("'%s:\\ Used Space'=%.2fGb;%.2f;%.2f;0.00;%.2f"), config.value_list,
|
||||
(total_disk_space - free_disk_space) / 1073741824, warning_used_space / 1073741824,
|
||||
critical_used_space / 1073741824, total_disk_space / 1073741824);
|
||||
|
||||
if (check_critical_value && percent_used_space >= critical_value)
|
||||
if (config.check_critical_value && percent_used_space >= config.critical_value) {
|
||||
return_code = STATE_CRITICAL;
|
||||
else if (check_warning_value && percent_used_space >= warning_value)
|
||||
} else if (config.check_warning_value && percent_used_space >= config.warning_value) {
|
||||
return_code = STATE_WARNING;
|
||||
else
|
||||
} else {
|
||||
return_code = STATE_OK;
|
||||
}
|
||||
|
||||
output_message = strdup(temp_string);
|
||||
perfdata = temp_string_perf;
|
||||
|
|
@ -271,41 +234,40 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CHECK_SERVICESTATE:
|
||||
case CHECK_PROCSTATE:
|
||||
|
||||
if (value_list == NULL)
|
||||
if (config.value_list == NULL) {
|
||||
output_message = strdup(_("No service/process specified"));
|
||||
else {
|
||||
preparelist(value_list); /* replace , between services with & to send the request */
|
||||
xasprintf(&send_buffer, "%s&%u&%s&%s", req_password, (vars_to_check == CHECK_SERVICESTATE) ? 5 : 6,
|
||||
(show_all) ? "ShowAll" : "ShowFail", value_list);
|
||||
fetch_data(server_address, server_port, send_buffer);
|
||||
numstr = strtok(recv_buffer, "&");
|
||||
if (numstr == NULL)
|
||||
} else {
|
||||
preparelist(config.value_list); /* replace , between services with & to send the request */
|
||||
xasprintf(&send_buffer, "%s&%u&%s&%s", config.req_password, (config.vars_to_check == CHECK_SERVICESTATE) ? 5 : 6,
|
||||
(config.show_all) ? "ShowAll" : "ShowFail", config.value_list);
|
||||
fetch_data(config.server_address, config.server_port, send_buffer);
|
||||
char *numstr = strtok(recv_buffer, "&");
|
||||
if (numstr == NULL) {
|
||||
die(STATE_UNKNOWN, _("could not fetch information from server\n"));
|
||||
}
|
||||
return_code = atoi(numstr);
|
||||
temp_string = strtok(NULL, "&");
|
||||
output_message = strdup(temp_string);
|
||||
}
|
||||
break;
|
||||
|
||||
case CHECK_MEMUSE:
|
||||
|
||||
xasprintf(&send_buffer, "%s&7", req_password);
|
||||
fetch_data(server_address, server_port, send_buffer);
|
||||
numstr = strtok(recv_buffer, "&");
|
||||
if (numstr == NULL)
|
||||
xasprintf(&send_buffer, "%s&7", config.req_password);
|
||||
fetch_data(config.server_address, config.server_port, send_buffer);
|
||||
char *numstr = strtok(recv_buffer, "&");
|
||||
if (numstr == NULL) {
|
||||
die(STATE_UNKNOWN, _("could not fetch information from server\n"));
|
||||
mem_commitLimit = atof(numstr);
|
||||
}
|
||||
double mem_commitLimit = atof(numstr);
|
||||
numstr = strtok(NULL, "&");
|
||||
if (numstr == NULL)
|
||||
if (numstr == NULL) {
|
||||
die(STATE_UNKNOWN, _("could not fetch information from server\n"));
|
||||
mem_commitByte = atof(numstr);
|
||||
percent_used_space = (mem_commitByte / mem_commitLimit) * 100;
|
||||
warning_used_space = ((float)warning_value / 100) * mem_commitLimit;
|
||||
critical_used_space = ((float)critical_value / 100) * mem_commitLimit;
|
||||
}
|
||||
double mem_commitByte = atof(numstr);
|
||||
double percent_used_space = (mem_commitByte / mem_commitLimit) * 100;
|
||||
double warning_used_space = ((float)config.warning_value / 100) * mem_commitLimit;
|
||||
double critical_used_space = ((float)config.critical_value / 100) * mem_commitLimit;
|
||||
|
||||
/* Divisor should be 1048567, not 3044515, as we are measuring "Commit Charge" here,
|
||||
which equals RAM + Pagefiles. */
|
||||
|
|
@ -316,15 +278,14 @@ int main(int argc, char **argv) {
|
|||
critical_used_space / 1048567, mem_commitLimit / 1048567);
|
||||
|
||||
return_code = STATE_OK;
|
||||
if (check_critical_value && percent_used_space >= critical_value)
|
||||
if (config.check_critical_value && percent_used_space >= config.critical_value) {
|
||||
return_code = STATE_CRITICAL;
|
||||
else if (check_warning_value && percent_used_space >= warning_value)
|
||||
} else if (config.check_warning_value && percent_used_space >= config.warning_value) {
|
||||
return_code = STATE_WARNING;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case CHECK_COUNTER:
|
||||
|
||||
case CHECK_COUNTER: {
|
||||
/*
|
||||
CHECK_COUNTER has been modified to provide extensive perfdata information.
|
||||
In order to do this, some modifications have been done to the code
|
||||
|
|
@ -346,26 +307,32 @@ int main(int argc, char **argv) {
|
|||
strange things will happen when you make graphs of your data.
|
||||
*/
|
||||
|
||||
if (value_list == NULL)
|
||||
double counter_value = 0.0;
|
||||
if (config.value_list == NULL) {
|
||||
output_message = strdup(_("No counter specified"));
|
||||
else {
|
||||
preparelist(value_list); /* replace , between services with & to send the request */
|
||||
isPercent = (strchr(value_list, '%') != NULL);
|
||||
} else {
|
||||
preparelist(config.value_list); /* replace , between services with & to send the request */
|
||||
bool isPercent = (strchr(config.value_list, '%') != NULL);
|
||||
|
||||
strtok(value_list, "&"); /* burn the first parameters */
|
||||
strtok(config.value_list, "&"); /* burn the first parameters */
|
||||
description = strtok(NULL, "&");
|
||||
counter_unit = strtok(NULL, "&");
|
||||
xasprintf(&send_buffer, "%s&8&%s", req_password, value_list);
|
||||
fetch_data(server_address, server_port, send_buffer);
|
||||
xasprintf(&send_buffer, "%s&8&%s", config.req_password, config.value_list);
|
||||
fetch_data(config.server_address, config.server_port, send_buffer);
|
||||
counter_value = atof(recv_buffer);
|
||||
|
||||
if (description == NULL)
|
||||
bool allRight = false;
|
||||
if (description == NULL) {
|
||||
xasprintf(&output_message, "%.f", counter_value);
|
||||
else if (isPercent) {
|
||||
} else if (isPercent) {
|
||||
counter_unit = strdup("%");
|
||||
allRight = true;
|
||||
}
|
||||
|
||||
char *minval = NULL;
|
||||
char *maxval = NULL;
|
||||
double fminval = 0;
|
||||
double fmaxval = 0;
|
||||
if ((counter_unit != NULL) && (!allRight)) {
|
||||
minval = strtok(NULL, "&");
|
||||
maxval = strtok(NULL, "&");
|
||||
|
|
@ -375,16 +342,18 @@ int main(int argc, char **argv) {
|
|||
fminval = (minval != NULL) ? strtod(minval, &errcvt) : -1;
|
||||
fmaxval = (minval != NULL) ? strtod(maxval, &errcvt) : -1;
|
||||
|
||||
if ((fminval == 0) && (minval == errcvt))
|
||||
if ((fminval == 0) && (minval == errcvt)) {
|
||||
output_message = strdup(_("Minimum value contains non-numbers"));
|
||||
else {
|
||||
if ((fmaxval == 0) && (maxval == errcvt))
|
||||
} else {
|
||||
if ((fmaxval == 0) && (maxval == errcvt)) {
|
||||
output_message = strdup(_("Maximum value contains non-numbers"));
|
||||
else
|
||||
} else {
|
||||
allRight = true; /* Everything is OK. */
|
||||
}
|
||||
}
|
||||
} else if ((counter_unit == NULL) && (description != NULL))
|
||||
} else if ((counter_unit == NULL) && (description != NULL)) {
|
||||
output_message = strdup(_("No unit counter specified"));
|
||||
}
|
||||
|
||||
if (allRight) {
|
||||
/* Let's format the output string, finally... */
|
||||
|
|
@ -396,63 +365,65 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
xasprintf(&output_message, "%s |", output_message);
|
||||
xasprintf(&output_message, "%s %s", output_message,
|
||||
fperfdata(description, counter_value, counter_unit, 1, warning_value, 1, critical_value,
|
||||
fperfdata(description, counter_value, counter_unit, 1, config.warning_value, 1, config.critical_value,
|
||||
(!(isPercent) && (minval != NULL)), fminval, (!(isPercent) && (minval != NULL)), fmaxval));
|
||||
}
|
||||
}
|
||||
|
||||
if (critical_value > warning_value) { /* Normal thresholds */
|
||||
if (check_critical_value && counter_value >= critical_value)
|
||||
if (config.critical_value > config.warning_value) { /* Normal thresholds */
|
||||
if (config.check_critical_value && counter_value >= config.critical_value) {
|
||||
return_code = STATE_CRITICAL;
|
||||
else if (check_warning_value && counter_value >= warning_value)
|
||||
} else if (config.check_warning_value && counter_value >= config.warning_value) {
|
||||
return_code = STATE_WARNING;
|
||||
else
|
||||
} else {
|
||||
return_code = STATE_OK;
|
||||
}
|
||||
} else { /* inverse thresholds */
|
||||
return_code = STATE_OK;
|
||||
if (check_critical_value && counter_value <= critical_value)
|
||||
if (config.check_critical_value && counter_value <= config.critical_value) {
|
||||
return_code = STATE_CRITICAL;
|
||||
else if (check_warning_value && counter_value <= warning_value)
|
||||
} else if (config.check_warning_value && counter_value <= config.warning_value) {
|
||||
return_code = STATE_WARNING;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
} break;
|
||||
case CHECK_FILEAGE:
|
||||
|
||||
if (value_list == NULL)
|
||||
if (config.value_list == NULL) {
|
||||
output_message = strdup(_("No counter specified"));
|
||||
else {
|
||||
preparelist(value_list); /* replace , between services with & to send the request */
|
||||
xasprintf(&send_buffer, "%s&9&%s", req_password, value_list);
|
||||
fetch_data(server_address, server_port, send_buffer);
|
||||
age_in_minutes = atoi(strtok(recv_buffer, "&"));
|
||||
} else {
|
||||
preparelist(config.value_list); /* replace , between services with & to send the request */
|
||||
xasprintf(&send_buffer, "%s&9&%s", config.req_password, config.value_list);
|
||||
fetch_data(config.server_address, config.server_port, send_buffer);
|
||||
unsigned long age_in_minutes = atoi(strtok(recv_buffer, "&"));
|
||||
description = strtok(NULL, "&");
|
||||
output_message = strdup(description);
|
||||
|
||||
if (critical_value > warning_value) { /* Normal thresholds */
|
||||
if (check_critical_value && age_in_minutes >= critical_value)
|
||||
if (config.critical_value > config.warning_value) { /* Normal thresholds */
|
||||
if (config.check_critical_value && age_in_minutes >= config.critical_value) {
|
||||
return_code = STATE_CRITICAL;
|
||||
else if (check_warning_value && age_in_minutes >= warning_value)
|
||||
} else if (config.check_warning_value && age_in_minutes >= config.warning_value) {
|
||||
return_code = STATE_WARNING;
|
||||
else
|
||||
} else {
|
||||
return_code = STATE_OK;
|
||||
}
|
||||
} else { /* inverse thresholds */
|
||||
if (check_critical_value && age_in_minutes <= critical_value)
|
||||
if (config.check_critical_value && age_in_minutes <= config.critical_value) {
|
||||
return_code = STATE_CRITICAL;
|
||||
else if (check_warning_value && age_in_minutes <= warning_value)
|
||||
} else if (config.check_warning_value && age_in_minutes <= config.warning_value) {
|
||||
return_code = STATE_WARNING;
|
||||
else
|
||||
} else {
|
||||
return_code = STATE_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CHECK_INSTANCES:
|
||||
if (value_list == NULL)
|
||||
if (config.value_list == NULL) {
|
||||
output_message = strdup(_("No counter specified"));
|
||||
else {
|
||||
xasprintf(&send_buffer, "%s&10&%s", req_password, value_list);
|
||||
fetch_data(server_address, server_port, send_buffer);
|
||||
} else {
|
||||
xasprintf(&send_buffer, "%s&10&%s", config.req_password, config.value_list);
|
||||
fetch_data(config.server_address, config.server_port, send_buffer);
|
||||
if (!strncmp(recv_buffer, "ERROR", 5)) {
|
||||
printf("NSClient - %s\n", recv_buffer);
|
||||
exit(STATE_UNKNOWN);
|
||||
|
|
@ -471,18 +442,16 @@ int main(int argc, char **argv) {
|
|||
/* reset timeout */
|
||||
alarm(0);
|
||||
|
||||
if (perfdata == NULL)
|
||||
if (perfdata == NULL) {
|
||||
printf("%s\n", output_message);
|
||||
else
|
||||
} else {
|
||||
printf("%s | %s\n", output_message, perfdata);
|
||||
}
|
||||
return return_code;
|
||||
}
|
||||
|
||||
/* process command-line arguments */
|
||||
int process_arguments(int argc, char **argv) {
|
||||
int c;
|
||||
|
||||
int option = 0;
|
||||
check_nt_config_wrapper process_arguments(int argc, char **argv) {
|
||||
static struct option longopts[] = {{"port", required_argument, 0, 'p'},
|
||||
{"timeout", required_argument, 0, 't'},
|
||||
{"critical", required_argument, 0, 'c'},
|
||||
|
|
@ -497,34 +466,44 @@ int process_arguments(int argc, char **argv) {
|
|||
{"help", no_argument, 0, 'h'},
|
||||
{0, 0, 0, 0}};
|
||||
|
||||
check_nt_config_wrapper result = {
|
||||
.errorcode = OK,
|
||||
.config = check_nt_config_init(),
|
||||
};
|
||||
|
||||
/* no options were supplied */
|
||||
if (argc < 2)
|
||||
return ERROR;
|
||||
if (argc < 2) {
|
||||
result.errorcode = ERROR;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* backwards compatibility */
|
||||
if (!is_option(argv[1])) {
|
||||
server_address = strdup(argv[1]);
|
||||
result.config.server_address = strdup(argv[1]);
|
||||
argv[1] = argv[0];
|
||||
argv = &argv[1];
|
||||
argc--;
|
||||
}
|
||||
|
||||
for (c = 1; c < argc; c++) {
|
||||
if (strcmp("-to", argv[c]) == 0)
|
||||
strcpy(argv[c], "-t");
|
||||
else if (strcmp("-wv", argv[c]) == 0)
|
||||
strcpy(argv[c], "-w");
|
||||
else if (strcmp("-cv", argv[c]) == 0)
|
||||
strcpy(argv[c], "-c");
|
||||
for (int index = 1; index < argc; index++) {
|
||||
if (strcmp("-to", argv[index]) == 0) {
|
||||
strcpy(argv[index], "-t");
|
||||
} else if (strcmp("-wv", argv[index]) == 0) {
|
||||
strcpy(argv[index], "-w");
|
||||
} else if (strcmp("-cv", argv[index]) == 0) {
|
||||
strcpy(argv[index], "-c");
|
||||
}
|
||||
}
|
||||
|
||||
while (1) {
|
||||
c = getopt_long(argc, argv, "+hVH:t:c:w:p:v:l:s:d:u", longopts, &option);
|
||||
int option = 0;
|
||||
while (true) {
|
||||
int option_index = getopt_long(argc, argv, "+hVH:t:c:w:p:v:l:s:d:u", longopts, &option);
|
||||
|
||||
if (c == -1 || c == EOF || c == 1)
|
||||
if (option_index == -1 || option_index == EOF || option_index == 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (c) {
|
||||
switch (option_index) {
|
||||
case '?': /* print short usage statement if args not parsable */
|
||||
usage5();
|
||||
case 'h': /* help */
|
||||
|
|
@ -534,118 +513,128 @@ int process_arguments(int argc, char **argv) {
|
|||
print_revision(progname, NP_VERSION);
|
||||
exit(STATE_UNKNOWN);
|
||||
case 'H': /* hostname */
|
||||
server_address = optarg;
|
||||
result.config.server_address = optarg;
|
||||
break;
|
||||
case 's': /* password */
|
||||
req_password = optarg;
|
||||
result.config.req_password = optarg;
|
||||
break;
|
||||
case 'p': /* port */
|
||||
if (is_intnonneg(optarg))
|
||||
server_port = atoi(optarg);
|
||||
else
|
||||
if (is_intnonneg(optarg)) {
|
||||
result.config.server_port = atoi(optarg);
|
||||
} else {
|
||||
die(STATE_UNKNOWN, _("Server port must be an integer\n"));
|
||||
}
|
||||
break;
|
||||
case 'v':
|
||||
if (strlen(optarg) < 4)
|
||||
return ERROR;
|
||||
if (!strcmp(optarg, "CLIENTVERSION"))
|
||||
vars_to_check = CHECK_CLIENTVERSION;
|
||||
else if (!strcmp(optarg, "CPULOAD"))
|
||||
vars_to_check = CHECK_CPULOAD;
|
||||
else if (!strcmp(optarg, "UPTIME"))
|
||||
vars_to_check = CHECK_UPTIME;
|
||||
else if (!strcmp(optarg, "USEDDISKSPACE"))
|
||||
vars_to_check = CHECK_USEDDISKSPACE;
|
||||
else if (!strcmp(optarg, "SERVICESTATE"))
|
||||
vars_to_check = CHECK_SERVICESTATE;
|
||||
else if (!strcmp(optarg, "PROCSTATE"))
|
||||
vars_to_check = CHECK_PROCSTATE;
|
||||
else if (!strcmp(optarg, "MEMUSE"))
|
||||
vars_to_check = CHECK_MEMUSE;
|
||||
else if (!strcmp(optarg, "COUNTER"))
|
||||
vars_to_check = CHECK_COUNTER;
|
||||
else if (!strcmp(optarg, "FILEAGE"))
|
||||
vars_to_check = CHECK_FILEAGE;
|
||||
else if (!strcmp(optarg, "INSTANCES"))
|
||||
vars_to_check = CHECK_INSTANCES;
|
||||
else
|
||||
return ERROR;
|
||||
if (strlen(optarg) < 4) {
|
||||
result.errorcode = ERROR;
|
||||
return result;
|
||||
}
|
||||
if (!strcmp(optarg, "CLIENTVERSION")) {
|
||||
result.config.vars_to_check = CHECK_CLIENTVERSION;
|
||||
} else if (!strcmp(optarg, "CPULOAD")) {
|
||||
result.config.vars_to_check = CHECK_CPULOAD;
|
||||
} else if (!strcmp(optarg, "UPTIME")) {
|
||||
result.config.vars_to_check = CHECK_UPTIME;
|
||||
} else if (!strcmp(optarg, "USEDDISKSPACE")) {
|
||||
result.config.vars_to_check = CHECK_USEDDISKSPACE;
|
||||
} else if (!strcmp(optarg, "SERVICESTATE")) {
|
||||
result.config.vars_to_check = CHECK_SERVICESTATE;
|
||||
} else if (!strcmp(optarg, "PROCSTATE")) {
|
||||
result.config.vars_to_check = CHECK_PROCSTATE;
|
||||
} else if (!strcmp(optarg, "MEMUSE")) {
|
||||
result.config.vars_to_check = CHECK_MEMUSE;
|
||||
} else if (!strcmp(optarg, "COUNTER")) {
|
||||
result.config.vars_to_check = CHECK_COUNTER;
|
||||
} else if (!strcmp(optarg, "FILEAGE")) {
|
||||
result.config.vars_to_check = CHECK_FILEAGE;
|
||||
} else if (!strcmp(optarg, "INSTANCES")) {
|
||||
result.config.vars_to_check = CHECK_INSTANCES;
|
||||
} else {
|
||||
result.errorcode = ERROR;
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
case 'l': /* value list */
|
||||
value_list = optarg;
|
||||
result.config.value_list = optarg;
|
||||
break;
|
||||
case 'w': /* warning threshold */
|
||||
warning_value = strtoul(optarg, NULL, 10);
|
||||
check_warning_value = true;
|
||||
result.config.warning_value = strtoul(optarg, NULL, 10);
|
||||
result.config.check_warning_value = true;
|
||||
break;
|
||||
case 'c': /* critical threshold */
|
||||
critical_value = strtoul(optarg, NULL, 10);
|
||||
check_critical_value = true;
|
||||
result.config.critical_value = strtoul(optarg, NULL, 10);
|
||||
result.config.check_critical_value = true;
|
||||
break;
|
||||
case 'd': /* Display select for services */
|
||||
if (!strcmp(optarg, "SHOWALL"))
|
||||
show_all = true;
|
||||
if (!strcmp(optarg, "SHOWALL")) {
|
||||
result.config.show_all = true;
|
||||
}
|
||||
break;
|
||||
case 'u':
|
||||
socket_timeout_state = STATE_UNKNOWN;
|
||||
break;
|
||||
case 't': /* timeout */
|
||||
socket_timeout = atoi(optarg);
|
||||
if (socket_timeout <= 0)
|
||||
return ERROR;
|
||||
if (socket_timeout <= 0) {
|
||||
result.errorcode = ERROR;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (server_address == NULL)
|
||||
if (result.config.server_address == NULL) {
|
||||
usage4(_("You must provide a server address or host name"));
|
||||
}
|
||||
|
||||
if (vars_to_check == CHECK_NONE)
|
||||
return ERROR;
|
||||
if (result.config.vars_to_check == CHECK_NONE) {
|
||||
result.errorcode = ERROR;
|
||||
return result;
|
||||
}
|
||||
|
||||
if (req_password == NULL)
|
||||
req_password = strdup(_("None"));
|
||||
if (result.config.req_password == NULL) {
|
||||
result.config.req_password = strdup(_("None"));
|
||||
}
|
||||
|
||||
return OK;
|
||||
return result;
|
||||
}
|
||||
|
||||
void fetch_data(const char *address, int port, const char *sendb) {
|
||||
int result;
|
||||
int result = process_tcp_request(address, port, sendb, recv_buffer, sizeof(recv_buffer));
|
||||
|
||||
result = process_tcp_request(address, port, sendb, recv_buffer, sizeof(recv_buffer));
|
||||
|
||||
if (result != STATE_OK)
|
||||
if (result != STATE_OK) {
|
||||
die(result, _("could not fetch information from server\n"));
|
||||
}
|
||||
|
||||
if (!strncmp(recv_buffer, "ERROR", 5))
|
||||
if (!strncmp(recv_buffer, "ERROR", 5)) {
|
||||
die(STATE_UNKNOWN, "NSClient - %s\n", recv_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
bool strtoularray(unsigned long *array, char *string, const char *delim) {
|
||||
/* split a <delim> delimited string into a long array */
|
||||
int idx = 0;
|
||||
char *t1;
|
||||
|
||||
for (idx = 0; idx < MAX_VALUE_LIST; idx++)
|
||||
for (int idx = 0; idx < MAX_VALUE_LIST; idx++) {
|
||||
array[idx] = 0;
|
||||
}
|
||||
|
||||
idx = 0;
|
||||
for (t1 = strtok(string, delim); t1 != NULL; t1 = strtok(NULL, delim)) {
|
||||
int idx = 0;
|
||||
for (char *t1 = strtok(string, delim); t1 != NULL; t1 = strtok(NULL, delim)) {
|
||||
if (is_numeric(t1) && idx < MAX_VALUE_LIST) {
|
||||
array[idx] = strtoul(t1, NULL, 10);
|
||||
idx++;
|
||||
} else
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void preparelist(char *string) {
|
||||
/* Replace all , with & which is the delimiter for the request */
|
||||
int i;
|
||||
|
||||
for (i = 0; (size_t)i < strlen(string); i++)
|
||||
for (int i = 0; (size_t)i < strlen(string); i++) {
|
||||
if (string[i] == ',') {
|
||||
string[i] = '&';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void print_help(void) {
|
||||
|
|
|
|||
53
plugins/check_nt.d/config.h
Normal file
53
plugins/check_nt.d/config.h
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../config.h"
|
||||
#include <stddef.h>
|
||||
|
||||
enum {
|
||||
PORT = 1248,
|
||||
};
|
||||
|
||||
enum checkvars {
|
||||
CHECK_NONE,
|
||||
CHECK_CLIENTVERSION,
|
||||
CHECK_CPULOAD,
|
||||
CHECK_UPTIME,
|
||||
CHECK_USEDDISKSPACE,
|
||||
CHECK_SERVICESTATE,
|
||||
CHECK_PROCSTATE,
|
||||
CHECK_MEMUSE,
|
||||
CHECK_COUNTER,
|
||||
CHECK_FILEAGE,
|
||||
CHECK_INSTANCES
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
char *server_address;
|
||||
int server_port;
|
||||
char *req_password;
|
||||
enum checkvars vars_to_check;
|
||||
bool show_all;
|
||||
char *value_list;
|
||||
bool check_warning_value;
|
||||
unsigned long warning_value;
|
||||
bool check_critical_value;
|
||||
unsigned long critical_value;
|
||||
} check_nt_config;
|
||||
|
||||
check_nt_config check_nt_config_init() {
|
||||
check_nt_config tmp = {
|
||||
.server_address = NULL,
|
||||
.server_port = PORT,
|
||||
.req_password = NULL,
|
||||
|
||||
.vars_to_check = CHECK_NONE,
|
||||
.show_all = false,
|
||||
.value_list = NULL,
|
||||
|
||||
.check_warning_value = false,
|
||||
.warning_value = 0,
|
||||
.check_critical_value = false,
|
||||
.critical_value = 0,
|
||||
};
|
||||
return tmp;
|
||||
}
|
||||
|
|
@ -35,6 +35,7 @@
|
|||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "thresholds.h"
|
||||
const char *progname = "check_ntp_peer";
|
||||
const char *copyright = "2006-2024";
|
||||
const char *email = "devel@monitoring-plugins.org";
|
||||
|
|
@ -42,30 +43,18 @@ const char *email = "devel@monitoring-plugins.org";
|
|||
#include "common.h"
|
||||
#include "netutils.h"
|
||||
#include "utils.h"
|
||||
#include "../lib/states.h"
|
||||
#include "check_ntp_peer.d/config.h"
|
||||
|
||||
static char *server_address = NULL;
|
||||
static int port = 123;
|
||||
static int verbose = 0;
|
||||
static bool quiet = false;
|
||||
static char *owarn = "60";
|
||||
static char *ocrit = "120";
|
||||
static bool do_stratum = false;
|
||||
static char *swarn = "-1:16";
|
||||
static char *scrit = "-1:16";
|
||||
static bool do_jitter = false;
|
||||
static char *jwarn = "-1:5000";
|
||||
static char *jcrit = "-1:10000";
|
||||
static bool do_truechimers = false;
|
||||
static char *twarn = "0:";
|
||||
static char *tcrit = "0:";
|
||||
static bool syncsource_found = false;
|
||||
static bool li_alarm = false;
|
||||
|
||||
static int process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
static thresholds *offset_thresholds = NULL;
|
||||
static thresholds *jitter_thresholds = NULL;
|
||||
static thresholds *stratum_thresholds = NULL;
|
||||
static thresholds *truechimer_thresholds = NULL;
|
||||
typedef struct {
|
||||
int errorcode;
|
||||
check_ntp_peer_config config;
|
||||
} check_ntp_peer_config_wrapper;
|
||||
static check_ntp_peer_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
static void print_help(void);
|
||||
void print_usage(void);
|
||||
|
||||
|
|
@ -157,25 +146,25 @@ typedef struct {
|
|||
printf("%u.%u.%u.%u", (x >> 24) & 0xff, (x >> 16) & 0xff, (x >> 8) & 0xff, x & 0xff); \
|
||||
} while (0);
|
||||
|
||||
void print_ntp_control_message(const ntp_control_message *p) {
|
||||
void print_ntp_control_message(const ntp_control_message *message) {
|
||||
printf("control packet contents:\n");
|
||||
printf("\tflags: 0x%.2x , 0x%.2x\n", p->flags, p->op);
|
||||
printf("\t li=%d (0x%.2x)\n", LI(p->flags), p->flags & LI_MASK);
|
||||
printf("\t vn=%d (0x%.2x)\n", VN(p->flags), p->flags & VN_MASK);
|
||||
printf("\t mode=%d (0x%.2x)\n", MODE(p->flags), p->flags & MODE_MASK);
|
||||
printf("\t response=%d (0x%.2x)\n", (p->op & REM_RESP) > 0, p->op & REM_RESP);
|
||||
printf("\t more=%d (0x%.2x)\n", (p->op & REM_MORE) > 0, p->op & REM_MORE);
|
||||
printf("\t error=%d (0x%.2x)\n", (p->op & REM_ERROR) > 0, p->op & REM_ERROR);
|
||||
printf("\t op=%d (0x%.2x)\n", p->op & OP_MASK, p->op & OP_MASK);
|
||||
printf("\tsequence: %d (0x%.2x)\n", ntohs(p->seq), ntohs(p->seq));
|
||||
printf("\tstatus: %d (0x%.2x)\n", ntohs(p->status), ntohs(p->status));
|
||||
printf("\tassoc: %d (0x%.2x)\n", ntohs(p->assoc), ntohs(p->assoc));
|
||||
printf("\toffset: %d (0x%.2x)\n", ntohs(p->offset), ntohs(p->offset));
|
||||
printf("\tcount: %d (0x%.2x)\n", ntohs(p->count), ntohs(p->count));
|
||||
printf("\tflags: 0x%.2x , 0x%.2x\n", message->flags, message->op);
|
||||
printf("\t li=%d (0x%.2x)\n", LI(message->flags), message->flags & LI_MASK);
|
||||
printf("\t vn=%d (0x%.2x)\n", VN(message->flags), message->flags & VN_MASK);
|
||||
printf("\t mode=%d (0x%.2x)\n", MODE(message->flags), message->flags & MODE_MASK);
|
||||
printf("\t response=%d (0x%.2x)\n", (message->op & REM_RESP) > 0, message->op & REM_RESP);
|
||||
printf("\t more=%d (0x%.2x)\n", (message->op & REM_MORE) > 0, message->op & REM_MORE);
|
||||
printf("\t error=%d (0x%.2x)\n", (message->op & REM_ERROR) > 0, message->op & REM_ERROR);
|
||||
printf("\t op=%d (0x%.2x)\n", message->op & OP_MASK, message->op & OP_MASK);
|
||||
printf("\tsequence: %d (0x%.2x)\n", ntohs(message->seq), ntohs(message->seq));
|
||||
printf("\tstatus: %d (0x%.2x)\n", ntohs(message->status), ntohs(message->status));
|
||||
printf("\tassoc: %d (0x%.2x)\n", ntohs(message->assoc), ntohs(message->assoc));
|
||||
printf("\toffset: %d (0x%.2x)\n", ntohs(message->offset), ntohs(message->offset));
|
||||
printf("\tcount: %d (0x%.2x)\n", ntohs(message->count), ntohs(message->count));
|
||||
|
||||
int numpeers = ntohs(p->count) / (sizeof(ntp_assoc_status_pair));
|
||||
if (p->op & REM_RESP && p->op & OP_READSTAT) {
|
||||
const ntp_assoc_status_pair *peer = (ntp_assoc_status_pair *)p->data;
|
||||
int numpeers = ntohs(message->count) / (sizeof(ntp_assoc_status_pair));
|
||||
if (message->op & REM_RESP && message->op & OP_READSTAT) {
|
||||
const ntp_assoc_status_pair *peer = (ntp_assoc_status_pair *)message->data;
|
||||
for (int i = 0; i < numpeers; i++) {
|
||||
printf("\tpeer id %.2x status %.2x", ntohs(peer[i].assoc), ntohs(peer[i].status));
|
||||
if (PEER_SEL(peer[i].status) >= PEER_SYNCSOURCE) {
|
||||
|
|
@ -190,13 +179,13 @@ void print_ntp_control_message(const ntp_control_message *p) {
|
|||
}
|
||||
}
|
||||
|
||||
void setup_control_request(ntp_control_message *p, uint8_t opcode, uint16_t seq) {
|
||||
memset(p, 0, sizeof(ntp_control_message));
|
||||
LI_SET(p->flags, LI_NOWARNING);
|
||||
VN_SET(p->flags, VN_RESERVED);
|
||||
MODE_SET(p->flags, MODE_CONTROLMSG);
|
||||
OP_SET(p->op, opcode);
|
||||
p->seq = htons(seq);
|
||||
void setup_control_request(ntp_control_message *message, uint8_t opcode, uint16_t seq) {
|
||||
memset(message, 0, sizeof(ntp_control_message));
|
||||
LI_SET(message->flags, LI_NOWARNING);
|
||||
VN_SET(message->flags, VN_RESERVED);
|
||||
MODE_SET(message->flags, MODE_CONTROLMSG);
|
||||
OP_SET(message->op, opcode);
|
||||
message->seq = htons(seq);
|
||||
/* Remaining fields are zero for requests */
|
||||
}
|
||||
|
||||
|
|
@ -211,10 +200,23 @@ void setup_control_request(ntp_control_message *p, uint8_t opcode, uint16_t seq)
|
|||
* status is pretty much useless as syncsource_found is a global variable
|
||||
* used later in main to check is the server was synchronized. It works
|
||||
* so I left it alone */
|
||||
int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum, int *num_truechimers) {
|
||||
*offset_result = STATE_UNKNOWN;
|
||||
*jitter = *stratum = -1;
|
||||
*num_truechimers = 0;
|
||||
typedef struct {
|
||||
mp_state_enum state;
|
||||
mp_state_enum offset_result;
|
||||
double offset;
|
||||
double jitter;
|
||||
long stratum;
|
||||
int num_truechimers;
|
||||
} ntp_request_result;
|
||||
ntp_request_result ntp_request(const check_ntp_peer_config config) {
|
||||
|
||||
ntp_request_result result = {
|
||||
.state = STATE_OK,
|
||||
.offset_result = STATE_UNKNOWN,
|
||||
.jitter = -1,
|
||||
.stratum = -1,
|
||||
.num_truechimers = 0,
|
||||
};
|
||||
|
||||
/* Long-winded explanation:
|
||||
* Getting the sync peer offset, jitter and stratum requires a number of
|
||||
|
|
@ -237,10 +239,10 @@ int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum
|
|||
void *tmp;
|
||||
ntp_assoc_status_pair *peers = NULL;
|
||||
int peer_offset = 0;
|
||||
int peers_size = 0;
|
||||
int npeers = 0;
|
||||
size_t peers_size = 0;
|
||||
size_t npeers = 0;
|
||||
int conn = -1;
|
||||
my_udp_connect(server_address, port, &conn);
|
||||
my_udp_connect(config.server_address, config.port, &conn);
|
||||
|
||||
/* keep sending requests until the server stops setting the
|
||||
* REM_MORE bit, though usually this is only 1 packet. */
|
||||
|
|
@ -255,24 +257,28 @@ int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum
|
|||
/* Attempt to read the largest size packet possible */
|
||||
req.count = htons(MAX_CM_SIZE);
|
||||
DBG(printf("receiving READSTAT response"))
|
||||
if (read(conn, &req, SIZEOF_NTPCM(req)) == -1)
|
||||
if (read(conn, &req, SIZEOF_NTPCM(req)) == -1) {
|
||||
die(STATE_CRITICAL, "NTP CRITICAL: No response from NTP server\n");
|
||||
}
|
||||
DBG(print_ntp_control_message(&req));
|
||||
/* discard obviously invalid packets */
|
||||
if (ntohs(req.count) > MAX_CM_SIZE)
|
||||
if (ntohs(req.count) > MAX_CM_SIZE) {
|
||||
die(STATE_CRITICAL, "NTP CRITICAL: Invalid packet received from NTP server\n");
|
||||
}
|
||||
} while (!(req.op & OP_READSTAT && ntohs(req.seq) == 1));
|
||||
|
||||
if (LI(req.flags) == LI_ALARM)
|
||||
if (LI(req.flags) == LI_ALARM) {
|
||||
li_alarm = true;
|
||||
}
|
||||
/* Each peer identifier is 4 bytes in the data section, which
|
||||
* we represent as a ntp_assoc_status_pair datatype.
|
||||
*/
|
||||
peers_size += ntohs(req.count);
|
||||
if ((tmp = realloc(peers, peers_size)) == NULL)
|
||||
if ((tmp = realloc(peers, peers_size)) == NULL) {
|
||||
free(peers), die(STATE_UNKNOWN, "can not (re)allocate 'peers' buffer\n");
|
||||
}
|
||||
peers = tmp;
|
||||
memcpy((void *)((ptrdiff_t)peers + peer_offset), (void *)req.data, ntohs(req.count));
|
||||
memcpy((peers + peer_offset), (void *)req.data, ntohs(req.count));
|
||||
npeers = peers_size / sizeof(ntp_assoc_status_pair);
|
||||
peer_offset += ntohs(req.count);
|
||||
} while (req.op & REM_MORE);
|
||||
|
|
@ -280,9 +286,9 @@ int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum
|
|||
/* first, let's find out if we have a sync source, or if there are
|
||||
* at least some candidates. In the latter case we'll issue
|
||||
* a warning but go ahead with the check on them. */
|
||||
for (int i = 0; i < npeers; i++) {
|
||||
for (size_t i = 0; i < npeers; i++) {
|
||||
if (PEER_SEL(peers[i].status) >= PEER_TRUECHIMER) {
|
||||
(*num_truechimers)++;
|
||||
result.num_truechimers++;
|
||||
if (PEER_SEL(peers[i].status) >= PEER_INCLUDED) {
|
||||
num_candidates++;
|
||||
if (PEER_SEL(peers[i].status) >= PEER_SYNCSOURCE) {
|
||||
|
|
@ -293,31 +299,35 @@ int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum
|
|||
}
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
printf("%d candidate peers available\n", num_candidates);
|
||||
if (verbose && syncsource_found)
|
||||
}
|
||||
if (verbose && syncsource_found) {
|
||||
printf("synchronization source found\n");
|
||||
}
|
||||
|
||||
int status = STATE_OK;
|
||||
if (!syncsource_found) {
|
||||
status = STATE_WARNING;
|
||||
if (verbose)
|
||||
result.state = STATE_WARNING;
|
||||
if (verbose) {
|
||||
printf("warning: no synchronization source found\n");
|
||||
}
|
||||
}
|
||||
if (li_alarm) {
|
||||
status = STATE_WARNING;
|
||||
if (verbose)
|
||||
result.state = STATE_WARNING;
|
||||
if (verbose) {
|
||||
printf("warning: LI_ALARM bit is set\n");
|
||||
}
|
||||
}
|
||||
|
||||
const char *getvar = "stratum,offset,jitter";
|
||||
char *data;
|
||||
for (int i = 0; i < npeers; i++) {
|
||||
for (size_t i = 0; i < npeers; i++) {
|
||||
/* Only query this server if it is the current sync source */
|
||||
/* If there's no sync.peer, query all candidates and use the best one */
|
||||
if (PEER_SEL(peers[i].status) >= min_peer_sel) {
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
printf("Getting offset, jitter and stratum for peer %.2x\n", ntohs(peers[i].assoc));
|
||||
}
|
||||
xasprintf(&data, "");
|
||||
do {
|
||||
setup_control_request(&req, OP_READVAR, 2);
|
||||
|
|
@ -342,60 +352,68 @@ int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum
|
|||
DBG(print_ntp_control_message(&req));
|
||||
} while (!(req.op & OP_READVAR && ntohs(req.seq) == 2));
|
||||
|
||||
if (!(req.op & REM_ERROR))
|
||||
if (!(req.op & REM_ERROR)) {
|
||||
xasprintf(&data, "%s%s", data, req.data);
|
||||
}
|
||||
} while (req.op & REM_MORE);
|
||||
|
||||
if (req.op & REM_ERROR) {
|
||||
if (strstr(getvar, "jitter")) {
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
printf("The command failed. This is usually caused by servers refusing the 'jitter'\nvariable. Restarting with "
|
||||
"'dispersion'...\n");
|
||||
}
|
||||
getvar = "stratum,offset,dispersion";
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
if (strlen(getvar)) {
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
printf("Server didn't like dispersion either; will retrieve everything\n");
|
||||
}
|
||||
getvar = "";
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (verbose > 1)
|
||||
if (verbose > 1) {
|
||||
printf("Server responded: >>>%s<<<\n", data);
|
||||
}
|
||||
|
||||
double tmp_offset = 0;
|
||||
char *value;
|
||||
char *nptr;
|
||||
/* get the offset */
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
printf("parsing offset from peer %.2x: ", ntohs(peers[i].assoc));
|
||||
}
|
||||
|
||||
value = np_extract_ntpvar(data, "offset");
|
||||
nptr = NULL;
|
||||
/* Convert the value if we have one */
|
||||
if (value != NULL)
|
||||
if (value != NULL) {
|
||||
tmp_offset = strtod(value, &nptr) / 1000;
|
||||
}
|
||||
/* If value is null or no conversion was performed */
|
||||
if (value == NULL || value == nptr) {
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
printf("error: unable to read server offset response.\n");
|
||||
}
|
||||
} else {
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
printf("%.10g\n", tmp_offset);
|
||||
if (*offset_result == STATE_UNKNOWN || fabs(tmp_offset) < fabs(*offset)) {
|
||||
*offset = tmp_offset;
|
||||
*offset_result = STATE_OK;
|
||||
}
|
||||
if (result.offset_result == STATE_UNKNOWN || fabs(tmp_offset) < fabs(result.offset)) {
|
||||
result.offset = tmp_offset;
|
||||
result.offset_result = STATE_OK;
|
||||
} else {
|
||||
/* Skip this one; move to the next */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (do_jitter) {
|
||||
if (config.do_jitter) {
|
||||
/* get the jitter */
|
||||
if (verbose) {
|
||||
printf("parsing %s from peer %.2x: ", strstr(getvar, "dispersion") != NULL ? "dispersion" : "jitter",
|
||||
|
|
@ -404,19 +422,21 @@ int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum
|
|||
value = np_extract_ntpvar(data, strstr(getvar, "dispersion") != NULL ? "dispersion" : "jitter");
|
||||
nptr = NULL;
|
||||
/* Convert the value if we have one */
|
||||
if (value != NULL)
|
||||
*jitter = strtod(value, &nptr);
|
||||
if (value != NULL) {
|
||||
result.jitter = strtod(value, &nptr);
|
||||
}
|
||||
/* If value is null or no conversion was performed */
|
||||
if (value == NULL || value == nptr) {
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
printf("error: unable to read server jitter/dispersion response.\n");
|
||||
*jitter = -1;
|
||||
}
|
||||
result.jitter = -1;
|
||||
} else if (verbose) {
|
||||
printf("%.10g\n", *jitter);
|
||||
printf("%.10g\n", result.jitter);
|
||||
}
|
||||
}
|
||||
|
||||
if (do_stratum) {
|
||||
if (config.do_stratum) {
|
||||
/* get the stratum */
|
||||
if (verbose) {
|
||||
printf("parsing stratum from peer %.2x: ", ntohs(peers[i].assoc));
|
||||
|
|
@ -424,28 +444,32 @@ int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum
|
|||
value = np_extract_ntpvar(data, "stratum");
|
||||
nptr = NULL;
|
||||
/* Convert the value if we have one */
|
||||
if (value != NULL)
|
||||
*stratum = strtol(value, &nptr, 10);
|
||||
if (value != NULL) {
|
||||
result.stratum = strtol(value, &nptr, 10);
|
||||
}
|
||||
if (value == NULL || value == nptr) {
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
printf("error: unable to read server stratum response.\n");
|
||||
*stratum = -1;
|
||||
}
|
||||
result.stratum = -1;
|
||||
} else {
|
||||
if (verbose)
|
||||
printf("%i\n", *stratum);
|
||||
if (verbose) {
|
||||
printf("%li\n", result.stratum);
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* if (PEER_SEL(peers[i].status) >= min_peer_sel) */
|
||||
} /* for (i = 0; i < npeers; i++) */
|
||||
} /* for (i = 0; i < npeers; i++) */
|
||||
|
||||
close(conn);
|
||||
if (peers != NULL)
|
||||
if (peers != NULL) {
|
||||
free(peers);
|
||||
}
|
||||
|
||||
return status;
|
||||
return result;
|
||||
}
|
||||
|
||||
int process_arguments(int argc, char **argv) {
|
||||
check_ntp_peer_config_wrapper process_arguments(int argc, char **argv) {
|
||||
static struct option longopts[] = {
|
||||
{"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, {"verbose", no_argument, 0, 'v'},
|
||||
{"use-ipv4", no_argument, 0, '4'}, {"use-ipv6", no_argument, 0, '6'}, {"quiet", no_argument, 0, 'q'},
|
||||
|
|
@ -454,14 +478,21 @@ int process_arguments(int argc, char **argv) {
|
|||
{"twarn", required_argument, 0, 'm'}, {"tcrit", required_argument, 0, 'n'}, {"timeout", required_argument, 0, 't'},
|
||||
{"hostname", required_argument, 0, 'H'}, {"port", required_argument, 0, 'p'}, {0, 0, 0, 0}};
|
||||
|
||||
if (argc < 2)
|
||||
if (argc < 2) {
|
||||
usage("\n");
|
||||
}
|
||||
|
||||
check_ntp_peer_config_wrapper result = {
|
||||
.errorcode = OK,
|
||||
.config = check_ntp_peer_config_init(),
|
||||
};
|
||||
|
||||
while (true) {
|
||||
int option = 0;
|
||||
int option_char = getopt_long(argc, argv, "Vhv46qw:c:W:C:j:k:m:n:t:H:p:", longopts, &option);
|
||||
if (option_char == -1 || option_char == EOF || option_char == 1)
|
||||
if (option_char == -1 || option_char == EOF || option_char == 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (option_char) {
|
||||
case 'h':
|
||||
|
|
@ -476,45 +507,46 @@ int process_arguments(int argc, char **argv) {
|
|||
verbose++;
|
||||
break;
|
||||
case 'q':
|
||||
quiet = true;
|
||||
result.config.quiet = true;
|
||||
break;
|
||||
case 'w':
|
||||
owarn = optarg;
|
||||
result.config.owarn = optarg;
|
||||
break;
|
||||
case 'c':
|
||||
ocrit = optarg;
|
||||
result.config.ocrit = optarg;
|
||||
break;
|
||||
case 'W':
|
||||
do_stratum = true;
|
||||
swarn = optarg;
|
||||
result.config.do_stratum = true;
|
||||
result.config.swarn = optarg;
|
||||
break;
|
||||
case 'C':
|
||||
do_stratum = true;
|
||||
scrit = optarg;
|
||||
result.config.do_stratum = true;
|
||||
result.config.scrit = optarg;
|
||||
break;
|
||||
case 'j':
|
||||
do_jitter = true;
|
||||
jwarn = optarg;
|
||||
result.config.do_jitter = true;
|
||||
result.config.jwarn = optarg;
|
||||
break;
|
||||
case 'k':
|
||||
do_jitter = true;
|
||||
jcrit = optarg;
|
||||
result.config.do_jitter = true;
|
||||
result.config.jcrit = optarg;
|
||||
break;
|
||||
case 'm':
|
||||
do_truechimers = true;
|
||||
twarn = optarg;
|
||||
result.config.do_truechimers = true;
|
||||
result.config.twarn = optarg;
|
||||
break;
|
||||
case 'n':
|
||||
do_truechimers = true;
|
||||
tcrit = optarg;
|
||||
result.config.do_truechimers = true;
|
||||
result.config.tcrit = optarg;
|
||||
break;
|
||||
case 'H':
|
||||
if (!is_host(optarg))
|
||||
if (!is_host(optarg)) {
|
||||
usage2(_("Invalid hostname/address"), optarg);
|
||||
server_address = strdup(optarg);
|
||||
}
|
||||
result.config.server_address = strdup(optarg);
|
||||
break;
|
||||
case 'p':
|
||||
port = atoi(optarg);
|
||||
result.config.port = atoi(optarg);
|
||||
break;
|
||||
case 't':
|
||||
socket_timeout = atoi(optarg);
|
||||
|
|
@ -536,29 +568,34 @@ int process_arguments(int argc, char **argv) {
|
|||
}
|
||||
}
|
||||
|
||||
if (server_address == NULL) {
|
||||
if (result.config.server_address == NULL) {
|
||||
usage4(_("Hostname was not supplied"));
|
||||
}
|
||||
|
||||
return 0;
|
||||
set_thresholds(&result.config.offset_thresholds, result.config.owarn, result.config.ocrit);
|
||||
set_thresholds(&result.config.jitter_thresholds, result.config.jwarn, result.config.jcrit);
|
||||
set_thresholds(&result.config.stratum_thresholds, result.config.swarn, result.config.scrit);
|
||||
set_thresholds(&result.config.truechimer_thresholds, result.config.twarn, result.config.tcrit);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
char *perfd_offset(double offset) {
|
||||
char *perfd_offset(double offset, thresholds *offset_thresholds) {
|
||||
return fperfdata("offset", offset, "s", true, offset_thresholds->warning->end, true, offset_thresholds->critical->end, false, 0, false,
|
||||
0);
|
||||
}
|
||||
|
||||
char *perfd_jitter(double jitter) {
|
||||
char *perfd_jitter(double jitter, bool do_jitter, thresholds *jitter_thresholds) {
|
||||
return fperfdata("jitter", jitter, "", do_jitter, jitter_thresholds->warning->end, do_jitter, jitter_thresholds->critical->end, true, 0,
|
||||
false, 0);
|
||||
}
|
||||
|
||||
char *perfd_stratum(int stratum) {
|
||||
char *perfd_stratum(int stratum, bool do_stratum, thresholds *stratum_thresholds) {
|
||||
return perfdata("stratum", stratum, "", do_stratum, (int)stratum_thresholds->warning->end, do_stratum,
|
||||
(int)stratum_thresholds->critical->end, true, 0, true, 16);
|
||||
}
|
||||
|
||||
char *perfd_truechimers(int num_truechimers) {
|
||||
char *perfd_truechimers(int num_truechimers, const bool do_truechimers, thresholds *truechimer_thresholds) {
|
||||
return perfdata("truechimers", num_truechimers, "", do_truechimers, (int)truechimer_thresholds->warning->end, do_truechimers,
|
||||
(int)truechimer_thresholds->critical->end, true, 0, false, 0);
|
||||
}
|
||||
|
|
@ -571,13 +608,13 @@ int main(int argc, char *argv[]) {
|
|||
/* Parse extra opts if any */
|
||||
argv = np_extra_opts(&argc, argv, progname);
|
||||
|
||||
if (process_arguments(argc, argv) == ERROR)
|
||||
usage4(_("Could not parse arguments"));
|
||||
check_ntp_peer_config_wrapper tmp_config = process_arguments(argc, argv);
|
||||
|
||||
set_thresholds(&offset_thresholds, owarn, ocrit);
|
||||
set_thresholds(&jitter_thresholds, jwarn, jcrit);
|
||||
set_thresholds(&stratum_thresholds, swarn, scrit);
|
||||
set_thresholds(&truechimer_thresholds, twarn, tcrit);
|
||||
if (tmp_config.errorcode == ERROR) {
|
||||
usage4(_("Could not parse arguments"));
|
||||
}
|
||||
|
||||
const check_ntp_peer_config config = tmp_config.config;
|
||||
|
||||
/* initialize alarm signal handling */
|
||||
signal(SIGALRM, socket_timeout_alarm_handler);
|
||||
|
|
@ -585,44 +622,40 @@ int main(int argc, char *argv[]) {
|
|||
/* set socket timeout */
|
||||
alarm(socket_timeout);
|
||||
|
||||
int offset_result;
|
||||
int stratum;
|
||||
int num_truechimers;
|
||||
double offset = 0;
|
||||
double jitter = 0;
|
||||
/* This returns either OK or WARNING (See comment preceding ntp_request) */
|
||||
int result = ntp_request(&offset, &offset_result, &jitter, &stratum, &num_truechimers);
|
||||
ntp_request_result ntp_res = ntp_request(config);
|
||||
mp_state_enum result = STATE_UNKNOWN;
|
||||
|
||||
if (offset_result == STATE_UNKNOWN) {
|
||||
if (ntp_res.offset_result == STATE_UNKNOWN) {
|
||||
/* if there's no sync peer (this overrides ntp_request output): */
|
||||
result = (quiet ? STATE_UNKNOWN : STATE_CRITICAL);
|
||||
result = (config.quiet ? STATE_UNKNOWN : STATE_CRITICAL);
|
||||
} else {
|
||||
/* Be quiet if there's no candidates either */
|
||||
if (quiet && result == STATE_WARNING)
|
||||
if (config.quiet && result == STATE_WARNING) {
|
||||
result = STATE_UNKNOWN;
|
||||
result = max_state_alt(result, get_status(fabs(offset), offset_thresholds));
|
||||
}
|
||||
result = max_state_alt(result, get_status(fabs(ntp_res.offset), config.offset_thresholds));
|
||||
}
|
||||
|
||||
int oresult = result;
|
||||
mp_state_enum oresult = result;
|
||||
mp_state_enum tresult = STATE_UNKNOWN;
|
||||
|
||||
int tresult = STATE_UNKNOWN;
|
||||
|
||||
if (do_truechimers) {
|
||||
tresult = get_status(num_truechimers, truechimer_thresholds);
|
||||
if (config.do_truechimers) {
|
||||
tresult = get_status(ntp_res.num_truechimers, config.truechimer_thresholds);
|
||||
result = max_state_alt(result, tresult);
|
||||
}
|
||||
|
||||
int sresult = STATE_UNKNOWN;
|
||||
mp_state_enum sresult = STATE_UNKNOWN;
|
||||
|
||||
if (do_stratum) {
|
||||
sresult = get_status(stratum, stratum_thresholds);
|
||||
if (config.do_stratum) {
|
||||
sresult = get_status((double)ntp_res.stratum, config.stratum_thresholds);
|
||||
result = max_state_alt(result, sresult);
|
||||
}
|
||||
|
||||
int jresult = STATE_UNKNOWN;
|
||||
mp_state_enum jresult = STATE_UNKNOWN;
|
||||
|
||||
if (do_jitter) {
|
||||
jresult = get_status(jitter, jitter_thresholds);
|
||||
if (config.do_jitter) {
|
||||
jresult = get_status(ntp_res.jitter, config.jitter_thresholds);
|
||||
result = max_state_alt(result, jresult);
|
||||
}
|
||||
|
||||
|
|
@ -641,59 +674,67 @@ int main(int argc, char *argv[]) {
|
|||
xasprintf(&result_line, _("NTP UNKNOWN:"));
|
||||
break;
|
||||
}
|
||||
if (!syncsource_found)
|
||||
|
||||
if (!syncsource_found) {
|
||||
xasprintf(&result_line, "%s %s,", result_line, _("Server not synchronized"));
|
||||
else if (li_alarm)
|
||||
} else if (li_alarm) {
|
||||
xasprintf(&result_line, "%s %s,", result_line, _("Server has the LI_ALARM bit set"));
|
||||
}
|
||||
|
||||
char *perfdata_line;
|
||||
if (offset_result == STATE_UNKNOWN) {
|
||||
if (ntp_res.offset_result == STATE_UNKNOWN) {
|
||||
xasprintf(&result_line, "%s %s", result_line, _("Offset unknown"));
|
||||
xasprintf(&perfdata_line, "");
|
||||
} else if (oresult == STATE_WARNING) {
|
||||
xasprintf(&result_line, "%s %s %.10g secs (WARNING)", result_line, _("Offset"), offset);
|
||||
xasprintf(&result_line, "%s %s %.10g secs (WARNING)", result_line, _("Offset"), ntp_res.offset);
|
||||
} else if (oresult == STATE_CRITICAL) {
|
||||
xasprintf(&result_line, "%s %s %.10g secs (CRITICAL)", result_line, _("Offset"), offset);
|
||||
xasprintf(&result_line, "%s %s %.10g secs (CRITICAL)", result_line, _("Offset"), ntp_res.offset);
|
||||
} else {
|
||||
xasprintf(&result_line, "%s %s %.10g secs", result_line, _("Offset"), offset);
|
||||
xasprintf(&result_line, "%s %s %.10g secs", result_line, _("Offset"), ntp_res.offset);
|
||||
}
|
||||
xasprintf(&perfdata_line, "%s", perfd_offset(offset));
|
||||
xasprintf(&perfdata_line, "%s", perfd_offset(ntp_res.offset, config.offset_thresholds));
|
||||
|
||||
if (do_jitter) {
|
||||
if (config.do_jitter) {
|
||||
if (jresult == STATE_WARNING) {
|
||||
xasprintf(&result_line, "%s, jitter=%f (WARNING)", result_line, jitter);
|
||||
xasprintf(&result_line, "%s, jitter=%f (WARNING)", result_line, ntp_res.jitter);
|
||||
} else if (jresult == STATE_CRITICAL) {
|
||||
xasprintf(&result_line, "%s, jitter=%f (CRITICAL)", result_line, jitter);
|
||||
xasprintf(&result_line, "%s, jitter=%f (CRITICAL)", result_line, ntp_res.jitter);
|
||||
} else {
|
||||
xasprintf(&result_line, "%s, jitter=%f", result_line, jitter);
|
||||
xasprintf(&result_line, "%s, jitter=%f", result_line, ntp_res.jitter);
|
||||
}
|
||||
xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_jitter(jitter));
|
||||
xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_jitter(ntp_res.jitter, config.do_jitter, config.jitter_thresholds));
|
||||
}
|
||||
if (do_stratum) {
|
||||
|
||||
if (config.do_stratum) {
|
||||
if (sresult == STATE_WARNING) {
|
||||
xasprintf(&result_line, "%s, stratum=%i (WARNING)", result_line, stratum);
|
||||
xasprintf(&result_line, "%s, stratum=%l (WARNING)", result_line, ntp_res.stratum);
|
||||
} else if (sresult == STATE_CRITICAL) {
|
||||
xasprintf(&result_line, "%s, stratum=%i (CRITICAL)", result_line, stratum);
|
||||
xasprintf(&result_line, "%s, stratum=%l (CRITICAL)", result_line, ntp_res.stratum);
|
||||
} else {
|
||||
xasprintf(&result_line, "%s, stratum=%i", result_line, stratum);
|
||||
xasprintf(&result_line, "%s, stratum=%l", result_line, ntp_res.stratum);
|
||||
}
|
||||
xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_stratum(stratum));
|
||||
xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_stratum(ntp_res.stratum, config.do_stratum, config.stratum_thresholds));
|
||||
}
|
||||
if (do_truechimers) {
|
||||
|
||||
if (config.do_truechimers) {
|
||||
if (tresult == STATE_WARNING) {
|
||||
xasprintf(&result_line, "%s, truechimers=%i (WARNING)", result_line, num_truechimers);
|
||||
xasprintf(&result_line, "%s, truechimers=%i (WARNING)", result_line, ntp_res.num_truechimers);
|
||||
} else if (tresult == STATE_CRITICAL) {
|
||||
xasprintf(&result_line, "%s, truechimers=%i (CRITICAL)", result_line, num_truechimers);
|
||||
xasprintf(&result_line, "%s, truechimers=%i (CRITICAL)", result_line, ntp_res.num_truechimers);
|
||||
} else {
|
||||
xasprintf(&result_line, "%s, truechimers=%i", result_line, num_truechimers);
|
||||
xasprintf(&result_line, "%s, truechimers=%i", result_line, ntp_res.num_truechimers);
|
||||
}
|
||||
xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_truechimers(num_truechimers));
|
||||
xasprintf(&perfdata_line, "%s %s", perfdata_line,
|
||||
perfd_truechimers(ntp_res.num_truechimers, config.do_truechimers, config.truechimer_thresholds));
|
||||
}
|
||||
|
||||
printf("%s|%s\n", result_line, perfdata_line);
|
||||
|
||||
if (server_address != NULL)
|
||||
free(server_address);
|
||||
return result;
|
||||
if (config.server_address != NULL) {
|
||||
free(config.server_address);
|
||||
}
|
||||
|
||||
exit(result);
|
||||
}
|
||||
|
||||
void print_help(void) {
|
||||
|
|
|
|||
67
plugins/check_ntp_peer.d/config.h
Normal file
67
plugins/check_ntp_peer.d/config.h
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../config.h"
|
||||
#include "thresholds.h"
|
||||
#include <stddef.h>
|
||||
|
||||
enum {
|
||||
DEFAULT_NTP_PORT = 123,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
char *server_address;
|
||||
int port;
|
||||
|
||||
bool quiet;
|
||||
|
||||
// truechimer stuff
|
||||
bool do_truechimers;
|
||||
char *twarn;
|
||||
char *tcrit;
|
||||
thresholds *truechimer_thresholds;
|
||||
|
||||
char *owarn;
|
||||
char *ocrit;
|
||||
thresholds *offset_thresholds;
|
||||
|
||||
// stratum stuff
|
||||
bool do_stratum;
|
||||
char *swarn;
|
||||
char *scrit;
|
||||
thresholds *stratum_thresholds;
|
||||
|
||||
// jitter stuff
|
||||
bool do_jitter;
|
||||
char *jwarn;
|
||||
char *jcrit;
|
||||
thresholds *jitter_thresholds;
|
||||
|
||||
} check_ntp_peer_config;
|
||||
|
||||
check_ntp_peer_config check_ntp_peer_config_init() {
|
||||
check_ntp_peer_config tmp = {
|
||||
.server_address = NULL,
|
||||
.port = DEFAULT_NTP_PORT,
|
||||
|
||||
.quiet = false,
|
||||
.do_truechimers = false,
|
||||
.twarn = "0:",
|
||||
.tcrit = "0:",
|
||||
.truechimer_thresholds = NULL,
|
||||
|
||||
.owarn = "60",
|
||||
.ocrit = "120",
|
||||
.offset_thresholds = NULL,
|
||||
|
||||
.do_stratum = false,
|
||||
.swarn = "-1:16",
|
||||
.scrit = "-1:16",
|
||||
.stratum_thresholds = NULL,
|
||||
|
||||
.do_jitter = false,
|
||||
.jwarn = "-1:5000",
|
||||
.jcrit = "-1:10000",
|
||||
.jitter_thresholds = NULL,
|
||||
};
|
||||
return tmp;
|
||||
}
|
||||
|
|
@ -41,17 +41,18 @@ const char *email = "devel@monitoring-plugins.org";
|
|||
#include "common.h"
|
||||
#include "netutils.h"
|
||||
#include "utils.h"
|
||||
#include "states.h"
|
||||
#include "thresholds.h"
|
||||
#include "check_ntp_time.d/config.h"
|
||||
|
||||
static char *server_address = NULL;
|
||||
static char *port = "123";
|
||||
static int verbose = 0;
|
||||
static bool quiet = false;
|
||||
static char *owarn = "60";
|
||||
static char *ocrit = "120";
|
||||
static int time_offset = 0;
|
||||
|
||||
static int process_arguments(int, char **);
|
||||
static thresholds *offset_thresholds = NULL;
|
||||
typedef struct {
|
||||
int errorcode;
|
||||
check_ntp_time_config config;
|
||||
} check_ntp_time_config_wrapper;
|
||||
static check_ntp_time_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
|
||||
static void print_help(void);
|
||||
void print_usage(void);
|
||||
|
||||
|
|
@ -159,7 +160,7 @@ typedef struct {
|
|||
#define EPOCHDIFF 0x83aa7e80UL
|
||||
|
||||
/* extract a 32-bit ntp fixed point number into a double */
|
||||
#define NTP32asDOUBLE(x) (ntohs(L16(x)) + (double)ntohs(R16(x)) / 65536.0)
|
||||
#define NTP32asDOUBLE(x) (ntohs(L16(x)) + ((double)ntohs(R16(x)) / 65536.0))
|
||||
|
||||
/* likewise for a 64-bit ntp fp number */
|
||||
#define NTP64asDOUBLE(n) \
|
||||
|
|
@ -208,56 +209,52 @@ typedef struct {
|
|||
} while (0);
|
||||
|
||||
/* calculate the offset of the local clock */
|
||||
static inline double calc_offset(const ntp_message *m, const struct timeval *t) {
|
||||
double client_tx = NTP64asDOUBLE(m->origts);
|
||||
double peer_rx = NTP64asDOUBLE(m->rxts);
|
||||
double peer_tx = NTP64asDOUBLE(m->txts);
|
||||
double client_rx = TVasDOUBLE((*t));
|
||||
return (.5 * ((peer_tx - client_rx) + (peer_rx - client_tx)));
|
||||
static inline double calc_offset(const ntp_message *message, const struct timeval *time_value) {
|
||||
double client_tx = NTP64asDOUBLE(message->origts);
|
||||
double peer_rx = NTP64asDOUBLE(message->rxts);
|
||||
double peer_tx = NTP64asDOUBLE(message->txts);
|
||||
double client_rx = TVasDOUBLE((*time_value));
|
||||
return (((peer_tx - client_rx) + (peer_rx - client_tx)) / 2);
|
||||
}
|
||||
|
||||
/* print out a ntp packet in human readable/debuggable format */
|
||||
void print_ntp_message(const ntp_message *p) {
|
||||
void print_ntp_message(const ntp_message *message) {
|
||||
struct timeval ref;
|
||||
struct timeval orig;
|
||||
struct timeval rx;
|
||||
struct timeval tx;
|
||||
|
||||
NTP64toTV(p->refts, ref);
|
||||
NTP64toTV(p->origts, orig);
|
||||
NTP64toTV(p->rxts, rx);
|
||||
NTP64toTV(p->txts, tx);
|
||||
NTP64toTV(message->refts, ref);
|
||||
NTP64toTV(message->origts, orig);
|
||||
|
||||
printf("packet contents:\n");
|
||||
printf("\tflags: 0x%.2x\n", p->flags);
|
||||
printf("\t li=%d (0x%.2x)\n", LI(p->flags), p->flags & LI_MASK);
|
||||
printf("\t vn=%d (0x%.2x)\n", VN(p->flags), p->flags & VN_MASK);
|
||||
printf("\t mode=%d (0x%.2x)\n", MODE(p->flags), p->flags & MODE_MASK);
|
||||
printf("\tstratum = %d\n", p->stratum);
|
||||
printf("\tpoll = %g\n", pow(2, p->poll));
|
||||
printf("\tprecision = %g\n", pow(2, p->precision));
|
||||
printf("\trtdelay = %-.16g\n", NTP32asDOUBLE(p->rtdelay));
|
||||
printf("\trtdisp = %-.16g\n", NTP32asDOUBLE(p->rtdisp));
|
||||
printf("\trefid = %x\n", p->refid);
|
||||
printf("\trefts = %-.16g\n", NTP64asDOUBLE(p->refts));
|
||||
printf("\torigts = %-.16g\n", NTP64asDOUBLE(p->origts));
|
||||
printf("\trxts = %-.16g\n", NTP64asDOUBLE(p->rxts));
|
||||
printf("\ttxts = %-.16g\n", NTP64asDOUBLE(p->txts));
|
||||
printf("\tflags: 0x%.2x\n", message->flags);
|
||||
printf("\t li=%d (0x%.2x)\n", LI(message->flags), message->flags & LI_MASK);
|
||||
printf("\t vn=%d (0x%.2x)\n", VN(message->flags), message->flags & VN_MASK);
|
||||
printf("\t mode=%d (0x%.2x)\n", MODE(message->flags), message->flags & MODE_MASK);
|
||||
printf("\tstratum = %d\n", message->stratum);
|
||||
printf("\tpoll = %g\n", pow(2, message->poll));
|
||||
printf("\tprecision = %g\n", pow(2, message->precision));
|
||||
printf("\trtdelay = %-.16g\n", NTP32asDOUBLE(message->rtdelay));
|
||||
printf("\trtdisp = %-.16g\n", NTP32asDOUBLE(message->rtdisp));
|
||||
printf("\trefid = %x\n", message->refid);
|
||||
printf("\trefts = %-.16g\n", NTP64asDOUBLE(message->refts));
|
||||
printf("\torigts = %-.16g\n", NTP64asDOUBLE(message->origts));
|
||||
printf("\trxts = %-.16g\n", NTP64asDOUBLE(message->rxts));
|
||||
printf("\ttxts = %-.16g\n", NTP64asDOUBLE(message->txts));
|
||||
}
|
||||
|
||||
void setup_request(ntp_message *p) {
|
||||
memset(p, 0, sizeof(ntp_message));
|
||||
LI_SET(p->flags, LI_ALARM);
|
||||
VN_SET(p->flags, 4);
|
||||
MODE_SET(p->flags, MODE_CLIENT);
|
||||
p->poll = 4;
|
||||
p->precision = (int8_t)0xfa;
|
||||
L16(p->rtdelay) = htons(1);
|
||||
L16(p->rtdisp) = htons(1);
|
||||
void setup_request(ntp_message *message) {
|
||||
memset(message, 0, sizeof(ntp_message));
|
||||
LI_SET(message->flags, LI_ALARM);
|
||||
VN_SET(message->flags, 4);
|
||||
MODE_SET(message->flags, MODE_CLIENT);
|
||||
message->poll = 4;
|
||||
message->precision = (int8_t)0xfa;
|
||||
L16(message->rtdelay) = htons(1);
|
||||
L16(message->rtdisp) = htons(1);
|
||||
|
||||
struct timeval t;
|
||||
gettimeofday(&t, NULL);
|
||||
TVtoNTP64(t, p->txts);
|
||||
TVtoNTP64(t, message->txts);
|
||||
}
|
||||
|
||||
/* select the "best" server from a list of servers, and return its index.
|
||||
|
|
@ -273,14 +270,16 @@ int best_offset_server(const ntp_server_results *slist, int nservers) {
|
|||
* stratum 0 is for reference clocks so no NTP server should ever report
|
||||
* a stratum 0 */
|
||||
if (slist[cserver].stratum == 0) {
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
printf("discarding peer %d: stratum=%d\n", cserver, slist[cserver].stratum);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
/* Sort out servers with error flags */
|
||||
if (LI(slist[cserver].flags) == LI_ALARM) {
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
printf("discarding peer %d: flags=%d\n", cserver, LI(slist[cserver].flags));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -322,7 +321,7 @@ int best_offset_server(const ntp_server_results *slist, int nservers) {
|
|||
* we don't waste time sitting around waiting for single packets.
|
||||
* - we also "manually" handle resolving host names and connecting, because
|
||||
* we have to do it in a way that our lazy macros don't handle currently :( */
|
||||
double offset_request(const char *host, int *status) {
|
||||
double offset_request(const char *host, const char *port, mp_state_enum *status, int time_offset) {
|
||||
/* setup hints to only return results from getaddrinfo that we'd like */
|
||||
struct addrinfo hints;
|
||||
memset(&hints, 0, sizeof(struct addrinfo));
|
||||
|
|
@ -331,39 +330,43 @@ double offset_request(const char *host, int *status) {
|
|||
hints.ai_socktype = SOCK_DGRAM;
|
||||
|
||||
/* fill in ai with the list of hosts resolved by the host name */
|
||||
struct addrinfo *ai = NULL;
|
||||
int ga_result = getaddrinfo(host, port, &hints, &ai);
|
||||
struct addrinfo *addresses = NULL;
|
||||
int ga_result = getaddrinfo(host, port, &hints, &addresses);
|
||||
if (ga_result != 0) {
|
||||
die(STATE_UNKNOWN, "error getting address for %s: %s\n", host, gai_strerror(ga_result));
|
||||
}
|
||||
|
||||
/* count the number of returned hosts, and allocate stuff accordingly */
|
||||
int num_hosts = 0;
|
||||
for (struct addrinfo *ai_tmp = ai; ai_tmp != NULL; ai_tmp = ai_tmp->ai_next) {
|
||||
size_t num_hosts = 0;
|
||||
for (struct addrinfo *ai_tmp = addresses; ai_tmp != NULL; ai_tmp = ai_tmp->ai_next) {
|
||||
num_hosts++;
|
||||
}
|
||||
|
||||
ntp_message *req = (ntp_message *)malloc(sizeof(ntp_message) * num_hosts);
|
||||
|
||||
if (req == NULL)
|
||||
if (req == NULL) {
|
||||
die(STATE_UNKNOWN, "can not allocate ntp message array");
|
||||
}
|
||||
int *socklist = (int *)malloc(sizeof(int) * num_hosts);
|
||||
|
||||
if (socklist == NULL)
|
||||
if (socklist == NULL) {
|
||||
die(STATE_UNKNOWN, "can not allocate socket array");
|
||||
}
|
||||
|
||||
struct pollfd *ufds = (struct pollfd *)malloc(sizeof(struct pollfd) * num_hosts);
|
||||
if (ufds == NULL)
|
||||
if (ufds == NULL) {
|
||||
die(STATE_UNKNOWN, "can not allocate socket array");
|
||||
}
|
||||
|
||||
ntp_server_results *servers = (ntp_server_results *)malloc(sizeof(ntp_server_results) * num_hosts);
|
||||
if (servers == NULL)
|
||||
if (servers == NULL) {
|
||||
die(STATE_UNKNOWN, "can not allocate server array");
|
||||
}
|
||||
memset(servers, 0, sizeof(ntp_server_results) * num_hosts);
|
||||
DBG(printf("Found %d peers to check\n", num_hosts));
|
||||
DBG(printf("Found %zu peers to check\n", num_hosts));
|
||||
|
||||
/* setup each socket for writing, and the corresponding struct pollfd */
|
||||
struct addrinfo *ai_tmp = ai;
|
||||
struct addrinfo *ai_tmp = addresses;
|
||||
for (int i = 0; ai_tmp; i++) {
|
||||
socklist[i] = socket(ai_tmp->ai_family, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (socklist[i] == -1) {
|
||||
|
|
@ -389,7 +392,7 @@ double offset_request(const char *host, int *status) {
|
|||
time_t start_ts = 0;
|
||||
time_t now_time = 0;
|
||||
now_time = start_ts = time(NULL);
|
||||
int servers_completed = 0;
|
||||
size_t servers_completed = 0;
|
||||
bool one_read = false;
|
||||
while (servers_completed < num_hosts && now_time - start_ts <= socket_timeout / 2) {
|
||||
/* loop through each server and find each one which hasn't
|
||||
|
|
@ -398,12 +401,14 @@ double offset_request(const char *host, int *status) {
|
|||
* and update the "waiting" timestamp with the current time. */
|
||||
now_time = time(NULL);
|
||||
|
||||
for (int i = 0; i < num_hosts; i++) {
|
||||
for (size_t i = 0; i < num_hosts; i++) {
|
||||
if (servers[i].waiting < now_time && servers[i].num_responses < AVG_NUM) {
|
||||
if (verbose && servers[i].waiting != 0)
|
||||
if (verbose && servers[i].waiting != 0) {
|
||||
printf("re-");
|
||||
if (verbose)
|
||||
printf("sending request to peer %d\n", i);
|
||||
}
|
||||
if (verbose) {
|
||||
printf("sending request to peer %zu\n", i);
|
||||
}
|
||||
setup_request(&req[i]);
|
||||
write(socklist[i], &req[i], sizeof(ntp_message));
|
||||
servers[i].waiting = now_time;
|
||||
|
|
@ -419,10 +424,10 @@ double offset_request(const char *host, int *status) {
|
|||
}
|
||||
|
||||
/* read from any sockets with pending data */
|
||||
for (int i = 0; servers_readable && i < num_hosts; i++) {
|
||||
for (size_t i = 0; servers_readable && i < num_hosts; i++) {
|
||||
if (ufds[i].revents & POLLIN && servers[i].num_responses < AVG_NUM) {
|
||||
if (verbose) {
|
||||
printf("response from peer %d: ", i);
|
||||
printf("response from peer %zu: ", i);
|
||||
}
|
||||
|
||||
read(ufds[i].fd, &req[i], sizeof(ntp_message));
|
||||
|
|
@ -442,14 +447,15 @@ double offset_request(const char *host, int *status) {
|
|||
servers[i].flags = req[i].flags;
|
||||
servers_readable--;
|
||||
one_read = true;
|
||||
if (servers[i].num_responses == AVG_NUM)
|
||||
if (servers[i].num_responses == AVG_NUM) {
|
||||
servers_completed++;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* lather, rinse, repeat. */
|
||||
}
|
||||
|
||||
if (one_read == false) {
|
||||
if (!one_read) {
|
||||
die(STATE_CRITICAL, "NTP CRITICAL: No response from NTP server\n");
|
||||
}
|
||||
|
||||
|
|
@ -467,21 +473,22 @@ double offset_request(const char *host, int *status) {
|
|||
}
|
||||
|
||||
/* cleanup */
|
||||
for (int j = 0; j < num_hosts; j++) {
|
||||
for (size_t j = 0; j < num_hosts; j++) {
|
||||
close(socklist[j]);
|
||||
}
|
||||
free(socklist);
|
||||
free(ufds);
|
||||
free(servers);
|
||||
free(req);
|
||||
freeaddrinfo(ai);
|
||||
freeaddrinfo(addresses);
|
||||
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
printf("overall average offset: %.10g\n", avg_offset);
|
||||
}
|
||||
return avg_offset;
|
||||
}
|
||||
|
||||
int process_arguments(int argc, char **argv) {
|
||||
check_ntp_time_config_wrapper process_arguments(int argc, char **argv) {
|
||||
static struct option longopts[] = {{"version", no_argument, 0, 'V'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
|
|
@ -496,14 +503,24 @@ int process_arguments(int argc, char **argv) {
|
|||
{"port", required_argument, 0, 'p'},
|
||||
{0, 0, 0, 0}};
|
||||
|
||||
if (argc < 2)
|
||||
if (argc < 2) {
|
||||
usage("\n");
|
||||
}
|
||||
|
||||
check_ntp_time_config_wrapper result = {
|
||||
.errorcode = OK,
|
||||
.config = check_ntp_time_config_init(),
|
||||
};
|
||||
|
||||
char *owarn = "60";
|
||||
char *ocrit = "120";
|
||||
|
||||
while (true) {
|
||||
int option = 0;
|
||||
int option_char = getopt_long(argc, argv, "Vhv46qw:c:t:H:p:o:", longopts, &option);
|
||||
if (option_char == -1 || option_char == EOF || option_char == 1)
|
||||
if (option_char == -1 || option_char == EOF || option_char == 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (option_char) {
|
||||
case 'h':
|
||||
|
|
@ -518,7 +535,7 @@ int process_arguments(int argc, char **argv) {
|
|||
verbose++;
|
||||
break;
|
||||
case 'q':
|
||||
quiet = true;
|
||||
result.config.quiet = true;
|
||||
break;
|
||||
case 'w':
|
||||
owarn = optarg;
|
||||
|
|
@ -527,18 +544,19 @@ int process_arguments(int argc, char **argv) {
|
|||
ocrit = optarg;
|
||||
break;
|
||||
case 'H':
|
||||
if (!is_host(optarg))
|
||||
if (!is_host(optarg)) {
|
||||
usage2(_("Invalid hostname/address"), optarg);
|
||||
server_address = strdup(optarg);
|
||||
}
|
||||
result.config.server_address = strdup(optarg);
|
||||
break;
|
||||
case 'p':
|
||||
port = strdup(optarg);
|
||||
result.config.port = strdup(optarg);
|
||||
break;
|
||||
case 't':
|
||||
socket_timeout = atoi(optarg);
|
||||
break;
|
||||
case 'o':
|
||||
time_offset = atoi(optarg);
|
||||
result.config.time_offset = atoi(optarg);
|
||||
break;
|
||||
case '4':
|
||||
address_family = AF_INET;
|
||||
|
|
@ -557,14 +575,16 @@ int process_arguments(int argc, char **argv) {
|
|||
}
|
||||
}
|
||||
|
||||
if (server_address == NULL) {
|
||||
if (result.config.server_address == NULL) {
|
||||
usage4(_("Hostname was not supplied"));
|
||||
}
|
||||
|
||||
return 0;
|
||||
set_thresholds(&result.config.offset_thresholds, owarn, ocrit);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
char *perfd_offset(double offset) {
|
||||
char *perfd_offset(double offset, thresholds *offset_thresholds) {
|
||||
return fperfdata("offset", offset, "s", true, offset_thresholds->warning->end, true, offset_thresholds->critical->end, false, 0, false,
|
||||
0);
|
||||
}
|
||||
|
|
@ -577,10 +597,13 @@ int main(int argc, char *argv[]) {
|
|||
/* Parse extra opts if any */
|
||||
argv = np_extra_opts(&argc, argv, progname);
|
||||
|
||||
if (process_arguments(argc, argv) == ERROR)
|
||||
usage4(_("Could not parse arguments"));
|
||||
check_ntp_time_config_wrapper tmp_config = process_arguments(argc, argv);
|
||||
|
||||
set_thresholds(&offset_thresholds, owarn, ocrit);
|
||||
if (tmp_config.errorcode == ERROR) {
|
||||
usage4(_("Could not parse arguments"));
|
||||
}
|
||||
|
||||
const check_ntp_time_config config = tmp_config.config;
|
||||
|
||||
/* initialize alarm signal handling */
|
||||
signal(SIGALRM, socket_timeout_alarm_handler);
|
||||
|
|
@ -588,13 +611,13 @@ int main(int argc, char *argv[]) {
|
|||
/* set socket timeout */
|
||||
alarm(socket_timeout);
|
||||
|
||||
int offset_result = STATE_OK;
|
||||
int result = STATE_OK;
|
||||
double offset = offset_request(server_address, &offset_result);
|
||||
mp_state_enum offset_result = STATE_OK;
|
||||
mp_state_enum result = STATE_OK;
|
||||
double offset = offset_request(config.server_address, config.port, &offset_result, config.time_offset);
|
||||
if (offset_result == STATE_UNKNOWN) {
|
||||
result = ((!quiet) ? STATE_UNKNOWN : STATE_CRITICAL);
|
||||
result = ((!config.quiet) ? STATE_UNKNOWN : STATE_CRITICAL);
|
||||
} else {
|
||||
result = get_status(fabs(offset), offset_thresholds);
|
||||
result = get_status(fabs(offset), config.offset_thresholds);
|
||||
}
|
||||
|
||||
char *result_line;
|
||||
|
|
@ -619,13 +642,14 @@ int main(int argc, char *argv[]) {
|
|||
xasprintf(&perfdata_line, "");
|
||||
} else {
|
||||
xasprintf(&result_line, "%s %s %.10g secs", result_line, _("Offset"), offset);
|
||||
xasprintf(&perfdata_line, "%s", perfd_offset(offset));
|
||||
xasprintf(&perfdata_line, "%s", perfd_offset(offset, config.offset_thresholds));
|
||||
}
|
||||
printf("%s|%s\n", result_line, perfdata_line);
|
||||
|
||||
if (server_address != NULL)
|
||||
free(server_address);
|
||||
return result;
|
||||
if (config.server_address != NULL) {
|
||||
free(config.server_address);
|
||||
}
|
||||
exit(result);
|
||||
}
|
||||
|
||||
void print_help(void) {
|
||||
|
|
|
|||
28
plugins/check_ntp_time.d/config.h
Normal file
28
plugins/check_ntp_time.d/config.h
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../config.h"
|
||||
#include "thresholds.h"
|
||||
#include <stddef.h>
|
||||
|
||||
typedef struct {
|
||||
char *server_address;
|
||||
char *port;
|
||||
|
||||
bool quiet;
|
||||
int time_offset;
|
||||
|
||||
thresholds *offset_thresholds;
|
||||
} check_ntp_time_config;
|
||||
|
||||
check_ntp_time_config check_ntp_time_config_init() {
|
||||
check_ntp_time_config tmp = {
|
||||
.server_address = NULL,
|
||||
.port = "123",
|
||||
|
||||
.quiet = false,
|
||||
.time_offset = 0,
|
||||
|
||||
.offset_thresholds = NULL,
|
||||
};
|
||||
return tmp;
|
||||
}
|
||||
|
|
@ -1,417 +0,0 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* Monitoring check_overcr plugin
|
||||
*
|
||||
* License: GPL
|
||||
* Copyright (c) 2000-2024 Monitoring Plugins Development Team
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* This file contains the check_overcr plugin
|
||||
*
|
||||
* This plugin attempts to contact the Over-CR collector daemon running on the
|
||||
* remote UNIX server in order to gather the requested system information.
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
const char *progname = "check_overcr";
|
||||
const char *copyright = "2000-2024";
|
||||
const char *email = "devel@monitoring-plugins.org";
|
||||
|
||||
#include "common.h"
|
||||
#include "netutils.h"
|
||||
#include "utils.h"
|
||||
|
||||
enum checkvar {
|
||||
NONE,
|
||||
LOAD1,
|
||||
LOAD5,
|
||||
LOAD15,
|
||||
DPU,
|
||||
PROCS,
|
||||
NETSTAT,
|
||||
UPTIME
|
||||
};
|
||||
|
||||
enum {
|
||||
PORT = 2000
|
||||
};
|
||||
|
||||
static char *server_address = NULL;
|
||||
static int server_port = PORT;
|
||||
static double warning_value = 0L;
|
||||
static double critical_value = 0L;
|
||||
static bool check_warning_value = false;
|
||||
static bool check_critical_value = false;
|
||||
static enum checkvar vars_to_check = NONE;
|
||||
|
||||
static int netstat_port = 0;
|
||||
static char *disk_name = NULL;
|
||||
static char *process_name = NULL;
|
||||
static char send_buffer[MAX_INPUT_BUFFER];
|
||||
|
||||
static int process_arguments(int, char **);
|
||||
void print_usage(void);
|
||||
static void print_help(void);
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int result = STATE_UNKNOWN;
|
||||
char recv_buffer[MAX_INPUT_BUFFER];
|
||||
char temp_buffer[MAX_INPUT_BUFFER];
|
||||
char *temp_ptr = NULL;
|
||||
bool found_disk = false;
|
||||
unsigned long percent_used_disk_space = 100;
|
||||
double load;
|
||||
double load_1min;
|
||||
double load_5min;
|
||||
double load_15min;
|
||||
int port_connections = 0;
|
||||
int processes = 0;
|
||||
double uptime_raw_hours;
|
||||
int uptime_raw_minutes = 0;
|
||||
int uptime_days = 0;
|
||||
int uptime_hours = 0;
|
||||
int uptime_minutes = 0;
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
textdomain(PACKAGE);
|
||||
|
||||
/* Parse extra opts if any */
|
||||
argv = np_extra_opts(&argc, argv, progname);
|
||||
|
||||
if (process_arguments(argc, argv) == ERROR)
|
||||
usage4(_("Could not parse arguments"));
|
||||
|
||||
/* initialize alarm signal handling */
|
||||
signal(SIGALRM, socket_timeout_alarm_handler);
|
||||
|
||||
/* set socket timeout */
|
||||
alarm(socket_timeout);
|
||||
|
||||
result = process_tcp_request2(server_address, server_port, send_buffer, recv_buffer, sizeof(recv_buffer));
|
||||
|
||||
switch (vars_to_check) {
|
||||
|
||||
case LOAD1:
|
||||
case LOAD5:
|
||||
case LOAD15:
|
||||
|
||||
if (result != STATE_OK)
|
||||
die(result, _("Unknown error fetching load data\n"));
|
||||
|
||||
temp_ptr = (char *)strtok(recv_buffer, "\r\n");
|
||||
if (temp_ptr == NULL)
|
||||
die(STATE_CRITICAL, _("Invalid response from server - no load information\n"));
|
||||
else
|
||||
load_1min = strtod(temp_ptr, NULL);
|
||||
|
||||
temp_ptr = (char *)strtok(NULL, "\r\n");
|
||||
if (temp_ptr == NULL)
|
||||
die(STATE_CRITICAL, _("Invalid response from server after load 1\n"));
|
||||
else
|
||||
load_5min = strtod(temp_ptr, NULL);
|
||||
|
||||
temp_ptr = (char *)strtok(NULL, "\r\n");
|
||||
if (temp_ptr == NULL)
|
||||
die(STATE_CRITICAL, _("Invalid response from server after load 5\n"));
|
||||
else
|
||||
load_15min = strtod(temp_ptr, NULL);
|
||||
|
||||
switch (vars_to_check) {
|
||||
case LOAD1:
|
||||
strcpy(temp_buffer, "1");
|
||||
load = load_1min;
|
||||
break;
|
||||
case LOAD5:
|
||||
strcpy(temp_buffer, "5");
|
||||
load = load_5min;
|
||||
break;
|
||||
default:
|
||||
strcpy(temp_buffer, "15");
|
||||
load = load_15min;
|
||||
break;
|
||||
}
|
||||
|
||||
if (check_critical_value && (load >= critical_value))
|
||||
result = STATE_CRITICAL;
|
||||
else if (check_warning_value && (load >= warning_value))
|
||||
result = STATE_WARNING;
|
||||
|
||||
die(result, _("Load %s - %s-min load average = %0.2f"), state_text(result), temp_buffer, load);
|
||||
|
||||
break;
|
||||
|
||||
case DPU:
|
||||
|
||||
if (result != STATE_OK)
|
||||
die(result, _("Unknown error fetching disk data\n"));
|
||||
|
||||
for (temp_ptr = (char *)strtok(recv_buffer, " "); temp_ptr != NULL; temp_ptr = (char *)strtok(NULL, " ")) {
|
||||
|
||||
if (!strcmp(temp_ptr, disk_name)) {
|
||||
found_disk = true;
|
||||
temp_ptr = (char *)strtok(NULL, "%");
|
||||
if (temp_ptr == NULL)
|
||||
die(STATE_CRITICAL, _("Invalid response from server\n"));
|
||||
else
|
||||
percent_used_disk_space = strtoul(temp_ptr, NULL, 10);
|
||||
break;
|
||||
}
|
||||
|
||||
temp_ptr = (char *)strtok(NULL, "\r\n");
|
||||
}
|
||||
|
||||
/* error if we couldn't find the info for the disk */
|
||||
if (!found_disk)
|
||||
die(STATE_CRITICAL, "CRITICAL - Disk '%s' non-existent or not mounted", disk_name);
|
||||
|
||||
if (check_critical_value && (percent_used_disk_space >= critical_value))
|
||||
result = STATE_CRITICAL;
|
||||
else if (check_warning_value && (percent_used_disk_space >= warning_value))
|
||||
result = STATE_WARNING;
|
||||
|
||||
die(result, "Disk %s - %lu%% used on %s", state_text(result), percent_used_disk_space, disk_name);
|
||||
|
||||
break;
|
||||
|
||||
case NETSTAT:
|
||||
|
||||
if (result != STATE_OK)
|
||||
die(result, _("Unknown error fetching network status\n"));
|
||||
else
|
||||
port_connections = strtod(recv_buffer, NULL);
|
||||
|
||||
if (check_critical_value && (port_connections >= critical_value))
|
||||
result = STATE_CRITICAL;
|
||||
else if (check_warning_value && (port_connections >= warning_value))
|
||||
result = STATE_WARNING;
|
||||
|
||||
die(result, _("Net %s - %d connection%s on port %d"), state_text(result), port_connections, (port_connections == 1) ? "" : "s",
|
||||
netstat_port);
|
||||
|
||||
break;
|
||||
|
||||
case PROCS:
|
||||
|
||||
if (result != STATE_OK)
|
||||
die(result, _("Unknown error fetching process status\n"));
|
||||
|
||||
temp_ptr = (char *)strtok(recv_buffer, "(");
|
||||
if (temp_ptr == NULL)
|
||||
die(STATE_CRITICAL, _("Invalid response from server\n"));
|
||||
|
||||
temp_ptr = (char *)strtok(NULL, ")");
|
||||
if (temp_ptr == NULL)
|
||||
die(STATE_CRITICAL, _("Invalid response from server\n"));
|
||||
else
|
||||
processes = strtod(temp_ptr, NULL);
|
||||
|
||||
if (check_critical_value && (processes >= critical_value))
|
||||
result = STATE_CRITICAL;
|
||||
else if (check_warning_value && (processes >= warning_value))
|
||||
result = STATE_WARNING;
|
||||
|
||||
die(result, _("Process %s - %d instance%s of %s running"), state_text(result), processes, (processes == 1) ? "" : "s",
|
||||
process_name);
|
||||
break;
|
||||
|
||||
case UPTIME:
|
||||
|
||||
if (result != STATE_OK)
|
||||
return result;
|
||||
|
||||
uptime_raw_hours = strtod(recv_buffer, NULL);
|
||||
uptime_raw_minutes = (unsigned long)(uptime_raw_hours * 60.0);
|
||||
|
||||
if (check_critical_value && (uptime_raw_minutes <= critical_value))
|
||||
result = STATE_CRITICAL;
|
||||
else if (check_warning_value && (uptime_raw_minutes <= warning_value))
|
||||
result = STATE_WARNING;
|
||||
|
||||
uptime_days = uptime_raw_minutes / 1440;
|
||||
uptime_raw_minutes %= 1440;
|
||||
uptime_hours = uptime_raw_minutes / 60;
|
||||
uptime_raw_minutes %= 60;
|
||||
uptime_minutes = uptime_raw_minutes;
|
||||
|
||||
die(result, _("Uptime %s - Up %d days %d hours %d minutes"), state_text(result), uptime_days, uptime_hours, uptime_minutes);
|
||||
break;
|
||||
|
||||
default:
|
||||
die(STATE_UNKNOWN, _("Nothing to check!\n"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* process command-line arguments */
|
||||
int process_arguments(int argc, char **argv) {
|
||||
int c;
|
||||
|
||||
int option = 0;
|
||||
static struct option longopts[] = {
|
||||
{"port", required_argument, 0, 'p'}, {"timeout", required_argument, 0, 't'}, {"critical", required_argument, 0, 'c'},
|
||||
{"warning", required_argument, 0, 'w'}, {"variable", required_argument, 0, 'v'}, {"hostname", required_argument, 0, 'H'},
|
||||
{"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}};
|
||||
|
||||
/* no options were supplied */
|
||||
if (argc < 2)
|
||||
return ERROR;
|
||||
|
||||
/* backwards compatibility */
|
||||
if (!is_option(argv[1])) {
|
||||
server_address = argv[1];
|
||||
argv[1] = argv[0];
|
||||
argv = &argv[1];
|
||||
argc--;
|
||||
}
|
||||
|
||||
for (c = 1; c < argc; c++) {
|
||||
if (strcmp("-to", argv[c]) == 0)
|
||||
strcpy(argv[c], "-t");
|
||||
else if (strcmp("-wv", argv[c]) == 0)
|
||||
strcpy(argv[c], "-w");
|
||||
else if (strcmp("-cv", argv[c]) == 0)
|
||||
strcpy(argv[c], "-c");
|
||||
}
|
||||
|
||||
while (1) {
|
||||
c = getopt_long(argc, argv, "+hVH:t:c:w:p:v:", longopts, &option);
|
||||
|
||||
if (c == -1 || c == EOF || c == 1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
case '?': /* print short usage statement if args not parsable */
|
||||
usage5();
|
||||
case 'h': /* help */
|
||||
print_help();
|
||||
exit(STATE_UNKNOWN);
|
||||
case 'V': /* version */
|
||||
print_revision(progname, NP_VERSION);
|
||||
exit(STATE_UNKNOWN);
|
||||
case 'H': /* hostname */
|
||||
server_address = optarg;
|
||||
break;
|
||||
case 'p': /* port */
|
||||
if (is_intnonneg(optarg))
|
||||
server_port = atoi(optarg);
|
||||
else
|
||||
die(STATE_UNKNOWN, _("Server port an integer\n"));
|
||||
break;
|
||||
case 'v': /* variable */
|
||||
if (strcmp(optarg, "LOAD") == 0) {
|
||||
strcpy(send_buffer, "LOAD\r\nQUIT\r\n");
|
||||
if (strcmp(optarg, "LOAD1") == 0)
|
||||
vars_to_check = LOAD1;
|
||||
else if (strcmp(optarg, "LOAD5") == 0)
|
||||
vars_to_check = LOAD5;
|
||||
else if (strcmp(optarg, "LOAD15") == 0)
|
||||
vars_to_check = LOAD15;
|
||||
} else if (strcmp(optarg, "UPTIME") == 0) {
|
||||
vars_to_check = UPTIME;
|
||||
strcpy(send_buffer, "UPTIME\r\n");
|
||||
} else if (strstr(optarg, "PROC") == optarg) {
|
||||
vars_to_check = PROCS;
|
||||
process_name = strscpy(process_name, optarg + 4);
|
||||
sprintf(send_buffer, "PROCESS %s\r\n", process_name);
|
||||
} else if (strstr(optarg, "NET") == optarg) {
|
||||
vars_to_check = NETSTAT;
|
||||
netstat_port = atoi(optarg + 3);
|
||||
sprintf(send_buffer, "NETSTAT %d\r\n", netstat_port);
|
||||
} else if (strstr(optarg, "DPU") == optarg) {
|
||||
vars_to_check = DPU;
|
||||
strcpy(send_buffer, "DISKSPACE\r\n");
|
||||
disk_name = strscpy(disk_name, optarg + 3);
|
||||
} else
|
||||
return ERROR;
|
||||
break;
|
||||
case 'w': /* warning threshold */
|
||||
warning_value = strtoul(optarg, NULL, 10);
|
||||
check_warning_value = true;
|
||||
break;
|
||||
case 'c': /* critical threshold */
|
||||
critical_value = strtoul(optarg, NULL, 10);
|
||||
check_critical_value = true;
|
||||
break;
|
||||
case 't': /* timeout */
|
||||
socket_timeout = atoi(optarg);
|
||||
if (socket_timeout <= 0)
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
void print_help(void) {
|
||||
char *myport;
|
||||
xasprintf(&myport, "%d", PORT);
|
||||
|
||||
print_revision(progname, NP_VERSION);
|
||||
|
||||
printf("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
|
||||
printf(COPYRIGHT, copyright, email);
|
||||
|
||||
printf("%s\n", _("This plugin attempts to contact the Over-CR collector daemon running on the"));
|
||||
printf("%s\n", _("remote UNIX server in order to gather the requested system information."));
|
||||
|
||||
printf("\n\n");
|
||||
|
||||
print_usage();
|
||||
|
||||
printf(UT_HELP_VRSN);
|
||||
printf(UT_EXTRA_OPTS);
|
||||
|
||||
printf(UT_HOST_PORT, 'p', myport);
|
||||
|
||||
printf(" %s\n", "-w, --warning=INTEGER");
|
||||
printf(" %s\n", _("Threshold which will result in a warning status"));
|
||||
printf(" %s\n", "-c, --critical=INTEGER");
|
||||
printf(" %s\n", _("Threshold which will result in a critical status"));
|
||||
printf(" %s\n", "-v, --variable=STRING");
|
||||
printf(" %s\n", _("Variable to check. Valid variables include:"));
|
||||
printf(" %s\n", _("LOAD1 = 1 minute average CPU load"));
|
||||
printf(" %s\n", _("LOAD5 = 5 minute average CPU load"));
|
||||
printf(" %s\n", _("LOAD15 = 15 minute average CPU load"));
|
||||
printf(" %s\n", _("DPU<filesys> = percent used disk space on filesystem <filesys>"));
|
||||
printf(" %s\n", _("PROC<process> = number of running processes with name <process>"));
|
||||
printf(" %s\n", _("NET<port> = number of active connections on TCP port <port>"));
|
||||
printf(" %s\n", _("UPTIME = system uptime in seconds"));
|
||||
|
||||
printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
|
||||
|
||||
printf(UT_VERBOSE);
|
||||
|
||||
printf("\n");
|
||||
printf("%s\n", _("This plugin requires that Eric Molitors' Over-CR collector daemon be"));
|
||||
printf("%s\n", _("running on the remote server."));
|
||||
printf("%s\n", _("Over-CR can be downloaded from http://www.molitor.org/overcr"));
|
||||
printf("%s\n", _("This plugin was tested with version 0.99.53 of the Over-CR collector"));
|
||||
|
||||
printf("\n");
|
||||
printf("%s\n", _("Notes:"));
|
||||
printf(" %s\n", _("For the available options, the critical threshold value should always be"));
|
||||
printf(" %s\n", _("higher than the warning threshold value, EXCEPT with the uptime variable"));
|
||||
|
||||
printf(UT_SUPPORT);
|
||||
}
|
||||
|
||||
void print_usage(void) {
|
||||
printf("%s\n", _("Usage:"));
|
||||
printf("%s -H host [-p port] [-v variable] [-w warning] [-c critical] [-t timeout]\n", progname);
|
||||
}
|
||||
|
|
@ -28,6 +28,7 @@
|
|||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "states.h"
|
||||
const char *progname = "check_pgsql";
|
||||
const char *copyright = "1999-2024";
|
||||
const char *email = "devel@monitoring-plugins.org";
|
||||
|
|
@ -35,12 +36,13 @@ const char *email = "devel@monitoring-plugins.org";
|
|||
#include "common.h"
|
||||
#include "utils.h"
|
||||
#include "utils_cmd.h"
|
||||
#include "check_pgsql.d/config.h"
|
||||
#include "thresholds.h"
|
||||
|
||||
#include "netutils.h"
|
||||
#include <libpq-fe.h>
|
||||
#include <pg_config_manual.h>
|
||||
|
||||
#define DEFAULT_DB "template1"
|
||||
#define DEFAULT_HOST "127.0.0.1"
|
||||
|
||||
/* return the PSQL server version as a 3-tuple */
|
||||
|
|
@ -53,33 +55,18 @@ const char *email = "devel@monitoring-plugins.org";
|
|||
#define PSQL_SOCKET3(host, port) \
|
||||
((NULL == (host)) || ('\0' == *(host))) ? DEFAULT_PGSOCKET_DIR : host, PSQL_IS_UNIX_DOMAIN_SOCKET(host) ? "/.s.PGSQL." : ":", port
|
||||
|
||||
enum {
|
||||
DEFAULT_PORT = 5432,
|
||||
DEFAULT_WARN = 2,
|
||||
DEFAULT_CRIT = 8
|
||||
};
|
||||
typedef struct {
|
||||
int errorcode;
|
||||
check_pgsql_config config;
|
||||
} check_pgsql_config_wrapper;
|
||||
static check_pgsql_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
|
||||
static int process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
static void print_help(void);
|
||||
static bool is_pg_logname(char * /*username*/);
|
||||
static int do_query(PGconn * /*conn*/, char * /*query*/);
|
||||
static mp_state_enum do_query(PGconn * /*conn*/, char * /*query*/, const char /*pgqueryname*/[], thresholds * /*qthresholds*/,
|
||||
char * /*query_warning*/, char * /*query_critical*/);
|
||||
void print_usage(void);
|
||||
|
||||
static char *pghost = NULL; /* host name of the backend server */
|
||||
static char *pgport = NULL; /* port of the backend server */
|
||||
static char *pgoptions = NULL;
|
||||
static char *pgtty = NULL;
|
||||
static char dbName[NAMEDATALEN] = DEFAULT_DB;
|
||||
static char *pguser = NULL;
|
||||
static char *pgpasswd = NULL;
|
||||
static char *pgparams = NULL;
|
||||
static double twarn = (double)DEFAULT_WARN;
|
||||
static double tcrit = (double)DEFAULT_CRIT;
|
||||
static char *pgquery = NULL;
|
||||
static char *pgqueryname = NULL;
|
||||
static char *query_warning = NULL;
|
||||
static char *query_critical = NULL;
|
||||
static thresholds *qthresholds = NULL;
|
||||
static int verbose = 0;
|
||||
|
||||
#define OPTID_QUERYNAME -1000
|
||||
|
|
@ -139,21 +126,19 @@ int main(int argc, char **argv) {
|
|||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
textdomain(PACKAGE);
|
||||
|
||||
/* begin, by setting the parameters for a backend connection if the
|
||||
* parameters are null, then the system will try to use reasonable
|
||||
* defaults by looking up environment variables or, failing that,
|
||||
* using hardwired constants */
|
||||
|
||||
pgoptions = NULL; /* special options to start up the backend server */
|
||||
pgtty = NULL; /* debugging tty for the backend server */
|
||||
|
||||
/* Parse extra opts if any */
|
||||
argv = np_extra_opts(&argc, argv, progname);
|
||||
|
||||
if (process_arguments(argc, argv) == ERROR)
|
||||
check_pgsql_config_wrapper tmp_config = process_arguments(argc, argv);
|
||||
if (tmp_config.errorcode == ERROR) {
|
||||
usage4(_("Could not parse arguments"));
|
||||
if (verbose > 2)
|
||||
}
|
||||
|
||||
const check_pgsql_config config = tmp_config.config;
|
||||
|
||||
if (verbose > 2) {
|
||||
printf("Arguments initialized\n");
|
||||
}
|
||||
|
||||
/* Set signal handling and alarm */
|
||||
if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) {
|
||||
|
|
@ -162,25 +147,32 @@ int main(int argc, char **argv) {
|
|||
alarm(timeout_interval);
|
||||
|
||||
char *conninfo = NULL;
|
||||
if (pgparams)
|
||||
asprintf(&conninfo, "%s ", pgparams);
|
||||
if (config.pgparams) {
|
||||
asprintf(&conninfo, "%s ", config.pgparams);
|
||||
}
|
||||
|
||||
asprintf(&conninfo, "%sdbname = '%s'", conninfo ? conninfo : "", dbName);
|
||||
if (pghost)
|
||||
asprintf(&conninfo, "%s host = '%s'", conninfo, pghost);
|
||||
if (pgport)
|
||||
asprintf(&conninfo, "%s port = '%s'", conninfo, pgport);
|
||||
if (pgoptions)
|
||||
asprintf(&conninfo, "%s options = '%s'", conninfo, pgoptions);
|
||||
asprintf(&conninfo, "%sdbname = '%s'", conninfo ? conninfo : "", config.dbName);
|
||||
if (config.pghost) {
|
||||
asprintf(&conninfo, "%s host = '%s'", conninfo, config.pghost);
|
||||
}
|
||||
if (config.pgport) {
|
||||
asprintf(&conninfo, "%s port = '%s'", conninfo, config.pgport);
|
||||
}
|
||||
if (config.pgoptions) {
|
||||
asprintf(&conninfo, "%s options = '%s'", conninfo, config.pgoptions);
|
||||
}
|
||||
/* if (pgtty) -- ignored by PQconnectdb */
|
||||
if (pguser)
|
||||
asprintf(&conninfo, "%s user = '%s'", conninfo, pguser);
|
||||
if (config.pguser) {
|
||||
asprintf(&conninfo, "%s user = '%s'", conninfo, config.pguser);
|
||||
}
|
||||
|
||||
if (verbose) /* do not include password (see right below) in output */
|
||||
printf("Connecting to PostgreSQL using conninfo: %s%s\n", conninfo, pgpasswd ? " password = <hidden>" : "");
|
||||
if (verbose) { /* do not include password (see right below) in output */
|
||||
printf("Connecting to PostgreSQL using conninfo: %s%s\n", conninfo, config.pgpasswd ? " password = <hidden>" : "");
|
||||
}
|
||||
|
||||
if (pgpasswd)
|
||||
asprintf(&conninfo, "%s password = '%s'", conninfo, pgpasswd);
|
||||
if (config.pgpasswd) {
|
||||
asprintf(&conninfo, "%s password = '%s'", conninfo, config.pgpasswd);
|
||||
}
|
||||
|
||||
/* make a connection to the database */
|
||||
struct timeval start_timeval;
|
||||
|
|
@ -194,24 +186,26 @@ int main(int argc, char **argv) {
|
|||
end_timeval.tv_usec += 1000000;
|
||||
}
|
||||
double elapsed_time =
|
||||
(double)(end_timeval.tv_sec - start_timeval.tv_sec) + (double)(end_timeval.tv_usec - start_timeval.tv_usec) / 1000000.0;
|
||||
(double)(end_timeval.tv_sec - start_timeval.tv_sec) + ((double)(end_timeval.tv_usec - start_timeval.tv_usec) / 1000000.0);
|
||||
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
printf("Time elapsed: %f\n", elapsed_time);
|
||||
}
|
||||
|
||||
/* check to see that the backend connection was successfully made */
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
printf("Verifying connection\n");
|
||||
}
|
||||
if (PQstatus(conn) == CONNECTION_BAD) {
|
||||
printf(_("CRITICAL - no connection to '%s' (%s).\n"), dbName, PQerrorMessage(conn));
|
||||
printf(_("CRITICAL - no connection to '%s' (%s).\n"), config.dbName, PQerrorMessage(conn));
|
||||
PQfinish(conn);
|
||||
return STATE_CRITICAL;
|
||||
}
|
||||
|
||||
int status = STATE_UNKNOWN;
|
||||
if (elapsed_time > tcrit) {
|
||||
mp_state_enum status = STATE_UNKNOWN;
|
||||
if (elapsed_time > config.tcrit) {
|
||||
status = STATE_CRITICAL;
|
||||
} else if (elapsed_time > twarn) {
|
||||
} else if (elapsed_time > config.twarn) {
|
||||
status = STATE_WARNING;
|
||||
} else {
|
||||
status = STATE_OK;
|
||||
|
|
@ -228,21 +222,23 @@ int main(int argc, char **argv) {
|
|||
PQprotocolVersion(conn), PQbackendPID(conn));
|
||||
}
|
||||
|
||||
printf(_(" %s - database %s (%f sec.)|%s\n"), state_text(status), dbName, elapsed_time,
|
||||
fperfdata("time", elapsed_time, "s", !!(twarn > 0.0), twarn, !!(tcrit > 0.0), tcrit, true, 0, false, 0));
|
||||
printf(_(" %s - database %s (%f sec.)|%s\n"), state_text(status), config.dbName, elapsed_time,
|
||||
fperfdata("time", elapsed_time, "s", (config.twarn > 0.0), config.twarn, (config.tcrit > 0.0), config.tcrit, true, 0, false, 0));
|
||||
|
||||
int query_status = STATE_UNKNOWN;
|
||||
if (pgquery)
|
||||
query_status = do_query(conn, pgquery);
|
||||
mp_state_enum query_status = STATE_UNKNOWN;
|
||||
if (config.pgquery) {
|
||||
query_status = do_query(conn, config.pgquery, config.pgqueryname, config.qthresholds, config.query_warning, config.query_critical);
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
printf("Closing connection\n");
|
||||
}
|
||||
PQfinish(conn);
|
||||
return (pgquery && query_status > status) ? query_status : status;
|
||||
return (config.pgquery && query_status > status) ? query_status : status;
|
||||
}
|
||||
|
||||
/* process command-line arguments */
|
||||
int process_arguments(int argc, char **argv) {
|
||||
check_pgsql_config_wrapper process_arguments(int argc, char **argv) {
|
||||
static struct option longopts[] = {{"help", no_argument, 0, 'h'},
|
||||
{"version", no_argument, 0, 'V'},
|
||||
{"timeout", required_argument, 0, 't'},
|
||||
|
|
@ -262,12 +258,18 @@ int process_arguments(int argc, char **argv) {
|
|||
{"verbose", no_argument, 0, 'v'},
|
||||
{0, 0, 0, 0}};
|
||||
|
||||
check_pgsql_config_wrapper result = {
|
||||
.errorcode = OK,
|
||||
.config = check_pgsql_config_init(),
|
||||
};
|
||||
|
||||
while (true) {
|
||||
int option = 0;
|
||||
int option_char = getopt_long(argc, argv, "hVt:c:w:H:P:d:l:p:a:o:q:C:W:v", longopts, &option);
|
||||
|
||||
if (option_char == EOF)
|
||||
if (option_char == EOF) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (option_char) {
|
||||
case '?': /* usage */
|
||||
|
|
@ -279,68 +281,75 @@ int process_arguments(int argc, char **argv) {
|
|||
print_revision(progname, NP_VERSION);
|
||||
exit(STATE_UNKNOWN);
|
||||
case 't': /* timeout period */
|
||||
if (!is_integer(optarg))
|
||||
if (!is_integer(optarg)) {
|
||||
usage2(_("Timeout interval must be a positive integer"), optarg);
|
||||
else
|
||||
} else {
|
||||
timeout_interval = atoi(optarg);
|
||||
}
|
||||
break;
|
||||
case 'c': /* critical time threshold */
|
||||
if (!is_nonnegative(optarg))
|
||||
if (!is_nonnegative(optarg)) {
|
||||
usage2(_("Critical threshold must be a positive integer"), optarg);
|
||||
else
|
||||
tcrit = strtod(optarg, NULL);
|
||||
} else {
|
||||
result.config.tcrit = strtod(optarg, NULL);
|
||||
}
|
||||
break;
|
||||
case 'w': /* warning time threshold */
|
||||
if (!is_nonnegative(optarg))
|
||||
if (!is_nonnegative(optarg)) {
|
||||
usage2(_("Warning threshold must be a positive integer"), optarg);
|
||||
else
|
||||
twarn = strtod(optarg, NULL);
|
||||
} else {
|
||||
result.config.twarn = strtod(optarg, NULL);
|
||||
}
|
||||
break;
|
||||
case 'C': /* critical query threshold */
|
||||
query_critical = optarg;
|
||||
result.config.query_critical = optarg;
|
||||
break;
|
||||
case 'W': /* warning query threshold */
|
||||
query_warning = optarg;
|
||||
result.config.query_warning = optarg;
|
||||
break;
|
||||
case 'H': /* host */
|
||||
if ((*optarg != '/') && (!is_host(optarg)))
|
||||
if ((*optarg != '/') && (!is_host(optarg))) {
|
||||
usage2(_("Invalid hostname/address"), optarg);
|
||||
else
|
||||
pghost = optarg;
|
||||
} else {
|
||||
result.config.pghost = optarg;
|
||||
}
|
||||
break;
|
||||
case 'P': /* port */
|
||||
if (!is_integer(optarg))
|
||||
if (!is_integer(optarg)) {
|
||||
usage2(_("Port must be a positive integer"), optarg);
|
||||
else
|
||||
pgport = optarg;
|
||||
} else {
|
||||
result.config.pgport = optarg;
|
||||
}
|
||||
break;
|
||||
case 'd': /* database name */
|
||||
if (strlen(optarg) >= NAMEDATALEN) {
|
||||
usage2(_("Database name exceeds the maximum length"), optarg);
|
||||
}
|
||||
snprintf(dbName, NAMEDATALEN, "%s", optarg);
|
||||
snprintf(result.config.dbName, NAMEDATALEN, "%s", optarg);
|
||||
break;
|
||||
case 'l': /* login name */
|
||||
if (!is_pg_logname(optarg))
|
||||
if (!is_pg_logname(optarg)) {
|
||||
usage2(_("User name is not valid"), optarg);
|
||||
else
|
||||
pguser = optarg;
|
||||
} else {
|
||||
result.config.pguser = optarg;
|
||||
}
|
||||
break;
|
||||
case 'p': /* authentication password */
|
||||
case 'a':
|
||||
pgpasswd = optarg;
|
||||
result.config.pgpasswd = optarg;
|
||||
break;
|
||||
case 'o':
|
||||
if (pgparams)
|
||||
asprintf(&pgparams, "%s %s", pgparams, optarg);
|
||||
else
|
||||
asprintf(&pgparams, "%s", optarg);
|
||||
if (result.config.pgparams) {
|
||||
asprintf(&result.config.pgparams, "%s %s", result.config.pgparams, optarg);
|
||||
} else {
|
||||
asprintf(&result.config.pgparams, "%s", optarg);
|
||||
}
|
||||
break;
|
||||
case 'q':
|
||||
pgquery = optarg;
|
||||
result.config.pgquery = optarg;
|
||||
break;
|
||||
case OPTID_QUERYNAME:
|
||||
pgqueryname = optarg;
|
||||
result.config.pgqueryname = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
|
|
@ -348,9 +357,9 @@ int process_arguments(int argc, char **argv) {
|
|||
}
|
||||
}
|
||||
|
||||
set_thresholds(&qthresholds, query_warning, query_critical);
|
||||
set_thresholds(&result.config.qthresholds, result.config.query_warning, result.config.query_critical);
|
||||
|
||||
return OK;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -378,8 +387,9 @@ should be added.</para>
|
|||
******************************************************************************/
|
||||
|
||||
bool is_pg_logname(char *username) {
|
||||
if (strlen(username) > NAMEDATALEN - 1)
|
||||
if (strlen(username) > NAMEDATALEN - 1) {
|
||||
return (false);
|
||||
}
|
||||
return (true);
|
||||
}
|
||||
|
||||
|
|
@ -394,7 +404,7 @@ bool is_pg_logname(char *username) {
|
|||
void print_help(void) {
|
||||
char *myport;
|
||||
|
||||
xasprintf(&myport, "%d", DEFAULT_PORT);
|
||||
xasprintf(&myport, "%d", 5432);
|
||||
|
||||
print_revision(progname, NP_VERSION);
|
||||
|
||||
|
|
@ -482,9 +492,11 @@ void print_usage(void) {
|
|||
"[-q <query>] [-C <critical query range>] [-W <warning query range>]\n");
|
||||
}
|
||||
|
||||
int do_query(PGconn *conn, char *query) {
|
||||
if (verbose)
|
||||
mp_state_enum do_query(PGconn *conn, char *query, const char pgqueryname[], thresholds *qthresholds, char *query_warning,
|
||||
char *query_critical) {
|
||||
if (verbose) {
|
||||
printf("Executing SQL query \"%s\".\n", query);
|
||||
}
|
||||
PGresult *res = PQexec(conn, query);
|
||||
|
||||
if (PGRES_TUPLES_OK != PQresultStatus(res)) {
|
||||
|
|
@ -510,8 +522,9 @@ int do_query(PGconn *conn, char *query) {
|
|||
|
||||
char *endptr = NULL;
|
||||
double value = strtod(val_str, &endptr);
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
printf("Query result: %f\n", value);
|
||||
}
|
||||
|
||||
if (endptr == val_str) {
|
||||
printf("QUERY %s - %s: %s\n", _("CRITICAL"), _("Is not a numeric"), val_str);
|
||||
|
|
@ -519,11 +532,12 @@ int do_query(PGconn *conn, char *query) {
|
|||
}
|
||||
|
||||
if ((endptr != NULL) && (*endptr != '\0')) {
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
printf("Garbage after value: %s.\n", endptr);
|
||||
}
|
||||
}
|
||||
|
||||
int my_status = get_status(value, qthresholds);
|
||||
mp_state_enum my_status = get_status(value, qthresholds);
|
||||
printf("QUERY %s - ", (my_status == STATE_OK) ? _("OK")
|
||||
: (my_status == STATE_WARNING) ? _("WARNING")
|
||||
: (my_status == STATE_CRITICAL) ? _("CRITICAL")
|
||||
|
|
|
|||
61
plugins/check_pgsql.d/config.h
Normal file
61
plugins/check_pgsql.d/config.h
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../config.h"
|
||||
#include "thresholds.h"
|
||||
#include <stddef.h>
|
||||
#include <pg_config_manual.h>
|
||||
|
||||
#define DEFAULT_DB "template1"
|
||||
|
||||
enum {
|
||||
DEFAULT_WARN = 2,
|
||||
DEFAULT_CRIT = 8,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
char *pghost; /* host name of the backend server */
|
||||
char *pgport; /* port of the backend server */
|
||||
char *pgoptions; /* special options to start up the backend server */
|
||||
char *pgtty; /* debugging tty for the backend server */
|
||||
char dbName[NAMEDATALEN];
|
||||
char *pguser;
|
||||
char *pgpasswd;
|
||||
char *pgparams;
|
||||
char *pgquery;
|
||||
char *pgqueryname;
|
||||
|
||||
double twarn;
|
||||
double tcrit;
|
||||
thresholds *qthresholds;
|
||||
char *query_warning;
|
||||
char *query_critical;
|
||||
} check_pgsql_config;
|
||||
|
||||
/* begin, by setting the parameters for a backend connection if the
|
||||
* parameters are null, then the system will try to use reasonable
|
||||
* defaults by looking up environment variables or, failing that,
|
||||
* using hardwired constants
|
||||
* this targets .pgoptions and .pgtty
|
||||
*/
|
||||
|
||||
check_pgsql_config check_pgsql_config_init() {
|
||||
check_pgsql_config tmp = {
|
||||
.pghost = NULL,
|
||||
.pgport = NULL,
|
||||
.pgoptions = NULL,
|
||||
.pgtty = NULL,
|
||||
.dbName = DEFAULT_DB,
|
||||
.pguser = NULL,
|
||||
.pgpasswd = NULL,
|
||||
.pgparams = NULL,
|
||||
.pgquery = NULL,
|
||||
.pgqueryname = NULL,
|
||||
|
||||
.twarn = (double)DEFAULT_WARN,
|
||||
.tcrit = (double)DEFAULT_CRIT,
|
||||
.qthresholds = NULL,
|
||||
.query_warning = NULL,
|
||||
.query_critical = NULL,
|
||||
};
|
||||
return tmp;
|
||||
}
|
||||
|
|
@ -36,61 +36,52 @@ const char *email = "devel@monitoring-plugins.org";
|
|||
#include "netutils.h"
|
||||
#include "popen.h"
|
||||
#include "utils.h"
|
||||
#include "check_ping.d/config.h"
|
||||
#include "../lib/states.h"
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#define WARN_DUPLICATES "DUPLICATES FOUND! "
|
||||
#define UNKNOWN_TRIP_TIME -1.0 /* -1 seconds */
|
||||
#define WARN_DUPLICATES "DUPLICATES FOUND! "
|
||||
|
||||
enum {
|
||||
UNKNOWN_PACKET_LOSS = 200, /* 200% */
|
||||
DEFAULT_MAX_PACKETS = 5 /* default no. of ICMP ECHO packets */
|
||||
};
|
||||
typedef struct {
|
||||
int errorcode;
|
||||
check_ping_config config;
|
||||
} check_ping_config_wrapper;
|
||||
static check_ping_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
static check_ping_config_wrapper validate_arguments(check_ping_config_wrapper /*config_wrapper*/);
|
||||
|
||||
static int process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
static int get_threshold(char * /*arg*/, float * /*trta*/, int * /*tpl*/);
|
||||
static int validate_arguments(void);
|
||||
static int run_ping(const char *cmd, const char *addr);
|
||||
static int error_scan(char buf[MAX_INPUT_BUFFER], const char *addr);
|
||||
static int get_threshold(char * /*arg*/, double * /*trta*/, int * /*tpl*/);
|
||||
|
||||
typedef struct {
|
||||
mp_state_enum state;
|
||||
double round_trip_average;
|
||||
int packet_loss;
|
||||
} ping_result;
|
||||
static ping_result run_ping(const char *cmd, const char *addr, double /*crta*/);
|
||||
|
||||
static mp_state_enum error_scan(char buf[MAX_INPUT_BUFFER], const char *addr);
|
||||
static void print_help(void);
|
||||
void print_usage(void);
|
||||
|
||||
static bool display_html = false;
|
||||
static int wpl = UNKNOWN_PACKET_LOSS;
|
||||
static int cpl = UNKNOWN_PACKET_LOSS;
|
||||
static float wrta = UNKNOWN_TRIP_TIME;
|
||||
static float crta = UNKNOWN_TRIP_TIME;
|
||||
static char **addresses = NULL;
|
||||
static int n_addresses = 0;
|
||||
static int max_addr = 1;
|
||||
static int max_packets = -1;
|
||||
static int verbose = 0;
|
||||
|
||||
static float rta = UNKNOWN_TRIP_TIME;
|
||||
static int pl = UNKNOWN_PACKET_LOSS;
|
||||
|
||||
static char *warn_text;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
char *cmd = NULL;
|
||||
char *rawcmd = NULL;
|
||||
int result = STATE_UNKNOWN;
|
||||
int this_result = STATE_UNKNOWN;
|
||||
int i;
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
setlocale(LC_NUMERIC, "C");
|
||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
textdomain(PACKAGE);
|
||||
|
||||
addresses = malloc(sizeof(char *) * max_addr);
|
||||
addresses[0] = NULL;
|
||||
|
||||
/* Parse extra opts if any */
|
||||
argv = np_extra_opts(&argc, argv, progname);
|
||||
|
||||
if (process_arguments(argc, argv) == ERROR)
|
||||
check_ping_config_wrapper tmp_config = process_arguments(argc, argv);
|
||||
if (tmp_config.errorcode == ERROR) {
|
||||
usage4(_("Could not parse arguments"));
|
||||
}
|
||||
|
||||
const check_ping_config config = tmp_config.config;
|
||||
|
||||
/* Set signal handling and alarm */
|
||||
if (signal(SIGALRM, popen_timeout_alarm_handler) == SIG_ERR) {
|
||||
|
|
@ -105,71 +96,86 @@ int main(int argc, char **argv) {
|
|||
alarm(timeout_interval);
|
||||
#endif
|
||||
|
||||
for (i = 0; i < n_addresses; i++) {
|
||||
|
||||
int result = STATE_UNKNOWN;
|
||||
char *rawcmd = NULL;
|
||||
for (size_t i = 0; i < config.n_addresses; i++) {
|
||||
#ifdef PING6_COMMAND
|
||||
if (address_family != AF_INET && is_inet6_addr(addresses[i]))
|
||||
if (address_family != AF_INET && is_inet6_addr(config.addresses[i])) {
|
||||
rawcmd = strdup(PING6_COMMAND);
|
||||
else
|
||||
} else {
|
||||
rawcmd = strdup(PING_COMMAND);
|
||||
}
|
||||
#else
|
||||
rawcmd = strdup(PING_COMMAND);
|
||||
#endif
|
||||
|
||||
/* does the host address of number of packets argument come first? */
|
||||
char *cmd = NULL;
|
||||
|
||||
/* does the host address of number of packets argument come first? */
|
||||
#ifdef PING_PACKETS_FIRST
|
||||
# ifdef PING_HAS_TIMEOUT
|
||||
xasprintf(&cmd, rawcmd, timeout_interval, max_packets, addresses[i]);
|
||||
xasprintf(&cmd, rawcmd, timeout_interval, config.max_packets, config.addresses[i]);
|
||||
# else
|
||||
xasprintf(&cmd, rawcmd, max_packets, addresses[i]);
|
||||
xasprintf(&cmd, rawcmd, config.max_packets, addresses[i]);
|
||||
# endif
|
||||
#else
|
||||
xasprintf(&cmd, rawcmd, addresses[i], max_packets);
|
||||
xasprintf(&cmd, rawcmd, addresses[i], config.max_packets);
|
||||
#endif
|
||||
|
||||
if (verbose >= 2)
|
||||
if (verbose >= 2) {
|
||||
printf("CMD: %s\n", cmd);
|
||||
}
|
||||
|
||||
/* run the command */
|
||||
this_result = run_ping(cmd, addresses[i]);
|
||||
|
||||
if (pl == UNKNOWN_PACKET_LOSS || rta < 0.0) {
|
||||
ping_result pinged = run_ping(cmd, config.addresses[i], config.crta);
|
||||
|
||||
if (pinged.packet_loss == UNKNOWN_PACKET_LOSS || pinged.round_trip_average < 0.0) {
|
||||
printf("%s\n", cmd);
|
||||
die(STATE_UNKNOWN, _("CRITICAL - Could not interpret output from ping command\n"));
|
||||
}
|
||||
|
||||
if (pl >= cpl || rta >= crta || rta < 0)
|
||||
this_result = STATE_CRITICAL;
|
||||
else if (pl >= wpl || rta >= wrta)
|
||||
this_result = STATE_WARNING;
|
||||
else if (pl >= 0 && rta >= 0)
|
||||
this_result = max_state(STATE_OK, this_result);
|
||||
if (pinged.packet_loss >= config.cpl || pinged.round_trip_average >= config.crta || pinged.round_trip_average < 0) {
|
||||
pinged.state = STATE_CRITICAL;
|
||||
} else if (pinged.packet_loss >= config.wpl || pinged.round_trip_average >= config.wrta) {
|
||||
pinged.state = STATE_WARNING;
|
||||
} else if (pinged.packet_loss >= 0 && pinged.round_trip_average >= 0) {
|
||||
pinged.state = max_state(STATE_OK, pinged.state);
|
||||
}
|
||||
|
||||
if (n_addresses > 1 && this_result != STATE_UNKNOWN)
|
||||
die(STATE_OK, "%s is alive\n", addresses[i]);
|
||||
if (config.n_addresses > 1 && pinged.state != STATE_UNKNOWN) {
|
||||
die(STATE_OK, "%s is alive\n", config.addresses[i]);
|
||||
}
|
||||
|
||||
if (display_html == true)
|
||||
printf("<A HREF='%s/traceroute.cgi?%s'>", CGIURL, addresses[i]);
|
||||
if (pl == 100)
|
||||
printf(_("PING %s - %sPacket loss = %d%%"), state_text(this_result), warn_text, pl);
|
||||
else
|
||||
printf(_("PING %s - %sPacket loss = %d%%, RTA = %2.2f ms"), state_text(this_result), warn_text, pl, rta);
|
||||
if (display_html == true)
|
||||
if (config.display_html) {
|
||||
printf("<A HREF='%s/traceroute.cgi?%s'>", CGIURL, config.addresses[i]);
|
||||
}
|
||||
if (pinged.packet_loss == 100) {
|
||||
printf(_("PING %s - %sPacket loss = %d%%"), state_text(pinged.state), warn_text, pinged.packet_loss);
|
||||
} else {
|
||||
printf(_("PING %s - %sPacket loss = %d%%, RTA = %2.2f ms"), state_text(pinged.state), warn_text, pinged.packet_loss,
|
||||
pinged.round_trip_average);
|
||||
}
|
||||
if (config.display_html) {
|
||||
printf("</A>");
|
||||
}
|
||||
|
||||
/* Print performance data */
|
||||
if (pl != 100) {
|
||||
printf("|%s",
|
||||
fperfdata("rta", (double)rta, "ms", wrta > 0 ? true : false, wrta, crta > 0 ? true : false, crta, true, 0, false, 0));
|
||||
if (pinged.packet_loss != 100) {
|
||||
printf("|%s", fperfdata("rta", pinged.round_trip_average, "ms", (bool)(config.wrta > 0), config.wrta, (bool)(config.crta > 0),
|
||||
config.crta, true, 0, false, 0));
|
||||
} else {
|
||||
printf("| rta=U;%f;%f;;", wrta, crta);
|
||||
printf("| rta=U;%f;%f;;", config.wrta, config.crta);
|
||||
}
|
||||
printf(" %s\n", perfdata("pl", (long)pl, "%", wpl > 0 ? true : false, wpl, cpl > 0 ? true : false, cpl, true, 0, false, 0));
|
||||
|
||||
if (verbose >= 2)
|
||||
printf("%f:%d%% %f:%d%%\n", wrta, wpl, crta, cpl);
|
||||
printf(" %s\n", perfdata("pl", (long)pinged.packet_loss, "%", (bool)(config.wpl > 0), config.wpl, (bool)(config.cpl > 0),
|
||||
config.cpl, true, 0, false, 0));
|
||||
|
||||
result = max_state(result, this_result);
|
||||
if (verbose >= 2) {
|
||||
printf("%f:%d%% %f:%d%%\n", config.wrta, config.wpl, config.crta, config.cpl);
|
||||
}
|
||||
|
||||
result = max_state(result, pinged.state);
|
||||
free(rawcmd);
|
||||
free(cmd);
|
||||
}
|
||||
|
|
@ -178,11 +184,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
/* process command-line arguments */
|
||||
int process_arguments(int argc, char **argv) {
|
||||
int c = 1;
|
||||
char *ptr;
|
||||
|
||||
int option = 0;
|
||||
check_ping_config_wrapper process_arguments(int argc, char **argv) {
|
||||
static struct option longopts[] = {STD_LONG_OPTS,
|
||||
{"packets", required_argument, 0, 'p'},
|
||||
{"nohtml", no_argument, 0, 'n'},
|
||||
|
|
@ -191,23 +193,35 @@ int process_arguments(int argc, char **argv) {
|
|||
{"use-ipv6", no_argument, 0, '6'},
|
||||
{0, 0, 0, 0}};
|
||||
|
||||
if (argc < 2)
|
||||
return ERROR;
|
||||
check_ping_config_wrapper result = {
|
||||
.errorcode = OK,
|
||||
.config = check_ping_config_init(),
|
||||
};
|
||||
|
||||
for (c = 1; c < argc; c++) {
|
||||
if (strcmp("-to", argv[c]) == 0)
|
||||
strcpy(argv[c], "-t");
|
||||
if (strcmp("-nohtml", argv[c]) == 0)
|
||||
strcpy(argv[c], "-n");
|
||||
if (argc < 2) {
|
||||
result.errorcode = ERROR;
|
||||
return result;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
c = getopt_long(argc, argv, "VvhnL46t:c:w:H:p:", longopts, &option);
|
||||
for (int index = 1; index < argc; index++) {
|
||||
if (strcmp("-to", argv[index]) == 0) {
|
||||
strcpy(argv[index], "-t");
|
||||
}
|
||||
if (strcmp("-nohtml", argv[index]) == 0) {
|
||||
strcpy(argv[index], "-n");
|
||||
}
|
||||
}
|
||||
|
||||
if (c == -1 || c == EOF)
|
||||
int option = 0;
|
||||
size_t max_addr = MAX_ADDR_START;
|
||||
while (true) {
|
||||
int option_index = getopt_long(argc, argv, "VvhnL46t:c:w:H:p:", longopts, &option);
|
||||
|
||||
if (option_index == -1 || option_index == EOF) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (c) {
|
||||
switch (option_index) {
|
||||
case '?': /* usage */
|
||||
usage5();
|
||||
case 'h': /* help */
|
||||
|
|
@ -234,17 +248,18 @@ int process_arguments(int argc, char **argv) {
|
|||
usage(_("IPv6 support not available\n"));
|
||||
#endif
|
||||
break;
|
||||
case 'H': /* hostname */
|
||||
ptr = optarg;
|
||||
while (1) {
|
||||
n_addresses++;
|
||||
if (n_addresses > max_addr) {
|
||||
case 'H': /* hostname */ {
|
||||
char *ptr = optarg;
|
||||
while (true) {
|
||||
result.config.n_addresses++;
|
||||
if (result.config.n_addresses > max_addr) {
|
||||
max_addr *= 2;
|
||||
addresses = realloc(addresses, sizeof(char *) * max_addr);
|
||||
if (addresses == NULL)
|
||||
result.config.addresses = realloc(result.config.addresses, sizeof(char *) * max_addr);
|
||||
if (result.config.addresses == NULL) {
|
||||
die(STATE_UNKNOWN, _("Could not realloc() addresses\n"));
|
||||
}
|
||||
}
|
||||
addresses[n_addresses - 1] = ptr;
|
||||
result.config.addresses[result.config.n_addresses - 1] = ptr;
|
||||
if ((ptr = index(ptr, ','))) {
|
||||
strcpy(ptr, "");
|
||||
ptr += sizeof(char);
|
||||
|
|
@ -252,203 +267,248 @@ int process_arguments(int argc, char **argv) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
case 'p': /* number of packets to send */
|
||||
if (is_intnonneg(optarg))
|
||||
max_packets = atoi(optarg);
|
||||
else
|
||||
if (is_intnonneg(optarg)) {
|
||||
result.config.max_packets = atoi(optarg);
|
||||
} else {
|
||||
usage2(_("<max_packets> (%s) must be a non-negative number\n"), optarg);
|
||||
}
|
||||
break;
|
||||
case 'n': /* no HTML */
|
||||
display_html = false;
|
||||
result.config.display_html = false;
|
||||
break;
|
||||
case 'L': /* show HTML */
|
||||
display_html = true;
|
||||
result.config.display_html = true;
|
||||
break;
|
||||
case 'c':
|
||||
get_threshold(optarg, &crta, &cpl);
|
||||
get_threshold(optarg, &result.config.crta, &result.config.cpl);
|
||||
break;
|
||||
case 'w':
|
||||
get_threshold(optarg, &wrta, &wpl);
|
||||
get_threshold(optarg, &result.config.wrta, &result.config.wpl);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
c = optind;
|
||||
if (c == argc)
|
||||
return validate_arguments();
|
||||
int arg_counter = optind;
|
||||
if (arg_counter == argc) {
|
||||
return validate_arguments(result);
|
||||
}
|
||||
|
||||
if (addresses[0] == NULL) {
|
||||
if (!is_host(argv[c])) {
|
||||
usage2(_("Invalid hostname/address"), argv[c]);
|
||||
if (result.config.addresses[0] == NULL) {
|
||||
if (!is_host(argv[arg_counter])) {
|
||||
usage2(_("Invalid hostname/address"), argv[arg_counter]);
|
||||
} else {
|
||||
addresses[0] = argv[c++];
|
||||
n_addresses++;
|
||||
if (c == argc)
|
||||
return validate_arguments();
|
||||
result.config.addresses[0] = argv[arg_counter++];
|
||||
result.config.n_addresses++;
|
||||
if (arg_counter == argc) {
|
||||
return validate_arguments(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (wpl == UNKNOWN_PACKET_LOSS) {
|
||||
if (!is_intpercent(argv[c])) {
|
||||
printf(_("<wpl> (%s) must be an integer percentage\n"), argv[c]);
|
||||
return ERROR;
|
||||
} else {
|
||||
wpl = atoi(argv[c++]);
|
||||
if (c == argc)
|
||||
return validate_arguments();
|
||||
if (result.config.wpl == UNKNOWN_PACKET_LOSS) {
|
||||
if (!is_intpercent(argv[arg_counter])) {
|
||||
printf(_("<wpl> (%s) must be an integer percentage\n"), argv[arg_counter]);
|
||||
result.errorcode = ERROR;
|
||||
return result;
|
||||
}
|
||||
result.config.wpl = atoi(argv[arg_counter++]);
|
||||
if (arg_counter == argc) {
|
||||
return validate_arguments(result);
|
||||
}
|
||||
}
|
||||
|
||||
if (cpl == UNKNOWN_PACKET_LOSS) {
|
||||
if (!is_intpercent(argv[c])) {
|
||||
printf(_("<cpl> (%s) must be an integer percentage\n"), argv[c]);
|
||||
return ERROR;
|
||||
} else {
|
||||
cpl = atoi(argv[c++]);
|
||||
if (c == argc)
|
||||
return validate_arguments();
|
||||
if (result.config.cpl == UNKNOWN_PACKET_LOSS) {
|
||||
if (!is_intpercent(argv[arg_counter])) {
|
||||
printf(_("<cpl> (%s) must be an integer percentage\n"), argv[arg_counter]);
|
||||
result.errorcode = ERROR;
|
||||
return result;
|
||||
}
|
||||
result.config.cpl = atoi(argv[arg_counter++]);
|
||||
if (arg_counter == argc) {
|
||||
return validate_arguments(result);
|
||||
}
|
||||
}
|
||||
|
||||
if (wrta < 0.0) {
|
||||
if (is_negative(argv[c])) {
|
||||
printf(_("<wrta> (%s) must be a non-negative number\n"), argv[c]);
|
||||
return ERROR;
|
||||
} else {
|
||||
wrta = atof(argv[c++]);
|
||||
if (c == argc)
|
||||
return validate_arguments();
|
||||
if (result.config.wrta < 0.0) {
|
||||
if (is_negative(argv[arg_counter])) {
|
||||
printf(_("<wrta> (%s) must be a non-negative number\n"), argv[arg_counter]);
|
||||
result.errorcode = ERROR;
|
||||
return result;
|
||||
}
|
||||
result.config.wrta = atof(argv[arg_counter++]);
|
||||
if (arg_counter == argc) {
|
||||
return validate_arguments(result);
|
||||
}
|
||||
}
|
||||
|
||||
if (crta < 0.0) {
|
||||
if (is_negative(argv[c])) {
|
||||
printf(_("<crta> (%s) must be a non-negative number\n"), argv[c]);
|
||||
return ERROR;
|
||||
} else {
|
||||
crta = atof(argv[c++]);
|
||||
if (c == argc)
|
||||
return validate_arguments();
|
||||
if (result.config.crta < 0.0) {
|
||||
if (is_negative(argv[arg_counter])) {
|
||||
printf(_("<crta> (%s) must be a non-negative number\n"), argv[arg_counter]);
|
||||
result.errorcode = ERROR;
|
||||
return result;
|
||||
}
|
||||
result.config.crta = atof(argv[arg_counter++]);
|
||||
if (arg_counter == argc) {
|
||||
return validate_arguments(result);
|
||||
}
|
||||
}
|
||||
|
||||
if (max_packets == -1) {
|
||||
if (is_intnonneg(argv[c])) {
|
||||
max_packets = atoi(argv[c++]);
|
||||
if (result.config.max_packets == -1) {
|
||||
if (is_intnonneg(argv[arg_counter])) {
|
||||
result.config.max_packets = atoi(argv[arg_counter++]);
|
||||
} else {
|
||||
printf(_("<max_packets> (%s) must be a non-negative number\n"), argv[c]);
|
||||
return ERROR;
|
||||
printf(_("<max_packets> (%s) must be a non-negative number\n"), argv[arg_counter]);
|
||||
result.errorcode = ERROR;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return validate_arguments();
|
||||
return validate_arguments(result);
|
||||
}
|
||||
|
||||
int get_threshold(char *arg, float *trta, int *tpl) {
|
||||
if (is_intnonneg(arg) && sscanf(arg, "%f", trta) == 1)
|
||||
int get_threshold(char *arg, double *trta, int *tpl) {
|
||||
if (is_intnonneg(arg) && sscanf(arg, "%lf", trta) == 1) {
|
||||
return OK;
|
||||
else if (strpbrk(arg, ",:") && strstr(arg, "%") && sscanf(arg, "%f%*[:,]%d%%", trta, tpl) == 2)
|
||||
}
|
||||
|
||||
if (strpbrk(arg, ",:") && strstr(arg, "%") && sscanf(arg, "%lf%*[:,]%d%%", trta, tpl) == 2) {
|
||||
return OK;
|
||||
else if (strstr(arg, "%") && sscanf(arg, "%d%%", tpl) == 1)
|
||||
}
|
||||
|
||||
if (strstr(arg, "%") && sscanf(arg, "%d%%", tpl) == 1) {
|
||||
return OK;
|
||||
}
|
||||
|
||||
usage2(_("%s: Warning threshold must be integer or percentage!\n\n"), arg);
|
||||
return STATE_UNKNOWN;
|
||||
}
|
||||
|
||||
int validate_arguments() {
|
||||
float max_seconds;
|
||||
int i;
|
||||
|
||||
if (wrta < 0.0) {
|
||||
check_ping_config_wrapper validate_arguments(check_ping_config_wrapper config_wrapper) {
|
||||
if (config_wrapper.config.wrta < 0.0) {
|
||||
printf(_("<wrta> was not set\n"));
|
||||
return ERROR;
|
||||
} else if (crta < 0.0) {
|
||||
config_wrapper.errorcode = ERROR;
|
||||
return config_wrapper;
|
||||
}
|
||||
|
||||
if (config_wrapper.config.crta < 0.0) {
|
||||
printf(_("<crta> was not set\n"));
|
||||
return ERROR;
|
||||
} else if (wpl == UNKNOWN_PACKET_LOSS) {
|
||||
config_wrapper.errorcode = ERROR;
|
||||
return config_wrapper;
|
||||
}
|
||||
|
||||
if (config_wrapper.config.wpl == UNKNOWN_PACKET_LOSS) {
|
||||
printf(_("<wpl> was not set\n"));
|
||||
return ERROR;
|
||||
} else if (cpl == UNKNOWN_PACKET_LOSS) {
|
||||
config_wrapper.errorcode = ERROR;
|
||||
return config_wrapper;
|
||||
}
|
||||
|
||||
if (config_wrapper.config.cpl == UNKNOWN_PACKET_LOSS) {
|
||||
printf(_("<cpl> was not set\n"));
|
||||
return ERROR;
|
||||
} else if (wrta > crta) {
|
||||
printf(_("<wrta> (%f) cannot be larger than <crta> (%f)\n"), wrta, crta);
|
||||
return ERROR;
|
||||
} else if (wpl > cpl) {
|
||||
printf(_("<wpl> (%d) cannot be larger than <cpl> (%d)\n"), wpl, cpl);
|
||||
return ERROR;
|
||||
config_wrapper.errorcode = ERROR;
|
||||
return config_wrapper;
|
||||
}
|
||||
|
||||
if (max_packets == -1)
|
||||
max_packets = DEFAULT_MAX_PACKETS;
|
||||
|
||||
max_seconds = crta / 1000.0 * max_packets + max_packets;
|
||||
if (max_seconds > timeout_interval)
|
||||
timeout_interval = (int)max_seconds;
|
||||
|
||||
for (i = 0; i < n_addresses; i++) {
|
||||
if (!is_host(addresses[i]))
|
||||
usage2(_("Invalid hostname/address"), addresses[i]);
|
||||
if (config_wrapper.config.wrta > config_wrapper.config.crta) {
|
||||
printf(_("<wrta> (%f) cannot be larger than <crta> (%f)\n"), config_wrapper.config.wrta, config_wrapper.config.crta);
|
||||
config_wrapper.errorcode = ERROR;
|
||||
return config_wrapper;
|
||||
}
|
||||
|
||||
if (n_addresses == 0) {
|
||||
if (config_wrapper.config.wpl > config_wrapper.config.cpl) {
|
||||
printf(_("<wpl> (%d) cannot be larger than <cpl> (%d)\n"), config_wrapper.config.wpl, config_wrapper.config.cpl);
|
||||
config_wrapper.errorcode = ERROR;
|
||||
return config_wrapper;
|
||||
}
|
||||
|
||||
if (config_wrapper.config.max_packets == -1) {
|
||||
config_wrapper.config.max_packets = DEFAULT_MAX_PACKETS;
|
||||
}
|
||||
|
||||
double max_seconds = (config_wrapper.config.crta / 1000.0 * config_wrapper.config.max_packets) + config_wrapper.config.max_packets;
|
||||
if (max_seconds > timeout_interval) {
|
||||
timeout_interval = (unsigned int)max_seconds;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < config_wrapper.config.n_addresses; i++) {
|
||||
if (!is_host(config_wrapper.config.addresses[i])) {
|
||||
usage2(_("Invalid hostname/address"), config_wrapper.config.addresses[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (config_wrapper.config.n_addresses == 0) {
|
||||
usage(_("You must specify a server address or host name"));
|
||||
}
|
||||
|
||||
return OK;
|
||||
return config_wrapper;
|
||||
}
|
||||
|
||||
int run_ping(const char *cmd, const char *addr) {
|
||||
char buf[MAX_INPUT_BUFFER];
|
||||
int result = STATE_UNKNOWN;
|
||||
int match;
|
||||
|
||||
if ((child_process = spopen(cmd)) == NULL)
|
||||
ping_result run_ping(const char *cmd, const char *addr, double crta) {
|
||||
if ((child_process = spopen(cmd)) == NULL) {
|
||||
die(STATE_UNKNOWN, _("Could not open pipe: %s\n"), cmd);
|
||||
}
|
||||
|
||||
child_stderr = fdopen(child_stderr_array[fileno(child_process)], "r");
|
||||
if (child_stderr == NULL)
|
||||
if (child_stderr == NULL) {
|
||||
printf(_("Cannot open stderr for %s\n"), cmd);
|
||||
}
|
||||
|
||||
char buf[MAX_INPUT_BUFFER];
|
||||
ping_result result = {
|
||||
.state = STATE_UNKNOWN,
|
||||
.packet_loss = UNKNOWN_PACKET_LOSS,
|
||||
.round_trip_average = UNKNOWN_TRIP_TIME,
|
||||
};
|
||||
|
||||
while (fgets(buf, MAX_INPUT_BUFFER - 1, child_process)) {
|
||||
|
||||
if (verbose >= 3)
|
||||
if (verbose >= 3) {
|
||||
printf("Output: %s", buf);
|
||||
}
|
||||
|
||||
result = max_state(result, error_scan(buf, addr));
|
||||
result.state = max_state(result.state, error_scan(buf, addr));
|
||||
|
||||
/* get the percent loss statistics */
|
||||
match = 0;
|
||||
if ((sscanf(buf, "%*d packets transmitted, %*d packets received, +%*d errors, %d%% packet loss%n", &pl, &match) && match) ||
|
||||
(sscanf(buf, "%*d packets transmitted, %*d packets received, +%*d duplicates, %d%% packet loss%n", &pl, &match) && match) ||
|
||||
(sscanf(buf, "%*d packets transmitted, %*d received, +%*d duplicates, %d%% packet loss%n", &pl, &match) && match) ||
|
||||
(sscanf(buf, "%*d packets transmitted, %*d packets received, %d%% packet loss%n", &pl, &match) && match) ||
|
||||
(sscanf(buf, "%*d packets transmitted, %*d packets received, %d%% loss, time%n", &pl, &match) && match) ||
|
||||
(sscanf(buf, "%*d packets transmitted, %*d received, %d%% loss, time%n", &pl, &match) && match) ||
|
||||
(sscanf(buf, "%*d packets transmitted, %*d received, %d%% packet loss, time%n", &pl, &match) && match) ||
|
||||
(sscanf(buf, "%*d packets transmitted, %*d received, +%*d errors, %d%% packet loss%n", &pl, &match) && match) ||
|
||||
(sscanf(buf, "%*d packets transmitted %*d received, +%*d errors, %d%% packet loss%n", &pl, &match) && match) ||
|
||||
(sscanf(buf, "%*[^(](%d%% %*[^)])%n", &pl, &match) && match))
|
||||
int match = 0;
|
||||
if ((sscanf(buf, "%*d packets transmitted, %*d packets received, +%*d errors, %d%% packet loss%n", &result.packet_loss, &match) ==
|
||||
1 &&
|
||||
match) ||
|
||||
(sscanf(buf, "%*d packets transmitted, %*d packets received, +%*d duplicates, %d%% packet loss%n", &result.packet_loss,
|
||||
&match) == 1 &&
|
||||
match) ||
|
||||
(sscanf(buf, "%*d packets transmitted, %*d received, +%*d duplicates, %d%% packet loss%n", &result.packet_loss, &match) == 1 &&
|
||||
match) ||
|
||||
(sscanf(buf, "%*d packets transmitted, %*d packets received, %d%% packet loss%n", &result.packet_loss, &match) == 1 && match) ||
|
||||
(sscanf(buf, "%*d packets transmitted, %*d packets received, %d%% loss, time%n", &result.packet_loss, &match) == 1 && match) ||
|
||||
(sscanf(buf, "%*d packets transmitted, %*d received, %d%% loss, time%n", &result.packet_loss, &match) == 1 && match) ||
|
||||
(sscanf(buf, "%*d packets transmitted, %*d received, %d%% packet loss, time%n", &result.packet_loss, &match) == 1 && match) ==
|
||||
1 ||
|
||||
(sscanf(buf, "%*d packets transmitted, %*d received, +%*d errors, %d%% packet loss%n", &result.packet_loss, &match) == 1 &&
|
||||
match) ||
|
||||
(sscanf(buf, "%*d packets transmitted %*d received, +%*d errors, %d%% packet loss%n", &result.packet_loss, &match) == 1 &&
|
||||
match) ||
|
||||
(sscanf(buf, "%*[^(](%d%% %*[^)])%n", &result.packet_loss, &match) == 1 && match)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* get the round trip average */
|
||||
else if ((sscanf(buf, "round-trip min/avg/max = %*f/%f/%*f%n", &rta, &match) && match) ||
|
||||
(sscanf(buf, "round-trip min/avg/max/mdev = %*f/%f/%*f/%*f%n", &rta, &match) && match) ||
|
||||
(sscanf(buf, "round-trip min/avg/max/sdev = %*f/%f/%*f/%*f%n", &rta, &match) && match) ||
|
||||
(sscanf(buf, "round-trip min/avg/max/stddev = %*f/%f/%*f/%*f%n", &rta, &match) && match) ||
|
||||
(sscanf(buf, "round-trip min/avg/max/std-dev = %*f/%f/%*f/%*f%n", &rta, &match) && match) ||
|
||||
(sscanf(buf, "round-trip (ms) min/avg/max = %*f/%f/%*f%n", &rta, &match) && match) ||
|
||||
(sscanf(buf, "round-trip (ms) min/avg/max/stddev = %*f/%f/%*f/%*f%n", &rta, &match) && match) ||
|
||||
(sscanf(buf, "rtt min/avg/max/mdev = %*f/%f/%*f/%*f ms%n", &rta, &match) && match) ||
|
||||
(sscanf(buf, "%*[^=] = %*fms, %*[^=] = %*fms, %*[^=] = %fms%n", &rta, &match) && match))
|
||||
if ((sscanf(buf, "round-trip min/avg/max = %*f/%lf/%*f%n", &result.round_trip_average, &match) == 1 && match) ||
|
||||
(sscanf(buf, "round-trip min/avg/max/mdev = %*f/%lf/%*f/%*f%n", &result.round_trip_average, &match) == 1 && match) ||
|
||||
(sscanf(buf, "round-trip min/avg/max/sdev = %*f/%lf/%*f/%*f%n", &result.round_trip_average, &match) == 1 && match) ||
|
||||
(sscanf(buf, "round-trip min/avg/max/stddev = %*f/%lf/%*f/%*f%n", &result.round_trip_average, &match) == 1 && match) ||
|
||||
(sscanf(buf, "round-trip min/avg/max/std-dev = %*f/%lf/%*f/%*f%n", &result.round_trip_average, &match) == 1 && match) ||
|
||||
(sscanf(buf, "round-trip (ms) min/avg/max = %*f/%lf/%*f%n", &result.round_trip_average, &match) == 1 && match) ||
|
||||
(sscanf(buf, "round-trip (ms) min/avg/max/stddev = %*f/%lf/%*f/%*f%n", &result.round_trip_average, &match) == 1 && match) ||
|
||||
(sscanf(buf, "rtt min/avg/max/mdev = %*f/%lf/%*f/%*f ms%n", &result.round_trip_average, &match) == 1 && match) ||
|
||||
(sscanf(buf, "%*[^=] = %*fms, %*[^=] = %*fms, %*[^=] = %lfms%n", &result.round_trip_average, &match) == 1 && match)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* this is needed because there is no rta if all packets are lost */
|
||||
if (pl == 100)
|
||||
rta = crta;
|
||||
if (result.packet_loss == 100) {
|
||||
result.round_trip_average = crta;
|
||||
}
|
||||
|
||||
/* check stderr, setting at least WARNING if there is output here */
|
||||
/* Add warning into warn_text */
|
||||
|
|
@ -459,8 +519,8 @@ int run_ping(const char *cmd, const char *addr) {
|
|||
if (verbose >= 3) {
|
||||
printf("Got stderr: %s", buf);
|
||||
}
|
||||
if ((result = error_scan(buf, addr)) == STATE_OK) {
|
||||
result = STATE_WARNING;
|
||||
if ((result.state = error_scan(buf, addr)) == STATE_OK) {
|
||||
result.state = STATE_WARNING;
|
||||
if (warn_text == NULL) {
|
||||
warn_text = strdup(_("System call sent warnings to stderr "));
|
||||
} else {
|
||||
|
|
@ -474,43 +534,46 @@ int run_ping(const char *cmd, const char *addr) {
|
|||
|
||||
spclose(child_process);
|
||||
|
||||
if (warn_text == NULL)
|
||||
if (warn_text == NULL) {
|
||||
warn_text = strdup("");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int error_scan(char buf[MAX_INPUT_BUFFER], const char *addr) {
|
||||
if (strstr(buf, "Network is unreachable") || strstr(buf, "Destination Net Unreachable") || strstr(buf, "No route"))
|
||||
mp_state_enum error_scan(char buf[MAX_INPUT_BUFFER], const char *addr) {
|
||||
if (strstr(buf, "Network is unreachable") || strstr(buf, "Destination Net Unreachable") || strstr(buf, "No route")) {
|
||||
die(STATE_CRITICAL, _("CRITICAL - Network Unreachable (%s)\n"), addr);
|
||||
else if (strstr(buf, "Destination Host Unreachable") || strstr(buf, "Address unreachable"))
|
||||
} else if (strstr(buf, "Destination Host Unreachable") || strstr(buf, "Address unreachable")) {
|
||||
die(STATE_CRITICAL, _("CRITICAL - Host Unreachable (%s)\n"), addr);
|
||||
else if (strstr(buf, "Destination Port Unreachable") || strstr(buf, "Port unreachable"))
|
||||
} else if (strstr(buf, "Destination Port Unreachable") || strstr(buf, "Port unreachable")) {
|
||||
die(STATE_CRITICAL, _("CRITICAL - Bogus ICMP: Port Unreachable (%s)\n"), addr);
|
||||
else if (strstr(buf, "Destination Protocol Unreachable"))
|
||||
} else if (strstr(buf, "Destination Protocol Unreachable")) {
|
||||
die(STATE_CRITICAL, _("CRITICAL - Bogus ICMP: Protocol Unreachable (%s)\n"), addr);
|
||||
else if (strstr(buf, "Destination Net Prohibited"))
|
||||
} else if (strstr(buf, "Destination Net Prohibited")) {
|
||||
die(STATE_CRITICAL, _("CRITICAL - Network Prohibited (%s)\n"), addr);
|
||||
else if (strstr(buf, "Destination Host Prohibited"))
|
||||
} else if (strstr(buf, "Destination Host Prohibited")) {
|
||||
die(STATE_CRITICAL, _("CRITICAL - Host Prohibited (%s)\n"), addr);
|
||||
else if (strstr(buf, "Packet filtered") || strstr(buf, "Administratively prohibited"))
|
||||
} else if (strstr(buf, "Packet filtered") || strstr(buf, "Administratively prohibited")) {
|
||||
die(STATE_CRITICAL, _("CRITICAL - Packet Filtered (%s)\n"), addr);
|
||||
else if (strstr(buf, "unknown host"))
|
||||
} else if (strstr(buf, "unknown host")) {
|
||||
die(STATE_CRITICAL, _("CRITICAL - Host not found (%s)\n"), addr);
|
||||
else if (strstr(buf, "Time to live exceeded") || strstr(buf, "Time exceeded"))
|
||||
} else if (strstr(buf, "Time to live exceeded") || strstr(buf, "Time exceeded")) {
|
||||
die(STATE_CRITICAL, _("CRITICAL - Time to live exceeded (%s)\n"), addr);
|
||||
else if (strstr(buf, "Destination unreachable: "))
|
||||
} else if (strstr(buf, "Destination unreachable: ")) {
|
||||
die(STATE_CRITICAL, _("CRITICAL - Destination Unreachable (%s)\n"), addr);
|
||||
|
||||
if (strstr(buf, "(DUP!)") || strstr(buf, "DUPLICATES FOUND")) {
|
||||
if (warn_text == NULL)
|
||||
warn_text = strdup(_(WARN_DUPLICATES));
|
||||
else if (!strstr(warn_text, _(WARN_DUPLICATES)) && xasprintf(&warn_text, "%s %s", warn_text, _(WARN_DUPLICATES)) == -1)
|
||||
die(STATE_UNKNOWN, _("Unable to realloc warn_text\n"));
|
||||
return (STATE_WARNING);
|
||||
}
|
||||
|
||||
return (STATE_OK);
|
||||
if (strstr(buf, "(DUP!)") || strstr(buf, "DUPLICATES FOUND")) {
|
||||
if (warn_text == NULL) {
|
||||
warn_text = strdup(_(WARN_DUPLICATES));
|
||||
} else if (!strstr(warn_text, _(WARN_DUPLICATES)) && xasprintf(&warn_text, "%s %s", warn_text, _(WARN_DUPLICATES)) == -1) {
|
||||
die(STATE_UNKNOWN, _("Unable to realloc warn_text\n"));
|
||||
}
|
||||
return STATE_WARNING;
|
||||
}
|
||||
|
||||
return STATE_OK;
|
||||
}
|
||||
|
||||
void print_help(void) {
|
||||
|
|
@ -551,9 +614,7 @@ void print_help(void) {
|
|||
|
||||
printf("\n");
|
||||
printf("%s\n", _("This plugin uses the ping command to probe the specified host for packet loss"));
|
||||
printf("%s\n", _("(percentage) and round trip average (milliseconds). It can produce HTML output"));
|
||||
printf("%s\n", _("linking to a traceroute CGI contributed by Ian Cass. The CGI can be found in"));
|
||||
printf("%s\n", _("the contrib area of the downloads section at http://www.nagios.org/"));
|
||||
printf("%s\n", _("(percentage) and round trip average (milliseconds). It can produce HTML output."));
|
||||
|
||||
printf(UT_SUPPORT);
|
||||
}
|
||||
|
|
|
|||
46
plugins/check_ping.d/config.h
Normal file
46
plugins/check_ping.d/config.h
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../config.h"
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
enum {
|
||||
UNKNOWN_PACKET_LOSS = 200, /* 200% */
|
||||
DEFAULT_MAX_PACKETS = 5 /* default no. of ICMP ECHO packets */
|
||||
};
|
||||
|
||||
#define UNKNOWN_TRIP_TIME -1.0 /* -1 seconds */
|
||||
|
||||
#define MAX_ADDR_START 1
|
||||
|
||||
typedef struct {
|
||||
bool display_html;
|
||||
int max_packets;
|
||||
|
||||
char **addresses;
|
||||
size_t n_addresses;
|
||||
|
||||
int wpl;
|
||||
int cpl;
|
||||
double wrta;
|
||||
double crta;
|
||||
} check_ping_config;
|
||||
|
||||
check_ping_config check_ping_config_init() {
|
||||
check_ping_config tmp = {
|
||||
.display_html = false,
|
||||
.max_packets = -1,
|
||||
|
||||
.addresses = NULL,
|
||||
.n_addresses = 0,
|
||||
|
||||
.wpl = UNKNOWN_PACKET_LOSS,
|
||||
.cpl = UNKNOWN_PACKET_LOSS,
|
||||
.wrta = UNKNOWN_TRIP_TIME,
|
||||
.crta = UNKNOWN_TRIP_TIME,
|
||||
};
|
||||
|
||||
tmp.addresses = calloc(MAX_ADDR_START, sizeof(char *));
|
||||
tmp.addresses[0] = NULL;
|
||||
return tmp;
|
||||
}
|
||||
|
|
@ -1,32 +1,32 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* Monitoring check_radius plugin
|
||||
*
|
||||
* License: GPL
|
||||
* Copyright (c) 1999-2024 Monitoring Plugins Development Team
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* This file contains the check_radius plugin
|
||||
*
|
||||
* Tests to see if a radius server is accepting connections.
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*****************************************************************************/
|
||||
*
|
||||
* Monitoring check_radius plugin
|
||||
*
|
||||
* License: GPL
|
||||
* Copyright (c) 1999-2024 Monitoring Plugins Development Team
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* This file contains the check_radius plugin
|
||||
*
|
||||
* Tests to see if a radius server is accepting connections.
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
const char *progname = "check_radius";
|
||||
const char *copyright = "2000-2024";
|
||||
|
|
@ -35,64 +35,57 @@ const char *email = "devel@monitoring-plugins.org";
|
|||
#include "common.h"
|
||||
#include "utils.h"
|
||||
#include "netutils.h"
|
||||
#include "states.h"
|
||||
#include "check_radius.d/config.h"
|
||||
|
||||
#if defined(HAVE_LIBRADCLI)
|
||||
#include <radcli/radcli.h>
|
||||
# include <radcli/radcli.h>
|
||||
#elif defined(HAVE_LIBFREERADIUS_CLIENT)
|
||||
#include <freeradius-client.h>
|
||||
# include <freeradius-client.h>
|
||||
#elif defined(HAVE_LIBRADIUSCLIENT_NG)
|
||||
#include <radiusclient-ng.h>
|
||||
# include <radiusclient-ng.h>
|
||||
#else
|
||||
#include <radiusclient.h>
|
||||
# include <radiusclient.h>
|
||||
#endif
|
||||
|
||||
static int process_arguments (int /*argc*/, char ** /*argv*/);
|
||||
static void print_help (void);
|
||||
void print_usage (void);
|
||||
typedef struct {
|
||||
int errorcode;
|
||||
check_radius_config config;
|
||||
} check_radius_config_wrapper;
|
||||
static check_radius_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
static void print_help(void);
|
||||
void print_usage(void);
|
||||
|
||||
#if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADIUSCLIENT_NG) || defined(HAVE_LIBRADCLI)
|
||||
#define my_rc_conf_str(a) rc_conf_str(rch,a)
|
||||
#if defined(HAVE_LIBRADCLI)
|
||||
#define my_rc_send_server(a,b) rc_send_server(rch,a,b,AUTH)
|
||||
# define my_rc_conf_str(a) rc_conf_str(rch, a)
|
||||
# if defined(HAVE_LIBRADCLI)
|
||||
# define my_rc_send_server(a, b) rc_send_server(rch, a, b, AUTH)
|
||||
# else
|
||||
# define my_rc_send_server(a, b) rc_send_server(rch, a, b)
|
||||
# endif
|
||||
# if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADCLI)
|
||||
# define my_rc_buildreq(a, b, c, d, e, f) rc_buildreq(rch, a, b, c, d, (a)->secret, e, f)
|
||||
# else
|
||||
# define my_rc_buildreq(a, b, c, d, e, f) rc_buildreq(rch, a, b, c, d, e, f)
|
||||
# endif
|
||||
# define my_rc_avpair_add(a, b, c, d) rc_avpair_add(rch, a, b, c, -1, d)
|
||||
# define my_rc_read_dictionary(a) rc_read_dictionary(rch, a)
|
||||
#else
|
||||
#define my_rc_send_server(a,b) rc_send_server(rch,a,b)
|
||||
#endif
|
||||
#if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADCLI)
|
||||
#define my_rc_buildreq(a,b,c,d,e,f) rc_buildreq(rch,a,b,c,d,(a)->secret,e,f)
|
||||
#else
|
||||
#define my_rc_buildreq(a,b,c,d,e,f) rc_buildreq(rch,a,b,c,d,e,f)
|
||||
#endif
|
||||
#define my_rc_avpair_add(a,b,c,d) rc_avpair_add(rch,a,b,c,-1,d)
|
||||
#define my_rc_read_dictionary(a) rc_read_dictionary(rch, a)
|
||||
#else
|
||||
#define my_rc_conf_str(a) rc_conf_str(a)
|
||||
#define my_rc_send_server(a,b) rc_send_server(a, b)
|
||||
#define my_rc_buildreq(a,b,c,d,e,f) rc_buildreq(a,b,c,d,e,f)
|
||||
#define my_rc_avpair_add(a,b,c,d) rc_avpair_add(a, b, c, d)
|
||||
#define my_rc_read_dictionary(a) rc_read_dictionary(a)
|
||||
# define my_rc_conf_str(a) rc_conf_str(a)
|
||||
# define my_rc_send_server(a, b) rc_send_server(a, b)
|
||||
# define my_rc_buildreq(a, b, c, d, e, f) rc_buildreq(a, b, c, d, e, f)
|
||||
# define my_rc_avpair_add(a, b, c, d) rc_avpair_add(a, b, c, d)
|
||||
# define my_rc_read_dictionary(a) rc_read_dictionary(a)
|
||||
#endif
|
||||
|
||||
/* REJECT_RC is only defined in some version of radiusclient. It has
|
||||
* been reported from radiusclient-ng 0.5.6 on FreeBSD 7.2-RELEASE */
|
||||
#ifndef REJECT_RC
|
||||
#define REJECT_RC BADRESP_RC
|
||||
# define REJECT_RC BADRESP_RC
|
||||
#endif
|
||||
|
||||
static int my_rc_read_config(char * /*a*/);
|
||||
static int my_rc_read_config(char * /*a*/, rc_handle ** /*rch*/);
|
||||
|
||||
#if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADIUSCLIENT_NG) || defined(HAVE_LIBRADCLI)
|
||||
static rc_handle *rch = NULL;
|
||||
#endif
|
||||
|
||||
static char *server = NULL;
|
||||
static char *username = NULL;
|
||||
static char *password = NULL;
|
||||
static char *nasid = NULL;
|
||||
static char *nasipaddress = NULL;
|
||||
static char *expect = NULL;
|
||||
static char *config_file = NULL;
|
||||
static unsigned short port = PW_AUTH_UDP_PORT;
|
||||
static int retries = 1;
|
||||
static bool verbose = false;
|
||||
|
||||
/******************************************************************************
|
||||
|
|
@ -148,149 +141,167 @@ Please note that all tags must be lowercase to use the DocBook XML DTD.
|
|||
-@@
|
||||
******************************************************************************/
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
setlocale(LC_ALL, "");
|
||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
textdomain(PACKAGE);
|
||||
|
||||
/* Parse extra opts if any */
|
||||
argv = np_extra_opts(&argc, argv, progname);
|
||||
|
||||
check_radius_config_wrapper tmp_config = process_arguments(argc, argv);
|
||||
|
||||
if (tmp_config.errorcode == ERROR) {
|
||||
usage4(_("Could not parse arguments"));
|
||||
}
|
||||
|
||||
check_radius_config config = tmp_config.config;
|
||||
|
||||
#if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADIUSCLIENT_NG) || defined(HAVE_LIBRADCLI)
|
||||
rc_handle *rch = NULL;
|
||||
#endif
|
||||
|
||||
char *str = strdup("dictionary");
|
||||
if ((config.config_file && my_rc_read_config(config.config_file, &rch)) || my_rc_read_dictionary(my_rc_conf_str(str))) {
|
||||
die(STATE_UNKNOWN, _("Config file error\n"));
|
||||
}
|
||||
|
||||
uint32_t service = PW_AUTHENTICATE_ONLY;
|
||||
|
||||
SEND_DATA data;
|
||||
memset(&data, 0, sizeof(data));
|
||||
if (!(my_rc_avpair_add(&data.send_pairs, PW_SERVICE_TYPE, &service, 0) &&
|
||||
my_rc_avpair_add(&data.send_pairs, PW_USER_NAME, config.username, 0) &&
|
||||
my_rc_avpair_add(&data.send_pairs, PW_USER_PASSWORD, config.password, 0))) {
|
||||
die(STATE_UNKNOWN, _("Out of Memory?\n"));
|
||||
}
|
||||
|
||||
if (config.nas_id != NULL) {
|
||||
if (!(my_rc_avpair_add(&data.send_pairs, PW_NAS_IDENTIFIER, config.nas_id, 0))) {
|
||||
die(STATE_UNKNOWN, _("Invalid NAS-Identifier\n"));
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
struct sockaddr_storage ss;
|
||||
char name[HOST_NAME_MAX];
|
||||
if (config.nas_ip_address == NULL) {
|
||||
if (gethostname(name, sizeof(name)) != 0) {
|
||||
die(STATE_UNKNOWN, _("gethostname() failed!\n"));
|
||||
}
|
||||
config.nas_ip_address = name;
|
||||
}
|
||||
|
||||
struct sockaddr_storage radius_server_socket;
|
||||
if (!dns_lookup(config.nas_ip_address, &radius_server_socket, AF_UNSPEC)) {
|
||||
die(STATE_UNKNOWN, _("Invalid NAS-IP-Address\n"));
|
||||
}
|
||||
|
||||
uint32_t client_id = ntohl(((struct sockaddr_in *)&radius_server_socket)->sin_addr.s_addr);
|
||||
if (my_rc_avpair_add(&(data.send_pairs), PW_NAS_IP_ADDRESS, &client_id, 0) == NULL) {
|
||||
die(STATE_UNKNOWN, _("Invalid NAS-IP-Address\n"));
|
||||
}
|
||||
|
||||
my_rc_buildreq(&data, PW_ACCESS_REQUEST, config.server, config.port, (int)timeout_interval, config.retries);
|
||||
|
||||
#ifdef RC_BUFFER_LEN
|
||||
char msg[RC_BUFFER_LEN];
|
||||
#else
|
||||
char msg[BUFFER_LEN];
|
||||
#endif
|
||||
SEND_DATA data;
|
||||
int result = STATE_UNKNOWN;
|
||||
uint32_t client_id, service;
|
||||
char *str;
|
||||
|
||||
setlocale (LC_ALL, "");
|
||||
bindtextdomain (PACKAGE, LOCALEDIR);
|
||||
textdomain (PACKAGE);
|
||||
|
||||
/* Parse extra opts if any */
|
||||
argv=np_extra_opts (&argc, argv, progname);
|
||||
|
||||
if (process_arguments (argc, argv) == ERROR)
|
||||
usage4 (_("Could not parse arguments"));
|
||||
|
||||
str = strdup ("dictionary");
|
||||
if ((config_file && my_rc_read_config (config_file)) ||
|
||||
my_rc_read_dictionary (my_rc_conf_str (str)))
|
||||
die (STATE_UNKNOWN, _("Config file error\n"));
|
||||
|
||||
service = PW_AUTHENTICATE_ONLY;
|
||||
|
||||
memset (&data, 0, sizeof(data));
|
||||
if (!(my_rc_avpair_add (&data.send_pairs, PW_SERVICE_TYPE, &service, 0) &&
|
||||
my_rc_avpair_add (&data.send_pairs, PW_USER_NAME, username, 0) &&
|
||||
my_rc_avpair_add (&data.send_pairs, PW_USER_PASSWORD, password, 0)
|
||||
))
|
||||
die (STATE_UNKNOWN, _("Out of Memory?\n"));
|
||||
|
||||
if (nasid != NULL) {
|
||||
if (!(my_rc_avpair_add (&data.send_pairs, PW_NAS_IDENTIFIER, nasid, 0)))
|
||||
die (STATE_UNKNOWN, _("Invalid NAS-Identifier\n"));
|
||||
int result = my_rc_send_server(&data, msg);
|
||||
rc_avpair_free(data.send_pairs);
|
||||
if (data.receive_pairs) {
|
||||
rc_avpair_free(data.receive_pairs);
|
||||
}
|
||||
|
||||
if (nasipaddress == NULL) {
|
||||
if (gethostname (name, sizeof(name)) != 0)
|
||||
die (STATE_UNKNOWN, _("gethostname() failed!\n"));
|
||||
nasipaddress = name;
|
||||
if (result == TIMEOUT_RC) {
|
||||
printf("Timeout\n");
|
||||
exit(STATE_CRITICAL);
|
||||
}
|
||||
if (!dns_lookup (nasipaddress, &ss, AF_INET)) /* TODO: Support IPv6. */
|
||||
die (STATE_UNKNOWN, _("Invalid NAS-IP-Address\n"));
|
||||
client_id = ntohl (((struct sockaddr_in *)&ss)->sin_addr.s_addr);
|
||||
if (my_rc_avpair_add (&(data.send_pairs), PW_NAS_IP_ADDRESS, &client_id, 0) == NULL)
|
||||
die (STATE_UNKNOWN, _("Invalid NAS-IP-Address\n"));
|
||||
|
||||
my_rc_buildreq (&data, PW_ACCESS_REQUEST, server, port, (int)timeout_interval,
|
||||
retries);
|
||||
if (result == ERROR_RC) {
|
||||
printf(_("Auth Error\n"));
|
||||
exit(STATE_CRITICAL);
|
||||
}
|
||||
|
||||
result = my_rc_send_server (&data, msg);
|
||||
rc_avpair_free (data.send_pairs);
|
||||
if (data.receive_pairs)
|
||||
rc_avpair_free (data.receive_pairs);
|
||||
if (result == REJECT_RC) {
|
||||
printf(_("Auth Failed\n"));
|
||||
exit(STATE_WARNING);
|
||||
}
|
||||
|
||||
if (result == BADRESP_RC) {
|
||||
printf(_("Bad Response\n"));
|
||||
exit(STATE_WARNING);
|
||||
}
|
||||
|
||||
if (config.expect && !strstr(msg, config.expect)) {
|
||||
printf("%s\n", msg);
|
||||
exit(STATE_WARNING);
|
||||
}
|
||||
|
||||
if (result == OK_RC) {
|
||||
printf(_("Auth OK\n"));
|
||||
exit(STATE_OK);
|
||||
}
|
||||
|
||||
if (result == TIMEOUT_RC)
|
||||
die (STATE_CRITICAL, _("Timeout\n"));
|
||||
if (result == ERROR_RC)
|
||||
die (STATE_CRITICAL, _("Auth Error\n"));
|
||||
if (result == REJECT_RC)
|
||||
die (STATE_WARNING, _("Auth Failed\n"));
|
||||
if (result == BADRESP_RC)
|
||||
die (STATE_WARNING, _("Bad Response\n"));
|
||||
if (expect && !strstr (msg, expect))
|
||||
die (STATE_WARNING, "%s\n", msg);
|
||||
if (result == OK_RC)
|
||||
die (STATE_OK, _("Auth OK\n"));
|
||||
(void)snprintf(msg, sizeof(msg), _("Unexpected result code %d"), result);
|
||||
die (STATE_UNKNOWN, "%s\n", msg);
|
||||
printf("%s\n", msg);
|
||||
exit(STATE_UNKNOWN);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* process command-line arguments */
|
||||
int
|
||||
process_arguments (int argc, char **argv)
|
||||
{
|
||||
int c;
|
||||
check_radius_config_wrapper process_arguments(int argc, char **argv) {
|
||||
static struct option longopts[] = {{"hostname", required_argument, 0, 'H'}, {"port", required_argument, 0, 'P'},
|
||||
{"username", required_argument, 0, 'u'}, {"password", required_argument, 0, 'p'},
|
||||
{"nas-id", required_argument, 0, 'n'}, {"nas-ip-address", required_argument, 0, 'N'},
|
||||
{"filename", required_argument, 0, 'F'}, {"expect", required_argument, 0, 'e'},
|
||||
{"retries", required_argument, 0, 'r'}, {"timeout", required_argument, 0, 't'},
|
||||
{"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'},
|
||||
{"help", no_argument, 0, 'h'}, {0, 0, 0, 0}};
|
||||
|
||||
int option = 0;
|
||||
static struct option longopts[] = {
|
||||
{"hostname", required_argument, 0, 'H'},
|
||||
{"port", required_argument, 0, 'P'},
|
||||
{"username", required_argument, 0, 'u'},
|
||||
{"password", required_argument, 0, 'p'},
|
||||
{"nas-id", required_argument, 0, 'n'},
|
||||
{"nas-ip-address", required_argument, 0, 'N'},
|
||||
{"filename", required_argument, 0, 'F'},
|
||||
{"expect", required_argument, 0, 'e'},
|
||||
{"retries", required_argument, 0, 'r'},
|
||||
{"timeout", required_argument, 0, 't'},
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
{"version", no_argument, 0, 'V'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{0, 0, 0, 0}
|
||||
check_radius_config_wrapper result = {
|
||||
.errorcode = OK,
|
||||
.config = check_radius_config_init(),
|
||||
};
|
||||
|
||||
while (1) {
|
||||
c = getopt_long (argc, argv, "+hVvH:P:F:u:p:n:N:t:r:e:", longopts,
|
||||
&option);
|
||||
while (true) {
|
||||
int option = 0;
|
||||
int option_index = getopt_long(argc, argv, "+hVvH:P:F:u:p:n:N:t:r:e:", longopts, &option);
|
||||
|
||||
if (c == -1 || c == EOF || c == 1)
|
||||
if (option_index == -1 || option_index == EOF || option_index == 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (c) {
|
||||
case '?': /* print short usage statement if args not parsable */
|
||||
usage5 ();
|
||||
case 'h': /* help */
|
||||
print_help ();
|
||||
exit (STATE_UNKNOWN);
|
||||
case 'V': /* version */
|
||||
print_revision (progname, NP_VERSION);
|
||||
exit (STATE_UNKNOWN);
|
||||
case 'v': /* verbose mode */
|
||||
switch (option_index) {
|
||||
case '?': /* print short usage statement if args not parsable */
|
||||
usage5();
|
||||
case 'h': /* help */
|
||||
print_help();
|
||||
exit(STATE_UNKNOWN);
|
||||
case 'V': /* version */
|
||||
print_revision(progname, NP_VERSION);
|
||||
exit(STATE_UNKNOWN);
|
||||
case 'v': /* verbose mode */
|
||||
verbose = true;
|
||||
break;
|
||||
case 'H': /* hostname */
|
||||
if (!is_host (optarg)) {
|
||||
usage2 (_("Invalid hostname/address"), optarg);
|
||||
case 'H': /* hostname */
|
||||
if (!is_host(optarg)) {
|
||||
usage2(_("Invalid hostname/address"), optarg);
|
||||
}
|
||||
server = optarg;
|
||||
result.config.server = optarg;
|
||||
break;
|
||||
case 'P': /* port */
|
||||
if (is_intnonneg (optarg))
|
||||
port = (unsigned short)atoi (optarg);
|
||||
else
|
||||
usage4 (_("Port must be a positive integer"));
|
||||
case 'P': /* port */
|
||||
if (is_intnonneg(optarg)) {
|
||||
result.config.port = (unsigned short)atoi(optarg);
|
||||
} else {
|
||||
usage4(_("Port must be a positive integer"));
|
||||
}
|
||||
break;
|
||||
case 'u': /* username */
|
||||
username = optarg;
|
||||
case 'u': /* username */
|
||||
result.config.username = optarg;
|
||||
break;
|
||||
case 'p': /* password */
|
||||
password = strdup(optarg);
|
||||
case 'p': /* password */
|
||||
result.config.password = strdup(optarg);
|
||||
|
||||
/* Delete the password from process list */
|
||||
while (*optarg != '\0') {
|
||||
|
|
@ -298,119 +309,115 @@ process_arguments (int argc, char **argv)
|
|||
optarg++;
|
||||
}
|
||||
break;
|
||||
case 'n': /* nas id */
|
||||
nasid = optarg;
|
||||
case 'n': /* nas id */
|
||||
result.config.nas_id = optarg;
|
||||
break;
|
||||
case 'N': /* nas ip address */
|
||||
nasipaddress = optarg;
|
||||
case 'N': /* nas ip address */
|
||||
result.config.nas_ip_address = optarg;
|
||||
break;
|
||||
case 'F': /* configuration file */
|
||||
config_file = optarg;
|
||||
case 'F': /* configuration file */
|
||||
result.config.config_file = optarg;
|
||||
break;
|
||||
case 'e': /* expect */
|
||||
expect = optarg;
|
||||
case 'e': /* expect */
|
||||
result.config.expect = optarg;
|
||||
break;
|
||||
case 'r': /* retries */
|
||||
if (is_intpos (optarg))
|
||||
retries = atoi (optarg);
|
||||
else
|
||||
usage4 (_("Number of retries must be a positive integer"));
|
||||
case 'r': /* retries */
|
||||
if (is_intpos(optarg)) {
|
||||
result.config.retries = atoi(optarg);
|
||||
} else {
|
||||
usage4(_("Number of retries must be a positive integer"));
|
||||
}
|
||||
break;
|
||||
case 't': /* timeout */
|
||||
if (is_intpos (optarg))
|
||||
timeout_interval = (unsigned)atoi (optarg);
|
||||
else
|
||||
usage2 (_("Timeout interval must be a positive integer"), optarg);
|
||||
case 't': /* timeout */
|
||||
if (is_intpos(optarg)) {
|
||||
timeout_interval = (unsigned)atoi(optarg);
|
||||
} else {
|
||||
usage2(_("Timeout interval must be a positive integer"), optarg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (server == NULL)
|
||||
usage4 (_("Hostname was not supplied"));
|
||||
if (username == NULL)
|
||||
usage4 (_("User not specified"));
|
||||
if (password == NULL)
|
||||
usage4 (_("Password not specified"));
|
||||
if (config_file == NULL)
|
||||
usage4 (_("Configuration file not specified"));
|
||||
if (result.config.server == NULL) {
|
||||
usage4(_("Hostname was not supplied"));
|
||||
}
|
||||
if (result.config.username == NULL) {
|
||||
usage4(_("User not specified"));
|
||||
}
|
||||
if (result.config.password == NULL) {
|
||||
usage4(_("Password not specified"));
|
||||
}
|
||||
if (result.config.config_file == NULL) {
|
||||
usage4(_("Configuration file not specified"));
|
||||
}
|
||||
|
||||
return OK;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
print_help (void)
|
||||
{
|
||||
void print_help(void) {
|
||||
char *myport;
|
||||
xasprintf (&myport, "%d", PW_AUTH_UDP_PORT);
|
||||
xasprintf(&myport, "%d", PW_AUTH_UDP_PORT);
|
||||
|
||||
print_revision (progname, NP_VERSION);
|
||||
print_revision(progname, NP_VERSION);
|
||||
|
||||
printf ("Copyright (c) 1999 Robert August Vincent II\n");
|
||||
printf (COPYRIGHT, copyright, email);
|
||||
printf("Copyright (c) 1999 Robert August Vincent II\n");
|
||||
printf(COPYRIGHT, copyright, email);
|
||||
|
||||
printf("%s\n", _("Tests to see if a RADIUS server is accepting connections."));
|
||||
|
||||
printf ("\n\n");
|
||||
printf("\n\n");
|
||||
|
||||
print_usage ();
|
||||
print_usage();
|
||||
|
||||
printf (UT_HELP_VRSN);
|
||||
printf (UT_EXTRA_OPTS);
|
||||
printf(UT_HELP_VRSN);
|
||||
printf(UT_EXTRA_OPTS);
|
||||
|
||||
printf (UT_HOST_PORT, 'P', myport);
|
||||
printf(UT_HOST_PORT, 'P', myport);
|
||||
|
||||
printf (" %s\n", "-u, --username=STRING");
|
||||
printf (" %s\n", _("The user to authenticate"));
|
||||
printf (" %s\n", "-p, --password=STRING");
|
||||
printf (" %s\n", _("Password for authentication (SECURITY RISK)"));
|
||||
printf (" %s\n", "-n, --nas-id=STRING");
|
||||
printf (" %s\n", _("NAS identifier"));
|
||||
printf (" %s\n", "-N, --nas-ip-address=STRING");
|
||||
printf (" %s\n", _("NAS IP Address"));
|
||||
printf (" %s\n", "-F, --filename=STRING");
|
||||
printf (" %s\n", _("Configuration file"));
|
||||
printf (" %s\n", "-e, --expect=STRING");
|
||||
printf (" %s\n", _("Response string to expect from the server"));
|
||||
printf (" %s\n", "-r, --retries=INTEGER");
|
||||
printf (" %s\n", _("Number of times to retry a failed connection"));
|
||||
printf(" %s\n", "-u, --username=STRING");
|
||||
printf(" %s\n", _("The user to authenticate"));
|
||||
printf(" %s\n", "-p, --password=STRING");
|
||||
printf(" %s\n", _("Password for authentication (SECURITY RISK)"));
|
||||
printf(" %s\n", "-n, --nas-id=STRING");
|
||||
printf(" %s\n", _("NAS identifier"));
|
||||
printf(" %s\n", "-N, --nas-ip-address=STRING");
|
||||
printf(" %s\n", _("NAS IP Address"));
|
||||
printf(" %s\n", "-F, --filename=STRING");
|
||||
printf(" %s\n", _("Configuration file"));
|
||||
printf(" %s\n", "-e, --expect=STRING");
|
||||
printf(" %s\n", _("Response string to expect from the server"));
|
||||
printf(" %s\n", "-r, --retries=INTEGER");
|
||||
printf(" %s\n", _("Number of times to retry a failed connection"));
|
||||
|
||||
printf (UT_CONN_TIMEOUT, timeout_interval);
|
||||
printf(UT_CONN_TIMEOUT, timeout_interval);
|
||||
|
||||
printf ("\n");
|
||||
printf ("%s\n", _("This plugin tests a RADIUS server to see if it is accepting connections."));
|
||||
printf ("%s\n", _("The server to test must be specified in the invocation, as well as a user"));
|
||||
printf ("%s\n", _("name and password. A configuration file must be present. The format of"));
|
||||
printf ("%s\n", _("the configuration file is described in the radiusclient library sources."));
|
||||
printf ("%s\n", _("The password option presents a substantial security issue because the"));
|
||||
printf ("%s\n", _("password can possibly be determined by careful watching of the command line"));
|
||||
printf ("%s\n", _("in a process listing. This risk is exacerbated because the plugin will"));
|
||||
printf ("%s\n", _("typically be executed at regular predictable intervals. Please be sure that"));
|
||||
printf ("%s\n", _("the password used does not allow access to sensitive system resources."));
|
||||
printf("\n");
|
||||
printf("%s\n", _("This plugin tests a RADIUS server to see if it is accepting connections."));
|
||||
printf("%s\n", _("The server to test must be specified in the invocation, as well as a user"));
|
||||
printf("%s\n", _("name and password. A configuration file must be present. The format of"));
|
||||
printf("%s\n", _("the configuration file is described in the radiusclient library sources."));
|
||||
printf("%s\n", _("The password option presents a substantial security issue because the"));
|
||||
printf("%s\n", _("password can possibly be determined by careful watching of the command line"));
|
||||
printf("%s\n", _("in a process listing. This risk is exacerbated because the plugin will"));
|
||||
printf("%s\n", _("typically be executed at regular predictable intervals. Please be sure that"));
|
||||
printf("%s\n", _("the password used does not allow access to sensitive system resources."));
|
||||
|
||||
printf (UT_SUPPORT);
|
||||
printf(UT_SUPPORT);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
print_usage (void)
|
||||
{
|
||||
printf ("%s\n", _("Usage:"));
|
||||
printf ("%s -H host -F config_file -u username -p password\n\
|
||||
void print_usage(void) {
|
||||
printf("%s\n", _("Usage:"));
|
||||
printf("%s -H host -F config_file -u username -p password\n\
|
||||
[-P port] [-t timeout] [-r retries] [-e expect]\n\
|
||||
[-n nas-id] [-N nas-ip-addr]\n", progname);
|
||||
[-n nas-id] [-N nas-ip-addr]\n",
|
||||
progname);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int my_rc_read_config(char * a)
|
||||
{
|
||||
int my_rc_read_config(char *config_file_name, rc_handle **rch) {
|
||||
#if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADIUSCLIENT_NG) || defined(HAVE_LIBRADCLI)
|
||||
rch = rc_read_config(a);
|
||||
*rch = rc_read_config(config_file_name);
|
||||
return (rch == NULL) ? 1 : 0;
|
||||
#else
|
||||
return rc_read_config(a);
|
||||
return rc_read_config(config_file_name);
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
42
plugins/check_radius.d/config.h
Normal file
42
plugins/check_radius.d/config.h
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../config.h"
|
||||
#include <stddef.h>
|
||||
#if defined(HAVE_LIBRADCLI)
|
||||
# include <radcli/radcli.h>
|
||||
#elif defined(HAVE_LIBFREERADIUS_CLIENT)
|
||||
# include <freeradius-client.h>
|
||||
#elif defined(HAVE_LIBRADIUSCLIENT_NG)
|
||||
# include <radiusclient-ng.h>
|
||||
#else
|
||||
# include <radiusclient.h>
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
char *server;
|
||||
char *username;
|
||||
char *password;
|
||||
char *config_file;
|
||||
char *nas_id;
|
||||
char *nas_ip_address;
|
||||
int retries;
|
||||
unsigned short port;
|
||||
|
||||
char *expect;
|
||||
} check_radius_config;
|
||||
|
||||
check_radius_config check_radius_config_init() {
|
||||
check_radius_config tmp = {
|
||||
.server = NULL,
|
||||
.username = NULL,
|
||||
.password = NULL,
|
||||
.config_file = NULL,
|
||||
.nas_id = NULL,
|
||||
.nas_ip_address = NULL,
|
||||
.retries = 1,
|
||||
.port = PW_AUTH_UDP_PORT,
|
||||
|
||||
.expect = NULL,
|
||||
};
|
||||
return tmp;
|
||||
}
|
||||
|
|
@ -28,6 +28,8 @@
|
|||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "states.h"
|
||||
#include <stdio.h>
|
||||
const char *progname = "check_real";
|
||||
const char *copyright = "2000-2024";
|
||||
const char *email = "devel@monitoring-plugins.org";
|
||||
|
|
@ -35,27 +37,20 @@ const char *email = "devel@monitoring-plugins.org";
|
|||
#include "common.h"
|
||||
#include "netutils.h"
|
||||
#include "utils.h"
|
||||
|
||||
enum {
|
||||
PORT = 554
|
||||
};
|
||||
#include "check_real.d/config.h"
|
||||
|
||||
#define EXPECT "RTSP/1."
|
||||
#define URL ""
|
||||
|
||||
static int process_arguments(int, char **);
|
||||
typedef struct {
|
||||
int errorcode;
|
||||
check_real_config config;
|
||||
} check_real_config_wrapper;
|
||||
static check_real_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
|
||||
static void print_help(void);
|
||||
void print_usage(void);
|
||||
|
||||
static int server_port = PORT;
|
||||
static char *server_address;
|
||||
static char *host_name;
|
||||
static char *server_url = NULL;
|
||||
static char *server_expect;
|
||||
static int warning_time = 0;
|
||||
static bool check_warning_time = false;
|
||||
static int critical_time = 0;
|
||||
static bool check_critical_time = false;
|
||||
static bool verbose = false;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
|
@ -66,8 +61,12 @@ int main(int argc, char **argv) {
|
|||
/* Parse extra opts if any */
|
||||
argv = np_extra_opts(&argc, argv, progname);
|
||||
|
||||
if (process_arguments(argc, argv) == ERROR)
|
||||
check_real_config_wrapper tmp_config = process_arguments(argc, argv);
|
||||
if (tmp_config.errorcode == ERROR) {
|
||||
usage4(_("Could not parse arguments"));
|
||||
}
|
||||
|
||||
const check_real_config config = tmp_config.config;
|
||||
|
||||
/* initialize alarm signal handling */
|
||||
signal(SIGALRM, socket_timeout_alarm_handler);
|
||||
|
|
@ -78,38 +77,51 @@ int main(int argc, char **argv) {
|
|||
|
||||
/* try to connect to the host at the given port number */
|
||||
int socket;
|
||||
if (my_tcp_connect(server_address, server_port, &socket) != STATE_OK)
|
||||
die(STATE_CRITICAL, _("Unable to connect to %s on port %d\n"), server_address, server_port);
|
||||
if (my_tcp_connect(config.server_address, config.server_port, &socket) != STATE_OK) {
|
||||
die(STATE_CRITICAL, _("Unable to connect to %s on port %d\n"), config.server_address, config.server_port);
|
||||
}
|
||||
|
||||
/* Part I - Server Check */
|
||||
|
||||
/* send the OPTIONS request */
|
||||
char buffer[MAX_INPUT_BUFFER];
|
||||
sprintf(buffer, "OPTIONS rtsp://%s:%d RTSP/1.0\r\n", host_name, server_port);
|
||||
int result = send(socket, buffer, strlen(buffer), 0);
|
||||
sprintf(buffer, "OPTIONS rtsp://%s:%d RTSP/1.0\r\n", config.host_name, config.server_port);
|
||||
ssize_t sent_bytes = send(socket, buffer, strlen(buffer), 0);
|
||||
if (sent_bytes == -1) {
|
||||
die(STATE_CRITICAL, _("Sending options to %s failed\n"), config.host_name);
|
||||
}
|
||||
|
||||
/* send the header sync */
|
||||
sprintf(buffer, "CSeq: 1\r\n");
|
||||
result = send(socket, buffer, strlen(buffer), 0);
|
||||
sent_bytes = send(socket, buffer, strlen(buffer), 0);
|
||||
if (sent_bytes == -1) {
|
||||
die(STATE_CRITICAL, _("Sending header sync to %s failed\n"), config.host_name);
|
||||
}
|
||||
|
||||
/* send a newline so the server knows we're done with the request */
|
||||
sprintf(buffer, "\r\n");
|
||||
result = send(socket, buffer, strlen(buffer), 0);
|
||||
sent_bytes = send(socket, buffer, strlen(buffer), 0);
|
||||
if (sent_bytes == -1) {
|
||||
die(STATE_CRITICAL, _("Sending newline to %s failed\n"), config.host_name);
|
||||
}
|
||||
|
||||
/* watch for the REAL connection string */
|
||||
result = recv(socket, buffer, MAX_INPUT_BUFFER - 1, 0);
|
||||
ssize_t received_bytes = recv(socket, buffer, MAX_INPUT_BUFFER - 1, 0);
|
||||
|
||||
/* return a CRITICAL status if we couldn't read any data */
|
||||
if (result == -1)
|
||||
die(STATE_CRITICAL, _("No data received from %s\n"), host_name);
|
||||
if (received_bytes == -1) {
|
||||
die(STATE_CRITICAL, _("No data received from %s\n"), config.host_name);
|
||||
}
|
||||
|
||||
mp_state_enum result = STATE_OK;
|
||||
char *status_line = NULL;
|
||||
/* make sure we find the response we are looking for */
|
||||
if (!strstr(buffer, server_expect)) {
|
||||
if (server_port == PORT)
|
||||
if (!strstr(buffer, config.server_expect)) {
|
||||
if (config.server_port == PORT) {
|
||||
printf("%s\n", _("Invalid REAL response received from host"));
|
||||
else
|
||||
printf(_("Invalid REAL response received from host on port %d\n"), server_port);
|
||||
} else {
|
||||
printf(_("Invalid REAL response received from host on port %d\n"), config.server_port);
|
||||
}
|
||||
} else {
|
||||
/* else we got the REAL string, so check the return code */
|
||||
|
||||
|
|
@ -117,69 +129,79 @@ int main(int argc, char **argv) {
|
|||
|
||||
result = STATE_OK;
|
||||
|
||||
status_line = (char *)strtok(buffer, "\n");
|
||||
status_line = strtok(buffer, "\n");
|
||||
|
||||
if (strstr(status_line, "200"))
|
||||
if (strstr(status_line, "200")) {
|
||||
result = STATE_OK;
|
||||
}
|
||||
|
||||
/* client errors result in a warning state */
|
||||
else if (strstr(status_line, "400"))
|
||||
else if (strstr(status_line, "400")) {
|
||||
result = STATE_WARNING;
|
||||
else if (strstr(status_line, "401"))
|
||||
} else if (strstr(status_line, "401")) {
|
||||
result = STATE_WARNING;
|
||||
else if (strstr(status_line, "402"))
|
||||
} else if (strstr(status_line, "402")) {
|
||||
result = STATE_WARNING;
|
||||
else if (strstr(status_line, "403"))
|
||||
} else if (strstr(status_line, "403")) {
|
||||
result = STATE_WARNING;
|
||||
else if (strstr(status_line, "404"))
|
||||
} else if (strstr(status_line, "404")) {
|
||||
result = STATE_WARNING;
|
||||
|
||||
/* server errors result in a critical state */
|
||||
else if (strstr(status_line, "500"))
|
||||
} else if (strstr(status_line, "500")) {
|
||||
/* server errors result in a critical state */
|
||||
result = STATE_CRITICAL;
|
||||
else if (strstr(status_line, "501"))
|
||||
} else if (strstr(status_line, "501")) {
|
||||
result = STATE_CRITICAL;
|
||||
else if (strstr(status_line, "502"))
|
||||
} else if (strstr(status_line, "502")) {
|
||||
result = STATE_CRITICAL;
|
||||
else if (strstr(status_line, "503"))
|
||||
} else if (strstr(status_line, "503")) {
|
||||
result = STATE_CRITICAL;
|
||||
|
||||
else
|
||||
} else {
|
||||
result = STATE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
/* Part II - Check stream exists and is ok */
|
||||
if ((result == STATE_OK) && (server_url != NULL)) {
|
||||
if ((result == STATE_OK) && (config.server_url != NULL)) {
|
||||
|
||||
/* Part I - Server Check */
|
||||
|
||||
/* send the DESCRIBE request */
|
||||
sprintf(buffer, "DESCRIBE rtsp://%s:%d%s RTSP/1.0\r\n", host_name, server_port, server_url);
|
||||
result = send(socket, buffer, strlen(buffer), 0);
|
||||
sprintf(buffer, "DESCRIBE rtsp://%s:%d%s RTSP/1.0\r\n", config.host_name, config.server_port, config.server_url);
|
||||
|
||||
ssize_t sent_bytes = send(socket, buffer, strlen(buffer), 0);
|
||||
if (sent_bytes == -1) {
|
||||
die(STATE_CRITICAL, _("Sending DESCRIBE request to %s failed\n"), config.host_name);
|
||||
}
|
||||
|
||||
/* send the header sync */
|
||||
sprintf(buffer, "CSeq: 2\r\n");
|
||||
result = send(socket, buffer, strlen(buffer), 0);
|
||||
sent_bytes = send(socket, buffer, strlen(buffer), 0);
|
||||
if (sent_bytes == -1) {
|
||||
die(STATE_CRITICAL, _("Sending DESCRIBE request to %s failed\n"), config.host_name);
|
||||
}
|
||||
|
||||
/* send a newline so the server knows we're done with the request */
|
||||
sprintf(buffer, "\r\n");
|
||||
result = send(socket, buffer, strlen(buffer), 0);
|
||||
sent_bytes = send(socket, buffer, strlen(buffer), 0);
|
||||
if (sent_bytes == -1) {
|
||||
die(STATE_CRITICAL, _("Sending DESCRIBE request to %s failed\n"), config.host_name);
|
||||
}
|
||||
|
||||
/* watch for the REAL connection string */
|
||||
result = recv(socket, buffer, MAX_INPUT_BUFFER - 1, 0);
|
||||
buffer[result] = '\0'; /* null terminate received buffer */
|
||||
|
||||
/* return a CRITICAL status if we couldn't read any data */
|
||||
if (result == -1) {
|
||||
ssize_t recv_bytes = recv(socket, buffer, MAX_INPUT_BUFFER - 1, 0);
|
||||
if (recv_bytes == -1) {
|
||||
/* return a CRITICAL status if we couldn't read any data */
|
||||
printf(_("No data received from host\n"));
|
||||
result = STATE_CRITICAL;
|
||||
} else {
|
||||
buffer[result] = '\0'; /* null terminate received buffer */
|
||||
/* make sure we find the response we are looking for */
|
||||
if (!strstr(buffer, server_expect)) {
|
||||
if (server_port == PORT)
|
||||
if (!strstr(buffer, config.server_expect)) {
|
||||
if (config.server_port == PORT) {
|
||||
printf("%s\n", _("Invalid REAL response received from host"));
|
||||
else
|
||||
printf(_("Invalid REAL response received from host on port %d\n"), server_port);
|
||||
} else {
|
||||
printf(_("Invalid REAL response received from host on port %d\n"), config.server_port);
|
||||
}
|
||||
} else {
|
||||
|
||||
/* else we got the REAL string, so check the return code */
|
||||
|
|
@ -188,51 +210,56 @@ int main(int argc, char **argv) {
|
|||
|
||||
result = STATE_OK;
|
||||
|
||||
status_line = (char *)strtok(buffer, "\n");
|
||||
status_line = strtok(buffer, "\n");
|
||||
|
||||
if (strstr(status_line, "200"))
|
||||
if (strstr(status_line, "200")) {
|
||||
result = STATE_OK;
|
||||
}
|
||||
|
||||
/* client errors result in a warning state */
|
||||
else if (strstr(status_line, "400"))
|
||||
else if (strstr(status_line, "400")) {
|
||||
result = STATE_WARNING;
|
||||
else if (strstr(status_line, "401"))
|
||||
} else if (strstr(status_line, "401")) {
|
||||
result = STATE_WARNING;
|
||||
else if (strstr(status_line, "402"))
|
||||
} else if (strstr(status_line, "402")) {
|
||||
result = STATE_WARNING;
|
||||
else if (strstr(status_line, "403"))
|
||||
} else if (strstr(status_line, "403")) {
|
||||
result = STATE_WARNING;
|
||||
else if (strstr(status_line, "404"))
|
||||
} else if (strstr(status_line, "404")) {
|
||||
result = STATE_WARNING;
|
||||
}
|
||||
|
||||
/* server errors result in a critical state */
|
||||
else if (strstr(status_line, "500"))
|
||||
else if (strstr(status_line, "500")) {
|
||||
result = STATE_CRITICAL;
|
||||
else if (strstr(status_line, "501"))
|
||||
} else if (strstr(status_line, "501")) {
|
||||
result = STATE_CRITICAL;
|
||||
else if (strstr(status_line, "502"))
|
||||
} else if (strstr(status_line, "502")) {
|
||||
result = STATE_CRITICAL;
|
||||
else if (strstr(status_line, "503"))
|
||||
} else if (strstr(status_line, "503")) {
|
||||
result = STATE_CRITICAL;
|
||||
}
|
||||
|
||||
else
|
||||
else {
|
||||
result = STATE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Return results */
|
||||
if (result == STATE_OK) {
|
||||
|
||||
if (check_critical_time && (end_time - start_time) > critical_time)
|
||||
if (config.check_critical_time && (end_time - start_time) > config.critical_time) {
|
||||
result = STATE_CRITICAL;
|
||||
else if (check_warning_time && (end_time - start_time) > warning_time)
|
||||
} else if (config.check_warning_time && (end_time - start_time) > config.warning_time) {
|
||||
result = STATE_WARNING;
|
||||
}
|
||||
|
||||
/* Put some HTML in here to create a dynamic link */
|
||||
printf(_("REAL %s - %d second response time\n"), state_text(result), (int)(end_time - start_time));
|
||||
} else
|
||||
} else {
|
||||
printf("%s\n", status_line);
|
||||
}
|
||||
|
||||
/* close the connection */
|
||||
close(socket);
|
||||
|
|
@ -240,11 +267,11 @@ int main(int argc, char **argv) {
|
|||
/* reset the alarm */
|
||||
alarm(0);
|
||||
|
||||
return result;
|
||||
exit(result);
|
||||
}
|
||||
|
||||
/* process command-line arguments */
|
||||
int process_arguments(int argc, char **argv) {
|
||||
check_real_config_wrapper process_arguments(int argc, char **argv) {
|
||||
static struct option longopts[] = {{"hostname", required_argument, 0, 'H'}, {"IPaddress", required_argument, 0, 'I'},
|
||||
{"expect", required_argument, 0, 'e'}, {"url", required_argument, 0, 'u'},
|
||||
{"port", required_argument, 0, 'p'}, {"critical", required_argument, 0, 'c'},
|
||||
|
|
@ -252,61 +279,70 @@ int process_arguments(int argc, char **argv) {
|
|||
{"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'},
|
||||
{"help", no_argument, 0, 'h'}, {0, 0, 0, 0}};
|
||||
|
||||
if (argc < 2)
|
||||
return ERROR;
|
||||
check_real_config_wrapper result = {
|
||||
.errorcode = OK,
|
||||
.config = check_real_config_init(),
|
||||
};
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (strcmp("-to", argv[i]) == 0)
|
||||
strcpy(argv[i], "-t");
|
||||
else if (strcmp("-wt", argv[i]) == 0)
|
||||
strcpy(argv[i], "-w");
|
||||
else if (strcmp("-ct", argv[i]) == 0)
|
||||
strcpy(argv[i], "-c");
|
||||
if (argc < 2) {
|
||||
result.errorcode = ERROR;
|
||||
return result;
|
||||
}
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (strcmp("-to", argv[i]) == 0) {
|
||||
strcpy(argv[i], "-t");
|
||||
} else if (strcmp("-wt", argv[i]) == 0) {
|
||||
strcpy(argv[i], "-w");
|
||||
} else if (strcmp("-ct", argv[i]) == 0) {
|
||||
strcpy(argv[i], "-c");
|
||||
}
|
||||
}
|
||||
|
||||
int option_char;
|
||||
while (true) {
|
||||
int option = 0;
|
||||
option_char = getopt_long(argc, argv, "+hvVI:H:e:u:p:w:c:t:", longopts, &option);
|
||||
int option_char = getopt_long(argc, argv, "+hvVI:H:e:u:p:w:c:t:", longopts, &option);
|
||||
|
||||
if (option_char == -1 || option_char == EOF)
|
||||
if (option_char == -1 || option_char == EOF) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (option_char) {
|
||||
case 'I': /* hostname */
|
||||
case 'H': /* hostname */
|
||||
if (server_address)
|
||||
if (result.config.server_address) {
|
||||
break;
|
||||
else if (is_host(optarg))
|
||||
server_address = optarg;
|
||||
else
|
||||
} else if (is_host(optarg)) {
|
||||
result.config.server_address = optarg;
|
||||
} else {
|
||||
usage2(_("Invalid hostname/address"), optarg);
|
||||
}
|
||||
break;
|
||||
case 'e': /* string to expect in response header */
|
||||
server_expect = optarg;
|
||||
result.config.server_expect = optarg;
|
||||
break;
|
||||
case 'u': /* server URL */
|
||||
server_url = optarg;
|
||||
result.config.server_url = optarg;
|
||||
break;
|
||||
case 'p': /* port */
|
||||
if (is_intpos(optarg)) {
|
||||
server_port = atoi(optarg);
|
||||
result.config.server_port = atoi(optarg);
|
||||
} else {
|
||||
usage4(_("Port must be a positive integer"));
|
||||
}
|
||||
break;
|
||||
case 'w': /* warning time threshold */
|
||||
if (is_intnonneg(optarg)) {
|
||||
warning_time = atoi(optarg);
|
||||
check_warning_time = true;
|
||||
result.config.warning_time = atoi(optarg);
|
||||
result.config.check_warning_time = true;
|
||||
} else {
|
||||
usage4(_("Warning time must be a positive integer"));
|
||||
}
|
||||
break;
|
||||
case 'c': /* critical time threshold */
|
||||
if (is_intnonneg(optarg)) {
|
||||
critical_time = atoi(optarg);
|
||||
check_critical_time = true;
|
||||
result.config.critical_time = atoi(optarg);
|
||||
result.config.check_critical_time = true;
|
||||
} else {
|
||||
usage4(_("Critical time must be a positive integer"));
|
||||
}
|
||||
|
|
@ -332,25 +368,28 @@ int process_arguments(int argc, char **argv) {
|
|||
}
|
||||
}
|
||||
|
||||
option_char = optind;
|
||||
if (server_address == NULL && argc > option_char) {
|
||||
int option_char = optind;
|
||||
if (result.config.server_address == NULL && argc > option_char) {
|
||||
if (is_host(argv[option_char])) {
|
||||
server_address = argv[option_char++];
|
||||
result.config.server_address = argv[option_char++];
|
||||
} else {
|
||||
usage2(_("Invalid hostname/address"), argv[option_char]);
|
||||
}
|
||||
}
|
||||
|
||||
if (server_address == NULL)
|
||||
if (result.config.server_address == NULL) {
|
||||
usage4(_("You must provide a server to check"));
|
||||
}
|
||||
|
||||
if (host_name == NULL)
|
||||
host_name = strdup(server_address);
|
||||
if (result.config.host_name == NULL) {
|
||||
result.config.host_name = strdup(result.config.server_address);
|
||||
}
|
||||
|
||||
if (server_expect == NULL)
|
||||
server_expect = strdup(EXPECT);
|
||||
if (result.config.server_expect == NULL) {
|
||||
result.config.server_expect = strdup(EXPECT);
|
||||
}
|
||||
|
||||
return OK;
|
||||
return result;
|
||||
}
|
||||
|
||||
void print_help(void) {
|
||||
|
|
|
|||
37
plugins/check_real.d/config.h
Normal file
37
plugins/check_real.d/config.h
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../config.h"
|
||||
#include <stddef.h>
|
||||
|
||||
enum {
|
||||
PORT = 554
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
char *server_address;
|
||||
char *host_name;
|
||||
int server_port;
|
||||
char *server_url;
|
||||
|
||||
char *server_expect;
|
||||
int warning_time;
|
||||
bool check_warning_time;
|
||||
int critical_time;
|
||||
bool check_critical_time;
|
||||
} check_real_config;
|
||||
|
||||
check_real_config check_real_config_init() {
|
||||
check_real_config tmp = {
|
||||
.server_address = NULL,
|
||||
.host_name = NULL,
|
||||
.server_port = PORT,
|
||||
.server_url = NULL,
|
||||
|
||||
.server_expect = NULL,
|
||||
.warning_time = 0,
|
||||
.check_warning_time = false,
|
||||
.critical_time = 0,
|
||||
.check_critical_time = false,
|
||||
};
|
||||
return tmp;
|
||||
}
|
||||
1153
plugins/check_smtp.c
1153
plugins/check_smtp.c
File diff suppressed because it is too large
Load diff
92
plugins/check_smtp.d/config.h
Normal file
92
plugins/check_smtp.d/config.h
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../config.h"
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
enum {
|
||||
SMTP_PORT = 25,
|
||||
SMTPS_PORT = 465
|
||||
};
|
||||
|
||||
#define SMTP_EXPECT "220"
|
||||
|
||||
typedef struct {
|
||||
int server_port;
|
||||
char *server_address;
|
||||
char *localhostname;
|
||||
char *server_expect;
|
||||
bool ignore_send_quit_failure;
|
||||
|
||||
double warning_time;
|
||||
bool check_warning_time;
|
||||
double critical_time;
|
||||
bool check_critical_time;
|
||||
bool use_ehlo;
|
||||
bool use_lhlo;
|
||||
|
||||
char *from_arg;
|
||||
bool send_mail_from;
|
||||
|
||||
int ncommands;
|
||||
char **commands;
|
||||
|
||||
int nresponses;
|
||||
char **responses;
|
||||
|
||||
char *authtype;
|
||||
char *authuser;
|
||||
char *authpass;
|
||||
|
||||
bool use_proxy_prefix;
|
||||
#ifdef HAVE_SSL
|
||||
bool check_cert;
|
||||
int days_till_exp_warn;
|
||||
int days_till_exp_crit;
|
||||
bool use_ssl;
|
||||
bool use_starttls;
|
||||
bool use_sni;
|
||||
#endif
|
||||
} check_smtp_config;
|
||||
|
||||
check_smtp_config check_smtp_config_init() {
|
||||
check_smtp_config tmp = {
|
||||
.server_port = SMTP_PORT,
|
||||
.server_address = NULL,
|
||||
.localhostname = NULL,
|
||||
|
||||
.server_expect = SMTP_EXPECT,
|
||||
.ignore_send_quit_failure = false,
|
||||
|
||||
.warning_time = 0,
|
||||
.check_warning_time = false,
|
||||
.critical_time = 0,
|
||||
.check_critical_time = false,
|
||||
.use_ehlo = false,
|
||||
.use_lhlo = false,
|
||||
|
||||
.from_arg = strdup(" "),
|
||||
.send_mail_from = false,
|
||||
|
||||
.ncommands = 0,
|
||||
.commands = NULL,
|
||||
|
||||
.nresponses = 0,
|
||||
.responses = NULL,
|
||||
|
||||
.authtype = NULL,
|
||||
.authuser = NULL,
|
||||
.authpass = NULL,
|
||||
|
||||
.use_proxy_prefix = false,
|
||||
#ifdef HAVE_SSL
|
||||
.check_cert = false,
|
||||
.days_till_exp_warn = 0,
|
||||
.days_till_exp_crit = 0,
|
||||
.use_ssl = false,
|
||||
.use_starttls = false,
|
||||
.use_sni = false,
|
||||
#endif
|
||||
};
|
||||
return tmp;
|
||||
}
|
||||
|
|
@ -28,6 +28,9 @@
|
|||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "output.h"
|
||||
#include "perfdata.h"
|
||||
#include "states.h"
|
||||
const char *progname = "check_ssh";
|
||||
const char *copyright = "2000-2024";
|
||||
const char *email = "devel@monitoring-plugins.org";
|
||||
|
|
@ -35,26 +38,26 @@ const char *email = "devel@monitoring-plugins.org";
|
|||
#include "./common.h"
|
||||
#include "./netutils.h"
|
||||
#include "utils.h"
|
||||
#include "./check_ssh.d/config.h"
|
||||
|
||||
#ifndef MSG_DONTWAIT
|
||||
# define MSG_DONTWAIT 0
|
||||
#endif
|
||||
|
||||
#define SSH_DFL_PORT 22
|
||||
#define BUFF_SZ 256
|
||||
#define BUFF_SZ 256
|
||||
|
||||
static int port = -1;
|
||||
static char *server_name = NULL;
|
||||
static char *remote_version = NULL;
|
||||
static char *remote_protocol = NULL;
|
||||
static bool verbose = false;
|
||||
|
||||
static int process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
static int validate_arguments(void);
|
||||
typedef struct process_arguments_wrapper {
|
||||
int errorcode;
|
||||
check_ssh_config config;
|
||||
} process_arguments_wrapper;
|
||||
|
||||
static process_arguments_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
static void print_help(void);
|
||||
void print_usage(void);
|
||||
|
||||
static int ssh_connect(char *haddr, int hport, char *remote_version, char *remote_protocol);
|
||||
static int ssh_connect(mp_check *overall, char *haddr, int hport, char *remote_version, char *remote_protocol);
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
setlocale(LC_ALL, "");
|
||||
|
|
@ -64,24 +67,35 @@ int main(int argc, char **argv) {
|
|||
/* Parse extra opts if any */
|
||||
argv = np_extra_opts(&argc, argv, progname);
|
||||
|
||||
if (process_arguments(argc, argv) == ERROR)
|
||||
process_arguments_wrapper tmp_config = process_arguments(argc, argv);
|
||||
|
||||
if (tmp_config.errorcode == ERROR) {
|
||||
usage4(_("Could not parse arguments"));
|
||||
}
|
||||
|
||||
check_ssh_config config = tmp_config.config;
|
||||
|
||||
mp_check overall = mp_check_init();
|
||||
if (config.output_format_is_set) {
|
||||
mp_set_format(config.output_format);
|
||||
}
|
||||
|
||||
/* initialize alarm signal handling */
|
||||
signal(SIGALRM, socket_timeout_alarm_handler);
|
||||
|
||||
alarm(socket_timeout);
|
||||
|
||||
/* ssh_connect exits if error is found */
|
||||
int result = ssh_connect(server_name, port, remote_version, remote_protocol);
|
||||
ssh_connect(&overall, config.server_name, config.port, config.remote_version, config.remote_protocol);
|
||||
|
||||
alarm(0);
|
||||
|
||||
return (result);
|
||||
mp_exit(overall);
|
||||
}
|
||||
|
||||
#define output_format_index CHAR_MAX + 1
|
||||
|
||||
/* process command-line arguments */
|
||||
int process_arguments(int argc, char **argv) {
|
||||
process_arguments_wrapper process_arguments(int argc, char **argv) {
|
||||
static struct option longopts[] = {{"help", no_argument, 0, 'h'},
|
||||
{"version", no_argument, 0, 'V'},
|
||||
{"host", required_argument, 0, 'H'}, /* backward compatibility */
|
||||
|
|
@ -93,22 +107,33 @@ int process_arguments(int argc, char **argv) {
|
|||
{"verbose", no_argument, 0, 'v'},
|
||||
{"remote-version", required_argument, 0, 'r'},
|
||||
{"remote-protocol", required_argument, 0, 'P'},
|
||||
{"output-format", required_argument, 0, output_format_index},
|
||||
{0, 0, 0, 0}};
|
||||
|
||||
if (argc < 2)
|
||||
return ERROR;
|
||||
process_arguments_wrapper result = {
|
||||
.config = check_ssh_config_init(),
|
||||
.errorcode = OK,
|
||||
};
|
||||
|
||||
for (int i = 1; i < argc; i++)
|
||||
if (strcmp("-to", argv[i]) == 0)
|
||||
if (argc < 2) {
|
||||
result.errorcode = ERROR;
|
||||
return result;
|
||||
}
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (strcmp("-to", argv[i]) == 0) {
|
||||
strcpy(argv[i], "-t");
|
||||
}
|
||||
}
|
||||
|
||||
int option_char;
|
||||
while (true) {
|
||||
int option = 0;
|
||||
option_char = getopt_long(argc, argv, "+Vhv46t:r:H:p:P:", longopts, &option);
|
||||
|
||||
if (option_char == -1 || option_char == EOF)
|
||||
if (option_char == -1 || option_char == EOF) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (option_char) {
|
||||
case '?': /* help */
|
||||
|
|
@ -123,10 +148,11 @@ int process_arguments(int argc, char **argv) {
|
|||
verbose = true;
|
||||
break;
|
||||
case 't': /* timeout period */
|
||||
if (!is_integer(optarg))
|
||||
if (!is_intpos(optarg)) {
|
||||
usage2(_("Timeout interval must be a positive integer"), optarg);
|
||||
else
|
||||
socket_timeout = atoi(optarg);
|
||||
} else {
|
||||
socket_timeout = (unsigned int)atoi(optarg);
|
||||
}
|
||||
break;
|
||||
case '4':
|
||||
address_family = AF_INET;
|
||||
|
|
@ -139,50 +165,61 @@ int process_arguments(int argc, char **argv) {
|
|||
#endif
|
||||
break;
|
||||
case 'r': /* remote version */
|
||||
remote_version = optarg;
|
||||
result.config.remote_version = optarg;
|
||||
break;
|
||||
case 'P': /* remote version */
|
||||
remote_protocol = optarg;
|
||||
result.config.remote_protocol = optarg;
|
||||
break;
|
||||
case 'H': /* host */
|
||||
if (!is_host(optarg))
|
||||
if (!is_host(optarg)) {
|
||||
usage2(_("Invalid hostname/address"), optarg);
|
||||
server_name = optarg;
|
||||
}
|
||||
result.config.server_name = optarg;
|
||||
break;
|
||||
case 'p': /* port */
|
||||
if (is_intpos(optarg)) {
|
||||
port = atoi(optarg);
|
||||
result.config.port = atoi(optarg);
|
||||
} else {
|
||||
usage2(_("Port number must be a positive integer"), optarg);
|
||||
}
|
||||
break;
|
||||
case output_format_index: {
|
||||
parsed_output_format parser = mp_parse_output_format(optarg);
|
||||
if (!parser.parsing_success) {
|
||||
// TODO List all available formats here, maybe add anothoer usage function
|
||||
printf("Invalid output format: %s\n", optarg);
|
||||
exit(STATE_UNKNOWN);
|
||||
}
|
||||
|
||||
result.config.output_format_is_set = true;
|
||||
result.config.output_format = parser.output_format;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option_char = optind;
|
||||
if (server_name == NULL && option_char < argc) {
|
||||
if (result.config.server_name == NULL && option_char < argc) {
|
||||
if (is_host(argv[option_char])) {
|
||||
server_name = argv[option_char++];
|
||||
result.config.server_name = argv[option_char++];
|
||||
}
|
||||
}
|
||||
|
||||
if (port == -1 && option_char < argc) {
|
||||
if (result.config.port == -1 && option_char < argc) {
|
||||
if (is_intpos(argv[option_char])) {
|
||||
port = atoi(argv[option_char++]);
|
||||
result.config.port = atoi(argv[option_char++]);
|
||||
} else {
|
||||
print_usage();
|
||||
exit(STATE_UNKNOWN);
|
||||
}
|
||||
}
|
||||
|
||||
return validate_arguments();
|
||||
}
|
||||
if (result.config.server_name == NULL) {
|
||||
result.errorcode = ERROR;
|
||||
return result;
|
||||
}
|
||||
|
||||
int validate_arguments(void) {
|
||||
if (server_name == NULL)
|
||||
return ERROR;
|
||||
if (port == -1) /* funky, but allows -p to override stray integer in args */
|
||||
port = SSH_DFL_PORT;
|
||||
return OK;
|
||||
return result;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
|
|
@ -191,28 +228,34 @@ int validate_arguments(void) {
|
|||
*
|
||||
*-----------------------------------------------------------------------*/
|
||||
|
||||
int ssh_connect(char *haddr, int hport, char *remote_version, char *remote_protocol) {
|
||||
int ssh_connect(mp_check *overall, char *haddr, int hport, char *desired_remote_version, char *desired_remote_protocol) {
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
int socket;
|
||||
int result = my_tcp_connect(haddr, hport, &socket);
|
||||
|
||||
if (result != STATE_OK)
|
||||
mp_subcheck connection_sc = mp_subcheck_init();
|
||||
if (result != STATE_OK) {
|
||||
connection_sc = mp_set_subcheck_state(connection_sc, STATE_CRITICAL);
|
||||
xasprintf(&connection_sc.output, "Failed to establish TCP connection to Host %s and Port %d", haddr, hport);
|
||||
mp_add_subcheck_to_check(overall, connection_sc);
|
||||
return result;
|
||||
}
|
||||
|
||||
char *output = (char *)calloc(BUFF_SZ + 1, sizeof(char));
|
||||
char *buffer = NULL;
|
||||
ssize_t recv_ret = 0;
|
||||
size_t recv_ret = 0;
|
||||
char *version_control_string = NULL;
|
||||
ssize_t byte_offset = 0;
|
||||
while ((version_control_string == NULL) && (recv_ret = recv(socket, output + byte_offset, BUFF_SZ - byte_offset, 0) > 0)) {
|
||||
size_t byte_offset = 0;
|
||||
while ((version_control_string == NULL) &&
|
||||
(recv_ret = recv(socket, output + byte_offset, (unsigned long)(BUFF_SZ - byte_offset), 0) > 0)) {
|
||||
|
||||
if (strchr(output, '\n')) { /* we've got at least one full line, start parsing*/
|
||||
byte_offset = 0;
|
||||
|
||||
char *index = NULL;
|
||||
int len = 0;
|
||||
unsigned long len = 0;
|
||||
while ((index = strchr(output + byte_offset, '\n')) != NULL) {
|
||||
/*Partition the buffer so that this line is a separate string,
|
||||
* by replacing the newline with NUL*/
|
||||
|
|
@ -243,14 +286,23 @@ int ssh_connect(char *haddr, int hport, char *remote_version, char *remote_proto
|
|||
}
|
||||
|
||||
if (recv_ret < 0) {
|
||||
printf("SSH CRITICAL - %s", strerror(errno));
|
||||
exit(STATE_CRITICAL);
|
||||
connection_sc = mp_set_subcheck_state(connection_sc, STATE_CRITICAL);
|
||||
xasprintf(&connection_sc.output, "%s", "SSH CRITICAL - %s", strerror(errno));
|
||||
mp_add_subcheck_to_check(overall, connection_sc);
|
||||
return OK;
|
||||
}
|
||||
|
||||
if (version_control_string == NULL) {
|
||||
printf("SSH CRITICAL - No version control string received");
|
||||
exit(STATE_CRITICAL);
|
||||
connection_sc = mp_set_subcheck_state(connection_sc, STATE_CRITICAL);
|
||||
xasprintf(&connection_sc.output, "%s", "SSH CRITICAL - No version control string received");
|
||||
mp_add_subcheck_to_check(overall, connection_sc);
|
||||
return OK;
|
||||
}
|
||||
|
||||
connection_sc = mp_set_subcheck_state(connection_sc, STATE_OK);
|
||||
xasprintf(&connection_sc.output, "%s", "Initial connection succeeded");
|
||||
mp_add_subcheck_to_check(overall, connection_sc);
|
||||
|
||||
/*
|
||||
* "When the connection has been established, both sides MUST send an
|
||||
* identification string. This identification string MUST be
|
||||
|
|
@ -259,8 +311,9 @@ int ssh_connect(char *haddr, int hport, char *remote_version, char *remote_proto
|
|||
* - RFC 4253:4.2
|
||||
*/
|
||||
strip(version_control_string);
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
printf("%s\n", version_control_string);
|
||||
}
|
||||
|
||||
char *ssh_proto = version_control_string + 4;
|
||||
|
||||
|
|
@ -288,41 +341,65 @@ int ssh_connect(char *haddr, int hport, char *remote_version, char *remote_proto
|
|||
if (tmp) {
|
||||
ssh_server[tmp - ssh_server] = '\0';
|
||||
}
|
||||
|
||||
mp_subcheck protocol_validity_sc = mp_subcheck_init();
|
||||
if (strlen(ssh_proto) == 0 || strlen(ssh_server) == 0) {
|
||||
printf(_("SSH CRITICAL - Invalid protocol version control string %s\n"), version_control_string);
|
||||
exit(STATE_CRITICAL);
|
||||
protocol_validity_sc = mp_set_subcheck_state(protocol_validity_sc, STATE_CRITICAL);
|
||||
xasprintf(&protocol_validity_sc.output, "Invalid protocol version control string %s", version_control_string);
|
||||
mp_add_subcheck_to_check(overall, protocol_validity_sc);
|
||||
return OK;
|
||||
}
|
||||
|
||||
protocol_validity_sc = mp_set_subcheck_state(protocol_validity_sc, STATE_OK);
|
||||
xasprintf(&protocol_validity_sc.output, "Valid protocol version control string %s", version_control_string);
|
||||
mp_add_subcheck_to_check(overall, protocol_validity_sc);
|
||||
|
||||
ssh_proto[strspn(ssh_proto, "0123456789. ")] = 0;
|
||||
|
||||
static char *rev_no = VERSION;
|
||||
xasprintf(&buffer, "SSH-%s-check_ssh_%s\r\n", ssh_proto, rev_no);
|
||||
send(socket, buffer, strlen(buffer), MSG_DONTWAIT);
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
printf("%s\n", buffer);
|
||||
}
|
||||
|
||||
if (remote_version && strcmp(remote_version, ssh_server)) {
|
||||
printf(_("SSH CRITICAL - %s (protocol %s) version mismatch, expected '%s'\n"), ssh_server, ssh_proto, remote_version);
|
||||
if (desired_remote_version && strcmp(desired_remote_version, ssh_server)) {
|
||||
mp_subcheck remote_version_sc = mp_subcheck_init();
|
||||
remote_version_sc = mp_set_subcheck_state(remote_version_sc, STATE_CRITICAL);
|
||||
xasprintf(&remote_version_sc.output, _("%s (protocol %s) version mismatch, expected '%s'"), ssh_server, ssh_proto,
|
||||
desired_remote_version);
|
||||
close(socket);
|
||||
exit(STATE_CRITICAL);
|
||||
mp_add_subcheck_to_check(overall, remote_version_sc);
|
||||
return OK;
|
||||
}
|
||||
|
||||
double elapsed_time = (double)deltime(tv) / 1.0e6;
|
||||
if (remote_protocol && strcmp(remote_protocol, ssh_proto)) {
|
||||
printf(_("SSH CRITICAL - %s (protocol %s) protocol version mismatch, expected '%s' | %s\n"), ssh_server, ssh_proto, remote_protocol,
|
||||
fperfdata("time", elapsed_time, "s", false, 0, false, 0, true, 0, true, (int)socket_timeout));
|
||||
close(socket);
|
||||
exit(STATE_CRITICAL);
|
||||
mp_perfdata time_pd = perfdata_init();
|
||||
time_pd.value = mp_create_pd_value(elapsed_time);
|
||||
time_pd.label = "time";
|
||||
time_pd.max_present = true;
|
||||
time_pd.max = mp_create_pd_value(socket_timeout);
|
||||
|
||||
mp_subcheck protocol_version_sc = mp_subcheck_init();
|
||||
mp_add_perfdata_to_subcheck(&protocol_version_sc, time_pd);
|
||||
|
||||
if (desired_remote_protocol && strcmp(desired_remote_protocol, ssh_proto)) {
|
||||
protocol_version_sc = mp_set_subcheck_state(protocol_version_sc, STATE_CRITICAL);
|
||||
xasprintf(&protocol_version_sc.output, _("%s (protocol %s) protocol version mismatch, expected '%s'"), ssh_server, ssh_proto,
|
||||
desired_remote_protocol);
|
||||
} else {
|
||||
protocol_version_sc = mp_set_subcheck_state(protocol_version_sc, STATE_OK);
|
||||
xasprintf(&protocol_version_sc.output, "SSH server version: %s (protocol version: %s)", ssh_server, ssh_proto);
|
||||
}
|
||||
|
||||
printf(_("SSH OK - %s (protocol %s) | %s\n"), ssh_server, ssh_proto,
|
||||
fperfdata("time", elapsed_time, "s", false, 0, false, 0, true, 0, true, (int)socket_timeout));
|
||||
mp_add_subcheck_to_check(overall, protocol_version_sc);
|
||||
close(socket);
|
||||
exit(STATE_OK);
|
||||
return OK;
|
||||
}
|
||||
|
||||
void print_help(void) {
|
||||
char *myport;
|
||||
xasprintf(&myport, "%d", SSH_DFL_PORT);
|
||||
xasprintf(&myport, "%d", default_ssh_port);
|
||||
|
||||
print_revision(progname, NP_VERSION);
|
||||
|
||||
|
|
@ -349,6 +426,7 @@ void print_help(void) {
|
|||
|
||||
printf(" %s\n", "-P, --remote-protocol=STRING");
|
||||
printf(" %s\n", _("Alert if protocol doesn't match expected protocol version (ex: 2.0)"));
|
||||
printf(UT_OUTPUT_FORMAT);
|
||||
|
||||
printf(UT_VERBOSE);
|
||||
|
||||
|
|
@ -357,5 +435,5 @@ void print_help(void) {
|
|||
|
||||
void print_usage(void) {
|
||||
printf("%s\n", _("Usage:"));
|
||||
printf("%s [-4|-6] [-t <timeout>] [-r <remote version>] [-p <port>] <host>\n", progname);
|
||||
printf("%s [-4|-6] [-t <timeout>] [-r <remote version>] [-p <port>] --hostname <host>\n", progname);
|
||||
}
|
||||
|
|
|
|||
29
plugins/check_ssh.d/config.h
Normal file
29
plugins/check_ssh.d/config.h
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include "../../lib/monitoringplug.h"
|
||||
|
||||
const int default_ssh_port = 22;
|
||||
|
||||
typedef struct check_ssh_config {
|
||||
int port;
|
||||
char *server_name;
|
||||
char *remote_version;
|
||||
char *remote_protocol;
|
||||
|
||||
bool output_format_is_set;
|
||||
mp_output_format output_format;
|
||||
} check_ssh_config;
|
||||
|
||||
check_ssh_config check_ssh_config_init(void) {
|
||||
check_ssh_config tmp = {
|
||||
.port = default_ssh_port,
|
||||
.server_name = NULL,
|
||||
.remote_version = NULL,
|
||||
.remote_protocol = NULL,
|
||||
|
||||
.output_format_is_set = false,
|
||||
};
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
|
@ -93,7 +93,7 @@ int main(int argc, char **argv) {
|
|||
double percent_used;
|
||||
mp_check overall = mp_check_init();
|
||||
if (config.output_format_is_set) {
|
||||
overall.format = config.output_format;
|
||||
mp_set_format(config.output_format);
|
||||
}
|
||||
mp_subcheck sc1 = mp_subcheck_init();
|
||||
sc1 = mp_set_subcheck_default_state(sc1, STATE_OK);
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "states.h"
|
||||
const char *progname = "check_time";
|
||||
const char *copyright = "1999-2024";
|
||||
const char *email = "devel@monitoring-plugins.org";
|
||||
|
|
@ -35,28 +36,15 @@ const char *email = "devel@monitoring-plugins.org";
|
|||
#include "common.h"
|
||||
#include "netutils.h"
|
||||
#include "utils.h"
|
||||
|
||||
enum {
|
||||
TIME_PORT = 37
|
||||
};
|
||||
#include "check_time.d/config.h"
|
||||
|
||||
#define UNIX_EPOCH 2208988800UL
|
||||
|
||||
static uint32_t raw_server_time;
|
||||
static unsigned long server_time, diff_time;
|
||||
static int warning_time = 0;
|
||||
static bool check_warning_time = false;
|
||||
static int critical_time = 0;
|
||||
static bool check_critical_time = false;
|
||||
static unsigned long warning_diff = 0;
|
||||
static bool check_warning_diff = false;
|
||||
static unsigned long critical_diff = 0;
|
||||
static bool check_critical_diff = false;
|
||||
static int server_port = TIME_PORT;
|
||||
static char *server_address = NULL;
|
||||
static bool use_udp = false;
|
||||
|
||||
static int process_arguments(int, char **);
|
||||
typedef struct {
|
||||
int errorcode;
|
||||
check_time_config config;
|
||||
} check_time_config_wrapper;
|
||||
static check_time_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
static void print_help(void);
|
||||
void print_usage(void);
|
||||
|
||||
|
|
@ -68,8 +56,12 @@ int main(int argc, char **argv) {
|
|||
/* Parse extra opts if any */
|
||||
argv = np_extra_opts(&argc, argv, progname);
|
||||
|
||||
if (process_arguments(argc, argv) == ERROR)
|
||||
check_time_config_wrapper tmp_config = process_arguments(argc, argv);
|
||||
if (tmp_config.errorcode == ERROR) {
|
||||
usage4(_("Could not parse arguments"));
|
||||
}
|
||||
|
||||
const check_time_config config = tmp_config.config;
|
||||
|
||||
/* initialize alarm signal handling */
|
||||
signal(SIGALRM, socket_timeout_alarm_handler);
|
||||
|
|
@ -79,37 +71,40 @@ int main(int argc, char **argv) {
|
|||
time(&start_time);
|
||||
|
||||
int socket;
|
||||
int result = STATE_UNKNOWN;
|
||||
mp_state_enum result = STATE_UNKNOWN;
|
||||
/* try to connect to the host at the given port number */
|
||||
if (use_udp) {
|
||||
result = my_udp_connect(server_address, server_port, &socket);
|
||||
if (config.use_udp) {
|
||||
result = my_udp_connect(config.server_address, config.server_port, &socket);
|
||||
} else {
|
||||
result = my_tcp_connect(server_address, server_port, &socket);
|
||||
result = my_tcp_connect(config.server_address, config.server_port, &socket);
|
||||
}
|
||||
|
||||
if (result != STATE_OK) {
|
||||
if (check_critical_time)
|
||||
if (config.check_critical_time) {
|
||||
result = STATE_CRITICAL;
|
||||
else if (check_warning_time)
|
||||
} else if (config.check_warning_time) {
|
||||
result = STATE_WARNING;
|
||||
else
|
||||
} else {
|
||||
result = STATE_UNKNOWN;
|
||||
die(result, _("TIME UNKNOWN - could not connect to server %s, port %d\n"), server_address, server_port);
|
||||
}
|
||||
die(result, _("TIME UNKNOWN - could not connect to server %s, port %d\n"), config.server_address, config.server_port);
|
||||
}
|
||||
|
||||
if (use_udp) {
|
||||
if (config.use_udp) {
|
||||
if (send(socket, "", 0, 0) < 0) {
|
||||
if (check_critical_time)
|
||||
if (config.check_critical_time) {
|
||||
result = STATE_CRITICAL;
|
||||
else if (check_warning_time)
|
||||
} else if (config.check_warning_time) {
|
||||
result = STATE_WARNING;
|
||||
else
|
||||
} else {
|
||||
result = STATE_UNKNOWN;
|
||||
die(result, _("TIME UNKNOWN - could not send UDP request to server %s, port %d\n"), server_address, server_port);
|
||||
}
|
||||
die(result, _("TIME UNKNOWN - could not send UDP request to server %s, port %d\n"), config.server_address, config.server_port);
|
||||
}
|
||||
}
|
||||
|
||||
/* watch for the connection string */
|
||||
uint32_t raw_server_time;
|
||||
result = recv(socket, (void *)&raw_server_time, sizeof(raw_server_time), 0);
|
||||
|
||||
/* close the connection */
|
||||
|
|
@ -121,48 +116,56 @@ int main(int argc, char **argv) {
|
|||
|
||||
/* return a WARNING status if we couldn't read any data */
|
||||
if (result <= 0) {
|
||||
if (check_critical_time)
|
||||
if (config.check_critical_time) {
|
||||
result = STATE_CRITICAL;
|
||||
else if (check_warning_time)
|
||||
} else if (config.check_warning_time) {
|
||||
result = STATE_WARNING;
|
||||
else
|
||||
} else {
|
||||
result = STATE_UNKNOWN;
|
||||
die(result, _("TIME UNKNOWN - no data received from server %s, port %d\n"), server_address, server_port);
|
||||
}
|
||||
die(result, _("TIME UNKNOWN - no data received from server %s, port %d\n"), config.server_address, config.server_port);
|
||||
}
|
||||
|
||||
result = STATE_OK;
|
||||
|
||||
time_t conntime = (end_time - start_time);
|
||||
if (check_critical_time && conntime > critical_time)
|
||||
if (config.check_critical_time && conntime > config.critical_time) {
|
||||
result = STATE_CRITICAL;
|
||||
else if (check_warning_time && conntime > warning_time)
|
||||
} else if (config.check_warning_time && conntime > config.warning_time) {
|
||||
result = STATE_WARNING;
|
||||
}
|
||||
|
||||
if (result != STATE_OK)
|
||||
if (result != STATE_OK) {
|
||||
die(result, _("TIME %s - %d second response time|%s\n"), state_text(result), (int)conntime,
|
||||
perfdata("time", (long)conntime, "s", check_warning_time, (long)warning_time, check_critical_time, (long)critical_time, true, 0,
|
||||
false, 0));
|
||||
perfdata("time", (long)conntime, "s", config.check_warning_time, (long)config.warning_time, config.check_critical_time,
|
||||
(long)config.critical_time, true, 0, false, 0));
|
||||
}
|
||||
|
||||
unsigned long server_time;
|
||||
unsigned long diff_time;
|
||||
server_time = ntohl(raw_server_time) - UNIX_EPOCH;
|
||||
if (server_time > (unsigned long)end_time)
|
||||
if (server_time > (unsigned long)end_time) {
|
||||
diff_time = server_time - (unsigned long)end_time;
|
||||
else
|
||||
} else {
|
||||
diff_time = (unsigned long)end_time - server_time;
|
||||
}
|
||||
|
||||
if (check_critical_diff && diff_time > critical_diff)
|
||||
if (config.check_critical_diff && diff_time > config.critical_diff) {
|
||||
result = STATE_CRITICAL;
|
||||
else if (check_warning_diff && diff_time > warning_diff)
|
||||
} else if (config.check_warning_diff && diff_time > config.warning_diff) {
|
||||
result = STATE_WARNING;
|
||||
}
|
||||
|
||||
printf(_("TIME %s - %lu second time difference|%s %s\n"), state_text(result), diff_time,
|
||||
perfdata("time", (long)conntime, "s", check_warning_time, (long)warning_time, check_critical_time, (long)critical_time, true, 0,
|
||||
false, 0),
|
||||
perfdata("offset", diff_time, "s", check_warning_diff, warning_diff, check_critical_diff, critical_diff, true, 0, false, 0));
|
||||
perfdata("time", (long)conntime, "s", config.check_warning_time, (long)config.warning_time, config.check_critical_time,
|
||||
(long)config.critical_time, true, 0, false, 0),
|
||||
perfdata("offset", diff_time, "s", config.check_warning_diff, config.warning_diff, config.check_critical_diff,
|
||||
config.critical_diff, true, 0, false, 0));
|
||||
return result;
|
||||
}
|
||||
|
||||
/* process command-line arguments */
|
||||
int process_arguments(int argc, char **argv) {
|
||||
check_time_config_wrapper process_arguments(int argc, char **argv) {
|
||||
static struct option longopts[] = {{"hostname", required_argument, 0, 'H'},
|
||||
{"warning-variance", required_argument, 0, 'w'},
|
||||
{"critical-variance", required_argument, 0, 'c'},
|
||||
|
|
@ -175,29 +178,37 @@ int process_arguments(int argc, char **argv) {
|
|||
{"help", no_argument, 0, 'h'},
|
||||
{0, 0, 0, 0}};
|
||||
|
||||
if (argc < 2)
|
||||
if (argc < 2) {
|
||||
usage("\n");
|
||||
}
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (strcmp("-to", argv[i]) == 0)
|
||||
if (strcmp("-to", argv[i]) == 0) {
|
||||
strcpy(argv[i], "-t");
|
||||
else if (strcmp("-wd", argv[i]) == 0)
|
||||
} else if (strcmp("-wd", argv[i]) == 0) {
|
||||
strcpy(argv[i], "-w");
|
||||
else if (strcmp("-cd", argv[i]) == 0)
|
||||
} else if (strcmp("-cd", argv[i]) == 0) {
|
||||
strcpy(argv[i], "-c");
|
||||
else if (strcmp("-wt", argv[i]) == 0)
|
||||
} else if (strcmp("-wt", argv[i]) == 0) {
|
||||
strcpy(argv[i], "-W");
|
||||
else if (strcmp("-ct", argv[i]) == 0)
|
||||
} else if (strcmp("-ct", argv[i]) == 0) {
|
||||
strcpy(argv[i], "-C");
|
||||
}
|
||||
}
|
||||
|
||||
check_time_config_wrapper result = {
|
||||
.errorcode = OK,
|
||||
.config = check_time_config_init(),
|
||||
};
|
||||
|
||||
int option_char;
|
||||
while (true) {
|
||||
int option = 0;
|
||||
option_char = getopt_long(argc, argv, "hVH:w:c:W:C:p:t:u", longopts, &option);
|
||||
|
||||
if (option_char == -1 || option_char == EOF)
|
||||
if (option_char == -1 || option_char == EOF) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (option_char) {
|
||||
case '?': /* print short usage statement if args not parsable */
|
||||
|
|
@ -209,18 +220,19 @@ int process_arguments(int argc, char **argv) {
|
|||
print_revision(progname, NP_VERSION);
|
||||
exit(STATE_UNKNOWN);
|
||||
case 'H': /* hostname */
|
||||
if (!is_host(optarg))
|
||||
if (!is_host(optarg)) {
|
||||
usage2(_("Invalid hostname/address"), optarg);
|
||||
server_address = optarg;
|
||||
}
|
||||
result.config.server_address = optarg;
|
||||
break;
|
||||
case 'w': /* warning-variance */
|
||||
if (is_intnonneg(optarg)) {
|
||||
warning_diff = strtoul(optarg, NULL, 10);
|
||||
check_warning_diff = true;
|
||||
result.config.warning_diff = strtoul(optarg, NULL, 10);
|
||||
result.config.check_warning_diff = true;
|
||||
} else if (strspn(optarg, "0123456789:,") > 0) {
|
||||
if (sscanf(optarg, "%lu%*[:,]%d", &warning_diff, &warning_time) == 2) {
|
||||
check_warning_diff = true;
|
||||
check_warning_time = true;
|
||||
if (sscanf(optarg, "%lu%*[:,]%d", &result.config.warning_diff, &result.config.warning_time) == 2) {
|
||||
result.config.check_warning_diff = true;
|
||||
result.config.check_warning_time = true;
|
||||
} else {
|
||||
usage4(_("Warning thresholds must be a positive integer"));
|
||||
}
|
||||
|
|
@ -230,12 +242,12 @@ int process_arguments(int argc, char **argv) {
|
|||
break;
|
||||
case 'c': /* critical-variance */
|
||||
if (is_intnonneg(optarg)) {
|
||||
critical_diff = strtoul(optarg, NULL, 10);
|
||||
check_critical_diff = true;
|
||||
result.config.critical_diff = strtoul(optarg, NULL, 10);
|
||||
result.config.check_critical_diff = true;
|
||||
} else if (strspn(optarg, "0123456789:,") > 0) {
|
||||
if (sscanf(optarg, "%lu%*[:,]%d", &critical_diff, &critical_time) == 2) {
|
||||
check_critical_diff = true;
|
||||
check_critical_time = true;
|
||||
if (sscanf(optarg, "%lu%*[:,]%d", &result.config.critical_diff, &result.config.critical_time) == 2) {
|
||||
result.config.check_critical_diff = true;
|
||||
result.config.check_critical_time = true;
|
||||
} else {
|
||||
usage4(_("Critical thresholds must be a positive integer"));
|
||||
}
|
||||
|
|
@ -244,48 +256,53 @@ int process_arguments(int argc, char **argv) {
|
|||
}
|
||||
break;
|
||||
case 'W': /* warning-connect */
|
||||
if (!is_intnonneg(optarg))
|
||||
if (!is_intnonneg(optarg)) {
|
||||
usage4(_("Warning threshold must be a positive integer"));
|
||||
else
|
||||
warning_time = atoi(optarg);
|
||||
check_warning_time = true;
|
||||
} else {
|
||||
result.config.warning_time = atoi(optarg);
|
||||
}
|
||||
result.config.check_warning_time = true;
|
||||
break;
|
||||
case 'C': /* critical-connect */
|
||||
if (!is_intnonneg(optarg))
|
||||
if (!is_intnonneg(optarg)) {
|
||||
usage4(_("Critical threshold must be a positive integer"));
|
||||
else
|
||||
critical_time = atoi(optarg);
|
||||
check_critical_time = true;
|
||||
} else {
|
||||
result.config.critical_time = atoi(optarg);
|
||||
}
|
||||
result.config.check_critical_time = true;
|
||||
break;
|
||||
case 'p': /* port */
|
||||
if (!is_intnonneg(optarg))
|
||||
if (!is_intnonneg(optarg)) {
|
||||
usage4(_("Port must be a positive integer"));
|
||||
else
|
||||
server_port = atoi(optarg);
|
||||
} else {
|
||||
result.config.server_port = atoi(optarg);
|
||||
}
|
||||
break;
|
||||
case 't': /* timeout */
|
||||
if (!is_intnonneg(optarg))
|
||||
if (!is_intnonneg(optarg)) {
|
||||
usage2(_("Timeout interval must be a positive integer"), optarg);
|
||||
else
|
||||
} else {
|
||||
socket_timeout = atoi(optarg);
|
||||
}
|
||||
break;
|
||||
case 'u': /* udp */
|
||||
use_udp = true;
|
||||
result.config.use_udp = true;
|
||||
}
|
||||
}
|
||||
|
||||
option_char = optind;
|
||||
if (server_address == NULL) {
|
||||
if (result.config.server_address == NULL) {
|
||||
if (argc > option_char) {
|
||||
if (!is_host(argv[option_char]))
|
||||
if (!is_host(argv[option_char])) {
|
||||
usage2(_("Invalid hostname/address"), optarg);
|
||||
server_address = argv[option_char];
|
||||
}
|
||||
result.config.server_address = argv[option_char];
|
||||
} else {
|
||||
usage4(_("Hostname was not supplied"));
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
return result;
|
||||
}
|
||||
|
||||
void print_help(void) {
|
||||
|
|
|
|||
42
plugins/check_time.d/config.h
Normal file
42
plugins/check_time.d/config.h
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../config.h"
|
||||
#include <stddef.h>
|
||||
|
||||
enum {
|
||||
TIME_PORT = 37
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
char *server_address;
|
||||
int server_port;
|
||||
bool use_udp;
|
||||
|
||||
int warning_time;
|
||||
bool check_warning_time;
|
||||
int critical_time;
|
||||
bool check_critical_time;
|
||||
unsigned long warning_diff;
|
||||
bool check_warning_diff;
|
||||
unsigned long critical_diff;
|
||||
bool check_critical_diff;
|
||||
} check_time_config;
|
||||
|
||||
check_time_config check_time_config_init() {
|
||||
check_time_config tmp = {
|
||||
.server_address = NULL,
|
||||
.server_port = TIME_PORT,
|
||||
.use_udp = false,
|
||||
|
||||
.warning_time = 0,
|
||||
.check_warning_time = false,
|
||||
.critical_time = 0,
|
||||
.check_critical_time = false,
|
||||
|
||||
.warning_diff = 0,
|
||||
.check_warning_diff = false,
|
||||
.critical_diff = 0,
|
||||
.check_critical_diff = false,
|
||||
};
|
||||
return tmp;
|
||||
}
|
||||
|
|
@ -39,69 +39,29 @@ const char *email = "devel@monitoring-plugins.org";
|
|||
#include "common.h"
|
||||
#include "netutils.h"
|
||||
#include "utils.h"
|
||||
|
||||
enum {
|
||||
PORT = 3493
|
||||
};
|
||||
|
||||
#define UPS_NONE 0 /* no supported options */
|
||||
#define UPS_UTILITY 1 /* supports utility line */
|
||||
#define UPS_BATTPCT 2 /* supports percent battery remaining */
|
||||
#define UPS_STATUS 4 /* supports UPS status */
|
||||
#define UPS_TEMP 8 /* supports UPS temperature */
|
||||
#define UPS_LOADPCT 16 /* supports load percent */
|
||||
#define UPS_REALPOWER 32 /* supports real power */
|
||||
|
||||
#define UPSSTATUS_NONE 0
|
||||
#define UPSSTATUS_OFF 1
|
||||
#define UPSSTATUS_OL 2
|
||||
#define UPSSTATUS_OB 4
|
||||
#define UPSSTATUS_LB 8
|
||||
#define UPSSTATUS_CAL 16
|
||||
#define UPSSTATUS_RB 32 /*Replace Battery */
|
||||
#define UPSSTATUS_BYPASS 64
|
||||
#define UPSSTATUS_OVER 128
|
||||
#define UPSSTATUS_TRIM 256
|
||||
#define UPSSTATUS_BOOST 512
|
||||
#define UPSSTATUS_CHRG 1024
|
||||
#define UPSSTATUS_DISCHRG 2048
|
||||
#define UPSSTATUS_UNKNOWN 4096
|
||||
#define UPSSTATUS_ALARM 8192
|
||||
#include "check_ups.d/config.h"
|
||||
#include "states.h"
|
||||
|
||||
enum {
|
||||
NOSUCHVAR = ERROR - 1
|
||||
};
|
||||
|
||||
typedef struct ups_config {
|
||||
unsigned int server_port;
|
||||
char *server_address;
|
||||
char *ups_name;
|
||||
double warning_value;
|
||||
double critical_value;
|
||||
bool check_warn;
|
||||
bool check_crit;
|
||||
int check_variable;
|
||||
int status;
|
||||
bool temp_output_c;
|
||||
} ups_config;
|
||||
|
||||
ups_config ups_config_init(void) {
|
||||
ups_config tmp = {0};
|
||||
tmp.server_port = PORT;
|
||||
tmp.server_address = NULL;
|
||||
tmp.ups_name = NULL;
|
||||
tmp.check_variable = UPS_NONE;
|
||||
tmp.status = UPSSTATUS_NONE;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// Forward declarations
|
||||
static int determine_status(ups_config * /*config*/, int *supported_options);
|
||||
static int get_ups_variable(const char * /*varname*/, char * /*buf*/, ups_config config);
|
||||
typedef struct {
|
||||
int errorcode;
|
||||
int ups_status;
|
||||
int supported_options;
|
||||
} determine_status_result;
|
||||
static determine_status_result determine_status(check_ups_config /*config*/);
|
||||
static int get_ups_variable(const char * /*varname*/, char * /*buf*/, check_ups_config config);
|
||||
|
||||
typedef struct {
|
||||
int errorcode;
|
||||
check_ups_config config;
|
||||
} check_ups_config_wrapper;
|
||||
static check_ups_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
static check_ups_config_wrapper validate_arguments(check_ups_config_wrapper /*config_wrapper*/);
|
||||
|
||||
static int process_arguments(int /*argc*/, char ** /*argv*/, ups_config * /*config*/);
|
||||
static int validate_arguments(ups_config /*config*/);
|
||||
static void print_help(void);
|
||||
void print_usage(void);
|
||||
|
||||
|
|
@ -109,28 +69,16 @@ int main(int argc, char **argv) {
|
|||
setlocale(LC_ALL, "");
|
||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
textdomain(PACKAGE);
|
||||
|
||||
char *ups_status;
|
||||
ups_status = strdup("N/A");
|
||||
|
||||
char *data;
|
||||
data = strdup("");
|
||||
|
||||
char *message;
|
||||
message = strdup("");
|
||||
|
||||
// Exit result
|
||||
int result = STATE_UNKNOWN;
|
||||
|
||||
/* Parse extra opts if any */
|
||||
argv = np_extra_opts(&argc, argv, progname);
|
||||
|
||||
// Config from commandline
|
||||
ups_config config = ups_config_init();
|
||||
check_ups_config_wrapper tmp_config = process_arguments(argc, argv);
|
||||
|
||||
if (process_arguments(argc, argv, &config) == ERROR) {
|
||||
if (tmp_config.errorcode == ERROR) {
|
||||
usage4(_("Could not parse arguments"));
|
||||
}
|
||||
// Config from commandline
|
||||
check_ups_config config = tmp_config.config;
|
||||
|
||||
/* initialize alarm signal handling */
|
||||
signal(SIGALRM, socket_timeout_alarm_handler);
|
||||
|
|
@ -138,71 +86,75 @@ int main(int argc, char **argv) {
|
|||
/* set socket timeout */
|
||||
alarm(socket_timeout);
|
||||
|
||||
int supported_options = UPS_NONE;
|
||||
|
||||
/* get the ups status if possible */
|
||||
if (determine_status(&config, &supported_options) != OK) {
|
||||
determine_status_result query_result = determine_status(config);
|
||||
if (query_result.errorcode != OK) {
|
||||
return STATE_CRITICAL;
|
||||
}
|
||||
|
||||
int ups_status_flags = query_result.ups_status;
|
||||
int supported_options = query_result.supported_options;
|
||||
|
||||
// Exit result
|
||||
mp_state_enum result = STATE_UNKNOWN;
|
||||
char *message = NULL;
|
||||
|
||||
if (supported_options & UPS_STATUS) {
|
||||
|
||||
ups_status = strdup("");
|
||||
|
||||
char *ups_status = strdup("");
|
||||
result = STATE_OK;
|
||||
|
||||
if (config.status & UPSSTATUS_OFF) {
|
||||
if (ups_status_flags & UPSSTATUS_OFF) {
|
||||
xasprintf(&ups_status, "Off");
|
||||
result = STATE_CRITICAL;
|
||||
} else if ((config.status & (UPSSTATUS_OB | UPSSTATUS_LB)) == (UPSSTATUS_OB | UPSSTATUS_LB)) {
|
||||
} else if ((ups_status_flags & (UPSSTATUS_OB | UPSSTATUS_LB)) == (UPSSTATUS_OB | UPSSTATUS_LB)) {
|
||||
xasprintf(&ups_status, _("On Battery, Low Battery"));
|
||||
result = STATE_CRITICAL;
|
||||
} else {
|
||||
if (config.status & UPSSTATUS_OL) {
|
||||
if (ups_status_flags & UPSSTATUS_OL) {
|
||||
xasprintf(&ups_status, "%s%s", ups_status, _("Online"));
|
||||
}
|
||||
if (config.status & UPSSTATUS_OB) {
|
||||
if (ups_status_flags & UPSSTATUS_OB) {
|
||||
xasprintf(&ups_status, "%s%s", ups_status, _("On Battery"));
|
||||
result = max_state(result, STATE_WARNING);
|
||||
}
|
||||
if (config.status & UPSSTATUS_LB) {
|
||||
if (ups_status_flags & UPSSTATUS_LB) {
|
||||
xasprintf(&ups_status, "%s%s", ups_status, _(", Low Battery"));
|
||||
result = max_state(result, STATE_WARNING);
|
||||
}
|
||||
if (config.status & UPSSTATUS_CAL) {
|
||||
if (ups_status_flags & UPSSTATUS_CAL) {
|
||||
xasprintf(&ups_status, "%s%s", ups_status, _(", Calibrating"));
|
||||
}
|
||||
if (config.status & UPSSTATUS_RB) {
|
||||
if (ups_status_flags & UPSSTATUS_RB) {
|
||||
xasprintf(&ups_status, "%s%s", ups_status, _(", Replace Battery"));
|
||||
result = max_state(result, STATE_WARNING);
|
||||
}
|
||||
if (config.status & UPSSTATUS_BYPASS) {
|
||||
if (ups_status_flags & UPSSTATUS_BYPASS) {
|
||||
xasprintf(&ups_status, "%s%s", ups_status, _(", On Bypass"));
|
||||
// Bypassing the battery is likely a bad thing
|
||||
result = STATE_CRITICAL;
|
||||
}
|
||||
if (config.status & UPSSTATUS_OVER) {
|
||||
if (ups_status_flags & UPSSTATUS_OVER) {
|
||||
xasprintf(&ups_status, "%s%s", ups_status, _(", Overload"));
|
||||
result = max_state(result, STATE_WARNING);
|
||||
}
|
||||
if (config.status & UPSSTATUS_TRIM) {
|
||||
if (ups_status_flags & UPSSTATUS_TRIM) {
|
||||
xasprintf(&ups_status, "%s%s", ups_status, _(", Trimming"));
|
||||
}
|
||||
if (config.status & UPSSTATUS_BOOST) {
|
||||
if (ups_status_flags & UPSSTATUS_BOOST) {
|
||||
xasprintf(&ups_status, "%s%s", ups_status, _(", Boosting"));
|
||||
}
|
||||
if (config.status & UPSSTATUS_CHRG) {
|
||||
if (ups_status_flags & UPSSTATUS_CHRG) {
|
||||
xasprintf(&ups_status, "%s%s", ups_status, _(", Charging"));
|
||||
}
|
||||
if (config.status & UPSSTATUS_DISCHRG) {
|
||||
if (ups_status_flags & UPSSTATUS_DISCHRG) {
|
||||
xasprintf(&ups_status, "%s%s", ups_status, _(", Discharging"));
|
||||
result = max_state(result, STATE_WARNING);
|
||||
}
|
||||
if (config.status & UPSSTATUS_ALARM) {
|
||||
if (ups_status_flags & UPSSTATUS_ALARM) {
|
||||
xasprintf(&ups_status, "%s%s", ups_status, _(", ALARM"));
|
||||
result = STATE_CRITICAL;
|
||||
}
|
||||
if (config.status & UPSSTATUS_UNKNOWN) {
|
||||
if (ups_status_flags & UPSSTATUS_UNKNOWN) {
|
||||
xasprintf(&ups_status, "%s%s", ups_status, _(", Unknown"));
|
||||
}
|
||||
}
|
||||
|
|
@ -211,7 +163,7 @@ int main(int argc, char **argv) {
|
|||
|
||||
int res;
|
||||
char temp_buffer[MAX_INPUT_BUFFER];
|
||||
|
||||
char *performance_data = strdup("");
|
||||
/* get the ups utility voltage if possible */
|
||||
res = get_ups_variable("input.voltage", temp_buffer, config);
|
||||
if (res == NOSUCHVAR) {
|
||||
|
|
@ -239,11 +191,12 @@ int main(int argc, char **argv) {
|
|||
} else if (config.check_warn && ups_utility_deviation >= config.warning_value) {
|
||||
result = max_state(result, STATE_WARNING);
|
||||
}
|
||||
xasprintf(&data, "%s",
|
||||
xasprintf(&performance_data, "%s",
|
||||
perfdata("voltage", (long)(1000 * ups_utility_voltage), "mV", config.check_warn, (long)(1000 * config.warning_value),
|
||||
config.check_crit, (long)(1000 * config.critical_value), true, 0, false, 0));
|
||||
} else {
|
||||
xasprintf(&data, "%s", perfdata("voltage", (long)(1000 * ups_utility_voltage), "mV", false, 0, false, 0, true, 0, false, 0));
|
||||
xasprintf(&performance_data, "%s",
|
||||
perfdata("voltage", (long)(1000 * ups_utility_voltage), "mV", false, 0, false, 0, true, 0, false, 0));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -266,11 +219,12 @@ int main(int argc, char **argv) {
|
|||
} else if (config.check_warn && ups_battery_percent <= config.warning_value) {
|
||||
result = max_state(result, STATE_WARNING);
|
||||
}
|
||||
xasprintf(&data, "%s %s", data,
|
||||
xasprintf(&performance_data, "%s %s", performance_data,
|
||||
perfdata("battery", (long)ups_battery_percent, "%", config.check_warn, (long)(config.warning_value),
|
||||
config.check_crit, (long)(config.critical_value), true, 0, true, 100));
|
||||
} else {
|
||||
xasprintf(&data, "%s %s", data, perfdata("battery", (long)ups_battery_percent, "%", false, 0, false, 0, true, 0, true, 100));
|
||||
xasprintf(&performance_data, "%s %s", performance_data,
|
||||
perfdata("battery", (long)ups_battery_percent, "%", false, 0, false, 0, true, 0, true, 100));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -293,11 +247,12 @@ int main(int argc, char **argv) {
|
|||
} else if (config.check_warn && ups_load_percent >= config.warning_value) {
|
||||
result = max_state(result, STATE_WARNING);
|
||||
}
|
||||
xasprintf(&data, "%s %s", data,
|
||||
xasprintf(&performance_data, "%s %s", performance_data,
|
||||
perfdata("load", (long)ups_load_percent, "%", config.check_warn, (long)(config.warning_value), config.check_crit,
|
||||
(long)(config.critical_value), true, 0, true, 100));
|
||||
} else {
|
||||
xasprintf(&data, "%s %s", data, perfdata("load", (long)ups_load_percent, "%", false, 0, false, 0, true, 0, true, 100));
|
||||
xasprintf(&performance_data, "%s %s", performance_data,
|
||||
perfdata("load", (long)ups_load_percent, "%", false, 0, false, 0, true, 0, true, 100));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -329,11 +284,12 @@ int main(int argc, char **argv) {
|
|||
} else if (config.check_warn && ups_temperature >= config.warning_value) {
|
||||
result = max_state(result, STATE_WARNING);
|
||||
}
|
||||
xasprintf(&data, "%s %s", data,
|
||||
xasprintf(&performance_data, "%s %s", performance_data,
|
||||
perfdata("temp", (long)ups_temperature, tunits, config.check_warn, (long)(config.warning_value), config.check_crit,
|
||||
(long)(config.critical_value), true, 0, false, 0));
|
||||
} else {
|
||||
xasprintf(&data, "%s %s", data, perfdata("temp", (long)ups_temperature, tunits, false, 0, false, 0, true, 0, false, 0));
|
||||
xasprintf(&performance_data, "%s %s", performance_data,
|
||||
perfdata("temp", (long)ups_temperature, tunits, false, 0, false, 0, true, 0, false, 0));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -355,11 +311,12 @@ int main(int argc, char **argv) {
|
|||
} else if (config.check_warn && ups_realpower >= config.warning_value) {
|
||||
result = max_state(result, STATE_WARNING);
|
||||
}
|
||||
xasprintf(&data, "%s %s", data,
|
||||
xasprintf(&performance_data, "%s %s", performance_data,
|
||||
perfdata("realpower", (long)ups_realpower, "W", config.check_warn, (long)(config.warning_value), config.check_crit,
|
||||
(long)(config.critical_value), true, 0, false, 0));
|
||||
} else {
|
||||
xasprintf(&data, "%s %s", data, perfdata("realpower", (long)ups_realpower, "W", false, 0, false, 0, true, 0, false, 0));
|
||||
xasprintf(&performance_data, "%s %s", performance_data,
|
||||
perfdata("realpower", (long)ups_realpower, "W", false, 0, false, 0, true, 0, false, 0));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -373,66 +330,73 @@ int main(int argc, char **argv) {
|
|||
/* reset timeout */
|
||||
alarm(0);
|
||||
|
||||
printf("UPS %s - %s|%s\n", state_text(result), message, data);
|
||||
return result;
|
||||
printf("UPS %s - %s|%s\n", state_text(result), message, performance_data);
|
||||
exit(result);
|
||||
}
|
||||
|
||||
/* determines what options are supported by the UPS */
|
||||
int determine_status(ups_config *config, int *supported_options) {
|
||||
char recv_buffer[MAX_INPUT_BUFFER];
|
||||
determine_status_result determine_status(const check_ups_config config) {
|
||||
|
||||
int res = get_ups_variable("ups.status", recv_buffer, *config);
|
||||
determine_status_result result = {
|
||||
.errorcode = OK,
|
||||
.ups_status = UPSSTATUS_NONE,
|
||||
.supported_options = 0,
|
||||
};
|
||||
|
||||
char recv_buffer[MAX_INPUT_BUFFER];
|
||||
int res = get_ups_variable("ups.status", recv_buffer, config);
|
||||
if (res == NOSUCHVAR) {
|
||||
return OK;
|
||||
return result;
|
||||
}
|
||||
|
||||
if (res != STATE_OK) {
|
||||
printf("%s\n", _("Invalid response received from host"));
|
||||
return ERROR;
|
||||
result.errorcode = ERROR;
|
||||
return result;
|
||||
}
|
||||
|
||||
*supported_options |= UPS_STATUS;
|
||||
result.supported_options |= UPS_STATUS;
|
||||
|
||||
char temp_buffer[MAX_INPUT_BUFFER];
|
||||
|
||||
strcpy(temp_buffer, recv_buffer);
|
||||
for (char *ptr = (char *)strtok(temp_buffer, " "); ptr != NULL; ptr = (char *)strtok(NULL, " ")) {
|
||||
for (char *ptr = strtok(temp_buffer, " "); ptr != NULL; ptr = strtok(NULL, " ")) {
|
||||
if (!strcmp(ptr, "OFF")) {
|
||||
config->status |= UPSSTATUS_OFF;
|
||||
result.ups_status |= UPSSTATUS_OFF;
|
||||
} else if (!strcmp(ptr, "OL")) {
|
||||
config->status |= UPSSTATUS_OL;
|
||||
result.ups_status |= UPSSTATUS_OL;
|
||||
} else if (!strcmp(ptr, "OB")) {
|
||||
config->status |= UPSSTATUS_OB;
|
||||
result.ups_status |= UPSSTATUS_OB;
|
||||
} else if (!strcmp(ptr, "LB")) {
|
||||
config->status |= UPSSTATUS_LB;
|
||||
result.ups_status |= UPSSTATUS_LB;
|
||||
} else if (!strcmp(ptr, "CAL")) {
|
||||
config->status |= UPSSTATUS_CAL;
|
||||
result.ups_status |= UPSSTATUS_CAL;
|
||||
} else if (!strcmp(ptr, "RB")) {
|
||||
config->status |= UPSSTATUS_RB;
|
||||
result.ups_status |= UPSSTATUS_RB;
|
||||
} else if (!strcmp(ptr, "BYPASS")) {
|
||||
config->status |= UPSSTATUS_BYPASS;
|
||||
result.ups_status |= UPSSTATUS_BYPASS;
|
||||
} else if (!strcmp(ptr, "OVER")) {
|
||||
config->status |= UPSSTATUS_OVER;
|
||||
result.ups_status |= UPSSTATUS_OVER;
|
||||
} else if (!strcmp(ptr, "TRIM")) {
|
||||
config->status |= UPSSTATUS_TRIM;
|
||||
result.ups_status |= UPSSTATUS_TRIM;
|
||||
} else if (!strcmp(ptr, "BOOST")) {
|
||||
config->status |= UPSSTATUS_BOOST;
|
||||
result.ups_status |= UPSSTATUS_BOOST;
|
||||
} else if (!strcmp(ptr, "CHRG")) {
|
||||
config->status |= UPSSTATUS_CHRG;
|
||||
result.ups_status |= UPSSTATUS_CHRG;
|
||||
} else if (!strcmp(ptr, "DISCHRG")) {
|
||||
config->status |= UPSSTATUS_DISCHRG;
|
||||
result.ups_status |= UPSSTATUS_DISCHRG;
|
||||
} else if (!strcmp(ptr, "ALARM")) {
|
||||
config->status |= UPSSTATUS_ALARM;
|
||||
result.ups_status |= UPSSTATUS_ALARM;
|
||||
} else {
|
||||
config->status |= UPSSTATUS_UNKNOWN;
|
||||
result.ups_status |= UPSSTATUS_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* gets a variable value for a specific UPS */
|
||||
int get_ups_variable(const char *varname, char *buf, const ups_config config) {
|
||||
int get_ups_variable(const char *varname, char *buf, const check_ups_config config) {
|
||||
char send_buffer[MAX_INPUT_BUFFER];
|
||||
|
||||
/* create the command string to send to the UPS daemon */
|
||||
|
|
@ -500,7 +464,7 @@ int get_ups_variable(const char *varname, char *buf, const ups_config config) {
|
|||
[-wv warn_value] [-cv crit_value] [-to to_sec] */
|
||||
|
||||
/* process command-line arguments */
|
||||
int process_arguments(int argc, char **argv, ups_config *config) {
|
||||
check_ups_config_wrapper process_arguments(int argc, char **argv) {
|
||||
|
||||
static struct option longopts[] = {{"hostname", required_argument, 0, 'H'},
|
||||
{"ups", required_argument, 0, 'u'},
|
||||
|
|
@ -514,8 +478,14 @@ int process_arguments(int argc, char **argv, ups_config *config) {
|
|||
{"help", no_argument, 0, 'h'},
|
||||
{0, 0, 0, 0}};
|
||||
|
||||
check_ups_config_wrapper result = {
|
||||
.errorcode = OK,
|
||||
.config = check_ups_config_init(),
|
||||
};
|
||||
|
||||
if (argc < 2) {
|
||||
return ERROR;
|
||||
result.errorcode = ERROR;
|
||||
return result;
|
||||
}
|
||||
|
||||
int c;
|
||||
|
|
@ -542,52 +512,52 @@ int process_arguments(int argc, char **argv, ups_config *config) {
|
|||
usage5();
|
||||
case 'H': /* hostname */
|
||||
if (is_host(optarg)) {
|
||||
config->server_address = optarg;
|
||||
result.config.server_address = optarg;
|
||||
} else {
|
||||
usage2(_("Invalid hostname/address"), optarg);
|
||||
}
|
||||
break;
|
||||
case 'T': /* FIXME: to be improved (ie "-T C" for Celsius or "-T F" for
|
||||
Fahrenheit) */
|
||||
config->temp_output_c = true;
|
||||
result.config.temp_output_c = true;
|
||||
break;
|
||||
case 'u': /* ups name */
|
||||
config->ups_name = optarg;
|
||||
result.config.ups_name = optarg;
|
||||
break;
|
||||
case 'p': /* port */
|
||||
if (is_intpos(optarg)) {
|
||||
config->server_port = atoi(optarg);
|
||||
result.config.server_port = atoi(optarg);
|
||||
} else {
|
||||
usage2(_("Port must be a positive integer"), optarg);
|
||||
}
|
||||
break;
|
||||
case 'c': /* critical time threshold */
|
||||
if (is_intnonneg(optarg)) {
|
||||
config->critical_value = atoi(optarg);
|
||||
config->check_crit = true;
|
||||
result.config.critical_value = atoi(optarg);
|
||||
result.config.check_crit = true;
|
||||
} else {
|
||||
usage2(_("Critical time must be a positive integer"), optarg);
|
||||
}
|
||||
break;
|
||||
case 'w': /* warning time threshold */
|
||||
if (is_intnonneg(optarg)) {
|
||||
config->warning_value = atoi(optarg);
|
||||
config->check_warn = true;
|
||||
result.config.warning_value = atoi(optarg);
|
||||
result.config.check_warn = true;
|
||||
} else {
|
||||
usage2(_("Warning time must be a positive integer"), optarg);
|
||||
}
|
||||
break;
|
||||
case 'v': /* variable */
|
||||
if (!strcmp(optarg, "LINE")) {
|
||||
config->check_variable = UPS_UTILITY;
|
||||
result.config.check_variable = UPS_UTILITY;
|
||||
} else if (!strcmp(optarg, "TEMP")) {
|
||||
config->check_variable = UPS_TEMP;
|
||||
result.config.check_variable = UPS_TEMP;
|
||||
} else if (!strcmp(optarg, "BATTPCT")) {
|
||||
config->check_variable = UPS_BATTPCT;
|
||||
result.config.check_variable = UPS_BATTPCT;
|
||||
} else if (!strcmp(optarg, "LOADPCT")) {
|
||||
config->check_variable = UPS_LOADPCT;
|
||||
result.config.check_variable = UPS_LOADPCT;
|
||||
} else if (!strcmp(optarg, "REALPOWER")) {
|
||||
config->check_variable = UPS_REALPOWER;
|
||||
result.config.check_variable = UPS_REALPOWER;
|
||||
} else {
|
||||
usage2(_("Unrecognized UPS variable"), optarg);
|
||||
}
|
||||
|
|
@ -608,27 +578,27 @@ int process_arguments(int argc, char **argv, ups_config *config) {
|
|||
}
|
||||
}
|
||||
|
||||
if (config->server_address == NULL && argc > optind) {
|
||||
if (result.config.server_address == NULL && argc > optind) {
|
||||
if (is_host(argv[optind])) {
|
||||
config->server_address = argv[optind++];
|
||||
result.config.server_address = argv[optind++];
|
||||
} else {
|
||||
usage2(_("Invalid hostname/address"), optarg);
|
||||
}
|
||||
}
|
||||
|
||||
if (config->server_address == NULL) {
|
||||
config->server_address = strdup("127.0.0.1");
|
||||
if (result.config.server_address == NULL) {
|
||||
result.config.server_address = strdup("127.0.0.1");
|
||||
}
|
||||
|
||||
return validate_arguments(*config);
|
||||
return validate_arguments(result);
|
||||
}
|
||||
|
||||
int validate_arguments(ups_config config) {
|
||||
if (!config.ups_name) {
|
||||
check_ups_config_wrapper validate_arguments(check_ups_config_wrapper config_wrapper) {
|
||||
if (config_wrapper.config.ups_name) {
|
||||
printf("%s\n", _("Error : no UPS indicated"));
|
||||
return ERROR;
|
||||
config_wrapper.errorcode = ERROR;
|
||||
}
|
||||
return OK;
|
||||
return config_wrapper;
|
||||
}
|
||||
|
||||
void print_help(void) {
|
||||
|
|
|
|||
55
plugins/check_ups.d/config.h
Normal file
55
plugins/check_ups.d/config.h
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../config.h"
|
||||
#include <stddef.h>
|
||||
|
||||
#define UPS_NONE 0 /* no supported options */
|
||||
#define UPS_UTILITY 1 /* supports utility line */
|
||||
#define UPS_BATTPCT 2 /* supports percent battery remaining */
|
||||
#define UPS_STATUS 4 /* supports UPS status */
|
||||
#define UPS_TEMP 8 /* supports UPS temperature */
|
||||
#define UPS_LOADPCT 16 /* supports load percent */
|
||||
#define UPS_REALPOWER 32 /* supports real power */
|
||||
|
||||
#define UPSSTATUS_NONE 0
|
||||
#define UPSSTATUS_OFF 1
|
||||
#define UPSSTATUS_OL 2
|
||||
#define UPSSTATUS_OB 4
|
||||
#define UPSSTATUS_LB 8
|
||||
#define UPSSTATUS_CAL 16
|
||||
#define UPSSTATUS_RB 32 /*Replace Battery */
|
||||
#define UPSSTATUS_BYPASS 64
|
||||
#define UPSSTATUS_OVER 128
|
||||
#define UPSSTATUS_TRIM 256
|
||||
#define UPSSTATUS_BOOST 512
|
||||
#define UPSSTATUS_CHRG 1024
|
||||
#define UPSSTATUS_DISCHRG 2048
|
||||
#define UPSSTATUS_UNKNOWN 4096
|
||||
#define UPSSTATUS_ALARM 8192
|
||||
|
||||
enum {
|
||||
PORT = 3493
|
||||
};
|
||||
|
||||
typedef struct ups_config {
|
||||
unsigned int server_port;
|
||||
char *server_address;
|
||||
char *ups_name;
|
||||
double warning_value;
|
||||
double critical_value;
|
||||
bool check_warn;
|
||||
bool check_crit;
|
||||
int check_variable;
|
||||
bool temp_output_c;
|
||||
} check_ups_config;
|
||||
|
||||
check_ups_config check_ups_config_init(void) {
|
||||
check_ups_config tmp = {0};
|
||||
tmp.server_port = PORT;
|
||||
tmp.server_address = NULL;
|
||||
tmp.ups_name = NULL;
|
||||
tmp.check_variable = UPS_NONE;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
|
@ -38,21 +38,18 @@ const char *email = "devel@monitoring-plugins.org";
|
|||
#include "common.h"
|
||||
#include "utils.h"
|
||||
#include "utils_cmd.h"
|
||||
#include "negate.d/config.h"
|
||||
#include "../lib/states.h"
|
||||
|
||||
#include <ctype.h>
|
||||
typedef struct {
|
||||
int errorcode;
|
||||
negate_config config;
|
||||
} negate_config_wrapper;
|
||||
static negate_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
static negate_config_wrapper validate_arguments(negate_config_wrapper /*config_wrapper*/);
|
||||
|
||||
static const char **process_arguments(int /*argc*/, char ** /*argv*/);
|
||||
static void validate_arguments(char ** /*command_line*/);
|
||||
static void print_help(void);
|
||||
void print_usage(void);
|
||||
static bool subst_text = false;
|
||||
|
||||
static int state[4] = {
|
||||
STATE_OK,
|
||||
STATE_WARNING,
|
||||
STATE_CRITICAL,
|
||||
STATE_UNKNOWN,
|
||||
};
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
setlocale(LC_ALL, "");
|
||||
|
|
@ -61,15 +58,24 @@ int main(int argc, char **argv) {
|
|||
|
||||
timeout_interval = DEFAULT_TIMEOUT;
|
||||
|
||||
char **command_line = (char **)process_arguments(argc, argv);
|
||||
negate_config_wrapper tmp_config = process_arguments(argc, argv);
|
||||
|
||||
if (tmp_config.errorcode == ERROR) {
|
||||
die(STATE_UNKNOWN, _("negate: Failed to parse input"));
|
||||
}
|
||||
|
||||
negate_config config = tmp_config.config;
|
||||
|
||||
char **command_line = config.command_line;
|
||||
|
||||
/* Set signal handling and alarm */
|
||||
if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR)
|
||||
if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) {
|
||||
die(STATE_UNKNOWN, _("Cannot catch SIGALRM"));
|
||||
}
|
||||
|
||||
(void)alarm((unsigned)timeout_interval);
|
||||
(void)alarm(timeout_interval);
|
||||
|
||||
int result = STATE_UNKNOWN;
|
||||
mp_state_enum result = STATE_UNKNOWN;
|
||||
output chld_out;
|
||||
output chld_err;
|
||||
|
||||
|
|
@ -86,46 +92,52 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
/* Return UNKNOWN or worse if no output is returned */
|
||||
if (chld_out.lines == 0)
|
||||
if (chld_out.lines == 0) {
|
||||
die(max_state_alt(result, STATE_UNKNOWN), _("No data returned from command\n"));
|
||||
}
|
||||
|
||||
char *sub;
|
||||
for (size_t i = 0; i < chld_out.lines; i++) {
|
||||
if (subst_text && result >= 0 && result <= 4 && result != state[result]) {
|
||||
if (config.subst_text && result >= 0 && result <= 4 && result != config.state[result]) {
|
||||
/* Loop over each match found */
|
||||
while ((sub = strstr(chld_out.line[i], state_text(result)))) {
|
||||
/* Terminate the first part and skip over the string we'll substitute */
|
||||
*sub = '\0';
|
||||
sub += strlen(state_text(result));
|
||||
/* then put everything back together */
|
||||
xasprintf(&chld_out.line[i], "%s%s%s", chld_out.line[i], state_text(state[result]), sub);
|
||||
xasprintf(&chld_out.line[i], "%s%s%s", chld_out.line[i], state_text(config.state[result]), sub);
|
||||
}
|
||||
}
|
||||
printf("%s\n", chld_out.line[i]);
|
||||
}
|
||||
|
||||
if (result >= 0 && result <= 4) {
|
||||
exit(state[result]);
|
||||
exit(config.state[result]);
|
||||
} else {
|
||||
exit(result);
|
||||
}
|
||||
}
|
||||
|
||||
/* process command-line arguments */
|
||||
static const char **process_arguments(int argc, char **argv) {
|
||||
static negate_config_wrapper process_arguments(int argc, char **argv) {
|
||||
static struct option longopts[] = {{"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'V'},
|
||||
{"timeout", required_argument, 0, 't'}, {"timeout-result", required_argument, 0, 'T'},
|
||||
{"ok", required_argument, 0, 'o'}, {"warning", required_argument, 0, 'w'},
|
||||
{"critical", required_argument, 0, 'c'}, {"unknown", required_argument, 0, 'u'},
|
||||
{"substitute", no_argument, 0, 's'}, {0, 0, 0, 0}};
|
||||
|
||||
negate_config_wrapper result = {
|
||||
.errorcode = OK,
|
||||
.config = negate_config_init(),
|
||||
};
|
||||
bool permute = true;
|
||||
while (true) {
|
||||
int option = 0;
|
||||
int option_char = getopt_long(argc, argv, "+hVt:T:o:w:c:u:s", longopts, &option);
|
||||
|
||||
if (option_char == -1 || option_char == EOF)
|
||||
if (option_char == -1 || option_char == EOF) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (option_char) {
|
||||
case '?': /* help */
|
||||
|
|
@ -139,58 +151,68 @@ static const char **process_arguments(int argc, char **argv) {
|
|||
print_revision(progname, NP_VERSION);
|
||||
exit(STATE_UNKNOWN);
|
||||
case 't': /* timeout period */
|
||||
if (!is_integer(optarg))
|
||||
if (!is_integer(optarg)) {
|
||||
usage2(_("Timeout interval must be a positive integer"), optarg);
|
||||
else
|
||||
} else {
|
||||
timeout_interval = atoi(optarg);
|
||||
}
|
||||
break;
|
||||
case 'T': /* Result to return on timeouts */
|
||||
if ((timeout_state = mp_translate_state(optarg)) == ERROR)
|
||||
if ((timeout_state = mp_translate_state(optarg)) == ERROR) {
|
||||
usage4(_("Timeout result must be a valid state name (OK, WARNING, CRITICAL, UNKNOWN) or integer (0-3)."));
|
||||
}
|
||||
break;
|
||||
case 'o': /* replacement for OK */
|
||||
if ((state[STATE_OK] = mp_translate_state(optarg)) == ERROR)
|
||||
if ((result.config.state[STATE_OK] = mp_translate_state(optarg)) == ERROR) {
|
||||
usage4(_("Ok must be a valid state name (OK, WARNING, CRITICAL, UNKNOWN) or integer (0-3)."));
|
||||
}
|
||||
permute = false;
|
||||
break;
|
||||
|
||||
case 'w': /* replacement for WARNING */
|
||||
if ((state[STATE_WARNING] = mp_translate_state(optarg)) == ERROR)
|
||||
if ((result.config.state[STATE_WARNING] = mp_translate_state(optarg)) == ERROR) {
|
||||
usage4(_("Warning must be a valid state name (OK, WARNING, CRITICAL, UNKNOWN) or integer (0-3)."));
|
||||
}
|
||||
permute = false;
|
||||
break;
|
||||
case 'c': /* replacement for CRITICAL */
|
||||
if ((state[STATE_CRITICAL] = mp_translate_state(optarg)) == ERROR)
|
||||
if ((result.config.state[STATE_CRITICAL] = mp_translate_state(optarg)) == ERROR) {
|
||||
usage4(_("Critical must be a valid state name (OK, WARNING, CRITICAL, UNKNOWN) or integer (0-3)."));
|
||||
}
|
||||
permute = false;
|
||||
break;
|
||||
case 'u': /* replacement for UNKNOWN */
|
||||
if ((state[STATE_UNKNOWN] = mp_translate_state(optarg)) == ERROR)
|
||||
if ((result.config.state[STATE_UNKNOWN] = mp_translate_state(optarg)) == ERROR) {
|
||||
usage4(_("Unknown must be a valid state name (OK, WARNING, CRITICAL, UNKNOWN) or integer (0-3)."));
|
||||
}
|
||||
permute = false;
|
||||
break;
|
||||
case 's': /* Substitute status text */
|
||||
subst_text = true;
|
||||
result.config.subst_text = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
validate_arguments(&argv[optind]);
|
||||
|
||||
if (permute) { /* No [owcu] switch specified, default to this */
|
||||
state[STATE_OK] = STATE_CRITICAL;
|
||||
state[STATE_CRITICAL] = STATE_OK;
|
||||
result.config.state[STATE_OK] = STATE_CRITICAL;
|
||||
result.config.state[STATE_CRITICAL] = STATE_OK;
|
||||
}
|
||||
|
||||
return (const char **)&argv[optind];
|
||||
result.config.command_line = &argv[optind];
|
||||
|
||||
return validate_arguments(result);
|
||||
}
|
||||
|
||||
void validate_arguments(char **command_line) {
|
||||
if (command_line[0] == NULL)
|
||||
negate_config_wrapper validate_arguments(negate_config_wrapper config_wrapper) {
|
||||
if (config_wrapper.config.command_line[0] == NULL) {
|
||||
usage4(_("Could not parse arguments"));
|
||||
}
|
||||
|
||||
if (strncmp(command_line[0], "/", 1) != 0 && strncmp(command_line[0], "./", 2) != 0)
|
||||
if (strncmp(config_wrapper.config.command_line[0], "/", 1) != 0 && strncmp(config_wrapper.config.command_line[0], "./", 2) != 0) {
|
||||
usage4(_("Require path to command"));
|
||||
}
|
||||
|
||||
return config_wrapper;
|
||||
}
|
||||
|
||||
void print_help(void) {
|
||||
|
|
|
|||
24
plugins/negate.d/config.h
Normal file
24
plugins/negate.d/config.h
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#pragma once
|
||||
|
||||
#include "states.h"
|
||||
|
||||
typedef struct {
|
||||
mp_state_enum state[4];
|
||||
bool subst_text;
|
||||
char **command_line;
|
||||
} negate_config;
|
||||
|
||||
negate_config negate_config_init() {
|
||||
negate_config tmp = {
|
||||
.state =
|
||||
{
|
||||
STATE_OK,
|
||||
STATE_WARNING,
|
||||
STATE_CRITICAL,
|
||||
STATE_UNKNOWN,
|
||||
},
|
||||
.subst_text = false,
|
||||
.command_line = NULL,
|
||||
};
|
||||
return tmp;
|
||||
}
|
||||
|
|
@ -28,6 +28,8 @@
|
|||
*****************************************************************************/
|
||||
|
||||
#include "common.h"
|
||||
#include "output.h"
|
||||
#include "states.h"
|
||||
#include "netutils.h"
|
||||
|
||||
unsigned int socket_timeout = DEFAULT_SOCKET_TIMEOUT;
|
||||
|
|
@ -43,12 +45,19 @@ int address_family = AF_INET;
|
|||
|
||||
/* handles socket timeouts */
|
||||
void socket_timeout_alarm_handler(int sig) {
|
||||
if (sig == SIGALRM)
|
||||
printf(_("%s - Socket timeout after %d seconds\n"), state_text(socket_timeout_state), socket_timeout);
|
||||
else
|
||||
printf(_("%s - Abnormal timeout after %d seconds\n"), state_text(socket_timeout_state), socket_timeout);
|
||||
mp_subcheck timeout_sc = mp_subcheck_init();
|
||||
timeout_sc = mp_set_subcheck_state(timeout_sc, socket_timeout_state);
|
||||
|
||||
exit(socket_timeout_state);
|
||||
if (sig == SIGALRM) {
|
||||
xasprintf(&timeout_sc.output, _("Socket timeout after %d seconds\n"), socket_timeout);
|
||||
} else {
|
||||
xasprintf(&timeout_sc.output, _("Abnormal timeout after %d seconds\n"), socket_timeout);
|
||||
}
|
||||
|
||||
mp_check overall = mp_check_init();
|
||||
mp_add_subcheck_to_check(&overall, timeout_sc);
|
||||
|
||||
mp_exit(overall);
|
||||
}
|
||||
|
||||
/* connects to a host on a specified tcp port, sends a string, and gets a
|
||||
|
|
@ -65,12 +74,13 @@ int process_tcp_request2(const char *server_address, int server_port, const char
|
|||
int recv_length = 0;
|
||||
|
||||
result = np_net_connect(server_address, server_port, &sd, IPPROTO_TCP);
|
||||
if (result != STATE_OK)
|
||||
if (result != STATE_OK) {
|
||||
return STATE_CRITICAL;
|
||||
}
|
||||
|
||||
send_result = send(sd, send_buffer, strlen(send_buffer), 0);
|
||||
if (send_result < 0 || (size_t)send_result != strlen(send_buffer)) {
|
||||
printf("%s\n", _("Send failed"));
|
||||
// printf("%s\n", _("Send failed"));
|
||||
result = STATE_WARNING;
|
||||
}
|
||||
|
||||
|
|
@ -87,7 +97,7 @@ int process_tcp_request2(const char *server_address, int server_port, const char
|
|||
if (!FD_ISSET(sd, &readfds)) { /* it hasn't */
|
||||
if (!recv_length) {
|
||||
strcpy(recv_buffer, "");
|
||||
printf("%s\n", _("No data was received from host!"));
|
||||
// printf("%s\n", _("No data was received from host!"));
|
||||
result = STATE_WARNING;
|
||||
} else { /* this one failed, but previous ones worked */
|
||||
recv_buffer[recv_length] = 0;
|
||||
|
|
@ -130,8 +140,9 @@ int process_request(const char *server_address, int server_port, int proto, cons
|
|||
result = STATE_OK;
|
||||
|
||||
result = np_net_connect(server_address, server_port, &sd, proto);
|
||||
if (result != STATE_OK)
|
||||
if (result != STATE_OK) {
|
||||
return STATE_CRITICAL;
|
||||
}
|
||||
|
||||
result = send_request(sd, proto, send_buffer, recv_buffer, recv_size);
|
||||
|
||||
|
|
@ -169,8 +180,9 @@ int np_net_connect(const char *host_name, int port, int *sd, int proto) {
|
|||
host_name++;
|
||||
len -= 2;
|
||||
}
|
||||
if (len >= sizeof(host))
|
||||
if (len >= sizeof(host)) {
|
||||
return STATE_UNKNOWN;
|
||||
}
|
||||
memcpy(host, host_name, len);
|
||||
host[len] = '\0';
|
||||
snprintf(port_str, sizeof(port_str), "%d", port);
|
||||
|
|
@ -226,13 +238,14 @@ int np_net_connect(const char *host_name, int port, int *sd, int proto) {
|
|||
die(STATE_UNKNOWN, _("Socket creation failed"));
|
||||
}
|
||||
result = connect(*sd, (struct sockaddr *)&su, sizeof(su));
|
||||
if (result < 0 && errno == ECONNREFUSED)
|
||||
if (result < 0 && errno == ECONNREFUSED) {
|
||||
was_refused = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (result == 0)
|
||||
if (result == 0) {
|
||||
return STATE_OK;
|
||||
else if (was_refused) {
|
||||
} else if (was_refused) {
|
||||
switch (econn_refuse_state) { /* a user-defined expected outcome */
|
||||
case STATE_OK:
|
||||
case STATE_WARNING: /* user wants WARN or OK on refusal, or... */
|
||||
|
|
@ -267,7 +280,7 @@ int send_request(int sd, int proto, const char *send_buffer, char *recv_buffer,
|
|||
|
||||
send_result = send(sd, send_buffer, strlen(send_buffer), 0);
|
||||
if (send_result < 0 || (size_t)send_result != strlen(send_buffer)) {
|
||||
printf("%s\n", _("Send failed"));
|
||||
// printf("%s\n", _("Send failed"));
|
||||
result = STATE_WARNING;
|
||||
}
|
||||
|
||||
|
|
@ -282,7 +295,7 @@ int send_request(int sd, int proto, const char *send_buffer, char *recv_buffer,
|
|||
/* make sure some data has arrived */
|
||||
if (!FD_ISSET(sd, &readfds)) {
|
||||
strcpy(recv_buffer, "");
|
||||
printf("%s\n", _("No data was received from host!"));
|
||||
// printf("%s\n", _("No data was received from host!"));
|
||||
result = STATE_WARNING;
|
||||
}
|
||||
|
||||
|
|
@ -290,11 +303,13 @@ int send_request(int sd, int proto, const char *send_buffer, char *recv_buffer,
|
|||
recv_result = recv(sd, recv_buffer, (size_t)recv_size - 1, 0);
|
||||
if (recv_result == -1) {
|
||||
strcpy(recv_buffer, "");
|
||||
if (proto != IPPROTO_TCP)
|
||||
printf("%s\n", _("Receive failed"));
|
||||
if (proto != IPPROTO_TCP) {
|
||||
// printf("%s\n", _("Receive failed"));
|
||||
}
|
||||
result = STATE_WARNING;
|
||||
} else
|
||||
} else {
|
||||
recv_buffer[recv_result] = 0;
|
||||
}
|
||||
|
||||
/* die returned string */
|
||||
recv_buffer[recv_size - 1] = 0;
|
||||
|
|
@ -303,26 +318,30 @@ int send_request(int sd, int proto, const char *send_buffer, char *recv_buffer,
|
|||
}
|
||||
|
||||
bool is_host(const char *address) {
|
||||
if (is_addr(address) || is_hostname(address))
|
||||
if (is_addr(address) || is_hostname(address)) {
|
||||
return (true);
|
||||
}
|
||||
|
||||
return (false);
|
||||
}
|
||||
|
||||
void host_or_die(const char *str) {
|
||||
if (!str || (!is_addr(str) && !is_hostname(str)))
|
||||
if (!str || (!is_addr(str) && !is_hostname(str))) {
|
||||
usage_va(_("Invalid hostname/address - %s"), str);
|
||||
}
|
||||
}
|
||||
|
||||
bool is_addr(const char *address) {
|
||||
#ifdef USE_IPV6
|
||||
if (address_family == AF_INET && is_inet_addr(address))
|
||||
if (address_family == AF_INET && is_inet_addr(address)) {
|
||||
return true;
|
||||
else if (address_family == AF_INET6 && is_inet6_addr(address))
|
||||
} else if (address_family == AF_INET6 && is_inet6_addr(address)) {
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
if (is_inet_addr(address))
|
||||
if (is_inet_addr(address)) {
|
||||
return (true);
|
||||
}
|
||||
#endif
|
||||
|
||||
return (false);
|
||||
|
|
@ -337,11 +356,13 @@ int dns_lookup(const char *in, struct sockaddr_storage *ss, int family) {
|
|||
hints.ai_family = family;
|
||||
|
||||
retval = getaddrinfo(in, NULL, &hints, &res);
|
||||
if (retval != 0)
|
||||
if (retval != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ss != NULL)
|
||||
if (ss != NULL) {
|
||||
memcpy(ss, res->ai_addr, res->ai_addrlen);
|
||||
}
|
||||
freeaddrinfo(res);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ $res = NPTest->testCmd(
|
|||
"./$plugin $host_nonresponsive -wt 1 -ct 2 -t 3"
|
||||
);
|
||||
cmp_ok( $res->return_code, '==', 2, "Webserver $host_nonresponsive not responding" );
|
||||
cmp_ok( $res->output, 'eq', "CRITICAL - Socket timeout after 3 seconds", "Output OK");
|
||||
like( $res->output, "/Socket timeout after/", "Output OK");
|
||||
|
||||
$res = NPTest->testCmd(
|
||||
"./$plugin $hostname_invalid -wt 1 -ct 2"
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ my $hostname_invalid = getTestParameter("NP_HOSTNAME_INVALID", "An invalid (no
|
|||
|
||||
my $jabberOK = '/JABBER OK\s-\s\d+\.\d+\ssecond response time on '.$host_tcp_jabber.' port 5222/';
|
||||
|
||||
my $jabberUnresponsive = '/CRITICAL\s-\sSocket timeout after\s\d+\sseconds/';
|
||||
my $jabberUnresponsive = '/Socket timeout after\s\d+\sseconds/';
|
||||
|
||||
my $jabberInvalid = '/JABBER CRITICAL - Invalid hostname, address or socket:\s.+/';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ SKIP: {
|
|||
|
||||
$result = NPTest->testCmd("$command -H $host_nonresponsive -b ou=blah -t 2 -w 1 -c 1");
|
||||
is( $result->return_code, 2, "$command -H $host_nonresponsive -b ou=blah -t 5 -w 2 -c 3" );
|
||||
is( $result->output, 'CRITICAL - Socket timeout after 2 seconds', "output ok" );
|
||||
like($result->output, '/Socket timeout after \d+ seconds/', "output ok" );
|
||||
};
|
||||
|
||||
SKIP: {
|
||||
|
|
|
|||
|
|
@ -21,11 +21,11 @@ plan skip_all => "check_mysql not compiled" unless (-x "check_mysql");
|
|||
plan tests => 15;
|
||||
|
||||
my $bad_login_output = '/Access denied for user /';
|
||||
my $mysqlserver = getTestParameter("NP_MYSQL_SERVER", "A MySQL Server hostname or IP with no slaves setup");
|
||||
my $mysqlsocket = getTestParameter("NP_MYSQL_SOCKET", "Full path to a MySQL Server socket with no slaves setup");
|
||||
my $mysqlserver = getTestParameter("NP_MYSQL_SERVER", "A MySQL Server hostname or IP with no replica setup");
|
||||
my $mysqlsocket = getTestParameter("NP_MYSQL_SOCKET", "Full path to a MySQL Server socket with no replica setup");
|
||||
my $mysql_login_details = getTestParameter("NP_MYSQL_LOGIN_DETAILS", "Command line parameters to specify login access (requires REPLICATION CLIENT privileges)", "-u test -ptest");
|
||||
my $with_slave = getTestParameter("NP_MYSQL_WITH_SLAVE", "MySQL server with slaves setup");
|
||||
my $with_slave_login = getTestParameter("NP_MYSQL_WITH_SLAVE_LOGIN", "Login details for server with slave (requires REPLICATION CLIENT privileges)", $mysql_login_details || "-u test -ptest");
|
||||
my $with_replica = getTestParameter("NP_MYSQL_WITH_REPLICA", "MySQL server with replica setup");
|
||||
my $with_replica_login = getTestParameter("NP_MYSQL_WITH_REPLICA_LOGIN", "Login details for server with replica (requires REPLICATION CLIENT privileges)", $mysql_login_details || "-u test -ptest");
|
||||
|
||||
my $result;
|
||||
|
||||
|
|
@ -39,8 +39,8 @@ SKIP: {
|
|||
like( $result->output, $bad_login_output, "Expected login failure message");
|
||||
|
||||
$result = NPTest->testCmd("./check_mysql -S -H $mysqlserver $mysql_login_details");
|
||||
cmp_ok( $result->return_code, "==", 1, "No slaves defined" );
|
||||
like( $result->output, "/No slaves defined/", "Correct error message");
|
||||
cmp_ok( $result->return_code, "==", 1, "No replicas defined" );
|
||||
like( $result->output, "/No replicas defined/", "Correct error message");
|
||||
}
|
||||
|
||||
SKIP: {
|
||||
|
|
@ -53,22 +53,22 @@ SKIP: {
|
|||
like( $result->output, $bad_login_output, "Expected login failure message");
|
||||
|
||||
$result = NPTest->testCmd("./check_mysql -S -s $mysqlsocket $mysql_login_details");
|
||||
cmp_ok( $result->return_code, "==", 1, "No slaves defined" );
|
||||
like( $result->output, "/No slaves defined/", "Correct error message");
|
||||
cmp_ok( $result->return_code, "==", 1, "No replicas defined" );
|
||||
like( $result->output, "/No replicas defined/", "Correct error message");
|
||||
}
|
||||
|
||||
SKIP: {
|
||||
skip "No mysql server with slaves defined", 5 unless $with_slave;
|
||||
$result = NPTest->testCmd("./check_mysql -H $with_slave $with_slave_login");
|
||||
skip "No mysql server with replicas defined", 5 unless $with_replica;
|
||||
$result = NPTest->testCmd("./check_mysql -H $with_replica $with_replica_login");
|
||||
cmp_ok( $result->return_code, '==', 0, "Login okay");
|
||||
|
||||
$result = NPTest->testCmd("./check_mysql -S -H $with_slave $with_slave_login");
|
||||
cmp_ok( $result->return_code, "==", 0, "Slaves okay" );
|
||||
$result = NPTest->testCmd("./check_mysql -S -H $with_replica $with_replica_login");
|
||||
cmp_ok( $result->return_code, "==", 0, "Replicas okay" );
|
||||
|
||||
$result = NPTest->testCmd("./check_mysql -S -H $with_slave $with_slave_login -w 60");
|
||||
cmp_ok( $result->return_code, '==', 0, 'Slaves are not > 60 seconds behind');
|
||||
$result = NPTest->testCmd("./check_mysql -S -H $with_replica $with_replica_login -w 60");
|
||||
cmp_ok( $result->return_code, '==', 0, 'Replicas are not > 60 seconds behind');
|
||||
|
||||
$result = NPTest->testCmd("./check_mysql -S -H $with_slave $with_slave_login -w 60:");
|
||||
$result = NPTest->testCmd("./check_mysql -S -H $with_replica $with_replica_login -w 60:");
|
||||
cmp_ok( $result->return_code, '==', 1, 'Alert warning if < 60 seconds behind');
|
||||
like( $result->output, "/^SLOW_SLAVE WARNING:/", "Output okay");
|
||||
like( $result->output, "/^SLOW_REPLICA WARNING:/", "Output okay");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ my $ntp_critmatch1 = '/^NTP\sCRITICAL:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})?
|
|||
my $ntp_okmatch2 = '/^NTP\sOK:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})?\ssecs,\sjitter=[0-9]+\.[0-9]+,\sstratum=[0-9]{1,2},\struechimers=[0-9]+/';
|
||||
my $ntp_warnmatch2 = '/^NTP\sWARNING:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})?\ssecs,\sjitter=[0-9]+\.[0-9]+,\sstratum=[0-9]{1,2}\s\(WARNING\),\struechimers=[0-9]+/';
|
||||
my $ntp_critmatch2 = '/^NTP\sCRITICAL:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})?\ssecs,\sjitter=[0-9]+\.[0-9]+\s\(CRITICAL\),\sstratum=[0-9]{1,2},\struechimers=[0-9]+/';
|
||||
my $ntp_noresponse = '/^(CRITICAL - Socket timeout after 3 seconds)|(NTP CRITICAL: No response from NTP server)$/';
|
||||
my $ntp_noresponse = '/(.*Socket timeout after \d+ seconds.*)|(.*No response from NTP server.*)/';
|
||||
my $ntp_nosuchhost = '/^check_ntp.*: Invalid hostname/address - ' . $hostname_invalid . '/';
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ my $hostname_invalid = getTestParameter( "NP_HOSTNAME_INVALID",
|
|||
"An invalid (not known to DNS) hostname", "nosuchhost" );
|
||||
my $res;
|
||||
|
||||
plan tests => 16;
|
||||
plan tests => 15;
|
||||
|
||||
SKIP: {
|
||||
skip "No SMTP server defined", 4 unless $host_tcp_smtp;
|
||||
|
|
@ -73,7 +73,6 @@ SKIP: {
|
|||
my $unused_port = 4465;
|
||||
$res = NPTest->testCmd( "./check_smtp -H $host_tcp_smtp_tls -p $unused_port --ssl" );
|
||||
is ($res->return_code, 2, "Check rc of connecting to $host_tcp_smtp_tls with TLS on unused port $unused_port" );
|
||||
like ($res->output, qr/^connect to address $host_tcp_smtp_tls and port $unused_port: Connection refused/, "Check output of connecting to $host_tcp_smtp_tls with TLS on unused port $unused_port");
|
||||
}
|
||||
|
||||
$res = NPTest->testCmd( "./check_smtp $host_nonresponsive" );
|
||||
|
|
|
|||
|
|
@ -5,10 +5,10 @@
|
|||
#
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Test::More;
|
||||
use NPTest;
|
||||
|
||||
my $res;
|
||||
use JSON;
|
||||
|
||||
# Required parameters
|
||||
my $ssh_host = getTestParameter("NP_SSH_HOST",
|
||||
|
|
@ -23,30 +23,38 @@ my $hostname_invalid = getTestParameter("NP_HOSTNAME_INVALID",
|
|||
"An invalid (not known to DNS) hostname",
|
||||
"nosuchhost" );
|
||||
|
||||
my $outputFormat = '--output-format mp-test-json';
|
||||
|
||||
plan tests => 14 + 6;
|
||||
plan tests => 24;
|
||||
|
||||
my $output;
|
||||
my $result;
|
||||
|
||||
SKIP: {
|
||||
skip "SSH_HOST must be defined", 6 unless $ssh_host;
|
||||
|
||||
|
||||
my $result = NPTest->testCmd(
|
||||
"./check_ssh -H $ssh_host"
|
||||
"./check_ssh -H $ssh_host" ." ". $outputFormat
|
||||
);
|
||||
cmp_ok($result->return_code, '==', 0, "Exit with return code 0 (OK)");
|
||||
like($result->output, '/^SSH OK - /', "Status text if command returned none (OK)");
|
||||
$output = decode_json($result->output);
|
||||
is($output->{'state'}, "OK", "State was correct");
|
||||
|
||||
|
||||
$result = NPTest->testCmd(
|
||||
"./check_ssh -H $host_nonresponsive -t 2"
|
||||
"./check_ssh -H $host_nonresponsive -t 2" ." ". $outputFormat
|
||||
);
|
||||
cmp_ok($result->return_code, '==', 2, "Exit with return code 0 (OK)");
|
||||
like($result->output, '/^CRITICAL - Socket timeout after 2 seconds/', "Status text if command returned none (OK)");
|
||||
cmp_ok($result->return_code, '==', 0, "Exit with return code 0 (OK)");
|
||||
$output = decode_json($result->output);
|
||||
is($output->{'state'}, "CRITICAL", "State was correct");
|
||||
|
||||
|
||||
|
||||
$result = NPTest->testCmd(
|
||||
"./check_ssh -H $hostname_invalid -t 2"
|
||||
"./check_ssh -H $hostname_invalid -t 2" ." ". $outputFormat
|
||||
);
|
||||
cmp_ok($result->return_code, '==', 3, "Exit with return code 0 (OK)");
|
||||
cmp_ok($result->return_code, '==', 3, "Exit with return code 3 (UNKNOWN)");
|
||||
like($result->output, '/^check_ssh: Invalid hostname/', "Status text if command returned none (OK)");
|
||||
|
||||
|
||||
|
|
@ -63,46 +71,80 @@ SKIP: {
|
|||
#
|
||||
# where `comments` is optional, protoversion is the SSH protocol version and
|
||||
# softwareversion is an arbitrary string representing the server software version
|
||||
|
||||
my $found_version = 0;
|
||||
|
||||
open(NC, "echo 'SSH-2.0-nagiosplug.ssh.0.1' | nc ${nc_flags}|");
|
||||
sleep 0.1;
|
||||
$res = NPTest->testCmd( "./check_ssh -H localhost -p 5003" );
|
||||
cmp_ok( $res->return_code, '==', 0, "Got SSH protocol version control string");
|
||||
like( $res->output, '/^SSH OK - nagiosplug.ssh.0.1 \(protocol 2.0\)/', "Output OK");
|
||||
$result = NPTest->testCmd( "./check_ssh -H localhost -p 5003" ." ". $outputFormat);
|
||||
cmp_ok($result->return_code, '==', 0, "Exit with return code 0 (OK)");
|
||||
$output = decode_json($result->output);
|
||||
is($output->{'state'}, "OK", "State was correct");
|
||||
|
||||
# looking for the version
|
||||
for my $subcheck (@{$output->{'checks'}}) {
|
||||
if ($subcheck->{'output'} =~ /.*nagiosplug.ssh.0.1 \(protocol version: 2.0\).*/ ){
|
||||
$found_version = 1;
|
||||
}
|
||||
}
|
||||
cmp_ok($found_version, '==', 1, "Output OK");
|
||||
close NC;
|
||||
|
||||
open(NC, "echo 'SSH-2.0-3.2.9.1' | nc ${nc_flags}|");
|
||||
sleep 0.1;
|
||||
$res = NPTest->testCmd( "./check_ssh -H localhost -p 5003" );
|
||||
cmp_ok( $res->return_code, "==", 0, "Got SSH protocol version control string with non-alpha softwareversion string");
|
||||
like( $res->output, '/^SSH OK - 3.2.9.1 \(protocol 2.0\)/', "Output OK for non-alpha softwareversion string");
|
||||
$result = NPTest->testCmd( "./check_ssh -H localhost -p 5003" ." ". $outputFormat);
|
||||
cmp_ok($result->return_code, '==', 0, "Exit with return code 0 (OK)");
|
||||
$output = decode_json($result->output);
|
||||
is($output->{'state'}, "OK", "State was correct");
|
||||
|
||||
$found_version = 0;
|
||||
for my $subcheck (@{$output->{'checks'}}) {
|
||||
if ($subcheck->{'output'} =~ /3.2.9.1 \(protocol version: 2.0\)/ ){
|
||||
$found_version = 1;
|
||||
}
|
||||
}
|
||||
cmp_ok($found_version, '==', 1, "Output OK");
|
||||
close NC;
|
||||
|
||||
open(NC, "echo 'SSH-2.0-nagiosplug.ssh.0.1 this is a comment' | nc ${nc_flags} |");
|
||||
sleep 0.1;
|
||||
$res = NPTest->testCmd( "./check_ssh -H localhost -p 5003 -r nagiosplug.ssh.0.1" );
|
||||
cmp_ok( $res->return_code, '==', 0, "Got SSH protocol version control string, and parsed comment appropriately");
|
||||
like( $res->output, '/^SSH OK - nagiosplug.ssh.0.1 \(protocol 2.0\)/', "Output OK");
|
||||
$result = NPTest->testCmd( "./check_ssh -H localhost -p 5003 -r nagiosplug.ssh.0.1" ." ". $outputFormat);
|
||||
cmp_ok($result->return_code, '==', 0, "Exit with return code 0 (OK)");
|
||||
$output = decode_json($result->output);
|
||||
is($output->{'state'}, "OK", "State was correct");
|
||||
|
||||
# looking for the version
|
||||
$found_version = 0;
|
||||
for my $subcheck (@{$output->{'checks'}}) {
|
||||
if ($subcheck->{'output'} =~ /nagiosplug.ssh.0.1 \(protocol version: 2.0\)/ ){
|
||||
$found_version = 1;
|
||||
}
|
||||
}
|
||||
cmp_ok($found_version, '==', 1, "Output OK");
|
||||
close NC;
|
||||
|
||||
open(NC, "echo 'SSH-' | nc ${nc_flags}|");
|
||||
sleep 0.1;
|
||||
$res = NPTest->testCmd( "./check_ssh -H localhost -p 5003" );
|
||||
cmp_ok( $res->return_code, '==', 2, "Got invalid SSH protocol version control string");
|
||||
like( $res->output, '/^SSH CRITICAL/', "Output OK");
|
||||
$result = NPTest->testCmd( "./check_ssh -H localhost -p 5003" ." ". $outputFormat);
|
||||
cmp_ok($result->return_code, '==', 0, "Exit with return code 0 (OK)");
|
||||
$output = decode_json($result->output);
|
||||
is($output->{'state'}, "CRITICAL", "Got invalid SSH protocol version control string");
|
||||
close NC;
|
||||
|
||||
open(NC, "echo '' | nc ${nc_flags}|");
|
||||
sleep 0.1;
|
||||
$res = NPTest->testCmd( "./check_ssh -H localhost -p 5003" );
|
||||
cmp_ok( $res->return_code, '==', 2, "No version control string received");
|
||||
like( $res->output, '/^SSH CRITICAL - No version control string received/', "Output OK");
|
||||
$result = NPTest->testCmd( "./check_ssh -H localhost -p 5003" ." ". $outputFormat);
|
||||
cmp_ok($result->return_code, '==', 0, "Exit with return code 0 (OK)");
|
||||
$output = decode_json($result->output);
|
||||
is($output->{'state'}, "CRITICAL", "No version control string received");
|
||||
close NC;
|
||||
|
||||
open(NC, "echo 'Not a version control string' | nc ${nc_flags}|");
|
||||
sleep 0.1;
|
||||
$res = NPTest->testCmd( "./check_ssh -H localhost -p 5003" );
|
||||
cmp_ok( $res->return_code, '==', 2, "No version control string received");
|
||||
like( $res->output, '/^SSH CRITICAL - No version control string received/', "Output OK");
|
||||
$result = NPTest->testCmd( "./check_ssh -H localhost -p 5003" ." ". $outputFormat);
|
||||
cmp_ok($result->return_code, '==', 0, "Exit with return code 0 (OK)");
|
||||
$output = decode_json($result->output);
|
||||
is($output->{'state'}, "CRITICAL", "No version control string received");
|
||||
close NC;
|
||||
|
||||
|
||||
|
|
@ -116,8 +158,18 @@ SKIP: {
|
|||
echo 'Some\nPrepended\nData\nLines\n'; sleep 0.2;
|
||||
echo 'SSH-2.0-nagiosplug.ssh.0.2';} | nc ${nc_flags}|");
|
||||
sleep 0.1;
|
||||
$res = NPTest->testCmd( "./check_ssh -H localhost -p 5003" );
|
||||
cmp_ok( $res->return_code, '==', 0, "Got delayed SSH protocol version control string");
|
||||
like( $res->output, '/^SSH OK - nagiosplug.ssh.0.2 \(protocol 2.0\)/', "Output OK");
|
||||
$result = NPTest->testCmd( "./check_ssh -H localhost -p 5003" ." ". $outputFormat);
|
||||
cmp_ok($result->return_code, '==', 0, "Exit with return code 0 (OK)");
|
||||
$output = decode_json($result->output);
|
||||
is($output->{'state'}, "OK", "State was correct");
|
||||
|
||||
# looking for the version
|
||||
$found_version = 0;
|
||||
for my $subcheck (@{$output->{'checks'}}) {
|
||||
if ($subcheck->{'output'} =~ /nagiosplug.ssh.0.2 \(protocol version: 2.0\)/ ){
|
||||
$found_version = 1;
|
||||
}
|
||||
}
|
||||
cmp_ok($found_version, '==', 1, "Output OK");
|
||||
close NC;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,42 +17,35 @@ my $message = '/^[0-9]+\% free \([0-9]+MiB out of [0-9]+MiB\)/';
|
|||
|
||||
$result = NPTest->testCmd( "./check_swap $outputFormat" ); # Always OK
|
||||
cmp_ok( $result->return_code, "==", 0, "Always OK" );
|
||||
$output = decode_json($result->output);
|
||||
is($output->{'state'}, "OK", "State was correct");
|
||||
like($output->{'checks'}->[0]->{'output'}, $message, "Output was correct");
|
||||
is($result->{'mp_test_result'}->{'state'}, "OK", "State was correct");
|
||||
like($result->{'mp_test_result'}->{'checks'}->[0]->{'output'}, $message, "Output was correct");
|
||||
|
||||
$result = NPTest->testCmd( "./check_swap -w 1048576 -c 1048576 $outputFormat" ); # 1 MB free
|
||||
cmp_ok( $result->return_code, "==", 0, "Always OK" );
|
||||
$output = decode_json($result->output);
|
||||
is($output->{'state'}, "OK", "State was correct");
|
||||
like($output->{'checks'}->[0]->{'output'}, $message, "Output was correct");
|
||||
is($result->{'mp_test_result'}->{'state'}, "OK", "State was correct");
|
||||
like($result->{'mp_test_result'}->{'checks'}->[0]->{'output'}, $message, "Output was correct");
|
||||
|
||||
$result = NPTest->testCmd( "./check_swap -w 1% -c 1% $outputFormat" ); # 1% free
|
||||
cmp_ok( $result->return_code, "==", 0, "Always OK" );
|
||||
$output = decode_json($result->output);
|
||||
is($output->{'state'}, "OK", "State was correct");
|
||||
like($output->{'checks'}->[0]->{'output'}, $message, "Output was correct");
|
||||
is($result->{'mp_test_result'}->{'state'}, "OK", "State was correct");
|
||||
like($result->{'mp_test_result'}->{'checks'}->[0]->{'output'}, $message, "Output was correct");
|
||||
|
||||
$result = NPTest->testCmd( "./check_swap -w 100% -c 100% $outputFormat" ); # 100% (always critical)
|
||||
cmp_ok( $result->return_code, "==", 0, "Always OK" );
|
||||
$output = decode_json($result->output);
|
||||
is($output->{'state'}, "CRITICAL", "State was correct");
|
||||
like($output->{'checks'}->[0]->{'output'}, $message, "Output was correct");
|
||||
is($result->{'mp_test_result'}->{'state'}, "CRITICAL", "State was correct");
|
||||
like($result->{'mp_test_result'}->{'checks'}->[0]->{'output'}, $message, "Output was correct");
|
||||
|
||||
$result = NPTest->testCmd( "./check_swap -w 100% -c 1% $outputFormat" ); # 100% (always warn)
|
||||
cmp_ok( $result->return_code, "==", 0, "Always OK" );
|
||||
$output = decode_json($result->output);
|
||||
is($output->{'state'}, "WARNING", "State was correct");
|
||||
like($output->{'checks'}->[0]->{'output'}, $message, "Output was correct");
|
||||
is($result->{'mp_test_result'}->{'state'}, "WARNING", "State was correct");
|
||||
like($result->{'mp_test_result'}->{'checks'}->[0]->{'output'}, $message, "Output was correct");
|
||||
|
||||
$result = NPTest->testCmd( "./check_swap -w 100% $outputFormat" ); # 100% (single threshold, always warn)
|
||||
cmp_ok( $result->return_code, "==", 0, "Always OK" );
|
||||
$output = decode_json($result->output);
|
||||
is($output->{'state'}, "WARNING", "State was correct");
|
||||
like($output->{'checks'}->[0]->{'output'}, $message, "Output was correct");
|
||||
is($result->{'mp_test_result'}->{'state'}, "WARNING", "State was correct");
|
||||
like($result->{'mp_test_result'}->{'checks'}->[0]->{'output'}, $message, "Output was correct");
|
||||
|
||||
$result = NPTest->testCmd( "./check_swap -c 100% $outputFormat" ); # 100% (single threshold, always critical)
|
||||
cmp_ok( $result->return_code, "==", 0, "Always OK" );
|
||||
$output = decode_json($result->output);
|
||||
is($output->{'state'}, "CRITICAL", "State was correct");
|
||||
like($output->{'checks'}->[0]->{'output'}, $message, "Output was correct");
|
||||
is($result->{'mp_test_result'}->{'state'}, "CRITICAL", "State was correct");
|
||||
like($result->{'mp_test_result'}->{'checks'}->[0]->{'output'}, $message, "Output was correct");
|
||||
|
|
|
|||
243
plugins/utils.c
243
plugins/utils.c
|
|
@ -89,41 +89,46 @@ bool is_numeric(char *number) {
|
|||
char tmp[1];
|
||||
float x;
|
||||
|
||||
if (!number)
|
||||
if (!number) {
|
||||
return false;
|
||||
else if (sscanf(number, "%f%c", &x, tmp) == 1)
|
||||
} else if (sscanf(number, "%f%c", &x, tmp) == 1) {
|
||||
return true;
|
||||
else
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool is_positive(char *number) {
|
||||
if (is_numeric(number) && atof(number) > 0.0)
|
||||
if (is_numeric(number) && atof(number) > 0.0) {
|
||||
return true;
|
||||
else
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool is_negative(char *number) {
|
||||
if (is_numeric(number) && atof(number) < 0.0)
|
||||
if (is_numeric(number) && atof(number) < 0.0) {
|
||||
return true;
|
||||
else
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool is_nonnegative(char *number) {
|
||||
if (is_numeric(number) && atof(number) >= 0.0)
|
||||
if (is_numeric(number) && atof(number) >= 0.0) {
|
||||
return true;
|
||||
else
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool is_percentage(char *number) {
|
||||
int x;
|
||||
if (is_numeric(number) && (x = atof(number)) >= 0 && x <= 100)
|
||||
if (is_numeric(number) && (x = atof(number)) >= 0 && x <= 100) {
|
||||
return true;
|
||||
else
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool is_percentage_expression(const char str[]) {
|
||||
|
|
@ -156,36 +161,41 @@ bool is_percentage_expression(const char str[]) {
|
|||
bool is_integer(char *number) {
|
||||
long int n;
|
||||
|
||||
if (!number || (strspn(number, "-0123456789 ") != strlen(number)))
|
||||
if (!number || (strspn(number, "-0123456789 ") != strlen(number))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
n = strtol(number, NULL, 10);
|
||||
|
||||
if (errno != ERANGE && n >= INT_MIN && n <= INT_MAX)
|
||||
if (errno != ERANGE && n >= INT_MIN && n <= INT_MAX) {
|
||||
return true;
|
||||
else
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool is_intpos(char *number) {
|
||||
if (is_integer(number) && atoi(number) > 0)
|
||||
if (is_integer(number) && atoi(number) > 0) {
|
||||
return true;
|
||||
else
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool is_intneg(char *number) {
|
||||
if (is_integer(number) && atoi(number) < 0)
|
||||
if (is_integer(number) && atoi(number) < 0) {
|
||||
return true;
|
||||
else
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool is_intnonneg(char *number) {
|
||||
if (is_integer(number) && atoi(number) >= 0)
|
||||
if (is_integer(number) && atoi(number) >= 0) {
|
||||
return true;
|
||||
else
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -247,19 +257,21 @@ bool is_uint64(char *number, uint64_t *target) {
|
|||
|
||||
bool is_intpercent(char *number) {
|
||||
int i;
|
||||
if (is_integer(number) && (i = atoi(number)) >= 0 && i <= 100)
|
||||
if (is_integer(number) && (i = atoi(number)) >= 0 && i <= 100) {
|
||||
return true;
|
||||
else
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool is_option(char *str) {
|
||||
if (!str)
|
||||
if (!str) {
|
||||
return false;
|
||||
else if (strspn(str, "-") == 1 || strspn(str, "-") == 2)
|
||||
} else if (strspn(str, "-") == 1 || strspn(str, "-") == 2) {
|
||||
return true;
|
||||
else
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef NEED_GETTIMEOFDAY
|
||||
|
|
@ -288,10 +300,11 @@ void strip(char *buffer) {
|
|||
|
||||
for (x = strlen(buffer); x >= 1; x--) {
|
||||
i = x - 1;
|
||||
if (buffer[i] == ' ' || buffer[i] == '\r' || buffer[i] == '\n' || buffer[i] == '\t')
|
||||
if (buffer[i] == ' ' || buffer[i] == '\r' || buffer[i] == '\n' || buffer[i] == '\t') {
|
||||
buffer[i] = '\0';
|
||||
else
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -309,8 +322,9 @@ void strip(char *buffer) {
|
|||
*****************************************************************************/
|
||||
|
||||
char *strscpy(char *dest, const char *src) {
|
||||
if (src == NULL)
|
||||
if (src == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
xasprintf(&dest, "%s", src);
|
||||
|
||||
|
|
@ -369,17 +383,21 @@ char *strscpy(char *dest, const char *src) {
|
|||
|
||||
char *strnl(char *str) {
|
||||
size_t len;
|
||||
if (str == NULL)
|
||||
if (str == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
str = strpbrk(str, "\r\n");
|
||||
if (str == NULL)
|
||||
if (str == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
len = strspn(str, "\r\n");
|
||||
if (str[len] == '\0')
|
||||
if (str[len] == '\0') {
|
||||
return NULL;
|
||||
}
|
||||
str += len;
|
||||
if (strlen(str) == 0)
|
||||
if (strlen(str) == 0) {
|
||||
return NULL;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
|
|
@ -402,15 +420,18 @@ char *strnl(char *str) {
|
|||
char *strpcpy(char *dest, const char *src, const char *str) {
|
||||
size_t len;
|
||||
|
||||
if (src)
|
||||
if (src) {
|
||||
len = strcspn(src, str);
|
||||
else
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (dest == NULL || strlen(dest) < len)
|
||||
if (dest == NULL || strlen(dest) < len) {
|
||||
dest = realloc(dest, len + 1);
|
||||
if (dest == NULL)
|
||||
}
|
||||
if (dest == NULL) {
|
||||
die(STATE_UNKNOWN, _("failed realloc in strpcpy\n"));
|
||||
}
|
||||
|
||||
strncpy(dest, src, len);
|
||||
dest[len] = '\0';
|
||||
|
|
@ -434,10 +455,11 @@ char *strpcpy(char *dest, const char *src, const char *str) {
|
|||
char *strpcat(char *dest, const char *src, const char *str) {
|
||||
size_t len, l2;
|
||||
|
||||
if (dest)
|
||||
if (dest) {
|
||||
len = strlen(dest);
|
||||
else
|
||||
} else {
|
||||
len = 0;
|
||||
}
|
||||
|
||||
if (src) {
|
||||
l2 = strcspn(src, str);
|
||||
|
|
@ -446,8 +468,9 @@ char *strpcat(char *dest, const char *src, const char *str) {
|
|||
}
|
||||
|
||||
dest = realloc(dest, len + l2 + 1);
|
||||
if (dest == NULL)
|
||||
if (dest == NULL) {
|
||||
die(STATE_UNKNOWN, _("failed malloc in strscat\n"));
|
||||
}
|
||||
|
||||
strncpy(dest + len, src, l2);
|
||||
dest[len + l2] = '\0';
|
||||
|
|
@ -463,8 +486,9 @@ char *strpcat(char *dest, const char *src, const char *str) {
|
|||
|
||||
int xvasprintf(char **strp, const char *fmt, va_list ap) {
|
||||
int result = vasprintf(strp, fmt, ap);
|
||||
if (result == -1 || *strp == NULL)
|
||||
if (result == -1 || *strp == NULL) {
|
||||
die(STATE_UNKNOWN, _("failed malloc in xvasprintf\n"));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -483,126 +507,145 @@ int xasprintf(char **strp, const char *fmt, ...) {
|
|||
*
|
||||
******************************************************************************/
|
||||
|
||||
char *perfdata(const char *label, long int val, const char *uom, int warnp, long int warn, int critp, long int crit, int minp,
|
||||
long int minv, int maxp, long int maxv) {
|
||||
char *perfdata(const char *label, long int val, const char *uom, bool warnp, long int warn, bool critp, long int crit, bool minp,
|
||||
long int minv, bool maxp, long int maxv) {
|
||||
char *data = NULL;
|
||||
|
||||
if (strpbrk(label, "'= "))
|
||||
if (strpbrk(label, "'= ")) {
|
||||
xasprintf(&data, "'%s'=%ld%s;", label, val, uom);
|
||||
else
|
||||
} else {
|
||||
xasprintf(&data, "%s=%ld%s;", label, val, uom);
|
||||
}
|
||||
|
||||
if (warnp)
|
||||
if (warnp) {
|
||||
xasprintf(&data, "%s%ld;", data, warn);
|
||||
else
|
||||
} else {
|
||||
xasprintf(&data, "%s;", data);
|
||||
}
|
||||
|
||||
if (critp)
|
||||
if (critp) {
|
||||
xasprintf(&data, "%s%ld;", data, crit);
|
||||
else
|
||||
} else {
|
||||
xasprintf(&data, "%s;", data);
|
||||
}
|
||||
|
||||
if (minp)
|
||||
if (minp) {
|
||||
xasprintf(&data, "%s%ld;", data, minv);
|
||||
else
|
||||
} else {
|
||||
xasprintf(&data, "%s;", data);
|
||||
}
|
||||
|
||||
if (maxp)
|
||||
if (maxp) {
|
||||
xasprintf(&data, "%s%ld", data, maxv);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
char *perfdata_uint64(const char *label, uint64_t val, const char *uom, int warnp, /* Warning present */
|
||||
uint64_t warn, int critp, /* Critical present */
|
||||
uint64_t crit, int minp, /* Minimum present */
|
||||
uint64_t minv, int maxp, /* Maximum present */
|
||||
char *perfdata_uint64(const char *label, uint64_t val, const char *uom, bool warnp, /* Warning present */
|
||||
uint64_t warn, bool critp, /* Critical present */
|
||||
uint64_t crit, bool minp, /* Minimum present */
|
||||
uint64_t minv, bool maxp, /* Maximum present */
|
||||
uint64_t maxv) {
|
||||
char *data = NULL;
|
||||
|
||||
if (strpbrk(label, "'= "))
|
||||
if (strpbrk(label, "'= ")) {
|
||||
xasprintf(&data, "'%s'=%" PRIu64 "%s;", label, val, uom);
|
||||
else
|
||||
} else {
|
||||
xasprintf(&data, "%s=%" PRIu64 "%s;", label, val, uom);
|
||||
}
|
||||
|
||||
if (warnp)
|
||||
if (warnp) {
|
||||
xasprintf(&data, "%s%" PRIu64 ";", data, warn);
|
||||
else
|
||||
} else {
|
||||
xasprintf(&data, "%s;", data);
|
||||
}
|
||||
|
||||
if (critp)
|
||||
if (critp) {
|
||||
xasprintf(&data, "%s%" PRIu64 ";", data, crit);
|
||||
else
|
||||
} else {
|
||||
xasprintf(&data, "%s;", data);
|
||||
}
|
||||
|
||||
if (minp)
|
||||
if (minp) {
|
||||
xasprintf(&data, "%s%" PRIu64 ";", data, minv);
|
||||
else
|
||||
} else {
|
||||
xasprintf(&data, "%s;", data);
|
||||
}
|
||||
|
||||
if (maxp)
|
||||
if (maxp) {
|
||||
xasprintf(&data, "%s%" PRIu64, data, maxv);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
char *perfdata_int64(const char *label, int64_t val, const char *uom, int warnp, /* Warning present */
|
||||
int64_t warn, int critp, /* Critical present */
|
||||
int64_t crit, int minp, /* Minimum present */
|
||||
int64_t minv, int maxp, /* Maximum present */
|
||||
char *perfdata_int64(const char *label, int64_t val, const char *uom, bool warnp, /* Warning present */
|
||||
int64_t warn, bool critp, /* Critical present */
|
||||
int64_t crit, bool minp, /* Minimum present */
|
||||
int64_t minv, bool maxp, /* Maximum present */
|
||||
int64_t maxv) {
|
||||
char *data = NULL;
|
||||
|
||||
if (strpbrk(label, "'= "))
|
||||
if (strpbrk(label, "'= ")) {
|
||||
xasprintf(&data, "'%s'=%" PRId64 "%s;", label, val, uom);
|
||||
else
|
||||
} else {
|
||||
xasprintf(&data, "%s=%" PRId64 "%s;", label, val, uom);
|
||||
}
|
||||
|
||||
if (warnp)
|
||||
if (warnp) {
|
||||
xasprintf(&data, "%s%" PRId64 ";", data, warn);
|
||||
else
|
||||
} else {
|
||||
xasprintf(&data, "%s;", data);
|
||||
}
|
||||
|
||||
if (critp)
|
||||
if (critp) {
|
||||
xasprintf(&data, "%s%" PRId64 ";", data, crit);
|
||||
else
|
||||
} else {
|
||||
xasprintf(&data, "%s;", data);
|
||||
}
|
||||
|
||||
if (minp)
|
||||
if (minp) {
|
||||
xasprintf(&data, "%s%" PRId64 ";", data, minv);
|
||||
else
|
||||
} else {
|
||||
xasprintf(&data, "%s;", data);
|
||||
}
|
||||
|
||||
if (maxp)
|
||||
if (maxp) {
|
||||
xasprintf(&data, "%s%" PRId64, data, maxv);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
char *fperfdata(const char *label, double val, const char *uom, int warnp, double warn, int critp, double crit, int minp, double minv,
|
||||
int maxp, double maxv) {
|
||||
char *fperfdata(const char *label, double val, const char *uom, bool warnp, double warn, bool critp, double crit, bool minp, double minv,
|
||||
bool maxp, double maxv) {
|
||||
char *data = NULL;
|
||||
|
||||
if (strpbrk(label, "'= "))
|
||||
if (strpbrk(label, "'= ")) {
|
||||
xasprintf(&data, "'%s'=", label);
|
||||
else
|
||||
} else {
|
||||
xasprintf(&data, "%s=", label);
|
||||
}
|
||||
|
||||
xasprintf(&data, "%s%f", data, val);
|
||||
xasprintf(&data, "%s%s;", data, uom);
|
||||
|
||||
if (warnp)
|
||||
if (warnp) {
|
||||
xasprintf(&data, "%s%f", data, warn);
|
||||
}
|
||||
|
||||
xasprintf(&data, "%s;", data);
|
||||
|
||||
if (critp)
|
||||
if (critp) {
|
||||
xasprintf(&data, "%s%f", data, crit);
|
||||
}
|
||||
|
||||
xasprintf(&data, "%s;", data);
|
||||
|
||||
if (minp)
|
||||
if (minp) {
|
||||
xasprintf(&data, "%s%f", data, minv);
|
||||
}
|
||||
|
||||
if (maxp) {
|
||||
xasprintf(&data, "%s;", data);
|
||||
|
|
@ -612,28 +655,32 @@ char *fperfdata(const char *label, double val, const char *uom, int warnp, doubl
|
|||
return data;
|
||||
}
|
||||
|
||||
char *sperfdata(const char *label, double val, const char *uom, char *warn, char *crit, int minp, double minv, int maxp, double maxv) {
|
||||
char *sperfdata(const char *label, double val, const char *uom, char *warn, char *crit, bool minp, double minv, bool maxp, double maxv) {
|
||||
char *data = NULL;
|
||||
if (strpbrk(label, "'= "))
|
||||
if (strpbrk(label, "'= ")) {
|
||||
xasprintf(&data, "'%s'=", label);
|
||||
else
|
||||
} else {
|
||||
xasprintf(&data, "%s=", label);
|
||||
}
|
||||
|
||||
xasprintf(&data, "%s%f", data, val);
|
||||
xasprintf(&data, "%s%s;", data, uom);
|
||||
|
||||
if (warn != NULL)
|
||||
if (warn != NULL) {
|
||||
xasprintf(&data, "%s%s", data, warn);
|
||||
}
|
||||
|
||||
xasprintf(&data, "%s;", data);
|
||||
|
||||
if (crit != NULL)
|
||||
if (crit != NULL) {
|
||||
xasprintf(&data, "%s%s", data, crit);
|
||||
}
|
||||
|
||||
xasprintf(&data, "%s;", data);
|
||||
|
||||
if (minp)
|
||||
if (minp) {
|
||||
xasprintf(&data, "%s%f", data, minv);
|
||||
}
|
||||
|
||||
if (maxp) {
|
||||
xasprintf(&data, "%s;", data);
|
||||
|
|
@ -643,28 +690,32 @@ char *sperfdata(const char *label, double val, const char *uom, char *warn, char
|
|||
return data;
|
||||
}
|
||||
|
||||
char *sperfdata_int(const char *label, int val, const char *uom, char *warn, char *crit, int minp, int minv, int maxp, int maxv) {
|
||||
char *sperfdata_int(const char *label, int val, const char *uom, char *warn, char *crit, bool minp, int minv, bool maxp, int maxv) {
|
||||
char *data = NULL;
|
||||
if (strpbrk(label, "'= "))
|
||||
if (strpbrk(label, "'= ")) {
|
||||
xasprintf(&data, "'%s'=", label);
|
||||
else
|
||||
} else {
|
||||
xasprintf(&data, "%s=", label);
|
||||
}
|
||||
|
||||
xasprintf(&data, "%s%d", data, val);
|
||||
xasprintf(&data, "%s%s;", data, uom);
|
||||
|
||||
if (warn != NULL)
|
||||
if (warn != NULL) {
|
||||
xasprintf(&data, "%s%s", data, warn);
|
||||
}
|
||||
|
||||
xasprintf(&data, "%s;", data);
|
||||
|
||||
if (crit != NULL)
|
||||
if (crit != NULL) {
|
||||
xasprintf(&data, "%s%s", data, crit);
|
||||
}
|
||||
|
||||
xasprintf(&data, "%s;", data);
|
||||
|
||||
if (minp)
|
||||
if (minp) {
|
||||
xasprintf(&data, "%s%d", data, minv);
|
||||
}
|
||||
|
||||
if (maxp) {
|
||||
xasprintf(&data, "%s;", data);
|
||||
|
|
|
|||
141
plugins/utils.h
141
plugins/utils.h
|
|
@ -21,43 +21,43 @@ suite of plugins. */
|
|||
|
||||
#ifdef NP_EXTRA_OPTS
|
||||
/* Include extra-opts functions if compiled in */
|
||||
#include "extra_opts.h"
|
||||
# include "extra_opts.h"
|
||||
#else
|
||||
/* else, fake np_extra_opts */
|
||||
#define np_extra_opts(acptr,av,pr) av
|
||||
# define np_extra_opts(acptr, av, pr) av
|
||||
#endif
|
||||
|
||||
/* Standardize version information, termination */
|
||||
|
||||
void support (void);
|
||||
void print_revision (const char *, const char *);
|
||||
void support(void);
|
||||
void print_revision(const char *, const char *);
|
||||
|
||||
extern time_t start_time, end_time;
|
||||
|
||||
/* Test input types */
|
||||
|
||||
bool is_integer (char *);
|
||||
bool is_intpos (char *);
|
||||
bool is_intneg (char *);
|
||||
bool is_intnonneg (char *);
|
||||
bool is_intpercent (char *);
|
||||
bool is_integer(char *);
|
||||
bool is_intpos(char *);
|
||||
bool is_intneg(char *);
|
||||
bool is_intnonneg(char *);
|
||||
bool is_intpercent(char *);
|
||||
bool is_uint64(char *number, uint64_t *target);
|
||||
bool is_int64(char *number, int64_t *target);
|
||||
|
||||
bool is_numeric (char *);
|
||||
bool is_positive (char *);
|
||||
bool is_negative (char *);
|
||||
bool is_nonnegative (char *);
|
||||
bool is_percentage (char *);
|
||||
bool is_percentage_expression (const char[]);
|
||||
bool is_numeric(char *);
|
||||
bool is_positive(char *);
|
||||
bool is_negative(char *);
|
||||
bool is_nonnegative(char *);
|
||||
bool is_percentage(char *);
|
||||
bool is_percentage_expression(const char[]);
|
||||
|
||||
bool is_option (char *);
|
||||
bool is_option(char *);
|
||||
|
||||
/* Generalized timer that will do milliseconds if available */
|
||||
#ifndef HAVE_STRUCT_TIMEVAL
|
||||
struct timeval {
|
||||
long tv_sec; /* seconds */
|
||||
long tv_usec; /* microseconds */
|
||||
long tv_sec; /* seconds */
|
||||
long tv_usec; /* microseconds */
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
@ -65,137 +65,142 @@ struct timeval {
|
|||
int gettimeofday(struct timeval *, struct timezone *);
|
||||
#endif
|
||||
|
||||
double delta_time (struct timeval tv);
|
||||
long deltime (struct timeval tv);
|
||||
double delta_time(struct timeval tv);
|
||||
long deltime(struct timeval tv);
|
||||
|
||||
/* Handle strings safely */
|
||||
|
||||
void strip (char *);
|
||||
char *strscpy (char *, const char *);
|
||||
char *strnl (char *);
|
||||
char *strpcpy (char *, const char *, const char *);
|
||||
char *strpcat (char *, const char *, const char *);
|
||||
int xvasprintf (char **strp, const char *fmt, va_list ap);
|
||||
int xasprintf (char **strp, const char *fmt, ...);
|
||||
void strip(char *);
|
||||
char *strscpy(char *, const char *);
|
||||
char *strnl(char *);
|
||||
char *strpcpy(char *, const char *, const char *);
|
||||
char *strpcat(char *, const char *, const char *);
|
||||
int xvasprintf(char **strp, const char *fmt, va_list ap);
|
||||
int xasprintf(char **strp, const char *fmt, ...);
|
||||
|
||||
void usage (const char *) __attribute__((noreturn));
|
||||
void usage(const char *) __attribute__((noreturn));
|
||||
void usage2(const char *, const char *) __attribute__((noreturn));
|
||||
void usage3(const char *, int) __attribute__((noreturn));
|
||||
void usage4(const char *) __attribute__((noreturn));
|
||||
void usage5(void) __attribute__((noreturn));
|
||||
void usage_va(const char *fmt, ...) __attribute__((noreturn));
|
||||
|
||||
#define max(a,b) (((a)>(b))?(a):(b))
|
||||
#define min(a,b) (((a)<(b))?(a):(b))
|
||||
#define max(a, b) (((a) > (b)) ? (a) : (b))
|
||||
#define min(a, b) (((a) < (b)) ? (a) : (b))
|
||||
|
||||
char *perfdata (const char *, long int, const char *, int, long int,
|
||||
int, long int, int, long int, int, long int);
|
||||
char *perfdata(const char *, long int, const char *, bool, long int, bool, long int, bool, long int, bool, long int);
|
||||
|
||||
char *perfdata_uint64 (const char *, uint64_t , const char *, int, uint64_t,
|
||||
int, uint64_t, int, uint64_t, int, uint64_t);
|
||||
char *perfdata_uint64(const char *, uint64_t, const char *, bool, uint64_t, bool, uint64_t, bool, uint64_t, bool, uint64_t);
|
||||
|
||||
char *perfdata_int64 (const char *, int64_t, const char *, int, int64_t,
|
||||
int, int64_t, int, int64_t, int, int64_t);
|
||||
char *perfdata_int64(const char *, int64_t, const char *, bool, int64_t, bool, int64_t, bool, int64_t, bool, int64_t);
|
||||
|
||||
char *fperfdata (const char *, double, const char *, int, double,
|
||||
int, double, int, double, int, double);
|
||||
char *fperfdata(const char *, double, const char *, bool, double, bool, double, bool, double, bool, double);
|
||||
|
||||
char *sperfdata (const char *, double, const char *, char *, char *,
|
||||
int, double, int, double);
|
||||
char *sperfdata(const char *, double, const char *, char *, char *, bool, double, bool, double);
|
||||
|
||||
char *sperfdata_int (const char *, int, const char *, char *, char *,
|
||||
int, int, int, int);
|
||||
char *sperfdata_int(const char *, int, const char *, char *, char *, bool, int, bool, int);
|
||||
|
||||
/* The idea here is that, although not every plugin will use all of these,
|
||||
most will or should. Therefore, for consistency, these very common
|
||||
/* The idea here is that, although not every plugin will use all of these,
|
||||
most will or should. Therefore, for consistency, these very common
|
||||
options should have only these meanings throughout the overall suite */
|
||||
|
||||
#define STD_LONG_OPTS \
|
||||
{"version",no_argument,0,'V'},\
|
||||
{"verbose",no_argument,0,'v'},\
|
||||
{"help",no_argument,0,'h'},\
|
||||
{"timeout",required_argument,0,'t'},\
|
||||
{"critical",required_argument,0,'c'},\
|
||||
{"warning",required_argument,0,'w'},\
|
||||
{"hostname",required_argument,0,'H'}
|
||||
#define STD_LONG_OPTS \
|
||||
{"version", no_argument, 0, 'V'}, {"verbose", no_argument, 0, 'v'}, {"help", no_argument, 0, 'h'}, \
|
||||
{"timeout", required_argument, 0, 't'}, {"critical", required_argument, 0, 'c'}, {"warning", required_argument, 0, 'w'}, \
|
||||
{"hostname", required_argument, 0, 'H'}
|
||||
|
||||
#define COPYRIGHT "Copyright (c) %s Monitoring Plugins Development Team\n\
|
||||
#define COPYRIGHT \
|
||||
"Copyright (c) %s Monitoring Plugins Development Team\n\
|
||||
\t<%s>\n\n"
|
||||
|
||||
#define UT_HLP_VRS _("\
|
||||
#define UT_HLP_VRS \
|
||||
_("\
|
||||
%s (-h | --help) for detailed help\n\
|
||||
%s (-V | --version) for version information\n")
|
||||
|
||||
#define UT_HELP_VRSN _("\
|
||||
#define UT_HELP_VRSN \
|
||||
_("\
|
||||
\nOptions:\n\
|
||||
-h, --help\n\
|
||||
Print detailed help screen\n\
|
||||
-V, --version\n\
|
||||
Print version information\n")
|
||||
|
||||
#define UT_HOST_PORT _("\
|
||||
#define UT_HOST_PORT \
|
||||
_("\
|
||||
-H, --hostname=ADDRESS\n\
|
||||
Host name, IP Address, or unix socket (must be an absolute path)\n\
|
||||
-%c, --port=INTEGER\n\
|
||||
Port number (default: %s)\n")
|
||||
|
||||
#define UT_IPv46 _("\
|
||||
#define UT_IPv46 \
|
||||
_("\
|
||||
-4, --use-ipv4\n\
|
||||
Use IPv4 connection\n\
|
||||
-6, --use-ipv6\n\
|
||||
Use IPv6 connection\n")
|
||||
|
||||
#define UT_VERBOSE _("\
|
||||
#define UT_VERBOSE \
|
||||
_("\
|
||||
-v, --verbose\n\
|
||||
Show details for command-line debugging (output may be truncated by\n\
|
||||
the monitoring system)\n")
|
||||
|
||||
#define UT_WARN_CRIT _("\
|
||||
#define UT_WARN_CRIT \
|
||||
_("\
|
||||
-w, --warning=DOUBLE\n\
|
||||
Response time to result in warning status (seconds)\n\
|
||||
-c, --critical=DOUBLE\n\
|
||||
Response time to result in critical status (seconds)\n")
|
||||
|
||||
#define UT_WARN_CRIT_RANGE _("\
|
||||
#define UT_WARN_CRIT_RANGE \
|
||||
_("\
|
||||
-w, --warning=RANGE\n\
|
||||
Warning range (format: start:end). Alert if outside this range\n\
|
||||
-c, --critical=RANGE\n\
|
||||
Critical range\n")
|
||||
|
||||
#define UT_CONN_TIMEOUT _("\
|
||||
#define UT_CONN_TIMEOUT \
|
||||
_("\
|
||||
-t, --timeout=INTEGER\n\
|
||||
Seconds before connection times out (default: %d)\n")
|
||||
|
||||
#define UT_PLUG_TIMEOUT _("\
|
||||
#define UT_PLUG_TIMEOUT \
|
||||
_("\
|
||||
-t, --timeout=INTEGER\n\
|
||||
Seconds before plugin times out (default: %d)\n")
|
||||
|
||||
#ifdef NP_EXTRA_OPTS
|
||||
#define UT_EXTRA_OPTS _("\
|
||||
# define UT_EXTRA_OPTS \
|
||||
_("\
|
||||
--extra-opts=[section][@file]\n\
|
||||
Read options from an ini file. See\n\
|
||||
https://www.monitoring-plugins.org/doc/extra-opts.html\n\
|
||||
for usage and examples.\n")
|
||||
#else
|
||||
#define UT_EXTRA_OPTS " \b"
|
||||
# define UT_EXTRA_OPTS " \b"
|
||||
#endif
|
||||
|
||||
#define UT_THRESHOLDS_NOTES _("\
|
||||
#define UT_THRESHOLDS_NOTES \
|
||||
_("\
|
||||
See:\n\
|
||||
https://www.monitoring-plugins.org/doc/guidelines.html#THRESHOLDFORMAT\n\
|
||||
for THRESHOLD format and examples.\n")
|
||||
|
||||
#define UT_SUPPORT _("\n\
|
||||
#define UT_SUPPORT \
|
||||
_("\n\
|
||||
Send email to help@monitoring-plugins.org if you have questions regarding\n\
|
||||
use of this software. To submit patches or suggest improvements, send email\n\
|
||||
to devel@monitoring-plugins.org\n\n")
|
||||
|
||||
#define UT_NOWARRANTY _("\n\
|
||||
#define UT_NOWARRANTY \
|
||||
_("\n\
|
||||
The Monitoring Plugins come with ABSOLUTELY NO WARRANTY. You may redistribute\n\
|
||||
copies of the plugins under the terms of the GNU General Public License.\n\
|
||||
For more information about these matters, see the file named COPYING.\n")
|
||||
|
||||
#define UT_OUTPUT_FORMAT _("\
|
||||
#define UT_OUTPUT_FORMAT \
|
||||
_("\
|
||||
--output-format=OUTPUT_FORMAT\n\
|
||||
Select output format. Valid values: \"multi-line\", \"mp-test-json\"\n")
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue