summaryrefslogtreecommitdiffstats
path: root/plugins-root
diff options
context:
space:
mode:
Diffstat (limited to 'plugins-root')
-rw-r--r--plugins-root/check_icmp.c89
1 files changed, 73 insertions, 16 deletions
diff --git a/plugins-root/check_icmp.c b/plugins-root/check_icmp.c
index 8b563e40..f4208371 100644
--- a/plugins-root/check_icmp.c
+++ b/plugins-root/check_icmp.c
@@ -184,7 +184,7 @@ static u_int get_timevar(const char *);
184static u_int get_timevaldiff(struct timeval *, struct timeval *); 184static u_int get_timevaldiff(struct timeval *, struct timeval *);
185static in_addr_t get_ip_address(const char *); 185static in_addr_t get_ip_address(const char *);
186static int wait_for_reply(int, u_int); 186static int wait_for_reply(int, u_int);
187static int recvfrom_wto(int, void *, unsigned int, struct sockaddr *, u_int *); 187static int recvfrom_wto(int, void *, unsigned int, struct sockaddr *, u_int *, struct timeval*);
188static int send_icmp_ping(int, struct rta_host *); 188static int send_icmp_ping(int, struct rta_host *);
189static int get_threshold(char *str, threshold *th); 189static int get_threshold(char *str, threshold *th);
190static void run_checks(void); 190static 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
876static int 902static int
877recvfrom_wto(int sock, void *buf, unsigned int len, struct sockaddr *saddr, 903recvfrom_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
910static void 967static void
@@ -1183,7 +1240,7 @@ static u_int
1183get_timevar(const char *str) 1240get_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