This is the code I use:
//Callback for a dns inquire
static void ICACHE_FLASH_ATTR udpserver_recv(void *arg, char *data, unsigned short len) {
struct espconn *conn=arg;
#ifdef DEBUG
uart0_sendStr("\r\nDNS INQUIRE\r\n");
#endif
if (len <13 || data[3] & 0x11110100 != 0) { //valid question
#ifdef DEBUG
uart0_sendStr("Non standard question\n");
#endif
return;
}
uint16_t numQuestions = ((uint16_t)data[4])<<8 | data[5];
//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, len-12); //Copy the rest of the query section
idx += len-12;
if (idx > 50) {
#ifdef DEBUG
uart0_sendStr("Query too long\n");
#endif
return;
}
//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 meas 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 ESP's IP address
response[idx + 12] = 192;
response[idx + 13] = 168;
response[idx + 14] = 4;
response[idx + 15] = 1;
espconn_sent((struct espconn *)arg, (char*)response, idx+16);
}
I set up the udp server like this:
dnsConnUdp.type=ESPCONN_UDP;
dnsConnUdp.state=ESPCONN_NONE;
dnsConnUdp.proto.udp = (esp_udp *)os_zalloc(sizeof(esp_udp));
dnsConnUdp.proto.udp->local_port = 53;
espconn_regist_recvcb(&dnsConnUdp, udpserver_recv);
espconn_create(&dnsConnUdp);
Hope it helps.
Works perfectly for me!