summaryrefslogtreecommitdiffstats
path: root/plugins/check_dig.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/check_dig.c')
-rw-r--r--plugins/check_dig.c168
1 files changed, 69 insertions, 99 deletions
diff --git a/plugins/check_dig.c b/plugins/check_dig.c
index 4394490e..bc4dcd5c 100644
--- a/plugins/check_dig.c
+++ b/plugins/check_dig.c
@@ -18,6 +18,12 @@
18 18
19*****************************************************************************/ 19*****************************************************************************/
20 20
21/* Hackers note:
22 * There are typecasts to (char *) from _("foo bar") in this file.
23 * They prevent compiler warnings. Never (ever), permute strings obtained
24 * that are typecast from (const char *) (which happens when --disable-nls)
25 * because on some architectures those strings are in non-writable memory */
26
21const char *progname = "check_dig"; 27const char *progname = "check_dig";
22const char *revision = "$Revision$"; 28const char *revision = "$Revision$";
23const char *copyright = "2002-2004"; 29const char *copyright = "2002-2004";
@@ -26,17 +32,15 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net";
26#include "common.h" 32#include "common.h"
27#include "netutils.h" 33#include "netutils.h"
28#include "utils.h" 34#include "utils.h"
29#include "popen.h" 35#include "runcmd.h"
30 36
31int process_arguments (int, char **); 37int process_arguments (int, char **);
32int validate_arguments (void); 38int validate_arguments (void);
33void print_help (void); 39void print_help (void);
34void print_usage (void); 40void print_usage (void);
35 41
36enum { 42#define UNDEFINED 0
37 UNDEFINED = 0, 43#define DEFAULT_PORT 53
38 DEFAULT_PORT = 53
39};
40 44
41char *query_address = NULL; 45char *query_address = NULL;
42char *record_type = "A"; 46char *record_type = "A";
@@ -51,26 +55,25 @@ struct timeval tv;
51int 55int
52main (int argc, char **argv) 56main (int argc, char **argv)
53{ 57{
54 char input_buffer[MAX_INPUT_BUFFER];
55 char *command_line; 58 char *command_line;
56 char *output; 59 output chld_out, chld_err;
60 char *msg = NULL;
61 size_t i;
57 char *t; 62 char *t;
58 long microsec; 63 long microsec;
59 double elapsed_time; 64 double elapsed_time;
60 int result = STATE_UNKNOWN; 65 int result = STATE_UNKNOWN;
61 66
62 output = strdup ("");
63
64 setlocale (LC_ALL, ""); 67 setlocale (LC_ALL, "");
65 bindtextdomain (PACKAGE, LOCALEDIR); 68 bindtextdomain (PACKAGE, LOCALEDIR);
66 textdomain (PACKAGE); 69 textdomain (PACKAGE);
67 70
68 /* Set signal handling and alarm */ 71 /* Set signal handling and alarm */
69 if (signal (SIGALRM, popen_timeout_alarm_handler) == SIG_ERR) 72 if (signal (SIGALRM, popen_timeout_alarm_handler) == SIG_ERR)
70 usage4 (_("Cannot catch SIGALRM")); 73 usage_va(_("Cannot catch SIGALRM"));
71 74
72 if (process_arguments (argc, argv) == ERROR) 75 if (process_arguments (argc, argv) == ERROR)
73 usage4 (_("Could not parse arguments")); 76 usage_va(_("Could not parse arguments"));
74 77
75 /* get the command to run */ 78 /* get the command to run */
76 asprintf (&command_line, "%s @%s -p %d %s -t %s", 79 asprintf (&command_line, "%s @%s -p %d %s -t %s",
@@ -89,100 +92,75 @@ main (int argc, char **argv)
89 } 92 }
90 93
91 /* run the command */ 94 /* run the command */
92 child_process = spopen (command_line); 95 if(np_runcmd(command_line, &chld_out, &chld_err, 0) != 0) {
93 if (child_process == NULL) { 96 result = STATE_WARNING;
94 printf (_("Could not open pipe: %s\n"), command_line); 97 msg = (char *)_("dig returned an error status");
95 return STATE_UNKNOWN;
96 } 98 }
97 99
98 child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); 100 for(i = 0; i < chld_out.lines; i++) {
99 if (child_stderr == NULL)
100 printf (_("Could not open stderr for %s\n"), command_line);
101
102 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) {
103
104 /* the server is responding, we just got the host name... */ 101 /* the server is responding, we just got the host name... */
105 if (strstr (input_buffer, ";; ANSWER SECTION:")) { 102 if (strstr (chld_out.line[i], ";; ANSWER SECTION:")) {
106 103
107 /* loop through the whole 'ANSWER SECTION' */ 104 /* loop through the whole 'ANSWER SECTION' */
108 do { 105 for(; i < chld_out.lines; i++) {
109 /* get the host address */ 106 /* get the host address */
110 if (!fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) 107 if (verbose)
111 break; 108 printf ("%s\n", chld_out.line[i]);
112
113 if (strpbrk (input_buffer, "\r\n"))
114 input_buffer[strcspn (input_buffer, "\r\n")] = '\0';
115 109
116 if (verbose && !strstr (input_buffer, ";; ")) 110 if (strstr (chld_out.line[i], (expected_address == NULL ? query_address : expected_address)) != NULL) {
117 printf ("%s\n", input_buffer); 111 msg = chld_out.line[i];
118
119 if (expected_address==NULL && strstr (input_buffer, query_address) != NULL) {
120 output = strdup(input_buffer);
121 result = STATE_OK; 112 result = STATE_OK;
122 }
123 else if (expected_address != NULL && strstr (input_buffer, expected_address) != NULL) {
124 output = strdup(input_buffer);
125 result = STATE_OK;
126 }
127
128 /* Translate output TAB -> SPACE */
129 t = output;
130 while ((t = index(t, '\t')) != NULL)
131 *t = ' ';
132 113
133 } while (!strstr (input_buffer, ";; ")); 114 /* Translate output TAB -> SPACE */
115 t = msg;
116 while ((t = strchr(t, '\t')) != NULL) *t = ' ';
117 break;
118 }
119 }
134 120
135 if (result == STATE_UNKNOWN) { 121 if (result == STATE_UNKNOWN) {
136 asprintf (&output, _("Server not found in ANSWER SECTION")); 122 msg = (char *)_("Server not found in ANSWER SECTION");
137 result = STATE_WARNING; 123 result = STATE_WARNING;
138 } 124 }
139 }
140
141 }
142
143 if (result == STATE_UNKNOWN) {
144 asprintf (&output, _("No ANSWER SECTION found"));
145 }
146 125
147 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) { 126 /* we found the answer section, so break out of the loop */
148 /* If we get anything on STDERR, at least set warning */ 127 break;
149 result = max_state (result, STATE_WARNING); 128 }
150 printf ("%s", input_buffer);
151 if (strlen (output) == 0)
152 output = strdup (1 + index (input_buffer, ':'));
153 } 129 }
154 130
155 (void) fclose (child_stderr); 131 if (result == STATE_UNKNOWN)
156 132 msg = (char *)_("No ANSWER SECTION found");
157 /* close the pipe */ 133
158 if (spclose (child_process)) { 134 /* If we get anything on STDERR, at least set warning */
159 result = max_state (result, STATE_WARNING); 135 if(chld_err.buflen > 0) {
160 if (strlen (output) == 0) 136 result = max_state(result, STATE_WARNING);
161 asprintf (&output, _("dig returned an error status")); 137 if(!msg) for(i = 0; i < chld_err.lines; i++) {
138 msg = strchr(chld_err.line[0], ':');
139 if(msg) {
140 msg++;
141 break;
142 }
143 }
162 } 144 }
163 145
164 microsec = deltime (tv); 146 microsec = deltime (tv);
165 elapsed_time = (double)microsec / 1.0e6; 147 elapsed_time = (double)microsec / 1.0e6;
166 148
167 if (output == NULL || strlen (output) == 0)
168 asprintf (&output, _(" Probably a non-existent host/domain"));
169
170 if (critical_interval > UNDEFINED && elapsed_time > critical_interval) 149 if (critical_interval > UNDEFINED && elapsed_time > critical_interval)
171 result = STATE_CRITICAL; 150 result = STATE_CRITICAL;
172 151
173 else if (warning_interval > UNDEFINED && elapsed_time > warning_interval) 152 else if (warning_interval > UNDEFINED && elapsed_time > warning_interval)
174 result = STATE_WARNING; 153 result = STATE_WARNING;
175 154
176 asprintf (&output, _("%.3f seconds response time (%s)"), elapsed_time, output); 155 printf ("DNS %s - %.3f seconds response time (%s)|%s\n",
177 156 state_text (result), elapsed_time,
178 printf ("DNS %s - %s|%s\n", 157 msg ? msg : _("Probably a non-existent host/domain"),
179 state_text (result), output,
180 fperfdata("time", elapsed_time, "s", 158 fperfdata("time", elapsed_time, "s",
181 (warning_interval>UNDEFINED?TRUE:FALSE), 159 (warning_interval>UNDEFINED?TRUE:FALSE),
182 warning_interval, 160 warning_interval,
183 (critical_interval>UNDEFINED?TRUE:FALSE), 161 (critical_interval>UNDEFINED?TRUE:FALSE),
184 critical_interval, 162 critical_interval,
185 TRUE, 0, FALSE, 0)); 163 TRUE, 0, FALSE, 0));
186 return result; 164 return result;
187} 165}
188 166
@@ -219,8 +197,6 @@ process_arguments (int argc, char **argv)
219 break; 197 break;
220 198
221 switch (c) { 199 switch (c) {
222 case '?': /* help */
223 usage2 (_("Unknown argument"), optarg);
224 case 'h': /* help */ 200 case 'h': /* help */
225 print_help (); 201 print_help ();
226 exit (STATE_OK); 202 exit (STATE_OK);
@@ -228,19 +204,15 @@ process_arguments (int argc, char **argv)
228 print_revision (progname, revision); 204 print_revision (progname, revision);
229 exit (STATE_OK); 205 exit (STATE_OK);
230 case 'H': /* hostname */ 206 case 'H': /* hostname */
231 if (is_host (optarg)) { 207 host_or_die(optarg);
232 dns_server = optarg; 208 dns_server = optarg;
233 }
234 else {
235 usage2 (_("Invalid hostname/address"), optarg);
236 }
237 break; 209 break;
238 case 'p': /* server port */ 210 case 'p': /* server port */
239 if (is_intpos (optarg)) { 211 if (is_intpos (optarg)) {
240 server_port = atoi (optarg); 212 server_port = atoi (optarg);
241 } 213 }
242 else { 214 else {
243 usage2 (_("Port must be a positive integer"), optarg); 215 usage_va(_("Port must be a positive integer - %s"), optarg);
244 } 216 }
245 break; 217 break;
246 case 'l': /* address to lookup */ 218 case 'l': /* address to lookup */
@@ -251,7 +223,7 @@ process_arguments (int argc, char **argv)
251 warning_interval = strtod (optarg, NULL); 223 warning_interval = strtod (optarg, NULL);
252 } 224 }
253 else { 225 else {
254 usage2 (_("Warning interval must be a positive integer"), optarg); 226 usage_va(_("Warning interval must be a positive integer - %s"), optarg);
255 } 227 }
256 break; 228 break;
257 case 'c': /* critical */ 229 case 'c': /* critical */
@@ -259,7 +231,7 @@ process_arguments (int argc, char **argv)
259 critical_interval = strtod (optarg, NULL); 231 critical_interval = strtod (optarg, NULL);
260 } 232 }
261 else { 233 else {
262 usage2 (_("Critical interval must be a positive integer"), optarg); 234 usage_va(_("Critical interval must be a positive integer - %s"), optarg);
263 } 235 }
264 break; 236 break;
265 case 't': /* timeout */ 237 case 't': /* timeout */
@@ -267,7 +239,7 @@ process_arguments (int argc, char **argv)
267 timeout_interval = atoi (optarg); 239 timeout_interval = atoi (optarg);
268 } 240 }
269 else { 241 else {
270 usage2 (_("Timeout interval must be a positive integer"), optarg); 242 usage_va(_("Timeout interval must be a positive integer - %s"), optarg);
271 } 243 }
272 break; 244 break;
273 case 'v': /* verbose */ 245 case 'v': /* verbose */
@@ -279,18 +251,16 @@ process_arguments (int argc, char **argv)
279 case 'a': 251 case 'a':
280 expected_address = optarg; 252 expected_address = optarg;
281 break; 253 break;
254 default: /* usage_va */
255 usage_va(_("Unknown argument - %s"), optarg);
282 } 256 }
283 } 257 }
284 258
285 c = optind; 259 c = optind;
286 if (dns_server == NULL) { 260 if (dns_server == NULL) {
287 if (c < argc) { 261 if (c < argc) {
288 if (is_host (argv[c])) { 262 host_or_die(argv[c]);
289 dns_server = argv[c]; 263 dns_server = argv[c];
290 }
291 else {
292 usage2 (_("Invalid hostname/address"), argv[c]);
293 }
294 } 264 }
295 else { 265 else {
296 dns_server = strdup ("127.0.0.1"); 266 dns_server = strdup ("127.0.0.1");
@@ -359,6 +329,6 @@ print_usage (void)
359{ 329{
360 printf ("\ 330 printf ("\
361Usage: %s -H host -l lookup [-p <server port>] [-T <query type>]\n\ 331Usage: %s -H host -l lookup [-p <server port>] [-T <query type>]\n\
362 [-w <warning interval>] [-c <critical interval>] [-t <timeout>]\n\ 332 [-w <warning interval>] [-c <critical interval>] [-t <timeout>]\n\
363 [-a <expected answer address>] [-v]\n", progname); 333 [-a <expected answer address>] [-v]\n", progname);
364} 334}