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