Warning, cross-references for /kernel/lwip/api/netdb.c need to be fixed.
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #include "lwip/netdb.h"
0037
0038 #if LWIP_DNS && LWIP_SOCKET
0039
0040 #include "lwip/err.h"
0041 #include "lwip/mem.h"
0042 #include "lwip/ip_addr.h"
0043 #include "lwip/api.h"
0044
0045 #include <string.h>
0046 #include <stdlib.h>
0047
0048
0049 struct gethostbyname_r_helper {
0050 struct ip_addr *addrs;
0051 struct ip_addr addr;
0052 char *aliases;
0053 };
0054
0055
0056 #if LWIP_DNS_API_DECLARE_H_ERRNO
0057 int h_errno;
0058 #endif
0059
0060
0061
0062 #ifndef LWIP_DNS_API_HOSTENT_STORAGE
0063 #define LWIP_DNS_API_HOSTENT_STORAGE 0
0064 #endif
0065
0066
0067 #if LWIP_DNS_API_HOSTENT_STORAGE
0068 #define HOSTENT_STORAGE
0069 #else
0070 #define HOSTENT_STORAGE static
0071 #endif
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082 struct hostent*
0083 lwip_gethostbyname(const char *name)
0084 {
0085 err_t err;
0086 struct ip_addr addr;
0087
0088
0089 HOSTENT_STORAGE struct hostent s_hostent;
0090 HOSTENT_STORAGE char *s_aliases;
0091 HOSTENT_STORAGE struct ip_addr s_hostent_addr;
0092 HOSTENT_STORAGE struct ip_addr *s_phostent_addr;
0093
0094
0095 err = netconn_gethostbyname(name, &addr);
0096 if (err != ERR_OK) {
0097 LWIP_DEBUGF(DNS_DEBUG, ("lwip_gethostbyname(%s) failed, err=%d\n", name, err));
0098 h_errno = HOST_NOT_FOUND;
0099 return NULL;
0100 }
0101
0102
0103 s_hostent_addr = addr;
0104 s_phostent_addr = &s_hostent_addr;
0105 s_hostent.h_name = (char*)name;
0106 s_hostent.h_aliases = &s_aliases;
0107 s_hostent.h_addrtype = AF_INET;
0108 s_hostent.h_length = sizeof(struct ip_addr);
0109 s_hostent.h_addr_list = (char**)&s_phostent_addr;
0110
0111 #if DNS_DEBUG
0112
0113 LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_name == %s\n", s_hostent.h_name));
0114 LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases == %p\n", s_hostent.h_aliases));
0115 if (s_hostent.h_aliases != NULL) {
0116 u8_t idx;
0117 for ( idx=0; s_hostent.h_aliases[idx]; idx++) {
0118 LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases[%i]-> == %p\n", idx, s_hostent.h_aliases[idx]));
0119 LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases[%i]-> == %s\n", idx, s_hostent.h_aliases[idx]));
0120 }
0121 }
0122 LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addrtype == %d\n", s_hostent.h_addrtype));
0123 LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_length == %d\n", s_hostent.h_length));
0124 LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list == %p\n", s_hostent.h_addr_list));
0125 if (s_hostent.h_addr_list != NULL) {
0126 u8_t idx;
0127 for ( idx=0; s_hostent.h_addr_list[idx]; idx++) {
0128 LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i] == %p\n", idx, s_hostent.h_addr_list[idx]));
0129 LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i]-> == %s\n", idx, ip_ntoa(s_hostent.h_addr_list[idx])));
0130 }
0131 }
0132 #endif
0133
0134 #if LWIP_DNS_API_HOSTENT_STORAGE
0135
0136 return sys_thread_hostent(&s_hostent);
0137 #else
0138 return &s_hostent;
0139 #endif
0140 }
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158 int
0159 lwip_gethostbyname_r(const char *name, struct hostent *ret, char *buf,
0160 size_t buflen, struct hostent **result, int *h_errnop)
0161 {
0162 err_t err;
0163 struct gethostbyname_r_helper *h;
0164 char *hostname;
0165 size_t namelen;
0166 int lh_errno;
0167
0168 if (h_errnop == NULL) {
0169
0170 h_errnop = &lh_errno;
0171 }
0172
0173 if (result == NULL) {
0174
0175 *h_errnop = EINVAL;
0176 return -1;
0177 }
0178
0179 *result = NULL;
0180 if ((name == NULL) || (ret == NULL) || (buf == 0)) {
0181
0182 *h_errnop = EINVAL;
0183 return -1;
0184 }
0185
0186 namelen = strlen(name);
0187 if (buflen < (sizeof(struct gethostbyname_r_helper) + namelen + 1 + (MEM_ALIGNMENT - 1))) {
0188
0189 *h_errnop = ERANGE;
0190 return -1;
0191 }
0192
0193 h = (struct gethostbyname_r_helper*)LWIP_MEM_ALIGN(buf);
0194 hostname = ((char*)h) + sizeof(struct gethostbyname_r_helper);
0195
0196
0197 err = netconn_gethostbyname(name, &(h->addr));
0198 if (err != ERR_OK) {
0199 LWIP_DEBUGF(DNS_DEBUG, ("lwip_gethostbyname(%s) failed, err=%d\n", name, err));
0200 *h_errnop = ENSRNOTFOUND;
0201 return -1;
0202 }
0203
0204
0205 MEMCPY(hostname, name, namelen);
0206 hostname[namelen] = 0;
0207
0208
0209 h->addrs = &(h->addr);
0210 h->aliases = NULL;
0211 ret->h_name = (char*)hostname;
0212 ret->h_aliases = &(h->aliases);
0213 ret->h_addrtype = AF_INET;
0214 ret->h_length = sizeof(struct ip_addr);
0215 ret->h_addr_list = (char**)&(h->addrs);
0216
0217
0218 *result = ret;
0219
0220
0221 return 0;
0222 }
0223
0224
0225
0226
0227
0228
0229
0230
0231 void
0232 lwip_freeaddrinfo(struct addrinfo *ai)
0233 {
0234 struct addrinfo *next;
0235
0236 while (ai != NULL) {
0237 next = ai->ai_next;
0238 mem_free(ai);
0239 ai = next;
0240 }
0241 }
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262 int
0263 lwip_getaddrinfo(const char *nodename, const char *servname,
0264 const struct addrinfo *hints, struct addrinfo **res)
0265 {
0266 err_t err;
0267 struct ip_addr addr;
0268 struct addrinfo *ai;
0269 struct sockaddr_in *sa = NULL;
0270 int port_nr = 0;
0271 size_t total_size;
0272 size_t namelen = 0;
0273
0274 if (res == NULL) {
0275 return EAI_FAIL;
0276 }
0277 *res = NULL;
0278 if ((nodename == NULL) && (servname == NULL)) {
0279 return EAI_NONAME;
0280 }
0281
0282 if (servname != NULL) {
0283
0284
0285 port_nr = atoi(servname);
0286 if ((port_nr <= 0) || (port_nr > 0xffff)) {
0287 return EAI_SERVICE;
0288 }
0289 }
0290
0291 if (nodename != NULL) {
0292
0293 err = netconn_gethostbyname(nodename, &addr);
0294 if (err != ERR_OK) {
0295 return EAI_FAIL;
0296 }
0297 } else {
0298
0299 addr.addr = htonl(INADDR_LOOPBACK);
0300 }
0301
0302 total_size = sizeof(struct addrinfo) + sizeof(struct sockaddr_in);
0303 if (nodename != NULL) {
0304 namelen = strlen(nodename);
0305 LWIP_ASSERT("namelen is too long", (namelen + 1) <= (mem_size_t)-1);
0306 total_size += namelen + 1;
0307 }
0308 ai = mem_malloc(total_size);
0309 if (ai == NULL) {
0310 goto memerr;
0311 }
0312 memset(ai, 0, total_size);
0313 sa = (struct sockaddr_in*)((u8_t*)ai + sizeof(struct addrinfo));
0314
0315 sa->sin_addr.s_addr = addr.addr;
0316 sa->sin_family = AF_INET;
0317 sa->sin_len = sizeof(struct sockaddr_in);
0318 sa->sin_port = htons(port_nr);
0319
0320
0321 ai->ai_family = AF_INET;
0322 if (hints != NULL) {
0323
0324 ai->ai_socktype = hints->ai_socktype;
0325 ai->ai_protocol = hints->ai_protocol;
0326 }
0327 if (nodename != NULL) {
0328
0329 ai->ai_canonname = ((char*)ai + sizeof(struct addrinfo) + sizeof(struct sockaddr_in));
0330 MEMCPY(ai->ai_canonname, nodename, namelen);
0331 ai->ai_canonname[namelen] = 0;
0332 }
0333 ai->ai_addrlen = sizeof(struct sockaddr_in);
0334 ai->ai_addr = (struct sockaddr*)sa;
0335
0336 *res = ai;
0337
0338 return 0;
0339 memerr:
0340 if (ai != NULL) {
0341 mem_free(ai);
0342 }
0343 return EAI_MEMORY;
0344 }
0345
0346 #endif