[monitoring-plugins] check_ping: Drop incomplete multiple hostname ...
Alvar Penning
git at monitoring-plugins.org
Tue Sep 15 16:10:15 CEST 2026
Module: monitoring-plugins
Branch: master
Commit: a83c0c3f9b96433082a949f2a46ea9e4039e7dc5
Author: Alvar Penning <post at 0x21.biz>
Date: Tue Sep 15 11:01:33 2026 +0200
URL: https://www.monitoring-plugins.org/repositories/monitoring-plugins/commit/?id=a83c0c3f
check_ping: Drop incomplete multiple hostname support
The check_ping check command had an incomplete and undocumented
implementation to accept multiple hostnames. These hostnames might
either be passed via multiple "-H" flags or as a single, comma-separated
value. The first hostname takes precedence over the following, which
were only tried in case of an UNKNOWN (!) error for the prior. However,
due to the timeout logic - ending the check command -, the later
hostnames were not even tried.
As being both undocumented and not functional, this feature was removed.
Note, the - also undocumented - option to pass ordered options after the
flags was left intact, also for a single hostname.
Most parts of the diff are just a change in the indentation level, as
the loop in the main function was removed.
Fixes #2346.
---
plugins/check_ping.c | 166 +++++++++++++++++-------------------------
plugins/check_ping.d/config.h | 11 +--
2 files changed, 70 insertions(+), 107 deletions(-)
diff --git a/plugins/check_ping.c b/plugins/check_ping.c
index 2d5fbe1b..6b71b860 100644
--- a/plugins/check_ping.c
+++ b/plugins/check_ping.c
@@ -91,10 +91,9 @@ int main(int argc, char **argv) {
unveil("/", "r");
unveil(NULL, NULL);
- /* - rpath is required to read --extra-opts
- * - dns for hostname resolution via mopl_net_is_host
- * - proc and exec are used to fork and exec
- * No promise is given up as they are all required within a loop. */
+ /* - rpath is required to read --extra-opts (given up later)
+ * - dns for hostname resolution via mopl_net_is_{host,inet6_addr} (given up later)
+ * - proc and exec are used to fork and exec (given up later) */
pledge("stdio rpath dns proc exec", NULL);
#endif // __OpenBSD__
@@ -126,89 +125,81 @@ int main(int argc, char **argv) {
alarm(timeout_interval);
#endif
- int result = STATE_UNKNOWN;
char *rawcmd = NULL;
- for (size_t i = 0; i < config.n_addresses; i++) {
#ifdef PING6_COMMAND
- if (address_family != AF_INET && mopl_net_is_inet6_addr(config.addresses[i])) {
- rawcmd = strdup(PING6_COMMAND);
- } else {
- rawcmd = strdup(PING_COMMAND);
- }
-#else
+ if (address_family != AF_INET && mopl_net_is_inet6_addr(config.address)) {
+ rawcmd = strdup(PING6_COMMAND);
+ } else {
rawcmd = strdup(PING_COMMAND);
+ }
+#else
+ rawcmd = strdup(PING_COMMAND);
#endif
- char *cmd = NULL;
+ char *cmd = NULL;
- /* does the host address of number of packets argument come first? */
+ /* does the host address of number of packets argument come first? */
#ifdef PING_PACKETS_FIRST
# ifdef PING_HAS_TIMEOUT
- mopl_utils_xasprintf(&cmd, rawcmd, timeout_interval, config.max_packets, config.addresses[i]);
+ mopl_utils_xasprintf(&cmd, rawcmd, timeout_interval, config.max_packets, config.address);
# else
- mopl_utils_xasprintf(&cmd, rawcmd, config.max_packets, config.addresses[i]);
+ mopl_utils_xasprintf(&cmd, rawcmd, config.max_packets, config.address);
# endif
#else
- mopl_utils_xasprintf(&cmd, rawcmd, config.addresses[i], config.max_packets);
+ mopl_utils_xasprintf(&cmd, rawcmd, config.address, config.max_packets);
#endif
- if (verbose >= 2) {
- printf("CMD: %s\n", cmd);
- }
-
- /* run the command */
+ if (verbose >= 2) {
+ printf("CMD: %s\n", cmd);
+ }
- ping_result pinged = run_ping(cmd, config.addresses[i], config.crta);
+ /* run the command */
+ ping_result pinged = run_ping(cmd, config.address, config.crta);
- if (pinged.packet_loss == UNKNOWN_PACKET_LOSS || pinged.round_trip_average < 0.0) {
- printf("%s\n", cmd);
- die(STATE_UNKNOWN, _("CRITICAL - Could not interpret output from ping command\n"));
- }
-
- if (pinged.packet_loss >= config.cpl || pinged.round_trip_average >= config.crta ||
- pinged.round_trip_average < 0) {
- pinged.state = STATE_CRITICAL;
- } else if (pinged.packet_loss >= config.wpl || pinged.round_trip_average >= config.wrta) {
- pinged.state = STATE_WARNING;
- } else if (pinged.packet_loss >= 0 && pinged.round_trip_average >= 0) {
- pinged.state = max_state(STATE_OK, pinged.state);
- }
+#ifdef __OpenBSD__
+ pledge("stdio", NULL);
+#endif // __OpenBSD__
- if (config.n_addresses > 1 && pinged.state != STATE_UNKNOWN) {
- die(STATE_OK, "%s is alive\n", config.addresses[i]);
- }
+ if (pinged.packet_loss == UNKNOWN_PACKET_LOSS || pinged.round_trip_average < 0.0) {
+ printf("%s\n", cmd);
+ die(STATE_UNKNOWN, _("CRITICAL - Could not interpret output from ping command\n"));
+ }
- if (pinged.packet_loss == 100) {
- printf(_("PING %s - %sPacket loss = %d%%"), state_text(pinged.state), warn_text,
- pinged.packet_loss);
- } else {
- printf(_("PING %s - %sPacket loss = %d%%, RTA = %2.2f ms"), state_text(pinged.state),
- warn_text, pinged.packet_loss, pinged.round_trip_average);
- }
+ if (pinged.packet_loss >= config.cpl || pinged.round_trip_average >= config.crta ||
+ pinged.round_trip_average < 0) {
+ pinged.state = STATE_CRITICAL;
+ } else if (pinged.packet_loss >= config.wpl || pinged.round_trip_average >= config.wrta) {
+ pinged.state = STATE_WARNING;
+ } else if (pinged.packet_loss >= 0 && pinged.round_trip_average >= 0) {
+ pinged.state = max_state(STATE_OK, pinged.state);
+ }
- /* Print performance data */
- if (pinged.packet_loss != 100) {
- printf("|%s",
- mopl_utils_fperfdata("rta", pinged.round_trip_average, "ms", (bool)(config.wrta > 0),
- config.wrta, (bool)(config.crta > 0), config.crta, true, 0, false, 0));
- } else {
- printf("| rta=U;%f;%f;;", config.wrta, config.crta);
- }
+ if (pinged.packet_loss == 100) {
+ printf(_("PING %s - %sPacket loss = %d%%"), state_text(pinged.state), warn_text,
+ pinged.packet_loss);
+ } else {
+ printf(_("PING %s - %sPacket loss = %d%%, RTA = %2.2f ms"), state_text(pinged.state),
+ warn_text, pinged.packet_loss, pinged.round_trip_average);
+ }
- printf(" %s\n",
- mopl_utils_perfdata("pl", (long)pinged.packet_loss, "%", (bool)(config.wpl > 0), config.wpl,
- (bool)(config.cpl > 0), config.cpl, true, 0, false, 0));
+ /* Print performance data */
+ if (pinged.packet_loss != 100) {
+ printf("|%s", mopl_utils_fperfdata(
+ "rta", pinged.round_trip_average, "ms", (bool)(config.wrta > 0),
+ config.wrta, (bool)(config.crta > 0), config.crta, true, 0, false, 0));
+ } else {
+ printf("| rta=U;%f;%f;;", config.wrta, config.crta);
+ }
- if (verbose >= 2) {
- printf("%f:%d%% %f:%d%%\n", config.wrta, config.wpl, config.crta, config.cpl);
- }
+ printf(" %s\n",
+ mopl_utils_perfdata("pl", (long)pinged.packet_loss, "%", (bool)(config.wpl > 0),
+ config.wpl, (bool)(config.cpl > 0), config.cpl, true, 0, false, 0));
- result = max_state(result, pinged.state);
- free(rawcmd);
- free(cmd);
+ if (verbose >= 2) {
+ printf("%f:%d%% %f:%d%%\n", config.wrta, config.wpl, config.crta, config.cpl);
}
- return result;
+ return pinged.state;
}
/* process command-line arguments */
@@ -241,7 +232,6 @@ check_ping_config_wrapper process_arguments(int argc, char **argv) {
}
int option = 0;
- size_t max_addr = MAX_ADDR_START;
while (true) {
int option_index = getopt_long(argc, argv, "VvhnL46t:c:w:H:p:", longopts, &option);
@@ -272,27 +262,9 @@ check_ping_config_wrapper process_arguments(int argc, char **argv) {
case '6': /* IPv6 only */
address_family = AF_INET6;
break;
- case 'H': /* hostname */ {
- char *ptr = optarg;
- while (true) {
- result.config.n_addresses++;
- if (result.config.n_addresses > max_addr) {
- max_addr *= 2;
- result.config.addresses =
- realloc(result.config.addresses, sizeof(char *) * max_addr);
- if (result.config.addresses == NULL) {
- die(STATE_UNKNOWN, _("Could not realloc() addresses\n"));
- }
- }
- result.config.addresses[result.config.n_addresses - 1] = ptr;
- if ((ptr = index(ptr, ','))) {
- strcpy(ptr, "");
- ptr += sizeof(char);
- } else {
- break;
- }
- }
- } break;
+ case 'H': /* hostname */
+ result.config.address = optarg;
+ break;
case 'p': /* number of packets to send */
if (mopl_utils_is_intnonneg(optarg)) {
result.config.max_packets = atoi(optarg);
@@ -318,12 +290,12 @@ check_ping_config_wrapper process_arguments(int argc, char **argv) {
return validate_arguments(result);
}
- if (result.config.addresses[0] == NULL) {
+ /* Undocumented compatibility behavior: ordered arguments after parsing options. */
+ if (result.config.address == NULL) {
if (!mopl_net_is_host(argv[arg_counter])) {
mopl_utils_usage2(_("Invalid hostname/address"), argv[arg_counter]);
} else {
- result.config.addresses[0] = argv[arg_counter++];
- result.config.n_addresses++;
+ result.config.address = argv[arg_counter++];
if (arg_counter == argc) {
return validate_arguments(result);
}
@@ -457,15 +429,12 @@ check_ping_config_wrapper validate_arguments(check_ping_config_wrapper config_wr
timeout_interval = (unsigned int)max_seconds;
}
- for (size_t i = 0; i < config_wrapper.config.n_addresses; i++) {
- if (!mopl_net_is_host(config_wrapper.config.addresses[i])) {
- mopl_utils_usage2(_("Invalid hostname/address"), config_wrapper.config.addresses[i]);
- }
- }
-
- if (config_wrapper.config.n_addresses == 0) {
+ if (config_wrapper.config.address == NULL) {
mopl_utils_usage(_("You must specify a server address or host name"));
}
+ if (!mopl_net_is_host(config_wrapper.config.address)) {
+ mopl_utils_usage2(_("Invalid hostname/address"), config_wrapper.config.address);
+ }
return config_wrapper;
}
@@ -585,7 +554,7 @@ ping_result run_ping(const char *cmd, const char *addr, double crta) {
warn_text = strdup(_("System call sent warnings to stderr "));
} else {
mopl_utils_xasprintf(&warn_text, "%s %s", warn_text,
- _("System call sent warnings to stderr "));
+ _("System call sent warnings to stderr "));
}
}
}
@@ -676,8 +645,7 @@ void print_help(void) {
printf("\n");
printf("%s\n",
_("This plugin uses the ping command to probe the specified host for packet loss"));
- printf("%s\n",
- _("(percentage) and round trip average (milliseconds)."));
+ printf("%s\n", _("(percentage) and round trip average (milliseconds)."));
printf(UT_SUPPORT);
}
diff --git a/plugins/check_ping.d/config.h b/plugins/check_ping.d/config.h
index f4af772a..3e0da7f3 100644
--- a/plugins/check_ping.d/config.h
+++ b/plugins/check_ping.d/config.h
@@ -11,13 +11,10 @@ enum {
#define UNKNOWN_TRIP_TIME -1.0 /* -1 seconds */
-#define MAX_ADDR_START 1
-
typedef struct {
int max_packets;
- char **addresses;
- size_t n_addresses;
+ char *address;
int wpl;
int cpl;
@@ -29,8 +26,7 @@ check_ping_config check_ping_config_init() {
check_ping_config tmp = {
.max_packets = -1,
- .addresses = NULL,
- .n_addresses = 0,
+ .address = NULL,
.wpl = UNKNOWN_PACKET_LOSS,
.cpl = UNKNOWN_PACKET_LOSS,
@@ -38,7 +34,6 @@ check_ping_config check_ping_config_init() {
.crta = UNKNOWN_TRIP_TIME,
};
- tmp.addresses = calloc(MAX_ADDR_START, sizeof(char *));
- tmp.addresses[0] = NULL;
+ tmp.address = NULL;
return tmp;
}
More information about the Commits
mailing list