diff options
| -rw-r--r-- | plugins-root/check_icmp.c | 294 |
1 files changed, 188 insertions, 106 deletions
diff --git a/plugins-root/check_icmp.c b/plugins-root/check_icmp.c index 960ab8f1..ea17b3a8 100644 --- a/plugins-root/check_icmp.c +++ b/plugins-root/check_icmp.c | |||
| @@ -272,8 +272,9 @@ static void crash(const char *fmt, ...) { | |||
| 272 | vprintf(fmt, ap); | 272 | vprintf(fmt, ap); |
| 273 | va_end(ap); | 273 | va_end(ap); |
| 274 | 274 | ||
| 275 | if (errno) | 275 | if (errno) { |
| 276 | printf(": %s", strerror(errno)); | 276 | printf(": %s", strerror(errno)); |
| 277 | } | ||
| 277 | puts(""); | 278 | puts(""); |
| 278 | 279 | ||
| 279 | exit(3); | 280 | exit(3); |
| @@ -282,8 +283,9 @@ static void crash(const char *fmt, ...) { | |||
| 282 | static const char *get_icmp_error_msg(unsigned char icmp_type, unsigned char icmp_code) { | 283 | static const char *get_icmp_error_msg(unsigned char icmp_type, unsigned char icmp_code) { |
| 283 | const char *msg = "unreachable"; | 284 | const char *msg = "unreachable"; |
| 284 | 285 | ||
| 285 | if (debug > 1) | 286 | if (debug > 1) { |
| 286 | printf("get_icmp_error_msg(%u, %u)\n", icmp_type, icmp_code); | 287 | printf("get_icmp_error_msg(%u, %u)\n", icmp_type, icmp_code); |
| 288 | } | ||
| 287 | switch (icmp_type) { | 289 | switch (icmp_type) { |
| 288 | case ICMP_UNREACH: | 290 | case ICMP_UNREACH: |
| 289 | switch (icmp_code) { | 291 | switch (icmp_code) { |
| @@ -392,8 +394,9 @@ static int handle_random_icmp(unsigned char *packet, struct sockaddr_storage *ad | |||
| 392 | return 0; | 394 | return 0; |
| 393 | } | 395 | } |
| 394 | 396 | ||
| 395 | if (debug) | 397 | if (debug) { |
| 396 | printf("handle_random_icmp(%p, %p)\n", (void *)&p, (void *)addr); | 398 | printf("handle_random_icmp(%p, %p)\n", (void *)&p, (void *)addr); |
| 399 | } | ||
| 397 | 400 | ||
| 398 | /* only handle a few types, since others can't possibly be replies to | 401 | /* only handle a few types, since others can't possibly be replies to |
| 399 | * us in a sane network (if it is anyway, it will be counted as lost | 402 | * us in a sane network (if it is anyway, it will be counted as lost |
| @@ -413,8 +416,9 @@ static int handle_random_icmp(unsigned char *packet, struct sockaddr_storage *ad | |||
| 413 | * to RFC 792). If it isn't, just ignore it */ | 416 | * to RFC 792). If it isn't, just ignore it */ |
| 414 | memcpy(&sent_icmp, packet + 28, sizeof(sent_icmp)); | 417 | memcpy(&sent_icmp, packet + 28, sizeof(sent_icmp)); |
| 415 | if (sent_icmp.icmp_type != ICMP_ECHO || ntohs(sent_icmp.icmp_id) != pid || ntohs(sent_icmp.icmp_seq) >= targets * packets) { | 418 | if (sent_icmp.icmp_type != ICMP_ECHO || ntohs(sent_icmp.icmp_id) != pid || ntohs(sent_icmp.icmp_seq) >= targets * packets) { |
| 416 | if (debug) | 419 | if (debug) { |
| 417 | printf("Packet is no response to a packet we sent\n"); | 420 | printf("Packet is no response to a packet we sent\n"); |
| 421 | } | ||
| 418 | return 0; | 422 | return 0; |
| 419 | } | 423 | } |
| 420 | 424 | ||
| @@ -429,8 +433,9 @@ static int handle_random_icmp(unsigned char *packet, struct sockaddr_storage *ad | |||
| 429 | icmp_lost++; | 433 | icmp_lost++; |
| 430 | host->icmp_lost++; | 434 | host->icmp_lost++; |
| 431 | /* don't spend time on lost hosts any more */ | 435 | /* don't spend time on lost hosts any more */ |
| 432 | if (host->flags & FLAG_LOST_CAUSE) | 436 | if (host->flags & FLAG_LOST_CAUSE) { |
| 433 | return 0; | 437 | return 0; |
| 438 | } | ||
| 434 | 439 | ||
| 435 | /* source quench means we're sending too fast, so increase the | 440 | /* source quench means we're sending too fast, so increase the |
| 436 | * interval and mark this packet lost */ | 441 | * interval and mark this packet lost */ |
| @@ -488,10 +493,11 @@ int main(int argc, char **argv) { | |||
| 488 | /* get calling name the old-fashioned way for portability instead | 493 | /* get calling name the old-fashioned way for portability instead |
| 489 | * of relying on the glibc-ism __progname */ | 494 | * of relying on the glibc-ism __progname */ |
| 490 | ptr = strrchr(argv[0], '/'); | 495 | ptr = strrchr(argv[0], '/'); |
| 491 | if (ptr) | 496 | if (ptr) { |
| 492 | progname = &ptr[1]; | 497 | progname = &ptr[1]; |
| 493 | else | 498 | } else { |
| 494 | progname = argv[0]; | 499 | progname = argv[0]; |
| 500 | } | ||
| 495 | 501 | ||
| 496 | /* now set defaults. Use progname to set them initially (allows for | 502 | /* now set defaults. Use progname to set them initially (allows for |
| 497 | * superfast check_host program when target host is up */ | 503 | * superfast check_host program when target host is up */ |
| @@ -534,10 +540,12 @@ int main(int argc, char **argv) { | |||
| 534 | 540 | ||
| 535 | /* support "--help" and "--version" */ | 541 | /* support "--help" and "--version" */ |
| 536 | if (argc == 2) { | 542 | if (argc == 2) { |
| 537 | if (!strcmp(argv[1], "--help")) | 543 | if (!strcmp(argv[1], "--help")) { |
| 538 | strcpy(argv[1], "-h"); | 544 | strcpy(argv[1], "-h"); |
| 539 | if (!strcmp(argv[1], "--version")) | 545 | } |
| 546 | if (!strcmp(argv[1], "--version")) { | ||
| 540 | strcpy(argv[1], "-V"); | 547 | strcpy(argv[1], "-V"); |
| 548 | } | ||
| 541 | } | 549 | } |
| 542 | 550 | ||
| 543 | /* Parse protocol arguments first */ | 551 | /* Parse protocol arguments first */ |
| @@ -545,14 +553,16 @@ int main(int argc, char **argv) { | |||
| 545 | while ((arg = getopt(argc, argv, opts_str)) != EOF) { | 553 | while ((arg = getopt(argc, argv, opts_str)) != EOF) { |
| 546 | switch (arg) { | 554 | switch (arg) { |
| 547 | case '4': | 555 | case '4': |
| 548 | if (address_family != -1) | 556 | if (address_family != -1) { |
| 549 | crash("Multiple protocol versions not supported"); | 557 | crash("Multiple protocol versions not supported"); |
| 558 | } | ||
| 550 | address_family = AF_INET; | 559 | address_family = AF_INET; |
| 551 | break; | 560 | break; |
| 552 | case '6': | 561 | case '6': |
| 553 | #ifdef USE_IPV6 | 562 | #ifdef USE_IPV6 |
| 554 | if (address_family != -1) | 563 | if (address_family != -1) { |
| 555 | crash("Multiple protocol versions not supported"); | 564 | crash("Multiple protocol versions not supported"); |
| 565 | } | ||
| 556 | address_family = AF_INET6; | 566 | address_family = AF_INET6; |
| 557 | #else | 567 | #else |
| 558 | usage(_("IPv6 support not available\n")); | 568 | usage(_("IPv6 support not available\n")); |
| @@ -579,9 +589,10 @@ int main(int argc, char **argv) { | |||
| 579 | if (size >= (sizeof(struct icmp) + sizeof(struct icmp_ping_data)) && size < MAX_PING_DATA) { | 589 | if (size >= (sizeof(struct icmp) + sizeof(struct icmp_ping_data)) && size < MAX_PING_DATA) { |
| 580 | icmp_data_size = size; | 590 | icmp_data_size = size; |
| 581 | icmp_pkt_size = size + ICMP_MINLEN; | 591 | icmp_pkt_size = size + ICMP_MINLEN; |
| 582 | } else | 592 | } else { |
| 583 | usage_va("ICMP data length must be between: %lu and %lu", sizeof(struct icmp) + sizeof(struct icmp_ping_data), | 593 | usage_va("ICMP data length must be between: %lu and %lu", sizeof(struct icmp) + sizeof(struct icmp_ping_data), |
| 584 | MAX_PING_DATA - 1); | 594 | MAX_PING_DATA - 1); |
| 595 | } | ||
| 585 | break; | 596 | break; |
| 586 | case 'i': | 597 | case 'i': |
| 587 | pkt_interval = get_timevar(optarg); | 598 | pkt_interval = get_timevar(optarg); |
| @@ -601,8 +612,9 @@ int main(int argc, char **argv) { | |||
| 601 | break; | 612 | break; |
| 602 | case 't': | 613 | case 't': |
| 603 | timeout = strtoul(optarg, NULL, 0); | 614 | timeout = strtoul(optarg, NULL, 0); |
| 604 | if (!timeout) | 615 | if (!timeout) { |
| 605 | timeout = 10; | 616 | timeout = 10; |
| 617 | } | ||
| 606 | break; | 618 | break; |
| 607 | case 'H': | 619 | case 'H': |
| 608 | add_target(optarg); | 620 | add_target(optarg); |
| @@ -709,18 +721,22 @@ int main(int argc, char **argv) { | |||
| 709 | default: | 721 | default: |
| 710 | crash("Address family not supported"); | 722 | crash("Address family not supported"); |
| 711 | } | 723 | } |
| 712 | if ((icmp_sock = socket(address_family, SOCK_RAW, icmp_proto)) != -1) | 724 | if ((icmp_sock = socket(address_family, SOCK_RAW, icmp_proto)) != -1) { |
| 713 | sockets |= HAVE_ICMP; | 725 | sockets |= HAVE_ICMP; |
| 714 | else | 726 | } else { |
| 715 | icmp_sockerrno = errno; | 727 | icmp_sockerrno = errno; |
| 728 | } | ||
| 716 | 729 | ||
| 717 | if (source_ip) | 730 | if (source_ip) { |
| 718 | set_source_ip(source_ip); | 731 | set_source_ip(source_ip); |
| 732 | } | ||
| 719 | 733 | ||
| 720 | #ifdef SO_TIMESTAMP | 734 | #ifdef SO_TIMESTAMP |
| 721 | if (setsockopt(icmp_sock, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on))) | 735 | if (setsockopt(icmp_sock, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on))) { |
| 722 | if (debug) | 736 | if (debug) { |
| 723 | printf("Warning: no SO_TIMESTAMP support\n"); | 737 | printf("Warning: no SO_TIMESTAMP support\n"); |
| 738 | } | ||
| 739 | } | ||
| 724 | #endif // SO_TIMESTAMP | 740 | #endif // SO_TIMESTAMP |
| 725 | 741 | ||
| 726 | /* now drop privileges (no effect if not setsuid or geteuid() == 0) */ | 742 | /* now drop privileges (no effect if not setsuid or geteuid() == 0) */ |
| @@ -746,16 +762,18 @@ int main(int argc, char **argv) { | |||
| 746 | /* return -1; */ | 762 | /* return -1; */ |
| 747 | /* } */ | 763 | /* } */ |
| 748 | } | 764 | } |
| 749 | if (!ttl) | 765 | if (!ttl) { |
| 750 | ttl = 64; | 766 | ttl = 64; |
| 767 | } | ||
| 751 | 768 | ||
| 752 | if (icmp_sock) { | 769 | if (icmp_sock) { |
| 753 | result = setsockopt(icmp_sock, SOL_IP, IP_TTL, &ttl, sizeof(ttl)); | 770 | result = setsockopt(icmp_sock, SOL_IP, IP_TTL, &ttl, sizeof(ttl)); |
| 754 | if (debug) { | 771 | if (debug) { |
| 755 | if (result == -1) | 772 | if (result == -1) { |
| 756 | printf("setsockopt failed\n"); | 773 | printf("setsockopt failed\n"); |
| 757 | else | 774 | } else { |
| 758 | printf("ttl set to %u\n", ttl); | 775 | printf("ttl set to %u\n", ttl); |
| 776 | } | ||
| 759 | } | 777 | } |
| 760 | } | 778 | } |
| 761 | 779 | ||
| @@ -763,18 +781,24 @@ int main(int argc, char **argv) { | |||
| 763 | * (nothing will break if they do), but some anal plugin maintainer | 781 | * (nothing will break if they do), but some anal plugin maintainer |
| 764 | * will probably add some printf() thing here later, so it might be | 782 | * will probably add some printf() thing here later, so it might be |
| 765 | * best to at least show them where to do it. ;) */ | 783 | * best to at least show them where to do it. ;) */ |
| 766 | if (warn.pl > crit.pl) | 784 | if (warn.pl > crit.pl) { |
| 767 | warn.pl = crit.pl; | 785 | warn.pl = crit.pl; |
| 768 | if (warn.rta > crit.rta) | 786 | } |
| 787 | if (warn.rta > crit.rta) { | ||
| 769 | warn.rta = crit.rta; | 788 | warn.rta = crit.rta; |
| 770 | if (warn_down > crit_down) | 789 | } |
| 790 | if (warn_down > crit_down) { | ||
| 771 | crit_down = warn_down; | 791 | crit_down = warn_down; |
| 772 | if (warn.jitter > crit.jitter) | 792 | } |
| 793 | if (warn.jitter > crit.jitter) { | ||
| 773 | crit.jitter = warn.jitter; | 794 | crit.jitter = warn.jitter; |
| 774 | if (warn.mos < crit.mos) | 795 | } |
| 796 | if (warn.mos < crit.mos) { | ||
| 775 | warn.mos = crit.mos; | 797 | warn.mos = crit.mos; |
| 776 | if (warn.score < crit.score) | 798 | } |
| 799 | if (warn.score < crit.score) { | ||
| 777 | warn.score = crit.score; | 800 | warn.score = crit.score; |
| 801 | } | ||
| 778 | 802 | ||
| 779 | #ifdef HAVE_SIGACTION | 803 | #ifdef HAVE_SIGACTION |
| 780 | sig_action.sa_sigaction = NULL; | 804 | sig_action.sa_sigaction = NULL; |
| @@ -791,8 +815,9 @@ int main(int argc, char **argv) { | |||
| 791 | signal(SIGTERM, finish); | 815 | signal(SIGTERM, finish); |
| 792 | signal(SIGALRM, finish); | 816 | signal(SIGALRM, finish); |
| 793 | #endif /* HAVE_SIGACTION */ | 817 | #endif /* HAVE_SIGACTION */ |
| 794 | if (debug) | 818 | if (debug) { |
| 795 | printf("Setting alarm timeout to %u seconds\n", timeout); | 819 | printf("Setting alarm timeout to %u seconds\n", timeout); |
| 820 | } | ||
| 796 | alarm(timeout); | 821 | alarm(timeout); |
| 797 | 822 | ||
| 798 | /* make sure we don't wait any longer than necessary */ | 823 | /* make sure we don't wait any longer than necessary */ |
| @@ -863,11 +888,13 @@ static void run_checks(void) { | |||
| 863 | for (i = 0; i < packets; i++) { | 888 | for (i = 0; i < packets; i++) { |
| 864 | for (t = 0; t < targets; t++) { | 889 | for (t = 0; t < targets; t++) { |
| 865 | /* don't send useless packets */ | 890 | /* don't send useless packets */ |
| 866 | if (!targets_alive) | 891 | if (!targets_alive) { |
| 867 | finish(0); | 892 | finish(0); |
| 893 | } | ||
| 868 | if (table[t]->flags & FLAG_LOST_CAUSE) { | 894 | if (table[t]->flags & FLAG_LOST_CAUSE) { |
| 869 | if (debug) | 895 | if (debug) { |
| 870 | printf("%s is a lost cause. not sending any more\n", table[t]->name); | 896 | printf("%s is a lost cause. not sending any more\n", table[t]->name); |
| 897 | } | ||
| 871 | continue; | 898 | continue; |
| 872 | } | 899 | } |
| 873 | 900 | ||
| @@ -886,15 +913,17 @@ static void run_checks(void) { | |||
| 886 | printf("time_passed: %u final_wait: %u max_completion_time: %llu\n", time_passed, final_wait, max_completion_time); | 913 | printf("time_passed: %u final_wait: %u max_completion_time: %llu\n", time_passed, final_wait, max_completion_time); |
| 887 | } | 914 | } |
| 888 | if (time_passed > max_completion_time) { | 915 | if (time_passed > max_completion_time) { |
| 889 | if (debug) | 916 | if (debug) { |
| 890 | printf("Time passed. Finishing up\n"); | 917 | printf("Time passed. Finishing up\n"); |
| 918 | } | ||
| 891 | finish(0); | 919 | finish(0); |
| 892 | } | 920 | } |
| 893 | 921 | ||
| 894 | /* catch the packets that might come in within the timeframe, but | 922 | /* catch the packets that might come in within the timeframe, but |
| 895 | * haven't yet */ | 923 | * haven't yet */ |
| 896 | if (debug) | 924 | if (debug) { |
| 897 | printf("Waiting for %u micro-seconds (%0.3f msecs)\n", final_wait, (float)final_wait / 1000); | 925 | printf("Waiting for %u micro-seconds (%0.3f msecs)\n", final_wait, (float)final_wait / 1000); |
| 926 | } | ||
| 898 | wait_for_reply(icmp_sock, final_wait); | 927 | wait_for_reply(icmp_sock, final_wait); |
| 899 | } | 928 | } |
| 900 | } | 929 | } |
| @@ -955,8 +984,9 @@ static int wait_for_reply(int sock, u_int t) { | |||
| 955 | continue; /* timeout for this one, so keep trying */ | 984 | continue; /* timeout for this one, so keep trying */ |
| 956 | } | 985 | } |
| 957 | if (n < 0) { | 986 | if (n < 0) { |
| 958 | if (debug) | 987 | if (debug) { |
| 959 | printf("recvfrom_wto() returned errors\n"); | 988 | printf("recvfrom_wto() returned errors\n"); |
| 989 | } | ||
| 960 | free(packet.buf); | 990 | free(packet.buf); |
| 961 | return n; | 991 | return n; |
| 962 | } | 992 | } |
| @@ -1003,8 +1033,9 @@ static int wait_for_reply(int sock, u_int t) { | |||
| 1003 | ntohs(packet.icp->icmp_seq) >= targets * packets)) || | 1033 | ntohs(packet.icp->icmp_seq) >= targets * packets)) || |
| 1004 | (address_family == PF_INET6 && (ntohs(packet.icp6->icmp6_id) != pid || packet.icp6->icmp6_type != ICMP6_ECHO_REPLY || | 1034 | (address_family == PF_INET6 && (ntohs(packet.icp6->icmp6_id) != pid || packet.icp6->icmp6_type != ICMP6_ECHO_REPLY || |
| 1005 | ntohs(packet.icp6->icmp6_seq) >= targets * packets))) { | 1035 | ntohs(packet.icp6->icmp6_seq) >= targets * packets))) { |
| 1006 | if (debug > 2) | 1036 | if (debug > 2) { |
| 1007 | printf("not a proper ICMP_ECHOREPLY\n"); | 1037 | printf("not a proper ICMP_ECHOREPLY\n"); |
| 1038 | } | ||
| 1008 | handle_random_icmp(buf + hlen, &resp_addr); | 1039 | handle_random_icmp(buf + hlen, &resp_addr); |
| 1009 | continue; | 1040 | continue; |
| 1010 | } | 1041 | } |
| @@ -1012,15 +1043,17 @@ static int wait_for_reply(int sock, u_int t) { | |||
| 1012 | /* this is indeed a valid response */ | 1043 | /* this is indeed a valid response */ |
| 1013 | if (address_family == PF_INET) { | 1044 | if (address_family == PF_INET) { |
| 1014 | memcpy(&data, packet.icp->icmp_data, sizeof(data)); | 1045 | memcpy(&data, packet.icp->icmp_data, sizeof(data)); |
| 1015 | if (debug > 2) | 1046 | if (debug > 2) { |
| 1016 | printf("ICMP echo-reply of len %lu, id %u, seq %u, cksum 0x%X\n", (unsigned long)sizeof(data), ntohs(packet.icp->icmp_id), | 1047 | printf("ICMP echo-reply of len %lu, id %u, seq %u, cksum 0x%X\n", (unsigned long)sizeof(data), ntohs(packet.icp->icmp_id), |
| 1017 | ntohs(packet.icp->icmp_seq), packet.icp->icmp_cksum); | 1048 | ntohs(packet.icp->icmp_seq), packet.icp->icmp_cksum); |
| 1049 | } | ||
| 1018 | host = table[ntohs(packet.icp->icmp_seq) / packets]; | 1050 | host = table[ntohs(packet.icp->icmp_seq) / packets]; |
| 1019 | } else { | 1051 | } else { |
| 1020 | memcpy(&data, &packet.icp6->icmp6_dataun.icmp6_un_data8[4], sizeof(data)); | 1052 | memcpy(&data, &packet.icp6->icmp6_dataun.icmp6_un_data8[4], sizeof(data)); |
| 1021 | if (debug > 2) | 1053 | if (debug > 2) { |
| 1022 | printf("ICMP echo-reply of len %lu, id %u, seq %u, cksum 0x%X\n", (unsigned long)sizeof(data), ntohs(packet.icp6->icmp6_id), | 1054 | printf("ICMP echo-reply of len %lu, id %u, seq %u, cksum 0x%X\n", (unsigned long)sizeof(data), ntohs(packet.icp6->icmp6_id), |
| 1023 | ntohs(packet.icp6->icmp6_seq), packet.icp6->icmp6_cksum); | 1055 | ntohs(packet.icp6->icmp6_seq), packet.icp6->icmp6_cksum); |
| 1056 | } | ||
| 1024 | host = table[ntohs(packet.icp6->icmp6_seq) / packets]; | 1057 | host = table[ntohs(packet.icp6->icmp6_seq) / packets]; |
| 1025 | } | 1058 | } |
| 1026 | 1059 | ||
| @@ -1051,8 +1084,9 @@ static int wait_for_reply(int sock, u_int t) { | |||
| 1051 | } | 1084 | } |
| 1052 | 1085 | ||
| 1053 | /* Check if packets in order */ | 1086 | /* Check if packets in order */ |
| 1054 | if (host->last_icmp_seq >= packet.icp->icmp_seq) | 1087 | if (host->last_icmp_seq >= packet.icp->icmp_seq) { |
| 1055 | host->order_status = STATE_CRITICAL; | 1088 | host->order_status = STATE_CRITICAL; |
| 1089 | } | ||
| 1056 | } | 1090 | } |
| 1057 | host->last_tdiff = tdiff; | 1091 | host->last_tdiff = tdiff; |
| 1058 | 1092 | ||
| @@ -1061,10 +1095,12 @@ static int wait_for_reply(int sock, u_int t) { | |||
| 1061 | host->time_waited += tdiff; | 1095 | host->time_waited += tdiff; |
| 1062 | host->icmp_recv++; | 1096 | host->icmp_recv++; |
| 1063 | icmp_recv++; | 1097 | icmp_recv++; |
| 1064 | if (tdiff > (unsigned int)host->rtmax) | 1098 | if (tdiff > (unsigned int)host->rtmax) { |
| 1065 | host->rtmax = tdiff; | 1099 | host->rtmax = tdiff; |
| 1066 | if (tdiff < (unsigned int)host->rtmin) | 1100 | } |
| 1101 | if (tdiff < (unsigned int)host->rtmin) { | ||
| 1067 | host->rtmin = tdiff; | 1102 | host->rtmin = tdiff; |
| 1103 | } | ||
| 1068 | 1104 | ||
| 1069 | if (debug) { | 1105 | if (debug) { |
| 1070 | char address[INET6_ADDRSTRLEN]; | 1106 | char address[INET6_ADDRSTRLEN]; |
| @@ -1142,9 +1178,10 @@ static int send_icmp_ping(int sock, struct rta_host *host) { | |||
| 1142 | icp->icmp_seq = htons(host->id++); | 1178 | icp->icmp_seq = htons(host->id++); |
| 1143 | icp->icmp_cksum = icmp_checksum((uint16_t *)buf, (size_t)icmp_pkt_size); | 1179 | icp->icmp_cksum = icmp_checksum((uint16_t *)buf, (size_t)icmp_pkt_size); |
| 1144 | 1180 | ||
| 1145 | if (debug > 2) | 1181 | if (debug > 2) { |
| 1146 | printf("Sending ICMP echo-request of len %lu, id %u, seq %u, cksum 0x%X to host %s\n", (unsigned long)sizeof(data), | 1182 | printf("Sending ICMP echo-request of len %lu, id %u, seq %u, cksum 0x%X to host %s\n", (unsigned long)sizeof(data), |
| 1147 | ntohs(icp->icmp_id), ntohs(icp->icmp_seq), icp->icmp_cksum, host->name); | 1183 | ntohs(icp->icmp_id), ntohs(icp->icmp_seq), icp->icmp_cksum, host->name); |
| 1184 | } | ||
| 1148 | } else { | 1185 | } else { |
| 1149 | struct icmp6_hdr *icp6 = (struct icmp6_hdr *)buf; | 1186 | struct icmp6_hdr *icp6 = (struct icmp6_hdr *)buf; |
| 1150 | addrlen = sizeof(struct sockaddr_in6); | 1187 | addrlen = sizeof(struct sockaddr_in6); |
| @@ -1216,8 +1253,9 @@ static int recvfrom_wto(int sock, void *buf, unsigned int len, struct sockaddr * | |||
| 1216 | #endif | 1253 | #endif |
| 1217 | 1254 | ||
| 1218 | if (!*timo) { | 1255 | if (!*timo) { |
| 1219 | if (debug) | 1256 | if (debug) { |
| 1220 | printf("*timo is not\n"); | 1257 | printf("*timo is not\n"); |
| 1258 | } | ||
| 1221 | return 0; | 1259 | return 0; |
| 1222 | } | 1260 | } |
| 1223 | 1261 | ||
| @@ -1230,13 +1268,15 @@ static int recvfrom_wto(int sock, void *buf, unsigned int len, struct sockaddr * | |||
| 1230 | errno = 0; | 1268 | errno = 0; |
| 1231 | gettimeofday(&then, &tz); | 1269 | gettimeofday(&then, &tz); |
| 1232 | n = select(sock + 1, &rd, &wr, NULL, &to); | 1270 | n = select(sock + 1, &rd, &wr, NULL, &to); |
| 1233 | if (n < 0) | 1271 | if (n < 0) { |
| 1234 | crash("select() in recvfrom_wto"); | 1272 | crash("select() in recvfrom_wto"); |
| 1273 | } | ||
| 1235 | gettimeofday(&now, &tz); | 1274 | gettimeofday(&now, &tz); |
| 1236 | *timo = get_timevaldiff(&then, &now); | 1275 | *timo = get_timevaldiff(&then, &now); |
| 1237 | 1276 | ||
| 1238 | if (!n) | 1277 | if (!n) { |
| 1239 | return 0; /* timeout */ | 1278 | return 0; /* timeout */ |
| 1279 | } | ||
| 1240 | 1280 | ||
| 1241 | slen = sizeof(struct sockaddr_storage); | 1281 | slen = sizeof(struct sockaddr_storage); |
| 1242 | 1282 | ||
| @@ -1281,15 +1321,19 @@ static void finish(int sig) { | |||
| 1281 | double R; | 1321 | double R; |
| 1282 | 1322 | ||
| 1283 | alarm(0); | 1323 | alarm(0); |
| 1284 | if (debug > 1) | 1324 | if (debug > 1) { |
| 1285 | printf("finish(%d) called\n", sig); | 1325 | printf("finish(%d) called\n", sig); |
| 1326 | } | ||
| 1286 | 1327 | ||
| 1287 | if (icmp_sock != -1) | 1328 | if (icmp_sock != -1) { |
| 1288 | close(icmp_sock); | 1329 | close(icmp_sock); |
| 1289 | if (udp_sock != -1) | 1330 | } |
| 1331 | if (udp_sock != -1) { | ||
| 1290 | close(udp_sock); | 1332 | close(udp_sock); |
| 1291 | if (tcp_sock != -1) | 1333 | } |
| 1334 | if (tcp_sock != -1) { | ||
| 1292 | close(tcp_sock); | 1335 | close(tcp_sock); |
| 1336 | } | ||
| 1293 | 1337 | ||
| 1294 | if (debug) { | 1338 | if (debug) { |
| 1295 | printf("icmp_sent: %u icmp_recv: %u icmp_lost: %u\n", icmp_sent, icmp_recv, icmp_lost); | 1339 | printf("icmp_sent: %u icmp_recv: %u icmp_lost: %u\n", icmp_sent, icmp_recv, icmp_lost); |
| @@ -1310,8 +1354,9 @@ static void finish(int sig) { | |||
| 1310 | rta = 0; | 1354 | rta = 0; |
| 1311 | status = STATE_CRITICAL; | 1355 | status = STATE_CRITICAL; |
| 1312 | /* up the down counter if not already counted */ | 1356 | /* up the down counter if not already counted */ |
| 1313 | if (!(host->flags & FLAG_LOST_CAUSE) && targets_alive) | 1357 | if (!(host->flags & FLAG_LOST_CAUSE) && targets_alive) { |
| 1314 | targets_down++; | 1358 | targets_down++; |
| 1359 | } | ||
| 1315 | } else { | 1360 | } else { |
| 1316 | pl = ((host->icmp_sent - host->icmp_recv) * 100) / host->icmp_sent; | 1361 | pl = ((host->icmp_sent - host->icmp_recv) * 100) / host->icmp_sent; |
| 1317 | rta = (double)host->time_waited / host->icmp_recv; | 1362 | rta = (double)host->time_waited / host->icmp_recv; |
| @@ -1444,26 +1489,30 @@ static void finish(int sig) { | |||
| 1444 | } | 1489 | } |
| 1445 | 1490 | ||
| 1446 | /* this is inevitable */ | 1491 | /* this is inevitable */ |
| 1447 | if (!targets_alive) | 1492 | if (!targets_alive) { |
| 1448 | status = STATE_CRITICAL; | 1493 | status = STATE_CRITICAL; |
| 1494 | } | ||
| 1449 | if (min_hosts_alive > -1) { | 1495 | if (min_hosts_alive > -1) { |
| 1450 | if (hosts_ok >= min_hosts_alive) | 1496 | if (hosts_ok >= min_hosts_alive) { |
| 1451 | status = STATE_OK; | 1497 | status = STATE_OK; |
| 1452 | else if ((hosts_ok + hosts_warn) >= min_hosts_alive) | 1498 | } else if ((hosts_ok + hosts_warn) >= min_hosts_alive) { |
| 1453 | status = STATE_WARNING; | 1499 | status = STATE_WARNING; |
| 1500 | } | ||
| 1454 | } | 1501 | } |
| 1455 | printf("%s - ", status_string[status]); | 1502 | printf("%s - ", status_string[status]); |
| 1456 | 1503 | ||
| 1457 | host = list; | 1504 | host = list; |
| 1458 | while (host) { | 1505 | while (host) { |
| 1459 | 1506 | ||
| 1460 | if (debug) | 1507 | if (debug) { |
| 1461 | puts(""); | 1508 | puts(""); |
| 1509 | } | ||
| 1462 | if (i) { | 1510 | if (i) { |
| 1463 | if (i < targets) | 1511 | if (i < targets) { |
| 1464 | printf(" :: "); | 1512 | printf(" :: "); |
| 1465 | else | 1513 | } else { |
| 1466 | printf("\n"); | 1514 | printf("\n"); |
| 1515 | } | ||
| 1467 | } | 1516 | } |
| 1468 | i++; | 1517 | i++; |
| 1469 | if (!host->icmp_recv) { | 1518 | if (!host->icmp_recv) { |
| @@ -1481,55 +1530,61 @@ static void finish(int sig) { | |||
| 1481 | printf("%s", host->name); | 1530 | printf("%s", host->name); |
| 1482 | /* rta text output */ | 1531 | /* rta text output */ |
| 1483 | if (rta_mode) { | 1532 | if (rta_mode) { |
| 1484 | if (status == STATE_OK) | 1533 | if (status == STATE_OK) { |
| 1485 | printf(" rta %0.3fms", host->rta / 1000); | 1534 | printf(" rta %0.3fms", host->rta / 1000); |
| 1486 | else if (status == STATE_WARNING && host->rta_status == status) | 1535 | } else if (status == STATE_WARNING && host->rta_status == status) { |
| 1487 | printf(" rta %0.3fms > %0.3fms", (float)host->rta / 1000, (float)warn.rta / 1000); | 1536 | printf(" rta %0.3fms > %0.3fms", (float)host->rta / 1000, (float)warn.rta / 1000); |
| 1488 | else if (status == STATE_CRITICAL && host->rta_status == status) | 1537 | } else if (status == STATE_CRITICAL && host->rta_status == status) { |
| 1489 | printf(" rta %0.3fms > %0.3fms", (float)host->rta / 1000, (float)crit.rta / 1000); | 1538 | printf(" rta %0.3fms > %0.3fms", (float)host->rta / 1000, (float)crit.rta / 1000); |
| 1539 | } | ||
| 1490 | } | 1540 | } |
| 1491 | /* pl text output */ | 1541 | /* pl text output */ |
| 1492 | if (pl_mode) { | 1542 | if (pl_mode) { |
| 1493 | if (status == STATE_OK) | 1543 | if (status == STATE_OK) { |
| 1494 | printf(" lost %u%%", host->pl); | 1544 | printf(" lost %u%%", host->pl); |
| 1495 | else if (status == STATE_WARNING && host->pl_status == status) | 1545 | } else if (status == STATE_WARNING && host->pl_status == status) { |
| 1496 | printf(" lost %u%% > %u%%", host->pl, warn.pl); | 1546 | printf(" lost %u%% > %u%%", host->pl, warn.pl); |
| 1497 | else if (status == STATE_CRITICAL && host->pl_status == status) | 1547 | } else if (status == STATE_CRITICAL && host->pl_status == status) { |
| 1498 | printf(" lost %u%% > %u%%", host->pl, crit.pl); | 1548 | printf(" lost %u%% > %u%%", host->pl, crit.pl); |
| 1549 | } | ||
| 1499 | } | 1550 | } |
| 1500 | /* jitter text output */ | 1551 | /* jitter text output */ |
| 1501 | if (jitter_mode) { | 1552 | if (jitter_mode) { |
| 1502 | if (status == STATE_OK) | 1553 | if (status == STATE_OK) { |
| 1503 | printf(" jitter %0.3fms", (float)host->jitter); | 1554 | printf(" jitter %0.3fms", (float)host->jitter); |
| 1504 | else if (status == STATE_WARNING && host->jitter_status == status) | 1555 | } else if (status == STATE_WARNING && host->jitter_status == status) { |
| 1505 | printf(" jitter %0.3fms > %0.3fms", (float)host->jitter, warn.jitter); | 1556 | printf(" jitter %0.3fms > %0.3fms", (float)host->jitter, warn.jitter); |
| 1506 | else if (status == STATE_CRITICAL && host->jitter_status == status) | 1557 | } else if (status == STATE_CRITICAL && host->jitter_status == status) { |
| 1507 | printf(" jitter %0.3fms > %0.3fms", (float)host->jitter, crit.jitter); | 1558 | printf(" jitter %0.3fms > %0.3fms", (float)host->jitter, crit.jitter); |
| 1559 | } | ||
| 1508 | } | 1560 | } |
| 1509 | /* mos text output */ | 1561 | /* mos text output */ |
| 1510 | if (mos_mode) { | 1562 | if (mos_mode) { |
| 1511 | if (status == STATE_OK) | 1563 | if (status == STATE_OK) { |
| 1512 | printf(" MOS %0.1f", (float)host->mos); | 1564 | printf(" MOS %0.1f", (float)host->mos); |
| 1513 | else if (status == STATE_WARNING && host->mos_status == status) | 1565 | } else if (status == STATE_WARNING && host->mos_status == status) { |
| 1514 | printf(" MOS %0.1f < %0.1f", (float)host->mos, (float)warn.mos); | 1566 | printf(" MOS %0.1f < %0.1f", (float)host->mos, (float)warn.mos); |
| 1515 | else if (status == STATE_CRITICAL && host->mos_status == status) | 1567 | } else if (status == STATE_CRITICAL && host->mos_status == status) { |
| 1516 | printf(" MOS %0.1f < %0.1f", (float)host->mos, (float)crit.mos); | 1568 | printf(" MOS %0.1f < %0.1f", (float)host->mos, (float)crit.mos); |
| 1569 | } | ||
| 1517 | } | 1570 | } |
| 1518 | /* score text output */ | 1571 | /* score text output */ |
| 1519 | if (score_mode) { | 1572 | if (score_mode) { |
| 1520 | if (status == STATE_OK) | 1573 | if (status == STATE_OK) { |
| 1521 | printf(" Score %u", (int)host->score); | 1574 | printf(" Score %u", (int)host->score); |
| 1522 | else if (status == STATE_WARNING && host->score_status == status) | 1575 | } else if (status == STATE_WARNING && host->score_status == status) { |
| 1523 | printf(" Score %u < %u", (int)host->score, (int)warn.score); | 1576 | printf(" Score %u < %u", (int)host->score, (int)warn.score); |
| 1524 | else if (status == STATE_CRITICAL && host->score_status == status) | 1577 | } else if (status == STATE_CRITICAL && host->score_status == status) { |
| 1525 | printf(" Score %u < %u", (int)host->score, (int)crit.score); | 1578 | printf(" Score %u < %u", (int)host->score, (int)crit.score); |
| 1579 | } | ||
| 1526 | } | 1580 | } |
| 1527 | /* order statis text output */ | 1581 | /* order statis text output */ |
| 1528 | if (order_mode) { | 1582 | if (order_mode) { |
| 1529 | if (status == STATE_OK) | 1583 | if (status == STATE_OK) { |
| 1530 | printf(" Packets in order"); | 1584 | printf(" Packets in order"); |
| 1531 | else if (status == STATE_CRITICAL && host->order_status == status) | 1585 | } else if (status == STATE_CRITICAL && host->order_status == status) { |
| 1532 | printf(" Packets out of order"); | 1586 | printf(" Packets out of order"); |
| 1587 | } | ||
| 1533 | } | 1588 | } |
| 1534 | } | 1589 | } |
| 1535 | host = host->next; | 1590 | host = host->next; |
| @@ -1542,8 +1597,9 @@ static void finish(int sig) { | |||
| 1542 | i = 0; | 1597 | i = 0; |
| 1543 | host = list; | 1598 | host = list; |
| 1544 | while (host) { | 1599 | while (host) { |
| 1545 | if (debug) | 1600 | if (debug) { |
| 1546 | puts(""); | 1601 | puts(""); |
| 1602 | } | ||
| 1547 | 1603 | ||
| 1548 | if (rta_mode) { | 1604 | if (rta_mode) { |
| 1549 | if (host->pl < 100) { | 1605 | if (host->pl < 100) { |
| @@ -1593,17 +1649,19 @@ static void finish(int sig) { | |||
| 1593 | } | 1649 | } |
| 1594 | 1650 | ||
| 1595 | if (min_hosts_alive > -1) { | 1651 | if (min_hosts_alive > -1) { |
| 1596 | if (hosts_ok >= min_hosts_alive) | 1652 | if (hosts_ok >= min_hosts_alive) { |
| 1597 | status = STATE_OK; | 1653 | status = STATE_OK; |
| 1598 | else if ((hosts_ok + hosts_warn) >= min_hosts_alive) | 1654 | } else if ((hosts_ok + hosts_warn) >= min_hosts_alive) { |
| 1599 | status = STATE_WARNING; | 1655 | status = STATE_WARNING; |
| 1656 | } | ||
| 1600 | } | 1657 | } |
| 1601 | 1658 | ||
| 1602 | /* finish with an empty line */ | 1659 | /* finish with an empty line */ |
| 1603 | puts(""); | 1660 | puts(""); |
| 1604 | if (debug) | 1661 | if (debug) { |
| 1605 | printf("targets: %u, targets_alive: %u, hosts_ok: %u, hosts_warn: %u, min_hosts_alive: %i\n", targets, targets_alive, hosts_ok, | 1662 | printf("targets: %u, targets_alive: %u, hosts_ok: %u, hosts_warn: %u, min_hosts_alive: %i\n", targets, targets_alive, hosts_ok, |
| 1606 | hosts_warn, min_hosts_alive); | 1663 | hosts_warn, min_hosts_alive); |
| 1664 | } | ||
| 1607 | 1665 | ||
| 1608 | exit(status); | 1666 | exit(status); |
| 1609 | } | 1667 | } |
| @@ -1616,8 +1674,9 @@ static u_int get_timevaldiff(struct timeval *early, struct timeval *later) { | |||
| 1616 | gettimeofday(&now, &tz); | 1674 | gettimeofday(&now, &tz); |
| 1617 | later = &now; | 1675 | later = &now; |
| 1618 | } | 1676 | } |
| 1619 | if (!early) | 1677 | if (!early) { |
| 1620 | early = &prog_start; | 1678 | early = &prog_start; |
| 1679 | } | ||
| 1621 | 1680 | ||
| 1622 | /* if early > later we return 0 so as to indicate a timeout */ | 1681 | /* if early > later we return 0 so as to indicate a timeout */ |
| 1623 | if (early->tv_sec > later->tv_sec || (early->tv_sec == later->tv_sec && early->tv_usec > later->tv_usec)) { | 1682 | if (early->tv_sec > later->tv_sec || (early->tv_sec == later->tv_sec && early->tv_usec > later->tv_usec)) { |
| @@ -1634,10 +1693,11 @@ static int add_target_ip(char *arg, struct sockaddr_storage *in) { | |||
| 1634 | struct sockaddr_in *sin, *host_sin; | 1693 | struct sockaddr_in *sin, *host_sin; |
| 1635 | struct sockaddr_in6 *sin6, *host_sin6; | 1694 | struct sockaddr_in6 *sin6, *host_sin6; |
| 1636 | 1695 | ||
| 1637 | if (address_family == AF_INET) | 1696 | if (address_family == AF_INET) { |
| 1638 | sin = (struct sockaddr_in *)in; | 1697 | sin = (struct sockaddr_in *)in; |
| 1639 | else | 1698 | } else { |
| 1640 | sin6 = (struct sockaddr_in6 *)in; | 1699 | sin6 = (struct sockaddr_in6 *)in; |
| 1700 | } | ||
| 1641 | 1701 | ||
| 1642 | /* disregard obviously stupid addresses | 1702 | /* disregard obviously stupid addresses |
| 1643 | * (I didn't find an ipv6 equivalent to INADDR_NONE) */ | 1703 | * (I didn't find an ipv6 equivalent to INADDR_NONE) */ |
| @@ -1654,8 +1714,9 @@ static int add_target_ip(char *arg, struct sockaddr_storage *in) { | |||
| 1654 | 1714 | ||
| 1655 | if ((address_family == AF_INET && host_sin->sin_addr.s_addr == sin->sin_addr.s_addr) || | 1715 | if ((address_family == AF_INET && host_sin->sin_addr.s_addr == sin->sin_addr.s_addr) || |
| 1656 | (address_family == AF_INET6 && host_sin6->sin6_addr.s6_addr == sin6->sin6_addr.s6_addr)) { | 1716 | (address_family == AF_INET6 && host_sin6->sin6_addr.s6_addr == sin6->sin6_addr.s6_addr)) { |
| 1657 | if (debug) | 1717 | if (debug) { |
| 1658 | printf("Identical IP already exists. Not adding %s\n", arg); | 1718 | printf("Identical IP already exists. Not adding %s\n", arg); |
| 1719 | } | ||
| 1659 | return -1; | 1720 | return -1; |
| 1660 | } | 1721 | } |
| 1661 | host = host->next; | 1722 | host = host->next; |
| @@ -1700,10 +1761,11 @@ static int add_target_ip(char *arg, struct sockaddr_storage *in) { | |||
| 1700 | host->score_status = 0; | 1761 | host->score_status = 0; |
| 1701 | host->pl_status = 0; | 1762 | host->pl_status = 0; |
| 1702 | 1763 | ||
| 1703 | if (!list) | 1764 | if (!list) { |
| 1704 | list = cursor = host; | 1765 | list = cursor = host; |
| 1705 | else | 1766 | } else { |
| 1706 | cursor->next = host; | 1767 | cursor->next = host; |
| 1768 | } | ||
| 1707 | 1769 | ||
| 1708 | cursor = host; | 1770 | cursor = host; |
| 1709 | targets++; | 1771 | targets++; |
| @@ -1777,8 +1839,9 @@ static int add_target(char *arg) { | |||
| 1777 | 1839 | ||
| 1778 | /* this is silly, but it works */ | 1840 | /* this is silly, but it works */ |
| 1779 | if (mode == MODE_HOSTCHECK || mode == MODE_ALL) { | 1841 | if (mode == MODE_HOSTCHECK || mode == MODE_ALL) { |
| 1780 | if (debug > 2) | 1842 | if (debug > 2) { |
| 1781 | printf("mode: %d\n", mode); | 1843 | printf("mode: %d\n", mode); |
| 1844 | } | ||
| 1782 | continue; | 1845 | continue; |
| 1783 | } | 1846 | } |
| 1784 | break; | 1847 | break; |
| @@ -1793,10 +1856,12 @@ static void set_source_ip(char *arg) { | |||
| 1793 | 1856 | ||
| 1794 | memset(&src, 0, sizeof(src)); | 1857 | memset(&src, 0, sizeof(src)); |
| 1795 | src.sin_family = address_family; | 1858 | src.sin_family = address_family; |
| 1796 | if ((src.sin_addr.s_addr = inet_addr(arg)) == INADDR_NONE) | 1859 | if ((src.sin_addr.s_addr = inet_addr(arg)) == INADDR_NONE) { |
| 1797 | src.sin_addr.s_addr = get_ip_address(arg); | 1860 | src.sin_addr.s_addr = get_ip_address(arg); |
| 1798 | if (bind(icmp_sock, (struct sockaddr *)&src, sizeof(src)) == -1) | 1861 | } |
| 1862 | if (bind(icmp_sock, (struct sockaddr *)&src, sizeof(src)) == -1) { | ||
| 1799 | crash("Cannot bind to IP address %s", arg); | 1863 | crash("Cannot bind to IP address %s", arg); |
| 1864 | } | ||
| 1800 | } | 1865 | } |
| 1801 | 1866 | ||
| 1802 | /* TODO: Move this to netutils.c and also change check_dhcp to use that. */ | 1867 | /* TODO: Move this to netutils.c and also change check_dhcp to use that. */ |
| @@ -1811,8 +1876,9 @@ static in_addr_t get_ip_address(const char *ifname) { | |||
| 1811 | 1876 | ||
| 1812 | ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0'; | 1877 | ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0'; |
| 1813 | 1878 | ||
| 1814 | if (ioctl(icmp_sock, SIOCGIFADDR, &ifr) == -1) | 1879 | if (ioctl(icmp_sock, SIOCGIFADDR, &ifr) == -1) { |
| 1815 | crash("Cannot determine IP address of interface %s", ifname); | 1880 | crash("Cannot determine IP address of interface %s", ifname); |
| 1881 | } | ||
| 1816 | 1882 | ||
| 1817 | memcpy(&ip, &ifr.ifr_addr, sizeof(ip)); | 1883 | memcpy(&ip, &ifr.ifr_addr, sizeof(ip)); |
| 1818 | #else | 1884 | #else |
| @@ -1835,47 +1901,57 @@ static u_int get_timevar(const char *str) { | |||
| 1835 | u_int i, d; /* integer and decimal, respectively */ | 1901 | u_int i, d; /* integer and decimal, respectively */ |
| 1836 | u_int factor = 1000; /* default to milliseconds */ | 1902 | u_int factor = 1000; /* default to milliseconds */ |
| 1837 | 1903 | ||
| 1838 | if (!str) | 1904 | if (!str) { |
| 1839 | return 0; | 1905 | return 0; |
| 1906 | } | ||
| 1840 | len = strlen(str); | 1907 | len = strlen(str); |
| 1841 | if (!len) | 1908 | if (!len) { |
| 1842 | return 0; | 1909 | return 0; |
| 1910 | } | ||
| 1843 | 1911 | ||
| 1844 | /* unit might be given as ms|m (millisec), | 1912 | /* unit might be given as ms|m (millisec), |
| 1845 | * us|u (microsec) or just plain s, for seconds */ | 1913 | * us|u (microsec) or just plain s, for seconds */ |
| 1846 | p = '\0'; | 1914 | p = '\0'; |
| 1847 | u = str[len - 1]; | 1915 | u = str[len - 1]; |
| 1848 | if (len >= 2 && !isdigit((int)str[len - 2])) | 1916 | if (len >= 2 && !isdigit((int)str[len - 2])) { |
| 1849 | p = str[len - 2]; | 1917 | p = str[len - 2]; |
| 1850 | if (p && u == 's') | 1918 | } |
| 1919 | if (p && u == 's') { | ||
| 1851 | u = p; | 1920 | u = p; |
| 1852 | else if (!p) | 1921 | } else if (!p) { |
| 1853 | p = u; | 1922 | p = u; |
| 1854 | if (debug > 2) | 1923 | } |
| 1924 | if (debug > 2) { | ||
| 1855 | printf("evaluating %s, u: %c, p: %c\n", str, u, p); | 1925 | printf("evaluating %s, u: %c, p: %c\n", str, u, p); |
| 1926 | } | ||
| 1856 | 1927 | ||
| 1857 | if (u == 'u') | 1928 | if (u == 'u') { |
| 1858 | factor = 1; /* microseconds */ | 1929 | factor = 1; /* microseconds */ |
| 1859 | else if (u == 'm') | 1930 | } else if (u == 'm') { |
| 1860 | factor = 1000; /* milliseconds */ | 1931 | factor = 1000; /* milliseconds */ |
| 1861 | else if (u == 's') | 1932 | } else if (u == 's') { |
| 1862 | factor = 1000000; /* seconds */ | 1933 | factor = 1000000; /* seconds */ |
| 1863 | if (debug > 2) | 1934 | } |
| 1935 | if (debug > 2) { | ||
| 1864 | printf("factor is %u\n", factor); | 1936 | printf("factor is %u\n", factor); |
| 1937 | } | ||
| 1865 | 1938 | ||
| 1866 | i = strtoul(str, &ptr, 0); | 1939 | i = strtoul(str, &ptr, 0); |
| 1867 | if (!ptr || *ptr != '.' || strlen(ptr) < 2 || factor == 1) | 1940 | if (!ptr || *ptr != '.' || strlen(ptr) < 2 || factor == 1) { |
| 1868 | return i * factor; | 1941 | return i * factor; |
| 1942 | } | ||
| 1869 | 1943 | ||
| 1870 | /* time specified in usecs can't have decimal points, so ignore them */ | 1944 | /* time specified in usecs can't have decimal points, so ignore them */ |
| 1871 | if (factor == 1) | 1945 | if (factor == 1) { |
| 1872 | return i; | 1946 | return i; |
| 1947 | } | ||
| 1873 | 1948 | ||
| 1874 | d = strtoul(ptr + 1, NULL, 0); | 1949 | d = strtoul(ptr + 1, NULL, 0); |
| 1875 | 1950 | ||
| 1876 | /* d is decimal, so get rid of excess digits */ | 1951 | /* d is decimal, so get rid of excess digits */ |
| 1877 | while (d >= factor) | 1952 | while (d >= factor) { |
| 1878 | d /= 10; | 1953 | d /= 10; |
| 1954 | } | ||
| 1879 | 1955 | ||
| 1880 | /* the last parenthesis avoids floating point exceptions. */ | 1956 | /* the last parenthesis avoids floating point exceptions. */ |
| 1881 | return ((i * factor) + (d * (factor / 10))); | 1957 | return ((i * factor) + (d * (factor / 10))); |
| @@ -1885,15 +1961,16 @@ static u_int get_timevar(const char *str) { | |||
| 1885 | static int get_threshold(char *str, threshold *th) { | 1961 | static int get_threshold(char *str, threshold *th) { |
| 1886 | char *p = NULL, i = 0; | 1962 | char *p = NULL, i = 0; |
| 1887 | 1963 | ||
| 1888 | if (!str || !strlen(str) || !th) | 1964 | if (!str || !strlen(str) || !th) { |
| 1889 | return -1; | 1965 | return -1; |
| 1966 | } | ||
| 1890 | 1967 | ||
| 1891 | /* pointer magic slims code by 10 lines. i is bof-stop on stupid libc's */ | 1968 | /* pointer magic slims code by 10 lines. i is bof-stop on stupid libc's */ |
| 1892 | p = &str[strlen(str) - 1]; | 1969 | p = &str[strlen(str) - 1]; |
| 1893 | while (p != &str[1]) { | 1970 | while (p != &str[1]) { |
| 1894 | if (*p == '%') | 1971 | if (*p == '%') { |
| 1895 | *p = '\0'; | 1972 | *p = '\0'; |
| 1896 | else if (*p == ',' && i) { | 1973 | } else if (*p == ',' && i) { |
| 1897 | *p = '\0'; /* reset it so get_timevar(str) works nicely later */ | 1974 | *p = '\0'; /* reset it so get_timevar(str) works nicely later */ |
| 1898 | th->pl = (unsigned char)strtoul(p + 1, NULL, 0); | 1975 | th->pl = (unsigned char)strtoul(p + 1, NULL, 0); |
| 1899 | break; | 1976 | break; |
| @@ -1903,13 +1980,16 @@ static int get_threshold(char *str, threshold *th) { | |||
| 1903 | } | 1980 | } |
| 1904 | th->rta = get_timevar(str); | 1981 | th->rta = get_timevar(str); |
| 1905 | 1982 | ||
| 1906 | if (!th->rta) | 1983 | if (!th->rta) { |
| 1907 | return -1; | 1984 | return -1; |
| 1985 | } | ||
| 1908 | 1986 | ||
| 1909 | if (th->rta > MAXTTL * 1000000) | 1987 | if (th->rta > MAXTTL * 1000000) { |
| 1910 | th->rta = MAXTTL * 1000000; | 1988 | th->rta = MAXTTL * 1000000; |
| 1911 | if (th->pl > 100) | 1989 | } |
| 1990 | if (th->pl > 100) { | ||
| 1912 | th->pl = 100; | 1991 | th->pl = 100; |
| 1992 | } | ||
| 1913 | 1993 | ||
| 1914 | return 0; | 1994 | return 0; |
| 1915 | } | 1995 | } |
| @@ -1925,8 +2005,9 @@ static int get_threshold(char *str, threshold *th) { | |||
| 1925 | * @param[in] mode Determines whether this a threshold for rta, packet_loss, jitter, mos or score (exclusively) | 2005 | * @param[in] mode Determines whether this a threshold for rta, packet_loss, jitter, mos or score (exclusively) |
| 1926 | */ | 2006 | */ |
| 1927 | static bool get_threshold2(char *str, size_t length, threshold *warn, threshold *crit, threshold_mode mode) { | 2007 | static bool get_threshold2(char *str, size_t length, threshold *warn, threshold *crit, threshold_mode mode) { |
| 1928 | if (!str || !length || !warn || !crit) | 2008 | if (!str || !length || !warn || !crit) { |
| 1929 | return false; | 2009 | return false; |
| 2010 | } | ||
| 1930 | 2011 | ||
| 1931 | // p points to the last char in str | 2012 | // p points to the last char in str |
| 1932 | char *p = &str[length - 1]; | 2013 | char *p = &str[length - 1]; |
| @@ -1999,8 +2080,9 @@ unsigned short icmp_checksum(uint16_t *p, size_t n) { | |||
| 1999 | } | 2080 | } |
| 2000 | 2081 | ||
| 2001 | /* mop up the occasional odd byte */ | 2082 | /* mop up the occasional odd byte */ |
| 2002 | if (n == 1) | 2083 | if (n == 1) { |
| 2003 | sum += *((uint8_t *)p - 1); | 2084 | sum += *((uint8_t *)p - 1); |
| 2085 | } | ||
| 2004 | 2086 | ||
| 2005 | sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ | 2087 | sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ |
| 2006 | sum += (sum >> 16); /* add carry */ | 2088 | sum += (sum >> 16); /* add carry */ |
