summaryrefslogtreecommitdiffstats
path: root/plugins-root/check_icmp.d
diff options
context:
space:
mode:
Diffstat (limited to 'plugins-root/check_icmp.d')
-rw-r--r--plugins-root/check_icmp.d/check_icmp_helpers.c134
-rw-r--r--plugins-root/check_icmp.d/check_icmp_helpers.h68
-rw-r--r--plugins-root/check_icmp.d/config.h111
3 files changed, 313 insertions, 0 deletions
diff --git a/plugins-root/check_icmp.d/check_icmp_helpers.c b/plugins-root/check_icmp.d/check_icmp_helpers.c
new file mode 100644
index 00000000..ec786305
--- /dev/null
+++ b/plugins-root/check_icmp.d/check_icmp_helpers.c
@@ -0,0 +1,134 @@
1#include "./config.h"
2#include <math.h>
3#include <netinet/in.h>
4#include <sys/socket.h>
5#include "./check_icmp_helpers.h"
6#include "../../plugins/netutils.h"
7
8// timeout as a global variable to make it available to the timeout handler
9unsigned int timeout = DEFAULT_TIMEOUT;
10
11check_icmp_config check_icmp_config_init() {
12 check_icmp_config tmp = {
13 .modes =
14 {
15 .order_mode = false,
16 .mos_mode = false,
17 .rta_mode = false,
18 .pl_mode = false,
19 .jitter_mode = false,
20 .score_mode = false,
21 },
22
23 .min_hosts_alive = -1,
24 .crit = {.pl = DEFAULT_CRIT_PL,
25 .rta = DEFAULT_CRIT_RTA,
26 .jitter = 50.0,
27 .mos = 3.0,
28 .score = 70.0},
29 .warn = {.pl = DEFAULT_WARN_PL,
30 .rta = DEFAULT_WARN_RTA,
31 .jitter = 40.0,
32 .mos = 3.5,
33 .score = 80.0},
34
35 .ttl = DEFAULT_TTL,
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,
40 .number_of_packets = DEFAULT_NUMBER_OF_PACKETS,
41
42 .source_ip = NULL,
43 .need_v4 = false,
44 .need_v6 = false,
45
46 .sender_id = 0,
47
48 .mode = MODE_RTA,
49
50 .number_of_targets = 0,
51 .targets = NULL,
52
53 .number_of_hosts = 0,
54 .hosts = NULL,
55 };
56 return tmp;
57}
58
59ping_target ping_target_init() {
60 ping_target tmp = {
61 .rtmin = INFINITY,
62
63 .jitter_min = INFINITY,
64
65 .found_out_of_order_packets = false,
66 };
67
68 return tmp;
69}
70
71check_icmp_state check_icmp_state_init() {
72 check_icmp_state tmp = {.icmp_sent = 0, .icmp_lost = 0, .icmp_recv = 0, .targets_down = 0};
73
74 return tmp;
75}
76
77ping_target_create_wrapper ping_target_create(struct sockaddr_storage address) {
78 ping_target_create_wrapper result = {
79 .errorcode = OK,
80 };
81
82 struct sockaddr_storage *tmp_addr = &address;
83
84 /* disregard obviously stupid addresses
85 * (I didn't find an ipv6 equivalent to INADDR_NONE) */
86 if (((tmp_addr->ss_family == AF_INET &&
87 (((struct sockaddr_in *)tmp_addr)->sin_addr.s_addr == INADDR_NONE ||
88 ((struct sockaddr_in *)tmp_addr)->sin_addr.s_addr == INADDR_ANY))) ||
89 (tmp_addr->ss_family == AF_INET6 &&
90 (((struct sockaddr_in6 *)tmp_addr)->sin6_addr.s6_addr == in6addr_any.s6_addr))) {
91 result.errorcode = ERROR;
92 return result;
93 }
94
95 /* add the fresh ip */
96 ping_target target = ping_target_init();
97
98 /* fill out the sockaddr_storage struct */
99 target.address = address;
100
101 result.host = target;
102
103 return result;
104}
105
106check_icmp_target_container check_icmp_target_container_init() {
107 check_icmp_target_container tmp = {
108 .name = NULL,
109 .number_of_targets = 0,
110 .target_list = NULL,
111 };
112 return tmp;
113}
114
115unsigned int ping_target_list_append(ping_target *list, ping_target *elem) {
116 if (elem == NULL || list == NULL) {
117 return 0;
118 }
119
120 while (list->next != NULL) {
121 list = list->next;
122 }
123
124 list->next = elem;
125
126 unsigned int result = 1;
127
128 while (elem->next != NULL) {
129 result++;
130 elem = elem->next;
131 }
132
133 return result;
134}
diff --git a/plugins-root/check_icmp.d/check_icmp_helpers.h b/plugins-root/check_icmp.d/check_icmp_helpers.h
new file mode 100644
index 00000000..dc6ea40b
--- /dev/null
+++ b/plugins-root/check_icmp.d/check_icmp_helpers.h
@@ -0,0 +1,68 @@
1#pragma once
2
3#include "../../lib/states.h"
4#include <netinet/in_systm.h>
5#include <netinet/in.h>
6#include <netinet/ip.h>
7#include <netinet/ip6.h>
8#include <netinet/ip_icmp.h>
9#include <netinet/icmp6.h>
10#include <arpa/inet.h>
11
12typedef struct ping_target {
13 unsigned short id; /* id in **table, and icmp pkts */
14 char *msg; /* icmp error message, if any */
15
16 struct sockaddr_storage address; /* the address of this host */
17 struct sockaddr_storage error_addr; /* stores address of error replies */
18 time_t time_waited; /* total time waited, in usecs */
19 unsigned int icmp_sent, icmp_recv, icmp_lost; /* counters */
20 unsigned char icmp_type, icmp_code; /* type and code from errors */
21 unsigned short flags; /* control/status flags */
22
23 double rtmax; /* max rtt */
24 double rtmin; /* min rtt */
25
26 double jitter; /* measured jitter */
27 double jitter_max; /* jitter rtt maximum */
28 double jitter_min; /* jitter rtt minimum */
29
30 time_t last_tdiff;
31 unsigned int last_icmp_seq; /* Last ICMP_SEQ to check out of order pkts */
32
33 bool found_out_of_order_packets;
34
35 struct ping_target *next;
36} ping_target;
37
38ping_target ping_target_init();
39
40typedef struct {
41 char *name;
42 ping_target *target_list;
43 unsigned int number_of_targets;
44} check_icmp_target_container;
45
46check_icmp_target_container check_icmp_target_container_init();
47
48typedef struct {
49 unsigned int icmp_sent;
50 unsigned int icmp_recv;
51 unsigned int icmp_lost;
52 unsigned short targets_down;
53} check_icmp_state;
54
55check_icmp_state check_icmp_state_init();
56
57typedef struct {
58 int errorcode;
59 ping_target host;
60} ping_target_create_wrapper;
61
62typedef struct {
63 int socket4;
64 int socket6;
65} check_icmp_socket_set;
66
67ping_target_create_wrapper ping_target_create(struct sockaddr_storage address);
68unsigned int ping_target_list_append(ping_target *list, ping_target *elem);
diff --git a/plugins-root/check_icmp.d/config.h b/plugins-root/check_icmp.d/config.h
new file mode 100644
index 00000000..fc9dd5a6
--- /dev/null
+++ b/plugins-root/check_icmp.d/config.h
@@ -0,0 +1,111 @@
1#pragma once
2
3#include "../../config.h"
4#include "../../lib/states.h"
5#include <stddef.h>
6#include <netinet/in_systm.h>
7#include <netinet/in.h>
8#include <netinet/ip.h>
9#include <netinet/ip6.h>
10#include <netinet/ip_icmp.h>
11#include <netinet/icmp6.h>
12#include <arpa/inet.h>
13#include <stdint.h>
14#include "./check_icmp_helpers.h"
15
16/* threshold structure. all values are maximum allowed, exclusive */
17typedef struct {
18 unsigned char pl; /* max allowed packet loss in percent */
19 time_t rta; /* roundtrip time average, microseconds */
20 double jitter; /* jitter time average, microseconds */
21 double mos; /* MOS */
22 double score; /* Score */
23} check_icmp_threshold;
24
25/* the different modes of this program are as follows:
26 * MODE_RTA: send all packets no matter what (mimic check_icmp and check_ping)
27 * MODE_HOSTCHECK: Return immediately upon any sign of life
28 * In addition, sends packets to ALL addresses assigned
29 * to this host (as returned by gethostbyname() or
30 * gethostbyaddr() and expects one host only to be checked at
31 * a time. Therefore, any packet response what so ever will
32 * count as a sign of life, even when received outside
33 * crit.rta limit. Do not misspell any additional IP's.
34 * MODE_ALL: Requires packets from ALL requested IP to return OK (default).
35 * MODE_ICMP: Default Mode
36 */
37typedef enum {
38 MODE_RTA,
39 MODE_HOSTCHECK,
40 MODE_ALL,
41 MODE_ICMP,
42} check_icmp_execution_mode;
43
44typedef struct {
45 bool order_mode;
46 bool mos_mode;
47 bool rta_mode;
48 bool pl_mode;
49 bool jitter_mode;
50 bool score_mode;
51} check_icmp_mode_switches;
52
53typedef struct {
54 check_icmp_mode_switches modes;
55
56 int min_hosts_alive;
57 check_icmp_threshold crit;
58 check_icmp_threshold warn;
59
60 unsigned long ttl;
61 unsigned short icmp_data_size;
62 unsigned short icmp_pkt_size;
63 time_t pkt_interval;
64 time_t target_interval;
65 unsigned short number_of_packets;
66
67 char *source_ip;
68 bool need_v4;
69 bool need_v6;
70
71 uint16_t sender_id; // PID of the main process, which is used as an ID in packets
72
73 check_icmp_execution_mode mode;
74
75 unsigned short number_of_targets;
76 ping_target *targets;
77
78 unsigned short number_of_hosts;
79 check_icmp_target_container *hosts;
80} check_icmp_config;
81
82check_icmp_config check_icmp_config_init();
83
84/* the data structure */
85typedef struct icmp_ping_data {
86 struct timeval stime; /* timestamp (saved in protocol struct as well) */
87 unsigned short ping_id;
88} icmp_ping_data;
89
90#define MAX_IP_PKT_SIZE 65536 /* (theoretical) max IP packet size */
91#define IP_HDR_SIZE 20
92#define MAX_PING_DATA (MAX_IP_PKT_SIZE - IP_HDR_SIZE - ICMP_MINLEN)
93#define MIN_PING_DATA_SIZE sizeof(struct icmp_ping_data)
94#define DEFAULT_PING_DATA_SIZE (MIN_PING_DATA_SIZE + 44)
95
96/* 80 msec packet interval by default */
97#define DEFAULT_PKT_INTERVAL 80000
98#define DEFAULT_TARGET_INTERVAL 0
99
100#define DEFAULT_WARN_RTA 200000
101#define DEFAULT_CRIT_RTA 500000
102#define DEFAULT_WARN_PL 40
103#define DEFAULT_CRIT_PL 80
104
105#define DEFAULT_TIMEOUT 10
106#define DEFAULT_TTL 64
107
108#define DEFAULT_NUMBER_OF_PACKETS 5
109
110#define PACKET_BACKOFF_FACTOR 1.5
111#define TARGET_BACKOFF_FACTOR 1.5