A stack which works with or without an Mbed os library. Provides IPv4 or IPv6 with a full 1500 byte buffer.

Dependents:   oldheating gps motorhome heating

Revision:
13:9cd54f7db57a
Child:
14:e75a59c1123d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/udp/dns/dnsquery.cpp	Mon May 01 18:20:55 2017 +0000
@@ -0,0 +1,170 @@
+#include    "mbed.h"
+#include     "log.h"
+#include     "net.h"
+#include    "dhcp.h"
+#include     "dns.h"
+#include     "udp.h"
+#include   "slaac.h"
+#include  "dnshdr.h"
+#include "dnsname.h"
+
+#define DEBUG true
+
+#define TIME_OUT_SENT 3
+
+#define MDNS_UNICAST false
+
+char     DnsQueryName[63];
+uint32_t DnsQueryIp4 = 0;
+char     DnsQueryIp6[16];
+
+int      DnsQueryProtocol = DNS_PROTOCOL_NONE;
+bool     DnsQueryIsBusy = false;
+
+static uint32_t started = 0;
+static uint32_t elapsed = 0;
+static void reap()
+{
+    if (!DnsQueryIsBusy) return;
+    
+    if (elapsed - started >= TIME_OUT_SENT)
+    {
+        char text[100];
+        LogTimeF("DNS reaped ongoing request for ");
+        if (DnsQueryName[0]) LogF("name %s", DnsQueryName);
+        if (DnsQueryIp4)
+        {
+            NetIp4AddressToString(DnsQueryIp4, sizeof(text), text);
+            LogF("ip4 %s", text);
+        }
+        if (DnsQueryIp6[0])
+        {
+            NetIp6AddressToString(DnsQueryIp6, sizeof(text), text);
+            LogF("ip6 %s", text);
+        }
+        LogF("\r\n");
+        
+        DnsQueryName[0]    = 0;
+        DnsQueryIp4        = 0;
+        DnsQueryIp6[0]     = 0;
+        DnsQueryIsBusy     = false;
+        started            = 0;
+        DnsQueryProtocol   = DNS_PROTOCOL_NONE;
+    }
+}
+void DnsQueryTick()
+{
+    elapsed++;
+    reap();
+}
+void DnsQueryIp4FromName(char * name, int protocol)
+{
+    strcpy(DnsQueryName, name);
+    DnsQueryIp4        = 0;
+    DnsQueryIp6[0]     = 0;
+    DnsQueryIsBusy     = true;
+    started            = elapsed;
+    DnsQueryProtocol   = protocol;
+}
+void DnsQueryIp6FromName(char * name, int protocol)
+{
+    strcpy(DnsQueryName, name);
+    DnsQueryIp4        = 0;
+    DnsQueryIp6[0]     = 0;
+    DnsQueryIsBusy     = true;
+    started            = elapsed;
+    DnsQueryProtocol   = protocol;
+}
+void DnsQueryNameFromIp4(uint32_t ip, int protocol)
+{
+    DnsQueryName[0]    = 0;
+    DnsQueryIp4        = ip;
+    DnsQueryIp6[0]     = 0;
+    DnsQueryIsBusy     = true;
+    started            = elapsed;
+    DnsQueryProtocol   = protocol;
+}
+void DnsQueryNameFromIp6(char* ip, int protocol)
+{
+    DnsQueryName[0]    = 0;
+    DnsQueryIp4        = 0;
+    memcpy(DnsQueryIp6, ip, 16);
+    DnsQueryIsBusy     = true;
+    started            = elapsed;
+    DnsQueryProtocol   = protocol;
+}
+int DnsQueryPoll(int* pSize)
+{   
+    if (!DnsQueryIsBusy)                                           return DO_NOTHING;
+    if (DnsQueryProtocol == DNS_PROTOCOL_UDNS && DhcpLocalIp == 0) return DO_NOTHING;
+    
+    static uint16_t id = 0;
+    DnsHdrId = ++id;
+    DnsHdrIsReply          = false;
+    DnsHdrIsRecursiveQuery = false;
+    
+    DnsHdrQdcount = 1;
+    DnsHdrAncount = 0;
+    DnsHdrNscount = 0;
+    DnsHdrArcount = 0;    
+
+    DnsHdrWrite();
+    char* p = DnsHdrData;
+    
+    if (DnsQueryIp4) //Reverse
+    {
+        if (DEBUG)
+        {
+            char text[20];
+            NetIp4AddressToString(DnsQueryIp4, sizeof(text), text);
+            switch (DnsQueryProtocol)
+            {
+                case DNS_PROTOCOL_UDNS:  LogTimeF("DNS sent DNS reverse request for %s\r\n", text); break;
+                case DNS_PROTOCOL_MDNS:  LogTimeF("DNS sent MDNS reverse request for %s\r\n", text); break;
+                case DNS_PROTOCOL_LLMNR: LogTimeF("DNS sent LLMNR reverse request for %s\r\n", text); break;
+            }
+        }
+        DnsNameEncodeIp4(DnsQueryIp4, &p);
+        *p++ = 0;
+        *p++ = DNS_RECORD_PTR;
+    }
+    else if (DnsQueryIp6[0])
+    {
+        if (DEBUG)
+        {
+            char text[60];
+            NetIp6AddressToString(DnsQueryIp6, sizeof(text), text);
+            switch (DnsQueryProtocol)
+            {
+                case DNS_PROTOCOL_UDNS:  LogTimeF("DNS sent DNS reverse request for %s\r\n", text); break;
+                case DNS_PROTOCOL_MDNS:  LogTimeF("DNS sent MDNS reverse request for %s\r\n", text); break;
+                case DNS_PROTOCOL_LLMNR: LogTimeF("DNS sent LLMNR reverse request for %s\r\n", text); break;
+            }
+        }
+        DnsNameEncodeIp6(DnsQueryIp6, &p);
+        *p++ = 0;
+        *p++ = DNS_RECORD_PTR;
+    }
+    else //Forward
+    {
+        DnsNameEncode(DnsQueryName, &p);
+        *p++ = 0;
+        *p++ = DNS_RECORD_A;
+    }
+    *p++ = DnsQueryProtocol == DNS_PROTOCOL_MDNS && MDNS_UNICAST ? 0x80 : 0; //Set the 15th bit (UNICAST_RESPONSE) to 1 if MDNS
+    *p++ = 1;  //QCLASS_IN = 1 - internet
+    
+    *pSize = p - DnsHdrPacket;
+    
+    DnsQueryIsBusy = false;
+
+    switch (DnsQueryProtocol)
+    {
+        case DNS_PROTOCOL_UDNS:  return   UNICAST_DNS;    //IPv6 ==> NdpDnsServer; IPv4 ==> DhcpDnsServer
+        case DNS_PROTOCOL_MDNS:  return MULTICAST_MDNS;
+        case DNS_PROTOCOL_LLMNR: return MULTICAST_LLMNR;
+        default:
+            LogTimeF("DNS unknown query protocol %d\r\n", DnsQueryProtocol);
+            return DO_NOTHING;
+    }
+}