summaryrefslogtreecommitdiffstats
path: root/plugins/check_time.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/check_time.c')
-rw-r--r--plugins/check_time.c200
1 files changed, 113 insertions, 87 deletions
diff --git a/plugins/check_time.c b/plugins/check_time.c
index d1f50683..99708ad3 100644
--- a/plugins/check_time.c
+++ b/plugins/check_time.c
@@ -28,6 +28,7 @@
28 * 28 *
29 *****************************************************************************/ 29 *****************************************************************************/
30 30
31#include "states.h"
31const char *progname = "check_time"; 32const char *progname = "check_time";
32const char *copyright = "1999-2024"; 33const char *copyright = "1999-2024";
33const char *email = "devel@monitoring-plugins.org"; 34const char *email = "devel@monitoring-plugins.org";
@@ -35,28 +36,15 @@ const char *email = "devel@monitoring-plugins.org";
35#include "common.h" 36#include "common.h"
36#include "netutils.h" 37#include "netutils.h"
37#include "utils.h" 38#include "utils.h"
38 39#include "check_time.d/config.h"
39enum {
40 TIME_PORT = 37
41};
42 40
43#define UNIX_EPOCH 2208988800UL 41#define UNIX_EPOCH 2208988800UL
44 42
45static uint32_t raw_server_time; 43typedef struct {
46static unsigned long server_time, diff_time; 44 int errorcode;
47static int warning_time = 0; 45 check_time_config config;
48static bool check_warning_time = false; 46} check_time_config_wrapper;
49static int critical_time = 0; 47static check_time_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
50static bool check_critical_time = false;
51static unsigned long warning_diff = 0;
52static bool check_warning_diff = false;
53static unsigned long critical_diff = 0;
54static bool check_critical_diff = false;
55static int server_port = TIME_PORT;
56static char *server_address = NULL;
57static bool use_udp = false;
58
59static int process_arguments(int, char **);
60static void print_help(void); 48static void print_help(void);
61void print_usage(void); 49void print_usage(void);
62 50
@@ -68,101 +56,123 @@ int main(int argc, char **argv) {
68 /* Parse extra opts if any */ 56 /* Parse extra opts if any */
69 argv = np_extra_opts(&argc, argv, progname); 57 argv = np_extra_opts(&argc, argv, progname);
70 58
71 if (process_arguments(argc, argv) == ERROR) 59 check_time_config_wrapper tmp_config = process_arguments(argc, argv);
60 if (tmp_config.errorcode == ERROR) {
72 usage4(_("Could not parse arguments")); 61 usage4(_("Could not parse arguments"));
62 }
63
64 const check_time_config config = tmp_config.config;
73 65
74 /* initialize alarm signal handling */ 66 /* initialize alarm signal handling */
75 signal(SIGALRM, socket_timeout_alarm_handler); 67 signal(SIGALRM, socket_timeout_alarm_handler);
76 68
77 /* set socket timeout */ 69 /* set socket timeout */
78 alarm(socket_timeout); 70 alarm(socket_timeout);
71 time_t start_time;
79 time(&start_time); 72 time(&start_time);
80 73
81 int socket; 74 int socket;
82 int result = STATE_UNKNOWN; 75 mp_state_enum result = STATE_UNKNOWN;
83 /* try to connect to the host at the given port number */ 76 /* try to connect to the host at the given port number */
84 if (use_udp) { 77 if (config.use_udp) {
85 result = my_udp_connect(server_address, server_port, &socket); 78 result = my_udp_connect(config.server_address, config.server_port, &socket);
86 } else { 79 } else {
87 result = my_tcp_connect(server_address, server_port, &socket); 80 result = my_tcp_connect(config.server_address, config.server_port, &socket);
88 } 81 }
89 82
90 if (result != STATE_OK) { 83 if (result != STATE_OK) {
91 if (check_critical_time) 84 if (config.check_critical_time) {
92 result = STATE_CRITICAL; 85 result = STATE_CRITICAL;
93 else if (check_warning_time) 86 } else if (config.check_warning_time) {
94 result = STATE_WARNING; 87 result = STATE_WARNING;
95 else 88 } else {
96 result = STATE_UNKNOWN; 89 result = STATE_UNKNOWN;
97 die(result, _("TIME UNKNOWN - could not connect to server %s, port %d\n"), server_address, server_port); 90 }
91 die(result, _("TIME UNKNOWN - could not connect to server %s, port %d\n"),
92 config.server_address, config.server_port);
98 } 93 }
99 94
100 if (use_udp) { 95 if (config.use_udp) {
101 if (send(socket, "", 0, 0) < 0) { 96 if (send(socket, "", 0, 0) < 0) {
102 if (check_critical_time) 97 if (config.check_critical_time) {
103 result = STATE_CRITICAL; 98 result = STATE_CRITICAL;
104 else if (check_warning_time) 99 } else if (config.check_warning_time) {
105 result = STATE_WARNING; 100 result = STATE_WARNING;
106 else 101 } else {
107 result = STATE_UNKNOWN; 102 result = STATE_UNKNOWN;
108 die(result, _("TIME UNKNOWN - could not send UDP request to server %s, port %d\n"), server_address, server_port); 103 }
104 die(result, _("TIME UNKNOWN - could not send UDP request to server %s, port %d\n"),
105 config.server_address, config.server_port);
109 } 106 }
110 } 107 }
111 108
112 /* watch for the connection string */ 109 /* watch for the connection string */
110 uint32_t raw_server_time;
113 result = recv(socket, (void *)&raw_server_time, sizeof(raw_server_time), 0); 111 result = recv(socket, (void *)&raw_server_time, sizeof(raw_server_time), 0);
114 112
115 /* close the connection */ 113 /* close the connection */
116 close(socket); 114 close(socket);
117 115
118 /* reset the alarm */ 116 /* reset the alarm */
117 time_t end_time;
119 time(&end_time); 118 time(&end_time);
120 alarm(0); 119 alarm(0);
121 120
122 /* return a WARNING status if we couldn't read any data */ 121 /* return a WARNING status if we couldn't read any data */
123 if (result <= 0) { 122 if (result <= 0) {
124 if (check_critical_time) 123 if (config.check_critical_time) {
125 result = STATE_CRITICAL; 124 result = STATE_CRITICAL;
126 else if (check_warning_time) 125 } else if (config.check_warning_time) {
127 result = STATE_WARNING; 126 result = STATE_WARNING;
128 else 127 } else {
129 result = STATE_UNKNOWN; 128 result = STATE_UNKNOWN;
130 die(result, _("TIME UNKNOWN - no data received from server %s, port %d\n"), server_address, server_port); 129 }
130 die(result, _("TIME UNKNOWN - no data received from server %s, port %d\n"),
131 config.server_address, config.server_port);
131 } 132 }
132 133
133 result = STATE_OK; 134 result = STATE_OK;
134 135
135 time_t conntime = (end_time - start_time); 136 time_t conntime = (end_time - start_time);
136 if (check_critical_time && conntime > critical_time) 137 if (config.check_critical_time && conntime > config.critical_time) {
137 result = STATE_CRITICAL; 138 result = STATE_CRITICAL;
138 else if (check_warning_time && conntime > warning_time) 139 } else if (config.check_warning_time && conntime > config.warning_time) {
139 result = STATE_WARNING; 140 result = STATE_WARNING;
141 }
140 142
141 if (result != STATE_OK) 143 if (result != STATE_OK) {
142 die(result, _("TIME %s - %d second response time|%s\n"), state_text(result), (int)conntime, 144 die(result, _("TIME %s - %d second response time|%s\n"), state_text(result), (int)conntime,
143 perfdata("time", (long)conntime, "s", check_warning_time, (long)warning_time, check_critical_time, (long)critical_time, true, 0, 145 perfdata("time", (long)conntime, "s", config.check_warning_time,
144 false, 0)); 146 (long)config.warning_time, config.check_critical_time,
147 (long)config.critical_time, true, 0, false, 0));
148 }
145 149
150 unsigned long server_time;
151 unsigned long diff_time;
146 server_time = ntohl(raw_server_time) - UNIX_EPOCH; 152 server_time = ntohl(raw_server_time) - UNIX_EPOCH;
147 if (server_time > (unsigned long)end_time) 153 if (server_time > (unsigned long)end_time) {
148 diff_time = server_time - (unsigned long)end_time; 154 diff_time = server_time - (unsigned long)end_time;
149 else 155 } else {
150 diff_time = (unsigned long)end_time - server_time; 156 diff_time = (unsigned long)end_time - server_time;
157 }
151 158
152 if (check_critical_diff && diff_time > critical_diff) 159 if (config.check_critical_diff && diff_time > config.critical_diff) {
153 result = STATE_CRITICAL; 160 result = STATE_CRITICAL;
154 else if (check_warning_diff && diff_time > warning_diff) 161 } else if (config.check_warning_diff && diff_time > config.warning_diff) {
155 result = STATE_WARNING; 162 result = STATE_WARNING;
163 }
156 164
157 printf(_("TIME %s - %lu second time difference|%s %s\n"), state_text(result), diff_time, 165 printf(_("TIME %s - %lu second time difference|%s %s\n"), state_text(result), diff_time,
158 perfdata("time", (long)conntime, "s", check_warning_time, (long)warning_time, check_critical_time, (long)critical_time, true, 0, 166 perfdata("time", (long)conntime, "s", config.check_warning_time,
159 false, 0), 167 (long)config.warning_time, config.check_critical_time,
160 perfdata("offset", diff_time, "s", check_warning_diff, warning_diff, check_critical_diff, critical_diff, true, 0, false, 0)); 168 (long)config.critical_time, true, 0, false, 0),
169 perfdata("offset", diff_time, "s", config.check_warning_diff, config.warning_diff,
170 config.check_critical_diff, config.critical_diff, true, 0, false, 0));
161 return result; 171 return result;
162} 172}
163 173
164/* process command-line arguments */ 174/* process command-line arguments */
165int process_arguments(int argc, char **argv) { 175check_time_config_wrapper process_arguments(int argc, char **argv) {
166 static struct option longopts[] = {{"hostname", required_argument, 0, 'H'}, 176 static struct option longopts[] = {{"hostname", required_argument, 0, 'H'},
167 {"warning-variance", required_argument, 0, 'w'}, 177 {"warning-variance", required_argument, 0, 'w'},
168 {"critical-variance", required_argument, 0, 'c'}, 178 {"critical-variance", required_argument, 0, 'c'},
@@ -175,29 +185,37 @@ int process_arguments(int argc, char **argv) {
175 {"help", no_argument, 0, 'h'}, 185 {"help", no_argument, 0, 'h'},
176 {0, 0, 0, 0}}; 186 {0, 0, 0, 0}};
177 187
178 if (argc < 2) 188 if (argc < 2) {
179 usage("\n"); 189 usage("\n");
190 }
180 191
181 for (int i = 1; i < argc; i++) { 192 for (int i = 1; i < argc; i++) {
182 if (strcmp("-to", argv[i]) == 0) 193 if (strcmp("-to", argv[i]) == 0) {
183 strcpy(argv[i], "-t"); 194 strcpy(argv[i], "-t");
184 else if (strcmp("-wd", argv[i]) == 0) 195 } else if (strcmp("-wd", argv[i]) == 0) {
185 strcpy(argv[i], "-w"); 196 strcpy(argv[i], "-w");
186 else if (strcmp("-cd", argv[i]) == 0) 197 } else if (strcmp("-cd", argv[i]) == 0) {
187 strcpy(argv[i], "-c"); 198 strcpy(argv[i], "-c");
188 else if (strcmp("-wt", argv[i]) == 0) 199 } else if (strcmp("-wt", argv[i]) == 0) {
189 strcpy(argv[i], "-W"); 200 strcpy(argv[i], "-W");
190 else if (strcmp("-ct", argv[i]) == 0) 201 } else if (strcmp("-ct", argv[i]) == 0) {
191 strcpy(argv[i], "-C"); 202 strcpy(argv[i], "-C");
203 }
192 } 204 }
193 205
206 check_time_config_wrapper result = {
207 .errorcode = OK,
208 .config = check_time_config_init(),
209 };
210
194 int option_char; 211 int option_char;
195 while (true) { 212 while (true) {
196 int option = 0; 213 int option = 0;
197 option_char = getopt_long(argc, argv, "hVH:w:c:W:C:p:t:u", longopts, &option); 214 option_char = getopt_long(argc, argv, "hVH:w:c:W:C:p:t:u", longopts, &option);
198 215
199 if (option_char == -1 || option_char == EOF) 216 if (option_char == -1 || option_char == EOF) {
200 break; 217 break;
218 }
201 219
202 switch (option_char) { 220 switch (option_char) {
203 case '?': /* print short usage statement if args not parsable */ 221 case '?': /* print short usage statement if args not parsable */
@@ -209,18 +227,20 @@ int process_arguments(int argc, char **argv) {
209 print_revision(progname, NP_VERSION); 227 print_revision(progname, NP_VERSION);
210 exit(STATE_UNKNOWN); 228 exit(STATE_UNKNOWN);
211 case 'H': /* hostname */ 229 case 'H': /* hostname */
212 if (!is_host(optarg)) 230 if (!is_host(optarg)) {
213 usage2(_("Invalid hostname/address"), optarg); 231 usage2(_("Invalid hostname/address"), optarg);
214 server_address = optarg; 232 }
233 result.config.server_address = optarg;
215 break; 234 break;
216 case 'w': /* warning-variance */ 235 case 'w': /* warning-variance */
217 if (is_intnonneg(optarg)) { 236 if (is_intnonneg(optarg)) {
218 warning_diff = strtoul(optarg, NULL, 10); 237 result.config.warning_diff = strtoul(optarg, NULL, 10);
219 check_warning_diff = true; 238 result.config.check_warning_diff = true;
220 } else if (strspn(optarg, "0123456789:,") > 0) { 239 } else if (strspn(optarg, "0123456789:,") > 0) {
221 if (sscanf(optarg, "%lu%*[:,]%d", &warning_diff, &warning_time) == 2) { 240 if (sscanf(optarg, "%lu%*[:,]%d", &result.config.warning_diff,
222 check_warning_diff = true; 241 &result.config.warning_time) == 2) {
223 check_warning_time = true; 242 result.config.check_warning_diff = true;
243 result.config.check_warning_time = true;
224 } else { 244 } else {
225 usage4(_("Warning thresholds must be a positive integer")); 245 usage4(_("Warning thresholds must be a positive integer"));
226 } 246 }
@@ -230,12 +250,13 @@ int process_arguments(int argc, char **argv) {
230 break; 250 break;
231 case 'c': /* critical-variance */ 251 case 'c': /* critical-variance */
232 if (is_intnonneg(optarg)) { 252 if (is_intnonneg(optarg)) {
233 critical_diff = strtoul(optarg, NULL, 10); 253 result.config.critical_diff = strtoul(optarg, NULL, 10);
234 check_critical_diff = true; 254 result.config.check_critical_diff = true;
235 } else if (strspn(optarg, "0123456789:,") > 0) { 255 } else if (strspn(optarg, "0123456789:,") > 0) {
236 if (sscanf(optarg, "%lu%*[:,]%d", &critical_diff, &critical_time) == 2) { 256 if (sscanf(optarg, "%lu%*[:,]%d", &result.config.critical_diff,
237 check_critical_diff = true; 257 &result.config.critical_time) == 2) {
238 check_critical_time = true; 258 result.config.check_critical_diff = true;
259 result.config.check_critical_time = true;
239 } else { 260 } else {
240 usage4(_("Critical thresholds must be a positive integer")); 261 usage4(_("Critical thresholds must be a positive integer"));
241 } 262 }
@@ -244,48 +265,53 @@ int process_arguments(int argc, char **argv) {
244 } 265 }
245 break; 266 break;
246 case 'W': /* warning-connect */ 267 case 'W': /* warning-connect */
247 if (!is_intnonneg(optarg)) 268 if (!is_intnonneg(optarg)) {
248 usage4(_("Warning threshold must be a positive integer")); 269 usage4(_("Warning threshold must be a positive integer"));
249 else 270 } else {
250 warning_time = atoi(optarg); 271 result.config.warning_time = atoi(optarg);
251 check_warning_time = true; 272 }
273 result.config.check_warning_time = true;
252 break; 274 break;
253 case 'C': /* critical-connect */ 275 case 'C': /* critical-connect */
254 if (!is_intnonneg(optarg)) 276 if (!is_intnonneg(optarg)) {
255 usage4(_("Critical threshold must be a positive integer")); 277 usage4(_("Critical threshold must be a positive integer"));
256 else 278 } else {
257 critical_time = atoi(optarg); 279 result.config.critical_time = atoi(optarg);
258 check_critical_time = true; 280 }
281 result.config.check_critical_time = true;
259 break; 282 break;
260 case 'p': /* port */ 283 case 'p': /* port */
261 if (!is_intnonneg(optarg)) 284 if (!is_intnonneg(optarg)) {
262 usage4(_("Port must be a positive integer")); 285 usage4(_("Port must be a positive integer"));
263 else 286 } else {
264 server_port = atoi(optarg); 287 result.config.server_port = atoi(optarg);
288 }
265 break; 289 break;
266 case 't': /* timeout */ 290 case 't': /* timeout */
267 if (!is_intnonneg(optarg)) 291 if (!is_intnonneg(optarg)) {
268 usage2(_("Timeout interval must be a positive integer"), optarg); 292 usage2(_("Timeout interval must be a positive integer"), optarg);
269 else 293 } else {
270 socket_timeout = atoi(optarg); 294 socket_timeout = atoi(optarg);
295 }
271 break; 296 break;
272 case 'u': /* udp */ 297 case 'u': /* udp */
273 use_udp = true; 298 result.config.use_udp = true;
274 } 299 }
275 } 300 }
276 301
277 option_char = optind; 302 option_char = optind;
278 if (server_address == NULL) { 303 if (result.config.server_address == NULL) {
279 if (argc > option_char) { 304 if (argc > option_char) {
280 if (!is_host(argv[option_char])) 305 if (!is_host(argv[option_char])) {
281 usage2(_("Invalid hostname/address"), optarg); 306 usage2(_("Invalid hostname/address"), optarg);
282 server_address = argv[option_char]; 307 }
308 result.config.server_address = argv[option_char];
283 } else { 309 } else {
284 usage4(_("Hostname was not supplied")); 310 usage4(_("Hostname was not supplied"));
285 } 311 }
286 } 312 }
287 313
288 return OK; 314 return result;
289} 315}
290 316
291void print_help(void) { 317void print_help(void) {