OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [Common/] [ethernet/] [lwIP_130/] [src/] [api/] [netdb.c] - Blame information for rev 606

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 606 jeremybenn
/**
2
 * @file
3
 * API functions for name resolving
4
 *
5
 */
6
 
7
/*
8
 * Redistribution and use in source and binary forms, with or without modification,
9
 * are permitted provided that the following conditions are met:
10
 *
11
 * 1. Redistributions of source code must retain the above copyright notice,
12
 *    this list of conditions and the following disclaimer.
13
 * 2. Redistributions in binary form must reproduce the above copyright notice,
14
 *    this list of conditions and the following disclaimer in the documentation
15
 *    and/or other materials provided with the distribution.
16
 * 3. The name of the author may not be used to endorse or promote products
17
 *    derived from this software without specific prior written permission.
18
 *
19
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
20
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
22
 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
24
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
27
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
28
 * OF SUCH DAMAGE.
29
 *
30
 * This file is part of the lwIP TCP/IP stack.
31
 *
32
 * Author: Simon Goldschmidt
33
 *
34
 */
35
 
36
#include "lwip/netdb.h"
37
 
38
#if LWIP_DNS && LWIP_SOCKET
39
 
40
#include "lwip/err.h"
41
#include "lwip/mem.h"
42
#include "lwip/ip_addr.h"
43
#include "lwip/api.h"
44
 
45
/** helper struct for gethostbyname_r to access the char* buffer */
46
struct gethostbyname_r_helper {
47
  struct ip_addr *addrs;
48
  struct ip_addr addr;
49
  char *aliases;
50
};
51
 
52
/** h_errno is exported in netdb.h for access by applications. */
53
#if LWIP_DNS_API_DECLARE_H_ERRNO
54
int h_errno;
55
#endif /* LWIP_DNS_API_DECLARE_H_ERRNO */
56
 
57
/** define "hostent" variables storage: 0 if we use a static (but unprotected)
58
 * set of variables for lwip_gethostbyname, 1 if we use a local storage */
59
#ifndef LWIP_DNS_API_HOSTENT_STORAGE
60
#define LWIP_DNS_API_HOSTENT_STORAGE 0
61
#endif
62
 
63
/** define "hostent" variables storage */
64
#if LWIP_DNS_API_HOSTENT_STORAGE
65
#define HOSTENT_STORAGE
66
#else
67
#define HOSTENT_STORAGE static
68
#endif /* LWIP_DNS_API_STATIC_HOSTENT */
69
 
70
/**
71
 * Returns an entry containing addresses of address family AF_INET
72
 * for the host with name name.
73
 * Due to dns_gethostbyname limitations, only one address is returned.
74
 *
75
 * @param name the hostname to resolve
76
 * @return an entry containing addresses of address family AF_INET
77
 *         for the host with name name
78
 */
79
struct hostent*
80
lwip_gethostbyname(const char *name)
81
{
82
  err_t err;
83
  struct ip_addr addr;
84
 
85
  /* buffer variables for lwip_gethostbyname() */
86
  HOSTENT_STORAGE struct hostent s_hostent;
87
  HOSTENT_STORAGE char *s_aliases;
88
  HOSTENT_STORAGE struct ip_addr s_hostent_addr;
89
  HOSTENT_STORAGE struct ip_addr *s_phostent_addr;
90
 
91
  /* query host IP address */
92
  err = netconn_gethostbyname(name, &addr);
93
  if (err != ERR_OK) {
94
    LWIP_DEBUGF(DNS_DEBUG, ("lwip_gethostbyname(%s) failed, err=%d\n", name, err));
95
    h_errno = HOST_NOT_FOUND;
96
    return NULL;
97
  }
98
 
99
  /* fill hostent */
100
  s_hostent_addr = addr;
101
  s_phostent_addr = &s_hostent_addr;
102
  s_hostent.h_name = (char*)name;
103
  s_hostent.h_aliases = &s_aliases;
104
  s_hostent.h_addrtype = AF_INET;
105
  s_hostent.h_length = sizeof(struct ip_addr);
106
  s_hostent.h_addr_list = (char**)&s_phostent_addr;
107
 
108
#if DNS_DEBUG
109
  /* dump hostent */
110
  LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_name           == %s\n",      s_hostent.h_name));
111
  LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases        == 0x%08lX\n",(u32_t)(s_hostent.h_aliases)));
112
  if (s_hostent.h_aliases != NULL) {
113
    u8_t idx;
114
    for ( idx=0; s_hostent.h_aliases[idx]; idx++) {
115
      LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases[%i]->   == 0x%08lX\n", idx, s_hostent.h_aliases[idx]));
116
      LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases[%i]->   == %s\n",      idx, s_hostent.h_aliases[idx]));
117
    }
118
  }
119
  LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addrtype       == %lu\n",    (u32_t)(s_hostent.h_addrtype)));
120
  LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_length         == %lu\n",    (u32_t)(s_hostent.h_length)));
121
  LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list      == 0x%08lX\n", s_hostent.h_addr_list));
122
  if (s_hostent.h_addr_list != NULL) {
123
    u8_t idx;
124
    for ( idx=0; s_hostent.h_addr_list[idx]; idx++) {
125
      LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i]   == 0x%08lX\n", idx, s_hostent.h_addr_list[idx]));
126
      LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i]-> == %s\n",      idx, inet_ntoa(*((struct in_addr*)(s_hostent.h_addr_list[idx])))));
127
    }
