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
udp/dns/dnsserver.cpp
- Committer:
- andrewboyson
- Date:
- 2017-07-03
- Revision:
- 22:914b970356f0
- Parent:
- 13:9cd54f7db57a
- Child:
- 32:679654f2d023
File content as of revision 22:914b970356f0:
#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) { if (DEBUG) LogTimeF("DnsServerHandleQuery length %d too long\r\n", *pSize); return DO_NOTHING; } if (DnsHdrQdcount > 4) { if (DEBUG) 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; }