diff options
Diffstat (limited to 'plugins/netutils.c')
-rw-r--r-- | plugins/netutils.c | 295 |
1 files changed, 144 insertions, 151 deletions
diff --git a/plugins/netutils.c b/plugins/netutils.c index c6af248e..e2916c65 100644 --- a/plugins/netutils.c +++ b/plugins/netutils.c | |||
@@ -1,33 +1,35 @@ | |||
1 | /***************************************************************************** | 1 | /***************************************************************************** |
2 | * | 2 | * |
3 | * Monitoring Plugins network utilities | 3 | * Monitoring Plugins network utilities |
4 | * | 4 | * |
5 | * License: GPL | 5 | * License: GPL |
6 | * Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) | 6 | * Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) |
7 | * Copyright (c) 2003-2008 Monitoring Plugins Development Team | 7 | * Copyright (c) 2003-2024 Monitoring Plugins Development Team |
8 | * | 8 | * |
9 | * Description: | 9 | * Description: |
10 | * | 10 | * |
11 | * This file contains commons functions used in many of the plugins. | 11 | * This file contains commons functions used in many of the plugins. |
12 | * | 12 | * |
13 | * | 13 | * |
14 | * This program is free software: you can redistribute it and/or modify | 14 | * This program is free software: you can redistribute it and/or modify |
15 | * it under the terms of the GNU General Public License as published by | 15 | * it under the terms of the GNU General Public License as published by |
16 | * the Free Software Foundation, either version 3 of the License, or | 16 | * the Free Software Foundation, either version 3 of the License, or |
17 | * (at your option) any later version. | 17 | * (at your option) any later version. |
18 | * | 18 | * |
19 | * This program is distributed in the hope that it will be useful, | 19 | * This program is distributed in the hope that it will be useful, |
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
22 | * GNU General Public License for more details. | 22 | * GNU General Public License for more details. |
23 | * | 23 | * |
24 | * You should have received a copy of the GNU General Public License | 24 | * You should have received a copy of the GNU General Public License |
25 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 25 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
26 | * | 26 | * |
27 | * | 27 | * |
28 | *****************************************************************************/ | 28 | *****************************************************************************/ |
29 | 29 | ||
30 | #include "common.h" | 30 | #include "common.h" |
31 | #include "output.h" | ||
32 | #include "states.h" | ||
31 | #include "netutils.h" | 33 | #include "netutils.h" |
32 | 34 | ||
33 | unsigned int socket_timeout = DEFAULT_SOCKET_TIMEOUT; | 35 | unsigned int socket_timeout = DEFAULT_SOCKET_TIMEOUT; |
@@ -42,25 +44,26 @@ int address_family = AF_INET; | |||
42 | #endif | 44 | #endif |
43 | 45 | ||
44 | /* handles socket timeouts */ | 46 | /* handles socket timeouts */ |
45 | void | 47 | void socket_timeout_alarm_handler(int sig) { |
46 | socket_timeout_alarm_handler (int sig) | 48 | mp_subcheck timeout_sc = mp_subcheck_init(); |
47 | { | 49 | timeout_sc = mp_set_subcheck_state(timeout_sc, socket_timeout_state); |
48 | if (sig == SIGALRM) | 50 | |
49 | printf (_("%s - Socket timeout after %d seconds\n"), state_text(socket_timeout_state), socket_timeout); | 51 | if (sig == SIGALRM) { |
50 | else | 52 | xasprintf(&timeout_sc.output, _("Socket timeout after %d seconds\n"), socket_timeout); |
51 | printf (_("%s - Abnormal timeout after %d seconds\n"), state_text(socket_timeout_state), socket_timeout); | 53 | } else { |
52 | 54 | xasprintf(&timeout_sc.output, _("Abnormal timeout after %d seconds\n"), socket_timeout); | |
53 | exit (socket_timeout_state); | 55 | } |
54 | } | ||
55 | 56 | ||
57 | mp_check overall = mp_check_init(); | ||
58 | mp_add_subcheck_to_check(&overall, timeout_sc); | ||
59 | |||
60 | mp_exit(overall); | ||
61 | } | ||
56 | 62 | ||
57 | /* connects to a host on a specified tcp port, sends a string, and gets a | 63 | /* connects to a host on a specified tcp port, sends a string, and gets a |
58 | response. loops on select-recv until timeout or eof to get all of a | 64 | response. loops on select-recv until timeout or eof to get all of a |
59 | multi-packet answer */ | 65 | multi-packet answer */ |
60 | int | 66 | int process_tcp_request2(const char *server_address, int server_port, const char *send_buffer, char *recv_buffer, int recv_size) { |
61 | process_tcp_request2 (const char *server_address, int server_port, | ||
62 | const char *send_buffer, char *recv_buffer, int recv_size) | ||
63 | { | ||
64 | 67 | ||
65 | int result; | 68 | int result; |
66 | int send_result; | 69 | int send_result; |
@@ -70,13 +73,14 @@ process_tcp_request2 (const char *server_address, int server_port, | |||
70 | fd_set readfds; | 73 | fd_set readfds; |
71 | int recv_length = 0; | 74 | int recv_length = 0; |
72 | 75 | ||
73 | result = np_net_connect (server_address, server_port, &sd, IPPROTO_TCP); | 76 | result = np_net_connect(server_address, server_port, &sd, IPPROTO_TCP); |
74 | if (result != STATE_OK) | 77 | if (result != STATE_OK) { |
75 | return STATE_CRITICAL; | 78 | return STATE_CRITICAL; |
79 | } | ||
76 | 80 | ||
77 | send_result = send (sd, send_buffer, strlen (send_buffer), 0); | 81 | send_result = send(sd, send_buffer, strlen(send_buffer), 0); |
78 | if (send_result<0 || (size_t)send_result!=strlen(send_buffer)) { | 82 | if (send_result < 0 || (size_t)send_result != strlen(send_buffer)) { |
79 | printf ("%s\n", _("Send failed")); | 83 | // printf("%s\n", _("Send failed")); |
80 | result = STATE_WARNING; | 84 | result = STATE_WARNING; |
81 | } | 85 | } |
82 | 86 | ||
@@ -85,38 +89,32 @@ process_tcp_request2 (const char *server_address, int server_port, | |||
85 | minus one for data from the host */ | 89 | minus one for data from the host */ |
86 | tv.tv_sec = socket_timeout - 1; | 90 | tv.tv_sec = socket_timeout - 1; |
87 | tv.tv_usec = 0; | 91 | tv.tv_usec = 0; |
88 | FD_ZERO (&readfds); | 92 | FD_ZERO(&readfds); |
89 | FD_SET (sd, &readfds); | 93 | FD_SET(sd, &readfds); |
90 | select (sd + 1, &readfds, NULL, NULL, &tv); | 94 | select(sd + 1, &readfds, NULL, NULL, &tv); |
91 | 95 | ||
92 | /* make sure some data has arrived */ | 96 | /* make sure some data has arrived */ |
93 | if (!FD_ISSET (sd, &readfds)) { /* it hasn't */ | 97 | if (!FD_ISSET(sd, &readfds)) { /* it hasn't */ |
94 | if (!recv_length) { | 98 | if (!recv_length) { |
95 | strcpy (recv_buffer, ""); | 99 | strcpy(recv_buffer, ""); |
96 | printf ("%s\n", _("No data was received from host!")); | 100 | // printf("%s\n", _("No data was received from host!")); |
97 | result = STATE_WARNING; | 101 | result = STATE_WARNING; |
98 | } | 102 | } else { /* this one failed, but previous ones worked */ |
99 | else { /* this one failed, but previous ones worked */ | ||
100 | recv_buffer[recv_length] = 0; | 103 | recv_buffer[recv_length] = 0; |
101 | } | 104 | } |
102 | break; | 105 | break; |
103 | } | 106 | } else { /* it has */ |
104 | else { /* it has */ | 107 | recv_result = recv(sd, recv_buffer + recv_length, (size_t)recv_size - recv_length - 1, 0); |
105 | recv_result = | ||
106 | recv (sd, recv_buffer + recv_length, | ||
107 | (size_t)recv_size - recv_length - 1, 0); | ||
108 | if (recv_result == -1) { | 108 | if (recv_result == -1) { |
109 | /* recv failed, bail out */ | 109 | /* recv failed, bail out */ |
110 | strcpy (recv_buffer + recv_length, ""); | 110 | strcpy(recv_buffer + recv_length, ""); |
111 | result = STATE_WARNING; | 111 | result = STATE_WARNING; |
112 | break; | 112 | break; |
113 | } | 113 | } else if (recv_result == 0) { |
114 | else if (recv_result == 0) { | ||
115 | /* end of file ? */ | 114 | /* end of file ? */ |
116 | recv_buffer[recv_length] = 0; | 115 | recv_buffer[recv_length] = 0; |
117 | break; | 116 | break; |
118 | } | 117 | } else { /* we got data! */ |
119 | else { /* we got data! */ | ||
120 | recv_length += recv_result; | 118 | recv_length += recv_result; |
121 | if (recv_length >= recv_size - 1) { | 119 | if (recv_length >= recv_size - 1) { |
122 | /* buffer full, we're done */ | 120 | /* buffer full, we're done */ |
@@ -129,42 +127,36 @@ process_tcp_request2 (const char *server_address, int server_port, | |||
129 | } | 127 | } |
130 | /* end while(1) */ | 128 | /* end while(1) */ |
131 | 129 | ||
132 | close (sd); | 130 | close(sd); |
133 | return result; | 131 | return result; |
134 | } | 132 | } |
135 | 133 | ||
136 | |||
137 | /* connects to a host on a specified port, sends a string, and gets a | 134 | /* connects to a host on a specified port, sends a string, and gets a |
138 | response */ | 135 | response */ |
139 | int | 136 | int process_request(const char *server_address, int server_port, int proto, const char *send_buffer, char *recv_buffer, int recv_size) { |
140 | process_request (const char *server_address, int server_port, int proto, | ||
141 | const char *send_buffer, char *recv_buffer, int recv_size) | ||
142 | { | ||
143 | int result; | 137 | int result; |
144 | int sd; | 138 | int sd; |
145 | 139 | ||
146 | result = STATE_OK; | 140 | result = STATE_OK; |
147 | 141 | ||
148 | result = np_net_connect (server_address, server_port, &sd, proto); | 142 | result = np_net_connect(server_address, server_port, &sd, proto); |
149 | if (result != STATE_OK) | 143 | if (result != STATE_OK) { |
150 | return STATE_CRITICAL; | 144 | return STATE_CRITICAL; |
145 | } | ||
151 | 146 | ||
152 | result = send_request (sd, proto, send_buffer, recv_buffer, recv_size); | 147 | result = send_request(sd, proto, send_buffer, recv_buffer, recv_size); |
153 | 148 | ||
154 | close (sd); | 149 | close(sd); |
155 | 150 | ||
156 | return result; | 151 | return result; |
157 | } | 152 | } |
158 | 153 | ||
159 | |||
160 | /* opens a tcp or udp connection to a remote host or local socket */ | 154 | /* opens a tcp or udp connection to a remote host or local socket */ |
161 | int | 155 | int np_net_connect(const char *host_name, int port, int *sd, int proto) { |
162 | np_net_connect (const char *host_name, int port, int *sd, int proto) | 156 | /* send back STATE_UNKOWN if there's an error |
163 | { | 157 | send back STATE_OK if we connect |
164 | /* send back STATE_UNKOWN if there's an error | 158 | send back STATE_CRITICAL if we can't connect. |
165 | send back STATE_OK if we connect | 159 | Let upstream figure out what to send to the user. */ |
166 | send back STATE_CRITICAL if we can't connect. | ||
167 | Let upstream figure out what to send to the user. */ | ||
168 | struct addrinfo hints; | 160 | struct addrinfo hints; |
169 | struct addrinfo *r, *res; | 161 | struct addrinfo *r, *res; |
170 | struct sockaddr_un su; | 162 | struct sockaddr_un su; |
@@ -176,43 +168,44 @@ np_net_connect (const char *host_name, int port, int *sd, int proto) | |||
176 | socktype = (proto == IPPROTO_UDP) ? SOCK_DGRAM : SOCK_STREAM; | 168 | socktype = (proto == IPPROTO_UDP) ? SOCK_DGRAM : SOCK_STREAM; |
177 | 169 | ||
178 | /* as long as it doesn't start with a '/', it's assumed a host or ip */ | 170 | /* as long as it doesn't start with a '/', it's assumed a host or ip */ |
179 | if (!is_socket){ | 171 | if (!is_socket) { |
180 | memset (&hints, 0, sizeof (hints)); | 172 | memset(&hints, 0, sizeof(hints)); |
181 | hints.ai_family = address_family; | 173 | hints.ai_family = address_family; |
182 | hints.ai_protocol = proto; | 174 | hints.ai_protocol = proto; |
183 | hints.ai_socktype = socktype; | 175 | hints.ai_socktype = socktype; |
184 | 176 | ||
185 | len = strlen (host_name); | 177 | len = strlen(host_name); |
186 | /* check for an [IPv6] address (and strip the brackets) */ | 178 | /* check for an [IPv6] address (and strip the brackets) */ |
187 | if (len >= 2 && host_name[0] == '[' && host_name[len - 1] == ']') { | 179 | if (len >= 2 && host_name[0] == '[' && host_name[len - 1] == ']') { |
188 | host_name++; | 180 | host_name++; |
189 | len -= 2; | 181 | len -= 2; |
190 | } | 182 | } |
191 | if (len >= sizeof(host)) | 183 | if (len >= sizeof(host)) { |
192 | return STATE_UNKNOWN; | 184 | return STATE_UNKNOWN; |
193 | memcpy (host, host_name, len); | 185 | } |
186 | memcpy(host, host_name, len); | ||
194 | host[len] = '\0'; | 187 | host[len] = '\0'; |
195 | snprintf (port_str, sizeof (port_str), "%d", port); | 188 | snprintf(port_str, sizeof(port_str), "%d", port); |
196 | result = getaddrinfo (host, port_str, &hints, &res); | 189 | result = getaddrinfo(host, port_str, &hints, &res); |
197 | 190 | ||
198 | if (result != 0) { | 191 | if (result != 0) { |
199 | printf ("%s\n", gai_strerror (result)); | 192 | // printf("%s\n", gai_strerror(result)); |
200 | return STATE_UNKNOWN; | 193 | return STATE_UNKNOWN; |
201 | } | 194 | } |
202 | 195 | ||
203 | r = res; | 196 | r = res; |
204 | while (r) { | 197 | while (r) { |
205 | /* attempt to create a socket */ | 198 | /* attempt to create a socket */ |
206 | *sd = socket (r->ai_family, socktype, r->ai_protocol); | 199 | *sd = socket(r->ai_family, socktype, r->ai_protocol); |
207 | 200 | ||
208 | if (*sd < 0) { | 201 | if (*sd < 0) { |
209 | printf ("%s\n", _("Socket creation failed")); | 202 | // printf("%s\n", _("Socket creation failed")); |
210 | freeaddrinfo (r); | 203 | freeaddrinfo(r); |
211 | return STATE_UNKNOWN; | 204 | return STATE_UNKNOWN; |
212 | } | 205 | } |
213 | 206 | ||
214 | /* attempt to open a connection */ | 207 | /* attempt to open a connection */ |
215 | result = connect (*sd, r->ai_addr, r->ai_addrlen); | 208 | result = connect(*sd, r->ai_addr, r->ai_addrlen); |
216 | 209 | ||
217 | if (result == 0) { | 210 | if (result == 0) { |
218 | was_refused = false; | 211 | was_refused = false; |
@@ -227,69 +220,67 @@ np_net_connect (const char *host_name, int port, int *sd, int proto) | |||
227 | } | 220 | } |
228 | } | 221 | } |
229 | 222 | ||
230 | close (*sd); | 223 | close(*sd); |
231 | r = r->ai_next; | 224 | r = r->ai_next; |
232 | } | 225 | } |
233 | freeaddrinfo (res); | 226 | freeaddrinfo(res); |
234 | } | 227 | } |
235 | /* else the hostname is interpreted as a path to a unix socket */ | 228 | /* else the hostname is interpreted as a path to a unix socket */ |
236 | else { | 229 | else { |
237 | if(strlen(host_name) >= UNIX_PATH_MAX){ | 230 | if (strlen(host_name) >= UNIX_PATH_MAX) { |
238 | die(STATE_UNKNOWN, _("Supplied path too long unix domain socket")); | 231 | die(STATE_UNKNOWN, _("Supplied path too long unix domain socket")); |
239 | } | 232 | } |
240 | memset(&su, 0, sizeof(su)); | 233 | memset(&su, 0, sizeof(su)); |
241 | su.sun_family = AF_UNIX; | 234 | su.sun_family = AF_UNIX; |
242 | strncpy(su.sun_path, host_name, UNIX_PATH_MAX); | 235 | strncpy(su.sun_path, host_name, UNIX_PATH_MAX); |
243 | *sd = socket(PF_UNIX, SOCK_STREAM, 0); | 236 | *sd = socket(PF_UNIX, SOCK_STREAM, 0); |
244 | if(*sd < 0){ | 237 | if (*sd < 0) { |
245 | die(STATE_UNKNOWN, _("Socket creation failed")); | 238 | die(STATE_UNKNOWN, _("Socket creation failed")); |
246 | } | 239 | } |
247 | result = connect(*sd, (struct sockaddr *)&su, sizeof(su)); | 240 | result = connect(*sd, (struct sockaddr *)&su, sizeof(su)); |
248 | if (result < 0 && errno == ECONNREFUSED) | 241 | if (result < 0 && errno == ECONNREFUSED) { |
249 | was_refused = true; | 242 | was_refused = true; |
243 | } | ||
250 | } | 244 | } |
251 | 245 | ||
252 | if (result == 0) | 246 | if (result == 0) { |
253 | return STATE_OK; | 247 | return STATE_OK; |
254 | else if (was_refused) { | 248 | } else if (was_refused) { |
255 | switch (econn_refuse_state) { /* a user-defined expected outcome */ | 249 | switch (econn_refuse_state) { /* a user-defined expected outcome */ |
256 | case STATE_OK: | 250 | case STATE_OK: |
257 | case STATE_WARNING: /* user wants WARN or OK on refusal, or... */ | 251 | case STATE_WARNING: /* user wants WARN or OK on refusal, or... */ |
258 | case STATE_CRITICAL: /* user did not set econn_refuse_state, or wanted critical */ | 252 | case STATE_CRITICAL: /* user did not set econn_refuse_state, or wanted critical */ |
259 | if (is_socket) | 253 | if (is_socket) { |
260 | printf("connect to file socket %s: %s\n", host_name, strerror(errno)); | 254 | // printf("connect to file socket %s: %s\n", host_name, strerror(errno)); |
261 | else | 255 | } else { |
262 | printf("connect to address %s and port %d: %s\n", | 256 | // printf("connect to address %s and port %d: %s\n", host_name, port, strerror(errno)); |
263 | host_name, port, strerror(errno)); | 257 | } |
264 | return STATE_CRITICAL; | 258 | return STATE_CRITICAL; |
265 | break; | 259 | break; |
266 | default: /* it's a logic error if we do not end up in STATE_(OK|WARNING|CRITICAL) */ | 260 | default: /* it's a logic error if we do not end up in STATE_(OK|WARNING|CRITICAL) */ |
267 | return STATE_UNKNOWN; | 261 | return STATE_UNKNOWN; |
268 | break; | 262 | break; |
269 | } | 263 | } |
270 | } | 264 | } else { |
271 | else { | 265 | if (is_socket) { |
272 | if (is_socket) | 266 | // printf("connect to file socket %s: %s\n", host_name, strerror(errno)); |
273 | printf("connect to file socket %s: %s\n", host_name, strerror(errno)); | 267 | } else { |
274 | else | 268 | // printf("connect to address %s and port %d: %s\n", host_name, port, strerror(errno)); |
275 | printf("connect to address %s and port %d: %s\n", | 269 | } |
276 | host_name, port, strerror(errno)); | ||
277 | return STATE_CRITICAL; | 270 | return STATE_CRITICAL; |
278 | } | 271 | } |
279 | } | 272 | } |
280 | 273 | ||
281 | int | 274 | int send_request(int sd, int proto, const char *send_buffer, char *recv_buffer, int recv_size) { |
282 | send_request (int sd, int proto, const char *send_buffer, char *recv_buffer, int recv_size) | ||
283 | { | ||
284 | int result = STATE_OK; | 275 | int result = STATE_OK; |
285 | int send_result; | 276 | int send_result; |
286 | int recv_result; | 277 | int recv_result; |
287 | struct timeval tv; | 278 | struct timeval tv; |
288 | fd_set readfds; | 279 | fd_set readfds; |
289 | 280 | ||
290 | send_result = send (sd, send_buffer, strlen (send_buffer), 0); | 281 | send_result = send(sd, send_buffer, strlen(send_buffer), 0); |
291 | if (send_result<0 || (size_t)send_result!=strlen(send_buffer)) { | 282 | if (send_result < 0 || (size_t)send_result != strlen(send_buffer)) { |
292 | printf ("%s\n", _("Send failed")); | 283 | // printf("%s\n", _("Send failed")); |
293 | result = STATE_WARNING; | 284 | result = STATE_WARNING; |
294 | } | 285 | } |
295 | 286 | ||
@@ -297,27 +288,28 @@ send_request (int sd, int proto, const char *send_buffer, char *recv_buffer, int | |||
297 | for data from the host */ | 288 | for data from the host */ |
298 | tv.tv_sec = socket_timeout - 1; | 289 | tv.tv_sec = socket_timeout - 1; |
299 | tv.tv_usec = 0; | 290 | tv.tv_usec = 0; |
300 | FD_ZERO (&readfds); | 291 | FD_ZERO(&readfds); |
301 | FD_SET (sd, &readfds); | 292 | FD_SET(sd, &readfds); |
302 | select (sd + 1, &readfds, NULL, NULL, &tv); | 293 | select(sd + 1, &readfds, NULL, NULL, &tv); |
303 | 294 | ||
304 | /* make sure some data has arrived */ | 295 | /* make sure some data has arrived */ |
305 | if (!FD_ISSET (sd, &readfds)) { | 296 | if (!FD_ISSET(sd, &readfds)) { |
306 | strcpy (recv_buffer, ""); | 297 | strcpy(recv_buffer, ""); |
307 | printf ("%s\n", _("No data was received from host!")); | 298 | // printf("%s\n", _("No data was received from host!")); |
308 | result = STATE_WARNING; | 299 | result = STATE_WARNING; |
309 | } | 300 | } |
310 | 301 | ||
311 | else { | 302 | else { |
312 | recv_result = recv (sd, recv_buffer, (size_t)recv_size - 1, 0); | 303 | recv_result = recv(sd, recv_buffer, (size_t)recv_size - 1, 0); |
313 | if (recv_result == -1) { | 304 | if (recv_result == -1) { |
314 | strcpy (recv_buffer, ""); | 305 | strcpy(recv_buffer, ""); |
315 | if (proto != IPPROTO_TCP) | 306 | if (proto != IPPROTO_TCP) { |
316 | printf ("%s\n", _("Receive failed")); | 307 | // printf("%s\n", _("Receive failed")); |
308 | } | ||
317 | result = STATE_WARNING; | 309 | result = STATE_WARNING; |
318 | } | 310 | } else { |
319 | else | ||
320 | recv_buffer[recv_result] = 0; | 311 | recv_buffer[recv_result] = 0; |
312 | } | ||
321 | 313 | ||
322 | /* die returned string */ | 314 | /* die returned string */ |
323 | recv_buffer[recv_size - 1] = 0; | 315 | recv_buffer[recv_size - 1] = 0; |
@@ -325,51 +317,52 @@ send_request (int sd, int proto, const char *send_buffer, char *recv_buffer, int | |||
325 | return result; | 317 | return result; |
326 | } | 318 | } |
327 | 319 | ||
328 | 320 | bool is_host(const char *address) { | |
329 | bool is_host (const char *address) { | 321 | if (is_addr(address) || is_hostname(address)) { |
330 | if (is_addr (address) || is_hostname (address)) | ||
331 | return (true); | 322 | return (true); |
323 | } | ||
332 | 324 | ||
333 | return (false); | 325 | return (false); |
334 | } | 326 | } |
335 | 327 | ||
336 | void | 328 | void host_or_die(const char *str) { |
337 | host_or_die(const char *str) | 329 | if (!str || (!is_addr(str) && !is_hostname(str))) { |
338 | { | ||
339 | if(!str || (!is_addr(str) && !is_hostname(str))) | ||
340 | usage_va(_("Invalid hostname/address - %s"), str); | 330 | usage_va(_("Invalid hostname/address - %s"), str); |
331 | } | ||
341 | } | 332 | } |
342 | 333 | ||
343 | bool is_addr (const char *address) { | 334 | bool is_addr(const char *address) { |
344 | #ifdef USE_IPV6 | 335 | #ifdef USE_IPV6 |
345 | if (address_family == AF_INET && is_inet_addr (address)) | 336 | if (address_family == AF_INET && is_inet_addr(address)) { |
346 | return true; | 337 | return true; |
347 | else if (address_family == AF_INET6 && is_inet6_addr (address)) | 338 | } else if (address_family == AF_INET6 && is_inet6_addr(address)) { |
348 | return true; | 339 | return true; |
340 | } | ||
349 | #else | 341 | #else |
350 | if (is_inet_addr (address)) | 342 | if (is_inet_addr(address)) { |
351 | return (true); | 343 | return (true); |
344 | } | ||
352 | #endif | 345 | #endif |
353 | 346 | ||
354 | return (false); | 347 | return (false); |
355 | } | 348 | } |
356 | 349 | ||
357 | int | 350 | int dns_lookup(const char *in, struct sockaddr_storage *ss, int family) { |
358 | dns_lookup (const char *in, struct sockaddr_storage *ss, int family) | ||
359 | { | ||
360 | struct addrinfo hints; | 351 | struct addrinfo hints; |
361 | struct addrinfo *res; | 352 | struct addrinfo *res; |
362 | int retval; | 353 | int retval; |
363 | 354 | ||
364 | memset (&hints, 0, sizeof(struct addrinfo)); | 355 | memset(&hints, 0, sizeof(struct addrinfo)); |
365 | hints.ai_family = family; | 356 | hints.ai_family = family; |
366 | 357 | ||
367 | retval = getaddrinfo (in, NULL, &hints, &res); | 358 | retval = getaddrinfo(in, NULL, &hints, &res); |
368 | if (retval != 0) | 359 | if (retval != 0) { |
369 | return false; | 360 | return false; |
361 | } | ||
370 | 362 | ||
371 | if (ss != NULL) | 363 | if (ss != NULL) { |
372 | memcpy (ss, res->ai_addr, res->ai_addrlen); | 364 | memcpy(ss, res->ai_addr, res->ai_addrlen); |
373 | freeaddrinfo (res); | 365 | } |
366 | freeaddrinfo(res); | ||
374 | return true; | 367 | return true; |
375 | } | 368 | } |