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

Committer:
andrewboyson
Date:
Wed Oct 04 07:51:02 2017 +0000
Revision:
37:793b39683406
Parent:
35:93c39d260a83
Child:
43:bc028d5a6424
Added trace back and trace forward to log messages

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 13:9cd54f7db57a 1 #include "mbed.h"
andrewboyson 13:9cd54f7db57a 2 #include "dns.h"
andrewboyson 13:9cd54f7db57a 3 #include "net.h"
andrewboyson 13:9cd54f7db57a 4 #include "log.h"
andrewboyson 14:e75a59c1123d 5 #include "net.h"
andrewboyson 14:e75a59c1123d 6 #include "eth.h"
andrewboyson 14:e75a59c1123d 7 #include "ip4.h"
andrewboyson 14:e75a59c1123d 8 #include "ip6.h"
andrewboyson 14:e75a59c1123d 9 #include "udp.h"
andrewboyson 37:793b39683406 10 #include "dnsname.h"
andrewboyson 13:9cd54f7db57a 11
andrewboyson 13:9cd54f7db57a 12 #define HEADER_LENGTH 12
andrewboyson 13:9cd54f7db57a 13
andrewboyson 13:9cd54f7db57a 14 __packed struct header
andrewboyson 13:9cd54f7db57a 15 {
andrewboyson 13:9cd54f7db57a 16 uint16_t id;
andrewboyson 13:9cd54f7db57a 17 uint8_t uflags;
andrewboyson 13:9cd54f7db57a 18 uint8_t lflags;
andrewboyson 13:9cd54f7db57a 19
andrewboyson 13:9cd54f7db57a 20 uint16_t qdcount;
andrewboyson 13:9cd54f7db57a 21 uint16_t ancount;
andrewboyson 13:9cd54f7db57a 22 uint16_t nscount;
andrewboyson 13:9cd54f7db57a 23 uint16_t arcount;
andrewboyson 13:9cd54f7db57a 24 };
andrewboyson 13:9cd54f7db57a 25
andrewboyson 13:9cd54f7db57a 26 uint16_t DnsHdrId;
andrewboyson 13:9cd54f7db57a 27
andrewboyson 13:9cd54f7db57a 28 bool DnsHdrIsReply;
andrewboyson 13:9cd54f7db57a 29 bool DnsHdrIsAuthoritative;
andrewboyson 13:9cd54f7db57a 30 bool DnsHdrIsRecursiveQuery;
andrewboyson 13:9cd54f7db57a 31
andrewboyson 13:9cd54f7db57a 32 uint16_t DnsHdrQdcount;
andrewboyson 13:9cd54f7db57a 33 uint16_t DnsHdrAncount;
andrewboyson 13:9cd54f7db57a 34 uint16_t DnsHdrNscount;
andrewboyson 13:9cd54f7db57a 35 uint16_t DnsHdrArcount;
andrewboyson 13:9cd54f7db57a 36
andrewboyson 13:9cd54f7db57a 37 char* DnsHdrPacket;
andrewboyson 13:9cd54f7db57a 38 char* DnsHdrData;
andrewboyson 13:9cd54f7db57a 39
andrewboyson 13:9cd54f7db57a 40 void DnsHdrSetup(void* pPacket)
andrewboyson 13:9cd54f7db57a 41 {
andrewboyson 13:9cd54f7db57a 42 DnsHdrPacket = (char*)pPacket;
andrewboyson 13:9cd54f7db57a 43 DnsHdrData = DnsHdrPacket + HEADER_LENGTH;
andrewboyson 13:9cd54f7db57a 44 }
andrewboyson 13:9cd54f7db57a 45
andrewboyson 13:9cd54f7db57a 46 void DnsHdrRead()
andrewboyson 13:9cd54f7db57a 47 {
andrewboyson 13:9cd54f7db57a 48 struct header* pHeader = (header*)DnsHdrPacket;
andrewboyson 13:9cd54f7db57a 49
andrewboyson 13:9cd54f7db57a 50 DnsHdrId = NetToHost16(pHeader->id);
andrewboyson 13:9cd54f7db57a 51
andrewboyson 13:9cd54f7db57a 52 uint8_t uflags = pHeader->uflags;
andrewboyson 13:9cd54f7db57a 53 DnsHdrIsReply = uflags & 0x80;
andrewboyson 13:9cd54f7db57a 54 DnsHdrIsAuthoritative = uflags & 0x04;
andrewboyson 33:714a0345e59b 55 DnsHdrIsRecursiveQuery = uflags & 0x01;
andrewboyson 13:9cd54f7db57a 56
andrewboyson 13:9cd54f7db57a 57 DnsHdrQdcount = NetToHost16(pHeader->qdcount);
andrewboyson 13:9cd54f7db57a 58 DnsHdrAncount = NetToHost16(pHeader->ancount);
andrewboyson 13:9cd54f7db57a 59 DnsHdrNscount = NetToHost16(pHeader->nscount);
andrewboyson 13:9cd54f7db57a 60 DnsHdrArcount = NetToHost16(pHeader->arcount);
andrewboyson 13:9cd54f7db57a 61
andrewboyson 13:9cd54f7db57a 62 }
andrewboyson 13:9cd54f7db57a 63 void DnsHdrWrite()
andrewboyson 13:9cd54f7db57a 64 {
andrewboyson 13:9cd54f7db57a 65 struct header* pHeader = (header*)DnsHdrPacket;
andrewboyson 13:9cd54f7db57a 66
andrewboyson 13:9cd54f7db57a 67 pHeader->id = NetToHost16(DnsHdrId);
andrewboyson 13:9cd54f7db57a 68
andrewboyson 13:9cd54f7db57a 69 uint8_t uflags = 0;
andrewboyson 13:9cd54f7db57a 70 uint8_t lflags = 0;
andrewboyson 13:9cd54f7db57a 71 if (DnsHdrIsReply) uflags |= 0x80;
andrewboyson 13:9cd54f7db57a 72 if (DnsHdrIsAuthoritative) uflags |= 0x04;
andrewboyson 13:9cd54f7db57a 73 if (DnsHdrIsRecursiveQuery) uflags |= 0x01;
andrewboyson 13:9cd54f7db57a 74 pHeader->uflags = uflags;
andrewboyson 13:9cd54f7db57a 75 pHeader->lflags = lflags;
andrewboyson 13:9cd54f7db57a 76
andrewboyson 13:9cd54f7db57a 77 pHeader->qdcount = NetToHost16(DnsHdrQdcount);
andrewboyson 13:9cd54f7db57a 78 pHeader->ancount = NetToHost16(DnsHdrAncount);
andrewboyson 13:9cd54f7db57a 79 pHeader->nscount = NetToHost16(DnsHdrNscount);
andrewboyson 13:9cd54f7db57a 80 pHeader->arcount = NetToHost16(DnsHdrArcount);
andrewboyson 13:9cd54f7db57a 81 }
andrewboyson 37:793b39683406 82 static void logContent()
andrewboyson 37:793b39683406 83 {
andrewboyson 37:793b39683406 84 char* p = DnsHdrData; //Local version of p which does not upset the global p used to build the response
andrewboyson 37:793b39683406 85
andrewboyson 37:793b39683406 86 char iEncodedName;
andrewboyson 37:793b39683406 87
andrewboyson 37:793b39683406 88 //Get the questions
andrewboyson 37:793b39683406 89 for (int q = 0; q < DnsHdrQdcount; q++)
andrewboyson 37:793b39683406 90 {
andrewboyson 37:793b39683406 91 if (p > DnsHdrData + 500)
andrewboyson 37:793b39683406 92 {
andrewboyson 37:793b39683406 93 Log("Questions have overrun the buffer\r\n");
andrewboyson 37:793b39683406 94 return;
andrewboyson 37:793b39683406 95 }
andrewboyson 37:793b39683406 96 iEncodedName = DnsNameIndexFromPointer(p);
andrewboyson 37:793b39683406 97 int nameLength = DnsNameLength(p);
andrewboyson 37:793b39683406 98 if (!nameLength) { LogTimeF("DnsServer-readQuestions namelength is zero\r\n"); return; }
andrewboyson 37:793b39683406 99 p += nameLength; //Skip past the name
andrewboyson 37:793b39683406 100 p++ ; //skip the first byte of the type
andrewboyson 37:793b39683406 101 char recordType = *p++; //read the record type
andrewboyson 37:793b39683406 102 p += 2; //skip the class
andrewboyson 37:793b39683406 103
andrewboyson 37:793b39683406 104 char text[256];
andrewboyson 37:793b39683406 105 DnsRecordTypeToString(recordType, sizeof(text), text);
andrewboyson 37:793b39683406 106 LogF(" Query %s type record of ", text);
andrewboyson 37:793b39683406 107 DnsNameDecodePtr(iEncodedName, sizeof(text), text);
andrewboyson 37:793b39683406 108 LogF("%s\r\n", text);
andrewboyson 37:793b39683406 109 }
andrewboyson 37:793b39683406 110
andrewboyson 37:793b39683406 111 //Get the answers
andrewboyson 37:793b39683406 112 for (int a = 0; a < DnsHdrAncount; a++)
andrewboyson 37:793b39683406 113 {
andrewboyson 37:793b39683406 114 if (p > DnsHdrData + 500)
andrewboyson 37:793b39683406 115 {
andrewboyson 37:793b39683406 116 Log("Answers have overrun the buffer\r\n");
andrewboyson 37:793b39683406 117 return;
andrewboyson 37:793b39683406 118 }
andrewboyson 37:793b39683406 119
andrewboyson 37:793b39683406 120 iEncodedName = DnsNameIndexFromPointer(p);
andrewboyson 37:793b39683406 121 int nameLength = DnsNameLength(p);
andrewboyson 37:793b39683406 122 if (!nameLength) { LogTimeF("DnsServer-readQuestions namelength is zero\r\n"); return; }
andrewboyson 37:793b39683406 123 p += nameLength; //Skip past the name
andrewboyson 37:793b39683406 124
andrewboyson 37:793b39683406 125 p++; //Skip the high byte of the record type
andrewboyson 37:793b39683406 126 int recordType = *p++; //Record type
andrewboyson 37:793b39683406 127
andrewboyson 37:793b39683406 128 p++; //Skip the high byte of the class type
andrewboyson 37:793b39683406 129 int classType = *p++; //Class type
andrewboyson 37:793b39683406 130
andrewboyson 37:793b39683406 131 int ttl = *p++; //32bit TTL
andrewboyson 37:793b39683406 132 ttl <<= 8; ttl += *p++;
andrewboyson 37:793b39683406 133 ttl <<= 8; ttl += *p++;
andrewboyson 37:793b39683406 134 ttl <<= 8; ttl += *p++;
andrewboyson 37:793b39683406 135
andrewboyson 37:793b39683406 136 int len = *p++; //16bit length
andrewboyson 37:793b39683406 137 len <<= 8; len += *p++;
andrewboyson 37:793b39683406 138
andrewboyson 37:793b39683406 139 char text[256];
andrewboyson 37:793b39683406 140 DnsRecordTypeToString(recordType, sizeof(text), text);
andrewboyson 37:793b39683406 141 LogF(" Answer %s type record of ", text);
andrewboyson 37:793b39683406 142 DnsNameDecodePtr(iEncodedName, sizeof(text), text);
andrewboyson 37:793b39683406 143 LogF(text);
andrewboyson 37:793b39683406 144
andrewboyson 37:793b39683406 145 switch (recordType) //Log the payload if its type is known
andrewboyson 37:793b39683406 146 {
andrewboyson 37:793b39683406 147 case DNS_RECORD_A:
andrewboyson 37:793b39683406 148 Ip4AddressToString(*(uint32_t*)p, sizeof(text), text);
andrewboyson 37:793b39683406 149 LogF(" ==> %s\r\n", text);
andrewboyson 37:793b39683406 150 break;
andrewboyson 37:793b39683406 151
andrewboyson 37:793b39683406 152 case DNS_RECORD_AAAA:
andrewboyson 37:793b39683406 153 Ip6AddressToString(p, sizeof(text), text);
andrewboyson 37:793b39683406 154 LogF(" ==> %s\r\n", text);
andrewboyson 37:793b39683406 155 break;
andrewboyson 37:793b39683406 156
andrewboyson 37:793b39683406 157 case DNS_RECORD_PTR:
andrewboyson 37:793b39683406 158 iEncodedName = DnsNameIndexFromPointer(p);
andrewboyson 37:793b39683406 159 DnsNameDecodePtr(iEncodedName, sizeof(text), text);
andrewboyson 37:793b39683406 160 LogF(" ==> %s\r\n", text);
andrewboyson 37:793b39683406 161 break;
andrewboyson 37:793b39683406 162
andrewboyson 37:793b39683406 163 case DNS_RECORD_TXT:
andrewboyson 37:793b39683406 164 LogF(" ==> %.*s\r\n", len, p);
andrewboyson 37:793b39683406 165 break;
andrewboyson 37:793b39683406 166 }
andrewboyson 37:793b39683406 167 p += len; //Adjust the pointer to the next character after the payload
andrewboyson 37:793b39683406 168
andrewboyson 37:793b39683406 169 }
andrewboyson 37:793b39683406 170 }
andrewboyson 37:793b39683406 171
andrewboyson 37:793b39683406 172 void DnsHdrLog(int protocol)
andrewboyson 13:9cd54f7db57a 173 {
andrewboyson 14:e75a59c1123d 174 char text[100];
andrewboyson 15:6ca6778168b1 175 DnsProtocolToString(protocol, sizeof(text), text);
andrewboyson 37:793b39683406 176 LogF("%s header\r\n", text);
andrewboyson 13:9cd54f7db57a 177 LogF(" Ident %hd\r\n", DnsHdrId);
andrewboyson 15:6ca6778168b1 178 if (DnsHdrIsReply)
andrewboyson 15:6ca6778168b1 179 {
andrewboyson 15:6ca6778168b1 180 if (DnsHdrIsAuthoritative) LogF(" Authoritative reply\r\n");
andrewboyson 15:6ca6778168b1 181 else LogF(" Non authoritative reply\r\n");
andrewboyson 15:6ca6778168b1 182 }
andrewboyson 15:6ca6778168b1 183 else
andrewboyson 15:6ca6778168b1 184 {
andrewboyson 15:6ca6778168b1 185 if (DnsHdrIsRecursiveQuery) LogF(" Recursive query\r\n");
andrewboyson 15:6ca6778168b1 186 else LogF(" Non recursive query\r\n");
andrewboyson 15:6ca6778168b1 187 }
andrewboyson 14:e75a59c1123d 188 LogF(" qd, an, ns, ar %hu, %hu, %hu, %hu\r\n", DnsHdrQdcount, DnsHdrAncount, DnsHdrNscount, DnsHdrArcount);
andrewboyson 37:793b39683406 189 logContent();
andrewboyson 13:9cd54f7db57a 190 }
andrewboyson 13:9cd54f7db57a 191