diff options
Diffstat (limited to 'plugins/check_ntp_peer.c')
| -rw-r--r-- | plugins/check_ntp_peer.c | 139 |
1 files changed, 72 insertions, 67 deletions
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" | ||
| 38 | const char *progname = "check_ntp_peer"; | 39 | const char *progname = "check_ntp_peer"; |
| 39 | const char *copyright = "2006-2024"; | 40 | const char *copyright = "2006-2024"; |
| 40 | const char *email = "devel@monitoring-plugins.org"; | 41 | const 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 | ||
| 46 | static char *server_address = NULL; | ||
| 47 | static int port = 123; | ||
| 48 | static int verbose = 0; | 48 | static int verbose = 0; |
| 49 | static bool quiet = false; | ||
| 50 | static char *owarn = "60"; | ||
| 51 | static char *ocrit = "120"; | ||
| 52 | static bool do_stratum = false; | ||
| 53 | static char *swarn = "-1:16"; | ||
| 54 | static char *scrit = "-1:16"; | ||
| 55 | static bool do_jitter = false; | ||
| 56 | static char *jwarn = "-1:5000"; | ||
| 57 | static char *jcrit = "-1:10000"; | ||
| 58 | static bool do_truechimers = false; | ||
| 59 | static char *twarn = "0:"; | ||
| 60 | static char *tcrit = "0:"; | ||
| 61 | static bool syncsource_found = false; | 49 | static bool syncsource_found = false; |
| 62 | static bool li_alarm = false; | 50 | static bool li_alarm = false; |
| 63 | 51 | ||
| 64 | static int process_arguments(int /*argc*/, char ** /*argv*/); | 52 | typedef struct { |
| 53 | int errorcode; | ||
| 54 | check_ntp_peer_config config; | ||
| 55 | } check_ntp_peer_config_wrapper; | ||
| 56 | static check_ntp_peer_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); | ||
| 65 | static thresholds *offset_thresholds = NULL; | 57 | static thresholds *offset_thresholds = NULL; |
| 66 | static thresholds *jitter_thresholds = NULL; | 58 | static thresholds *jitter_thresholds = NULL; |
| 67 | static thresholds *stratum_thresholds = NULL; | 59 | static 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 */ |
| 214 | int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum, int *num_truechimers) { | 206 | mp_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 | ||
| 471 | int process_arguments(int argc, char **argv) { | 464 | check_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 | ||
| 572 | char *perfd_offset(double offset) { | 570 | char *perfd_offset(double offset) { |
| @@ -574,17 +572,17 @@ char *perfd_offset(double offset) { | |||
| 574 | 0); | 572 | 0); |
| 575 | } | 573 | } |
| 576 | 574 | ||
| 577 | char *perfd_jitter(double jitter) { | 575 | char *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 | ||
| 582 | char *perfd_stratum(int stratum) { | 580 | char *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 | ||
| 587 | char *perfd_truechimers(int num_truechimers) { | 585 | char *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 | ||
| 729 | void print_help(void) { | 734 | void print_help(void) { |
