00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "lwip/netdb.h"
00037
00038 #if LWIP_DNS && LWIP_SOCKET
00039
00040 #include "lwip/err.h"
00041 #include "lwip/mem.h"
00042 #include "lwip/memp.h"
00043 #include "lwip/ip_addr.h"
00044 #include "lwip/api.h"
00045 #include "lwip/dns.h"
00046
00047 #include <string.h>
00048 #include <stdlib.h>
00049
00050
00051 struct gethostbyname_r_helper {
00052 ip_addr_t *addr_list[2];
00053 ip_addr_t addr;
00054 char *aliases;
00055 };
00056
00057
00058 #if LWIP_DNS_API_DECLARE_H_ERRNO
00059 int h_errno;
00060 #endif
00061
00062
00063
00064 #ifndef LWIP_DNS_API_HOSTENT_STORAGE
00065 #define LWIP_DNS_API_HOSTENT_STORAGE 0
00066 #endif
00067
00068
00069 #if LWIP_DNS_API_HOSTENT_STORAGE
00070 #define HOSTENT_STORAGE
00071 #else
00072 #define HOSTENT_STORAGE static
00073 #endif
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 struct hostent*
00085 lwip_gethostbyname(const char *name)
00086 {
00087 err_t err;
00088 ip_addr_t addr;
00089
00090
00091 HOSTENT_STORAGE struct hostent s_hostent;
00092 HOSTENT_STORAGE char *s_aliases;
00093 HOSTENT_STORAGE ip_addr_t s_hostent_addr;
00094 HOSTENT_STORAGE ip_addr_t *s_phostent_addr[2];
00095
00096
00097 err = netconn_gethostbyname(name, &addr);
00098 if (err != ERR_OK) {
00099 LWIP_DEBUGF(DNS_DEBUG, ("lwip_gethostbyname(%s) failed, err=%d\n", name, err));
00100 h_errno = HOST_NOT_FOUND;
00101 return NULL;
00102 }
00103
00104
00105 s_hostent_addr = addr;
00106 s_phostent_addr[0] = &s_hostent_addr;
00107 s_phostent_addr[1] = NULL;
00108 s_hostent.h_name = (char*)name;
00109 s_hostent.h_aliases = &s_aliases;
00110 s_hostent.h_addrtype = AF_INET;
00111 s_hostent.h_length = sizeof(ip_addr_t);
00112 s_hostent.h_addr_list = (char**)&s_phostent_addr;
00113
00114 #if DNS_DEBUG
00115
00116 LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_name == %s\n", s_hostent.h_name));
00117 LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases == %p\n", s_hostent.h_aliases));
00118 if (s_hostent.h_aliases != NULL) {
00119 u8_t idx;
00120 for ( idx=0; s_hostent.h_aliases[idx]; idx++) {
00121 LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases[%i]-> == %p\n", idx, s_hostent.h_aliases[idx]));
00122 LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases[%i]-> == %s\n", idx, s_hostent.h_aliases[idx]));
00123 }
00124 }
00125 LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addrtype == %d\n", s_hostent.h_addrtype));
00126 LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_length == %d\n", s_hostent.h_length));
00127 LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list == %p\n", s_hostent.h_addr_list));
00128 if (s_hostent.h_addr_list != NULL) {
00129 u8_t idx;
00130 for ( idx=0; s_hostent.h_addr_list[idx]; idx++) {
00131 LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i] == %p\n", idx, s_hostent.h_addr_list[idx]));
00132 LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i]-> == %s\n", idx, ip_ntoa((ip_addr_t*)s_hostent.h_addr_list[idx])));
00133 }
00134 }
00135 #endif
00136
00137 #if LWIP_DNS_API_HOSTENT_STORAGE
00138
00139 return sys_thread_hostent(&s_hostent);
00140 #else
00141 return &s_hostent;
00142 #endif
00143 }
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161 int
00162 lwip_gethostbyname_r(const char *name, struct hostent *ret, char *buf,
00163 size_t buflen, struct hostent **result, int *h_errnop)
00164 {
00165 err_t err;
00166 struct gethostbyname_r_helper *h;
00167 char *hostname;
00168 size_t namelen;
00169 int lh_errno;
00170
00171 if (h_errnop == NULL) {
00172
00173 h_errnop = &lh_errno;
00174 }
00175
00176 if (result == NULL) {
00177
00178 *h_errnop = EINVAL;
00179 return -1;
00180 }
00181
00182 *result = NULL;
00183 if ((name == NULL) || (ret == NULL) || (buf == NULL)) {
00184
00185 *h_errnop = EINVAL;
00186 return -1;
00187 }
00188
00189 namelen = strlen(name);
00190 if (buflen < (sizeof(struct gethostbyname_r_helper) + namelen + 1 + (MEM_ALIGNMENT - 1))) {
00191
00192 *h_errnop = ERANGE;
00193 return -1;
00194 }
00195
00196 h = (struct gethostbyname_r_helper*)LWIP_MEM_ALIGN(buf);
00197 hostname = ((char*)h) + sizeof(struct gethostbyname_r_helper);
00198
00199
00200 err = netconn_gethostbyname(name, &h->addr);
00201 if (err != ERR_OK) {
00202 LWIP_DEBUGF(DNS_DEBUG, ("lwip_gethostbyname(%s) failed, err=%d\n", name, err));
00203 *h_errnop = HOST_NOT_FOUND;
00204 return -1;
00205 }
00206
00207
00208 MEMCPY(hostname, name, namelen);
00209 hostname[namelen] = 0;
00210
00211
00212 h->addr_list[0] = &h->addr;
00213 h->addr_list[1] = NULL;
00214 h->aliases = NULL;
00215 ret->h_name = hostname;
00216 ret->h_aliases = &h->aliases;
00217 ret->h_addrtype = AF_INET;
00218 ret->h_length = sizeof(ip_addr_t);
00219 ret->h_addr_list = (char**)&h->addr_list;
00220
00221
00222 *result = ret;
00223
00224
00225 return 0;
00226 }
00227
00228
00229
00230
00231
00232
00233
00234
00235 void
00236 lwip_freeaddrinfo(struct addrinfo *ai)
00237 {
00238 struct addrinfo *next;
00239
00240 while (ai != NULL) {
00241 next = ai->ai_next;
00242 memp_free(MEMP_NETDB, ai);
00243 ai = next;
00244 }
00245 }
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266 int
00267 lwip_getaddrinfo(const char *nodename, const char *servname,
00268 const struct addrinfo *hints, struct addrinfo **res)
00269 {
00270 err_t err;
00271 ip_addr_t addr;
00272 struct addrinfo *ai;
00273 struct sockaddr_in *sa = NULL;
00274 int port_nr = 0;
00275 size_t total_size;
00276 size_t namelen = 0;
00277
00278 if (res == NULL) {
00279 return EAI_FAIL;
00280 }
00281 *res = NULL;
00282 if ((nodename == NULL) && (servname == NULL)) {
00283 return EAI_NONAME;
00284 }
00285
00286 if (servname != NULL) {
00287
00288
00289 port_nr = atoi(servname);
00290 if ((port_nr <= 0) || (port_nr > 0xffff)) {
00291 return EAI_SERVICE;
00292 }
00293 }
00294
00295 if (nodename != NULL) {
00296
00297 err = netconn_gethostbyname(nodename, &addr);
00298 if (err != ERR_OK) {
00299 return EAI_FAIL;
00300 }
00301 } else {
00302
00303 ip_addr_set_loopback(&addr);
00304 }
00305
00306 total_size = sizeof(struct addrinfo) + sizeof(struct sockaddr_in);
00307 if (nodename != NULL) {
00308 namelen = strlen(nodename);
00309 LWIP_ASSERT("namelen is too long", (namelen + 1) <= (mem_size_t)-1);
00310 total_size += namelen + 1;
00311 }
00312
00313 LWIP_ASSERT("total_size <= NETDB_ELEM_SIZE: please report this!",
00314 total_size <= NETDB_ELEM_SIZE);
00315 ai = (struct addrinfo *)memp_malloc(MEMP_NETDB);
00316 if (ai == NULL) {
00317 goto memerr;
00318 }
00319 memset(ai, 0, total_size);
00320 sa = (struct sockaddr_in*)((u8_t*)ai + sizeof(struct addrinfo));
00321
00322 inet_addr_from_ipaddr(&sa->sin_addr, &addr);
00323 sa->sin_family = AF_INET;
00324 sa->sin_len = sizeof(struct sockaddr_in);
00325 sa->sin_port = htons((u16_t)port_nr);
00326
00327
00328 ai->ai_family = AF_INET;
00329 if (hints != NULL) {
00330
00331 ai->ai_socktype = hints->ai_socktype;
00332 ai->ai_protocol = hints->ai_protocol;
00333 }
00334 if (nodename != NULL) {
00335
00336 ai->ai_canonname = ((char*)ai + sizeof(struct addrinfo) + sizeof(struct sockaddr_in));
00337 MEMCPY(ai->ai_canonname, nodename, namelen);
00338 ai->ai_canonname[namelen] = 0;
00339 }
00340 ai->ai_addrlen = sizeof(struct sockaddr_in);
00341 ai->ai_addr = (struct sockaddr*)sa;
00342
00343 *res = ai;
00344
00345 return 0;
00346 memerr:
00347 if (ai != NULL) {
00348 memp_free(MEMP_NETDB, ai);
00349 }
00350 return EAI_MEMORY;
00351 }
00352
00353 #endif