summaryrefslogtreecommitdiffstats
path: root/plugins/check_nt.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/check_nt.c')
-rw-r--r--plugins/check_nt.c756
1 files changed, 0 insertions, 756 deletions
diff --git a/plugins/check_nt.c b/plugins/check_nt.c
deleted file mode 100644
index 7dd23e5c..00000000
--- a/plugins/check_nt.c
+++ /dev/null
@@ -1,756 +0,0 @@
1/*****************************************************************************
2 *
3 * Monitoring check_nt plugin
4 *
5 * License: GPL
6 * Copyright (c) 2000-2002 Yves Rubin (rubiyz@yahoo.com)
7 * Copyright (c) 2003-2024 Monitoring Plugins Development Team
8 *
9 * Description:
10 *
11 * This file contains the check_nt plugin
12 *
13 * This plugin collects data from the NSClient service running on a
14 * Windows NT/2000/XP/2003 server.
15 * This plugin requires NSClient software to run on NT
16 * (https://nsclient.org/)
17 *
18 *
19 * This program is free software: you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation, either version 3 of the License, or
22 * (at your option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License
30 * along with this program. If not, see <http://www.gnu.org/licenses/>.
31 *
32 *
33 *****************************************************************************/
34
35const char *progname = "check_nt";
36const char *copyright = "2000-2024";
37const char *email = "devel@monitoring-plugins.org";
38
39#include "common.h"
40#include "netutils.h"
41#include "utils.h"
42#include "check_nt.d/config.h"
43
44enum {
45 MAX_VALUE_LIST = 30,
46};
47
48static char recv_buffer[MAX_INPUT_BUFFER];
49
50static void fetch_data(const char *address, int port, const char *sendb);
51
52typedef struct {
53 int errorcode;
54 check_nt_config config;
55} check_nt_config_wrapper;
56static check_nt_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
57
58static void preparelist(char *string);
59static bool strtoularray(unsigned long *array, char *string, const char *delim);
60static void print_help(void);
61void print_usage(void);
62
63int main(int argc, char **argv) {
64 setlocale(LC_ALL, "");
65 bindtextdomain(PACKAGE, LOCALEDIR);
66 textdomain(PACKAGE);
67
68 /* Parse extra opts if any */
69 argv = np_extra_opts(&argc, argv, progname);
70
71 check_nt_config_wrapper tmp_config = process_arguments(argc, argv);
72 if (tmp_config.errorcode == ERROR) {
73 usage4(_("Could not parse arguments"));
74 }
75
76 const check_nt_config config = tmp_config.config;
77
78 /* initialize alarm signal handling */
79 signal(SIGALRM, socket_timeout_alarm_handler);
80
81 /* set socket timeout */
82 alarm(socket_timeout);
83
84 int return_code = STATE_UNKNOWN;
85 char *send_buffer = NULL;
86 char *output_message = NULL;
87 char *perfdata = NULL;
88 char *temp_string = NULL;
89 char *temp_string_perf = NULL;
90 char *description = NULL;
91 char *counter_unit = NULL;
92 char *errcvt = NULL;
93 unsigned long lvalue_list[MAX_VALUE_LIST];
94 switch (config.vars_to_check) {
95 case CHECK_CLIENTVERSION:
96 xasprintf(&send_buffer, "%s&1", config.req_password);
97 fetch_data(config.server_address, config.server_port, send_buffer);
98 if (config.value_list != NULL && strcmp(recv_buffer, config.value_list) != 0) {
99 xasprintf(&output_message, _("Wrong client version - running: %s, required: %s"), recv_buffer, config.value_list);
100 return_code = STATE_WARNING;
101 } else {
102 xasprintf(&output_message, "%s", recv_buffer);
103 return_code = STATE_OK;
104 }
105 break;
106 case CHECK_CPULOAD:
107 if (config.value_list == NULL) {
108 output_message = strdup(_("missing -l parameters"));
109 } else if (!strtoularray(lvalue_list, config.value_list, ",")) {
110 output_message = strdup(_("wrong -l parameter."));
111 } else {
112 /* -l parameters is present with only integers */
113 return_code = STATE_OK;
114 temp_string = strdup(_("CPU Load"));
115 temp_string_perf = strdup(" ");
116
117 /* loop until one of the parameters is wrong or not present */
118 int offset = 0;
119 while (lvalue_list[0 + offset] > (unsigned long)0 && lvalue_list[0 + offset] <= (unsigned long)17280 &&
120 lvalue_list[1 + offset] > (unsigned long)0 && lvalue_list[1 + offset] <= (unsigned long)100 &&
121 lvalue_list[2 + offset] > (unsigned long)0 && lvalue_list[2 + offset] <= (unsigned long)100) {
122
123 /* Send request and retrieve data */
124 xasprintf(&send_buffer, "%s&2&%lu", config.req_password, lvalue_list[0 + offset]);
125 fetch_data(config.server_address, config.server_port, send_buffer);
126
127 unsigned long utilization = strtoul(recv_buffer, NULL, 10);
128
129 /* Check if any of the request is in a warning or critical state */
130 if (utilization >= lvalue_list[2 + offset]) {
131 return_code = STATE_CRITICAL;
132 } else if (utilization >= lvalue_list[1 + offset] && return_code < STATE_WARNING) {
133 return_code = STATE_WARNING;
134 }
135
136 xasprintf(&output_message, _(" %lu%% (%lu min average)"), utilization, lvalue_list[0 + offset]);
137 xasprintf(&temp_string, "%s%s", temp_string, output_message);
138 xasprintf(&perfdata, _(" '%lu min avg Load'=%lu%%;%lu;%lu;0;100"), lvalue_list[0 + offset], utilization,
139 lvalue_list[1 + offset], lvalue_list[2 + offset]);
140 xasprintf(&temp_string_perf, "%s%s", temp_string_perf, perfdata);
141 offset += 3; /* move across the array */
142 }
143
144 if (strlen(temp_string) > 10) { /* we had at least one loop */
145 output_message = strdup(temp_string);
146 perfdata = temp_string_perf;
147 } else {
148 output_message = strdup(_("not enough values for -l parameters"));
149 }
150 }
151 break;
152 case CHECK_UPTIME: {
153 char *tmp_value_list = config.value_list;
154 if (config.value_list == NULL) {
155 tmp_value_list = "minutes";
156 }
157 if (strncmp(tmp_value_list, "seconds", strlen("seconds") + 1) && strncmp(tmp_value_list, "minutes", strlen("minutes") + 1) &&
158 strncmp(config.value_list, "hours", strlen("hours") + 1) && strncmp(tmp_value_list, "days", strlen("days") + 1)) {
159
160 output_message = strdup(_("wrong -l argument"));
161 } else {
162 xasprintf(&send_buffer, "%s&3", config.req_password);
163 fetch_data(config.server_address, config.server_port, send_buffer);
164 unsigned long uptime = strtoul(recv_buffer, NULL, 10);
165 int updays = uptime / 86400;
166 int uphours = (uptime % 86400) / 3600;
167 int upminutes = ((uptime % 86400) % 3600) / 60;
168
169 if (!strncmp(tmp_value_list, "minutes", strlen("minutes"))) {
170 uptime = uptime / 60;
171 } else if (!strncmp(tmp_value_list, "hours", strlen("hours"))) {
172 uptime = uptime / 3600;
173 } else if (!strncmp(tmp_value_list, "days", strlen("days"))) {
174 uptime = uptime / 86400;
175 }
176 /* else uptime in seconds, nothing to do */
177
178 xasprintf(&output_message, _("System Uptime - %u day(s) %u hour(s) %u minute(s) |uptime=%lu"), updays, uphours, upminutes,
179 uptime);
180
181 if (config.check_critical_value && uptime <= config.critical_value) {
182 return_code = STATE_CRITICAL;
183 } else if (config.check_warning_value && uptime <= config.warning_value) {
184 return_code = STATE_WARNING;
185 } else {
186 return_code = STATE_OK;
187 }
188 }
189 } break;
190 case CHECK_USEDDISKSPACE:
191 if (config.value_list == NULL) {
192 output_message = strdup(_("missing -l parameters"));
193 } else if (strlen(config.value_list) != 1) {
194 output_message = strdup(_("wrong -l argument"));
195 } else {
196 xasprintf(&send_buffer, "%s&4&%s", config.req_password, config.value_list);
197 fetch_data(config.server_address, config.server_port, send_buffer);
198 char *fds = strtok(recv_buffer, "&");
199 char *tds = strtok(NULL, "&");
200 double total_disk_space = 0;
201 double free_disk_space = 0;
202 if (fds != NULL) {
203 free_disk_space = atof(fds);
204 }
205 if (tds != NULL) {
206 total_disk_space = atof(tds);
207 }
208
209 if (total_disk_space > 0 && free_disk_space >= 0) {
210 double percent_used_space = ((total_disk_space - free_disk_space) / total_disk_space) * 100;
211 double warning_used_space = ((float)config.warning_value / 100) * total_disk_space;
212 double critical_used_space = ((float)config.critical_value / 100) * total_disk_space;
213
214 xasprintf(&temp_string, _("%s:\\ - total: %.2f Gb - used: %.2f Gb (%.0f%%) - free %.2f Gb (%.0f%%)"), config.value_list,
215 total_disk_space / 1073741824, (total_disk_space - free_disk_space) / 1073741824, percent_used_space,
216 free_disk_space / 1073741824, (free_disk_space / total_disk_space) * 100);
217 xasprintf(&temp_string_perf, _("'%s:\\ Used Space'=%.2fGb;%.2f;%.2f;0.00;%.2f"), config.value_list,
218 (total_disk_space - free_disk_space) / 1073741824, warning_used_space / 1073741824,
219 critical_used_space / 1073741824, total_disk_space / 1073741824);
220
221 if (config.check_critical_value && percent_used_space >= config.critical_value) {
222 return_code = STATE_CRITICAL;
223 } else if (config.check_warning_value && percent_used_space >= config.warning_value) {
224 return_code = STATE_WARNING;
225 } else {
226 return_code = STATE_OK;
227 }
228
229 output_message = strdup(temp_string);
230 perfdata = temp_string_perf;
231 } else {
232 output_message = strdup(_("Free disk space : Invalid drive"));
233 return_code = STATE_UNKNOWN;
234 }
235 }
236 break;
237 case CHECK_SERVICESTATE:
238 case CHECK_PROCSTATE:
239 if (config.value_list == NULL) {
240 output_message = strdup(_("No service/process specified"));
241 } else {
242 preparelist(config.value_list); /* replace , between services with & to send the request */
243 xasprintf(&send_buffer, "%s&%u&%s&%s", config.req_password, (config.vars_to_check == CHECK_SERVICESTATE) ? 5 : 6,
244 (config.show_all) ? "ShowAll" : "ShowFail", config.value_list);
245 fetch_data(config.server_address, config.server_port, send_buffer);
246 char *numstr = strtok(recv_buffer, "&");
247 if (numstr == NULL) {
248 die(STATE_UNKNOWN, _("could not fetch information from server\n"));
249 }
250 return_code = atoi(numstr);
251 temp_string = strtok(NULL, "&");
252 output_message = strdup(temp_string);
253 }
254 break;
255 case CHECK_MEMUSE:
256 xasprintf(&send_buffer, "%s&7", config.req_password);
257 fetch_data(config.server_address, config.server_port, send_buffer);
258 char *numstr = strtok(recv_buffer, "&");
259 if (numstr == NULL) {
260 die(STATE_UNKNOWN, _("could not fetch information from server\n"));
261 }
262 double mem_commitLimit = atof(numstr);
263 numstr = strtok(NULL, "&");
264 if (numstr == NULL) {
265 die(STATE_UNKNOWN, _("could not fetch information from server\n"));
266 }
267 double mem_commitByte = atof(numstr);
268 double percent_used_space = (mem_commitByte / mem_commitLimit) * 100;
269 double warning_used_space = ((float)config.warning_value / 100) * mem_commitLimit;
270 double critical_used_space = ((float)config.critical_value / 100) * mem_commitLimit;
271
272 /* Divisor should be 1048567, not 3044515, as we are measuring "Commit Charge" here,
273 which equals RAM + Pagefiles. */
274 xasprintf(&output_message, _("Memory usage: total:%.2f MB - used: %.2f MB (%.0f%%) - free: %.2f MB (%.0f%%)"),
275 mem_commitLimit / 1048567, mem_commitByte / 1048567, percent_used_space, (mem_commitLimit - mem_commitByte) / 1048567,
276 (mem_commitLimit - mem_commitByte) / mem_commitLimit * 100);
277 xasprintf(&perfdata, _("'Memory usage'=%.2fMB;%.2f;%.2f;0.00;%.2f"), mem_commitByte / 1048567, warning_used_space / 1048567,
278 critical_used_space / 1048567, mem_commitLimit / 1048567);
279
280 return_code = STATE_OK;
281 if (config.check_critical_value && percent_used_space >= config.critical_value) {
282 return_code = STATE_CRITICAL;
283 } else if (config.check_warning_value && percent_used_space >= config.warning_value) {
284 return_code = STATE_WARNING;
285 }
286
287 break;
288 case CHECK_COUNTER: {
289 /*
290 CHECK_COUNTER has been modified to provide extensive perfdata information.
291 In order to do this, some modifications have been done to the code
292 and some constraints have been introduced.
293
294 1) For the sake of simplicity of the code, perfdata information will only be
295 provided when the "description" field is added.
296
297 2) If the counter you're going to measure is percent-based, the code will detect
298 the percent sign in its name and will attribute minimum (0%) and maximum (100%)
299 values automagically, as well the "%" sign to graph units.
300
301 3) OTOH, if the counter is "absolute", you'll have to provide the following
302 the counter unit - that is, the dimensions of the counter you're getting. Examples:
303 pages/s, packets transferred, etc.
304
305 4) If you want, you may provide the minimum and maximum values to expect. They aren't mandatory,
306 but once specified they MUST have the same order of magnitude and units of -w and -c; otherwise.
307 strange things will happen when you make graphs of your data.
308 */
309
310 double counter_value = 0.0;
311 if (config.value_list == NULL) {
312 output_message = strdup(_("No counter specified"));
313 } else {
314 preparelist(config.value_list); /* replace , between services with & to send the request */
315 bool isPercent = (strchr(config.value_list, '%') != NULL);
316
317 strtok(config.value_list, "&"); /* burn the first parameters */
318 description = strtok(NULL, "&");
319 counter_unit = strtok(NULL, "&");
320 xasprintf(&send_buffer, "%s&8&%s", config.req_password, config.value_list);
321 fetch_data(config.server_address, config.server_port, send_buffer);
322 counter_value = atof(recv_buffer);
323
324 bool allRight = false;
325 if (description == NULL) {
326 xasprintf(&output_message, "%.f", counter_value);
327 } else if (isPercent) {
328 counter_unit = strdup("%");
329 allRight = true;
330 }
331
332 char *minval = NULL;
333 char *maxval = NULL;
334 double fminval = 0;
335 double fmaxval = 0;
336 if ((counter_unit != NULL) && (!allRight)) {
337 minval = strtok(NULL, "&");
338 maxval = strtok(NULL, "&");
339
340 /* All parameters specified. Let's check the numbers */
341
342 fminval = (minval != NULL) ? strtod(minval, &errcvt) : -1;
343 fmaxval = (minval != NULL) ? strtod(maxval, &errcvt) : -1;
344
345 if ((fminval == 0) && (minval == errcvt)) {
346 output_message = strdup(_("Minimum value contains non-numbers"));
347 } else {
348 if ((fmaxval == 0) && (maxval == errcvt)) {
349 output_message = strdup(_("Maximum value contains non-numbers"));
350 } else {
351 allRight = true; /* Everything is OK. */
352 }
353 }
354 } else if ((counter_unit == NULL) && (description != NULL)) {
355 output_message = strdup(_("No unit counter specified"));
356 }
357
358 if (allRight) {
359 /* Let's format the output string, finally... */
360 if (strstr(description, "%") == NULL) {
361 xasprintf(&output_message, "%s = %.2f %s", description, counter_value, counter_unit);
362 } else {
363 /* has formatting, will segv if wrong */
364 xasprintf(&output_message, description, counter_value);
365 }
366 xasprintf(&output_message, "%s |", output_message);
367 xasprintf(&output_message, "%s %s", output_message,
368 fperfdata(description, counter_value, counter_unit, 1, config.warning_value, 1, config.critical_value,
369 (!(isPercent) && (minval != NULL)), fminval, (!(isPercent) && (minval != NULL)), fmaxval));
370 }
371 }
372
373 if (config.critical_value > config.warning_value) { /* Normal thresholds */
374 if (config.check_critical_value && counter_value >= config.critical_value) {
375 return_code = STATE_CRITICAL;
376 } else if (config.check_warning_value && counter_value >= config.warning_value) {
377 return_code = STATE_WARNING;
378 } else {
379 return_code = STATE_OK;
380 }
381 } else { /* inverse thresholds */
382 return_code = STATE_OK;
383 if (config.check_critical_value && counter_value <= config.critical_value) {
384 return_code = STATE_CRITICAL;
385 } else if (config.check_warning_value && counter_value <= config.warning_value) {
386 return_code = STATE_WARNING;
387 }
388 }
389 } break;
390 case CHECK_FILEAGE:
391 if (config.value_list == NULL) {
392 output_message = strdup(_("No counter specified"));
393 } else {
394 preparelist(config.value_list); /* replace , between services with & to send the request */
395 xasprintf(&send_buffer, "%s&9&%s", config.req_password, config.value_list);
396 fetch_data(config.server_address, config.server_port, send_buffer);
397 unsigned long age_in_minutes = atoi(strtok(recv_buffer, "&"));
398 description = strtok(NULL, "&");
399 output_message = strdup(description);
400
401 if (config.critical_value > config.warning_value) { /* Normal thresholds */
402 if (config.check_critical_value && age_in_minutes >= config.critical_value) {
403 return_code = STATE_CRITICAL;
404 } else if (config.check_warning_value && age_in_minutes >= config.warning_value) {
405 return_code = STATE_WARNING;
406 } else {
407 return_code = STATE_OK;
408 }
409 } else { /* inverse thresholds */
410 if (config.check_critical_value && age_in_minutes <= config.critical_value) {
411 return_code = STATE_CRITICAL;
412 } else if (config.check_warning_value && age_in_minutes <= config.warning_value) {
413 return_code = STATE_WARNING;
414 } else {
415 return_code = STATE_OK;
416 }
417 }
418 }
419 break;
420
421 case CHECK_INSTANCES:
422 if (config.value_list == NULL) {
423 output_message = strdup(_("No counter specified"));
424 } else {
425 xasprintf(&send_buffer, "%s&10&%s", config.req_password, config.value_list);
426 fetch_data(config.server_address, config.server_port, send_buffer);
427 if (!strncmp(recv_buffer, "ERROR", 5)) {
428 printf("NSClient - %s\n", recv_buffer);
429 exit(STATE_UNKNOWN);
430 }
431 xasprintf(&output_message, "%s", recv_buffer);
432 return_code = STATE_OK;
433 }
434 break;
435
436 case CHECK_NONE:
437 default:
438 usage4(_("Please specify a variable to check"));
439 break;
440 }
441
442 /* reset timeout */
443 alarm(0);
444
445 if (perfdata == NULL) {
446 printf("%s\n", output_message);
447 } else {
448 printf("%s | %s\n", output_message, perfdata);
449 }
450 return return_code;
451}
452
453/* process command-line arguments */
454check_nt_config_wrapper process_arguments(int argc, char **argv) {
455 static struct option longopts[] = {{"port", required_argument, 0, 'p'},
456 {"timeout", required_argument, 0, 't'},
457 {"critical", required_argument, 0, 'c'},
458 {"warning", required_argument, 0, 'w'},
459 {"variable", required_argument, 0, 'v'},
460 {"hostname", required_argument, 0, 'H'},
461 {"params", required_argument, 0, 'l'},
462 {"secret", required_argument, 0, 's'},
463 {"display", required_argument, 0, 'd'},
464 {"unknown-timeout", no_argument, 0, 'u'},
465 {"version", no_argument, 0, 'V'},
466 {"help", no_argument, 0, 'h'},
467 {0, 0, 0, 0}};
468
469 check_nt_config_wrapper result = {
470 .errorcode = OK,
471 .config = check_nt_config_init(),
472 };
473
474 /* no options were supplied */
475 if (argc < 2) {
476 result.errorcode = ERROR;
477 return result;
478 }
479
480 /* backwards compatibility */
481 if (!is_option(argv[1])) {
482 result.config.server_address = strdup(argv[1]);
483 argv[1] = argv[0];
484 argv = &argv[1];
485 argc--;
486 }
487
488 for (int index = 1; index < argc; index++) {
489 if (strcmp("-to", argv[index]) == 0) {
490 strcpy(argv[index], "-t");
491 } else if (strcmp("-wv", argv[index]) == 0) {
492 strcpy(argv[index], "-w");
493 } else if (strcmp("-cv", argv[index]) == 0) {
494 strcpy(argv[index], "-c");
495 }
496 }
497
498 int option = 0;
499 while (true) {
500 int option_index = getopt_long(argc, argv, "+hVH:t:c:w:p:v:l:s:d:u", longopts, &option);
501
502 if (option_index == -1 || option_index == EOF || option_index == 1) {
503 break;
504 }
505
506 switch (option_index) {
507 case '?': /* print short usage statement if args not parsable */
508 usage5();
509 case 'h': /* help */
510 print_help();
511 exit(STATE_UNKNOWN);
512 case 'V': /* version */
513 print_revision(progname, NP_VERSION);
514 exit(STATE_UNKNOWN);
515 case 'H': /* hostname */
516 result.config.server_address = optarg;
517 break;
518 case 's': /* password */
519 result.config.req_password = optarg;
520 break;
521 case 'p': /* port */
522 if (is_intnonneg(optarg)) {
523 result.config.server_port = atoi(optarg);
524 } else {
525 die(STATE_UNKNOWN, _("Server port must be an integer\n"));
526 }
527 break;
528 case 'v':
529 if (strlen(optarg) < 4) {
530 result.errorcode = ERROR;
531 return result;
532 }
533 if (!strcmp(optarg, "CLIENTVERSION")) {
534 result.config.vars_to_check = CHECK_CLIENTVERSION;
535 } else if (!strcmp(optarg, "CPULOAD")) {
536 result.config.vars_to_check = CHECK_CPULOAD;
537 } else if (!strcmp(optarg, "UPTIME")) {
538 result.config.vars_to_check = CHECK_UPTIME;
539 } else if (!strcmp(optarg, "USEDDISKSPACE")) {
540 result.config.vars_to_check = CHECK_USEDDISKSPACE;
541 } else if (!strcmp(optarg, "SERVICESTATE")) {
542 result.config.vars_to_check = CHECK_SERVICESTATE;
543 } else if (!strcmp(optarg, "PROCSTATE")) {
544 result.config.vars_to_check = CHECK_PROCSTATE;
545 } else if (!strcmp(optarg, "MEMUSE")) {
546 result.config.vars_to_check = CHECK_MEMUSE;
547 } else if (!strcmp(optarg, "COUNTER")) {
548 result.config.vars_to_check = CHECK_COUNTER;
549 } else if (!strcmp(optarg, "FILEAGE")) {
550 result.config.vars_to_check = CHECK_FILEAGE;
551 } else if (!strcmp(optarg, "INSTANCES")) {
552 result.config.vars_to_check = CHECK_INSTANCES;
553 } else {
554 result.errorcode = ERROR;
555 return result;
556 }
557 break;
558 case 'l': /* value list */
559 result.config.value_list = optarg;
560 break;
561 case 'w': /* warning threshold */
562 result.config.warning_value = strtoul(optarg, NULL, 10);
563 result.config.check_warning_value = true;
564 break;
565 case 'c': /* critical threshold */
566 result.config.critical_value = strtoul(optarg, NULL, 10);
567 result.config.check_critical_value = true;
568 break;
569 case 'd': /* Display select for services */
570 if (!strcmp(optarg, "SHOWALL")) {
571 result.config.show_all = true;
572 }
573 break;
574 case 'u':
575 socket_timeout_state = STATE_UNKNOWN;
576 break;
577 case 't': /* timeout */
578 socket_timeout = atoi(optarg);
579 if (socket_timeout <= 0) {
580 result.errorcode = ERROR;
581 return result;
582 }
583 }
584 }
585 if (result.config.server_address == NULL) {
586 usage4(_("You must provide a server address or host name"));
587 }
588
589 if (result.config.vars_to_check == CHECK_NONE) {
590 result.errorcode = ERROR;
591 return result;
592 }
593
594 if (result.config.req_password == NULL) {
595 result.config.req_password = strdup(_("None"));
596 }
597
598 return result;
599}
600
601void fetch_data(const char *address, int port, const char *sendb) {
602 int result = process_tcp_request(address, port, sendb, recv_buffer, sizeof(recv_buffer));
603
604 if (result != STATE_OK) {
605 die(result, _("could not fetch information from server\n"));
606 }
607
608 if (!strncmp(recv_buffer, "ERROR", 5)) {
609 die(STATE_UNKNOWN, "NSClient - %s\n", recv_buffer);
610 }
611}
612
613bool strtoularray(unsigned long *array, char *string, const char *delim) {
614 /* split a <delim> delimited string into a long array */
615 for (int idx = 0; idx < MAX_VALUE_LIST; idx++) {
616 array[idx] = 0;
617 }
618
619 int idx = 0;
620 for (char *t1 = strtok(string, delim); t1 != NULL; t1 = strtok(NULL, delim)) {
621 if (is_numeric(t1) && idx < MAX_VALUE_LIST) {
622 array[idx] = strtoul(t1, NULL, 10);
623 idx++;
624 } else {
625 return false;
626 }
627 }
628 return true;
629}
630
631void preparelist(char *string) {
632 /* Replace all , with & which is the delimiter for the request */
633 for (int i = 0; (size_t)i < strlen(string); i++) {
634 if (string[i] == ',') {
635 string[i] = '&';
636 }
637 }
638}
639
640void print_help(void) {
641 print_revision(progname, NP_VERSION);
642
643 printf("Copyright (c) 2000 Yves Rubin (rubiyz@yahoo.com)\n");
644 printf(COPYRIGHT, copyright, email);
645
646 printf("%s\n", _("This plugin collects data from the NSClient service running on a"));
647 printf("%s\n", _("Windows NT/2000/XP/2003 server."));
648
649 printf("\n\n");
650
651 print_usage();
652
653 printf(UT_HELP_VRSN);
654 printf(UT_EXTRA_OPTS);
655
656 printf("%s\n", _("Options:"));
657 printf(" %s\n", "-H, --hostname=HOST");
658 printf(" %s\n", _("Name of the host to check"));
659 printf(" %s\n", "-p, --port=INTEGER");
660 printf(" %s", _("Optional port number (default: "));
661 printf("%d)\n", PORT);
662 printf(" %s\n", "-s, --secret=<password>");
663 printf(" %s\n", _("Password needed for the request"));
664 printf(" %s\n", "-w, --warning=INTEGER");
665 printf(" %s\n", _("Threshold which will result in a warning status"));
666 printf(" %s\n", "-c, --critical=INTEGER");
667 printf(" %s\n", _("Threshold which will result in a critical status"));
668 printf(" %s\n", "-t, --timeout=INTEGER");
669 printf(" %s", _("Seconds before connection attempt times out (default: "));
670 printf(" %s\n", "-l, --params=<parameters>");
671 printf(" %s", _("Parameters passed to specified check (see below)"));
672 printf(" %s\n", "-d, --display={SHOWALL}");
673 printf(" %s", _("Display options (currently only SHOWALL works)"));
674 printf(" %s\n", "-u, --unknown-timeout");
675 printf(" %s", _("Return UNKNOWN on timeouts"));
676 printf("%d)\n", DEFAULT_SOCKET_TIMEOUT);
677 printf(" %s\n", "-h, --help");
678 printf(" %s\n", _("Print this help screen"));
679 printf(" %s\n", "-V, --version");
680 printf(" %s\n", _("Print version information"));
681 printf(" %s\n", "-v, --variable=STRING");
682 printf(" %s\n\n", _("Variable to check"));
683 printf("%s\n", _("Valid variables are:"));
684 printf(" %s", "CLIENTVERSION =");
685 printf(" %s\n", _("Get the NSClient version"));
686 printf(" %s\n", _("If -l <version> is specified, will return warning if versions differ."));
687 printf(" %s\n", "CPULOAD =");
688 printf(" %s\n", _("Average CPU load on last x minutes."));
689 printf(" %s\n", _("Request a -l parameter with the following syntax:"));
690 printf(" %s\n", _("-l <minutes range>,<warning threshold>,<critical threshold>."));
691 printf(" %s\n", _("<minute range> should be less than 24*60."));
692 printf(" %s\n", _("Thresholds are percentage and up to 10 requests can be done in one shot."));
693 printf(" %s\n", "ie: -l 60,90,95,120,90,95");
694 printf(" %s\n", "UPTIME =");
695 printf(" %s\n", _("Get the uptime of the machine."));
696 printf(" %s\n", _("-l <unit> "));
697 printf(" %s\n", _("<unit> = seconds, minutes, hours, or days. (default: minutes)"));
698 printf(" %s\n", _("Thresholds will use the unit specified above."));
699 printf(" %s\n", "USEDDISKSPACE =");
700 printf(" %s\n", _("Size and percentage of disk use."));
701 printf(" %s\n", _("Request a -l parameter containing the drive letter only."));
702 printf(" %s\n", _("Warning and critical thresholds can be specified with -w and -c."));
703 printf(" %s\n", "MEMUSE =");
704 printf(" %s\n", _("Memory use."));
705 printf(" %s\n", _("Warning and critical thresholds can be specified with -w and -c."));
706 printf(" %s\n", "SERVICESTATE =");
707 printf(" %s\n", _("Check the state of one or several services."));
708 printf(" %s\n", _("Request a -l parameters with the following syntax:"));
709 printf(" %s\n", _("-l <service1>,<service2>,<service3>,..."));
710 printf(" %s\n", _("You can specify -d SHOWALL in case you want to see working services"));
711 printf(" %s\n", _("in the returned string."));
712 printf(" %s\n", "PROCSTATE =");
713 printf(" %s\n", _("Check if one or several process are running."));
714 printf(" %s\n", _("Same syntax as SERVICESTATE."));
715 printf(" %s\n", "COUNTER =");
716 printf(" %s\n", _("Check any performance counter of Windows NT/2000."));
717 printf(" %s\n", _("Request a -l parameters with the following syntax:"));
718 printf(" %s\n", _("-l \"\\\\<performance object>\\\\counter\",\"<description>"));
719 printf(" %s\n", _("The <description> parameter is optional and is given to a printf "));
720 printf(" %s\n", _("output command which requires a float parameter."));
721 printf(" %s\n", _("If <description> does not include \"%%\", it is used as a label."));
722 printf(" %s\n", _("Some examples:"));
723 printf(" %s\n", "\"Paging file usage is %%.2f %%%%\"");
724 printf(" %s\n", "\"%%.f %%%% paging file used.\"");
725 printf(" %s\n", "INSTANCES =");
726 printf(" %s\n", _("Check any performance counter object of Windows NT/2000."));
727 printf(" %s\n", _("Syntax: check_nt -H <hostname> -p <port> -v INSTANCES -l <counter object>"));
728 printf(" %s\n", _("<counter object> is a Windows Perfmon Counter object (eg. Process),"));
729 printf(" %s\n", _("if it is two words, it should be enclosed in quotes"));
730 printf(" %s\n", _("The returned results will be a comma-separated list of instances on "));
731 printf(" %s\n", _(" the selected computer for that object."));
732 printf(" %s\n", _("The purpose of this is to be run from command line to determine what instances"));
733 printf(" %s\n", _(" are available for monitoring without having to log onto the Windows server"));
734 printf(" %s\n", _(" to run Perfmon directly."));
735 printf(" %s\n", _("It can also be used in scripts that automatically create the monitoring service"));
736 printf(" %s\n", _(" configuration files."));
737 printf(" %s\n", _("Some examples:"));
738 printf(" %s\n\n", _("check_nt -H 192.168.1.1 -p 1248 -v INSTANCES -l Process"));
739
740 printf("%s\n", _("Notes:"));
741 printf(" %s\n", _("- The NSClient service should be running on the server to get any information"));
742 printf(" %s\n", "(http://nsclient.ready2run.nl).");
743 printf(" %s\n", _("- Critical thresholds should be lower than warning thresholds"));
744 printf(" %s\n", _("- Default port 1248 is sometimes in use by other services. The error"));
745 printf(" %s\n", _("output when this happens contains \"Cannot map xxxxx to protocol number\"."));
746 printf(" %s\n", _("One fix for this is to change the port to something else on check_nt "));
747 printf(" %s\n", _("and on the client service it\'s connecting to."));
748
749 printf(UT_SUPPORT);
750}
751
752void print_usage(void) {
753 printf("%s\n", _("Usage:"));
754 printf("%s -H host -v variable [-p port] [-w warning] [-c critical]\n", progname);
755 printf("[-l params] [-d SHOWALL] [-u] [-t timeout]\n");
756}