128
  }
129
#endif /* DNS_DEBUG */
130
 
131
#if LWIP_DNS_API_HOSTENT_STORAGE
132
  /* this function should return the "per-thread" hostent after copy from s_hostent */
133
  return sys_thread_hostent(&s_hostent);
134
#else
135
  return &s_hostent;
136
#endif /* LWIP_DNS_API_HOSTENT_STORAGE */
137
}
138
 
139
/**
140
 * Thread-safe variant of lwip_gethostbyname: instead of using a static
141
 * buffer, this function takes buffer and errno pointers as arguments
142
 * and uses these for the result.
143
 *
144
 * @param name the hostname to resolve
145
 * @param ret pre-allocated struct where to store the result
146
 * @param buf pre-allocated buffer where to store additional data
147
 * @param buflen the size of buf
148
 * @param result pointer to a hostent pointer that is set to ret on success
149
 *               and set to zero on error
150
 * @param h_errnop pointer to an int where to store errors (instead of modifying
151
 *                 the global h_errno)
152
 * @return 0 on success, non-zero on error, additional error information
153
 *         is stored in *h_errnop instead of h_errno to be thread-safe
154
 */
155
int
156
lwip_gethostbyname_r(const char *name, struct hostent *ret, char *buf,
157
                size_t buflen, struct hostent **result, int *h_errnop)
158
{
159
  err_t err;
160
  struct gethostbyname_r_helper *h;
161
  char *hostname;
162
  size_t namelen;
163
  int lh_errno;
164
 
165
  if (h_errnop == NULL) {
166
    /* ensure h_errnop is never NULL */
167
    h_errnop = &lh_errno;
168
  }
169
 
170
  if (result == NULL) {
171
    /* not all arguments given */
172
    *h_errnop = EINVAL;
173
    return -1;
174
  }
175
  /* first thing to do: set *result to nothing */
176
  *result = NULL;
177
  if ((name == NULL) || (ret == NULL) || (buf == 0)) {
178
    /* not all arguments given */
179
    *h_errnop = EINVAL;
180
    return -1;
181
  }
182
 
183
  namelen = strlen(name);
184
  if (buflen < (sizeof(struct gethostbyname_r_helper) + namelen + 1 + (MEM_ALIGNMENT - 1))) {
185
    /* buf can't hold the data needed + a copy of name */
186
    *h_errnop = ERANGE;
187
    return -1;
188
  }
189
 
190
  h = (struct gethostbyname_r_helper*)LWIP_MEM_ALIGN(buf);
191
  hostname = ((char*)h) + sizeof(struct gethostbyname_r_helper);
192
 
193
  /* query host IP address */
194
  err = netconn_gethostbyname(name, &(h->addr));
195
  if (err != ERR_OK) {
196
    LWIP_DEBUGF(DNS_DEBUG, ("lwip_gethostbyname(%s) failed, err=%d\n", name, err));
197
    *h_errnop = ENSRNOTFOUND;
198
    return -1;
199
  }
200
 
201
  /* copy the hostname into buf */
202
  MEMCPY(hostname, name, namelen);
203
  hostname[namelen] = 0;
204
 
205
  /* fill hostent */
206
  h->addrs = &(h->addr);
207
  h->aliases = NULL;
208
  ret->h_name = (char*)hostname;
209
  ret->h_aliases = &(h->aliases);
210
  ret->h_addrtype = AF_INET;
211
  ret->h_length = sizeof(struct ip_addr);
212
  ret->h_addr_list = (char**)&(h->addrs);
213
 
214
  /* set result != NULL */
215
  *result = ret;
216
 
217
  /* return success */
218
  return 0;
219
}
220
 
221
/**
222
 * Frees one or more addrinfo structures returned by getaddrinfo(), along with
223
 * any additional storage associated with those structures. If the ai_next field
224
 * of the structure is not null, the entire list of structures is freed.
225
 *
226
 * @param ai struct addrinfo to free
227
 */
