diff options
| -rw-r--r-- | plugins/netutils.c | 253 | ||||
| -rw-r--r-- | plugins/netutils.h.in | 17 | ||||
| -rw-r--r-- | plugins/utils.c | 72 | ||||
| -rw-r--r-- | plugins/utils.h.in | 4 |
4 files changed, 116 insertions, 230 deletions
diff --git a/plugins/netutils.c b/plugins/netutils.c index fc85a246..c0e82dad 100644 --- a/plugins/netutils.c +++ b/plugins/netutils.c | |||
| @@ -40,20 +40,18 @@ RETSIGTYPE socket_timeout_alarm_handler (int); | |||
| 40 | int process_tcp_request2 (char *, int, char *, char *, int); | 40 | int process_tcp_request2 (char *, int, char *, char *, int); |
| 41 | int process_tcp_request (char *, int, char *, char *, int); | 41 | int process_tcp_request (char *, int, char *, char *, int); |
| 42 | int process_udp_request (char *, int, char *, char *, int); | 42 | int process_udp_request (char *, int, char *, char *, int); |
| 43 | int process_request (char *, int, char *, char *, char *, int); | 43 | int process_request (char *, int, int, char *, char *, int); |
| 44 | 44 | ||
| 45 | int my_tcp_connect (char *, int, int *); | 45 | int my_tcp_connect (char *, int, int *); |
| 46 | int my_udp_connect (char *, int, int *); | 46 | int my_udp_connect (char *, int, int *); |
| 47 | int my_connect (char *, int, int *, char *); | 47 | int my_connect (char *, int, int *, int); |
| 48 | |||
| 49 | int my_inet_aton (register const char *, struct in_addr *); | ||
| 50 | 48 | ||
| 51 | /* handles socket timeouts */ | 49 | /* handles socket timeouts */ |
| 52 | void | 50 | void |
| 53 | socket_timeout_alarm_handler (int sig) | 51 | socket_timeout_alarm_handler (int sig) |
| 54 | { | 52 | { |
| 55 | 53 | ||
| 56 | printf ("Socket timeout after %d seconds\n", socket_timeout); | 54 | printf ("CRITICAL - Socket timeout after %d seconds\n", socket_timeout); |
| 57 | 55 | ||
| 58 | exit (STATE_CRITICAL); | 56 | exit (STATE_CRITICAL); |
| 59 | } | 57 | } |
| @@ -62,16 +60,13 @@ socket_timeout_alarm_handler (int sig) | |||
| 62 | /* connects to a host on a specified TCP port, sends a string, | 60 | /* connects to a host on a specified TCP port, sends a string, |
| 63 | and gets a response */ | 61 | and gets a response */ |
| 64 | int | 62 | int |
| 65 | process_tcp_request (char *server_address, | 63 | process_tcp_request (char *server_address, int server_port, |
| 66 | int server_port, | 64 | char *send_buffer, char *recv_buffer, int recv_size) |
| 67 | char *send_buffer, char *recv_buffer, int recv_size) | ||
| 68 | { | 65 | { |
| 69 | int result; | 66 | int result; |
| 70 | char proto[4] = "tcp"; | ||
| 71 | 67 | ||
| 72 | result = process_request (server_address, | 68 | result = process_request (server_address, server_port, |
| 73 | server_port, | 69 | IPPROTO_TCP, send_buffer, recv_buffer, recv_size); |
| 74 | proto, send_buffer, recv_buffer, recv_size); | ||
| 75 | 70 | ||
| 76 | return result; | 71 | return result; |
| 77 | } | 72 | } |
| @@ -80,16 +75,13 @@ process_tcp_request (char *server_address, | |||
| 80 | /* connects to a host on a specified UDP port, sends a string, and gets a | 75 | /* connects to a host on a specified UDP port, sends a string, and gets a |
| 81 | response */ | 76 | response */ |
| 82 | int | 77 | int |
| 83 | process_udp_request (char *server_address, | 78 | process_udp_request (char *server_address, int server_port, |
| 84 | int server_port, | 79 | char *send_buffer, char *recv_buffer, int recv_size) |
| 85 | char *send_buffer, char *recv_buffer, int recv_size) | ||
| 86 | { | 80 | { |
| 87 | int result; | 81 | int result; |
| 88 | char proto[4] = "udp"; | ||
| 89 | 82 | ||
| 90 | result = process_request (server_address, | 83 | result = process_request (server_address, server_port, |
| 91 | server_port, | 84 | IPPROTO_UDP, send_buffer, recv_buffer, recv_size); |
| 92 | proto, send_buffer, recv_buffer, recv_size); | ||
| 93 | 85 | ||
| 94 | return result; | 86 | return result; |
| 95 | } | 87 | } |
| @@ -100,9 +92,8 @@ process_udp_request (char *server_address, | |||
| 100 | response. loops on select-recv until timeout or eof to get all of a | 92 | response. loops on select-recv until timeout or eof to get all of a |
| 101 | multi-packet answer */ | 93 | multi-packet answer */ |
| 102 | int | 94 | int |
| 103 | process_tcp_request2 (char *server_address, | 95 | process_tcp_request2 (char *server_address, int server_port, |
| 104 | int server_port, | 96 | char *send_buffer, char *recv_buffer, int recv_size) |
| 105 | char *send_buffer, char *recv_buffer, int recv_size) | ||
| 106 | { | 97 | { |
| 107 | 98 | ||
| 108 | int result; | 99 | int result; |
| @@ -113,7 +104,7 @@ process_tcp_request2 (char *server_address, | |||
| 113 | fd_set readfds; | 104 | fd_set readfds; |
| 114 | int recv_length = 0; | 105 | int recv_length = 0; |
| 115 | 106 | ||
| 116 | result = my_connect (server_address, server_port, &sd, "tcp"); | 107 | result = my_connect (server_address, server_port, &sd, IPPROTO_TCP); |
| 117 | if (result != STATE_OK) | 108 | if (result != STATE_OK) |
| 118 | return STATE_CRITICAL; | 109 | return STATE_CRITICAL; |
| 119 | 110 | ||
| @@ -146,25 +137,31 @@ process_tcp_request2 (char *server_address, | |||
| 146 | } | 137 | } |
| 147 | else { /* it has */ | 138 | else { /* it has */ |
| 148 | recv_result = | 139 | recv_result = |
| 149 | recv (sd, recv_buffer + recv_length, recv_size - recv_length - 1, 0); | 140 | recv (sd, recv_buffer + recv_length, |
| 150 | if (recv_result == -1) { /* recv failed, bail out */ | 141 | recv_size - recv_length - 1, 0); |
| 142 | if (recv_result == -1) { | ||
| 143 | /* recv failed, bail out */ | ||
| 151 | strcpy (recv_buffer + recv_length, ""); | 144 | strcpy (recv_buffer + recv_length, ""); |
| 152 | result = STATE_WARNING; | 145 | result = STATE_WARNING; |
| 153 | break; | 146 | break; |
| 154 | } | 147 | } |
| 155 | else if (recv_result == 0) { /* end of file ? */ | 148 | else if (recv_result == 0) { |
| 149 | /* end of file ? */ | ||
| 156 | recv_buffer[recv_length] = 0; | 150 | recv_buffer[recv_length] = 0; |
| 157 | break; | 151 | break; |
| 158 | } | 152 | } |
| 159 | else { /* we got data! */ | 153 | else { /* we got data! */ |
| 160 | recv_length += recv_result; | 154 | recv_length += recv_result; |
| 161 | if (recv_length >= recv_size - 1) { /* buffer full, we're done */ | 155 | if (recv_length >= recv_size - 1) { |
| 156 | /* buffer full, we're done */ | ||
| 162 | recv_buffer[recv_size - 1] = 0; | 157 | recv_buffer[recv_size - 1] = 0; |
| 163 | break; | 158 | break; |
| 164 | } | 159 | } |
| 165 | } | 160 | } |
| 166 | } /* end if(!FD_ISSET(sd,&readfds)) */ | 161 | } |
| 167 | } /* end while(1) */ | 162 | /* end if(!FD_ISSET(sd,&readfds)) */ |
| 163 | } | ||
| 164 | /* end while(1) */ | ||
| 168 | 165 | ||
| 169 | close (sd); | 166 | close (sd); |
| 170 | return result; | 167 | return result; |
| @@ -173,10 +170,8 @@ process_tcp_request2 (char *server_address, | |||
| 173 | /* connects to a host on a specified port, sends a string, and gets a | 170 | /* connects to a host on a specified port, sends a string, and gets a |
| 174 | response */ | 171 | response */ |
| 175 | int | 172 | int |
| 176 | process_request (char *server_address, | 173 | process_request (char *server_address, int server_port, int proto, |
| 177 | int server_port, | 174 | char *send_buffer, char *recv_buffer, int recv_size) |
| 178 | char *proto, | ||
| 179 | char *send_buffer, char *recv_buffer, int recv_size) | ||
| 180 | { | 175 | { |
| 181 | int result; | 176 | int result; |
| 182 | int send_result; | 177 | int send_result; |
| @@ -216,7 +211,7 @@ process_request (char *server_address, | |||
| 216 | recv_result = recv (sd, recv_buffer, recv_size - 1, 0); | 211 | recv_result = recv (sd, recv_buffer, recv_size - 1, 0); |
| 217 | if (recv_result == -1) { | 212 | if (recv_result == -1) { |
| 218 | strcpy (recv_buffer, ""); | 213 | strcpy (recv_buffer, ""); |
| 219 | if (!strcmp (proto, "tcp")) | 214 | if (proto != IPPROTO_TCP) |
| 220 | printf ("recv() failed\n"); | 215 | printf ("recv() failed\n"); |
| 221 | result = STATE_WARNING; | 216 | result = STATE_WARNING; |
| 222 | } | 217 | } |
| @@ -238,9 +233,8 @@ int | |||
| 238 | my_tcp_connect (char *host_name, int port, int *sd) | 233 | my_tcp_connect (char *host_name, int port, int *sd) |
| 239 | { | 234 | { |
| 240 | int result; | 235 | int result; |
| 241 | char proto[4] = "tcp"; | ||
| 242 | 236 | ||
| 243 | result = my_connect (host_name, port, sd, proto); | 237 | result = my_connect (host_name, port, sd, IPPROTO_TCP); |
| 244 | 238 | ||
| 245 | return result; | 239 | return result; |
| 246 | } | 240 | } |
| @@ -251,9 +245,8 @@ int | |||
| 251 | my_udp_connect (char *host_name, int port, int *sd) | 245 | my_udp_connect (char *host_name, int port, int *sd) |
| 252 | { | 246 | { |
| 253 | int result; | 247 | int result; |
| 254 | char proto[4] = "udp"; | ||
| 255 | 248 | ||
| 256 | result = my_connect (host_name, port, sd, proto); | 249 | result = my_connect (host_name, port, sd, IPPROTO_UDP); |
| 257 | 250 | ||
| 258 | return result; | 251 | return result; |
| 259 | } | 252 | } |
| @@ -261,169 +254,53 @@ my_udp_connect (char *host_name, int port, int *sd) | |||
| 261 | 254 | ||
| 262 | /* opens a tcp or udp connection to a remote host */ | 255 | /* opens a tcp or udp connection to a remote host */ |
| 263 | int | 256 | int |
| 264 | my_connect (char *host_name, int port, int *sd, char *proto) | 257 | my_connect (char *host_name, int port, int *sd, int proto) |
| 265 | { | 258 | { |
| 266 | struct sockaddr_in servaddr; | 259 | struct addrinfo hints; |
| 267 | struct hostent *hp; | 260 | struct addrinfo *res; |
| 268 | struct protoent *ptrp; | 261 | struct addrinfo *ptrp; |
| 262 | char port_str[6]; | ||
| 269 | int result; | 263 | int result; |
| 270 | 264 | ||
| 271 | bzero ((char *) &servaddr, sizeof (servaddr)); | 265 | memset (&hints, 0, sizeof (hints)); |
| 272 | servaddr.sin_family = AF_INET; | 266 | hints.ai_family = PF_UNSPEC; |
| 273 | servaddr.sin_port = htons (port); | 267 | hints.ai_protocol = proto; |
| 274 | 268 | ||
| 275 | /* try to bypass using a DNS lookup if this is just an IP address */ | 269 | snprintf (port_str, sizeof (port_str), "%d", port); |
| 276 | if (!my_inet_aton (host_name, &servaddr.sin_addr)) { | 270 | result = getaddrinfo (host_name, port_str, &hints, &res); |
| 277 | |||
| 278 | /* else do a DNS lookup */ | ||
| 279 | hp = gethostbyname ((const char *) host_name); | ||
| 280 | if (hp == NULL) { | ||
| 281 | printf ("Invalid host name '%s'\n", host_name); | ||
| 282 | return STATE_UNKNOWN; | ||
| 283 | } | ||
| 284 | |||
| 285 | memcpy (&servaddr.sin_addr, hp->h_addr, hp->h_length); | ||
| 286 | } | ||
| 287 | |||
| 288 | /* map transport protocol name to protocol number */ | ||
| 289 | if ((ptrp = getprotobyname (proto)) == NULL) { | ||
| 290 | printf ("Cannot map \"%s\" to protocol number\n", proto); | ||
| 291 | return STATE_UNKNOWN; | ||
| 292 | } | ||
| 293 | 271 | ||
| 294 | /* create a socket */ | 272 | if (result != 0) { |
| 295 | *sd = | 273 | printf ("%s\n", gai_strerror (result)); |
| 296 | socket (PF_INET, (!strcmp (proto, "udp")) ? SOCK_DGRAM : SOCK_STREAM, | ||
| 297 | ptrp->p_proto); | ||
| 298 | if (*sd < 0) { | ||
| 299 | printf ("Socket creation failed\n"); | ||
| 300 | return STATE_UNKNOWN; | 274 | return STATE_UNKNOWN; |
| 301 | } | 275 | } |
| 276 | else { | ||
| 277 | while (res) { | ||
| 278 | /* attempt to create a socket */ | ||
| 279 | *sd = socket (res->ai_family, (proto == IPPROTO_UDP) ? | ||
| 280 | SOCK_DGRAM : SOCK_STREAM, res->ai_protocol); | ||
| 281 | |||
| 282 | if (*sd < 0) { | ||
| 283 | printf ("Socket creation failed\n"); | ||
| 284 | freeaddrinfo (res); | ||
| 285 | return STATE_UNKNOWN; | ||
| 286 | } | ||
| 302 | 287 | ||
| 303 | /* open a connection */ | 288 | /* attempt to open a connection */ |
| 304 | result = connect (*sd, (struct sockaddr *) &servaddr, sizeof (servaddr)); | 289 | result = connect (*sd, res->ai_addr, res->ai_addrlen); |
| 305 | if (result < 0) { | ||
| 306 | switch (errno) { | ||
| 307 | case ECONNREFUSED: | ||
| 308 | printf ("Connection refused by host\n"); | ||
| 309 | break; | ||
| 310 | case ETIMEDOUT: | ||
| 311 | printf ("Timeout while attempting connection\n"); | ||
| 312 | break; | ||
| 313 | case ENETUNREACH: | ||
| 314 | printf ("Network is unreachable\n"); | ||
| 315 | break; | ||
| 316 | default: | ||
| 317 | printf ("Connection refused or timed out\n"); | ||
| 318 | } | ||
| 319 | |||
| 320 | return STATE_CRITICAL; | ||
| 321 | } | ||
| 322 | |||
| 323 | return STATE_OK; | ||
| 324 | } | ||
| 325 | |||
| 326 | |||
| 327 | |||
| 328 | /* This code was taken from Fyodor's nmap utility, which was originally | ||
| 329 | taken from the GLIBC 2.0.6 libraries because Solaris doesn't contain | ||
| 330 | the inet_aton() funtion. */ | ||
| 331 | int | ||
| 332 | my_inet_aton (register const char *cp, struct in_addr *addr) | ||
| 333 | { | ||
| 334 | register unsigned int val; /* changed from u_long --david */ | ||
| 335 | register int base, n; | ||
| 336 | register char c; | ||
| 337 | u_int parts[4]; | ||
| 338 | register u_int *pp = parts; | ||
| 339 | |||
| 340 | c = *cp; | ||
| 341 | |||
| 342 | for (;;) { | ||
| 343 | |||
| 344 | /* | ||
| 345 | * Collect number up to ``.''. | ||
| 346 | * Values are specified as for C: | ||
| 347 | * 0x=hex, 0=octal, isdigit=decimal. | ||
| 348 | */ | ||
| 349 | if (!isdigit ((int) c)) | ||
| 350 | return (0); | ||
| 351 | val = 0; | ||
| 352 | base = 10; | ||
| 353 | |||
| 354 | if (c == '0') { | ||
| 355 | c = *++cp; | ||
| 356 | if (c == 'x' || c == 'X') | ||
| 357 | base = 16, c = *++cp; | ||
| 358 | else | ||
| 359 | base = 8; | ||
| 360 | } | ||
| 361 | 290 | ||
| 362 | for (;;) { | 291 | if (result == 0) |
| 363 | if (isascii ((int) c) && isdigit ((int) c)) { | ||
| 364 | val = (val * base) + (c - '0'); | ||
| 365 | c = *++cp; | ||
| 366 | } | ||
| 367 | else if (base == 16 && isascii ((int) c) && isxdigit ((int) c)) { | ||
| 368 | val = (val << 4) | (c + 10 - (islower ((int) c) ? 'a' : 'A')); | ||
| 369 | c = *++cp; | ||
| 370 | } | ||
| 371 | else | ||
| 372 | break; | 292 | break; |
| 373 | } | ||
| 374 | 293 | ||
| 375 | if (c == '.') { | 294 | close (*sd); |
| 376 | 295 | res = res->ai_next; | |
| 377 | /* | ||
| 378 | * Internet format: | ||
| 379 | * a.b.c.d | ||
| 380 | * a.b.c (with c treated as 16 bits) | ||
| 381 | * a.b (with b treated as 24 bits) | ||
| 382 | */ | ||
| 383 | if (pp >= parts + 3) | ||
| 384 | return (0); | ||
| 385 | *pp++ = val; | ||
| 386 | c = *++cp; | ||
| 387 | } | 296 | } |
| 388 | else | 297 | freeaddrinfo (res); |
| 389 | break; | ||
| 390 | } | 298 | } |
| 391 | 299 | ||
| 392 | /* Check for trailing characters */ | 300 | if (result == 0) |
| 393 | if (c != '\0' && (!isascii ((int) c) || !isspace ((int) c))) | 301 | return STATE_OK; |
| 394 | return (0); | 302 | else { |
| 395 | 303 | printf ("%s\n", strerror(errno)); | |
| 396 | /* Concoct the address according to the number of parts specified */ | 304 | return STATE_CRITICAL; |
| 397 | n = pp - parts + 1; | ||
| 398 | switch (n) { | ||
| 399 | |||
| 400 | case 0: | ||
| 401 | return (0); /* initial nondigit */ | ||
| 402 | |||
| 403 | case 1: /* a -- 32 bits */ | ||
| 404 | break; | ||
| 405 | |||
| 406 | case 2: /* a.b -- 8.24 bits */ | ||
| 407 | if (val > 0xffffff) | ||
| 408 | return (0); | ||
| 409 | val |= parts[0] << 24; | ||
| 410 | break; | ||
| 411 | |||
| 412 | case 3: /* a.b.c -- 8.8.16 bits */ | ||
| 413 | if (val > 0xffff) | ||
| 414 | return (0); | ||
| 415 | val |= (parts[0] << 24) | (parts[1] << 16); | ||
| 416 | break; | ||
| 417 | |||
| 418 | case 4: /* a.b.c.d -- 8.8.8.8 bits */ | ||
| 419 | if (val > 0xff) | ||
| 420 | return (0); | ||
| 421 | val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); | ||
| 422 | break; | ||
| 423 | } | 305 | } |
| 424 | |||
| 425 | if (addr) | ||
| 426 | addr->s_addr = htonl (val); | ||
| 427 | |||
| 428 | return (1); | ||
| 429 | } | 306 | } |
diff --git a/plugins/netutils.h.in b/plugins/netutils.h.in index 1907ab7e..69cf2781 100644 --- a/plugins/netutils.h.in +++ b/plugins/netutils.h.in | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #undef HAVE_STRINGS_H | 34 | #undef HAVE_STRINGS_H |
| 35 | #undef HAVE_STRING_H | 35 | #undef HAVE_STRING_H |
| 36 | 36 | ||
| 37 | #include "config.h" | ||
| 37 | #include "common.h" | 38 | #include "common.h" |
| 38 | #include <netinet/in.h> | 39 | #include <netinet/in.h> |
| 39 | #include <arpa/inet.h> | 40 | #include <arpa/inet.h> |
| @@ -41,22 +42,16 @@ | |||
| 41 | void socket_timeout_alarm_handler (int); | 42 | void socket_timeout_alarm_handler (int); |
| 42 | 43 | ||
| 43 | int process_tcp_request2 (char *address, int port, char *sbuffer, | 44 | int process_tcp_request2 (char *address, int port, char *sbuffer, |
| 44 | char *rbuffer, int rsize); | 45 | char *rbuffer, int rsize); |
| 45 | int process_tcp_request (char *address, int port, char *sbuffer, | 46 | int process_tcp_request (char *address, int port, char *sbuffer, |
| 46 | char *rbuffer, int rsize); | 47 | char *rbuffer, int rsize); |
| 47 | int process_udp_request (char *address, int port, char *sbuffer, | 48 | int process_udp_request (char *address, int port, char *sbuffer, |
| 48 | char *rbuffer, int rsize); | 49 | char *rbuffer, int rsize); |
| 49 | int process_request (char *address, int port, char *proto, char *sbuffer, | 50 | int process_request (char *address, int port, char *proto, char *sbuffer, |
| 50 | char *rbuffer, int rsize); | 51 | char *rbuffer, int rsize); |
| 51 | 52 | ||
| 52 | int my_tcp_connect (char *address, int port, int *sd); | 53 | int my_tcp_connect (char *address, int port, int *sd); |
| 53 | int my_udp_connect (char *address, int port, int *sd); | 54 | int my_udp_connect (char *address, int port, int *sd); |
| 54 | int my_connect (char *address, int port, int *sd, char *proto); | 55 | int my_connect (char *address, int port, int *sd, int proto); |
| 55 | |||
| 56 | int my_inet_aton (register const char *cp, struct in_addr *addr); | ||
| 57 | 56 | ||
| 58 | #ifndef DEFAULT_SOCKET_TIMEOUT | ||
| 59 | #include "config.h" | ||
| 60 | #include "common.h" | ||
| 61 | #endif | ||
| 62 | int socket_timeout = DEFAULT_SOCKET_TIMEOUT; | 57 | int socket_timeout = DEFAULT_SOCKET_TIMEOUT; |
diff --git a/plugins/utils.c b/plugins/utils.c index aaa9fe5a..0d250677 100644 --- a/plugins/utils.c +++ b/plugins/utils.c | |||
| @@ -17,6 +17,8 @@ | |||
| 17 | #include <stdarg.h> | 17 | #include <stdarg.h> |
| 18 | #include <limits.h> | 18 | #include <limits.h> |
| 19 | 19 | ||
| 20 | #include <arpa/inet.h> | ||
| 21 | |||
| 20 | extern int timeout_interval; | 22 | extern int timeout_interval; |
| 21 | extern const char *progname; | 23 | extern const char *progname; |
| 22 | 24 | ||
| @@ -27,7 +29,10 @@ void terminate (int, const char *fmt, ...); | |||
| 27 | RETSIGTYPE timeout_alarm_handler (int); | 29 | RETSIGTYPE timeout_alarm_handler (int); |
| 28 | 30 | ||
| 29 | int is_host (char *); | 31 | int is_host (char *); |
| 30 | int is_dotted_quad (char *); | 32 | int is_addr (char *); |
| 33 | int resolve_host_or_addr (char *, int); | ||
| 34 | int is_inet_addr (char *); | ||
| 35 | int is_inet6_addr (char *); | ||
| 31 | int is_hostname (char *); | 36 | int is_hostname (char *); |
| 32 | 37 | ||
| 33 | int is_integer (char *); | 38 | int is_integer (char *); |
| @@ -58,7 +63,7 @@ char *strpcat (char *dest, const char *src, const char *str); | |||
| 58 | #define TXTBLK 128 | 63 | #define TXTBLK 128 |
| 59 | 64 | ||
| 60 | /* ************************************************************************** | 65 | /* ************************************************************************** |
| 61 | * max_state(STATE_x, STATE_y) | 66 | /* max_state(STATE_x, STATE_y) |
| 62 | * compares STATE_x to STATE_y and returns result based on the following | 67 | * compares STATE_x to STATE_y and returns result based on the following |
| 63 | * STATE_UNKNOWN < STATE_OK < STATE_WARNING < STATE_CRITICAL | 68 | * STATE_UNKNOWN < STATE_OK < STATE_WARNING < STATE_CRITICAL |
| 64 | * | 69 | * |
| @@ -167,28 +172,50 @@ timeout_alarm_handler (int signo) | |||
| 167 | int | 172 | int |
| 168 | is_host (char *address) | 173 | is_host (char *address) |
| 169 | { | 174 | { |
| 170 | if (is_dotted_quad (address) || is_hostname (address)) | 175 | if (is_addr (address) || is_hostname (address)) |
| 171 | return (TRUE); | 176 | return (TRUE); |
| 177 | |||
| 172 | return (FALSE); | 178 | return (FALSE); |
| 173 | } | 179 | } |
| 174 | 180 | ||
| 175 | int | 181 | int |
| 176 | is_dotted_quad (char *address) | 182 | is_addr (char *address) |
| 177 | { | 183 | { |
| 178 | int o1, o2, o3, o4; | 184 | if (is_inet_addr (address) || is_inet6_addr (address)) |
| 179 | char c[1]; | 185 | return (TRUE); |
| 180 | 186 | ||
| 181 | if (!address) | 187 | return (FALSE); |
| 182 | return FALSE; | 188 | } |
| 183 | 189 | ||
| 184 | if (sscanf (address, "%d.%d.%d.%d%c", &o1, &o2, &o3, &o4, c) != 4) | 190 | int |
| 185 | return FALSE; | 191 | resolve_host_or_addr (char *address, int family) |
| 186 | else if (o1 > 255 || o2 > 255 || o3 > 255 || o4 > 255) | 192 | { |
| 187 | return FALSE; | 193 | struct addrinfo hints; |
| 188 | else if (o1 < 0 || o2 < 0 || o3 < 0 || o4 < 0) | 194 | struct addrinfo *res; |
| 195 | int retval; | ||
| 196 | |||
| 197 | memset (&hints, 0, sizeof (hints)); | ||
| 198 | hints.ai_family = family; | ||
| 199 | retval = getaddrinfo (address, NULL, &hints, &res); | ||
| 200 | |||
| 201 | if (retval != 0) | ||
| 189 | return FALSE; | 202 | return FALSE; |
| 190 | else | 203 | else { |
| 204 | freeaddrinfo (res); | ||
| 191 | return TRUE; | 205 | return TRUE; |
| 206 | } | ||
| 207 | } | ||
| 208 | |||
| 209 | int | ||
| 210 | is_inet_addr (char *address) | ||
| 211 | { | ||
| 212 | return resolve_host_or_addr (address, AF_INET); | ||
| 213 | } | ||
| 214 | |||
| 215 | int | ||
| 216 | is_inet6_addr (char *address) | ||
| 217 | { | ||
| 218 | return resolve_host_or_addr (address, AF_INET6); | ||
| 192 | } | 219 | } |
| 193 | 220 | ||
| 194 | /* from RFC-1035 | 221 | /* from RFC-1035 |
| @@ -201,22 +228,7 @@ is_dotted_quad (char *address) | |||
| 201 | int | 228 | int |
| 202 | is_hostname (char *s1) | 229 | is_hostname (char *s1) |
| 203 | { | 230 | { |
| 204 | if (!s1 || strlen (s1) > 63) { | 231 | return resolve_host_or_addr (s1, AF_UNSPEC); |
| 205 | return FALSE; | ||
| 206 | } | ||
| 207 | if (strcspn (s1, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUWVXYZ0123456789-.") != 0) { | ||
| 208 | return FALSE; | ||
| 209 | } | ||
| 210 | if (strspn (s1, "0123456789-.") == 1) { | ||
| 211 | return FALSE; | ||
| 212 | } | ||
| 213 | while ((s1 = index (s1, '.'))) { | ||
| 214 | s1++; | ||
| 215 | if (strspn (s1, "0123456789-.") == 1) { | ||
| 216 | return FALSE; | ||
| 217 | } | ||
| 218 | } | ||
| 219 | return TRUE; | ||
| 220 | } | 232 | } |
| 221 | 233 | ||
| 222 | int | 234 | int |
diff --git a/plugins/utils.h.in b/plugins/utils.h.in index 317ec46f..0d947f42 100644 --- a/plugins/utils.h.in +++ b/plugins/utils.h.in | |||
| @@ -28,7 +28,9 @@ int timeout_interval = DEFAULT_SOCKET_TIMEOUT; | |||
| 28 | /* Test input types */ | 28 | /* Test input types */ |
| 29 | 29 | ||
| 30 | int is_host (char *); | 30 | int is_host (char *); |
| 31 | int is_dotted_quad (char *); | 31 | int is_addr (char *); |
| 32 | int is_inet_addr (char *); | ||
| 33 | int is_inet6_addr (char *); | ||
| 32 | int is_hostname (char *); | 34 | int is_hostname (char *); |
| 33 | 35 | ||
| 34 | int is_integer (char *); | 36 | int is_integer (char *); |
