Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: oldheating gps motorhome heating
Diff: udp/dns/dnsserver.cpp
- Revision:
- 13:9cd54f7db57a
- Child:
- 22:914b970356f0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/udp/dns/dnsserver.cpp Mon May 01 18:20:55 2017 +0000 @@ -0,0 +1,143 @@ +#include "mbed.h" +#include "dnshdr.h" +#include "dnsname.h" +#include "net.h" +#include "dns.h" +#include "log.h" +#include "dhcp.h" +#include "slaac.h" +#include "io.h" + +#define DEBUG false + +int DnsServerHandleQuery(int dnsProtocol, int *pSize) //Received an mdns or llmnr query on port 5353 or 5355 +{ + if (DEBUG) DnsHdrLog("server received query", dnsProtocol); + + if ( *pSize > 512) { LogTimeF("DnsServerHandleQuery length %d too long\r\n", *pSize); return DO_NOTHING; } + if (DnsHdrQdcount > 4) { LogTimeF("DnsServerHandleQuery too many queries %d\r\n", *pSize); return DO_NOTHING; } + + char *p = DnsHdrData; + + char iEncodedName; + bool isMe = false; + int types[4]; + bool mdnsUnicastReply = false; + + //Get the questions + DnsHdrAncount = 0; + for (int q = 0; q < DnsHdrQdcount; q++) + { + iEncodedName = DnsNameIndexFromPointer(p); + int nameLength = DnsNameLength(p); + if (!nameLength) return DO_NOTHING; + if (!q) isMe = DnsNameCompare(p, NetName); //get the name: rtc.local; 3.1.168.192.inaddr.arpa; etc + p += nameLength; //Skip past the name + p++ ; //skip the first byte of the type + char recordType = *p++; //read the record type + if (*p++ & 0x80) mdnsUnicastReply = true; //Check the 15th bit (UNICAST-RESPONSE) + p += 1; //skip the class + + types[q] = recordType; + + if (DEBUG) + { + switch (recordType) + { + case DNS_RECORD_A: LogF(" for IP4 address\r\n"); break; + case DNS_RECORD_PTR: LogF(" for name\r\n"); break; + case DNS_RECORD_AAAA: LogF(" for IP6 address\r\n"); break; + default: LogF(" for unrecognised record type %d\r\n", recordType); break; + } + char text[256]; + DnsNameDecode(iEncodedName, sizeof(text), text); + LogF(" Name %s\r\n", text); + } + } + if (!isMe) return DO_NOTHING; + + //Respond to the questions + for (int q = 0; q < DnsHdrQdcount; q++) + { + switch (types[q]) + { + case DNS_RECORD_A: + if (p - DnsHdrPacket > 500) + { + LogTimeF("DNS server ip4 query reply is getting too big\r\n"); + return DO_NOTHING; + } + DnsHdrAncount++; + //Name + DnsNameEncode(NetName, &p); + + //16 bit Type + *p++ = 0; //MSB type + *p++ = DNS_RECORD_A; + + //Class + *p++ = dnsProtocol == DNS_PROTOCOL_MDNS ? 0x80 : 0; //Set the 15th bit (CACHE_FLUSH) to 1 if MDNS + *p++ = 1; //QCLASS_IN = 1 - internet + + //32 bit TTL seconds + *p++ = 0; + *p++ = 0; + *p++ = 4; //1024 seconds + *p++ = 0; + + //16bit length in bytes + *p++ = 0; + *p++ = 4; + + //Value + memcpy(p, &DhcpLocalIp, 4); + p += 4; + break; + + case DNS_RECORD_AAAA: + if (p - DnsHdrPacket > 500) + { + LogTimeF("DNS server Ip6 query reply is getting too big\r\n"); + return DO_NOTHING; + } + DnsHdrAncount++; + //Name + DnsNameEncode(NetName, &p); + + //16 bit Type + *p++ = 0; //MSB type + *p++ = DNS_RECORD_AAAA; + + //Class + *p++ = dnsProtocol == DNS_PROTOCOL_MDNS ? 0x80 : 0; //Set the 15th bit (CACHE_FLUSH) to 1 if MDNS + *p++ = 1; //QCLASS_IN = 1 - internet + + //32 bit TTL seconds + *p++ = 0; + *p++ = 0; + *p++ = 4; //1024 seconds + *p++ = 0; + + //16bit length in bytes + *p++ = 0; + *p++ = 16; + + //Value + memcpy(p, SlaacLinkLocalIp, 16); + p += 16; + break; + } + } + if (!DnsHdrAncount) return DO_NOTHING; + + DnsHdrIsReply = true; + DnsHdrIsAuthoritative = true; + DnsHdrWrite(); + + *pSize = p - DnsHdrPacket; + + if (DEBUG) DnsHdrLog("server sending reply", dnsProtocol); + + if (dnsProtocol == DNS_PROTOCOL_MDNS && !mdnsUnicastReply) return MULTICAST_MDNS; + return UNICAST; +}