diff options
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/Makefile.am | 2 | ||||
-rw-r--r-- | plugins/check_tcp.c | 24 | ||||
-rw-r--r-- | plugins/netutils.c | 64 | ||||
-rw-r--r-- | plugins/netutils.h | 8 | ||||
-rw-r--r-- | plugins/utils.h | 2 |
5 files changed, 69 insertions, 31 deletions
diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 569199d..4c33ee1 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am | |||
@@ -17,7 +17,7 @@ libexec_PROGRAMS = check_disk check_dummy check_http check_load \ | |||
17 | urlize @EXTRAS@ | 17 | urlize @EXTRAS@ |
18 | 18 | ||
19 | check_tcp_programs = check_ftp check_imap check_nntp check_pop \ | 19 | check_tcp_programs = check_ftp check_imap check_nntp check_pop \ |
20 | check_udp2 @check_tcp_ssl@ | 20 | check_udp2 check_clamd @check_tcp_ssl@ |
21 | 21 | ||
22 | EXTRA_PROGRAMS = check_mysql check_radius check_pgsql check_snmp check_hpjd \ | 22 | EXTRA_PROGRAMS = check_mysql check_radius check_pgsql check_snmp check_hpjd \ |
23 | check_swap check_fping check_ldap check_game check_dig \ | 23 | check_swap check_fping check_ldap check_game check_dig \ |
diff --git a/plugins/check_tcp.c b/plugins/check_tcp.c index 1b6513b..3aef1e7 100644 --- a/plugins/check_tcp.c +++ b/plugins/check_tcp.c | |||
@@ -177,6 +177,12 @@ main (int argc, char **argv) | |||
177 | QUIT = "QUIT\r\n"; | 177 | QUIT = "QUIT\r\n"; |
178 | PORT = 119; | 178 | PORT = 119; |
179 | } | 179 | } |
180 | else if (strncmp(SERVICE, "CLAMD", 5)) { | ||
181 | SEND = "PING"; | ||
182 | EXPECT = "PONG"; | ||
183 | QUIT = NULL; | ||
184 | PORT = 3310; | ||
185 | } | ||
180 | /* fallthrough check, so it's supposed to use reverse matching */ | 186 | /* fallthrough check, so it's supposed to use reverse matching */ |
181 | else if (strcmp (SERVICE, "TCP")) | 187 | else if (strcmp (SERVICE, "TCP")) |
182 | usage (_("CRITICAL - Generic check_tcp called with unknown service\n")); | 188 | usage (_("CRITICAL - Generic check_tcp called with unknown service\n")); |
@@ -318,10 +324,14 @@ main (int argc, char **argv) | |||
318 | printf(_("%s %s - "), SERVICE, state_text(result)); | 324 | printf(_("%s %s - "), SERVICE, state_text(result)); |
319 | 325 | ||
320 | if(match == -2 && len && !(flags & FLAG_HIDE_OUTPUT)) | 326 | if(match == -2 && len && !(flags & FLAG_HIDE_OUTPUT)) |
321 | printf("Unexpected response from host: %s", status); | 327 | printf("Unexpected response from host/socket: %s", status); |
322 | else | 328 | else { |
323 | printf("%.3f second response time on port %d", | 329 | printf("%.3f second response time on ", elapsed_time); |
324 | elapsed_time, server_port); | 330 | if(server_address[0] != '/') |
331 | printf("port %d", server_port); | ||
332 | else | ||
333 | printf("socket %s", server_address); | ||
334 | } | ||
325 | 335 | ||
326 | if (match != -2 && !(flags & FLAG_HIDE_OUTPUT) && len) | 336 | if (match != -2 && !(flags & FLAG_HIDE_OUTPUT) && len) |
327 | printf (" [%s]", status); | 337 | printf (" [%s]", status); |
@@ -431,8 +441,6 @@ process_arguments (int argc, char **argv) | |||
431 | #endif | 441 | #endif |
432 | break; | 442 | break; |
433 | case 'H': /* hostname */ | 443 | case 'H': /* hostname */ |
434 | if (is_host (optarg) == FALSE) | ||
435 | usage2 (_("Invalid hostname/address"), optarg); | ||
436 | server_address = optarg; | 444 | server_address = optarg; |
437 | break; | 445 | break; |
438 | case 'c': /* critical */ | 446 | case 'c': /* critical */ |
@@ -542,6 +550,8 @@ process_arguments (int argc, char **argv) | |||
542 | 550 | ||
543 | if (server_address == NULL) | 551 | if (server_address == NULL) |
544 | usage4 (_("You must provide a server address")); | 552 | usage4 (_("You must provide a server address")); |
553 | else if (is_host (optarg) == FALSE && optarg[0] != '/') | ||
554 | usage2 (_("Invalid hostname, address, or socket"), optarg); | ||
545 | 555 | ||
546 | return TRUE; | 556 | return TRUE; |
547 | } | 557 | } |
@@ -555,7 +565,7 @@ print_help (void) | |||
555 | printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n"); | 565 | printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n"); |
556 | printf (COPYRIGHT, copyright, email); | 566 | printf (COPYRIGHT, copyright, email); |
557 | 567 | ||
558 | printf (_("This plugin tests %s connections with the specified host.\n\n"), | 568 | printf (_("This plugin tests %s connections with the specified host (or unix socket).\n\n"), |
559 | SERVICE); | 569 | SERVICE); |
560 | 570 | ||
561 | print_usage (); | 571 | print_usage (); |
diff --git a/plugins/netutils.c b/plugins/netutils.c index 0824527..6f3a151 100644 --- a/plugins/netutils.c +++ b/plugins/netutils.c | |||
@@ -155,42 +155,46 @@ process_request (const char *server_address, int server_port, int proto, | |||
155 | } | 155 | } |
156 | 156 | ||
157 | 157 | ||
158 | /* opens a tcp or udp connection to a remote host */ | 158 | /* opens a tcp or udp connection to a remote host or local socket */ |
159 | int | 159 | int |
160 | np_net_connect (const char *host_name, int port, int *sd, int proto) | 160 | np_net_connect (const char *host_name, int port, int *sd, int proto) |
161 | { | 161 | { |
162 | struct addrinfo hints; | 162 | struct addrinfo hints; |
163 | struct addrinfo *res, *res0; | 163 | struct addrinfo *r, *res; |
164 | struct sockaddr_un su; | ||
164 | char port_str[6]; | 165 | char port_str[6]; |
165 | int result; | 166 | int socktype, result; |
166 | 167 | ||
167 | memset (&hints, 0, sizeof (hints)); | 168 | socktype = (proto == IPPROTO_UDP) ? SOCK_DGRAM : SOCK_STREAM; |
168 | hints.ai_family = address_family; | ||
169 | hints.ai_protocol = proto; | ||
170 | hints.ai_socktype = (proto == IPPROTO_UDP) ? SOCK_DGRAM : SOCK_STREAM; | ||
171 | 169 | ||
172 | snprintf (port_str, sizeof (port_str), "%d", port); | 170 | /* as long as it doesn't start with a '/', it's assumed a host or ip */ |
173 | result = getaddrinfo (host_name, port_str, &hints, &res0); | 171 | if(host_name[0] != '/'){ |
172 | memset (&hints, 0, sizeof (hints)); | ||
173 | hints.ai_family = address_family; | ||
174 | hints.ai_protocol = proto; | ||
175 | hints.ai_socktype = socktype; | ||
174 | 176 | ||
175 | if (result != 0) { | 177 | snprintf (port_str, sizeof (port_str), "%d", port); |
176 | printf ("%s\n", gai_strerror (result)); | 178 | result = getaddrinfo (host_name, port_str, &hints, &res); |
177 | return STATE_UNKNOWN; | 179 | |
178 | } | 180 | if (result != 0) { |
179 | else { | 181 | printf ("%s\n", gai_strerror (result)); |
180 | res = res0; | 182 | return STATE_UNKNOWN; |
181 | while (res) { | 183 | } |
184 | |||
185 | r = res; | ||
186 | while (r) { | ||
182 | /* attempt to create a socket */ | 187 | /* attempt to create a socket */ |
183 | *sd = socket (res->ai_family, (proto == IPPROTO_UDP) ? | 188 | *sd = socket (r->ai_family, socktype, r->ai_protocol); |
184 | SOCK_DGRAM : SOCK_STREAM, res->ai_protocol); | ||
185 | 189 | ||
186 | if (*sd < 0) { | 190 | if (*sd < 0) { |
187 | printf (_("Socket creation failed\n")); | 191 | printf (_("Socket creation failed\n")); |
188 | freeaddrinfo (res); | 192 | freeaddrinfo (r); |
189 | return STATE_UNKNOWN; | 193 | return STATE_UNKNOWN; |
190 | } | 194 | } |
191 | 195 | ||
192 | /* attempt to open a connection */ | 196 | /* attempt to open a connection */ |
193 | result = connect (*sd, res->ai_addr, res->ai_addrlen); | 197 | result = connect (*sd, r->ai_addr, r->ai_addrlen); |
194 | 198 | ||
195 | if (result == 0) { | 199 | if (result == 0) { |
196 | was_refused = FALSE; | 200 | was_refused = FALSE; |
@@ -206,9 +210,25 @@ np_net_connect (const char *host_name, int port, int *sd, int proto) | |||
206 | } | 210 | } |
207 | 211 | ||
208 | close (*sd); | 212 | close (*sd); |
209 | res = res->ai_next; | 213 | r = r->ai_next; |
214 | } | ||
215 | freeaddrinfo (res); | ||
216 | } | ||
217 | /* else the hostname is interpreted as a path to a unix socket */ | ||
218 | else { | ||
219 | if(strlen(host_name) >= UNIX_PATH_MAX){ | ||
220 | die(_("Supplied path too long unix domain socket")); | ||
221 | } | ||
222 | memset(&su, 0, sizeof(su)); | ||
223 | su.sun_family = AF_UNIX; | ||
224 | strncpy(su.sun_path, host_name, UNIX_PATH_MAX); | ||
225 | *sd = socket(PF_UNIX, SOCK_STREAM, 0); | ||
226 | if(sd < 0){ | ||
227 | die(_("Socket creation failed")); | ||
210 | } | 228 | } |
211 | freeaddrinfo (res0); | 229 | result = connect(*sd, (struct sockaddr *)&su, sizeof(su)); |
230 | if (result < 0 && errno == ECONNREFUSED) | ||
231 | was_refused = TRUE; | ||
212 | } | 232 | } |
213 | 233 | ||
214 | if (result == 0) | 234 | if (result == 0) |
diff --git a/plugins/netutils.h b/plugins/netutils.h index 9b0557d..8bc7bd6 100644 --- a/plugins/netutils.h +++ b/plugins/netutils.h | |||
@@ -40,6 +40,14 @@ | |||
40 | #include <netinet/in.h> | 40 | #include <netinet/in.h> |
41 | #include <arpa/inet.h> | 41 | #include <arpa/inet.h> |
42 | 42 | ||
43 | #ifdef HAVE_SYS_UN_H | ||
44 | # include <sys/un.h> | ||
45 | # ifndef UNIX_PATH_MAX | ||
46 | /* linux uses this, on sun it's hard-coded at 108 without a define */ | ||
47 | # define UNIX_PATH_MAX 108 | ||
48 | # endif /* UNIX_PATH_MAX */ | ||
49 | #endif /* HAVE_SYS_UN_H */ | ||
50 | |||
43 | RETSIGTYPE socket_timeout_alarm_handler (int) __attribute__((noreturn)); | 51 | RETSIGTYPE socket_timeout_alarm_handler (int) __attribute__((noreturn)); |
44 | 52 | ||
45 | /* process_request and wrapper macros */ | 53 | /* process_request and wrapper macros */ |
diff --git a/plugins/utils.h b/plugins/utils.h index ffdb545..2d97634 100644 --- a/plugins/utils.h +++ b/plugins/utils.h | |||
@@ -139,7 +139,7 @@ char *fperfdata (const char *, | |||
139 | 139 | ||
140 | #define UT_HOST_PORT "\ | 140 | #define UT_HOST_PORT "\ |
141 | -H, --hostname=ADDRESS\n\ | 141 | -H, --hostname=ADDRESS\n\ |
142 | Host name or IP Address\n\ | 142 | Host name, IP Address, or unix socket (must be an absolute path)\n\ |
143 | -%c, --port=INTEGER\n\ | 143 | -%c, --port=INTEGER\n\ |
144 | Port number (default: %s)\n" | 144 | Port number (default: %s)\n" |
145 | 145 | ||