diff options
Diffstat (limited to 'plugins')
| -rw-r--r-- | plugins/check_ntp_peer.c | 94 |
1 files changed, 62 insertions, 32 deletions
diff --git a/plugins/check_ntp_peer.c b/plugins/check_ntp_peer.c index f99e5032..35abdf10 100644 --- a/plugins/check_ntp_peer.c +++ b/plugins/check_ntp_peer.c | |||
| @@ -255,22 +255,26 @@ int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum | |||
| 255 | /* Attempt to read the largest size packet possible */ | 255 | /* Attempt to read the largest size packet possible */ |
| 256 | req.count = htons(MAX_CM_SIZE); | 256 | req.count = htons(MAX_CM_SIZE); |
| 257 | DBG(printf("receiving READSTAT response")) | 257 | DBG(printf("receiving READSTAT response")) |
| 258 | if (read(conn, &req, SIZEOF_NTPCM(req)) == -1) | 258 | if (read(conn, &req, SIZEOF_NTPCM(req)) == -1) { |
| 259 | die(STATE_CRITICAL, "NTP CRITICAL: No response from NTP server\n"); | 259 | die(STATE_CRITICAL, "NTP CRITICAL: No response from NTP server\n"); |
| 260 | } | ||
| 260 | DBG(print_ntp_control_message(&req)); | 261 | DBG(print_ntp_control_message(&req)); |
| 261 | /* discard obviously invalid packets */ | 262 | /* discard obviously invalid packets */ |
| 262 | if (ntohs(req.count) > MAX_CM_SIZE) | 263 | if (ntohs(req.count) > MAX_CM_SIZE) { |
| 263 | die(STATE_CRITICAL, "NTP CRITICAL: Invalid packet received from NTP server\n"); | 264 | die(STATE_CRITICAL, "NTP CRITICAL: Invalid packet received from NTP server\n"); |
| 265 | } | ||
| 264 | } while (!(req.op & OP_READSTAT && ntohs(req.seq) == 1)); | 266 | } while (!(req.op & OP_READSTAT && ntohs(req.seq) == 1)); |
| 265 | 267 | ||
| 266 | if (LI(req.flags) == LI_ALARM) | 268 | if (LI(req.flags) == LI_ALARM) { |
| 267 | li_alarm = true; | 269 | li_alarm = true; |
| 270 | } | ||
| 268 | /* Each peer identifier is 4 bytes in the data section, which | 271 | /* Each peer identifier is 4 bytes in the data section, which |
| 269 | * we represent as a ntp_assoc_status_pair datatype. | 272 | * we represent as a ntp_assoc_status_pair datatype. |
| 270 | */ | 273 | */ |
| 271 | peers_size += ntohs(req.count); | 274 | peers_size += ntohs(req.count); |
| 272 | if ((tmp = realloc(peers, peers_size)) == NULL) | 275 | if ((tmp = realloc(peers, peers_size)) == NULL) { |
| 273 | free(peers), die(STATE_UNKNOWN, "can not (re)allocate 'peers' buffer\n"); | 276 | free(peers), die(STATE_UNKNOWN, "can not (re)allocate 'peers' buffer\n"); |
| 277 | } | ||
| 274 | peers = tmp; | 278 | peers = tmp; |
| 275 | memcpy((void *)((ptrdiff_t)peers + peer_offset), (void *)req.data, ntohs(req.count)); | 279 | memcpy((void *)((ptrdiff_t)peers + peer_offset), (void *)req.data, ntohs(req.count)); |
| 276 | npeers = peers_size / sizeof(ntp_assoc_status_pair); | 280 | npeers = peers_size / sizeof(ntp_assoc_status_pair); |
| @@ -293,21 +297,25 @@ int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum | |||
| 293 | } | 297 | } |
| 294 | } | 298 | } |
| 295 | 299 | ||
| 296 | if (verbose) | 300 | if (verbose) { |
| 297 | printf("%d candidate peers available\n", num_candidates); | 301 | printf("%d candidate peers available\n", num_candidates); |
| 298 | if (verbose && syncsource_found) | 302 | } |
| 303 | if (verbose && syncsource_found) { | ||
| 299 | printf("synchronization source found\n"); | 304 | printf("synchronization source found\n"); |
| 305 | } | ||
| 300 | 306 | ||
| 301 | int status = STATE_OK; | 307 | int status = STATE_OK; |
| 302 | if (!syncsource_found) { | 308 | if (!syncsource_found) { |
| 303 | status = STATE_WARNING; | 309 | status = STATE_WARNING; |
| 304 | if (verbose) | 310 | if (verbose) { |
| 305 | printf("warning: no synchronization source found\n"); | 311 | printf("warning: no synchronization source found\n"); |
| 312 | } | ||
| 306 | } | 313 | } |
| 307 | if (li_alarm) { | 314 | if (li_alarm) { |
| 308 | status = STATE_WARNING; | 315 | status = STATE_WARNING; |
| 309 | if (verbose) | 316 | if (verbose) { |
| 310 | printf("warning: LI_ALARM bit is set\n"); | 317 | printf("warning: LI_ALARM bit is set\n"); |
| 318 | } | ||
| 311 | } | 319 | } |
| 312 | 320 | ||
| 313 | const char *getvar = "stratum,offset,jitter"; | 321 | const char *getvar = "stratum,offset,jitter"; |
| @@ -316,8 +324,9 @@ int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum | |||
| 316 | /* Only query this server if it is the current sync source */ | 324 | /* Only query this server if it is the current sync source */ |
| 317 | /* If there's no sync.peer, query all candidates and use the best one */ | 325 | /* If there's no sync.peer, query all candidates and use the best one */ |
| 318 | if (PEER_SEL(peers[i].status) >= min_peer_sel) { | 326 | if (PEER_SEL(peers[i].status) >= min_peer_sel) { |
| 319 | if (verbose) | 327 | if (verbose) { |
| 320 | printf("Getting offset, jitter and stratum for peer %.2x\n", ntohs(peers[i].assoc)); | 328 | printf("Getting offset, jitter and stratum for peer %.2x\n", ntohs(peers[i].assoc)); |
| 329 | } | ||
| 321 | xasprintf(&data, ""); | 330 | xasprintf(&data, ""); |
| 322 | do { | 331 | do { |
| 323 | setup_control_request(&req, OP_READVAR, 2); | 332 | setup_control_request(&req, OP_READVAR, 2); |
| @@ -342,50 +351,58 @@ int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum | |||
| 342 | DBG(print_ntp_control_message(&req)); | 351 | DBG(print_ntp_control_message(&req)); |
| 343 | } while (!(req.op & OP_READVAR && ntohs(req.seq) == 2)); | 352 | } while (!(req.op & OP_READVAR && ntohs(req.seq) == 2)); |
| 344 | 353 | ||
| 345 | if (!(req.op & REM_ERROR)) | 354 | if (!(req.op & REM_ERROR)) { |
| 346 | xasprintf(&data, "%s%s", data, req.data); | 355 | xasprintf(&data, "%s%s", data, req.data); |
| 356 | } | ||
| 347 | } while (req.op & REM_MORE); | 357 | } while (req.op & REM_MORE); |
| 348 | 358 | ||
| 349 | if (req.op & REM_ERROR) { | 359 | if (req.op & REM_ERROR) { |
| 350 | if (strstr(getvar, "jitter")) { | 360 | if (strstr(getvar, "jitter")) { |
| 351 | if (verbose) | 361 | if (verbose) { |
| 352 | printf("The command failed. This is usually caused by servers refusing the 'jitter'\nvariable. Restarting with " | 362 | printf("The command failed. This is usually caused by servers refusing the 'jitter'\nvariable. Restarting with " |
| 353 | "'dispersion'...\n"); | 363 | "'dispersion'...\n"); |
| 364 | } | ||
| 354 | getvar = "stratum,offset,dispersion"; | 365 | getvar = "stratum,offset,dispersion"; |
| 355 | i--; | 366 | i--; |
| 356 | continue; | 367 | continue; |
| 357 | } | 368 | } |
| 358 | if (strlen(getvar)) { | 369 | if (strlen(getvar)) { |
| 359 | if (verbose) | 370 | if (verbose) { |
| 360 | printf("Server didn't like dispersion either; will retrieve everything\n"); | 371 | printf("Server didn't like dispersion either; will retrieve everything\n"); |
| 372 | } | ||
| 361 | getvar = ""; | 373 | getvar = ""; |
| 362 | i--; | 374 | i--; |
| 363 | continue; | 375 | continue; |
| 364 | } | 376 | } |
| 365 | } | 377 | } |
| 366 | 378 | ||
| 367 | if (verbose > 1) | 379 | if (verbose > 1) { |
| 368 | printf("Server responded: >>>%s<<<\n", data); | 380 | printf("Server responded: >>>%s<<<\n", data); |
| 381 | } | ||
| 369 | 382 | ||
| 370 | double tmp_offset = 0; | 383 | double tmp_offset = 0; |
| 371 | char *value; | 384 | char *value; |
| 372 | char *nptr; | 385 | char *nptr; |
| 373 | /* get the offset */ | 386 | /* get the offset */ |
| 374 | if (verbose) | 387 | if (verbose) { |
| 375 | printf("parsing offset from peer %.2x: ", ntohs(peers[i].assoc)); | 388 | printf("parsing offset from peer %.2x: ", ntohs(peers[i].assoc)); |
| 389 | } | ||
| 376 | 390 | ||
| 377 | value = np_extract_ntpvar(data, "offset"); | 391 | value = np_extract_ntpvar(data, "offset"); |
| 378 | nptr = NULL; | 392 | nptr = NULL; |
| 379 | /* Convert the value if we have one */ | 393 | /* Convert the value if we have one */ |
| 380 | if (value != NULL) | 394 | if (value != NULL) { |
| 381 | tmp_offset = strtod(value, &nptr) / 1000; | 395 | tmp_offset = strtod(value, &nptr) / 1000; |
| 396 | } | ||
| 382 | /* If value is null or no conversion was performed */ | 397 | /* If value is null or no conversion was performed */ |
| 383 | if (value == NULL || value == nptr) { | 398 | if (value == NULL || value == nptr) { |
| 384 | if (verbose) | 399 | if (verbose) { |
| 385 | printf("error: unable to read server offset response.\n"); | 400 | printf("error: unable to read server offset response.\n"); |
| 401 | } | ||
| 386 | } else { | 402 | } else { |
| 387 | if (verbose) | 403 | if (verbose) { |
| 388 | printf("%.10g\n", tmp_offset); | 404 | printf("%.10g\n", tmp_offset); |
| 405 | } | ||
| 389 | if (*offset_result == STATE_UNKNOWN || fabs(tmp_offset) < fabs(*offset)) { | 406 | if (*offset_result == STATE_UNKNOWN || fabs(tmp_offset) < fabs(*offset)) { |
| 390 | *offset = tmp_offset; | 407 | *offset = tmp_offset; |
| 391 | *offset_result = STATE_OK; | 408 | *offset_result = STATE_OK; |
| @@ -404,12 +421,14 @@ int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum | |||
| 404 | value = np_extract_ntpvar(data, strstr(getvar, "dispersion") != NULL ? "dispersion" : "jitter"); | 421 | value = np_extract_ntpvar(data, strstr(getvar, "dispersion") != NULL ? "dispersion" : "jitter"); |
| 405 | nptr = NULL; | 422 | nptr = NULL; |
| 406 | /* Convert the value if we have one */ | 423 | /* Convert the value if we have one */ |
| 407 | if (value != NULL) | 424 | if (value != NULL) { |
| 408 | *jitter = strtod(value, &nptr); | 425 | *jitter = strtod(value, &nptr); |
| 426 | } | ||
| 409 | /* If value is null or no conversion was performed */ | 427 | /* If value is null or no conversion was performed */ |
| 410 | if (value == NULL || value == nptr) { | 428 | if (value == NULL || value == nptr) { |
| 411 | if (verbose) | 429 | if (verbose) { |
| 412 | printf("error: unable to read server jitter/dispersion response.\n"); | 430 | printf("error: unable to read server jitter/dispersion response.\n"); |
| 431 | } | ||
| 413 | *jitter = -1; | 432 | *jitter = -1; |
| 414 | } else if (verbose) { | 433 | } else if (verbose) { |
| 415 | printf("%.10g\n", *jitter); | 434 | printf("%.10g\n", *jitter); |
| @@ -424,23 +443,27 @@ int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum | |||
| 424 | value = np_extract_ntpvar(data, "stratum"); | 443 | value = np_extract_ntpvar(data, "stratum"); |
| 425 | nptr = NULL; | 444 | nptr = NULL; |
| 426 | /* Convert the value if we have one */ | 445 | /* Convert the value if we have one */ |
| 427 | if (value != NULL) | 446 | if (value != NULL) { |
| 428 | *stratum = strtol(value, &nptr, 10); | 447 | *stratum = strtol(value, &nptr, 10); |
| 448 | } | ||
| 429 | if (value == NULL || value == nptr) { | 449 | if (value == NULL || value == nptr) { |
| 430 | if (verbose) | 450 | if (verbose) { |
| 431 | printf("error: unable to read server stratum response.\n"); | 451 | printf("error: unable to read server stratum response.\n"); |
| 452 | } | ||
| 432 | *stratum = -1; | 453 | *stratum = -1; |
| 433 | } else { | 454 | } else { |
| 434 | if (verbose) | 455 | if (verbose) { |
| 435 | printf("%i\n", *stratum); | 456 | printf("%i\n", *stratum); |
| 457 | } | ||
| 436 | } | 458 | } |
| 437 | } | 459 | } |
| 438 | } /* if (PEER_SEL(peers[i].status) >= min_peer_sel) */ | 460 | } /* if (PEER_SEL(peers[i].status) >= min_peer_sel) */ |
| 439 | } /* for (i = 0; i < npeers; i++) */ | 461 | } /* for (i = 0; i < npeers; i++) */ |
| 440 | 462 | ||
| 441 | close(conn); | 463 | close(conn); |
| 442 | if (peers != NULL) | 464 | if (peers != NULL) { |
| 443 | free(peers); | 465 | free(peers); |
| 466 | } | ||
| 444 | 467 | ||
| 445 | return status; | 468 | return status; |
| 446 | } | 469 | } |
| @@ -454,14 +477,16 @@ int process_arguments(int argc, char **argv) { | |||
| 454 | {"twarn", required_argument, 0, 'm'}, {"tcrit", required_argument, 0, 'n'}, {"timeout", required_argument, 0, 't'}, | 477 | {"twarn", required_argument, 0, 'm'}, {"tcrit", required_argument, 0, 'n'}, {"timeout", required_argument, 0, 't'}, |
| 455 | {"hostname", required_argument, 0, 'H'}, {"port", required_argument, 0, 'p'}, {0, 0, 0, 0}}; | 478 | {"hostname", required_argument, 0, 'H'}, {"port", required_argument, 0, 'p'}, {0, 0, 0, 0}}; |
| 456 | 479 | ||
| 457 | if (argc < 2) | 480 | if (argc < 2) { |
| 458 | usage("\n"); | 481 | usage("\n"); |
| 482 | } | ||
| 459 | 483 | ||
| 460 | while (true) { | 484 | while (true) { |
| 461 | int option = 0; | 485 | int option = 0; |
| 462 | int option_char = getopt_long(argc, argv, "Vhv46qw:c:W:C:j:k:m:n:t:H:p:", longopts, &option); | 486 | int option_char = getopt_long(argc, argv, "Vhv46qw:c:W:C:j:k:m:n:t:H:p:", longopts, &option); |
| 463 | if (option_char == -1 || option_char == EOF || option_char == 1) | 487 | if (option_char == -1 || option_char == EOF || option_char == 1) { |
| 464 | break; | 488 | break; |
| 489 | } | ||
| 465 | 490 | ||
| 466 | switch (option_char) { | 491 | switch (option_char) { |
| 467 | case 'h': | 492 | case 'h': |
| @@ -509,8 +534,9 @@ int process_arguments(int argc, char **argv) { | |||
| 509 | tcrit = optarg; | 534 | tcrit = optarg; |
| 510 | break; | 535 | break; |
| 511 | case 'H': | 536 | case 'H': |
| 512 | if (!is_host(optarg)) | 537 | if (!is_host(optarg)) { |
| 513 | usage2(_("Invalid hostname/address"), optarg); | 538 | usage2(_("Invalid hostname/address"), optarg); |
| 539 | } | ||
| 514 | server_address = strdup(optarg); | 540 | server_address = strdup(optarg); |
| 515 | break; | 541 | break; |
| 516 | case 'p': | 542 | case 'p': |
| @@ -571,8 +597,9 @@ int main(int argc, char *argv[]) { | |||
| 571 | /* Parse extra opts if any */ | 597 | /* Parse extra opts if any */ |
| 572 | argv = np_extra_opts(&argc, argv, progname); | 598 | argv = np_extra_opts(&argc, argv, progname); |
| 573 | 599 | ||
| 574 | if (process_arguments(argc, argv) == ERROR) | 600 | if (process_arguments(argc, argv) == ERROR) { |
| 575 | usage4(_("Could not parse arguments")); | 601 | usage4(_("Could not parse arguments")); |
| 602 | } | ||
| 576 | 603 | ||
| 577 | set_thresholds(&offset_thresholds, owarn, ocrit); | 604 | set_thresholds(&offset_thresholds, owarn, ocrit); |
| 578 | set_thresholds(&jitter_thresholds, jwarn, jcrit); | 605 | set_thresholds(&jitter_thresholds, jwarn, jcrit); |
| @@ -598,8 +625,9 @@ int main(int argc, char *argv[]) { | |||
| 598 | result = (quiet ? STATE_UNKNOWN : STATE_CRITICAL); | 625 | result = (quiet ? STATE_UNKNOWN : STATE_CRITICAL); |
| 599 | } else { | 626 | } else { |
| 600 | /* Be quiet if there's no candidates either */ | 627 | /* Be quiet if there's no candidates either */ |
| 601 | if (quiet && result == STATE_WARNING) | 628 | if (quiet && result == STATE_WARNING) { |
| 602 | result = STATE_UNKNOWN; | 629 | result = STATE_UNKNOWN; |
| 630 | } | ||
| 603 | result = max_state_alt(result, get_status(fabs(offset), offset_thresholds)); | 631 | result = max_state_alt(result, get_status(fabs(offset), offset_thresholds)); |
| 604 | } | 632 | } |
| 605 | 633 | ||
| @@ -641,10 +669,11 @@ int main(int argc, char *argv[]) { | |||
| 641 | xasprintf(&result_line, _("NTP UNKNOWN:")); | 669 | xasprintf(&result_line, _("NTP UNKNOWN:")); |
| 642 | break; | 670 | break; |
| 643 | } | 671 | } |
| 644 | if (!syncsource_found) | 672 | if (!syncsource_found) { |
| 645 | xasprintf(&result_line, "%s %s,", result_line, _("Server not synchronized")); | 673 | xasprintf(&result_line, "%s %s,", result_line, _("Server not synchronized")); |
| 646 | else if (li_alarm) | 674 | } else if (li_alarm) { |
| 647 | xasprintf(&result_line, "%s %s,", result_line, _("Server has the LI_ALARM bit set")); | 675 | xasprintf(&result_line, "%s %s,", result_line, _("Server has the LI_ALARM bit set")); |
| 676 | } | ||
| 648 | 677 | ||
| 649 | char *perfdata_line; | 678 | char *perfdata_line; |
| 650 | if (offset_result == STATE_UNKNOWN) { | 679 | if (offset_result == STATE_UNKNOWN) { |
| @@ -691,8 +720,9 @@ int main(int argc, char *argv[]) { | |||
| 691 | } | 720 | } |
| 692 | printf("%s|%s\n", result_line, perfdata_line); | 721 | printf("%s|%s\n", result_line, perfdata_line); |
| 693 | 722 | ||
| 694 | if (server_address != NULL) | 723 | if (server_address != NULL) { |
| 695 | free(server_address); | 724 | free(server_address); |
| 725 | } | ||
| 696 | return result; | 726 | return result; |
| 697 | } | 727 | } |
| 698 | 728 | ||
