1 /******************************************************************************
2 *
3 * Program: NetWare statistics plugin for Nagios
4 * License: GPL
5 *
6 * License Information:
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 * $Id$
23 *
24 *****************************************************************************/
26 const char *progname = "check_nwstat";
27 #define REVISION "$Revision$"
28 #define COPYRIGHT "Copyright (c) 1999-2001 Ethan Galstad"
30 #define SUMMARY "\
31 This plugin attempts to contact the MRTGEXT NLM running on a Novell server\n\
32 to gather the requested system information.\n"
34 #define OPTIONS "\
35 -H host [-v variable] [-w warning] [-c critical]\n\
36 [-p port] [-t timeout]"
38 #define LONGOPTIONS "\
39 -H, --hostname=HOST\n\
40 Name of the host to check\n\
41 -v, --variable=STRING\n\
42 Variable to check. Valid variables include:\n\
43 LOAD1 = 1 minute average CPU load\n\
44 LOAD5 = 5 minute average CPU load\n\
45 LOAD15 = 15 minute average CPU load\n\
46 CONNS = number of currently licensed connections\n\
47 VPF<vol> = percent free space on volume <vol>\n\
48 VKF<vol> = KB of free space on volume <vol>\n\
49 LTCH = percent long term cache hits\n\
50 CBUFF = current number of cache buffers\n\
51 CDBUFF = current number of dirty cache buffers\n\
52 LRUM = LRU sitting time in minutes\n\
53 DSDB = check to see if DS Database is open\n\
54 DSVER = NDS version\n\
55 LOGINS = check to see if logins are enabled\n\
56 UPRB = used packet receive buffers\n\
57 PUPRB = percent (of max) used packet receive buffers\n\
58 SAPENTRIES = number of entries in the SAP table\n\
59 SAPENTRIES<n> = number of entries in the SAP table for SAP type <n>\n\
60 OFILES = number of open files\n\
61 VPP<vol> = percent purgeable space on volume <vol>\n\
62 VKP<vol> = KB of purgeable space on volume <vol>\n\
63 VPNP<vol> = percent not yet purgeable space on volume <vol>\n\
64 VKNP<vol> = KB of not yet purgeable space on volume <vol>\n\
65 ABENDS = number of abended threads (NW 5.x only)\n\
66 CSPROCS = number of current service processes (NW 5.x only)\n\
67 TSYNC = timesync status \n\
68 LRUS = LRU sitting time in seconds\n\
69 DCB = dirty cache buffers as a percentage of the total\n\
70 TCB = dirty cache buffers as a percentage of the original\n\
71 UPTIME = server uptime\n\
72 -w, --warning=INTEGER\n\
73 Threshold which will result in a warning status\n\
74 -c, --critical=INTEGER\n\
75 Threshold which will result in a critical status\n\
76 -p, --port=INTEGER\n\
77 Optional port number (default: %d)\n\
78 -t, --timeout=INTEGER\n\
79 Seconds before connection attempt times out (default: %d)\n\
80 -o, --osversion\n\
81 Include server version string in results\n\
82 -h, --help\n\
83 Print this help screen\n\
84 -V, --version\n\
85 Print version information\n"
87 #define DESCRIPTION "\
88 Notes:\n\
89 - This plugin requres that the MRTGEXT.NLM file from James Drews' MRTG\n\
90 extension for NetWare be loaded on the Novell servers you wish to check.\n\
91 (available from http://www.engr.wisc.edu/~drews/mrtg/)\n\
92 - Values for critical thresholds should be lower than warning thresholds\n\
93 when the following variables are checked: VPF, VKF, LTCH, CBUFF, DCB, \n\
94 TCB, LRUS and LRUM.\n"
96 #include "config.h"
97 #include "common.h"
98 #include "netutils.h"
99 #include "utils.h"
101 #define CHECK_NONE 0
102 #define CHECK_LOAD1 1 /* check 1 minute CPU load */
103 #define CHECK_LOAD5 2 /* check 5 minute CPU load */
104 #define CHECK_LOAD15 3 /* check 15 minute CPU load */
105 #define CHECK_CONNS 4 /* check number of connections */
106 #define CHECK_VPF 5 /* check % free space on volume */
107 #define CHECK_VKF 6 /* check KB free space on volume */
108 #define CHECK_LTCH 7 /* check long-term cache hit percentage */
109 #define CHECK_CBUFF 8 /* check total cache buffers */
110 #define CHECK_CDBUFF 9 /* check dirty cache buffers */
111 #define CHECK_LRUM 10 /* check LRU sitting time in minutes */
112 #define CHECK_DSDB 11 /* check to see if DS Database is open */
113 #define CHECK_LOGINS 12 /* check to see if logins are enabled */
114 #define CHECK_PUPRB 13 /* check % of used packet receive buffers */
115 #define CHECK_UPRB 14 /* check used packet receive buffers */
116 #define CHECK_SAPENTRIES 15 /* check SAP entries */
117 #define CHECK_OFILES 16 /* check number of open files */
118 #define CHECK_VKP 17 /* check KB purgeable space on volume */
119 #define CHECK_VPP 18 /* check % purgeable space on volume */
120 #define CHECK_VKNP 19 /* check KB not yet purgeable space on volume */
121 #define CHECK_VPNP 20 /* check % not yet purgeable space on volume */
122 #define CHECK_ABENDS 21 /* check abended thread count */
123 #define CHECK_CSPROCS 22 /* check number of current service processes */
124 #define CHECK_TSYNC 23 /* check timesync status 0=no 1=yes in sync to the network */
125 #define CHECK_LRUS 24 /* check LRU sitting time in seconds */
126 #define CHECK_DCB 25 /* check dirty cache buffers as a percentage of the total */
127 #define CHECK_TCB 26 /* check total cache buffers as a percentage of the original */
128 #define CHECK_DSVER 27 /* check NDS version */
129 #define CHECK_UPTIME 28 /* check server uptime */
131 #define PORT 9999
133 char *server_address=NULL;
134 char *volume_name=NULL;
135 int server_port=PORT;
136 unsigned long warning_value=0L;
137 unsigned long critical_value=0L;
138 int check_warning_value=FALSE;
139 int check_critical_value=FALSE;
140 int check_netware_version=FALSE;
141 unsigned long vars_to_check=CHECK_NONE;
142 int sap_number=-1;
144 int process_arguments(int, char **);
145 void print_usage(void);
146 void print_help(void);
148 int main(int argc, char **argv){
149 int result;
150 char *send_buffer=NULL;
151 char recv_buffer[MAX_INPUT_BUFFER];
152 char *output_message=NULL;
153 char *temp_buffer=NULL;
154 char *netware_version=NULL;
156 int total_cache_buffers=0;
157 int dirty_cache_buffers=0;
158 int time_sync_status=0;
159 int open_files=0;
160 int abended_threads=0;
161 int max_service_processes=0;
162 int current_service_processes=0;
163 unsigned long free_disk_space=0L;
164 unsigned long total_disk_space=0L;
165 unsigned long purgeable_disk_space=0L;
166 unsigned long non_purgeable_disk_space=0L;
167 int percent_free_space=0;
168 int percent_purgeable_space=0;
169 int percent_non_purgeable_space=0;
170 unsigned long current_connections=0L;
171 unsigned long utilization=0L;
172 int cache_hits=0;
173 unsigned long cache_buffers=0L;
174 unsigned long lru_time=0L;
175 char uptime[MAX_INPUT_BUFFER];
176 int max_packet_receive_buffers=0;
177 int used_packet_receive_buffers=0;
178 unsigned long percent_used_packet_receive_buffers=0L;
179 int sap_entries=0;
181 if(process_arguments(argc,argv)==ERROR)
182 usage("Could not parse arguments\n");
184 /* initialize alarm signal handling */
185 signal(SIGALRM,socket_timeout_alarm_handler);
187 /* set socket timeout */
188 alarm(socket_timeout);
190 /* get OS version string */
191 if (check_netware_version==TRUE) {
192 send_buffer = strscpy(send_buffer,"S19\r\n");
193 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
194 if(result!=STATE_OK)
195 return result;
196 if(!strcmp(recv_buffer,"-1\n"))
197 asprintf(&netware_version,"");
198 else {
199 recv_buffer[strlen(recv_buffer)-1]=0;
200 asprintf(&netware_version,"NetWare %s: ",recv_buffer);
201 }
202 } else
203 asprintf(&netware_version,"");
206 /* check CPU load */
207 if (vars_to_check==CHECK_LOAD1 || vars_to_check==CHECK_LOAD5 || vars_to_check==CHECK_LOAD15) {
209 switch(vars_to_check){
210 case CHECK_LOAD1:
211 temp_buffer = strscpy(temp_buffer,"1");
212 break;
213 case CHECK_LOAD5:
214 temp_buffer = strscpy(temp_buffer,"5");
215 break;
216 default:
217 temp_buffer = strscpy(temp_buffer,"15");
218 break;
219 }
221 asprintf(&send_buffer,"UTIL%s\r\n",temp_buffer);
222 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
223 if(result!=STATE_OK)
224 return result;
225 utilization=strtoul(recv_buffer,NULL,10);
226 send_buffer = strscpy(send_buffer,"UPTIME\r\n");
227 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
228 if(result!=STATE_OK)
229 return result;
230 recv_buffer[strlen(recv_buffer)-1]=0;
231 sprintf(uptime,"Up %s,",recv_buffer);
233 if(check_critical_value==TRUE && utilization >= critical_value)
234 result=STATE_CRITICAL;
235 else if(check_warning_value==TRUE && utilization >= warning_value)
236 result=STATE_WARNING;
238 asprintf(&output_message,"Load %s - %s %s-min load average = %lu%%",(result==STATE_OK)?"ok":"problem",uptime,temp_buffer,utilization);
240 /* check number of user connections */
241 } else if (vars_to_check==CHECK_CONNS) {
243 send_buffer = strscpy(send_buffer,"CONNECT\r\n");
244 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
245 if(result!=STATE_OK)
246 return result;
247 current_connections=strtoul(recv_buffer,NULL,10);
249 if(check_critical_value==TRUE && current_connections >= critical_value)
250 result=STATE_CRITICAL;
251 else if(check_warning_value==TRUE && current_connections >= warning_value)
252 result=STATE_WARNING;
253 asprintf(&output_message,"Conns %s - %lu current connections",(result==STATE_OK)?"ok":"problem",current_connections);
255 /* check % long term cache hits */
256 } else if (vars_to_check==CHECK_LTCH) {
258 send_buffer = strscpy(send_buffer,"S1\r\n");
259 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
260 if(result!=STATE_OK)
261 return result;
262 cache_hits=atoi(recv_buffer);
264 if(check_critical_value==TRUE && cache_hits <= critical_value)
265 result=STATE_CRITICAL;
266 else if(check_warning_value==TRUE && cache_hits <= warning_value)
267 result=STATE_WARNING;
268 asprintf(&output_message,"Long term cache hits = %d%%",cache_hits);
270 /* check cache buffers */
271 } else if (vars_to_check==CHECK_CBUFF) {
273 send_buffer = strscpy(send_buffer,"S2\r\n");
274 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
275 if(result!=STATE_OK)
276 return result;
277 cache_buffers=strtoul(recv_buffer,NULL,10);
279 if(check_critical_value==TRUE && cache_buffers <= critical_value)
280 result=STATE_CRITICAL;
281 else if(check_warning_value==TRUE && cache_buffers <= warning_value)
282 result=STATE_WARNING;
283 asprintf(&output_message,"Total cache buffers = %lu",cache_buffers);
285 /* check dirty cache buffers */
286 } else if (vars_to_check==CHECK_CDBUFF) {
288 send_buffer = strscpy(send_buffer,"S3\r\n");
289 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
290 if(result!=STATE_OK)
291 return result;
292 cache_buffers=strtoul(recv_buffer,NULL,10);
294 if(check_critical_value==TRUE && cache_buffers >= critical_value)
295 result=STATE_CRITICAL;
296 else if(check_warning_value==TRUE && cache_buffers >= warning_value)
297 result=STATE_WARNING;
298 asprintf(&output_message,"Dirty cache buffers = %lu",cache_buffers);
300 /* check LRU sitting time in minutes */
301 } else if (vars_to_check==CHECK_LRUM) {
303 send_buffer = strscpy(send_buffer,"S5\r\n");
304 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
305 if(result!=STATE_OK)
306 return result;
307 lru_time=strtoul(recv_buffer,NULL,10);
309 if(check_critical_value==TRUE && lru_time <= critical_value)
310 result=STATE_CRITICAL;
311 else if(check_warning_value==TRUE && lru_time <= warning_value)
312 result=STATE_WARNING;
313 asprintf(&output_message,"LRU sitting time = %lu minutes",lru_time);
316 /* check KB free space on volume */
317 } else if (vars_to_check==CHECK_VKF) {
319 asprintf(&send_buffer,"VKF%s\r\n",volume_name);
320 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
321 if(result!=STATE_OK)
322 return result;
324 if (!strcmp(recv_buffer,"-1\n")) {
325 asprintf(&output_message,"Error: Volume '%s' does not exist!",volume_name);
326 result=STATE_CRITICAL;
327 } else {
328 free_disk_space=strtoul(recv_buffer,NULL,10);
329 if(check_critical_value==TRUE && free_disk_space <= critical_value)
330 result=STATE_CRITICAL;
331 else if(check_warning_value==TRUE && free_disk_space <= warning_value)
332 result=STATE_WARNING;
333 asprintf(&output_message,"%s%lu KB free on volume %s",(result==STATE_OK)?"":"Only ",free_disk_space,volume_name);
334 }
336 /* check % free space on volume */
337 } else if (vars_to_check==CHECK_VPF) {
339 asprintf(&send_buffer,"VKF%s\r\n",volume_name);
340 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
341 if(result!=STATE_OK)
342 return result;
344 if(!strcmp(recv_buffer,"-1\n")){
346 asprintf(&output_message,"Error: Volume '%s' does not exist!",volume_name);
347 result=STATE_CRITICAL;
349 } else {
351 free_disk_space=strtoul(recv_buffer,NULL,10);
353 asprintf(&send_buffer,"VKS%s\r\n",volume_name);
354 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
355 if(result!=STATE_OK)
356 return result;
357 total_disk_space=strtoul(recv_buffer,NULL,10);
359 percent_free_space=(int)(((double)free_disk_space/(double)total_disk_space)*100.0);
361 if(check_critical_value==TRUE && percent_free_space <= critical_value)
362 result=STATE_CRITICAL;
363 else if(check_warning_value==TRUE && percent_free_space <= warning_value)
364 result=STATE_WARNING;
365 free_disk_space/=1024;
366 asprintf(&output_message,"%lu MB (%d%%) free on volume %s",free_disk_space,percent_free_space,volume_name);
367 }
369 /* check to see if DS Database is open or closed */
370 } else if(vars_to_check==CHECK_DSDB) {
372 send_buffer = strscpy(send_buffer,"S11\r\n");
373 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
374 if(result!=STATE_OK)
375 return result;
376 if(atoi(recv_buffer)==1)
377 result=STATE_OK;
378 else
379 result=STATE_WARNING;
381 send_buffer = strscpy(send_buffer,"S13\r\n");
382 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
383 temp_buffer=strtok(recv_buffer,"\r\n");
385 asprintf(&output_message,"Directory Services Database is %s (DS version %s)",(result==STATE_OK)?"open":"closed",temp_buffer);
387 /* check to see if logins are enabled */
388 } else if (vars_to_check==CHECK_LOGINS) {
390 send_buffer = strscpy(send_buffer,"S12\r\n");
391 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
392 if(result!=STATE_OK)
393 return result;
394 if(atoi(recv_buffer)==1)
395 result=STATE_OK;
396 else
397 result=STATE_WARNING;
399 asprintf(&output_message,"Logins are %s",(result==STATE_OK)?"enabled":"disabled");
401 /* check packet receive buffers */
402 } else if (vars_to_check==CHECK_UPRB || vars_to_check==CHECK_PUPRB) {
404 asprintf(&send_buffer,"S15\r\n",volume_name);
405 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
406 if(result!=STATE_OK)
407 return result;
409 used_packet_receive_buffers=atoi(recv_buffer);
411 asprintf(&send_buffer,"S16\r\n",volume_name);
412 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
413 if(result!=STATE_OK)
414 return result;
416 max_packet_receive_buffers=atoi(recv_buffer);
418 percent_used_packet_receive_buffers=(unsigned long)(((double)used_packet_receive_buffers/(double)max_packet_receive_buffers)*100.0);
420 if(vars_to_check==CHECK_UPRB){
421 if(check_critical_value==TRUE && used_packet_receive_buffers >= critical_value)
422 result=STATE_CRITICAL;
423 else if(check_warning_value==TRUE && used_packet_receive_buffers >= warning_value)
424 result=STATE_WARNING;
425 } else {
426 if(check_critical_value==TRUE && percent_used_packet_receive_buffers >= critical_value)
427 result=STATE_CRITICAL;
428 else if(check_warning_value==TRUE && percent_used_packet_receive_buffers >= warning_value)
429 result=STATE_WARNING;
430 }
432 asprintf(&output_message,"%d of %d (%lu%%) packet receive buffers used",used_packet_receive_buffers,max_packet_receive_buffers,percent_used_packet_receive_buffers);
434 /* check SAP table entries */
435 } else if (vars_to_check==CHECK_SAPENTRIES) {
437 if(sap_number==-1)
438 asprintf(&send_buffer,"S9\r\n");
439 else
440 asprintf(&send_buffer,"S9.%d\r\n",sap_number);
441 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
442 if(result!=STATE_OK)
443 return result;
445 sap_entries=atoi(recv_buffer);
447 if(check_critical_value==TRUE && sap_entries >= critical_value)
448 result=STATE_CRITICAL;
449 else if(check_warning_value==TRUE && sap_entries >= warning_value)
450 result=STATE_WARNING;
452 if(sap_number==-1)
453 asprintf(&output_message,"%d entries in SAP table",sap_entries);
454 else
455 asprintf(&output_message,"%d entries in SAP table for SAP type %d",sap_entries,sap_number);
457 /* check KB purgeable space on volume */
458 } else if (vars_to_check==CHECK_VKP) {
460 asprintf(&send_buffer,"VKP%s\r\n",volume_name);
461 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
462 if(result!=STATE_OK)
463 return result;
465 if (!strcmp(recv_buffer,"-1\n")) {
466 asprintf(&output_message,"Error: Volume '%s' does not exist!",volume_name);
467 result=STATE_CRITICAL;
468 } else {
469 purgeable_disk_space=strtoul(recv_buffer,NULL,10);
470 if(check_critical_value==TRUE && purgeable_disk_space >= critical_value)
471 result=STATE_CRITICAL;
472 else if(check_warning_value==TRUE && purgeable_disk_space >= warning_value)
473 result=STATE_WARNING;
474 asprintf(&output_message,"%s%lu KB purgeable on volume %s",(result==STATE_OK)?"":"Only ",purgeable_disk_space,volume_name);
475 }
477 /* check % purgeable space on volume */
478 } else if (vars_to_check==CHECK_VPP) {
480 asprintf(&send_buffer,"VKP%s\r\n",volume_name);
481 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
482 if(result!=STATE_OK)
483 return result;
485 if(!strcmp(recv_buffer,"-1\n")){
487 asprintf(&output_message,"Error: Volume '%s' does not exist!",volume_name);
488 result=STATE_CRITICAL;
490 } else {
492 purgeable_disk_space=strtoul(recv_buffer,NULL,10);
494 asprintf(&send_buffer,"VKS%s\r\n",volume_name);
495 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
496 if(result!=STATE_OK)
497 return result;
498 total_disk_space=strtoul(recv_buffer,NULL,10);
500 percent_purgeable_space=(int)(((double)purgeable_disk_space/(double)total_disk_space)*100.0);
502 if(check_critical_value==TRUE && percent_purgeable_space >= critical_value)
503 result=STATE_CRITICAL;
504 else if(check_warning_value==TRUE && percent_purgeable_space >= warning_value)
505 result=STATE_WARNING;
506 purgeable_disk_space/=1024;
507 asprintf(&output_message,"%lu MB (%d%%) purgeable on volume %s",purgeable_disk_space,percent_purgeable_space,volume_name);
508 }
510 /* check KB not yet purgeable space on volume */
511 } else if (vars_to_check==CHECK_VKNP) {
513 asprintf(&send_buffer,"VKNP%s\r\n",volume_name);
514 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
515 if(result!=STATE_OK)
516 return result;
518 if (!strcmp(recv_buffer,"-1\n")) {
519 asprintf(&output_message,"Error: Volume '%s' does not exist!",volume_name);
520 result=STATE_CRITICAL;
521 } else {
522 non_purgeable_disk_space=strtoul(recv_buffer,NULL,10);
523 if(check_critical_value==TRUE && non_purgeable_disk_space >= critical_value)
524 result=STATE_CRITICAL;
525 else if(check_warning_value==TRUE && non_purgeable_disk_space >= warning_value)
526 result=STATE_WARNING;
527 asprintf(&output_message,"%s%lu KB not yet purgeable on volume %s",(result==STATE_OK)?"":"Only ",non_purgeable_disk_space,volume_name);
528 }
530 /* check % not yet purgeable space on volume */
531 } else if (vars_to_check==CHECK_VPNP) {
533 asprintf(&send_buffer,"VKNP%s\r\n",volume_name);
534 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
535 if(result!=STATE_OK)
536 return result;
538 if(!strcmp(recv_buffer,"-1\n")){
540 asprintf(&output_message,"Error: Volume '%s' does not exist!",volume_name);
541 result=STATE_CRITICAL;
543 } else {
545 non_purgeable_disk_space=strtoul(recv_buffer,NULL,10);
547 asprintf(&send_buffer,"VKS%s\r\n",volume_name);
548 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
549 if(result!=STATE_OK)
550 return result;
551 total_disk_space=strtoul(recv_buffer,NULL,10);
553 percent_non_purgeable_space=(int)(((double)non_purgeable_disk_space/(double)total_disk_space)*100.0);
555 if(check_critical_value==TRUE && percent_non_purgeable_space >= critical_value)
556 result=STATE_CRITICAL;
557 else if(check_warning_value==TRUE && percent_non_purgeable_space >= warning_value)
558 result=STATE_WARNING;
559 purgeable_disk_space/=1024;
560 asprintf(&output_message,"%lu MB (%d%%) not yet purgeable on volume %s",non_purgeable_disk_space,percent_non_purgeable_space,volume_name);
561 }
563 /* check # of open files */
564 } else if (vars_to_check==CHECK_OFILES) {
566 asprintf(&send_buffer,"S18\r\n");
567 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
568 if(result!=STATE_OK)
569 return result;
571 open_files=atoi(recv_buffer);
573 if(check_critical_value==TRUE && open_files >= critical_value)
574 result=STATE_CRITICAL;
575 else if(check_warning_value==TRUE && open_files >= warning_value)
576 result=STATE_WARNING;
578 asprintf(&output_message,"%d open files",open_files);
580 /* check # of abended threads (Netware 5.x only) */
581 } else if (vars_to_check==CHECK_ABENDS) {
583 asprintf(&send_buffer,"S17\r\n");
584 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
585 if(result!=STATE_OK)
586 return result;
588 abended_threads=atoi(recv_buffer);
590 if(check_critical_value==TRUE && abended_threads >= critical_value)
591 result=STATE_CRITICAL;
592 else if(check_warning_value==TRUE && abended_threads >= warning_value)
593 result=STATE_WARNING;
595 asprintf(&output_message,"%d abended threads",abended_threads);
597 /* check # of current service processes (Netware 5.x only) */
598 } else if (vars_to_check==CHECK_CSPROCS) {
600 asprintf(&send_buffer,"S20\r\n");
601 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
602 if(result!=STATE_OK)
603 return result;
605 max_service_processes=atoi(recv_buffer);
607 asprintf(&send_buffer,"S21\r\n");
608 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
609 if(result!=STATE_OK)
610 return result;
612 current_service_processes=atoi(recv_buffer);
614 if(check_critical_value==TRUE && current_service_processes >= critical_value)
615 result=STATE_CRITICAL;
616 else if(check_warning_value==TRUE && current_service_processes >= warning_value)
617 result=STATE_WARNING;
619 asprintf(&output_message,"%d current service processes (%d max)",current_service_processes,max_service_processes);
621 /* check # Timesync Status */
622 } else if (vars_to_check==CHECK_TSYNC) {
624 asprintf(&send_buffer,"S22\r\n");
625 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
626 if(result!=STATE_OK)
627 return result;
629 time_sync_status=atoi(recv_buffer);
631 if(time_sync_status==0) {
632 result=STATE_CRITICAL;
633 asprintf(&output_message,"Critical: Time not in sync with network!");
634 }
635 else {
636 asprintf(&output_message,"OK! Time in sync with network!");
637 }
639 /* check LRU sitting time in secondss */
640 } else if (vars_to_check==CHECK_LRUS) {
642 send_buffer = strscpy(send_buffer,"S4\r\n");
643 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
644 if(result!=STATE_OK)
645 return result;
646 lru_time=strtoul(recv_buffer,NULL,10);
648 if(check_critical_value==TRUE && lru_time <= critical_value)
649 result=STATE_CRITICAL;
650 else if(check_warning_value==TRUE && lru_time <= warning_value)
651 result=STATE_WARNING;
652 asprintf(&output_message,"LRU sitting time = %lu seconds",lru_time);
655 /* check % dirty cache buffers as a percentage of the total*/
656 } else if (vars_to_check==CHECK_DCB) {
658 send_buffer = strscpy(send_buffer,"S6\r\n");
659 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
660 if(result!=STATE_OK)
661 return result;
662 dirty_cache_buffers=atoi(recv_buffer);
664 if(check_critical_value==TRUE && dirty_cache_buffers <= critical_value)
665 result=STATE_CRITICAL;
666 else if(check_warning_value==TRUE && dirty_cache_buffers <= warning_value)
667 result=STATE_WARNING;
668 asprintf(&output_message,"dirty cache buffers = %d%% of the total",dirty_cache_buffers);
670 /* check % total cache buffers as a percentage of the original*/
671 } else if (vars_to_check==CHECK_TCB) {
673 send_buffer = strscpy(send_buffer,"S7\r\n");
674 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
675 if(result!=STATE_OK)
676 return result;
677 total_cache_buffers=atoi(recv_buffer);
679 if(check_critical_value==TRUE && total_cache_buffers <= critical_value)
680 result=STATE_CRITICAL;
681 else if(check_warning_value==TRUE && total_cache_buffers <= warning_value)
682 result=STATE_WARNING;
683 asprintf(&output_message,"total cache buffers = %d%% of the original",total_cache_buffers);
685 } else if (vars_to_check==CHECK_DSVER) {
686 asprintf(&send_buffer,"S13\r\n");
687 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
688 if(result!=STATE_OK)
689 return result;
691 recv_buffer[strlen(recv_buffer)-1]=0;
693 asprintf(&output_message,"NDS Version %s",recv_buffer);
695 } else if (vars_to_check==CHECK_UPTIME) {
696 asprintf(&send_buffer,"UPTIME\r\n");
697 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
698 if(result!=STATE_OK)
699 return result;
701 recv_buffer[strlen(recv_buffer)-1]=0;
703 asprintf(&output_message,"Up %s",recv_buffer);
705 } else {
707 output_message = strscpy(output_message,"Nothing to check!\n");
708 result=STATE_UNKNOWN;
710 }
712 /* reset timeout */
713 alarm(0);
715 printf("%s%s\n",netware_version,output_message);
717 return result;
718 }
721 /* process command-line arguments */
722 int process_arguments(int argc, char **argv){
723 int c;
725 int option_index = 0;
726 static struct option long_options[] =
727 {
728 {"port", required_argument,0,'p'},
729 {"timeout", required_argument,0,'t'},
730 {"critical", required_argument,0,'c'},
731 {"warning", required_argument,0,'w'},
732 {"variable", required_argument,0,'v'},
733 {"hostname", required_argument,0,'H'},
734 {"osversion",no_argument, 0,'o'},
735 {"version", no_argument, 0,'V'},
736 {"help", no_argument, 0,'h'},
737 {0,0,0,0}
738 };
740 /* no options were supplied */
741 if(argc<2) return ERROR;
743 /* backwards compatibility */
744 if (! is_option(argv[1])) {
745 server_address=argv[1];
746 argv[1]=argv[0];
747 argv=&argv[1];
748 argc--;
749 }
751 for (c=1;c<argc;c++) {
752 if(strcmp("-to",argv[c])==0)
753 strcpy(argv[c],"-t");
754 else if (strcmp("-wv",argv[c])==0)
755 strcpy(argv[c],"-w");
756 else if (strcmp("-cv",argv[c])==0)
757 strcpy(argv[c],"-c");
758 }
760 while (1){
761 c = getopt_long(argc,argv,"+hoVH:t:c:w:p:v:",long_options,&option_index);
763 if (c==-1||c==EOF||c==1)
764 break;
766 switch (c)
767 {
768 case '?': /* print short usage statement if args not parsable */
769 printf ("%s: Unknown argument: %s\n\n", progname, optarg);
770 print_usage();
771 exit(STATE_UNKNOWN);
772 case 'h': /* help */
773 print_help();
774 exit(STATE_OK);
775 case 'V': /* version */
776 print_revision(progname,"$Revision$");
777 exit(STATE_OK);
778 case 'H': /* hostname */
779 server_address=optarg;
780 break;
781 case 'o': /* display nos version */
782 check_netware_version=TRUE;
783 break;
784 case 'p': /* port */
785 if (is_intnonneg(optarg))
786 server_port=atoi(optarg);
787 else
788 terminate(STATE_UNKNOWN,"Server port an integer (seconds)\nType '%s -h' for additional help\n",progname);
789 break;
790 case 'v':
791 if(strlen(optarg)<3)
792 return ERROR;
793 if(!strcmp(optarg,"LOAD1"))
794 vars_to_check=CHECK_LOAD1;
795 else if(!strcmp(optarg,"LOAD5"))
796 vars_to_check=CHECK_LOAD5;
797 else if(!strcmp(optarg,"LOAD15"))
798 vars_to_check=CHECK_LOAD15;
799 else if(!strcmp(optarg,"CONNS"))
800 vars_to_check=CHECK_CONNS;
801 else if(!strcmp(optarg,"LTCH"))
802 vars_to_check=CHECK_LTCH;
803 else if(!strcmp(optarg,"DCB"))
804 vars_to_check=CHECK_DCB;
805 else if(!strcmp(optarg,"TCB"))
806 vars_to_check=CHECK_TCB;
807 else if(!strcmp(optarg,"CBUFF"))
808 vars_to_check=CHECK_CBUFF;
809 else if(!strcmp(optarg,"CDBUFF"))
810 vars_to_check=CHECK_CDBUFF;
811 else if(!strcmp(optarg,"LRUM"))
812 vars_to_check=CHECK_LRUM;
813 else if(!strcmp(optarg,"LRUS"))
814 vars_to_check=CHECK_LRUS;
815 else if(strncmp(optarg,"VPF",3)==0){
816 vars_to_check=CHECK_VPF;
817 volume_name = strscpy(volume_name,optarg+3);
818 if(!strcmp(volume_name,""))
819 volume_name = strscpy(volume_name,"SYS");
820 }
821 else if(strncmp(optarg,"VKF",3)==0){
822 vars_to_check=CHECK_VKF;
823 volume_name = strscpy(volume_name,optarg+3);
824 if(!strcmp(volume_name,""))
825 volume_name = strscpy(volume_name,"SYS");
826 }
827 else if(!strcmp(optarg,"DSDB"))
828 vars_to_check=CHECK_DSDB;
829 else if(!strcmp(optarg,"LOGINS"))
830 vars_to_check=CHECK_LOGINS;
831 else if(!strcmp(optarg,"UPRB"))
832 vars_to_check=CHECK_UPRB;
833 else if(!strcmp(optarg,"PUPRB"))
834 vars_to_check=CHECK_PUPRB;
835 else if(!strncmp(optarg,"SAPENTRIES",10)){
836 vars_to_check=CHECK_SAPENTRIES;
837 if(strlen(optarg)>10)
838 sap_number=atoi(optarg+10);
839 else
840 sap_number=-1;
841 }
842 else if(!strcmp(optarg,"OFILES"))
843 vars_to_check=CHECK_OFILES;
844 else if(strncmp(optarg,"VKP",3)==0){
845 vars_to_check=CHECK_VKP;
846 volume_name = strscpy(volume_name,optarg+3);
847 if(!strcmp(volume_name,""))
848 volume_name = strscpy(volume_name,"SYS");
849 }
850 else if(strncmp(optarg,"VPP",3)==0){
851 vars_to_check=CHECK_VPP;
852 volume_name = strscpy(volume_name,optarg+3);
853 if(!strcmp(volume_name,""))
854 volume_name = strscpy(volume_name,"SYS");
855 }
856 else if(strncmp(optarg,"VKNP",4)==0){
857 vars_to_check=CHECK_VKNP;
858 volume_name = strscpy(volume_name,optarg+4);
859 if(!strcmp(volume_name,""))
860 volume_name = strscpy(volume_name,"SYS");
861 }
862 else if(strncmp(optarg,"VPNP",4)==0){
863 vars_to_check=CHECK_VPNP;
864 volume_name = strscpy(volume_name,optarg+4);
865 if(!strcmp(volume_name,""))
866 volume_name = strscpy(volume_name,"SYS");
867 }
868 else if(!strcmp(optarg,"ABENDS"))
869 vars_to_check=CHECK_ABENDS;
870 else if(!strcmp(optarg,"CSPROCS"))
871 vars_to_check=CHECK_CSPROCS;
872 else if(!strcmp(optarg,"TSYNC"))
873 vars_to_check=CHECK_TSYNC;
874 else if(!strcmp(optarg,"DSVER"))
875 vars_to_check=CHECK_DSVER;
876 else if(!strcmp(optarg,"UPTIME"))
877 vars_to_check=CHECK_UPTIME;
878 else
879 return ERROR;
880 break;
881 case 'w': /* warning threshold */
882 warning_value=strtoul(optarg,NULL,10);
883 check_warning_value=TRUE;
884 break;
885 case 'c': /* critical threshold */
886 critical_value=strtoul(optarg,NULL,10);
887 check_critical_value=TRUE;
888 break;
889 case 't': /* timeout */
890 socket_timeout=atoi(optarg);
891 if(socket_timeout<=0)
892 return ERROR;
893 }
895 }
897 return OK;
898 }
901 void print_usage(void)
902 {
903 printf
904 ("Usage:\n"
905 " %s %s\n"
906 " %s (-h | --help) for detailed help\n"
907 " %s (-V | --version) for version information\n",
908 progname, OPTIONS, progname, progname);
909 }
911 void print_help(void)
912 {
913 print_revision (progname, REVISION);
914 printf ("%s\n\n%s\n", COPYRIGHT, SUMMARY);
915 print_usage();
916 printf
917 ("\nOptions:\n" LONGOPTIONS "\n" DESCRIPTION "\n",
918 PORT, DEFAULT_SOCKET_TIMEOUT);
919 support ();
920 }