diff options
| author | Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> | 2025-04-02 01:04:25 +0200 |
|---|---|---|
| committer | Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> | 2025-04-02 01:04:25 +0200 |
| commit | f62f182653650f274be0018d7a8f166aa99719d7 (patch) | |
| tree | d65da45bbe9753528a11f467eb871d2370db07cb | |
| parent | 4ab8a54c52fa78c1d8d757bcb75a8e5d4b3e560f (diff) | |
| download | monitoring-plugins-f62f182653650f274be0018d7a8f166aa99719d7.tar.gz | |
check_icmp: localise variables
| -rw-r--r-- | plugins-root/check_icmp.c | 208 |
1 files changed, 89 insertions, 119 deletions
diff --git a/plugins-root/check_icmp.c b/plugins-root/check_icmp.c index 6a4239a8..061e7d82 100644 --- a/plugins-root/check_icmp.c +++ b/plugins-root/check_icmp.c | |||
| @@ -65,6 +65,7 @@ const char *email = "devel@monitoring-plugins.org"; | |||
| 65 | #include <netinet/icmp6.h> | 65 | #include <netinet/icmp6.h> |
| 66 | #include <arpa/inet.h> | 66 | #include <arpa/inet.h> |
| 67 | #include <math.h> | 67 | #include <math.h> |
| 68 | #include <netdb.h> | ||
| 68 | 69 | ||
| 69 | /** sometimes undefined system macros (quite a few, actually) **/ | 70 | /** sometimes undefined system macros (quite a few, actually) **/ |
| 70 | #ifndef MAXTTL | 71 | #ifndef MAXTTL |
| @@ -261,10 +262,10 @@ static bool order_mode = false; | |||
| 261 | 262 | ||
| 262 | /** code start **/ | 263 | /** code start **/ |
| 263 | static void crash(const char *fmt, ...) { | 264 | static void crash(const char *fmt, ...) { |
| 264 | va_list ap; | ||
| 265 | 265 | ||
| 266 | printf("%s: ", progname); | 266 | printf("%s: ", progname); |
| 267 | 267 | ||
| 268 | va_list ap; | ||
| 268 | va_start(ap, fmt); | 269 | va_start(ap, fmt); |
| 269 | vprintf(fmt, ap); | 270 | vprintf(fmt, ap); |
| 270 | va_end(ap); | 271 | va_end(ap); |
| @@ -383,9 +384,6 @@ static const char *get_icmp_error_msg(unsigned char icmp_type, unsigned char icm | |||
| 383 | 384 | ||
| 384 | static int handle_random_icmp(unsigned char *packet, struct sockaddr_storage *addr) { | 385 | static int handle_random_icmp(unsigned char *packet, struct sockaddr_storage *addr) { |
| 385 | struct icmp p; | 386 | struct icmp p; |
| 386 | struct icmp sent_icmp; | ||
| 387 | struct rta_host *host = NULL; | ||
| 388 | |||
| 389 | memcpy(&p, packet, sizeof(p)); | 387 | memcpy(&p, packet, sizeof(p)); |
| 390 | if (p.icmp_type == ICMP_ECHO && ntohs(p.icmp_id) == pid) { | 388 | if (p.icmp_type == ICMP_ECHO && ntohs(p.icmp_id) == pid) { |
| 391 | /* echo request from us to us (pinging localhost) */ | 389 | /* echo request from us to us (pinging localhost) */ |
| @@ -412,6 +410,7 @@ static int handle_random_icmp(unsigned char *packet, struct sockaddr_storage *ad | |||
| 412 | 410 | ||
| 413 | /* might be for us. At least it holds the original package (according | 411 | /* might be for us. At least it holds the original package (according |
| 414 | * to RFC 792). If it isn't, just ignore it */ | 412 | * to RFC 792). If it isn't, just ignore it */ |
| 413 | struct icmp sent_icmp; | ||
| 415 | memcpy(&sent_icmp, packet + 28, sizeof(sent_icmp)); | 414 | memcpy(&sent_icmp, packet + 28, sizeof(sent_icmp)); |
| 416 | if (sent_icmp.icmp_type != ICMP_ECHO || ntohs(sent_icmp.icmp_id) != pid || ntohs(sent_icmp.icmp_seq) >= targets * packets) { | 415 | if (sent_icmp.icmp_type != ICMP_ECHO || ntohs(sent_icmp.icmp_id) != pid || ntohs(sent_icmp.icmp_seq) >= targets * packets) { |
| 417 | if (debug) { | 416 | if (debug) { |
| @@ -421,7 +420,7 @@ static int handle_random_icmp(unsigned char *packet, struct sockaddr_storage *ad | |||
| 421 | } | 420 | } |
| 422 | 421 | ||
| 423 | /* it is indeed a response for us */ | 422 | /* it is indeed a response for us */ |
| 424 | host = table[ntohs(sent_icmp.icmp_seq) / packets]; | 423 | struct rta_host *host = table[ntohs(sent_icmp.icmp_seq) / packets]; |
| 425 | if (debug) { | 424 | if (debug) { |
| 426 | char address[INET6_ADDRSTRLEN]; | 425 | char address[INET6_ADDRSTRLEN]; |
| 427 | parse_address(addr, address, sizeof(address)); | 426 | parse_address(addr, address, sizeof(address)); |
| @@ -463,28 +462,15 @@ void parse_address(struct sockaddr_storage *addr, char *address, int size) { | |||
| 463 | } | 462 | } |
| 464 | 463 | ||
| 465 | int main(int argc, char **argv) { | 464 | int main(int argc, char **argv) { |
| 466 | int i; | ||
| 467 | char *ptr; | ||
| 468 | long int arg; | ||
| 469 | int icmp_sockerrno; | ||
| 470 | int udp_sockerrno; | ||
| 471 | int tcp_sockerrno; | ||
| 472 | int result; | ||
| 473 | struct rta_host *host; | ||
| 474 | #ifdef HAVE_SIGACTION | ||
| 475 | struct sigaction sig_action; | ||
| 476 | #endif | ||
| 477 | #ifdef SO_TIMESTAMP | ||
| 478 | int on = 1; | ||
| 479 | #endif | ||
| 480 | char *source_ip = NULL; | ||
| 481 | char *opts_str = "vhVw:c:n:p:t:H:s:i:b:I:l:m:P:R:J:S:M:O64"; | ||
| 482 | setlocale(LC_ALL, ""); | 465 | setlocale(LC_ALL, ""); |
| 483 | bindtextdomain(PACKAGE, LOCALEDIR); | 466 | bindtextdomain(PACKAGE, LOCALEDIR); |
| 484 | textdomain(PACKAGE); | 467 | textdomain(PACKAGE); |
| 485 | 468 | ||
| 486 | /* we only need to be setsuid when we get the sockets, so do | 469 | /* we only need to be setsuid when we get the sockets, so do |
| 487 | * that before pointer magic (esp. on network data) */ | 470 | * that before pointer magic (esp. on network data) */ |
| 471 | int icmp_sockerrno; | ||
| 472 | int udp_sockerrno; | ||
| 473 | int tcp_sockerrno; | ||
| 488 | icmp_sockerrno = udp_sockerrno = tcp_sockerrno = sockets = 0; | 474 | icmp_sockerrno = udp_sockerrno = tcp_sockerrno = sockets = 0; |
| 489 | 475 | ||
| 490 | address_family = -1; | 476 | address_family = -1; |
| @@ -492,7 +478,7 @@ int main(int argc, char **argv) { | |||
| 492 | 478 | ||
| 493 | /* get calling name the old-fashioned way for portability instead | 479 | /* get calling name the old-fashioned way for portability instead |
| 494 | * of relying on the glibc-ism __progname */ | 480 | * of relying on the glibc-ism __progname */ |
| 495 | ptr = strrchr(argv[0], '/'); | 481 | char *ptr = strrchr(argv[0], '/'); |
| 496 | if (ptr) { | 482 | if (ptr) { |
| 497 | progname = &ptr[1]; | 483 | progname = &ptr[1]; |
| 498 | } else { | 484 | } else { |
| @@ -549,7 +535,9 @@ int main(int argc, char **argv) { | |||
| 549 | } | 535 | } |
| 550 | 536 | ||
| 551 | /* Parse protocol arguments first */ | 537 | /* Parse protocol arguments first */ |
| 552 | for (i = 1; i < argc; i++) { | 538 | char *opts_str = "vhVw:c:n:p:t:H:s:i:b:I:l:m:P:R:J:S:M:O64"; |
| 539 | for (int i = 1; i < argc; i++) { | ||
| 540 | long int arg; | ||
| 553 | while ((arg = getopt(argc, argv, opts_str)) != EOF) { | 541 | while ((arg = getopt(argc, argv, opts_str)) != EOF) { |
| 554 | switch (arg) { | 542 | switch (arg) { |
| 555 | case '4': | 543 | case '4': |
| @@ -578,7 +566,9 @@ int main(int argc, char **argv) { | |||
| 578 | unsigned long size; | 566 | unsigned long size; |
| 579 | bool err; | 567 | bool err; |
| 580 | /* parse the arguments */ | 568 | /* parse the arguments */ |
| 581 | for (i = 1; i < argc; i++) { | 569 | char *source_ip = NULL; |
| 570 | for (int i = 1; i < argc; i++) { | ||
| 571 | long int arg; | ||
| 582 | while ((arg = getopt(argc, argv, opts_str)) != EOF) { | 572 | while ((arg = getopt(argc, argv, opts_str)) != EOF) { |
| 583 | switch (arg) { | 573 | switch (arg) { |
| 584 | case 'v': | 574 | case 'v': |
| @@ -732,6 +722,7 @@ int main(int argc, char **argv) { | |||
| 732 | } | 722 | } |
| 733 | 723 | ||
| 734 | #ifdef SO_TIMESTAMP | 724 | #ifdef SO_TIMESTAMP |
| 725 | int on = 1; | ||
| 735 | if (setsockopt(icmp_sock, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on))) { | 726 | if (setsockopt(icmp_sock, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on))) { |
| 736 | if (debug) { | 727 | if (debug) { |
| 737 | printf("Warning: no SO_TIMESTAMP support\n"); | 728 | printf("Warning: no SO_TIMESTAMP support\n"); |
| @@ -767,7 +758,7 @@ int main(int argc, char **argv) { | |||
| 767 | } | 758 | } |
| 768 | 759 | ||
| 769 | if (icmp_sock) { | 760 | if (icmp_sock) { |
| 770 | result = setsockopt(icmp_sock, SOL_IP, IP_TTL, &ttl, sizeof(ttl)); | 761 | int result = setsockopt(icmp_sock, SOL_IP, IP_TTL, &ttl, sizeof(ttl)); |
| 771 | if (debug) { | 762 | if (debug) { |
| 772 | if (result == -1) { | 763 | if (result == -1) { |
| 773 | printf("setsockopt failed\n"); | 764 | printf("setsockopt failed\n"); |
| @@ -801,6 +792,7 @@ int main(int argc, char **argv) { | |||
| 801 | } | 792 | } |
| 802 | 793 | ||
| 803 | #ifdef HAVE_SIGACTION | 794 | #ifdef HAVE_SIGACTION |
| 795 | struct sigaction sig_action; | ||
| 804 | sig_action.sa_sigaction = NULL; | 796 | sig_action.sa_sigaction = NULL; |
| 805 | sig_action.sa_handler = finish; | 797 | sig_action.sa_handler = finish; |
| 806 | sigfillset(&sig_action.sa_mask); | 798 | sigfillset(&sig_action.sa_mask); |
| @@ -856,13 +848,13 @@ int main(int argc, char **argv) { | |||
| 856 | crash("minimum alive hosts is negative (%i)", min_hosts_alive); | 848 | crash("minimum alive hosts is negative (%i)", min_hosts_alive); |
| 857 | } | 849 | } |
| 858 | 850 | ||
| 859 | host = list; | 851 | struct rta_host *host = list; |
| 860 | table = malloc(sizeof(struct rta_host *) * targets); | 852 | table = malloc(sizeof(struct rta_host *) * targets); |
| 861 | if (!table) { | 853 | if (!table) { |
| 862 | crash("main(): malloc failed for host table"); | 854 | crash("main(): malloc failed for host table"); |
| 863 | } | 855 | } |
| 864 | 856 | ||
| 865 | i = 0; | 857 | int i = 0; |
| 866 | while (host) { | 858 | while (host) { |
| 867 | host->id = i * packets; | 859 | host->id = i * packets; |
| 868 | table[i] = host; | 860 | table[i] = host; |
| @@ -879,16 +871,11 @@ int main(int argc, char **argv) { | |||
| 879 | } | 871 | } |
| 880 | 872 | ||
| 881 | static void run_checks(void) { | 873 | static void run_checks(void) { |
| 882 | u_int i; | ||
| 883 | u_int t; | ||
| 884 | u_int final_wait; | ||
| 885 | u_int time_passed; | ||
| 886 | |||
| 887 | /* this loop might actually violate the pkt_interval or target_interval | 874 | /* this loop might actually violate the pkt_interval or target_interval |
| 888 | * settings, but only if there aren't any packets on the wire which | 875 | * settings, but only if there aren't any packets on the wire which |
| 889 | * indicates that the target can handle an increased packet rate */ | 876 | * indicates that the target can handle an increased packet rate */ |
| 890 | for (i = 0; i < packets; i++) { | 877 | for (u_int i = 0; i < packets; i++) { |
| 891 | for (t = 0; t < targets; t++) { | 878 | for (u_int t = 0; t < targets; t++) { |
| 892 | /* don't send useless packets */ | 879 | /* don't send useless packets */ |
| 893 | if (!targets_alive) { | 880 | if (!targets_alive) { |
| 894 | finish(0); | 881 | finish(0); |
| @@ -908,8 +895,8 @@ static void run_checks(void) { | |||
| 908 | } | 895 | } |
| 909 | 896 | ||
| 910 | if (icmp_pkts_en_route && targets_alive) { | 897 | if (icmp_pkts_en_route && targets_alive) { |
| 911 | time_passed = get_timevaldiff(NULL, NULL); | 898 | u_int time_passed = get_timevaldiff(NULL, NULL); |
| 912 | final_wait = max_completion_time - time_passed; | 899 | u_int final_wait = max_completion_time - time_passed; |
| 913 | 900 | ||
| 914 | if (debug) { | 901 | if (debug) { |
| 915 | printf("time_passed: %u final_wait: %u max_completion_time: %llu\n", time_passed, final_wait, max_completion_time); | 902 | printf("time_passed: %u final_wait: %u max_completion_time: %llu\n", time_passed, final_wait, max_completion_time); |
| @@ -941,21 +928,7 @@ static void run_checks(void) { | |||
| 941 | * icmp echo reply : the rest | 928 | * icmp echo reply : the rest |
| 942 | */ | 929 | */ |
| 943 | static int wait_for_reply(int sock, u_int t) { | 930 | static int wait_for_reply(int sock, u_int t) { |
| 944 | int n; | ||
| 945 | int hlen; | ||
| 946 | static unsigned char buf[65536]; | ||
| 947 | struct sockaddr_storage resp_addr; | ||
| 948 | union ip_hdr *ip; | ||
| 949 | union icmp_packet packet; | 931 | union icmp_packet packet; |
| 950 | struct rta_host *host; | ||
| 951 | struct icmp_ping_data data; | ||
| 952 | struct timeval wait_start; | ||
| 953 | struct timeval now; | ||
| 954 | u_int tdiff; | ||
| 955 | u_int i; | ||
| 956 | u_int per_pkt_wait; | ||
| 957 | double jitter_tmp; | ||
| 958 | |||
| 959 | if (!(packet.buf = malloc(icmp_pkt_size))) { | 932 | if (!(packet.buf = malloc(icmp_pkt_size))) { |
| 960 | crash("send_icmp_ping(): failed to malloc %d bytes for send buffer", icmp_pkt_size); | 933 | crash("send_icmp_ping(): failed to malloc %d bytes for send buffer", icmp_pkt_size); |
| 961 | return -1; /* might be reached if we're in debug mode */ | 934 | return -1; /* might be reached if we're in debug mode */ |
| @@ -969,10 +942,15 @@ static int wait_for_reply(int sock, u_int t) { | |||
| 969 | return 0; | 942 | return 0; |
| 970 | } | 943 | } |
| 971 | 944 | ||
| 945 | struct timeval wait_start; | ||
| 972 | gettimeofday(&wait_start, &tz); | 946 | gettimeofday(&wait_start, &tz); |
| 973 | 947 | ||
| 974 | i = t; | 948 | u_int i = t; |
| 975 | per_pkt_wait = t / icmp_pkts_en_route; | 949 | struct sockaddr_storage resp_addr; |
| 950 | u_int per_pkt_wait = t / icmp_pkts_en_route; | ||
| 951 | static unsigned char buf[65536]; | ||
| 952 | union ip_hdr *ip; | ||
| 953 | struct timeval now; | ||
| 976 | while (icmp_pkts_en_route && get_timevaldiff(&wait_start, NULL) < i) { | 954 | while (icmp_pkts_en_route && get_timevaldiff(&wait_start, NULL) < i) { |
| 977 | t = per_pkt_wait; | 955 | t = per_pkt_wait; |
| 978 | 956 | ||
| @@ -982,7 +960,7 @@ static int wait_for_reply(int sock, u_int t) { | |||
| 982 | } | 960 | } |
| 983 | 961 | ||
| 984 | /* reap responses until we hit a timeout */ | 962 | /* reap responses until we hit a timeout */ |
| 985 | n = recvfrom_wto(sock, buf, sizeof(buf), (struct sockaddr *)&resp_addr, &t, &now); | 963 | int n = recvfrom_wto(sock, buf, sizeof(buf), (struct sockaddr *)&resp_addr, &t, &now); |
| 986 | if (!n) { | 964 | if (!n) { |
| 987 | if (debug > 1) { | 965 | if (debug > 1) { |
| 988 | printf("recvfrom_wto() timed out during a %u usecs wait\n", per_pkt_wait); | 966 | printf("recvfrom_wto() timed out during a %u usecs wait\n", per_pkt_wait); |
| @@ -1015,7 +993,7 @@ static int wait_for_reply(int sock, u_int t) { | |||
| 1015 | * off the bottom 4 bits */ | 993 | * off the bottom 4 bits */ |
| 1016 | /* hlen = (ip->ip_vhl & 0x0f) << 2; */ | 994 | /* hlen = (ip->ip_vhl & 0x0f) << 2; */ |
| 1017 | /* #else */ | 995 | /* #else */ |
| 1018 | hlen = (address_family == AF_INET6) ? 0 : ip->ip.ip_hl << 2; | 996 | int hlen = (address_family == AF_INET6) ? 0 : ip->ip.ip_hl << 2; |
| 1019 | /* #endif */ | 997 | /* #endif */ |
| 1020 | 998 | ||
| 1021 | if (n < (hlen + ICMP_MINLEN)) { | 999 | if (n < (hlen + ICMP_MINLEN)) { |
| @@ -1047,6 +1025,8 @@ static int wait_for_reply(int sock, u_int t) { | |||
| 1047 | } | 1025 | } |
| 1048 | 1026 | ||
| 1049 | /* this is indeed a valid response */ | 1027 | /* this is indeed a valid response */ |
| 1028 | struct rta_host *host; | ||
| 1029 | struct icmp_ping_data data; | ||
| 1050 | if (address_family == PF_INET) { | 1030 | if (address_family == PF_INET) { |
| 1051 | memcpy(&data, packet.icp->icmp_data, sizeof(data)); | 1031 | memcpy(&data, packet.icp->icmp_data, sizeof(data)); |
| 1052 | if (debug > 2) { | 1032 | if (debug > 2) { |
| @@ -1063,10 +1043,11 @@ static int wait_for_reply(int sock, u_int t) { | |||
| 1063 | host = table[ntohs(packet.icp6->icmp6_seq) / packets]; | 1043 | host = table[ntohs(packet.icp6->icmp6_seq) / packets]; |
| 1064 | } | 1044 | } |
| 1065 | 1045 | ||
| 1066 | tdiff = get_timevaldiff(&data.stime, &now); | 1046 | u_int tdiff = get_timevaldiff(&data.stime, &now); |
| 1067 | 1047 | ||
| 1068 | if (host->last_tdiff > 0) { | 1048 | if (host->last_tdiff > 0) { |
| 1069 | /* Calculate jitter */ | 1049 | /* Calculate jitter */ |
| 1050 | double jitter_tmp; | ||
| 1070 | if (host->last_tdiff > tdiff) { | 1051 | if (host->last_tdiff > tdiff) { |
| 1071 | jitter_tmp = host->last_tdiff - tdiff; | 1052 | jitter_tmp = host->last_tdiff - tdiff; |
| 1072 | } else { | 1053 | } else { |
| @@ -1143,20 +1124,14 @@ static int wait_for_reply(int sock, u_int t) { | |||
| 1143 | 1124 | ||
| 1144 | /* the ping functions */ | 1125 | /* the ping functions */ |
| 1145 | static int send_icmp_ping(int sock, struct rta_host *host) { | 1126 | static int send_icmp_ping(int sock, struct rta_host *host) { |
| 1146 | long int len; | ||
| 1147 | size_t addrlen; | ||
| 1148 | struct icmp_ping_data data; | ||
| 1149 | struct msghdr hdr; | ||
| 1150 | struct iovec iov; | ||
| 1151 | struct timeval tv; | ||
| 1152 | void *buf = NULL; | ||
| 1153 | |||
| 1154 | if (sock == -1) { | 1127 | if (sock == -1) { |
| 1155 | errno = 0; | 1128 | errno = 0; |
| 1156 | crash("Attempt to send on bogus socket"); | 1129 | crash("Attempt to send on bogus socket"); |
| 1157 | return -1; | 1130 | return -1; |
| 1158 | } | 1131 | } |
| 1159 | 1132 | ||
| 1133 | void *buf = NULL; | ||
| 1134 | |||
| 1160 | if (!buf) { | 1135 | if (!buf) { |
| 1161 | if (!(buf = malloc(icmp_pkt_size))) { | 1136 | if (!(buf = malloc(icmp_pkt_size))) { |
| 1162 | crash("send_icmp_ping(): failed to malloc %d bytes for send buffer", icmp_pkt_size); | 1137 | crash("send_icmp_ping(): failed to malloc %d bytes for send buffer", icmp_pkt_size); |
| @@ -1165,14 +1140,18 @@ static int send_icmp_ping(int sock, struct rta_host *host) { | |||
| 1165 | } | 1140 | } |
| 1166 | memset(buf, 0, icmp_pkt_size); | 1141 | memset(buf, 0, icmp_pkt_size); |
| 1167 | 1142 | ||
| 1143 | struct timeval tv; | ||
| 1168 | if ((gettimeofday(&tv, &tz)) == -1) { | 1144 | if ((gettimeofday(&tv, &tz)) == -1) { |
| 1169 | free(buf); | 1145 | free(buf); |
| 1170 | return -1; | 1146 | return -1; |
| 1171 | } | 1147 | } |
| 1172 | 1148 | ||
| 1149 | struct icmp_ping_data data; | ||
| 1173 | data.ping_id = 10; /* host->icmp.icmp_sent; */ | 1150 | data.ping_id = 10; /* host->icmp.icmp_sent; */ |
| 1174 | memcpy(&data.stime, &tv, sizeof(tv)); | 1151 | memcpy(&data.stime, &tv, sizeof(tv)); |
| 1175 | 1152 | ||
| 1153 | size_t addrlen; | ||
| 1154 | |||
| 1176 | if (address_family == AF_INET) { | 1155 | if (address_family == AF_INET) { |
| 1177 | struct icmp *icp = (struct icmp *)buf; | 1156 | struct icmp *icp = (struct icmp *)buf; |
| 1178 | addrlen = sizeof(struct sockaddr_in); | 1157 | addrlen = sizeof(struct sockaddr_in); |
| @@ -1209,10 +1188,12 @@ static int send_icmp_ping(int sock, struct rta_host *host) { | |||
| 1209 | } | 1188 | } |
| 1210 | } | 1189 | } |
| 1211 | 1190 | ||
| 1191 | struct iovec iov; | ||
| 1212 | memset(&iov, 0, sizeof(iov)); | 1192 | memset(&iov, 0, sizeof(iov)); |
| 1213 | iov.iov_base = buf; | 1193 | iov.iov_base = buf; |
| 1214 | iov.iov_len = icmp_pkt_size; | 1194 | iov.iov_len = icmp_pkt_size; |
| 1215 | 1195 | ||
| 1196 | struct msghdr hdr; | ||
| 1216 | memset(&hdr, 0, sizeof(hdr)); | 1197 | memset(&hdr, 0, sizeof(hdr)); |
| 1217 | hdr.msg_name = (struct sockaddr *)&host->saddr_in; | 1198 | hdr.msg_name = (struct sockaddr *)&host->saddr_in; |
| 1218 | hdr.msg_namelen = addrlen; | 1199 | hdr.msg_namelen = addrlen; |
| @@ -1221,6 +1202,7 @@ static int send_icmp_ping(int sock, struct rta_host *host) { | |||
| 1221 | 1202 | ||
| 1222 | errno = 0; | 1203 | errno = 0; |
| 1223 | 1204 | ||
| 1205 | long int len; | ||
| 1224 | /* MSG_CONFIRM is a linux thing and only available on linux kernels >= 2.3.15, see send(2) */ | 1206 | /* MSG_CONFIRM is a linux thing and only available on linux kernels >= 2.3.15, see send(2) */ |
| 1225 | #ifdef MSG_CONFIRM | 1207 | #ifdef MSG_CONFIRM |
| 1226 | len = sendmsg(sock, &hdr, MSG_CONFIRM); | 1208 | len = sendmsg(sock, &hdr, MSG_CONFIRM); |
| @@ -1247,19 +1229,9 @@ static int send_icmp_ping(int sock, struct rta_host *host) { | |||
| 1247 | } | 1229 | } |
| 1248 | 1230 | ||
| 1249 | static int recvfrom_wto(int sock, void *buf, unsigned int len, struct sockaddr *saddr, u_int *timo, struct timeval *tv) { | 1231 | static int recvfrom_wto(int sock, void *buf, unsigned int len, struct sockaddr *saddr, u_int *timo, struct timeval *tv) { |
| 1250 | u_int slen; | ||
| 1251 | int n; | ||
| 1252 | int ret; | ||
| 1253 | struct timeval to; | ||
| 1254 | struct timeval then; | ||
| 1255 | struct timeval now; | ||
| 1256 | fd_set rd; | ||
| 1257 | fd_set wr; | ||
| 1258 | #ifdef HAVE_MSGHDR_MSG_CONTROL | 1232 | #ifdef HAVE_MSGHDR_MSG_CONTROL |
| 1259 | char ans_data[4096]; | 1233 | char ans_data[4096]; |
| 1260 | #endif // HAVE_MSGHDR_MSG_CONTROL | 1234 | #endif // HAVE_MSGHDR_MSG_CONTROL |
| 1261 | struct msghdr hdr; | ||
| 1262 | struct iovec iov; | ||
| 1263 | #ifdef SO_TIMESTAMP | 1235 | #ifdef SO_TIMESTAMP |
| 1264 | struct cmsghdr *chdr; | 1236 | struct cmsghdr *chdr; |
| 1265 | #endif | 1237 | #endif |
| @@ -1271,18 +1243,24 @@ static int recvfrom_wto(int sock, void *buf, unsigned int len, struct sockaddr * | |||
| 1271 | return 0; | 1243 | return 0; |
| 1272 | } | 1244 | } |
| 1273 | 1245 | ||
| 1246 | struct timeval to; | ||
| 1274 | to.tv_sec = *timo / 1000000; | 1247 | to.tv_sec = *timo / 1000000; |
| 1275 | to.tv_usec = (*timo - (to.tv_sec * 1000000)); | 1248 | to.tv_usec = (*timo - (to.tv_sec * 1000000)); |
| 1276 | 1249 | ||
| 1250 | fd_set rd; | ||
| 1251 | fd_set wr; | ||
| 1277 | FD_ZERO(&rd); | 1252 | FD_ZERO(&rd); |
| 1278 | FD_ZERO(&wr); | 1253 | FD_ZERO(&wr); |
| 1279 | FD_SET(sock, &rd); | 1254 | FD_SET(sock, &rd); |
| 1280 | errno = 0; | 1255 | errno = 0; |
| 1256 | |||
| 1257 | struct timeval then; | ||
| 1281 | gettimeofday(&then, &tz); | 1258 | gettimeofday(&then, &tz); |
| 1282 | n = select(sock + 1, &rd, &wr, NULL, &to); | 1259 | int n = select(sock + 1, &rd, &wr, NULL, &to); |
| 1283 | if (n < 0) { | 1260 | if (n < 0) { |
| 1284 | crash("select() in recvfrom_wto"); | 1261 | crash("select() in recvfrom_wto"); |
| 1285 | } | 1262 | } |
| 1263 | struct timeval now; | ||
| 1286 | gettimeofday(&now, &tz); | 1264 | gettimeofday(&now, &tz); |
| 1287 | *timo = get_timevaldiff(&then, &now); | 1265 | *timo = get_timevaldiff(&then, &now); |
| 1288 | 1266 | ||
| @@ -1290,12 +1268,14 @@ static int recvfrom_wto(int sock, void *buf, unsigned int len, struct sockaddr * | |||
| 1290 | return 0; /* timeout */ | 1268 | return 0; /* timeout */ |
| 1291 | } | 1269 | } |
| 1292 | 1270 | ||
| 1293 | slen = sizeof(struct sockaddr_storage); | 1271 | u_int slen = sizeof(struct sockaddr_storage); |
| 1294 | 1272 | ||
| 1273 | struct iovec iov; | ||
| 1295 | memset(&iov, 0, sizeof(iov)); | 1274 | memset(&iov, 0, sizeof(iov)); |
| 1296 | iov.iov_base = buf; | 1275 | iov.iov_base = buf; |
| 1297 | iov.iov_len = len; | 1276 | iov.iov_len = len; |
| 1298 | 1277 | ||
| 1278 | struct msghdr hdr; | ||
| 1299 | memset(&hdr, 0, sizeof(hdr)); | 1279 | memset(&hdr, 0, sizeof(hdr)); |
| 1300 | hdr.msg_name = saddr; | 1280 | hdr.msg_name = saddr; |
| 1301 | hdr.msg_namelen = slen; | 1281 | hdr.msg_namelen = slen; |
| @@ -1306,7 +1286,7 @@ static int recvfrom_wto(int sock, void *buf, unsigned int len, struct sockaddr * | |||
| 1306 | hdr.msg_controllen = sizeof(ans_data); | 1286 | hdr.msg_controllen = sizeof(ans_data); |
| 1307 | #endif | 1287 | #endif |
| 1308 | 1288 | ||
| 1309 | ret = recvmsg(sock, &hdr, 0); | 1289 | int ret = recvmsg(sock, &hdr, 0); |
| 1310 | #ifdef SO_TIMESTAMP | 1290 | #ifdef SO_TIMESTAMP |
| 1311 | for (chdr = CMSG_FIRSTHDR(&hdr); chdr; chdr = CMSG_NXTHDR(&hdr, chdr)) { | 1291 | for (chdr = CMSG_FIRSTHDR(&hdr); chdr; chdr = CMSG_NXTHDR(&hdr, chdr)) { |
| 1312 | if (chdr->cmsg_level == SOL_SOCKET && chdr->cmsg_type == SO_TIMESTAMP && chdr->cmsg_len >= CMSG_LEN(sizeof(struct timeval))) { | 1292 | if (chdr->cmsg_level == SOL_SOCKET && chdr->cmsg_type == SO_TIMESTAMP && chdr->cmsg_len >= CMSG_LEN(sizeof(struct timeval))) { |
| @@ -1322,16 +1302,6 @@ static int recvfrom_wto(int sock, void *buf, unsigned int len, struct sockaddr * | |||
| 1322 | } | 1302 | } |
| 1323 | 1303 | ||
| 1324 | static void finish(int sig) { | 1304 | static void finish(int sig) { |
| 1325 | u_int i = 0; | ||
| 1326 | unsigned char pl; | ||
| 1327 | double rta; | ||
| 1328 | struct rta_host *host; | ||
| 1329 | const char *status_string[] = {"OK", "WARNING", "CRITICAL", "UNKNOWN", "DEPENDENT"}; | ||
| 1330 | int hosts_ok = 0; | ||
| 1331 | int hosts_warn = 0; | ||
| 1332 | int this_status; | ||
| 1333 | double R; | ||
| 1334 | |||
| 1335 | alarm(0); | 1305 | alarm(0); |
| 1336 | if (debug > 1) { | 1306 | if (debug > 1) { |
| 1337 | printf("finish(%d) called\n", sig); | 1307 | printf("finish(%d) called\n", sig); |
| @@ -1354,11 +1324,17 @@ static void finish(int sig) { | |||
| 1354 | 1324 | ||
| 1355 | /* iterate thrice to calculate values, give output, and print perfparse */ | 1325 | /* iterate thrice to calculate values, give output, and print perfparse */ |
| 1356 | status = STATE_OK; | 1326 | status = STATE_OK; |
| 1357 | host = list; | 1327 | struct rta_host *host = list; |
| 1358 | 1328 | ||
| 1329 | u_int i = 0; | ||
| 1330 | const char *status_string[] = {"OK", "WARNING", "CRITICAL", "UNKNOWN", "DEPENDENT"}; | ||
| 1331 | int hosts_ok = 0; | ||
| 1332 | int hosts_warn = 0; | ||
| 1359 | while (host) { | 1333 | while (host) { |
| 1360 | this_status = STATE_OK; | 1334 | int this_status = STATE_OK; |
| 1361 | 1335 | ||
| 1336 | unsigned char pl; | ||
| 1337 | double rta; | ||
| 1362 | if (!host->icmp_recv) { | 1338 | if (!host->icmp_recv) { |
| 1363 | /* rta 0 is ofcourse not entirely correct, but will still show up | 1339 | /* rta 0 is ofcourse not entirely correct, but will still show up |
| 1364 | * conspicuously as missing entries in perfparse and cacti */ | 1340 | * conspicuously as missing entries in perfparse and cacti */ |
| @@ -1398,6 +1374,7 @@ static void finish(int sig) { | |||
| 1398 | */ | 1374 | */ |
| 1399 | host->EffectiveLatency = (rta / 1000) + host->jitter * 2 + 10; | 1375 | host->EffectiveLatency = (rta / 1000) + host->jitter * 2 + 10; |
| 1400 | 1376 | ||
| 1377 | double R; | ||
| 1401 | if (host->EffectiveLatency < 160) { | 1378 | if (host->EffectiveLatency < 160) { |
| 1402 | R = 93.2 - (host->EffectiveLatency / 40); | 1379 | R = 93.2 - (host->EffectiveLatency / 40); |
| 1403 | } else { | 1380 | } else { |
| @@ -1687,7 +1664,6 @@ static void finish(int sig) { | |||
| 1687 | } | 1664 | } |
| 1688 | 1665 | ||
| 1689 | static u_int get_timevaldiff(struct timeval *early, struct timeval *later) { | 1666 | static u_int get_timevaldiff(struct timeval *early, struct timeval *later) { |
| 1690 | u_int ret; | ||
| 1691 | struct timeval now; | 1667 | struct timeval now; |
| 1692 | 1668 | ||
| 1693 | if (!later) { | 1669 | if (!later) { |
| @@ -1702,19 +1678,15 @@ static u_int get_timevaldiff(struct timeval *early, struct timeval *later) { | |||
| 1702 | if (early->tv_sec > later->tv_sec || (early->tv_sec == later->tv_sec && early->tv_usec > later->tv_usec)) { | 1678 | if (early->tv_sec > later->tv_sec || (early->tv_sec == later->tv_sec && early->tv_usec > later->tv_usec)) { |
| 1703 | return 0; | 1679 | return 0; |
| 1704 | } | 1680 | } |
| 1705 | ret = (later->tv_sec - early->tv_sec) * 1000000; | 1681 | u_int ret = (later->tv_sec - early->tv_sec) * 1000000; |
| 1706 | ret += later->tv_usec - early->tv_usec; | 1682 | ret += later->tv_usec - early->tv_usec; |
| 1707 | 1683 | ||
| 1708 | return ret; | 1684 | return ret; |
| 1709 | } | 1685 | } |
| 1710 | 1686 | ||
| 1711 | static int add_target_ip(char *arg, struct sockaddr_storage *in) { | 1687 | static int add_target_ip(char *arg, struct sockaddr_storage *in) { |
| 1712 | struct rta_host *host; | ||
| 1713 | struct sockaddr_in *sin; | 1688 | struct sockaddr_in *sin; |
| 1714 | struct sockaddr_in *host_sin; | ||
| 1715 | struct sockaddr_in6 *sin6; | 1689 | struct sockaddr_in6 *sin6; |
| 1716 | struct sockaddr_in6 *host_sin6; | ||
| 1717 | |||
| 1718 | if (address_family == AF_INET) { | 1690 | if (address_family == AF_INET) { |
| 1719 | sin = (struct sockaddr_in *)in; | 1691 | sin = (struct sockaddr_in *)in; |
| 1720 | } else { | 1692 | } else { |
| @@ -1729,7 +1701,9 @@ static int add_target_ip(char *arg, struct sockaddr_storage *in) { | |||
| 1729 | } | 1701 | } |
| 1730 | 1702 | ||
| 1731 | /* no point in adding two identical IP's, so don't. ;) */ | 1703 | /* no point in adding two identical IP's, so don't. ;) */ |
| 1732 | host = list; | 1704 | struct sockaddr_in *host_sin; |
| 1705 | struct sockaddr_in6 *host_sin6; | ||
| 1706 | struct rta_host *host = list; | ||
| 1733 | while (host) { | 1707 | while (host) { |
| 1734 | host_sin = (struct sockaddr_in *)&host->saddr_in; | 1708 | host_sin = (struct sockaddr_in *)&host->saddr_in; |
| 1735 | host_sin6 = (struct sockaddr_in6 *)&host->saddr_in; | 1709 | host_sin6 = (struct sockaddr_in6 *)&host->saddr_in; |
| @@ -1797,14 +1771,10 @@ static int add_target_ip(char *arg, struct sockaddr_storage *in) { | |||
| 1797 | 1771 | ||
| 1798 | /* wrapper for add_target_ip */ | 1772 | /* wrapper for add_target_ip */ |
| 1799 | static int add_target(char *arg) { | 1773 | static int add_target(char *arg) { |
| 1800 | int error; | ||
| 1801 | int result = -1; | ||
| 1802 | struct sockaddr_storage ip; | 1774 | struct sockaddr_storage ip; |
| 1803 | struct addrinfo hints; | ||
| 1804 | struct addrinfo *res; | ||
| 1805 | struct addrinfo *p; | ||
| 1806 | struct sockaddr_in *sin; | 1775 | struct sockaddr_in *sin; |
| 1807 | struct sockaddr_in6 *sin6; | 1776 | struct sockaddr_in6 *sin6; |
| 1777 | int result = -1; | ||
| 1808 | 1778 | ||
| 1809 | switch (address_family) { | 1779 | switch (address_family) { |
| 1810 | case -1: | 1780 | case -1: |
| @@ -1841,6 +1811,8 @@ static int add_target(char *arg) { | |||
| 1841 | /* don't add all ip's if we were given a specific one */ | 1811 | /* don't add all ip's if we were given a specific one */ |
| 1842 | return add_target_ip(arg, &ip); | 1812 | return add_target_ip(arg, &ip); |
| 1843 | } | 1813 | } |
| 1814 | |||
| 1815 | struct addrinfo hints; | ||
| 1844 | errno = 0; | 1816 | errno = 0; |
| 1845 | memset(&hints, 0, sizeof(hints)); | 1817 | memset(&hints, 0, sizeof(hints)); |
| 1846 | if (address_family == -1) { | 1818 | if (address_family == -1) { |
| @@ -1849,6 +1821,9 @@ static int add_target(char *arg) { | |||
| 1849 | hints.ai_family = address_family == AF_INET ? PF_INET : PF_INET6; | 1821 | hints.ai_family = address_family == AF_INET ? PF_INET : PF_INET6; |
| 1850 | } | 1822 | } |
| 1851 | hints.ai_socktype = SOCK_RAW; | 1823 | hints.ai_socktype = SOCK_RAW; |
| 1824 | |||
| 1825 | int error; | ||
| 1826 | struct addrinfo *res; | ||
| 1852 | if ((error = getaddrinfo(arg, NULL, &hints, &res)) != 0) { | 1827 | if ((error = getaddrinfo(arg, NULL, &hints, &res)) != 0) { |
| 1853 | errno = 0; | 1828 | errno = 0; |
| 1854 | crash("Failed to resolve %s: %s", arg, gai_strerror(error)); | 1829 | crash("Failed to resolve %s: %s", arg, gai_strerror(error)); |
| @@ -1857,7 +1832,7 @@ static int add_target(char *arg) { | |||
| 1857 | address_family = res->ai_family; | 1832 | address_family = res->ai_family; |
| 1858 | 1833 | ||
| 1859 | /* possibly add all the IP's as targets */ | 1834 | /* possibly add all the IP's as targets */ |
| 1860 | for (p = res; p != NULL; p = p->ai_next) { | 1835 | for (struct addrinfo *p = res; p != NULL; p = p->ai_next) { |
| 1861 | memcpy(&ip, p->ai_addr, p->ai_addrlen); | 1836 | memcpy(&ip, p->ai_addr, p->ai_addrlen); |
| 1862 | add_target_ip(arg, &ip); | 1837 | add_target_ip(arg, &ip); |
| 1863 | 1838 | ||
| @@ -1920,26 +1895,19 @@ static in_addr_t get_ip_address(const char *ifname) { | |||
| 1920 | * return value is in microseconds | 1895 | * return value is in microseconds |
| 1921 | */ | 1896 | */ |
| 1922 | static u_int get_timevar(const char *str) { | 1897 | static u_int get_timevar(const char *str) { |
| 1923 | char p; | ||
| 1924 | char u; | ||
| 1925 | char *ptr; | ||
| 1926 | size_t len; | ||
| 1927 | u_int i; | ||
| 1928 | u_int d; /* integer and decimal, respectively */ | ||
| 1929 | u_int factor = 1000; /* default to milliseconds */ | ||
| 1930 | |||
| 1931 | if (!str) { | 1898 | if (!str) { |
| 1932 | return 0; | 1899 | return 0; |
| 1933 | } | 1900 | } |
| 1934 | len = strlen(str); | 1901 | |
| 1902 | size_t len = strlen(str); | ||
| 1935 | if (!len) { | 1903 | if (!len) { |
| 1936 | return 0; | 1904 | return 0; |
| 1937 | } | 1905 | } |
| 1938 | 1906 | ||
| 1939 | /* unit might be given as ms|m (millisec), | 1907 | /* unit might be given as ms|m (millisec), |
| 1940 | * us|u (microsec) or just plain s, for seconds */ | 1908 | * us|u (microsec) or just plain s, for seconds */ |
| 1941 | p = '\0'; | 1909 | char p = '\0'; |
| 1942 | u = str[len - 1]; | 1910 | char u = str[len - 1]; |
| 1943 | if (len >= 2 && !isdigit((int)str[len - 2])) { | 1911 | if (len >= 2 && !isdigit((int)str[len - 2])) { |
| 1944 | p = str[len - 2]; | 1912 | p = str[len - 2]; |
| 1945 | } | 1913 | } |
| @@ -1952,6 +1920,7 @@ static u_int get_timevar(const char *str) { | |||
| 1952 | printf("evaluating %s, u: %c, p: %c\n", str, u, p); | 1920 | printf("evaluating %s, u: %c, p: %c\n", str, u, p); |
| 1953 | } | 1921 | } |
| 1954 | 1922 | ||
| 1923 | u_int factor = 1000; /* default to milliseconds */ | ||
| 1955 | if (u == 'u') { | 1924 | if (u == 'u') { |
| 1956 | factor = 1; /* microseconds */ | 1925 | factor = 1; /* microseconds */ |
| 1957 | } else if (u == 'm') { | 1926 | } else if (u == 'm') { |
| @@ -1963,6 +1932,8 @@ static u_int get_timevar(const char *str) { | |||
| 1963 | printf("factor is %u\n", factor); | 1932 | printf("factor is %u\n", factor); |
| 1964 | } | 1933 | } |
| 1965 | 1934 | ||
| 1935 | char *ptr; | ||
| 1936 | u_int i; | ||
| 1966 | i = strtoul(str, &ptr, 0); | 1937 | i = strtoul(str, &ptr, 0); |
| 1967 | if (!ptr || *ptr != '.' || strlen(ptr) < 2 || factor == 1) { | 1938 | if (!ptr || *ptr != '.' || strlen(ptr) < 2 || factor == 1) { |
| 1968 | return i * factor; | 1939 | return i * factor; |
| @@ -1973,7 +1944,8 @@ static u_int get_timevar(const char *str) { | |||
| 1973 | return i; | 1944 | return i; |
| 1974 | } | 1945 | } |
| 1975 | 1946 | ||
| 1976 | d = strtoul(ptr + 1, NULL, 0); | 1947 | /* integer and decimal, respectively */ |
| 1948 | u_int d = strtoul(ptr + 1, NULL, 0); | ||
| 1977 | 1949 | ||
| 1978 | /* d is decimal, so get rid of excess digits */ | 1950 | /* d is decimal, so get rid of excess digits */ |
| 1979 | while (d >= factor) { | 1951 | while (d >= factor) { |
| @@ -1986,15 +1958,13 @@ static u_int get_timevar(const char *str) { | |||
| 1986 | 1958 | ||
| 1987 | /* not too good at checking errors, but it'll do (main() should barfe on -1) */ | 1959 | /* not too good at checking errors, but it'll do (main() should barfe on -1) */ |
| 1988 | static int get_threshold(char *str, threshold *th) { | 1960 | static int get_threshold(char *str, threshold *th) { |
| 1989 | char *p = NULL; | ||
| 1990 | char i = 0; | ||
| 1991 | |||
| 1992 | if (!str || !strlen(str) || !th) { | 1961 | if (!str || !strlen(str) || !th) { |
| 1993 | return -1; | 1962 | return -1; |
| 1994 | } | 1963 | } |
| 1995 | 1964 | ||
| 1996 | /* pointer magic slims code by 10 lines. i is bof-stop on stupid libc's */ | 1965 | /* pointer magic slims code by 10 lines. i is bof-stop on stupid libc's */ |
| 1997 | p = &str[strlen(str) - 1]; | 1966 | char i = 0; |
| 1967 | char *p = &str[strlen(str) - 1]; | ||
| 1998 | while (p != &str[1]) { | 1968 | while (p != &str[1]) { |
| 1999 | if (*p == '%') { | 1969 | if (*p == '%') { |
| 2000 | *p = '\0'; | 1970 | *p = '\0'; |
| @@ -2098,7 +2068,6 @@ static bool parse_threshold2_helper(char *s, size_t length, threshold *thr, thre | |||
| 2098 | } | 2068 | } |
| 2099 | 2069 | ||
| 2100 | unsigned short icmp_checksum(uint16_t *p, size_t n) { | 2070 | unsigned short icmp_checksum(uint16_t *p, size_t n) { |
| 2101 | unsigned short cksum; | ||
| 2102 | long sum = 0; | 2071 | long sum = 0; |
| 2103 | 2072 | ||
| 2104 | /* sizeof(uint16_t) == 2 */ | 2073 | /* sizeof(uint16_t) == 2 */ |
| @@ -2114,7 +2083,8 @@ unsigned short icmp_checksum(uint16_t *p, size_t n) { | |||
| 2114 | 2083 | ||
| 2115 | sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ | 2084 | sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ |
| 2116 | sum += (sum >> 16); /* add carry */ | 2085 | sum += (sum >> 16); /* add carry */ |
| 2117 | cksum = ~sum; /* ones-complement, trunc to 16 bits */ | 2086 | unsigned short cksum; |
| 2087 | cksum = ~sum; /* ones-complement, trunc to 16 bits */ | ||
| 2118 | 2088 | ||
| 2119 | return cksum; | 2089 | return cksum; |
| 2120 | } | 2090 | } |
