summaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
authorLorenz Kästle <12514511+RincewindsHat@users.noreply.github.com>2025-03-12 01:00:48 +0100
committerLorenz Kästle <12514511+RincewindsHat@users.noreply.github.com>2025-03-12 01:00:48 +0100
commit8b2222e8b704fc451093996e906c07a6a8e3538a (patch)
tree317862c640dada64ccb7faf2c4c74bb39f2f80e2 /plugins
parent9f6f32324e694d51e9e01e07fcd9694736f7846a (diff)
downloadmonitoring-plugins-8b2222e8b704fc451093996e906c07a6a8e3538a.tar.gz
Refactor check_ntp_peer
Diffstat (limited to 'plugins')
-rw-r--r--plugins/Makefile.am1
-rw-r--r--plugins/check_ntp_peer.c139
-rw-r--r--plugins/check_ntp_peer.d/config.h54
3 files changed, 127 insertions, 67 deletions
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 5d4449bf..a294cfef 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -60,6 +60,7 @@ EXTRA_DIST = t \
60 check_mrtgtraf.d \ 60 check_mrtgtraf.d \
61 check_mysql_query.d \ 61 check_mysql_query.d \
62 check_mrtg.d \ 62 check_mrtg.d \
63 check_ntp_peer.d \
63 check_apt.d \ 64 check_apt.d \
64 check_by_ssh.d \ 65 check_by_ssh.d \
65 check_smtp.d \ 66 check_smtp.d \
diff --git a/plugins/check_ntp_peer.c b/plugins/check_ntp_peer.c
index 35abdf10..6979d275 100644
--- a/plugins/check_ntp_peer.c
+++ b/plugins/check_ntp_peer.c
@@ -35,6 +35,7 @@
35 * 35 *
36 *****************************************************************************/ 36 *****************************************************************************/
37 37
38#include "states.h"
38const char *progname = "check_ntp_peer"; 39const char *progname = "check_ntp_peer";
39const char *copyright = "2006-2024"; 40const char *copyright = "2006-2024";
40const char *email = "devel@monitoring-plugins.org"; 41const char *email = "devel@monitoring-plugins.org";
@@ -42,26 +43,17 @@ const char *email = "devel@monitoring-plugins.org";
42#include "common.h" 43#include "common.h"
43#include "netutils.h" 44#include "netutils.h"
44#include "utils.h" 45#include "utils.h"
46#include "check_ntp_peer.d/config.h"
45 47
46static char *server_address = NULL;
47static int port = 123;
48static int verbose = 0; 48static int verbose = 0;
49static bool quiet = false;
50static char *owarn = "60";
51static char *ocrit = "120";
52static bool do_stratum = false;
53static char *swarn = "-1:16";
54static char *scrit = "-1:16";
55static bool do_jitter = false;
56static char *jwarn = "-1:5000";
57static char *jcrit = "-1:10000";
58static bool do_truechimers = false;
59static char *twarn = "0:";
60static char *tcrit = "0:";
61static bool syncsource_found = false; 49static bool syncsource_found = false;
62static bool li_alarm = false; 50static bool li_alarm = false;
63 51
64static int process_arguments(int /*argc*/, char ** /*argv*/); 52typedef struct {
53 int errorcode;
54 check_ntp_peer_config config;
55} check_ntp_peer_config_wrapper;
56static check_ntp_peer_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
65static thresholds *offset_thresholds = NULL; 57static thresholds *offset_thresholds = NULL;
66static thresholds *jitter_thresholds = NULL; 58static thresholds *jitter_thresholds = NULL;
67static thresholds *stratum_thresholds = NULL; 59static thresholds *stratum_thresholds = NULL;
@@ -211,7 +203,8 @@ void setup_control_request(ntp_control_message *p, uint8_t opcode, uint16_t seq)
211 * status is pretty much useless as syncsource_found is a global variable 203 * status is pretty much useless as syncsource_found is a global variable
212 * used later in main to check is the server was synchronized. It works 204 * used later in main to check is the server was synchronized. It works
213 * so I left it alone */ 205 * so I left it alone */
214int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum, int *num_truechimers) { 206mp_state_enum ntp_request(double *offset, int *offset_result, double *jitter, int *stratum, int *num_truechimers,
207 const check_ntp_peer_config config) {
215 *offset_result = STATE_UNKNOWN; 208 *offset_result = STATE_UNKNOWN;
216 *jitter = *stratum = -1; 209 *jitter = *stratum = -1;
217 *num_truechimers = 0; 210 *num_truechimers = 0;
@@ -240,7 +233,7 @@ int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum
240 int peers_size = 0; 233 int peers_size = 0;
241 int npeers = 0; 234 int npeers = 0;
242 int conn = -1; 235 int conn = -1;
243 my_udp_connect(server_address, port, &conn); 236 my_udp_connect(config.server_address, config.port, &conn);
244 237
245 /* keep sending requests until the server stops setting the 238 /* keep sending requests until the server stops setting the
246 * REM_MORE bit, though usually this is only 1 packet. */ 239 * REM_MORE bit, though usually this is only 1 packet. */
@@ -412,7 +405,7 @@ int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum
412 } 405 }
413 } 406 }
414 407
415 if (do_jitter) { 408 if (config.do_jitter) {
416 /* get the jitter */ 409 /* get the jitter */
417 if (verbose) { 410 if (verbose) {
418 printf("parsing %s from peer %.2x: ", strstr(getvar, "dispersion") != NULL ? "dispersion" : "jitter", 411 printf("parsing %s from peer %.2x: ", strstr(getvar, "dispersion") != NULL ? "dispersion" : "jitter",
@@ -435,7 +428,7 @@ int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum
435 } 428 }
436 } 429 }
437 430
438 if (do_stratum) { 431 if (config.do_stratum) {
439 /* get the stratum */ 432 /* get the stratum */
440 if (verbose) { 433 if (verbose) {
441 printf("parsing stratum from peer %.2x: ", ntohs(peers[i].assoc)); 434 printf("parsing stratum from peer %.2x: ", ntohs(peers[i].assoc));
@@ -468,7 +461,7 @@ int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum
468 return status; 461 return status;
469} 462}
470 463
471int process_arguments(int argc, char **argv) { 464check_ntp_peer_config_wrapper process_arguments(int argc, char **argv) {
472 static struct option longopts[] = { 465 static struct option longopts[] = {
473 {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, {"verbose", no_argument, 0, 'v'}, 466 {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, {"verbose", no_argument, 0, 'v'},
474 {"use-ipv4", no_argument, 0, '4'}, {"use-ipv6", no_argument, 0, '6'}, {"quiet", no_argument, 0, 'q'}, 467 {"use-ipv4", no_argument, 0, '4'}, {"use-ipv6", no_argument, 0, '6'}, {"quiet", no_argument, 0, 'q'},
@@ -481,6 +474,11 @@ int process_arguments(int argc, char **argv) {
481 usage("\n"); 474 usage("\n");
482 } 475 }
483 476
477 check_ntp_peer_config_wrapper result = {
478 .errorcode = OK,
479 .config = check_ntp_peer_config_init(),
480 };
481
484 while (true) { 482 while (true) {
485 int option = 0; 483 int option = 0;
486 int option_char = getopt_long(argc, argv, "Vhv46qw:c:W:C:j:k:m:n:t:H:p:", longopts, &option); 484 int option_char = getopt_long(argc, argv, "Vhv46qw:c:W:C:j:k:m:n:t:H:p:", longopts, &option);
@@ -501,46 +499,46 @@ int process_arguments(int argc, char **argv) {
501 verbose++; 499 verbose++;
502 break; 500 break;
503 case 'q': 501 case 'q':
504 quiet = true; 502 result.config.quiet = true;
505 break; 503 break;
506 case 'w': 504 case 'w':
507 owarn = optarg; 505 result.config.owarn = optarg;
508 break; 506 break;
509 case 'c': 507 case 'c':
510 ocrit = optarg; 508 result.config.ocrit = optarg;
511 break; 509 break;
512 case 'W': 510 case 'W':
513 do_stratum = true; 511 result.config.do_stratum = true;
514 swarn = optarg; 512 result.config.swarn = optarg;
515 break; 513 break;
516 case 'C': 514 case 'C':
517 do_stratum = true; 515 result.config.do_stratum = true;
518 scrit = optarg; 516 result.config.scrit = optarg;
519 break; 517 break;
520 case 'j': 518 case 'j':
521 do_jitter = true; 519 result.config.do_jitter = true;
522 jwarn = optarg; 520 result.config.jwarn = optarg;
523 break; 521 break;
524 case 'k': 522 case 'k':
525 do_jitter = true; 523 result.config.do_jitter = true;
526 jcrit = optarg; 524 result.config.jcrit = optarg;
527 break; 525 break;
528 case 'm': 526 case 'm':
529 do_truechimers = true; 527 result.config.do_truechimers = true;
530 twarn = optarg; 528 result.config.twarn = optarg;
531 break; 529 break;
532 case 'n': 530 case 'n':
533 do_truechimers = true; 531 result.config.do_truechimers = true;
534 tcrit = optarg; 532 result.config.tcrit = optarg;
535 break; 533 break;
536 case 'H': 534 case 'H':
537 if (!is_host(optarg)) { 535 if (!is_host(optarg)) {
538 usage2(_("Invalid hostname/address"), optarg); 536 usage2(_("Invalid hostname/address"), optarg);
539 } 537 }
540 server_address = strdup(optarg); 538 result.config.server_address = strdup(optarg);
541 break; 539 break;
542 case 'p': 540 case 'p':
543 port = atoi(optarg); 541 result.config.port = atoi(optarg);
544 break; 542 break;
545 case 't': 543 case 't':
546 socket_timeout = atoi(optarg); 544 socket_timeout = atoi(optarg);
@@ -562,11 +560,11 @@ int process_arguments(int argc, char **argv) {
562 } 560 }
563 } 561 }
564 562
565 if (server_address == NULL) { 563 if (result.config.server_address == NULL) {
566 usage4(_("Hostname was not supplied")); 564 usage4(_("Hostname was not supplied"));
567 } 565 }
568 566
569 return 0; 567 return result;
570} 568}
571 569
572char *perfd_offset(double offset) { 570char *perfd_offset(double offset) {
@@ -574,17 +572,17 @@ char *perfd_offset(double offset) {
574 0); 572 0);
575} 573}
576 574
577char *perfd_jitter(double jitter) { 575char *perfd_jitter(double jitter, bool do_jitter) {
578 return fperfdata("jitter", jitter, "", do_jitter, jitter_thresholds->warning->end, do_jitter, jitter_thresholds->critical->end, true, 0, 576 return fperfdata("jitter", jitter, "", do_jitter, jitter_thresholds->warning->end, do_jitter, jitter_thresholds->critical->end, true, 0,
579 false, 0); 577 false, 0);
580} 578}
581 579
582char *perfd_stratum(int stratum) { 580char *perfd_stratum(int stratum, bool do_stratum) {
583 return perfdata("stratum", stratum, "", do_stratum, (int)stratum_thresholds->warning->end, do_stratum, 581 return perfdata("stratum", stratum, "", do_stratum, (int)stratum_thresholds->warning->end, do_stratum,
584 (int)stratum_thresholds->critical->end, true, 0, true, 16); 582 (int)stratum_thresholds->critical->end, true, 0, true, 16);
585} 583}
586 584
587char *perfd_truechimers(int num_truechimers) { 585char *perfd_truechimers(int num_truechimers, const bool do_truechimers) {
588 return perfdata("truechimers", num_truechimers, "", do_truechimers, (int)truechimer_thresholds->warning->end, do_truechimers, 586 return perfdata("truechimers", num_truechimers, "", do_truechimers, (int)truechimer_thresholds->warning->end, do_truechimers,
589 (int)truechimer_thresholds->critical->end, true, 0, false, 0); 587 (int)truechimer_thresholds->critical->end, true, 0, false, 0);
590} 588}
@@ -597,14 +595,18 @@ int main(int argc, char *argv[]) {
597 /* Parse extra opts if any */ 595 /* Parse extra opts if any */
598 argv = np_extra_opts(&argc, argv, progname); 596 argv = np_extra_opts(&argc, argv, progname);
599 597
600 if (process_arguments(argc, argv) == ERROR) { 598 check_ntp_peer_config_wrapper tmp_config = process_arguments(argc, argv);
599
600 if (tmp_config.errorcode == ERROR) {
601 usage4(_("Could not parse arguments")); 601 usage4(_("Could not parse arguments"));
602 } 602 }
603 603
604 set_thresholds(&offset_thresholds, owarn, ocrit); 604 const check_ntp_peer_config config = tmp_config.config;
605 set_thresholds(&jitter_thresholds, jwarn, jcrit); 605
606 set_thresholds(&stratum_thresholds, swarn, scrit); 606 set_thresholds(&offset_thresholds, config.owarn, config.ocrit);
607 set_thresholds(&truechimer_thresholds, twarn, tcrit); 607 set_thresholds(&jitter_thresholds, config.jwarn, config.jcrit);
608 set_thresholds(&stratum_thresholds, config.swarn, config.scrit);
609 set_thresholds(&truechimer_thresholds, config.twarn, config.tcrit);
608 610
609 /* initialize alarm signal handling */ 611 /* initialize alarm signal handling */
610 signal(SIGALRM, socket_timeout_alarm_handler); 612 signal(SIGALRM, socket_timeout_alarm_handler);
@@ -618,38 +620,37 @@ int main(int argc, char *argv[]) {
618 double offset = 0; 620 double offset = 0;
619 double jitter = 0; 621 double jitter = 0;
620 /* This returns either OK or WARNING (See comment preceding ntp_request) */ 622 /* This returns either OK or WARNING (See comment preceding ntp_request) */
621 int result = ntp_request(&offset, &offset_result, &jitter, &stratum, &num_truechimers); 623 mp_state_enum result = ntp_request(&offset, &offset_result, &jitter, &stratum, &num_truechimers, config);
622 624
623 if (offset_result == STATE_UNKNOWN) { 625 if (offset_result == STATE_UNKNOWN) {
624 /* if there's no sync peer (this overrides ntp_request output): */ 626 /* if there's no sync peer (this overrides ntp_request output): */
625 result = (quiet ? STATE_UNKNOWN : STATE_CRITICAL); 627 result = (config.quiet ? STATE_UNKNOWN : STATE_CRITICAL);
626 } else { 628 } else {
627 /* Be quiet if there's no candidates either */ 629 /* Be quiet if there's no candidates either */
628 if (quiet && result == STATE_WARNING) { 630 if (config.quiet && result == STATE_WARNING) {
629 result = STATE_UNKNOWN; 631 result = STATE_UNKNOWN;
630 } 632 }
631 result = max_state_alt(result, get_status(fabs(offset), offset_thresholds)); 633 result = max_state_alt(result, get_status(fabs(offset), offset_thresholds));
632 } 634 }
633 635
634 int oresult = result; 636 mp_state_enum oresult = result;
635 637 mp_state_enum tresult = STATE_UNKNOWN;
636 int tresult = STATE_UNKNOWN;
637 638
638 if (do_truechimers) { 639 if (config.do_truechimers) {
639 tresult = get_status(num_truechimers, truechimer_thresholds); 640 tresult = get_status(num_truechimers, truechimer_thresholds);
640 result = max_state_alt(result, tresult); 641 result = max_state_alt(result, tresult);
641 } 642 }
642 643
643 int sresult = STATE_UNKNOWN; 644 mp_state_enum sresult = STATE_UNKNOWN;
644 645
645 if (do_stratum) { 646 if (config.do_stratum) {
646 sresult = get_status(stratum, stratum_thresholds); 647 sresult = get_status(stratum, stratum_thresholds);
647 result = max_state_alt(result, sresult); 648 result = max_state_alt(result, sresult);
648 } 649 }
649 650
650 int jresult = STATE_UNKNOWN; 651 mp_state_enum jresult = STATE_UNKNOWN;
651 652
652 if (do_jitter) { 653 if (config.do_jitter) {
653 jresult = get_status(jitter, jitter_thresholds); 654 jresult = get_status(jitter, jitter_thresholds);
654 result = max_state_alt(result, jresult); 655 result = max_state_alt(result, jresult);
655 } 656 }
@@ -669,6 +670,7 @@ int main(int argc, char *argv[]) {
669 xasprintf(&result_line, _("NTP UNKNOWN:")); 670 xasprintf(&result_line, _("NTP UNKNOWN:"));
670 break; 671 break;
671 } 672 }
673
672 if (!syncsource_found) { 674 if (!syncsource_found) {
673 xasprintf(&result_line, "%s %s,", result_line, _("Server not synchronized")); 675 xasprintf(&result_line, "%s %s,", result_line, _("Server not synchronized"));
674 } else if (li_alarm) { 676 } else if (li_alarm) {
@@ -688,7 +690,7 @@ int main(int argc, char *argv[]) {
688 } 690 }
689 xasprintf(&perfdata_line, "%s", perfd_offset(offset)); 691 xasprintf(&perfdata_line, "%s", perfd_offset(offset));
690 692
691 if (do_jitter) { 693 if (config.do_jitter) {
692 if (jresult == STATE_WARNING) { 694 if (jresult == STATE_WARNING) {
693 xasprintf(&result_line, "%s, jitter=%f (WARNING)", result_line, jitter); 695 xasprintf(&result_line, "%s, jitter=%f (WARNING)", result_line, jitter);
694 } else if (jresult == STATE_CRITICAL) { 696 } else if (jresult == STATE_CRITICAL) {
@@ -696,9 +698,10 @@ int main(int argc, char *argv[]) {
696 } else { 698 } else {
697 xasprintf(&result_line, "%s, jitter=%f", result_line, jitter); 699 xasprintf(&result_line, "%s, jitter=%f", result_line, jitter);
698 } 700 }
699 xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_jitter(jitter)); 701 xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_jitter(jitter, config.do_jitter));
700 } 702 }
701 if (do_stratum) { 703
704 if (config.do_stratum) {
702 if (sresult == STATE_WARNING) { 705 if (sresult == STATE_WARNING) {
703 xasprintf(&result_line, "%s, stratum=%i (WARNING)", result_line, stratum); 706 xasprintf(&result_line, "%s, stratum=%i (WARNING)", result_line, stratum);
704 } else if (sresult == STATE_CRITICAL) { 707 } else if (sresult == STATE_CRITICAL) {
@@ -706,9 +709,10 @@ int main(int argc, char *argv[]) {
706 } else { 709 } else {
707 xasprintf(&result_line, "%s, stratum=%i", result_line, stratum); 710 xasprintf(&result_line, "%s, stratum=%i", result_line, stratum);
708 } 711 }
709 xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_stratum(stratum)); 712 xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_stratum(stratum, config.do_stratum));
710 } 713 }
711 if (do_truechimers) { 714
715 if (config.do_truechimers) {
712 if (tresult == STATE_WARNING) { 716 if (tresult == STATE_WARNING) {
713 xasprintf(&result_line, "%s, truechimers=%i (WARNING)", result_line, num_truechimers); 717 xasprintf(&result_line, "%s, truechimers=%i (WARNING)", result_line, num_truechimers);
714 } else if (tresult == STATE_CRITICAL) { 718 } else if (tresult == STATE_CRITICAL) {
@@ -716,14 +720,15 @@ int main(int argc, char *argv[]) {
716 } else { 720 } else {
717 xasprintf(&result_line, "%s, truechimers=%i", result_line, num_truechimers); 721 xasprintf(&result_line, "%s, truechimers=%i", result_line, num_truechimers);
718 } 722 }
719 xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_truechimers(num_truechimers)); 723 xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_truechimers(num_truechimers, config.do_truechimers));
720 } 724 }
721 printf("%s|%s\n", result_line, perfdata_line); 725 printf("%s|%s\n", result_line, perfdata_line);
722 726
723 if (server_address != NULL) { 727 if (config.server_address != NULL) {
724 free(server_address); 728 free(config.server_address);
725 } 729 }
726 return result; 730
731 exit(result);
727} 732}
728 733
729void print_help(void) { 734void print_help(void) {
diff --git a/plugins/check_ntp_peer.d/config.h b/plugins/check_ntp_peer.d/config.h
new file mode 100644
index 00000000..1907af7c
--- /dev/null
+++ b/plugins/check_ntp_peer.d/config.h
@@ -0,0 +1,54 @@
1#pragma once
2
3#include "../../config.h"
4#include <stddef.h>
5
6enum {
7 DEFAULT_NTP_PORT = 123,
8};
9
10typedef struct {
11 char *server_address;
12 int port;
13
14 bool quiet;
15
16 // truechimer stuff
17 bool do_truechimers;
18 char *twarn;
19 char *tcrit;
20
21 char *owarn;
22 char *ocrit;
23
24 // stratum stuff
25 bool do_stratum;
26 char *swarn;
27 char *scrit;
28
29 // jitter stuff
30 bool do_jitter;
31 char *jwarn;
32 char *jcrit;
33} check_ntp_peer_config;
34
35check_ntp_peer_config check_ntp_peer_config_init() {
36 check_ntp_peer_config tmp = {
37 .server_address = NULL,
38 .port = DEFAULT_NTP_PORT,
39
40 .quiet = false,
41 .do_truechimers = false,
42 .twarn = "0:",
43 .tcrit = "0:",
44 .owarn = "60",
45 .ocrit = "120",
46 .do_stratum = false,
47 .swarn = "-1:16",
48 .scrit = "-1:16",
49 .do_jitter = false,
50 .jwarn = "-1:5000",
51 .jcrit = "-1:10000",
52 };
53 return tmp;
54}