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:
Sun Dec 02 18:40:35 2018 +0000
Revision:
93:580fc113d9e9
Parent:
66:18a10c0b6d93
Child:
128:79052cb4a41c
Removed ClockTick and replaced with ms timer.

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