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
Diff: udp/dns/dns.c
- Revision:
- 61:aad055f1b0d1
- Parent:
- 59:e0e556c8bd46
- Child:
- 83:08c983006a6e
diff -r 1d8c7a1e7483 -r aad055f1b0d1 udp/dns/dns.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/udp/dns/dns.c Thu Jan 11 17:38:21 2018 +0000 @@ -0,0 +1,190 @@ +#include <stdint.h> +#include <stdbool.h> +#include <string.h> +#include <stdio.h> + +#include "dns.h" +#include "dnshdr.h" +#include "dnsquery.h" +#include "dnsreply.h" +#include "dnsserver.h" +#include "log.h" +#include "dhcp.h" + +void DnsProtocolString(uint8_t protocol, int size, char* text) +{ + switch (protocol) + { + case DNS_PROTOCOL_UDNS: strncpy (text, "DNS", size); break; + case DNS_PROTOCOL_MDNS: strncpy (text, "MDNS", size); break; + case DNS_PROTOCOL_LLMNR: strncpy (text, "LLMNR", size); break; + default: snprintf(text, size, "%d", protocol); break; + } +} + +void DnsRecordTypeString(uint8_t recordtype, int size, char* text) +{ + switch (recordtype) + { + case DNS_RECORD_A: strncpy (text, "A", size); break; + case DNS_RECORD_AAAA: strncpy (text, "AAAA", size); break; + case DNS_RECORD_PTR: strncpy (text, "PTR", size); break; + case DNS_RECORD_TXT: strncpy (text, "TXT", size); break; + case DNS_RECORD_SRV: strncpy (text, "SRV", size); break; + default: snprintf(text, size, "%d", recordtype); break; + } +} +void DnsProtocolLog(uint8_t protocol) +{ + switch (protocol) + { + case DNS_PROTOCOL_UDNS: Log ("DNS "); break; + case DNS_PROTOCOL_MDNS: Log ("MDNS "); break; + case DNS_PROTOCOL_LLMNR: Log ("LLMNR"); break; + default: LogF("%d", protocol); break; + } +} + +void DnsRecordTypeLog(uint8_t recordtype) +{ + switch (recordtype) + { + case DNS_RECORD_A: Log ("A" ); break; + case DNS_RECORD_AAAA: Log ("AAAA"); break; + case DNS_RECORD_PTR: Log ("PTR" ); break; + case DNS_RECORD_TXT: Log ("TXT" ); break; + case DNS_RECORD_SRV: Log ("SRV" ); break; + default: LogF("%d", recordtype); break; + } +} +int DnsGetNextProtocol4(int protocol) +{ + switch(protocol) + { + case DNS_PROTOCOL_NONE: return DNS_PROTOCOL_UDNS; + case DNS_PROTOCOL_UDNS: return DNS_PROTOCOL_MDNS; + case DNS_PROTOCOL_MDNS: return DNS_PROTOCOL_LLMNR; + case DNS_PROTOCOL_LLMNR: return DNS_PROTOCOL_NONE; + default: LogTimeF("DNS invalid protocol %d\r\n", protocol); return DNS_PROTOCOL_NONE; + } +} +int DnsGetNextProtocol6(int protocol) +{ + switch(protocol) + { + case DNS_PROTOCOL_NONE: return DNS_PROTOCOL_MDNS; + case DNS_PROTOCOL_MDNS: return DNS_PROTOCOL_LLMNR; + case DNS_PROTOCOL_LLMNR: return DNS_PROTOCOL_UDNS; + case DNS_PROTOCOL_UDNS: return DNS_PROTOCOL_NONE; + default: LogTimeF("DNS invalid protocol %d\r\n", protocol); return DNS_PROTOCOL_NONE; + } +} +bool DnsHostNamesEquate(char* pA, char* pB) +{ + while(true) + { + char a = *pA++; + char b = *pB++; + if (a >= 'A' && a <= 'Z') a |= 0x20; //Make lower case + if (b >= 'A' && b <= 'Z') b |= 0x20; //Make lower case + if (a != b) return false; //If different then stop and return the fact + if (!a) break; //No need to check 'b' too as it will necessarily be equal to 'a' at this point. + } + return true; //If we get here the strings must equate. +} + +int DnsMakeFullNameFromName(int protocol, const char* p, int size, char* result) +{ + int i = 0; + char c; + + while (i < size - 1) + { + c = *p++; + if (!c) break; + *result++ = c; + i++; + } + if (protocol == DNS_PROTOCOL_MDNS) + { + p = ".local"; + while (i < size - 1) + { + c = *p++; + if (!c) break; + *result++ = c; + i++; + } + } + if (protocol == DNS_PROTOCOL_UDNS && DhcpDomainName[0]) //Shouldn't do this in IPv6 as DHCP is IPv4 only + { + if (i < size - 1) + { + *result++ = '.'; + i++; + } + p = DhcpDomainName; + while (i < size - 1) + { + c = *p++; + if (!c) break; + *result++ = c; + i++; + } + } + *result = 0; //Terminate the resulting string + return i; +} +int DnsStripNameFromFullName(int protocol, char* p, int size, char* result) +{ + int i = 0; + char c; + + while (i < size - 1) + { + c = *p++; + if (c == 0) break; //End of the fqdn so stop + if (c == '.') + { + if (protocol == DNS_PROTOCOL_UDNS) + { + 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. + } + else + { + break; //Strip the domain from an LLMNR (there shouldn't be one) or MDNS (it should always be '.local') fqdn + } + } + *result++ = c; + i++; + } + *result = 0; //Terminate the copied string + return i; +} + +void DnsMain() +{ + DnsQueryMain(); +} + +int DnsHandlePacketReceived(void (*traceback)(void), int dnsProtocol, int sizeRx, void* pPacketRx, int* pSizeTx, void* pPacketTx) +{ + DnsHdrSetup(pPacketRx, sizeRx); + DnsHdrRead(); + + int action; + if (DnsHdrIsReply) + { + action = DnsReplyHandle(traceback, dnsProtocol); + } + else + { + action = DnsServerHandleQuery(traceback, dnsProtocol, pPacketTx, pSizeTx); + } + return action; +} + +int DnsPollForPacketToSend(void* pPacketTx, int* pSize) +{ + return DnsQueryPoll(pPacketTx, pSize); +} \ No newline at end of file