diff options
Diffstat (limited to 'plugins/check_dig.c')
| -rw-r--r-- | plugins/check_dig.c | 168 |
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 | |||
| 21 | const char *progname = "check_dig"; | 27 | const char *progname = "check_dig"; |
| 22 | const char *revision = "$Revision$"; | 28 | const char *revision = "$Revision$"; |
| 23 | const char *copyright = "2002-2004"; | 29 | const 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 | ||
| 31 | int process_arguments (int, char **); | 37 | int process_arguments (int, char **); |
| 32 | int validate_arguments (void); | 38 | int validate_arguments (void); |
| 33 | void print_help (void); | 39 | void print_help (void); |
| 34 | void print_usage (void); | 40 | void print_usage (void); |
| 35 | 41 | ||
| 36 | enum { | 42 | #define UNDEFINED 0 |
| 37 | UNDEFINED = 0, | 43 | #define DEFAULT_PORT 53 |
| 38 | DEFAULT_PORT = 53 | ||
| 39 | }; | ||
| 40 | 44 | ||
| 41 | char *query_address = NULL; | 45 | char *query_address = NULL; |
| 42 | char *record_type = "A"; | 46 | char *record_type = "A"; |
| @@ -51,26 +55,25 @@ struct timeval tv; | |||
| 51 | int | 55 | int |
| 52 | main (int argc, char **argv) | 56 | main (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 ("\ |
| 361 | Usage: %s -H host -l lookup [-p <server port>] [-T <query type>]\n\ | 331 | Usage: %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 | } |
