diff options
-rw-r--r-- | plugins-root/check_icmp.c | 66 | ||||
-rw-r--r-- | plugins-root/t/check_icmp.t | 7 |
2 files changed, 43 insertions, 30 deletions
diff --git a/plugins-root/check_icmp.c b/plugins-root/check_icmp.c index f97b0ed7..61198237 100644 --- a/plugins-root/check_icmp.c +++ b/plugins-root/check_icmp.c | |||
@@ -50,19 +50,11 @@ const char *email = "devel@monitoring-plugins.org"; | |||
50 | #if HAVE_SYS_SOCKIO_H | 50 | #if HAVE_SYS_SOCKIO_H |
51 | #include <sys/sockio.h> | 51 | #include <sys/sockio.h> |
52 | #endif | 52 | #endif |
53 | #include <sys/ioctl.h> | 53 | |
54 | #include <sys/time.h> | 54 | #include <sys/time.h> |
55 | #include <sys/types.h> | ||
56 | #include <stdio.h> | ||
57 | #include <stdlib.h> | ||
58 | #include <stdarg.h> | ||
59 | #include <unistd.h> | ||
60 | #include <stddef.h> | ||
61 | #include <errno.h> | 55 | #include <errno.h> |
62 | #include <string.h> | 56 | #include <signal.h> |
63 | #include <ctype.h> | 57 | #include <ctype.h> |
64 | #include <netdb.h> | ||
65 | #include <sys/socket.h> | ||
66 | #include <net/if.h> | 58 | #include <net/if.h> |
67 | #include <netinet/in_systm.h> | 59 | #include <netinet/in_systm.h> |
68 | #include <netinet/in.h> | 60 | #include <netinet/in.h> |
@@ -71,8 +63,6 @@ const char *email = "devel@monitoring-plugins.org"; | |||
71 | #include <netinet/ip_icmp.h> | 63 | #include <netinet/ip_icmp.h> |
72 | #include <netinet/icmp6.h> | 64 | #include <netinet/icmp6.h> |
73 | #include <arpa/inet.h> | 65 | #include <arpa/inet.h> |
74 | #include <signal.h> | ||
75 | #include <float.h> | ||
76 | 66 | ||
77 | 67 | ||
78 | /** sometimes undefined system macros (quite a few, actually) **/ | 68 | /** sometimes undefined system macros (quite a few, actually) **/ |
@@ -207,7 +197,7 @@ static int add_target(char *); | |||
207 | static int add_target_ip(char *, struct sockaddr_storage *); | 197 | static int add_target_ip(char *, struct sockaddr_storage *); |
208 | static int handle_random_icmp(unsigned char *, struct sockaddr_storage *); | 198 | static int handle_random_icmp(unsigned char *, struct sockaddr_storage *); |
209 | static void parse_address(struct sockaddr_storage *, char *, int); | 199 | static void parse_address(struct sockaddr_storage *, char *, int); |
210 | static unsigned short icmp_checksum(unsigned short *, int); | 200 | static unsigned short icmp_checksum(uint16_t *, size_t); |
211 | static void finish(int); | 201 | static void finish(int); |
212 | static void crash(const char *, ...); | 202 | static void crash(const char *, ...); |
213 | 203 | ||
@@ -465,7 +455,6 @@ main(int argc, char **argv) | |||
465 | /* Parse protocol arguments first */ | 455 | /* Parse protocol arguments first */ |
466 | for(i = 1; i < argc; i++) { | 456 | for(i = 1; i < argc; i++) { |
467 | while((arg = getopt(argc, argv, opts_str)) != EOF) { | 457 | while((arg = getopt(argc, argv, opts_str)) != EOF) { |
468 | unsigned short size; | ||
469 | switch(arg) { | 458 | switch(arg) { |
470 | case '4': | 459 | case '4': |
471 | if (address_family != -1) | 460 | if (address_family != -1) |
@@ -488,10 +477,10 @@ main(int argc, char **argv) | |||
488 | /* Reset argument scanning */ | 477 | /* Reset argument scanning */ |
489 | optind = 1; | 478 | optind = 1; |
490 | 479 | ||
480 | unsigned short size; | ||
491 | /* parse the arguments */ | 481 | /* parse the arguments */ |
492 | for(i = 1; i < argc; i++) { | 482 | for(i = 1; i < argc; i++) { |
493 | while((arg = getopt(argc, argv, opts_str)) != EOF) { | 483 | while((arg = getopt(argc, argv, opts_str)) != EOF) { |
494 | unsigned short size; | ||
495 | switch(arg) { | 484 | switch(arg) { |
496 | case 'v': | 485 | case 'v': |
497 | debug++; | 486 | debug++; |
@@ -720,7 +709,7 @@ main(int argc, char **argv) | |||
720 | static void | 709 | static void |
721 | run_checks() | 710 | run_checks() |
722 | { | 711 | { |
723 | u_int i, t, result; | 712 | u_int i, t; |
724 | u_int final_wait, time_passed; | 713 | u_int final_wait, time_passed; |
725 | 714 | ||
726 | /* this loop might actually violate the pkt_interval or target_interval | 715 | /* this loop might actually violate the pkt_interval or target_interval |
@@ -738,9 +727,9 @@ run_checks() | |||
738 | 727 | ||
739 | /* we're still in the game, so send next packet */ | 728 | /* we're still in the game, so send next packet */ |
740 | (void)send_icmp_ping(icmp_sock, table[t]); | 729 | (void)send_icmp_ping(icmp_sock, table[t]); |
741 | result = wait_for_reply(icmp_sock, target_interval); | 730 | wait_for_reply(icmp_sock, target_interval); |
742 | } | 731 | } |
743 | result = wait_for_reply(icmp_sock, pkt_interval * targets); | 732 | wait_for_reply(icmp_sock, pkt_interval * targets); |
744 | } | 733 | } |
745 | 734 | ||
746 | if(icmp_pkts_en_route && targets_alive) { | 735 | if(icmp_pkts_en_route && targets_alive) { |
@@ -760,7 +749,7 @@ run_checks() | |||
760 | * haven't yet */ | 749 | * haven't yet */ |
761 | if(debug) printf("Waiting for %u micro-seconds (%0.3f msecs)\n", | 750 | if(debug) printf("Waiting for %u micro-seconds (%0.3f msecs)\n", |
762 | final_wait, (float)final_wait / 1000); | 751 | final_wait, (float)final_wait / 1000); |
763 | result = wait_for_reply(icmp_sock, final_wait); | 752 | wait_for_reply(icmp_sock, final_wait); |
764 | } | 753 | } |
765 | } | 754 | } |
766 | 755 | ||
@@ -779,7 +768,7 @@ static int | |||
779 | wait_for_reply(int sock, u_int t) | 768 | wait_for_reply(int sock, u_int t) |
780 | { | 769 | { |
781 | int n, hlen; | 770 | int n, hlen; |
782 | static unsigned char buf[4096]; | 771 | static unsigned char buf[65536]; |
783 | struct sockaddr_storage resp_addr; | 772 | struct sockaddr_storage resp_addr; |
784 | union ip_hdr *ip; | 773 | union ip_hdr *ip; |
785 | union icmp_packet packet; | 774 | union icmp_packet packet; |
@@ -916,9 +905,27 @@ wait_for_reply(int sock, u_int t) | |||
916 | if(debug) { | 905 | if(debug) { |
917 | char address[INET6_ADDRSTRLEN]; | 906 | char address[INET6_ADDRSTRLEN]; |
918 | parse_address(&resp_addr, address, sizeof(address)); | 907 | parse_address(&resp_addr, address, sizeof(address)); |
919 | printf("%0.3f ms rtt from %s, outgoing ttl: %u, incoming ttl: %u, max: %0.3f, min: %0.3f\n", | 908 | |
920 | (float)tdiff / 1000, address, | 909 | switch(address_family) { |
921 | ttl, ip->ip.ip_ttl, (float)host->rtmax / 1000, (float)host->rtmin / 1000); | 910 | case AF_INET: { |
911 | printf("%0.3f ms rtt from %s, outgoing ttl: %u, incoming ttl: %u, max: %0.3f, min: %0.3f\n", | ||
912 | (float)tdiff / 1000, | ||
913 | address, | ||
914 | ttl, | ||
915 | ip->ip.ip_ttl, | ||
916 | (float)host->rtmax / 1000, | ||
917 | (float)host->rtmin / 1000); | ||
918 | break; | ||
919 | }; | ||
920 | case AF_INET6: { | ||
921 | printf("%0.3f ms rtt from %s, outgoing ttl: %u, max: %0.3f, min: %0.3f\n", | ||
922 | (float)tdiff / 1000, | ||
923 | address, | ||
924 | ttl, | ||
925 | (float)host->rtmax / 1000, | ||
926 | (float)host->rtmin / 1000); | ||
927 | }; | ||
928 | } | ||
922 | } | 929 | } |
923 | 930 | ||
924 | /* if we're in hostcheck mode, exit with limited printouts */ | 931 | /* if we're in hostcheck mode, exit with limited printouts */ |
@@ -980,7 +987,7 @@ send_icmp_ping(int sock, struct rta_host *host) | |||
980 | icp->icmp_cksum = 0; | 987 | icp->icmp_cksum = 0; |
981 | icp->icmp_id = htons(pid); | 988 | icp->icmp_id = htons(pid); |
982 | icp->icmp_seq = htons(host->id++); | 989 | icp->icmp_seq = htons(host->id++); |
983 | icp->icmp_cksum = icmp_checksum((unsigned short*)buf, icmp_pkt_size); | 990 | icp->icmp_cksum = icmp_checksum((uint16_t*)buf, (size_t)icmp_pkt_size); |
984 | 991 | ||
985 | if (debug > 2) | 992 | if (debug > 2) |
986 | printf("Sending ICMP echo-request of len %lu, id %u, seq %u, cksum 0x%X to host %s\n", | 993 | printf("Sending ICMP echo-request of len %lu, id %u, seq %u, cksum 0x%X to host %s\n", |
@@ -1517,18 +1524,19 @@ get_threshold(char *str, threshold *th) | |||
1517 | } | 1524 | } |
1518 | 1525 | ||
1519 | unsigned short | 1526 | unsigned short |
1520 | icmp_checksum(unsigned short *p, int n) | 1527 | icmp_checksum(uint16_t *p, size_t n) |
1521 | { | 1528 | { |
1522 | unsigned short cksum; | 1529 | unsigned short cksum; |
1523 | long sum = 0; | 1530 | long sum = 0; |
1524 | 1531 | ||
1525 | while(n > 2) { | 1532 | /* sizeof(uint16_t) == 2 */ |
1526 | sum += *p++; | 1533 | while(n >= 2) { |
1527 | n -= sizeof(unsigned short); | 1534 | sum += *(p++); |
1535 | n -= 2; | ||
1528 | } | 1536 | } |
1529 | 1537 | ||
1530 | /* mop up the occasional odd byte */ | 1538 | /* mop up the occasional odd byte */ |
1531 | if(n == 1) sum += (unsigned char)*p; | 1539 | if(n == 1) sum += *((uint8_t *)p -1); |
1532 | 1540 | ||
1533 | sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ | 1541 | sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ |
1534 | sum += (sum >> 16); /* add carry */ | 1542 | sum += (sum >> 16); /* add carry */ |
diff --git a/plugins-root/t/check_icmp.t b/plugins-root/t/check_icmp.t index 55edc31b..f6aa6813 100644 --- a/plugins-root/t/check_icmp.t +++ b/plugins-root/t/check_icmp.t | |||
@@ -12,7 +12,7 @@ my $allow_sudo = getTestParameter( "NP_ALLOW_SUDO", | |||
12 | "no" ); | 12 | "no" ); |
13 | 13 | ||
14 | if ($allow_sudo eq "yes" or $> == 0) { | 14 | if ($allow_sudo eq "yes" or $> == 0) { |
15 | plan tests => 18; | 15 | plan tests => 20; |
16 | } else { | 16 | } else { |
17 | plan skip_all => "Need sudo to test check_icmp"; | 17 | plan skip_all => "Need sudo to test check_icmp"; |
18 | } | 18 | } |
@@ -89,3 +89,8 @@ $res = NPTest->testCmd( | |||
89 | is( $res->return_code, 0, "IPv4 source_ip accepted" ); | 89 | is( $res->return_code, 0, "IPv4 source_ip accepted" ); |
90 | like( $res->output, $successOutput, "Output OK" ); | 90 | like( $res->output, $successOutput, "Output OK" ); |
91 | 91 | ||
92 | $res = NPTest->testCmd( | ||
93 | "$sudo ./check_icmp -H $host_responsive -b 65507" | ||
94 | ); | ||
95 | is( $res->return_code, 0, "Try max paket size" ); | ||
96 | like( $res->output, $successOutput, "Output OK - Didn't overflow" ); | ||