From 285db2a9fa25519cacd48a76347ae2dee0c06605 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 18 Mar 2025 14:36:20 +0100 Subject: Move disk specific stuff from lib to plugin specific directory --- lib/Makefile.am | 3 +- lib/utils_disk.c | 255 ------------------------------------------------------- lib/utils_disk.h | 48 ----------- 3 files changed, 1 insertion(+), 305 deletions(-) delete mode 100644 lib/utils_disk.c delete mode 100644 lib/utils_disk.h (limited to 'lib') diff --git a/lib/Makefile.am b/lib/Makefile.am index e41201c4..a9f3ff40 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -7,10 +7,9 @@ noinst_LIBRARIES = libmonitoringplug.a AM_CPPFLAGS = -DNP_STATE_DIR_PREFIX=\"$(localstatedir)\" \ -I$(srcdir) -I$(top_srcdir)/gl -I$(top_srcdir)/intl -I$(top_srcdir)/plugins -libmonitoringplug_a_SOURCES = utils_base.c utils_disk.c utils_tcp.c utils_cmd.c maxfd.c output.c perfdata.c output.c thresholds.c vendor/cJSON/cJSON.c +libmonitoringplug_a_SOURCES = utils_base.c utils_tcp.c utils_cmd.c maxfd.c output.c perfdata.c output.c thresholds.c vendor/cJSON/cJSON.c EXTRA_DIST = utils_base.h \ - utils_disk.h \ utils_tcp.h \ utils_cmd.h \ parse_ini.h \ diff --git a/lib/utils_disk.c b/lib/utils_disk.c deleted file mode 100644 index 2b761f5e..00000000 --- a/lib/utils_disk.c +++ /dev/null @@ -1,255 +0,0 @@ -/***************************************************************************** - * - * Library for check_disk - * - * License: GPL - * Copyright (c) 1999-2024 Monitoring Plugins Development Team - * - * Description: - * - * This file contains utilities for check_disk. These are tested by libtap - * - * - * 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 . - * - * - *****************************************************************************/ - -#include "common.h" -#include "utils_disk.h" -#include "gl/fsusage.h" -#include - -void np_add_name(struct name_list **list, const char *name) { - struct name_list *new_entry; - new_entry = (struct name_list *)malloc(sizeof *new_entry); - new_entry->name = (char *)name; - new_entry->next = *list; - *list = new_entry; -} - -/* @brief Initialises a new regex at the begin of list via regcomp(3) - * - * @details if the regex fails to compile the error code of regcomp(3) is returned - * and list is not modified, otherwise list is modified to point to the new - * element - * @param list Pointer to a linked list of regex_list elements - * @param regex the string containing the regex which should be inserted into the list - * @param clags the cflags parameter for regcomp(3) - */ -int np_add_regex(struct regex_list **list, const char *regex, int cflags) { - struct regex_list *new_entry = (struct regex_list *)malloc(sizeof *new_entry); - - if (new_entry == NULL) { - die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); - } - - int regcomp_result = regcomp(&new_entry->regex, regex, cflags); - - if (!regcomp_result) { - // regcomp succeeded - new_entry->next = *list; - *list = new_entry; - - return 0; - } else { - // regcomp failed - free(new_entry); - - return regcomp_result; - } -} - -/* Initialises a new parameter at the end of list */ -struct parameter_list *np_add_parameter(struct parameter_list **list, const char *name) { - struct parameter_list *current = *list; - struct parameter_list *new_path; - new_path = (struct parameter_list *)malloc(sizeof *new_path); - new_path->name = (char *)malloc(strlen(name) + 1); - new_path->best_match = NULL; - new_path->name_next = NULL; - new_path->name_prev = NULL; - new_path->freespace_bytes = NULL; - new_path->freespace_units = NULL; - new_path->freespace_percent = NULL; - new_path->usedspace_bytes = NULL; - new_path->usedspace_units = NULL; - new_path->usedspace_percent = NULL; - new_path->usedinodes_percent = NULL; - new_path->freeinodes_percent = NULL; - new_path->group = NULL; - new_path->dfree_pct = -1; - new_path->dused_pct = -1; - new_path->total = 0; - new_path->available = 0; - new_path->available_to_root = 0; - new_path->used = 0; - new_path->dused_units = 0; - new_path->dfree_units = 0; - new_path->dtotal_units = 0; - new_path->inodes_total = 0; - new_path->inodes_free = 0; - new_path->inodes_free_to_root = 0; - new_path->inodes_used = 0; - new_path->dused_inodes_percent = 0; - new_path->dfree_inodes_percent = 0; - - strcpy(new_path->name, name); - - if (current == NULL) { - *list = new_path; - new_path->name_prev = NULL; - } else { - while (current->name_next) { - current = current->name_next; - } - current->name_next = new_path; - new_path->name_prev = current; - } - return new_path; -} - -/* Delete a given parameter from list and return pointer to next element*/ -struct parameter_list *np_del_parameter(struct parameter_list *item, struct parameter_list *prev) { - if (item == NULL) { - return NULL; - } - struct parameter_list *next; - - if (item->name_next) - next = item->name_next; - else - next = NULL; - - if (next) - next->name_prev = prev; - - if (prev) - prev->name_next = next; - - if (item->name) { - free(item->name); - } - free(item); - - return next; -} - -/* returns a pointer to the struct found in the list */ -struct parameter_list *np_find_parameter(struct parameter_list *list, const char *name) { - struct parameter_list *temp_list; - for (temp_list = list; temp_list; temp_list = temp_list->name_next) { - if (!strcmp(temp_list->name, name)) - return temp_list; - } - - return NULL; -} - -void np_set_best_match(struct parameter_list *desired, struct mount_entry *mount_list, bool exact) { - struct parameter_list *d; - for (d = desired; d; d = d->name_next) { - if (!d->best_match) { - struct mount_entry *me; - size_t name_len = strlen(d->name); - size_t best_match_len = 0; - struct mount_entry *best_match = NULL; - struct fs_usage fsp; - - /* set best match if path name exactly matches a mounted device name */ - for (me = mount_list; me; me = me->me_next) { - if (strcmp(me->me_devname, d->name) == 0) { - if (get_fs_usage(me->me_mountdir, me->me_devname, &fsp) >= 0) { - best_match = me; - } - } - } - - /* set best match by directory name if no match was found by devname */ - if (!best_match) { - for (me = mount_list; me; me = me->me_next) { - size_t len = strlen(me->me_mountdir); - if ((!exact && - (best_match_len <= len && len <= name_len && (len == 1 || strncmp(me->me_mountdir, d->name, len) == 0))) || - (exact && strcmp(me->me_mountdir, d->name) == 0)) { - if (get_fs_usage(me->me_mountdir, me->me_devname, &fsp) >= 0) { - best_match = me; - best_match_len = len; - } - } - } - } - - if (best_match) { - d->best_match = best_match; - } else { - d->best_match = NULL; /* Not sure why this is needed as it should be null on initialisation */ - } - } - } -} - -/* Returns true if name is in list */ -bool np_find_name(struct name_list *list, const char *name) { - const struct name_list *n; - - if (list == NULL || name == NULL) { - return false; - } - for (n = list; n; n = n->next) { - if (!strcmp(name, n->name)) { - return true; - } - } - return false; -} - -/* Returns true if name is in list */ -bool np_find_regmatch(struct regex_list *list, const char *name) { - int len; - regmatch_t m; - - if (name == NULL) { - return false; - } - - len = strlen(name); - - for (; list; list = list->next) { - /* Emulate a full match as if surrounded with ^( )$ - by checking whether the match spans the whole name */ - if (!regexec(&list->regex, name, 1, &m, 0) && m.rm_so == 0 && m.rm_eo == len) { - return true; - } - } - - return false; -} - -bool np_seen_name(struct name_list *list, const char *name) { - const struct name_list *s; - for (s = list; s; s = s->next) { - if (!strcmp(s->name, name)) { - return true; - } - } - return false; -} - -bool np_regex_match_mount_entry(struct mount_entry *me, regex_t *re) { - if (regexec(re, me->me_devname, (size_t)0, NULL, 0) == 0 || regexec(re, me->me_mountdir, (size_t)0, NULL, 0) == 0) { - return true; - } - return false; -} diff --git a/lib/utils_disk.h b/lib/utils_disk.h deleted file mode 100644 index c5e81dc1..00000000 --- a/lib/utils_disk.h +++ /dev/null @@ -1,48 +0,0 @@ -/* Header file for utils_disk */ - -#include "mountlist.h" -#include "utils_base.h" -#include "regex.h" - -struct name_list { - char *name; - struct name_list *next; -}; - -struct regex_list { - regex_t regex; - struct regex_list *next; -}; - -struct parameter_list { - char *name; - thresholds *freespace_bytes; - thresholds *freespace_units; - thresholds *freespace_percent; - thresholds *usedspace_bytes; - thresholds *usedspace_units; - thresholds *usedspace_percent; - thresholds *usedinodes_percent; - thresholds *freeinodes_percent; - char *group; - struct mount_entry *best_match; - struct parameter_list *name_next; - struct parameter_list *name_prev; - uintmax_t total, available, available_to_root, used, inodes_free, inodes_free_to_root, inodes_used, inodes_total; - double dfree_pct, dused_pct; - uint64_t dused_units, dfree_units, dtotal_units; - double dused_inodes_percent, dfree_inodes_percent; -}; - -void np_add_name(struct name_list **list, const char *name); -bool np_find_name(struct name_list *list, const char *name); -bool np_seen_name(struct name_list *list, const char *name); -int np_add_regex(struct regex_list **list, const char *regex, int cflags); -bool np_find_regmatch(struct regex_list *list, const char *name); -struct parameter_list *np_add_parameter(struct parameter_list **list, const char *name); -struct parameter_list *np_find_parameter(struct parameter_list *list, const char *name); -struct parameter_list *np_del_parameter(struct parameter_list *item, struct parameter_list *prev); - -int search_parameter_list(struct parameter_list *list, const char *name); -void np_set_best_match(struct parameter_list *desired, struct mount_entry *mount_list, bool exact); -bool np_regex_match_mount_entry(struct mount_entry *me, regex_t *re); -- cgit v1.2.3-74-g34f1 From 59e0a258f9c0f393bf29cced1f35743f74e7b10c Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 18 Mar 2025 15:57:44 +0100 Subject: Migrate disk tests from lib, tool --- .gitignore | 3 +- configure.ac | 4 +- lib/tests/Makefile.am | 6 +- lib/tests/test_disk.c | 192 -------------------------------------- lib/tests/test_disk.t | 6 -- plugins/Makefile.am | 8 +- plugins/check_disk.d/utils_disk.c | 4 +- plugins/check_disk.d/utils_disk.h | 2 +- plugins/common.h | 6 +- plugins/tests/test_check_disk.c | 192 ++++++++++++++++++++++++++++++++++++++ plugins/tests/test_check_disk.t | 6 ++ 11 files changed, 216 insertions(+), 213 deletions(-) delete mode 100644 lib/tests/test_disk.c delete mode 100755 lib/tests/test_disk.t create mode 100644 plugins/tests/test_check_disk.c create mode 100755 plugins/tests/test_check_disk.t (limited to 'lib') diff --git a/.gitignore b/.gitignore index 5245495e..8b14f429 100644 --- a/.gitignore +++ b/.gitignore @@ -114,7 +114,6 @@ NP-VERSION-FILE /lib/tests/Makefile.in /lib/tests/test_base64 /lib/tests/test_cmd -/lib/tests/test_disk /lib/tests/test_tcp /lib/tests/test_utils /lib/tests/utils_base.Po @@ -223,7 +222,7 @@ plugins/check_disk.d/.dirstamp /plugins/tests/Makefile /plugins/tests/Makefile.in /plugins/tests/test_utils -/plugins/tests/test_disk +/plugins/tests/test_check_disk /plugins/tests/test_check_swap /plugins/tests/.deps /plugins/tests/.dirstamp diff --git a/configure.ac b/configure.ac index 204fc6e3..fdc9b699 100644 --- a/configure.ac +++ b/configure.ac @@ -181,10 +181,10 @@ fi # Finally, define tests if we use libtap if test "$enable_libtap" = "yes" ; then - EXTRA_TEST="test_utils test_disk test_tcp test_cmd test_base64" + EXTRA_TEST="test_utils test_tcp test_cmd test_base64" AC_SUBST(EXTRA_TEST) - EXTRA_PLUGIN_TESTS="tests/test_check_swap" + EXTRA_PLUGIN_TESTS="tests/test_check_swap tests/test_check_disk" AC_SUBST(EXTRA_PLUGIN_TESTS) fi diff --git a/lib/tests/Makefile.am b/lib/tests/Makefile.am index 9be94f6d..7798a72e 100644 --- a/lib/tests/Makefile.am +++ b/lib/tests/Makefile.am @@ -8,9 +8,9 @@ check_PROGRAMS = @EXTRA_TEST@ AM_CPPFLAGS = -DNP_STATE_DIR_PREFIX=\"$(localstatedir)\" \ -I$(top_srcdir)/lib -I$(top_srcdir)/gl -I$(top_srcdir)/intl -I$(top_srcdir)/plugins -EXTRA_PROGRAMS = test_utils test_disk test_tcp test_cmd test_base64 test_ini1 test_ini3 test_opts1 test_opts2 test_opts3 test_generic_output +EXTRA_PROGRAMS = test_utils test_tcp test_cmd test_base64 test_ini1 test_ini3 test_opts1 test_opts2 test_opts3 test_generic_output -np_test_scripts = test_base64.t test_cmd.t test_disk.t test_ini1.t test_ini3.t test_opts1.t test_opts2.t test_opts3.t test_tcp.t test_utils.t test_generic_output.t +np_test_scripts = test_base64.t test_cmd.t test_ini1.t test_ini3.t test_opts1.t test_opts2.t test_opts3.t test_tcp.t test_utils.t test_generic_output.t np_test_files = config-dos.ini config-opts.ini config-tiny.ini plugin.ini plugins.ini EXTRA_DIST = $(np_test_scripts) $(np_test_files) var @@ -29,7 +29,7 @@ AM_CFLAGS = -g -I$(top_srcdir)/lib -I$(top_srcdir)/gl $(tap_cflags) AM_LDFLAGS = $(tap_ldflags) -ltap LDADD = $(top_srcdir)/lib/libmonitoringplug.a $(top_srcdir)/gl/libgnu.a $(LIB_CRYPTO) -SOURCES = test_utils.c test_disk.c test_tcp.c test_cmd.c test_base64.c test_ini1.c test_ini3.c test_opts1.c test_opts2.c test_opts3.c test_generic_output.c +SOURCES = test_utils.c test_tcp.c test_cmd.c test_base64.c test_ini1.c test_ini3.c test_opts1.c test_opts2.c test_opts3.c test_generic_output.c test: ${noinst_PROGRAMS} perl -MTest::Harness -e '$$Test::Harness::switches=""; runtests(map {$$_ .= ".t"} @ARGV)' $(EXTRA_PROGRAMS) diff --git a/lib/tests/test_disk.c b/lib/tests/test_disk.c deleted file mode 100644 index c18db7a4..00000000 --- a/lib/tests/test_disk.c +++ /dev/null @@ -1,192 +0,0 @@ -/***************************************************************************** - * - * 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 . - * - * - *****************************************************************************/ - -#include "common.h" -#include "utils_disk.h" -#include "tap.h" -#include "regex.h" - -void np_test_mount_entry_regex(struct mount_entry *dummy_mount_list, char *regstr, int cflags, int expect, char *desc); - -int main(int argc, char **argv) { - struct name_list *exclude_filesystem = NULL; - struct name_list *exclude_fstype = NULL; - struct name_list *dummy_mountlist = NULL; - struct name_list *temp_name; - struct parameter_list *paths = NULL; - struct parameter_list *p, *prev = NULL, *last = NULL; - - struct mount_entry *dummy_mount_list; - struct mount_entry *me; - struct mount_entry **mtail = &dummy_mount_list; - int cflags = REG_NOSUB | REG_EXTENDED; - int found = 0, count = 0; - - plan_tests(33); - - ok(np_find_name(exclude_filesystem, "/var/log") == false, "/var/log not in list"); - np_add_name(&exclude_filesystem, "/var/log"); - ok(np_find_name(exclude_filesystem, "/var/log") == true, "is in list now"); - ok(np_find_name(exclude_filesystem, "/home") == false, "/home not in list"); - np_add_name(&exclude_filesystem, "/home"); - ok(np_find_name(exclude_filesystem, "/home") == true, "is in list now"); - ok(np_find_name(exclude_filesystem, "/var/log") == true, "/var/log still in list"); - - ok(np_find_name(exclude_fstype, "iso9660") == false, "iso9660 not in list"); - np_add_name(&exclude_fstype, "iso9660"); - ok(np_find_name(exclude_fstype, "iso9660") == true, "is in list now"); - - ok(np_find_name(exclude_filesystem, "iso9660") == false, "Make sure no clashing in variables"); - - /* - for (temp_name = exclude_filesystem; temp_name; temp_name = temp_name->next) { - printf("Name: %s\n", temp_name->name); - } - */ - - me = (struct mount_entry *)malloc(sizeof *me); - me->me_devname = strdup("/dev/c0t0d0s0"); - me->me_mountdir = strdup("/"); - *mtail = me; - mtail = &me->me_next; - - me = (struct mount_entry *)malloc(sizeof *me); - me->me_devname = strdup("/dev/c1t0d1s0"); - me->me_mountdir = strdup("/var"); - *mtail = me; - mtail = &me->me_next; - - me = (struct mount_entry *)malloc(sizeof *me); - me->me_devname = strdup("/dev/c2t0d0s0"); - me->me_mountdir = strdup("/home"); - *mtail = me; - mtail = &me->me_next; - - np_test_mount_entry_regex(dummy_mount_list, strdup("/"), cflags, 3, strdup("a")); - np_test_mount_entry_regex(dummy_mount_list, strdup("/dev"), cflags, 3, strdup("regex on dev names:")); - np_test_mount_entry_regex(dummy_mount_list, strdup("/foo"), cflags, 0, strdup("regex on non existent dev/path:")); - np_test_mount_entry_regex(dummy_mount_list, strdup("/Foo"), cflags | REG_ICASE, 0, strdup("regi on non existent dev/path:")); - np_test_mount_entry_regex(dummy_mount_list, strdup("/c.t0"), cflags, 3, strdup("partial devname regex match:")); - np_test_mount_entry_regex(dummy_mount_list, strdup("c0t0"), cflags, 1, strdup("partial devname regex match:")); - np_test_mount_entry_regex(dummy_mount_list, strdup("C0t0"), cflags | REG_ICASE, 1, strdup("partial devname regi match:")); - np_test_mount_entry_regex(dummy_mount_list, strdup("home"), cflags, 1, strdup("partial pathname regex match:")); - np_test_mount_entry_regex(dummy_mount_list, strdup("hOme"), cflags | REG_ICASE, 1, strdup("partial pathname regi match:")); - np_test_mount_entry_regex(dummy_mount_list, strdup("(/home)|(/var)"), cflags, 2, strdup("grouped regex pathname match:")); - np_test_mount_entry_regex(dummy_mount_list, strdup("(/homE)|(/Var)"), cflags | REG_ICASE, 2, strdup("grouped regi pathname match:")); - - np_add_parameter(&paths, "/home/groups"); - np_add_parameter(&paths, "/var"); - np_add_parameter(&paths, "/tmp"); - np_add_parameter(&paths, "/home/tonvoon"); - np_add_parameter(&paths, "/dev/c2t0d0s0"); - - np_set_best_match(paths, dummy_mount_list, false); - for (p = paths; p; p = p->name_next) { - struct mount_entry *temp_me; - temp_me = p->best_match; - if (!strcmp(p->name, "/home/groups")) { - ok(temp_me && !strcmp(temp_me->me_mountdir, "/home"), "/home/groups got right best match: /home"); - } else if (!strcmp(p->name, "/var")) { - ok(temp_me && !strcmp(temp_me->me_mountdir, "/var"), "/var got right best match: /var"); - } else if (!strcmp(p->name, "/tmp")) { - ok(temp_me && !strcmp(temp_me->me_mountdir, "/"), "/tmp got right best match: /"); - } else if (!strcmp(p->name, "/home/tonvoon")) { - ok(temp_me && !strcmp(temp_me->me_mountdir, "/home"), "/home/tonvoon got right best match: /home"); - } else if (!strcmp(p->name, "/dev/c2t0d0s0")) { - ok(temp_me && !strcmp(temp_me->me_devname, "/dev/c2t0d0s0"), "/dev/c2t0d0s0 got right best match: /dev/c2t0d0s0"); - } - } - - paths = NULL; /* Bad boy - should free, but this is a test suite */ - np_add_parameter(&paths, "/home/groups"); - np_add_parameter(&paths, "/var"); - np_add_parameter(&paths, "/tmp"); - np_add_parameter(&paths, "/home/tonvoon"); - np_add_parameter(&paths, "/home"); - - np_set_best_match(paths, dummy_mount_list, true); - for (p = paths; p; p = p->name_next) { - if (!strcmp(p->name, "/home/groups")) { - ok(!p->best_match, "/home/groups correctly not found"); - } else if (!strcmp(p->name, "/var")) { - ok(p->best_match, "/var found"); - } else if (!strcmp(p->name, "/tmp")) { - ok(!p->best_match, "/tmp correctly not found"); - } else if (!strcmp(p->name, "/home/tonvoon")) { - ok(!p->best_match, "/home/tonvoon not found"); - } else if (!strcmp(p->name, "/home")) { - ok(p->best_match, "/home found"); - } - } - - /* test deleting first element in paths */ - paths = np_del_parameter(paths, NULL); - for (p = paths; p; p = p->name_next) { - if (!strcmp(p->name, "/home/groups")) - found = 1; - } - ok(found == 0, "first element successfully deleted"); - found = 0; - - p = paths; - while (p) { - if (!strcmp(p->name, "/tmp")) - p = np_del_parameter(p, prev); - else { - prev = p; - p = p->name_next; - } - } - - for (p = paths; p; p = p->name_next) { - if (!strcmp(p->name, "/tmp")) - found = 1; - if (p->name_next) - prev = p; - else - last = p; - } - ok(found == 0, "/tmp element successfully deleted"); - - p = np_del_parameter(last, prev); - for (p = paths; p; p = p->name_next) { - if (!strcmp(p->name, "/home")) - found = 1; - last = p; - count++; - } - ok(found == 0, "last (/home) element successfully deleted"); - ok(count == 2, "two elements remaining"); - - return exit_status(); -} - -void np_test_mount_entry_regex(struct mount_entry *dummy_mount_list, char *regstr, int cflags, int expect, char *desc) { - int matches = 0; - regex_t re; - struct mount_entry *me; - if (regcomp(&re, regstr, cflags) == 0) { - for (me = dummy_mount_list; me; me = me->me_next) { - if (np_regex_match_mount_entry(me, &re)) - matches++; - } - ok(matches == expect, "%s '%s' matched %i/3 entries. ok: %i/3", desc, regstr, expect, matches); - - } else - ok(false, "regex '%s' not compilable", regstr); -} diff --git a/lib/tests/test_disk.t b/lib/tests/test_disk.t deleted file mode 100755 index da84dfdf..00000000 --- a/lib/tests/test_disk.t +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/perl -use Test::More; -if (! -e "./test_disk") { - plan skip_all => "./test_disk not compiled - please enable libtap library to test"; -} -exec "./test_disk"; diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 30283cb4..04fb7ed2 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -40,11 +40,13 @@ EXTRA_PROGRAMS = check_mysql check_radius check_pgsql check_snmp check_hpjd \ check_nagios check_by_ssh check_dns check_nt check_ide_smart \ check_procs check_mysql_query check_apt check_dbi check_curl \ \ - tests/test_check_swap + tests/test_check_swap \ + tests/test_check_disk SUBDIRS = picohttpparser -np_test_scripts = tests/test_check_swap.t +np_test_scripts = tests/test_check_swap.t \ + tests/test_check_disk.t EXTRA_DIST = t \ tests \ @@ -167,6 +169,8 @@ endif tests_test_check_swap_LDADD = $(BASEOBJS) $(tap_ldflags) -ltap tests_test_check_swap_SOURCES = tests/test_check_swap.c check_swap.d/swap.c +tests_test_check_disk_LDADD = $(BASEOBJS) $(tap_ldflags) check_disk.d/utils_disk.c -ltap +tests_test_check_disk_SOURCES = tests/test_check_disk.c ############################################################################## # secondary dependencies diff --git a/plugins/check_disk.d/utils_disk.c b/plugins/check_disk.d/utils_disk.c index 1d806715..369c85d5 100644 --- a/plugins/check_disk.d/utils_disk.c +++ b/plugins/check_disk.d/utils_disk.c @@ -26,9 +26,9 @@ * *****************************************************************************/ -#include "common.h" +#include "../common.h" #include "utils_disk.h" -#include "gl/fsusage.h" +#include "../../gl/fsusage.h" #include void np_add_name(struct name_list **list, const char *name) { diff --git a/plugins/check_disk.d/utils_disk.h b/plugins/check_disk.d/utils_disk.h index 1c68fed9..0c69f987 100644 --- a/plugins/check_disk.d/utils_disk.h +++ b/plugins/check_disk.d/utils_disk.h @@ -2,7 +2,7 @@ #include "../../config.h" #include "../../gl/mountlist.h" -#include "utils_base.h" +#include "../../lib/utils_base.h" #include "regex.h" #include diff --git a/plugins/common.h b/plugins/common.h index 603bae55..35d1e549 100644 --- a/plugins/common.h +++ b/plugins/common.h @@ -31,7 +31,7 @@ #ifndef _COMMON_H_ #define _COMMON_H_ -#include "config.h" +#include "../config.h" #include "../lib/monitoringplug.h" #ifdef HAVE_FEATURES_H @@ -110,7 +110,7 @@ /* GNU Libraries */ #include -#include "dirname.h" +#include "../gl/dirname.h" #include @@ -190,7 +190,7 @@ enum { * Internationalization * */ -#include "gettext.h" +#include "../gl/gettext.h" #define _(String) gettext (String) #if ! ENABLE_NLS # undef textdomain diff --git a/plugins/tests/test_check_disk.c b/plugins/tests/test_check_disk.c new file mode 100644 index 00000000..92d0d270 --- /dev/null +++ b/plugins/tests/test_check_disk.c @@ -0,0 +1,192 @@ +/***************************************************************************** + * + * 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 . + * + * + *****************************************************************************/ + +#include "common.h" +#include "../check_disk.d/utils_disk.h" +#include "../../tap/tap.h" +#include "regex.h" + +void np_test_mount_entry_regex(struct mount_entry *dummy_mount_list, char *regstr, int cflags, int expect, char *desc); + +int main(int argc, char **argv) { + struct name_list *exclude_filesystem = NULL; + struct name_list *exclude_fstype = NULL; + struct name_list *dummy_mountlist = NULL; + struct name_list *temp_name; + struct parameter_list *paths = NULL; + struct parameter_list *p, *prev = NULL, *last = NULL; + + struct mount_entry *dummy_mount_list; + struct mount_entry *me; + struct mount_entry **mtail = &dummy_mount_list; + int cflags = REG_NOSUB | REG_EXTENDED; + int found = 0, count = 0; + + plan_tests(33); + + ok(np_find_name(exclude_filesystem, "/var/log") == false, "/var/log not in list"); + np_add_name(&exclude_filesystem, "/var/log"); + ok(np_find_name(exclude_filesystem, "/var/log") == true, "is in list now"); + ok(np_find_name(exclude_filesystem, "/home") == false, "/home not in list"); + np_add_name(&exclude_filesystem, "/home"); + ok(np_find_name(exclude_filesystem, "/home") == true, "is in list now"); + ok(np_find_name(exclude_filesystem, "/var/log") == true, "/var/log still in list"); + + ok(np_find_name(exclude_fstype, "iso9660") == false, "iso9660 not in list"); + np_add_name(&exclude_fstype, "iso9660"); + ok(np_find_name(exclude_fstype, "iso9660") == true, "is in list now"); + + ok(np_find_name(exclude_filesystem, "iso9660") == false, "Make sure no clashing in variables"); + + /* + for (temp_name = exclude_filesystem; temp_name; temp_name = temp_name->next) { + printf("Name: %s\n", temp_name->name); + } + */ + + me = (struct mount_entry *)malloc(sizeof *me); + me->me_devname = strdup("/dev/c0t0d0s0"); + me->me_mountdir = strdup("/"); + *mtail = me; + mtail = &me->me_next; + + me = (struct mount_entry *)malloc(sizeof *me); + me->me_devname = strdup("/dev/c1t0d1s0"); + me->me_mountdir = strdup("/var"); + *mtail = me; + mtail = &me->me_next; + + me = (struct mount_entry *)malloc(sizeof *me); + me->me_devname = strdup("/dev/c2t0d0s0"); + me->me_mountdir = strdup("/home"); + *mtail = me; + mtail = &me->me_next; + + np_test_mount_entry_regex(dummy_mount_list, strdup("/"), cflags, 3, strdup("a")); + np_test_mount_entry_regex(dummy_mount_list, strdup("/dev"), cflags, 3, strdup("regex on dev names:")); + np_test_mount_entry_regex(dummy_mount_list, strdup("/foo"), cflags, 0, strdup("regex on non existent dev/path:")); + np_test_mount_entry_regex(dummy_mount_list, strdup("/Foo"), cflags | REG_ICASE, 0, strdup("regi on non existent dev/path:")); + np_test_mount_entry_regex(dummy_mount_list, strdup("/c.t0"), cflags, 3, strdup("partial devname regex match:")); + np_test_mount_entry_regex(dummy_mount_list, strdup("c0t0"), cflags, 1, strdup("partial devname regex match:")); + np_test_mount_entry_regex(dummy_mount_list, strdup("C0t0"), cflags | REG_ICASE, 1, strdup("partial devname regi match:")); + np_test_mount_entry_regex(dummy_mount_list, strdup("home"), cflags, 1, strdup("partial pathname regex match:")); + np_test_mount_entry_regex(dummy_mount_list, strdup("hOme"), cflags | REG_ICASE, 1, strdup("partial pathname regi match:")); + np_test_mount_entry_regex(dummy_mount_list, strdup("(/home)|(/var)"), cflags, 2, strdup("grouped regex pathname match:")); + np_test_mount_entry_regex(dummy_mount_list, strdup("(/homE)|(/Var)"), cflags | REG_ICASE, 2, strdup("grouped regi pathname match:")); + + np_add_parameter(&paths, "/home/groups"); + np_add_parameter(&paths, "/var"); + np_add_parameter(&paths, "/tmp"); + np_add_parameter(&paths, "/home/tonvoon"); + np_add_parameter(&paths, "/dev/c2t0d0s0"); + + np_set_best_match(paths, dummy_mount_list, false); + for (p = paths; p; p = p->name_next) { + struct mount_entry *temp_me; + temp_me = p->best_match; + if (!strcmp(p->name, "/home/groups")) { + ok(temp_me && !strcmp(temp_me->me_mountdir, "/home"), "/home/groups got right best match: /home"); + } else if (!strcmp(p->name, "/var")) { + ok(temp_me && !strcmp(temp_me->me_mountdir, "/var"), "/var got right best match: /var"); + } else if (!strcmp(p->name, "/tmp")) { + ok(temp_me && !strcmp(temp_me->me_mountdir, "/"), "/tmp got right best match: /"); + } else if (!strcmp(p->name, "/home/tonvoon")) { + ok(temp_me && !strcmp(temp_me->me_mountdir, "/home"), "/home/tonvoon got right best match: /home"); + } else if (!strcmp(p->name, "/dev/c2t0d0s0")) { + ok(temp_me && !strcmp(temp_me->me_devname, "/dev/c2t0d0s0"), "/dev/c2t0d0s0 got right best match: /dev/c2t0d0s0"); + } + } + + paths = NULL; /* Bad boy - should free, but this is a test suite */ + np_add_parameter(&paths, "/home/groups"); + np_add_parameter(&paths, "/var"); + np_add_parameter(&paths, "/tmp"); + np_add_parameter(&paths, "/home/tonvoon"); + np_add_parameter(&paths, "/home"); + + np_set_best_match(paths, dummy_mount_list, true); + for (p = paths; p; p = p->name_next) { + if (!strcmp(p->name, "/home/groups")) { + ok(!p->best_match, "/home/groups correctly not found"); + } else if (!strcmp(p->name, "/var")) { + ok(p->best_match, "/var found"); + } else if (!strcmp(p->name, "/tmp")) { + ok(!p->best_match, "/tmp correctly not found"); + } else if (!strcmp(p->name, "/home/tonvoon")) { + ok(!p->best_match, "/home/tonvoon not found"); + } else if (!strcmp(p->name, "/home")) { + ok(p->best_match, "/home found"); + } + } + + /* test deleting first element in paths */ + paths = np_del_parameter(paths, NULL); + for (p = paths; p; p = p->name_next) { + if (!strcmp(p->name, "/home/groups")) + found = 1; + } + ok(found == 0, "first element successfully deleted"); + found = 0; + + p = paths; + while (p) { + if (!strcmp(p->name, "/tmp")) + p = np_del_parameter(p, prev); + else { + prev = p; + p = p->name_next; + } + } + + for (p = paths; p; p = p->name_next) { + if (!strcmp(p->name, "/tmp")) + found = 1; + if (p->name_next) + prev = p; + else + last = p; + } + ok(found == 0, "/tmp element successfully deleted"); + + p = np_del_parameter(last, prev); + for (p = paths; p; p = p->name_next) { + if (!strcmp(p->name, "/home")) + found = 1; + last = p; + count++; + } + ok(found == 0, "last (/home) element successfully deleted"); + ok(count == 2, "two elements remaining"); + + return exit_status(); +} + +void np_test_mount_entry_regex(struct mount_entry *dummy_mount_list, char *regstr, int cflags, int expect, char *desc) { + int matches = 0; + regex_t re; + struct mount_entry *me; + if (regcomp(&re, regstr, cflags) == 0) { + for (me = dummy_mount_list; me; me = me->me_next) { + if (np_regex_match_mount_entry(me, &re)) + matches++; + } + ok(matches == expect, "%s '%s' matched %i/3 entries. ok: %i/3", desc, regstr, expect, matches); + + } else + ok(false, "regex '%s' not compilable", regstr); +} diff --git a/plugins/tests/test_check_disk.t b/plugins/tests/test_check_disk.t new file mode 100755 index 00000000..56354650 --- /dev/null +++ b/plugins/tests/test_check_disk.t @@ -0,0 +1,6 @@ +#!/usr/bin/perl +use Test::More; +if (! -e "./test_check_disk") { + plan skip_all => "./test_check_disk not compiled - please enable libtap library to test"; +} +exec "./test_check_disk"; -- cgit v1.2.3-74-g34f1 From f84f614f219b395810e4ca35d5eb5f5a8d2f1d5b Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Sun, 30 Mar 2025 22:34:20 +0200 Subject: Bugfix in output --- lib/output.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/output.c b/lib/output.c index 61fbf832..01e50770 100644 --- a/lib/output.c +++ b/lib/output.c @@ -13,6 +13,7 @@ // == Global variables static mp_output_format output_format = MP_FORMAT_DEFAULT; +static mp_output_detail_level level_of_detail = MP_DETAIL_ALL; // == Prototypes == static char *fmt_subcheck_output(mp_output_format output_format, mp_subcheck check, unsigned int indentation); @@ -202,7 +203,12 @@ mp_state_enum mp_compute_subcheck_state(const mp_subcheck check) { } mp_subcheck_list *scl = check.subchecks; - mp_state_enum result = check.default_state; + + if (scl == NULL) { + return check.default_state; + } + + mp_state_enum result = STATE_OK; while (scl != NULL) { result = max_state_alt(result, mp_compute_subcheck_state(scl->subcheck)); -- cgit v1.2.3-74-g34f1 From f413ac38e30e606beda4ef7f6bf1db40b49682d3 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Sun, 30 Mar 2025 22:34:42 +0200 Subject: Add selectable level of detail for output --- lib/output.c | 8 +++++++- lib/output.h | 16 +++++++++++++--- 2 files changed, 20 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/output.c b/lib/output.c index 01e50770..c408a2f5 100644 --- a/lib/output.c +++ b/lib/output.c @@ -253,7 +253,9 @@ char *mp_fmt_output(mp_check check) { mp_subcheck_list *subchecks = check.subchecks; while (subchecks != NULL) { - asprintf(&result, "%s\n%s", result, fmt_subcheck_output(MP_FORMAT_MULTI_LINE, subchecks->subcheck, 1)); + if (level_of_detail == MP_DETAIL_ALL || mp_compute_subcheck_state(subchecks->subcheck) != STATE_OK) { + asprintf(&result, "%s\n%s", result, fmt_subcheck_output(MP_FORMAT_MULTI_LINE, subchecks->subcheck, 1)); + } subchecks = subchecks->next; } @@ -545,3 +547,7 @@ parsed_output_format mp_parse_output_format(char *format_string) { void mp_set_format(mp_output_format format) { output_format = format; } mp_output_format mp_get_format(void) { return output_format; } + +void mp_set_level_of_detail(mp_output_detail_level level) { level_of_detail = level; } + +mp_output_detail_level mp_get_level_of_detail(void) { return level_of_detail; } diff --git a/lib/output.h b/lib/output.h index 2bdfa074..3bd91f90 100644 --- a/lib/output.h +++ b/lib/output.h @@ -38,8 +38,18 @@ typedef enum output_format { /* * Format related functions */ - void mp_set_format(mp_output_format format); - mp_output_format mp_get_format(void); +void mp_set_format(mp_output_format format); +mp_output_format mp_get_format(void); + +// Output detail level + +typedef enum output_detail_level { + MP_DETAIL_ALL, + MP_DETAIL_NON_OK_ONLY, +} mp_output_detail_level; + +void mp_set_level_of_detail(mp_output_detail_level level); +mp_output_detail_level mp_get_level_of_detail(void); /* * The main state object of a plugin. Exists only ONCE per plugin. @@ -48,7 +58,7 @@ typedef enum output_format { * in the first layer of subchecks */ typedef struct { - char *summary; // Overall summary, if not set a summary will be automatically generated + char *summary; // Overall summary, if not set a summary will be automatically generated mp_subcheck_list *subchecks; } mp_check; -- cgit v1.2.3-74-g34f1 From 1921cfccd6d83edb15a04fdb143a3176fb96dd22 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Sun, 30 Mar 2025 22:35:29 +0200 Subject: Always quote perfdata labels --- lib/perfdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/perfdata.c b/lib/perfdata.c index 661756c5..4f9c9558 100644 --- a/lib/perfdata.c +++ b/lib/perfdata.c @@ -33,7 +33,7 @@ char *pd_value_to_string(const mp_perfdata_value pd) { char *pd_to_string(mp_perfdata pd) { assert(pd.label != NULL); char *result = NULL; - asprintf(&result, "%s=", pd.label); + asprintf(&result, "'%s'=", pd.label); asprintf(&result, "%s%s", result, pd_value_to_string(pd.value)); -- cgit v1.2.3-74-g34f1 From 6e108cc25e75ec74013838620b26dabdd480718a Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Sun, 30 Mar 2025 22:36:07 +0200 Subject: Add more helpers to perfdata functions --- lib/perfdata.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/perfdata.h | 12 ++++++++ 2 files changed, 99 insertions(+) (limited to 'lib') diff --git a/lib/perfdata.c b/lib/perfdata.c index 4f9c9558..1742342e 100644 --- a/lib/perfdata.c +++ b/lib/perfdata.c @@ -514,3 +514,90 @@ perfdata_value_parser_wrapper parse_pd_value(const char *input) { } return result; } + +mp_perfdata mp_set_pd_max_value(mp_perfdata perfdata, mp_perfdata_value value) { + perfdata.max = value; + perfdata.max_present = true; + return perfdata; +} + +mp_perfdata mp_set_pd_min_value(mp_perfdata perfdata, mp_perfdata_value value) { + perfdata.min = value; + perfdata.min_present = true; + return perfdata; +} + +double mp_get_pd_value(mp_perfdata_value value) { + assert(value.type != PD_TYPE_NONE); + switch (value.type) { + case PD_TYPE_DOUBLE: + return value.pd_double; + case PD_TYPE_INT: + return (double)value.pd_int; + case PD_TYPE_UINT: + return (double)value.pd_uint; + default: + return 0; // just to make the compiler happy + } +} + +mp_perfdata_value mp_pd_value_multiply(mp_perfdata_value left, mp_perfdata_value right) { + if (left.type == right.type) { + switch (left.type) { + case PD_TYPE_DOUBLE: + left.pd_double *= right.pd_double; + return left; + case PD_TYPE_INT: + left.pd_int *= right.pd_int; + return left; + case PD_TYPE_UINT: + left.pd_uint *= right.pd_uint; + return left; + default: + // what to here? + return left; + } + } + + // Different types, oh boy, just do the lazy thing for now and switch to double + switch (left.type) { + case PD_TYPE_INT: + left.pd_double = (double)left.pd_int; + left.type = PD_TYPE_DOUBLE; + break; + case PD_TYPE_UINT: + left.pd_double = (double)left.pd_uint; + left.type = PD_TYPE_DOUBLE; + break; + case PD_TYPE_DOUBLE: + default: + // already there + } + + switch (right.type) { + case PD_TYPE_INT: + right.pd_double = (double)right.pd_int; + right.type = PD_TYPE_DOUBLE; + break; + case PD_TYPE_UINT: + right.pd_double = (double)right.pd_uint; + right.type = PD_TYPE_DOUBLE; + break; + case PD_TYPE_DOUBLE: + default: + // already there + } + + left.pd_double *= right.pd_double; + return left; +} + +mp_range mp_range_multiply(mp_range range, mp_perfdata_value factor) { + if (!range.end_infinity) { + range.end = mp_pd_value_multiply(range.end, factor); + } + if (!range.start_infinity) { + range.start = mp_pd_value_multiply(range.start, factor); + } + return range; +} diff --git a/lib/perfdata.h b/lib/perfdata.h index 74583ee5..cb552678 100644 --- a/lib/perfdata.h +++ b/lib/perfdata.h @@ -171,6 +171,11 @@ mp_perfdata_value mp_create_pd_value_u_long(unsigned long); mp_perfdata_value mp_create_pd_value_long_long(long long); mp_perfdata_value mp_create_pd_value_u_long_long(unsigned long long); +mp_perfdata mp_set_pd_max_value(mp_perfdata perfdata, mp_perfdata_value value); +mp_perfdata mp_set_pd_min_value(mp_perfdata perfdata, mp_perfdata_value value); + +double mp_get_pd_value(mp_perfdata_value value); + /* * Free the memory used by a pd_list */ @@ -178,6 +183,13 @@ void pd_list_free(pd_list[1]); int cmp_perfdata_value(mp_perfdata_value, mp_perfdata_value); +// ================ +// Helper functions +// ================ + +mp_perfdata_value mp_pd_value_multiply(mp_perfdata_value left, mp_perfdata_value right); +mp_range mp_range_multiply(mp_range range, mp_perfdata_value factor); + // ================= // String formatters // ================= -- cgit v1.2.3-74-g34f1 From 0205694ce977af97a71c58e0ae3c431299ceb7bb Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Sun, 30 Mar 2025 22:36:38 +0200 Subject: Fix wrong return state in threshold function --- lib/thresholds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/thresholds.c b/lib/thresholds.c index ddefae37..171f5093 100644 --- a/lib/thresholds.c +++ b/lib/thresholds.c @@ -51,7 +51,7 @@ mp_state_enum mp_get_pd_status(mp_perfdata perfdata) { } if (perfdata.warn_present) { if (mp_check_range(perfdata.value, perfdata.warn)) { - return STATE_CRITICAL; + return STATE_WARNING; } } -- cgit v1.2.3-74-g34f1 From 0bca1d1aa36b13723e77672eae162352e9be99c9 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Sun, 30 Mar 2025 22:36:55 +0200 Subject: Implement some helper functions for thresholds --- lib/thresholds.c | 12 ++++++++++++ lib/thresholds.h | 3 +++ 2 files changed, 15 insertions(+) (limited to 'lib') diff --git a/lib/thresholds.c b/lib/thresholds.c index 171f5093..de2b9315 100644 --- a/lib/thresholds.c +++ b/lib/thresholds.c @@ -57,3 +57,15 @@ mp_state_enum mp_get_pd_status(mp_perfdata perfdata) { return STATE_OK; } + +mp_thresholds mp_thresholds_set_warn(mp_thresholds thlds, mp_range warn) { + thlds.warning = warn; + thlds.warning_is_set = true; + return thlds; +} + +mp_thresholds mp_thresholds_set_crit(mp_thresholds thlds, mp_range crit) { + thlds.critical = crit; + thlds.critical_is_set = true; + return thlds; +} diff --git a/lib/thresholds.h b/lib/thresholds.h index 4e7defee..5f9f9247 100644 --- a/lib/thresholds.h +++ b/lib/thresholds.h @@ -24,5 +24,8 @@ mp_perfdata mp_pd_set_thresholds(mp_perfdata /* pd */, mp_thresholds /* th */); mp_state_enum mp_get_pd_status(mp_perfdata /* pd */); +mp_thresholds mp_thresholds_set_warn(mp_thresholds thlds, mp_range warn); +mp_thresholds mp_thresholds_set_crit(mp_thresholds thlds, mp_range crit); + char *fmt_threshold_warning(thresholds th); char *fmt_threshold_critical(thresholds th); -- cgit v1.2.3-74-g34f1 From 430c641d9c6c3efb3fb0493b35e11dbc6ede2faa Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Sun, 30 Mar 2025 23:55:16 +0200 Subject: Try to circumvent some old compiler errors --- lib/perfdata.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'lib') diff --git a/lib/perfdata.c b/lib/perfdata.c index 1742342e..f425ffcf 100644 --- a/lib/perfdata.c +++ b/lib/perfdata.c @@ -569,9 +569,6 @@ mp_perfdata_value mp_pd_value_multiply(mp_perfdata_value left, mp_perfdata_value left.pd_double = (double)left.pd_uint; left.type = PD_TYPE_DOUBLE; break; - case PD_TYPE_DOUBLE: - default: - // already there } switch (right.type) { @@ -583,9 +580,6 @@ mp_perfdata_value mp_pd_value_multiply(mp_perfdata_value left, mp_perfdata_value right.pd_double = (double)right.pd_uint; right.type = PD_TYPE_DOUBLE; break; - case PD_TYPE_DOUBLE: - default: - // already there } left.pd_double *= right.pd_double; -- cgit v1.2.3-74-g34f1 From d0647ec7e1500c0e6164ac9820a7d623582bdde2 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Mon, 31 Mar 2025 23:41:51 +0200 Subject: Some code simplifications --- lib/utils_base.c | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) (limited to 'lib') diff --git a/lib/utils_base.c b/lib/utils_base.c index ff9540c7..c49a473f 100644 --- a/lib/utils_base.c +++ b/lib/utils_base.c @@ -225,27 +225,15 @@ bool mp_check_range(const mp_perfdata_value value, const mp_range my_range) { if (my_range.end_infinity == false && my_range.start_infinity == false) { // range: .........|---inside---|........... // value - if ((cmp_perfdata_value(my_range.start, value) < 1) && (cmp_perfdata_value(value, my_range.end) <= 0)) { - is_inside = true; - } else { - is_inside = false; - } + is_inside = ((cmp_perfdata_value(my_range.start, value) < 1) && (cmp_perfdata_value(value, my_range.end) <= 0)); } else if (my_range.start_infinity == false && my_range.end_infinity == true) { // range: .........|---inside--------- // value - if (cmp_perfdata_value(my_range.start, value) < 0) { - is_inside = true; - } else { - is_inside = false; - } + is_inside = (cmp_perfdata_value(my_range.start, value) < 0); } else if (my_range.start_infinity == true && my_range.end_infinity == false) { // range: -inside--------|.................... // value - if (cmp_perfdata_value(value, my_range.end) == -1) { - is_inside = true; - } else { - is_inside = false; - } + is_inside = (cmp_perfdata_value(value, my_range.end) == -1); } else { // range from -inf to inf, so always inside is_inside = true; -- cgit v1.2.3-74-g34f1 From ec47bbbda6b99f0efc1801a424812a4dd457f9b6 Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Fri, 9 May 2025 10:49:02 +0200 Subject: changed filename in cmd_file_read to const char * (check_apt warning) --- lib/utils_cmd.c | 2 +- lib/utils_cmd.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/utils_cmd.c b/lib/utils_cmd.c index 18350ac0..9b222409 100644 --- a/lib/utils_cmd.c +++ b/lib/utils_cmd.c @@ -346,7 +346,7 @@ int cmd_run_array(char *const *argv, output *out, output *err, int flags) { return _cmd_close(fd); } -int cmd_file_read(char *filename, output *out, int flags) { +int cmd_file_read(const char *filename, output *out, int flags) { int fd; if (out) memset(out, 0, sizeof(output)); diff --git a/lib/utils_cmd.h b/lib/utils_cmd.h index d00069c9..728ece23 100644 --- a/lib/utils_cmd.h +++ b/lib/utils_cmd.h @@ -20,7 +20,7 @@ typedef struct output output; /** prototypes **/ int cmd_run(const char *, output *, output *, int); int cmd_run_array(char *const *, output *, output *, int); -int cmd_file_read(char *, output *, int); +int cmd_file_read(const char *, output *, int); /* only multi-threaded plugins need to bother with this */ void cmd_init(void); -- cgit v1.2.3-74-g34f1 From 322cd6f829e55a91edbfc42201775afb552b5660 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Sat, 17 May 2025 11:26:27 +0200 Subject: Lib: Add perfdata for char and unsigned char --- lib/perfdata.c | 8 ++++++++ lib/perfdata.h | 4 ++++ plugins-root/Makefile.am | 2 +- 3 files changed, 13 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/perfdata.c b/lib/perfdata.c index f425ffcf..b87de7e0 100644 --- a/lib/perfdata.c +++ b/lib/perfdata.c @@ -257,6 +257,10 @@ mp_perfdata mp_set_pd_value_double(mp_perfdata pd, double value) { return pd; } +mp_perfdata mp_set_pd_value_char(mp_perfdata pd, char value) { return mp_set_pd_value_long_long(pd, (long long)value); } + +mp_perfdata mp_set_pd_value_u_char(mp_perfdata pd, unsigned char value) { return mp_set_pd_value_u_long_long(pd, (unsigned long long)value); } + mp_perfdata mp_set_pd_value_int(mp_perfdata pd, int value) { return mp_set_pd_value_long_long(pd, (long long)value); } mp_perfdata mp_set_pd_value_u_int(mp_perfdata pd, unsigned int value) { return mp_set_pd_value_u_long_long(pd, (unsigned long long)value); } @@ -288,6 +292,10 @@ mp_perfdata_value mp_create_pd_value_double(double value) { mp_perfdata_value mp_create_pd_value_float(float value) { return mp_create_pd_value_double((double)value); } +mp_perfdata_value mp_create_pd_value_char(char value) { return mp_create_pd_value_long_long((long long)value); } + +mp_perfdata_value mp_create_pd_value_u_char(unsigned char value) { return mp_create_pd_value_u_long_long((unsigned long long)value); } + mp_perfdata_value mp_create_pd_value_int(int value) { return mp_create_pd_value_long_long((long long)value); } mp_perfdata_value mp_create_pd_value_u_int(unsigned int value) { return mp_create_pd_value_u_long_long((unsigned long long)value); } diff --git a/lib/perfdata.h b/lib/perfdata.h index cb552678..7fd908a9 100644 --- a/lib/perfdata.h +++ b/lib/perfdata.h @@ -155,6 +155,8 @@ mp_perfdata mp_set_pd_value_u_long_long(mp_perfdata, unsigned long long); _Generic((V), \ float: mp_create_pd_value_float, \ double: mp_create_pd_value_double, \ + char: mp_create_pd_value_char, \ + unsigned char: mp_create_pd_value_u_char, \ int: mp_create_pd_value_int, \ unsigned int: mp_create_pd_value_u_int, \ long: mp_create_pd_value_long, \ @@ -164,6 +166,8 @@ mp_perfdata mp_set_pd_value_u_long_long(mp_perfdata, unsigned long long); mp_perfdata_value mp_create_pd_value_float(float); mp_perfdata_value mp_create_pd_value_double(double); +mp_perfdata_value mp_create_pd_value_char(char); +mp_perfdata_value mp_create_pd_value_u_char(unsigned char); mp_perfdata_value mp_create_pd_value_int(int); mp_perfdata_value mp_create_pd_value_u_int(unsigned int); mp_perfdata_value mp_create_pd_value_long(long); diff --git a/plugins-root/Makefile.am b/plugins-root/Makefile.am index f09f5e07..fffc0575 100644 --- a/plugins-root/Makefile.am +++ b/plugins-root/Makefile.am @@ -91,7 +91,7 @@ pst3_LDFLAGS = @PST3CFLAGS@ # pst3 must not use monitoringplug/gnulib includes! pst3_CPPFLAGS = -check_dhcp_DEPENDENCIES = check_dhcp.c $(NETOBJS) $(DEPLIBS) +check_dhcp_DEPENDENCIES = check_dhcp.c $(NETOBJS) $(DEPLIBS) check_icmp_DEPENDENCIES = check_icmp.c $(NETOBJS) clean-local: -- cgit v1.2.3-74-g34f1 From b71cb430cb79e89b5d8bf56990919b6c753cd271 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Thu, 19 Jun 2025 01:15:11 +0200 Subject: Implement flexible state override functions --- lib/output.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++------------- lib/output.h | 31 ++++++++++++++++++----- 2 files changed, 90 insertions(+), 24 deletions(-) (limited to 'lib') diff --git a/lib/output.c b/lib/output.c index c408a2f5..b398c2ad 100644 --- a/lib/output.c +++ b/lib/output.c @@ -16,7 +16,8 @@ static mp_output_format output_format = MP_FORMAT_DEFAULT; static mp_output_detail_level level_of_detail = MP_DETAIL_ALL; // == Prototypes == -static char *fmt_subcheck_output(mp_output_format output_format, mp_subcheck check, unsigned int indentation); +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); // == Implementation == @@ -58,7 +59,9 @@ static inline char *fmt_subcheck_perfdata(mp_subcheck check) { * It sets useful defaults */ mp_check mp_check_init(void) { - mp_check check = {0}; + mp_check check = { + .evaluation_function = &mp_eval_check_default, + }; return check; } @@ -121,7 +124,8 @@ void mp_add_perfdata_to_subcheck(mp_subcheck check[static 1], const mp_perfdata */ int mp_add_subcheck_to_subcheck(mp_subcheck check[static 1], mp_subcheck subcheck) { if (subcheck.output == NULL) { - die(STATE_UNKNOWN, "%s - %s #%d: %s", __FILE__, __func__, __LINE__, "Sub check output is NULL"); + die(STATE_UNKNOWN, "%s - %s #%d: %s", __FILE__, __func__, __LINE__, + "Sub check output is NULL"); } mp_subcheck_list *tmp = NULL; @@ -194,18 +198,30 @@ char *get_subcheck_summary(mp_check check) { return result; } +mp_state_enum mp_compute_subcheck_state(const mp_subcheck subcheck) { + if (subcheck.evaluation_function == NULL) { + return mp_eval_subcheck_default(subcheck); + } + return subcheck.evaluation_function(subcheck); +} + /* - * Generate the result state of a mp_subcheck object based on it's own state and it's subchecks states + * Generate the result state of a mp_subcheck object based on its own state and its subchecks + * states */ -mp_state_enum mp_compute_subcheck_state(const mp_subcheck check) { - if (check.state_set_explicitly) { - return check.state; +mp_state_enum mp_eval_subcheck_default(mp_subcheck subcheck) { + if (subcheck.evaluation_function != NULL) { + return subcheck.evaluation_function(subcheck); } - mp_subcheck_list *scl = check.subchecks; + if (subcheck.state_set_explicitly) { + return subcheck.state; + } + + mp_subcheck_list *scl = subcheck.subchecks; if (scl == NULL) { - return check.default_state; + return subcheck.default_state; } mp_state_enum result = STATE_OK; @@ -218,10 +234,18 @@ mp_state_enum mp_compute_subcheck_state(const mp_subcheck check) { return result; } +mp_state_enum mp_compute_check_state(const mp_check check) { + // just a safety check + if (check.evaluation_function == NULL) { + return mp_eval_check_default(check); + } + return check.evaluation_function(check); +} + /* * Generate the result state of a mp_check object based on it's own state and it's subchecks states */ -mp_state_enum mp_compute_check_state(const mp_check check) { +mp_state_enum mp_eval_check_default(const mp_check check) { assert(check.subchecks != NULL); // a mp_check without subchecks is invalid, die here mp_subcheck_list *scl = check.subchecks; @@ -253,8 +277,10 @@ char *mp_fmt_output(mp_check check) { mp_subcheck_list *subchecks = check.subchecks; while (subchecks != NULL) { - if (level_of_detail == MP_DETAIL_ALL || mp_compute_subcheck_state(subchecks->subcheck) != STATE_OK) { - asprintf(&result, "%s\n%s", result, fmt_subcheck_output(MP_FORMAT_MULTI_LINE, subchecks->subcheck, 1)); + if (level_of_detail == MP_DETAIL_ALL || + mp_compute_subcheck_state(subchecks->subcheck) != STATE_OK) { + asprintf(&result, "%s\n%s", result, + fmt_subcheck_output(MP_FORMAT_MULTI_LINE, subchecks->subcheck, 1)); } subchecks = subchecks->next; } @@ -266,7 +292,8 @@ char *mp_fmt_output(mp_check check) { if (pd_string == NULL) { asprintf(&pd_string, "%s", fmt_subcheck_perfdata(subchecks->subcheck)); } else { - asprintf(&pd_string, "%s %s", pd_string, fmt_subcheck_perfdata(subchecks->subcheck)); + asprintf(&pd_string, "%s %s", pd_string, + fmt_subcheck_perfdata(subchecks->subcheck)); } subchecks = subchecks->next; @@ -335,19 +362,21 @@ static char *generate_indentation_string(unsigned int indentation) { /* * Helper function to generate the output string of mp_subcheck */ -static inline char *fmt_subcheck_output(mp_output_format output_format, mp_subcheck check, unsigned int indentation) { +static inline char *fmt_subcheck_output(mp_output_format output_format, mp_subcheck check, + unsigned int indentation) { char *result = NULL; mp_subcheck_list *subchecks = NULL; switch (output_format) { case MP_FORMAT_MULTI_LINE: - asprintf(&result, "%s\\_[%s] - %s", generate_indentation_string(indentation), state_text(mp_compute_subcheck_state(check)), - check.output); + asprintf(&result, "%s\\_[%s] - %s", generate_indentation_string(indentation), + state_text(mp_compute_subcheck_state(check)), check.output); subchecks = check.subchecks; while (subchecks != NULL) { - asprintf(&result, "%s\n%s", result, fmt_subcheck_output(output_format, subchecks->subcheck, indentation + 1)); + asprintf(&result, "%s\n%s", result, + fmt_subcheck_output(output_format, subchecks->subcheck, indentation + 1)); subchecks = subchecks->next; } return result; @@ -551,3 +580,23 @@ mp_output_format mp_get_format(void) { return output_format; } void mp_set_level_of_detail(mp_output_detail_level level) { level_of_detail = level; } mp_output_detail_level mp_get_level_of_detail(void) { return level_of_detail; } + +mp_state_enum mp_eval_ok(mp_check overall) { + (void)overall; + return STATE_OK; +} + +mp_state_enum mp_eval_warning(mp_check overall) { + (void)overall; + return STATE_WARNING; +} + +mp_state_enum mp_eval_critical(mp_check overall) { + (void)overall; + return STATE_CRITICAL; +} + +mp_state_enum mp_eval_unknown(mp_check overall) { + (void)overall; + return STATE_UNKNOWN; +} diff --git a/lib/output.h b/lib/output.h index 3bd91f90..c63c8e3f 100644 --- a/lib/output.h +++ b/lib/output.h @@ -7,15 +7,21 @@ /* * A partial check result */ -typedef struct { +typedef struct mp_subcheck mp_subcheck; +struct mp_subcheck { mp_state_enum state; // OK, Warning, Critical ... set explicitly mp_state_enum default_state; // OK, Warning, Critical .. if not set explicitly - bool state_set_explicitly; // was the state set explicitly (or should it be derived from subchecks) + bool state_set_explicitly; // was the state set explicitly (or should it be derived from + // subchecks) - char *output; // Text output for humans ("Filesystem xyz is fine", "Could not create TCP connection to..") - pd_list *perfdata; // Performance data for this check + char *output; // Text output for humans ("Filesystem xyz is fine", "Could not create TCP + // connection to..") + pd_list *perfdata; // Performance data for this check struct subcheck_list *subchecks; // subchecks deeper in the hierarchy -} mp_subcheck; + + // the evaluation_functions computes the state of subcheck + mp_state_enum (*evaluation_function)(mp_subcheck); +}; /* * A list of subchecks, used in subchecks and the main check @@ -57,10 +63,14 @@ mp_output_detail_level mp_get_level_of_detail(void); * The final result is always derived from the children and the "worst" state * in the first layer of subchecks */ -typedef struct { +typedef struct mp_check mp_check; +struct mp_check { char *summary; // Overall summary, if not set a summary will be automatically generated mp_subcheck_list *subchecks; -} mp_check; + + // the evaluation_functions computes the state of check + mp_state_enum (*evaluation_function)(mp_check); +}; mp_check mp_check_init(void); mp_subcheck mp_subcheck_init(void); @@ -78,6 +88,13 @@ void mp_add_summary(mp_check check[static 1], char *summary); mp_state_enum mp_compute_check_state(mp_check); mp_state_enum mp_compute_subcheck_state(mp_subcheck); +mp_state_enum mp_eval_ok(mp_check overall); +mp_state_enum mp_eval_warning(mp_check overall); +mp_state_enum mp_eval_critical(mp_check overall); +mp_state_enum mp_eval_unknown(mp_check overall); +mp_state_enum mp_eval_check_default(mp_check check); +mp_state_enum mp_eval_subcheck_default(mp_subcheck subcheck); + typedef struct { bool parsing_success; mp_output_format output_format; -- cgit v1.2.3-74-g34f1 From bb4ce15997a3023c5c4f2bb434b37699797272da Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Sun, 6 Jul 2025 22:47:01 +0200 Subject: Make multiline output look better --- lib/output.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/output.c b/lib/output.c index 61fbf832..fbde490e 100644 --- a/lib/output.c +++ b/lib/output.c @@ -332,7 +332,37 @@ static inline char *fmt_subcheck_output(mp_output_format output_format, mp_subch mp_subcheck_list *subchecks = NULL; switch (output_format) { - case MP_FORMAT_MULTI_LINE: + case MP_FORMAT_MULTI_LINE: { + char *tmp_string = NULL; + if ((tmp_string = strchr(check.output, '\n')) != NULL) { + // This is a multiline string, put the correct indentation in before proceeding + char *intermediate_string = ""; + bool have_residual_chars = false; + + while (tmp_string != NULL) { + *tmp_string = '\0'; + xasprintf(&intermediate_string, "%s%s\n%s", intermediate_string,check.output, generate_indentation_string(indentation+1)); // one more indentation to make it look better + + if (*(tmp_string + 1) != '\0') { + check.output = tmp_string + 1; + have_residual_chars = true; + } else { + // Null after the \n, so this is the end + have_residual_chars = false; + break; + } + + tmp_string = strchr(check.output, '\n'); + } + + // add the rest (if any) + if (have_residual_chars) { + char *tmp = check.output; + xasprintf(&check.output, "%s\n%s%s", intermediate_string, generate_indentation_string(indentation+1), tmp); + } else { + check.output = intermediate_string; + } + } asprintf(&result, "%s\\_[%s] - %s", generate_indentation_string(indentation), state_text(mp_compute_subcheck_state(check)), check.output); @@ -343,6 +373,7 @@ static inline char *fmt_subcheck_output(mp_output_format output_format, mp_subch subchecks = subchecks->next; } return result; + } default: die(STATE_UNKNOWN, "Invalid format"); } -- cgit v1.2.3-74-g34f1 From 4966b920a2392484a6ae83a4a499c24a2942c832 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Fri, 1 Aug 2025 14:29:08 +0200 Subject: General smal improvements to the lib logic --- lib/utils_base.c | 15 ++++++++------- lib/utils_base.h | 5 +++-- 2 files changed, 11 insertions(+), 9 deletions(-) (limited to 'lib') diff --git a/lib/utils_base.c b/lib/utils_base.c index c49a473f..60103614 100644 --- a/lib/utils_base.c +++ b/lib/utils_base.c @@ -25,6 +25,7 @@ *****************************************************************************/ #include "../plugins/common.h" +#include "states.h" #include #include "utils_base.h" #include @@ -256,21 +257,21 @@ bool check_range(double value, range *my_range) { yes = false; } - if (my_range->end_infinity == false && my_range->start_infinity == false) { + if (!my_range->end_infinity&& !my_range->start_infinity) { if ((my_range->start <= value) && (value <= my_range->end)) { return no; } return yes; } - if (my_range->start_infinity == false && my_range->end_infinity == true) { + if (!my_range->start_infinity && my_range->end_infinity) { if (my_range->start <= value) { return no; } return yes; } - if (my_range->start_infinity == true && my_range->end_infinity == false) { + if (my_range->start_infinity && !my_range->end_infinity ) { if (value <= my_range->end) { return no; } @@ -280,14 +281,14 @@ bool check_range(double value, range *my_range) { } /* Returns status */ -int get_status(double value, thresholds *my_thresholds) { +mp_state_enum get_status(double value, thresholds *my_thresholds) { if (my_thresholds->critical != NULL) { - if (check_range(value, my_thresholds->critical) == true) { + if (check_range(value, my_thresholds->critical)) { return STATE_CRITICAL; } } if (my_thresholds->warning != NULL) { - if (check_range(value, my_thresholds->warning) == true) { + if (check_range(value, my_thresholds->warning)) { return STATE_WARNING; } } @@ -395,7 +396,7 @@ char *np_extract_value(const char *varlist, const char *name, char sep) { return value; } -const char *state_text(int result) { +const char *state_text(mp_state_enum result) { switch (result) { case STATE_OK: return "OK"; diff --git a/lib/utils_base.h b/lib/utils_base.h index 123066f8..8fb114c2 100644 --- a/lib/utils_base.h +++ b/lib/utils_base.h @@ -7,6 +7,7 @@ #include "./perfdata.h" #include "./thresholds.h" +#include "states.h" #ifndef USE_OPENSSL @@ -55,7 +56,7 @@ void set_thresholds(thresholds **, char *, char *); void print_thresholds(const char *, thresholds *); bool check_range(double, range *); bool mp_check_range(mp_perfdata_value, mp_range); -int get_status(double, thresholds *); +mp_state_enum get_status(double, thresholds *); /* Handle timeouts */ extern int timeout_state; @@ -107,6 +108,6 @@ void np_state_write_string(time_t, char *); void np_init(char *, int argc, char **argv); void np_set_args(int argc, char **argv); void np_cleanup(void); -const char *state_text(int); +const char *state_text(mp_state_enum); #endif /* _UTILS_BASE_ */ -- cgit v1.2.3-74-g34f1 From babeb765e5725610dbf7673c91a3a5a4e5a8810f Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 27 Aug 2025 12:15:45 +0200 Subject: Fix range comparison and aesthetic improvements --- lib/utils_base.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/utils_base.c b/lib/utils_base.c index c49a473f..1e92b29b 100644 --- a/lib/utils_base.c +++ b/lib/utils_base.c @@ -222,15 +222,15 @@ void print_thresholds(const char *threshold_name, thresholds *my_threshold) { bool mp_check_range(const mp_perfdata_value value, const mp_range my_range) { bool is_inside = false; - if (my_range.end_infinity == false && my_range.start_infinity == false) { + if (!my_range.end_infinity && !my_range.start_infinity) { // range: .........|---inside---|........... // value - is_inside = ((cmp_perfdata_value(my_range.start, value) < 1) && (cmp_perfdata_value(value, my_range.end) <= 0)); - } else if (my_range.start_infinity == false && my_range.end_infinity == true) { + is_inside = ((cmp_perfdata_value(value, my_range.start) >= 0) && (cmp_perfdata_value(value, my_range.end) <= 0)); + } else if (!my_range.start_infinity && my_range.end_infinity) { // range: .........|---inside--------- // value - is_inside = (cmp_perfdata_value(my_range.start, value) < 0); - } else if (my_range.start_infinity == true && my_range.end_infinity == false) { + is_inside = (cmp_perfdata_value(value, my_range.start) >= 0); + } else if (my_range.start_infinity && !my_range.end_infinity) { // range: -inside--------|.................... // value is_inside = (cmp_perfdata_value(value, my_range.end) == -1); -- cgit v1.2.3-74-g34f1 From 888cd29202df5b99d4cd7834b11b030f2c39859f Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Mon, 1 Sep 2025 11:24:44 +0200 Subject: lib/utils_base.c: clang-format --- lib/utils_base.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) (limited to 'lib') diff --git a/lib/utils_base.c b/lib/utils_base.c index 1e92b29b..5ba865c9 100644 --- a/lib/utils_base.c +++ b/lib/utils_base.c @@ -33,12 +33,12 @@ #include #include -#define np_free(ptr) \ - { \ - if (ptr) { \ - free(ptr); \ - ptr = NULL; \ - } \ +#define np_free(ptr) \ + { \ + if (ptr) { \ + free(ptr); \ + ptr = NULL; \ + } \ } monitoring_plugin *this_monitoring_plugin = NULL; @@ -153,7 +153,8 @@ range *parse_range_string(char *str) { set_range_end(temp_range, end); } - if (temp_range->start_infinity == true || temp_range->end_infinity == true || temp_range->start <= temp_range->end) { + if (temp_range->start_infinity == true || temp_range->end_infinity == true || + temp_range->start <= temp_range->end) { return temp_range; } free(temp_range); @@ -205,12 +206,14 @@ void print_thresholds(const char *threshold_name, thresholds *my_threshold) { printf("Threshold not set"); } else { if (my_threshold->warning) { - printf("Warning: start=%g end=%g; ", my_threshold->warning->start, my_threshold->warning->end); + printf("Warning: start=%g end=%g; ", my_threshold->warning->start, + my_threshold->warning->end); } else { printf("Warning not set; "); } if (my_threshold->critical) { - printf("Critical: start=%g end=%g", my_threshold->critical->start, my_threshold->critical->end); + printf("Critical: start=%g end=%g", my_threshold->critical->start, + my_threshold->critical->end); } else { printf("Critical not set"); } @@ -225,7 +228,8 @@ bool mp_check_range(const mp_perfdata_value value, const mp_range my_range) { if (!my_range.end_infinity && !my_range.start_infinity) { // range: .........|---inside---|........... // value - is_inside = ((cmp_perfdata_value(value, my_range.start) >= 0) && (cmp_perfdata_value(value, my_range.end) <= 0)); + is_inside = ((cmp_perfdata_value(value, my_range.start) >= 0) && + (cmp_perfdata_value(value, my_range.end) <= 0)); } else if (!my_range.start_infinity && my_range.end_infinity) { // range: .........|---inside--------- // value @@ -239,7 +243,8 @@ bool mp_check_range(const mp_perfdata_value value, const mp_range my_range) { is_inside = true; } - if ((is_inside && my_range.alert_on_inside_range == INSIDE) || (!is_inside && my_range.alert_on_inside_range == OUTSIDE)) { + if ((is_inside && my_range.alert_on_inside_range == INSIDE) || + (!is_inside && my_range.alert_on_inside_range == OUTSIDE)) { return true; } @@ -557,8 +562,8 @@ void np_enable_state(char *keyname, int expected_data_version) { this_state->state_data = NULL; /* Calculate filename */ - ret = asprintf(&temp_filename, "%s/%lu/%s/%s", _np_state_calculate_location_prefix(), (unsigned long)geteuid(), - this_monitoring_plugin->plugin_name, this_state->name); + ret = asprintf(&temp_filename, "%s/%lu/%s/%s", _np_state_calculate_location_prefix(), + (unsigned long)geteuid(), this_monitoring_plugin->plugin_name, this_state->name); if (ret < 0) { die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); } -- cgit v1.2.3-74-g34f1 From 28bb2fa0a499b46e279244990b8268c1ed8823bc Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Mon, 1 Sep 2025 11:27:49 +0200 Subject: lib/utils_base.c: small refactoring --- lib/perfdata.h | 2 +- lib/utils_base.c | 195 ++++++++++++++++++++++++++----------------------------- 2 files changed, 94 insertions(+), 103 deletions(-) (limited to 'lib') diff --git a/lib/perfdata.h b/lib/perfdata.h index 7fd908a9..c5d4a61d 100644 --- a/lib/perfdata.h +++ b/lib/perfdata.h @@ -45,7 +45,7 @@ typedef struct range_struct { double start; bool start_infinity; double end; - int end_infinity; + bool end_infinity; int alert_on; /* OUTSIDE (default) or INSIDE */ char *text; /* original unparsed text input */ } range; diff --git a/lib/utils_base.c b/lib/utils_base.c index 5ba865c9..43e88e7a 100644 --- a/lib/utils_base.c +++ b/lib/utils_base.c @@ -46,7 +46,7 @@ monitoring_plugin *this_monitoring_plugin = NULL; int timeout_state = STATE_CRITICAL; unsigned int timeout_interval = DEFAULT_SOCKET_TIMEOUT; -bool _np_state_read_file(FILE *); +bool _np_state_read_file(FILE *state_file); void np_init(char *plugin_name, int argc, char **argv) { if (this_monitoring_plugin == NULL) { @@ -153,7 +153,7 @@ range *parse_range_string(char *str) { set_range_end(temp_range, end); } - if (temp_range->start_infinity == true || temp_range->end_infinity == true || + if (temp_range->start_infinity || temp_range->end_infinity || temp_range->start <= temp_range->end) { return temp_range; } @@ -261,21 +261,21 @@ bool check_range(double value, range *my_range) { yes = false; } - if (my_range->end_infinity == false && my_range->start_infinity == false) { + if (!my_range->end_infinity && !my_range->start_infinity) { if ((my_range->start <= value) && (value <= my_range->end)) { return no; } return yes; } - if (my_range->start_infinity == false && my_range->end_infinity == true) { + if (!my_range->start_infinity && my_range->end_infinity) { if (my_range->start <= value) { return no; } return yes; } - if (my_range->start_infinity == true && my_range->end_infinity == false) { + if (my_range->start_infinity && !my_range->end_infinity) { if (value <= my_range->end) { return no; } @@ -287,12 +287,12 @@ bool check_range(double value, range *my_range) { /* Returns status */ int get_status(double value, thresholds *my_thresholds) { if (my_thresholds->critical != NULL) { - if (check_range(value, my_thresholds->critical) == true) { + if (check_range(value, my_thresholds->critical)) { return STATE_CRITICAL; } } if (my_thresholds->warning != NULL) { - if (check_range(value, my_thresholds->warning) == true) { + if (check_range(value, my_thresholds->warning)) { return STATE_WARNING; } } @@ -301,32 +301,31 @@ int get_status(double value, thresholds *my_thresholds) { char *np_escaped_string(const char *string) { char *data; - int i; - int j = 0; + int write_index = 0; data = strdup(string); - for (i = 0; data[i]; i++) { + for (int i = 0; data[i]; i++) { if (data[i] == '\\') { switch (data[++i]) { case 'n': - data[j++] = '\n'; + data[write_index++] = '\n'; break; case 'r': - data[j++] = '\r'; + data[write_index++] = '\r'; break; case 't': - data[j++] = '\t'; + data[write_index++] = '\t'; break; case '\\': - data[j++] = '\\'; + data[write_index++] = '\\'; break; default: - data[j++] = data[i]; + data[write_index++] = data[i]; } } else { - data[j++] = data[i]; + data[write_index++] = data[i]; } } - data[j] = '\0'; + data[write_index] = '\0'; return data; } @@ -341,33 +340,35 @@ int np_check_if_root(void) { return (geteuid() == 0); } char *np_extract_value(const char *varlist, const char *name, char sep) { char *tmp = NULL; char *value = NULL; - int i; - while (1) { + while (true) { /* Strip any leading space */ - for (; isspace(varlist[0]); varlist++) + for (; isspace(varlist[0]); varlist++) { ; + } if (strncmp(name, varlist, strlen(name)) == 0) { varlist += strlen(name); /* strip trailing spaces */ - for (; isspace(varlist[0]); varlist++) + for (; isspace(varlist[0]); varlist++) { ; + } if (varlist[0] == '=') { /* We matched the key, go past the = sign */ varlist++; /* strip leading spaces */ - for (; isspace(varlist[0]); varlist++) + for (; isspace(varlist[0]); varlist++) { ; + } if ((tmp = index(varlist, sep))) { /* Value is delimited by a comma */ if (tmp - varlist == 0) { continue; } - value = (char *)calloc(1, tmp - varlist + 1); - strncpy(value, varlist, tmp - varlist); + value = (char *)calloc(1, (unsigned long)(tmp - varlist + 1)); + strncpy(value, varlist, (unsigned long)(tmp - varlist)); value[tmp - varlist] = '\0'; } else { /* Value is delimited by a \0 */ @@ -392,7 +393,7 @@ char *np_extract_value(const char *varlist, const char *name, char sep) { /* Clean-up trailing spaces/newlines */ if (value) { - for (i = strlen(value) - 1; isspace(value[i]); i--) { + for (unsigned long i = strlen(value) - 1; isspace(value[i]); i--) { value[i] = '\0'; } } @@ -441,11 +442,7 @@ int mp_translate_state(char *state_text) { * parse of argv, so that uniqueness in parameters are reflected there. */ char *_np_state_generate_key(void) { - int i; char **argv = this_monitoring_plugin->argv; - char keyname[41]; - char *p = NULL; - unsigned char result[256]; #ifdef USE_OPENSSL @@ -458,7 +455,7 @@ char *_np_state_generate_key(void) { EVP_DigestInit(ctx, EVP_sha256()); - for (i = 0; i < this_monitoring_plugin->argc; i++) { + for (int i = 0; i < this_monitoring_plugin->argc; i++) { EVP_DigestUpdate(ctx, argv[i], strlen(argv[i])); } @@ -467,24 +464,26 @@ char *_np_state_generate_key(void) { struct sha256_ctx ctx; - for (i = 0; i < this_monitoring_plugin->argc; i++) { + for (int i = 0; i < this_monitoring_plugin->argc; i++) { sha256_process_bytes(argv[i], strlen(argv[i]), &ctx); } sha256_finish_ctx(&ctx, result); #endif // FOUNDOPENSSL - for (i = 0; i < 20; ++i) { + char keyname[41]; + for (int i = 0; i < 20; ++i) { sprintf(&keyname[2 * i], "%02x", result[i]); } keyname[40] = '\0'; - p = strdup(keyname); - if (p == NULL) { + char *keyname_copy = strdup(keyname); + if (keyname_copy == NULL) { die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno)); } - return p; + + return keyname_copy; } void _cleanup_state_data(void) { @@ -525,21 +524,16 @@ char *_np_state_calculate_location_prefix(void) { * UNKNOWN if exception */ void np_enable_state(char *keyname, int expected_data_version) { - state_key *this_state = NULL; - char *temp_filename = NULL; - char *temp_keyname = NULL; - char *p = NULL; - int ret; - if (this_monitoring_plugin == NULL) { die(STATE_UNKNOWN, _("This requires np_init to be called")); } - this_state = (state_key *)calloc(1, sizeof(state_key)); + state_key *this_state = (state_key *)calloc(1, sizeof(state_key)); if (this_state == NULL) { die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); } + char *temp_keyname = NULL; if (keyname == NULL) { temp_keyname = _np_state_generate_key(); } else { @@ -548,13 +542,14 @@ void np_enable_state(char *keyname, int expected_data_version) { die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno)); } } + /* Die if invalid characters used for keyname */ - p = temp_keyname; - while (*p != '\0') { - if (!(isalnum(*p) || *p == '_')) { + char *tmp_char = temp_keyname; + while (*tmp_char != '\0') { + if (!(isalnum(*tmp_char) || *tmp_char == '_')) { die(STATE_UNKNOWN, _("Invalid character for keyname - only alphanumerics or '_'")); } - p++; + tmp_char++; } this_state->name = temp_keyname; this_state->plugin_name = this_monitoring_plugin->plugin_name; @@ -562,9 +557,11 @@ void np_enable_state(char *keyname, int expected_data_version) { this_state->state_data = NULL; /* Calculate filename */ - ret = asprintf(&temp_filename, "%s/%lu/%s/%s", _np_state_calculate_location_prefix(), - (unsigned long)geteuid(), this_monitoring_plugin->plugin_name, this_state->name); - if (ret < 0) { + char *temp_filename = NULL; + int error = + asprintf(&temp_filename, "%s/%lu/%s/%s", _np_state_calculate_location_prefix(), + (unsigned long)geteuid(), this_monitoring_plugin->plugin_name, this_state->name); + if (error < 0) { die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); } @@ -581,19 +578,17 @@ void np_enable_state(char *keyname, int expected_data_version) { * if exceptional error. */ state_data *np_state_read(void) { - state_data *this_state_data = NULL; - FILE *statefile; - bool rc = false; - if (this_monitoring_plugin == NULL) { die(STATE_UNKNOWN, _("This requires np_init to be called")); } + bool error_code = false; + /* Open file. If this fails, no previous state found */ - statefile = fopen(this_monitoring_plugin->state->_filename, "r"); + FILE *statefile = fopen(this_monitoring_plugin->state->_filename, "r"); if (statefile != NULL) { - this_state_data = (state_data *)calloc(1, sizeof(state_data)); + state_data *this_state_data = (state_data *)calloc(1, sizeof(state_data)); if (this_state_data == NULL) { die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); } @@ -601,12 +596,12 @@ state_data *np_state_read(void) { this_state_data->data = NULL; this_monitoring_plugin->state->state_data = this_state_data; - rc = _np_state_read_file(statefile); + error_code = _np_state_read_file(statefile); fclose(statefile); } - if (!rc) { + if (!error_code) { _cleanup_state_data(); } @@ -616,13 +611,17 @@ state_data *np_state_read(void) { /* * Read the state file */ -bool _np_state_read_file(FILE *f) { +bool _np_state_read_file(FILE *state_file) { + time_t current_time; + time(¤t_time); + + /* Note: This introduces a limit of 1024 bytes in the string data */ + char *line = (char *)calloc(1, 1024); + if (line == NULL) { + die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); + } + bool status = false; - size_t pos; - char *line; - int i; - int failure = 0; - time_t current_time, data_time; enum { STATE_FILE_VERSION, STATE_DATA_VERSION, @@ -631,16 +630,9 @@ bool _np_state_read_file(FILE *f) { STATE_DATA_END } expected = STATE_FILE_VERSION; - time(¤t_time); - - /* Note: This introduces a limit of 1024 bytes in the string data */ - line = (char *)calloc(1, 1024); - if (line == NULL) { - die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); - } - - while (!failure && (fgets(line, 1024, f)) != NULL) { - pos = strlen(line); + int failure = 0; + while (!failure && (fgets(line, 1024, state_file)) != NULL) { + size_t pos = strlen(line); if (line[pos - 1] == '\n') { line[pos - 1] = '\0'; } @@ -650,32 +642,32 @@ bool _np_state_read_file(FILE *f) { } switch (expected) { - case STATE_FILE_VERSION: - i = atoi(line); + case STATE_FILE_VERSION: { + int i = atoi(line); if (i != NP_STATE_FORMAT_VERSION) { failure++; } else { expected = STATE_DATA_VERSION; } - break; - case STATE_DATA_VERSION: - i = atoi(line); + } break; + case STATE_DATA_VERSION: { + int i = atoi(line); if (i != this_monitoring_plugin->state->data_version) { failure++; } else { expected = STATE_DATA_TIME; } - break; - case STATE_DATA_TIME: + } break; + case STATE_DATA_TIME: { /* If time > now, error */ - data_time = strtoul(line, NULL, 10); + time_t data_time = strtoul(line, NULL, 10); if (data_time > current_time) { failure++; } else { this_monitoring_plugin->state->state_data->time = data_time; expected = STATE_DATA_TEXT; } - break; + } break; case STATE_DATA_TEXT: this_monitoring_plugin->state->state_data->data = strdup(line); if (this_monitoring_plugin->state->state_data->data == NULL) { @@ -700,27 +692,24 @@ bool _np_state_read_file(FILE *f) { * Will die with UNKNOWN if errors */ void np_state_write_string(time_t data_time, char *data_string) { - FILE *fp; - char *temp_file = NULL; - int fd = 0, result = 0; time_t current_time; - char *directories = NULL; - char *p = NULL; - if (data_time == 0) { time(¤t_time); } else { current_time = data_time; } + int result = 0; + /* If file doesn't currently exist, create directories */ if (access(this_monitoring_plugin->state->_filename, F_OK) != 0) { + char *directories = NULL; result = asprintf(&directories, "%s", this_monitoring_plugin->state->_filename); if (result < 0) { die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); } - for (p = directories + 1; *p; p++) { + for (char *p = directories + 1; *p; p++) { if (*p == '/') { *p = '\0'; if ((access(directories, F_OK) != 0) && (mkdir(directories, S_IRWXU) != 0)) { @@ -734,37 +723,39 @@ void np_state_write_string(time_t data_time, char *data_string) { np_free(directories); } + char *temp_file = NULL; result = asprintf(&temp_file, "%s.XXXXXX", this_monitoring_plugin->state->_filename); if (result < 0) { die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); } - if ((fd = mkstemp(temp_file)) == -1) { + int temp_file_desc = 0; + if ((temp_file_desc = mkstemp(temp_file)) == -1) { np_free(temp_file); die(STATE_UNKNOWN, _("Cannot create temporary filename")); } - fp = (FILE *)fdopen(fd, "w"); - if (fp == NULL) { - close(fd); + FILE *temp_file_pointer = (FILE *)fdopen(temp_file_desc, "w"); + if (temp_file_pointer == NULL) { + close(temp_file_desc); unlink(temp_file); np_free(temp_file); die(STATE_UNKNOWN, _("Unable to open temporary state file")); } - fprintf(fp, "# NP State file\n"); - fprintf(fp, "%d\n", NP_STATE_FORMAT_VERSION); - fprintf(fp, "%d\n", this_monitoring_plugin->state->data_version); - fprintf(fp, "%lu\n", current_time); - fprintf(fp, "%s\n", data_string); + fprintf(temp_file_pointer, "# NP State file\n"); + fprintf(temp_file_pointer, "%d\n", NP_STATE_FORMAT_VERSION); + fprintf(temp_file_pointer, "%d\n", this_monitoring_plugin->state->data_version); + fprintf(temp_file_pointer, "%lu\n", current_time); + fprintf(temp_file_pointer, "%s\n", data_string); - fchmod(fd, S_IRUSR | S_IWUSR | S_IRGRP); + fchmod(temp_file_desc, S_IRUSR | S_IWUSR | S_IRGRP); - fflush(fp); + fflush(temp_file_pointer); - result = fclose(fp); + result = fclose(temp_file_pointer); - fsync(fd); + fsync(temp_file_desc); if (result != 0) { unlink(temp_file); -- cgit v1.2.3-74-g34f1 From 87195f5511bf18db2a64f71ea9783ebbfb33c3a5 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Mon, 8 Sep 2025 15:57:06 +0200 Subject: check_snmp: refactoring + fixes This commit moves the state retention logic to check_snmp as it is only used there and I do not want it to be used at all, so it doesn't get a place in the lib. Otherwise this adapts tests and fixes the rate computing in the refactored version of check_snmp. Also fixes some bugs detected with the tests --- lib/Makefile.am | 2 +- lib/tests/test_utils.c | 190 +------ lib/utils_base.c | 344 ------------ lib/utils_base.h | 22 - plugins/Makefile.am | 14 +- plugins/check_snmp.c | 778 +++++++++++++-------------- plugins/check_snmp.d/check_snmp_helpers.c | 861 +++++++++++++++++++++++++++++- plugins/check_snmp.d/check_snmp_helpers.h | 64 +++ plugins/check_snmp.d/config.h | 25 +- plugins/tests/check_snmp.t | 159 +++--- plugins/tests/check_snmp_agent.pl | 78 ++- plugins/tests/test_check_snmp.c | 175 ++++++ plugins/tests/test_check_snmp.t | 6 + 13 files changed, 1647 insertions(+), 1071 deletions(-) create mode 100644 plugins/tests/test_check_snmp.c create mode 100755 plugins/tests/test_check_snmp.t (limited to 'lib') diff --git a/lib/Makefile.am b/lib/Makefile.am index a9f3ff40..27a08278 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -4,7 +4,7 @@ SUBDIRS = . tests noinst_LIBRARIES = libmonitoringplug.a -AM_CPPFLAGS = -DNP_STATE_DIR_PREFIX=\"$(localstatedir)\" \ +AM_CPPFLAGS = \ -I$(srcdir) -I$(top_srcdir)/gl -I$(top_srcdir)/intl -I$(top_srcdir)/plugins libmonitoringplug_a_SOURCES = utils_base.c utils_tcp.c utils_cmd.c maxfd.c output.c perfdata.c output.c thresholds.c vendor/cJSON/cJSON.c diff --git a/lib/tests/test_utils.c b/lib/tests/test_utils.c index c3150f00..8040dec8 100644 --- a/lib/tests/test_utils.c +++ b/lib/tests/test_utils.c @@ -28,17 +28,7 @@ #include "utils_base.c" int main(int argc, char **argv) { - char state_path[1024]; - range *range; - double temp; - thresholds *thresholds = NULL; - int i, rc; - char *temp_string; - state_key *temp_state_key = NULL; - state_data *temp_state_data; - time_t current_time; - - plan_tests(185); + plan_tests(155); ok(this_monitoring_plugin == NULL, "monitoring_plugin not initialised"); @@ -57,7 +47,7 @@ int main(int argc, char **argv) { np_set_args(argc, argv); - range = parse_range_string("6"); + range *range = parse_range_string("6"); ok(range != NULL, "'6' is valid range"); ok(range->start == 0, "Start correct"); ok(range->start_infinity == false, "Not using negative infinity"); @@ -97,7 +87,7 @@ int main(int argc, char **argv) { free(range); range = parse_range_string("12345678901234567890:"); - temp = atof("12345678901234567890"); /* Can't just use this because number too large */ + double temp = atof("12345678901234567890"); /* Can't just use this because number too large */ ok(range != NULL, "'12345678901234567890:' is valid range"); ok(range->start == temp, "Start correct"); ok(range->start_infinity == false, "Not using negative infinity"); @@ -158,32 +148,34 @@ int main(int argc, char **argv) { range = parse_range_string("2:1"); ok(range == NULL, "'2:1' rejected"); - rc = _set_thresholds(&thresholds, NULL, NULL); - ok(rc == 0, "Thresholds (NULL, NULL) set"); + thresholds *thresholds = NULL; + int returnCode; + returnCode = _set_thresholds(&thresholds, NULL, NULL); + ok(returnCode == 0, "Thresholds (NULL, NULL) set"); ok(thresholds->warning == NULL, "Warning not set"); ok(thresholds->critical == NULL, "Critical not set"); - rc = _set_thresholds(&thresholds, NULL, "80"); - ok(rc == 0, "Thresholds (NULL, '80') set"); + returnCode = _set_thresholds(&thresholds, NULL, "80"); + ok(returnCode == 0, "Thresholds (NULL, '80') set"); ok(thresholds->warning == NULL, "Warning not set"); ok(thresholds->critical->end == 80, "Critical set correctly"); - rc = _set_thresholds(&thresholds, "5:33", NULL); - ok(rc == 0, "Thresholds ('5:33', NULL) set"); + returnCode = _set_thresholds(&thresholds, "5:33", NULL); + ok(returnCode == 0, "Thresholds ('5:33', NULL) set"); ok(thresholds->warning->start == 5, "Warning start set"); ok(thresholds->warning->end == 33, "Warning end set"); ok(thresholds->critical == NULL, "Critical not set"); - rc = _set_thresholds(&thresholds, "30", "60"); - ok(rc == 0, "Thresholds ('30', '60') set"); + returnCode = _set_thresholds(&thresholds, "30", "60"); + ok(returnCode == 0, "Thresholds ('30', '60') set"); ok(thresholds->warning->end == 30, "Warning set correctly"); ok(thresholds->critical->end == 60, "Critical set correctly"); ok(get_status(15.3, thresholds) == STATE_OK, "15.3 - ok"); ok(get_status(30.0001, thresholds) == STATE_WARNING, "30.0001 - warning"); ok(get_status(69, thresholds) == STATE_CRITICAL, "69 - critical"); - rc = _set_thresholds(&thresholds, "-10:-2", "-30:20"); - ok(rc == 0, "Thresholds ('-30:20', '-10:-2') set"); + returnCode = _set_thresholds(&thresholds, "-10:-2", "-30:20"); + ok(returnCode == 0, "Thresholds ('-30:20', '-10:-2') set"); ok(thresholds->warning->start == -10, "Warning start set correctly"); ok(thresholds->warning->end == -2, "Warning end set correctly"); ok(thresholds->critical->start == -30, "Critical start set correctly"); @@ -304,164 +296,28 @@ int main(int argc, char **argv) { test = np_extract_ntpvar("", "foo"); ok(!test, "Empty string return NULL"); - /* This is the result of running ./test_utils */ - temp_string = (char *)_np_state_generate_key(); - ok(!strcmp(temp_string, "e2d17f995fd4c020411b85e3e3d0ff7306d4147e"), "Got hash with exe and no parameters") || - diag("You are probably running in wrong directory. Must run as ./test_utils"); - - this_monitoring_plugin->argc = 4; - this_monitoring_plugin->argv[0] = "./test_utils"; - this_monitoring_plugin->argv[1] = "here"; - this_monitoring_plugin->argv[2] = "--and"; - this_monitoring_plugin->argv[3] = "now"; - temp_string = (char *)_np_state_generate_key(); - ok(!strcmp(temp_string, "bd72da9f78ff1419fad921ea5e43ce56508aef6c"), "Got based on expected argv"); - - unsetenv("MP_STATE_PATH"); - temp_string = (char *)_np_state_calculate_location_prefix(); - ok(!strcmp(temp_string, NP_STATE_DIR_PREFIX), "Got default directory"); - - setenv("MP_STATE_PATH", "", 1); - temp_string = (char *)_np_state_calculate_location_prefix(); - ok(!strcmp(temp_string, NP_STATE_DIR_PREFIX), "Got default directory even with empty string"); - - setenv("MP_STATE_PATH", "/usr/local/nagios/var", 1); - temp_string = (char *)_np_state_calculate_location_prefix(); - ok(!strcmp(temp_string, "/usr/local/nagios/var"), "Got default directory"); - - ok(temp_state_key == NULL, "temp_state_key initially empty"); - - this_monitoring_plugin->argc = 1; - this_monitoring_plugin->argv[0] = "./test_utils"; - np_enable_state(NULL, 51); - temp_state_key = this_monitoring_plugin->state; - ok(!strcmp(temp_state_key->plugin_name, "check_test"), "Got plugin name"); - ok(!strcmp(temp_state_key->name, "e2d17f995fd4c020411b85e3e3d0ff7306d4147e"), "Got generated filename"); - - np_enable_state("allowedchars_in_keyname", 77); - temp_state_key = this_monitoring_plugin->state; - sprintf(state_path, "/usr/local/nagios/var/%lu/check_test/allowedchars_in_keyname", (unsigned long)geteuid()); - ok(!strcmp(temp_state_key->plugin_name, "check_test"), "Got plugin name"); - ok(!strcmp(temp_state_key->name, "allowedchars_in_keyname"), "Got key name with valid chars"); - ok(!strcmp(temp_state_key->_filename, state_path), "Got internal filename"); - - /* Don't do this test just yet. Will die */ - /* - np_enable_state("bad^chars$in@here", 77); - temp_state_key = this_monitoring_plugin->state; - ok( !strcmp(temp_state_key->name, "bad_chars_in_here"), "Got key name with bad chars replaced" ); - */ - - np_enable_state("funnykeyname", 54); - temp_state_key = this_monitoring_plugin->state; - sprintf(state_path, "/usr/local/nagios/var/%lu/check_test/funnykeyname", (unsigned long)geteuid()); - ok(!strcmp(temp_state_key->plugin_name, "check_test"), "Got plugin name"); - ok(!strcmp(temp_state_key->name, "funnykeyname"), "Got key name"); - - ok(!strcmp(temp_state_key->_filename, state_path), "Got internal filename"); - ok(temp_state_key->data_version == 54, "Version set"); - - temp_state_data = np_state_read(); - ok(temp_state_data == NULL, "Got no state data as file does not exist"); - - /* - temp_fp = fopen("var/statefile", "r"); - if (temp_fp==NULL) - printf("Error opening. errno=%d\n", errno); - printf("temp_fp=%s\n", temp_fp); - ok( _np_state_read_file(temp_fp) == true, "Can read state file" ); - fclose(temp_fp); - */ - - temp_state_key->_filename = "var/statefile"; - temp_state_data = np_state_read(); - ok(this_monitoring_plugin->state->state_data != NULL, "Got state data now") || - diag("Are you running in right directory? Will get coredump next if not"); - ok(this_monitoring_plugin->state->state_data->time == 1234567890, "Got time"); - ok(!strcmp((char *)this_monitoring_plugin->state->state_data->data, "String to read"), "Data as expected"); - - temp_state_key->data_version = 53; - temp_state_data = np_state_read(); - ok(temp_state_data == NULL, "Older data version gives NULL"); - temp_state_key->data_version = 54; - - temp_state_key->_filename = "var/nonexistent"; - temp_state_data = np_state_read(); - ok(temp_state_data == NULL, "Missing file gives NULL"); - ok(this_monitoring_plugin->state->state_data == NULL, "No state information"); - - temp_state_key->_filename = "var/oldformat"; - temp_state_data = np_state_read(); - ok(temp_state_data == NULL, "Old file format gives NULL"); - - temp_state_key->_filename = "var/baddate"; - temp_state_data = np_state_read(); - ok(temp_state_data == NULL, "Bad date gives NULL"); - - temp_state_key->_filename = "var/missingdataline"; - temp_state_data = np_state_read(); - ok(temp_state_data == NULL, "Missing data line gives NULL"); - - unlink("var/generated"); - temp_state_key->_filename = "var/generated"; - current_time = 1234567890; - np_state_write_string(current_time, "String to read"); - ok(system("cmp var/generated var/statefile") == 0, "Generated file same as expected"); - - unlink("var/generated_directory/statefile"); - unlink("var/generated_directory"); - temp_state_key->_filename = "var/generated_directory/statefile"; - current_time = 1234567890; - np_state_write_string(current_time, "String to read"); - ok(system("cmp var/generated_directory/statefile var/statefile") == 0, "Have created directory"); - - /* This test to check cannot write to dir - can't automate yet */ - /* - unlink("var/generated_bad_dir"); - mkdir("var/generated_bad_dir", S_IRUSR); - np_state_write_string(current_time, "String to read"); - */ - - temp_state_key->_filename = "var/generated"; - time(¤t_time); - np_state_write_string(0, "String to read"); - temp_state_data = np_state_read(); - /* Check time is set to current_time */ - ok(system("cmp var/generated var/statefile > /dev/null") != 0, "Generated file should be different this time"); - ok(this_monitoring_plugin->state->state_data->time - current_time <= 1, "Has time generated from current time"); - - /* Don't know how to automatically test this. Need to be able to redefine die and catch the error */ - /* - temp_state_key->_filename="/dev/do/not/expect/to/be/able/to/write"; - np_state_write_string(0, "Bad file"); - */ - - np_cleanup(); - - ok(this_monitoring_plugin == NULL, "Free'd this_monitoring_plugin"); - ok(mp_suid() == false, "Test aren't suid"); /* base states with random case */ char *states[] = {"Ok", "wArnINg", "cRiTIcaL", "UnKNoWN", NULL}; - for (i = 0; states[i] != NULL; i++) { - /* out of the random case states, create the lower and upper versions + numeric string one */ + for (int i = 0; states[i] != NULL; i++) { + /* out of the random case states, create the lower and upper versions + numeric string one + */ char *statelower = strdup(states[i]); char *stateupper = strdup(states[i]); char statenum[2]; - char *temp_ptr; - for (temp_ptr = statelower; *temp_ptr; temp_ptr++) { - *temp_ptr = tolower(*temp_ptr); + for (char *temp_ptr = statelower; *temp_ptr; temp_ptr++) { + *temp_ptr = (char)tolower(*temp_ptr); } - for (temp_ptr = stateupper; *temp_ptr; temp_ptr++) { - *temp_ptr = toupper(*temp_ptr); + for (char *temp_ptr = stateupper; *temp_ptr; temp_ptr++) { + *temp_ptr = (char)toupper(*temp_ptr); } snprintf(statenum, 2, "%i", i); /* Base test names, we'll append the state string */ char testname[64] = "Translate state string: "; - int tlen = strlen(testname); + size_t tlen = strlen(testname); strcpy(testname + tlen, states[i]); ok(i == mp_translate_state(states[i]), testname); diff --git a/lib/utils_base.c b/lib/utils_base.c index 43e88e7a..29b393d0 100644 --- a/lib/utils_base.c +++ b/lib/utils_base.c @@ -74,14 +74,6 @@ void np_set_args(int argc, char **argv) { void np_cleanup(void) { if (this_monitoring_plugin != NULL) { - if (this_monitoring_plugin->state != NULL) { - if (this_monitoring_plugin->state->state_data) { - np_free(this_monitoring_plugin->state->state_data->data); - np_free(this_monitoring_plugin->state->state_data); - } - np_free(this_monitoring_plugin->state->name); - np_free(this_monitoring_plugin->state); - } np_free(this_monitoring_plugin->plugin_name); np_free(this_monitoring_plugin); } @@ -435,339 +427,3 @@ int mp_translate_state(char *state_text) { } return ERROR; } - -/* - * Returns a string to use as a keyname, based on an md5 hash of argv, thus - * hopefully a unique key per service/plugin invocation. Use the extra-opts - * parse of argv, so that uniqueness in parameters are reflected there. - */ -char *_np_state_generate_key(void) { - char **argv = this_monitoring_plugin->argv; - unsigned char result[256]; - -#ifdef USE_OPENSSL - /* - * This code path is chosen if openssl is available (which should be the most common - * scenario). Alternatively, the gnulib implementation/ - * - */ - EVP_MD_CTX *ctx = EVP_MD_CTX_new(); - - EVP_DigestInit(ctx, EVP_sha256()); - - for (int i = 0; i < this_monitoring_plugin->argc; i++) { - EVP_DigestUpdate(ctx, argv[i], strlen(argv[i])); - } - - EVP_DigestFinal(ctx, result, NULL); -#else - - struct sha256_ctx ctx; - - for (int i = 0; i < this_monitoring_plugin->argc; i++) { - sha256_process_bytes(argv[i], strlen(argv[i]), &ctx); - } - - sha256_finish_ctx(&ctx, result); -#endif // FOUNDOPENSSL - - char keyname[41]; - for (int i = 0; i < 20; ++i) { - sprintf(&keyname[2 * i], "%02x", result[i]); - } - - keyname[40] = '\0'; - - char *keyname_copy = strdup(keyname); - if (keyname_copy == NULL) { - die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno)); - } - - return keyname_copy; -} - -void _cleanup_state_data(void) { - if (this_monitoring_plugin->state->state_data != NULL) { - np_free(this_monitoring_plugin->state->state_data->data); - np_free(this_monitoring_plugin->state->state_data); - } -} - -/* - * Internal function. Returns either: - * envvar NAGIOS_PLUGIN_STATE_DIRECTORY - * statically compiled shared state directory - */ -char *_np_state_calculate_location_prefix(void) { - char *env_dir; - - /* Do not allow passing MP_STATE_PATH in setuid plugins - * for security reasons */ - if (!mp_suid()) { - env_dir = getenv("MP_STATE_PATH"); - if (env_dir && env_dir[0] != '\0') { - return env_dir; - } - /* This is the former ENV, for backward-compatibility */ - env_dir = getenv("NAGIOS_PLUGIN_STATE_DIRECTORY"); - if (env_dir && env_dir[0] != '\0') { - return env_dir; - } - } - - return NP_STATE_DIR_PREFIX; -} - -/* - * Initiatializer for state routines. - * Sets variables. Generates filename. Returns np_state_key. die with - * UNKNOWN if exception - */ -void np_enable_state(char *keyname, int expected_data_version) { - if (this_monitoring_plugin == NULL) { - die(STATE_UNKNOWN, _("This requires np_init to be called")); - } - - state_key *this_state = (state_key *)calloc(1, sizeof(state_key)); - if (this_state == NULL) { - die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); - } - - char *temp_keyname = NULL; - if (keyname == NULL) { - temp_keyname = _np_state_generate_key(); - } else { - temp_keyname = strdup(keyname); - if (temp_keyname == NULL) { - die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno)); - } - } - - /* Die if invalid characters used for keyname */ - char *tmp_char = temp_keyname; - while (*tmp_char != '\0') { - if (!(isalnum(*tmp_char) || *tmp_char == '_')) { - die(STATE_UNKNOWN, _("Invalid character for keyname - only alphanumerics or '_'")); - } - tmp_char++; - } - this_state->name = temp_keyname; - this_state->plugin_name = this_monitoring_plugin->plugin_name; - this_state->data_version = expected_data_version; - this_state->state_data = NULL; - - /* Calculate filename */ - char *temp_filename = NULL; - int error = - asprintf(&temp_filename, "%s/%lu/%s/%s", _np_state_calculate_location_prefix(), - (unsigned long)geteuid(), this_monitoring_plugin->plugin_name, this_state->name); - if (error < 0) { - die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); - } - - this_state->_filename = temp_filename; - - this_monitoring_plugin->state = this_state; -} - -/* - * Will return NULL if no data is available (first run). If key currently - * exists, read data. If state file format version is not expected, return - * as if no data. Get state data version number and compares to expected. - * If numerically lower, then return as no previous state. die with UNKNOWN - * if exceptional error. - */ -state_data *np_state_read(void) { - if (this_monitoring_plugin == NULL) { - die(STATE_UNKNOWN, _("This requires np_init to be called")); - } - - bool error_code = false; - - /* Open file. If this fails, no previous state found */ - FILE *statefile = fopen(this_monitoring_plugin->state->_filename, "r"); - if (statefile != NULL) { - - state_data *this_state_data = (state_data *)calloc(1, sizeof(state_data)); - if (this_state_data == NULL) { - die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); - } - - this_state_data->data = NULL; - this_monitoring_plugin->state->state_data = this_state_data; - - error_code = _np_state_read_file(statefile); - - fclose(statefile); - } - - if (!error_code) { - _cleanup_state_data(); - } - - return this_monitoring_plugin->state->state_data; -} - -/* - * Read the state file - */ -bool _np_state_read_file(FILE *state_file) { - time_t current_time; - time(¤t_time); - - /* Note: This introduces a limit of 1024 bytes in the string data */ - char *line = (char *)calloc(1, 1024); - if (line == NULL) { - die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); - } - - bool status = false; - enum { - STATE_FILE_VERSION, - STATE_DATA_VERSION, - STATE_DATA_TIME, - STATE_DATA_TEXT, - STATE_DATA_END - } expected = STATE_FILE_VERSION; - - int failure = 0; - while (!failure && (fgets(line, 1024, state_file)) != NULL) { - size_t pos = strlen(line); - if (line[pos - 1] == '\n') { - line[pos - 1] = '\0'; - } - - if (line[0] == '#') { - continue; - } - - switch (expected) { - case STATE_FILE_VERSION: { - int i = atoi(line); - if (i != NP_STATE_FORMAT_VERSION) { - failure++; - } else { - expected = STATE_DATA_VERSION; - } - } break; - case STATE_DATA_VERSION: { - int i = atoi(line); - if (i != this_monitoring_plugin->state->data_version) { - failure++; - } else { - expected = STATE_DATA_TIME; - } - } break; - case STATE_DATA_TIME: { - /* If time > now, error */ - time_t data_time = strtoul(line, NULL, 10); - if (data_time > current_time) { - failure++; - } else { - this_monitoring_plugin->state->state_data->time = data_time; - expected = STATE_DATA_TEXT; - } - } break; - case STATE_DATA_TEXT: - this_monitoring_plugin->state->state_data->data = strdup(line); - if (this_monitoring_plugin->state->state_data->data == NULL) { - die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno)); - } - expected = STATE_DATA_END; - status = true; - break; - case STATE_DATA_END:; - } - } - - np_free(line); - return status; -} - -/* - * If time=NULL, use current time. Create state file, with state format - * version, default text. Writes version, time, and data. Avoid locking - * problems - use mv to write and then swap. Possible loss of state data if - * two things writing to same key at same time. - * Will die with UNKNOWN if errors - */ -void np_state_write_string(time_t data_time, char *data_string) { - time_t current_time; - if (data_time == 0) { - time(¤t_time); - } else { - current_time = data_time; - } - - int result = 0; - - /* If file doesn't currently exist, create directories */ - if (access(this_monitoring_plugin->state->_filename, F_OK) != 0) { - char *directories = NULL; - result = asprintf(&directories, "%s", this_monitoring_plugin->state->_filename); - if (result < 0) { - die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); - } - - for (char *p = directories + 1; *p; p++) { - if (*p == '/') { - *p = '\0'; - if ((access(directories, F_OK) != 0) && (mkdir(directories, S_IRWXU) != 0)) { - /* Can't free this! Otherwise error message is wrong! */ - /* np_free(directories); */ - die(STATE_UNKNOWN, _("Cannot create directory: %s"), directories); - } - *p = '/'; - } - } - np_free(directories); - } - - char *temp_file = NULL; - result = asprintf(&temp_file, "%s.XXXXXX", this_monitoring_plugin->state->_filename); - if (result < 0) { - die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); - } - - int temp_file_desc = 0; - if ((temp_file_desc = mkstemp(temp_file)) == -1) { - np_free(temp_file); - die(STATE_UNKNOWN, _("Cannot create temporary filename")); - } - - FILE *temp_file_pointer = (FILE *)fdopen(temp_file_desc, "w"); - if (temp_file_pointer == NULL) { - close(temp_file_desc); - unlink(temp_file); - np_free(temp_file); - die(STATE_UNKNOWN, _("Unable to open temporary state file")); - } - - fprintf(temp_file_pointer, "# NP State file\n"); - fprintf(temp_file_pointer, "%d\n", NP_STATE_FORMAT_VERSION); - fprintf(temp_file_pointer, "%d\n", this_monitoring_plugin->state->data_version); - fprintf(temp_file_pointer, "%lu\n", current_time); - fprintf(temp_file_pointer, "%s\n", data_string); - - fchmod(temp_file_desc, S_IRUSR | S_IWUSR | S_IRGRP); - - fflush(temp_file_pointer); - - result = fclose(temp_file_pointer); - - fsync(temp_file_desc); - - if (result != 0) { - unlink(temp_file); - np_free(temp_file); - die(STATE_UNKNOWN, _("Error writing temp file")); - } - - if (rename(temp_file, this_monitoring_plugin->state->_filename) != 0) { - unlink(temp_file); - np_free(temp_file); - die(STATE_UNKNOWN, _("Cannot rename state temp file")); - } - - np_free(temp_file); -} diff --git a/lib/utils_base.h b/lib/utils_base.h index 123066f8..f1c99a54 100644 --- a/lib/utils_base.h +++ b/lib/utils_base.h @@ -8,7 +8,6 @@ #include "./perfdata.h" #include "./thresholds.h" - #ifndef USE_OPENSSL # include "sha256.h" #endif @@ -26,25 +25,8 @@ #define OUTSIDE 0 #define INSIDE 1 -#define NP_STATE_FORMAT_VERSION 1 - -typedef struct state_data_struct { - time_t time; - void *data; - int length; /* Of binary data */ -} state_data; - -typedef struct state_key_struct { - char *name; - char *plugin_name; - int data_version; - char *_filename; - state_data *state_data; -} state_key; - typedef struct np_struct { char *plugin_name; - state_key *state; int argc; char **argv; } monitoring_plugin; @@ -100,10 +82,6 @@ char *np_extract_value(const char *, const char *, char); */ int mp_translate_state(char *); -void np_enable_state(char *, int); -state_data *np_state_read(void); -void np_state_write_string(time_t, char *); - void np_init(char *, int argc, char **argv); void np_set_args(int argc, char **argv); void np_cleanup(void); diff --git a/plugins/Makefile.am b/plugins/Makefile.am index f2f1777f..deae938d 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -13,8 +13,14 @@ AM_CFLAGS = -DNP_VERSION='"$(NP_VERSION)"' VPATH = $(top_srcdir) $(top_srcdir)/lib $(top_srcdir)/plugins $(top_srcdir)/plugins/t -AM_CPPFLAGS = -I.. -I$(top_srcdir)/lib -I$(top_srcdir)/gl -I$(top_srcdir)/intl \ - @LDAPINCLUDE@ @PGINCLUDE@ @SSLINCLUDE@ +AM_CPPFLAGS = -I.. \ + -I$(top_srcdir)/lib \ + -I$(top_srcdir)/gl \ + -I$(top_srcdir)/intl \ + -DNP_STATE_DIR_PREFIX=\"$(localstatedir)\" \ + @LDAPINCLUDE@ \ + @PGINCLUDE@ \ + @SSLINCLUDE@ localedir = $(datadir)/locale # gettext docs say to use AM_CPPFLAGS, but per module_CPPFLAGS override this @@ -42,11 +48,13 @@ EXTRA_PROGRAMS = check_mysql check_radius check_pgsql check_hpjd \ check_procs check_mysql_query check_apt check_dbi check_curl \ \ tests/test_check_swap \ + tests/test_check_snmp \ tests/test_check_disk SUBDIRS = picohttpparser np_test_scripts = tests/test_check_swap.t \ + tests/test_check_snmp.t \ tests/test_check_disk.t EXTRA_DIST = t \ @@ -178,6 +186,8 @@ endif tests_test_check_swap_LDADD = $(BASEOBJS) $(tap_ldflags) -ltap tests_test_check_swap_SOURCES = tests/test_check_swap.c check_swap.d/swap.c +tests_test_check_snmp_LDADD = $(BASEOBJS) $(tap_ldflags) -ltap +tests_test_check_snmp_SOURCES = tests/test_check_snmp.c check_snmp.d/check_snmp_helpers.c tests_test_check_disk_LDADD = $(BASEOBJS) $(tap_ldflags) check_disk.d/utils_disk.c -ltap tests_test_check_disk_SOURCES = tests/test_check_disk.c diff --git a/plugins/check_snmp.c b/plugins/check_snmp.c index 3c054259..a5a7afe8 100644 --- a/plugins/check_snmp.c +++ b/plugins/check_snmp.c @@ -37,10 +37,8 @@ const char *email = "devel@monitoring-plugins.org"; #include "./utils.h" #include "../lib/states.h" -#include "../lib/thresholds.h" #include "../lib/utils_base.h" #include "../lib/output.h" -#include "../lib/perfdata.h" #include "check_snmp.d/check_snmp_helpers.h" #include @@ -49,6 +47,7 @@ const char *email = "devel@monitoring-plugins.org"; #include #include "check_snmp.d/config.h" +#include #include #include #include @@ -63,6 +62,7 @@ const char *email = "devel@monitoring-plugins.org"; #include #include #include "../gl/regex.h" +#include "../gl/base64.h" #include const char DEFAULT_COMMUNITY[] = "public"; @@ -86,7 +86,168 @@ static char *get_next_argument(char *str); void print_usage(void); void print_help(void); -static int verbose = 0; +int verbose = 0; + +typedef struct { + int errorcode; + char *state_string; +} gen_state_string_type; +gen_state_string_type gen_state_string(check_snmp_state_entry *entries, size_t num_of_entries) { + char *encoded_string = NULL; + gen_state_string_type result = {.errorcode = OK, .state_string = NULL}; + + if (verbose > 1) { + printf("%s:\n", __FUNCTION__); + for (size_t i = 0; i < num_of_entries; i++) { + printf("Entry timestamp %lu: %s", entries[i].timestamp, ctime(&entries[i].timestamp)); + switch (entries[i].type) { + case ASN_GAUGE: + printf("Type GAUGE\n"); + break; + case ASN_TIMETICKS: + printf("Type TIMETICKS\n"); + break; + case ASN_COUNTER: + printf("Type COUNTER\n"); + break; + case ASN_UINTEGER: + printf("Type UINTEGER\n"); + break; + case ASN_COUNTER64: + printf("Type COUNTER64\n"); + break; + case ASN_FLOAT: + printf("Type FLOAT\n"); + case ASN_DOUBLE: + printf("Type DOUBLE\n"); + break; + case ASN_INTEGER: + printf("Type INTEGER\n"); + break; + } + + switch (entries[i].type) { + case ASN_GAUGE: + case ASN_TIMETICKS: + case ASN_COUNTER: + case ASN_UINTEGER: + case ASN_COUNTER64: + printf("Value %llu\n", entries[i].value.uIntVal); + break; + case ASN_FLOAT: + case ASN_DOUBLE: + printf("Value %f\n", entries[i].value.doubleVal); + break; + case ASN_INTEGER: + printf("Value %lld\n", entries[i].value.intVal); + break; + } + } + } + + idx_t encoded = base64_encode_alloc((const char *)entries, + (idx_t)(num_of_entries * sizeof(check_snmp_state_entry)), + &encoded_string); + + if (encoded > 0 && encoded_string != NULL) { + // success + if (verbose > 1) { + printf("encoded string: %s\n", encoded_string); + printf("encoded string length: %lu\n", strlen(encoded_string)); + } + result.state_string = encoded_string; + return result; + } + result.errorcode = ERROR; + return result; +} + +typedef struct { + int errorcode; + check_snmp_state_entry *state; +} recover_state_data_type; +recover_state_data_type recover_state_data(char *state_string, idx_t state_string_length) { + recover_state_data_type result = {.errorcode = OK, .state = NULL}; + + if (verbose > 1) { + printf("%s:\n", __FUNCTION__); + printf("State string: %s\n", state_string); + printf("State string length: %lu\n", state_string_length); + } + + idx_t outlen = 0; + bool decoded = + base64_decode_alloc(state_string, state_string_length, (char **)&result.state, &outlen); + + if (!decoded) { + if (verbose) { + printf("Failed to decode state string\n"); + } + // failure to decode + result.errorcode = ERROR; + return result; + } + + if (result.state == NULL) { + // Memory Error? + result.errorcode = ERROR; + return result; + } + + if (verbose > 1) { + printf("Recovered %lu entries of size %lu\n", + (size_t)outlen / sizeof(check_snmp_state_entry), outlen); + + for (size_t i = 0; i < (size_t)outlen / sizeof(check_snmp_state_entry); i++) { + printf("Entry timestamp %lu: %s", result.state[i].timestamp, + ctime(&result.state[i].timestamp)); + switch (result.state[i].type) { + case ASN_GAUGE: + printf("Type GAUGE\n"); + break; + case ASN_TIMETICKS: + printf("Type TIMETICKS\n"); + break; + case ASN_COUNTER: + printf("Type COUNTER\n"); + break; + case ASN_UINTEGER: + printf("Type UINTEGER\n"); + break; + case ASN_COUNTER64: + printf("Type COUNTER64\n"); + break; + case ASN_FLOAT: + printf("Type FLOAT\n"); + case ASN_DOUBLE: + printf("Type DOUBLE\n"); + break; + case ASN_INTEGER: + printf("Type INTEGER\n"); + break; + } + + switch (result.state[i].type) { + case ASN_GAUGE: + case ASN_TIMETICKS: + case ASN_COUNTER: + case ASN_UINTEGER: + case ASN_COUNTER64: + printf("Value %llu\n", result.state[i].value.uIntVal); + break; + case ASN_FLOAT: + case ASN_DOUBLE: + printf("Value %f\n", result.state[i].value.doubleVal); + break; + case ASN_INTEGER: + printf("Value %lld\n", result.state[i].value.intVal); + break; + } + } + } + + return result; +} int main(int argc, char **argv) { setlocale(LC_ALL, ""); @@ -97,6 +258,8 @@ int main(int argc, char **argv) { np_init((char *)progname, argc, argv); + state_key stateKey = np_enable_state(NULL, 1, progname, argc, argv); + /* Parse extra opts if any */ argv = np_extra_opts(&argc, argv, progname); @@ -105,9 +268,6 @@ int main(int argc, char **argv) { // Initialize net-snmp before touching the session we are going to use init_snmp("check_snmp"); - time_t current_time; - time(¤t_time); - process_arguments_wrapper paw_tmp = process_arguments(argc, argv); if (paw_tmp.errorcode == ERROR) { usage4(_("Could not parse arguments")); @@ -119,347 +279,103 @@ int main(int argc, char **argv) { mp_set_format(config.output_format); } - if (config.ignore_mib_parsing_errors) { - char *opt_toggle_res = snmp_mib_toggle_options("e"); - if (opt_toggle_res != NULL) { - die(STATE_UNKNOWN, "Unable to disable MIB parsing errors"); - } - } - - struct snmp_pdu *pdu = NULL; - if (config.use_getnext) { - pdu = snmp_pdu_create(SNMP_MSG_GETNEXT); - } else { - pdu = snmp_pdu_create(SNMP_MSG_GET); - } - - for (size_t i = 0; i < config.num_of_test_units; i++) { - assert(config.test_units[i].oid != NULL); - if (verbose > 0) { - printf("OID %zu to parse: %s\n", i, config.test_units[i].oid); - } - - oid tmp_OID[MAX_OID_LEN]; - size_t tmp_OID_len = MAX_OID_LEN; - if (snmp_parse_oid(config.test_units[i].oid, tmp_OID, &tmp_OID_len) != NULL) { - // success - snmp_add_null_var(pdu, tmp_OID, tmp_OID_len); - } else { - // failed - snmp_perror("Parsing failure"); - die(STATE_UNKNOWN, "Failed to parse OID\n"); - } - } - /* Set signal handling and alarm */ if (signal(SIGALRM, runcmd_timeout_alarm_handler) == SIG_ERR) { usage4(_("Cannot catch SIGALRM")); } - const int timeout_safety_tolerance = 5; - alarm((timeout_interval * (unsigned int)config.snmp_session.retries) + - timeout_safety_tolerance); - - struct snmp_session *active_session = snmp_open(&config.snmp_session); - if (active_session == NULL) { - int pcliberr = 0; - int psnmperr = 0; - char *pperrstring = NULL; - snmp_error(&config.snmp_session, &pcliberr, &psnmperr, &pperrstring); - die(STATE_UNKNOWN, "Failed to open SNMP session: %s\n", pperrstring); - } - - struct snmp_pdu *response = NULL; - int snmp_query_status = snmp_synch_response(active_session, pdu, &response); - - if (!(snmp_query_status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR)) { - int pcliberr = 0; - int psnmperr = 0; - char *pperrstring = NULL; - snmp_error(active_session, &pcliberr, &psnmperr, &pperrstring); + time_t current_time; + time(¤t_time); - if (psnmperr == SNMPERR_TIMEOUT) { - // We exit with critical here for some historical reason - die(STATE_CRITICAL, "SNMP query ran into a timeout\n"); - } - die(STATE_UNKNOWN, "SNMP query failed: %s\n", pperrstring); + if (verbose > 2) { + printf("current time: %s (timestamp: %lu)\n", ctime(¤t_time), current_time); } - snmp_close(active_session); - - /* disable alarm again */ - alarm(0); + snmp_responces response = do_snmp_query(config.snmp_params); mp_check overall = mp_check_init(); - mp_subcheck sc_successfull_query = mp_subcheck_init(); - xasprintf(&sc_successfull_query.output, "SNMP query was successful"); - sc_successfull_query = mp_set_subcheck_state(sc_successfull_query, STATE_OK); - mp_add_subcheck_to_check(&overall, sc_successfull_query); - - // We got the the query results, now process them - size_t loop_index = 0; - for (netsnmp_variable_list *vars = response->variables; vars; - vars = vars->next_variable, loop_index++) { - mp_subcheck sc_oid_test = mp_subcheck_init(); + if (response.errorcode == OK) { + mp_subcheck sc_successfull_query = mp_subcheck_init(); + xasprintf(&sc_successfull_query.output, "SNMP query was successful"); + sc_successfull_query = mp_set_subcheck_state(sc_successfull_query, STATE_OK); + mp_add_subcheck_to_check(&overall, sc_successfull_query); + } else { + // Error treatment here, either partial or whole + mp_subcheck sc_failed_query = mp_subcheck_init(); + xasprintf(&sc_failed_query.output, "SNMP query failed"); + sc_failed_query = mp_set_subcheck_state(sc_failed_query, STATE_OK); + mp_add_subcheck_to_check(&overall, sc_failed_query); + mp_exit(overall); + } - if (verbose > 0) { - printf("loop_index: %zu\n", loop_index); - } + check_snmp_state_entry *prev_state = NULL; + bool have_previous_state = false; - if ((config.test_units[loop_index].label != NULL) && - (strcmp(config.test_units[loop_index].label, "") != 0)) { - xasprintf(&sc_oid_test.output, "%s - ", config.test_units[loop_index].label); + if (config.evaluation_params.calculate_rate) { + state_data *previous_state = np_state_read(stateKey); + if (previous_state == NULL) { + // failed to recover state + // or no previous state + have_previous_state = false; } else { - sc_oid_test.output = strdup(""); - } - - char oid_string[(MAX_OID_LEN * 2) + 1] = {}; - - int oid_string_result = - snprint_objid(oid_string, (MAX_OID_LEN * 2) + 1, vars->name, vars->name_length); - if (oid_string_result <= 0) { - // TODO error here - } - - if (verbose > 2) { - printf("Processing oid %s\n", oid_string); - } + // sanity check + recover_state_data_type prev_state_wrapper = + recover_state_data(previous_state->data, (idx_t)previous_state->length); - mp_perfdata_value pd_result_val = {0}; - xasprintf(&sc_oid_test.output, "%sOID: %s", sc_oid_test.output, oid_string); - sc_oid_test = mp_set_subcheck_default_state(sc_oid_test, STATE_OK); - - switch (vars->type) { - case ASN_OCTET_STR: { - if (verbose) { - printf("Debug: Got a string\n"); - } - - char *tmp = (char *)vars->val.string; - - if (strchr(tmp, '"') != NULL) { - // got double quote in the string - if (strchr(tmp, '\'') != NULL) { - // got single quote in the string too - // dont quote that at all to avoid even more confusion - xasprintf(&sc_oid_test.output, "%s - Value: %s", sc_oid_test.output, tmp); - } else { - // quote with single quotes - xasprintf(&sc_oid_test.output, "%s - Value: '%s'", sc_oid_test.output, tmp); - } + if (prev_state_wrapper.errorcode == OK) { + have_previous_state = true; + prev_state = prev_state_wrapper.state; } else { - // quote with double quotes - xasprintf(&sc_oid_test.output, "%s - Value: \"%s\"", sc_oid_test.output, tmp); - } - - if (strlen(tmp) == 0) { - sc_oid_test = mp_set_subcheck_state(sc_oid_test, config.nulloid_result); + have_previous_state = false; + prev_state = NULL; } - - // String matching test - if ((config.test_units[loop_index].eval_mthd.crit_string)) { - if (strcmp(tmp, config.string_cmp_value)) { - sc_oid_test = mp_set_subcheck_state( - sc_oid_test, (config.invert_search) ? STATE_CRITICAL : STATE_OK); - } else { - sc_oid_test = mp_set_subcheck_state( - sc_oid_test, (config.invert_search) ? STATE_OK : STATE_CRITICAL); - } - } else if (config.test_units[loop_index].eval_mthd.crit_regex) { - const size_t nmatch = config.regex_cmp_value.re_nsub + 1; - regmatch_t pmatch[nmatch]; - memset(pmatch, '\0', sizeof(regmatch_t) * nmatch); - - int excode = regexec(&config.regex_cmp_value, tmp, nmatch, pmatch, 0); - if (excode == 0) { - sc_oid_test = mp_set_subcheck_state( - sc_oid_test, (config.invert_search) ? STATE_OK : STATE_CRITICAL); - } else if (excode != REG_NOMATCH) { - char errbuf[MAX_INPUT_BUFFER] = ""; - regerror(excode, &config.regex_cmp_value, errbuf, MAX_INPUT_BUFFER); - printf(_("Execute Error: %s\n"), errbuf); - exit(STATE_CRITICAL); - } else { // REG_NOMATCH - sc_oid_test = mp_set_subcheck_state( - sc_oid_test, config.invert_search ? STATE_CRITICAL : STATE_OK); - } - } - - mp_add_subcheck_to_check(&overall, sc_oid_test); } - continue; - case ASN_OPAQUE: - if (verbose) { - printf("Debug: Got OPAQUE\n"); - } - break; - case ASN_COUNTER64: { - if (verbose) { - printf("Debug: Got counter64\n"); - } - struct counter64 tmp = *(vars->val.counter64); - uint64_t counter = (tmp.high << 32) + tmp.low; - - if (config.multiplier_set || config.offset_set) { - double processed = 0; - if (config.multiplier_set) { - processed = (double)counter * config.multiplier; - } - - if (config.offset_set) { - processed += config.offset; - } - pd_result_val = mp_create_pd_value(processed); - } else { - pd_result_val = mp_create_pd_value(counter); - } - - } break; - /* Numerical values */ - case ASN_GAUGE: // same as ASN_UNSIGNED - case ASN_TIMETICKS: - case ASN_COUNTER: - case ASN_UINTEGER: { - if (verbose) { - printf("Debug: Got a Integer like\n"); - } - unsigned long tmp = (unsigned long)*(vars->val.integer); - - if (config.multiplier_set || config.offset_set) { - double processed = 0; - if (config.multiplier_set) { - processed = (double)tmp * config.multiplier; - } + } - if (config.offset_set) { - processed += config.offset; - } - pd_result_val = mp_create_pd_value(processed); - } else { - pd_result_val = mp_create_pd_value(tmp); - } - break; + check_snmp_state_entry *new_state = NULL; + if (config.evaluation_params.calculate_rate) { + new_state = calloc(config.snmp_params.num_of_test_units, sizeof(check_snmp_state_entry)); + if (new_state == NULL) { + die(STATE_UNKNOWN, "memory allocation failed"); } - case ASN_INTEGER: { - if (verbose) { - printf("Debug: Got a Integer\n"); - } - - long tmp = *(vars->val.integer); - - if (config.multiplier_set || config.offset_set) { - double processed = 0; - if (config.multiplier_set) { - processed = (double)tmp * config.multiplier; - } - - if (config.offset_set) { - processed += config.offset; - } - pd_result_val = mp_create_pd_value(processed); - } else { - pd_result_val = mp_create_pd_value(tmp); - } - - } break; - case ASN_FLOAT: { - if (verbose) { - printf("Debug: Got a float\n"); - } - double tmp = *(vars->val.floatVal); - - if (config.multiplier_set) { - tmp *= config.multiplier; - } - - if (config.offset_set) { - tmp += config.offset; - } + } - pd_result_val = mp_create_pd_value(tmp); - break; + // We got the the query results, now process them + for (size_t loop_index = 0; loop_index < config.snmp_params.num_of_test_units; loop_index++) { + if (verbose > 0) { + printf("loop_index: %zu\n", loop_index); } - case ASN_DOUBLE: { - if (verbose) { - printf("Debug: Got a double\n"); - } - double tmp = *(vars->val.doubleVal); - if (config.multiplier_set) { - tmp *= config.multiplier; - } - - if (config.offset_set) { - tmp += config.offset; - } - pd_result_val = mp_create_pd_value(tmp); - break; + check_snmp_state_entry previous_unit_state = {}; + if (config.evaluation_params.calculate_rate && have_previous_state) { + previous_unit_state = prev_state[loop_index]; } - case ASN_IPADDRESS: - if (verbose) { - printf("Debug: Got an IP address\n"); - } - continue; - default: - if (verbose) { - printf("Debug: Got a unmatched result type: %hhu\n", vars->type); - } - // TODO: Error here? - continue; - } - - // some kind of numerical value - mp_perfdata pd_num_val = { - .value = pd_result_val, - }; - if (!config.use_perf_data_labels_from_input) { - // Use oid for perdata label - pd_num_val.label = strdup(oid_string); - // TODO strdup error checking - } else if (config.test_units[loop_index].label != NULL && - strcmp(config.test_units[loop_index].label, "") != 0) { - pd_num_val.label = config.test_units[loop_index].label; - } else { - pd_num_val.label = config.test_units[loop_index].oid; - } + check_snmp_evaluation single_eval = + evaluate_single_unit(response.response_values[loop_index], config.evaluation_params, + config.snmp_params.test_units[loop_index], current_time, + previous_unit_state, have_previous_state); - if (config.test_units[loop_index].unit_value != NULL && - strcmp(config.test_units[loop_index].unit_value, "") != 0) { - pd_num_val.uom = config.test_units[loop_index].unit_value; + if (config.evaluation_params.calculate_rate && + mp_compute_subcheck_state(single_eval.sc) != STATE_UNKNOWN) { + new_state[loop_index] = single_eval.state; } - xasprintf(&sc_oid_test.output, "%s Value: %s", sc_oid_test.output, - pd_value_to_string(pd_result_val)); + mp_add_subcheck_to_check(&overall, single_eval.sc); + } - if (config.test_units[loop_index].unit_value != NULL && - strcmp(config.test_units[loop_index].unit_value, "") != 0) { - xasprintf(&sc_oid_test.output, "%s%s", sc_oid_test.output, - config.test_units[loop_index].unit_value); - } + if (config.evaluation_params.calculate_rate) { + // store state + gen_state_string_type current_state_wrapper = + gen_state_string(new_state, config.snmp_params.num_of_test_units); - if (config.test_units[loop_index].threshold.warning_is_set || - config.test_units[loop_index].threshold.critical_is_set) { - pd_num_val = mp_pd_set_thresholds(pd_num_val, config.test_units[loop_index].threshold); - mp_state_enum tmp_state = mp_get_pd_status(pd_num_val); - - if (tmp_state == STATE_WARNING) { - sc_oid_test = mp_set_subcheck_state(sc_oid_test, STATE_WARNING); - xasprintf(&sc_oid_test.output, "%s - number violates warning threshold", - sc_oid_test.output); - } else if (tmp_state == STATE_CRITICAL) { - sc_oid_test = mp_set_subcheck_state(sc_oid_test, STATE_CRITICAL); - xasprintf(&sc_oid_test.output, "%s - number violates critical threshold", - sc_oid_test.output); - } + if (current_state_wrapper.errorcode == OK) { + np_state_write_string(stateKey, current_time, current_state_wrapper.state_string); + } else { + die(STATE_UNKNOWN, "failed to create state string"); } - - mp_add_perfdata_to_subcheck(&sc_oid_test, pd_num_val); - - mp_add_subcheck_to_check(&overall, sc_oid_test); } - mp_exit(overall); } @@ -472,6 +388,8 @@ static process_arguments_wrapper process_arguments(int argc, char **argv) { ignore_mib_parsing_errors_index, connection_prefix_index, output_format_index, + calculate_rate, + rate_multiplier }; static struct option longopts[] = { @@ -510,6 +428,8 @@ static process_arguments_wrapper process_arguments(int argc, char **argv) { {"ignore-mib-parsing-errors", no_argument, 0, ignore_mib_parsing_errors_index}, {"connection-prefix", required_argument, 0, connection_prefix_index}, {"output-format", required_argument, 0, output_format_index}, + {"rate", no_argument, 0, calculate_rate}, + {"rate-multiplier", required_argument, 0, rate_multiplier}, {0, 0, 0, 0}}; if (argc < 2) { @@ -575,8 +495,8 @@ static process_arguments_wrapper process_arguments(int argc, char **argv) { } check_snmp_config config = check_snmp_config_init(); - config.test_units = tmp; - config.num_of_test_units = oid_counter; + config.snmp_params.test_units = tmp; + config.snmp_params.num_of_test_units = oid_counter; option = 0; optind = 1; // Reset argument scanner @@ -616,11 +536,11 @@ static process_arguments_wrapper process_arguments(int argc, char **argv) { /* Connection info */ case 'C': /* group or community */ - config.snmp_session.community = (unsigned char *)optarg; - config.snmp_session.community_len = strlen(optarg); + config.snmp_params.snmp_session.community = (unsigned char *)optarg; + config.snmp_params.snmp_session.community_len = strlen(optarg); break; case 'H': /* Host or server */ - config.snmp_session.peername = optarg; + config.snmp_params.snmp_session.peername = optarg; break; case 'p': /*port number */ // Add port to "peername" below to not rely on argument order @@ -630,15 +550,15 @@ static process_arguments_wrapper process_arguments(int argc, char **argv) { miblist = optarg; break; case 'n': /* use_getnext instead of get */ - config.use_getnext = true; + config.snmp_params.use_getnext = true; break; case 'P': /* SNMP protocol version */ if (strcasecmp("1", optarg) == 0) { - config.snmp_session.version = SNMP_VERSION_1; + config.snmp_params.snmp_session.version = SNMP_VERSION_1; } else if (strcasecmp("2c", optarg) == 0) { - config.snmp_session.version = SNMP_VERSION_2c; + config.snmp_params.snmp_session.version = SNMP_VERSION_2c; } else if (strcasecmp("3", optarg) == 0) { - config.snmp_session.version = SNMP_VERSION_3; + config.snmp_params.snmp_session.version = SNMP_VERSION_3; } else { die(STATE_UNKNOWN, "invalid SNMP version/protocol: %s", optarg); } @@ -646,45 +566,51 @@ static process_arguments_wrapper process_arguments(int argc, char **argv) { break; case 'N': /* SNMPv3 context name */ - config.snmp_session.contextName = optarg; - config.snmp_session.contextNameLen = strlen(optarg); + config.snmp_params.snmp_session.contextName = optarg; + config.snmp_params.snmp_session.contextNameLen = strlen(optarg); break; case 'L': /* security level */ if (strcasecmp("noAuthNoPriv", optarg) == 0) { - config.snmp_session.securityLevel = SNMP_SEC_LEVEL_NOAUTH; + config.snmp_params.snmp_session.securityLevel = SNMP_SEC_LEVEL_NOAUTH; } else if (strcasecmp("authNoPriv", optarg) == 0) { - config.snmp_session.securityLevel = SNMP_SEC_LEVEL_AUTHNOPRIV; + config.snmp_params.snmp_session.securityLevel = SNMP_SEC_LEVEL_AUTHNOPRIV; } else if (strcasecmp("authPriv", optarg) == 0) { - config.snmp_session.securityLevel = SNMP_SEC_LEVEL_AUTHPRIV; + config.snmp_params.snmp_session.securityLevel = SNMP_SEC_LEVEL_AUTHPRIV; } else { die(STATE_UNKNOWN, "invalid security level: %s", optarg); } break; case 'U': /* security username */ - config.snmp_session.securityName = optarg; - config.snmp_session.securityNameLen = strlen(optarg); + config.snmp_params.snmp_session.securityName = optarg; + config.snmp_params.snmp_session.securityNameLen = strlen(optarg); break; case 'a': /* auth protocol */ // SNMPv3: SHA or MD5 // TODO Test for availability of individual protocols if (strcasecmp("MD5", optarg) == 0) { - config.snmp_session.securityAuthProto = usmHMACMD5AuthProtocol; - config.snmp_session.securityAuthProtoLen = OID_LENGTH(usmHMACMD5AuthProtocol); + config.snmp_params.snmp_session.securityAuthProto = usmHMACMD5AuthProtocol; + config.snmp_params.snmp_session.securityAuthProtoLen = + OID_LENGTH(usmHMACMD5AuthProtocol); } else if (strcasecmp("SHA", optarg) == 0) { - config.snmp_session.securityAuthProto = usmHMACSHA1AuthProtocol; - config.snmp_session.securityAuthProtoLen = OID_LENGTH(usmHMACSHA1AuthProtocol); + config.snmp_params.snmp_session.securityAuthProto = usmHMACSHA1AuthProtocol; + config.snmp_params.snmp_session.securityAuthProtoLen = + OID_LENGTH(usmHMACSHA1AuthProtocol); } else if (strcasecmp("SHA224", optarg) == 0) { - config.snmp_session.securityAuthProto = usmHMAC128SHA224AuthProtocol; - config.snmp_session.securityAuthProtoLen = OID_LENGTH(usmHMAC128SHA224AuthProtocol); + config.snmp_params.snmp_session.securityAuthProto = usmHMAC128SHA224AuthProtocol; + config.snmp_params.snmp_session.securityAuthProtoLen = + OID_LENGTH(usmHMAC128SHA224AuthProtocol); } else if (strcasecmp("SHA256", optarg) == 0) { - config.snmp_session.securityAuthProto = usmHMAC192SHA256AuthProtocol; - config.snmp_session.securityAuthProtoLen = OID_LENGTH(usmHMAC192SHA256AuthProtocol); + config.snmp_params.snmp_session.securityAuthProto = usmHMAC192SHA256AuthProtocol; + config.snmp_params.snmp_session.securityAuthProtoLen = + OID_LENGTH(usmHMAC192SHA256AuthProtocol); } else if (strcasecmp("SHA384", optarg) == 0) { - config.snmp_session.securityAuthProto = usmHMAC256SHA384AuthProtocol; - config.snmp_session.securityAuthProtoLen = OID_LENGTH(usmHMAC256SHA384AuthProtocol); + config.snmp_params.snmp_session.securityAuthProto = usmHMAC256SHA384AuthProtocol; + config.snmp_params.snmp_session.securityAuthProtoLen = + OID_LENGTH(usmHMAC256SHA384AuthProtocol); } else if (strcasecmp("SHA512", optarg) == 0) { - config.snmp_session.securityAuthProto = usmHMAC384SHA512AuthProtocol; - config.snmp_session.securityAuthProtoLen = OID_LENGTH(usmHMAC384SHA512AuthProtocol); + config.snmp_params.snmp_session.securityAuthProto = usmHMAC384SHA512AuthProtocol; + config.snmp_params.snmp_session.securityAuthProtoLen = + OID_LENGTH(usmHMAC384SHA512AuthProtocol); } else { die(STATE_UNKNOWN, "Unknown authentication protocol"); } @@ -692,24 +618,28 @@ static process_arguments_wrapper process_arguments(int argc, char **argv) { case 'x': /* priv protocol */ if (strcasecmp("DES", optarg) == 0) { #ifdef HAVE_USM_DES_PRIV_PROTOCOL - config.snmp_session.securityAuthProto = usmDESPrivProtocol; - config.snmp_session.securityAuthProtoLen = OID_LENGTH(usmDESPrivProtocol); + config.snmp_params.snmp_session.securityAuthProto = usmDESPrivProtocol; + config.snmp_params.snmp_session.securityAuthProtoLen = + OID_LENGTH(usmDESPrivProtocol); #else die(STATE_UNKNOWN, "DES Privacy Protocol not available on this platform"); #endif } else if (strcasecmp("AES", optarg) == 0) { - config.snmp_session.securityAuthProto = usmAESPrivProtocol; - config.snmp_session.securityAuthProtoLen = OID_LENGTH(usmAESPrivProtocol); + config.snmp_params.snmp_session.securityAuthProto = usmAESPrivProtocol; + config.snmp_params.snmp_session.securityAuthProtoLen = + OID_LENGTH(usmAESPrivProtocol); // } else if (strcasecmp("AES128", optarg)) { // config.snmp_session.securityAuthProto = usmAES128PrivProtocol; // config.snmp_session.securityAuthProtoLen = OID_LENGTH(usmAES128PrivProtocol) // / OID_LENGTH(oid); } else if (strcasecmp("AES192", optarg) == 0) { - config.snmp_session.securityAuthProto = usmAES192PrivProtocol; - config.snmp_session.securityAuthProtoLen = OID_LENGTH(usmAES192PrivProtocol); + config.snmp_params.snmp_session.securityAuthProto = usmAES192PrivProtocol; + config.snmp_params.snmp_session.securityAuthProtoLen = + OID_LENGTH(usmAES192PrivProtocol); } else if (strcasecmp("AES256", optarg) == 0) { - config.snmp_session.securityAuthProto = usmAES256PrivProtocol; - config.snmp_session.securityAuthProtoLen = OID_LENGTH(usmAES256PrivProtocol); + config.snmp_params.snmp_session.securityAuthProto = usmAES256PrivProtocol; + config.snmp_params.snmp_session.securityAuthProtoLen = + OID_LENGTH(usmAES256PrivProtocol); // } else if (strcasecmp("AES192Cisco", optarg)) { // config.snmp_session.securityAuthProto = usmAES192CiscoPrivProtocol; // config.snmp_session.securityAuthProtoLen = @@ -738,7 +668,7 @@ static process_arguments_wrapper process_arguments(int argc, char **argv) { if (!is_integer(optarg)) { usage2(_("Retries interval must be a positive integer"), optarg); } else { - config.snmp_session.retries = atoi(optarg); + config.snmp_params.snmp_session.retries = atoi(optarg); } break; case 't': /* timeout period */ @@ -751,10 +681,10 @@ static process_arguments_wrapper process_arguments(int argc, char **argv) { /* Test parameters */ case 'c': /* critical threshold */ - check_snmp_set_thresholds(optarg, config.test_units, oid_counter, true); + check_snmp_set_thresholds(optarg, config.snmp_params.test_units, oid_counter, true); break; case 'w': /* warning threshold */ - check_snmp_set_thresholds(optarg, config.test_units, oid_counter, false); + check_snmp_set_thresholds(optarg, config.snmp_params.test_units, oid_counter, false); break; case 'o': /* object identifier */ if (strspn(optarg, "0123456789.,") != strlen(optarg)) { @@ -763,25 +693,27 @@ static process_arguments_wrapper process_arguments(int argc, char **argv) { * so we have a mib variable, rather than just an SNMP OID, * so we have to actually read the mib files */ - config.need_mibs = true; + config.snmp_params.need_mibs = true; } for (char *ptr = strtok(optarg, ", "); ptr != NULL; ptr = strtok(NULL, ", "), tmp_oid_counter++) { - config.test_units[tmp_oid_counter].oid = strdup(ptr); + config.snmp_params.test_units[tmp_oid_counter].oid = strdup(ptr); } break; case 'z': /* Null OID Return Check */ if (!is_integer(optarg)) { usage2(_("Exit status must be a positive integer"), optarg); } else { - config.nulloid_result = atoi(optarg); + config.evaluation_params.nulloid_result = atoi(optarg); } break; case 's': /* string or substring */ - strncpy(config.string_cmp_value, optarg, sizeof(config.string_cmp_value) - 1); - config.string_cmp_value[sizeof(config.string_cmp_value) - 1] = 0; - config.test_units[eval_counter++].eval_mthd.crit_string = true; + strncpy(config.evaluation_params.string_cmp_value, optarg, + sizeof(config.evaluation_params.string_cmp_value) - 1); + config.evaluation_params + .string_cmp_value[sizeof(config.evaluation_params.string_cmp_value) - 1] = 0; + config.snmp_params.test_units[eval_counter++].eval_mthd.crit_string = true; break; case 'R': /* regex */ cflags = REG_ICASE; @@ -792,72 +724,73 @@ static process_arguments_wrapper process_arguments(int argc, char **argv) { cflags |= REG_EXTENDED | REG_NOSUB | REG_NEWLINE; strncpy(regex_expect, optarg, sizeof(regex_expect) - 1); regex_expect[sizeof(regex_expect) - 1] = 0; - int errcode = regcomp(&config.regex_cmp_value, regex_expect, cflags); + int errcode = regcomp(&config.evaluation_params.regex_cmp_value, regex_expect, cflags); if (errcode != 0) { char errbuf[MAX_INPUT_BUFFER] = ""; - regerror(errcode, &config.regex_cmp_value, errbuf, MAX_INPUT_BUFFER); + regerror(errcode, &config.evaluation_params.regex_cmp_value, errbuf, + MAX_INPUT_BUFFER); printf("Could Not Compile Regular Expression: %s", errbuf); process_arguments_wrapper result = { .errorcode = ERROR, }; return result; } - config.test_units[eval_counter++].eval_mthd.crit_regex = true; + config.snmp_params.test_units[eval_counter++].eval_mthd.crit_regex = true; } break; case 'l': /* label */ { - if (labels_counter >= config.num_of_test_units) { + if (labels_counter >= config.snmp_params.num_of_test_units) { break; } char *ptr = trim_whitespaces_and_check_quoting(optarg); if (ptr[0] == '\'') { - config.test_units[labels_counter].label = ptr + 1; + config.snmp_params.test_units[labels_counter].label = ptr + 1; } else { - config.test_units[labels_counter].label = ptr; + config.snmp_params.test_units[labels_counter].label = ptr; } while (ptr && (ptr = get_next_argument(ptr))) { labels_counter++; ptr = trim_whitespaces_and_check_quoting(ptr); if (ptr[0] == '\'') { - config.test_units[labels_counter].label = ptr + 1; + config.snmp_params.test_units[labels_counter].label = ptr + 1; } else { - config.test_units[labels_counter].label = ptr; + config.snmp_params.test_units[labels_counter].label = ptr; } } labels_counter++; } break; case 'u': /* units */ { - if (unitv_counter >= config.num_of_test_units) { + if (unitv_counter >= config.snmp_params.num_of_test_units) { break; } char *ptr = trim_whitespaces_and_check_quoting(optarg); if (ptr[0] == '\'') { - config.test_units[unitv_counter].unit_value = ptr + 1; + config.snmp_params.test_units[unitv_counter].unit_value = ptr + 1; } else { - config.test_units[unitv_counter].unit_value = ptr; + config.snmp_params.test_units[unitv_counter].unit_value = ptr; } while (ptr && (ptr = get_next_argument(ptr))) { unitv_counter++; ptr = trim_whitespaces_and_check_quoting(ptr); if (ptr[0] == '\'') { - config.test_units[unitv_counter].unit_value = ptr + 1; + config.snmp_params.test_units[unitv_counter].unit_value = ptr + 1; } else { - config.test_units[unitv_counter].unit_value = ptr; + config.snmp_params.test_units[unitv_counter].unit_value = ptr; } } unitv_counter++; } break; case offset_index: - config.offset = strtod(optarg, NULL); - config.offset_set = true; + config.evaluation_params.offset = strtod(optarg, NULL); + config.evaluation_params.offset_set = true; break; case invert_search_index: - config.invert_search = false; + config.evaluation_params.invert_search = false; break; case 'O': - config.use_perf_data_labels_from_input = true; + config.evaluation_params.use_oid_as_perf_data_label = true; break; case '4': // The default, do something here to be exclusive to -6 instead of doing nothing? @@ -871,12 +804,12 @@ static process_arguments_wrapper process_arguments(int argc, char **argv) { break; case 'M': if (strspn(optarg, "0123456789.,") == strlen(optarg)) { - config.multiplier = strtod(optarg, NULL); - config.multiplier_set = true; + config.evaluation_params.multiplier = strtod(optarg, NULL); + config.evaluation_params.multiplier_set = true; } break; case ignore_mib_parsing_errors_index: - config.ignore_mib_parsing_errors = true; + config.snmp_params.ignore_mib_parsing_errors = true; break; case 'f': // Deprecated format option for floating point values break; @@ -892,13 +825,22 @@ static process_arguments_wrapper process_arguments(int argc, char **argv) { config.output_format = parser.output_format; break; } + case calculate_rate: + config.evaluation_params.calculate_rate = true; + break; + case rate_multiplier: + if (!is_integer(optarg) || + ((config.evaluation_params.rate_multiplier = (unsigned int)atoi(optarg)) <= 0)) { + usage2(_("Rate multiplier must be a positive integer"), optarg); + } + break; default: die(STATE_UNKNOWN, "Unknown option"); } } - if (config.snmp_session.peername == NULL) { - config.snmp_session.peername = argv[optind]; + if (config.snmp_params.snmp_session.peername == NULL) { + config.snmp_params.snmp_session.peername = argv[optind]; } // Build true peername here if necessary @@ -908,7 +850,8 @@ static process_arguments_wrapper process_arguments(int argc, char **argv) { // The default, do nothing } else if (strcasecmp(connection_prefix, "tcp") == 0) { // use tcp/ipv4 - xasprintf(&config.snmp_session.peername, "tcp:%s", config.snmp_session.peername); + xasprintf(&config.snmp_params.snmp_session.peername, "tcp:%s", + config.snmp_params.snmp_session.peername); } else if (strcasecmp(connection_prefix, "tcp6") == 0 || strcasecmp(connection_prefix, "tcpv6") == 0 || strcasecmp(connection_prefix, "tcpipv6") == 0 || @@ -917,19 +860,23 @@ static process_arguments_wrapper process_arguments(int argc, char **argv) { strcasecmp(connection_prefix, "udpv6") == 0) { // Man page (or net-snmp) code says IPv6 addresses should be wrapped in [], but it // works anyway therefore do nothing here - xasprintf(&config.snmp_session.peername, "%s:%s", connection_prefix, - config.snmp_session.peername); + xasprintf(&config.snmp_params.snmp_session.peername, "%s:%s", connection_prefix, + config.snmp_params.snmp_session.peername); } else if (strcmp(connection_prefix, "tls") == 0) { // TODO: Anything else to do here? - xasprintf(&config.snmp_session.peername, "tls:%s", config.snmp_session.peername); + xasprintf(&config.snmp_params.snmp_session.peername, "tls:%s", + config.snmp_params.snmp_session.peername); } else if (strcmp(connection_prefix, "dtls") == 0) { // TODO: Anything else to do here? - xasprintf(&config.snmp_session.peername, "dtls:%s", config.snmp_session.peername); + xasprintf(&config.snmp_params.snmp_session.peername, "dtls:%s", + config.snmp_params.snmp_session.peername); } else if (strcmp(connection_prefix, "unix") == 0) { // TODO: Check whether this is a valid path? - xasprintf(&config.snmp_session.peername, "unix:%s", config.snmp_session.peername); + xasprintf(&config.snmp_params.snmp_session.peername, "unix:%s", + config.snmp_params.snmp_session.peername); } else if (strcmp(connection_prefix, "ipx") == 0) { - xasprintf(&config.snmp_session.peername, "ipx:%s", config.snmp_session.peername); + xasprintf(&config.snmp_params.snmp_session.peername, "ipx:%s", + config.snmp_params.snmp_session.peername); } else { // Don't know that prefix, die here die(STATE_UNKNOWN, "Unknown connection prefix"); @@ -937,17 +884,18 @@ static process_arguments_wrapper process_arguments(int argc, char **argv) { } /* Check server_address is given */ - if (config.snmp_session.peername == NULL) { + if (config.snmp_params.snmp_session.peername == NULL) { die(STATE_UNKNOWN, _("No host specified\n")); } if (port != NULL) { - xasprintf(&config.snmp_session.peername, "%s:%s", config.snmp_session.peername, port); + xasprintf(&config.snmp_params.snmp_session.peername, "%s:%s", + config.snmp_params.snmp_session.peername, port); } /* check whether to load locally installed MIBS (CPU/disk intensive) */ if (miblist == NULL) { - if (config.need_mibs) { + if (config.snmp_params.need_mibs) { setenv("MIBLS", DEFAULT_MIBLIST, 1); } else { setenv("MIBLS", "NONE", 1); @@ -959,37 +907,37 @@ static process_arguments_wrapper process_arguments(int argc, char **argv) { } // Historical default is SNMP v2c - if (!snmp_version_set_explicitely && config.snmp_session.community != NULL) { - config.snmp_session.version = SNMP_VERSION_2c; + if (!snmp_version_set_explicitely && config.snmp_params.snmp_session.community != NULL) { + config.snmp_params.snmp_session.version = SNMP_VERSION_2c; } - if ((config.snmp_session.version == SNMP_VERSION_1) || - (config.snmp_session.version == SNMP_VERSION_2c)) { /* snmpv1 or snmpv2c */ - /* - config.numauthpriv = 2; - config.authpriv = calloc(config.numauthpriv, sizeof(char *)); - config.authpriv[0] = strdup("-c"); - config.authpriv[1] = strdup(community); - */ - } else if (config.snmp_session.version == SNMP_VERSION_3) { /* snmpv3 args */ + if ((config.snmp_params.snmp_session.version == SNMP_VERSION_1) || + (config.snmp_params.snmp_session.version == SNMP_VERSION_2c)) { /* snmpv1 or snmpv2c */ + /* + config.numauthpriv = 2; + config.authpriv = calloc(config.numauthpriv, sizeof(char *)); + config.authpriv[0] = strdup("-c"); + config.authpriv[1] = strdup(community); + */ + } else if (config.snmp_params.snmp_session.version == SNMP_VERSION_3) { /* snmpv3 args */ // generate keys for priv and auth here (if demanded) - if (config.snmp_session.securityName == NULL) { + if (config.snmp_params.snmp_session.securityName == NULL) { die(STATE_UNKNOWN, _("Required parameter: %s\n"), "secname"); } - switch (config.snmp_session.securityLevel) { + switch (config.snmp_params.snmp_session.securityLevel) { case SNMP_SEC_LEVEL_AUTHPRIV: { if (authpasswd == NULL) { die(STATE_UNKNOWN, "No authentication passphrase was given, but authorization was requested"); } // auth and priv - int priv_key_generated = - generate_Ku(config.snmp_session.securityPrivProto, - (unsigned int)config.snmp_session.securityPrivProtoLen, authpasswd, - strlen((const char *)authpasswd), config.snmp_session.securityPrivKey, - &config.snmp_session.securityPrivKeyLen); + int priv_key_generated = generate_Ku( + config.snmp_params.snmp_session.securityPrivProto, + (unsigned int)config.snmp_params.snmp_session.securityPrivProtoLen, authpasswd, + strlen((const char *)authpasswd), config.snmp_params.snmp_session.securityPrivKey, + &config.snmp_params.snmp_session.securityPrivKeyLen); if (priv_key_generated != SNMPERR_SUCCESS) { die(STATE_UNKNOWN, "Failed to generate privacy key"); @@ -1000,11 +948,11 @@ static process_arguments_wrapper process_arguments(int argc, char **argv) { if (privpasswd == NULL) { die(STATE_UNKNOWN, "No privacy passphrase was given, but privacy was requested"); } - int auth_key_generated = - generate_Ku(config.snmp_session.securityAuthProto, - (unsigned int)config.snmp_session.securityAuthProtoLen, privpasswd, - strlen((const char *)privpasswd), config.snmp_session.securityAuthKey, - &config.snmp_session.securityAuthKeyLen); + int auth_key_generated = generate_Ku( + config.snmp_params.snmp_session.securityAuthProto, + (unsigned int)config.snmp_params.snmp_session.securityAuthProtoLen, privpasswd, + strlen((const char *)privpasswd), config.snmp_params.snmp_session.securityAuthKey, + &config.snmp_params.snmp_session.securityAuthKeyLen); if (auth_key_generated != SNMPERR_SUCCESS) { die(STATE_UNKNOWN, "Failed to generate privacy key"); diff --git a/plugins/check_snmp.d/check_snmp_helpers.c b/plugins/check_snmp.d/check_snmp_helpers.c index 8f4bcb9c..9fa396d8 100644 --- a/plugins/check_snmp.d/check_snmp_helpers.c +++ b/plugins/check_snmp.d/check_snmp_helpers.c @@ -1,6 +1,15 @@ #include "./check_snmp_helpers.h" #include #include "../../lib/utils_base.h" +#include "config.h" +#include +#include "../utils.h" +#include "output.h" +#include "states.h" +#include +#include + +extern int verbose; check_snmp_test_unit check_snmp_test_unit_init() { check_snmp_test_unit tmp = { @@ -78,38 +87,848 @@ int check_snmp_set_thresholds(const char *threshold_string, check_snmp_test_unit const int DEFAULT_PROTOCOL = SNMP_VERSION_1; const char DEFAULT_OUTPUT_DELIMITER[] = " "; -const int RANDOM_STATE_DATA_LENGTH_PREDICTION = 1024; +const int RANDOM_STATE_DATA_LENGTH_PREDICTION = 8192; check_snmp_config check_snmp_config_init() { check_snmp_config tmp = { - .use_getnext = false, + .snmp_params = + { + .use_getnext = false, + + .ignore_mib_parsing_errors = false, + .need_mibs = false, - .ignore_mib_parsing_errors = false, - .need_mibs = false, + .test_units = NULL, + .num_of_test_units = 0, + }, - .test_units = NULL, - .num_of_test_units = 0, + .evaluation_params = + { + .nulloid_result = STATE_UNKNOWN, // state to return if no result for query - .nulloid_result = STATE_UNKNOWN, // state to return if no result for query + .invert_search = true, + .regex_cmp_value = {}, + .string_cmp_value = "", - .invert_search = true, - .regex_cmp_value = {}, - .string_cmp_value = "", + .multiplier = 1.0, + .multiplier_set = false, + .offset = 0, + .offset_set = false, - .multiplier = 1.0, - .multiplier_set = false, - .offset = 0, - .offset_set = false, + .use_oid_as_perf_data_label = false, - .use_perf_data_labels_from_input = false, + .calculate_rate = false, + .rate_multiplier = 1, + }, }; - snmp_sess_init(&tmp.snmp_session); + snmp_sess_init(&tmp.snmp_params.snmp_session); - tmp.snmp_session.retries = DEFAULT_RETRIES; - tmp.snmp_session.version = DEFAULT_SNMP_VERSION; - tmp.snmp_session.securityLevel = SNMP_SEC_LEVEL_NOAUTH; - tmp.snmp_session.community = (unsigned char *)"public"; - tmp.snmp_session.community_len = strlen("public"); + tmp.snmp_params.snmp_session.retries = DEFAULT_RETRIES; + tmp.snmp_params.snmp_session.version = DEFAULT_SNMP_VERSION; + tmp.snmp_params.snmp_session.securityLevel = SNMP_SEC_LEVEL_NOAUTH; + tmp.snmp_params.snmp_session.community = (unsigned char *)"public"; + tmp.snmp_params.snmp_session.community_len = strlen("public"); return tmp; } + +snmp_responces do_snmp_query(check_snmp_config_snmp_parameters parameters) { + if (parameters.ignore_mib_parsing_errors) { + char *opt_toggle_res = snmp_mib_toggle_options("e"); + if (opt_toggle_res != NULL) { + die(STATE_UNKNOWN, "Unable to disable MIB parsing errors"); + } + } + + struct snmp_pdu *pdu = NULL; + if (parameters.use_getnext) { + pdu = snmp_pdu_create(SNMP_MSG_GETNEXT); + } else { + pdu = snmp_pdu_create(SNMP_MSG_GET); + } + + for (size_t i = 0; i < parameters.num_of_test_units; i++) { + assert(parameters.test_units[i].oid != NULL); + if (verbose > 0) { + printf("OID %zu to parse: %s\n", i, parameters.test_units[i].oid); + } + + oid tmp_OID[MAX_OID_LEN]; + size_t tmp_OID_len = MAX_OID_LEN; + if (snmp_parse_oid(parameters.test_units[i].oid, tmp_OID, &tmp_OID_len) != NULL) { + // success + snmp_add_null_var(pdu, tmp_OID, tmp_OID_len); + } else { + // failed + snmp_perror("Parsing failure"); + die(STATE_UNKNOWN, "Failed to parse OID\n"); + } + } + + const int timeout_safety_tolerance = 5; + alarm((timeout_interval * (unsigned int)parameters.snmp_session.retries) + + timeout_safety_tolerance); + + struct snmp_session *active_session = snmp_open(¶meters.snmp_session); + if (active_session == NULL) { + int pcliberr = 0; + int psnmperr = 0; + char *pperrstring = NULL; + snmp_error(¶meters.snmp_session, &pcliberr, &psnmperr, &pperrstring); + die(STATE_UNKNOWN, "Failed to open SNMP session: %s\n", pperrstring); + } + + struct snmp_pdu *response = NULL; + int snmp_query_status = snmp_synch_response(active_session, pdu, &response); + + if (!(snmp_query_status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR)) { + int pcliberr = 0; + int psnmperr = 0; + char *pperrstring = NULL; + snmp_error(active_session, &pcliberr, &psnmperr, &pperrstring); + + if (psnmperr == SNMPERR_TIMEOUT) { + // We exit with critical here for some historical reason + die(STATE_CRITICAL, "SNMP query ran into a timeout\n"); + } + die(STATE_UNKNOWN, "SNMP query failed: %s\n", pperrstring); + } + + snmp_close(active_session); + + /* disable alarm again */ + alarm(0); + + snmp_responces result = { + .errorcode = OK, + .response_values = calloc(parameters.num_of_test_units, sizeof(response_value)), + }; + + if (result.response_values == NULL) { + result.errorcode = ERROR; + return result; + } + + // We got the the query results, now process them + size_t loop_index = 0; + for (netsnmp_variable_list *vars = response->variables; vars; + vars = vars->next_variable, loop_index++) { + + for (size_t jdx = 0; jdx < vars->name_length; jdx++) { + result.response_values[loop_index].oid[jdx] = vars->name[jdx]; + } + result.response_values[loop_index].oid_length = vars->name_length; + + switch (vars->type) { + case ASN_OCTET_STR: { + result.response_values[loop_index].string_response = strdup((char *)vars->val.string); + result.response_values[loop_index].type = vars->type; + if (verbose) { + printf("Debug: Got a string as response: %s\n", vars->val.string); + } + } + continue; + case ASN_OPAQUE: + if (verbose) { + printf("Debug: Got OPAQUE\n"); + } + break; + /* Numerical values */ + case ASN_COUNTER64: { + if (verbose) { + printf("Debug: Got counter64\n"); + } + struct counter64 tmp = *(vars->val.counter64); + uint64_t counter = (tmp.high << 32) + tmp.low; + result.response_values[loop_index].value.uIntVal = counter; + result.response_values[loop_index].type = vars->type; + } break; + case ASN_GAUGE: // same as ASN_UNSIGNED + case ASN_TIMETICKS: + case ASN_COUNTER: + case ASN_UINTEGER: { + if (verbose) { + printf("Debug: Got a Integer like\n"); + } + result.response_values[loop_index].value.uIntVal = (unsigned long)*(vars->val.integer); + result.response_values[loop_index].type = vars->type; + } break; + case ASN_INTEGER: { + if (verbose) { + printf("Debug: Got a Integer\n"); + } + result.response_values[loop_index].value.intVal = *(vars->val.integer); + result.response_values[loop_index].type = vars->type; + } break; + case ASN_FLOAT: { + if (verbose) { + printf("Debug: Got a float\n"); + } + result.response_values[loop_index].value.doubleVal = *(vars->val.floatVal); + result.response_values[loop_index].type = vars->type; + } break; + case ASN_DOUBLE: { + if (verbose) { + printf("Debug: Got a double\n"); + } + result.response_values[loop_index].value.doubleVal = *(vars->val.doubleVal); + result.response_values[loop_index].type = vars->type; + break; + } + case ASN_IPADDRESS: + if (verbose) { + printf("Debug: Got an IP address\n"); + } + result.response_values[loop_index].type = vars->type; + + // TODO: print address here, state always ok? or regex match? + continue; + default: + if (verbose) { + printf("Debug: Got a unmatched result type: %hhu\n", vars->type); + } + // TODO: Error here? + continue; + } + } + + return result; +} + +check_snmp_evaluation evaluate_single_unit(response_value response, + check_snmp_evaluation_parameters eval_params, + check_snmp_test_unit test_unit, time_t query_timestamp, + check_snmp_state_entry prev_state, + bool have_previous_state) { + mp_subcheck sc_oid_test = mp_subcheck_init(); + + if ((test_unit.label != NULL) && (strcmp(test_unit.label, "") != 0)) { + xasprintf(&sc_oid_test.output, "%s - ", test_unit.label); + } else { + sc_oid_test.output = strdup(""); + } + + char oid_string[(MAX_OID_LEN * 2) + 1] = {}; + + int oid_string_result = + snprint_objid(oid_string, (MAX_OID_LEN * 2) + 1, response.oid, response.oid_length); + if (oid_string_result <= 0) { + // TODO error here + die(STATE_UNKNOWN, "snprint_objid failed\n"); + } + + xasprintf(&sc_oid_test.output, "%sOID: %s", sc_oid_test.output, oid_string); + sc_oid_test = mp_set_subcheck_default_state(sc_oid_test, STATE_OK); + + if (verbose > 2) { + printf("Processing oid %s\n", oid_string); + } + + bool got_a_numerical_value = false; + mp_perfdata_value pd_result_val = {0}; + + check_snmp_state_entry result_state = { + .timestamp = query_timestamp, + .oid_length = response.oid_length, + .type = response.type, + }; + + for (size_t i = 0; i < response.oid_length; i++) { + result_state.oid[i] = response.oid[i]; + } + + if (have_previous_state) { + if (query_timestamp == prev_state.timestamp) { + // somehow we have the same timestamp again, that can't be good + sc_oid_test = mp_set_subcheck_state(sc_oid_test, STATE_UNKNOWN); + xasprintf(&sc_oid_test.output, "Time duration between plugin calls is invalid"); + + check_snmp_evaluation result = { + .sc = sc_oid_test, + .state = result_state, + }; + + return result; + } + } + // compute rate time difference + double timeDiff = 0; + if (have_previous_state) { + if (verbose) { + printf("Previous timestamp: %s", ctime(&prev_state.timestamp)); + printf("Current timestamp: %s", ctime(&query_timestamp)); + } + timeDiff = difftime(query_timestamp, prev_state.timestamp) / eval_params.rate_multiplier; + } + + mp_perfdata pd_num_val = {}; + + switch (response.type) { + case ASN_OCTET_STR: { + char *tmp = response.string_response; + if (strchr(tmp, '"') != NULL) { + // got double quote in the string + if (strchr(tmp, '\'') != NULL) { + // got single quote in the string too + // dont quote that at all to avoid even more confusion + xasprintf(&sc_oid_test.output, "%s - Value: %s", sc_oid_test.output, tmp); + } else { + // quote with single quotes + xasprintf(&sc_oid_test.output, "%s - Value: '%s'", sc_oid_test.output, tmp); + } + } else { + // quote with double quotes + xasprintf(&sc_oid_test.output, "%s - Value: \"%s\"", sc_oid_test.output, tmp); + } + + if (strlen(tmp) == 0) { + sc_oid_test = mp_set_subcheck_state(sc_oid_test, eval_params.nulloid_result); + } + + // String matching test + if ((test_unit.eval_mthd.crit_string)) { + if (strcmp(tmp, eval_params.string_cmp_value)) { + sc_oid_test = mp_set_subcheck_state( + sc_oid_test, (eval_params.invert_search) ? STATE_CRITICAL : STATE_OK); + } else { + sc_oid_test = mp_set_subcheck_state( + sc_oid_test, (eval_params.invert_search) ? STATE_OK : STATE_CRITICAL); + } + } else if (test_unit.eval_mthd.crit_regex) { + const size_t nmatch = eval_params.regex_cmp_value.re_nsub + 1; + regmatch_t pmatch[nmatch]; + memset(pmatch, '\0', sizeof(regmatch_t) * nmatch); + + int excode = regexec(&eval_params.regex_cmp_value, tmp, nmatch, pmatch, 0); + if (excode == 0) { + sc_oid_test = mp_set_subcheck_state( + sc_oid_test, (eval_params.invert_search) ? STATE_OK : STATE_CRITICAL); + } else if (excode != REG_NOMATCH) { + char errbuf[MAX_INPUT_BUFFER] = ""; + regerror(excode, &eval_params.regex_cmp_value, errbuf, MAX_INPUT_BUFFER); + printf(_("Execute Error: %s\n"), errbuf); + exit(STATE_CRITICAL); + } else { // REG_NOMATCH + sc_oid_test = mp_set_subcheck_state( + sc_oid_test, eval_params.invert_search ? STATE_CRITICAL : STATE_OK); + } + } + } break; + case ASN_COUNTER64: + got_a_numerical_value = true; + + result_state.value.uIntVal = response.value.uIntVal; + result_state.type = response.type; + + // TODO: perfdata unit counter + if (eval_params.calculate_rate && have_previous_state) { + if (prev_state.value.uIntVal > response.value.uIntVal) { + // overflow + unsigned long long tmp = + (UINT64_MAX - prev_state.value.uIntVal) + response.value.uIntVal; + + tmp /= timeDiff; + pd_result_val = mp_create_pd_value(tmp); + } else { + pd_result_val = mp_create_pd_value( + (response.value.uIntVal - prev_state.value.uIntVal) / timeDiff); + } + } else { + // It's only a counter if we cont compute rate + pd_num_val.uom = "c"; + pd_result_val = mp_create_pd_value(response.value.uIntVal); + } + break; + case ASN_GAUGE: // same as ASN_UNSIGNED + case ASN_TIMETICKS: + case ASN_COUNTER: + case ASN_UINTEGER: { + got_a_numerical_value = true; + long long treated_value = (long long)response.value.uIntVal; + + if (eval_params.multiplier_set || eval_params.offset_set) { + double processed = 0; + if (eval_params.offset_set) { + processed += eval_params.offset; + } + + if (eval_params.multiplier_set) { + processed = processed * eval_params.multiplier; + } + + treated_value = lround(processed); + } + + result_state.value.intVal = treated_value; + + if (eval_params.calculate_rate && have_previous_state) { + if (verbose > 2) { + printf("%s: Rate calculation (int/counter/gauge): prev: %lli\n", __FUNCTION__, + prev_state.value.intVal); + printf("%s: Rate calculation (int/counter/gauge): current: %lli\n", __FUNCTION__, + treated_value); + } + double rate = (treated_value - prev_state.value.intVal) / timeDiff; + pd_result_val = mp_create_pd_value(rate); + } else { + pd_result_val = mp_create_pd_value(treated_value); + + if (response.type == ASN_COUNTER) { + pd_num_val.uom = "c"; + } + } + + } break; + case ASN_INTEGER: { + if (eval_params.multiplier_set || eval_params.offset_set) { + double processed = 0; + if (eval_params.multiplier_set) { + processed = (double)response.value.intVal * eval_params.multiplier; + } + + if (eval_params.offset_set) { + processed += eval_params.offset; + } + + result_state.value.doubleVal = processed; + + if (eval_params.calculate_rate && have_previous_state) { + pd_result_val = + mp_create_pd_value((processed - prev_state.value.doubleVal) / timeDiff); + } else { + pd_result_val = mp_create_pd_value(processed); + } + } else { + result_state.value.intVal = response.value.intVal; + + if (eval_params.calculate_rate && have_previous_state) { + pd_result_val = mp_create_pd_value( + (response.value.intVal - prev_state.value.intVal) / timeDiff); + } else { + pd_result_val = mp_create_pd_value(response.value.intVal); + } + } + + got_a_numerical_value = true; + } break; + case ASN_FLOAT: // fallthrough + case ASN_DOUBLE: { + got_a_numerical_value = true; + double tmp = response.value.doubleVal; + if (eval_params.offset_set) { + tmp += eval_params.offset; + } + + if (eval_params.multiplier_set) { + tmp *= eval_params.multiplier; + } + + if (eval_params.calculate_rate && have_previous_state) { + pd_result_val = mp_create_pd_value((tmp - prev_state.value.doubleVal) / timeDiff); + } else { + pd_result_val = mp_create_pd_value(tmp); + } + got_a_numerical_value = true; + + result_state.value.doubleVal = tmp; + } break; + case ASN_IPADDRESS: + // TODO + } + + if (got_a_numerical_value) { + if (eval_params.use_oid_as_perf_data_label) { + // Use oid for perdata label + pd_num_val.label = strdup(oid_string); + // TODO strdup error checking + } else if (test_unit.label != NULL && strcmp(test_unit.label, "") != 0) { + pd_num_val.label = strdup(test_unit.label); + } else { + pd_num_val.label = strdup(test_unit.oid); + } + + if (!(eval_params.calculate_rate && !have_previous_state)) { + // some kind of numerical value + if (test_unit.unit_value != NULL && strcmp(test_unit.unit_value, "") != 0) { + pd_num_val.uom = test_unit.unit_value; + } + + pd_num_val.value = pd_result_val; + + xasprintf(&sc_oid_test.output, "%s Value: %s", sc_oid_test.output, + pd_value_to_string(pd_result_val)); + + if (test_unit.unit_value != NULL && strcmp(test_unit.unit_value, "") != 0) { + xasprintf(&sc_oid_test.output, "%s%s", sc_oid_test.output, test_unit.unit_value); + } + + if (test_unit.threshold.warning_is_set || test_unit.threshold.critical_is_set) { + pd_num_val = mp_pd_set_thresholds(pd_num_val, test_unit.threshold); + mp_state_enum tmp_state = mp_get_pd_status(pd_num_val); + + if (tmp_state == STATE_WARNING) { + sc_oid_test = mp_set_subcheck_state(sc_oid_test, STATE_WARNING); + xasprintf(&sc_oid_test.output, "%s - number violates warning threshold", + sc_oid_test.output); + } else if (tmp_state == STATE_CRITICAL) { + sc_oid_test = mp_set_subcheck_state(sc_oid_test, STATE_CRITICAL); + xasprintf(&sc_oid_test.output, "%s - number violates critical threshold", + sc_oid_test.output); + } + } + + mp_add_perfdata_to_subcheck(&sc_oid_test, pd_num_val); + } else { + // should calculate rate, but there is no previous state, so first run + // exit with ok now + sc_oid_test = mp_set_subcheck_state(sc_oid_test, STATE_OK); + xasprintf(&sc_oid_test.output, "%s - No previous data to calculate rate - assume okay", + sc_oid_test.output); + } + } + + check_snmp_evaluation result = { + .sc = sc_oid_test, + .state = result_state, + }; + + return result; +} + +char *_np_state_generate_key(int argc, char **argv); + +/* + * If time=NULL, use current time. Create state file, with state format + * version, default text. Writes version, time, and data. Avoid locking + * problems - use mv to write and then swap. Possible loss of state data if + * two things writing to same key at same time. + * Will die with UNKNOWN if errors + */ +void np_state_write_string(state_key stateKey, time_t timestamp, char *stringToStore) { + time_t current_time; + if (timestamp == 0) { + time(¤t_time); + } else { + current_time = timestamp; + } + + int result = 0; + + /* If file doesn't currently exist, create directories */ + if (access(stateKey._filename, F_OK) != 0) { + char *directories = NULL; + result = asprintf(&directories, "%s", stateKey._filename); + if (result < 0) { + die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); + } + + for (char *p = directories + 1; *p; p++) { + if (*p == '/') { + *p = '\0'; + if ((access(directories, F_OK) != 0) && (mkdir(directories, S_IRWXU) != 0)) { + /* Can't free this! Otherwise error message is wrong! */ + /* np_free(directories); */ + die(STATE_UNKNOWN, _("Cannot create directory: %s"), directories); + } + *p = '/'; + } + } + + if (directories) { + free(directories); + } + } + + char *temp_file = NULL; + result = asprintf(&temp_file, "%s.XXXXXX", stateKey._filename); + if (result < 0) { + die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); + } + + int temp_file_desc = 0; + if ((temp_file_desc = mkstemp(temp_file)) == -1) { + if (temp_file) { + free(temp_file); + } + die(STATE_UNKNOWN, _("Cannot create temporary filename")); + } + + FILE *temp_file_pointer = fdopen(temp_file_desc, "w"); + if (temp_file_pointer == NULL) { + close(temp_file_desc); + unlink(temp_file); + if (temp_file) { + free(temp_file); + } + die(STATE_UNKNOWN, _("Unable to open temporary state file")); + } + + fprintf(temp_file_pointer, "# NP State file\n"); + fprintf(temp_file_pointer, "%d\n", NP_STATE_FORMAT_VERSION); + fprintf(temp_file_pointer, "%d\n", stateKey.data_version); + fprintf(temp_file_pointer, "%lu\n", current_time); + fprintf(temp_file_pointer, "%s\n", stringToStore); + + fchmod(temp_file_desc, S_IRUSR | S_IWUSR | S_IRGRP); + + fflush(temp_file_pointer); + + result = fclose(temp_file_pointer); + + fsync(temp_file_desc); + + if (result != 0) { + unlink(temp_file); + if (temp_file) { + free(temp_file); + } + die(STATE_UNKNOWN, _("Error writing temp file")); + } + + if (rename(temp_file, stateKey._filename) != 0) { + unlink(temp_file); + if (temp_file) { + free(temp_file); + } + die(STATE_UNKNOWN, _("Cannot rename state temp file")); + } + + if (temp_file) { + free(temp_file); + } +} + +/* + * Read the state file + */ +bool _np_state_read_file(FILE *state_file, state_key stateKey) { + time_t current_time; + time(¤t_time); + + /* Note: This introduces a limit of 8192 bytes in the string data */ + char *line = (char *)calloc(1, 8192); + if (line == NULL) { + die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); + } + + bool status = false; + enum { + STATE_FILE_VERSION, + STATE_DATA_VERSION, + STATE_DATA_TIME, + STATE_DATA_TEXT, + STATE_DATA_END + } expected = STATE_FILE_VERSION; + + int failure = 0; + while (!failure && (fgets(line, 8192, state_file)) != NULL) { + size_t pos = strlen(line); + if (line[pos - 1] == '\n') { + line[pos - 1] = '\0'; + } + + if (line[0] == '#') { + continue; + } + + switch (expected) { + case STATE_FILE_VERSION: { + int i = atoi(line); + if (i != NP_STATE_FORMAT_VERSION) { + failure++; + } else { + expected = STATE_DATA_VERSION; + } + } break; + case STATE_DATA_VERSION: { + int i = atoi(line); + if (i != stateKey.data_version) { + failure++; + } else { + expected = STATE_DATA_TIME; + } + } break; + case STATE_DATA_TIME: { + /* If time > now, error */ + time_t data_time = strtoul(line, NULL, 10); + if (data_time > current_time) { + failure++; + } else { + stateKey.state_data->time = data_time; + expected = STATE_DATA_TEXT; + } + } break; + case STATE_DATA_TEXT: + stateKey.state_data->data = strdup(line); + if (stateKey.state_data->data == NULL) { + die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno)); + } + stateKey.state_data->length = strlen(line); + expected = STATE_DATA_END; + status = true; + break; + case STATE_DATA_END:; + } + } + + if (line) { + free(line); + } + return status; +} +/* + * Will return NULL if no data is available (first run). If key currently + * exists, read data. If state file format version is not expected, return + * as if no data. Get state data version number and compares to expected. + * If numerically lower, then return as no previous state. die with UNKNOWN + * if exceptional error. + */ +state_data *np_state_read(state_key stateKey) { + /* Open file. If this fails, no previous state found */ + FILE *statefile = fopen(stateKey._filename, "r"); + state_data *this_state_data = (state_data *)calloc(1, sizeof(state_data)); + if (statefile != NULL) { + + if (this_state_data == NULL) { + die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); + } + + this_state_data->data = NULL; + stateKey.state_data = this_state_data; + + if (_np_state_read_file(statefile, stateKey)) { + this_state_data->errorcode = OK; + } else { + this_state_data->errorcode = ERROR; + } + + fclose(statefile); + } else { + // Failed to open state file + this_state_data->errorcode = ERROR; + } + + return stateKey.state_data; +} + +/* + * Internal function. Returns either: + * envvar NAGIOS_PLUGIN_STATE_DIRECTORY + * statically compiled shared state directory + */ +char *_np_state_calculate_location_prefix(void) { + char *env_dir; + + /* Do not allow passing MP_STATE_PATH in setuid plugins + * for security reasons */ + if (!mp_suid()) { + env_dir = getenv("MP_STATE_PATH"); + if (env_dir && env_dir[0] != '\0') { + return env_dir; + } + /* This is the former ENV, for backward-compatibility */ + env_dir = getenv("NAGIOS_PLUGIN_STATE_DIRECTORY"); + if (env_dir && env_dir[0] != '\0') { + return env_dir; + } + } + + return NP_STATE_DIR_PREFIX; +} + +/* + * Initiatializer for state routines. + * Sets variables. Generates filename. Returns np_state_key. die with + * UNKNOWN if exception + */ +state_key np_enable_state(char *keyname, int expected_data_version, char *plugin_name, int argc, + char **argv) { + state_key *this_state = (state_key *)calloc(1, sizeof(state_key)); + if (this_state == NULL) { + die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); + } + + char *temp_keyname = NULL; + if (keyname == NULL) { + temp_keyname = _np_state_generate_key(argc, argv); + } else { + temp_keyname = strdup(keyname); + if (temp_keyname == NULL) { + die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno)); + } + } + + /* Die if invalid characters used for keyname */ + char *tmp_char = temp_keyname; + while (*tmp_char != '\0') { + if (!(isalnum(*tmp_char) || *tmp_char == '_')) { + die(STATE_UNKNOWN, _("Invalid character for keyname - only alphanumerics or '_'")); + } + tmp_char++; + } + this_state->name = temp_keyname; + this_state->plugin_name = plugin_name; + this_state->data_version = expected_data_version; + this_state->state_data = NULL; + + /* Calculate filename */ + char *temp_filename = NULL; + int error = asprintf(&temp_filename, "%s/%lu/%s/%s", _np_state_calculate_location_prefix(), + (unsigned long)geteuid(), plugin_name, this_state->name); + if (error < 0) { + die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); + } + + this_state->_filename = temp_filename; + + return *this_state; +} + +/* + * Returns a string to use as a keyname, based on an md5 hash of argv, thus + * hopefully a unique key per service/plugin invocation. Use the extra-opts + * parse of argv, so that uniqueness in parameters are reflected there. + */ +char *_np_state_generate_key(int argc, char **argv) { + unsigned char result[256]; + +#ifdef USE_OPENSSL + /* + * This code path is chosen if openssl is available (which should be the most common + * scenario). Alternatively, the gnulib implementation/ + * + */ + EVP_MD_CTX *ctx = EVP_MD_CTX_new(); + + EVP_DigestInit(ctx, EVP_sha256()); + + for (int i = 0; i < argc; i++) { + EVP_DigestUpdate(ctx, argv[i], strlen(argv[i])); + } + + EVP_DigestFinal(ctx, result, NULL); +#else + + struct sha256_ctx ctx; + + for (int i = 0; i < this_monitoring_plugin->argc; i++) { + sha256_process_bytes(argv[i], strlen(argv[i]), &ctx); + } + + sha256_finish_ctx(&ctx, result); +#endif // FOUNDOPENSSL + + char keyname[41]; + for (int i = 0; i < 20; ++i) { + sprintf(&keyname[2 * i], "%02x", result[i]); + } + + keyname[40] = '\0'; + + char *keyname_copy = strdup(keyname); + if (keyname_copy == NULL) { + die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno)); + } + + return keyname_copy; +} diff --git a/plugins/check_snmp.d/check_snmp_helpers.h b/plugins/check_snmp.d/check_snmp_helpers.h index 28e3c4e3..0f7780b1 100644 --- a/plugins/check_snmp.d/check_snmp_helpers.h +++ b/plugins/check_snmp.d/check_snmp_helpers.h @@ -1,7 +1,71 @@ #pragma once #include "./config.h" +#include check_snmp_test_unit check_snmp_test_unit_init(); int check_snmp_set_thresholds(const char *, check_snmp_test_unit[], size_t, bool); check_snmp_config check_snmp_config_init(); + +typedef struct { + oid oid[MAX_OID_LEN]; + size_t oid_length; + unsigned char type; + union { + uint64_t uIntVal; + int64_t intVal; + double doubleVal; + } value; + char *string_response; +} response_value; + +typedef struct { + int errorcode; + response_value *response_values; +} snmp_responces; +snmp_responces do_snmp_query(check_snmp_config_snmp_parameters parameters); + +// state is similar to response, but only numerics and a timestamp +typedef struct { + time_t timestamp; + oid oid[MAX_OID_LEN]; + size_t oid_length; + unsigned char type; + union { + unsigned long long uIntVal; + long long intVal; + double doubleVal; + } value; +} check_snmp_state_entry; + +typedef struct { + check_snmp_state_entry state; + mp_subcheck sc; +} check_snmp_evaluation; +check_snmp_evaluation evaluate_single_unit(response_value response, + check_snmp_evaluation_parameters eval_params, + check_snmp_test_unit test_unit, time_t query_timestamp, + check_snmp_state_entry prev_state, + bool have_previous_state); + +#define NP_STATE_FORMAT_VERSION 1 + +typedef struct state_data_struct { + time_t time; + void *data; + size_t length; /* Of binary data */ + int errorcode; +} state_data; + +typedef struct state_key_struct { + char *name; + char *plugin_name; + int data_version; + char *_filename; + state_data *state_data; +} state_key; + +state_data *np_state_read(state_key stateKey); +state_key np_enable_state(char *keyname, int expected_data_version, char *plugin_name, int argc, + char **argv); +void np_state_write_string(state_key stateKey, time_t timestamp, char *stringToStore); diff --git a/plugins/check_snmp.d/config.h b/plugins/check_snmp.d/config.h index e68986e2..a5d5aa52 100644 --- a/plugins/check_snmp.d/config.h +++ b/plugins/check_snmp.d/config.h @@ -1,7 +1,7 @@ #pragma once -#include "thresholds.h" -#include "states.h" +#include "../../lib/thresholds.h" +#include "../../lib/states.h" #include #include #include @@ -18,7 +18,7 @@ #include #include -#define DEFAULT_PORT "161" +#define DEFAULT_PORT "161" #define DEFAULT_RETRIES 5 typedef struct eval_method { @@ -34,10 +34,8 @@ typedef struct check_snmp_test_unit { mp_thresholds threshold; } check_snmp_test_unit; -typedef struct check_snmp_config { - // SNMP session to use +typedef struct { struct snmp_session snmp_session; - // use getnet instead of get bool use_getnext; @@ -47,7 +45,9 @@ typedef struct check_snmp_config { check_snmp_test_unit *test_units; size_t num_of_test_units; +} check_snmp_config_snmp_parameters; +typedef struct { // State if an empty value is encountered mp_state_enum nulloid_result; @@ -63,7 +63,18 @@ typedef struct check_snmp_config { bool offset_set; // Modify output - bool use_perf_data_labels_from_input; + bool use_oid_as_perf_data_label; + + // activate rate calucation + bool calculate_rate; + unsigned int rate_multiplier; +} check_snmp_evaluation_parameters; + +typedef struct check_snmp_config { + // SNMP session to use + check_snmp_config_snmp_parameters snmp_params; + + check_snmp_evaluation_parameters evaluation_params; mp_output_format output_format; bool output_format_is_set; diff --git a/plugins/tests/check_snmp.t b/plugins/tests/check_snmp.t index bfe42e16..26d67898 100755 --- a/plugins/tests/check_snmp.t +++ b/plugins/tests/check_snmp.t @@ -4,12 +4,13 @@ # use strict; +use warnings; use Test::More; use NPTest; use FindBin qw($Bin); use POSIX qw/strftime/; -my $tests = 81; +my $tests = 75; # Check that all dependent modules are available eval { require NetSNMP::OID; @@ -76,49 +77,36 @@ my $res; $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.0"); cmp_ok( $res->return_code, '==', 0, "Exit OK when querying a multi-line string" ); -like($res->output, '/^SNMP OK - /', "String contains SNMP OK"); -like($res->output, '/'.quotemeta('SNMP OK - Cisco Internetwork Operating System Software | -.1.3.6.1.4.1.8072.3.2.67.0: -"Cisco Internetwork Operating System Software -IOS (tm) Catalyst 4000 \"L3\" Switch Software (cat4000-I9K91S-M), Version -12.2(20)EWA, RELEASE SOFTWARE (fc1) -Technical Support: http://www.cisco.com/techsupport -Copyright (c) 1986-2004 by cisco Systems, Inc. -"').'/m', "String contains all lines"); +like($res->output, '/.*Cisco Internetwork Operating System Software.*/m', "String contains all lines"); # sysContact.0 is "Alice" (from our snmpd.conf) $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.0 -o sysContact.0 -o .1.3.6.1.4.1.8072.3.2.67.1"); cmp_ok( $res->return_code, '==', 0, "Exit OK when querying multi-line OIDs" ); -like($res->output, '/^SNMP OK - /', "String contains SNMP OK"); -like($res->output, '/'.quotemeta('SNMP OK - Cisco Internetwork Operating System Software ').'"?Alice"?'.quotemeta(' Kisco Outernetwork Oserating Gystem Totware | -.1.3.6.1.4.1.8072.3.2.67.0: -"Cisco Internetwork Operating System Software -IOS (tm) Catalyst 4000 \"L3\" Switch Software (cat4000-I9K91S-M), Version -12.2(20)EWA, RELEASE SOFTWARE (fc1) -Technical Support: http://www.cisco.com/techsupport -Copyright (c) 1986-2004 by cisco Systems, Inc. -" -.1.3.6.1.4.1.8072.3.2.67.1: -"Kisco Outernetwork Oserating Gystem Totware -Copyleft (c) 2400-2689 by kisco Systrems, Inc."').'/m', "String contains all lines with multiple OIDs"); +# like($res->output, '/^SNMP OK - /', "String contains SNMP OK"); +like($res->output, '/.*Cisco Internetwork Operating System Software.*/m', "String contains all lines with multiple OIDs"); +like($res->output, '/.*Alice.*/m', "String contains all lines with multiple OIDs"); +like($res->output, '/.*Kisco Outernetwork Oserating Gystem Totware.*/m', "String contains all lines with multiple OIDs"); $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.2"); -like($res->output, '/'.quotemeta('SNMP OK - This should not confuse check_snmp \"parser\" | -.1.3.6.1.4.1.8072.3.2.67.2: -"This should not confuse check_snmp \"parser\" -into thinking there is no 2nd line"').'/m', "Attempt to confuse parser No.1"); +cmp_ok( $res->return_code, '==', 0, "Exit OK when querying multi-line OIDs" ); +# like($res->output, '/'.quotemeta('This should not confuse check_snmp \"parser\" | +# .1.3.6.1.4.1.8072.3.2.67.2: +# "This should not confuse check_snmp \"parser\" +# into thinking there is no 2nd line"').'/m', "Attempt to confuse parser No.1"); $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.3"); -like($res->output, '/'.quotemeta('SNMP OK - It\'s getting even harder if the line | -.1.3.6.1.4.1.8072.3.2.67.3: -"It\'s getting even harder if the line -ends with with this: C:\\\\"').'/m', "Attempt to confuse parser No.2"); +cmp_ok( $res->return_code, '==', 0, "Exit OK when querying multi-line OIDs" ); +# like($res->output, '/'.quotemeta('It\'s getting even harder if the line | +# .1.3.6.1.4.1.8072.3.2.67.3: +# "It\'s getting even harder if the line +# ends with with this: C:\\\\"').'/m', "Attempt to confuse parser No.2"); $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.4"); -like($res->output, '/'.quotemeta('SNMP OK - And now have fun with with this: \"C:\\\\\" | -.1.3.6.1.4.1.8072.3.2.67.4: -"And now have fun with with this: \"C:\\\\\" -because we\'re not done yet!"').'/m', "Attempt to confuse parser No.3"); +cmp_ok( $res->return_code, '==', 0, "Exit OK when querying multi-line OIDs" ); +# like($res->output, '/'.quotemeta('And now have fun with with this: \"C:\\\\\" | +# .1.3.6.1.4.1.8072.3.2.67.4: +# "And now have fun with with this: \"C:\\\\\" +# because we\'re not done yet!"').'/m', "Attempt to confuse parser No.3"); system("rm -f ".$ENV{'MP_STATE_PATH'}."/*/check_snmp/*"); @@ -131,156 +119,159 @@ SKIP: { my $ts = time(); $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -w 600" ); is($res->return_code, 0, "Returns OK"); - is($res->output, "No previous data to calculate rate - assume okay"); + like($res->output, "/.*No previous data to calculate rate - assume okay.*/"); # test rate 1 second later $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts+1))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -w 600" ); is($res->return_code, 1, "WARNING - due to going above rate calculation" ); - is($res->output, "SNMP RATE WARNING - *666* | iso.3.6.1.4.1.8072.3.2.67.10=666;600 "); + like($res->output, "/.*=666.*/"); # test rate with same time $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts+1))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -w 600" ); is($res->return_code, 3, "UNKNOWN - basically the divide by zero error" ); - is($res->output, "Time duration between plugin calls is invalid"); + like($res->output, "/.*Time duration between plugin calls is invalid.*/"); $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -l inoctets" ); is($res->return_code, 0, "OK for first call" ); - is($res->output, "No previous data to calculate rate - assume okay" ); + like($res->output, "/.*No previous data to calculate rate - assume okay.*/" ); # test rate 1 second later $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts+1))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -l inoctets" ); is($res->return_code, 0, "OK as no thresholds" ); - is($res->output, "SNMP RATE OK - inoctets 666 | inoctets=666 ", "Check label"); + like($res->output, "/.*inoctets.*=666.*/m", "Check label"); # test rate 3 seconds later $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts+3))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -l inoctets" ); is($res->return_code, 0, "OK as no thresholds" ); - is($res->output, "SNMP RATE OK - inoctets 333 | inoctets=333 ", "Check rate decreases due to longer interval"); + like($res->output, "/.*inoctets.*333.*/", "Check rate decreases due to longer interval"); # label performance data check $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 -l test" ); is($res->return_code, 0, "OK as no thresholds" ); - is($res->output, "SNMP OK - test 67996 | test=67996c ", "Check label"); + like($res->output, "/.*test.?=67996c/", "Check label"); - $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 -l \"test'test\"" ); - is($res->return_code, 0, "OK as no thresholds" ); - is($res->output, "SNMP OK - test'test 68662 | \"test'test\"=68662c ", "Check label"); + # following test is deactivated since it was not valid due to the guidelines (no single quote in label allowed) + # $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 -l \"test'test\"" ); + # is($res->return_code, 0, "OK as no thresholds" ); + # is($res->output, "test'test 68662 | \"test'test\"=68662c ", "Check label"); $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 -l 'test\"test'" ); is($res->return_code, 0, "OK as no thresholds" ); - is($res->output, "SNMP OK - test\"test 69328 | 'test\"test'=69328c ", "Check label"); + like($res->output, "/.*'test\"test'=68662c.*/", "Check label"); $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 -l test -O" ); is($res->return_code, 0, "OK as no thresholds" ); - is($res->output, "SNMP OK - test 69994 | iso.3.6.1.4.1.8072.3.2.67.10=69994c ", "Check label"); + like($res->output, "/.*.67.10.?=69328c.*/", "Check label"); $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10" ); is($res->return_code, 0, "OK as no thresholds" ); - is($res->output, "SNMP OK - 70660 | iso.3.6.1.4.1.8072.3.2.67.10=70660c ", "Check label"); + like($res->output, "/.*8072.3.2.67.10.?=69994c.*/", "Check label"); $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 -l 'test test'" ); is($res->return_code, 0, "OK as no thresholds" ); - is($res->output, "SNMP OK - test test 71326 | 'test test'=71326c ", "Check label"); + like($res->output, "/.*'test test'=70660c/", "Check label"); $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -l inoctets_per_minute --rate-multiplier=60" ); is($res->return_code, 0, "OK for first call" ); - is($res->output, "No previous data to calculate rate - assume okay" ); + like($res->output, "/.*No previous data to calculate rate - assume okay.*/" ); # test 1 second later $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts+1))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -l inoctets_per_minute --rate-multiplier=60" ); is($res->return_code, 0, "OK as no thresholds" ); - is($res->output, "SNMP RATE OK - inoctets_per_minute 39960 | inoctets_per_minute=39960 ", "Checking multiplier"); + like($res->output, "/.*inoctets_per_minute.*=39960/", "Checking multiplier"); }; -$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.11 -s '\"stringtests\"'" ); +$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.11 -s 'stringtests'" ); is($res->return_code, 0, "OK as string matches" ); -is($res->output, 'SNMP OK - "stringtests" | ', "Good string match" ); +like($res->output, '/.*stringtests.*/', "Good string match" ); $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.11 -s ring" ); is($res->return_code, 2, "CRITICAL as string doesn't match (though is a substring)" ); -is($res->output, 'SNMP CRITICAL - *"stringtests"* | ', "Failed string match" ); +like($res->output, '/.*stringtests.*/', "Failed string match" ); -$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.11 --invert-search -s '\"stringtests\"'" ); +$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.11 --invert-search -s 'stringtests'" ); is($res->return_code, 2, "CRITICAL as string matches but inverted" ); -is($res->output, 'SNMP CRITICAL - *"stringtests"* | ', "Inverted string match" ); +like($res->output, '/.*"stringtests".*/', "Inverted string match" ); $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.11 --invert-search -s ring" ); is($res->return_code, 0, "OK as string doesn't match but inverted" ); -is($res->output, 'SNMP OK - "stringtests" | ', "OK as inverted string no match" ); +like($res->output, '/.*"stringtests".*/', "OK as inverted string no match" ); $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.12 -w 4:5" ); -is($res->return_code, 1, "Numeric in string test" ); -is($res->output, 'SNMP WARNING - *3.5* | iso.3.6.1.4.1.8072.3.2.67.12=3.5;4:5 ', "WARNING threshold checks for string masquerading as number" ); +# a string is a string and not a number +is($res->return_code, 0, "Numeric in string test" ); +like($res->output, '/.*3.5.*| iso.3.6.1.4.1.8072.3.2.67.12=3.5;4:5/', "WARNING threshold checks for string masquerading as number" ); $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.13" ); is($res->return_code, 0, "Not really numeric test" ); -is($res->output, 'SNMP OK - "87.4startswithnumberbutshouldbestring" | ', "Check string with numeric start is still string" ); +like($res->output, '/.*"87.4startswithnumberbutshouldbestring".*/', "Check string with numeric start is still string" ); $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.14" ); is($res->return_code, 0, "Not really numeric test (trying best to fool it)" ); -is($res->output, 'SNMP OK - "555\"I said\"" | ', "Check string with a double quote following is still a string (looks like the perl routine will always escape though)" ); +like($res->output, '/.*\'555"I said"\'.*/', "Check string with a double quote following is still a string (looks like the perl routine will always escape though)" ); $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.15 -r 'CUSTOM CHECK OK'" ); is($res->return_code, 0, "String check should check whole string, not a parsed number" ); -is($res->output, 'SNMP OK - "CUSTOM CHECK OK: foo is 12345" | ', "String check with numbers returns whole string"); +like($res->output, '/.*CUSTOM CHECK OK: foo is 12345.*/', "String check with numbers returns whole string"); $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.16 -w -2: -c -3:" ); is($res->return_code, 0, "Negative integer check OK" ); -is($res->output, 'SNMP OK - -2 | iso.3.6.1.4.1.8072.3.2.67.16=-2;-2:;-3: ', "Negative integer check OK output" ); +like($res->output, '/.*-2.*| iso.3.6.1.4.1.8072.3.2.67.16=-2;-2:;-3:/', "Negative integer check OK output" ); $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.16 -w -2: -c -3:" ); is($res->return_code, 1, "Negative integer check WARNING" ); -is($res->output, 'SNMP WARNING - *-3* | iso.3.6.1.4.1.8072.3.2.67.16=-3;-2:;-3: ', "Negative integer check WARNING output" ); +like($res->output, '/.*-3.*| iso.3.6.1.4.1.8072.3.2.67.16=-3;-2:;-3:/', "Negative integer check WARNING output" ); $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.16 -w -2: -c -3:" ); is($res->return_code, 2, "Negative integer check CRITICAL" ); -is($res->output, 'SNMP CRITICAL - *-4* | iso.3.6.1.4.1.8072.3.2.67.16=-4;-2:;-3: ', "Negative integer check CRITICAL output" ); +like($res->output, '/.*-4.*| iso.3.6.1.4.1.8072.3.2.67.16=-4;-2:;-3:/', "Negative integer check CRITICAL output" ); $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.17 -w -3: -c -6:" ); is($res->return_code, 1, "Negative integer as string, WARNING" ); -is($res->output, 'SNMP WARNING - *-4* | iso.3.6.1.4.1.8072.3.2.67.17=-4;-3:;-6: ', "Negative integer as string, WARNING output" ); +like($res->output, '/.*-4.*| iso.3.6.1.4.1.8072.3.2.67.17=-4;-3:;-6:/', "Negative integer as string, WARNING output" ); $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.17 -w -2: -c -3:" ); is($res->return_code, 2, "Negative integer as string, CRITICAL" ); -is($res->output, 'SNMP CRITICAL - *-4* | iso.3.6.1.4.1.8072.3.2.67.17=-4;-2:;-3: ', "Negative integer as string, CRITICAL output" ); +like($res->output, '/.*-4.*| iso.3.6.1.4.1.8072.3.2.67.17=-4;-2:;-3:/', "Negative integer as string, CRITICAL output" ); -$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.18 -c '~:-6.5'" ); -is($res->return_code, 0, "Negative float OK" ); -is($res->output, 'SNMP OK - -6.6 | iso.3.6.1.4.1.8072.3.2.67.18=-6.6;;@-6.5:~ ', "Negative float OK output" ); +# deactivated since the perl agent api of snmpd really does not allow floats +# $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.18 -c '~:-6.5'" ); +# is($res->return_code, 0, "Negative float OK" ); +# is($res->output, '-6.6 | iso.3.6.1.4.1.8072.3.2.67.18=-6.6;;@-6.5:~ ', "Negative float OK output" ); -$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.18 -w '~:-6.65' -c '~:-6.55'" ); -is($res->return_code, 1, "Negative float WARNING" ); -is($res->output, 'SNMP WARNING - *-6.6* | iso.3.6.1.4.1.8072.3.2.67.18=-6.6;@-6.65:~;@-6.55:~ ', "Negative float WARNING output" ); +# $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.18 -w '~:-6.65' -c '~:-6.55'" ); +# is($res->return_code, 1, "Negative float WARNING" ); +# like($res->output, '/-6.6.*| .*67.18=-6.6;@-6.65:~;@-6.55:~/', "Negative float WARNING output" ); $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10,.1.3.6.1.4.1.8072.3.2.67.17 -w '1:100000,-10:20' -c '2:200000,-20:30'" ); is($res->return_code, 0, "Multiple OIDs with thresholds" ); -like($res->output, '/SNMP OK - \d+ -4 | iso.3.6.1.4.1.8072.3.2.67.10=\d+c;1:100000;2:200000 iso.3.6.1.4.1.8072.3.2.67.17=-4;-10:20;-20:30/', "Multiple OIDs with thresholds output" ); +like($res->output, '/-4.*| .*67.10=\d+c;1:100000;2:200000 .*67.17=-4;-10:20;-20:30/', "Multiple OIDs with thresholds output" ); $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10,.1.3.6.1.4.1.8072.3.2.67.17 -w '1:100000,-1:2' -c '2:200000,-20:30'" ); is($res->return_code, 1, "Multiple OIDs with thresholds" ); -like($res->output, '/SNMP WARNING - \d+ \*-4\* | iso.3.6.1.4.1.8072.3.2.67.10=\d+c;1:100000;2:200000 iso.3.6.1.4.1.8072.3.2.67.17=-4;-10:20;-20:30/', "Multiple OIDs with thresholds output" ); +like($res->output, '/-4.*| iso.3.6.1.4.1.8072.3.2.67.10=\d+c;1:100000;2:200000 iso.3.6.1.4.1.8072.3.2.67.17=-4;-10:20;-20:30/', "Multiple OIDs with thresholds output" ); -$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10,.1.3.6.1.4.1.8072.3.2.67.17 -w 1,2 -c 1" ); +$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10,.1.3.6.1.4.1.8072.3.2.67.17 -w 1,2 -c 1 -O" ); is($res->return_code, 2, "Multiple OIDs with some thresholds" ); -like($res->output, '/SNMP CRITICAL - \*\d+\* \*-4\* | iso.3.6.1.4.1.8072.3.2.67.10=\d+c;1;2 iso.3.6.1.4.1.8072.3.2.67.17=-4;;/', "Multiple OIDs with thresholds output" ); +like($res->output, '/.*-4.*| iso.3.6.1.4.1.8072.3.2.67.10=\d+c;1;2 iso.3.6.1.4.1.8072.3.2.67.17=-4;;/', "Multiple OIDs with thresholds output" ); $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.19"); is($res->return_code, 0, "Test plain .1.3.6.1.4.1.8072.3.2.67.6 RC" ); -is($res->output,'SNMP OK - 42 | iso.3.6.1.4.1.8072.3.2.67.19=42 ', "Test plain value of .1.3.6.1.4.1.8072.3.2.67.1" ); +like($res->output,'/.*42.*| iso.3.6.1.4.1.8072.3.2.67.19=42/', "Test plain value of .1.3.6.1.4.1.8072.3.2.67.1" ); $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.19 -M .1"); is($res->return_code, 0, "Test multiply RC" ); -is($res->output,'SNMP OK - 4.200000 | iso.3.6.1.4.1.8072.3.2.67.19=4.200000 ' , "Test multiply .1 output" ); +like($res->output,'/.*4.200000.*| iso.3.6.1.4.1.8072.3.2.67.19=4.200000/' , "Test multiply .1 output" ); -$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.19 --multiplier=.1 -f '%.2f' "); -is($res->return_code, 0, "Test multiply RC + format" ); -is($res->output, 'SNMP OK - 4.20 | iso.3.6.1.4.1.8072.3.2.67.19=4.20 ', "Test multiply .1 output + format" ); +$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.19 --multiplier=.1"); +is($res->return_code, 0, "Test multiply RC" ); +like($res->output, '/.*4.20.*| iso.3.6.1.4.1.8072.3.2.67.19=4.20/', "Test multiply .1 output" ); -$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.19 --multiplier=.1 -f '%.2f' -w 1"); -is($res->return_code, 1, "Test multiply RC + format + thresholds" ); -is($res->output, 'SNMP WARNING - *4.20* | iso.3.6.1.4.1.8072.3.2.67.19=4.20;1 ', "Test multiply .1 output + format + thresholds" ); +$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.19 --multiplier=.1 -w 1"); +is($res->return_code, 1, "Test multiply RC + thresholds" ); +like($res->output, '/.*4.20.* | iso.3.6.1.4.1.8072.3.2.67.19=4.20+;1/', "Test multiply .1 output + thresholds" ); diff --git a/plugins/tests/check_snmp_agent.pl b/plugins/tests/check_snmp_agent.pl index 38912e98..608b6f92 100644 --- a/plugins/tests/check_snmp_agent.pl +++ b/plugins/tests/check_snmp_agent.pl @@ -4,9 +4,10 @@ # #use strict; # Doesn't work +use warnings; use NetSNMP::OID qw(:all); use NetSNMP::agent; -use NetSNMP::ASN qw(ASN_OCTET_STR ASN_COUNTER ASN_COUNTER64 ASN_INTEGER ASN_INTEGER64 ASN_UNSIGNED ASN_UNSIGNED64); +use NetSNMP::ASN qw(ASN_OCTET_STR ASN_COUNTER ASN_COUNTER64 ASN_INTEGER ASN_INTEGER64 ASN_UNSIGNED ASN_UNSIGNED64 ASN_FLOAT); #use Math::Int64 qw(uint64); # Skip that module while we don't need it sub uint64 { return $_ } @@ -22,21 +23,82 @@ IOS (tm) Catalyst 4000 "L3" Switch Software (cat4000-I9K91S-M), Version Technical Support: http://www.cisco.com/techsupport Copyright (c) 1986-2004 by cisco Systems, Inc. '; -my $multilin2 = "Kisco Outernetwork Oserating Gystem Totware +my $multiline2 = "Kisco Outernetwork Oserating Gystem Totware Copyleft (c) 2400-2689 by kisco Systrems, Inc."; -my $multilin3 = 'This should not confuse check_snmp "parser" +my $multiline3 = 'This should not confuse check_snmp "parser" into thinking there is no 2nd line'; -my $multilin4 = 'It\'s getting even harder if the line +my $multiline4 = 'It\'s getting even harder if the line ends with with this: C:\\'; -my $multilin5 = 'And now have fun with with this: "C:\\" +my $multiline5 = 'And now have fun with with this: "C:\\" because we\'re not done yet!'; # Next are arrays of indexes (Type, initial value and increments) # 0..19 <---- please update comment when adding/removing fields -my @fields = (ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_UNSIGNED, ASN_UNSIGNED, ASN_COUNTER, ASN_COUNTER64, ASN_UNSIGNED, ASN_COUNTER, ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_INTEGER, ASN_OCTET_STR, ASN_OCTET_STR, ASN_INTEGER ); -my @values = ($multiline, $multilin2, $multilin3, $multilin4, $multilin5, 4294965296, 1000, 4294965296, uint64("18446744073709351616"), int(rand(2**32)), 64000, "stringtests", "3.5", "87.4startswithnumberbutshouldbestring", '555"I said"', 'CUSTOM CHECK OK: foo is 12345', -2, '-4', '-6.6', 42 ); +my @fields = (ASN_OCTET_STR, # 0 + ASN_OCTET_STR, # 1 + ASN_OCTET_STR, # 2 + ASN_OCTET_STR, # 3 + ASN_OCTET_STR, # 4 + ASN_UNSIGNED, # 5 + ASN_UNSIGNED, # 6 + ASN_COUNTER, # 7 + ASN_COUNTER64, # 8 + ASN_UNSIGNED, # 9 + ASN_COUNTER, # 10 + ASN_OCTET_STR, # 11 + ASN_OCTET_STR, # 12 + ASN_OCTET_STR, # 13 + ASN_OCTET_STR, # 14 + ASN_OCTET_STR, # 15 + ASN_INTEGER, # 16 + ASN_INTEGER, # 17 + ASN_FLOAT, # 18 + ASN_INTEGER # 19 + ); +my @values = ($multiline, # 0 + $multiline2, # 1 + $multiline3, # 2 + $multiline4, # 3 + $multiline5, # 4 + 4294965296, # 5 + 1000, # 6 + 4294965296, # 7 + uint64("18446744073709351616"), # 8 + int(rand(2**32)), # 9 + 64000, # 10 + "stringtests", # 11 + "3.5", # 12 + "87.4startswithnumberbutshouldbestring", # 13 + '555"I said"', # 14 + 'CUSTOM CHECK OK: foo is 12345', # 15 + '-2', # 16 + '-4', # 17 + '-6.6', # 18 + 42 # 19 + ); # undef increments are randomized -my @incrts = (undef, undef, undef, undef, undef, 1000, -500, 1000, 100000, undef, 666, undef, undef, undef, undef, undef, -1, undef, undef, 0 ); +my @incrts = ( + undef, # 0 + undef, # 1 + undef, # 2 + undef, # 3 + undef, # 4 + 1000, # 5 + -500, # 6 + 1000, # 7 + 100000, # 8 + undef, # 9 + 666, # 10 + undef, # 11 + undef, # 12 + undef, # 13 + undef, # 14 + undef, # 15 + -1, # 16 + 0, # 17 + undef, # 18 + 0 # 19 + ); # Number of elements in our OID my $oidelts; diff --git a/plugins/tests/test_check_snmp.c b/plugins/tests/test_check_snmp.c new file mode 100644 index 00000000..d71706d0 --- /dev/null +++ b/plugins/tests/test_check_snmp.c @@ -0,0 +1,175 @@ +/***************************************************************************** + * + * 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 . + * + * + *****************************************************************************/ + +#include "tap.h" +#include "../../config.h" + +#include +#include +#include + +#include "utils_base.c" +#include "../check_snmp.d/check_snmp_helpers.h" + +char *_np_state_generate_key(int argc, char **argv); +char *_np_state_calculate_location_prefix(void); + +int main(int argc, char **argv) { + char *temp_string = (char *)_np_state_generate_key(argc, argv); + ok(!strcmp(temp_string, "e2d17f995fd4c020411b85e3e3d0ff7306d4147e"), + "Got hash with exe and no parameters") || + diag("You are probably running in wrong directory. Must run as ./test_utils"); + + int fake_argc = 4; + char *fake_argv[] = { + "./test_utils", + "here", + "--and", + "now", + }; + temp_string = (char *)_np_state_generate_key(fake_argc, fake_argv); + ok(!strcmp(temp_string, "bd72da9f78ff1419fad921ea5e43ce56508aef6c"), + "Got based on expected argv"); + + unsetenv("MP_STATE_PATH"); + temp_string = (char *)_np_state_calculate_location_prefix(); + ok(!strcmp(temp_string, NP_STATE_DIR_PREFIX), "Got default directory"); + + setenv("MP_STATE_PATH", "", 1); + temp_string = (char *)_np_state_calculate_location_prefix(); + ok(!strcmp(temp_string, NP_STATE_DIR_PREFIX), "Got default directory even with empty string"); + + setenv("MP_STATE_PATH", "/usr/local/nagios/var", 1); + temp_string = (char *)_np_state_calculate_location_prefix(); + ok(!strcmp(temp_string, "/usr/local/nagios/var"), "Got default directory"); + + fake_argc = 1; + fake_argv[0] = "./test_utils"; + state_key temp_state_key1 = np_enable_state(NULL, 51, "check_test", fake_argc, fake_argv); + ok(!strcmp(temp_state_key1.plugin_name, "check_test"), "Got plugin name"); + ok(!strcmp(temp_state_key1.name, "e2d17f995fd4c020411b85e3e3d0ff7306d4147e"), + "Got generated filename"); + + state_key temp_state_key2 = + np_enable_state("allowedchars_in_keyname", 77, "check_snmp", fake_argc, fake_argv); + + char state_path[1024]; + sprintf(state_path, "/usr/local/nagios/var/%lu/check_test/allowedchars_in_keyname", + (unsigned long)geteuid()); + ok(!strcmp(temp_state_key2.plugin_name, "check_test"), "Got plugin name"); + ok(!strcmp(temp_state_key2.name, "allowedchars_in_keyname"), "Got key name with valid chars"); + ok(!strcmp(temp_state_key2._filename, state_path), "Got internal filename"); + + /* Don't do this test just yet. Will die */ + /* + np_enable_state("bad^chars$in@here", 77); + temp_state_key = this_monitoring_plugin->state; + ok( !strcmp(temp_state_key->name, "bad_chars_in_here"), "Got key name with bad chars replaced" + ); + */ + + state_key temp_state_key3 = + np_enable_state("funnykeyname", 54, "check_snmp", fake_argc, fake_argv); + sprintf(state_path, "/usr/local/nagios/var/%lu/check_test/funnykeyname", + (unsigned long)geteuid()); + ok(!strcmp(temp_state_key3.plugin_name, "check_test"), "Got plugin name"); + ok(!strcmp(temp_state_key3.name, "funnykeyname"), "Got key name"); + + ok(!strcmp(temp_state_key3._filename, state_path), "Got internal filename"); + ok(temp_state_key3.data_version == 54, "Version set"); + + state_data *temp_state_data = np_state_read(temp_state_key3); + ok(temp_state_data == NULL, "Got no state data as file does not exist"); + + /* + temp_fp = fopen("var/statefile", "r"); + if (temp_fp==NULL) + printf("Error opening. errno=%d\n", errno); + printf("temp_fp=%s\n", temp_fp); + ok( _np_state_read_file(temp_fp) == true, "Can read state file" ); + fclose(temp_fp); + */ + + temp_state_key3._filename = "var/statefile"; + temp_state_data = np_state_read(temp_state_key3); + ok(temp_state_data != NULL, "Got state data now") || + diag("Are you running in right directory? Will get coredump next if not"); + ok(temp_state_data->time == 1234567890, "Got time"); + ok(!strcmp((char *)temp_state_data->data, "String to read"), "Data as expected"); + + temp_state_key3.data_version = 53; + temp_state_data = np_state_read(temp_state_key3); + ok(temp_state_data == NULL, "Older data version gives NULL"); + temp_state_key3.data_version = 54; + + temp_state_key3._filename = "var/nonexistent"; + temp_state_data = np_state_read(temp_state_key3); + ok(temp_state_data == NULL, "Missing file gives NULL"); + + temp_state_key3._filename = "var/oldformat"; + temp_state_data = np_state_read(temp_state_key3); + ok(temp_state_data == NULL, "Old file format gives NULL"); + + temp_state_key3._filename = "var/baddate"; + temp_state_data = np_state_read(temp_state_key3); + ok(temp_state_data == NULL, "Bad date gives NULL"); + + temp_state_key3._filename = "var/missingdataline"; + temp_state_data = np_state_read(temp_state_key3); + ok(temp_state_data == NULL, "Missing data line gives NULL"); + + unlink("var/generated"); + temp_state_key3._filename = "var/generated"; + + time_t current_time = 1234567890; + np_state_write_string(temp_state_key3, current_time, "String to read"); + ok(system("cmp var/generated var/statefile") == 0, "Generated file same as expected"); + + unlink("var/generated_directory/statefile"); + unlink("var/generated_directory"); + temp_state_key3._filename = "var/generated_directory/statefile"; + current_time = 1234567890; + np_state_write_string(temp_state_key3, current_time, "String to read"); + ok(system("cmp var/generated_directory/statefile var/statefile") == 0, + "Have created directory"); + + /* This test to check cannot write to dir - can't automate yet */ + /* + unlink("var/generated_bad_dir"); + mkdir("var/generated_bad_dir", S_IRUSR); + np_state_write_string(current_time, "String to read"); + */ + + temp_state_key3._filename = "var/generated"; + time(¤t_time); + np_state_write_string(temp_state_key3, 0, "String to read"); + temp_state_data = np_state_read(temp_state_key3); + /* Check time is set to current_time */ + ok(system("cmp var/generated var/statefile > /dev/null") != 0, + "Generated file should be different this time"); + ok(temp_state_data->time - current_time <= 1, "Has time generated from current time"); + + /* Don't know how to automatically test this. Need to be able to redefine die and catch the + * error */ + /* + temp_state_key->_filename="/dev/do/not/expect/to/be/able/to/write"; + np_state_write_string(0, "Bad file"); + */ + + np_cleanup(); +} diff --git a/plugins/tests/test_check_snmp.t b/plugins/tests/test_check_snmp.t new file mode 100755 index 00000000..967633e9 --- /dev/null +++ b/plugins/tests/test_check_snmp.t @@ -0,0 +1,6 @@ +#!/usr/bin/perl +use Test::More; +if (! -e "./test_check_snmp") { + plan skip_all => "./test_check_snmp not compiled - please enable libtap library to test"; +} +exec "./test_check_snmp"; -- cgit v1.2.3-74-g34f1 From be9db2e02f5e3ffdf14c84beb5382336bbfca063 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Mon, 8 Sep 2025 15:59:20 +0200 Subject: lib: code formatting, perfdata label sanity checking and so on --- lib/perfdata.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 58 insertions(+), 14 deletions(-) (limited to 'lib') diff --git a/lib/perfdata.c b/lib/perfdata.c index b87de7e0..2930a8bc 100644 --- a/lib/perfdata.c +++ b/lib/perfdata.c @@ -33,7 +33,18 @@ char *pd_value_to_string(const mp_perfdata_value pd) { char *pd_to_string(mp_perfdata pd) { assert(pd.label != NULL); char *result = NULL; - asprintf(&result, "'%s'=", pd.label); + + if (strchr(pd.label, '\'') == NULL) { + asprintf(&result, "'%s'=", pd.label); + } else { + // we have a illegal single quote in the string + // replace it silently instead of complaining + for (char *ptr = pd.label; *ptr == '\0'; ptr++) { + if (*ptr == '\'') { + *ptr = '_'; + } + } + } asprintf(&result, "%s%s", result, pd_value_to_string(pd.value)); @@ -249,7 +260,9 @@ char *mp_range_to_string(const mp_range input) { return result; } -mp_perfdata mp_set_pd_value_float(mp_perfdata pd, float value) { return mp_set_pd_value_double(pd, value); } +mp_perfdata mp_set_pd_value_float(mp_perfdata pd, float value) { + return mp_set_pd_value_double(pd, value); +} mp_perfdata mp_set_pd_value_double(mp_perfdata pd, double value) { pd.value.pd_double = value; @@ -257,15 +270,25 @@ mp_perfdata mp_set_pd_value_double(mp_perfdata pd, double value) { return pd; } -mp_perfdata mp_set_pd_value_char(mp_perfdata pd, char value) { return mp_set_pd_value_long_long(pd, (long long)value); } +mp_perfdata mp_set_pd_value_char(mp_perfdata pd, char value) { + return mp_set_pd_value_long_long(pd, (long long)value); +} -mp_perfdata mp_set_pd_value_u_char(mp_perfdata pd, unsigned char value) { return mp_set_pd_value_u_long_long(pd, (unsigned long long)value); } +mp_perfdata mp_set_pd_value_u_char(mp_perfdata pd, unsigned char value) { + return mp_set_pd_value_u_long_long(pd, (unsigned long long)value); +} -mp_perfdata mp_set_pd_value_int(mp_perfdata pd, int value) { return mp_set_pd_value_long_long(pd, (long long)value); } +mp_perfdata mp_set_pd_value_int(mp_perfdata pd, int value) { + return mp_set_pd_value_long_long(pd, (long long)value); +} -mp_perfdata mp_set_pd_value_u_int(mp_perfdata pd, unsigned int value) { return mp_set_pd_value_u_long_long(pd, (unsigned long long)value); } +mp_perfdata mp_set_pd_value_u_int(mp_perfdata pd, unsigned int value) { + return mp_set_pd_value_u_long_long(pd, (unsigned long long)value); +} -mp_perfdata mp_set_pd_value_long(mp_perfdata pd, long value) { return mp_set_pd_value_long_long(pd, (long long)value); } +mp_perfdata mp_set_pd_value_long(mp_perfdata pd, long value) { + return mp_set_pd_value_long_long(pd, (long long)value); +} mp_perfdata mp_set_pd_value_u_long(mp_perfdata pd, unsigned long value) { return mp_set_pd_value_u_long_long(pd, (unsigned long long)value); @@ -290,19 +313,33 @@ mp_perfdata_value mp_create_pd_value_double(double value) { return res; } -mp_perfdata_value mp_create_pd_value_float(float value) { return mp_create_pd_value_double((double)value); } +mp_perfdata_value mp_create_pd_value_float(float value) { + return mp_create_pd_value_double((double)value); +} -mp_perfdata_value mp_create_pd_value_char(char value) { return mp_create_pd_value_long_long((long long)value); } +mp_perfdata_value mp_create_pd_value_char(char value) { + return mp_create_pd_value_long_long((long long)value); +} -mp_perfdata_value mp_create_pd_value_u_char(unsigned char value) { return mp_create_pd_value_u_long_long((unsigned long long)value); } +mp_perfdata_value mp_create_pd_value_u_char(unsigned char value) { + return mp_create_pd_value_u_long_long((unsigned long long)value); +} -mp_perfdata_value mp_create_pd_value_int(int value) { return mp_create_pd_value_long_long((long long)value); } +mp_perfdata_value mp_create_pd_value_int(int value) { + return mp_create_pd_value_long_long((long long)value); +} -mp_perfdata_value mp_create_pd_value_u_int(unsigned int value) { return mp_create_pd_value_u_long_long((unsigned long long)value); } +mp_perfdata_value mp_create_pd_value_u_int(unsigned int value) { + return mp_create_pd_value_u_long_long((unsigned long long)value); +} -mp_perfdata_value mp_create_pd_value_long(long value) { return mp_create_pd_value_long_long((long long)value); } +mp_perfdata_value mp_create_pd_value_long(long value) { + return mp_create_pd_value_long_long((long long)value); +} -mp_perfdata_value mp_create_pd_value_u_long(unsigned long value) { return mp_create_pd_value_u_long_long((unsigned long long)value); } +mp_perfdata_value mp_create_pd_value_u_long(unsigned long value) { + return mp_create_pd_value_u_long_long((unsigned long long)value); +} mp_perfdata_value mp_create_pd_value_long_long(long long value) { mp_perfdata_value res = {0}; @@ -368,6 +405,13 @@ mp_range_parsed mp_parse_range_string(const char *input) { } char *working_copy = strdup(input); + if (working_copy == NULL) { + // strdup error, probably + mp_range_parsed result = { + .error = MP_RANGE_PARSING_FAILURE, + }; + return result; + } input = working_copy; char *separator = index(working_copy, ':'); -- cgit v1.2.3-74-g34f1 From aaff3aa9da27ff7666d2a776d524c784b76eb3d7 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Fri, 12 Sep 2025 16:36:48 +0200 Subject: lib: some formatting + remove some unnecessary stuff --- lib/perfdata.h | 46 +++++++++++++++++++++++----------------------- lib/thresholds.h | 4 ++-- 2 files changed, 25 insertions(+), 25 deletions(-) (limited to 'lib') diff --git a/lib/perfdata.h b/lib/perfdata.h index c5d4a61d..e51ef5fd 100644 --- a/lib/perfdata.h +++ b/lib/perfdata.h @@ -28,7 +28,7 @@ typedef struct { /* * New range type with generic numerical values */ -typedef struct mp_range_struct { +typedef struct { mp_perfdata_value start; bool start_infinity; /* false (default) or true */ @@ -41,7 +41,7 @@ typedef struct mp_range_struct { /* * Old range type with floating point values */ -typedef struct range_struct { +typedef struct { double start; bool start_infinity; double end; @@ -53,7 +53,7 @@ typedef struct range_struct { /* * Perfdata type for storing perfdata output */ -typedef struct perfdata_struct { +typedef struct { char *label; char *uom; mp_perfdata_value value; @@ -131,15 +131,15 @@ mp_range_parsed mp_parse_range_string(const char * /*input*/); */ void pd_list_append(pd_list[1], mp_perfdata); -#define mp_set_pd_value(P, V) \ - _Generic((V), \ - float: mp_set_pd_value_float, \ - double: mp_set_pd_value_double, \ - int: mp_set_pd_value_int, \ - unsigned int: mp_set_pd_value_u_int, \ - long: mp_set_pd_value_long, \ - unsigned long: mp_set_pd_value_u_long, \ - long long: mp_set_pd_value_long_long, \ +#define mp_set_pd_value(P, V) \ + _Generic((V), \ + float: mp_set_pd_value_float, \ + double: mp_set_pd_value_double, \ + int: mp_set_pd_value_int, \ + unsigned int: mp_set_pd_value_u_int, \ + long: mp_set_pd_value_long, \ + unsigned long: mp_set_pd_value_u_long, \ + long long: mp_set_pd_value_long_long, \ unsigned long long: mp_set_pd_value_u_long_long)(P, V) mp_perfdata mp_set_pd_value_float(mp_perfdata, float); @@ -151,17 +151,17 @@ mp_perfdata mp_set_pd_value_u_long(mp_perfdata, unsigned long); mp_perfdata mp_set_pd_value_long_long(mp_perfdata, long long); mp_perfdata mp_set_pd_value_u_long_long(mp_perfdata, unsigned long long); -#define mp_create_pd_value(V) \ - _Generic((V), \ - float: mp_create_pd_value_float, \ - double: mp_create_pd_value_double, \ - char: mp_create_pd_value_char, \ - unsigned char: mp_create_pd_value_u_char, \ - int: mp_create_pd_value_int, \ - unsigned int: mp_create_pd_value_u_int, \ - long: mp_create_pd_value_long, \ - unsigned long: mp_create_pd_value_u_long, \ - long long: mp_create_pd_value_long_long, \ +#define mp_create_pd_value(V) \ + _Generic((V), \ + float: mp_create_pd_value_float, \ + double: mp_create_pd_value_double, \ + char: mp_create_pd_value_char, \ + unsigned char: mp_create_pd_value_u_char, \ + int: mp_create_pd_value_int, \ + unsigned int: mp_create_pd_value_u_int, \ + long: mp_create_pd_value_long, \ + unsigned long: mp_create_pd_value_u_long, \ + long long: mp_create_pd_value_long_long, \ unsigned long long: mp_create_pd_value_u_long_long)(V) mp_perfdata_value mp_create_pd_value_float(float); diff --git a/lib/thresholds.h b/lib/thresholds.h index 5f9f9247..f8647681 100644 --- a/lib/thresholds.h +++ b/lib/thresholds.h @@ -6,12 +6,12 @@ /* * Old threshold type using the old range type */ -typedef struct thresholds_struct { +typedef struct { range *warning; range *critical; } thresholds; -typedef struct mp_thresholds_struct { +typedef struct { bool warning_is_set; mp_range warning; bool critical_is_set; -- cgit v1.2.3-74-g34f1 From 802e46f8ea36c344f112d7e1dd8d64d17a4cc939 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Mon, 15 Sep 2025 12:59:37 +0200 Subject: Run clang-format again --- lib/extra_opts.c | 28 +- lib/maxfd.c | 5 +- lib/output.c | 11 +- lib/parse_ini.c | 112 +++-- lib/tests/test_base64.c | 271 +++++++----- lib/tests/test_cmd.c | 27 +- lib/tests/test_generic_output.c | 6 +- lib/tests/test_ini1.c | 51 ++- lib/tests/test_opts1.c | 34 +- lib/tests/test_opts2.c | 69 +-- lib/tests/test_tcp.c | 23 +- lib/utils_base.c | 4 +- lib/utils_cmd.c | 95 ++-- lib/utils_tcp.c | 25 +- lib/utils_tcp.h | 3 +- plugins-root/check_dhcp.c | 258 +++++++---- plugins-root/check_icmp.d/config.h | 2 +- plugins-root/pst3.c | 441 +++++++++---------- plugins/check_by_ssh.c | 108 +++-- plugins/check_cluster.c | 26 +- plugins/check_dbi.c | 108 +++-- plugins/check_dig.c | 18 +- plugins/check_disk.c | 288 +++++++----- plugins/check_disk.d/utils_disk.c | 35 +- plugins/check_disk.d/utils_disk.h | 9 +- plugins/check_dns.c | 133 ++++-- plugins/check_dummy.c | 15 +- plugins/check_fping.c | 58 ++- plugins/check_fping.d/config.h | 1 - plugins/check_game.c | 68 +-- plugins/check_hpjd.c | 14 +- plugins/check_ldap.c | 50 ++- plugins/check_load.c | 24 +- plugins/check_mrtg.c | 53 ++- plugins/check_mrtgtraf.c | 32 +- plugins/check_mysql.c | 88 ++-- plugins/check_mysql_query.c | 37 +- plugins/check_nt.c | 115 +++-- plugins/check_ntp.c | 756 +++++++++++++++++--------------- plugins/check_ntp_peer.c | 118 ++--- plugins/check_ntp_time.c | 91 ++-- plugins/check_pgsql.c | 77 ++-- plugins/check_ping.c | 125 ++++-- plugins/check_procs.c | 93 ++-- plugins/check_radius.c | 36 +- plugins/check_real.c | 28 +- plugins/check_smtp.c | 119 +++-- plugins/check_swap.c | 23 +- plugins/check_swap.d/check_swap.h | 3 +- plugins/check_swap.d/swap.c | 18 +- plugins/check_tcp.c | 147 ++++--- plugins/check_time.c | 25 +- plugins/check_ups.c | 47 +- plugins/check_ups.d/config.h | 1 - plugins/check_users.c | 19 +- plugins/check_users.d/users.c | 6 +- plugins/common.h | 175 ++++---- plugins/negate.c | 44 +- plugins/netutils.c | 12 +- plugins/picohttpparser/picohttpparser.c | 243 +++++----- plugins/picohttpparser/picohttpparser.h | 31 +- plugins/popen.c | 68 ++- plugins/popen.h | 20 +- plugins/runcmd.c | 77 ++-- plugins/runcmd.h | 47 +- plugins/sslutils.c | 6 +- plugins/tests/test_check_disk.c | 48 +- plugins/tests/test_check_swap.c | 4 +- plugins/urlize.c | 36 +- plugins/utils.c | 35 +- plugins/utils.h | 51 ++- tap/tap.c | 25 +- tap/tap.h | 43 +- tools/mini_epn.c | 96 ++-- 74 files changed, 3290 insertions(+), 2248 deletions(-) (limited to 'lib') diff --git a/lib/extra_opts.c b/lib/extra_opts.c index 88787336..857b34b4 100644 --- a/lib/extra_opts.c +++ b/lib/extra_opts.c @@ -27,12 +27,13 @@ /* FIXME: copied from utils.h; we should move a bunch of libs! */ bool is_option2(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; + } } /* this is the externally visible function used by plugins */ @@ -56,8 +57,9 @@ char **np_extra_opts(int *argc, char **argv, const char *plugin_name) { /* It is a single argument with value */ argptr = argv[i] + 13; /* Delete the extra opts argument */ - for (j = i; j < *argc; j++) + for (j = i; j < *argc; j++) { argv[j] = argv[j + 1]; + } i--; *argc -= 1; } else if (strcmp(argv[i], "--extra-opts") == 0) { @@ -65,8 +67,9 @@ char **np_extra_opts(int *argc, char **argv, const char *plugin_name) { /* It is a argument with separate value */ argptr = argv[i + 1]; /* Delete the extra-opts argument/value */ - for (j = i; j < *argc - 1; j++) + for (j = i; j < *argc - 1; j++) { argv[j] = argv[j + 2]; + } i -= 2; *argc -= 2; ea_num--; @@ -74,8 +77,9 @@ char **np_extra_opts(int *argc, char **argv, const char *plugin_name) { /* It has no value */ optfound = 1; /* Delete the extra opts argument */ - for (j = i; j < *argc; j++) + for (j = i; j < *argc; j++) { argv[j] = argv[j + 1]; + } i--; *argc -= 1; } @@ -94,16 +98,18 @@ char **np_extra_opts(int *argc, char **argv, const char *plugin_name) { /* append the list to extra_args */ if (extra_args == NULL) { extra_args = ea1; - while ((ea1 = ea1->next)) + while ((ea1 = ea1->next)) { ea_num++; + } } else { ea_tmp = extra_args; while (ea_tmp->next) { ea_tmp = ea_tmp->next; } ea_tmp->next = ea1; - while ((ea1 = ea1->next)) + while ((ea1 = ea1->next)) { ea_num++; + } } ea1 = ea_tmp = NULL; } @@ -116,8 +122,9 @@ char **np_extra_opts(int *argc, char **argv, const char *plugin_name) { /* done processing arguments. now create a new argv array... */ argv_new = (char **)malloc((ea_num + 1) * sizeof(char **)); - if (argv_new == NULL) + if (argv_new == NULL) { die(STATE_UNKNOWN, _("malloc() failed!\n")); + } /* starting with program name */ argv_new[0] = argv[0]; @@ -130,8 +137,9 @@ char **np_extra_opts(int *argc, char **argv, const char *plugin_name) { free(ea1); } /* finally the rest of the argv array */ - for (i = 1; i < *argc; i++) + for (i = 1; i < *argc; i++) { argv_new[argc_new++] = argv[i]; + } *argc = argc_new; /* and terminate. */ argv_new[argc_new] = NULL; diff --git a/lib/maxfd.c b/lib/maxfd.c index ca5b6e54..9b58d8e3 100644 --- a/lib/maxfd.c +++ b/lib/maxfd.c @@ -31,10 +31,11 @@ long mp_open_max(void) { #ifdef _SC_OPEN_MAX errno = 0; if ((maxfd = sysconf(_SC_OPEN_MAX)) < 0) { - if (errno == 0) + if (errno == 0) { maxfd = DEFAULT_MAXFD; /* it's indeterminate */ - else + } else { die(STATE_UNKNOWN, _("sysconf error for _SC_OPEN_MAX\n")); + } } #elif defined(OPEN_MAX) return OPEN_MAX diff --git a/lib/output.c b/lib/output.c index 34ff7dab..f283969f 100644 --- a/lib/output.c +++ b/lib/output.c @@ -377,7 +377,9 @@ static inline char *fmt_subcheck_output(mp_output_format output_format, mp_subch while (tmp_string != NULL) { *tmp_string = '\0'; - asprintf(&intermediate_string, "%s%s\n%s", intermediate_string,check.output, generate_indentation_string(indentation+1)); // one more indentation to make it look better + asprintf(&intermediate_string, "%s%s\n%s", intermediate_string, check.output, + generate_indentation_string( + indentation + 1)); // one more indentation to make it look better if (*(tmp_string + 1) != '\0') { check.output = tmp_string + 1; @@ -394,13 +396,14 @@ static inline char *fmt_subcheck_output(mp_output_format output_format, mp_subch // add the rest (if any) if (have_residual_chars) { char *tmp = check.output; - xasprintf(&check.output, "%s\n%s%s", intermediate_string, generate_indentation_string(indentation+1), tmp); + xasprintf(&check.output, "%s\n%s%s", intermediate_string, + generate_indentation_string(indentation + 1), tmp); } else { check.output = intermediate_string; } } - asprintf(&result, "%s\\_[%s] - %s", generate_indentation_string(indentation), state_text(mp_compute_subcheck_state(check)), - check.output); + asprintf(&result, "%s\\_[%s] - %s", generate_indentation_string(indentation), + state_text(mp_compute_subcheck_state(check)), check.output); subchecks = check.subchecks; diff --git a/lib/parse_ini.c b/lib/parse_ini.c index 1289aae2..4c3c1b93 100644 --- a/lib/parse_ini.c +++ b/lib/parse_ini.c @@ -40,19 +40,22 @@ typedef struct { char *stanza; } np_ini_info; -static char *default_ini_file_names[] = {"monitoring-plugins.ini", "plugins.ini", "nagios-plugins.ini", NULL}; +static char *default_ini_file_names[] = {"monitoring-plugins.ini", "plugins.ini", + "nagios-plugins.ini", NULL}; static char *default_ini_path_names[] = { - "/usr/local/etc/monitoring-plugins/monitoring-plugins.ini", "/usr/local/etc/monitoring-plugins.ini", - "/etc/monitoring-plugins/monitoring-plugins.ini", "/etc/monitoring-plugins.ini", + "/usr/local/etc/monitoring-plugins/monitoring-plugins.ini", + "/usr/local/etc/monitoring-plugins.ini", "/etc/monitoring-plugins/monitoring-plugins.ini", + "/etc/monitoring-plugins.ini", /* deprecated path names (for backward compatibility): */ - "/etc/nagios/plugins.ini", "/usr/local/nagios/etc/plugins.ini", "/usr/local/etc/nagios/plugins.ini", "/etc/opt/nagios/plugins.ini", - "/etc/nagios-plugins.ini", "/usr/local/etc/nagios-plugins.ini", "/etc/opt/nagios-plugins.ini", NULL}; + "/etc/nagios/plugins.ini", "/usr/local/nagios/etc/plugins.ini", + "/usr/local/etc/nagios/plugins.ini", "/etc/opt/nagios/plugins.ini", "/etc/nagios-plugins.ini", + "/usr/local/etc/nagios-plugins.ini", "/etc/opt/nagios-plugins.ini", NULL}; /* eat all characters from a FILE pointer until n is encountered */ -#define GOBBLE_TO(f, c, n) \ - do { \ - (c) = fgetc((f)); \ +#define GOBBLE_TO(f, c, n) \ + do { \ + (c) = fgetc((f)); \ } while ((c) != EOF && (c) != (n)) /* internal function that returns the constructed defaults options */ @@ -87,8 +90,9 @@ static void parse_locator(const char *locator, const char *def_stanza, np_ini_in i->stanza = strdup(def_stanza); } - if (i->stanza == NULL) + if (i->stanza == NULL) { die(STATE_UNKNOWN, _("malloc() failed!\n")); + } /* check whether there's an @file part */ if (stanza_len == locator_len) { @@ -99,8 +103,9 @@ static void parse_locator(const char *locator, const char *def_stanza, np_ini_in i->file_string_on_heap = true; } - if (i->file == NULL || i->file[0] == '\0') + if (i->file == NULL || i->file[0] == '\0') { die(STATE_UNKNOWN, _("Cannot find config file in any standard location.\n")); + } } /* @@ -112,26 +117,31 @@ np_arg_list *np_get_defaults(const char *locator, const char *default_section) { np_ini_info i; int is_suid_plugin = mp_suid(); - if (is_suid_plugin && idpriv_temp_drop() == -1) + if (is_suid_plugin && idpriv_temp_drop() == -1) { die(STATE_UNKNOWN, _("Cannot drop privileges: %s\n"), strerror(errno)); + } parse_locator(locator, default_section, &i); inifile = strcmp(i.file, "-") == 0 ? stdin : fopen(i.file, "r"); - if (inifile == NULL) + if (inifile == NULL) { die(STATE_UNKNOWN, _("Can't read config file: %s\n"), strerror(errno)); - if (!read_defaults(inifile, i.stanza, &defaults)) + } + if (!read_defaults(inifile, i.stanza, &defaults)) { die(STATE_UNKNOWN, _("Invalid section '%s' in config file '%s'\n"), i.stanza, i.file); + } if (i.file_string_on_heap) { free(i.file); } - if (inifile != stdin) + if (inifile != stdin) { fclose(inifile); + } free(i.stanza); - if (is_suid_plugin && idpriv_temp_restore() == -1) + if (is_suid_plugin && idpriv_temp_restore() == -1) { die(STATE_UNKNOWN, _("Cannot restore privileges: %s\n"), strerror(errno)); + } return defaults; } @@ -158,8 +168,9 @@ static int read_defaults(FILE *f, const char *stanza, np_arg_list **opts) { /* our little stanza-parsing state machine */ while ((c = fgetc(f)) != EOF) { /* gobble up leading whitespace */ - if (isspace(c)) + if (isspace(c)) { continue; + } switch (c) { /* globble up comment lines */ case ';': @@ -172,9 +183,11 @@ static int read_defaults(FILE *f, const char *stanza, np_arg_list **opts) { for (i = 0; i < stanza_len; i++) { c = fgetc(f); /* strip leading whitespace */ - if (i == 0) - for (; isspace(c); c = fgetc(f)) + if (i == 0) { + for (; isspace(c); c = fgetc(f)) { continue; + } + } /* nope, read to the end of the line */ if (c != stanza[i]) { GOBBLE_TO(f, c, '\n'); @@ -185,10 +198,12 @@ static int read_defaults(FILE *f, const char *stanza, np_arg_list **opts) { if (i == stanza_len) { c = fgetc(f); /* strip trailing whitespace */ - for (; isspace(c); c = fgetc(f)) + for (; isspace(c); c = fgetc(f)) { continue; - if (c == ']') + } + if (c == ']') { stanzastate = RIGHTSTANZA; + } } break; /* otherwise, we're in the body of a stanza or a parse error */ @@ -239,12 +254,13 @@ static int add_option(FILE *f, np_arg_list **optlst) { if (linebuf == NULL || read_pos + read_sz >= linebuf_sz) { linebuf_sz = linebuf_sz > 0 ? linebuf_sz << 1 : read_sz; linebuf = realloc(linebuf, linebuf_sz); - if (linebuf == NULL) + if (linebuf == NULL) { die(STATE_UNKNOWN, _("malloc() failed!\n")); + } } - if (fgets(&linebuf[read_pos], (int)read_sz, f) == NULL) + if (fgets(&linebuf[read_pos], (int)read_sz, f) == NULL) { done_reading = 1; - else { + } else { read_pos = strlen(linebuf); if (linebuf[read_pos - 1] == '\n') { linebuf[--read_pos] = '\0'; @@ -256,38 +272,46 @@ static int add_option(FILE *f, np_arg_list **optlst) { /* all that to read one line, isn't C fun? :) now comes the parsing :/ */ /* skip leading whitespace */ - for (optptr = linebuf; optptr < lineend && isspace(*optptr); optptr++) + for (optptr = linebuf; optptr < lineend && isspace(*optptr); optptr++) { continue; + } /* continue to '=' or EOL, watching for spaces that might precede it */ for (eqptr = optptr; eqptr < lineend && *eqptr != '='; eqptr++) { - if (isspace(*eqptr) && optend == NULL) + if (isspace(*eqptr) && optend == NULL) { optend = eqptr; - else + } else { optend = NULL; + } } - if (optend == NULL) + if (optend == NULL) { optend = eqptr; + } --optend; /* ^[[:space:]]*=foo is a syntax error */ - if (optptr == eqptr) + if (optptr == eqptr) { die(STATE_UNKNOWN, "%s\n", _("Config file error")); + } /* continue from '=' to start of value or EOL */ - for (valptr = eqptr + 1; valptr < lineend && isspace(*valptr); valptr++) + for (valptr = eqptr + 1; valptr < lineend && isspace(*valptr); valptr++) { continue; + } /* continue to the end of value */ - for (valend = valptr; valend < lineend; valend++) + for (valend = valptr; valend < lineend; valend++) { continue; + } --valend; /* finally trim off trailing spaces */ - for (; isspace(*valend); valend--) + for (; isspace(*valend); valend--) { continue; + } /* calculate the length of "--foo" */ opt_len = (size_t)(1 + optend - optptr); /* 1-character params needs only one dash */ - if (opt_len == 1) + if (opt_len == 1) { cfg_len = 1 + (opt_len); - else + } else { cfg_len = 2 + (opt_len); + } /* if valptrarg[read_pos] = '\0'; /* ...and put that to the end of the list */ - if (*optlst == NULL) + if (*optlst == NULL) { *optlst = optnew; - else { - while (opttmp->next != NULL) + } else { + while (opttmp->next != NULL) { opttmp = opttmp->next; + } opttmp->next = optnew; } @@ -344,7 +370,8 @@ static int add_option(FILE *f, np_arg_list **optlst) { static char *default_file(void) { char *ini_file; - if ((ini_file = getenv("MP_CONFIG_FILE")) != NULL || (ini_file = default_file_in_path()) != NULL) { + if ((ini_file = getenv("MP_CONFIG_FILE")) != NULL || + (ini_file = default_file_in_path()) != NULL) { return ini_file; } @@ -360,16 +387,19 @@ static char *default_file_in_path(void) { char *config_path, **file; char *dir, *ini_file, *tokens; - if ((config_path = getenv("NAGIOS_CONFIG_PATH")) == NULL) + if ((config_path = getenv("NAGIOS_CONFIG_PATH")) == NULL) { return NULL; + } /* shall we spit out a warning that NAGIOS_CONFIG_PATH is deprecated? */ - if ((tokens = strdup(config_path)) == NULL) + if ((tokens = strdup(config_path)) == NULL) { die(STATE_UNKNOWN, "%s\n", _("Insufficient Memory")); + } for (dir = strtok(tokens, ":"); dir != NULL; dir = strtok(NULL, ":")) { for (file = default_ini_file_names; *file != NULL; file++) { - if ((asprintf(&ini_file, "%s/%s", dir, *file)) < 0) + if ((asprintf(&ini_file, "%s/%s", dir, *file)) < 0) { die(STATE_UNKNOWN, "%s\n", _("Insufficient Memory")); + } if (access(ini_file, F_OK) == 0) { free(tokens); return ini_file; diff --git a/lib/tests/test_base64.c b/lib/tests/test_base64.c index 94cb5aa9..798244da 100644 --- a/lib/tests/test_base64.c +++ b/lib/tests/test_base64.c @@ -180,117 +180,168 @@ int main(int argc, char **argv) { #endif char random[1024] = { - 0x0b, 0x30, 0x44, 0x62, 0x7c, 0x22, 0x1f, 0x0d, 0x05, 0x67, 0x2c, 0x2a, 0x39, 0x21, 0x46, 0x08, 0x50, 0x66, 0x34, 0x37, 0x0b, 0x45, - 0x4b, 0x38, 0x32, 0x06, 0x7a, 0x3e, 0x7f, 0x0c, 0x40, 0x18, 0x6b, 0x2d, 0x60, 0x4c, 0x60, 0x0c, 0x23, 0x43, 0x3b, 0x3e, 0x1b, 0x16, - 0x04, 0x46, 0x58, 0x3f, 0x40, 0x6a, 0x11, 0x05, 0x63, 0x71, 0x14, 0x35, 0x47, 0x79, 0x13, 0x6f, 0x6b, 0x27, 0x18, 0x5b, 0x48, 0x27, - 0x3e, 0x6f, 0x15, 0x33, 0x4f, 0x3e, 0x5e, 0x51, 0x73, 0x68, 0x25, 0x0f, 0x06, 0x5b, 0x7c, 0x72, 0x75, 0x3e, 0x3f, 0x1b, 0x5c, 0x6d, - 0x6a, 0x39, 0x7c, 0x63, 0x63, 0x60, 0x6c, 0x7a, 0x33, 0x76, 0x52, 0x13, 0x25, 0x33, 0x7d, 0x65, 0x23, 0x27, 0x11, 0x06, 0x06, 0x47, - 0x71, 0x1e, 0x14, 0x74, 0x63, 0x70, 0x2d, 0x15, 0x27, 0x18, 0x51, 0x06, 0x05, 0x33, 0x11, 0x2c, 0x6b, 0x00, 0x2d, 0x77, 0x20, 0x48, - 0x0d, 0x73, 0x51, 0x45, 0x25, 0x7f, 0x7f, 0x35, 0x26, 0x2e, 0x26, 0x53, 0x24, 0x68, 0x1e, 0x0e, 0x58, 0x3a, 0x59, 0x50, 0x56, 0x37, - 0x5f, 0x66, 0x01, 0x4c, 0x5a, 0x64, 0x32, 0x50, 0x7b, 0x6a, 0x20, 0x72, 0x2b, 0x1d, 0x7e, 0x43, 0x7b, 0x61, 0x42, 0x0b, 0x61, 0x73, - 0x24, 0x79, 0x3a, 0x6b, 0x4a, 0x79, 0x6e, 0x09, 0x0f, 0x27, 0x2d, 0x0c, 0x5e, 0x32, 0x4b, 0x0d, 0x79, 0x46, 0x39, 0x21, 0x0a, 0x26, - 0x5f, 0x3a, 0x00, 0x26, 0x3f, 0x13, 0x2e, 0x7e, 0x50, 0x2b, 0x67, 0x46, 0x72, 0x3f, 0x3b, 0x01, 0x46, 0x1b, 0x0b, 0x35, 0x49, 0x39, - 0x19, 0x70, 0x3d, 0x02, 0x41, 0x0e, 0x38, 0x05, 0x76, 0x65, 0x4f, 0x31, 0x6c, 0x5e, 0x17, 0x04, 0x15, 0x36, 0x26, 0x64, 0x34, 0x14, - 0x17, 0x7c, 0x0e, 0x0b, 0x5b, 0x55, 0x53, 0x6b, 0x00, 0x42, 0x41, 0x4f, 0x02, 0x5c, 0x13, 0x0a, 0x2c, 0x2c, 0x3e, 0x10, 0x14, 0x33, - 0x45, 0x7c, 0x7a, 0x5a, 0x31, 0x61, 0x39, 0x08, 0x22, 0x6a, 0x1e, 0x0f, 0x6f, 0x1b, 0x6c, 0x13, 0x5e, 0x79, 0x20, 0x79, 0x50, 0x62, - 0x06, 0x2c, 0x76, 0x17, 0x04, 0x2b, 0x2a, 0x75, 0x1f, 0x0c, 0x37, 0x4e, 0x0f, 0x7b, 0x2d, 0x34, 0x75, 0x60, 0x31, 0x74, 0x2e, 0x0a, - 0x4a, 0x11, 0x6c, 0x49, 0x25, 0x01, 0x3a, 0x3d, 0x22, 0x1e, 0x6d, 0x18, 0x51, 0x78, 0x2d, 0x62, 0x31, 0x4c, 0x50, 0x40, 0x17, 0x4b, - 0x6f, 0x22, 0x00, 0x7f, 0x61, 0x2a, 0x34, 0x3e, 0x00, 0x5f, 0x2f, 0x5f, 0x2f, 0x14, 0x2a, 0x55, 0x27, 0x1f, 0x46, 0x1f, 0x12, 0x46, - 0x5e, 0x1e, 0x0c, 0x7c, 0x38, 0x01, 0x61, 0x64, 0x76, 0x22, 0x6e, 0x08, 0x20, 0x38, 0x4f, 0x73, 0x72, 0x55, 0x12, 0x42, 0x19, 0x50, - 0x61, 0x43, 0x77, 0x7d, 0x41, 0x2e, 0x35, 0x4f, 0x3d, 0x31, 0x28, 0x58, 0x67, 0x1b, 0x03, 0x51, 0x20, 0x32, 0x1c, 0x08, 0x6e, 0x37, - 0x75, 0x37, 0x44, 0x4f, 0x68, 0x19, 0x07, 0x64, 0x14, 0x28, 0x25, 0x2b, 0x69, 0x35, 0x18, 0x27, 0x26, 0x14, 0x13, 0x70, 0x42, 0x19, - 0x12, 0x75, 0x3e, 0x02, 0x5d, 0x7c, 0x13, 0x1f, 0x16, 0x53, 0x3b, 0x74, 0x48, 0x3c, 0x5e, 0x39, 0x6c, 0x1c, 0x1c, 0x74, 0x39, 0x1f, - 0x00, 0x1b, 0x06, 0x0a, 0x68, 0x3b, 0x52, 0x4f, 0x1e, 0x6e, 0x3c, 0x35, 0x0c, 0x38, 0x0e, 0x0b, 0x3b, 0x1a, 0x76, 0x23, 0x29, 0x53, - 0x1e, 0x5f, 0x41, 0x0c, 0x4b, 0x0a, 0x65, 0x28, 0x78, 0x67, 0x48, 0x59, 0x26, 0x6d, 0x31, 0x76, 0x23, 0x70, 0x61, 0x64, 0x3b, 0x38, - 0x79, 0x66, 0x74, 0x53, 0x2c, 0x64, 0x64, 0x54, 0x03, 0x54, 0x65, 0x44, 0x4c, 0x18, 0x4f, 0x48, 0x20, 0x4f, 0x72, 0x10, 0x3f, 0x0c, - 0x52, 0x2d, 0x03, 0x14, 0x03, 0x51, 0x42, 0x10, 0x77, 0x6a, 0x34, 0x06, 0x32, 0x03, 0x72, 0x14, 0x7c, 0x08, 0x5d, 0x52, 0x1a, 0x62, - 0x7c, 0x3e, 0x30, 0x7e, 0x5f, 0x7f, 0x54, 0x0f, 0x44, 0x49, 0x5d, 0x5e, 0x10, 0x6a, 0x06, 0x2b, 0x06, 0x53, 0x10, 0x39, 0x37, 0x32, - 0x4a, 0x4e, 0x3d, 0x2b, 0x65, 0x38, 0x39, 0x07, 0x72, 0x54, 0x64, 0x4d, 0x56, 0x6a, 0x03, 0x22, 0x70, 0x7b, 0x5f, 0x60, 0x0b, 0x2a, - 0x0b, 0x6b, 0x10, 0x64, 0x14, 0x05, 0x22, 0x00, 0x73, 0x40, 0x23, 0x5b, 0x51, 0x1f, 0x2b, 0x1a, 0x5d, 0x69, 0x7a, 0x46, 0x0c, 0x5f, - 0x32, 0x4b, 0x4a, 0x28, 0x52, 0x79, 0x5b, 0x12, 0x42, 0x18, 0x00, 0x5d, 0x27, 0x31, 0x53, 0x3c, 0x4c, 0x36, 0x4e, 0x38, 0x3f, 0x72, - 0x03, 0x71, 0x02, 0x5b, 0x36, 0x59, 0x7f, 0x75, 0x6e, 0x08, 0x54, 0x0d, 0x34, 0x1c, 0x34, 0x57, 0x5d, 0x69, 0x48, 0x00, 0x3b, 0x05, - 0x07, 0x6e, 0x27, 0x65, 0x6e, 0x40, 0x3d, 0x3a, 0x4f, 0x72, 0x5d, 0x39, 0x16, 0x0f, 0x63, 0x12, 0x12, 0x15, 0x3a, 0x70, 0x0d, 0x57, - 0x18, 0x0d, 0x5e, 0x3d, 0x22, 0x68, 0x68, 0x7c, 0x6d, 0x4f, 0x0c, 0x7b, 0x09, 0x2d, 0x4a, 0x73, 0x20, 0x47, 0x07, 0x57, 0x75, 0x5d, - 0x53, 0x70, 0x34, 0x21, 0x40, 0x57, 0x51, 0x5e, 0x49, 0x44, 0x00, 0x54, 0x27, 0x04, 0x68, 0x7e, 0x59, 0x56, 0x58, 0x74, 0x14, 0x3c, - 0x16, 0x33, 0x41, 0x16, 0x4b, 0x2f, 0x49, 0x37, 0x0a, 0x54, 0x08, 0x08, 0x1f, 0x39, 0x67, 0x76, 0x28, 0x28, 0x07, 0x1d, 0x61, 0x47, - 0x51, 0x4d, 0x75, 0x26, 0x52, 0x47, 0x47, 0x0c, 0x57, 0x58, 0x74, 0x3e, 0x62, 0x6c, 0x58, 0x3a, 0x44, 0x1e, 0x16, 0x2e, 0x21, 0x1c, - 0x73, 0x45, 0x67, 0x74, 0x4f, 0x33, 0x66, 0x0e, 0x74, 0x66, 0x26, 0x1f, 0x2e, 0x38, 0x44, 0x40, 0x7e, 0x2a, 0x50, 0x52, 0x5e, 0x43, - 0x01, 0x7a, 0x38, 0x49, 0x3c, 0x55, 0x4d, 0x5a, 0x44, 0x08, 0x26, 0x59, 0x4d, 0x45, 0x0b, 0x48, 0x0a, 0x33, 0x5e, 0x4a, 0x4d, 0x75, - 0x16, 0x17, 0x63, 0x46, 0x01, 0x2a, 0x55, 0x7b, 0x0f, 0x02, 0x73, 0x6a, 0x4b, 0x7f, 0x75, 0x65, 0x3c, 0x4c, 0x33, 0x39, 0x6c, 0x74, - 0x05, 0x60, 0x0f, 0x7f, 0x2d, 0x41, 0x4d, 0x4d, 0x46, 0x71, 0x09, 0x6f, 0x4f, 0x60, 0x15, 0x0f, 0x46, 0x73, 0x63, 0x4c, 0x5e, 0x74, - 0x30, 0x0d, 0x28, 0x43, 0x08, 0x72, 0x32, 0x04, 0x2e, 0x31, 0x29, 0x27, 0x44, 0x6d, 0x13, 0x17, 0x48, 0x0f, 0x49, 0x52, 0x10, 0x13, - 0x7f, 0x17, 0x16, 0x62, 0x79, 0x35, 0x78, 0x3e, 0x01, 0x7c, 0x2e, 0x0f, 0x76, 0x3e, 0x5e, 0x53, 0x6c, 0x5b, 0x5f, 0x7c, 0x19, 0x41, - 0x02, 0x2f, 0x17, 0x64, 0x41, 0x75, 0x10, 0x04, 0x47, 0x7c, 0x3d, 0x4b, 0x52, 0x00, 0x10, 0x5d, 0x51, 0x4e, 0x7a, 0x27, 0x25, 0x55, - 0x40, 0x12, 0x35, 0x60, 0x05, 0x1b, 0x34, 0x2d, 0x04, 0x7a, 0x6a, 0x69, 0x02, 0x79, 0x03, 0x3a, 0x2f, 0x06, 0x0a, 0x79, 0x7b, 0x12, - 0x5d, 0x7c, 0x52, 0x29, 0x47, 0x58, 0x12, 0x73, 0x3f, 0x27, 0x56, 0x05, 0x0c, 0x48, 0x32, 0x58, 0x6b, 0x57, 0x5c, 0x03, 0x64, 0x56, - 0x11, 0x52, 0x7a, 0x30, 0x36, 0x29, 0x17, 0x3b, 0x68, 0x7a, 0x7c, 0x05, 0x6b, 0x6b, 0x13, 0x6a, 0x24, 0x5c, 0x68, 0x42, 0x18, 0x32, - 0x03, 0x73, 0x6e, 0x04, 0x21, 0x2e, 0x01, 0x04, 0x63, 0x7d, 0x44, 0x41, 0x12, 0x31, 0x0b, 0x15, 0x1f, 0x70, 0x00, 0x2e, 0x66, 0x14, - 0x3c, 0x7f, 0x2b, 0x00, 0x1f, 0x0c, 0x28, 0x59, 0x0a, 0x16, 0x49, 0x5a, 0x5c, 0x64, 0x65, 0x4b, 0x11, 0x29, 0x15, 0x36, 0x5a, 0x65, - 0x19, 0x4f, 0x60, 0x23, 0x3a, 0x3a, 0x13, 0x25, 0x02, 0x78, 0x4c, 0x54}; + 0x0b, 0x30, 0x44, 0x62, 0x7c, 0x22, 0x1f, 0x0d, 0x05, 0x67, 0x2c, 0x2a, 0x39, 0x21, 0x46, + 0x08, 0x50, 0x66, 0x34, 0x37, 0x0b, 0x45, 0x4b, 0x38, 0x32, 0x06, 0x7a, 0x3e, 0x7f, 0x0c, + 0x40, 0x18, 0x6b, 0x2d, 0x60, 0x4c, 0x60, 0x0c, 0x23, 0x43, 0x3b, 0x3e, 0x1b, 0x16, 0x04, + 0x46, 0x58, 0x3f, 0x40, 0x6a, 0x11, 0x05, 0x63, 0x71, 0x14, 0x35, 0x47, 0x79, 0x13, 0x6f, + 0x6b, 0x27, 0x18, 0x5b, 0x48, 0x27, 0x3e, 0x6f, 0x15, 0x33, 0x4f, 0x3e, 0x5e, 0x51, 0x73, + 0x68, 0x25, 0x0f, 0x06, 0x5b, 0x7c, 0x72, 0x75, 0x3e, 0x3f, 0x1b, 0x5c, 0x6d, 0x6a, 0x39, + 0x7c, 0x63, 0x63, 0x60, 0x6c, 0x7a, 0x33, 0x76, 0x52, 0x13, 0x25, 0x33, 0x7d, 0x65, 0x23, + 0x27, 0x11, 0x06, 0x06, 0x47, 0x71, 0x1e, 0x14, 0x74, 0x63, 0x70, 0x2d, 0x15, 0x27, 0x18, + 0x51, 0x06, 0x05, 0x33, 0x11, 0x2c, 0x6b, 0x00, 0x2d, 0x77, 0x20, 0x48, 0x0d, 0x73, 0x51, + 0x45, 0x25, 0x7f, 0x7f, 0x35, 0x26, 0x2e, 0x26, 0x53, 0x24, 0x68, 0x1e, 0x0e, 0x58, 0x3a, + 0x59, 0x50, 0x56, 0x37, 0x5f, 0x66, 0x01, 0x4c, 0x5a, 0x64, 0x32, 0x50, 0x7b, 0x6a, 0x20, + 0x72, 0x2b, 0x1d, 0x7e, 0x43, 0x7b, 0x61, 0x42, 0x0b, 0x61, 0x73, 0x24, 0x79, 0x3a, 0x6b, + 0x4a, 0x79, 0x6e, 0x09, 0x0f, 0x27, 0x2d, 0x0c, 0x5e, 0x32, 0x4b, 0x0d, 0x79, 0x46, 0x39, + 0x21, 0x0a, 0x26, 0x5f, 0x3a, 0x00, 0x26, 0x3f, 0x13, 0x2e, 0x7e, 0x50, 0x2b, 0x67, 0x46, + 0x72, 0x3f, 0x3b, 0x01, 0x46, 0x1b, 0x0b, 0x35, 0x49, 0x39, 0x19, 0x70, 0x3d, 0x02, 0x41, + 0x0e, 0x38, 0x05, 0x76, 0x65, 0x4f, 0x31, 0x6c, 0x5e, 0x17, 0x04, 0x15, 0x36, 0x26, 0x64, + 0x34, 0x14, 0x17, 0x7c, 0x0e, 0x0b, 0x5b, 0x55, 0x53, 0x6b, 0x00, 0x42, 0x41, 0x4f, 0x02, + 0x5c, 0x13, 0x0a, 0x2c, 0x2c, 0x3e, 0x10, 0x14, 0x33, 0x45, 0x7c, 0x7a, 0x5a, 0x31, 0x61, + 0x39, 0x08, 0x22, 0x6a, 0x1e, 0x0f, 0x6f, 0x1b, 0x6c, 0x13, 0x5e, 0x79, 0x20, 0x79, 0x50, + 0x62, 0x06, 0x2c, 0x76, 0x17, 0x04, 0x2b, 0x2a, 0x75, 0x1f, 0x0c, 0x37, 0x4e, 0x0f, 0x7b, + 0x2d, 0x34, 0x75, 0x60, 0x31, 0x74, 0x2e, 0x0a, 0x4a, 0x11, 0x6c, 0x49, 0x25, 0x01, 0x3a, + 0x3d, 0x22, 0x1e, 0x6d, 0x18, 0x51, 0x78, 0x2d, 0x62, 0x31, 0x4c, 0x50, 0x40, 0x17, 0x4b, + 0x6f, 0x22, 0x00, 0x7f, 0x61, 0x2a, 0x34, 0x3e, 0x00, 0x5f, 0x2f, 0x5f, 0x2f, 0x14, 0x2a, + 0x55, 0x27, 0x1f, 0x46, 0x1f, 0x12, 0x46, 0x5e, 0x1e, 0x0c, 0x7c, 0x38, 0x01, 0x61, 0x64, + 0x76, 0x22, 0x6e, 0x08, 0x20, 0x38, 0x4f, 0x73, 0x72, 0x55, 0x12, 0x42, 0x19, 0x50, 0x61, + 0x43, 0x77, 0x7d, 0x41, 0x2e, 0x35, 0x4f, 0x3d, 0x31, 0x28, 0x58, 0x67, 0x1b, 0x03, 0x51, + 0x20, 0x32, 0x1c, 0x08, 0x6e, 0x37, 0x75, 0x37, 0x44, 0x4f, 0x68, 0x19, 0x07, 0x64, 0x14, + 0x28, 0x25, 0x2b, 0x69, 0x35, 0x18, 0x27, 0x26, 0x14, 0x13, 0x70, 0x42, 0x19, 0x12, 0x75, + 0x3e, 0x02, 0x5d, 0x7c, 0x13, 0x1f, 0x16, 0x53, 0x3b, 0x74, 0x48, 0x3c, 0x5e, 0x39, 0x6c, + 0x1c, 0x1c, 0x74, 0x39, 0x1f, 0x00, 0x1b, 0x06, 0x0a, 0x68, 0x3b, 0x52, 0x4f, 0x1e, 0x6e, + 0x3c, 0x35, 0x0c, 0x38, 0x0e, 0x0b, 0x3b, 0x1a, 0x76, 0x23, 0x29, 0x53, 0x1e, 0x5f, 0x41, + 0x0c, 0x4b, 0x0a, 0x65, 0x28, 0x78, 0x67, 0x48, 0x59, 0x26, 0x6d, 0x31, 0x76, 0x23, 0x70, + 0x61, 0x64, 0x3b, 0x38, 0x79, 0x66, 0x74, 0x53, 0x2c, 0x64, 0x64, 0x54, 0x03, 0x54, 0x65, + 0x44, 0x4c, 0x18, 0x4f, 0x48, 0x20, 0x4f, 0x72, 0x10, 0x3f, 0x0c, 0x52, 0x2d, 0x03, 0x14, + 0x03, 0x51, 0x42, 0x10, 0x77, 0x6a, 0x34, 0x06, 0x32, 0x03, 0x72, 0x14, 0x7c, 0x08, 0x5d, + 0x52, 0x1a, 0x62, 0x7c, 0x3e, 0x30, 0x7e, 0x5f, 0x7f, 0x54, 0x0f, 0x44, 0x49, 0x5d, 0x5e, + 0x10, 0x6a, 0x06, 0x2b, 0x06, 0x53, 0x10, 0x39, 0x37, 0x32, 0x4a, 0x4e, 0x3d, 0x2b, 0x65, + 0x38, 0x39, 0x07, 0x72, 0x54, 0x64, 0x4d, 0x56, 0x6a, 0x03, 0x22, 0x70, 0x7b, 0x5f, 0x60, + 0x0b, 0x2a, 0x0b, 0x6b, 0x10, 0x64, 0x14, 0x05, 0x22, 0x00, 0x73, 0x40, 0x23, 0x5b, 0x51, + 0x1f, 0x2b, 0x1a, 0x5d, 0x69, 0x7a, 0x46, 0x0c, 0x5f, 0x32, 0x4b, 0x4a, 0x28, 0x52, 0x79, + 0x5b, 0x12, 0x42, 0x18, 0x00, 0x5d, 0x27, 0x31, 0x53, 0x3c, 0x4c, 0x36, 0x4e, 0x38, 0x3f, + 0x72, 0x03, 0x71, 0x02, 0x5b, 0x36, 0x59, 0x7f, 0x75, 0x6e, 0x08, 0x54, 0x0d, 0x34, 0x1c, + 0x34, 0x57, 0x5d, 0x69, 0x48, 0x00, 0x3b, 0x05, 0x07, 0x6e, 0x27, 0x65, 0x6e, 0x40, 0x3d, + 0x3a, 0x4f, 0x72, 0x5d, 0x39, 0x16, 0x0f, 0x63, 0x12, 0x12, 0x15, 0x3a, 0x70, 0x0d, 0x57, + 0x18, 0x0d, 0x5e, 0x3d, 0x22, 0x68, 0x68, 0x7c, 0x6d, 0x4f, 0x0c, 0x7b, 0x09, 0x2d, 0x4a, + 0x73, 0x20, 0x47, 0x07, 0x57, 0x75, 0x5d, 0x53, 0x70, 0x34, 0x21, 0x40, 0x57, 0x51, 0x5e, + 0x49, 0x44, 0x00, 0x54, 0x27, 0x04, 0x68, 0x7e, 0x59, 0x56, 0x58, 0x74, 0x14, 0x3c, 0x16, + 0x33, 0x41, 0x16, 0x4b, 0x2f, 0x49, 0x37, 0x0a, 0x54, 0x08, 0x08, 0x1f, 0x39, 0x67, 0x76, + 0x28, 0x28, 0x07, 0x1d, 0x61, 0x47, 0x51, 0x4d, 0x75, 0x26, 0x52, 0x47, 0x47, 0x0c, 0x57, + 0x58, 0x74, 0x3e, 0x62, 0x6c, 0x58, 0x3a, 0x44, 0x1e, 0x16, 0x2e, 0x21, 0x1c, 0x73, 0x45, + 0x67, 0x74, 0x4f, 0x33, 0x66, 0x0e, 0x74, 0x66, 0x26, 0x1f, 0x2e, 0x38, 0x44, 0x40, 0x7e, + 0x2a, 0x50, 0x52, 0x5e, 0x43, 0x01, 0x7a, 0x38, 0x49, 0x3c, 0x55, 0x4d, 0x5a, 0x44, 0x08, + 0x26, 0x59, 0x4d, 0x45, 0x0b, 0x48, 0x0a, 0x33, 0x5e, 0x4a, 0x4d, 0x75, 0x16, 0x17, 0x63, + 0x46, 0x01, 0x2a, 0x55, 0x7b, 0x0f, 0x02, 0x73, 0x6a, 0x4b, 0x7f, 0x75, 0x65, 0x3c, 0x4c, + 0x33, 0x39, 0x6c, 0x74, 0x05, 0x60, 0x0f, 0x7f, 0x2d, 0x41, 0x4d, 0x4d, 0x46, 0x71, 0x09, + 0x6f, 0x4f, 0x60, 0x15, 0x0f, 0x46, 0x73, 0x63, 0x4c, 0x5e, 0x74, 0x30, 0x0d, 0x28, 0x43, + 0x08, 0x72, 0x32, 0x04, 0x2e, 0x31, 0x29, 0x27, 0x44, 0x6d, 0x13, 0x17, 0x48, 0x0f, 0x49, + 0x52, 0x10, 0x13, 0x7f, 0x17, 0x16, 0x62, 0x79, 0x35, 0x78, 0x3e, 0x01, 0x7c, 0x2e, 0x0f, + 0x76, 0x3e, 0x5e, 0x53, 0x6c, 0x5b, 0x5f, 0x7c, 0x19, 0x41, 0x02, 0x2f, 0x17, 0x64, 0x41, + 0x75, 0x10, 0x04, 0x47, 0x7c, 0x3d, 0x4b, 0x52, 0x00, 0x10, 0x5d, 0x51, 0x4e, 0x7a, 0x27, + 0x25, 0x55, 0x40, 0x12, 0x35, 0x60, 0x05, 0x1b, 0x34, 0x2d, 0x04, 0x7a, 0x6a, 0x69, 0x02, + 0x79, 0x03, 0x3a, 0x2f, 0x06, 0x0a, 0x79, 0x7b, 0x12, 0x5d, 0x7c, 0x52, 0x29, 0x47, 0x58, + 0x12, 0x73, 0x3f, 0x27, 0x56, 0x05, 0x0c, 0x48, 0x32, 0x58, 0x6b, 0x57, 0x5c, 0x03, 0x64, + 0x56, 0x11, 0x52, 0x7a, 0x30, 0x36, 0x29, 0x17, 0x3b, 0x68, 0x7a, 0x7c, 0x05, 0x6b, 0x6b, + 0x13, 0x6a, 0x24, 0x5c, 0x68, 0x42, 0x18, 0x32, 0x03, 0x73, 0x6e, 0x04, 0x21, 0x2e, 0x01, + 0x04, 0x63, 0x7d, 0x44, 0x41, 0x12, 0x31, 0x0b, 0x15, 0x1f, 0x70, 0x00, 0x2e, 0x66, 0x14, + 0x3c, 0x7f, 0x2b, 0x00, 0x1f, 0x0c, 0x28, 0x59, 0x0a, 0x16, 0x49, 0x5a, 0x5c, 0x64, 0x65, + 0x4b, 0x11, 0x29, 0x15, 0x36, 0x5a, 0x65, 0x19, 0x4f, 0x60, 0x23, 0x3a, 0x3a, 0x13, 0x25, + 0x02, 0x78, 0x4c, 0x54}; char b64_known[1369] = { - 0x43, 0x7a, 0x42, 0x45, 0x59, 0x6e, 0x77, 0x69, 0x48, 0x77, 0x30, 0x46, 0x5a, 0x79, 0x77, 0x71, 0x4f, 0x53, 0x46, 0x47, 0x43, 0x46, - 0x42, 0x6d, 0x4e, 0x44, 0x63, 0x4c, 0x52, 0x55, 0x73, 0x34, 0x4d, 0x67, 0x5a, 0x36, 0x50, 0x6e, 0x38, 0x4d, 0x51, 0x42, 0x68, 0x72, - 0x4c, 0x57, 0x42, 0x4d, 0x59, 0x41, 0x77, 0x6a, 0x51, 0x7a, 0x73, 0x2b, 0x47, 0x78, 0x59, 0x45, 0x52, 0x6c, 0x67, 0x2f, 0x51, 0x47, - 0x6f, 0x52, 0x42, 0x57, 0x4e, 0x78, 0x46, 0x44, 0x56, 0x48, 0x65, 0x52, 0x4e, 0x76, 0x61, 0x79, 0x63, 0x59, 0x57, 0x30, 0x67, 0x6e, - 0x50, 0x6d, 0x38, 0x56, 0x4d, 0x30, 0x38, 0x2b, 0x58, 0x6c, 0x46, 0x7a, 0x61, 0x43, 0x55, 0x50, 0x42, 0x6c, 0x74, 0x38, 0x63, 0x6e, - 0x55, 0x2b, 0x50, 0x78, 0x74, 0x63, 0x62, 0x57, 0x6f, 0x35, 0x66, 0x47, 0x4e, 0x6a, 0x59, 0x47, 0x78, 0x36, 0x4d, 0x33, 0x5a, 0x53, - 0x45, 0x79, 0x55, 0x7a, 0x66, 0x57, 0x55, 0x6a, 0x4a, 0x78, 0x45, 0x47, 0x42, 0x6b, 0x64, 0x78, 0x48, 0x68, 0x52, 0x30, 0x59, 0x33, - 0x41, 0x74, 0x46, 0x53, 0x63, 0x59, 0x55, 0x51, 0x59, 0x46, 0x4d, 0x78, 0x45, 0x73, 0x61, 0x77, 0x41, 0x74, 0x64, 0x79, 0x42, 0x49, - 0x44, 0x58, 0x4e, 0x52, 0x52, 0x53, 0x56, 0x2f, 0x66, 0x7a, 0x55, 0x6d, 0x4c, 0x69, 0x5a, 0x54, 0x4a, 0x47, 0x67, 0x65, 0x44, 0x6c, - 0x67, 0x36, 0x57, 0x56, 0x42, 0x57, 0x4e, 0x31, 0x39, 0x6d, 0x41, 0x55, 0x78, 0x61, 0x5a, 0x44, 0x4a, 0x51, 0x65, 0x32, 0x6f, 0x67, - 0x63, 0x69, 0x73, 0x64, 0x66, 0x6b, 0x4e, 0x37, 0x59, 0x55, 0x49, 0x4c, 0x59, 0x58, 0x4d, 0x6b, 0x65, 0x54, 0x70, 0x72, 0x53, 0x6e, - 0x6c, 0x75, 0x43, 0x51, 0x38, 0x6e, 0x4c, 0x51, 0x78, 0x65, 0x4d, 0x6b, 0x73, 0x4e, 0x65, 0x55, 0x59, 0x35, 0x49, 0x51, 0x6f, 0x6d, - 0x58, 0x7a, 0x6f, 0x41, 0x4a, 0x6a, 0x38, 0x54, 0x4c, 0x6e, 0x35, 0x51, 0x4b, 0x32, 0x64, 0x47, 0x63, 0x6a, 0x38, 0x37, 0x41, 0x55, - 0x59, 0x62, 0x43, 0x7a, 0x56, 0x4a, 0x4f, 0x52, 0x6c, 0x77, 0x50, 0x51, 0x4a, 0x42, 0x44, 0x6a, 0x67, 0x46, 0x64, 0x6d, 0x56, 0x50, - 0x4d, 0x57, 0x78, 0x65, 0x46, 0x77, 0x51, 0x56, 0x4e, 0x69, 0x5a, 0x6b, 0x4e, 0x42, 0x51, 0x58, 0x66, 0x41, 0x34, 0x4c, 0x57, 0x31, - 0x56, 0x54, 0x61, 0x77, 0x42, 0x43, 0x51, 0x55, 0x38, 0x43, 0x58, 0x42, 0x4d, 0x4b, 0x4c, 0x43, 0x77, 0x2b, 0x45, 0x42, 0x51, 0x7a, - 0x52, 0x58, 0x78, 0x36, 0x57, 0x6a, 0x46, 0x68, 0x4f, 0x51, 0x67, 0x69, 0x61, 0x68, 0x34, 0x50, 0x62, 0x78, 0x74, 0x73, 0x45, 0x31, - 0x35, 0x35, 0x49, 0x48, 0x6c, 0x51, 0x59, 0x67, 0x59, 0x73, 0x64, 0x68, 0x63, 0x45, 0x4b, 0x79, 0x70, 0x31, 0x48, 0x77, 0x77, 0x33, - 0x54, 0x67, 0x39, 0x37, 0x4c, 0x54, 0x52, 0x31, 0x59, 0x44, 0x46, 0x30, 0x4c, 0x67, 0x70, 0x4b, 0x45, 0x57, 0x78, 0x4a, 0x4a, 0x51, - 0x45, 0x36, 0x50, 0x53, 0x49, 0x65, 0x62, 0x52, 0x68, 0x52, 0x65, 0x43, 0x31, 0x69, 0x4d, 0x55, 0x78, 0x51, 0x51, 0x42, 0x64, 0x4c, - 0x62, 0x79, 0x49, 0x41, 0x66, 0x32, 0x45, 0x71, 0x4e, 0x44, 0x34, 0x41, 0x58, 0x79, 0x39, 0x66, 0x4c, 0x78, 0x51, 0x71, 0x56, 0x53, - 0x63, 0x66, 0x52, 0x68, 0x38, 0x53, 0x52, 0x6c, 0x34, 0x65, 0x44, 0x48, 0x77, 0x34, 0x41, 0x57, 0x46, 0x6b, 0x64, 0x69, 0x4a, 0x75, - 0x43, 0x43, 0x41, 0x34, 0x54, 0x33, 0x4e, 0x79, 0x56, 0x52, 0x4a, 0x43, 0x47, 0x56, 0x42, 0x68, 0x51, 0x33, 0x64, 0x39, 0x51, 0x53, - 0x34, 0x31, 0x54, 0x7a, 0x30, 0x78, 0x4b, 0x46, 0x68, 0x6e, 0x47, 0x77, 0x4e, 0x52, 0x49, 0x44, 0x49, 0x63, 0x43, 0x47, 0x34, 0x33, - 0x64, 0x54, 0x64, 0x45, 0x54, 0x32, 0x67, 0x5a, 0x42, 0x32, 0x51, 0x55, 0x4b, 0x43, 0x55, 0x72, 0x61, 0x54, 0x55, 0x59, 0x4a, 0x79, - 0x59, 0x55, 0x45, 0x33, 0x42, 0x43, 0x47, 0x52, 0x4a, 0x31, 0x50, 0x67, 0x4a, 0x64, 0x66, 0x42, 0x4d, 0x66, 0x46, 0x6c, 0x4d, 0x37, - 0x64, 0x45, 0x67, 0x38, 0x58, 0x6a, 0x6c, 0x73, 0x48, 0x42, 0x78, 0x30, 0x4f, 0x52, 0x38, 0x41, 0x47, 0x77, 0x59, 0x4b, 0x61, 0x44, - 0x74, 0x53, 0x54, 0x78, 0x35, 0x75, 0x50, 0x44, 0x55, 0x4d, 0x4f, 0x41, 0x34, 0x4c, 0x4f, 0x78, 0x70, 0x32, 0x49, 0x79, 0x6c, 0x54, - 0x48, 0x6c, 0x39, 0x42, 0x44, 0x45, 0x73, 0x4b, 0x5a, 0x53, 0x68, 0x34, 0x5a, 0x30, 0x68, 0x5a, 0x4a, 0x6d, 0x30, 0x78, 0x64, 0x69, - 0x4e, 0x77, 0x59, 0x57, 0x51, 0x37, 0x4f, 0x48, 0x6c, 0x6d, 0x64, 0x46, 0x4d, 0x73, 0x5a, 0x47, 0x52, 0x55, 0x41, 0x31, 0x52, 0x6c, - 0x52, 0x45, 0x77, 0x59, 0x54, 0x30, 0x67, 0x67, 0x54, 0x33, 0x49, 0x51, 0x50, 0x77, 0x78, 0x53, 0x4c, 0x51, 0x4d, 0x55, 0x41, 0x31, - 0x46, 0x43, 0x45, 0x48, 0x64, 0x71, 0x4e, 0x41, 0x59, 0x79, 0x41, 0x33, 0x49, 0x55, 0x66, 0x41, 0x68, 0x64, 0x55, 0x68, 0x70, 0x69, - 0x66, 0x44, 0x34, 0x77, 0x66, 0x6c, 0x39, 0x2f, 0x56, 0x41, 0x39, 0x45, 0x53, 0x56, 0x31, 0x65, 0x45, 0x47, 0x6f, 0x47, 0x4b, 0x77, - 0x5a, 0x54, 0x45, 0x44, 0x6b, 0x33, 0x4d, 0x6b, 0x70, 0x4f, 0x50, 0x53, 0x74, 0x6c, 0x4f, 0x44, 0x6b, 0x48, 0x63, 0x6c, 0x52, 0x6b, - 0x54, 0x56, 0x5a, 0x71, 0x41, 0x79, 0x4a, 0x77, 0x65, 0x31, 0x39, 0x67, 0x43, 0x79, 0x6f, 0x4c, 0x61, 0x78, 0x42, 0x6b, 0x46, 0x41, - 0x55, 0x69, 0x41, 0x48, 0x4e, 0x41, 0x49, 0x31, 0x74, 0x52, 0x48, 0x79, 0x73, 0x61, 0x58, 0x57, 0x6c, 0x36, 0x52, 0x67, 0x78, 0x66, - 0x4d, 0x6b, 0x74, 0x4b, 0x4b, 0x46, 0x4a, 0x35, 0x57, 0x78, 0x4a, 0x43, 0x47, 0x41, 0x42, 0x64, 0x4a, 0x7a, 0x46, 0x54, 0x50, 0x45, - 0x77, 0x32, 0x54, 0x6a, 0x67, 0x2f, 0x63, 0x67, 0x4e, 0x78, 0x41, 0x6c, 0x73, 0x32, 0x57, 0x58, 0x39, 0x31, 0x62, 0x67, 0x68, 0x55, - 0x44, 0x54, 0x51, 0x63, 0x4e, 0x46, 0x64, 0x64, 0x61, 0x55, 0x67, 0x41, 0x4f, 0x77, 0x55, 0x48, 0x62, 0x69, 0x64, 0x6c, 0x62, 0x6b, - 0x41, 0x39, 0x4f, 0x6b, 0x39, 0x79, 0x58, 0x54, 0x6b, 0x57, 0x44, 0x32, 0x4d, 0x53, 0x45, 0x68, 0x55, 0x36, 0x63, 0x41, 0x31, 0x58, - 0x47, 0x41, 0x31, 0x65, 0x50, 0x53, 0x4a, 0x6f, 0x61, 0x48, 0x78, 0x74, 0x54, 0x77, 0x78, 0x37, 0x43, 0x53, 0x31, 0x4b, 0x63, 0x79, - 0x42, 0x48, 0x42, 0x31, 0x64, 0x31, 0x58, 0x56, 0x4e, 0x77, 0x4e, 0x43, 0x46, 0x41, 0x56, 0x31, 0x46, 0x65, 0x53, 0x55, 0x51, 0x41, - 0x56, 0x43, 0x63, 0x45, 0x61, 0x48, 0x35, 0x5a, 0x56, 0x6c, 0x68, 0x30, 0x46, 0x44, 0x77, 0x57, 0x4d, 0x30, 0x45, 0x57, 0x53, 0x79, - 0x39, 0x4a, 0x4e, 0x77, 0x70, 0x55, 0x43, 0x41, 0x67, 0x66, 0x4f, 0x57, 0x64, 0x32, 0x4b, 0x43, 0x67, 0x48, 0x48, 0x57, 0x46, 0x48, - 0x55, 0x55, 0x31, 0x31, 0x4a, 0x6c, 0x4a, 0x48, 0x52, 0x77, 0x78, 0x58, 0x57, 0x48, 0x51, 0x2b, 0x59, 0x6d, 0x78, 0x59, 0x4f, 0x6b, - 0x51, 0x65, 0x46, 0x69, 0x34, 0x68, 0x48, 0x48, 0x4e, 0x46, 0x5a, 0x33, 0x52, 0x50, 0x4d, 0x32, 0x59, 0x4f, 0x64, 0x47, 0x59, 0x6d, - 0x48, 0x79, 0x34, 0x34, 0x52, 0x45, 0x42, 0x2b, 0x4b, 0x6c, 0x42, 0x53, 0x58, 0x6b, 0x4d, 0x42, 0x65, 0x6a, 0x68, 0x4a, 0x50, 0x46, - 0x56, 0x4e, 0x57, 0x6b, 0x51, 0x49, 0x4a, 0x6c, 0x6c, 0x4e, 0x52, 0x51, 0x74, 0x49, 0x43, 0x6a, 0x4e, 0x65, 0x53, 0x6b, 0x31, 0x31, - 0x46, 0x68, 0x64, 0x6a, 0x52, 0x67, 0x45, 0x71, 0x56, 0x58, 0x73, 0x50, 0x41, 0x6e, 0x4e, 0x71, 0x53, 0x33, 0x39, 0x31, 0x5a, 0x54, - 0x78, 0x4d, 0x4d, 0x7a, 0x6c, 0x73, 0x64, 0x41, 0x56, 0x67, 0x44, 0x33, 0x38, 0x74, 0x51, 0x55, 0x31, 0x4e, 0x52, 0x6e, 0x45, 0x4a, - 0x62, 0x30, 0x39, 0x67, 0x46, 0x51, 0x39, 0x47, 0x63, 0x32, 0x4e, 0x4d, 0x58, 0x6e, 0x51, 0x77, 0x44, 0x53, 0x68, 0x44, 0x43, 0x48, - 0x49, 0x79, 0x42, 0x43, 0x34, 0x78, 0x4b, 0x53, 0x64, 0x45, 0x62, 0x52, 0x4d, 0x58, 0x53, 0x41, 0x39, 0x4a, 0x55, 0x68, 0x41, 0x54, - 0x66, 0x78, 0x63, 0x57, 0x59, 0x6e, 0x6b, 0x31, 0x65, 0x44, 0x34, 0x42, 0x66, 0x43, 0x34, 0x50, 0x64, 0x6a, 0x35, 0x65, 0x55, 0x32, - 0x78, 0x62, 0x58, 0x33, 0x77, 0x5a, 0x51, 0x51, 0x49, 0x76, 0x46, 0x32, 0x52, 0x42, 0x64, 0x52, 0x41, 0x45, 0x52, 0x33, 0x77, 0x39, - 0x53, 0x31, 0x49, 0x41, 0x45, 0x46, 0x31, 0x52, 0x54, 0x6e, 0x6f, 0x6e, 0x4a, 0x56, 0x56, 0x41, 0x45, 0x6a, 0x56, 0x67, 0x42, 0x52, - 0x73, 0x30, 0x4c, 0x51, 0x52, 0x36, 0x61, 0x6d, 0x6b, 0x43, 0x65, 0x51, 0x4d, 0x36, 0x4c, 0x77, 0x59, 0x4b, 0x65, 0x58, 0x73, 0x53, - 0x58, 0x58, 0x78, 0x53, 0x4b, 0x55, 0x64, 0x59, 0x45, 0x6e, 0x4d, 0x2f, 0x4a, 0x31, 0x59, 0x46, 0x44, 0x45, 0x67, 0x79, 0x57, 0x47, - 0x74, 0x58, 0x58, 0x41, 0x4e, 0x6b, 0x56, 0x68, 0x46, 0x53, 0x65, 0x6a, 0x41, 0x32, 0x4b, 0x52, 0x63, 0x37, 0x61, 0x48, 0x70, 0x38, - 0x42, 0x57, 0x74, 0x72, 0x45, 0x32, 0x6f, 0x6b, 0x58, 0x47, 0x68, 0x43, 0x47, 0x44, 0x49, 0x44, 0x63, 0x32, 0x34, 0x45, 0x49, 0x53, - 0x34, 0x42, 0x42, 0x47, 0x4e, 0x39, 0x52, 0x45, 0x45, 0x53, 0x4d, 0x51, 0x73, 0x56, 0x48, 0x33, 0x41, 0x41, 0x4c, 0x6d, 0x59, 0x55, - 0x50, 0x48, 0x38, 0x72, 0x41, 0x42, 0x38, 0x4d, 0x4b, 0x46, 0x6b, 0x4b, 0x46, 0x6b, 0x6c, 0x61, 0x58, 0x47, 0x52, 0x6c, 0x53, 0x78, - 0x45, 0x70, 0x46, 0x54, 0x5a, 0x61, 0x5a, 0x52, 0x6c, 0x50, 0x59, 0x43, 0x4d, 0x36, 0x4f, 0x68, 0x4d, 0x6c, 0x41, 0x6e, 0x68, 0x4d, - 0x56, 0x41, 0x3d, 0x3d, 0x00}; + 0x43, 0x7a, 0x42, 0x45, 0x59, 0x6e, 0x77, 0x69, 0x48, 0x77, 0x30, 0x46, 0x5a, 0x79, 0x77, + 0x71, 0x4f, 0x53, 0x46, 0x47, 0x43, 0x46, 0x42, 0x6d, 0x4e, 0x44, 0x63, 0x4c, 0x52, 0x55, + 0x73, 0x34, 0x4d, 0x67, 0x5a, 0x36, 0x50, 0x6e, 0x38, 0x4d, 0x51, 0x42, 0x68, 0x72, 0x4c, + 0x57, 0x42, 0x4d, 0x59, 0x41, 0x77, 0x6a, 0x51, 0x7a, 0x73, 0x2b, 0x47, 0x78, 0x59, 0x45, + 0x52, 0x6c, 0x67, 0x2f, 0x51, 0x47, 0x6f, 0x52, 0x42, 0x57, 0x4e, 0x78, 0x46, 0x44, 0x56, + 0x48, 0x65, 0x52, 0x4e, 0x76, 0x61, 0x79, 0x63, 0x59, 0x57, 0x30, 0x67, 0x6e, 0x50, 0x6d, + 0x38, 0x56, 0x4d, 0x30, 0x38, 0x2b, 0x58, 0x6c, 0x46, 0x7a, 0x61, 0x43, 0x55, 0x50, 0x42, + 0x6c, 0x74, 0x38, 0x63, 0x6e, 0x55, 0x2b, 0x50, 0x78, 0x74, 0x63, 0x62, 0x57, 0x6f, 0x35, + 0x66, 0x47, 0x4e, 0x6a, 0x59, 0x47, 0x78, 0x36, 0x4d, 0x33, 0x5a, 0x53, 0x45, 0x79, 0x55, + 0x7a, 0x66, 0x57, 0x55, 0x6a, 0x4a, 0x78, 0x45, 0x47, 0x42, 0x6b, 0x64, 0x78, 0x48, 0x68, + 0x52, 0x30, 0x59, 0x33, 0x41, 0x74, 0x46, 0x53, 0x63, 0x59, 0x55, 0x51, 0x59, 0x46, 0x4d, + 0x78, 0x45, 0x73, 0x61, 0x77, 0x41, 0x74, 0x64, 0x79, 0x42, 0x49, 0x44, 0x58, 0x4e, 0x52, + 0x52, 0x53, 0x56, 0x2f, 0x66, 0x7a, 0x55, 0x6d, 0x4c, 0x69, 0x5a, 0x54, 0x4a, 0x47, 0x67, + 0x65, 0x44, 0x6c, 0x67, 0x36, 0x57, 0x56, 0x42, 0x57, 0x4e, 0x31, 0x39, 0x6d, 0x41, 0x55, + 0x78, 0x61, 0x5a, 0x44, 0x4a, 0x51, 0x65, 0x32, 0x6f, 0x67, 0x63, 0x69, 0x73, 0x64, 0x66, + 0x6b, 0x4e, 0x37, 0x59, 0x55, 0x49, 0x4c, 0x59, 0x58, 0x4d, 0x6b, 0x65, 0x54, 0x70, 0x72, + 0x53, 0x6e, 0x6c, 0x75, 0x43, 0x51, 0x38, 0x6e, 0x4c, 0x51, 0x78, 0x65, 0x4d, 0x6b, 0x73, + 0x4e, 0x65, 0x55, 0x59, 0x35, 0x49, 0x51, 0x6f, 0x6d, 0x58, 0x7a, 0x6f, 0x41, 0x4a, 0x6a, + 0x38, 0x54, 0x4c, 0x6e, 0x35, 0x51, 0x4b, 0x32, 0x64, 0x47, 0x63, 0x6a, 0x38, 0x37, 0x41, + 0x55, 0x59, 0x62, 0x43, 0x7a, 0x56, 0x4a, 0x4f, 0x52, 0x6c, 0x77, 0x50, 0x51, 0x4a, 0x42, + 0x44, 0x6a, 0x67, 0x46, 0x64, 0x6d, 0x56, 0x50, 0x4d, 0x57, 0x78, 0x65, 0x46, 0x77, 0x51, + 0x56, 0x4e, 0x69, 0x5a, 0x6b, 0x4e, 0x42, 0x51, 0x58, 0x66, 0x41, 0x34, 0x4c, 0x57, 0x31, + 0x56, 0x54, 0x61, 0x77, 0x42, 0x43, 0x51, 0x55, 0x38, 0x43, 0x58, 0x42, 0x4d, 0x4b, 0x4c, + 0x43, 0x77, 0x2b, 0x45, 0x42, 0x51, 0x7a, 0x52, 0x58, 0x78, 0x36, 0x57, 0x6a, 0x46, 0x68, + 0x4f, 0x51, 0x67, 0x69, 0x61, 0x68, 0x34, 0x50, 0x62, 0x78, 0x74, 0x73, 0x45, 0x31, 0x35, + 0x35, 0x49, 0x48, 0x6c, 0x51, 0x59, 0x67, 0x59, 0x73, 0x64, 0x68, 0x63, 0x45, 0x4b, 0x79, + 0x70, 0x31, 0x48, 0x77, 0x77, 0x33, 0x54, 0x67, 0x39, 0x37, 0x4c, 0x54, 0x52, 0x31, 0x59, + 0x44, 0x46, 0x30, 0x4c, 0x67, 0x70, 0x4b, 0x45, 0x57, 0x78, 0x4a, 0x4a, 0x51, 0x45, 0x36, + 0x50, 0x53, 0x49, 0x65, 0x62, 0x52, 0x68, 0x52, 0x65, 0x43, 0x31, 0x69, 0x4d, 0x55, 0x78, + 0x51, 0x51, 0x42, 0x64, 0x4c, 0x62, 0x79, 0x49, 0x41, 0x66, 0x32, 0x45, 0x71, 0x4e, 0x44, + 0x34, 0x41, 0x58, 0x79, 0x39, 0x66, 0x4c, 0x78, 0x51, 0x71, 0x56, 0x53, 0x63, 0x66, 0x52, + 0x68, 0x38, 0x53, 0x52, 0x6c, 0x34, 0x65, 0x44, 0x48, 0x77, 0x34, 0x41, 0x57, 0x46, 0x6b, + 0x64, 0x69, 0x4a, 0x75, 0x43, 0x43, 0x41, 0x34, 0x54, 0x33, 0x4e, 0x79, 0x56, 0x52, 0x4a, + 0x43, 0x47, 0x56, 0x42, 0x68, 0x51, 0x33, 0x64, 0x39, 0x51, 0x53, 0x34, 0x31, 0x54, 0x7a, + 0x30, 0x78, 0x4b, 0x46, 0x68, 0x6e, 0x47, 0x77, 0x4e, 0x52, 0x49, 0x44, 0x49, 0x63, 0x43, + 0x47, 0x34, 0x33, 0x64, 0x54, 0x64, 0x45, 0x54, 0x32, 0x67, 0x5a, 0x42, 0x32, 0x51, 0x55, + 0x4b, 0x43, 0x55, 0x72, 0x61, 0x54, 0x55, 0x59, 0x4a, 0x79, 0x59, 0x55, 0x45, 0x33, 0x42, + 0x43, 0x47, 0x52, 0x4a, 0x31, 0x50, 0x67, 0x4a, 0x64, 0x66, 0x42, 0x4d, 0x66, 0x46, 0x6c, + 0x4d, 0x37, 0x64, 0x45, 0x67, 0x38, 0x58, 0x6a, 0x6c, 0x73, 0x48, 0x42, 0x78, 0x30, 0x4f, + 0x52, 0x38, 0x41, 0x47, 0x77, 0x59, 0x4b, 0x61, 0x44, 0x74, 0x53, 0x54, 0x78, 0x35, 0x75, + 0x50, 0x44, 0x55, 0x4d, 0x4f, 0x41, 0x34, 0x4c, 0x4f, 0x78, 0x70, 0x32, 0x49, 0x79, 0x6c, + 0x54, 0x48, 0x6c, 0x39, 0x42, 0x44, 0x45, 0x73, 0x4b, 0x5a, 0x53, 0x68, 0x34, 0x5a, 0x30, + 0x68, 0x5a, 0x4a, 0x6d, 0x30, 0x78, 0x64, 0x69, 0x4e, 0x77, 0x59, 0x57, 0x51, 0x37, 0x4f, + 0x48, 0x6c, 0x6d, 0x64, 0x46, 0x4d, 0x73, 0x5a, 0x47, 0x52, 0x55, 0x41, 0x31, 0x52, 0x6c, + 0x52, 0x45, 0x77, 0x59, 0x54, 0x30, 0x67, 0x67, 0x54, 0x33, 0x49, 0x51, 0x50, 0x77, 0x78, + 0x53, 0x4c, 0x51, 0x4d, 0x55, 0x41, 0x31, 0x46, 0x43, 0x45, 0x48, 0x64, 0x71, 0x4e, 0x41, + 0x59, 0x79, 0x41, 0x33, 0x49, 0x55, 0x66, 0x41, 0x68, 0x64, 0x55, 0x68, 0x70, 0x69, 0x66, + 0x44, 0x34, 0x77, 0x66, 0x6c, 0x39, 0x2f, 0x56, 0x41, 0x39, 0x45, 0x53, 0x56, 0x31, 0x65, + 0x45, 0x47, 0x6f, 0x47, 0x4b, 0x77, 0x5a, 0x54, 0x45, 0x44, 0x6b, 0x33, 0x4d, 0x6b, 0x70, + 0x4f, 0x50, 0x53, 0x74, 0x6c, 0x4f, 0x44, 0x6b, 0x48, 0x63, 0x6c, 0x52, 0x6b, 0x54, 0x56, + 0x5a, 0x71, 0x41, 0x79, 0x4a, 0x77, 0x65, 0x31, 0x39, 0x67, 0x43, 0x79, 0x6f, 0x4c, 0x61, + 0x78, 0x42, 0x6b, 0x46, 0x41, 0x55, 0x69, 0x41, 0x48, 0x4e, 0x41, 0x49, 0x31, 0x74, 0x52, + 0x48, 0x79, 0x73, 0x61, 0x58, 0x57, 0x6c, 0x36, 0x52, 0x67, 0x78, 0x66, 0x4d, 0x6b, 0x74, + 0x4b, 0x4b, 0x46, 0x4a, 0x35, 0x57, 0x78, 0x4a, 0x43, 0x47, 0x41, 0x42, 0x64, 0x4a, 0x7a, + 0x46, 0x54, 0x50, 0x45, 0x77, 0x32, 0x54, 0x6a, 0x67, 0x2f, 0x63, 0x67, 0x4e, 0x78, 0x41, + 0x6c, 0x73, 0x32, 0x57, 0x58, 0x39, 0x31, 0x62, 0x67, 0x68, 0x55, 0x44, 0x54, 0x51, 0x63, + 0x4e, 0x46, 0x64, 0x64, 0x61, 0x55, 0x67, 0x41, 0x4f, 0x77, 0x55, 0x48, 0x62, 0x69, 0x64, + 0x6c, 0x62, 0x6b, 0x41, 0x39, 0x4f, 0x6b, 0x39, 0x79, 0x58, 0x54, 0x6b, 0x57, 0x44, 0x32, + 0x4d, 0x53, 0x45, 0x68, 0x55, 0x36, 0x63, 0x41, 0x31, 0x58, 0x47, 0x41, 0x31, 0x65, 0x50, + 0x53, 0x4a, 0x6f, 0x61, 0x48, 0x78, 0x74, 0x54, 0x77, 0x78, 0x37, 0x43, 0x53, 0x31, 0x4b, + 0x63, 0x79, 0x42, 0x48, 0x42, 0x31, 0x64, 0x31, 0x58, 0x56, 0x4e, 0x77, 0x4e, 0x43, 0x46, + 0x41, 0x56, 0x31, 0x46, 0x65, 0x53, 0x55, 0x51, 0x41, 0x56, 0x43, 0x63, 0x45, 0x61, 0x48, + 0x35, 0x5a, 0x56, 0x6c, 0x68, 0x30, 0x46, 0x44, 0x77, 0x57, 0x4d, 0x30, 0x45, 0x57, 0x53, + 0x79, 0x39, 0x4a, 0x4e, 0x77, 0x70, 0x55, 0x43, 0x41, 0x67, 0x66, 0x4f, 0x57, 0x64, 0x32, + 0x4b, 0x43, 0x67, 0x48, 0x48, 0x57, 0x46, 0x48, 0x55, 0x55, 0x31, 0x31, 0x4a, 0x6c, 0x4a, + 0x48, 0x52, 0x77, 0x78, 0x58, 0x57, 0x48, 0x51, 0x2b, 0x59, 0x6d, 0x78, 0x59, 0x4f, 0x6b, + 0x51, 0x65, 0x46, 0x69, 0x34, 0x68, 0x48, 0x48, 0x4e, 0x46, 0x5a, 0x33, 0x52, 0x50, 0x4d, + 0x32, 0x59, 0x4f, 0x64, 0x47, 0x59, 0x6d, 0x48, 0x79, 0x34, 0x34, 0x52, 0x45, 0x42, 0x2b, + 0x4b, 0x6c, 0x42, 0x53, 0x58, 0x6b, 0x4d, 0x42, 0x65, 0x6a, 0x68, 0x4a, 0x50, 0x46, 0x56, + 0x4e, 0x57, 0x6b, 0x51, 0x49, 0x4a, 0x6c, 0x6c, 0x4e, 0x52, 0x51, 0x74, 0x49, 0x43, 0x6a, + 0x4e, 0x65, 0x53, 0x6b, 0x31, 0x31, 0x46, 0x68, 0x64, 0x6a, 0x52, 0x67, 0x45, 0x71, 0x56, + 0x58, 0x73, 0x50, 0x41, 0x6e, 0x4e, 0x71, 0x53, 0x33, 0x39, 0x31, 0x5a, 0x54, 0x78, 0x4d, + 0x4d, 0x7a, 0x6c, 0x73, 0x64, 0x41, 0x56, 0x67, 0x44, 0x33, 0x38, 0x74, 0x51, 0x55, 0x31, + 0x4e, 0x52, 0x6e, 0x45, 0x4a, 0x62, 0x30, 0x39, 0x67, 0x46, 0x51, 0x39, 0x47, 0x63, 0x32, + 0x4e, 0x4d, 0x58, 0x6e, 0x51, 0x77, 0x44, 0x53, 0x68, 0x44, 0x43, 0x48, 0x49, 0x79, 0x42, + 0x43, 0x34, 0x78, 0x4b, 0x53, 0x64, 0x45, 0x62, 0x52, 0x4d, 0x58, 0x53, 0x41, 0x39, 0x4a, + 0x55, 0x68, 0x41, 0x54, 0x66, 0x78, 0x63, 0x57, 0x59, 0x6e, 0x6b, 0x31, 0x65, 0x44, 0x34, + 0x42, 0x66, 0x43, 0x34, 0x50, 0x64, 0x6a, 0x35, 0x65, 0x55, 0x32, 0x78, 0x62, 0x58, 0x33, + 0x77, 0x5a, 0x51, 0x51, 0x49, 0x76, 0x46, 0x32, 0x52, 0x42, 0x64, 0x52, 0x41, 0x45, 0x52, + 0x33, 0x77, 0x39, 0x53, 0x31, 0x49, 0x41, 0x45, 0x46, 0x31, 0x52, 0x54, 0x6e, 0x6f, 0x6e, + 0x4a, 0x56, 0x56, 0x41, 0x45, 0x6a, 0x56, 0x67, 0x42, 0x52, 0x73, 0x30, 0x4c, 0x51, 0x52, + 0x36, 0x61, 0x6d, 0x6b, 0x43, 0x65, 0x51, 0x4d, 0x36, 0x4c, 0x77, 0x59, 0x4b, 0x65, 0x58, + 0x73, 0x53, 0x58, 0x58, 0x78, 0x53, 0x4b, 0x55, 0x64, 0x59, 0x45, 0x6e, 0x4d, 0x2f, 0x4a, + 0x31, 0x59, 0x46, 0x44, 0x45, 0x67, 0x79, 0x57, 0x47, 0x74, 0x58, 0x58, 0x41, 0x4e, 0x6b, + 0x56, 0x68, 0x46, 0x53, 0x65, 0x6a, 0x41, 0x32, 0x4b, 0x52, 0x63, 0x37, 0x61, 0x48, 0x70, + 0x38, 0x42, 0x57, 0x74, 0x72, 0x45, 0x32, 0x6f, 0x6b, 0x58, 0x47, 0x68, 0x43, 0x47, 0x44, + 0x49, 0x44, 0x63, 0x32, 0x34, 0x45, 0x49, 0x53, 0x34, 0x42, 0x42, 0x47, 0x4e, 0x39, 0x52, + 0x45, 0x45, 0x53, 0x4d, 0x51, 0x73, 0x56, 0x48, 0x33, 0x41, 0x41, 0x4c, 0x6d, 0x59, 0x55, + 0x50, 0x48, 0x38, 0x72, 0x41, 0x42, 0x38, 0x4d, 0x4b, 0x46, 0x6b, 0x4b, 0x46, 0x6b, 0x6c, + 0x61, 0x58, 0x47, 0x52, 0x6c, 0x53, 0x78, 0x45, 0x70, 0x46, 0x54, 0x5a, 0x61, 0x5a, 0x52, + 0x6c, 0x50, 0x59, 0x43, 0x4d, 0x36, 0x4f, 0x68, 0x4d, 0x6c, 0x41, 0x6e, 0x68, 0x4d, 0x56, + 0x41, 0x3d, 0x3d, 0x00}; char *b64_test; plan_tests(1); diff --git a/lib/tests/test_cmd.c b/lib/tests/test_cmd.c index c8867dfb..ade0da90 100644 --- a/lib/tests/test_cmd.c +++ b/lib/tests/test_cmd.c @@ -67,7 +67,8 @@ int main(int argc, char **argv) { result = cmd_run_array(command_line, &chld_out, &chld_err, 0); ok(chld_out.lines == 1, "(array) Check for expected number of stdout lines"); ok(chld_err.lines == 0, "(array) Check for expected number of stderr lines"); - ok(strcmp(chld_out.line[0], "this is test one") == 0, "(array) Check for expected stdout output"); + ok(strcmp(chld_out.line[0], "this is test one") == 0, + "(array) Check for expected stdout output"); ok(result == 0, "(array) Checking exit code"); /* ensure everything is empty again */ @@ -82,7 +83,8 @@ int main(int argc, char **argv) { ok(chld_out.lines == 1, "(string) Check for expected number of stdout lines"); ok(chld_err.lines == 0, "(string) Check for expected number of stderr lines"); - ok(strcmp(chld_out.line[0], "this is test one") == 0, "(string) Check for expected stdout output"); + ok(strcmp(chld_out.line[0], "this is test one") == 0, + "(string) Check for expected stdout output"); ok(result == 0, "(string) Checking exit code"); diag("Running plain echo command, set two"); @@ -104,7 +106,8 @@ int main(int argc, char **argv) { result = cmd_run_array(command_line, &chld_out, &chld_err, 0); ok(chld_out.lines == 1, "(array) Check for expected number of stdout lines"); ok(chld_err.lines == 0, "(array) Check for expected number of stderr lines"); - ok(strcmp(chld_out.line[0], "this is test two") == 0, "(array) Check for expected stdout output"); + ok(strcmp(chld_out.line[0], "this is test two") == 0, + "(array) Check for expected stdout output"); ok(result == 0, "(array) Checking exit code"); /* ensure everything is empty again */ @@ -119,7 +122,8 @@ int main(int argc, char **argv) { ok(chld_out.lines == 1, "(string) Check for expected number of stdout lines"); ok(chld_err.lines == 0, "(string) Check for expected number of stderr lines"); - ok(strcmp(chld_out.line[0], "this is test one") == 0, "(string) Check for expected stdout output"); + ok(strcmp(chld_out.line[0], "this is test one") == 0, + "(string) Check for expected stdout output"); ok(result == 0, "(string) Checking exit code"); /* ensure everything is empty again */ @@ -130,7 +134,8 @@ int main(int argc, char **argv) { ok(chld_err.lines == 0, "(initialised) Checking stderr is reset"); ok(result == UNSET, "(initialised) Checking exit code is reset"); - /* Pass linefeeds via parameters through - those should be evaluated by echo to give multi line output */ + /* Pass linefeeds via parameters through - those should be evaluated by echo to give multi line + * output */ command_line[0] = strdup("/bin/echo"); command_line[1] = strdup("this is a test via echo\nline two\nit's line 3"); command_line[2] = strdup("and (note space between '3' and 'and') $$ will not get evaluated"); @@ -138,9 +143,12 @@ int main(int argc, char **argv) { result = cmd_run_array(command_line, &chld_out, &chld_err, 0); ok(chld_out.lines == 3, "(array) Check for expected number of stdout lines"); ok(chld_err.lines == 0, "(array) Check for expected number of stderr lines"); - ok(strcmp(chld_out.line[0], "this is a test via echo") == 0, "(array) Check line 1 for expected stdout output"); - ok(strcmp(chld_out.line[1], "line two") == 0, "(array) Check line 2 for expected stdout output"); - ok(strcmp(chld_out.line[2], "it's line 3 and (note space between '3' and 'and') $$ will not get evaluated") == 0, + ok(strcmp(chld_out.line[0], "this is a test via echo") == 0, + "(array) Check line 1 for expected stdout output"); + ok(strcmp(chld_out.line[1], "line two") == 0, + "(array) Check line 2 for expected stdout output"); + ok(strcmp(chld_out.line[2], + "it's line 3 and (note space between '3' and 'and') $$ will not get evaluated") == 0, "(array) Check line 3 for expected stdout output"); ok(result == 0, "(array) Checking exit code"); @@ -171,7 +179,8 @@ int main(int argc, char **argv) { ok(chld_out.lines == 0, "/bin/sh returns no stdout when file is missing..."); ok(chld_err.lines == 1, "...but does give an error line"); - ok(strstr(chld_err.line[0], "non-existent-file") != NULL, "And missing filename is in error message"); + ok(strstr(chld_err.line[0], "non-existent-file") != NULL, + "And missing filename is in error message"); ok(result != 0, "Get non-zero return code from /bin/sh"); /* ensure everything is empty again */ diff --git a/lib/tests/test_generic_output.c b/lib/tests/test_generic_output.c index e67aefc9..e4a78bcd 100644 --- a/lib/tests/test_generic_output.c +++ b/lib/tests/test_generic_output.c @@ -110,7 +110,8 @@ void test_two_subchecks(void) { sc1.output = "foobar"; sc1 = mp_set_subcheck_state(sc1, STATE_WARNING); - ok(mp_compute_subcheck_state(sc1) == STATE_WARNING, "Test subcheck state directly after setting it"); + ok(mp_compute_subcheck_state(sc1) == STATE_WARNING, + "Test subcheck state directly after setting it"); mp_perfdata pd1 = perfdata_init(); @@ -129,7 +130,8 @@ void test_two_subchecks(void) { mp_add_subcheck_to_subcheck(&sc1, sc2); - ok(mp_compute_subcheck_state(sc1) == STATE_WARNING, "Test subcheck state after adding a subcheck"); + ok(mp_compute_subcheck_state(sc1) == STATE_WARNING, + "Test subcheck state after adding a subcheck"); mp_check check = mp_check_init(); mp_add_subcheck_to_check(&check, sc1); diff --git a/lib/tests/test_ini1.c b/lib/tests/test_ini1.c index 246c1250..3792d142 100644 --- a/lib/tests/test_ini1.c +++ b/lib/tests/test_ini1.c @@ -42,8 +42,9 @@ char *list2str(np_arg_list *optlst) { free(optltmp); } /* Strip last whitespace */ - if (strlen(optstr) > 1) + if (strlen(optstr) > 1) { optstr[strlen(optstr) - 1] = '\0'; + } return optstr; } @@ -54,15 +55,18 @@ int main(int argc, char **argv) { plan_tests(12); optstr = list2str(np_get_defaults("section@./config-tiny.ini", "check_disk")); - ok(!strcmp(optstr, "--one=two --Foo=Bar --this=Your Mother! --blank"), "config-tiny.ini's section as expected"); + ok(!strcmp(optstr, "--one=two --Foo=Bar --this=Your Mother! --blank"), + "config-tiny.ini's section as expected"); my_free(optstr); optstr = list2str(np_get_defaults("@./config-tiny.ini", "section")); - ok(!strcmp(optstr, "--one=two --Foo=Bar --this=Your Mother! --blank"), "Used default section name, without specific"); + ok(!strcmp(optstr, "--one=two --Foo=Bar --this=Your Mother! --blank"), + "Used default section name, without specific"); my_free(optstr); optstr = list2str(np_get_defaults("Section Two@./config-tiny.ini", "check_disk")); - ok(!strcmp(optstr, "--something else=blah --remove=whitespace"), "config-tiny.ini's Section Two as expected"); + ok(!strcmp(optstr, "--something else=blah --remove=whitespace"), + "config-tiny.ini's Section Two as expected"); my_free(optstr); optstr = list2str(np_get_defaults("/path/to/file.txt@./config-tiny.ini", "check_disk")); @@ -70,15 +74,18 @@ int main(int argc, char **argv) { my_free(optstr); optstr = list2str(np_get_defaults("section2@./config-tiny.ini", "check_disk")); - ok(!strcmp(optstr, "--this=that"), "config-tiny.ini's section2 with whitespace before section name"); + ok(!strcmp(optstr, "--this=that"), + "config-tiny.ini's section2 with whitespace before section name"); my_free(optstr); optstr = list2str(np_get_defaults("section3@./config-tiny.ini", "check_disk")); - ok(!strcmp(optstr, "--this=that"), "config-tiny.ini's section3 with whitespace after section name"); + ok(!strcmp(optstr, "--this=that"), + "config-tiny.ini's section3 with whitespace after section name"); my_free(optstr); optstr = list2str(np_get_defaults("check_mysql@./plugin.ini", "check_disk")); - ok(!strcmp(optstr, "--username=operator --password=secret"), "plugin.ini's check_mysql as expected"); + ok(!strcmp(optstr, "--username=operator --password=secret"), + "plugin.ini's check_mysql as expected"); my_free(optstr); optstr = list2str(np_get_defaults("check_mysql2@./plugin.ini", "check_disk")); @@ -90,29 +97,39 @@ int main(int argc, char **argv) { my_free(optstr); optstr = list2str(np_get_defaults("Section Two@./config-dos.ini", "check_disk")); - ok(!strcmp(optstr, "--something else=blah --remove=whitespace"), "config-dos.ini's Section Two as expected"); + ok(!strcmp(optstr, "--something else=blah --remove=whitespace"), + "config-dos.ini's Section Two as expected"); my_free(optstr); optstr = list2str(np_get_defaults("section_twice@./plugin.ini", "check_disk")); - ok(!strcmp(optstr, "--foo=bar --bar=foo"), "plugin.ini's section_twice defined twice in the file"); + ok(!strcmp(optstr, "--foo=bar --bar=foo"), + "plugin.ini's section_twice defined twice in the file"); my_free(optstr); optstr = list2str(np_get_defaults("tcp_long_lines@plugins.ini", "check_tcp")); - ok(!strcmp(optstr, "--escape --send=Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar " + ok(!strcmp(optstr, "--escape --send=Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda " + "yadda Foo bar BAZ yadda yadda yadda Foo bar " "BAZ yadda yadda yadda Foo bar BAZ yadda yadda " - "yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda " + "yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar " + "BAZ yadda yadda yadda Foo bar BAZ yadda " "yadda yadda Foo bar BAZ yadda yadda yadda Foo " - "bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda " + "bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda " + "yadda yadda Foo bar BAZ yadda yadda " "yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ " - "yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda --expect=Foo bar BAZ yadda yadda " + "yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda " + "yadda --expect=Foo bar BAZ yadda yadda " "yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ " - "yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo " + "yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda " + "yadda Foo bar BAZ yadda yadda yadda Foo " "bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda " - "yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda " + "yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar " + "BAZ yadda yadda yadda Foo bar BAZ yadda " "yadda yadda Foo bar BAZ yadda yadda yadda Foo " - "bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda " + "bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda " + "yadda yadda Foo bar BAZ yadda yadda " "yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ " - "yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo " + "yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda " + "yadda Foo bar BAZ yadda yadda yadda Foo " "bar BAZ yadda yadda yadda --jail"), "Long options"); my_free(optstr); diff --git a/lib/tests/test_opts1.c b/lib/tests/test_opts1.c index 984183d3..99da5596 100644 --- a/lib/tests/test_opts1.c +++ b/lib/tests/test_opts1.c @@ -47,16 +47,18 @@ void my_free(int *argc, char **newargv, char **argv) { printf("'%s' ", newargv[i]); /* Stop freeing when we get to the start of the original array */ if (freeflag) { - if (newargv[i] == argv[1]) + if (newargv[i] == argv[1]) { freeflag = 0; - else + } else { free(newargv[i]); + } } } printf("\n"); /* Free only if it's a different array */ - if (newargv != argv) + if (newargv != argv) { free(newargv); + } *argc = 0; } #endif @@ -69,8 +71,9 @@ int array_diff(int i1, char **a1, int i2, char **a2) { return 0; } for (i = 0; i <= i1; i++) { - if (a1[i] == NULL && a2[i] == NULL) + if (a1[i] == NULL && a2[i] == NULL) { continue; + } if (a1[i] == NULL || a2[i] == NULL) { printf(" Argument # %i null in one array!\n", i); return 0; @@ -110,27 +113,36 @@ int main(int argc, char **argv) { { char *argv_test[] = {"prog_name", "--extra-opts=@./config-opts.ini", (char *)NULL}; argc_test = 2; - char *argv_known[] = {"prog_name", "--foo=Bar", "--this=Your Mother!", "--blank", (char *)NULL}; + char *argv_known[] = {"prog_name", "--foo=Bar", "--this=Your Mother!", "--blank", + (char *)NULL}; argv_new = np_extra_opts(&argc_test, argv_test, "check_disk"); ok(array_diff(argc_test, argv_new, 4, argv_known), "Only extra opts using default section"); my_free(&argc_test, argv_new, argv_test); } { - char *argv_test[] = {"prog_name", "--extra-opts=sect1@./config-opts.ini", "--extra-opts", "sect2@./config-opts.ini", (char *)NULL}; + char *argv_test[] = {"prog_name", "--extra-opts=sect1@./config-opts.ini", "--extra-opts", + "sect2@./config-opts.ini", (char *)NULL}; argc_test = 4; - char *argv_known[] = {"prog_name", "--one=two", "--something else=oops", "--this=that", (char *)NULL}; + char *argv_known[] = {"prog_name", "--one=two", "--something else=oops", "--this=that", + (char *)NULL}; argv_new = np_extra_opts(&argc_test, argv_test, "check_disk"); ok(array_diff(argc_test, argv_new, 4, argv_known), "Only extra opts specified twice"); my_free(&argc_test, argv_new, argv_test); } { - char *argv_test[] = {"prog_name", "--arg1=val1", "--extra-opts=@./config-opts.ini", "--extra-opts", "sect1@./config-opts.ini", - "--arg2", (char *)NULL}; + char *argv_test[] = {"prog_name", + "--arg1=val1", + "--extra-opts=@./config-opts.ini", + "--extra-opts", + "sect1@./config-opts.ini", + "--arg2", + (char *)NULL}; argc_test = 6; - char *argv_known[] = {"prog_name", "--foo=Bar", "--this=Your Mother!", "--blank", "--one=two", - "--arg1=val1", "--arg2", (char *)NULL}; + char *argv_known[] = {"prog_name", "--foo=Bar", "--this=Your Mother!", + "--blank", "--one=two", "--arg1=val1", + "--arg2", (char *)NULL}; argv_new = np_extra_opts(&argc_test, argv_test, "check_disk"); ok(array_diff(argc_test, argv_new, 7, argv_known), "twice extra opts using two sections"); my_free(&argc_test, argv_new, argv_test); diff --git a/lib/tests/test_opts2.c b/lib/tests/test_opts2.c index 23496617..d1b0aca3 100644 --- a/lib/tests/test_opts2.c +++ b/lib/tests/test_opts2.c @@ -30,16 +30,18 @@ void my_free(int *argc, char **newargv, char **argv) { printf("'%s' ", newargv[i]); /* Stop freeing when we get to the start of the original array */ if (freeflag) { - if (newargv[i] == argv[1]) + if (newargv[i] == argv[1]) { freeflag = 0; - else + } else { free(newargv[i]); + } } } printf("\n"); /* Free only if it's a different array */ - if (newargv != argv) + if (newargv != argv) { free(newargv); + } *argc = 0; } @@ -51,8 +53,9 @@ int array_diff(int i1, char **a1, int i2, char **a2) { return 0; } for (i = 0; i <= i1; i++) { - if (a1[i] == NULL && a2[i] == NULL) + if (a1[i] == NULL && a2[i] == NULL) { continue; + } if (a1[i] == NULL || a2[i] == NULL) { printf(" Argument # %i null in one array!\n", i); return 0; @@ -90,7 +93,8 @@ int main(int argc, char **argv) { } { - char *argv_test[] = {"prog_name", "arg1", "--extra-opts=section1", "--arg3", "val2", (char *)NULL}; + char *argv_test[] = {"prog_name", "arg1", "--extra-opts=section1", + "--arg3", "val2", (char *)NULL}; argc_test = 5; char *argv_known[] = {"prog_name", "--foobar=baz", "arg1", "--arg3", "val2", (char *)NULL}; argv_new = np_extra_opts(&argc_test, argv_test, "check_disk"); @@ -108,30 +112,39 @@ int main(int argc, char **argv) { } { - char *argv_test[] = {"check_tcp", "--extra-opts", "--extra-opts=tcp_long_lines", (char *)NULL}; + char *argv_test[] = {"check_tcp", "--extra-opts", "--extra-opts=tcp_long_lines", + (char *)NULL}; argc_test = 3; - char *argv_known[] = { - "check_tcp", - "--timeout=10", - "--escape", - "--send=Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda " - "yadda Foo bar BAZ yadda " - "yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda " - "yadda Foo bar BAZ " - "yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda " - "yadda yadda Foo bar " - "BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda", - "--expect=Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda " - "yadda Foo bar BAZ yadda " - "yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda " - "yadda Foo bar BAZ " - "yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda " - "yadda yadda Foo bar " - "BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ " - "yadda yadda yadda Foo " - "bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda", - "--jail", - (char *)NULL}; + char *argv_known[] = {"check_tcp", + "--timeout=10", + "--escape", + "--send=Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda " + "Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda " + "yadda Foo bar BAZ yadda " + "yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda " + "yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda " + "yadda Foo bar BAZ " + "yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda " + "yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda " + "yadda yadda Foo bar " + "BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ " + "yadda yadda yadda Foo bar BAZ yadda yadda yadda", + "--expect=Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda " + "yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda " + "yadda Foo bar BAZ yadda " + "yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda " + "yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda " + "yadda Foo bar BAZ " + "yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda " + "yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda " + "yadda yadda Foo bar " + "BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ " + "yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ " + "yadda yadda yadda Foo " + "bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ " + "yadda yadda yadda Foo bar BAZ yadda yadda yadda", + "--jail", + (char *)NULL}; argv_new = np_extra_opts(&argc_test, argv_test, "check_tcp"); ok(array_diff(argc_test, argv_new, 6, argv_known), "Long lines test"); my_free(&argc_test, argv_new, argv_test); diff --git a/lib/tests/test_tcp.c b/lib/tests/test_tcp.c index 1b3003e9..de3a2102 100644 --- a/lib/tests/test_tcp.c +++ b/lib/tests/test_tcp.c @@ -32,19 +32,28 @@ int main(void) { server_expect[1] = strdup("bb"); server_expect[2] = strdup("CC"); - ok(np_expect_match("AA bb CC XX", server_expect, server_expect_count, NP_MATCH_EXACT) == NP_MATCH_SUCCESS, + ok(np_expect_match("AA bb CC XX", server_expect, server_expect_count, NP_MATCH_EXACT) == + NP_MATCH_SUCCESS, "Test matching any string at the beginning (first expect string)"); - ok(np_expect_match("bb AA CC XX", server_expect, server_expect_count, NP_MATCH_EXACT) == NP_MATCH_SUCCESS, + ok(np_expect_match("bb AA CC XX", server_expect, server_expect_count, NP_MATCH_EXACT) == + NP_MATCH_SUCCESS, "Test matching any string at the beginning (second expect string)"); ok(np_expect_match("b", server_expect, server_expect_count, NP_MATCH_EXACT) == NP_MATCH_RETRY, "Test matching any string at the beginning (substring match)"); - ok(np_expect_match("XX bb AA CC XX", server_expect, server_expect_count, NP_MATCH_EXACT) == NP_MATCH_FAILURE, + ok(np_expect_match("XX bb AA CC XX", server_expect, server_expect_count, NP_MATCH_EXACT) == + NP_MATCH_FAILURE, "Test with strings not matching at the beginning"); - ok(np_expect_match("XX CC XX", server_expect, server_expect_count, NP_MATCH_EXACT) == NP_MATCH_FAILURE, "Test matching any string"); - ok(np_expect_match("XX", server_expect, server_expect_count, 0) == NP_MATCH_RETRY, "Test not matching any string"); - ok(np_expect_match("XX AA bb CC XX", server_expect, server_expect_count, NP_MATCH_ALL) == NP_MATCH_SUCCESS, + ok(np_expect_match("XX CC XX", server_expect, server_expect_count, NP_MATCH_EXACT) == + NP_MATCH_FAILURE, + "Test matching any string"); + ok(np_expect_match("XX", server_expect, server_expect_count, 0) == NP_MATCH_RETRY, + "Test not matching any string"); + ok(np_expect_match("XX AA bb CC XX", server_expect, server_expect_count, NP_MATCH_ALL) == + NP_MATCH_SUCCESS, "Test matching all strings"); - ok(np_expect_match("XX bb CC XX", server_expect, server_expect_count, NP_MATCH_ALL) == NP_MATCH_RETRY, "Test not matching all strings"); + ok(np_expect_match("XX bb CC XX", server_expect, server_expect_count, NP_MATCH_ALL) == + NP_MATCH_RETRY, + "Test not matching all strings"); ok(np_expect_match("XX XX", server_expect, server_expect_count, NP_MATCH_ALL) == NP_MATCH_RETRY, "Test not matching any string (testing all)"); diff --git a/lib/utils_base.c b/lib/utils_base.c index e95eeaf0..69024bc9 100644 --- a/lib/utils_base.c +++ b/lib/utils_base.c @@ -254,7 +254,7 @@ bool check_range(double value, range *my_range) { yes = false; } - if (!my_range->end_infinity&& !my_range->start_infinity) { + if (!my_range->end_infinity && !my_range->start_infinity) { if ((my_range->start <= value) && (value <= my_range->end)) { return no; } @@ -268,7 +268,7 @@ bool check_range(double value, range *my_range) { return yes; } - if (my_range->start_infinity && !my_range->end_infinity ) { + if (my_range->start_infinity && !my_range->end_infinity) { if (value <= my_range->end) { return no; } diff --git a/lib/utils_cmd.c b/lib/utils_cmd.c index 9b222409..d1feaa33 100644 --- a/lib/utils_cmd.c +++ b/lib/utils_cmd.c @@ -71,7 +71,7 @@ extern char **environ; #endif #ifndef WIFEXITED -# define WIFEXITED(stat_val) (((stat_val)&255) == 0) +# define WIFEXITED(stat_val) (((stat_val) & 255) == 0) #endif /* 4.3BSD Reno doesn't define SIG_ERR */ @@ -103,8 +103,9 @@ void cmd_init(void) { maxfd = MAXFD_LIMIT; } - if (!_cmd_pids) + if (!_cmd_pids) { _cmd_pids = calloc(maxfd, sizeof(pid_t)); + } } /* Start running a command, array style */ @@ -116,13 +117,15 @@ static int _cmd_open(char *const *argv, int *pfd, int *pfderr) { int i = 0; - if (!_cmd_pids) + if (!_cmd_pids) { CMD_INIT; + } setenv("LC_ALL", "C", 1); - if (pipe(pfd) < 0 || pipe(pfderr) < 0 || (pid = fork()) < 0) + if (pipe(pfd) < 0 || pipe(pfderr) < 0 || (pid = fork()) < 0) { return -1; /* errno set by the failing function */ + } /* child runs exceve() and _exit. */ if (pid == 0) { @@ -147,9 +150,11 @@ static int _cmd_open(char *const *argv, int *pfd, int *pfderr) { * This is executed in a separate address space (pure child), * so we don't have to worry about async safety */ long maxfd = mp_open_max(); - for (i = 0; i < maxfd; i++) - if (_cmd_pids[i] > 0) + for (i = 0; i < maxfd; i++) { + if (_cmd_pids[i] > 0) { close(i); + } + } execve(argv[0], argv, environ); _exit(STATE_UNKNOWN); @@ -172,17 +177,21 @@ static int _cmd_close(int fd) { /* make sure the provided fd was opened */ long maxfd = mp_open_max(); - if (fd < 0 || fd > maxfd || !_cmd_pids || (pid = _cmd_pids[fd]) == 0) + if (fd < 0 || fd > maxfd || !_cmd_pids || (pid = _cmd_pids[fd]) == 0) { return -1; + } _cmd_pids[fd] = 0; - if (close(fd) == -1) + if (close(fd) == -1) { return -1; + } /* EINTR is ok (sort of), everything else is bad */ - while (waitpid(pid, &status, 0) < 0) - if (errno != EINTR) + while (waitpid(pid, &status, 0) < 0) { + if (errno != EINTR) { return -1; + } + } /* return child's termination status */ return (WIFEXITED(status)) ? WEXITSTATUS(status) : -1; @@ -212,15 +221,17 @@ static int _cmd_fetch_output(int fd, output *op, int flags) { /* some plugins may want to keep output unbroken, and some commands * will yield no output, so return here for those */ - if (flags & CMD_NO_ARRAYS || !op->buf || !op->buflen) + if (flags & CMD_NO_ARRAYS || !op->buf || !op->buflen) { return op->buflen; + } /* and some may want both */ if (flags & CMD_NO_ASSOC) { buf = malloc(op->buflen); memcpy(buf, op->buf, op->buflen); - } else + } else { buf = op->buf; + } op->line = NULL; op->lens = NULL; @@ -241,8 +252,9 @@ static int _cmd_fetch_output(int fd, output *op, int flags) { op->line[lineno] = &buf[i]; /* hop to next newline or end of buffer */ - while (buf[i] != '\n' && i < op->buflen) + while (buf[i] != '\n' && i < op->buflen) { i++; + } buf[i] = '\0'; /* calculate the string length using pointer difference */ @@ -262,30 +274,36 @@ int cmd_run(const char *cmdstring, output *out, output *err, int flags) { char *cmd = NULL; char *str = NULL; - if (cmdstring == NULL) + if (cmdstring == NULL) { return -1; + } /* initialize the structs */ - if (out) + if (out) { memset(out, 0, sizeof(output)); - if (err) + } + if (err) { memset(err, 0, sizeof(output)); + } /* make copy of command string so strtok() doesn't silently modify it */ /* (the calling program may want to access it later) */ cmdlen = strlen(cmdstring); - if ((cmd = malloc(cmdlen + 1)) == NULL) + if ((cmd = malloc(cmdlen + 1)) == NULL) { return -1; + } memcpy(cmd, cmdstring, cmdlen); cmd[cmdlen] = '\0'; /* This is not a shell, so we don't handle "???" */ - if (strstr(cmdstring, "\"")) + if (strstr(cmdstring, "\"")) { return -1; + } /* allow single quotes, but only if non-whitesapce doesn't occur on both sides */ - if (strstr(cmdstring, " ' ") || strstr(cmdstring, "'''")) + if (strstr(cmdstring, " ' ") || strstr(cmdstring, "'''")) { return -1; + } /* each arg must be whitespace-separated, so args can be a maximum * of (len / 2) + 1. We add 1 extra to the mix for NULL termination */ @@ -304,8 +322,9 @@ int cmd_run(const char *cmdstring, output *out, output *err, int flags) { if (strstr(str, "'") == str) { /* handle SIMPLE quoted strings */ str++; - if (!strstr(str, "'")) + if (!strstr(str, "'")) { return -1; /* balanced? */ + } cmd = 1 + strstr(str, "'"); str[strcspn(str, "'")] = 0; } else { @@ -317,8 +336,9 @@ int cmd_run(const char *cmdstring, output *out, output *err, int flags) { } } - if (cmd && strlen(cmd) == strspn(cmd, " \t\r\n")) + if (cmd && strlen(cmd) == strspn(cmd, " \t\r\n")) { cmd = NULL; + } argv[i++] = str; } @@ -330,50 +350,61 @@ int cmd_run_array(char *const *argv, output *out, output *err, int flags) { int fd, pfd_out[2], pfd_err[2]; /* initialize the structs */ - if (out) + if (out) { memset(out, 0, sizeof(output)); - if (err) + } + if (err) { memset(err, 0, sizeof(output)); + } - if ((fd = _cmd_open(argv, pfd_out, pfd_err)) == -1) + if ((fd = _cmd_open(argv, pfd_out, pfd_err)) == -1) { die(STATE_UNKNOWN, _("Could not open pipe: %s\n"), argv[0]); + } - if (out) + if (out) { out->lines = _cmd_fetch_output(pfd_out[0], out, flags); - if (err) + } + if (err) { err->lines = _cmd_fetch_output(pfd_err[0], err, flags); + } return _cmd_close(fd); } int cmd_file_read(const char *filename, output *out, int flags) { int fd; - if (out) + if (out) { memset(out, 0, sizeof(output)); + } if ((fd = open(filename, O_RDONLY)) == -1) { die(STATE_UNKNOWN, _("Error opening %s: %s"), filename, strerror(errno)); } - if (out) + if (out) { out->lines = _cmd_fetch_output(fd, out, flags); + } - if (close(fd) == -1) + if (close(fd) == -1) { die(STATE_UNKNOWN, _("Error closing %s: %s"), filename, strerror(errno)); + } return 0; } void timeout_alarm_handler(int signo) { if (signo == SIGALRM) { - printf(_("%s - Plugin timed out after %d seconds\n"), state_text(timeout_state), timeout_interval); + printf(_("%s - Plugin timed out after %d seconds\n"), state_text(timeout_state), + timeout_interval); long maxfd = mp_open_max(); - if (_cmd_pids) + if (_cmd_pids) { for (long int i = 0; i < maxfd; i++) { - if (_cmd_pids[i] != 0) + if (_cmd_pids[i] != 0) { kill(_cmd_pids[i], SIGKILL); + } } + } exit(timeout_state); } diff --git a/lib/utils_tcp.c b/lib/utils_tcp.c index daae1d54..1482458b 100644 --- a/lib/utils_tcp.c +++ b/lib/utils_tcp.c @@ -29,18 +29,21 @@ #include "common.h" #include "utils_tcp.h" -#define VERBOSE(message) \ - do { \ - if (flags & NP_MATCH_VERBOSE) \ - puts(message); \ +#define VERBOSE(message) \ + do { \ + if (flags & NP_MATCH_VERBOSE) \ + puts(message); \ } while (0) -enum np_match_result np_expect_match(char *status, char **server_expect, int expect_count, int flags) { +enum np_match_result np_expect_match(char *status, char **server_expect, int expect_count, + int flags) { int i, match = 0, partial = 0; for (i = 0; i < expect_count; i++) { - if (flags & NP_MATCH_VERBOSE) - printf("looking for [%s] %s [%s]\n", server_expect[i], (flags & NP_MATCH_EXACT) ? "in beginning of" : "anywhere in", status); + if (flags & NP_MATCH_VERBOSE) { + printf("looking for [%s] %s [%s]\n", server_expect[i], + (flags & NP_MATCH_EXACT) ? "in beginning of" : "anywhere in", status); + } if (flags & NP_MATCH_EXACT) { if (strncmp(status, server_expect[i], strlen(server_expect[i])) == 0) { @@ -60,10 +63,12 @@ enum np_match_result np_expect_match(char *status, char **server_expect, int exp VERBOSE("couldn't find it"); } - if ((flags & NP_MATCH_ALL && match == expect_count) || (!(flags & NP_MATCH_ALL) && match >= 1)) + if ((flags & NP_MATCH_ALL && match == expect_count) || + (!(flags & NP_MATCH_ALL) && match >= 1)) { return NP_MATCH_SUCCESS; - else if (partial > 0 || !(flags & NP_MATCH_EXACT)) + } else if (partial > 0 || !(flags & NP_MATCH_EXACT)) { return NP_MATCH_RETRY; - else + } else { return NP_MATCH_FAILURE; + } } diff --git a/lib/utils_tcp.h b/lib/utils_tcp.h index a7d83c59..e5cdbb82 100644 --- a/lib/utils_tcp.h +++ b/lib/utils_tcp.h @@ -17,4 +17,5 @@ enum np_match_result { NP_MATCH_RETRY }; -enum np_match_result np_expect_match(char *status, char **server_expect, int server_expect_count, int flags); +enum np_match_result np_expect_match(char *status, char **server_expect, int server_expect_count, + int flags); diff --git a/plugins-root/check_dhcp.c b/plugins-root/check_dhcp.c index daed9cb0..9a96547f 100644 --- a/plugins-root/check_dhcp.c +++ b/plugins-root/check_dhcp.c @@ -127,17 +127,17 @@ static long mac_addr_dlpi(const char *, int, u_char *); #define MAX_DHCP_OPTIONS_LENGTH 312 typedef struct dhcp_packet_struct { - uint8_t op; /* packet type */ - uint8_t htype; /* type of hardware address for this machine (Ethernet, etc) */ - uint8_t hlen; /* length of hardware address (of this machine) */ - uint8_t hops; /* hops */ - uint32_t xid; /* random transaction id number - chosen by this machine */ - uint16_t secs; /* seconds used in timing */ - uint16_t flags; /* flags */ - struct in_addr ciaddr; /* IP address of this machine (if we already have one) */ - struct in_addr yiaddr; /* IP address of this machine (offered by the DHCP server) */ - struct in_addr siaddr; /* IP address of next server */ - struct in_addr giaddr; /* IP address of DHCP relay */ + uint8_t op; /* packet type */ + uint8_t htype; /* type of hardware address for this machine (Ethernet, etc) */ + uint8_t hlen; /* length of hardware address (of this machine) */ + uint8_t hops; /* hops */ + uint32_t xid; /* random transaction id number - chosen by this machine */ + uint16_t secs; /* seconds used in timing */ + uint16_t flags; /* flags */ + struct in_addr ciaddr; /* IP address of this machine (if we already have one) */ + struct in_addr yiaddr; /* IP address of this machine (offered by the DHCP server) */ + struct in_addr siaddr; /* IP address of next server */ + struct in_addr giaddr; /* IP address of DHCP relay */ unsigned char chaddr[MAX_DHCP_CHADDR_LENGTH]; /* hardware address of this machine */ char sname[MAX_DHCP_SNAME_LENGTH]; /* name of DHCP server */ char file[MAX_DHCP_FILE_LENGTH]; /* boot file name (used for diskless booting?) */ @@ -199,7 +199,8 @@ static void print_help(void); static void resolve_host(const char * /*in*/, struct in_addr * /*out*/); static unsigned char *mac_aton(const char * /*string*/); static void print_hardware_address(const unsigned char * /*address*/); -static int get_hardware_address(int /*sock*/, char * /*interface_name*/, unsigned char *client_hardware_address); +static int get_hardware_address(int /*sock*/, char * /*interface_name*/, + unsigned char *client_hardware_address); typedef struct get_ip_address_wrapper { int error; @@ -211,32 +212,40 @@ typedef struct send_dhcp_discover_wrapper { int error; uint32_t packet_xid; } send_dhcp_discover_wrapper; -static send_dhcp_discover_wrapper send_dhcp_discover(int socket, bool unicast, struct in_addr dhcp_ip, struct in_addr requested_address, - bool request_specific_address, struct in_addr my_ip, - unsigned char *client_hardware_address); +static send_dhcp_discover_wrapper +send_dhcp_discover(int socket, bool unicast, struct in_addr dhcp_ip, + struct in_addr requested_address, bool request_specific_address, + struct in_addr my_ip, unsigned char *client_hardware_address); typedef struct get_dhcp_offer_wrapper { int error; int valid_responses; dhcp_offer *dhcp_offer_list; } get_dhcp_offer_wrapper; -static get_dhcp_offer_wrapper get_dhcp_offer(int /*sock*/, int dhcpoffer_timeout, uint32_t packet_xid, dhcp_offer *dhcp_offer_list, +static get_dhcp_offer_wrapper get_dhcp_offer(int /*sock*/, int dhcpoffer_timeout, + uint32_t packet_xid, dhcp_offer *dhcp_offer_list, const unsigned char *client_hardware_address); -static mp_subcheck get_results(bool exclusive, int requested_servers, struct in_addr requested_address, bool request_specific_address, - requested_server *requested_server_list, int valid_responses, dhcp_offer *dhcp_offer_list); +static mp_subcheck get_results(bool exclusive, int requested_servers, + struct in_addr requested_address, bool request_specific_address, + requested_server *requested_server_list, int valid_responses, + dhcp_offer *dhcp_offer_list); typedef struct add_dhcp_offer_wrapper { int error; dhcp_offer *dhcp_offer_list; } add_dhcp_offer_wrapper; -static add_dhcp_offer_wrapper add_dhcp_offer(struct in_addr /*source*/, dhcp_packet * /*offer_packet*/, dhcp_offer *dhcp_offer_list); +static add_dhcp_offer_wrapper add_dhcp_offer(struct in_addr /*source*/, + dhcp_packet * /*offer_packet*/, + dhcp_offer *dhcp_offer_list); static int free_dhcp_offer_list(dhcp_offer *dhcp_offer_list); static int free_requested_server_list(requested_server *requested_server_list); static int create_dhcp_socket(bool /*unicast*/, char *network_interface_name); static int close_dhcp_socket(int /*sock*/); -static int send_dhcp_packet(void * /*buffer*/, int /*buffer_size*/, int /*sock*/, struct sockaddr_in * /*dest*/); -static int receive_dhcp_packet(void * /*buffer*/, int /*buffer_size*/, int /*sock*/, int /*timeout*/, struct sockaddr_in * /*address*/); +static int send_dhcp_packet(void * /*buffer*/, int /*buffer_size*/, int /*sock*/, + struct sockaddr_in * /*dest*/); +static int receive_dhcp_packet(void * /*buffer*/, int /*buffer_size*/, int /*sock*/, + int /*timeout*/, struct sockaddr_in * /*address*/); int main(int argc, char **argv) { setlocale(LC_ALL, ""); @@ -271,7 +280,8 @@ int main(int argc, char **argv) { struct in_addr my_ip = {0}; if (config.unicast_mode) { /* get IP address of client machine */ - get_ip_address_wrapper tmp_get_ip = get_ip_address(dhcp_socket, config.network_interface_name); + get_ip_address_wrapper tmp_get_ip = + get_ip_address(dhcp_socket, config.network_interface_name); if (tmp_get_ip.error == OK) { my_ip = tmp_get_ip.my_ip; } else { @@ -281,8 +291,9 @@ int main(int argc, char **argv) { } /* send DHCPDISCOVER packet */ - send_dhcp_discover_wrapper disco_res = send_dhcp_discover(dhcp_socket, config.unicast_mode, config.dhcp_ip, config.requested_address, - config.request_specific_address, my_ip, client_hardware_address); + send_dhcp_discover_wrapper disco_res = send_dhcp_discover( + dhcp_socket, config.unicast_mode, config.dhcp_ip, config.requested_address, + config.request_specific_address, my_ip, client_hardware_address); if (disco_res.error != OK) { // DO something? @@ -290,8 +301,8 @@ int main(int argc, char **argv) { } /* wait for a DHCPOFFER packet */ - get_dhcp_offer_wrapper offer_res = - get_dhcp_offer(dhcp_socket, config.dhcpoffer_timeout, disco_res.packet_xid, NULL, client_hardware_address); + get_dhcp_offer_wrapper offer_res = get_dhcp_offer( + dhcp_socket, config.dhcpoffer_timeout, disco_res.packet_xid, NULL, client_hardware_address); int valid_responses = 0; dhcp_offer *dhcp_offer_list = NULL; @@ -308,8 +319,10 @@ int main(int argc, char **argv) { mp_check overall = mp_check_init(); /* determine state/plugin output to return */ - mp_subcheck sc_res = get_results(config.exclusive_mode, config.num_of_requested_servers, config.requested_address, - config.request_specific_address, config.requested_server_list, valid_responses, dhcp_offer_list); + mp_subcheck sc_res = + get_results(config.exclusive_mode, config.num_of_requested_servers, + config.requested_address, config.request_specific_address, + config.requested_server_list, valid_responses, dhcp_offer_list); mp_add_subcheck_to_check(&overall, sc_res); /* free allocated memory */ free_dhcp_offer_list(dhcp_offer_list); @@ -357,17 +370,20 @@ int get_hardware_address(int sock, char *interface_name, unsigned char *client_h } if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) { - printf(_("Error: Couldn't get hardware address from %s. sysctl 1 error - %s.\n"), interface_name, strerror(errno)); + printf(_("Error: Couldn't get hardware address from %s. sysctl 1 error - %s.\n"), + interface_name, strerror(errno)); exit(STATE_UNKNOWN); } if ((buf = malloc(len)) == NULL) { - printf(_("Error: Couldn't get hardware address from interface %s. malloc error - %s.\n"), interface_name, strerror(errno)); + printf(_("Error: Couldn't get hardware address from interface %s. malloc error - %s.\n"), + interface_name, strerror(errno)); exit(4); } if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) { - printf(_("Error: Couldn't get hardware address from %s. sysctl 2 error - %s.\n"), interface_name, strerror(errno)); + printf(_("Error: Couldn't get hardware address from %s. sysctl 2 error - %s.\n"), + interface_name, strerror(errno)); exit(STATE_UNKNOWN); } @@ -398,12 +414,16 @@ int get_hardware_address(int sock, char *interface_name, unsigned char *client_h unit = atoi(p); strncat(dev, interface_name, 6); } else { - printf(_("Error: can't find unit number in interface_name (%s) - expecting TypeNumber eg lnc0.\n"), interface_name); + printf(_("Error: can't find unit number in interface_name (%s) - expecting TypeNumber eg " + "lnc0.\n"), + interface_name); exit(STATE_UNKNOWN); } stat = mac_addr_dlpi(dev, unit, client_hardware_address); if (stat != 0) { - printf(_("Error: can't read MAC address from DLPI streams interface for device %s unit %d.\n"), dev, unit); + printf( + _("Error: can't read MAC address from DLPI streams interface for device %s unit %d.\n"), + dev, unit); exit(STATE_UNKNOWN); } @@ -415,7 +435,9 @@ int get_hardware_address(int sock, char *interface_name, unsigned char *client_h stat = mac_addr_dlpi(dev, unit, client_hardware_address); if (stat != 0) { - printf(_("Error: can't read MAC address from DLPI streams interface for device %s unit %d.\n"), dev, unit); + printf( + _("Error: can't read MAC address from DLPI streams interface for device %s unit %d.\n"), + dev, unit); exit(STATE_UNKNOWN); } /* Kompf 2000-2003 */ @@ -463,8 +485,10 @@ get_ip_address_wrapper get_ip_address(int sock, char *interface_name) { } /* sends a DHCPDISCOVER broadcast message in an attempt to find DHCP servers */ -static send_dhcp_discover_wrapper send_dhcp_discover(int sock, bool unicast, struct in_addr dhcp_ip, struct in_addr requested_address, - bool request_specific_address, struct in_addr my_ip, +static send_dhcp_discover_wrapper send_dhcp_discover(int sock, bool unicast, struct in_addr dhcp_ip, + struct in_addr requested_address, + bool request_specific_address, + struct in_addr my_ip, unsigned char *client_hardware_address) { dhcp_packet discover_packet = {0}; /* boot request flag (backward compatible with BOOTP servers) */ @@ -506,8 +530,9 @@ static send_dhcp_discover_wrapper send_dhcp_discover(int sock, bool unicast, str unsigned short opts = 4; /* DHCP message type is embedded in options field */ - discover_packet.options[opts++] = DHCP_OPTION_MESSAGE_TYPE; /* DHCP message type option identifier */ - discover_packet.options[opts++] = '\x01'; /* DHCP message option length in bytes */ + discover_packet.options[opts++] = + DHCP_OPTION_MESSAGE_TYPE; /* DHCP message type option identifier */ + discover_packet.options[opts++] = '\x01'; /* DHCP message option length in bytes */ discover_packet.options[opts++] = DHCPDISCOVER; /* the IP address we're requesting */ @@ -535,8 +560,10 @@ static send_dhcp_discover_wrapper send_dhcp_discover(int sock, bool unicast, str }; if (verbose) { - printf(_("DHCPDISCOVER to %s port %d\n"), inet_ntoa(sockaddr_broadcast.sin_addr), ntohs(sockaddr_broadcast.sin_port)); - printf("DHCPDISCOVER XID: %u (0x%X)\n", ntohl(discover_packet.xid), ntohl(discover_packet.xid)); + printf(_("DHCPDISCOVER to %s port %d\n"), inet_ntoa(sockaddr_broadcast.sin_addr), + ntohs(sockaddr_broadcast.sin_port)); + printf("DHCPDISCOVER XID: %u (0x%X)\n", ntohl(discover_packet.xid), + ntohl(discover_packet.xid)); printf("DHCDISCOVER ciaddr: %s\n", inet_ntoa(discover_packet.ciaddr)); printf("DHCDISCOVER yiaddr: %s\n", inet_ntoa(discover_packet.yiaddr)); printf("DHCDISCOVER siaddr: %s\n", inet_ntoa(discover_packet.siaddr)); @@ -554,7 +581,8 @@ static send_dhcp_discover_wrapper send_dhcp_discover(int sock, bool unicast, str } /* waits for a DHCPOFFER message from one or more DHCP servers */ -get_dhcp_offer_wrapper get_dhcp_offer(int sock, int dhcpoffer_timeout, uint32_t packet_xid, dhcp_offer *dhcp_offer_list, +get_dhcp_offer_wrapper get_dhcp_offer(int sock, int dhcpoffer_timeout, uint32_t packet_xid, + dhcp_offer *dhcp_offer_list, const unsigned char *client_hardware_address) { time_t start_time; time(&start_time); @@ -578,7 +606,8 @@ get_dhcp_offer_wrapper get_dhcp_offer(int sock, int dhcpoffer_timeout, uint32_t dhcp_packet offer_packet = {0}; result = OK; - result = receive_dhcp_packet(&offer_packet, sizeof(offer_packet), sock, dhcpoffer_timeout, &source); + result = receive_dhcp_packet(&offer_packet, sizeof(offer_packet), sock, dhcpoffer_timeout, + &source); if (result != OK) { if (verbose) { @@ -607,8 +636,9 @@ get_dhcp_offer_wrapper get_dhcp_offer(int sock, int dhcpoffer_timeout, uint32_t /* check packet xid to see if its the same as the one we used in the discover packet */ if (ntohl(offer_packet.xid) != packet_xid) { if (verbose) { - printf(_("DHCPOFFER XID (%u) did not match DHCPDISCOVER XID (%u) - ignoring packet\n"), ntohl(offer_packet.xid), - packet_xid); + printf( + _("DHCPOFFER XID (%u) did not match DHCPDISCOVER XID (%u) - ignoring packet\n"), + ntohl(offer_packet.xid), packet_xid); } continue; @@ -648,7 +678,8 @@ get_dhcp_offer_wrapper get_dhcp_offer(int sock, int dhcpoffer_timeout, uint32_t printf("DHCPOFFER giaddr: %s\n", inet_ntoa(offer_packet.giaddr)); } - add_dhcp_offer_wrapper add_res = add_dhcp_offer(source.sin_addr, &offer_packet, dhcp_offer_list); + add_dhcp_offer_wrapper add_res = + add_dhcp_offer(source.sin_addr, &offer_packet, dhcp_offer_list); if (add_res.error != OK) { // TODO } else { @@ -673,7 +704,8 @@ get_dhcp_offer_wrapper get_dhcp_offer(int sock, int dhcpoffer_timeout, uint32_t /* sends a DHCP packet */ int send_dhcp_packet(void *buffer, int buffer_size, int sock, struct sockaddr_in *dest) { - int result = sendto(sock, (char *)buffer, buffer_size, 0, (struct sockaddr *)dest, sizeof(*dest)); + int result = + sendto(sock, (char *)buffer, buffer_size, 0, (struct sockaddr *)dest, sizeof(*dest)); if (verbose) { printf(_("send_dhcp_packet result: %d\n"), result); @@ -687,7 +719,8 @@ int send_dhcp_packet(void *buffer, int buffer_size, int sock, struct sockaddr_in } /* receives a DHCP packet */ -int receive_dhcp_packet(void *buffer, int buffer_size, int sock, int timeout, struct sockaddr_in *address) { +int receive_dhcp_packet(void *buffer, int buffer_size, int sock, int timeout, + struct sockaddr_in *address) { /* wait for data to arrive (up time timeout) */ struct timeval timeout_val = { .tv_sec = timeout, @@ -711,7 +744,8 @@ int receive_dhcp_packet(void *buffer, int buffer_size, int sock, int timeout, st struct sockaddr_in source_address = {0}; socklen_t address_size = sizeof(source_address); - int recv_result = recvfrom(sock, (char *)buffer, buffer_size, 0, (struct sockaddr *)&source_address, &address_size); + int recv_result = recvfrom(sock, (char *)buffer, buffer_size, 0, + (struct sockaddr *)&source_address, &address_size); if (verbose) { printf("recv_result: %d\n", recv_result); } @@ -775,7 +809,8 @@ int create_dhcp_socket(bool unicast, char *network_interface_name) { strncpy(interface.ifr_ifrn.ifrn_name, network_interface_name, IFNAMSIZ - 1); interface.ifr_ifrn.ifrn_name[IFNAMSIZ - 1] = '\0'; if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, (char *)&interface, sizeof(interface)) < 0) { - printf(_("Error: Could not bind socket to interface %s. Check your privileges...\n"), network_interface_name); + printf(_("Error: Could not bind socket to interface %s. Check your privileges...\n"), + network_interface_name); exit(STATE_UNKNOWN); } @@ -786,7 +821,8 @@ int create_dhcp_socket(bool unicast, char *network_interface_name) { /* bind the socket */ if (bind(sock, (struct sockaddr *)&myname, sizeof(myname)) < 0) { - printf(_("Error: Could not bind to DHCP socket (port %d)! Check your privileges...\n"), DHCP_CLIENT_PORT); + printf(_("Error: Could not bind to DHCP socket (port %d)! Check your privileges...\n"), + DHCP_CLIENT_PORT); exit(STATE_UNKNOWN); } @@ -800,7 +836,8 @@ int close_dhcp_socket(int sock) { } /* adds a requested server address to list in memory */ -int add_requested_server(struct in_addr server_address, int *requested_servers, requested_server **requested_server_list) { +int add_requested_server(struct in_addr server_address, int *requested_servers, + requested_server **requested_server_list) { requested_server *new_server = (requested_server *)malloc(sizeof(requested_server)); if (new_server == NULL) { return ERROR; @@ -822,7 +859,8 @@ int add_requested_server(struct in_addr server_address, int *requested_servers, } /* adds a DHCP OFFER to list in memory */ -add_dhcp_offer_wrapper add_dhcp_offer(struct in_addr source, dhcp_packet *offer_packet, dhcp_offer *dhcp_offer_list) { +add_dhcp_offer_wrapper add_dhcp_offer(struct in_addr source, dhcp_packet *offer_packet, + dhcp_offer *dhcp_offer_list) { if (offer_packet == NULL) { add_dhcp_offer_wrapper tmp = { .error = ERROR, @@ -859,15 +897,18 @@ add_dhcp_offer_wrapper add_dhcp_offer(struct in_addr source, dhcp_packet *offer_ dhcp_lease_time = ntohl(dhcp_lease_time); break; case DHCP_OPTION_RENEWAL_TIME: - memcpy(&dhcp_renewal_time, &offer_packet->options[dchp_opt_idx], sizeof(dhcp_renewal_time)); + memcpy(&dhcp_renewal_time, &offer_packet->options[dchp_opt_idx], + sizeof(dhcp_renewal_time)); dhcp_renewal_time = ntohl(dhcp_renewal_time); break; case DHCP_OPTION_REBINDING_TIME: - memcpy(&dhcp_rebinding_time, &offer_packet->options[dchp_opt_idx], sizeof(dhcp_rebinding_time)); + memcpy(&dhcp_rebinding_time, &offer_packet->options[dchp_opt_idx], + sizeof(dhcp_rebinding_time)); dhcp_rebinding_time = ntohl(dhcp_rebinding_time); break; case DHCP_OPTION_SERVER_IDENTIFIER: - memcpy(&serv_ident.s_addr, &offer_packet->options[dchp_opt_idx], sizeof(serv_ident.s_addr)); + memcpy(&serv_ident.s_addr, &offer_packet->options[dchp_opt_idx], + sizeof(serv_ident.s_addr)); break; } @@ -955,7 +996,8 @@ int free_dhcp_offer_list(dhcp_offer *dhcp_offer_list) { /* frees memory allocated to requested server list */ int free_requested_server_list(requested_server *requested_server_list) { requested_server *next_server; - for (requested_server *this_server = requested_server_list; this_server != NULL; this_server = next_server) { + for (requested_server *this_server = requested_server_list; this_server != NULL; + this_server = next_server) { next_server = this_server->next; free(this_server); } @@ -964,8 +1006,10 @@ int free_requested_server_list(requested_server *requested_server_list) { } /* gets state and plugin output to return */ -mp_subcheck get_results(bool exclusive, const int requested_servers, const struct in_addr requested_address, bool request_specific_address, - requested_server *requested_server_list, int valid_responses, dhcp_offer *dhcp_offer_list) { +mp_subcheck get_results(bool exclusive, const int requested_servers, + const struct in_addr requested_address, bool request_specific_address, + requested_server *requested_server_list, int valid_responses, + dhcp_offer *dhcp_offer_list) { mp_subcheck sc_dhcp_results = mp_subcheck_init(); sc_dhcp_results = mp_set_subcheck_default_state(sc_dhcp_results, STATE_OK); @@ -995,22 +1039,28 @@ mp_subcheck get_results(bool exclusive, const int requested_servers, const struc /* checks responses from requested servers */ int requested_responses = 0; if (requested_servers > 0) { - for (requested_server *temp_server = requested_server_list; temp_server != NULL; temp_server = temp_server->next) { - for (dhcp_offer *temp_offer = dhcp_offer_list; temp_offer != NULL; temp_offer = temp_offer->next) { + for (requested_server *temp_server = requested_server_list; temp_server != NULL; + temp_server = temp_server->next) { + for (dhcp_offer *temp_offer = dhcp_offer_list; temp_offer != NULL; + temp_offer = temp_offer->next) { /* get max lease time we were offered */ - if (temp_offer->lease_time > max_lease_time || temp_offer->lease_time == DHCP_INFINITE_TIME) { + if (temp_offer->lease_time > max_lease_time || + temp_offer->lease_time == DHCP_INFINITE_TIME) { max_lease_time = temp_offer->lease_time; } /* see if we got the address we requested */ - if (!memcmp(&requested_address, &temp_offer->offered_address, sizeof(requested_address))) { + if (!memcmp(&requested_address, &temp_offer->offered_address, + sizeof(requested_address))) { received_requested_address = true; } /* see if the servers we wanted a response from, talked to us or not */ - if (!memcmp(&temp_offer->server_address, &temp_server->server_address, sizeof(temp_server->server_address))) { + if (!memcmp(&temp_offer->server_address, &temp_server->server_address, + sizeof(temp_server->server_address))) { if (verbose) { - printf(_("DHCP Server Match: Offerer=%s"), inet_ntoa(temp_offer->server_address)); + printf(_("DHCP Server Match: Offerer=%s"), + inet_ntoa(temp_offer->server_address)); printf(_(" Requested=%s"), inet_ntoa(temp_server->server_address)); if (temp_server->answered) { printf(_(" (duplicate)")); @@ -1028,7 +1078,8 @@ mp_subcheck get_results(bool exclusive, const int requested_servers, const struc } /* exclusive mode: check for undesired offers */ - for (dhcp_offer *temp_offer = dhcp_offer_list; temp_offer != NULL; temp_offer = temp_offer->next) { + for (dhcp_offer *temp_offer = dhcp_offer_list; temp_offer != NULL; + temp_offer = temp_offer->next) { if (!temp_offer->desired) { undesired_offer = temp_offer; /* Checks only for the first undesired offer */ break; /* no further checks needed */ @@ -1036,7 +1087,8 @@ mp_subcheck get_results(bool exclusive, const int requested_servers, const struc } mp_subcheck sc_rqust_srvs = mp_subcheck_init(); - xasprintf(&sc_rqust_srvs.output, "%d of %d requested servers responded", requested_responses, requested_servers); + xasprintf(&sc_rqust_srvs.output, "%d of %d requested servers responded", + requested_responses, requested_servers); if (requested_responses == requested_servers) { sc_rqust_srvs = mp_set_subcheck_state(sc_rqust_srvs, STATE_OK); @@ -1053,14 +1105,17 @@ mp_subcheck get_results(bool exclusive, const int requested_servers, const struc } else { /* else check and see if we got our requested address from any server */ - for (dhcp_offer *temp_offer = dhcp_offer_list; temp_offer != NULL; temp_offer = temp_offer->next) { + for (dhcp_offer *temp_offer = dhcp_offer_list; temp_offer != NULL; + temp_offer = temp_offer->next) { /* get max lease time we were offered */ - if (temp_offer->lease_time > max_lease_time || temp_offer->lease_time == DHCP_INFINITE_TIME) { + if (temp_offer->lease_time > max_lease_time || + temp_offer->lease_time == DHCP_INFINITE_TIME) { max_lease_time = temp_offer->lease_time; } /* see if we got the address we requested */ - if (!memcmp(&requested_address, &temp_offer->offered_address, sizeof(requested_address))) { + if (!memcmp(&requested_address, &temp_offer->offered_address, + sizeof(requested_address))) { received_requested_address = true; } } @@ -1069,7 +1124,8 @@ mp_subcheck get_results(bool exclusive, const int requested_servers, const struc if (max_lease_time == DHCP_INFINITE_TIME) { xasprintf(&sc_dhcp_results.output, "%s, max lease time = Infinity", sc_dhcp_results.output); } else { - xasprintf(&sc_dhcp_results.output, "%s, max lease time = %" PRIu32 " seconds", sc_dhcp_results.output, max_lease_time); + xasprintf(&sc_dhcp_results.output, "%s, max lease time = %" PRIu32 " seconds", + sc_dhcp_results.output, max_lease_time); } if (exclusive) { @@ -1083,8 +1139,8 @@ mp_subcheck get_results(bool exclusive, const int requested_servers, const struc // Get the addresses for printout // 1.address of the sending server char server_address[INET_ADDRSTRLEN]; - const char *server_address_transformed = - inet_ntop(AF_INET, &undesired_offer->server_address, server_address, sizeof(server_address)); + const char *server_address_transformed = inet_ntop( + AF_INET, &undesired_offer->server_address, server_address, sizeof(server_address)); if (server_address != server_address_transformed) { die(STATE_UNKNOWN, "inet_ntop failed"); @@ -1093,13 +1149,15 @@ mp_subcheck get_results(bool exclusive, const int requested_servers, const struc // 2.address offered char offered_address[INET_ADDRSTRLEN]; const char *offered_address_transformed = - inet_ntop(AF_INET, &undesired_offer->offered_address, offered_address, sizeof(offered_address)); + inet_ntop(AF_INET, &undesired_offer->offered_address, offered_address, + sizeof(offered_address)); if (offered_address != offered_address_transformed) { die(STATE_UNKNOWN, "inet_ntop failed"); } - xasprintf(&sc_rogue_server.output, "Rogue DHCP Server detected! Server %s offered %s", server_address, offered_address); + xasprintf(&sc_rogue_server.output, "Rogue DHCP Server detected! Server %s offered %s", + server_address, offered_address); } else { sc_rogue_server = mp_set_subcheck_state(sc_rogue_server, STATE_OK); xasprintf(&sc_rogue_server.output, "No Rogue DHCP Server detected"); @@ -1112,10 +1170,12 @@ mp_subcheck get_results(bool exclusive, const int requested_servers, const struc if (received_requested_address) { sc_rqustd_addr = mp_set_subcheck_state(sc_rqustd_addr, STATE_OK); - xasprintf(&sc_rqustd_addr.output, "Requested address (%s) was offered", inet_ntoa(requested_address)); + xasprintf(&sc_rqustd_addr.output, "Requested address (%s) was offered", + inet_ntoa(requested_address)); } else { sc_rqustd_addr = mp_set_subcheck_state(sc_rqustd_addr, STATE_WARNING); - xasprintf(&sc_rqustd_addr.output, "Requested address (%s) was NOT offered", inet_ntoa(requested_address)); + xasprintf(&sc_rqustd_addr.output, "Requested address (%s) was NOT offered", + inet_ntoa(requested_address)); } mp_add_subcheck_to_subcheck(&sc_dhcp_results, sc_rqustd_addr); @@ -1138,18 +1198,19 @@ process_arguments_wrapper process_arguments(int argc, char **argv) { }; int option_index = 0; - static struct option long_options[] = {{"serverip", required_argument, 0, 's'}, - {"requestedip", required_argument, 0, 'r'}, - {"timeout", required_argument, 0, 't'}, - {"interface", required_argument, 0, 'i'}, - {"mac", required_argument, 0, 'm'}, - {"unicast", no_argument, 0, 'u'}, - {"exclusive", no_argument, 0, 'x'}, - {"verbose", no_argument, 0, 'v'}, - {"version", no_argument, 0, 'V'}, - {"help", no_argument, 0, 'h'}, - {"output-format", required_argument, 0, output_format_index}, - {0, 0, 0, 0}}; + static struct option long_options[] = { + {"serverip", required_argument, 0, 's'}, + {"requestedip", required_argument, 0, 'r'}, + {"timeout", required_argument, 0, 't'}, + {"interface", required_argument, 0, 'i'}, + {"mac", required_argument, 0, 'm'}, + {"unicast", no_argument, 0, 'u'}, + {"exclusive", no_argument, 0, 'x'}, + {"verbose", no_argument, 0, 'v'}, + {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, + {"output-format", required_argument, 0, output_format_index}, + {0, 0, 0, 0}}; check_dhcp_config config = check_dhcp_config_init(); int option_char = 0; @@ -1163,7 +1224,8 @@ process_arguments_wrapper process_arguments(int argc, char **argv) { switch (option_char) { case 's': /* DHCP server address */ resolve_host(optarg, &config.dhcp_ip); - add_requested_server(config.dhcp_ip, &config.num_of_requested_servers, &config.requested_server_list); + add_requested_server(config.dhcp_ip, &config.num_of_requested_servers, + &config.requested_server_list); break; case 'r': /* address we are requested from DHCP servers */ @@ -1187,7 +1249,8 @@ process_arguments_wrapper process_arguments(int argc, char **argv) { break; case 'i': /* interface name */ - strncpy(config.network_interface_name, optarg, sizeof(config.network_interface_name) - 1); + strncpy(config.network_interface_name, optarg, + sizeof(config.network_interface_name) - 1); config.network_interface_name[sizeof(config.network_interface_name) - 1] = '\x0'; break; @@ -1289,7 +1352,8 @@ static int put_ctrl(int fd, int len, int pri) { ctl.len = len; if (putmsg(fd, &ctl, 0, pri) < 0) { - printf(_("Error: DLPI stream API failed to get MAC in put_ctrl/putmsg(): %s.\n"), strerror(errno)); + printf(_("Error: DLPI stream API failed to get MAC in put_ctrl/putmsg(): %s.\n"), + strerror(errno)); exit(STATE_UNKNOWN); } @@ -1302,7 +1366,8 @@ static int put_both(int fd, int clen, int dlen, int pri) { ctl.len = clen; dat.len = dlen; if (putmsg(fd, &ctl, &dat, pri) < 0) { - printf(_("Error: DLPI stream API failed to get MAC in put_both/putmsg().\n"), strerror(errno)); + printf(_("Error: DLPI stream API failed to get MAC in put_both/putmsg().\n"), + strerror(errno)); exit(STATE_UNKNOWN); } @@ -1314,7 +1379,8 @@ static int dl_open(const char *dev, int unit, int *fd) { dl_attach_req_t *attach_req = (dl_attach_req_t *)ctl_area; if ((*fd = open(dev, O_RDWR)) == -1) { - printf(_("Error: DLPI stream API failed to get MAC in dl_attach_req/open(%s..): %s.\n"), dev, strerror(errno)); + printf(_("Error: DLPI stream API failed to get MAC in dl_attach_req/open(%s..): %s.\n"), + dev, strerror(errno)); exit(STATE_UNKNOWN); } attach_req->dl_primitive = DL_ATTACH_REQ; @@ -1338,7 +1404,8 @@ static int dl_bind(int fd, int sap, u_char *addr) { put_ctrl(fd, sizeof(dl_bind_req_t), 0); get_msg(fd); if (GOT_ERR == check_ctrl(DL_BIND_ACK)) { - printf(_("Error: DLPI stream API failed to get MAC in dl_bind/check_ctrl(): %s.\n"), strerror(errno)); + printf(_("Error: DLPI stream API failed to get MAC in dl_bind/check_ctrl(): %s.\n"), + strerror(errno)); exit(STATE_UNKNOWN); } bcopy((u_char *)bind_ack + bind_ack->dl_addr_offset, addr, bind_ack->dl_addr_length); @@ -1455,7 +1522,8 @@ void print_help(void) { printf(" %s\n", "-u, --unicast"); printf(" %s\n", _("Unicast testing: mimic a DHCP relay, requires -s")); printf(" %s\n", "-x, --exclusive"); - printf(" %s\n", _("Only requested DHCP server may response (rogue DHCP server detection), requires -s")); + printf(" %s\n", + _("Only requested DHCP server may response (rogue DHCP server detection), requires -s")); printf(UT_SUPPORT); } diff --git a/plugins-root/check_icmp.d/config.h b/plugins-root/check_icmp.d/config.h index c348bef5..be388d0a 100644 --- a/plugins-root/check_icmp.d/config.h +++ b/plugins-root/check_icmp.d/config.h @@ -97,7 +97,7 @@ typedef struct icmp_ping_data { /* 80 msec packet interval by default */ // DEPRECATED, remove when removing the option -#define DEFAULT_PKT_INTERVAL 80000 +#define DEFAULT_PKT_INTERVAL 80000 #define DEFAULT_TARGET_INTERVAL 0 diff --git a/plugins-root/pst3.c b/plugins-root/pst3.c index 1f69f3a6..1bfe3d35 100644 --- a/plugins-root/pst3.c +++ b/plugins-root/pst3.c @@ -1,45 +1,45 @@ /***************************************************************************** -* -* pst3 -* -* License: GPL -* Copyright (c) 2008 Monitoring Plugins Development Team -* -* Description: -* -* This file contains the pst3 executable. This is a replacement ps command -* for Solaris to get output which provides a long argument listing, which -* is not possible with the standard ps command (due to truncation). /usr/ucb/ps -* also has issues where some fields run into each other. -* -* This executable works by reading process address structures, so needs -* to be executed as root -* -* Originally written by R.W.Ingraham -* Rewritten by Duncan Ferguson (Altinity Ltd, June 2008) -* The rewrite was necessary as /dev/kmem is not available within -* non-global zones on Solaris 10 -* -* Details for rewrite came from -* source of /usr/ucb/ps on Solaris: -* http://cvs.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/ucbcmd/ps/ps.c#argvoff -* usenet group posting -* http://groups.google.com/group/comp.unix.solaris/tree/browse_frm/month/2001-09/bfa40c08bac819a2?rnum=141&_done=%2Fgroup%2Fcomp.unix.solaris%2Fbrowse_frm%2Fmonth%2F2001-09%3F -* -* 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 . -* -*****************************************************************************/ + * + * pst3 + * + * License: GPL + * Copyright (c) 2008 Monitoring Plugins Development Team + * + * Description: + * + * This file contains the pst3 executable. This is a replacement ps command + * for Solaris to get output which provides a long argument listing, which + * is not possible with the standard ps command (due to truncation). /usr/ucb/ps + * also has issues where some fields run into each other. + * + * This executable works by reading process address structures, so needs + * to be executed as root + * + * Originally written by R.W.Ingraham + * Rewritten by Duncan Ferguson (Altinity Ltd, June 2008) + * The rewrite was necessary as /dev/kmem is not available within + * non-global zones on Solaris 10 + * + * Details for rewrite came from + * source of /usr/ucb/ps on Solaris: + * http://cvs.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/ucbcmd/ps/ps.c#argvoff + * usenet group posting + * http://groups.google.com/group/comp.unix.solaris/tree/browse_frm/month/2001-09/bfa40c08bac819a2?rnum=141&_done=%2Fgroup%2Fcomp.unix.solaris%2Fbrowse_frm%2Fmonth%2F2001-09%3F + * + * 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 . + * + *****************************************************************************/ #include #include @@ -55,14 +55,14 @@ * Constants */ -#define PROC_DIR "/proc" -#define ARGS 30 +#define PROC_DIR "/proc" +#define ARGS 30 /* * Globals */ -static char * szProg; +static char *szProg; /* * Prototypes @@ -71,192 +71,179 @@ void usage(); /*----------------------------------------------------------------------------*/ -int main (int argc, char **argv) -{ - DIR *procdir; - struct dirent *proc; - char ps_name[ARGS]; - char as_name[ARGS]; - psinfo_t psinfo; - - /* Set our program name global */ - if ((szProg = strrchr(argv[0], '/')) != NULL) - szProg++; - else - szProg = argv[0]; - - /* if given any parameters, print out help */ - if(argc > 1) { - (void)usage(); - exit(1); - } - - /* Make sure that our euid is root */ - if (geteuid() != 0) - { - fprintf(stderr, "%s: This program can only be run by the root user!\n", szProg); - exit(1); - } - - if ((procdir = opendir(PROC_DIR)) == NULL) { - fprintf(stderr, "%s: cannot open PROC directory %s\n", szProg, PROC_DIR); - exit(1); - } - - /* Display column headings */ - printf("%c %5s %5s %5s %6s %6s %4s %s %s\n", - 'S', - "UID", - "PID", - "PPID", - "VSZ", - "RSS", - "%CPU", - "COMMAND", - "ARGS" - ); - - /* Zip through all of the process entries */ - while((proc = readdir(procdir))) { - int ps_fd; - int as_fd; - off_t argoff; - int i; - char *args; - char *procname; - char *ptr; - int argslen; - uintptr_t args_addr;; - uintptr_t *args_vecs;; - int args_count; - - if(proc->d_name[0] == '.') - continue; - - sprintf(ps_name,"%s/%s/%s",PROC_DIR,proc->d_name,"psinfo"); - sprintf(as_name,"%s/%s/%s",PROC_DIR,proc->d_name,"as"); -try_again: - if((ps_fd = open(ps_name, O_RDONLY)) == -1) - continue; - - if((as_fd = open(as_name, O_RDONLY)) == -1) { - close(ps_fd); - continue; - } - - if(read(ps_fd, &psinfo, sizeof(psinfo)) != sizeof(psinfo)) { - int err = errno; - close(ps_fd); - close(as_fd); - if(err == EAGAIN) goto try_again; - if(err != ENOENT) - fprintf(stderr, "%s: read() on %s: %s\n", szProg, - ps_name, strerror(err)); - continue; - } - close(ps_fd); - - /* system process, ignore since the previous version did */ - if( - psinfo.pr_nlwp == 0 || - strcmp(psinfo.pr_lwp.pr_clname, "SYS") == 0 - ) { - continue; - } - - /* get the procname to match previous versions */ - procname = strdup(psinfo.pr_psargs); - if((ptr = strchr(procname, ' ')) != NULL) - *ptr = '\0'; - if((ptr = strrchr(procname, '/')) != NULL) - ptr++; - else - ptr = procname; - - /* - * print out what we currently know - */ - printf("%c %5d %5d %5d %6lu %6lu %4.1f %s ", - psinfo.pr_lwp.pr_sname, - psinfo.pr_euid, - psinfo.pr_pid, - psinfo.pr_ppid, - psinfo.pr_size, - psinfo.pr_rssize, - ((float)(psinfo.pr_pctcpu) / 0x8000 * 100.0), - ptr - ); - free(procname); - - /* - * and now for the command line stuff - */ - - args_addr = psinfo.pr_argv; - args_count = psinfo.pr_argc; - args_vecs = malloc(args_count * sizeof(uintptr_t)); - - if(psinfo.pr_dmodel == PR_MODEL_NATIVE) { - /* this process matches target process */ - pread(as_fd,args_vecs, args_count * sizeof(uintptr_t), - args_addr); - } else { - /* this process is 64bit, target process is 32 bit*/ - caddr32_t *args_vecs32 = (caddr32_t *)args_vecs; - pread(as_fd,args_vecs32,args_count * sizeof(caddr32_t), - args_addr); - for (i=args_count-1;i>=0;--i) - args_vecs[i]=args_vecs32[i]; - } - - /* - * now read in the args - if what we read in fills buffer - * resize buffer and reread that bit again - */ - argslen=ARGS; - args=malloc(argslen+1); - for(i=0;i 1) { + (void)usage(); + exit(1); + } + + /* Make sure that our euid is root */ + if (geteuid() != 0) { + fprintf(stderr, "%s: This program can only be run by the root user!\n", szProg); + exit(1); + } + + if ((procdir = opendir(PROC_DIR)) == NULL) { + fprintf(stderr, "%s: cannot open PROC directory %s\n", szProg, PROC_DIR); + exit(1); + } + + /* Display column headings */ + printf("%c %5s %5s %5s %6s %6s %4s %s %s\n", 'S', "UID", "PID", "PPID", "VSZ", "RSS", "%CPU", + "COMMAND", "ARGS"); + + /* Zip through all of the process entries */ + while ((proc = readdir(procdir))) { + int ps_fd; + int as_fd; + off_t argoff; + int i; + char *args; + char *procname; + char *ptr; + int argslen; + uintptr_t args_addr; + ; + uintptr_t *args_vecs; + ; + int args_count; + + if (proc->d_name[0] == '.') { + continue; + } + + sprintf(ps_name, "%s/%s/%s", PROC_DIR, proc->d_name, "psinfo"); + sprintf(as_name, "%s/%s/%s", PROC_DIR, proc->d_name, "as"); + try_again: + if ((ps_fd = open(ps_name, O_RDONLY)) == -1) { + continue; + } + + if ((as_fd = open(as_name, O_RDONLY)) == -1) { + close(ps_fd); + continue; + } + + if (read(ps_fd, &psinfo, sizeof(psinfo)) != sizeof(psinfo)) { + int err = errno; + close(ps_fd); + close(as_fd); + if (err == EAGAIN) { + goto try_again; + } + if (err != ENOENT) { + fprintf(stderr, "%s: read() on %s: %s\n", szProg, ps_name, strerror(err)); + } + continue; + } + close(ps_fd); + + /* system process, ignore since the previous version did */ + if (psinfo.pr_nlwp == 0 || strcmp(psinfo.pr_lwp.pr_clname, "SYS") == 0) { + continue; + } + + /* get the procname to match previous versions */ + procname = strdup(psinfo.pr_psargs); + if ((ptr = strchr(procname, ' ')) != NULL) { + *ptr = '\0'; + } + if ((ptr = strrchr(procname, '/')) != NULL) { + ptr++; + } else { + ptr = procname; + } + + /* + * print out what we currently know + */ + printf("%c %5d %5d %5d %6lu %6lu %4.1f %s ", psinfo.pr_lwp.pr_sname, psinfo.pr_euid, + psinfo.pr_pid, psinfo.pr_ppid, psinfo.pr_size, psinfo.pr_rssize, + ((float)(psinfo.pr_pctcpu) / 0x8000 * 100.0), ptr); + free(procname); + + /* + * and now for the command line stuff + */ + + args_addr = psinfo.pr_argv; + args_count = psinfo.pr_argc; + args_vecs = malloc(args_count * sizeof(uintptr_t)); + + if (psinfo.pr_dmodel == PR_MODEL_NATIVE) { + /* this process matches target process */ + pread(as_fd, args_vecs, args_count * sizeof(uintptr_t), args_addr); + } else { + /* this process is 64bit, target process is 32 bit*/ + caddr32_t *args_vecs32 = (caddr32_t *)args_vecs; + pread(as_fd, args_vecs32, args_count * sizeof(caddr32_t), args_addr); + for (i = args_count - 1; i >= 0; --i) { + args_vecs[i] = args_vecs32[i]; + } + } + + /* + * now read in the args - if what we read in fills buffer + * resize buffer and reread that bit again + */ + argslen = ARGS; + args = malloc(argslen + 1); + for (i = 0; i < args_count; i++) { + memset(args, '\0', argslen + 1); + if (pread(as_fd, args, argslen, args_vecs[i]) <= 0) { + break; + } + args[argslen] = '\0'; + if (strlen(args) == argslen) { + argslen += ARGS; + args = realloc(args, argslen + 1); + i--; + continue; + } + printf(" %s", args); + } + free(args_vecs); + free(args); + close(as_fd); + printf("\n"); + } + + (void)closedir(procdir); + + return (0); } /*----------------------------------------------------------------------------*/ void usage() { - printf("%s: Help output\n\n", szProg); - printf("If this program is given any arguments, this help is displayed.\n"); - printf("This command is used to print out the full command line for all\n"); - printf("running processes because /usr/bin/ps is limited to 80 chars and\n"); - printf("/usr/ucb/ps can merge columns together.\n\n"); - printf("Columns are:\n"); - printf("\tS - State of process - see 'ps' man page\n"); - printf("\tUID - UID of the process owner\n"); - printf("\tPID - PID of the process\n"); - printf("\tPPID - PID of the parent process\n"); - printf("\tVSZ - Virtual memory usage (kilobytes)\n"); - printf("\tRSS - Real memory usage (kilobytes)\n"); - printf("\t%%CPU - CPU usage\n"); - printf("\tCOMMAND - Command being run\n"); - printf("\tARGS - Full command line with arguments\n"); - return; + printf("%s: Help output\n\n", szProg); + printf("If this program is given any arguments, this help is displayed.\n"); + printf("This command is used to print out the full command line for all\n"); + printf("running processes because /usr/bin/ps is limited to 80 chars and\n"); + printf("/usr/ucb/ps can merge columns together.\n\n"); + printf("Columns are:\n"); + printf("\tS - State of process - see 'ps' man page\n"); + printf("\tUID - UID of the process owner\n"); + printf("\tPID - PID of the process\n"); + printf("\tPPID - PID of the parent process\n"); + printf("\tVSZ - Virtual memory usage (kilobytes)\n"); + printf("\tRSS - Real memory usage (kilobytes)\n"); + printf("\t%%CPU - CPU usage\n"); + printf("\tCOMMAND - Command being run\n"); + printf("\tARGS - Full command line with arguments\n"); + return; } diff --git a/plugins/check_by_ssh.c b/plugins/check_by_ssh.c index 2bc38d49..74b7a46f 100644 --- a/plugins/check_by_ssh.c +++ b/plugins/check_by_ssh.c @@ -45,7 +45,8 @@ typedef struct { 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 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); @@ -90,7 +91,8 @@ int main(int argc, char **argv) { /* SSH returns 255 if connection attempt fails; include the first line of error output */ if (result == 255 && config.unknown_timeout) { - printf(_("SSH connection failed: %s\n"), chld_err.lines > 0 ? chld_err.line[0] : "(no error output)"); + printf(_("SSH connection failed: %s\n"), + chld_err.lines > 0 ? chld_err.line[0] : "(no error output)"); return STATE_UNKNOWN; } @@ -134,7 +136,8 @@ int main(int argc, char **argv) { puts(chld_out.line[i]); } } else { - printf(_("%s - check_by_ssh: Remote command '%s' returned status %d\n"), state_text(result), config.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 */ } @@ -160,9 +163,11 @@ int main(int argc, char **argv) { die(STATE_UNKNOWN, _("%s: Error parsing output\n"), progname); } - 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); + 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); } } @@ -172,34 +177,35 @@ int main(int argc, char **argv) { /* process command-line arguments */ 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'}, - {"fork", no_argument, 0, 'f'}, - {"timeout", required_argument, 0, 't'}, - {"unknown-timeout", no_argument, 0, 'U'}, - {"host", required_argument, 0, 'H'}, /* backward compatibility */ - {"hostname", required_argument, 0, 'H'}, - {"port", required_argument, 0, 'p'}, - {"output", required_argument, 0, 'O'}, - {"name", required_argument, 0, 'n'}, - {"services", required_argument, 0, 's'}, - {"identity", required_argument, 0, 'i'}, - {"user", required_argument, 0, 'u'}, - {"logname", required_argument, 0, 'l'}, - {"command", required_argument, 0, 'C'}, - {"skip", optional_argument, 0, 'S'}, /* backwards compatibility */ - {"skip-stdout", optional_argument, 0, 'S'}, - {"skip-stderr", optional_argument, 0, 'E'}, - {"warn-on-stderr", no_argument, 0, 'W'}, - {"proto1", no_argument, 0, '1'}, - {"proto2", no_argument, 0, '2'}, - {"use-ipv4", no_argument, 0, '4'}, - {"use-ipv6", no_argument, 0, '6'}, - {"ssh-option", required_argument, 0, 'o'}, - {"quiet", no_argument, 0, 'q'}, - {"configfile", optional_argument, 0, 'F'}, - {0, 0, 0, 0}}; + static struct option longopts[] = { + {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, + {"verbose", no_argument, 0, 'v'}, + {"fork", no_argument, 0, 'f'}, + {"timeout", required_argument, 0, 't'}, + {"unknown-timeout", no_argument, 0, 'U'}, + {"host", required_argument, 0, 'H'}, /* backward compatibility */ + {"hostname", required_argument, 0, 'H'}, + {"port", required_argument, 0, 'p'}, + {"output", required_argument, 0, 'O'}, + {"name", required_argument, 0, 'n'}, + {"services", required_argument, 0, 's'}, + {"identity", required_argument, 0, 'i'}, + {"user", required_argument, 0, 'u'}, + {"logname", required_argument, 0, 'l'}, + {"command", required_argument, 0, 'C'}, + {"skip", optional_argument, 0, 'S'}, /* backwards compatibility */ + {"skip-stdout", optional_argument, 0, 'S'}, + {"skip-stderr", optional_argument, 0, 'E'}, + {"warn-on-stderr", no_argument, 0, 'W'}, + {"proto1", no_argument, 0, '1'}, + {"proto2", no_argument, 0, '2'}, + {"use-ipv4", no_argument, 0, '4'}, + {"use-ipv6", no_argument, 0, '6'}, + {"ssh-option", required_argument, 0, 'o'}, + {"quiet", no_argument, 0, 'q'}, + {"configfile", optional_argument, 0, 'F'}, + {0, 0, 0, 0}}; check_by_ssh_config_wrapper result = { .errorcode = OK, @@ -221,7 +227,8 @@ check_by_ssh_config_wrapper process_arguments(int argc, char **argv) { 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); + 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; @@ -266,11 +273,13 @@ check_by_ssh_config_wrapper process_arguments(int argc, char **argv) { char *p2; p1 = optarg; - result.config.service = realloc(result.config.service, (++result.config.number_of_services) * sizeof(char *)); + result.config.service = realloc(result.config.service, + (++result.config.number_of_services) * sizeof(char *)); while ((p2 = index(p1, ':'))) { *p2 = '\0'; result.config.service[result.config.number_of_services - 1] = p1; - result.config.service = realloc(result.config.service, (++result.config.number_of_services) * sizeof(char *)); + result.config.service = realloc( + result.config.service, (++result.config.number_of_services) * sizeof(char *)); p1 = p2 + 1; } result.config.service[result.config.number_of_services - 1] = p1; @@ -309,7 +318,8 @@ check_by_ssh_config_wrapper process_arguments(int argc, char **argv) { case 'C': /* Command for remote machine */ result.config.commands++; if (result.config.commands > 1) { - xasprintf(&result.config.remotecmd, "%s;echo STATUS CODE: $?;", result.config.remotecmd); + xasprintf(&result.config.remotecmd, "%s;echo STATUS CODE: $?;", + result.config.remotecmd); } xasprintf(&result.config.remotecmd, "%s%s", result.config.remotecmd, optarg); break; @@ -396,7 +406,8 @@ command_construct comm_append(command_construct cmd, const char *str) { die(STATE_UNKNOWN, _("%s: Argument limit of %d exceeded\n"), progname, NP_MAXARGS); } - if ((cmd.commargv = (char **)realloc(cmd.commargv, (cmd.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")); } @@ -412,12 +423,18 @@ check_by_ssh_config_wrapper validate_arguments(check_by_ssh_config_wrapper confi return config_wrapper; } - 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 (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 (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); + die(STATE_UNKNOWN, + _("%s: In passive mode, you must provide the host short name from the monitoring " + "configs.\n"), + progname); } return config_wrapper; @@ -454,7 +471,8 @@ void print_help(void) { printf(" %s\n", "-W, --warn-on-stderr]"); printf(" %s\n", _("Exit with an warning, if there is an output on STDERR")); printf(" %s\n", "-f"); - printf(" %s\n", _("tells ssh to fork rather than create a tty [optional]. This will always return OK if ssh is executed")); + printf(" %s\n", _("tells ssh to fork rather than create a tty [optional]. This will always " + "return OK if ssh is executed")); printf(" %s\n", "-C, --command='COMMAND STRING'"); printf(" %s\n", _("command to execute on the remote machine")); printf(" %s\n", "-l, --logname=USERNAME"); @@ -490,7 +508,9 @@ void print_help(void) { printf(" %s\n", _("all of -O, -s, and -n options (servicelist order must match '-C'options)")); printf("\n"); printf("%s\n", _("Examples:")); - printf(" %s\n", "$ check_by_ssh -H localhost -n lh -s c1:c2:c3 -C uptime -C uptime -C uptime -O /tmp/foo"); + printf( + " %s\n", + "$ check_by_ssh -H localhost -n lh -s c1:c2:c3 -C uptime -C uptime -C uptime -O /tmp/foo"); printf(" %s\n", "$ cat /tmp/foo"); printf(" %s\n", "[1080933700] PROCESS_SERVICE_CHECK_RESULT;flint;c1;0; up 2 days"); printf(" %s\n", "[1080933700] PROCESS_SERVICE_CHECK_RESULT;flint;c2;0; up 2 days"); diff --git a/plugins/check_cluster.c b/plugins/check_cluster.c index 9b695499..373520ee 100644 --- a/plugins/check_cluster.c +++ b/plugins/check_cluster.c @@ -112,25 +112,30 @@ int main(int argc, char **argv) { int return_code = STATE_OK; /* return the status of the cluster */ 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), - (config.label == NULL) ? "Service cluster" : config.label, total_services_ok, total_services_warning, total_services_unknown, + 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), (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, 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); + (config.label == NULL) ? "Host cluster" : config.label, total_hosts_up, + total_hosts_down, total_hosts_unreachable); } exit(return_code); } 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}}; + 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, @@ -251,7 +256,8 @@ void print_help(void) { printf("\n"); printf("%s\n", _("Examples:")); printf(" %s\n", "check_cluster -s -d 2,0,2,0 -c @3:"); - printf(" %s\n", _("Will alert critical if there are 3 or more service data points in a non-OK")); + printf(" %s\n", + _("Will alert critical if there are 3 or more service data points in a non-OK")); printf(" %s\n", _("state.")); printf(UT_SUPPORT); diff --git a/plugins/check_dbi.c b/plugins/check_dbi.c index 9efcd1cb..468ded31 100644 --- a/plugins/check_dbi.c +++ b/plugins/check_dbi.c @@ -71,8 +71,9 @@ static double timediff(struct timeval /*start*/, struct timeval /*end*/); static void np_dbi_print_error(dbi_conn /*conn*/, char * /*fmt*/, ...); -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*/); +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; @@ -118,7 +119,8 @@ int main(int argc, char **argv) { dbi_inst *instance_p = {0}; if (dbi_initialize_r(NULL, instance_p) < 0) { - printf("UNKNOWN - failed to initialize DBI; possibly you don't have any drivers installed.\n"); + printf( + "UNKNOWN - failed to initialize DBI; possibly you don't have any drivers installed.\n"); return STATE_UNKNOWN; } @@ -133,10 +135,12 @@ int main(int argc, char **argv) { 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", config.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)) { + for (driver = dbi_driver_list_r(NULL, instance_p); driver; + driver = dbi_driver_list_r(driver, instance_p)) { printf(" - %s\n", dbi_driver_get_name(driver)); } return STATE_UNKNOWN; @@ -156,7 +160,8 @@ int main(int argc, char **argv) { const char *opt; if (verbose > 1) { - printf("Setting DBI driver option '%s' to '%s'\n", config.dbi_options[i].key, config.dbi_options[i].value); + 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, config.dbi_options[i].key, config.dbi_options[i].value)) { @@ -164,10 +169,12 @@ int main(int argc, char **argv) { } /* else: status != 0 */ - np_dbi_print_error(conn, "UNKNOWN - failed to set option '%s' to '%s'", config.dbi_options[i].key, config.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)) { + for (opt = dbi_conn_get_option_list(conn, NULL); opt; + opt = dbi_conn_get_option_list(conn, opt)) { printf(" - %s\n", opt); } dbi_conn_close(conn); @@ -230,14 +237,16 @@ int main(int argc, char **argv) { } if (dbi_conn_select_db(conn, config.dbi_database)) { - np_dbi_print_error(conn, "UNKNOWN - failed to select database '%s'", config.dbi_database); + np_dbi_print_error(conn, "UNKNOWN - failed to select database '%s'", + config.dbi_database); return STATE_UNKNOWN; } } if (config.dbi_query) { /* execute query */ - status = do_query(conn, &query_val_str, &query_val, &query_time, config.metric, config.type, config.dbi_query); + 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; @@ -281,7 +290,8 @@ int main(int argc, char **argv) { /* 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((config.metric != METRIC_QUERY_RESULT) || (!isnan(query_val)) || (config.type == TYPE_STRING)); + assert((config.metric != METRIC_QUERY_RESULT) || (!isnan(query_val)) || + (config.type == TYPE_STRING)); assert((config.type != TYPE_STRING) || (config.expect || config.expect_re_str)); @@ -289,12 +299,14 @@ int main(int argc, char **argv) { 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 : "", query_time); + printf(", '%s' returned '%s' in %fs", config.dbi_query, + query_val_str ? query_val_str : "", query_time); if (status != STATE_OK) { 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" : "")); + printf(" (expected regex /%s/%s)", config.expect_re_str, + ((config.expect_re_cflags & REG_ICASE) ? "i" : "")); } } } else if (isnan(query_val)) { @@ -304,18 +316,31 @@ int main(int argc, char **argv) { } } - printf(" | conntime=%fs;%s;%s;0; server_version=%u;%s;%s;0;", conn_time, - ((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 : ""); + printf( + " | conntime=%fs;%s;%s;0; server_version=%u;%s;%s;0;", conn_time, + ((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(" 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(" 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; @@ -442,7 +467,8 @@ check_dbi_config_wrapper process_arguments(int argc, char **argv) { *value = '\0'; ++value; - new = realloc(result.config.dbi_options, (result.config.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); @@ -464,7 +490,8 @@ check_dbi_config_wrapper process_arguments(int argc, char **argv) { } } - set_thresholds(&result.config.dbi_thresholds, result.config.warning_range, result.config.critical_range); + set_thresholds(&result.config.dbi_thresholds, result.config.warning_range, + result.config.critical_range); return validate_arguments(result); } @@ -474,21 +501,28 @@ check_dbi_config_wrapper validate_arguments(check_dbi_config_wrapper config_wrap usage("Must specify a DBI driver"); } - if (((config_wrapper.config.metric == METRIC_QUERY_RESULT) || (config_wrapper.config.metric == METRIC_QUERY_TIME)) && + 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 ((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)) { + 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 (config_wrapper.config.expect && (config_wrapper.config.warning_range || config_wrapper.config.critical_range || config_wrapper.config.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 (config_wrapper.config.expect_re_str && (config_wrapper.config.warning_range || config_wrapper.config.critical_range || config_wrapper.config.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"); } @@ -496,7 +530,8 @@ check_dbi_config_wrapper validate_arguments(check_dbi_config_wrapper config_wrap usage("Option -e requires metric QUERY_RESULT"); } - if (config_wrapper.config.expect_re_str && (config_wrapper.config.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"); } @@ -607,7 +642,8 @@ void print_usage(void) { printf(" [-e ] [-r|-R ]\n"); } -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 *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) { @@ -630,7 +666,8 @@ const char *get_field_str(dbi_conn conn, dbi_result res, unsigned short field_ty return str; } -double get_field(dbi_conn conn, dbi_result res, unsigned short *field_type, mp_dbi_metric metric, mp_dbi_type 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) { @@ -679,7 +716,8 @@ double get_field(dbi_conn conn, dbi_result res, unsigned short *field_type, mp_d return 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) { +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; @@ -747,8 +785,8 @@ mp_state_enum get_query_result(dbi_conn conn, dbi_result res, const char **res_v return STATE_OK; } -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) { +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; diff --git a/plugins/check_dig.c b/plugins/check_dig.c index d0903be2..c27e5f13 100644 --- a/plugins/check_dig.c +++ b/plugins/check_dig.c @@ -81,8 +81,9 @@ int main(int argc, char **argv) { 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, config.dig_args, config.query_transport, - config.server_port, config.dns_server, config.query_address, config.record_type, config.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); struct timeval start_time; @@ -118,8 +119,9 @@ int main(int argc, char **argv) { printf("%s\n", chld_out.line[i]); } - if (strcasestr(chld_out.line[i], (config.expected_address == NULL ? config.query_address : config.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; @@ -174,8 +176,9 @@ int main(int argc, char **argv) { 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", (config.warning_interval > UNDEFINED), config.warning_interval, - (config.critical_interval > UNDEFINED), config.critical_interval, true, 0, false, 0)); + 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); } @@ -335,7 +338,8 @@ void print_help(void) { printf(" %s\n", "-T, --record_type=STRING"); printf(" %s\n", _("Record type to lookup (default: A)")); printf(" %s\n", "-a, --expected_address=STRING"); - printf(" %s\n", _("An address expected to be in the answer section. If not set, uses whatever")); + printf(" %s\n", + _("An address expected to be in the answer section. If not set, uses whatever")); printf(" %s\n", _("was in -l")); printf(" %s\n", "-A, --dig-arguments=STRING"); printf(" %s\n", _("Pass STRING as argument(s) to dig")); diff --git a/plugins/check_disk.c b/plugins/check_disk.c index 515ddff0..d42b5486 100644 --- a/plugins/check_disk.c +++ b/plugins/check_disk.c @@ -78,18 +78,21 @@ typedef struct { } check_disk_config_wrapper; static check_disk_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); -static void set_all_thresholds(parameter_list_elem *path, char *warn_freespace_units, char *crit_freespace_units, - char *warn_freespace_percent, char *crit_freespace_percent, char *warn_freeinodes_percent, +static void set_all_thresholds(parameter_list_elem *path, char *warn_freespace_units, + char *crit_freespace_units, char *warn_freespace_percent, + char *crit_freespace_percent, char *warn_freeinodes_percent, char *crit_freeinodes_percent); static double calculate_percent(uintmax_t /*value*/, uintmax_t /*total*/); static bool stat_path(parameter_list_elem * /*parameters*/, bool /*ignore_missing*/); /* - * Puts the values from a struct fs_usage into a parameter_list with an additional flag to control how reserved - * and inodes should be judged (ignored or not) + * Puts the values from a struct fs_usage into a parameter_list with an additional flag to control + * how reserved and inodes should be judged (ignored or not) */ -static parameter_list_elem get_path_stats(parameter_list_elem parameters, struct fs_usage fsp, bool freespace_ignore_reserved); -static mp_subcheck evaluate_filesystem(measurement_unit measurement_unit, bool display_inodes_perfdata, byte_unit unit); +static parameter_list_elem get_path_stats(parameter_list_elem parameters, struct fs_usage fsp, + bool freespace_ignore_reserved); +static mp_subcheck evaluate_filesystem(measurement_unit measurement_unit, + bool display_inodes_perfdata, byte_unit unit); void print_usage(void); static void print_help(void); @@ -111,7 +114,6 @@ const byte_unit TeraBytes_factor = 1000000000000; const byte_unit PetaBytes_factor = 1000000000000000; const byte_unit ExaBytes_factor = 1000000000000000000; - int main(int argc, char **argv) { setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); @@ -140,7 +142,8 @@ int main(int argc, char **argv) { } if (!config.path_ignored) { - mp_int_fs_list_set_best_match(config.path_select_list, config.mount_list, config.exact_match); + mp_int_fs_list_set_best_match(config.path_select_list, config.mount_list, + config.exact_match); } // Error if no match found for specified paths @@ -203,20 +206,23 @@ int main(int argc, char **argv) { } if (path->group == NULL) { - if (config.fs_exclude_list && np_find_regmatch(config.fs_exclude_list, mount_entry->me_type)) { + if (config.fs_exclude_list && + np_find_regmatch(config.fs_exclude_list, mount_entry->me_type)) { // Skip excluded fs's path = mp_int_fs_list_del(&config.path_select_list, path); continue; } - if (config.device_path_exclude_list && (np_find_name(config.device_path_exclude_list, mount_entry->me_devname) || - np_find_name(config.device_path_exclude_list, mount_entry->me_mountdir))) { + if (config.device_path_exclude_list && + (np_find_name(config.device_path_exclude_list, mount_entry->me_devname) || + np_find_name(config.device_path_exclude_list, mount_entry->me_mountdir))) { // Skip excluded device or mount paths path = mp_int_fs_list_del(&config.path_select_list, path); continue; } - if (config.fs_include_list && !np_find_regmatch(config.fs_include_list, mount_entry->me_type)) { + if (config.fs_include_list && + !np_find_regmatch(config.fs_include_list, mount_entry->me_type)) { // Skip not included fstypes path = mp_int_fs_list_del(&config.path_select_list, path); continue; @@ -259,8 +265,8 @@ int main(int argc, char **argv) { if (verbose >= 3) { printf("For %s, used_units=%lu free_units=%lu total_units=%lu " "fsp.fsu_blocksize=%lu\n", - mount_entry->me_mountdir, filesystem->used_bytes, filesystem->free_bytes, filesystem->total_bytes, - fsp.fsu_blocksize); + mount_entry->me_mountdir, filesystem->used_bytes, filesystem->free_bytes, + filesystem->total_bytes, fsp.fsu_blocksize); } } else { // failed to retrieve file system data or not mounted? @@ -285,12 +291,14 @@ int main(int argc, char **argv) { measurement_unit_list *measurements = NULL; measurement_unit_list *current = NULL; // create measuring units, because of groups - for (parameter_list_elem *filesystem = config.path_select_list.first; filesystem; filesystem = mp_int_fs_list_get_next(filesystem)) { + for (parameter_list_elem *filesystem = config.path_select_list.first; filesystem; + filesystem = mp_int_fs_list_get_next(filesystem)) { assert(filesystem->best_match != NULL); if (filesystem->group == NULL) { // create a measurement unit for the fs - measurement_unit unit = create_measurement_unit_from_filesystem(*filesystem, config.display_mntp); + measurement_unit unit = + create_measurement_unit_from_filesystem(*filesystem, config.display_mntp); if (measurements == NULL) { measurements = current = add_measurement_list(NULL, unit); } else { @@ -300,14 +308,17 @@ int main(int argc, char **argv) { // Grouped elements are consecutive if (measurements == NULL) { // first entry - measurement_unit unit = create_measurement_unit_from_filesystem(*filesystem, config.display_mntp); + measurement_unit unit = + create_measurement_unit_from_filesystem(*filesystem, config.display_mntp); unit.name = strdup(filesystem->group); measurements = current = add_measurement_list(NULL, unit); } else { - // if this is the first element of a group, the name of the previous entry is different + // if this is the first element of a group, the name of the previous entry is + // different if (strcmp(filesystem->group, current->unit.name) != 0) { // so, this must be the first element of a group - measurement_unit unit = create_measurement_unit_from_filesystem(*filesystem, config.display_mntp); + measurement_unit unit = + create_measurement_unit_from_filesystem(*filesystem, config.display_mntp); unit.name = filesystem->group; current = add_measurement_list(measurements, unit); @@ -322,7 +333,8 @@ int main(int argc, char **argv) { /* Process for every path in list */ if (measurements != NULL) { for (measurement_unit_list *unit = measurements; unit; unit = unit->next) { - mp_subcheck unit_sc = evaluate_filesystem(unit->unit, config.display_inodes_perfdata, config.display_unit); + mp_subcheck unit_sc = evaluate_filesystem(unit->unit, config.display_inodes_perfdata, + config.display_unit); mp_add_subcheck_to_check(&overall, unit_sc); } } else { @@ -433,7 +445,8 @@ check_disk_config_wrapper process_arguments(int argc, char **argv) { while (true) { int option = 0; - int option_index = getopt_long(argc, argv, "+?VqhvefCt:c:w:K:W:u:p:x:X:N:mklLPg:R:r:i:I:MEAn", longopts, &option); + int option_index = getopt_long( + argc, argv, "+?VqhvefCt:c:w:K:W:u:p:x:X:N:mklLPg:R:r:i:I:MEAn", longopts, &option); if (option_index == -1 || option_index == EOF) { break; @@ -578,9 +591,10 @@ check_disk_config_wrapper process_arguments(int argc, char **argv) { result.config.display_inodes_perfdata = true; break; case 'p': /* select path */ { - if (!(warn_freespace_units || crit_freespace_units || warn_freespace_percent || crit_freespace_percent || - warn_freeinodes_percent || crit_freeinodes_percent)) { - die(STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), _("Must set a threshold value before using -p\n")); + if (!(warn_freespace_units || crit_freespace_units || warn_freespace_percent || + crit_freespace_percent || warn_freeinodes_percent || crit_freeinodes_percent)) { + die(STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), + _("Must set a threshold value before using -p\n")); } /* add parameter if not found. overwrite thresholds if path has already been added */ @@ -595,7 +609,8 @@ check_disk_config_wrapper process_arguments(int argc, char **argv) { // } } search_entry->group = group; - set_all_thresholds(search_entry, warn_freespace_units, crit_freespace_units, warn_freespace_percent, crit_freespace_percent, + set_all_thresholds(search_entry, warn_freespace_units, crit_freespace_units, + warn_freespace_percent, crit_freespace_percent, warn_freeinodes_percent, crit_freeinodes_percent); @@ -603,7 +618,8 @@ check_disk_config_wrapper process_arguments(int argc, char **argv) { // if (!stat_path(se, result.config.ignore_missing)) { // break; // } - mp_int_fs_list_set_best_match(result.config.path_select_list, result.config.mount_list, result.config.exact_match); + mp_int_fs_list_set_best_match(result.config.path_select_list, result.config.mount_list, + result.config.exact_match); path_selected = true; } break; @@ -615,7 +631,8 @@ check_disk_config_wrapper process_arguments(int argc, char **argv) { if (err != 0) { char errbuf[MAX_INPUT_BUFFER]; regerror(err, &result.config.fs_exclude_list->regex, errbuf, MAX_INPUT_BUFFER); - die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf); + die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), + _("Could not compile regular expression"), errbuf); } break; case 'N': /* include file system type */ @@ -623,7 +640,8 @@ check_disk_config_wrapper process_arguments(int argc, char **argv) { if (err != 0) { char errbuf[MAX_INPUT_BUFFER]; regerror(err, &result.config.fs_exclude_list->regex, errbuf, MAX_INPUT_BUFFER); - die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf); + die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), + _("Could not compile regular expression"), errbuf); } } break; case 'v': /* verbose */ @@ -638,7 +656,8 @@ check_disk_config_wrapper process_arguments(int argc, char **argv) { break; case 'E': if (path_selected) { - die(STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), _("Must set -E before selecting paths\n")); + die(STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), + _("Must set -E before selecting paths\n")); } result.config.exact_match = true; break; @@ -647,7 +666,8 @@ check_disk_config_wrapper process_arguments(int argc, char **argv) { break; case 'g': if (path_selected) { - die(STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), _("Must set group value before selecting paths\n")); + die(STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), + _("Must set group value before selecting paths\n")); } group = optarg; break; @@ -657,14 +677,16 @@ check_disk_config_wrapper process_arguments(int argc, char **argv) { case 'i': { if (!path_selected) { die(STATE_UNKNOWN, "DISK %s: %s\n", _("UNKNOWN"), - _("Paths need to be selected before using -i/-I. Use -A to select all paths explicitly")); + _("Paths need to be selected before using -i/-I. Use -A to select all paths " + "explicitly")); } regex_t regex; int err = regcomp(®ex, optarg, cflags); if (err != 0) { char errbuf[MAX_INPUT_BUFFER]; regerror(err, ®ex, errbuf, MAX_INPUT_BUFFER); - die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf); + die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), + _("Could not compile regular expression"), errbuf); } for (parameter_list_elem *elem = result.config.path_select_list.first; elem;) { @@ -695,10 +717,11 @@ check_disk_config_wrapper process_arguments(int argc, char **argv) { cflags |= REG_ICASE; // Intentional fallthrough case 'r': { - if (!(warn_freespace_units || crit_freespace_units || warn_freespace_percent || crit_freespace_percent || - warn_freeinodes_percent || crit_freeinodes_percent)) { + if (!(warn_freespace_units || crit_freespace_units || warn_freespace_percent || + crit_freespace_percent || warn_freeinodes_percent || crit_freeinodes_percent)) { die(STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), - _("Must set a threshold value before using -r/-R/-A (--ereg-path/--eregi-path/--all)\n")); + _("Must set a threshold value before using -r/-R/-A " + "(--ereg-path/--eregi-path/--all)\n")); } regex_t regex; @@ -706,7 +729,8 @@ check_disk_config_wrapper process_arguments(int argc, char **argv) { if (err != 0) { char errbuf[MAX_INPUT_BUFFER]; regerror(err, ®ex, errbuf, MAX_INPUT_BUFFER); - die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf); + die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), + _("Could not compile regular expression"), errbuf); } bool found = false; @@ -714,16 +738,21 @@ check_disk_config_wrapper process_arguments(int argc, char **argv) { if (np_regex_match_mount_entry(me, ®ex)) { found = true; if (verbose >= 3) { - printf("%s %s matching expression %s\n", me->me_devname, me->me_mountdir, optarg); + printf("%s %s matching expression %s\n", me->me_devname, me->me_mountdir, + optarg); } - /* add parameter if not found. overwrite thresholds if path has already been added */ + /* add parameter if not found. overwrite thresholds if path has already been + * added */ parameter_list_elem *se = NULL; - if (!(se = mp_int_fs_list_find(result.config.path_select_list, me->me_mountdir))) { - se = mp_int_fs_list_append(&result.config.path_select_list, me->me_mountdir); + if (!(se = mp_int_fs_list_find(result.config.path_select_list, + me->me_mountdir))) { + se = + mp_int_fs_list_append(&result.config.path_select_list, me->me_mountdir); } se->group = group; - set_all_thresholds(se, warn_freespace_units, crit_freespace_units, warn_freespace_percent, crit_freespace_percent, + set_all_thresholds(se, warn_freespace_units, crit_freespace_units, + warn_freespace_percent, crit_freespace_percent, warn_freeinodes_percent, crit_freeinodes_percent); } } @@ -735,11 +764,13 @@ check_disk_config_wrapper process_arguments(int argc, char **argv) { break; } - die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), _("Regular expression did not match any path or disk"), optarg); + die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), + _("Regular expression did not match any path or disk"), optarg); } path_selected = true; - mp_int_fs_list_set_best_match(result.config.path_select_list, result.config.mount_list, result.config.exact_match); + mp_int_fs_list_set_best_match(result.config.path_select_list, result.config.mount_list, + result.config.exact_match); cflags = default_cflags; } break; @@ -747,16 +778,20 @@ check_disk_config_wrapper process_arguments(int argc, char **argv) { result.config.display_mntp = true; break; case 'C': { - /* add all mount entries to path_select list if no partitions have been explicitly defined using -p */ + /* add all mount entries to path_select list if no partitions have been explicitly + * defined using -p */ if (!path_selected) { parameter_list_elem *path; for (struct mount_entry *me = result.config.mount_list; me; me = me->me_next) { - if (!(path = mp_int_fs_list_find(result.config.path_select_list, me->me_mountdir))) { - path = mp_int_fs_list_append(&result.config.path_select_list, me->me_mountdir); + if (!(path = mp_int_fs_list_find(result.config.path_select_list, + me->me_mountdir))) { + path = + mp_int_fs_list_append(&result.config.path_select_list, me->me_mountdir); } path->best_match = me; path->group = group; - set_all_thresholds(path, warn_freespace_units, crit_freespace_units, warn_freespace_percent, crit_freespace_percent, + set_all_thresholds(path, warn_freespace_units, crit_freespace_units, + warn_freespace_percent, crit_freespace_percent, warn_freeinodes_percent, crit_freeinodes_percent); } } @@ -843,10 +878,12 @@ check_disk_config_wrapper process_arguments(int argc, char **argv) { if (verbose > 0) { printf("Got an positional filesystem: %s\n", argv[index]); } - struct parameter_list *se = mp_int_fs_list_append(&result.config.path_select_list, strdup(argv[index++])); + struct parameter_list *se = + mp_int_fs_list_append(&result.config.path_select_list, strdup(argv[index++])); path_selected = true; - set_all_thresholds(se, warn_freespace_units, crit_freespace_units, warn_freespace_percent, crit_freespace_percent, - warn_freeinodes_percent, crit_freeinodes_percent); + set_all_thresholds(se, warn_freespace_units, crit_freespace_units, warn_freespace_percent, + crit_freespace_percent, warn_freeinodes_percent, + crit_freeinodes_percent); } // If a list of paths has not been explicitly selected, find entire @@ -864,18 +901,21 @@ check_disk_config_wrapper process_arguments(int argc, char **argv) { } path->best_match = me; path->group = group; - set_all_thresholds(path, warn_freespace_units, crit_freespace_units, warn_freespace_percent, crit_freespace_percent, + set_all_thresholds(path, warn_freespace_units, crit_freespace_units, + warn_freespace_percent, crit_freespace_percent, warn_freeinodes_percent, crit_freeinodes_percent); } } // Set thresholds to the appropriate unit - for (parameter_list_elem *tmp = result.config.path_select_list.first; tmp; tmp = mp_int_fs_list_get_next(tmp)) { + for (parameter_list_elem *tmp = result.config.path_select_list.first; tmp; + tmp = mp_int_fs_list_get_next(tmp)) { mp_perfdata_value factor = mp_create_pd_value(unit); if (tmp->freespace_units.critical_is_set) { - tmp->freespace_units.critical = mp_range_multiply(tmp->freespace_units.critical, factor); + tmp->freespace_units.critical = + mp_range_multiply(tmp->freespace_units.critical, factor); } if (tmp->freespace_units.warning_is_set) { tmp->freespace_units.warning = mp_range_multiply(tmp->freespace_units.warning, factor); @@ -885,8 +925,10 @@ check_disk_config_wrapper process_arguments(int argc, char **argv) { return result; } -void set_all_thresholds(parameter_list_elem *path, char *warn_freespace_units, char *crit_freespace_units, char *warn_freespace_percent, - char *crit_freespace_percent, char *warn_freeinodes_percent, char *crit_freeinodes_percent) { +void set_all_thresholds(parameter_list_elem *path, char *warn_freespace_units, + char *crit_freespace_units, char *warn_freespace_percent, + char *crit_freespace_percent, char *warn_freeinodes_percent, + char *crit_freeinodes_percent) { mp_range_parsed tmp; if (warn_freespace_units) { @@ -927,7 +969,8 @@ void print_help(void) { printf(COPYRIGHT, copyright, email); printf("%s\n", _("This plugin checks the amount of used disk space on a mounted file system")); - printf("%s\n", _("and generates an alert if free space is less than one of the threshold values")); + printf("%s\n", + _("and generates an alert if free space is less than one of the threshold values")); printf("\n\n"); @@ -949,7 +992,8 @@ void print_help(void) { printf(" %s\n", "-K, --icritical=PERCENT%"); printf(" %s\n", _("Exit with CRITICAL status if less than PERCENT of inode space is free")); printf(" %s\n", "-p, --path=PATH, --partition=PARTITION"); - printf(" %s\n", _("Mount point or block device as emitted by the mount(8) command (may be repeated)")); + printf(" %s\n", + _("Mount point or block device as emitted by the mount(8) command (may be repeated)")); printf(" %s\n", "-x, --exclude_device=PATH "); printf(" %s\n", _("Ignore device (only works if -p unspecified)")); printf(" %s\n", "-C, --clear"); @@ -963,71 +1007,88 @@ void print_help(void) { printf(" %s\n", "-P, --iperfdata"); printf(" %s\n", _("Display inode usage in perfdata")); printf(" %s\n", "-g, --group=NAME"); - printf(" %s\n", _("Group paths. Thresholds apply to (free-)space of all partitions together")); + printf(" %s\n", + _("Group paths. Thresholds apply to (free-)space of all partitions together")); printf(" %s\n", "-l, --local"); printf(" %s\n", _("Only check local filesystems")); printf(" %s\n", "-L, --stat-remote-fs"); - printf(" %s\n", _("Only check local filesystems against thresholds. Yet call stat on remote filesystems")); + printf( + " %s\n", + _("Only check local filesystems against thresholds. Yet call stat on remote filesystems")); printf(" %s\n", _("to test if they are accessible (e.g. to detect Stale NFS Handles)")); printf(" %s\n", "-M, --mountpoint"); printf(" %s\n", _("Display the (block) device instead of the mount point")); printf(" %s\n", "-A, --all"); printf(" %s\n", _("Explicitly select all paths. This is equivalent to -R '.*'")); printf(" %s\n", "-R, --eregi-path=PATH, --eregi-partition=PARTITION"); - printf(" %s\n", _("Case insensitive regular expression for path/partition (may be repeated)")); + printf(" %s\n", + _("Case insensitive regular expression for path/partition (may be repeated)")); printf(" %s\n", "-r, --ereg-path=PATH, --ereg-partition=PARTITION"); printf(" %s\n", _("Regular expression for path or partition (may be repeated)")); printf(" %s\n", "-I, --ignore-eregi-path=PATH, --ignore-eregi-partition=PARTITION"); - printf(" %s\n", _("Regular expression to ignore selected path/partition (case insensitive) (may be repeated)")); + printf(" %s\n", _("Regular expression to ignore selected path/partition (case insensitive) " + "(may be repeated)")); printf(" %s\n", "-i, --ignore-ereg-path=PATH, --ignore-ereg-partition=PARTITION"); - printf(" %s\n", _("Regular expression to ignore selected path or partition (may be repeated)")); + printf(" %s\n", + _("Regular expression to ignore selected path or partition (may be repeated)")); printf(" %s\n", "-n, --ignore-missing"); - printf(" %s\n", _("Return OK if no filesystem matches, filesystem does not exist or is inaccessible.")); + printf(" %s\n", + _("Return OK if no filesystem matches, filesystem does not exist or is inaccessible.")); printf(" %s\n", _("(Provide this option before -p / -r / --ereg-path if used)")); printf(UT_PLUG_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); printf(" %s\n", "-u, --units=STRING"); printf(" %s\n", _("Select the unit used for the absolute value thresholds")); - printf( - " %s\n", - _("Choose one of \"bytes\", \"KiB\", \"kB\", \"MiB\", \"MB\", \"GiB\", \"GB\", \"TiB\", \"TB\", \"PiB\", \"PB\" (default: MiB)")); + printf(" %s\n", _("Choose one of \"bytes\", \"KiB\", \"kB\", \"MiB\", \"MB\", \"GiB\", " + "\"GB\", \"TiB\", \"TB\", \"PiB\", \"PB\" (default: MiB)")); printf(" %s\n", "-k, --kilobytes"); printf(" %s\n", _("Same as '--units kB'")); printf(" %s\n", "--display-unit"); printf(" %s\n", _("Select the unit used for in the output")); - printf( - " %s\n", - _("Choose one of \"bytes\", \"KiB\", \"kB\", \"MiB\", \"MB\", \"GiB\", \"GB\", \"TiB\", \"TB\", \"PiB\", \"PB\" (default: MiB)")); + printf(" %s\n", _("Choose one of \"bytes\", \"KiB\", \"kB\", \"MiB\", \"MB\", \"GiB\", " + "\"GB\", \"TiB\", \"TB\", \"PiB\", \"PB\" (default: MiB)")); printf(" %s\n", "-m, --megabytes"); printf(" %s\n", _("Same as '--units MB'")); printf(UT_VERBOSE); printf(" %s\n", "-X, --exclude-type=TYPE_REGEX"); - printf(" %s\n", _("Ignore all filesystems of types matching given regex(7) (may be repeated)")); + printf(" %s\n", + _("Ignore all filesystems of types matching given regex(7) (may be repeated)")); printf(" %s\n", "-N, --include-type=TYPE_REGEX"); - printf(" %s\n", _("Check only filesystems where the type matches this given regex(7) (may be repeated)")); + printf( + " %s\n", + _("Check only filesystems where the type matches this given regex(7) (may be repeated)")); printf(UT_OUTPUT_FORMAT); printf("\n"); printf("%s\n", _("General usage hints:")); - printf(" %s\n", _("- Arguments are positional! \"-w 5 -c 1 -p /foo -w6 -c2 -p /bar\" is not the same as")); + printf( + " %s\n", + _("- Arguments are positional! \"-w 5 -c 1 -p /foo -w6 -c2 -p /bar\" is not the same as")); printf(" %s\n", _("\"-w 5 -c 1 -p /bar w6 -c2 -p /foo\".")); - printf(" %s\n", _("- The syntax is broadly: \"{thresholds a} {paths a} -C {thresholds b} {thresholds b} ...\"")); + printf(" %s\n", _("- The syntax is broadly: \"{thresholds a} {paths a} -C {thresholds b} " + "{thresholds b} ...\"")); printf("\n"); printf("%s\n", _("Examples:")); printf(" %s\n", "check_disk -w 10% -c 5% -p /tmp -p /var -C -w 100000 -c 50000 -p /"); printf(" %s\n\n", _("Checks /tmp and /var at 10% and 5%, and / at 100MB and 50MB")); - printf(" %s\n", "check_disk -w 100 -c 50 -C -w 1000 -c 500 -g sidDATA -r '^/oracle/SID/data.*$'"); - printf(" %s\n", _("Checks all filesystems not matching -r at 100M and 50M. The fs matching the -r regex")); - printf(" %s\n\n", _("are grouped which means the freespace thresholds are applied to all disks together")); + printf(" %s\n", + "check_disk -w 100 -c 50 -C -w 1000 -c 500 -g sidDATA -r '^/oracle/SID/data.*$'"); + printf( + " %s\n", + _("Checks all filesystems not matching -r at 100M and 50M. The fs matching the -r regex")); + printf(" %s\n\n", + _("are grouped which means the freespace thresholds are applied to all disks together")); printf(" %s\n", "check_disk -w 100 -c 50 -C -w 1000 -c 500 -p /foo -C -w 5% -c 3% -p /bar"); - printf(" %s\n", _("Checks /foo for 1000M/500M and /bar for 5/3%. All remaining volumes use 100M/50M")); + printf(" %s\n", + _("Checks /foo for 1000M/500M and /bar for 5/3%. All remaining volumes use 100M/50M")); printf(UT_SUPPORT); } void print_usage(void) { printf("%s\n", _("Usage:")); - printf(" %s {-w absolute_limit |-w percentage_limit%% | -W inode_percentage_limit } {-c absolute_limit|-c percentage_limit%% | -K " + printf(" %s {-w absolute_limit |-w percentage_limit%% | -W inode_percentage_limit } {-c " + "absolute_limit|-c percentage_limit%% | -K " "inode_percentage_limit } {-p path | -x device}\n", progname); printf("[-C] [-E] [-e] [-f] [-g group ] [-k] [-l] [-M] [-m] [-R path ] [-r path ]\n"); @@ -1049,13 +1110,15 @@ bool stat_path(parameter_list_elem *parameters, bool ignore_missing) { return false; } printf("DISK %s - ", _("CRITICAL")); - die(STATE_CRITICAL, _("%s %s: %s\n"), parameters->name, _("is not accessible"), strerror(errno)); + die(STATE_CRITICAL, _("%s %s: %s\n"), parameters->name, _("is not accessible"), + strerror(errno)); } return true; } -static parameter_list_elem get_path_stats(parameter_list_elem parameters, const struct fs_usage fsp, bool freespace_ignore_reserved) { +static parameter_list_elem get_path_stats(parameter_list_elem parameters, const struct fs_usage fsp, + bool freespace_ignore_reserved) { uintmax_t available = fsp.fsu_bavail; uintmax_t available_to_root = fsp.fsu_bfree; uintmax_t used = fsp.fsu_blocks - fsp.fsu_bfree; @@ -1082,7 +1145,8 @@ static parameter_list_elem get_path_stats(parameter_list_elem parameters, const /* option activated : we subtract the root-reserved inodes from the total */ /* not all OS report fsp->fsu_favail, only the ones with statvfs syscall */ /* for others, fsp->fsu_ffree == fsp->fsu_favail */ - parameters.inodes_total = fsp.fsu_files - parameters.inodes_free_to_root + parameters.inodes_free; + parameters.inodes_total = + fsp.fsu_files - parameters.inodes_free_to_root + parameters.inodes_free; } else { /* default behaviour : take all the inodes into account */ parameters.inodes_total = fsp.fsu_files; @@ -1091,7 +1155,8 @@ static parameter_list_elem get_path_stats(parameter_list_elem parameters, const return parameters; } -mp_subcheck evaluate_filesystem(measurement_unit measurement_unit, bool display_inodes_perfdata, byte_unit unit) { +mp_subcheck evaluate_filesystem(measurement_unit measurement_unit, bool display_inodes_perfdata, + byte_unit unit) { mp_subcheck result = mp_subcheck_init(); result = mp_set_subcheck_default_state(result, STATE_UNKNOWN); xasprintf(&result.output, "%s", measurement_unit.name); @@ -1108,10 +1173,12 @@ mp_subcheck evaluate_filesystem(measurement_unit measurement_unit, bool display_ freespace_bytes_sc = mp_set_subcheck_default_state(freespace_bytes_sc, STATE_OK); if (unit != Humanized) { - xasprintf(&freespace_bytes_sc.output, "Free space absolute: %ju%s (of %ju%s)", (uintmax_t)(measurement_unit.free_bytes / unit), - get_unit_string(unit), (uintmax_t)(measurement_unit.total_bytes / unit), get_unit_string(unit)); + xasprintf(&freespace_bytes_sc.output, "Free space absolute: %ju%s (of %ju%s)", + (uintmax_t)(measurement_unit.free_bytes / unit), get_unit_string(unit), + (uintmax_t)(measurement_unit.total_bytes / unit), get_unit_string(unit)); } else { - xasprintf(&freespace_bytes_sc.output, "Free space absolute: %s (of %s)", humanize_byte_value(measurement_unit.free_bytes, false), + xasprintf(&freespace_bytes_sc.output, "Free space absolute: %s (of %s)", + humanize_byte_value(measurement_unit.free_bytes, false), humanize_byte_value((unsigned long long)measurement_unit.total_bytes, false)); } @@ -1127,29 +1194,37 @@ mp_subcheck evaluate_filesystem(measurement_unit measurement_unit, bool display_ // special case for absolute space thresholds here: // if absolute values are not set, compute the thresholds from percentage thresholds mp_thresholds temp_thlds = measurement_unit.freespace_bytes_thresholds; - if (!temp_thlds.critical_is_set && measurement_unit.freespace_percent_thresholds.critical_is_set) { + if (!temp_thlds.critical_is_set && + measurement_unit.freespace_percent_thresholds.critical_is_set) { mp_range tmp_range = measurement_unit.freespace_percent_thresholds.critical; if (!tmp_range.end_infinity) { - tmp_range.end = mp_create_pd_value(mp_get_pd_value(tmp_range.end) / 100 * measurement_unit.total_bytes); + tmp_range.end = mp_create_pd_value(mp_get_pd_value(tmp_range.end) / 100 * + measurement_unit.total_bytes); } if (!tmp_range.start_infinity) { - tmp_range.start = mp_create_pd_value(mp_get_pd_value(tmp_range.start) / 100 * measurement_unit.total_bytes); + tmp_range.start = mp_create_pd_value(mp_get_pd_value(tmp_range.start) / 100 * + measurement_unit.total_bytes); } - measurement_unit.freespace_bytes_thresholds = mp_thresholds_set_crit(measurement_unit.freespace_bytes_thresholds, tmp_range); + measurement_unit.freespace_bytes_thresholds = + mp_thresholds_set_crit(measurement_unit.freespace_bytes_thresholds, tmp_range); used_space = mp_pd_set_thresholds(used_space, measurement_unit.freespace_bytes_thresholds); } - if (!temp_thlds.warning_is_set && measurement_unit.freespace_percent_thresholds.warning_is_set) { + if (!temp_thlds.warning_is_set && + measurement_unit.freespace_percent_thresholds.warning_is_set) { mp_range tmp_range = measurement_unit.freespace_percent_thresholds.warning; if (!tmp_range.end_infinity) { - tmp_range.end = mp_create_pd_value(mp_get_pd_value(tmp_range.end) / 100 * measurement_unit.total_bytes); + tmp_range.end = mp_create_pd_value(mp_get_pd_value(tmp_range.end) / 100 * + measurement_unit.total_bytes); } if (!tmp_range.start_infinity) { - tmp_range.start = mp_create_pd_value(mp_get_pd_value(tmp_range.start) / 100 * measurement_unit.total_bytes); + tmp_range.start = mp_create_pd_value(mp_get_pd_value(tmp_range.start) / 100 * + measurement_unit.total_bytes); } - measurement_unit.freespace_bytes_thresholds = mp_thresholds_set_warn(measurement_unit.freespace_bytes_thresholds, tmp_range); + measurement_unit.freespace_bytes_thresholds = + mp_thresholds_set_warn(measurement_unit.freespace_bytes_thresholds, tmp_range); used_space = mp_pd_set_thresholds(used_space, measurement_unit.freespace_bytes_thresholds); } @@ -1161,15 +1236,18 @@ mp_subcheck evaluate_filesystem(measurement_unit measurement_unit, bool display_ mp_subcheck freespace_percent_sc = mp_subcheck_init(); freespace_percent_sc = mp_set_subcheck_default_state(freespace_percent_sc, STATE_OK); - double free_percentage = calculate_percent(measurement_unit.free_bytes, measurement_unit.total_bytes); + double free_percentage = + calculate_percent(measurement_unit.free_bytes, measurement_unit.total_bytes); xasprintf(&freespace_percent_sc.output, "Free space percentage: %g%%", free_percentage); // Using perfdata here just to get to the test result mp_perfdata free_space_percent_pd = perfdata_init(); free_space_percent_pd.value = mp_create_pd_value(free_percentage); - free_space_percent_pd = mp_pd_set_thresholds(free_space_percent_pd, measurement_unit.freespace_percent_thresholds); + free_space_percent_pd = + mp_pd_set_thresholds(free_space_percent_pd, measurement_unit.freespace_percent_thresholds); - freespace_percent_sc = mp_set_subcheck_state(freespace_percent_sc, mp_get_pd_status(free_space_percent_pd)); + freespace_percent_sc = + mp_set_subcheck_state(freespace_percent_sc, mp_get_pd_status(free_space_percent_pd)); mp_add_subcheck_to_subcheck(&result, freespace_percent_sc); // ================ @@ -1181,35 +1259,41 @@ mp_subcheck evaluate_filesystem(measurement_unit measurement_unit, bool display_ mp_subcheck freeindodes_percent_sc = mp_subcheck_init(); freeindodes_percent_sc = mp_set_subcheck_default_state(freeindodes_percent_sc, STATE_OK); - double free_inode_percentage = calculate_percent(measurement_unit.inodes_free, measurement_unit.inodes_total); + double free_inode_percentage = + calculate_percent(measurement_unit.inodes_free, measurement_unit.inodes_total); if (verbose > 0) { printf("free inode percentage computed: %g\n", free_inode_percentage); } - xasprintf(&freeindodes_percent_sc.output, "Inodes free: %g%% (%ju of %ju)", free_inode_percentage, measurement_unit.inodes_free, + xasprintf(&freeindodes_percent_sc.output, "Inodes free: %g%% (%ju of %ju)", + free_inode_percentage, measurement_unit.inodes_free, measurement_unit.inodes_total); mp_perfdata inodes_pd = perfdata_init(); xasprintf(&inodes_pd.label, "%s (inodes)", measurement_unit.name); inodes_pd = mp_set_pd_value(inodes_pd, measurement_unit.inodes_used); - inodes_pd = mp_set_pd_max_value(inodes_pd, mp_create_pd_value(measurement_unit.inodes_total)); + inodes_pd = + mp_set_pd_max_value(inodes_pd, mp_create_pd_value(measurement_unit.inodes_total)); inodes_pd = mp_set_pd_min_value(inodes_pd, mp_create_pd_value(0)); mp_thresholds absolut_inode_thresholds = measurement_unit.freeinodes_percent_thresholds; if (absolut_inode_thresholds.critical_is_set) { absolut_inode_thresholds.critical = - mp_range_multiply(absolut_inode_thresholds.critical, mp_create_pd_value(measurement_unit.inodes_total / 100)); + mp_range_multiply(absolut_inode_thresholds.critical, + mp_create_pd_value(measurement_unit.inodes_total / 100)); } if (absolut_inode_thresholds.warning_is_set) { absolut_inode_thresholds.warning = - mp_range_multiply(absolut_inode_thresholds.warning, mp_create_pd_value(measurement_unit.inodes_total / 100)); + mp_range_multiply(absolut_inode_thresholds.warning, + mp_create_pd_value(measurement_unit.inodes_total / 100)); } inodes_pd = mp_pd_set_thresholds(inodes_pd, absolut_inode_thresholds); - freeindodes_percent_sc = mp_set_subcheck_state(freeindodes_percent_sc, mp_get_pd_status(inodes_pd)); + freeindodes_percent_sc = + mp_set_subcheck_state(freeindodes_percent_sc, mp_get_pd_status(inodes_pd)); if (display_inodes_perfdata) { mp_add_perfdata_to_subcheck(&freeindodes_percent_sc, inodes_pd); } diff --git a/plugins/check_disk.d/utils_disk.c b/plugins/check_disk.d/utils_disk.c index eec1282b..0b89018d 100644 --- a/plugins/check_disk.d/utils_disk.c +++ b/plugins/check_disk.d/utils_disk.c @@ -126,7 +126,8 @@ bool np_find_regmatch(struct regex_list *list, const char *name) { /* Emulate a full match as if surrounded with ^( )$ by checking whether the match spans the whole name */ regmatch_t dummy_match; - if (!regexec(&list->regex, name, 1, &dummy_match, 0) && dummy_match.rm_so == 0 && dummy_match.rm_eo == len) { + if (!regexec(&list->regex, name, 1, &dummy_match, 0) && dummy_match.rm_so == 0 && + dummy_match.rm_eo == len) { return true; } } @@ -144,7 +145,8 @@ bool np_seen_name(struct name_list *list, const char *name) { } bool np_regex_match_mount_entry(struct mount_entry *me, regex_t *re) { - return ((regexec(re, me->me_devname, (size_t)0, NULL, 0) == 0) || (regexec(re, me->me_mountdir, (size_t)0, NULL, 0) == 0)); + return ((regexec(re, me->me_devname, (size_t)0, NULL, 0) == 0) || + (regexec(re, me->me_mountdir, (size_t)0, NULL, 0) == 0)); } check_disk_config check_disk_config_init() { @@ -264,7 +266,8 @@ measurement_unit_list *add_measurement_list(measurement_unit_list *list, measure return new; } -measurement_unit add_filesystem_to_measurement_unit(measurement_unit unit, parameter_list_elem filesystem) { +measurement_unit add_filesystem_to_measurement_unit(measurement_unit unit, + parameter_list_elem filesystem) { unit.free_bytes += filesystem.free_bytes; unit.used_bytes += filesystem.used_bytes; @@ -277,7 +280,8 @@ measurement_unit add_filesystem_to_measurement_unit(measurement_unit unit, param return unit; } -measurement_unit create_measurement_unit_from_filesystem(parameter_list_elem filesystem, bool display_mntp) { +measurement_unit create_measurement_unit_from_filesystem(parameter_list_elem filesystem, + bool display_mntp) { measurement_unit result = measurement_unit_init(); if (!display_mntp) { result.name = strdup(filesystem.best_match->me_mountdir); @@ -469,17 +473,20 @@ parameter_list_elem *mp_int_fs_list_get_next(parameter_list_elem *current) { return current->next; } -void mp_int_fs_list_set_best_match(filesystem_list list, struct mount_entry *mount_list, bool exact) { +void mp_int_fs_list_set_best_match(filesystem_list list, struct mount_entry *mount_list, + bool exact) { for (parameter_list_elem *elem = list.first; elem; elem = mp_int_fs_list_get_next(elem)) { if (!elem->best_match) { size_t name_len = strlen(elem->name); struct mount_entry *best_match = NULL; /* set best match if path name exactly matches a mounted device name */ - for (struct mount_entry *mount_entry = mount_list; mount_entry; mount_entry = mount_entry->me_next) { + for (struct mount_entry *mount_entry = mount_list; mount_entry; + mount_entry = mount_entry->me_next) { if (strcmp(mount_entry->me_devname, elem->name) == 0) { struct fs_usage fsp; - if (get_fs_usage(mount_entry->me_mountdir, mount_entry->me_devname, &fsp) >= 0) { + if (get_fs_usage(mount_entry->me_mountdir, mount_entry->me_devname, &fsp) >= + 0) { best_match = mount_entry; } } @@ -488,15 +495,18 @@ void mp_int_fs_list_set_best_match(filesystem_list list, struct mount_entry *mou /* set best match by directory name if no match was found by devname */ if (!best_match) { size_t best_match_len = 0; - for (struct mount_entry *mount_entry = mount_list; mount_entry; mount_entry = mount_entry->me_next) { + for (struct mount_entry *mount_entry = mount_list; mount_entry; + mount_entry = mount_entry->me_next) { size_t len = strlen(mount_entry->me_mountdir); - if ((!exact && (best_match_len <= len && len <= name_len && - (len == 1 || strncmp(mount_entry->me_mountdir, elem->name, len) == 0))) || + if ((!exact && + (best_match_len <= len && len <= name_len && + (len == 1 || strncmp(mount_entry->me_mountdir, elem->name, len) == 0))) || (exact && strcmp(mount_entry->me_mountdir, elem->name) == 0)) { struct fs_usage fsp; - if (get_fs_usage(mount_entry->me_mountdir, mount_entry->me_devname, &fsp) >= 0) { + if (get_fs_usage(mount_entry->me_mountdir, mount_entry->me_devname, &fsp) >= + 0) { best_match = mount_entry; best_match_len = len; } @@ -507,7 +517,8 @@ void mp_int_fs_list_set_best_match(filesystem_list list, struct mount_entry *mou if (best_match) { elem->best_match = best_match; } else { - elem->best_match = NULL; /* Not sure why this is needed as it should be null on initialisation */ + elem->best_match = + NULL; /* Not sure why this is needed as it should be null on initialisation */ } // No filesystem without a mount_entry! diff --git a/plugins/check_disk.d/utils_disk.h b/plugins/check_disk.d/utils_disk.h index 6831d1fd..c96d4296 100644 --- a/plugins/check_disk.d/utils_disk.h +++ b/plugins/check_disk.d/utils_disk.h @@ -141,12 +141,15 @@ parameter_list_elem *mp_int_fs_list_append(filesystem_list *list, const char *na parameter_list_elem *mp_int_fs_list_find(filesystem_list list, const char *name); parameter_list_elem *mp_int_fs_list_del(filesystem_list *list, parameter_list_elem *item); parameter_list_elem *mp_int_fs_list_get_next(parameter_list_elem *current); -void mp_int_fs_list_set_best_match(filesystem_list list, struct mount_entry *mount_list, bool exact); +void mp_int_fs_list_set_best_match(filesystem_list list, struct mount_entry *mount_list, + bool exact); measurement_unit measurement_unit_init(); measurement_unit_list *add_measurement_list(measurement_unit_list *list, measurement_unit elem); -measurement_unit add_filesystem_to_measurement_unit(measurement_unit unit, parameter_list_elem filesystem); -measurement_unit create_measurement_unit_from_filesystem(parameter_list_elem filesystem, bool display_mntp); +measurement_unit add_filesystem_to_measurement_unit(measurement_unit unit, + parameter_list_elem filesystem); +measurement_unit create_measurement_unit_from_filesystem(parameter_list_elem filesystem, + bool display_mntp); int search_parameter_list(parameter_list_elem *list, const char *name); bool np_regex_match_mount_entry(struct mount_entry *, regex_t *); diff --git a/plugins/check_dns.c b/plugins/check_dns.c index 95f33083..56f91dae 100644 --- a/plugins/check_dns.c +++ b/plugins/check_dns.c @@ -48,7 +48,8 @@ typedef struct { } 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 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); @@ -127,7 +128,8 @@ int main(int argc, char **argv) { puts(chld_out.line[i]); } - if (strcasestr(chld_out.line[i], ".in-addr.arpa") || strcasestr(chld_out.line[i], ".ip6.arpa")) { + if (strcasestr(chld_out.line[i], ".in-addr.arpa") || + strcasestr(chld_out.line[i], ".ip6.arpa")) { if ((strstr(chld_out.line[i], "canonical name = ") != NULL)) { continue; } @@ -145,7 +147,8 @@ int main(int argc, char **argv) { 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); + die(STATE_UNKNOWN, _("'%s' returned a weirdly formatted Server line\n"), + NSLOOKUP_COMMAND); } temp_buffer++; @@ -157,21 +160,25 @@ int main(int argc, char **argv) { strip(temp_buffer); if (strlen(temp_buffer) == 0) { - die(STATE_CRITICAL, _("DNS CRITICAL - '%s' returned empty server string\n"), NSLOOKUP_COMMAND); + die(STATE_CRITICAL, _("DNS CRITICAL - '%s' returned empty server string\n"), + NSLOOKUP_COMMAND); } if (strcmp(temp_buffer, config.dns_server) != 0) { - die(STATE_CRITICAL, _("DNS CRITICAL - No response from DNS %s\n"), config.dns_server); + 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:")) { parse_address = true; - } else if (parse_address && (strstr(chld_out.line[i], "Address:") || strstr(chld_out.line[i], "Addresses:"))) { + } 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); + die(STATE_UNKNOWN, _("'%s' returned a weirdly formatted Address line\n"), + NSLOOKUP_COMMAND); } temp_buffer++; @@ -183,7 +190,8 @@ int main(int argc, char **argv) { strip(temp_buffer); if (strlen(temp_buffer) == 0) { - die(STATE_CRITICAL, _("DNS CRITICAL - '%s' returned empty host name string\n"), NSLOOKUP_COMMAND); + die(STATE_CRITICAL, _("DNS CRITICAL - '%s' returned empty host name string\n"), + NSLOOKUP_COMMAND); } addresses[n_addresses++] = strdup(temp_buffer); @@ -209,7 +217,8 @@ int main(int argc, char **argv) { } 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)); + result = + max_state(result, error_scan(chld_err.line[i], &is_nxdomain, config.dns_server)); msg = strchr(input_buffer, ':'); if (msg) { msg++; @@ -242,7 +251,8 @@ int main(int argc, char **argv) { } *adrp = 0; } else { - die(STATE_CRITICAL, _("DNS CRITICAL - '%s' msg parsing exited with no address\n"), NSLOOKUP_COMMAND); + die(STATE_CRITICAL, _("DNS CRITICAL - '%s' msg parsing exited with no address\n"), + NSLOOKUP_COMMAND); } /* compare to expected address */ @@ -255,7 +265,8 @@ int main(int argc, char **argv) { for (size_t i = 0; i < config.expected_address_cnt; i++) { /* check if we get a match on 'raw' ip or cidr */ 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])) { + 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); @@ -279,7 +290,8 @@ int main(int argc, char **argv) { if (config.expect_nxdomain) { if (!is_nxdomain) { result = STATE_CRITICAL; - xasprintf(&msg, _("Domain '%s' was found by the server: '%s'\n"), config.query_address, address); + xasprintf(&msg, _("Domain '%s' was found by the server: '%s'\n"), config.query_address, + address); } else { if (address != NULL) { free(address); @@ -291,7 +303,8 @@ int main(int argc, char **argv) { /* check if authoritative */ if (result == STATE_OK && config.expect_authority && non_authoritative) { result = STATE_CRITICAL; - xasprintf(&msg, _("server %s is not authoritative for %s"), config.dns_server, config.query_address); + xasprintf(&msg, _("server %s is not authoritative for %s"), config.dns_server, + config.query_address); } long microsec = deltime(tv); @@ -306,24 +319,36 @@ int main(int argc, char **argv) { } else if (result == STATE_CRITICAL) { printf("DNS %s: ", _("CRITICAL")); } - printf(ngettext("%.3f second response time", "%.3f seconds response time", elapsed_time), elapsed_time); + printf(ngettext("%.3f second response time", "%.3f seconds response time", elapsed_time), + elapsed_time); 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, + 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", 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 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)); + printf("|%s\n", + fperfdata("time", elapsed_time, "s", false, 0, false, 0, true, 0, false, 0)); } } else if (result == STATE_WARNING) { - printf(_("DNS WARNING - %s\n"), !strcmp(msg, "") ? _(" Probably a non-existent host/domain") : msg); + printf(_("DNS WARNING - %s\n"), + !strcmp(msg, "") ? _(" Probably a non-existent host/domain") : msg); } else if (result == STATE_CRITICAL) { - printf(_("DNS CRITICAL - %s\n"), !strcmp(msg, "") ? _(" Probably a non-existent host/domain") : msg); + printf(_("DNS CRITICAL - %s\n"), + !strcmp(msg, "") ? _(" Probably a non-existent host/domain") : msg); } else { - printf(_("DNS UNKNOWN - %s\n"), !strcmp(msg, "") ? _(" Probably a non-existent host/domain") : msg); + printf(_("DNS UNKNOWN - %s\n"), + !strcmp(msg, "") ? _(" Probably a non-existent host/domain") : msg); } exit(result); @@ -342,29 +367,34 @@ bool ip_match_cidr(const char *addr, const char *cidr_ro) { mask = atoi(mask_c); /* https://www.cryptobells.com/verifying-ips-in-a-subnet-in-php/ */ - return (ip2long(addr) & ~((1 << (32 - mask)) - 1)) == (ip2long(subnet) >> (32 - mask)) << (32 - mask); + return (ip2long(addr) & ~((1 << (32 - mask)) - 1)) == (ip2long(subnet) >> (32 - mask)) + << (32 - mask); } unsigned long ip2long(const char *src) { unsigned long ip[4]; /* http://computer-programming-forum.com/47-c-language/1376ffb92a12c471.htm */ - return (sscanf(src, "%3lu.%3lu.%3lu.%3lu", &ip[0], &ip[1], &ip[2], &ip[3]) == 4 && ip[0] < 256 && ip[1] < 256 && ip[2] < 256 && - ip[3] < 256) + return (sscanf(src, "%3lu.%3lu.%3lu.%3lu", &ip[0], &ip[1], &ip[2], &ip[3]) == 4 && + ip[0] < 256 && ip[1] < 256 && ip[2] < 256 && ip[3] < 256) ? ip[0] << 24 | ip[1] << 16 | ip[2] << 8 | ip[3] : 0; } -mp_state_enum error_scan(char *input_buffer, bool *is_nxdomain, const char dns_server[ADDRESS_LENGTH]) { +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") || + 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) { *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")) || + 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."))) { return STATE_OK; } @@ -382,8 +412,9 @@ mp_state_enum error_scan(char *input_buffer, bool *is_nxdomain, const char dns_s } /* 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"))) { + 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"))) { die(STATE_CRITICAL, _("Connection to DNS %s was refused\n"), dns_server); } @@ -504,20 +535,24 @@ check_dns_config_wrapper process_arguments(int argc, char **argv) { if (strchr(optarg, ',') != NULL) { char *comma = strchr(optarg, ','); while (comma != NULL) { - 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 = (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, ','); } result.config.expected_address = - (char **)realloc(result.config.expected_address, (result.config.expected_address_cnt + 1) * sizeof(char **)); + (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 { result.config.expected_address = - (char **)realloc(result.config.expected_address, (result.config.expected_address_cnt + 1) * sizeof(char **)); + (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++; } @@ -586,9 +621,11 @@ void print_help(void) { printf("Copyright (c) 1999 Ethan Galstad \n"); printf(COPYRIGHT, copyright, email); - printf("%s\n", _("This plugin uses the nslookup program to obtain the IP address for the given host/domain query.")); + printf("%s\n", _("This plugin uses the nslookup program to obtain the IP address for the given " + "host/domain query.")); printf("%s\n", _("An optional DNS server to use may be specified.")); - printf("%s\n", _("If no DNS server is specified, the default server(s) specified in /etc/resolv.conf will be used.")); + printf("%s\n", _("If no DNS server is specified, the default server(s) specified in " + "/etc/resolv.conf will be used.")); printf("\n\n"); @@ -602,11 +639,14 @@ void print_help(void) { printf(" -s, --server=HOST\n"); printf(" %s\n", _("Optional DNS server you want to use for the lookup")); printf(" -a, --expected-address=IP-ADDRESS|CIDR|HOST\n"); - printf(" %s\n", _("Optional IP-ADDRESS/CIDR you expect the DNS server to return. HOST must end")); - printf(" %s\n", _("with a dot (.). This option can be repeated multiple times (Returns OK if any")); + printf(" %s\n", + _("Optional IP-ADDRESS/CIDR you expect the DNS server to return. HOST must end")); + printf(" %s\n", + _("with a dot (.). This option can be repeated multiple times (Returns OK if any")); printf(" %s\n", _("value matches).")); printf(" -n, --expect-nxdomain\n"); - printf(" %s\n", _("Expect the DNS server to return NXDOMAIN (i.e. the domain was not found)")); + printf(" %s\n", + _("Expect the DNS server to return NXDOMAIN (i.e. the domain was not found)")); printf(" %s\n", _("Cannot be used together with -a")); printf(" -A, --expect-authority\n"); printf(" %s\n", _("Optionally expect the DNS server to be authoritative for the lookup")); @@ -615,7 +655,8 @@ void print_help(void) { printf(" -c, --critical=seconds\n"); printf(" %s\n", _("Return critical if elapsed time exceeds value. Default off")); printf(" -L, --all\n"); - printf(" %s\n", _("Return critical if the list of expected addresses does not match all addresses")); + printf(" %s\n", + _("Return critical if the list of expected addresses does not match all addresses")); printf(" %s\n", _("returned. Default off")); printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); @@ -625,5 +666,7 @@ void print_help(void) { void print_usage(void) { printf("%s\n", _("Usage:")); - printf("%s -H host [-s server] [-a expected-address] [-n] [-A] [-t timeout] [-w warn] [-c crit] [-L]\n", progname); + printf("%s -H host [-s server] [-a expected-address] [-n] [-A] [-t timeout] [-w warn] [-c " + "crit] [-L]\n", + progname); } diff --git a/plugins/check_dummy.c b/plugins/check_dummy.c index 19f6c046..602d5868 100644 --- a/plugins/check_dummy.c +++ b/plugins/check_dummy.c @@ -45,18 +45,19 @@ int main(int argc, char **argv) { bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); - if (argc < 2) + if (argc < 2) { usage4(_("Could not parse arguments")); - else if (strcmp(argv[1], "-V") == 0 || strcmp(argv[1], "--version") == 0) { + } else if (strcmp(argv[1], "-V") == 0 || strcmp(argv[1], "--version") == 0) { print_revision(progname, NP_VERSION); exit(STATE_UNKNOWN); } else if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) { print_help(); exit(STATE_UNKNOWN); - } else if (!is_integer(argv[1])) + } else if (!is_integer(argv[1])) { usage4(_("Arguments to check_dummy must be an integer")); - else + } else { result = atoi(argv[1]); + } switch (result) { case STATE_OK: @@ -78,8 +79,9 @@ int main(int argc, char **argv) { return STATE_UNKNOWN; } - if (argc >= 3) + if (argc >= 3) { printf(": %s", argv[2]); + } printf("\n"); @@ -92,7 +94,8 @@ void print_help(void) { printf("Copyright (c) 1999 Ethan Galstad \n"); printf(COPYRIGHT, copyright, email); - printf("%s\n", _("This plugin will simply return the state corresponding to the numeric value")); + printf("%s\n", + _("This plugin will simply return the state corresponding to the numeric value")); printf("%s\n", _("of the argument with optional text")); diff --git a/plugins/check_fping.c b/plugins/check_fping.c index 8018e06d..6160c2cb 100644 --- a/plugins/check_fping.c +++ b/plugins/check_fping.c @@ -46,8 +46,9 @@ enum { RTA = 1 }; -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*/); +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; @@ -133,9 +134,11 @@ int main(int argc, char **argv) { if (config.icmp_timestamp) { // no packet size settable for ICMP timestamp - xasprintf(&command_line, "%s %s -c %d %s", fping_prog, option_string, config.packet_count, server); + xasprintf(&command_line, "%s %s -c %d %s", fping_prog, option_string, config.packet_count, + server); } else { - xasprintf(&command_line, "%s %s-b %d -c %d %s", fping_prog, option_string, config.packet_size, config.packet_count, server); + xasprintf(&command_line, "%s %s-b %d -c %d %s", fping_prog, option_string, + config.packet_size, config.packet_count, server); } if (verbose) { @@ -160,8 +163,9 @@ int main(int argc, char **argv) { if (verbose) { printf("%s", 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)); + 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 */ @@ -170,8 +174,9 @@ int main(int argc, char **argv) { if (verbose) { printf("%s", 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)); + 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); @@ -200,8 +205,8 @@ int main(int argc, char **argv) { return status; } -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) { +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; @@ -214,7 +219,8 @@ mp_state_enum textscan(char *buf, const char *server_name, bool crta_p, double c die(STATE_OK, _("FPING %s - %s (rta=%f ms)|%s\n"), state_text(STATE_OK), server_name, rta, /* No loss since we only waited for the first reply perfdata ("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, true, 0, true, 100), */ - fperfdata("rta", rta / 1.0e3, "s", wrta_p, wrta / 1.0e3, crta_p, crta / 1.0e3, true, 0, false, 0)); + 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; @@ -255,9 +261,11 @@ mp_state_enum textscan(char *buf, const char *server_name, bool crta_p, double c } else { status = STATE_OK; } - die(status, _("FPING %s - %s (loss=%.0f%%, rta=%f ms)|%s %s\n"), state_text(status), server_name, loss, rta, + 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, false, 0, false, 0), - fperfdata("rta", rta / 1.0e3, "s", wrta_p, wrta / 1.0e3, crta_p, crta / 1.0e3, true, 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")) { /* no min/max/avg if host was unreachable in fping v2.2.b1 */ @@ -350,7 +358,8 @@ check_fping_config_wrapper process_arguments(int argc, char **argv) { } while (true) { - int option_index = 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 (option_index == -1 || option_index == EOF || option_index == 1) { break; @@ -487,10 +496,12 @@ int get_threshold(char *arg, char *rv[2]) { if (arg2) { arg1[strcspn(arg1, ",:")] = 0; if (strstr(arg1, "%") && strstr(arg2, "%")) { - die(STATE_UNKNOWN, _("%s: Only one threshold may be packet loss (%s)\n"), progname, arg); + die(STATE_UNKNOWN, _("%s: Only one threshold may be packet loss (%s)\n"), progname, + arg); } if (!strstr(arg1, "%") && !strstr(arg2, "%")) { - die(STATE_UNKNOWN, _("%s: Only one threshold must be packet loss (%s)\n"), progname, arg); + die(STATE_UNKNOWN, _("%s: Only one threshold must be packet loss (%s)\n"), progname, + arg); } } @@ -516,7 +527,8 @@ void print_help(void) { printf("Copyright (c) 1999 Didi Rieder \n"); printf(COPYRIGHT, copyright, email); - printf("%s\n", _("This plugin will use the fping command to ping the specified host for a fast check")); + printf("%s\n", + _("This plugin will use the fping command to ping the specified host for a fast check")); printf("%s\n", _("Note that it is necessary to set the suid flag on fping.")); @@ -530,7 +542,8 @@ void print_help(void) { printf(UT_IPv46); printf(" %s\n", "-H, --hostname=HOST"); - printf(" %s\n", _("name or IP Address of host to ping (IP Address bypasses name lookup, reducing system load)")); + printf(" %s\n", _("name or IP Address of host to ping (IP Address bypasses name lookup, " + "reducing system load)")); printf(" %s\n", "-w, --warning=THRESHOLD"); printf(" %s\n", _("warning threshold pair")); printf(" %s\n", "-c, --critical=THRESHOLD"); @@ -544,7 +557,8 @@ void print_help(void) { printf(" %s\n", "-T, --target-timeout=INTEGER"); printf(" %s (default: fping's default for -t)\n", _("Target timeout (ms)")); printf(" %s\n", "-i, --interval=INTEGER"); - printf(" %s (default: fping's default for -p)\n", _("Interval (ms) between sending packets")); + printf(" %s (default: fping's default for -p)\n", + _("Interval (ms) between sending packets")); printf(" %s\n", "-S, --sourceip=HOST"); printf(" %s\n", _("name or IP Address of sourceip")); printf(" %s\n", "-I, --sourceif=IF"); @@ -565,7 +579,8 @@ void print_help(void) { #endif printf(UT_VERBOSE); printf("\n"); - printf(" %s\n", _("THRESHOLD is ,%% where is the round trip average travel time (ms)")); + printf(" %s\n", + _("THRESHOLD is ,%% where is the round trip average travel time (ms)")); printf(" %s\n", _("which triggers a WARNING or CRITICAL state, and is the percentage of")); printf(" %s\n", _("packet loss to trigger an alarm state.")); @@ -577,5 +592,6 @@ void print_help(void) { void print_usage(void) { printf("%s\n", _("Usage:")); - printf(" %s -w limit -c limit [-b size] [-n number] [-T number] [-i number]\n", progname); + printf(" %s -w limit -c limit [-b size] [-n number] [-T number] [-i number]\n", + progname); } diff --git a/plugins/check_fping.d/config.h b/plugins/check_fping.d/config.h index d95e9ded..d3e50565 100644 --- a/plugins/check_fping.d/config.h +++ b/plugins/check_fping.d/config.h @@ -36,7 +36,6 @@ typedef struct { unsigned int fwmark; bool fwmark_set; - // only available with fping version >= 5.3 // Setting icmp_timestamp tells fping to use ICMP Timestamp (ICMP type 13) instead // of ICMP Echo diff --git a/plugins/check_game.c b/plugins/check_game.c index c0193b03..974a7253 100644 --- a/plugins/check_game.c +++ b/plugins/check_game.c @@ -77,7 +77,8 @@ int main(int argc, char **argv) { /* create the command line to execute */ char *command_line = NULL; - xasprintf(&command_line, "%s -raw %s -%s %s", PATH_TO_QSTAT, QSTAT_DATA_DELIMITER, config.game_type, config.server_ip); + xasprintf(&command_line, "%s -raw %s -%s %s", PATH_TO_QSTAT, QSTAT_DATA_DELIMITER, + config.game_type, config.server_ip); if (config.port) { xasprintf(&command_line, "%s:%-d", command_line, config.port); @@ -130,11 +131,13 @@ 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[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)); + 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)); } exit(result); @@ -144,19 +147,20 @@ int main(int argc, char **argv) { #define max_players_field_index 130 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'}, - {"timeout", required_argument, 0, 't'}, - {"hostname", required_argument, 0, 'H'}, - {"port", required_argument, 0, 'P'}, - {"game-type", required_argument, 0, 'G'}, - {"map-field", required_argument, 0, 'm'}, - {"ping-field", required_argument, 0, 'p'}, - {"game-field", required_argument, 0, 'g'}, - {"players-field", required_argument, 0, players_field_index}, - {"max-players-field", required_argument, 0, max_players_field_index}, - {0, 0, 0, 0}}; + static struct option long_opts[] = { + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'V'}, + {"verbose", no_argument, 0, 'v'}, + {"timeout", required_argument, 0, 't'}, + {"hostname", required_argument, 0, 'H'}, + {"port", required_argument, 0, 'P'}, + {"game-type", required_argument, 0, 'G'}, + {"map-field", required_argument, 0, 'm'}, + {"ping-field", required_argument, 0, 'p'}, + {"game-field", required_argument, 0, 'g'}, + {"players-field", required_argument, 0, players_field_index}, + {"max-players-field", required_argument, 0, max_players_field_index}, + {0, 0, 0, 0}}; check_game_config_wrapper result = { .config = check_game_config_init(), @@ -216,21 +220,24 @@ check_game_config_wrapper process_arguments(int argc, char **argv) { break; case 'p': /* index of ping field */ result.config.qstat_ping_field = atoi(optarg); - if (result.config.qstat_ping_field < 0 || result.config.qstat_ping_field > QSTAT_MAX_RETURN_ARGS) { + 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 */ result.config.qstat_map_field = atoi(optarg); - if (result.config.qstat_map_field < 0 || result.config.qstat_map_field > QSTAT_MAX_RETURN_ARGS) { + 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 */ result.config.qstat_game_field = atoi(optarg); - if (result.config.qstat_game_field < 0 || result.config.qstat_game_field > QSTAT_MAX_RETURN_ARGS) { + if (result.config.qstat_game_field < 0 || + result.config.qstat_game_field > QSTAT_MAX_RETURN_ARGS) { result.errorcode = ERROR; return result; } @@ -240,14 +247,16 @@ check_game_config_wrapper process_arguments(int argc, char **argv) { 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) { + if (result.config.qstat_game_players < 0 || + result.config.qstat_game_players > QSTAT_MAX_RETURN_ARGS) { result.errorcode = ERROR; return result; } break; 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) { + if (result.config.qstat_game_players_max < 0 || + result.config.qstat_game_players_max > QSTAT_MAX_RETURN_ARGS) { result.errorcode = ERROR; return result; } @@ -286,7 +295,7 @@ void print_help(void) { printf(UT_HELP_VRSN); printf(UT_EXTRA_OPTS); printf(" -H, --hostname=ADDRESS\n" - " Host name, IP Address, or unix socket (must be an absolute path)\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"); @@ -300,8 +309,10 @@ void print_help(void) { printf("\n"); printf("%s\n", _("Notes:")); - printf(" %s\n", _("This plugin uses the 'qstat' command, the popular game server status query tool.")); - printf(" %s\n", _("If you don't have the package installed, you will need to download it from")); + printf(" %s\n", + _("This plugin uses the 'qstat' command, the popular game server status query tool.")); + printf(" %s\n", + _("If you don't have the package installed, you will need to download it from")); printf(" %s\n", _("https://github.com/multiplay/qstat before you can use this plugin.")); printf(UT_SUPPORT); @@ -309,7 +320,8 @@ void print_help(void) { void print_usage(void) { printf("%s\n", _("Usage:")); - printf(" %s [-hvV] [-P port] [-t timeout] [-g game_field] [-m map_field] [-p ping_field] [-G game-time] [-H hostname] " + printf(" %s [-hvV] [-P port] [-t timeout] [-g game_field] [-m map_field] [-p ping_field] [-G " + "game-time] [-H hostname] " "\n", progname); } diff --git a/plugins/check_hpjd.c b/plugins/check_hpjd.c index 62417fd6..9907abc5 100644 --- a/plugins/check_hpjd.c +++ b/plugins/check_hpjd.c @@ -85,13 +85,16 @@ int main(int argc, char **argv) { 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, - HPJD_INTERVENTION_REQUIRED, HPJD_GD_PERIPHERAL_ERROR, HPJD_GD_PAPER_JAM, HPJD_GD_PAPER_OUT, HPJD_GD_TONER_LOW, - HPJD_GD_PAGE_PUNT, HPJD_GD_MEMORY_OUT, HPJD_GD_DOOR_OPEN, HPJD_GD_PAPER_OUTPUT, HPJD_GD_STATUS_DISPLAY); + 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, HPJD_INTERVENTION_REQUIRED, + HPJD_GD_PERIPHERAL_ERROR, HPJD_GD_PAPER_JAM, HPJD_GD_PAPER_OUT, HPJD_GD_TONER_LOW, + 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 */ 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); + 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); @@ -177,7 +180,8 @@ int main(int argc, char **argv) { strcpy(display_message, temp_buffer + 1); break; default: /* fold multiline message */ - strncat(display_message, input_buffer, sizeof(display_message) - strlen(display_message) - 1); + strncat(display_message, input_buffer, + sizeof(display_message) - strlen(display_message) - 1); } } diff --git a/plugins/check_ldap.c b/plugins/check_ldap.c index 597644bd..77a33304 100644 --- a/plugins/check_ldap.c +++ b/plugins/check_ldap.c @@ -108,7 +108,8 @@ int main(int argc, char *argv[]) { #ifdef HAVE_LDAP_SET_OPTION /* set ldap options */ - if (ldap_set_option(ldap_connection, LDAP_OPT_PROTOCOL_VERSION, &config.ld_protocol) != LDAP_OPT_SUCCESS) { + 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; } @@ -135,7 +136,8 @@ int main(int argc, char *argv[]) { } 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(ldap_connection, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS) { + if (ldap_get_option(ldap_connection, LDAP_OPT_PROTOCOL_VERSION, &version) == + LDAP_OPT_SUCCESS) { if (version < LDAP_VERSION3) { version = LDAP_VERSION3; ldap_set_option(ldap_connection, LDAP_OPT_PROTOCOL_VERSION, &version); @@ -156,7 +158,8 @@ int main(int argc, char *argv[]) { } /* bind to the ldap server */ - if (ldap_bind_s(ldap_connection, config.ld_binddn, config.ld_passwd, LDAP_AUTH_SIMPLE) != LDAP_SUCCESS) { + 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"); } @@ -168,8 +171,10 @@ int main(int argc, char *argv[]) { int num_entries = 0; /* do a search of all objectclasses in the base dn */ 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) { + (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"); } @@ -215,14 +220,16 @@ int main(int argc, char *argv[]) { /* print out the result */ 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)); + 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", config.warn_time_set, config.warn_time, config.crit_time_set, config.crit_time, true, 0, - false, 0)); + fperfdata("time", elapsed_time, "s", config.warn_time_set, config.warn_time, + config.crit_time_set, config.crit_time, true, 0, false, 0)); } exit(status); @@ -273,7 +280,8 @@ check_ldap_config_wrapper process_arguments(int argc, char **argv) { int option = 0; while (true) { - int option_index = 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 (option_index == -1 || option_index == EOF) { break; @@ -381,7 +389,8 @@ check_ldap_config_wrapper process_arguments(int argc, char **argv) { result.config.ld_port = DEFAULT_PORT; } - if (strstr(argv[0], "check_ldaps") && !result.config.starttls && !result.config.ssl_on_connect) { + if (strstr(argv[0], "check_ldaps") && !result.config.starttls && + !result.config.ssl_on_connect) { result.config.starttls = true; } @@ -398,7 +407,8 @@ check_ldap_config_wrapper validate_arguments(check_ldap_config_wrapper config_wr } 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); + set_thresholds(&config_wrapper.config.entries_thresholds, + config_wrapper.config.warn_entries, config_wrapper.config.crit_entries); } if (config_wrapper.config.ld_passwd == NULL) { @@ -435,11 +445,13 @@ void print_help(void) { 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", _("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 %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]"); @@ -463,9 +475,11 @@ void print_help(void) { 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(_(" 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", _("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.")); diff --git a/plugins/check_load.c b/plugins/check_load.c index 2925bff3..f7a6f7fd 100644 --- a/plugins/check_load.c +++ b/plugins/check_load.c @@ -168,7 +168,8 @@ int main(int argc, char **argv) { mp_subcheck scaled_load_sc1 = mp_subcheck_init(); scaled_load_sc1 = mp_set_subcheck_state(scaled_load_sc1, mp_get_pd_status(pd_scaled_load1)); mp_add_perfdata_to_subcheck(&scaled_load_sc1, pd_scaled_load1); - xasprintf(&scaled_load_sc1.output, "1 Minute: %s", pd_value_to_string(pd_scaled_load1.value)); + xasprintf(&scaled_load_sc1.output, "1 Minute: %s", + pd_value_to_string(pd_scaled_load1.value)); mp_add_subcheck_to_subcheck(&scaled_load_sc, scaled_load_sc1); mp_perfdata pd_scaled_load5 = perfdata_init(); @@ -179,7 +180,8 @@ int main(int argc, char **argv) { mp_subcheck scaled_load_sc5 = mp_subcheck_init(); scaled_load_sc5 = mp_set_subcheck_state(scaled_load_sc5, mp_get_pd_status(pd_scaled_load5)); mp_add_perfdata_to_subcheck(&scaled_load_sc5, pd_scaled_load5); - xasprintf(&scaled_load_sc5.output, "5 Minutes: %s", pd_value_to_string(pd_scaled_load5.value)); + xasprintf(&scaled_load_sc5.output, "5 Minutes: %s", + pd_value_to_string(pd_scaled_load5.value)); mp_add_subcheck_to_subcheck(&scaled_load_sc, scaled_load_sc5); mp_perfdata pd_scaled_load15 = perfdata_init(); @@ -188,9 +190,11 @@ int main(int argc, char **argv) { pd_scaled_load15 = mp_pd_set_thresholds(pd_scaled_load15, config.th_load[2]); mp_subcheck scaled_load_sc15 = mp_subcheck_init(); - scaled_load_sc15 = mp_set_subcheck_state(scaled_load_sc15, mp_get_pd_status(pd_scaled_load15)); + scaled_load_sc15 = + mp_set_subcheck_state(scaled_load_sc15, mp_get_pd_status(pd_scaled_load15)); mp_add_perfdata_to_subcheck(&scaled_load_sc15, pd_scaled_load15); - xasprintf(&scaled_load_sc15.output, "15 Minutes: %s", pd_value_to_string(pd_scaled_load15.value)); + xasprintf(&scaled_load_sc15.output, "15 Minutes: %s", + pd_value_to_string(pd_scaled_load15.value)); mp_add_subcheck_to_subcheck(&scaled_load_sc, scaled_load_sc15); mp_add_subcheck_to_check(&overall, scaled_load_sc); @@ -245,11 +249,13 @@ int main(int argc, char **argv) { mp_subcheck top_proc_sc = mp_subcheck_init(); top_proc_sc = mp_set_subcheck_state(top_proc_sc, STATE_OK); top_processes_result top_proc = print_top_consuming_processes(config.n_procs_to_show); - xasprintf(&top_proc_sc.output, "Top %lu CPU time consuming processes", config.n_procs_to_show); + xasprintf(&top_proc_sc.output, "Top %lu CPU time consuming processes", + config.n_procs_to_show); if (top_proc.errorcode == OK) { for (unsigned long i = 0; i < config.n_procs_to_show; i++) { - xasprintf(&top_proc_sc.output, "%s\n%s", top_proc_sc.output, top_proc.top_processes[i]); + xasprintf(&top_proc_sc.output, "%s\n%s", top_proc_sc.output, + top_proc.top_processes[i]); } } @@ -417,7 +423,8 @@ void print_help(void) { void print_usage(void) { printf("%s\n", _("Usage:")); - printf("%s [-r] -w WLOAD1,WLOAD5,WLOAD15 -c CLOAD1,CLOAD5,CLOAD15 [-n NUMBER_OF_PROCS]\n", progname); + printf("%s [-r] -w WLOAD1,WLOAD5,WLOAD15 -c CLOAD1,CLOAD5,CLOAD15 [-n NUMBER_OF_PROCS]\n", + progname); } #ifdef PS_USES_PROCPCPU @@ -462,7 +469,8 @@ static top_processes_result print_top_consuming_processes(unsigned long n_procs_ #ifdef PS_USES_PROCPCPU qsort(chld_out.line + 1, chld_out.lines - 1, sizeof(char *), cmpstringp); #endif /* PS_USES_PROCPCPU */ - unsigned long lines_to_show = chld_out.lines < (size_t)(n_procs_to_show + 1) ? chld_out.lines : n_procs_to_show + 1; + unsigned long lines_to_show = + chld_out.lines < (size_t)(n_procs_to_show + 1) ? chld_out.lines : n_procs_to_show + 1; result.top_processes = calloc(lines_to_show, sizeof(char *)); if (result.top_processes == NULL) { diff --git a/plugins/check_mrtg.c b/plugins/check_mrtg.c index 5bd276dc..4a17049a 100644 --- a/plugins/check_mrtg.c +++ b/plugins/check_mrtg.c @@ -129,7 +129,8 @@ int main(int argc, char **argv) { time_t current_time; time(¤t_time); 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)); + printf(_("MRTG data has expired (%d minutes old)\n"), + (int)((current_time - timestamp) / 60)); return STATE_WARNING; } @@ -148,20 +149,29 @@ int main(int argc, char **argv) { result = STATE_WARNING; } - 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)); + 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 */ 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}}; + 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}}; check_mrtg_config_wrapper result = { .errorcode = OK, @@ -242,7 +252,9 @@ check_mrtg_config_wrapper process_arguments(int argc, char **argv) { 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); + die(STATE_UNKNOWN, + _("%s is not a valid expiration time\nUse '%s -h' for additional help\n"), + argv[option_char], progname); } } @@ -334,25 +346,32 @@ void print_help(void) { printf(" %s\n", _("\"Bytes Per Second\", \"%% Utilization\")")); printf("\n"); - printf(" %s\n", _("If the value exceeds the threshold, a WARNING status is returned. If")); + printf(" %s\n", + _("If the value exceeds the threshold, a WARNING status is returned. If")); printf(" %s\n", _("the value exceeds the threshold, a CRITICAL status is returned. If")); printf(" %s\n", _("the data in the log file is older than old, a WARNING")); printf(" %s\n", _("status is returned and a warning message is printed.")); printf("\n"); - printf(" %s\n", _("This plugin is useful for monitoring MRTG data that does not correspond to")); - printf(" %s\n", _("bandwidth usage. (Use the check_mrtgtraf plugin for monitoring bandwidth).")); - printf(" %s\n", _("It can be used to monitor any kind of data that MRTG is monitoring - errors,")); - printf(" %s\n", _("packets/sec, etc. I use MRTG in conjunction with the Novell NLM that allows")); + printf(" %s\n", + _("This plugin is useful for monitoring MRTG data that does not correspond to")); + printf(" %s\n", + _("bandwidth usage. (Use the check_mrtgtraf plugin for monitoring bandwidth).")); + printf(" %s\n", + _("It can be used to monitor any kind of data that MRTG is monitoring - errors,")); + printf(" %s\n", + _("packets/sec, etc. I use MRTG in conjunction with the Novell NLM that allows")); printf(" %s\n", _("me to track processor utilization, user connections, drive space, etc and")); printf(" %s\n\n", _("this plugin works well for monitoring that kind of data as well.")); printf("%s\n", _("Notes:")); - printf(" %s\n", _("- This plugin only monitors one of the two variables stored in the MRTG log")); + printf(" %s\n", + _("- This plugin only monitors one of the two variables stored in the MRTG log")); printf(" %s\n", _("file. If you want to monitor both values you will have to define two")); printf(" %s\n", _("commands with different values for the argument. Of course,")); printf(" %s\n", _("you can always hack the code to make this plugin work for you...")); - printf(" %s\n", _("- MRTG stands for the Multi Router Traffic Grapher. It can be downloaded from")); + printf(" %s\n", + _("- MRTG stands for the Multi Router Traffic Grapher. It can be downloaded from")); printf(" %s\n", "http://ee-staff.ethz.ch/~oetiker/webtools/mrtg/mrtg.html"); printf(UT_SUPPORT); diff --git a/plugins/check_mrtgtraf.c b/plugins/check_mrtgtraf.c index 8c7cf8aa..10ce936f 100644 --- a/plugins/check_mrtgtraf.c +++ b/plugins/check_mrtgtraf.c @@ -122,7 +122,8 @@ int main(int argc, char **argv) { time_t current_time; time(¤t_time); 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)); + die(STATE_WARNING, _("MRTG data has expired (%d minutes old)\n"), + (int)((current_time - timestamp) / 60)); } unsigned long incoming_rate = 0L; @@ -177,21 +178,26 @@ int main(int argc, char **argv) { } int result = STATE_OK; - if (incoming_rate > config.incoming_critical_threshold || outgoing_rate > config.outgoing_critical_threshold) { + if (incoming_rate > config.incoming_critical_threshold || + outgoing_rate > config.outgoing_critical_threshold) { result = STATE_CRITICAL; - } else if (incoming_rate > config.incoming_warning_threshold || outgoing_rate > config.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"), (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)config.incoming_warning_threshold, - config.incoming_warning_threshold, (int)config.incoming_critical_threshold, config.incoming_critical_threshold, + 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)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, + 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); @@ -249,10 +255,12 @@ check_mrtgtraf_config_wrapper process_arguments(int argc, char **argv) { result.config.use_average = (bool)(strcmp(optarg, "MAX")); break; case 'c': /* warning threshold */ - sscanf(optarg, "%lu,%lu", &result.config.incoming_critical_threshold, &result.config.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", &result.config.incoming_warning_threshold, &result.config.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); diff --git a/plugins/check_mysql.c b/plugins/check_mysql.c index ca3422b5..3d7ec4cd 100644 --- a/plugins/check_mysql.c +++ b/plugins/check_mysql.c @@ -50,15 +50,23 @@ static int verbose = 0; #define LENGTH_METRIC_UNIT 6 static const char *metric_unit[LENGTH_METRIC_UNIT] = { - "Open_files", "Open_tables", "Qcache_free_memory", "Qcache_queries_in_cache", "Threads_connected", "Threads_running"}; + "Open_files", "Open_tables", "Qcache_free_memory", "Qcache_queries_in_cache", + "Threads_connected", "Threads_running"}; #define LENGTH_METRIC_COUNTER 9 -static const char *metric_counter[LENGTH_METRIC_COUNTER] = { - "Connections", "Qcache_hits", "Qcache_inserts", "Qcache_lowmem_prunes", "Qcache_not_cached", "Queries", - "Questions", "Table_locks_waited", "Uptime"}; - -#define MYSQLDUMP_THREADS_QUERY \ - "SELECT COUNT(1) mysqldumpThreads FROM information_schema.processlist WHERE info LIKE 'SELECT /*!40001 SQL_NO_CACHE */%'" +static const char *metric_counter[LENGTH_METRIC_COUNTER] = {"Connections", + "Qcache_hits", + "Qcache_inserts", + "Qcache_lowmem_prunes", + "Qcache_not_cached", + "Queries", + "Questions", + "Table_locks_waited", + "Uptime"}; + +#define MYSQLDUMP_THREADS_QUERY \ + "SELECT COUNT(1) mysqldumpThreads FROM information_schema.processlist WHERE info LIKE " \ + "'SELECT /*!40001 SQL_NO_CACHE */%'" typedef struct { int errorcode; @@ -99,16 +107,19 @@ int main(int argc, char **argv) { } if (config.ssl) { - mysql_ssl_set(&mysql, config.key, config.cert, config.ca_cert, config.ca_dir, config.ciphers); + mysql_ssl_set(&mysql, config.key, config.cert, config.ca_cert, config.ca_dir, + config.ciphers); } /* establish a connection to the server and error checking */ - 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_real_connect(&mysql, config.db_host, config.db_user, config.db_pass, config.db, + config.db_port, config.db_socket, 0)) { /* Depending on internally-selected auth plugin MySQL might return */ /* ER_ACCESS_DENIED_NO_PASSWORD_ERROR or ER_ACCESS_DENIED_ERROR. */ /* Semantically these errors are the same. */ - if (config.ignore_auth && - (mysql_errno(&mysql) == ER_ACCESS_DENIED_ERROR || mysql_errno(&mysql) == ER_ACCESS_DENIED_NO_PASSWORD_ERROR)) { - printf("MySQL OK - Version: %s (protocol %d)\n", mysql_get_server_info(&mysql), mysql_get_proto_info(&mysql)); + if (config.ignore_auth && (mysql_errno(&mysql) == ER_ACCESS_DENIED_ERROR || + mysql_errno(&mysql) == ER_ACCESS_DENIED_NO_PASSWORD_ERROR)) { + printf("MySQL OK - Version: %s (protocol %d)\n", mysql_get_server_info(&mysql), + mysql_get_proto_info(&mysql)); mysql_close(&mysql); return STATE_OK; } @@ -157,13 +168,17 @@ int main(int argc, char **argv) { while ((row = mysql_fetch_row(res)) != NULL) { for (int i = 0; i < LENGTH_METRIC_UNIT; i++) { if (strcmp(row[0], metric_unit[i]) == 0) { - xasprintf(&perf, "%s%s ", perf, perfdata(metric_unit[i], atol(row[1]), "", false, 0, false, 0, false, 0, false, 0)); + xasprintf(&perf, "%s%s ", perf, + perfdata(metric_unit[i], atol(row[1]), "", false, 0, false, 0, false, + 0, false, 0)); continue; } } for (int i = 0; i < LENGTH_METRIC_COUNTER; i++) { if (strcmp(row[0], metric_counter[i]) == 0) { - xasprintf(&perf, "%s%s ", perf, perfdata(metric_counter[i], atol(row[1]), "c", false, 0, false, 0, false, 0, false, 0)); + xasprintf(&perf, "%s%s ", perf, + perfdata(metric_counter[i], atol(row[1]), "c", false, 0, false, 0, + false, 0, false, 0)); continue; } } @@ -189,8 +204,8 @@ int main(int argc, char **argv) { unsigned long minor_version = (server_verion_int % 10000) / 100; unsigned long patch_version = (server_verion_int % 100); if (verbose) { - printf("Found MariaDB: %s, main version: %lu, minor version: %lu, patch version: %lu\n", server_version, major_version, - minor_version, patch_version); + printf("Found MariaDB: %s, main version: %lu, minor version: %lu, patch version: %lu\n", + server_version, major_version, minor_version, patch_version); } if (strstr(server_version, "MariaDB") != NULL) { @@ -292,11 +307,15 @@ int main(int argc, char **argv) { } /* Save replica status in replica_result */ - snprintf(replica_result, REPLICA_RESULTSIZE, "Replica IO: %s Replica SQL: %s Seconds Behind Master: %s", row[replica_io_field], - row[replica_sql_field], seconds_behind_field != -1 ? row[seconds_behind_field] : "Unknown"); - - /* Raise critical error if SQL THREAD or IO THREAD are stopped, but only if there are no mysqldump threads running */ - if (strcmp(row[replica_io_field], "Yes") != 0 || strcmp(row[replica_sql_field], "Yes") != 0) { + snprintf(replica_result, REPLICA_RESULTSIZE, + "Replica IO: %s Replica SQL: %s Seconds Behind Master: %s", + row[replica_io_field], row[replica_sql_field], + seconds_behind_field != -1 ? row[seconds_behind_field] : "Unknown"); + + /* Raise critical error if SQL THREAD or IO THREAD are stopped, but only if there are no + * mysqldump threads running */ + if (strcmp(row[replica_io_field], "Yes") != 0 || + strcmp(row[replica_sql_field], "Yes") != 0) { MYSQL_RES *res_mysqldump; MYSQL_ROW row_mysqldump; unsigned int mysqldump_threads = 0; @@ -325,20 +344,23 @@ int main(int argc, char **argv) { if (seconds_behind_field == -1) { printf("seconds_behind_field not found\n"); } else { - printf("seconds_behind_field(index %d)=%s\n", seconds_behind_field, row[seconds_behind_field]); + printf("seconds_behind_field(index %d)=%s\n", seconds_behind_field, + row[seconds_behind_field]); } } /* Check Seconds Behind against threshold */ - if ((seconds_behind_field != -1) && (row[seconds_behind_field] != NULL && strcmp(row[seconds_behind_field], "NULL") != 0)) { + if ((seconds_behind_field != -1) && (row[seconds_behind_field] != NULL && + strcmp(row[seconds_behind_field], "NULL") != 0)) { double value = atof(row[seconds_behind_field]); int status; status = get_status(value, config.my_threshold); xasprintf(&perf, "%s %s", perf, - fperfdata("seconds behind master", value, "s", true, (double)config.warning_time, true, - (double)config.critical_time, false, 0, false, 0)); + fperfdata("seconds behind master", value, "s", true, + (double)config.warning_time, true, (double)config.critical_time, + false, 0, false, 0)); if (status == STATE_WARNING) { printf("SLOW_REPLICA %s: %s|%s\n", _("WARNING"), replica_result, perf); @@ -410,7 +432,8 @@ check_mysql_config_wrapper process_arguments(int argc, char **argv) { int option = 0; while (true) { - int option_index = getopt_long(argc, argv, "hlvVnSP:p:u:d:H:s:c:w:a:k:C:D:L:f:g:", longopts, &option); + int option_index = + getopt_long(argc, argv, "hlvVnSP:p:u:d:H:s:c:w:a:k:C:D:L:f:g:", longopts, &option); if (option_index == -1 || option_index == EOF) { break; @@ -580,15 +603,17 @@ void print_help(void) { printf(" ==> %s <==\n", _("IMPORTANT: THIS FORM OF AUTHENTICATION IS NOT SECURE!!!")); printf(" %s\n", _("Your clear-text password could be visible as a process table entry")); printf(" %s\n", "-S, --check-slave"); - printf(" %s\n", - _("Check if the slave thread is running properly. This option is deprecated in favour of check-replica, which does the same")); + printf(" %s\n", _("Check if the slave thread is running properly. This option is deprecated " + "in favour of check-replica, which does the same")); printf(" %s\n", "--check-replica"); printf(" %s\n", _("Check if the replica thread is running properly.")); printf(" %s\n", "-w, --warning"); - printf(" %s\n", _("Exit with WARNING status if replica server is more than INTEGER seconds")); + printf(" %s\n", + _("Exit with WARNING status if replica server is more than INTEGER seconds")); printf(" %s\n", _("behind master")); printf(" %s\n", "-c, --critical"); - printf(" %s\n", _("Exit with CRITICAL status if replica server is more then INTEGER seconds")); + printf(" %s\n", + _("Exit with CRITICAL status if replica server is more then INTEGER seconds")); printf(" %s\n", _("behind master")); printf(" %s\n", "-l, --ssl"); printf(" %s\n", _("Use ssl encryption")); @@ -604,7 +629,8 @@ void print_help(void) { printf(" %s\n", _("List of valid SSL ciphers")); printf("\n"); - printf(" %s\n", _("There are no required arguments. By default, the local database is checked")); + printf(" %s\n", + _("There are no required arguments. By default, the local database is checked")); printf(" %s\n", _("using the default unix socket. You can force TCP on localhost by using an")); printf(" %s\n", _("IP address or FQDN ('localhost' will use the socket as well).")); diff --git a/plugins/check_mysql_query.c b/plugins/check_mysql_query.c index 5e04a94b..c7e84deb 100644 --- a/plugins/check_mysql_query.c +++ b/plugins/check_mysql_query.c @@ -47,7 +47,8 @@ typedef struct { 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 check_mysql_query_config_wrapper + validate_arguments(check_mysql_query_config_wrapper /*config_wrapper*/); static void print_help(void); void print_usage(void); @@ -83,7 +84,8 @@ int main(int argc, char **argv) { } /* establish a connection to the server and error checking */ - 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_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) { @@ -155,8 +157,11 @@ int main(int argc, char **argv) { printf("QUERY %s: ", _("CRITICAL")); } 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)); + 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; @@ -164,12 +169,21 @@ int main(int argc, char **argv) { /* process command-line arguments */ 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'}, - {"group", required_argument, 0, 'g'}, {"port", required_argument, 0, 'P'}, {"verbose", no_argument, 0, 'v'}, - {"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}}; + 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'}, + {"group", required_argument, 0, 'g'}, + {"port", required_argument, 0, 'P'}, + {"verbose", no_argument, 0, 'v'}, + {"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}}; check_mysql_query_config_wrapper result = { .errorcode = OK, @@ -255,7 +269,8 @@ check_mysql_query_config_wrapper process_arguments(int argc, char **argv) { return validate_arguments(result); } -check_mysql_query_config_wrapper validate_arguments(check_mysql_query_config_wrapper config_wrapper) { +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"); } diff --git a/plugins/check_nt.c b/plugins/check_nt.c index 7dd23e5c..35ca92cd 100644 --- a/plugins/check_nt.c +++ b/plugins/check_nt.c @@ -96,7 +96,8 @@ int main(int argc, char **argv) { 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); + 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); @@ -116,9 +117,12 @@ int main(int argc, char **argv) { /* 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) { + 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", config.req_password, lvalue_list[0 + offset]); @@ -133,10 +137,12 @@ int main(int argc, char **argv) { return_code = STATE_WARNING; } - xasprintf(&output_message, _(" %lu%% (%lu min average)"), utilization, lvalue_list[0 + offset]); + xasprintf(&output_message, _(" %lu%% (%lu min average)"), utilization, + lvalue_list[0 + offset]); xasprintf(&temp_string, "%s%s", temp_string, output_message); - xasprintf(&perfdata, _(" '%lu min avg Load'=%lu%%;%lu;%lu;0;100"), lvalue_list[0 + offset], utilization, - lvalue_list[1 + offset], lvalue_list[2 + offset]); + xasprintf(&perfdata, _(" '%lu min avg Load'=%lu%%;%lu;%lu;0;100"), + lvalue_list[0 + offset], utilization, lvalue_list[1 + offset], + lvalue_list[2 + offset]); xasprintf(&temp_string_perf, "%s%s", temp_string_perf, perfdata); offset += 3; /* move across the array */ } @@ -154,8 +160,10 @@ int main(int argc, char **argv) { if (config.value_list == NULL) { tmp_value_list = "minutes"; } - 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)) { + 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 { @@ -175,8 +183,9 @@ int main(int argc, char **argv) { } /* 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); + xasprintf(&output_message, + _("System Uptime - %u day(s) %u hour(s) %u minute(s) |uptime=%lu"), updays, + uphours, upminutes, uptime); if (config.check_critical_value && uptime <= config.critical_value) { return_code = STATE_CRITICAL; @@ -207,20 +216,27 @@ int main(int argc, char **argv) { } if (total_disk_space > 0 && free_disk_space >= 0) { - double percent_used_space = ((total_disk_space - free_disk_space) / total_disk_space) * 100; + 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%%)"), 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"), config.value_list, - (total_disk_space - free_disk_space) / 1073741824, warning_used_space / 1073741824, - critical_used_space / 1073741824, total_disk_space / 1073741824); + 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%%)"), + 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"), + config.value_list, (total_disk_space - free_disk_space) / 1073741824, + warning_used_space / 1073741824, critical_used_space / 1073741824, + total_disk_space / 1073741824); if (config.check_critical_value && percent_used_space >= config.critical_value) { return_code = STATE_CRITICAL; - } else if (config.check_warning_value && percent_used_space >= config.warning_value) { + } else if (config.check_warning_value && + percent_used_space >= config.warning_value) { return_code = STATE_WARNING; } else { return_code = STATE_OK; @@ -239,8 +255,10 @@ int main(int argc, char **argv) { if (config.value_list == NULL) { output_message = strdup(_("No service/process specified")); } 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, + 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, "&"); @@ -271,10 +289,14 @@ int main(int argc, char **argv) { /* Divisor should be 1048567, not 3044515, as we are measuring "Commit Charge" here, which equals RAM + Pagefiles. */ - xasprintf(&output_message, _("Memory usage: total:%.2f MB - used: %.2f MB (%.0f%%) - free: %.2f MB (%.0f%%)"), - mem_commitLimit / 1048567, mem_commitByte / 1048567, percent_used_space, (mem_commitLimit - mem_commitByte) / 1048567, - (mem_commitLimit - mem_commitByte) / mem_commitLimit * 100); - xasprintf(&perfdata, _("'Memory usage'=%.2fMB;%.2f;%.2f;0.00;%.2f"), mem_commitByte / 1048567, warning_used_space / 1048567, + xasprintf( + &output_message, + _("Memory usage: total:%.2f MB - used: %.2f MB (%.0f%%) - free: %.2f MB (%.0f%%)"), + mem_commitLimit / 1048567, mem_commitByte / 1048567, percent_used_space, + (mem_commitLimit - mem_commitByte) / 1048567, + (mem_commitLimit - mem_commitByte) / mem_commitLimit * 100); + xasprintf(&perfdata, _("'Memory usage'=%.2fMB;%.2f;%.2f;0.00;%.2f"), + mem_commitByte / 1048567, warning_used_space / 1048567, critical_used_space / 1048567, mem_commitLimit / 1048567); return_code = STATE_OK; @@ -302,16 +324,17 @@ int main(int argc, char **argv) { the counter unit - that is, the dimensions of the counter you're getting. Examples: pages/s, packets transferred, etc. - 4) If you want, you may provide the minimum and maximum values to expect. They aren't mandatory, - but once specified they MUST have the same order of magnitude and units of -w and -c; otherwise. - strange things will happen when you make graphs of your data. + 4) If you want, you may provide the minimum and maximum values to expect. They aren't + mandatory, but once specified they MUST have the same order of magnitude and units of -w and + -c; otherwise. strange things will happen when you make graphs of your data. */ double counter_value = 0.0; if (config.value_list == NULL) { output_message = strdup(_("No counter specified")); } else { - preparelist(config.value_list); /* replace , between services with & to send the request */ + preparelist( + config.value_list); /* replace , between services with & to send the request */ bool isPercent = (strchr(config.value_list, '%') != NULL); strtok(config.value_list, "&"); /* burn the first parameters */ @@ -358,15 +381,18 @@ int main(int argc, char **argv) { if (allRight) { /* Let's format the output string, finally... */ if (strstr(description, "%") == NULL) { - xasprintf(&output_message, "%s = %.2f %s", description, counter_value, counter_unit); + xasprintf(&output_message, "%s = %.2f %s", description, counter_value, + counter_unit); } else { /* has formatting, will segv if wrong */ xasprintf(&output_message, description, counter_value); } xasprintf(&output_message, "%s |", output_message); xasprintf(&output_message, "%s %s", output_message, - fperfdata(description, counter_value, counter_unit, 1, config.warning_value, 1, config.critical_value, - (!(isPercent) && (minval != NULL)), fminval, (!(isPercent) && (minval != NULL)), fmaxval)); + fperfdata(description, counter_value, counter_unit, 1, + config.warning_value, 1, config.critical_value, + (!(isPercent) && (minval != NULL)), fminval, + (!(isPercent) && (minval != NULL)), fmaxval)); } } @@ -391,7 +417,8 @@ int main(int argc, char **argv) { if (config.value_list == NULL) { output_message = strdup(_("No counter specified")); } else { - preparelist(config.value_list); /* replace , between services with & to send the request */ + 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, "&")); @@ -724,25 +751,31 @@ void print_help(void) { printf(" %s\n", "\"%%.f %%%% paging file used.\""); printf(" %s\n", "INSTANCES ="); printf(" %s\n", _("Check any performance counter object of Windows NT/2000.")); - printf(" %s\n", _("Syntax: check_nt -H -p -v INSTANCES -l ")); + printf(" %s\n", + _("Syntax: check_nt -H -p -v INSTANCES -l ")); printf(" %s\n", _(" is a Windows Perfmon Counter object (eg. Process),")); printf(" %s\n", _("if it is two words, it should be enclosed in quotes")); printf(" %s\n", _("The returned results will be a comma-separated list of instances on ")); printf(" %s\n", _(" the selected computer for that object.")); - printf(" %s\n", _("The purpose of this is to be run from command line to determine what instances")); - printf(" %s\n", _(" are available for monitoring without having to log onto the Windows server")); + printf(" %s\n", + _("The purpose of this is to be run from command line to determine what instances")); + printf(" %s\n", + _(" are available for monitoring without having to log onto the Windows server")); printf(" %s\n", _(" to run Perfmon directly.")); - printf(" %s\n", _("It can also be used in scripts that automatically create the monitoring service")); + printf(" %s\n", + _("It can also be used in scripts that automatically create the monitoring service")); printf(" %s\n", _(" configuration files.")); printf(" %s\n", _("Some examples:")); printf(" %s\n\n", _("check_nt -H 192.168.1.1 -p 1248 -v INSTANCES -l Process")); printf("%s\n", _("Notes:")); - printf(" %s\n", _("- The NSClient service should be running on the server to get any information")); + printf(" %s\n", + _("- The NSClient service should be running on the server to get any information")); printf(" %s\n", "(http://nsclient.ready2run.nl)."); printf(" %s\n", _("- Critical thresholds should be lower than warning thresholds")); printf(" %s\n", _("- Default port 1248 is sometimes in use by other services. The error")); - printf(" %s\n", _("output when this happens contains \"Cannot map xxxxx to protocol number\".")); + printf(" %s\n", + _("output when this happens contains \"Cannot map xxxxx to protocol number\".")); printf(" %s\n", _("One fix for this is to change the port to something else on check_nt ")); printf(" %s\n", _("and on the client service it\'s connecting to.")); diff --git a/plugins/check_ntp.c b/plugins/check_ntp.c index d33f8786..b22cc3c1 100644 --- a/plugins/check_ntp.c +++ b/plugins/check_ntp.c @@ -1,34 +1,34 @@ /***************************************************************************** -* -* Monitoring check_ntp plugin -* -* License: GPL -* Copyright (c) 2006 Sean Finney -* Copyright (c) 2006-2024 Monitoring Plugins Development Team -* -* Description: -* -* This file contains the check_ntp plugin -* -* This plugin to check ntp servers independent of any commandline -* programs or external libraries. -* -* -* 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 . -* -* -*****************************************************************************/ + * + * Monitoring check_ntp plugin + * + * License: GPL + * Copyright (c) 2006 Sean Finney + * Copyright (c) 2006-2024 Monitoring Plugins Development Team + * + * Description: + * + * This file contains the check_ntp plugin + * + * This plugin to check ntp servers independent of any commandline + * programs or external libraries. + * + * + * 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 . + * + * + *****************************************************************************/ const char *progname = "check_ntp"; const char *copyright = "2006-2024"; @@ -38,24 +38,24 @@ const char *email = "devel@monitoring-plugins.org"; #include "netutils.h" #include "utils.h" -static char *server_address=NULL; -static int verbose=0; +static char *server_address = NULL; +static int verbose = 0; static bool do_offset = false; -static char *owarn="60"; -static char *ocrit="120"; +static char *owarn = "60"; +static char *ocrit = "120"; static bool do_jitter = false; -static char *jwarn="5000"; -static char *jcrit="10000"; +static char *jwarn = "5000"; +static char *jcrit = "10000"; -static int process_arguments (int /*argc*/, char ** /*argv*/); +static int process_arguments(int /*argc*/, char ** /*argv*/); static thresholds *offset_thresholds = NULL; static thresholds *jitter_thresholds = NULL; -static void print_help (void); -void print_usage (void); +static void print_help(void); +void print_usage(void); /* number of times to perform each request to get a good average. */ #ifndef AVG_NUM -#define AVG_NUM 4 +# define AVG_NUM 4 #endif /* max size of control message data */ @@ -63,17 +63,17 @@ void print_usage (void); /* this structure holds everything in an ntp request/response as per rfc1305 */ typedef struct { - uint8_t flags; /* byte with leapindicator,vers,mode. see macros */ - uint8_t stratum; /* clock stratum */ - int8_t poll; /* polling interval */ - int8_t precision; /* precision of the local clock */ - int32_t rtdelay; /* total rt delay, as a fixed point num. see macros */ - uint32_t rtdisp; /* like above, but for max err to primary src */ - uint32_t refid; /* ref clock identifier */ - uint64_t refts; /* reference timestamp. local time local clock */ - uint64_t origts; /* time at which request departed client */ - uint64_t rxts; /* time at which request arrived at server */ - uint64_t txts; /* time at which request departed server */ + uint8_t flags; /* byte with leapindicator,vers,mode. see macros */ + uint8_t stratum; /* clock stratum */ + int8_t poll; /* polling interval */ + int8_t precision; /* precision of the local clock */ + int32_t rtdelay; /* total rt delay, as a fixed point num. see macros */ + uint32_t rtdisp; /* like above, but for max err to primary src */ + uint32_t refid; /* ref clock identifier */ + uint64_t refts; /* reference timestamp. local time local clock */ + uint64_t origts; /* time at which request departed client */ + uint64_t rxts; /* time at which request arrived at server */ + uint64_t txts; /* time at which request departed server */ } ntp_message; /* this structure holds data about results from querying offset from a peer */ @@ -84,20 +84,20 @@ typedef struct { double rtdelay; /* converted from the ntp_message */ double rtdisp; /* converted from the ntp_message */ double offset[AVG_NUM]; /* offsets from each response */ - uint8_t flags; /* byte with leapindicator,vers,mode. see macros */ + uint8_t flags; /* byte with leapindicator,vers,mode. see macros */ } ntp_server_results; /* this structure holds everything in an ntp control message as per rfc1305 */ typedef struct { - uint8_t flags; /* byte with leapindicator,vers,mode. see macros */ - uint8_t op; /* R,E,M bits and Opcode */ - uint16_t seq; /* Packet sequence */ - uint16_t status; /* Clock status */ - uint16_t assoc; /* Association */ - uint16_t offset; /* Similar to TCP sequence # */ - uint16_t count; /* # bytes of data */ + uint8_t flags; /* byte with leapindicator,vers,mode. see macros */ + uint8_t op; /* R,E,M bits and Opcode */ + uint16_t seq; /* Packet sequence */ + uint16_t status; /* Clock status */ + uint16_t assoc; /* Association */ + uint16_t offset; /* Similar to TCP sequence # */ + uint16_t count; /* # bytes of data */ char data[MAX_CM_SIZE]; /* ASCII data of the request */ - /* NB: not necessarily NULL terminated! */ + /* NB: not necessarily NULL terminated! */ } ntp_control_message; /* this is an association/status-word pair found in control packet responses */ @@ -108,38 +108,50 @@ typedef struct { /* bits 1,2 are the leap indicator */ #define LI_MASK 0xc0 -#define LI(x) ((x&LI_MASK)>>6) -#define LI_SET(x,y) do{ x |= ((y<<6)&LI_MASK); }while(0) +#define LI(x) ((x & LI_MASK) >> 6) +#define LI_SET(x, y) \ + do { \ + x |= ((y << 6) & LI_MASK); \ + } while (0) /* and these are the values of the leap indicator */ -#define LI_NOWARNING 0x00 -#define LI_EXTRASEC 0x01 +#define LI_NOWARNING 0x00 +#define LI_EXTRASEC 0x01 #define LI_MISSINGSEC 0x02 -#define LI_ALARM 0x03 +#define LI_ALARM 0x03 /* bits 3,4,5 are the ntp version */ #define VN_MASK 0x38 -#define VN(x) ((x&VN_MASK)>>3) -#define VN_SET(x,y) do{ x |= ((y<<3)&VN_MASK); }while(0) +#define VN(x) ((x & VN_MASK) >> 3) +#define VN_SET(x, y) \ + do { \ + x |= ((y << 3) & VN_MASK); \ + } while (0) #define VN_RESERVED 0x02 /* bits 6,7,8 are the ntp mode */ #define MODE_MASK 0x07 -#define MODE(x) (x&MODE_MASK) -#define MODE_SET(x,y) do{ x |= (y&MODE_MASK); }while(0) +#define MODE(x) (x & MODE_MASK) +#define MODE_SET(x, y) \ + do { \ + x |= (y & MODE_MASK); \ + } while (0) /* here are some values */ -#define MODE_CLIENT 0x03 +#define MODE_CLIENT 0x03 #define MODE_CONTROLMSG 0x06 /* In control message, bits 8-10 are R,E,M bits */ -#define REM_MASK 0xe0 -#define REM_RESP 0x80 +#define REM_MASK 0xe0 +#define REM_RESP 0x80 #define REM_ERROR 0x40 -#define REM_MORE 0x20 +#define REM_MORE 0x20 /* In control message, bits 11 - 15 are opcode */ #define OP_MASK 0x1f -#define OP_SET(x,y) do{ x |= (y&OP_MASK); }while(0) +#define OP_SET(x, y) \ + do { \ + x |= (y & OP_MASK); \ + } while (0) #define OP_READSTAT 0x01 #define OP_READVAR 0x02 /* In peer status bytes, bits 6,7,8 determine clock selection status */ -#define PEER_SEL(x) ((ntohs(x)>>8)&0x07) -#define PEER_INCLUDED 0x04 +#define PEER_SEL(x) ((ntohs(x) >> 8) & 0x07) +#define PEER_INCLUDED 0x04 #define PEER_SYNCSOURCE 0x06 /** @@ -153,82 +165,92 @@ typedef struct { /* macros to access the left/right 16 bits of a 32-bit ntp "fixed point" number. note that these can be used as lvalues too */ -#define L16(x) (((uint16_t*)&x)[0]) -#define R16(x) (((uint16_t*)&x)[1]) +#define L16(x) (((uint16_t *)&x)[0]) +#define R16(x) (((uint16_t *)&x)[1]) /* macros to access the left/right 32 bits of a 64-bit ntp "fixed point" number. these too can be used as lvalues */ -#define L32(x) (((uint32_t*)&x)[0]) -#define R32(x) (((uint32_t*)&x)[1]) +#define L32(x) (((uint32_t *)&x)[0]) +#define R32(x) (((uint32_t *)&x)[1]) /* ntp wants seconds since 1/1/00, epoch is 1/1/70. this is the difference */ #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) (double)(((uint64_t)n)?\ - (ntohl(L32(n))-EPOCHDIFF) + \ - (.00000001*(0.5+(double)(ntohl(R32(n))/42.94967296))):\ - 0) +#define NTP64asDOUBLE(n) \ + (double)(((uint64_t)n) ? (ntohl(L32(n)) - EPOCHDIFF) + \ + (.00000001 * (0.5 + (double)(ntohl(R32(n)) / 42.94967296))) \ + : 0) /* convert a struct timeval to a double */ -#define TVasDOUBLE(x) (double)(x.tv_sec+(0.000001*x.tv_usec)) +#define TVasDOUBLE(x) (double)(x.tv_sec + (0.000001 * x.tv_usec)) /* convert an ntp 64-bit fp number to a struct timeval */ -#define NTP64toTV(n,t) \ - do{ if(!n) t.tv_sec = t.tv_usec = 0; \ - else { \ - t.tv_sec=ntohl(L32(n))-EPOCHDIFF; \ - t.tv_usec=(int)(0.5+(double)(ntohl(R32(n))/4294.967296)); \ - } \ - }while(0) +#define NTP64toTV(n, t) \ + do { \ + if (!n) \ + t.tv_sec = t.tv_usec = 0; \ + else { \ + t.tv_sec = ntohl(L32(n)) - EPOCHDIFF; \ + t.tv_usec = (int)(0.5 + (double)(ntohl(R32(n)) / 4294.967296)); \ + } \ + } while (0) /* convert a struct timeval to an ntp 64-bit fp number */ -#define TVtoNTP64(t,n) \ - do{ if(!t.tv_usec && !t.tv_sec) n=0x0UL; \ - else { \ - L32(n)=htonl(t.tv_sec + EPOCHDIFF); \ - R32(n)=htonl((uint64_t)((4294.967296*t.tv_usec)+.5)); \ - } \ - } while(0) +#define TVtoNTP64(t, n) \ + do { \ + if (!t.tv_usec && !t.tv_sec) \ + n = 0x0UL; \ + else { \ + L32(n) = htonl(t.tv_sec + EPOCHDIFF); \ + R32(n) = htonl((uint64_t)((4294.967296 * t.tv_usec) + .5)); \ + } \ + } while (0) /* NTP control message header is 12 bytes, plus any data in the data * field, plus null padding to the nearest 32-bit boundary per rfc. */ -#define SIZEOF_NTPCM(m) (12+ntohs(m.count)+((ntohs(m.count)%4)?4-(ntohs(m.count)%4):0)) +#define SIZEOF_NTPCM(m) \ + (12 + ntohs(m.count) + ((ntohs(m.count) % 4) ? 4 - (ntohs(m.count) % 4) : 0)) /* finally, a little helper or two for debugging: */ -#define DBG(x) do{if(verbose>1){ x; }}while(0); -#define PRINTSOCKADDR(x) \ - do{ \ - printf("%u.%u.%u.%u", (x>>24)&0xff, (x>>16)&0xff, (x>>8)&0xff, x&0xff);\ - }while(0); +#define DBG(x) \ + do { \ + if (verbose > 1) { \ + x; \ + } \ + } while (0); +#define PRINTSOCKADDR(x) \ + do { \ + printf("%u.%u.%u.%u", (x >> 24) & 0xff, (x >> 16) & 0xff, (x >> 8) & 0xff, x & 0xff); \ + } while (0); /* calculate the offset of the local clock */ -static inline double calc_offset(const ntp_message *m, const struct timeval *t){ +static inline double calc_offset(const ntp_message *m, const struct timeval *t) { double client_tx, peer_rx, peer_tx, client_rx; client_tx = NTP64asDOUBLE(m->origts); peer_rx = NTP64asDOUBLE(m->rxts); peer_tx = NTP64asDOUBLE(m->txts); - client_rx=TVasDOUBLE((*t)); - return (.5*((peer_tx-client_rx)+(peer_rx-client_tx))); + client_rx = TVasDOUBLE((*t)); + return (.5 * ((peer_tx - client_rx) + (peer_rx - client_tx))); } /* 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 *p) { struct timeval ref, orig, rx, tx; - NTP64toTV(p->refts,ref); - NTP64toTV(p->origts,orig); - NTP64toTV(p->rxts,rx); - NTP64toTV(p->txts,tx); + NTP64toTV(p->refts, ref); + NTP64toTV(p->origts, orig); + NTP64toTV(p->rxts, rx); + NTP64toTV(p->txts, tx); 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("\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)); @@ -241,32 +263,31 @@ void print_ntp_message(const ntp_message *p){ printf("\ttxts = %-.16g\n", NTP64asDOUBLE(p->txts)); } -void print_ntp_control_message(const ntp_control_message *p){ - int i=0, numpeers=0; - const ntp_assoc_status_pair *peer=NULL; +void print_ntp_control_message(const ntp_control_message *p) { + int i = 0, numpeers = 0; + const ntp_assoc_status_pair *peer = NULL; 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("\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)); - numpeers=ntohs(p->count)/(sizeof(ntp_assoc_status_pair)); - if(p->op&REM_RESP && p->op&OP_READSTAT){ - peer=(ntp_assoc_status_pair*)p->data; - for(i=0;i= PEER_INCLUDED){ - if(PEER_SEL(peer[i].status) >= PEER_SYNCSOURCE){ + numpeers = ntohs(p->count) / (sizeof(ntp_assoc_status_pair)); + if (p->op & REM_RESP && p->op & OP_READSTAT) { + peer = (ntp_assoc_status_pair *)p->data; + for (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_INCLUDED) { + if (PEER_SEL(peer[i].status) >= PEER_SYNCSOURCE) { printf(" <-- current sync source"); } else { printf(" <-- current sync candidate"); @@ -277,41 +298,45 @@ void print_ntp_control_message(const ntp_control_message *p){ } } -void setup_request(ntp_message *p){ +void setup_request(ntp_message *p) { struct timeval t; 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); + p->poll = 4; + p->precision = (int8_t)0xfa; + L16(p->rtdelay) = htons(1); + L16(p->rtdisp) = htons(1); gettimeofday(&t, NULL); - TVtoNTP64(t,p->txts); + TVtoNTP64(t, p->txts); } /* select the "best" server from a list of servers, and return its index. * this is done by filtering servers based on stratum, dispersion, and * finally round-trip delay. */ -int best_offset_server(const ntp_server_results *slist, int nservers){ - int cserver=0, best_server=-1; +int best_offset_server(const ntp_server_results *slist, int nservers) { + int cserver = 0, best_server = -1; /* for each server */ - for(cserver=0; cserver= 0) { + if (best_server >= 0) { DBG(printf("best server selected: peer %d\n", best_server)); return best_server; } else { @@ -354,16 +379,16 @@ 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){ - int i=0, ga_result=0, num_hosts=0, *socklist=NULL, respnum=0; - int servers_completed=0, one_read=0, servers_readable=0, best_index=-1; - time_t now_time=0, start_ts=0; - ntp_message *req=NULL; - double avg_offset=0.; +double offset_request(const char *host, int *status) { + int i = 0, ga_result = 0, num_hosts = 0, *socklist = NULL, respnum = 0; + int servers_completed = 0, one_read = 0, servers_readable = 0, best_index = -1; + time_t now_time = 0, start_ts = 0; + ntp_message *req = NULL; + double avg_offset = 0.; struct timeval recv_time; - struct addrinfo *ai=NULL, *ai_tmp=NULL, hints; - struct pollfd *ufds=NULL; - ntp_server_results *servers=NULL; + struct addrinfo *ai = NULL, *ai_tmp = NULL, hints; + struct pollfd *ufds = NULL; + ntp_server_results *servers = NULL; /* setup hints to only return results from getaddrinfo that we'd like */ memset(&hints, 0, sizeof(struct addrinfo)); @@ -373,97 +398,112 @@ double offset_request(const char *host, int *status){ /* fill in ai with the list of hosts resolved by the host name */ ga_result = getaddrinfo(host, "123", &hints, &ai); - if(ga_result!=0){ - die(STATE_UNKNOWN, "error getting address for %s: %s\n", - host, gai_strerror(ga_result)); + 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 */ - for(ai_tmp=ai; ai_tmp!=NULL; ai_tmp=ai_tmp->ai_next){ num_hosts++; } - req=(ntp_message*)malloc(sizeof(ntp_message)*num_hosts); - if(req==NULL) die(STATE_UNKNOWN, "can not allocate ntp message array"); - socklist=(int*)malloc(sizeof(int)*num_hosts); - if(socklist==NULL) die(STATE_UNKNOWN, "can not allocate socket array"); - ufds=(struct pollfd*)malloc(sizeof(struct pollfd)*num_hosts); - if(ufds==NULL) die(STATE_UNKNOWN, "can not allocate socket array"); - servers=(ntp_server_results*)malloc(sizeof(ntp_server_results)*num_hosts); - if(servers==NULL) die(STATE_UNKNOWN, "can not allocate server array"); - memset(servers, 0, sizeof(ntp_server_results)*num_hosts); + for (ai_tmp = ai; ai_tmp != NULL; ai_tmp = ai_tmp->ai_next) { + num_hosts++; + } + req = (ntp_message *)malloc(sizeof(ntp_message) * num_hosts); + if (req == NULL) { + die(STATE_UNKNOWN, "can not allocate ntp message array"); + } + socklist = (int *)malloc(sizeof(int) * num_hosts); + if (socklist == NULL) { + die(STATE_UNKNOWN, "can not allocate socket array"); + } + ufds = (struct pollfd *)malloc(sizeof(struct pollfd) * num_hosts); + if (ufds == NULL) { + die(STATE_UNKNOWN, "can not allocate socket array"); + } + servers = (ntp_server_results *)malloc(sizeof(ntp_server_results) * num_hosts); + 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)); /* setup each socket for writing, and the corresponding struct pollfd */ - ai_tmp=ai; - for(i=0;ai_tmp;i++){ - socklist[i]=socket(ai_tmp->ai_family, SOCK_DGRAM, IPPROTO_UDP); - if(socklist[i] == -1) { + ai_tmp = ai; + for (i = 0; ai_tmp; i++) { + socklist[i] = socket(ai_tmp->ai_family, SOCK_DGRAM, IPPROTO_UDP); + if (socklist[i] == -1) { perror(NULL); die(STATE_UNKNOWN, "can not create new socket"); } - if(connect(socklist[i], ai_tmp->ai_addr, ai_tmp->ai_addrlen)){ + if (connect(socklist[i], ai_tmp->ai_addr, ai_tmp->ai_addrlen)) { /* don't die here, because it is enough if there is one server answering in time. This also would break for dual ipv4/6 stacked ntp servers when the client only supports on of them. */ DBG(printf("can't create socket connection on peer %i: %s\n", i, strerror(errno))); } else { - ufds[i].fd=socklist[i]; - ufds[i].events=POLLIN; - ufds[i].revents=0; + ufds[i].fd = socklist[i]; + ufds[i].events = POLLIN; + ufds[i].revents = 0; } ai_tmp = ai_tmp->ai_next; } /* now do AVG_NUM checks to each host. we stop before timeout/2 seconds * have passed in order to ensure post-processing and jitter time. */ - now_time=start_ts=time(NULL); - while(servers_completedflags, LI_NOWARNING); VN_SET(p->flags, VN_RESERVED); @@ -512,16 +553,16 @@ setup_control_request(ntp_control_message *p, uint8_t opcode, uint16_t seq){ } /* XXX handle responses with the error bit set */ -double jitter_request(int *status){ - int conn=-1, i, npeers=0, num_candidates=0; +double jitter_request(int *status) { + int conn = -1, i, npeers = 0, num_candidates = 0; bool syncsource_found = false; - int run=0, min_peer_sel=PEER_INCLUDED, num_selected=0, num_valid=0; - int peers_size=0, peer_offset=0; - ntp_assoc_status_pair *peers=NULL; + int run = 0, min_peer_sel = PEER_INCLUDED, num_selected = 0, num_valid = 0; + int peers_size = 0, peer_offset = 0; + ntp_assoc_status_pair *peers = NULL; ntp_control_message req; const char *getvar = "jitter"; double rval = 0.0, jitter = -1.0; - char *startofvalue=NULL, *nptr=NULL; + char *startofvalue = NULL, *nptr = NULL; void *tmp; /* Long-winded explanation: @@ -542,54 +583,62 @@ double jitter_request(int *status){ /* keep sending requests until the server stops setting the * REM_MORE bit, though usually this is only 1 packet. */ - do{ + do { setup_control_request(&req, OP_READSTAT, 1); DBG(printf("sending READSTAT request")); write(conn, &req, SIZEOF_NTPCM(req)); DBG(print_ntp_control_message(&req)); /* Attempt to read the largest size packet possible */ - req.count=htons(MAX_CM_SIZE); + req.count = htons(MAX_CM_SIZE); DBG(printf("receiving READSTAT response")) read(conn, &req, SIZEOF_NTPCM(req)); DBG(print_ntp_control_message(&req)); /* 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) + * we represent as a ntp_assoc_status_pair datatype. + */ + peers_size += ntohs(req.count); + 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)); - npeers=peers_size/sizeof(ntp_assoc_status_pair); - peer_offset+=ntohs(req.count); - } while(req.op&REM_MORE); + } + peers = tmp; + memcpy((void *)((ptrdiff_t)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); /* first, let's find out if we have a sync source, or if there are * at least some candidates. in the case of the latter we'll issue * a warning but go ahead with the check on them. */ - for (i = 0; i < npeers; i++){ - if (PEER_SEL(peers[i].status) >= PEER_INCLUDED){ + for (i = 0; i < npeers; i++) { + if (PEER_SEL(peers[i].status) >= PEER_INCLUDED) { num_candidates++; - if(PEER_SEL(peers[i].status) >= PEER_SYNCSOURCE){ + if (PEER_SEL(peers[i].status) >= PEER_SYNCSOURCE) { syncsource_found = true; - min_peer_sel=PEER_SYNCSOURCE; + min_peer_sel = PEER_SYNCSOURCE; } } } - if(verbose) printf("%d candidate peers available\n", num_candidates); - if(verbose && syncsource_found) printf("synchronization source found\n"); - if(! syncsource_found){ + if (verbose) { + printf("%d candidate peers available\n", num_candidates); + } + if (verbose && syncsource_found) { + printf("synchronization source found\n"); + } + if (!syncsource_found) { *status = STATE_UNKNOWN; - if(verbose) printf("warning: no synchronization source found\n"); + if (verbose) { + printf("warning: no synchronization source found\n"); + } } - - for (run=0; run= min_peer_sel){ - char jitter_data[MAX_CM_SIZE+1]; + if (PEER_SEL(peers[i].status) >= min_peer_sel) { + char jitter_data[MAX_CM_SIZE + 1]; size_t jitter_data_count; num_selected++; @@ -602,7 +651,7 @@ double jitter_request(int *status){ */ /* Older servers doesn't know what jitter is, so if we get an * error on the first pass we redo it with "dispersion" */ - strncpy(req.data, getvar, MAX_CM_SIZE-1); + strncpy(req.data, getvar, MAX_CM_SIZE - 1); req.count = htons(strlen(getvar)); DBG(printf("sending READVAR request...\n")); write(conn, &req, SIZEOF_NTPCM(req)); @@ -613,8 +662,11 @@ double jitter_request(int *status){ read(conn, &req, SIZEOF_NTPCM(req)); DBG(print_ntp_control_message(&req)); - if(req.op&REM_ERROR && strstr(getvar, "jitter")) { - if(verbose) printf("The 'jitter' command failed (old ntp server?)\nRestarting with 'dispersion'...\n"); + if (req.op & REM_ERROR && strstr(getvar, "jitter")) { + if (verbose) { + printf("The 'jitter' command failed (old ntp server?)\nRestarting with " + "'dispersion'...\n"); + } getvar = "dispersion"; num_selected--; i--; @@ -622,32 +674,33 @@ double jitter_request(int *status){ } /* get to the float value */ - if(verbose) { + if (verbose) { printf("parsing jitter from peer %.2x: ", ntohs(peers[i].assoc)); } - if((jitter_data_count = ntohs(req.count)) >= sizeof(jitter_data)){ - die(STATE_UNKNOWN, - _("jitter response too large (%lu bytes)\n"), - (unsigned long)jitter_data_count); + if ((jitter_data_count = ntohs(req.count)) >= sizeof(jitter_data)) { + die(STATE_UNKNOWN, _("jitter response too large (%lu bytes)\n"), + (unsigned long)jitter_data_count); } memcpy(jitter_data, req.data, jitter_data_count); jitter_data[jitter_data_count] = '\0'; startofvalue = strchr(jitter_data, '='); - if(startofvalue != NULL) { + if (startofvalue != NULL) { startofvalue++; jitter = strtod(startofvalue, &nptr); } - if(startofvalue == NULL || startofvalue==nptr){ + if (startofvalue == NULL || startofvalue == nptr) { printf("warning: unable to read server jitter response.\n"); *status = STATE_UNKNOWN; } else { - if(verbose) printf("%g\n", jitter); + if (verbose) { + printf("%g\n", jitter); + } num_valid++; rval += jitter; } } } - if(verbose){ + if (verbose) { printf("jitter parsed from %d/%d peers\n", num_valid, num_selected); } } @@ -655,37 +708,33 @@ double jitter_request(int *status){ rval = num_valid ? rval / num_valid : -1.0; close(conn); - if(peers!=NULL) free(peers); + if (peers != NULL) { + free(peers); + } /* If we return -1.0, it means no synchronization source was found */ return rval; } -int process_arguments(int argc, char **argv){ +int process_arguments(int argc, char **argv) { int c; - int option=0; + int option = 0; 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'}, - {"warning", required_argument, 0, 'w'}, - {"critical", required_argument, 0, 'c'}, - {"jwarn", required_argument, 0, 'j'}, - {"jcrit", required_argument, 0, 'k'}, - {"timeout", required_argument, 0, 't'}, - {"hostname", required_argument, 0, 'H'}, - {0, 0, 0, 0} - }; - - - if (argc < 2) - usage ("\n"); + {"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'}, {"warning", required_argument, 0, 'w'}, + {"critical", required_argument, 0, 'c'}, {"jwarn", required_argument, 0, 'j'}, + {"jcrit", required_argument, 0, 'k'}, {"timeout", required_argument, 0, 't'}, + {"hostname", required_argument, 0, 'H'}, {0, 0, 0, 0}}; + + if (argc < 2) { + usage("\n"); + } while (1) { - c = getopt_long (argc, argv, "Vhv46w:c:j:k:t:H:", longopts, &option); - if (c == -1 || c == EOF || c == 1) + c = getopt_long(argc, argv, "Vhv46w:c:j:k:t:H:", longopts, &option); + if (c == -1 || c == EOF || c == 1) { break; + } switch (c) { case 'h': @@ -716,12 +765,13 @@ int process_arguments(int argc, char **argv){ jcrit = optarg; break; case 'H': - if(!is_host(optarg)) + if (!is_host(optarg)) { usage2(_("Invalid hostname/address"), optarg); + } server_address = strdup(optarg); break; case 't': - socket_timeout=atoi(optarg); + socket_timeout = atoi(optarg); break; case '4': address_family = AF_INET; @@ -730,64 +780,59 @@ int process_arguments(int argc, char **argv){ #ifdef USE_IPV6 address_family = AF_INET6; #else - usage4 (_("IPv6 support not available")); + usage4(_("IPv6 support not available")); #endif break; case '?': /* print short usage statement if args not parsable */ - usage5 (); + usage5(); break; } } - if(server_address == NULL){ + if (server_address == NULL) { usage4(_("Hostname was not supplied")); } return 0; } -char *perfd_offset (double offset) -{ - return fperfdata ("offset", offset, "s", - true, offset_thresholds->warning->end, - true, offset_thresholds->critical->end, - false, 0, false, 0); +char *perfd_offset(double offset) { + return fperfdata("offset", offset, "s", true, offset_thresholds->warning->end, true, + offset_thresholds->critical->end, false, 0, false, 0); } -char *perfd_jitter (double jitter) -{ - return fperfdata ("jitter", jitter, "s", - do_jitter, jitter_thresholds->warning->end, - do_jitter, jitter_thresholds->critical->end, - true, 0, false, 0); +char *perfd_jitter(double jitter) { + return fperfdata("jitter", jitter, "s", do_jitter, jitter_thresholds->warning->end, do_jitter, + jitter_thresholds->critical->end, true, 0, false, 0); } -int main(int argc, char *argv[]){ +int main(int argc, char *argv[]) { int result, offset_result, jitter_result; - double offset=0, jitter=0; + double offset = 0, jitter = 0; char *result_line, *perfdata_line; - setlocale (LC_ALL, ""); - bindtextdomain (PACKAGE, LOCALEDIR); - textdomain (PACKAGE); + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); result = offset_result = jitter_result = STATE_OK; /* 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")); + if (process_arguments(argc, argv) == ERROR) { + usage4(_("Could not parse arguments")); + } set_thresholds(&offset_thresholds, owarn, ocrit); set_thresholds(&jitter_thresholds, jwarn, jcrit); /* 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); offset = offset_request(server_address, &offset_result); /* check_ntp used to always return CRITICAL if offset_result == STATE_UNKNOWN. @@ -803,31 +848,32 @@ int main(int argc, char *argv[]){ * servers recognize. Trying to check the jitter on OpenNTPD * (for example) will result in an error */ - if(do_jitter){ - jitter=jitter_request(&jitter_result); + if (do_jitter) { + jitter = jitter_request(&jitter_result); result = max_state_alt(result, get_status(jitter, jitter_thresholds)); /* -1 indicates that we couldn't calculate the jitter * Only overrides STATE_OK from the offset */ - if(jitter == -1.0 && result == STATE_OK) + if (jitter == -1.0 && result == STATE_OK) { result = STATE_UNKNOWN; + } } result = max_state_alt(result, jitter_result); switch (result) { - case STATE_CRITICAL : - xasprintf(&result_line, _("NTP CRITICAL:")); - break; - case STATE_WARNING : - xasprintf(&result_line, _("NTP WARNING:")); - break; - case STATE_OK : - xasprintf(&result_line, _("NTP OK:")); - break; - default : - xasprintf(&result_line, _("NTP UNKNOWN:")); - break; + case STATE_CRITICAL: + xasprintf(&result_line, _("NTP CRITICAL:")); + break; + case STATE_WARNING: + xasprintf(&result_line, _("NTP WARNING:")); + break; + case STATE_OK: + xasprintf(&result_line, _("NTP OK:")); + break; + default: + xasprintf(&result_line, _("NTP UNKNOWN:")); + break; } - if(offset_result == STATE_UNKNOWN){ + if (offset_result == STATE_UNKNOWN) { xasprintf(&result_line, "%s %s", result_line, _("Offset unknown")); xasprintf(&perfdata_line, ""); } else { @@ -836,41 +882,41 @@ int main(int argc, char *argv[]){ } if (do_jitter) { xasprintf(&result_line, "%s, jitter=%f", result_line, jitter); - xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_jitter(jitter)); + xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_jitter(jitter)); } printf("%s|%s\n", result_line, perfdata_line); - if(server_address!=NULL) free(server_address); + if (server_address != NULL) { + free(server_address); + } return result; } - - -void print_help(void){ +void print_help(void) { print_revision(progname, NP_VERSION); - printf ("Copyright (c) 2006 Sean Finney\n"); - printf (COPYRIGHT, copyright, email); + printf("Copyright (c) 2006 Sean Finney\n"); + printf(COPYRIGHT, copyright, email); - printf ("%s\n", _("This plugin checks the selected ntp server")); + printf("%s\n", _("This plugin checks the selected ntp server")); - printf ("\n\n"); + printf("\n\n"); print_usage(); - printf (UT_HELP_VRSN); - printf (UT_EXTRA_OPTS); - printf (UT_HOST_PORT, 'p', "123"); - printf (UT_IPv46); - printf (" %s\n", "-w, --warning=THRESHOLD"); - printf (" %s\n", _("Offset to result in warning status (seconds)")); - printf (" %s\n", "-c, --critical=THRESHOLD"); - printf (" %s\n", _("Offset to result in critical status (seconds)")); - printf (" %s\n", "-j, --jwarn=THRESHOLD"); - printf (" %s\n", _("Warning threshold for jitter")); - printf (" %s\n", "-k, --jcrit=THRESHOLD"); - printf (" %s\n", _("Critical threshold for jitter")); - printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); - printf (UT_VERBOSE); + printf(UT_HELP_VRSN); + printf(UT_EXTRA_OPTS); + printf(UT_HOST_PORT, 'p', "123"); + printf(UT_IPv46); + printf(" %s\n", "-w, --warning=THRESHOLD"); + printf(" %s\n", _("Offset to result in warning status (seconds)")); + printf(" %s\n", "-c, --critical=THRESHOLD"); + printf(" %s\n", _("Offset to result in critical status (seconds)")); + printf(" %s\n", "-j, --jwarn=THRESHOLD"); + printf(" %s\n", _("Warning threshold for jitter")); + printf(" %s\n", "-k, --jcrit=THRESHOLD"); + printf(" %s\n", _("Critical threshold for jitter")); + printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); + printf(UT_VERBOSE); printf("\n"); printf("%s\n", _("Notes:")); @@ -881,21 +927,21 @@ void print_help(void){ printf(" %s\n", _("Normal offset check:")); printf(" %s\n", ("./check_ntp -H ntpserv -w 0.5 -c 1")); printf("\n"); - printf(" %s\n", _("Check jitter too, avoiding critical notifications if jitter isn't available")); + printf(" %s\n", + _("Check jitter too, avoiding critical notifications if jitter isn't available")); printf(" %s\n", _("(See Notes above for more details on thresholds formats):")); printf(" %s\n", ("./check_ntp -H ntpserv -w 0.5 -c 1 -j -1:100 -k -1:200")); - printf (UT_SUPPORT); + printf(UT_SUPPORT); - printf ("%s\n", _("WARNING: check_ntp is deprecated. Please use check_ntp_peer or")); - printf ("%s\n\n", _("check_ntp_time instead.")); + printf("%s\n", _("WARNING: check_ntp is deprecated. Please use check_ntp_peer or")); + printf("%s\n\n", _("check_ntp_time instead.")); } -void -print_usage(void) -{ - printf ("%s\n", _("WARNING: check_ntp is deprecated. Please use check_ntp_peer or")); - printf ("%s\n\n", _("check_ntp_time instead.")); - printf ("%s\n", _("Usage:")); - printf(" %s -H [-w ] [-c ] [-j ] [-k ] [-4|-6] [-v verbose]\n", progname); +void print_usage(void) { + printf("%s\n", _("WARNING: check_ntp is deprecated. Please use check_ntp_peer or")); + printf("%s\n\n", _("check_ntp_time instead.")); + printf("%s\n", _("Usage:")); + printf(" %s -H [-w ] [-c ] [-j ] [-k ] [-4|-6] [-v verbose]\n", + progname); } diff --git a/plugins/check_ntp_peer.c b/plugins/check_ntp_peer.c index 5c4ff386..24d1c9b5 100644 --- a/plugins/check_ntp_peer.c +++ b/plugins/check_ntp_peer.c @@ -83,9 +83,9 @@ typedef struct { /* bits 1,2 are the leap indicator */ #define LI_MASK 0xc0 #define LI(x) ((x & LI_MASK) >> 6) -#define LI_SET(x, y) \ - do { \ - x |= ((y << 6) & LI_MASK); \ +#define LI_SET(x, y) \ + do { \ + x |= ((y << 6) & LI_MASK); \ } while (0) /* and these are the values of the leap indicator */ #define LI_NOWARNING 0x00 @@ -95,17 +95,17 @@ typedef struct { /* bits 3,4,5 are the ntp version */ #define VN_MASK 0x38 #define VN(x) ((x & VN_MASK) >> 3) -#define VN_SET(x, y) \ - do { \ - x |= ((y << 3) & VN_MASK); \ +#define VN_SET(x, y) \ + do { \ + x |= ((y << 3) & VN_MASK); \ } while (0) #define VN_RESERVED 0x02 /* bits 6,7,8 are the ntp mode */ #define MODE_MASK 0x07 #define MODE(x) (x & MODE_MASK) -#define MODE_SET(x, y) \ - do { \ - x |= (y & MODE_MASK); \ +#define MODE_SET(x, y) \ + do { \ + x |= (y & MODE_MASK); \ } while (0) /* here are some values */ #define MODE_CLIENT 0x03 @@ -117,9 +117,9 @@ typedef struct { #define REM_MORE 0x20 /* In control message, bits 11 - 15 are opcode */ #define OP_MASK 0x1f -#define OP_SET(x, y) \ - do { \ - x |= (y & OP_MASK); \ +#define OP_SET(x, y) \ + do { \ + x |= (y & OP_MASK); \ } while (0) #define OP_READSTAT 0x01 #define OP_READVAR 0x02 @@ -132,18 +132,19 @@ typedef struct { /* NTP control message header is 12 bytes, plus any data in the data * field, plus null padding to the nearest 32-bit boundary per rfc. */ -#define SIZEOF_NTPCM(m) (12 + ntohs(m.count) + ((ntohs(m.count) % 4) ? 4 - (ntohs(m.count) % 4) : 0)) +#define SIZEOF_NTPCM(m) \ + (12 + ntohs(m.count) + ((ntohs(m.count) % 4) ? 4 - (ntohs(m.count) % 4) : 0)) /* finally, a little helper or two for debugging: */ -#define DBG(x) \ - do { \ - if (verbose > 1) { \ - x; \ - } \ +#define DBG(x) \ + do { \ + if (verbose > 1) { \ + x; \ + } \ } while (0); -#define PRINTSOCKADDR(x) \ - do { \ - printf("%u.%u.%u.%u", (x >> 24) & 0xff, (x >> 16) & 0xff, (x >> 8) & 0xff, x & 0xff); \ +#define PRINTSOCKADDR(x) \ + do { \ + 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 *message) { @@ -360,7 +361,8 @@ ntp_request_result ntp_request(const check_ntp_peer_config config) { if (req.op & REM_ERROR) { if (strstr(getvar, "jitter")) { if (verbose) { - printf("The command failed. This is usually caused by servers refusing the 'jitter'\nvariable. Restarting with " + printf("The command failed. This is usually caused by servers refusing the " + "'jitter'\nvariable. Restarting with " "'dispersion'...\n"); } getvar = "stratum,offset,dispersion"; @@ -404,7 +406,8 @@ ntp_request_result ntp_request(const check_ntp_peer_config config) { if (verbose) { printf("%.10g\n", tmp_offset); } - if (result.offset_result == STATE_UNKNOWN || fabs(tmp_offset) < fabs(result.offset)) { + if (result.offset_result == STATE_UNKNOWN || + fabs(tmp_offset) < fabs(result.offset)) { result.offset = tmp_offset; result.offset_result = STATE_OK; } else { @@ -416,10 +419,12 @@ ntp_request_result ntp_request(const check_ntp_peer_config config) { if (config.do_jitter) { /* get the jitter */ if (verbose) { - printf("parsing %s from peer %.2x: ", strstr(getvar, "dispersion") != NULL ? "dispersion" : "jitter", + printf("parsing %s from peer %.2x: ", + strstr(getvar, "dispersion") != NULL ? "dispersion" : "jitter", ntohs(peers[i].assoc)); } - value = np_extract_ntpvar(data, strstr(getvar, "dispersion") != NULL ? "dispersion" : "jitter"); + value = np_extract_ntpvar(data, strstr(getvar, "dispersion") != NULL ? "dispersion" + : "jitter"); nptr = NULL; /* Convert the value if we have one */ if (value != NULL) { @@ -471,12 +476,15 @@ ntp_request_result ntp_request(const check_ntp_peer_config config) { 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'}, - {"warning", required_argument, 0, 'w'}, {"critical", required_argument, 0, 'c'}, {"swarn", required_argument, 0, 'W'}, - {"scrit", required_argument, 0, 'C'}, {"jwarn", required_argument, 0, 'j'}, {"jcrit", required_argument, 0, 'k'}, - {"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}}; + {"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'}, + {"warning", required_argument, 0, 'w'}, {"critical", required_argument, 0, 'c'}, + {"swarn", required_argument, 0, 'W'}, {"scrit", required_argument, 0, 'C'}, + {"jwarn", required_argument, 0, 'j'}, {"jcrit", required_argument, 0, 'k'}, + {"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) { usage("\n"); @@ -489,7 +497,8 @@ check_ntp_peer_config_wrapper process_arguments(int argc, char **argv) { 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); + 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) { break; } @@ -581,22 +590,24 @@ check_ntp_peer_config_wrapper process_arguments(int argc, char **argv) { } 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); + return fperfdata("offset", offset, "s", true, offset_thresholds->warning->end, true, + offset_thresholds->critical->end, false, 0, false, 0); } 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); + 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, 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); + 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, const bool do_truechimers, thresholds *truechimer_thresholds) { - return perfdata("truechimers", num_truechimers, "", do_truechimers, (int)truechimer_thresholds->warning->end, do_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); } @@ -686,9 +697,11 @@ int main(int argc, char *argv[]) { 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"), ntp_res.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"), ntp_res.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"), ntp_res.offset); } @@ -702,7 +715,8 @@ int main(int argc, char *argv[]) { } else { xasprintf(&result_line, "%s, jitter=%f", result_line, ntp_res.jitter); } - xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_jitter(ntp_res.jitter, config.do_jitter, config.jitter_thresholds)); + xasprintf(&perfdata_line, "%s %s", perfdata_line, + perfd_jitter(ntp_res.jitter, config.do_jitter, config.jitter_thresholds)); } if (config.do_stratum) { @@ -713,19 +727,23 @@ int main(int argc, char *argv[]) { } else { xasprintf(&result_line, "%s, stratum=%li", result_line, ntp_res.stratum); } - xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_stratum(ntp_res.stratum, config.do_stratum, config.stratum_thresholds)); + xasprintf(&perfdata_line, "%s %s", perfdata_line, + perfd_stratum(ntp_res.stratum, config.do_stratum, config.stratum_thresholds)); } if (config.do_truechimers) { if (tresult == STATE_WARNING) { - xasprintf(&result_line, "%s, truechimers=%i (WARNING)", result_line, ntp_res.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, ntp_res.num_truechimers); + xasprintf(&result_line, "%s, truechimers=%i (CRITICAL)", result_line, + ntp_res.num_truechimers); } else { xasprintf(&result_line, "%s, truechimers=%i", result_line, ntp_res.num_truechimers); } xasprintf(&perfdata_line, "%s %s", perfdata_line, - perfd_truechimers(ntp_res.num_truechimers, config.do_truechimers, config.truechimer_thresholds)); + perfd_truechimers(ntp_res.num_truechimers, config.do_truechimers, + config.truechimer_thresholds)); } printf("%s|%s\n", result_line, perfdata_line); @@ -753,7 +771,8 @@ void print_help(void) { printf(UT_IPv46); printf(UT_HOST_PORT, 'p', "123"); printf(" %s\n", "-q, --quiet"); - printf(" %s\n", _("Returns UNKNOWN instead of CRITICAL or WARNING if server isn't synchronized")); + printf(" %s\n", + _("Returns UNKNOWN instead of CRITICAL or WARNING if server isn't synchronized")); printf(" %s\n", "-w, --warning=THRESHOLD"); printf(" %s\n", _("Offset to result in warning status (seconds)")); printf(" %s\n", "-c, --critical=THRESHOLD"); @@ -790,7 +809,8 @@ void print_help(void) { printf(" %s\n", _("Simple NTP server check:")); printf(" %s\n", ("./check_ntp_peer -H ntpserv -w 0.5 -c 1")); printf("\n"); - printf(" %s\n", _("Check jitter too, avoiding critical notifications if jitter isn't available")); + printf(" %s\n", + _("Check jitter too, avoiding critical notifications if jitter isn't available")); printf(" %s\n", _("(See Notes above for more details on thresholds formats):")); printf(" %s\n", ("./check_ntp_peer -H ntpserv -w 0.5 -c 1 -j -1:100 -k -1:200")); printf("\n"); diff --git a/plugins/check_ntp_time.c b/plugins/check_ntp_time.c index 31162883..ad69b804 100644 --- a/plugins/check_ntp_time.c +++ b/plugins/check_ntp_time.c @@ -93,9 +93,9 @@ typedef struct { /* bits 1,2 are the leap indicator */ #define LI_MASK 0xc0 #define LI(x) ((x & LI_MASK) >> 6) -#define LI_SET(x, y) \ - do { \ - x |= ((y << 6) & LI_MASK); \ +#define LI_SET(x, y) \ + do { \ + x |= ((y << 6) & LI_MASK); \ } while (0) /* and these are the values of the leap indicator */ #define LI_NOWARNING 0x00 @@ -105,17 +105,17 @@ typedef struct { /* bits 3,4,5 are the ntp version */ #define VN_MASK 0x38 #define VN(x) ((x & VN_MASK) >> 3) -#define VN_SET(x, y) \ - do { \ - x |= ((y << 3) & VN_MASK); \ +#define VN_SET(x, y) \ + do { \ + x |= ((y << 3) & VN_MASK); \ } while (0) #define VN_RESERVED 0x02 /* bits 6,7,8 are the ntp mode */ #define MODE_MASK 0x07 #define MODE(x) (x & MODE_MASK) -#define MODE_SET(x, y) \ - do { \ - x |= (y & MODE_MASK); \ +#define MODE_SET(x, y) \ + do { \ + x |= (y & MODE_MASK); \ } while (0) /* here are some values */ #define MODE_CLIENT 0x03 @@ -127,9 +127,9 @@ typedef struct { #define REM_MORE 0x20 /* In control message, bits 11 - 15 are opcode */ #define OP_MASK 0x1f -#define OP_SET(x, y) \ - do { \ - x |= (y & OP_MASK); \ +#define OP_SET(x, y) \ + do { \ + x |= (y & OP_MASK); \ } while (0) #define OP_READSTAT 0x01 #define OP_READVAR 0x02 @@ -163,32 +163,34 @@ typedef struct { #define NTP32asDOUBLE(x) (ntohs(L16(x)) + ((double)ntohs(R16(x)) / 65536.0)) /* likewise for a 64-bit ntp fp number */ -#define NTP64asDOUBLE(n) \ - (double)(((uint64_t)n) ? (ntohl(L32(n)) - EPOCHDIFF) + (.00000001 * (0.5 + (double)(ntohl(R32(n)) / 42.94967296))) : 0) +#define NTP64asDOUBLE(n) \ + (double)(((uint64_t)n) ? (ntohl(L32(n)) - EPOCHDIFF) + \ + (.00000001 * (0.5 + (double)(ntohl(R32(n)) / 42.94967296))) \ + : 0) /* convert a struct timeval to a double */ #define TVasDOUBLE(x) (double)(x.tv_sec + (0.000001 * x.tv_usec)) /* convert an ntp 64-bit fp number to a struct timeval */ -#define NTP64toTV(n, t) \ - do { \ - if (!n) \ - t.tv_sec = t.tv_usec = 0; \ - else { \ - t.tv_sec = ntohl(L32(n)) - EPOCHDIFF; \ - t.tv_usec = (int)(0.5 + (double)(ntohl(R32(n)) / 4294.967296)); \ - } \ +#define NTP64toTV(n, t) \ + do { \ + if (!n) \ + t.tv_sec = t.tv_usec = 0; \ + else { \ + t.tv_sec = ntohl(L32(n)) - EPOCHDIFF; \ + t.tv_usec = (int)(0.5 + (double)(ntohl(R32(n)) / 4294.967296)); \ + } \ } while (0) /* convert a struct timeval to an ntp 64-bit fp number */ -#define TVtoNTP64(t, n) \ - do { \ - if (!t.tv_usec && !t.tv_sec) \ - n = 0x0UL; \ - else { \ - L32(n) = htonl(t.tv_sec + EPOCHDIFF); \ - R32(n) = htonl((uint64_t)((4294.967296 * t.tv_usec) + .5)); \ - } \ +#define TVtoNTP64(t, n) \ + do { \ + if (!t.tv_usec && !t.tv_sec) \ + n = 0x0UL; \ + else { \ + L32(n) = htonl(t.tv_sec + EPOCHDIFF); \ + R32(n) = htonl((uint64_t)((4294.967296 * t.tv_usec) + .5)); \ + } \ } while (0) /* NTP control message header is 12 bytes, plus any data in the data @@ -197,15 +199,15 @@ typedef struct { #define SIZEOF_NTPCM(m) (12 + ntohs(m.count) + ((m.count) ? 4 - (ntohs(m.count) % 4) : 0)) /* finally, a little helper or two for debugging: */ -#define DBG(x) \ - do { \ - if (verbose > 1) { \ - x; \ - } \ +#define DBG(x) \ + do { \ + if (verbose > 1) { \ + x; \ + } \ } while (0); -#define PRINTSOCKADDR(x) \ - do { \ - printf("%u.%u.%u.%u", (x >> 24) & 0xff, (x >> 16) & 0xff, (x >> 8) & 0xff, x & 0xff); \ +#define PRINTSOCKADDR(x) \ + do { \ + printf("%u.%u.%u.%u", (x >> 24) & 0xff, (x >> 16) & 0xff, (x >> 8) & 0xff, x & 0xff); \ } while (0); /* calculate the offset of the local clock */ @@ -358,7 +360,8 @@ double offset_request(const char *host, const char *port, mp_state_enum *status, die(STATE_UNKNOWN, "can not allocate socket array"); } - ntp_server_results *servers = (ntp_server_results *)malloc(sizeof(ntp_server_results) * num_hosts); + ntp_server_results *servers = + (ntp_server_results *)malloc(sizeof(ntp_server_results) * num_hosts); if (servers == NULL) { die(STATE_UNKNOWN, "can not allocate server array"); } @@ -585,8 +588,8 @@ check_ntp_time_config_wrapper process_arguments(int argc, char **argv) { } 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); + return fperfdata("offset", offset, "s", true, offset_thresholds->warning->end, true, + offset_thresholds->critical->end, false, 0, false, 0); } int main(int argc, char *argv[]) { @@ -613,7 +616,8 @@ int main(int argc, char *argv[]) { 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); + double offset = + offset_request(config.server_address, config.port, &offset_result, config.time_offset); if (offset_result == STATE_UNKNOWN) { result = ((!config.quiet) ? STATE_UNKNOWN : STATE_CRITICAL); } else { @@ -701,5 +705,6 @@ void print_help(void) { void print_usage(void) { printf("%s\n", _("Usage:")); - printf(" %s -H [-4|-6] [-w ] [-c ] [-v verbose] [-o