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 Aug 17 14:21:02 2017 +0000
Revision:
32:679654f2d023
Parent:
30:e34173b7585c
Child:
33:714a0345e59b
Corrected issues with .local in llmnr and mdns

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