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:
Thu Jan 11 17:38:21 2018 +0000
Revision:
61:aad055f1b0d1
Parent:
udp/dns/dnshdr.cpp@59:e0e556c8bd46
Child:
121:bc048b65a630
Removed dependence on Mbed OS

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 61:aad055f1b0d1 1 #include <stdint.h>
andrewboyson 61:aad055f1b0d1 2 #include <stdbool.h>
andrewboyson 61:aad055f1b0d1 3
andrewboyson 13:9cd54f7db57a 4 #include "dns.h"
andrewboyson 13:9cd54f7db57a 5 #include "net.h"
andrewboyson 13:9cd54f7db57a 6 #include "log.h"
andrewboyson 14:e75a59c1123d 7 #include "net.h"
andrewboyson 14:e75a59c1123d 8 #include "eth.h"
andrewboyson 49:1a6336f2b3f9 9 #include "ip4addr.h"
andrewboyson 49:1a6336f2b3f9 10 #include "ip6addr.h"
andrewboyson 14:e75a59c1123d 11 #include "udp.h"
andrewboyson 37:793b39683406 12 #include "dnsname.h"
andrewboyson 13:9cd54f7db57a 13
andrewboyson 13:9cd54f7db57a 14 #define HEADER_LENGTH 12
andrewboyson 13:9cd54f7db57a 15
andrewboyson 13:9cd54f7db57a 16 __packed struct header
andrewboyson 13:9cd54f7db57a 17 {
andrewboyson 13:9cd54f7db57a 18 uint16_t id;
andrewboyson 13:9cd54f7db57a 19 uint8_t uflags;
andrewboyson 13:9cd54f7db57a 20 uint8_t lflags;
andrewboyson 13:9cd54f7db57a 21
andrewboyson 13:9cd54f7db57a 22 uint16_t qdcount;
andrewboyson 13:9cd54f7db57a 23 uint16_t ancount;
andrewboyson 13:9cd54f7db57a 24 uint16_t nscount;
andrewboyson 13:9cd54f7db57a 25 uint16_t arcount;
andrewboyson 13:9cd54f7db57a 26 };
andrewboyson 13:9cd54f7db57a 27
andrewboyson 13:9cd54f7db57a 28 uint16_t DnsHdrId;
andrewboyson 13:9cd54f7db57a 29
andrewboyson 13:9cd54f7db57a 30 bool DnsHdrIsReply;
andrewboyson 13:9cd54f7db57a 31 bool DnsHdrIsAuthoritative;
andrewboyson 13:9cd54f7db57a 32 bool DnsHdrIsRecursiveQuery;
andrewboyson 13:9cd54f7db57a 33
andrewboyson 13:9cd54f7db57a 34 uint16_t DnsHdrQdcount;
andrewboyson 13:9cd54f7db57a 35 uint16_t DnsHdrAncount;
andrewboyson 13:9cd54f7db57a 36 uint16_t DnsHdrNscount;
andrewboyson 13:9cd54f7db57a 37 uint16_t DnsHdrArcount;
andrewboyson 13:9cd54f7db57a 38
andrewboyson 13:9cd54f7db57a 39 char* DnsHdrPacket;
andrewboyson 13:9cd54f7db57a 40 char* DnsHdrData;
andrewboyson 59:e0e556c8bd46 41 int DnsHdrDataLength;
andrewboyson 13:9cd54f7db57a 42
andrewboyson 59:e0e556c8bd46 43 void DnsHdrSetup(void* pPacket, int lenPacket)
andrewboyson 13:9cd54f7db57a 44 {
andrewboyson 13:9cd54f7db57a 45 DnsHdrPacket = (char*)pPacket;
andrewboyson 61:aad055f1b0d1 46 DnsHdrData = DnsHdrPacket + sizeof(struct header);
andrewboyson 61:aad055f1b0d1 47 DnsHdrDataLength = lenPacket - sizeof(struct header);
andrewboyson 13:9cd54f7db57a 48 }
andrewboyson 13:9cd54f7db57a 49
andrewboyson 13:9cd54f7db57a 50 void DnsHdrRead()
andrewboyson 13:9cd54f7db57a 51 {
andrewboyson 61:aad055f1b0d1 52 struct header* pHeader = (struct header*)DnsHdrPacket;
andrewboyson 13:9cd54f7db57a 53
andrewboyson 13:9cd54f7db57a 54 DnsHdrId = NetToHost16(pHeader->id);
andrewboyson 13:9cd54f7db57a 55
andrewboyson 13:9cd54f7db57a 56 uint8_t uflags = pHeader->uflags;
andrewboyson 13:9cd54f7db57a 57 DnsHdrIsReply = uflags & 0x80;
andrewboyson 13:9cd54f7db57a 58 DnsHdrIsAuthoritative = uflags & 0x04;
andrewboyson 33:714a0345e59b 59 DnsHdrIsRecursiveQuery = uflags & 0x01;
andrewboyson 13:9cd54f7db57a 60
andrewboyson 13:9cd54f7db57a 61 DnsHdrQdcount = NetToHost16(pHeader->qdcount);
andrewboyson 13:9cd54f7db57a 62 DnsHdrAncount = NetToHost16(pHeader->ancount);
andrewboyson 13:9cd54f7db57a 63 DnsHdrNscount = NetToHost16(pHeader->nscount);
andrewboyson 13:9cd54f7db57a 64 DnsHdrArcount = NetToHost16(pHeader->arcount);
andrewboyson 13:9cd54f7db57a 65
andrewboyson 13:9cd54f7db57a 66 }
andrewboyson 13:9cd54f7db57a 67 void DnsHdrWrite()
andrewboyson 13:9cd54f7db57a 68 {
andrewboyson 61:aad055f1b0d1 69 struct header* pHeader = (struct header*)DnsHdrPacket;
andrewboyson 13:9cd54f7db57a 70
andrewboyson 13:9cd54f7db57a 71 pHeader->id = NetToHost16(DnsHdrId);
andrewboyson 13:9cd54f7db57a 72
andrewboyson 13:9cd54f7db57a 73 uint8_t uflags = 0;
andrewboyson 13:9cd54f7db57a 74 uint8_t lflags = 0;
andrewboyson 13:9cd54f7db57a 75 if (DnsHdrIsReply) uflags |= 0x80;
andrewboyson 13:9cd54f7db57a 76 if (DnsHdrIsAuthoritative) uflags |= 0x04;
andrewboyson 13:9cd54f7db57a 77 if (DnsHdrIsRecursiveQuery) uflags |= 0x01;
andrewboyson 13:9cd54f7db57a 78 pHeader->uflags = uflags;
andrewboyson 13:9cd54f7db57a 79 pHeader->lflags = lflags;
andrewboyson 13:9cd54f7db57a 80
andrewboyson 13:9cd54f7db57a 81 pHeader->qdcount = NetToHost16(DnsHdrQdcount);
andrewboyson 13:9cd54f7db57a 82 pHeader->ancount = NetToHost16(DnsHdrAncount);
andrewboyson 13:9cd54f7db57a 83 pHeader->nscount = NetToHost16(DnsHdrNscount);
andrewboyson 13:9cd54f7db57a 84 pHeader->arcount = NetToHost16(DnsHdrArcount);
andrewboyson 13:9cd54f7db57a 85 }
andrewboyson 58:d48c899e482f 86 static uint16_t decodeUint16(char* p)
andrewboyson 58:d48c899e482f 87 {
andrewboyson 58:d48c899e482f 88 uint16_t value = *p++;
andrewboyson 58:d48c899e482f 89 value <<= 8; value += *p++;
andrewboyson 58:d48c899e482f 90 return value;
andrewboyson 58:d48c899e482f 91 }
andrewboyson 58:d48c899e482f 92 static uint32_t decodeUint32(char* p)
andrewboyson 58:d48c899e482f 93 {
andrewboyson 58:d48c899e482f 94 uint32_t value = *p++;
andrewboyson 58:d48c899e482f 95 value <<= 8; value += *p++;
andrewboyson 58:d48c899e482f 96 value <<= 8; value += *p++;
andrewboyson 58:d48c899e482f 97 value <<= 8; value += *p++;
andrewboyson 58:d48c899e482f 98 return value;
andrewboyson 58:d48c899e482f 99 }
andrewboyson 58:d48c899e482f 100 static void logRecordA(int len, char* p)
andrewboyson 58:d48c899e482f 101 {
andrewboyson 58:d48c899e482f 102 if (len == 4) Ip4AddressLog(*(uint32_t*)p);
andrewboyson 58:d48c899e482f 103 else LogF("expected 4 bytes but had %d", len);
andrewboyson 58:d48c899e482f 104 }
andrewboyson 58:d48c899e482f 105 static void logRecordAAAA(int len, char* p)
andrewboyson 58:d48c899e482f 106 {
andrewboyson 58:d48c899e482f 107 if (len == 16) Ip6AddressLog(p);
andrewboyson 58:d48c899e482f 108 else LogF("expected 16 bytes but had %d", len);
andrewboyson 58:d48c899e482f 109 }
andrewboyson 58:d48c899e482f 110 static void logRecordPTR(int len, char* p)
andrewboyson 58:d48c899e482f 111 {
andrewboyson 58:d48c899e482f 112 if (len <= DNS_MAX_LABEL_LENGTH) DnsNameLogPtr(p);
andrewboyson 58:d48c899e482f 113 else LogF("length %d is greater than max DNS label length of %d\r\n", len, DNS_MAX_LABEL_LENGTH);
andrewboyson 58:d48c899e482f 114 }
andrewboyson 58:d48c899e482f 115 static void logRecordSRV(int len, char* p)
andrewboyson 58:d48c899e482f 116 {
andrewboyson 58:d48c899e482f 117 LogF("pri=%d " , decodeUint16(p)); p += 2;
andrewboyson 58:d48c899e482f 118 LogF("wei=%d " , decodeUint16(p)); p += 2;
andrewboyson 58:d48c899e482f 119 LogF("port=%d ", decodeUint16(p)); p += 2;
andrewboyson 58:d48c899e482f 120 DnsNameLogPtr(p);
andrewboyson 58:d48c899e482f 121 }
andrewboyson 58:d48c899e482f 122 static void logRecordTXT(int len, char* p)
andrewboyson 58:d48c899e482f 123 {
andrewboyson 58:d48c899e482f 124 char* pEnd = p + len;
andrewboyson 58:d48c899e482f 125 while (p < pEnd)
andrewboyson 58:d48c899e482f 126 {
andrewboyson 58:d48c899e482f 127 Log("\r\n ");
andrewboyson 58:d48c899e482f 128 int fieldLen = *p++;
andrewboyson 58:d48c899e482f 129 for (int i = 0; i < fieldLen; i++) LogPush(*p++);
andrewboyson 58:d48c899e482f 130 }
andrewboyson 58:d48c899e482f 131 }
andrewboyson 37:793b39683406 132 static void logContent()
andrewboyson 37:793b39683406 133 {
andrewboyson 58:d48c899e482f 134 char* p = DnsHdrData;
andrewboyson 37:793b39683406 135
andrewboyson 37:793b39683406 136 //Get the questions
andrewboyson 37:793b39683406 137 for (int q = 0; q < DnsHdrQdcount; q++)
andrewboyson 37:793b39683406 138 {
andrewboyson 59:e0e556c8bd46 139 if (p >= DnsHdrData + DnsHdrDataLength)
andrewboyson 37:793b39683406 140 {
andrewboyson 58:d48c899e482f 141 Log(" Questions have overrun the buffer\r\n");
andrewboyson 37:793b39683406 142 return;
andrewboyson 37:793b39683406 143 }
andrewboyson 58:d48c899e482f 144 char* pEncodedName = p;
andrewboyson 37:793b39683406 145 int nameLength = DnsNameLength(p);
andrewboyson 58:d48c899e482f 146 if (!nameLength) { LogTimeF(" Questions namelength is zero\r\n"); return; }
andrewboyson 37:793b39683406 147 p += nameLength; //Skip past the name
andrewboyson 37:793b39683406 148 p++ ; //skip the first byte of the type
andrewboyson 37:793b39683406 149 char recordType = *p++; //read the record type
andrewboyson 37:793b39683406 150 p += 2; //skip the class
andrewboyson 37:793b39683406 151
andrewboyson 47:73af5c0b0dc2 152 LogF(" Query ");
andrewboyson 47:73af5c0b0dc2 153 DnsRecordTypeLog(recordType);
andrewboyson 47:73af5c0b0dc2 154 Log(" type record of ");
andrewboyson 58:d48c899e482f 155 DnsNameLogPtr(pEncodedName);
andrewboyson 47:73af5c0b0dc2 156 Log("\r\n");
andrewboyson 37:793b39683406 157 }
andrewboyson 37:793b39683406 158
andrewboyson 37:793b39683406 159 //Get the answers
andrewboyson 37:793b39683406 160 for (int a = 0; a < DnsHdrAncount; a++)
andrewboyson 37:793b39683406 161 {
andrewboyson 59:e0e556c8bd46 162 if (p >= DnsHdrData + DnsHdrDataLength) { Log(" Answers have overrun the buffer\r\n"); return; }
andrewboyson 37:793b39683406 163
andrewboyson 58:d48c899e482f 164 char* pEncodedName = p;
andrewboyson 37:793b39683406 165 int nameLength = DnsNameLength(p);
andrewboyson 43:bc028d5a6424 166 if (!nameLength) { Log(" Answer name length is zero\r\n"); return; }
andrewboyson 37:793b39683406 167 p += nameLength; //Skip past the name
andrewboyson 37:793b39683406 168
andrewboyson 37:793b39683406 169 p++; //Skip the high byte of the record type
andrewboyson 37:793b39683406 170 int recordType = *p++; //Record type
andrewboyson 37:793b39683406 171
andrewboyson 37:793b39683406 172 p++; //Skip the high byte of the class type
andrewboyson 37:793b39683406 173 int classType = *p++; //Class type
andrewboyson 37:793b39683406 174
andrewboyson 58:d48c899e482f 175 int ttl = decodeUint32(p); p += 4; //32bit TTL
andrewboyson 37:793b39683406 176
andrewboyson 58:d48c899e482f 177 int len = decodeUint16(p); p += 2; //16bit length
andrewboyson 37:793b39683406 178
andrewboyson 43:bc028d5a6424 179 Log(" Answer ");
andrewboyson 47:73af5c0b0dc2 180 DnsRecordTypeLog(recordType);
andrewboyson 43:bc028d5a6424 181 Log(" type record of ");
andrewboyson 58:d48c899e482f 182 DnsNameLogPtr(pEncodedName);
andrewboyson 43:bc028d5a6424 183 Log(" ==> ");
andrewboyson 37:793b39683406 184
andrewboyson 37:793b39683406 185 switch (recordType) //Log the payload if its type is known
andrewboyson 37:793b39683406 186 {
andrewboyson 58:d48c899e482f 187 case DNS_RECORD_A: logRecordA (len, p); break;
andrewboyson 58:d48c899e482f 188 case DNS_RECORD_AAAA: logRecordAAAA(len, p); break;
andrewboyson 58:d48c899e482f 189 case DNS_RECORD_PTR: logRecordPTR (len, p); break;
andrewboyson 58:d48c899e482f 190 case DNS_RECORD_SRV: logRecordSRV (len, p); break;
andrewboyson 58:d48c899e482f 191 case DNS_RECORD_TXT: logRecordTXT (len, p); break;
andrewboyson 58:d48c899e482f 192 default: LogF("%d characters", len); break;
andrewboyson 37:793b39683406 193 }
andrewboyson 43:bc028d5a6424 194 Log("\r\n");
andrewboyson 37:793b39683406 195 p += len; //Adjust the pointer to the next character after the payload
andrewboyson 37:793b39683406 196 }
andrewboyson 37:793b39683406 197 }
andrewboyson 37:793b39683406 198
andrewboyson 37:793b39683406 199 void DnsHdrLog(int protocol)
andrewboyson 13:9cd54f7db57a 200 {
andrewboyson 43:bc028d5a6424 201 if (NetTraceVerbose)
andrewboyson 15:6ca6778168b1 202 {
andrewboyson 47:73af5c0b0dc2 203 DnsProtocolLog(protocol);
andrewboyson 47:73af5c0b0dc2 204 Log(" header\r\n");
andrewboyson 43:bc028d5a6424 205 LogF(" Ident %hd\r\n", DnsHdrId);
andrewboyson 43:bc028d5a6424 206 if (DnsHdrIsReply)
andrewboyson 43:bc028d5a6424 207 {
andrewboyson 43:bc028d5a6424 208 if (DnsHdrIsAuthoritative) LogF(" Authoritative reply\r\n");
andrewboyson 43:bc028d5a6424 209 else LogF(" Non authoritative reply\r\n");
andrewboyson 43:bc028d5a6424 210 }
andrewboyson 43:bc028d5a6424 211 else
andrewboyson 43:bc028d5a6424 212 {
andrewboyson 43:bc028d5a6424 213 if (DnsHdrIsRecursiveQuery) LogF(" Recursive query\r\n");
andrewboyson 43:bc028d5a6424 214 else LogF(" Non recursive query\r\n");
andrewboyson 43:bc028d5a6424 215 }
andrewboyson 43:bc028d5a6424 216 LogF(" qd, an, ns, ar %hu, %hu, %hu, %hu\r\n", DnsHdrQdcount, DnsHdrAncount, DnsHdrNscount, DnsHdrArcount);
andrewboyson 15:6ca6778168b1 217 }
andrewboyson 15:6ca6778168b1 218 else
andrewboyson 15:6ca6778168b1 219 {
andrewboyson 47:73af5c0b0dc2 220 DnsProtocolLog(protocol);
andrewboyson 47:73af5c0b0dc2 221 LogF(" header qd, an, ns, ar %hu, %hu, %hu, %hu\r\n", DnsHdrQdcount, DnsHdrAncount, DnsHdrNscount, DnsHdrArcount);
andrewboyson 15:6ca6778168b1 222 }
andrewboyson 37:793b39683406 223 logContent();
andrewboyson 13:9cd54f7db57a 224 }
andrewboyson 13:9cd54f7db57a 225