Ruby  2.1.10p492(2016-04-01revision54464)
getaddrinfo.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the project nor the names of its contributors
14  * may be used to endorse or promote products derived from this software
15  * without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29 
30 /*
31  * "#ifdef FAITH" part is local hack for supporting IPv4-v6 translator.
32  *
33  * Issues to be discussed:
34  * - Thread safe-ness must be checked.
35  * - Return values. There are nonstandard return values defined and used
36  * in the source code. This is because RFC2133 is silent about which error
37  * code must be returned for which situation.
38  * - PF_UNSPEC case would be handled in getipnodebyname() with the AI_ALL flag.
39  */
40 
41 #include "ruby/config.h"
42 #ifdef RUBY_EXTCONF_H
43 #include RUBY_EXTCONF_H
44 #endif
45 #include <sys/types.h>
46 #ifndef _WIN32
47 #include <sys/param.h>
48 #if defined(__BEOS__) && !defined(__HAIKU__) && !defined(BONE)
49 # include <net/socket.h>
50 #else
51 # include <sys/socket.h>
52 #endif
53 #include <netinet/in.h>
54 #if defined(HAVE_ARPA_INET_H)
55 #include <arpa/inet.h>
56 #endif
57 #if defined(HAVE_ARPA_NAMESER_H)
58 #include <arpa/nameser.h>
59 #endif
60 #include <netdb.h>
61 #if defined(HAVE_RESOLV_H)
62 #ifdef _SX
63 #include <stdio.h>
64 #endif
65 #include <resolv.h>
66 #endif
67 #include <unistd.h>
68 #else
69 #include <winsock2.h>
70 #include <ws2tcpip.h>
71 #include <io.h>
72 #endif
73 #include <string.h>
74 #include <stdio.h>
75 #include <stdlib.h>
76 #include <stddef.h>
77 #include <ctype.h>
78 
79 #ifdef SOCKS5
80 #include <socks.h>
81 #endif
82 
83 #ifndef HAVE_TYPE_SOCKLEN_T
84 typedef int socklen_t;
85 #endif
86 
87 #include "addrinfo.h"
88 #include "sockport.h"
89 
90 #define SUCCESS 0
91 #define ANY 0
92 #define YES 1
93 #define NO 0
94 
95 #ifdef FAITH
96 static int translate = NO;
97 static struct in6_addr faith_prefix = IN6ADDR_ANY_INIT;
98 #endif
99 
100 static const char in_addrany[] = { 0, 0, 0, 0 };
101 static const char in6_addrany[] = {
102  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
103 };
104 static const char in_loopback[] = { 127, 0, 0, 1 };
105 static const char in6_loopback[] = {
106  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
107 };
108 
109 struct sockinet {
110  u_char si_len;
111  u_char si_family;
113 };
114 
115 static const struct afd {
116  int a_af;
119  int a_off;
120  const char *a_addrany;
121  const char *a_loopback;
122 } afdl [] = {
123 #ifdef INET6
124 #define N_INET6 0
125  {PF_INET6, sizeof(struct in6_addr),
126  sizeof(struct sockaddr_in6),
127  offsetof(struct sockaddr_in6, sin6_addr),
129 #define N_INET 1
130 #else
131 #define N_INET 0
132 #endif
133  {PF_INET, sizeof(struct in_addr),
134  sizeof(struct sockaddr_in),
135  offsetof(struct sockaddr_in, sin_addr),
137  {0, 0, 0, 0, NULL, NULL},
138 };
139 
140 #ifdef INET6
141 #define PTON_MAX 16
142 #else
143 #define PTON_MAX 4
144 #endif
145 
146 static int get_name __P((const char *, const struct afd *,
147  struct addrinfo **, char *, struct addrinfo *,
148  int));
149 static int get_addr __P((const char *, int, struct addrinfo **,
150  struct addrinfo *, int));
151 static int str_isnumber __P((const char *));
152 
153 static const char *const ai_errlist[] = {
154  "success.",
155  "address family for hostname not supported.", /* EAI_ADDRFAMILY */
156  "temporary failure in name resolution.", /* EAI_AGAIN */
157  "invalid value for ai_flags.", /* EAI_BADFLAGS */
158  "non-recoverable failure in name resolution.", /* EAI_FAIL */
159  "ai_family not supported.", /* EAI_FAMILY */
160  "memory allocation failure.", /* EAI_MEMORY */
161  "no address associated with hostname.", /* EAI_NODATA */
162  "hostname nor servname provided, or not known.",/* EAI_NONAME */
163  "servname not supported for ai_socktype.", /* EAI_SERVICE */
164  "ai_socktype not supported.", /* EAI_SOCKTYPE */
165  "system error returned in errno.", /* EAI_SYSTEM */
166  "invalid value for hints.", /* EAI_BADHINTS */
167  "resolved protocol is unknown.", /* EAI_PROTOCOL */
168  "unknown error.", /* EAI_MAX */
169 };
170 
171 #define GET_CANONNAME(ai, str) \
172 if (pai->ai_flags & AI_CANONNAME) {\
173  if (((ai)->ai_canonname = (char *)malloc(strlen(str) + 1)) != NULL) {\
174  strcpy((ai)->ai_canonname, (str));\
175  } else {\
176  error = EAI_MEMORY;\
177  goto free;\
178  }\
179 }
180 
181 #define GET_AI(ai, afd, addr, port) {\
182  char *p;\
183  if (((ai) = (struct addrinfo *)malloc(sizeof(struct addrinfo) +\
184  ((afd)->a_socklen)))\
185  == NULL) {\
186  error = EAI_MEMORY;\
187  goto free;\
188  }\
189  memcpy((ai), pai, sizeof(struct addrinfo));\
190  (ai)->ai_addr = (struct sockaddr *)((ai) + 1);\
191  (ai)->ai_family = (afd)->a_af;\
192  (ai)->ai_addrlen = (afd)->a_socklen;\
193  INIT_SOCKADDR((ai)->ai_addr, (afd)->a_af, (afd)->a_socklen);\
194  ((struct sockinet *)(ai)->ai_addr)->si_port = (port);\
195  p = (char *)((ai)->ai_addr);\
196  memcpy(p + (afd)->a_off, (addr), (afd)->a_addrlen);\
197 }
198 
199 #define ERR(err) { error = (err); goto bad; }
200 
201 #ifndef HAVE_GAI_STRERROR
202 #ifdef GAI_STRERROR_CONST
203 const
204 #endif
205 char *
206 gai_strerror(int ecode)
207 {
208  if (ecode < 0 || ecode > EAI_MAX)
209  ecode = EAI_MAX;
210  return (char *)ai_errlist[ecode];
211 }
212 #endif
213 
214 void
216 {
217  struct addrinfo *next;
218 
219  do {
220  next = ai->ai_next;
221  if (ai->ai_canonname)
222  free(ai->ai_canonname);
223  /* no need to free(ai->ai_addr) */
224  free(ai);
225  } while ((ai = next) != NULL);
226 }
227 
228 static int
229 str_isnumber(const char *p)
230 {
231  char *q = (char *)p;
232  while (*q) {
233  if (! isdigit(*q))
234  return NO;
235  q++;
236  }
237  return YES;
238 }
239 
240 #ifndef HAVE_INET_PTON
241 
242 static int
243 inet_pton(int af, const char *hostname, void *pton)
244 {
245  struct in_addr in;
246 
247 #ifdef HAVE_INET_ATON
248  if (!inet_aton(hostname, &in))
249  return 0;
250 #else
251  int d1, d2, d3, d4;
252  char ch;
253 
254  if (sscanf(hostname, "%d.%d.%d.%d%c", &d1, &d2, &d3, &d4, &ch) == 4 &&
255  0 <= d1 && d1 <= 255 && 0 <= d2 && d2 <= 255 &&
256  0 <= d3 && d3 <= 255 && 0 <= d4 && d4 <= 255) {
257  in.s_addr = htonl(
258  ((long) d1 << 24) | ((long) d2 << 16) |
259  ((long) d3 << 8) | ((long) d4 << 0));
260  }
261  else {
262  return 0;
263  }
264 #endif
265  memcpy(pton, &in, sizeof(in));
266  return 1;
267 }
268 #endif
269 
270 int
271 getaddrinfo(const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res)
272 {
273  struct addrinfo sentinel;
274  struct addrinfo *top = NULL;
275  struct addrinfo *cur;
276  int i, error = 0;
277  char pton[PTON_MAX];
278  struct addrinfo ai;
279  struct addrinfo *pai;
280  u_short port;
281 
282 #ifdef FAITH
283  static int firsttime = 1;
284 
285  if (firsttime) {
286  /* translator hack */
287  {
288  char *q = getenv("GAI");
289  if (q && inet_pton(AF_INET6, q, &faith_prefix) == 1)
290  translate = YES;
291  }
292  firsttime = 0;
293  }
294 #endif
295 
296  /* initialize file static vars */
297  sentinel.ai_next = NULL;
298  cur = &sentinel;
299  pai = &ai;
300  pai->ai_flags = 0;
301  pai->ai_family = PF_UNSPEC;
302  pai->ai_socktype = ANY;
303  pai->ai_protocol = ANY;
304  pai->ai_addrlen = 0;
305  pai->ai_canonname = NULL;
306  pai->ai_addr = NULL;
307  pai->ai_next = NULL;
308  port = ANY;
309 
310  if (hostname == NULL && servname == NULL)
311  return EAI_NONAME;
312  if (hints) {
313  /* error check for hints */
314  if (hints->ai_addrlen || hints->ai_canonname ||
315  hints->ai_addr || hints->ai_next)
316  ERR(EAI_BADHINTS); /* xxx */
317  if (hints->ai_flags & ~AI_MASK)
318  ERR(EAI_BADFLAGS);
319  switch (hints->ai_family) {
320  case PF_UNSPEC:
321  case PF_INET:
322 #ifdef INET6
323  case PF_INET6:
324 #endif
325  break;
326  default:
327  ERR(EAI_FAMILY);
328  }
329  memcpy(pai, hints, sizeof(*pai));
330  switch (pai->ai_socktype) {
331  case ANY:
332  switch (pai->ai_protocol) {
333  case ANY:
334  break;
335  case IPPROTO_UDP:
336  pai->ai_socktype = SOCK_DGRAM;
337  break;
338  case IPPROTO_TCP:
339  pai->ai_socktype = SOCK_STREAM;
340  break;
341  default:
342 #if defined(SOCK_RAW)
343  pai->ai_socktype = SOCK_RAW;
344 #endif
345  break;
346  }
347  break;
348 #if defined(SOCK_RAW)
349  case SOCK_RAW:
350  break;
351 #endif
352  case SOCK_DGRAM:
353  if (pai->ai_protocol != IPPROTO_UDP &&
354  pai->ai_protocol != ANY)
355  ERR(EAI_BADHINTS); /*xxx*/
356  pai->ai_protocol = IPPROTO_UDP;
357  break;
358  case SOCK_STREAM:
359  if (pai->ai_protocol != IPPROTO_TCP &&
360  pai->ai_protocol != ANY)
361  ERR(EAI_BADHINTS); /*xxx*/
362  pai->ai_protocol = IPPROTO_TCP;
363  break;
364  default:
365  ERR(EAI_SOCKTYPE);
366  break;
367  }
368  }
369 
370  /*
371  * service port
372  */
373  if (servname) {
374  if (str_isnumber(servname)) {
375  if (pai->ai_socktype == ANY) {
376  /* caller accept *ANY* socktype */
377  pai->ai_socktype = SOCK_DGRAM;
378  pai->ai_protocol = IPPROTO_UDP;
379  }
380  port = htons((unsigned short)atoi(servname));
381  } else if (pai->ai_flags & AI_NUMERICSERV) {
382  ERR(EAI_NONAME);
383  } else {
384  struct servent *sp;
385  const char *proto;
386 
387  proto = NULL;
388  switch (pai->ai_socktype) {
389  case ANY:
390  proto = NULL;
391  break;
392  case SOCK_DGRAM:
393  proto = "udp";
394  break;
395  case SOCK_STREAM:
396  proto = "tcp";
397  break;
398  default:
399  fprintf(stderr, "panic!\n");
400  break;
401  }
402  if ((sp = getservbyname((char*)servname, proto)) == NULL)
403  ERR(EAI_SERVICE);
404  port = sp->s_port;
405  if (pai->ai_socktype == ANY)
406  if (strcmp(sp->s_proto, "udp") == 0) {
407  pai->ai_socktype = SOCK_DGRAM;
408  pai->ai_protocol = IPPROTO_UDP;
409  } else if (strcmp(sp->s_proto, "tcp") == 0) {
410  pai->ai_socktype = SOCK_STREAM;
411  pai->ai_protocol = IPPROTO_TCP;
412  } else
413  ERR(EAI_PROTOCOL); /*xxx*/
414  }
415  }
416 
417  /*
418  * hostname == NULL.
419  * passive socket -> anyaddr (0.0.0.0 or ::)
420  * non-passive socket -> localhost (127.0.0.1 or ::1)
421  */
422  if (hostname == NULL) {
423  const struct afd *afd;
424  int s;
425 
426  for (afd = &afdl[0]; afd->a_af; afd++) {
427  if (!(pai->ai_family == PF_UNSPEC
428  || pai->ai_family == afd->a_af)) {
429  continue;
430  }
431 
432  /*
433  * filter out AFs that are not supported by the kernel
434  * XXX errno?
435  */
436  s = socket(afd->a_af, SOCK_DGRAM, 0);
437  if (s < 0)
438  continue;
439 #if defined(__BEOS__)
440  closesocket(s);
441 #else
442  close(s);
443 #endif
444 
445  if (pai->ai_flags & AI_PASSIVE) {
446  GET_AI(cur->ai_next, afd, afd->a_addrany, port);
447  /* xxx meaningless?
448  * GET_CANONNAME(cur->ai_next, "anyaddr");
449  */
450  } else {
451  GET_AI(cur->ai_next, afd, afd->a_loopback,
452  port);
453  /* xxx meaningless?
454  * GET_CANONNAME(cur->ai_next, "localhost");
455  */
456  }
457  cur = cur->ai_next;
458  }
459  top = sentinel.ai_next;
460  if (top)
461  goto good;
462  else
463  ERR(EAI_FAMILY);
464  }
465 
466  /* hostname as numeric name */
467  for (i = 0; afdl[i].a_af; i++) {
468  if (inet_pton(afdl[i].a_af, hostname, pton)) {
469  u_long v4a;
470 #ifdef INET6
471  u_char pfx;
472 #endif
473 
474  switch (afdl[i].a_af) {
475  case AF_INET:
476  v4a = ((struct in_addr *)pton)->s_addr;
477  if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a))
478  pai->ai_flags &= ~AI_CANONNAME;
479  v4a >>= IN_CLASSA_NSHIFT;
480  if (v4a == 0 || v4a == IN_LOOPBACKNET)
481  pai->ai_flags &= ~AI_CANONNAME;
482  break;
483 #ifdef INET6
484  case AF_INET6:
485  pfx = ((struct in6_addr *)pton)->s6_addr[0];
486  if (pfx == 0 || pfx == 0xfe || pfx == 0xff)
487  pai->ai_flags &= ~AI_CANONNAME;
488  break;
489 #endif
490  }
491 
492  if (pai->ai_family == afdl[i].a_af ||
493  pai->ai_family == PF_UNSPEC) {
494  if (! (pai->ai_flags & AI_CANONNAME)) {
495  GET_AI(top, &afdl[i], pton, port);
496  goto good;
497  }
498  /*
499  * if AI_CANONNAME and if reverse lookup
500  * fail, return ai anyway to pacify
501  * calling application.
502  *
503  * XXX getaddrinfo() is a name->address
504  * translation function, and it looks strange
505  * that we do addr->name translation here.
506  */
507  get_name(pton, &afdl[i], &top, pton, pai, port);
508  goto good;
509  } else
510  ERR(EAI_FAMILY); /*xxx*/
511  }
512  }
513 
514  if (pai->ai_flags & AI_NUMERICHOST)
515  ERR(EAI_NONAME);
516 
517  /* hostname as alphabetical name */
518  error = get_addr(hostname, pai->ai_family, &top, pai, port);
519  if (error == 0) {
520  if (top) {
521  good:
522  *res = top;
523  return SUCCESS;
524  } else
525  error = EAI_FAIL;
526  }
527  free:
528  if (top)
529  freeaddrinfo(top);
530  bad:
531  *res = NULL;
532  return error;
533 }
534 
535 static int
536 get_name(const char *addr, const struct afd *afd, struct addrinfo **res, char *numaddr, struct addrinfo *pai, int port0)
537 {
538  u_short port = port0 & 0xffff;
539  struct hostent *hp;
540  struct addrinfo *cur;
541  int error = 0;
542 #ifdef INET6
543  int h_error;
544 #endif
545 
546 #ifdef INET6
547  hp = getipnodebyaddr(addr, afd->a_addrlen, afd->a_af, &h_error);
548 #else
549  hp = gethostbyaddr((char*)addr, afd->a_addrlen, AF_INET);
550 #endif
551  if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) {
552  GET_AI(cur, afd, hp->h_addr_list[0], port);
553  GET_CANONNAME(cur, hp->h_name);
554  } else
555  GET_AI(cur, afd, numaddr, port);
556 
557 #ifdef INET6
558  if (hp)
559  freehostent(hp);
560 #endif
561  *res = cur;
562  return SUCCESS;
563  free:
564  if (cur)
565  freeaddrinfo(cur);
566 #ifdef INET6
567  if (hp)
568  freehostent(hp);
569 #endif
570  /* bad: */
571  *res = NULL;
572  return error;
573 }
574 
575 static int
576 get_addr(const char *hostname, int af, struct addrinfo **res, struct addrinfo *pai, int port0)
577 {
578  u_short port = port0 & 0xffff;
579  struct addrinfo sentinel;
580  struct hostent *hp;
581  struct addrinfo *top, *cur;
582  const struct afd *afd;
583  int i, error = 0, h_error;
584  char *ap;
585 
586  top = NULL;
587  sentinel.ai_next = NULL;
588  cur = &sentinel;
589 #ifdef INET6
590  if (af == AF_UNSPEC) {
591  hp = getipnodebyname(hostname, AF_INET6,
592  AI_ADDRCONFIG|AI_ALL|AI_V4MAPPED, &h_error);
593  } else
594  hp = getipnodebyname(hostname, af, AI_ADDRCONFIG, &h_error);
595 #else
596  if (strlen(hostname) >= NI_MAXHOST) ERR(EAI_NODATA);
597  hp = gethostbyname((char*)hostname);
598  h_error = h_errno;
599 #endif
600  if (hp == NULL) {
601  switch (h_error) {
602  case HOST_NOT_FOUND:
603  case NO_DATA:
604  error = EAI_NODATA;
605  break;
606  case TRY_AGAIN:
607  error = EAI_AGAIN;
608  break;
609  case NO_RECOVERY:
610  default:
611  error = EAI_FAIL;
612  break;
613  }
614  goto bad;
615  }
616 
617  if ((hp->h_name == NULL) || (hp->h_name[0] == 0) ||
618  (hp->h_addr_list[0] == NULL))
619  ERR(EAI_FAIL);
620 
621  for (i = 0; (ap = hp->h_addr_list[i]) != NULL; i++) {
622  switch (af) {
623 #ifdef INET6
624  case AF_INET6:
625  afd = &afdl[N_INET6];
626  break;
627 #endif
628 #ifndef INET6
629  default: /* AF_UNSPEC */
630 #endif
631  case AF_INET:
632  afd = &afdl[N_INET];
633  break;
634 #ifdef INET6
635  default: /* AF_UNSPEC */
636  if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ap)) {
637  ap += sizeof(struct in6_addr) -
638  sizeof(struct in_addr);
639  afd = &afdl[N_INET];
640  } else
641  afd = &afdl[N_INET6];
642  break;
643 #endif
644  }
645 #ifdef FAITH
646  if (translate && afd->a_af == AF_INET) {
647  struct in6_addr *in6;
648 
649  GET_AI(cur->ai_next, &afdl[N_INET6], ap, port);
650  in6 = &((struct sockaddr_in6 *)cur->ai_next->ai_addr)->sin6_addr;
651  memcpy(&in6->s6_addr, &faith_prefix,
652  sizeof(struct in6_addr) - sizeof(struct in_addr));
653  memcpy(&in6->s6_addr + sizeof(struct in_addr), ap,
654  sizeof(struct in_addr));
655  } else
656 #endif /* FAITH */
657  GET_AI(cur->ai_next, afd, ap, port);
658  if (cur == &sentinel) {
659  top = cur->ai_next;
660  GET_CANONNAME(top, hp->h_name);
661  }
662  cur = cur->ai_next;
663  }
664 #ifdef INET6
665  freehostent(hp);
666 #endif
667  *res = top;
668  return SUCCESS;
669  free:
670  if (top)
671  freeaddrinfo(top);
672 #ifdef INET6
673  if (hp)
674  freehostent(hp);
675 #endif
676  bad:
677  *res = NULL;
678  return error;
679 }
#define EAI_MAX
Definition: addrinfo.h:91
int a_af
Definition: getaddrinfo.c:116
static const char *const ai_errlist[]
Definition: getaddrinfo.c:153
size_t strlen(const char *)
#define PF_INET
Definition: sockport.h:109
u_char si_family
Definition: getaddrinfo.c:111
#define EAI_BADFLAGS
Definition: addrinfo.h:80
#define d1
static const char in_addrany[]
Definition: getaddrinfo.c:100
static const struct afd afdl[]
const char * a_loopback
Definition: getaddrinfo.c:121
#define GET_CANONNAME(ai, str)
Definition: getaddrinfo.c:171
int a_socklen
Definition: getaddrinfo.c:118
if((ID)(DISPID) nameid !=nameid)
Definition: win32ole.c:770
#define freehostent
Definition: addrinfo.h:153
static int get_addr(const char *hostname, int af, struct addrinfo **res, struct addrinfo *pai, int port0)
Definition: getaddrinfo.c:576
#define AI_PASSIVE
Definition: addrinfo.h:96
#define AI_CANONNAME
Definition: addrinfo.h:97
static int get_name(const char *addr, const struct afd *afd, struct addrinfo **res, char *numaddr, struct addrinfo *pai, int port0)
Definition: getaddrinfo.c:536
static const char in_loopback[]
Definition: getaddrinfo.c:104
#define EAI_PROTOCOL
Definition: addrinfo.h:90
#define EAI_AGAIN
Definition: addrinfo.h:79
#define EAI_FAMILY
Definition: addrinfo.h:82
#define GET_AI(ai, afd, addr, port)
Definition: getaddrinfo.c:181
#define YES
Definition: getaddrinfo.c:92
char * ai_canonname
Definition: addrinfo.h:137
#define offsetof(p_type, field)
Definition: addrinfo.h:186
#define IN_CLASSA_NSHIFT
Definition: sockport.h:93
int getaddrinfo(const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res)
Definition: getaddrinfo.c:271
#define u_short
Definition: vsnprintf.c:65
#define EAI_SOCKTYPE
Definition: addrinfo.h:87
#define SUCCESS
Definition: getaddrinfo.c:90
char * gai_strerror(int ecode)
Definition: getaddrinfo.c:206
#define N_INET
#define AI_ADDRCONFIG
Definition: addrinfo.h:108
int socklen_t
Definition: getaddrinfo.c:84
#define AI_V4MAPPED
Definition: addrinfo.h:109
void freeaddrinfo(struct addrinfo *ai)
Definition: getaddrinfo.c:215
#define PTON_MAX
Definition: getaddrinfo.c:143
#define EAI_BADHINTS
Definition: addrinfo.h:89
#define AI_NUMERICHOST
Definition: addrinfo.h:98
#define bad(x)
Definition: _sdbm.c:124
#define AI_ALL
Definition: addrinfo.h:106
static int inet_pton(int af, const char *hostname, void *pton)
Definition: getaddrinfo.c:243
int ai_protocol
Definition: addrinfo.h:135
#define getenv(name)
Definition: win32.c:66
unsigned int top
Definition: nkf.c:4309
static const char in6_loopback[]
Definition: getaddrinfo.c:105
#define AI_NUMERICSERV
Definition: addrinfo.h:99
#define EAI_FAIL
Definition: addrinfo.h:81
int a_off
Definition: getaddrinfo.c:119
#define sizeof(x)
Definition: zlib.c:58
#define PF_UNSPEC
Definition: sockport.h:105
int ai_socktype
Definition: addrinfo.h:134
static int get_name __P((const char *, const struct afd *, struct addrinfo **, char *, struct addrinfo *, int))
static int str_isnumber(const char *p)
Definition: getaddrinfo.c:229
static const char in6_addrany[]
Definition: getaddrinfo.c:101
#define proto(p)
Definition: sdbm.h:60
#define EAI_SERVICE
Definition: addrinfo.h:86
u_char si_len
Definition: getaddrinfo.c:110
#define AF_UNSPEC
Definition: sockport.h:101
#define IN_EXPERIMENTAL(i)
Definition: sockport.h:89
struct addrinfo * ai_next
Definition: addrinfo.h:139
#define AI_MASK
Definition: addrinfo.h:103
const char * a_addrany
Definition: getaddrinfo.c:120
#define NO
Definition: getaddrinfo.c:93
#define u_long
Definition: vsnprintf.c:64
u_short si_port
Definition: getaddrinfo.c:112
#define EAI_NONAME
Definition: addrinfo.h:85
#define ERR(err)
Definition: getaddrinfo.c:199
#define IN_LOOPBACKNET
Definition: sockport.h:97
size_t ai_addrlen
Definition: addrinfo.h:136
int ai_flags
Definition: addrinfo.h:132
int a_addrlen
Definition: getaddrinfo.c:117
#define EAI_NODATA
Definition: addrinfo.h:84
#define ANY
Definition: getaddrinfo.c:91
#define NULL
Definition: _sdbm.c:102
#define NI_MAXHOST
Definition: addrinfo.h:117
free(psz)
struct sockaddr * ai_addr
Definition: addrinfo.h:138
#define IN_MULTICAST(i)
Definition: sockport.h:85
int ai_family
Definition: addrinfo.h:133