91 #ifndef DNS_SERVER_ADDRESS 92 #define DNS_SERVER_ADDRESS(ipaddr) (ip4_addr_set_u32(ipaddr, 0xDEDE43D0)) 96 #ifndef DNS_SERVER_PORT 97 #define DNS_SERVER_PORT 53 101 #ifndef DNS_MAX_RETRIES 102 #define DNS_MAX_RETRIES 4 107 #define DNS_MAX_TTL 604800 111 #define DNS_FLAG1_RESPONSE 0x80 112 #define DNS_FLAG1_OPCODE_STATUS 0x10 113 #define DNS_FLAG1_OPCODE_INVERSE 0x08 114 #define DNS_FLAG1_OPCODE_STANDARD 0x00 115 #define DNS_FLAG1_AUTHORATIVE 0x04 116 #define DNS_FLAG1_TRUNC 0x02 117 #define DNS_FLAG1_RD 0x01 118 #define DNS_FLAG2_RA 0x80 119 #define DNS_FLAG2_ERR_MASK 0x0f 120 #define DNS_FLAG2_ERR_NONE 0x00 121 #define DNS_FLAG2_ERR_NAME 0x03 124 #define DNS_STATE_UNUSED 0 125 #define DNS_STATE_NEW 1 126 #define DNS_STATE_ASKING 2 127 #define DNS_STATE_DONE 3 129 #ifdef PACK_STRUCT_USE_INCLUDES 130 # include "arch/bpstruct.h" 144 #ifdef PACK_STRUCT_USE_INCLUDES 145 # include "arch/epstruct.h" 147 #define SIZEOF_DNS_HDR 12 157 #define SIZEOF_DNS_QUERY 4 169 #define SIZEOF_DNS_ANSWER 10 172 struct dns_table_entry {
187 #if DNS_LOCAL_HOSTLIST 189 #if DNS_LOCAL_HOSTLIST_IS_DYNAMIC 192 static struct local_hostlist_entry *local_hostlist_dynamic;
197 #ifndef DNS_LOCAL_HOSTLIST_STORAGE_PRE 198 #define DNS_LOCAL_HOSTLIST_STORAGE_PRE static 202 #ifndef DNS_LOCAL_HOSTLIST_STORAGE_POST 203 #define DNS_LOCAL_HOSTLIST_STORAGE_POST 205 DNS_LOCAL_HOSTLIST_STORAGE_PRE
struct local_hostlist_entry local_hostlist_static[]
206 DNS_LOCAL_HOSTLIST_STORAGE_POST = DNS_LOCAL_HOSTLIST_INIT;
210 static void dns_init_local();
215 static void dns_recv(
void *s,
struct udp_pcb *pcb,
struct pbuf *p,
ip_addr_t *addr,
u16_t port);
216 static void dns_check_entries(
void);
223 static struct udp_pcb *dns_pcb;
224 static u8_t dns_seqno;
229 static u8_t* dns_payload;
230 static u8_t dns_random;
243 DNS_SERVER_ADDRESS(&dnsserver);
248 if (dns_pcb ==
NULL) {
251 if (dns_pcb !=
NULL) {
254 LWIP_ASSERT(
"For implicit initialization to work, DNS_STATE_UNUSED needs to be 0",
255 DNS_STATE_UNUSED == 0);
259 udp_recv(dns_pcb, dns_recv,
NULL);
262 dns_setserver(0, &dnsserver);
265 #if DNS_LOCAL_HOSTLIST 281 dns_servers[numdns] = (*dnsserver);
293 dns_getserver(
u8_t numdns)
296 return dns_servers[numdns];
309 if (dns_pcb !=
NULL) {
315 #if DNS_LOCAL_HOSTLIST 319 #if DNS_LOCAL_HOSTLIST_IS_DYNAMIC && defined(DNS_LOCAL_HOSTLIST_INIT) 321 struct local_hostlist_entry *entry;
323 struct local_hostlist_entry local_hostlist_init[] = DNS_LOCAL_HOSTLIST_INIT;
325 for (i = 0; i <
sizeof(local_hostlist_init) /
sizeof(
struct local_hostlist_entry); i++) {
326 struct local_hostlist_entry *init_entry = &local_hostlist_init[i];
329 LWIP_ASSERT(
"namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN", namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN);
330 entry = (
struct local_hostlist_entry *)
memp_malloc(MEMP_LOCALHOSTLIST);
333 entry->name = (
char*)entry +
sizeof(
struct local_hostlist_entry);
334 MEMCPY((
char*)entry->name, init_entry->name, namelen);
335 ((
char*)entry->name)[namelen] = 0;
336 entry->addr = init_entry->addr;
337 entry->next = local_hostlist_dynamic;
338 local_hostlist_dynamic = entry;
352 dns_lookup_local(
const char *hostname)
354 #if DNS_LOCAL_HOSTLIST_IS_DYNAMIC 355 struct local_hostlist_entry *entry = local_hostlist_dynamic;
356 while(entry !=
NULL) {
357 if(
strcmp(entry->name, hostname) == 0) {
364 for (i = 0; i <
sizeof(local_hostlist_static) /
sizeof(
struct local_hostlist_entry); i++) {
365 if(
strcmp(local_hostlist_static[i].name, hostname) == 0) {
373 #if DNS_LOCAL_HOSTLIST_IS_DYNAMIC 383 dns_local_removehost(
const char *hostname,
const ip_addr_t *addr)
386 struct local_hostlist_entry *entry = local_hostlist_dynamic;
387 struct local_hostlist_entry *last_entry =
NULL;
388 while (entry !=
NULL) {
389 if (((hostname ==
NULL) || !
strcmp(entry->name, hostname)) &&
391 struct local_hostlist_entry *free_entry;
392 if (last_entry !=
NULL) {
393 last_entry->next = entry->next;
395 local_hostlist_dynamic = entry->next;
399 memp_free(MEMP_LOCALHOSTLIST, free_entry);
418 dns_local_addhost(
const char *hostname,
const ip_addr_t *addr)
420 struct local_hostlist_entry *entry;
424 LWIP_ASSERT(
"namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN", namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN);
425 entry = (
struct local_hostlist_entry *)
memp_malloc(MEMP_LOCALHOSTLIST);
429 entry->name = (
char*)entry +
sizeof(
struct local_hostlist_entry);
430 MEMCPY((
char*)entry->name, hostname, namelen);
431 ((
char*)entry->name)[namelen] = 0;
433 entry->next = local_hostlist_dynamic;
434 local_hostlist_dynamic = entry;
454 dns_lookup(
const char *name)
457 #if DNS_LOCAL_HOSTLIST || defined(DNS_LOOKUP_LOCAL_EXTERN) 460 #if DNS_LOCAL_HOSTLIST 461 if ((addr = dns_lookup_local(name)) !=
IPADDR_NONE) {
465 #ifdef DNS_LOOKUP_LOCAL_EXTERN 466 if((addr = DNS_LOOKUP_LOCAL_EXTERN(name)) !=
IPADDR_NONE) {
473 if ((dns_table[i].
state == DNS_STATE_DONE) &&
474 (
strcmp(name, dns_table[i].name) == 0)) {
485 #if DNS_DOES_NAME_CHECK 497 dns_compare_name(
unsigned char *query,
unsigned char *
response)
504 if ((n & 0xc0) == 0xc0) {
510 if ((*query) != (*response)) {
519 }
while (*response != 0);
532 dns_parse_name(
unsigned char *query)
539 if ((n & 0xc0) == 0xc0) {
549 }
while (*query != 0);
564 dns_send(
u8_t numdns,
const char* name,
u8_t id)
568 struct dns_query qry;
571 const char *pHostname;
575 (
u16_t)(numdns), name));
585 hdr = (
struct dns_hdr*)p->
payload;
587 hdr->id =
htons(
id + dns_random);
588 hdr->flags1 = DNS_FLAG1_RD;
590 query = (
char*)hdr + SIZEOF_DNS_HDR;
599 for(n = 0; *pHostname !=
'.' && *pHostname != 0; ++pHostname) {
605 }
while(*pHostname != 0);
611 SMEMCPY(query, &qry, SIZEOF_DNS_QUERY);
617 udp_connect(dns_pcb, &dns_servers[numdns], DNS_SERVER_PORT);
619 err = udp_sendto(dns_pcb, p, &dns_servers[numdns], DNS_SERVER_PORT);
640 dns_check_entry(
u8_t i)
643 struct dns_table_entry *pEntry = &dns_table[i];
645 LWIP_ASSERT(
"array index out of bounds", i < DNS_TABLE_SIZE);
647 switch(pEntry->state) {
649 case DNS_STATE_NEW: {
651 pEntry->state = DNS_STATE_ASKING;
657 err = dns_send(pEntry->numdns, pEntry->name, i);
660 (
"dns_send returned error: %s\n",
lwip_strerr(err)));
665 case DNS_STATE_ASKING: {
666 if (--pEntry->tmr == 0) {
667 if (++pEntry->retries == DNS_MAX_RETRIES) {
678 (*pEntry->found)(pEntry->name,
NULL, pEntry->arg);
680 pEntry->state = DNS_STATE_UNUSED;
681 pEntry->found =
NULL;
687 pEntry->tmr = pEntry->retries;
690 err = dns_send(pEntry->numdns, pEntry->name, i);
693 (
"dns_send returned error: %s\n",
lwip_strerr(err)));
699 case DNS_STATE_DONE: {
701 if (--pEntry->ttl == 0) {
704 pEntry->state = DNS_STATE_UNUSED;
705 pEntry->found =
NULL;
709 case DNS_STATE_UNUSED:
722 dns_check_entries(
void)
742 struct dns_answer ans;
743 struct dns_table_entry *pEntry;
744 u16_t nquestions, nanswers;
762 if (p->
tot_len < (SIZEOF_DNS_HDR + SIZEOF_DNS_QUERY + SIZEOF_DNS_ANSWER)) {
771 hdr = (
struct dns_hdr*)dns_payload;
774 if (i < DNS_TABLE_SIZE) {
775 pEntry = &dns_table[i];
776 if(pEntry->state == DNS_STATE_ASKING) {
778 pEntry->state = DNS_STATE_DONE;
779 pEntry->err = hdr->flags2 & DNS_FLAG2_ERR_MASK;
783 nquestions =
htons(hdr->numquestions);
784 nanswers =
htons(hdr->numanswers);
787 if (((hdr->flags1 & DNS_FLAG1_RESPONSE) == 0) || (pEntry->err != 0) || (nquestions != 1)) {
793 #if DNS_DOES_NAME_CHECK 795 if (dns_compare_name((
unsigned char *)(pEntry->name), (
unsigned char *)dns_payload + SIZEOF_DNS_HDR) != 0) {
803 pHostname = (
char *) dns_parse_name((
unsigned char *)dns_payload + SIZEOF_DNS_HDR) + SIZEOF_DNS_QUERY;
805 while (nanswers > 0) {
807 pHostname = (
char *) dns_parse_name((
unsigned char *)pHostname);
810 SMEMCPY(&ans, pHostname, SIZEOF_DNS_ANSWER);
811 if((ans.type ==
PP_HTONS(DNS_RRTYPE_A)) && (ans.cls ==
PP_HTONS(DNS_RRCLASS_IN)) &&
814 pEntry->ttl =
ntohl(ans.ttl);
815 if (pEntry->ttl > DNS_MAX_TTL) {
816 pEntry->ttl = DNS_MAX_TTL;
819 SMEMCPY(&(pEntry->ipaddr), (pHostname+SIZEOF_DNS_ANSWER),
sizeof(
ip_addr_t));
825 (*pEntry->found)(pEntry->name, &pEntry->ipaddr, pEntry->arg);
830 pHostname = pHostname + SIZEOF_DNS_ANSWER +
htons(ans.len);
847 (*pEntry->found)(pEntry->name,
NULL, pEntry->arg);
850 pEntry->state = DNS_STATE_UNUSED;
851 pEntry->found =
NULL;
873 struct dns_table_entry *pEntry =
NULL;
879 pEntry = &dns_table[i];
881 if (pEntry->state == DNS_STATE_UNUSED)
885 if (pEntry->state == DNS_STATE_DONE) {
886 if ((dns_seqno - pEntry->seqno) > lseq) {
887 lseq = dns_seqno - pEntry->seqno;
894 if (i == DNS_TABLE_SIZE) {
895 if ((lseqi >= DNS_TABLE_SIZE) || (dns_table[lseqi].
state != DNS_STATE_DONE)) {
902 pEntry = &dns_table[i];
910 pEntry->state = DNS_STATE_NEW;
911 pEntry->seqno = dns_seqno++;
912 pEntry->found = found;
913 pEntry->arg = callback_arg;
915 MEMCPY(pEntry->name, name, namelen);
916 pEntry->name[namelen] = 0;
951 if ((dns_pcb ==
NULL) || (addr ==
NULL) ||
952 (!hostname) || (!hostname[0]) ||
958 if (
strcmp(hostname,
"localhost")==0) {
976 return dns_enqueue(hostname, found, callback_arg);
#define ip4_addr_get_u32(src_ipaddr)
#define DNS_MAX_NAME_LENGTH
void memp_free(memp_t type, void *mem) ICACHE_FLASH_ATTR
#define SMEMCPY(dst, src, len)
en61107_response_t response
#define ip_addr_debug_print(debug, ipaddr)
const ip_addr_t ip_addr_any ICACHE_RODATA_ATTR
#define ip_addr_set_loopback(ipaddr)
#define ICACHE_FLASH_ATTR
void * memp_malloc(memp_t type) ICACHE_FLASH_ATTR
#define LWIP_DEBUGF(debug, message)
#define ip_addr_cmp(addr1, addr2)
#define ip_addr_copy(dest, src)
#define LWIP_MEM_ALIGN_BUFFER(size)
void(* dns_found_callback)(const char *name, ip_addr_t *ipaddr, void *callback_arg)
unsigned long os_random(void)
#define PACK_STRUCT_STRUCT
typedefPACK_STRUCT_END struct ip_addr ip_addr_t
#define LWIP_DBG_LEVEL_WARNING
#define ip_addr_isany(addr1)
u8_t pbuf_free(struct pbuf *p) ICACHE_FLASH_ATTR
#define PACK_STRUCT_BEGIN
u32_t ipaddr_addr(const char *cp) ICACHE_FLASH_ATTR
#define MEMCPY(dst, src, len)
#define LWIP_ASSERT(message, assertion)
u16_t pbuf_copy_partial(struct pbuf *p, void *dataptr, u16_t len, u16_t offset) ICACHE_FLASH_ATTR
#define ip4_addr_set_u32(dest_ipaddr, src_u32)
void pbuf_realloc(struct pbuf *p, u16_t size) ICACHE_FLASH_ATTR
#define LWIP_UNUSED_ARG(x)
#define LWIP_MEM_ALIGN(addr)
struct pbuf * pbuf_alloc(pbuf_layer l, u16_t length, pbuf_type type) ICACHE_FLASH_ATTR
#define PACK_STRUCT_FIELD(x)