1968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
2968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold/* Copyright 1998 by the Massachusetts Institute of Technology.
3968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold *
4968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * Permission to use, copy, modify, and distribute this
5968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * software and its documentation for any purpose and without
6968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * fee is hereby granted, provided that the above copyright
7968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * notice appear in all copies and that both that copyright
8968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * notice and this permission notice appear in supporting
9968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * documentation, and that the name of M.I.T. not be used in
10968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * advertising or publicity pertaining to distribution of the
11968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * software without specific, written prior permission.
12968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * M.I.T. makes no representations about the suitability of
13968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * this software for any purpose.  It is provided "as is"
14968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * without express or implied warranty.
15968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold */
16968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
17968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#include "ares_setup.h"
18968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
19968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#ifdef HAVE_SYS_SOCKET_H
20968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#  include <sys/socket.h>
21968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#endif
22968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#ifdef HAVE_NETINET_IN_H
23968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#  include <netinet/in.h>
24968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#endif
25968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#ifdef HAVE_NETDB_H
26968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#  include <netdb.h>
27968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#endif
28968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#ifdef HAVE_ARPA_INET_H
29968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#  include <arpa/inet.h>
30968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#endif
31968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#ifdef HAVE_ARPA_NAMESER_H
32968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#  include <arpa/nameser.h>
33968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#else
34968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#  include "nameser.h"
35968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#endif
36968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#ifdef HAVE_ARPA_NAMESER_COMPAT_H
37968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#  include <arpa/nameser_compat.h>
38968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#endif
39968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
40968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#ifdef HAVE_STRINGS_H
41968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#  include <strings.h>
42968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#endif
43968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
44968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#include <stdlib.h>
45968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#include <string.h>
46968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#ifdef HAVE_LIMITS_H
47968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#  include <limits.h>
48968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#endif
49968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
50968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#include "ares.h"
51968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#include "ares_dns.h"
52968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#include "ares_private.h"
53968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
54968bf19396ad404e89420f5d67900fce13f4186cGilad Arnoldint ares_parse_a_reply(const unsigned char *abuf, int alen,
55968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                       struct hostent **host,
56968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                       struct ares_addrttl *addrttls, int *naddrttls)
57968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold{
58968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  unsigned int qdcount, ancount;
59968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  int status, i, rr_type, rr_class, rr_len, rr_ttl, naddrs;
60968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  int cname_ttl = INT_MAX;  /* the TTL imposed by the CNAME chain */
61968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  int naliases;
62968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  long len;
63968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  const unsigned char *aptr;
64968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  char *hostname, *rr_name, *rr_data, **aliases;
65968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  struct in_addr *addrs;
66968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  struct hostent *hostent;
67968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  const int max_addr_ttls = (addrttls && naddrttls) ? *naddrttls : 0;
68968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
69968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  /* Set *host to NULL for all failure cases. */
70968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  if (host)
71968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    *host = NULL;
72968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  /* Same with *naddrttls. */
73968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  if (naddrttls)
74968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    *naddrttls = 0;
75968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
76968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  /* Give up if abuf doesn't have room for a header. */
77968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  if (alen < HFIXEDSZ)
78968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    return ARES_EBADRESP;
79968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
80968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  /* Fetch the question and answer count from the header. */
81968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  qdcount = DNS_HEADER_QDCOUNT(abuf);
82968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  ancount = DNS_HEADER_ANCOUNT(abuf);
83968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  if (qdcount != 1)
84968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    return ARES_EBADRESP;
85968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
86968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  /* Expand the name from the question, and skip past the question. */
87968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  aptr = abuf + HFIXEDSZ;
88968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  status = ares__expand_name_for_response(aptr, abuf, alen, &hostname, &len);
89968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  if (status != ARES_SUCCESS)
90968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    return status;
91968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  if (aptr + len + QFIXEDSZ > abuf + alen)
92968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    {
93968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      free(hostname);
94968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      return ARES_EBADRESP;
95968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    }
96968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  aptr += len + QFIXEDSZ;
97968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
98968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  if (host)
99968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    {
100968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      /* Allocate addresses and aliases; ancount gives an upper bound for
101968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold         both. */
102968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      addrs = malloc(ancount * sizeof(struct in_addr));
103968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (!addrs)
104968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        {
105968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          free(hostname);
106968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          return ARES_ENOMEM;
107968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        }
108968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      aliases = malloc((ancount + 1) * sizeof(char *));
109968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (!aliases)
110968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        {
111968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          free(hostname);
112968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          free(addrs);
113968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          return ARES_ENOMEM;
114968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        }
115968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    }
116968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  else
117968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    {
118968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      addrs = NULL;
119968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      aliases = NULL;
120968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    }
121968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
122968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  naddrs = 0;
123968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  naliases = 0;
124968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
125968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  /* Examine each answer resource record (RR) in turn. */
126968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  for (i = 0; i < (int)ancount; i++)
127968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    {
128968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      /* Decode the RR up to the data field. */
129968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      status = ares__expand_name_for_response(aptr, abuf, alen, &rr_name, &len);
130968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (status != ARES_SUCCESS)
131968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        break;
132968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      aptr += len;
133968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (aptr + RRFIXEDSZ > abuf + alen)
134968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        {
135968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          free(rr_name);
136968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          status = ARES_EBADRESP;
137968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          break;
138968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        }
139968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      rr_type = DNS_RR_TYPE(aptr);
140968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      rr_class = DNS_RR_CLASS(aptr);
141968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      rr_len = DNS_RR_LEN(aptr);
142968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      rr_ttl = DNS_RR_TTL(aptr);
143968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      aptr += RRFIXEDSZ;
144968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
145968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (rr_class == C_IN && rr_type == T_A
146968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          && rr_len == sizeof(struct in_addr)
147968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          && strcasecmp(rr_name, hostname) == 0)
148968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        {
149968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          if (addrs)
150968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold            {
151968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold              if (aptr + sizeof(struct in_addr) > abuf + alen)
152968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold              {
153968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                free(rr_name);
154968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                status = ARES_EBADRESP;
155968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                break;
156968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold              }
157968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold              memcpy(&addrs[naddrs], aptr, sizeof(struct in_addr));
158968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold            }
159968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          if (naddrs < max_addr_ttls)
160968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold            {
161968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold              struct ares_addrttl * const at = &addrttls[naddrs];
162968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold              if (aptr + sizeof(struct in_addr) > abuf + alen)
163968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold              {
164968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                free(rr_name);
165968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                status = ARES_EBADRESP;
166968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                break;
167968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold              }
168968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold              memcpy(&at->ipaddr, aptr,  sizeof(struct in_addr));
169968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold              at->ttl = rr_ttl;
170968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold            }
171968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          naddrs++;
172968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          status = ARES_SUCCESS;
173968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        }
174968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
175968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (rr_class == C_IN && rr_type == T_CNAME)
176968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        {
177968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          /* Record the RR name as an alias. */
178968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          if (aliases)
179968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold            aliases[naliases] = rr_name;
180968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          else
181968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold            free(rr_name);
182968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          naliases++;
183968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
184968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          /* Decode the RR data and replace the hostname with it. */
185968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          status = ares__expand_name_for_response(aptr, abuf, alen, &rr_data,
186968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                                                  &len);
187968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          if (status != ARES_SUCCESS)
188968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold            break;
189968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          free(hostname);
190968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          hostname = rr_data;
191968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
192968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          /* Take the min of the TTLs we see in the CNAME chain. */
193968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          if (cname_ttl > rr_ttl)
194968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold            cname_ttl = rr_ttl;
195968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        }
196968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      else
197968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        free(rr_name);
198968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
199968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      aptr += rr_len;
200968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (aptr > abuf + alen)
201968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        {
202968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          status = ARES_EBADRESP;
203968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          break;
204968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        }
205968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    }
206968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
207968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  if (status == ARES_SUCCESS && naddrs == 0 && naliases == 0)
208968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    /* the check for naliases to be zero is to make sure CNAME responses
209968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold       don't get caught here */
210968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    status = ARES_ENODATA;
211968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  if (status == ARES_SUCCESS)
212968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    {
213968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      /* We got our answer. */
214968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (naddrttls)
215968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        {
216968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          const int n = naddrs < max_addr_ttls ? naddrs : max_addr_ttls;
217968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          for (i = 0; i < n; i++)
218968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold            {
219968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold              /* Ensure that each A TTL is no larger than the CNAME TTL. */
220968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold              if (addrttls[i].ttl > cname_ttl)
221968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                addrttls[i].ttl = cname_ttl;
222968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold            }
223968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          *naddrttls = n;
224968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        }
225968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (aliases)
226968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        aliases[naliases] = NULL;
227968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (host)
228968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        {
229968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          /* Allocate memory to build the host entry. */
230968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          hostent = malloc(sizeof(struct hostent));
231968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          if (hostent)
232968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold            {
233968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold              hostent->h_addr_list = malloc((naddrs + 1) * sizeof(char *));
234968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold              if (hostent->h_addr_list)
235968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                {
236968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                  /* Fill in the hostent and return successfully. */
237968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                  hostent->h_name = hostname;
238968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                  hostent->h_aliases = aliases;
239968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                  hostent->h_addrtype = AF_INET;
240968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                  hostent->h_length = sizeof(struct in_addr);
241968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                  for (i = 0; i < naddrs; i++)
242968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                    hostent->h_addr_list[i] = (char *) &addrs[i];
243968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                  hostent->h_addr_list[naddrs] = NULL;
244968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                  if (!naddrs && addrs)
245968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                    free(addrs);
246968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                  *host = hostent;
247968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                  return ARES_SUCCESS;
248968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                }
249968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold              free(hostent);
250968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold            }
251968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold          status = ARES_ENOMEM;
252968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        }
253968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold     }
254968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  if (aliases)
255968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    {
256968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      for (i = 0; i < naliases; i++)
257968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        free(aliases[i]);
258968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      free(aliases);
259968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    }
260968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  free(addrs);
261968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  free(hostname);
262968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  return status;
263968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold}
264