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:
Wed Dec 23 09:52:47 2020 +0000
Revision:
173:9bc30cd82a76
Parent:
172:9bc3c7b2cca1
Child:
176:7eb916c22084
Fixed problem with decoding 32 bit numbers in ndp

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 13:9cd54f7db57a 18
andrewboyson 37:793b39683406 19 bool DnsQueryTrace = false;
andrewboyson 13:9cd54f7db57a 20
andrewboyson 93:580fc113d9e9 21 #define TIME_OUT_SENT_MS 3000
andrewboyson 13:9cd54f7db57a 22
andrewboyson 13:9cd54f7db57a 23 #define MDNS_UNICAST false
andrewboyson 13:9cd54f7db57a 24
andrewboyson 35:93c39d260a83 25 char DnsQueryName[DNS_MAX_LABEL_LENGTH+1];
andrewboyson 13:9cd54f7db57a 26 uint32_t DnsQueryIp4 = 0;
andrewboyson 13:9cd54f7db57a 27 char DnsQueryIp6[16];
andrewboyson 30:e34173b7585c 28 bool DnsQueryIsBusy = false;
andrewboyson 13:9cd54f7db57a 29
andrewboyson 171:f708d6776752 30 static char _RecordType = DNS_RECORD_NONE;
andrewboyson 171:f708d6776752 31 static int _DnsProtocol = DNS_PROTOCOL_NONE;
andrewboyson 171:f708d6776752 32 static int _IpProtocol = 0;
andrewboyson 171:f708d6776752 33 static uint32_t _StartedMs = 0;
andrewboyson 171:f708d6776752 34
andrewboyson 13:9cd54f7db57a 35 static void reap()
andrewboyson 13:9cd54f7db57a 36 {
andrewboyson 13:9cd54f7db57a 37 if (!DnsQueryIsBusy) return;
andrewboyson 13:9cd54f7db57a 38
andrewboyson 171:f708d6776752 39 if (MsTimerRelative(_StartedMs, TIME_OUT_SENT_MS))
andrewboyson 13:9cd54f7db57a 40 {
andrewboyson 173:9bc30cd82a76 41 LogTimeF("DnsQuery reaped ongoing request for record type ");
andrewboyson 173:9bc30cd82a76 42 DnsRecordTypeLog(_RecordType);
andrewboyson 173:9bc30cd82a76 43 if (DnsQueryName[0]) { LogF(" name '%s'", DnsQueryName); }
andrewboyson 173:9bc30cd82a76 44 if (DnsQueryIp4) { Log(" address "); Ip4AddressLog(DnsQueryIp4); }
andrewboyson 173:9bc30cd82a76 45 if (DnsQueryIp6[0]) { Log(" address "); Ip6AddrLog (DnsQueryIp6); }
andrewboyson 173:9bc30cd82a76 46 Log(" using ");
andrewboyson 173:9bc30cd82a76 47 DnsProtocolLog(_DnsProtocol);
andrewboyson 173:9bc30cd82a76 48 Log(" over ");
andrewboyson 173:9bc30cd82a76 49 EthProtocolLog(_IpProtocol);
andrewboyson 13:9cd54f7db57a 50 LogF("\r\n");
andrewboyson 13:9cd54f7db57a 51
andrewboyson 13:9cd54f7db57a 52 DnsQueryName[0] = 0;
andrewboyson 13:9cd54f7db57a 53 DnsQueryIp4 = 0;
andrewboyson 13:9cd54f7db57a 54 DnsQueryIp6[0] = 0;
andrewboyson 13:9cd54f7db57a 55 DnsQueryIsBusy = false;
andrewboyson 171:f708d6776752 56 _StartedMs = MsTimerCount;
andrewboyson 171:f708d6776752 57 _DnsProtocol = DNS_PROTOCOL_NONE;
andrewboyson 171:f708d6776752 58 _IpProtocol = 0;
andrewboyson 171:f708d6776752 59 _RecordType = DNS_RECORD_NONE;
andrewboyson 13:9cd54f7db57a 60 }
andrewboyson 13:9cd54f7db57a 61 }
andrewboyson 43:bc028d5a6424 62 void DnsQueryMain()
andrewboyson 13:9cd54f7db57a 63 {
andrewboyson 93:580fc113d9e9 64 reap();
andrewboyson 13:9cd54f7db57a 65 }
andrewboyson 171:f708d6776752 66 void DnsQueryIp4FromName(char * name, int dnsProtocol, int ipProtocol)
andrewboyson 13:9cd54f7db57a 67 {
andrewboyson 171:f708d6776752 68 DnsLabelMakeFullNameFromName(dnsProtocol, name, sizeof(DnsQueryName), DnsQueryName);
andrewboyson 171:f708d6776752 69 DnsQueryIp4 = 0;
andrewboyson 171:f708d6776752 70 DnsQueryIp6[0] = 0;
andrewboyson 171:f708d6776752 71 DnsQueryIsBusy = true;
andrewboyson 171:f708d6776752 72 _StartedMs = MsTimerCount;
andrewboyson 171:f708d6776752 73 _DnsProtocol = dnsProtocol;
andrewboyson 171:f708d6776752 74 _IpProtocol = ipProtocol;
andrewboyson 171:f708d6776752 75 _RecordType = DNS_RECORD_A;
andrewboyson 13:9cd54f7db57a 76 }
andrewboyson 171:f708d6776752 77 void DnsQueryIp6FromName(char * name, int dnsProtocol, int ipProtocol)
andrewboyson 13:9cd54f7db57a 78 {
andrewboyson 171:f708d6776752 79 DnsLabelMakeFullNameFromName(dnsProtocol, name, sizeof(DnsQueryName), DnsQueryName);
andrewboyson 171:f708d6776752 80 DnsQueryIp4 = 0;
andrewboyson 171:f708d6776752 81 DnsQueryIp6[0] = 0;
andrewboyson 171:f708d6776752 82 DnsQueryIsBusy = true;
andrewboyson 171:f708d6776752 83 _StartedMs = MsTimerCount;
andrewboyson 171:f708d6776752 84 _DnsProtocol = dnsProtocol;
andrewboyson 171:f708d6776752 85 _IpProtocol = ipProtocol;
andrewboyson 171:f708d6776752 86 _RecordType = DNS_RECORD_AAAA;
andrewboyson 13:9cd54f7db57a 87 }
andrewboyson 171:f708d6776752 88 void DnsQueryNameFromIp4(uint32_t ip, int dnsProtocol, int ipProtocol)
andrewboyson 13:9cd54f7db57a 89 {
andrewboyson 171:f708d6776752 90 DnsQueryName[0] = 0;
andrewboyson 171:f708d6776752 91 DnsQueryIp4 = ip;
andrewboyson 171:f708d6776752 92 DnsQueryIp6[0] = 0;
andrewboyson 171:f708d6776752 93 DnsQueryIsBusy = true;
andrewboyson 171:f708d6776752 94 _StartedMs = MsTimerCount;
andrewboyson 171:f708d6776752 95 _DnsProtocol = dnsProtocol;
andrewboyson 171:f708d6776752 96 _IpProtocol = ipProtocol;
andrewboyson 171:f708d6776752 97 _RecordType = DNS_RECORD_PTR;
andrewboyson 13:9cd54f7db57a 98 }
andrewboyson 171:f708d6776752 99 void DnsQueryNameFromIp6(char* ip, int dnsProtocol, int ipProtocol)
andrewboyson 13:9cd54f7db57a 100 {
andrewboyson 171:f708d6776752 101 DnsQueryName[0] = 0;
andrewboyson 171:f708d6776752 102 DnsQueryIp4 = 0;
andrewboyson 172:9bc3c7b2cca1 103 Ip6AddrCopy(DnsQueryIp6, ip);
andrewboyson 171:f708d6776752 104 DnsQueryIsBusy = true;
andrewboyson 171:f708d6776752 105 _StartedMs = MsTimerCount;
andrewboyson 171:f708d6776752 106 _DnsProtocol = dnsProtocol;
andrewboyson 171:f708d6776752 107 _IpProtocol = ipProtocol;
andrewboyson 171:f708d6776752 108 _RecordType = DNS_RECORD_PTR;
andrewboyson 30:e34173b7585c 109 }
andrewboyson 30:e34173b7585c 110 static void logQuery()
andrewboyson 30:e34173b7585c 111 {
andrewboyson 43:bc028d5a6424 112 if (NetTraceNewLine) Log("\r\n");
andrewboyson 47:73af5c0b0dc2 113 LogTimeF("DnsQuery sent ");
andrewboyson 171:f708d6776752 114 DnsProtocolLog(_DnsProtocol);
andrewboyson 47:73af5c0b0dc2 115 Log(" request for ");
andrewboyson 171:f708d6776752 116 DnsRecordTypeLog(_RecordType);
andrewboyson 47:73af5c0b0dc2 117 Log(" ");
andrewboyson 30:e34173b7585c 118 if (DnsQueryIp4) //Reverse
andrewboyson 30:e34173b7585c 119 {
andrewboyson 47:73af5c0b0dc2 120 Ip4AddressLog(DnsQueryIp4);
andrewboyson 30:e34173b7585c 121 }
andrewboyson 30:e34173b7585c 122 else if (DnsQueryIp6[0])
andrewboyson 30:e34173b7585c 123 {
andrewboyson 172:9bc3c7b2cca1 124 Ip6AddrLog(DnsQueryIp6);
andrewboyson 30:e34173b7585c 125 }
andrewboyson 30:e34173b7585c 126 else //Forward
andrewboyson 30:e34173b7585c 127 {
andrewboyson 47:73af5c0b0dc2 128 Log(DnsQueryName);
andrewboyson 30:e34173b7585c 129 }
andrewboyson 47:73af5c0b0dc2 130 Log("\r\n");
andrewboyson 13:9cd54f7db57a 131 }
andrewboyson 171:f708d6776752 132 int DnsQueryPoll(int ipType, void* pPacket, int* pSize)
andrewboyson 13:9cd54f7db57a 133 {
andrewboyson 59:e0e556c8bd46 134 DnsHdrSetup(pPacket, *pSize);
andrewboyson 59:e0e556c8bd46 135
andrewboyson 171:f708d6776752 136 if (!DnsQueryIsBusy) return DO_NOTHING;
andrewboyson 172:9bc3c7b2cca1 137 if (_IpProtocol != EthProtocol) return DO_NOTHING; //Only use a poll from the required protocol
andrewboyson 171:f708d6776752 138 if (_DnsProtocol == DNS_PROTOCOL_UDNS && DhcpLocalIp == 0) return DO_NOTHING;
andrewboyson 173:9bc30cd82a76 139 if (_RecordType == DNS_RECORD_NONE) return DO_NOTHING;
andrewboyson 173:9bc30cd82a76 140 if (_DnsProtocol == DNS_PROTOCOL_NONE) return DO_NOTHING;
andrewboyson 13:9cd54f7db57a 141
andrewboyson 57:e0fb648acf48 142 NetTraceHostCheckIp6(DnsQueryIp6);
andrewboyson 57:e0fb648acf48 143
andrewboyson 57:e0fb648acf48 144 if (DnsQueryTrace || NetTraceHostGetMatched()) logQuery();
andrewboyson 30:e34173b7585c 145
andrewboyson 13:9cd54f7db57a 146 static uint16_t id = 0;
andrewboyson 13:9cd54f7db57a 147 DnsHdrId = ++id;
andrewboyson 13:9cd54f7db57a 148 DnsHdrIsReply = false;
andrewboyson 171:f708d6776752 149 DnsHdrIsAuthoritative = false; //Added 12/12/2020
andrewboyson 13:9cd54f7db57a 150 DnsHdrIsRecursiveQuery = false;
andrewboyson 13:9cd54f7db57a 151
andrewboyson 13:9cd54f7db57a 152 DnsHdrQdcount = 1;
andrewboyson 13:9cd54f7db57a 153 DnsHdrAncount = 0;
andrewboyson 13:9cd54f7db57a 154 DnsHdrNscount = 0;
andrewboyson 13:9cd54f7db57a 155 DnsHdrArcount = 0;
andrewboyson 13:9cd54f7db57a 156
andrewboyson 13:9cd54f7db57a 157 DnsHdrWrite();
andrewboyson 13:9cd54f7db57a 158 char* p = DnsHdrData;
andrewboyson 13:9cd54f7db57a 159
andrewboyson 30:e34173b7585c 160 if (DnsQueryIp4 ) DnsNameEncodeIp4(DnsQueryIp4, &p);
andrewboyson 30:e34173b7585c 161 else if (DnsQueryIp6[0]) DnsNameEncodeIp6(DnsQueryIp6, &p);
andrewboyson 37:793b39683406 162 else DnsNameEncodePtr(DnsQueryName, &p);
andrewboyson 30:e34173b7585c 163
andrewboyson 30:e34173b7585c 164 *p++ = 0;
andrewboyson 171:f708d6776752 165 *p++ = _RecordType;
andrewboyson 171:f708d6776752 166 *p++ = _DnsProtocol == DNS_PROTOCOL_MDNS && MDNS_UNICAST ? 0x80 : 0; //Set the 15th bit (UNICAST_RESPONSE) to 1 if MDNS
andrewboyson 13:9cd54f7db57a 167 *p++ = 1; //QCLASS_IN = 1 - internet
andrewboyson 13:9cd54f7db57a 168
andrewboyson 13:9cd54f7db57a 169 *pSize = p - DnsHdrPacket;
andrewboyson 13:9cd54f7db57a 170
andrewboyson 13:9cd54f7db57a 171 DnsQueryIsBusy = false;
andrewboyson 38:cc8945857a0d 172
andrewboyson 171:f708d6776752 173 if (DnsQueryTrace || NetTraceHostGetMatched()) DnsHdrLog(_DnsProtocol);
andrewboyson 13:9cd54f7db57a 174
andrewboyson 37:793b39683406 175 int dest = DO_NOTHING;
andrewboyson 37:793b39683406 176
andrewboyson 171:f708d6776752 177 switch (_DnsProtocol)
andrewboyson 13:9cd54f7db57a 178 {
andrewboyson 37:793b39683406 179 case DNS_PROTOCOL_UDNS: dest = UNICAST_DNS; break; //IPv6 ==> NdpDnsServer; IPv4 ==> DhcpDnsServer
andrewboyson 37:793b39683406 180 case DNS_PROTOCOL_MDNS: dest = MULTICAST_MDNS; break;
andrewboyson 37:793b39683406 181 case DNS_PROTOCOL_LLMNR: dest = MULTICAST_LLMNR; break;
andrewboyson 13:9cd54f7db57a 182 default:
andrewboyson 171:f708d6776752 183 LogTimeF("DNS unknown query protocol %d\r\n", _DnsProtocol);
andrewboyson 13:9cd54f7db57a 184 return DO_NOTHING;
andrewboyson 13:9cd54f7db57a 185 }
andrewboyson 37:793b39683406 186
andrewboyson 57:e0fb648acf48 187 return ActionMakeFromDestAndTrace(dest, DnsQueryTrace || NetTraceHostGetMatched());
andrewboyson 13:9cd54f7db57a 188 }