228
void
229
lwip_freeaddrinfo(struct addrinfo *ai)
230
{
231
  struct addrinfo *next;
232
 
233
  while (ai != NULL) {
234
    if (ai->ai_addr != NULL) {
235
      mem_free(ai->ai_addr);
236
    }
237
    if (ai->ai_canonname != NULL) {
238
      mem_free(ai->ai_canonname);
239
    }
240
    next = ai->ai_next;
241
    mem_free(ai);
242
    ai = next;
243
  }
244
}
245
 
246
/**
247
 * Translates the name of a service location (for example, a host name) and/or
248
 * a service name and returns a set of socket addresses and associated
249
 * information to be used in creating a socket with which to address the
250
 * specified service.
251
 * Memory for the result is allocated internally and must be freed by calling
252
 * lwip_freeaddrinfo()!
253
 *
254
 * Due to a limitation in dns_gethostbyname, only the first address of a
255
 * host is returned.
256
 * Also, service names are not supported (only port numbers)!
257
 *
258
 * @param nodename descriptive name or address string of the host
259
 *                 (may be NULL -> local address)
260
 * @param servname port number as string of NULL
261
 * @param hints structure containing input values that set socktype and protocol
262
 * @param res pointer to a pointer where to store the result (set to NULL on failure)
263
 * @return 0 on success, non-zero on failure
264
 */
265
int
266
lwip_getaddrinfo(const char *nodename, const char *servname,
267
       const struct addrinfo *hints, struct addrinfo **res)
268
{
269
  err_t err;
270
  struct ip_addr addr;
271
  struct addrinfo *ai;
272
  struct sockaddr_in *sa = NULL;
273
  int port_nr = 0;
274
 
275
  if (res == NULL) {
276
    return EAI_FAIL;
277
  }
278
  *res = NULL;
279
  if ((nodename == NULL) && (servname == NULL)) {
280
    return EAI_NONAME;
281
  }
282
 
283
  if (servname != NULL) {
284
    /* service name specified: convert to port number
285
     * @todo?: currently, only ASCII integers (port numbers) are supported! */
286
    port_nr = atoi(servname);
287
    if ((port_nr <= 0) || (port_nr > 0xffff)) {
288
      return EAI_SERVICE;
289
    }
290
  }
291
 
292
  if (nodename != NULL) {
293
    /* service location specified, try to resolve */
294
    err = netconn_gethostbyname(nodename, &addr);
295
    if (err != ERR_OK) {
296
      return EAI_FAIL;
297
    }
298
  } else {
299
    /* service location specified, use loopback address */
300
    addr.addr = INADDR_LOOPBACK;
301
  }
302
 
303
  ai = mem_malloc(sizeof(struct addrinfo));
304
  if (ai == NULL) {
305
    goto memerr;
306
  }
307
  memset(ai, 0, sizeof(struct addrinfo));
308
  sa = mem_malloc(sizeof(struct sockaddr_in));
309
  if (sa == NULL) {
310
    goto memerr;
311
  }
312
  memset(sa, 0, sizeof(struct sockaddr_in));
313
  /* set up sockaddr */
314
  sa->sin_addr.s_addr = addr.addr;
315
  sa->sin_family = AF_INET;
316
  sa->sin_len = sizeof(struct sockaddr_in);
317
  sa->sin_port = htons(port_nr);
318
 
319
  /* set up addrinfo */
320
  ai->ai_family = AF_INET;
321
  if (hints != NULL) {
322
    /* copy socktype & protocol from hints if specified */
323
    ai->ai_socktype = hints->ai_socktype;
324
    ai->ai_protocol = hints->ai_protocol;
325
  }
326
  if (nodename != NULL) {
327
    /* copy nodename to canonname if specified */
328
    size_t namelen = strlen(nodename);
329
    ai->ai_canonname = mem_malloc(namelen + 1);
330
    if (ai->ai_canonname == NULL) {
331
      goto memerr;
332
    }
333
    MEMCPY(ai->ai_canonname, nodename, namelen);
334
    ai->ai_canonname[namelen] = 0;
335
  }
336
  ai->ai_addrlen = sizeof(struct sockaddr_in);
337
  ai->ai_addr = (struct sockaddr*)sa;
338
 
339
  *res = ai;
340
 
341
  return 0;
342
memerr:
343
  if (ai != NULL) {
344
    mem_free(ai);
345
  }
346
  if (sa != NULL) {
347
    mem_free(sa);
348
  }
349
  return EAI_MEMORY;
350
}
351
 
352
#endif /* LWIP_DNS && LWIP_SOCKET */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.