summaryrefslogtreecommitdiffstats
path: root/plugins/check_ntp_peer.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/check_ntp_peer.c')
-rw-r--r--plugins/check_ntp_peer.c118
1 files changed, 69 insertions, 49 deletions
diff --git a/plugins/check_ntp_peer.c b/plugins/check_ntp_peer.c
index 5c4ff386..24d1c9b5 100644
--- a/plugins/check_ntp_peer.c
+++ b/plugins/check_ntp_peer.c
@@ -83,9 +83,9 @@ typedef struct {
83/* bits 1,2 are the leap indicator */ 83/* bits 1,2 are the leap indicator */
84#define LI_MASK 0xc0 84#define LI_MASK 0xc0
85#define LI(x) ((x & LI_MASK) >> 6) 85#define LI(x) ((x & LI_MASK) >> 6)
86#define LI_SET(x, y) \ 86#define LI_SET(x, y) \
87 do { \ 87 do { \
88 x |= ((y << 6) & LI_MASK); \ 88 x |= ((y << 6) & LI_MASK); \
89 } while (0) 89 } while (0)
90/* and these are the values of the leap indicator */ 90/* and these are the values of the leap indicator */
91#define LI_NOWARNING 0x00 91#define LI_NOWARNING 0x00
@@ -95,17 +95,17 @@ typedef struct {
95/* bits 3,4,5 are the ntp version */ 95/* bits 3,4,5 are the ntp version */
96#define VN_MASK 0x38 96#define VN_MASK 0x38
97#define VN(x) ((x & VN_MASK) >> 3) 97#define VN(x) ((x & VN_MASK) >> 3)
98#define VN_SET(x, y) \ 98#define VN_SET(x, y) \
99 do { \ 99 do { \
100 x |= ((y << 3) & VN_MASK); \ 100 x |= ((y << 3) & VN_MASK); \
101 } while (0) 101 } while (0)
102#define VN_RESERVED 0x02 102#define VN_RESERVED 0x02
103/* bits 6,7,8 are the ntp mode */ 103/* bits 6,7,8 are the ntp mode */
104#define MODE_MASK 0x07 104#define MODE_MASK 0x07
105#define MODE(x) (x & MODE_MASK) 105#define MODE(x) (x & MODE_MASK)
106#define MODE_SET(x, y) \ 106#define MODE_SET(x, y) \
107 do { \ 107 do { \
108 x |= (y & MODE_MASK); \ 108 x |= (y & MODE_MASK); \
109 } while (0) 109 } while (0)
110/* here are some values */ 110/* here are some values */
111#define MODE_CLIENT 0x03 111#define MODE_CLIENT 0x03
@@ -117,9 +117,9 @@ typedef struct {
117#define REM_MORE 0x20 117#define REM_MORE 0x20
118/* In control message, bits 11 - 15 are opcode */ 118/* In control message, bits 11 - 15 are opcode */
119#define OP_MASK 0x1f 119#define OP_MASK 0x1f
120#define OP_SET(x, y) \ 120#define OP_SET(x, y) \
121 do { \ 121 do { \
122 x |= (y & OP_MASK); \ 122 x |= (y & OP_MASK); \
123 } while (0) 123 } while (0)
124#define OP_READSTAT 0x01 124#define OP_READSTAT 0x01
125#define OP_READVAR 0x02 125#define OP_READVAR 0x02
@@ -132,18 +132,19 @@ typedef struct {
132/* NTP control message header is 12 bytes, plus any data in the data 132/* NTP control message header is 12 bytes, plus any data in the data
133 * field, plus null padding to the nearest 32-bit boundary per rfc. 133 * field, plus null padding to the nearest 32-bit boundary per rfc.
134 */ 134 */
135#define SIZEOF_NTPCM(m) (12 + ntohs(m.count) + ((ntohs(m.count) % 4) ? 4 - (ntohs(m.count) % 4) : 0)) 135#define SIZEOF_NTPCM(m) \
136 (12 + ntohs(m.count) + ((ntohs(m.count) % 4) ? 4 - (ntohs(m.count) % 4) : 0))
136 137
137/* finally, a little helper or two for debugging: */ 138/* finally, a little helper or two for debugging: */
138#define DBG(x) \ 139#define DBG(x) \
139 do { \ 140 do { \
140 if (verbose > 1) { \ 141 if (verbose > 1) { \
141 x; \ 142 x; \
142 } \ 143 } \
143 } while (0); 144 } while (0);
144#define PRINTSOCKADDR(x) \ 145#define PRINTSOCKADDR(x) \
145 do { \ 146 do { \
146 printf("%u.%u.%u.%u", (x >> 24) & 0xff, (x >> 16) & 0xff, (x >> 8) & 0xff, x & 0xff); \ 147 printf("%u.%u.%u.%u", (x >> 24) & 0xff, (x >> 16) & 0xff, (x >> 8) & 0xff, x & 0xff); \
147 } while (0); 148 } while (0);
148 149
149void print_ntp_control_message(const ntp_control_message *message) { 150void print_ntp_control_message(const ntp_control_message *message) {
@@ -360,7 +361,8 @@ ntp_request_result ntp_request(const check_ntp_peer_config config) {
360 if (req.op & REM_ERROR) { 361 if (req.op & REM_ERROR) {
361 if (strstr(getvar, "jitter")) { 362 if (strstr(getvar, "jitter")) {
362 if (verbose) { 363 if (verbose) {
363 printf("The command failed. This is usually caused by servers refusing the 'jitter'\nvariable. Restarting with " 364 printf("The command failed. This is usually caused by servers refusing the "
365 "'jitter'\nvariable. Restarting with "
364 "'dispersion'...\n"); 366 "'dispersion'...\n");
365 } 367 }
366 getvar = "stratum,offset,dispersion"; 368 getvar = "stratum,offset,dispersion";
@@ -404,7 +406,8 @@ ntp_request_result ntp_request(const check_ntp_peer_config config) {
404 if (verbose) { 406 if (verbose) {
405 printf("%.10g\n", tmp_offset); 407 printf("%.10g\n", tmp_offset);
406 } 408 }
407 if (result.offset_result == STATE_UNKNOWN || fabs(tmp_offset) < fabs(result.offset)) { 409 if (result.offset_result == STATE_UNKNOWN ||
410 fabs(tmp_offset) < fabs(result.offset)) {
408 result.offset = tmp_offset; 411 result.offset = tmp_offset;
409 result.offset_result = STATE_OK; 412 result.offset_result = STATE_OK;
410 } else { 413 } else {
@@ -416,10 +419,12 @@ ntp_request_result ntp_request(const check_ntp_peer_config config) {
416 if (config.do_jitter) { 419 if (config.do_jitter) {
417 /* get the jitter */ 420 /* get the jitter */
418 if (verbose) { 421 if (verbose) {
419 printf("parsing %s from peer %.2x: ", strstr(getvar, "dispersion") != NULL ? "dispersion" : "jitter", 422 printf("parsing %s from peer %.2x: ",
423 strstr(getvar, "dispersion") != NULL ? "dispersion" : "jitter",
420 ntohs(peers[i].assoc)); 424 ntohs(peers[i].assoc));
421 } 425 }
422 value = np_extract_ntpvar(data, strstr(getvar, "dispersion") != NULL ? "dispersion" : "jitter"); 426 value = np_extract_ntpvar(data, strstr(getvar, "dispersion") != NULL ? "dispersion"
427 : "jitter");
423 nptr = NULL; 428 nptr = NULL;
424 /* Convert the value if we have one */ 429 /* Convert the value if we have one */
425 if (value != NULL) { 430 if (value != NULL) {
@@ -471,12 +476,15 @@ ntp_request_result ntp_request(const check_ntp_peer_config config) {
471 476
472check_ntp_peer_config_wrapper process_arguments(int argc, char **argv) { 477check_ntp_peer_config_wrapper process_arguments(int argc, char **argv) {
473 static struct option longopts[] = { 478 static struct option longopts[] = {
474 {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, {"verbose", no_argument, 0, 'v'}, 479 {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'},
475 {"use-ipv4", no_argument, 0, '4'}, {"use-ipv6", no_argument, 0, '6'}, {"quiet", no_argument, 0, 'q'}, 480 {"verbose", no_argument, 0, 'v'}, {"use-ipv4", no_argument, 0, '4'},
476 {"warning", required_argument, 0, 'w'}, {"critical", required_argument, 0, 'c'}, {"swarn", required_argument, 0, 'W'}, 481 {"use-ipv6", no_argument, 0, '6'}, {"quiet", no_argument, 0, 'q'},
477 {"scrit", required_argument, 0, 'C'}, {"jwarn", required_argument, 0, 'j'}, {"jcrit", required_argument, 0, 'k'}, 482 {"warning", required_argument, 0, 'w'}, {"critical", required_argument, 0, 'c'},
478 {"twarn", required_argument, 0, 'm'}, {"tcrit", required_argument, 0, 'n'}, {"timeout", required_argument, 0, 't'}, 483 {"swarn", required_argument, 0, 'W'}, {"scrit", required_argument, 0, 'C'},
479 {"hostname", required_argument, 0, 'H'}, {"port", required_argument, 0, 'p'}, {0, 0, 0, 0}}; 484 {"jwarn", required_argument, 0, 'j'}, {"jcrit", required_argument, 0, 'k'},
485 {"twarn", required_argument, 0, 'm'}, {"tcrit", required_argument, 0, 'n'},
486 {"timeout", required_argument, 0, 't'}, {"hostname", required_argument, 0, 'H'},
487 {"port", required_argument, 0, 'p'}, {0, 0, 0, 0}};
480 488
481 if (argc < 2) { 489 if (argc < 2) {
482 usage("\n"); 490 usage("\n");
@@ -489,7 +497,8 @@ check_ntp_peer_config_wrapper process_arguments(int argc, char **argv) {
489 497
490 while (true) { 498 while (true) {
491 int option = 0; 499 int option = 0;
492 int option_char = getopt_long(argc, argv, "Vhv46qw:c:W:C:j:k:m:n:t:H:p:", longopts, &option); 500 int option_char =
501 getopt_long(argc, argv, "Vhv46qw:c:W:C:j:k:m:n:t:H:p:", longopts, &option);
493 if (option_char == -1 || option_char == EOF || option_char == 1) { 502 if (option_char == -1 || option_char == EOF || option_char == 1) {
494 break; 503 break;
495 } 504 }
@@ -581,22 +590,24 @@ check_ntp_peer_config_wrapper process_arguments(int argc, char **argv) {
581} 590}
582 591
583char *perfd_offset(double offset, thresholds *offset_thresholds) { 592char *perfd_offset(double offset, thresholds *offset_thresholds) {
584 return fperfdata("offset", offset, "s", true, offset_thresholds->warning->end, true, offset_thresholds->critical->end, false, 0, false, 593 return fperfdata("offset", offset, "s", true, offset_thresholds->warning->end, true,
585 0); 594 offset_thresholds->critical->end, false, 0, false, 0);
586} 595}
587 596
588char *perfd_jitter(double jitter, bool do_jitter, thresholds *jitter_thresholds) { 597char *perfd_jitter(double jitter, bool do_jitter, thresholds *jitter_thresholds) {
589 return fperfdata("jitter", jitter, "", do_jitter, jitter_thresholds->warning->end, do_jitter, jitter_thresholds->critical->end, true, 0, 598 return fperfdata("jitter", jitter, "", do_jitter, jitter_thresholds->warning->end, do_jitter,
590 false, 0); 599 jitter_thresholds->critical->end, true, 0, false, 0);
591} 600}
592 601
593char *perfd_stratum(int stratum, bool do_stratum, thresholds *stratum_thresholds) { 602char *perfd_stratum(int stratum, bool do_stratum, thresholds *stratum_thresholds) {
594 return perfdata("stratum", stratum, "", do_stratum, (int)stratum_thresholds->warning->end, do_stratum, 603 return perfdata("stratum", stratum, "", do_stratum, (int)stratum_thresholds->warning->end,
595 (int)stratum_thresholds->critical->end, true, 0, true, 16); 604 do_stratum, (int)stratum_thresholds->critical->end, true, 0, true, 16);
596} 605}
597 606
598char *perfd_truechimers(int num_truechimers, const bool do_truechimers, thresholds *truechimer_thresholds) { 607char *perfd_truechimers(int num_truechimers, const bool do_truechimers,
599 return perfdata("truechimers", num_truechimers, "", do_truechimers, (int)truechimer_thresholds->warning->end, do_truechimers, 608 thresholds *truechimer_thresholds) {
609 return perfdata("truechimers", num_truechimers, "", do_truechimers,
610 (int)truechimer_thresholds->warning->end, do_truechimers,
600 (int)truechimer_thresholds->critical->end, true, 0, false, 0); 611 (int)truechimer_thresholds->critical->end, true, 0, false, 0);
601} 612}
602 613
@@ -686,9 +697,11 @@ int main(int argc, char *argv[]) {
686 xasprintf(&result_line, "%s %s", result_line, _("Offset unknown")); 697 xasprintf(&result_line, "%s %s", result_line, _("Offset unknown"));
687 xasprintf(&perfdata_line, ""); 698 xasprintf(&perfdata_line, "");
688 } else if (oresult == STATE_WARNING) { 699 } else if (oresult == STATE_WARNING) {
689 xasprintf(&result_line, "%s %s %.10g secs (WARNING)", result_line, _("Offset"), ntp_res.offset); 700 xasprintf(&result_line, "%s %s %.10g secs (WARNING)", result_line, _("Offset"),
701 ntp_res.offset);
690 } else if (oresult == STATE_CRITICAL) { 702 } else if (oresult == STATE_CRITICAL) {
691 xasprintf(&result_line, "%s %s %.10g secs (CRITICAL)", result_line, _("Offset"), ntp_res.offset); 703 xasprintf(&result_line, "%s %s %.10g secs (CRITICAL)", result_line, _("Offset"),
704 ntp_res.offset);
692 } else { 705 } else {
693 xasprintf(&result_line, "%s %s %.10g secs", result_line, _("Offset"), ntp_res.offset); 706 xasprintf(&result_line, "%s %s %.10g secs", result_line, _("Offset"), ntp_res.offset);
694 } 707 }
@@ -702,7 +715,8 @@ int main(int argc, char *argv[]) {
702 } else { 715 } else {
703 xasprintf(&result_line, "%s, jitter=%f", result_line, ntp_res.jitter); 716 xasprintf(&result_line, "%s, jitter=%f", result_line, ntp_res.jitter);
704 } 717 }
705 xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_jitter(ntp_res.jitter, config.do_jitter, config.jitter_thresholds)); 718 xasprintf(&perfdata_line, "%s %s", perfdata_line,
719 perfd_jitter(ntp_res.jitter, config.do_jitter, config.jitter_thresholds));
706 } 720 }
707 721
708 if (config.do_stratum) { 722 if (config.do_stratum) {
@@ -713,19 +727,23 @@ int main(int argc, char *argv[]) {
713 } else { 727 } else {
714 xasprintf(&result_line, "%s, stratum=%li", result_line, ntp_res.stratum); 728 xasprintf(&result_line, "%s, stratum=%li", result_line, ntp_res.stratum);
715 } 729 }
716 xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_stratum(ntp_res.stratum, config.do_stratum, config.stratum_thresholds)); 730 xasprintf(&perfdata_line, "%s %s", perfdata_line,
731 perfd_stratum(ntp_res.stratum, config.do_stratum, config.stratum_thresholds));
717 } 732 }
718 733
719 if (config.do_truechimers) { 734 if (config.do_truechimers) {
720 if (tresult == STATE_WARNING) { 735 if (tresult == STATE_WARNING) {
721 xasprintf(&result_line, "%s, truechimers=%i (WARNING)", result_line, ntp_res.num_truechimers); 736 xasprintf(&result_line, "%s, truechimers=%i (WARNING)", result_line,
737 ntp_res.num_truechimers);
722 } else if (tresult == STATE_CRITICAL) { 738 } else if (tresult == STATE_CRITICAL) {
723 xasprintf(&result_line, "%s, truechimers=%i (CRITICAL)", result_line, ntp_res.num_truechimers); 739 xasprintf(&result_line, "%s, truechimers=%i (CRITICAL)", result_line,
740 ntp_res.num_truechimers);
724 } else { 741 } else {
725 xasprintf(&result_line, "%s, truechimers=%i", result_line, ntp_res.num_truechimers); 742 xasprintf(&result_line, "%s, truechimers=%i", result_line, ntp_res.num_truechimers);
726 } 743 }
727 xasprintf(&perfdata_line, "%s %s", perfdata_line, 744 xasprintf(&perfdata_line, "%s %s", perfdata_line,
728 perfd_truechimers(ntp_res.num_truechimers, config.do_truechimers, config.truechimer_thresholds)); 745 perfd_truechimers(ntp_res.num_truechimers, config.do_truechimers,
746 config.truechimer_thresholds));
729 } 747 }
730 748
731 printf("%s|%s\n", result_line, perfdata_line); 749 printf("%s|%s\n", result_line, perfdata_line);
@@ -753,7 +771,8 @@ void print_help(void) {
753 printf(UT_IPv46); 771 printf(UT_IPv46);
754 printf(UT_HOST_PORT, 'p', "123"); 772 printf(UT_HOST_PORT, 'p', "123");
755 printf(" %s\n", "-q, --quiet"); 773 printf(" %s\n", "-q, --quiet");
756 printf(" %s\n", _("Returns UNKNOWN instead of CRITICAL or WARNING if server isn't synchronized")); 774 printf(" %s\n",
775 _("Returns UNKNOWN instead of CRITICAL or WARNING if server isn't synchronized"));
757 printf(" %s\n", "-w, --warning=THRESHOLD"); 776 printf(" %s\n", "-w, --warning=THRESHOLD");
758 printf(" %s\n", _("Offset to result in warning status (seconds)")); 777 printf(" %s\n", _("Offset to result in warning status (seconds)"));
759 printf(" %s\n", "-c, --critical=THRESHOLD"); 778 printf(" %s\n", "-c, --critical=THRESHOLD");
@@ -790,7 +809,8 @@ void print_help(void) {
790 printf(" %s\n", _("Simple NTP server check:")); 809 printf(" %s\n", _("Simple NTP server check:"));
791 printf(" %s\n", ("./check_ntp_peer -H ntpserv -w 0.5 -c 1")); 810 printf(" %s\n", ("./check_ntp_peer -H ntpserv -w 0.5 -c 1"));
792 printf("\n"); 811 printf("\n");
793 printf(" %s\n", _("Check jitter too, avoiding critical notifications if jitter isn't available")); 812 printf(" %s\n",
813 _("Check jitter too, avoiding critical notifications if jitter isn't available"));
794 printf(" %s\n", _("(See Notes above for more details on thresholds formats):")); 814 printf(" %s\n", _("(See Notes above for more details on thresholds formats):"));
795 printf(" %s\n", ("./check_ntp_peer -H ntpserv -w 0.5 -c 1 -j -1:100 -k -1:200")); 815 printf(" %s\n", ("./check_ntp_peer -H ntpserv -w 0.5 -c 1 -j -1:100 -k -1:200"));
796 printf("\n"); 816 printf("\n");