diff options
Diffstat (limited to 'plugins-root')
| -rw-r--r-- | plugins-root/check_icmp.c | 69 |
1 files changed, 43 insertions, 26 deletions
diff --git a/plugins-root/check_icmp.c b/plugins-root/check_icmp.c index d46d2ccc..5bfb5cb5 100644 --- a/plugins-root/check_icmp.c +++ b/plugins-root/check_icmp.c | |||
| @@ -54,6 +54,9 @@ const char *email = "devel@monitoring-plugins.org"; | |||
| 54 | #endif | 54 | #endif |
| 55 | 55 | ||
| 56 | #include <sys/time.h> | 56 | #include <sys/time.h> |
| 57 | #if defined(SIOCGIFADDR) | ||
| 58 | # include <sys/ioctl.h> | ||
| 59 | #endif /* SIOCGIFADDR */ | ||
| 57 | #include <errno.h> | 60 | #include <errno.h> |
| 58 | #include <signal.h> | 61 | #include <signal.h> |
| 59 | #include <ctype.h> | 62 | #include <ctype.h> |
| @@ -146,7 +149,7 @@ static get_timevar_wrapper get_timevar(const char *str); | |||
| 146 | static time_t get_timevaldiff(struct timeval earlier, struct timeval later); | 149 | static time_t get_timevaldiff(struct timeval earlier, struct timeval later); |
| 147 | static time_t get_timevaldiff_to_now(struct timeval earlier); | 150 | static time_t get_timevaldiff_to_now(struct timeval earlier); |
| 148 | 151 | ||
| 149 | static in_addr_t get_ip_address(const char *ifname); | 152 | static in_addr_t get_ip_address(const char *ifname, const int icmp_sock); |
| 150 | static void set_source_ip(char *arg, int icmp_sock, sa_family_t addr_family); | 153 | static void set_source_ip(char *arg, int icmp_sock, sa_family_t addr_family); |
| 151 | 154 | ||
| 152 | /* Receiving data */ | 155 | /* Receiving data */ |
| @@ -1467,10 +1470,13 @@ static recvfrom_wto_wrapper recvfrom_wto(const check_icmp_socket_set sockset, vo | |||
| 1467 | }; | 1470 | }; |
| 1468 | 1471 | ||
| 1469 | ssize_t ret; | 1472 | ssize_t ret; |
| 1470 | if (FD_ISSET(sockset.socket4, &read_fds)) { | 1473 | |
| 1474 | // Test explicitly whether sockets are in use | ||
| 1475 | // this is necessary at least on OpenBSD where FD_ISSET will segfault otherwise | ||
| 1476 | if ((sockset.socket4 != -1) && FD_ISSET(sockset.socket4, &read_fds)) { | ||
| 1471 | ret = recvmsg(sockset.socket4, &hdr, 0); | 1477 | ret = recvmsg(sockset.socket4, &hdr, 0); |
| 1472 | result.recv_proto = AF_INET; | 1478 | result.recv_proto = AF_INET; |
| 1473 | } else if (FD_ISSET(sockset.socket6, &read_fds)) { | 1479 | } else if ((sockset.socket6 != -1) && FD_ISSET(sockset.socket6, &read_fds)) { |
| 1474 | ret = recvmsg(sockset.socket6, &hdr, 0); | 1480 | ret = recvmsg(sockset.socket6, &hdr, 0); |
| 1475 | result.recv_proto = AF_INET6; | 1481 | result.recv_proto = AF_INET6; |
| 1476 | } else { | 1482 | } else { |
| @@ -1769,7 +1775,7 @@ static void set_source_ip(char *arg, const int icmp_sock, sa_family_t addr_famil | |||
| 1769 | memset(&src, 0, sizeof(src)); | 1775 | memset(&src, 0, sizeof(src)); |
| 1770 | src.sin_family = addr_family; | 1776 | src.sin_family = addr_family; |
| 1771 | if ((src.sin_addr.s_addr = inet_addr(arg)) == INADDR_NONE) { | 1777 | if ((src.sin_addr.s_addr = inet_addr(arg)) == INADDR_NONE) { |
| 1772 | src.sin_addr.s_addr = get_ip_address(arg); | 1778 | src.sin_addr.s_addr = get_ip_address(arg, icmp_sock); |
| 1773 | } | 1779 | } |
| 1774 | if (bind(icmp_sock, (struct sockaddr *)&src, sizeof(src)) == -1) { | 1780 | if (bind(icmp_sock, (struct sockaddr *)&src, sizeof(src)) == -1) { |
| 1775 | crash("Cannot bind to IP address %s", arg); | 1781 | crash("Cannot bind to IP address %s", arg); |
| @@ -1777,8 +1783,9 @@ static void set_source_ip(char *arg, const int icmp_sock, sa_family_t addr_famil | |||
| 1777 | } | 1783 | } |
| 1778 | 1784 | ||
| 1779 | /* TODO: Move this to netutils.c and also change check_dhcp to use that. */ | 1785 | /* TODO: Move this to netutils.c and also change check_dhcp to use that. */ |
| 1780 | static in_addr_t get_ip_address(const char *ifname) { | 1786 | static in_addr_t get_ip_address(const char *ifname, const int icmp_sock) { |
| 1781 | // TODO: Rewrite this so the function return an error and we exit somewhere else | 1787 | // TODO: Rewrite this so the function return an error and we exit somewhere else |
| 1788 | |||
| 1782 | struct sockaddr_in ip_address; | 1789 | struct sockaddr_in ip_address; |
| 1783 | ip_address.sin_addr.s_addr = 0; // Fake initialization to make compiler happy | 1790 | ip_address.sin_addr.s_addr = 0; // Fake initialization to make compiler happy |
| 1784 | #if defined(SIOCGIFADDR) | 1791 | #if defined(SIOCGIFADDR) |
| @@ -1792,8 +1799,11 @@ static in_addr_t get_ip_address(const char *ifname) { | |||
| 1792 | crash("Cannot determine IP address of interface %s", ifname); | 1799 | crash("Cannot determine IP address of interface %s", ifname); |
| 1793 | } | 1800 | } |
| 1794 | 1801 | ||
| 1795 | memcpy(&ip, &ifr.ifr_addr, sizeof(ip)); | 1802 | memcpy(&ip_address, &ifr.ifr_addr, sizeof(ip_address)); |
| 1796 | #else | 1803 | #else |
| 1804 | // fake operation to make the compiler happy | ||
| 1805 | (void)icmp_sock; | ||
| 1806 | |||
| 1797 | (void)ifname; | 1807 | (void)ifname; |
| 1798 | errno = 0; | 1808 | errno = 0; |
| 1799 | crash("Cannot get interface IP address on this platform."); | 1809 | crash("Cannot get interface IP address on this platform."); |
| @@ -2043,7 +2053,7 @@ unsigned short icmp_checksum(uint16_t *packet, size_t packet_size) { | |||
| 2043 | 2053 | ||
| 2044 | /* mop up the occasional odd byte */ | 2054 | /* mop up the occasional odd byte */ |
| 2045 | if (packet_size == 1) { | 2055 | if (packet_size == 1) { |
| 2046 | sum += *((uint8_t *)packet - 1); | 2056 | sum += *((uint8_t *)packet); |
| 2047 | } | 2057 | } |
| 2048 | 2058 | ||
| 2049 | sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ | 2059 | sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ |
| @@ -2242,7 +2252,7 @@ mp_subcheck evaluate_target(ping_target target, check_icmp_mode_switches modes, | |||
| 2242 | * round trip jitter, but double the impact to latency | 2252 | * round trip jitter, but double the impact to latency |
| 2243 | * then add 10 for protocol latencies (in milliseconds). | 2253 | * then add 10 for protocol latencies (in milliseconds). |
| 2244 | */ | 2254 | */ |
| 2245 | EffectiveLatency = ((double)rta / 1000) + target.jitter * 2 + 10; | 2255 | EffectiveLatency = ((double)rta / 1000) + (target.jitter * 2) + 10; |
| 2246 | 2256 | ||
| 2247 | double R; | 2257 | double R; |
| 2248 | if (EffectiveLatency < 160) { | 2258 | if (EffectiveLatency < 160) { |
| @@ -2401,25 +2411,32 @@ mp_subcheck evaluate_target(ping_target target, check_icmp_mode_switches modes, | |||
| 2401 | if (modes.score_mode) { | 2411 | if (modes.score_mode) { |
| 2402 | mp_subcheck sc_score = mp_subcheck_init(); | 2412 | mp_subcheck sc_score = mp_subcheck_init(); |
| 2403 | sc_score = mp_set_subcheck_default_state(sc_score, STATE_OK); | 2413 | sc_score = mp_set_subcheck_default_state(sc_score, STATE_OK); |
| 2404 | xasprintf(&sc_score.output, "Score %f", score); | ||
| 2405 | |||
| 2406 | if (score <= crit.score) { | ||
| 2407 | sc_score = mp_set_subcheck_state(sc_score, STATE_CRITICAL); | ||
| 2408 | xasprintf(&sc_score.output, "%s <= %f", sc_score.output, crit.score); | ||
| 2409 | } else if (score <= warn.score) { | ||
| 2410 | sc_score = mp_set_subcheck_state(sc_score, STATE_WARNING); | ||
| 2411 | xasprintf(&sc_score.output, "%s <= %f", sc_score.output, warn.score); | ||
| 2412 | } | ||
| 2413 | 2414 | ||
| 2414 | if (packet_loss < 100) { | 2415 | if (target.icmp_recv > 1) { |
| 2415 | mp_perfdata pd_score = perfdata_init(); | 2416 | xasprintf(&sc_score.output, "Score %f", score); |
| 2416 | xasprintf(&pd_score.label, "%sscore", address); | 2417 | |
| 2417 | pd_score.value = mp_create_pd_value(score); | 2418 | if (score <= crit.score) { |
| 2418 | pd_score.warn = mp_range_set_end(pd_score.warn, mp_create_pd_value(warn.score)); | 2419 | sc_score = mp_set_subcheck_state(sc_score, STATE_CRITICAL); |
| 2419 | pd_score.crit = mp_range_set_end(pd_score.crit, mp_create_pd_value(crit.score)); | 2420 | xasprintf(&sc_score.output, "%s <= %f", sc_score.output, crit.score); |
| 2420 | pd_score.min = mp_create_pd_value(0); | 2421 | } else if (score <= warn.score) { |
| 2421 | pd_score.max = mp_create_pd_value(100); | 2422 | sc_score = mp_set_subcheck_state(sc_score, STATE_WARNING); |
| 2422 | mp_add_perfdata_to_subcheck(&sc_score, pd_score); | 2423 | xasprintf(&sc_score.output, "%s <= %f", sc_score.output, warn.score); |
| 2424 | } | ||
| 2425 | |||
| 2426 | if (packet_loss < 100) { | ||
| 2427 | mp_perfdata pd_score = perfdata_init(); | ||
| 2428 | xasprintf(&pd_score.label, "%sscore", address); | ||
| 2429 | pd_score.value = mp_create_pd_value(score); | ||
| 2430 | pd_score.warn = mp_range_set_end(pd_score.warn, mp_create_pd_value(warn.score)); | ||
| 2431 | pd_score.crit = mp_range_set_end(pd_score.crit, mp_create_pd_value(crit.score)); | ||
| 2432 | pd_score.min = mp_create_pd_value(0); | ||
| 2433 | pd_score.max = mp_create_pd_value(100); | ||
| 2434 | mp_add_perfdata_to_subcheck(&sc_score, pd_score); | ||
| 2435 | } | ||
| 2436 | |||
| 2437 | } else { | ||
| 2438 | // score mode disabled due to not enough received packages | ||
| 2439 | xasprintf(&sc_score.output, "Score mode disabled, not enough packets received"); | ||
| 2423 | } | 2440 | } |
| 2424 | 2441 | ||
| 2425 | mp_add_subcheck_to_subcheck(&result, sc_score); | 2442 | mp_add_subcheck_to_subcheck(&result, sc_score); |
