mirror of
https://github.com/monitoring-plugins/monitoring-plugins.git
synced 2026-04-20 21:57:10 -04:00
WIP - check_icmp refactor 7
This commit is contained in:
parent
fbcd11acb7
commit
8f08e7ab3e
1 changed files with 109 additions and 86 deletions
|
|
@ -184,17 +184,24 @@ static parse_threshold2_helper_wrapper parse_threshold2_helper(char *threshold_s
|
|||
threshold_mode mode);
|
||||
|
||||
/* main test function */
|
||||
static void run_checks(check_icmp_mode_switches modes, int min_hosts_alive,
|
||||
unsigned short icmp_pkt_size, unsigned int *pkt_interval,
|
||||
unsigned int *target_interval, check_icmp_threshold warn,
|
||||
check_icmp_threshold crit, uint16_t sender_id,
|
||||
static void run_checks(unsigned short icmp_pkt_size, unsigned int *pkt_interval,
|
||||
unsigned int *target_interval, uint16_t sender_id,
|
||||
check_icmp_execution_mode mode, unsigned int max_completion_time,
|
||||
struct timeval prog_start, ping_target **table, unsigned short packets,
|
||||
int icmp_sock, unsigned short number_of_targets,
|
||||
check_icmp_state *program_state, ping_target *target_list);
|
||||
check_icmp_state *program_state);
|
||||
mp_subcheck evaluate_target(ping_target target, check_icmp_mode_switches modes,
|
||||
check_icmp_threshold warn, check_icmp_threshold crit);
|
||||
|
||||
typedef struct {
|
||||
int targets_ok;
|
||||
int targets_warn;
|
||||
mp_subcheck sc_host;
|
||||
} evaluate_host_wrapper;
|
||||
evaluate_host_wrapper evaluate_host(check_icmp_target_container host,
|
||||
check_icmp_mode_switches modes, check_icmp_threshold warn,
|
||||
check_icmp_threshold crit);
|
||||
|
||||
/* Target aquisition */
|
||||
typedef struct {
|
||||
int error_code;
|
||||
|
|
@ -213,7 +220,7 @@ typedef struct {
|
|||
int error_code;
|
||||
ping_target *target;
|
||||
} add_target_ip_wrapper;
|
||||
static add_target_ip_wrapper add_target_ip(char *arg, struct sockaddr_storage *address);
|
||||
static add_target_ip_wrapper add_target_ip(struct sockaddr_storage address);
|
||||
|
||||
static void parse_address(struct sockaddr_storage *addr, char *address, socklen_t size);
|
||||
|
||||
|
|
@ -223,7 +230,8 @@ static unsigned short icmp_checksum(uint16_t *packet, size_t packet_size);
|
|||
static void finish(int sign, check_icmp_mode_switches modes, int min_hosts_alive,
|
||||
check_icmp_threshold warn, check_icmp_threshold crit, int icmp_sock,
|
||||
unsigned short number_of_targets, check_icmp_state *program_state,
|
||||
ping_target *target_list) __attribute__((noreturn));
|
||||
check_icmp_target_container host_list[], unsigned short number_of_hosts,
|
||||
mp_check overall[static 1]);
|
||||
|
||||
/* Error exit */
|
||||
static void crash(const char *fmt, ...);
|
||||
|
|
@ -247,8 +255,6 @@ typedef struct {
|
|||
int errorcode;
|
||||
check_icmp_config config;
|
||||
} check_icmp_config_wrapper;
|
||||
check_icmp_config_wrapper process_arguments(int argc, char **argv);
|
||||
|
||||
check_icmp_config_wrapper process_arguments(int argc, char **argv) {
|
||||
/* get calling name the old-fashioned way for portability instead
|
||||
* of relying on the glibc-ism __progname */
|
||||
|
|
@ -313,7 +319,11 @@ check_icmp_config_wrapper process_arguments(int argc, char **argv) {
|
|||
break;
|
||||
case 'H': {
|
||||
result.config.number_of_hosts++;
|
||||
break;
|
||||
}
|
||||
case 'v':
|
||||
debug++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -345,9 +355,6 @@ check_icmp_config_wrapper process_arguments(int argc, char **argv) {
|
|||
long int arg;
|
||||
while ((arg = getopt(argc, argv, opts_str)) != EOF) {
|
||||
switch (arg) {
|
||||
case 'v':
|
||||
debug++;
|
||||
break;
|
||||
case 'b': {
|
||||
long size = strtol(optarg, NULL, 0);
|
||||
if ((unsigned long)size >= (sizeof(struct icmp) + sizeof(struct icmp_ping_data)) &&
|
||||
|
|
@ -859,6 +866,7 @@ int main(int argc, char **argv) {
|
|||
crash("minimum alive hosts is negative (%i)", config.min_hosts_alive);
|
||||
}
|
||||
|
||||
// Build an index table of all targets
|
||||
ping_target *host = config.targets;
|
||||
ping_target **table = malloc(sizeof(ping_target *) * config.number_of_targets);
|
||||
if (!table) {
|
||||
|
|
@ -878,27 +886,26 @@ int main(int argc, char **argv) {
|
|||
|
||||
check_icmp_state program_state = check_icmp_state_init();
|
||||
|
||||
run_checks(config.modes, config.min_hosts_alive, config.icmp_data_size, &pkt_interval,
|
||||
&target_interval, config.warn, config.crit, config.sender_id, config.mode,
|
||||
max_completion_time, prog_start, table, config.number_of_packets, icmp_sock,
|
||||
config.number_of_targets, &program_state, config.targets);
|
||||
run_checks(config.icmp_data_size, &pkt_interval, &target_interval, config.sender_id,
|
||||
config.mode, max_completion_time, prog_start, table, config.number_of_packets,
|
||||
icmp_sock, config.number_of_targets, &program_state);
|
||||
|
||||
errno = 0;
|
||||
finish(0, config.modes, config.min_hosts_alive, config.warn, config.crit, icmp_sock,
|
||||
config.number_of_targets, &program_state, config.targets);
|
||||
|
||||
return (0);
|
||||
mp_check overall = mp_check_init();
|
||||
finish(0, config.modes, config.min_hosts_alive, config.warn, config.crit, icmp_sock,
|
||||
config.number_of_targets, &program_state, config.hosts, config.number_of_hosts,
|
||||
&overall);
|
||||
|
||||
mp_exit(overall);
|
||||
}
|
||||
|
||||
static void run_checks(check_icmp_mode_switches modes, int min_hosts_alive,
|
||||
unsigned short icmp_pkt_size, unsigned int *pkt_interval,
|
||||
unsigned int *target_interval, check_icmp_threshold warn,
|
||||
check_icmp_threshold crit, const uint16_t sender_id,
|
||||
static void run_checks(unsigned short icmp_pkt_size, unsigned int *pkt_interval,
|
||||
unsigned int *target_interval, const uint16_t sender_id,
|
||||
const check_icmp_execution_mode mode, const unsigned int max_completion_time,
|
||||
const struct timeval prog_start, ping_target **table,
|
||||
const unsigned short packets, const int icmp_sock,
|
||||
const unsigned short number_of_targets, check_icmp_state *program_state,
|
||||
ping_target *target_list) {
|
||||
const unsigned short number_of_targets, check_icmp_state *program_state) {
|
||||
/* this loop might actually violate the pkt_interval or target_interval
|
||||
* settings, but only if there aren't any packets on the wire which
|
||||
* indicates that the target can handle an increased packet rate */
|
||||
|
|
@ -906,8 +913,7 @@ static void run_checks(check_icmp_mode_switches modes, int min_hosts_alive,
|
|||
for (unsigned int target_index = 0; target_index < number_of_targets; target_index++) {
|
||||
/* don't send useless packets */
|
||||
if (!targets_alive(number_of_targets, program_state->targets_down)) {
|
||||
finish(0, modes, min_hosts_alive, warn, crit, icmp_sock, number_of_targets,
|
||||
program_state, target_list);
|
||||
return;
|
||||
}
|
||||
if (table[target_index]->flags & FLAG_LOST_CAUSE) {
|
||||
if (debug) {
|
||||
|
|
@ -952,8 +958,7 @@ static void run_checks(check_icmp_mode_switches modes, int min_hosts_alive,
|
|||
if (debug) {
|
||||
printf("Time passed. Finishing up\n");
|
||||
}
|
||||
finish(0, modes, min_hosts_alive, warn, crit, icmp_sock, number_of_targets,
|
||||
program_state, target_list);
|
||||
return;
|
||||
}
|
||||
|
||||
/* catch the packets that might come in within the timeframe, but
|
||||
|
|
@ -1383,7 +1388,8 @@ static ssize_t recvfrom_wto(const int sock, void *buf, const unsigned int len,
|
|||
static void finish(int sig, check_icmp_mode_switches modes, int min_hosts_alive,
|
||||
check_icmp_threshold warn, check_icmp_threshold crit, const int icmp_sock,
|
||||
const unsigned short number_of_targets, check_icmp_state *program_state,
|
||||
ping_target *target_list) {
|
||||
check_icmp_target_container host_list[], unsigned short number_of_hosts,
|
||||
mp_check overall[static 1]) {
|
||||
// Deactivate alarm
|
||||
alarm(0);
|
||||
|
||||
|
|
@ -1402,29 +1408,21 @@ static void finish(int sig, check_icmp_mode_switches modes, int min_hosts_alive,
|
|||
targets_alive(number_of_targets, program_state->targets_down));
|
||||
}
|
||||
|
||||
mp_check overall = mp_check_init();
|
||||
|
||||
// loop over targets to evaluate each one
|
||||
ping_target *host = target_list;
|
||||
int hosts_ok = 0;
|
||||
int hosts_warn = 0;
|
||||
while (host) {
|
||||
if (host->flags & FLAG_LOST_CAUSE) {
|
||||
program_state->targets_down++;
|
||||
}
|
||||
// TODO call evaluate here
|
||||
mp_subcheck sc_target = evaluate_target(*host, modes, warn, crit);
|
||||
int targets_ok = 0;
|
||||
int targets_warn = 0;
|
||||
for (unsigned short i = 0; i < number_of_hosts; i++) {
|
||||
evaluate_host_wrapper host_check = evaluate_host(host_list[i], modes, warn, crit);
|
||||
|
||||
mp_add_subcheck_to_check(&overall, sc_target);
|
||||
targets_ok += host_check.targets_ok;
|
||||
targets_warn += host_check.targets_warn;
|
||||
|
||||
mp_state_enum target_state = mp_compute_subcheck_state(sc_target);
|
||||
if (target_state == STATE_OK) {
|
||||
hosts_ok++;
|
||||
} else if (target_state == STATE_WARNING) {
|
||||
hosts_warn++;
|
||||
}
|
||||
mp_add_subcheck_to_check(overall, host_check.sc_host);
|
||||
}
|
||||
|
||||
host = host->next;
|
||||
if (number_of_hosts == 1) {
|
||||
// Exit early here, since the other checks only make sense for multiple hosts
|
||||
return;
|
||||
}
|
||||
|
||||
/* this is inevitable */
|
||||
|
|
@ -1432,7 +1430,7 @@ static void finish(int sig, check_icmp_mode_switches modes, int min_hosts_alive,
|
|||
mp_subcheck sc_no_target_alive = mp_subcheck_init();
|
||||
sc_no_target_alive = mp_set_subcheck_state(sc_no_target_alive, STATE_CRITICAL);
|
||||
sc_no_target_alive.output = strdup("No target is alive!");
|
||||
mp_add_subcheck_to_check(&overall, sc_no_target_alive);
|
||||
mp_add_subcheck_to_check(overall, sc_no_target_alive);
|
||||
}
|
||||
|
||||
if (min_hosts_alive > -1) {
|
||||
|
|
@ -1440,10 +1438,10 @@ static void finish(int sig, check_icmp_mode_switches modes, int min_hosts_alive,
|
|||
sc_min_targets_alive = mp_set_subcheck_default_state(sc_min_targets_alive, STATE_OK);
|
||||
|
||||
// TODO problably broken now
|
||||
if (hosts_ok >= min_hosts_alive) {
|
||||
if (targets_ok >= min_hosts_alive) {
|
||||
// TODO this should overwrite the main state
|
||||
sc_min_targets_alive = mp_set_subcheck_state(sc_min_targets_alive, STATE_OK);
|
||||
} else if ((hosts_ok + hosts_warn) >= min_hosts_alive) {
|
||||
} else if ((targets_ok + targets_warn) >= min_hosts_alive) {
|
||||
sc_min_targets_alive = mp_set_subcheck_state(sc_min_targets_alive, STATE_WARNING);
|
||||
}
|
||||
}
|
||||
|
|
@ -1453,10 +1451,8 @@ static void finish(int sig, check_icmp_mode_switches modes, int min_hosts_alive,
|
|||
printf(
|
||||
"targets: %u, targets_alive: %u, hosts_ok: %u, hosts_warn: %u, min_hosts_alive: %i\n",
|
||||
number_of_targets, targets_alive(number_of_targets, program_state->targets_down),
|
||||
hosts_ok, hosts_warn, min_hosts_alive);
|
||||
targets_ok, targets_warn, min_hosts_alive);
|
||||
}
|
||||
|
||||
mp_exit(overall);
|
||||
}
|
||||
|
||||
static time_t get_timevaldiff(const struct timeval earlier, const struct timeval later) {
|
||||
|
|
@ -1479,13 +1475,18 @@ static time_t get_timevaldiff_to_now(struct timeval earlier) {
|
|||
return get_timevaldiff(earlier, now);
|
||||
}
|
||||
|
||||
static add_target_ip_wrapper add_target_ip(char *arg, struct sockaddr_storage *address) {
|
||||
static add_target_ip_wrapper add_target_ip(struct sockaddr_storage address) {
|
||||
if (debug) {
|
||||
char straddr[INET6_ADDRSTRLEN];
|
||||
parse_address((struct sockaddr_storage *)&address, straddr, sizeof(straddr));
|
||||
printf("add_target_ip called with: %s\n", straddr);
|
||||
}
|
||||
struct sockaddr_in *sin;
|
||||
struct sockaddr_in6 *sin6;
|
||||
if (address_family == AF_INET) {
|
||||
sin = (struct sockaddr_in *)address;
|
||||
sin = (struct sockaddr_in *)&address;
|
||||
} else {
|
||||
sin6 = (struct sockaddr_in6 *)address;
|
||||
sin6 = (struct sockaddr_in6 *)&address;
|
||||
}
|
||||
|
||||
add_target_ip_wrapper result = {
|
||||
|
|
@ -1502,38 +1503,20 @@ static add_target_ip_wrapper add_target_ip(char *arg, struct sockaddr_storage *a
|
|||
return result;
|
||||
}
|
||||
|
||||
// TODO: allow duplicate targets for now, might be on purpose
|
||||
/* no point in adding two identical IP's, so don't. ;) */
|
||||
// struct sockaddr_in *host_sin;
|
||||
// struct sockaddr_in6 *host_sin6;
|
||||
// ping_target *host = host_list;
|
||||
// while (host) {
|
||||
// host_sin = (struct sockaddr_in *)&host->saddr_in;
|
||||
// host_sin6 = (struct sockaddr_in6 *)&host->saddr_in;
|
||||
|
||||
// if ((address_family == AF_INET && host_sin->sin_addr.s_addr == sin->sin_addr.s_addr) ||
|
||||
// (address_family == AF_INET6 &&
|
||||
// host_sin6->sin6_addr.s6_addr == sin6->sin6_addr.s6_addr)) {
|
||||
// if (debug) {
|
||||
// printf("Identical IP already exists. Not adding %s\n", arg);
|
||||
// }
|
||||
// return -1;
|
||||
// }
|
||||
// host = host->next;
|
||||
// }
|
||||
// get string representation of address
|
||||
char straddr[INET6_ADDRSTRLEN];
|
||||
parse_address((&address), straddr, sizeof(straddr));
|
||||
|
||||
/* add the fresh ip */
|
||||
ping_target *target = (ping_target *)calloc(1, sizeof(ping_target));
|
||||
if (!target) {
|
||||
char straddr[INET6_ADDRSTRLEN];
|
||||
parse_address((struct sockaddr_storage *)&address, straddr, sizeof(straddr));
|
||||
crash("add_target_ip(%s, %s): malloc(%lu) failed", arg, straddr, sizeof(ping_target));
|
||||
crash("add_target_ip(%s): malloc(%lu) failed", straddr, sizeof(ping_target));
|
||||
}
|
||||
|
||||
*target = ping_target_init();
|
||||
|
||||
/* set the values. use calling name for output */
|
||||
target->name = strdup(arg);
|
||||
target->name = strdup(straddr);
|
||||
|
||||
/* fill out the sockaddr_storage struct */
|
||||
struct sockaddr_in *host_sin;
|
||||
|
|
@ -1556,9 +1539,13 @@ static add_target_ip_wrapper add_target_ip(char *arg, struct sockaddr_storage *a
|
|||
|
||||
/* wrapper for add_target_ip */
|
||||
static add_target_wrapper add_target(char *arg, const check_icmp_execution_mode mode) {
|
||||
struct sockaddr_storage address_storage;
|
||||
struct sockaddr_in *sin;
|
||||
struct sockaddr_in6 *sin6;
|
||||
if (debug > 0) {
|
||||
printf("add_target called with argument %s\n", arg);
|
||||
}
|
||||
|
||||
struct sockaddr_storage address_storage = {};
|
||||
struct sockaddr_in *sin = NULL;
|
||||
struct sockaddr_in6 *sin6 = NULL;
|
||||
int error_code = -1;
|
||||
|
||||
switch (address_family) {
|
||||
|
|
@ -1598,7 +1585,7 @@ static add_target_wrapper add_target(char *arg, const check_icmp_execution_mode
|
|||
/* don't resolve if we don't have to */
|
||||
if (error_code == 1) {
|
||||
/* don't add all ip's if we were given a specific one */
|
||||
add_target_ip_wrapper targeted = add_target_ip(arg, &address_storage);
|
||||
add_target_ip_wrapper targeted = add_target_ip(address_storage);
|
||||
|
||||
if (targeted.error_code != OK) {
|
||||
result.error_code = ERROR;
|
||||
|
|
@ -1634,7 +1621,8 @@ static add_target_wrapper add_target(char *arg, const check_icmp_execution_mode
|
|||
for (struct addrinfo *address = res; address != NULL; address = address->ai_next) {
|
||||
struct sockaddr_storage temporary_ip_address;
|
||||
memcpy(&temporary_ip_address, address->ai_addr, address->ai_addrlen);
|
||||
add_target_ip_wrapper tmp = add_target_ip(arg, &temporary_ip_address);
|
||||
|
||||
add_target_ip_wrapper tmp = add_target_ip(temporary_ip_address);
|
||||
|
||||
if (tmp.error_code != OK) {
|
||||
// No proper error handling
|
||||
|
|
@ -2039,6 +2027,10 @@ void print_usage(void) {
|
|||
}
|
||||
|
||||
static add_host_wrapper add_host(char *arg, check_icmp_execution_mode mode) {
|
||||
if (debug) {
|
||||
printf("add_host called with argument %s\n", arg);
|
||||
}
|
||||
|
||||
add_host_wrapper result = {
|
||||
.error_code = OK,
|
||||
.host = check_icmp_target_container_init(),
|
||||
|
|
@ -2324,3 +2316,34 @@ mp_subcheck evaluate_target(ping_target target, check_icmp_mode_switches modes,
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
evaluate_host_wrapper evaluate_host(check_icmp_target_container host,
|
||||
check_icmp_mode_switches modes, check_icmp_threshold warn,
|
||||
check_icmp_threshold crit) {
|
||||
evaluate_host_wrapper result = {
|
||||
.targets_warn = 0,
|
||||
.targets_ok = 0,
|
||||
.sc_host = mp_subcheck_init(),
|
||||
};
|
||||
result.sc_host = mp_set_subcheck_default_state(result.sc_host, STATE_OK);
|
||||
|
||||
result.sc_host.output = strdup(host.name);
|
||||
|
||||
ping_target *target = host.target_list;
|
||||
for (unsigned int i = 0; i < host.number_of_targets; i++) {
|
||||
mp_subcheck sc_target = evaluate_target(*target, modes, warn, crit);
|
||||
|
||||
mp_state_enum target_state = mp_compute_subcheck_state(sc_target);
|
||||
|
||||
if (target_state == STATE_WARNING) {
|
||||
result.targets_warn++;
|
||||
} else if (target_state == STATE_OK) {
|
||||
result.targets_ok++;
|
||||
}
|
||||
mp_add_subcheck_to_subcheck(&result.sc_host, sc_target);
|
||||
|
||||
target = target->next;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue