summaryrefslogtreecommitdiff
path: root/dnsserver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dnsserver.cpp')
-rw-r--r--dnsserver.cpp82
1 files changed, 82 insertions, 0 deletions
diff --git a/dnsserver.cpp b/dnsserver.cpp
new file mode 100644
index 0000000..9fe1925
--- /dev/null
+++ b/dnsserver.cpp
@@ -0,0 +1,82 @@
+#include "dnsserver.h"
+
+DNSServer::DNSServer()
+{
+ _ttl = htonl(600);
+ _errorReplyCode = DNSReplyCode::NonExistentDomain;
+}
+
+bool DNSServer::start(const IPAddress &resolvedIP)
+{
+ _buffer = NULL;
+ _resolvedIP[0] = resolvedIP[0];
+ _resolvedIP[1] = resolvedIP[1];
+ _resolvedIP[2] = resolvedIP[2];
+ _resolvedIP[3] = resolvedIP[3];
+ return _udp.begin(53) == 1;
+}
+
+void DNSServer::stop()
+{
+ _udp.stop();
+ free(_buffer);
+ _buffer = NULL;
+}
+
+void DNSServer::processNextRequest()
+{
+ _currentPacketSize = _udp.parsePacket();
+ if (_currentPacketSize)
+ {
+ if (_buffer != NULL) free(_buffer);
+ _buffer = (unsigned char*)malloc(_currentPacketSize * sizeof(char));
+ if (_buffer == NULL) return;
+ _udp.read(_buffer, _currentPacketSize);
+
+ _dnsHeader = (DNSHeader*) _buffer;
+
+ if (_dnsHeader->QR == DNS_QR_QUERY &&
+ _dnsHeader->OPCode == DNS_OPCODE_QUERY &&
+ requestIncludesOnlyOneQuestion())
+ {
+ replyWithIP(); // reply with the same ip regardless of request
+ }
+ }
+}
+
+bool DNSServer::requestIncludesOnlyOneQuestion()
+{
+ return ntohs(_dnsHeader->QDCount) == 1 &&
+ _dnsHeader->ANCount == 0 &&
+ _dnsHeader->NSCount == 0 &&
+ _dnsHeader->ARCount == 0;
+}
+
+void DNSServer::replyWithIP()
+{
+ if (_buffer == NULL) return;
+ _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();
+}