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@22:914b970356f0, 2017-07-03 (annotated)
- Committer:
- andrewboyson
- Date:
- Mon Jul 03 14:29:07 2017 +0000
- Revision:
- 22:914b970356f0
- Parent:
- 13:9cd54f7db57a
- Child:
- 32:679654f2d023
Corrected NTP client function
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
andrewboyson | 13:9cd54f7db57a | 1 | #include "mbed.h" |
andrewboyson | 13:9cd54f7db57a | 2 | #include "dnshdr.h" |
andrewboyson | 13:9cd54f7db57a | 3 | #include "dnsname.h" |
andrewboyson | 13:9cd54f7db57a | 4 | #include "net.h" |
andrewboyson | 13:9cd54f7db57a | 5 | #include "dns.h" |
andrewboyson | 13:9cd54f7db57a | 6 | #include "log.h" |
andrewboyson | 13:9cd54f7db57a | 7 | #include "dhcp.h" |
andrewboyson | 13:9cd54f7db57a | 8 | #include "slaac.h" |
andrewboyson | 13:9cd54f7db57a | 9 | #include "io.h" |
andrewboyson | 13:9cd54f7db57a | 10 | |
andrewboyson | 13:9cd54f7db57a | 11 | #define DEBUG false |
andrewboyson | 13:9cd54f7db57a | 12 | |
andrewboyson | 13:9cd54f7db57a | 13 | int DnsServerHandleQuery(int dnsProtocol, int *pSize) //Received an mdns or llmnr query on port 5353 or 5355 |
andrewboyson | 13:9cd54f7db57a | 14 | { |
andrewboyson | 13:9cd54f7db57a | 15 | if (DEBUG) DnsHdrLog("server received query", dnsProtocol); |
andrewboyson | 13:9cd54f7db57a | 16 | |
andrewboyson | 22:914b970356f0 | 17 | if ( *pSize > 512) |
andrewboyson | 22:914b970356f0 | 18 | { |
andrewboyson | 22:914b970356f0 | 19 | if (DEBUG) LogTimeF("DnsServerHandleQuery length %d too long\r\n", *pSize); |
andrewboyson | 22:914b970356f0 | 20 | return DO_NOTHING; |
andrewboyson | 22:914b970356f0 | 21 | } |
andrewboyson | 22:914b970356f0 | 22 | if (DnsHdrQdcount > 4) |
andrewboyson | 22:914b970356f0 | 23 | { |
andrewboyson | 22:914b970356f0 | 24 | if (DEBUG) LogTimeF("DnsServerHandleQuery too many queries %d\r\n", *pSize); |
andrewboyson | 22:914b970356f0 | 25 | return DO_NOTHING; |
andrewboyson | 22:914b970356f0 | 26 | } |
andrewboyson | 13:9cd54f7db57a | 27 | |
andrewboyson | 13:9cd54f7db57a | 28 | char *p = DnsHdrData; |
andrewboyson | 13:9cd54f7db57a | 29 | |
andrewboyson | 13:9cd54f7db57a | 30 | char iEncodedName; |
andrewboyson | 13:9cd54f7db57a | 31 | bool isMe = false; |
andrewboyson | 13:9cd54f7db57a | 32 | int types[4]; |
andrewboyson | 13:9cd54f7db57a | 33 | bool mdnsUnicastReply = false; |
andrewboyson | 13:9cd54f7db57a | 34 | |
andrewboyson | 13:9cd54f7db57a | 35 | //Get the questions |
andrewboyson | 13:9cd54f7db57a | 36 | DnsHdrAncount = 0; |
andrewboyson | 13:9cd54f7db57a | 37 | for (int q = 0; q < DnsHdrQdcount; q++) |
andrewboyson | 13:9cd54f7db57a | 38 | { |
andrewboyson | 13:9cd54f7db57a | 39 | iEncodedName = DnsNameIndexFromPointer(p); |
andrewboyson | 13:9cd54f7db57a | 40 | int nameLength = DnsNameLength(p); |
andrewboyson | 13:9cd54f7db57a | 41 | if (!nameLength) return DO_NOTHING; |
andrewboyson | 13:9cd54f7db57a | 42 | if (!q) isMe = DnsNameCompare(p, NetName); //get the name: rtc.local; 3.1.168.192.inaddr.arpa; etc |
andrewboyson | 13:9cd54f7db57a | 43 | p += nameLength; //Skip past the name |
andrewboyson | 13:9cd54f7db57a | 44 | p++ ; //skip the first byte of the type |
andrewboyson | 13:9cd54f7db57a | 45 | char recordType = *p++; //read the record type |
andrewboyson | 13:9cd54f7db57a | 46 | if (*p++ & 0x80) mdnsUnicastReply = true; //Check the 15th bit (UNICAST-RESPONSE) |
andrewboyson | 13:9cd54f7db57a | 47 | p += 1; //skip the class |
andrewboyson | 13:9cd54f7db57a | 48 | |
andrewboyson | 13:9cd54f7db57a | 49 | types[q] = recordType; |
andrewboyson | 13:9cd54f7db57a | 50 | |
andrewboyson | 13:9cd54f7db57a | 51 | if (DEBUG) |
andrewboyson | 13:9cd54f7db57a | 52 | { |
andrewboyson | 13:9cd54f7db57a | 53 | switch (recordType) |
andrewboyson | 13:9cd54f7db57a | 54 | { |
andrewboyson | 13:9cd54f7db57a | 55 | case DNS_RECORD_A: LogF(" for IP4 address\r\n"); break; |
andrewboyson | 13:9cd54f7db57a | 56 | case DNS_RECORD_PTR: LogF(" for name\r\n"); break; |
andrewboyson | 13:9cd54f7db57a | 57 | case DNS_RECORD_AAAA: LogF(" for IP6 address\r\n"); break; |
andrewboyson | 13:9cd54f7db57a | 58 | default: LogF(" for unrecognised record type %d\r\n", recordType); break; |
andrewboyson | 13:9cd54f7db57a | 59 | } |
andrewboyson | 13:9cd54f7db57a | 60 | char text[256]; |
andrewboyson | 13:9cd54f7db57a | 61 | DnsNameDecode(iEncodedName, sizeof(text), text); |
andrewboyson | 13:9cd54f7db57a | 62 | LogF(" Name %s\r\n", text); |
andrewboyson | 13:9cd54f7db57a | 63 | } |
andrewboyson | 13:9cd54f7db57a | 64 | } |
andrewboyson | 13:9cd54f7db57a | 65 | if (!isMe) return DO_NOTHING; |
andrewboyson | 13:9cd54f7db57a | 66 | |
andrewboyson | 13:9cd54f7db57a | 67 | //Respond to the questions |
andrewboyson | 13:9cd54f7db57a | 68 | for (int q = 0; q < DnsHdrQdcount; q++) |
andrewboyson | 13:9cd54f7db57a | 69 | { |
andrewboyson | 13:9cd54f7db57a | 70 | switch (types[q]) |
andrewboyson | 13:9cd54f7db57a | 71 | { |
andrewboyson | 13:9cd54f7db57a | 72 | case DNS_RECORD_A: |
andrewboyson | 13:9cd54f7db57a | 73 | if (p - DnsHdrPacket > 500) |
andrewboyson | 13:9cd54f7db57a | 74 | { |
andrewboyson | 13:9cd54f7db57a | 75 | LogTimeF("DNS server ip4 query reply is getting too big\r\n"); |
andrewboyson | 13:9cd54f7db57a | 76 | return DO_NOTHING; |
andrewboyson | 13:9cd54f7db57a | 77 | } |
andrewboyson | 13:9cd54f7db57a | 78 | DnsHdrAncount++; |
andrewboyson | 13:9cd54f7db57a | 79 | //Name |
andrewboyson | 13:9cd54f7db57a | 80 | DnsNameEncode(NetName, &p); |
andrewboyson | 13:9cd54f7db57a | 81 | |
andrewboyson | 13:9cd54f7db57a | 82 | //16 bit Type |
andrewboyson | 13:9cd54f7db57a | 83 | *p++ = 0; //MSB type |
andrewboyson | 13:9cd54f7db57a | 84 | *p++ = DNS_RECORD_A; |
andrewboyson | 13:9cd54f7db57a | 85 | |
andrewboyson | 13:9cd54f7db57a | 86 | //Class |
andrewboyson | 13:9cd54f7db57a | 87 | *p++ = dnsProtocol == DNS_PROTOCOL_MDNS ? 0x80 : 0; //Set the 15th bit (CACHE_FLUSH) to 1 if MDNS |
andrewboyson | 13:9cd54f7db57a | 88 | *p++ = 1; //QCLASS_IN = 1 - internet |
andrewboyson | 13:9cd54f7db57a | 89 | |
andrewboyson | 13:9cd54f7db57a | 90 | //32 bit TTL seconds |
andrewboyson | 13:9cd54f7db57a | 91 | *p++ = 0; |
andrewboyson | 13:9cd54f7db57a | 92 | *p++ = 0; |
andrewboyson | 13:9cd54f7db57a | 93 | *p++ = 4; //1024 seconds |
andrewboyson | 13:9cd54f7db57a | 94 | *p++ = 0; |
andrewboyson | 13:9cd54f7db57a | 95 | |
andrewboyson | 13:9cd54f7db57a | 96 | //16bit length in bytes |
andrewboyson | 13:9cd54f7db57a | 97 | *p++ = 0; |
andrewboyson | 13:9cd54f7db57a | 98 | *p++ = 4; |
andrewboyson | 13:9cd54f7db57a | 99 | |
andrewboyson | 13:9cd54f7db57a | 100 | //Value |
andrewboyson | 13:9cd54f7db57a | 101 | memcpy(p, &DhcpLocalIp, 4); |
andrewboyson | 13:9cd54f7db57a | 102 | p += 4; |
andrewboyson | 13:9cd54f7db57a | 103 | break; |
andrewboyson | 13:9cd54f7db57a | 104 | |
andrewboyson | 13:9cd54f7db57a | 105 | case DNS_RECORD_AAAA: |
andrewboyson | 13:9cd54f7db57a | 106 | if (p - DnsHdrPacket > 500) |
andrewboyson | 13:9cd54f7db57a | 107 | { |
andrewboyson | 13:9cd54f7db57a | 108 | LogTimeF("DNS server Ip6 query reply is getting too big\r\n"); |
andrewboyson | 13:9cd54f7db57a | 109 | return DO_NOTHING; |
andrewboyson | 13:9cd54f7db57a | 110 | } |
andrewboyson | 13:9cd54f7db57a | 111 | DnsHdrAncount++; |
andrewboyson | 13:9cd54f7db57a | 112 | //Name |
andrewboyson | 13:9cd54f7db57a | 113 | DnsNameEncode(NetName, &p); |
andrewboyson | 13:9cd54f7db57a | 114 | |
andrewboyson | 13:9cd54f7db57a | 115 | //16 bit Type |
andrewboyson | 13:9cd54f7db57a | 116 | *p++ = 0; //MSB type |
andrewboyson | 13:9cd54f7db57a | 117 | *p++ = DNS_RECORD_AAAA; |
andrewboyson | 13:9cd54f7db57a | 118 | |
andrewboyson | 13:9cd54f7db57a | 119 | //Class |
andrewboyson | 13:9cd54f7db57a | 120 | *p++ = dnsProtocol == DNS_PROTOCOL_MDNS ? 0x80 : 0; //Set the 15th bit (CACHE_FLUSH) to 1 if MDNS |
andrewboyson | 13:9cd54f7db57a | 121 | *p++ = 1; //QCLASS_IN = 1 - internet |
andrewboyson | 13:9cd54f7db57a | 122 | |
andrewboyson | 13:9cd54f7db57a | 123 | //32 bit TTL seconds |
andrewboyson | 13:9cd54f7db57a | 124 | *p++ = 0; |
andrewboyson | 13:9cd54f7db57a | 125 | *p++ = 0; |
andrewboyson | 13:9cd54f7db57a | 126 | *p++ = 4; //1024 seconds |
andrewboyson | 13:9cd54f7db57a | 127 | *p++ = 0; |
andrewboyson | 13:9cd54f7db57a | 128 | |
andrewboyson | 13:9cd54f7db57a | 129 | //16bit length in bytes |
andrewboyson | 13:9cd54f7db57a | 130 | *p++ = 0; |
andrewboyson | 13:9cd54f7db57a | 131 | *p++ = 16; |
andrewboyson | 13:9cd54f7db57a | 132 | |
andrewboyson | 13:9cd54f7db57a | 133 | //Value |
andrewboyson | 13:9cd54f7db57a | 134 | memcpy(p, SlaacLinkLocalIp, 16); |
andrewboyson | 13:9cd54f7db57a | 135 | p += 16; |
andrewboyson | 13:9cd54f7db57a | 136 | break; |
andrewboyson | 13:9cd54f7db57a | 137 | } |
andrewboyson | 13:9cd54f7db57a | 138 | } |
andrewboyson | 13:9cd54f7db57a | 139 | if (!DnsHdrAncount) return DO_NOTHING; |
andrewboyson | 13:9cd54f7db57a | 140 | |
andrewboyson | 13:9cd54f7db57a | 141 | DnsHdrIsReply = true; |
andrewboyson | 13:9cd54f7db57a | 142 | DnsHdrIsAuthoritative = true; |
andrewboyson | 13:9cd54f7db57a | 143 | DnsHdrWrite(); |
andrewboyson | 13:9cd54f7db57a | 144 | |
andrewboyson | 13:9cd54f7db57a | 145 | *pSize = p - DnsHdrPacket; |
andrewboyson | 13:9cd54f7db57a | 146 | |
andrewboyson | 13:9cd54f7db57a | 147 | if (DEBUG) DnsHdrLog("server sending reply", dnsProtocol); |
andrewboyson | 13:9cd54f7db57a | 148 | |
andrewboyson | 13:9cd54f7db57a | 149 | if (dnsProtocol == DNS_PROTOCOL_MDNS && !mdnsUnicastReply) return MULTICAST_MDNS; |
andrewboyson | 13:9cd54f7db57a | 150 | return UNICAST; |
andrewboyson | 13:9cd54f7db57a | 151 | } |