1 /*****************************************************************************
3 * Nagios check_time plugin
6 * Copyright (c) 1999-2007 Nagios Plugins Development Team
10 * This file contains the check_time plugin
12 * This plugin will check the time difference with the specified host.
15 * This program is free software: you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation, either version 3 of the License, or
18 * (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program. If not, see <http://www.gnu.org/licenses/>.
29 *****************************************************************************/
31 const char *progname
= "check_time";
32 const char *copyright
= "1999-2007";
33 const char *email
= "nagiosplug-devel@lists.sourceforge.net";
43 #define UNIX_EPOCH 2208988800UL
45 uint32_t raw_server_time
;
46 unsigned long server_time
, diff_time
;
48 int check_warning_time
= FALSE
;
49 int critical_time
= 0;
50 int check_critical_time
= FALSE
;
51 unsigned long warning_diff
= 0;
52 int check_warning_diff
= FALSE
;
53 unsigned long critical_diff
= 0;
54 int check_critical_diff
= FALSE
;
55 int server_port
= TIME_PORT
;
56 char *server_address
= NULL
;
59 int process_arguments (int, char **);
60 void print_help (void);
61 void print_usage (void);
64 main (int argc
, char **argv
)
67 int result
= STATE_UNKNOWN
;
70 setlocale (LC_ALL
, "");
71 bindtextdomain (PACKAGE
, LOCALEDIR
);
74 /* Parse extra opts if any */
75 argv
=np_extra_opts (&argc
, argv
, progname
);
77 if (process_arguments (argc
, argv
) == ERROR
)
78 usage4 (_("Could not parse arguments"));
80 /* initialize alarm signal handling */
81 signal (SIGALRM
, socket_timeout_alarm_handler
);
83 /* set socket timeout */
84 alarm (socket_timeout
);
87 /* try to connect to the host at the given port number */
89 result
= my_udp_connect (server_address
, server_port
, &sd
);
91 result
= my_tcp_connect (server_address
, server_port
, &sd
);
94 if (result
!= STATE_OK
) {
95 if (check_critical_time
== TRUE
)
96 result
= STATE_CRITICAL
;
97 else if (check_warning_time
== TRUE
)
98 result
= STATE_WARNING
;
100 result
= STATE_UNKNOWN
;
102 _("TIME UNKNOWN - could not connect to server %s, port %d\n"),
103 server_address
, server_port
);
107 if (send (sd
, "", 0, 0) < 0) {
108 if (check_critical_time
== TRUE
)
109 result
= STATE_CRITICAL
;
110 else if (check_warning_time
== TRUE
)
111 result
= STATE_WARNING
;
113 result
= STATE_UNKNOWN
;
115 _("TIME UNKNOWN - could not send UDP request to server %s, port %d\n"),
116 server_address
, server_port
);
120 /* watch for the connection string */
121 result
= recv (sd
, (void *)&raw_server_time
, sizeof (raw_server_time
), 0);
123 /* close the connection */
126 /* reset the alarm */
130 /* return a WARNING status if we couldn't read any data */
132 if (check_critical_time
== TRUE
)
133 result
= STATE_CRITICAL
;
134 else if (check_warning_time
== TRUE
)
135 result
= STATE_WARNING
;
137 result
= STATE_UNKNOWN
;
139 _("TIME UNKNOWN - no data received from server %s, port %d\n"),
140 server_address
, server_port
);
145 conntime
= (end_time
- start_time
);
146 if (check_critical_time
== TRUE
&& conntime
> critical_time
)
147 result
= STATE_CRITICAL
;
148 else if (check_warning_time
== TRUE
&& conntime
> warning_time
)
149 result
= STATE_WARNING
;
151 if (result
!= STATE_OK
)
152 die (result
, _("TIME %s - %d second response time|%s\n"),
153 state_text (result
), (int)conntime
,
154 perfdata ("time", (long)conntime
, "s",
155 check_warning_time
, (long)warning_time
,
156 check_critical_time
, (long)critical_time
,
159 server_time
= ntohl (raw_server_time
) - UNIX_EPOCH
;
160 if (server_time
> (unsigned long)end_time
)
161 diff_time
= server_time
- (unsigned long)end_time
;
163 diff_time
= (unsigned long)end_time
- server_time
;
165 if (check_critical_diff
== TRUE
&& diff_time
> critical_diff
)
166 result
= STATE_CRITICAL
;
167 else if (check_warning_diff
== TRUE
&& diff_time
> warning_diff
)
168 result
= STATE_WARNING
;
170 printf (_("TIME %s - %lu second time difference|%s %s\n"),
171 state_text (result
), diff_time
,
172 perfdata ("time", (long)conntime
, "s",
173 check_warning_time
, (long)warning_time
,
174 check_critical_time
, (long)critical_time
,
176 perfdata ("offset", diff_time
, "s",
177 check_warning_diff
, warning_diff
,
178 check_critical_diff
, critical_diff
,
185 /* process command-line arguments */
187 process_arguments (int argc
, char **argv
)
192 static struct option longopts
[] = {
193 {"hostname", required_argument
, 0, 'H'},
194 {"warning-variance", required_argument
, 0, 'w'},
195 {"critical-variance", required_argument
, 0, 'c'},
196 {"warning-connect", required_argument
, 0, 'W'},
197 {"critical-connect", required_argument
, 0, 'C'},
198 {"port", required_argument
, 0, 'p'},
199 {"udp", no_argument
, 0, 'u'},
200 {"timeout", required_argument
, 0, 't'},
201 {"version", no_argument
, 0, 'V'},
202 {"help", no_argument
, 0, 'h'},
209 for (c
= 1; c
< argc
; c
++) {
210 if (strcmp ("-to", argv
[c
]) == 0)
211 strcpy (argv
[c
], "-t");
212 else if (strcmp ("-wd", argv
[c
]) == 0)
213 strcpy (argv
[c
], "-w");
214 else if (strcmp ("-cd", argv
[c
]) == 0)
215 strcpy (argv
[c
], "-c");
216 else if (strcmp ("-wt", argv
[c
]) == 0)
217 strcpy (argv
[c
], "-W");
218 else if (strcmp ("-ct", argv
[c
]) == 0)
219 strcpy (argv
[c
], "-C");
223 c
= getopt_long (argc
, argv
, "hVH:w:c:W:C:p:t:u", longopts
,
226 if (c
== -1 || c
== EOF
)
230 case '?': /* print short usage statement if args not parsable */
235 case 'V': /* version */
236 print_revision (progname
, NP_VERSION
);
238 case 'H': /* hostname */
239 if (is_host (optarg
) == FALSE
)
240 usage2 (_("Invalid hostname/address"), optarg
);
241 server_address
= optarg
;
243 case 'w': /* warning-variance */
244 if (is_intnonneg (optarg
)) {
245 warning_diff
= strtoul (optarg
, NULL
, 10);
246 check_warning_diff
= TRUE
;
248 else if (strspn (optarg
, "0123456789:,") > 0) {
249 if (sscanf (optarg
, "%lu%*[:,]%d", &warning_diff
, &warning_time
) == 2) {
250 check_warning_diff
= TRUE
;
251 check_warning_time
= TRUE
;
254 usage4 (_("Warning thresholds must be a positive integer"));
258 usage4 (_("Warning threshold must be a positive integer"));
261 case 'c': /* critical-variance */
262 if (is_intnonneg (optarg
)) {
263 critical_diff
= strtoul (optarg
, NULL
, 10);
264 check_critical_diff
= TRUE
;
266 else if (strspn (optarg
, "0123456789:,") > 0) {
267 if (sscanf (optarg
, "%lu%*[:,]%d", &critical_diff
, &critical_time
) ==
269 check_critical_diff
= TRUE
;
270 check_critical_time
= TRUE
;
273 usage4 (_("Critical thresholds must be a positive integer"));
277 usage4 (_("Critical threshold must be a positive integer"));
280 case 'W': /* warning-connect */
281 if (!is_intnonneg (optarg
))
282 usage4 (_("Warning threshold must be a positive integer"));
284 warning_time
= atoi (optarg
);
285 check_warning_time
= TRUE
;
287 case 'C': /* critical-connect */
288 if (!is_intnonneg (optarg
))
289 usage4 (_("Critical threshold must be a positive integer"));
291 critical_time
= atoi (optarg
);
292 check_critical_time
= TRUE
;
295 if (!is_intnonneg (optarg
))
296 usage4 (_("Port must be a positive integer"));
298 server_port
= atoi (optarg
);
300 case 't': /* timeout */
301 if (!is_intnonneg (optarg
))
302 usage2 (_("Timeout interval must be a positive integer"), optarg
);
304 socket_timeout
= atoi (optarg
);
312 if (server_address
== NULL
) {
314 if (is_host (argv
[c
]) == FALSE
)
315 usage2 (_("Invalid hostname/address"), optarg
);
316 server_address
= argv
[c
];
319 usage4 (_("Hostname was not supplied"));
332 asprintf (&myport
, "%d", TIME_PORT
);
334 print_revision (progname
, NP_VERSION
);
336 printf ("Copyright (c) 1999 Ethan Galstad\n");
337 printf (COPYRIGHT
, copyright
, email
);
339 printf ("%s\n", _("This plugin will check the time on the specified host."));
345 printf (_(UT_HELP_VRSN
));
346 printf (_(UT_EXTRA_OPTS
));
348 printf (_(UT_HOST_PORT
), 'p', myport
);
350 printf (" %s\n", "-u, --udp");
351 printf (" %s\n", _("Use UDP to connect, not TCP"));
352 printf (" %s\n", "-w, --warning-variance=INTEGER");
353 printf (" %s\n", _("Time difference (sec.) necessary to result in a warning status"));
354 printf (" %s\n", "-c, --critical-variance=INTEGER");
355 printf (" %s\n", _("Time difference (sec.) necessary to result in a critical status"));
356 printf (" %s\n", "-W, --warning-connect=INTEGER");
357 printf (" %s\n", _("Response time (sec.) necessary to result in warning status"));
358 printf (" %s\n", "-C, --critical-connect=INTEGER");
359 printf (" %s\n", _("Response time (sec.) necessary to result in critical status"));
361 printf (_(UT_TIMEOUT
), DEFAULT_SOCKET_TIMEOUT
);
365 printf ("%s\n", _("Notes:"));
366 printf (_(UT_EXTRA_OPTS_NOTES
));
369 printf (_(UT_SUPPORT
));
377 printf (_("Usage:"));
378 printf ("%s -H <host_address> [-p port] [-u] [-w variance] [-c variance]\n",progname
);
379 printf (" [-W connect_time] [-C connect_time] [-t timeout]\n");