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

Committer:
andrewboyson
Date:
Thu Oct 19 20:56:58 2017 +0000
Revision:
43:bc028d5a6424
Parent:
38:cc8945857a0d
Child:
47:73af5c0b0dc2
Added verbose option to trace

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 13:9cd54f7db57a 1 #include "mbed.h"
andrewboyson 13:9cd54f7db57a 2 #include "log.h"
andrewboyson 43:bc028d5a6424 3 #include "clock.h"
andrewboyson 13:9cd54f7db57a 4 #include "net.h"
andrewboyson 37:793b39683406 5 #include "action.h"
andrewboyson 14:e75a59c1123d 6 #include "ip4.h"
andrewboyson 14:e75a59c1123d 7 #include "ip6.h"
andrewboyson 13:9cd54f7db57a 8 #include "dhcp.h"
andrewboyson 13:9cd54f7db57a 9 #include "dns.h"
andrewboyson 13:9cd54f7db57a 10 #include "udp.h"
andrewboyson 13:9cd54f7db57a 11 #include "slaac.h"
andrewboyson 13:9cd54f7db57a 12 #include "dnshdr.h"
andrewboyson 13:9cd54f7db57a 13 #include "dnsname.h"
andrewboyson 13:9cd54f7db57a 14
andrewboyson 37:793b39683406 15 bool DnsQueryTrace = false;
andrewboyson 13:9cd54f7db57a 16
andrewboyson 13:9cd54f7db57a 17 #define TIME_OUT_SENT 3
andrewboyson 13:9cd54f7db57a 18
andrewboyson 13:9cd54f7db57a 19 #define MDNS_UNICAST false
andrewboyson 13:9cd54f7db57a 20
andrewboyson 35:93c39d260a83 21 char DnsQueryName[DNS_MAX_LABEL_LENGTH+1];
andrewboyson 13:9cd54f7db57a 22 uint32_t DnsQueryIp4 = 0;
andrewboyson 13:9cd54f7db57a 23 char DnsQueryIp6[16];
andrewboyson 13:9cd54f7db57a 24
andrewboyson 30:e34173b7585c 25 char DnsQueryRecordType = DNS_RECORD_NONE;
andrewboyson 30:e34173b7585c 26 int DnsQueryProtocol = DNS_PROTOCOL_NONE;
andrewboyson 30:e34173b7585c 27 bool DnsQueryIsBusy = false;
andrewboyson 13:9cd54f7db57a 28
andrewboyson 13:9cd54f7db57a 29 static uint32_t started = 0;
andrewboyson 13:9cd54f7db57a 30 static uint32_t elapsed = 0;
andrewboyson 13:9cd54f7db57a 31 static void reap()
andrewboyson 13:9cd54f7db57a 32 {
andrewboyson 13:9cd54f7db57a 33 if (!DnsQueryIsBusy) return;
andrewboyson 13:9cd54f7db57a 34
andrewboyson 13:9cd54f7db57a 35 if (elapsed - started >= TIME_OUT_SENT)
andrewboyson 13:9cd54f7db57a 36 {
andrewboyson 13:9cd54f7db57a 37 char text[100];
andrewboyson 13:9cd54f7db57a 38 LogTimeF("DNS reaped ongoing request for ");
andrewboyson 13:9cd54f7db57a 39 if (DnsQueryName[0]) LogF("name %s", DnsQueryName);
andrewboyson 13:9cd54f7db57a 40 if (DnsQueryIp4)
andrewboyson 13:9cd54f7db57a 41 {
andrewboyson 14:e75a59c1123d 42 Ip4AddressToString(DnsQueryIp4, sizeof(text), text);
andrewboyson 13:9cd54f7db57a 43 LogF("ip4 %s", text);
andrewboyson 13:9cd54f7db57a 44 }
andrewboyson 13:9cd54f7db57a 45 if (DnsQueryIp6[0])
andrewboyson 13:9cd54f7db57a 46 {
andrewboyson 14:e75a59c1123d 47 Ip6AddressToString(DnsQueryIp6, sizeof(text), text);
andrewboyson 13:9cd54f7db57a 48 LogF("ip6 %s", text);
andrewboyson 13:9cd54f7db57a 49 }
andrewboyson 13:9cd54f7db57a 50 LogF("\r\n");
andrewboyson 13:9cd54f7db57a 51
andrewboyson 13:9cd54f7db57a 52 DnsQueryName[0] = 0;
andrewboyson 13:9cd54f7db57a 53 DnsQueryIp4 = 0;
andrewboyson 13:9cd54f7db57a 54 DnsQueryIp6[0] = 0;
andrewboyson 13:9cd54f7db57a 55 DnsQueryIsBusy = false;
andrewboyson 13:9cd54f7db57a 56 started = 0;
andrewboyson 13:9cd54f7db57a 57 DnsQueryProtocol = DNS_PROTOCOL_NONE;
andrewboyson 30:e34173b7585c 58 DnsQueryRecordType = DNS_RECORD_NONE;
andrewboyson 13:9cd54f7db57a 59 }
andrewboyson 13:9cd54f7db57a 60 }
andrewboyson 43:bc028d5a6424 61 void DnsQueryMain()
andrewboyson 13:9cd54f7db57a 62 {
andrewboyson 43:bc028d5a6424 63 if (ClockTicked)
andrewboyson 43:bc028d5a6424 64 {
andrewboyson 43:bc028d5a6424 65 elapsed++;
andrewboyson 43:bc028d5a6424 66 reap();
andrewboyson 43:bc028d5a6424 67 }
andrewboyson 13:9cd54f7db57a 68 }
andrewboyson 13:9cd54f7db57a 69 void DnsQueryIp4FromName(char * name, int protocol)
andrewboyson 13:9cd54f7db57a 70 {
andrewboyson 32:679654f2d023 71 DnsMakeFullNameFromName(protocol, name, sizeof(DnsQueryName), DnsQueryName);
andrewboyson 13:9cd54f7db57a 72 DnsQueryIp4 = 0;
andrewboyson 13:9cd54f7db57a 73 DnsQueryIp6[0] = 0;
andrewboyson 13:9cd54f7db57a 74 DnsQueryIsBusy = true;
andrewboyson 13:9cd54f7db57a 75 started = elapsed;
andrewboyson 13:9cd54f7db57a 76 DnsQueryProtocol = protocol;
andrewboyson 30:e34173b7585c 77 DnsQueryRecordType = DNS_RECORD_A;
andrewboyson 13:9cd54f7db57a 78 }
andrewboyson 13:9cd54f7db57a 79 void DnsQueryIp6FromName(char * name, int protocol)
andrewboyson 13:9cd54f7db57a 80 {
andrewboyson 32:679654f2d023 81 DnsMakeFullNameFromName(protocol, name, sizeof(DnsQueryName), DnsQueryName);
andrewboyson 13:9cd54f7db57a 82 DnsQueryIp4 = 0;
andrewboyson 13:9cd54f7db57a 83 DnsQueryIp6[0] = 0;
andrewboyson 13:9cd54f7db57a 84 DnsQueryIsBusy = true;
andrewboyson 13:9cd54f7db57a 85 started = elapsed;
andrewboyson 13:9cd54f7db57a 86 DnsQueryProtocol = protocol;
andrewboyson 30:e34173b7585c 87 DnsQueryRecordType = DNS_RECORD_AAAA;
andrewboyson 13:9cd54f7db57a 88 }
andrewboyson 13:9cd54f7db57a 89 void DnsQueryNameFromIp4(uint32_t ip, int protocol)
andrewboyson 13:9cd54f7db57a 90 {
andrewboyson 13:9cd54f7db57a 91 DnsQueryName[0] = 0;
andrewboyson 13:9cd54f7db57a 92 DnsQueryIp4 = ip;
andrewboyson 13:9cd54f7db57a 93 DnsQueryIp6[0] = 0;
andrewboyson 13:9cd54f7db57a 94 DnsQueryIsBusy = true;
andrewboyson 13:9cd54f7db57a 95 started = elapsed;
andrewboyson 13:9cd54f7db57a 96 DnsQueryProtocol = protocol;
andrewboyson 30:e34173b7585c 97 DnsQueryRecordType = DNS_RECORD_PTR;
andrewboyson 13:9cd54f7db57a 98 }
andrewboyson 13:9cd54f7db57a 99 void DnsQueryNameFromIp6(char* ip, int protocol)
andrewboyson 13:9cd54f7db57a 100 {
andrewboyson 13:9cd54f7db57a 101 DnsQueryName[0] = 0;
andrewboyson 13:9cd54f7db57a 102 DnsQueryIp4 = 0;
andrewboyson 36:900e24b27bfb 103 Ip6Copy(DnsQueryIp6, ip);
andrewboyson 13:9cd54f7db57a 104 DnsQueryIsBusy = true;
andrewboyson 13:9cd54f7db57a 105 started = elapsed;
andrewboyson 13:9cd54f7db57a 106 DnsQueryProtocol = protocol;
andrewboyson 30:e34173b7585c 107 DnsQueryRecordType = DNS_RECORD_PTR;
andrewboyson 30:e34173b7585c 108 }
andrewboyson 30:e34173b7585c 109 static void logQuery()
andrewboyson 30:e34173b7585c 110 {
andrewboyson 30:e34173b7585c 111 char text[60];
andrewboyson 30:e34173b7585c 112 DnsProtocolToString(DnsQueryProtocol, sizeof(text), text);
andrewboyson 43:bc028d5a6424 113 if (NetTraceNewLine) Log("\r\n");
andrewboyson 32:679654f2d023 114 LogTimeF("DnsQuery sent %s request for ", text);
andrewboyson 30:e34173b7585c 115 DnsRecordTypeToString(DnsQueryRecordType, sizeof(text), text);
andrewboyson 30:e34173b7585c 116 LogF("%s ", text);
andrewboyson 30:e34173b7585c 117 if (DnsQueryIp4) //Reverse
andrewboyson 30:e34173b7585c 118 {
andrewboyson 30:e34173b7585c 119 Ip4AddressToString(DnsQueryIp4, sizeof(text), text);
andrewboyson 30:e34173b7585c 120 LogF("%s\r\n", text);
andrewboyson 30:e34173b7585c 121 }
andrewboyson 30:e34173b7585c 122 else if (DnsQueryIp6[0])
andrewboyson 30:e34173b7585c 123 {
andrewboyson 30:e34173b7585c 124 Ip6AddressToString(DnsQueryIp6, sizeof(text), text);
andrewboyson 30:e34173b7585c 125 LogF("%s\r\n", text);
andrewboyson 30:e34173b7585c 126 }
andrewboyson 30:e34173b7585c 127 else //Forward
andrewboyson 30:e34173b7585c 128 {
andrewboyson 30:e34173b7585c 129 LogF("%s\r\n", DnsQueryName);
andrewboyson 30:e34173b7585c 130 }
andrewboyson 13:9cd54f7db57a 131 }
andrewboyson 13:9cd54f7db57a 132 int DnsQueryPoll(int* pSize)
andrewboyson 13:9cd54f7db57a 133 {
andrewboyson 13:9cd54f7db57a 134 if (!DnsQueryIsBusy) return DO_NOTHING;
andrewboyson 13:9cd54f7db57a 135 if (DnsQueryProtocol == DNS_PROTOCOL_UDNS && DhcpLocalIp == 0) return DO_NOTHING;
andrewboyson 13:9cd54f7db57a 136
andrewboyson 37:793b39683406 137 if (DnsQueryTrace) logQuery();
andrewboyson 30:e34173b7585c 138
andrewboyson 13:9cd54f7db57a 139 static uint16_t id = 0;
andrewboyson 13:9cd54f7db57a 140 DnsHdrId = ++id;
andrewboyson 13:9cd54f7db57a 141 DnsHdrIsReply = false;
andrewboyson 13:9cd54f7db57a 142 DnsHdrIsRecursiveQuery = false;
andrewboyson 13:9cd54f7db57a 143
andrewboyson 13:9cd54f7db57a 144 DnsHdrQdcount = 1;
andrewboyson 13:9cd54f7db57a 145 DnsHdrAncount = 0;
andrewboyson 13:9cd54f7db57a 146 DnsHdrNscount = 0;
andrewboyson 13:9cd54f7db57a 147 DnsHdrArcount = 0;
andrewboyson 13:9cd54f7db57a 148
andrewboyson 13:9cd54f7db57a 149 DnsHdrWrite();
andrewboyson 13:9cd54f7db57a 150 char* p = DnsHdrData;
andrewboyson 13:9cd54f7db57a 151
andrewboyson 30:e34173b7585c 152 if (DnsQueryIp4 ) DnsNameEncodeIp4(DnsQueryIp4, &p);
andrewboyson 30:e34173b7585c 153 else if (DnsQueryIp6[0]) DnsNameEncodeIp6(DnsQueryIp6, &p);
andrewboyson 37:793b39683406 154 else DnsNameEncodePtr(DnsQueryName, &p);
andrewboyson 30:e34173b7585c 155
andrewboyson 30:e34173b7585c 156 *p++ = 0;
andrewboyson 30:e34173b7585c 157 *p++ = DnsQueryRecordType;
andrewboyson 13:9cd54f7db57a 158 *p++ = DnsQueryProtocol == DNS_PROTOCOL_MDNS && MDNS_UNICAST ? 0x80 : 0; //Set the 15th bit (UNICAST_RESPONSE) to 1 if MDNS
andrewboyson 13:9cd54f7db57a 159 *p++ = 1; //QCLASS_IN = 1 - internet
andrewboyson 13:9cd54f7db57a 160
andrewboyson 13:9cd54f7db57a 161 *pSize = p - DnsHdrPacket;
andrewboyson 13:9cd54f7db57a 162
andrewboyson 13:9cd54f7db57a 163 DnsQueryIsBusy = false;
andrewboyson 38:cc8945857a0d 164
andrewboyson 38:cc8945857a0d 165 if (DnsQueryTrace) DnsHdrLog(DnsQueryProtocol);
andrewboyson 13:9cd54f7db57a 166
andrewboyson 37:793b39683406 167 int dest = DO_NOTHING;
andrewboyson 37:793b39683406 168
andrewboyson 13:9cd54f7db57a 169 switch (DnsQueryProtocol)
andrewboyson 13:9cd54f7db57a 170 {
andrewboyson 37:793b39683406 171 case DNS_PROTOCOL_UDNS: dest = UNICAST_DNS; break; //IPv6 ==> NdpDnsServer; IPv4 ==> DhcpDnsServer
andrewboyson 37:793b39683406 172 case DNS_PROTOCOL_MDNS: dest = MULTICAST_MDNS; break;
andrewboyson 37:793b39683406 173 case DNS_PROTOCOL_LLMNR: dest = MULTICAST_LLMNR; break;
andrewboyson 13:9cd54f7db57a 174 default:
andrewboyson 13:9cd54f7db57a 175 LogTimeF("DNS unknown query protocol %d\r\n", DnsQueryProtocol);
andrewboyson 13:9cd54f7db57a 176 return DO_NOTHING;
andrewboyson 13:9cd54f7db57a 177 }
andrewboyson 37:793b39683406 178
andrewboyson 37:793b39683406 179 return ActionMakeFromDestAndTrace(dest, DnsQueryTrace);
andrewboyson 13:9cd54f7db57a 180 }