LwIP with PPP & Ethernet integration

Dependents:   NetworkingCoreLib

This is the mbed port of the LwIP stack: http://savannah.nongnu.org/projects/lwip/

It includes contributed content from NXP's port for LPCxxxx devices: http://www.lpcware.com/content/project/lightweight-ip-lwip-networking-stack

Licence

LwIP is licenced under the BSD licence:

Copyright (c) 2001-2004 Swedish Institute of Computer Science. 
All rights reserved. 
Redistribution and use in source and binary forms, with or without modification, 
are permitted provided that the following conditions are met: 
1. Redistributions of source code must retain the above copyright notice, 
this list of conditions and the following disclaimer. 
2. Redistributions in binary form must reproduce the above copyright notice, 
this list of conditions and the following disclaimer in the documentation 
and/or other materials provided with the distribution. 
3. The name of the author may not be used to endorse or promote products 
derived from this software without specific prior written permission. 
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
OF SUCH DAMAGE.
Committer:
donatien
Date:
Thu May 24 15:53:48 2012 +0000
Revision:
0:8e01dca41002
Merge with Emilio's LwIp

Who changed what in which revision?

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