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 Jan 11 17:38:21 2018 +0000
Revision:
61:aad055f1b0d1
Parent:
udp/dns/dns.cpp@59:e0e556c8bd46
Child:
83:08c983006a6e
Removed dependence on Mbed OS

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