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