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:
Mon May 01 18:20:55 2017 +0000
Revision:
13:9cd54f7db57a
Child:
14:e75a59c1123d
Added ability to read DNS queries with encoded IP addresses

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