summaryrefslogtreecommitdiffstats
path: root/plugins-root
diff options
context:
space:
mode:
Diffstat (limited to 'plugins-root')
-rw-r--r--plugins-root/check_icmp.c704
-rw-r--r--plugins-root/check_icmp.d/check_icmp_helpers.c22
-rw-r--r--plugins-root/check_icmp.d/check_icmp_helpers.h13
-rw-r--r--plugins-root/check_icmp.d/config.h4
4 files changed, 360 insertions, 383 deletions
diff --git a/plugins-root/check_icmp.c b/plugins-root/check_icmp.c
index 8565f32d..34adf6fe 100644
--- a/plugins-root/check_icmp.c
+++ b/plugins-root/check_icmp.c
@@ -46,6 +46,8 @@ const char *email = "devel@monitoring-plugins.org";
46#include "../plugins/common.h" 46#include "../plugins/common.h"
47#include "netutils.h" 47#include "netutils.h"
48#include "utils.h" 48#include "utils.h"
49#include "output.h"
50#include "perfdata.h"
49 51
50#if HAVE_SYS_SOCKIO_H 52#if HAVE_SYS_SOCKIO_H
51# include <sys/sockio.h> 53# include <sys/sockio.h>
@@ -182,8 +184,7 @@ static parse_threshold2_helper_wrapper parse_threshold2_helper(char *threshold_s
182 threshold_mode mode); 184 threshold_mode mode);
183 185
184/* main test function */ 186/* main test function */
185static void run_checks(bool order_mode, bool mos_mode, bool rta_mode, bool pl_mode, 187static void run_checks(check_icmp_mode_switches modes, int min_hosts_alive,
186 bool jitter_mode, bool score_mode, int min_hosts_alive,
187 unsigned short icmp_pkt_size, unsigned int *pkt_interval, 188 unsigned short icmp_pkt_size, unsigned int *pkt_interval,
188 unsigned int *target_interval, check_icmp_threshold warn, 189 unsigned int *target_interval, check_icmp_threshold warn,
189 check_icmp_threshold crit, uint16_t sender_id, 190 check_icmp_threshold crit, uint16_t sender_id,
@@ -191,6 +192,8 @@ static void run_checks(bool order_mode, bool mos_mode, bool rta_mode, bool pl_mo
191 struct timeval prog_start, ping_target **table, unsigned short packets, 192 struct timeval prog_start, ping_target **table, unsigned short packets,
192 int icmp_sock, unsigned short number_of_targets, 193 int icmp_sock, unsigned short number_of_targets,
193 check_icmp_state *program_state, ping_target *target_list); 194 check_icmp_state *program_state, ping_target *target_list);
195mp_subcheck evaluate_target(ping_target target, check_icmp_mode_switches modes,
196 check_icmp_threshold warn, check_icmp_threshold crit);
194 197
195/* Target aquisition */ 198/* Target aquisition */
196typedef struct { 199typedef struct {
@@ -198,6 +201,7 @@ typedef struct {
198 check_icmp_target_container host; 201 check_icmp_target_container host;
199} add_host_wrapper; 202} add_host_wrapper;
200static add_host_wrapper add_host(char *arg, check_icmp_execution_mode mode); 203static add_host_wrapper add_host(char *arg, check_icmp_execution_mode mode);
204
201typedef struct { 205typedef struct {
202 int error_code; 206 int error_code;
203 ping_target *targets; 207 ping_target *targets;
@@ -216,11 +220,10 @@ static void parse_address(struct sockaddr_storage *addr, char *address, socklen_
216static unsigned short icmp_checksum(uint16_t *packet, size_t packet_size); 220static unsigned short icmp_checksum(uint16_t *packet, size_t packet_size);
217 221
218/* End of run function */ 222/* End of run function */
219static void finish(int /*sig*/, bool order_mode, bool mos_mode, bool rta_mode, bool pl_mode, 223static void finish(int sign, check_icmp_mode_switches modes, int min_hosts_alive,
220 bool jitter_mode, bool score_mode, int min_hosts_alive,
221 check_icmp_threshold warn, check_icmp_threshold crit, int icmp_sock, 224 check_icmp_threshold warn, check_icmp_threshold crit, int icmp_sock,
222 unsigned short number_of_targets, check_icmp_state *program_state, 225 unsigned short number_of_targets, check_icmp_state *program_state,
223 ping_target *target_list); 226 ping_target *target_list) __attribute__((noreturn));
224 227
225/* Error exit */ 228/* Error exit */
226static void crash(const char *fmt, ...); 229static void crash(const char *fmt, ...);
@@ -336,6 +339,7 @@ check_icmp_config_wrapper process_arguments(int argc, char **argv) {
336 /* Reset argument scanning */ 339 /* Reset argument scanning */
337 optind = 1; 340 optind = 1;
338 341
342 int host_counter = 0;
339 /* parse the arguments */ 343 /* parse the arguments */
340 for (int i = 1; i < argc; i++) { 344 for (int i = 1; i < argc; i++) {
341 long int arg; 345 long int arg;
@@ -391,15 +395,20 @@ check_icmp_config_wrapper process_arguments(int argc, char **argv) {
391 // TODO die here and complain about wrong input 395 // TODO die here and complain about wrong input
392 break; 396 break;
393 case 'H': { 397 case 'H': {
394 add_target_wrapper add_result = add_target(optarg, result.config.mode); 398 add_host_wrapper host_add_result = add_host(optarg, result.config.mode);
395 if (add_result.error_code == OK) { 399 if (host_add_result.error_code == OK) {
400 result.config.hosts[host_counter] = host_add_result.host;
401 host_counter++;
402
396 if (result.config.targets != NULL) { 403 if (result.config.targets != NULL) {
397 result.config.number_of_targets += 404 result.config.number_of_targets += ping_target_list_append(
398 ping_target_list_append(result.config.targets, add_result.targets); 405 result.config.targets, host_add_result.host.target_list);
399 } else { 406 } else {
400 result.config.targets = add_result.targets; 407 result.config.targets = host_add_result.host.target_list;
401 result.config.number_of_targets += add_result.number_of_targets; 408 result.config.number_of_targets += host_add_result.host.number_of_targets;
402 } 409 }
410 } else {
411 // TODO adding host failed, crash here
403 } 412 }
404 } break; 413 } break;
405 case 'l': 414 case 'l':
@@ -428,7 +437,7 @@ check_icmp_config_wrapper process_arguments(int argc, char **argv) {
428 437
429 result.config.warn = rta_th.warn; 438 result.config.warn = rta_th.warn;
430 result.config.crit = rta_th.crit; 439 result.config.crit = rta_th.crit;
431 result.config.rta_mode = true; 440 result.config.modes.rta_mode = true;
432 } break; 441 } break;
433 case 'P': /* packet loss mode */ { 442 case 'P': /* packet loss mode */ {
434 get_threshold2_wrapper pl_th = 443 get_threshold2_wrapper pl_th =
@@ -440,7 +449,7 @@ check_icmp_config_wrapper process_arguments(int argc, char **argv) {
440 449
441 result.config.warn = pl_th.warn; 450 result.config.warn = pl_th.warn;
442 result.config.crit = pl_th.crit; 451 result.config.crit = pl_th.crit;
443 result.config.pl_mode = true; 452 result.config.modes.pl_mode = true;
444 } break; 453 } break;
445 case 'J': /* jitter mode */ { 454 case 'J': /* jitter mode */ {
446 get_threshold2_wrapper jitter_th = 455 get_threshold2_wrapper jitter_th =
@@ -452,7 +461,7 @@ check_icmp_config_wrapper process_arguments(int argc, char **argv) {
452 461
453 result.config.warn = jitter_th.warn; 462 result.config.warn = jitter_th.warn;
454 result.config.crit = jitter_th.crit; 463 result.config.crit = jitter_th.crit;
455 result.config.jitter_mode = true; 464 result.config.modes.jitter_mode = true;
456 } break; 465 } break;
457 case 'M': /* MOS mode */ { 466 case 'M': /* MOS mode */ {
458 get_threshold2_wrapper mos_th = get_threshold2( 467 get_threshold2_wrapper mos_th = get_threshold2(
@@ -463,7 +472,7 @@ check_icmp_config_wrapper process_arguments(int argc, char **argv) {
463 472
464 result.config.warn = mos_th.warn; 473 result.config.warn = mos_th.warn;
465 result.config.crit = mos_th.crit; 474 result.config.crit = mos_th.crit;
466 result.config.mos_mode = true; 475 result.config.modes.mos_mode = true;
467 } break; 476 } break;
468 case 'S': /* score mode */ { 477 case 'S': /* score mode */ {
469 get_threshold2_wrapper score_th = 478 get_threshold2_wrapper score_th =
@@ -475,10 +484,10 @@ check_icmp_config_wrapper process_arguments(int argc, char **argv) {
475 484
476 result.config.warn = score_th.warn; 485 result.config.warn = score_th.warn;
477 result.config.crit = score_th.crit; 486 result.config.crit = score_th.crit;
478 result.config.score_mode = true; 487 result.config.modes.score_mode = true;
479 } break; 488 } break;
480 case 'O': /* out of order mode */ 489 case 'O': /* out of order mode */
481 result.config.order_mode = true; 490 result.config.modes.order_mode = true;
482 break; 491 break;
483 } 492 }
484 } 493 }
@@ -869,22 +878,19 @@ int main(int argc, char **argv) {
869 878
870 check_icmp_state program_state = check_icmp_state_init(); 879 check_icmp_state program_state = check_icmp_state_init();
871 880
872 run_checks(config.order_mode, config.mos_mode, config.rta_mode, config.pl_mode, 881 run_checks(config.modes, config.min_hosts_alive, config.icmp_data_size,
873 config.jitter_mode, config.score_mode, config.min_hosts_alive, config.icmp_data_size,
874 &pkt_interval, &target_interval, config.warn, config.crit, config.sender_id, 882 &pkt_interval, &target_interval, config.warn, config.crit, config.sender_id,
875 config.mode, max_completion_time, prog_start, table, config.number_of_packets, 883 config.mode, max_completion_time, prog_start, table, config.number_of_packets,
876 icmp_sock, config.number_of_targets, &program_state, config.targets); 884 icmp_sock, config.number_of_targets, &program_state, config.targets);
877 885
878 errno = 0; 886 errno = 0;
879 finish(0, config.order_mode, config.mos_mode, config.rta_mode, config.pl_mode, 887 finish(0, config.modes, config.min_hosts_alive, config.warn, config.crit,
880 config.jitter_mode, config.score_mode, config.min_hosts_alive, config.warn, config.crit,
881 icmp_sock, config.number_of_targets, &program_state, config.targets); 888 icmp_sock, config.number_of_targets, &program_state, config.targets);
882 889
883 return (0); 890 return (0);
884} 891}
885 892
886static void run_checks(bool order_mode, bool mos_mode, bool rta_mode, bool pl_mode, 893static void run_checks(check_icmp_mode_switches modes, int min_hosts_alive,
887 bool jitter_mode, bool score_mode, int min_hosts_alive,
888 unsigned short icmp_pkt_size, unsigned int *pkt_interval, 894 unsigned short icmp_pkt_size, unsigned int *pkt_interval,
889 unsigned int *target_interval, check_icmp_threshold warn, 895 unsigned int *target_interval, check_icmp_threshold warn,
890 check_icmp_threshold crit, const uint16_t sender_id, 896 check_icmp_threshold crit, const uint16_t sender_id,
@@ -900,7 +906,7 @@ static void run_checks(bool order_mode, bool mos_mode, bool rta_mode, bool pl_mo
900 for (unsigned int target_index = 0; target_index < number_of_targets; target_index++) { 906 for (unsigned int target_index = 0; target_index < number_of_targets; target_index++) {
901 /* don't send useless packets */ 907 /* don't send useless packets */
902 if (!targets_alive(number_of_targets, program_state->targets_down)) { 908 if (!targets_alive(number_of_targets, program_state->targets_down)) {
903 finish(0, order_mode, mos_mode, rta_mode, pl_mode, jitter_mode, score_mode, 909 finish(0, modes,
904 min_hosts_alive, warn, crit, icmp_sock, number_of_targets, program_state, 910 min_hosts_alive, warn, crit, icmp_sock, number_of_targets, program_state,
905 target_list); 911 target_list);
906 } 912 }
@@ -947,7 +953,7 @@ static void run_checks(bool order_mode, bool mos_mode, bool rta_mode, bool pl_mo
947 if (debug) { 953 if (debug) {
948 printf("Time passed. Finishing up\n"); 954 printf("Time passed. Finishing up\n");
949 } 955 }
950 finish(0, order_mode, mos_mode, rta_mode, pl_mode, jitter_mode, score_mode, 956 finish(0, modes,
951 min_hosts_alive, warn, crit, icmp_sock, number_of_targets, program_state, 957 min_hosts_alive, warn, crit, icmp_sock, number_of_targets, program_state,
952 target_list); 958 target_list);
953 } 959 }
@@ -1139,7 +1145,7 @@ static int wait_for_reply(int sock, const time_t time_interval, unsigned short i
1139 1145
1140 /* Check if packets in order */ 1146 /* Check if packets in order */
1141 if (target->last_icmp_seq >= packet.icp->icmp_seq) { 1147 if (target->last_icmp_seq >= packet.icp->icmp_seq) {
1142 target->order_status = STATE_CRITICAL; 1148 target->found_out_of_order_packets = true;
1143 } 1149 }
1144 } 1150 }
1145 target->last_tdiff = tdiff; 1151 target->last_tdiff = tdiff;
@@ -1376,8 +1382,7 @@ static ssize_t recvfrom_wto(const int sock, void *buf, const unsigned int len,
1376 return (ret); 1382 return (ret);
1377} 1383}
1378 1384
1379static void finish(int sig, bool order_mode, bool mos_mode, bool rta_mode, bool pl_mode, 1385static void finish(int sig, check_icmp_mode_switches modes, int min_hosts_alive,
1380 bool jitter_mode, bool score_mode, int min_hosts_alive,
1381 check_icmp_threshold warn, check_icmp_threshold crit, const int icmp_sock, 1386 check_icmp_threshold warn, check_icmp_threshold crit, const int icmp_sock,
1382 const unsigned short number_of_targets, check_icmp_state *program_state, 1387 const unsigned short number_of_targets, check_icmp_state *program_state,
1383 ping_target *target_list) { 1388 ping_target *target_list) {
@@ -1399,358 +1404,53 @@ static void finish(int sig, bool order_mode, bool mos_mode, bool rta_mode, bool
1399 targets_alive(number_of_targets, program_state->targets_down)); 1404 targets_alive(number_of_targets, program_state->targets_down));
1400 } 1405 }
1401 1406
1402 /* iterate thrice to calculate values, give output, and print perfparse */ 1407 mp_check overall = mp_check_init();
1403 mp_state_enum status = STATE_OK;
1404 ping_target *host = target_list;
1405 1408
1406 unsigned int target_counter = 0; 1409 // loop over targets to evaluate each one
1407 const char *status_string[] = {"OK", "WARNING", "CRITICAL", "UNKNOWN", "DEPENDENT"}; 1410 ping_target *host = target_list;
1408 int hosts_ok = 0; 1411 int hosts_ok = 0;
1409 int hosts_warn = 0; 1412 int hosts_warn = 0;
1410 while (host) { 1413 while (host) {
1411 mp_state_enum this_status = STATE_OK; 1414 if (host->flags & FLAG_LOST_CAUSE) {
1412 1415 program_state->targets_down++;
1413 unsigned char packet_loss;
1414 double rta;
1415 if (!host->icmp_recv) {
1416 /* rta 0 is ofcourse not entirely correct, but will still show up
1417 * conspicuously as missing entries in perfparse and cacti */
1418 packet_loss = 100;
1419 rta = 0;
1420 status = STATE_CRITICAL;
1421 /* up the down counter if not already counted */
1422 if (!(host->flags & FLAG_LOST_CAUSE) &&
1423 targets_alive(number_of_targets, program_state->targets_down)) {
1424 program_state->targets_down++;
1425 }
1426 } else {
1427 packet_loss =
1428 (unsigned char)((host->icmp_sent - host->icmp_recv) * 100) / host->icmp_sent;
1429 rta = (double)host->time_waited / host->icmp_recv;
1430 }
1431
1432 if (host->icmp_recv > 1) {
1433 /*
1434 * This algorithm is probably pretty much blindly copied from
1435 * locations like this one:
1436 * https://www.slac.stanford.edu/comp/net/wan-mon/tutorial.html#mos It calculates a MOS
1437 * value (range of 1 to 5, where 1 is bad and 5 really good). According to some quick
1438 * research MOS originates from the Audio/Video transport network area. Whether it can
1439 * and should be computed from ICMP data, I can not say.
1440 *
1441 * Anyway the basic idea is to map a value "R" with a range of 0-100 to the MOS value
1442 *
1443 * MOS stands likely for Mean Opinion Score (
1444 * https://en.wikipedia.org/wiki/Mean_Opinion_Score )
1445 *
1446 * More links:
1447 * - https://confluence.slac.stanford.edu/display/IEPM/MOS
1448 */
1449 host->jitter = (host->jitter / (host->icmp_recv - 1) / 1000);
1450
1451 /*
1452 * Take the average round trip latency (in milliseconds), add
1453 * round trip jitter, but double the impact to latency
1454 * then add 10 for protocol latencies (in milliseconds).
1455 */
1456 host->EffectiveLatency = (rta / 1000) + host->jitter * 2 + 10;
1457
1458 double R;
1459 if (host->EffectiveLatency < 160) {
1460 R = 93.2 - (host->EffectiveLatency / 40);
1461 } else {
1462 R = 93.2 - ((host->EffectiveLatency - 120) / 10);
1463 }
1464
1465 // Now, let us deduct 2.5 R values per percentage of packet loss (i.e. a
1466 // loss of 5% will be entered as 5).
1467 R = R - (packet_loss * 2.5);
1468
1469 if (R < 0) {
1470 R = 0;
1471 }
1472
1473 host->score = R;
1474 host->mos = 1 + ((0.035) * R) + ((.000007) * R * (R - 60) * (100 - R));
1475 } else {
1476 host->jitter = 0;
1477 host->jitter_min = 0;
1478 host->jitter_max = 0;
1479 host->mos = 0;
1480 }
1481
1482 host->pl = packet_loss;
1483 host->rta = rta;
1484
1485 /* if no new mode selected, use old schema */
1486 if (!rta_mode && !pl_mode && !jitter_mode && !score_mode && !mos_mode && !order_mode) {
1487 rta_mode = true;
1488 pl_mode = true;
1489 }
1490
1491 /* Check which mode is on and do the warn / Crit stuff */
1492 if (rta_mode) {
1493 if (rta >= crit.rta) {
1494 this_status = STATE_CRITICAL;
1495 status = STATE_CRITICAL;
1496 host->rta_status = STATE_CRITICAL;
1497 } else if (status != STATE_CRITICAL && (rta >= warn.rta)) {
1498 this_status = (this_status <= STATE_WARNING ? STATE_WARNING : this_status);
1499 status = STATE_WARNING;
1500 host->rta_status = STATE_WARNING;
1501 }
1502 }
1503
1504 if (pl_mode) {
1505 if (packet_loss >= crit.pl) {
1506 this_status = STATE_CRITICAL;
1507 status = STATE_CRITICAL;
1508 host->pl_status = STATE_CRITICAL;
1509 } else if (status != STATE_CRITICAL && (packet_loss >= warn.pl)) {
1510 this_status = (this_status <= STATE_WARNING ? STATE_WARNING : this_status);
1511 status = STATE_WARNING;
1512 host->pl_status = STATE_WARNING;
1513 }
1514 } 1416 }
1417 // TODO call evaluate here
1418 mp_subcheck sc_target = evaluate_target(*host, modes, warn, crit);
1515 1419
1516 if (jitter_mode) { 1420 mp_add_subcheck_to_check(&overall, sc_target);
1517 if (host->jitter >= crit.jitter) {
1518 this_status = STATE_CRITICAL;
1519 status = STATE_CRITICAL;
1520 host->jitter_status = STATE_CRITICAL;
1521 } else if (status != STATE_CRITICAL && (host->jitter >= warn.jitter)) {
1522 this_status = (this_status <= STATE_WARNING ? STATE_WARNING : this_status);
1523 status = STATE_WARNING;
1524 host->jitter_status = STATE_WARNING;
1525 }
1526 }
1527 1421
1528 if (mos_mode) { 1422 mp_state_enum target_state = mp_compute_subcheck_state(sc_target);
1529 if (host->mos <= crit.mos) { 1423 if (target_state == STATE_OK) {
1530 this_status = STATE_CRITICAL;
1531 status = STATE_CRITICAL;
1532 host->mos_status = STATE_CRITICAL;
1533 } else if (status != STATE_CRITICAL && (host->mos <= warn.mos)) {
1534 this_status = (this_status <= STATE_WARNING ? STATE_WARNING : this_status);
1535 status = STATE_WARNING;
1536 host->mos_status = STATE_WARNING;
1537 }
1538 }
1539
1540 if (score_mode) {
1541 if (host->score <= crit.score) {
1542 this_status = STATE_CRITICAL;
1543 status = STATE_CRITICAL;
1544 host->score_status = STATE_CRITICAL;
1545 } else if (status != STATE_CRITICAL && (host->score <= warn.score)) {
1546 this_status = (this_status <= STATE_WARNING ? STATE_WARNING : this_status);
1547 status = STATE_WARNING;
1548 host->score_status = STATE_WARNING;
1549 }
1550 }
1551
1552 if (this_status == STATE_WARNING) {
1553 hosts_warn++;
1554 } else if (this_status == STATE_OK) {
1555 hosts_ok++; 1424 hosts_ok++;
1425 } else if (target_state == STATE_WARNING) {
1426 hosts_warn++;
1556 } 1427 }
1557 1428
1558 host = host->next; 1429 host = host->next;
1559 } 1430 }
1560 1431
1561 /* this is inevitable */ 1432 /* this is inevitable */
1562 if (!targets_alive(number_of_targets, program_state->targets_down)) { 1433 if (targets_alive(number_of_targets, program_state->targets_down) == 0) {
1563 status = STATE_CRITICAL; 1434 mp_subcheck sc_no_target_alive = mp_subcheck_init();
1564 } 1435 sc_no_target_alive = mp_set_subcheck_state(sc_no_target_alive, STATE_CRITICAL);
1565 if (min_hosts_alive > -1) { 1436 sc_no_target_alive.output = strdup("No target is alive!");
1566 if (hosts_ok >= min_hosts_alive) { 1437 mp_add_subcheck_to_check(&overall, sc_no_target_alive);
1567 status = STATE_OK;
1568 } else if ((hosts_ok + hosts_warn) >= min_hosts_alive) {
1569 status = STATE_WARNING;
1570 }
1571 }
1572 printf("%s - ", status_string[status]);
1573
1574 host = target_list;
1575 while (host) {
1576 if (debug) {
1577 puts("");
1578 }
1579
1580 if (target_counter) {
1581 if (target_counter < number_of_targets) {
1582 printf(" :: ");
1583 } else {
1584 printf("\n");
1585 }
1586 }
1587
1588 target_counter++;
1589
1590 if (!host->icmp_recv) {
1591 status = STATE_CRITICAL;
1592 host->rtmin = 0;
1593 host->jitter_min = 0;
1594
1595 if (host->flags & FLAG_LOST_CAUSE) {
1596 char address[INET6_ADDRSTRLEN];
1597 parse_address(&host->error_addr, address, sizeof(address));
1598 printf("%s: %s @ %s. rta nan, lost %d%%", host->name,
1599 get_icmp_error_msg(host->icmp_type, host->icmp_code), address, 100);
1600 } else { /* not marked as lost cause, so we have no flags for it */
1601 printf("%s: rta nan, lost 100%%", host->name);
1602 }
1603 } else { /* !icmp_recv */
1604 printf("%s", host->name);
1605 /* rta text output */
1606 if (rta_mode) {
1607 if (status == STATE_OK) {
1608 printf(" rta %0.3fms", host->rta / 1000);
1609 } else if (status == STATE_WARNING && host->rta_status == status) {
1610 printf(" rta %0.3fms > %0.3fms", (float)host->rta / 1000,
1611 (float)warn.rta / 1000);
1612 } else if (status == STATE_CRITICAL && host->rta_status == status) {
1613 printf(" rta %0.3fms > %0.3fms", (float)host->rta / 1000,
1614 (float)crit.rta / 1000);
1615 }
1616 }
1617
1618 /* pl text output */
1619 if (pl_mode) {
1620 if (status == STATE_OK) {
1621 printf(" lost %u%%", host->pl);
1622 } else if (status == STATE_WARNING && host->pl_status == status) {
1623 printf(" lost %u%% > %u%%", host->pl, warn.pl);
1624 } else if (status == STATE_CRITICAL && host->pl_status == status) {
1625 printf(" lost %u%% > %u%%", host->pl, crit.pl);
1626 }
1627 }
1628
1629 /* jitter text output */
1630 if (jitter_mode) {
1631 if (status == STATE_OK) {
1632 printf(" jitter %0.3fms", (float)host->jitter);
1633 } else if (status == STATE_WARNING && host->jitter_status == status) {
1634 printf(" jitter %0.3fms > %0.3fms", (float)host->jitter, warn.jitter);
1635 } else if (status == STATE_CRITICAL && host->jitter_status == status) {
1636 printf(" jitter %0.3fms > %0.3fms", (float)host->jitter, crit.jitter);
1637 }
1638 }
1639
1640 /* mos text output */
1641 if (mos_mode) {
1642 if (status == STATE_OK) {
1643 printf(" MOS %0.1f", (float)host->mos);
1644 } else if (status == STATE_WARNING && host->mos_status == status) {
1645 printf(" MOS %0.1f < %0.1f", (float)host->mos, (float)warn.mos);
1646 } else if (status == STATE_CRITICAL && host->mos_status == status) {
1647 printf(" MOS %0.1f < %0.1f", (float)host->mos, (float)crit.mos);
1648 }
1649 }
1650
1651 /* score text output */
1652 if (score_mode) {
1653 if (status == STATE_OK) {
1654 printf(" Score %u", (int)host->score);
1655 } else if (status == STATE_WARNING && host->score_status == status) {
1656 printf(" Score %u < %u", (int)host->score, (int)warn.score);
1657 } else if (status == STATE_CRITICAL && host->score_status == status) {
1658 printf(" Score %u < %u", (int)host->score, (int)crit.score);
1659 }
1660 }
1661
1662 /* order statis text output */
1663 if (order_mode) {
1664 if (status == STATE_OK) {
1665 printf(" Packets in order");
1666 } else if (status == STATE_CRITICAL && host->order_status == status) {
1667 printf(" Packets out of order");
1668 }
1669 }
1670 }
1671 host = host->next;
1672 }
1673
1674 /* iterate once more for pretty perfparse output */
1675 if (!(!rta_mode && !pl_mode && !jitter_mode && !score_mode && !mos_mode && order_mode)) {
1676 printf("|");
1677 }
1678
1679 target_counter = 0;
1680 host = target_list;
1681 while (host) {
1682 if (debug) {
1683 puts("");
1684 }
1685
1686 if (rta_mode) {
1687 if (host->pl < 100) {
1688 printf("%srta=%0.3fms;%0.3f;%0.3f;0; %srtmax=%0.3fms;;;; %srtmin=%0.3fms;;;; ",
1689 (number_of_targets > 1) ? host->name : "", host->rta / 1000,
1690 (float)warn.rta / 1000, (float)crit.rta / 1000,
1691 (number_of_targets > 1) ? host->name : "", (float)host->rtmax / 1000,
1692 (number_of_targets > 1) ? host->name : "",
1693 (host->rtmin < INFINITY) ? (float)host->rtmin / 1000 : (float)0);
1694 } else {
1695 printf("%srta=U;;;; %srtmax=U;;;; %srtmin=U;;;; ",
1696 (number_of_targets > 1) ? host->name : "",
1697 (number_of_targets > 1) ? host->name : "",
1698 (number_of_targets > 1) ? host->name : "");
1699 }
1700 }
1701
1702 if (pl_mode) {
1703 printf("%spl=%u%%;%u;%u;0;100 ", (number_of_targets > 1) ? host->name : "", host->pl,
1704 warn.pl, crit.pl);
1705 }
1706
1707 if (jitter_mode) {
1708 if (host->pl < 100) {
1709 printf("%sjitter_avg=%0.3fms;%0.3f;%0.3f;0; %sjitter_max=%0.3fms;;;; "
1710 "%sjitter_min=%0.3fms;;;; ",
1711 (number_of_targets > 1) ? host->name : "", (float)host->jitter,
1712 (float)warn.jitter, (float)crit.jitter,
1713 (number_of_targets > 1) ? host->name : "", (float)host->jitter_max / 1000,
1714 (number_of_targets > 1) ? host->name : "", (float)host->jitter_min / 1000);
1715 } else {
1716 printf("%sjitter_avg=U;;;; %sjitter_max=U;;;; %sjitter_min=U;;;; ",
1717 (number_of_targets > 1) ? host->name : "",
1718 (number_of_targets > 1) ? host->name : "",
1719 (number_of_targets > 1) ? host->name : "");
1720 }
1721 }
1722
1723 if (mos_mode) {
1724 if (host->pl < 100) {
1725 printf("%smos=%0.1f;%0.1f;%0.1f;0;5 ", (number_of_targets > 1) ? host->name : "",
1726 (float)host->mos, (float)warn.mos, (float)crit.mos);
1727 } else {
1728 printf("%smos=U;;;; ", (number_of_targets > 1) ? host->name : "");
1729 }
1730 }
1731
1732 if (score_mode) {
1733 if (host->pl < 100) {
1734 printf("%sscore=%u;%u;%u;0;100 ", (number_of_targets > 1) ? host->name : "",
1735 (int)host->score, (int)warn.score, (int)crit.score);
1736 } else {
1737 printf("%sscore=U;;;; ", (number_of_targets > 1) ? host->name : "");
1738 }
1739 }
1740
1741 host = host->next;
1742 } 1438 }
1743 1439
1744 if (min_hosts_alive > -1) { 1440 if (min_hosts_alive > -1) {
1441 mp_subcheck sc_min_targets_alive = mp_subcheck_init();
1442 sc_min_targets_alive = mp_set_subcheck_default_state(sc_min_targets_alive, STATE_OK);
1443
1444 // TODO problably broken now
1745 if (hosts_ok >= min_hosts_alive) { 1445 if (hosts_ok >= min_hosts_alive) {
1746 status = STATE_OK; 1446 // TODO this should overwrite the main state
1447 sc_min_targets_alive = mp_set_subcheck_state(sc_min_targets_alive, STATE_OK);
1747 } else if ((hosts_ok + hosts_warn) >= min_hosts_alive) { 1448 } else if ((hosts_ok + hosts_warn) >= min_hosts_alive) {
1748 status = STATE_WARNING; 1449 sc_min_targets_alive = mp_set_subcheck_state(sc_min_targets_alive, STATE_WARNING);
1749 } 1450 }
1750 } 1451 }
1751 1452
1752 /* finish with an empty line */ 1453 /* finish with an empty line */
1753 puts("");
1754 if (debug) { 1454 if (debug) {
1755 printf( 1455 printf(
1756 "targets: %u, targets_alive: %u, hosts_ok: %u, hosts_warn: %u, min_hosts_alive: %i\n", 1456 "targets: %u, targets_alive: %u, hosts_ok: %u, hosts_warn: %u, min_hosts_alive: %i\n",
@@ -1758,7 +1458,7 @@ static void finish(int sig, bool order_mode, bool mos_mode, bool rta_mode, bool
1758 hosts_ok, hosts_warn, min_hosts_alive); 1458 hosts_ok, hosts_warn, min_hosts_alive);
1759 } 1459 }
1760 1460
1761 exit(status); 1461 mp_exit(overall);
1762} 1462}
1763 1463
1764static time_t get_timevaldiff(const struct timeval earlier, const struct timeval later) { 1464static time_t get_timevaldiff(const struct timeval earlier, const struct timeval later) {
@@ -1825,7 +1525,7 @@ static add_target_ip_wrapper add_target_ip(char *arg, struct sockaddr_storage *a
1825 // } 1525 // }
1826 1526
1827 /* add the fresh ip */ 1527 /* add the fresh ip */
1828 ping_target *target = (ping_target *)malloc(sizeof(ping_target)); 1528 ping_target *target = (ping_target *)calloc(1, sizeof(ping_target));
1829 if (!target) { 1529 if (!target) {
1830 char straddr[INET6_ADDRSTRLEN]; 1530 char straddr[INET6_ADDRSTRLEN];
1831 parse_address((struct sockaddr_storage *)&address, straddr, sizeof(straddr)); 1531 parse_address((struct sockaddr_storage *)&address, straddr, sizeof(straddr));
@@ -2339,3 +2039,289 @@ void print_usage(void) {
2339 printf("%s\n", _("Usage:")); 2039 printf("%s\n", _("Usage:"));
2340 printf(" %s [options] [-H] host1 host2 hostN\n", progname); 2040 printf(" %s [options] [-H] host1 host2 hostN\n", progname);
2341} 2041}
2042
2043static add_host_wrapper add_host(char *arg, check_icmp_execution_mode mode) {
2044 add_host_wrapper result = {
2045 .error_code = OK,
2046 .host = check_icmp_target_container_init(),
2047 };
2048
2049 add_target_wrapper targets = add_target(arg, mode);
2050
2051 if (targets.error_code != OK) {
2052 result.error_code = targets.error_code;
2053 return result;
2054 }
2055
2056 result.host = check_icmp_target_container_init();
2057
2058 result.host.name = strdup(arg);
2059 result.host.target_list = targets.targets;
2060 result.host.number_of_targets = targets.number_of_targets;
2061
2062 return result;
2063}
2064
2065mp_subcheck evaluate_target(ping_target target, check_icmp_mode_switches modes,
2066 check_icmp_threshold warn, check_icmp_threshold crit) {
2067 /* if no new mode selected, use old schema */
2068 if (!modes.rta_mode && !modes.pl_mode && !modes.jitter_mode && !modes.score_mode && !modes.mos_mode && !modes.order_mode) {
2069 modes.rta_mode = true;
2070 modes.pl_mode = true;
2071 }
2072
2073 mp_subcheck result = mp_subcheck_init();
2074 result = mp_set_subcheck_default_state(result, STATE_OK);
2075 xasprintf(&result.output, "%s", target.name);
2076
2077 double packet_loss;
2078 double rta;
2079 if (!target.icmp_recv) {
2080 /* rta 0 is of course not entirely correct, but will still show up
2081 * conspicuously as missing entries in perfparse and cacti */
2082 packet_loss = 100;
2083 rta = 0;
2084 result = mp_set_subcheck_state(result, STATE_CRITICAL);
2085 /* up the down counter if not already counted */
2086
2087 if (target.flags & FLAG_LOST_CAUSE) {
2088 char address[INET6_ADDRSTRLEN];
2089 parse_address(&target.error_addr, address, sizeof(address));
2090 xasprintf(&result.output, "%s: %s @ %s", result.output,
2091 get_icmp_error_msg(target.icmp_type, target.icmp_code), address);
2092 } else { /* not marked as lost cause, so we have no flags for it */
2093 xasprintf(&result.output, "%s", result.output);
2094 }
2095 } else {
2096 packet_loss =
2097 (unsigned char)((target.icmp_sent - target.icmp_recv) * 100) / target.icmp_sent;
2098 rta = (double)target.time_waited / target.icmp_recv;
2099 }
2100
2101 double EffectiveLatency;
2102 double mos; /* Mean opinion score */
2103 double score; /* score */
2104
2105 if (target.icmp_recv > 1) {
2106 /*
2107 * This algorithm is probably pretty much blindly copied from
2108 * locations like this one:
2109 * https://www.slac.stanford.edu/comp/net/wan-mon/tutorial.html#mos It calculates a MOS
2110 * value (range of 1 to 5, where 1 is bad and 5 really good). According to some quick
2111 * research MOS originates from the Audio/Video transport network area. Whether it can
2112 * and should be computed from ICMP data, I can not say.
2113 *
2114 * Anyway the basic idea is to map a value "R" with a range of 0-100 to the MOS value
2115 *
2116 * MOS stands likely for Mean Opinion Score (
2117 * https://en.wikipedia.org/wiki/Mean_Opinion_Score )
2118 *
2119 * More links:
2120 * - https://confluence.slac.stanford.edu/display/IEPM/MOS
2121 */
2122 target.jitter = (target.jitter / (target.icmp_recv - 1) / 1000);
2123
2124 /*
2125 * Take the average round trip latency (in milliseconds), add
2126 * round trip jitter, but double the impact to latency
2127 * then add 10 for protocol latencies (in milliseconds).
2128 */
2129 EffectiveLatency = (rta / 1000) + target.jitter * 2 + 10;
2130
2131 double R;
2132 if (EffectiveLatency < 160) {
2133 R = 93.2 - (EffectiveLatency / 40);
2134 } else {
2135 R = 93.2 - ((EffectiveLatency - 120) / 10);
2136 }
2137
2138 // Now, let us deduct 2.5 R values per percentage of packet loss (i.e. a
2139 // loss of 5% will be entered as 5).
2140 R = R - (packet_loss * 2.5);
2141
2142 if (R < 0) {
2143 R = 0;
2144 }
2145
2146 score = R;
2147 mos = 1 + ((0.035) * R) + ((.000007) * R * (R - 60) * (100 - R));
2148 } else {
2149 target.jitter = 0;
2150 target.jitter_min = 0;
2151 target.jitter_max = 0;
2152 mos = 0;
2153 }
2154
2155 /* Check which mode is on and do the warn / Crit stuff */
2156 if (modes.rta_mode) {
2157 mp_subcheck sc_rta = mp_subcheck_init();
2158 sc_rta = mp_set_subcheck_default_state(sc_rta, STATE_OK);
2159 xasprintf(&sc_rta.output, "rta %0.3fms", rta / 1000);
2160
2161 if (rta >= crit.rta) {
2162 sc_rta = mp_set_subcheck_state(sc_rta, STATE_CRITICAL);
2163 xasprintf(&sc_rta.output, "%s > %0.3fms", sc_rta.output, crit.rta / 1000);
2164 } else if (rta >= warn.rta) {
2165 sc_rta = mp_set_subcheck_state(sc_rta, STATE_WARNING);
2166 xasprintf(&sc_rta.output, "%s > %0.3fms", sc_rta.output, warn.rta / 1000);
2167 }
2168
2169 if (packet_loss < 100) {
2170 mp_perfdata pd_rta = perfdata_init();
2171 xasprintf(&pd_rta.label, "%srta", target.name);
2172 pd_rta.uom = strdup("ms");
2173 pd_rta.value = mp_create_pd_value(rta / 1000);
2174 pd_rta.min = mp_create_pd_value(0);
2175
2176 pd_rta.warn = mp_range_set_end(pd_rta.warn, mp_create_pd_value(warn.rta));
2177 pd_rta.crit = mp_range_set_end(pd_rta.crit, mp_create_pd_value(crit.rta));
2178 mp_add_perfdata_to_subcheck(&sc_rta, pd_rta);
2179
2180 mp_perfdata pd_rt_min = perfdata_init();
2181 xasprintf(&pd_rt_min.label, "%srtmin", target.name);
2182 pd_rt_min.value = mp_create_pd_value(target.rtmin / 1000);
2183 pd_rt_min.uom = strdup("ms");
2184 mp_add_perfdata_to_subcheck(&sc_rta, pd_rt_min);
2185
2186 mp_perfdata pd_rt_max = perfdata_init();
2187 xasprintf(&pd_rt_max.label, "%srtmax", target.name);
2188 pd_rt_max.value = mp_create_pd_value(target.rtmax / 1000);
2189 pd_rt_max.uom = strdup("ms");
2190 mp_add_perfdata_to_subcheck(&sc_rta, pd_rt_max);
2191 }
2192
2193 mp_add_subcheck_to_subcheck(&result, sc_rta);
2194 }
2195
2196 if (modes.pl_mode) {
2197 mp_subcheck sc_pl = mp_subcheck_init();
2198 sc_pl = mp_set_subcheck_default_state(sc_pl, STATE_OK);
2199 xasprintf(&sc_pl.output, "packet loss %.1f%%", packet_loss);
2200
2201 if (packet_loss >= crit.pl) {
2202 sc_pl = mp_set_subcheck_state(sc_pl, STATE_CRITICAL);
2203 xasprintf(&sc_pl.output, "%s > %u%%", sc_pl.output, crit.pl);
2204 } else if (packet_loss >= warn.pl) {
2205 sc_pl = mp_set_subcheck_state(sc_pl, STATE_WARNING);
2206 xasprintf(&sc_pl.output, "%s > %u%%", sc_pl.output, crit.pl);
2207 }
2208
2209 mp_perfdata pd_pl = perfdata_init();
2210 xasprintf(&pd_pl.label, "%spl", target.name);
2211 pd_pl.uom = strdup("%");
2212
2213 pd_pl.warn = mp_range_set_end(pd_pl.warn, mp_create_pd_value(warn.pl));
2214 pd_pl.crit = mp_range_set_end(pd_pl.crit, mp_create_pd_value(crit.pl));
2215 pd_pl.value = mp_create_pd_value(packet_loss);
2216
2217 mp_add_perfdata_to_subcheck(&sc_pl, pd_pl);
2218
2219 mp_add_subcheck_to_subcheck(&result, sc_pl);
2220 }
2221
2222 if (modes.jitter_mode) {
2223 mp_subcheck sc_jitter = mp_subcheck_init();
2224 sc_jitter = mp_set_subcheck_default_state(sc_jitter, STATE_OK);
2225 xasprintf(&sc_jitter.output, "jitter %0.3fms", target.jitter);
2226
2227 if (target.jitter >= crit.jitter) {
2228 sc_jitter = mp_set_subcheck_state(sc_jitter, STATE_CRITICAL);
2229 xasprintf(&sc_jitter.output, "%s > %0.3fms", sc_jitter.output, crit.jitter);
2230 } else if (target.jitter >= warn.jitter) {
2231 sc_jitter = mp_set_subcheck_state(sc_jitter, STATE_WARNING);
2232 xasprintf(&sc_jitter.output, "%s > %0.3fms", sc_jitter.output, warn.jitter);
2233 }
2234
2235 if (packet_loss < 100) {
2236 mp_perfdata pd_jitter = perfdata_init();
2237 pd_jitter.uom = strdup("ms");
2238 xasprintf(&pd_jitter.label, "%sjitter_avg", target.name);
2239 pd_jitter.value = mp_create_pd_value(target.jitter);
2240 pd_jitter.warn = mp_range_set_end(pd_jitter.warn, mp_create_pd_value(warn.jitter));
2241 pd_jitter.crit = mp_range_set_end(pd_jitter.crit, mp_create_pd_value(crit.jitter));
2242 mp_add_perfdata_to_subcheck(&sc_jitter, pd_jitter);
2243
2244 mp_perfdata pd_jitter_min = perfdata_init();
2245 pd_jitter_min.uom = strdup("ms");
2246 xasprintf(&pd_jitter_min.label, "%sjitter_min", target.name);
2247 pd_jitter_min.value = mp_create_pd_value(target.jitter_min);
2248 mp_add_perfdata_to_subcheck(&sc_jitter, pd_jitter_min);
2249
2250 mp_perfdata pd_jitter_max = perfdata_init();
2251 pd_jitter_max.uom = strdup("ms");
2252 xasprintf(&pd_jitter_max.label, "%sjitter_max", target.name);
2253 pd_jitter_max.value = mp_create_pd_value(target.jitter_max);
2254 mp_add_perfdata_to_subcheck(&sc_jitter, pd_jitter_max);
2255 }
2256 mp_add_subcheck_to_subcheck(&result, sc_jitter);
2257 }
2258
2259 if (modes.mos_mode) {
2260 mp_subcheck sc_mos = mp_subcheck_init();
2261 sc_mos = mp_set_subcheck_default_state(sc_mos, STATE_OK);
2262 xasprintf(&sc_mos.output, "MOS %0.1f", mos);
2263
2264 if (mos <= crit.mos) {
2265 sc_mos = mp_set_subcheck_state(sc_mos, STATE_CRITICAL);
2266 xasprintf(&sc_mos.output, "%s < %0.1f", sc_mos.output, crit.mos);
2267 } else if (mos <= warn.mos) {
2268 sc_mos = mp_set_subcheck_state(sc_mos, STATE_WARNING);
2269 xasprintf(&sc_mos.output, "%s < %0.1f", sc_mos.output, warn.mos);
2270 }
2271
2272 if (packet_loss < 100) {
2273 mp_perfdata pd_mos = perfdata_init();
2274 xasprintf(&pd_mos.label, "%smos", target.name);
2275 pd_mos.value = mp_create_pd_value(mos);
2276 pd_mos.warn = mp_range_set_end(pd_mos.warn, mp_create_pd_value(warn.mos));
2277 pd_mos.crit = mp_range_set_end(pd_mos.crit, mp_create_pd_value(crit.mos));
2278 pd_mos.min = mp_create_pd_value(0);
2279 pd_mos.max = mp_create_pd_value(5);
2280 mp_add_perfdata_to_subcheck(&sc_mos, pd_mos);
2281 }
2282 mp_add_subcheck_to_subcheck(&result, sc_mos);
2283 }
2284
2285 if (modes.score_mode) {
2286 mp_subcheck sc_score = mp_subcheck_init();
2287 sc_score = mp_set_subcheck_default_state(sc_score, STATE_OK);
2288 xasprintf(&sc_score.output, "Score %u", score);
2289
2290 if (score <= crit.score) {
2291 sc_score = mp_set_subcheck_state(sc_score, STATE_CRITICAL);
2292 xasprintf(&sc_score.output, "%s < %u", sc_score.output, crit.score);
2293 } else if (score <= warn.score) {
2294 sc_score = mp_set_subcheck_state(sc_score, STATE_WARNING);
2295 xasprintf(&sc_score.output, "%s < %u", sc_score.output, warn.score);
2296 }
2297
2298 if (packet_loss < 100) {
2299 mp_perfdata pd_score = perfdata_init();
2300 xasprintf(&pd_score.label, "%sscore", target.name);
2301 pd_score.value = mp_create_pd_value(score);
2302 pd_score.warn = mp_range_set_end(pd_score.warn, mp_create_pd_value(warn.score));
2303 pd_score.crit = mp_range_set_end(pd_score.crit, mp_create_pd_value(crit.score));
2304 pd_score.min = mp_create_pd_value(0);
2305 pd_score.max = mp_create_pd_value(100);
2306 mp_add_perfdata_to_subcheck(&sc_score, pd_score);
2307 }
2308
2309 mp_add_subcheck_to_subcheck(&result, sc_score);
2310 }
2311
2312 if (modes.order_mode) {
2313 mp_subcheck sc_order = mp_subcheck_init();
2314 sc_order = mp_set_subcheck_default_state(sc_order, STATE_OK);
2315
2316 if (target.found_out_of_order_packets) {
2317 mp_set_subcheck_state(sc_order, STATE_CRITICAL);
2318 xasprintf(&sc_order.output, "Packets out of order");
2319 } else {
2320 xasprintf(&sc_order.output, "Packets in order");
2321 }
2322
2323 mp_add_subcheck_to_subcheck(&result, sc_order);
2324 }
2325
2326 return result;
2327}
diff --git a/plugins-root/check_icmp.d/check_icmp_helpers.c b/plugins-root/check_icmp.d/check_icmp_helpers.c
index 58e13581..a2b54c6a 100644
--- a/plugins-root/check_icmp.d/check_icmp_helpers.c
+++ b/plugins-root/check_icmp.d/check_icmp_helpers.c
@@ -10,12 +10,15 @@ unsigned int timeout = DEFAULT_TIMEOUT;
10 10
11check_icmp_config check_icmp_config_init() { 11check_icmp_config check_icmp_config_init() {
12 check_icmp_config tmp = { 12 check_icmp_config tmp = {
13 .order_mode = false, 13 .modes =
14 .mos_mode = false, 14 {
15 .rta_mode = false, 15 .order_mode = false,
16 .pl_mode = false, 16 .mos_mode = false,
17 .jitter_mode = false, 17 .rta_mode = false,
18 .score_mode = false, 18 .pl_mode = false,
19 .jitter_mode = false,
20 .score_mode = false,
21 },
19 22
20 .min_hosts_alive = -1, 23 .min_hosts_alive = -1,
21 .crit = {.pl = DEFAULT_CRIT_PL, 24 .crit = {.pl = DEFAULT_CRIT_PL,
@@ -56,12 +59,7 @@ ping_target ping_target_init() {
56 59
57 .jitter_min = INFINITY, 60 .jitter_min = INFINITY,
58 61
59 .rta_status = STATE_OK, 62 .found_out_of_order_packets = false,
60 .jitter_status = STATE_OK,
61 .mos_status = STATE_OK,
62 .score_status = STATE_OK,
63 .pl_status = STATE_OK,
64 .order_status = STATE_OK,
65 }; 63 };
66 64
67 return tmp; 65 return tmp;
diff --git a/plugins-root/check_icmp.d/check_icmp_helpers.h b/plugins-root/check_icmp.d/check_icmp_helpers.h
index 3e798f72..68c39b4a 100644
--- a/plugins-root/check_icmp.d/check_icmp_helpers.h
+++ b/plugins-root/check_icmp.d/check_icmp_helpers.h
@@ -20,7 +20,6 @@ typedef struct rta_host {
20 unsigned char icmp_type, icmp_code; /* type and code from errors */ 20 unsigned char icmp_type, icmp_code; /* type and code from errors */
21 unsigned short flags; /* control/status flags */ 21 unsigned short flags; /* control/status flags */
22 22
23 double rta; /* measured RTA */
24 double rtmax; /* max rtt */ 23 double rtmax; /* max rtt */
25 double rtmin; /* min rtt */ 24 double rtmin; /* min rtt */
26 25
@@ -28,20 +27,10 @@ typedef struct rta_host {
28 double jitter_max; /* jitter rtt maximum */ 27 double jitter_max; /* jitter rtt maximum */
29 double jitter_min; /* jitter rtt minimum */ 28 double jitter_min; /* jitter rtt minimum */
30 29
31 double EffectiveLatency;
32 double mos; /* Mean opinion score */
33 double score; /* score */
34
35 time_t last_tdiff; 30 time_t last_tdiff;
36 unsigned int last_icmp_seq; /* Last ICMP_SEQ to check out of order pkts */ 31 unsigned int last_icmp_seq; /* Last ICMP_SEQ to check out of order pkts */
37 unsigned char pl; /* measured packet loss */
38 32
39 mp_state_enum rta_status; // check result for RTA checks 33 bool found_out_of_order_packets;
40 mp_state_enum jitter_status; // check result for Jitter checks
41 mp_state_enum mos_status; // check result for MOS checks
42 mp_state_enum score_status; // check result for score checks
43 mp_state_enum pl_status; // check result for packet loss checks
44 mp_state_enum order_status; // check result for packet order checks
45 34
46 struct rta_host *next; 35 struct rta_host *next;
47} ping_target; 36} ping_target;
diff --git a/plugins-root/check_icmp.d/config.h b/plugins-root/check_icmp.d/config.h
index 3599c0f0..aa33c991 100644
--- a/plugins-root/check_icmp.d/config.h
+++ b/plugins-root/check_icmp.d/config.h
@@ -48,6 +48,10 @@ typedef struct {
48 bool pl_mode; 48 bool pl_mode;
49 bool jitter_mode; 49 bool jitter_mode;
50 bool score_mode; 50 bool score_mode;
51} check_icmp_mode_switches;
52
53typedef struct {
54 check_icmp_mode_switches modes;
51 55
52 int min_hosts_alive; 56 int min_hosts_alive;
53 check_icmp_threshold crit; 57 check_icmp_threshold crit;