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 Oct 06 10:18:01 2017 +0000
Revision:
41:db727df5f98b
Parent:
37:793b39683406
Child:
43:bc028d5a6424
Changed DNS order between IPv4 and IPv6

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 13:9cd54f7db57a 1 #include "dns.h"
andrewboyson 13:9cd54f7db57a 2 #include "dnshdr.h"
andrewboyson 13:9cd54f7db57a 3 #include "dnsquery.h"
andrewboyson 13:9cd54f7db57a 4 #include "dnsreply.h"
andrewboyson 13:9cd54f7db57a 5 #include "dnsserver.h"
andrewboyson 13:9cd54f7db57a 6 #include "io.h"
andrewboyson 32:679654f2d023 7 #include "log.h"
andrewboyson 32:679654f2d023 8 #include "dhcp.h"
andrewboyson 13:9cd54f7db57a 9
andrewboyson 13:9cd54f7db57a 10 void DnsProtocolToString(uint8_t protocol, int size, char* text)
andrewboyson 13:9cd54f7db57a 11 {
andrewboyson 13:9cd54f7db57a 12 switch (protocol)
andrewboyson 13:9cd54f7db57a 13 {
andrewboyson 13:9cd54f7db57a 14 case DNS_PROTOCOL_UDNS: strncpy (text, "DNS", size); break;
andrewboyson 13:9cd54f7db57a 15 case DNS_PROTOCOL_MDNS: strncpy (text, "MDNS", size); break;
andrewboyson 13:9cd54f7db57a 16 case DNS_PROTOCOL_LLMNR: strncpy (text, "LLMNR", size); break;
andrewboyson 13:9cd54f7db57a 17 default: snprintf(text, size, "%d", protocol); break;
andrewboyson 13:9cd54f7db57a 18 }
andrewboyson 13:9cd54f7db57a 19 }
andrewboyson 13:9cd54f7db57a 20
andrewboyson 13:9cd54f7db57a 21 void DnsRecordTypeToString(uint8_t recordtype, int size, char* text)
andrewboyson 13:9cd54f7db57a 22 {
andrewboyson 13:9cd54f7db57a 23 switch (recordtype)
andrewboyson 13:9cd54f7db57a 24 {
andrewboyson 13:9cd54f7db57a 25 case DNS_RECORD_A: strncpy (text, "A", size); break;
andrewboyson 13:9cd54f7db57a 26 case DNS_RECORD_AAAA: strncpy (text, "AAAA", size); break;
andrewboyson 13:9cd54f7db57a 27 case DNS_RECORD_PTR: strncpy (text, "PTR", size); break;
andrewboyson 15:6ca6778168b1 28 case DNS_RECORD_TXT: strncpy (text, "TXT", size); break;
andrewboyson 15:6ca6778168b1 29 case DNS_RECORD_SRV: strncpy (text, "SRV", size); break;
andrewboyson 13:9cd54f7db57a 30 default: snprintf(text, size, "%d", recordtype); break;
andrewboyson 13:9cd54f7db57a 31 }
andrewboyson 13:9cd54f7db57a 32 }
andrewboyson 41:db727df5f98b 33 int DnsGetNextProtocol4(int protocol)
andrewboyson 32:679654f2d023 34 {
andrewboyson 32:679654f2d023 35 switch(protocol)
andrewboyson 32:679654f2d023 36 {
andrewboyson 32:679654f2d023 37 case DNS_PROTOCOL_NONE: return DNS_PROTOCOL_UDNS;
andrewboyson 32:679654f2d023 38 case DNS_PROTOCOL_UDNS: return DNS_PROTOCOL_MDNS;
andrewboyson 32:679654f2d023 39 case DNS_PROTOCOL_MDNS: return DNS_PROTOCOL_LLMNR;
andrewboyson 32:679654f2d023 40 case DNS_PROTOCOL_LLMNR: return DNS_PROTOCOL_NONE;
andrewboyson 32:679654f2d023 41 default: LogTimeF("DNS invalid protocol %d\r\n", protocol); return DNS_PROTOCOL_NONE;
andrewboyson 32:679654f2d023 42 }
andrewboyson 32:679654f2d023 43 }
andrewboyson 41:db727df5f98b 44 int DnsGetNextProtocol6(int protocol)
andrewboyson 41:db727df5f98b 45 {
andrewboyson 41:db727df5f98b 46 switch(protocol)
andrewboyson 41:db727df5f98b 47 {
andrewboyson 41:db727df5f98b 48 case DNS_PROTOCOL_NONE: return DNS_PROTOCOL_MDNS;
andrewboyson 41:db727df5f98b 49 case DNS_PROTOCOL_MDNS: return DNS_PROTOCOL_LLMNR;
andrewboyson 41:db727df5f98b 50 case DNS_PROTOCOL_LLMNR: return DNS_PROTOCOL_UDNS;
andrewboyson 41:db727df5f98b 51 case DNS_PROTOCOL_UDNS: return DNS_PROTOCOL_NONE;
andrewboyson 41:db727df5f98b 52 default: LogTimeF("DNS invalid protocol %d\r\n", protocol); return DNS_PROTOCOL_NONE;
andrewboyson 41:db727df5f98b 53 }
andrewboyson 41:db727df5f98b 54 }
andrewboyson 33:714a0345e59b 55 bool DnsHostNamesEquate(char* pA, char* pB)
andrewboyson 33:714a0345e59b 56 {
andrewboyson 33:714a0345e59b 57 while(true)
andrewboyson 33:714a0345e59b 58 {
andrewboyson 33:714a0345e59b 59 char a = *pA++;
andrewboyson 33:714a0345e59b 60 char b = *pB++;
andrewboyson 33:714a0345e59b 61 if (a >= 'A' && a <= 'Z') a |= 0x20; //Make lower case
andrewboyson 33:714a0345e59b 62 if (b >= 'A' && b <= 'Z') b |= 0x20; //Make lower case
andrewboyson 33:714a0345e59b 63 if (a != b) return false; //If different then stop and return the fact
andrewboyson 33:714a0345e59b 64 if (!a) break; //No need to check 'b' too as it will necessarily be equal to 'a' at this point.
andrewboyson 33:714a0345e59b 65 }
andrewboyson 33:714a0345e59b 66 return true; //If we get here the strings must equate.
andrewboyson 33:714a0345e59b 67 }
andrewboyson 33:714a0345e59b 68
andrewboyson 32:679654f2d023 69 int DnsMakeFullNameFromName(int protocol, char* p, int size, char* result)
andrewboyson 32:679654f2d023 70 {
andrewboyson 32:679654f2d023 71 int i = 0;
andrewboyson 32:679654f2d023 72 char c;
andrewboyson 32:679654f2d023 73
andrewboyson 32:679654f2d023 74 while (i < size - 1)
andrewboyson 32:679654f2d023 75 {
andrewboyson 32:679654f2d023 76 c = *p++;
andrewboyson 32:679654f2d023 77 if (!c) break;
andrewboyson 32:679654f2d023 78 *result++ = c;
andrewboyson 32:679654f2d023 79 i++;
andrewboyson 32:679654f2d023 80 }
andrewboyson 32:679654f2d023 81 if (protocol == DNS_PROTOCOL_MDNS)
andrewboyson 32:679654f2d023 82 {
andrewboyson 32:679654f2d023 83 p = ".local";
andrewboyson 32:679654f2d023 84 while (i < size - 1)
andrewboyson 32:679654f2d023 85 {
andrewboyson 32:679654f2d023 86 c = *p++;
andrewboyson 32:679654f2d023 87 if (!c) break;
andrewboyson 32:679654f2d023 88 *result++ = c;
andrewboyson 32:679654f2d023 89 i++;
andrewboyson 32:679654f2d023 90 }
andrewboyson 32:679654f2d023 91 }
andrewboyson 32:679654f2d023 92 if (protocol == DNS_PROTOCOL_UDNS && DhcpDomainName[0]) //Shouldn't do this in IPv6 as DHCP is IPv4 only
andrewboyson 32:679654f2d023 93 {
andrewboyson 32:679654f2d023 94 if (i < size - 1)
andrewboyson 32:679654f2d023 95 {
andrewboyson 32:679654f2d023 96 *result++ = '.';
andrewboyson 32:679654f2d023 97 i++;
andrewboyson 32:679654f2d023 98 }
andrewboyson 32:679654f2d023 99 p = DhcpDomainName;
andrewboyson 32:679654f2d023 100 while (i < size - 1)
andrewboyson 32:679654f2d023 101 {
andrewboyson 32:679654f2d023 102 c = *p++;
andrewboyson 32:679654f2d023 103 if (!c) break;
andrewboyson 32:679654f2d023 104 *result++ = c;
andrewboyson 32:679654f2d023 105 i++;
andrewboyson 32:679654f2d023 106 }
andrewboyson 32:679654f2d023 107 }
andrewboyson 32:679654f2d023 108 *result = 0; //Terminate the resulting string
andrewboyson 32:679654f2d023 109 return i;
andrewboyson 32:679654f2d023 110 }
andrewboyson 32:679654f2d023 111 int DnsStripNameFromFullName(int protocol, char* p, int size, char* result)
andrewboyson 32:679654f2d023 112 {
andrewboyson 32:679654f2d023 113 int i = 0;
andrewboyson 32:679654f2d023 114 char c;
andrewboyson 32:679654f2d023 115
andrewboyson 32:679654f2d023 116 while (i < size - 1)
andrewboyson 32:679654f2d023 117 {
andrewboyson 32:679654f2d023 118 c = *p++;
andrewboyson 32:679654f2d023 119 if (c == 0) break; //End of the fqdn so stop
andrewboyson 32:679654f2d023 120 if (c == '.')
andrewboyson 32:679654f2d023 121 {
andrewboyson 32:679654f2d023 122 if (protocol == DNS_PROTOCOL_UDNS)
andrewboyson 32:679654f2d023 123 {
andrewboyson 32:679654f2d023 124 if (strcmp(p, DhcpDomainName) == 0) break; //Strip the domain from a UDNS fqdn if, and only if, it matches the domain given in DHCP. IPv4 only.
andrewboyson 32:679654f2d023 125 }
andrewboyson 32:679654f2d023 126 else
andrewboyson 32:679654f2d023 127 {
andrewboyson 32:679654f2d023 128 break; //Strip the domain from an LLMNR (there shouldn't be one) or MDNS (it should always be '.local') fqdn
andrewboyson 32:679654f2d023 129 }
andrewboyson 32:679654f2d023 130 }
andrewboyson 32:679654f2d023 131 *result++ = c;
andrewboyson 32:679654f2d023 132 i++;
andrewboyson 32:679654f2d023 133 }
andrewboyson 32:679654f2d023 134 *result = 0; //Terminate the copied string
andrewboyson 32:679654f2d023 135 return i;
andrewboyson 32:679654f2d023 136 }
andrewboyson 13:9cd54f7db57a 137
andrewboyson 13:9cd54f7db57a 138 void DnsTick()
andrewboyson 13:9cd54f7db57a 139 {
andrewboyson 13:9cd54f7db57a 140 DnsQueryTick();
andrewboyson 13:9cd54f7db57a 141 }
andrewboyson 13:9cd54f7db57a 142
andrewboyson 37:793b39683406 143 int DnsHandlePacketReceived(void (*traceback)(void), int dnsProtocol, int* pSize, void* pPacket)
andrewboyson 13:9cd54f7db57a 144 {
andrewboyson 13:9cd54f7db57a 145 DnsHdrSetup(pPacket);
andrewboyson 13:9cd54f7db57a 146 DnsHdrRead();
andrewboyson 13:9cd54f7db57a 147 int action;
andrewboyson 13:9cd54f7db57a 148 if (DnsHdrIsReply)
andrewboyson 13:9cd54f7db57a 149 {
andrewboyson 37:793b39683406 150 action = DnsReplyHandle(traceback, dnsProtocol, pSize);
andrewboyson 13:9cd54f7db57a 151 }
andrewboyson 13:9cd54f7db57a 152 else
andrewboyson 13:9cd54f7db57a 153 {
andrewboyson 37:793b39683406 154 action = DnsServerHandleQuery(traceback, dnsProtocol, pSize);
andrewboyson 13:9cd54f7db57a 155 }
andrewboyson 13:9cd54f7db57a 156 return action;
andrewboyson 13:9cd54f7db57a 157 }
andrewboyson 13:9cd54f7db57a 158
andrewboyson 13:9cd54f7db57a 159 int DnsPollForPacketToSend(void* pPacket, int* pSize)
andrewboyson 13:9cd54f7db57a 160 {
andrewboyson 13:9cd54f7db57a 161 DnsHdrSetup(pPacket);
andrewboyson 13:9cd54f7db57a 162 return DnsQueryPoll(pSize);
andrewboyson 13:9cd54f7db57a 163 }