1bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* 2bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Copyright (C) 2000-2003 Damien Miller. All rights reserved. 3bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Copyright (C) 1999 WIDE Project. All rights reserved. 4bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * 5bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Redistribution and use in source and binary forms, with or without 6bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * modification, are permitted provided that the following conditions 7bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * are met: 8bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * 1. Redistributions of source code must retain the above copyright 9bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * notice, this list of conditions and the following disclaimer. 10bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * 2. Redistributions in binary form must reproduce the above copyright 11bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * notice, this list of conditions and the following disclaimer in the 12bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * documentation and/or other materials provided with the distribution. 13bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * 3. Neither the name of the project nor the names of its contributors 14bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * may be used to endorse or promote products derived from this software 15bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * without specific prior written permission. 16bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * 17bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 18bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 21bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * SUCH DAMAGE. 28bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 29bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 30bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* 31bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Pseudo-implementation of RFC2553 name / address resolution functions 32bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * 33bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * But these functions are not implemented correctly. The minimum subset 34bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * is implemented for ssh use only. For example, this routine assumes 35bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * that ai_family is AF_INET. Don't use it for another purpose. 36bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 37bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 38bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "includes.h" 39bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 40bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <stdlib.h> 41bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <string.h> 42bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 43bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <netinet/in.h> 44bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <arpa/inet.h> 45bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 46bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifndef HAVE_GETNAMEINFO 47bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanint getnameinfo(const struct sockaddr *sa, size_t salen, char *host, 48bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman size_t hostlen, char *serv, size_t servlen, int flags) 49bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 50bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman struct sockaddr_in *sin = (struct sockaddr_in *)sa; 51bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman struct hostent *hp; 52bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman char tmpserv[16]; 53bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 54bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (sa->sa_family != AF_UNSPEC && sa->sa_family != AF_INET) 55bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return (EAI_FAMILY); 56bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (serv != NULL) { 57bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman snprintf(tmpserv, sizeof(tmpserv), "%d", ntohs(sin->sin_port)); 58bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (strlcpy(serv, tmpserv, servlen) >= servlen) 59bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return (EAI_MEMORY); 60bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 61bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 62bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (host != NULL) { 63bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (flags & NI_NUMERICHOST) { 64bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (strlcpy(host, inet_ntoa(sin->sin_addr), 65bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman hostlen) >= hostlen) 66bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return (EAI_MEMORY); 67bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman else 68bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return (0); 69bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } else { 70bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman hp = gethostbyaddr((char *)&sin->sin_addr, 71bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman sizeof(struct in_addr), AF_INET); 72bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (hp == NULL) 73bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return (EAI_NODATA); 74bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 75bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (strlcpy(host, hp->h_name, hostlen) >= hostlen) 76bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return (EAI_MEMORY); 77bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman else 78bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return (0); 79bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 80bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 81bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return (0); 82bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 83bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif /* !HAVE_GETNAMEINFO */ 84bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 85bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifndef HAVE_GAI_STRERROR 86bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef HAVE_CONST_GAI_STRERROR_PROTO 87bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanconst char * 88bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#else 89bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanchar * 90bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 91bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmangai_strerror(int err) 92bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 93bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman switch (err) { 94bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman case EAI_NODATA: 95bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return ("no address associated with name"); 96bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman case EAI_MEMORY: 97bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return ("memory allocation failure."); 98bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman case EAI_NONAME: 99bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return ("nodename nor servname provided, or not known"); 100bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman case EAI_FAMILY: 101bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return ("ai_family not supported"); 102bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman default: 103bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return ("unknown/invalid error."); 104bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 105bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 106bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif /* !HAVE_GAI_STRERROR */ 107bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 108bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifndef HAVE_FREEADDRINFO 109bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanvoid 110bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanfreeaddrinfo(struct addrinfo *ai) 111bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 112bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman struct addrinfo *next; 113bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 114bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman for(; ai != NULL;) { 115bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman next = ai->ai_next; 116bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman free(ai); 117bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman ai = next; 118bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 119bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 120bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif /* !HAVE_FREEADDRINFO */ 121bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 122bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifndef HAVE_GETADDRINFO 123bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstatic struct 124bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanaddrinfo *malloc_ai(int port, u_long addr, const struct addrinfo *hints) 125bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 126bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman struct addrinfo *ai; 127bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 128bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman ai = malloc(sizeof(*ai) + sizeof(struct sockaddr_in)); 129bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (ai == NULL) 130bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return (NULL); 131bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 132bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman memset(ai, '\0', sizeof(*ai) + sizeof(struct sockaddr_in)); 133bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 134bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman ai->ai_addr = (struct sockaddr *)(ai + 1); 135bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* XXX -- ssh doesn't use sa_len */ 136bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman ai->ai_addrlen = sizeof(struct sockaddr_in); 137bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman ai->ai_addr->sa_family = ai->ai_family = AF_INET; 138bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 139bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman ((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port; 140bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman ((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr; 141bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 142bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* XXX: the following is not generally correct, but does what we want */ 143bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (hints->ai_socktype) 144bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman ai->ai_socktype = hints->ai_socktype; 145bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman else 146bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman ai->ai_socktype = SOCK_STREAM; 147bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 148bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (hints->ai_protocol) 149bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman ai->ai_protocol = hints->ai_protocol; 150bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 151bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return (ai); 152bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 153bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 154bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanint 155bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmangetaddrinfo(const char *hostname, const char *servname, 156bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman const struct addrinfo *hints, struct addrinfo **res) 157bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 158bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman struct hostent *hp; 159bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman struct servent *sp; 160bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman struct in_addr in; 161bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int i; 162bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman long int port; 163bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman u_long addr; 164bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 165bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman port = 0; 166bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (hints && hints->ai_family != AF_UNSPEC && 167bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman hints->ai_family != AF_INET) 168bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return (EAI_FAMILY); 169bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (servname != NULL) { 170bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman char *cp; 171bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 172bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman port = strtol(servname, &cp, 10); 173bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (port > 0 && port <= 65535 && *cp == '\0') 174bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman port = htons(port); 175bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman else if ((sp = getservbyname(servname, NULL)) != NULL) 176bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman port = sp->s_port; 177bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman else 178bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman port = 0; 179bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 180bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 181bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (hints && hints->ai_flags & AI_PASSIVE) { 182bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman addr = htonl(0x00000000); 183bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (hostname && inet_aton(hostname, &in) != 0) 184bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman addr = in.s_addr; 185bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman *res = malloc_ai(port, addr, hints); 186bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (*res == NULL) 187bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return (EAI_MEMORY); 188bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return (0); 189bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 190bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 191bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (!hostname) { 192bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman *res = malloc_ai(port, htonl(0x7f000001), hints); 193bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (*res == NULL) 194bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return (EAI_MEMORY); 195bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return (0); 196bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 197bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 198bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (inet_aton(hostname, &in)) { 199bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman *res = malloc_ai(port, in.s_addr, hints); 200bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (*res == NULL) 201bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return (EAI_MEMORY); 202bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return (0); 203bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 204bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 205bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Don't try DNS if AI_NUMERICHOST is set */ 206bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (hints && hints->ai_flags & AI_NUMERICHOST) 207bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return (EAI_NONAME); 208bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 209bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman hp = gethostbyname(hostname); 210bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) { 211bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman struct addrinfo *cur, *prev; 212bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 213bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman cur = prev = *res = NULL; 214bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman for (i = 0; hp->h_addr_list[i]; i++) { 215bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman struct in_addr *in = (struct in_addr *)hp->h_addr_list[i]; 216bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 217bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman cur = malloc_ai(port, in->s_addr, hints); 218bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (cur == NULL) { 219bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (*res != NULL) 220bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman freeaddrinfo(*res); 221bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return (EAI_MEMORY); 222bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 223bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (prev) 224bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman prev->ai_next = cur; 225bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman else 226bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman *res = cur; 227bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 228bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman prev = cur; 229bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 230bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return (0); 231bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 232bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 233bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return (EAI_NODATA); 234bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 235bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif /* !HAVE_GETADDRINFO */ 236