summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plugins-root/check_icmp.c208
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 **/
263static void crash(const char *fmt, ...) { 264static 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
384static int handle_random_icmp(unsigned char *packet, struct sockaddr_storage *addr) { 385static 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
465int main(int argc, char **argv) { 464int 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
881static void run_checks(void) { 873static 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 */
943static int wait_for_reply(int sock, u_int t) { 930static 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 */
1145static int send_icmp_ping(int sock, struct rta_host *host) { 1126static 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
1249static int recvfrom_wto(int sock, void *buf, unsigned int len, struct sockaddr *saddr, u_int *timo, struct timeval *tv) { 1231static 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
1324static void finish(int sig) { 1304static 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
1689static u_int get_timevaldiff(struct timeval *early, struct timeval *later) { 1666static 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
1711static int add_target_ip(char *arg, struct sockaddr_storage *in) { 1687static 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 */
1799static int add_target(char *arg) { 1773static 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 */
1922static u_int get_timevar(const char *str) { 1897static 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) */
1988static int get_threshold(char *str, threshold *th) { 1960static 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
2100unsigned short icmp_checksum(uint16_t *p, size_t n) { 2070unsigned 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}