summaryrefslogtreecommitdiffstats
path: root/plugins-root
diff options
context:
space:
mode:
Diffstat (limited to 'plugins-root')
-rw-r--r--plugins-root/check_icmp.c294
-rw-r--r--plugins-root/check_icmp.d/check_icmp_helpers.c4
-rw-r--r--plugins-root/check_icmp.d/config.h12
3 files changed, 157 insertions, 153 deletions
diff --git a/plugins-root/check_icmp.c b/plugins-root/check_icmp.c
index 55405b8a..d46d2ccc 100644
--- a/plugins-root/check_icmp.c
+++ b/plugins-root/check_icmp.c
@@ -151,10 +151,9 @@ static void set_source_ip(char *arg, int icmp_sock, sa_family_t addr_family);
151 151
152/* Receiving data */ 152/* Receiving data */
153static int wait_for_reply(check_icmp_socket_set sockset, time_t time_interval, 153static int wait_for_reply(check_icmp_socket_set sockset, time_t time_interval,
154 unsigned short icmp_pkt_size, time_t *pkt_interval, 154 unsigned short icmp_pkt_size, time_t *target_interval, uint16_t sender_id,
155 time_t *target_interval, uint16_t sender_id, ping_target **table, 155 ping_target **table, unsigned short packets,
156 unsigned short packets, unsigned short number_of_targets, 156 unsigned short number_of_targets, check_icmp_state *program_state);
157 check_icmp_state *program_state);
158 157
159typedef struct { 158typedef struct {
160 sa_family_t recv_proto; 159 sa_family_t recv_proto;
@@ -164,9 +163,9 @@ static recvfrom_wto_wrapper recvfrom_wto(check_icmp_socket_set sockset, void *bu
164 struct sockaddr *saddr, time_t *timeout, 163 struct sockaddr *saddr, time_t *timeout,
165 struct timeval *received_timestamp); 164 struct timeval *received_timestamp);
166static int handle_random_icmp(unsigned char *packet, struct sockaddr_storage *addr, 165static int handle_random_icmp(unsigned char *packet, struct sockaddr_storage *addr,
167 time_t *pkt_interval, time_t *target_interval, uint16_t sender_id, 166 time_t *target_interval, uint16_t sender_id, ping_target **table,
168 ping_target **table, unsigned short packets, 167 unsigned short packets, unsigned short number_of_targets,
169 unsigned short number_of_targets, check_icmp_state *program_state); 168 check_icmp_state *program_state);
170 169
171/* Sending data */ 170/* Sending data */
172static int send_icmp_ping(check_icmp_socket_set sockset, ping_target *host, 171static int send_icmp_ping(check_icmp_socket_set sockset, ping_target *host,
@@ -198,11 +197,11 @@ static parse_threshold2_helper_wrapper parse_threshold2_helper(char *threshold_s
198 threshold_mode mode); 197 threshold_mode mode);
199 198
200/* main test function */ 199/* main test function */
201static void run_checks(unsigned short icmp_pkt_size, time_t *pkt_interval, time_t *target_interval, 200static void run_checks(unsigned short icmp_pkt_size, time_t *target_interval, uint16_t sender_id,
202 uint16_t sender_id, check_icmp_execution_mode mode, 201 check_icmp_execution_mode mode, time_t max_completion_time,
203 time_t max_completion_time, struct timeval prog_start, ping_target **table, 202 struct timeval prog_start, ping_target **table, unsigned short packets,
204 unsigned short packets, check_icmp_socket_set sockset, 203 check_icmp_socket_set sockset, unsigned short number_of_targets,
205 unsigned short number_of_targets, check_icmp_state *program_state); 204 check_icmp_state *program_state);
206mp_subcheck evaluate_target(ping_target target, check_icmp_mode_switches modes, 205mp_subcheck evaluate_target(ping_target target, check_icmp_mode_switches modes,
207 check_icmp_threshold warn, check_icmp_threshold crit); 206 check_icmp_threshold warn, check_icmp_threshold crit);
208 207
@@ -297,14 +296,12 @@ check_icmp_config_wrapper process_arguments(int argc, char **argv) {
297 result.config.mode = MODE_ICMP; 296 result.config.mode = MODE_ICMP;
298 } else if (!strcmp(progname, "check_host")) { 297 } else if (!strcmp(progname, "check_host")) {
299 result.config.mode = MODE_HOSTCHECK; 298 result.config.mode = MODE_HOSTCHECK;
300 result.config.pkt_interval = 1000000;
301 result.config.number_of_packets = 5; 299 result.config.number_of_packets = 5;
302 result.config.crit.rta = result.config.warn.rta = 1000000; 300 result.config.crit.rta = result.config.warn.rta = 1000000;
303 result.config.crit.pl = result.config.warn.pl = 100; 301 result.config.crit.pl = result.config.warn.pl = 100;
304 } else if (!strcmp(progname, "check_rta_multi")) { 302 } else if (!strcmp(progname, "check_rta_multi")) {
305 result.config.mode = MODE_ALL; 303 result.config.mode = MODE_ALL;
306 result.config.target_interval = 0; 304 result.config.target_interval = 0;
307 result.config.pkt_interval = 50000;
308 result.config.number_of_packets = 5; 305 result.config.number_of_packets = 5;
309 } 306 }
310 /* support "--help" and "--version" */ 307 /* support "--help" and "--version" */
@@ -319,13 +316,44 @@ check_icmp_config_wrapper process_arguments(int argc, char **argv) {
319 316
320 sa_family_t enforced_ai_family = AF_UNSPEC; 317 sa_family_t enforced_ai_family = AF_UNSPEC;
321 318
319 enum {
320 output_format_index = CHAR_MAX + 1,
321 };
322
323 struct option longopts[] = {
324 {"version", no_argument, 0, 'V'},
325 {"help", no_argument, 0, 'h'},
326 {"verbose", no_argument, 0, 'v'},
327 {"Host", required_argument, 0, 'H'},
328 {"ipv4-only", no_argument, 0, '4'},
329 {"ipv6-only", no_argument, 0, '6'},
330 {"warning", required_argument, 0, 'w'},
331 {"critical", required_argument, 0, 'c'},
332 {"rta-mode-thresholds", required_argument, 0, 'R'},
333 {"packet-loss-mode-thresholds", required_argument, 0, 'P'},
334 {"jitter-mode-thresholds", required_argument, 0, 'J'},
335 {"mos-mode-thresholds", required_argument, 0, 'M'},
336 {"score-mode-thresholds", required_argument, 0, 'S'},
337 {"out-of-order-packets", no_argument, 0, 'O'},
338 {"number-of-packets", required_argument, 0, 'n'},
339 {"number-of-packets", required_argument, 0, 'p'},
340 {"packet-interval", required_argument, 0, 'i'},
341 {"target-interval", required_argument, 0, 'I'},
342 {"minimal-host-alive", required_argument, 0, 'm'},
343 {"outgoing-ttl", required_argument, 0, 'l'},
344 {"size", required_argument, 0, 'b'},
345 {"output-format", required_argument, 0, output_format_index},
346 {},
347 };
348
322 // Parse protocol arguments first 349 // Parse protocol arguments first
323 // and count hosts here 350 // and count hosts here
324 char *opts_str = "vhVw:c:n:p:t:H:s:i:b:I:l:m:P:R:J:S:M:O64"; 351 char *opts_str = "vhVw:c:n:p:t:H:s:i:b:I:l:m:P:R:J:S:M:O64";
325 for (int i = 1; i < argc; i++) { 352 for (int i = 1; i < argc; i++) {
326 long int arg; 353 long int arg;
327 while ((arg = getopt(argc, argv, opts_str)) != EOF) { 354 while ((arg = getopt_long(argc, argv, opts_str, longopts, NULL)) != EOF) {
328 switch (arg) { 355 switch (arg) {
356
329 case '4': 357 case '4':
330 if (enforced_ai_family != AF_UNSPEC) { 358 if (enforced_ai_family != AF_UNSPEC) {
331 crash("Multiple protocol versions not supported"); 359 crash("Multiple protocol versions not supported");
@@ -342,6 +370,11 @@ check_icmp_config_wrapper process_arguments(int argc, char **argv) {
342 result.config.number_of_hosts++; 370 result.config.number_of_hosts++;
343 break; 371 break;
344 } 372 }
373 case 'h': /* help */
374 // Trigger help here to avoid adding hosts before that (and doing DNS queries)
375 print_help();
376 exit(STATE_UNKNOWN);
377 break;
345 case 'v': 378 case 'v':
346 debug++; 379 debug++;
347 break; 380 break;
@@ -374,14 +407,13 @@ check_icmp_config_wrapper process_arguments(int argc, char **argv) {
374 /* parse the arguments */ 407 /* parse the arguments */
375 for (int i = 1; i < argc; i++) { 408 for (int i = 1; i < argc; i++) {
376 long int arg; 409 long int arg;
377 while ((arg = getopt(argc, argv, opts_str)) != EOF) { 410 while ((arg = getopt_long(argc, argv, opts_str, longopts, NULL)) != EOF) {
378 switch (arg) { 411 switch (arg) {
379 case 'b': { 412 case 'b': {
380 long size = strtol(optarg, NULL, 0); 413 long size = strtol(optarg, NULL, 0);
381 if ((unsigned long)size >= (sizeof(struct icmp) + sizeof(struct icmp_ping_data)) && 414 if ((unsigned long)size >= (sizeof(struct icmp) + sizeof(struct icmp_ping_data)) &&
382 size < MAX_PING_DATA) { 415 size < MAX_PING_DATA) {
383 result.config.icmp_data_size = (unsigned short)size; 416 result.config.icmp_data_size = (unsigned short)size;
384 result.config.icmp_pkt_size = (unsigned short)(size + ICMP_MINLEN);
385 } else { 417 } else {
386 usage_va("ICMP data length must be between: %lu and %lu", 418 usage_va("ICMP data length must be between: %lu and %lu",
387 sizeof(struct icmp) + sizeof(struct icmp_ping_data), 419 sizeof(struct icmp) + sizeof(struct icmp_ping_data),
@@ -389,13 +421,7 @@ check_icmp_config_wrapper process_arguments(int argc, char **argv) {
389 } 421 }
390 } break; 422 } break;
391 case 'i': { 423 case 'i': {
392 get_timevar_wrapper parsed_time = get_timevar(optarg); 424 // packet_interval was unused and is now removed
393
394 if (parsed_time.error_code == OK) {
395 result.config.pkt_interval = parsed_time.time_range;
396 } else {
397 crash("failed to parse packet interval");
398 }
399 } break; 425 } break;
400 case 'I': { 426 case 'I': {
401 get_timevar_wrapper parsed_time = get_timevar(optarg); 427 get_timevar_wrapper parsed_time = get_timevar(optarg);
@@ -455,7 +481,7 @@ check_icmp_config_wrapper process_arguments(int argc, char **argv) {
455 result.config.need_v6 = true; 481 result.config.need_v6 = true;
456 } 482 }
457 } else { 483 } else {
458 // TODO adding host failed, crash here 484 crash("Failed to add host, unable to parse it correctly");
459 } 485 }
460 } break; 486 } break;
461 case 'l': 487 case 'l':
@@ -470,10 +496,6 @@ check_icmp_config_wrapper process_arguments(int argc, char **argv) {
470 case 'V': /* version */ 496 case 'V': /* version */
471 print_revision(progname, NP_VERSION); 497 print_revision(progname, NP_VERSION);
472 exit(STATE_UNKNOWN); 498 exit(STATE_UNKNOWN);
473 case 'h': /* help */
474 print_help();
475 exit(STATE_UNKNOWN);
476 break;
477 case 'R': /* RTA mode */ { 499 case 'R': /* RTA mode */ {
478 get_threshold2_wrapper rta_th = get_threshold2( 500 get_threshold2_wrapper rta_th = get_threshold2(
479 optarg, strlen(optarg), result.config.warn, result.config.crit, const_rta_mode); 501 optarg, strlen(optarg), result.config.warn, result.config.crit, const_rta_mode);
@@ -536,6 +558,18 @@ check_icmp_config_wrapper process_arguments(int argc, char **argv) {
536 case 'O': /* out of order mode */ 558 case 'O': /* out of order mode */
537 result.config.modes.order_mode = true; 559 result.config.modes.order_mode = true;
538 break; 560 break;
561 case output_format_index: {
562 parsed_output_format parser = mp_parse_output_format(optarg);
563 if (!parser.parsing_success) {
564 // TODO List all available formats here, maybe add anothoer usage function
565 printf("Invalid output format: %s\n", optarg);
566 exit(STATE_UNKNOWN);
567 }
568
569 result.config.output_format_is_set = true;
570 result.config.output_format = parser.output_format;
571 break;
572 }
539 } 573 }
540 } 574 }
541 } 575 }
@@ -697,8 +731,8 @@ static const char *get_icmp_error_msg(unsigned char icmp_type, unsigned char icm
697} 731}
698 732
699static int handle_random_icmp(unsigned char *packet, struct sockaddr_storage *addr, 733static int handle_random_icmp(unsigned char *packet, struct sockaddr_storage *addr,
700 time_t *pkt_interval, time_t *target_interval, 734 time_t *target_interval, const uint16_t sender_id,
701 const uint16_t sender_id, ping_target **table, unsigned short packets, 735 ping_target **table, unsigned short packets,
702 const unsigned short number_of_targets, 736 const unsigned short number_of_targets,
703 check_icmp_state *program_state) { 737 check_icmp_state *program_state) {
704 struct icmp icmp_packet; 738 struct icmp icmp_packet;
@@ -758,7 +792,6 @@ static int handle_random_icmp(unsigned char *packet, struct sockaddr_storage *ad
758 /* source quench means we're sending too fast, so increase the 792 /* source quench means we're sending too fast, so increase the
759 * interval and mark this packet lost */ 793 * interval and mark this packet lost */
760 if (icmp_packet.icmp_type == ICMP_SOURCEQUENCH) { 794 if (icmp_packet.icmp_type == ICMP_SOURCEQUENCH) {
761 *pkt_interval = (unsigned int)((double)*pkt_interval * PACKET_BACKOFF_FACTOR);
762 *target_interval = (unsigned int)((double)*target_interval * TARGET_BACKOFF_FACTOR); 795 *target_interval = (unsigned int)((double)*target_interval * TARGET_BACKOFF_FACTOR);
763 } else { 796 } else {
764 program_state->targets_down++; 797 program_state->targets_down++;
@@ -803,18 +836,9 @@ int main(int argc, char **argv) {
803 836
804 const check_icmp_config config = tmp_config.config; 837 const check_icmp_config config = tmp_config.config;
805 838
806 // int icmp_proto = IPPROTO_ICMP; 839 if (config.output_format_is_set) {
807 // add_target might change address_family 840 mp_set_format(config.output_format);
808 // switch (address_family) { 841 }
809 // case AF_INET:
810 // icmp_proto = IPPROTO_ICMP;
811 // break;
812 // case AF_INET6:
813 // icmp_proto = IPPROTO_ICMPV6;
814 // break;
815 // default:
816 // crash("Address family not supported");
817 // }
818 842
819 check_icmp_socket_set sockset = { 843 check_icmp_socket_set sockset = {
820 .socket4 = -1, 844 .socket4 = -1,
@@ -899,18 +923,17 @@ int main(int argc, char **argv) {
899 gettimeofday(&prog_start, NULL); 923 gettimeofday(&prog_start, NULL);
900 924
901 time_t max_completion_time = 925 time_t max_completion_time =
902 ((config.pkt_interval * config.number_of_targets * config.number_of_packets) + 926 (config.target_interval * config.number_of_targets) +
903 (config.target_interval * config.number_of_targets)) +
904 (config.crit.rta * config.number_of_targets * config.number_of_packets) + config.crit.rta; 927 (config.crit.rta * config.number_of_targets * config.number_of_packets) + config.crit.rta;
905 928
906 if (debug) { 929 if (debug) {
907 printf("packets: %u, targets: %u\n" 930 printf("packets: %u, targets: %u\n"
908 "target_interval: %0.3f, pkt_interval %0.3f\n" 931 "target_interval: %0.3f\n"
909 "crit.rta: %0.3f\n" 932 "crit.rta: %0.3f\n"
910 "max_completion_time: %0.3f\n", 933 "max_completion_time: %0.3f\n",
911 config.number_of_packets, config.number_of_targets, 934 config.number_of_packets, config.number_of_targets,
912 (float)config.target_interval / 1000, (float)config.pkt_interval / 1000, 935 (float)config.target_interval / 1000, (float)config.crit.rta / 1000,
913 (float)config.crit.rta / 1000, (float)max_completion_time / 1000); 936 (float)max_completion_time / 1000);
914 } 937 }
915 938
916 if (debug) { 939 if (debug) {
@@ -923,9 +946,8 @@ int main(int argc, char **argv) {
923 if (debug) { 946 if (debug) {
924 printf("crit = {%ld, %u%%}, warn = {%ld, %u%%}\n", config.crit.rta, config.crit.pl, 947 printf("crit = {%ld, %u%%}, warn = {%ld, %u%%}\n", config.crit.rta, config.crit.pl,
925 config.warn.rta, config.warn.pl); 948 config.warn.rta, config.warn.pl);
926 printf("pkt_interval: %ld target_interval: %ld\n", config.pkt_interval, 949 printf("target_interval: %ld\n", config.target_interval);
927 config.target_interval); 950 printf("icmp_pkt_size: %u timeout: %u\n", config.icmp_data_size + ICMP_MINLEN, timeout);
928 printf("icmp_pkt_size: %u timeout: %u\n", config.icmp_pkt_size, timeout);
929 } 951 }
930 952
931 if (config.min_hosts_alive < -1) { 953 if (config.min_hosts_alive < -1) {
@@ -948,14 +970,13 @@ int main(int argc, char **argv) {
948 target_index++; 970 target_index++;
949 } 971 }
950 972
951 time_t pkt_interval = config.pkt_interval;
952 time_t target_interval = config.target_interval; 973 time_t target_interval = config.target_interval;
953 974
954 check_icmp_state program_state = check_icmp_state_init(); 975 check_icmp_state program_state = check_icmp_state_init();
955 976
956 run_checks(config.icmp_data_size, &pkt_interval, &target_interval, config.sender_id, 977 run_checks(config.icmp_data_size, &target_interval, config.sender_id, config.mode,
957 config.mode, max_completion_time, prog_start, table, config.number_of_packets, 978 max_completion_time, prog_start, table, config.number_of_packets, sockset,
958 sockset, config.number_of_targets, &program_state); 979 config.number_of_targets, &program_state);
959 980
960 errno = 0; 981 errno = 0;
961 982
@@ -974,7 +995,7 @@ int main(int argc, char **argv) {
974 mp_exit(overall); 995 mp_exit(overall);
975} 996}
976 997
977static void run_checks(unsigned short icmp_pkt_size, time_t *pkt_interval, time_t *target_interval, 998static void run_checks(unsigned short icmp_pkt_size, time_t *target_interval,
978 const uint16_t sender_id, const check_icmp_execution_mode mode, 999 const uint16_t sender_id, const check_icmp_execution_mode mode,
979 const time_t max_completion_time, const struct timeval prog_start, 1000 const time_t max_completion_time, const struct timeval prog_start,
980 ping_target **table, const unsigned short packets, 1001 ping_target **table, const unsigned short packets,
@@ -1007,17 +1028,15 @@ static void run_checks(unsigned short icmp_pkt_size, time_t *pkt_interval, time_
1007 if (targets_alive(number_of_targets, program_state->targets_down) || 1028 if (targets_alive(number_of_targets, program_state->targets_down) ||
1008 get_timevaldiff(prog_start, prog_start) < max_completion_time || 1029 get_timevaldiff(prog_start, prog_start) < max_completion_time ||
1009 !(mode == MODE_HOSTCHECK && program_state->targets_down)) { 1030 !(mode == MODE_HOSTCHECK && program_state->targets_down)) {
1010 wait_for_reply(sockset, *target_interval, icmp_pkt_size, pkt_interval, 1031 wait_for_reply(sockset, *target_interval, icmp_pkt_size, target_interval, sender_id,
1011 target_interval, sender_id, table, packets, number_of_targets, 1032 table, packets, number_of_targets, program_state);
1012 program_state);
1013 } 1033 }
1014 } 1034 }
1015 if (targets_alive(number_of_targets, program_state->targets_down) || 1035 if (targets_alive(number_of_targets, program_state->targets_down) ||
1016 get_timevaldiff_to_now(prog_start) < max_completion_time || 1036 get_timevaldiff_to_now(prog_start) < max_completion_time ||
1017 !(mode == MODE_HOSTCHECK && program_state->targets_down)) { 1037 !(mode == MODE_HOSTCHECK && program_state->targets_down)) {
1018 wait_for_reply(sockset, *pkt_interval * number_of_targets, icmp_pkt_size, pkt_interval, 1038 wait_for_reply(sockset, number_of_targets, icmp_pkt_size, target_interval, sender_id,
1019 target_interval, sender_id, table, packets, number_of_targets, 1039 table, packets, number_of_targets, program_state);
1020 program_state);
1021 } 1040 }
1022 } 1041 }
1023 1042
@@ -1047,8 +1066,8 @@ static void run_checks(unsigned short icmp_pkt_size, time_t *pkt_interval, time_
1047 if (targets_alive(number_of_targets, program_state->targets_down) || 1066 if (targets_alive(number_of_targets, program_state->targets_down) ||
1048 get_timevaldiff_to_now(prog_start) < max_completion_time || 1067 get_timevaldiff_to_now(prog_start) < max_completion_time ||
1049 !(mode == MODE_HOSTCHECK && program_state->targets_down)) { 1068 !(mode == MODE_HOSTCHECK && program_state->targets_down)) {
1050 wait_for_reply(sockset, final_wait, icmp_pkt_size, pkt_interval, target_interval, 1069 wait_for_reply(sockset, final_wait, icmp_pkt_size, target_interval, sender_id, table,
1051 sender_id, table, packets, number_of_targets, program_state); 1070 packets, number_of_targets, program_state);
1052 } 1071 }
1053 } 1072 }
1054} 1073}
@@ -1064,10 +1083,9 @@ static void run_checks(unsigned short icmp_pkt_size, time_t *pkt_interval, time_
1064 * icmp echo reply : the rest 1083 * icmp echo reply : the rest
1065 */ 1084 */
1066static int wait_for_reply(check_icmp_socket_set sockset, const time_t time_interval, 1085static int wait_for_reply(check_icmp_socket_set sockset, const time_t time_interval,
1067 unsigned short icmp_pkt_size, time_t *pkt_interval, 1086 unsigned short icmp_pkt_size, time_t *target_interval, uint16_t sender_id,
1068 time_t *target_interval, uint16_t sender_id, ping_target **table, 1087 ping_target **table, const unsigned short packets,
1069 const unsigned short packets, const unsigned short number_of_targets, 1088 const unsigned short number_of_targets, check_icmp_state *program_state) {
1070 check_icmp_state *program_state) {
1071 union icmp_packet packet; 1089 union icmp_packet packet;
1072 if (!(packet.buf = malloc(icmp_pkt_size))) { 1090 if (!(packet.buf = malloc(icmp_pkt_size))) {
1073 crash("send_icmp_ping(): failed to malloc %d bytes for send buffer", icmp_pkt_size); 1091 crash("send_icmp_ping(): failed to malloc %d bytes for send buffer", icmp_pkt_size);
@@ -1153,8 +1171,8 @@ static int wait_for_reply(check_icmp_socket_set sockset, const time_t time_inter
1153 printf("not a proper ICMP_ECHOREPLY\n"); 1171 printf("not a proper ICMP_ECHOREPLY\n");
1154 } 1172 }
1155 1173
1156 handle_random_icmp(buf + hlen, &resp_addr, pkt_interval, target_interval, sender_id, 1174 handle_random_icmp(buf + hlen, &resp_addr, target_interval, sender_id, table, packets,
1157 table, packets, number_of_targets, program_state); 1175 number_of_targets, program_state);
1158 1176
1159 continue; 1177 continue;
1160 } 1178 }
@@ -1511,14 +1529,6 @@ static void finish(int sig, check_icmp_mode_switches modes, int min_hosts_alive,
1511 mp_add_subcheck_to_check(overall, host_check.sc_host); 1529 mp_add_subcheck_to_check(overall, host_check.sc_host);
1512 } 1530 }
1513 1531
1514 /* this is inevitable */
1515 // if (targets_alive(number_of_targets, program_state->targets_down) == 0) {
1516 // mp_subcheck sc_no_target_alive = mp_subcheck_init();
1517 // sc_no_target_alive = mp_set_subcheck_state(sc_no_target_alive, STATE_CRITICAL);
1518 // sc_no_target_alive.output = strdup("No target is alive!");
1519 // mp_add_subcheck_to_check(overall, sc_no_target_alive);
1520 // }
1521
1522 if (min_hosts_alive > -1) { 1532 if (min_hosts_alive > -1) {
1523 mp_subcheck sc_min_targets_alive = mp_subcheck_init(); 1533 mp_subcheck sc_min_targets_alive = mp_subcheck_init();
1524 sc_min_targets_alive = mp_set_subcheck_default_state(sc_min_targets_alive, STATE_OK); 1534 sc_min_targets_alive = mp_set_subcheck_default_state(sc_min_targets_alive, STATE_OK);
@@ -2045,77 +2055,77 @@ unsigned short icmp_checksum(uint16_t *packet, size_t packet_size) {
2045} 2055}
2046 2056
2047void print_help(void) { 2057void print_help(void) {
2048 /*print_revision (progname);*/ /* FIXME: Why? */ 2058 // print_revision (progname); /* FIXME: Why? */
2049 printf("Copyright (c) 2005 Andreas Ericsson <ae@op5.se>\n"); 2059 printf("Copyright (c) 2005 Andreas Ericsson <ae@op5.se>\n");
2050 2060
2051 printf(COPYRIGHT, copyright, email); 2061 printf(COPYRIGHT, copyright, email);
2052 2062
2053 printf("\n\n");
2054
2055 print_usage(); 2063 print_usage();
2056 2064
2057 printf(UT_HELP_VRSN); 2065 printf(UT_HELP_VRSN);
2058 printf(UT_EXTRA_OPTS); 2066 printf(UT_EXTRA_OPTS);
2059 2067
2060 printf(" %s\n", "-H"); 2068 printf(" -H, --Host=HOST\n");
2061 printf(" %s\n", _("specify a target")); 2069 printf(" %s\n",
2062 printf(" %s\n", "[-4|-6]"); 2070 _("specify a target, might be one of: resolveable name | IPv6 address | IPv4 address\n"
2063 printf(" %s\n", _("Use IPv4 (default) or IPv6 to communicate with the targets")); 2071 " (required, can be given multiple times)"));
2064 printf(" %s\n", "-w"); 2072 printf(" %s\n", "[-4|-6], [--ipv4-only|--ipv6-only]");
2065 printf(" %s", _("warning threshold (currently ")); 2073 printf(" %s\n", _("Use IPv4 or IPv6 only to communicate with the targets"));
2074 printf(" %s\n", "-w, --warning=WARN_VALUE");
2075 printf(" %s", _("warning threshold (default "));
2066 printf("%0.3fms,%u%%)\n", (float)DEFAULT_WARN_RTA / 1000, DEFAULT_WARN_PL); 2076 printf("%0.3fms,%u%%)\n", (float)DEFAULT_WARN_RTA / 1000, DEFAULT_WARN_PL);
2067 printf(" %s\n", "-c"); 2077 printf(" %s\n", "-c, --critical=CRIT_VALUE");
2068 printf(" %s", _("critical threshold (currently ")); 2078 printf(" %s", _("critical threshold (default "));
2069 printf("%0.3fms,%u%%)\n", (float)DEFAULT_CRIT_RTA / 1000, DEFAULT_CRIT_PL); 2079 printf("%0.3fms,%u%%)\n", (float)DEFAULT_CRIT_RTA / 1000, DEFAULT_CRIT_PL);
2070 2080
2071 printf(" %s\n", "-R"); 2081 printf(" %s\n", "-R, --rta-mode-thresholds=RTA_THRESHOLDS");
2072 printf(" %s\n", 2082 printf(" %s\n",
2073 _("RTA, round trip average, mode warning,critical, ex. 100ms,200ms unit in ms")); 2083 _("RTA (round trip average) mode warning,critical, ex. 100ms,200ms unit in ms"));
2074 printf(" %s\n", "-P"); 2084 printf(" %s\n", "-P, --packet-loss-mode-thresholds=PACKET_LOSS_THRESHOLD");
2075 printf(" %s\n", _("packet loss mode, ex. 40%,50% , unit in %")); 2085 printf(" %s\n", _("packet loss mode, ex. 40%,50% , unit in %"));
2076 printf(" %s\n", "-J"); 2086 printf(" %s\n", "-J, --jitter-mode-thresholds=JITTER_MODE_THRESHOLD");
2077 printf(" %s\n", _("jitter mode warning,critical, ex. 40.000ms,50.000ms , unit in ms ")); 2087 printf(" %s\n", _("jitter mode warning,critical, ex. 40.000ms,50.000ms , unit in ms "));
2078 printf(" %s\n", "-M"); 2088 printf(" %s\n", "-M, --mos-mode-thresholds=MOS_MODE_THRESHOLD");
2079 printf(" %s\n", _("MOS mode, between 0 and 4.4 warning,critical, ex. 3.5,3.0")); 2089 printf(" %s\n", _("MOS mode, between 0 and 4.4 warning,critical, ex. 3.5,3.0"));
2080 printf(" %s\n", "-S"); 2090 printf(" %s\n", "-S, --score-mode-thresholds=SCORE_MODE_THRESHOLD");
2081 printf(" %s\n", _("score mode, max value 100 warning,critical, ex. 80,70 ")); 2091 printf(" %s\n", _("score mode, max value 100 warning,critical, ex. 80,70 "));
2082 printf(" %s\n", "-O"); 2092 printf(" %s\n", "-O, --out-of-order-packets");
2083 printf(" %s\n", _("detect out of order ICMP packts ")); 2093 printf(
2084 printf(" %s\n", "-H"); 2094 " %s\n",
2085 printf(" %s\n", _("specify a target")); 2095 _("detect out of order ICMP packets, if such packets are found, the result is CRITICAL"));
2086 printf(" %s\n", "-s"); 2096 printf(" %s\n", "[-n|-p], --number-of-packets=NUMBER_OF_PACKETS");
2087 printf(" %s\n", _("specify a source IP address or device name")); 2097 printf(" %s", _("number of packets to send (default "));
2088 printf(" %s\n", "-n");
2089 printf(" %s", _("number of packets to send (currently "));
2090 printf("%u)\n", DEFAULT_NUMBER_OF_PACKETS);
2091 printf(" %s\n", "-p");
2092 printf(" %s", _("number of packets to send (currently "));
2093 printf("%u)\n", DEFAULT_NUMBER_OF_PACKETS); 2098 printf("%u)\n", DEFAULT_NUMBER_OF_PACKETS);
2099
2094 printf(" %s\n", "-i"); 2100 printf(" %s\n", "-i");
2095 printf(" %s", _("max packet interval (currently ")); 2101 printf(" %s", _("[DEPRECATED] packet interval (default "));
2096 printf("%0.3fms)\n", (float)DEFAULT_PKT_INTERVAL / 1000); 2102 printf("%0.3fms)\n", (float)DEFAULT_PKT_INTERVAL / 1000);
2097 printf(" %s\n", "-I"); 2103 printf(" %s", _("This option was never actually used and is just mentioned here for "
2098 printf(" %s", _("max target interval (currently ")); 2104 "historical purposes\n"));
2099 printf("%0.3fms)\n", (float)DEFAULT_TARGET_INTERVAL / 1000); 2105
2100 printf(" %s\n", "-m"); 2106 printf(" %s\n", "-I, --target-interval=TARGET_INTERVAL");
2101 printf(" %s", _("number of alive hosts required for success")); 2107 printf(" %s%0.3fms)\n The time interval to wait in between one target and the next\n",
2108 _("max target interval (default "), (float)DEFAULT_TARGET_INTERVAL / 1000);
2109 printf(" %s\n", "-m, --minimal-host-alive=MIN_ALIVE");
2110 printf(" %s", _("number of alive hosts required for success. If less than MIN_ALIVE hosts "
2111 "are OK, but MIN_ALIVE hosts are WARNING or OK, WARNING, else CRITICAL"));
2102 printf("\n"); 2112 printf("\n");
2103 printf(" %s\n", "-l"); 2113 printf(" %s\n", "-l, --outgoing-ttl=OUTGOING_TTL");
2104 printf(" %s", _("TTL on outgoing packets (currently ")); 2114 printf(" %s", _("TTL on outgoing packets (default "));
2105 printf("%u)\n", DEFAULT_TTL); 2115 printf("%u)\n", DEFAULT_TTL);
2106 printf(" %s\n", "-t"); 2116 printf(" %s\n", "-b, --size=SIZE");
2107 printf(" %s", _("timeout value (seconds, currently ")); 2117 printf(" %s\n", _("Number of icmp ping data bytes to send"));
2108 printf("%u)\n", DEFAULT_TIMEOUT); 2118 printf(" %s %lu + %d)\n", _("Packet size will be SIZE + icmp header (default"),
2109 printf(" %s\n", "-b");
2110 printf(" %s\n", _("Number of icmp data bytes to send"));
2111 printf(" %s %lu + %d)\n", _("Packet size will be data bytes + icmp header (currently"),
2112 DEFAULT_PING_DATA_SIZE, ICMP_MINLEN); 2119 DEFAULT_PING_DATA_SIZE, ICMP_MINLEN);
2113 printf(" %s\n", "-v"); 2120 printf(" %s\n", "-v, --verbose");
2114 printf(" %s\n", _("verbose")); 2121 printf(" %s\n", _("Verbosity, can be given multiple times (for debugging)"));
2122
2123 printf(UT_OUTPUT_FORMAT);
2124
2115 printf("\n"); 2125 printf("\n");
2116 printf("%s\n", _("Notes:")); 2126 printf("%s\n", _("Notes:"));
2117 printf(" %s\n", _("If none of R,P,J,M,S or O is specified, default behavior is -R -P")); 2127 printf(" %s\n", _("If none of R,P,J,M,S or O is specified, default behavior is -R -P"));
2118 printf(" %s\n", _("The -H switch is optional. Naming a host (or several) to check is not.")); 2128 printf(" %s\n", _("Naming a host (or several) to check is not."));
2119 printf("\n"); 2129 printf("\n");
2120 printf(" %s\n", _("Threshold format for -w and -c is 200.25,60% for 200.25 msec RTA and 60%")); 2130 printf(" %s\n", _("Threshold format for -w and -c is 200.25,60% for 200.25 msec RTA and 60%"));
2121 printf(" %s\n", _("packet loss. The default values should work well for most users.")); 2131 printf(" %s\n", _("packet loss. The default values should work well for most users."));
@@ -2123,23 +2133,13 @@ void print_help(void) {
2123 _("You can specify different RTA factors using the standardized abbreviations")); 2133 _("You can specify different RTA factors using the standardized abbreviations"));
2124 printf(" %s\n", 2134 printf(" %s\n",
2125 _("us (microseconds), ms (milliseconds, default) or just plain s for seconds.")); 2135 _("us (microseconds), ms (milliseconds, default) or just plain s for seconds."));
2126 /* -d not yet implemented */
2127 /* printf ("%s\n", _("Threshold format for -d is warn,crit. 12,14 means WARNING if >= 12
2128 hops")); printf ("%s\n", _("are spent and CRITICAL if >= 14 hops are spent.")); printf
2129 ("%s\n\n", _("NOTE: Some systems decrease TTL when forming ICMP_ECHOREPLY, others do
2130 not."));*/
2131 printf("\n");
2132 printf(" %s\n", _("The -v switch can be specified several times for increased verbosity."));
2133 /* printf ("%s\n", _("Long options are currently unsupported."));
2134 printf ("%s\n", _("Options marked with * require an argument"));
2135 */
2136 2136
2137 printf(UT_SUPPORT); 2137 printf(UT_SUPPORT);
2138} 2138}
2139 2139
2140void print_usage(void) { 2140void print_usage(void) {
2141 printf("%s\n", _("Usage:")); 2141 printf("%s\n", _("Usage:"));
2142 printf(" %s [options] [-H] host1 host2 hostN\n", progname); 2142 printf(" %s [options] [-H host1 [-H host2 [-H hostN]]]\n", progname);
2143} 2143}
2144 2144
2145static add_host_wrapper add_host(char *arg, check_icmp_execution_mode mode, 2145static add_host_wrapper add_host(char *arg, check_icmp_execution_mode mode,
@@ -2276,10 +2276,10 @@ mp_subcheck evaluate_target(ping_target target, check_icmp_mode_switches modes,
2276 2276
2277 if (rta >= crit.rta) { 2277 if (rta >= crit.rta) {
2278 sc_rta = mp_set_subcheck_state(sc_rta, STATE_CRITICAL); 2278 sc_rta = mp_set_subcheck_state(sc_rta, STATE_CRITICAL);
2279 xasprintf(&sc_rta.output, "%s > %0.3fms", sc_rta.output, (double)crit.rta / 1000); 2279 xasprintf(&sc_rta.output, "%s >= %0.3fms", sc_rta.output, (double)crit.rta / 1000);
2280 } else if (rta >= warn.rta) { 2280 } else if (rta >= warn.rta) {
2281 sc_rta = mp_set_subcheck_state(sc_rta, STATE_WARNING); 2281 sc_rta = mp_set_subcheck_state(sc_rta, STATE_WARNING);
2282 xasprintf(&sc_rta.output, "%s > %0.3fms", sc_rta.output, (double)warn.rta / 1000); 2282 xasprintf(&sc_rta.output, "%s >= %0.3fms", sc_rta.output, (double)warn.rta / 1000);
2283 } 2283 }
2284 2284
2285 if (packet_loss < 100) { 2285 if (packet_loss < 100) {
@@ -2316,10 +2316,10 @@ mp_subcheck evaluate_target(ping_target target, check_icmp_mode_switches modes,
2316 2316
2317 if (packet_loss >= crit.pl) { 2317 if (packet_loss >= crit.pl) {
2318 sc_pl = mp_set_subcheck_state(sc_pl, STATE_CRITICAL); 2318 sc_pl = mp_set_subcheck_state(sc_pl, STATE_CRITICAL);
2319 xasprintf(&sc_pl.output, "%s > %u%%", sc_pl.output, crit.pl); 2319 xasprintf(&sc_pl.output, "%s >= %u%%", sc_pl.output, crit.pl);
2320 } else if (packet_loss >= warn.pl) { 2320 } else if (packet_loss >= warn.pl) {
2321 sc_pl = mp_set_subcheck_state(sc_pl, STATE_WARNING); 2321 sc_pl = mp_set_subcheck_state(sc_pl, STATE_WARNING);
2322 xasprintf(&sc_pl.output, "%s > %u%%", sc_pl.output, crit.pl); 2322 xasprintf(&sc_pl.output, "%s >= %u%%", sc_pl.output, warn.pl);
2323 } 2323 }
2324 2324
2325 mp_perfdata pd_pl = perfdata_init(); 2325 mp_perfdata pd_pl = perfdata_init();
@@ -2342,10 +2342,10 @@ mp_subcheck evaluate_target(ping_target target, check_icmp_mode_switches modes,
2342 2342
2343 if (target.jitter >= crit.jitter) { 2343 if (target.jitter >= crit.jitter) {
2344 sc_jitter = mp_set_subcheck_state(sc_jitter, STATE_CRITICAL); 2344 sc_jitter = mp_set_subcheck_state(sc_jitter, STATE_CRITICAL);
2345 xasprintf(&sc_jitter.output, "%s > %0.3fms", sc_jitter.output, crit.jitter); 2345 xasprintf(&sc_jitter.output, "%s >= %0.3fms", sc_jitter.output, crit.jitter);
2346 } else if (target.jitter >= warn.jitter) { 2346 } else if (target.jitter >= warn.jitter) {
2347 sc_jitter = mp_set_subcheck_state(sc_jitter, STATE_WARNING); 2347 sc_jitter = mp_set_subcheck_state(sc_jitter, STATE_WARNING);
2348 xasprintf(&sc_jitter.output, "%s > %0.3fms", sc_jitter.output, warn.jitter); 2348 xasprintf(&sc_jitter.output, "%s >= %0.3fms", sc_jitter.output, warn.jitter);
2349 } 2349 }
2350 2350
2351 if (packet_loss < 100) { 2351 if (packet_loss < 100) {
@@ -2379,10 +2379,10 @@ mp_subcheck evaluate_target(ping_target target, check_icmp_mode_switches modes,
2379 2379
2380 if (mos <= crit.mos) { 2380 if (mos <= crit.mos) {
2381 sc_mos = mp_set_subcheck_state(sc_mos, STATE_CRITICAL); 2381 sc_mos = mp_set_subcheck_state(sc_mos, STATE_CRITICAL);
2382 xasprintf(&sc_mos.output, "%s < %0.1f", sc_mos.output, crit.mos); 2382 xasprintf(&sc_mos.output, "%s <= %0.1f", sc_mos.output, crit.mos);
2383 } else if (mos <= warn.mos) { 2383 } else if (mos <= warn.mos) {
2384 sc_mos = mp_set_subcheck_state(sc_mos, STATE_WARNING); 2384 sc_mos = mp_set_subcheck_state(sc_mos, STATE_WARNING);
2385 xasprintf(&sc_mos.output, "%s < %0.1f", sc_mos.output, warn.mos); 2385 xasprintf(&sc_mos.output, "%s <= %0.1f", sc_mos.output, warn.mos);
2386 } 2386 }
2387 2387
2388 if (packet_loss < 100) { 2388 if (packet_loss < 100) {
@@ -2391,8 +2391,8 @@ mp_subcheck evaluate_target(ping_target target, check_icmp_mode_switches modes,
2391 pd_mos.value = mp_create_pd_value(mos); 2391 pd_mos.value = mp_create_pd_value(mos);
2392 pd_mos.warn = mp_range_set_end(pd_mos.warn, mp_create_pd_value(warn.mos)); 2392 pd_mos.warn = mp_range_set_end(pd_mos.warn, mp_create_pd_value(warn.mos));
2393 pd_mos.crit = mp_range_set_end(pd_mos.crit, mp_create_pd_value(crit.mos)); 2393 pd_mos.crit = mp_range_set_end(pd_mos.crit, mp_create_pd_value(crit.mos));
2394 pd_mos.min = mp_create_pd_value(0); 2394 pd_mos.min = mp_create_pd_value(0); // MOS starts at 0
2395 pd_mos.max = mp_create_pd_value(5); 2395 pd_mos.max = mp_create_pd_value(5); // MOS max is 5, by definition
2396 mp_add_perfdata_to_subcheck(&sc_mos, pd_mos); 2396 mp_add_perfdata_to_subcheck(&sc_mos, pd_mos);
2397 } 2397 }
2398 mp_add_subcheck_to_subcheck(&result, sc_mos); 2398 mp_add_subcheck_to_subcheck(&result, sc_mos);
@@ -2405,10 +2405,10 @@ mp_subcheck evaluate_target(ping_target target, check_icmp_mode_switches modes,
2405 2405
2406 if (score <= crit.score) { 2406 if (score <= crit.score) {
2407 sc_score = mp_set_subcheck_state(sc_score, STATE_CRITICAL); 2407 sc_score = mp_set_subcheck_state(sc_score, STATE_CRITICAL);
2408 xasprintf(&sc_score.output, "%s < %f", sc_score.output, crit.score); 2408 xasprintf(&sc_score.output, "%s <= %f", sc_score.output, crit.score);
2409 } else if (score <= warn.score) { 2409 } else if (score <= warn.score) {
2410 sc_score = mp_set_subcheck_state(sc_score, STATE_WARNING); 2410 sc_score = mp_set_subcheck_state(sc_score, STATE_WARNING);
2411 xasprintf(&sc_score.output, "%s < %f", sc_score.output, warn.score); 2411 xasprintf(&sc_score.output, "%s <= %f", sc_score.output, warn.score);
2412 } 2412 }
2413 2413
2414 if (packet_loss < 100) { 2414 if (packet_loss < 100) {
diff --git a/plugins-root/check_icmp.d/check_icmp_helpers.c b/plugins-root/check_icmp.d/check_icmp_helpers.c
index ec786305..d56fbd8b 100644
--- a/plugins-root/check_icmp.d/check_icmp_helpers.c
+++ b/plugins-root/check_icmp.d/check_icmp_helpers.c
@@ -34,8 +34,6 @@ check_icmp_config check_icmp_config_init() {
34 34
35 .ttl = DEFAULT_TTL, 35 .ttl = DEFAULT_TTL,
36 .icmp_data_size = DEFAULT_PING_DATA_SIZE, 36 .icmp_data_size = DEFAULT_PING_DATA_SIZE,
37 .icmp_pkt_size = DEFAULT_PING_DATA_SIZE + ICMP_MINLEN,
38 .pkt_interval = DEFAULT_PKT_INTERVAL,
39 .target_interval = 0, 37 .target_interval = 0,
40 .number_of_packets = DEFAULT_NUMBER_OF_PACKETS, 38 .number_of_packets = DEFAULT_NUMBER_OF_PACKETS,
41 39
@@ -52,6 +50,8 @@ check_icmp_config check_icmp_config_init() {
52 50
53 .number_of_hosts = 0, 51 .number_of_hosts = 0,
54 .hosts = NULL, 52 .hosts = NULL,
53
54 .output_format_is_set = false,
55 }; 55 };
56 return tmp; 56 return tmp;
57} 57}
diff --git a/plugins-root/check_icmp.d/config.h b/plugins-root/check_icmp.d/config.h
index fc9dd5a6..c348bef5 100644
--- a/plugins-root/check_icmp.d/config.h
+++ b/plugins-root/check_icmp.d/config.h
@@ -12,11 +12,12 @@
12#include <arpa/inet.h> 12#include <arpa/inet.h>
13#include <stdint.h> 13#include <stdint.h>
14#include "./check_icmp_helpers.h" 14#include "./check_icmp_helpers.h"
15#include "output.h"
15 16
16/* threshold structure. all values are maximum allowed, exclusive */ 17/* threshold structure. all values are maximum allowed, exclusive */
17typedef struct { 18typedef struct {
18 unsigned char pl; /* max allowed packet loss in percent */ 19 unsigned char pl; /* max allowed packet loss in percent */
19 time_t rta; /* roundtrip time average, microseconds */ 20 time_t rta; /* roundtrip time average, microseconds */
20 double jitter; /* jitter time average, microseconds */ 21 double jitter; /* jitter time average, microseconds */
21 double mos; /* MOS */ 22 double mos; /* MOS */
22 double score; /* Score */ 23 double score; /* Score */
@@ -59,8 +60,6 @@ typedef struct {
59 60
60 unsigned long ttl; 61 unsigned long ttl;
61 unsigned short icmp_data_size; 62 unsigned short icmp_data_size;
62 unsigned short icmp_pkt_size;
63 time_t pkt_interval;
64 time_t target_interval; 63 time_t target_interval;
65 unsigned short number_of_packets; 64 unsigned short number_of_packets;
66 65
@@ -77,6 +76,9 @@ typedef struct {
77 76
78 unsigned short number_of_hosts; 77 unsigned short number_of_hosts;
79 check_icmp_target_container *hosts; 78 check_icmp_target_container *hosts;
79
80 mp_output_format output_format;
81 bool output_format_is_set;
80} check_icmp_config; 82} check_icmp_config;
81 83
82check_icmp_config check_icmp_config_init(); 84check_icmp_config check_icmp_config_init();
@@ -94,7 +96,9 @@ typedef struct icmp_ping_data {
94#define DEFAULT_PING_DATA_SIZE (MIN_PING_DATA_SIZE + 44) 96#define DEFAULT_PING_DATA_SIZE (MIN_PING_DATA_SIZE + 44)
95 97
96/* 80 msec packet interval by default */ 98/* 80 msec packet interval by default */
97#define DEFAULT_PKT_INTERVAL 80000 99// DEPRECATED, remove when removing the option
100#define DEFAULT_PKT_INTERVAL 80000
101
98#define DEFAULT_TARGET_INTERVAL 0 102#define DEFAULT_TARGET_INTERVAL 0
99 103
100#define DEFAULT_WARN_RTA 200000 104#define DEFAULT_WARN_RTA 200000