summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/ChangeLog.txt2
-rw-r--r--apps/include/netutils/resolv.h5
-rw-r--r--apps/netutils/dhcpc/dhcpc.c62
-rw-r--r--apps/netutils/resolv/Kconfig9
-rw-r--r--apps/netutils/resolv/resolv.c130
-rw-r--r--apps/netutils/webclient/webclient.c56
-rw-r--r--apps/nshlib/nsh_netcmds.c15
7 files changed, 173 insertions, 106 deletions
diff --git a/apps/ChangeLog.txt b/apps/ChangeLog.txt
index b73f072bc..54a6f5cfa 100644
--- a/apps/ChangeLog.txt
+++ b/apps/ChangeLog.txt
@@ -370,3 +370,5 @@
when I was trying to add correct handling for loss of connection (Darcy Gong)
* apps/nshlib/nsh_telnetd.c: Add support for login to Telnet session via
username and password (Darcy Gong).
+ * apps/netutils/resolv/resolv.c (and files using the DNS resolver): Various
+ DNS address resolution improvements from Darcy Gong.
diff --git a/apps/include/netutils/resolv.h b/apps/include/netutils/resolv.h
index bf71e3b6e..21b9b576c 100644
--- a/apps/include/netutils/resolv.h
+++ b/apps/include/netutils/resolv.h
@@ -74,6 +74,11 @@ EXTERN void resolv_getserver(FAR struct in_addr *dnsserver);
EXTERN int resolv_query(FAR const char *name, FAR struct sockaddr_in *addr);
#endif
+EXTERN int dns_gethostip(const char *hostname, in_addr_t *ipaddr);
+#define dns_setserver resolv_conf
+#define dns_getserver resolv_getserver
+#define dns_whois resolv_query
+
#undef EXTERN
#if defined(__cplusplus)
}
diff --git a/apps/netutils/dhcpc/dhcpc.c b/apps/netutils/dhcpc/dhcpc.c
index 9801242fe..f5e15c8dc 100644
--- a/apps/netutils/dhcpc/dhcpc.c
+++ b/apps/netutils/dhcpc/dhcpc.c
@@ -352,9 +352,9 @@ void *dhcpc_open(const void *macaddr, int maclen)
struct sockaddr_in addr;
struct timeval tv;
- dbg("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
- ((uint8_t*)macaddr)[0], ((uint8_t*)macaddr)[1], ((uint8_t*)macaddr)[2],
- ((uint8_t*)macaddr)[3], ((uint8_t*)macaddr)[4], ((uint8_t*)macaddr)[5]);
+ ndbg("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ ((uint8_t*)macaddr)[0], ((uint8_t*)macaddr)[1], ((uint8_t*)macaddr)[2],
+ ((uint8_t*)macaddr)[3], ((uint8_t*)macaddr)[4], ((uint8_t*)macaddr)[5]);
/* Allocate an internal DHCP structure */
@@ -456,7 +456,7 @@ int dhcpc_request(void *handle, struct dhcpc_state *presult)
{
/* Send the DISCOVER command */
- dbg("Broadcast DISCOVER\n");
+ ndbg("Broadcast DISCOVER\n");
if (dhcpc_sendmsg(pdhcpc, presult, DHCPDISCOVER) < 0)
{
return ERROR;
@@ -474,7 +474,7 @@ int dhcpc_request(void *handle, struct dhcpc_state *presult)
* by a new OFFER.
*/
- dbg("Received OFFER from %08x\n", ntohl(presult->serverid.s_addr));
+ ndbg("Received OFFER from %08x\n", ntohl(presult->serverid.s_addr));
pdhcpc->ipaddr.s_addr = presult->ipaddr.s_addr;
pdhcpc->serverid.s_addr = presult->serverid.s_addr;
@@ -509,7 +509,7 @@ int dhcpc_request(void *handle, struct dhcpc_state *presult)
{
/* Send the REQUEST message to obtain the lease that was offered to us. */
- dbg("Send REQUEST\n");
+ ndbg("Send REQUEST\n");
if (dhcpc_sendmsg(pdhcpc, presult, DHCPREQUEST) < 0)
{
return ERROR;
@@ -531,7 +531,7 @@ int dhcpc_request(void *handle, struct dhcpc_state *presult)
if (msgtype == DHCPACK)
{
- dbg("Received ACK\n");
+ ndbg("Received ACK\n");
state = STATE_HAVE_LEASE;
}
@@ -541,7 +541,7 @@ int dhcpc_request(void *handle, struct dhcpc_state *presult)
else if (msgtype == DHCPNAK)
{
- dbg("Received NAK\n");
+ ndbg("Received NAK\n");
break;
}
@@ -552,7 +552,7 @@ int dhcpc_request(void *handle, struct dhcpc_state *presult)
else if (msgtype == DHCPOFFER)
{
- dbg("Received another OFFER, send DECLINE\n");
+ ndbg("Received another OFFER, send DECLINE\n");
(void)dhcpc_sendmsg(pdhcpc, presult, DHCPDECLINE);
}
@@ -560,7 +560,7 @@ int dhcpc_request(void *handle, struct dhcpc_state *presult)
else
{
- dbg("Ignoring msgtype=%d\n", msgtype);
+ ndbg("Ignoring msgtype=%d\n", msgtype);
}
}
@@ -582,26 +582,26 @@ int dhcpc_request(void *handle, struct dhcpc_state *presult)
}
while (state != STATE_HAVE_LEASE);
- dbg("Got IP address %d.%d.%d.%d\n",
- (presult->ipaddr.s_addr >> 24 ) & 0xff,
- (presult->ipaddr.s_addr >> 16 ) & 0xff,
- (presult->ipaddr.s_addr >> 8 ) & 0xff,
- (presult->ipaddr.s_addr ) & 0xff);
- dbg("Got netmask %d.%d.%d.%d\n",
- (presult->netmask.s_addr >> 24 ) & 0xff,
- (presult->netmask.s_addr >> 16 ) & 0xff,
- (presult->netmask.s_addr >> 8 ) & 0xff,
- (presult->netmask.s_addr ) & 0xff);
- dbg("Got DNS server %d.%d.%d.%d\n",
- (presult->dnsaddr.s_addr >> 24 ) & 0xff,
- (presult->dnsaddr.s_addr >> 16 ) & 0xff,
- (presult->dnsaddr.s_addr >> 8 ) & 0xff,
- (presult->dnsaddr.s_addr ) & 0xff);
- dbg("Got default router %d.%d.%d.%d\n",
- (presult->default_router.s_addr >> 24 ) & 0xff,
- (presult->default_router.s_addr >> 16 ) & 0xff,
- (presult->default_router.s_addr >> 8 ) & 0xff,
- (presult->default_router.s_addr ) & 0xff);
- dbg("Lease expires in %d seconds\n", presult->lease_time);
+ ndbg("Got IP address %d.%d.%d.%d\n",
+ (presult->ipaddr.s_addr ) & 0xff,
+ (presult->ipaddr.s_addr >> 8 ) & 0xff,
+ (presult->ipaddr.s_addr >> 16 ) & 0xff,
+ (presult->ipaddr.s_addr >> 24 ) & 0xff);
+ ndbg("Got netmask %d.%d.%d.%d\n",
+ (presult->netmask.s_addr ) & 0xff,
+ (presult->netmask.s_addr >> 8 ) & 0xff,
+ (presult->netmask.s_addr >> 16 ) & 0xff,
+ (presult->netmask.s_addr >> 24 ) & 0xff);
+ ndbg("Got DNS server %d.%d.%d.%d\n",
+ (presult->dnsaddr.s_addr ) & 0xff,
+ (presult->dnsaddr.s_addr >> 8 ) & 0xff,
+ (presult->dnsaddr.s_addr >> 16 ) & 0xff,
+ (presult->dnsaddr.s_addr >> 24 ) & 0xff);
+ ndbg("Got default router %d.%d.%d.%d\n",
+ (presult->default_router.s_addr ) & 0xff,
+ (presult->default_router.s_addr >> 8 ) & 0xff,
+ (presult->default_router.s_addr >> 16 ) & 0xff,
+ (presult->default_router.s_addr >> 24 ) & 0xff);
+ ndbg("Lease expires in %d seconds\n", presult->lease_time);
return OK;
}
diff --git a/apps/netutils/resolv/Kconfig b/apps/netutils/resolv/Kconfig
index f92d732f5..afbe0eaa5 100644
--- a/apps/netutils/resolv/Kconfig
+++ b/apps/netutils/resolv/Kconfig
@@ -15,3 +15,12 @@ config NET_RESOLV_ENTRIES
depends on NETUTILS_RESOLV
---help---
Number of resolver entries. Default: 8
+
+NET_RESOLV_MAXRESPONSE
+ int "Max response size"
+ default 96
+ depends on NETUTILS_RESOLV
+ ---help---
+ This setting determines the maximum size of DHCP response message that
+ can be received. The default is 96 but may need to be larger on enterprise
+ networks (perhaps 176).
diff --git a/apps/netutils/resolv/resolv.c b/apps/netutils/resolv/resolv.c
index 98d1b28e8..eb60c098e 100644
--- a/apps/netutils/resolv/resolv.c
+++ b/apps/netutils/resolv/resolv.c
@@ -59,11 +59,13 @@
#include <time.h>
#include <errno.h>
#include <debug.h>
+#include <assert.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <apps/netutils/resolv.h>
+#include <apps/netutils/uiplib.h>
/****************************************************************************
* Definitions
@@ -96,7 +98,12 @@
#define DNS_FLAG2_ERR_NAME 0x03
#define SEND_BUFFER_SIZE 64
-#define RECV_BUFFER_SIZE 64
+
+#ifdef CONFIG_NET_RESOLV_MAXRESPONSE
+# define RECV_BUFFER_SIZE CONFIG_NET_RESOLV_MAXRESPONSE
+#else
+# define RECV_BUFFER_SIZE 96
+#endif
#ifdef CONFIG_NET_IPv6
#define ADDRLEN sizeof(struct sockaddr_in6)
@@ -233,6 +240,13 @@ static int send_query(const char *name, struct sockaddr_in *addr)
while(*nameptr != 0);
memcpy(query, endquery, 5);
+
+#ifdef CONFIG_NET_IPv6
+ DEBUGASSERT(((struct sockaddr *)addr)->sa_family == AF_INET6);
+#else
+ DEBUGASSERT(((struct sockaddr *)addr)->sa_family == AF_INET);
+#endif
+
return sendto(g_sockfd, buffer, query + 5 - buffer, 0, (struct sockaddr*)addr, ADDRLEN);
}
@@ -262,10 +276,10 @@ int recv_response(struct sockaddr_in *addr)
hdr = (struct dns_hdr *)buffer;
- dbg( "ID %d\n", htons(hdr->id));
- dbg( "Query %d\n", hdr->flags1 & DNS_FLAG1_RESPONSE);
- dbg( "Error %d\n", hdr->flags2 & DNS_FLAG2_ERR_MASK);
- dbg( "Num questions %d, answers %d, authrr %d, extrarr %d\n",
+ ndbg("ID %d\n", htons(hdr->id));
+ ndbg("Query %d\n", hdr->flags1 & DNS_FLAG1_RESPONSE);
+ ndbg("Error %d\n", hdr->flags2 & DNS_FLAG2_ERR_MASK);
+ ndbg("Num questions %d, answers %d, authrr %d, extrarr %d\n",
htons(hdr->numquestions), htons(hdr->numanswers),
htons(hdr->numauthrr), htons(hdr->numextrarr));
@@ -286,7 +300,28 @@ int recv_response(struct sockaddr_in *addr)
/* Skip the name in the question. XXX: This should really be
* checked agains the name in the question, to be sure that they
* match.
- */
+ */
+
+#ifdef CONFIG_DEBUG_NET
+ {
+ int d = 64;
+ nameptr = parse_name((unsigned char *)buffer + 12) + 4;
+
+ for (;;)
+ {
+ ndbg("%02X %02X %02X %02X %02X %02X %02X %02X \n",
+ nameptr[0],nameptr[1],nameptr[2],nameptr[3],
+ nameptr[4],nameptr[5],nameptr[6],nameptr[7]);
+
+ nameptr += 8;
+ d -= 8;
+ if (d < 0)
+ {
+ break;
+ }
+ }
+ }
+#endif
nameptr = parse_name((unsigned char *)buffer + 12) + 4;
@@ -301,7 +336,7 @@ int recv_response(struct sockaddr_in *addr)
/* Compressed name. */
nameptr +=2;
- dbg("Compressed anwser\n");
+ ndbg("Compressed anwser\n");
}
else
{
@@ -310,21 +345,23 @@ int recv_response(struct sockaddr_in *addr)
}
ans = (struct dns_answer *)nameptr;
- dbg("Answer: type %x, class %x, ttl %x, length %x\n",
- htons(ans->type), htons(ans->class), (htons(ans->ttl[0]) << 16) | htons(ans->ttl[1]),
- htons(ans->len));
+ ndbg("Answer: type %x, class %x, ttl %x, length %x \n", /* 0x%08X\n", */
+ htons(ans->type), htons(ans->class),
+ (htons(ans->ttl[0]) << 16) | htons(ans->ttl[1]),
+ htons(ans->len) /* , ans->ipaddr.s_addr */);
/* Check for IP address type and Internet class. Others are discarded. */
if (ans->type == HTONS(1) && ans->class == HTONS(1) && ans->len == HTONS(4))
{
- dbg("IP address %d.%d.%d.%d\n",
- (ans->ipaddr.s_addr >> 24 ) & 0xff,
- (ans->ipaddr.s_addr >> 16 ) & 0xff,
- (ans->ipaddr.s_addr >> 8 ) & 0xff,
- (ans->ipaddr.s_addr ) & 0xff);
-
- /* XXX: we should really check that this IP address is the one
+ ans->ipaddr.s_addr = *(uint32_t*)(nameptr+10);
+ ndbg("IP address %d.%d.%d.%d\n",
+ (ans->ipaddr.s_addr ) & 0xff,
+ (ans->ipaddr.s_addr >> 8 ) & 0xff,
+ (ans->ipaddr.s_addr >> 16 ) & 0xff,
+ (ans->ipaddr.s_addr >> 24 ) & 0xff);
+
+ /* XXX: we should really check that this IP address is the one
* we want.
*/
@@ -336,6 +373,7 @@ int recv_response(struct sockaddr_in *addr)
nameptr = nameptr + 10 + htons(ans->len);
}
}
+
return ERROR;
}
@@ -343,6 +381,62 @@ int recv_response(struct sockaddr_in *addr)
* Public Functions
****************************************************************************/
+/****************************************************************************
+ * Name: dns_gethostip
+ ****************************************************************************/
+
+int dns_gethostip(const char *hostname, in_addr_t *ipaddr)
+{
+#ifdef CONFIG_HAVE_GETHOSTBYNAME
+
+ struct hostent *he;
+
+ nvdbg("Getting address of %s\n", hostname);
+ he = gethostbyname(hostname);
+ if (!he)
+ {
+ ndbg("gethostbyname failed: %d\n", h_errno);
+ return ERROR;
+ }
+
+ nvdbg("Using IP address %04x%04x\n",
+ (uint16_t)he->h_addr[1], (uint16_t)he->h_addr[0]);
+
+ memcpy(ipaddr, he->h_addr, sizeof(in_addr_t));
+ return OK;
+
+#else
+
+# ifdef CONFIG_NET_IPv6
+ struct sockaddr_in6 addr;
+# else
+ struct sockaddr_in addr;
+# endif
+
+ /* First check if the host is an IP address. */
+
+ if (!uiplib_ipaddrconv(hostname, (uint8_t*)ipaddr))
+ {
+ /* 'host' does not point to a valid address string. Try to resolve
+ * the host name to an IP address.
+ */
+
+ if (resolv_query(hostname, &addr) < 0)
+ {
+ /* Needs to set the errno here */
+
+ return ERROR;
+ }
+
+ /* Save the host address -- Needs fixed for IPv6 */
+
+ *ipaddr = addr.sin_addr.s_addr;
+ }
+ return OK;
+
+#endif
+}
+
/* Get the binding for name. */
#ifdef CONFIG_NET_IPv6
@@ -358,7 +452,7 @@ int resolv_query(FAR const char *name, FAR struct sockaddr_in *addr)
for (retries = 0; retries < 3; retries++)
{
- if (send_query(name, addr) < 0)
+ if (send_query(name, &g_dnsserver) < 0)
{
return ERROR;
}
diff --git a/apps/netutils/webclient/webclient.c b/apps/netutils/webclient/webclient.c
index 5a84c4fd1..8ce7b93a0 100644
--- a/apps/netutils/webclient/webclient.c
+++ b/apps/netutils/webclient/webclient.c
@@ -168,60 +168,6 @@ static char *wget_strcpy(char *dest, const char *src)
}
/****************************************************************************
- * Name: wget_resolvehost
- ****************************************************************************/
-
-static inline int wget_resolvehost(const char *hostname, in_addr_t *ipaddr)
-{
-#ifdef CONFIG_HAVE_GETHOSTBYNAME
-
- struct hostent *he;
-
- nvdbg("Getting address of %s\n", hostname);
- he = gethostbyname(hostname);
- if (!he)
- {
- ndbg("gethostbyname failed: %d\n", h_errno);
- return ERROR;
- }
-
- nvdbg("Using IP address %04x%04x\n", (uint16_t)he->h_addr[1], (uint16_t)he->h_addr[0]);
- memcpy(ipaddr, he->h_addr, sizeof(in_addr_t));
- return OK;
-
-#else
-
-# ifdef CONFIG_NET_IPv6
- struct sockaddr_in6 addr;
-# else
- struct sockaddr_in addr;
-# endif
-
- /* First check if the host is an IP address. */
-
- if (!uiplib_ipaddrconv(hostname, (uint8_t*)ipaddr))
- {
- /* 'host' does not point to a valid address string. Try to resolve
- * the host name to an IP address.
- */
-
- if (resolv_query(hostname, &addr) < 0)
- {
- /* Needs to set the errno here */
-
- return ERROR;
- }
-
- /* Save the host address -- Needs fixed for IPv6 */
-
- *ipaddr = addr.sin_addr.s_addr;
- }
- return OK;
-
-#endif
-}
-
-/****************************************************************************
* Name: wget_parsestatus
****************************************************************************/
@@ -465,7 +411,7 @@ int wget(FAR const char *url, FAR char *buffer, int buflen,
server.sin_family = AF_INET;
server.sin_port = htons(ws.port);
- ret = wget_resolvehost(ws.hostname, &server.sin_addr.s_addr);
+ ret = dns_gethostip(ws.hostname, &server.sin_addr.s_addr);
if (ret < 0)
{
/* Could not resolve host (or malformed IP address) */
diff --git a/apps/nshlib/nsh_netcmds.c b/apps/nshlib/nsh_netcmds.c
index cfea5a08a..e04dab123 100644
--- a/apps/nshlib/nsh_netcmds.c
+++ b/apps/nshlib/nsh_netcmds.c
@@ -51,6 +51,7 @@
#include <fcntl.h> /* Needed for open */
#include <libgen.h> /* Needed for basename */
#include <errno.h>
+#include <debug.h>
#include <nuttx/net/net.h>
#include <nuttx/clock.h>
@@ -80,6 +81,12 @@
# endif
#endif
+#ifdef CONFIG_HAVE_GETHOSTBYNAME
+# include <netdb.h>
+#else
+# include <apps/netutils/resolv.h>
+#endif
+
#include "nsh.h"
#include "nsh_console.h"
@@ -599,7 +606,7 @@ int cmd_ping(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
if (optind == argc-1)
{
staddr = argv[optind];
- if (!uiplib_ipaddrconv(staddr, (FAR unsigned char*)&ipaddr))
+ if (dns_gethostip(staddr, &ipaddr) < 0)
{
goto errout;
}
@@ -621,7 +628,11 @@ int cmd_ping(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
/* Loop for the specified count */
- nsh_output(vtbl, "PING %s %d bytes of data\n", staddr, DEFAULT_PING_DATALEN);
+ nsh_output(vtbl, "PING %d.%d.%d.%d %d bytes of data\n",
+ (ipaddr ) & 0xff, (ipaddr >> 8 ) & 0xff,
+ (ipaddr >> 16 ) & 0xff, (ipaddr >> 24 ) & 0xff,
+ DEFAULT_PING_DATALEN);
+
start = g_system_timer;
for (i = 1; i <= count; i++)
{