void DNSServer::onReceive(pbuf* buf, IPAddress remoteIP, uint16_t remotePort) { if (_buffer != NULL) free(_buffer); _buffer = (char*)malloc(buf->tot_len * sizeof(char)); if (_buffer == NULL) return; pbuf_copy_partial(buf, _buffer, buf->tot_len, 0); debugf("DNS REQ for %s from %s:%d", getDomainNameWithoutWwwPrefix().c_str(), remoteIP.toString().c_str(), remotePort); _dnsHeader = (DNSHeader*) _buffer; if (_dnsHeader->QR == DNS_QR_QUERY && _dnsHeader->OPCode == DNS_OPCODE_QUERY && requestIncludesOnlyOneQuestion() && (_domainName == "*" || getDomainNameWithoutWwwPrefix() == _domainName) ) { char response[buf->tot_len+16]; int idx = buf->tot_len; _dnsHeader->QR = DNS_QR_RESPONSE; _dnsHeader->ANCount = _dnsHeader->QDCount; _dnsHeader->QDCount = _dnsHeader->QDCount; memcpy(response, _buffer, idx); //Set a pointer to the domain name in the question section response[idx] = 0xC0; response[idx+1] = 0x0C; //Type: "Host Address" response[idx+2] = 0x00; response[idx+3] = 0x01; //Set the response class to IN response[idx+4] = 0x00; response[idx+5] = 0x01; //TTL response[idx+6] = _ttl >> 24; response[idx+7] = _ttl >> 16; response[idx+8] = _ttl >> 8; response[idx+9] = _ttl; //RDATA length response[idx+10] = 0x00; response[idx+11] = 0x04; //4 byte IP address //The IP address response[idx+12] = _resolvedIP[0]; response[idx+13] = _resolvedIP[1]; response[idx+14] = _resolvedIP[2]; response[idx+15] = _resolvedIP[3]; sendTo(remoteIP, remotePort, response, idx+16); }
void DNSServer::processNextRequest() { _currentPacketSize = _udp.parsePacket(); if (_currentPacketSize) { _buffer = (unsigned char*)malloc(_currentPacketSize * sizeof(char)); _udp.read(_buffer, _currentPacketSize); _dnsHeader = (DNSHeader*) _buffer; if (_dnsHeader->QR == DNS_QR_QUERY && _dnsHeader->OPCode == DNS_OPCODE_QUERY && requestIncludesOnlyOneQuestion() && (_domainName == "*" || getDomainNameWithoutWwwPrefix() == _domainName) ) { replyWithIP(); } else if (_dnsHeader->QR == DNS_QR_QUERY) { replyWithCustomCode(); } free(_buffer); } }
void DNSServer::replyWithIP() { _dnsHeader->QR = DNS_QR_RESPONSE; _dnsHeader->ANCount = _dnsHeader->QDCount; _dnsHeader->QDCount = _dnsHeader->QDCount; //_dnsHeader->RA = 1; _udp.beginPacket(_udp.remoteIP(), _udp.remotePort()); _udp.write(_buffer, _currentPacketSize); _udp.write((uint8_t)192); // answer name is a pointer _udp.write((uint8_t)12); // pointer to offset at 0x00c _udp.write((uint8_t)0); // 0x0001 answer is type A query (host address) _udp.write((uint8_t)1); _udp.write((uint8_t)0); //0x0001 answer is class IN (internet address) _udp.write((uint8_t)1); _udp.write((unsigned char*)&_ttl, 4); // Length of RData is 4 bytes (because, in this case, RData is IPv4) _udp.write((uint8_t)0); _udp.write((uint8_t)4); _udp.write(_resolvedIP, sizeof(_resolvedIP)); _udp.endPacket(); #ifdef DEBUG DEBUG_OUTPUT.print("DNS responds: "); DEBUG_OUTPUT.print(_resolvedIP[0]); DEBUG_OUTPUT.print("."); DEBUG_OUTPUT.print(_resolvedIP[1]); DEBUG_OUTPUT.print("."); DEBUG_OUTPUT.print(_resolvedIP[2]); DEBUG_OUTPUT.print("."); DEBUG_OUTPUT.print(_resolvedIP[3]); DEBUG_OUTPUT.print(" for "); DEBUG_OUTPUT.println(getDomainNameWithoutWwwPrefix()); #endif }