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 May 20 14:32:52 2021 +0000
Revision:
200:5acbc41bf469
Parent:
193:47a953ab571b
Increased number of arp entries from 20 to 30 to accommodate the number of WIZ devices plus a few incoming port 80 calls from the internet.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 61:aad055f1b0d1 1 #include <stdint.h>
andrewboyson 61:aad055f1b0d1 2 #include <stdbool.h>
andrewboyson 61:aad055f1b0d1 3
andrewboyson 13:9cd54f7db57a 4 #include "log.h"
andrewboyson 93:580fc113d9e9 5 #include "mstimer.h"
andrewboyson 13:9cd54f7db57a 6 #include "net.h"
andrewboyson 37:793b39683406 7 #include "action.h"
andrewboyson 49:1a6336f2b3f9 8 #include "ip4addr.h"
andrewboyson 49:1a6336f2b3f9 9 #include "ip6addr.h"
andrewboyson 13:9cd54f7db57a 10 #include "dhcp.h"
andrewboyson 13:9cd54f7db57a 11 #include "dns.h"
andrewboyson 13:9cd54f7db57a 12 #include "udp.h"
andrewboyson 172:9bc3c7b2cca1 13 #include "eth.h"
andrewboyson 13:9cd54f7db57a 14 #include "slaac.h"
andrewboyson 13:9cd54f7db57a 15 #include "dnshdr.h"
andrewboyson 13:9cd54f7db57a 16 #include "dnsname.h"
andrewboyson 128:79052cb4a41c 17 #include "dnslabel.h"
andrewboyson 193:47a953ab571b 18 #include "ar6.h"
andrewboyson 193:47a953ab571b 19 #include "ndp.h"
andrewboyson 193:47a953ab571b 20 #include "mac.h"
andrewboyson 13:9cd54f7db57a 21
andrewboyson 37:793b39683406 22 bool DnsQueryTrace = false;
andrewboyson 13:9cd54f7db57a 23
andrewboyson 93:580fc113d9e9 24 #define TIME_OUT_SENT_MS 3000
andrewboyson 13:9cd54f7db57a 25
andrewboyson 13:9cd54f7db57a 26 #define MDNS_UNICAST false
andrewboyson 13:9cd54f7db57a 27
andrewboyson 35:93c39d260a83 28 char DnsQueryName[DNS_MAX_LABEL_LENGTH+1];
andrewboyson 13:9cd54f7db57a 29 uint32_t DnsQueryIp4 = 0;
andrewboyson 13:9cd54f7db57a 30 char DnsQueryIp6[16];
andrewboyson 30:e34173b7585c 31 bool DnsQueryIsBusy = false;
andrewboyson 13:9cd54f7db57a 32
andrewboyson 171:f708d6776752 33 static char _RecordType = DNS_RECORD_NONE;
andrewboyson 171:f708d6776752 34 static int _DnsProtocol = DNS_PROTOCOL_NONE;
andrewboyson 171:f708d6776752 35 static int _IpProtocol = 0;
andrewboyson 171:f708d6776752 36 static uint32_t _StartedMs = 0;
andrewboyson 171:f708d6776752 37
andrewboyson 13:9cd54f7db57a 38 static void reap()
andrewboyson 13:9cd54f7db57a 39 {
andrewboyson 13:9cd54f7db57a 40 if (!DnsQueryIsBusy) return;
andrewboyson 13:9cd54f7db57a 41
andrewboyson 171:f708d6776752 42 if (MsTimerRelative(_StartedMs, TIME_OUT_SENT_MS))
andrewboyson 13:9cd54f7db57a 43 {
andrewboyson 173:9bc30cd82a76 44 LogTimeF("DnsQuery reaped ongoing request for record type ");
andrewboyson 173:9bc30cd82a76 45 DnsRecordTypeLog(_RecordType);
andrewboyson 173:9bc30cd82a76 46 if (DnsQueryName[0]) { LogF(" name '%s'", DnsQueryName); }
andrewboyson 187:122fc1996c86 47 if (DnsQueryIp4) { Log(" address "); Ip4AddrLog(DnsQueryIp4); }
andrewboyson 187:122fc1996c86 48 if (DnsQueryIp6[0]) { Log(" address "); Ip6AddrLog(DnsQueryIp6); }
andrewboyson 173:9bc30cd82a76 49 Log(" using ");
andrewboyson 173:9bc30cd82a76 50 DnsProtocolLog(_DnsProtocol);
andrewboyson 173:9bc30cd82a76 51 Log(" over ");
andrewboyson 173:9bc30cd82a76 52 EthProtocolLog(_IpProtocol);
andrewboyson 13:9cd54f7db57a 53 LogF("\r\n");
andrewboyson 13:9cd54f7db57a 54
andrewboyson 13:9cd54f7db57a 55 DnsQueryName[0] = 0;
andrewboyson 13:9cd54f7db57a 56 DnsQueryIp4 = 0;
andrewboyson 13:9cd54f7db57a 57 DnsQueryIp6[0] = 0;
andrewboyson 13:9cd54f7db57a 58 DnsQueryIsBusy = false;
andrewboyson 171:f708d6776752 59 _StartedMs = MsTimerCount;
andrewboyson 171:f708d6776752 60 _DnsProtocol = DNS_PROTOCOL_NONE;
andrewboyson 171:f708d6776752 61 _IpProtocol = 0;
andrewboyson 171:f708d6776752 62 _RecordType = DNS_RECORD_NONE;
andrewboyson 13:9cd54f7db57a 63 }
andrewboyson 13:9cd54f7db57a 64 }
andrewboyson 43:bc028d5a6424 65 void DnsQueryMain()
andrewboyson 13:9cd54f7db57a 66 {
andrewboyson 93:580fc113d9e9 67 reap();
andrewboyson 13:9cd54f7db57a 68 }
andrewboyson 171:f708d6776752 69 void DnsQueryIp4FromName(char * name, int dnsProtocol, int ipProtocol)
andrewboyson 13:9cd54f7db57a 70 {
andrewboyson 176:7eb916c22084 71 if (!name[0])
andrewboyson 176:7eb916c22084 72 {
andrewboyson 176:7eb916c22084 73 LogTime("DnsQueryIp4FromName called with no name\r\n");
andrewboyson 176:7eb916c22084 74 return;
andrewboyson 176:7eb916c22084 75 }
andrewboyson 171:f708d6776752 76 DnsLabelMakeFullNameFromName(dnsProtocol, name, sizeof(DnsQueryName), DnsQueryName);
andrewboyson 171:f708d6776752 77 DnsQueryIp4 = 0;
andrewboyson 171:f708d6776752 78 DnsQueryIp6[0] = 0;
andrewboyson 171:f708d6776752 79 DnsQueryIsBusy = true;
andrewboyson 171:f708d6776752 80 _StartedMs = MsTimerCount;
andrewboyson 171:f708d6776752 81 _DnsProtocol = dnsProtocol;
andrewboyson 171:f708d6776752 82 _IpProtocol = ipProtocol;
andrewboyson 171:f708d6776752 83 _RecordType = DNS_RECORD_A;
andrewboyson 13:9cd54f7db57a 84 }
andrewboyson 171:f708d6776752 85 void DnsQueryIp6FromName(char * name, int dnsProtocol, int ipProtocol)
andrewboyson 13:9cd54f7db57a 86 {
andrewboyson 176:7eb916c22084 87 if (!name[0])
andrewboyson 176:7eb916c22084 88 {
andrewboyson 176:7eb916c22084 89 LogTime("DnsQueryIp6FromName called with no name\r\n");
andrewboyson 176:7eb916c22084 90 return;
andrewboyson 176:7eb916c22084 91 }
andrewboyson 171:f708d6776752 92 DnsLabelMakeFullNameFromName(dnsProtocol, name, sizeof(DnsQueryName), DnsQueryName);
andrewboyson 171:f708d6776752 93 DnsQueryIp4 = 0;
andrewboyson 171:f708d6776752 94 DnsQueryIp6[0] = 0;
andrewboyson 171:f708d6776752 95 DnsQueryIsBusy = true;
andrewboyson 171:f708d6776752 96 _StartedMs = MsTimerCount;
andrewboyson 171:f708d6776752 97 _DnsProtocol = dnsProtocol;
andrewboyson 171:f708d6776752 98 _IpProtocol = ipProtocol;
andrewboyson 171:f708d6776752 99 _RecordType = DNS_RECORD_AAAA;
andrewboyson 13:9cd54f7db57a 100 }
andrewboyson 171:f708d6776752 101 void DnsQueryNameFromIp4(uint32_t ip, int dnsProtocol, int ipProtocol)
andrewboyson 13:9cd54f7db57a 102 {
andrewboyson 176:7eb916c22084 103 if (!ip)
andrewboyson 176:7eb916c22084 104 {
andrewboyson 176:7eb916c22084 105 LogTime("DnsQueryNameFromIp4 called with no ip\r\n");
andrewboyson 176:7eb916c22084 106 return;
andrewboyson 176:7eb916c22084 107 }
andrewboyson 171:f708d6776752 108 DnsQueryName[0] = 0;
andrewboyson 171:f708d6776752 109 DnsQueryIp4 = ip;
andrewboyson 171:f708d6776752 110 DnsQueryIp6[0] = 0;
andrewboyson 171:f708d6776752 111 DnsQueryIsBusy = true;
andrewboyson 171:f708d6776752 112 _StartedMs = MsTimerCount;
andrewboyson 171:f708d6776752 113 _DnsProtocol = dnsProtocol;
andrewboyson 171:f708d6776752 114 _IpProtocol = ipProtocol;
andrewboyson 171:f708d6776752 115 _RecordType = DNS_RECORD_PTR;
andrewboyson 13:9cd54f7db57a 116 }
andrewboyson 171:f708d6776752 117 void DnsQueryNameFromIp6(char* ip, int dnsProtocol, int ipProtocol)
andrewboyson 13:9cd54f7db57a 118 {
andrewboyson 176:7eb916c22084 119 if (!ip[0])
andrewboyson 176:7eb916c22084 120 {
andrewboyson 176:7eb916c22084 121 LogTime("DnsQueryNameFromIp6 called with no ip\r\n");
andrewboyson 176:7eb916c22084 122 return;
andrewboyson 176:7eb916c22084 123 }
andrewboyson 171:f708d6776752 124 DnsQueryName[0] = 0;
andrewboyson 171:f708d6776752 125 DnsQueryIp4 = 0;
andrewboyson 172:9bc3c7b2cca1 126 Ip6AddrCopy(DnsQueryIp6, ip);
andrewboyson 171:f708d6776752 127 DnsQueryIsBusy = true;
andrewboyson 171:f708d6776752 128 _StartedMs = MsTimerCount;
andrewboyson 171:f708d6776752 129 _DnsProtocol = dnsProtocol;
andrewboyson 171:f708d6776752 130 _IpProtocol = ipProtocol;
andrewboyson 171:f708d6776752 131 _RecordType = DNS_RECORD_PTR;
andrewboyson 30:e34173b7585c 132 }
andrewboyson 30:e34173b7585c 133 static void logQuery()
andrewboyson 30:e34173b7585c 134 {
andrewboyson 43:bc028d5a6424 135 if (NetTraceNewLine) Log("\r\n");
andrewboyson 47:73af5c0b0dc2 136 LogTimeF("DnsQuery sent ");
andrewboyson 171:f708d6776752 137 DnsProtocolLog(_DnsProtocol);
andrewboyson 47:73af5c0b0dc2 138 Log(" request for ");
andrewboyson 171:f708d6776752 139 DnsRecordTypeLog(_RecordType);
andrewboyson 47:73af5c0b0dc2 140 Log(" ");
andrewboyson 30:e34173b7585c 141 if (DnsQueryIp4) //Reverse
andrewboyson 30:e34173b7585c 142 {
andrewboyson 187:122fc1996c86 143 Ip4AddrLog(DnsQueryIp4);
andrewboyson 30:e34173b7585c 144 }
andrewboyson 30:e34173b7585c 145 else if (DnsQueryIp6[0])
andrewboyson 30:e34173b7585c 146 {
andrewboyson 172:9bc3c7b2cca1 147 Ip6AddrLog(DnsQueryIp6);
andrewboyson 30:e34173b7585c 148 }
andrewboyson 30:e34173b7585c 149 else //Forward
andrewboyson 30:e34173b7585c 150 {
andrewboyson 47:73af5c0b0dc2 151 Log(DnsQueryName);
andrewboyson 30:e34173b7585c 152 }
andrewboyson 47:73af5c0b0dc2 153 Log("\r\n");
andrewboyson 13:9cd54f7db57a 154 }
andrewboyson 171:f708d6776752 155 int DnsQueryPoll(int ipType, void* pPacket, int* pSize)
andrewboyson 13:9cd54f7db57a 156 {
andrewboyson 59:e0e556c8bd46 157 DnsHdrSetup(pPacket, *pSize);
andrewboyson 59:e0e556c8bd46 158
andrewboyson 171:f708d6776752 159 if (!DnsQueryIsBusy) return DO_NOTHING;
andrewboyson 172:9bc3c7b2cca1 160 if (_IpProtocol != EthProtocol) return DO_NOTHING; //Only use a poll from the required protocol
andrewboyson 171:f708d6776752 161 if (_DnsProtocol == DNS_PROTOCOL_UDNS && DhcpLocalIp == 0) return DO_NOTHING;
andrewboyson 173:9bc30cd82a76 162 if (_RecordType == DNS_RECORD_NONE) return DO_NOTHING;
andrewboyson 173:9bc30cd82a76 163 if (_DnsProtocol == DNS_PROTOCOL_NONE) return DO_NOTHING;
andrewboyson 13:9cd54f7db57a 164
andrewboyson 193:47a953ab571b 165
andrewboyson 193:47a953ab571b 166 //For IPv6 UDNS check if have the MAC for the DNS server and, if not, request it and stop
andrewboyson 193:47a953ab571b 167 if (_IpProtocol == ETH_IPV6 && _DnsProtocol == DNS_PROTOCOL_UDNS)
andrewboyson 193:47a953ab571b 168 {
andrewboyson 193:47a953ab571b 169 if (!Ar6CheckHaveMacAndFetchIfNot(NdpDnsServer)) return DO_NOTHING;
andrewboyson 193:47a953ab571b 170 }
andrewboyson 193:47a953ab571b 171
andrewboyson 57:e0fb648acf48 172 NetTraceHostCheckIp6(DnsQueryIp6);
andrewboyson 57:e0fb648acf48 173
andrewboyson 57:e0fb648acf48 174 if (DnsQueryTrace || NetTraceHostGetMatched()) logQuery();
andrewboyson 30:e34173b7585c 175
andrewboyson 13:9cd54f7db57a 176 static uint16_t id = 0;
andrewboyson 13:9cd54f7db57a 177 DnsHdrId = ++id;
andrewboyson 13:9cd54f7db57a 178 DnsHdrIsReply = false;
andrewboyson 171:f708d6776752 179 DnsHdrIsAuthoritative = false; //Added 12/12/2020
andrewboyson 13:9cd54f7db57a 180 DnsHdrIsRecursiveQuery = false;
andrewboyson 13:9cd54f7db57a 181
andrewboyson 13:9cd54f7db57a 182 DnsHdrQdcount = 1;
andrewboyson 13:9cd54f7db57a 183 DnsHdrAncount = 0;
andrewboyson 13:9cd54f7db57a 184 DnsHdrNscount = 0;
andrewboyson 13:9cd54f7db57a 185 DnsHdrArcount = 0;
andrewboyson 13:9cd54f7db57a 186
andrewboyson 13:9cd54f7db57a 187 DnsHdrWrite();
andrewboyson 13:9cd54f7db57a 188 char* p = DnsHdrData;
andrewboyson 13:9cd54f7db57a 189
andrewboyson 176:7eb916c22084 190 if (DnsQueryIp4 ) DnsNameEncodeIp4(DnsQueryIp4, &p);
andrewboyson 176:7eb916c22084 191 else if (DnsQueryIp6[0] ) DnsNameEncodeIp6(DnsQueryIp6, &p);
andrewboyson 176:7eb916c22084 192 else if (DnsQueryName[0]) DnsNameEncodePtr(DnsQueryName, &p);
andrewboyson 176:7eb916c22084 193 else return DO_NOTHING;
andrewboyson 30:e34173b7585c 194
andrewboyson 30:e34173b7585c 195 *p++ = 0;
andrewboyson 171:f708d6776752 196 *p++ = _RecordType;
andrewboyson 171:f708d6776752 197 *p++ = _DnsProtocol == DNS_PROTOCOL_MDNS && MDNS_UNICAST ? 0x80 : 0; //Set the 15th bit (UNICAST_RESPONSE) to 1 if MDNS
andrewboyson 13:9cd54f7db57a 198 *p++ = 1; //QCLASS_IN = 1 - internet
andrewboyson 13:9cd54f7db57a 199
andrewboyson 13:9cd54f7db57a 200 *pSize = p - DnsHdrPacket;
andrewboyson 13:9cd54f7db57a 201
andrewboyson 13:9cd54f7db57a 202 DnsQueryIsBusy = false;
andrewboyson 38:cc8945857a0d 203
andrewboyson 171:f708d6776752 204 if (DnsQueryTrace || NetTraceHostGetMatched()) DnsHdrLog(_DnsProtocol);
andrewboyson 13:9cd54f7db57a 205
andrewboyson 37:793b39683406 206 int dest = DO_NOTHING;
andrewboyson 37:793b39683406 207
andrewboyson 171:f708d6776752 208 switch (_DnsProtocol)
andrewboyson 13:9cd54f7db57a 209 {
andrewboyson 37:793b39683406 210 case DNS_PROTOCOL_UDNS: dest = UNICAST_DNS; break; //IPv6 ==> NdpDnsServer; IPv4 ==> DhcpDnsServer
andrewboyson 37:793b39683406 211 case DNS_PROTOCOL_MDNS: dest = MULTICAST_MDNS; break;
andrewboyson 37:793b39683406 212 case DNS_PROTOCOL_LLMNR: dest = MULTICAST_LLMNR; break;
andrewboyson 13:9cd54f7db57a 213 default:
andrewboyson 171:f708d6776752 214 LogTimeF("DNS unknown query protocol %d\r\n", _DnsProtocol);
andrewboyson 13:9cd54f7db57a 215 return DO_NOTHING;
andrewboyson 13:9cd54f7db57a 216 }
andrewboyson 37:793b39683406 217
andrewboyson 57:e0fb648acf48 218 return ActionMakeFromDestAndTrace(dest, DnsQueryTrace || NetTraceHostGetMatched());
andrewboyson 13:9cd54f7db57a 219 }