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:
Fri May 05 17:44:16 2017 +0000
Revision:
14:e75a59c1123d
Parent:
13:9cd54f7db57a
Child:
15:6ca6778168b1
Made IP addresses and ports available to debug messages

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