static void ICACHE_FLASH_ATTR dnsQueryReceived(void *arg, char *data, unsigned short length) { // parse incoming query domain char domain[30]; char *writePos=domain; memset(domain,0,30); int offSet=12; int len=data[offSet]; while(len!=0 && offSet<length) { offSet++; memcpy(writePos,data+offSet,len); writePos+=len; //advance offSet+=len; len=data[offSet]; if(len!=0) { *writePos='.'; writePos++; } } DNS_DBG("DNS Query Received: %s",domain); if(!isKnownDNS(domain)) return; struct espconn *conn=arg; remot_info *premot = NULL; if (espconn_get_connection_info(conn,&premot,0) == ESPCONN_OK) { os_memcpy(conn->proto.udp->remote_ip, premot->remote_ip, 4); conn->proto.udp->remote_port = premot->remote_port; uint8_t *ip1 = conn->proto.udp->remote_ip; NODE_DBG("UDP:\nremote_ip: %d.%d.%d.%d remote_port: %d\n",ip4_addr1_16(ip1),ip4_addr2_16(ip1), ip4_addr3_16(ip1), ip4_addr4_16(ip1), premot->remote_port); } else { NODE_ERR("UDP: connection_info == NULL?\n"); } //build response char response[100] = {data[0], data[1], 0b10000100 | (0b00000001 & data[2]), //response, authorative answer, not truncated, copy the recursion bit 0b00000000, //no recursion available, no errors data[4], data[5], //Question count data[4], data[5], //answer count 0x00, 0x00, //NS record count 0x00, 0x00}; //Resource record count int idx = 12; memcpy(response+12, data+12, length-12); //Copy the rest of the query section idx += length-12; //Set a pointer to the domain name in the question section response[idx] = 0xC0; response[idx+1] = 0x0C; //Set the type to "Host Address" response[idx+2] = 0x00; response[idx+3] = 0x01; //Set the response class to IN response[idx+4] = 0x00; response[idx+5] = 0x01; //A 32 bit integer specifying TTL in seconds, 0 means no caching response[idx+6] = 0x00; response[idx+7] = 0x00; response[idx+8] = 0x00; response[idx+9] = 0x00; //RDATA length response[idx+10] = 0x00; response[idx+11] = 0x04; //4 byte IP address //The IP address response[idx + 12] = 192; response[idx + 13] = 168; response[idx + 14] = 4; response[idx + 15] = 1; int ret = espconn_send(conn, (uint8_t*)response, idx+16); uint8_t *ip = conn->proto.udp->local_ip; NODE_DBG("local_ip: %d.%d.%d.%d local_port: %d\n",ip4_addr1_16(ip),ip4_addr2_16(ip), ip4_addr3_16(ip), ip4_addr4_16(ip),conn->proto.udp->local_port); NODE_DBG("DNS reply sent\n"); }
/* ******************************************************************************** * MAKE DNS QUERY AND PARSE THE REPLY * * Description : This function makes DNS query message and parses the reply from DNS server. * Arguments : name - is a pointer to the domain name. * Returns : if succeeds : 1, fails : -1 * Note : ******************************************************************************** */ int DNS::query(char *name) { int state; static uint32_t dns_wait_time = 0; struct dhdr dhp; uint8_t ip[4]; uint16_t len, port; uint8_t dns_server_ip[4]; uint8_t BUFPUB[100]; get_local_dns(dns_server_ip); len = makequery(0, (uint8_t *)name, BUFPUB, MAX_DNS_BUF_SIZE); DNS_DBG("ÓòÃû:[%s]\r\n", name); DNS_DBG("ÓòÃû½âÎöÖÐ...\r\n"); while(1) { state = socket_status(s); if(state == SOCK_CLOSED) { DNS_DBG("dns's socket closed!,socket: %d\r\n", s); DNS_DBG("openning dns's socket... !\r\n"); if(_socket(s, Sn_MR_UDP, port, 0) == 1) DNS_DBG("open dns's socket seccusse!\r\n"); } if(state == SOCK_UDP) { DNS_DBG("sending query cmd...\r\n"); if(_sendto(s, BUFPUB, len, dns_server_ip, IPPORT_DOMAIN) > 0) DNS_DBG("send dns cmd ok!\r\n"); if ((len = recv_available(s)) > 0) { if (len > MAX_DNS_BUF_SIZE) { len = MAX_DNS_BUF_SIZE; } len = _recvfrom(s, BUFPUB, len, ip, &port); DNS_DBG("receiv dns's date ok!datelen:%d\r\n", len); if(parseMSG(&dhp, BUFPUB)) { _close(s); DNS_DBG("query is ok!\r\n"); return 1; } else { DNS_DBG("dns's date is bad!\r\n"); return -1; } } else { DNS_DBG("wait dns's date...!\r\n"); delay_ms(1000); dns_wait_time++; } if(dns_wait_time >= 3) { _close(s); return -2; } } }; }