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 NLM:<nlm> = check if NLM is loaded and report version (e.g. \"NLM:TSANDS.NLM\")\n\
73 -w, --warning=INTEGER\n\
74 Threshold which will result in a warning status\n\
75 -c, --critical=INTEGER\n\
76 Threshold which will result in a critical status\n\
77 -p, --port=INTEGER\n\
78 Optional port number (default: %d)\n\
79 -t, --timeout=INTEGER\n\
80 Seconds before connection attempt times out (default: %d)\n\
81 -o, --osversion\n\
82 Include server version string in results\n\
83 -h, --help\n\
84 Print this help screen\n\
85 -V, --version\n\
86 Print version information\n"
88 #define DESCRIPTION "\
89 Notes:\n\
90 - This plugin requres that the MRTGEXT.NLM file from James Drews' MRTG\n\
91 extension for NetWare be loaded on the Novell servers you wish to check.\n\
92 (available from http://www.engr.wisc.edu/~drews/mrtg/)\n\
93 - Values for critical thresholds should be lower than warning thresholds\n\
94 when the following variables are checked: VPF, VKF, LTCH, CBUFF, DCB, \n\
95 TCB, LRUS and LRUM.\n"
97 #include "config.h"
98 #include "common.h"
99 #include "netutils.h"
100 #include "utils.h"
102 #define CHECK_NONE 0
103 #define CHECK_LOAD1 1 /* check 1 minute CPU load */
104 #define CHECK_LOAD5 2 /* check 5 minute CPU load */
105 #define CHECK_LOAD15 3 /* check 15 minute CPU load */
106 #define CHECK_CONNS 4 /* check number of connections */
107 #define CHECK_VPF 5 /* check % free space on volume */
108 #define CHECK_VKF 6 /* check KB free space on volume */
109 #define CHECK_LTCH 7 /* check long-term cache hit percentage */
110 #define CHECK_CBUFF 8 /* check total cache buffers */
111 #define CHECK_CDBUFF 9 /* check dirty cache buffers */
112 #define CHECK_LRUM 10 /* check LRU sitting time in minutes */
113 #define CHECK_DSDB 11 /* check to see if DS Database is open */
114 #define CHECK_LOGINS 12 /* check to see if logins are enabled */
115 #define CHECK_PUPRB 13 /* check % of used packet receive buffers */
116 #define CHECK_UPRB 14 /* check used packet receive buffers */
117 #define CHECK_SAPENTRIES 15 /* check SAP entries */
118 #define CHECK_OFILES 16 /* check number of open files */
119 #define CHECK_VKP 17 /* check KB purgeable space on volume */
120 #define CHECK_VPP 18 /* check % purgeable space on volume */
121 #define CHECK_VKNP 19 /* check KB not yet purgeable space on volume */
122 #define CHECK_VPNP 20 /* check % not yet purgeable space on volume */
123 #define CHECK_ABENDS 21 /* check abended thread count */
124 #define CHECK_CSPROCS 22 /* check number of current service processes */
125 #define CHECK_TSYNC 23 /* check timesync status 0=no 1=yes in sync to the network */
126 #define CHECK_LRUS 24 /* check LRU sitting time in seconds */
127 #define CHECK_DCB 25 /* check dirty cache buffers as a percentage of the total */
128 #define CHECK_TCB 26 /* check total cache buffers as a percentage of the original */
129 #define CHECK_DSVER 27 /* check NDS version */
130 #define CHECK_UPTIME 28 /* check server uptime */
131 #define CHECK_NLM 29 /* check NLM loaded */
133 #define PORT 9999
135 char *server_address=NULL;
136 char *volume_name=NULL;
137 char *nlm_name=NULL;
138 int server_port=PORT;
139 unsigned long warning_value=0L;
140 unsigned long critical_value=0L;
141 int check_warning_value=FALSE;
142 int check_critical_value=FALSE;
143 int check_netware_version=FALSE;
144 unsigned long vars_to_check=CHECK_NONE;
145 int sap_number=-1;
147 int process_arguments(int, char **);
148 void print_usage(void);
149 void print_help(void);
151 int main(int argc, char **argv){
152 int result;
153 char *send_buffer=NULL;
154 char recv_buffer[MAX_INPUT_BUFFER];
155 char *output_message=NULL;
156 char *temp_buffer=NULL;
157 char *netware_version=NULL;
159 int total_cache_buffers=0;
160 int dirty_cache_buffers=0;
161 int time_sync_status=0;
162 int open_files=0;
163 int abended_threads=0;
164 int max_service_processes=0;
165 int current_service_processes=0;
166 unsigned long free_disk_space=0L;
167 unsigned long total_disk_space=0L;
168 unsigned long purgeable_disk_space=0L;
169 unsigned long non_purgeable_disk_space=0L;
170 int percent_free_space=0;
171 int percent_purgeable_space=0;
172 int percent_non_purgeable_space=0;
173 unsigned long current_connections=0L;
174 unsigned long utilization=0L;
175 int cache_hits=0;
176 unsigned long cache_buffers=0L;
177 unsigned long lru_time=0L;
178 char uptime[MAX_INPUT_BUFFER];
179 int max_packet_receive_buffers=0;
180 int used_packet_receive_buffers=0;
181 unsigned long percent_used_packet_receive_buffers=0L;
182 int sap_entries=0;
184 if(process_arguments(argc,argv)==ERROR)
185 usage("Could not parse arguments\n");
187 /* initialize alarm signal handling */
188 signal(SIGALRM,socket_timeout_alarm_handler);
190 /* set socket timeout */
191 alarm(socket_timeout);
193 /* get OS version string */
194 if (check_netware_version==TRUE) {
195 send_buffer = strscpy(send_buffer,"S19\r\n");
196 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
197 if(result!=STATE_OK)
198 return result;
199 if(!strcmp(recv_buffer,"-1\n"))
200 asprintf(&netware_version,"");
201 else {
202 recv_buffer[strlen(recv_buffer)-1]=0;
203 asprintf(&netware_version,"NetWare %s: ",recv_buffer);
204 }
205 } else
206 asprintf(&netware_version,"");
209 /* check CPU load */
210 if (vars_to_check==CHECK_LOAD1 || vars_to_check==CHECK_LOAD5 || vars_to_check==CHECK_LOAD15) {
212 switch(vars_to_check){
213 case CHECK_LOAD1:
214 temp_buffer = strscpy(temp_buffer,"1");
215 break;
216 case CHECK_LOAD5:
217 temp_buffer = strscpy(temp_buffer,"5");
218 break;
219 default:
220 temp_buffer = strscpy(temp_buffer,"15");
221 break;
222 }
224 asprintf(&send_buffer,"UTIL%s\r\n",temp_buffer);
225 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
226 if(result!=STATE_OK)
227 return result;
228 utilization=strtoul(recv_buffer,NULL,10);
229 send_buffer = strscpy(send_buffer,"UPTIME\r\n");
230 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
231 if(result!=STATE_OK)
232 return result;
233 recv_buffer[strlen(recv_buffer)-1]=0;
234 sprintf(uptime,"Up %s,",recv_buffer);
236 if(check_critical_value==TRUE && utilization >= critical_value)
237 result=STATE_CRITICAL;
238 else if(check_warning_value==TRUE && utilization >= warning_value)
239 result=STATE_WARNING;
241 asprintf(&output_message,"Load %s - %s %s-min load average = %lu%%",(result==STATE_OK)?"ok":"problem",uptime,temp_buffer,utilization);
243 /* check number of user connections */
244 } else if (vars_to_check==CHECK_CONNS) {
246 send_buffer = strscpy(send_buffer,"CONNECT\r\n");
247 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
248 if(result!=STATE_OK)
249 return result;
250 current_connections=strtoul(recv_buffer,NULL,10);
252 if(check_critical_value==TRUE && current_connections >= critical_value)
253 result=STATE_CRITICAL;
254 else if(check_warning_value==TRUE && current_connections >= warning_value)
255 result=STATE_WARNING;
256 asprintf(&output_message,"Conns %s - %lu current connections",(result==STATE_OK)?"ok":"problem",current_connections);
258 /* check % long term cache hits */
259 } else if (vars_to_check==CHECK_LTCH) {
261 send_buffer = strscpy(send_buffer,"S1\r\n");
262 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
263 if(result!=STATE_OK)
264 return result;
265 cache_hits=atoi(recv_buffer);
267 if(check_critical_value==TRUE && cache_hits <= critical_value)
268 result=STATE_CRITICAL;
269 else if(check_warning_value==TRUE && cache_hits <= warning_value)
270 result=STATE_WARNING;
271 asprintf(&output_message,"Long term cache hits = %d%%",cache_hits);
273 /* check cache buffers */
274 } else if (vars_to_check==CHECK_CBUFF) {
276 send_buffer = strscpy(send_buffer,"S2\r\n");
277 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
278 if(result!=STATE_OK)
279 return result;
280 cache_buffers=strtoul(recv_buffer,NULL,10);
282 if(check_critical_value==TRUE && cache_buffers <= critical_value)
283 result=STATE_CRITICAL;
284 else if(check_warning_value==TRUE && cache_buffers <= warning_value)
285 result=STATE_WARNING;
286 asprintf(&output_message,"Total cache buffers = %lu",cache_buffers);
288 /* check dirty cache buffers */
289 } else if (vars_to_check==CHECK_CDBUFF) {
291 send_buffer = strscpy(send_buffer,"S3\r\n");
292 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
293 if(result!=STATE_OK)
294 return result;
295 cache_buffers=strtoul(recv_buffer,NULL,10);
297 if(check_critical_value==TRUE && cache_buffers >= critical_value)
298 result=STATE_CRITICAL;
299 else if(check_warning_value==TRUE && cache_buffers >= warning_value)
300 result=STATE_WARNING;
301 asprintf(&output_message,"Dirty cache buffers = %lu",cache_buffers);
303 /* check LRU sitting time in minutes */
304 } else if (vars_to_check==CHECK_LRUM) {
306 send_buffer = strscpy(send_buffer,"S5\r\n");
307 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
308 if(result!=STATE_OK)
309 return result;
310 lru_time=strtoul(recv_buffer,NULL,10);
312 if(check_critical_value==TRUE && lru_time <= critical_value)
313 result=STATE_CRITICAL;
314 else if(check_warning_value==TRUE && lru_time <= warning_value)
315 result=STATE_WARNING;
316 asprintf(&output_message,"LRU sitting time = %lu minutes",lru_time);
319 /* check KB free space on volume */
320 } else if (vars_to_check==CHECK_VKF) {
322 asprintf(&send_buffer,"VKF%s\r\n",volume_name);
323 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
324 if(result!=STATE_OK)
325 return result;
327 if (!strcmp(recv_buffer,"-1\n")) {
328 asprintf(&output_message,"Error: Volume '%s' does not exist!",volume_name);
329 result=STATE_CRITICAL;
330 } else {
331 free_disk_space=strtoul(recv_buffer,NULL,10);
332 if(check_critical_value==TRUE && free_disk_space <= critical_value)
333 result=STATE_CRITICAL;
334 else if(check_warning_value==TRUE && free_disk_space <= warning_value)
335 result=STATE_WARNING;
336 asprintf(&output_message,"%s%lu KB free on volume %s",(result==STATE_OK)?"":"Only ",free_disk_space,volume_name);
337 }
339 /* check % free space on volume */
340 } else if (vars_to_check==CHECK_VPF) {
342 asprintf(&send_buffer,"VKF%s\r\n",volume_name);
343 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
344 if(result!=STATE_OK)
345 return result;
347 if(!strcmp(recv_buffer,"-1\n")){
349 asprintf(&output_message,"Error: Volume '%s' does not exist!",volume_name);
350 result=STATE_CRITICAL;
352 } else {
354 free_disk_space=strtoul(recv_buffer,NULL,10);
356 asprintf(&send_buffer,"VKS%s\r\n",volume_name);
357 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
358 if(result!=STATE_OK)
359 return result;
360 total_disk_space=strtoul(recv_buffer,NULL,10);
362 percent_free_space=(int)(((double)free_disk_space/(double)total_disk_space)*100.0);
364 if(check_critical_value==TRUE && percent_free_space <= critical_value)
365 result=STATE_CRITICAL;
366 else if(check_warning_value==TRUE && percent_free_space <= warning_value)
367 result=STATE_WARNING;
368 free_disk_space/=1024;
369 asprintf(&output_message,"%lu MB (%d%%) free on volume %s",free_disk_space,percent_free_space,volume_name);
370 }
372 /* check to see if DS Database is open or closed */
373 } else if(vars_to_check==CHECK_DSDB) {
375 send_buffer = strscpy(send_buffer,"S11\r\n");
376 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
377 if(result!=STATE_OK)
378 return result;
379 if(atoi(recv_buffer)==1)
380 result=STATE_OK;
381 else
382 result=STATE_WARNING;
384 send_buffer = strscpy(send_buffer,"S13\r\n");
385 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
386 temp_buffer=strtok(recv_buffer,"\r\n");
388 asprintf(&output_message,"Directory Services Database is %s (DS version %s)",(result==STATE_OK)?"open":"closed",temp_buffer);
390 /* check to see if logins are enabled */
391 } else if (vars_to_check==CHECK_LOGINS) {
393 send_buffer = strscpy(send_buffer,"S12\r\n");
394 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
395 if(result!=STATE_OK)
396 return result;
397 if(atoi(recv_buffer)==1)
398 result=STATE_OK;
399 else
400 result=STATE_WARNING;
402 asprintf(&output_message,"Logins are %s",(result==STATE_OK)?"enabled":"disabled");
404 /* check packet receive buffers */
405 } else if (vars_to_check==CHECK_UPRB || vars_to_check==CHECK_PUPRB) {
407 asprintf(&send_buffer,"S15\r\n",volume_name);
408 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
409 if(result!=STATE_OK)
410 return result;
412 used_packet_receive_buffers=atoi(recv_buffer);
414 asprintf(&send_buffer,"S16\r\n",volume_name);
415 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
416 if(result!=STATE_OK)
417 return result;
419 max_packet_receive_buffers=atoi(recv_buffer);
421 percent_used_packet_receive_buffers=(unsigned long)(((double)used_packet_receive_buffers/(double)max_packet_receive_buffers)*100.0);
423 if(vars_to_check==CHECK_UPRB){
424 if(check_critical_value==TRUE && used_packet_receive_buffers >= critical_value)
425 result=STATE_CRITICAL;
426 else if(check_warning_value==TRUE && used_packet_receive_buffers >= warning_value)
427 result=STATE_WARNING;
428 } else {
429 if(check_critical_value==TRUE && percent_used_packet_receive_buffers >= critical_value)
430 result=STATE_CRITICAL;
431 else if(check_warning_value==TRUE && percent_used_packet_receive_buffers >= warning_value)
432 result=STATE_WARNING;
433 }
435 asprintf(&output_message,"%d of %d (%lu%%) packet receive buffers used",used_packet_receive_buffers,max_packet_receive_buffers,percent_used_packet_receive_buffers);
437 /* check SAP table entries */
438 } else if (vars_to_check==CHECK_SAPENTRIES) {
440 if(sap_number==-1)
441 asprintf(&send_buffer,"S9\r\n");
442 else
443 asprintf(&send_buffer,"S9.%d\r\n",sap_number);
444 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
445 if(result!=STATE_OK)
446 return result;
448 sap_entries=atoi(recv_buffer);
450 if(check_critical_value==TRUE && sap_entries >= critical_value)
451 result=STATE_CRITICAL;
452 else if(check_warning_value==TRUE && sap_entries >= warning_value)
453 result=STATE_WARNING;
455 if(sap_number==-1)
456 asprintf(&output_message,"%d entries in SAP table",sap_entries);
457 else
458 asprintf(&output_message,"%d entries in SAP table for SAP type %d",sap_entries,sap_number);
460 /* check KB purgeable space on volume */
461 } else if (vars_to_check==CHECK_VKP) {
463 asprintf(&send_buffer,"VKP%s\r\n",volume_name);
464 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
465 if(result!=STATE_OK)
466 return result;
468 if (!strcmp(recv_buffer,"-1\n")) {
469 asprintf(&output_message,"Error: Volume '%s' does not exist!",volume_name);
470 result=STATE_CRITICAL;
471 } else {
472 purgeable_disk_space=strtoul(recv_buffer,NULL,10);
473 if(check_critical_value==TRUE && purgeable_disk_space >= critical_value)
474 result=STATE_CRITICAL;
475 else if(check_warning_value==TRUE && purgeable_disk_space >= warning_value)
476 result=STATE_WARNING;
477 asprintf(&output_message,"%s%lu KB purgeable on volume %s",(result==STATE_OK)?"":"Only ",purgeable_disk_space,volume_name);
478 }
480 /* check % purgeable space on volume */
481 } else if (vars_to_check==CHECK_VPP) {
483 asprintf(&send_buffer,"VKP%s\r\n",volume_name);
484 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
485 if(result!=STATE_OK)
486 return result;
488 if(!strcmp(recv_buffer,"-1\n")){
490 asprintf(&output_message,"Error: Volume '%s' does not exist!",volume_name);
491 result=STATE_CRITICAL;
493 } else {
495 purgeable_disk_space=strtoul(recv_buffer,NULL,10);
497 asprintf(&send_buffer,"VKS%s\r\n",volume_name);
498 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
499 if(result!=STATE_OK)
500 return result;
501 total_disk_space=strtoul(recv_buffer,NULL,10);
503 percent_purgeable_space=(int)(((double)purgeable_disk_space/(double)total_disk_space)*100.0);
505 if(check_critical_value==TRUE && percent_purgeable_space >= critical_value)
506 result=STATE_CRITICAL;
507 else if(check_warning_value==TRUE && percent_purgeable_space >= warning_value)
508 result=STATE_WARNING;
509 purgeable_disk_space/=1024;
510 asprintf(&output_message,"%lu MB (%d%%) purgeable on volume %s",purgeable_disk_space,percent_purgeable_space,volume_name);
511 }
513 /* check KB not yet purgeable space on volume */
514 } else if (vars_to_check==CHECK_VKNP) {
516 asprintf(&send_buffer,"VKNP%s\r\n",volume_name);
517 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
518 if(result!=STATE_OK)
519 return result;
521 if (!strcmp(recv_buffer,"-1\n")) {
522 asprintf(&output_message,"Error: Volume '%s' does not exist!",volume_name);
523 result=STATE_CRITICAL;
524 } else {
525 non_purgeable_disk_space=strtoul(recv_buffer,NULL,10);
526 if(check_critical_value==TRUE && non_purgeable_disk_space >= critical_value)
527 result=STATE_CRITICAL;
528 else if(check_warning_value==TRUE && non_purgeable_disk_space >= warning_value)
529 result=STATE_WARNING;
530 asprintf(&output_message,"%s%lu KB not yet purgeable on volume %s",(result==STATE_OK)?"":"Only ",non_purgeable_disk_space,volume_name);
531 }
533 /* check % not yet purgeable space on volume */
534 } else if (vars_to_check==CHECK_VPNP) {
536 asprintf(&send_buffer,"VKNP%s\r\n",volume_name);
537 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
538 if(result!=STATE_OK)
539 return result;
541 if(!strcmp(recv_buffer,"-1\n")){
543 asprintf(&output_message,"Error: Volume '%s' does not exist!",volume_name);
544 result=STATE_CRITICAL;
546 } else {
548 non_purgeable_disk_space=strtoul(recv_buffer,NULL,10);
550 asprintf(&send_buffer,"VKS%s\r\n",volume_name);
551 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
552 if(result!=STATE_OK)
553 return result;
554 total_disk_space=strtoul(recv_buffer,NULL,10);
556 percent_non_purgeable_space=(int)(((double)non_purgeable_disk_space/(double)total_disk_space)*100.0);
558 if(check_critical_value==TRUE && percent_non_purgeable_space >= critical_value)
559 result=STATE_CRITICAL;
560 else if(check_warning_value==TRUE && percent_non_purgeable_space >= warning_value)
561 result=STATE_WARNING;
562 purgeable_disk_space/=1024;
563 asprintf(&output_message,"%lu MB (%d%%) not yet purgeable on volume %s",non_purgeable_disk_space,percent_non_purgeable_space,volume_name);
564 }
566 /* check # of open files */
567 } else if (vars_to_check==CHECK_OFILES) {
569 asprintf(&send_buffer,"S18\r\n");
570 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
571 if(result!=STATE_OK)
572 return result;
574 open_files=atoi(recv_buffer);
576 if(check_critical_value==TRUE && open_files >= critical_value)
577 result=STATE_CRITICAL;
578 else if(check_warning_value==TRUE && open_files >= warning_value)
579 result=STATE_WARNING;
581 asprintf(&output_message,"%d open files",open_files);
583 /* check # of abended threads (Netware 5.x only) */
584 } else if (vars_to_check==CHECK_ABENDS) {
586 asprintf(&send_buffer,"S17\r\n");
587 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
588 if(result!=STATE_OK)
589 return result;
591 abended_threads=atoi(recv_buffer);
593 if(check_critical_value==TRUE && abended_threads >= critical_value)
594 result=STATE_CRITICAL;
595 else if(check_warning_value==TRUE && abended_threads >= warning_value)
596 result=STATE_WARNING;
598 asprintf(&output_message,"%d abended threads",abended_threads);
600 /* check # of current service processes (Netware 5.x only) */
601 } else if (vars_to_check==CHECK_CSPROCS) {
603 asprintf(&send_buffer,"S20\r\n");
604 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
605 if(result!=STATE_OK)
606 return result;
608 max_service_processes=atoi(recv_buffer);
610 asprintf(&send_buffer,"S21\r\n");
611 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
612 if(result!=STATE_OK)
613 return result;
615 current_service_processes=atoi(recv_buffer);
617 if(check_critical_value==TRUE && current_service_processes >= critical_value)
618 result=STATE_CRITICAL;
619 else if(check_warning_value==TRUE && current_service_processes >= warning_value)
620 result=STATE_WARNING;
622 asprintf(&output_message,"%d current service processes (%d max)",current_service_processes,max_service_processes);
624 /* check # Timesync Status */
625 } else if (vars_to_check==CHECK_TSYNC) {
627 asprintf(&send_buffer,"S22\r\n");
628 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
629 if(result!=STATE_OK)
630 return result;
632 time_sync_status=atoi(recv_buffer);
634 if(time_sync_status==0) {
635 result=STATE_CRITICAL;
636 asprintf(&output_message,"Critical: Time not in sync with network!");
637 }
638 else {
639 asprintf(&output_message,"OK! Time in sync with network!");
640 }
642 /* check LRU sitting time in secondss */
643 } else if (vars_to_check==CHECK_LRUS) {
645 send_buffer = strscpy(send_buffer,"S4\r\n");
646 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
647 if(result!=STATE_OK)
648 return result;
649 lru_time=strtoul(recv_buffer,NULL,10);
651 if(check_critical_value==TRUE && lru_time <= critical_value)
652 result=STATE_CRITICAL;
653 else if(check_warning_value==TRUE && lru_time <= warning_value)
654 result=STATE_WARNING;
655 asprintf(&output_message,"LRU sitting time = %lu seconds",lru_time);
658 /* check % dirty cache buffers as a percentage of the total*/
659 } else if (vars_to_check==CHECK_DCB) {
661 send_buffer = strscpy(send_buffer,"S6\r\n");
662 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
663 if(result!=STATE_OK)
664 return result;
665 dirty_cache_buffers=atoi(recv_buffer);
667 if(check_critical_value==TRUE && dirty_cache_buffers <= critical_value)
668 result=STATE_CRITICAL;
669 else if(check_warning_value==TRUE && dirty_cache_buffers <= warning_value)
670 result=STATE_WARNING;
671 asprintf(&output_message,"dirty cache buffers = %d%% of the total",dirty_cache_buffers);
673 /* check % total cache buffers as a percentage of the original*/
674 } else if (vars_to_check==CHECK_TCB) {
676 send_buffer = strscpy(send_buffer,"S7\r\n");
677 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
678 if(result!=STATE_OK)
679 return result;
680 total_cache_buffers=atoi(recv_buffer);
682 if(check_critical_value==TRUE && total_cache_buffers <= critical_value)
683 result=STATE_CRITICAL;
684 else if(check_warning_value==TRUE && total_cache_buffers <= warning_value)
685 result=STATE_WARNING;
686 asprintf(&output_message,"total cache buffers = %d%% of the original",total_cache_buffers);
688 } else if (vars_to_check==CHECK_DSVER) {
689 asprintf(&send_buffer,"S13\r\n");
690 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
691 if(result!=STATE_OK)
692 return result;
694 recv_buffer[strlen(recv_buffer)-1]=0;
696 asprintf(&output_message,"NDS Version %s",recv_buffer);
698 } else if (vars_to_check==CHECK_UPTIME) {
699 asprintf(&send_buffer,"UPTIME\r\n");
700 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
701 if(result!=STATE_OK)
702 return result;
704 recv_buffer[strlen(recv_buffer)-1]=0;
706 asprintf(&output_message,"Up %s",recv_buffer);
708 } else if (vars_to_check==CHECK_NLM) {
709 asprintf(&send_buffer,"S24:%s\r\n",nlm_name);
710 result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer));
711 if(result!=STATE_OK)
712 return result;
714 recv_buffer[strlen(recv_buffer)-1]=0;
715 if(strcmp(recv_buffer,"-1")) {
716 asprintf(&output_message,"Module %s version %s is loaded",nlm_name,recv_buffer);
717 } else {
718 result=STATE_CRITICAL;
719 asprintf(&output_message,"Module %s is not loaded",nlm_name);
720 }
722 } else {
724 output_message = strscpy(output_message,"Nothing to check!\n");
725 result=STATE_UNKNOWN;
727 }
729 /* reset timeout */
730 alarm(0);
732 printf("%s%s\n",netware_version,output_message);
734 return result;
735 }
738 /* process command-line arguments */
739 int process_arguments(int argc, char **argv){
740 int c;
742 int option_index = 0;
743 static struct option long_options[] =
744 {
745 {"port", required_argument,0,'p'},
746 {"timeout", required_argument,0,'t'},
747 {"critical", required_argument,0,'c'},
748 {"warning", required_argument,0,'w'},
749 {"variable", required_argument,0,'v'},
750 {"hostname", required_argument,0,'H'},
751 {"osversion",no_argument, 0,'o'},
752 {"version", no_argument, 0,'V'},
753 {"help", no_argument, 0,'h'},
754 {0,0,0,0}
755 };
757 /* no options were supplied */
758 if(argc<2) return ERROR;
760 /* backwards compatibility */
761 if (! is_option(argv[1])) {
762 server_address=argv[1];
763 argv[1]=argv[0];
764 argv=&argv[1];
765 argc--;
766 }
768 for (c=1;c<argc;c++) {
769 if(strcmp("-to",argv[c])==0)
770 strcpy(argv[c],"-t");
771 else if (strcmp("-wv",argv[c])==0)
772 strcpy(argv[c],"-w");
773 else if (strcmp("-cv",argv[c])==0)
774 strcpy(argv[c],"-c");
775 }
777 while (1){
778 c = getopt_long(argc,argv,"+hoVH:t:c:w:p:v:",long_options,&option_index);
780 if (c==-1||c==EOF||c==1)
781 break;
783 switch (c)
784 {
785 case '?': /* print short usage statement if args not parsable */
786 printf ("%s: Unknown argument: %s\n\n", progname, optarg);
787 print_usage();
788 exit(STATE_UNKNOWN);
789 case 'h': /* help */
790 print_help();
791 exit(STATE_OK);
792 case 'V': /* version */
793 print_revision(progname,"$Revision$");
794 exit(STATE_OK);
795 case 'H': /* hostname */
796 server_address=optarg;
797 break;
798 case 'o': /* display nos version */
799 check_netware_version=TRUE;
800 break;
801 case 'p': /* port */
802 if (is_intnonneg(optarg))
803 server_port=atoi(optarg);
804 else
805 terminate(STATE_UNKNOWN,"Server port an integer (seconds)\nType '%s -h' for additional help\n",progname);
806 break;
807 case 'v':
808 if(strlen(optarg)<3)
809 return ERROR;
810 if(!strcmp(optarg,"LOAD1"))
811 vars_to_check=CHECK_LOAD1;
812 else if(!strcmp(optarg,"LOAD5"))
813 vars_to_check=CHECK_LOAD5;
814 else if(!strcmp(optarg,"LOAD15"))
815 vars_to_check=CHECK_LOAD15;
816 else if(!strcmp(optarg,"CONNS"))
817 vars_to_check=CHECK_CONNS;
818 else if(!strcmp(optarg,"LTCH"))
819 vars_to_check=CHECK_LTCH;
820 else if(!strcmp(optarg,"DCB"))
821 vars_to_check=CHECK_DCB;
822 else if(!strcmp(optarg,"TCB"))
823 vars_to_check=CHECK_TCB;
824 else if(!strcmp(optarg,"CBUFF"))
825 vars_to_check=CHECK_CBUFF;
826 else if(!strcmp(optarg,"CDBUFF"))
827 vars_to_check=CHECK_CDBUFF;
828 else if(!strcmp(optarg,"LRUM"))
829 vars_to_check=CHECK_LRUM;
830 else if(!strcmp(optarg,"LRUS"))
831 vars_to_check=CHECK_LRUS;
832 else if(strncmp(optarg,"VPF",3)==0){
833 vars_to_check=CHECK_VPF;
834 volume_name = strscpy(volume_name,optarg+3);
835 if(!strcmp(volume_name,""))
836 volume_name = strscpy(volume_name,"SYS");
837 }
838 else if(strncmp(optarg,"VKF",3)==0){
839 vars_to_check=CHECK_VKF;
840 volume_name = strscpy(volume_name,optarg+3);
841 if(!strcmp(volume_name,""))
842 volume_name = strscpy(volume_name,"SYS");
843 }
844 else if(!strcmp(optarg,"DSDB"))
845 vars_to_check=CHECK_DSDB;
846 else if(!strcmp(optarg,"LOGINS"))
847 vars_to_check=CHECK_LOGINS;
848 else if(!strcmp(optarg,"UPRB"))
849 vars_to_check=CHECK_UPRB;
850 else if(!strcmp(optarg,"PUPRB"))
851 vars_to_check=CHECK_PUPRB;
852 else if(!strncmp(optarg,"SAPENTRIES",10)){
853 vars_to_check=CHECK_SAPENTRIES;
854 if(strlen(optarg)>10)
855 sap_number=atoi(optarg+10);
856 else
857 sap_number=-1;
858 }
859 else if(!strcmp(optarg,"OFILES"))
860 vars_to_check=CHECK_OFILES;
861 else if(strncmp(optarg,"VKP",3)==0){
862 vars_to_check=CHECK_VKP;
863 volume_name = strscpy(volume_name,optarg+3);
864 if(!strcmp(volume_name,""))
865 volume_name = strscpy(volume_name,"SYS");
866 }
867 else if(strncmp(optarg,"VPP",3)==0){
868 vars_to_check=CHECK_VPP;
869 volume_name = strscpy(volume_name,optarg+3);
870 if(!strcmp(volume_name,""))
871 volume_name = strscpy(volume_name,"SYS");
872 }
873 else if(strncmp(optarg,"VKNP",4)==0){
874 vars_to_check=CHECK_VKNP;
875 volume_name = strscpy(volume_name,optarg+4);
876 if(!strcmp(volume_name,""))
877 volume_name = strscpy(volume_name,"SYS");
878 }
879 else if(strncmp(optarg,"VPNP",4)==0){
880 vars_to_check=CHECK_VPNP;
881 volume_name = strscpy(volume_name,optarg+4);
882 if(!strcmp(volume_name,""))
883 volume_name = strscpy(volume_name,"SYS");
884 }
885 else if(!strcmp(optarg,"ABENDS"))
886 vars_to_check=CHECK_ABENDS;
887 else if(!strcmp(optarg,"CSPROCS"))
888 vars_to_check=CHECK_CSPROCS;
889 else if(!strcmp(optarg,"TSYNC"))
890 vars_to_check=CHECK_TSYNC;
891 else if(!strcmp(optarg,"DSVER"))
892 vars_to_check=CHECK_DSVER;
893 else if(!strcmp(optarg,"UPTIME"))
894 vars_to_check=CHECK_UPTIME;
895 else if(strncmp(optarg,"NLM:",4)==0) {
896 vars_to_check=CHECK_NLM;
897 nlm_name=strscpy(nlm_name,optarg+4);
898 }
899 else
900 return ERROR;
901 break;
902 case 'w': /* warning threshold */
903 warning_value=strtoul(optarg,NULL,10);
904 check_warning_value=TRUE;
905 break;
906 case 'c': /* critical threshold */
907 critical_value=strtoul(optarg,NULL,10);
908 check_critical_value=TRUE;
909 break;
910 case 't': /* timeout */
911 socket_timeout=atoi(optarg);
912 if(socket_timeout<=0)
913 return ERROR;
914 }
916 }
918 return OK;
919 }
922 void print_usage(void)
923 {
924 printf
925 ("Usage:\n"
926 " %s %s\n"
927 " %s (-h | --help) for detailed help\n"
928 " %s (-V | --version) for version information\n",
929 progname, OPTIONS, progname, progname);
930 }
932 void print_help(void)
933 {
934 print_revision (progname, REVISION);
935 printf ("%s\n\n%s\n", COPYRIGHT, SUMMARY);
936 print_usage();
937 printf
938 ("\nOptions:\n" LONGOPTIONS "\n" DESCRIPTION "\n",
939 PORT, DEFAULT_SOCKET_TIMEOUT);
940 support ();
941 }