diff options
Diffstat (limited to 'plugins-root')
-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 | } |