diff options
Diffstat (limited to 'plugins/netutils.c')
-rw-r--r-- | plugins/netutils.c | 236 |
1 files changed, 103 insertions, 133 deletions
diff --git a/plugins/netutils.c b/plugins/netutils.c index c6af248..ee81912 100644 --- a/plugins/netutils.c +++ b/plugins/netutils.c | |||
@@ -1,31 +1,31 @@ | |||
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 "netutils.h" | 31 | #include "netutils.h" |
@@ -42,25 +42,19 @@ int address_family = AF_INET; | |||
42 | #endif | 42 | #endif |
43 | 43 | ||
44 | /* handles socket timeouts */ | 44 | /* handles socket timeouts */ |
45 | void | 45 | void socket_timeout_alarm_handler(int sig) { |
46 | socket_timeout_alarm_handler (int sig) | ||
47 | { | ||
48 | if (sig == SIGALRM) | 46 | if (sig == SIGALRM) |
49 | printf (_("%s - Socket timeout after %d seconds\n"), state_text(socket_timeout_state), socket_timeout); | 47 | printf(_("%s - Socket timeout after %d seconds\n"), state_text(socket_timeout_state), socket_timeout); |
50 | else | 48 | else |
51 | printf (_("%s - Abnormal timeout after %d seconds\n"), state_text(socket_timeout_state), socket_timeout); | 49 | printf(_("%s - Abnormal timeout after %d seconds\n"), state_text(socket_timeout_state), socket_timeout); |
52 | 50 | ||
53 | exit (socket_timeout_state); | 51 | exit(socket_timeout_state); |
54 | } | 52 | } |
55 | 53 | ||
56 | |||
57 | /* connects to a host on a specified tcp port, sends a string, and gets a | 54 | /* 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 | 55 | response. loops on select-recv until timeout or eof to get all of a |
59 | multi-packet answer */ | 56 | multi-packet answer */ |
60 | int | 57 | 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 | 58 | ||
65 | int result; | 59 | int result; |
66 | int send_result; | 60 | int send_result; |
@@ -70,13 +64,13 @@ process_tcp_request2 (const char *server_address, int server_port, | |||
70 | fd_set readfds; | 64 | fd_set readfds; |
71 | int recv_length = 0; | 65 | int recv_length = 0; |
72 | 66 | ||
73 | result = np_net_connect (server_address, server_port, &sd, IPPROTO_TCP); | 67 | result = np_net_connect(server_address, server_port, &sd, IPPROTO_TCP); |
74 | if (result != STATE_OK) | 68 | if (result != STATE_OK) |
75 | return STATE_CRITICAL; | 69 | return STATE_CRITICAL; |
76 | 70 | ||
77 | send_result = send (sd, send_buffer, strlen (send_buffer), 0); | 71 | send_result = send(sd, send_buffer, strlen(send_buffer), 0); |
78 | if (send_result<0 || (size_t)send_result!=strlen(send_buffer)) { | 72 | if (send_result < 0 || (size_t)send_result != strlen(send_buffer)) { |
79 | printf ("%s\n", _("Send failed")); | 73 | printf("%s\n", _("Send failed")); |
80 | result = STATE_WARNING; | 74 | result = STATE_WARNING; |
81 | } | 75 | } |
82 | 76 | ||
@@ -85,38 +79,32 @@ process_tcp_request2 (const char *server_address, int server_port, | |||
85 | minus one for data from the host */ | 79 | minus one for data from the host */ |
86 | tv.tv_sec = socket_timeout - 1; | 80 | tv.tv_sec = socket_timeout - 1; |
87 | tv.tv_usec = 0; | 81 | tv.tv_usec = 0; |
88 | FD_ZERO (&readfds); | 82 | FD_ZERO(&readfds); |
89 | FD_SET (sd, &readfds); | 83 | FD_SET(sd, &readfds); |
90 | select (sd + 1, &readfds, NULL, NULL, &tv); | 84 | select(sd + 1, &readfds, NULL, NULL, &tv); |
91 | 85 | ||
92 | /* make sure some data has arrived */ | 86 | /* make sure some data has arrived */ |
93 | if (!FD_ISSET (sd, &readfds)) { /* it hasn't */ | 87 | if (!FD_ISSET(sd, &readfds)) { /* it hasn't */ |
94 | if (!recv_length) { | 88 | if (!recv_length) { |
95 | strcpy (recv_buffer, ""); | 89 | strcpy(recv_buffer, ""); |
96 | printf ("%s\n", _("No data was received from host!")); | 90 | printf("%s\n", _("No data was received from host!")); |
97 | result = STATE_WARNING; | 91 | result = STATE_WARNING; |
98 | } | 92 | } else { /* this one failed, but previous ones worked */ |
99 | else { /* this one failed, but previous ones worked */ | ||
100 | recv_buffer[recv_length] = 0; | 93 | recv_buffer[recv_length] = 0; |
101 | } | 94 | } |
102 | break; | 95 | break; |
103 | } | 96 | } else { /* it has */ |
104 | else { /* it has */ | 97 | 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) { | 98 | if (recv_result == -1) { |
109 | /* recv failed, bail out */ | 99 | /* recv failed, bail out */ |
110 | strcpy (recv_buffer + recv_length, ""); | 100 | strcpy(recv_buffer + recv_length, ""); |
111 | result = STATE_WARNING; | 101 | result = STATE_WARNING; |
112 | break; | 102 | break; |
113 | } | 103 | } else if (recv_result == 0) { |
114 | else if (recv_result == 0) { | ||
115 | /* end of file ? */ | 104 | /* end of file ? */ |
116 | recv_buffer[recv_length] = 0; | 105 | recv_buffer[recv_length] = 0; |
117 | break; | 106 | break; |
118 | } | 107 | } else { /* we got data! */ |
119 | else { /* we got data! */ | ||
120 | recv_length += recv_result; | 108 | recv_length += recv_result; |
121 | if (recv_length >= recv_size - 1) { | 109 | if (recv_length >= recv_size - 1) { |
122 | /* buffer full, we're done */ | 110 | /* buffer full, we're done */ |
@@ -129,42 +117,35 @@ process_tcp_request2 (const char *server_address, int server_port, | |||
129 | } | 117 | } |
130 | /* end while(1) */ | 118 | /* end while(1) */ |
131 | 119 | ||
132 | close (sd); | 120 | close(sd); |
133 | return result; | 121 | return result; |
134 | } | 122 | } |
135 | 123 | ||
136 | |||
137 | /* connects to a host on a specified port, sends a string, and gets a | 124 | /* connects to a host on a specified port, sends a string, and gets a |
138 | response */ | 125 | response */ |
139 | int | 126 | 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; | 127 | int result; |
144 | int sd; | 128 | int sd; |
145 | 129 | ||
146 | result = STATE_OK; | 130 | result = STATE_OK; |
147 | 131 | ||
148 | result = np_net_connect (server_address, server_port, &sd, proto); | 132 | result = np_net_connect(server_address, server_port, &sd, proto); |
149 | if (result != STATE_OK) | 133 | if (result != STATE_OK) |
150 | return STATE_CRITICAL; | 134 | return STATE_CRITICAL; |
151 | 135 | ||
152 | result = send_request (sd, proto, send_buffer, recv_buffer, recv_size); | 136 | result = send_request(sd, proto, send_buffer, recv_buffer, recv_size); |
153 | 137 | ||
154 | close (sd); | 138 | close(sd); |
155 | 139 | ||
156 | return result; | 140 | return result; |
157 | } | 141 | } |
158 | 142 | ||
159 | |||
160 | /* opens a tcp or udp connection to a remote host or local socket */ | 143 | /* opens a tcp or udp connection to a remote host or local socket */ |
161 | int | 144 | 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) | 145 | /* send back STATE_UNKOWN if there's an error |
163 | { | 146 | send back STATE_OK if we connect |
164 | /* send back STATE_UNKOWN if there's an error | 147 | send back STATE_CRITICAL if we can't connect. |
165 | send back STATE_OK if we connect | 148 | 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; | 149 | struct addrinfo hints; |
169 | struct addrinfo *r, *res; | 150 | struct addrinfo *r, *res; |
170 | struct sockaddr_un su; | 151 | struct sockaddr_un su; |
@@ -176,13 +157,13 @@ np_net_connect (const char *host_name, int port, int *sd, int proto) | |||
176 | socktype = (proto == IPPROTO_UDP) ? SOCK_DGRAM : SOCK_STREAM; | 157 | socktype = (proto == IPPROTO_UDP) ? SOCK_DGRAM : SOCK_STREAM; |
177 | 158 | ||
178 | /* as long as it doesn't start with a '/', it's assumed a host or ip */ | 159 | /* as long as it doesn't start with a '/', it's assumed a host or ip */ |
179 | if (!is_socket){ | 160 | if (!is_socket) { |
180 | memset (&hints, 0, sizeof (hints)); | 161 | memset(&hints, 0, sizeof(hints)); |
181 | hints.ai_family = address_family; | 162 | hints.ai_family = address_family; |
182 | hints.ai_protocol = proto; | 163 | hints.ai_protocol = proto; |
183 | hints.ai_socktype = socktype; | 164 | hints.ai_socktype = socktype; |
184 | 165 | ||
185 | len = strlen (host_name); | 166 | len = strlen(host_name); |
186 | /* check for an [IPv6] address (and strip the brackets) */ | 167 | /* check for an [IPv6] address (and strip the brackets) */ |
187 | if (len >= 2 && host_name[0] == '[' && host_name[len - 1] == ']') { | 168 | if (len >= 2 && host_name[0] == '[' && host_name[len - 1] == ']') { |
188 | host_name++; | 169 | host_name++; |
@@ -190,29 +171,29 @@ np_net_connect (const char *host_name, int port, int *sd, int proto) | |||
190 | } | 171 | } |
191 | if (len >= sizeof(host)) | 172 | if (len >= sizeof(host)) |
192 | return STATE_UNKNOWN; | 173 | return STATE_UNKNOWN; |
193 | memcpy (host, host_name, len); | 174 | memcpy(host, host_name, len); |
194 | host[len] = '\0'; | 175 | host[len] = '\0'; |
195 | snprintf (port_str, sizeof (port_str), "%d", port); | 176 | snprintf(port_str, sizeof(port_str), "%d", port); |
196 | result = getaddrinfo (host, port_str, &hints, &res); | 177 | result = getaddrinfo(host, port_str, &hints, &res); |
197 | 178 | ||
198 | if (result != 0) { | 179 | if (result != 0) { |
199 | printf ("%s\n", gai_strerror (result)); | 180 | printf("%s\n", gai_strerror(result)); |
200 | return STATE_UNKNOWN; | 181 | return STATE_UNKNOWN; |
201 | } | 182 | } |
202 | 183 | ||
203 | r = res; | 184 | r = res; |
204 | while (r) { | 185 | while (r) { |
205 | /* attempt to create a socket */ | 186 | /* attempt to create a socket */ |
206 | *sd = socket (r->ai_family, socktype, r->ai_protocol); | 187 | *sd = socket(r->ai_family, socktype, r->ai_protocol); |
207 | 188 | ||
208 | if (*sd < 0) { | 189 | if (*sd < 0) { |
209 | printf ("%s\n", _("Socket creation failed")); | 190 | printf("%s\n", _("Socket creation failed")); |
210 | freeaddrinfo (r); | 191 | freeaddrinfo(r); |
211 | return STATE_UNKNOWN; | 192 | return STATE_UNKNOWN; |
212 | } | 193 | } |
213 | 194 | ||
214 | /* attempt to open a connection */ | 195 | /* attempt to open a connection */ |
215 | result = connect (*sd, r->ai_addr, r->ai_addrlen); | 196 | result = connect(*sd, r->ai_addr, r->ai_addrlen); |
216 | 197 | ||
217 | if (result == 0) { | 198 | if (result == 0) { |
218 | was_refused = false; | 199 | was_refused = false; |
@@ -227,21 +208,21 @@ np_net_connect (const char *host_name, int port, int *sd, int proto) | |||
227 | } | 208 | } |
228 | } | 209 | } |
229 | 210 | ||
230 | close (*sd); | 211 | close(*sd); |
231 | r = r->ai_next; | 212 | r = r->ai_next; |
232 | } | 213 | } |
233 | freeaddrinfo (res); | 214 | freeaddrinfo(res); |
234 | } | 215 | } |
235 | /* else the hostname is interpreted as a path to a unix socket */ | 216 | /* else the hostname is interpreted as a path to a unix socket */ |
236 | else { | 217 | else { |
237 | if(strlen(host_name) >= UNIX_PATH_MAX){ | 218 | if (strlen(host_name) >= UNIX_PATH_MAX) { |
238 | die(STATE_UNKNOWN, _("Supplied path too long unix domain socket")); | 219 | die(STATE_UNKNOWN, _("Supplied path too long unix domain socket")); |
239 | } | 220 | } |
240 | memset(&su, 0, sizeof(su)); | 221 | memset(&su, 0, sizeof(su)); |
241 | su.sun_family = AF_UNIX; | 222 | su.sun_family = AF_UNIX; |
242 | strncpy(su.sun_path, host_name, UNIX_PATH_MAX); | 223 | strncpy(su.sun_path, host_name, UNIX_PATH_MAX); |
243 | *sd = socket(PF_UNIX, SOCK_STREAM, 0); | 224 | *sd = socket(PF_UNIX, SOCK_STREAM, 0); |
244 | if(*sd < 0){ | 225 | if (*sd < 0) { |
245 | die(STATE_UNKNOWN, _("Socket creation failed")); | 226 | die(STATE_UNKNOWN, _("Socket creation failed")); |
246 | } | 227 | } |
247 | result = connect(*sd, (struct sockaddr *)&su, sizeof(su)); | 228 | result = connect(*sd, (struct sockaddr *)&su, sizeof(su)); |
@@ -259,37 +240,32 @@ np_net_connect (const char *host_name, int port, int *sd, int proto) | |||
259 | if (is_socket) | 240 | if (is_socket) |
260 | printf("connect to file socket %s: %s\n", host_name, strerror(errno)); | 241 | printf("connect to file socket %s: %s\n", host_name, strerror(errno)); |
261 | else | 242 | else |
262 | printf("connect to address %s and port %d: %s\n", | 243 | printf("connect to address %s and port %d: %s\n", host_name, port, strerror(errno)); |
263 | host_name, port, strerror(errno)); | ||
264 | return STATE_CRITICAL; | 244 | return STATE_CRITICAL; |
265 | break; | 245 | break; |
266 | default: /* it's a logic error if we do not end up in STATE_(OK|WARNING|CRITICAL) */ | 246 | default: /* it's a logic error if we do not end up in STATE_(OK|WARNING|CRITICAL) */ |
267 | return STATE_UNKNOWN; | 247 | return STATE_UNKNOWN; |
268 | break; | 248 | break; |
269 | } | 249 | } |
270 | } | 250 | } else { |
271 | else { | ||
272 | if (is_socket) | 251 | if (is_socket) |
273 | printf("connect to file socket %s: %s\n", host_name, strerror(errno)); | 252 | printf("connect to file socket %s: %s\n", host_name, strerror(errno)); |
274 | else | 253 | else |
275 | printf("connect to address %s and port %d: %s\n", | 254 | printf("connect to address %s and port %d: %s\n", host_name, port, strerror(errno)); |
276 | host_name, port, strerror(errno)); | ||
277 | return STATE_CRITICAL; | 255 | return STATE_CRITICAL; |
278 | } | 256 | } |
279 | } | 257 | } |
280 | 258 | ||
281 | int | 259 | 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; | 260 | int result = STATE_OK; |
285 | int send_result; | 261 | int send_result; |
286 | int recv_result; | 262 | int recv_result; |
287 | struct timeval tv; | 263 | struct timeval tv; |
288 | fd_set readfds; | 264 | fd_set readfds; |
289 | 265 | ||
290 | send_result = send (sd, send_buffer, strlen (send_buffer), 0); | 266 | send_result = send(sd, send_buffer, strlen(send_buffer), 0); |
291 | if (send_result<0 || (size_t)send_result!=strlen(send_buffer)) { | 267 | if (send_result < 0 || (size_t)send_result != strlen(send_buffer)) { |
292 | printf ("%s\n", _("Send failed")); | 268 | printf("%s\n", _("Send failed")); |
293 | result = STATE_WARNING; | 269 | result = STATE_WARNING; |
294 | } | 270 | } |
295 | 271 | ||
@@ -297,26 +273,25 @@ send_request (int sd, int proto, const char *send_buffer, char *recv_buffer, int | |||
297 | for data from the host */ | 273 | for data from the host */ |
298 | tv.tv_sec = socket_timeout - 1; | 274 | tv.tv_sec = socket_timeout - 1; |
299 | tv.tv_usec = 0; | 275 | tv.tv_usec = 0; |
300 | FD_ZERO (&readfds); | 276 | FD_ZERO(&readfds); |
301 | FD_SET (sd, &readfds); | 277 | FD_SET(sd, &readfds); |
302 | select (sd + 1, &readfds, NULL, NULL, &tv); | 278 | select(sd + 1, &readfds, NULL, NULL, &tv); |
303 | 279 | ||
304 | /* make sure some data has arrived */ | 280 | /* make sure some data has arrived */ |
305 | if (!FD_ISSET (sd, &readfds)) { | 281 | if (!FD_ISSET(sd, &readfds)) { |
306 | strcpy (recv_buffer, ""); | 282 | strcpy(recv_buffer, ""); |
307 | printf ("%s\n", _("No data was received from host!")); | 283 | printf("%s\n", _("No data was received from host!")); |
308 | result = STATE_WARNING; | 284 | result = STATE_WARNING; |
309 | } | 285 | } |
310 | 286 | ||
311 | else { | 287 | else { |
312 | recv_result = recv (sd, recv_buffer, (size_t)recv_size - 1, 0); | 288 | recv_result = recv(sd, recv_buffer, (size_t)recv_size - 1, 0); |
313 | if (recv_result == -1) { | 289 | if (recv_result == -1) { |
314 | strcpy (recv_buffer, ""); | 290 | strcpy(recv_buffer, ""); |
315 | if (proto != IPPROTO_TCP) | 291 | if (proto != IPPROTO_TCP) |
316 | printf ("%s\n", _("Receive failed")); | 292 | printf("%s\n", _("Receive failed")); |
317 | result = STATE_WARNING; | 293 | result = STATE_WARNING; |
318 | } | 294 | } else |
319 | else | ||
320 | recv_buffer[recv_result] = 0; | 295 | recv_buffer[recv_result] = 0; |
321 | 296 | ||
322 | /* die returned string */ | 297 | /* die returned string */ |
@@ -325,51 +300,46 @@ send_request (int sd, int proto, const char *send_buffer, char *recv_buffer, int | |||
325 | return result; | 300 | return result; |
326 | } | 301 | } |
327 | 302 | ||
328 | 303 | bool is_host(const char *address) { | |
329 | bool is_host (const char *address) { | 304 | if (is_addr(address) || is_hostname(address)) |
330 | if (is_addr (address) || is_hostname (address)) | ||
331 | return (true); | 305 | return (true); |
332 | 306 | ||
333 | return (false); | 307 | return (false); |
334 | } | 308 | } |
335 | 309 | ||
336 | void | 310 | void host_or_die(const char *str) { |
337 | host_or_die(const char *str) | 311 | 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); | 312 | usage_va(_("Invalid hostname/address - %s"), str); |
341 | } | 313 | } |
342 | 314 | ||
343 | bool is_addr (const char *address) { | 315 | bool is_addr(const char *address) { |
344 | #ifdef USE_IPV6 | 316 | #ifdef USE_IPV6 |
345 | if (address_family == AF_INET && is_inet_addr (address)) | 317 | if (address_family == AF_INET && is_inet_addr(address)) |
346 | return true; | 318 | return true; |
347 | else if (address_family == AF_INET6 && is_inet6_addr (address)) | 319 | else if (address_family == AF_INET6 && is_inet6_addr(address)) |
348 | return true; | 320 | return true; |
349 | #else | 321 | #else |
350 | if (is_inet_addr (address)) | 322 | if (is_inet_addr(address)) |
351 | return (true); | 323 | return (true); |
352 | #endif | 324 | #endif |
353 | 325 | ||
354 | return (false); | 326 | return (false); |
355 | } | 327 | } |
356 | 328 | ||
357 | int | 329 | 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; | 330 | struct addrinfo hints; |
361 | struct addrinfo *res; | 331 | struct addrinfo *res; |
362 | int retval; | 332 | int retval; |
363 | 333 | ||
364 | memset (&hints, 0, sizeof(struct addrinfo)); | 334 | memset(&hints, 0, sizeof(struct addrinfo)); |
365 | hints.ai_family = family; | 335 | hints.ai_family = family; |
366 | 336 | ||
367 | retval = getaddrinfo (in, NULL, &hints, &res); | 337 | retval = getaddrinfo(in, NULL, &hints, &res); |
368 | if (retval != 0) | 338 | if (retval != 0) |
369 | return false; | 339 | return false; |
370 | 340 | ||
371 | if (ss != NULL) | 341 | if (ss != NULL) |
372 | memcpy (ss, res->ai_addr, res->ai_addrlen); | 342 | memcpy(ss, res->ai_addr, res->ai_addrlen); |
373 | freeaddrinfo (res); | 343 | freeaddrinfo(res); |
374 | return true; | 344 | return true; |
375 | } | 345 | } |