4 * This file includes getaddrinfo(), freeaddrinfo() and gai_strerror().
5 * These funtions are defined in rfc2133.
7 * But these functions are not implemented correctly. The minimum subset
8 * is implemented for ssh use only. For exapmle, this routine assumes
9 * that ai_family is AF_INET. Don't use it for another purpose.
18 #ifndef HAVE_GAI_STRERROR
24 return ("no address associated with name");
26 return ("memory allocation failure.");
28 return ("nodename nor servname provided, or not known");
30 return ("unknown/invalid error.");
33 #endif /* !HAVE_GAI_STRERROR */
35 #ifndef HAVE_FREEADDRINFO
37 freeaddrinfo(struct addrinfo *ai)
39 struct addrinfo *next;
47 #endif /* !HAVE_FREEADDRINFO */
49 #ifndef HAVE_GETADDRINFO
51 addrinfo *malloc_ai(int port, u_long addr, const struct addrinfo *hints)
55 ai = xmalloc(sizeof(*ai) + sizeof(struct sockaddr_in));
57 memset(ai, '\0', sizeof(*ai) + sizeof(struct sockaddr_in));
59 ai->ai_addr = (struct sockaddr *)(ai + 1);
60 /* XXX -- ssh doesn't use sa_len */
61 ai->ai_addrlen = sizeof(struct sockaddr_in);
62 ai->ai_addr->sa_family = ai->ai_family = AF_INET;
64 ((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port;
65 ((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr;
67 /* XXX: the following is not generally correct, but does what we want */
68 if (hints->ai_socktype)
69 ai->ai_socktype = hints->ai_socktype;
71 ai->ai_socktype = SOCK_STREAM;
73 if (hints->ai_protocol)
74 ai->ai_protocol = hints->ai_protocol;
80 getaddrinfo(const char *hostname, const char *servname,
81 const struct addrinfo *hints, struct addrinfo **res)
91 if (servname != NULL) {
94 port = strtol(servname, &cp, 10);
95 if (port > 0 && port <= 65535 && *cp == '\0')
97 else if ((sp = getservbyname(servname, NULL)) != NULL)
103 if (hints && hints->ai_flags & AI_PASSIVE) {
104 addr = htonl(0x00000000);
105 if (hostname && inet_aton(hostname, &in) != 0)
107 *res = malloc_ai(port, addr, hints);
112 *res = malloc_ai(port, htonl(0x7f000001), hints);
116 if (inet_aton(hostname, &in)) {
117 *res = malloc_ai(port, in.s_addr, hints);
121 /* Don't try DNS if AI_NUMERICHOST is set */
122 if (hints && hints->ai_flags & AI_NUMERICHOST)
125 hp = gethostbyname(hostname);
126 if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) {
127 struct addrinfo *cur, *prev;
130 for (i = 0; hp->h_addr_list[i]; i++) {
131 struct in_addr *in = (struct in_addr *)hp->h_addr_list[i];
133 cur = malloc_ai(port, in->s_addr, hints);
146 #endif /* !HAVE_GETADDRINFO */