diff options
| author | Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> | 2025-05-05 22:52:56 +0200 |
|---|---|---|
| committer | Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> | 2025-05-05 22:52:56 +0200 |
| commit | 5fd8191a50df6be712c9143ca6d73de7878f57d1 (patch) | |
| tree | 67afdf36446aafa30f7b6daf56895dd233f01b4b | |
| parent | 5a6adcb7db497fba7b89471a6d58dba80330ff4a (diff) | |
| download | monitoring-plugins-5fd8191a50df6be712c9143ca6d73de7878f57d1.tar.gz | |
WIP - check_icmp refactor 3
| -rw-r--r-- | plugins-root/check_icmp.c | 150 | ||||
| -rw-r--r-- | plugins-root/check_icmp.d/check_icmp_helpers.c | 25 | ||||
| -rw-r--r-- | plugins-root/check_icmp.d/config.h | 58 |
3 files changed, 118 insertions, 115 deletions
diff --git a/plugins-root/check_icmp.c b/plugins-root/check_icmp.c index 99414014..9d163678 100644 --- a/plugins-root/check_icmp.c +++ b/plugins-root/check_icmp.c | |||
| @@ -142,37 +142,38 @@ static void set_source_ip(char * /*arg*/, int icmp_sock); | |||
| 142 | 142 | ||
| 143 | /* Receiving data */ | 143 | /* Receiving data */ |
| 144 | static int wait_for_reply(int socket, time_t time_interval, unsigned short icmp_pkt_size, | 144 | static int wait_for_reply(int socket, time_t time_interval, unsigned short icmp_pkt_size, |
| 145 | unsigned int *pkt_interval, unsigned int *target_interval, pid_t pid, | 145 | unsigned int *pkt_interval, unsigned int *target_interval, |
| 146 | ping_target **table, unsigned short packets, | 146 | uint16_t sender_id, ping_target **table, unsigned short packets, |
| 147 | unsigned short number_of_targets, check_icmp_state *program_state); | 147 | unsigned short number_of_targets, check_icmp_state *program_state); |
| 148 | 148 | ||
| 149 | static ssize_t recvfrom_wto(int /*sock*/, void * /*buf*/, unsigned int /*len*/, | 149 | static ssize_t recvfrom_wto(int /*sock*/, void * /*buf*/, unsigned int /*len*/, |
| 150 | struct sockaddr * /*saddr*/, time_t *timeout, struct timeval * /*tv*/); | 150 | struct sockaddr * /*saddr*/, time_t *timeout, struct timeval * /*tv*/); |
| 151 | static int handle_random_icmp(unsigned char * /*packet*/, struct sockaddr_storage * /*addr*/, | 151 | static int handle_random_icmp(unsigned char * /*packet*/, struct sockaddr_storage * /*addr*/, |
| 152 | unsigned int *pkt_interval, unsigned int *target_interval, pid_t pid, | 152 | unsigned int *pkt_interval, unsigned int *target_interval, uint16_t sender_id, |
| 153 | ping_target **table, unsigned short packets, | 153 | ping_target **table, unsigned short packets, |
| 154 | unsigned short number_of_targets, check_icmp_state *program_state); | 154 | unsigned short number_of_targets, check_icmp_state *program_state); |
| 155 | 155 | ||
| 156 | /* Sending data */ | 156 | /* Sending data */ |
| 157 | static int send_icmp_ping(int /*sock*/, ping_target * /*host*/, unsigned short icmp_pkt_size, | 157 | static int send_icmp_ping(int /*sock*/, ping_target * /*host*/, unsigned short icmp_pkt_size, |
| 158 | pid_t pid, check_icmp_state *program_state); | 158 | uint16_t sender_id, check_icmp_state *program_state); |
| 159 | 159 | ||
| 160 | /* Threshold related */ | 160 | /* Threshold related */ |
| 161 | static int get_threshold(char *str, threshold *threshold); | 161 | static int get_threshold(char *str, check_icmp_threshold *threshold); |
| 162 | static bool get_threshold2(char *str, size_t length, threshold * /*warn*/, threshold * /*crit*/, | 162 | static bool get_threshold2(char *str, size_t length, check_icmp_threshold * /*warn*/, |
| 163 | threshold_mode mode); | 163 | check_icmp_threshold * /*crit*/, threshold_mode mode); |
| 164 | static bool parse_threshold2_helper(char *threshold_string, size_t length, threshold *thr, | 164 | static bool parse_threshold2_helper(char *threshold_string, size_t length, |
| 165 | threshold_mode mode); | 165 | check_icmp_threshold *thr, threshold_mode mode); |
| 166 | 166 | ||
| 167 | /* main test function */ | 167 | /* main test function */ |
| 168 | static void run_checks(bool order_mode, bool mos_mode, bool rta_mode, bool pl_mode, | 168 | static void run_checks(bool order_mode, bool mos_mode, bool rta_mode, bool pl_mode, |
| 169 | bool jitter_mode, bool score_mode, int min_hosts_alive, | 169 | bool jitter_mode, bool score_mode, int min_hosts_alive, |
| 170 | unsigned short icmp_pkt_size, unsigned int *pkt_interval, | 170 | unsigned short icmp_pkt_size, unsigned int *pkt_interval, |
| 171 | unsigned int *target_interval, threshold warn, threshold crit, pid_t pid, | 171 | unsigned int *target_interval, check_icmp_threshold warn, |
| 172 | int mode, unsigned int max_completion_time, struct timeval prog_start, | 172 | check_icmp_threshold crit, uint16_t sender_id, |
| 173 | ping_target **table, unsigned short packets, int icmp_sock, | 173 | check_icmp_execution_mode mode, unsigned int max_completion_time, |
| 174 | unsigned short number_of_targets, check_icmp_state *program_state, | 174 | struct timeval prog_start, ping_target **table, unsigned short packets, |
| 175 | ping_target *target_list); | 175 | int icmp_sock, unsigned short number_of_targets, |
| 176 | check_icmp_state *program_state, ping_target *target_list); | ||
| 176 | 177 | ||
| 177 | /* Target aquisition */ | 178 | /* Target aquisition */ |
| 178 | typedef struct { | 179 | typedef struct { |
| @@ -190,13 +191,14 @@ static add_target_ip_wrapper add_target_ip(char * /*arg*/, struct sockaddr_stora | |||
| 190 | 191 | ||
| 191 | static void parse_address(struct sockaddr_storage * /*addr*/, char * /*address*/, socklen_t size); | 192 | static void parse_address(struct sockaddr_storage * /*addr*/, char * /*address*/, socklen_t size); |
| 192 | 193 | ||
| 193 | static unsigned short icmp_checksum(uint16_t * /*p*/, size_t /*n*/); | 194 | static unsigned short icmp_checksum(uint16_t *packet, size_t packet_size); |
| 194 | 195 | ||
| 195 | /* End of run function */ | 196 | /* End of run function */ |
| 196 | static void finish(int /*sig*/, bool order_mode, bool mos_mode, bool rta_mode, bool pl_mode, | 197 | static void finish(int /*sig*/, bool order_mode, bool mos_mode, bool rta_mode, bool pl_mode, |
| 197 | bool jitter_mode, bool score_mode, int min_hosts_alive, threshold warn, | 198 | bool jitter_mode, bool score_mode, int min_hosts_alive, |
| 198 | threshold crit, int icmp_sock, unsigned short number_of_targets, | 199 | check_icmp_threshold warn, check_icmp_threshold crit, int icmp_sock, |
| 199 | check_icmp_state *program_state, ping_target *target_list); | 200 | unsigned short number_of_targets, check_icmp_state *program_state, |
| 201 | ping_target *target_list); | ||
| 200 | 202 | ||
| 201 | /* Error exit */ | 203 | /* Error exit */ |
| 202 | static void crash(const char * /*fmt*/, ...); | 204 | static void crash(const char * /*fmt*/, ...); |
| @@ -239,21 +241,21 @@ check_icmp_config_wrapper process_arguments(int argc, char **argv) { | |||
| 239 | 241 | ||
| 240 | /* use the pid to mark packets as ours */ | 242 | /* use the pid to mark packets as ours */ |
| 241 | /* Some systems have 32-bit pid_t so mask off only 16 bits */ | 243 | /* Some systems have 32-bit pid_t so mask off only 16 bits */ |
| 242 | result.config.pid = getpid() & 0xffff; | 244 | result.config.sender_id = getpid() & 0xffff; |
| 243 | 245 | ||
| 244 | if (!strcmp(progname, "check_icmp") || !strcmp(progname, "check_ping")) { | 246 | if (!strcmp(progname, "check_icmp") || !strcmp(progname, "check_ping")) { |
| 245 | result.config.mode = MODE_ICMP; | 247 | result.config.mode = MODE_ICMP; |
| 246 | } else if (!strcmp(progname, "check_host")) { | 248 | } else if (!strcmp(progname, "check_host")) { |
| 247 | result.config.mode = MODE_HOSTCHECK; | 249 | result.config.mode = MODE_HOSTCHECK; |
| 248 | result.config.pkt_interval = 1000000; | 250 | result.config.pkt_interval = 1000000; |
| 249 | result.config.packets = 5; | 251 | result.config.number_of_packets = 5; |
| 250 | result.config.crit.rta = result.config.warn.rta = 1000000; | 252 | result.config.crit.rta = result.config.warn.rta = 1000000; |
| 251 | result.config.crit.pl = result.config.warn.pl = 100; | 253 | result.config.crit.pl = result.config.warn.pl = 100; |
| 252 | } else if (!strcmp(progname, "check_rta_multi")) { | 254 | } else if (!strcmp(progname, "check_rta_multi")) { |
| 253 | result.config.mode = MODE_ALL; | 255 | result.config.mode = MODE_ALL; |
| 254 | result.config.target_interval = 0; | 256 | result.config.target_interval = 0; |
| 255 | result.config.pkt_interval = 50000; | 257 | result.config.pkt_interval = 50000; |
| 256 | result.config.packets = 5; | 258 | result.config.number_of_packets = 5; |
| 257 | } | 259 | } |
| 258 | /* support "--help" and "--version" */ | 260 | /* support "--help" and "--version" */ |
| 259 | if (argc == 2) { | 261 | if (argc == 2) { |
| @@ -279,14 +281,10 @@ check_icmp_config_wrapper process_arguments(int argc, char **argv) { | |||
| 279 | address_family = AF_INET; | 281 | address_family = AF_INET; |
| 280 | break; | 282 | break; |
| 281 | case '6': | 283 | case '6': |
| 282 | #ifdef USE_IPV6 | ||
| 283 | if (address_family != -1) { | 284 | if (address_family != -1) { |
| 284 | crash("Multiple protocol versions not supported"); | 285 | crash("Multiple protocol versions not supported"); |
| 285 | } | 286 | } |
| 286 | address_family = AF_INET6; | 287 | address_family = AF_INET6; |
| 287 | #else | ||
| 288 | usage(_("IPv6 support not available\n")); | ||
| 289 | #endif | ||
| 290 | break; | 288 | break; |
| 291 | case 'H': { | 289 | case 'H': { |
| 292 | result.config.number_of_hosts++; | 290 | result.config.number_of_hosts++; |
| @@ -351,10 +349,10 @@ check_icmp_config_wrapper process_arguments(int argc, char **argv) { | |||
| 351 | break; | 349 | break; |
| 352 | case 'n': | 350 | case 'n': |
| 353 | case 'p': | 351 | case 'p': |
| 354 | result.config.packets = (unsigned short)strtoul(optarg, NULL, 0); | 352 | result.config.number_of_packets = (unsigned short)strtoul(optarg, NULL, 0); |
| 355 | if (result.config.packets > 20) { | 353 | if (result.config.number_of_packets > 20) { |
| 356 | errno = 0; | 354 | errno = 0; |
| 357 | crash("packets is > 20 (%d)", result.config.packets); | 355 | crash("packets is > 20 (%d)", result.config.number_of_packets); |
| 358 | } | 356 | } |
| 359 | break; | 357 | break; |
| 360 | case 't': | 358 | case 't': |
| @@ -599,18 +597,18 @@ static const char *get_icmp_error_msg(unsigned char icmp_type, unsigned char icm | |||
| 599 | 597 | ||
| 600 | static int handle_random_icmp(unsigned char *packet, struct sockaddr_storage *addr, | 598 | static int handle_random_icmp(unsigned char *packet, struct sockaddr_storage *addr, |
| 601 | unsigned int *pkt_interval, unsigned int *target_interval, | 599 | unsigned int *pkt_interval, unsigned int *target_interval, |
| 602 | const pid_t pid, ping_target **table, unsigned short packets, | 600 | const uint16_t sender_id, ping_target **table, unsigned short packets, |
| 603 | const unsigned short number_of_targets, | 601 | const unsigned short number_of_targets, |
| 604 | check_icmp_state *program_state) { | 602 | check_icmp_state *program_state) { |
| 605 | struct icmp p; | 603 | struct icmp icmp_packet; |
| 606 | memcpy(&p, packet, sizeof(p)); | 604 | memcpy(&icmp_packet, packet, sizeof(icmp_packet)); |
| 607 | if (p.icmp_type == ICMP_ECHO && ntohs(p.icmp_id) == pid) { | 605 | if (icmp_packet.icmp_type == ICMP_ECHO && ntohs(icmp_packet.icmp_id) == sender_id) { |
| 608 | /* echo request from us to us (pinging localhost) */ | 606 | /* echo request from us to us (pinging localhost) */ |
| 609 | return 0; | 607 | return 0; |
| 610 | } | 608 | } |
| 611 | 609 | ||
| 612 | if (debug) { | 610 | if (debug) { |
| 613 | printf("handle_random_icmp(%p, %p)\n", (void *)&p, (void *)addr); | 611 | printf("handle_random_icmp(%p, %p)\n", (void *)&icmp_packet, (void *)addr); |
| 614 | } | 612 | } |
| 615 | 613 | ||
| 616 | /* only handle a few types, since others can't possibly be replies to | 614 | /* only handle a few types, since others can't possibly be replies to |
| @@ -623,8 +621,8 @@ static int handle_random_icmp(unsigned char *packet, struct sockaddr_storage *ad | |||
| 623 | * TIMXCEED actually sends a proper icmp response we will have passed | 621 | * TIMXCEED actually sends a proper icmp response we will have passed |
| 624 | * too many hops to have a hope of reaching it later, in which case it | 622 | * too many hops to have a hope of reaching it later, in which case it |
| 625 | * indicates overconfidence in the network, poor routing or both. */ | 623 | * indicates overconfidence in the network, poor routing or both. */ |
| 626 | if (p.icmp_type != ICMP_UNREACH && p.icmp_type != ICMP_TIMXCEED && | 624 | if (icmp_packet.icmp_type != ICMP_UNREACH && icmp_packet.icmp_type != ICMP_TIMXCEED && |
| 627 | p.icmp_type != ICMP_SOURCEQUENCH && p.icmp_type != ICMP_PARAMPROB) { | 625 | icmp_packet.icmp_type != ICMP_SOURCEQUENCH && icmp_packet.icmp_type != ICMP_PARAMPROB) { |
| 628 | return 0; | 626 | return 0; |
| 629 | } | 627 | } |
| 630 | 628 | ||
| @@ -632,7 +630,7 @@ static int handle_random_icmp(unsigned char *packet, struct sockaddr_storage *ad | |||
| 632 | * to RFC 792). If it isn't, just ignore it */ | 630 | * to RFC 792). If it isn't, just ignore it */ |
| 633 | struct icmp sent_icmp; | 631 | struct icmp sent_icmp; |
| 634 | memcpy(&sent_icmp, packet + 28, sizeof(sent_icmp)); | 632 | memcpy(&sent_icmp, packet + 28, sizeof(sent_icmp)); |
| 635 | if (sent_icmp.icmp_type != ICMP_ECHO || ntohs(sent_icmp.icmp_id) != pid || | 633 | if (sent_icmp.icmp_type != ICMP_ECHO || ntohs(sent_icmp.icmp_id) != sender_id || |
| 636 | ntohs(sent_icmp.icmp_seq) >= number_of_targets * packets) { | 634 | ntohs(sent_icmp.icmp_seq) >= number_of_targets * packets) { |
| 637 | if (debug) { | 635 | if (debug) { |
| 638 | printf("Packet is no response to a packet we sent\n"); | 636 | printf("Packet is no response to a packet we sent\n"); |
| @@ -646,7 +644,7 @@ static int handle_random_icmp(unsigned char *packet, struct sockaddr_storage *ad | |||
| 646 | char address[INET6_ADDRSTRLEN]; | 644 | char address[INET6_ADDRSTRLEN]; |
| 647 | parse_address(addr, address, sizeof(address)); | 645 | parse_address(addr, address, sizeof(address)); |
| 648 | printf("Received \"%s\" from %s for ICMP ECHO sent to %s.\n", | 646 | printf("Received \"%s\" from %s for ICMP ECHO sent to %s.\n", |
| 649 | get_icmp_error_msg(p.icmp_type, p.icmp_code), address, host->name); | 647 | get_icmp_error_msg(icmp_packet.icmp_type, icmp_packet.icmp_code), address, host->name); |
| 650 | } | 648 | } |
| 651 | 649 | ||
| 652 | program_state->icmp_lost++; | 650 | program_state->icmp_lost++; |
| @@ -658,15 +656,15 @@ static int handle_random_icmp(unsigned char *packet, struct sockaddr_storage *ad | |||
| 658 | 656 | ||
| 659 | /* source quench means we're sending too fast, so increase the | 657 | /* source quench means we're sending too fast, so increase the |
| 660 | * interval and mark this packet lost */ | 658 | * interval and mark this packet lost */ |
| 661 | if (p.icmp_type == ICMP_SOURCEQUENCH) { | 659 | if (icmp_packet.icmp_type == ICMP_SOURCEQUENCH) { |
| 662 | *pkt_interval = (unsigned int)(*pkt_interval * PACKET_BACKOFF_FACTOR); | 660 | *pkt_interval = (unsigned int)(*pkt_interval * PACKET_BACKOFF_FACTOR); |
| 663 | *target_interval = (unsigned int)(*target_interval * TARGET_BACKOFF_FACTOR); | 661 | *target_interval = (unsigned int)(*target_interval * TARGET_BACKOFF_FACTOR); |
| 664 | } else { | 662 | } else { |
| 665 | program_state->targets_down++; | 663 | program_state->targets_down++; |
| 666 | host->flags |= FLAG_LOST_CAUSE; | 664 | host->flags |= FLAG_LOST_CAUSE; |
| 667 | } | 665 | } |
| 668 | host->icmp_type = p.icmp_type; | 666 | host->icmp_type = icmp_packet.icmp_type; |
| 669 | host->icmp_code = p.icmp_code; | 667 | host->icmp_code = icmp_packet.icmp_code; |
| 670 | host->error_addr = *addr; | 668 | host->error_addr = *addr; |
| 671 | 669 | ||
| 672 | return 0; | 670 | return 0; |
| @@ -772,18 +770,18 @@ int main(int argc, char **argv) { | |||
| 772 | gettimeofday(&prog_start, NULL); | 770 | gettimeofday(&prog_start, NULL); |
| 773 | 771 | ||
| 774 | unsigned int max_completion_time = | 772 | unsigned int max_completion_time = |
| 775 | ((config.number_of_targets * config.packets * config.pkt_interval) + | 773 | ((config.number_of_targets * config.number_of_packets * config.pkt_interval) + |
| 776 | (config.number_of_targets * config.target_interval)) + | 774 | (config.number_of_targets * config.target_interval)) + |
| 777 | (config.number_of_targets * config.packets * config.crit.rta) + config.crit.rta; | 775 | (config.number_of_targets * config.number_of_packets * config.crit.rta) + config.crit.rta; |
| 778 | 776 | ||
| 779 | if (debug) { | 777 | if (debug) { |
| 780 | printf("packets: %u, targets: %u\n" | 778 | printf("packets: %u, targets: %u\n" |
| 781 | "target_interval: %0.3f, pkt_interval %0.3f\n" | 779 | "target_interval: %0.3f, pkt_interval %0.3f\n" |
| 782 | "crit.rta: %0.3f\n" | 780 | "crit.rta: %0.3f\n" |
| 783 | "max_completion_time: %0.3f\n", | 781 | "max_completion_time: %0.3f\n", |
| 784 | config.packets, config.number_of_targets, (float)config.target_interval / 1000, | 782 | config.number_of_packets, config.number_of_targets, |
| 785 | (float)config.pkt_interval / 1000, (float)config.crit.rta / 1000, | 783 | (float)config.target_interval / 1000, (float)config.pkt_interval / 1000, |
| 786 | (float)max_completion_time / 1000); | 784 | (float)config.crit.rta / 1000, (float)max_completion_time / 1000); |
| 787 | } | 785 | } |
| 788 | 786 | ||
| 789 | if (debug) { | 787 | if (debug) { |
| @@ -814,7 +812,7 @@ int main(int argc, char **argv) { | |||
| 814 | 812 | ||
| 815 | unsigned short target_index = 0; | 813 | unsigned short target_index = 0; |
| 816 | while (host) { | 814 | while (host) { |
| 817 | host->id = target_index * config.packets; | 815 | host->id = target_index * config.number_of_packets; |
| 818 | table[target_index] = host; | 816 | table[target_index] = host; |
| 819 | host = host->next; | 817 | host = host->next; |
| 820 | target_index++; | 818 | target_index++; |
| @@ -827,9 +825,9 @@ int main(int argc, char **argv) { | |||
| 827 | 825 | ||
| 828 | run_checks(config.order_mode, config.mos_mode, config.rta_mode, config.pl_mode, | 826 | run_checks(config.order_mode, config.mos_mode, config.rta_mode, config.pl_mode, |
| 829 | config.jitter_mode, config.score_mode, config.min_hosts_alive, config.icmp_data_size, | 827 | config.jitter_mode, config.score_mode, config.min_hosts_alive, config.icmp_data_size, |
| 830 | &pkt_interval, &target_interval, config.warn, config.crit, config.pid, config.mode, | 828 | &pkt_interval, &target_interval, config.warn, config.crit, config.sender_id, |
| 831 | max_completion_time, prog_start, table, config.packets, icmp_sock, | 829 | config.mode, max_completion_time, prog_start, table, config.number_of_packets, |
| 832 | config.number_of_targets, &program_state, config.targets); | 830 | icmp_sock, config.number_of_targets, &program_state, config.targets); |
| 833 | 831 | ||
| 834 | errno = 0; | 832 | errno = 0; |
| 835 | finish(0, config.order_mode, config.mos_mode, config.rta_mode, config.pl_mode, | 833 | finish(0, config.order_mode, config.mos_mode, config.rta_mode, config.pl_mode, |
| @@ -842,8 +840,9 @@ int main(int argc, char **argv) { | |||
| 842 | static void run_checks(bool order_mode, bool mos_mode, bool rta_mode, bool pl_mode, | 840 | static void run_checks(bool order_mode, bool mos_mode, bool rta_mode, bool pl_mode, |
| 843 | bool jitter_mode, bool score_mode, int min_hosts_alive, | 841 | bool jitter_mode, bool score_mode, int min_hosts_alive, |
| 844 | unsigned short icmp_pkt_size, unsigned int *pkt_interval, | 842 | unsigned short icmp_pkt_size, unsigned int *pkt_interval, |
| 845 | unsigned int *target_interval, threshold warn, threshold crit, | 843 | unsigned int *target_interval, check_icmp_threshold warn, |
| 846 | const pid_t pid, const int mode, const unsigned int max_completion_time, | 844 | check_icmp_threshold crit, const uint16_t sender_id, |
| 845 | const check_icmp_execution_mode mode, const unsigned int max_completion_time, | ||
| 847 | const struct timeval prog_start, ping_target **table, | 846 | const struct timeval prog_start, ping_target **table, |
| 848 | const unsigned short packets, const int icmp_sock, | 847 | const unsigned short packets, const int icmp_sock, |
| 849 | const unsigned short number_of_targets, check_icmp_state *program_state, | 848 | const unsigned short number_of_targets, check_icmp_state *program_state, |
| @@ -867,14 +866,15 @@ static void run_checks(bool order_mode, bool mos_mode, bool rta_mode, bool pl_mo | |||
| 867 | } | 866 | } |
| 868 | 867 | ||
| 869 | /* we're still in the game, so send next packet */ | 868 | /* we're still in the game, so send next packet */ |
| 870 | (void)send_icmp_ping(icmp_sock, table[target_index], icmp_pkt_size, pid, program_state); | 869 | (void)send_icmp_ping(icmp_sock, table[target_index], icmp_pkt_size, sender_id, |
| 870 | program_state); | ||
| 871 | 871 | ||
| 872 | /* wrap up if all targets are declared dead */ | 872 | /* wrap up if all targets are declared dead */ |
| 873 | if (targets_alive(number_of_targets, program_state->targets_down) || | 873 | if (targets_alive(number_of_targets, program_state->targets_down) || |
| 874 | get_timevaldiff(prog_start, prog_start) < max_completion_time || | 874 | get_timevaldiff(prog_start, prog_start) < max_completion_time || |
| 875 | !(mode == MODE_HOSTCHECK && program_state->targets_down)) { | 875 | !(mode == MODE_HOSTCHECK && program_state->targets_down)) { |
| 876 | wait_for_reply(icmp_sock, *target_interval, icmp_pkt_size, pkt_interval, | 876 | wait_for_reply(icmp_sock, *target_interval, icmp_pkt_size, pkt_interval, |
| 877 | target_interval, pid, table, packets, number_of_targets, | 877 | target_interval, sender_id, table, packets, number_of_targets, |
| 878 | program_state); | 878 | program_state); |
| 879 | } | 879 | } |
| 880 | } | 880 | } |
| @@ -882,8 +882,8 @@ static void run_checks(bool order_mode, bool mos_mode, bool rta_mode, bool pl_mo | |||
| 882 | get_timevaldiff_to_now(prog_start) < max_completion_time || | 882 | get_timevaldiff_to_now(prog_start) < max_completion_time || |
| 883 | !(mode == MODE_HOSTCHECK && program_state->targets_down)) { | 883 | !(mode == MODE_HOSTCHECK && program_state->targets_down)) { |
| 884 | wait_for_reply(icmp_sock, *pkt_interval * number_of_targets, icmp_pkt_size, | 884 | wait_for_reply(icmp_sock, *pkt_interval * number_of_targets, icmp_pkt_size, |
| 885 | pkt_interval, target_interval, pid, table, packets, number_of_targets, | 885 | pkt_interval, target_interval, sender_id, table, packets, |
| 886 | program_state); | 886 | number_of_targets, program_state); |
| 887 | } | 887 | } |
| 888 | } | 888 | } |
| 889 | 889 | ||
| @@ -915,8 +915,8 @@ static void run_checks(bool order_mode, bool mos_mode, bool rta_mode, bool pl_mo | |||
| 915 | if (targets_alive(number_of_targets, program_state->targets_down) || | 915 | if (targets_alive(number_of_targets, program_state->targets_down) || |
| 916 | get_timevaldiff_to_now(prog_start) < max_completion_time || | 916 | get_timevaldiff_to_now(prog_start) < max_completion_time || |
| 917 | !(mode == MODE_HOSTCHECK && program_state->targets_down)) { | 917 | !(mode == MODE_HOSTCHECK && program_state->targets_down)) { |
| 918 | wait_for_reply(icmp_sock, final_wait, icmp_pkt_size, pkt_interval, target_interval, pid, | 918 | wait_for_reply(icmp_sock, final_wait, icmp_pkt_size, pkt_interval, target_interval, |
| 919 | table, packets, number_of_targets, program_state); | 919 | sender_id, table, packets, number_of_targets, program_state); |
| 920 | } | 920 | } |
| 921 | } | 921 | } |
| 922 | } | 922 | } |
| @@ -932,8 +932,8 @@ static void run_checks(bool order_mode, bool mos_mode, bool rta_mode, bool pl_mo | |||
| 932 | * icmp echo reply : the rest | 932 | * icmp echo reply : the rest |
| 933 | */ | 933 | */ |
| 934 | static int wait_for_reply(int sock, const time_t time_interval, unsigned short icmp_pkt_size, | 934 | static int wait_for_reply(int sock, const time_t time_interval, unsigned short icmp_pkt_size, |
| 935 | unsigned int *pkt_interval, unsigned int *target_interval, pid_t pid, | 935 | unsigned int *pkt_interval, unsigned int *target_interval, |
| 936 | ping_target **table, const unsigned short packets, | 936 | uint16_t sender_id, ping_target **table, const unsigned short packets, |
| 937 | const unsigned short number_of_targets, check_icmp_state *program_state) { | 937 | const unsigned short number_of_targets, check_icmp_state *program_state) { |
| 938 | union icmp_packet packet; | 938 | union icmp_packet packet; |
| 939 | if (!(packet.buf = malloc(icmp_pkt_size))) { | 939 | if (!(packet.buf = malloc(icmp_pkt_size))) { |
| @@ -1027,16 +1027,16 @@ static int wait_for_reply(int sock, const time_t time_interval, unsigned short i | |||
| 1027 | : sizeof(struct icmp));*/ | 1027 | : sizeof(struct icmp));*/ |
| 1028 | 1028 | ||
| 1029 | if ((address_family == PF_INET && | 1029 | if ((address_family == PF_INET && |
| 1030 | (ntohs(packet.icp->icmp_id) != pid || packet.icp->icmp_type != ICMP_ECHOREPLY || | 1030 | (ntohs(packet.icp->icmp_id) != sender_id || packet.icp->icmp_type != ICMP_ECHOREPLY || |
| 1031 | ntohs(packet.icp->icmp_seq) >= number_of_targets * packets)) || | 1031 | ntohs(packet.icp->icmp_seq) >= number_of_targets * packets)) || |
| 1032 | (address_family == PF_INET6 && | 1032 | (address_family == PF_INET6 && |
| 1033 | (ntohs(packet.icp6->icmp6_id) != pid || packet.icp6->icmp6_type != ICMP6_ECHO_REPLY || | 1033 | (ntohs(packet.icp6->icmp6_id) != sender_id || packet.icp6->icmp6_type != ICMP6_ECHO_REPLY || |
| 1034 | ntohs(packet.icp6->icmp6_seq) >= number_of_targets * packets))) { | 1034 | ntohs(packet.icp6->icmp6_seq) >= number_of_targets * packets))) { |
| 1035 | if (debug > 2) { | 1035 | if (debug > 2) { |
| 1036 | printf("not a proper ICMP_ECHOREPLY\n"); | 1036 | printf("not a proper ICMP_ECHOREPLY\n"); |
| 1037 | } | 1037 | } |
| 1038 | 1038 | ||
| 1039 | handle_random_icmp(buf + hlen, &resp_addr, pkt_interval, target_interval, pid, table, | 1039 | handle_random_icmp(buf + hlen, &resp_addr, pkt_interval, target_interval, sender_id, table, |
| 1040 | packets, number_of_targets, program_state); | 1040 | packets, number_of_targets, program_state); |
| 1041 | 1041 | ||
| 1042 | continue; | 1042 | continue; |
| @@ -1136,7 +1136,7 @@ static int wait_for_reply(int sock, const time_t time_interval, unsigned short i | |||
| 1136 | 1136 | ||
| 1137 | /* the ping functions */ | 1137 | /* the ping functions */ |
| 1138 | static int send_icmp_ping(const int sock, ping_target *host, const unsigned short icmp_pkt_size, | 1138 | static int send_icmp_ping(const int sock, ping_target *host, const unsigned short icmp_pkt_size, |
| 1139 | const pid_t pid, check_icmp_state *program_state) { | 1139 | const uint16_t sender_id, check_icmp_state *program_state) { |
| 1140 | if (sock == -1) { | 1140 | if (sock == -1) { |
| 1141 | errno = 0; | 1141 | errno = 0; |
| 1142 | crash("Attempt to send on bogus socket"); | 1142 | crash("Attempt to send on bogus socket"); |
| @@ -1174,7 +1174,7 @@ static int send_icmp_ping(const int sock, ping_target *host, const unsigned shor | |||
| 1174 | icp->icmp_type = ICMP_ECHO; | 1174 | icp->icmp_type = ICMP_ECHO; |
| 1175 | icp->icmp_code = 0; | 1175 | icp->icmp_code = 0; |
| 1176 | icp->icmp_cksum = 0; | 1176 | icp->icmp_cksum = 0; |
| 1177 | icp->icmp_id = htons((uint16_t)pid); | 1177 | icp->icmp_id = htons((uint16_t)sender_id); |
| 1178 | icp->icmp_seq = htons(host->id++); | 1178 | icp->icmp_seq = htons(host->id++); |
| 1179 | icp->icmp_cksum = icmp_checksum((uint16_t *)buf, (size_t)icmp_pkt_size); | 1179 | icp->icmp_cksum = icmp_checksum((uint16_t *)buf, (size_t)icmp_pkt_size); |
| 1180 | 1180 | ||
| @@ -1192,7 +1192,7 @@ static int send_icmp_ping(const int sock, ping_target *host, const unsigned shor | |||
| 1192 | icp6->icmp6_type = ICMP6_ECHO_REQUEST; | 1192 | icp6->icmp6_type = ICMP6_ECHO_REQUEST; |
| 1193 | icp6->icmp6_code = 0; | 1193 | icp6->icmp6_code = 0; |
| 1194 | icp6->icmp6_cksum = 0; | 1194 | icp6->icmp6_cksum = 0; |
| 1195 | icp6->icmp6_id = htons((uint16_t)pid); | 1195 | icp6->icmp6_id = htons((uint16_t)sender_id); |
| 1196 | icp6->icmp6_seq = htons(host->id++); | 1196 | icp6->icmp6_seq = htons(host->id++); |
| 1197 | // let checksum be calculated automatically | 1197 | // let checksum be calculated automatically |
| 1198 | 1198 | ||
| @@ -1330,9 +1330,10 @@ static ssize_t recvfrom_wto(const int sock, void *buf, const unsigned int len, | |||
| 1330 | } | 1330 | } |
| 1331 | 1331 | ||
| 1332 | static void finish(int sig, bool order_mode, bool mos_mode, bool rta_mode, bool pl_mode, | 1332 | static void finish(int sig, bool order_mode, bool mos_mode, bool rta_mode, bool pl_mode, |
| 1333 | bool jitter_mode, bool score_mode, int min_hosts_alive, threshold warn, | 1333 | bool jitter_mode, bool score_mode, int min_hosts_alive, |
| 1334 | threshold crit, const int icmp_sock, const unsigned short number_of_targets, | 1334 | check_icmp_threshold warn, check_icmp_threshold crit, const int icmp_sock, |
| 1335 | check_icmp_state *program_state, ping_target *target_list) { | 1335 | const unsigned short number_of_targets, check_icmp_state *program_state, |
| 1336 | ping_target *target_list) { | ||
| 1336 | // Deactivate alarm | 1337 | // Deactivate alarm |
| 1337 | alarm(0); | 1338 | alarm(0); |
| 1338 | 1339 | ||
| @@ -1821,13 +1822,12 @@ static add_target_wrapper add_target(char *arg, const int mode) { | |||
| 1821 | address_family = AF_INET; | 1822 | address_family = AF_INET; |
| 1822 | sin = (struct sockaddr_in *)&address_storage; | 1823 | sin = (struct sockaddr_in *)&address_storage; |
| 1823 | error_code = inet_pton(address_family, arg, &sin->sin_addr); | 1824 | error_code = inet_pton(address_family, arg, &sin->sin_addr); |
| 1824 | #ifdef USE_IPV6 | 1825 | |
| 1825 | if (error_code != 1) { | 1826 | if (error_code != 1) { |
| 1826 | address_family = AF_INET6; | 1827 | address_family = AF_INET6; |
| 1827 | sin6 = (struct sockaddr_in6 *)&address_storage; | 1828 | sin6 = (struct sockaddr_in6 *)&address_storage; |
| 1828 | error_code = inet_pton(address_family, arg, &sin6->sin6_addr); | 1829 | error_code = inet_pton(address_family, arg, &sin6->sin6_addr); |
| 1829 | } | 1830 | } |
| 1830 | #endif | ||
| 1831 | /* If we don't find any valid addresses, we still don't know the address_family */ | 1831 | /* If we don't find any valid addresses, we still don't know the address_family */ |
| 1832 | if (error_code != 1) { | 1832 | if (error_code != 1) { |
| 1833 | address_family = -1; | 1833 | address_family = -1; |
| @@ -2029,7 +2029,7 @@ static unsigned int get_timevar(const char *str) { | |||
| 2029 | } | 2029 | } |
| 2030 | 2030 | ||
| 2031 | /* not too good at checking errors, but it'll do (main() should barfe on -1) */ | 2031 | /* not too good at checking errors, but it'll do (main() should barfe on -1) */ |
| 2032 | static int get_threshold(char *str, threshold *threshold) { | 2032 | static int get_threshold(char *str, check_icmp_threshold *threshold) { |
| 2033 | if (!str || !strlen(str) || !threshold) { | 2033 | if (!str || !strlen(str) || !threshold) { |
| 2034 | return -1; | 2034 | return -1; |
| 2035 | } | 2035 | } |
| @@ -2075,8 +2075,8 @@ static int get_threshold(char *str, threshold *threshold) { | |||
| 2075 | * @param[in] mode Determines whether this a threshold for rta, packet_loss, jitter, mos or score | 2075 | * @param[in] mode Determines whether this a threshold for rta, packet_loss, jitter, mos or score |
| 2076 | * (exclusively) | 2076 | * (exclusively) |
| 2077 | */ | 2077 | */ |
| 2078 | static bool get_threshold2(char *str, size_t length, threshold *warn, threshold *crit, | 2078 | static bool get_threshold2(char *str, size_t length, check_icmp_threshold *warn, |
| 2079 | threshold_mode mode) { | 2079 | check_icmp_threshold *crit, threshold_mode mode) { |
| 2080 | if (!str || !length || !warn || !crit) { | 2080 | if (!str || !length || !warn || !crit) { |
| 2081 | return false; | 2081 | return false; |
| 2082 | } | 2082 | } |
| @@ -2106,8 +2106,8 @@ static bool get_threshold2(char *str, size_t length, threshold *warn, threshold | |||
| 2106 | return parse_threshold2_helper(work_pointer, strlen(work_pointer), warn, mode); | 2106 | return parse_threshold2_helper(work_pointer, strlen(work_pointer), warn, mode); |
| 2107 | } | 2107 | } |
| 2108 | 2108 | ||
| 2109 | static bool parse_threshold2_helper(char *threshold_string, size_t length, threshold *thr, | 2109 | static bool parse_threshold2_helper(char *threshold_string, size_t length, |
| 2110 | threshold_mode mode) { | 2110 | check_icmp_threshold *thr, threshold_mode mode) { |
| 2111 | char *resultChecker = {0}; | 2111 | char *resultChecker = {0}; |
| 2112 | 2112 | ||
| 2113 | switch (mode) { | 2113 | switch (mode) { |
diff --git a/plugins-root/check_icmp.d/check_icmp_helpers.c b/plugins-root/check_icmp.d/check_icmp_helpers.c index 2efe6e59..2a521b04 100644 --- a/plugins-root/check_icmp.d/check_icmp_helpers.c +++ b/plugins-root/check_icmp.d/check_icmp_helpers.c | |||
| @@ -10,8 +10,6 @@ unsigned int timeout = DEFAULT_TIMEOUT; | |||
| 10 | 10 | ||
| 11 | check_icmp_config check_icmp_config_init() { | 11 | check_icmp_config check_icmp_config_init() { |
| 12 | check_icmp_config tmp = { | 12 | check_icmp_config tmp = { |
| 13 | .source_ip = NULL, | ||
| 14 | |||
| 15 | .order_mode = false, | 13 | .order_mode = false, |
| 16 | .mos_mode = false, | 14 | .mos_mode = false, |
| 17 | .rta_mode = false, | 15 | .rta_mode = false, |
| @@ -20,10 +18,6 @@ check_icmp_config check_icmp_config_init() { | |||
| 20 | .score_mode = false, | 18 | .score_mode = false, |
| 21 | 19 | ||
| 22 | .min_hosts_alive = -1, | 20 | .min_hosts_alive = -1, |
| 23 | .icmp_data_size = DEFAULT_PING_DATA_SIZE, | ||
| 24 | .icmp_pkt_size = DEFAULT_PING_DATA_SIZE + ICMP_MINLEN, | ||
| 25 | .pkt_interval = DEFAULT_PKT_INTERVAL, | ||
| 26 | .target_interval = 0, | ||
| 27 | .crit = {.pl = DEFAULT_CRIT_PL, | 21 | .crit = {.pl = DEFAULT_CRIT_PL, |
| 28 | .rta = DEFAULT_CRIT_RTA, | 22 | .rta = DEFAULT_CRIT_RTA, |
| 29 | .jitter = 50.0, | 23 | .jitter = 50.0, |
| @@ -34,11 +28,18 @@ check_icmp_config check_icmp_config_init() { | |||
| 34 | .jitter = 40.0, | 28 | .jitter = 40.0, |
| 35 | .mos = 3.5, | 29 | .mos = 3.5, |
| 36 | .score = 80.0}, | 30 | .score = 80.0}, |
| 37 | .pid = {}, | 31 | |
| 38 | .mode = MODE_RTA, | ||
| 39 | .ttl = DEFAULT_TTL, | 32 | .ttl = DEFAULT_TTL, |
| 33 | .icmp_data_size = DEFAULT_PING_DATA_SIZE, | ||
| 34 | .icmp_pkt_size = DEFAULT_PING_DATA_SIZE + ICMP_MINLEN, | ||
| 35 | .pkt_interval = DEFAULT_PKT_INTERVAL, | ||
| 36 | .target_interval = 0, | ||
| 37 | .number_of_packets = DEFAULT_NUMBER_OF_PACKETS, | ||
| 38 | .source_ip = NULL, | ||
| 39 | |||
| 40 | .sender_id = {}, | ||
| 40 | 41 | ||
| 41 | .packets = DEFAULT_NUMBER_OF_PACKETS, | 42 | .mode = MODE_RTA, |
| 42 | 43 | ||
| 43 | .number_of_targets = 0, | 44 | .number_of_targets = 0, |
| 44 | .targets = NULL, | 45 | .targets = NULL, |
| @@ -168,10 +169,10 @@ unsigned int ping_target_list_append(ping_target *list, ping_target *elem) { | |||
| 168 | return result; | 169 | return result; |
| 169 | } | 170 | } |
| 170 | 171 | ||
| 171 | void check_icmp_timeout_handler(int signal, siginfo_t * info, void *ucontext) { | 172 | void check_icmp_timeout_handler(int signal, siginfo_t *info, void *ucontext) { |
| 172 | // Ignore unused arguments | 173 | // Ignore unused arguments |
| 173 | (void) info; | 174 | (void)info; |
| 174 | (void) ucontext; | 175 | (void)ucontext; |
| 175 | mp_subcheck timeout_sc = mp_subcheck_init(); | 176 | mp_subcheck timeout_sc = mp_subcheck_init(); |
| 176 | timeout_sc = mp_set_subcheck_state(timeout_sc, socket_timeout_state); | 177 | timeout_sc = mp_set_subcheck_state(timeout_sc, socket_timeout_state); |
| 177 | 178 | ||
diff --git a/plugins-root/check_icmp.d/config.h b/plugins-root/check_icmp.d/config.h index deae9bec..3599c0f0 100644 --- a/plugins-root/check_icmp.d/config.h +++ b/plugins-root/check_icmp.d/config.h | |||
| @@ -10,20 +10,38 @@ | |||
| 10 | #include <netinet/ip_icmp.h> | 10 | #include <netinet/ip_icmp.h> |
| 11 | #include <netinet/icmp6.h> | 11 | #include <netinet/icmp6.h> |
| 12 | #include <arpa/inet.h> | 12 | #include <arpa/inet.h> |
| 13 | #include <stdint.h> | ||
| 13 | #include "./check_icmp_helpers.h" | 14 | #include "./check_icmp_helpers.h" |
| 14 | 15 | ||
| 15 | /* threshold structure. all values are maximum allowed, exclusive */ | 16 | /* threshold structure. all values are maximum allowed, exclusive */ |
| 16 | typedef struct threshold { | 17 | typedef struct { |
| 17 | unsigned char pl; /* max allowed packet loss in percent */ | 18 | unsigned char pl; /* max allowed packet loss in percent */ |
| 18 | unsigned int rta; /* roundtrip time average, microseconds */ | 19 | unsigned int rta; /* roundtrip time average, microseconds */ |
| 19 | double jitter; /* jitter time average, microseconds */ | 20 | double jitter; /* jitter time average, microseconds */ |
| 20 | double mos; /* MOS */ | 21 | double mos; /* MOS */ |
| 21 | double score; /* Score */ | 22 | double score; /* Score */ |
| 22 | } threshold; | 23 | } check_icmp_threshold; |
| 23 | 24 | ||
| 24 | typedef struct { | 25 | /* the different modes of this program are as follows: |
| 25 | char *source_ip; | 26 | * MODE_RTA: send all packets no matter what (mimic check_icmp and check_ping) |
| 27 | * MODE_HOSTCHECK: Return immediately upon any sign of life | ||
| 28 | * In addition, sends packets to ALL addresses assigned | ||
| 29 | * to this host (as returned by gethostbyname() or | ||
| 30 | * gethostbyaddr() and expects one host only to be checked at | ||
| 31 | * a time. Therefore, any packet response what so ever will | ||
| 32 | * count as a sign of life, even when received outside | ||
| 33 | * crit.rta limit. Do not misspell any additional IP's. | ||
| 34 | * MODE_ALL: Requires packets from ALL requested IP to return OK (default). | ||
| 35 | * MODE_ICMP: Default Mode | ||
| 36 | */ | ||
| 37 | typedef enum { | ||
| 38 | MODE_RTA, | ||
| 39 | MODE_HOSTCHECK, | ||
| 40 | MODE_ALL, | ||
| 41 | MODE_ICMP, | ||
| 42 | } check_icmp_execution_mode; | ||
| 26 | 43 | ||
| 44 | typedef struct { | ||
| 27 | bool order_mode; | 45 | bool order_mode; |
| 28 | bool mos_mode; | 46 | bool mos_mode; |
| 29 | bool rta_mode; | 47 | bool rta_mode; |
| @@ -32,18 +50,20 @@ typedef struct { | |||
| 32 | bool score_mode; | 50 | bool score_mode; |
| 33 | 51 | ||
| 34 | int min_hosts_alive; | 52 | int min_hosts_alive; |
| 53 | check_icmp_threshold crit; | ||
| 54 | check_icmp_threshold warn; | ||
| 55 | |||
| 56 | unsigned long ttl; | ||
| 35 | unsigned short icmp_data_size; | 57 | unsigned short icmp_data_size; |
| 36 | unsigned short icmp_pkt_size; | 58 | unsigned short icmp_pkt_size; |
| 37 | unsigned int pkt_interval; | 59 | unsigned int pkt_interval; |
| 38 | unsigned int target_interval; | 60 | unsigned int target_interval; |
| 39 | threshold crit; | 61 | unsigned short number_of_packets; |
| 40 | threshold warn; | 62 | char *source_ip; |
| 41 | pid_t pid; | ||
| 42 | 63 | ||
| 43 | int mode; | 64 | uint16_t sender_id; // PID of the main process, which is used as an ID in packets |
| 44 | unsigned long ttl; | ||
| 45 | 65 | ||
| 46 | unsigned short packets; | 66 | check_icmp_execution_mode mode; |
| 47 | 67 | ||
| 48 | unsigned short number_of_targets; | 68 | unsigned short number_of_targets; |
| 49 | ping_target *targets; | 69 | ping_target *targets; |
| @@ -78,24 +98,6 @@ typedef struct icmp_ping_data { | |||
| 78 | #define DEFAULT_TIMEOUT 10 | 98 | #define DEFAULT_TIMEOUT 10 |
| 79 | #define DEFAULT_TTL 64 | 99 | #define DEFAULT_TTL 64 |
| 80 | 100 | ||
| 81 | /* the different modes of this program are as follows: | ||
| 82 | * MODE_RTA: send all packets no matter what (mimic check_icmp and check_ping) | ||
| 83 | * MODE_HOSTCHECK: Return immediately upon any sign of life | ||
| 84 | * In addition, sends packets to ALL addresses assigned | ||
| 85 | * to this host (as returned by gethostbyname() or | ||
| 86 | * gethostbyaddr() and expects one host only to be checked at | ||
| 87 | * a time. Therefore, any packet response what so ever will | ||
| 88 | * count as a sign of life, even when received outside | ||
| 89 | * crit.rta limit. Do not misspell any additional IP's. | ||
| 90 | * MODE_ALL: Requires packets from ALL requested IP to return OK (default). | ||
| 91 | * MODE_ICMP: implement something similar to check_icmp (MODE_RTA without | ||
| 92 | * tcp and udp args does this) | ||
| 93 | */ | ||
| 94 | #define MODE_RTA 0 | ||
| 95 | #define MODE_HOSTCHECK 1 | ||
| 96 | #define MODE_ALL 2 | ||
| 97 | #define MODE_ICMP 3 | ||
| 98 | |||
| 99 | #define DEFAULT_NUMBER_OF_PACKETS 5 | 101 | #define DEFAULT_NUMBER_OF_PACKETS 5 |
| 100 | 102 | ||
| 101 | #define PACKET_BACKOFF_FACTOR 1.5 | 103 | #define PACKET_BACKOFF_FACTOR 1.5 |
