1 /*****************************************************************************
3 * Nagios check_time plugin
6 * Copyright (c) 1999-2007 Nagios Plugins Development Team
8 * Last Modified: $Date$
12 * This file contains the check_time plugin
14 * This plugin will check the time difference with the specified host.
17 * This program is free software: you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation, either version 3 of the License, or
20 * (at your option) any later version.
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
27 * You should have received a copy of the GNU General Public License
28 * along with this program. If not, see <http://www.gnu.org/licenses/>.
32 *****************************************************************************/
34 const char *progname
= "check_time";
35 const char *revision
= "$Revision$";
36 const char *copyright
= "1999-2007";
37 const char *email
= "nagiosplug-devel@lists.sourceforge.net";
47 #define UNIX_EPOCH 2208988800UL
49 uint32_t raw_server_time
;
50 unsigned long server_time
, diff_time
;
52 int check_warning_time
= FALSE
;
53 int critical_time
= 0;
54 int check_critical_time
= FALSE
;
55 unsigned long warning_diff
= 0;
56 int check_warning_diff
= FALSE
;
57 unsigned long critical_diff
= 0;
58 int check_critical_diff
= FALSE
;
59 int server_port
= TIME_PORT
;
60 char *server_address
= NULL
;
63 int process_arguments (int, char **);
64 void print_help (void);
65 void print_usage (void);
68 main (int argc
, char **argv
)
71 int result
= STATE_UNKNOWN
;
74 setlocale (LC_ALL
, "");
75 bindtextdomain (PACKAGE
, LOCALEDIR
);
78 /* Parse extra opts if any */
79 argv
=np_extra_opts (&argc
, argv
, progname
);
81 if (process_arguments (argc
, argv
) == ERROR
)
82 usage4 (_("Could not parse arguments"));
84 /* initialize alarm signal handling */
85 signal (SIGALRM
, socket_timeout_alarm_handler
);
87 /* set socket timeout */
88 alarm (socket_timeout
);
91 /* try to connect to the host at the given port number */
93 result
= my_udp_connect (server_address
, server_port
, &sd
);
95 result
= my_tcp_connect (server_address
, server_port
, &sd
);
98 if (result
!= STATE_OK
) {
99 if (check_critical_time
== TRUE
)
100 result
= STATE_CRITICAL
;
101 else if (check_warning_time
== TRUE
)
102 result
= STATE_WARNING
;
104 result
= STATE_UNKNOWN
;
106 _("TIME UNKNOWN - could not connect to server %s, port %d\n"),
107 server_address
, server_port
);
111 if (send (sd
, "", 0, 0) < 0) {
112 if (check_critical_time
== TRUE
)
113 result
= STATE_CRITICAL
;
114 else if (check_warning_time
== TRUE
)
115 result
= STATE_WARNING
;
117 result
= STATE_UNKNOWN
;
119 _("TIME UNKNOWN - could not send UDP request to server %s, port %d\n"),
120 server_address
, server_port
);
124 /* watch for the connection string */
125 result
= recv (sd
, (void *)&raw_server_time
, sizeof (raw_server_time
), 0);
127 /* close the connection */
130 /* reset the alarm */
134 /* return a WARNING status if we couldn't read any data */
136 if (check_critical_time
== TRUE
)
137 result
= STATE_CRITICAL
;
138 else if (check_warning_time
== TRUE
)
139 result
= STATE_WARNING
;
141 result
= STATE_UNKNOWN
;
143 _("TIME UNKNOWN - no data received from server %s, port %d\n"),
144 server_address
, server_port
);
149 conntime
= (end_time
- start_time
);
150 if (check_critical_time
== TRUE
&& conntime
> critical_time
)
151 result
= STATE_CRITICAL
;
152 else if (check_warning_time
== TRUE
&& conntime
> warning_time
)
153 result
= STATE_WARNING
;
155 if (result
!= STATE_OK
)
156 die (result
, _("TIME %s - %d second response time|%s\n"),
157 state_text (result
), (int)conntime
,
158 perfdata ("time", (long)conntime
, "s",
159 check_warning_time
, (long)warning_time
,
160 check_critical_time
, (long)critical_time
,
163 server_time
= ntohl (raw_server_time
) - UNIX_EPOCH
;
164 if (server_time
> (unsigned long)end_time
)
165 diff_time
= server_time
- (unsigned long)end_time
;
167 diff_time
= (unsigned long)end_time
- server_time
;
169 if (check_critical_diff
== TRUE
&& diff_time
> critical_diff
)
170 result
= STATE_CRITICAL
;
171 else if (check_warning_diff
== TRUE
&& diff_time
> warning_diff
)
172 result
= STATE_WARNING
;
174 printf (_("TIME %s - %lu second time difference|%s %s\n"),
175 state_text (result
), diff_time
,
176 perfdata ("time", (long)conntime
, "s",
177 check_warning_time
, (long)warning_time
,
178 check_critical_time
, (long)critical_time
,
180 perfdata ("offset", diff_time
, "s",
181 check_warning_diff
, warning_diff
,
182 check_critical_diff
, critical_diff
,
189 /* process command-line arguments */
191 process_arguments (int argc
, char **argv
)
196 static struct option longopts
[] = {
197 {"hostname", required_argument
, 0, 'H'},
198 {"warning-variance", required_argument
, 0, 'w'},
199 {"critical-variance", required_argument
, 0, 'c'},
200 {"warning-connect", required_argument
, 0, 'W'},
201 {"critical-connect", required_argument
, 0, 'C'},
202 {"port", required_argument
, 0, 'p'},
203 {"udp", no_argument
, 0, 'u'},
204 {"timeout", required_argument
, 0, 't'},
205 {"version", no_argument
, 0, 'V'},
206 {"help", no_argument
, 0, 'h'},
213 for (c
= 1; c
< argc
; c
++) {
214 if (strcmp ("-to", argv
[c
]) == 0)
215 strcpy (argv
[c
], "-t");
216 else if (strcmp ("-wd", argv
[c
]) == 0)
217 strcpy (argv
[c
], "-w");
218 else if (strcmp ("-cd", argv
[c
]) == 0)
219 strcpy (argv
[c
], "-c");
220 else if (strcmp ("-wt", argv
[c
]) == 0)
221 strcpy (argv
[c
], "-W");
222 else if (strcmp ("-ct", argv
[c
]) == 0)
223 strcpy (argv
[c
], "-C");
227 c
= getopt_long (argc
, argv
, "hVH:w:c:W:C:p:t:u", longopts
,
230 if (c
== -1 || c
== EOF
)
234 case '?': /* print short usage statement if args not parsable */
239 case 'V': /* version */
240 print_revision (progname
, revision
);
242 case 'H': /* hostname */
243 if (is_host (optarg
) == FALSE
)
244 usage2 (_("Invalid hostname/address"), optarg
);
245 server_address
= optarg
;
247 case 'w': /* warning-variance */
248 if (is_intnonneg (optarg
)) {
249 warning_diff
= strtoul (optarg
, NULL
, 10);
250 check_warning_diff
= TRUE
;
252 else if (strspn (optarg
, "0123456789:,") > 0) {
253 if (sscanf (optarg
, "%lu%*[:,]%d", &warning_diff
, &warning_time
) == 2) {
254 check_warning_diff
= TRUE
;
255 check_warning_time
= TRUE
;
258 usage4 (_("Warning thresholds must be a positive integer"));
262 usage4 (_("Warning threshold must be a positive integer"));
265 case 'c': /* critical-variance */
266 if (is_intnonneg (optarg
)) {
267 critical_diff
= strtoul (optarg
, NULL
, 10);
268 check_critical_diff
= TRUE
;
270 else if (strspn (optarg
, "0123456789:,") > 0) {
271 if (sscanf (optarg
, "%lu%*[:,]%d", &critical_diff
, &critical_time
) ==
273 check_critical_diff
= TRUE
;
274 check_critical_time
= TRUE
;
277 usage4 (_("Critical thresholds must be a positive integer"));
281 usage4 (_("Critical threshold must be a positive integer"));
284 case 'W': /* warning-connect */
285 if (!is_intnonneg (optarg
))
286 usage4 (_("Warning threshold must be a positive integer"));
288 warning_time
= atoi (optarg
);
289 check_warning_time
= TRUE
;
291 case 'C': /* critical-connect */
292 if (!is_intnonneg (optarg
))
293 usage4 (_("Critical threshold must be a positive integer"));
295 critical_time
= atoi (optarg
);
296 check_critical_time
= TRUE
;
299 if (!is_intnonneg (optarg
))
300 usage4 (_("Port must be a positive integer"));
302 server_port
= atoi (optarg
);
304 case 't': /* timeout */
305 if (!is_intnonneg (optarg
))
306 usage2 (_("Timeout interval must be a positive integer"), optarg
);
308 socket_timeout
= atoi (optarg
);
316 if (server_address
== NULL
) {
318 if (is_host (argv
[c
]) == FALSE
)
319 usage2 (_("Invalid hostname/address"), optarg
);
320 server_address
= argv
[c
];
323 usage4 (_("Hostname was not supplied"));
336 asprintf (&myport
, "%d", TIME_PORT
);
338 print_revision (progname
, revision
);
340 printf ("Copyright (c) 1999 Ethan Galstad\n");
341 printf (COPYRIGHT
, copyright
, email
);
343 printf ("%s\n", _("This plugin will check the time on the specified host."));
349 printf (_(UT_HELP_VRSN
));
350 printf (_(UT_EXTRA_OPTS
));
352 printf (_(UT_HOST_PORT
), 'p', myport
);
354 printf (" %s\n", "-u, --udp");
355 printf (" %s\n", _("Use UDP to connect, not TCP"));
356 printf (" %s\n", "-w, --warning-variance=INTEGER");
357 printf (" %s\n", _("Time difference (sec.) necessary to result in a warning status"));
358 printf (" %s\n", "-c, --critical-variance=INTEGER");
359 printf (" %s\n", _("Time difference (sec.) necessary to result in a critical status"));
360 printf (" %s\n", "-W, --warning-connect=INTEGER");
361 printf (" %s\n", _("Response time (sec.) necessary to result in warning status"));
362 printf (" %s\n", "-C, --critical-connect=INTEGER");
363 printf (" %s\n", _("Response time (sec.) necessary to result in critical status"));
365 printf (_(UT_TIMEOUT
), DEFAULT_SOCKET_TIMEOUT
);
369 printf ("%s\n", _("Notes:"));
370 printf (_(UT_EXTRA_OPTS_NOTES
));
373 printf (_(UT_SUPPORT
));
381 printf (_("Usage:"));
382 printf ("%s -H <host_address> [-p port] [-u] [-w variance] [-c variance]\n",progname
);
383 printf (" [-W connect_time] [-C connect_time] [-t timeout]\n");