diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2012-10-20 13:47:30 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2012-10-20 13:47:30 +0000 |
commit | 915c0105267a9685d3fa1bc915dc08bbb5883d55 (patch) | |
tree | 748852e6262da138e2481a706be911c0b548df57 /apps | |
parent | e67fe7912645818ff9f4f19481b64fe363f5d357 (diff) | |
download | px4-nuttx-915c0105267a9685d3fa1bc915dc08bbb5883d55.tar.gz px4-nuttx-915c0105267a9685d3fa1bc915dc08bbb5883d55.tar.bz2 px4-nuttx-915c0105267a9685d3fa1bc915dc08bbb5883d55.zip |
DNS fixes from Darcy Gong (part 1 of 2)
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5235 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'apps')
-rw-r--r-- | apps/ChangeLog.txt | 2 | ||||
-rw-r--r-- | apps/include/netutils/resolv.h | 5 | ||||
-rw-r--r-- | apps/netutils/dhcpc/dhcpc.c | 62 | ||||
-rw-r--r-- | apps/netutils/resolv/Kconfig | 9 | ||||
-rw-r--r-- | apps/netutils/resolv/resolv.c | 130 | ||||
-rw-r--r-- | apps/netutils/webclient/webclient.c | 56 | ||||
-rw-r--r-- | apps/nshlib/nsh_netcmds.c | 15 |
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++) { |