forked from Archive/PX4-Autopilot
DNS fixes from Darcy Gong (part 1 of 2)
git-svn-id: http://svn.code.sf.net/p/nuttx/code/trunk@5235 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
860e5f0524
commit
78ba846c06
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -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);
|
||||
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
|
||||
/* 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;
|
||||
}
|
||||
|
|
|
@ -167,60 +167,6 @@ static char *wget_strcpy(char *dest, const char *src)
|
|||
return dest + len;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* 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) */
|
||||
|
|
|
@ -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++)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue