1 /*****************************************************************************
2  *
3  * modpnpsender.c - NEB Module for sending PNP performance data
4  *
5  * Copyright (c) 2007-2009 Hendrik Baecker (http://www.process-zero.de)
6  *
7  * Last Modified: $LastChangedDate: 2009-01-07 19:53:58 +0100 (Wed, 07 Jan 2009) $
8  * by: 		  $Author: hendrikb $
9  *
10  *
11  * Description:
12  *
13  * Will follow soon....
14  *
15  *
16  * Instructions:
17  *
18  * Compile with the following command:
19  *
20  *     gcc -shared -o modpnpsender.o modpnpsender.c
21  *
22  *****************************************************************************/
23 
24 /* include (minimum required) event broker header files */
25 #include "../include/nebmodules.h"
26 #include "../include/nebcallbacks.h"
27 
28 /* include other event broker header files that we need for our work */
29 #include "../include/nebstructs.h"
30 #include "../include/broker.h"
31 
32 /* include some Nagios stuff as well */
33 #include "../include/config.h"
34 #include "../include/common.h"
35 #include "../include/nagios.h"
36 
37 #include <sys/types.h>
38 #include <sys/socket.h>
39 #include <errno.h>
40 #include <time.h>
41 
42 #define OPEN 	1
43 #define CLOSE	0
44 
45 #define BUFFER 1024
46 
47 /* specify event broker API version (required) */
48 NEB_API_VERSION(CURRENT_NEB_API_VERSION);
49 
50 #define DEFAULT_SERVERPORT 5661
51 
52 void *modpnpsender_module_handle=NULL;
53 
54 int modpnpsender_handle_data(int,void *);
55 int send_data(nebstruct_service_check_data *);
56 int open_sock();
57 
58 char *serverip="127.0.0.1";
59 char *port, *saveptr1;
60 int serverport=DEFAULT_SERVERPORT;
61 int socket_status=CLOSE;
62 
63 /* this function gets called when the module is loaded by the event broker */
nebmodule_init(int flags,char * args,nebmodule * handle)64 int nebmodule_init(int flags, char *args, nebmodule *handle){
65 	char temp_buffer[1024];
66 	time_t current_time;
67 	unsigned long interval;
68 
69 	/* save our handle */
70 	modpnpsender_module_handle=handle;
71 
72 	/* log module info to the Nagios log file */
73 	write_to_all_logs("modpnpsender: Copyright (c)2007 Hendrik Baecker (andurin@process-zero.de)",NSLOG_INFO_MESSAGE);
74 
75 	/* log a message to the Nagios log file */
76 	snprintf(temp_buffer,sizeof(temp_buffer)-1,"modpnpsender: PNPSender module starting the engines!\n");
77 	temp_buffer[sizeof(temp_buffer)-1]='\x0';
78 	write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE);
79 
80 	if(args == NULL) {
81 	        write_to_all_logs("modpnpsender: WARNING assuming '127.0.0.1' as destination IP Address)",NSLOG_INFO_MESSAGE);
82 	}
83 	else {
84 		if((serverip = strtok_r(args, " ", &saveptr1))!=NULL){
85 			serverip = serverip;
86 		}
87 
88 		if((port = strtok_r(NULL, " ", &saveptr1))!=NULL){
89 			serverport=atoi(port);
90 		}
91 	}
92 
93 
94 	snprintf(temp_buffer,sizeof(temp_buffer)-1,"modpnpsender: Arguments are %s - %d",serverip,serverport);
95 	temp_buffer[sizeof(temp_buffer)-1]='\x0';
96 	write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE);
97 
98 
99 	/* register to be notified of certain events... */
100 	neb_register_callback(NEBCALLBACK_SERVICE_CHECK_DATA,modpnpsender_module_handle,0,modpnpsender_handle_data);
101 
102 	return 0;
103         }
104 
105 
106 /* this function gets called when the module is unloaded by the event broker */
nebmodule_deinit(int flags,int reason)107 int nebmodule_deinit(int flags, int reason){
108 	char temp_buffer[1024];
109 
110 	/* deregister for all events we previously registered for... */
111 	neb_deregister_callback(NEBCALLBACK_SERVICE_CHECK_DATA,modpnpsender_handle_data);
112 
113 	/* log a message to the Nagios log file */
114 	snprintf(temp_buffer,sizeof(temp_buffer)-1,"modpnpsender: Exiting - Thanks for for the flight!\n");
115 	temp_buffer[sizeof(temp_buffer)-1]='\x0';
116 	write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE);
117 
118 	return 0;
119         }
120 
121 
122 /* handle data from Nagios daemon */
modpnpsender_handle_data(int event_type,void * data)123 int modpnpsender_handle_data(int event_type, void *data){
124 	nebstruct_service_check_data *scdata=NULL;
125 	char temp_buffer[1024];
126 
127 	/* what type of event/data do we have? */
128 	switch(event_type){
129 
130 	case NEBCALLBACK_SERVICE_CHECK_DATA:
131 
132 		/* a service check event occurs */
133                 if((scdata=(nebstruct_service_check_data *)data)!=NULL){
134 
135 			if (scdata->type==NEBTYPE_SERVICECHECK_INITIATE) {
136 
137 				/* Check if this service check has performance data */
138 
139 				if (scdata->perf_data != NULL) {
140 					snprintf(temp_buffer,sizeof(temp_buffer)-1,"modpnpsender: Processing PNP for %s / %s with perfdata %s",scdata->host_name,scdata->service_description,scdata->perf_data);
141 					temp_buffer[sizeof(temp_buffer)-1]='\x0';
142 					write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE);
143 					if(send_data(scdata)!=0) {
144 					        write_to_all_logs("modpnpsender: An error occured while sending data!",NSLOG_INFO_MESSAGE);
145 					}
146 					else {
147 					        write_to_all_logs("modpnpsender: Message sent - finish for now.",NSLOG_INFO_MESSAGE);
148 						return 0;
149 					}
150 				}
151         	        }
152 		}
153 	        break;
154 
155 
156 	default:
157 		break;
158 	        }
159 
160 	return 0;
161         }
162 
163 /*********************************************
164  *
165  * Sending Data
166  *
167  * *******************************************/
168 
send_data(nebstruct_service_check_data * data)169 int send_data(nebstruct_service_check_data *data){
170 	char temp_buffer[1024];
171 	char *message;
172 	int socket;
173 	int message_length = 1024;
174 	char cmd[1024];
175 	time_t t;
176 
177 	if (socket_status == CLOSE) {
178 		socket = open_sock();
179 		if (socket == -1) {
180 			write_to_all_logs("modpnpsender: Arg! Socket is -1",NSLOG_INFO_MESSAGE);
181 			return (-1);
182 			}
183 		}
184 
185 	if (!(message = (char *) malloc(message_length))) {
186 		snprintf(temp_buffer,sizeof(temp_buffer)-1,"modpnpsender: cannot allocate memory for message. Aborting...\n");
187                 temp_buffer[sizeof(temp_buffer)-1]='\x0';
188                 write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE);
189 		return (-1);
190 	}
191 
192 	bzero((void *)message, message_length);
193 
194 	strcat(message,"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n");
195 	strcat(message,"<NAGIOS>\n<NAGIOS_DATATYPE>serviceperfdata</NAGIOS_DATATYPE>\n");
196 
197 	strcat(message,"<NAGIOS_HOSTNAME>");
198 	strcat(message,data->host_name);
199 	strcat(message,"</NAGIOS_HOSTNAME>\n");
200 
201 	strcat(message,"<NAGIOS_SERVICEDESC>");
202 	strcat(message,data->service_description);
203 	strcat(message,"</NAGIOS_SERVICEDESC>\n");
204 
205 	strcat(message,"<NAGIOS_SERVICEPERFDATA>");
206 	strcat(message,data->perf_data);
207 	strcat(message,"</NAGIOS_SERVICEPERFDATA>\n");
208 
209 	strcat(message,"<NAGIOS_SERVICECHECKCOMMAND>");
210         if (data->command_name != NULL) {
211 		strcat(message,data->command_name);
212 		}
213         strcat(message,"</NAGIOS_SERVICECHECKCOMMAND>\n");
214 
215         strcat(message,"<NAGIOS_SERVICECHECKCOMMAND_ARGS>");
216         if (data->command_args != NULL) strcat(message,data->command_args);
217         strcat(message,"</NAGIOS_SERVICECHECKCOMMAND>\n");
218 
219         strcat(message,"<NAGIOS_SERVICECHECKCOMMAND_LINE>");
220         if (data->command_line != NULL) strcat(message,data->command_line);
221         strcat(message,"</NAGIOS_SERVICECHECKCOMMAND>\n");
222 
223         strcat(message,"<NAGIOS_SERVICEOUTPUT>");
224         if (data->output != NULL) strcat(message,data->output);
225         strcat(message,"</NAGIOS_SERVICEOUTPUT>\n");
226 
227 
228 	time(&t);
229 	snprintf(temp_buffer, sizeof(temp_buffer)-1,"%ld",t);
230 	temp_buffer[sizeof(temp_buffer)-1]='\x0';
231 
232  	strcat(message,"<NAGIOS_TIMET>");
233 	strcat(message, temp_buffer);
234 	strcat(message,"</NAGIOS_TIMET>\n");
235 	bzero((void *)temp_buffer,sizeof(temp_buffer)-1);
236 
237 	strcat(message,"</NAGIOS>\n");
238 
239 	if(send(socket, message, strlen(message), 0) == -1) {
240 		snprintf(temp_buffer,sizeof(temp_buffer)-1,"modpnpsender: error while sending message to server. - %s\n",strerror(errno));
241                 temp_buffer[sizeof(temp_buffer)-1]='\x0';
242                 write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE);
243 	}
244 
245 	close (socket);
246 	socket_status = CLOSE;
247 
248 	snprintf(temp_buffer,sizeof(temp_buffer)-1,"modpnpsender: Sending perfdata for %s / %s with perfdata %s",data->host_name,data->service_description,data->perf_data);
249         temp_buffer[sizeof(temp_buffer)-1]='\x0';
250         write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE);
251 
252 	return 0;
253 }
254 
open_sock()255 int open_sock(){
256 	int tosocket; /* the socket descriptor*/
257 	char temp_buffer[BUFFER];
258 
259 	/* description of struct sockaddr_in is mentioned in netinet/in.h */
260 	struct sockaddr_in toaddr; /* store address of server here */
261 
262 	/* create tcp socket */
263 	tosocket = socket(PF_INET,SOCK_STREAM,0);
264 	if(tosocket == -1){
265 		snprintf(temp_buffer,sizeof(temp_buffer)-1,"modpnpsender: Unable to create socket. Aborting...\n");
266                 temp_buffer[sizeof(temp_buffer)-1]='\x0';
267                 write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE);
268 		return(-1);
269 		}
270 	/* else {
271                 snprintf(temp_buffer,sizeof(temp_buffer)-1,"modpnpsender: Socket is OK....\n");
272                 temp_buffer[sizeof(temp_buffer)-1]='\x0';
273                 write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE);
274 		} */
275 
276 	/* define server address */
277 	toaddr.sin_family = PF_INET;
278 	toaddr.sin_addr.s_addr =  inet_addr(serverip);
279 	toaddr.sin_port = htons(serverport);
280 
281 	/* connect to server */
282 	if(connect(tosocket, (struct sockaddr *)&toaddr, sizeof(toaddr)) == -1){
283 
284 		snprintf(temp_buffer,sizeof(temp_buffer)-1,"modpnpsender: Unable to connect to server '%s' on port %d. Aborting...\n", serverip, serverport);
285 		temp_buffer[sizeof(temp_buffer)-1]='\x0';
286 		write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE);
287 		// write_to_all_logs("modpnpsender: Connect failed... closing the socket...",NSLOG_INFO_MESSAGE);
288 		close (tosocket);
289 		// write_to_all_logs("modpnpsender: Socket closed...",NSLOG_INFO_MESSAGE);
290 		return(-1);
291 		}
292 	else {
293 		socket_status=OPEN;
294 		return tosocket;
295 		}
296 	return (-1);
297 }
298