]>
Commit | Line | Data |
---|---|---|
fea681da | 1 | .\" Copyright 2000 Sam Varshavchik <mrsam@courier-mta.com> |
35bf3cc8 | 2 | .\" and Copyright (c) 2007 Michael Kerrisk <mtk-manpages@gmx.net> |
fea681da MK |
3 | .\" |
4 | .\" Permission is granted to make and distribute verbatim copies of this | |
5 | .\" manual provided the copyright notice and this permission notice are | |
6 | .\" preserved on all copies. | |
7 | .\" | |
8 | .\" Permission is granted to copy and distribute modified versions of this | |
9 | .\" manual under the conditions for verbatim copying, provided that the | |
10 | .\" entire resulting derived work is distributed under the terms of a | |
11 | .\" permission notice identical to this one. | |
c13182ef | 12 | .\" |
fea681da MK |
13 | .\" Since the Linux kernel and libraries are constantly changing, this |
14 | .\" manual page may be incorrect or out-of-date. The author(s) assume no | |
15 | .\" responsibility for errors or omissions, or for damages resulting from | |
16 | .\" the use of the information contained herein. The author(s) may not | |
17 | .\" have taken the same level of care in the production of this manual, | |
18 | .\" which is licensed free of charge, as they might when working | |
19 | .\" professionally. | |
c13182ef | 20 | .\" |
fea681da MK |
21 | .\" Formatted or processed versions of this manual, if unaccompanied by |
22 | .\" the source, must acknowledge the copyright and authors of this work. | |
23 | .\" | |
24 | .\" References: RFC 2553 | |
8d18d6ed | 25 | .\" |
c13182ef | 26 | .\" 2005-08-09, mtk, added AI_ALL, AI_ADDRCONFIG, AI_V4MAPPED, |
8d18d6ed | 27 | .\" and AI_NUMERICSERV. |
35bf3cc8 | 28 | .\" 2007-06-08, mtk: added example programs |
8d18d6ed | 29 | .\" |
35bf3cc8 | 30 | .TH GETADDRINFO 3 2007-06-08 "GNU" "Linux Programmer's Manual" |
fea681da MK |
31 | .SH NAME |
32 | getaddrinfo, freeaddrinfo, gai_strerror \- network address and service translation | |
33 | .SH SYNOPSIS | |
34 | .nf | |
35 | .B #include <sys/types.h> | |
36 | .B #include <sys/socket.h> | |
37 | .B #include <netdb.h> | |
38 | .sp | |
39 | .BI "int getaddrinfo(const char *" "node" ", const char *" "service" , | |
40 | .BI " const struct addrinfo *" "hints" , | |
41 | .BI " struct addrinfo **" "res" ); | |
42 | .sp | |
43 | .BI "void freeaddrinfo(struct addrinfo *" "res" ); | |
44 | .sp | |
45 | .BI "const char *gai_strerror(int " "errcode" ); | |
46 | .fi | |
47 | .SH DESCRIPTION | |
48 | The | |
49 | .BR getaddrinfo (3) | |
50 | function combines the functionality provided by the | |
51 | .BR getipnodebyname (3), | |
52 | .BR getipnodebyaddr (3), | |
53 | .BR getservbyname (3), | |
54 | and | |
55 | .BR getservbyport (3) | |
56 | functions into a single interface. | |
57 | The thread-safe | |
58 | .BR getaddrinfo (3) | |
35bf3cc8 MK |
59 | function creates one or more socket address structures |
60 | that can be used by the | |
fea681da MK |
61 | .BR bind (2) |
62 | and | |
63 | .BR connect (2) | |
64 | system calls to create a client or a server socket. | |
65 | .PP | |
66 | The | |
67 | .BR getaddrinfo (3) | |
68 | function is not limited to creating IPv4 socket address structures; | |
69 | IPv6 socket address structures can be created if IPv6 support is available. | |
70 | These socket address structures can be used directly by | |
71 | .BR bind (2) | |
72 | or | |
73 | .BR connect (2), | |
74 | to prepare a client or a server socket. | |
75 | .PP | |
76 | The | |
8478ee02 | 77 | .I addrinfo |
fea681da MK |
78 | structure used by this function contains the following members: |
79 | .sp | |
80 | .nf | |
81 | .B struct addrinfo { | |
82 | .BI " int " "ai_flags" ";" | |
83 | .BI " int " "ai_family" ";" | |
84 | .BI " int " "ai_socktype" ";" | |
85 | .BI " int " "ai_protocol" ";" | |
86 | .BI " size_t " "ai_addrlen" ";" | |
87 | .BI " struct sockaddr *" "ai_addr" ";" | |
88 | .BI " char *" "ai_canonname" ";" | |
89 | .BI " struct addrinfo *" "ai_next" ";" | |
90 | .B }; | |
91 | .fi | |
92 | .PP | |
93 | .BR getaddrinfo (3) | |
94 | sets | |
95 | .I res | |
8194de33 | 96 | to point to a dynamically-allocated linked list of |
8478ee02 | 97 | .I addrinfo |
fea681da MK |
98 | structures, linked by the |
99 | .I ai_next | |
100 | member. | |
101 | There are several reasons why | |
8194de33 | 102 | the linked list may have more than one |
8478ee02 | 103 | .I addrinfo |
fea681da MK |
104 | structure, including: if the network host is |
105 | multi-homed; or if the same service | |
106 | is available from multiple socket protocols (one | |
107 | .B SOCK_STREAM | |
c13182ef | 108 | address and another |
fea681da MK |
109 | .B SOCK_DGRAM |
110 | address, for example). | |
111 | .PP | |
112 | The members | |
113 | .IR ai_family , | |
114 | .IR ai_socktype , | |
115 | and | |
116 | .I ai_protocol | |
117 | have the same meaning as the corresponding parameters in the | |
118 | .BR socket (2) | |
119 | system call. | |
120 | The | |
121 | .BR getaddrinfo (3) | |
122 | function returns socket addresses in either IPv4 or IPv6 | |
123 | address family, | |
124 | .RI "(" "ai_family" | |
125 | will be set to either | |
8d18d6ed | 126 | .B AF_INET |
fea681da | 127 | or |
8d18d6ed | 128 | .BR AF_INET6 ). |
fea681da MK |
129 | .PP |
130 | The | |
131 | .I hints | |
132 | parameter specifies | |
133 | the preferred socket type, or protocol. | |
134 | A NULL | |
135 | .I hints | |
136 | specifies that any network address or protocol is acceptable. | |
8d18d6ed | 137 | If this parameter is not NULL it points to an |
8478ee02 | 138 | .I addrinfo |
fea681da MK |
139 | structure |
140 | whose | |
141 | .IR ai_family , | |
142 | .IR ai_socktype , | |
143 | and | |
144 | .I ai_protocol | |
145 | members specify the preferred socket type. | |
8d18d6ed | 146 | .B AF_UNSPEC |
fea681da MK |
147 | in |
148 | .I ai_family | |
149 | specifies any protocol family (either IPv4 or IPv6, for example). | |
150 | 0 in | |
151 | .I ai_socktype | |
152 | or | |
153 | .I ai_protocol | |
154 | specifies that any socket type or protocol is acceptable as well. | |
155 | The | |
156 | .I ai_flags | |
157 | member | |
158 | specifies additional options, defined below. | |
159 | Multiple flags are specified by logically OR-ing them together. | |
160 | All the other members in the | |
161 | .I hints | |
162 | parameter must contain either 0, or a null pointer. | |
163 | .PP | |
164 | The | |
165 | .I node | |
166 | or | |
167 | .I service | |
168 | parameter, but not both, may be NULL. | |
169 | .I node | |
170 | specifies either a numerical network address | |
171 | (dotted-decimal format for IPv4, hexadecimal format for IPv6) | |
172 | or a network hostname, whose network addresses are looked up and resolved. | |
8d18d6ed MK |
173 | If |
174 | .I hints.ai_flags | |
175 | contains the | |
fea681da MK |
176 | .B AI_NUMERICHOST |
177 | flag then the | |
178 | .I node | |
179 | parameter must be a numerical network address. | |
180 | The | |
181 | .B AI_NUMERICHOST | |
182 | flag suppresses any potentially lengthy network host address lookups. | |
183 | .PP | |
184 | The | |
185 | .BR getaddrinfo (3) | |
8194de33 | 186 | function creates a linked list of |
8478ee02 | 187 | .I addrinfo |
fea681da MK |
188 | structures, one for each network address subject to any restrictions |
189 | imposed by the | |
190 | .I hints | |
191 | parameter. | |
8194de33 | 192 | The |
fea681da | 193 | .I ai_canonname |
c13182ef MK |
194 | field of the first of these |
195 | .I addrinfo | |
8194de33 | 196 | structures is set to point to the official name of the host, if |
8d18d6ed | 197 | .I hints.ai_flags |
fea681da MK |
198 | includes the |
199 | .B AI_CANONNAME | |
200 | flag. | |
c13182ef | 201 | .\" In glibc prior to 2.3.4, the ai_canonname of each addrinfo |
8194de33 | 202 | .\" structure was set pointing to the canonical name; that was |
c13182ef | 203 | .\" more than POSIX.1-2001 specified, or other implementations provided. |
8194de33 | 204 | .\" MTK, Aug 05 |
fea681da MK |
205 | .IR ai_family , |
206 | .IR ai_socktype , | |
207 | and | |
208 | .I ai_protocol | |
209 | specify the socket creation parameters. | |
210 | A pointer to the socket address is placed in the | |
211 | .I ai_addr | |
212 | member, and the length of the socket address, in bytes, | |
213 | is placed in the | |
214 | .I ai_addrlen | |
215 | member. | |
216 | .PP | |
217 | If | |
218 | .I node | |
219 | is NULL, | |
220 | the | |
221 | network address in each socket structure is initialized according to the | |
222 | .B AI_PASSIVE | |
8d18d6ed MK |
223 | flag, which is set in |
224 | .IR hints.ai_flags . | |
fea681da MK |
225 | The network address in each socket structure will be left unspecified |
226 | if | |
227 | .B AI_PASSIVE | |
228 | flag is set. | |
229 | This is used by server applications, which intend to accept | |
230 | client connections on any network address. | |
231 | The network address will be set to the loopback interface address | |
232 | if the | |
233 | .B AI_PASSIVE | |
234 | flag is not set. | |
235 | This is used by client applications, which intend to connect | |
236 | to a server running on the same network host. | |
237 | .PP | |
8d18d6ed MK |
238 | If |
239 | .I hints.ai_flags | |
240 | includes the | |
241 | .B AI_ADDRCONFIG | |
242 | flag, then IPv4 addresses are returned in the list pointed to by | |
243 | .I result | |
c13182ef MK |
244 | only if the local system has at least one |
245 | IPv4 address configured, and IPv6 addresses are only returned | |
8d18d6ed MK |
246 | if the local system has at least one IPv6 address configured. |
247 | .PP | |
248 | If | |
249 | .I hint.ai_flags | |
250 | specifies the | |
251 | .B AI_V4MAPPED | |
252 | flag, and | |
253 | .I hints.ai_family | |
254 | was specified as | |
255 | .BR AF_INET6 , | |
256 | and no matching IPv6 addresses could be found, | |
257 | then return IPv4-mapped IPv6 addresses in the list pointed to by | |
258 | .IR result . | |
259 | If both | |
260 | .B AI_V4MAPPED | |
261 | and | |
262 | .B AI_ALL | |
263 | are specified in | |
264 | .IR hints.ai_family , | |
c13182ef | 265 | then return both IPv6 and IPv4-mapped IPv6 addresses |
8d18d6ed MK |
266 | in the list pointed to by |
267 | .IR result . | |
268 | .B AI_ALL | |
269 | is ignored if | |
270 | .B AI_V4MAPPED | |
271 | is not also specified. | |
272 | .PP | |
fea681da MK |
273 | .I service |
274 | sets the port number in the network address of each socket structure. | |
275 | If | |
276 | .I service | |
277 | is NULL the port number will be left uninitialized. | |
8d18d6ed MK |
278 | If |
279 | .B AI_NUMERICSERV | |
280 | is specified in | |
c13182ef | 281 | .IR hints.ai_flags |
8d18d6ed MK |
282 | and |
283 | .I service | |
c13182ef | 284 | is not NULL, then |
8d18d6ed MK |
285 | .I service |
286 | must point to a string containing a numeric port number. | |
287 | This flag is used to inhibit the invocation of a name resolution service | |
288 | in cases where it is known not to be required. | |
fea681da MK |
289 | .PP |
290 | The | |
291 | .BR freeaddrinfo (3) | |
292 | function frees the memory that was allocated | |
8194de33 | 293 | for the dynamically allocated linked list |
fea681da | 294 | .IR res . |
22135cad MK |
295 | .SS "Extensions to getaddrinfo() for Internationalized Domain Names" |
296 | .PP | |
297 | Starting with glibc 2.3.4, | |
c13182ef MK |
298 | .BR getaddrinfo () |
299 | has been extended to selectively allow the incoming and outgoing | |
300 | host names to be transparently converted to and from the | |
22135cad MK |
301 | Internationalized Domain Name (IDN) format (see RFC 3490, |
302 | .IR "Internationalizing Domain Names in Applications (IDNA)" ). | |
303 | Four new flags are defined: | |
304 | .TP | |
305 | .B AI_IDN | |
306 | If this flag is specified, then the node name given in | |
307 | .I node | |
308 | is converted to IDN format if necessary. | |
309 | The source encoding is that of the current locale. | |
310 | ||
c13182ef MK |
311 | If the input name contains non-ASCII characters, then the IDN encoding |
312 | is used. | |
22135cad | 313 | Those parts of the node name (delimited by dots) that contain |
c13182ef | 314 | non-ASCII characters are encoded using ASCII Compatible Encoding (ACE) |
22135cad MK |
315 | before being passed to the name resolution functions. |
316 | .\" Implementation Detail: | |
317 | .\" To minimize effects on system performance the implementation might | |
318 | .\" want to check whether the input string contains any non-ASCII | |
319 | .\" characters. If there are none the IDN step can be skipped completely. | |
320 | .\" On systems which allow not-ASCII safe encodings for a locale this | |
321 | .\" might be a problem. | |
322 | .TP | |
323 | .B AI_CANONIDN | |
c13182ef MK |
324 | After a successful name lookup, and if the |
325 | .B AI_CANONNAME | |
22135cad MK |
326 | flag was specified, |
327 | .BR getaddrinfo () | |
328 | will return the canonical name of the | |
c13182ef MK |
329 | node corresponding to the |
330 | .I addrinfo | |
22135cad MK |
331 | structure value passed back. |
332 | The return value is an exact copy of the value returned by the name | |
333 | resolution function. | |
334 | ||
c13182ef MK |
335 | If the name is encoded using ACE, then it will contain the |
336 | .I xn-- | |
337 | prefix for one or more components of the name. | |
338 | To convert these components into a readable form the | |
339 | .B AI_CANONIDN | |
340 | flag can be passed in addition to | |
341 | .BR AI_CANONNAME . | |
22135cad MK |
342 | The resulting string is encoded using the current locale's encoding. |
343 | .\" | |
344 | .\"Implementation Detail: | |
345 | .\"If no component of the returned name starts with xn-- the IDN | |
346 | .\"step can be skipped, therefore avoiding unnecessary slowdowns. | |
347 | .TP | |
348 | .BR AI_IDN_ALLOW_UNASSIGNED ", " AI_IDN_USE_STD3_ASCII_RULES | |
c13182ef | 349 | Setting these flags will enable the |
22135cad | 350 | IDNA_ALLOW_UNASSIGNED (allow unassigned Unicode code points) and |
c13182ef MK |
351 | IDNA_USE_STD3_ASCII_RULES (check output to make sure it is a STD3 |
352 | conforming host name) | |
22135cad | 353 | flags respectively to be used in the IDNA handling. |
fea681da | 354 | .SH "RETURN VALUE" |
d5da3c8d | 355 | .\" FIXME glibc defines the following additional errors, some which |
c13182ef | 356 | .\" can probably be returned by getaddrinfo(); they need to |
22135cad MK |
357 | .\" be documented. |
358 | .\" # ifdef __USE_GNU | |
359 | .\" # define EAI_INPROGRESS -100 /* Processing request in progress. */ | |
360 | .\" # define EAI_CANCELED -101 /* Request canceled. */ | |
361 | .\" # define EAI_NOTCANCELED -102 /* Request not canceled. */ | |
362 | .\" # define EAI_ALLDONE -103 /* All requests done. */ | |
363 | .\" # define EAI_INTR -104 /* Interrupted by a signal. */ | |
364 | .\" # define EAI_IDN_ENCODE -105 /* IDN encoding failed. */ | |
365 | .\" # endif | |
fea681da MK |
366 | .BR getaddrinfo (3) |
367 | returns 0 if it succeeds, or one of the following non-zero error codes: | |
368 | .TP | |
a0aa388d MK |
369 | .B EAI_ADDRFAMILY |
370 | The specified network host does not have any network addresses in the | |
371 | requested address family. | |
fea681da | 372 | .TP |
a0aa388d MK |
373 | .B EAI_AGAIN |
374 | The name server returned a temporary failure indication. | |
375 | Try again later. | |
fea681da MK |
376 | .TP |
377 | .B EAI_BADFLAGS | |
378 | .I ai_flags | |
379 | contains invalid flags. | |
380 | .TP | |
a0aa388d MK |
381 | .B EAI_FAIL |
382 | The name server returned a permanent failure indication. | |
383 | .TP | |
384 | .B EAI_FAMILY | |
385 | The requested address family is not supported at all. | |
386 | .TP | |
387 | .B EAI_MEMORY | |
388 | Out of memory. | |
389 | .TP | |
390 | .B EAI_NODATA | |
391 | The specified network host exists, but does not have any | |
392 | network addresses defined. | |
393 | .TP | |
fea681da MK |
394 | .B EAI_NONAME |
395 | The | |
396 | .I node | |
397 | or | |
398 | .I service | |
8d18d6ed | 399 | is not known; or both |
fea681da MK |
400 | .I node |
401 | and | |
402 | .I service | |
8d18d6ed MK |
403 | are NULL; or |
404 | .B AI_NUMERICSERV | |
405 | was specified in | |
406 | .I hints.ai_flags | |
c13182ef | 407 | and |
8d18d6ed MK |
408 | .I service |
409 | was not a numeric port-number string. | |
fea681da MK |
410 | .TP |
411 | .B EAI_SERVICE | |
412 | The requested service is not available for the requested socket type. | |
413 | It may be available through another socket type. | |
414 | .TP | |
a0aa388d MK |
415 | .B EAI_SOCKTYPE |
416 | The requested socket type is not supported at all. | |
fea681da MK |
417 | .TP |
418 | .B EAI_SYSTEM | |
419 | Other system error, check | |
420 | .I errno | |
421 | for details. | |
422 | .PP | |
423 | The | |
424 | .BR gai_strerror (3) | |
425 | function translates these error codes to a human readable string, | |
426 | suitable for error reporting. | |
427 | .SH "CONFORMING TO" | |
68e1685c | 428 | POSIX.1-2001. |
fea681da | 429 | The |
63aa9df0 | 430 | .BR getaddrinfo () |
331da7c3 | 431 | function is documented in RFC\ 2553. |
8d18d6ed MK |
432 | .SH "NOTES" |
433 | .BR AI_ADDRCONFIG , | |
d63f46e1 | 434 | .BR AI_ALL , |
8d18d6ed MK |
435 | and |
436 | .BR AI_V4MAPPED | |
437 | are available since glibc 2.3.3. | |
438 | .BR AI_NUMERICSERV | |
439 | is available since glibc 2.3.4. | |
35bf3cc8 | 440 | .SH EXAMPLE |
88a180b7 MK |
441 | .\" getnameinfo.3 refers to this example |
442 | .\" socket.2 refers to this example | |
443 | .\" bind.2 refers to this example | |
444 | .\" connect.2 refers to this example | |
445 | .\" recvfrom.2 refers to this example | |
446 | .\" sendto.2 refers to this example | |
35bf3cc8 MK |
447 | The following programs demonstrate the use of |
448 | .BR getaddrinfo (), | |
449 | .BR gai_strerror (), | |
450 | .BR freeaddrinfo (), | |
451 | and | |
452 | .BR getnameinfo (3). | |
453 | The programs are an echo server and client for UDP datagrams. | |
454 | ||
455 | This is the server: | |
456 | .in +0.25i | |
457 | .nf | |
458 | ||
459 | #include <sys/types.h> | |
460 | #include <stdio.h> | |
461 | #include <stdlib.h> | |
462 | #include <unistd.h> | |
463 | #include <string.h> | |
464 | #include <sys/socket.h> | |
465 | #include <netdb.h> | |
466 | ||
467 | #define BUF_SIZE 500 | |
468 | ||
469 | int | |
470 | main(int argc, char *argv[]) | |
471 | { | |
472 | struct addrinfo hints; | |
473 | struct addrinfo *result, *rp; | |
474 | int sfd, s; | |
475 | struct sockaddr_storage peer_addr; | |
476 | socklen_t peer_addr_len; | |
477 | ssize_t nread; | |
478 | char buf[BUF_SIZE]; | |
479 | ||
480 | if (argc != 2) { | |
481 | fprintf(stderr, "Usage: %s port\\n", argv[0]); | |
482 | exit(EXIT_FAILURE); | |
483 | } | |
484 | ||
485 | memset(&hints, 0, sizeof(struct addrinfo)); | |
486 | hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ | |
487 | hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */ | |
488 | hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */ | |
489 | hints.ai_protocol = 0; /* Any protocol */ | |
490 | ||
491 | s = getaddrinfo(NULL, argv[1], &hints, &result); | |
492 | if (s != 0) { | |
493 | fprintf(stderr, "getaddrinfo: %s\\n", gai_strerror(s)); | |
494 | exit(EXIT_FAILURE); | |
495 | } | |
496 | ||
497 | /* getaddrinfo() returns a list of address structures. | |
498 | Try each address until we successfully bind(). | |
9daa4fb9 | 499 | If socket(2) (or bind(2)) fails, we (close the socket |
35bf3cc8 MK |
500 | and) try the next address. */ |
501 | ||
502 | for (rp = result; rp != NULL; rp = rp->ai_next) { | |
503 | sfd = socket(rp->ai_family, rp->ai_socktype, | |
504 | rp->ai_protocol); | |
505 | if (sfd == -1) | |
506 | continue; | |
507 | ||
508 | if (bind(sfd, rp->ai_addr, rp->ai_addrlen) == 0) | |
509 | break; /* Success */ | |
510 | ||
511 | close(sfd); | |
512 | } | |
513 | ||
514 | if (rp == NULL) { /* No address succeeded */ | |
515 | fprintf(stderr, "Could not bind\\n"); | |
516 | exit(EXIT_FAILURE); | |
517 | } | |
518 | ||
519 | freeaddrinfo(result); /* No longer needed */ | |
520 | ||
521 | /* Read datagrams and echo them back to sender */ | |
522 | ||
523 | for (;;) { | |
524 | peer_addr_len = sizeof(struct sockaddr_storage); | |
525 | nread = recvfrom(sfd, buf, BUF_SIZE, 0, | |
526 | (struct sockaddr *) &peer_addr, &peer_addr_len); | |
527 | if (nread == -1) | |
528 | continue; /* Ignore failed request */ | |
529 | ||
530 | char host[NI_MAXHOST], service[NI_MAXSERV]; | |
531 | ||
532 | s = getnameinfo((struct sockaddr *) &peer_addr, | |
533 | peer_addr_len, host, NI_MAXHOST, | |
534 | service, NI_MAXSERV, NI_NUMERICSERV); | |
535 | if (s == 0) | |
536 | printf("Received %ld bytes from %s:%s\\n", | |
537 | (long) nread, host, service); | |
538 | else | |
539 | fprintf(stderr, "getnameinfo: %s\\n", gai_strerror(s)); | |
540 | ||
541 | ||
542 | if (sendto(sfd, buf, nread, 0, | |
543 | (struct sockaddr *) &peer_addr, | |
544 | peer_addr_len) != nread) | |
545 | fprintf(stderr, "Error sending response\\n"); | |
546 | } | |
547 | } | |
548 | .fi | |
549 | .in | |
550 | ||
551 | This is the client: | |
552 | .in +0.25i | |
553 | .nf | |
554 | ||
555 | #include <sys/types.h> | |
556 | #include <sys/socket.h> | |
557 | #include <netdb.h> | |
558 | #include <stdio.h> | |
559 | #include <stdlib.h> | |
560 | #include <unistd.h> | |
561 | #include <string.h> | |
562 | ||
563 | #define BUF_SIZE 500 | |
564 | ||
565 | int | |
566 | main(int argc, char *argv[]) | |
567 | { | |
568 | struct addrinfo hints; | |
569 | struct addrinfo *result, *rp; | |
570 | int sfd, s, j; | |
571 | size_t len; | |
572 | ssize_t nread; | |
573 | char buf[BUF_SIZE]; | |
574 | ||
575 | if (argc < 3) { | |
576 | fprintf(stderr, "Usage: %s host port msg...\\n", argv[0]); | |
577 | exit(EXIT_FAILURE); | |
578 | } | |
579 | ||
580 | /* Obtain address(es) matching host/port */ | |
581 | ||
582 | memset(&hints, 0, sizeof(struct addrinfo)); | |
583 | hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ | |
584 | hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */ | |
585 | hints.ai_flags = 0; | |
586 | hints.ai_protocol = 0; /* Any protocol */ | |
587 | ||
588 | s = getaddrinfo(argv[1], argv[2], &hints, &result); | |
589 | if (s != 0) { | |
590 | fprintf(stderr, "getaddrinfo: %s\\n", gai_strerror(s)); | |
591 | exit(EXIT_FAILURE); | |
592 | } | |
593 | ||
594 | /* getaddrinfo() returns a list of address structures. | |
595 | Try each address until we successfully connect(). | |
596 | If socket() (or connect()) fails, we (close the socket | |
597 | and) try the next address. */ | |
598 | ||
599 | for (rp = result; rp != NULL; rp = rp->ai_next) { | |
600 | sfd = socket(rp->ai_family, rp->ai_socktype, | |
601 | rp->ai_protocol); | |
602 | if (sfd == -1) | |
603 | continue; | |
604 | ||
605 | if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1) | |
606 | break; /* Success */ | |
607 | ||
608 | close(sfd); | |
609 | } | |
610 | ||
611 | if (rp == NULL) { /* No address succeeded */ | |
612 | fprintf(stderr, "Could not connect\\n"); | |
613 | exit(EXIT_FAILURE); | |
614 | } | |
615 | ||
616 | freeaddrinfo(result); /* No longer needed */ | |
617 | ||
618 | /* Send remaining command-line arguments as separate | |
619 | datagrams, and read responses from server */ | |
620 | ||
621 | for (j = 3; j < argc; j++) { | |
622 | len = strlen(argv[j]) + 1; | |
623 | /* +1 for terminating null byte */ | |
624 | ||
625 | if (len + 1 > BUF_SIZE) { | |
626 | fprintf(stderr, | |
627 | "Ignoring long message in argument %d\\n", j); | |
628 | continue; | |
629 | } | |
630 | ||
631 | if (write(sfd, argv[j], len) != len) { | |
632 | fprintf(stderr, "partial/failed write\\n"); | |
633 | exit(EXIT_FAILURE); | |
634 | } | |
635 | ||
636 | nread = read(sfd, buf, BUF_SIZE); | |
637 | if (nread == -1) { | |
638 | perror("read"); | |
639 | exit(EXIT_FAILURE); | |
640 | } | |
641 | ||
642 | printf("Received %ld bytes: %s\\n", (long) nread, buf); | |
643 | } | |
644 | ||
645 | exit(EXIT_SUCCESS); | |
646 | } | |
647 | .fi | |
648 | .in | |
fea681da MK |
649 | .SH "SEE ALSO" |
650 | .BR getipnodebyaddr (3), | |
651 | .BR getipnodebyname (3) | |
35bf3cc8 | 652 | .BR getnameinfo (3), |