diff options
Diffstat (limited to 'plugins-root')
-rw-r--r-- | plugins-root/check_icmp.c | 98 | ||||
-rw-r--r-- | plugins-root/check_icmp.d/config.h | 2 |
2 files changed, 65 insertions, 35 deletions
diff --git a/plugins-root/check_icmp.c b/plugins-root/check_icmp.c index a57edef4..dad03ffa 100644 --- a/plugins-root/check_icmp.c +++ b/plugins-root/check_icmp.c | |||
@@ -138,7 +138,11 @@ void print_help(); | |||
138 | void print_usage(void); | 138 | void print_usage(void); |
139 | 139 | ||
140 | /* Time related */ | 140 | /* Time related */ |
141 | static unsigned int get_timevar(const char *str); | 141 | typedef struct { |
142 | int error_code; | ||
143 | time_t time_range; | ||
144 | } get_timevar_wrapper; | ||
145 | static get_timevar_wrapper get_timevar(const char *str); | ||
142 | static time_t get_timevaldiff(struct timeval earlier, struct timeval later); | 146 | static time_t get_timevaldiff(struct timeval earlier, struct timeval later); |
143 | static time_t get_timevaldiff_to_now(struct timeval earlier); | 147 | static time_t get_timevaldiff_to_now(struct timeval earlier); |
144 | 148 | ||
@@ -196,8 +200,8 @@ static parse_threshold2_helper_wrapper parse_threshold2_helper(char *threshold_s | |||
196 | /* main test function */ | 200 | /* main test function */ |
197 | static void run_checks(unsigned short icmp_pkt_size, time_t *pkt_interval, time_t *target_interval, | 201 | static void run_checks(unsigned short icmp_pkt_size, time_t *pkt_interval, time_t *target_interval, |
198 | uint16_t sender_id, check_icmp_execution_mode mode, | 202 | uint16_t sender_id, check_icmp_execution_mode mode, |
199 | unsigned int max_completion_time, struct timeval prog_start, | 203 | time_t max_completion_time, struct timeval prog_start, ping_target **table, |
200 | ping_target **table, unsigned short packets, check_icmp_socket_set sockset, | 204 | unsigned short packets, check_icmp_socket_set sockset, |
201 | unsigned short number_of_targets, check_icmp_state *program_state); | 205 | unsigned short number_of_targets, check_icmp_state *program_state); |
202 | mp_subcheck evaluate_target(ping_target target, check_icmp_mode_switches modes, | 206 | mp_subcheck evaluate_target(ping_target target, check_icmp_mode_switches modes, |
203 | check_icmp_threshold warn, check_icmp_threshold crit); | 207 | check_icmp_threshold warn, check_icmp_threshold crit); |
@@ -249,7 +253,7 @@ static void finish(int sign, check_icmp_mode_switches modes, int min_hosts_alive | |||
249 | mp_check overall[static 1]); | 253 | mp_check overall[static 1]); |
250 | 254 | ||
251 | /* Error exit */ | 255 | /* Error exit */ |
252 | static void crash(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); | 256 | static void crash(const char *fmt, ...) __attribute__((format(printf, 1, 2))); |
253 | 257 | ||
254 | /** global variables **/ | 258 | /** global variables **/ |
255 | static int debug = 0; | 259 | static int debug = 0; |
@@ -384,12 +388,24 @@ check_icmp_config_wrapper process_arguments(int argc, char **argv) { | |||
384 | MAX_PING_DATA - 1); | 388 | MAX_PING_DATA - 1); |
385 | } | 389 | } |
386 | } break; | 390 | } break; |
387 | case 'i': | 391 | case 'i': { |
388 | result.config.pkt_interval = get_timevar(optarg); | 392 | get_timevar_wrapper parsed_time = get_timevar(optarg); |
389 | break; | 393 | |
390 | case 'I': | 394 | if (parsed_time.error_code == OK) { |
391 | result.config.target_interval = get_timevar(optarg); | 395 | result.config.pkt_interval = parsed_time.time_range; |
392 | break; | 396 | } else { |
397 | crash("failed to parse packet interval"); | ||
398 | } | ||
399 | } break; | ||
400 | case 'I': { | ||
401 | get_timevar_wrapper parsed_time = get_timevar(optarg); | ||
402 | |||
403 | if (parsed_time.error_code == OK) { | ||
404 | result.config.target_interval = parsed_time.time_range; | ||
405 | } else { | ||
406 | crash("failed to parse target interval"); | ||
407 | } | ||
408 | } break; | ||
393 | case 'w': { | 409 | case 'w': { |
394 | get_threshold_wrapper warn = get_threshold(optarg, result.config.warn); | 410 | get_threshold_wrapper warn = get_threshold(optarg, result.config.warn); |
395 | if (warn.errorcode == OK) { | 411 | if (warn.errorcode == OK) { |
@@ -575,7 +591,7 @@ static void crash(const char *fmt, ...) { | |||
575 | puts(""); | 591 | puts(""); |
576 | 592 | ||
577 | exit(3); | 593 | exit(3); |
578 | } | 594 | } |
579 | 595 | ||
580 | static const char *get_icmp_error_msg(unsigned char icmp_type, unsigned char icmp_code) { | 596 | static const char *get_icmp_error_msg(unsigned char icmp_type, unsigned char icmp_code) { |
581 | const char *msg = "unreachable"; | 597 | const char *msg = "unreachable"; |
@@ -743,8 +759,8 @@ static int handle_random_icmp(unsigned char *packet, struct sockaddr_storage *ad | |||
743 | /* source quench means we're sending too fast, so increase the | 759 | /* source quench means we're sending too fast, so increase the |
744 | * interval and mark this packet lost */ | 760 | * interval and mark this packet lost */ |
745 | if (icmp_packet.icmp_type == ICMP_SOURCEQUENCH) { | 761 | if (icmp_packet.icmp_type == ICMP_SOURCEQUENCH) { |
746 | *pkt_interval = (unsigned int)(*pkt_interval * PACKET_BACKOFF_FACTOR); | 762 | *pkt_interval = (unsigned int)((double)*pkt_interval * PACKET_BACKOFF_FACTOR); |
747 | *target_interval = (unsigned int)(*target_interval * TARGET_BACKOFF_FACTOR); | 763 | *target_interval = (unsigned int)((double)*target_interval * TARGET_BACKOFF_FACTOR); |
748 | } else { | 764 | } else { |
749 | program_state->targets_down++; | 765 | program_state->targets_down++; |
750 | host->flags |= FLAG_LOST_CAUSE; | 766 | host->flags |= FLAG_LOST_CAUSE; |
@@ -899,7 +915,7 @@ int main(int argc, char **argv) { | |||
899 | gettimeofday(&prog_start, NULL); | 915 | gettimeofday(&prog_start, NULL); |
900 | 916 | ||
901 | time_t max_completion_time = | 917 | time_t max_completion_time = |
902 | ((config.pkt_interval *config.number_of_targets * config.number_of_packets) + | 918 | ((config.pkt_interval * config.number_of_targets * config.number_of_packets) + |
903 | (config.target_interval * config.number_of_targets)) + | 919 | (config.target_interval * config.number_of_targets)) + |
904 | (config.number_of_targets * config.number_of_packets * config.crit.rta) + config.crit.rta; | 920 | (config.number_of_targets * config.number_of_packets * config.crit.rta) + config.crit.rta; |
905 | 921 | ||
@@ -921,7 +937,7 @@ int main(int argc, char **argv) { | |||
921 | } | 937 | } |
922 | 938 | ||
923 | if (debug) { | 939 | if (debug) { |
924 | printf("crit = {%u, %u%%}, warn = {%u, %u%%}\n", config.crit.rta, config.crit.pl, | 940 | printf("crit = {%ld, %u%%}, warn = {%ld, %u%%}\n", config.crit.rta, config.crit.pl, |
925 | config.warn.rta, config.warn.pl); | 941 | config.warn.rta, config.warn.pl); |
926 | printf("pkt_interval: %ld target_interval: %ld\n", config.pkt_interval, | 942 | printf("pkt_interval: %ld target_interval: %ld\n", config.pkt_interval, |
927 | config.target_interval); | 943 | config.target_interval); |
@@ -976,7 +992,7 @@ int main(int argc, char **argv) { | |||
976 | 992 | ||
977 | static void run_checks(unsigned short icmp_pkt_size, time_t *pkt_interval, time_t *target_interval, | 993 | static void run_checks(unsigned short icmp_pkt_size, time_t *pkt_interval, time_t *target_interval, |
978 | const uint16_t sender_id, const check_icmp_execution_mode mode, | 994 | const uint16_t sender_id, const check_icmp_execution_mode mode, |
979 | const unsigned int max_completion_time, const struct timeval prog_start, | 995 | const time_t max_completion_time, const struct timeval prog_start, |
980 | ping_target **table, const unsigned short packets, | 996 | ping_target **table, const unsigned short packets, |
981 | const check_icmp_socket_set sockset, const unsigned short number_of_targets, | 997 | const check_icmp_socket_set sockset, const unsigned short number_of_targets, |
982 | check_icmp_state *program_state) { | 998 | check_icmp_state *program_state) { |
@@ -1028,7 +1044,7 @@ static void run_checks(unsigned short icmp_pkt_size, time_t *pkt_interval, time_ | |||
1028 | time_t final_wait = max_completion_time - time_passed; | 1044 | time_t final_wait = max_completion_time - time_passed; |
1029 | 1045 | ||
1030 | if (debug) { | 1046 | if (debug) { |
1031 | printf("time_passed: %ld final_wait: %ld max_completion_time: %u\n", time_passed, | 1047 | printf("time_passed: %ld final_wait: %ld max_completion_time: %ld\n", time_passed, |
1032 | final_wait, max_completion_time); | 1048 | final_wait, max_completion_time); |
1033 | } | 1049 | } |
1034 | if (time_passed > max_completion_time) { | 1050 | if (time_passed > max_completion_time) { |
@@ -1138,7 +1154,6 @@ static int wait_for_reply(check_icmp_socket_set sockset, const time_t time_inter | |||
1138 | parse_address(&resp_addr, address, sizeof(address)); | 1154 | parse_address(&resp_addr, address, sizeof(address)); |
1139 | crash("received packet too short for ICMP (%ld bytes, expected %d) from %s\n", | 1155 | crash("received packet too short for ICMP (%ld bytes, expected %d) from %s\n", |
1140 | recv_foo.received, hlen + icmp_pkt_size, address); | 1156 | recv_foo.received, hlen + icmp_pkt_size, address); |
1141 | |||
1142 | } | 1157 | } |
1143 | /* check the response */ | 1158 | /* check the response */ |
1144 | memcpy(packet.buf, buf + hlen, icmp_pkt_size); | 1159 | memcpy(packet.buf, buf + hlen, icmp_pkt_size); |
@@ -1272,7 +1287,7 @@ static int send_icmp_ping(const check_icmp_socket_set sockset, ping_target *host | |||
1272 | data.ping_id = 10; /* host->icmp.icmp_sent; */ | 1287 | data.ping_id = 10; /* host->icmp.icmp_sent; */ |
1273 | memcpy(&data.stime, ¤t_time, sizeof(current_time)); | 1288 | memcpy(&data.stime, ¤t_time, sizeof(current_time)); |
1274 | 1289 | ||
1275 | socklen_t addrlen; | 1290 | socklen_t addrlen = 0; |
1276 | 1291 | ||
1277 | if (host->address.ss_family == AF_INET) { | 1292 | if (host->address.ss_family == AF_INET) { |
1278 | struct icmp *icp = (struct icmp *)buf; | 1293 | struct icmp *icp = (struct icmp *)buf; |
@@ -1789,14 +1804,21 @@ static in_addr_t get_ip_address(const char *ifname) { | |||
1789 | * s = seconds | 1804 | * s = seconds |
1790 | * return value is in microseconds | 1805 | * return value is in microseconds |
1791 | */ | 1806 | */ |
1792 | static unsigned int get_timevar(const char *str) { | 1807 | static get_timevar_wrapper get_timevar(const char *str) { |
1808 | get_timevar_wrapper result = { | ||
1809 | .error_code = OK, | ||
1810 | .time_range = 0, | ||
1811 | }; | ||
1812 | |||
1793 | if (!str) { | 1813 | if (!str) { |
1794 | return 0; | 1814 | result.error_code = ERROR; |
1815 | return result; | ||
1795 | } | 1816 | } |
1796 | 1817 | ||
1797 | size_t len = strlen(str); | 1818 | size_t len = strlen(str); |
1798 | if (!len) { | 1819 | if (!len) { |
1799 | return 0; | 1820 | result.error_code = ERROR; |
1821 | return result; | ||
1800 | } | 1822 | } |
1801 | 1823 | ||
1802 | /* unit might be given as ms|m (millisec), | 1824 | /* unit might be given as ms|m (millisec), |
@@ -1834,12 +1856,14 @@ static unsigned int get_timevar(const char *str) { | |||
1834 | unsigned long pre_radix; | 1856 | unsigned long pre_radix; |
1835 | pre_radix = strtoul(str, &ptr, 0); | 1857 | pre_radix = strtoul(str, &ptr, 0); |
1836 | if (!ptr || *ptr != '.' || strlen(ptr) < 2 || factor == 1) { | 1858 | if (!ptr || *ptr != '.' || strlen(ptr) < 2 || factor == 1) { |
1837 | return (unsigned int)(pre_radix * factor); | 1859 | result.time_range = (unsigned int)(pre_radix * factor); |
1860 | return result; | ||
1838 | } | 1861 | } |
1839 | 1862 | ||
1840 | /* time specified in usecs can't have decimal points, so ignore them */ | 1863 | /* time specified in usecs can't have decimal points, so ignore them */ |
1841 | if (factor == 1) { | 1864 | if (factor == 1) { |
1842 | return (unsigned int)pre_radix; | 1865 | result.time_range = (unsigned int)pre_radix; |
1866 | return result; | ||
1843 | } | 1867 | } |
1844 | 1868 | ||
1845 | /* integer and decimal, respectively */ | 1869 | /* integer and decimal, respectively */ |
@@ -1851,10 +1875,10 @@ static unsigned int get_timevar(const char *str) { | |||
1851 | } | 1875 | } |
1852 | 1876 | ||
1853 | /* the last parenthesis avoids floating point exceptions. */ | 1877 | /* the last parenthesis avoids floating point exceptions. */ |
1854 | return (unsigned int)((pre_radix * factor) + (post_radix * (factor / 10))); | 1878 | result.time_range = (unsigned int)((pre_radix * factor) + (post_radix * (factor / 10))); |
1879 | return result; | ||
1855 | } | 1880 | } |
1856 | 1881 | ||
1857 | /* not too good at checking errors, but it'll do (main() should barfe on -1) */ | ||
1858 | static get_threshold_wrapper get_threshold(char *str, check_icmp_threshold threshold) { | 1882 | static get_threshold_wrapper get_threshold(char *str, check_icmp_threshold threshold) { |
1859 | get_threshold_wrapper result = { | 1883 | get_threshold_wrapper result = { |
1860 | .errorcode = OK, | 1884 | .errorcode = OK, |
@@ -1880,9 +1904,15 @@ static get_threshold_wrapper get_threshold(char *str, check_icmp_threshold thres | |||
1880 | is_at_last_char = true; | 1904 | is_at_last_char = true; |
1881 | tmp--; | 1905 | tmp--; |
1882 | } | 1906 | } |
1883 | result.threshold.rta = get_timevar(str); | ||
1884 | 1907 | ||
1885 | if (!result.threshold.rta) { | 1908 | get_timevar_wrapper parsed_time = get_timevar(str); |
1909 | |||
1910 | if (parsed_time.error_code == OK) { | ||
1911 | result.threshold.rta = parsed_time.time_range; | ||
1912 | } else { | ||
1913 | if (debug > 1) { | ||
1914 | printf("%s: failed to parse rta threshold\n", __FUNCTION__); | ||
1915 | } | ||
1886 | result.errorcode = ERROR; | 1916 | result.errorcode = ERROR; |
1887 | return result; | 1917 | return result; |
1888 | } | 1918 | } |
@@ -2170,7 +2200,7 @@ mp_subcheck evaluate_target(ping_target target, check_icmp_mode_switches modes, | |||
2170 | xasprintf(&result.output, "%s", address); | 2200 | xasprintf(&result.output, "%s", address); |
2171 | 2201 | ||
2172 | double packet_loss; | 2202 | double packet_loss; |
2173 | double rta; | 2203 | time_t rta; |
2174 | if (!target.icmp_recv) { | 2204 | if (!target.icmp_recv) { |
2175 | /* rta 0 is of course not entirely correct, but will still show up | 2205 | /* rta 0 is of course not entirely correct, but will still show up |
2176 | * conspicuously as missing entries in perfparse and cacti */ | 2206 | * conspicuously as missing entries in perfparse and cacti */ |
@@ -2188,7 +2218,7 @@ mp_subcheck evaluate_target(ping_target target, check_icmp_mode_switches modes, | |||
2188 | } else { | 2218 | } else { |
2189 | packet_loss = | 2219 | packet_loss = |
2190 | (unsigned char)((target.icmp_sent - target.icmp_recv) * 100) / target.icmp_sent; | 2220 | (unsigned char)((target.icmp_sent - target.icmp_recv) * 100) / target.icmp_sent; |
2191 | rta = (double)target.time_waited / target.icmp_recv; | 2221 | rta = target.time_waited / target.icmp_recv; |
2192 | } | 2222 | } |
2193 | 2223 | ||
2194 | double EffectiveLatency; | 2224 | double EffectiveLatency; |
@@ -2219,7 +2249,7 @@ mp_subcheck evaluate_target(ping_target target, check_icmp_mode_switches modes, | |||
2219 | * round trip jitter, but double the impact to latency | 2249 | * round trip jitter, but double the impact to latency |
2220 | * then add 10 for protocol latencies (in milliseconds). | 2250 | * then add 10 for protocol latencies (in milliseconds). |
2221 | */ | 2251 | */ |
2222 | EffectiveLatency = (rta / 1000) + target.jitter * 2 + 10; | 2252 | EffectiveLatency = ((double)rta / 1000) + target.jitter * 2 + 10; |
2223 | 2253 | ||
2224 | double R; | 2254 | double R; |
2225 | if (EffectiveLatency < 160) { | 2255 | if (EffectiveLatency < 160) { |
@@ -2249,14 +2279,14 @@ mp_subcheck evaluate_target(ping_target target, check_icmp_mode_switches modes, | |||
2249 | if (modes.rta_mode) { | 2279 | if (modes.rta_mode) { |
2250 | mp_subcheck sc_rta = mp_subcheck_init(); | 2280 | mp_subcheck sc_rta = mp_subcheck_init(); |
2251 | sc_rta = mp_set_subcheck_default_state(sc_rta, STATE_OK); | 2281 | sc_rta = mp_set_subcheck_default_state(sc_rta, STATE_OK); |
2252 | xasprintf(&sc_rta.output, "rta %0.3fms", rta / 1000); | 2282 | xasprintf(&sc_rta.output, "rta %0.3fms", (double)rta / 1000); |
2253 | 2283 | ||
2254 | if (rta >= crit.rta) { | 2284 | if (rta >= crit.rta) { |
2255 | sc_rta = mp_set_subcheck_state(sc_rta, STATE_CRITICAL); | 2285 | sc_rta = mp_set_subcheck_state(sc_rta, STATE_CRITICAL); |
2256 | xasprintf(&sc_rta.output, "%s > %0.3fms", sc_rta.output, (double) crit.rta / 1000); | 2286 | xasprintf(&sc_rta.output, "%s > %0.3fms", sc_rta.output, (double)crit.rta / 1000); |
2257 | } else if (rta >= warn.rta) { | 2287 | } else if (rta >= warn.rta) { |
2258 | sc_rta = mp_set_subcheck_state(sc_rta, STATE_WARNING); | 2288 | sc_rta = mp_set_subcheck_state(sc_rta, STATE_WARNING); |
2259 | xasprintf(&sc_rta.output, "%s > %0.3fms", sc_rta.output, (double) warn.rta / 1000); | 2289 | xasprintf(&sc_rta.output, "%s > %0.3fms", sc_rta.output, (double)warn.rta / 1000); |
2260 | } | 2290 | } |
2261 | 2291 | ||
2262 | if (packet_loss < 100) { | 2292 | if (packet_loss < 100) { |
diff --git a/plugins-root/check_icmp.d/config.h b/plugins-root/check_icmp.d/config.h index 97be7fc1..fc9dd5a6 100644 --- a/plugins-root/check_icmp.d/config.h +++ b/plugins-root/check_icmp.d/config.h | |||
@@ -16,7 +16,7 @@ | |||
16 | /* threshold structure. all values are maximum allowed, exclusive */ | 16 | /* threshold structure. all values are maximum allowed, exclusive */ |
17 | typedef struct { | 17 | typedef struct { |
18 | unsigned char pl; /* max allowed packet loss in percent */ | 18 | unsigned char pl; /* max allowed packet loss in percent */ |
19 | unsigned int rta; /* roundtrip time average, microseconds */ | 19 | time_t rta; /* roundtrip time average, microseconds */ |
20 | double jitter; /* jitter time average, microseconds */ | 20 | double jitter; /* jitter time average, microseconds */ |
21 | double mos; /* MOS */ | 21 | double mos; /* MOS */ |
22 | double score; /* Score */ | 22 | double score; /* Score */ |