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 May 20 14:32:52 2021 +0000
Revision:
200:5acbc41bf469
Parent:
187:122fc1996c86
Increased number of arp entries from 20 to 30 to accommodate the number of WIZ devices plus a few incoming port 80 calls from the internet.

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