diff options
Diffstat (limited to 'plugins-root/t')
0 files changed, 0 insertions, 0 deletions
diff --git a/plugins-root/check_icmp.c b/plugins-root/check_icmp.c index 8b563e4..f420837 100644 --- a/plugins-root/check_icmp.c +++ b/plugins-root/check_icmp.c | |||
@@ -184,7 +184,7 @@ static u_int get_timevar(const char *); | |||
184 | static u_int get_timevaldiff(struct timeval *, struct timeval *); | 184 | static u_int get_timevaldiff(struct timeval *, struct timeval *); |
185 | static in_addr_t get_ip_address(const char *); | 185 | static in_addr_t get_ip_address(const char *); |
186 | static int wait_for_reply(int, u_int); | 186 | static int wait_for_reply(int, u_int); |
187 | static int recvfrom_wto(int, void *, unsigned int, struct sockaddr *, u_int *); | 187 | static int recvfrom_wto(int, void *, unsigned int, struct sockaddr *, u_int *, struct timeval*); |
188 | static int send_icmp_ping(int, struct rta_host *); | 188 | static int send_icmp_ping(int, struct rta_host *); |
189 | static int get_threshold(char *str, threshold *th); | 189 | static int get_threshold(char *str, threshold *th); |
190 | static void run_checks(void); | 190 | static void run_checks(void); |
@@ -378,6 +378,9 @@ main(int argc, char **argv) | |||
378 | int icmp_sockerrno, udp_sockerrno, tcp_sockerrno; | 378 | int icmp_sockerrno, udp_sockerrno, tcp_sockerrno; |
379 | int result; | 379 | int result; |
380 | struct rta_host *host; | 380 | struct rta_host *host; |
381 | #ifdef SO_TIMESTAMP | ||
382 | int on = 1; | ||
383 | #endif | ||
381 | 384 | ||
382 | setlocale (LC_ALL, ""); | 385 | setlocale (LC_ALL, ""); |
383 | bindtextdomain (PACKAGE, LOCALEDIR); | 386 | bindtextdomain (PACKAGE, LOCALEDIR); |
@@ -402,6 +405,11 @@ main(int argc, char **argv) | |||
402 | /* now drop privileges (no effect if not setsuid or geteuid() == 0) */ | 405 | /* now drop privileges (no effect if not setsuid or geteuid() == 0) */ |
403 | setuid(getuid()); | 406 | setuid(getuid()); |
404 | 407 | ||
408 | #ifdef SO_TIMESTAMP | ||
409 | if(setsockopt(icmp_sock, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on))) | ||
410 | if(debug) printf("Warning: no SO_TIMESTAMP support\n"); | ||
411 | #endif // SO_TIMESTAMP | ||
412 | |||
405 | /* POSIXLY_CORRECT might break things, so unset it (the portable way) */ | 413 | /* POSIXLY_CORRECT might break things, so unset it (the portable way) */ |
406 | environ = NULL; | 414 | environ = NULL; |
407 | 415 | ||
@@ -462,13 +470,13 @@ main(int argc, char **argv) | |||
462 | /* parse the arguments */ | 470 | /* parse the arguments */ |
463 | for(i = 1; i < argc; i++) { | 471 | for(i = 1; i < argc; i++) { |
464 | while((arg = getopt(argc, argv, "vhVw:c:n:p:t:H:s:i:b:I:l:m:")) != EOF) { | 472 | while((arg = getopt(argc, argv, "vhVw:c:n:p:t:H:s:i:b:I:l:m:")) != EOF) { |
465 | long size; | 473 | unsigned short size; |
466 | switch(arg) { | 474 | switch(arg) { |
467 | case 'v': | 475 | case 'v': |
468 | debug++; | 476 | debug++; |
469 | break; | 477 | break; |
470 | case 'b': | 478 | case 'b': |
471 | size = strtol(optarg,NULL,0); | 479 | size = (unsigned short)strtol(optarg,NULL,0); |
472 | if (size >= (sizeof(struct icmp) + sizeof(struct icmp_ping_data)) && | 480 | if (size >= (sizeof(struct icmp) + sizeof(struct icmp_ping_data)) && |
473 | size < MAX_PING_DATA) { | 481 | size < MAX_PING_DATA) { |
474 | icmp_data_size = size; | 482 | icmp_data_size = size; |
@@ -727,7 +735,7 @@ wait_for_reply(int sock, u_int t) | |||
727 | 735 | ||
728 | /* reap responses until we hit a timeout */ | 736 | /* reap responses until we hit a timeout */ |
729 | n = recvfrom_wto(sock, buf, sizeof(buf), | 737 | n = recvfrom_wto(sock, buf, sizeof(buf), |
730 | (struct sockaddr *)&resp_addr, &t); | 738 | (struct sockaddr *)&resp_addr, &t, &now); |
731 | if(!n) { | 739 | if(!n) { |
732 | if(debug > 1) { | 740 | if(debug > 1) { |
733 | printf("recvfrom_wto() timed out during a %u usecs wait\n", | 741 | printf("recvfrom_wto() timed out during a %u usecs wait\n", |
@@ -777,11 +785,11 @@ wait_for_reply(int sock, u_int t) | |||
777 | /* this is indeed a valid response */ | 785 | /* this is indeed a valid response */ |
778 | memcpy(&data, icp.icmp_data, sizeof(data)); | 786 | memcpy(&data, icp.icmp_data, sizeof(data)); |
779 | if (debug > 2) | 787 | if (debug > 2) |
780 | printf("ICMP echo-reply of len %u, id %u, seq %u, cksum 0x%X\n", | 788 | printf("ICMP echo-reply of len %lu, id %u, seq %u, cksum 0x%X\n", |
781 | sizeof(data), ntohs(icp.icmp_id), ntohs(icp.icmp_seq), icp.icmp_cksum); | 789 | (unsigned long)sizeof(data), ntohs(icp.icmp_id), |
790 | ntohs(icp.icmp_seq), icp.icmp_cksum); | ||
782 | 791 | ||
783 | host = table[ntohs(icp.icmp_seq)/packets]; | 792 | host = table[ntohs(icp.icmp_seq)/packets]; |
784 | gettimeofday(&now, &tz); | ||
785 | tdiff = get_timevaldiff(&data.stime, &now); | 793 | tdiff = get_timevaldiff(&data.stime, &now); |
786 | 794 | ||
787 | host->time_waited += tdiff; | 795 | host->time_waited += tdiff; |
@@ -823,6 +831,8 @@ send_icmp_ping(int sock, struct rta_host *host) | |||
823 | } packet = { NULL }; | 831 | } packet = { NULL }; |
824 | long int len; | 832 | long int len; |
825 | struct icmp_ping_data data; | 833 | struct icmp_ping_data data; |
834 | struct msghdr hdr; | ||
835 | struct iovec iov; | ||
826 | struct timeval tv; | 836 | struct timeval tv; |
827 | struct sockaddr *addr; | 837 | struct sockaddr *addr; |
828 | 838 | ||
@@ -855,11 +865,27 @@ send_icmp_ping(int sock, struct rta_host *host) | |||
855 | packet.icp->icmp_cksum = icmp_checksum(packet.cksum_in, icmp_pkt_size); | 865 | packet.icp->icmp_cksum = icmp_checksum(packet.cksum_in, icmp_pkt_size); |
856 | 866 | ||
857 | if (debug > 2) | 867 | if (debug > 2) |
858 | printf("Sending ICMP echo-request of len %u, id %u, seq %u, cksum 0x%X to host %s\n", | 868 | printf("Sending ICMP echo-request of len %lu, id %u, seq %u, cksum 0x%X to host %s\n", |
859 | sizeof(data), ntohs(packet.icp->icmp_id), ntohs(packet.icp->icmp_seq), packet.icp->icmp_cksum, host->name); | 869 | (unsigned long)sizeof(data), ntohs(packet.icp->icmp_id), |
860 | 870 | ntohs(packet.icp->icmp_seq), packet.icp->icmp_cksum, | |
861 | len = sendto(sock, packet.buf, icmp_pkt_size, 0, (struct sockaddr *)addr, | 871 | host->name); |
862 | sizeof(struct sockaddr)); | 872 | |
873 | memset(&iov, 0, sizeof(iov)); | ||
874 | iov.iov_base = packet.buf; | ||
875 | iov.iov_len = icmp_pkt_size; | ||
876 | |||
877 | memset(&hdr, 0, sizeof(hdr)); | ||
878 | hdr.msg_name = addr; | ||
879 | hdr.msg_namelen = sizeof(struct sockaddr); | ||
880 | hdr.msg_iov = &iov; | ||
881 | hdr.msg_iovlen = 1; | ||
882 | |||
883 | /* MSG_CONFIRM is a linux thing and only available on linux kernels >= 2.3.15, see send(2) */ | ||
884 | #ifdef MSG_CONFIRM | ||
885 | len = sendmsg(sock, &hdr, MSG_CONFIRM); | ||
886 | #else | ||
887 | len = sendmsg(sock, &hdr, 0); | ||
888 | #endif | ||
863 | 889 | ||
864 | if(len < 0 || (unsigned int)len != icmp_pkt_size) { | 890 | if(len < 0 || (unsigned int)len != icmp_pkt_size) { |
865 | if(debug) printf("Failed to send ping to %s\n", | 891 | if(debug) printf("Failed to send ping to %s\n", |
@@ -875,12 +901,18 @@ send_icmp_ping(int sock, struct rta_host *host) | |||
875 | 901 | ||
876 | static int | 902 | static int |
877 | recvfrom_wto(int sock, void *buf, unsigned int len, struct sockaddr *saddr, | 903 | recvfrom_wto(int sock, void *buf, unsigned int len, struct sockaddr *saddr, |
878 | u_int *timo) | 904 | u_int *timo, struct timeval* tv) |
879 | { | 905 | { |
880 | u_int slen; | 906 | u_int slen; |
881 | int n; | 907 | int n, ret; |
882 | struct timeval to, then, now; | 908 | struct timeval to, then, now; |
883 | fd_set rd, wr; | 909 | fd_set rd, wr; |
910 | char ans_data[4096]; | ||
911 | struct msghdr hdr; | ||
912 | struct iovec iov; | ||
913 | #ifdef SO_TIMESTAMP | ||
914 | struct cmsghdr* chdr; | ||
915 | #endif | ||
884 | 916 | ||
885 | if(!*timo) { | 917 | if(!*timo) { |
886 | if(debug) printf("*timo is not\n"); | 918 | if(debug) printf("*timo is not\n"); |
@@ -904,7 +936,32 @@ recvfrom_wto(int sock, void *buf, unsigned int len, struct sockaddr *saddr, | |||
904 | 936 | ||
905 | slen = sizeof(struct sockaddr); | 937 | slen = sizeof(struct sockaddr); |
906 | 938 | ||
907 | return recvfrom(sock, buf, len, 0, saddr, &slen); | 939 | memset(&iov, 0, sizeof(iov)); |
940 | iov.iov_base = buf; | ||
941 | iov.iov_len = len; | ||
942 | |||
943 | memset(&hdr, 0, sizeof(hdr)); | ||
944 | hdr.msg_name = saddr; | ||
945 | hdr.msg_namelen = slen; | ||
946 | hdr.msg_iov = &iov; | ||
947 | hdr.msg_iovlen = 1; | ||
948 | hdr.msg_control = ans_data; | ||
949 | hdr.msg_controllen = sizeof(ans_data); | ||
950 | |||
951 | ret = recvmsg(sock, &hdr, 0); | ||
952 | #ifdef SO_TIMESTAMP | ||
953 | for(chdr = CMSG_FIRSTHDR(&hdr); chdr; chdr = CMSG_NXTHDR(&hdr, chdr)) { | ||
954 | if(chdr->cmsg_level == SOL_SOCKET | ||
955 | && chdr->cmsg_type == SO_TIMESTAMP | ||
956 | && chdr->cmsg_len >= CMSG_LEN(sizeof(struct timeval))) { | ||
957 | memcpy(tv, CMSG_DATA(chdr), sizeof(*tv)); | ||
958 | break ; | ||
959 | } | ||
960 | } | ||
961 | if (!chdr) | ||
962 | #endif // SO_TIMESTAMP | ||
963 | gettimeofday(tv, &tz); | ||
964 | return (ret); | ||
908 | } | 965 | } |
909 | 966 | ||
910 | static void | 967 | static void |
@@ -1183,7 +1240,7 @@ static u_int | |||
1183 | get_timevar(const char *str) | 1240 | get_timevar(const char *str) |
1184 | { | 1241 | { |
1185 | char p, u, *ptr; | 1242 | char p, u, *ptr; |
1186 | unsigned int len; | 1243 | size_t len; |
1187 | u_int i, d; /* integer and decimal, respectively */ | 1244 | u_int i, d; /* integer and decimal, respectively */ |
1188 | u_int factor = 1000; /* default to milliseconds */ | 1245 | u_int factor = 1000; /* default to milliseconds */ |
1189 | 1246 | ||