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/dnsquery.c
- Revision:
- 61:aad055f1b0d1
- Parent:
- 59:e0e556c8bd46
- Child:
- 65:37acccf2752f
diff -r 1d8c7a1e7483 -r aad055f1b0d1 udp/dns/dnsquery.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/udp/dns/dnsquery.c Thu Jan 11 17:38:21 2018 +0000 @@ -0,0 +1,182 @@ +#include <stdint.h> +#include <stdbool.h> + +#include "log.h" +#include "clock.h" +#include "net.h" +#include "action.h" +#include "ip4addr.h" +#include "ip6addr.h" +#include "dhcp.h" +#include "dns.h" +#include "udp.h" +#include "slaac.h" +#include "dnshdr.h" +#include "dnsname.h" + +bool DnsQueryTrace = false; + +#define TIME_OUT_SENT 3 + +#define MDNS_UNICAST false + +char DnsQueryName[DNS_MAX_LABEL_LENGTH+1]; +uint32_t DnsQueryIp4 = 0; +char DnsQueryIp6[16]; + +char DnsQueryRecordType = DNS_RECORD_NONE; +int DnsQueryProtocol = DNS_PROTOCOL_NONE; +bool DnsQueryIsBusy = false; + +static uint32_t started = 0; +static uint32_t elapsed = 0; +static void reap() +{ + if (!DnsQueryIsBusy) return; + + if (elapsed - started >= TIME_OUT_SENT) + { + LogTimeF("DNS reaped ongoing request for "); + if (DnsQueryName[0]) LogF("name %s", DnsQueryName); + if (DnsQueryIp4) + { + Log("ip4 "); Ip4AddressLog(DnsQueryIp4); + } + if (DnsQueryIp6[0]) + { + Log("ip6 "); Ip6AddressLog(DnsQueryIp6); + } + LogF("\r\n"); + + DnsQueryName[0] = 0; + DnsQueryIp4 = 0; + DnsQueryIp6[0] = 0; + DnsQueryIsBusy = false; + started = 0; + DnsQueryProtocol = DNS_PROTOCOL_NONE; + DnsQueryRecordType = DNS_RECORD_NONE; + } +} +void DnsQueryMain() +{ + if (ClockTicked) + { + elapsed++; + reap(); + } +} +void DnsQueryIp4FromName(char * name, int protocol) +{ + DnsMakeFullNameFromName(protocol, name, sizeof(DnsQueryName), DnsQueryName); + DnsQueryIp4 = 0; + DnsQueryIp6[0] = 0; + DnsQueryIsBusy = true; + started = elapsed; + DnsQueryProtocol = protocol; + DnsQueryRecordType = DNS_RECORD_A; +} +void DnsQueryIp6FromName(char * name, int protocol) +{ + DnsMakeFullNameFromName(protocol, name, sizeof(DnsQueryName), DnsQueryName); + DnsQueryIp4 = 0; + DnsQueryIp6[0] = 0; + DnsQueryIsBusy = true; + started = elapsed; + DnsQueryProtocol = protocol; + DnsQueryRecordType = DNS_RECORD_AAAA; +} +void DnsQueryNameFromIp4(uint32_t ip, int protocol) +{ + DnsQueryName[0] = 0; + DnsQueryIp4 = ip; + DnsQueryIp6[0] = 0; + DnsQueryIsBusy = true; + started = elapsed; + DnsQueryProtocol = protocol; + DnsQueryRecordType = DNS_RECORD_PTR; +} +void DnsQueryNameFromIp6(char* ip, int protocol) +{ + DnsQueryName[0] = 0; + DnsQueryIp4 = 0; + Ip6AddressCopy(DnsQueryIp6, ip); + DnsQueryIsBusy = true; + started = elapsed; + DnsQueryProtocol = protocol; + DnsQueryRecordType = DNS_RECORD_PTR; +} +static void logQuery() +{ + if (NetTraceNewLine) Log("\r\n"); + LogTimeF("DnsQuery sent "); + DnsProtocolLog(DnsQueryProtocol); + Log(" request for "); + DnsRecordTypeLog(DnsQueryRecordType); + Log(" "); + if (DnsQueryIp4) //Reverse + { + Ip4AddressLog(DnsQueryIp4); + } + else if (DnsQueryIp6[0]) + { + Ip6AddressLog(DnsQueryIp6); + } + else //Forward + { + Log(DnsQueryName); + } + Log("\r\n"); +} +int DnsQueryPoll(void* pPacket, int* pSize) +{ + DnsHdrSetup(pPacket, *pSize); + + if (!DnsQueryIsBusy) return DO_NOTHING; + if (DnsQueryProtocol == DNS_PROTOCOL_UDNS && DhcpLocalIp == 0) return DO_NOTHING; + + NetTraceHostCheckIp6(DnsQueryIp6); + + if (DnsQueryTrace || NetTraceHostGetMatched()) logQuery(); + + static uint16_t id = 0; + DnsHdrId = ++id; + DnsHdrIsReply = false; + DnsHdrIsRecursiveQuery = false; + + DnsHdrQdcount = 1; + DnsHdrAncount = 0; + DnsHdrNscount = 0; + DnsHdrArcount = 0; + + DnsHdrWrite(); + char* p = DnsHdrData; + + if (DnsQueryIp4 ) DnsNameEncodeIp4(DnsQueryIp4, &p); + else if (DnsQueryIp6[0]) DnsNameEncodeIp6(DnsQueryIp6, &p); + else DnsNameEncodePtr(DnsQueryName, &p); + + *p++ = 0; + *p++ = DnsQueryRecordType; + *p++ = DnsQueryProtocol == DNS_PROTOCOL_MDNS && MDNS_UNICAST ? 0x80 : 0; //Set the 15th bit (UNICAST_RESPONSE) to 1 if MDNS + *p++ = 1; //QCLASS_IN = 1 - internet + + *pSize = p - DnsHdrPacket; + + DnsQueryIsBusy = false; + + if (DnsQueryTrace || NetTraceHostGetMatched()) DnsHdrLog(DnsQueryProtocol); + + int dest = DO_NOTHING; + + switch (DnsQueryProtocol) + { + case DNS_PROTOCOL_UDNS: dest = UNICAST_DNS; break; //IPv6 ==> NdpDnsServer; IPv4 ==> DhcpDnsServer + case DNS_PROTOCOL_MDNS: dest = MULTICAST_MDNS; break; + case DNS_PROTOCOL_LLMNR: dest = MULTICAST_LLMNR; break; + default: + LogTimeF("DNS unknown query protocol %d\r\n", DnsQueryProtocol); + return DO_NOTHING; + } + + return ActionMakeFromDestAndTrace(dest, DnsQueryTrace || NetTraceHostGetMatched()); +}