[monitoring-plugins] check_ntp_time/check_ntp_peer: unix socket ...

GitHub git at monitoring-plugins.org
Fri Nov 28 11:00:13 CET 2025


    Module: monitoring-plugins
    Branch: master
    Commit: 2f96b82c9b67ca1aad6cd584a9c458d060bdd4bb
    Author: Lorenz Kästle <12514511+RincewindsHat at users.noreply.github.com>
 Committer: GitHub <noreply at github.com>
      Date: Fri Nov 28 10:52:39 2025 +0100
       URL: https://www.monitoring-plugins.org/repositories/monitoring-plugins/commit/?id=2f96b82c

check_ntp_time/check_ntp_peer: unix socket handling (#2187)

* check_ntp_time/check_ntp_peer: unix socket handling

* No tests for check_ntp since it is deprecated

---

 plugins/check_ntp_peer.c |  2 +-
 plugins/check_ntp_time.c | 81 +++++++++++++++++++++++++++++++++++-------------
 plugins/t/check_ntp.t    |  2 +-
 3 files changed, 61 insertions(+), 24 deletions(-)

diff --git a/plugins/check_ntp_peer.c b/plugins/check_ntp_peer.c
index f7cad630..26f74286 100644
--- a/plugins/check_ntp_peer.c
+++ b/plugins/check_ntp_peer.c
@@ -625,7 +625,7 @@ check_ntp_peer_config_wrapper process_arguments(int argc, char **argv) {
 				mp_thresholds_set_crit(result.config.truechimer_thresholds, tmp.range);
 		} break;
 		case 'H':
-			if (!is_host(optarg)) {
+			if (!is_host(optarg) && (optarg[0] != '/')) {
 				usage2(_("Invalid hostname/address"), optarg);
 			}
 			result.config.server_address = strdup(optarg);
diff --git a/plugins/check_ntp_time.c b/plugins/check_ntp_time.c
index 602b6010..1300faea 100644
--- a/plugins/check_ntp_time.c
+++ b/plugins/check_ntp_time.c
@@ -42,6 +42,8 @@
 #include "states.h"
 #include "thresholds.h"
 #include "check_ntp_time.d/config.h"
+#include <netinet/in.h>
+#include <sys/socket.h>
 
 static int verbose = 0;
 
@@ -336,17 +338,26 @@ static offset_request_wrapper offset_request(const char *host, const char *port,
 	hints.ai_protocol = IPPROTO_UDP;
 	hints.ai_socktype = SOCK_DGRAM;
 
-	/* fill in ai with the list of hosts resolved by the host name */
+	bool is_socket;
 	struct addrinfo *addresses = NULL;
-	int ga_result = getaddrinfo(host, port, &hints, &addresses);
-	if (ga_result != 0) {
-		die(STATE_UNKNOWN, "error getting address for %s: %s\n", host, gai_strerror(ga_result));
-	}
-
-	/* count the number of returned hosts, and allocate stuff accordingly */
 	size_t num_hosts = 0;
-	for (struct addrinfo *ai_tmp = addresses; ai_tmp != NULL; ai_tmp = ai_tmp->ai_next) {
-		num_hosts++;
+	if (host[0] == '/') {
+		num_hosts = 1;
+		is_socket = true;
+	} else {
+		is_socket = false;
+
+		/* fill in ai with the list of hosts resolved by the host name */
+		struct addrinfo *addresses = NULL;
+		int ga_result = getaddrinfo(host, port, &hints, &addresses);
+		if (ga_result != 0) {
+			die(STATE_UNKNOWN, "error getting address for %s: %s\n", host, gai_strerror(ga_result));
+		}
+
+		/* count the number of returned hosts, and allocate stuff accordingly */
+		for (struct addrinfo *ai_tmp = addresses; ai_tmp != NULL; ai_tmp = ai_tmp->ai_next) {
+			num_hosts++;
+		}
 	}
 
 	ntp_message *req = (ntp_message *)malloc(sizeof(ntp_message) * num_hosts);
@@ -374,25 +385,51 @@ static offset_request_wrapper offset_request(const char *host, const char *port,
 	DBG(printf("Found %zu peers to check\n", num_hosts));
 
 	/* setup each socket for writing, and the corresponding struct pollfd */
-	struct addrinfo *ai_tmp = addresses;
-	for (int i = 0; ai_tmp; i++) {
-		socklist[i] = socket(ai_tmp->ai_family, SOCK_DGRAM, IPPROTO_UDP);
-		if (socklist[i] == -1) {
-			perror(NULL);
-			die(STATE_UNKNOWN, "can not create new socket");
+	if (is_socket) {
+		socklist[0] = socket(AF_UNIX, SOCK_STREAM, 0);
+		if (socklist[0] == -1) {
+			DBG(printf("can't create socket: %s\n", strerror(errno)));
+			die(STATE_UNKNOWN, "can not create new socket\n");
 		}
-		if (connect(socklist[i], ai_tmp->ai_addr, ai_tmp->ai_addrlen)) {
+
+		struct sockaddr_un unix_socket = {
+			.sun_family = AF_UNIX,
+		};
+
+		strncpy(unix_socket.sun_path, host, strlen(host));
+
+		if (connect(socklist[0], &unix_socket, sizeof(unix_socket))) {
 			/* 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)));
+			DBG(printf("can't create socket connection on peer %i: %s\n", 0, strerror(errno)));
 		} else {
-			ufds[i].fd = socklist[i];
-			ufds[i].events = POLLIN;
-			ufds[i].revents = 0;
+			ufds[0].fd = socklist[0];
+			ufds[0].events = POLLIN;
+			ufds[0].revents = 0;
+		}
+	} else {
+		struct addrinfo *ai_tmp = addresses;
+		for (int i = 0; ai_tmp; i++) {
+			socklist[i] = socket(ai_tmp->ai_family, SOCK_DGRAM, IPPROTO_UDP);
+			if (socklist[i] == -1) {
+				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;
 		}
-		ai_tmp = ai_tmp->ai_next;
 	}
 
 	/* now do AVG_NUM checks to each host. We stop before timeout/2 seconds
@@ -586,7 +623,7 @@ static check_ntp_time_config_wrapper process_arguments(int argc, char **argv) {
 				mp_thresholds_set_crit(result.config.offset_thresholds, tmp.range);
 		} break;
 		case 'H':
-			if (!is_host(optarg)) {
+			if (!is_host(optarg) && (optarg[0] != '/')) {
 				usage2(_("Invalid hostname/address"), optarg);
 			}
 			result.config.server_address = strdup(optarg);
diff --git a/plugins/t/check_ntp.t b/plugins/t/check_ntp.t
index a8ac7bb8..7703bc3b 100644
--- a/plugins/t/check_ntp.t
+++ b/plugins/t/check_ntp.t
@@ -8,7 +8,7 @@ use strict;
 use Test::More;
 use NPTest;
 
-my @PLUGINS1 = ('check_ntp', 'check_ntp_peer', 'check_ntp_time');
+my @PLUGINS1 = ('check_ntp_peer', 'check_ntp_time');
 my @PLUGINS2 = ('check_ntp_peer');
 
 plan tests => (12 * scalar(@PLUGINS1)) + (6 * scalar(@PLUGINS2));



More information about the Commits mailing list