Andrew Boyson / net

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Mon May 01 18:20:55 2017 +0000
Revision:
13:9cd54f7db57a
Child:
22:914b970356f0
Added ability to read DNS queries with encoded IP addresses

Who changed what in which revision?

UserRevisionLine numberNew 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 13:9cd54f7db57a 17 if ( *pSize > 512) { LogTimeF("DnsServerHandleQuery length %d too long\r\n", *pSize); return DO_NOTHING; }
andrewboyson 13:9cd54f7db57a 18 if (DnsHdrQdcount > 4) { LogTimeF("DnsServerHandleQuery too many queries %d\r\n", *pSize); return DO_NOTHING; }
andrewboyson 13:9cd54f7db57a 19
andrewboyson 13:9cd54f7db57a 20 char *p = DnsHdrData;
andrewboyson 13:9cd54f7db57a 21
andrewboyson 13:9cd54f7db57a 22 char iEncodedName;
andrewboyson 13:9cd54f7db57a 23 bool isMe = false;
andrewboyson 13:9cd54f7db57a 24 int types[4];
andrewboyson 13:9cd54f7db57a 25 bool mdnsUnicastReply = false;
andrewboyson 13:9cd54f7db57a 26
andrewboyson 13:9cd54f7db57a 27 //Get the questions
andrewboyson 13:9cd54f7db57a 28 DnsHdrAncount = 0;
andrewboyson 13:9cd54f7db57a 29 for (int q = 0; q < DnsHdrQdcount; q++)
andrewboyson 13:9cd54f7db57a 30 {
andrewboyson 13:9cd54f7db57a 31 iEncodedName = DnsNameIndexFromPointer(p);
andrewboyson 13:9cd54f7db57a 32 int nameLength = DnsNameLength(p);
andrewboyson 13:9cd54f7db57a 33 if (!nameLength) return DO_NOTHING;
andrewboyson 13:9cd54f7db57a 34 if (!q) isMe = DnsNameCompare(p, NetName); //get the name: rtc.local; 3.1.168.192.inaddr.arpa; etc
andrewboyson 13:9cd54f7db57a 35 p += nameLength; //Skip past the name
andrewboyson 13:9cd54f7db57a 36 p++ ; //skip the first byte of the type
andrewboyson 13:9cd54f7db57a 37 char recordType = *p++; //read the record type
andrewboyson 13:9cd54f7db57a 38 if (*p++ & 0x80) mdnsUnicastReply = true; //Check the 15th bit (UNICAST-RESPONSE)
andrewboyson 13:9cd54f7db57a 39 p += 1; //skip the class
andrewboyson 13:9cd54f7db57a 40
andrewboyson 13:9cd54f7db57a 41 types[q] = recordType;
andrewboyson 13:9cd54f7db57a 42
andrewboyson 13:9cd54f7db57a 43 if (DEBUG)
andrewboyson 13:9cd54f7db57a 44 {
andrewboyson 13:9cd54f7db57a 45 switch (recordType)
andrewboyson 13:9cd54f7db57a 46 {
andrewboyson 13:9cd54f7db57a 47 case DNS_RECORD_A: LogF(" for IP4 address\r\n"); break;
andrewboyson 13:9cd54f7db57a 48 case DNS_RECORD_PTR: LogF(" for name\r\n"); break;
andrewboyson 13:9cd54f7db57a 49 case DNS_RECORD_AAAA: LogF(" for IP6 address\r\n"); break;
andrewboyson 13:9cd54f7db57a 50 default: LogF(" for unrecognised record type %d\r\n", recordType); break;
andrewboyson 13:9cd54f7db57a 51 }
andrewboyson 13:9cd54f7db57a 52 char text[256];
andrewboyson 13:9cd54f7db57a 53 DnsNameDecode(iEncodedName, sizeof(text), text);
andrewboyson 13:9cd54f7db57a 54 LogF(" Name %s\r\n", text);
andrewboyson 13:9cd54f7db57a 55 }
andrewboyson 13:9cd54f7db57a 56 }
andrewboyson 13:9cd54f7db57a 57 if (!isMe) return DO_NOTHING;
andrewboyson 13:9cd54f7db57a 58
andrewboyson 13:9cd54f7db57a 59 //Respond to the questions
andrewboyson 13:9cd54f7db57a 60 for (int q = 0; q < DnsHdrQdcount; q++)
andrewboyson 13:9cd54f7db57a 61 {
andrewboyson 13:9cd54f7db57a 62 switch (types[q])
andrewboyson 13:9cd54f7db57a 63 {
andrewboyson 13:9cd54f7db57a 64 case DNS_RECORD_A:
andrewboyson 13:9cd54f7db57a 65 if (p - DnsHdrPacket > 500)
andrewboyson 13:9cd54f7db57a 66 {
andrewboyson 13:9cd54f7db57a 67 LogTimeF("DNS server ip4 query reply is getting too big\r\n");
andrewboyson 13:9cd54f7db57a 68 return DO_NOTHING;
andrewboyson 13:9cd54f7db57a 69 }
andrewboyson 13:9cd54f7db57a 70 DnsHdrAncount++;
andrewboyson 13:9cd54f7db57a 71 //Name
andrewboyson 13:9cd54f7db57a 72 DnsNameEncode(NetName, &p);
andrewboyson 13:9cd54f7db57a 73
andrewboyson 13:9cd54f7db57a 74 //16 bit Type
andrewboyson 13:9cd54f7db57a 75 *p++ = 0; //MSB type
andrewboyson 13:9cd54f7db57a 76 *p++ = DNS_RECORD_A;
andrewboyson 13:9cd54f7db57a 77
andrewboyson 13:9cd54f7db57a 78 //Class
andrewboyson 13:9cd54f7db57a 79 *p++ = dnsProtocol == DNS_PROTOCOL_MDNS ? 0x80 : 0; //Set the 15th bit (CACHE_FLUSH) to 1 if MDNS
andrewboyson 13:9cd54f7db57a 80 *p++ = 1; //QCLASS_IN = 1 - internet
andrewboyson 13:9cd54f7db57a 81
andrewboyson 13:9cd54f7db57a 82 //32 bit TTL seconds
andrewboyson 13:9cd54f7db57a 83 *p++ = 0;
andrewboyson 13:9cd54f7db57a 84 *p++ = 0;
andrewboyson 13:9cd54f7db57a 85 *p++ = 4; //1024 seconds
andrewboyson 13:9cd54f7db57a 86 *p++ = 0;
andrewboyson 13:9cd54f7db57a 87
andrewboyson 13:9cd54f7db57a 88 //16bit length in bytes
andrewboyson 13:9cd54f7db57a 89 *p++ = 0;
andrewboyson 13:9cd54f7db57a 90 *p++ = 4;
andrewboyson 13:9cd54f7db57a 91
andrewboyson 13:9cd54f7db57a 92 //Value
andrewboyson 13:9cd54f7db57a 93 memcpy(p, &DhcpLocalIp, 4);
andrewboyson 13:9cd54f7db57a 94 p += 4;
andrewboyson 13:9cd54f7db57a 95 break;
andrewboyson 13:9cd54f7db57a 96
andrewboyson 13:9cd54f7db57a 97 case DNS_RECORD_AAAA:
andrewboyson 13:9cd54f7db57a 98 if (p - DnsHdrPacket > 500)
andrewboyson 13:9cd54f7db57a 99 {
andrewboyson 13:9cd54f7db57a 100 LogTimeF("DNS server Ip6 query reply is getting too big\r\n");
andrewboyson 13:9cd54f7db57a 101 return DO_NOTHING;
andrewboyson 13:9cd54f7db57a 102 }
andrewboyson 13:9cd54f7db57a 103 DnsHdrAncount++;
andrewboyson 13:9cd54f7db57a 104 //Name
andrewboyson 13:9cd54f7db57a 105 DnsNameEncode(NetName, &p);
andrewboyson 13:9cd54f7db57a 106
andrewboyson 13:9cd54f7db57a 107 //16 bit Type
andrewboyson 13:9cd54f7db57a 108 *p++ = 0; //MSB type
andrewboyson 13:9cd54f7db57a 109 *p++ = DNS_RECORD_AAAA;
andrewboyson 13:9cd54f7db57a 110
andrewboyson 13:9cd54f7db57a 111 //Class
andrewboyson 13:9cd54f7db57a 112 *p++ = dnsProtocol == DNS_PROTOCOL_MDNS ? 0x80 : 0; //Set the 15th bit (CACHE_FLUSH) to 1 if MDNS
andrewboyson 13:9cd54f7db57a 113 *p++ = 1; //QCLASS_IN = 1 - internet
andrewboyson 13:9cd54f7db57a 114
andrewboyson 13:9cd54f7db57a 115 //32 bit TTL seconds
andrewboyson 13:9cd54f7db57a 116 *p++ = 0;
andrewboyson 13:9cd54f7db57a 117 *p++ = 0;
andrewboyson 13:9cd54f7db57a 118 *p++ = 4; //1024 seconds
andrewboyson 13:9cd54f7db57a 119 *p++ = 0;
andrewboyson 13:9cd54f7db57a 120
andrewboyson 13:9cd54f7db57a 121 //16bit length in bytes
andrewboyson 13:9cd54f7db57a 122 *p++ = 0;
andrewboyson 13:9cd54f7db57a 123 *p++ = 16;
andrewboyson 13:9cd54f7db57a 124
andrewboyson 13:9cd54f7db57a 125 //Value
andrewboyson 13:9cd54f7db57a 126 memcpy(p, SlaacLinkLocalIp, 16);
andrewboyson 13:9cd54f7db57a 127 p += 16;
andrewboyson 13:9cd54f7db57a 128 break;
andrewboyson 13:9cd54f7db57a 129 }
andrewboyson 13:9cd54f7db57a 130 }
andrewboyson 13:9cd54f7db57a 131 if (!DnsHdrAncount) return DO_NOTHING;
andrewboyson 13:9cd54f7db57a 132
andrewboyson 13:9cd54f7db57a 133 DnsHdrIsReply = true;
andrewboyson 13:9cd54f7db57a 134 DnsHdrIsAuthoritative = true;
andrewboyson 13:9cd54f7db57a 135 DnsHdrWrite();
andrewboyson 13:9cd54f7db57a 136
andrewboyson 13:9cd54f7db57a 137 *pSize = p - DnsHdrPacket;
andrewboyson 13:9cd54f7db57a 138
andrewboyson 13:9cd54f7db57a 139 if (DEBUG) DnsHdrLog("server sending reply", dnsProtocol);
andrewboyson 13:9cd54f7db57a 140
andrewboyson 13:9cd54f7db57a 141 if (dnsProtocol == DNS_PROTOCOL_MDNS && !mdnsUnicastReply) return MULTICAST_MDNS;
andrewboyson 13:9cd54f7db57a 142 return UNICAST;
andrewboyson 13:9cd54f7db57a 143 }