summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plugins/check_ntp_time.c105
1 files changed, 51 insertions, 54 deletions
diff --git a/plugins/check_ntp_time.c b/plugins/check_ntp_time.c
index 05c3d1e4..c757bc08 100644
--- a/plugins/check_ntp_time.c
+++ b/plugins/check_ntp_time.c
@@ -41,6 +41,7 @@ const char *email = "devel@monitoring-plugins.org";
41#include "common.h" 41#include "common.h"
42#include "netutils.h" 42#include "netutils.h"
43#include "utils.h" 43#include "utils.h"
44#include "states.h"
44 45
45static char *server_address = NULL; 46static char *server_address = NULL;
46static char *port = "123"; 47static char *port = "123";
@@ -50,7 +51,7 @@ static char *owarn = "60";
50static char *ocrit = "120"; 51static char *ocrit = "120";
51static int time_offset = 0; 52static int time_offset = 0;
52 53
53static int process_arguments(int, char **); 54static int process_arguments(int /*argc*/, char ** /*argv*/);
54static thresholds *offset_thresholds = NULL; 55static thresholds *offset_thresholds = NULL;
55static void print_help(void); 56static void print_help(void);
56void print_usage(void); 57void print_usage(void);
@@ -159,7 +160,7 @@ typedef struct {
159#define EPOCHDIFF 0x83aa7e80UL 160#define EPOCHDIFF 0x83aa7e80UL
160 161
161/* extract a 32-bit ntp fixed point number into a double */ 162/* extract a 32-bit ntp fixed point number into a double */
162#define NTP32asDOUBLE(x) (ntohs(L16(x)) + (double)ntohs(R16(x)) / 65536.0) 163#define NTP32asDOUBLE(x) (ntohs(L16(x)) + ((double)ntohs(R16(x)) / 65536.0))
163 164
164/* likewise for a 64-bit ntp fp number */ 165/* likewise for a 64-bit ntp fp number */
165#define NTP64asDOUBLE(n) \ 166#define NTP64asDOUBLE(n) \
@@ -208,56 +209,52 @@ typedef struct {
208 } while (0); 209 } while (0);
209 210
210/* calculate the offset of the local clock */ 211/* calculate the offset of the local clock */
211static inline double calc_offset(const ntp_message *m, const struct timeval *t) { 212static inline double calc_offset(const ntp_message *message, const struct timeval *time_value) {
212 double client_tx = NTP64asDOUBLE(m->origts); 213 double client_tx = NTP64asDOUBLE(message->origts);
213 double peer_rx = NTP64asDOUBLE(m->rxts); 214 double peer_rx = NTP64asDOUBLE(message->rxts);
214 double peer_tx = NTP64asDOUBLE(m->txts); 215 double peer_tx = NTP64asDOUBLE(message->txts);
215 double client_rx = TVasDOUBLE((*t)); 216 double client_rx = TVasDOUBLE((*time_value));
216 return (.5 * ((peer_tx - client_rx) + (peer_rx - client_tx))); 217 return (((peer_tx - client_rx) + (peer_rx - client_tx)) / 2);
217} 218}
218 219
219/* print out a ntp packet in human readable/debuggable format */ 220/* print out a ntp packet in human readable/debuggable format */
220void print_ntp_message(const ntp_message *p) { 221void print_ntp_message(const ntp_message *message) {
221 struct timeval ref; 222 struct timeval ref;
222 struct timeval orig; 223 struct timeval orig;
223 struct timeval rx;
224 struct timeval tx;
225 224
226 NTP64toTV(p->refts, ref); 225 NTP64toTV(message->refts, ref);
227 NTP64toTV(p->origts, orig); 226 NTP64toTV(message->origts, orig);
228 NTP64toTV(p->rxts, rx);
229 NTP64toTV(p->txts, tx);
230 227
231 printf("packet contents:\n"); 228 printf("packet contents:\n");
232 printf("\tflags: 0x%.2x\n", p->flags); 229 printf("\tflags: 0x%.2x\n", message->flags);
233 printf("\t li=%d (0x%.2x)\n", LI(p->flags), p->flags & LI_MASK); 230 printf("\t li=%d (0x%.2x)\n", LI(message->flags), message->flags & LI_MASK);
234 printf("\t vn=%d (0x%.2x)\n", VN(p->flags), p->flags & VN_MASK); 231 printf("\t vn=%d (0x%.2x)\n", VN(message->flags), message->flags & VN_MASK);
235 printf("\t mode=%d (0x%.2x)\n", MODE(p->flags), p->flags & MODE_MASK); 232 printf("\t mode=%d (0x%.2x)\n", MODE(message->flags), message->flags & MODE_MASK);
236 printf("\tstratum = %d\n", p->stratum); 233 printf("\tstratum = %d\n", message->stratum);
237 printf("\tpoll = %g\n", pow(2, p->poll)); 234 printf("\tpoll = %g\n", pow(2, message->poll));
238 printf("\tprecision = %g\n", pow(2, p->precision)); 235 printf("\tprecision = %g\n", pow(2, message->precision));
239 printf("\trtdelay = %-.16g\n", NTP32asDOUBLE(p->rtdelay)); 236 printf("\trtdelay = %-.16g\n", NTP32asDOUBLE(message->rtdelay));
240 printf("\trtdisp = %-.16g\n", NTP32asDOUBLE(p->rtdisp)); 237 printf("\trtdisp = %-.16g\n", NTP32asDOUBLE(message->rtdisp));
241 printf("\trefid = %x\n", p->refid); 238 printf("\trefid = %x\n", message->refid);
242 printf("\trefts = %-.16g\n", NTP64asDOUBLE(p->refts)); 239 printf("\trefts = %-.16g\n", NTP64asDOUBLE(message->refts));
243 printf("\torigts = %-.16g\n", NTP64asDOUBLE(p->origts)); 240 printf("\torigts = %-.16g\n", NTP64asDOUBLE(message->origts));
244 printf("\trxts = %-.16g\n", NTP64asDOUBLE(p->rxts)); 241 printf("\trxts = %-.16g\n", NTP64asDOUBLE(message->rxts));
245 printf("\ttxts = %-.16g\n", NTP64asDOUBLE(p->txts)); 242 printf("\ttxts = %-.16g\n", NTP64asDOUBLE(message->txts));
246} 243}
247 244
248void setup_request(ntp_message *p) { 245void setup_request(ntp_message *message) {
249 memset(p, 0, sizeof(ntp_message)); 246 memset(message, 0, sizeof(ntp_message));
250 LI_SET(p->flags, LI_ALARM); 247 LI_SET(message->flags, LI_ALARM);
251 VN_SET(p->flags, 4); 248 VN_SET(message->flags, 4);
252 MODE_SET(p->flags, MODE_CLIENT); 249 MODE_SET(message->flags, MODE_CLIENT);
253 p->poll = 4; 250 message->poll = 4;
254 p->precision = (int8_t)0xfa; 251 message->precision = (int8_t)0xfa;
255 L16(p->rtdelay) = htons(1); 252 L16(message->rtdelay) = htons(1);
256 L16(p->rtdisp) = htons(1); 253 L16(message->rtdisp) = htons(1);
257 254
258 struct timeval t; 255 struct timeval t;
259 gettimeofday(&t, NULL); 256 gettimeofday(&t, NULL);
260 TVtoNTP64(t, p->txts); 257 TVtoNTP64(t, message->txts);
261} 258}
262 259
263/* select the "best" server from a list of servers, and return its index. 260/* select the "best" server from a list of servers, and return its index.
@@ -324,7 +321,7 @@ int best_offset_server(const ntp_server_results *slist, int nservers) {
324 * we don't waste time sitting around waiting for single packets. 321 * we don't waste time sitting around waiting for single packets.
325 * - we also "manually" handle resolving host names and connecting, because 322 * - we also "manually" handle resolving host names and connecting, because
326 * we have to do it in a way that our lazy macros don't handle currently :( */ 323 * we have to do it in a way that our lazy macros don't handle currently :( */
327double offset_request(const char *host, int *status) { 324double offset_request(const char *host, mp_state_enum *status) {
328 /* setup hints to only return results from getaddrinfo that we'd like */ 325 /* setup hints to only return results from getaddrinfo that we'd like */
329 struct addrinfo hints; 326 struct addrinfo hints;
330 memset(&hints, 0, sizeof(struct addrinfo)); 327 memset(&hints, 0, sizeof(struct addrinfo));
@@ -333,15 +330,15 @@ double offset_request(const char *host, int *status) {
333 hints.ai_socktype = SOCK_DGRAM; 330 hints.ai_socktype = SOCK_DGRAM;
334 331
335 /* fill in ai with the list of hosts resolved by the host name */ 332 /* fill in ai with the list of hosts resolved by the host name */
336 struct addrinfo *ai = NULL; 333 struct addrinfo *addresses = NULL;
337 int ga_result = getaddrinfo(host, port, &hints, &ai); 334 int ga_result = getaddrinfo(host, port, &hints, &addresses);
338 if (ga_result != 0) { 335 if (ga_result != 0) {
339 die(STATE_UNKNOWN, "error getting address for %s: %s\n", host, gai_strerror(ga_result)); 336 die(STATE_UNKNOWN, "error getting address for %s: %s\n", host, gai_strerror(ga_result));
340 } 337 }
341 338
342 /* count the number of returned hosts, and allocate stuff accordingly */ 339 /* count the number of returned hosts, and allocate stuff accordingly */
343 int num_hosts = 0; 340 size_t num_hosts = 0;
344 for (struct addrinfo *ai_tmp = ai; ai_tmp != NULL; ai_tmp = ai_tmp->ai_next) { 341 for (struct addrinfo *ai_tmp = addresses; ai_tmp != NULL; ai_tmp = ai_tmp->ai_next) {
345 num_hosts++; 342 num_hosts++;
346 } 343 }
347 344
@@ -366,10 +363,10 @@ double offset_request(const char *host, int *status) {
366 die(STATE_UNKNOWN, "can not allocate server array"); 363 die(STATE_UNKNOWN, "can not allocate server array");
367 } 364 }
368 memset(servers, 0, sizeof(ntp_server_results) * num_hosts); 365 memset(servers, 0, sizeof(ntp_server_results) * num_hosts);
369 DBG(printf("Found %d peers to check\n", num_hosts)); 366 DBG(printf("Found %zu peers to check\n", num_hosts));
370 367
371 /* setup each socket for writing, and the corresponding struct pollfd */ 368 /* setup each socket for writing, and the corresponding struct pollfd */
372 struct addrinfo *ai_tmp = ai; 369 struct addrinfo *ai_tmp = addresses;
373 for (int i = 0; ai_tmp; i++) { 370 for (int i = 0; ai_tmp; i++) {
374 socklist[i] = socket(ai_tmp->ai_family, SOCK_DGRAM, IPPROTO_UDP); 371 socklist[i] = socket(ai_tmp->ai_family, SOCK_DGRAM, IPPROTO_UDP);
375 if (socklist[i] == -1) { 372 if (socklist[i] == -1) {
@@ -427,10 +424,10 @@ double offset_request(const char *host, int *status) {
427 } 424 }
428 425
429 /* read from any sockets with pending data */ 426 /* read from any sockets with pending data */
430 for (int i = 0; servers_readable && i < num_hosts; i++) { 427 for (size_t i = 0; servers_readable && i < num_hosts; i++) {
431 if (ufds[i].revents & POLLIN && servers[i].num_responses < AVG_NUM) { 428 if (ufds[i].revents & POLLIN && servers[i].num_responses < AVG_NUM) {
432 if (verbose) { 429 if (verbose) {
433 printf("response from peer %d: ", i); 430 printf("response from peer %zu: ", i);
434 } 431 }
435 432
436 read(ufds[i].fd, &req[i], sizeof(ntp_message)); 433 read(ufds[i].fd, &req[i], sizeof(ntp_message));
@@ -458,7 +455,7 @@ double offset_request(const char *host, int *status) {
458 /* lather, rinse, repeat. */ 455 /* lather, rinse, repeat. */
459 } 456 }
460 457
461 if (one_read == false) { 458 if (!one_read) {
462 die(STATE_CRITICAL, "NTP CRITICAL: No response from NTP server\n"); 459 die(STATE_CRITICAL, "NTP CRITICAL: No response from NTP server\n");
463 } 460 }
464 461
@@ -476,14 +473,14 @@ double offset_request(const char *host, int *status) {
476 } 473 }
477 474
478 /* cleanup */ 475 /* cleanup */
479 for (int j = 0; j < num_hosts; j++) { 476 for (size_t j = 0; j < num_hosts; j++) {
480 close(socklist[j]); 477 close(socklist[j]);
481 } 478 }
482 free(socklist); 479 free(socklist);
483 free(ufds); 480 free(ufds);
484 free(servers); 481 free(servers);
485 free(req); 482 free(req);
486 freeaddrinfo(ai); 483 freeaddrinfo(addresses);
487 484
488 if (verbose) { 485 if (verbose) {
489 printf("overall average offset: %.10g\n", avg_offset); 486 printf("overall average offset: %.10g\n", avg_offset);
@@ -602,8 +599,8 @@ int main(int argc, char *argv[]) {
602 /* set socket timeout */ 599 /* set socket timeout */
603 alarm(socket_timeout); 600 alarm(socket_timeout);
604 601
605 int offset_result = STATE_OK; 602 mp_state_enum offset_result = STATE_OK;
606 int result = STATE_OK; 603 mp_state_enum result = STATE_OK;
607 double offset = offset_request(server_address, &offset_result); 604 double offset = offset_request(server_address, &offset_result);
608 if (offset_result == STATE_UNKNOWN) { 605 if (offset_result == STATE_UNKNOWN) {
609 result = ((!quiet) ? STATE_UNKNOWN : STATE_CRITICAL); 606 result = ((!quiet) ? STATE_UNKNOWN : STATE_CRITICAL);
@@ -640,7 +637,7 @@ int main(int argc, char *argv[]) {
640 if (server_address != NULL) { 637 if (server_address != NULL) {
641 free(server_address); 638 free(server_address);
642 } 639 }
643 return result; 640 exit(result);
644} 641}
645 642
646void print_help(void) { 643void print_help(void) {