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
udp/dns/dnsquery.c@200:5acbc41bf469, 2021-05-20 (annotated)
- 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?
User | Revision | Line number | New 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 | } |