mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-10-01 04:12:07 +00:00
opt.h, init.c, tcpip.c, dhcp.c, dns.h, dns.c: add DNS client for simple name requests with RAW api interface. Initialization is done in lwip_init() with build time options. DNS timer is added in tcpip_thread context. DHCP can set DNS server ip addresses when options are received. You need to set LWIP_DNS=1 in your lwipopts.h file (LWIP_DNS=0 in opt.h). DNS_DEBUG can be set to get some traces with LWIP_DEBUGF. Sanity check have been added. There is a "todo" list with points to improve.
This commit is contained in:
parent
a4d14722f3
commit
0c0e8d6544
@ -19,6 +19,15 @@ HISTORY
|
|||||||
|
|
||||||
++ New features:
|
++ New features:
|
||||||
|
|
||||||
|
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
|
||||||
|
requests with RAW api interface. Initialization is done in lwip_init() with
|
||||||
|
build time options. DNS timer is added in tcpip_thread context. DHCP can set
|
||||||
|
DNS server ip addresses when options are received. You need to set LWIP_DNS=1
|
||||||
|
in your lwipopts.h file (LWIP_DNS=0 in opt.h). DNS_DEBUG can be set to get
|
||||||
|
some traces with LWIP_DEBUGF. Sanity check have been added. There is a "todo"
|
||||||
|
list with points to improve.
|
||||||
|
|
||||||
2007-11-06 Simon Goldschmidt
|
2007-11-06 Simon Goldschmidt
|
||||||
* opt.h, mib2.c: Patch #6215: added ifAdminStatus write support (if explicitly
|
* opt.h, mib2.c: Patch #6215: added ifAdminStatus write support (if explicitly
|
||||||
enabled by defining SNMP_SAFE_REQUESTS to 0); added code to check link status
|
enabled by defining SNMP_SAFE_REQUESTS to 0); added code to check link status
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
#include "lwip/autoip.h"
|
#include "lwip/autoip.h"
|
||||||
#include "lwip/dhcp.h"
|
#include "lwip/dhcp.h"
|
||||||
#include "lwip/igmp.h"
|
#include "lwip/igmp.h"
|
||||||
|
#include "lwip/dns.h"
|
||||||
#include "lwip/tcpip.h"
|
#include "lwip/tcpip.h"
|
||||||
#include "lwip/init.h"
|
#include "lwip/init.h"
|
||||||
#include "netif/etharp.h"
|
#include "netif/etharp.h"
|
||||||
@ -202,6 +203,22 @@ igmp_timer(void *arg)
|
|||||||
}
|
}
|
||||||
#endif /* LWIP_IGMP */
|
#endif /* LWIP_IGMP */
|
||||||
|
|
||||||
|
#if LWIP_DNS
|
||||||
|
/**
|
||||||
|
* Timer callback function that calls dns_tmr() and reschedules itself.
|
||||||
|
*
|
||||||
|
* @param arg unused argument
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
dns_timer(void *arg)
|
||||||
|
{
|
||||||
|
LWIP_UNUSED_ARG(arg);
|
||||||
|
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip: dns_tmr()\n"));
|
||||||
|
dns_tmr();
|
||||||
|
sys_timeout(DNS_TMR_INTERVAL, dns_timer, NULL);
|
||||||
|
}
|
||||||
|
#endif /* LWIP_DNS */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The main lwIP thread. This thread has exclusive access to lwIP core functions
|
* The main lwIP thread. This thread has exclusive access to lwIP core functions
|
||||||
* (unless access to them is not locked). Other threads communicate with this
|
* (unless access to them is not locked). Other threads communicate with this
|
||||||
@ -234,6 +251,9 @@ tcpip_thread(void *arg)
|
|||||||
#if LWIP_IGMP
|
#if LWIP_IGMP
|
||||||
sys_timeout(IGMP_TMR_INTERVAL, igmp_timer, NULL);
|
sys_timeout(IGMP_TMR_INTERVAL, igmp_timer, NULL);
|
||||||
#endif /* LWIP_IGMP */
|
#endif /* LWIP_IGMP */
|
||||||
|
#if LWIP_DNS
|
||||||
|
sys_timeout(DNS_TMR_INTERVAL, dns_timer, NULL);
|
||||||
|
#endif /* LWIP_DNS */
|
||||||
|
|
||||||
if (tcpip_init_done != NULL) {
|
if (tcpip_init_done != NULL) {
|
||||||
tcpip_init_done(tcpip_init_done_arg);
|
tcpip_init_done(tcpip_init_done_arg);
|
||||||
|
@ -81,6 +81,7 @@
|
|||||||
#include "lwip/sys.h"
|
#include "lwip/sys.h"
|
||||||
#include "lwip/dhcp.h"
|
#include "lwip/dhcp.h"
|
||||||
#include "lwip/autoip.h"
|
#include "lwip/autoip.h"
|
||||||
|
#include "lwip/dns.h"
|
||||||
#include "netif/etharp.h"
|
#include "netif/etharp.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -517,6 +518,9 @@ static void dhcp_handle_ack(struct netif *netif)
|
|||||||
dhcp->dns_count = DHCP_MAX_DNS;
|
dhcp->dns_count = DHCP_MAX_DNS;
|
||||||
for (n = 0; n < dhcp->dns_count; n++) {
|
for (n = 0; n < dhcp->dns_count; n++) {
|
||||||
dhcp->offered_dns_addr[n].addr = htonl(dhcp_get_option_long(&option_ptr[2 + n * 4]));
|
dhcp->offered_dns_addr[n].addr = htonl(dhcp_get_option_long(&option_ptr[2 + n * 4]));
|
||||||
|
#if LWIP_DNS
|
||||||
|
dns_setserver( n, (struct ip_addr *)(&(dhcp->offered_dns_addr[n].addr)));
|
||||||
|
#endif /* LWIP_DNS */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
640
src/core/dns.c
Normal file
640
src/core/dns.c
Normal file
@ -0,0 +1,640 @@
|
|||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* DNS - host name to IP address resolver.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
* This file implements a DNS host name to IP address resolver.
|
||||||
|
|
||||||
|
* Port to lwIP from uIP
|
||||||
|
* by Jim Pettinato April 2007
|
||||||
|
|
||||||
|
* uIP version Copyright (c) 2002-2003, Adam Dunkels.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior
|
||||||
|
* written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||||
|
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||||
|
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* DNS.C
|
||||||
|
*
|
||||||
|
* The lwIP DNS resolver functions are used to lookup a host name and
|
||||||
|
* map it to a numerical IP address. It maintains a list of resolved
|
||||||
|
* hostnames that can be queried with the dns_lookup() function.
|
||||||
|
* New hostnames can be resolved using the dns_query() function.
|
||||||
|
*
|
||||||
|
* The lwIP version of the resolver also adds a non-blocking version of
|
||||||
|
* gethostbyname() that will work with a raw API application. This function
|
||||||
|
* checks for an IP address string first and converts it if it is valid.
|
||||||
|
* gethostbyname() then does a dns_lookup() to see if the name is
|
||||||
|
* already in the table. If so, the IP is returned. If not, a query is
|
||||||
|
* issued and the function returns with a DNS_QUERY_QUEUED status. The app
|
||||||
|
* using the dns client must then go into a waiting state.
|
||||||
|
*
|
||||||
|
* Once a hostname has been resolved (or found to be non-existent),
|
||||||
|
* the resolver code calls a specified callback function (which
|
||||||
|
* must be implemented by the module that uses the resolver).
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @todo: define good default values (rfc compliance) */
|
||||||
|
/** @todo: secondary server support */
|
||||||
|
/** @todo: compressed answer support */
|
||||||
|
/** @todo: improve answer parsing, more checkings... */
|
||||||
|
/** @todo: possible alignment problems to access to dns_answer fields? */
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------
|
||||||
|
* RFC 1035 - Domain names - implementation and specification
|
||||||
|
* RFC 2181 - Clarifications to the DNS Specification
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------
|
||||||
|
* Includes
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "lwip/opt.h"
|
||||||
|
|
||||||
|
#if LWIP_DNS /* don't build if not configured for use in lwipopts.h */
|
||||||
|
|
||||||
|
#include "lwip/udp.h"
|
||||||
|
#include "lwip/dns.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/** DNS server IP address */
|
||||||
|
#ifndef DNS_SERVER_ADDRESS
|
||||||
|
#define DNS_SERVER_ADDRESS inet_addr("208.67.222.222") /* resolver1.opendns.com */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** DNS server port address */
|
||||||
|
#ifndef DNS_SERVER_PORT
|
||||||
|
#define DNS_SERVER_PORT 53
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The maximum number of table entries to maintain locally */
|
||||||
|
#ifndef DNS_TABLE_SIZE
|
||||||
|
#define DNS_TABLE_SIZE 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The maximum length of a host name supported in the name table. */
|
||||||
|
#ifndef DNS_MAX_NAME_LENGTH
|
||||||
|
#define DNS_MAX_NAME_LENGTH 256
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The maximum number of retries when asking for a name, before "timeout". */
|
||||||
|
#ifndef DNS_MAX_RETRIES
|
||||||
|
#define DNS_MAX_RETRIES 8
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* DNS entry time to live (in DNS_TMR_INTERVAL ticks) */
|
||||||
|
#ifndef DNS_TTL_ENTRY
|
||||||
|
#define DNS_TTL_ENTRY 60
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* DNS protocol flags */
|
||||||
|
#define DNS_FLAG1_RESPONSE 0x80
|
||||||
|
#define DNS_FLAG1_OPCODE_STATUS 0x10
|
||||||
|
#define DNS_FLAG1_OPCODE_INVERSE 0x08
|
||||||
|
#define DNS_FLAG1_OPCODE_STANDARD 0x00
|
||||||
|
#define DNS_FLAG1_AUTHORATIVE 0x04
|
||||||
|
#define DNS_FLAG1_TRUNC 0x02
|
||||||
|
#define DNS_FLAG1_RD 0x01
|
||||||
|
#define DNS_FLAG2_RA 0x80
|
||||||
|
#define DNS_FLAG2_ERR_MASK 0x0f
|
||||||
|
#define DNS_FLAG2_ERR_NONE 0x00
|
||||||
|
#define DNS_FLAG2_ERR_NAME 0x03
|
||||||
|
|
||||||
|
/* DNS protocol states */
|
||||||
|
#define DNS_STATE_UNUSED 0
|
||||||
|
#define DNS_STATE_NEW 1
|
||||||
|
#define DNS_STATE_ASKING 2
|
||||||
|
#define DNS_STATE_DONE 3
|
||||||
|
|
||||||
|
/* DNS field TYPE used for "Resource Records" */
|
||||||
|
#define DNS_RRTYPE_A 1 /* a host address */
|
||||||
|
#define DNS_RRTYPE_NS 2 /* an authoritative name server */
|
||||||
|
#define DNS_RRTYPE_MD 3 /* a mail destination (Obsolete - use MX) */
|
||||||
|
#define DNS_RRTYPE_MF 4 /* a mail forwarder (Obsolete - use MX) */
|
||||||
|
#define DNS_RRTYPE_CNAME 5 /* the canonical name for an alias */
|
||||||
|
#define DNS_RRTYPE_SOA 6 /* marks the start of a zone of authority */
|
||||||
|
#define DNS_RRTYPE_MB 7 /* a mailbox domain name (EXPERIMENTAL) */
|
||||||
|
#define DNS_RRTYPE_MG 8 /* a mail group member (EXPERIMENTAL) */
|
||||||
|
#define DNS_RRTYPE_MR 9 /* a mail rename domain name (EXPERIMENTAL) */
|
||||||
|
#define DNS_RRTYPE_NULL 10 /* a null RR (EXPERIMENTAL) */
|
||||||
|
#define DNS_RRTYPE_WKS 11 /* a well known service description */
|
||||||
|
#define DNS_RRTYPE_PTR 12 /* a domain name pointer */
|
||||||
|
#define DNS_RRTYPE_HINFO 13 /* host information */
|
||||||
|
#define DNS_RRTYPE_MINFO 14 /* mailbox or mail list information */
|
||||||
|
#define DNS_RRTYPE_MX 15 /* mail exchange */
|
||||||
|
#define DNS_RRTYPE_TXT 16 /* text strings */
|
||||||
|
|
||||||
|
/* DNS field CLASS used for "Resource Records" */
|
||||||
|
#define DNS_RRCLASS_IN 1 /* the Internet */
|
||||||
|
#define DNS_RRCLASS_CS 2 /* the CSNET class (Obsolete - used only for examples in some obsolete RFCs) */
|
||||||
|
#define DNS_RRCLASS_CH 3 /* the CHAOS class */
|
||||||
|
#define DNS_RRCLASS_HS 4 /* Hesiod [Dyer 87] */
|
||||||
|
#define DNS_RRCLASS_FLUSH 0x800 /* Flush bit */
|
||||||
|
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/bpstruct.h"
|
||||||
|
#endif
|
||||||
|
PACK_STRUCT_BEGIN
|
||||||
|
/** DNS message header */
|
||||||
|
struct dns_hdr {
|
||||||
|
u16_t id;
|
||||||
|
u8_t flags1;
|
||||||
|
u8_t flags2;
|
||||||
|
u16_t numquestions;
|
||||||
|
u16_t numanswers;
|
||||||
|
u16_t numauthrr;
|
||||||
|
u16_t numextrarr;
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
PACK_STRUCT_END
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/epstruct.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/bpstruct.h"
|
||||||
|
#endif
|
||||||
|
PACK_STRUCT_BEGIN
|
||||||
|
/** DNS answer message structure */
|
||||||
|
struct dns_answer {
|
||||||
|
/* DNS answer record starts with either a domain name or a pointer
|
||||||
|
to a name already present somewhere in the packet. */
|
||||||
|
u16_t type;
|
||||||
|
u16_t class;
|
||||||
|
u32_t ttl;
|
||||||
|
u16_t len;
|
||||||
|
struct ip_addr ipaddr;
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
PACK_STRUCT_END
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/epstruct.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/bpstruct.h"
|
||||||
|
#endif
|
||||||
|
PACK_STRUCT_BEGIN
|
||||||
|
/** DNS table entry */
|
||||||
|
struct dns_table_entry {
|
||||||
|
u8_t state;
|
||||||
|
u8_t tmr;
|
||||||
|
u8_t retries;
|
||||||
|
u8_t ttl;
|
||||||
|
u8_t seqno;
|
||||||
|
u8_t err;
|
||||||
|
char name[DNS_MAX_NAME_LENGTH];
|
||||||
|
struct ip_addr ipaddr;
|
||||||
|
void (* found)(char *name, struct ip_addr *ipaddr, void *arg); /* pointer to callback on DNS query done */
|
||||||
|
void *arg;
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
PACK_STRUCT_END
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/epstruct.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* forward declarations */
|
||||||
|
static void dns_recv(void *s, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port);
|
||||||
|
static void dns_check_entries(void);
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------
|
||||||
|
* Globales
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* DNS variables */
|
||||||
|
static struct udp_pcb *dns_pcb;
|
||||||
|
static struct dns_table_entry dns_table[DNS_TABLE_SIZE];
|
||||||
|
static u8_t dns_seqno;
|
||||||
|
|
||||||
|
/* DNS request termination sequence: zero(1)+type(2)+class(2) */
|
||||||
|
static unsigned char dns_endquery[] = {0,0,1,0,1};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the resolver and configure which DNS server to use for queries.
|
||||||
|
*
|
||||||
|
* param dnsserver A pointer to a 4-byte representation of the IP
|
||||||
|
* address of the DNS server to be configured.
|
||||||
|
*/
|
||||||
|
err_t
|
||||||
|
dns_init()
|
||||||
|
{
|
||||||
|
u8_t i;
|
||||||
|
struct ip_addr dnsserver = {DNS_SERVER_ADDRESS};
|
||||||
|
|
||||||
|
LWIP_DEBUGF(DNS_DEBUG, ("dns_init: initializing\n"));
|
||||||
|
|
||||||
|
/* if dns client not yet initialized... */
|
||||||
|
if (dns_pcb == NULL) {
|
||||||
|
dns_pcb = udp_new();
|
||||||
|
|
||||||
|
if (dns_pcb != NULL) {
|
||||||
|
/* initialize DNS table */
|
||||||
|
for (i=0; i<DNS_TABLE_SIZE; ++i) {
|
||||||
|
dns_table[i].state = DNS_STATE_UNUSED;
|
||||||
|
dns_table[i].found = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* initialize DNS client */
|
||||||
|
udp_bind(dns_pcb, IP_ADDR_ANY, 0);
|
||||||
|
udp_recv(dns_pcb, dns_recv, NULL);
|
||||||
|
|
||||||
|
/* initialize default DNS primary server */
|
||||||
|
dns_setserver(0, &dnsserver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain the currently configured DNS server.
|
||||||
|
* return unsigned long encoding of the IP address of
|
||||||
|
* the currently configured DNS server or NULL if no DNS server has
|
||||||
|
* been configured.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
dns_setserver(u8_t numdns, struct ip_addr *dnsserver)
|
||||||
|
{
|
||||||
|
LWIP_UNUSED_ARG(numdns);
|
||||||
|
if ((dns_pcb != NULL) && (dnsserver != NULL) && (dnsserver->addr !=0 )) {
|
||||||
|
udp_connect( dns_pcb, dnsserver, DNS_SERVER_PORT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain the currently configured DNS server.
|
||||||
|
* return unsigned long encoding of the IP address of
|
||||||
|
* the currently configured DNS server or NULL if no DNS server has
|
||||||
|
* been configured.
|
||||||
|
*/
|
||||||
|
u32_t
|
||||||
|
dns_getserver(u8_t numdns)
|
||||||
|
{
|
||||||
|
LWIP_UNUSED_ARG(numdns);
|
||||||
|
return ((dns_pcb != NULL)?dns_pcb->remote_ip.addr:0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The DNS resolver client timer - handle retries and timeouts
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
dns_tmr(void)
|
||||||
|
{
|
||||||
|
if (dns_pcb != NULL) {
|
||||||
|
LWIP_DEBUGF(DNS_DEBUG, ("dns_tmr: dns_check_entries\n"));
|
||||||
|
dns_check_entries();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Look up a hostname in the array of known hostnames.
|
||||||
|
*
|
||||||
|
* \note This function only looks in the internal array of known
|
||||||
|
* hostnames, it does not send out a query for the hostname if none
|
||||||
|
* was found. The function dns_query() can be used to send a query
|
||||||
|
* for a hostname.
|
||||||
|
*
|
||||||
|
* return A pointer to a 4-byte representation of the hostname's IP
|
||||||
|
* address, or NULL if the hostname was not found in the array of
|
||||||
|
* hostnames.
|
||||||
|
*/
|
||||||
|
u32_t
|
||||||
|
dns_lookup(char *name)
|
||||||
|
{
|
||||||
|
u8_t i;
|
||||||
|
|
||||||
|
/* Walk through name list, return entry if found. If not, return NULL. */
|
||||||
|
for (i=0; i<DNS_TABLE_SIZE; ++i) {
|
||||||
|
if ( (dns_table[i].state==DNS_STATE_DONE) && (strcmp(name, dns_table[i].name)==0) ) {
|
||||||
|
LWIP_DEBUGF(DNS_DEBUG, ("dns_lookup: \"%s\": found = ", name));
|
||||||
|
ip_addr_debug_print(DNS_DEBUG, (&(dns_table[i].ipaddr)));
|
||||||
|
LWIP_DEBUGF(DNS_DEBUG, ("\n"));
|
||||||
|
return dns_table[i].ipaddr.addr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dns_parse_name() - walk through a compact encoded DNS name and return the end
|
||||||
|
* of the name.
|
||||||
|
*/
|
||||||
|
static unsigned char *
|
||||||
|
dns_parse_name(unsigned char *query)
|
||||||
|
{
|
||||||
|
unsigned char n;
|
||||||
|
|
||||||
|
do {
|
||||||
|
n = *query++;
|
||||||
|
|
||||||
|
while(n > 0) {
|
||||||
|
++query;
|
||||||
|
--n;
|
||||||
|
};
|
||||||
|
} while(*query != 0);
|
||||||
|
|
||||||
|
return query + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dns_send
|
||||||
|
*/
|
||||||
|
static err_t
|
||||||
|
dns_send( char* name, u8_t id)
|
||||||
|
{
|
||||||
|
struct dns_hdr *hdr;
|
||||||
|
struct pbuf *p;
|
||||||
|
char *query, *nptr, *pHostname;
|
||||||
|
u8_t n;
|
||||||
|
|
||||||
|
LWIP_DEBUGF(DNS_DEBUG, ("dns_send: \"%s\": request\n", name));
|
||||||
|
|
||||||
|
/* if here, we have either a new query or a retry on a previous query to process */
|
||||||
|
p = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dns_hdr)+DNS_MAX_NAME_LENGTH+sizeof(dns_endquery), PBUF_RAM);
|
||||||
|
if (p) {
|
||||||
|
hdr = (struct dns_hdr *)p->payload;
|
||||||
|
memset(hdr, 0, sizeof(struct dns_hdr));
|
||||||
|
hdr->id = htons(id);
|
||||||
|
hdr->flags1 = DNS_FLAG1_RD;
|
||||||
|
hdr->numquestions = htons(1);
|
||||||
|
query = (char *)hdr + sizeof(struct dns_hdr);
|
||||||
|
pHostname = name;
|
||||||
|
--pHostname;
|
||||||
|
/* convert hostname into suitable query format. */
|
||||||
|
do {
|
||||||
|
++pHostname;
|
||||||
|
nptr = query;
|
||||||
|
++query;
|
||||||
|
for(n = 0; *pHostname != '.' && *pHostname != 0; ++pHostname) {
|
||||||
|
*query = *pHostname;
|
||||||
|
++query;
|
||||||
|
++n;
|
||||||
|
}
|
||||||
|
*nptr = n;
|
||||||
|
} while(*pHostname != 0);
|
||||||
|
|
||||||
|
memcpy( query, dns_endquery, sizeof(dns_endquery));
|
||||||
|
|
||||||
|
// resize pbuf to the exact dns query
|
||||||
|
pbuf_realloc(p, (query+sizeof(dns_endquery))-((char*)(p->payload)));
|
||||||
|
|
||||||
|
// send dns packet
|
||||||
|
udp_send(dns_pcb, p);
|
||||||
|
|
||||||
|
// free pbuf
|
||||||
|
pbuf_free(p);
|
||||||
|
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERR_BUF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dns_check_entries() - Runs through the list of names to see if there are any
|
||||||
|
* that have not yet been queried and, if so, sends out a query.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
dns_check_entries(void)
|
||||||
|
{
|
||||||
|
u8_t i;
|
||||||
|
struct dns_table_entry *pEntry;
|
||||||
|
|
||||||
|
for (i = 0; i < DNS_TABLE_SIZE; ++i) {
|
||||||
|
pEntry = &dns_table[i];
|
||||||
|
switch(pEntry->state) {
|
||||||
|
|
||||||
|
case DNS_STATE_NEW:
|
||||||
|
case DNS_STATE_ASKING: {
|
||||||
|
if (pEntry->state == DNS_STATE_ASKING) {
|
||||||
|
if (--pEntry->tmr == 0) {
|
||||||
|
if (++pEntry->retries == DNS_MAX_RETRIES) {
|
||||||
|
LWIP_DEBUGF(DNS_DEBUG, ("dns_check_entries: \"%s\": timeout\n", pEntry->name));
|
||||||
|
/* call specified callback function if provided */
|
||||||
|
if (pEntry->found)
|
||||||
|
(*pEntry->found)(pEntry->name, NULL, pEntry->arg);
|
||||||
|
/* flush this entry */
|
||||||
|
pEntry->state = DNS_STATE_UNUSED;
|
||||||
|
pEntry->found = NULL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* wait longer for the next retry */
|
||||||
|
pEntry->tmr = pEntry->retries;
|
||||||
|
} else {
|
||||||
|
/* Its timer has not run out, so we move on to next entry. */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pEntry->state = DNS_STATE_ASKING;
|
||||||
|
pEntry->tmr = 1;
|
||||||
|
pEntry->retries = 0;
|
||||||
|
}
|
||||||
|
/* send DNS packet for this entry */
|
||||||
|
dns_send(pEntry->name, i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case DNS_STATE_DONE: {
|
||||||
|
/* if the time to live is nul */
|
||||||
|
if (--pEntry->ttl == 0) {
|
||||||
|
LWIP_DEBUGF(DNS_DEBUG, ("dns_check_entries: \"%s\": flush\n", pEntry->name));
|
||||||
|
/* flush this entry */
|
||||||
|
pEntry->state = DNS_STATE_UNUSED;
|
||||||
|
pEntry->found = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback for DNS responses
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
dns_recv(void *s, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port)
|
||||||
|
{
|
||||||
|
u8_t i;
|
||||||
|
char *pHostname;
|
||||||
|
struct dns_answer *ans;
|
||||||
|
struct dns_hdr *hdr;
|
||||||
|
struct dns_table_entry *pEntry;
|
||||||
|
u8_t nquestions, nanswers;
|
||||||
|
|
||||||
|
hdr = (struct dns_hdr *)p->payload;
|
||||||
|
|
||||||
|
/* The ID in the DNS header should be our entry into the name table. */
|
||||||
|
i = htons(hdr->id);
|
||||||
|
pEntry = &dns_table[i];
|
||||||
|
if( (i < DNS_TABLE_SIZE) && (pEntry->state == DNS_STATE_ASKING) ) {
|
||||||
|
/* This entry is now completed. */
|
||||||
|
pEntry->state = DNS_STATE_DONE;
|
||||||
|
pEntry->ttl = DNS_TTL_ENTRY;
|
||||||
|
pEntry->err = hdr->flags2 & DNS_FLAG2_ERR_MASK;
|
||||||
|
|
||||||
|
/* Check for error. If so, call callback to inform. */
|
||||||
|
if(pEntry->err != 0) {
|
||||||
|
LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": error in flags\n", pEntry->name));
|
||||||
|
/* call specified callback function if provided */
|
||||||
|
if (pEntry->found)
|
||||||
|
(*pEntry->found)(pEntry->name, NULL, pEntry->arg);
|
||||||
|
/* flush this entry */
|
||||||
|
pEntry->state = DNS_STATE_UNUSED;
|
||||||
|
pEntry->found = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We only care about the question(s) and the answers. The authrr
|
||||||
|
and the extrarr are simply discarded. */
|
||||||
|
nquestions = htons(hdr->numquestions);
|
||||||
|
nanswers = htons(hdr->numanswers);
|
||||||
|
|
||||||
|
/* Skip the name in the question. XXX: This should really be checked
|
||||||
|
agains the name in the question, to be sure that they match. */
|
||||||
|
pHostname = (char *) dns_parse_name((unsigned char *)p->payload + sizeof(struct dns_hdr)) + 4/*type(2)+class(2)*/;
|
||||||
|
|
||||||
|
while(nanswers > 0) {
|
||||||
|
/* The first byte in the answer resource record determines if it
|
||||||
|
is a compressed record or a normal one. */
|
||||||
|
if(*pHostname & 0xc0) {
|
||||||
|
/* Compressed name. */
|
||||||
|
pHostname +=2;
|
||||||
|
/* printf("Compressed anwser\n");*/
|
||||||
|
} else {
|
||||||
|
/* Not compressed name. */
|
||||||
|
pHostname = (char *) dns_parse_name((unsigned char *)pHostname);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: isn't it any problem to access to dns_answer fields since pHostname's length can be unaligned? */
|
||||||
|
ans = (struct dns_answer *)pHostname;
|
||||||
|
/* printf("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));*/
|
||||||
|
|
||||||
|
/* Check for IP address type and Internet class. Others are discarded. */
|
||||||
|
if((ntohs(ans->type) == DNS_RRTYPE_A) && (ntohs(ans->class) == DNS_RRCLASS_IN) && (ntohs(ans->len) == 4/*IPv4 address*/) ) {
|
||||||
|
/* TODO: we should really check that this IP address is the one we want. */
|
||||||
|
pEntry->ipaddr = ans->ipaddr;
|
||||||
|
LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": response = ", pEntry->name));
|
||||||
|
ip_addr_debug_print(DNS_DEBUG, (&(pEntry->ipaddr)));
|
||||||
|
LWIP_DEBUGF(DNS_DEBUG, ("\n"));
|
||||||
|
/* call specified callback function if provided */
|
||||||
|
if (pEntry->found)
|
||||||
|
(*pEntry->found)(pEntry->name, &pEntry->ipaddr, pEntry->arg);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
pHostname = pHostname + 10 + htons(ans->len);
|
||||||
|
}
|
||||||
|
--nanswers;
|
||||||
|
}
|
||||||
|
LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": error in response\n", pEntry->name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queues a name so that a question for the name will be sent out.
|
||||||
|
* param name - The hostname that is to be queried.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
dns_query(char *name, void (*found)(char *name, struct ip_addr *addr, void *arg), void *arg)
|
||||||
|
{
|
||||||
|
u8_t i;
|
||||||
|
u8_t lseq, lseqi;
|
||||||
|
struct dns_table_entry *pEntry;
|
||||||
|
|
||||||
|
/* search an unused entry, or the oldest one */
|
||||||
|
lseq = lseqi = 0;
|
||||||
|
for (i = 0; i < DNS_TABLE_SIZE; ++i) {
|
||||||
|
pEntry = &dns_table[i];
|
||||||
|
/* is it an unused entry ? */
|
||||||
|
if (pEntry->state == DNS_STATE_UNUSED)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* check if this is the oldest entry used */
|
||||||
|
if (dns_seqno - pEntry->seqno > lseq) {
|
||||||
|
lseq = dns_seqno - pEntry->seqno;
|
||||||
|
lseqi = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if we don't have found an unused entry, use the oldest one */
|
||||||
|
if (i == DNS_TABLE_SIZE) {
|
||||||
|
i = lseqi;
|
||||||
|
pEntry = &dns_table[i];
|
||||||
|
/* since we replace the previous entry, we "unblock" the caller */
|
||||||
|
LWIP_DEBUGF(DNS_DEBUG, ("dns_query: \"%s\": replaced by new entry\n", pEntry->name));
|
||||||
|
/* call specified callback function if provided */
|
||||||
|
if (pEntry->found)
|
||||||
|
(*pEntry->found)(pEntry->name, NULL, pEntry->arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fill the entry */
|
||||||
|
strcpy(pEntry->name, name);
|
||||||
|
pEntry->found = found;
|
||||||
|
pEntry->arg = arg;
|
||||||
|
pEntry->state = DNS_STATE_NEW;
|
||||||
|
pEntry->seqno = dns_seqno++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NON-BLOCKING callback version for use with raw API
|
||||||
|
*/
|
||||||
|
DNS_RESULT dns_gethostbyname(char *hostname, struct ip_addr *addr,
|
||||||
|
void (*found)(char *name, struct ip_addr *ipaddr, void *arg),
|
||||||
|
void *arg
|
||||||
|
)
|
||||||
|
{
|
||||||
|
/* not initialized or no valid server yet, or invalid addr pointer */
|
||||||
|
if ((dns_pcb == NULL) || (addr == NULL))
|
||||||
|
return DNS_QUERY_INVALID;
|
||||||
|
|
||||||
|
/* invalid hostname */
|
||||||
|
if ((!hostname) || (!hostname[0]))
|
||||||
|
return DNS_QUERY_INVALID;
|
||||||
|
|
||||||
|
/* invalid hostname length */
|
||||||
|
if (strlen(hostname) >= DNS_MAX_NAME_LENGTH)
|
||||||
|
return DNS_QUERY_INVALID;
|
||||||
|
|
||||||
|
/* host name already in octet notation? set ip addr and return COMPLETE */
|
||||||
|
if ((addr->addr = inet_addr(hostname)) != INADDR_NONE)
|
||||||
|
return DNS_COMPLETE;
|
||||||
|
|
||||||
|
/* already have this address cached? */
|
||||||
|
if ((addr->addr = dns_lookup(hostname)) != 0)
|
||||||
|
return DNS_COMPLETE;
|
||||||
|
|
||||||
|
/* queue query with specified callback */
|
||||||
|
dns_query(hostname, found, arg);
|
||||||
|
|
||||||
|
/* force to send request */
|
||||||
|
dns_check_entries();
|
||||||
|
|
||||||
|
return DNS_QUERY_QUEUED;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* LWIP_DNS */
|
@ -52,6 +52,7 @@
|
|||||||
#include "lwip/tcp.h"
|
#include "lwip/tcp.h"
|
||||||
#include "lwip/autoip.h"
|
#include "lwip/autoip.h"
|
||||||
#include "lwip/igmp.h"
|
#include "lwip/igmp.h"
|
||||||
|
#include "lwip/dns.h"
|
||||||
#include "netif/etharp.h"
|
#include "netif/etharp.h"
|
||||||
|
|
||||||
/* Compile-time sanity checks for configuration errors.
|
/* Compile-time sanity checks for configuration errors.
|
||||||
@ -75,6 +76,9 @@
|
|||||||
#if (!LWIP_UDP && LWIP_IGMP)
|
#if (!LWIP_UDP && LWIP_IGMP)
|
||||||
#error "If you want to use IGMP, you have to define LWIP_UDP=1 in your lwipopts.h"
|
#error "If you want to use IGMP, you have to define LWIP_UDP=1 in your lwipopts.h"
|
||||||
#endif
|
#endif
|
||||||
|
#if (!LWIP_UDP && LWIP_DNS)
|
||||||
|
#error "If you want to use DNS, you have to define LWIP_UDP=1 in your lwipopts.h"
|
||||||
|
#endif
|
||||||
#if (LWIP_ARP && (ARP_TABLE_SIZE > 0x7f))
|
#if (LWIP_ARP && (ARP_TABLE_SIZE > 0x7f))
|
||||||
#error "If you want to use ARP, ARP_TABLE_SIZE must fit in an s8_t, so, you have to reduce it in your lwipopts.h"
|
#error "If you want to use ARP, ARP_TABLE_SIZE must fit in an s8_t, so, you have to reduce it in your lwipopts.h"
|
||||||
#endif
|
#endif
|
||||||
@ -136,7 +140,7 @@
|
|||||||
#error "One and exactly one of LWIP_EVENT_API and LWIP_CALLBACK_API has to be enabled in lwipopts.h"
|
#error "One and exactly one of LWIP_EVENT_API and LWIP_CALLBACK_API has to be enabled in lwipopts.h"
|
||||||
#endif
|
#endif
|
||||||
/* There must be sufficient timeouts, taking into account requirements of the subsystems. */
|
/* There must be sufficient timeouts, taking into account requirements of the subsystems. */
|
||||||
#if ((NO_SYS==0) && (MEMP_NUM_SYS_TIMEOUT < (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_IGMP + LWIP_PPP)))
|
#if ((NO_SYS==0) && (MEMP_NUM_SYS_TIMEOUT < (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_IGMP + LWIP_DNS + LWIP_PPP)))
|
||||||
#error "MEMP_NUM_SYS_TIMEOUT is too low to accomodate all required timeouts"
|
#error "MEMP_NUM_SYS_TIMEOUT is too low to accomodate all required timeouts"
|
||||||
#endif
|
#endif
|
||||||
#if (IP_REASSEMBLY && (MEMP_NUM_REASSDATA > IP_REASS_MAX_PBUFS))
|
#if (IP_REASSEMBLY && (MEMP_NUM_REASSDATA > IP_REASS_MAX_PBUFS))
|
||||||
@ -233,4 +237,7 @@ lwip_init(void)
|
|||||||
#if LWIP_IGMP
|
#if LWIP_IGMP
|
||||||
igmp_init();
|
igmp_init();
|
||||||
#endif /* LWIP_IGMP */
|
#endif /* LWIP_IGMP */
|
||||||
|
#if LWIP_DNS
|
||||||
|
dns_init();
|
||||||
|
#endif /* LWIP_DNS */
|
||||||
}
|
}
|
||||||
|
90
src/include/lwip/dns.h
Normal file
90
src/include/lwip/dns.h
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
/**
|
||||||
|
* lwip DNS resolver header file.
|
||||||
|
|
||||||
|
* Author: Jim Pettinato
|
||||||
|
* April 2007
|
||||||
|
|
||||||
|
* ported from uIP resolv.c Copyright (c) 2002-2003, Adam Dunkels.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior
|
||||||
|
* written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||||
|
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||||
|
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __LWIP_DNS_H__
|
||||||
|
#define __LWIP_DNS_H__
|
||||||
|
|
||||||
|
#include "lwip/opt.h"
|
||||||
|
|
||||||
|
#if LWIP_DNS /* don't build if not configured for use in lwipopts.h */
|
||||||
|
|
||||||
|
/** DNS timer period */
|
||||||
|
#ifndef DNS_TMR_INTERVAL
|
||||||
|
#define DNS_TMR_INTERVAL 1000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* enumerated list of possible result values returned by dns_gethostname() */
|
||||||
|
typedef enum dns_result {
|
||||||
|
DNS_QUERY_INVALID,
|
||||||
|
DNS_QUERY_QUEUED,
|
||||||
|
DNS_COMPLETE
|
||||||
|
}DNS_RESULT;
|
||||||
|
|
||||||
|
/* initializes the resolver */
|
||||||
|
err_t dns_init(void);
|
||||||
|
|
||||||
|
/* handles requests, retries and timeouts - call every DNS_TMR_INTERVAL tick */
|
||||||
|
void dns_tmr(void);
|
||||||
|
|
||||||
|
/* initializes DNS server IP address */
|
||||||
|
void dns_setserver(u8_t numdns, struct ip_addr *dnsserver);
|
||||||
|
|
||||||
|
/* returns configured DNS server IP address */
|
||||||
|
u32_t dns_getserver(u8_t numdns);
|
||||||
|
|
||||||
|
/* returns IP for host 'name' only if already in table */
|
||||||
|
u32_t dns_lookup(char *name);
|
||||||
|
|
||||||
|
/* resolove a host 'name' in ip address */
|
||||||
|
DNS_RESULT dns_gethostbyname(char *hostName, struct ip_addr *addr,
|
||||||
|
void (*found)(char *name, struct ip_addr *ipaddr, void *arg),
|
||||||
|
void *arg);
|
||||||
|
|
||||||
|
/* dns_gethostbyname() - Returns immediately with one of DNS_RESULT return codes
|
||||||
|
* Return value will be DNS_COMPLETE if hostName is a valid
|
||||||
|
* IP address string or the host name is already in the local
|
||||||
|
* names table. Returns DNS_REQUEST_QUEUED and queues a
|
||||||
|
* request to be sent to the DNS server for resolution if no
|
||||||
|
* errors are present.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* dns_found_func() - Callback which is invoked when a hostname is found.
|
||||||
|
* This function should be implemented by the application using the DNS resolver.
|
||||||
|
* param 'name' - pointer to the name that was looked up.
|
||||||
|
* param 'ipaddr' - pointer to a struct ip_addr containing the IP address of the
|
||||||
|
* hostname, or NULL if the name could not be found.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif /* LWIP_DNS */
|
||||||
|
|
||||||
|
#endif /* __LWIP_DNS_H__ */
|
@ -546,6 +546,19 @@
|
|||||||
#define LWIP_IGMP 0
|
#define LWIP_IGMP 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
----------------------------------
|
||||||
|
---------- DNS options -----------
|
||||||
|
----------------------------------
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* LWIP_DNS==1: Turn on DNS module. UDP must be available for DNS
|
||||||
|
* transport.
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_DNS
|
||||||
|
#define LWIP_DNS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
---------------------------------
|
---------------------------------
|
||||||
---------- UDP options ----------
|
---------- UDP options ----------
|
||||||
@ -1515,4 +1528,11 @@
|
|||||||
#define SNMP_MIB_DEBUG LWIP_DBG_OFF
|
#define SNMP_MIB_DEBUG LWIP_DBG_OFF
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DNS_DEBUG: Enable debugging for DNS.
|
||||||
|
*/
|
||||||
|
#ifndef DNS_DEBUG
|
||||||
|
#define DNS_DEBUG LWIP_DBG_OFF
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* __LWIP_OPT_H__ */
|
#endif /* __LWIP_OPT_H__ */
|
||||||
|
Loading…
Reference in New Issue
Block a user