diff --git a/CHANGELOG b/CHANGELOG index d4bdd666..11608bdf 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -28,7 +28,7 @@ HISTORY 2007-11-16 Simon Goldschmidt * api.h, api_msg.h, api_lib.c, api_msg.c, socket.h, socket.c: Added sequential dns resolver function for netconn api (netconn_gethostbyname) and socket api - (gethostbyname). + (gethostbyname/gethostbyname_r). 2007-11-15 Jim Pettinato, Frédéric Bernon * opt.h, init.c, tcpip.c, dhcp.c, dns.h, dns.c: add DNS client for simple name diff --git a/src/api/sockets.c b/src/api/sockets.c index f85efd8c..06b06ac2 100644 --- a/src/api/sockets.c +++ b/src/api/sockets.c @@ -86,6 +86,14 @@ struct lwip_setgetsockopt_data { err_t err; }; +#if LWIP_DNS +struct gethostbyname_r_helper { + struct ip_addr *addrs; + struct ip_addr addr; + char *aliases; +}; +#endif /* LWIP_DNS */ + static struct lwip_socket sockets[NUM_SOCKETS]; static struct lwip_select_cb *select_cb_list; @@ -1860,6 +1868,62 @@ lwip_gethostbyname(const char *name) return &s_hostent; } + +int +lwip_gethostbyname_r(const char *name, struct hostent *ret, char *buf, + size_t buflen, struct hostent **result, int *h_errnop) +{ + err_t err; + struct gethostbyname_r_helper *h; + char *hostname; + size_t namelen; + + if (result == NULL) { + /* not all arguments given */ + return EINVAL; + } + /* first thing to do: set *result to nothing */ + *result = NULL; + if ((name == NULL) || (ret == NULL) || (buf == 0)) { + /* not all arguments given */ + return EINVAL; + } + + namelen = strlen(name); + if (buflen < (sizeof(struct gethostbyname_r_helper) + namelen + 1 + (MEM_ALIGNMENT - 1))) { + /* buf can't hold the data needed + a copy of name */ + return ERANGE; + } + + h = (struct gethostbyname_r_helper*)LWIP_MEM_ALIGN(buf); + hostname = ((char*)h) + sizeof(struct gethostbyname_r_helper); + + /* query host IP address */ + err = netconn_gethostbyname(name, &(h->addr)); + if (err != ERR_OK) { + LWIP_DEBUGF(DNS_DEBUG, ("lwip_gethostbyname(%s) failed, err=%d\n", name, err)); + return ENSRNOTFOUND; + } + + /* copy the hostname into buf */ + memcpy(hostname, name, namelen); + hostname[namelen] = 0; + + /* fill hostent */ + h->addrs = &(h->addr); + h->aliases = NULL; + ret->h_name = (char*)hostname; + ret->h_aliases = &(h->aliases); + ret->h_addrtype = AF_INET; + ret->h_length = sizeof(struct ip_addr); + ret->h_addr_list = (char**)&(h->addrs); + + /* set result != NULL */ + *result = ret; + + /* return success */ + return 0; +} #endif /* LWIP_DNS*/ #endif /* LWIP_SOCKET */ diff --git a/src/include/lwip/sockets.h b/src/include/lwip/sockets.h index eadeb8ef..de54649f 100644 --- a/src/include/lwip/sockets.h +++ b/src/include/lwip/sockets.h @@ -315,6 +315,8 @@ int lwip_ioctl(int s, long cmd, void *argp); #if LWIP_DNS struct hostent *lwip_gethostbyname(const char *name); +int lwip_gethostbyname_r(const char *name, struct hostent *ret, char *buf, + size_t buflen, struct hostent **result, int *h_errnop); #endif /* LWIP_DNS */ #if LWIP_COMPAT_SOCKETS @@ -336,6 +338,7 @@ struct hostent *lwip_gethostbyname(const char *name); #define select(a,b,c,d,e) lwip_select(a,b,c,d,e) #define ioctlsocket(a,b,c) lwip_ioctl(a,b,c) #define gethostbyname(a) lwip_gethostbyname(a) +#define gethostbyname_r(a,b,c,d,e,f) lwip_gethostbyname_r(a,b,c,d,e,f) #if LWIP_POSIX_SOCKETS_IO_NAMES #define read(a,b,c) lwip_read(a,b,c)