From 37c543e2b20657a8f4c120ba6b52e8e605a417bb Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 12 Mar 2025 13:50:39 +0100 Subject: Remove check_nwstat check_nwstat is a plugin which was used to determine the health of things on Novel machines. Since Novel is quite dead (even more so the product, this can be removed and this commit does just that to reduce ressource usage. --- .github/monitoring-plugins.spec | 14 -------------- 1 file changed, 14 deletions(-) (limited to '.github/monitoring-plugins.spec') diff --git a/.github/monitoring-plugins.spec b/.github/monitoring-plugins.spec index 64ee34f2..10799128 100644 --- a/.github/monitoring-plugins.spec +++ b/.github/monitoring-plugins.spec @@ -191,7 +191,6 @@ Requires: %{name}-nt Requires: %{name}-ntp Requires: %{name}-ntp_peer Requires: %{name}-ntp_time -Requires: %{name}-nwstat Requires: %{name}-oracle Requires: %{name}-pgsql Requires: %{name}-ping @@ -702,19 +701,6 @@ Provides check_ntp_time of the Monitoring Plugins. -# check_nwstat -%package nwstat -Summary: Monitoring Plugins - check_nwstat -Requires: %{name} = %{version}-%{release} - -%description nwstat -Provides check_nwstat of the Monitoring Plugins. - -%files nwstat -%{plugindir}/check_nwstat - - - # check_oracle %package oracle Summary: Monitoring Plugins - check_oracle -- cgit v1.2.3-74-g34f1 From 776c51a66f6eb9c3d6f018cb3786c6441f6b7171 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 27 Aug 2025 19:18:15 +0200 Subject: Add netsnmp lib to specfile --- .github/monitoring-plugins.spec | 1 + 1 file changed, 1 insertion(+) (limited to '.github/monitoring-plugins.spec') diff --git a/.github/monitoring-plugins.spec b/.github/monitoring-plugins.spec index 10799128..e3352988 100644 --- a/.github/monitoring-plugins.spec +++ b/.github/monitoring-plugins.spec @@ -824,6 +824,7 @@ Provides check_smtp of the Monitoring Plugins. Summary: Monitoring Plugins - check_snmp Requires: %{name} = %{version}-%{release} Requires: net-snmp +Build-Requires: net-snmp-devel %description snmp Provides check_snmp of the Monitoring Plugins. -- cgit v1.2.3-74-g34f1 From d3e1c0314d94e9f97c822fc80659c7234308045f Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 27 Aug 2025 19:29:56 +0200 Subject: Fix Specfile requires --- .github/monitoring-plugins.spec | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to '.github/monitoring-plugins.spec') diff --git a/.github/monitoring-plugins.spec b/.github/monitoring-plugins.spec index e3352988..ce22606b 100644 --- a/.github/monitoring-plugins.spec +++ b/.github/monitoring-plugins.spec @@ -88,6 +88,9 @@ BuildRequires: postgresql-devel # check_radius BuildRequires: radcli-devel +# check_snmp +BuildRequires: net-snmp-devel + %description Common files for Monitoring Plugins @@ -824,7 +827,6 @@ Provides check_smtp of the Monitoring Plugins. Summary: Monitoring Plugins - check_snmp Requires: %{name} = %{version}-%{release} Requires: net-snmp -Build-Requires: net-snmp-devel %description snmp Provides check_snmp of the Monitoring Plugins. -- cgit v1.2.3-74-g34f1 From 30a9908d8d02fe7ffc813adfe80e24663dcee654 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 3 Dec 2025 22:39:19 +0100 Subject: Remove check_nt (#2195) check_nt was used to connect NSclient++ on windows, both the method and the target are pretty much dead. Therefor check_nt gets removed. --- .github/monitoring-plugins.spec | 13 - .gitignore | 1 - REQUIREMENTS | 8 +- configure.ac | 5 - plugins/Makefile.am | 4 +- plugins/check_nt.c | 789 ---------------------------------------- plugins/check_nt.d/config.h | 53 --- plugins/tests/check_nt.t | 80 ---- 8 files changed, 3 insertions(+), 950 deletions(-) delete mode 100644 plugins/check_nt.c delete mode 100644 plugins/check_nt.d/config.h delete mode 100755 plugins/tests/check_nt.t (limited to '.github/monitoring-plugins.spec') diff --git a/.github/monitoring-plugins.spec b/.github/monitoring-plugins.spec index ce22606b..5878a862 100644 --- a/.github/monitoring-plugins.spec +++ b/.github/monitoring-plugins.spec @@ -652,19 +652,6 @@ Provides check_nagios of the Monitoring Plugins. -# check_nt -%package nt -Summary: Monitoring Plugins - check_nt -Requires: %{name} = %{version}-%{release} - -%description nt -Provides check_nt of the Monitoring Plugins. - -%files nt -%{plugindir}/check_nt - - - # check_ntp %package ntp Summary: Monitoring Plugins - check_ntp diff --git a/.gitignore b/.gitignore index 00e19d52..a91edd7c 100644 --- a/.gitignore +++ b/.gitignore @@ -174,7 +174,6 @@ plugins/check_disk.d/.dirstamp /plugins/check_netsaint /plugins/check_nntp /plugins/check_nntps -/plugins/check_nt /plugins/check_ntp /plugins/check_ntp_peer /plugins/check_ntp_time diff --git a/REQUIREMENTS b/REQUIREMENTS index 551fdb1a..8f1befbd 100644 --- a/REQUIREMENTS +++ b/REQUIREMENTS @@ -26,7 +26,7 @@ check_curl: other SSL implementations are currently not supported - uriparser 0.7.5 or later https://uriparser.github.io/ - + check_fping: - Requires the fping utility distributed with SATAN. Either download and install SATAN or grab the fping program from @@ -87,16 +87,12 @@ check_ifstatus/check_ifoperstatus - Requires Net::SNMP perl module http://www.perl.com/CPAN/modules/by-authors/id/D/DT/DTOWN/ -check_nt: - - Requires NSClient to run on the NT server to monitor - http://nsclient.ready2run.nl/ - check_ups: - Requires Network UPS Tools (>= 1.4) to run on the server to monitor http://www.networkupstools.org/ check_ide_smart: - - Uses the Linux specific SMART interface [http://smartlinux.sourceforge.net/smart/index.php]. + - Uses the Linux specific SMART interface [http://smartlinux.sourceforge.net/smart/index.php]. OS Specific Issues ------------------ diff --git a/configure.ac b/configure.ac index 705183a2..2bf94014 100644 --- a/configure.ac +++ b/configure.ac @@ -1832,11 +1832,6 @@ if test -n "$PATH_TO_APTGET" ; then fi -if test -f $srcdir/plugins/check_nt.c ; then - EXTRAS="$EXTRAS check_nt\$(EXEEXT)" -fi - - dnl used in check_dhcp AC_CHECK_HEADERS(sys/sockio.h) diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 1a9399f0..877c0947 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -44,7 +44,7 @@ check_tcp_programs = check_ftp check_imap check_nntp check_pop \ EXTRA_PROGRAMS = check_mysql check_radius check_pgsql check_hpjd \ check_swap check_fping check_ldap check_game check_dig \ - check_nagios check_by_ssh check_dns check_nt check_ide_smart \ + check_nagios check_by_ssh check_dns check_ide_smart \ check_procs check_mysql_query check_apt check_dbi check_curl \ \ tests/test_check_swap \ @@ -76,7 +76,6 @@ EXTRA_DIST = t \ check_tcp.d \ check_real.d \ check_ssh.d \ - check_nt.d \ check_dns.d \ check_mrtgtraf.d \ check_mysql_query.d \ @@ -157,7 +156,6 @@ check_mysql_query_CFLAGS = $(AM_CFLAGS) $(MYSQLCFLAGS) check_mysql_query_CPPFLAGS = $(AM_CPPFLAGS) $(MYSQLINCLUDE) check_mysql_query_LDADD = $(NETLIBS) $(MYSQLLIBS) check_nagios_LDADD = $(BASEOBJS) -check_nt_LDADD = $(NETLIBS) check_ntp_LDADD = $(NETLIBS) $(MATHLIBS) check_ntp_peer_LDADD = $(NETLIBS) $(MATHLIBS) check_pgsql_LDADD = $(NETLIBS) $(PGLIBS) diff --git a/plugins/check_nt.c b/plugins/check_nt.c deleted file mode 100644 index 35ca92cd..00000000 --- a/plugins/check_nt.c +++ /dev/null @@ -1,789 +0,0 @@ -/***************************************************************************** - * - * Monitoring check_nt plugin - * - * License: GPL - * Copyright (c) 2000-2002 Yves Rubin (rubiyz@yahoo.com) - * Copyright (c) 2003-2024 Monitoring Plugins Development Team - * - * Description: - * - * This file contains the check_nt plugin - * - * This plugin collects data from the NSClient service running on a - * Windows NT/2000/XP/2003 server. - * This plugin requires NSClient software to run on NT - * (https://nsclient.org/) - * - * - * 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_nt"; -const char *copyright = "2000-2024"; -const char *email = "devel@monitoring-plugins.org"; - -#include "common.h" -#include "netutils.h" -#include "utils.h" -#include "check_nt.d/config.h" - -enum { - MAX_VALUE_LIST = 30, -}; - -static char recv_buffer[MAX_INPUT_BUFFER]; - -static void fetch_data(const char *address, int port, const char *sendb); - -typedef struct { - int errorcode; - check_nt_config config; -} check_nt_config_wrapper; -static check_nt_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); - -static void preparelist(char *string); -static bool strtoularray(unsigned long *array, char *string, const char *delim); -static void print_help(void); -void print_usage(void); - -int main(int argc, char **argv) { - setlocale(LC_ALL, ""); - bindtextdomain(PACKAGE, LOCALEDIR); - textdomain(PACKAGE); - - /* Parse extra opts if any */ - argv = np_extra_opts(&argc, argv, progname); - - check_nt_config_wrapper tmp_config = process_arguments(argc, argv); - if (tmp_config.errorcode == ERROR) { - usage4(_("Could not parse arguments")); - } - - const check_nt_config config = tmp_config.config; - - /* initialize alarm signal handling */ - signal(SIGALRM, socket_timeout_alarm_handler); - - /* set socket timeout */ - alarm(socket_timeout); - - int return_code = STATE_UNKNOWN; - char *send_buffer = NULL; - char *output_message = NULL; - char *perfdata = NULL; - char *temp_string = NULL; - char *temp_string_perf = NULL; - char *description = NULL; - char *counter_unit = NULL; - char *errcvt = NULL; - unsigned long lvalue_list[MAX_VALUE_LIST]; - switch (config.vars_to_check) { - case CHECK_CLIENTVERSION: - xasprintf(&send_buffer, "%s&1", config.req_password); - fetch_data(config.server_address, config.server_port, send_buffer); - if (config.value_list != NULL && strcmp(recv_buffer, config.value_list) != 0) { - xasprintf(&output_message, _("Wrong client version - running: %s, required: %s"), - recv_buffer, config.value_list); - return_code = STATE_WARNING; - } else { - xasprintf(&output_message, "%s", recv_buffer); - return_code = STATE_OK; - } - break; - case CHECK_CPULOAD: - if (config.value_list == NULL) { - output_message = strdup(_("missing -l parameters")); - } else if (!strtoularray(lvalue_list, config.value_list, ",")) { - output_message = strdup(_("wrong -l parameter.")); - } else { - /* -l parameters is present with only integers */ - return_code = STATE_OK; - temp_string = strdup(_("CPU Load")); - temp_string_perf = strdup(" "); - - /* loop until one of the parameters is wrong or not present */ - int offset = 0; - while (lvalue_list[0 + offset] > (unsigned long)0 && - lvalue_list[0 + offset] <= (unsigned long)17280 && - lvalue_list[1 + offset] > (unsigned long)0 && - lvalue_list[1 + offset] <= (unsigned long)100 && - lvalue_list[2 + offset] > (unsigned long)0 && - lvalue_list[2 + offset] <= (unsigned long)100) { - - /* Send request and retrieve data */ - xasprintf(&send_buffer, "%s&2&%lu", config.req_password, lvalue_list[0 + offset]); - fetch_data(config.server_address, config.server_port, send_buffer); - - unsigned long utilization = strtoul(recv_buffer, NULL, 10); - - /* Check if any of the request is in a warning or critical state */ - if (utilization >= lvalue_list[2 + offset]) { - return_code = STATE_CRITICAL; - } else if (utilization >= lvalue_list[1 + offset] && return_code < STATE_WARNING) { - return_code = STATE_WARNING; - } - - xasprintf(&output_message, _(" %lu%% (%lu min average)"), utilization, - lvalue_list[0 + offset]); - xasprintf(&temp_string, "%s%s", temp_string, output_message); - 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 */ - } - - if (strlen(temp_string) > 10) { /* we had at least one loop */ - output_message = strdup(temp_string); - perfdata = temp_string_perf; - } else { - output_message = strdup(_("not enough values for -l parameters")); - } - } - break; - case CHECK_UPTIME: { - char *tmp_value_list = config.value_list; - 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)) { - - output_message = strdup(_("wrong -l argument")); - } else { - xasprintf(&send_buffer, "%s&3", config.req_password); - fetch_data(config.server_address, config.server_port, send_buffer); - unsigned long uptime = strtoul(recv_buffer, NULL, 10); - int updays = uptime / 86400; - int uphours = (uptime % 86400) / 3600; - int upminutes = ((uptime % 86400) % 3600) / 60; - - if (!strncmp(tmp_value_list, "minutes", strlen("minutes"))) { - uptime = uptime / 60; - } else if (!strncmp(tmp_value_list, "hours", strlen("hours"))) { - uptime = uptime / 3600; - } else if (!strncmp(tmp_value_list, "days", strlen("days"))) { - uptime = uptime / 86400; - } - /* else uptime in seconds, nothing to do */ - - xasprintf(&output_message, - _("System Uptime - %u day(s) %u hour(s) %u minute(s) |uptime=%lu"), updays, - uphours, upminutes, uptime); - - if (config.check_critical_value && uptime <= config.critical_value) { - return_code = STATE_CRITICAL; - } else if (config.check_warning_value && uptime <= config.warning_value) { - return_code = STATE_WARNING; - } else { - return_code = STATE_OK; - } - } - } break; - case CHECK_USEDDISKSPACE: - if (config.value_list == NULL) { - output_message = strdup(_("missing -l parameters")); - } else if (strlen(config.value_list) != 1) { - output_message = strdup(_("wrong -l argument")); - } else { - xasprintf(&send_buffer, "%s&4&%s", config.req_password, config.value_list); - fetch_data(config.server_address, config.server_port, send_buffer); - char *fds = strtok(recv_buffer, "&"); - char *tds = strtok(NULL, "&"); - double total_disk_space = 0; - double free_disk_space = 0; - if (fds != NULL) { - free_disk_space = atof(fds); - } - if (tds != NULL) { - total_disk_space = atof(tds); - } - - if (total_disk_space > 0 && free_disk_space >= 0) { - 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); - - 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) { - return_code = STATE_WARNING; - } else { - return_code = STATE_OK; - } - - output_message = strdup(temp_string); - perfdata = temp_string_perf; - } else { - output_message = strdup(_("Free disk space : Invalid drive")); - return_code = STATE_UNKNOWN; - } - } - break; - case CHECK_SERVICESTATE: - case CHECK_PROCSTATE: - 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, - (config.show_all) ? "ShowAll" : "ShowFail", config.value_list); - fetch_data(config.server_address, config.server_port, send_buffer); - char *numstr = strtok(recv_buffer, "&"); - if (numstr == NULL) { - die(STATE_UNKNOWN, _("could not fetch information from server\n")); - } - return_code = atoi(numstr); - temp_string = strtok(NULL, "&"); - output_message = strdup(temp_string); - } - break; - case CHECK_MEMUSE: - xasprintf(&send_buffer, "%s&7", config.req_password); - fetch_data(config.server_address, config.server_port, send_buffer); - char *numstr = strtok(recv_buffer, "&"); - if (numstr == NULL) { - die(STATE_UNKNOWN, _("could not fetch information from server\n")); - } - double mem_commitLimit = atof(numstr); - numstr = strtok(NULL, "&"); - if (numstr == NULL) { - die(STATE_UNKNOWN, _("could not fetch information from server\n")); - } - double mem_commitByte = atof(numstr); - double percent_used_space = (mem_commitByte / mem_commitLimit) * 100; - double warning_used_space = ((float)config.warning_value / 100) * mem_commitLimit; - double critical_used_space = ((float)config.critical_value / 100) * mem_commitLimit; - - /* Divisor should be 1048567, not 3044515, as we are measuring "Commit Charge" here, - which equals RAM + Pagefiles. */ - 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; - 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) { - return_code = STATE_WARNING; - } - - break; - case CHECK_COUNTER: { - /* - CHECK_COUNTER has been modified to provide extensive perfdata information. - In order to do this, some modifications have been done to the code - and some constraints have been introduced. - - 1) For the sake of simplicity of the code, perfdata information will only be - provided when the "description" field is added. - - 2) If the counter you're going to measure is percent-based, the code will detect - the percent sign in its name and will attribute minimum (0%) and maximum (100%) - values automagically, as well the "%" sign to graph units. - - 3) OTOH, if the counter is "absolute", you'll have to provide the following - 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. - */ - - 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 */ - bool isPercent = (strchr(config.value_list, '%') != NULL); - - strtok(config.value_list, "&"); /* burn the first parameters */ - description = strtok(NULL, "&"); - counter_unit = strtok(NULL, "&"); - xasprintf(&send_buffer, "%s&8&%s", config.req_password, config.value_list); - fetch_data(config.server_address, config.server_port, send_buffer); - counter_value = atof(recv_buffer); - - bool allRight = false; - if (description == NULL) { - xasprintf(&output_message, "%.f", counter_value); - } else if (isPercent) { - counter_unit = strdup("%"); - allRight = true; - } - - char *minval = NULL; - char *maxval = NULL; - double fminval = 0; - double fmaxval = 0; - if ((counter_unit != NULL) && (!allRight)) { - minval = strtok(NULL, "&"); - maxval = strtok(NULL, "&"); - - /* All parameters specified. Let's check the numbers */ - - fminval = (minval != NULL) ? strtod(minval, &errcvt) : -1; - fmaxval = (minval != NULL) ? strtod(maxval, &errcvt) : -1; - - if ((fminval == 0) && (minval == errcvt)) { - output_message = strdup(_("Minimum value contains non-numbers")); - } else { - if ((fmaxval == 0) && (maxval == errcvt)) { - output_message = strdup(_("Maximum value contains non-numbers")); - } else { - allRight = true; /* Everything is OK. */ - } - } - } else if ((counter_unit == NULL) && (description != NULL)) { - output_message = strdup(_("No unit counter specified")); - } - - if (allRight) { - /* Let's format the output string, finally... */ - if (strstr(description, "%") == NULL) { - 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)); - } - } - - if (config.critical_value > config.warning_value) { /* Normal thresholds */ - if (config.check_critical_value && counter_value >= config.critical_value) { - return_code = STATE_CRITICAL; - } else if (config.check_warning_value && counter_value >= config.warning_value) { - return_code = STATE_WARNING; - } else { - return_code = STATE_OK; - } - } else { /* inverse thresholds */ - return_code = STATE_OK; - if (config.check_critical_value && counter_value <= config.critical_value) { - return_code = STATE_CRITICAL; - } else if (config.check_warning_value && counter_value <= config.warning_value) { - return_code = STATE_WARNING; - } - } - } break; - case CHECK_FILEAGE: - if (config.value_list == NULL) { - output_message = strdup(_("No counter specified")); - } else { - preparelist( - config.value_list); /* replace , between services with & to send the request */ - xasprintf(&send_buffer, "%s&9&%s", config.req_password, config.value_list); - fetch_data(config.server_address, config.server_port, send_buffer); - unsigned long age_in_minutes = atoi(strtok(recv_buffer, "&")); - description = strtok(NULL, "&"); - output_message = strdup(description); - - if (config.critical_value > config.warning_value) { /* Normal thresholds */ - if (config.check_critical_value && age_in_minutes >= config.critical_value) { - return_code = STATE_CRITICAL; - } else if (config.check_warning_value && age_in_minutes >= config.warning_value) { - return_code = STATE_WARNING; - } else { - return_code = STATE_OK; - } - } else { /* inverse thresholds */ - if (config.check_critical_value && age_in_minutes <= config.critical_value) { - return_code = STATE_CRITICAL; - } else if (config.check_warning_value && age_in_minutes <= config.warning_value) { - return_code = STATE_WARNING; - } else { - return_code = STATE_OK; - } - } - } - break; - - case CHECK_INSTANCES: - if (config.value_list == NULL) { - output_message = strdup(_("No counter specified")); - } else { - xasprintf(&send_buffer, "%s&10&%s", config.req_password, config.value_list); - fetch_data(config.server_address, config.server_port, send_buffer); - if (!strncmp(recv_buffer, "ERROR", 5)) { - printf("NSClient - %s\n", recv_buffer); - exit(STATE_UNKNOWN); - } - xasprintf(&output_message, "%s", recv_buffer); - return_code = STATE_OK; - } - break; - - case CHECK_NONE: - default: - usage4(_("Please specify a variable to check")); - break; - } - - /* reset timeout */ - alarm(0); - - if (perfdata == NULL) { - printf("%s\n", output_message); - } else { - printf("%s | %s\n", output_message, perfdata); - } - return return_code; -} - -/* process command-line arguments */ -check_nt_config_wrapper process_arguments(int argc, char **argv) { - static struct option longopts[] = {{"port", required_argument, 0, 'p'}, - {"timeout", required_argument, 0, 't'}, - {"critical", required_argument, 0, 'c'}, - {"warning", required_argument, 0, 'w'}, - {"variable", required_argument, 0, 'v'}, - {"hostname", required_argument, 0, 'H'}, - {"params", required_argument, 0, 'l'}, - {"secret", required_argument, 0, 's'}, - {"display", required_argument, 0, 'd'}, - {"unknown-timeout", no_argument, 0, 'u'}, - {"version", no_argument, 0, 'V'}, - {"help", no_argument, 0, 'h'}, - {0, 0, 0, 0}}; - - check_nt_config_wrapper result = { - .errorcode = OK, - .config = check_nt_config_init(), - }; - - /* no options were supplied */ - if (argc < 2) { - result.errorcode = ERROR; - return result; - } - - /* backwards compatibility */ - if (!is_option(argv[1])) { - result.config.server_address = strdup(argv[1]); - argv[1] = argv[0]; - argv = &argv[1]; - argc--; - } - - for (int index = 1; index < argc; index++) { - if (strcmp("-to", argv[index]) == 0) { - strcpy(argv[index], "-t"); - } else if (strcmp("-wv", argv[index]) == 0) { - strcpy(argv[index], "-w"); - } else if (strcmp("-cv", argv[index]) == 0) { - strcpy(argv[index], "-c"); - } - } - - int option = 0; - while (true) { - int option_index = getopt_long(argc, argv, "+hVH:t:c:w:p:v:l:s:d:u", longopts, &option); - - if (option_index == -1 || option_index == EOF || option_index == 1) { - break; - } - - switch (option_index) { - case '?': /* print short usage statement if args not parsable */ - usage5(); - case 'h': /* help */ - print_help(); - exit(STATE_UNKNOWN); - case 'V': /* version */ - print_revision(progname, NP_VERSION); - exit(STATE_UNKNOWN); - case 'H': /* hostname */ - result.config.server_address = optarg; - break; - case 's': /* password */ - result.config.req_password = optarg; - break; - case 'p': /* port */ - if (is_intnonneg(optarg)) { - result.config.server_port = atoi(optarg); - } else { - die(STATE_UNKNOWN, _("Server port must be an integer\n")); - } - break; - case 'v': - if (strlen(optarg) < 4) { - result.errorcode = ERROR; - return result; - } - if (!strcmp(optarg, "CLIENTVERSION")) { - result.config.vars_to_check = CHECK_CLIENTVERSION; - } else if (!strcmp(optarg, "CPULOAD")) { - result.config.vars_to_check = CHECK_CPULOAD; - } else if (!strcmp(optarg, "UPTIME")) { - result.config.vars_to_check = CHECK_UPTIME; - } else if (!strcmp(optarg, "USEDDISKSPACE")) { - result.config.vars_to_check = CHECK_USEDDISKSPACE; - } else if (!strcmp(optarg, "SERVICESTATE")) { - result.config.vars_to_check = CHECK_SERVICESTATE; - } else if (!strcmp(optarg, "PROCSTATE")) { - result.config.vars_to_check = CHECK_PROCSTATE; - } else if (!strcmp(optarg, "MEMUSE")) { - result.config.vars_to_check = CHECK_MEMUSE; - } else if (!strcmp(optarg, "COUNTER")) { - result.config.vars_to_check = CHECK_COUNTER; - } else if (!strcmp(optarg, "FILEAGE")) { - result.config.vars_to_check = CHECK_FILEAGE; - } else if (!strcmp(optarg, "INSTANCES")) { - result.config.vars_to_check = CHECK_INSTANCES; - } else { - result.errorcode = ERROR; - return result; - } - break; - case 'l': /* value list */ - result.config.value_list = optarg; - break; - case 'w': /* warning threshold */ - result.config.warning_value = strtoul(optarg, NULL, 10); - result.config.check_warning_value = true; - break; - case 'c': /* critical threshold */ - result.config.critical_value = strtoul(optarg, NULL, 10); - result.config.check_critical_value = true; - break; - case 'd': /* Display select for services */ - if (!strcmp(optarg, "SHOWALL")) { - result.config.show_all = true; - } - break; - case 'u': - socket_timeout_state = STATE_UNKNOWN; - break; - case 't': /* timeout */ - socket_timeout = atoi(optarg); - if (socket_timeout <= 0) { - result.errorcode = ERROR; - return result; - } - } - } - if (result.config.server_address == NULL) { - usage4(_("You must provide a server address or host name")); - } - - if (result.config.vars_to_check == CHECK_NONE) { - result.errorcode = ERROR; - return result; - } - - if (result.config.req_password == NULL) { - result.config.req_password = strdup(_("None")); - } - - return result; -} - -void fetch_data(const char *address, int port, const char *sendb) { - int result = process_tcp_request(address, port, sendb, recv_buffer, sizeof(recv_buffer)); - - if (result != STATE_OK) { - die(result, _("could not fetch information from server\n")); - } - - if (!strncmp(recv_buffer, "ERROR", 5)) { - die(STATE_UNKNOWN, "NSClient - %s\n", recv_buffer); - } -} - -bool strtoularray(unsigned long *array, char *string, const char *delim) { - /* split a delimited string into a long array */ - for (int idx = 0; idx < MAX_VALUE_LIST; idx++) { - array[idx] = 0; - } - - int idx = 0; - for (char *t1 = strtok(string, delim); t1 != NULL; t1 = strtok(NULL, delim)) { - if (is_numeric(t1) && idx < MAX_VALUE_LIST) { - array[idx] = strtoul(t1, NULL, 10); - idx++; - } else { - return false; - } - } - return true; -} - -void preparelist(char *string) { - /* Replace all , with & which is the delimiter for the request */ - for (int i = 0; (size_t)i < strlen(string); i++) { - if (string[i] == ',') { - string[i] = '&'; - } - } -} - -void print_help(void) { - print_revision(progname, NP_VERSION); - - printf("Copyright (c) 2000 Yves Rubin (rubiyz@yahoo.com)\n"); - printf(COPYRIGHT, copyright, email); - - printf("%s\n", _("This plugin collects data from the NSClient service running on a")); - printf("%s\n", _("Windows NT/2000/XP/2003 server.")); - - printf("\n\n"); - - print_usage(); - - printf(UT_HELP_VRSN); - printf(UT_EXTRA_OPTS); - - printf("%s\n", _("Options:")); - printf(" %s\n", "-H, --hostname=HOST"); - printf(" %s\n", _("Name of the host to check")); - printf(" %s\n", "-p, --port=INTEGER"); - printf(" %s", _("Optional port number (default: ")); - printf("%d)\n", PORT); - printf(" %s\n", "-s, --secret="); - printf(" %s\n", _("Password needed for the request")); - printf(" %s\n", "-w, --warning=INTEGER"); - printf(" %s\n", _("Threshold which will result in a warning status")); - printf(" %s\n", "-c, --critical=INTEGER"); - printf(" %s\n", _("Threshold which will result in a critical status")); - printf(" %s\n", "-t, --timeout=INTEGER"); - printf(" %s", _("Seconds before connection attempt times out (default: ")); - printf(" %s\n", "-l, --params="); - printf(" %s", _("Parameters passed to specified check (see below)")); - printf(" %s\n", "-d, --display={SHOWALL}"); - printf(" %s", _("Display options (currently only SHOWALL works)")); - printf(" %s\n", "-u, --unknown-timeout"); - printf(" %s", _("Return UNKNOWN on timeouts")); - printf("%d)\n", DEFAULT_SOCKET_TIMEOUT); - printf(" %s\n", "-h, --help"); - printf(" %s\n", _("Print this help screen")); - printf(" %s\n", "-V, --version"); - printf(" %s\n", _("Print version information")); - printf(" %s\n", "-v, --variable=STRING"); - printf(" %s\n\n", _("Variable to check")); - printf("%s\n", _("Valid variables are:")); - printf(" %s", "CLIENTVERSION ="); - printf(" %s\n", _("Get the NSClient version")); - printf(" %s\n", _("If -l is specified, will return warning if versions differ.")); - printf(" %s\n", "CPULOAD ="); - printf(" %s\n", _("Average CPU load on last x minutes.")); - printf(" %s\n", _("Request a -l parameter with the following syntax:")); - printf(" %s\n", _("-l ,,.")); - printf(" %s\n", _(" should be less than 24*60.")); - printf(" %s\n", _("Thresholds are percentage and up to 10 requests can be done in one shot.")); - printf(" %s\n", "ie: -l 60,90,95,120,90,95"); - printf(" %s\n", "UPTIME ="); - printf(" %s\n", _("Get the uptime of the machine.")); - printf(" %s\n", _("-l ")); - printf(" %s\n", _(" = seconds, minutes, hours, or days. (default: minutes)")); - printf(" %s\n", _("Thresholds will use the unit specified above.")); - printf(" %s\n", "USEDDISKSPACE ="); - printf(" %s\n", _("Size and percentage of disk use.")); - printf(" %s\n", _("Request a -l parameter containing the drive letter only.")); - printf(" %s\n", _("Warning and critical thresholds can be specified with -w and -c.")); - printf(" %s\n", "MEMUSE ="); - printf(" %s\n", _("Memory use.")); - printf(" %s\n", _("Warning and critical thresholds can be specified with -w and -c.")); - printf(" %s\n", "SERVICESTATE ="); - printf(" %s\n", _("Check the state of one or several services.")); - printf(" %s\n", _("Request a -l parameters with the following syntax:")); - printf(" %s\n", _("-l ,,,...")); - printf(" %s\n", _("You can specify -d SHOWALL in case you want to see working services")); - printf(" %s\n", _("in the returned string.")); - printf(" %s\n", "PROCSTATE ="); - printf(" %s\n", _("Check if one or several process are running.")); - printf(" %s\n", _("Same syntax as SERVICESTATE.")); - printf(" %s\n", "COUNTER ="); - printf(" %s\n", _("Check any performance counter of Windows NT/2000.")); - printf(" %s\n", _("Request a -l parameters with the following syntax:")); - printf(" %s\n", _("-l \"\\\\\\\\counter\",\"")); - printf(" %s\n", _("The parameter is optional and is given to a printf ")); - printf(" %s\n", _("output command which requires a float parameter.")); - printf(" %s\n", _("If does not include \"%%\", it is used as a label.")); - printf(" %s\n", _("Some examples:")); - printf(" %s\n", "\"Paging file usage is %%.2f %%%%\""); - 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", _(" 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", _(" to run Perfmon directly.")); - 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", "(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", _("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.")); - - printf(UT_SUPPORT); -} - -void print_usage(void) { - printf("%s\n", _("Usage:")); - printf("%s -H host -v variable [-p port] [-w warning] [-c critical]\n", progname); - printf("[-l params] [-d SHOWALL] [-u] [-t timeout]\n"); -} diff --git a/plugins/check_nt.d/config.h b/plugins/check_nt.d/config.h deleted file mode 100644 index 431889cb..00000000 --- a/plugins/check_nt.d/config.h +++ /dev/null @@ -1,53 +0,0 @@ -#pragma once - -#include "../../config.h" -#include - -enum { - PORT = 1248, -}; - -enum checkvars { - CHECK_NONE, - CHECK_CLIENTVERSION, - CHECK_CPULOAD, - CHECK_UPTIME, - CHECK_USEDDISKSPACE, - CHECK_SERVICESTATE, - CHECK_PROCSTATE, - CHECK_MEMUSE, - CHECK_COUNTER, - CHECK_FILEAGE, - CHECK_INSTANCES -}; - -typedef struct { - char *server_address; - int server_port; - char *req_password; - enum checkvars vars_to_check; - bool show_all; - char *value_list; - bool check_warning_value; - unsigned long warning_value; - bool check_critical_value; - unsigned long critical_value; -} check_nt_config; - -check_nt_config check_nt_config_init() { - check_nt_config tmp = { - .server_address = NULL, - .server_port = PORT, - .req_password = NULL, - - .vars_to_check = CHECK_NONE, - .show_all = false, - .value_list = NULL, - - .check_warning_value = false, - .warning_value = 0, - .check_critical_value = false, - .critical_value = 0, - }; - return tmp; -} diff --git a/plugins/tests/check_nt.t b/plugins/tests/check_nt.t deleted file mode 100755 index 223d4933..00000000 --- a/plugins/tests/check_nt.t +++ /dev/null @@ -1,80 +0,0 @@ -#! /usr/bin/perl -w -I .. -# -# Test check_nt by having a stub check_nt daemon -# - -use strict; -use Test::More; -use NPTest; -use FindBin qw($Bin); - -use IO::Socket; -use IO::Select; -use POSIX; - -my $port = 50000 + int(rand(1000)); - -my $pid = fork(); -if ($pid) { - # Parent - #print "parent\n"; - # give our webserver some time to startup - sleep(1); -} else { - # Child - #print "child\n"; - - my $server = IO::Socket::INET->new( - LocalPort => $port, - Type => SOCK_STREAM, - Reuse => 1, - Proto => "tcp", - Listen => 10, - ) or die "Cannot be a tcp server on port $port: $@"; - - $server->autoflush(1); - - print "Please contact me at port $port\n"; - while (my $client = $server->accept ) { - my $data = ""; - my $rv = $client->recv($data, POSIX::BUFSIZ, 0); - - my ($password, $command, $arg) = split('&', $data); - - if ($command eq "4") { - if ($arg eq "c") { - print $client "930000000&1000000000"; - } elsif ($arg eq "d") { - print $client "UNKNOWN: Drive is not a fixed drive"; - } - } - } - exit; -} - -END { if ($pid) { print "Killing $pid\n"; kill "INT", $pid } }; - -if ($ARGV[0] && $ARGV[0] eq "-d") { - sleep 1000; -} - -if (-x "./check_nt") { - plan tests => 5; -} else { - plan skip_all => "No check_nt compiled"; -} - -my $result; -my $command = "./check_nt -H 127.0.0.1 -p $port"; - -$result = NPTest->testCmd( "$command -v USEDDISKSPACE -l c" ); -is( $result->return_code, 0, "USEDDISKSPACE c"); -is( $result->output, q{c:\ - total: 0.93 Gb - used: 0.07 Gb (7%) - free 0.87 Gb (93%) | 'c:\ Used Space'=0.07Gb;0.00;0.00;0.00;0.93}, "Output right" ); - -$result = NPTest->testCmd( "$command -v USEDDISKSPACE -l d" ); -is( $result->return_code, 3, "USEDDISKSPACE d - invalid"); -is( $result->output, "Free disk space : Invalid drive", "Output right" ); - -$result = NPTest->testCmd( "./check_nt -v USEDDISKSPACE -l d" ); -is( $result->return_code, 3, "Fail if -H missing"); - -- cgit v1.2.3-74-g34f1 From c735cf423417eee6de8624cd7032ebf8aeeef7ad Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Thu, 4 Dec 2025 13:23:50 +0100 Subject: Remove check_ntp (#2194) check_ntp was marked as deprecated for forever (SVN times). In the spirit of cleaning up and removing the dead bodies, this commit removes check_ntp and all its connections. --- .github/monitoring-plugins.spec | 13 - .gitignore | 1 - plugins/Makefile.am | 3 +- plugins/check_ntp.c | 947 ---------------------------------------- 4 files changed, 1 insertion(+), 963 deletions(-) delete mode 100644 plugins/check_ntp.c (limited to '.github/monitoring-plugins.spec') diff --git a/.github/monitoring-plugins.spec b/.github/monitoring-plugins.spec index 5878a862..fa47cdc7 100644 --- a/.github/monitoring-plugins.spec +++ b/.github/monitoring-plugins.spec @@ -652,19 +652,6 @@ Provides check_nagios of the Monitoring Plugins. -# check_ntp -%package ntp -Summary: Monitoring Plugins - check_ntp -Requires: %{name} = %{version}-%{release} - -%description ntp -Provides check_ntp of the Monitoring Plugins. - -%files ntp -%{plugindir}/check_ntp - - - # check_ntp_peer %package ntp_peer Summary: Monitoring Plugins - check_ntp_peer diff --git a/.gitignore b/.gitignore index a91edd7c..d0115b05 100644 --- a/.gitignore +++ b/.gitignore @@ -174,7 +174,6 @@ plugins/check_disk.d/.dirstamp /plugins/check_netsaint /plugins/check_nntp /plugins/check_nntps -/plugins/check_ntp /plugins/check_ntp_peer /plugins/check_ntp_time /plugins/check_pgsql diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 877c0947..d098fa8a 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -33,7 +33,7 @@ MATHLIBS = @MATHLIBS@ #AM_CFLAGS = -Wall libexec_PROGRAMS = check_apt check_cluster check_disk check_dummy check_http check_load \ - check_mrtg check_mrtgtraf check_ntp check_ntp_peer check_ping \ + check_mrtg check_mrtgtraf check_ntp_peer check_ping \ check_real check_smtp check_ssh check_tcp check_time check_ntp_time \ check_ups check_users negate \ urlize @EXTRAS@ \ @@ -156,7 +156,6 @@ check_mysql_query_CFLAGS = $(AM_CFLAGS) $(MYSQLCFLAGS) check_mysql_query_CPPFLAGS = $(AM_CPPFLAGS) $(MYSQLINCLUDE) check_mysql_query_LDADD = $(NETLIBS) $(MYSQLLIBS) check_nagios_LDADD = $(BASEOBJS) -check_ntp_LDADD = $(NETLIBS) $(MATHLIBS) check_ntp_peer_LDADD = $(NETLIBS) $(MATHLIBS) check_pgsql_LDADD = $(NETLIBS) $(PGLIBS) check_ping_LDADD = $(NETLIBS) diff --git a/plugins/check_ntp.c b/plugins/check_ntp.c deleted file mode 100644 index b22cc3c1..00000000 --- a/plugins/check_ntp.c +++ /dev/null @@ -1,947 +0,0 @@ -/***************************************************************************** - * - * 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"; -const char *email = "devel@monitoring-plugins.org"; - -#include "common.h" -#include "netutils.h" -#include "utils.h" - -static char *server_address = NULL; -static int verbose = 0; -static bool do_offset = false; -static char *owarn = "60"; -static char *ocrit = "120"; -static bool do_jitter = false; -static char *jwarn = "5000"; -static char *jcrit = "10000"; - -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); - -/* number of times to perform each request to get a good average. */ -#ifndef AVG_NUM -# define AVG_NUM 4 -#endif - -/* max size of control message data */ -#define MAX_CM_SIZE 468 - -/* 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 */ -} ntp_message; - -/* this structure holds data about results from querying offset from a peer */ -typedef struct { - time_t waiting; /* ts set when we started waiting for a response */ - int num_responses; /* number of successfully received responses */ - uint8_t stratum; /* copied verbatim from the ntp_message */ - 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 */ -} 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 */ - char data[MAX_CM_SIZE]; /* ASCII data of the request */ - /* NB: not necessarily NULL terminated! */ -} ntp_control_message; - -/* this is an association/status-word pair found in control packet responses */ -typedef struct { - uint16_t assoc; - uint16_t status; -} ntp_assoc_status_pair; - -/* 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) -/* and these are the values of the leap indicator */ -#define LI_NOWARNING 0x00 -#define LI_EXTRASEC 0x01 -#define LI_MISSINGSEC 0x02 -#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_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) -/* here are some values */ -#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_ERROR 0x40 -#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_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_SYNCSOURCE 0x06 - -/** - ** a note about the 32-bit "fixed point" numbers: - ** - they are divided into halves, each being a 16-bit int in network byte order: - - the first 16 bits are an int on the left side of a decimal point. - - the second 16 bits represent a fraction n/(2^16) - likewise for the 64-bit "fixed point" numbers with everything doubled :) - **/ - -/* 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]) -/* 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]) - -/* 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) - -/* 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) - -/* 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)); \ - } \ - } 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) - -/* 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)) - -/* 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); - -/* calculate the offset of the local clock */ -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))); -} - -/* print out a ntp packet in human readable/debuggable format */ -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); - - printf("packet contents:\n"); - printf("\tflags: 0x%.2x\n", p->flags); - printf("\t li=%d (0x%.2x)\n", LI(p->flags), p->flags & LI_MASK); - printf("\t vn=%d (0x%.2x)\n", VN(p->flags), p->flags & VN_MASK); - printf("\t mode=%d (0x%.2x)\n", MODE(p->flags), p->flags & MODE_MASK); - printf("\tstratum = %d\n", p->stratum); - printf("\tpoll = %g\n", pow(2, p->poll)); - printf("\tprecision = %g\n", pow(2, p->precision)); - printf("\trtdelay = %-.16g\n", NTP32asDOUBLE(p->rtdelay)); - printf("\trtdisp = %-.16g\n", NTP32asDOUBLE(p->rtdisp)); - printf("\trefid = %x\n", p->refid); - printf("\trefts = %-.16g\n", NTP64asDOUBLE(p->refts)); - printf("\torigts = %-.16g\n", NTP64asDOUBLE(p->origts)); - printf("\trxts = %-.16g\n", NTP64asDOUBLE(p->rxts)); - printf("\ttxts = %-.16g\n", NTP64asDOUBLE(p->txts)); -} - -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("\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 < 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"); - } - } - printf("\n"); - } - } -} - -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); - - gettimeofday(&t, NULL); - 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; - - /* for each server */ - for (cserver = 0; cserver < nservers; cserver++) { - /* We don't want any servers that fails these tests */ - /* Sort out servers that didn't respond or responede with a 0 stratum; - * stratum 0 is for reference clocks so no NTP server should ever report - * a stratum 0 */ - if (slist[cserver].stratum == 0) { - if (verbose) { - printf("discarding peer %d: stratum=%d\n", cserver, slist[cserver].stratum); - } - continue; - } - /* Sort out servers with error flags */ - if (LI(slist[cserver].flags) == LI_ALARM) { - if (verbose) { - printf("discarding peer %d: flags=%d\n", cserver, LI(slist[cserver].flags)); - } - continue; - } - - /* If we don't have a server yet, use the first one */ - if (best_server == -1) { - best_server = cserver; - DBG(printf("using peer %d as our first candidate\n", best_server)); - continue; - } - - /* compare the server to the best one we've seen so far */ - /* does it have an equal or better stratum? */ - DBG(printf("comparing peer %d with peer %d\n", cserver, best_server)); - if (slist[cserver].stratum <= slist[best_server].stratum) { - DBG(printf("stratum for peer %d <= peer %d\n", cserver, best_server)); - /* does it have an equal or better dispersion? */ - if (slist[cserver].rtdisp <= slist[best_server].rtdisp) { - DBG(printf("dispersion for peer %d <= peer %d\n", cserver, best_server)); - /* does it have a better rtdelay? */ - if (slist[cserver].rtdelay < slist[best_server].rtdelay) { - DBG(printf("rtdelay for peer %d < peer %d\n", cserver, best_server)); - best_server = cserver; - DBG(printf("peer %d is now our best candidate\n", best_server)); - } - } - } - } - - if (best_server >= 0) { - DBG(printf("best server selected: peer %d\n", best_server)); - return best_server; - } else { - DBG(printf("no peers meeting synchronization criteria :(\n")); - return -1; - } -} - -/* do everything we need to get the total average offset - * - we use a certain amount of parallelization with poll() to ensure - * 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.; - struct timeval recv_time; - 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)); - hints.ai_family = address_family; - hints.ai_protocol = IPPROTO_UDP; - hints.ai_socktype = SOCK_DGRAM; - - /* 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)); - } - - /* 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); - 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) { - perror(NULL); - die(STATE_UNKNOWN, "can not create new socket"); - } - 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; - } - 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_completed < num_hosts && now_time - start_ts <= socket_timeout / 2) { - /* loop through each server and find each one which hasn't - * been touched in the past second or so and is still lacking - * some responses. for each of these servers, send a new request, - * and update the "waiting" timestamp with the current time. */ - now_time = time(NULL); - - for (i = 0; i < num_hosts; i++) { - if (servers[i].waiting < now_time && servers[i].num_responses < AVG_NUM) { - if (verbose && servers[i].waiting != 0) { - printf("re-"); - } - if (verbose) { - printf("sending request to peer %d\n", i); - } - setup_request(&req[i]); - write(socklist[i], &req[i], sizeof(ntp_message)); - servers[i].waiting = now_time; - break; - } - } - - /* quickly poll for any sockets with pending data */ - servers_readable = poll(ufds, num_hosts, 100); - if (servers_readable == -1) { - perror("polling ntp sockets"); - die(STATE_UNKNOWN, "communication errors"); - } - - /* read from any sockets with pending data */ - for (i = 0; servers_readable && i < num_hosts; i++) { - if (ufds[i].revents & POLLIN && servers[i].num_responses < AVG_NUM) { - if (verbose) { - printf("response from peer %d: ", i); - } - - read(ufds[i].fd, &req[i], sizeof(ntp_message)); - gettimeofday(&recv_time, NULL); - DBG(print_ntp_message(&req[i])); - respnum = servers[i].num_responses++; - servers[i].offset[respnum] = calc_offset(&req[i], &recv_time); - if (verbose) { - printf("offset %.10g\n", servers[i].offset[respnum]); - } - servers[i].stratum = req[i].stratum; - servers[i].rtdisp = NTP32asDOUBLE(req[i].rtdisp); - servers[i].rtdelay = NTP32asDOUBLE(req[i].rtdelay); - servers[i].waiting = 0; - servers[i].flags = req[i].flags; - servers_readable--; - one_read = 1; - if (servers[i].num_responses == AVG_NUM) { - servers_completed++; - } - } - } - /* lather, rinse, repeat. */ - } - - if (one_read == 0) { - die(STATE_CRITICAL, "NTP CRITICAL: No response from NTP server\n"); - } - - /* now, pick the best server from the list */ - best_index = best_offset_server(servers, num_hosts); - if (best_index < 0) { - *status = STATE_UNKNOWN; - } else { - /* finally, calculate the average offset */ - for (i = 0; i < servers[best_index].num_responses; i++) { - avg_offset += servers[best_index].offset[i]; - } - avg_offset /= servers[best_index].num_responses; - } - - /* cleanup */ - /* FIXME: Not closing the socket to avoid reuse of the local port - * which can cause old NTP packets to be read instead of NTP control - * packets in jitter_request(). THERE MUST BE ANOTHER WAY... - * for(j=0; jflags, LI_NOWARNING); - VN_SET(p->flags, VN_RESERVED); - MODE_SET(p->flags, MODE_CONTROLMSG); - OP_SET(p->op, opcode); - p->seq = htons(seq); - /* Remaining fields are zero for requests */ -} - -/* XXX handle responses with the error bit set */ -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; - ntp_control_message req; - const char *getvar = "jitter"; - double rval = 0.0, jitter = -1.0; - char *startofvalue = NULL, *nptr = NULL; - void *tmp; - - /* Long-winded explanation: - * Getting the jitter requires a number of steps: - * 1) Send a READSTAT request. - * 2) Interpret the READSTAT reply - * a) The data section contains a list of peer identifiers (16 bits) - * and associated status words (16 bits) - * b) We want the value of 0x06 in the SEL (peer selection) value, - * which means "current synchronizatin source". If that's missing, - * we take anything better than 0x04 (see the rfc for details) but - * set a minimum of warning. - * 3) Send a READVAR request for information on each peer identified - * in 2b greater than the minimum selection value. - * 4) Extract the jitter value from the data[] (it's ASCII) - */ - my_udp_connect(server_address, 123, &conn); - - /* keep sending requests until the server stops setting the - * REM_MORE bit, though usually this is only 1 packet. */ - 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); - 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) { - 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); - - /* 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) { - num_candidates++; - if (PEER_SEL(peers[i].status) >= PEER_SYNCSOURCE) { - syncsource_found = true; - 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) { - *status = STATE_UNKNOWN; - if (verbose) { - printf("warning: no synchronization source found\n"); - } - } - - for (run = 0; run < AVG_NUM; run++) { - if (verbose) { - printf("jitter run %d of %d\n", run + 1, AVG_NUM); - } - for (i = 0; i < npeers; i++) { - /* Only query this server if it is the current sync source */ - if (PEER_SEL(peers[i].status) >= min_peer_sel) { - char jitter_data[MAX_CM_SIZE + 1]; - size_t jitter_data_count; - - num_selected++; - setup_control_request(&req, OP_READVAR, 2); - req.assoc = peers[i].assoc; - /* By spec, putting the variable name "jitter" in the request - * should cause the server to provide _only_ the jitter value. - * thus reducing net traffic, guaranteeing us only a single - * datagram in reply, and making interpretation much simpler - */ - /* 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); - req.count = htons(strlen(getvar)); - DBG(printf("sending READVAR request...\n")); - write(conn, &req, SIZEOF_NTPCM(req)); - DBG(print_ntp_control_message(&req)); - - req.count = htons(MAX_CM_SIZE); - DBG(printf("receiving READVAR response...\n")); - 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"); - } - getvar = "dispersion"; - num_selected--; - i--; - continue; - } - - /* get to the float value */ - 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); - } - memcpy(jitter_data, req.data, jitter_data_count); - jitter_data[jitter_data_count] = '\0'; - startofvalue = strchr(jitter_data, '='); - if (startofvalue != NULL) { - startofvalue++; - jitter = strtod(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); - } - num_valid++; - rval += jitter; - } - } - } - if (verbose) { - printf("jitter parsed from %d/%d peers\n", num_valid, num_selected); - } - } - - rval = num_valid ? rval / num_valid : -1.0; - - close(conn); - 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 c; - 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"); - } - - while (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': - print_help(); - exit(STATE_UNKNOWN); - break; - case 'V': - print_revision(progname, NP_VERSION); - exit(STATE_UNKNOWN); - break; - case 'v': - verbose++; - break; - case 'w': - do_offset = true; - owarn = optarg; - break; - case 'c': - do_offset = true; - ocrit = optarg; - break; - case 'j': - do_jitter = true; - jwarn = optarg; - break; - case 'k': - do_jitter = true; - jcrit = optarg; - break; - case 'H': - if (!is_host(optarg)) { - usage2(_("Invalid hostname/address"), optarg); - } - server_address = strdup(optarg); - break; - case 't': - socket_timeout = atoi(optarg); - break; - case '4': - address_family = AF_INET; - break; - case '6': -#ifdef USE_IPV6 - address_family = AF_INET6; -#else - usage4(_("IPv6 support not available")); -#endif - break; - case '?': - /* print short usage statement if args not parsable */ - usage5(); - break; - } - } - - 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_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 result, offset_result, jitter_result; - double offset = 0, jitter = 0; - char *result_line, *perfdata_line; - - 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); - - 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); - - /* set socket timeout */ - alarm(socket_timeout); - - offset = offset_request(server_address, &offset_result); - /* check_ntp used to always return CRITICAL if offset_result == STATE_UNKNOWN. - * Now we'll only do that is the offset thresholds were set */ - if (do_offset && offset_result == STATE_UNKNOWN) { - result = STATE_CRITICAL; - } else { - result = get_status(fabs(offset), offset_thresholds); - } - - /* If not told to check the jitter, we don't even send packets. - * jitter is checked using NTP control packets, which not all - * servers recognize. Trying to check the jitter on OpenNTPD - * (for example) will result in an error - */ - 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) { - 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; - } - if (offset_result == STATE_UNKNOWN) { - xasprintf(&result_line, "%s %s", result_line, _("Offset unknown")); - xasprintf(&perfdata_line, ""); - } else { - xasprintf(&result_line, "%s %s %.10g secs", result_line, _("Offset"), offset); - xasprintf(&perfdata_line, "%s", perfd_offset(offset)); - } - if (do_jitter) { - xasprintf(&result_line, "%s, jitter=%f", result_line, 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); - } - return result; -} - -void print_help(void) { - print_revision(progname, NP_VERSION); - - printf("Copyright (c) 2006 Sean Finney\n"); - printf(COPYRIGHT, copyright, email); - - printf("%s\n", _("This plugin checks the selected ntp server")); - - 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("\n"); - printf("%s\n", _("Notes:")); - printf(UT_THRESHOLDS_NOTES); - - printf("\n"); - printf("%s\n", _("Examples:")); - 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", _("(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("%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); -} -- cgit v1.2.3-74-g34f1 From 3f62439e7538439a5f12eb569f3e8d5ab341d26a Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Mon, 29 Dec 2025 11:58:18 +0100 Subject: Fake changelog in spec file since the rpm build seems to fail --- .github/monitoring-plugins.spec | 4 ++++ 1 file changed, 4 insertions(+) (limited to '.github/monitoring-plugins.spec') diff --git a/.github/monitoring-plugins.spec b/.github/monitoring-plugins.spec index fa47cdc7..e3465227 100644 --- a/.github/monitoring-plugins.spec +++ b/.github/monitoring-plugins.spec @@ -922,3 +922,7 @@ Provides check_wave of the Monitoring Plugins. %files wave %{plugindir}/check_wave + +%changelog +* Wed Oct 20 2011 John Doe 0.8.18.1-0.1 +- Initial RPM release -- cgit v1.2.3-74-g34f1