diff options
| author | M. Sean Finney <seanius@users.sourceforge.net> | 2005-10-25 10:38:02 +0000 |
|---|---|---|
| committer | M. Sean Finney <seanius@users.sourceforge.net> | 2005-10-25 10:38:02 +0000 |
| commit | 16cd0c8151eee652d88b0b6f3aaa5b917cb87e13 (patch) | |
| tree | 9587540f51701d62d73670c6c1963f9119c793b5 /plugins/netutils.c | |
| parent | ceebd58040b1688749d58dd76963af639cf8c803 (diff) | |
| download | monitoring-plugins-16cd0c8151eee652d88b0b6f3aaa5b917cb87e13.tar.gz | |
- added code to allow check_tcp (via np_net_connect) work with local
unix sockets. some testing would be welcome. based on idea from
Alex Samorukov.
- also introduced a check_clamd behavior in check_tcp.
git-svn-id: https://nagiosplug.svn.sourceforge.net/svnroot/nagiosplug/nagiosplug/trunk@1261 f882894a-f735-0410-b71e-b25c423dba1c
Diffstat (limited to 'plugins/netutils.c')
| -rw-r--r-- | plugins/netutils.c | 64 |
1 files changed, 42 insertions, 22 deletions
diff --git a/plugins/netutils.c b/plugins/netutils.c index 08245276..6f3a1510 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) |
