static void ICACHE_FLASH_ATTR captdnsRecv(void* arg, char *pusrdata, unsigned short length) { struct espconn *conn=(struct espconn *)arg; #else static void ICACHE_FLASH_ATTR captdnsRecv(struct sockaddr_in *premote_addr, char *pusrdata, unsigned short length) { #endif char buff[DNS_LEN]; char reply[DNS_LEN]; int i; char *rend=&reply[length]; char *p=pusrdata; DnsHeader *hdr=(DnsHeader*)p; DnsHeader *rhdr=(DnsHeader*)&reply[0]; p+=sizeof(DnsHeader); // printf("DNS packet: id 0x%X flags 0x%X rcode 0x%X qcnt %d ancnt %d nscount %d arcount %d len %d\n", // my_ntohs(&hdr->id), hdr->flags, hdr->rcode, my_ntohs(&hdr->qdcount), my_ntohs(&hdr->ancount), my_ntohs(&hdr->nscount), my_ntohs(&hdr->arcount), length); //Some sanity checks: if (length>DNS_LEN) return; //Packet is longer than DNS implementation allows if (length<sizeof(DnsHeader)) return; //Packet is too short if (hdr->ancount || hdr->nscount || hdr->arcount) return; //this is a reply, don't know what to do with it if (hdr->flags&FLAG_TC) return; //truncated, can't use this //Reply is basically the request plus the needed data memcpy(reply, pusrdata, length); rhdr->flags|=FLAG_QR; for (i=0; i<my_ntohs(&hdr->qdcount); i++) { //Grab the labels in the q string p=labelToStr(pusrdata, p, length, buff, sizeof(buff)); if (p==NULL) return; DnsQuestionFooter *qf=(DnsQuestionFooter*)p; p+=sizeof(DnsQuestionFooter); printf("DNS: Q (type 0x%X class 0x%X) for %s\n", my_ntohs(&qf->type), my_ntohs(&qf->class), buff); if (my_ntohs(&qf->type)==QTYPE_A) { //They want to know the IPv4 address of something. //Build the response. rend=strToLabel(buff, rend, sizeof(reply)-(rend-reply)); //Add the label if (rend==NULL) return; DnsResourceFooter *rf=(DnsResourceFooter *)rend; rend+=sizeof(DnsResourceFooter); setn16(&rf->type, QTYPE_A); setn16(&rf->class, QCLASS_IN); setn32(&rf->ttl, 0); setn16(&rf->rdlength, 4); //IPv4 addr is 4 bytes; //Grab the current IP of the softap interface struct ip_info info; wifi_get_ip_info(SOFTAP_IF, &info); *rend++=ip4_addr1(&info.ip); *rend++=ip4_addr2(&info.ip); *rend++=ip4_addr3(&info.ip); *rend++=ip4_addr4(&info.ip); setn16(&rhdr->ancount, my_ntohs(&rhdr->ancount)+1); // printf("Added A rec to resp. Resp len is %d\n", (rend-reply)); } else if (my_ntohs(&qf->type)==QTYPE_NS) {
setn16(&rf->type, QTYPE_A); setn16(&rf->class, QCLASS_IN); setn32(&rf->ttl, 0); setn16(&rf->rdlength, 4); //IPv4 addr is 4 bytes; //Grab the current IP of the softap interface struct ip_info info; wifi_get_ip_info(SOFTAP_IF, &info); *rend++=ip4_addr1(&info.ip); *rend++=ip4_addr2(&info.ip); *rend++=ip4_addr3(&info.ip); *rend++=ip4_addr4(&info.ip); setn16(&rhdr->ancount, my_ntohs(&rhdr->ancount)+1); // printf("Added A rec to resp. Resp len is %d\n", (rend-reply)); } else if (my_ntohs(&qf->type)==QTYPE_NS) { //Give ns server. Basically can be whatever we want because it'll get resolved to our IP later anyway. rend=strToLabel(buff, rend, sizeof(reply)-(rend-reply)); //Add the label DnsResourceFooter *rf=(DnsResourceFooter *)rend; rend+=sizeof(DnsResourceFooter); setn16(&rf->type, QTYPE_NS); setn16(&rf->class, QCLASS_IN); setn16(&rf->ttl, 0); setn16(&rf->rdlength, 4); *rend++=2; *rend++='n'; *rend++='s'; *rend++=0; setn16(&rhdr->ancount, my_ntohs(&rhdr->ancount)+1); // printf("Added NS rec to resp. Resp len is %d\n", (rend-reply)); } else if (my_ntohs(&qf->type)==QTYPE_URI) { //Give uri to us rend=strToLabel(buff, rend, sizeof(reply)-(rend-reply)); //Add the label
setn16(&rf->type, QTYPE_A); setn16(&rf->class, QCLASS_IN); setn32(&rf->ttl, 0); setn16(&rf->rdlength, 4); //IPv4 addr is 4 bytes; //Grab the current IP of the softap interface struct ip_info info; wifi_get_ip_info(SOFTAP_IF, &info); *rend++=ip4_addr1(&info.ip); *rend++=ip4_addr2(&info.ip); *rend++=ip4_addr3(&info.ip); *rend++=ip4_addr4(&info.ip); setn16(&rhdr->ancount, local_ntohs(&rhdr->ancount)+1); // printf("Added A rec to resp. Resp len is %d\n", (rend-reply)); } else if (local_ntohs(&qf->type)==QTYPE_NS) { //Give ns server. Basically can be whatever we want because it'll get resolved to our IP later anyway. rend=strToLabel(buff, rend, DNS_LEN-(rend-reply)); //Add the label DnsResourceFooter *rf=(DnsResourceFooter *)rend; rend+=sizeof(DnsResourceFooter); setn16(&rf->type, QTYPE_NS); setn16(&rf->class, QCLASS_IN); setn16(&rf->ttl, 0); setn16(&rf->rdlength, 4); *rend++=2; *rend++='n'; *rend++='s'; *rend++=0; setn16(&rhdr->ancount, local_ntohs(&rhdr->ancount)+1); // printf("Added NS rec to resp. Resp len is %d\n", (rend-reply)); } else if (local_ntohs(&qf->type)==QTYPE_URI) { //Give uri to us rend=strToLabel(buff, rend, DNS_LEN-(rend-reply)); //Add the label