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" ); | ||
